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