SparcInstrInfo.td revision e105a3901fecce76e789566ecbfbc87a5b4ce899
1//===- SparcInstrInfo.td - Target Description for Sparc Target ------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the Sparc instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Instruction format superclass 16//===----------------------------------------------------------------------===// 17 18include "SparcInstrFormats.td" 19 20//===----------------------------------------------------------------------===// 21// Feature predicates. 22//===----------------------------------------------------------------------===// 23 24// HasV9 - This predicate is true when the target processor supports V9 25// instructions. Note that the machine may be running in 32-bit mode. 26def HasV9 : Predicate<"Subtarget.isV9()">; 27 28// HasNoV9 - This predicate is true when the target doesn't have V9 29// instructions. Use of this is just a hack for the isel not having proper 30// costs for V8 instructions that are more expensive than their V9 ones. 31def HasNoV9 : Predicate<"!Subtarget.isV9()">; 32 33// HasVIS - This is true when the target processor has VIS extensions. 34def HasVIS : Predicate<"Subtarget.isVIS()">; 35 36// UseDeprecatedInsts - This predicate is true when the target processor is a 37// V8, or when it is V9 but the V8 deprecated instructions are efficient enough 38// to use when appropriate. In either of these cases, the instruction selector 39// will pick deprecated instructions. 40def UseDeprecatedInsts : Predicate<"Subtarget.useDeprecatedV8Instructions()">; 41 42//===----------------------------------------------------------------------===// 43// Instruction Pattern Stuff 44//===----------------------------------------------------------------------===// 45 46def simm11 : PatLeaf<(imm), [{ return isInt<11>(N->getSExtValue()); }]>; 47 48def simm13 : PatLeaf<(imm), [{ return isInt<13>(N->getSExtValue()); }]>; 49 50def LO10 : SDNodeXForm<imm, [{ 51 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() & 1023, 52 MVT::i32); 53}]>; 54 55def HI22 : SDNodeXForm<imm, [{ 56 // Transformation function: shift the immediate value down into the low bits. 57 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 10, MVT::i32); 58}]>; 59 60def SETHIimm : PatLeaf<(imm), [{ 61 return (((unsigned)N->getZExtValue() >> 10) << 10) == 62 (unsigned)N->getZExtValue(); 63}], HI22>; 64 65// Addressing modes. 66def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>; 67def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex], []>; 68 69// Address operands 70def MEMrr : Operand<i32> { 71 let PrintMethod = "printMemOperand"; 72 let MIOperandInfo = (ops IntRegs, IntRegs); 73} 74def MEMri : Operand<i32> { 75 let PrintMethod = "printMemOperand"; 76 let MIOperandInfo = (ops IntRegs, i32imm); 77} 78 79// Branch targets have OtherVT type. 80def brtarget : Operand<OtherVT>; 81def calltarget : Operand<i32>; 82 83// Operand for printing out a condition code. 84let PrintMethod = "printCCOperand" in 85 def CCOp : Operand<i32>; 86 87def SDTSPcmpfcc : 88SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisSameAs<0, 1>]>; 89def SDTSPbrcc : 90SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 91def SDTSPselectcc : 92SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>]>; 93def SDTSPFTOI : 94SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>; 95def SDTSPITOF : 96SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; 97 98def SPcmpicc : SDNode<"SPISD::CMPICC", SDTIntBinOp, [SDNPOutGlue]>; 99def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>; 100def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 101def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 102 103def SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>; 104def SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>; 105 106def SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>; 107def SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>; 108 109def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>; 110def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>; 111 112// These are target-independent nodes, but have target-specific formats. 113def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 114def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 115 SDTCisVT<1, i32> ]>; 116 117def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 118 [SDNPHasChain, SDNPOutGlue]>; 119def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 120 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 121 122def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; 123def call : SDNode<"SPISD::CALL", SDT_SPCall, 124 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 125 SDNPVariadic]>; 126 127def retflag : SDNode<"SPISD::RET_FLAG", SDTNone, 128 [SDNPHasChain, SDNPOptInGlue]>; 129 130def flushw : SDNode<"SPISD::FLUSHW", SDTNone, 131 [SDNPHasChain]>; 132 133def getPCX : Operand<i32> { 134 let PrintMethod = "printGetPCX"; 135} 136 137//===----------------------------------------------------------------------===// 138// SPARC Flag Conditions 139//===----------------------------------------------------------------------===// 140 141// Note that these values must be kept in sync with the CCOp::CondCode enum 142// values. 143class ICC_VAL<int N> : PatLeaf<(i32 N)>; 144def ICC_NE : ICC_VAL< 9>; // Not Equal 145def ICC_E : ICC_VAL< 1>; // Equal 146def ICC_G : ICC_VAL<10>; // Greater 147def ICC_LE : ICC_VAL< 2>; // Less or Equal 148def ICC_GE : ICC_VAL<11>; // Greater or Equal 149def ICC_L : ICC_VAL< 3>; // Less 150def ICC_GU : ICC_VAL<12>; // Greater Unsigned 151def ICC_LEU : ICC_VAL< 4>; // Less or Equal Unsigned 152def ICC_CC : ICC_VAL<13>; // Carry Clear/Great or Equal Unsigned 153def ICC_CS : ICC_VAL< 5>; // Carry Set/Less Unsigned 154def ICC_POS : ICC_VAL<14>; // Positive 155def ICC_NEG : ICC_VAL< 6>; // Negative 156def ICC_VC : ICC_VAL<15>; // Overflow Clear 157def ICC_VS : ICC_VAL< 7>; // Overflow Set 158 159class FCC_VAL<int N> : PatLeaf<(i32 N)>; 160def FCC_U : FCC_VAL<23>; // Unordered 161def FCC_G : FCC_VAL<22>; // Greater 162def FCC_UG : FCC_VAL<21>; // Unordered or Greater 163def FCC_L : FCC_VAL<20>; // Less 164def FCC_UL : FCC_VAL<19>; // Unordered or Less 165def FCC_LG : FCC_VAL<18>; // Less or Greater 166def FCC_NE : FCC_VAL<17>; // Not Equal 167def FCC_E : FCC_VAL<25>; // Equal 168def FCC_UE : FCC_VAL<24>; // Unordered or Equal 169def FCC_GE : FCC_VAL<25>; // Greater or Equal 170def FCC_UGE : FCC_VAL<26>; // Unordered or Greater or Equal 171def FCC_LE : FCC_VAL<27>; // Less or Equal 172def FCC_ULE : FCC_VAL<28>; // Unordered or Less or Equal 173def FCC_O : FCC_VAL<29>; // Ordered 174 175//===----------------------------------------------------------------------===// 176// Instruction Class Templates 177//===----------------------------------------------------------------------===// 178 179/// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot. 180multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode> { 181 def rr : F3_1<2, Op3Val, 182 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 183 !strconcat(OpcStr, " $b, $c, $dst"), 184 [(set IntRegs:$dst, (OpNode IntRegs:$b, IntRegs:$c))]>; 185 def ri : F3_2<2, Op3Val, 186 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 187 !strconcat(OpcStr, " $b, $c, $dst"), 188 [(set IntRegs:$dst, (OpNode IntRegs:$b, simm13:$c))]>; 189} 190 191/// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no 192/// pattern. 193multiclass F3_12np<string OpcStr, bits<6> Op3Val> { 194 def rr : F3_1<2, Op3Val, 195 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 196 !strconcat(OpcStr, " $b, $c, $dst"), []>; 197 def ri : F3_2<2, Op3Val, 198 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 199 !strconcat(OpcStr, " $b, $c, $dst"), []>; 200} 201 202//===----------------------------------------------------------------------===// 203// Instructions 204//===----------------------------------------------------------------------===// 205 206// Pseudo instructions. 207class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 208 : InstSP<outs, ins, asmstr, pattern>; 209 210// GETPCX for PIC 211let Defs = [O7] in { 212 def GETPCX : Pseudo<(outs getPCX:$getpcseq), (ins), "$getpcseq", [] >; 213} 214 215let Defs = [O6], Uses = [O6] in { 216def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 217 "!ADJCALLSTACKDOWN $amt", 218 [(callseq_start timm:$amt)]>; 219def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 220 "!ADJCALLSTACKUP $amt1", 221 [(callseq_end timm:$amt1, timm:$amt2)]>; 222} 223 224let hasSideEffects = 1, mayStore = 1 in { 225 let rd = 0, rs1 = 0, rs2 = 0 in 226 def FLUSHW : F3_1<0b10, 0b101011, (outs), (ins), 227 "flushw", 228 [(flushw)]>, Requires<[HasV9]>; 229 let rd = 0, rs1 = 1, simm13 = 3 in 230 def TA3 : F3_2<0b10, 0b111010, (outs), (ins), 231 "ta 3", 232 [(flushw)]>; 233} 234 235// FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the 236// fpmover pass. 237let Predicates = [HasNoV9] in { // Only emit these in V8 mode. 238 def FpMOVD : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$src), 239 "!FpMOVD $src, $dst", []>; 240 def FpNEGD : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$src), 241 "!FpNEGD $src, $dst", 242 [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>; 243 def FpABSD : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$src), 244 "!FpABSD $src, $dst", 245 [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>; 246} 247 248// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 249// instruction selection into a branch sequence. This has to handle all 250// permutations of selection between i32/f32/f64 on ICC and FCC. 251 // Expanded after instruction selection. 252let Uses = [ICC], usesCustomInserter = 1 in { 253 def SELECT_CC_Int_ICC 254 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 255 "; SELECT_CC_Int_ICC PSEUDO!", 256 [(set IntRegs:$dst, (SPselecticc IntRegs:$T, IntRegs:$F, 257 imm:$Cond))]>; 258 def SELECT_CC_FP_ICC 259 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 260 "; SELECT_CC_FP_ICC PSEUDO!", 261 [(set FPRegs:$dst, (SPselecticc FPRegs:$T, FPRegs:$F, 262 imm:$Cond))]>; 263 264 def SELECT_CC_DFP_ICC 265 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 266 "; SELECT_CC_DFP_ICC PSEUDO!", 267 [(set DFPRegs:$dst, (SPselecticc DFPRegs:$T, DFPRegs:$F, 268 imm:$Cond))]>; 269} 270 271let usesCustomInserter = 1, Uses = [FCC] in { 272 273 def SELECT_CC_Int_FCC 274 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 275 "; SELECT_CC_Int_FCC PSEUDO!", 276 [(set IntRegs:$dst, (SPselectfcc IntRegs:$T, IntRegs:$F, 277 imm:$Cond))]>; 278 279 def SELECT_CC_FP_FCC 280 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 281 "; SELECT_CC_FP_FCC PSEUDO!", 282 [(set FPRegs:$dst, (SPselectfcc FPRegs:$T, FPRegs:$F, 283 imm:$Cond))]>; 284 def SELECT_CC_DFP_FCC 285 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 286 "; SELECT_CC_DFP_FCC PSEUDO!", 287 [(set DFPRegs:$dst, (SPselectfcc DFPRegs:$T, DFPRegs:$F, 288 imm:$Cond))]>; 289} 290 291 292// Section A.3 - Synthetic Instructions, p. 85 293// special cases of JMPL: 294let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in { 295 let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in 296 def RETL: F3_2<2, 0b111000, (outs), (ins), "retl", [(retflag)]>; 297 298 let rd = I7.Num, rs1 = G0.Num, simm13 = 8 in 299 def RET: F3_2<2, 0b111000, (outs), (ins), "ret", []>; 300} 301 302// Section B.1 - Load Integer Instructions, p. 90 303def LDSBrr : F3_1<3, 0b001001, 304 (outs IntRegs:$dst), (ins MEMrr:$addr), 305 "ldsb [$addr], $dst", 306 [(set IntRegs:$dst, (sextloadi8 ADDRrr:$addr))]>; 307def LDSBri : F3_2<3, 0b001001, 308 (outs IntRegs:$dst), (ins MEMri:$addr), 309 "ldsb [$addr], $dst", 310 [(set IntRegs:$dst, (sextloadi8 ADDRri:$addr))]>; 311def LDSHrr : F3_1<3, 0b001010, 312 (outs IntRegs:$dst), (ins MEMrr:$addr), 313 "ldsh [$addr], $dst", 314 [(set IntRegs:$dst, (sextloadi16 ADDRrr:$addr))]>; 315def LDSHri : F3_2<3, 0b001010, 316 (outs IntRegs:$dst), (ins MEMri:$addr), 317 "ldsh [$addr], $dst", 318 [(set IntRegs:$dst, (sextloadi16 ADDRri:$addr))]>; 319def LDUBrr : F3_1<3, 0b000001, 320 (outs IntRegs:$dst), (ins MEMrr:$addr), 321 "ldub [$addr], $dst", 322 [(set IntRegs:$dst, (zextloadi8 ADDRrr:$addr))]>; 323def LDUBri : F3_2<3, 0b000001, 324 (outs IntRegs:$dst), (ins MEMri:$addr), 325 "ldub [$addr], $dst", 326 [(set IntRegs:$dst, (zextloadi8 ADDRri:$addr))]>; 327def LDUHrr : F3_1<3, 0b000010, 328 (outs IntRegs:$dst), (ins MEMrr:$addr), 329 "lduh [$addr], $dst", 330 [(set IntRegs:$dst, (zextloadi16 ADDRrr:$addr))]>; 331def LDUHri : F3_2<3, 0b000010, 332 (outs IntRegs:$dst), (ins MEMri:$addr), 333 "lduh [$addr], $dst", 334 [(set IntRegs:$dst, (zextloadi16 ADDRri:$addr))]>; 335def LDrr : F3_1<3, 0b000000, 336 (outs IntRegs:$dst), (ins MEMrr:$addr), 337 "ld [$addr], $dst", 338 [(set IntRegs:$dst, (load ADDRrr:$addr))]>; 339def LDri : F3_2<3, 0b000000, 340 (outs IntRegs:$dst), (ins MEMri:$addr), 341 "ld [$addr], $dst", 342 [(set IntRegs:$dst, (load ADDRri:$addr))]>; 343 344// Section B.2 - Load Floating-point Instructions, p. 92 345def LDFrr : F3_1<3, 0b100000, 346 (outs FPRegs:$dst), (ins MEMrr:$addr), 347 "ld [$addr], $dst", 348 [(set FPRegs:$dst, (load ADDRrr:$addr))]>; 349def LDFri : F3_2<3, 0b100000, 350 (outs FPRegs:$dst), (ins MEMri:$addr), 351 "ld [$addr], $dst", 352 [(set FPRegs:$dst, (load ADDRri:$addr))]>; 353def LDDFrr : F3_1<3, 0b100011, 354 (outs DFPRegs:$dst), (ins MEMrr:$addr), 355 "ldd [$addr], $dst", 356 [(set DFPRegs:$dst, (load ADDRrr:$addr))]>; 357def LDDFri : F3_2<3, 0b100011, 358 (outs DFPRegs:$dst), (ins MEMri:$addr), 359 "ldd [$addr], $dst", 360 [(set DFPRegs:$dst, (load ADDRri:$addr))]>; 361 362// Section B.4 - Store Integer Instructions, p. 95 363def STBrr : F3_1<3, 0b000101, 364 (outs), (ins MEMrr:$addr, IntRegs:$src), 365 "stb $src, [$addr]", 366 [(truncstorei8 IntRegs:$src, ADDRrr:$addr)]>; 367def STBri : F3_2<3, 0b000101, 368 (outs), (ins MEMri:$addr, IntRegs:$src), 369 "stb $src, [$addr]", 370 [(truncstorei8 IntRegs:$src, ADDRri:$addr)]>; 371def STHrr : F3_1<3, 0b000110, 372 (outs), (ins MEMrr:$addr, IntRegs:$src), 373 "sth $src, [$addr]", 374 [(truncstorei16 IntRegs:$src, ADDRrr:$addr)]>; 375def STHri : F3_2<3, 0b000110, 376 (outs), (ins MEMri:$addr, IntRegs:$src), 377 "sth $src, [$addr]", 378 [(truncstorei16 IntRegs:$src, ADDRri:$addr)]>; 379def STrr : F3_1<3, 0b000100, 380 (outs), (ins MEMrr:$addr, IntRegs:$src), 381 "st $src, [$addr]", 382 [(store IntRegs:$src, ADDRrr:$addr)]>; 383def STri : F3_2<3, 0b000100, 384 (outs), (ins MEMri:$addr, IntRegs:$src), 385 "st $src, [$addr]", 386 [(store IntRegs:$src, ADDRri:$addr)]>; 387 388// Section B.5 - Store Floating-point Instructions, p. 97 389def STFrr : F3_1<3, 0b100100, 390 (outs), (ins MEMrr:$addr, FPRegs:$src), 391 "st $src, [$addr]", 392 [(store FPRegs:$src, ADDRrr:$addr)]>; 393def STFri : F3_2<3, 0b100100, 394 (outs), (ins MEMri:$addr, FPRegs:$src), 395 "st $src, [$addr]", 396 [(store FPRegs:$src, ADDRri:$addr)]>; 397def STDFrr : F3_1<3, 0b100111, 398 (outs), (ins MEMrr:$addr, DFPRegs:$src), 399 "std $src, [$addr]", 400 [(store DFPRegs:$src, ADDRrr:$addr)]>; 401def STDFri : F3_2<3, 0b100111, 402 (outs), (ins MEMri:$addr, DFPRegs:$src), 403 "std $src, [$addr]", 404 [(store DFPRegs:$src, ADDRri:$addr)]>; 405 406// Section B.9 - SETHI Instruction, p. 104 407def SETHIi: F2_1<0b100, 408 (outs IntRegs:$dst), (ins i32imm:$src), 409 "sethi $src, $dst", 410 [(set IntRegs:$dst, SETHIimm:$src)]>; 411 412// Section B.10 - NOP Instruction, p. 105 413// (It's a special case of SETHI) 414let rd = 0, imm22 = 0 in 415 def NOP : F2_1<0b100, (outs), (ins), "nop", []>; 416 417// Section B.11 - Logical Instructions, p. 106 418defm AND : F3_12<"and", 0b000001, and>; 419 420def ANDNrr : F3_1<2, 0b000101, 421 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 422 "andn $b, $c, $dst", 423 [(set IntRegs:$dst, (and IntRegs:$b, (not IntRegs:$c)))]>; 424def ANDNri : F3_2<2, 0b000101, 425 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 426 "andn $b, $c, $dst", []>; 427 428defm OR : F3_12<"or", 0b000010, or>; 429 430def ORNrr : F3_1<2, 0b000110, 431 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 432 "orn $b, $c, $dst", 433 [(set IntRegs:$dst, (or IntRegs:$b, (not IntRegs:$c)))]>; 434def ORNri : F3_2<2, 0b000110, 435 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 436 "orn $b, $c, $dst", []>; 437defm XOR : F3_12<"xor", 0b000011, xor>; 438 439def XNORrr : F3_1<2, 0b000111, 440 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 441 "xnor $b, $c, $dst", 442 [(set IntRegs:$dst, (not (xor IntRegs:$b, IntRegs:$c)))]>; 443def XNORri : F3_2<2, 0b000111, 444 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 445 "xnor $b, $c, $dst", []>; 446 447// Section B.12 - Shift Instructions, p. 107 448defm SLL : F3_12<"sll", 0b100101, shl>; 449defm SRL : F3_12<"srl", 0b100110, srl>; 450defm SRA : F3_12<"sra", 0b100111, sra>; 451 452// Section B.13 - Add Instructions, p. 108 453defm ADD : F3_12<"add", 0b000000, add>; 454 455// "LEA" forms of add (patterns to make tblgen happy) 456def LEA_ADDri : F3_2<2, 0b000000, 457 (outs IntRegs:$dst), (ins MEMri:$addr), 458 "add ${addr:arith}, $dst", 459 [(set IntRegs:$dst, ADDRri:$addr)]>; 460 461let Defs = [ICC] in 462 defm ADDCC : F3_12<"addcc", 0b010000, addc>; 463 464let Uses = [ICC] in 465 defm ADDX : F3_12<"addx", 0b001000, adde>; 466 467// Section B.15 - Subtract Instructions, p. 110 468defm SUB : F3_12 <"sub" , 0b000100, sub>; 469let Uses = [ICC] in 470 defm SUBX : F3_12 <"subx" , 0b001100, sube>; 471 472let Defs = [ICC] in 473 defm SUBCC : F3_12 <"subcc", 0b010100, SPcmpicc>; 474 475let Uses = [ICC], Defs = [ICC] in 476 def SUBXCCrr: F3_1<2, 0b011100, 477 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 478 "subxcc $b, $c, $dst", []>; 479 480 481// Section B.18 - Multiply Instructions, p. 113 482let Defs = [Y] in { 483 defm UMUL : F3_12np<"umul", 0b001010>; 484 defm SMUL : F3_12 <"smul", 0b001011, mul>; 485} 486 487// Section B.19 - Divide Instructions, p. 115 488let Defs = [Y] in { 489 defm UDIV : F3_12np<"udiv", 0b001110>; 490 defm SDIV : F3_12np<"sdiv", 0b001111>; 491} 492 493// Section B.20 - SAVE and RESTORE, p. 117 494defm SAVE : F3_12np<"save" , 0b111100>; 495defm RESTORE : F3_12np<"restore", 0b111101>; 496 497// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119 498 499// conditional branch class: 500class BranchSP<bits<4> cc, dag ins, string asmstr, list<dag> pattern> 501 : F2_2<cc, 0b010, (outs), ins, asmstr, pattern> { 502 let isBranch = 1; 503 let isTerminator = 1; 504 let hasDelaySlot = 1; 505} 506 507let isBarrier = 1 in 508 def BA : BranchSP<0b1000, (ins brtarget:$dst), 509 "ba $dst", 510 [(br bb:$dst)]>; 511 512// FIXME: the encoding for the JIT should look at the condition field. 513let Uses = [ICC] in 514 def BCOND : BranchSP<0, (ins brtarget:$dst, CCOp:$cc), 515 "b$cc $dst", 516 [(SPbricc bb:$dst, imm:$cc)]>; 517 518 519// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 520 521// floating-point conditional branch class: 522class FPBranchSP<bits<4> cc, dag ins, string asmstr, list<dag> pattern> 523 : F2_2<cc, 0b110, (outs), ins, asmstr, pattern> { 524 let isBranch = 1; 525 let isTerminator = 1; 526 let hasDelaySlot = 1; 527} 528 529// FIXME: the encoding for the JIT should look at the condition field. 530let Uses = [FCC] in 531 def FBCOND : FPBranchSP<0, (ins brtarget:$dst, CCOp:$cc), 532 "fb$cc $dst", 533 [(SPbrfcc bb:$dst, imm:$cc)]>; 534 535 536// Section B.24 - Call and Link Instruction, p. 125 537// This is the only Format 1 instruction 538let Uses = [O6], 539 hasDelaySlot = 1, isCall = 1, 540 Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7, 541 D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, 542 ICC, FCC, Y] in { 543 def CALL : InstSP<(outs), (ins calltarget:$dst, variable_ops), 544 "call $dst", []> { 545 bits<30> disp; 546 let op = 1; 547 let Inst{29-0} = disp; 548 } 549 550 // indirect calls 551 def JMPLrr : F3_1<2, 0b111000, 552 (outs), (ins MEMrr:$ptr, variable_ops), 553 "call $ptr", 554 [(call ADDRrr:$ptr)]>; 555 def JMPLri : F3_2<2, 0b111000, 556 (outs), (ins MEMri:$ptr, variable_ops), 557 "call $ptr", 558 [(call ADDRri:$ptr)]>; 559} 560 561// Section B.28 - Read State Register Instructions 562let Uses = [Y] in 563 def RDY : F3_1<2, 0b101000, 564 (outs IntRegs:$dst), (ins), 565 "rd %y, $dst", []>; 566 567// Section B.29 - Write State Register Instructions 568let Defs = [Y] in { 569 def WRYrr : F3_1<2, 0b110000, 570 (outs), (ins IntRegs:$b, IntRegs:$c), 571 "wr $b, $c, %y", []>; 572 def WRYri : F3_2<2, 0b110000, 573 (outs), (ins IntRegs:$b, i32imm:$c), 574 "wr $b, $c, %y", []>; 575} 576// Convert Integer to Floating-point Instructions, p. 141 577def FITOS : F3_3<2, 0b110100, 0b011000100, 578 (outs FPRegs:$dst), (ins FPRegs:$src), 579 "fitos $src, $dst", 580 [(set FPRegs:$dst, (SPitof FPRegs:$src))]>; 581def FITOD : F3_3<2, 0b110100, 0b011001000, 582 (outs DFPRegs:$dst), (ins FPRegs:$src), 583 "fitod $src, $dst", 584 [(set DFPRegs:$dst, (SPitof FPRegs:$src))]>; 585 586// Convert Floating-point to Integer Instructions, p. 142 587def FSTOI : F3_3<2, 0b110100, 0b011010001, 588 (outs FPRegs:$dst), (ins FPRegs:$src), 589 "fstoi $src, $dst", 590 [(set FPRegs:$dst, (SPftoi FPRegs:$src))]>; 591def FDTOI : F3_3<2, 0b110100, 0b011010010, 592 (outs FPRegs:$dst), (ins DFPRegs:$src), 593 "fdtoi $src, $dst", 594 [(set FPRegs:$dst, (SPftoi DFPRegs:$src))]>; 595 596// Convert between Floating-point Formats Instructions, p. 143 597def FSTOD : F3_3<2, 0b110100, 0b011001001, 598 (outs DFPRegs:$dst), (ins FPRegs:$src), 599 "fstod $src, $dst", 600 [(set DFPRegs:$dst, (fextend FPRegs:$src))]>; 601def FDTOS : F3_3<2, 0b110100, 0b011000110, 602 (outs FPRegs:$dst), (ins DFPRegs:$src), 603 "fdtos $src, $dst", 604 [(set FPRegs:$dst, (fround DFPRegs:$src))]>; 605 606// Floating-point Move Instructions, p. 144 607def FMOVS : F3_3<2, 0b110100, 0b000000001, 608 (outs FPRegs:$dst), (ins FPRegs:$src), 609 "fmovs $src, $dst", []>; 610def FNEGS : F3_3<2, 0b110100, 0b000000101, 611 (outs FPRegs:$dst), (ins FPRegs:$src), 612 "fnegs $src, $dst", 613 [(set FPRegs:$dst, (fneg FPRegs:$src))]>; 614def FABSS : F3_3<2, 0b110100, 0b000001001, 615 (outs FPRegs:$dst), (ins FPRegs:$src), 616 "fabss $src, $dst", 617 [(set FPRegs:$dst, (fabs FPRegs:$src))]>; 618 619 620// Floating-point Square Root Instructions, p.145 621def FSQRTS : F3_3<2, 0b110100, 0b000101001, 622 (outs FPRegs:$dst), (ins FPRegs:$src), 623 "fsqrts $src, $dst", 624 [(set FPRegs:$dst, (fsqrt FPRegs:$src))]>; 625def FSQRTD : F3_3<2, 0b110100, 0b000101010, 626 (outs DFPRegs:$dst), (ins DFPRegs:$src), 627 "fsqrtd $src, $dst", 628 [(set DFPRegs:$dst, (fsqrt DFPRegs:$src))]>; 629 630 631 632// Floating-point Add and Subtract Instructions, p. 146 633def FADDS : F3_3<2, 0b110100, 0b001000001, 634 (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), 635 "fadds $src1, $src2, $dst", 636 [(set FPRegs:$dst, (fadd FPRegs:$src1, FPRegs:$src2))]>; 637def FADDD : F3_3<2, 0b110100, 0b001000010, 638 (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), 639 "faddd $src1, $src2, $dst", 640 [(set DFPRegs:$dst, (fadd DFPRegs:$src1, DFPRegs:$src2))]>; 641def FSUBS : F3_3<2, 0b110100, 0b001000101, 642 (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), 643 "fsubs $src1, $src2, $dst", 644 [(set FPRegs:$dst, (fsub FPRegs:$src1, FPRegs:$src2))]>; 645def FSUBD : F3_3<2, 0b110100, 0b001000110, 646 (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), 647 "fsubd $src1, $src2, $dst", 648 [(set DFPRegs:$dst, (fsub DFPRegs:$src1, DFPRegs:$src2))]>; 649 650// Floating-point Multiply and Divide Instructions, p. 147 651def FMULS : F3_3<2, 0b110100, 0b001001001, 652 (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), 653 "fmuls $src1, $src2, $dst", 654 [(set FPRegs:$dst, (fmul FPRegs:$src1, FPRegs:$src2))]>; 655def FMULD : F3_3<2, 0b110100, 0b001001010, 656 (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), 657 "fmuld $src1, $src2, $dst", 658 [(set DFPRegs:$dst, (fmul DFPRegs:$src1, DFPRegs:$src2))]>; 659def FSMULD : F3_3<2, 0b110100, 0b001101001, 660 (outs DFPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), 661 "fsmuld $src1, $src2, $dst", 662 [(set DFPRegs:$dst, (fmul (fextend FPRegs:$src1), 663 (fextend FPRegs:$src2)))]>; 664def FDIVS : F3_3<2, 0b110100, 0b001001101, 665 (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), 666 "fdivs $src1, $src2, $dst", 667 [(set FPRegs:$dst, (fdiv FPRegs:$src1, FPRegs:$src2))]>; 668def FDIVD : F3_3<2, 0b110100, 0b001001110, 669 (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), 670 "fdivd $src1, $src2, $dst", 671 [(set DFPRegs:$dst, (fdiv DFPRegs:$src1, DFPRegs:$src2))]>; 672 673// Floating-point Compare Instructions, p. 148 674// Note: the 2nd template arg is different for these guys. 675// Note 2: the result of a FCMP is not available until the 2nd cycle 676// after the instr is retired, but there is no interlock. This behavior 677// is modelled with a forced noop after the instruction. 678let Defs = [FCC] in { 679 def FCMPS : F3_3<2, 0b110101, 0b001010001, 680 (outs), (ins FPRegs:$src1, FPRegs:$src2), 681 "fcmps $src1, $src2\n\tnop", 682 [(SPcmpfcc FPRegs:$src1, FPRegs:$src2)]>; 683 def FCMPD : F3_3<2, 0b110101, 0b001010010, 684 (outs), (ins DFPRegs:$src1, DFPRegs:$src2), 685 "fcmpd $src1, $src2\n\tnop", 686 [(SPcmpfcc DFPRegs:$src1, DFPRegs:$src2)]>; 687} 688 689//===----------------------------------------------------------------------===// 690// V9 Instructions 691//===----------------------------------------------------------------------===// 692 693// V9 Conditional Moves. 694let Predicates = [HasV9], Constraints = "$T = $dst" in { 695 // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. 696 // FIXME: Add instruction encodings for the JIT some day. 697 let Uses = [ICC] in { 698 def MOVICCrr 699 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, CCOp:$cc), 700 "mov$cc %icc, $F, $dst", 701 [(set IntRegs:$dst, 702 (SPselecticc IntRegs:$F, IntRegs:$T, imm:$cc))]>; 703 def MOVICCri 704 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, i32imm:$F, CCOp:$cc), 705 "mov$cc %icc, $F, $dst", 706 [(set IntRegs:$dst, 707 (SPselecticc simm11:$F, IntRegs:$T, imm:$cc))]>; 708 } 709 710 let Uses = [FCC] in { 711 def MOVFCCrr 712 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, CCOp:$cc), 713 "mov$cc %fcc0, $F, $dst", 714 [(set IntRegs:$dst, 715 (SPselectfcc IntRegs:$F, IntRegs:$T, imm:$cc))]>; 716 def MOVFCCri 717 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, i32imm:$F, CCOp:$cc), 718 "mov$cc %fcc0, $F, $dst", 719 [(set IntRegs:$dst, 720 (SPselectfcc simm11:$F, IntRegs:$T, imm:$cc))]>; 721 } 722 723 let Uses = [ICC] in { 724 def FMOVS_ICC 725 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, CCOp:$cc), 726 "fmovs$cc %icc, $F, $dst", 727 [(set FPRegs:$dst, 728 (SPselecticc FPRegs:$F, FPRegs:$T, imm:$cc))]>; 729 def FMOVD_ICC 730 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, CCOp:$cc), 731 "fmovd$cc %icc, $F, $dst", 732 [(set DFPRegs:$dst, 733 (SPselecticc DFPRegs:$F, DFPRegs:$T, imm:$cc))]>; 734 } 735 736 let Uses = [FCC] in { 737 def FMOVS_FCC 738 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, CCOp:$cc), 739 "fmovs$cc %fcc0, $F, $dst", 740 [(set FPRegs:$dst, 741 (SPselectfcc FPRegs:$F, FPRegs:$T, imm:$cc))]>; 742 def FMOVD_FCC 743 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, CCOp:$cc), 744 "fmovd$cc %fcc0, $F, $dst", 745 [(set DFPRegs:$dst, 746 (SPselectfcc DFPRegs:$F, DFPRegs:$T, imm:$cc))]>; 747 } 748 749} 750 751// Floating-Point Move Instructions, p. 164 of the V9 manual. 752let Predicates = [HasV9] in { 753 def FMOVD : F3_3<2, 0b110100, 0b000000010, 754 (outs DFPRegs:$dst), (ins DFPRegs:$src), 755 "fmovd $src, $dst", []>; 756 def FNEGD : F3_3<2, 0b110100, 0b000000110, 757 (outs DFPRegs:$dst), (ins DFPRegs:$src), 758 "fnegd $src, $dst", 759 [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>; 760 def FABSD : F3_3<2, 0b110100, 0b000001010, 761 (outs DFPRegs:$dst), (ins DFPRegs:$src), 762 "fabsd $src, $dst", 763 [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>; 764} 765 766// POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear 767// the top 32-bits before using it. To do this clearing, we use a SLLri X,0. 768def POPCrr : F3_1<2, 0b101110, 769 (outs IntRegs:$dst), (ins IntRegs:$src), 770 "popc $src, $dst", []>, Requires<[HasV9]>; 771def : Pat<(ctpop IntRegs:$src), 772 (POPCrr (SLLri IntRegs:$src, 0))>; 773 774//===----------------------------------------------------------------------===// 775// Non-Instruction Patterns 776//===----------------------------------------------------------------------===// 777 778// Small immediates. 779def : Pat<(i32 simm13:$val), 780 (ORri G0, imm:$val)>; 781// Arbitrary immediates. 782def : Pat<(i32 imm:$val), 783 (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>; 784 785// subc 786def : Pat<(subc IntRegs:$b, IntRegs:$c), 787 (SUBCCrr IntRegs:$b, IntRegs:$c)>; 788def : Pat<(subc IntRegs:$b, simm13:$val), 789 (SUBCCri IntRegs:$b, imm:$val)>; 790 791// Global addresses, constant pool entries 792def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; 793def : Pat<(SPlo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>; 794def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>; 795def : Pat<(SPlo tconstpool:$in), (ORri G0, tconstpool:$in)>; 796 797// Add reg, lo. This is used when taking the addr of a global/constpool entry. 798def : Pat<(add IntRegs:$r, (SPlo tglobaladdr:$in)), 799 (ADDri IntRegs:$r, tglobaladdr:$in)>; 800def : Pat<(add IntRegs:$r, (SPlo tconstpool:$in)), 801 (ADDri IntRegs:$r, tconstpool:$in)>; 802 803// Calls: 804def : Pat<(call tglobaladdr:$dst), 805 (CALL tglobaladdr:$dst)>; 806def : Pat<(call texternalsym:$dst), 807 (CALL texternalsym:$dst)>; 808 809// Map integer extload's to zextloads. 810def : Pat<(i32 (extloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 811def : Pat<(i32 (extloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 812def : Pat<(i32 (extloadi8 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 813def : Pat<(i32 (extloadi8 ADDRri:$src)), (LDUBri ADDRri:$src)>; 814def : Pat<(i32 (extloadi16 ADDRrr:$src)), (LDUHrr ADDRrr:$src)>; 815def : Pat<(i32 (extloadi16 ADDRri:$src)), (LDUHri ADDRri:$src)>; 816 817// zextload bool -> zextload byte 818def : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 819def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 820