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