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