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