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