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