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