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