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