1//===-- SparcInstrInfo.td - Target Description for Sparc Target -----------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the Sparc instructions in TableGen format. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14// Instruction format superclass 15//===----------------------------------------------------------------------===// 16 17include "SparcInstrFormats.td" 18 19//===----------------------------------------------------------------------===// 20// Feature predicates. 21//===----------------------------------------------------------------------===// 22 23// True when generating 32-bit code. 24def Is32Bit : Predicate<"!Subtarget->is64Bit()">; 25 26// True when generating 64-bit code. This also implies HasV9. 27def Is64Bit : Predicate<"Subtarget->is64Bit()">; 28 29def UseSoftMulDiv : Predicate<"Subtarget->useSoftMulDiv()">, 30 AssemblerPredicate<(all_of FeatureSoftMulDiv)>; 31 32// HasV9 - This predicate is true when the target processor supports V9 33// instructions. Note that the machine may be running in 32-bit mode. 34def HasV9 : Predicate<"Subtarget->isV9()">, 35 AssemblerPredicate<(all_of FeatureV9)>; 36 37// HasNoV9 - This predicate is true when the target doesn't have V9 38// instructions. Use of this is just a hack for the isel not having proper 39// costs for V8 instructions that are more expensive than their V9 ones. 40def HasNoV9 : Predicate<"!Subtarget->isV9()">; 41 42// HasVIS - This is true when the target processor has VIS extensions. 43def HasVIS : Predicate<"Subtarget->isVIS()">, 44 AssemblerPredicate<(all_of FeatureVIS)>; 45def HasVIS2 : Predicate<"Subtarget->isVIS2()">, 46 AssemblerPredicate<(all_of FeatureVIS2)>; 47def HasVIS3 : Predicate<"Subtarget->isVIS3()">, 48 AssemblerPredicate<(all_of FeatureVIS3)>; 49 50// HasHardQuad - This is true when the target processor supports quad floating 51// point instructions. 52def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">; 53 54// HasLeonCASA - This is true when the target processor supports the CASA 55// instruction 56def HasLeonCASA : Predicate<"Subtarget->hasLeonCasa()">; 57 58// HasPWRPSR - This is true when the target processor supports partial 59// writes to the PSR register that only affects the ET field. 60def HasPWRPSR : Predicate<"Subtarget->hasPWRPSR()">, 61 AssemblerPredicate<(all_of FeaturePWRPSR)>; 62 63// HasUMAC_SMAC - This is true when the target processor supports the 64// UMAC and SMAC instructions 65def HasUMAC_SMAC : Predicate<"Subtarget->hasUmacSmac()">; 66 67def HasNoFdivSqrtFix : Predicate<"!Subtarget->fixAllFDIVSQRT()">; 68def HasFMULS : Predicate<"!Subtarget->hasNoFMULS()">; 69def HasFSMULD : Predicate<"!Subtarget->hasNoFSMULD()">; 70 71// UseDeprecatedInsts - This predicate is true when the target processor is a 72// V8, or when it is V9 but the V8 deprecated instructions are efficient enough 73// to use when appropriate. In either of these cases, the instruction selector 74// will pick deprecated instructions. 75def UseDeprecatedInsts : Predicate<"Subtarget->useDeprecatedV8Instructions()">; 76 77//===----------------------------------------------------------------------===// 78// Instruction Pattern Stuff 79//===----------------------------------------------------------------------===// 80 81def simm11 : PatLeaf<(imm), [{ return isInt<11>(N->getSExtValue()); }]>; 82 83def simm13 : PatLeaf<(imm), [{ return isInt<13>(N->getSExtValue()); }]>; 84 85def LO10 : SDNodeXForm<imm, [{ 86 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() & 1023, SDLoc(N), 87 MVT::i32); 88}]>; 89 90def HI22 : SDNodeXForm<imm, [{ 91 // Transformation function: shift the immediate value down into the low bits. 92 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 10, SDLoc(N), 93 MVT::i32); 94}]>; 95 96// Return the complement of a HI22 immediate value. 97def HI22_not : SDNodeXForm<imm, [{ 98 return CurDAG->getTargetConstant(~(unsigned)N->getZExtValue() >> 10, SDLoc(N), 99 MVT::i32); 100}]>; 101 102def SETHIimm : PatLeaf<(imm), [{ 103 return isShiftedUInt<22, 10>(N->getZExtValue()); 104}], HI22>; 105 106// The N->hasOneUse() prevents the immediate from being instantiated in both 107// normal and complement form. 108def SETHIimm_not : PatLeaf<(i32 imm), [{ 109 return N->hasOneUse() && isShiftedUInt<22, 10>(~(unsigned)N->getZExtValue()); 110}], HI22_not>; 111 112// Addressing modes. 113def ADDRrr : ComplexPattern<iPTR, 2, "SelectADDRrr", [], []>; 114def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri", [frameindex], []>; 115 116// Constrained operands for the shift operations. 117class ShiftAmtImmAsmOperand<int Bits> : AsmOperandClass { 118 let Name = "ShiftAmtImm" # Bits; 119 let ParserMethod = "parseShiftAmtImm<" # Bits # ">"; 120} 121def shift_imm5 : Operand<i32> { 122 let ParserMatchClass = ShiftAmtImmAsmOperand<5>; 123} 124def shift_imm6 : Operand<i32> { 125 let ParserMatchClass = ShiftAmtImmAsmOperand<6>; 126} 127 128// Address operands 129def SparcMEMrrAsmOperand : AsmOperandClass { 130 let Name = "MEMrr"; 131 let ParserMethod = "parseMEMOperand"; 132} 133 134def SparcMEMriAsmOperand : AsmOperandClass { 135 let Name = "MEMri"; 136 let ParserMethod = "parseMEMOperand"; 137} 138 139def MEMrr : Operand<iPTR> { 140 let PrintMethod = "printMemOperand"; 141 let MIOperandInfo = (ops ptr_rc, ptr_rc); 142 let ParserMatchClass = SparcMEMrrAsmOperand; 143} 144def MEMri : Operand<iPTR> { 145 let PrintMethod = "printMemOperand"; 146 let MIOperandInfo = (ops ptr_rc, i32imm); 147 let ParserMatchClass = SparcMEMriAsmOperand; 148} 149 150// Represents a tail relocation operand for instructions such as add, ld, call. 151class SparcTailRelocSymAsmOperand<string Kind> : AsmOperandClass { 152 let Name = "TailRelocSym" # Kind; 153 let RenderMethod = "addTailRelocSymOperands"; 154 let PredicateMethod = "isTailRelocSym"; 155 let ParserMethod = "parseTailRelocSym<TailRelocKind::" # Kind # ">"; 156} 157 158def TailRelocSymGOTLoad : Operand<iPTR> { 159 let ParserMatchClass = SparcTailRelocSymAsmOperand<"Load_GOT">; 160} 161 162def TailRelocSymTLSAdd : Operand<iPTR> { 163 let ParserMatchClass = SparcTailRelocSymAsmOperand<"Add_TLS">; 164} 165 166def TailRelocSymTLSLoad : Operand<iPTR> { 167 let ParserMatchClass = SparcTailRelocSymAsmOperand<"Load_TLS">; 168} 169 170def TailRelocSymTLSCall : Operand<iPTR> { 171 let ParserMatchClass = SparcTailRelocSymAsmOperand<"Call_TLS">; 172} 173 174def SparcMembarTagAsmOperand : AsmOperandClass { 175 let Name = "MembarTag"; 176 let ParserMethod = "parseMembarTag"; 177} 178 179def MembarTag : Operand<i32> { 180 let PrintMethod = "printMembarTag"; 181 let ParserMatchClass = SparcMembarTagAsmOperand; 182} 183 184// Branch targets have OtherVT type. 185def brtarget : Operand<OtherVT> { 186 let EncoderMethod = "getBranchTargetOpValue"; 187} 188 189def bprtarget : Operand<OtherVT> { 190 let EncoderMethod = "getBranchPredTargetOpValue"; 191} 192 193def bprtarget16 : Operand<OtherVT> { 194 let EncoderMethod = "getBranchOnRegTargetOpValue"; 195} 196 197def SparcCallTargetAsmOperand : AsmOperandClass { 198 let Name = "CallTarget"; 199 let ParserMethod = "parseCallTarget"; 200} 201 202def calltarget : Operand<i32> { 203 let EncoderMethod = "getCallTargetOpValue"; 204 let DecoderMethod = "DecodeCall"; 205 let ParserMatchClass = SparcCallTargetAsmOperand; 206} 207 208def simm13Op : Operand<i32> { 209 let DecoderMethod = "DecodeSIMM13"; 210 let EncoderMethod = "getSImm13OpValue"; 211} 212 213// Operand for printing out a condition code. 214let PrintMethod = "printCCOperand" in 215 def CCOp : Operand<i32>; 216 217def SDTSPcmpicc : 218SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; 219def SDTSPcmpfcc : 220SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisSameAs<0, 1>]>; 221def SDTSPbrcc : 222SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 223def SDTSPselectcc : 224SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>]>; 225def SDTSPFTOI : 226SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>; 227def SDTSPITOF : 228SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; 229def SDTSPFTOX : 230SDTypeProfile<1, 1, [SDTCisVT<0, f64>, SDTCisFP<1>]>; 231def SDTSPXTOF : 232SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f64>]>; 233 234def SDTSPtlsadd : 235SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>; 236def SDTSPtlsld : 237SDTypeProfile<1, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>; 238 239def SDTSPloadgdop : 240SDTypeProfile<1, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>; 241 242def SPcmpicc : SDNode<"SPISD::CMPICC", SDTSPcmpicc, [SDNPOutGlue]>; 243def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>; 244def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 245def SPbrxcc : SDNode<"SPISD::BRXCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 246def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 247 248def SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>; 249def SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>; 250 251def SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>; 252def SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>; 253def SPftox : SDNode<"SPISD::FTOX", SDTSPFTOX>; 254def SPxtof : SDNode<"SPISD::XTOF", SDTSPXTOF>; 255 256def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>; 257def SPselectxcc : SDNode<"SPISD::SELECT_XCC", SDTSPselectcc, [SDNPInGlue]>; 258def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>; 259 260// These are target-independent nodes, but have target-specific formats. 261def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>, 262 SDTCisVT<1, i32> ]>; 263def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 264 SDTCisVT<1, i32> ]>; 265 266def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 267 [SDNPHasChain, SDNPOutGlue]>; 268def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 269 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 270 271def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; 272def call : SDNode<"SPISD::CALL", SDT_SPCall, 273 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 274 SDNPVariadic]>; 275 276def tailcall : SDNode<"SPISD::TAIL_CALL", SDT_SPCall, 277 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 278 SDNPVariadic]>; 279 280def SDT_SPRet : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 281def retflag : SDNode<"SPISD::RET_FLAG", SDT_SPRet, 282 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 283 284def flushw : SDNode<"SPISD::FLUSHW", SDTNone, 285 [SDNPHasChain, SDNPSideEffect, SDNPMayStore]>; 286 287def tlsadd : SDNode<"SPISD::TLS_ADD", SDTSPtlsadd>; 288def tlsld : SDNode<"SPISD::TLS_LD", SDTSPtlsld>; 289def tlscall : SDNode<"SPISD::TLS_CALL", SDT_SPCall, 290 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 291 SDNPVariadic]>; 292 293def load_gdop : SDNode<"SPISD::LOAD_GDOP", SDTSPloadgdop>; 294 295def getPCX : Operand<iPTR> { 296 let PrintMethod = "printGetPCX"; 297} 298 299//===----------------------------------------------------------------------===// 300// SPARC Flag Conditions 301//===----------------------------------------------------------------------===// 302 303// Note that these values must be kept in sync with the CCOp::CondCode enum 304// values. 305class ICC_VAL<int N> : PatLeaf<(i32 N)>; 306def ICC_NE : ICC_VAL< 9>; // Not Equal 307def ICC_E : ICC_VAL< 1>; // Equal 308def ICC_G : ICC_VAL<10>; // Greater 309def ICC_LE : ICC_VAL< 2>; // Less or Equal 310def ICC_GE : ICC_VAL<11>; // Greater or Equal 311def ICC_L : ICC_VAL< 3>; // Less 312def ICC_GU : ICC_VAL<12>; // Greater Unsigned 313def ICC_LEU : ICC_VAL< 4>; // Less or Equal Unsigned 314def ICC_CC : ICC_VAL<13>; // Carry Clear/Great or Equal Unsigned 315def ICC_CS : ICC_VAL< 5>; // Carry Set/Less Unsigned 316def ICC_POS : ICC_VAL<14>; // Positive 317def ICC_NEG : ICC_VAL< 6>; // Negative 318def ICC_VC : ICC_VAL<15>; // Overflow Clear 319def ICC_VS : ICC_VAL< 7>; // Overflow Set 320 321class FCC_VAL<int N> : PatLeaf<(i32 N)>; 322def FCC_U : FCC_VAL<23>; // Unordered 323def FCC_G : FCC_VAL<22>; // Greater 324def FCC_UG : FCC_VAL<21>; // Unordered or Greater 325def FCC_L : FCC_VAL<20>; // Less 326def FCC_UL : FCC_VAL<19>; // Unordered or Less 327def FCC_LG : FCC_VAL<18>; // Less or Greater 328def FCC_NE : FCC_VAL<17>; // Not Equal 329def FCC_E : FCC_VAL<25>; // Equal 330def FCC_UE : FCC_VAL<26>; // Unordered or Equal 331def FCC_GE : FCC_VAL<27>; // Greater or Equal 332def FCC_UGE : FCC_VAL<28>; // Unordered or Greater or Equal 333def FCC_LE : FCC_VAL<29>; // Less or Equal 334def FCC_ULE : FCC_VAL<30>; // Unordered or Less or Equal 335def FCC_O : FCC_VAL<31>; // Ordered 336 337class CPCC_VAL<int N> : PatLeaf<(i32 N)>; 338def CPCC_3 : CPCC_VAL<39>; // 3 339def CPCC_2 : CPCC_VAL<38>; // 2 340def CPCC_23 : CPCC_VAL<37>; // 2 or 3 341def CPCC_1 : CPCC_VAL<36>; // 1 342def CPCC_13 : CPCC_VAL<35>; // 1 or 3 343def CPCC_12 : CPCC_VAL<34>; // 1 or 2 344def CPCC_123 : CPCC_VAL<33>; // 1 or 2 or 3 345def CPCC_0 : CPCC_VAL<41>; // 0 346def CPCC_03 : CPCC_VAL<42>; // 0 or 3 347def CPCC_02 : CPCC_VAL<43>; // 0 or 2 348def CPCC_023 : CPCC_VAL<44>; // 0 or 2 or 3 349def CPCC_01 : CPCC_VAL<45>; // 0 or 1 350def CPCC_013 : CPCC_VAL<46>; // 0 or 1 or 3 351def CPCC_012 : CPCC_VAL<47>; // 0 or 1 or 2 352 353//===----------------------------------------------------------------------===// 354// Instruction Class Templates 355//===----------------------------------------------------------------------===// 356 357/// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot. 358multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode, 359 RegisterClass RC, ValueType Ty, Operand immOp, 360 InstrItinClass itin = IIC_iu_instr> { 361 def rr : F3_1<2, Op3Val, 362 (outs RC:$rd), (ins RC:$rs1, RC:$rs2), 363 !strconcat(OpcStr, " $rs1, $rs2, $rd"), 364 [(set Ty:$rd, (OpNode Ty:$rs1, Ty:$rs2))], 365 itin>; 366 def ri : F3_2<2, Op3Val, 367 (outs RC:$rd), (ins RC:$rs1, immOp:$simm13), 368 !strconcat(OpcStr, " $rs1, $simm13, $rd"), 369 [(set Ty:$rd, (OpNode Ty:$rs1, (Ty simm13:$simm13)))], 370 itin>; 371} 372 373/// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no 374/// pattern. 375multiclass F3_12np<string OpcStr, bits<6> Op3Val, InstrItinClass itin = IIC_iu_instr> { 376 def rr : F3_1<2, Op3Val, 377 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 378 !strconcat(OpcStr, " $rs1, $rs2, $rd"), [], 379 itin>; 380 def ri : F3_2<2, Op3Val, 381 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 382 !strconcat(OpcStr, " $rs1, $simm13, $rd"), [], 383 itin>; 384} 385 386// Load multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot. 387multiclass Load<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode, 388 RegisterClass RC, ValueType Ty, InstrItinClass itin = IIC_iu_instr> { 389 def rr : F3_1<3, Op3Val, 390 (outs RC:$dst), (ins MEMrr:$addr), 391 !strconcat(OpcStr, " [$addr], $dst"), 392 [(set Ty:$dst, (OpNode ADDRrr:$addr))], 393 itin>; 394 def ri : F3_2<3, Op3Val, 395 (outs RC:$dst), (ins MEMri:$addr), 396 !strconcat(OpcStr, " [$addr], $dst"), 397 [(set Ty:$dst, (OpNode ADDRri:$addr))], 398 itin>; 399} 400 401// TODO: Instructions of the LoadASI class are currently asm only; hooking up 402// CodeGen's address spaces to use these is a future task. 403class LoadASI<string OpcStr, bits<6> Op3Val, RegisterClass RC> : 404 F3_1_asi<3, Op3Val, (outs RC:$dst), (ins MEMrr:$addr, i8imm:$asi), 405 !strconcat(OpcStr, "a [$addr] $asi, $dst"), 406 []>; 407 408// LoadA multiclass - As above, but also define alternate address space variant 409multiclass LoadA<string OpcStr, bits<6> Op3Val, bits<6> LoadAOp3Val, 410 SDPatternOperator OpNode, RegisterClass RC, ValueType Ty, 411 InstrItinClass itin = NoItinerary> : 412 Load<OpcStr, Op3Val, OpNode, RC, Ty, itin> { 413 def Arr : LoadASI<OpcStr, LoadAOp3Val, RC>; 414} 415 416// The LDSTUB instruction is supported for asm only. 417// It is unlikely that general-purpose code could make use of it. 418// CAS is preferred for sparc v9. 419def LDSTUBrr : F3_1<3, 0b001101, (outs IntRegs:$dst), (ins MEMrr:$addr), 420 "ldstub [$addr], $dst", []>; 421def LDSTUBri : F3_2<3, 0b001101, (outs IntRegs:$dst), (ins MEMri:$addr), 422 "ldstub [$addr], $dst", []>; 423def LDSTUBArr : F3_1_asi<3, 0b011101, (outs IntRegs:$dst), 424 (ins MEMrr:$addr, i8imm:$asi), 425 "ldstuba [$addr] $asi, $dst", []>; 426 427// Store multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot. 428multiclass Store<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode, 429 RegisterClass RC, ValueType Ty, InstrItinClass itin = IIC_st> { 430 def rr : F3_1<3, Op3Val, 431 (outs), (ins MEMrr:$addr, RC:$rd), 432 !strconcat(OpcStr, " $rd, [$addr]"), 433 [(OpNode Ty:$rd, ADDRrr:$addr)], 434 itin>; 435 def ri : F3_2<3, Op3Val, 436 (outs), (ins MEMri:$addr, RC:$rd), 437 !strconcat(OpcStr, " $rd, [$addr]"), 438 [(OpNode Ty:$rd, ADDRri:$addr)], 439 itin>; 440} 441 442// TODO: Instructions of the StoreASI class are currently asm only; hooking up 443// CodeGen's address spaces to use these is a future task. 444class StoreASI<string OpcStr, bits<6> Op3Val, RegisterClass RC, 445 InstrItinClass itin = IIC_st> : 446 F3_1_asi<3, Op3Val, (outs), (ins MEMrr:$addr, RC:$rd, i8imm:$asi), 447 !strconcat(OpcStr, "a $rd, [$addr] $asi"), 448 [], 449 itin>; 450 451multiclass StoreA<string OpcStr, bits<6> Op3Val, bits<6> StoreAOp3Val, 452 SDPatternOperator OpNode, RegisterClass RC, ValueType Ty> : 453 Store<OpcStr, Op3Val, OpNode, RC, Ty> { 454 def Arr : StoreASI<OpcStr, StoreAOp3Val, RC>; 455} 456 457//===----------------------------------------------------------------------===// 458// Instructions 459//===----------------------------------------------------------------------===// 460 461// Pseudo instructions. 462class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 463 : InstSP<outs, ins, asmstr, pattern> { 464 let isCodeGenOnly = 1; 465 let isPseudo = 1; 466} 467 468// GETPCX for PIC 469let Defs = [O7] in { 470 def GETPCX : Pseudo<(outs getPCX:$getpcseq), (ins), "$getpcseq", [] >; 471} 472 473let Defs = [O6], Uses = [O6] in { 474def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 475 "!ADJCALLSTACKDOWN $amt1, $amt2", 476 [(callseq_start timm:$amt1, timm:$amt2)]>; 477def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 478 "!ADJCALLSTACKUP $amt1", 479 [(callseq_end timm:$amt1, timm:$amt2)]>; 480} 481 482let hasSideEffects = 1, mayStore = 1 in { 483 let rd = 0, rs1 = 0, rs2 = 0 in 484 def FLUSHW : F3_1<0b10, 0b101011, (outs), (ins), 485 "flushw", 486 [(flushw)]>, Requires<[HasV9]>; 487 let rd = 8, rs1 = 0, simm13 = 3 in 488 def TA3 : F3_2<0b10, 0b111010, (outs), (ins), 489 "ta 3", 490 [(flushw)]>; 491} 492 493// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 494// instruction selection into a branch sequence. This has to handle all 495// permutations of selection between i32/f32/f64 on ICC and FCC. 496// Expanded after instruction selection. 497let Uses = [ICC], usesCustomInserter = 1 in { 498 def SELECT_CC_Int_ICC 499 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 500 "; SELECT_CC_Int_ICC PSEUDO!", 501 [(set i32:$dst, (SPselecticc i32:$T, i32:$F, imm:$Cond))]>; 502 def SELECT_CC_FP_ICC 503 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 504 "; SELECT_CC_FP_ICC PSEUDO!", 505 [(set f32:$dst, (SPselecticc f32:$T, f32:$F, imm:$Cond))]>; 506 507 def SELECT_CC_DFP_ICC 508 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 509 "; SELECT_CC_DFP_ICC PSEUDO!", 510 [(set f64:$dst, (SPselecticc f64:$T, f64:$F, imm:$Cond))]>; 511 512 def SELECT_CC_QFP_ICC 513 : Pseudo<(outs QFPRegs:$dst), (ins QFPRegs:$T, QFPRegs:$F, i32imm:$Cond), 514 "; SELECT_CC_QFP_ICC PSEUDO!", 515 [(set f128:$dst, (SPselecticc f128:$T, f128:$F, imm:$Cond))]>; 516} 517 518let Uses = [ICC], usesCustomInserter = 1 in { 519 def SELECT_CC_Int_XCC 520 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 521 "; SELECT_CC_Int_XCC PSEUDO!", 522 [(set i32:$dst, (SPselectxcc i32:$T, i32:$F, imm:$Cond))]>; 523 def SELECT_CC_FP_XCC 524 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 525 "; SELECT_CC_FP_XCC PSEUDO!", 526 [(set f32:$dst, (SPselectxcc f32:$T, f32:$F, imm:$Cond))]>; 527 528 def SELECT_CC_DFP_XCC 529 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 530 "; SELECT_CC_DFP_XCC PSEUDO!", 531 [(set f64:$dst, (SPselectxcc f64:$T, f64:$F, imm:$Cond))]>; 532 533 def SELECT_CC_QFP_XCC 534 : Pseudo<(outs QFPRegs:$dst), (ins QFPRegs:$T, QFPRegs:$F, i32imm:$Cond), 535 "; SELECT_CC_QFP_XCC PSEUDO!", 536 [(set f128:$dst, (SPselectxcc f128:$T, f128:$F, imm:$Cond))]>; 537} 538 539let usesCustomInserter = 1, Uses = [FCC0] in { 540 541 def SELECT_CC_Int_FCC 542 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 543 "; SELECT_CC_Int_FCC PSEUDO!", 544 [(set i32:$dst, (SPselectfcc i32:$T, i32:$F, imm:$Cond))]>; 545 546 def SELECT_CC_FP_FCC 547 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 548 "; SELECT_CC_FP_FCC PSEUDO!", 549 [(set f32:$dst, (SPselectfcc f32:$T, f32:$F, imm:$Cond))]>; 550 def SELECT_CC_DFP_FCC 551 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 552 "; SELECT_CC_DFP_FCC PSEUDO!", 553 [(set f64:$dst, (SPselectfcc f64:$T, f64:$F, imm:$Cond))]>; 554 def SELECT_CC_QFP_FCC 555 : Pseudo<(outs QFPRegs:$dst), (ins QFPRegs:$T, QFPRegs:$F, i32imm:$Cond), 556 "; SELECT_CC_QFP_FCC PSEUDO!", 557 [(set f128:$dst, (SPselectfcc f128:$T, f128:$F, imm:$Cond))]>; 558} 559 560// Section B.1 - Load Integer Instructions, p. 90 561let DecoderMethod = "DecodeLoadInt" in { 562 defm LDSB : LoadA<"ldsb", 0b001001, 0b011001, sextloadi8, IntRegs, i32>; 563 defm LDSH : LoadA<"ldsh", 0b001010, 0b011010, sextloadi16, IntRegs, i32>; 564 defm LDUB : LoadA<"ldub", 0b000001, 0b010001, zextloadi8, IntRegs, i32>; 565 defm LDUH : LoadA<"lduh", 0b000010, 0b010010, zextloadi16, IntRegs, i32>; 566 defm LD : LoadA<"ld", 0b000000, 0b010000, load, IntRegs, i32>; 567} 568 569let DecoderMethod = "DecodeLoadIntPair" in 570 defm LDD : LoadA<"ldd", 0b000011, 0b010011, load, IntPair, v2i32, IIC_ldd>; 571 572// Section B.2 - Load Floating-point Instructions, p. 92 573let DecoderMethod = "DecodeLoadFP" in { 574 defm LDF : Load<"ld", 0b100000, load, FPRegs, f32, IIC_iu_or_fpu_instr>; 575 def LDFArr : LoadASI<"ld", 0b110000, FPRegs>, 576 Requires<[HasV9]>; 577} 578let DecoderMethod = "DecodeLoadDFP" in { 579 defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64, IIC_ldd>; 580 def LDDFArr : LoadASI<"ldd", 0b110011, DFPRegs>, 581 Requires<[HasV9]>; 582} 583let DecoderMethod = "DecodeLoadQFP" in 584 defm LDQF : LoadA<"ldq", 0b100010, 0b110010, load, QFPRegs, f128>, 585 Requires<[HasV9, HasHardQuad]>; 586 587let DecoderMethod = "DecodeLoadCP" in 588 defm LDC : Load<"ld", 0b110000, load, CoprocRegs, i32>; 589let DecoderMethod = "DecodeLoadCPPair" in 590 defm LDDC : Load<"ldd", 0b110011, load, CoprocPair, v2i32, IIC_ldd>; 591 592let DecoderMethod = "DecodeLoadCP", Defs = [CPSR] in { 593 let rd = 0 in { 594 def LDCSRrr : F3_1<3, 0b110001, (outs), (ins MEMrr:$addr), 595 "ld [$addr], %csr", []>; 596 def LDCSRri : F3_2<3, 0b110001, (outs), (ins MEMri:$addr), 597 "ld [$addr], %csr", []>; 598 } 599} 600 601let DecoderMethod = "DecodeLoadFP" in 602 let Defs = [FSR] in { 603 let rd = 0 in { 604 def LDFSRrr : F3_1<3, 0b100001, (outs), (ins MEMrr:$addr), 605 "ld [$addr], %fsr", [], IIC_iu_or_fpu_instr>; 606 def LDFSRri : F3_2<3, 0b100001, (outs), (ins MEMri:$addr), 607 "ld [$addr], %fsr", [], IIC_iu_or_fpu_instr>; 608 } 609 let rd = 1 in { 610 def LDXFSRrr : F3_1<3, 0b100001, (outs), (ins MEMrr:$addr), 611 "ldx [$addr], %fsr", []>, Requires<[HasV9]>; 612 def LDXFSRri : F3_2<3, 0b100001, (outs), (ins MEMri:$addr), 613 "ldx [$addr], %fsr", []>, Requires<[HasV9]>; 614 } 615 } 616 617let mayLoad = 1, isAsmParserOnly = 1 in { 618 def GDOP_LDrr : F3_1<3, 0b000000, 619 (outs IntRegs:$dst), 620 (ins MEMrr:$addr, TailRelocSymGOTLoad:$sym), 621 "ld [$addr], $dst, $sym", 622 [(set i32:$dst, 623 (load_gdop ADDRrr:$addr, tglobaladdr:$sym))]>; 624} 625 626// Section B.4 - Store Integer Instructions, p. 95 627let DecoderMethod = "DecodeStoreInt" in { 628 defm STB : StoreA<"stb", 0b000101, 0b010101, truncstorei8, IntRegs, i32>; 629 defm STH : StoreA<"sth", 0b000110, 0b010110, truncstorei16, IntRegs, i32>; 630 defm ST : StoreA<"st", 0b000100, 0b010100, store, IntRegs, i32>; 631} 632 633let DecoderMethod = "DecodeStoreIntPair" in 634 defm STD : StoreA<"std", 0b000111, 0b010111, store, IntPair, v2i32>; 635 636// Section B.5 - Store Floating-point Instructions, p. 97 637let DecoderMethod = "DecodeStoreFP" in { 638 defm STF : Store<"st", 0b100100, store, FPRegs, f32>; 639 def STFArr : StoreASI<"st", 0b110100, FPRegs>, 640 Requires<[HasV9]>; 641} 642let DecoderMethod = "DecodeStoreDFP" in { 643 defm STDF : Store<"std", 0b100111, store, DFPRegs, f64, IIC_std>; 644 def STDFArr : StoreASI<"std", 0b110111, DFPRegs>, 645 Requires<[HasV9]>; 646} 647let DecoderMethod = "DecodeStoreQFP" in 648 defm STQF : StoreA<"stq", 0b100110, 0b110110, store, QFPRegs, f128>, 649 Requires<[HasV9, HasHardQuad]>; 650 651let DecoderMethod = "DecodeStoreCP" in 652 defm STC : Store<"st", 0b110100, store, CoprocRegs, i32>; 653 654let DecoderMethod = "DecodeStoreCPPair" in 655 defm STDC : Store<"std", 0b110111, store, CoprocPair, v2i32, IIC_std>; 656 657let DecoderMethod = "DecodeStoreCP", rd = 0 in { 658 let Defs = [CPSR] in { 659 def STCSRrr : F3_1<3, 0b110101, (outs MEMrr:$addr), (ins), 660 "st %csr, [$addr]", [], IIC_st>; 661 def STCSRri : F3_2<3, 0b110101, (outs MEMri:$addr), (ins), 662 "st %csr, [$addr]", [], IIC_st>; 663 } 664 let Defs = [CPQ] in { 665 def STDCQrr : F3_1<3, 0b110110, (outs MEMrr:$addr), (ins), 666 "std %cq, [$addr]", [], IIC_std>; 667 def STDCQri : F3_2<3, 0b110110, (outs MEMri:$addr), (ins), 668 "std %cq, [$addr]", [], IIC_std>; 669 } 670} 671 672let DecoderMethod = "DecodeStoreFP" in { 673 let rd = 0 in { 674 let Defs = [FSR] in { 675 def STFSRrr : F3_1<3, 0b100101, (outs MEMrr:$addr), (ins), 676 "st %fsr, [$addr]", [], IIC_st>; 677 def STFSRri : F3_2<3, 0b100101, (outs MEMri:$addr), (ins), 678 "st %fsr, [$addr]", [], IIC_st>; 679 } 680 let Defs = [FQ] in { 681 def STDFQrr : F3_1<3, 0b100110, (outs MEMrr:$addr), (ins), 682 "std %fq, [$addr]", [], IIC_std>; 683 def STDFQri : F3_2<3, 0b100110, (outs MEMri:$addr), (ins), 684 "std %fq, [$addr]", [], IIC_std>; 685 } 686 } 687 let rd = 1, Defs = [FSR] in { 688 def STXFSRrr : F3_1<3, 0b100101, (outs MEMrr:$addr), (ins), 689 "stx %fsr, [$addr]", []>, Requires<[HasV9]>; 690 def STXFSRri : F3_2<3, 0b100101, (outs MEMri:$addr), (ins), 691 "stx %fsr, [$addr]", []>, Requires<[HasV9]>; 692 } 693} 694 695// Section B.8 - SWAP Register with Memory Instruction 696// (Atomic swap) 697let Constraints = "$val = $dst", DecoderMethod = "DecodeSWAP" in { 698 def SWAPrr : F3_1<3, 0b001111, 699 (outs IntRegs:$dst), (ins MEMrr:$addr, IntRegs:$val), 700 "swap [$addr], $dst", 701 [(set i32:$dst, (atomic_swap_32 ADDRrr:$addr, i32:$val))]>; 702 def SWAPri : F3_2<3, 0b001111, 703 (outs IntRegs:$dst), (ins MEMri:$addr, IntRegs:$val), 704 "swap [$addr], $dst", 705 [(set i32:$dst, (atomic_swap_32 ADDRri:$addr, i32:$val))]>; 706 def SWAPArr : F3_1_asi<3, 0b011111, 707 (outs IntRegs:$dst), (ins MEMrr:$addr, i8imm:$asi, IntRegs:$val), 708 "swapa [$addr] $asi, $dst", 709 [/*FIXME: pattern?*/]>; 710} 711 712 713// Section B.9 - SETHI Instruction, p. 104 714def SETHIi: F2_1<0b100, 715 (outs IntRegs:$rd), (ins i32imm:$imm22), 716 "sethi $imm22, $rd", 717 [(set i32:$rd, SETHIimm:$imm22)], 718 IIC_iu_instr>; 719 720// Section B.10 - NOP Instruction, p. 105 721// (It's a special case of SETHI) 722let rd = 0, imm22 = 0 in 723 def NOP : F2_1<0b100, (outs), (ins), "nop", []>; 724 725// Section B.11 - Logical Instructions, p. 106 726defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, simm13Op>; 727 728def ANDNrr : F3_1<2, 0b000101, 729 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 730 "andn $rs1, $rs2, $rd", 731 [(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>; 732def ANDNri : F3_2<2, 0b000101, 733 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 734 "andn $rs1, $simm13, $rd", []>; 735 736defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, simm13Op>; 737 738def ORNrr : F3_1<2, 0b000110, 739 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 740 "orn $rs1, $rs2, $rd", 741 [(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>; 742def ORNri : F3_2<2, 0b000110, 743 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 744 "orn $rs1, $simm13, $rd", []>; 745defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, simm13Op>; 746 747def XNORrr : F3_1<2, 0b000111, 748 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 749 "xnor $rs1, $rs2, $rd", 750 [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>; 751def XNORri : F3_2<2, 0b000111, 752 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 753 "xnor $rs1, $simm13, $rd", []>; 754 755def : Pat<(and IntRegs:$rs1, SETHIimm_not:$rs2), 756 (ANDNrr i32:$rs1, (SETHIi SETHIimm_not:$rs2))>; 757 758def : Pat<(or IntRegs:$rs1, SETHIimm_not:$rs2), 759 (ORNrr i32:$rs1, (SETHIi SETHIimm_not:$rs2))>; 760 761let Defs = [ICC] in { 762 defm ANDCC : F3_12np<"andcc", 0b010001>; 763 defm ANDNCC : F3_12np<"andncc", 0b010101>; 764 defm ORCC : F3_12np<"orcc", 0b010010>; 765 defm ORNCC : F3_12np<"orncc", 0b010110>; 766 defm XORCC : F3_12np<"xorcc", 0b010011>; 767 defm XNORCC : F3_12np<"xnorcc", 0b010111>; 768} 769 770// Section B.12 - Shift Instructions, p. 107 771defm SLL : F3_S<"sll", 0b100101, 0, shl, i32, shift_imm5, IntRegs>; 772defm SRL : F3_S<"srl", 0b100110, 0, srl, i32, shift_imm5, IntRegs>; 773defm SRA : F3_S<"sra", 0b100111, 0, sra, i32, shift_imm5, IntRegs>; 774 775// Section B.13 - Add Instructions, p. 108 776defm ADD : F3_12<"add", 0b000000, add, IntRegs, i32, simm13Op>; 777 778// "LEA" forms of add (patterns to make tblgen happy) 779let Predicates = [Is32Bit], isCodeGenOnly = 1 in 780 def LEA_ADDri : F3_2<2, 0b000000, 781 (outs IntRegs:$dst), (ins MEMri:$addr), 782 "add ${addr:arith}, $dst", 783 [(set iPTR:$dst, ADDRri:$addr)]>; 784 785let Defs = [ICC] in 786 defm ADDCC : F3_12<"addcc", 0b010000, addc, IntRegs, i32, simm13Op>; 787 788let Uses = [ICC] in 789 defm ADDC : F3_12np<"addx", 0b001000>; 790 791let Uses = [ICC], Defs = [ICC] in 792 defm ADDE : F3_12<"addxcc", 0b011000, adde, IntRegs, i32, simm13Op>; 793 794// Section B.15 - Subtract Instructions, p. 110 795defm SUB : F3_12 <"sub" , 0b000100, sub, IntRegs, i32, simm13Op>; 796let Uses = [ICC], Defs = [ICC] in 797 defm SUBE : F3_12 <"subxcc" , 0b011100, sube, IntRegs, i32, simm13Op>; 798 799let Defs = [ICC] in 800 defm SUBCC : F3_12 <"subcc", 0b010100, subc, IntRegs, i32, simm13Op>; 801 802let Uses = [ICC] in 803 defm SUBC : F3_12np <"subx", 0b001100>; 804 805// cmp (from Section A.3) is a specialized alias for subcc 806let Defs = [ICC], rd = 0 in { 807 def CMPrr : F3_1<2, 0b010100, 808 (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 809 "cmp $rs1, $rs2", 810 [(SPcmpicc i32:$rs1, i32:$rs2)]>; 811 def CMPri : F3_2<2, 0b010100, 812 (outs), (ins IntRegs:$rs1, simm13Op:$simm13), 813 "cmp $rs1, $simm13", 814 [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>; 815} 816 817// Section B.18 - Multiply Instructions, p. 113 818let Defs = [Y] in { 819 defm UMUL : F3_12<"umul", 0b001010, umullohi, IntRegs, i32, simm13Op, IIC_iu_umul>; 820 defm SMUL : F3_12<"smul", 0b001011, smullohi, IntRegs, i32, simm13Op, IIC_iu_smul>; 821} 822 823let Defs = [Y, ICC] in { 824 defm UMULCC : F3_12np<"umulcc", 0b011010, IIC_iu_umul>; 825 defm SMULCC : F3_12np<"smulcc", 0b011011, IIC_iu_smul>; 826} 827 828let Defs = [Y, ICC], Uses = [Y, ICC] in { 829 defm MULSCC : F3_12np<"mulscc", 0b100100>; 830} 831 832// Section B.19 - Divide Instructions, p. 115 833let Uses = [Y], Defs = [Y] in { 834 defm UDIV : F3_12np<"udiv", 0b001110, IIC_iu_div>; 835 defm SDIV : F3_12np<"sdiv", 0b001111, IIC_iu_div>; 836} 837 838let Uses = [Y], Defs = [Y, ICC] in { 839 defm UDIVCC : F3_12np<"udivcc", 0b011110, IIC_iu_div>; 840 defm SDIVCC : F3_12np<"sdivcc", 0b011111, IIC_iu_div>; 841} 842 843// Section B.20 - SAVE and RESTORE, p. 117 844defm SAVE : F3_12np<"save" , 0b111100>; 845defm RESTORE : F3_12np<"restore", 0b111101>; 846 847// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119 848 849// unconditional branch class. 850class BranchAlways<dag ins, string asmstr, list<dag> pattern> 851 : F2_2<0b010, 0, (outs), ins, asmstr, pattern> { 852 let isBranch = 1; 853 let isTerminator = 1; 854 let hasDelaySlot = 1; 855 let isBarrier = 1; 856} 857 858let cond = 8 in 859 def BA : BranchAlways<(ins brtarget:$imm22), "ba $imm22", [(br bb:$imm22)]>; 860 861 862let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { 863 864// conditional branch class: 865class BranchSP<dag ins, string asmstr, list<dag> pattern> 866 : F2_2<0b010, 0, (outs), ins, asmstr, pattern, IIC_iu_instr>; 867 868// conditional branch with annul class: 869class BranchSPA<dag ins, string asmstr, list<dag> pattern> 870 : F2_2<0b010, 1, (outs), ins, asmstr, pattern, IIC_iu_instr>; 871 872// Conditional branch class on %icc|%xcc with predication: 873multiclass IPredBranch<string regstr, list<dag> CCPattern> { 874 def CC : F2_3<0b001, 0, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond), 875 !strconcat("b$cond ", !strconcat(regstr, ", $imm19")), 876 CCPattern, 877 IIC_iu_instr>; 878 def CCA : F2_3<0b001, 1, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond), 879 !strconcat("b$cond,a ", !strconcat(regstr, ", $imm19")), 880 [], 881 IIC_iu_instr>; 882 def CCNT : F2_3<0b001, 0, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond), 883 !strconcat("b$cond,pn ", !strconcat(regstr, ", $imm19")), 884 [], 885 IIC_iu_instr>; 886 def CCANT : F2_3<0b001, 1, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond), 887 !strconcat("b$cond,a,pn ", !strconcat(regstr, ", $imm19")), 888 [], 889 IIC_iu_instr>; 890} 891 892} // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 893 894 895// Indirect branch instructions. 896let isTerminator = 1, isBarrier = 1, hasDelaySlot = 1, isBranch =1, 897 isIndirectBranch = 1, rd = 0, isCodeGenOnly = 1 in { 898 def BINDrr : F3_1<2, 0b111000, 899 (outs), (ins MEMrr:$ptr), 900 "jmp $ptr", 901 [(brind ADDRrr:$ptr)]>; 902 def BINDri : F3_2<2, 0b111000, 903 (outs), (ins MEMri:$ptr), 904 "jmp $ptr", 905 [(brind ADDRri:$ptr)]>; 906} 907 908let Uses = [ICC] in { 909 def BCOND : BranchSP<(ins brtarget:$imm22, CCOp:$cond), 910 "b$cond $imm22", 911 [(SPbricc bb:$imm22, imm:$cond)]>; 912 def BCONDA : BranchSPA<(ins brtarget:$imm22, CCOp:$cond), 913 "b$cond,a $imm22", []>; 914 915 let Predicates = [HasV9], cc = 0b00 in 916 defm BPI : IPredBranch<"%icc", []>; 917} 918 919// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 920 921let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { 922 923// floating-point conditional branch class: 924class FPBranchSP<dag ins, string asmstr, list<dag> pattern> 925 : F2_2<0b110, 0, (outs), ins, asmstr, pattern, IIC_fpu_normal_instr>; 926 927// floating-point conditional branch with annul class: 928class FPBranchSPA<dag ins, string asmstr, list<dag> pattern> 929 : F2_2<0b110, 1, (outs), ins, asmstr, pattern, IIC_fpu_normal_instr>; 930 931// Conditional branch class on %fcc0-%fcc3 with predication: 932multiclass FPredBranch { 933 def CC : F2_3<0b101, 0, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond, 934 FCCRegs:$cc), 935 "fb$cond $cc, $imm19", [], IIC_fpu_normal_instr>; 936 def CCA : F2_3<0b101, 1, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond, 937 FCCRegs:$cc), 938 "fb$cond,a $cc, $imm19", [], IIC_fpu_normal_instr>; 939 def CCNT : F2_3<0b101, 0, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond, 940 FCCRegs:$cc), 941 "fb$cond,pn $cc, $imm19", [], IIC_fpu_normal_instr>; 942 def CCANT : F2_3<0b101, 1, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond, 943 FCCRegs:$cc), 944 "fb$cond,a,pn $cc, $imm19", [], IIC_fpu_normal_instr>; 945} 946} // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 947 948let Uses = [FCC0] in { 949 def FBCOND : FPBranchSP<(ins brtarget:$imm22, CCOp:$cond), 950 "fb$cond $imm22", 951 [(SPbrfcc bb:$imm22, imm:$cond)]>; 952 def FBCONDA : FPBranchSPA<(ins brtarget:$imm22, CCOp:$cond), 953 "fb$cond,a $imm22", []>; 954} 955 956let Predicates = [HasV9] in 957 defm BPF : FPredBranch; 958 959// Section B.22 - Branch on Co-processor Condition Codes Instructions, p. 123 960let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in { 961 962// co-processor conditional branch class: 963class CPBranchSP<dag ins, string asmstr, list<dag> pattern> 964 : F2_2<0b111, 0, (outs), ins, asmstr, pattern>; 965 966// co-processor conditional branch with annul class: 967class CPBranchSPA<dag ins, string asmstr, list<dag> pattern> 968 : F2_2<0b111, 1, (outs), ins, asmstr, pattern>; 969 970} // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 971 972def CBCOND : CPBranchSP<(ins brtarget:$imm22, CCOp:$cond), 973 "cb$cond $imm22", 974 [(SPbrfcc bb:$imm22, imm:$cond)]>; 975def CBCONDA : CPBranchSPA<(ins brtarget:$imm22, CCOp:$cond), 976 "cb$cond,a $imm22", []>; 977 978// Section B.24 - Call and Link Instruction, p. 125 979// This is the only Format 1 instruction 980let Uses = [O6], 981 hasDelaySlot = 1, isCall = 1 in { 982 def CALL : InstSP<(outs), (ins calltarget:$disp, variable_ops), 983 "call $disp", 984 [], 985 IIC_jmp_or_call> { 986 bits<30> disp; 987 let op = 1; 988 let Inst{29-0} = disp; 989 } 990 991 // indirect calls: special cases of JMPL. 992 let isCodeGenOnly = 1, rd = 15 in { 993 def CALLrr : F3_1<2, 0b111000, 994 (outs), (ins MEMrr:$ptr, variable_ops), 995 "call $ptr", 996 [(call ADDRrr:$ptr)], 997 IIC_jmp_or_call>; 998 def CALLri : F3_2<2, 0b111000, 999 (outs), (ins MEMri:$ptr, variable_ops), 1000 "call $ptr", 1001 [(call ADDRri:$ptr)], 1002 IIC_jmp_or_call>; 1003 } 1004} 1005 1006// Section B.25 - Jump and Link Instruction 1007 1008// JMPL Instruction. 1009let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, 1010 DecoderMethod = "DecodeJMPL" in { 1011 def JMPLrr: F3_1<2, 0b111000, 1012 (outs IntRegs:$dst), (ins MEMrr:$addr), 1013 "jmpl $addr, $dst", 1014 [], 1015 IIC_jmp_or_call>; 1016 def JMPLri: F3_2<2, 0b111000, 1017 (outs IntRegs:$dst), (ins MEMri:$addr), 1018 "jmpl $addr, $dst", 1019 [], 1020 IIC_jmp_or_call>; 1021} 1022 1023// Section A.3 - Synthetic Instructions, p. 85 1024// special cases of JMPL: 1025let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, 1026 isCodeGenOnly = 1 in { 1027 let rd = 0, rs1 = 15 in 1028 def RETL: F3_2<2, 0b111000, 1029 (outs), (ins i32imm:$val), 1030 "jmp %o7+$val", 1031 [(retflag simm13:$val)], 1032 IIC_jmp_or_call>; 1033 1034 let rd = 0, rs1 = 31 in 1035 def RET: F3_2<2, 0b111000, 1036 (outs), (ins i32imm:$val), 1037 "jmp %i7+$val", 1038 [], 1039 IIC_jmp_or_call>; 1040} 1041 1042// Section B.26 - Return from Trap Instruction 1043let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, 1044 isBarrier = 1, rd = 0, DecoderMethod = "DecodeReturn" in { 1045 def RETTrr : F3_1<2, 0b111001, 1046 (outs), (ins MEMrr:$addr), 1047 "rett $addr", 1048 [], 1049 IIC_jmp_or_call>; 1050 def RETTri : F3_2<2, 0b111001, 1051 (outs), (ins MEMri:$addr), 1052 "rett $addr", 1053 [], 1054 IIC_jmp_or_call>; 1055} 1056 1057 1058// Section B.27 - Trap on Integer Condition Codes Instruction 1059// conditional branch class: 1060let DecoderNamespace = "SparcV8", DecoderMethod = "DecodeTRAP", hasSideEffects = 1, Uses = [ICC], cc = 0b00 in 1061{ 1062 def TRAPrr : TRAPSPrr<0b111010, 1063 (outs), (ins IntRegs:$rs1, IntRegs:$rs2, CCOp:$cond), 1064 "t$cond $rs1 + $rs2", 1065 []>; 1066 def TRAPri : TRAPSPri<0b111010, 1067 (outs), (ins IntRegs:$rs1, i32imm:$imm, CCOp:$cond), 1068 "t$cond $rs1 + $imm", 1069 []>; 1070} 1071 1072multiclass TRAP<string regStr> { 1073 def rr : TRAPSPrr<0b111010, 1074 (outs), (ins IntRegs:$rs1, IntRegs:$rs2, CCOp:$cond), 1075 !strconcat(!strconcat("t$cond ", regStr), ", $rs1 + $rs2"), 1076 []>; 1077 def ri : TRAPSPri<0b111010, 1078 (outs), (ins IntRegs:$rs1, i32imm:$imm, CCOp:$cond), 1079 !strconcat(!strconcat("t$cond ", regStr), ", $rs1 + $imm"), 1080 []>; 1081} 1082 1083let DecoderNamespace = "SparcV9", DecoderMethod = "DecodeTRAP", Predicates = [HasV9], hasSideEffects = 1, Uses = [ICC], cc = 0b00 in 1084 defm TICC : TRAP<"%icc">; 1085 1086 1087let isBarrier = 1, isTerminator = 1, rd = 0b01000, rs1 = 0, simm13 = 5 in 1088 def TA5 : F3_2<0b10, 0b111010, (outs), (ins), "ta 5", [(trap)]>; 1089 1090let hasSideEffects = 1, rd = 0b01000, rs1 = 0, simm13 = 1 in 1091 def TA1 : F3_2<0b10, 0b111010, (outs), (ins), "ta 1", [(debugtrap)]>; 1092 1093// Section B.28 - Read State Register Instructions 1094let rs2 = 0 in 1095 def RDASR : F3_1<2, 0b101000, 1096 (outs IntRegs:$rd), (ins ASRRegs:$rs1), 1097 "rd $rs1, $rd", []>; 1098 1099// PSR, WIM, and TBR don't exist on the SparcV9, only the V8. 1100let Predicates = [HasNoV9] in { 1101 let rs2 = 0, rs1 = 0, Uses=[PSR] in 1102 def RDPSR : F3_1<2, 0b101001, 1103 (outs IntRegs:$rd), (ins), 1104 "rd %psr, $rd", []>; 1105 1106 let rs2 = 0, rs1 = 0, Uses=[WIM] in 1107 def RDWIM : F3_1<2, 0b101010, 1108 (outs IntRegs:$rd), (ins), 1109 "rd %wim, $rd", []>; 1110 1111 let rs2 = 0, rs1 = 0, Uses=[TBR] in 1112 def RDTBR : F3_1<2, 0b101011, 1113 (outs IntRegs:$rd), (ins), 1114 "rd %tbr, $rd", []>; 1115} 1116 1117// PC don't exist on the SparcV8, only the V9. 1118let Predicates = [HasV9] in { 1119 let rs2 = 0, rs1 = 5 in 1120 def RDPC : F3_1<2, 0b101000, 1121 (outs IntRegs:$rd), (ins), 1122 "rd %pc, $rd", []>; 1123} 1124 1125// Section B.29 - Write State Register Instructions 1126def WRASRrr : F3_1<2, 0b110000, 1127 (outs ASRRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 1128 "wr $rs1, $rs2, $rd", []>; 1129def WRASRri : F3_2<2, 0b110000, 1130 (outs ASRRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 1131 "wr $rs1, $simm13, $rd", []>; 1132 1133// PSR, WIM, and TBR don't exist on the SparcV9, only the V8. 1134let Predicates = [HasNoV9] in { 1135 let Defs = [PSR], rd=0 in { 1136 def WRPSRrr : F3_1<2, 0b110001, 1137 (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 1138 "wr $rs1, $rs2, %psr", []>; 1139 def WRPSRri : F3_2<2, 0b110001, 1140 (outs), (ins IntRegs:$rs1, simm13Op:$simm13), 1141 "wr $rs1, $simm13, %psr", []>; 1142 } 1143 1144 let Defs = [WIM], rd=0 in { 1145 def WRWIMrr : F3_1<2, 0b110010, 1146 (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 1147 "wr $rs1, $rs2, %wim", []>; 1148 def WRWIMri : F3_2<2, 0b110010, 1149 (outs), (ins IntRegs:$rs1, simm13Op:$simm13), 1150 "wr $rs1, $simm13, %wim", []>; 1151 } 1152 1153 let Defs = [TBR], rd=0 in { 1154 def WRTBRrr : F3_1<2, 0b110011, 1155 (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 1156 "wr $rs1, $rs2, %tbr", []>; 1157 def WRTBRri : F3_2<2, 0b110011, 1158 (outs), (ins IntRegs:$rs1, simm13Op:$simm13), 1159 "wr $rs1, $simm13, %tbr", []>; 1160 } 1161} 1162 1163// Section B.30 - STBAR Instruction 1164let hasSideEffects = 1, rd = 0, rs1 = 0b01111, rs2 = 0 in 1165 def STBAR : F3_1<2, 0b101000, (outs), (ins), "stbar", []>; 1166 1167 1168// Section B.31 - Unimplemented Instruction 1169let rd = 0 in 1170 def UNIMP : F2_1<0b000, (outs), (ins i32imm:$imm22), 1171 "unimp $imm22", []>; 1172 1173// Section B.32 - Flush Instruction Memory 1174let rd = 0 in { 1175 def FLUSHrr : F3_1<2, 0b111011, (outs), (ins MEMrr:$addr), 1176 "flush $addr", []>; 1177 def FLUSHri : F3_2<2, 0b111011, (outs), (ins MEMri:$addr), 1178 "flush $addr", []>; 1179 1180 // The no-arg FLUSH is only here for the benefit of the InstAlias 1181 // "flush", which cannot seem to use FLUSHrr, due to the inability 1182 // to construct a MEMrr with fixed G0 registers. 1183 let rs1 = 0, rs2 = 0 in 1184 def FLUSH : F3_1<2, 0b111011, (outs), (ins), "flush %g0", []>; 1185} 1186 1187// Section B.33 - Floating-point Operate (FPop) Instructions 1188 1189// Convert Integer to Floating-point Instructions, p. 141 1190def FITOS : F3_3u<2, 0b110100, 0b011000100, 1191 (outs FPRegs:$rd), (ins FPRegs:$rs2), 1192 "fitos $rs2, $rd", 1193 [(set FPRegs:$rd, (SPitof FPRegs:$rs2))], 1194 IIC_fpu_fast_instr>; 1195def FITOD : F3_3u<2, 0b110100, 0b011001000, 1196 (outs DFPRegs:$rd), (ins FPRegs:$rs2), 1197 "fitod $rs2, $rd", 1198 [(set DFPRegs:$rd, (SPitof FPRegs:$rs2))], 1199 IIC_fpu_fast_instr>; 1200def FITOQ : F3_3u<2, 0b110100, 0b011001100, 1201 (outs QFPRegs:$rd), (ins FPRegs:$rs2), 1202 "fitoq $rs2, $rd", 1203 [(set QFPRegs:$rd, (SPitof FPRegs:$rs2))]>, 1204 Requires<[HasHardQuad]>; 1205 1206// Convert Floating-point to Integer Instructions, p. 142 1207def FSTOI : F3_3u<2, 0b110100, 0b011010001, 1208 (outs FPRegs:$rd), (ins FPRegs:$rs2), 1209 "fstoi $rs2, $rd", 1210 [(set FPRegs:$rd, (SPftoi FPRegs:$rs2))], 1211 IIC_fpu_fast_instr>; 1212def FDTOI : F3_3u<2, 0b110100, 0b011010010, 1213 (outs FPRegs:$rd), (ins DFPRegs:$rs2), 1214 "fdtoi $rs2, $rd", 1215 [(set FPRegs:$rd, (SPftoi DFPRegs:$rs2))], 1216 IIC_fpu_fast_instr>; 1217def FQTOI : F3_3u<2, 0b110100, 0b011010011, 1218 (outs FPRegs:$rd), (ins QFPRegs:$rs2), 1219 "fqtoi $rs2, $rd", 1220 [(set FPRegs:$rd, (SPftoi QFPRegs:$rs2))]>, 1221 Requires<[HasHardQuad]>; 1222 1223// Convert between Floating-point Formats Instructions, p. 143 1224def FSTOD : F3_3u<2, 0b110100, 0b011001001, 1225 (outs DFPRegs:$rd), (ins FPRegs:$rs2), 1226 "fstod $rs2, $rd", 1227 [(set f64:$rd, (fpextend f32:$rs2))], 1228 IIC_fpu_stod>; 1229def FSTOQ : F3_3u<2, 0b110100, 0b011001101, 1230 (outs QFPRegs:$rd), (ins FPRegs:$rs2), 1231 "fstoq $rs2, $rd", 1232 [(set f128:$rd, (fpextend f32:$rs2))]>, 1233 Requires<[HasHardQuad]>; 1234def FDTOS : F3_3u<2, 0b110100, 0b011000110, 1235 (outs FPRegs:$rd), (ins DFPRegs:$rs2), 1236 "fdtos $rs2, $rd", 1237 [(set f32:$rd, (fpround f64:$rs2))], 1238 IIC_fpu_fast_instr>; 1239def FDTOQ : F3_3u<2, 0b110100, 0b011001110, 1240 (outs QFPRegs:$rd), (ins DFPRegs:$rs2), 1241 "fdtoq $rs2, $rd", 1242 [(set f128:$rd, (fpextend f64:$rs2))]>, 1243 Requires<[HasHardQuad]>; 1244def FQTOS : F3_3u<2, 0b110100, 0b011000111, 1245 (outs FPRegs:$rd), (ins QFPRegs:$rs2), 1246 "fqtos $rs2, $rd", 1247 [(set f32:$rd, (fpround f128:$rs2))]>, 1248 Requires<[HasHardQuad]>; 1249def FQTOD : F3_3u<2, 0b110100, 0b011001011, 1250 (outs DFPRegs:$rd), (ins QFPRegs:$rs2), 1251 "fqtod $rs2, $rd", 1252 [(set f64:$rd, (fpround f128:$rs2))]>, 1253 Requires<[HasHardQuad]>; 1254 1255// Floating-point Move Instructions, p. 144 1256def FMOVS : F3_3u<2, 0b110100, 0b000000001, 1257 (outs FPRegs:$rd), (ins FPRegs:$rs2), 1258 "fmovs $rs2, $rd", []>; 1259def FNEGS : F3_3u<2, 0b110100, 0b000000101, 1260 (outs FPRegs:$rd), (ins FPRegs:$rs2), 1261 "fnegs $rs2, $rd", 1262 [(set f32:$rd, (fneg f32:$rs2))], 1263 IIC_fpu_negs>; 1264def FABSS : F3_3u<2, 0b110100, 0b000001001, 1265 (outs FPRegs:$rd), (ins FPRegs:$rs2), 1266 "fabss $rs2, $rd", 1267 [(set f32:$rd, (fabs f32:$rs2))], 1268 IIC_fpu_abs>; 1269 1270 1271// Floating-point Square Root Instructions, p.145 1272// FSQRTS generates an erratum on LEON processors, so by disabling this instruction 1273// this will be promoted to use FSQRTD with doubles instead. 1274let Predicates = [HasNoFdivSqrtFix] in 1275def FSQRTS : F3_3u<2, 0b110100, 0b000101001, 1276 (outs FPRegs:$rd), (ins FPRegs:$rs2), 1277 "fsqrts $rs2, $rd", 1278 [(set f32:$rd, (fsqrt f32:$rs2))], 1279 IIC_fpu_sqrts>; 1280def FSQRTD : F3_3u<2, 0b110100, 0b000101010, 1281 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 1282 "fsqrtd $rs2, $rd", 1283 [(set f64:$rd, (fsqrt f64:$rs2))], 1284 IIC_fpu_sqrtd>; 1285def FSQRTQ : F3_3u<2, 0b110100, 0b000101011, 1286 (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 1287 "fsqrtq $rs2, $rd", 1288 [(set f128:$rd, (fsqrt f128:$rs2))]>, 1289 Requires<[HasHardQuad]>; 1290 1291 1292 1293// Floating-point Add and Subtract Instructions, p. 146 1294def FADDS : F3_3<2, 0b110100, 0b001000001, 1295 (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1296 "fadds $rs1, $rs2, $rd", 1297 [(set f32:$rd, (fadd f32:$rs1, f32:$rs2))], 1298 IIC_fpu_fast_instr>; 1299def FADDD : F3_3<2, 0b110100, 0b001000010, 1300 (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1301 "faddd $rs1, $rs2, $rd", 1302 [(set f64:$rd, (fadd f64:$rs1, f64:$rs2))], 1303 IIC_fpu_fast_instr>; 1304def FADDQ : F3_3<2, 0b110100, 0b001000011, 1305 (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1306 "faddq $rs1, $rs2, $rd", 1307 [(set f128:$rd, (fadd f128:$rs1, f128:$rs2))]>, 1308 Requires<[HasHardQuad]>; 1309 1310def FSUBS : F3_3<2, 0b110100, 0b001000101, 1311 (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1312 "fsubs $rs1, $rs2, $rd", 1313 [(set f32:$rd, (fsub f32:$rs1, f32:$rs2))], 1314 IIC_fpu_fast_instr>; 1315def FSUBD : F3_3<2, 0b110100, 0b001000110, 1316 (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1317 "fsubd $rs1, $rs2, $rd", 1318 [(set f64:$rd, (fsub f64:$rs1, f64:$rs2))], 1319 IIC_fpu_fast_instr>; 1320def FSUBQ : F3_3<2, 0b110100, 0b001000111, 1321 (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1322 "fsubq $rs1, $rs2, $rd", 1323 [(set f128:$rd, (fsub f128:$rs1, f128:$rs2))]>, 1324 Requires<[HasHardQuad]>; 1325 1326 1327// Floating-point Multiply and Divide Instructions, p. 147 1328def FMULS : F3_3<2, 0b110100, 0b001001001, 1329 (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1330 "fmuls $rs1, $rs2, $rd", 1331 [(set f32:$rd, (fmul f32:$rs1, f32:$rs2))], 1332 IIC_fpu_muls>, 1333 Requires<[HasFMULS]>; 1334def FMULD : F3_3<2, 0b110100, 0b001001010, 1335 (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1336 "fmuld $rs1, $rs2, $rd", 1337 [(set f64:$rd, (fmul f64:$rs1, f64:$rs2))], 1338 IIC_fpu_muld>; 1339def FMULQ : F3_3<2, 0b110100, 0b001001011, 1340 (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1341 "fmulq $rs1, $rs2, $rd", 1342 [(set f128:$rd, (fmul f128:$rs1, f128:$rs2))]>, 1343 Requires<[HasHardQuad]>; 1344 1345def FSMULD : F3_3<2, 0b110100, 0b001101001, 1346 (outs DFPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1347 "fsmuld $rs1, $rs2, $rd", 1348 [(set f64:$rd, (fmul (fpextend f32:$rs1), 1349 (fpextend f32:$rs2)))], 1350 IIC_fpu_muld>, 1351 Requires<[HasFSMULD]>; 1352def FDMULQ : F3_3<2, 0b110100, 0b001101110, 1353 (outs QFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1354 "fdmulq $rs1, $rs2, $rd", 1355 [(set f128:$rd, (fmul (fpextend f64:$rs1), 1356 (fpextend f64:$rs2)))]>, 1357 Requires<[HasHardQuad]>; 1358 1359// FDIVS generates an erratum on LEON processors, so by disabling this instruction 1360// this will be promoted to use FDIVD with doubles instead. 1361def FDIVS : F3_3<2, 0b110100, 0b001001101, 1362 (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1363 "fdivs $rs1, $rs2, $rd", 1364 [(set f32:$rd, (fdiv f32:$rs1, f32:$rs2))], 1365 IIC_fpu_divs>; 1366def FDIVD : F3_3<2, 0b110100, 0b001001110, 1367 (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1368 "fdivd $rs1, $rs2, $rd", 1369 [(set f64:$rd, (fdiv f64:$rs1, f64:$rs2))], 1370 IIC_fpu_divd>; 1371def FDIVQ : F3_3<2, 0b110100, 0b001001111, 1372 (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1373 "fdivq $rs1, $rs2, $rd", 1374 [(set f128:$rd, (fdiv f128:$rs1, f128:$rs2))]>, 1375 Requires<[HasHardQuad]>; 1376 1377// Floating-point Compare Instructions, p. 148 1378// Note: the 2nd template arg is different for these guys. 1379// Note 2: the result of a FCMP is not available until the 2nd cycle 1380// after the instr is retired, but there is no interlock in Sparc V8. 1381// This behavior is modeled with a forced noop after the instruction in 1382// DelaySlotFiller. 1383 1384let Defs = [FCC0], rd = 0, isCodeGenOnly = 1 in { 1385 def FCMPS : F3_3c<2, 0b110101, 0b001010001, 1386 (outs), (ins FPRegs:$rs1, FPRegs:$rs2), 1387 "fcmps $rs1, $rs2", 1388 [(SPcmpfcc f32:$rs1, f32:$rs2)], 1389 IIC_fpu_fast_instr>; 1390 def FCMPD : F3_3c<2, 0b110101, 0b001010010, 1391 (outs), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1392 "fcmpd $rs1, $rs2", 1393 [(SPcmpfcc f64:$rs1, f64:$rs2)], 1394 IIC_fpu_fast_instr>; 1395 def FCMPQ : F3_3c<2, 0b110101, 0b001010011, 1396 (outs), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1397 "fcmpq $rs1, $rs2", 1398 [(SPcmpfcc f128:$rs1, f128:$rs2)]>, 1399 Requires<[HasHardQuad]>; 1400} 1401 1402//===----------------------------------------------------------------------===// 1403// Instructions for Thread Local Storage(TLS). 1404//===----------------------------------------------------------------------===// 1405let isAsmParserOnly = 1 in { 1406def TLS_ADDrr : F3_1<2, 0b000000, 1407 (outs IntRegs:$rd), 1408 (ins IntRegs:$rs1, IntRegs:$rs2, TailRelocSymTLSAdd:$sym), 1409 "add $rs1, $rs2, $rd, $sym", 1410 [(set i32:$rd, 1411 (tlsadd i32:$rs1, i32:$rs2, tglobaltlsaddr:$sym))]>; 1412 1413let mayLoad = 1 in { 1414 def TLS_LDrr : F3_1<3, 0b000000, 1415 (outs IntRegs:$dst), 1416 (ins MEMrr:$addr, TailRelocSymTLSLoad:$sym), 1417 "ld [$addr], $dst, $sym", 1418 [(set i32:$dst, 1419 (tlsld ADDRrr:$addr, tglobaltlsaddr:$sym))]>; 1420} 1421 1422let Uses = [O6], isCall = 1, hasDelaySlot = 1 in 1423 def TLS_CALL : InstSP<(outs), 1424 (ins calltarget:$disp, TailRelocSymTLSCall:$sym, 1425 variable_ops), 1426 "call $disp, $sym", 1427 [(tlscall texternalsym:$disp, tglobaltlsaddr:$sym)], 1428 IIC_jmp_or_call> { 1429 bits<30> disp; 1430 let op = 1; 1431 let Inst{29-0} = disp; 1432} 1433} 1434 1435//===----------------------------------------------------------------------===// 1436// Instructions for tail calls. 1437//===----------------------------------------------------------------------===// 1438let isCodeGenOnly = 1, isReturn = 1, hasDelaySlot = 1, 1439 isTerminator = 1, isBarrier = 1 in { 1440 def TAIL_CALL : InstSP<(outs), (ins calltarget:$disp, variable_ops), 1441 "call $disp", 1442 [(tailcall tglobaladdr:$disp)]> { 1443 bits<30> disp; 1444 let op = 1; 1445 let Inst{29-0} = disp; 1446 } 1447} 1448 1449def : Pat<(tailcall (iPTR texternalsym:$dst)), 1450 (TAIL_CALL texternalsym:$dst)>; 1451 1452let isCodeGenOnly = 1, isReturn = 1, hasDelaySlot = 1, isTerminator = 1, 1453 isBarrier = 1, rd = 0 in { 1454 def TAIL_CALLri : F3_2<2, 0b111000, 1455 (outs), (ins MEMri:$ptr, variable_ops), 1456 "jmp $ptr", 1457 [(tailcall ADDRri:$ptr)]>; 1458} 1459 1460//===----------------------------------------------------------------------===// 1461// V9 Instructions 1462//===----------------------------------------------------------------------===// 1463 1464// V9 Conditional Moves. 1465let Predicates = [HasV9], Constraints = "$f = $rd" in { 1466 // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. 1467 let Uses = [ICC], intcc = 1, cc = 0b00 in { 1468 def MOVICCrr 1469 : F4_1<0b101100, (outs IntRegs:$rd), 1470 (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), 1471 "mov$cond %icc, $rs2, $rd", 1472 [(set i32:$rd, (SPselecticc i32:$rs2, i32:$f, imm:$cond))]>; 1473 1474 def MOVICCri 1475 : F4_2<0b101100, (outs IntRegs:$rd), 1476 (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond), 1477 "mov$cond %icc, $simm11, $rd", 1478 [(set i32:$rd, 1479 (SPselecticc simm11:$simm11, i32:$f, imm:$cond))]>; 1480 } 1481 1482 let Uses = [FCC0], intcc = 0, cc = 0b00 in { 1483 def MOVFCCrr 1484 : F4_1<0b101100, (outs IntRegs:$rd), 1485 (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), 1486 "mov$cond %fcc0, $rs2, $rd", 1487 [(set i32:$rd, (SPselectfcc i32:$rs2, i32:$f, imm:$cond))]>; 1488 def MOVFCCri 1489 : F4_2<0b101100, (outs IntRegs:$rd), 1490 (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond), 1491 "mov$cond %fcc0, $simm11, $rd", 1492 [(set i32:$rd, 1493 (SPselectfcc simm11:$simm11, i32:$f, imm:$cond))]>; 1494 } 1495 1496 let Uses = [ICC], intcc = 1, opf_cc = 0b00 in { 1497 def FMOVS_ICC 1498 : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), 1499 (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), 1500 "fmovs$cond %icc, $rs2, $rd", 1501 [(set f32:$rd, (SPselecticc f32:$rs2, f32:$f, imm:$cond))]>; 1502 def FMOVD_ICC 1503 : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), 1504 (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), 1505 "fmovd$cond %icc, $rs2, $rd", 1506 [(set f64:$rd, (SPselecticc f64:$rs2, f64:$f, imm:$cond))]>; 1507 let Predicates = [HasV9, HasHardQuad] in 1508 def FMOVQ_ICC 1509 : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), 1510 (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), 1511 "fmovq$cond %icc, $rs2, $rd", 1512 [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>; 1513 } 1514 1515 let Uses = [FCC0], intcc = 0, opf_cc = 0b00 in { 1516 def FMOVS_FCC 1517 : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), 1518 (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), 1519 "fmovs$cond %fcc0, $rs2, $rd", 1520 [(set f32:$rd, (SPselectfcc f32:$rs2, f32:$f, imm:$cond))]>; 1521 def FMOVD_FCC 1522 : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), 1523 (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), 1524 "fmovd$cond %fcc0, $rs2, $rd", 1525 [(set f64:$rd, (SPselectfcc f64:$rs2, f64:$f, imm:$cond))]>; 1526 let Predicates = [HasV9, HasHardQuad] in 1527 def FMOVQ_FCC 1528 : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), 1529 (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), 1530 "fmovq$cond %fcc0, $rs2, $rd", 1531 [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>; 1532 } 1533 1534} 1535 1536// Floating-Point Move Instructions, p. 164 of the V9 manual. 1537let Predicates = [HasV9] in { 1538 def FMOVD : F3_3u<2, 0b110100, 0b000000010, 1539 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 1540 "fmovd $rs2, $rd", []>; 1541 let Predicates = [HasV9, HasHardQuad] in 1542 def FMOVQ : F3_3u<2, 0b110100, 0b000000011, 1543 (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 1544 "fmovq $rs2, $rd", []>; 1545 def FNEGD : F3_3u<2, 0b110100, 0b000000110, 1546 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 1547 "fnegd $rs2, $rd", 1548 [(set f64:$rd, (fneg f64:$rs2))]>; 1549 let Predicates = [HasV9, HasHardQuad] in 1550 def FNEGQ : F3_3u<2, 0b110100, 0b000000111, 1551 (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 1552 "fnegq $rs2, $rd", 1553 [(set f128:$rd, (fneg f128:$rs2))]>; 1554 def FABSD : F3_3u<2, 0b110100, 0b000001010, 1555 (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 1556 "fabsd $rs2, $rd", 1557 [(set f64:$rd, (fabs f64:$rs2))]>; 1558 let Predicates = [HasV9, HasHardQuad] in 1559 def FABSQ : F3_3u<2, 0b110100, 0b000001011, 1560 (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 1561 "fabsq $rs2, $rd", 1562 [(set f128:$rd, (fabs f128:$rs2))]>; 1563} 1564 1565// Floating-point compare instruction with %fcc0-%fcc3. 1566def V9FCMPS : F3_3c<2, 0b110101, 0b001010001, 1567 (outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1568 "fcmps $rd, $rs1, $rs2", []>; 1569def V9FCMPD : F3_3c<2, 0b110101, 0b001010010, 1570 (outs FCCRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1571 "fcmpd $rd, $rs1, $rs2", []>; 1572def V9FCMPQ : F3_3c<2, 0b110101, 0b001010011, 1573 (outs FCCRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1574 "fcmpq $rd, $rs1, $rs2", []>, 1575 Requires<[HasHardQuad]>; 1576 1577let hasSideEffects = 1 in { 1578 def V9FCMPES : F3_3c<2, 0b110101, 0b001010101, 1579 (outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 1580 "fcmpes $rd, $rs1, $rs2", []>; 1581 def V9FCMPED : F3_3c<2, 0b110101, 0b001010110, 1582 (outs FCCRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 1583 "fcmped $rd, $rs1, $rs2", []>; 1584 def V9FCMPEQ : F3_3c<2, 0b110101, 0b001010111, 1585 (outs FCCRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 1586 "fcmpeq $rd, $rs1, $rs2", []>, 1587 Requires<[HasHardQuad]>; 1588} 1589 1590// Floating point conditional move instrucitons with %fcc0-%fcc3. 1591let Predicates = [HasV9] in { 1592 let Constraints = "$f = $rd", intcc = 0 in { 1593 def V9MOVFCCrr 1594 : F4_1<0b101100, (outs IntRegs:$rd), 1595 (ins FCCRegs:$cc, IntRegs:$rs2, IntRegs:$f, CCOp:$cond), 1596 "mov$cond $cc, $rs2, $rd", []>; 1597 def V9MOVFCCri 1598 : F4_2<0b101100, (outs IntRegs:$rd), 1599 (ins FCCRegs:$cc, i32imm:$simm11, IntRegs:$f, CCOp:$cond), 1600 "mov$cond $cc, $simm11, $rd", []>; 1601 def V9FMOVS_FCC 1602 : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), 1603 (ins FCCRegs:$opf_cc, FPRegs:$rs2, FPRegs:$f, CCOp:$cond), 1604 "fmovs$cond $opf_cc, $rs2, $rd", []>; 1605 def V9FMOVD_FCC 1606 : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), 1607 (ins FCCRegs:$opf_cc, DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), 1608 "fmovd$cond $opf_cc, $rs2, $rd", []>; 1609 let Predicates = [HasV9, HasHardQuad] in 1610 def V9FMOVQ_FCC 1611 : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), 1612 (ins FCCRegs:$opf_cc, QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), 1613 "fmovq$cond $opf_cc, $rs2, $rd", []>; 1614 } // Constraints = "$f = $rd", ... 1615} // let Predicates = [hasV9] 1616 1617 1618// POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear 1619// the top 32-bits before using it. To do this clearing, we use a SRLri X,0. 1620let rs1 = 0 in 1621 def POPCrr : F3_1<2, 0b101110, 1622 (outs IntRegs:$rd), (ins IntRegs:$rs2), 1623 "popc $rs2, $rd", []>, Requires<[HasV9]>; 1624def : Pat<(i32 (ctpop i32:$src)), 1625 (POPCrr (SRLri $src, 0))>; 1626 1627let Predicates = [HasV9], hasSideEffects = 1, rd = 0, rs1 = 0b01111 in 1628 def MEMBARi : F3_2<2, 0b101000, (outs), (ins MembarTag:$simm13), 1629 "membar $simm13", []>; 1630 1631let Predicates = [HasV9], rd = 15, rs1 = 0b00000 in 1632 def SIR: F3_2<2, 0b110000, (outs), 1633 (ins simm13Op:$simm13), 1634 "sir $simm13", []>; 1635 1636// The CAS instruction, unlike other instructions, only comes in a 1637// form which requires an ASI be provided. The ASI value hardcoded 1638// here is ASI_PRIMARY, the default unprivileged ASI for SparcV9. 1639let Predicates = [HasV9], Constraints = "$swap = $rd", asi = 0b10000000 in 1640 def CASrr: F3_1_asi<3, 0b111100, 1641 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2, 1642 IntRegs:$swap), 1643 "cas [$rs1], $rs2, $rd", 1644 [(set i32:$rd, 1645 (atomic_cmp_swap_32 iPTR:$rs1, i32:$rs2, i32:$swap))]>; 1646 1647 1648// CASA is supported as an instruction on some LEON3 and all LEON4 processors. 1649// This version can be automatically lowered from C code, selecting ASI 10 1650let Predicates = [HasLeonCASA], Constraints = "$swap = $rd", asi = 0b00001010 in 1651 def CASAasi10: F3_1_asi<3, 0b111100, 1652 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2, 1653 IntRegs:$swap), 1654 "casa [$rs1] 10, $rs2, $rd", 1655 [(set i32:$rd, 1656 (atomic_cmp_swap_32 iPTR:$rs1, i32:$rs2, i32:$swap))]>; 1657 1658// CASA supported on some LEON3 and all LEON4 processors. Same pattern as 1659// CASrr, above, but with a different ASI. This version is supported for 1660// inline assembly lowering only. 1661let Predicates = [HasLeonCASA], Constraints = "$swap = $rd" in 1662 def CASArr: F3_1_asi<3, 0b111100, 1663 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2, 1664 IntRegs:$swap, i8imm:$asi), 1665 "casa [$rs1] $asi, $rs2, $rd", []>; 1666 1667// TODO: Add DAG sequence to lower these instructions. Currently, only provided 1668// as inline assembler-supported instructions. 1669let Predicates = [HasUMAC_SMAC], Defs = [Y, ASR18], Uses = [Y, ASR18] in { 1670 def SMACrr : F3_1<2, 0b111111, 1671 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2, ASRRegs:$asr18), 1672 "smac $rs1, $rs2, $rd", 1673 [], IIC_smac_umac>; 1674 1675 def SMACri : F3_2<2, 0b111111, 1676 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13, ASRRegs:$asr18), 1677 "smac $rs1, $simm13, $rd", 1678 [], IIC_smac_umac>; 1679 1680 def UMACrr : F3_1<2, 0b111110, 1681 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2, ASRRegs:$asr18), 1682 "umac $rs1, $rs2, $rd", 1683 [], IIC_smac_umac>; 1684 1685 def UMACri : F3_2<2, 0b111110, 1686 (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13, ASRRegs:$asr18), 1687 "umac $rs1, $simm13, $rd", 1688 [], IIC_smac_umac>; 1689} 1690 1691// The partial write WRPSR instruction has a non-zero destination 1692// register value to separate it from the standard instruction. 1693let Predicates = [HasPWRPSR], Defs = [PSR], rd=1 in { 1694 def PWRPSRrr : F3_1<2, 0b110001, 1695 (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 1696 "pwr $rs1, $rs2, %psr", []>; 1697 def PWRPSRri : F3_2<2, 0b110001, 1698 (outs), (ins IntRegs:$rs1, simm13Op:$simm13), 1699 "pwr $rs1, $simm13, %psr", []>; 1700} 1701 1702let Defs = [ICC] in { 1703defm TADDCC : F3_12np<"taddcc", 0b100000>; 1704defm TSUBCC : F3_12np<"tsubcc", 0b100001>; 1705 1706let hasSideEffects = 1 in { 1707 defm TADDCCTV : F3_12np<"taddcctv", 0b100010>; 1708 defm TSUBCCTV : F3_12np<"tsubcctv", 0b100011>; 1709} 1710} 1711 1712// Section A.42 - Prefetch Data 1713let Predicates = [HasV9] in { 1714 def PREFETCHr : F3_1<3, 0b101101, 1715 (outs), (ins MEMrr:$addr, shift_imm5:$rd), 1716 "prefetch [$addr], $rd", []>; 1717 def PREFETCHi : F3_2<3, 0b101101, 1718 (outs), (ins MEMri:$addr, shift_imm5:$rd), 1719 "prefetch [$addr], $rd", []>; 1720} 1721 1722 1723 1724// Section A.43 - Read Privileged Register Instructions 1725let Predicates = [HasV9] in { 1726let rs2 = 0 in 1727 def RDPR : F3_1<2, 0b101010, 1728 (outs IntRegs:$rd), (ins PRRegs:$rs1), 1729 "rdpr $rs1, $rd", []>; 1730} 1731 1732// Section A.62 - Write Privileged Register Instructions 1733let Predicates = [HasV9] in { 1734 def WRPRrr : F3_1<2, 0b110010, 1735 (outs PRRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 1736 "wrpr $rs1, $rs2, $rd", []>; 1737 def WRPRri : F3_2<2, 0b110010, 1738 (outs PRRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), 1739 "wrpr $rs1, $simm13, $rd", []>; 1740} 1741 1742//===----------------------------------------------------------------------===// 1743// Non-Instruction Patterns 1744//===----------------------------------------------------------------------===// 1745 1746// Zero immediate. 1747def : Pat<(i32 0), 1748 (ORrr (i32 G0), (i32 G0))>; 1749// Small immediates. 1750def : Pat<(i32 simm13:$val), 1751 (ORri (i32 G0), imm:$val)>; 1752// Arbitrary immediates. 1753def : Pat<(i32 imm:$val), 1754 (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>; 1755 1756 1757// Global addresses, constant pool entries 1758let Predicates = [Is32Bit] in { 1759 1760def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; 1761def : Pat<(SPlo tglobaladdr:$in), (ORri (i32 G0), tglobaladdr:$in)>; 1762def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>; 1763def : Pat<(SPlo tconstpool:$in), (ORri (i32 G0), tconstpool:$in)>; 1764 1765// GlobalTLS addresses 1766def : Pat<(SPhi tglobaltlsaddr:$in), (SETHIi tglobaltlsaddr:$in)>; 1767def : Pat<(SPlo tglobaltlsaddr:$in), (ORri (i32 G0), tglobaltlsaddr:$in)>; 1768def : Pat<(add (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), 1769 (ADDri (SETHIi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; 1770def : Pat<(xor (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), 1771 (XORri (SETHIi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; 1772 1773// Blockaddress 1774def : Pat<(SPhi tblockaddress:$in), (SETHIi tblockaddress:$in)>; 1775def : Pat<(SPlo tblockaddress:$in), (ORri (i32 G0), tblockaddress:$in)>; 1776 1777// Add reg, lo. This is used when taking the addr of a global/constpool entry. 1778def : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (ADDri $r, tglobaladdr:$in)>; 1779def : Pat<(add iPTR:$r, (SPlo tconstpool:$in)), (ADDri $r, tconstpool:$in)>; 1780def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)), 1781 (ADDri $r, tblockaddress:$in)>; 1782} 1783 1784// Calls: 1785def : Pat<(call tglobaladdr:$dst), 1786 (CALL tglobaladdr:$dst)>; 1787def : Pat<(call texternalsym:$dst), 1788 (CALL texternalsym:$dst)>; 1789 1790// Map integer extload's to zextloads. 1791def : Pat<(i32 (extloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1792def : Pat<(i32 (extloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1793def : Pat<(i32 (extloadi8 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1794def : Pat<(i32 (extloadi8 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1795def : Pat<(i32 (extloadi16 ADDRrr:$src)), (LDUHrr ADDRrr:$src)>; 1796def : Pat<(i32 (extloadi16 ADDRri:$src)), (LDUHri ADDRri:$src)>; 1797 1798// zextload bool -> zextload byte 1799def : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1800def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1801 1802// store 0, addr -> store %g0, addr 1803def : Pat<(store (i32 0), ADDRrr:$dst), (STrr ADDRrr:$dst, (i32 G0))>; 1804def : Pat<(store (i32 0), ADDRri:$dst), (STri ADDRri:$dst, (i32 G0))>; 1805 1806// store bar for all atomic_fence in V8. 1807let Predicates = [HasNoV9] in 1808 def : Pat<(atomic_fence timm, timm), (STBAR)>; 1809 1810let Predicates = [HasV9] in 1811 def : Pat<(atomic_fence timm, timm), (MEMBARi 0xf)>; 1812 1813// atomic_load addr -> load addr 1814def : Pat<(i32 (atomic_load_8 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1815def : Pat<(i32 (atomic_load_8 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1816def : Pat<(i32 (atomic_load_16 ADDRrr:$src)), (LDUHrr ADDRrr:$src)>; 1817def : Pat<(i32 (atomic_load_16 ADDRri:$src)), (LDUHri ADDRri:$src)>; 1818def : Pat<(i32 (atomic_load_32 ADDRrr:$src)), (LDrr ADDRrr:$src)>; 1819def : Pat<(i32 (atomic_load_32 ADDRri:$src)), (LDri ADDRri:$src)>; 1820 1821// atomic_store val, addr -> store val, addr 1822def : Pat<(atomic_store_8 ADDRrr:$dst, i32:$val), (STBrr ADDRrr:$dst, $val)>; 1823def : Pat<(atomic_store_8 ADDRri:$dst, i32:$val), (STBri ADDRri:$dst, $val)>; 1824def : Pat<(atomic_store_16 ADDRrr:$dst, i32:$val), (STHrr ADDRrr:$dst, $val)>; 1825def : Pat<(atomic_store_16 ADDRri:$dst, i32:$val), (STHri ADDRri:$dst, $val)>; 1826def : Pat<(atomic_store_32 ADDRrr:$dst, i32:$val), (STrr ADDRrr:$dst, $val)>; 1827def : Pat<(atomic_store_32 ADDRri:$dst, i32:$val), (STri ADDRri:$dst, $val)>; 1828 1829// extract_vector 1830def : Pat<(extractelt (v2i32 IntPair:$Rn), 0), 1831 (i32 (EXTRACT_SUBREG IntPair:$Rn, sub_even))>; 1832def : Pat<(extractelt (v2i32 IntPair:$Rn), 1), 1833 (i32 (EXTRACT_SUBREG IntPair:$Rn, sub_odd))>; 1834 1835// build_vector 1836def : Pat<(build_vector (i32 IntRegs:$a1), (i32 IntRegs:$a2)), 1837 (INSERT_SUBREG 1838 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), (i32 IntRegs:$a1), sub_even), 1839 (i32 IntRegs:$a2), sub_odd)>; 1840 1841 1842include "SparcInstr64Bit.td" 1843include "SparcInstrVIS.td" 1844include "SparcInstrAliases.td" 1845