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