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// True when generating 32-bit code. 25def Is32Bit : Predicate<"!Subtarget->is64Bit()">; 26 27// True when generating 64-bit code. This also implies HasV9. 28def 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. 32def 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. 38def HasNoV9 : Predicate<"!Subtarget->isV9()">; 39 40// HasVIS - This is true when the target processor has VIS extensions. 41def HasVIS : Predicate<"Subtarget->isVIS()">, 42 AssemblerPredicate<"FeatureVIS">; 43def HasVIS2 : Predicate<"Subtarget->isVIS2()">, 44 AssemblerPredicate<"FeatureVIS2">; 45def HasVIS3 : Predicate<"Subtarget->isVIS3()">, 46 AssemblerPredicate<"FeatureVIS3">; 47 48// HasHardQuad - This is true when the target processor supports quad floating 49// point instructions. 50def 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. 56def UseDeprecatedInsts : Predicate<"Subtarget->useDeprecatedV8Instructions()">; 57 58//===----------------------------------------------------------------------===// 59// Instruction Pattern Stuff 60//===----------------------------------------------------------------------===// 61 62def simm11 : PatLeaf<(imm), [{ return isInt<11>(N->getSExtValue()); }]>; 63 64def simm13 : PatLeaf<(imm), [{ return isInt<13>(N->getSExtValue()); }]>; 65 66def LO10 : SDNodeXForm<imm, [{ 67 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() & 1023, 68 MVT::i32); 69}]>; 70 71def 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 76def SETHIimm : PatLeaf<(imm), [{ 77 return isShiftedUInt<22, 10>(N->getZExtValue()); 78}], HI22>; 79 80// Addressing modes. 81def ADDRrr : ComplexPattern<iPTR, 2, "SelectADDRrr", [], []>; 82def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri", [frameindex], []>; 83 84// Address operands 85def SparcMEMrrAsmOperand : AsmOperandClass { 86 let Name = "MEMrr"; 87 let ParserMethod = "parseMEMOperand"; 88} 89 90def SparcMEMriAsmOperand : AsmOperandClass { 91 let Name = "MEMri"; 92 let ParserMethod = "parseMEMOperand"; 93} 94 95def MEMrr : Operand<iPTR> { 96 let PrintMethod = "printMemOperand"; 97 let MIOperandInfo = (ops ptr_rc, ptr_rc); 98 let ParserMatchClass = SparcMEMrrAsmOperand; 99} 100def MEMri : Operand<iPTR> { 101 let PrintMethod = "printMemOperand"; 102 let MIOperandInfo = (ops ptr_rc, i32imm); 103 let ParserMatchClass = SparcMEMriAsmOperand; 104} 105 106def TLSSym : Operand<iPTR>; 107 108// Branch targets have OtherVT type. 109def brtarget : Operand<OtherVT> { 110 let EncoderMethod = "getBranchTargetOpValue"; 111} 112 113def bprtarget : Operand<OtherVT> { 114 let EncoderMethod = "getBranchPredTargetOpValue"; 115} 116 117def bprtarget16 : Operand<OtherVT> { 118 let EncoderMethod = "getBranchOnRegTargetOpValue"; 119} 120 121def calltarget : Operand<i32> { 122 let EncoderMethod = "getCallTargetOpValue"; 123 let DecoderMethod = "DecodeCall"; 124} 125 126def simm13Op : Operand<i32> { 127 let DecoderMethod = "DecodeSIMM13"; 128} 129 130// Operand for printing out a condition code. 131let PrintMethod = "printCCOperand" in 132 def CCOp : Operand<i32>; 133 134def SDTSPcmpicc : 135SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; 136def SDTSPcmpfcc : 137SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisSameAs<0, 1>]>; 138def SDTSPbrcc : 139SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 140def SDTSPselectcc : 141SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>]>; 142def SDTSPFTOI : 143SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>; 144def SDTSPITOF : 145SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; 146def SDTSPFTOX : 147SDTypeProfile<1, 1, [SDTCisVT<0, f64>, SDTCisFP<1>]>; 148def SDTSPXTOF : 149SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f64>]>; 150 151def SDTSPtlsadd : 152SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>; 153def SDTSPtlsld : 154SDTypeProfile<1, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>; 155 156def SPcmpicc : SDNode<"SPISD::CMPICC", SDTSPcmpicc, [SDNPOutGlue]>; 157def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>; 158def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 159def SPbrxcc : SDNode<"SPISD::BRXCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 160def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 161 162def SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>; 163def SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>; 164 165def SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>; 166def SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>; 167def SPftox : SDNode<"SPISD::FTOX", SDTSPFTOX>; 168def SPxtof : SDNode<"SPISD::XTOF", SDTSPXTOF>; 169 170def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>; 171def SPselectxcc : SDNode<"SPISD::SELECT_XCC", SDTSPselectcc, [SDNPInGlue]>; 172def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>; 173 174// These are target-independent nodes, but have target-specific formats. 175def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 176def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 177 SDTCisVT<1, i32> ]>; 178 179def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 180 [SDNPHasChain, SDNPOutGlue]>; 181def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 182 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 183 184def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; 185def call : SDNode<"SPISD::CALL", SDT_SPCall, 186 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 187 SDNPVariadic]>; 188 189def SDT_SPRet : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 190def retflag : SDNode<"SPISD::RET_FLAG", SDT_SPRet, 191 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 192 193def flushw : SDNode<"SPISD::FLUSHW", SDTNone, 194 [SDNPHasChain, SDNPSideEffect, SDNPMayStore]>; 195 196def tlsadd : SDNode<"SPISD::TLS_ADD", SDTSPtlsadd>; 197def tlsld : SDNode<"SPISD::TLS_LD", SDTSPtlsld>; 198def tlscall : SDNode<"SPISD::TLS_CALL", SDT_SPCall, 199 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 200 SDNPVariadic]>; 201 202def 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. 212class ICC_VAL<int N> : PatLeaf<(i32 N)>; 213def ICC_NE : ICC_VAL< 9>; // Not Equal 214def ICC_E : ICC_VAL< 1>; // Equal 215def ICC_G : ICC_VAL<10>; // Greater 216def ICC_LE : ICC_VAL< 2>; // Less or Equal 217def ICC_GE : ICC_VAL<11>; // Greater or Equal 218def ICC_L : ICC_VAL< 3>; // Less 219def ICC_GU : ICC_VAL<12>; // Greater Unsigned 220def ICC_LEU : ICC_VAL< 4>; // Less or Equal Unsigned 221def ICC_CC : ICC_VAL<13>; // Carry Clear/Great or Equal Unsigned 222def ICC_CS : ICC_VAL< 5>; // Carry Set/Less Unsigned 223def ICC_POS : ICC_VAL<14>; // Positive 224def ICC_NEG : ICC_VAL< 6>; // Negative 225def ICC_VC : ICC_VAL<15>; // Overflow Clear 226def ICC_VS : ICC_VAL< 7>; // Overflow Set 227 228class FCC_VAL<int N> : PatLeaf<(i32 N)>; 229def FCC_U : FCC_VAL<23>; // Unordered 230def FCC_G : FCC_VAL<22>; // Greater 231def FCC_UG : FCC_VAL<21>; // Unordered or Greater 232def FCC_L : FCC_VAL<20>; // Less 233def FCC_UL : FCC_VAL<19>; // Unordered or Less 234def FCC_LG : FCC_VAL<18>; // Less or Greater 235def FCC_NE : FCC_VAL<17>; // Not Equal 236def FCC_E : FCC_VAL<25>; // Equal 237def FCC_UE : FCC_VAL<24>; // Unordered or Equal 238def FCC_GE : FCC_VAL<25>; // Greater or Equal 239def FCC_UGE : FCC_VAL<26>; // Unordered or Greater or Equal 240def FCC_LE : FCC_VAL<27>; // Less or Equal 241def FCC_ULE : FCC_VAL<28>; // Unordered or Less or Equal 242def 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. 249multiclass 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. 263multiclass 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. 273multiclass 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. 286multiclass 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. 303class 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 310let Defs = [O7] in { 311 def GETPCX : Pseudo<(outs getPCX:$getpcseq), (ins), "$getpcseq", [] >; 312} 313 314let Defs = [O6], Uses = [O6] in { 315def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 316 "!ADJCALLSTACKDOWN $amt", 317 [(callseq_start timm:$amt)]>; 318def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 319 "!ADJCALLSTACKUP $amt1", 320 [(callseq_end timm:$amt1, timm:$amt2)]>; 321} 322 323let 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 334let isBarrier = 1, isTerminator = 1, rd = 0b01000, rs1 = 0, simm13 = 5 in 335 def TA5 : F3_2<0b10, 0b111010, (outs), (ins), "ta 5", [(trap)]>; 336 337let 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. 345let 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 366let 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. 388let 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: 398let 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 409let 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 418let 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 427let DecoderMethod = "DecodeLoadFP" in 428 defm LDF : Load<"ld", 0b100000, load, FPRegs, f32>; 429let DecoderMethod = "DecodeLoadDFP" in 430 defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64>; 431let 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 436let 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 443let DecoderMethod = "DecodeStoreFP" in 444 defm STF : Store<"st", 0b100100, store, FPRegs, f32>; 445let DecoderMethod = "DecodeStoreDFP" in 446 defm STDF : Store<"std", 0b100111, store, DFPRegs, f64>; 447let 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 452def 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) 459let rd = 0, imm22 = 0 in 460 def NOP : F2_1<0b100, (outs), (ins), "nop", []>; 461 462// Section B.11 - Logical Instructions, p. 106 463defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, simm13Op>; 464 465def 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)))]>; 469def ANDNri : F3_2<2, 0b000101, 470 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 471 "andn $rs1, $simm13, $rd", []>; 472 473defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, simm13Op>; 474 475def 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)))]>; 479def ORNri : F3_2<2, 0b000110, 480 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 481 "orn $rs1, $simm13, $rd", []>; 482defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, simm13Op>; 483 484def 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)))]>; 488def XNORri : F3_2<2, 0b000111, 489 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 490 "xnor $rs1, $simm13, $rd", []>; 491 492let 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 502defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, simm13Op>; 503defm SRL : F3_12<"srl", 0b100110, srl, IntRegs, i32, simm13Op>; 504defm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i32, simm13Op>; 505 506// Section B.13 - Add Instructions, p. 108 507defm ADD : F3_12<"add", 0b000000, add, IntRegs, i32, simm13Op>; 508 509// "LEA" forms of add (patterns to make tblgen happy) 510let 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 516let Defs = [ICC] in 517 defm ADDCC : F3_12<"addcc", 0b010000, addc, IntRegs, i32, simm13Op>; 518 519let Uses = [ICC] in 520 defm ADDC : F3_12np<"addx", 0b001000>; 521 522let 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 526defm SUB : F3_12 <"sub" , 0b000100, sub, IntRegs, i32, simm13Op>; 527let Uses = [ICC], Defs = [ICC] in 528 defm SUBE : F3_12 <"subxcc" , 0b011100, sube, IntRegs, i32, simm13Op>; 529 530let Defs = [ICC] in 531 defm SUBCC : F3_12 <"subcc", 0b010100, subc, IntRegs, i32, simm13Op>; 532 533let Uses = [ICC] in 534 defm SUBC : F3_12np <"subx", 0b001100>; 535 536let 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 548let Defs = [Y] in { 549 defm UMUL : F3_12np<"umul", 0b001010>; 550 defm SMUL : F3_12 <"smul", 0b001011, mul, IntRegs, i32, simm13Op>; 551} 552 553let 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 559let Defs = [Y] in { 560 defm UDIV : F3_12np<"udiv", 0b001110>; 561 defm SDIV : F3_12np<"sdiv", 0b001111>; 562} 563 564let 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 570defm SAVE : F3_12np<"save" , 0b111100>; 571defm RESTORE : F3_12np<"restore", 0b111101>; 572 573// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119 574 575// unconditional branch class. 576class 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 584let cond = 8 in 585 def BA : BranchAlways<(ins brtarget:$imm22), "ba $imm22", [(br bb:$imm22)]>; 586 587 588let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { 589 590// conditional branch class: 591class BranchSP<dag ins, string asmstr, list<dag> pattern> 592 : F2_2<0b010, 0, (outs), ins, asmstr, pattern>; 593 594// conditional branch with annul class: 595class 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: 599multiclass 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. 618let 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 630let 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 643let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { 644 645// floating-point conditional branch class: 646class 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: 650class 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: 654multiclass 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 670let 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 678let 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 684let 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 707let 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 713let 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 722def FITOS : F3_3u<2, 0b110100, 0b011000100, 723 (outs FPRegs:$rd), (ins FPRegs:$rs2), 724 "fitos $rs2, $rd", 725 [(set FPRegs:$rd, (SPitof FPRegs:$rs2))]>; 726def FITOD : F3_3u<2, 0b110100, 0b011001000, 727 (outs DFPRegs:$rd), (ins FPRegs:$rs2), 728 "fitod $rs2, $rd", 729 [(set DFPRegs:$rd, (SPitof FPRegs:$rs2))]>; 730def 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 737def FSTOI : F3_3u<2, 0b110100, 0b011010001, 738 (outs FPRegs:$rd), (ins FPRegs:$rs2), 739 "fstoi $rs2, $rd", 740 [(set FPRegs:$rd, (SPftoi FPRegs:$rs2))]>; 741def FDTOI : F3_3u<2, 0b110100, 0b011010010, 742 (outs FPRegs:$rd), (ins DFPRegs:$rs2), 743 "fdtoi $rs2, $rd", 744 [(set FPRegs:$rd, (SPftoi DFPRegs:$rs2))]>; 745def 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 752def FSTOD : F3_3u<2, 0b110100, 0b011001001, 753 (outs DFPRegs:$rd), (ins FPRegs:$rs2), 754 "fstod $rs2, $rd", 755 [(set f64:$rd, (fextend f32:$rs2))]>; 756def 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]>; 761def FDTOS : F3_3u<2, 0b110100, 0b011000110, 762 (outs FPRegs:$rd), (ins DFPRegs:$rs2), 763 "fdtos $rs2, $rd", 764 [(set f32:$rd, (fround f64:$rs2))]>; 765def 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]>; 770def 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]>; 775def 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 782def FMOVS : F3_3u<2, 0b110100, 0b000000001, 783 (outs FPRegs:$rd), (ins FPRegs:$rs2), 784 "fmovs $rs2, $rd", []>; 785def FNEGS : F3_3u<2, 0b110100, 0b000000101, 786 (outs FPRegs:$rd), (ins FPRegs:$rs2), 787 "fnegs $rs2, $rd", 788 [(set f32:$rd, (fneg f32:$rs2))]>; 789def 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 796def FSQRTS : F3_3u<2, 0b110100, 0b000101001, 797 (outs FPRegs:$rd), (ins FPRegs:$rs2), 798 "fsqrts $rs2, $rd", 799 [(set f32:$rd, (fsqrt f32:$rs2))]>; 800def FSQRTD : F3_3u<2, 0b110100, 0b000101010, 801 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 802 "fsqrtd $rs2, $rd", 803 [(set f64:$rd, (fsqrt f64:$rs2))]>; 804def 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 813def 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))]>; 817def 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))]>; 821def 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 827def 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))]>; 831def 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))]>; 835def 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 843def 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))]>; 847def 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))]>; 851def 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 857def 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)))]>; 862def 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 869def 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))]>; 873def 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))]>; 877def 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 890let 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//===----------------------------------------------------------------------===// 909let isCodeGenOnly = 1, isAsmParserOnly = 1 in { 910def 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 917let 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 924let 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. 940let 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. 1012let 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. 1041def V9FCMPS : F3_3c<2, 0b110101, 0b001010001, 1042 (outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1043 "fcmps $rd, $rs1, $rs2", []>; 1044def V9FCMPD : F3_3c<2, 0b110101, 0b001010010, 1045 (outs FCCRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1046 "fcmpd $rd, $rs1, $rs2", []>; 1047def V9FCMPQ : F3_3c<2, 0b110101, 0b001010011, 1048 (outs FCCRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1049 "fcmpq $rd, $rs1, $rs2", []>, 1050 Requires<[HasHardQuad]>; 1051 1052let 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. 1066let 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. 1095let rs1 = 0 in 1096 def POPCrr : F3_1<2, 0b101110, 1097 (outs IntRegs:$dst), (ins IntRegs:$src), 1098 "popc $src, $dst", []>, Requires<[HasV9]>; 1099def : Pat<(ctpop i32:$src), 1100 (POPCrr (SRLri $src, 0))>; 1101 1102// Atomic swap. 1103let hasSideEffects =1, rd = 0, rs1 = 0b01111, rs2 = 0 in 1104 def STBAR : F3_1<2, 0b101000, (outs), (ins), "stbar", []>; 1105 1106let Predicates = [HasV9], hasSideEffects = 1, rd = 0, rs1 = 0b01111 in 1107 def MEMBARi : F3_2<2, 0b101000, (outs), (ins simm13Op:$simm13), 1108 "membar $simm13", []>; 1109 1110let 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 1121let 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 1129let Defs = [ICC] in { 1130defm TADDCC : F3_12np<"taddcc", 0b100000>; 1131defm TSUBCC : F3_12np<"tsubcc", 0b100001>; 1132 1133let hasSideEffects = 1 in { 1134 defm TADDCCTV : F3_12np<"taddcctv", 0b100010>; 1135 defm TSUBCCTV : F3_12np<"tsubcctv", 0b100011>; 1136} 1137} 1138 1139multiclass 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 1148let hasSideEffects = 1, Uses = [ICC], cc = 0b00 in 1149 defm TICC : TRAP<"%icc">; 1150 1151//===----------------------------------------------------------------------===// 1152// Non-Instruction Patterns 1153//===----------------------------------------------------------------------===// 1154 1155// Small immediates. 1156def : Pat<(i32 simm13:$val), 1157 (ORri (i32 G0), imm:$val)>; 1158// Arbitrary immediates. 1159def : Pat<(i32 imm:$val), 1160 (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>; 1161 1162 1163// Global addresses, constant pool entries 1164let Predicates = [Is32Bit] in { 1165 1166def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; 1167def : Pat<(SPlo tglobaladdr:$in), (ORri (i32 G0), tglobaladdr:$in)>; 1168def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>; 1169def : Pat<(SPlo tconstpool:$in), (ORri (i32 G0), tconstpool:$in)>; 1170 1171// GlobalTLS addresses 1172def : Pat<(SPhi tglobaltlsaddr:$in), (SETHIi tglobaltlsaddr:$in)>; 1173def : Pat<(SPlo tglobaltlsaddr:$in), (ORri (i32 G0), tglobaltlsaddr:$in)>; 1174def : Pat<(add (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), 1175 (ADDri (SETHIi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; 1176def : Pat<(xor (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), 1177 (XORri (SETHIi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; 1178 1179// Blockaddress 1180def : Pat<(SPhi tblockaddress:$in), (SETHIi tblockaddress:$in)>; 1181def : 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. 1184def : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (ADDri $r, tglobaladdr:$in)>; 1185def : Pat<(add iPTR:$r, (SPlo tconstpool:$in)), (ADDri $r, tconstpool:$in)>; 1186def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)), 1187 (ADDri $r, tblockaddress:$in)>; 1188} 1189 1190// Calls: 1191def : Pat<(call tglobaladdr:$dst), 1192 (CALL tglobaladdr:$dst)>; 1193def : Pat<(call texternalsym:$dst), 1194 (CALL texternalsym:$dst)>; 1195 1196// Map integer extload's to zextloads. 1197def : Pat<(i32 (extloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1198def : Pat<(i32 (extloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1199def : Pat<(i32 (extloadi8 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1200def : Pat<(i32 (extloadi8 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1201def : Pat<(i32 (extloadi16 ADDRrr:$src)), (LDUHrr ADDRrr:$src)>; 1202def : Pat<(i32 (extloadi16 ADDRri:$src)), (LDUHri ADDRri:$src)>; 1203 1204// zextload bool -> zextload byte 1205def : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1206def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1207 1208// store 0, addr -> store %g0, addr 1209def : Pat<(store (i32 0), ADDRrr:$dst), (STrr ADDRrr:$dst, (i32 G0))>; 1210def : Pat<(store (i32 0), ADDRri:$dst), (STri ADDRri:$dst, (i32 G0))>; 1211 1212// store bar for all atomic_fence in V8. 1213let Predicates = [HasNoV9] in 1214 def : Pat<(atomic_fence imm, imm), (STBAR)>; 1215 1216// atomic_load_32 addr -> load addr 1217def : Pat<(i32 (atomic_load ADDRrr:$src)), (LDrr ADDRrr:$src)>; 1218def : Pat<(i32 (atomic_load ADDRri:$src)), (LDri ADDRri:$src)>; 1219 1220// atomic_store_32 val, addr -> store val, addr 1221def : Pat<(atomic_store ADDRrr:$dst, i32:$val), (STrr ADDRrr:$dst, $val)>; 1222def : Pat<(atomic_store ADDRri:$dst, i32:$val), (STri ADDRri:$dst, $val)>; 1223 1224 1225include "SparcInstr64Bit.td" 1226include "SparcInstrVIS.td" 1227include "SparcInstrAliases.td" 1228