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