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