2 //***************************************************************************
9 // 7/15/01 - Vikram Adve - Created
10 //**************************************************************************/
12 #ifndef LLVM_CODEGEN_SPARC_H
13 #define LLVM_CODEGEN_SPARC_H
15 #include "llvm/CodeGen/TargetMachine.h"
17 // OpCodeMask definitions for the Sparc V9
19 const OpCodeMask Immed = 0x00002000; // immed or reg operand?
20 const OpCodeMask Annul = 0x20000000; // annul delay instr?
21 const OpCodeMask PredictTaken = 0x00080000; // predict branch taken?
24 //---------------------------------------------------------------------------
25 // enum SparcMachineOpCode.
26 // const MachineInstrDescriptor SparcMachineInstrDesc[]
29 // Description of UltraSparc machine instructions.
31 //---------------------------------------------------------------------------
34 enum SparcMachineOpCode {
38 // Synthetic SPARC assembly opcodes for setting a register to a constant
42 // Set high-order bits of register and clear low-order bits
45 // Add or add with carry.
46 // Immed bit specifies if second operand is immediate(1) or register(0)
52 // Subtract or subtract with carry.
53 // Immed bit specifies if second operand is immediate(1) or register(0)
59 // Integer multiply, signed divide, unsigned divide.
60 // Note that the deprecated 32-bit multiply and multiply-step are not used.
65 // Floating point add, subtract, compare
75 // NOTE: FCMPE{S,D,Q}: FP Compare With Exception are currently unused!
77 // Floating point multiply or divide.
109 // Convert from floating point to floating point formats
117 // Convert from floating point to integer formats
125 // Convert from integer to floating point formats
133 // Branch on integer comparison with zero.
134 // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
135 // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
143 // Branch on integer condition code.
144 // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
145 // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
163 // Branch on floating point condition code.
164 // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
165 // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
183 // Conditional move on integer comparison with zero.
191 // Conditional move on integer condition code.
209 // Conditional move on floating point condition code.
210 // Note that the enum name is not the same as the assembly mnemonic below
211 // because that would duplicate some entries with those above.
212 // Therefore, we use MOVF here instead of MOV.
230 // Load integer instructions
239 // Load floating-point instructions
241 LDD, // use of this for integers is deprecated for Sparc V9
244 // Store integer instructions
250 // Store floating-point instructions
254 // Call, Return, and "Jump and link"
255 // Immed bit specifies if second operand is immediate(1) or register(0)
260 // End-of-array marker
264 const MachineInstrDescriptor SparcMachineInstrDesc[] = {
266 // Fields of each structure:
269 // resultPosition (0-based; -1 if no result),
271 // immedIsSignExtended,
272 // numDelaySlots (in cycles)
273 // latency (in cycles)
276 { "NOP", 0, -1, 0, false, 0, 1, M_NOP_FLAG },
278 // Synthetic SPARC assembly opcodes for setting a register to a constant.
279 // Max immediate constant should be ignored for both these instructions.
280 { "SETSW", 2, 1, 0, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
281 { "SETUW", 2, 1, 0, false, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG | M_ARITH_FLAG },
283 // Set high-order bits of register and clear low-order bits
284 { "SETHI", 2, 1, (1 << 22) - 1, false, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG | M_ARITH_FLAG },
286 // Add or add with carry.
287 { "ADD", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
288 { "ADDcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
289 { "ADDC", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
290 { "ADDCcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
292 // Sub tract or subtract with carry.
293 { "SUB", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
294 { "SUBcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
295 { "SUBC", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
296 { "SUBCcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
298 // Integer multiply, signed divide, unsigned divide.
299 // Note that the deprecated 32-bit multiply and multiply-step are not used.
300 { "MULX", 3, 2, (1 << 12) - 1, true, 0, 3, M_INT_FLAG | M_ARITH_FLAG },
301 { "SDIVX", 3, 2, (1 << 12) - 1, true, 0, 6, M_INT_FLAG | M_ARITH_FLAG },
302 { "UDIVX", 3, 2, (1 << 12) - 1, true, 0, 6, M_INT_FLAG | M_ARITH_FLAG },
304 // Floating point add, subtract, compare.
305 // Note that destination of FCMP* instructions is operand 0, not operand 2.
306 { "FADDS", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
307 { "FADDD", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
308 { "FADDQ", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
309 { "FSUBS", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
310 { "FSUBD", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
311 { "FSUBQ", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
312 { "FCMPS", 3, 0, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
313 { "FCMPD", 3, 0, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
314 { "FCMPQ", 3, 0, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
315 // NOTE: FCMPE{S,D,Q}: FP Compare With Exception are currently unused!
317 // Floating point multiply or divide.
318 { "FMULS", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
319 { "FMULD", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
320 { "FMULQ", 3, 2, 0, false, 0, 0, M_FLOAT_FLAG | M_ARITH_FLAG },
321 { "FSMULD", 3, 2, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
322 { "FDMULQ", 3, 2, 0, false, 0, 0, M_FLOAT_FLAG | M_ARITH_FLAG },
323 { "FDIVS", 3, 2, 0, false, 0, 22, M_FLOAT_FLAG | M_ARITH_FLAG },
324 { "FDIVD", 3, 2, 0, false, 0, 22, M_FLOAT_FLAG | M_ARITH_FLAG },
325 { "FDIVQ", 3, 2, 0, false, 0, 0, M_FLOAT_FLAG | M_ARITH_FLAG },
327 // Logical operations
328 { "AND", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
329 { "ANDcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
330 { "ANDN", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
331 { "ANDNcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
332 { "OR", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
333 { "ORcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
334 { "ORN", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
335 { "ORNcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
336 { "XOR", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
337 { "XORcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
338 { "XNOR", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
339 { "XNORcc", 3, 2, (1 << 12) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
342 { "SLL", 3, 2, (1 << 5) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
343 { "SRL", 3, 2, (1 << 5) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
344 { "SRA", 3, 2, (1 << 5) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
345 { "SLLX", 3, 2, (1 << 6) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
346 { "SRLX", 3, 2, (1 << 6) - 1, true, 0, 1, M_INT_FLAG | M_LOGICAL_FLAG},
347 { "SRAX", 3, 2, (1 << 6) - 1, true, 0, 1, M_INT_FLAG | M_ARITH_FLAG },
349 // Convert from floating point to floating point formats
350 { "FSTOD", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
351 { "FSTOQ", 2, 1, 0, false, 0, 0, M_FLOAT_FLAG | M_ARITH_FLAG },
352 { "FDTOS", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_ARITH_FLAG },
353 { "FDTOQ", 2, 1, 0, false, 0, 0, M_FLOAT_FLAG | M_ARITH_FLAG },
354 { "FQTOS", 2, 1, 0, false, 0, 0, M_FLOAT_FLAG | M_ARITH_FLAG },
355 { "FQTOD", 2, 1, 0, false, 0, 0, M_FLOAT_FLAG | M_ARITH_FLAG },
357 // Convert from floating point to integer formats.
358 // Note that this accesses both integer and floating point registers.
359 { "FSTOX", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
360 { "FDTOX", 2, 1, 0, false, 0, 0, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
361 { "FQTOX", 2, 1, 0, false, 0, 2, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
362 { "FSTOI", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
363 { "FDTOI", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
364 { "FQTOI", 2, 1, 0, false, 0, 0, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
366 // Convert from integer to floating point formats
367 // Note that this accesses both integer and floating point registers.
368 { "FXTOS", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
369 { "FXTOD", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
370 { "FXTOQ", 2, 1, 0, false, 0, 0, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
371 { "FITOS", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
372 { "FITOD", 2, 1, 0, false, 0, 3, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
373 { "FITOQ", 2, 1, 0, false, 0, 0, M_FLOAT_FLAG | M_INT_FLAG | M_ARITH_FLAG },
375 // Branch on integer comparison with zero.
376 // Latency includes the delay slot.
377 { "BRZ", 2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
378 { "BRLEZ", 2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
379 { "BRLZ", 2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
380 { "BRNZ", 2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
381 { "BRGZ", 2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
382 { "BRGEZ", 2, -1, (1 << 15) - 1, true, 1, 2, M_INT_FLAG | M_BRANCH_FLAG },
384 // Branch on condition code.
385 // The first argument specifies the ICC register: %icc or %xcc
386 // Latency includes the delay slot.
387 { "BA", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
388 { "BN", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
389 { "BNE", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
390 { "BE", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
391 { "BG", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
392 { "BLE", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
393 { "BGE", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
394 { "BL", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
395 { "BGU", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
396 { "BLEU", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
397 { "BCC", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
398 { "BCS", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
399 { "BPOS", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
400 { "BNEG", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
401 { "BVC", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
402 { "BVS", 2, -1, (1 << 21) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
404 // Branch on floating point condition code.
405 // Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
406 // PredictTaken bit hints if branch should be predicted taken(1) or not(0).
407 // The first argument is the FCCn register (0 <= n <= 3).
408 // Latency includes the delay slot.
409 { "FBA", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
410 { "FBN", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
411 { "FBU", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
412 { "FBG", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
413 { "FBUG", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
414 { "FBL", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
415 { "FBUL", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
416 { "FBLG", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
417 { "FBNE", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
418 { "FBE", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
419 { "FBUE", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
420 { "FBGE", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
421 { "FBUGE", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
422 { "FBLE", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
423 { "FBULE", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
424 { "FBO", 2, -1, (1 << 18) - 1, true, 1, 2, M_CC_FLAG | M_BRANCH_FLAG },
426 // Conditional move on integer comparison with zero.
427 { "MOVRZ", 3, 2, (1 << 12) - 1, true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
428 { "MOVRLEZ", 3, 2, (1 << 12) - 1, true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
429 { "MOVRLZ", 3, 2, (1 << 12) - 1, true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
430 { "MOVRNZ", 3, 2, (1 << 12) - 1, true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
431 { "MOVRGZ", 3, 2, (1 << 12) - 1, true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
432 { "MOVRGEZ", 3, 2, (1 << 12) - 1, true, 0, 1, M_CONDL_FLAG | M_INT_FLAG },
434 // Conditional move on integer condition code.
435 // The first argument specifies the ICC register: %icc or %xcc
436 { "MOVA", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
437 { "MOVN", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
438 { "MOVNE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
439 { "MOVE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
440 { "MOVG", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
441 { "MOVLE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
442 { "MOVGE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
443 { "MOVL", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
444 { "MOVGU", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
445 { "MOVLEU", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
446 { "MOVCC", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
447 { "MOVCS", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
448 { "MOVPOS", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
449 { "MOVNEG", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
450 { "MOVVC", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
451 { "MOVVS", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
453 // Conditional move (of integer register) on floating point condition code.
454 // The first argument is the FCCn register (0 <= n <= 3).
455 // Note that the enum name above is not the same as the assembly mnemonic
456 // because some of the assembly mnemonics are the same as the move on
457 // integer CC (e.g., MOVG), and we cannot have the same enum entry twice.
458 { "MOVA", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
459 { "MOVN", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
460 { "MOVU", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
461 { "MOVG", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
462 { "MOVUG", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
463 { "MOVL", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
464 { "MOVUL", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
465 { "MOVLG", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
466 { "MOVNE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
467 { "MOVE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
468 { "MOVUE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
469 { "MOVGE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
470 { "MOVUGE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
471 { "MOVLE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
472 { "MOVULE", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
473 { "MOVO", 3, 2, (1 << 12) - 1, true, 0, 1, M_CC_FLAG | M_INT_FLAG },
475 // Load integer instructions
476 // Latency includes 1 cycle for address generation (Sparc IIi)
477 // Signed loads of less than 64 bits need an extra cycle for sign-extension.
479 // Not reflected here: After a 3-cycle loads, all subsequent consecutive
480 // loads also require 3 cycles to avoid contention for the load return
481 // stage. Latency returns to 2 cycles after the first cycle with no load.
482 { "LDSB", 3, 2, (1 << 12) - 1, true, 0, 3, M_INT_FLAG | M_LOAD_FLAG },
483 { "LDSH", 3, 2, (1 << 12) - 1, true, 0, 3, M_INT_FLAG | M_LOAD_FLAG },
484 { "LDSW", 3, 2, (1 << 12) - 1, true, 0, 3, M_INT_FLAG | M_LOAD_FLAG },
485 { "LDUB", 3, 2, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_LOAD_FLAG },
486 { "LDUH", 3, 2, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_LOAD_FLAG },
487 { "LDUW", 3, 2, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_LOAD_FLAG },
488 { "LDX", 3, 2, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_LOAD_FLAG },
490 // Load floating-point instructions
491 // Latency includes 1 cycle for address generation (Sparc IIi)
492 { "LD", 3, 2, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_LOAD_FLAG },
493 { "LDD", 3, 2, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_LOAD_FLAG },
494 { "LDQ", 3, 2, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_LOAD_FLAG },
496 // Store integer instructions
497 // Latency includes 1 cycle for address generation (Sparc IIi)
498 { "STB", 3, -1, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_STORE_FLAG },
499 { "STH", 3, -1, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_STORE_FLAG },
500 { "STW", 3, -1, (1 << 12) - 1, true, 0, 2, M_INT_FLAG | M_STORE_FLAG },
501 { "STX", 3, -1, (1 << 12) - 1, true, 0, 3, M_INT_FLAG | M_STORE_FLAG },
503 // Store floating-point instructions (Sparc IIi)
504 { "ST", 3, -1, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_STORE_FLAG},
505 { "STD", 3, -1, (1 << 12) - 1, true, 0, 2, M_FLOAT_FLAG | M_STORE_FLAG},
507 // Call, Return and "Jump and link".
508 // Latency includes the delay slot.
509 { "CALL", 1, -1, (1 << 29) - 1, true, 1, 2, M_BRANCH_FLAG | M_CALL_FLAG},
510 { "JMPL", 3, -1, (1 << 12) - 1, true, 1, 2, M_BRANCH_FLAG | M_CALL_FLAG},
511 { "RETURN", 2, -1, 0, false, 1, 2, M_BRANCH_FLAG | M_RET_FLAG },
513 // End-of-array marker
514 { "INVALID_SPARC_OPCODE", 0, -1, 0, false, 0, 0, 0x0 }
519 //---------------------------------------------------------------------------
520 // class UltraSparcInstrInfo
523 // Information about individual instructions.
524 // Most information is stored in the SparcMachineInstrDesc array above.
525 // Other information is computed on demand, and most such functions
526 // default to member functions in base class MachineInstrInfo.
527 //---------------------------------------------------------------------------
529 class UltraSparcInstrInfo : public MachineInstrInfo {
531 /*ctor*/ UltraSparcInstrInfo()
532 : MachineInstrInfo(SparcMachineInstrDesc, INVALID_OPCODE)
535 virtual bool hasResultInterlock (MachineOpCode opCode)
537 // All UltraSPARC instructions have interlocks (note that delay slots
538 // are not considered here).
539 // However, instructions that use the result of an FCMP produce a
540 // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
541 // Force the compiler to insert a software interlock (i.e., gap of
542 // 2 other groups, including NOPs if necessary).
543 return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ);
548 //---------------------------------------------------------------------------
549 // class UltraSparcMachine
552 // Primary interface to machine description for the UltraSPARC.
553 // Primarily just initializes machine-dependent parameters in
554 // class TargetMachine, and creates machine-dependent subclasses
555 // for classes such as MachineInstrInfo.
556 //---------------------------------------------------------------------------
558 class UltraSparc: public TargetMachine {
560 /*ctor*/ UltraSparc ();
561 /*dtor*/ virtual ~UltraSparc ();
565 /***************************************************************************/