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