1235633Sdim//===-- SparcInstrInfo.td - Target Description for Sparc Target -----------===// 2235633Sdim// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7235633Sdim// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file describes the Sparc instructions in TableGen format. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed//===----------------------------------------------------------------------===// 15193323Sed// Instruction format superclass 16193323Sed//===----------------------------------------------------------------------===// 17193323Sed 18193323Sedinclude "SparcInstrFormats.td" 19193323Sed 20193323Sed//===----------------------------------------------------------------------===// 21193323Sed// Feature predicates. 22193323Sed//===----------------------------------------------------------------------===// 23193323Sed 24252723Sdim// True when generating 32-bit code. 25252723Sdimdef Is32Bit : Predicate<"!Subtarget.is64Bit()">; 26252723Sdim 27252723Sdim// True when generating 64-bit code. This also implies HasV9. 28252723Sdimdef Is64Bit : Predicate<"Subtarget.is64Bit()">; 29252723Sdim 30193323Sed// HasV9 - This predicate is true when the target processor supports V9 31193323Sed// instructions. Note that the machine may be running in 32-bit mode. 32193323Seddef HasV9 : Predicate<"Subtarget.isV9()">; 33193323Sed 34193323Sed// HasNoV9 - This predicate is true when the target doesn't have V9 35193323Sed// instructions. Use of this is just a hack for the isel not having proper 36193323Sed// costs for V8 instructions that are more expensive than their V9 ones. 37193323Seddef HasNoV9 : Predicate<"!Subtarget.isV9()">; 38193323Sed 39193323Sed// HasVIS - This is true when the target processor has VIS extensions. 40193323Seddef HasVIS : Predicate<"Subtarget.isVIS()">; 41193323Sed 42263509Sdim// HasHardQuad - This is true when the target processor supports quad floating 43263509Sdim// point instructions. 44263509Sdimdef HasHardQuad : Predicate<"Subtarget.hasHardQuad()">; 45263509Sdim 46193323Sed// UseDeprecatedInsts - This predicate is true when the target processor is a 47193323Sed// V8, or when it is V9 but the V8 deprecated instructions are efficient enough 48193323Sed// to use when appropriate. In either of these cases, the instruction selector 49193323Sed// will pick deprecated instructions. 50193323Seddef UseDeprecatedInsts : Predicate<"Subtarget.useDeprecatedV8Instructions()">; 51193323Sed 52193323Sed//===----------------------------------------------------------------------===// 53193323Sed// Instruction Pattern Stuff 54193323Sed//===----------------------------------------------------------------------===// 55193323Sed 56212904Sdimdef simm11 : PatLeaf<(imm), [{ return isInt<11>(N->getSExtValue()); }]>; 57193323Sed 58212904Sdimdef simm13 : PatLeaf<(imm), [{ return isInt<13>(N->getSExtValue()); }]>; 59193323Sed 60193323Seddef LO10 : SDNodeXForm<imm, [{ 61193323Sed return CurDAG->getTargetConstant((unsigned)N->getZExtValue() & 1023, 62193323Sed MVT::i32); 63193323Sed}]>; 64193323Sed 65193323Seddef HI22 : SDNodeXForm<imm, [{ 66193323Sed // Transformation function: shift the immediate value down into the low bits. 67193323Sed return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 10, MVT::i32); 68193323Sed}]>; 69193323Sed 70193323Seddef SETHIimm : PatLeaf<(imm), [{ 71252723Sdim return isShiftedUInt<22, 10>(N->getZExtValue()); 72193323Sed}], HI22>; 73193323Sed 74193323Sed// Addressing modes. 75252723Sdimdef ADDRrr : ComplexPattern<iPTR, 2, "SelectADDRrr", [], []>; 76252723Sdimdef ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri", [frameindex], []>; 77193323Sed 78193323Sed// Address operands 79263764Sdimdef SparcMEMrrAsmOperand : AsmOperandClass { 80263764Sdim let Name = "MEMrr"; 81263764Sdim let ParserMethod = "parseMEMOperand"; 82263764Sdim} 83263764Sdim 84263764Sdimdef SparcMEMriAsmOperand : AsmOperandClass { 85263764Sdim let Name = "MEMri"; 86263764Sdim let ParserMethod = "parseMEMOperand"; 87263764Sdim} 88263764Sdim 89252723Sdimdef MEMrr : Operand<iPTR> { 90193323Sed let PrintMethod = "printMemOperand"; 91252723Sdim let MIOperandInfo = (ops ptr_rc, ptr_rc); 92263764Sdim let ParserMatchClass = SparcMEMrrAsmOperand; 93193323Sed} 94252723Sdimdef MEMri : Operand<iPTR> { 95193323Sed let PrintMethod = "printMemOperand"; 96252723Sdim let MIOperandInfo = (ops ptr_rc, i32imm); 97263764Sdim let ParserMatchClass = SparcMEMriAsmOperand; 98193323Sed} 99193323Sed 100263509Sdimdef TLSSym : Operand<iPTR>; 101263509Sdim 102193323Sed// Branch targets have OtherVT type. 103263764Sdimdef brtarget : Operand<OtherVT> { 104263764Sdim let EncoderMethod = "getBranchTargetOpValue"; 105263764Sdim} 106193323Sed 107263764Sdimdef calltarget : Operand<i32> { 108263764Sdim let EncoderMethod = "getCallTargetOpValue"; 109263764Sdim} 110263764Sdim 111193323Sed// Operand for printing out a condition code. 112193323Sedlet PrintMethod = "printCCOperand" in 113193323Sed def CCOp : Operand<i32>; 114193323Sed 115263509Sdimdef SDTSPcmpicc : 116263509SdimSDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; 117263509Sdimdef SDTSPcmpfcc : 118193323SedSDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisSameAs<0, 1>]>; 119263509Sdimdef SDTSPbrcc : 120193323SedSDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 121193323Seddef SDTSPselectcc : 122193323SedSDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>]>; 123193323Seddef SDTSPFTOI : 124193323SedSDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>; 125193323Seddef SDTSPITOF : 126193323SedSDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; 127263509Sdimdef SDTSPFTOX : 128263509SdimSDTypeProfile<1, 1, [SDTCisVT<0, f64>, SDTCisFP<1>]>; 129263509Sdimdef SDTSPXTOF : 130263509SdimSDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f64>]>; 131193323Sed 132263509Sdimdef SDTSPtlsadd : 133263509SdimSDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>; 134263509Sdimdef SDTSPtlsld : 135263509SdimSDTypeProfile<1, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>; 136263509Sdim 137263509Sdimdef SPcmpicc : SDNode<"SPISD::CMPICC", SDTSPcmpicc, [SDNPOutGlue]>; 138218893Sdimdef SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>; 139218893Sdimdef SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 140252723Sdimdef SPbrxcc : SDNode<"SPISD::BRXCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 141218893Sdimdef SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>; 142193323Sed 143193323Seddef SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>; 144193323Seddef SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>; 145193323Sed 146193323Seddef SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>; 147193323Seddef SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>; 148263509Sdimdef SPftox : SDNode<"SPISD::FTOX", SDTSPFTOX>; 149263509Sdimdef SPxtof : SDNode<"SPISD::XTOF", SDTSPXTOF>; 150193323Sed 151218893Sdimdef SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>; 152252723Sdimdef SPselectxcc : SDNode<"SPISD::SELECT_XCC", SDTSPselectcc, [SDNPInGlue]>; 153218893Sdimdef SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>; 154193323Sed 155198090Srdivacky// These are target-independent nodes, but have target-specific formats. 156193323Seddef SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 157193323Seddef SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 158193323Sed SDTCisVT<1, i32> ]>; 159193323Sed 160193323Seddef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 161218893Sdim [SDNPHasChain, SDNPOutGlue]>; 162193323Seddef callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 163218893Sdim [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 164193323Sed 165218893Sdimdef SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; 166193323Seddef call : SDNode<"SPISD::CALL", SDT_SPCall, 167218893Sdim [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 168218893Sdim SDNPVariadic]>; 169193323Sed 170219077Sdimdef SDT_SPRet : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 171219077Sdimdef retflag : SDNode<"SPISD::RET_FLAG", SDT_SPRet, 172252723Sdim [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 173193323Sed 174218893Sdimdef flushw : SDNode<"SPISD::FLUSHW", SDTNone, 175245431Sdim [SDNPHasChain, SDNPSideEffect, SDNPMayStore]>; 176218893Sdim 177263509Sdimdef tlsadd : SDNode<"SPISD::TLS_ADD", SDTSPtlsadd>; 178263509Sdimdef tlsld : SDNode<"SPISD::TLS_LD", SDTSPtlsld>; 179263509Sdimdef tlscall : SDNode<"SPISD::TLS_CALL", SDT_SPCall, 180263509Sdim [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 181263509Sdim SDNPVariadic]>; 182263509Sdim 183263764Sdimdef getPCX : Operand<iPTR> { 184198090Srdivacky let PrintMethod = "printGetPCX"; 185219077Sdim} 186198090Srdivacky 187193323Sed//===----------------------------------------------------------------------===// 188193323Sed// SPARC Flag Conditions 189193323Sed//===----------------------------------------------------------------------===// 190193323Sed 191193323Sed// Note that these values must be kept in sync with the CCOp::CondCode enum 192193323Sed// values. 193193323Sedclass ICC_VAL<int N> : PatLeaf<(i32 N)>; 194193323Seddef ICC_NE : ICC_VAL< 9>; // Not Equal 195193323Seddef ICC_E : ICC_VAL< 1>; // Equal 196193323Seddef ICC_G : ICC_VAL<10>; // Greater 197193323Seddef ICC_LE : ICC_VAL< 2>; // Less or Equal 198193323Seddef ICC_GE : ICC_VAL<11>; // Greater or Equal 199193323Seddef ICC_L : ICC_VAL< 3>; // Less 200193323Seddef ICC_GU : ICC_VAL<12>; // Greater Unsigned 201193323Seddef ICC_LEU : ICC_VAL< 4>; // Less or Equal Unsigned 202193323Seddef ICC_CC : ICC_VAL<13>; // Carry Clear/Great or Equal Unsigned 203193323Seddef ICC_CS : ICC_VAL< 5>; // Carry Set/Less Unsigned 204193323Seddef ICC_POS : ICC_VAL<14>; // Positive 205193323Seddef ICC_NEG : ICC_VAL< 6>; // Negative 206193323Seddef ICC_VC : ICC_VAL<15>; // Overflow Clear 207193323Seddef ICC_VS : ICC_VAL< 7>; // Overflow Set 208193323Sed 209193323Sedclass FCC_VAL<int N> : PatLeaf<(i32 N)>; 210193323Seddef FCC_U : FCC_VAL<23>; // Unordered 211193323Seddef FCC_G : FCC_VAL<22>; // Greater 212193323Seddef FCC_UG : FCC_VAL<21>; // Unordered or Greater 213193323Seddef FCC_L : FCC_VAL<20>; // Less 214193323Seddef FCC_UL : FCC_VAL<19>; // Unordered or Less 215193323Seddef FCC_LG : FCC_VAL<18>; // Less or Greater 216193323Seddef FCC_NE : FCC_VAL<17>; // Not Equal 217193323Seddef FCC_E : FCC_VAL<25>; // Equal 218193323Seddef FCC_UE : FCC_VAL<24>; // Unordered or Equal 219193323Seddef FCC_GE : FCC_VAL<25>; // Greater or Equal 220193323Seddef FCC_UGE : FCC_VAL<26>; // Unordered or Greater or Equal 221193323Seddef FCC_LE : FCC_VAL<27>; // Less or Equal 222193323Seddef FCC_ULE : FCC_VAL<28>; // Unordered or Less or Equal 223193323Seddef FCC_O : FCC_VAL<29>; // Ordered 224193323Sed 225193323Sed//===----------------------------------------------------------------------===// 226193323Sed// Instruction Class Templates 227193323Sed//===----------------------------------------------------------------------===// 228193323Sed 229193323Sed/// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot. 230263764Sdimmulticlass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode, 231263764Sdim RegisterClass RC, ValueType Ty, Operand immOp> { 232263509Sdim def rr : F3_1<2, Op3Val, 233263764Sdim (outs RC:$rd), (ins RC:$rs1, RC:$rs2), 234263764Sdim !strconcat(OpcStr, " $rs1, $rs2, $rd"), 235263764Sdim [(set Ty:$rd, (OpNode Ty:$rs1, Ty:$rs2))]>; 236193323Sed def ri : F3_2<2, Op3Val, 237263764Sdim (outs RC:$rd), (ins RC:$rs1, immOp:$simm13), 238263764Sdim !strconcat(OpcStr, " $rs1, $simm13, $rd"), 239263764Sdim [(set Ty:$rd, (OpNode Ty:$rs1, (Ty simm13:$simm13)))]>; 240193323Sed} 241193323Sed 242193323Sed/// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no 243193323Sed/// pattern. 244193323Sedmulticlass F3_12np<string OpcStr, bits<6> Op3Val> { 245263509Sdim def rr : F3_1<2, Op3Val, 246263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 247263764Sdim !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; 248193323Sed def ri : F3_2<2, Op3Val, 249263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), 250263764Sdim !strconcat(OpcStr, " $rs1, $simm13, $rd"), []>; 251193323Sed} 252193323Sed 253263764Sdim// Load multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot. 254263764Sdimmulticlass Load<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode, 255263764Sdim RegisterClass RC, ValueType Ty> { 256263764Sdim def rr : F3_1<3, Op3Val, 257263764Sdim (outs RC:$dst), (ins MEMrr:$addr), 258263764Sdim !strconcat(OpcStr, " [$addr], $dst"), 259263764Sdim [(set Ty:$dst, (OpNode ADDRrr:$addr))]>; 260263764Sdim def ri : F3_2<3, Op3Val, 261263764Sdim (outs RC:$dst), (ins MEMri:$addr), 262263764Sdim !strconcat(OpcStr, " [$addr], $dst"), 263263764Sdim [(set Ty:$dst, (OpNode ADDRri:$addr))]>; 264263764Sdim} 265263764Sdim 266263764Sdim// Store multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot. 267263764Sdimmulticlass Store<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode, 268263764Sdim RegisterClass RC, ValueType Ty> { 269263764Sdim def rr : F3_1<3, Op3Val, 270263764Sdim (outs), (ins MEMrr:$addr, RC:$rd), 271263764Sdim !strconcat(OpcStr, " $rd, [$addr]"), 272263764Sdim [(OpNode Ty:$rd, ADDRrr:$addr)]>; 273263764Sdim def ri : F3_2<3, Op3Val, 274263764Sdim (outs), (ins MEMri:$addr, RC:$rd), 275263764Sdim !strconcat(OpcStr, " $rd, [$addr]"), 276263764Sdim [(OpNode Ty:$rd, ADDRri:$addr)]>; 277263764Sdim} 278263764Sdim 279193323Sed//===----------------------------------------------------------------------===// 280193323Sed// Instructions 281193323Sed//===----------------------------------------------------------------------===// 282193323Sed 283193323Sed// Pseudo instructions. 284193323Sedclass Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 285263764Sdim : InstSP<outs, ins, asmstr, pattern> { 286263764Sdim let isCodeGenOnly = 1; 287263764Sdim let isPseudo = 1; 288263764Sdim} 289193323Sed 290198090Srdivacky// GETPCX for PIC 291218893Sdimlet Defs = [O7] in { 292198090Srdivacky def GETPCX : Pseudo<(outs getPCX:$getpcseq), (ins), "$getpcseq", [] >; 293198090Srdivacky} 294198090Srdivacky 295193323Sedlet Defs = [O6], Uses = [O6] in { 296193323Seddef ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 297193323Sed "!ADJCALLSTACKDOWN $amt", 298193323Sed [(callseq_start timm:$amt)]>; 299193323Seddef ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 300193323Sed "!ADJCALLSTACKUP $amt1", 301193323Sed [(callseq_end timm:$amt1, timm:$amt2)]>; 302193323Sed} 303193323Sed 304218893Sdimlet hasSideEffects = 1, mayStore = 1 in { 305218893Sdim let rd = 0, rs1 = 0, rs2 = 0 in 306218893Sdim def FLUSHW : F3_1<0b10, 0b101011, (outs), (ins), 307218893Sdim "flushw", 308218893Sdim [(flushw)]>, Requires<[HasV9]>; 309218893Sdim let rd = 0, rs1 = 1, simm13 = 3 in 310218893Sdim def TA3 : F3_2<0b10, 0b111010, (outs), (ins), 311218893Sdim "ta 3", 312218893Sdim [(flushw)]>; 313218893Sdim} 314218893Sdim 315263764Sdimlet isBarrier = 1, isTerminator = 1, rd = 0b1000, rs1 = 0, simm13 = 5 in 316263764Sdim def TA5 : F3_2<0b10, 0b111010, (outs), (ins), "ta 5", [(trap)]>; 317263764Sdim 318263509Sdimlet rd = 0 in 319263509Sdim def UNIMP : F2_1<0b000, (outs), (ins i32imm:$val), 320263509Sdim "unimp $val", []>; 321219077Sdim 322198892Srdivacky// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 323198892Srdivacky// instruction selection into a branch sequence. This has to handle all 324198892Srdivacky// permutations of selection between i32/f32/f64 on ICC and FCC. 325263509Sdim// Expanded after instruction selection. 326263509Sdimlet Uses = [ICC], usesCustomInserter = 1 in { 327193323Sed def SELECT_CC_Int_ICC 328193323Sed : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 329193323Sed "; SELECT_CC_Int_ICC PSEUDO!", 330252723Sdim [(set i32:$dst, (SPselecticc i32:$T, i32:$F, imm:$Cond))]>; 331218893Sdim def SELECT_CC_FP_ICC 332218893Sdim : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 333218893Sdim "; SELECT_CC_FP_ICC PSEUDO!", 334252723Sdim [(set f32:$dst, (SPselecticc f32:$T, f32:$F, imm:$Cond))]>; 335218893Sdim 336218893Sdim def SELECT_CC_DFP_ICC 337218893Sdim : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 338218893Sdim "; SELECT_CC_DFP_ICC PSEUDO!", 339252723Sdim [(set f64:$dst, (SPselecticc f64:$T, f64:$F, imm:$Cond))]>; 340263509Sdim 341263509Sdim def SELECT_CC_QFP_ICC 342263509Sdim : Pseudo<(outs QFPRegs:$dst), (ins QFPRegs:$T, QFPRegs:$F, i32imm:$Cond), 343263509Sdim "; SELECT_CC_QFP_ICC PSEUDO!", 344263509Sdim [(set f128:$dst, (SPselecticc f128:$T, f128:$F, imm:$Cond))]>; 345218893Sdim} 346218893Sdim 347218893Sdimlet usesCustomInserter = 1, Uses = [FCC] in { 348218893Sdim 349193323Sed def SELECT_CC_Int_FCC 350193323Sed : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), 351193323Sed "; SELECT_CC_Int_FCC PSEUDO!", 352252723Sdim [(set i32:$dst, (SPselectfcc i32:$T, i32:$F, imm:$Cond))]>; 353218893Sdim 354193323Sed def SELECT_CC_FP_FCC 355193323Sed : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), 356193323Sed "; SELECT_CC_FP_FCC PSEUDO!", 357252723Sdim [(set f32:$dst, (SPselectfcc f32:$T, f32:$F, imm:$Cond))]>; 358193323Sed def SELECT_CC_DFP_FCC 359193323Sed : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), 360193323Sed "; SELECT_CC_DFP_FCC PSEUDO!", 361252723Sdim [(set f64:$dst, (SPselectfcc f64:$T, f64:$F, imm:$Cond))]>; 362263509Sdim def SELECT_CC_QFP_FCC 363263509Sdim : Pseudo<(outs QFPRegs:$dst), (ins QFPRegs:$T, QFPRegs:$F, i32imm:$Cond), 364263509Sdim "; SELECT_CC_QFP_FCC PSEUDO!", 365263509Sdim [(set f128:$dst, (SPselectfcc f128:$T, f128:$F, imm:$Cond))]>; 366193323Sed} 367193323Sed 368263764Sdim// JMPL Instruction. 369263764Sdimlet isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in { 370263764Sdim def JMPLrr: F3_1<2, 0b111000, (outs IntRegs:$dst), (ins MEMrr:$addr), 371263764Sdim "jmpl $addr, $dst", []>; 372263764Sdim def JMPLri: F3_2<2, 0b111000, (outs IntRegs:$dst), (ins MEMri:$addr), 373263764Sdim "jmpl $addr, $dst", []>; 374263764Sdim} 375193323Sed 376193323Sed// Section A.3 - Synthetic Instructions, p. 85 377193323Sed// special cases of JMPL: 378263764Sdimlet isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, 379263764Sdim isCodeGenOnly = 1 in { 380263509Sdim let rd = 0, rs1 = 15 in 381219077Sdim def RETL: F3_2<2, 0b111000, (outs), (ins i32imm:$val), 382219077Sdim "jmp %o7+$val", [(retflag simm13:$val)]>; 383218893Sdim 384263509Sdim let rd = 0, rs1 = 31 in 385219077Sdim def RET: F3_2<2, 0b111000, (outs), (ins i32imm:$val), 386219077Sdim "jmp %i7+$val", []>; 387193323Sed} 388193323Sed 389193323Sed// Section B.1 - Load Integer Instructions, p. 90 390263764Sdimdefm LDSB : Load<"ldsb", 0b001001, sextloadi8, IntRegs, i32>; 391263764Sdimdefm LDSH : Load<"ldsh", 0b001010, sextloadi16, IntRegs, i32>; 392263764Sdimdefm LDUB : Load<"ldub", 0b000001, zextloadi8, IntRegs, i32>; 393263764Sdimdefm LDUH : Load<"lduh", 0b000010, zextloadi16, IntRegs, i32>; 394263764Sdimdefm LD : Load<"ld", 0b000000, load, IntRegs, i32>; 395193323Sed 396193323Sed// Section B.2 - Load Floating-point Instructions, p. 92 397263764Sdimdefm LDF : Load<"ld", 0b100000, load, FPRegs, f32>; 398263764Sdimdefm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64>; 399263764Sdimdefm LDQF : Load<"ldq", 0b100010, load, QFPRegs, f128>, 400263764Sdim Requires<[HasV9, HasHardQuad]>; 401193323Sed 402193323Sed// Section B.4 - Store Integer Instructions, p. 95 403263764Sdimdefm STB : Store<"stb", 0b000101, truncstorei8, IntRegs, i32>; 404263764Sdimdefm STH : Store<"sth", 0b000110, truncstorei16, IntRegs, i32>; 405263764Sdimdefm ST : Store<"st", 0b000100, store, IntRegs, i32>; 406193323Sed 407193323Sed// Section B.5 - Store Floating-point Instructions, p. 97 408263764Sdimdefm STF : Store<"st", 0b100100, store, FPRegs, f32>; 409263764Sdimdefm STDF : Store<"std", 0b100111, store, DFPRegs, f64>; 410263764Sdimdefm STQF : Store<"stq", 0b100110, store, QFPRegs, f128>, 411263764Sdim Requires<[HasV9, HasHardQuad]>; 412193323Sed 413193323Sed// Section B.9 - SETHI Instruction, p. 104 414193323Seddef SETHIi: F2_1<0b100, 415263509Sdim (outs IntRegs:$rd), (ins i32imm:$imm22), 416263509Sdim "sethi $imm22, $rd", 417263509Sdim [(set i32:$rd, SETHIimm:$imm22)]>; 418193323Sed 419193323Sed// Section B.10 - NOP Instruction, p. 105 420193323Sed// (It's a special case of SETHI) 421193323Sedlet rd = 0, imm22 = 0 in 422193323Sed def NOP : F2_1<0b100, (outs), (ins), "nop", []>; 423193323Sed 424193323Sed// Section B.11 - Logical Instructions, p. 106 425263764Sdimdefm AND : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>; 426193323Sed 427193323Seddef ANDNrr : F3_1<2, 0b000101, 428263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 429263764Sdim "andn $rs1, $rs2, $rd", 430263764Sdim [(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>; 431193323Seddef ANDNri : F3_2<2, 0b000101, 432263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), 433263764Sdim "andn $rs1, $simm13, $rd", []>; 434193323Sed 435263764Sdimdefm OR : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>; 436193323Sed 437193323Seddef ORNrr : F3_1<2, 0b000110, 438263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 439263764Sdim "orn $rs1, $rs2, $rd", 440263764Sdim [(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>; 441193323Seddef ORNri : F3_2<2, 0b000110, 442263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), 443263764Sdim "orn $rs1, $simm13, $rd", []>; 444263764Sdimdefm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>; 445193323Sed 446193323Seddef XNORrr : F3_1<2, 0b000111, 447263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 448263764Sdim "xnor $rs1, $rs2, $rd", 449263764Sdim [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>; 450193323Seddef XNORri : F3_2<2, 0b000111, 451263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), 452263764Sdim "xnor $rs1, $simm13, $rd", []>; 453193323Sed 454193323Sed// Section B.12 - Shift Instructions, p. 107 455263764Sdimdefm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>; 456263764Sdimdefm SRL : F3_12<"srl", 0b100110, srl, IntRegs, i32, i32imm>; 457263764Sdimdefm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i32, i32imm>; 458193323Sed 459193323Sed// Section B.13 - Add Instructions, p. 108 460263764Sdimdefm ADD : F3_12<"add", 0b000000, add, IntRegs, i32, i32imm>; 461193323Sed 462193323Sed// "LEA" forms of add (patterns to make tblgen happy) 463263764Sdimlet Predicates = [Is32Bit], isCodeGenOnly = 1 in 464263509Sdim def LEA_ADDri : F3_2<2, 0b000000, 465263509Sdim (outs IntRegs:$dst), (ins MEMri:$addr), 466263509Sdim "add ${addr:arith}, $dst", 467263509Sdim [(set iPTR:$dst, ADDRri:$addr)]>; 468198090Srdivacky 469263509Sdimlet Defs = [ICC] in 470263764Sdim defm ADDCC : F3_12<"addcc", 0b010000, addc, IntRegs, i32, i32imm>; 471198090Srdivacky 472263509Sdimlet Uses = [ICC], Defs = [ICC] in 473263764Sdim defm ADDE : F3_12<"addxcc", 0b011000, adde, IntRegs, i32, i32imm>; 474193323Sed 475193323Sed// Section B.15 - Subtract Instructions, p. 110 476263764Sdimdefm SUB : F3_12 <"sub" , 0b000100, sub, IntRegs, i32, i32imm>; 477263509Sdimlet Uses = [ICC], Defs = [ICC] in 478263764Sdim defm SUBE : F3_12 <"subxcc" , 0b011100, sube, IntRegs, i32, i32imm>; 479193323Sed 480263509Sdimlet Defs = [ICC] in 481263764Sdim defm SUBCC : F3_12 <"subcc", 0b010100, subc, IntRegs, i32, i32imm>; 482193323Sed 483263509Sdimlet Defs = [ICC], rd = 0 in { 484263509Sdim def CMPrr : F3_1<2, 0b010100, 485263764Sdim (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 486263764Sdim "cmp $rs1, $rs2", 487263764Sdim [(SPcmpicc i32:$rs1, i32:$rs2)]>; 488263509Sdim def CMPri : F3_2<2, 0b010100, 489263764Sdim (outs), (ins IntRegs:$rs1, i32imm:$simm13), 490263764Sdim "cmp $rs1, $simm13", 491263764Sdim [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>; 492263509Sdim} 493263509Sdim 494193323Sed// Section B.18 - Multiply Instructions, p. 113 495218893Sdimlet Defs = [Y] in { 496218893Sdim defm UMUL : F3_12np<"umul", 0b001010>; 497263764Sdim defm SMUL : F3_12 <"smul", 0b001011, mul, IntRegs, i32, i32imm>; 498218893Sdim} 499193323Sed 500193323Sed// Section B.19 - Divide Instructions, p. 115 501218893Sdimlet Defs = [Y] in { 502218893Sdim defm UDIV : F3_12np<"udiv", 0b001110>; 503218893Sdim defm SDIV : F3_12np<"sdiv", 0b001111>; 504218893Sdim} 505193323Sed 506193323Sed// Section B.20 - SAVE and RESTORE, p. 117 507193323Seddefm SAVE : F3_12np<"save" , 0b111100>; 508193323Seddefm RESTORE : F3_12np<"restore", 0b111101>; 509193323Sed 510193323Sed// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119 511193323Sed 512263509Sdim// unconditional branch class. 513263509Sdimclass BranchAlways<dag ins, string asmstr, list<dag> pattern> 514263509Sdim : F2_2<0b010, (outs), ins, asmstr, pattern> { 515263509Sdim let isBranch = 1; 516263509Sdim let isTerminator = 1; 517263509Sdim let hasDelaySlot = 1; 518263509Sdim let isBarrier = 1; 519263509Sdim} 520263509Sdim 521263509Sdimlet cond = 8 in 522263509Sdim def BA : BranchAlways<(ins brtarget:$imm22), "ba $imm22", [(br bb:$imm22)]>; 523263509Sdim 524193323Sed// conditional branch class: 525263509Sdimclass BranchSP<dag ins, string asmstr, list<dag> pattern> 526263509Sdim : F2_2<0b010, (outs), ins, asmstr, pattern> { 527193323Sed let isBranch = 1; 528193323Sed let isTerminator = 1; 529193323Sed let hasDelaySlot = 1; 530193323Sed} 531193323Sed 532263509Sdim// Indirect branch instructions. 533263764Sdimlet isTerminator = 1, isBarrier = 1, hasDelaySlot = 1, isBranch =1, 534263764Sdim isIndirectBranch = 1, rd = 0, isCodeGenOnly = 1 in { 535263509Sdim def BINDrr : F3_1<2, 0b111000, 536263509Sdim (outs), (ins MEMrr:$ptr), 537263509Sdim "jmp $ptr", 538263509Sdim [(brind ADDRrr:$ptr)]>; 539263509Sdim def BINDri : F3_2<2, 0b111000, 540263509Sdim (outs), (ins MEMri:$ptr), 541263509Sdim "jmp $ptr", 542263509Sdim [(brind ADDRri:$ptr)]>; 543263509Sdim} 544198090Srdivacky 545198090Srdivackylet Uses = [ICC] in 546263509Sdim def BCOND : BranchSP<(ins brtarget:$imm22, CCOp:$cond), 547263509Sdim "b$cond $imm22", 548263509Sdim [(SPbricc bb:$imm22, imm:$cond)]>; 549193323Sed 550193323Sed// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 551193323Sed 552193323Sed// floating-point conditional branch class: 553263509Sdimclass FPBranchSP<dag ins, string asmstr, list<dag> pattern> 554263509Sdim : F2_2<0b110, (outs), ins, asmstr, pattern> { 555193323Sed let isBranch = 1; 556193323Sed let isTerminator = 1; 557193323Sed let hasDelaySlot = 1; 558193323Sed} 559193323Sed 560198090Srdivackylet Uses = [FCC] in 561263509Sdim def FBCOND : FPBranchSP<(ins brtarget:$imm22, CCOp:$cond), 562263509Sdim "fb$cond $imm22", 563263509Sdim [(SPbrfcc bb:$imm22, imm:$cond)]>; 564193323Sed 565193323Sed 566193323Sed// Section B.24 - Call and Link Instruction, p. 125 567193323Sed// This is the only Format 1 instruction 568218893Sdimlet Uses = [O6], 569263509Sdim hasDelaySlot = 1, isCall = 1 in { 570218893Sdim def CALL : InstSP<(outs), (ins calltarget:$dst, variable_ops), 571193323Sed "call $dst", []> { 572193323Sed bits<30> disp; 573193323Sed let op = 1; 574193323Sed let Inst{29-0} = disp; 575193323Sed } 576263509Sdim 577263764Sdim // indirect calls: special cases of JMPL. 578263764Sdim let isCodeGenOnly = 1, rd = 15 in { 579263764Sdim def CALLrr : F3_1<2, 0b111000, 580263764Sdim (outs), (ins MEMrr:$ptr, variable_ops), 581263764Sdim "call $ptr", 582263764Sdim [(call ADDRrr:$ptr)]>; 583263764Sdim def CALLri : F3_2<2, 0b111000, 584263764Sdim (outs), (ins MEMri:$ptr, variable_ops), 585263764Sdim "call $ptr", 586263764Sdim [(call ADDRri:$ptr)]>; 587263764Sdim } 588193323Sed} 589193323Sed 590193323Sed// Section B.28 - Read State Register Instructions 591263509Sdimlet Uses = [Y], rs1 = 0, rs2 = 0 in 592218893Sdim def RDY : F3_1<2, 0b101000, 593218893Sdim (outs IntRegs:$dst), (ins), 594218893Sdim "rd %y, $dst", []>; 595193323Sed 596193323Sed// Section B.29 - Write State Register Instructions 597263509Sdimlet Defs = [Y], rd = 0 in { 598218893Sdim def WRYrr : F3_1<2, 0b110000, 599218893Sdim (outs), (ins IntRegs:$b, IntRegs:$c), 600218893Sdim "wr $b, $c, %y", []>; 601218893Sdim def WRYri : F3_2<2, 0b110000, 602218893Sdim (outs), (ins IntRegs:$b, i32imm:$c), 603218893Sdim "wr $b, $c, %y", []>; 604218893Sdim} 605193323Sed// Convert Integer to Floating-point Instructions, p. 141 606263509Sdimdef FITOS : F3_3u<2, 0b110100, 0b011000100, 607263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs2), 608263764Sdim "fitos $rs2, $rd", 609263764Sdim [(set FPRegs:$rd, (SPitof FPRegs:$rs2))]>; 610263509Sdimdef FITOD : F3_3u<2, 0b110100, 0b011001000, 611263764Sdim (outs DFPRegs:$rd), (ins FPRegs:$rs2), 612263764Sdim "fitod $rs2, $rd", 613263764Sdim [(set DFPRegs:$rd, (SPitof FPRegs:$rs2))]>; 614263509Sdimdef FITOQ : F3_3u<2, 0b110100, 0b011001100, 615263764Sdim (outs QFPRegs:$rd), (ins FPRegs:$rs2), 616263764Sdim "fitoq $rs2, $rd", 617263764Sdim [(set QFPRegs:$rd, (SPitof FPRegs:$rs2))]>, 618263509Sdim Requires<[HasHardQuad]>; 619193323Sed 620193323Sed// Convert Floating-point to Integer Instructions, p. 142 621263509Sdimdef FSTOI : F3_3u<2, 0b110100, 0b011010001, 622263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs2), 623263764Sdim "fstoi $rs2, $rd", 624263764Sdim [(set FPRegs:$rd, (SPftoi FPRegs:$rs2))]>; 625263509Sdimdef FDTOI : F3_3u<2, 0b110100, 0b011010010, 626263764Sdim (outs FPRegs:$rd), (ins DFPRegs:$rs2), 627263764Sdim "fdtoi $rs2, $rd", 628263764Sdim [(set FPRegs:$rd, (SPftoi DFPRegs:$rs2))]>; 629263509Sdimdef FQTOI : F3_3u<2, 0b110100, 0b011010011, 630263764Sdim (outs FPRegs:$rd), (ins QFPRegs:$rs2), 631263764Sdim "fqtoi $rs2, $rd", 632263764Sdim [(set FPRegs:$rd, (SPftoi QFPRegs:$rs2))]>, 633263509Sdim Requires<[HasHardQuad]>; 634193323Sed 635193323Sed// Convert between Floating-point Formats Instructions, p. 143 636263509Sdimdef FSTOD : F3_3u<2, 0b110100, 0b011001001, 637263764Sdim (outs DFPRegs:$rd), (ins FPRegs:$rs2), 638263764Sdim "fstod $rs2, $rd", 639263764Sdim [(set f64:$rd, (fextend f32:$rs2))]>; 640263509Sdimdef FSTOQ : F3_3u<2, 0b110100, 0b011001101, 641263764Sdim (outs QFPRegs:$rd), (ins FPRegs:$rs2), 642263764Sdim "fstoq $rs2, $rd", 643263764Sdim [(set f128:$rd, (fextend f32:$rs2))]>, 644263509Sdim Requires<[HasHardQuad]>; 645263509Sdimdef FDTOS : F3_3u<2, 0b110100, 0b011000110, 646263764Sdim (outs FPRegs:$rd), (ins DFPRegs:$rs2), 647263764Sdim "fdtos $rs2, $rd", 648263764Sdim [(set f32:$rd, (fround f64:$rs2))]>; 649263764Sdimdef FDTOQ : F3_3u<2, 0b110100, 0b011001110, 650263764Sdim (outs QFPRegs:$rd), (ins DFPRegs:$rs2), 651263764Sdim "fdtoq $rs2, $rd", 652263764Sdim [(set f128:$rd, (fextend f64:$rs2))]>, 653263509Sdim Requires<[HasHardQuad]>; 654263509Sdimdef FQTOS : F3_3u<2, 0b110100, 0b011000111, 655263764Sdim (outs FPRegs:$rd), (ins QFPRegs:$rs2), 656263764Sdim "fqtos $rs2, $rd", 657263764Sdim [(set f32:$rd, (fround f128:$rs2))]>, 658263509Sdim Requires<[HasHardQuad]>; 659263509Sdimdef FQTOD : F3_3u<2, 0b110100, 0b011001011, 660263764Sdim (outs DFPRegs:$rd), (ins QFPRegs:$rs2), 661263764Sdim "fqtod $rs2, $rd", 662263764Sdim [(set f64:$rd, (fround f128:$rs2))]>, 663263509Sdim Requires<[HasHardQuad]>; 664193323Sed 665193323Sed// Floating-point Move Instructions, p. 144 666263509Sdimdef FMOVS : F3_3u<2, 0b110100, 0b000000001, 667263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs2), 668263764Sdim "fmovs $rs2, $rd", []>; 669263509Sdimdef FNEGS : F3_3u<2, 0b110100, 0b000000101, 670263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs2), 671263764Sdim "fnegs $rs2, $rd", 672263764Sdim [(set f32:$rd, (fneg f32:$rs2))]>; 673263509Sdimdef FABSS : F3_3u<2, 0b110100, 0b000001001, 674263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs2), 675263764Sdim "fabss $rs2, $rd", 676263764Sdim [(set f32:$rd, (fabs f32:$rs2))]>; 677193323Sed 678193323Sed 679193323Sed// Floating-point Square Root Instructions, p.145 680263509Sdimdef FSQRTS : F3_3u<2, 0b110100, 0b000101001, 681263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs2), 682263764Sdim "fsqrts $rs2, $rd", 683263764Sdim [(set f32:$rd, (fsqrt f32:$rs2))]>; 684263509Sdimdef FSQRTD : F3_3u<2, 0b110100, 0b000101010, 685263764Sdim (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 686263764Sdim "fsqrtd $rs2, $rd", 687263764Sdim [(set f64:$rd, (fsqrt f64:$rs2))]>; 688263509Sdimdef FSQRTQ : F3_3u<2, 0b110100, 0b000101011, 689263764Sdim (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 690263764Sdim "fsqrtq $rs2, $rd", 691263764Sdim [(set f128:$rd, (fsqrt f128:$rs2))]>, 692263509Sdim Requires<[HasHardQuad]>; 693193323Sed 694193323Sed 695193323Sed 696193323Sed// Floating-point Add and Subtract Instructions, p. 146 697193323Seddef FADDS : F3_3<2, 0b110100, 0b001000001, 698263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 699263764Sdim "fadds $rs1, $rs2, $rd", 700263764Sdim [(set f32:$rd, (fadd f32:$rs1, f32:$rs2))]>; 701193323Seddef FADDD : F3_3<2, 0b110100, 0b001000010, 702263764Sdim (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 703263764Sdim "faddd $rs1, $rs2, $rd", 704263764Sdim [(set f64:$rd, (fadd f64:$rs1, f64:$rs2))]>; 705263509Sdimdef FADDQ : F3_3<2, 0b110100, 0b001000011, 706263764Sdim (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 707263764Sdim "faddq $rs1, $rs2, $rd", 708263764Sdim [(set f128:$rd, (fadd f128:$rs1, f128:$rs2))]>, 709263509Sdim Requires<[HasHardQuad]>; 710263509Sdim 711193323Seddef FSUBS : F3_3<2, 0b110100, 0b001000101, 712263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 713263764Sdim "fsubs $rs1, $rs2, $rd", 714263764Sdim [(set f32:$rd, (fsub f32:$rs1, f32:$rs2))]>; 715193323Seddef FSUBD : F3_3<2, 0b110100, 0b001000110, 716263764Sdim (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 717263764Sdim "fsubd $rs1, $rs2, $rd", 718263764Sdim [(set f64:$rd, (fsub f64:$rs1, f64:$rs2))]>; 719263509Sdimdef FSUBQ : F3_3<2, 0b110100, 0b001000111, 720263764Sdim (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 721263764Sdim "fsubq $rs1, $rs2, $rd", 722263764Sdim [(set f128:$rd, (fsub f128:$rs1, f128:$rs2))]>, 723263509Sdim Requires<[HasHardQuad]>; 724193323Sed 725263509Sdim 726193323Sed// Floating-point Multiply and Divide Instructions, p. 147 727193323Seddef FMULS : F3_3<2, 0b110100, 0b001001001, 728263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 729263764Sdim "fmuls $rs1, $rs2, $rd", 730263764Sdim [(set f32:$rd, (fmul f32:$rs1, f32:$rs2))]>; 731193323Seddef FMULD : F3_3<2, 0b110100, 0b001001010, 732263764Sdim (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 733263764Sdim "fmuld $rs1, $rs2, $rd", 734263764Sdim [(set f64:$rd, (fmul f64:$rs1, f64:$rs2))]>; 735263509Sdimdef FMULQ : F3_3<2, 0b110100, 0b001001011, 736263764Sdim (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 737263764Sdim "fmulq $rs1, $rs2, $rd", 738263764Sdim [(set f128:$rd, (fmul f128:$rs1, f128:$rs2))]>, 739263509Sdim Requires<[HasHardQuad]>; 740263509Sdim 741193323Seddef FSMULD : F3_3<2, 0b110100, 0b001101001, 742263764Sdim (outs DFPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 743263764Sdim "fsmuld $rs1, $rs2, $rd", 744263764Sdim [(set f64:$rd, (fmul (fextend f32:$rs1), 745263764Sdim (fextend f32:$rs2)))]>; 746263509Sdimdef FDMULQ : F3_3<2, 0b110100, 0b001101110, 747263764Sdim (outs QFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 748263764Sdim "fdmulq $rs1, $rs2, $rd", 749263764Sdim [(set f128:$rd, (fmul (fextend f64:$rs1), 750263764Sdim (fextend f64:$rs2)))]>, 751263509Sdim Requires<[HasHardQuad]>; 752263509Sdim 753193323Seddef FDIVS : F3_3<2, 0b110100, 0b001001101, 754263764Sdim (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), 755263764Sdim "fdivs $rs1, $rs2, $rd", 756263764Sdim [(set f32:$rd, (fdiv f32:$rs1, f32:$rs2))]>; 757193323Seddef FDIVD : F3_3<2, 0b110100, 0b001001110, 758263764Sdim (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), 759263764Sdim "fdivd $rs1, $rs2, $rd", 760263764Sdim [(set f64:$rd, (fdiv f64:$rs1, f64:$rs2))]>; 761263509Sdimdef FDIVQ : F3_3<2, 0b110100, 0b001001111, 762263764Sdim (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), 763263764Sdim "fdivq $rs1, $rs2, $rd", 764263764Sdim [(set f128:$rd, (fdiv f128:$rs1, f128:$rs2))]>, 765263509Sdim Requires<[HasHardQuad]>; 766193323Sed 767193323Sed// Floating-point Compare Instructions, p. 148 768193323Sed// Note: the 2nd template arg is different for these guys. 769193323Sed// Note 2: the result of a FCMP is not available until the 2nd cycle 770263509Sdim// after the instr is retired, but there is no interlock in Sparc V8. 771263509Sdim// This behavior is modeled with a forced noop after the instruction in 772263509Sdim// DelaySlotFiller. 773263509Sdim 774198090Srdivackylet Defs = [FCC] in { 775263509Sdim def FCMPS : F3_3c<2, 0b110101, 0b001010001, 776263764Sdim (outs), (ins FPRegs:$rs1, FPRegs:$rs2), 777263764Sdim "fcmps $rs1, $rs2", 778263764Sdim [(SPcmpfcc f32:$rs1, f32:$rs2)]>; 779263509Sdim def FCMPD : F3_3c<2, 0b110101, 0b001010010, 780263764Sdim (outs), (ins DFPRegs:$rs1, DFPRegs:$rs2), 781263764Sdim "fcmpd $rs1, $rs2", 782263764Sdim [(SPcmpfcc f64:$rs1, f64:$rs2)]>; 783263509Sdim def FCMPQ : F3_3c<2, 0b110101, 0b001010011, 784263764Sdim (outs), (ins QFPRegs:$rs1, QFPRegs:$rs2), 785263764Sdim "fcmpq $rs1, $rs2", 786263764Sdim [(SPcmpfcc f128:$rs1, f128:$rs2)]>, 787263509Sdim Requires<[HasHardQuad]>; 788198090Srdivacky} 789193323Sed 790193323Sed//===----------------------------------------------------------------------===// 791263509Sdim// Instructions for Thread Local Storage(TLS). 792263509Sdim//===----------------------------------------------------------------------===// 793263764Sdimlet isCodeGenOnly = 1, isAsmParserOnly = 1 in { 794263509Sdimdef TLS_ADDrr : F3_1<2, 0b000000, 795263509Sdim (outs IntRegs:$rd), 796263509Sdim (ins IntRegs:$rs1, IntRegs:$rs2, TLSSym:$sym), 797263509Sdim "add $rs1, $rs2, $rd, $sym", 798263509Sdim [(set i32:$rd, 799263509Sdim (tlsadd i32:$rs1, i32:$rs2, tglobaltlsaddr:$sym))]>; 800263509Sdim 801263509Sdimlet mayLoad = 1 in 802263509Sdim def TLS_LDrr : F3_1<3, 0b000000, 803263509Sdim (outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym), 804263509Sdim "ld [$addr], $dst, $sym", 805263509Sdim [(set i32:$dst, 806263509Sdim (tlsld ADDRrr:$addr, tglobaltlsaddr:$sym))]>; 807263509Sdim 808263509Sdimlet Uses = [O6], isCall = 1, hasDelaySlot = 1 in 809263509Sdim def TLS_CALL : InstSP<(outs), 810263509Sdim (ins calltarget:$disp, TLSSym:$sym, variable_ops), 811263509Sdim "call $disp, $sym", 812263509Sdim [(tlscall texternalsym:$disp, tglobaltlsaddr:$sym)]> { 813263509Sdim bits<30> disp; 814263509Sdim let op = 1; 815263509Sdim let Inst{29-0} = disp; 816263509Sdim} 817263764Sdim} 818263509Sdim 819263509Sdim//===----------------------------------------------------------------------===// 820193323Sed// V9 Instructions 821193323Sed//===----------------------------------------------------------------------===// 822193323Sed 823193323Sed// V9 Conditional Moves. 824263509Sdimlet Predicates = [HasV9], Constraints = "$f = $rd" in { 825193323Sed // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. 826263509Sdim let Uses = [ICC], cc = 0b100 in { 827218893Sdim def MOVICCrr 828263509Sdim : F4_1<0b101100, (outs IntRegs:$rd), 829263509Sdim (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), 830263509Sdim "mov$cond %icc, $rs2, $rd", 831263509Sdim [(set i32:$rd, (SPselecticc i32:$rs2, i32:$f, imm:$cond))]>; 832263509Sdim 833218893Sdim def MOVICCri 834263509Sdim : F4_2<0b101100, (outs IntRegs:$rd), 835263509Sdim (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond), 836263509Sdim "mov$cond %icc, $simm11, $rd", 837263509Sdim [(set i32:$rd, 838263509Sdim (SPselecticc simm11:$simm11, i32:$f, imm:$cond))]>; 839218893Sdim } 840193323Sed 841263509Sdim let Uses = [FCC], cc = 0b000 in { 842218893Sdim def MOVFCCrr 843263509Sdim : F4_1<0b101100, (outs IntRegs:$rd), 844263509Sdim (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), 845263509Sdim "mov$cond %fcc0, $rs2, $rd", 846263509Sdim [(set i32:$rd, (SPselectfcc i32:$rs2, i32:$f, imm:$cond))]>; 847218893Sdim def MOVFCCri 848263509Sdim : F4_2<0b101100, (outs IntRegs:$rd), 849263509Sdim (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond), 850263509Sdim "mov$cond %fcc0, $simm11, $rd", 851263509Sdim [(set i32:$rd, 852263509Sdim (SPselectfcc simm11:$simm11, i32:$f, imm:$cond))]>; 853218893Sdim } 854193323Sed 855263509Sdim let Uses = [ICC], opf_cc = 0b100 in { 856218893Sdim def FMOVS_ICC 857263509Sdim : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), 858263509Sdim (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), 859263509Sdim "fmovs$cond %icc, $rs2, $rd", 860263509Sdim [(set f32:$rd, (SPselecticc f32:$rs2, f32:$f, imm:$cond))]>; 861218893Sdim def FMOVD_ICC 862263509Sdim : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), 863263509Sdim (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), 864263509Sdim "fmovd$cond %icc, $rs2, $rd", 865263509Sdim [(set f64:$rd, (SPselecticc f64:$rs2, f64:$f, imm:$cond))]>; 866263509Sdim def FMOVQ_ICC 867263509Sdim : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), 868263509Sdim (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), 869263764Sdim "fmovq$cond %icc, $rs2, $rd", 870263764Sdim [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>, 871263764Sdim Requires<[HasHardQuad]>; 872218893Sdim } 873193323Sed 874263509Sdim let Uses = [FCC], opf_cc = 0b000 in { 875218893Sdim def FMOVS_FCC 876263509Sdim : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), 877263509Sdim (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), 878263509Sdim "fmovs$cond %fcc0, $rs2, $rd", 879263509Sdim [(set f32:$rd, (SPselectfcc f32:$rs2, f32:$f, imm:$cond))]>; 880218893Sdim def FMOVD_FCC 881263509Sdim : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), 882263509Sdim (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), 883263509Sdim "fmovd$cond %fcc0, $rs2, $rd", 884263509Sdim [(set f64:$rd, (SPselectfcc f64:$rs2, f64:$f, imm:$cond))]>; 885263509Sdim def FMOVQ_FCC 886263509Sdim : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), 887263509Sdim (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), 888263764Sdim "fmovq$cond %fcc0, $rs2, $rd", 889263764Sdim [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>, 890263764Sdim Requires<[HasHardQuad]>; 891218893Sdim } 892218893Sdim 893193323Sed} 894193323Sed 895193323Sed// Floating-Point Move Instructions, p. 164 of the V9 manual. 896193323Sedlet Predicates = [HasV9] in { 897263509Sdim def FMOVD : F3_3u<2, 0b110100, 0b000000010, 898263764Sdim (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 899263764Sdim "fmovd $rs2, $rd", []>; 900263509Sdim def FMOVQ : F3_3u<2, 0b110100, 0b000000011, 901263764Sdim (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 902263764Sdim "fmovq $rs2, $rd", []>, 903263509Sdim Requires<[HasHardQuad]>; 904263509Sdim def FNEGD : F3_3u<2, 0b110100, 0b000000110, 905263764Sdim (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 906263764Sdim "fnegd $rs2, $rd", 907263764Sdim [(set f64:$rd, (fneg f64:$rs2))]>; 908263509Sdim def FNEGQ : F3_3u<2, 0b110100, 0b000000111, 909263764Sdim (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 910263764Sdim "fnegq $rs2, $rd", 911263764Sdim [(set f128:$rd, (fneg f128:$rs2))]>, 912263509Sdim Requires<[HasHardQuad]>; 913263509Sdim def FABSD : F3_3u<2, 0b110100, 0b000001010, 914263764Sdim (outs DFPRegs:$rd), (ins DFPRegs:$rs2), 915263764Sdim "fabsd $rs2, $rd", 916263764Sdim [(set f64:$rd, (fabs f64:$rs2))]>; 917263509Sdim def FABSQ : F3_3u<2, 0b110100, 0b000001011, 918263764Sdim (outs QFPRegs:$rd), (ins QFPRegs:$rs2), 919263764Sdim "fabsq $rs2, $rd", 920263764Sdim [(set f128:$rd, (fabs f128:$rs2))]>, 921263509Sdim Requires<[HasHardQuad]>; 922193323Sed} 923193323Sed 924193323Sed// POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear 925263764Sdim// the top 32-bits before using it. To do this clearing, we use a SRLri X,0. 926263509Sdimlet rs1 = 0 in 927263509Sdim def POPCrr : F3_1<2, 0b101110, 928263509Sdim (outs IntRegs:$dst), (ins IntRegs:$src), 929263509Sdim "popc $src, $dst", []>, Requires<[HasV9]>; 930252723Sdimdef : Pat<(ctpop i32:$src), 931263764Sdim (POPCrr (SRLri $src, 0))>; 932193323Sed 933263764Sdim// Atomic swap. 934263764Sdimlet hasSideEffects =1, rd = 0, rs1 = 0b01111, rs2 = 0 in 935263764Sdim def STBAR : F3_1<2, 0b101000, (outs), (ins), "stbar", []>; 936263764Sdim 937263764Sdimlet Predicates = [HasV9], hasSideEffects = 1, rd = 0, rs1 = 0b01111 in 938263764Sdim def MEMBARi : F3_2<2, 0b101000, (outs), (ins i32imm:$simm13), 939263764Sdim "membar $simm13", []>; 940263764Sdim 941263764Sdimlet Constraints = "$val = $dst" in { 942263764Sdim def SWAPrr : F3_1<3, 0b001111, 943263764Sdim (outs IntRegs:$dst), (ins MEMrr:$addr, IntRegs:$val), 944263764Sdim "swap [$addr], $dst", 945263764Sdim [(set i32:$dst, (atomic_swap_32 ADDRrr:$addr, i32:$val))]>; 946263764Sdim def SWAPri : F3_2<3, 0b001111, 947263764Sdim (outs IntRegs:$dst), (ins MEMri:$addr, IntRegs:$val), 948263764Sdim "swap [$addr], $dst", 949263764Sdim [(set i32:$dst, (atomic_swap_32 ADDRri:$addr, i32:$val))]>; 950263764Sdim} 951263764Sdim 952263764Sdimlet Predicates = [HasV9], Constraints = "$swap = $rd" in 953263764Sdim def CASrr: F3_1_asi<3, 0b111100, 0b10000000, 954263764Sdim (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2, 955263764Sdim IntRegs:$swap), 956263764Sdim "cas [$rs1], $rs2, $rd", 957263764Sdim [(set i32:$rd, 958263764Sdim (atomic_cmp_swap iPTR:$rs1, i32:$rs2, i32:$swap))]>; 959263764Sdim 960193323Sed//===----------------------------------------------------------------------===// 961193323Sed// Non-Instruction Patterns 962193323Sed//===----------------------------------------------------------------------===// 963193323Sed 964193323Sed// Small immediates. 965193323Seddef : Pat<(i32 simm13:$val), 966252723Sdim (ORri (i32 G0), imm:$val)>; 967193323Sed// Arbitrary immediates. 968193323Seddef : Pat<(i32 imm:$val), 969193323Sed (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>; 970193323Sed 971193323Sed 972193323Sed// Global addresses, constant pool entries 973263764Sdimlet Predicates = [Is32Bit] in { 974263764Sdim 975193323Seddef : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; 976252723Sdimdef : Pat<(SPlo tglobaladdr:$in), (ORri (i32 G0), tglobaladdr:$in)>; 977193323Seddef : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>; 978252723Sdimdef : Pat<(SPlo tconstpool:$in), (ORri (i32 G0), tconstpool:$in)>; 979193323Sed 980263509Sdim// GlobalTLS addresses 981263509Sdimdef : Pat<(SPhi tglobaltlsaddr:$in), (SETHIi tglobaltlsaddr:$in)>; 982263509Sdimdef : Pat<(SPlo tglobaltlsaddr:$in), (ORri (i32 G0), tglobaltlsaddr:$in)>; 983263509Sdimdef : Pat<(add (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), 984263509Sdim (ADDri (SETHIi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; 985263509Sdimdef : Pat<(xor (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), 986263509Sdim (XORri (SETHIi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; 987263509Sdim 988263509Sdim// Blockaddress 989263509Sdimdef : Pat<(SPhi tblockaddress:$in), (SETHIi tblockaddress:$in)>; 990263509Sdimdef : Pat<(SPlo tblockaddress:$in), (ORri (i32 G0), tblockaddress:$in)>; 991263509Sdim 992193323Sed// Add reg, lo. This is used when taking the addr of a global/constpool entry. 993252723Sdimdef : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (ADDri $r, tglobaladdr:$in)>; 994252723Sdimdef : Pat<(add iPTR:$r, (SPlo tconstpool:$in)), (ADDri $r, tconstpool:$in)>; 995263509Sdimdef : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)), 996263509Sdim (ADDri $r, tblockaddress:$in)>; 997263764Sdim} 998193323Sed 999263509Sdim// Calls: 1000193323Seddef : Pat<(call tglobaladdr:$dst), 1001193323Sed (CALL tglobaladdr:$dst)>; 1002193323Seddef : Pat<(call texternalsym:$dst), 1003193323Sed (CALL texternalsym:$dst)>; 1004193323Sed 1005193323Sed// Map integer extload's to zextloads. 1006193323Seddef : Pat<(i32 (extloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1007193323Seddef : Pat<(i32 (extloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1008193323Seddef : Pat<(i32 (extloadi8 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1009193323Seddef : Pat<(i32 (extloadi8 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1010193323Seddef : Pat<(i32 (extloadi16 ADDRrr:$src)), (LDUHrr ADDRrr:$src)>; 1011193323Seddef : Pat<(i32 (extloadi16 ADDRri:$src)), (LDUHri ADDRri:$src)>; 1012193323Sed 1013193323Sed// zextload bool -> zextload byte 1014193323Seddef : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; 1015193323Seddef : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; 1016252723Sdim 1017263509Sdim// store 0, addr -> store %g0, addr 1018263509Sdimdef : Pat<(store (i32 0), ADDRrr:$dst), (STrr ADDRrr:$dst, (i32 G0))>; 1019263509Sdimdef : Pat<(store (i32 0), ADDRri:$dst), (STri ADDRri:$dst, (i32 G0))>; 1020263509Sdim 1021263764Sdim// store bar for all atomic_fence in V8. 1022263764Sdimlet Predicates = [HasNoV9] in 1023263764Sdim def : Pat<(atomic_fence imm, imm), (STBAR)>; 1024263764Sdim 1025263764Sdim// atomic_load_32 addr -> load addr 1026263764Sdimdef : Pat<(i32 (atomic_load ADDRrr:$src)), (LDrr ADDRrr:$src)>; 1027263764Sdimdef : Pat<(i32 (atomic_load ADDRri:$src)), (LDri ADDRri:$src)>; 1028263764Sdim 1029263764Sdim// atomic_store_32 val, addr -> store val, addr 1030263764Sdimdef : Pat<(atomic_store ADDRrr:$dst, i32:$val), (STrr ADDRrr:$dst, $val)>; 1031263764Sdimdef : Pat<(atomic_store ADDRri:$dst, i32:$val), (STri ADDRri:$dst, $val)>; 1032263764Sdim 1033263764Sdim 1034252723Sdiminclude "SparcInstr64Bit.td" 1035263764Sdiminclude "SparcInstrAliases.td" 1036