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