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