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