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