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