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. 345 346def PPCRegGPRCAsmOperand : AsmOperandClass { 347 let Name = "RegGPRC"; let PredicateMethod = "isRegNumber"; 348} 349def gprc : RegisterOperand<GPRC> { 350 let ParserMatchClass = PPCRegGPRCAsmOperand; 351} 352def PPCRegG8RCAsmOperand : AsmOperandClass { 353 let Name = "RegG8RC"; let PredicateMethod = "isRegNumber"; 354} 355def g8rc : RegisterOperand<G8RC> { 356 let ParserMatchClass = PPCRegG8RCAsmOperand; 357} 358def PPCRegGPRCNoR0AsmOperand : AsmOperandClass { 359 let Name = "RegGPRCNoR0"; let PredicateMethod = "isRegNumber"; 360} 361def gprc_nor0 : RegisterOperand<GPRC_NOR0> { 362 let ParserMatchClass = PPCRegGPRCNoR0AsmOperand; 363} 364def PPCRegG8RCNoX0AsmOperand : AsmOperandClass { 365 let Name = "RegG8RCNoX0"; let PredicateMethod = "isRegNumber"; 366} 367def g8rc_nox0 : RegisterOperand<G8RC_NOX0> { 368 let ParserMatchClass = PPCRegG8RCNoX0AsmOperand; 369} 370def PPCRegF8RCAsmOperand : AsmOperandClass { 371 let Name = "RegF8RC"; let PredicateMethod = "isRegNumber"; 372} 373def f8rc : RegisterOperand<F8RC> { 374 let ParserMatchClass = PPCRegF8RCAsmOperand; 375} 376def PPCRegF4RCAsmOperand : AsmOperandClass { 377 let Name = "RegF4RC"; let PredicateMethod = "isRegNumber"; 378} 379def f4rc : RegisterOperand<F4RC> { 380 let ParserMatchClass = PPCRegF4RCAsmOperand; 381} 382def PPCRegVRRCAsmOperand : AsmOperandClass { 383 let Name = "RegVRRC"; let PredicateMethod = "isRegNumber"; 384} 385def vrrc : RegisterOperand<VRRC> { 386 let ParserMatchClass = PPCRegVRRCAsmOperand; 387} 388def PPCRegCRBITRCAsmOperand : AsmOperandClass { 389 let Name = "RegCRBITRC"; let PredicateMethod = "isRegNumber"; 390} 391def crbitrc : RegisterOperand<CRBITRC> { 392 let ParserMatchClass = PPCRegCRBITRCAsmOperand; 393} 394def PPCRegCRRCAsmOperand : AsmOperandClass { 395 let Name = "RegCRRC"; let PredicateMethod = "isCCRegNumber"; 396} 397def crrc : RegisterOperand<CRRC> { 398 let ParserMatchClass = PPCRegCRRCAsmOperand; 399} 400 401def PPCS5ImmAsmOperand : AsmOperandClass { 402 let Name = "S5Imm"; let PredicateMethod = "isS5Imm"; 403 let RenderMethod = "addImmOperands"; 404} 405def s5imm : Operand<i32> { 406 let PrintMethod = "printS5ImmOperand"; 407 let ParserMatchClass = PPCS5ImmAsmOperand; 408} 409def PPCU5ImmAsmOperand : AsmOperandClass { 410 let Name = "U5Imm"; let PredicateMethod = "isU5Imm"; 411 let RenderMethod = "addImmOperands"; 412} 413def u5imm : Operand<i32> { 414 let PrintMethod = "printU5ImmOperand"; 415 let ParserMatchClass = PPCU5ImmAsmOperand; 416} 417def PPCU6ImmAsmOperand : AsmOperandClass { 418 let Name = "U6Imm"; let PredicateMethod = "isU6Imm"; 419 let RenderMethod = "addImmOperands"; 420} 421def u6imm : Operand<i32> { 422 let PrintMethod = "printU6ImmOperand"; 423 let ParserMatchClass = PPCU6ImmAsmOperand; 424} 425def PPCS16ImmAsmOperand : AsmOperandClass { 426 let Name = "S16Imm"; let PredicateMethod = "isS16Imm"; 427 let RenderMethod = "addImmOperands"; 428} 429def s16imm : Operand<i32> { 430 let PrintMethod = "printS16ImmOperand"; 431 let ParserMatchClass = PPCS16ImmAsmOperand; 432} 433def PPCU16ImmAsmOperand : AsmOperandClass { 434 let Name = "U16Imm"; let PredicateMethod = "isU16Imm"; 435 let RenderMethod = "addImmOperands"; 436} 437def u16imm : Operand<i32> { 438 let PrintMethod = "printU16ImmOperand"; 439 let ParserMatchClass = PPCU16ImmAsmOperand; 440} 441def directbrtarget : Operand<OtherVT> { 442 let PrintMethod = "printBranchOperand"; 443 let EncoderMethod = "getDirectBrEncoding"; 444} 445def condbrtarget : Operand<OtherVT> { 446 let PrintMethod = "printBranchOperand"; 447 let EncoderMethod = "getCondBrEncoding"; 448} 449def calltarget : Operand<iPTR> { 450 let EncoderMethod = "getDirectBrEncoding"; 451} 452def aaddr : Operand<iPTR> { 453 let PrintMethod = "printAbsAddrOperand"; 454} 455def symbolHi: Operand<i32> { 456 let PrintMethod = "printSymbolHi"; 457 let EncoderMethod = "getHA16Encoding"; 458 let ParserMatchClass = PPCS16ImmAsmOperand; 459} 460def symbolLo: Operand<i32> { 461 let PrintMethod = "printSymbolLo"; 462 let EncoderMethod = "getLO16Encoding"; 463 let ParserMatchClass = PPCS16ImmAsmOperand; 464} 465def PPCCRBitMaskOperand : AsmOperandClass { 466 let Name = "CRBitMask"; let PredicateMethod = "isCRBitMask"; 467} 468def crbitm: Operand<i8> { 469 let PrintMethod = "printcrbitm"; 470 let EncoderMethod = "get_crbitm_encoding"; 471 let ParserMatchClass = PPCCRBitMaskOperand; 472} 473// Address operands 474// A version of ptr_rc which excludes R0 (or X0 in 64-bit mode). 475def PPCRegGxRCNoR0Operand : AsmOperandClass { 476 let Name = "RegGxRCNoR0"; let PredicateMethod = "isRegNumber"; 477} 478def ptr_rc_nor0 : Operand<iPTR>, PointerLikeRegClass<1> { 479 let ParserMatchClass = PPCRegGxRCNoR0Operand; 480} 481// A version of ptr_rc usable with the asm parser. 482def PPCRegGxRCOperand : AsmOperandClass { 483 let Name = "RegGxRC"; let PredicateMethod = "isRegNumber"; 484} 485def ptr_rc_idx : Operand<iPTR>, PointerLikeRegClass<0> { 486 let ParserMatchClass = PPCRegGxRCOperand; 487} 488 489def PPCDispRIOperand : AsmOperandClass { 490 let Name = "DispRI"; let PredicateMethod = "isS16Imm"; 491} 492def dispRI : Operand<iPTR> { 493 let ParserMatchClass = PPCDispRIOperand; 494} 495def PPCDispRIXOperand : AsmOperandClass { 496 let Name = "DispRIX"; let PredicateMethod = "isS16ImmX4"; 497} 498def dispRIX : Operand<iPTR> { 499 let ParserMatchClass = PPCDispRIXOperand; 500} 501 502def memri : Operand<iPTR> { 503 let PrintMethod = "printMemRegImm"; 504 let MIOperandInfo = (ops dispRI:$imm, ptr_rc_nor0:$reg); 505 let EncoderMethod = "getMemRIEncoding"; 506} 507def memrr : Operand<iPTR> { 508 let PrintMethod = "printMemRegReg"; 509 let MIOperandInfo = (ops ptr_rc_nor0:$ptrreg, ptr_rc_idx:$offreg); 510} 511def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits. 512 let PrintMethod = "printMemRegImmShifted"; 513 let MIOperandInfo = (ops dispRIX:$imm, ptr_rc_nor0:$reg); 514 let EncoderMethod = "getMemRIXEncoding"; 515} 516 517// A single-register address. This is used with the SjLj 518// pseudo-instructions. 519def memr : Operand<iPTR> { 520 let MIOperandInfo = (ops ptr_rc:$ptrreg); 521} 522 523// PowerPC Predicate operand. 524def pred : Operand<OtherVT> { 525 let PrintMethod = "printPredicateOperand"; 526 let MIOperandInfo = (ops i32imm:$bibo, crrc:$reg); 527} 528 529// Define PowerPC specific addressing mode. 530def iaddr : ComplexPattern<iPTR, 2, "SelectAddrImm", [], []>; 531def xaddr : ComplexPattern<iPTR, 2, "SelectAddrIdx", [], []>; 532def xoaddr : ComplexPattern<iPTR, 2, "SelectAddrIdxOnly",[], []>; 533def ixaddr : ComplexPattern<iPTR, 2, "SelectAddrImmShift", [], []>; // "std" 534 535// The address in a single register. This is used with the SjLj 536// pseudo-instructions. 537def addr : ComplexPattern<iPTR, 1, "SelectAddr",[], []>; 538 539/// This is just the offset part of iaddr, used for preinc. 540def iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>; 541 542//===----------------------------------------------------------------------===// 543// PowerPC Instruction Predicate Definitions. 544def In32BitMode : Predicate<"!PPCSubTarget.isPPC64()">; 545def In64BitMode : Predicate<"PPCSubTarget.isPPC64()">; 546def IsBookE : Predicate<"PPCSubTarget.isBookE()">; 547 548//===----------------------------------------------------------------------===// 549// PowerPC Multiclass Definitions. 550 551multiclass XForm_6r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, 552 string asmbase, string asmstr, InstrItinClass itin, 553 list<dag> pattern> { 554 let BaseName = asmbase in { 555 def NAME : XForm_6<opcode, xo, OOL, IOL, 556 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 557 pattern>, RecFormRel; 558 let Defs = [CR0] in 559 def o : XForm_6<opcode, xo, OOL, IOL, 560 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 561 []>, isDOT, RecFormRel; 562 } 563} 564 565multiclass XForm_6rc<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, 566 string asmbase, string asmstr, InstrItinClass itin, 567 list<dag> pattern> { 568 let BaseName = asmbase in { 569 let Defs = [CARRY] in 570 def NAME : XForm_6<opcode, xo, OOL, IOL, 571 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 572 pattern>, RecFormRel; 573 let Defs = [CARRY, CR0] in 574 def o : XForm_6<opcode, xo, OOL, IOL, 575 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 576 []>, isDOT, RecFormRel; 577 } 578} 579 580multiclass XForm_10r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, 581 string asmbase, string asmstr, InstrItinClass itin, 582 list<dag> pattern> { 583 let BaseName = asmbase in { 584 def NAME : XForm_10<opcode, xo, OOL, IOL, 585 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 586 pattern>, RecFormRel; 587 let Defs = [CR0] in 588 def o : XForm_10<opcode, xo, OOL, IOL, 589 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 590 []>, isDOT, RecFormRel; 591 } 592} 593 594multiclass XForm_10rc<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, 595 string asmbase, string asmstr, InstrItinClass itin, 596 list<dag> pattern> { 597 let BaseName = asmbase in { 598 let Defs = [CARRY] in 599 def NAME : XForm_10<opcode, xo, OOL, IOL, 600 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 601 pattern>, RecFormRel; 602 let Defs = [CARRY, CR0] in 603 def o : XForm_10<opcode, xo, OOL, IOL, 604 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 605 []>, isDOT, RecFormRel; 606 } 607} 608 609multiclass XForm_11r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, 610 string asmbase, string asmstr, InstrItinClass itin, 611 list<dag> pattern> { 612 let BaseName = asmbase in { 613 def NAME : XForm_11<opcode, xo, OOL, IOL, 614 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 615 pattern>, RecFormRel; 616 let Defs = [CR0] in 617 def o : XForm_11<opcode, xo, OOL, IOL, 618 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 619 []>, isDOT, RecFormRel; 620 } 621} 622 623multiclass XOForm_1r<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL, 624 string asmbase, string asmstr, InstrItinClass itin, 625 list<dag> pattern> { 626 let BaseName = asmbase in { 627 def NAME : XOForm_1<opcode, xo, oe, OOL, IOL, 628 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 629 pattern>, RecFormRel; 630 let Defs = [CR0] in 631 def o : XOForm_1<opcode, xo, oe, OOL, IOL, 632 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 633 []>, isDOT, RecFormRel; 634 } 635} 636 637multiclass XOForm_1rc<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL, 638 string asmbase, string asmstr, InstrItinClass itin, 639 list<dag> pattern> { 640 let BaseName = asmbase in { 641 let Defs = [CARRY] in 642 def NAME : XOForm_1<opcode, xo, oe, OOL, IOL, 643 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 644 pattern>, RecFormRel; 645 let Defs = [CARRY, CR0] in 646 def o : XOForm_1<opcode, xo, oe, OOL, IOL, 647 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 648 []>, isDOT, RecFormRel; 649 } 650} 651 652multiclass XOForm_3r<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL, 653 string asmbase, string asmstr, InstrItinClass itin, 654 list<dag> pattern> { 655 let BaseName = asmbase in { 656 def NAME : XOForm_3<opcode, xo, oe, OOL, IOL, 657 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 658 pattern>, RecFormRel; 659 let Defs = [CR0] in 660 def o : XOForm_3<opcode, xo, oe, OOL, IOL, 661 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 662 []>, isDOT, RecFormRel; 663 } 664} 665 666multiclass XOForm_3rc<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL, 667 string asmbase, string asmstr, InstrItinClass itin, 668 list<dag> pattern> { 669 let BaseName = asmbase in { 670 let Defs = [CARRY] in 671 def NAME : XOForm_3<opcode, xo, oe, OOL, IOL, 672 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 673 pattern>, RecFormRel; 674 let Defs = [CARRY, CR0] in 675 def o : XOForm_3<opcode, xo, oe, OOL, IOL, 676 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 677 []>, isDOT, RecFormRel; 678 } 679} 680 681multiclass MForm_2r<bits<6> opcode, dag OOL, dag IOL, 682 string asmbase, string asmstr, InstrItinClass itin, 683 list<dag> pattern> { 684 let BaseName = asmbase in { 685 def NAME : MForm_2<opcode, OOL, IOL, 686 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 687 pattern>, RecFormRel; 688 let Defs = [CR0] in 689 def o : MForm_2<opcode, OOL, IOL, 690 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 691 []>, isDOT, RecFormRel; 692 } 693} 694 695multiclass MDForm_1r<bits<6> opcode, bits<3> xo, dag OOL, dag IOL, 696 string asmbase, string asmstr, InstrItinClass itin, 697 list<dag> pattern> { 698 let BaseName = asmbase in { 699 def NAME : MDForm_1<opcode, xo, OOL, IOL, 700 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 701 pattern>, RecFormRel; 702 let Defs = [CR0] in 703 def o : MDForm_1<opcode, xo, OOL, IOL, 704 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 705 []>, isDOT, RecFormRel; 706 } 707} 708 709multiclass MDSForm_1r<bits<6> opcode, bits<4> xo, dag OOL, dag IOL, 710 string asmbase, string asmstr, InstrItinClass itin, 711 list<dag> pattern> { 712 let BaseName = asmbase in { 713 def NAME : MDSForm_1<opcode, xo, OOL, IOL, 714 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 715 pattern>, RecFormRel; 716 let Defs = [CR0] in 717 def o : MDSForm_1<opcode, xo, OOL, IOL, 718 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 719 []>, isDOT, RecFormRel; 720 } 721} 722 723multiclass XSForm_1rc<bits<6> opcode, bits<9> xo, dag OOL, dag IOL, 724 string asmbase, string asmstr, InstrItinClass itin, 725 list<dag> pattern> { 726 let BaseName = asmbase in { 727 let Defs = [CARRY] in 728 def NAME : XSForm_1<opcode, xo, OOL, IOL, 729 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 730 pattern>, RecFormRel; 731 let Defs = [CARRY, CR0] in 732 def o : XSForm_1<opcode, xo, OOL, IOL, 733 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 734 []>, isDOT, RecFormRel; 735 } 736} 737 738multiclass XForm_26r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, 739 string asmbase, string asmstr, InstrItinClass itin, 740 list<dag> pattern> { 741 let BaseName = asmbase in { 742 def NAME : XForm_26<opcode, xo, OOL, IOL, 743 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 744 pattern>, RecFormRel; 745 let Defs = [CR1] in 746 def o : XForm_26<opcode, xo, OOL, IOL, 747 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 748 []>, isDOT, RecFormRel; 749 } 750} 751 752multiclass AForm_1r<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, 753 string asmbase, string asmstr, InstrItinClass itin, 754 list<dag> pattern> { 755 let BaseName = asmbase in { 756 def NAME : AForm_1<opcode, xo, OOL, IOL, 757 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 758 pattern>, RecFormRel; 759 let Defs = [CR1] in 760 def o : AForm_1<opcode, xo, OOL, IOL, 761 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 762 []>, isDOT, RecFormRel; 763 } 764} 765 766multiclass AForm_2r<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, 767 string asmbase, string asmstr, InstrItinClass itin, 768 list<dag> pattern> { 769 let BaseName = asmbase in { 770 def NAME : AForm_2<opcode, xo, OOL, IOL, 771 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 772 pattern>, RecFormRel; 773 let Defs = [CR1] in 774 def o : AForm_2<opcode, xo, OOL, IOL, 775 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 776 []>, isDOT, RecFormRel; 777 } 778} 779 780multiclass AForm_3r<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, 781 string asmbase, string asmstr, InstrItinClass itin, 782 list<dag> pattern> { 783 let BaseName = asmbase in { 784 def NAME : AForm_3<opcode, xo, OOL, IOL, 785 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 786 pattern>, RecFormRel; 787 let Defs = [CR1] in 788 def o : AForm_3<opcode, xo, OOL, IOL, 789 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 790 []>, isDOT, RecFormRel; 791 } 792} 793 794//===----------------------------------------------------------------------===// 795// PowerPC Instruction Definitions. 796 797// Pseudo-instructions: 798 799let hasCtrlDep = 1 in { 800let Defs = [R1], Uses = [R1] in { 801def ADJCALLSTACKDOWN : Pseudo<(outs), (ins u16imm:$amt), "#ADJCALLSTACKDOWN $amt", 802 [(callseq_start timm:$amt)]>; 803def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2), "#ADJCALLSTACKUP $amt1 $amt2", 804 [(callseq_end timm:$amt1, timm:$amt2)]>; 805} 806 807def UPDATE_VRSAVE : Pseudo<(outs gprc:$rD), (ins gprc:$rS), 808 "UPDATE_VRSAVE $rD, $rS", []>; 809} 810 811let Defs = [R1], Uses = [R1] in 812def DYNALLOC : Pseudo<(outs gprc:$result), (ins gprc:$negsize, memri:$fpsi), "#DYNALLOC", 813 [(set i32:$result, 814 (PPCdynalloc i32:$negsize, iaddr:$fpsi))]>; 815 816// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 817// instruction selection into a branch sequence. 818let usesCustomInserter = 1, // Expanded after instruction selection. 819 PPC970_Single = 1 in { 820 // Note that SELECT_CC_I4 and SELECT_CC_I8 use the no-r0 register classes 821 // because either operand might become the first operand in an isel, and 822 // that operand cannot be r0. 823 def SELECT_CC_I4 : Pseudo<(outs gprc:$dst), (ins crrc:$cond, 824 gprc_nor0:$T, gprc_nor0:$F, 825 i32imm:$BROPC), "#SELECT_CC_I4", 826 []>; 827 def SELECT_CC_I8 : Pseudo<(outs g8rc:$dst), (ins crrc:$cond, 828 g8rc_nox0:$T, g8rc_nox0:$F, 829 i32imm:$BROPC), "#SELECT_CC_I8", 830 []>; 831 def SELECT_CC_F4 : Pseudo<(outs f4rc:$dst), (ins crrc:$cond, f4rc:$T, f4rc:$F, 832 i32imm:$BROPC), "#SELECT_CC_F4", 833 []>; 834 def SELECT_CC_F8 : Pseudo<(outs f8rc:$dst), (ins crrc:$cond, f8rc:$T, f8rc:$F, 835 i32imm:$BROPC), "#SELECT_CC_F8", 836 []>; 837 def SELECT_CC_VRRC: Pseudo<(outs vrrc:$dst), (ins crrc:$cond, vrrc:$T, vrrc:$F, 838 i32imm:$BROPC), "#SELECT_CC_VRRC", 839 []>; 840} 841 842// SPILL_CR - Indicate that we're dumping the CR register, so we'll need to 843// scavenge a register for it. 844let mayStore = 1 in 845def SPILL_CR : Pseudo<(outs), (ins crrc:$cond, memri:$F), 846 "#SPILL_CR", []>; 847 848// RESTORE_CR - Indicate that we're restoring the CR register (previously 849// spilled), so we'll need to scavenge a register for it. 850let mayLoad = 1 in 851def RESTORE_CR : Pseudo<(outs crrc:$cond), (ins memri:$F), 852 "#RESTORE_CR", []>; 853 854let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in { 855 let isReturn = 1, Uses = [LR, RM] in 856 def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (outs), (ins), "blr", BrB, 857 [(retflag)]>; 858 let isBranch = 1, isIndirectBranch = 1, Uses = [CTR] in { 859 def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>; 860 861 let isCodeGenOnly = 1 in 862 def BCCTR : XLForm_2_br<19, 528, 0, (outs), (ins pred:$cond), 863 "b${cond:cc}ctr ${cond:reg}", BrB, []>; 864 } 865} 866 867let Defs = [LR] in 868 def MovePCtoLR : Pseudo<(outs), (ins), "#MovePCtoLR", []>, 869 PPC970_Unit_BRU; 870 871let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in { 872 let isBarrier = 1 in { 873 def B : IForm<18, 0, 0, (outs), (ins directbrtarget:$dst), 874 "b $dst", BrB, 875 [(br bb:$dst)]>; 876 } 877 878 // BCC represents an arbitrary conditional branch on a predicate. 879 // FIXME: should be able to write a pattern for PPCcondbranch, but can't use 880 // a two-value operand where a dag node expects two operands. :( 881 let isCodeGenOnly = 1 in { 882 def BCC : BForm<16, 0, 0, (outs), (ins pred:$cond, condbrtarget:$dst), 883 "b${cond:cc} ${cond:reg}, $dst" 884 /*[(PPCcondbranch crrc:$crS, imm:$opc, bb:$dst)]*/>; 885 let isReturn = 1, Uses = [LR, RM] in 886 def BCLR : XLForm_2_br<19, 16, 0, (outs), (ins pred:$cond), 887 "b${cond:cc}lr ${cond:reg}", BrB, []>; 888 889 let isReturn = 1, Defs = [CTR], Uses = [CTR, LR, RM] in { 890 def BDZLR : XLForm_2_ext<19, 16, 18, 0, 0, (outs), (ins), 891 "bdzlr", BrB, []>; 892 def BDNZLR : XLForm_2_ext<19, 16, 16, 0, 0, (outs), (ins), 893 "bdnzlr", BrB, []>; 894 } 895 } 896 897 let Defs = [CTR], Uses = [CTR] in { 898 def BDZ : BForm_1<16, 18, 0, 0, (outs), (ins condbrtarget:$dst), 899 "bdz $dst">; 900 def BDNZ : BForm_1<16, 16, 0, 0, (outs), (ins condbrtarget:$dst), 901 "bdnz $dst">; 902 } 903} 904 905// The unconditional BCL used by the SjLj setjmp code. 906let isCall = 1, hasCtrlDep = 1, isCodeGenOnly = 1, PPC970_Unit = 7 in { 907 let Defs = [LR], Uses = [RM] in { 908 def BCLalways : BForm_2<16, 20, 31, 0, 1, (outs), (ins condbrtarget:$dst), 909 "bcl 20, 31, $dst">; 910 } 911} 912 913let isCall = 1, PPC970_Unit = 7, Defs = [LR] in { 914 // Convenient aliases for call instructions 915 let Uses = [RM] in { 916 def BL : IForm<18, 0, 1, (outs), (ins calltarget:$func), 917 "bl $func", BrB, []>; // See Pat patterns below. 918 def BLA : IForm<18, 1, 1, (outs), (ins aaddr:$func), 919 "bla $func", BrB, [(PPCcall (i32 imm:$func))]>; 920 } 921 let Uses = [CTR, RM] in { 922 def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins), 923 "bctrl", BrB, [(PPCbctrl)]>, 924 Requires<[In32BitMode]>; 925 926 let isCodeGenOnly = 1 in 927 def BCCTRL : XLForm_2_br<19, 528, 1, (outs), (ins pred:$cond), 928 "b${cond:cc}ctrl ${cond:reg}", BrB, []>; 929 } 930} 931 932let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in 933def TCRETURNdi :Pseudo< (outs), 934 (ins calltarget:$dst, i32imm:$offset), 935 "#TC_RETURNd $dst $offset", 936 []>; 937 938 939let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in 940def TCRETURNai :Pseudo<(outs), (ins aaddr:$func, i32imm:$offset), 941 "#TC_RETURNa $func $offset", 942 [(PPCtc_return (i32 imm:$func), imm:$offset)]>; 943 944let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in 945def TCRETURNri : Pseudo<(outs), (ins CTRRC:$dst, i32imm:$offset), 946 "#TC_RETURNr $dst $offset", 947 []>; 948 949 950let isCodeGenOnly = 1 in { 951 952let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, isBranch = 1, 953 isIndirectBranch = 1, isCall = 1, isReturn = 1, Uses = [CTR, RM] in 954def TAILBCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>, 955 Requires<[In32BitMode]>; 956 957 958 959let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7, 960 isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in 961def TAILB : IForm<18, 0, 0, (outs), (ins calltarget:$dst), 962 "b $dst", BrB, 963 []>; 964 965} 966 967let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7, 968 isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in 969def TAILBA : IForm<18, 0, 0, (outs), (ins aaddr:$dst), 970 "ba $dst", BrB, 971 []>; 972 973let hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in { 974 def EH_SjLj_SetJmp32 : Pseudo<(outs gprc:$dst), (ins memr:$buf), 975 "#EH_SJLJ_SETJMP32", 976 [(set i32:$dst, (PPCeh_sjlj_setjmp addr:$buf))]>, 977 Requires<[In32BitMode]>; 978 let isTerminator = 1 in 979 def EH_SjLj_LongJmp32 : Pseudo<(outs), (ins memr:$buf), 980 "#EH_SJLJ_LONGJMP32", 981 [(PPCeh_sjlj_longjmp addr:$buf)]>, 982 Requires<[In32BitMode]>; 983} 984 985let isBranch = 1, isTerminator = 1 in { 986 def EH_SjLj_Setup : Pseudo<(outs), (ins directbrtarget:$dst), 987 "#EH_SjLj_Setup\t$dst", []>; 988} 989 990// DCB* instructions. 991def DCBA : DCB_Form<758, 0, (outs), (ins memrr:$dst), 992 "dcba $dst", LdStDCBF, [(int_ppc_dcba xoaddr:$dst)]>, 993 PPC970_DGroup_Single; 994def DCBF : DCB_Form<86, 0, (outs), (ins memrr:$dst), 995 "dcbf $dst", LdStDCBF, [(int_ppc_dcbf xoaddr:$dst)]>, 996 PPC970_DGroup_Single; 997def DCBI : DCB_Form<470, 0, (outs), (ins memrr:$dst), 998 "dcbi $dst", LdStDCBF, [(int_ppc_dcbi xoaddr:$dst)]>, 999 PPC970_DGroup_Single; 1000def DCBST : DCB_Form<54, 0, (outs), (ins memrr:$dst), 1001 "dcbst $dst", LdStDCBF, [(int_ppc_dcbst xoaddr:$dst)]>, 1002 PPC970_DGroup_Single; 1003def DCBT : DCB_Form<278, 0, (outs), (ins memrr:$dst), 1004 "dcbt $dst", LdStDCBF, [(int_ppc_dcbt xoaddr:$dst)]>, 1005 PPC970_DGroup_Single; 1006def DCBTST : DCB_Form<246, 0, (outs), (ins memrr:$dst), 1007 "dcbtst $dst", LdStDCBF, [(int_ppc_dcbtst xoaddr:$dst)]>, 1008 PPC970_DGroup_Single; 1009def DCBZ : DCB_Form<1014, 0, (outs), (ins memrr:$dst), 1010 "dcbz $dst", LdStDCBF, [(int_ppc_dcbz xoaddr:$dst)]>, 1011 PPC970_DGroup_Single; 1012def DCBZL : DCB_Form<1014, 1, (outs), (ins memrr:$dst), 1013 "dcbzl $dst", LdStDCBF, [(int_ppc_dcbzl xoaddr:$dst)]>, 1014 PPC970_DGroup_Single; 1015 1016def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 1)), 1017 (DCBT xoaddr:$dst)>; 1018 1019// Atomic operations 1020let usesCustomInserter = 1 in { 1021 let Defs = [CR0] in { 1022 def ATOMIC_LOAD_ADD_I8 : Pseudo< 1023 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_ADD_I8", 1024 [(set i32:$dst, (atomic_load_add_8 xoaddr:$ptr, i32:$incr))]>; 1025 def ATOMIC_LOAD_SUB_I8 : Pseudo< 1026 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_SUB_I8", 1027 [(set i32:$dst, (atomic_load_sub_8 xoaddr:$ptr, i32:$incr))]>; 1028 def ATOMIC_LOAD_AND_I8 : Pseudo< 1029 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_AND_I8", 1030 [(set i32:$dst, (atomic_load_and_8 xoaddr:$ptr, i32:$incr))]>; 1031 def ATOMIC_LOAD_OR_I8 : Pseudo< 1032 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_OR_I8", 1033 [(set i32:$dst, (atomic_load_or_8 xoaddr:$ptr, i32:$incr))]>; 1034 def ATOMIC_LOAD_XOR_I8 : Pseudo< 1035 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "ATOMIC_LOAD_XOR_I8", 1036 [(set i32:$dst, (atomic_load_xor_8 xoaddr:$ptr, i32:$incr))]>; 1037 def ATOMIC_LOAD_NAND_I8 : Pseudo< 1038 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I8", 1039 [(set i32:$dst, (atomic_load_nand_8 xoaddr:$ptr, i32:$incr))]>; 1040 def ATOMIC_LOAD_ADD_I16 : Pseudo< 1041 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_ADD_I16", 1042 [(set i32:$dst, (atomic_load_add_16 xoaddr:$ptr, i32:$incr))]>; 1043 def ATOMIC_LOAD_SUB_I16 : Pseudo< 1044 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_SUB_I16", 1045 [(set i32:$dst, (atomic_load_sub_16 xoaddr:$ptr, i32:$incr))]>; 1046 def ATOMIC_LOAD_AND_I16 : Pseudo< 1047 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_AND_I16", 1048 [(set i32:$dst, (atomic_load_and_16 xoaddr:$ptr, i32:$incr))]>; 1049 def ATOMIC_LOAD_OR_I16 : Pseudo< 1050 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_OR_I16", 1051 [(set i32:$dst, (atomic_load_or_16 xoaddr:$ptr, i32:$incr))]>; 1052 def ATOMIC_LOAD_XOR_I16 : Pseudo< 1053 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_XOR_I16", 1054 [(set i32:$dst, (atomic_load_xor_16 xoaddr:$ptr, i32:$incr))]>; 1055 def ATOMIC_LOAD_NAND_I16 : Pseudo< 1056 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I16", 1057 [(set i32:$dst, (atomic_load_nand_16 xoaddr:$ptr, i32:$incr))]>; 1058 def ATOMIC_LOAD_ADD_I32 : Pseudo< 1059 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_ADD_I32", 1060 [(set i32:$dst, (atomic_load_add_32 xoaddr:$ptr, i32:$incr))]>; 1061 def ATOMIC_LOAD_SUB_I32 : Pseudo< 1062 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_SUB_I32", 1063 [(set i32:$dst, (atomic_load_sub_32 xoaddr:$ptr, i32:$incr))]>; 1064 def ATOMIC_LOAD_AND_I32 : Pseudo< 1065 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_AND_I32", 1066 [(set i32:$dst, (atomic_load_and_32 xoaddr:$ptr, i32:$incr))]>; 1067 def ATOMIC_LOAD_OR_I32 : Pseudo< 1068 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_OR_I32", 1069 [(set i32:$dst, (atomic_load_or_32 xoaddr:$ptr, i32:$incr))]>; 1070 def ATOMIC_LOAD_XOR_I32 : Pseudo< 1071 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_XOR_I32", 1072 [(set i32:$dst, (atomic_load_xor_32 xoaddr:$ptr, i32:$incr))]>; 1073 def ATOMIC_LOAD_NAND_I32 : Pseudo< 1074 (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I32", 1075 [(set i32:$dst, (atomic_load_nand_32 xoaddr:$ptr, i32:$incr))]>; 1076 1077 def ATOMIC_CMP_SWAP_I8 : Pseudo< 1078 (outs gprc:$dst), (ins memrr:$ptr, gprc:$old, gprc:$new), "#ATOMIC_CMP_SWAP_I8", 1079 [(set i32:$dst, (atomic_cmp_swap_8 xoaddr:$ptr, i32:$old, i32:$new))]>; 1080 def ATOMIC_CMP_SWAP_I16 : Pseudo< 1081 (outs gprc:$dst), (ins memrr:$ptr, gprc:$old, gprc:$new), "#ATOMIC_CMP_SWAP_I16 $dst $ptr $old $new", 1082 [(set i32:$dst, (atomic_cmp_swap_16 xoaddr:$ptr, i32:$old, i32:$new))]>; 1083 def ATOMIC_CMP_SWAP_I32 : Pseudo< 1084 (outs gprc:$dst), (ins memrr:$ptr, gprc:$old, gprc:$new), "#ATOMIC_CMP_SWAP_I32 $dst $ptr $old $new", 1085 [(set i32:$dst, (atomic_cmp_swap_32 xoaddr:$ptr, i32:$old, i32:$new))]>; 1086 1087 def ATOMIC_SWAP_I8 : Pseudo< 1088 (outs gprc:$dst), (ins memrr:$ptr, gprc:$new), "#ATOMIC_SWAP_i8", 1089 [(set i32:$dst, (atomic_swap_8 xoaddr:$ptr, i32:$new))]>; 1090 def ATOMIC_SWAP_I16 : Pseudo< 1091 (outs gprc:$dst), (ins memrr:$ptr, gprc:$new), "#ATOMIC_SWAP_I16", 1092 [(set i32:$dst, (atomic_swap_16 xoaddr:$ptr, i32:$new))]>; 1093 def ATOMIC_SWAP_I32 : Pseudo< 1094 (outs gprc:$dst), (ins memrr:$ptr, gprc:$new), "#ATOMIC_SWAP_I32", 1095 [(set i32:$dst, (atomic_swap_32 xoaddr:$ptr, i32:$new))]>; 1096 } 1097} 1098 1099// Instructions to support atomic operations 1100def LWARX : XForm_1<31, 20, (outs gprc:$rD), (ins memrr:$src), 1101 "lwarx $rD, $src", LdStLWARX, 1102 [(set i32:$rD, (PPClarx xoaddr:$src))]>; 1103 1104let Defs = [CR0] in 1105def STWCX : XForm_1<31, 150, (outs), (ins gprc:$rS, memrr:$dst), 1106 "stwcx. $rS, $dst", LdStSTWCX, 1107 [(PPCstcx i32:$rS, xoaddr:$dst)]>, 1108 isDOT; 1109 1110let isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in 1111def TRAP : XForm_24<31, 4, (outs), (ins), "trap", LdStLoad, [(trap)]>; 1112 1113//===----------------------------------------------------------------------===// 1114// PPC32 Load Instructions. 1115// 1116 1117// Unindexed (r+i) Loads. 1118let canFoldAsLoad = 1, PPC970_Unit = 2 in { 1119def LBZ : DForm_1<34, (outs gprc:$rD), (ins memri:$src), 1120 "lbz $rD, $src", LdStLoad, 1121 [(set i32:$rD, (zextloadi8 iaddr:$src))]>; 1122def LHA : DForm_1<42, (outs gprc:$rD), (ins memri:$src), 1123 "lha $rD, $src", LdStLHA, 1124 [(set i32:$rD, (sextloadi16 iaddr:$src))]>, 1125 PPC970_DGroup_Cracked; 1126def LHZ : DForm_1<40, (outs gprc:$rD), (ins memri:$src), 1127 "lhz $rD, $src", LdStLoad, 1128 [(set i32:$rD, (zextloadi16 iaddr:$src))]>; 1129def LWZ : DForm_1<32, (outs gprc:$rD), (ins memri:$src), 1130 "lwz $rD, $src", LdStLoad, 1131 [(set i32:$rD, (load iaddr:$src))]>; 1132 1133def LFS : DForm_1<48, (outs f4rc:$rD), (ins memri:$src), 1134 "lfs $rD, $src", LdStLFD, 1135 [(set f32:$rD, (load iaddr:$src))]>; 1136def LFD : DForm_1<50, (outs f8rc:$rD), (ins memri:$src), 1137 "lfd $rD, $src", LdStLFD, 1138 [(set f64:$rD, (load iaddr:$src))]>; 1139 1140 1141// Unindexed (r+i) Loads with Update (preinc). 1142let mayLoad = 1, neverHasSideEffects = 1 in { 1143def LBZU : DForm_1<35, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), 1144 "lbzu $rD, $addr", LdStLoadUpd, 1145 []>, RegConstraint<"$addr.reg = $ea_result">, 1146 NoEncode<"$ea_result">; 1147 1148def LHAU : DForm_1<43, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), 1149 "lhau $rD, $addr", LdStLHAU, 1150 []>, RegConstraint<"$addr.reg = $ea_result">, 1151 NoEncode<"$ea_result">; 1152 1153def LHZU : DForm_1<41, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), 1154 "lhzu $rD, $addr", LdStLoadUpd, 1155 []>, RegConstraint<"$addr.reg = $ea_result">, 1156 NoEncode<"$ea_result">; 1157 1158def LWZU : DForm_1<33, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), 1159 "lwzu $rD, $addr", LdStLoadUpd, 1160 []>, RegConstraint<"$addr.reg = $ea_result">, 1161 NoEncode<"$ea_result">; 1162 1163def LFSU : DForm_1<49, (outs f4rc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), 1164 "lfsu $rD, $addr", LdStLFDU, 1165 []>, RegConstraint<"$addr.reg = $ea_result">, 1166 NoEncode<"$ea_result">; 1167 1168def LFDU : DForm_1<51, (outs f8rc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), 1169 "lfdu $rD, $addr", LdStLFDU, 1170 []>, RegConstraint<"$addr.reg = $ea_result">, 1171 NoEncode<"$ea_result">; 1172 1173 1174// Indexed (r+r) Loads with Update (preinc). 1175def LBZUX : XForm_1<31, 119, (outs gprc:$rD, ptr_rc_nor0:$ea_result), 1176 (ins memrr:$addr), 1177 "lbzux $rD, $addr", LdStLoadUpd, 1178 []>, RegConstraint<"$addr.ptrreg = $ea_result">, 1179 NoEncode<"$ea_result">; 1180 1181def LHAUX : XForm_1<31, 375, (outs gprc:$rD, ptr_rc_nor0:$ea_result), 1182 (ins memrr:$addr), 1183 "lhaux $rD, $addr", LdStLHAU, 1184 []>, RegConstraint<"$addr.ptrreg = $ea_result">, 1185 NoEncode<"$ea_result">; 1186 1187def LHZUX : XForm_1<31, 311, (outs gprc:$rD, ptr_rc_nor0:$ea_result), 1188 (ins memrr:$addr), 1189 "lhzux $rD, $addr", LdStLoadUpd, 1190 []>, RegConstraint<"$addr.ptrreg = $ea_result">, 1191 NoEncode<"$ea_result">; 1192 1193def LWZUX : XForm_1<31, 55, (outs gprc:$rD, ptr_rc_nor0:$ea_result), 1194 (ins memrr:$addr), 1195 "lwzux $rD, $addr", LdStLoadUpd, 1196 []>, RegConstraint<"$addr.ptrreg = $ea_result">, 1197 NoEncode<"$ea_result">; 1198 1199def LFSUX : XForm_1<31, 567, (outs f4rc:$rD, ptr_rc_nor0:$ea_result), 1200 (ins memrr:$addr), 1201 "lfsux $rD, $addr", LdStLFDU, 1202 []>, RegConstraint<"$addr.ptrreg = $ea_result">, 1203 NoEncode<"$ea_result">; 1204 1205def LFDUX : XForm_1<31, 631, (outs f8rc:$rD, ptr_rc_nor0:$ea_result), 1206 (ins memrr:$addr), 1207 "lfdux $rD, $addr", LdStLFDU, 1208 []>, RegConstraint<"$addr.ptrreg = $ea_result">, 1209 NoEncode<"$ea_result">; 1210} 1211} 1212 1213// Indexed (r+r) Loads. 1214// 1215let canFoldAsLoad = 1, PPC970_Unit = 2 in { 1216def LBZX : XForm_1<31, 87, (outs gprc:$rD), (ins memrr:$src), 1217 "lbzx $rD, $src", LdStLoad, 1218 [(set i32:$rD, (zextloadi8 xaddr:$src))]>; 1219def LHAX : XForm_1<31, 343, (outs gprc:$rD), (ins memrr:$src), 1220 "lhax $rD, $src", LdStLHA, 1221 [(set i32:$rD, (sextloadi16 xaddr:$src))]>, 1222 PPC970_DGroup_Cracked; 1223def LHZX : XForm_1<31, 279, (outs gprc:$rD), (ins memrr:$src), 1224 "lhzx $rD, $src", LdStLoad, 1225 [(set i32:$rD, (zextloadi16 xaddr:$src))]>; 1226def LWZX : XForm_1<31, 23, (outs gprc:$rD), (ins memrr:$src), 1227 "lwzx $rD, $src", LdStLoad, 1228 [(set i32:$rD, (load xaddr:$src))]>; 1229 1230 1231def LHBRX : XForm_1<31, 790, (outs gprc:$rD), (ins memrr:$src), 1232 "lhbrx $rD, $src", LdStLoad, 1233 [(set i32:$rD, (PPClbrx xoaddr:$src, i16))]>; 1234def LWBRX : XForm_1<31, 534, (outs gprc:$rD), (ins memrr:$src), 1235 "lwbrx $rD, $src", LdStLoad, 1236 [(set i32:$rD, (PPClbrx xoaddr:$src, i32))]>; 1237 1238def LFSX : XForm_25<31, 535, (outs f4rc:$frD), (ins memrr:$src), 1239 "lfsx $frD, $src", LdStLFD, 1240 [(set f32:$frD, (load xaddr:$src))]>; 1241def LFDX : XForm_25<31, 599, (outs f8rc:$frD), (ins memrr:$src), 1242 "lfdx $frD, $src", LdStLFD, 1243 [(set f64:$frD, (load xaddr:$src))]>; 1244 1245def LFIWAX : XForm_25<31, 855, (outs f8rc:$frD), (ins memrr:$src), 1246 "lfiwax $frD, $src", LdStLFD, 1247 [(set f64:$frD, (PPClfiwax xoaddr:$src))]>; 1248def LFIWZX : XForm_25<31, 887, (outs f8rc:$frD), (ins memrr:$src), 1249 "lfiwzx $frD, $src", LdStLFD, 1250 [(set f64:$frD, (PPClfiwzx xoaddr:$src))]>; 1251} 1252 1253//===----------------------------------------------------------------------===// 1254// PPC32 Store Instructions. 1255// 1256 1257// Unindexed (r+i) Stores. 1258let PPC970_Unit = 2 in { 1259def STB : DForm_1<38, (outs), (ins gprc:$rS, memri:$src), 1260 "stb $rS, $src", LdStStore, 1261 [(truncstorei8 i32:$rS, iaddr:$src)]>; 1262def STH : DForm_1<44, (outs), (ins gprc:$rS, memri:$src), 1263 "sth $rS, $src", LdStStore, 1264 [(truncstorei16 i32:$rS, iaddr:$src)]>; 1265def STW : DForm_1<36, (outs), (ins gprc:$rS, memri:$src), 1266 "stw $rS, $src", LdStStore, 1267 [(store i32:$rS, iaddr:$src)]>; 1268def STFS : DForm_1<52, (outs), (ins f4rc:$rS, memri:$dst), 1269 "stfs $rS, $dst", LdStSTFD, 1270 [(store f32:$rS, iaddr:$dst)]>; 1271def STFD : DForm_1<54, (outs), (ins f8rc:$rS, memri:$dst), 1272 "stfd $rS, $dst", LdStSTFD, 1273 [(store f64:$rS, iaddr:$dst)]>; 1274} 1275 1276// Unindexed (r+i) Stores with Update (preinc). 1277let PPC970_Unit = 2, mayStore = 1 in { 1278def STBU : DForm_1<39, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memri:$dst), 1279 "stbu $rS, $dst", LdStStoreUpd, []>, 1280 RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">; 1281def STHU : DForm_1<45, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memri:$dst), 1282 "sthu $rS, $dst", LdStStoreUpd, []>, 1283 RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">; 1284def STWU : DForm_1<37, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memri:$dst), 1285 "stwu $rS, $dst", LdStStoreUpd, []>, 1286 RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">; 1287def STFSU : DForm_1<53, (outs ptr_rc_nor0:$ea_res), (ins f4rc:$rS, memri:$dst), 1288 "stfsu $rS, $dst", LdStSTFDU, []>, 1289 RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">; 1290def STFDU : DForm_1<55, (outs ptr_rc_nor0:$ea_res), (ins f8rc:$rS, memri:$dst), 1291 "stfdu $rS, $dst", LdStSTFDU, []>, 1292 RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">; 1293} 1294 1295// Patterns to match the pre-inc stores. We can't put the patterns on 1296// the instruction definitions directly as ISel wants the address base 1297// and offset to be separate operands, not a single complex operand. 1298def : Pat<(pre_truncsti8 i32:$rS, iPTR:$ptrreg, iaddroff:$ptroff), 1299 (STBU $rS, iaddroff:$ptroff, $ptrreg)>; 1300def : Pat<(pre_truncsti16 i32:$rS, iPTR:$ptrreg, iaddroff:$ptroff), 1301 (STHU $rS, iaddroff:$ptroff, $ptrreg)>; 1302def : Pat<(pre_store i32:$rS, iPTR:$ptrreg, iaddroff:$ptroff), 1303 (STWU $rS, iaddroff:$ptroff, $ptrreg)>; 1304def : Pat<(pre_store f32:$rS, iPTR:$ptrreg, iaddroff:$ptroff), 1305 (STFSU $rS, iaddroff:$ptroff, $ptrreg)>; 1306def : Pat<(pre_store f64:$rS, iPTR:$ptrreg, iaddroff:$ptroff), 1307 (STFDU $rS, iaddroff:$ptroff, $ptrreg)>; 1308 1309// Indexed (r+r) Stores. 1310let PPC970_Unit = 2 in { 1311def STBX : XForm_8<31, 215, (outs), (ins gprc:$rS, memrr:$dst), 1312 "stbx $rS, $dst", LdStStore, 1313 [(truncstorei8 i32:$rS, xaddr:$dst)]>, 1314 PPC970_DGroup_Cracked; 1315def STHX : XForm_8<31, 407, (outs), (ins gprc:$rS, memrr:$dst), 1316 "sthx $rS, $dst", LdStStore, 1317 [(truncstorei16 i32:$rS, xaddr:$dst)]>, 1318 PPC970_DGroup_Cracked; 1319def STWX : XForm_8<31, 151, (outs), (ins gprc:$rS, memrr:$dst), 1320 "stwx $rS, $dst", LdStStore, 1321 [(store i32:$rS, xaddr:$dst)]>, 1322 PPC970_DGroup_Cracked; 1323 1324def STHBRX: XForm_8<31, 918, (outs), (ins gprc:$rS, memrr:$dst), 1325 "sthbrx $rS, $dst", LdStStore, 1326 [(PPCstbrx i32:$rS, xoaddr:$dst, i16)]>, 1327 PPC970_DGroup_Cracked; 1328def STWBRX: XForm_8<31, 662, (outs), (ins gprc:$rS, memrr:$dst), 1329 "stwbrx $rS, $dst", LdStStore, 1330 [(PPCstbrx i32:$rS, xoaddr:$dst, i32)]>, 1331 PPC970_DGroup_Cracked; 1332 1333def STFIWX: XForm_28<31, 983, (outs), (ins f8rc:$frS, memrr:$dst), 1334 "stfiwx $frS, $dst", LdStSTFD, 1335 [(PPCstfiwx f64:$frS, xoaddr:$dst)]>; 1336 1337def STFSX : XForm_28<31, 663, (outs), (ins f4rc:$frS, memrr:$dst), 1338 "stfsx $frS, $dst", LdStSTFD, 1339 [(store f32:$frS, xaddr:$dst)]>; 1340def STFDX : XForm_28<31, 727, (outs), (ins f8rc:$frS, memrr:$dst), 1341 "stfdx $frS, $dst", LdStSTFD, 1342 [(store f64:$frS, xaddr:$dst)]>; 1343} 1344 1345// Indexed (r+r) Stores with Update (preinc). 1346let PPC970_Unit = 2, mayStore = 1 in { 1347def STBUX : XForm_8<31, 247, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memrr:$dst), 1348 "stbux $rS, $dst", LdStStoreUpd, []>, 1349 RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, 1350 PPC970_DGroup_Cracked; 1351def STHUX : XForm_8<31, 439, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memrr:$dst), 1352 "sthux $rS, $dst", LdStStoreUpd, []>, 1353 RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, 1354 PPC970_DGroup_Cracked; 1355def STWUX : XForm_8<31, 183, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memrr:$dst), 1356 "stwux $rS, $dst", LdStStoreUpd, []>, 1357 RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, 1358 PPC970_DGroup_Cracked; 1359def STFSUX: XForm_8<31, 695, (outs ptr_rc_nor0:$ea_res), (ins f4rc:$rS, memrr:$dst), 1360 "stfsux $rS, $dst", LdStSTFDU, []>, 1361 RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, 1362 PPC970_DGroup_Cracked; 1363def STFDUX: XForm_8<31, 759, (outs ptr_rc_nor0:$ea_res), (ins f8rc:$rS, memrr:$dst), 1364 "stfdux $rS, $dst", LdStSTFDU, []>, 1365 RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, 1366 PPC970_DGroup_Cracked; 1367} 1368 1369// Patterns to match the pre-inc stores. We can't put the patterns on 1370// the instruction definitions directly as ISel wants the address base 1371// and offset to be separate operands, not a single complex operand. 1372def : Pat<(pre_truncsti8 i32:$rS, iPTR:$ptrreg, iPTR:$ptroff), 1373 (STBUX $rS, $ptrreg, $ptroff)>; 1374def : Pat<(pre_truncsti16 i32:$rS, iPTR:$ptrreg, iPTR:$ptroff), 1375 (STHUX $rS, $ptrreg, $ptroff)>; 1376def : Pat<(pre_store i32:$rS, iPTR:$ptrreg, iPTR:$ptroff), 1377 (STWUX $rS, $ptrreg, $ptroff)>; 1378def : Pat<(pre_store f32:$rS, iPTR:$ptrreg, iPTR:$ptroff), 1379 (STFSUX $rS, $ptrreg, $ptroff)>; 1380def : Pat<(pre_store f64:$rS, iPTR:$ptrreg, iPTR:$ptroff), 1381 (STFDUX $rS, $ptrreg, $ptroff)>; 1382 1383def SYNC : XForm_24_sync<31, 598, (outs), (ins), 1384 "sync", LdStSync, 1385 [(int_ppc_sync)]>; 1386 1387//===----------------------------------------------------------------------===// 1388// PPC32 Arithmetic Instructions. 1389// 1390 1391let PPC970_Unit = 1 in { // FXU Operations. 1392def ADDI : DForm_2<14, (outs gprc:$rD), (ins gprc_nor0:$rA, symbolLo:$imm), 1393 "addi $rD, $rA, $imm", IntSimple, 1394 [(set i32:$rD, (add i32:$rA, immSExt16:$imm))]>; 1395let BaseName = "addic" in { 1396let Defs = [CARRY] in 1397def ADDIC : DForm_2<12, (outs gprc:$rD), (ins gprc:$rA, s16imm:$imm), 1398 "addic $rD, $rA, $imm", IntGeneral, 1399 [(set i32:$rD, (addc i32:$rA, immSExt16:$imm))]>, 1400 RecFormRel, PPC970_DGroup_Cracked; 1401let Defs = [CARRY, CR0] in 1402def ADDICo : DForm_2<13, (outs gprc:$rD), (ins gprc:$rA, s16imm:$imm), 1403 "addic. $rD, $rA, $imm", IntGeneral, 1404 []>, isDOT, RecFormRel; 1405} 1406def ADDIS : DForm_2<15, (outs gprc:$rD), (ins gprc_nor0:$rA, symbolHi:$imm), 1407 "addis $rD, $rA, $imm", IntSimple, 1408 [(set i32:$rD, (add i32:$rA, imm16ShiftedSExt:$imm))]>; 1409let isCodeGenOnly = 1 in 1410def LA : DForm_2<14, (outs gprc:$rD), (ins gprc_nor0:$rA, symbolLo:$sym), 1411 "la $rD, $sym($rA)", IntGeneral, 1412 [(set i32:$rD, (add i32:$rA, 1413 (PPClo tglobaladdr:$sym, 0)))]>; 1414def MULLI : DForm_2< 7, (outs gprc:$rD), (ins gprc:$rA, s16imm:$imm), 1415 "mulli $rD, $rA, $imm", IntMulLI, 1416 [(set i32:$rD, (mul i32:$rA, immSExt16:$imm))]>; 1417let Defs = [CARRY] in 1418def SUBFIC : DForm_2< 8, (outs gprc:$rD), (ins gprc:$rA, s16imm:$imm), 1419 "subfic $rD, $rA, $imm", IntGeneral, 1420 [(set i32:$rD, (subc immSExt16:$imm, i32:$rA))]>; 1421 1422let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in { 1423 def LI : DForm_2_r0<14, (outs gprc:$rD), (ins symbolLo:$imm), 1424 "li $rD, $imm", IntSimple, 1425 [(set i32:$rD, immSExt16:$imm)]>; 1426 def LIS : DForm_2_r0<15, (outs gprc:$rD), (ins symbolHi:$imm), 1427 "lis $rD, $imm", IntSimple, 1428 [(set i32:$rD, imm16ShiftedSExt:$imm)]>; 1429} 1430} 1431 1432let PPC970_Unit = 1 in { // FXU Operations. 1433let Defs = [CR0] in { 1434def ANDIo : DForm_4<28, (outs gprc:$dst), (ins gprc:$src1, u16imm:$src2), 1435 "andi. $dst, $src1, $src2", IntGeneral, 1436 [(set i32:$dst, (and i32:$src1, immZExt16:$src2))]>, 1437 isDOT; 1438def ANDISo : DForm_4<29, (outs gprc:$dst), (ins gprc:$src1, u16imm:$src2), 1439 "andis. $dst, $src1, $src2", IntGeneral, 1440 [(set i32:$dst, (and i32:$src1, imm16ShiftedZExt:$src2))]>, 1441 isDOT; 1442} 1443def ORI : DForm_4<24, (outs gprc:$dst), (ins gprc:$src1, u16imm:$src2), 1444 "ori $dst, $src1, $src2", IntSimple, 1445 [(set i32:$dst, (or i32:$src1, immZExt16:$src2))]>; 1446def ORIS : DForm_4<25, (outs gprc:$dst), (ins gprc:$src1, u16imm:$src2), 1447 "oris $dst, $src1, $src2", IntSimple, 1448 [(set i32:$dst, (or i32:$src1, imm16ShiftedZExt:$src2))]>; 1449def XORI : DForm_4<26, (outs gprc:$dst), (ins gprc:$src1, u16imm:$src2), 1450 "xori $dst, $src1, $src2", IntSimple, 1451 [(set i32:$dst, (xor i32:$src1, immZExt16:$src2))]>; 1452def XORIS : DForm_4<27, (outs gprc:$dst), (ins gprc:$src1, u16imm:$src2), 1453 "xoris $dst, $src1, $src2", IntSimple, 1454 [(set i32:$dst, (xor i32:$src1, imm16ShiftedZExt:$src2))]>; 1455def NOP : DForm_4_zero<24, (outs), (ins), "nop", IntSimple, 1456 []>; 1457let isCompare = 1, neverHasSideEffects = 1 in { 1458 def CMPWI : DForm_5_ext<11, (outs crrc:$crD), (ins gprc:$rA, s16imm:$imm), 1459 "cmpwi $crD, $rA, $imm", IntCompare>; 1460 def CMPLWI : DForm_6_ext<10, (outs crrc:$dst), (ins gprc:$src1, u16imm:$src2), 1461 "cmplwi $dst, $src1, $src2", IntCompare>; 1462} 1463} 1464 1465let PPC970_Unit = 1, neverHasSideEffects = 1 in { // FXU Operations. 1466defm NAND : XForm_6r<31, 476, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1467 "nand", "$rA, $rS, $rB", IntSimple, 1468 [(set i32:$rA, (not (and i32:$rS, i32:$rB)))]>; 1469defm AND : XForm_6r<31, 28, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1470 "and", "$rA, $rS, $rB", IntSimple, 1471 [(set i32:$rA, (and i32:$rS, i32:$rB))]>; 1472defm ANDC : XForm_6r<31, 60, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1473 "andc", "$rA, $rS, $rB", IntSimple, 1474 [(set i32:$rA, (and i32:$rS, (not i32:$rB)))]>; 1475defm OR : XForm_6r<31, 444, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1476 "or", "$rA, $rS, $rB", IntSimple, 1477 [(set i32:$rA, (or i32:$rS, i32:$rB))]>; 1478defm NOR : XForm_6r<31, 124, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1479 "nor", "$rA, $rS, $rB", IntSimple, 1480 [(set i32:$rA, (not (or i32:$rS, i32:$rB)))]>; 1481defm ORC : XForm_6r<31, 412, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1482 "orc", "$rA, $rS, $rB", IntSimple, 1483 [(set i32:$rA, (or i32:$rS, (not i32:$rB)))]>; 1484defm EQV : XForm_6r<31, 284, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1485 "eqv", "$rA, $rS, $rB", IntSimple, 1486 [(set i32:$rA, (not (xor i32:$rS, i32:$rB)))]>; 1487defm XOR : XForm_6r<31, 316, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1488 "xor", "$rA, $rS, $rB", IntSimple, 1489 [(set i32:$rA, (xor i32:$rS, i32:$rB))]>; 1490defm SLW : XForm_6r<31, 24, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1491 "slw", "$rA, $rS, $rB", IntGeneral, 1492 [(set i32:$rA, (PPCshl i32:$rS, i32:$rB))]>; 1493defm SRW : XForm_6r<31, 536, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1494 "srw", "$rA, $rS, $rB", IntGeneral, 1495 [(set i32:$rA, (PPCsrl i32:$rS, i32:$rB))]>; 1496defm SRAW : XForm_6rc<31, 792, (outs gprc:$rA), (ins gprc:$rS, gprc:$rB), 1497 "sraw", "$rA, $rS, $rB", IntShift, 1498 [(set i32:$rA, (PPCsra i32:$rS, i32:$rB))]>; 1499} 1500 1501let PPC970_Unit = 1 in { // FXU Operations. 1502let neverHasSideEffects = 1 in { 1503defm SRAWI : XForm_10rc<31, 824, (outs gprc:$rA), (ins gprc:$rS, u5imm:$SH), 1504 "srawi", "$rA, $rS, $SH", IntShift, 1505 [(set i32:$rA, (sra i32:$rS, (i32 imm:$SH)))]>; 1506defm CNTLZW : XForm_11r<31, 26, (outs gprc:$rA), (ins gprc:$rS), 1507 "cntlzw", "$rA, $rS", IntGeneral, 1508 [(set i32:$rA, (ctlz i32:$rS))]>; 1509defm EXTSB : XForm_11r<31, 954, (outs gprc:$rA), (ins gprc:$rS), 1510 "extsb", "$rA, $rS", IntSimple, 1511 [(set i32:$rA, (sext_inreg i32:$rS, i8))]>; 1512defm EXTSH : XForm_11r<31, 922, (outs gprc:$rA), (ins gprc:$rS), 1513 "extsh", "$rA, $rS", IntSimple, 1514 [(set i32:$rA, (sext_inreg i32:$rS, i16))]>; 1515} 1516let isCompare = 1, neverHasSideEffects = 1 in { 1517 def CMPW : XForm_16_ext<31, 0, (outs crrc:$crD), (ins gprc:$rA, gprc:$rB), 1518 "cmpw $crD, $rA, $rB", IntCompare>; 1519 def CMPLW : XForm_16_ext<31, 32, (outs crrc:$crD), (ins gprc:$rA, gprc:$rB), 1520 "cmplw $crD, $rA, $rB", IntCompare>; 1521} 1522} 1523let PPC970_Unit = 3 in { // FPU Operations. 1524//def FCMPO : XForm_17<63, 32, (outs CRRC:$crD), (ins FPRC:$fA, FPRC:$fB), 1525// "fcmpo $crD, $fA, $fB", FPCompare>; 1526let isCompare = 1, neverHasSideEffects = 1 in { 1527 def FCMPUS : XForm_17<63, 0, (outs crrc:$crD), (ins f4rc:$fA, f4rc:$fB), 1528 "fcmpu $crD, $fA, $fB", FPCompare>; 1529 def FCMPUD : XForm_17<63, 0, (outs crrc:$crD), (ins f8rc:$fA, f8rc:$fB), 1530 "fcmpu $crD, $fA, $fB", FPCompare>; 1531} 1532 1533let Uses = [RM] in { 1534 let neverHasSideEffects = 1 in { 1535 defm FCTIWZ : XForm_26r<63, 15, (outs f8rc:$frD), (ins f8rc:$frB), 1536 "fctiwz", "$frD, $frB", FPGeneral, 1537 [(set f64:$frD, (PPCfctiwz f64:$frB))]>; 1538 1539 defm FRSP : XForm_26r<63, 12, (outs f4rc:$frD), (ins f8rc:$frB), 1540 "frsp", "$frD, $frB", FPGeneral, 1541 [(set f32:$frD, (fround f64:$frB))]>; 1542 1543 // The frin -> nearbyint mapping is valid only in fast-math mode. 1544 let Interpretation64Bit = 1 in 1545 defm FRIND : XForm_26r<63, 392, (outs f8rc:$frD), (ins f8rc:$frB), 1546 "frin", "$frD, $frB", FPGeneral, 1547 [(set f64:$frD, (fnearbyint f64:$frB))]>; 1548 defm FRINS : XForm_26r<63, 392, (outs f4rc:$frD), (ins f4rc:$frB), 1549 "frin", "$frD, $frB", FPGeneral, 1550 [(set f32:$frD, (fnearbyint f32:$frB))]>; 1551 } 1552 1553 // These pseudos expand to rint but also set FE_INEXACT when the result does 1554 // not equal the argument. 1555 let usesCustomInserter = 1, Defs = [RM] in { // FIXME: Model FPSCR! 1556 def FRINDrint : Pseudo<(outs f8rc:$frD), (ins f8rc:$frB), 1557 "#FRINDrint", [(set f64:$frD, (frint f64:$frB))]>; 1558 def FRINSrint : Pseudo<(outs f4rc:$frD), (ins f4rc:$frB), 1559 "#FRINSrint", [(set f32:$frD, (frint f32:$frB))]>; 1560 } 1561 1562 let neverHasSideEffects = 1 in { 1563 let Interpretation64Bit = 1 in 1564 defm FRIPD : XForm_26r<63, 456, (outs f8rc:$frD), (ins f8rc:$frB), 1565 "frip", "$frD, $frB", FPGeneral, 1566 [(set f64:$frD, (fceil f64:$frB))]>; 1567 defm FRIPS : XForm_26r<63, 456, (outs f4rc:$frD), (ins f4rc:$frB), 1568 "frip", "$frD, $frB", FPGeneral, 1569 [(set f32:$frD, (fceil f32:$frB))]>; 1570 let Interpretation64Bit = 1 in 1571 defm FRIZD : XForm_26r<63, 424, (outs f8rc:$frD), (ins f8rc:$frB), 1572 "friz", "$frD, $frB", FPGeneral, 1573 [(set f64:$frD, (ftrunc f64:$frB))]>; 1574 defm FRIZS : XForm_26r<63, 424, (outs f4rc:$frD), (ins f4rc:$frB), 1575 "friz", "$frD, $frB", FPGeneral, 1576 [(set f32:$frD, (ftrunc f32:$frB))]>; 1577 let Interpretation64Bit = 1 in 1578 defm FRIMD : XForm_26r<63, 488, (outs f8rc:$frD), (ins f8rc:$frB), 1579 "frim", "$frD, $frB", FPGeneral, 1580 [(set f64:$frD, (ffloor f64:$frB))]>; 1581 defm FRIMS : XForm_26r<63, 488, (outs f4rc:$frD), (ins f4rc:$frB), 1582 "frim", "$frD, $frB", FPGeneral, 1583 [(set f32:$frD, (ffloor f32:$frB))]>; 1584 1585 defm FSQRT : XForm_26r<63, 22, (outs f8rc:$frD), (ins f8rc:$frB), 1586 "fsqrt", "$frD, $frB", FPSqrt, 1587 [(set f64:$frD, (fsqrt f64:$frB))]>; 1588 defm FSQRTS : XForm_26r<59, 22, (outs f4rc:$frD), (ins f4rc:$frB), 1589 "fsqrts", "$frD, $frB", FPSqrt, 1590 [(set f32:$frD, (fsqrt f32:$frB))]>; 1591 } 1592 } 1593} 1594 1595/// Note that FMR is defined as pseudo-ops on the PPC970 because they are 1596/// often coalesced away and we don't want the dispatch group builder to think 1597/// that they will fill slots (which could cause the load of a LSU reject to 1598/// sneak into a d-group with a store). 1599let neverHasSideEffects = 1 in 1600defm FMR : XForm_26r<63, 72, (outs f4rc:$frD), (ins f4rc:$frB), 1601 "fmr", "$frD, $frB", FPGeneral, 1602 []>, // (set f32:$frD, f32:$frB) 1603 PPC970_Unit_Pseudo; 1604 1605let PPC970_Unit = 3, neverHasSideEffects = 1 in { // FPU Operations. 1606// These are artificially split into two different forms, for 4/8 byte FP. 1607defm FABSS : XForm_26r<63, 264, (outs f4rc:$frD), (ins f4rc:$frB), 1608 "fabs", "$frD, $frB", FPGeneral, 1609 [(set f32:$frD, (fabs f32:$frB))]>; 1610let Interpretation64Bit = 1 in 1611defm FABSD : XForm_26r<63, 264, (outs f8rc:$frD), (ins f8rc:$frB), 1612 "fabs", "$frD, $frB", FPGeneral, 1613 [(set f64:$frD, (fabs f64:$frB))]>; 1614defm FNABSS : XForm_26r<63, 136, (outs f4rc:$frD), (ins f4rc:$frB), 1615 "fnabs", "$frD, $frB", FPGeneral, 1616 [(set f32:$frD, (fneg (fabs f32:$frB)))]>; 1617let Interpretation64Bit = 1 in 1618defm FNABSD : XForm_26r<63, 136, (outs f8rc:$frD), (ins f8rc:$frB), 1619 "fnabs", "$frD, $frB", FPGeneral, 1620 [(set f64:$frD, (fneg (fabs f64:$frB)))]>; 1621defm FNEGS : XForm_26r<63, 40, (outs f4rc:$frD), (ins f4rc:$frB), 1622 "fneg", "$frD, $frB", FPGeneral, 1623 [(set f32:$frD, (fneg f32:$frB))]>; 1624let Interpretation64Bit = 1 in 1625defm FNEGD : XForm_26r<63, 40, (outs f8rc:$frD), (ins f8rc:$frB), 1626 "fneg", "$frD, $frB", FPGeneral, 1627 [(set f64:$frD, (fneg f64:$frB))]>; 1628 1629// Reciprocal estimates. 1630defm FRE : XForm_26r<63, 24, (outs f8rc:$frD), (ins f8rc:$frB), 1631 "fre", "$frD, $frB", FPGeneral, 1632 [(set f64:$frD, (PPCfre f64:$frB))]>; 1633defm FRES : XForm_26r<59, 24, (outs f4rc:$frD), (ins f4rc:$frB), 1634 "fres", "$frD, $frB", FPGeneral, 1635 [(set f32:$frD, (PPCfre f32:$frB))]>; 1636defm FRSQRTE : XForm_26r<63, 26, (outs f8rc:$frD), (ins f8rc:$frB), 1637 "frsqrte", "$frD, $frB", FPGeneral, 1638 [(set f64:$frD, (PPCfrsqrte f64:$frB))]>; 1639defm FRSQRTES : XForm_26r<59, 26, (outs f4rc:$frD), (ins f4rc:$frB), 1640 "frsqrtes", "$frD, $frB", FPGeneral, 1641 [(set f32:$frD, (PPCfrsqrte f32:$frB))]>; 1642} 1643 1644// XL-Form instructions. condition register logical ops. 1645// 1646let neverHasSideEffects = 1 in 1647def MCRF : XLForm_3<19, 0, (outs crrc:$BF), (ins crrc:$BFA), 1648 "mcrf $BF, $BFA", BrMCR>, 1649 PPC970_DGroup_First, PPC970_Unit_CRU; 1650 1651def CREQV : XLForm_1<19, 289, (outs crbitrc:$CRD), 1652 (ins crbitrc:$CRA, crbitrc:$CRB), 1653 "creqv $CRD, $CRA, $CRB", BrCR, 1654 []>; 1655 1656def CROR : XLForm_1<19, 449, (outs crbitrc:$CRD), 1657 (ins crbitrc:$CRA, crbitrc:$CRB), 1658 "cror $CRD, $CRA, $CRB", BrCR, 1659 []>; 1660 1661let isCodeGenOnly = 1 in { 1662def CRSET : XLForm_1_ext<19, 289, (outs crbitrc:$dst), (ins), 1663 "creqv $dst, $dst, $dst", BrCR, 1664 []>; 1665 1666def CRUNSET: XLForm_1_ext<19, 193, (outs crbitrc:$dst), (ins), 1667 "crxor $dst, $dst, $dst", BrCR, 1668 []>; 1669 1670let Defs = [CR1EQ], CRD = 6 in { 1671def CR6SET : XLForm_1_ext<19, 289, (outs), (ins), 1672 "creqv 6, 6, 6", BrCR, 1673 [(PPCcr6set)]>; 1674 1675def CR6UNSET: XLForm_1_ext<19, 193, (outs), (ins), 1676 "crxor 6, 6, 6", BrCR, 1677 [(PPCcr6unset)]>; 1678} 1679} 1680 1681// XFX-Form instructions. Instructions that deal with SPRs. 1682// 1683let Uses = [CTR] in { 1684def MFCTR : XFXForm_1_ext<31, 339, 9, (outs gprc:$rT), (ins), 1685 "mfctr $rT", SprMFSPR>, 1686 PPC970_DGroup_First, PPC970_Unit_FXU; 1687} 1688let Defs = [CTR], Pattern = [(PPCmtctr i32:$rS)] in { 1689def MTCTR : XFXForm_7_ext<31, 467, 9, (outs), (ins gprc:$rS), 1690 "mtctr $rS", SprMTSPR>, 1691 PPC970_DGroup_First, PPC970_Unit_FXU; 1692} 1693 1694let Defs = [LR] in { 1695def MTLR : XFXForm_7_ext<31, 467, 8, (outs), (ins gprc:$rS), 1696 "mtlr $rS", SprMTSPR>, 1697 PPC970_DGroup_First, PPC970_Unit_FXU; 1698} 1699let Uses = [LR] in { 1700def MFLR : XFXForm_1_ext<31, 339, 8, (outs gprc:$rT), (ins), 1701 "mflr $rT", SprMFSPR>, 1702 PPC970_DGroup_First, PPC970_Unit_FXU; 1703} 1704 1705// Move to/from VRSAVE: despite being a SPR, the VRSAVE register is renamed like 1706// a GPR on the PPC970. As such, copies in and out have the same performance 1707// characteristics as an OR instruction. 1708def MTVRSAVE : XFXForm_7_ext<31, 467, 256, (outs), (ins gprc:$rS), 1709 "mtspr 256, $rS", IntGeneral>, 1710 PPC970_DGroup_Single, PPC970_Unit_FXU; 1711def MFVRSAVE : XFXForm_1_ext<31, 339, 256, (outs gprc:$rT), (ins), 1712 "mfspr $rT, 256", IntGeneral>, 1713 PPC970_DGroup_First, PPC970_Unit_FXU; 1714 1715let isCodeGenOnly = 1 in { 1716 def MTVRSAVEv : XFXForm_7_ext<31, 467, 256, 1717 (outs VRSAVERC:$reg), (ins gprc:$rS), 1718 "mtspr 256, $rS", IntGeneral>, 1719 PPC970_DGroup_Single, PPC970_Unit_FXU; 1720 def MFVRSAVEv : XFXForm_1_ext<31, 339, 256, (outs gprc:$rT), 1721 (ins VRSAVERC:$reg), 1722 "mfspr $rT, 256", IntGeneral>, 1723 PPC970_DGroup_First, PPC970_Unit_FXU; 1724} 1725 1726// SPILL_VRSAVE - Indicate that we're dumping the VRSAVE register, 1727// so we'll need to scavenge a register for it. 1728let mayStore = 1 in 1729def SPILL_VRSAVE : Pseudo<(outs), (ins VRSAVERC:$vrsave, memri:$F), 1730 "#SPILL_VRSAVE", []>; 1731 1732// RESTORE_VRSAVE - Indicate that we're restoring the VRSAVE register (previously 1733// spilled), so we'll need to scavenge a register for it. 1734let mayLoad = 1 in 1735def RESTORE_VRSAVE : Pseudo<(outs VRSAVERC:$vrsave), (ins memri:$F), 1736 "#RESTORE_VRSAVE", []>; 1737 1738let neverHasSideEffects = 1 in { 1739def MTCRF : XFXForm_5<31, 144, (outs crbitm:$FXM), (ins gprc:$rS), 1740 "mtcrf $FXM, $rS", BrMCRX>, 1741 PPC970_MicroCode, PPC970_Unit_CRU; 1742 1743// This is a pseudo for MFCR, which implicitly uses all 8 of its subregisters; 1744// declaring that here gives the local register allocator problems with this: 1745// vreg = MCRF CR0 1746// MFCR <kill of whatever preg got assigned to vreg> 1747// while not declaring it breaks DeadMachineInstructionElimination. 1748// As it turns out, in all cases where we currently use this, 1749// we're only interested in one subregister of it. Represent this in the 1750// instruction to keep the register allocator from becoming confused. 1751// 1752// FIXME: Make this a real Pseudo instruction when the JIT switches to MC. 1753let isCodeGenOnly = 1 in 1754def MFCRpseud: XFXForm_3<31, 19, (outs gprc:$rT), (ins crbitm:$FXM), 1755 "#MFCRpseud", SprMFCR>, 1756 PPC970_MicroCode, PPC970_Unit_CRU; 1757 1758def MFOCRF: XFXForm_5a<31, 19, (outs gprc:$rT), (ins crbitm:$FXM), 1759 "mfocrf $rT, $FXM", SprMFCR>, 1760 PPC970_DGroup_First, PPC970_Unit_CRU; 1761} // neverHasSideEffects = 1 1762 1763let neverHasSideEffects = 1 in 1764def MFCR : XFXForm_3<31, 19, (outs gprc:$rT), (ins), 1765 "mfcr $rT", SprMFCR>, 1766 PPC970_MicroCode, PPC970_Unit_CRU; 1767 1768// Pseudo instruction to perform FADD in round-to-zero mode. 1769let usesCustomInserter = 1, Uses = [RM] in { 1770 def FADDrtz: Pseudo<(outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), "", 1771 [(set f64:$FRT, (PPCfaddrtz f64:$FRA, f64:$FRB))]>; 1772} 1773 1774// The above pseudo gets expanded to make use of the following instructions 1775// to manipulate FPSCR. Note that FPSCR is not modeled at the DAG level. 1776let Uses = [RM], Defs = [RM] in { 1777 def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM), 1778 "mtfsb0 $FM", IntMTFSB0, []>, 1779 PPC970_DGroup_Single, PPC970_Unit_FPU; 1780 def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM), 1781 "mtfsb1 $FM", IntMTFSB0, []>, 1782 PPC970_DGroup_Single, PPC970_Unit_FPU; 1783 def MTFSF : XFLForm<63, 711, (outs), (ins i32imm:$FM, f8rc:$rT), 1784 "mtfsf $FM, $rT", IntMTFSB0, []>, 1785 PPC970_DGroup_Single, PPC970_Unit_FPU; 1786} 1787let Uses = [RM] in { 1788 def MFFS : XForm_42<63, 583, (outs f8rc:$rT), (ins), 1789 "mffs $rT", IntMFFS, 1790 [(set f64:$rT, (PPCmffs))]>, 1791 PPC970_DGroup_Single, PPC970_Unit_FPU; 1792} 1793 1794 1795let PPC970_Unit = 1, neverHasSideEffects = 1 in { // FXU Operations. 1796// XO-Form instructions. Arithmetic instructions that can set overflow bit 1797// 1798defm ADD4 : XOForm_1r<31, 266, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1799 "add", "$rT, $rA, $rB", IntSimple, 1800 [(set i32:$rT, (add i32:$rA, i32:$rB))]>; 1801defm ADDC : XOForm_1rc<31, 10, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1802 "addc", "$rT, $rA, $rB", IntGeneral, 1803 [(set i32:$rT, (addc i32:$rA, i32:$rB))]>, 1804 PPC970_DGroup_Cracked; 1805defm DIVW : XOForm_1r<31, 491, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1806 "divw", "$rT, $rA, $rB", IntDivW, 1807 [(set i32:$rT, (sdiv i32:$rA, i32:$rB))]>, 1808 PPC970_DGroup_First, PPC970_DGroup_Cracked; 1809defm DIVWU : XOForm_1r<31, 459, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1810 "divwu", "$rT, $rA, $rB", IntDivW, 1811 [(set i32:$rT, (udiv i32:$rA, i32:$rB))]>, 1812 PPC970_DGroup_First, PPC970_DGroup_Cracked; 1813defm MULHW : XOForm_1r<31, 75, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1814 "mulhw", "$rT, $rA, $rB", IntMulHW, 1815 [(set i32:$rT, (mulhs i32:$rA, i32:$rB))]>; 1816defm MULHWU : XOForm_1r<31, 11, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1817 "mulhwu", "$rT, $rA, $rB", IntMulHWU, 1818 [(set i32:$rT, (mulhu i32:$rA, i32:$rB))]>; 1819defm MULLW : XOForm_1r<31, 235, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1820 "mullw", "$rT, $rA, $rB", IntMulHW, 1821 [(set i32:$rT, (mul i32:$rA, i32:$rB))]>; 1822defm SUBF : XOForm_1r<31, 40, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1823 "subf", "$rT, $rA, $rB", IntGeneral, 1824 [(set i32:$rT, (sub i32:$rB, i32:$rA))]>; 1825defm SUBFC : XOForm_1rc<31, 8, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1826 "subfc", "$rT, $rA, $rB", IntGeneral, 1827 [(set i32:$rT, (subc i32:$rB, i32:$rA))]>, 1828 PPC970_DGroup_Cracked; 1829defm NEG : XOForm_3r<31, 104, 0, (outs gprc:$rT), (ins gprc:$rA), 1830 "neg", "$rT, $rA", IntSimple, 1831 [(set i32:$rT, (ineg i32:$rA))]>; 1832let Uses = [CARRY] in { 1833defm ADDE : XOForm_1rc<31, 138, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1834 "adde", "$rT, $rA, $rB", IntGeneral, 1835 [(set i32:$rT, (adde i32:$rA, i32:$rB))]>; 1836defm ADDME : XOForm_3rc<31, 234, 0, (outs gprc:$rT), (ins gprc:$rA), 1837 "addme", "$rT, $rA", IntGeneral, 1838 [(set i32:$rT, (adde i32:$rA, -1))]>; 1839defm ADDZE : XOForm_3rc<31, 202, 0, (outs gprc:$rT), (ins gprc:$rA), 1840 "addze", "$rT, $rA", IntGeneral, 1841 [(set i32:$rT, (adde i32:$rA, 0))]>; 1842defm SUBFE : XOForm_1rc<31, 136, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB), 1843 "subfe", "$rT, $rA, $rB", IntGeneral, 1844 [(set i32:$rT, (sube i32:$rB, i32:$rA))]>; 1845defm SUBFME : XOForm_3rc<31, 232, 0, (outs gprc:$rT), (ins gprc:$rA), 1846 "subfme", "$rT, $rA", IntGeneral, 1847 [(set i32:$rT, (sube -1, i32:$rA))]>; 1848defm SUBFZE : XOForm_3rc<31, 200, 0, (outs gprc:$rT), (ins gprc:$rA), 1849 "subfze", "$rT, $rA", IntGeneral, 1850 [(set i32:$rT, (sube 0, i32:$rA))]>; 1851} 1852} 1853 1854// A-Form instructions. Most of the instructions executed in the FPU are of 1855// this type. 1856// 1857let PPC970_Unit = 3, neverHasSideEffects = 1 in { // FPU Operations. 1858let Uses = [RM] in { 1859 defm FMADD : AForm_1r<63, 29, 1860 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB), 1861 "fmadd", "$FRT, $FRA, $FRC, $FRB", FPFused, 1862 [(set f64:$FRT, (fma f64:$FRA, f64:$FRC, f64:$FRB))]>; 1863 defm FMADDS : AForm_1r<59, 29, 1864 (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC, f4rc:$FRB), 1865 "fmadds", "$FRT, $FRA, $FRC, $FRB", FPGeneral, 1866 [(set f32:$FRT, (fma f32:$FRA, f32:$FRC, f32:$FRB))]>; 1867 defm FMSUB : AForm_1r<63, 28, 1868 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB), 1869 "fmsub", "$FRT, $FRA, $FRC, $FRB", FPFused, 1870 [(set f64:$FRT, 1871 (fma f64:$FRA, f64:$FRC, (fneg f64:$FRB)))]>; 1872 defm FMSUBS : AForm_1r<59, 28, 1873 (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC, f4rc:$FRB), 1874 "fmsubs", "$FRT, $FRA, $FRC, $FRB", FPGeneral, 1875 [(set f32:$FRT, 1876 (fma f32:$FRA, f32:$FRC, (fneg f32:$FRB)))]>; 1877 defm FNMADD : AForm_1r<63, 31, 1878 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB), 1879 "fnmadd", "$FRT, $FRA, $FRC, $FRB", FPFused, 1880 [(set f64:$FRT, 1881 (fneg (fma f64:$FRA, f64:$FRC, f64:$FRB)))]>; 1882 defm FNMADDS : AForm_1r<59, 31, 1883 (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC, f4rc:$FRB), 1884 "fnmadds", "$FRT, $FRA, $FRC, $FRB", FPGeneral, 1885 [(set f32:$FRT, 1886 (fneg (fma f32:$FRA, f32:$FRC, f32:$FRB)))]>; 1887 defm FNMSUB : AForm_1r<63, 30, 1888 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB), 1889 "fnmsub", "$FRT, $FRA, $FRC, $FRB", FPFused, 1890 [(set f64:$FRT, (fneg (fma f64:$FRA, f64:$FRC, 1891 (fneg f64:$FRB))))]>; 1892 defm FNMSUBS : AForm_1r<59, 30, 1893 (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC, f4rc:$FRB), 1894 "fnmsubs", "$FRT, $FRA, $FRC, $FRB", FPGeneral, 1895 [(set f32:$FRT, (fneg (fma f32:$FRA, f32:$FRC, 1896 (fneg f32:$FRB))))]>; 1897} 1898// FSEL is artificially split into 4 and 8-byte forms for the result. To avoid 1899// having 4 of these, force the comparison to always be an 8-byte double (code 1900// should use an FMRSD if the input comparison value really wants to be a float) 1901// and 4/8 byte forms for the result and operand type.. 1902let Interpretation64Bit = 1 in 1903defm FSELD : AForm_1r<63, 23, 1904 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB), 1905 "fsel", "$FRT, $FRA, $FRC, $FRB", FPGeneral, 1906 [(set f64:$FRT, (PPCfsel f64:$FRA, f64:$FRC, f64:$FRB))]>; 1907defm FSELS : AForm_1r<63, 23, 1908 (outs f4rc:$FRT), (ins f8rc:$FRA, f4rc:$FRC, f4rc:$FRB), 1909 "fsel", "$FRT, $FRA, $FRC, $FRB", FPGeneral, 1910 [(set f32:$FRT, (PPCfsel f64:$FRA, f32:$FRC, f32:$FRB))]>; 1911let Uses = [RM] in { 1912 defm FADD : AForm_2r<63, 21, 1913 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), 1914 "fadd", "$FRT, $FRA, $FRB", FPAddSub, 1915 [(set f64:$FRT, (fadd f64:$FRA, f64:$FRB))]>; 1916 defm FADDS : AForm_2r<59, 21, 1917 (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB), 1918 "fadds", "$FRT, $FRA, $FRB", FPGeneral, 1919 [(set f32:$FRT, (fadd f32:$FRA, f32:$FRB))]>; 1920 defm FDIV : AForm_2r<63, 18, 1921 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), 1922 "fdiv", "$FRT, $FRA, $FRB", FPDivD, 1923 [(set f64:$FRT, (fdiv f64:$FRA, f64:$FRB))]>; 1924 defm FDIVS : AForm_2r<59, 18, 1925 (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB), 1926 "fdivs", "$FRT, $FRA, $FRB", FPDivS, 1927 [(set f32:$FRT, (fdiv f32:$FRA, f32:$FRB))]>; 1928 defm FMUL : AForm_3r<63, 25, 1929 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC), 1930 "fmul", "$FRT, $FRA, $FRC", FPFused, 1931 [(set f64:$FRT, (fmul f64:$FRA, f64:$FRC))]>; 1932 defm FMULS : AForm_3r<59, 25, 1933 (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC), 1934 "fmuls", "$FRT, $FRA, $FRC", FPGeneral, 1935 [(set f32:$FRT, (fmul f32:$FRA, f32:$FRC))]>; 1936 defm FSUB : AForm_2r<63, 20, 1937 (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), 1938 "fsub", "$FRT, $FRA, $FRB", FPAddSub, 1939 [(set f64:$FRT, (fsub f64:$FRA, f64:$FRB))]>; 1940 defm FSUBS : AForm_2r<59, 20, 1941 (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB), 1942 "fsubs", "$FRT, $FRA, $FRB", FPGeneral, 1943 [(set f32:$FRT, (fsub f32:$FRA, f32:$FRB))]>; 1944 } 1945} 1946 1947let neverHasSideEffects = 1 in { 1948let PPC970_Unit = 1 in { // FXU Operations. 1949 let isSelect = 1 in 1950 def ISEL : AForm_4<31, 15, 1951 (outs gprc:$rT), (ins gprc_nor0:$rA, gprc:$rB, crbitrc:$cond), 1952 "isel $rT, $rA, $rB, $cond", IntGeneral, 1953 []>; 1954} 1955 1956let PPC970_Unit = 1 in { // FXU Operations. 1957// M-Form instructions. rotate and mask instructions. 1958// 1959let isCommutable = 1 in { 1960// RLWIMI can be commuted if the rotate amount is zero. 1961defm RLWIMI : MForm_2r<20, (outs gprc:$rA), 1962 (ins gprc:$rSi, gprc:$rS, u5imm:$SH, u5imm:$MB, 1963 u5imm:$ME), "rlwimi", "$rA, $rS, $SH, $MB, $ME", IntRotate, 1964 []>, PPC970_DGroup_Cracked, RegConstraint<"$rSi = $rA">, 1965 NoEncode<"$rSi">; 1966} 1967let BaseName = "rlwinm" in { 1968def RLWINM : MForm_2<21, 1969 (outs gprc:$rA), (ins gprc:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), 1970 "rlwinm $rA, $rS, $SH, $MB, $ME", IntGeneral, 1971 []>, RecFormRel; 1972let Defs = [CR0] in 1973def RLWINMo : MForm_2<21, 1974 (outs gprc:$rA), (ins gprc:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), 1975 "rlwinm. $rA, $rS, $SH, $MB, $ME", IntGeneral, 1976 []>, isDOT, RecFormRel, PPC970_DGroup_Cracked; 1977} 1978defm RLWNM : MForm_2r<23, (outs gprc:$rA), 1979 (ins gprc:$rS, gprc:$rB, u5imm:$MB, u5imm:$ME), 1980 "rlwnm", "$rA, $rS, $rB, $MB, $ME", IntGeneral, 1981 []>; 1982} 1983} // neverHasSideEffects = 1 1984 1985//===----------------------------------------------------------------------===// 1986// PowerPC Instruction Patterns 1987// 1988 1989// Arbitrary immediate support. Implement in terms of LIS/ORI. 1990def : Pat<(i32 imm:$imm), 1991 (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>; 1992 1993// Implement the 'not' operation with the NOR instruction. 1994def NOT : Pat<(not i32:$in), 1995 (NOR $in, $in)>; 1996 1997// ADD an arbitrary immediate. 1998def : Pat<(add i32:$in, imm:$imm), 1999 (ADDIS (ADDI $in, (LO16 imm:$imm)), (HA16 imm:$imm))>; 2000// OR an arbitrary immediate. 2001def : Pat<(or i32:$in, imm:$imm), 2002 (ORIS (ORI $in, (LO16 imm:$imm)), (HI16 imm:$imm))>; 2003// XOR an arbitrary immediate. 2004def : Pat<(xor i32:$in, imm:$imm), 2005 (XORIS (XORI $in, (LO16 imm:$imm)), (HI16 imm:$imm))>; 2006// SUBFIC 2007def : Pat<(sub immSExt16:$imm, i32:$in), 2008 (SUBFIC $in, imm:$imm)>; 2009 2010// SHL/SRL 2011def : Pat<(shl i32:$in, (i32 imm:$imm)), 2012 (RLWINM $in, imm:$imm, 0, (SHL32 imm:$imm))>; 2013def : Pat<(srl i32:$in, (i32 imm:$imm)), 2014 (RLWINM $in, (SRL32 imm:$imm), imm:$imm, 31)>; 2015 2016// ROTL 2017def : Pat<(rotl i32:$in, i32:$sh), 2018 (RLWNM $in, $sh, 0, 31)>; 2019def : Pat<(rotl i32:$in, (i32 imm:$imm)), 2020 (RLWINM $in, imm:$imm, 0, 31)>; 2021 2022// RLWNM 2023def : Pat<(and (rotl i32:$in, i32:$sh), maskimm32:$imm), 2024 (RLWNM $in, $sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>; 2025 2026// Calls 2027def : Pat<(PPCcall (i32 tglobaladdr:$dst)), 2028 (BL tglobaladdr:$dst)>; 2029def : Pat<(PPCcall (i32 texternalsym:$dst)), 2030 (BL texternalsym:$dst)>; 2031 2032 2033def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm), 2034 (TCRETURNdi tglobaladdr:$dst, imm:$imm)>; 2035 2036def : Pat<(PPCtc_return (i32 texternalsym:$dst), imm:$imm), 2037 (TCRETURNdi texternalsym:$dst, imm:$imm)>; 2038 2039def : Pat<(PPCtc_return CTRRC:$dst, imm:$imm), 2040 (TCRETURNri CTRRC:$dst, imm:$imm)>; 2041 2042 2043 2044// Hi and Lo for Darwin Global Addresses. 2045def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>; 2046def : Pat<(PPClo tglobaladdr:$in, 0), (LI tglobaladdr:$in)>; 2047def : Pat<(PPChi tconstpool:$in, 0), (LIS tconstpool:$in)>; 2048def : Pat<(PPClo tconstpool:$in, 0), (LI tconstpool:$in)>; 2049def : Pat<(PPChi tjumptable:$in, 0), (LIS tjumptable:$in)>; 2050def : Pat<(PPClo tjumptable:$in, 0), (LI tjumptable:$in)>; 2051def : Pat<(PPChi tblockaddress:$in, 0), (LIS tblockaddress:$in)>; 2052def : Pat<(PPClo tblockaddress:$in, 0), (LI tblockaddress:$in)>; 2053def : Pat<(PPChi tglobaltlsaddr:$g, i32:$in), 2054 (ADDIS $in, tglobaltlsaddr:$g)>; 2055def : Pat<(PPClo tglobaltlsaddr:$g, i32:$in), 2056 (ADDI $in, tglobaltlsaddr:$g)>; 2057def : Pat<(add i32:$in, (PPChi tglobaladdr:$g, 0)), 2058 (ADDIS $in, tglobaladdr:$g)>; 2059def : Pat<(add i32:$in, (PPChi tconstpool:$g, 0)), 2060 (ADDIS $in, tconstpool:$g)>; 2061def : Pat<(add i32:$in, (PPChi tjumptable:$g, 0)), 2062 (ADDIS $in, tjumptable:$g)>; 2063def : Pat<(add i32:$in, (PPChi tblockaddress:$g, 0)), 2064 (ADDIS $in, tblockaddress:$g)>; 2065 2066// Standard shifts. These are represented separately from the real shifts above 2067// so that we can distinguish between shifts that allow 5-bit and 6-bit shift 2068// amounts. 2069def : Pat<(sra i32:$rS, i32:$rB), 2070 (SRAW $rS, $rB)>; 2071def : Pat<(srl i32:$rS, i32:$rB), 2072 (SRW $rS, $rB)>; 2073def : Pat<(shl i32:$rS, i32:$rB), 2074 (SLW $rS, $rB)>; 2075 2076def : Pat<(zextloadi1 iaddr:$src), 2077 (LBZ iaddr:$src)>; 2078def : Pat<(zextloadi1 xaddr:$src), 2079 (LBZX xaddr:$src)>; 2080def : Pat<(extloadi1 iaddr:$src), 2081 (LBZ iaddr:$src)>; 2082def : Pat<(extloadi1 xaddr:$src), 2083 (LBZX xaddr:$src)>; 2084def : Pat<(extloadi8 iaddr:$src), 2085 (LBZ iaddr:$src)>; 2086def : Pat<(extloadi8 xaddr:$src), 2087 (LBZX xaddr:$src)>; 2088def : Pat<(extloadi16 iaddr:$src), 2089 (LHZ iaddr:$src)>; 2090def : Pat<(extloadi16 xaddr:$src), 2091 (LHZX xaddr:$src)>; 2092def : Pat<(f64 (extloadf32 iaddr:$src)), 2093 (COPY_TO_REGCLASS (LFS iaddr:$src), F8RC)>; 2094def : Pat<(f64 (extloadf32 xaddr:$src)), 2095 (COPY_TO_REGCLASS (LFSX xaddr:$src), F8RC)>; 2096 2097def : Pat<(f64 (fextend f32:$src)), 2098 (COPY_TO_REGCLASS $src, F8RC)>; 2099 2100def : Pat<(atomic_fence (imm), (imm)), (SYNC)>; 2101 2102// Additional FNMSUB patterns: -a*c + b == -(a*c - b) 2103def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B), 2104 (FNMSUB $A, $C, $B)>; 2105def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B), 2106 (FNMSUB $A, $C, $B)>; 2107def : Pat<(fma (fneg f32:$A), f32:$C, f32:$B), 2108 (FNMSUBS $A, $C, $B)>; 2109def : Pat<(fma f32:$A, (fneg f32:$C), f32:$B), 2110 (FNMSUBS $A, $C, $B)>; 2111 2112include "PPCInstrAltivec.td" 2113include "PPCInstr64Bit.td" 2114 2115 2116//===----------------------------------------------------------------------===// 2117// PowerPC Instructions used for assembler/disassembler only 2118// 2119 2120def ISYNC : XLForm_2_ext<19, 150, 0, 0, 0, (outs), (ins), 2121 "isync", SprISYNC, []>; 2122 2123def ICBI : XForm_1a<31, 982, (outs), (ins memrr:$src), 2124 "icbi $src", LdStICBI, []>; 2125 2126//===----------------------------------------------------------------------===// 2127// PowerPC Assembler Instruction Aliases 2128// 2129 2130// Pseudo-instructions for alternate assembly syntax (never used by codegen). 2131// These are aliases that require C++ handling to convert to the target 2132// instruction, while InstAliases can be handled directly by tblgen. 2133class PPCAsmPseudo<string asm, dag iops> 2134 : Instruction { 2135 let Namespace = "PPC"; 2136 bit PPC64 = 0; // Default value, override with isPPC64 2137 2138 let OutOperandList = (outs); 2139 let InOperandList = iops; 2140 let Pattern = []; 2141 let AsmString = asm; 2142 let isAsmParserOnly = 1; 2143 let isPseudo = 1; 2144} 2145 2146def : InstAlias<"mr $rA, $rB", (OR8 g8rc:$rA, g8rc:$rB, g8rc:$rB)>; 2147 2148def SLWI : PPCAsmPseudo<"slwi $rA, $rS, $n", 2149 (ins gprc:$rA, gprc:$rS, u5imm:$n)>; 2150def SRWI : PPCAsmPseudo<"srwi $rA, $rS, $n", 2151 (ins gprc:$rA, gprc:$rS, u5imm:$n)>; 2152def SLDI : PPCAsmPseudo<"sldi $rA, $rS, $n", 2153 (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>; 2154def SRDI : PPCAsmPseudo<"srdi $rA, $rS, $n", 2155 (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>; 2156 2157def : InstAlias<"blt $cc, $dst", (BCC 12, crrc:$cc, condbrtarget:$dst)>; 2158def : InstAlias<"bgt $cc, $dst", (BCC 44, crrc:$cc, condbrtarget:$dst)>; 2159def : InstAlias<"beq $cc, $dst", (BCC 76, crrc:$cc, condbrtarget:$dst)>; 2160def : InstAlias<"bun $cc, $dst", (BCC 108, crrc:$cc, condbrtarget:$dst)>; 2161def : InstAlias<"bso $cc, $dst", (BCC 108, crrc:$cc, condbrtarget:$dst)>; 2162def : InstAlias<"bge $cc, $dst", (BCC 4, crrc:$cc, condbrtarget:$dst)>; 2163def : InstAlias<"bnl $cc, $dst", (BCC 4, crrc:$cc, condbrtarget:$dst)>; 2164def : InstAlias<"ble $cc, $dst", (BCC 36, crrc:$cc, condbrtarget:$dst)>; 2165def : InstAlias<"bng $cc, $dst", (BCC 36, crrc:$cc, condbrtarget:$dst)>; 2166def : InstAlias<"bne $cc, $dst", (BCC 68, crrc:$cc, condbrtarget:$dst)>; 2167def : InstAlias<"bnu $cc, $dst", (BCC 100, crrc:$cc, condbrtarget:$dst)>; 2168def : InstAlias<"bns $cc, $dst", (BCC 100, crrc:$cc, condbrtarget:$dst)>; 2169 2170def : InstAlias<"bltlr $cc", (BCLR 12, crrc:$cc)>; 2171def : InstAlias<"bgtlr $cc", (BCLR 44, crrc:$cc)>; 2172def : InstAlias<"beqlr $cc", (BCLR 76, crrc:$cc)>; 2173def : InstAlias<"bunlr $cc", (BCLR 108, crrc:$cc)>; 2174def : InstAlias<"bsolr $cc", (BCLR 108, crrc:$cc)>; 2175def : InstAlias<"bgelr $cc", (BCLR 4, crrc:$cc)>; 2176def : InstAlias<"bnllr $cc", (BCLR 4, crrc:$cc)>; 2177def : InstAlias<"blelr $cc", (BCLR 36, crrc:$cc)>; 2178def : InstAlias<"bnglr $cc", (BCLR 36, crrc:$cc)>; 2179def : InstAlias<"bnelr $cc", (BCLR 68, crrc:$cc)>; 2180def : InstAlias<"bnulr $cc", (BCLR 100, crrc:$cc)>; 2181def : InstAlias<"bnslr $cc", (BCLR 100, crrc:$cc)>; 2182 2183def : InstAlias<"bltctr $cc", (BCCTR 12, crrc:$cc)>; 2184def : InstAlias<"bgtctr $cc", (BCCTR 44, crrc:$cc)>; 2185def : InstAlias<"beqctr $cc", (BCCTR 76, crrc:$cc)>; 2186def : InstAlias<"bunctr $cc", (BCCTR 108, crrc:$cc)>; 2187def : InstAlias<"bsoctr $cc", (BCCTR 108, crrc:$cc)>; 2188def : InstAlias<"bgectr $cc", (BCCTR 4, crrc:$cc)>; 2189def : InstAlias<"bnlctr $cc", (BCCTR 4, crrc:$cc)>; 2190def : InstAlias<"blectr $cc", (BCCTR 36, crrc:$cc)>; 2191def : InstAlias<"bngctr $cc", (BCCTR 36, crrc:$cc)>; 2192def : InstAlias<"bnectr $cc", (BCCTR 68, crrc:$cc)>; 2193def : InstAlias<"bnuctr $cc", (BCCTR 100, crrc:$cc)>; 2194def : InstAlias<"bnsctr $cc", (BCCTR 100, crrc:$cc)>; 2195 2196def : InstAlias<"bltctrl $cc", (BCCTRL 12, crrc:$cc)>; 2197def : InstAlias<"bgtctrl $cc", (BCCTRL 44, crrc:$cc)>; 2198def : InstAlias<"beqctrl $cc", (BCCTRL 76, crrc:$cc)>; 2199def : InstAlias<"bunctrl $cc", (BCCTRL 108, crrc:$cc)>; 2200def : InstAlias<"bsoctrl $cc", (BCCTRL 108, crrc:$cc)>; 2201def : InstAlias<"bgectrl $cc", (BCCTRL 4, crrc:$cc)>; 2202def : InstAlias<"bnlctrl $cc", (BCCTRL 4, crrc:$cc)>; 2203def : InstAlias<"blectrl $cc", (BCCTRL 36, crrc:$cc)>; 2204def : InstAlias<"bngctrl $cc", (BCCTRL 36, crrc:$cc)>; 2205def : InstAlias<"bnectrl $cc", (BCCTRL 68, crrc:$cc)>; 2206def : InstAlias<"bnuctrl $cc", (BCCTRL 100, crrc:$cc)>; 2207def : InstAlias<"bnsctrl $cc", (BCCTRL 100, crrc:$cc)>; 2208 2209