ARMInstrInfo.td revision 24ad3be2dbdf34a342afe90a17a4ec846a2c16de
1//===- ARMInstrInfo.td - Target Description for ARM Target -*- 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 ARM instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// ARM specific DAG Nodes. 16// 17 18// Type profiles. 19def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 20def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; 21 22def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>; 23 24def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 25 26def SDT_ARMCMov : SDTypeProfile<1, 3, 27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 28 SDTCisVT<3, i32>]>; 29 30def SDT_ARMBrcond : SDTypeProfile<0, 2, 31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 32 33def SDT_ARMBrJT : SDTypeProfile<0, 3, 34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 35 SDTCisVT<2, i32>]>; 36 37def SDT_ARMBr2JT : SDTypeProfile<0, 4, 38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 40 41def SDT_ARMBCC_i64 : SDTypeProfile<0, 6, 42 [SDTCisVT<0, i32>, 43 SDTCisVT<1, i32>, SDTCisVT<2, i32>, 44 SDTCisVT<3, i32>, SDTCisVT<4, i32>, 45 SDTCisVT<5, OtherVT>]>; 46 47def SDT_ARMAnd : SDTypeProfile<1, 2, 48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 49 SDTCisVT<2, i32>]>; 50 51def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 52 53def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, 54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; 55 56def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; 57def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>, 58 SDTCisInt<2>]>; 59def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>; 60 61def SDT_ARMMEMBARRIER : SDTypeProfile<0, 0, []>; 62def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>; 63def SDT_ARMMEMBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 64def SDT_ARMSYNCBARRIERMCR : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 65 66def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 67 68def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 69 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 70 71// Node definitions. 72def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; 73def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; 74 75def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, 76 [SDNPHasChain, SDNPOutFlag]>; 77def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd, 78 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 79 80def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall, 81 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, 82 SDNPVariadic]>; 83def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall, 84 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, 85 SDNPVariadic]>; 86def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall, 87 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, 88 SDNPVariadic]>; 89 90def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone, 91 [SDNPHasChain, SDNPOptInFlag]>; 92 93def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, 94 [SDNPInFlag]>; 95def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov, 96 [SDNPInFlag]>; 97 98def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, 99 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; 100 101def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, 102 [SDNPHasChain]>; 103def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT, 104 [SDNPHasChain]>; 105 106def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64, 107 [SDNPHasChain]>; 108 109def ARMand : SDNode<"ARMISD::AND", SDT_ARMAnd, 110 [SDNPOutFlag]>; 111 112def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, 113 [SDNPOutFlag]>; 114 115def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, 116 [SDNPOutFlag, SDNPCommutative]>; 117 118def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; 119 120def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; 121def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; 122def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>; 123 124def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; 125def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", 126 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>; 127def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP", 128 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>; 129 130def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER, 131 [SDNPHasChain]>; 132def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER, 133 [SDNPHasChain]>; 134def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERMCR, 135 [SDNPHasChain]>; 136def ARMSyncBarrierMCR : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERMCR, 137 [SDNPHasChain]>; 138 139def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>; 140 141def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET, 142 [SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>; 143 144 145def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>; 146 147//===----------------------------------------------------------------------===// 148// ARM Instruction Predicate Definitions. 149// 150def HasV4T : Predicate<"Subtarget->hasV4TOps()">; 151def NoV4T : Predicate<"!Subtarget->hasV4TOps()">; 152def HasV5T : Predicate<"Subtarget->hasV5TOps()">; 153def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">; 154def HasV6 : Predicate<"Subtarget->hasV6Ops()">; 155def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">; 156def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; 157def HasV7 : Predicate<"Subtarget->hasV7Ops()">; 158def NoVFP : Predicate<"!Subtarget->hasVFP2()">; 159def HasVFP2 : Predicate<"Subtarget->hasVFP2()">; 160def HasVFP3 : Predicate<"Subtarget->hasVFP3()">; 161def HasNEON : Predicate<"Subtarget->hasNEON()">; 162def HasDivide : Predicate<"Subtarget->hasDivide()">; 163def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">; 164def HasDB : Predicate<"Subtarget->hasDataBarrier()">; 165def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; 166def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; 167def IsThumb : Predicate<"Subtarget->isThumb()">; 168def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; 169def IsThumb2 : Predicate<"Subtarget->isThumb2()">; 170def IsARM : Predicate<"!Subtarget->isThumb()">; 171def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; 172def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; 173 174// FIXME: Eventually this will be just "hasV6T2Ops". 175def UseMovt : Predicate<"Subtarget->useMovt()">; 176def DontUseMovt : Predicate<"!Subtarget->useMovt()">; 177def UseVMLx : Predicate<"Subtarget->useVMLx()">; 178 179//===----------------------------------------------------------------------===// 180// ARM Flag Definitions. 181 182class RegConstraint<string C> { 183 string Constraints = C; 184} 185 186//===----------------------------------------------------------------------===// 187// ARM specific transformation functions and pattern fragments. 188// 189 190// so_imm_neg_XFORM - Return a so_imm value packed into the format described for 191// so_imm_neg def below. 192def so_imm_neg_XFORM : SDNodeXForm<imm, [{ 193 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 194}]>; 195 196// so_imm_not_XFORM - Return a so_imm value packed into the format described for 197// so_imm_not def below. 198def so_imm_not_XFORM : SDNodeXForm<imm, [{ 199 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32); 200}]>; 201 202// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24. 203def rot_imm : PatLeaf<(i32 imm), [{ 204 int32_t v = (int32_t)N->getZExtValue(); 205 return v == 8 || v == 16 || v == 24; 206}]>; 207 208/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15]. 209def imm1_15 : PatLeaf<(i32 imm), [{ 210 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16; 211}]>; 212 213/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31]. 214def imm16_31 : PatLeaf<(i32 imm), [{ 215 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32; 216}]>; 217 218def so_imm_neg : 219 PatLeaf<(imm), [{ 220 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1; 221 }], so_imm_neg_XFORM>; 222 223def so_imm_not : 224 PatLeaf<(imm), [{ 225 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1; 226 }], so_imm_not_XFORM>; 227 228// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits. 229def sext_16_node : PatLeaf<(i32 GPR:$a), [{ 230 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17; 231}]>; 232 233/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield 234/// e.g., 0xf000ffff 235def bf_inv_mask_imm : Operand<i32>, 236 PatLeaf<(imm), [{ 237 return ARM::isBitFieldInvertedMask(N->getZExtValue()); 238}] > { 239 let PrintMethod = "printBitfieldInvMaskImmOperand"; 240} 241 242/// Split a 32-bit immediate into two 16 bit parts. 243def hi16 : SDNodeXForm<imm, [{ 244 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32); 245}]>; 246 247def lo16AllZero : PatLeaf<(i32 imm), [{ 248 // Returns true if all low 16-bits are 0. 249 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0; 250}], hi16>; 251 252/// imm0_65535 predicate - True if the 32-bit immediate is in the range 253/// [0.65535]. 254def imm0_65535 : PatLeaf<(i32 imm), [{ 255 return (uint32_t)N->getZExtValue() < 65536; 256}]>; 257 258class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 259class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>; 260 261/// adde and sube predicates - True based on whether the carry flag output 262/// will be needed or not. 263def adde_dead_carry : 264 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS), 265 [{return !N->hasAnyUseOfValue(1);}]>; 266def sube_dead_carry : 267 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS), 268 [{return !N->hasAnyUseOfValue(1);}]>; 269def adde_live_carry : 270 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS), 271 [{return N->hasAnyUseOfValue(1);}]>; 272def sube_live_carry : 273 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS), 274 [{return N->hasAnyUseOfValue(1);}]>; 275 276//===----------------------------------------------------------------------===// 277// Operand Definitions. 278// 279 280// Branch target. 281def brtarget : Operand<OtherVT>; 282 283// A list of registers separated by comma. Used by load/store multiple. 284def reglist : Operand<i32> { 285 let PrintMethod = "printRegisterList"; 286} 287 288// An operand for the CONSTPOOL_ENTRY pseudo-instruction. 289def cpinst_operand : Operand<i32> { 290 let PrintMethod = "printCPInstOperand"; 291} 292 293def jtblock_operand : Operand<i32> { 294 let PrintMethod = "printJTBlockOperand"; 295} 296def jt2block_operand : Operand<i32> { 297 let PrintMethod = "printJT2BlockOperand"; 298} 299 300// Local PC labels. 301def pclabel : Operand<i32> { 302 let PrintMethod = "printPCLabel"; 303} 304 305// shift_imm: An integer that encodes a shift amount and the type of shift 306// (currently either asr or lsl) using the same encoding used for the 307// immediates in so_reg operands. 308def shift_imm : Operand<i32> { 309 let PrintMethod = "printShiftImmOperand"; 310} 311 312// shifter_operand operands: so_reg and so_imm. 313def so_reg : Operand<i32>, // reg reg imm 314 ComplexPattern<i32, 3, "SelectShifterOperandReg", 315 [shl,srl,sra,rotr]> { 316 let PrintMethod = "printSORegOperand"; 317 let MIOperandInfo = (ops GPR, GPR, i32imm); 318} 319 320// so_imm - Match a 32-bit shifter_operand immediate operand, which is an 321// 8-bit immediate rotated by an arbitrary number of bits. so_imm values are 322// represented in the imm field in the same 12-bit form that they are encoded 323// into so_imm instructions: the 8-bit immediate is the least significant bits 324// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11]. 325def so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_so_imm(N); }]> { 326 string EncoderMethod = "getSOImmOpValue"; 327 let PrintMethod = "printSOImmOperand"; 328} 329 330// Break so_imm's up into two pieces. This handles immediates with up to 16 331// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to 332// get the first/second pieces. 333def so_imm2part : Operand<i32>, 334 PatLeaf<(imm), [{ 335 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 336 }]> { 337 let PrintMethod = "printSOImm2PartOperand"; 338} 339 340def so_imm2part_1 : SDNodeXForm<imm, [{ 341 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue()); 342 return CurDAG->getTargetConstant(V, MVT::i32); 343}]>; 344 345def so_imm2part_2 : SDNodeXForm<imm, [{ 346 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue()); 347 return CurDAG->getTargetConstant(V, MVT::i32); 348}]>; 349 350def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{ 351 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue()); 352 }]> { 353 let PrintMethod = "printSOImm2PartOperand"; 354} 355 356def so_neg_imm2part_1 : SDNodeXForm<imm, [{ 357 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue()); 358 return CurDAG->getTargetConstant(V, MVT::i32); 359}]>; 360 361def so_neg_imm2part_2 : SDNodeXForm<imm, [{ 362 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue()); 363 return CurDAG->getTargetConstant(V, MVT::i32); 364}]>; 365 366/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31]. 367def imm0_31 : Operand<i32>, PatLeaf<(imm), [{ 368 return (int32_t)N->getZExtValue() < 32; 369}]>; 370 371// Define ARM specific addressing modes. 372 373// addrmode2base := reg +/- imm12 374// 375def addrmode2base : Operand<i32>, 376 ComplexPattern<i32, 3, "SelectAddrMode2Base", []> { 377 let PrintMethod = "printAddrMode2Operand"; 378 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 379} 380// addrmode2shop := reg +/- reg shop imm 381// 382def addrmode2shop : Operand<i32>, 383 ComplexPattern<i32, 3, "SelectAddrMode2ShOp", []> { 384 let PrintMethod = "printAddrMode2Operand"; 385 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 386} 387 388// addrmode2 := (addrmode2base || addrmode2shop) 389// 390def addrmode2 : Operand<i32>, 391 ComplexPattern<i32, 3, "SelectAddrMode2", []> { 392 let PrintMethod = "printAddrMode2Operand"; 393 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 394} 395 396def am2offset : Operand<i32>, 397 ComplexPattern<i32, 2, "SelectAddrMode2Offset", 398 [], [SDNPWantRoot]> { 399 let PrintMethod = "printAddrMode2OffsetOperand"; 400 let MIOperandInfo = (ops GPR, i32imm); 401} 402 403// addrmode3 := reg +/- reg 404// addrmode3 := reg +/- imm8 405// 406def addrmode3 : Operand<i32>, 407 ComplexPattern<i32, 3, "SelectAddrMode3", []> { 408 let PrintMethod = "printAddrMode3Operand"; 409 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 410} 411 412def am3offset : Operand<i32>, 413 ComplexPattern<i32, 2, "SelectAddrMode3Offset", 414 [], [SDNPWantRoot]> { 415 let PrintMethod = "printAddrMode3OffsetOperand"; 416 let MIOperandInfo = (ops GPR, i32imm); 417} 418 419// addrmode4 := reg, <mode|W> 420// 421def addrmode4 : Operand<i32>, 422 ComplexPattern<i32, 2, "SelectAddrMode4", []> { 423 let PrintMethod = "printAddrMode4Operand"; 424 let MIOperandInfo = (ops GPR:$addr, i32imm); 425} 426 427// addrmode5 := reg +/- imm8*4 428// 429def addrmode5 : Operand<i32>, 430 ComplexPattern<i32, 2, "SelectAddrMode5", []> { 431 let PrintMethod = "printAddrMode5Operand"; 432 let MIOperandInfo = (ops GPR:$base, i32imm); 433} 434 435// addrmode6 := reg with optional writeback 436// 437def addrmode6 : Operand<i32>, 438 ComplexPattern<i32, 2, "SelectAddrMode6", []> { 439 let PrintMethod = "printAddrMode6Operand"; 440 let MIOperandInfo = (ops GPR:$addr, i32imm); 441} 442 443def am6offset : Operand<i32> { 444 let PrintMethod = "printAddrMode6OffsetOperand"; 445 let MIOperandInfo = (ops GPR); 446} 447 448// addrmodepc := pc + reg 449// 450def addrmodepc : Operand<i32>, 451 ComplexPattern<i32, 2, "SelectAddrModePC", []> { 452 let PrintMethod = "printAddrModePCOperand"; 453 let MIOperandInfo = (ops GPR, i32imm); 454} 455 456def nohash_imm : Operand<i32> { 457 let PrintMethod = "printNoHashImmediate"; 458} 459 460//===----------------------------------------------------------------------===// 461 462include "ARMInstrFormats.td" 463 464//===----------------------------------------------------------------------===// 465// Multiclass helpers... 466// 467 468/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a 469/// binop that produces a value. 470multiclass AsI1_bin_irs<bits<4> opcod, string opc, 471 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 472 PatFrag opnode, bit Commutable = 0> { 473 // The register-immediate version is re-materializable. This is useful 474 // in particular for taking the address of a local. 475 let isReMaterializable = 1 in { 476 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, 477 iii, opc, "\t$Rd, $Rn, $imm", 478 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> { 479 bits<4> Rd; 480 bits<4> Rn; 481 bits<12> imm; 482 let Inst{25} = 1; 483 let Inst{15-12} = Rd; 484 let Inst{19-16} = Rn; 485 let Inst{11-0} = imm; 486 } 487 } 488 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 489 iir, opc, "\t$Rd, $Rn, $Rm", 490 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> { 491 bits<4> Rd; 492 bits<4> Rn; 493 bits<4> Rm; 494 let Inst{11-4} = 0b00000000; 495 let Inst{25} = 0; 496 let isCommutable = Commutable; 497 let Inst{3-0} = Rm; 498 let Inst{15-12} = Rd; 499 let Inst{19-16} = Rn; 500 } 501 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 502 iis, opc, "\t$dst, $a, $b", 503 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> { 504 bits<4> Rd; 505 bits<4> Rn; 506 bits<4> Rm; 507 let Inst{25} = 0; 508 let Inst{3-0} = Rm; 509 let Inst{15-12} = Rd; 510 let Inst{19-16} = Rn; 511 } 512} 513 514/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the 515/// instruction modifies the CPSR register. 516let Defs = [CPSR] in { 517multiclass AI1_bin_s_irs<bits<4> opcod, string opc, 518 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 519 PatFrag opnode, bit Commutable = 0> { 520 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 521 iii, opc, "\t$dst, $a, $b", 522 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> { 523 let Inst{20} = 1; 524 let Inst{25} = 1; 525 } 526 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, 527 iir, opc, "\t$dst, $a, $b", 528 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> { 529 let isCommutable = Commutable; 530 let Inst{11-4} = 0b00000000; 531 let Inst{20} = 1; 532 let Inst{25} = 0; 533 } 534 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 535 iis, opc, "\t$dst, $a, $b", 536 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> { 537 let Inst{20} = 1; 538 let Inst{25} = 0; 539 } 540} 541} 542 543/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 544/// patterns. Similar to AsI1_bin_irs except the instruction does not produce 545/// a explicit result, only implicitly set CPSR. 546let isCompare = 1, Defs = [CPSR] in { 547multiclass AI1_cmp_irs<bits<4> opcod, string opc, 548 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 549 PatFrag opnode, bit Commutable = 0> { 550 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, iii, 551 opc, "\t$a, $b", 552 [(opnode GPR:$a, so_imm:$b)]> { 553 let Inst{20} = 1; 554 let Inst{25} = 1; 555 } 556 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, iir, 557 opc, "\t$a, $b", 558 [(opnode GPR:$a, GPR:$b)]> { 559 let Inst{11-4} = 0b00000000; 560 let Inst{20} = 1; 561 let Inst{25} = 0; 562 let isCommutable = Commutable; 563 } 564 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, iis, 565 opc, "\t$a, $b", 566 [(opnode GPR:$a, so_reg:$b)]> { 567 let Inst{20} = 1; 568 let Inst{25} = 0; 569 } 570} 571} 572 573/// AI_ext_rrot - A unary operation with two forms: one whose operand is a 574/// register and one whose operand is a register rotated by 8/16/24. 575/// FIXME: Remove the 'r' variant. Its rot_imm is zero. 576multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> { 577 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src), 578 IIC_iEXTr, opc, "\t$dst, $src", 579 [(set GPR:$dst, (opnode GPR:$src))]>, 580 Requires<[IsARM, HasV6]> { 581 let Inst{11-10} = 0b00; 582 let Inst{19-16} = 0b1111; 583 } 584 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot), 585 IIC_iEXTr, opc, "\t$dst, $src, ror $rot", 586 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>, 587 Requires<[IsARM, HasV6]> { 588 let Inst{19-16} = 0b1111; 589 } 590} 591 592multiclass AI_ext_rrot_np<bits<8> opcod, string opc> { 593 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src), 594 IIC_iEXTr, opc, "\t$dst, $src", 595 [/* For disassembly only; pattern left blank */]>, 596 Requires<[IsARM, HasV6]> { 597 let Inst{11-10} = 0b00; 598 let Inst{19-16} = 0b1111; 599 } 600 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot), 601 IIC_iEXTr, opc, "\t$dst, $src, ror $rot", 602 [/* For disassembly only; pattern left blank */]>, 603 Requires<[IsARM, HasV6]> { 604 let Inst{19-16} = 0b1111; 605 } 606} 607 608/// AI_exta_rrot - A binary operation with two forms: one whose operand is a 609/// register and one whose operand is a register rotated by 8/16/24. 610multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> { 611 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), 612 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS", 613 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>, 614 Requires<[IsARM, HasV6]> { 615 let Inst{11-10} = 0b00; 616 } 617 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, 618 i32imm:$rot), 619 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot", 620 [(set GPR:$dst, (opnode GPR:$LHS, 621 (rotr GPR:$RHS, rot_imm:$rot)))]>, 622 Requires<[IsARM, HasV6]>; 623} 624 625// For disassembly only. 626multiclass AI_exta_rrot_np<bits<8> opcod, string opc> { 627 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), 628 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS", 629 [/* For disassembly only; pattern left blank */]>, 630 Requires<[IsARM, HasV6]> { 631 let Inst{11-10} = 0b00; 632 } 633 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, 634 i32imm:$rot), 635 IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot", 636 [/* For disassembly only; pattern left blank */]>, 637 Requires<[IsARM, HasV6]>; 638} 639 640/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. 641let Uses = [CPSR] in { 642multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 643 bit Commutable = 0> { 644 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 645 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b", 646 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, 647 Requires<[IsARM]> { 648 let Inst{25} = 1; 649 } 650 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 651 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b", 652 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>, 653 Requires<[IsARM]> { 654 let isCommutable = Commutable; 655 let Inst{11-4} = 0b00000000; 656 let Inst{25} = 0; 657 } 658 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 659 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b", 660 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>, 661 Requires<[IsARM]> { 662 let Inst{25} = 0; 663 } 664} 665// Carry setting variants 666let Defs = [CPSR] in { 667multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode, 668 bit Commutable = 0> { 669 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 670 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"), 671 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, 672 Requires<[IsARM]> { 673 let Inst{20} = 1; 674 let Inst{25} = 1; 675 } 676 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 677 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"), 678 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>, 679 Requires<[IsARM]> { 680 let Inst{11-4} = 0b00000000; 681 let Inst{20} = 1; 682 let Inst{25} = 0; 683 } 684 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 685 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"), 686 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>, 687 Requires<[IsARM]> { 688 let Inst{20} = 1; 689 let Inst{25} = 0; 690 } 691} 692} 693} 694 695//===----------------------------------------------------------------------===// 696// Instructions 697//===----------------------------------------------------------------------===// 698 699//===----------------------------------------------------------------------===// 700// Miscellaneous Instructions. 701// 702 703/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in 704/// the function. The first operand is the ID# for this instruction, the second 705/// is the index into the MachineConstantPool that this is, the third is the 706/// size in bytes of this constant pool entry. 707let neverHasSideEffects = 1, isNotDuplicable = 1 in 708def CONSTPOOL_ENTRY : 709PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 710 i32imm:$size), NoItinerary, "", []>; 711 712// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE 713// from removing one half of the matched pairs. That breaks PEI, which assumes 714// these will always be in pairs, and asserts if it finds otherwise. Better way? 715let Defs = [SP], Uses = [SP], hasSideEffects = 1 in { 716def ADJCALLSTACKUP : 717PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, "", 718 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; 719 720def ADJCALLSTACKDOWN : 721PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, "", 722 [(ARMcallseq_start timm:$amt)]>; 723} 724 725def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "", 726 [/* For disassembly only; pattern left blank */]>, 727 Requires<[IsARM, HasV6T2]> { 728 let Inst{27-16} = 0b001100100000; 729 let Inst{7-0} = 0b00000000; 730} 731 732def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "", 733 [/* For disassembly only; pattern left blank */]>, 734 Requires<[IsARM, HasV6T2]> { 735 let Inst{27-16} = 0b001100100000; 736 let Inst{7-0} = 0b00000001; 737} 738 739def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "", 740 [/* For disassembly only; pattern left blank */]>, 741 Requires<[IsARM, HasV6T2]> { 742 let Inst{27-16} = 0b001100100000; 743 let Inst{7-0} = 0b00000010; 744} 745 746def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "", 747 [/* For disassembly only; pattern left blank */]>, 748 Requires<[IsARM, HasV6T2]> { 749 let Inst{27-16} = 0b001100100000; 750 let Inst{7-0} = 0b00000011; 751} 752 753def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel", 754 "\t$dst, $a, $b", 755 [/* For disassembly only; pattern left blank */]>, 756 Requires<[IsARM, HasV6]> { 757 let Inst{27-20} = 0b01101000; 758 let Inst{7-4} = 0b1011; 759} 760 761def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "", 762 [/* For disassembly only; pattern left blank */]>, 763 Requires<[IsARM, HasV6T2]> { 764 let Inst{27-16} = 0b001100100000; 765 let Inst{7-0} = 0b00000100; 766} 767 768// The i32imm operand $val can be used by a debugger to store more information 769// about the breakpoint. 770def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val", 771 [/* For disassembly only; pattern left blank */]>, 772 Requires<[IsARM]> { 773 let Inst{27-20} = 0b00010010; 774 let Inst{7-4} = 0b0111; 775} 776 777// Change Processor State is a system instruction -- for disassembly only. 778// The singleton $opt operand contains the following information: 779// opt{4-0} = mode from Inst{4-0} 780// opt{5} = changemode from Inst{17} 781// opt{8-6} = AIF from Inst{8-6} 782// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable 783def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt", 784 [/* For disassembly only; pattern left blank */]>, 785 Requires<[IsARM]> { 786 let Inst{31-28} = 0b1111; 787 let Inst{27-20} = 0b00010000; 788 let Inst{16} = 0; 789 let Inst{5} = 0; 790} 791 792// Preload signals the memory system of possible future data/instruction access. 793// These are for disassembly only. 794// 795// A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0. 796// The neg_zero operand translates -0 to -1, -1 to -2, ..., etc. 797multiclass APreLoad<bit data, bit read, string opc> { 798 799 def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary, 800 !strconcat(opc, "\t[$base, $imm]"), []> { 801 let Inst{31-26} = 0b111101; 802 let Inst{25} = 0; // 0 for immediate form 803 let Inst{24} = data; 804 let Inst{22} = read; 805 let Inst{21-20} = 0b01; 806 } 807 808 def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary, 809 !strconcat(opc, "\t$addr"), []> { 810 let Inst{31-26} = 0b111101; 811 let Inst{25} = 1; // 1 for register form 812 let Inst{24} = data; 813 let Inst{22} = read; 814 let Inst{21-20} = 0b01; 815 let Inst{4} = 0; 816 } 817} 818 819defm PLD : APreLoad<1, 1, "pld">; 820defm PLDW : APreLoad<1, 0, "pldw">; 821defm PLI : APreLoad<0, 1, "pli">; 822 823def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe", 824 [/* For disassembly only; pattern left blank */]>, 825 Requires<[IsARM]> { 826 let Inst{31-28} = 0b1111; 827 let Inst{27-20} = 0b00010000; 828 let Inst{16} = 1; 829 let Inst{9} = 1; 830 let Inst{7-4} = 0b0000; 831} 832 833def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle", 834 [/* For disassembly only; pattern left blank */]>, 835 Requires<[IsARM]> { 836 let Inst{31-28} = 0b1111; 837 let Inst{27-20} = 0b00010000; 838 let Inst{16} = 1; 839 let Inst{9} = 0; 840 let Inst{7-4} = 0b0000; 841} 842 843def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt", 844 [/* For disassembly only; pattern left blank */]>, 845 Requires<[IsARM, HasV7]> { 846 let Inst{27-16} = 0b001100100000; 847 let Inst{7-4} = 0b1111; 848} 849 850// A5.4 Permanently UNDEFINED instructions. 851let isBarrier = 1, isTerminator = 1 in 852def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary, 853 "trap", [(trap)]>, 854 Requires<[IsARM]> { 855 let Inst{27-25} = 0b011; 856 let Inst{24-20} = 0b11111; 857 let Inst{7-5} = 0b111; 858 let Inst{4} = 0b1; 859} 860 861// Address computation and loads and stores in PIC mode. 862let isNotDuplicable = 1 in { 863def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p), 864 Pseudo, IIC_iALUr, "", 865 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>; 866 867let AddedComplexity = 10 in { 868def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 869 Pseudo, IIC_iLoad_r, "", 870 [(set GPR:$dst, (load addrmodepc:$addr))]>; 871 872def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 873 Pseudo, IIC_iLoad_bh_r, "", 874 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>; 875 876def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 877 Pseudo, IIC_iLoad_bh_r, "", 878 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>; 879 880def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 881 Pseudo, IIC_iLoad_bh_r, "", 882 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>; 883 884def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 885 Pseudo, IIC_iLoad_bh_r, "", 886 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>; 887} 888let AddedComplexity = 10 in { 889def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 890 Pseudo, IIC_iStore_r, "", 891 [(store GPR:$src, addrmodepc:$addr)]>; 892 893def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 894 Pseudo, IIC_iStore_bh_r, "", 895 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>; 896 897def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 898 Pseudo, IIC_iStore_bh_r, "", 899 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; 900} 901} // isNotDuplicable = 1 902 903 904// LEApcrel - Load a pc-relative address into a register without offending the 905// assembler. 906let neverHasSideEffects = 1 in { 907let isReMaterializable = 1 in 908def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), 909 Pseudo, IIC_iALUi, 910 "adr$p\t$dst, #$label", []>; 911 912} // neverHasSideEffects 913def LEApcrelJT : AXI1<0x0, (outs GPR:$dst), 914 (ins i32imm:$label, nohash_imm:$id, pred:$p), 915 Pseudo, IIC_iALUi, 916 "adr$p\t$dst, #${label}_${id}", []> { 917 let Inst{25} = 1; 918} 919 920//===----------------------------------------------------------------------===// 921// Control Flow Instructions. 922// 923 924let isReturn = 1, isTerminator = 1, isBarrier = 1 in { 925 // ARMV4T and above 926 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 927 "bx", "\tlr", [(ARMretflag)]>, 928 Requires<[IsARM, HasV4T]> { 929 let Inst{3-0} = 0b1110; 930 let Inst{7-4} = 0b0001; 931 let Inst{19-8} = 0b111111111111; 932 let Inst{27-20} = 0b00010010; 933 } 934 935 // ARMV4 only 936 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br, 937 "mov", "\tpc, lr", [(ARMretflag)]>, 938 Requires<[IsARM, NoV4T]> { 939 let Inst{11-0} = 0b000000001110; 940 let Inst{15-12} = 0b1111; 941 let Inst{19-16} = 0b0000; 942 let Inst{27-20} = 0b00011010; 943 } 944} 945 946// Indirect branches 947let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 948 // ARMV4T and above 949 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", 950 [(brind GPR:$dst)]>, 951 Requires<[IsARM, HasV4T]> { 952 bits<4> dst; 953 let Inst{7-4} = 0b0001; 954 let Inst{19-8} = 0b111111111111; 955 let Inst{27-20} = 0b00010010; 956 let Inst{31-28} = 0b1110; 957 let Inst{3-0} = dst; 958 } 959 960 // ARMV4 only 961 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst", 962 [(brind GPR:$dst)]>, 963 Requires<[IsARM, NoV4T]> { 964 bits<4> dst; 965 let Inst{11-4} = 0b00000000; 966 let Inst{15-12} = 0b1111; 967 let Inst{19-16} = 0b0000; 968 let Inst{27-20} = 0b00011010; 969 let Inst{31-28} = 0b1110; 970 let Inst{3-0} = dst; 971 } 972} 973 974// FIXME: remove when we have a way to marking a MI with these properties. 975// FIXME: Should pc be an implicit operand like PICADD, etc? 976let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 977 hasExtraDefRegAllocReq = 1 in 978 def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, 979 reglist:$dsts, variable_ops), 980 IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr, 981 "ldm${addr:submode}${p}\t$addr!, $dsts", 982 "$addr.addr = $wb", []>; 983 984// On non-Darwin platforms R9 is callee-saved. 985let isCall = 1, 986 Defs = [R0, R1, R2, R3, R12, LR, 987 D0, D1, D2, D3, D4, D5, D6, D7, 988 D16, D17, D18, D19, D20, D21, D22, D23, 989 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 990 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), 991 IIC_Br, "bl\t$func", 992 [(ARMcall tglobaladdr:$func)]>, 993 Requires<[IsARM, IsNotDarwin]> { 994 let Inst{31-28} = 0b1110; 995 } 996 997 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), 998 IIC_Br, "bl", "\t$func", 999 [(ARMcall_pred tglobaladdr:$func)]>, 1000 Requires<[IsARM, IsNotDarwin]>; 1001 1002 // ARMv5T and above 1003 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, 1004 IIC_Br, "blx\t$func", 1005 [(ARMcall GPR:$func)]>, 1006 Requires<[IsARM, HasV5T, IsNotDarwin]> { 1007 bits<4> func; 1008 let Inst{7-4} = 0b0011; 1009 let Inst{19-8} = 0b111111111111; 1010 let Inst{27-20} = 0b00010010; 1011 let Inst{3-0} = func; 1012 } 1013 1014 // ARMv4T 1015 // Note: Restrict $func to the tGPR regclass to prevent it being in LR. 1016 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops), 1017 IIC_Br, "mov\tlr, pc\n\tbx\t$func", 1018 [(ARMcall_nolink tGPR:$func)]>, 1019 Requires<[IsARM, HasV4T, IsNotDarwin]> { 1020 let Inst{7-4} = 0b0001; 1021 let Inst{19-8} = 0b111111111111; 1022 let Inst{27-20} = 0b00010010; 1023 } 1024 1025 // ARMv4 1026 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops), 1027 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func", 1028 [(ARMcall_nolink tGPR:$func)]>, 1029 Requires<[IsARM, NoV4T, IsNotDarwin]> { 1030 let Inst{11-4} = 0b00000000; 1031 let Inst{15-12} = 0b1111; 1032 let Inst{19-16} = 0b0000; 1033 let Inst{27-20} = 0b00011010; 1034 } 1035} 1036 1037// On Darwin R9 is call-clobbered. 1038let isCall = 1, 1039 Defs = [R0, R1, R2, R3, R9, R12, LR, 1040 D0, D1, D2, D3, D4, D5, D6, D7, 1041 D16, D17, D18, D19, D20, D21, D22, D23, 1042 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 1043 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), 1044 IIC_Br, "bl\t$func", 1045 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> { 1046 let Inst{31-28} = 0b1110; 1047 } 1048 1049 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), 1050 IIC_Br, "bl", "\t$func", 1051 [(ARMcall_pred tglobaladdr:$func)]>, 1052 Requires<[IsARM, IsDarwin]>; 1053 1054 // ARMv5T and above 1055 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, 1056 IIC_Br, "blx\t$func", 1057 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> { 1058 let Inst{7-4} = 0b0011; 1059 let Inst{19-8} = 0b111111111111; 1060 let Inst{27-20} = 0b00010010; 1061 } 1062 1063 // ARMv4T 1064 // Note: Restrict $func to the tGPR regclass to prevent it being in LR. 1065 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops), 1066 IIC_Br, "mov\tlr, pc\n\tbx\t$func", 1067 [(ARMcall_nolink tGPR:$func)]>, 1068 Requires<[IsARM, HasV4T, IsDarwin]> { 1069 let Inst{7-4} = 0b0001; 1070 let Inst{19-8} = 0b111111111111; 1071 let Inst{27-20} = 0b00010010; 1072 } 1073 1074 // ARMv4 1075 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops), 1076 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func", 1077 [(ARMcall_nolink tGPR:$func)]>, 1078 Requires<[IsARM, NoV4T, IsDarwin]> { 1079 let Inst{11-4} = 0b00000000; 1080 let Inst{15-12} = 0b1111; 1081 let Inst{19-16} = 0b0000; 1082 let Inst{27-20} = 0b00011010; 1083 } 1084} 1085 1086// Tail calls. 1087 1088let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { 1089 // Darwin versions. 1090 let Defs = [R0, R1, R2, R3, R9, R12, 1091 D0, D1, D2, D3, D4, D5, D6, D7, 1092 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, 1093 D27, D28, D29, D30, D31, PC], 1094 Uses = [SP] in { 1095 def TCRETURNdi : AInoP<(outs), (ins i32imm:$dst, variable_ops), 1096 Pseudo, IIC_Br, 1097 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>; 1098 1099 def TCRETURNri : AInoP<(outs), (ins tcGPR:$dst, variable_ops), 1100 Pseudo, IIC_Br, 1101 "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>; 1102 1103 def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), 1104 IIC_Br, "b\t$dst @ TAILCALL", 1105 []>, Requires<[IsDarwin]>; 1106 1107 def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), 1108 IIC_Br, "b.w\t$dst @ TAILCALL", 1109 []>, Requires<[IsDarwin]>; 1110 1111 def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops), 1112 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL", 1113 []>, Requires<[IsDarwin]> { 1114 let Inst{7-4} = 0b0001; 1115 let Inst{19-8} = 0b111111111111; 1116 let Inst{27-20} = 0b00010010; 1117 let Inst{31-28} = 0b1110; 1118 } 1119 } 1120 1121 // Non-Darwin versions (the difference is R9). 1122 let Defs = [R0, R1, R2, R3, R12, 1123 D0, D1, D2, D3, D4, D5, D6, D7, 1124 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, 1125 D27, D28, D29, D30, D31, PC], 1126 Uses = [SP] in { 1127 def TCRETURNdiND : AInoP<(outs), (ins i32imm:$dst, variable_ops), 1128 Pseudo, IIC_Br, 1129 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>; 1130 1131 def TCRETURNriND : AInoP<(outs), (ins tcGPR:$dst, variable_ops), 1132 Pseudo, IIC_Br, 1133 "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>; 1134 1135 def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), 1136 IIC_Br, "b\t$dst @ TAILCALL", 1137 []>, Requires<[IsARM, IsNotDarwin]>; 1138 1139 def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), 1140 IIC_Br, "b.w\t$dst @ TAILCALL", 1141 []>, Requires<[IsThumb, IsNotDarwin]>; 1142 1143 def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops), 1144 BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL", 1145 []>, Requires<[IsNotDarwin]> { 1146 let Inst{7-4} = 0b0001; 1147 let Inst{19-8} = 0b111111111111; 1148 let Inst{27-20} = 0b00010010; 1149 let Inst{31-28} = 0b1110; 1150 } 1151 } 1152} 1153 1154let isBranch = 1, isTerminator = 1 in { 1155 // B is "predicable" since it can be xformed into a Bcc. 1156 let isBarrier = 1 in { 1157 let isPredicable = 1 in 1158 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br, 1159 "b\t$target", [(br bb:$target)]>; 1160 1161 let isNotDuplicable = 1, isIndirectBranch = 1 in { 1162 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id), 1163 IIC_Br, "mov\tpc, $target$jt", 1164 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> { 1165 let Inst{11-4} = 0b00000000; 1166 let Inst{15-12} = 0b1111; 1167 let Inst{20} = 0; // S Bit 1168 let Inst{24-21} = 0b1101; 1169 let Inst{27-25} = 0b000; 1170 } 1171 def BR_JTm : JTI<(outs), 1172 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id), 1173 IIC_Br, "ldr\tpc, $target$jt", 1174 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt, 1175 imm:$id)]> { 1176 let Inst{15-12} = 0b1111; 1177 let Inst{20} = 1; // L bit 1178 let Inst{21} = 0; // W bit 1179 let Inst{22} = 0; // B bit 1180 let Inst{24} = 1; // P bit 1181 let Inst{27-25} = 0b011; 1182 } 1183 def BR_JTadd : JTI<(outs), 1184 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id), 1185 IIC_Br, "add\tpc, $target, $idx$jt", 1186 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, 1187 imm:$id)]> { 1188 let Inst{15-12} = 0b1111; 1189 let Inst{20} = 0; // S bit 1190 let Inst{24-21} = 0b0100; 1191 let Inst{27-25} = 0b000; 1192 } 1193 } // isNotDuplicable = 1, isIndirectBranch = 1 1194 } // isBarrier = 1 1195 1196 // FIXME: should be able to write a pattern for ARMBrcond, but can't use 1197 // a two-value operand where a dag node expects two operands. :( 1198 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target), 1199 IIC_Br, "b", "\t$target", 1200 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>; 1201} 1202 1203// Branch and Exchange Jazelle -- for disassembly only 1204def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func", 1205 [/* For disassembly only; pattern left blank */]> { 1206 let Inst{23-20} = 0b0010; 1207 //let Inst{19-8} = 0xfff; 1208 let Inst{7-4} = 0b0010; 1209} 1210 1211// Secure Monitor Call is a system instruction -- for disassembly only 1212def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt", 1213 [/* For disassembly only; pattern left blank */]> { 1214 let Inst{23-20} = 0b0110; 1215 let Inst{7-4} = 0b0111; 1216} 1217 1218// Supervisor Call (Software Interrupt) -- for disassembly only 1219let isCall = 1 in { 1220def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", 1221 [/* For disassembly only; pattern left blank */]>; 1222} 1223 1224// Store Return State is a system instruction -- for disassembly only 1225def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode), 1226 NoItinerary, "srs${addr:submode}\tsp!, $mode", 1227 [/* For disassembly only; pattern left blank */]> { 1228 let Inst{31-28} = 0b1111; 1229 let Inst{22-20} = 0b110; // W = 1 1230} 1231 1232def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode), 1233 NoItinerary, "srs${addr:submode}\tsp, $mode", 1234 [/* For disassembly only; pattern left blank */]> { 1235 let Inst{31-28} = 0b1111; 1236 let Inst{22-20} = 0b100; // W = 0 1237} 1238 1239// Return From Exception is a system instruction -- for disassembly only 1240def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base), 1241 NoItinerary, "rfe${addr:submode}\t$base!", 1242 [/* For disassembly only; pattern left blank */]> { 1243 let Inst{31-28} = 0b1111; 1244 let Inst{22-20} = 0b011; // W = 1 1245} 1246 1247def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base), 1248 NoItinerary, "rfe${addr:submode}\t$base", 1249 [/* For disassembly only; pattern left blank */]> { 1250 let Inst{31-28} = 0b1111; 1251 let Inst{22-20} = 0b001; // W = 0 1252} 1253 1254//===----------------------------------------------------------------------===// 1255// Load / store Instructions. 1256// 1257 1258// Load 1259let canFoldAsLoad = 1, isReMaterializable = 1 in 1260def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r, 1261 "ldr", "\t$dst, $addr", 1262 [(set GPR:$dst, (load addrmode2:$addr))]>; 1263 1264// Special LDR for loads from non-pc-relative constpools. 1265let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, 1266 isReMaterializable = 1 in 1267def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad_r, 1268 "ldr", "\t$dst, $addr", []>; 1269 1270// Loads with zero extension 1271def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 1272 IIC_iLoad_bh_r, "ldrh", "\t$dst, $addr", 1273 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>; 1274 1275def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 1276 IIC_iLoad_bh_r, "ldrb", "\t$dst, $addr", 1277 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>; 1278 1279// Loads with sign extension 1280def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 1281 IIC_iLoad_bh_r, "ldrsh", "\t$dst, $addr", 1282 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>; 1283 1284def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 1285 IIC_iLoad_bh_r, "ldrsb", "\t$dst, $addr", 1286 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>; 1287 1288let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 1289// Load doubleword 1290def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm, 1291 IIC_iLoad_d_r, "ldrd", "\t$dst1, $addr", 1292 []>, Requires<[IsARM, HasV5TE]>; 1293 1294// Indexed loads 1295def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb), 1296 (ins addrmode2:$addr), LdFrm, IIC_iLoad_ru, 1297 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 1298 1299def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb), 1300 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru, 1301 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 1302 1303def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb), 1304 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru, 1305 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 1306 1307def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb), 1308 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru, 1309 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 1310 1311def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb), 1312 (ins addrmode2:$addr), LdFrm, IIC_iLoad_bh_ru, 1313 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 1314 1315def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb), 1316 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru, 1317 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 1318 1319def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb), 1320 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru, 1321 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 1322 1323def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb), 1324 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru, 1325 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 1326 1327def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb), 1328 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_bh_ru, 1329 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 1330 1331def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb), 1332 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_ru, 1333 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 1334 1335// For disassembly only 1336def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb), 1337 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad_d_ru, 1338 "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>, 1339 Requires<[IsARM, HasV5TE]>; 1340 1341// For disassembly only 1342def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb), 1343 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_d_ru, 1344 "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>, 1345 Requires<[IsARM, HasV5TE]>; 1346 1347} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 1348 1349// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. 1350 1351def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb), 1352 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad_ru, 1353 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { 1354 let Inst{21} = 1; // overwrite 1355} 1356 1357def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb), 1358 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad_bh_ru, 1359 "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { 1360 let Inst{21} = 1; // overwrite 1361} 1362 1363def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb), 1364 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru, 1365 "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { 1366 let Inst{21} = 1; // overwrite 1367} 1368 1369def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb), 1370 (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru, 1371 "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> { 1372 let Inst{21} = 1; // overwrite 1373} 1374 1375def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb), 1376 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad_bh_ru, 1377 "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> { 1378 let Inst{21} = 1; // overwrite 1379} 1380 1381// Store 1382def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore_r, 1383 "str", "\t$src, $addr", 1384 [(store GPR:$src, addrmode2:$addr)]>; 1385 1386// Stores with truncate 1387def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, 1388 IIC_iStore_bh_r, "strh", "\t$src, $addr", 1389 [(truncstorei16 GPR:$src, addrmode3:$addr)]>; 1390 1391def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, 1392 IIC_iStore_bh_r, "strb", "\t$src, $addr", 1393 [(truncstorei8 GPR:$src, addrmode2:$addr)]>; 1394 1395// Store doubleword 1396let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in 1397def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr), 1398 StMiscFrm, IIC_iStore_d_r, 1399 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>; 1400 1401// Indexed stores 1402def STR_PRE : AI2stwpr<(outs GPR:$base_wb), 1403 (ins GPR:$src, GPR:$base, am2offset:$offset), 1404 StFrm, IIC_iStore_ru, 1405 "str", "\t$src, [$base, $offset]!", "$base = $base_wb", 1406 [(set GPR:$base_wb, 1407 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>; 1408 1409def STR_POST : AI2stwpo<(outs GPR:$base_wb), 1410 (ins GPR:$src, GPR:$base,am2offset:$offset), 1411 StFrm, IIC_iStore_ru, 1412 "str", "\t$src, [$base], $offset", "$base = $base_wb", 1413 [(set GPR:$base_wb, 1414 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>; 1415 1416def STRH_PRE : AI3sthpr<(outs GPR:$base_wb), 1417 (ins GPR:$src, GPR:$base,am3offset:$offset), 1418 StMiscFrm, IIC_iStore_ru, 1419 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb", 1420 [(set GPR:$base_wb, 1421 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>; 1422 1423def STRH_POST: AI3sthpo<(outs GPR:$base_wb), 1424 (ins GPR:$src, GPR:$base,am3offset:$offset), 1425 StMiscFrm, IIC_iStore_bh_ru, 1426 "strh", "\t$src, [$base], $offset", "$base = $base_wb", 1427 [(set GPR:$base_wb, (post_truncsti16 GPR:$src, 1428 GPR:$base, am3offset:$offset))]>; 1429 1430def STRB_PRE : AI2stbpr<(outs GPR:$base_wb), 1431 (ins GPR:$src, GPR:$base,am2offset:$offset), 1432 StFrm, IIC_iStore_bh_ru, 1433 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb", 1434 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src, 1435 GPR:$base, am2offset:$offset))]>; 1436 1437def STRB_POST: AI2stbpo<(outs GPR:$base_wb), 1438 (ins GPR:$src, GPR:$base,am2offset:$offset), 1439 StFrm, IIC_iStore_bh_ru, 1440 "strb", "\t$src, [$base], $offset", "$base = $base_wb", 1441 [(set GPR:$base_wb, (post_truncsti8 GPR:$src, 1442 GPR:$base, am2offset:$offset))]>; 1443 1444// For disassembly only 1445def STRD_PRE : AI3stdpr<(outs GPR:$base_wb), 1446 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset), 1447 StMiscFrm, IIC_iStore_d_ru, 1448 "strd", "\t$src1, $src2, [$base, $offset]!", 1449 "$base = $base_wb", []>; 1450 1451// For disassembly only 1452def STRD_POST: AI3stdpo<(outs GPR:$base_wb), 1453 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset), 1454 StMiscFrm, IIC_iStore_d_ru, 1455 "strd", "\t$src1, $src2, [$base], $offset", 1456 "$base = $base_wb", []>; 1457 1458// STRT, STRBT, and STRHT are for disassembly only. 1459 1460def STRT : AI2stwpo<(outs GPR:$base_wb), 1461 (ins GPR:$src, GPR:$base,am2offset:$offset), 1462 StFrm, IIC_iStore_ru, 1463 "strt", "\t$src, [$base], $offset", "$base = $base_wb", 1464 [/* For disassembly only; pattern left blank */]> { 1465 let Inst{21} = 1; // overwrite 1466} 1467 1468def STRBT : AI2stbpo<(outs GPR:$base_wb), 1469 (ins GPR:$src, GPR:$base,am2offset:$offset), 1470 StFrm, IIC_iStore_bh_ru, 1471 "strbt", "\t$src, [$base], $offset", "$base = $base_wb", 1472 [/* For disassembly only; pattern left blank */]> { 1473 let Inst{21} = 1; // overwrite 1474} 1475 1476def STRHT: AI3sthpo<(outs GPR:$base_wb), 1477 (ins GPR:$src, GPR:$base,am3offset:$offset), 1478 StMiscFrm, IIC_iStore_bh_ru, 1479 "strht", "\t$src, [$base], $offset", "$base = $base_wb", 1480 [/* For disassembly only; pattern left blank */]> { 1481 let Inst{21} = 1; // overwrite 1482} 1483 1484//===----------------------------------------------------------------------===// 1485// Load / store multiple Instructions. 1486// 1487 1488let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 1489def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p, 1490 reglist:$dsts, variable_ops), 1491 IndexModeNone, LdStMulFrm, IIC_iLoad_m, 1492 "ldm${addr:submode}${p}\t$addr, $dsts", "", []>; 1493 1494def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, 1495 reglist:$dsts, variable_ops), 1496 IndexModeUpd, LdStMulFrm, IIC_iLoad_mu, 1497 "ldm${addr:submode}${p}\t$addr!, $dsts", 1498 "$addr.addr = $wb", []>; 1499} // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq 1500 1501let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { 1502def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p, 1503 reglist:$srcs, variable_ops), 1504 IndexModeNone, LdStMulFrm, IIC_iStore_m, 1505 "stm${addr:submode}${p}\t$addr, $srcs", "", []>; 1506 1507def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, 1508 reglist:$srcs, variable_ops), 1509 IndexModeUpd, LdStMulFrm, IIC_iStore_mu, 1510 "stm${addr:submode}${p}\t$addr!, $srcs", 1511 "$addr.addr = $wb", []>; 1512} // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq 1513 1514//===----------------------------------------------------------------------===// 1515// Move Instructions. 1516// 1517 1518let neverHasSideEffects = 1 in 1519def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr, 1520 "mov", "\t$Rd, $Rm", []>, UnaryDP { 1521 bits<4> Rd; 1522 bits<4> Rm; 1523 1524 let Inst{11-4} = 0b00000000; 1525 let Inst{25} = 0; 1526 let Inst{3-0} = Rm; 1527 let Inst{15-12} = Rd; 1528} 1529 1530// A version for the smaller set of tail call registers. 1531let neverHasSideEffects = 1 in 1532def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm, 1533 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP { 1534 bits<4> Rd; 1535 bits<4> Rm; 1536 1537 let Inst{11-4} = 0b00000000; 1538 let Inst{25} = 0; 1539 let Inst{3-0} = Rm; 1540 let Inst{15-12} = Rd; 1541} 1542 1543def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins so_reg:$src), 1544 DPSoRegFrm, IIC_iMOVsr, 1545 "mov", "\t$Rd, $src", [(set GPR:$Rd, so_reg:$src)]>, UnaryDP { 1546 let Inst{25} = 0; 1547} 1548 1549let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1550def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi, 1551 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP { 1552 bits<4> Rd; 1553 bits<12> imm; 1554 let Inst{25} = 1; 1555 let Inst{15-12} = Rd; 1556 let Inst{19-16} = 0b0000; 1557 let Inst{11-0} = imm; 1558} 1559 1560let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1561def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 1562 DPFrm, IIC_iMOVi, 1563 "movw", "\t$dst, $src", 1564 [(set GPR:$dst, imm0_65535:$src)]>, 1565 Requires<[IsARM, HasV6T2]>, UnaryDP { 1566 let Inst{20} = 0; 1567 let Inst{25} = 1; 1568} 1569 1570let Constraints = "$src = $dst" in 1571def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm), 1572 DPFrm, IIC_iMOVi, 1573 "movt", "\t$dst, $imm", 1574 [(set GPR:$dst, 1575 (or (and GPR:$src, 0xffff), 1576 lo16AllZero:$imm))]>, UnaryDP, 1577 Requires<[IsARM, HasV6T2]> { 1578 let Inst{20} = 0; 1579 let Inst{25} = 1; 1580} 1581 1582def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, 1583 Requires<[IsARM, HasV6T2]>; 1584 1585let Uses = [CPSR] in 1586def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi, 1587 "mov", "\t$dst, $src, rrx", 1588 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP; 1589 1590// These aren't really mov instructions, but we have to define them this way 1591// due to flag operands. 1592 1593let Defs = [CPSR] in { 1594def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 1595 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1", 1596 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP; 1597def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 1598 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1", 1599 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP; 1600} 1601 1602//===----------------------------------------------------------------------===// 1603// Extend Instructions. 1604// 1605 1606// Sign extenders 1607 1608defm SXTB : AI_ext_rrot<0b01101010, 1609 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; 1610defm SXTH : AI_ext_rrot<0b01101011, 1611 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; 1612 1613defm SXTAB : AI_exta_rrot<0b01101010, 1614 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 1615defm SXTAH : AI_exta_rrot<0b01101011, 1616 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 1617 1618// For disassembly only 1619defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">; 1620 1621// For disassembly only 1622defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">; 1623 1624// Zero extenders 1625 1626let AddedComplexity = 16 in { 1627defm UXTB : AI_ext_rrot<0b01101110, 1628 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; 1629defm UXTH : AI_ext_rrot<0b01101111, 1630 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 1631defm UXTB16 : AI_ext_rrot<0b01101100, 1632 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 1633 1634// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 1635// The transformation should probably be done as a combiner action 1636// instead so we can include a check for masking back in the upper 1637// eight bits of the source into the lower eight bits of the result. 1638//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), 1639// (UXTB16r_rot GPR:$Src, 24)>; 1640def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), 1641 (UXTB16r_rot GPR:$Src, 8)>; 1642 1643defm UXTAB : AI_exta_rrot<0b01101110, "uxtab", 1644 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 1645defm UXTAH : AI_exta_rrot<0b01101111, "uxtah", 1646 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 1647} 1648 1649// This isn't safe in general, the add is two 16-bit units, not a 32-bit add. 1650// For disassembly only 1651defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; 1652 1653 1654def SBFX : I<(outs GPR:$dst), 1655 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), 1656 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 1657 "sbfx", "\t$dst, $src, $lsb, $width", "", []>, 1658 Requires<[IsARM, HasV6T2]> { 1659 let Inst{27-21} = 0b0111101; 1660 let Inst{6-4} = 0b101; 1661} 1662 1663def UBFX : I<(outs GPR:$dst), 1664 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), 1665 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 1666 "ubfx", "\t$dst, $src, $lsb, $width", "", []>, 1667 Requires<[IsARM, HasV6T2]> { 1668 let Inst{27-21} = 0b0111111; 1669 let Inst{6-4} = 0b101; 1670} 1671 1672//===----------------------------------------------------------------------===// 1673// Arithmetic Instructions. 1674// 1675 1676defm ADD : AsI1_bin_irs<0b0100, "add", 1677 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 1678 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 1679defm SUB : AsI1_bin_irs<0b0010, "sub", 1680 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 1681 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1682 1683// ADD and SUB with 's' bit set. 1684defm ADDS : AI1_bin_s_irs<0b0100, "adds", 1685 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 1686 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; 1687defm SUBS : AI1_bin_s_irs<0b0010, "subs", 1688 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 1689 BinOpFrag<(subc node:$LHS, node:$RHS)>>; 1690 1691defm ADC : AI1_adde_sube_irs<0b0101, "adc", 1692 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>; 1693defm SBC : AI1_adde_sube_irs<0b0110, "sbc", 1694 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>; 1695defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs", 1696 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>; 1697defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs", 1698 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>; 1699 1700def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 1701 IIC_iALUi, "rsb", "\t$dst, $a, $b", 1702 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> { 1703 let Inst{25} = 1; 1704} 1705 1706// The reg/reg form is only defined for the disassembler; for codegen it is 1707// equivalent to SUBrr. 1708def RSBrr : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, 1709 IIC_iALUr, "rsb", "\t$dst, $a, $b", 1710 [/* For disassembly only; pattern left blank */]> { 1711 let Inst{25} = 0; 1712 let Inst{11-4} = 0b00000000; 1713} 1714 1715def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 1716 IIC_iALUsr, "rsb", "\t$dst, $a, $b", 1717 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> { 1718 let Inst{25} = 0; 1719} 1720 1721// RSB with 's' bit set. 1722let Defs = [CPSR] in { 1723def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 1724 IIC_iALUi, "rsbs", "\t$dst, $a, $b", 1725 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> { 1726 let Inst{20} = 1; 1727 let Inst{25} = 1; 1728} 1729def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 1730 IIC_iALUsr, "rsbs", "\t$dst, $a, $b", 1731 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> { 1732 let Inst{20} = 1; 1733 let Inst{25} = 0; 1734} 1735} 1736 1737let Uses = [CPSR] in { 1738def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 1739 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b", 1740 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>, 1741 Requires<[IsARM]> { 1742 let Inst{25} = 1; 1743} 1744// The reg/reg form is only defined for the disassembler; for codegen it is 1745// equivalent to SUBrr. 1746def RSCrr : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1747 DPFrm, IIC_iALUr, "rsc", "\t$dst, $a, $b", 1748 [/* For disassembly only; pattern left blank */]> { 1749 let Inst{25} = 0; 1750 let Inst{11-4} = 0b00000000; 1751} 1752def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 1753 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b", 1754 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>, 1755 Requires<[IsARM]> { 1756 let Inst{25} = 0; 1757} 1758} 1759 1760// FIXME: Allow these to be predicated. 1761let Defs = [CPSR], Uses = [CPSR] in { 1762def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 1763 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b", 1764 [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>, 1765 Requires<[IsARM]> { 1766 let Inst{20} = 1; 1767 let Inst{25} = 1; 1768} 1769def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 1770 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b", 1771 [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>, 1772 Requires<[IsARM]> { 1773 let Inst{20} = 1; 1774 let Inst{25} = 0; 1775} 1776} 1777 1778// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1779// The assume-no-carry-in form uses the negation of the input since add/sub 1780// assume opposite meanings of the carry flag (i.e., carry == !borrow). 1781// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 1782// details. 1783def : ARMPat<(add GPR:$src, so_imm_neg:$imm), 1784 (SUBri GPR:$src, so_imm_neg:$imm)>; 1785def : ARMPat<(addc GPR:$src, so_imm_neg:$imm), 1786 (SUBSri GPR:$src, so_imm_neg:$imm)>; 1787// The with-carry-in form matches bitwise not instead of the negation. 1788// Effectively, the inverse interpretation of the carry flag already accounts 1789// for part of the negation. 1790def : ARMPat<(adde GPR:$src, so_imm_not:$imm), 1791 (SBCri GPR:$src, so_imm_not:$imm)>; 1792 1793// Note: These are implemented in C++ code, because they have to generate 1794// ADD/SUBrs instructions, which use a complex pattern that a xform function 1795// cannot produce. 1796// (mul X, 2^n+1) -> (add (X << n), X) 1797// (mul X, 2^n-1) -> (rsb X, (X << n)) 1798 1799// ARM Arithmetic Instruction -- for disassembly only 1800// GPR:$dst = GPR:$a op GPR:$b 1801class AAI<bits<8> op27_20, bits<4> op7_4, string opc, 1802 list<dag> pattern = [/* For disassembly only; pattern left blank */]> 1803 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr, 1804 opc, "\t$dst, $a, $b", pattern> { 1805 let Inst{27-20} = op27_20; 1806 let Inst{7-4} = op7_4; 1807} 1808 1809// Saturating add/subtract -- for disassembly only 1810 1811def QADD : AAI<0b00010000, 0b0101, "qadd", 1812 [(set GPR:$dst, (int_arm_qadd GPR:$a, GPR:$b))]>; 1813def QADD16 : AAI<0b01100010, 0b0001, "qadd16">; 1814def QADD8 : AAI<0b01100010, 0b1001, "qadd8">; 1815def QASX : AAI<0b01100010, 0b0011, "qasx">; 1816def QDADD : AAI<0b00010100, 0b0101, "qdadd">; 1817def QDSUB : AAI<0b00010110, 0b0101, "qdsub">; 1818def QSAX : AAI<0b01100010, 0b0101, "qsax">; 1819def QSUB : AAI<0b00010010, 0b0101, "qsub", 1820 [(set GPR:$dst, (int_arm_qsub GPR:$a, GPR:$b))]>; 1821def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">; 1822def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">; 1823def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">; 1824def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">; 1825def UQASX : AAI<0b01100110, 0b0011, "uqasx">; 1826def UQSAX : AAI<0b01100110, 0b0101, "uqsax">; 1827def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">; 1828def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">; 1829 1830// Signed/Unsigned add/subtract -- for disassembly only 1831 1832def SASX : AAI<0b01100001, 0b0011, "sasx">; 1833def SADD16 : AAI<0b01100001, 0b0001, "sadd16">; 1834def SADD8 : AAI<0b01100001, 0b1001, "sadd8">; 1835def SSAX : AAI<0b01100001, 0b0101, "ssax">; 1836def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">; 1837def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">; 1838def UASX : AAI<0b01100101, 0b0011, "uasx">; 1839def UADD16 : AAI<0b01100101, 0b0001, "uadd16">; 1840def UADD8 : AAI<0b01100101, 0b1001, "uadd8">; 1841def USAX : AAI<0b01100101, 0b0101, "usax">; 1842def USUB16 : AAI<0b01100101, 0b0111, "usub16">; 1843def USUB8 : AAI<0b01100101, 0b1111, "usub8">; 1844 1845// Signed/Unsigned halving add/subtract -- for disassembly only 1846 1847def SHASX : AAI<0b01100011, 0b0011, "shasx">; 1848def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">; 1849def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">; 1850def SHSAX : AAI<0b01100011, 0b0101, "shsax">; 1851def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">; 1852def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">; 1853def UHASX : AAI<0b01100111, 0b0011, "uhasx">; 1854def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">; 1855def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">; 1856def UHSAX : AAI<0b01100111, 0b0101, "uhsax">; 1857def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">; 1858def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">; 1859 1860// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only 1861 1862def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), 1863 MulFrm /* for convenience */, NoItinerary, "usad8", 1864 "\t$dst, $a, $b", []>, 1865 Requires<[IsARM, HasV6]> { 1866 let Inst{27-20} = 0b01111000; 1867 let Inst{15-12} = 0b1111; 1868 let Inst{7-4} = 0b0001; 1869} 1870def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1871 MulFrm /* for convenience */, NoItinerary, "usada8", 1872 "\t$dst, $a, $b, $acc", []>, 1873 Requires<[IsARM, HasV6]> { 1874 let Inst{27-20} = 0b01111000; 1875 let Inst{7-4} = 0b0001; 1876} 1877 1878// Signed/Unsigned saturate -- for disassembly only 1879 1880def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh), 1881 SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh", 1882 [/* For disassembly only; pattern left blank */]> { 1883 let Inst{27-21} = 0b0110101; 1884 let Inst{5-4} = 0b01; 1885} 1886 1887def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm, 1888 NoItinerary, "ssat16", "\t$dst, $bit_pos, $a", 1889 [/* For disassembly only; pattern left blank */]> { 1890 let Inst{27-20} = 0b01101010; 1891 let Inst{7-4} = 0b0011; 1892} 1893 1894def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, shift_imm:$sh), 1895 SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh", 1896 [/* For disassembly only; pattern left blank */]> { 1897 let Inst{27-21} = 0b0110111; 1898 let Inst{5-4} = 0b01; 1899} 1900 1901def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm, 1902 NoItinerary, "usat16", "\t$dst, $bit_pos, $a", 1903 [/* For disassembly only; pattern left blank */]> { 1904 let Inst{27-20} = 0b01101110; 1905 let Inst{7-4} = 0b0011; 1906} 1907 1908def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>; 1909def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>; 1910 1911//===----------------------------------------------------------------------===// 1912// Bitwise Instructions. 1913// 1914 1915defm AND : AsI1_bin_irs<0b0000, "and", 1916 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 1917 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 1918defm ANDS : AI1_bin_s_irs<0b0000, "and", 1919 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 1920 BinOpFrag<(ARMand node:$LHS, node:$RHS)>, 1>; 1921defm ORR : AsI1_bin_irs<0b1100, "orr", 1922 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 1923 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 1924defm EOR : AsI1_bin_irs<0b0001, "eor", 1925 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 1926 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 1927defm BIC : AsI1_bin_irs<0b1110, "bic", 1928 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 1929 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 1930 1931def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), 1932 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 1933 "bfc", "\t$dst, $imm", "$src = $dst", 1934 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>, 1935 Requires<[IsARM, HasV6T2]> { 1936 let Inst{27-21} = 0b0111110; 1937 let Inst{6-0} = 0b0011111; 1938} 1939 1940// A8.6.18 BFI - Bitfield insert (Encoding A1) 1941def BFI : I<(outs GPR:$dst), (ins GPR:$src, GPR:$val, bf_inv_mask_imm:$imm), 1942 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 1943 "bfi", "\t$dst, $val, $imm", "$src = $dst", 1944 [(set GPR:$dst, (ARMbfi GPR:$src, GPR:$val, 1945 bf_inv_mask_imm:$imm))]>, 1946 Requires<[IsARM, HasV6T2]> { 1947 let Inst{27-21} = 0b0111110; 1948 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 1949} 1950 1951def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMVNr, 1952 "mvn", "\t$dst, $src", 1953 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP { 1954 let Inst{25} = 0; 1955 let Inst{11-4} = 0b00000000; 1956} 1957def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm, 1958 IIC_iMVNsr, "mvn", "\t$dst, $src", 1959 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP { 1960 let Inst{25} = 0; 1961} 1962let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1963def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 1964 IIC_iMVNi, "mvn", "\t$dst, $imm", 1965 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP { 1966 let Inst{25} = 1; 1967} 1968 1969def : ARMPat<(and GPR:$src, so_imm_not:$imm), 1970 (BICri GPR:$src, so_imm_not:$imm)>; 1971 1972//===----------------------------------------------------------------------===// 1973// Multiply Instructions. 1974// 1975 1976let isCommutable = 1 in 1977def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1978 IIC_iMUL32, "mul", "\t$dst, $a, $b", 1979 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; 1980 1981def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1982 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c", 1983 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; 1984 1985def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1986 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c", 1987 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>, 1988 Requires<[IsARM, HasV6T2]>; 1989 1990// Extra precision multiplies with low / high results 1991let neverHasSideEffects = 1 in { 1992let isCommutable = 1 in { 1993def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst), 1994 (ins GPR:$a, GPR:$b), IIC_iMUL64, 1995 "smull", "\t$ldst, $hdst, $a, $b", []>; 1996 1997def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst), 1998 (ins GPR:$a, GPR:$b), IIC_iMUL64, 1999 "umull", "\t$ldst, $hdst, $a, $b", []>; 2000} 2001 2002// Multiply + accumulate 2003def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst), 2004 (ins GPR:$a, GPR:$b), IIC_iMAC64, 2005 "smlal", "\t$ldst, $hdst, $a, $b", []>; 2006 2007def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst), 2008 (ins GPR:$a, GPR:$b), IIC_iMAC64, 2009 "umlal", "\t$ldst, $hdst, $a, $b", []>; 2010 2011def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst), 2012 (ins GPR:$a, GPR:$b), IIC_iMAC64, 2013 "umaal", "\t$ldst, $hdst, $a, $b", []>, 2014 Requires<[IsARM, HasV6]>; 2015} // neverHasSideEffects 2016 2017// Most significant word multiply 2018def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2019 IIC_iMUL32, "smmul", "\t$dst, $a, $b", 2020 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>, 2021 Requires<[IsARM, HasV6]> { 2022 let Inst{7-4} = 0b0001; 2023 let Inst{15-12} = 0b1111; 2024} 2025 2026def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2027 IIC_iMUL32, "smmulr", "\t$dst, $a, $b", 2028 [/* For disassembly only; pattern left blank */]>, 2029 Requires<[IsARM, HasV6]> { 2030 let Inst{7-4} = 0b0011; // R = 1 2031 let Inst{15-12} = 0b1111; 2032} 2033 2034def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 2035 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c", 2036 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>, 2037 Requires<[IsARM, HasV6]> { 2038 let Inst{7-4} = 0b0001; 2039} 2040 2041def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 2042 IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c", 2043 [/* For disassembly only; pattern left blank */]>, 2044 Requires<[IsARM, HasV6]> { 2045 let Inst{7-4} = 0b0011; // R = 1 2046} 2047 2048def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 2049 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c", 2050 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>, 2051 Requires<[IsARM, HasV6]> { 2052 let Inst{7-4} = 0b1101; 2053} 2054 2055def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 2056 IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c", 2057 [/* For disassembly only; pattern left blank */]>, 2058 Requires<[IsARM, HasV6]> { 2059 let Inst{7-4} = 0b1111; // R = 1 2060} 2061 2062multiclass AI_smul<string opc, PatFrag opnode> { 2063 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2064 IIC_iMUL16, !strconcat(opc, "bb"), "\t$dst, $a, $b", 2065 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), 2066 (sext_inreg GPR:$b, i16)))]>, 2067 Requires<[IsARM, HasV5TE]> { 2068 let Inst{5} = 0; 2069 let Inst{6} = 0; 2070 } 2071 2072 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2073 IIC_iMUL16, !strconcat(opc, "bt"), "\t$dst, $a, $b", 2074 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), 2075 (sra GPR:$b, (i32 16))))]>, 2076 Requires<[IsARM, HasV5TE]> { 2077 let Inst{5} = 0; 2078 let Inst{6} = 1; 2079 } 2080 2081 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2082 IIC_iMUL16, !strconcat(opc, "tb"), "\t$dst, $a, $b", 2083 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), 2084 (sext_inreg GPR:$b, i16)))]>, 2085 Requires<[IsARM, HasV5TE]> { 2086 let Inst{5} = 1; 2087 let Inst{6} = 0; 2088 } 2089 2090 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2091 IIC_iMUL16, !strconcat(opc, "tt"), "\t$dst, $a, $b", 2092 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), 2093 (sra GPR:$b, (i32 16))))]>, 2094 Requires<[IsARM, HasV5TE]> { 2095 let Inst{5} = 1; 2096 let Inst{6} = 1; 2097 } 2098 2099 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2100 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b", 2101 [(set GPR:$dst, (sra (opnode GPR:$a, 2102 (sext_inreg GPR:$b, i16)), (i32 16)))]>, 2103 Requires<[IsARM, HasV5TE]> { 2104 let Inst{5} = 1; 2105 let Inst{6} = 0; 2106 } 2107 2108 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2109 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b", 2110 [(set GPR:$dst, (sra (opnode GPR:$a, 2111 (sra GPR:$b, (i32 16))), (i32 16)))]>, 2112 Requires<[IsARM, HasV5TE]> { 2113 let Inst{5} = 1; 2114 let Inst{6} = 1; 2115 } 2116} 2117 2118 2119multiclass AI_smla<string opc, PatFrag opnode> { 2120 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 2121 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", 2122 [(set GPR:$dst, (add GPR:$acc, 2123 (opnode (sext_inreg GPR:$a, i16), 2124 (sext_inreg GPR:$b, i16))))]>, 2125 Requires<[IsARM, HasV5TE]> { 2126 let Inst{5} = 0; 2127 let Inst{6} = 0; 2128 } 2129 2130 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 2131 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", 2132 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16), 2133 (sra GPR:$b, (i32 16)))))]>, 2134 Requires<[IsARM, HasV5TE]> { 2135 let Inst{5} = 0; 2136 let Inst{6} = 1; 2137 } 2138 2139 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 2140 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", 2141 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)), 2142 (sext_inreg GPR:$b, i16))))]>, 2143 Requires<[IsARM, HasV5TE]> { 2144 let Inst{5} = 1; 2145 let Inst{6} = 0; 2146 } 2147 2148 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 2149 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", 2150 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)), 2151 (sra GPR:$b, (i32 16)))))]>, 2152 Requires<[IsARM, HasV5TE]> { 2153 let Inst{5} = 1; 2154 let Inst{6} = 1; 2155 } 2156 2157 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 2158 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", 2159 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, 2160 (sext_inreg GPR:$b, i16)), (i32 16))))]>, 2161 Requires<[IsARM, HasV5TE]> { 2162 let Inst{5} = 0; 2163 let Inst{6} = 0; 2164 } 2165 2166 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 2167 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", 2168 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, 2169 (sra GPR:$b, (i32 16))), (i32 16))))]>, 2170 Requires<[IsARM, HasV5TE]> { 2171 let Inst{5} = 0; 2172 let Inst{6} = 1; 2173 } 2174} 2175 2176defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2177defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2178 2179// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only 2180def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b), 2181 IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b", 2182 [/* For disassembly only; pattern left blank */]>, 2183 Requires<[IsARM, HasV5TE]> { 2184 let Inst{5} = 0; 2185 let Inst{6} = 0; 2186} 2187 2188def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b), 2189 IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b", 2190 [/* For disassembly only; pattern left blank */]>, 2191 Requires<[IsARM, HasV5TE]> { 2192 let Inst{5} = 0; 2193 let Inst{6} = 1; 2194} 2195 2196def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b), 2197 IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b", 2198 [/* For disassembly only; pattern left blank */]>, 2199 Requires<[IsARM, HasV5TE]> { 2200 let Inst{5} = 1; 2201 let Inst{6} = 0; 2202} 2203 2204def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b), 2205 IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b", 2206 [/* For disassembly only; pattern left blank */]>, 2207 Requires<[IsARM, HasV5TE]> { 2208 let Inst{5} = 1; 2209 let Inst{6} = 1; 2210} 2211 2212// Helper class for AI_smld -- for disassembly only 2213class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops, 2214 InstrItinClass itin, string opc, string asm> 2215 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> { 2216 let Inst{4} = 1; 2217 let Inst{5} = swap; 2218 let Inst{6} = sub; 2219 let Inst{7} = 0; 2220 let Inst{21-20} = 0b00; 2221 let Inst{22} = long; 2222 let Inst{27-23} = 0b01110; 2223} 2224 2225multiclass AI_smld<bit sub, string opc> { 2226 2227 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 2228 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">; 2229 2230 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 2231 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">; 2232 2233 def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b), 2234 NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">; 2235 2236 def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b), 2237 NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">; 2238 2239} 2240 2241defm SMLA : AI_smld<0, "smla">; 2242defm SMLS : AI_smld<1, "smls">; 2243 2244multiclass AI_sdml<bit sub, string opc> { 2245 2246 def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2247 NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> { 2248 let Inst{15-12} = 0b1111; 2249 } 2250 2251 def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 2252 NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> { 2253 let Inst{15-12} = 0b1111; 2254 } 2255 2256} 2257 2258defm SMUA : AI_sdml<0, "smua">; 2259defm SMUS : AI_sdml<1, "smus">; 2260 2261//===----------------------------------------------------------------------===// 2262// Misc. Arithmetic Instructions. 2263// 2264 2265def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 2266 "clz", "\t$dst, $src", 2267 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> { 2268 let Inst{7-4} = 0b0001; 2269 let Inst{11-8} = 0b1111; 2270 let Inst{19-16} = 0b1111; 2271} 2272 2273def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 2274 "rbit", "\t$dst, $src", 2275 [(set GPR:$dst, (ARMrbit GPR:$src))]>, 2276 Requires<[IsARM, HasV6T2]> { 2277 let Inst{7-4} = 0b0011; 2278 let Inst{11-8} = 0b1111; 2279 let Inst{19-16} = 0b1111; 2280} 2281 2282def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 2283 "rev", "\t$dst, $src", 2284 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> { 2285 let Inst{7-4} = 0b0011; 2286 let Inst{11-8} = 0b1111; 2287 let Inst{19-16} = 0b1111; 2288} 2289 2290def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 2291 "rev16", "\t$dst, $src", 2292 [(set GPR:$dst, 2293 (or (and (srl GPR:$src, (i32 8)), 0xFF), 2294 (or (and (shl GPR:$src, (i32 8)), 0xFF00), 2295 (or (and (srl GPR:$src, (i32 8)), 0xFF0000), 2296 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>, 2297 Requires<[IsARM, HasV6]> { 2298 let Inst{7-4} = 0b1011; 2299 let Inst{11-8} = 0b1111; 2300 let Inst{19-16} = 0b1111; 2301} 2302 2303def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 2304 "revsh", "\t$dst, $src", 2305 [(set GPR:$dst, 2306 (sext_inreg 2307 (or (srl (and GPR:$src, 0xFF00), (i32 8)), 2308 (shl GPR:$src, (i32 8))), i16))]>, 2309 Requires<[IsARM, HasV6]> { 2310 let Inst{7-4} = 0b1011; 2311 let Inst{11-8} = 0b1111; 2312 let Inst{19-16} = 0b1111; 2313} 2314 2315def lsl_shift_imm : SDNodeXForm<imm, [{ 2316 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue()); 2317 return CurDAG->getTargetConstant(Sh, MVT::i32); 2318}]>; 2319 2320def lsl_amt : PatLeaf<(i32 imm), [{ 2321 return (N->getZExtValue() < 32); 2322}], lsl_shift_imm>; 2323 2324def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst), 2325 (ins GPR:$src1, GPR:$src2, shift_imm:$sh), 2326 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh", 2327 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), 2328 (and (shl GPR:$src2, lsl_amt:$sh), 2329 0xFFFF0000)))]>, 2330 Requires<[IsARM, HasV6]> { 2331 let Inst{6-4} = 0b001; 2332} 2333 2334// Alternate cases for PKHBT where identities eliminate some nodes. 2335def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)), 2336 (PKHBT GPR:$src1, GPR:$src2, 0)>; 2337def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$sh)), 2338 (PKHBT GPR:$src1, GPR:$src2, (lsl_shift_imm imm16_31:$sh))>; 2339 2340def asr_shift_imm : SDNodeXForm<imm, [{ 2341 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue()); 2342 return CurDAG->getTargetConstant(Sh, MVT::i32); 2343}]>; 2344 2345def asr_amt : PatLeaf<(i32 imm), [{ 2346 return (N->getZExtValue() <= 32); 2347}], asr_shift_imm>; 2348 2349// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 2350// will match the pattern below. 2351def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst), 2352 (ins GPR:$src1, GPR:$src2, shift_imm:$sh), 2353 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh", 2354 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), 2355 (and (sra GPR:$src2, asr_amt:$sh), 2356 0xFFFF)))]>, 2357 Requires<[IsARM, HasV6]> { 2358 let Inst{6-4} = 0b101; 2359} 2360 2361// Alternate cases for PKHTB where identities eliminate some nodes. Note that 2362// a shift amount of 0 is *not legal* here, it is PKHBT instead. 2363def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)), 2364 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>; 2365def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), 2366 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)), 2367 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>; 2368 2369//===----------------------------------------------------------------------===// 2370// Comparison Instructions... 2371// 2372 2373defm CMP : AI1_cmp_irs<0b1010, "cmp", 2374 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, 2375 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 2376 2377// FIXME: We have to be careful when using the CMN instruction and comparison 2378// with 0. One would expect these two pieces of code should give identical 2379// results: 2380// 2381// rsbs r1, r1, 0 2382// cmp r0, r1 2383// mov r0, #0 2384// it ls 2385// mov r0, #1 2386// 2387// and: 2388// 2389// cmn r0, r1 2390// mov r0, #0 2391// it ls 2392// mov r0, #1 2393// 2394// However, the CMN gives the *opposite* result when r1 is 0. This is because 2395// the carry flag is set in the CMP case but not in the CMN case. In short, the 2396// CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the 2397// value of r0 and the carry bit (because the "carry bit" parameter to 2398// AddWithCarry is defined as 1 in this case, the carry flag will always be set 2399// when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is 2400// never a "carry" when this AddWithCarry is performed (because the "carry bit" 2401// parameter to AddWithCarry is defined as 0). 2402// 2403// When x is 0 and unsigned: 2404// 2405// x = 0 2406// ~x = 0xFFFF FFFF 2407// ~x + 1 = 0x1 0000 0000 2408// (-x = 0) != (0x1 0000 0000 = ~x + 1) 2409// 2410// Therefore, we should disable CMN when comparing against zero, until we can 2411// limit when the CMN instruction is used (when we know that the RHS is not 0 or 2412// when it's a comparison which doesn't look at the 'carry' flag). 2413// 2414// (See the ARM docs for the "AddWithCarry" pseudo-code.) 2415// 2416// This is related to <rdar://problem/7569620>. 2417// 2418//defm CMN : AI1_cmp_irs<0b1011, "cmn", 2419// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; 2420 2421// Note that TST/TEQ don't set all the same flags that CMP does! 2422defm TST : AI1_cmp_irs<0b1000, "tst", 2423 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 2424 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>; 2425defm TEQ : AI1_cmp_irs<0b1001, "teq", 2426 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 2427 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>; 2428 2429defm CMPz : AI1_cmp_irs<0b1010, "cmp", 2430 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, 2431 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>; 2432defm CMNz : AI1_cmp_irs<0b1011, "cmn", 2433 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, 2434 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>; 2435 2436//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), 2437// (CMNri GPR:$src, so_imm_neg:$imm)>; 2438 2439def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm), 2440 (CMNzri GPR:$src, so_imm_neg:$imm)>; 2441 2442// Pseudo i64 compares for some floating point compares. 2443let usesCustomInserter = 1, isBranch = 1, isTerminator = 1, 2444 Defs = [CPSR] in { 2445def BCCi64 : PseudoInst<(outs), 2446 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst), 2447 IIC_Br, "", 2448 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>; 2449 2450def BCCZi64 : PseudoInst<(outs), 2451 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, "", 2452 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>; 2453} // usesCustomInserter 2454 2455 2456// Conditional moves 2457// FIXME: should be able to write a pattern for ARMcmov, but can't use 2458// a two-value operand where a dag node expects two operands. :( 2459// FIXME: These should all be pseudo-instructions that get expanded to 2460// the normal MOV instructions. That would fix the dependency on 2461// special casing them in tblgen. 2462let neverHasSideEffects = 1 in { 2463def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm, 2464 IIC_iCMOVr, "mov", "\t$dst, $true", 2465 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>, 2466 RegConstraint<"$false = $dst">, UnaryDP { 2467 let Inst{11-4} = 0b00000000; 2468 let Inst{25} = 0; 2469} 2470 2471def MOVCCs : AI1<0b1101, (outs GPR:$dst), 2472 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr, 2473 "mov", "\t$dst, $true", 2474 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>, 2475 RegConstraint<"$false = $dst">, UnaryDP { 2476 let Inst{25} = 0; 2477} 2478 2479def MOVCCi16 : AI1<0b1000, (outs GPR:$dst), (ins GPR:$false, i32imm:$src), 2480 DPFrm, IIC_iMOVi, 2481 "movw", "\t$dst, $src", 2482 []>, 2483 RegConstraint<"$false = $dst">, Requires<[IsARM, HasV6T2]>, 2484 UnaryDP { 2485 let Inst{20} = 0; 2486 let Inst{25} = 1; 2487} 2488 2489def MOVCCi : AI1<0b1101, (outs GPR:$dst), 2490 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi, 2491 "mov", "\t$dst, $true", 2492 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>, 2493 RegConstraint<"$false = $dst">, UnaryDP { 2494 let Inst{25} = 1; 2495} 2496} // neverHasSideEffects 2497 2498//===----------------------------------------------------------------------===// 2499// Atomic operations intrinsics 2500// 2501 2502// memory barriers protect the atomic sequences 2503let hasSideEffects = 1 in { 2504def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "", 2505 [(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> { 2506 let Inst{31-4} = 0xf57ff05; 2507 // FIXME: add support for options other than a full system DMB 2508 // See DMB disassembly-only variants below. 2509 let Inst{3-0} = 0b1111; 2510} 2511 2512def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "", 2513 [(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> { 2514 let Inst{31-4} = 0xf57ff04; 2515 // FIXME: add support for options other than a full system DSB 2516 // See DSB disassembly-only variants below. 2517 let Inst{3-0} = 0b1111; 2518} 2519 2520def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary, 2521 "mcr", "\tp15, 0, $zero, c7, c10, 5", 2522 [(ARMMemBarrierMCR GPR:$zero)]>, 2523 Requires<[IsARM, HasV6]> { 2524 // FIXME: add support for options other than a full system DMB 2525 // FIXME: add encoding 2526} 2527 2528def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary, 2529 "mcr", "\tp15, 0, $zero, c7, c10, 4", 2530 [(ARMSyncBarrierMCR GPR:$zero)]>, 2531 Requires<[IsARM, HasV6]> { 2532 // FIXME: add support for options other than a full system DSB 2533 // FIXME: add encoding 2534} 2535} 2536 2537// Memory Barrier Operations Variants -- for disassembly only 2538 2539def memb_opt : Operand<i32> { 2540 let PrintMethod = "printMemBOption"; 2541} 2542 2543class AMBI<bits<4> op7_4, string opc> 2544 : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt", 2545 [/* For disassembly only; pattern left blank */]>, 2546 Requires<[IsARM, HasDB]> { 2547 let Inst{31-8} = 0xf57ff0; 2548 let Inst{7-4} = op7_4; 2549} 2550 2551// These DMB variants are for disassembly only. 2552def DMBvar : AMBI<0b0101, "dmb">; 2553 2554// These DSB variants are for disassembly only. 2555def DSBvar : AMBI<0b0100, "dsb">; 2556 2557// ISB has only full system option -- for disassembly only 2558def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>, 2559 Requires<[IsARM, HasDB]> { 2560 let Inst{31-4} = 0xf57ff06; 2561 let Inst{3-0} = 0b1111; 2562} 2563 2564let usesCustomInserter = 1 in { 2565 let Uses = [CPSR] in { 2566 def ATOMIC_LOAD_ADD_I8 : PseudoInst< 2567 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2568 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>; 2569 def ATOMIC_LOAD_SUB_I8 : PseudoInst< 2570 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2571 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>; 2572 def ATOMIC_LOAD_AND_I8 : PseudoInst< 2573 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2574 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>; 2575 def ATOMIC_LOAD_OR_I8 : PseudoInst< 2576 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2577 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>; 2578 def ATOMIC_LOAD_XOR_I8 : PseudoInst< 2579 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2580 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>; 2581 def ATOMIC_LOAD_NAND_I8 : PseudoInst< 2582 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2583 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>; 2584 def ATOMIC_LOAD_ADD_I16 : PseudoInst< 2585 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2586 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>; 2587 def ATOMIC_LOAD_SUB_I16 : PseudoInst< 2588 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2589 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>; 2590 def ATOMIC_LOAD_AND_I16 : PseudoInst< 2591 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2592 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>; 2593 def ATOMIC_LOAD_OR_I16 : PseudoInst< 2594 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2595 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>; 2596 def ATOMIC_LOAD_XOR_I16 : PseudoInst< 2597 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2598 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>; 2599 def ATOMIC_LOAD_NAND_I16 : PseudoInst< 2600 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2601 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>; 2602 def ATOMIC_LOAD_ADD_I32 : PseudoInst< 2603 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2604 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>; 2605 def ATOMIC_LOAD_SUB_I32 : PseudoInst< 2606 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2607 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>; 2608 def ATOMIC_LOAD_AND_I32 : PseudoInst< 2609 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2610 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>; 2611 def ATOMIC_LOAD_OR_I32 : PseudoInst< 2612 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2613 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>; 2614 def ATOMIC_LOAD_XOR_I32 : PseudoInst< 2615 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2616 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>; 2617 def ATOMIC_LOAD_NAND_I32 : PseudoInst< 2618 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, "", 2619 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>; 2620 2621 def ATOMIC_SWAP_I8 : PseudoInst< 2622 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "", 2623 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>; 2624 def ATOMIC_SWAP_I16 : PseudoInst< 2625 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "", 2626 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>; 2627 def ATOMIC_SWAP_I32 : PseudoInst< 2628 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, "", 2629 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>; 2630 2631 def ATOMIC_CMP_SWAP_I8 : PseudoInst< 2632 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "", 2633 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>; 2634 def ATOMIC_CMP_SWAP_I16 : PseudoInst< 2635 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "", 2636 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>; 2637 def ATOMIC_CMP_SWAP_I32 : PseudoInst< 2638 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "", 2639 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>; 2640} 2641} 2642 2643let mayLoad = 1 in { 2644def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 2645 "ldrexb", "\t$dest, [$ptr]", 2646 []>; 2647def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 2648 "ldrexh", "\t$dest, [$ptr]", 2649 []>; 2650def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 2651 "ldrex", "\t$dest, [$ptr]", 2652 []>; 2653def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr), 2654 NoItinerary, 2655 "ldrexd", "\t$dest, $dest2, [$ptr]", 2656 []>; 2657} 2658 2659let mayStore = 1, Constraints = "@earlyclobber $success" in { 2660def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 2661 NoItinerary, 2662 "strexb", "\t$success, $src, [$ptr]", 2663 []>; 2664def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 2665 NoItinerary, 2666 "strexh", "\t$success, $src, [$ptr]", 2667 []>; 2668def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 2669 NoItinerary, 2670 "strex", "\t$success, $src, [$ptr]", 2671 []>; 2672def STREXD : AIstrex<0b01, (outs GPR:$success), 2673 (ins GPR:$src, GPR:$src2, GPR:$ptr), 2674 NoItinerary, 2675 "strexd", "\t$success, $src, $src2, [$ptr]", 2676 []>; 2677} 2678 2679// Clear-Exclusive is for disassembly only. 2680def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", 2681 [/* For disassembly only; pattern left blank */]>, 2682 Requires<[IsARM, HasV7]> { 2683 let Inst{31-20} = 0xf57; 2684 let Inst{7-4} = 0b0001; 2685} 2686 2687// SWP/SWPB are deprecated in V6/V7 and for disassembly only. 2688let mayLoad = 1 in { 2689def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary, 2690 "swp", "\t$dst, $src, [$ptr]", 2691 [/* For disassembly only; pattern left blank */]> { 2692 let Inst{27-23} = 0b00010; 2693 let Inst{22} = 0; // B = 0 2694 let Inst{21-20} = 0b00; 2695 let Inst{7-4} = 0b1001; 2696} 2697 2698def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary, 2699 "swpb", "\t$dst, $src, [$ptr]", 2700 [/* For disassembly only; pattern left blank */]> { 2701 let Inst{27-23} = 0b00010; 2702 let Inst{22} = 1; // B = 1 2703 let Inst{21-20} = 0b00; 2704 let Inst{7-4} = 0b1001; 2705} 2706} 2707 2708//===----------------------------------------------------------------------===// 2709// TLS Instructions 2710// 2711 2712// __aeabi_read_tp preserves the registers r1-r3. 2713let isCall = 1, 2714 Defs = [R0, R12, LR, CPSR] in { 2715 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br, 2716 "bl\t__aeabi_read_tp", 2717 [(set R0, ARMthread_pointer)]>; 2718} 2719 2720//===----------------------------------------------------------------------===// 2721// SJLJ Exception handling intrinsics 2722// eh_sjlj_setjmp() is an instruction sequence to store the return 2723// address and save #0 in R0 for the non-longjmp case. 2724// Since by its nature we may be coming from some other function to get 2725// here, and we're using the stack frame for the containing function to 2726// save/restore registers, we can't keep anything live in regs across 2727// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 2728// when we get here from a longjmp(). We force everthing out of registers 2729// except for our own input by listing the relevant registers in Defs. By 2730// doing so, we also cause the prologue/epilogue code to actively preserve 2731// all of the callee-saved resgisters, which is exactly what we want. 2732// A constant value is passed in $val, and we use the location as a scratch. 2733let Defs = 2734 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0, 2735 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, 2736 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, 2737 D31 ], hasSideEffects = 1, isBarrier = 1 in { 2738 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val), 2739 AddrModeNone, SizeSpecial, IndexModeNone, 2740 Pseudo, NoItinerary, "", "", 2741 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 2742 Requires<[IsARM, HasVFP2]>; 2743} 2744 2745let Defs = 2746 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ], 2747 hasSideEffects = 1, isBarrier = 1 in { 2748 def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val), 2749 AddrModeNone, SizeSpecial, IndexModeNone, 2750 Pseudo, NoItinerary, "", "", 2751 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 2752 Requires<[IsARM, NoVFP]>; 2753} 2754 2755// FIXME: Non-Darwin version(s) 2756let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, 2757 Defs = [ R7, LR, SP ] in { 2758def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch), 2759 AddrModeNone, SizeSpecial, IndexModeNone, 2760 Pseudo, NoItinerary, "", "", 2761 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, 2762 Requires<[IsARM, IsDarwin]>; 2763} 2764 2765//===----------------------------------------------------------------------===// 2766// Non-Instruction Patterns 2767// 2768 2769// Large immediate handling. 2770 2771// Two piece so_imms. 2772// FIXME: Expand this in ARMExpandPseudoInsts. 2773// FIXME: Remove this when we can do generalized remat. 2774let isReMaterializable = 1 in 2775def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 2776 Pseudo, IIC_iMOVix2, 2777 "mov", "\t$dst, $src", 2778 [(set GPR:$dst, so_imm2part:$src)]>, 2779 Requires<[IsARM, NoV6T2]>; 2780 2781def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS), 2782 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 2783 (so_imm2part_2 imm:$RHS))>; 2784def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS), 2785 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 2786 (so_imm2part_2 imm:$RHS))>; 2787def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS), 2788 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 2789 (so_imm2part_2 imm:$RHS))>; 2790def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS), 2791 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)), 2792 (so_neg_imm2part_2 imm:$RHS))>; 2793 2794// 32-bit immediate using movw + movt. 2795// This is a single pseudo instruction, the benefit is that it can be remat'd 2796// as a single unit instead of having to handle reg inputs. 2797// FIXME: Remove this when we can do generalized remat. 2798let isReMaterializable = 1 in 2799def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, "", 2800 [(set GPR:$dst, (i32 imm:$src))]>, 2801 Requires<[IsARM, HasV6T2]>; 2802 2803// ConstantPool, GlobalAddress, and JumpTable 2804def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>, 2805 Requires<[IsARM, DontUseMovt]>; 2806def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; 2807def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>, 2808 Requires<[IsARM, UseMovt]>; 2809def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), 2810 (LEApcrelJT tjumptable:$dst, imm:$id)>; 2811 2812// TODO: add,sub,and, 3-instr forms? 2813 2814// Tail calls 2815def : ARMPat<(ARMtcret tcGPR:$dst), 2816 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>; 2817 2818def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)), 2819 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>; 2820 2821def : ARMPat<(ARMtcret (i32 texternalsym:$dst)), 2822 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>; 2823 2824def : ARMPat<(ARMtcret tcGPR:$dst), 2825 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>; 2826 2827def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)), 2828 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>; 2829 2830def : ARMPat<(ARMtcret (i32 texternalsym:$dst)), 2831 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>; 2832 2833// Direct calls 2834def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>, 2835 Requires<[IsARM, IsNotDarwin]>; 2836def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>, 2837 Requires<[IsARM, IsDarwin]>; 2838 2839// zextload i1 -> zextload i8 2840def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; 2841 2842// extload -> zextload 2843def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; 2844def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>; 2845def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; 2846 2847def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; 2848def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>; 2849 2850// smul* and smla* 2851def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 2852 (sra (shl GPR:$b, (i32 16)), (i32 16))), 2853 (SMULBB GPR:$a, GPR:$b)>; 2854def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b), 2855 (SMULBB GPR:$a, GPR:$b)>; 2856def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 2857 (sra GPR:$b, (i32 16))), 2858 (SMULBT GPR:$a, GPR:$b)>; 2859def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))), 2860 (SMULBT GPR:$a, GPR:$b)>; 2861def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), 2862 (sra (shl GPR:$b, (i32 16)), (i32 16))), 2863 (SMULTB GPR:$a, GPR:$b)>; 2864def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b), 2865 (SMULTB GPR:$a, GPR:$b)>; 2866def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 2867 (i32 16)), 2868 (SMULWB GPR:$a, GPR:$b)>; 2869def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)), 2870 (SMULWB GPR:$a, GPR:$b)>; 2871 2872def : ARMV5TEPat<(add GPR:$acc, 2873 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 2874 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 2875 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 2876def : ARMV5TEPat<(add GPR:$acc, 2877 (mul sext_16_node:$a, sext_16_node:$b)), 2878 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 2879def : ARMV5TEPat<(add GPR:$acc, 2880 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 2881 (sra GPR:$b, (i32 16)))), 2882 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 2883def : ARMV5TEPat<(add GPR:$acc, 2884 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))), 2885 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 2886def : ARMV5TEPat<(add GPR:$acc, 2887 (mul (sra GPR:$a, (i32 16)), 2888 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 2889 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 2890def : ARMV5TEPat<(add GPR:$acc, 2891 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)), 2892 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 2893def : ARMV5TEPat<(add GPR:$acc, 2894 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 2895 (i32 16))), 2896 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 2897def : ARMV5TEPat<(add GPR:$acc, 2898 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))), 2899 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 2900 2901//===----------------------------------------------------------------------===// 2902// Thumb Support 2903// 2904 2905include "ARMInstrThumb.td" 2906 2907//===----------------------------------------------------------------------===// 2908// Thumb2 Support 2909// 2910 2911include "ARMInstrThumb2.td" 2912 2913//===----------------------------------------------------------------------===// 2914// Floating Point Support 2915// 2916 2917include "ARMInstrVFP.td" 2918 2919//===----------------------------------------------------------------------===// 2920// Advanced SIMD (NEON) Support 2921// 2922 2923include "ARMInstrNEON.td" 2924 2925//===----------------------------------------------------------------------===// 2926// Coprocessor Instructions. For disassembly only. 2927// 2928 2929def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 2930 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 2931 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2", 2932 [/* For disassembly only; pattern left blank */]> { 2933 let Inst{4} = 0; 2934} 2935 2936def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 2937 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 2938 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2", 2939 [/* For disassembly only; pattern left blank */]> { 2940 let Inst{31-28} = 0b1111; 2941 let Inst{4} = 0; 2942} 2943 2944class ACI<dag oops, dag iops, string opc, string asm> 2945 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary, 2946 opc, asm, "", [/* For disassembly only; pattern left blank */]> { 2947 let Inst{27-25} = 0b110; 2948} 2949 2950multiclass LdStCop<bits<4> op31_28, bit load, string opc> { 2951 2952 def _OFFSET : ACI<(outs), 2953 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), 2954 opc, "\tp$cop, cr$CRd, $addr"> { 2955 let Inst{31-28} = op31_28; 2956 let Inst{24} = 1; // P = 1 2957 let Inst{21} = 0; // W = 0 2958 let Inst{22} = 0; // D = 0 2959 let Inst{20} = load; 2960 } 2961 2962 def _PRE : ACI<(outs), 2963 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), 2964 opc, "\tp$cop, cr$CRd, $addr!"> { 2965 let Inst{31-28} = op31_28; 2966 let Inst{24} = 1; // P = 1 2967 let Inst{21} = 1; // W = 1 2968 let Inst{22} = 0; // D = 0 2969 let Inst{20} = load; 2970 } 2971 2972 def _POST : ACI<(outs), 2973 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), 2974 opc, "\tp$cop, cr$CRd, [$base], $offset"> { 2975 let Inst{31-28} = op31_28; 2976 let Inst{24} = 0; // P = 0 2977 let Inst{21} = 1; // W = 1 2978 let Inst{22} = 0; // D = 0 2979 let Inst{20} = load; 2980 } 2981 2982 def _OPTION : ACI<(outs), 2983 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option), 2984 opc, "\tp$cop, cr$CRd, [$base], $option"> { 2985 let Inst{31-28} = op31_28; 2986 let Inst{24} = 0; // P = 0 2987 let Inst{23} = 1; // U = 1 2988 let Inst{21} = 0; // W = 0 2989 let Inst{22} = 0; // D = 0 2990 let Inst{20} = load; 2991 } 2992 2993 def L_OFFSET : ACI<(outs), 2994 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), 2995 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> { 2996 let Inst{31-28} = op31_28; 2997 let Inst{24} = 1; // P = 1 2998 let Inst{21} = 0; // W = 0 2999 let Inst{22} = 1; // D = 1 3000 let Inst{20} = load; 3001 } 3002 3003 def L_PRE : ACI<(outs), 3004 (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), 3005 !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { 3006 let Inst{31-28} = op31_28; 3007 let Inst{24} = 1; // P = 1 3008 let Inst{21} = 1; // W = 1 3009 let Inst{22} = 1; // D = 1 3010 let Inst{20} = load; 3011 } 3012 3013 def L_POST : ACI<(outs), 3014 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), 3015 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> { 3016 let Inst{31-28} = op31_28; 3017 let Inst{24} = 0; // P = 0 3018 let Inst{21} = 1; // W = 1 3019 let Inst{22} = 1; // D = 1 3020 let Inst{20} = load; 3021 } 3022 3023 def L_OPTION : ACI<(outs), 3024 (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option), 3025 !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> { 3026 let Inst{31-28} = op31_28; 3027 let Inst{24} = 0; // P = 0 3028 let Inst{23} = 1; // U = 1 3029 let Inst{21} = 0; // W = 0 3030 let Inst{22} = 1; // D = 1 3031 let Inst{20} = load; 3032 } 3033} 3034 3035defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">; 3036defm LDC2 : LdStCop<0b1111, 1, "ldc2">; 3037defm STC : LdStCop<{?,?,?,?}, 0, "stc">; 3038defm STC2 : LdStCop<0b1111, 0, "stc2">; 3039 3040def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 3041 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 3042 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2", 3043 [/* For disassembly only; pattern left blank */]> { 3044 let Inst{20} = 0; 3045 let Inst{4} = 1; 3046} 3047 3048def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 3049 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 3050 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2", 3051 [/* For disassembly only; pattern left blank */]> { 3052 let Inst{31-28} = 0b1111; 3053 let Inst{20} = 0; 3054 let Inst{4} = 1; 3055} 3056 3057def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 3058 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 3059 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2", 3060 [/* For disassembly only; pattern left blank */]> { 3061 let Inst{20} = 1; 3062 let Inst{4} = 1; 3063} 3064 3065def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 3066 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 3067 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2", 3068 [/* For disassembly only; pattern left blank */]> { 3069 let Inst{31-28} = 0b1111; 3070 let Inst{20} = 1; 3071 let Inst{4} = 1; 3072} 3073 3074def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc, 3075 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm), 3076 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm", 3077 [/* For disassembly only; pattern left blank */]> { 3078 let Inst{23-20} = 0b0100; 3079} 3080 3081def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc, 3082 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm), 3083 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm", 3084 [/* For disassembly only; pattern left blank */]> { 3085 let Inst{31-28} = 0b1111; 3086 let Inst{23-20} = 0b0100; 3087} 3088 3089def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc, 3090 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm), 3091 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm", 3092 [/* For disassembly only; pattern left blank */]> { 3093 let Inst{23-20} = 0b0101; 3094} 3095 3096def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc, 3097 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm), 3098 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm", 3099 [/* For disassembly only; pattern left blank */]> { 3100 let Inst{31-28} = 0b1111; 3101 let Inst{23-20} = 0b0101; 3102} 3103 3104//===----------------------------------------------------------------------===// 3105// Move between special register and ARM core register -- for disassembly only 3106// 3107 3108def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr", 3109 [/* For disassembly only; pattern left blank */]> { 3110 let Inst{23-20} = 0b0000; 3111 let Inst{7-4} = 0b0000; 3112} 3113 3114def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr", 3115 [/* For disassembly only; pattern left blank */]> { 3116 let Inst{23-20} = 0b0100; 3117 let Inst{7-4} = 0b0000; 3118} 3119 3120def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary, 3121 "msr", "\tcpsr$mask, $src", 3122 [/* For disassembly only; pattern left blank */]> { 3123 let Inst{23-20} = 0b0010; 3124 let Inst{7-4} = 0b0000; 3125} 3126 3127def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary, 3128 "msr", "\tcpsr$mask, $a", 3129 [/* For disassembly only; pattern left blank */]> { 3130 let Inst{23-20} = 0b0010; 3131 let Inst{7-4} = 0b0000; 3132} 3133 3134def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary, 3135 "msr", "\tspsr$mask, $src", 3136 [/* For disassembly only; pattern left blank */]> { 3137 let Inst{23-20} = 0b0110; 3138 let Inst{7-4} = 0b0000; 3139} 3140 3141def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary, 3142 "msr", "\tspsr$mask, $a", 3143 [/* For disassembly only; pattern left blank */]> { 3144 let Inst{23-20} = 0b0110; 3145 let Inst{7-4} = 0b0000; 3146} 3147