blob: 1980c2e803af3039957094daaeccea1857285bac [file] [log] [blame]
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001//===-- SparcInternals.h - Header file for Sparc backend ---------*- C++ -*--=//
2//
3// This file defines stuff that is to be private to the Sparc backend, but is
4// shared among different portions of the backend.
5//
6//===----------------------------------------------------------------------===//
7
8#ifndef SPARC_INTERNALS_H
9#define SPARC_INTERNALS_H
10
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000011
12#include "SparcRegClassInfo.h"
13#include "llvm/Target/TargetMachine.h"
14#include "llvm/Target/MachineInstrInfo.h"
15
Vikram S. Adve339084b2001-09-18 13:04:24 +000016#include "llvm/Target/MachineSchedInfo.h"
Chris Lattnerc6495ee2001-09-14 03:56:45 +000017#include "llvm/Type.h"
Vikram S. Adve339084b2001-09-18 13:04:24 +000018
Chris Lattner46cbff62001-09-14 16:56:32 +000019#include <sys/types.h>
Chris Lattnerc6495ee2001-09-14 03:56:45 +000020
Chris Lattnerf6e0e282001-09-14 04:32:55 +000021class UltraSparc;
22
Chris Lattnerc6495ee2001-09-14 03:56:45 +000023// OpCodeMask definitions for the Sparc V9
24//
25const OpCodeMask Immed = 0x00002000; // immed or reg operand?
26const OpCodeMask Annul = 0x20000000; // annul delay instr?
27const OpCodeMask PredictTaken = 0x00080000; // predict branch taken?
28
29
30enum SparcInstrSchedClass {
31 SPARC_NONE, /* Instructions with no scheduling restrictions */
32 SPARC_IEUN, /* Integer class that can use IEU0 or IEU1 */
33 SPARC_IEU0, /* Integer class IEU0 */
34 SPARC_IEU1, /* Integer class IEU1 */
35 SPARC_FPM, /* FP Multiply or Divide instructions */
36 SPARC_FPA, /* All other FP instructions */
37 SPARC_CTI, /* Control-transfer instructions */
38 SPARC_LD, /* Load instructions */
39 SPARC_ST, /* Store instructions */
40 SPARC_SINGLE, /* Instructions that must issue by themselves */
41
42 SPARC_INV, /* This should stay at the end for the next value */
43 SPARC_NUM_SCHED_CLASSES = SPARC_INV
44};
45
Chris Lattnerc6495ee2001-09-14 03:56:45 +000046
47//---------------------------------------------------------------------------
48// enum SparcMachineOpCode.
49// const MachineInstrDescriptor SparcMachineInstrDesc[]
50//
51// Purpose:
52// Description of UltraSparc machine instructions.
53//
54//---------------------------------------------------------------------------
55
Chris Lattnerc6495ee2001-09-14 03:56:45 +000056enum SparcMachineOpCode {
57
58 NOP,
59
60 // Synthetic SPARC assembly opcodes for setting a register to a constant
61 SETSW,
62 SETUW,
63
64 // Set high-order bits of register and clear low-order bits
65 SETHI,
66
67 // Add or add with carry.
68 // Immed bit specifies if second operand is immediate(1) or register(0)
69 ADD,
70 ADDcc,
71 ADDC,
72 ADDCcc,
73
74 // Subtract or subtract with carry.
75 // Immed bit specifies if second operand is immediate(1) or register(0)
76 SUB,
77 SUBcc,
78 SUBC,
79 SUBCcc,
80
81 // Integer multiply, signed divide, unsigned divide.
82 // Note that the deprecated 32-bit multiply and multiply-step are not used.
83 MULX,
84 SDIVX,
85 UDIVX,
86
87 // Floating point add, subtract, compare
88 FADDS,
89 FADDD,
90 FADDQ,
91 FSUBS,
92 FSUBD,
93 FSUBQ,
94 FCMPS,
95 FCMPD,
96 FCMPQ,
97 // NOTE: FCMPE{S,D,Q}: FP Compare With Exception are currently unused!
98
99 // Floating point multiply or divide.
100 FMULS,
101 FMULD,
102 FMULQ,
103 FSMULD,
104 FDMULQ,
105 FDIVS,
106 FDIVD,
107 FDIVQ,
108 FSQRTS,
109 FSQRTD,
110 FSQRTQ,
111
112 // Logical operations
113 AND,
114 ANDcc,
115 ANDN,
116 ANDNcc,
117 OR,
118 ORcc,
119 ORN,
120 ORNcc,
121 XOR,
122 XORcc,
123 XNOR,
124 XNORcc,
125
126 // Shift operations
127 SLL,
128 SRL,
129 SRA,
130 SLLX,
131 SRLX,
132 SRAX,
133
134 // Floating point move, negate, and abs instructions
135 FMOVS,
136 FMOVD,
137//FMOVQ,
138 FNEGS,
139 FNEGD,
140//FNEGQ,
141 FABSS,
142 FABSD,
143//FABSQ,
144
145 // Convert from floating point to floating point formats
146 FSTOD,
147 FSTOQ,
148 FDTOS,
149 FDTOQ,
150 FQTOS,
151 FQTOD,
152
153 // Convert from floating point to integer formats
154 FSTOX,
155 FDTOX,
156 FQTOX,
157 FSTOI,
158 FDTOI,
159 FQTOI,
160
161 // Convert from integer to floating point formats
162 FXTOS,
163 FXTOD,
164 FXTOQ,
165 FITOS,
166 FITOD,
167 FITOQ,
168
169 // Branch on integer comparison with zero.
170 // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
171 // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
172 BRZ,
173 BRLEZ,
174 BRLZ,
175 BRNZ,
176 BRGZ,
177 BRGEZ,
178
179 // Branch on integer condition code.
180 // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
181 // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
182 BA,
183 BN,
184 BNE,
185 BE,
186 BG,
187 BLE,
188 BGE,
189 BL,
190 BGU,
191 BLEU,
192 BCC,
193 BCS,
194 BPOS,
195 BNEG,
196 BVC,
197 BVS,
198
199 // Branch on floating point condition code.
200 // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
201 // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
202 FBA,
203 FBN,
204 FBU,
205 FBG,
206 FBUG,
207 FBL,
208 FBUL,
209 FBLG,
210 FBNE,
211 FBE,
212 FBUE,
213 FBGE,
214 FBUGE,
215 FBLE,
216 FBULE,
217 FBO,
218
219 // Conditional move on integer comparison with zero.
220 MOVRZ,
221 MOVRLEZ,
222 MOVRLZ,
223 MOVRNZ,
224 MOVRGZ,
225 MOVRGEZ,
226
227 // Conditional move on integer condition code.
228 MOVA,
229 MOVN,
230 MOVNE,
231 MOVE,
232 MOVG,
233 MOVLE,
234 MOVGE,
235 MOVL,
236 MOVGU,
237 MOVLEU,
238 MOVCC,
239 MOVCS,
240 MOVPOS,
241 MOVNEG,
242 MOVVC,
243 MOVVS,
244
245 // Conditional move on floating point condition code.
246 // Note that the enum name is not the same as the assembly mnemonic below
247 // because that would duplicate some entries with those above.
248 // Therefore, we use MOVF here instead of MOV.
249 MOVFA,
250 MOVFN,
251 MOVFU,
252 MOVFG,
253 MOVFUG,
254 MOVFL,
255 MOVFUL,
256 MOVFLG,
257 MOVFNE,
258 MOVFE,
259 MOVFUE,
260 MOVFGE,
261 MOVFUGE,
262 MOVFLE,
263 MOVFULE,
264 MOVFO,
265
266 // Conditional move of floating point register on each of the above:
267 // i. on integer comparison with zero.
268 // ii. on integer condition code
269 // iii. on floating point condition code
270 // Note that the same set is repeated for S,D,Q register classes.
271 FMOVRSZ,
272 FMOVRSLEZ,
273 FMOVRSLZ,
274 FMOVRSNZ,
275 FMOVRSGZ,
276 FMOVRSGEZ,
277
278 FMOVSA,
279 FMOVSN,
280 FMOVSNE,
281 FMOVSE,
282 FMOVSG,
283 FMOVSLE,
284 FMOVSGE,
285 FMOVSL,
286 FMOVSGU,
287 FMOVSLEU,
288 FMOVSCC,
289 FMOVSCS,
290 FMOVSPOS,
291 FMOVSNEG,
292 FMOVSVC,
293 FMOVSVS,
294
295 FMOVSFA,
296 FMOVSFN,
297 FMOVSFU,
298 FMOVSFG,
299 FMOVSFUG,
300 FMOVSFL,
301 FMOVSFUL,
302 FMOVSFLG,
303 FMOVSFNE,
304 FMOVSFE,
305 FMOVSFUE,
306 FMOVSFGE,
307 FMOVSFUGE,
308 FMOVSFLE,
309 FMOVSFULE,
310 FMOVSFO,
311
312 FMOVRDZ,
313 FMOVRDLEZ,
314 FMOVRDLZ,
315 FMOVRDNZ,
316 FMOVRDGZ,
317 FMOVRDGEZ,
318
319 FMOVDA,
320 FMOVDN,
321 FMOVDNE,
322 FMOVDE,
323 FMOVDG,
324 FMOVDLE,
325 FMOVDGE,
326 FMOVDL,
327 FMOVDGU,
328 FMOVDLEU,
329 FMOVDCC,
330 FMOVDCS,
331 FMOVDPOS,
332 FMOVDNEG,
333 FMOVDVC,
334 FMOVDVS,
335
336 FMOVDFA,
337 FMOVDFN,
338 FMOVDFU,
339 FMOVDFG,
340 FMOVDFUG,
341 FMOVDFL,
342 FMOVDFUL,
343 FMOVDFLG,
344 FMOVDFNE,
345 FMOVDFE,
346 FMOVDFUE,
347 FMOVDFGE,
348 FMOVDFUGE,
349 FMOVDFLE,
350 FMOVDFULE,
351 FMOVDFO,
352
353 FMOVRQZ,
354 FMOVRQLEZ,
355 FMOVRQLZ,
356 FMOVRQNZ,
357 FMOVRQGZ,
358 FMOVRQGEZ,
359
360 FMOVQA,
361 FMOVQN,
362 FMOVQNE,
363 FMOVQE,
364 FMOVQG,
365 FMOVQLE,
366 FMOVQGE,
367 FMOVQL,
368 FMOVQGU,
369 FMOVQLEU,
370 FMOVQCC,
371 FMOVQCS,
372 FMOVQPOS,
373 FMOVQNEG,
374 FMOVQVC,
375 FMOVQVS,
376
377 FMOVQFA,
378 FMOVQFN,
379 FMOVQFU,
380 FMOVQFG,
381 FMOVQFUG,
382 FMOVQFL,
383 FMOVQFUL,
384 FMOVQFLG,
385 FMOVQFNE,
386 FMOVQFE,
387 FMOVQFUE,
388 FMOVQFGE,
389 FMOVQFUGE,
390 FMOVQFLE,
391 FMOVQFULE,
392 FMOVQFO,
393
394 // Load integer instructions
395 LDSB,
396 LDSH,
397 LDSW,
398 LDUB,
399 LDUH,
400 LDUW,
401 LDX,
402
403 // Load floating-point instructions
404 LD,
405 LDD, // use of this for integers is deprecated for Sparc V9
406 LDQ,
407
408 // Store integer instructions
409 STB,
410 STH,
411 STW,
412 STX,
413
414 // Store floating-point instructions
415 ST,
416 STD,
417
418 // Call, Return, and "Jump and link"
419 // Immed bit specifies if second operand is immediate(1) or register(0)
420 CALL,
421 JMPL,
422 RETURN, // last valid opcode
423
424 // Synthetic phi operation for near-SSA form of machine code
425 PHI,
426
427 // End-of-array marker
428 INVALID_OPCODE,
429 NUM_REAL_OPCODES = RETURN+1, // number of valid opcodes
430 NUM_TOTAL_OPCODES = INVALID_OPCODE
431};
432
433const MachineInstrDescriptor SparcMachineInstrDesc[] = {
434
435 // Fields of each structure:
436 // opCodeString,
437 // numOperands,
438 // resultPosition (0-based; -1 if no result),
439 // maxImmedConst,
440 // immedIsSignExtended,
441 // numDelaySlots (in cycles)
442 // latency (in cycles)
443 // instr sched class (defined above)
444 // instr class flags (defined in TargretMachine.h)
445
446 { "NOP", 0, -1, 0, false, 0, 1, SPARC_NONE, M_NOP_FLAG },
447
448 // Synthetic SPARC assembly opcodes for setting a register to a constant.
449 // Max immediate constant should be ignored for both these instructions.
450 { "SETSW", 2, 1, 0, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG },
451 { "SETUW", 2, 1, 0, false, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG | M_ARITH_FLAG },
452
453 // Set high-order bits of register and clear low-order bits
454 { "SETHI", 2, 1, (1 << 22) - 1, false, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG | M_ARITH_FLAG },
455
456 // Add or add with carry.
457 { "ADD", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG },
458 { "ADDcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG },
459 { "ADDC", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG },
460 { "ADDCcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG },
461
462 // Sub tract or subtract with carry.
463 { "SUB", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG },
464 { "SUBcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG },
465 { "SUBC", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG },
466 { "SUBCcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG },
467
468 // Integer multiply, signed divide, unsigned divide.
469 // Note that the deprecated 32-bit multiply and multiply-step are not used.
470 { "MULX", 3, 2, (1 << 12) - 1, true, 0, 3, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG },
471 { "SDIVX", 3, 2, (1 << 12) - 1, true, 0, 6, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG },
472 { "UDIVX", 3, 2, (1 << 12) - 1, true, 0, 6, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG },
473
474 // Floating point add, subtract, compare.
475 // Note that destination of FCMP* instructions is operand 0, not operand 2.
476 { "FADDS", 3, 2, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
477 { "FADDD", 3, 2, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
478 { "FADDQ", 3, 2, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
479 { "FSUBS", 3, 2, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
480 { "FSUBD", 3, 2, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
481 { "FSUBQ", 3, 2, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
482 { "FCMPS", 3, 0, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
483 { "FCMPD", 3, 0, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
484 { "FCMPQ", 3, 0, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
485 // NOTE: FCMPE{S,D,Q}: FP Compare With Exception are currently unused!
486
487 // Floating point multiply or divide.
488 { "FMULS", 3, 2, 0, false, 0, 3, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
489 { "FMULD", 3, 2, 0, false, 0, 3, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
490 { "FMULQ", 3, 2, 0, false, 0, 0, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
491 { "FSMULD", 3, 2, 0, false, 0, 3, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
492 { "FDMULQ", 3, 2, 0, false, 0, 0, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
493 { "FDIVS", 3, 2, 0, false, 0, 12, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
494 { "FDIVD", 3, 2, 0, false, 0, 22, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
495 { "FDIVQ", 3, 2, 0, false, 0, 0, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
496 { "FSQRTS", 3, 2, 0, false, 0, 12, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
497 { "FSQRTD", 3, 2, 0, false, 0, 22, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
498 { "FSQRTQ", 3, 2, 0, false, 0, 0, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG },
499
500 // Logical operations
501 { "AND", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG},
502 { "ANDcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG},
503 { "ANDN", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG},
504 { "ANDNcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG},
505 { "OR", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG},
506 { "ORcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG},
507 { "ORN", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG},
508 { "ORNcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG},
509 { "XOR", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG},
510 { "XORcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG},
511 { "XNOR", 3, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG},
512 { "XNORcc", 4, 2, (1 << 12) - 1, true, 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG},
513
514 // Shift operations
515 { "SLL", 3, 2, (1 << 5) - 1, true, 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG},
516 { "SRL", 3, 2, (1 << 5) - 1, true, 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG},
517 { "SRA", 3, 2, (1 << 5) - 1, true, 0, 1, SPARC_IEU0, M_INT_FLAG | M_ARITH_FLAG },
518 { "SLLX", 3, 2, (1 << 6) - 1, true, 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG},
519 { "SRLX", 3, 2, (1 << 6) - 1, true, 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG},
520 { "SRAX", 3, 2, (1 << 6) - 1, true, 0, 1, SPARC_IEU0, M_INT_FLAG | M_ARITH_FLAG },
521
522 // Floating point move, negate, and abs instructions
523 { "FMOVS", 2, 1, 0, false, 0, 1, SPARC_FPA, M_FLOAT_FLAG },
524 { "FMOVD", 2, 1, 0, false, 0, 1, SPARC_FPA, M_FLOAT_FLAG },
525//{ "FMOVQ", 2, 1, 0, false, 0, ?, SPARC_FPA, M_FLOAT_FLAG },
526 { "FNEGS", 2, 1, 0, false, 0, 1, SPARC_FPA, M_FLOAT_FLAG },
527 { "FNEGD", 2, 1, 0, false, 0, 1, SPARC_FPA, M_FLOAT_FLAG },
528//{ "FNEGQ", 2, 1, 0, false, 0, ?, SPARC_FPA, M_FLOAT_FLAG },
529 { "FABSS", 2, 1, 0, false, 0, 1, SPARC_FPA, M_FLOAT_FLAG },
530 { "FABSD", 2, 1, 0, false, 0, 1, SPARC_FPA, M_FLOAT_FLAG },
531//{ "FABSQ", 2, 1, 0, false, 0, ?, SPARC_FPA, M_FLOAT_FLAG },
532
533 // Convert from floating point to floating point formats
534 { "FSTOD", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
535 { "FSTOQ", 2, 1, 0, false, 0, 0, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
536 { "FDTOS", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
537 { "FDTOQ", 2, 1, 0, false, 0, 0, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
538 { "FQTOS", 2, 1, 0, false, 0, 0, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
539 { "FQTOD", 2, 1, 0, false, 0, 0, SPARC_FPA, M_FLOAT_FLAG | M_ARITH_FLAG },
540
541 // Convert from floating point to integer formats.
542 // Note that this accesses both integer and floating point registers.
543 { "FSTOX", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
544 { "FDTOX", 2, 1, 0, false, 0, 0, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
545 { "FQTOX", 2, 1, 0, false, 0, 2, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
546 { "FSTOI", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
547 { "FDTOI", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
548 { "FQTOI", 2, 1, 0, false, 0, 0, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
549
550 // Convert from integer to floating point formats
551 // Note that this accesses both integer and floating point registers.
552 { "FXTOS", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
553 { "FXTOD", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
554 { "FXTOQ", 2, 1, 0, false, 0, 0, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
555 { "FITOS", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
556 { "FITOD", 2, 1, 0, false, 0, 3, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
557 { "FITOQ", 2, 1, 0, false, 0, 0, SPARC_FPA, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
558
559 // Branch on integer comparison with zero.
560 // Latency includes the delay slot.
561 { "BRZ", 2, -1, (1 << 15) - 1, true, 1, 2, SPARC_CTI, M_INT_FLAG | M_BRANCH_FLAG },
562 { "BRLEZ", 2, -1, (1 << 15) - 1, true, 1, 2, SPARC_CTI, M_INT_FLAG | M_BRANCH_FLAG },
563 { "BRLZ", 2, -1, (1 << 15) - 1, true, 1, 2, SPARC_CTI, M_INT_FLAG | M_BRANCH_FLAG },
564 { "BRNZ", 2, -1, (1 << 15) - 1, true, 1, 2, SPARC_CTI, M_INT_FLAG | M_BRANCH_FLAG },
565 { "BRGZ", 2, -1, (1 << 15) - 1, true, 1, 2, SPARC_CTI, M_INT_FLAG | M_BRANCH_FLAG },
566 { "BRGEZ", 2, -1, (1 << 15) - 1, true, 1, 2, SPARC_CTI, M_INT_FLAG | M_BRANCH_FLAG },
567
568 // Branch on condition code.
569 // The first argument specifies the ICC register: %icc or %xcc
570 // Latency includes the delay slot.
571 { "BA", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
572 { "BN", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
573 { "BNE", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
574 { "BE", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
575 { "BG", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
576 { "BLE", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
577 { "BGE", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
578 { "BL", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
579 { "BGU", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
580 { "BLEU", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
581 { "BCC", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
582 { "BCS", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
583 { "BPOS", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
584 { "BNEG", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
585 { "BVC", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
586 { "BVS", 2, -1, (1 << 21) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
587
588 // Branch on floating point condition code.
589 // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
590 // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
591 // The first argument is the FCCn register (0 <= n <= 3).
592 // Latency includes the delay slot.
593 { "FBA", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
594 { "FBN", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
595 { "FBU", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
596 { "FBG", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
597 { "FBUG", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
598 { "FBL", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
599 { "FBUL", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
600 { "FBLG", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
601 { "FBNE", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
602 { "FBE", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
603 { "FBUE", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
604 { "FBGE", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
605 { "FBUGE", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
606 { "FBLE", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
607 { "FBULE", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
608 { "FBO", 2, -1, (1 << 18) - 1, true, 1, 2, SPARC_CTI, M_CC_FLAG | M_BRANCH_FLAG },
609
610 // Conditional move on integer comparison with zero.
611 { "MOVRZ", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_INT_FLAG },
612 { "MOVRLEZ", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_INT_FLAG },
613 { "MOVRLZ", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_INT_FLAG },
614 { "MOVRNZ", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_INT_FLAG },
615 { "MOVRGZ", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_INT_FLAG },
616 { "MOVRGEZ", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_INT_FLAG },
617
618 // Conditional move on integer condition code.
619 // The first argument specifies the ICC register: %icc or %xcc
620 { "MOVA", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
621 { "MOVN", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
622 { "MOVNE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
623 { "MOVE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
624 { "MOVG", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
625 { "MOVLE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
626 { "MOVGE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
627 { "MOVL", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
628 { "MOVGU", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
629 { "MOVLEU", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
630 { "MOVCC", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
631 { "MOVCS", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
632 { "MOVPOS", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
633 { "MOVNEG", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
634 { "MOVVC", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
635 { "MOVVS", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
636
637 // Conditional move (of integer register) on floating point condition code.
638 // The first argument is the FCCn register (0 <= n <= 3).
639 // Note that the enum name above is not the same as the assembly mnemonic
640 // because some of the assembly mnemonics are the same as the move on
641 // integer CC (e.g., MOVG), and we cannot have the same enum entry twice.
642 { "MOVA", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
643 { "MOVN", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
644 { "MOVU", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
645 { "MOVG", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
646 { "MOVUG", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
647 { "MOVL", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
648 { "MOVUL", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
649 { "MOVLG", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
650 { "MOVNE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
651 { "MOVE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
652 { "MOVUE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
653 { "MOVGE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
654 { "MOVUGE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
655 { "MOVLE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
656 { "MOVULE", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
657 { "MOVO", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_INT_FLAG },
658
659 // Conditional move of floating point register on each of the above:
660 // i. on integer comparison with zero.
661 // ii. on integer condition code
662 // iii. on floating point condition code
663 // Note that the same set is repeated for S,D,Q register classes.
664 { "FMOVRSZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
665 { "FMOVRSLEZ",3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
666 { "FMOVRSLZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
667 { "FMOVRSNZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
668 { "FMOVRSGZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
669 { "FMOVRSGEZ",3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
670
671 { "FMOVSA", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
672 { "FMOVSN", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
673 { "FMOVSNE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
674 { "FMOVSE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
675 { "FMOVSG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
676 { "FMOVSLE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
677 { "FMOVSGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
678 { "FMOVSL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
679 { "FMOVSGU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
680 { "FMOVSLEU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
681 { "FMOVSCC", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
682 { "FMOVSCS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
683 { "FMOVSPOS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
684 { "FMOVSNEG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
685 { "FMOVSVC", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
686 { "FMOVSVS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
687
688 { "FMOVSA", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
689 { "FMOVSN", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
690 { "FMOVSU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
691 { "FMOVSG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
692 { "FMOVSUG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
693 { "FMOVSL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
694 { "FMOVSUL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
695 { "FMOVSLG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
696 { "FMOVSNE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
697 { "FMOVSE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
698 { "FMOVSUE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
699 { "FMOVSGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
700 { "FMOVSUGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
701 { "FMOVSLE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
702 { "FMOVSULE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
703 { "FMOVSO", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
704
705 { "FMOVRDZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
706 { "FMOVRDLEZ",3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
707 { "FMOVRDLZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
708 { "FMOVRDNZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
709 { "FMOVRDGZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
710 { "FMOVRDGEZ",3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
711
712 { "FMOVDA", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
713 { "FMOVDN", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
714 { "FMOVDNE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
715 { "FMOVDE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
716 { "FMOVDG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
717 { "FMOVDLE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
718 { "FMOVDGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
719 { "FMOVDL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
720 { "FMOVDGU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
721 { "FMOVDLEU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
722 { "FMOVDCC", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
723 { "FMOVDCS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
724 { "FMOVDPOS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
725 { "FMOVDNEG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
726 { "FMOVDVC", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
727 { "FMOVDVS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
728
729 { "FMOVDA", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
730 { "FMOVDN", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
731 { "FMOVDU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
732 { "FMOVDG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
733 { "FMOVDUG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
734 { "FMOVDL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
735 { "FMOVDUL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
736 { "FMOVDLG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
737 { "FMOVDNE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
738 { "FMOVDE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
739 { "FMOVDUE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
740 { "FMOVDGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
741 { "FMOVDUGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
742 { "FMOVDLE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
743 { "FMOVDULE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
744 { "FMOVDO", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
745
746 { "FMOVRQZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
747 { "FMOVRQLEZ",3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
748 { "FMOVRQLZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
749 { "FMOVRQNZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
750 { "FMOVRQGZ", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
751 { "FMOVRQGEZ",3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CONDL_FLAG | M_FLOAT_FLAG | M_INT_FLAG },
752
753 { "FMOVQA", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
754 { "FMOVQN", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
755 { "FMOVQNE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
756 { "FMOVQE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
757 { "FMOVQG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
758 { "FMOVQLE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
759 { "FMOVQGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
760 { "FMOVQL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
761 { "FMOVQGU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
762 { "FMOVQLEU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
763 { "FMOVQCC", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
764 { "FMOVQCS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
765 { "FMOVQPOS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
766 { "FMOVQNEG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
767 { "FMOVQVC", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
768 { "FMOVQVS", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
769
770 { "FMOVQA", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
771 { "FMOVQN", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
772 { "FMOVQU", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
773 { "FMOVQG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
774 { "FMOVQUG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
775 { "FMOVQL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
776 { "FMOVQUL", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
777 { "FMOVQLG", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
778 { "FMOVQNE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
779 { "FMOVQE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
780 { "FMOVQUE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
781 { "FMOVQGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
782 { "FMOVQUGE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
783 { "FMOVQLE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
784 { "FMOVQULE", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
785 { "FMOVQO", 3, 2, 0, false, 0, 2, SPARC_SINGLE, M_CC_FLAG | M_FLOAT_FLAG },
786
787 // Load integer instructions
788 // Latency includes 1 cycle for address generation (Sparc IIi)
789 // Signed loads of less than 64 bits need an extra cycle for sign-extension.
790 //
791 // Not reflected here: After a 3-cycle loads, all subsequent consecutive
792 // loads also require 3 cycles to avoid contention for the load return
793 // stage. Latency returns to 2 cycles after the first cycle with no load.
794 { "LDSB", 3, 2, (1 << 12) - 1, true, 0, 3, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG },
795 { "LDSH", 3, 2, (1 << 12) - 1, true, 0, 3, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG },
796 { "LDSW", 3, 2, (1 << 12) - 1, true, 0, 3, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG },
797 { "LDUB", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG },
798 { "LDUH", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG },
799 { "LDUW", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG },
800 { "LDX", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG },
801
802 // Load floating-point instructions
803 // Latency includes 1 cycle for address generation (Sparc IIi)
804 { "LD", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG },
805 { "LDD", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG },
806 { "LDQ", 3, 2, (1 << 12) - 1, true, 0, 2, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG },
807
808 // Store integer instructions
809 // Latency includes 1 cycle for address generation (Sparc IIi)
810 { "STB", 3, -1, (1 << 12) - 1, true, 0, 2, SPARC_ST, M_INT_FLAG | M_STORE_FLAG },
811 { "STH", 3, -1, (1 << 12) - 1, true, 0, 2, SPARC_ST, M_INT_FLAG | M_STORE_FLAG },
812 { "STW", 3, -1, (1 << 12) - 1, true, 0, 2, SPARC_ST, M_INT_FLAG | M_STORE_FLAG },
813 { "STX", 3, -1, (1 << 12) - 1, true, 0, 3, SPARC_ST, M_INT_FLAG | M_STORE_FLAG },
814
815 // Store floating-point instructions (Sparc IIi)
816 { "ST", 3, -1, (1 << 12) - 1, true, 0, 2, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG},
817 { "STD", 3, -1, (1 << 12) - 1, true, 0, 2, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG},
818
819 // Call, Return and "Jump and link".
820 // Latency includes the delay slot.
821 { "CALL", 1, -1, (1 << 29) - 1, true, 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_CALL_FLAG},
822 { "JMPL", 3, -1, (1 << 12) - 1, true, 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_CALL_FLAG},
823 { "RETURN", 2, -1, 0, false, 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_RET_FLAG },
824
825 // Synthetic phi operation for near-SSA form of machine code
826 // Number of operands is variable, indicated by -1. Result is the first op.
827
828 { "PHI", -1, 0, 0, false, 0, 0, SPARC_INV, M_DUMMY_PHI_FLAG },
829
830};
831
832
833
834//---------------------------------------------------------------------------
835// class UltraSparcInstrInfo
836//
837// Purpose:
838// Information about individual instructions.
839// Most information is stored in the SparcMachineInstrDesc array above.
840// Other information is computed on demand, and most such functions
841// default to member functions in base class MachineInstrInfo.
842//---------------------------------------------------------------------------
843
844class UltraSparcInstrInfo : public MachineInstrInfo {
845public:
846 /*ctor*/ UltraSparcInstrInfo();
847
848 virtual bool hasResultInterlock (MachineOpCode opCode)
849 {
850 // All UltraSPARC instructions have interlocks (note that delay slots
851 // are not considered here).
852 // However, instructions that use the result of an FCMP produce a
853 // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
854 // Force the compiler to insert a software interlock (i.e., gap of
855 // 2 other groups, including NOPs if necessary).
856 return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ);
857 }
858
859};
860
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000861
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000862
863class LiveRange;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000864class UltraSparc;
865
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000866
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000867
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000868class UltraSparcRegInfo : public MachineRegInfo
869{
870
871 private:
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000872
873 enum RegClassIDs {
874 IntRegClassID,
875 FloatRegClassID,
876 IntCCRegClassID,
877 FloatCCRegClassID
878 };
879
880 // WARNING: If the above enum order must be changed, also modify
881 // getRegisterClassOfValue method below since it assumes this particular
882 // order for efficiency.
883
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000884
885 // reverse pointer to get info about the ultra sparc machine
886 const UltraSparc *const UltraSparcInfo;
887
888 // Int arguments can be passed in 6 int regs - %o0 to %o5 (cannot be changed)
889 unsigned const NumOfIntArgRegs;
890
891 // Float arguments can be passed in this many regs - can be canged if needed
892 // %f0 - %f5 are used (can hold 6 floats or 3 doubles)
893 unsigned const NumOfFloatArgRegs;
894
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000895 //void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
896
897 void setCallOrRetArgCol(LiveRange *const LR, const unsigned RegNo,
898 const MachineInstr *MI,AddedInstrMapType &AIMap)const;
899
900 MachineInstr * getCopy2RegMI(const Value *SrcVal, const unsigned Reg,
901 unsigned RegClassID) const ;
902
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000903
904
905 public:
906
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000907
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000908 UltraSparcRegInfo(const UltraSparc *const USI ) : UltraSparcInfo(USI),
909 NumOfIntArgRegs(6),
910 NumOfFloatArgRegs(6)
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000911 {
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000912 MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
913 MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000914 MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
915 MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000916
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000917 assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 6 &&
918 "6 Float regs are used for float arg passing");
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000919 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000920
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000921 // ***** TODO Delete
922 ~UltraSparcRegInfo(void) { } // empty destructor
923
924
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000925 inline const UltraSparc & getUltraSparcInfo() const {
926 return *UltraSparcInfo;
927 }
928
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000929
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000930
931 inline unsigned getRegClassIDOfValue (const Value *const Val,
932 bool isCCReg = false) const {
933
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000934 Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000935
936 unsigned res;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000937
938 if( ty && ty <= Type::LongTyID || (ty == Type::PointerTyID) )
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000939 res = IntRegClassID; // sparc int reg (ty=0: void)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000940 else if( ty <= Type::DoubleTyID)
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000941 res = FloatRegClassID; // sparc float reg class
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000942 else {
943 cout << "TypeID: " << ty << endl;
944 assert(0 && "Cannot resolve register class for type");
945
946 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000947
948 if(isCCReg)
949 return res + 2; // corresponidng condition code regiser
950
951 else
952 return res;
953
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000954 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000955
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000956 // returns the register tha contains always zero
957 inline int getZeroRegNum() const { return SparcIntRegOrder::g0; }
958
959 // returns the reg used for pushing the address when a method is called.
960 // This can be used for other purposes between calls
961 unsigned getCallAddressReg() const { return SparcIntRegOrder::o7; }
962
963
964 // and when we return from a method. It should be made sure that this
965 // register contains the return value when a return instruction is reached.
966 unsigned getReturnAddressReg() const { return SparcIntRegOrder::i7; }
967
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000968 void colorArgs(const Method *const Meth, LiveRangeInfo& LRI) const;
969
970 static void printReg(const LiveRange *const LR) ;
971
972 void colorCallArgs(vector<const Instruction *> & CallInstrList,
973 LiveRangeInfo& LRI,
974 AddedInstrMapType& AddedInstrMap ) const;
975
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000976 void colorRetArg(vector<const Instruction *> &
977 RetInstrList, LiveRangeInfo& LRI,
978 AddedInstrMapType &AddedInstrMap) const;
979
980
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000981 // this method provides a unique number for each register
982 inline int getUnifiedRegNum(int RegClassID, int reg) const {
983
984 if( RegClassID == IntRegClassID && reg < 32 )
985 return reg;
986 else if ( RegClassID == FloatRegClassID && reg < 64)
987 return reg + 32; // we have 32 int regs
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000988 else if( RegClassID == FloatCCRegClassID && reg < 4)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000989 return reg + 32 + 64; // 32 int, 64 float
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000990 else if( RegClassID == IntCCRegClassID )
991 return 4+ 32 + 64; // only int cc reg
992 else
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000993 assert(0 && "Invalid register class or reg number");
994
995 }
996
997 // given the unified register number, this gives the name
998 inline const string getUnifiedRegName(int reg) const {
999
1000 if( reg < 32 )
1001 return SparcIntRegOrder::getRegName(reg);
1002 else if ( reg < (64 + 32) )
1003 return SparcFloatRegOrder::getRegName( reg - 32);
1004 else if( reg < (64+32+4) )
Ruchira Sasankae38bd5332001-09-15 00:30:44 +00001005 return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
1006 else if ( reg == 64+32+4)
1007 return "xcc"; // only integer cc reg
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001008 else
1009 assert(0 && "Invalid register number");
1010 }
1011
1012
1013};
1014
1015
1016
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001017/*---------------------------------------------------------------------------
1018Scheduling guidelines for SPARC IIi:
1019
1020I-Cache alignment rules (pg 326)
1021-- Align a branch target instruction so that it's entire group is within
1022 the same cache line (may be 1-4 instructions).
1023** Don't let a branch that is predicted taken be the last instruction
1024 on an I-cache line: delay slot will need an entire line to be fetched
1025-- Make a FP instruction or a branch be the 4th instruction in a group.
1026 For branches, there are tradeoffs in reordering to make this happen
1027 (see pg. 327).
1028** Don't put a branch in a group that crosses a 32-byte boundary!
1029 An artificial branch is inserted after every 32 bytes, and having
1030 another branch will force the group to be broken into 2 groups.
1031
1032iTLB rules:
1033-- Don't let a loop span two memory pages, if possible
1034
1035Branch prediction performance:
1036-- Don't make the branch in a delay slot the target of a branch
1037-- Try not to have 2 predicted branches within a group of 4 instructions
1038 (because each such group has a single branch target field).
1039-- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
1040 the wrong prediction bits being used in some cases).
1041
1042D-Cache timing constraints:
1043-- Signed int loads of less than 64 bits have 3 cycle latency, not 2
1044-- All other loads that hit in D-Cache have 2 cycle latency
1045-- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
1046-- Mis-aligned loads or stores cause a trap. In particular, replace
1047 mis-aligned FP double precision l/s with 2 single-precision l/s.
1048-- Simulations of integer codes show increase in avg. group size of
1049 33% when code (including esp. non-faulting loads) is moved across
1050 one branch, and 50% across 2 branches.
1051
1052E-Cache timing constraints:
1053-- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
1054
1055Store buffer timing constraints:
1056-- Stores can be executed in same cycle as instruction producing the value
1057-- Stores are buffered and have lower priority for E-cache until
1058 highwater mark is reached in the store buffer (5 stores)
1059
1060Pipeline constraints:
1061-- Shifts can only use IEU0.
1062-- CC setting instructions can only use IEU1.
1063-- Several other instructions must only use IEU1:
1064 EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
1065-- Two instructions cannot store to the same register file in a single cycle
1066 (single write port per file).
1067
1068Issue and grouping constraints:
1069-- FP and branch instructions must use slot 4.
1070-- Shift instructions cannot be grouped with other IEU0-specific instructions.
1071-- CC setting instructions cannot be grouped with other IEU1-specific instrs.
1072-- Several instructions must be issued in a single-instruction group:
1073 MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
1074-- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
1075--
1076--
1077
1078Branch delay slot scheduling rules:
1079-- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
1080 has a 9-instruction penalty: the entire pipeline is flushed when the
1081 second instruction reaches stage 9 (W-Writeback).
1082-- Avoid putting multicycle instructions, and instructions that may cause
1083 load misses, in the delay slot of an annulling branch.
1084-- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
1085 delay slot of an annulling branch.
1086
1087 *--------------------------------------------------------------------------- */
1088
1089//---------------------------------------------------------------------------
1090// List of CPUResources for UltraSPARC IIi.
1091//---------------------------------------------------------------------------
1092
1093const CPUResource AllIssueSlots( "All Instr Slots", 4);
1094const CPUResource IntIssueSlots( "Int Instr Slots", 3);
1095const CPUResource First3IssueSlots("Instr Slots 0-3", 3);
1096const CPUResource LSIssueSlots( "Load-Store Instr Slot", 1);
1097const CPUResource CTIIssueSlots( "Ctrl Transfer Instr Slot", 1);
1098const CPUResource FPAIssueSlots( "Int Instr Slot 1", 1);
1099const CPUResource FPMIssueSlots( "Int Instr Slot 1", 1);
1100
1101// IEUN instructions can use either Alu and should use IAluN.
1102// IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0.
1103// IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1.
1104const CPUResource IAluN("Int ALU 1or2", 2);
1105const CPUResource IAlu0("Int ALU 1", 1);
1106const CPUResource IAlu1("Int ALU 2", 1);
1107
1108const CPUResource LSAluC1("Load/Store Unit Addr Cycle", 1);
1109const CPUResource LSAluC2("Load/Store Unit Issue Cycle", 1);
1110const CPUResource LdReturn("Load Return Unit", 1);
1111
1112const CPUResource FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
1113const CPUResource FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
1114const CPUResource FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
1115
1116const CPUResource FPAAluC1("FP Other Alu Cycle 1", 1);
1117const CPUResource FPAAluC2("FP Other Alu Cycle 2", 1);
1118const CPUResource FPAAluC3("FP Other Alu Cycle 3", 1);
1119
1120const CPUResource IRegReadPorts("Int Reg ReadPorts", INT_MAX); // CHECK
1121const CPUResource IRegWritePorts("Int Reg WritePorts", 2); // CHECK
1122const CPUResource FPRegReadPorts("FP Reg Read Ports", INT_MAX); // CHECK
1123const CPUResource FPRegWritePorts("FP Reg Write Ports", 1); // CHECK
1124
1125const CPUResource CTIDelayCycle( "CTI delay cycle", 1);
1126const CPUResource FCMPDelayCycle("FCMP delay cycle", 1);
1127
1128
1129//---------------------------------------------------------------------------
1130// const InstrClassRUsage SparcRUsageDesc[]
1131//
1132// Purpose:
1133// Resource usage information for instruction in each scheduling class.
1134// The InstrRUsage Objects for individual classes are specified first.
1135// Note that fetch and decode are decoupled from the execution pipelines
1136// via an instr buffer, so they are not included in the cycles below.
1137//---------------------------------------------------------------------------
1138
1139const InstrClassRUsage NoneClassRUsage = {
1140 SPARC_NONE,
1141 /*totCycles*/ 7,
1142
1143 /* maxIssueNum */ 4,
1144 /* isSingleIssue */ false,
1145 /* breaksGroup */ false,
1146 /* numBubbles */ 0,
1147
1148 /*numSlots*/ 4,
1149 /* feasibleSlots[] */ { 0, 1, 2, 3 },
1150
1151 /*numEntries*/ 0,
1152 /* V[] */ {
1153 /*Cycle G */
1154 /*Cycle E */
1155 /*Cycle C */
1156 /*Cycle N1*/
1157 /*Cycle N1*/
1158 /*Cycle N1*/
1159 /*Cycle W */
1160 }
1161};
1162
1163const InstrClassRUsage IEUNClassRUsage = {
1164 SPARC_IEUN,
1165 /*totCycles*/ 7,
1166
1167 /* maxIssueNum */ 3,
1168 /* isSingleIssue */ false,
1169 /* breaksGroup */ false,
1170 /* numBubbles */ 0,
1171
1172 /*numSlots*/ 3,
1173 /* feasibleSlots[] */ { 0, 1, 2 },
1174
1175 /*numEntries*/ 4,
1176 /* V[] */ {
1177 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1178 { IntIssueSlots.rid, 0, 1 },
1179 /*Cycle E */ { IAluN.rid, 1, 1 },
1180 /*Cycle C */
1181 /*Cycle N1*/
1182 /*Cycle N1*/
1183 /*Cycle N1*/
1184 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
1185 }
1186};
1187
1188const InstrClassRUsage IEU0ClassRUsage = {
1189 SPARC_IEU0,
1190 /*totCycles*/ 7,
1191
1192 /* maxIssueNum */ 1,
1193 /* isSingleIssue */ false,
1194 /* breaksGroup */ false,
1195 /* numBubbles */ 0,
1196
1197 /*numSlots*/ 3,
1198 /* feasibleSlots[] */ { 0, 1, 2 },
1199
1200 /*numEntries*/ 5,
1201 /* V[] */ {
1202 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1203 { IntIssueSlots.rid, 0, 1 },
1204 /*Cycle E */ { IAluN.rid, 1, 1 },
1205 { IAlu0.rid, 1, 1 },
1206 /*Cycle C */
1207 /*Cycle N1*/
1208 /*Cycle N1*/
1209 /*Cycle N1*/
1210 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
1211 }
1212};
1213
1214const InstrClassRUsage IEU1ClassRUsage = {
1215 SPARC_IEU1,
1216 /*totCycles*/ 7,
1217
1218 /* maxIssueNum */ 1,
1219 /* isSingleIssue */ false,
1220 /* breaksGroup */ false,
1221 /* numBubbles */ 0,
1222
1223 /*numSlots*/ 3,
1224 /* feasibleSlots[] */ { 0, 1, 2 },
1225
1226 /*numEntries*/ 5,
1227 /* V[] */ {
1228 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1229 { IntIssueSlots.rid, 0, 1 },
1230 /*Cycle E */ { IAluN.rid, 1, 1 },
1231 { IAlu1.rid, 1, 1 },
1232 /*Cycle C */
1233 /*Cycle N1*/
1234 /*Cycle N1*/
1235 /*Cycle N1*/
1236 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
1237 }
1238};
1239
1240const InstrClassRUsage FPMClassRUsage = {
1241 SPARC_FPM,
1242 /*totCycles*/ 7,
1243
1244 /* maxIssueNum */ 1,
1245 /* isSingleIssue */ false,
1246 /* breaksGroup */ false,
1247 /* numBubbles */ 0,
1248
1249 /*numSlots*/ 4,
1250 /* feasibleSlots[] */ { 0, 1, 2, 3 },
1251
1252 /*numEntries*/ 7,
1253 /* V[] */ {
1254 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1255 { FPMIssueSlots.rid, 0, 1 },
1256 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
1257 /*Cycle C */ { FPMAluC1.rid, 2, 1 },
1258 /*Cycle N1*/ { FPMAluC2.rid, 3, 1 },
1259 /*Cycle N1*/ { FPMAluC3.rid, 4, 1 },
1260 /*Cycle N1*/
1261 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
1262 }
1263};
1264
1265const InstrClassRUsage FPAClassRUsage = {
1266 SPARC_FPA,
1267 /*totCycles*/ 7,
1268
1269 /* maxIssueNum */ 1,
1270 /* isSingleIssue */ false,
1271 /* breaksGroup */ false,
1272 /* numBubbles */ 0,
1273
1274 /*numSlots*/ 4,
1275 /* feasibleSlots[] */ { 0, 1, 2, 3 },
1276
1277 /*numEntries*/ 7,
1278 /* V[] */ {
1279 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1280 { FPAIssueSlots.rid, 0, 1 },
1281 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
1282 /*Cycle C */ { FPAAluC1.rid, 2, 1 },
1283 /*Cycle N1*/ { FPAAluC2.rid, 3, 1 },
1284 /*Cycle N1*/ { FPAAluC3.rid, 4, 1 },
1285 /*Cycle N1*/
1286 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
1287 }
1288};
1289
1290const InstrClassRUsage LDClassRUsage = {
1291 SPARC_LD,
1292 /*totCycles*/ 7,
1293
1294 /* maxIssueNum */ 1,
1295 /* isSingleIssue */ false,
1296 /* breaksGroup */ false,
1297 /* numBubbles */ 0,
1298
1299 /*numSlots*/ 3,
1300 /* feasibleSlots[] */ { 0, 1, 2, },
1301
1302 /*numEntries*/ 6,
1303 /* V[] */ {
1304 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1305 { First3IssueSlots.rid, 0, 1 },
1306 { LSIssueSlots.rid, 0, 1 },
1307 /*Cycle E */ { LSAluC1.rid, 1, 1 },
1308 /*Cycle C */ { LSAluC2.rid, 2, 1 },
1309 { LdReturn.rid, 2, 1 },
1310 /*Cycle N1*/
1311 /*Cycle N1*/
1312 /*Cycle N1*/
1313 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
1314 }
1315};
1316
1317const InstrClassRUsage STClassRUsage = {
1318 SPARC_ST,
1319 /*totCycles*/ 7,
1320
1321 /* maxIssueNum */ 1,
1322 /* isSingleIssue */ false,
1323 /* breaksGroup */ false,
1324 /* numBubbles */ 0,
1325
1326 /*numSlots*/ 3,
1327 /* feasibleSlots[] */ { 0, 1, 2 },
1328
1329 /*numEntries*/ 4,
1330 /* V[] */ {
1331 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1332 { First3IssueSlots.rid, 0, 1 },
1333 { LSIssueSlots.rid, 0, 1 },
1334 /*Cycle E */ { LSAluC1.rid, 1, 1 },
1335 /*Cycle C */ { LSAluC2.rid, 2, 1 }
1336 /*Cycle N1*/
1337 /*Cycle N1*/
1338 /*Cycle N1*/
1339 /*Cycle W */
1340 }
1341};
1342
1343const InstrClassRUsage CTIClassRUsage = {
1344 SPARC_CTI,
1345 /*totCycles*/ 7,
1346
1347 /* maxIssueNum */ 1,
1348 /* isSingleIssue */ false,
1349 /* breaksGroup */ false,
1350 /* numBubbles */ 0,
1351
1352 /*numSlots*/ 4,
1353 /* feasibleSlots[] */ { 0, 1, 2, 3 },
1354
1355 /*numEntries*/ 4,
1356 /* V[] */ {
1357 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1358 { CTIIssueSlots.rid, 0, 1 },
1359 /*Cycle E */ { IAlu0.rid, 1, 1 },
1360 /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
1361 /*Cycle C */
1362 /*Cycle N1*/
1363 /*Cycle N1*/
1364 /*Cycle N1*/
1365 /*Cycle W */
1366 }
1367};
1368
1369const InstrClassRUsage SingleClassRUsage = {
1370 SPARC_SINGLE,
1371 /*totCycles*/ 7,
1372
1373 /* maxIssueNum */ 1,
1374 /* isSingleIssue */ true,
1375 /* breaksGroup */ false,
1376 /* numBubbles */ 0,
1377
1378 /*numSlots*/ 1,
1379 /* feasibleSlots[] */ { 0 },
1380
1381 /*numEntries*/ 5,
1382 /* V[] */ {
1383 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1384 { AllIssueSlots.rid, 0, 1 },
1385 { AllIssueSlots.rid, 0, 1 },
1386 { AllIssueSlots.rid, 0, 1 },
1387 /*Cycle E */ { IAlu0.rid, 1, 1 }
1388 /*Cycle C */
1389 /*Cycle N1*/
1390 /*Cycle N1*/
1391 /*Cycle N1*/
1392 /*Cycle W */
1393 }
1394};
1395
1396
1397const InstrClassRUsage SparcRUsageDesc[] = {
1398 NoneClassRUsage,
1399 IEUNClassRUsage,
1400 IEU0ClassRUsage,
1401 IEU1ClassRUsage,
1402 FPMClassRUsage,
1403 FPAClassRUsage,
1404 CTIClassRUsage,
1405 LDClassRUsage,
1406 STClassRUsage,
1407 SingleClassRUsage
1408};
1409
1410
1411//---------------------------------------------------------------------------
1412// const InstrIssueDelta SparcInstrIssueDeltas[]
1413//
1414// Purpose:
1415// Changes to issue restrictions information in InstrClassRUsage for
1416// instructions that differ from other instructions in their class.
1417//---------------------------------------------------------------------------
1418
1419const InstrIssueDelta SparcInstrIssueDeltas[] = {
1420
1421 // opCode, isSingleIssue, breaksGroup, numBubbles
1422
1423 // Special cases for single-issue only
1424 // Other single issue cases are below.
1425//{ LDDA, true, true, 0 },
1426//{ STDA, true, true, 0 },
1427//{ LDDF, true, true, 0 },
1428//{ LDDFA, true, true, 0 },
1429 { ADDC, true, true, 0 },
1430 { ADDCcc, true, true, 0 },
1431 { SUBC, true, true, 0 },
1432 { SUBCcc, true, true, 0 },
1433//{ SAVE, true, true, 0 },
1434//{ RESTORE, true, true, 0 },
1435//{ LDSTUB, true, true, 0 },
1436//{ SWAP, true, true, 0 },
1437//{ SWAPA, true, true, 0 },
1438//{ CAS, true, true, 0 },
1439//{ CASA, true, true, 0 },
1440//{ CASX, true, true, 0 },
1441//{ CASXA, true, true, 0 },
1442//{ LDFSR, true, true, 0 },
1443//{ LDFSRA, true, true, 0 },
1444//{ LDXFSR, true, true, 0 },
1445//{ LDXFSRA, true, true, 0 },
1446//{ STFSR, true, true, 0 },
1447//{ STFSRA, true, true, 0 },
1448//{ STXFSR, true, true, 0 },
1449//{ STXFSRA, true, true, 0 },
1450//{ SAVED, true, true, 0 },
1451//{ RESTORED, true, true, 0 },
1452//{ FLUSH, true, true, 9 },
1453//{ FLUSHW, true, true, 9 },
1454//{ ALIGNADDR, true, true, 0 },
1455 { RETURN, true, true, 0 },
1456//{ DONE, true, true, 0 },
1457//{ RETRY, true, true, 0 },
1458//{ WR, true, true, 0 },
1459//{ WRPR, true, true, 4 },
1460//{ RD, true, true, 0 },
1461//{ RDPR, true, true, 0 },
1462//{ TCC, true, true, 0 },
1463//{ SHUTDOWN, true, true, 0 },
1464
1465 // Special cases for breaking group *before*
1466 // CURRENTLY NOT SUPPORTED!
1467 { CALL, false, false, 0 },
1468 { JMPL, false, false, 0 },
1469
1470 // Special cases for breaking the group *after*
1471 { MULX, true, true, (4+34)/2 },
1472 { FDIVS, false, true, 0 },
1473 { FDIVD, false, true, 0 },
1474 { FDIVQ, false, true, 0 },
1475 { FSQRTS, false, true, 0 },
1476 { FSQRTD, false, true, 0 },
1477 { FSQRTQ, false, true, 0 },
1478//{ FCMP{LE,GT,NE,EQ}, false, true, 0 },
1479
1480 // Instructions that introduce bubbles
1481//{ MULScc, true, true, 2 },
1482//{ SMULcc, true, true, (4+18)/2 },
1483//{ UMULcc, true, true, (4+19)/2 },
1484 { SDIVX, true, true, 68 },
1485 { UDIVX, true, true, 68 },
1486//{ SDIVcc, true, true, 36 },
1487//{ UDIVcc, true, true, 37 },
1488//{ WR, false, false, 4 },
1489//{ WRPR, false, false, 4 },
1490};
1491
1492
1493//---------------------------------------------------------------------------
1494// const InstrRUsageDelta SparcInstrUsageDeltas[]
1495//
1496// Purpose:
1497// Changes to resource usage information in InstrClassRUsage for
1498// instructions that differ from other instructions in their class.
1499//---------------------------------------------------------------------------
1500
1501const InstrRUsageDelta SparcInstrUsageDeltas[] = {
1502
1503 // MachineOpCode, Resource, Start cycle, Num cycles
1504
1505 //
1506 // JMPL counts as a load/store instruction for issue!
1507 //
1508 { JMPL, LSIssueSlots.rid, 0, 1 },
1509
1510 //
1511 // Many instructions cannot issue for the next 2 cycles after an FCMP
1512 // We model that with a fake resource FCMPDelayCycle.
1513 //
1514 { FCMPS, FCMPDelayCycle.rid, 1, 3 },
1515 { FCMPD, FCMPDelayCycle.rid, 1, 3 },
1516 { FCMPQ, FCMPDelayCycle.rid, 1, 3 },
1517
1518 { MULX, FCMPDelayCycle.rid, 1, 1 },
1519 { SDIVX, FCMPDelayCycle.rid, 1, 1 },
1520 { UDIVX, FCMPDelayCycle.rid, 1, 1 },
1521//{ SMULcc, FCMPDelayCycle.rid, 1, 1 },
1522//{ UMULcc, FCMPDelayCycle.rid, 1, 1 },
1523//{ SDIVcc, FCMPDelayCycle.rid, 1, 1 },
1524//{ UDIVcc, FCMPDelayCycle.rid, 1, 1 },
1525 { STD, FCMPDelayCycle.rid, 1, 1 },
1526 { FMOVRSZ, FCMPDelayCycle.rid, 1, 1 },
1527 { FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
1528 { FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
1529 { FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
1530 { FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
1531 { FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
1532
1533 //
1534 // Some instructions are stalled in the GROUP stage if a CTI is in
1535 // the E or C stage
1536 //
1537 { LDD, CTIDelayCycle.rid, 1, 1 },
1538//{ LDDA, CTIDelayCycle.rid, 1, 1 },
1539//{ LDDSTUB, CTIDelayCycle.rid, 1, 1 },
1540//{ LDDSTUBA, CTIDelayCycle.rid, 1, 1 },
1541//{ SWAP, CTIDelayCycle.rid, 1, 1 },
1542//{ SWAPA, CTIDelayCycle.rid, 1, 1 },
1543//{ CAS, CTIDelayCycle.rid, 1, 1 },
1544//{ CASA, CTIDelayCycle.rid, 1, 1 },
1545//{ CASX, CTIDelayCycle.rid, 1, 1 },
1546//{ CASXA, CTIDelayCycle.rid, 1, 1 },
1547
1548 //
1549 // Signed int loads of less than dword size return data in cycle N1 (not C)
1550 // and put all loads in consecutive cycles into delayed load return mode.
1551 //
1552 { LDSB, LdReturn.rid, 2, -1 },
1553 { LDSB, LdReturn.rid, 3, 1 },
1554
1555 { LDSH, LdReturn.rid, 2, -1 },
1556 { LDSH, LdReturn.rid, 3, 1 },
1557
1558 { LDSW, LdReturn.rid, 2, -1 },
1559 { LDSW, LdReturn.rid, 3, 1 },
1560
1561
1562#undef EXPLICIT_BUBBLES_NEEDED
1563#ifdef EXPLICIT_BUBBLES_NEEDED
1564 //
1565 // MULScc inserts one bubble.
1566 // This means it breaks the current group (captured in UltraSparcSchedInfo)
1567 // *and occupies all issue slots for the next cycle
1568 //
1569//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1570//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1571//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1572//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1573
1574 //
1575 // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
1576 // We just model this with a simple average.
1577 //
1578//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1579//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1580//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1581//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1582
1583 // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
1584//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1585//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1586//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1587//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1588
1589 //
1590 // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
1591 //
1592 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1593 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1594 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1595 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1596
1597 //
1598 // SDIVcc inserts 36 bubbles.
1599 //
1600//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1601//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1602//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1603//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1604
1605 // UDIVcc inserts 37 bubbles.
1606//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1607//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1608//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1609//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1610
1611 //
1612 // SDIVX inserts 68 bubbles.
1613 //
1614 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1615 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1616 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1617 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1618
1619 //
1620 // UDIVX inserts 68 bubbles.
1621 //
1622 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1623 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1624 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1625 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1626
1627 //
1628 // WR inserts 4 bubbles.
1629 //
1630//{ WR, AllIssueSlots.rid, 2, 68-1 },
1631//{ WR, AllIssueSlots.rid, 2, 68-1 },
1632//{ WR, AllIssueSlots.rid, 2, 68-1 },
1633//{ WR, AllIssueSlots.rid, 2, 68-1 },
1634
1635 //
1636 // WRPR inserts 4 bubbles.
1637 //
1638//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1639//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1640//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1641//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1642
1643 //
1644 // DONE inserts 9 bubbles.
1645 //
1646//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1647//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1648//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1649//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1650
1651 //
1652 // RETRY inserts 9 bubbles.
1653 //
1654//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1655//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1656//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1657//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1658
1659#endif EXPLICIT_BUBBLES_NEEDED
1660};
1661
1662
1663
1664// Additional delays to be captured in code:
1665// 1. RDPR from several state registers (page 349)
1666// 2. RD from *any* register (page 349)
1667// 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
1668// 4. Integer store can be in same group as instr producing value to store.
1669// 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
1670// 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
1671// 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
1672// 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
1673// follow an annulling branch cannot be issued in the same group or in
1674// the 3 groups following the branch.
1675// 9. A predicted annulled load does not stall dependent instructions.
1676// Other annulled delay slot instructions *do* stall dependents, so
1677// nothing special needs to be done for them during scheduling.
1678//10. Do not put a load use that may be annulled in the same group as the
1679// branch. The group will stall until the load returns.
1680//11. Single-prec. FP loads lock 2 registers, for dependency checking.
1681//
1682//
1683// Additional delays we cannot or will not capture:
1684// 1. If DCTI is last word of cache line, it is delayed until next line can be
1685// fetched. Also, other DCTI alignment-related delays (pg 352)
1686// 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
1687// Also, several other store-load and load-store conflicts (pg 358)
1688// 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
1689// 4. There can be at most 8 outstanding buffered store instructions
1690// (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
1691
1692
1693
1694//---------------------------------------------------------------------------
1695// class UltraSparcSchedInfo
1696//
1697// Purpose:
1698// Interface to instruction scheduling information for UltraSPARC.
1699// The parameter values above are based on UltraSPARC IIi.
1700//---------------------------------------------------------------------------
1701
1702
1703class UltraSparcSchedInfo: public MachineSchedInfo {
1704public:
1705 /*ctor*/ UltraSparcSchedInfo (const MachineInstrInfo* mii);
1706 /*dtor*/ virtual ~UltraSparcSchedInfo () {}
1707protected:
1708 virtual void initializeResources ();
1709};
1710
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001711
1712//---------------------------------------------------------------------------
1713// class UltraSparcMachine
1714//
1715// Purpose:
1716// Primary interface to machine description for the UltraSPARC.
1717// Primarily just initializes machine-dependent parameters in
1718// class TargetMachine, and creates machine-dependent subclasses
Vikram S. Adve339084b2001-09-18 13:04:24 +00001719// for classes such as InstrInfo, SchedInfo and RegInfo.
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001720//---------------------------------------------------------------------------
1721
1722class UltraSparc : public TargetMachine {
Vikram S. Adve339084b2001-09-18 13:04:24 +00001723private:
1724 UltraSparcInstrInfo instrInfo;
1725 UltraSparcSchedInfo schedInfo;
1726 UltraSparcRegInfo regInfo;
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001727public:
1728 UltraSparc();
1729 virtual ~UltraSparc() {}
Vikram S. Adve339084b2001-09-18 13:04:24 +00001730
1731 virtual const MachineInstrInfo& getInstrInfo() const { return instrInfo; }
1732
1733 virtual const MachineSchedInfo& getSchedInfo() const { return schedInfo; }
1734
1735 virtual const MachineRegInfo& getRegInfo() const { return regInfo; }
1736
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001737 // compileMethod - For the sparc, we do instruction selection, followed by
1738 // delay slot scheduling, then register allocation.
1739 //
1740 virtual bool compileMethod(Method *M);
1741};
1742
1743
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001744#endif