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