PPCInstrInfo.td revision 239462
1//===-- PPCInstrInfo.td - The PowerPC Instruction Set ------*- tablegen -*-===// 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 subset of the 32-bit PowerPC instruction set, as used 11// by the PowerPC instruction selector. 12// 13//===----------------------------------------------------------------------===// 14 15include "PPCInstrFormats.td" 16 17//===----------------------------------------------------------------------===// 18// PowerPC specific type constraints. 19// 20def SDT_PPCstfiwx : SDTypeProfile<0, 2, [ // stfiwx 21 SDTCisVT<0, f64>, SDTCisPtrTy<1> 22]>; 23def SDT_PPCCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 24def SDT_PPCCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 25 SDTCisVT<1, i32> ]>; 26def SDT_PPCvperm : SDTypeProfile<1, 3, [ 27 SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2> 28]>; 29 30def SDT_PPCvcmp : SDTypeProfile<1, 3, [ 31 SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32> 32]>; 33 34def SDT_PPCcondbr : SDTypeProfile<0, 3, [ 35 SDTCisVT<0, i32>, SDTCisVT<2, OtherVT> 36]>; 37 38def SDT_PPClbrx : SDTypeProfile<1, 2, [ 39 SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT> 40]>; 41def SDT_PPCstbrx : SDTypeProfile<0, 3, [ 42 SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT> 43]>; 44 45def SDT_PPClarx : SDTypeProfile<1, 1, [ 46 SDTCisInt<0>, SDTCisPtrTy<1> 47]>; 48def SDT_PPCstcx : SDTypeProfile<0, 2, [ 49 SDTCisInt<0>, SDTCisPtrTy<1> 50]>; 51 52def SDT_PPCTC_ret : SDTypeProfile<0, 2, [ 53 SDTCisPtrTy<0>, SDTCisVT<1, i32> 54]>; 55 56def SDT_PPCnop : SDTypeProfile<0, 0, []>; 57 58//===----------------------------------------------------------------------===// 59// PowerPC specific DAG Nodes. 60// 61 62def PPCfcfid : SDNode<"PPCISD::FCFID" , SDTFPUnaryOp, []>; 63def PPCfctidz : SDNode<"PPCISD::FCTIDZ", SDTFPUnaryOp, []>; 64def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>; 65def PPCstfiwx : SDNode<"PPCISD::STFIWX", SDT_PPCstfiwx, 66 [SDNPHasChain, SDNPMayStore]>; 67 68// This sequence is used for long double->int conversions. It changes the 69// bits in the FPSCR which is not modelled. 70def PPCmffs : SDNode<"PPCISD::MFFS", SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>, 71 [SDNPOutGlue]>; 72def PPCmtfsb0 : SDNode<"PPCISD::MTFSB0", SDTypeProfile<0, 1, [SDTCisInt<0>]>, 73 [SDNPInGlue, SDNPOutGlue]>; 74def PPCmtfsb1 : SDNode<"PPCISD::MTFSB1", SDTypeProfile<0, 1, [SDTCisInt<0>]>, 75 [SDNPInGlue, SDNPOutGlue]>; 76def PPCfaddrtz: SDNode<"PPCISD::FADDRTZ", SDTFPBinOp, 77 [SDNPInGlue, SDNPOutGlue]>; 78def PPCmtfsf : SDNode<"PPCISD::MTFSF", SDTypeProfile<1, 3, 79 [SDTCisVT<0, f64>, SDTCisInt<1>, SDTCisVT<2, f64>, 80 SDTCisVT<3, f64>]>, 81 [SDNPInGlue]>; 82 83def PPCfsel : SDNode<"PPCISD::FSEL", 84 // Type constraint for fsel. 85 SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, 86 SDTCisFP<0>, SDTCisVT<1, f64>]>, []>; 87 88def PPChi : SDNode<"PPCISD::Hi", SDTIntBinOp, []>; 89def PPClo : SDNode<"PPCISD::Lo", SDTIntBinOp, []>; 90def PPCtoc_entry: SDNode<"PPCISD::TOC_ENTRY", SDTIntBinOp, [SDNPMayLoad]>; 91def PPCvmaddfp : SDNode<"PPCISD::VMADDFP", SDTFPTernaryOp, []>; 92def PPCvnmsubfp : SDNode<"PPCISD::VNMSUBFP", SDTFPTernaryOp, []>; 93 94def PPCvperm : SDNode<"PPCISD::VPERM", SDT_PPCvperm, []>; 95 96// These nodes represent the 32-bit PPC shifts that operate on 6-bit shift 97// amounts. These nodes are generated by the multi-precision shift code. 98def PPCsrl : SDNode<"PPCISD::SRL" , SDTIntShiftOp>; 99def PPCsra : SDNode<"PPCISD::SRA" , SDTIntShiftOp>; 100def PPCshl : SDNode<"PPCISD::SHL" , SDTIntShiftOp>; 101 102def PPCextsw_32 : SDNode<"PPCISD::EXTSW_32" , SDTIntUnaryOp>; 103def PPCstd_32 : SDNode<"PPCISD::STD_32" , SDTStore, 104 [SDNPHasChain, SDNPMayStore]>; 105 106// These are target-independent nodes, but have target-specific formats. 107def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeqStart, 108 [SDNPHasChain, SDNPOutGlue]>; 109def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeqEnd, 110 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 111 112def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; 113def PPCcall_Darwin : SDNode<"PPCISD::CALL_Darwin", SDT_PPCCall, 114 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 115 SDNPVariadic]>; 116def PPCcall_SVR4 : SDNode<"PPCISD::CALL_SVR4", SDT_PPCCall, 117 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 118 SDNPVariadic]>; 119def PPCcall_nop_SVR4 : SDNode<"PPCISD::CALL_NOP_SVR4", SDT_PPCCall, 120 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 121 SDNPVariadic]>; 122def PPCnop : SDNode<"PPCISD::NOP", SDT_PPCnop, [SDNPInGlue, SDNPOutGlue]>; 123def PPCload : SDNode<"PPCISD::LOAD", SDTypeProfile<1, 1, []>, 124 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 125def PPCload_toc : SDNode<"PPCISD::LOAD_TOC", SDTypeProfile<0, 1, []>, 126 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; 127def PPCtoc_restore : SDNode<"PPCISD::TOC_RESTORE", SDTypeProfile<0, 0, []>, 128 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; 129def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall, 130 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 131def PPCbctrl_Darwin : SDNode<"PPCISD::BCTRL_Darwin", SDTNone, 132 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 133 SDNPVariadic]>; 134 135def PPCbctrl_SVR4 : SDNode<"PPCISD::BCTRL_SVR4", SDTNone, 136 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 137 SDNPVariadic]>; 138 139def retflag : SDNode<"PPCISD::RET_FLAG", SDTNone, 140 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 141 142def PPCtc_return : SDNode<"PPCISD::TC_RETURN", SDT_PPCTC_ret, 143 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 144 145def PPCvcmp : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>; 146def PPCvcmp_o : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp, [SDNPOutGlue]>; 147 148def PPCcondbranch : SDNode<"PPCISD::COND_BRANCH", SDT_PPCcondbr, 149 [SDNPHasChain, SDNPOptInGlue]>; 150 151def PPClbrx : SDNode<"PPCISD::LBRX", SDT_PPClbrx, 152 [SDNPHasChain, SDNPMayLoad]>; 153def PPCstbrx : SDNode<"PPCISD::STBRX", SDT_PPCstbrx, 154 [SDNPHasChain, SDNPMayStore]>; 155 156// Instructions to support atomic operations 157def PPClarx : SDNode<"PPCISD::LARX", SDT_PPClarx, 158 [SDNPHasChain, SDNPMayLoad]>; 159def PPCstcx : SDNode<"PPCISD::STCX", SDT_PPCstcx, 160 [SDNPHasChain, SDNPMayStore]>; 161 162// Instructions to support dynamic alloca. 163def SDTDynOp : SDTypeProfile<1, 2, []>; 164def PPCdynalloc : SDNode<"PPCISD::DYNALLOC", SDTDynOp, [SDNPHasChain]>; 165 166//===----------------------------------------------------------------------===// 167// PowerPC specific transformation functions and pattern fragments. 168// 169 170def SHL32 : SDNodeXForm<imm, [{ 171 // Transformation function: 31 - imm 172 return getI32Imm(31 - N->getZExtValue()); 173}]>; 174 175def SRL32 : SDNodeXForm<imm, [{ 176 // Transformation function: 32 - imm 177 return N->getZExtValue() ? getI32Imm(32 - N->getZExtValue()) : getI32Imm(0); 178}]>; 179 180def LO16 : SDNodeXForm<imm, [{ 181 // Transformation function: get the low 16 bits. 182 return getI32Imm((unsigned short)N->getZExtValue()); 183}]>; 184 185def HI16 : SDNodeXForm<imm, [{ 186 // Transformation function: shift the immediate value down into the low bits. 187 return getI32Imm((unsigned)N->getZExtValue() >> 16); 188}]>; 189 190def HA16 : SDNodeXForm<imm, [{ 191 // Transformation function: shift the immediate value down into the low bits. 192 signed int Val = N->getZExtValue(); 193 return getI32Imm((Val - (signed short)Val) >> 16); 194}]>; 195def MB : SDNodeXForm<imm, [{ 196 // Transformation function: get the start bit of a mask 197 unsigned mb = 0, me; 198 (void)isRunOfOnes((unsigned)N->getZExtValue(), mb, me); 199 return getI32Imm(mb); 200}]>; 201 202def ME : SDNodeXForm<imm, [{ 203 // Transformation function: get the end bit of a mask 204 unsigned mb, me = 0; 205 (void)isRunOfOnes((unsigned)N->getZExtValue(), mb, me); 206 return getI32Imm(me); 207}]>; 208def maskimm32 : PatLeaf<(imm), [{ 209 // maskImm predicate - True if immediate is a run of ones. 210 unsigned mb, me; 211 if (N->getValueType(0) == MVT::i32) 212 return isRunOfOnes((unsigned)N->getZExtValue(), mb, me); 213 else 214 return false; 215}]>; 216 217def immSExt16 : PatLeaf<(imm), [{ 218 // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended 219 // field. Used by instructions like 'addi'. 220 if (N->getValueType(0) == MVT::i32) 221 return (int32_t)N->getZExtValue() == (short)N->getZExtValue(); 222 else 223 return (int64_t)N->getZExtValue() == (short)N->getZExtValue(); 224}]>; 225def immZExt16 : PatLeaf<(imm), [{ 226 // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended 227 // field. Used by instructions like 'ori'. 228 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue(); 229}], LO16>; 230 231// imm16Shifted* - These match immediates where the low 16-bits are zero. There 232// are two forms: imm16ShiftedSExt and imm16ShiftedZExt. These two forms are 233// identical in 32-bit mode, but in 64-bit mode, they return true if the 234// immediate fits into a sign/zero extended 32-bit immediate (with the low bits 235// clear). 236def imm16ShiftedZExt : PatLeaf<(imm), [{ 237 // imm16ShiftedZExt predicate - True if only bits in the top 16-bits of the 238 // immediate are set. Used by instructions like 'xoris'. 239 return (N->getZExtValue() & ~uint64_t(0xFFFF0000)) == 0; 240}], HI16>; 241 242def imm16ShiftedSExt : PatLeaf<(imm), [{ 243 // imm16ShiftedSExt predicate - True if only bits in the top 16-bits of the 244 // immediate are set. Used by instructions like 'addis'. Identical to 245 // imm16ShiftedZExt in 32-bit mode. 246 if (N->getZExtValue() & 0xFFFF) return false; 247 if (N->getValueType(0) == MVT::i32) 248 return true; 249 // For 64-bit, make sure it is sext right. 250 return N->getZExtValue() == (uint64_t)(int)N->getZExtValue(); 251}], HI16>; 252 253 254//===----------------------------------------------------------------------===// 255// PowerPC Flag Definitions. 256 257class isPPC64 { bit PPC64 = 1; } 258class isDOT { 259 list<Register> Defs = [CR0]; 260 bit RC = 1; 261} 262 263class RegConstraint<string C> { 264 string Constraints = C; 265} 266class NoEncode<string E> { 267 string DisableEncoding = E; 268} 269 270 271//===----------------------------------------------------------------------===// 272// PowerPC Operand Definitions. 273 274def s5imm : Operand<i32> { 275 let PrintMethod = "printS5ImmOperand"; 276} 277def u5imm : Operand<i32> { 278 let PrintMethod = "printU5ImmOperand"; 279} 280def u6imm : Operand<i32> { 281 let PrintMethod = "printU6ImmOperand"; 282} 283def s16imm : Operand<i32> { 284 let PrintMethod = "printS16ImmOperand"; 285} 286def u16imm : Operand<i32> { 287 let PrintMethod = "printU16ImmOperand"; 288} 289def s16immX4 : Operand<i32> { // Multiply imm by 4 before printing. 290 let PrintMethod = "printS16X4ImmOperand"; 291} 292def directbrtarget : Operand<OtherVT> { 293 let PrintMethod = "printBranchOperand"; 294 let EncoderMethod = "getDirectBrEncoding"; 295} 296def condbrtarget : Operand<OtherVT> { 297 let PrintMethod = "printBranchOperand"; 298 let EncoderMethod = "getCondBrEncoding"; 299} 300def calltarget : Operand<iPTR> { 301 let EncoderMethod = "getDirectBrEncoding"; 302} 303def aaddr : Operand<iPTR> { 304 let PrintMethod = "printAbsAddrOperand"; 305} 306def symbolHi: Operand<i32> { 307 let PrintMethod = "printSymbolHi"; 308 let EncoderMethod = "getHA16Encoding"; 309} 310def symbolLo: Operand<i32> { 311 let PrintMethod = "printSymbolLo"; 312 let EncoderMethod = "getLO16Encoding"; 313} 314def crbitm: Operand<i8> { 315 let PrintMethod = "printcrbitm"; 316 let EncoderMethod = "get_crbitm_encoding"; 317} 318// Address operands 319def memri : Operand<iPTR> { 320 let PrintMethod = "printMemRegImm"; 321 let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg); 322 let EncoderMethod = "getMemRIEncoding"; 323} 324def memrr : Operand<iPTR> { 325 let PrintMethod = "printMemRegReg"; 326 let MIOperandInfo = (ops ptr_rc:$offreg, ptr_rc:$ptrreg); 327} 328def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits. 329 let PrintMethod = "printMemRegImmShifted"; 330 let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg); 331 let EncoderMethod = "getMemRIXEncoding"; 332} 333def tocentry : Operand<iPTR> { 334 let MIOperandInfo = (ops i32imm:$imm); 335} 336 337// PowerPC Predicate operand. 20 = (0<<5)|20 = always, CR0 is a dummy reg 338// that doesn't matter. 339def pred : PredicateOperand<OtherVT, (ops imm, CRRC), 340 (ops (i32 20), (i32 zero_reg))> { 341 let PrintMethod = "printPredicateOperand"; 342} 343 344// Define PowerPC specific addressing mode. 345def iaddr : ComplexPattern<iPTR, 2, "SelectAddrImm", [], []>; 346def xaddr : ComplexPattern<iPTR, 2, "SelectAddrIdx", [], []>; 347def xoaddr : ComplexPattern<iPTR, 2, "SelectAddrIdxOnly",[], []>; 348def ixaddr : ComplexPattern<iPTR, 2, "SelectAddrImmShift", [], []>; // "std" 349 350/// This is just the offset part of iaddr, used for preinc. 351def iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>; 352def xaddroff : ComplexPattern<iPTR, 1, "SelectAddrIdxOffs", [], []>; 353 354//===----------------------------------------------------------------------===// 355// PowerPC Instruction Predicate Definitions. 356def In32BitMode : Predicate<"!PPCSubTarget.isPPC64()">; 357def In64BitMode : Predicate<"PPCSubTarget.isPPC64()">; 358def IsBookE : Predicate<"PPCSubTarget.isBookE()">; 359 360//===----------------------------------------------------------------------===// 361// PowerPC Instruction Definitions. 362 363// Pseudo-instructions: 364 365let hasCtrlDep = 1 in { 366let Defs = [R1], Uses = [R1] in { 367def ADJCALLSTACKDOWN : Pseudo<(outs), (ins u16imm:$amt), "", 368 [(callseq_start timm:$amt)]>; 369def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2), "", 370 [(callseq_end timm:$amt1, timm:$amt2)]>; 371} 372 373def UPDATE_VRSAVE : Pseudo<(outs GPRC:$rD), (ins GPRC:$rS), 374 "UPDATE_VRSAVE $rD, $rS", []>; 375} 376 377let Defs = [R1], Uses = [R1] in 378def DYNALLOC : Pseudo<(outs GPRC:$result), (ins GPRC:$negsize, memri:$fpsi), "", 379 [(set GPRC:$result, 380 (PPCdynalloc GPRC:$negsize, iaddr:$fpsi))]>; 381 382// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 383// instruction selection into a branch sequence. 384let usesCustomInserter = 1, // Expanded after instruction selection. 385 PPC970_Single = 1 in { 386 def SELECT_CC_I4 : Pseudo<(outs GPRC:$dst), (ins CRRC:$cond, GPRC:$T, GPRC:$F, 387 i32imm:$BROPC), "", 388 []>; 389 def SELECT_CC_I8 : Pseudo<(outs G8RC:$dst), (ins CRRC:$cond, G8RC:$T, G8RC:$F, 390 i32imm:$BROPC), "", 391 []>; 392 def SELECT_CC_F4 : Pseudo<(outs F4RC:$dst), (ins CRRC:$cond, F4RC:$T, F4RC:$F, 393 i32imm:$BROPC), "", 394 []>; 395 def SELECT_CC_F8 : Pseudo<(outs F8RC:$dst), (ins CRRC:$cond, F8RC:$T, F8RC:$F, 396 i32imm:$BROPC), "", 397 []>; 398 def SELECT_CC_VRRC: Pseudo<(outs VRRC:$dst), (ins CRRC:$cond, VRRC:$T, VRRC:$F, 399 i32imm:$BROPC), "", 400 []>; 401} 402 403// SPILL_CR - Indicate that we're dumping the CR register, so we'll need to 404// scavenge a register for it. 405let mayStore = 1 in 406def SPILL_CR : Pseudo<(outs), (ins CRRC:$cond, memri:$F), 407 "", []>; 408 409// RESTORE_CR - Indicate that we're restoring the CR register (previously 410// spilled), so we'll need to scavenge a register for it. 411let mayLoad = 1 in 412def RESTORE_CR : Pseudo<(outs CRRC:$cond), (ins memri:$F), 413 "", []>; 414 415let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in { 416 let isReturn = 1, Uses = [LR, RM] in 417 def BLR : XLForm_2_br<19, 16, 0, (outs), (ins pred:$p), 418 "b${p:cc}lr ${p:reg}", BrB, 419 [(retflag)]>; 420 let isBranch = 1, isIndirectBranch = 1, Uses = [CTR] in 421 def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>; 422} 423 424let Defs = [LR] in 425 def MovePCtoLR : Pseudo<(outs), (ins), "", []>, 426 PPC970_Unit_BRU; 427 428let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in { 429 let isBarrier = 1 in { 430 def B : IForm<18, 0, 0, (outs), (ins directbrtarget:$dst), 431 "b $dst", BrB, 432 [(br bb:$dst)]>; 433 } 434 435 // BCC represents an arbitrary conditional branch on a predicate. 436 // FIXME: should be able to write a pattern for PPCcondbranch, but can't use 437 // a two-value operand where a dag node expects two operands. :( 438 def BCC : BForm<16, 0, 0, (outs), (ins pred:$cond, condbrtarget:$dst), 439 "b${cond:cc} ${cond:reg}, $dst" 440 /*[(PPCcondbranch CRRC:$crS, imm:$opc, bb:$dst)]*/>; 441 442 let Defs = [CTR], Uses = [CTR] in { 443 def BDZ : IForm_ext<16, 18, 0, 0, (outs), (ins condbrtarget:$dst), 444 "bdz $dst", BrB, []>; 445 def BDNZ : IForm_ext<16, 16, 0, 0, (outs), (ins condbrtarget:$dst), 446 "bdnz $dst", BrB, []>; 447 } 448} 449 450// Darwin ABI Calls. 451let isCall = 1, PPC970_Unit = 7, Defs = [LR] in { 452 // Convenient aliases for call instructions 453 let Uses = [RM] in { 454 def BL_Darwin : IForm<18, 0, 1, 455 (outs), (ins calltarget:$func), 456 "bl $func", BrB, []>; // See Pat patterns below. 457 def BLA_Darwin : IForm<18, 1, 1, 458 (outs), (ins aaddr:$func), 459 "bla $func", BrB, [(PPCcall_Darwin (i32 imm:$func))]>; 460 } 461 let Uses = [CTR, RM] in { 462 def BCTRL_Darwin : XLForm_2_ext<19, 528, 20, 0, 1, 463 (outs), (ins), 464 "bctrl", BrB, 465 [(PPCbctrl_Darwin)]>, Requires<[In32BitMode]>; 466 } 467} 468 469// SVR4 ABI Calls. 470let isCall = 1, PPC970_Unit = 7, Defs = [LR] in { 471 // Convenient aliases for call instructions 472 let Uses = [RM] in { 473 def BL_SVR4 : IForm<18, 0, 1, 474 (outs), (ins calltarget:$func), 475 "bl $func", BrB, []>; // See Pat patterns below. 476 def BLA_SVR4 : IForm<18, 1, 1, 477 (outs), (ins aaddr:$func), 478 "bla $func", BrB, 479 [(PPCcall_SVR4 (i32 imm:$func))]>; 480 } 481 let Uses = [CTR, RM] in { 482 def BCTRL_SVR4 : XLForm_2_ext<19, 528, 20, 0, 1, 483 (outs), (ins), 484 "bctrl", BrB, 485 [(PPCbctrl_SVR4)]>, Requires<[In32BitMode]>; 486 } 487} 488 489 490let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in 491def TCRETURNdi :Pseudo< (outs), 492 (ins calltarget:$dst, i32imm:$offset), 493 "#TC_RETURNd $dst $offset", 494 []>; 495 496 497let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in 498def TCRETURNai :Pseudo<(outs), (ins aaddr:$func, i32imm:$offset), 499 "#TC_RETURNa $func $offset", 500 [(PPCtc_return (i32 imm:$func), imm:$offset)]>; 501 502let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in 503def TCRETURNri : Pseudo<(outs), (ins CTRRC:$dst, i32imm:$offset), 504 "#TC_RETURNr $dst $offset", 505 []>; 506 507 508let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, isBranch = 1, 509 isIndirectBranch = 1, isCall = 1, isReturn = 1, Uses = [CTR, RM] in 510def TAILBCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>, 511 Requires<[In32BitMode]>; 512 513 514 515let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7, 516 isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in 517def TAILB : IForm<18, 0, 0, (outs), (ins calltarget:$dst), 518 "b $dst", BrB, 519 []>; 520 521 522let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7, 523 isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in 524def TAILBA : IForm<18, 0, 0, (outs), (ins aaddr:$dst), 525 "ba $dst", BrB, 526 []>; 527 528 529// DCB* instructions. 530def DCBA : DCB_Form<758, 0, (outs), (ins memrr:$dst), 531 "dcba $dst", LdStDCBF, [(int_ppc_dcba xoaddr:$dst)]>, 532 PPC970_DGroup_Single; 533def DCBF : DCB_Form<86, 0, (outs), (ins memrr:$dst), 534 "dcbf $dst", LdStDCBF, [(int_ppc_dcbf xoaddr:$dst)]>, 535 PPC970_DGroup_Single; 536def DCBI : DCB_Form<470, 0, (outs), (ins memrr:$dst), 537 "dcbi $dst", LdStDCBF, [(int_ppc_dcbi xoaddr:$dst)]>, 538 PPC970_DGroup_Single; 539def DCBST : DCB_Form<54, 0, (outs), (ins memrr:$dst), 540 "dcbst $dst", LdStDCBF, [(int_ppc_dcbst xoaddr:$dst)]>, 541 PPC970_DGroup_Single; 542def DCBT : DCB_Form<278, 0, (outs), (ins memrr:$dst), 543 "dcbt $dst", LdStDCBF, [(int_ppc_dcbt xoaddr:$dst)]>, 544 PPC970_DGroup_Single; 545def DCBTST : DCB_Form<246, 0, (outs), (ins memrr:$dst), 546 "dcbtst $dst", LdStDCBF, [(int_ppc_dcbtst xoaddr:$dst)]>, 547 PPC970_DGroup_Single; 548def DCBZ : DCB_Form<1014, 0, (outs), (ins memrr:$dst), 549 "dcbz $dst", LdStDCBF, [(int_ppc_dcbz xoaddr:$dst)]>, 550 PPC970_DGroup_Single; 551def DCBZL : DCB_Form<1014, 1, (outs), (ins memrr:$dst), 552 "dcbzl $dst", LdStDCBF, [(int_ppc_dcbzl xoaddr:$dst)]>, 553 PPC970_DGroup_Single; 554 555def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 1)), 556 (DCBT xoaddr:$dst)>; 557 558// Atomic operations 559let usesCustomInserter = 1 in { 560 let Defs = [CR0] in { 561 def ATOMIC_LOAD_ADD_I8 : Pseudo< 562 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 563 [(set GPRC:$dst, (atomic_load_add_8 xoaddr:$ptr, GPRC:$incr))]>; 564 def ATOMIC_LOAD_SUB_I8 : Pseudo< 565 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 566 [(set GPRC:$dst, (atomic_load_sub_8 xoaddr:$ptr, GPRC:$incr))]>; 567 def ATOMIC_LOAD_AND_I8 : Pseudo< 568 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 569 [(set GPRC:$dst, (atomic_load_and_8 xoaddr:$ptr, GPRC:$incr))]>; 570 def ATOMIC_LOAD_OR_I8 : Pseudo< 571 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 572 [(set GPRC:$dst, (atomic_load_or_8 xoaddr:$ptr, GPRC:$incr))]>; 573 def ATOMIC_LOAD_XOR_I8 : Pseudo< 574 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 575 [(set GPRC:$dst, (atomic_load_xor_8 xoaddr:$ptr, GPRC:$incr))]>; 576 def ATOMIC_LOAD_NAND_I8 : Pseudo< 577 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 578 [(set GPRC:$dst, (atomic_load_nand_8 xoaddr:$ptr, GPRC:$incr))]>; 579 def ATOMIC_LOAD_ADD_I16 : Pseudo< 580 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 581 [(set GPRC:$dst, (atomic_load_add_16 xoaddr:$ptr, GPRC:$incr))]>; 582 def ATOMIC_LOAD_SUB_I16 : Pseudo< 583 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 584 [(set GPRC:$dst, (atomic_load_sub_16 xoaddr:$ptr, GPRC:$incr))]>; 585 def ATOMIC_LOAD_AND_I16 : Pseudo< 586 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 587 [(set GPRC:$dst, (atomic_load_and_16 xoaddr:$ptr, GPRC:$incr))]>; 588 def ATOMIC_LOAD_OR_I16 : Pseudo< 589 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 590 [(set GPRC:$dst, (atomic_load_or_16 xoaddr:$ptr, GPRC:$incr))]>; 591 def ATOMIC_LOAD_XOR_I16 : Pseudo< 592 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 593 [(set GPRC:$dst, (atomic_load_xor_16 xoaddr:$ptr, GPRC:$incr))]>; 594 def ATOMIC_LOAD_NAND_I16 : Pseudo< 595 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 596 [(set GPRC:$dst, (atomic_load_nand_16 xoaddr:$ptr, GPRC:$incr))]>; 597 def ATOMIC_LOAD_ADD_I32 : Pseudo< 598 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 599 [(set GPRC:$dst, (atomic_load_add_32 xoaddr:$ptr, GPRC:$incr))]>; 600 def ATOMIC_LOAD_SUB_I32 : Pseudo< 601 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 602 [(set GPRC:$dst, (atomic_load_sub_32 xoaddr:$ptr, GPRC:$incr))]>; 603 def ATOMIC_LOAD_AND_I32 : Pseudo< 604 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 605 [(set GPRC:$dst, (atomic_load_and_32 xoaddr:$ptr, GPRC:$incr))]>; 606 def ATOMIC_LOAD_OR_I32 : Pseudo< 607 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 608 [(set GPRC:$dst, (atomic_load_or_32 xoaddr:$ptr, GPRC:$incr))]>; 609 def ATOMIC_LOAD_XOR_I32 : Pseudo< 610 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 611 [(set GPRC:$dst, (atomic_load_xor_32 xoaddr:$ptr, GPRC:$incr))]>; 612 def ATOMIC_LOAD_NAND_I32 : Pseudo< 613 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "", 614 [(set GPRC:$dst, (atomic_load_nand_32 xoaddr:$ptr, GPRC:$incr))]>; 615 616 def ATOMIC_CMP_SWAP_I8 : Pseudo< 617 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "", 618 [(set GPRC:$dst, 619 (atomic_cmp_swap_8 xoaddr:$ptr, GPRC:$old, GPRC:$new))]>; 620 def ATOMIC_CMP_SWAP_I16 : Pseudo< 621 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "", 622 [(set GPRC:$dst, 623 (atomic_cmp_swap_16 xoaddr:$ptr, GPRC:$old, GPRC:$new))]>; 624 def ATOMIC_CMP_SWAP_I32 : Pseudo< 625 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "", 626 [(set GPRC:$dst, 627 (atomic_cmp_swap_32 xoaddr:$ptr, GPRC:$old, GPRC:$new))]>; 628 629 def ATOMIC_SWAP_I8 : Pseudo< 630 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "", 631 [(set GPRC:$dst, (atomic_swap_8 xoaddr:$ptr, GPRC:$new))]>; 632 def ATOMIC_SWAP_I16 : Pseudo< 633 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "", 634 [(set GPRC:$dst, (atomic_swap_16 xoaddr:$ptr, GPRC:$new))]>; 635 def ATOMIC_SWAP_I32 : Pseudo< 636 (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "", 637 [(set GPRC:$dst, (atomic_swap_32 xoaddr:$ptr, GPRC:$new))]>; 638 } 639} 640 641// Instructions to support atomic operations 642def LWARX : XForm_1<31, 20, (outs GPRC:$rD), (ins memrr:$src), 643 "lwarx $rD, $src", LdStLWARX, 644 [(set GPRC:$rD, (PPClarx xoaddr:$src))]>; 645 646let Defs = [CR0] in 647def STWCX : XForm_1<31, 150, (outs), (ins GPRC:$rS, memrr:$dst), 648 "stwcx. $rS, $dst", LdStSTWCX, 649 [(PPCstcx GPRC:$rS, xoaddr:$dst)]>, 650 isDOT; 651 652let isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in 653def TRAP : XForm_24<31, 4, (outs), (ins), "trap", LdStLoad, [(trap)]>; 654 655//===----------------------------------------------------------------------===// 656// PPC32 Load Instructions. 657// 658 659// Unindexed (r+i) Loads. 660let canFoldAsLoad = 1, PPC970_Unit = 2 in { 661def LBZ : DForm_1<34, (outs GPRC:$rD), (ins memri:$src), 662 "lbz $rD, $src", LdStLoad, 663 [(set GPRC:$rD, (zextloadi8 iaddr:$src))]>; 664def LHA : DForm_1<42, (outs GPRC:$rD), (ins memri:$src), 665 "lha $rD, $src", LdStLHA, 666 [(set GPRC:$rD, (sextloadi16 iaddr:$src))]>, 667 PPC970_DGroup_Cracked; 668def LHZ : DForm_1<40, (outs GPRC:$rD), (ins memri:$src), 669 "lhz $rD, $src", LdStLoad, 670 [(set GPRC:$rD, (zextloadi16 iaddr:$src))]>; 671def LWZ : DForm_1<32, (outs GPRC:$rD), (ins memri:$src), 672 "lwz $rD, $src", LdStLoad, 673 [(set GPRC:$rD, (load iaddr:$src))]>; 674 675def LFS : DForm_1<48, (outs F4RC:$rD), (ins memri:$src), 676 "lfs $rD, $src", LdStLFDU, 677 [(set F4RC:$rD, (load iaddr:$src))]>; 678def LFD : DForm_1<50, (outs F8RC:$rD), (ins memri:$src), 679 "lfd $rD, $src", LdStLFD, 680 [(set F8RC:$rD, (load iaddr:$src))]>; 681 682 683// Unindexed (r+i) Loads with Update (preinc). 684let mayLoad = 1 in { 685def LBZU : DForm_1<35, (outs GPRC:$rD, ptr_rc:$ea_result), (ins memri:$addr), 686 "lbzu $rD, $addr", LdStLoad, 687 []>, RegConstraint<"$addr.reg = $ea_result">, 688 NoEncode<"$ea_result">; 689 690def LHAU : DForm_1<43, (outs GPRC:$rD, ptr_rc:$ea_result), (ins memri:$addr), 691 "lhau $rD, $addr", LdStLoad, 692 []>, RegConstraint<"$addr.reg = $ea_result">, 693 NoEncode<"$ea_result">; 694 695def LHZU : DForm_1<41, (outs GPRC:$rD, ptr_rc:$ea_result), (ins memri:$addr), 696 "lhzu $rD, $addr", LdStLoad, 697 []>, RegConstraint<"$addr.reg = $ea_result">, 698 NoEncode<"$ea_result">; 699 700def LWZU : DForm_1<33, (outs GPRC:$rD, ptr_rc:$ea_result), (ins memri:$addr), 701 "lwzu $rD, $addr", LdStLoad, 702 []>, RegConstraint<"$addr.reg = $ea_result">, 703 NoEncode<"$ea_result">; 704 705def LFSU : DForm_1<49, (outs F4RC:$rD, ptr_rc:$ea_result), (ins memri:$addr), 706 "lfs $rD, $addr", LdStLFDU, 707 []>, RegConstraint<"$addr.reg = $ea_result">, 708 NoEncode<"$ea_result">; 709 710def LFDU : DForm_1<51, (outs F8RC:$rD, ptr_rc:$ea_result), (ins memri:$addr), 711 "lfd $rD, $addr", LdStLFD, 712 []>, RegConstraint<"$addr.reg = $ea_result">, 713 NoEncode<"$ea_result">; 714 715 716// Indexed (r+r) Loads with Update (preinc). 717def LBZUX : XForm_1<31, 119, (outs GPRC:$rD, ptr_rc:$ea_result), 718 (ins memrr:$addr), 719 "lbzux $rD, $addr", LdStLoad, 720 []>, RegConstraint<"$addr.offreg = $ea_result">, 721 NoEncode<"$ea_result">; 722 723def LHAUX : XForm_1<31, 375, (outs GPRC:$rD, ptr_rc:$ea_result), 724 (ins memrr:$addr), 725 "lhaux $rD, $addr", LdStLoad, 726 []>, RegConstraint<"$addr.offreg = $ea_result">, 727 NoEncode<"$ea_result">; 728 729def LHZUX : XForm_1<31, 331, (outs GPRC:$rD, ptr_rc:$ea_result), 730 (ins memrr:$addr), 731 "lhzux $rD, $addr", LdStLoad, 732 []>, RegConstraint<"$addr.offreg = $ea_result">, 733 NoEncode<"$ea_result">; 734 735def LWZUX : XForm_1<31, 55, (outs GPRC:$rD, ptr_rc:$ea_result), 736 (ins memrr:$addr), 737 "lwzux $rD, $addr", LdStLoad, 738 []>, RegConstraint<"$addr.offreg = $ea_result">, 739 NoEncode<"$ea_result">; 740 741def LFSUX : XForm_1<31, 567, (outs F4RC:$rD, ptr_rc:$ea_result), 742 (ins memrr:$addr), 743 "lfsux $rD, $addr", LdStLoad, 744 []>, RegConstraint<"$addr.offreg = $ea_result">, 745 NoEncode<"$ea_result">; 746 747def LFDUX : XForm_1<31, 631, (outs F8RC:$rD, ptr_rc:$ea_result), 748 (ins memrr:$addr), 749 "lfdux $rD, $addr", LdStLoad, 750 []>, RegConstraint<"$addr.offreg = $ea_result">, 751 NoEncode<"$ea_result">; 752} 753} 754 755// Indexed (r+r) Loads. 756// 757let canFoldAsLoad = 1, PPC970_Unit = 2 in { 758def LBZX : XForm_1<31, 87, (outs GPRC:$rD), (ins memrr:$src), 759 "lbzx $rD, $src", LdStLoad, 760 [(set GPRC:$rD, (zextloadi8 xaddr:$src))]>; 761def LHAX : XForm_1<31, 343, (outs GPRC:$rD), (ins memrr:$src), 762 "lhax $rD, $src", LdStLHA, 763 [(set GPRC:$rD, (sextloadi16 xaddr:$src))]>, 764 PPC970_DGroup_Cracked; 765def LHZX : XForm_1<31, 279, (outs GPRC:$rD), (ins memrr:$src), 766 "lhzx $rD, $src", LdStLoad, 767 [(set GPRC:$rD, (zextloadi16 xaddr:$src))]>; 768def LWZX : XForm_1<31, 23, (outs GPRC:$rD), (ins memrr:$src), 769 "lwzx $rD, $src", LdStLoad, 770 [(set GPRC:$rD, (load xaddr:$src))]>; 771 772 773def LHBRX : XForm_1<31, 790, (outs GPRC:$rD), (ins memrr:$src), 774 "lhbrx $rD, $src", LdStLoad, 775 [(set GPRC:$rD, (PPClbrx xoaddr:$src, i16))]>; 776def LWBRX : XForm_1<31, 534, (outs GPRC:$rD), (ins memrr:$src), 777 "lwbrx $rD, $src", LdStLoad, 778 [(set GPRC:$rD, (PPClbrx xoaddr:$src, i32))]>; 779 780def LFSX : XForm_25<31, 535, (outs F4RC:$frD), (ins memrr:$src), 781 "lfsx $frD, $src", LdStLFDU, 782 [(set F4RC:$frD, (load xaddr:$src))]>; 783def LFDX : XForm_25<31, 599, (outs F8RC:$frD), (ins memrr:$src), 784 "lfdx $frD, $src", LdStLFDU, 785 [(set F8RC:$frD, (load xaddr:$src))]>; 786} 787 788//===----------------------------------------------------------------------===// 789// PPC32 Store Instructions. 790// 791 792// Unindexed (r+i) Stores. 793let PPC970_Unit = 2 in { 794def STB : DForm_1<38, (outs), (ins GPRC:$rS, memri:$src), 795 "stb $rS, $src", LdStStore, 796 [(truncstorei8 GPRC:$rS, iaddr:$src)]>; 797def STH : DForm_1<44, (outs), (ins GPRC:$rS, memri:$src), 798 "sth $rS, $src", LdStStore, 799 [(truncstorei16 GPRC:$rS, iaddr:$src)]>; 800def STW : DForm_1<36, (outs), (ins GPRC:$rS, memri:$src), 801 "stw $rS, $src", LdStStore, 802 [(store GPRC:$rS, iaddr:$src)]>; 803def STFS : DForm_1<52, (outs), (ins F4RC:$rS, memri:$dst), 804 "stfs $rS, $dst", LdStUX, 805 [(store F4RC:$rS, iaddr:$dst)]>; 806def STFD : DForm_1<54, (outs), (ins F8RC:$rS, memri:$dst), 807 "stfd $rS, $dst", LdStUX, 808 [(store F8RC:$rS, iaddr:$dst)]>; 809} 810 811// Unindexed (r+i) Stores with Update (preinc). 812let PPC970_Unit = 2 in { 813def STBU : DForm_1a<39, (outs ptr_rc:$ea_res), (ins GPRC:$rS, 814 symbolLo:$ptroff, ptr_rc:$ptrreg), 815 "stbu $rS, $ptroff($ptrreg)", LdStStore, 816 [(set ptr_rc:$ea_res, 817 (pre_truncsti8 GPRC:$rS, ptr_rc:$ptrreg, 818 iaddroff:$ptroff))]>, 819 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; 820def STHU : DForm_1a<45, (outs ptr_rc:$ea_res), (ins GPRC:$rS, 821 symbolLo:$ptroff, ptr_rc:$ptrreg), 822 "sthu $rS, $ptroff($ptrreg)", LdStStore, 823 [(set ptr_rc:$ea_res, 824 (pre_truncsti16 GPRC:$rS, ptr_rc:$ptrreg, 825 iaddroff:$ptroff))]>, 826 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; 827def STWU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins GPRC:$rS, 828 symbolLo:$ptroff, ptr_rc:$ptrreg), 829 "stwu $rS, $ptroff($ptrreg)", LdStStore, 830 [(set ptr_rc:$ea_res, (pre_store GPRC:$rS, ptr_rc:$ptrreg, 831 iaddroff:$ptroff))]>, 832 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; 833def STFSU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins F4RC:$rS, 834 symbolLo:$ptroff, ptr_rc:$ptrreg), 835 "stfsu $rS, $ptroff($ptrreg)", LdStStore, 836 [(set ptr_rc:$ea_res, (pre_store F4RC:$rS, ptr_rc:$ptrreg, 837 iaddroff:$ptroff))]>, 838 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; 839def STFDU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins F8RC:$rS, 840 symbolLo:$ptroff, ptr_rc:$ptrreg), 841 "stfdu $rS, $ptroff($ptrreg)", LdStStore, 842 [(set ptr_rc:$ea_res, (pre_store F8RC:$rS, ptr_rc:$ptrreg, 843 iaddroff:$ptroff))]>, 844 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; 845} 846 847 848// Indexed (r+r) Stores. 849// 850let PPC970_Unit = 2 in { 851def STBX : XForm_8<31, 215, (outs), (ins GPRC:$rS, memrr:$dst), 852 "stbx $rS, $dst", LdStStore, 853 [(truncstorei8 GPRC:$rS, xaddr:$dst)]>, 854 PPC970_DGroup_Cracked; 855def STHX : XForm_8<31, 407, (outs), (ins GPRC:$rS, memrr:$dst), 856 "sthx $rS, $dst", LdStStore, 857 [(truncstorei16 GPRC:$rS, xaddr:$dst)]>, 858 PPC970_DGroup_Cracked; 859def STWX : XForm_8<31, 151, (outs), (ins GPRC:$rS, memrr:$dst), 860 "stwx $rS, $dst", LdStStore, 861 [(store GPRC:$rS, xaddr:$dst)]>, 862 PPC970_DGroup_Cracked; 863 864def STBUX : XForm_8<31, 247, (outs ptr_rc:$ea_res), 865 (ins GPRC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg), 866 "stbux $rS, $ptroff, $ptrreg", LdStStore, 867 [(set ptr_rc:$ea_res, 868 (pre_truncsti8 GPRC:$rS, 869 ptr_rc:$ptrreg, xaddroff:$ptroff))]>, 870 RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">, 871 PPC970_DGroup_Cracked; 872 873def STHUX : XForm_8<31, 439, (outs ptr_rc:$ea_res), 874 (ins GPRC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg), 875 "sthux $rS, $ptroff, $ptrreg", LdStStore, 876 [(set ptr_rc:$ea_res, 877 (pre_truncsti16 GPRC:$rS, 878 ptr_rc:$ptrreg, xaddroff:$ptroff))]>, 879 RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">, 880 PPC970_DGroup_Cracked; 881 882def STWUX : XForm_8<31, 183, (outs ptr_rc:$ea_res), 883 (ins GPRC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg), 884 "stwux $rS, $ptroff, $ptrreg", LdStStore, 885 [(set ptr_rc:$ea_res, 886 (pre_store GPRC:$rS, ptr_rc:$ptrreg, xaddroff:$ptroff))]>, 887 RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">, 888 PPC970_DGroup_Cracked; 889 890def STFSUX : XForm_8<31, 695, (outs ptr_rc:$ea_res), 891 (ins F4RC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg), 892 "stfsux $rS, $ptroff, $ptrreg", LdStStore, 893 [(set ptr_rc:$ea_res, 894 (pre_store F4RC:$rS, ptr_rc:$ptrreg, xaddroff:$ptroff))]>, 895 RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">, 896 PPC970_DGroup_Cracked; 897 898def STFDUX : XForm_8<31, 759, (outs ptr_rc:$ea_res), 899 (ins F8RC:$rS, ptr_rc:$ptroff, ptr_rc:$ptrreg), 900 "stfdux $rS, $ptroff, $ptrreg", LdStStore, 901 [(set ptr_rc:$ea_res, 902 (pre_store F8RC:$rS, ptr_rc:$ptrreg, xaddroff:$ptroff))]>, 903 RegConstraint<"$ptroff = $ea_res">, NoEncode<"$ea_res">, 904 PPC970_DGroup_Cracked; 905 906def STHBRX: XForm_8<31, 918, (outs), (ins GPRC:$rS, memrr:$dst), 907 "sthbrx $rS, $dst", LdStStore, 908 [(PPCstbrx GPRC:$rS, xoaddr:$dst, i16)]>, 909 PPC970_DGroup_Cracked; 910def STWBRX: XForm_8<31, 662, (outs), (ins GPRC:$rS, memrr:$dst), 911 "stwbrx $rS, $dst", LdStStore, 912 [(PPCstbrx GPRC:$rS, xoaddr:$dst, i32)]>, 913 PPC970_DGroup_Cracked; 914 915def STFIWX: XForm_28<31, 983, (outs), (ins F8RC:$frS, memrr:$dst), 916 "stfiwx $frS, $dst", LdStUX, 917 [(PPCstfiwx F8RC:$frS, xoaddr:$dst)]>; 918 919def STFSX : XForm_28<31, 663, (outs), (ins F4RC:$frS, memrr:$dst), 920 "stfsx $frS, $dst", LdStUX, 921 [(store F4RC:$frS, xaddr:$dst)]>; 922def STFDX : XForm_28<31, 727, (outs), (ins F8RC:$frS, memrr:$dst), 923 "stfdx $frS, $dst", LdStUX, 924 [(store F8RC:$frS, xaddr:$dst)]>; 925} 926 927def SYNC : XForm_24_sync<31, 598, (outs), (ins), 928 "sync", LdStSync, 929 [(int_ppc_sync)]>; 930 931//===----------------------------------------------------------------------===// 932// PPC32 Arithmetic Instructions. 933// 934 935let PPC970_Unit = 1 in { // FXU Operations. 936def ADDI : DForm_2<14, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), 937 "addi $rD, $rA, $imm", IntSimple, 938 [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>; 939def ADDIL : DForm_2<14, (outs GPRC:$rD), (ins GPRC:$rA, symbolLo:$imm), 940 "addi $rD, $rA, $imm", IntSimple, 941 [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>; 942let Defs = [CARRY] in { 943def ADDIC : DForm_2<12, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), 944 "addic $rD, $rA, $imm", IntGeneral, 945 [(set GPRC:$rD, (addc GPRC:$rA, immSExt16:$imm))]>, 946 PPC970_DGroup_Cracked; 947def ADDICo : DForm_2<13, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), 948 "addic. $rD, $rA, $imm", IntGeneral, 949 []>; 950} 951def ADDIS : DForm_2<15, (outs GPRC:$rD), (ins GPRC:$rA, symbolHi:$imm), 952 "addis $rD, $rA, $imm", IntSimple, 953 [(set GPRC:$rD, (add GPRC:$rA, imm16ShiftedSExt:$imm))]>; 954def LA : DForm_2<14, (outs GPRC:$rD), (ins GPRC:$rA, symbolLo:$sym), 955 "la $rD, $sym($rA)", IntGeneral, 956 [(set GPRC:$rD, (add GPRC:$rA, 957 (PPClo tglobaladdr:$sym, 0)))]>; 958def MULLI : DForm_2< 7, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), 959 "mulli $rD, $rA, $imm", IntMulLI, 960 [(set GPRC:$rD, (mul GPRC:$rA, immSExt16:$imm))]>; 961let Defs = [CARRY] in { 962def SUBFIC : DForm_2< 8, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), 963 "subfic $rD, $rA, $imm", IntGeneral, 964 [(set GPRC:$rD, (subc immSExt16:$imm, GPRC:$rA))]>; 965} 966 967let isReMaterializable = 1 in { 968 def LI : DForm_2_r0<14, (outs GPRC:$rD), (ins symbolLo:$imm), 969 "li $rD, $imm", IntSimple, 970 [(set GPRC:$rD, immSExt16:$imm)]>; 971 def LIS : DForm_2_r0<15, (outs GPRC:$rD), (ins symbolHi:$imm), 972 "lis $rD, $imm", IntSimple, 973 [(set GPRC:$rD, imm16ShiftedSExt:$imm)]>; 974} 975} 976 977let PPC970_Unit = 1 in { // FXU Operations. 978def ANDIo : DForm_4<28, (outs GPRC:$dst), (ins GPRC:$src1, u16imm:$src2), 979 "andi. $dst, $src1, $src2", IntGeneral, 980 [(set GPRC:$dst, (and GPRC:$src1, immZExt16:$src2))]>, 981 isDOT; 982def ANDISo : DForm_4<29, (outs GPRC:$dst), (ins GPRC:$src1, u16imm:$src2), 983 "andis. $dst, $src1, $src2", IntGeneral, 984 [(set GPRC:$dst, (and GPRC:$src1,imm16ShiftedZExt:$src2))]>, 985 isDOT; 986def ORI : DForm_4<24, (outs GPRC:$dst), (ins GPRC:$src1, u16imm:$src2), 987 "ori $dst, $src1, $src2", IntSimple, 988 [(set GPRC:$dst, (or GPRC:$src1, immZExt16:$src2))]>; 989def ORIS : DForm_4<25, (outs GPRC:$dst), (ins GPRC:$src1, u16imm:$src2), 990 "oris $dst, $src1, $src2", IntSimple, 991 [(set GPRC:$dst, (or GPRC:$src1, imm16ShiftedZExt:$src2))]>; 992def XORI : DForm_4<26, (outs GPRC:$dst), (ins GPRC:$src1, u16imm:$src2), 993 "xori $dst, $src1, $src2", IntSimple, 994 [(set GPRC:$dst, (xor GPRC:$src1, immZExt16:$src2))]>; 995def XORIS : DForm_4<27, (outs GPRC:$dst), (ins GPRC:$src1, u16imm:$src2), 996 "xoris $dst, $src1, $src2", IntSimple, 997 [(set GPRC:$dst, (xor GPRC:$src1,imm16ShiftedZExt:$src2))]>; 998def NOP : DForm_4_zero<24, (outs), (ins), "nop", IntSimple, 999 []>; 1000def CMPWI : DForm_5_ext<11, (outs CRRC:$crD), (ins GPRC:$rA, s16imm:$imm), 1001 "cmpwi $crD, $rA, $imm", IntCompare>; 1002def CMPLWI : DForm_6_ext<10, (outs CRRC:$dst), (ins GPRC:$src1, u16imm:$src2), 1003 "cmplwi $dst, $src1, $src2", IntCompare>; 1004} 1005 1006 1007let PPC970_Unit = 1 in { // FXU Operations. 1008def NAND : XForm_6<31, 476, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1009 "nand $rA, $rS, $rB", IntSimple, 1010 [(set GPRC:$rA, (not (and GPRC:$rS, GPRC:$rB)))]>; 1011def AND : XForm_6<31, 28, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1012 "and $rA, $rS, $rB", IntSimple, 1013 [(set GPRC:$rA, (and GPRC:$rS, GPRC:$rB))]>; 1014def ANDC : XForm_6<31, 60, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1015 "andc $rA, $rS, $rB", IntSimple, 1016 [(set GPRC:$rA, (and GPRC:$rS, (not GPRC:$rB)))]>; 1017def OR : XForm_6<31, 444, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1018 "or $rA, $rS, $rB", IntSimple, 1019 [(set GPRC:$rA, (or GPRC:$rS, GPRC:$rB))]>; 1020def NOR : XForm_6<31, 124, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1021 "nor $rA, $rS, $rB", IntSimple, 1022 [(set GPRC:$rA, (not (or GPRC:$rS, GPRC:$rB)))]>; 1023def ORC : XForm_6<31, 412, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1024 "orc $rA, $rS, $rB", IntSimple, 1025 [(set GPRC:$rA, (or GPRC:$rS, (not GPRC:$rB)))]>; 1026def EQV : XForm_6<31, 284, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1027 "eqv $rA, $rS, $rB", IntSimple, 1028 [(set GPRC:$rA, (not (xor GPRC:$rS, GPRC:$rB)))]>; 1029def XOR : XForm_6<31, 316, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1030 "xor $rA, $rS, $rB", IntSimple, 1031 [(set GPRC:$rA, (xor GPRC:$rS, GPRC:$rB))]>; 1032def SLW : XForm_6<31, 24, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1033 "slw $rA, $rS, $rB", IntGeneral, 1034 [(set GPRC:$rA, (PPCshl GPRC:$rS, GPRC:$rB))]>; 1035def SRW : XForm_6<31, 536, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1036 "srw $rA, $rS, $rB", IntGeneral, 1037 [(set GPRC:$rA, (PPCsrl GPRC:$rS, GPRC:$rB))]>; 1038let Defs = [CARRY] in { 1039def SRAW : XForm_6<31, 792, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), 1040 "sraw $rA, $rS, $rB", IntShift, 1041 [(set GPRC:$rA, (PPCsra GPRC:$rS, GPRC:$rB))]>; 1042} 1043} 1044 1045let PPC970_Unit = 1 in { // FXU Operations. 1046let Defs = [CARRY] in { 1047def SRAWI : XForm_10<31, 824, (outs GPRC:$rA), (ins GPRC:$rS, u5imm:$SH), 1048 "srawi $rA, $rS, $SH", IntShift, 1049 [(set GPRC:$rA, (sra GPRC:$rS, (i32 imm:$SH)))]>; 1050} 1051def CNTLZW : XForm_11<31, 26, (outs GPRC:$rA), (ins GPRC:$rS), 1052 "cntlzw $rA, $rS", IntGeneral, 1053 [(set GPRC:$rA, (ctlz GPRC:$rS))]>; 1054def EXTSB : XForm_11<31, 954, (outs GPRC:$rA), (ins GPRC:$rS), 1055 "extsb $rA, $rS", IntSimple, 1056 [(set GPRC:$rA, (sext_inreg GPRC:$rS, i8))]>; 1057def EXTSH : XForm_11<31, 922, (outs GPRC:$rA), (ins GPRC:$rS), 1058 "extsh $rA, $rS", IntSimple, 1059 [(set GPRC:$rA, (sext_inreg GPRC:$rS, i16))]>; 1060 1061def CMPW : XForm_16_ext<31, 0, (outs CRRC:$crD), (ins GPRC:$rA, GPRC:$rB), 1062 "cmpw $crD, $rA, $rB", IntCompare>; 1063def CMPLW : XForm_16_ext<31, 32, (outs CRRC:$crD), (ins GPRC:$rA, GPRC:$rB), 1064 "cmplw $crD, $rA, $rB", IntCompare>; 1065} 1066let PPC970_Unit = 3 in { // FPU Operations. 1067//def FCMPO : XForm_17<63, 32, (outs CRRC:$crD), (ins FPRC:$fA, FPRC:$fB), 1068// "fcmpo $crD, $fA, $fB", FPCompare>; 1069def FCMPUS : XForm_17<63, 0, (outs CRRC:$crD), (ins F4RC:$fA, F4RC:$fB), 1070 "fcmpu $crD, $fA, $fB", FPCompare>; 1071def FCMPUD : XForm_17<63, 0, (outs CRRC:$crD), (ins F8RC:$fA, F8RC:$fB), 1072 "fcmpu $crD, $fA, $fB", FPCompare>; 1073 1074let Uses = [RM] in { 1075 def FCTIWZ : XForm_26<63, 15, (outs F8RC:$frD), (ins F8RC:$frB), 1076 "fctiwz $frD, $frB", FPGeneral, 1077 [(set F8RC:$frD, (PPCfctiwz F8RC:$frB))]>; 1078 def FRSP : XForm_26<63, 12, (outs F4RC:$frD), (ins F8RC:$frB), 1079 "frsp $frD, $frB", FPGeneral, 1080 [(set F4RC:$frD, (fround F8RC:$frB))]>; 1081 def FSQRT : XForm_26<63, 22, (outs F8RC:$frD), (ins F8RC:$frB), 1082 "fsqrt $frD, $frB", FPSqrt, 1083 [(set F8RC:$frD, (fsqrt F8RC:$frB))]>; 1084 def FSQRTS : XForm_26<59, 22, (outs F4RC:$frD), (ins F4RC:$frB), 1085 "fsqrts $frD, $frB", FPSqrt, 1086 [(set F4RC:$frD, (fsqrt F4RC:$frB))]>; 1087 } 1088} 1089 1090/// Note that FMR is defined as pseudo-ops on the PPC970 because they are 1091/// often coalesced away and we don't want the dispatch group builder to think 1092/// that they will fill slots (which could cause the load of a LSU reject to 1093/// sneak into a d-group with a store). 1094def FMR : XForm_26<63, 72, (outs F4RC:$frD), (ins F4RC:$frB), 1095 "fmr $frD, $frB", FPGeneral, 1096 []>, // (set F4RC:$frD, F4RC:$frB) 1097 PPC970_Unit_Pseudo; 1098 1099let PPC970_Unit = 3 in { // FPU Operations. 1100// These are artificially split into two different forms, for 4/8 byte FP. 1101def FABSS : XForm_26<63, 264, (outs F4RC:$frD), (ins F4RC:$frB), 1102 "fabs $frD, $frB", FPGeneral, 1103 [(set F4RC:$frD, (fabs F4RC:$frB))]>; 1104def FABSD : XForm_26<63, 264, (outs F8RC:$frD), (ins F8RC:$frB), 1105 "fabs $frD, $frB", FPGeneral, 1106 [(set F8RC:$frD, (fabs F8RC:$frB))]>; 1107def FNABSS : XForm_26<63, 136, (outs F4RC:$frD), (ins F4RC:$frB), 1108 "fnabs $frD, $frB", FPGeneral, 1109 [(set F4RC:$frD, (fneg (fabs F4RC:$frB)))]>; 1110def FNABSD : XForm_26<63, 136, (outs F8RC:$frD), (ins F8RC:$frB), 1111 "fnabs $frD, $frB", FPGeneral, 1112 [(set F8RC:$frD, (fneg (fabs F8RC:$frB)))]>; 1113def FNEGS : XForm_26<63, 40, (outs F4RC:$frD), (ins F4RC:$frB), 1114 "fneg $frD, $frB", FPGeneral, 1115 [(set F4RC:$frD, (fneg F4RC:$frB))]>; 1116def FNEGD : XForm_26<63, 40, (outs F8RC:$frD), (ins F8RC:$frB), 1117 "fneg $frD, $frB", FPGeneral, 1118 [(set F8RC:$frD, (fneg F8RC:$frB))]>; 1119} 1120 1121 1122// XL-Form instructions. condition register logical ops. 1123// 1124def MCRF : XLForm_3<19, 0, (outs CRRC:$BF), (ins CRRC:$BFA), 1125 "mcrf $BF, $BFA", BrMCR>, 1126 PPC970_DGroup_First, PPC970_Unit_CRU; 1127 1128def CREQV : XLForm_1<19, 289, (outs CRBITRC:$CRD), 1129 (ins CRBITRC:$CRA, CRBITRC:$CRB), 1130 "creqv $CRD, $CRA, $CRB", BrCR, 1131 []>; 1132 1133def CROR : XLForm_1<19, 449, (outs CRBITRC:$CRD), 1134 (ins CRBITRC:$CRA, CRBITRC:$CRB), 1135 "cror $CRD, $CRA, $CRB", BrCR, 1136 []>; 1137 1138def CRSET : XLForm_1_ext<19, 289, (outs CRBITRC:$dst), (ins), 1139 "creqv $dst, $dst, $dst", BrCR, 1140 []>; 1141 1142def CRUNSET: XLForm_1_ext<19, 193, (outs CRBITRC:$dst), (ins), 1143 "crxor $dst, $dst, $dst", BrCR, 1144 []>; 1145 1146// XFX-Form instructions. Instructions that deal with SPRs. 1147// 1148let Uses = [CTR] in { 1149def MFCTR : XFXForm_1_ext<31, 339, 9, (outs GPRC:$rT), (ins), 1150 "mfctr $rT", SprMFSPR>, 1151 PPC970_DGroup_First, PPC970_Unit_FXU; 1152} 1153let Defs = [CTR], Pattern = [(PPCmtctr GPRC:$rS)] in { 1154def MTCTR : XFXForm_7_ext<31, 467, 9, (outs), (ins GPRC:$rS), 1155 "mtctr $rS", SprMTSPR>, 1156 PPC970_DGroup_First, PPC970_Unit_FXU; 1157} 1158 1159let Defs = [LR] in { 1160def MTLR : XFXForm_7_ext<31, 467, 8, (outs), (ins GPRC:$rS), 1161 "mtlr $rS", SprMTSPR>, 1162 PPC970_DGroup_First, PPC970_Unit_FXU; 1163} 1164let Uses = [LR] in { 1165def MFLR : XFXForm_1_ext<31, 339, 8, (outs GPRC:$rT), (ins), 1166 "mflr $rT", SprMFSPR>, 1167 PPC970_DGroup_First, PPC970_Unit_FXU; 1168} 1169 1170// Move to/from VRSAVE: despite being a SPR, the VRSAVE register is renamed like 1171// a GPR on the PPC970. As such, copies in and out have the same performance 1172// characteristics as an OR instruction. 1173def MTVRSAVE : XFXForm_7_ext<31, 467, 256, (outs), (ins GPRC:$rS), 1174 "mtspr 256, $rS", IntGeneral>, 1175 PPC970_DGroup_Single, PPC970_Unit_FXU; 1176def MFVRSAVE : XFXForm_1_ext<31, 339, 256, (outs GPRC:$rT), (ins), 1177 "mfspr $rT, 256", IntGeneral>, 1178 PPC970_DGroup_First, PPC970_Unit_FXU; 1179 1180def MTCRF : XFXForm_5<31, 144, (outs crbitm:$FXM), (ins GPRC:$rS), 1181 "mtcrf $FXM, $rS", BrMCRX>, 1182 PPC970_MicroCode, PPC970_Unit_CRU; 1183 1184// This is a pseudo for MFCR, which implicitly uses all 8 of its subregisters; 1185// declaring that here gives the local register allocator problems with this: 1186// vreg = MCRF CR0 1187// MFCR <kill of whatever preg got assigned to vreg> 1188// while not declaring it breaks DeadMachineInstructionElimination. 1189// As it turns out, in all cases where we currently use this, 1190// we're only interested in one subregister of it. Represent this in the 1191// instruction to keep the register allocator from becoming confused. 1192// 1193// FIXME: Make this a real Pseudo instruction when the JIT switches to MC. 1194def MFCRpseud: XFXForm_3<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM), 1195 "", SprMFCR>, 1196 PPC970_MicroCode, PPC970_Unit_CRU; 1197 1198def MFCR : XFXForm_3<31, 19, (outs GPRC:$rT), (ins), 1199 "mfcr $rT", SprMFCR>, 1200 PPC970_MicroCode, PPC970_Unit_CRU; 1201 1202def MFOCRF: XFXForm_5a<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM), 1203 "mfocrf $rT, $FXM", SprMFCR>, 1204 PPC970_DGroup_First, PPC970_Unit_CRU; 1205 1206// Instructions to manipulate FPSCR. Only long double handling uses these. 1207// FPSCR is not modelled; we use the SDNode Flag to keep things in order. 1208 1209let Uses = [RM], Defs = [RM] in { 1210 def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM), 1211 "mtfsb0 $FM", IntMTFSB0, 1212 [(PPCmtfsb0 (i32 imm:$FM))]>, 1213 PPC970_DGroup_Single, PPC970_Unit_FPU; 1214 def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM), 1215 "mtfsb1 $FM", IntMTFSB0, 1216 [(PPCmtfsb1 (i32 imm:$FM))]>, 1217 PPC970_DGroup_Single, PPC970_Unit_FPU; 1218 // MTFSF does not actually produce an FP result. We pretend it copies 1219 // input reg B to the output. If we didn't do this it would look like the 1220 // instruction had no outputs (because we aren't modelling the FPSCR) and 1221 // it would be deleted. 1222 def MTFSF : XFLForm<63, 711, (outs F8RC:$FRA), 1223 (ins i32imm:$FM, F8RC:$rT, F8RC:$FRB), 1224 "mtfsf $FM, $rT", "$FRB = $FRA", IntMTFSB0, 1225 [(set F8RC:$FRA, (PPCmtfsf (i32 imm:$FM), 1226 F8RC:$rT, F8RC:$FRB))]>, 1227 PPC970_DGroup_Single, PPC970_Unit_FPU; 1228} 1229let Uses = [RM] in { 1230 def MFFS : XForm_42<63, 583, (outs F8RC:$rT), (ins), 1231 "mffs $rT", IntMFFS, 1232 [(set F8RC:$rT, (PPCmffs))]>, 1233 PPC970_DGroup_Single, PPC970_Unit_FPU; 1234 def FADDrtz: AForm_2<63, 21, 1235 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), 1236 "fadd $FRT, $FRA, $FRB", FPGeneral, 1237 [(set F8RC:$FRT, (PPCfaddrtz F8RC:$FRA, F8RC:$FRB))]>, 1238 PPC970_DGroup_Single, PPC970_Unit_FPU; 1239} 1240 1241 1242let PPC970_Unit = 1 in { // FXU Operations. 1243 1244// XO-Form instructions. Arithmetic instructions that can set overflow bit 1245// 1246def ADD4 : XOForm_1<31, 266, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1247 "add $rT, $rA, $rB", IntSimple, 1248 [(set GPRC:$rT, (add GPRC:$rA, GPRC:$rB))]>; 1249let Defs = [CARRY] in { 1250def ADDC : XOForm_1<31, 10, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1251 "addc $rT, $rA, $rB", IntGeneral, 1252 [(set GPRC:$rT, (addc GPRC:$rA, GPRC:$rB))]>, 1253 PPC970_DGroup_Cracked; 1254} 1255def DIVW : XOForm_1<31, 491, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1256 "divw $rT, $rA, $rB", IntDivW, 1257 [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>, 1258 PPC970_DGroup_First, PPC970_DGroup_Cracked; 1259def DIVWU : XOForm_1<31, 459, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1260 "divwu $rT, $rA, $rB", IntDivW, 1261 [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>, 1262 PPC970_DGroup_First, PPC970_DGroup_Cracked; 1263def MULHW : XOForm_1<31, 75, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1264 "mulhw $rT, $rA, $rB", IntMulHW, 1265 [(set GPRC:$rT, (mulhs GPRC:$rA, GPRC:$rB))]>; 1266def MULHWU : XOForm_1<31, 11, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1267 "mulhwu $rT, $rA, $rB", IntMulHWU, 1268 [(set GPRC:$rT, (mulhu GPRC:$rA, GPRC:$rB))]>; 1269def MULLW : XOForm_1<31, 235, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1270 "mullw $rT, $rA, $rB", IntMulHW, 1271 [(set GPRC:$rT, (mul GPRC:$rA, GPRC:$rB))]>; 1272def SUBF : XOForm_1<31, 40, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1273 "subf $rT, $rA, $rB", IntGeneral, 1274 [(set GPRC:$rT, (sub GPRC:$rB, GPRC:$rA))]>; 1275let Defs = [CARRY] in { 1276def SUBFC : XOForm_1<31, 8, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1277 "subfc $rT, $rA, $rB", IntGeneral, 1278 [(set GPRC:$rT, (subc GPRC:$rB, GPRC:$rA))]>, 1279 PPC970_DGroup_Cracked; 1280} 1281def NEG : XOForm_3<31, 104, 0, (outs GPRC:$rT), (ins GPRC:$rA), 1282 "neg $rT, $rA", IntSimple, 1283 [(set GPRC:$rT, (ineg GPRC:$rA))]>; 1284let Uses = [CARRY], Defs = [CARRY] in { 1285def ADDE : XOForm_1<31, 138, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1286 "adde $rT, $rA, $rB", IntGeneral, 1287 [(set GPRC:$rT, (adde GPRC:$rA, GPRC:$rB))]>; 1288def ADDME : XOForm_3<31, 234, 0, (outs GPRC:$rT), (ins GPRC:$rA), 1289 "addme $rT, $rA", IntGeneral, 1290 [(set GPRC:$rT, (adde GPRC:$rA, -1))]>; 1291def ADDZE : XOForm_3<31, 202, 0, (outs GPRC:$rT), (ins GPRC:$rA), 1292 "addze $rT, $rA", IntGeneral, 1293 [(set GPRC:$rT, (adde GPRC:$rA, 0))]>; 1294def SUBFE : XOForm_1<31, 136, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), 1295 "subfe $rT, $rA, $rB", IntGeneral, 1296 [(set GPRC:$rT, (sube GPRC:$rB, GPRC:$rA))]>; 1297def SUBFME : XOForm_3<31, 232, 0, (outs GPRC:$rT), (ins GPRC:$rA), 1298 "subfme $rT, $rA", IntGeneral, 1299 [(set GPRC:$rT, (sube -1, GPRC:$rA))]>; 1300def SUBFZE : XOForm_3<31, 200, 0, (outs GPRC:$rT), (ins GPRC:$rA), 1301 "subfze $rT, $rA", IntGeneral, 1302 [(set GPRC:$rT, (sube 0, GPRC:$rA))]>; 1303} 1304} 1305 1306// A-Form instructions. Most of the instructions executed in the FPU are of 1307// this type. 1308// 1309let PPC970_Unit = 3 in { // FPU Operations. 1310let Uses = [RM] in { 1311 def FMADD : AForm_1<63, 29, 1312 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), 1313 "fmadd $FRT, $FRA, $FRC, $FRB", FPFused, 1314 [(set F8RC:$FRT, 1315 (fma F8RC:$FRA, F8RC:$FRC, F8RC:$FRB))]>; 1316 def FMADDS : AForm_1<59, 29, 1317 (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), 1318 "fmadds $FRT, $FRA, $FRC, $FRB", FPGeneral, 1319 [(set F4RC:$FRT, 1320 (fma F4RC:$FRA, F4RC:$FRC, F4RC:$FRB))]>; 1321 def FMSUB : AForm_1<63, 28, 1322 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), 1323 "fmsub $FRT, $FRA, $FRC, $FRB", FPFused, 1324 [(set F8RC:$FRT, 1325 (fma F8RC:$FRA, F8RC:$FRC, (fneg F8RC:$FRB)))]>; 1326 def FMSUBS : AForm_1<59, 28, 1327 (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), 1328 "fmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral, 1329 [(set F4RC:$FRT, 1330 (fma F4RC:$FRA, F4RC:$FRC, (fneg F4RC:$FRB)))]>; 1331 def FNMADD : AForm_1<63, 31, 1332 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), 1333 "fnmadd $FRT, $FRA, $FRC, $FRB", FPFused, 1334 [(set F8RC:$FRT, 1335 (fneg (fma F8RC:$FRA, F8RC:$FRC, F8RC:$FRB)))]>; 1336 def FNMADDS : AForm_1<59, 31, 1337 (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), 1338 "fnmadds $FRT, $FRA, $FRC, $FRB", FPGeneral, 1339 [(set F4RC:$FRT, 1340 (fneg (fma F4RC:$FRA, F4RC:$FRC, F4RC:$FRB)))]>; 1341 def FNMSUB : AForm_1<63, 30, 1342 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), 1343 "fnmsub $FRT, $FRA, $FRC, $FRB", FPFused, 1344 [(set F8RC:$FRT, (fneg (fma F8RC:$FRA, F8RC:$FRC, 1345 (fneg F8RC:$FRB))))]>; 1346 def FNMSUBS : AForm_1<59, 30, 1347 (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), 1348 "fnmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral, 1349 [(set F4RC:$FRT, (fneg (fma F4RC:$FRA, F4RC:$FRC, 1350 (fneg F4RC:$FRB))))]>; 1351} 1352// FSEL is artificially split into 4 and 8-byte forms for the result. To avoid 1353// having 4 of these, force the comparison to always be an 8-byte double (code 1354// should use an FMRSD if the input comparison value really wants to be a float) 1355// and 4/8 byte forms for the result and operand type.. 1356def FSELD : AForm_1<63, 23, 1357 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), 1358 "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral, 1359 [(set F8RC:$FRT, (PPCfsel F8RC:$FRA,F8RC:$FRC,F8RC:$FRB))]>; 1360def FSELS : AForm_1<63, 23, 1361 (outs F4RC:$FRT), (ins F8RC:$FRA, F4RC:$FRC, F4RC:$FRB), 1362 "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral, 1363 [(set F4RC:$FRT, (PPCfsel F8RC:$FRA,F4RC:$FRC,F4RC:$FRB))]>; 1364let Uses = [RM] in { 1365 def FADD : AForm_2<63, 21, 1366 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), 1367 "fadd $FRT, $FRA, $FRB", FPGeneral, 1368 [(set F8RC:$FRT, (fadd F8RC:$FRA, F8RC:$FRB))]>; 1369 def FADDS : AForm_2<59, 21, 1370 (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB), 1371 "fadds $FRT, $FRA, $FRB", FPGeneral, 1372 [(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>; 1373 def FDIV : AForm_2<63, 18, 1374 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), 1375 "fdiv $FRT, $FRA, $FRB", FPDivD, 1376 [(set F8RC:$FRT, (fdiv F8RC:$FRA, F8RC:$FRB))]>; 1377 def FDIVS : AForm_2<59, 18, 1378 (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB), 1379 "fdivs $FRT, $FRA, $FRB", FPDivS, 1380 [(set F4RC:$FRT, (fdiv F4RC:$FRA, F4RC:$FRB))]>; 1381 def FMUL : AForm_3<63, 25, 1382 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), 1383 "fmul $FRT, $FRA, $FRB", FPFused, 1384 [(set F8RC:$FRT, (fmul F8RC:$FRA, F8RC:$FRB))]>; 1385 def FMULS : AForm_3<59, 25, 1386 (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB), 1387 "fmuls $FRT, $FRA, $FRB", FPGeneral, 1388 [(set F4RC:$FRT, (fmul F4RC:$FRA, F4RC:$FRB))]>; 1389 def FSUB : AForm_2<63, 20, 1390 (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), 1391 "fsub $FRT, $FRA, $FRB", FPGeneral, 1392 [(set F8RC:$FRT, (fsub F8RC:$FRA, F8RC:$FRB))]>; 1393 def FSUBS : AForm_2<59, 20, 1394 (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB), 1395 "fsubs $FRT, $FRA, $FRB", FPGeneral, 1396 [(set F4RC:$FRT, (fsub F4RC:$FRA, F4RC:$FRB))]>; 1397 } 1398} 1399 1400let PPC970_Unit = 1 in { // FXU Operations. 1401 def ISEL : AForm_1<31, 15, 1402 (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB, pred:$cond), 1403 "isel $rT, $rA, $rB, $cond", IntGeneral, 1404 []>; 1405} 1406 1407let PPC970_Unit = 1 in { // FXU Operations. 1408// M-Form instructions. rotate and mask instructions. 1409// 1410let isCommutable = 1 in { 1411// RLWIMI can be commuted if the rotate amount is zero. 1412def RLWIMI : MForm_2<20, 1413 (outs GPRC:$rA), (ins GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB, 1414 u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME", IntRotate, 1415 []>, PPC970_DGroup_Cracked, RegConstraint<"$rSi = $rA">, 1416 NoEncode<"$rSi">; 1417} 1418def RLWINM : MForm_2<21, 1419 (outs GPRC:$rA), (ins GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), 1420 "rlwinm $rA, $rS, $SH, $MB, $ME", IntGeneral, 1421 []>; 1422def RLWINMo : MForm_2<21, 1423 (outs GPRC:$rA), (ins GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), 1424 "rlwinm. $rA, $rS, $SH, $MB, $ME", IntGeneral, 1425 []>, isDOT, PPC970_DGroup_Cracked; 1426def RLWNM : MForm_2<23, 1427 (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME), 1428 "rlwnm $rA, $rS, $rB, $MB, $ME", IntGeneral, 1429 []>; 1430} 1431 1432 1433//===----------------------------------------------------------------------===// 1434// PowerPC Instruction Patterns 1435// 1436 1437// Arbitrary immediate support. Implement in terms of LIS/ORI. 1438def : Pat<(i32 imm:$imm), 1439 (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>; 1440 1441// Implement the 'not' operation with the NOR instruction. 1442def NOT : Pat<(not GPRC:$in), 1443 (NOR GPRC:$in, GPRC:$in)>; 1444 1445// ADD an arbitrary immediate. 1446def : Pat<(add GPRC:$in, imm:$imm), 1447 (ADDIS (ADDI GPRC:$in, (LO16 imm:$imm)), (HA16 imm:$imm))>; 1448// OR an arbitrary immediate. 1449def : Pat<(or GPRC:$in, imm:$imm), 1450 (ORIS (ORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; 1451// XOR an arbitrary immediate. 1452def : Pat<(xor GPRC:$in, imm:$imm), 1453 (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; 1454// SUBFIC 1455def : Pat<(sub immSExt16:$imm, GPRC:$in), 1456 (SUBFIC GPRC:$in, imm:$imm)>; 1457 1458// SHL/SRL 1459def : Pat<(shl GPRC:$in, (i32 imm:$imm)), 1460 (RLWINM GPRC:$in, imm:$imm, 0, (SHL32 imm:$imm))>; 1461def : Pat<(srl GPRC:$in, (i32 imm:$imm)), 1462 (RLWINM GPRC:$in, (SRL32 imm:$imm), imm:$imm, 31)>; 1463 1464// ROTL 1465def : Pat<(rotl GPRC:$in, GPRC:$sh), 1466 (RLWNM GPRC:$in, GPRC:$sh, 0, 31)>; 1467def : Pat<(rotl GPRC:$in, (i32 imm:$imm)), 1468 (RLWINM GPRC:$in, imm:$imm, 0, 31)>; 1469 1470// RLWNM 1471def : Pat<(and (rotl GPRC:$in, GPRC:$sh), maskimm32:$imm), 1472 (RLWNM GPRC:$in, GPRC:$sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>; 1473 1474// Calls 1475def : Pat<(PPCcall_Darwin (i32 tglobaladdr:$dst)), 1476 (BL_Darwin tglobaladdr:$dst)>; 1477def : Pat<(PPCcall_Darwin (i32 texternalsym:$dst)), 1478 (BL_Darwin texternalsym:$dst)>; 1479def : Pat<(PPCcall_SVR4 (i32 tglobaladdr:$dst)), 1480 (BL_SVR4 tglobaladdr:$dst)>; 1481def : Pat<(PPCcall_SVR4 (i32 texternalsym:$dst)), 1482 (BL_SVR4 texternalsym:$dst)>; 1483 1484 1485def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm), 1486 (TCRETURNdi tglobaladdr:$dst, imm:$imm)>; 1487 1488def : Pat<(PPCtc_return (i32 texternalsym:$dst), imm:$imm), 1489 (TCRETURNdi texternalsym:$dst, imm:$imm)>; 1490 1491def : Pat<(PPCtc_return CTRRC:$dst, imm:$imm), 1492 (TCRETURNri CTRRC:$dst, imm:$imm)>; 1493 1494 1495 1496// Hi and Lo for Darwin Global Addresses. 1497def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>; 1498def : Pat<(PPClo tglobaladdr:$in, 0), (LI tglobaladdr:$in)>; 1499def : Pat<(PPChi tconstpool:$in, 0), (LIS tconstpool:$in)>; 1500def : Pat<(PPClo tconstpool:$in, 0), (LI tconstpool:$in)>; 1501def : Pat<(PPChi tjumptable:$in, 0), (LIS tjumptable:$in)>; 1502def : Pat<(PPClo tjumptable:$in, 0), (LI tjumptable:$in)>; 1503def : Pat<(PPChi tblockaddress:$in, 0), (LIS tblockaddress:$in)>; 1504def : Pat<(PPClo tblockaddress:$in, 0), (LI tblockaddress:$in)>; 1505def : Pat<(PPChi tglobaltlsaddr:$g, GPRC:$in), 1506 (ADDIS GPRC:$in, tglobaltlsaddr:$g)>; 1507def : Pat<(PPClo tglobaltlsaddr:$g, GPRC:$in), 1508 (ADDIL GPRC:$in, tglobaltlsaddr:$g)>; 1509def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), 1510 (ADDIS GPRC:$in, tglobaladdr:$g)>; 1511def : Pat<(add GPRC:$in, (PPChi tconstpool:$g, 0)), 1512 (ADDIS GPRC:$in, tconstpool:$g)>; 1513def : Pat<(add GPRC:$in, (PPChi tjumptable:$g, 0)), 1514 (ADDIS GPRC:$in, tjumptable:$g)>; 1515def : Pat<(add GPRC:$in, (PPChi tblockaddress:$g, 0)), 1516 (ADDIS GPRC:$in, tblockaddress:$g)>; 1517 1518// Standard shifts. These are represented separately from the real shifts above 1519// so that we can distinguish between shifts that allow 5-bit and 6-bit shift 1520// amounts. 1521def : Pat<(sra GPRC:$rS, GPRC:$rB), 1522 (SRAW GPRC:$rS, GPRC:$rB)>; 1523def : Pat<(srl GPRC:$rS, GPRC:$rB), 1524 (SRW GPRC:$rS, GPRC:$rB)>; 1525def : Pat<(shl GPRC:$rS, GPRC:$rB), 1526 (SLW GPRC:$rS, GPRC:$rB)>; 1527 1528def : Pat<(zextloadi1 iaddr:$src), 1529 (LBZ iaddr:$src)>; 1530def : Pat<(zextloadi1 xaddr:$src), 1531 (LBZX xaddr:$src)>; 1532def : Pat<(extloadi1 iaddr:$src), 1533 (LBZ iaddr:$src)>; 1534def : Pat<(extloadi1 xaddr:$src), 1535 (LBZX xaddr:$src)>; 1536def : Pat<(extloadi8 iaddr:$src), 1537 (LBZ iaddr:$src)>; 1538def : Pat<(extloadi8 xaddr:$src), 1539 (LBZX xaddr:$src)>; 1540def : Pat<(extloadi16 iaddr:$src), 1541 (LHZ iaddr:$src)>; 1542def : Pat<(extloadi16 xaddr:$src), 1543 (LHZX xaddr:$src)>; 1544def : Pat<(f64 (extloadf32 iaddr:$src)), 1545 (COPY_TO_REGCLASS (LFS iaddr:$src), F8RC)>; 1546def : Pat<(f64 (extloadf32 xaddr:$src)), 1547 (COPY_TO_REGCLASS (LFSX xaddr:$src), F8RC)>; 1548 1549def : Pat<(f64 (fextend F4RC:$src)), 1550 (COPY_TO_REGCLASS F4RC:$src, F8RC)>; 1551 1552// Memory barriers 1553def : Pat<(membarrier (i32 imm /*ll*/), 1554 (i32 imm /*ls*/), 1555 (i32 imm /*sl*/), 1556 (i32 imm /*ss*/), 1557 (i32 imm /*device*/)), 1558 (SYNC)>; 1559 1560def : Pat<(atomic_fence (imm), (imm)), (SYNC)>; 1561 1562include "PPCInstrAltivec.td" 1563include "PPCInstr64Bit.td" 1564