blob: 87e4cd0e983d3e9d157a1f4abdece6de1dc67db7 [file] [log] [blame]
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001//===-- SparcInternals.h - Header file for Sparc backend ---------*- C++ -*--=//
2//
3// This file defines stuff that is to be private to the Sparc backend, but is
4// shared among different portions of the backend.
5//
6//===----------------------------------------------------------------------===//
7
8#ifndef SPARC_INTERNALS_H
9#define SPARC_INTERNALS_H
10
Chris Lattnerc6495ee2001-09-14 03:56:45 +000011#include "SparcRegInfo.h"
Chris Lattner46cbff62001-09-14 16:56:32 +000012#include "llvm/Target/SchedInfo.h"
Chris Lattnerc6495ee2001-09-14 03:56:45 +000013#include "llvm/Type.h"
Chris Lattner46cbff62001-09-14 16:56:32 +000014#include <sys/types.h>
Chris Lattnerc6495ee2001-09-14 03:56:45 +000015
Chris Lattnerf6e0e282001-09-14 04:32:55 +000016class UltraSparc;
17
Chris Lattnerc6495ee2001-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 Lattnerc6495ee2001-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 Lattnerc6495ee2001-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 Sasankae38bd5332001-09-15 00:30:44 +0000856
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000857//---------------------------------------------------------------------------
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000858// class UltraSparcRegInfo
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000859//
860// Purpose:
861// This class provides info about sparc register classes.
862//---------------------------------------------------------------------------
863
864class LiveRange;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000865class UltraSparc;
866
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000867
868class UltraSparcRegInfo : public MachineRegInfo
869{
870
871 private:
Ruchira Sasankae38bd5332001-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 Lattnerc6495ee2001-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 Lattnerc6495ee2001-09-14 03:56:45 +0000900
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000901 UltraSparcRegInfo(const UltraSparc *const USI ) : UltraSparcInfo(USI),
902 NumOfIntArgRegs(6),
903 NumOfFloatArgRegs(6)
904 {
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000905 MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
906 MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000907 MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
908 MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000909
910 assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 6 &&
911 "6 Float regs are used for float arg passing");
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000912 }
913
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000914 // ***** TODO Delete
915 ~UltraSparcRegInfo(void) { } // empty destructor
916
917
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000918 inline const UltraSparc & getUltraSparcInfo() const {
919 return *UltraSparcInfo;
920 }
921
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000922
923
924 inline unsigned getRegClassIDOfValue (const Value *const Val,
925 bool isCCReg = false) const {
926
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000927 Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000928
929 unsigned res;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000930
931 if( ty && ty <= Type::LongTyID || (ty == Type::PointerTyID) )
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000932 res = IntRegClassID; // sparc int reg (ty=0: void)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000933 else if( ty <= Type::DoubleTyID)
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000934 res = FloatRegClassID; // sparc float reg class
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000935 else {
936 cout << "TypeID: " << ty << endl;
937 assert(0 && "Cannot resolve register class for type");
938
939 }
Ruchira Sasankae38bd5332001-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 Lattnerc6495ee2001-09-14 03:56:45 +0000947 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000948
Ruchira Sasanka866f1382001-09-15 19:11:31 +0000949 // returns the register tha contains always zero
950 inline unsigned getZeroReg() {
951 return SparcIntRegOrder::g0;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000952 }
953
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000954 void colorArgs(const Method *const Meth, LiveRangeInfo& LRI) const;
955
956 static void printReg(const LiveRange *const LR) ;
957
958 void colorCallArgs(vector<const Instruction *> & CallInstrList,
959 LiveRangeInfo& LRI,
960 AddedInstrMapType& AddedInstrMap ) const;
961
962 // this method provides a unique number for each register
963 inline int getUnifiedRegNum(int RegClassID, int reg) const {
964
965 if( RegClassID == IntRegClassID && reg < 32 )
966 return reg;
967 else if ( RegClassID == FloatRegClassID && reg < 64)
968 return reg + 32; // we have 32 int regs
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000969 else if( RegClassID == FloatCCRegClassID && reg < 4)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000970 return reg + 32 + 64; // 32 int, 64 float
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000971 else if( RegClassID == IntCCRegClassID )
972 return 4+ 32 + 64; // only int cc reg
973 else
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000974 assert(0 && "Invalid register class or reg number");
975
976 }
977
978 // given the unified register number, this gives the name
979 inline const string getUnifiedRegName(int reg) const {
980
981 if( reg < 32 )
982 return SparcIntRegOrder::getRegName(reg);
983 else if ( reg < (64 + 32) )
984 return SparcFloatRegOrder::getRegName( reg - 32);
985 else if( reg < (64+32+4) )
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000986 return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
987 else if ( reg == 64+32+4)
988 return "xcc"; // only integer cc reg
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000989 else
990 assert(0 && "Invalid register number");
991 }
992
993
994};
995
996
997
998
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000999/*---------------------------------------------------------------------------
1000Scheduling guidelines for SPARC IIi:
1001
1002I-Cache alignment rules (pg 326)
1003-- Align a branch target instruction so that it's entire group is within
1004 the same cache line (may be 1-4 instructions).
1005** Don't let a branch that is predicted taken be the last instruction
1006 on an I-cache line: delay slot will need an entire line to be fetched
1007-- Make a FP instruction or a branch be the 4th instruction in a group.
1008 For branches, there are tradeoffs in reordering to make this happen
1009 (see pg. 327).
1010** Don't put a branch in a group that crosses a 32-byte boundary!
1011 An artificial branch is inserted after every 32 bytes, and having
1012 another branch will force the group to be broken into 2 groups.
1013
1014iTLB rules:
1015-- Don't let a loop span two memory pages, if possible
1016
1017Branch prediction performance:
1018-- Don't make the branch in a delay slot the target of a branch
1019-- Try not to have 2 predicted branches within a group of 4 instructions
1020 (because each such group has a single branch target field).
1021-- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
1022 the wrong prediction bits being used in some cases).
1023
1024D-Cache timing constraints:
1025-- Signed int loads of less than 64 bits have 3 cycle latency, not 2
1026-- All other loads that hit in D-Cache have 2 cycle latency
1027-- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
1028-- Mis-aligned loads or stores cause a trap. In particular, replace
1029 mis-aligned FP double precision l/s with 2 single-precision l/s.
1030-- Simulations of integer codes show increase in avg. group size of
1031 33% when code (including esp. non-faulting loads) is moved across
1032 one branch, and 50% across 2 branches.
1033
1034E-Cache timing constraints:
1035-- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
1036
1037Store buffer timing constraints:
1038-- Stores can be executed in same cycle as instruction producing the value
1039-- Stores are buffered and have lower priority for E-cache until
1040 highwater mark is reached in the store buffer (5 stores)
1041
1042Pipeline constraints:
1043-- Shifts can only use IEU0.
1044-- CC setting instructions can only use IEU1.
1045-- Several other instructions must only use IEU1:
1046 EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
1047-- Two instructions cannot store to the same register file in a single cycle
1048 (single write port per file).
1049
1050Issue and grouping constraints:
1051-- FP and branch instructions must use slot 4.
1052-- Shift instructions cannot be grouped with other IEU0-specific instructions.
1053-- CC setting instructions cannot be grouped with other IEU1-specific instrs.
1054-- Several instructions must be issued in a single-instruction group:
1055 MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
1056-- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
1057--
1058--
1059
1060Branch delay slot scheduling rules:
1061-- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
1062 has a 9-instruction penalty: the entire pipeline is flushed when the
1063 second instruction reaches stage 9 (W-Writeback).
1064-- Avoid putting multicycle instructions, and instructions that may cause
1065 load misses, in the delay slot of an annulling branch.
1066-- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
1067 delay slot of an annulling branch.
1068
1069 *--------------------------------------------------------------------------- */
1070
1071//---------------------------------------------------------------------------
1072// List of CPUResources for UltraSPARC IIi.
1073//---------------------------------------------------------------------------
1074
1075const CPUResource AllIssueSlots( "All Instr Slots", 4);
1076const CPUResource IntIssueSlots( "Int Instr Slots", 3);
1077const CPUResource First3IssueSlots("Instr Slots 0-3", 3);
1078const CPUResource LSIssueSlots( "Load-Store Instr Slot", 1);
1079const CPUResource CTIIssueSlots( "Ctrl Transfer Instr Slot", 1);
1080const CPUResource FPAIssueSlots( "Int Instr Slot 1", 1);
1081const CPUResource FPMIssueSlots( "Int Instr Slot 1", 1);
1082
1083// IEUN instructions can use either Alu and should use IAluN.
1084// IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0.
1085// IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1.
1086const CPUResource IAluN("Int ALU 1or2", 2);
1087const CPUResource IAlu0("Int ALU 1", 1);
1088const CPUResource IAlu1("Int ALU 2", 1);
1089
1090const CPUResource LSAluC1("Load/Store Unit Addr Cycle", 1);
1091const CPUResource LSAluC2("Load/Store Unit Issue Cycle", 1);
1092const CPUResource LdReturn("Load Return Unit", 1);
1093
1094const CPUResource FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
1095const CPUResource FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
1096const CPUResource FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
1097
1098const CPUResource FPAAluC1("FP Other Alu Cycle 1", 1);
1099const CPUResource FPAAluC2("FP Other Alu Cycle 2", 1);
1100const CPUResource FPAAluC3("FP Other Alu Cycle 3", 1);
1101
1102const CPUResource IRegReadPorts("Int Reg ReadPorts", INT_MAX); // CHECK
1103const CPUResource IRegWritePorts("Int Reg WritePorts", 2); // CHECK
1104const CPUResource FPRegReadPorts("FP Reg Read Ports", INT_MAX); // CHECK
1105const CPUResource FPRegWritePorts("FP Reg Write Ports", 1); // CHECK
1106
1107const CPUResource CTIDelayCycle( "CTI delay cycle", 1);
1108const CPUResource FCMPDelayCycle("FCMP delay cycle", 1);
1109
1110
1111//---------------------------------------------------------------------------
1112// const InstrClassRUsage SparcRUsageDesc[]
1113//
1114// Purpose:
1115// Resource usage information for instruction in each scheduling class.
1116// The InstrRUsage Objects for individual classes are specified first.
1117// Note that fetch and decode are decoupled from the execution pipelines
1118// via an instr buffer, so they are not included in the cycles below.
1119//---------------------------------------------------------------------------
1120
1121const InstrClassRUsage NoneClassRUsage = {
1122 SPARC_NONE,
1123 /*totCycles*/ 7,
1124
1125 /* maxIssueNum */ 4,
1126 /* isSingleIssue */ false,
1127 /* breaksGroup */ false,
1128 /* numBubbles */ 0,
1129
1130 /*numSlots*/ 4,
1131 /* feasibleSlots[] */ { 0, 1, 2, 3 },
1132
1133 /*numEntries*/ 0,
1134 /* V[] */ {
1135 /*Cycle G */
1136 /*Cycle E */
1137 /*Cycle C */
1138 /*Cycle N1*/
1139 /*Cycle N1*/
1140 /*Cycle N1*/
1141 /*Cycle W */
1142 }
1143};
1144
1145const InstrClassRUsage IEUNClassRUsage = {
1146 SPARC_IEUN,
1147 /*totCycles*/ 7,
1148
1149 /* maxIssueNum */ 3,
1150 /* isSingleIssue */ false,
1151 /* breaksGroup */ false,
1152 /* numBubbles */ 0,
1153
1154 /*numSlots*/ 3,
1155 /* feasibleSlots[] */ { 0, 1, 2 },
1156
1157 /*numEntries*/ 4,
1158 /* V[] */ {
1159 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1160 { IntIssueSlots.rid, 0, 1 },
1161 /*Cycle E */ { IAluN.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 IEU0ClassRUsage = {
1171 SPARC_IEU0,
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 { IAlu0.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 IEU1ClassRUsage = {
1197 SPARC_IEU1,
1198 /*totCycles*/ 7,
1199
1200 /* maxIssueNum */ 1,
1201 /* isSingleIssue */ false,
1202 /* breaksGroup */ false,
1203 /* numBubbles */ 0,
1204
1205 /*numSlots*/ 3,
1206 /* feasibleSlots[] */ { 0, 1, 2 },
1207
1208 /*numEntries*/ 5,
1209 /* V[] */ {
1210 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1211 { IntIssueSlots.rid, 0, 1 },
1212 /*Cycle E */ { IAluN.rid, 1, 1 },
1213 { IAlu1.rid, 1, 1 },
1214 /*Cycle C */
1215 /*Cycle N1*/
1216 /*Cycle N1*/
1217 /*Cycle N1*/
1218 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
1219 }
1220};
1221
1222const InstrClassRUsage FPMClassRUsage = {
1223 SPARC_FPM,
1224 /*totCycles*/ 7,
1225
1226 /* maxIssueNum */ 1,
1227 /* isSingleIssue */ false,
1228 /* breaksGroup */ false,
1229 /* numBubbles */ 0,
1230
1231 /*numSlots*/ 4,
1232 /* feasibleSlots[] */ { 0, 1, 2, 3 },
1233
1234 /*numEntries*/ 7,
1235 /* V[] */ {
1236 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1237 { FPMIssueSlots.rid, 0, 1 },
1238 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
1239 /*Cycle C */ { FPMAluC1.rid, 2, 1 },
1240 /*Cycle N1*/ { FPMAluC2.rid, 3, 1 },
1241 /*Cycle N1*/ { FPMAluC3.rid, 4, 1 },
1242 /*Cycle N1*/
1243 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
1244 }
1245};
1246
1247const InstrClassRUsage FPAClassRUsage = {
1248 SPARC_FPA,
1249 /*totCycles*/ 7,
1250
1251 /* maxIssueNum */ 1,
1252 /* isSingleIssue */ false,
1253 /* breaksGroup */ false,
1254 /* numBubbles */ 0,
1255
1256 /*numSlots*/ 4,
1257 /* feasibleSlots[] */ { 0, 1, 2, 3 },
1258
1259 /*numEntries*/ 7,
1260 /* V[] */ {
1261 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1262 { FPAIssueSlots.rid, 0, 1 },
1263 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
1264 /*Cycle C */ { FPAAluC1.rid, 2, 1 },
1265 /*Cycle N1*/ { FPAAluC2.rid, 3, 1 },
1266 /*Cycle N1*/ { FPAAluC3.rid, 4, 1 },
1267 /*Cycle N1*/
1268 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
1269 }
1270};
1271
1272const InstrClassRUsage LDClassRUsage = {
1273 SPARC_LD,
1274 /*totCycles*/ 7,
1275
1276 /* maxIssueNum */ 1,
1277 /* isSingleIssue */ false,
1278 /* breaksGroup */ false,
1279 /* numBubbles */ 0,
1280
1281 /*numSlots*/ 3,
1282 /* feasibleSlots[] */ { 0, 1, 2, },
1283
1284 /*numEntries*/ 6,
1285 /* V[] */ {
1286 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1287 { First3IssueSlots.rid, 0, 1 },
1288 { LSIssueSlots.rid, 0, 1 },
1289 /*Cycle E */ { LSAluC1.rid, 1, 1 },
1290 /*Cycle C */ { LSAluC2.rid, 2, 1 },
1291 { LdReturn.rid, 2, 1 },
1292 /*Cycle N1*/
1293 /*Cycle N1*/
1294 /*Cycle N1*/
1295 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
1296 }
1297};
1298
1299const InstrClassRUsage STClassRUsage = {
1300 SPARC_ST,
1301 /*totCycles*/ 7,
1302
1303 /* maxIssueNum */ 1,
1304 /* isSingleIssue */ false,
1305 /* breaksGroup */ false,
1306 /* numBubbles */ 0,
1307
1308 /*numSlots*/ 3,
1309 /* feasibleSlots[] */ { 0, 1, 2 },
1310
1311 /*numEntries*/ 4,
1312 /* V[] */ {
1313 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1314 { First3IssueSlots.rid, 0, 1 },
1315 { LSIssueSlots.rid, 0, 1 },
1316 /*Cycle E */ { LSAluC1.rid, 1, 1 },
1317 /*Cycle C */ { LSAluC2.rid, 2, 1 }
1318 /*Cycle N1*/
1319 /*Cycle N1*/
1320 /*Cycle N1*/
1321 /*Cycle W */
1322 }
1323};
1324
1325const InstrClassRUsage CTIClassRUsage = {
1326 SPARC_CTI,
1327 /*totCycles*/ 7,
1328
1329 /* maxIssueNum */ 1,
1330 /* isSingleIssue */ false,
1331 /* breaksGroup */ false,
1332 /* numBubbles */ 0,
1333
1334 /*numSlots*/ 4,
1335 /* feasibleSlots[] */ { 0, 1, 2, 3 },
1336
1337 /*numEntries*/ 4,
1338 /* V[] */ {
1339 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1340 { CTIIssueSlots.rid, 0, 1 },
1341 /*Cycle E */ { IAlu0.rid, 1, 1 },
1342 /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
1343 /*Cycle C */
1344 /*Cycle N1*/
1345 /*Cycle N1*/
1346 /*Cycle N1*/
1347 /*Cycle W */
1348 }
1349};
1350
1351const InstrClassRUsage SingleClassRUsage = {
1352 SPARC_SINGLE,
1353 /*totCycles*/ 7,
1354
1355 /* maxIssueNum */ 1,
1356 /* isSingleIssue */ true,
1357 /* breaksGroup */ false,
1358 /* numBubbles */ 0,
1359
1360 /*numSlots*/ 1,
1361 /* feasibleSlots[] */ { 0 },
1362
1363 /*numEntries*/ 5,
1364 /* V[] */ {
1365 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
1366 { AllIssueSlots.rid, 0, 1 },
1367 { AllIssueSlots.rid, 0, 1 },
1368 { AllIssueSlots.rid, 0, 1 },
1369 /*Cycle E */ { IAlu0.rid, 1, 1 }
1370 /*Cycle C */
1371 /*Cycle N1*/
1372 /*Cycle N1*/
1373 /*Cycle N1*/
1374 /*Cycle W */
1375 }
1376};
1377
1378
1379const InstrClassRUsage SparcRUsageDesc[] = {
1380 NoneClassRUsage,
1381 IEUNClassRUsage,
1382 IEU0ClassRUsage,
1383 IEU1ClassRUsage,
1384 FPMClassRUsage,
1385 FPAClassRUsage,
1386 CTIClassRUsage,
1387 LDClassRUsage,
1388 STClassRUsage,
1389 SingleClassRUsage
1390};
1391
1392
1393//---------------------------------------------------------------------------
1394// const InstrIssueDelta SparcInstrIssueDeltas[]
1395//
1396// Purpose:
1397// Changes to issue restrictions information in InstrClassRUsage for
1398// instructions that differ from other instructions in their class.
1399//---------------------------------------------------------------------------
1400
1401const InstrIssueDelta SparcInstrIssueDeltas[] = {
1402
1403 // opCode, isSingleIssue, breaksGroup, numBubbles
1404
1405 // Special cases for single-issue only
1406 // Other single issue cases are below.
1407//{ LDDA, true, true, 0 },
1408//{ STDA, true, true, 0 },
1409//{ LDDF, true, true, 0 },
1410//{ LDDFA, true, true, 0 },
1411 { ADDC, true, true, 0 },
1412 { ADDCcc, true, true, 0 },
1413 { SUBC, true, true, 0 },
1414 { SUBCcc, true, true, 0 },
1415//{ SAVE, true, true, 0 },
1416//{ RESTORE, true, true, 0 },
1417//{ LDSTUB, true, true, 0 },
1418//{ SWAP, true, true, 0 },
1419//{ SWAPA, true, true, 0 },
1420//{ CAS, true, true, 0 },
1421//{ CASA, true, true, 0 },
1422//{ CASX, true, true, 0 },
1423//{ CASXA, true, true, 0 },
1424//{ LDFSR, true, true, 0 },
1425//{ LDFSRA, true, true, 0 },
1426//{ LDXFSR, true, true, 0 },
1427//{ LDXFSRA, true, true, 0 },
1428//{ STFSR, true, true, 0 },
1429//{ STFSRA, true, true, 0 },
1430//{ STXFSR, true, true, 0 },
1431//{ STXFSRA, true, true, 0 },
1432//{ SAVED, true, true, 0 },
1433//{ RESTORED, true, true, 0 },
1434//{ FLUSH, true, true, 9 },
1435//{ FLUSHW, true, true, 9 },
1436//{ ALIGNADDR, true, true, 0 },
1437 { RETURN, true, true, 0 },
1438//{ DONE, true, true, 0 },
1439//{ RETRY, true, true, 0 },
1440//{ WR, true, true, 0 },
1441//{ WRPR, true, true, 4 },
1442//{ RD, true, true, 0 },
1443//{ RDPR, true, true, 0 },
1444//{ TCC, true, true, 0 },
1445//{ SHUTDOWN, true, true, 0 },
1446
1447 // Special cases for breaking group *before*
1448 // CURRENTLY NOT SUPPORTED!
1449 { CALL, false, false, 0 },
1450 { JMPL, false, false, 0 },
1451
1452 // Special cases for breaking the group *after*
1453 { MULX, true, true, (4+34)/2 },
1454 { FDIVS, false, true, 0 },
1455 { FDIVD, false, true, 0 },
1456 { FDIVQ, false, true, 0 },
1457 { FSQRTS, false, true, 0 },
1458 { FSQRTD, false, true, 0 },
1459 { FSQRTQ, false, true, 0 },
1460//{ FCMP{LE,GT,NE,EQ}, false, true, 0 },
1461
1462 // Instructions that introduce bubbles
1463//{ MULScc, true, true, 2 },
1464//{ SMULcc, true, true, (4+18)/2 },
1465//{ UMULcc, true, true, (4+19)/2 },
1466 { SDIVX, true, true, 68 },
1467 { UDIVX, true, true, 68 },
1468//{ SDIVcc, true, true, 36 },
1469//{ UDIVcc, true, true, 37 },
1470//{ WR, false, false, 4 },
1471//{ WRPR, false, false, 4 },
1472};
1473
1474
1475//---------------------------------------------------------------------------
1476// const InstrRUsageDelta SparcInstrUsageDeltas[]
1477//
1478// Purpose:
1479// Changes to resource usage information in InstrClassRUsage for
1480// instructions that differ from other instructions in their class.
1481//---------------------------------------------------------------------------
1482
1483const InstrRUsageDelta SparcInstrUsageDeltas[] = {
1484
1485 // MachineOpCode, Resource, Start cycle, Num cycles
1486
1487 //
1488 // JMPL counts as a load/store instruction for issue!
1489 //
1490 { JMPL, LSIssueSlots.rid, 0, 1 },
1491
1492 //
1493 // Many instructions cannot issue for the next 2 cycles after an FCMP
1494 // We model that with a fake resource FCMPDelayCycle.
1495 //
1496 { FCMPS, FCMPDelayCycle.rid, 1, 3 },
1497 { FCMPD, FCMPDelayCycle.rid, 1, 3 },
1498 { FCMPQ, FCMPDelayCycle.rid, 1, 3 },
1499
1500 { MULX, FCMPDelayCycle.rid, 1, 1 },
1501 { SDIVX, FCMPDelayCycle.rid, 1, 1 },
1502 { UDIVX, FCMPDelayCycle.rid, 1, 1 },
1503//{ SMULcc, FCMPDelayCycle.rid, 1, 1 },
1504//{ UMULcc, FCMPDelayCycle.rid, 1, 1 },
1505//{ SDIVcc, FCMPDelayCycle.rid, 1, 1 },
1506//{ UDIVcc, FCMPDelayCycle.rid, 1, 1 },
1507 { STD, FCMPDelayCycle.rid, 1, 1 },
1508 { FMOVRSZ, FCMPDelayCycle.rid, 1, 1 },
1509 { FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
1510 { FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
1511 { FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
1512 { FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
1513 { FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
1514
1515 //
1516 // Some instructions are stalled in the GROUP stage if a CTI is in
1517 // the E or C stage
1518 //
1519 { LDD, CTIDelayCycle.rid, 1, 1 },
1520//{ LDDA, CTIDelayCycle.rid, 1, 1 },
1521//{ LDDSTUB, CTIDelayCycle.rid, 1, 1 },
1522//{ LDDSTUBA, CTIDelayCycle.rid, 1, 1 },
1523//{ SWAP, CTIDelayCycle.rid, 1, 1 },
1524//{ SWAPA, CTIDelayCycle.rid, 1, 1 },
1525//{ CAS, CTIDelayCycle.rid, 1, 1 },
1526//{ CASA, CTIDelayCycle.rid, 1, 1 },
1527//{ CASX, CTIDelayCycle.rid, 1, 1 },
1528//{ CASXA, CTIDelayCycle.rid, 1, 1 },
1529
1530 //
1531 // Signed int loads of less than dword size return data in cycle N1 (not C)
1532 // and put all loads in consecutive cycles into delayed load return mode.
1533 //
1534 { LDSB, LdReturn.rid, 2, -1 },
1535 { LDSB, LdReturn.rid, 3, 1 },
1536
1537 { LDSH, LdReturn.rid, 2, -1 },
1538 { LDSH, LdReturn.rid, 3, 1 },
1539
1540 { LDSW, LdReturn.rid, 2, -1 },
1541 { LDSW, LdReturn.rid, 3, 1 },
1542
1543
1544#undef EXPLICIT_BUBBLES_NEEDED
1545#ifdef EXPLICIT_BUBBLES_NEEDED
1546 //
1547 // MULScc inserts one bubble.
1548 // This means it breaks the current group (captured in UltraSparcSchedInfo)
1549 // *and occupies all issue slots for the next cycle
1550 //
1551//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1552//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1553//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1554//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1555
1556 //
1557 // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
1558 // We just model this with a simple average.
1559 //
1560//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1561//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1562//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1563//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1564
1565 // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
1566//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1567//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1568//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1569//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1570
1571 //
1572 // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
1573 //
1574 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1575 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1576 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1577 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1578
1579 //
1580 // SDIVcc inserts 36 bubbles.
1581 //
1582//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1583//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1584//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1585//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1586
1587 // UDIVcc inserts 37 bubbles.
1588//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1589//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1590//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1591//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1592
1593 //
1594 // SDIVX inserts 68 bubbles.
1595 //
1596 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1597 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1598 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1599 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1600
1601 //
1602 // UDIVX inserts 68 bubbles.
1603 //
1604 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1605 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1606 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1607 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1608
1609 //
1610 // WR inserts 4 bubbles.
1611 //
1612//{ WR, AllIssueSlots.rid, 2, 68-1 },
1613//{ WR, AllIssueSlots.rid, 2, 68-1 },
1614//{ WR, AllIssueSlots.rid, 2, 68-1 },
1615//{ WR, AllIssueSlots.rid, 2, 68-1 },
1616
1617 //
1618 // WRPR inserts 4 bubbles.
1619 //
1620//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1621//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1622//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1623//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1624
1625 //
1626 // DONE inserts 9 bubbles.
1627 //
1628//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1629//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1630//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1631//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1632
1633 //
1634 // RETRY inserts 9 bubbles.
1635 //
1636//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1637//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1638//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1639//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1640
1641#endif EXPLICIT_BUBBLES_NEEDED
1642};
1643
1644
1645
1646// Additional delays to be captured in code:
1647// 1. RDPR from several state registers (page 349)
1648// 2. RD from *any* register (page 349)
1649// 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
1650// 4. Integer store can be in same group as instr producing value to store.
1651// 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
1652// 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
1653// 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
1654// 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
1655// follow an annulling branch cannot be issued in the same group or in
1656// the 3 groups following the branch.
1657// 9. A predicted annulled load does not stall dependent instructions.
1658// Other annulled delay slot instructions *do* stall dependents, so
1659// nothing special needs to be done for them during scheduling.
1660//10. Do not put a load use that may be annulled in the same group as the
1661// branch. The group will stall until the load returns.
1662//11. Single-prec. FP loads lock 2 registers, for dependency checking.
1663//
1664//
1665// Additional delays we cannot or will not capture:
1666// 1. If DCTI is last word of cache line, it is delayed until next line can be
1667// fetched. Also, other DCTI alignment-related delays (pg 352)
1668// 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
1669// Also, several other store-load and load-store conflicts (pg 358)
1670// 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
1671// 4. There can be at most 8 outstanding buffered store instructions
1672// (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
1673
1674
1675
1676//---------------------------------------------------------------------------
1677// class UltraSparcSchedInfo
1678//
1679// Purpose:
1680// Interface to instruction scheduling information for UltraSPARC.
1681// The parameter values above are based on UltraSPARC IIi.
1682//---------------------------------------------------------------------------
1683
1684
1685class UltraSparcSchedInfo: public MachineSchedInfo {
1686public:
1687 /*ctor*/ UltraSparcSchedInfo (const MachineInstrInfo* mii);
1688 /*dtor*/ virtual ~UltraSparcSchedInfo () {}
1689protected:
1690 virtual void initializeResources ();
1691};
1692
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001693
1694//---------------------------------------------------------------------------
1695// class UltraSparcMachine
1696//
1697// Purpose:
1698// Primary interface to machine description for the UltraSPARC.
1699// Primarily just initializes machine-dependent parameters in
1700// class TargetMachine, and creates machine-dependent subclasses
1701// for classes such as MachineInstrInfo.
1702//---------------------------------------------------------------------------
1703
1704class UltraSparc : public TargetMachine {
1705 UltraSparcInstrInfo InstInfo;
1706 UltraSparcSchedInfo InstSchedulingInfo;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +00001707 UltraSparcRegInfo RegInfo;
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001708public:
1709 UltraSparc();
1710 virtual ~UltraSparc() {}
1711
1712 virtual const MachineInstrInfo& getInstrInfo() const { return InstInfo; }
1713
Ruchira Sasankae38bd5332001-09-15 00:30:44 +00001714 virtual const MachineRegInfo& getRegInfo() const { return RegInfo; }
1715
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001716 // compileMethod - For the sparc, we do instruction selection, followed by
1717 // delay slot scheduling, then register allocation.
1718 //
1719 virtual bool compileMethod(Method *M);
1720};
1721
1722
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001723#endif