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