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