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