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