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