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