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 18 include "SparcInstrFormats.td" 19 20 //===----------------------------------------------------------------------===// 21 // Feature predicates. 22 //===----------------------------------------------------------------------===// 23 24 // True when generating 32-bit code. 25 def Is32Bit : Predicate<"!Subtarget->is64Bit()">; 26 27 // True when generating 64-bit code. This also implies HasV9. 28 def Is64Bit : Predicate<"Subtarget->is64Bit()">; 29 30 // HasV9 - This predicate is true when the target processor supports V9 31 // instructions. Note that the machine may be running in 32-bit mode. 32 def HasV9 : Predicate<"Subtarget->isV9()">, 33 AssemblerPredicate<"FeatureV9">; 34 35 // HasNoV9 - This predicate is true when the target doesn't have V9 36 // instructions. Use of this is just a hack for the isel not having proper 37 // costs for V8 instructions that are more expensive than their V9 ones. 38 def HasNoV9 : Predicate<"!Subtarget->isV9()">; 39 40 // HasVIS - This is true when the target processor has VIS extensions. 41 def HasVIS : Predicate<"Subtarget->isVIS()">, 42 AssemblerPredicate<"FeatureVIS">; 43 def HasVIS2 : Predicate<"Subtarget->isVIS2()">, 44 AssemblerPredicate<"FeatureVIS2">; 45 def HasVIS3 : Predicate<"Subtarget->isVIS3()">, 46 AssemblerPredicate<"FeatureVIS3">; 47 48 // HasHardQuad - This is true when the target processor supports quad floating 49 // point instructions. 50 def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">; 51 52 // UseDeprecatedInsts - This predicate is true when the target processor is a 53 // V8, or when it is V9 but the V8 deprecated instructions are efficient enough 54 // to use when appropriate. In either of these cases, the instruction selector 55 // will pick deprecated instructions. 56 def UseDeprecatedInsts : Predicate<"Subtarget->useDeprecatedV8Instructions()">; 57 58 //===----------------------------------------------------------------------===// 59 // Instruction Pattern Stuff 60 //===----------------------------------------------------------------------===// 61 62 def simm11 : PatLeaf<(imm), [{ return isInt<11>(N->getSExtValue()); }]>; 63 64 def simm13 : PatLeaf<(imm), [{ return isInt<13>(N->getSExtValue()); }]>; 65 66 def LO10 : SDNodeXForm<imm, [{ 67 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() & 1023, 68 MVT::i32); 69 }]>; 70 71 def HI22 : SDNodeXForm<imm, [{ 72 // Transformation function: shift the immediate value down into the low bits. 73 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 10, MVT::i32); 74 }]>; 75 76 def SETHIimm : PatLeaf<(imm), [{ 77 return isShiftedUInt<22, 10>(N->getZExtValue()); 78 }], HI22>; 79 80 // Addressing modes. 81 def ADDRrr : ComplexPattern<iPTR, 2, "SelectADDRrr", [], []>; 82 def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri", [frameindex], []>; 83 84 // Address operands 85 def SparcMEMrrAsmOperand : AsmOperandClass { 86 let Name = "MEMrr"; 87 let ParserMethod = "parseMEMOperand"; 88 } 89 90 def SparcMEMriAsmOperand : AsmOperandClass { 91 let Name = "MEMri"; 92 let ParserMethod = "parseMEMOperand"; 93 } 94 95 def MEMrr : Operand<iPTR> { 96 let PrintMethod = "printMemOperand"; 97 let MIOperandInfo = (ops ptr_rc, ptr_rc); 98 let ParserMatchClass = SparcMEMrrAsmOperand; 99 } 100 def MEMri : Operand<iPTR> { 101 let PrintMethod = "printMemOperand"; 102 let MIOperandInfo = (ops ptr_rc, i32imm); 103 let ParserMatchClass = SparcMEMriAsmOperand; 104 } 105 106 def TLSSym : Operand<iPTR>; 107 108 // Branch targets have OtherVT type. 109 def brtarget : Operand<OtherVT> { 110 let EncoderMethod = "getBranchTargetOpValue"; 111 } 112 113 def bprtarget : Operand<OtherVT> { 114 let EncoderMethod = "getBranchPredTargetOpValue"; 115 } 116 117 def bprtarget16 : Operand<OtherVT> { 118 let EncoderMethod = "getBranchOnRegTargetOpValue"; 119 } 120 121 def calltarget : Operand<i32> { 122 let EncoderMethod = "getCallTargetOpValue"; 123 let DecoderMethod = "DecodeCall"; 124 } 125 126 def simm13Op : Operand<i32> { 127 let DecoderMethod = "DecodeSIMM13"; 128 } 129 130 // Operand for printing out a condition code. 131 let PrintMethod = "printCCOperand" in 132 def CCOp : Operand<i32>; 133 134 def SDTSPcmpicc : 135 SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; 136 def SDTSPcmpfcc : 137 SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisSameAs<0, 1>]>; 138 def SDTSPbrcc : 139 SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 140 def SDTSPselectcc : 141 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>]>; 142 def SDTSPFTOI : 143 SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>; 144 def SDTSPITOF : 145 SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; 146 def SDTSPFTOX : 147 SDTypeProfile<1, 1, [SDTCisVT<0, f64>, SDTCisFP<1>]>; 148 def SDTSPXTOF : 149 SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f64>]>; 150 151 def SDTSPtlsadd : 152 SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>; 153 def SDTSPtlsld : 154 SDTypeProfile<1, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>; 155 156 def SPcmpicc : SDNode<"SPISD::CMPICC", SDTSPcmpicc, [SDNPOutGlue]>; 157 def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>; 158 def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 159 def SPbrxcc : SDNode<"SPISD::BRXCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 160 def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 161 162 def SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>; 163 def SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>; 164 165 def SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>; 166 def SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>; 167 def SPftox : SDNode<"SPISD::FTOX", SDTSPFTOX>; 168 def SPxtof : SDNode<"SPISD::XTOF", SDTSPXTOF>; 169 170 def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>; 171 def SPselectxcc : SDNode<"SPISD::SELECT_XCC", SDTSPselectcc, [SDNPInGlue]>; 172 def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>; 173 174 // These are target-independent nodes, but have target-specific formats. 175 def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 176 def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 177 SDTCisVT<1, i32> ]>; 178 179 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 180 [SDNPHasChain, SDNPOutGlue]>; 181 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 182 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 183 184 def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; 185 def call : SDNode<"SPISD::CALL", SDT_SPCall, 186 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 187 SDNPVariadic]>; 188 189 def SDT_SPRet : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 190 def retflag : SDNode<"SPISD::RET_FLAG", SDT_SPRet, 191 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 192 193 def flushw : SDNode<"SPISD::FLUSHW", SDTNone, 194 [SDNPHasChain, SDNPSideEffect, SDNPMayStore]>; 195 196 def tlsadd : SDNode<"SPISD::TLS_ADD", SDTSPtlsadd>; 197 def tlsld : SDNode<"SPISD::TLS_LD", SDTSPtlsld>; 198 def tlscall : SDNode<"SPISD::TLS_CALL", SDT_SPCall, 199 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 200 SDNPVariadic]>; 201 202 def getPCX : Operand<iPTR> { 203 let PrintMethod = "printGetPCX"; 204 } 205 206 //===----------------------------------------------------------------------===// 207 // SPARC Flag Conditions 208 //===----------------------------------------------------------------------===// 209 210 // Note that these values must be kept in sync with the CCOp::CondCode enum 211 // values. 212 class ICC_VAL<int N> : PatLeaf<(i32 N)>; 213 def ICC_NE : ICC_VAL< 9>; // Not Equal 214 def ICC_E : ICC_VAL< 1>; // Equal 215 def ICC_G : ICC_VAL<10>; // Greater 216 def ICC_LE : ICC_VAL< 2>; // Less or Equal 217 def ICC_GE : ICC_VAL<11>; // Greater or Equal 218 def ICC_L : ICC_VAL< 3>; // Less 219 def ICC_GU : ICC_VAL<12>; // Greater Unsigned 220 def ICC_LEU : ICC_VAL< 4>; // Less or Equal Unsigned 221 def ICC_CC : ICC_VAL<13>; // Carry Clear/Great or Equal Unsigned 222 def ICC_CS : ICC_VAL< 5>; // Carry Set/Less Unsigned 223 def ICC_POS : ICC_VAL<14>; // Positive 224 def ICC_NEG : ICC_VAL< 6>; // Negative 225 def ICC_VC : ICC_VAL<15>; // Overflow Clear 226 def ICC_VS : ICC_VAL< 7>; // Overflow Set 227 228 class FCC_VAL<int N> : PatLeaf<(i32 N)>; 229 def FCC_U : FCC_VAL<23>; // Unordered 230 def FCC_G : FCC_VAL<22>; // Greater 231 def FCC_UG : FCC_VAL<21>; // Unordered or Greater 232 def FCC_L : FCC_VAL<20>; // Less 233 def FCC_UL : FCC_VAL<19>; // Unordered or Less 234 def FCC_LG : FCC_VAL<18>; // Less or Greater 235 def FCC_NE : FCC_VAL<17>; // Not Equal 236 def FCC_E : FCC_VAL<25>; // Equal 237 def FCC_UE : FCC_VAL<24>; // Unordered or Equal 238 def FCC_GE : FCC_VAL<25>; // Greater or Equal 239 def FCC_UGE : FCC_VAL<26>; // Unordered or Greater or Equal 240 def FCC_LE : FCC_VAL<27>; // Less or Equal 241 def FCC_ULE : FCC_VAL<28>; // Unordered or Less or Equal 242 def FCC_O : FCC_VAL<29>; // Ordered 243 244 //===----------------------------------------------------------------------===// 245 // Instruction Class Templates 246 //===----------------------------------------------------------------------===// 247 248 /// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot. 249 multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode, 250 RegisterClass RC, ValueType Ty, Operand immOp> { 251 def rr : F3_1<2, Op3Val, 252 (outs RC:$rd), (ins RC:$rs1, RC:$rs2), 253 !strconcat(OpcStr, " $rs1, $rs2, $rd"), 254 [(set Ty:$rd, (OpNode Ty:$rs1, Ty:$rs2))]>; 255 def ri : F3_2<2, Op3Val, 256 (outs RC:$rd), (ins RC:$rs1, immOp:$simm13), 257 !strconcat(OpcStr, " $rs1, $simm13, $rd"), 258 [(set Ty:$rd, (OpNode Ty:$rs1, (Ty simm13:$simm13)))]>; 259 } 260 261 /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no 262 /// pattern. 263 multiclass F3_12np<string OpcStr, bits<6> Op3Val> { 264 def rr : F3_1<2, Op3Val, 265 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 266 !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; 267 def ri : F3_2<2, Op3Val, 268 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 269 !strconcat(OpcStr, " $rs1, $simm13, $rd"), []>; 270 } 271 272 // Load multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot. 273 multiclass Load<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode, 274 RegisterClass RC, ValueType Ty> { 275 def rr : F3_1<3, Op3Val, 276 (outs RC:$dst), (ins MEMrr:$addr), 277 !strconcat(OpcStr, " [$addr], $dst"), 278 [(set Ty:$dst, (OpNode ADDRrr:$addr))]>; 279 def ri : F3_2<3, Op3Val, 280 (outs RC:$dst), (ins MEMri:$addr), 281 !strconcat(OpcStr, " [$addr], $dst"), 282 [(set Ty:$dst, (OpNode ADDRri:$addr))]>; 283 } 284 285 // Store multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot. 286 multiclass Store<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode, 287 RegisterClass RC, ValueType Ty> { 288 def rr : F3_1<3, Op3Val, 289 (outs), (ins MEMrr:$addr, RC:$rd), 290 !strconcat(OpcStr, " $rd, [$addr]"), 291 [(OpNode Ty:$rd, ADDRrr:$addr)]>; 292 def ri : F3_2<3, Op3Val, 293 (outs), (ins MEMri:$addr, RC:$rd), 294 !strconcat(OpcStr, " $rd, [$addr]"), 295 [(OpNode Ty:$rd, ADDRri:$addr)]>; 296 } 297 298 //===----------------------------------------------------------------------===// 299 // Instructions 300 //===----------------------------------------------------------------------===// 301 302 // Pseudo instructions. 303 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 304 : InstSP<outs, ins, asmstr, pattern> { 305 let isCodeGenOnly = 1; 306 let isPseudo = 1; 307 } 308 309 // GETPCX for PIC 310 let Defs = [O7] in { 311 def GETPCX : Pseudo<(outs getPCX:$getpcseq), (ins), "$getpcseq", [] >; 312 } 313 314 let Defs = [O6], Uses = [O6] in { 315 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 316 "!ADJCALLSTACKDOWN $amt", 317 [(callseq_start timm:$amt)]>; 318 def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 319 "!ADJCALLSTACKUP $amt1", 320 [(callseq_end timm:$amt1, timm:$amt2)]>; 321 } 322 323 let hasSideEffects = 1, mayStore = 1 in { 324 let rd = 0, rs1 = 0, rs2 = 0 in 325 def FLUSHW : F3_1<0b10, 0b101011, (outs), (ins), 326 "flushw", 327 [(flushw)]>, Requires<[HasV9]>; 328 let rd = 0, rs1 = 1, simm13 = 3 in 329 def TA3 : F3_2<0b10, 0b111010, (outs), (ins), 330 "ta 3", 331 [(flushw)]>; 332 } 333 334 let isBarrier = 1, isTerminator = 1, rd = 0b01000, rs1 = 0, simm13 = 5 in 335 def TA5 : F3_2<0b10, 0b111010, (outs), (ins), "ta 5", [(trap)]>; 336 337 let rd = 0 in 338 def UNIMP : F2_1<0b000, (outs), (ins i32imm:$imm22), 339 "unimp $imm22", []>; 340 341 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 342 // instruction selection into a branch sequence. This has to handle all 343 // permutations of selection between i32/f32/f64 on ICC and FCC. 344 // Expanded after instruction selection. 345 let Uses = [ICC], usesCustomInserter = 1 in { 346 def SELECT_CC_Int_ICC 347 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 348 "; SELECT_CC_Int_ICC PSEUDO!", 349 [(set i32:$dst, (SPselecticc i32:$T, i32:$F, imm:$Cond))]>; 350 def SELECT_CC_FP_ICC 351 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 352 "; SELECT_CC_FP_ICC PSEUDO!", 353 [(set f32:$dst, (SPselecticc f32:$T, f32:$F, imm:$Cond))]>; 354 355 def SELECT_CC_DFP_ICC 356 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 357 "; SELECT_CC_DFP_ICC PSEUDO!", 358 [(set f64:$dst, (SPselecticc f64:$T, f64:$F, imm:$Cond))]>; 359 360 def SELECT_CC_QFP_ICC 361 : Pseudo<(outs QFPRegs:$dst), (ins QFPRegs:$T, QFPRegs:$F, i32imm:$Cond), 362 "; SELECT_CC_QFP_ICC PSEUDO!", 363 [(set f128:$dst, (SPselecticc f128:$T, f128:$F, imm:$Cond))]>; 364 } 365 366 let usesCustomInserter = 1, Uses = [FCC0] in { 367 368 def SELECT_CC_Int_FCC 369 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 370 "; SELECT_CC_Int_FCC PSEUDO!", 371 [(set i32:$dst, (SPselectfcc i32:$T, i32:$F, imm:$Cond))]>; 372 373 def SELECT_CC_FP_FCC 374 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 375 "; SELECT_CC_FP_FCC PSEUDO!", 376 [(set f32:$dst, (SPselectfcc f32:$T, f32:$F, imm:$Cond))]>; 377 def SELECT_CC_DFP_FCC 378 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 379 "; SELECT_CC_DFP_FCC PSEUDO!", 380 [(set f64:$dst, (SPselectfcc f64:$T, f64:$F, imm:$Cond))]>; 381 def SELECT_CC_QFP_FCC 382 : Pseudo<(outs QFPRegs:$dst), (ins QFPRegs:$T, QFPRegs:$F, i32imm:$Cond), 383 "; SELECT_CC_QFP_FCC PSEUDO!", 384 [(set f128:$dst, (SPselectfcc f128:$T, f128:$F, imm:$Cond))]>; 385 } 386 387 // JMPL Instruction. 388 let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, 389 DecoderMethod = "DecodeJMPL" in { 390 def JMPLrr: F3_1<2, 0b111000, (outs IntRegs:$dst), (ins MEMrr:$addr), 391 "jmpl $addr, $dst", []>; 392 def JMPLri: F3_2<2, 0b111000, (outs IntRegs:$dst), (ins MEMri:$addr), 393 "jmpl $addr, $dst", []>; 394 } 395 396 // Section A.3 - Synthetic Instructions, p. 85 397 // special cases of JMPL: 398 let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, 399 isCodeGenOnly = 1 in { 400 let rd = 0, rs1 = 15 in 401 def RETL: F3_2<2, 0b111000, (outs), (ins i32imm:$val), 402 "jmp %o7+$val", [(retflag simm13:$val)]>; 403 404 let rd = 0, rs1 = 31 in 405 def RET: F3_2<2, 0b111000, (outs), (ins i32imm:$val), 406 "jmp %i7+$val", []>; 407 } 408 409 let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, 410 isBarrier = 1, rd = 0, DecoderMethod = "DecodeReturn" in { 411 def RETTrr : F3_1<2, 0b111001, (outs), (ins MEMrr:$addr), 412 "rett $addr", []>; 413 def RETTri : F3_2<2, 0b111001, (outs), (ins MEMri:$addr), 414 "rett $addr", []>; 415 } 416 417 // Section B.1 - Load Integer Instructions, p. 90 418 let DecoderMethod = "DecodeLoadInt" in { 419 defm LDSB : Load<"ldsb", 0b001001, sextloadi8, IntRegs, i32>; 420 defm LDSH : Load<"ldsh", 0b001010, sextloadi16, IntRegs, i32>; 421 defm LDUB : Load<"ldub", 0b000001, zextloadi8, IntRegs, i32>; 422 defm LDUH : Load<"lduh", 0b000010, zextloadi16, IntRegs, i32>; 423 defm LD : Load<"ld", 0b000000, load, IntRegs, i32>; 424 } 425 426 // Section B.2 - Load Floating-point Instructions, p. 92 427 let DecoderMethod = "DecodeLoadFP" in 428 defm LDF : Load<"ld", 0b100000, load, FPRegs, f32>; 429 let DecoderMethod = "DecodeLoadDFP" in 430 defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64>; 431 let DecoderMethod = "DecodeLoadQFP" in 432 defm LDQF : Load<"ldq", 0b100010, load, QFPRegs, f128>, 433 Requires<[HasV9, HasHardQuad]>; 434 435 // Section B.4 - Store Integer Instructions, p. 95 436 let DecoderMethod = "DecodeStoreInt" in { 437 defm STB : Store<"stb", 0b000101, truncstorei8, IntRegs, i32>; 438 defm STH : Store<"sth", 0b000110, truncstorei16, IntRegs, i32>; 439 defm ST : Store<"st", 0b000100, store, IntRegs, i32>; 440 } 441 442 // Section B.5 - Store Floating-point Instructions, p. 97 443 let DecoderMethod = "DecodeStoreFP" in 444 defm STF : Store<"st", 0b100100, store, FPRegs, f32>; 445 let DecoderMethod = "DecodeStoreDFP" in 446 defm STDF : Store<"std", 0b100111, store, DFPRegs, f64>; 447 let DecoderMethod = "DecodeStoreQFP" in 448 defm STQF : Store<"stq", 0b100110, store, QFPRegs, f128>, 449 Requires<[HasV9, HasHardQuad]>; 450 451 // Section B.9 - SETHI Instruction, p. 104 452 def SETHIi: F2_1<0b100, 453 (outs IntRegs:$rd), (ins i32imm:$imm22), 454 "sethi $imm22, $rd", 455 [(set i32:$rd, SETHIimm:$imm22)]>; 456 457 // Section B.10 - NOP Instruction, p. 105 458 // (It's a special case of SETHI) 459 let rd = 0, imm22 = 0 in 460 def NOP : F2_1<0b100, (outs), (ins), "nop", []>; 461 462 // Section B.11 - Logical Instructions, p. 106 463 defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, simm13Op>; 464 465 def ANDNrr : F3_1<2, 0b000101, 466 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 467 "andn $rs1, $rs2, $rd", 468 [(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>; 469 def ANDNri : F3_2<2, 0b000101, 470 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 471 "andn $rs1, $simm13, $rd", []>; 472 473 defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, simm13Op>; 474 475 def ORNrr : F3_1<2, 0b000110, 476 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 477 "orn $rs1, $rs2, $rd", 478 [(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>; 479 def ORNri : F3_2<2, 0b000110, 480 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 481 "orn $rs1, $simm13, $rd", []>; 482 defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, simm13Op>; 483 484 def XNORrr : F3_1<2, 0b000111, 485 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 486 "xnor $rs1, $rs2, $rd", 487 [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>; 488 def XNORri : F3_2<2, 0b000111, 489 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 490 "xnor $rs1, $simm13, $rd", []>; 491 492 let Defs = [ICC] in { 493 defm ANDCC : F3_12np<"andcc", 0b010001>; 494 defm ANDNCC : F3_12np<"andncc", 0b010101>; 495 defm ORCC : F3_12np<"orcc", 0b010010>; 496 defm ORNCC : F3_12np<"orncc", 0b010110>; 497 defm XORCC : F3_12np<"xorcc", 0b010011>; 498 defm XNORCC : F3_12np<"xnorcc", 0b010111>; 499 } 500 501 // Section B.12 - Shift Instructions, p. 107 502 defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, simm13Op>; 503 defm SRL : F3_12<"srl", 0b100110, srl, IntRegs, i32, simm13Op>; 504 defm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i32, simm13Op>; 505 506 // Section B.13 - Add Instructions, p. 108 507 defm ADD : F3_12<"add", 0b000000, add, IntRegs, i32, simm13Op>; 508 509 // "LEA" forms of add (patterns to make tblgen happy) 510 let Predicates = [Is32Bit], isCodeGenOnly = 1 in 511 def LEA_ADDri : F3_2<2, 0b000000, 512 (outs IntRegs:$dst), (ins MEMri:$addr), 513 "add ${addr:arith}, $dst", 514 [(set iPTR:$dst, ADDRri:$addr)]>; 515 516 let Defs = [ICC] in 517 defm ADDCC : F3_12<"addcc", 0b010000, addc, IntRegs, i32, simm13Op>; 518 519 let Uses = [ICC] in 520 defm ADDC : F3_12np<"addx", 0b001000>; 521 522 let Uses = [ICC], Defs = [ICC] in 523 defm ADDE : F3_12<"addxcc", 0b011000, adde, IntRegs, i32, simm13Op>; 524 525 // Section B.15 - Subtract Instructions, p. 110 526 defm SUB : F3_12 <"sub" , 0b000100, sub, IntRegs, i32, simm13Op>; 527 let Uses = [ICC], Defs = [ICC] in 528 defm SUBE : F3_12 <"subxcc" , 0b011100, sube, IntRegs, i32, simm13Op>; 529 530 let Defs = [ICC] in 531 defm SUBCC : F3_12 <"subcc", 0b010100, subc, IntRegs, i32, simm13Op>; 532 533 let Uses = [ICC] in 534 defm SUBC : F3_12np <"subx", 0b001100>; 535 536 let Defs = [ICC], rd = 0 in { 537 def CMPrr : F3_1<2, 0b010100, 538 (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 539 "cmp $rs1, $rs2", 540 [(SPcmpicc i32:$rs1, i32:$rs2)]>; 541 def CMPri : F3_2<2, 0b010100, 542 (outs), (ins IntRegs:$rs1, simm13Op:$simm13), 543 "cmp $rs1, $simm13", 544 [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>; 545 } 546 547 // Section B.18 - Multiply Instructions, p. 113 548 let Defs = [Y] in { 549 defm UMUL : F3_12np<"umul", 0b001010>; 550 defm SMUL : F3_12 <"smul", 0b001011, mul, IntRegs, i32, simm13Op>; 551 } 552 553 let Defs = [Y, ICC] in { 554 defm UMULCC : F3_12np<"umulcc", 0b011010>; 555 defm SMULCC : F3_12np<"smulcc", 0b011011>; 556 } 557 558 // Section B.19 - Divide Instructions, p. 115 559 let Defs = [Y] in { 560 defm UDIV : F3_12np<"udiv", 0b001110>; 561 defm SDIV : F3_12np<"sdiv", 0b001111>; 562 } 563 564 let Defs = [Y, ICC] in { 565 defm UDIVCC : F3_12np<"udivcc", 0b011110>; 566 defm SDIVCC : F3_12np<"sdivcc", 0b011111>; 567 } 568 569 // Section B.20 - SAVE and RESTORE, p. 117 570 defm SAVE : F3_12np<"save" , 0b111100>; 571 defm RESTORE : F3_12np<"restore", 0b111101>; 572 573 // Section B.21 - Branch on Integer Condition Codes Instructions, p. 119 574 575 // unconditional branch class. 576 class BranchAlways<dag ins, string asmstr, list<dag> pattern> 577 : F2_2<0b010, 0, (outs), ins, asmstr, pattern> { 578 let isBranch = 1; 579 let isTerminator = 1; 580 let hasDelaySlot = 1; 581 let isBarrier = 1; 582 } 583 584 let cond = 8 in 585 def BA : BranchAlways<(ins brtarget:$imm22), "ba $imm22", [(br bb:$imm22)]>; 586 587 588 let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { 589 590 // conditional branch class: 591 class BranchSP<dag ins, string asmstr, list<dag> pattern> 592 : F2_2<0b010, 0, (outs), ins, asmstr, pattern>; 593 594 // conditional branch with annul class: 595 class BranchSPA<dag ins, string asmstr, list<dag> pattern> 596 : F2_2<0b010, 1, (outs), ins, asmstr, pattern>; 597 598 // Conditional branch class on %icc|%xcc with predication: 599 multiclass IPredBranch<string regstr, list<dag> CCPattern> { 600 def CC : F2_3<0b001, 0, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond), 601 !strconcat("b$cond ", !strconcat(regstr, ", $imm19")), 602 CCPattern>; 603 def CCA : F2_3<0b001, 1, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond), 604 !strconcat("b$cond,a ", !strconcat(regstr, ", $imm19")), 605 []>; 606 def CCNT : F2_3<0b001, 0, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond), 607 !strconcat("b$cond,pn ", !strconcat(regstr, ", $imm19")), 608 []>; 609 def CCANT : F2_3<0b001, 1, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond), 610 !strconcat("b$cond,a,pn ", !strconcat(regstr, ", $imm19")), 611 []>; 612 } 613 614 } // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 615 616 617 // Indirect branch instructions. 618 let isTerminator = 1, isBarrier = 1, hasDelaySlot = 1, isBranch =1, 619 isIndirectBranch = 1, rd = 0, isCodeGenOnly = 1 in { 620 def BINDrr : F3_1<2, 0b111000, 621 (outs), (ins MEMrr:$ptr), 622 "jmp $ptr", 623 [(brind ADDRrr:$ptr)]>; 624 def BINDri : F3_2<2, 0b111000, 625 (outs), (ins MEMri:$ptr), 626 "jmp $ptr", 627 [(brind ADDRri:$ptr)]>; 628 } 629 630 let Uses = [ICC] in { 631 def BCOND : BranchSP<(ins brtarget:$imm22, CCOp:$cond), 632 "b$cond $imm22", 633 [(SPbricc bb:$imm22, imm:$cond)]>; 634 def BCONDA : BranchSPA<(ins brtarget:$imm22, CCOp:$cond), 635 "b$cond,a $imm22", []>; 636 637 let Predicates = [HasV9], cc = 0b00 in 638 defm BPI : IPredBranch<"%icc", []>; 639 } 640 641 // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 642 643 let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { 644 645 // floating-point conditional branch class: 646 class FPBranchSP<dag ins, string asmstr, list<dag> pattern> 647 : F2_2<0b110, 0, (outs), ins, asmstr, pattern>; 648 649 // floating-point conditional branch with annul class: 650 class FPBranchSPA<dag ins, string asmstr, list<dag> pattern> 651 : F2_2<0b110, 1, (outs), ins, asmstr, pattern>; 652 653 // Conditional branch class on %fcc0-%fcc3 with predication: 654 multiclass FPredBranch { 655 def CC : F2_3<0b101, 0, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond, 656 FCCRegs:$cc), 657 "fb$cond $cc, $imm19", []>; 658 def CCA : F2_3<0b101, 1, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond, 659 FCCRegs:$cc), 660 "fb$cond,a $cc, $imm19", []>; 661 def CCNT : F2_3<0b101, 0, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond, 662 FCCRegs:$cc), 663 "fb$cond,pn $cc, $imm19", []>; 664 def CCANT : F2_3<0b101, 1, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond, 665 FCCRegs:$cc), 666 "fb$cond,a,pn $cc, $imm19", []>; 667 } 668 } // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 669 670 let Uses = [FCC0] in { 671 def FBCOND : FPBranchSP<(ins brtarget:$imm22, CCOp:$cond), 672 "fb$cond $imm22", 673 [(SPbrfcc bb:$imm22, imm:$cond)]>; 674 def FBCONDA : FPBranchSPA<(ins brtarget:$imm22, CCOp:$cond), 675 "fb$cond,a $imm22", []>; 676 } 677 678 let Predicates = [HasV9] in 679 defm BPF : FPredBranch; 680 681 682 // Section B.24 - Call and Link Instruction, p. 125 683 // This is the only Format 1 instruction 684 let Uses = [O6], 685 hasDelaySlot = 1, isCall = 1 in { 686 def CALL : InstSP<(outs), (ins calltarget:$disp, variable_ops), 687 "call $disp", []> { 688 bits<30> disp; 689 let op = 1; 690 let Inst{29-0} = disp; 691 } 692 693 // indirect calls: special cases of JMPL. 694 let isCodeGenOnly = 1, rd = 15 in { 695 def CALLrr : F3_1<2, 0b111000, 696 (outs), (ins MEMrr:$ptr, variable_ops), 697 "call $ptr", 698 [(call ADDRrr:$ptr)]>; 699 def CALLri : F3_2<2, 0b111000, 700 (outs), (ins MEMri:$ptr, variable_ops), 701 "call $ptr", 702 [(call ADDRri:$ptr)]>; 703 } 704 } 705 706 // Section B.28 - Read State Register Instructions 707 let Uses = [Y], rs1 = 0, rs2 = 0 in 708 def RDY : F3_1<2, 0b101000, 709 (outs IntRegs:$dst), (ins), 710 "rd %y, $dst", []>; 711 712 // Section B.29 - Write State Register Instructions 713 let Defs = [Y], rd = 0 in { 714 def WRYrr : F3_1<2, 0b110000, 715 (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 716 "wr $rs1, $rs2, %y", []>; 717 def WRYri : F3_2<2, 0b110000, 718 (outs), (ins IntRegs:$rs1, simm13Op:$simm13), 719 "wr $rs1, $simm13, %y", []>; 720 } 721 // Convert Integer to Floating-point Instructions, p. 141 722 def FITOS : F3_3u<2, 0b110100, 0b011000100, 723 (outs FPRegs:$rd), (ins FPRegs:$rs2), 724 "fitos $rs2, $rd", 725 [(set FPRegs:$rd, (SPitof FPRegs:$rs2))]>; 726 def FITOD : F3_3u<2, 0b110100, 0b011001000, 727 (outs DFPRegs:$rd), (ins FPRegs:$rs2), 728 "fitod $rs2, $rd", 729 [(set DFPRegs:$rd, (SPitof FPRegs:$rs2))]>; 730 def FITOQ : F3_3u<2, 0b110100, 0b011001100, 731 (outs QFPRegs:$rd), (ins FPRegs:$rs2), 732 "fitoq $rs2, $rd", 733 [(set QFPRegs:$rd, (SPitof FPRegs:$rs2))]>, 734 Requires<[HasHardQuad]>; 735 736 // Convert Floating-point to Integer Instructions, p. 142 737 def FSTOI : F3_3u<2, 0b110100, 0b011010001, 738 (outs FPRegs:$rd), (ins FPRegs:$rs2), 739 "fstoi $rs2, $rd", 740 [(set FPRegs:$rd, (SPftoi FPRegs:$rs2))]>; 741 def FDTOI : F3_3u<2, 0b110100, 0b011010010, 742 (outs FPRegs:$rd), (ins DFPRegs:$rs2), 743 "fdtoi $rs2, $rd", 744 [(set FPRegs:$rd, (SPftoi DFPRegs:$rs2))]>; 745 def FQTOI : F3_3u<2, 0b110100, 0b011010011, 746 (outs FPRegs:$rd), (ins QFPRegs:$rs2), 747 "fqtoi $rs2, $rd", 748 [(set FPRegs:$rd, (SPftoi QFPRegs:$rs2))]>, 749 Requires<[HasHardQuad]>; 750 751 // Convert between Floating-point Formats Instructions, p. 143 752 def FSTOD : F3_3u<2, 0b110100, 0b011001001, 753 (outs DFPRegs:$rd), (ins FPRegs:$rs2), 754 "fstod $rs2, $rd", 755 [(set f64:$rd, (fextend f32:$rs2))]>; 756 def FSTOQ : F3_3u<2, 0b110100, 0b011001101, 757 (outs QFPRegs:$rd), (ins FPRegs:$rs2), 758 "fstoq $rs2, $rd", 759 [(set f128:$rd, (fextend f32:$rs2))]>, 760 Requires<[HasHardQuad]>; 761 def FDTOS : F3_3u<2, 0b110100, 0b011000110, 762 (outs FPRegs:$rd), (ins DFPRegs:$rs2), 763 "fdtos $rs2, $rd", 764 [(set f32:$rd, (fround f64:$rs2))]>; 765 def FDTOQ : F3_3u<2, 0b110100, 0b011001110, 766 (outs QFPRegs:$rd), (ins DFPRegs:$rs2), 767 "fdtoq $rs2, $rd", 768 [(set f128:$rd, (fextend f64:$rs2))]>, 769 Requires<[HasHardQuad]>; 770 def FQTOS : F3_3u<2, 0b110100, 0b011000111, 771 (outs FPRegs:$rd), (ins QFPRegs:$rs2), 772 "fqtos $rs2, $rd", 773 [(set f32:$rd, (fround f128:$rs2))]>, 774 Requires<[HasHardQuad]>; 775 def FQTOD : F3_3u<2, 0b110100, 0b011001011, 776 (outs DFPRegs:$rd), (ins QFPRegs:$rs2), 777 "fqtod $rs2, $rd", 778 [(set f64:$rd, (fround f128:$rs2))]>, 779 Requires<[HasHardQuad]>; 780 781 // Floating-point Move Instructions, p. 144 782 def FMOVS : F3_3u<2, 0b110100, 0b000000001, 783 (outs FPRegs:$rd), (ins FPRegs:$rs2), 784 "fmovs $rs2, $rd", []>; 785 def FNEGS : F3_3u<2, 0b110100, 0b000000101, 786 (outs FPRegs:$rd), (ins FPRegs:$rs2), 787 "fnegs $rs2, $rd", 788 [(set f32:$rd, (fneg f32:$rs2))]>; 789 def FABSS : F3_3u<2, 0b110100, 0b000001001, 790 (outs FPRegs:$rd), (ins FPRegs:$rs2), 791 "fabss $rs2, $rd", 792 [(set f32:$rd, (fabs f32:$rs2))]>; 793 794 795 // Floating-point Square Root Instructions, p.145 796 def FSQRTS : F3_3u<2, 0b110100, 0b000101001, 797 (outs FPRegs:$rd), (ins FPRegs:$rs2), 798 "fsqrts $rs2, $rd", 799 [(set f32:$rd, (fsqrt f32:$rs2))]>; 800 def FSQRTD : F3_3u<2, 0b110100, 0b000101010, 801 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 802 "fsqrtd $rs2, $rd", 803 [(set f64:$rd, (fsqrt f64:$rs2))]>; 804 def FSQRTQ : F3_3u<2, 0b110100, 0b000101011, 805 (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 806 "fsqrtq $rs2, $rd", 807 [(set f128:$rd, (fsqrt f128:$rs2))]>, 808 Requires<[HasHardQuad]>; 809 810 811 812 // Floating-point Add and Subtract Instructions, p. 146 813 def FADDS : F3_3<2, 0b110100, 0b001000001, 814 (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 815 "fadds $rs1, $rs2, $rd", 816 [(set f32:$rd, (fadd f32:$rs1, f32:$rs2))]>; 817 def FADDD : F3_3<2, 0b110100, 0b001000010, 818 (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 819 "faddd $rs1, $rs2, $rd", 820 [(set f64:$rd, (fadd f64:$rs1, f64:$rs2))]>; 821 def FADDQ : F3_3<2, 0b110100, 0b001000011, 822 (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 823 "faddq $rs1, $rs2, $rd", 824 [(set f128:$rd, (fadd f128:$rs1, f128:$rs2))]>, 825 Requires<[HasHardQuad]>; 826 827 def FSUBS : F3_3<2, 0b110100, 0b001000101, 828 (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 829 "fsubs $rs1, $rs2, $rd", 830 [(set f32:$rd, (fsub f32:$rs1, f32:$rs2))]>; 831 def FSUBD : F3_3<2, 0b110100, 0b001000110, 832 (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 833 "fsubd $rs1, $rs2, $rd", 834 [(set f64:$rd, (fsub f64:$rs1, f64:$rs2))]>; 835 def FSUBQ : F3_3<2, 0b110100, 0b001000111, 836 (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 837 "fsubq $rs1, $rs2, $rd", 838 [(set f128:$rd, (fsub f128:$rs1, f128:$rs2))]>, 839 Requires<[HasHardQuad]>; 840 841 842 // Floating-point Multiply and Divide Instructions, p. 147 843 def FMULS : F3_3<2, 0b110100, 0b001001001, 844 (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 845 "fmuls $rs1, $rs2, $rd", 846 [(set f32:$rd, (fmul f32:$rs1, f32:$rs2))]>; 847 def FMULD : F3_3<2, 0b110100, 0b001001010, 848 (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 849 "fmuld $rs1, $rs2, $rd", 850 [(set f64:$rd, (fmul f64:$rs1, f64:$rs2))]>; 851 def FMULQ : F3_3<2, 0b110100, 0b001001011, 852 (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 853 "fmulq $rs1, $rs2, $rd", 854 [(set f128:$rd, (fmul f128:$rs1, f128:$rs2))]>, 855 Requires<[HasHardQuad]>; 856 857 def FSMULD : F3_3<2, 0b110100, 0b001101001, 858 (outs DFPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 859 "fsmuld $rs1, $rs2, $rd", 860 [(set f64:$rd, (fmul (fextend f32:$rs1), 861 (fextend f32:$rs2)))]>; 862 def FDMULQ : F3_3<2, 0b110100, 0b001101110, 863 (outs QFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 864 "fdmulq $rs1, $rs2, $rd", 865 [(set f128:$rd, (fmul (fextend f64:$rs1), 866 (fextend f64:$rs2)))]>, 867 Requires<[HasHardQuad]>; 868 869 def FDIVS : F3_3<2, 0b110100, 0b001001101, 870 (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 871 "fdivs $rs1, $rs2, $rd", 872 [(set f32:$rd, (fdiv f32:$rs1, f32:$rs2))]>; 873 def FDIVD : F3_3<2, 0b110100, 0b001001110, 874 (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 875 "fdivd $rs1, $rs2, $rd", 876 [(set f64:$rd, (fdiv f64:$rs1, f64:$rs2))]>; 877 def FDIVQ : F3_3<2, 0b110100, 0b001001111, 878 (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 879 "fdivq $rs1, $rs2, $rd", 880 [(set f128:$rd, (fdiv f128:$rs1, f128:$rs2))]>, 881 Requires<[HasHardQuad]>; 882 883 // Floating-point Compare Instructions, p. 148 884 // Note: the 2nd template arg is different for these guys. 885 // Note 2: the result of a FCMP is not available until the 2nd cycle 886 // after the instr is retired, but there is no interlock in Sparc V8. 887 // This behavior is modeled with a forced noop after the instruction in 888 // DelaySlotFiller. 889 890 let Defs = [FCC0], rd = 0, isCodeGenOnly = 1 in { 891 def FCMPS : F3_3c<2, 0b110101, 0b001010001, 892 (outs), (ins FPRegs:$rs1, FPRegs:$rs2), 893 "fcmps $rs1, $rs2", 894 [(SPcmpfcc f32:$rs1, f32:$rs2)]>; 895 def FCMPD : F3_3c<2, 0b110101, 0b001010010, 896 (outs), (ins DFPRegs:$rs1, DFPRegs:$rs2), 897 "fcmpd $rs1, $rs2", 898 [(SPcmpfcc f64:$rs1, f64:$rs2)]>; 899 def FCMPQ : F3_3c<2, 0b110101, 0b001010011, 900 (outs), (ins QFPRegs:$rs1, QFPRegs:$rs2), 901 "fcmpq $rs1, $rs2", 902 [(SPcmpfcc f128:$rs1, f128:$rs2)]>, 903 Requires<[HasHardQuad]>; 904 } 905 906 //===----------------------------------------------------------------------===// 907 // Instructions for Thread Local Storage(TLS). 908 //===----------------------------------------------------------------------===// 909 let isCodeGenOnly = 1, isAsmParserOnly = 1 in { 910 def TLS_ADDrr : F3_1<2, 0b000000, 911 (outs IntRegs:$rd), 912 (ins IntRegs:$rs1, IntRegs:$rs2, TLSSym:$sym), 913 "add $rs1, $rs2, $rd, $sym", 914 [(set i32:$rd, 915 (tlsadd i32:$rs1, i32:$rs2, tglobaltlsaddr:$sym))]>; 916 917 let mayLoad = 1 in 918 def TLS_LDrr : F3_1<3, 0b000000, 919 (outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym), 920 "ld [$addr], $dst, $sym", 921 [(set i32:$dst, 922 (tlsld ADDRrr:$addr, tglobaltlsaddr:$sym))]>; 923 924 let Uses = [O6], isCall = 1, hasDelaySlot = 1 in 925 def TLS_CALL : InstSP<(outs), 926 (ins calltarget:$disp, TLSSym:$sym, variable_ops), 927 "call $disp, $sym", 928 [(tlscall texternalsym:$disp, tglobaltlsaddr:$sym)]> { 929 bits<30> disp; 930 let op = 1; 931 let Inst{29-0} = disp; 932 } 933 } 934 935 //===----------------------------------------------------------------------===// 936 // V9 Instructions 937 //===----------------------------------------------------------------------===// 938 939 // V9 Conditional Moves. 940 let Predicates = [HasV9], Constraints = "$f = $rd" in { 941 // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. 942 let Uses = [ICC], intcc = 1, cc = 0b00 in { 943 def MOVICCrr 944 : F4_1<0b101100, (outs IntRegs:$rd), 945 (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), 946 "mov$cond %icc, $rs2, $rd", 947 [(set i32:$rd, (SPselecticc i32:$rs2, i32:$f, imm:$cond))]>; 948 949 def MOVICCri 950 : F4_2<0b101100, (outs IntRegs:$rd), 951 (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond), 952 "mov$cond %icc, $simm11, $rd", 953 [(set i32:$rd, 954 (SPselecticc simm11:$simm11, i32:$f, imm:$cond))]>; 955 } 956 957 let Uses = [FCC0], intcc = 0, cc = 0b00 in { 958 def MOVFCCrr 959 : F4_1<0b101100, (outs IntRegs:$rd), 960 (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), 961 "mov$cond %fcc0, $rs2, $rd", 962 [(set i32:$rd, (SPselectfcc i32:$rs2, i32:$f, imm:$cond))]>; 963 def MOVFCCri 964 : F4_2<0b101100, (outs IntRegs:$rd), 965 (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond), 966 "mov$cond %fcc0, $simm11, $rd", 967 [(set i32:$rd, 968 (SPselectfcc simm11:$simm11, i32:$f, imm:$cond))]>; 969 } 970 971 let Uses = [ICC], intcc = 1, opf_cc = 0b00 in { 972 def FMOVS_ICC 973 : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), 974 (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), 975 "fmovs$cond %icc, $rs2, $rd", 976 [(set f32:$rd, (SPselecticc f32:$rs2, f32:$f, imm:$cond))]>; 977 def FMOVD_ICC 978 : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), 979 (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), 980 "fmovd$cond %icc, $rs2, $rd", 981 [(set f64:$rd, (SPselecticc f64:$rs2, f64:$f, imm:$cond))]>; 982 def FMOVQ_ICC 983 : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), 984 (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), 985 "fmovq$cond %icc, $rs2, $rd", 986 [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>, 987 Requires<[HasHardQuad]>; 988 } 989 990 let Uses = [FCC0], intcc = 0, opf_cc = 0b00 in { 991 def FMOVS_FCC 992 : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), 993 (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), 994 "fmovs$cond %fcc0, $rs2, $rd", 995 [(set f32:$rd, (SPselectfcc f32:$rs2, f32:$f, imm:$cond))]>; 996 def FMOVD_FCC 997 : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), 998 (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), 999 "fmovd$cond %fcc0, $rs2, $rd", 1000 [(set f64:$rd, (SPselectfcc f64:$rs2, f64:$f, imm:$cond))]>; 1001 def FMOVQ_FCC 1002 : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), 1003 (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), 1004 "fmovq$cond %fcc0, $rs2, $rd", 1005 [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>, 1006 Requires<[HasHardQuad]>; 1007 } 1008 1009 } 1010 1011 // Floating-Point Move Instructions, p. 164 of the V9 manual. 1012 let Predicates = [HasV9] in { 1013 def FMOVD : F3_3u<2, 0b110100, 0b000000010, 1014 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 1015 "fmovd $rs2, $rd", []>; 1016 def FMOVQ : F3_3u<2, 0b110100, 0b000000011, 1017 (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 1018 "fmovq $rs2, $rd", []>, 1019 Requires<[HasHardQuad]>; 1020 def FNEGD : F3_3u<2, 0b110100, 0b000000110, 1021 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 1022 "fnegd $rs2, $rd", 1023 [(set f64:$rd, (fneg f64:$rs2))]>; 1024 def FNEGQ : F3_3u<2, 0b110100, 0b000000111, 1025 (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 1026 "fnegq $rs2, $rd", 1027 [(set f128:$rd, (fneg f128:$rs2))]>, 1028 Requires<[HasHardQuad]>; 1029 def FABSD : F3_3u<2, 0b110100, 0b000001010, 1030 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 1031 "fabsd $rs2, $rd", 1032 [(set f64:$rd, (fabs f64:$rs2))]>; 1033 def FABSQ : F3_3u<2, 0b110100, 0b000001011, 1034 (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 1035 "fabsq $rs2, $rd", 1036 [(set f128:$rd, (fabs f128:$rs2))]>, 1037 Requires<[HasHardQuad]>; 1038 } 1039 1040 // Floating-point compare instruction with %fcc0-%fcc3. 1041 def V9FCMPS : F3_3c<2, 0b110101, 0b001010001, 1042 (outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1043 "fcmps $rd, $rs1, $rs2", []>; 1044 def V9FCMPD : F3_3c<2, 0b110101, 0b001010010, 1045 (outs FCCRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1046 "fcmpd $rd, $rs1, $rs2", []>; 1047 def V9FCMPQ : F3_3c<2, 0b110101, 0b001010011, 1048 (outs FCCRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1049 "fcmpq $rd, $rs1, $rs2", []>, 1050 Requires<[HasHardQuad]>; 1051 1052 let hasSideEffects = 1 in { 1053 def V9FCMPES : F3_3c<2, 0b110101, 0b001010101, 1054 (outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1055 "fcmpes $rd, $rs1, $rs2", []>; 1056 def V9FCMPED : F3_3c<2, 0b110101, 0b001010110, 1057 (outs FCCRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1058 "fcmped $rd, $rs1, $rs2", []>; 1059 def V9FCMPEQ : F3_3c<2, 0b110101, 0b001010111, 1060 (outs FCCRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1061 "fcmpeq $rd, $rs1, $rs2", []>, 1062 Requires<[HasHardQuad]>; 1063 } 1064 1065 // Floating point conditional move instrucitons with %fcc0-%fcc3. 1066 let Predicates = [HasV9] in { 1067 let Constraints = "$f = $rd", intcc = 0 in { 1068 def V9MOVFCCrr 1069 : F4_1<0b101100, (outs IntRegs:$rd), 1070 (ins FCCRegs:$cc, IntRegs:$rs2, IntRegs:$f, CCOp:$cond), 1071 "mov$cond $cc, $rs2, $rd", []>; 1072 def V9MOVFCCri 1073 : F4_2<0b101100, (outs IntRegs:$rd), 1074 (ins FCCRegs:$cc, i32imm:$simm11, IntRegs:$f, CCOp:$cond), 1075 "mov$cond $cc, $simm11, $rd", []>; 1076 def V9FMOVS_FCC 1077 : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), 1078 (ins FCCRegs:$opf_cc, FPRegs:$rs2, FPRegs:$f, CCOp:$cond), 1079 "fmovs$cond $opf_cc, $rs2, $rd", []>; 1080 def V9FMOVD_FCC 1081 : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), 1082 (ins FCCRegs:$opf_cc, DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), 1083 "fmovd$cond $opf_cc, $rs2, $rd", []>; 1084 def V9FMOVQ_FCC 1085 : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), 1086 (ins FCCRegs:$opf_cc, QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), 1087 "fmovq$cond $opf_cc, $rs2, $rd", []>, 1088 Requires<[HasHardQuad]>; 1089 } // Constraints = "$f = $rd", ... 1090 } // let Predicates = [hasV9] 1091 1092 1093 // POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear 1094 // the top 32-bits before using it. To do this clearing, we use a SRLri X,0. 1095 let rs1 = 0 in 1096 def POPCrr : F3_1<2, 0b101110, 1097 (outs IntRegs:$dst), (ins IntRegs:$src), 1098 "popc $src, $dst", []>, Requires<[HasV9]>; 1099 def : Pat<(ctpop i32:$src), 1100 (POPCrr (SRLri $src, 0))>; 1101 1102 // Atomic swap. 1103 let hasSideEffects =1, rd = 0, rs1 = 0b01111, rs2 = 0 in 1104 def STBAR : F3_1<2, 0b101000, (outs), (ins), "stbar", []>; 1105 1106 let Predicates = [HasV9], hasSideEffects = 1, rd = 0, rs1 = 0b01111 in 1107 def MEMBARi : F3_2<2, 0b101000, (outs), (ins simm13Op:$simm13), 1108 "membar $simm13", []>; 1109 1110 let Constraints = "$val = $dst", DecoderMethod = "DecodeSWAP" in { 1111 def SWAPrr : F3_1<3, 0b001111, 1112 (outs IntRegs:$dst), (ins MEMrr:$addr, IntRegs:$val), 1113 "swap [$addr], $dst", 1114 [(set i32:$dst, (atomic_swap_32 ADDRrr:$addr, i32:$val))]>; 1115 def SWAPri : F3_2<3, 0b001111, 1116 (outs IntRegs:$dst), (ins MEMri:$addr, IntRegs:$val), 1117 "swap [$addr], $dst", 1118 [(set i32:$dst, (atomic_swap_32 ADDRri:$addr, i32:$val))]>; 1119 } 1120 1121 let Predicates = [HasV9], Constraints = "$swap = $rd" in 1122 def CASrr: F3_1_asi<3, 0b111100, 0b10000000, 1123 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2, 1124 IntRegs:$swap), 1125 "cas [$rs1], $rs2, $rd", 1126 [(set i32:$rd, 1127 (atomic_cmp_swap iPTR:$rs1, i32:$rs2, i32:$swap))]>; 1128 1129 let Defs = [ICC] in { 1130 defm TADDCC : F3_12np<"taddcc", 0b100000>; 1131 defm TSUBCC : F3_12np<"tsubcc", 0b100001>; 1132 1133 let hasSideEffects = 1 in { 1134 defm TADDCCTV : F3_12np<"taddcctv", 0b100010>; 1135 defm TSUBCCTV : F3_12np<"tsubcctv", 0b100011>; 1136 } 1137 } 1138 1139 multiclass TRAP<string regStr> { 1140 def rr : TRAPSPrr<0b111010, (outs), (ins IntRegs:$rs1, IntRegs:$rs2, 1141 CCOp:$cond), 1142 !strconcat(!strconcat("t$cond ", regStr), ", $rs1 + $rs2"), []>; 1143 def ri : TRAPSPri<0b111010, (outs), (ins IntRegs:$rs1, i32imm:$imm, 1144 CCOp:$cond), 1145 !strconcat(!strconcat("t$cond ", regStr), ", $rs1 + $imm"), []>; 1146 } 1147 1148 let hasSideEffects = 1, Uses = [ICC], cc = 0b00 in 1149 defm TICC : TRAP<"%icc">; 1150 1151 //===----------------------------------------------------------------------===// 1152 // Non-Instruction Patterns 1153 //===----------------------------------------------------------------------===// 1154 1155 // Small immediates. 1156 def : Pat<(i32 simm13:$val), 1157 (ORri (i32 G0), imm:$val)>; 1158 // Arbitrary immediates. 1159 def : Pat<(i32 imm:$val), 1160 (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>; 1161 1162 1163 // Global addresses, constant pool entries 1164 let Predicates = [Is32Bit] in { 1165 1166 def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; 1167 def : Pat<(SPlo tglobaladdr:$in), (ORri (i32 G0), tglobaladdr:$in)>; 1168 def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>; 1169 def : Pat<(SPlo tconstpool:$in), (ORri (i32 G0), tconstpool:$in)>; 1170 1171 // GlobalTLS addresses 1172 def : Pat<(SPhi tglobaltlsaddr:$in), (SETHIi tglobaltlsaddr:$in)>; 1173 def : Pat<(SPlo tglobaltlsaddr:$in), (ORri (i32 G0), tglobaltlsaddr:$in)>; 1174 def : Pat<(add (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), 1175 (ADDri (SETHIi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; 1176 def : Pat<(xor (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), 1177 (XORri (SETHIi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; 1178 1179 // Blockaddress 1180 def : Pat<(SPhi tblockaddress:$in), (SETHIi tblockaddress:$in)>; 1181 def : Pat<(SPlo tblockaddress:$in), (ORri (i32 G0), tblockaddress:$in)>; 1182 1183 // Add reg, lo. This is used when taking the addr of a global/constpool entry. 1184 def : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (ADDri $r, tglobaladdr:$in)>; 1185 def : Pat<(add iPTR:$r, (SPlo tconstpool:$in)), (ADDri $r, tconstpool:$in)>; 1186 def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)), 1187 (ADDri $r, tblockaddress:$in)>; 1188 } 1189 1190 // Calls: 1191 def : Pat<(call tglobaladdr:$dst), 1192 (CALL tglobaladdr:$dst)>; 1193 def : Pat<(call texternalsym:$dst), 1194 (CALL texternalsym:$dst)>; 1195 1196 // Map integer extload's to zextloads. 1197 def : Pat<(i32 (extloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1198 def : Pat<(i32 (extloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1199 def : Pat<(i32 (extloadi8 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1200 def : Pat<(i32 (extloadi8 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1201 def : Pat<(i32 (extloadi16 ADDRrr:$src)), (LDUHrr ADDRrr:$src)>; 1202 def : Pat<(i32 (extloadi16 ADDRri:$src)), (LDUHri ADDRri:$src)>; 1203 1204 // zextload bool -> zextload byte 1205 def : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1206 def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1207 1208 // store 0, addr -> store %g0, addr 1209 def : Pat<(store (i32 0), ADDRrr:$dst), (STrr ADDRrr:$dst, (i32 G0))>; 1210 def : Pat<(store (i32 0), ADDRri:$dst), (STri ADDRri:$dst, (i32 G0))>; 1211 1212 // store bar for all atomic_fence in V8. 1213 let Predicates = [HasNoV9] in 1214 def : Pat<(atomic_fence imm, imm), (STBAR)>; 1215 1216 // atomic_load_32 addr -> load addr 1217 def : Pat<(i32 (atomic_load ADDRrr:$src)), (LDrr ADDRrr:$src)>; 1218 def : Pat<(i32 (atomic_load ADDRri:$src)), (LDri ADDRri:$src)>; 1219 1220 // atomic_store_32 val, addr -> store val, addr 1221 def : Pat<(atomic_store ADDRrr:$dst, i32:$val), (STrr ADDRrr:$dst, $val)>; 1222 def : Pat<(atomic_store ADDRri:$dst, i32:$val), (STri ADDRri:$dst, $val)>; 1223 1224 1225 include "SparcInstr64Bit.td" 1226 include "SparcInstrVIS.td" 1227 include "SparcInstrAliases.td" 1228