*** empty log message ***
[oota-llvm.git] / include / llvm / CodeGen / Sparc.h
1 // $Id$ -*-c++-*-
2 //***************************************************************************
3 // File:
4 //      Sparc.cpp
5 // 
6 // Purpose:
7 //      
8 // History:
9 //      7/15/01  -  Vikram Adve  -  Created
10 //**************************************************************************/
11
12 #ifndef LLVM_CODEGEN_SPARC_H
13 #define LLVM_CODEGEN_SPARC_H
14
15 #include <sys/types.h>
16 #include "llvm/CodeGen/TargetMachine.h"
17 #include "llvm/Type.h"
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 #include "llvm/CodeGen/SparcRegInfo.h"
877
878 class LiveRange;
879 class UltraSparc;
880
881
882 class UltraSparcRegInfo : public MachineRegInfo
883 {
884
885  private:
886   enum RegClassIDs { IntRegClassID, FloatRegClassID, FloatCCREgClassID };
887
888   // reverse pointer to get info about the ultra sparc machine
889   const UltraSparc *const UltraSparcInfo;
890
891   // Int arguments can be passed in 6 int regs - %o0 to %o5 (cannot be changed)
892   unsigned const NumOfIntArgRegs;
893
894   // Float arguments can be passed in this many regs - can be canged if needed
895   // %f0 - %f5 are used (can hold 6 floats or 3 doubles)
896   unsigned const NumOfFloatArgRegs;
897
898   void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
899
900
901  public:
902
903   UltraSparcRegInfo(const UltraSparc *USI ) : UltraSparcInfo(USI), 
904                                               NumOfIntArgRegs(6), 
905                                               NumOfFloatArgRegs(6) 
906   {    
907
908     MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
909     MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
910
911     assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 6 && 
912             "6 Float regs are used for float arg passing");
913
914   }
915
916   inline const UltraSparc & getUltraSparcInfo() const { 
917     return *UltraSparcInfo;
918   }
919
920   inline unsigned getRegClassIDOfValue (const Value *const Val) const {
921     Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
922     
923     if( ty && ty <= Type::LongTyID || (ty == Type::PointerTyID) )  
924       return IntRegClassID;             // sparc int reg (ty=0: void)
925     else if( ty <= Type::DoubleTyID)
926       return FloatRegClassID;           // sparc float reg class
927     else { 
928       cout << "TypeID: " << ty << endl;
929       assert(0 && "Cannot resolve register class for type");
930
931     }
932   }
933  
934   void colorArgs(const Method *const Meth, LiveRangeInfo& LRI) const;
935
936   static void printReg(const LiveRange *const LR);
937
938   void colorCallArgs(vector<const Instruction *> & CallInstrList, 
939                      LiveRangeInfo& LRI ) const;
940
941 };
942
943
944
945
946
947 //---------------------------------------------------------------------------
948 // class UltraSparcMachine 
949 // 
950 // Purpose:
951 //   Primary interface to machine description for the UltraSPARC.
952 //   Primarily just initializes machine-dependent parameters in
953 //   class TargetMachine, and creates machine-dependent subclasses
954 //   for classes such as MachineInstrInfo. 
955 //---------------------------------------------------------------------------
956
957 class UltraSparc: public TargetMachine {
958 public:
959   /*ctor*/              UltraSparc      ();
960   /*dtor*/ virtual      ~UltraSparc     ();
961 };
962
963
964
965
966
967 /*---------------------------------------------------------------------------
968 Scheduling guidelines for SPARC IIi:
969
970 I-Cache alignment rules (pg 326)
971 -- Align a branch target instruction so that it's entire group is within
972    the same cache line (may be 1-4 instructions).
973 ** Don't let a branch that is predicted taken be the last instruction
974    on an I-cache line: delay slot will need an entire line to be fetched
975 -- Make a FP instruction or a branch be the 4th instruction in a group.
976    For branches, there are tradeoffs in reordering to make this happen
977    (see pg. 327).
978 ** Don't put a branch in a group that crosses a 32-byte boundary!
979    An artificial branch is inserted after every 32 bytes, and having
980    another branch will force the group to be broken into 2 groups. 
981
982 iTLB rules:
983 -- Don't let a loop span two memory pages, if possible
984
985 Branch prediction performance:
986 -- Don't make the branch in a delay slot the target of a branch
987 -- Try not to have 2 predicted branches within a group of 4 instructions
988    (because each such group has a single branch target field).
989 -- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
990    the wrong prediction bits being used in some cases).
991
992 D-Cache timing constraints:
993 -- Signed int loads of less than 64 bits have 3 cycle latency, not 2
994 -- All other loads that hit in D-Cache have 2 cycle latency
995 -- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
996 -- Mis-aligned loads or stores cause a trap.  In particular, replace
997    mis-aligned FP double precision l/s with 2 single-precision l/s.
998 -- Simulations of integer codes show increase in avg. group size of
999    33% when code (including esp. non-faulting loads) is moved across
1000    one branch, and 50% across 2 branches.
1001
1002 E-Cache timing constraints:
1003 -- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
1004
1005 Store buffer timing constraints:
1006 -- Stores can be executed in same cycle as instruction producing the value
1007 -- Stores are buffered and have lower priority for E-cache until
1008    highwater mark is reached in the store buffer (5 stores)
1009
1010 Pipeline constraints:
1011 -- Shifts can only use IEU0.
1012 -- CC setting instructions can only use IEU1.
1013 -- Several other instructions must only use IEU1:
1014    EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
1015 -- Two instructions cannot store to the same register file in a single cycle
1016    (single write port per file).
1017
1018 Issue and grouping constraints:
1019 -- FP and branch instructions must use slot 4.
1020 -- Shift instructions cannot be grouped with other IEU0-specific instructions.
1021 -- CC setting instructions cannot be grouped with other IEU1-specific instrs.
1022 -- Several instructions must be issued in a single-instruction group:
1023         MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
1024 -- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
1025 -- 
1026 -- 
1027
1028 Branch delay slot scheduling rules:
1029 -- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
1030    has a 9-instruction penalty: the entire pipeline is flushed when the
1031    second instruction reaches stage 9 (W-Writeback).
1032 -- Avoid putting multicycle instructions, and instructions that may cause
1033    load misses, in the delay slot of an annulling branch.
1034 -- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
1035    delay slot of an annulling branch.
1036
1037  *--------------------------------------------------------------------------- */
1038
1039 //---------------------------------------------------------------------------
1040 // List of CPUResources for UltraSPARC IIi.
1041 //---------------------------------------------------------------------------
1042
1043 const CPUResource  AllIssueSlots(   "All Instr Slots", 4);
1044 const CPUResource  IntIssueSlots(   "Int Instr Slots", 3);
1045 const CPUResource  First3IssueSlots("Instr Slots 0-3", 3);
1046 const CPUResource  LSIssueSlots(    "Load-Store Instr Slot", 1);
1047 const CPUResource  CTIIssueSlots(   "Ctrl Transfer Instr Slot", 1);
1048 const CPUResource  FPAIssueSlots(   "Int Instr Slot 1", 1);
1049 const CPUResource  FPMIssueSlots(   "Int Instr Slot 1", 1);
1050
1051 // IEUN instructions can use either Alu and should use IAluN.
1052 // IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0. 
1053 // IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1. 
1054 const CPUResource  IAluN("Int ALU 1or2", 2);
1055 const CPUResource  IAlu0("Int ALU 1",    1);
1056 const CPUResource  IAlu1("Int ALU 2",    1);
1057
1058 const CPUResource  LSAluC1("Load/Store Unit Addr Cycle", 1);
1059 const CPUResource  LSAluC2("Load/Store Unit Issue Cycle", 1);
1060 const CPUResource  LdReturn("Load Return Unit", 1);
1061
1062 const CPUResource  FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
1063 const CPUResource  FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
1064 const CPUResource  FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
1065
1066 const CPUResource  FPAAluC1("FP Other Alu Cycle 1", 1);
1067 const CPUResource  FPAAluC2("FP Other Alu Cycle 2", 1);
1068 const CPUResource  FPAAluC3("FP Other Alu Cycle 3", 1);
1069
1070 const CPUResource  IRegReadPorts("Int Reg ReadPorts", INT_MAX);  // CHECK
1071 const CPUResource  IRegWritePorts("Int Reg WritePorts", 2);      // CHECK
1072 const CPUResource  FPRegReadPorts("FP Reg Read Ports", INT_MAX); // CHECK
1073 const CPUResource  FPRegWritePorts("FP Reg Write Ports", 1);     // CHECK
1074
1075 const CPUResource  CTIDelayCycle( "CTI  delay cycle", 1);
1076 const CPUResource  FCMPDelayCycle("FCMP delay cycle", 1);
1077
1078
1079 //---------------------------------------------------------------------------
1080 // const InstrClassRUsage SparcRUsageDesc[]
1081 // 
1082 // Purpose:
1083 //   Resource usage information for instruction in each scheduling class.
1084 //   The InstrRUsage Objects for individual classes are specified first.
1085 //   Note that fetch and decode are decoupled from the execution pipelines
1086 //   via an instr buffer, so they are not included in the cycles below.
1087 //---------------------------------------------------------------------------
1088
1089 const InstrClassRUsage NoneClassRUsage = {
1090   SPARC_NONE,
1091   /*totCycles*/ 7,
1092   
1093   /* maxIssueNum */ 4,
1094   /* isSingleIssue */ false,
1095   /* breaksGroup */ false,
1096   /* numBubbles */ 0,
1097   
1098   /*numSlots*/ 4,
1099   /* feasibleSlots[] */ { 0, 1, 2, 3 },
1100   
1101   /*numEntries*/ 0,
1102   /* V[] */ {
1103     /*Cycle G */
1104     /*Cycle E */
1105     /*Cycle C */
1106     /*Cycle N1*/
1107     /*Cycle N1*/
1108     /*Cycle N1*/
1109     /*Cycle W */
1110   }
1111 };
1112
1113 const InstrClassRUsage IEUNClassRUsage = {
1114   SPARC_IEUN,
1115   /*totCycles*/ 7,
1116   
1117   /* maxIssueNum */ 3,
1118   /* isSingleIssue */ false,
1119   /* breaksGroup */ false,
1120   /* numBubbles */ 0,
1121   
1122   /*numSlots*/ 3,
1123   /* feasibleSlots[] */ { 0, 1, 2 },
1124   
1125   /*numEntries*/ 4,
1126   /* V[] */ {
1127     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1128                  { IntIssueSlots.rid, 0, 1 },
1129     /*Cycle E */ { IAluN.rid, 1, 1 },
1130     /*Cycle C */
1131     /*Cycle N1*/
1132     /*Cycle N1*/
1133     /*Cycle N1*/
1134     /*Cycle W */ { IRegWritePorts.rid, 6, 1  }
1135   }
1136 };
1137
1138 const InstrClassRUsage IEU0ClassRUsage = {
1139   SPARC_IEU0,
1140   /*totCycles*/ 7,
1141   
1142   /* maxIssueNum */ 1,
1143   /* isSingleIssue */ false,
1144   /* breaksGroup */ false,
1145   /* numBubbles */ 0,
1146   
1147   /*numSlots*/ 3,
1148   /* feasibleSlots[] */ { 0, 1, 2 },
1149   
1150   /*numEntries*/ 5,
1151   /* V[] */ {
1152     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1153                  { IntIssueSlots.rid, 0, 1 },
1154     /*Cycle E */ { IAluN.rid, 1, 1 },
1155                  { IAlu0.rid, 1, 1 },
1156     /*Cycle C */
1157     /*Cycle N1*/
1158     /*Cycle N1*/
1159     /*Cycle N1*/
1160     /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
1161   }
1162 };
1163
1164 const InstrClassRUsage IEU1ClassRUsage = {
1165   SPARC_IEU1,
1166   /*totCycles*/ 7,
1167   
1168   /* maxIssueNum */ 1,
1169   /* isSingleIssue */ false,
1170   /* breaksGroup */ false,
1171   /* numBubbles */ 0,
1172   
1173   /*numSlots*/ 3,
1174   /* feasibleSlots[] */ { 0, 1, 2 },
1175   
1176   /*numEntries*/ 5,
1177   /* V[] */ {
1178     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1179                { IntIssueSlots.rid, 0, 1 },
1180     /*Cycle E */ { IAluN.rid, 1, 1 },
1181                { IAlu1.rid, 1, 1 },
1182     /*Cycle C */
1183     /*Cycle N1*/
1184     /*Cycle N1*/
1185     /*Cycle N1*/
1186     /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
1187   }
1188 };
1189
1190 const InstrClassRUsage FPMClassRUsage = {
1191   SPARC_FPM,
1192   /*totCycles*/ 7,
1193   
1194   /* maxIssueNum */ 1,
1195   /* isSingleIssue */ false,
1196   /* breaksGroup */ false,
1197   /* numBubbles */ 0,
1198   
1199   /*numSlots*/ 4,
1200   /* feasibleSlots[] */ { 0, 1, 2, 3 },
1201   
1202   /*numEntries*/ 7,
1203   /* V[] */ {
1204     /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
1205                  { FPMIssueSlots.rid,   0, 1 },
1206     /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
1207     /*Cycle C */ { FPMAluC1.rid,        2, 1 },
1208     /*Cycle N1*/ { FPMAluC2.rid,        3, 1 },
1209     /*Cycle N1*/ { FPMAluC3.rid,        4, 1 },
1210     /*Cycle N1*/
1211     /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
1212   }
1213 };
1214
1215 const InstrClassRUsage FPAClassRUsage = {
1216   SPARC_FPA,
1217   /*totCycles*/ 7,
1218   
1219   /* maxIssueNum */ 1,
1220   /* isSingleIssue */ false,
1221   /* breaksGroup */ false,
1222   /* numBubbles */ 0,
1223   
1224   /*numSlots*/ 4,
1225   /* feasibleSlots[] */ { 0, 1, 2, 3 },
1226   
1227   /*numEntries*/ 7,
1228   /* V[] */ {
1229     /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
1230                  { FPAIssueSlots.rid,   0, 1 },
1231     /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
1232     /*Cycle C */ { FPAAluC1.rid,        2, 1 },
1233     /*Cycle N1*/ { FPAAluC2.rid,        3, 1 },
1234     /*Cycle N1*/ { FPAAluC3.rid,        4, 1 },
1235     /*Cycle N1*/
1236     /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
1237   }
1238 };
1239
1240 const InstrClassRUsage LDClassRUsage = {
1241   SPARC_LD,
1242   /*totCycles*/ 7,
1243   
1244   /* maxIssueNum */ 1,
1245   /* isSingleIssue */ false,
1246   /* breaksGroup */ false,
1247   /* numBubbles */ 0,
1248   
1249   /*numSlots*/ 3,
1250   /* feasibleSlots[] */ { 0, 1, 2, },
1251   
1252   /*numEntries*/ 6,
1253   /* V[] */ {
1254     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
1255                  { First3IssueSlots.rid, 0, 1 },
1256                  { LSIssueSlots.rid,     0, 1 },
1257     /*Cycle E */ { LSAluC1.rid,          1, 1 },
1258     /*Cycle C */ { LSAluC2.rid,          2, 1 },
1259                  { LdReturn.rid,         2, 1 },
1260     /*Cycle N1*/
1261     /*Cycle N1*/
1262     /*Cycle N1*/
1263     /*Cycle W */ { IRegWritePorts.rid,   6, 1 }
1264   }
1265 };
1266
1267 const InstrClassRUsage STClassRUsage = {
1268   SPARC_ST,
1269   /*totCycles*/ 7,
1270   
1271   /* maxIssueNum */ 1,
1272   /* isSingleIssue */ false,
1273   /* breaksGroup */ false,
1274   /* numBubbles */ 0,
1275   
1276   /*numSlots*/ 3,
1277   /* feasibleSlots[] */ { 0, 1, 2 },
1278   
1279   /*numEntries*/ 4,
1280   /* V[] */ {
1281     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
1282                  { First3IssueSlots.rid, 0, 1 },
1283                  { LSIssueSlots.rid,     0, 1 },
1284     /*Cycle E */ { LSAluC1.rid,          1, 1 },
1285     /*Cycle C */ { LSAluC2.rid,          2, 1 }
1286     /*Cycle N1*/
1287     /*Cycle N1*/
1288     /*Cycle N1*/
1289     /*Cycle W */
1290   }
1291 };
1292
1293 const InstrClassRUsage CTIClassRUsage = {
1294   SPARC_CTI,
1295   /*totCycles*/ 7,
1296   
1297   /* maxIssueNum */ 1,
1298   /* isSingleIssue */ false,
1299   /* breaksGroup */ false,
1300   /* numBubbles */ 0,
1301   
1302   /*numSlots*/ 4,
1303   /* feasibleSlots[] */ { 0, 1, 2, 3 },
1304   
1305   /*numEntries*/ 4,
1306   /* V[] */ {
1307     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
1308                  { CTIIssueSlots.rid,    0, 1 },
1309     /*Cycle E */ { IAlu0.rid,            1, 1 },
1310     /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
1311     /*Cycle C */             
1312     /*Cycle N1*/
1313     /*Cycle N1*/
1314     /*Cycle N1*/
1315     /*Cycle W */
1316   }
1317 };
1318
1319 const InstrClassRUsage SingleClassRUsage = {
1320   SPARC_SINGLE,
1321   /*totCycles*/ 7,
1322   
1323   /* maxIssueNum */ 1,
1324   /* isSingleIssue */ true,
1325   /* breaksGroup */ false,
1326   /* numBubbles */ 0,
1327   
1328   /*numSlots*/ 1,
1329   /* feasibleSlots[] */ { 0 },
1330   
1331   /*numEntries*/ 5,
1332   /* V[] */ {
1333     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
1334                  { AllIssueSlots.rid,    0, 1 },
1335                  { AllIssueSlots.rid,    0, 1 },
1336                  { AllIssueSlots.rid,    0, 1 },
1337     /*Cycle E */ { IAlu0.rid,            1, 1 }
1338     /*Cycle C */
1339     /*Cycle N1*/
1340     /*Cycle N1*/
1341     /*Cycle N1*/
1342     /*Cycle W */
1343   }
1344 };
1345
1346
1347 const InstrClassRUsage SparcRUsageDesc[] = {
1348   NoneClassRUsage,
1349   IEUNClassRUsage,
1350   IEU0ClassRUsage,
1351   IEU1ClassRUsage,
1352   FPMClassRUsage,
1353   FPAClassRUsage,
1354   CTIClassRUsage,
1355   LDClassRUsage,
1356   STClassRUsage,
1357   SingleClassRUsage
1358 };
1359
1360
1361 //---------------------------------------------------------------------------
1362 // const InstrIssueDelta  SparcInstrIssueDeltas[]
1363 // 
1364 // Purpose:
1365 //   Changes to issue restrictions information in InstrClassRUsage for
1366 //   instructions that differ from other instructions in their class.
1367 //---------------------------------------------------------------------------
1368
1369 const InstrIssueDelta  SparcInstrIssueDeltas[] = {
1370
1371   // opCode,  isSingleIssue,  breaksGroup,  numBubbles
1372
1373                                 // Special cases for single-issue only
1374                                 // Other single issue cases are below.
1375 //{ LDDA,       true,   true,   0 },
1376 //{ STDA,       true,   true,   0 },
1377 //{ LDDF,       true,   true,   0 },
1378 //{ LDDFA,      true,   true,   0 },
1379   { ADDC,       true,   true,   0 },
1380   { ADDCcc,     true,   true,   0 },
1381   { SUBC,       true,   true,   0 },
1382   { SUBCcc,     true,   true,   0 },
1383 //{ SAVE,       true,   true,   0 },
1384 //{ RESTORE,    true,   true,   0 },
1385 //{ LDSTUB,     true,   true,   0 },
1386 //{ SWAP,       true,   true,   0 },
1387 //{ SWAPA,      true,   true,   0 },
1388 //{ CAS,        true,   true,   0 },
1389 //{ CASA,       true,   true,   0 },
1390 //{ CASX,       true,   true,   0 },
1391 //{ CASXA,      true,   true,   0 },
1392 //{ LDFSR,      true,   true,   0 },
1393 //{ LDFSRA,     true,   true,   0 },
1394 //{ LDXFSR,     true,   true,   0 },
1395 //{ LDXFSRA,    true,   true,   0 },
1396 //{ STFSR,      true,   true,   0 },
1397 //{ STFSRA,     true,   true,   0 },
1398 //{ STXFSR,     true,   true,   0 },
1399 //{ STXFSRA,    true,   true,   0 },
1400 //{ SAVED,      true,   true,   0 },
1401 //{ RESTORED,   true,   true,   0 },
1402 //{ FLUSH,      true,   true,   9 },
1403 //{ FLUSHW,     true,   true,   9 },
1404 //{ ALIGNADDR,  true,   true,   0 },
1405   { RETURN,     true,   true,   0 },
1406 //{ DONE,       true,   true,   0 },
1407 //{ RETRY,      true,   true,   0 },
1408 //{ WR,         true,   true,   0 },
1409 //{ WRPR,       true,   true,   4 },
1410 //{ RD,         true,   true,   0 },
1411 //{ RDPR,       true,   true,   0 },
1412 //{ TCC,        true,   true,   0 },
1413 //{ SHUTDOWN,   true,   true,   0 },
1414   
1415                                 // Special cases for breaking group *before*
1416                                 // CURRENTLY NOT SUPPORTED!
1417   { CALL,       false,  false,  0 },
1418   { JMPL,       false,  false,  0 },
1419   
1420                                 // Special cases for breaking the group *after*
1421   { MULX,       true,   true,   (4+34)/2 },
1422   { FDIVS,      false,  true,   0 },
1423   { FDIVD,      false,  true,   0 },
1424   { FDIVQ,      false,  true,   0 },
1425   { FSQRTS,     false,  true,   0 },
1426   { FSQRTD,     false,  true,   0 },
1427   { FSQRTQ,     false,  true,   0 },
1428 //{ FCMP{LE,GT,NE,EQ}, false, true, 0 },
1429   
1430                                 // Instructions that introduce bubbles
1431 //{ MULScc,     true,   true,   2 },
1432 //{ SMULcc,     true,   true,   (4+18)/2 },
1433 //{ UMULcc,     true,   true,   (4+19)/2 },
1434   { SDIVX,      true,   true,   68 },
1435   { UDIVX,      true,   true,   68 },
1436 //{ SDIVcc,     true,   true,   36 },
1437 //{ UDIVcc,     true,   true,   37 },
1438 //{ WR,         false,  false,  4 },
1439 //{ WRPR,       false,  false,  4 },
1440 };
1441
1442
1443 //---------------------------------------------------------------------------
1444 // const InstrRUsageDelta SparcInstrUsageDeltas[]
1445 // 
1446 // Purpose:
1447 //   Changes to resource usage information in InstrClassRUsage for
1448 //   instructions that differ from other instructions in their class.
1449 //---------------------------------------------------------------------------
1450
1451 const InstrRUsageDelta SparcInstrUsageDeltas[] = {
1452
1453   // MachineOpCode, Resource, Start cycle, Num cycles
1454
1455   // 
1456   // JMPL counts as a load/store instruction for issue!
1457   //
1458   { JMPL,     LSIssueSlots.rid,  0,  1 },
1459   
1460   // 
1461   // Many instructions cannot issue for the next 2 cycles after an FCMP
1462   // We model that with a fake resource FCMPDelayCycle.
1463   // 
1464   { FCMPS,    FCMPDelayCycle.rid, 1, 3 },
1465   { FCMPD,    FCMPDelayCycle.rid, 1, 3 },
1466   { FCMPQ,    FCMPDelayCycle.rid, 1, 3 },
1467   
1468   { MULX,     FCMPDelayCycle.rid, 1, 1 },
1469   { SDIVX,    FCMPDelayCycle.rid, 1, 1 },
1470   { UDIVX,    FCMPDelayCycle.rid, 1, 1 },
1471 //{ SMULcc,   FCMPDelayCycle.rid, 1, 1 },
1472 //{ UMULcc,   FCMPDelayCycle.rid, 1, 1 },
1473 //{ SDIVcc,   FCMPDelayCycle.rid, 1, 1 },
1474 //{ UDIVcc,   FCMPDelayCycle.rid, 1, 1 },
1475   { STD,      FCMPDelayCycle.rid, 1, 1 },
1476   { FMOVRSZ,  FCMPDelayCycle.rid, 1, 1 },
1477   { FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
1478   { FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
1479   { FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
1480   { FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
1481   { FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
1482   
1483   // 
1484   // Some instructions are stalled in the GROUP stage if a CTI is in
1485   // the E or C stage
1486   // 
1487   { LDD,      CTIDelayCycle.rid,  1, 1 },
1488 //{ LDDA,     CTIDelayCycle.rid,  1, 1 },
1489 //{ LDDSTUB,  CTIDelayCycle.rid,  1, 1 },
1490 //{ LDDSTUBA, CTIDelayCycle.rid,  1, 1 },
1491 //{ SWAP,     CTIDelayCycle.rid,  1, 1 },
1492 //{ SWAPA,    CTIDelayCycle.rid,  1, 1 },
1493 //{ CAS,      CTIDelayCycle.rid,  1, 1 },
1494 //{ CASA,     CTIDelayCycle.rid,  1, 1 },
1495 //{ CASX,     CTIDelayCycle.rid,  1, 1 },
1496 //{ CASXA,    CTIDelayCycle.rid,  1, 1 },
1497   
1498   //
1499   // Signed int loads of less than dword size return data in cycle N1 (not C)
1500   // and put all loads in consecutive cycles into delayed load return mode.
1501   //
1502   { LDSB,    LdReturn.rid,  2, -1 },
1503   { LDSB,    LdReturn.rid,  3,  1 },
1504   
1505   { LDSH,    LdReturn.rid,  2, -1 },
1506   { LDSH,    LdReturn.rid,  3,  1 },
1507   
1508   { LDSW,    LdReturn.rid,  2, -1 },
1509   { LDSW,    LdReturn.rid,  3,  1 },
1510
1511
1512 #undef EXPLICIT_BUBBLES_NEEDED
1513 #ifdef EXPLICIT_BUBBLES_NEEDED
1514   // 
1515   // MULScc inserts one bubble.
1516   // This means it breaks the current group (captured in UltraSparcSchedInfo)
1517   // *and occupies all issue slots for the next cycle
1518   // 
1519 //{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
1520 //{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
1521 //{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
1522 //{ MULScc,  AllIssueSlots.rid,  2, 2-1 },
1523   
1524   // 
1525   // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
1526   // We just model this with a simple average.
1527   // 
1528 //{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1529 //{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1530 //{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1531 //{ SMULcc,  AllIssueSlots.rid,  2, ((4+18)/2)-1 },
1532   
1533   // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
1534 //{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1535 //{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1536 //{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1537 //{ UMULcc,  AllIssueSlots.rid,  2, ((4+19)/2)-1 },
1538   
1539   // 
1540   // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
1541   // 
1542   { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1543   { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1544   { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1545   { MULX,    AllIssueSlots.rid,  2, ((4+34)/2)-1 },
1546   
1547   // 
1548   // SDIVcc inserts 36 bubbles.
1549   // 
1550 //{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
1551 //{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
1552 //{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
1553 //{ SDIVcc,  AllIssueSlots.rid,  2, 36-1 },
1554   
1555   // UDIVcc inserts 37 bubbles.
1556 //{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
1557 //{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
1558 //{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
1559 //{ UDIVcc,  AllIssueSlots.rid,  2, 37-1 },
1560   
1561   // 
1562   // SDIVX inserts 68 bubbles.
1563   // 
1564   { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
1565   { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
1566   { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
1567   { SDIVX,   AllIssueSlots.rid,  2, 68-1 },
1568   
1569   // 
1570   // UDIVX inserts 68 bubbles.
1571   // 
1572   { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
1573   { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
1574   { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
1575   { UDIVX,   AllIssueSlots.rid,  2, 68-1 },
1576   
1577   // 
1578   // WR inserts 4 bubbles.
1579   // 
1580 //{ WR,     AllIssueSlots.rid, 2, 68-1 },
1581 //{ WR,     AllIssueSlots.rid, 2, 68-1 },
1582 //{ WR,     AllIssueSlots.rid, 2, 68-1 },
1583 //{ WR,     AllIssueSlots.rid,  2, 68-1 },
1584   
1585   // 
1586   // WRPR inserts 4 bubbles.
1587   // 
1588 //{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
1589 //{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
1590 //{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
1591 //{ WRPR,   AllIssueSlots.rid,  2, 68-1 },
1592   
1593   // 
1594   // DONE inserts 9 bubbles.
1595   // 
1596 //{ DONE,   AllIssueSlots.rid, 2, 9-1 },
1597 //{ DONE,   AllIssueSlots.rid, 2, 9-1 },
1598 //{ DONE,   AllIssueSlots.rid, 2, 9-1 },
1599 //{ DONE,   AllIssueSlots.rid, 2, 9-1 },
1600   
1601   // 
1602   // RETRY inserts 9 bubbles.
1603   // 
1604 //{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
1605 //{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
1606 //{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
1607 //{ RETRY,   AllIssueSlots.rid,  2, 9-1 },
1608
1609 #endif EXPLICIT_BUBBLES_NEEDED
1610 };
1611
1612
1613
1614 // Additional delays to be captured in code:
1615 // 1. RDPR from several state registers (page 349)
1616 // 2. RD   from *any* register (page 349)
1617 // 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
1618 // 4. Integer store can be in same group as instr producing value to store.
1619 // 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
1620 // 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
1621 // 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
1622 // 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
1623 //    follow an annulling branch cannot be issued in the same group or in
1624 //    the 3 groups following the branch.
1625 // 9. A predicted annulled load does not stall dependent instructions.
1626 //    Other annulled delay slot instructions *do* stall dependents, so
1627 //    nothing special needs to be done for them during scheduling.
1628 //10. Do not put a load use that may be annulled in the same group as the
1629 //    branch.  The group will stall until the load returns.
1630 //11. Single-prec. FP loads lock 2 registers, for dependency checking.
1631 //
1632 // 
1633 // Additional delays we cannot or will not capture:
1634 // 1. If DCTI is last word of cache line, it is delayed until next line can be
1635 //    fetched.  Also, other DCTI alignment-related delays (pg 352)
1636 // 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
1637 //    Also, several other store-load and load-store conflicts (pg 358)
1638 // 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
1639 // 4. There can be at most 8 outstanding buffered store instructions
1640 //     (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
1641
1642
1643
1644 //---------------------------------------------------------------------------
1645 // class UltraSparcSchedInfo
1646 // 
1647 // Purpose:
1648 //   Interface to instruction scheduling information for UltraSPARC.
1649 //   The parameter values above are based on UltraSPARC IIi.
1650 //---------------------------------------------------------------------------
1651
1652
1653 class UltraSparcSchedInfo: public MachineSchedInfo {
1654 public:
1655   /*ctor*/         UltraSparcSchedInfo  (const MachineInstrInfo* mii);
1656   /*dtor*/ virtual ~UltraSparcSchedInfo () {}
1657 protected:
1658   virtual void  initializeResources     ();
1659 };
1660
1661
1662 /***************************************************************************/
1663
1664 #endif