ARMInstrInfo.td revision b3e1bf54b29354c6d332cfaffcc86cd776fd4ca8
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, [SDTCisInt<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 HasV5T : Predicate<"Subtarget->hasV5TOps()">; 117def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">; 118def HasV6 : Predicate<"Subtarget->hasV6Ops()">; 119def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">; 120def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; 121def HasV7 : Predicate<"Subtarget->hasV7Ops()">; 122def HasVFP2 : Predicate<"Subtarget->hasVFP2()">; 123def HasVFP3 : Predicate<"Subtarget->hasVFP3()">; 124def HasNEON : Predicate<"Subtarget->hasNEON()">; 125def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; 126def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; 127def IsThumb : Predicate<"Subtarget->isThumb()">; 128def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; 129def IsThumb2 : Predicate<"Subtarget->isThumb2()">; 130def IsARM : Predicate<"!Subtarget->isThumb()">; 131def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; 132def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; 133def CarryDefIsUnused : Predicate<"!N->hasAnyUseOfValue(1)">; 134def CarryDefIsUsed : Predicate<"N->hasAnyUseOfValue(1)">; 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//===----------------------------------------------------------------------===// 240// Operand Definitions. 241// 242 243// Branch target. 244def brtarget : Operand<OtherVT>; 245 246// A list of registers separated by comma. Used by load/store multiple. 247def reglist : Operand<i32> { 248 let PrintMethod = "printRegisterList"; 249} 250 251// An operand for the CONSTPOOL_ENTRY pseudo-instruction. 252def cpinst_operand : Operand<i32> { 253 let PrintMethod = "printCPInstOperand"; 254} 255 256def jtblock_operand : Operand<i32> { 257 let PrintMethod = "printJTBlockOperand"; 258} 259def jt2block_operand : Operand<i32> { 260 let PrintMethod = "printJT2BlockOperand"; 261} 262 263// Local PC labels. 264def pclabel : Operand<i32> { 265 let PrintMethod = "printPCLabel"; 266} 267 268// shifter_operand operands: so_reg and so_imm. 269def so_reg : Operand<i32>, // reg reg imm 270 ComplexPattern<i32, 3, "SelectShifterOperandReg", 271 [shl,srl,sra,rotr]> { 272 let PrintMethod = "printSORegOperand"; 273 let MIOperandInfo = (ops GPR, GPR, i32imm); 274} 275 276// so_imm - Match a 32-bit shifter_operand immediate operand, which is an 277// 8-bit immediate rotated by an arbitrary number of bits. so_imm values are 278// represented in the imm field in the same 12-bit form that they are encoded 279// into so_imm instructions: the 8-bit immediate is the least significant bits 280// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11]. 281def so_imm : Operand<i32>, 282 PatLeaf<(imm), [{ 283 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1; 284 }]> { 285 let PrintMethod = "printSOImmOperand"; 286} 287 288// Break so_imm's up into two pieces. This handles immediates with up to 16 289// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to 290// get the first/second pieces. 291def so_imm2part : Operand<i32>, 292 PatLeaf<(imm), [{ 293 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 294 }]> { 295 let PrintMethod = "printSOImm2PartOperand"; 296} 297 298def so_imm2part_1 : SDNodeXForm<imm, [{ 299 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue()); 300 return CurDAG->getTargetConstant(V, MVT::i32); 301}]>; 302 303def so_imm2part_2 : SDNodeXForm<imm, [{ 304 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue()); 305 return CurDAG->getTargetConstant(V, MVT::i32); 306}]>; 307 308def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{ 309 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue()); 310 }]> { 311 let PrintMethod = "printSOImm2PartOperand"; 312} 313 314def so_neg_imm2part_1 : SDNodeXForm<imm, [{ 315 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue()); 316 return CurDAG->getTargetConstant(V, MVT::i32); 317}]>; 318 319def so_neg_imm2part_2 : SDNodeXForm<imm, [{ 320 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue()); 321 return CurDAG->getTargetConstant(V, MVT::i32); 322}]>; 323 324/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31]. 325def imm0_31 : Operand<i32>, PatLeaf<(imm), [{ 326 return (int32_t)N->getZExtValue() < 32; 327}]>; 328 329// Define ARM specific addressing modes. 330 331// addrmode2 := reg +/- reg shop imm 332// addrmode2 := reg +/- imm12 333// 334def addrmode2 : Operand<i32>, 335 ComplexPattern<i32, 3, "SelectAddrMode2", []> { 336 let PrintMethod = "printAddrMode2Operand"; 337 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 338} 339 340def am2offset : Operand<i32>, 341 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> { 342 let PrintMethod = "printAddrMode2OffsetOperand"; 343 let MIOperandInfo = (ops GPR, i32imm); 344} 345 346// addrmode3 := reg +/- reg 347// addrmode3 := reg +/- imm8 348// 349def addrmode3 : Operand<i32>, 350 ComplexPattern<i32, 3, "SelectAddrMode3", []> { 351 let PrintMethod = "printAddrMode3Operand"; 352 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 353} 354 355def am3offset : Operand<i32>, 356 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> { 357 let PrintMethod = "printAddrMode3OffsetOperand"; 358 let MIOperandInfo = (ops GPR, i32imm); 359} 360 361// addrmode4 := reg, <mode|W> 362// 363def addrmode4 : Operand<i32>, 364 ComplexPattern<i32, 2, "SelectAddrMode4", []> { 365 let PrintMethod = "printAddrMode4Operand"; 366 let MIOperandInfo = (ops GPR, i32imm); 367} 368 369// addrmode5 := reg +/- imm8*4 370// 371def addrmode5 : Operand<i32>, 372 ComplexPattern<i32, 2, "SelectAddrMode5", []> { 373 let PrintMethod = "printAddrMode5Operand"; 374 let MIOperandInfo = (ops GPR, i32imm); 375} 376 377// addrmode6 := reg with optional writeback 378// 379def addrmode6 : Operand<i32>, 380 ComplexPattern<i32, 4, "SelectAddrMode6", []> { 381 let PrintMethod = "printAddrMode6Operand"; 382 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm); 383} 384 385// addrmodepc := pc + reg 386// 387def addrmodepc : Operand<i32>, 388 ComplexPattern<i32, 2, "SelectAddrModePC", []> { 389 let PrintMethod = "printAddrModePCOperand"; 390 let MIOperandInfo = (ops GPR, i32imm); 391} 392 393def nohash_imm : Operand<i32> { 394 let PrintMethod = "printNoHashImmediate"; 395} 396 397//===----------------------------------------------------------------------===// 398 399include "ARMInstrFormats.td" 400 401//===----------------------------------------------------------------------===// 402// Multiclass helpers... 403// 404 405/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a 406/// binop that produces a value. 407multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode, 408 bit Commutable = 0> { 409 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 410 IIC_iALUi, opc, "\t$dst, $a, $b", 411 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> { 412 let Inst{25} = 1; 413 } 414 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, 415 IIC_iALUr, opc, "\t$dst, $a, $b", 416 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> { 417 let Inst{11-4} = 0b00000000; 418 let Inst{25} = 0; 419 let isCommutable = Commutable; 420 } 421 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 422 IIC_iALUsr, opc, "\t$dst, $a, $b", 423 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> { 424 let Inst{25} = 0; 425 } 426} 427 428/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the 429/// instruction modifies the CPSR register. 430let Defs = [CPSR] in { 431multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode, 432 bit Commutable = 0> { 433 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 434 IIC_iALUi, opc, "\t$dst, $a, $b", 435 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> { 436 let Inst{20} = 1; 437 let Inst{25} = 1; 438 } 439 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, 440 IIC_iALUr, opc, "\t$dst, $a, $b", 441 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> { 442 let isCommutable = Commutable; 443 let Inst{11-4} = 0b00000000; 444 let Inst{20} = 1; 445 let Inst{25} = 0; 446 } 447 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 448 IIC_iALUsr, opc, "\t$dst, $a, $b", 449 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> { 450 let Inst{20} = 1; 451 let Inst{25} = 0; 452 } 453} 454} 455 456/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 457/// patterns. Similar to AsI1_bin_irs except the instruction does not produce 458/// a explicit result, only implicitly set CPSR. 459let Defs = [CPSR] in { 460multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode, 461 bit Commutable = 0> { 462 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi, 463 opc, "\t$a, $b", 464 [(opnode GPR:$a, so_imm:$b)]> { 465 let Inst{20} = 1; 466 let Inst{25} = 1; 467 } 468 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr, 469 opc, "\t$a, $b", 470 [(opnode GPR:$a, GPR:$b)]> { 471 let Inst{11-4} = 0b00000000; 472 let Inst{20} = 1; 473 let Inst{25} = 0; 474 let isCommutable = Commutable; 475 } 476 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr, 477 opc, "\t$a, $b", 478 [(opnode GPR:$a, so_reg:$b)]> { 479 let Inst{20} = 1; 480 let Inst{25} = 0; 481 } 482} 483} 484 485/// AI_unary_rrot - A unary operation with two forms: one whose operand is a 486/// register and one whose operand is a register rotated by 8/16/24. 487/// FIXME: Remove the 'r' variant. Its rot_imm is zero. 488multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> { 489 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src), 490 IIC_iUNAr, opc, "\t$dst, $src", 491 [(set GPR:$dst, (opnode GPR:$src))]>, 492 Requires<[IsARM, HasV6]> { 493 let Inst{11-10} = 0b00; 494 let Inst{19-16} = 0b1111; 495 } 496 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot), 497 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot", 498 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>, 499 Requires<[IsARM, HasV6]> { 500 let Inst{19-16} = 0b1111; 501 } 502} 503 504/// AI_bin_rrot - A binary operation with two forms: one whose operand is a 505/// register and one whose operand is a register rotated by 8/16/24. 506multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> { 507 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), 508 IIC_iALUr, opc, "\t$dst, $LHS, $RHS", 509 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>, 510 Requires<[IsARM, HasV6]> { 511 let Inst{11-10} = 0b00; 512 } 513 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot), 514 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot", 515 [(set GPR:$dst, (opnode GPR:$LHS, 516 (rotr GPR:$RHS, rot_imm:$rot)))]>, 517 Requires<[IsARM, HasV6]>; 518} 519 520/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. 521let Uses = [CPSR] in { 522multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 523 bit Commutable = 0> { 524 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 525 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b", 526 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, 527 Requires<[IsARM, CarryDefIsUnused]> { 528 let Inst{25} = 1; 529 } 530 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 531 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b", 532 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>, 533 Requires<[IsARM, CarryDefIsUnused]> { 534 let isCommutable = Commutable; 535 let Inst{11-4} = 0b00000000; 536 let Inst{25} = 0; 537 } 538 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 539 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b", 540 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>, 541 Requires<[IsARM, CarryDefIsUnused]> { 542 let Inst{25} = 0; 543 } 544} 545// Carry setting variants 546let Defs = [CPSR] in { 547multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode, 548 bit Commutable = 0> { 549 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 550 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"), 551 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, 552 Requires<[IsARM, CarryDefIsUsed]> { 553 let Defs = [CPSR]; 554 let Inst{20} = 1; 555 let Inst{25} = 1; 556 } 557 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 558 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"), 559 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>, 560 Requires<[IsARM, CarryDefIsUsed]> { 561 let Defs = [CPSR]; 562 let Inst{11-4} = 0b00000000; 563 let Inst{20} = 1; 564 let Inst{25} = 0; 565 } 566 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 567 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"), 568 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>, 569 Requires<[IsARM, CarryDefIsUsed]> { 570 let Defs = [CPSR]; 571 let Inst{20} = 1; 572 let Inst{25} = 0; 573 } 574} 575} 576} 577 578//===----------------------------------------------------------------------===// 579// Instructions 580//===----------------------------------------------------------------------===// 581 582//===----------------------------------------------------------------------===// 583// Miscellaneous Instructions. 584// 585 586/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in 587/// the function. The first operand is the ID# for this instruction, the second 588/// is the index into the MachineConstantPool that this is, the third is the 589/// size in bytes of this constant pool entry. 590let neverHasSideEffects = 1, isNotDuplicable = 1 in 591def CONSTPOOL_ENTRY : 592PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 593 i32imm:$size), NoItinerary, 594 "${instid:label} ${cpidx:cpentry}", []>; 595 596let Defs = [SP], Uses = [SP] in { 597def ADJCALLSTACKUP : 598PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, 599 "@ ADJCALLSTACKUP $amt1", 600 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; 601 602def ADJCALLSTACKDOWN : 603PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, 604 "@ ADJCALLSTACKDOWN $amt", 605 [(ARMcallseq_start timm:$amt)]>; 606} 607 608def NOP : AI<(outs), (ins), Pseudo, NoItinerary, "nop", "", 609 [/* For disassembly only; pattern left blank */]>, 610 Requires<[IsARM, HasV6T2]> { 611 let Inst{27-16} = 0b001100100000; 612 let Inst{7-0} = 0b00000000; 613} 614 615// The i32imm operand $val can be used by a debugger to store more information 616// about the breakpoint. 617def BKPT : AI<(outs), (ins i32imm:$val), Pseudo, NoItinerary, "bkpt", "\t$val", 618 [/* For disassembly only; pattern left blank */]>, 619 Requires<[IsARM]> { 620 let Inst{27-20} = 0b00010010; 621 let Inst{7-4} = 0b0111; 622} 623 624// Change Processor State is a system instruction -- for disassembly only. 625// The singleton $opt operand contains the following information: 626// opt{4-0} = mode from Inst{4-0} 627// opt{5} = changemode from Inst{17} 628// opt{8-6} = AIF from Inst{8-6} 629// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable 630def CPS : AXI<(outs),(ins i32imm:$opt), Pseudo, NoItinerary, "cps${opt:cps}", 631 [/* For disassembly only; pattern left blank */]>, 632 Requires<[IsARM]> { 633 let Inst{31-28} = 0b1111; 634 let Inst{27-20} = 0b00010000; 635 let Inst{16} = 0; 636 let Inst{5} = 0; 637} 638 639def DBG : AI<(outs), (ins i32imm:$opt), Pseudo, NoItinerary, "dbg", "\t$opt", 640 [/* For disassembly only; pattern left blank */]>, 641 Requires<[IsARM, HasV7]> { 642 let Inst{27-16} = 0b001100100000; 643 let Inst{7-4} = 0b1111; 644} 645 646// A5.4 Permanently UNDEFINED instructions. 647def TRAP : AI<(outs), (ins), Pseudo, NoItinerary, "trap", "", 648 [/* For disassembly only; pattern left blank */]>, 649 Requires<[IsARM]> { 650 let Inst{27-25} = 0b011; 651 let Inst{24-20} = 0b11111; 652 let Inst{7-5} = 0b111; 653 let Inst{4} = 0b1; 654} 655 656// Address computation and loads and stores in PIC mode. 657let isNotDuplicable = 1 in { 658def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p), 659 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a", 660 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>; 661 662let AddedComplexity = 10 in { 663def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 664 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr", 665 [(set GPR:$dst, (load addrmodepc:$addr))]>; 666 667def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 668 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr", 669 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>; 670 671def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 672 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr", 673 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>; 674 675def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 676 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr", 677 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>; 678 679def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 680 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr", 681 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>; 682} 683let AddedComplexity = 10 in { 684def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 685 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr", 686 [(store GPR:$src, addrmodepc:$addr)]>; 687 688def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 689 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr", 690 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>; 691 692def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 693 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr", 694 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; 695} 696} // isNotDuplicable = 1 697 698 699// LEApcrel - Load a pc-relative address into a register without offending the 700// assembler. 701def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), 702 Pseudo, IIC_iALUi, 703 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(", 704 "${:private}PCRELL${:uid}+8))\n"), 705 !strconcat("${:private}PCRELL${:uid}:\n\t", 706 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")), 707 []>; 708 709def LEApcrelJT : AXI1<0x0, (outs GPR:$dst), 710 (ins i32imm:$label, nohash_imm:$id, pred:$p), 711 Pseudo, IIC_iALUi, 712 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, " 713 "(${label}_${id}-(", 714 "${:private}PCRELL${:uid}+8))\n"), 715 !strconcat("${:private}PCRELL${:uid}:\n\t", 716 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")), 717 []> { 718 let Inst{25} = 1; 719} 720 721//===----------------------------------------------------------------------===// 722// Control Flow Instructions. 723// 724 725let isReturn = 1, isTerminator = 1, isBarrier = 1 in 726 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 727 "bx", "\tlr", [(ARMretflag)]> { 728 let Inst{3-0} = 0b1110; 729 let Inst{7-4} = 0b0001; 730 let Inst{19-8} = 0b111111111111; 731 let Inst{27-20} = 0b00010010; 732} 733 734// Indirect branches 735let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 736 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", 737 [(brind GPR:$dst)]> { 738 let Inst{7-4} = 0b0001; 739 let Inst{19-8} = 0b111111111111; 740 let Inst{27-20} = 0b00010010; 741 let Inst{31-28} = 0b1110; 742 } 743} 744 745// FIXME: remove when we have a way to marking a MI with these properties. 746// FIXME: Should pc be an implicit operand like PICADD, etc? 747let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 748 hasExtraDefRegAllocReq = 1 in 749 def LDM_RET : AXI4ld<(outs), 750 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 751 LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb", 752 []>; 753 754// On non-Darwin platforms R9 is callee-saved. 755let isCall = 1, 756 Defs = [R0, R1, R2, R3, R12, LR, 757 D0, D1, D2, D3, D4, D5, D6, D7, 758 D16, D17, D18, D19, D20, D21, D22, D23, 759 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 760 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), 761 IIC_Br, "bl\t${func:call}", 762 [(ARMcall tglobaladdr:$func)]>, 763 Requires<[IsARM, IsNotDarwin]> { 764 let Inst{31-28} = 0b1110; 765 } 766 767 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), 768 IIC_Br, "bl", "\t${func:call}", 769 [(ARMcall_pred tglobaladdr:$func)]>, 770 Requires<[IsARM, IsNotDarwin]>; 771 772 // ARMv5T and above 773 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, 774 IIC_Br, "blx\t$func", 775 [(ARMcall GPR:$func)]>, 776 Requires<[IsARM, HasV5T, IsNotDarwin]> { 777 let Inst{7-4} = 0b0011; 778 let Inst{19-8} = 0b111111111111; 779 let Inst{27-20} = 0b00010010; 780 } 781 782 // ARMv4T 783 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops), 784 IIC_Br, "mov\tlr, pc\n\tbx\t$func", 785 [(ARMcall_nolink GPR:$func)]>, 786 Requires<[IsARM, IsNotDarwin]> { 787 let Inst{7-4} = 0b0001; 788 let Inst{19-8} = 0b111111111111; 789 let Inst{27-20} = 0b00010010; 790 } 791} 792 793// On Darwin R9 is call-clobbered. 794let isCall = 1, 795 Defs = [R0, R1, R2, R3, R9, R12, LR, 796 D0, D1, D2, D3, D4, D5, D6, D7, 797 D16, D17, D18, D19, D20, D21, D22, D23, 798 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 799 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), 800 IIC_Br, "bl\t${func:call}", 801 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> { 802 let Inst{31-28} = 0b1110; 803 } 804 805 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), 806 IIC_Br, "bl", "\t${func:call}", 807 [(ARMcall_pred tglobaladdr:$func)]>, 808 Requires<[IsARM, IsDarwin]>; 809 810 // ARMv5T and above 811 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, 812 IIC_Br, "blx\t$func", 813 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> { 814 let Inst{7-4} = 0b0011; 815 let Inst{19-8} = 0b111111111111; 816 let Inst{27-20} = 0b00010010; 817 } 818 819 // ARMv4T 820 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops), 821 IIC_Br, "mov\tlr, pc\n\tbx\t$func", 822 [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> { 823 let Inst{7-4} = 0b0001; 824 let Inst{19-8} = 0b111111111111; 825 let Inst{27-20} = 0b00010010; 826 } 827} 828 829let isBranch = 1, isTerminator = 1 in { 830 // B is "predicable" since it can be xformed into a Bcc. 831 let isBarrier = 1 in { 832 let isPredicable = 1 in 833 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br, 834 "b\t$target", [(br bb:$target)]>; 835 836 let isNotDuplicable = 1, isIndirectBranch = 1 in { 837 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id), 838 IIC_Br, "mov\tpc, $target \n$jt", 839 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> { 840 let Inst{11-4} = 0b00000000; 841 let Inst{15-12} = 0b1111; 842 let Inst{20} = 0; // S Bit 843 let Inst{24-21} = 0b1101; 844 let Inst{27-25} = 0b000; 845 } 846 def BR_JTm : JTI<(outs), 847 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id), 848 IIC_Br, "ldr\tpc, $target \n$jt", 849 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt, 850 imm:$id)]> { 851 let Inst{15-12} = 0b1111; 852 let Inst{20} = 1; // L bit 853 let Inst{21} = 0; // W bit 854 let Inst{22} = 0; // B bit 855 let Inst{24} = 1; // P bit 856 let Inst{27-25} = 0b011; 857 } 858 def BR_JTadd : JTI<(outs), 859 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id), 860 IIC_Br, "add\tpc, $target, $idx \n$jt", 861 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, 862 imm:$id)]> { 863 let Inst{15-12} = 0b1111; 864 let Inst{20} = 0; // S bit 865 let Inst{24-21} = 0b0100; 866 let Inst{27-25} = 0b000; 867 } 868 } // isNotDuplicable = 1, isIndirectBranch = 1 869 } // isBarrier = 1 870 871 // FIXME: should be able to write a pattern for ARMBrcond, but can't use 872 // a two-value operand where a dag node expects two operands. :( 873 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target), 874 IIC_Br, "b", "\t$target", 875 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>; 876} 877 878// Supervisor call (software interrupt) -- for disassembly only 879let isCall = 1 in { 880def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", 881 [/* For disassembly only; pattern left blank */]>; 882} 883 884//===----------------------------------------------------------------------===// 885// Load / store Instructions. 886// 887 888// Load 889let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 890def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr, 891 "ldr", "\t$dst, $addr", 892 [(set GPR:$dst, (load addrmode2:$addr))]>; 893 894// Special LDR for loads from non-pc-relative constpools. 895let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1, 896 mayHaveSideEffects = 1 in 897def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr, 898 "ldr", "\t$dst, $addr", []>; 899 900// Loads with zero extension 901def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 902 IIC_iLoadr, "ldrh", "\t$dst, $addr", 903 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>; 904 905def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 906 IIC_iLoadr, "ldrb", "\t$dst, $addr", 907 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>; 908 909// Loads with sign extension 910def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 911 IIC_iLoadr, "ldrsh", "\t$dst, $addr", 912 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>; 913 914def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 915 IIC_iLoadr, "ldrsb", "\t$dst, $addr", 916 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>; 917 918let mayLoad = 1, hasExtraDefRegAllocReq = 1 in { 919// Load doubleword 920def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm, 921 IIC_iLoadr, "ldrd", "\t$dst1, $addr", 922 []>, Requires<[IsARM, HasV5TE]>; 923 924// Indexed loads 925def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb), 926 (ins addrmode2:$addr), LdFrm, IIC_iLoadru, 927 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 928 929def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb), 930 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru, 931 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 932 933def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb), 934 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru, 935 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 936 937def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb), 938 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru, 939 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 940 941def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb), 942 (ins addrmode2:$addr), LdFrm, IIC_iLoadru, 943 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 944 945def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb), 946 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru, 947 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 948 949def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb), 950 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru, 951 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 952 953def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb), 954 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru, 955 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 956 957def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb), 958 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru, 959 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 960 961def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb), 962 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru, 963 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 964} 965 966// LDRT and LDRBT are for disassembly only. 967 968def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb), 969 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru, 970 "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { 971 let Inst{21} = 1; // overwrite 972} 973 974def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb), 975 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru, 976 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []> { 977 let Inst{21} = 1; // overwrite 978} 979 980// Store 981def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer, 982 "str", "\t$src, $addr", 983 [(store GPR:$src, addrmode2:$addr)]>; 984 985// Stores with truncate 986def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer, 987 "strh", "\t$src, $addr", 988 [(truncstorei16 GPR:$src, addrmode3:$addr)]>; 989 990def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer, 991 "strb", "\t$src, $addr", 992 [(truncstorei8 GPR:$src, addrmode2:$addr)]>; 993 994// Store doubleword 995let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 996def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr), 997 StMiscFrm, IIC_iStorer, 998 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>; 999 1000// Indexed stores 1001def STR_PRE : AI2stwpr<(outs GPR:$base_wb), 1002 (ins GPR:$src, GPR:$base, am2offset:$offset), 1003 StFrm, IIC_iStoreru, 1004 "str", "\t$src, [$base, $offset]!", "$base = $base_wb", 1005 [(set GPR:$base_wb, 1006 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>; 1007 1008def STR_POST : AI2stwpo<(outs GPR:$base_wb), 1009 (ins GPR:$src, GPR:$base,am2offset:$offset), 1010 StFrm, IIC_iStoreru, 1011 "str", "\t$src, [$base], $offset", "$base = $base_wb", 1012 [(set GPR:$base_wb, 1013 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>; 1014 1015def STRH_PRE : AI3sthpr<(outs GPR:$base_wb), 1016 (ins GPR:$src, GPR:$base,am3offset:$offset), 1017 StMiscFrm, IIC_iStoreru, 1018 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb", 1019 [(set GPR:$base_wb, 1020 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>; 1021 1022def STRH_POST: AI3sthpo<(outs GPR:$base_wb), 1023 (ins GPR:$src, GPR:$base,am3offset:$offset), 1024 StMiscFrm, IIC_iStoreru, 1025 "strh", "\t$src, [$base], $offset", "$base = $base_wb", 1026 [(set GPR:$base_wb, (post_truncsti16 GPR:$src, 1027 GPR:$base, am3offset:$offset))]>; 1028 1029def STRB_PRE : AI2stbpr<(outs GPR:$base_wb), 1030 (ins GPR:$src, GPR:$base,am2offset:$offset), 1031 StFrm, IIC_iStoreru, 1032 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb", 1033 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src, 1034 GPR:$base, am2offset:$offset))]>; 1035 1036def STRB_POST: AI2stbpo<(outs GPR:$base_wb), 1037 (ins GPR:$src, GPR:$base,am2offset:$offset), 1038 StFrm, IIC_iStoreru, 1039 "strb", "\t$src, [$base], $offset", "$base = $base_wb", 1040 [(set GPR:$base_wb, (post_truncsti8 GPR:$src, 1041 GPR:$base, am2offset:$offset))]>; 1042 1043// STRT and STRBT are for disassembly only. 1044 1045def STRT : AI2stwpo<(outs GPR:$base_wb), 1046 (ins GPR:$src, GPR:$base,am2offset:$offset), 1047 StFrm, IIC_iStoreru, 1048 "strt", "\t$src, [$base], $offset", "$base = $base_wb", 1049 [/* For disassembly only; pattern left blank */]> { 1050 let Inst{21} = 1; // overwrite 1051} 1052 1053def STRBT : AI2stbpo<(outs GPR:$base_wb), 1054 (ins GPR:$src, GPR:$base,am2offset:$offset), 1055 StFrm, IIC_iStoreru, 1056 "strbt", "\t$src, [$base], $offset", "$base = $base_wb", 1057 [/* For disassembly only; pattern left blank */]> { 1058 let Inst{21} = 1; // overwrite 1059} 1060 1061//===----------------------------------------------------------------------===// 1062// Load / store multiple Instructions. 1063// 1064 1065let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 1066def LDM : AXI4ld<(outs), 1067 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 1068 LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb", 1069 []>; 1070 1071let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 1072def STM : AXI4st<(outs), 1073 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 1074 LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb", 1075 []>; 1076 1077//===----------------------------------------------------------------------===// 1078// Move Instructions. 1079// 1080 1081let neverHasSideEffects = 1 in 1082def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr, 1083 "mov", "\t$dst, $src", []>, UnaryDP { 1084 let Inst{11-4} = 0b00000000; 1085 let Inst{25} = 0; 1086} 1087 1088def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 1089 DPSoRegFrm, IIC_iMOVsr, 1090 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP { 1091 let Inst{25} = 0; 1092} 1093 1094let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1095def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi, 1096 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP { 1097 let Inst{25} = 1; 1098} 1099 1100let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1101def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 1102 DPFrm, IIC_iMOVi, 1103 "movw", "\t$dst, $src", 1104 [(set GPR:$dst, imm0_65535:$src)]>, 1105 Requires<[IsARM, HasV6T2]>, UnaryDP { 1106 let Inst{20} = 0; 1107 let Inst{25} = 1; 1108} 1109 1110let Constraints = "$src = $dst" in 1111def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm), 1112 DPFrm, IIC_iMOVi, 1113 "movt", "\t$dst, $imm", 1114 [(set GPR:$dst, 1115 (or (and GPR:$src, 0xffff), 1116 lo16AllZero:$imm))]>, UnaryDP, 1117 Requires<[IsARM, HasV6T2]> { 1118 let Inst{20} = 0; 1119 let Inst{25} = 1; 1120} 1121 1122def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, 1123 Requires<[IsARM, HasV6T2]>; 1124 1125let Uses = [CPSR] in 1126def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi, 1127 "mov", "\t$dst, $src, rrx", 1128 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP; 1129 1130// These aren't really mov instructions, but we have to define them this way 1131// due to flag operands. 1132 1133let Defs = [CPSR] in { 1134def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 1135 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1", 1136 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP; 1137def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 1138 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1", 1139 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP; 1140} 1141 1142//===----------------------------------------------------------------------===// 1143// Extend Instructions. 1144// 1145 1146// Sign extenders 1147 1148defm SXTB : AI_unary_rrot<0b01101010, 1149 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; 1150defm SXTH : AI_unary_rrot<0b01101011, 1151 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; 1152 1153defm SXTAB : AI_bin_rrot<0b01101010, 1154 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 1155defm SXTAH : AI_bin_rrot<0b01101011, 1156 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 1157 1158// TODO: SXT(A){B|H}16 1159 1160// Zero extenders 1161 1162let AddedComplexity = 16 in { 1163defm UXTB : AI_unary_rrot<0b01101110, 1164 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; 1165defm UXTH : AI_unary_rrot<0b01101111, 1166 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 1167defm UXTB16 : AI_unary_rrot<0b01101100, 1168 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 1169 1170def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), 1171 (UXTB16r_rot GPR:$Src, 24)>; 1172def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), 1173 (UXTB16r_rot GPR:$Src, 8)>; 1174 1175defm UXTAB : AI_bin_rrot<0b01101110, "uxtab", 1176 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 1177defm UXTAH : AI_bin_rrot<0b01101111, "uxtah", 1178 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 1179} 1180 1181// This isn't safe in general, the add is two 16-bit units, not a 32-bit add. 1182//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>; 1183 1184// TODO: UXT(A){B|H}16 1185 1186def SBFX : I<(outs GPR:$dst), 1187 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), 1188 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi, 1189 "sbfx", "\t$dst, $src, $lsb, $width", "", []>, 1190 Requires<[IsARM, HasV6T2]> { 1191 let Inst{27-21} = 0b0111101; 1192 let Inst{6-4} = 0b101; 1193} 1194 1195def UBFX : I<(outs GPR:$dst), 1196 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), 1197 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi, 1198 "ubfx", "\t$dst, $src, $lsb, $width", "", []>, 1199 Requires<[IsARM, HasV6T2]> { 1200 let Inst{27-21} = 0b0111111; 1201 let Inst{6-4} = 0b101; 1202} 1203 1204//===----------------------------------------------------------------------===// 1205// Arithmetic Instructions. 1206// 1207 1208defm ADD : AsI1_bin_irs<0b0100, "add", 1209 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 1210defm SUB : AsI1_bin_irs<0b0010, "sub", 1211 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1212 1213// ADD and SUB with 's' bit set. 1214defm ADDS : AI1_bin_s_irs<0b0100, "adds", 1215 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; 1216defm SUBS : AI1_bin_s_irs<0b0010, "subs", 1217 BinOpFrag<(subc node:$LHS, node:$RHS)>>; 1218 1219defm ADC : AI1_adde_sube_irs<0b0101, "adc", 1220 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>; 1221defm SBC : AI1_adde_sube_irs<0b0110, "sbc", 1222 BinOpFrag<(sube node:$LHS, node:$RHS)>>; 1223defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs", 1224 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>; 1225defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs", 1226 BinOpFrag<(sube node:$LHS, node:$RHS)>>; 1227 1228// These don't define reg/reg forms, because they are handled above. 1229def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 1230 IIC_iALUi, "rsb", "\t$dst, $a, $b", 1231 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> { 1232 let Inst{25} = 1; 1233} 1234 1235def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 1236 IIC_iALUsr, "rsb", "\t$dst, $a, $b", 1237 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> { 1238 let Inst{25} = 0; 1239} 1240 1241// RSB with 's' bit set. 1242let Defs = [CPSR] in { 1243def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 1244 IIC_iALUi, "rsbs", "\t$dst, $a, $b", 1245 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> { 1246 let Inst{20} = 1; 1247 let Inst{25} = 1; 1248} 1249def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 1250 IIC_iALUsr, "rsbs", "\t$dst, $a, $b", 1251 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> { 1252 let Inst{20} = 1; 1253 let Inst{25} = 0; 1254} 1255} 1256 1257let Uses = [CPSR] in { 1258def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 1259 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b", 1260 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, 1261 Requires<[IsARM, CarryDefIsUnused]> { 1262 let Inst{25} = 1; 1263} 1264def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 1265 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b", 1266 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>, 1267 Requires<[IsARM, CarryDefIsUnused]> { 1268 let Inst{25} = 0; 1269} 1270} 1271 1272// FIXME: Allow these to be predicated. 1273let Defs = [CPSR], Uses = [CPSR] in { 1274def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 1275 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b", 1276 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, 1277 Requires<[IsARM, CarryDefIsUnused]> { 1278 let Inst{20} = 1; 1279 let Inst{25} = 1; 1280} 1281def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 1282 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b", 1283 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>, 1284 Requires<[IsARM, CarryDefIsUnused]> { 1285 let Inst{20} = 1; 1286 let Inst{25} = 0; 1287} 1288} 1289 1290// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1291def : ARMPat<(add GPR:$src, so_imm_neg:$imm), 1292 (SUBri GPR:$src, so_imm_neg:$imm)>; 1293 1294//def : ARMPat<(addc GPR:$src, so_imm_neg:$imm), 1295// (SUBSri GPR:$src, so_imm_neg:$imm)>; 1296//def : ARMPat<(adde GPR:$src, so_imm_neg:$imm), 1297// (SBCri GPR:$src, so_imm_neg:$imm)>; 1298 1299// Note: These are implemented in C++ code, because they have to generate 1300// ADD/SUBrs instructions, which use a complex pattern that a xform function 1301// cannot produce. 1302// (mul X, 2^n+1) -> (add (X << n), X) 1303// (mul X, 2^n-1) -> (rsb X, (X << n)) 1304 1305 1306//===----------------------------------------------------------------------===// 1307// Bitwise Instructions. 1308// 1309 1310defm AND : AsI1_bin_irs<0b0000, "and", 1311 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 1312defm ORR : AsI1_bin_irs<0b1100, "orr", 1313 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 1314defm EOR : AsI1_bin_irs<0b0001, "eor", 1315 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 1316defm BIC : AsI1_bin_irs<0b1110, "bic", 1317 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 1318 1319def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), 1320 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 1321 "bfc", "\t$dst, $imm", "$src = $dst", 1322 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>, 1323 Requires<[IsARM, HasV6T2]> { 1324 let Inst{27-21} = 0b0111110; 1325 let Inst{6-0} = 0b0011111; 1326} 1327 1328def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr, 1329 "mvn", "\t$dst, $src", 1330 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP { 1331 let Inst{25} = 0; 1332 let Inst{11-4} = 0b00000000; 1333} 1334def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm, 1335 IIC_iMOVsr, "mvn", "\t$dst, $src", 1336 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP { 1337 let Inst{25} = 0; 1338} 1339let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1340def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 1341 IIC_iMOVi, "mvn", "\t$dst, $imm", 1342 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP { 1343 let Inst{25} = 1; 1344} 1345 1346def : ARMPat<(and GPR:$src, so_imm_not:$imm), 1347 (BICri GPR:$src, so_imm_not:$imm)>; 1348 1349//===----------------------------------------------------------------------===// 1350// Multiply Instructions. 1351// 1352 1353let isCommutable = 1 in 1354def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1355 IIC_iMUL32, "mul", "\t$dst, $a, $b", 1356 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; 1357 1358def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1359 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c", 1360 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; 1361 1362def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1363 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c", 1364 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>, 1365 Requires<[IsARM, HasV6T2]>; 1366 1367// Extra precision multiplies with low / high results 1368let neverHasSideEffects = 1 in { 1369let isCommutable = 1 in { 1370def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst), 1371 (ins GPR:$a, GPR:$b), IIC_iMUL64, 1372 "smull", "\t$ldst, $hdst, $a, $b", []>; 1373 1374def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst), 1375 (ins GPR:$a, GPR:$b), IIC_iMUL64, 1376 "umull", "\t$ldst, $hdst, $a, $b", []>; 1377} 1378 1379// Multiply + accumulate 1380def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst), 1381 (ins GPR:$a, GPR:$b), IIC_iMAC64, 1382 "smlal", "\t$ldst, $hdst, $a, $b", []>; 1383 1384def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst), 1385 (ins GPR:$a, GPR:$b), IIC_iMAC64, 1386 "umlal", "\t$ldst, $hdst, $a, $b", []>; 1387 1388def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst), 1389 (ins GPR:$a, GPR:$b), IIC_iMAC64, 1390 "umaal", "\t$ldst, $hdst, $a, $b", []>, 1391 Requires<[IsARM, HasV6]>; 1392} // neverHasSideEffects 1393 1394// Most significant word multiply 1395def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1396 IIC_iMUL32, "smmul", "\t$dst, $a, $b", 1397 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>, 1398 Requires<[IsARM, HasV6]> { 1399 let Inst{7-4} = 0b0001; 1400 let Inst{15-12} = 0b1111; 1401} 1402 1403def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1404 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c", 1405 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>, 1406 Requires<[IsARM, HasV6]> { 1407 let Inst{7-4} = 0b0001; 1408} 1409 1410 1411def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1412 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c", 1413 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>, 1414 Requires<[IsARM, HasV6]> { 1415 let Inst{7-4} = 0b1101; 1416} 1417 1418multiclass AI_smul<string opc, PatFrag opnode> { 1419 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1420 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b", 1421 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), 1422 (sext_inreg GPR:$b, i16)))]>, 1423 Requires<[IsARM, HasV5TE]> { 1424 let Inst{5} = 0; 1425 let Inst{6} = 0; 1426 } 1427 1428 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1429 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b", 1430 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), 1431 (sra GPR:$b, (i32 16))))]>, 1432 Requires<[IsARM, HasV5TE]> { 1433 let Inst{5} = 0; 1434 let Inst{6} = 1; 1435 } 1436 1437 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1438 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b", 1439 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), 1440 (sext_inreg GPR:$b, i16)))]>, 1441 Requires<[IsARM, HasV5TE]> { 1442 let Inst{5} = 1; 1443 let Inst{6} = 0; 1444 } 1445 1446 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1447 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b", 1448 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), 1449 (sra GPR:$b, (i32 16))))]>, 1450 Requires<[IsARM, HasV5TE]> { 1451 let Inst{5} = 1; 1452 let Inst{6} = 1; 1453 } 1454 1455 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1456 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b", 1457 [(set GPR:$dst, (sra (opnode GPR:$a, 1458 (sext_inreg GPR:$b, i16)), (i32 16)))]>, 1459 Requires<[IsARM, HasV5TE]> { 1460 let Inst{5} = 1; 1461 let Inst{6} = 0; 1462 } 1463 1464 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1465 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b", 1466 [(set GPR:$dst, (sra (opnode GPR:$a, 1467 (sra GPR:$b, (i32 16))), (i32 16)))]>, 1468 Requires<[IsARM, HasV5TE]> { 1469 let Inst{5} = 1; 1470 let Inst{6} = 1; 1471 } 1472} 1473 1474 1475multiclass AI_smla<string opc, PatFrag opnode> { 1476 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1477 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", 1478 [(set GPR:$dst, (add GPR:$acc, 1479 (opnode (sext_inreg GPR:$a, i16), 1480 (sext_inreg GPR:$b, i16))))]>, 1481 Requires<[IsARM, HasV5TE]> { 1482 let Inst{5} = 0; 1483 let Inst{6} = 0; 1484 } 1485 1486 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1487 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", 1488 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16), 1489 (sra GPR:$b, (i32 16)))))]>, 1490 Requires<[IsARM, HasV5TE]> { 1491 let Inst{5} = 0; 1492 let Inst{6} = 1; 1493 } 1494 1495 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1496 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", 1497 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)), 1498 (sext_inreg GPR:$b, i16))))]>, 1499 Requires<[IsARM, HasV5TE]> { 1500 let Inst{5} = 1; 1501 let Inst{6} = 0; 1502 } 1503 1504 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1505 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", 1506 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)), 1507 (sra GPR:$b, (i32 16)))))]>, 1508 Requires<[IsARM, HasV5TE]> { 1509 let Inst{5} = 1; 1510 let Inst{6} = 1; 1511 } 1512 1513 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1514 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", 1515 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, 1516 (sext_inreg GPR:$b, i16)), (i32 16))))]>, 1517 Requires<[IsARM, HasV5TE]> { 1518 let Inst{5} = 0; 1519 let Inst{6} = 0; 1520 } 1521 1522 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1523 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", 1524 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, 1525 (sra GPR:$b, (i32 16))), (i32 16))))]>, 1526 Requires<[IsARM, HasV5TE]> { 1527 let Inst{5} = 0; 1528 let Inst{6} = 1; 1529 } 1530} 1531 1532defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 1533defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 1534 1535// TODO: Halfword multiple accumulate long: SMLAL<x><y> 1536// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD 1537 1538//===----------------------------------------------------------------------===// 1539// Misc. Arithmetic Instructions. 1540// 1541 1542def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1543 "clz", "\t$dst, $src", 1544 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> { 1545 let Inst{7-4} = 0b0001; 1546 let Inst{11-8} = 0b1111; 1547 let Inst{19-16} = 0b1111; 1548} 1549 1550def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1551 "rbit", "\t$dst, $src", 1552 [(set GPR:$dst, (ARMrbit GPR:$src))]>, 1553 Requires<[IsARM, HasV6T2]> { 1554 let Inst{7-4} = 0b0011; 1555 let Inst{11-8} = 0b1111; 1556 let Inst{19-16} = 0b1111; 1557} 1558 1559def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1560 "rev", "\t$dst, $src", 1561 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> { 1562 let Inst{7-4} = 0b0011; 1563 let Inst{11-8} = 0b1111; 1564 let Inst{19-16} = 0b1111; 1565} 1566 1567def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1568 "rev16", "\t$dst, $src", 1569 [(set GPR:$dst, 1570 (or (and (srl GPR:$src, (i32 8)), 0xFF), 1571 (or (and (shl GPR:$src, (i32 8)), 0xFF00), 1572 (or (and (srl GPR:$src, (i32 8)), 0xFF0000), 1573 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>, 1574 Requires<[IsARM, HasV6]> { 1575 let Inst{7-4} = 0b1011; 1576 let Inst{11-8} = 0b1111; 1577 let Inst{19-16} = 0b1111; 1578} 1579 1580def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1581 "revsh", "\t$dst, $src", 1582 [(set GPR:$dst, 1583 (sext_inreg 1584 (or (srl (and GPR:$src, 0xFF00), (i32 8)), 1585 (shl GPR:$src, (i32 8))), i16))]>, 1586 Requires<[IsARM, HasV6]> { 1587 let Inst{7-4} = 0b1011; 1588 let Inst{11-8} = 0b1111; 1589 let Inst{19-16} = 0b1111; 1590} 1591 1592def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst), 1593 (ins GPR:$src1, GPR:$src2, i32imm:$shamt), 1594 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt", 1595 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), 1596 (and (shl GPR:$src2, (i32 imm:$shamt)), 1597 0xFFFF0000)))]>, 1598 Requires<[IsARM, HasV6]> { 1599 let Inst{6-4} = 0b001; 1600} 1601 1602// Alternate cases for PKHBT where identities eliminate some nodes. 1603def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)), 1604 (PKHBT GPR:$src1, GPR:$src2, 0)>; 1605def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)), 1606 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>; 1607 1608 1609def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst), 1610 (ins GPR:$src1, GPR:$src2, i32imm:$shamt), 1611 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt", 1612 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), 1613 (and (sra GPR:$src2, imm16_31:$shamt), 1614 0xFFFF)))]>, Requires<[IsARM, HasV6]> { 1615 let Inst{6-4} = 0b101; 1616} 1617 1618// Alternate cases for PKHTB where identities eliminate some nodes. Note that 1619// a shift amount of 0 is *not legal* here, it is PKHBT instead. 1620def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))), 1621 (PKHTB GPR:$src1, GPR:$src2, 16)>; 1622def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), 1623 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)), 1624 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>; 1625 1626//===----------------------------------------------------------------------===// 1627// Comparison Instructions... 1628// 1629 1630defm CMP : AI1_cmp_irs<0b1010, "cmp", 1631 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 1632//FIXME: Disable CMN, as CCodes are backwards from compare expectations 1633// Compare-to-zero still works out, just not the relationals 1634//defm CMN : AI1_cmp_irs<0b1011, "cmn", 1635// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; 1636 1637// Note that TST/TEQ don't set all the same flags that CMP does! 1638defm TST : AI1_cmp_irs<0b1000, "tst", 1639 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>; 1640defm TEQ : AI1_cmp_irs<0b1001, "teq", 1641 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>; 1642 1643defm CMPz : AI1_cmp_irs<0b1010, "cmp", 1644 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>; 1645defm CMNz : AI1_cmp_irs<0b1011, "cmn", 1646 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>; 1647 1648//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), 1649// (CMNri GPR:$src, so_imm_neg:$imm)>; 1650 1651def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm), 1652 (CMNzri GPR:$src, so_imm_neg:$imm)>; 1653 1654 1655// Conditional moves 1656// FIXME: should be able to write a pattern for ARMcmov, but can't use 1657// a two-value operand where a dag node expects two operands. :( 1658def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm, 1659 IIC_iCMOVr, "mov", "\t$dst, $true", 1660 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>, 1661 RegConstraint<"$false = $dst">, UnaryDP { 1662 let Inst{11-4} = 0b00000000; 1663 let Inst{25} = 0; 1664} 1665 1666def MOVCCs : AI1<0b1101, (outs GPR:$dst), 1667 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr, 1668 "mov", "\t$dst, $true", 1669 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>, 1670 RegConstraint<"$false = $dst">, UnaryDP { 1671 let Inst{25} = 0; 1672} 1673 1674def MOVCCi : AI1<0b1101, (outs GPR:$dst), 1675 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi, 1676 "mov", "\t$dst, $true", 1677 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>, 1678 RegConstraint<"$false = $dst">, UnaryDP { 1679 let Inst{25} = 1; 1680} 1681 1682//===----------------------------------------------------------------------===// 1683// Atomic operations intrinsics 1684// 1685 1686// memory barriers protect the atomic sequences 1687let hasSideEffects = 1 in { 1688def Int_MemBarrierV7 : AInoP<(outs), (ins), 1689 Pseudo, NoItinerary, 1690 "dmb", "", 1691 [(ARMMemBarrierV7)]>, 1692 Requires<[IsARM, HasV7]> { 1693 let Inst{31-4} = 0xf57ff05; 1694 // FIXME: add support for options other than a full system DMB 1695 let Inst{3-0} = 0b1111; 1696} 1697 1698def Int_SyncBarrierV7 : AInoP<(outs), (ins), 1699 Pseudo, NoItinerary, 1700 "dsb", "", 1701 [(ARMSyncBarrierV7)]>, 1702 Requires<[IsARM, HasV7]> { 1703 let Inst{31-4} = 0xf57ff04; 1704 // FIXME: add support for options other than a full system DSB 1705 let Inst{3-0} = 0b1111; 1706} 1707 1708def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero), 1709 Pseudo, NoItinerary, 1710 "mcr", "\tp15, 0, $zero, c7, c10, 5", 1711 [(ARMMemBarrierV6 GPR:$zero)]>, 1712 Requires<[IsARM, HasV6]> { 1713 // FIXME: add support for options other than a full system DMB 1714 // FIXME: add encoding 1715} 1716 1717def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero), 1718 Pseudo, NoItinerary, 1719 "mcr", "\tp15, 0, $zero, c7, c10, 4", 1720 [(ARMSyncBarrierV6 GPR:$zero)]>, 1721 Requires<[IsARM, HasV6]> { 1722 // FIXME: add support for options other than a full system DSB 1723 // FIXME: add encoding 1724} 1725} 1726 1727let usesCustomInserter = 1 in { 1728 let Uses = [CPSR] in { 1729 def ATOMIC_LOAD_ADD_I8 : PseudoInst< 1730 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1731 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!", 1732 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>; 1733 def ATOMIC_LOAD_SUB_I8 : PseudoInst< 1734 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1735 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!", 1736 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>; 1737 def ATOMIC_LOAD_AND_I8 : PseudoInst< 1738 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1739 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!", 1740 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>; 1741 def ATOMIC_LOAD_OR_I8 : PseudoInst< 1742 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1743 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!", 1744 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>; 1745 def ATOMIC_LOAD_XOR_I8 : PseudoInst< 1746 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1747 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!", 1748 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>; 1749 def ATOMIC_LOAD_NAND_I8 : PseudoInst< 1750 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1751 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!", 1752 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>; 1753 def ATOMIC_LOAD_ADD_I16 : PseudoInst< 1754 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1755 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!", 1756 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>; 1757 def ATOMIC_LOAD_SUB_I16 : PseudoInst< 1758 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1759 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!", 1760 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>; 1761 def ATOMIC_LOAD_AND_I16 : PseudoInst< 1762 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1763 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!", 1764 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>; 1765 def ATOMIC_LOAD_OR_I16 : PseudoInst< 1766 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1767 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!", 1768 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>; 1769 def ATOMIC_LOAD_XOR_I16 : PseudoInst< 1770 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1771 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!", 1772 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>; 1773 def ATOMIC_LOAD_NAND_I16 : PseudoInst< 1774 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1775 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!", 1776 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>; 1777 def ATOMIC_LOAD_ADD_I32 : PseudoInst< 1778 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1779 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!", 1780 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>; 1781 def ATOMIC_LOAD_SUB_I32 : PseudoInst< 1782 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1783 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!", 1784 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>; 1785 def ATOMIC_LOAD_AND_I32 : PseudoInst< 1786 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1787 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!", 1788 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>; 1789 def ATOMIC_LOAD_OR_I32 : PseudoInst< 1790 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1791 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!", 1792 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>; 1793 def ATOMIC_LOAD_XOR_I32 : PseudoInst< 1794 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1795 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!", 1796 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>; 1797 def ATOMIC_LOAD_NAND_I32 : PseudoInst< 1798 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1799 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!", 1800 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>; 1801 1802 def ATOMIC_SWAP_I8 : PseudoInst< 1803 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 1804 "${:comment} ATOMIC_SWAP_I8 PSEUDO!", 1805 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>; 1806 def ATOMIC_SWAP_I16 : PseudoInst< 1807 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 1808 "${:comment} ATOMIC_SWAP_I16 PSEUDO!", 1809 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>; 1810 def ATOMIC_SWAP_I32 : PseudoInst< 1811 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 1812 "${:comment} ATOMIC_SWAP_I32 PSEUDO!", 1813 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>; 1814 1815 def ATOMIC_CMP_SWAP_I8 : PseudoInst< 1816 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 1817 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!", 1818 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>; 1819 def ATOMIC_CMP_SWAP_I16 : PseudoInst< 1820 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 1821 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!", 1822 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>; 1823 def ATOMIC_CMP_SWAP_I32 : PseudoInst< 1824 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 1825 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!", 1826 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>; 1827} 1828} 1829 1830let mayLoad = 1 in { 1831def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 1832 "ldrexb", "\t$dest, [$ptr]", 1833 []>; 1834def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 1835 "ldrexh", "\t$dest, [$ptr]", 1836 []>; 1837def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 1838 "ldrex", "\t$dest, [$ptr]", 1839 []>; 1840def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr), 1841 NoItinerary, 1842 "ldrexd", "\t$dest, $dest2, [$ptr]", 1843 []>; 1844} 1845 1846let mayStore = 1, Constraints = "@earlyclobber $success" in { 1847def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 1848 NoItinerary, 1849 "strexb", "\t$success, $src, [$ptr]", 1850 []>; 1851def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 1852 NoItinerary, 1853 "strexh", "\t$success, $src, [$ptr]", 1854 []>; 1855def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 1856 NoItinerary, 1857 "strex", "\t$success, $src, [$ptr]", 1858 []>; 1859def STREXD : AIstrex<0b01, (outs GPR:$success), 1860 (ins GPR:$src, GPR:$src2, GPR:$ptr), 1861 NoItinerary, 1862 "strexd", "\t$success, $src, $src2, [$ptr]", 1863 []>; 1864} 1865 1866// SWP/SWPB are deprecated in V6/V7 and for disassembly only. 1867let mayLoad = 1 in { 1868def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary, 1869 "swp", "\t$dst, $src, [$ptr]", 1870 [/* For disassembly only; pattern left blank */]> { 1871 let Inst{27-23} = 0b00010; 1872 let Inst{22} = 0; // B = 0 1873 let Inst{21-20} = 0b00; 1874 let Inst{7-4} = 0b1001; 1875} 1876 1877def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary, 1878 "swpb", "\t$dst, $src, [$ptr]", 1879 [/* For disassembly only; pattern left blank */]> { 1880 let Inst{27-23} = 0b00010; 1881 let Inst{22} = 1; // B = 1 1882 let Inst{21-20} = 0b00; 1883 let Inst{7-4} = 0b1001; 1884} 1885} 1886 1887//===----------------------------------------------------------------------===// 1888// TLS Instructions 1889// 1890 1891// __aeabi_read_tp preserves the registers r1-r3. 1892let isCall = 1, 1893 Defs = [R0, R12, LR, CPSR] in { 1894 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br, 1895 "bl\t__aeabi_read_tp", 1896 [(set R0, ARMthread_pointer)]>; 1897} 1898 1899//===----------------------------------------------------------------------===// 1900// SJLJ Exception handling intrinsics 1901// eh_sjlj_setjmp() is an instruction sequence to store the return 1902// address and save #0 in R0 for the non-longjmp case. 1903// Since by its nature we may be coming from some other function to get 1904// here, and we're using the stack frame for the containing function to 1905// save/restore registers, we can't keep anything live in regs across 1906// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 1907// when we get here from a longjmp(). We force everthing out of registers 1908// except for our own input by listing the relevant registers in Defs. By 1909// doing so, we also cause the prologue/epilogue code to actively preserve 1910// all of the callee-saved resgisters, which is exactly what we want. 1911// A constant value is passed in $val, and we use the location as a scratch. 1912let Defs = 1913 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0, 1914 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, 1915 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, 1916 D31 ] in { 1917 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val), 1918 AddrModeNone, SizeSpecial, IndexModeNone, 1919 Pseudo, NoItinerary, 1920 "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t" 1921 "add\t$val, pc, #8\n\t" 1922 "str\t$val, [$src, #+4]\n\t" 1923 "mov\tr0, #0\n\t" 1924 "add\tpc, pc, #0\n\t" 1925 "mov\tr0, #1 @ eh_setjmp end", "", 1926 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>; 1927} 1928 1929//===----------------------------------------------------------------------===// 1930// Non-Instruction Patterns 1931// 1932 1933// Large immediate handling. 1934 1935// Two piece so_imms. 1936let isReMaterializable = 1 in 1937def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 1938 Pseudo, IIC_iMOVi, 1939 "mov", "\t$dst, $src", 1940 [(set GPR:$dst, so_imm2part:$src)]>, 1941 Requires<[IsARM, NoV6T2]>; 1942 1943def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS), 1944 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 1945 (so_imm2part_2 imm:$RHS))>; 1946def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS), 1947 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 1948 (so_imm2part_2 imm:$RHS))>; 1949def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS), 1950 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 1951 (so_imm2part_2 imm:$RHS))>; 1952def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS), 1953 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)), 1954 (so_neg_imm2part_2 imm:$RHS))>; 1955 1956// 32-bit immediate using movw + movt. 1957// This is a single pseudo instruction, the benefit is that it can be remat'd 1958// as a single unit instead of having to handle reg inputs. 1959// FIXME: Remove this when we can do generalized remat. 1960let isReMaterializable = 1 in 1961def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi, 1962 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}", 1963 [(set GPR:$dst, (i32 imm:$src))]>, 1964 Requires<[IsARM, HasV6T2]>; 1965 1966// ConstantPool, GlobalAddress, and JumpTable 1967def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>, 1968 Requires<[IsARM, DontUseMovt]>; 1969def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; 1970def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>, 1971 Requires<[IsARM, UseMovt]>; 1972def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), 1973 (LEApcrelJT tjumptable:$dst, imm:$id)>; 1974 1975// TODO: add,sub,and, 3-instr forms? 1976 1977 1978// Direct calls 1979def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>, 1980 Requires<[IsARM, IsNotDarwin]>; 1981def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>, 1982 Requires<[IsARM, IsDarwin]>; 1983 1984// zextload i1 -> zextload i8 1985def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; 1986 1987// extload -> zextload 1988def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; 1989def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>; 1990def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; 1991 1992def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; 1993def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>; 1994 1995// smul* and smla* 1996def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 1997 (sra (shl GPR:$b, (i32 16)), (i32 16))), 1998 (SMULBB GPR:$a, GPR:$b)>; 1999def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b), 2000 (SMULBB GPR:$a, GPR:$b)>; 2001def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 2002 (sra GPR:$b, (i32 16))), 2003 (SMULBT GPR:$a, GPR:$b)>; 2004def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))), 2005 (SMULBT GPR:$a, GPR:$b)>; 2006def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), 2007 (sra (shl GPR:$b, (i32 16)), (i32 16))), 2008 (SMULTB GPR:$a, GPR:$b)>; 2009def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b), 2010 (SMULTB GPR:$a, GPR:$b)>; 2011def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 2012 (i32 16)), 2013 (SMULWB GPR:$a, GPR:$b)>; 2014def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)), 2015 (SMULWB GPR:$a, GPR:$b)>; 2016 2017def : ARMV5TEPat<(add GPR:$acc, 2018 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 2019 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 2020 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 2021def : ARMV5TEPat<(add GPR:$acc, 2022 (mul sext_16_node:$a, sext_16_node:$b)), 2023 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 2024def : ARMV5TEPat<(add GPR:$acc, 2025 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 2026 (sra GPR:$b, (i32 16)))), 2027 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 2028def : ARMV5TEPat<(add GPR:$acc, 2029 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))), 2030 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 2031def : ARMV5TEPat<(add GPR:$acc, 2032 (mul (sra GPR:$a, (i32 16)), 2033 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 2034 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 2035def : ARMV5TEPat<(add GPR:$acc, 2036 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)), 2037 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 2038def : ARMV5TEPat<(add GPR:$acc, 2039 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 2040 (i32 16))), 2041 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 2042def : ARMV5TEPat<(add GPR:$acc, 2043 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))), 2044 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 2045 2046//===----------------------------------------------------------------------===// 2047// Thumb Support 2048// 2049 2050include "ARMInstrThumb.td" 2051 2052//===----------------------------------------------------------------------===// 2053// Thumb2 Support 2054// 2055 2056include "ARMInstrThumb2.td" 2057 2058//===----------------------------------------------------------------------===// 2059// Floating Point Support 2060// 2061 2062include "ARMInstrVFP.td" 2063 2064//===----------------------------------------------------------------------===// 2065// Advanced SIMD (NEON) Support 2066// 2067 2068include "ARMInstrNEON.td" 2069 2070//===----------------------------------------------------------------------===// 2071// Coprocessor Instructions. For disassembly only. 2072// 2073 2074def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 2075 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 2076 NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2", 2077 [/* For disassembly only; pattern left blank */]> { 2078 let Inst{4} = 0; 2079} 2080 2081def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 2082 nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 2083 NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2", 2084 [/* For disassembly only; pattern left blank */]> { 2085 let Inst{31-28} = 0b1111; 2086 let Inst{4} = 0; 2087} 2088 2089def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 2090 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 2091 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2", 2092 [/* For disassembly only; pattern left blank */]> { 2093 let Inst{20} = 0; 2094 let Inst{4} = 1; 2095} 2096 2097def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 2098 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 2099 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2", 2100 [/* For disassembly only; pattern left blank */]> { 2101 let Inst{31-28} = 0b1111; 2102 let Inst{20} = 0; 2103 let Inst{4} = 1; 2104} 2105 2106def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 2107 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 2108 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2", 2109 [/* For disassembly only; pattern left blank */]> { 2110 let Inst{20} = 1; 2111 let Inst{4} = 1; 2112} 2113 2114def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1, 2115 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2), 2116 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2", 2117 [/* For disassembly only; pattern left blank */]> { 2118 let Inst{31-28} = 0b1111; 2119 let Inst{20} = 1; 2120 let Inst{4} = 1; 2121} 2122 2123def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc, 2124 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm), 2125 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm", 2126 [/* For disassembly only; pattern left blank */]> { 2127 let Inst{23-20} = 0b0100; 2128} 2129 2130def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc, 2131 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm), 2132 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm", 2133 [/* For disassembly only; pattern left blank */]> { 2134 let Inst{31-28} = 0b1111; 2135 let Inst{23-20} = 0b0100; 2136} 2137 2138def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc, 2139 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm), 2140 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm", 2141 [/* For disassembly only; pattern left blank */]> { 2142 let Inst{23-20} = 0b0101; 2143} 2144 2145def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc, 2146 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm), 2147 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm", 2148 [/* For disassembly only; pattern left blank */]> { 2149 let Inst{31-28} = 0b1111; 2150 let Inst{23-20} = 0b0101; 2151} 2152 2153//===----------------------------------------------------------------------===// 2154// Move between special register and ARM core register -- for disassembly only 2155// 2156 2157def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr", 2158 [/* For disassembly only; pattern left blank */]> { 2159 let Inst{23-20} = 0b0000; 2160 let Inst{7-4} = 0b0000; 2161} 2162 2163def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr", 2164 [/* For disassembly only; pattern left blank */]> { 2165 let Inst{23-20} = 0b0100; 2166 let Inst{7-4} = 0b0000; 2167} 2168 2169// FIXME: mask is ignored for the time being. 2170def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "mrs", "\tcpsr, $src", 2171 [/* For disassembly only; pattern left blank */]> { 2172 let Inst{23-20} = 0b0010; 2173 let Inst{7-4} = 0b0000; 2174} 2175 2176// FIXME: mask is ignored for the time being. 2177def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"mrs","\tspsr, $src", 2178 [/* For disassembly only; pattern left blank */]> { 2179 let Inst{23-20} = 0b0110; 2180 let Inst{7-4} = 0b0000; 2181} 2182