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