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