Added several SPARC instructions including conditional move and SETHI.
[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 "llvm/CodeGen/TargetMachine.h"
16
17 // OpCodeMask definitions for the Sparc V9
18 // 
19 const OpCodeMask        Immed           = 0x00002000; // immed or reg operand?
20 const OpCodeMask        Annul           = 0x20000000; // annul delay instr?
21 const OpCodeMask        PredictTaken    = 0x00080000; // predict branch taken?
22
23
24 //---------------------------------------------------------------------------
25 // enum SparcMachineOpCode. 
26 // const MachineInstrDescriptor SparcMachineInstrDesc[]
27 // 
28 // Purpose:
29 //   Description of UltraSparc machine instructions.
30 // 
31 //---------------------------------------------------------------------------
32
33
34 enum SparcMachineOpCode {
35
36   NOP,
37   
38   // Synthetic SPARC assembly opcodes for setting a register to a constant
39   SETSW,
40   SETUW,
41   
42   // Set high-order bits of register and clear low-order bits
43   SETHI,
44   
45   // Add or add with carry.
46   // Immed bit specifies if second operand is immediate(1) or register(0)
47   ADD,
48   ADDcc,
49   ADDC,
50   ADDCcc,
51
52   // Subtract or subtract with carry.
53   // Immed bit specifies if second operand is immediate(1) or register(0)
54   SUB,
55   SUBcc,
56   SUBC,
57   SUBCcc,
58   
59   // Integer multiply, signed divide, unsigned divide.
60   // Note that the deprecated 32-bit multiply and multiply-step are not used.
61   MULX,
62   SDIVX,
63   UDIVX,
64   
65   // Floating point add, subtract, compare
66   FADDS,
67   FADDD,
68   FADDQ,
69   FSUBS,
70   FSUBD,
71   FSUBQ,
72   FCMPS,
73   FCMPD,
74   FCMPQ,
75   // NOTE: FCMPE{S,D,Q}: FP Compare With Exception are currently unused!
76   
77   // Floating point multiply or divide.
78   FMULS,
79   FMULD,
80   FMULQ,
81   FSMULD,
82   FDMULQ,
83   FDIVS,
84   FDIVD,
85   FDIVQ,
86   
87   // Logical operations
88   AND,
89   ANDcc,
90   ANDN,
91   ANDNcc,
92   OR,
93   ORcc,
94   ORN,
95   ORNcc,
96   XOR,
97   XORcc,
98   XNOR,
99   XNORcc,
100   
101   // Shift operations
102   SLL,
103   SRL,
104   SRA,
105   SLLX,
106   SRLX,
107   SRAX,
108   
109   // Convert from floating point to floating point formats
110   FSTOD,
111   FSTOQ,
112   FDTOS,
113   FDTOQ,
114   FQTOS,
115   FQTOD,
116   
117   // Convert from floating point to integer formats
118   FSTOX,
119   FDTOX,
120   FQTOX,
121   FSTOI,
122   FDTOI,
123   FQTOI,
124   
125   // Convert from integer to floating point formats
126   FXTOS,
127   FXTOD,
128   FXTOQ,
129   FITOS,
130   FITOD,
131   FITOQ,
132   
133   // Branch on integer comparison with zero.
134   // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
135   // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
136   BRZ,
137   BRLEZ,
138   BRLZ,
139   BRNZ,
140   BRGZ,
141   BRGEZ,
142
143   // Branch on integer condition code.
144   // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
145   // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
146   BA,
147   BN,
148   BNE,
149   BE,
150   BG,
151   BLE,
152   BGE,
153   BL,
154   BGU,
155   BLEU,
156   BCC,
157   BCS,
158   BPOS,
159   BNEG,
160   BVC,
161   BVS,
162
163   // Branch on floating point condition code.
164   // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
165   // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
166   FBA,
167   FBN,
168   FBU,
169   FBG,
170   FBUG,
171   FBL,
172   FBUL,
173   FBLG,
174   FBNE,
175   FBE,
176   FBUE,
177   FBGE,
178   FBUGE,
179   FBLE,
180   FBULE,
181   FBO,
182
183   // Conditional move on integer comparison with zero.
184   MOVRZ,
185   MOVRLEZ,
186   MOVRLZ,
187   MOVRNZ,
188   MOVRGZ,
189   MOVRGEZ,
190
191   // Conditional move on integer condition code.
192   MOVA,
193   MOVN,
194   MOVNE,
195   MOVE,
196   MOVG,
197   MOVLE,
198   MOVGE,
199   MOVL,
200   MOVGU,
201   MOVLEU,
202   MOVCC,
203   MOVCS,
204   MOVPOS,
205   MOVNEG,
206   MOVVC,
207   MOVVS,
208
209   // Conditional move on floating point condition code.
210   // Note that the enum name is not the same as the assembly mnemonic below
211   // because that would duplicate some entries with those above.
212   // Therefore, we use MOVF here instead of MOV.
213   MOVFA,
214   MOVFN,
215   MOVFU,
216   MOVFG,
217   MOVFUG,
218   MOVFL,
219   MOVFUL,
220   MOVFLG,
221   MOVFNE,
222   MOVFE,
223   MOVFUE,
224   MOVFGE,
225   MOVFUGE,
226   MOVFLE,
227   MOVFULE,
228   MOVFO,
229
230   // Load integer instructions
231   LDSB,
232   LDSH,
233   LDSW,
234   LDUB,
235   LDUH,
236   LDUW,
237   LDX,
238   
239   // Load floating-point instructions
240   LD,
241   LDD,                  // use of this for integers is deprecated for Sparc V9
242   LDQ,
243   
244   // Store integer instructions
245   STB,
246   STH,
247   STW,
248   STX,
249   
250   // Store floating-point instructions
251   ST,
252   STD,
253   
254   // Call, Return, and "Jump and link"
255   // Immed bit specifies if second operand is immediate(1) or register(0)
256   CALL,
257   JMPL,
258   RETURN,
259
260   // End-of-array marker
261   INVALID_OPCODE
262 };
263
264 const MachineInstrDescriptor SparcMachineInstrDesc[] = {
265   
266   // Fields of each structure:
267   // opCodeString,
268   //           numOperands,
269   //                resultPosition (0-based; -1 if no result),
270   //                     maxImmedConst,
271   //                         immedIsSignExtended,
272   //                                numDelaySlots (in cycles)
273   //                                    latency (in cycles)
274   //                                        class flags
275   
276   { "NOP",      0,  -1,  0,  false, 0,  1,  M_NOP_FLAG },
277   
278   // Synthetic SPARC assembly opcodes for setting a register to a constant.
279   // Max immediate constant should be ignored for both these instructions.
280   { "SETSW",    2,   1,  0,  true,  0,  1,  M_INT_FLAG | M_ARITH_FLAG },
281   { "SETUW",    2,   1,  0,  false, 0,  1,  M_INT_FLAG | M_LOGICAL_FLAG | M_ARITH_FLAG },
282
283   // Set high-order bits of register and clear low-order bits
284   { "SETHI",    2,  1,  (1 << 22) - 1, false, 0,  1,  M_INT_FLAG | M_LOGICAL_FLAG | M_ARITH_FLAG },
285   
286   // Add or add with carry.
287   { "ADD",      3,  2,  (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
288   { "ADDcc",    3,  2,  (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
289   { "ADDC",     3,  2,  (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
290   { "ADDCcc",   3,  2,  (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
291
292   // Sub tract or subtract with carry.
293   { "SUB",      3,  2,  (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
294   { "SUBcc",    3,  2,  (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
295   { "SUBC",     3,  2,  (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
296   { "SUBCcc",   3,  2,  (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
297
298   // Integer multiply, signed divide, unsigned divide.
299   // Note that the deprecated 32-bit multiply and multiply-step are not used.
300   { "MULX",     3,  2,  (1 << 12) - 1, true, 0, 3, M_INT_FLAG | M_ARITH_FLAG },
301   { "SDIVX",    3,  2,  (1 << 12) - 1, true, 0, 6, M_INT_FLAG | M_ARITH_FLAG },
302   { "UDIVX",    3,  2,  (1 << 12) - 1, true, 0, 6, M_INT_FLAG | M_ARITH_FLAG },
303   
304   // Floating point add, subtract, compare.
305   // Note that destination of FCMP* instructions is operand 0, not operand 2.
306   { "FADDS",    3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
307   { "FADDD",    3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
308   { "FADDQ",    3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
309   { "FSUBS",    3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
310   { "FSUBD",    3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
311   { "FSUBQ",    3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
312   { "FCMPS",    3,  0,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
313   { "FCMPD",    3,  0,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
314   { "FCMPQ",    3,  0,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
315   // NOTE: FCMPE{S,D,Q}: FP Compare With Exception are currently unused!
316   
317   // Floating point multiply or divide.
318   { "FMULS",    3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
319   { "FMULD",    3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
320   { "FMULQ",    3,  2,  0,  false, 0, 0,  M_FLOAT_FLAG | M_ARITH_FLAG },
321   { "FSMULD",   3,  2,  0,  false, 0, 3,  M_FLOAT_FLAG | M_ARITH_FLAG },
322   { "FDMULQ",   3,  2,  0,  false, 0, 0,  M_FLOAT_FLAG | M_ARITH_FLAG },
323   { "FDIVS",    3,  2,  0,  false, 0, 22, M_FLOAT_FLAG | M_ARITH_FLAG },
324   { "FDIVD",    3,  2,  0,  false, 0, 22, M_FLOAT_FLAG | M_ARITH_FLAG },
325   { "FDIVQ",    3,  2,  0,  false, 0, 0,  M_FLOAT_FLAG | M_ARITH_FLAG },
326   
327   // Logical operations
328   { "AND",      3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
329   { "ANDcc",    3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
330   { "ANDN",     3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
331   { "ANDNcc",   3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
332   { "OR",       3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
333   { "ORcc",     3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
334   { "ORN",      3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
335   { "ORNcc",    3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
336   { "XOR",      3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
337   { "XORcc",    3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
338   { "XNOR",     3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
339   { "XNORcc",   3,  2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
340   
341   // Shift operations
342   { "SLL",      3,  2, (1 << 5) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
343   { "SRL",      3,  2, (1 << 5) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
344   { "SRA",      3,  2, (1 << 5) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
345   { "SLLX",     3,  2, (1 << 6) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
346   { "SRLX",     3,  2, (1 << 6) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
347   { "SRAX",     3,  2, (1 << 6) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
348   
349   // Convert from floating point to floating point formats
350   { "FSTOD",    2,  1,  0,  false,  0,  3,  M_FLOAT_FLAG | M_ARITH_FLAG },
351   { "FSTOQ",    2,  1,  0,  false,  0,  0,  M_FLOAT_FLAG | M_ARITH_FLAG },
352   { "FDTOS",    2,  1,  0,  false,  0,  3,  M_FLOAT_FLAG | M_ARITH_FLAG },
353   { "FDTOQ",    2,  1,  0,  false,  0,  0,  M_FLOAT_FLAG | M_ARITH_FLAG },
354   { "FQTOS",    2,  1,  0,  false,  0,  0,  M_FLOAT_FLAG | M_ARITH_FLAG },
355   { "FQTOD",    2,  1,  0,  false,  0,  0,  M_FLOAT_FLAG | M_ARITH_FLAG },
356   
357   // Convert from floating point to integer formats.
358   // Note that this accesses both integer and floating point registers.
359   { "FSTOX",    2,  1,  0,  false, 0, 3,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
360   { "FDTOX",    2,  1,  0,  false, 0, 0,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
361   { "FQTOX",    2,  1,  0,  false, 0, 2,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
362   { "FSTOI",    2,  1,  0,  false, 0, 3,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
363   { "FDTOI",    2,  1,  0,  false, 0, 3,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
364   { "FQTOI",    2,  1,  0,  false, 0, 0,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
365   
366   // Convert from integer to floating point formats
367   // Note that this accesses both integer and floating point registers.
368   { "FXTOS",    2,  1,  0,  false, 0, 3,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
369   { "FXTOD",    2,  1,  0,  false, 0, 3,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
370   { "FXTOQ",    2,  1,  0,  false, 0, 0,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
371   { "FITOS",    2,  1,  0,  false, 0, 3,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
372   { "FITOD",    2,  1,  0,  false, 0, 3,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
373   { "FITOQ",    2,  1,  0,  false, 0, 0,  M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
374   
375   // Branch on integer comparison with zero.
376   // Latency includes the delay slot.
377   { "BRZ",      2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
378   { "BRLEZ",    2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
379   { "BRLZ",     2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
380   { "BRNZ",     2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
381   { "BRGZ",     2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
382   { "BRGEZ",    2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
383
384   // Branch on condition code.
385   // The first argument specifies the ICC register: %icc or %xcc
386   // Latency includes the delay slot.
387   { "BA",       2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
388   { "BN",       2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
389   { "BNE",      2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
390   { "BE",       2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
391   { "BG",       2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
392   { "BLE",      2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
393   { "BGE",      2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
394   { "BL",       2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
395   { "BGU",      2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
396   { "BLEU",     2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
397   { "BCC",      2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
398   { "BCS",      2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
399   { "BPOS",     2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
400   { "BNEG",     2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
401   { "BVC",      2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
402   { "BVS",      2,  -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
403
404   // Branch on floating point condition code.
405   // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
406   // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
407   // The first argument is the FCCn register (0 <= n <= 3).
408   // Latency includes the delay slot.
409   { "FBA",      2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
410   { "FBN",      2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
411   { "FBU",      2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
412   { "FBG",      2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
413   { "FBUG",     2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
414   { "FBL",      2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
415   { "FBUL",     2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
416   { "FBLG",     2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
417   { "FBNE",     2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
418   { "FBE",      2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
419   { "FBUE",     2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
420   { "FBGE",     2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
421   { "FBUGE",    2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
422   { "FBLE",     2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
423   { "FBULE",    2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
424   { "FBO",      2,  -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
425
426   // Conditional move on integer comparison with zero.
427   { "MOVRZ",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
428   { "MOVRLEZ",  3,  2, (1 << 12) - 1,  true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
429   { "MOVRLZ",   3,  2, (1 << 12) - 1,  true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
430   { "MOVRNZ",   3,  2, (1 << 12) - 1,  true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
431   { "MOVRGZ",   3,  2, (1 << 12) - 1,  true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
432   { "MOVRGEZ",  3,  2, (1 << 12) - 1,  true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
433
434   // Conditional move on integer condition code.
435   // The first argument specifies the ICC register: %icc or %xcc
436   { "MOVA",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
437   { "MOVN",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
438   { "MOVNE",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
439   { "MOVE",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
440   { "MOVG",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
441   { "MOVLE",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
442   { "MOVGE",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
443   { "MOVL",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
444   { "MOVGU",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
445   { "MOVLEU",   3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
446   { "MOVCC",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
447   { "MOVCS",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
448   { "MOVPOS",   3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
449   { "MOVNEG",   3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
450   { "MOVVC",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
451   { "MOVVS",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
452
453   // Conditional move (of integer register) on floating point condition code.
454   // The first argument is the FCCn register (0 <= n <= 3).
455   // Note that the enum name above is not the same as the assembly mnemonic
456   // because some of the assembly mnemonics are the same as the move on
457   // integer CC (e.g., MOVG), and we cannot have the same enum entry twice.
458   { "MOVA",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
459   { "MOVN",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
460   { "MOVU",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
461   { "MOVG",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
462   { "MOVUG",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
463   { "MOVL",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
464   { "MOVUL",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
465   { "MOVLG",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
466   { "MOVNE",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
467   { "MOVE",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
468   { "MOVUE",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
469   { "MOVGE",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
470   { "MOVUGE",   3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
471   { "MOVLE",    3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
472   { "MOVULE",   3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
473   { "MOVO",     3,  2, (1 << 12) - 1,  true, 0, 1, M_CC_FLAG | M_INT_FLAG },
474
475   // Load integer instructions
476   // Latency includes 1 cycle for address generation (Sparc IIi)
477   // Signed loads of less than 64 bits need an extra cycle for sign-extension.
478   //
479   // Not reflected here: After a 3-cycle loads, all subsequent consecutive
480   // loads also require 3 cycles to avoid contention for the load return
481   // stage.  Latency returns to 2 cycles after the first cycle with no load.
482   { "LDSB",     3,  2, (1 << 12) - 1,  true, 0, 3, M_INT_FLAG | M_LOAD_FLAG },
483   { "LDSH",     3,  2, (1 << 12) - 1,  true, 0, 3, M_INT_FLAG | M_LOAD_FLAG },
484   { "LDSW",     3,  2, (1 << 12) - 1,  true, 0, 3, M_INT_FLAG | M_LOAD_FLAG },
485   { "LDUB",     3,  2, (1 << 12) - 1,  true, 0, 2, M_INT_FLAG | M_LOAD_FLAG },
486   { "LDUH",     3,  2, (1 << 12) - 1,  true, 0, 2, M_INT_FLAG | M_LOAD_FLAG },
487   { "LDUW",     3,  2, (1 << 12) - 1,  true, 0, 2, M_INT_FLAG | M_LOAD_FLAG },
488   { "LDX",      3,  2, (1 << 12) - 1,  true, 0, 2, M_INT_FLAG | M_LOAD_FLAG },
489   
490   // Load floating-point instructions
491   // Latency includes 1 cycle for address generation (Sparc IIi)
492   { "LD",       3, 2, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_LOAD_FLAG },
493   { "LDD",      3, 2, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_LOAD_FLAG },
494   { "LDQ",      3, 2, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_LOAD_FLAG },
495   
496   // Store integer instructions
497   // Latency includes 1 cycle for address generation (Sparc IIi)
498   { "STB",      3, -1, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_STORE_FLAG },
499   { "STH",      3, -1, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_STORE_FLAG },
500   { "STW",      3, -1, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_STORE_FLAG },
501   { "STX",      3, -1, (1 << 12) - 1, true, 0, 3, M_INT_FLAG | M_STORE_FLAG },
502   
503   // Store floating-point instructions (Sparc IIi)
504   { "ST",       3, -1, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_STORE_FLAG},
505   { "STD",      3, -1, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_STORE_FLAG},
506   
507   // Call, Return and "Jump and link".
508   // Latency includes the delay slot.
509   { "CALL",     1, -1, (1 << 29) - 1, true, 1, 2, M_BRANCH_FLAG | M_CALL_FLAG},
510   { "JMPL",     3, -1, (1 << 12) - 1, true, 1, 2, M_BRANCH_FLAG | M_CALL_FLAG},
511   { "RETURN",   2, -1,  0,           false, 1, 2, M_BRANCH_FLAG | M_RET_FLAG },
512   
513   // End-of-array marker
514   { "INVALID_SPARC_OPCODE",     0,  -1,  0,  false, 0, 0,  0x0 }
515 };
516
517
518
519 //---------------------------------------------------------------------------
520 // class UltraSparcInstrInfo 
521 // 
522 // Purpose:
523 //   Information about individual instructions.
524 //   Most information is stored in the SparcMachineInstrDesc array above.
525 //   Other information is computed on demand, and most such functions
526 //   default to member functions in base class MachineInstrInfo. 
527 //---------------------------------------------------------------------------
528
529 class UltraSparcInstrInfo : public MachineInstrInfo {
530 public:
531   /*ctor*/      UltraSparcInstrInfo()
532     : MachineInstrInfo(SparcMachineInstrDesc, INVALID_OPCODE)
533   {}
534   
535   virtual bool          hasResultInterlock      (MachineOpCode opCode)
536   {
537     // All UltraSPARC instructions have interlocks (note that delay slots
538     // are not considered here).
539     // However, instructions that use the result of an FCMP produce a
540     // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
541     // Force the compiler to insert a software interlock (i.e., gap of
542     // 2 other groups, including NOPs if necessary).
543     return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ);
544   }
545 };
546
547
548 //---------------------------------------------------------------------------
549 // class UltraSparcMachine 
550 // 
551 // Purpose:
552 //   Primary interface to machine description for the UltraSPARC.
553 //   Primarily just initializes machine-dependent parameters in
554 //   class TargetMachine, and creates machine-dependent subclasses
555 //   for classes such as MachineInstrInfo. 
556 //---------------------------------------------------------------------------
557
558 class UltraSparc: public TargetMachine {
559 public:
560   /*ctor*/              UltraSparc      ();
561   /*dtor*/ virtual      ~UltraSparc     ();
562 };
563
564
565 /***************************************************************************/
566
567 #endif