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