ARMInstrInfo.td revision 239462
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> ]>; 21def SDT_ARMStructByVal : SDTypeProfile<0, 4, 22 [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 23 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 24 25def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>; 26 27def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 28 29def SDT_ARMCMov : SDTypeProfile<1, 3, 30 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 31 SDTCisVT<3, i32>]>; 32 33def SDT_ARMBrcond : SDTypeProfile<0, 2, 34 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 35 36def SDT_ARMBrJT : SDTypeProfile<0, 3, 37 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 38 SDTCisVT<2, i32>]>; 39 40def SDT_ARMBr2JT : SDTypeProfile<0, 4, 41 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 42 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 43 44def SDT_ARMBCC_i64 : SDTypeProfile<0, 6, 45 [SDTCisVT<0, i32>, 46 SDTCisVT<1, i32>, SDTCisVT<2, i32>, 47 SDTCisVT<3, i32>, SDTCisVT<4, i32>, 48 SDTCisVT<5, OtherVT>]>; 49 50def SDT_ARMAnd : SDTypeProfile<1, 2, 51 [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 52 SDTCisVT<2, i32>]>; 53 54def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 55 56def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, 57 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; 58 59def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; 60def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>, 61 SDTCisInt<2>]>; 62def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>; 63 64def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 65 66def SDT_ARMPREFETCH : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, 67 SDTCisInt<1>]>; 68 69def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 70 71def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 72 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 73 74def SDTBinaryArithWithFlags : SDTypeProfile<2, 2, 75 [SDTCisSameAs<0, 2>, 76 SDTCisSameAs<0, 3>, 77 SDTCisInt<0>, SDTCisVT<1, i32>]>; 78 79// SDTBinaryArithWithFlagsInOut - RES1, CPSR = op LHS, RHS, CPSR 80def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3, 81 [SDTCisSameAs<0, 2>, 82 SDTCisSameAs<0, 3>, 83 SDTCisInt<0>, 84 SDTCisVT<1, i32>, 85 SDTCisVT<4, i32>]>; 86// Node definitions. 87def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; 88def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>; 89def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>; 90def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; 91 92def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, 93 [SDNPHasChain, SDNPOutGlue]>; 94def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd, 95 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 96def ARMcopystructbyval : SDNode<"ARMISD::COPY_STRUCT_BYVAL" , 97 SDT_ARMStructByVal, 98 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, 99 SDNPMayStore, SDNPMayLoad]>; 100 101def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall, 102 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 103 SDNPVariadic]>; 104def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall, 105 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 106 SDNPVariadic]>; 107def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall, 108 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 109 SDNPVariadic]>; 110 111def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone, 112 [SDNPHasChain, SDNPOptInGlue]>; 113 114def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, 115 [SDNPInGlue]>; 116 117def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, 118 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; 119 120def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, 121 [SDNPHasChain]>; 122def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT, 123 [SDNPHasChain]>; 124 125def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64, 126 [SDNPHasChain]>; 127 128def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, 129 [SDNPOutGlue]>; 130 131def ARMcmn : SDNode<"ARMISD::CMN", SDT_ARMCmp, 132 [SDNPOutGlue]>; 133 134def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, 135 [SDNPOutGlue, SDNPCommutative]>; 136 137def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; 138 139def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; 140def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; 141def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>; 142 143def ARMaddc : SDNode<"ARMISD::ADDC", SDTBinaryArithWithFlags, 144 [SDNPCommutative]>; 145def ARMsubc : SDNode<"ARMISD::SUBC", SDTBinaryArithWithFlags>; 146def ARMadde : SDNode<"ARMISD::ADDE", SDTBinaryArithWithFlagsInOut>; 147def ARMsube : SDNode<"ARMISD::SUBE", SDTBinaryArithWithFlagsInOut>; 148 149def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; 150def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", 151 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>; 152def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP", 153 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>; 154 155def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER, 156 [SDNPHasChain]>; 157def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER, 158 [SDNPHasChain]>; 159def ARMPreload : SDNode<"ARMISD::PRELOAD", SDT_ARMPREFETCH, 160 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>; 161 162def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>; 163 164def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET, 165 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 166 167 168def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>; 169 170//===----------------------------------------------------------------------===// 171// ARM Instruction Predicate Definitions. 172// 173def HasV4T : Predicate<"Subtarget->hasV4TOps()">, 174 AssemblerPredicate<"HasV4TOps", "armv4t">; 175def NoV4T : Predicate<"!Subtarget->hasV4TOps()">; 176def HasV5T : Predicate<"Subtarget->hasV5TOps()">; 177def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, 178 AssemblerPredicate<"HasV5TEOps", "armv5te">; 179def HasV6 : Predicate<"Subtarget->hasV6Ops()">, 180 AssemblerPredicate<"HasV6Ops", "armv6">; 181def NoV6 : Predicate<"!Subtarget->hasV6Ops()">; 182def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, 183 AssemblerPredicate<"HasV6T2Ops", "armv6t2">; 184def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; 185def HasV7 : Predicate<"Subtarget->hasV7Ops()">, 186 AssemblerPredicate<"HasV7Ops", "armv7">; 187def NoVFP : Predicate<"!Subtarget->hasVFP2()">; 188def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, 189 AssemblerPredicate<"FeatureVFP2", "VFP2">; 190def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, 191 AssemblerPredicate<"FeatureVFP3", "VFP3">; 192def HasVFP4 : Predicate<"Subtarget->hasVFP4()">, 193 AssemblerPredicate<"FeatureVFP4", "VFP4">; 194def HasNEON : Predicate<"Subtarget->hasNEON()">, 195 AssemblerPredicate<"FeatureNEON", "NEON">; 196def HasFP16 : Predicate<"Subtarget->hasFP16()">, 197 AssemblerPredicate<"FeatureFP16","half-float">; 198def HasDivide : Predicate<"Subtarget->hasDivide()">, 199 AssemblerPredicate<"FeatureHWDiv", "divide">; 200def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">, 201 AssemblerPredicate<"FeatureT2XtPk", 202 "pack/extract">; 203def HasThumb2DSP : Predicate<"Subtarget->hasThumb2DSP()">, 204 AssemblerPredicate<"FeatureDSPThumb2", 205 "thumb2-dsp">; 206def HasDB : Predicate<"Subtarget->hasDataBarrier()">, 207 AssemblerPredicate<"FeatureDB", 208 "data-barriers">; 209def HasMP : Predicate<"Subtarget->hasMPExtension()">, 210 AssemblerPredicate<"FeatureMP", 211 "mp-extensions">; 212def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; 213def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; 214def IsThumb : Predicate<"Subtarget->isThumb()">, 215 AssemblerPredicate<"ModeThumb", "thumb">; 216def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; 217def IsThumb2 : Predicate<"Subtarget->isThumb2()">, 218 AssemblerPredicate<"ModeThumb,FeatureThumb2", 219 "thumb2">; 220def IsMClass : Predicate<"Subtarget->isMClass()">, 221 AssemblerPredicate<"FeatureMClass", "armv7m">; 222def IsARClass : Predicate<"!Subtarget->isMClass()">, 223 AssemblerPredicate<"!FeatureMClass", 224 "armv7a/r">; 225def IsARM : Predicate<"!Subtarget->isThumb()">, 226 AssemblerPredicate<"!ModeThumb", "arm-mode">; 227def IsIOS : Predicate<"Subtarget->isTargetIOS()">; 228def IsNotIOS : Predicate<"!Subtarget->isTargetIOS()">; 229def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">; 230 231// FIXME: Eventually this will be just "hasV6T2Ops". 232def UseMovt : Predicate<"Subtarget->useMovt()">; 233def DontUseMovt : Predicate<"!Subtarget->useMovt()">; 234def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">; 235 236// Prefer fused MAC for fp mul + add over fp VMLA / VMLS if they are available. 237// But only select them if more precision in FP computation is allowed. 238// Do not use them for Darwin platforms. 239def UseFusedMAC : Predicate<"(TM.Options.AllowFPOpFusion ==" 240 " FPOpFusion::Fast) && " 241 "!Subtarget->isTargetDarwin()">; 242def DontUseFusedMAC : Predicate<"!Subtarget->hasVFP4() || " 243 "Subtarget->isTargetDarwin()">; 244 245def IsLE : Predicate<"TLI.isLittleEndian()">; 246def IsBE : Predicate<"TLI.isBigEndian()">; 247 248//===----------------------------------------------------------------------===// 249// ARM Flag Definitions. 250 251class RegConstraint<string C> { 252 string Constraints = C; 253} 254 255//===----------------------------------------------------------------------===// 256// ARM specific transformation functions and pattern fragments. 257// 258 259// imm_neg_XFORM - Return a imm value packed into the format described for 260// imm_neg defs below. 261def imm_neg_XFORM : SDNodeXForm<imm, [{ 262 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 263}]>; 264 265// so_imm_not_XFORM - Return a so_imm value packed into the format described for 266// so_imm_not def below. 267def so_imm_not_XFORM : SDNodeXForm<imm, [{ 268 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32); 269}]>; 270 271/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31]. 272def imm16_31 : ImmLeaf<i32, [{ 273 return (int32_t)Imm >= 16 && (int32_t)Imm < 32; 274}]>; 275 276def so_imm_neg_asmoperand : AsmOperandClass { let Name = "ARMSOImmNeg"; } 277def so_imm_neg : Operand<i32>, PatLeaf<(imm), [{ 278 int64_t Value = -(int)N->getZExtValue(); 279 return Value && ARM_AM::getSOImmVal(Value) != -1; 280 }], imm_neg_XFORM> { 281 let ParserMatchClass = so_imm_neg_asmoperand; 282} 283 284// Note: this pattern doesn't require an encoder method and such, as it's 285// only used on aliases (Pat<> and InstAlias<>). The actual encoding 286// is handled by the destination instructions, which use so_imm. 287def so_imm_not_asmoperand : AsmOperandClass { let Name = "ARMSOImmNot"; } 288def so_imm_not : Operand<i32>, PatLeaf<(imm), [{ 289 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1; 290 }], so_imm_not_XFORM> { 291 let ParserMatchClass = so_imm_not_asmoperand; 292} 293 294// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits. 295def sext_16_node : PatLeaf<(i32 GPR:$a), [{ 296 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17; 297}]>; 298 299/// Split a 32-bit immediate into two 16 bit parts. 300def hi16 : SDNodeXForm<imm, [{ 301 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32); 302}]>; 303 304def lo16AllZero : PatLeaf<(i32 imm), [{ 305 // Returns true if all low 16-bits are 0. 306 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0; 307}], hi16>; 308 309class BinOpWithFlagFrag<dag res> : 310 PatFrag<(ops node:$LHS, node:$RHS, node:$FLAG), res>; 311class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 312class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>; 313 314// An 'and' node with a single use. 315def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ 316 return N->hasOneUse(); 317}]>; 318 319// An 'xor' node with a single use. 320def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{ 321 return N->hasOneUse(); 322}]>; 323 324// An 'fmul' node with a single use. 325def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{ 326 return N->hasOneUse(); 327}]>; 328 329// An 'fadd' node which checks for single non-hazardous use. 330def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{ 331 return hasNoVMLxHazardUse(N); 332}]>; 333 334// An 'fsub' node which checks for single non-hazardous use. 335def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{ 336 return hasNoVMLxHazardUse(N); 337}]>; 338 339//===----------------------------------------------------------------------===// 340// Operand Definitions. 341// 342 343// Immediate operands with a shared generic asm render method. 344class ImmAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; } 345 346// Branch target. 347// FIXME: rename brtarget to t2_brtarget 348def brtarget : Operand<OtherVT> { 349 let EncoderMethod = "getBranchTargetOpValue"; 350 let OperandType = "OPERAND_PCREL"; 351 let DecoderMethod = "DecodeT2BROperand"; 352} 353 354// FIXME: get rid of this one? 355def uncondbrtarget : Operand<OtherVT> { 356 let EncoderMethod = "getUnconditionalBranchTargetOpValue"; 357 let OperandType = "OPERAND_PCREL"; 358} 359 360// Branch target for ARM. Handles conditional/unconditional 361def br_target : Operand<OtherVT> { 362 let EncoderMethod = "getARMBranchTargetOpValue"; 363 let OperandType = "OPERAND_PCREL"; 364} 365 366// Call target. 367// FIXME: rename bltarget to t2_bl_target? 368def bltarget : Operand<i32> { 369 // Encoded the same as branch targets. 370 let EncoderMethod = "getBranchTargetOpValue"; 371 let OperandType = "OPERAND_PCREL"; 372} 373 374// Call target for ARM. Handles conditional/unconditional 375// FIXME: rename bl_target to t2_bltarget? 376def bl_target : Operand<i32> { 377 let EncoderMethod = "getARMBLTargetOpValue"; 378 let OperandType = "OPERAND_PCREL"; 379} 380 381def blx_target : Operand<i32> { 382 let EncoderMethod = "getARMBLXTargetOpValue"; 383 let OperandType = "OPERAND_PCREL"; 384} 385 386// A list of registers separated by comma. Used by load/store multiple. 387def RegListAsmOperand : AsmOperandClass { let Name = "RegList"; } 388def reglist : Operand<i32> { 389 let EncoderMethod = "getRegisterListOpValue"; 390 let ParserMatchClass = RegListAsmOperand; 391 let PrintMethod = "printRegisterList"; 392 let DecoderMethod = "DecodeRegListOperand"; 393} 394 395def DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; } 396def dpr_reglist : Operand<i32> { 397 let EncoderMethod = "getRegisterListOpValue"; 398 let ParserMatchClass = DPRRegListAsmOperand; 399 let PrintMethod = "printRegisterList"; 400 let DecoderMethod = "DecodeDPRRegListOperand"; 401} 402 403def SPRRegListAsmOperand : AsmOperandClass { let Name = "SPRRegList"; } 404def spr_reglist : Operand<i32> { 405 let EncoderMethod = "getRegisterListOpValue"; 406 let ParserMatchClass = SPRRegListAsmOperand; 407 let PrintMethod = "printRegisterList"; 408 let DecoderMethod = "DecodeSPRRegListOperand"; 409} 410 411// An operand for the CONSTPOOL_ENTRY pseudo-instruction. 412def cpinst_operand : Operand<i32> { 413 let PrintMethod = "printCPInstOperand"; 414} 415 416// Local PC labels. 417def pclabel : Operand<i32> { 418 let PrintMethod = "printPCLabel"; 419} 420 421// ADR instruction labels. 422def AdrLabelAsmOperand : AsmOperandClass { let Name = "AdrLabel"; } 423def adrlabel : Operand<i32> { 424 let EncoderMethod = "getAdrLabelOpValue"; 425 let ParserMatchClass = AdrLabelAsmOperand; 426 let PrintMethod = "printAdrLabelOperand"; 427} 428 429def neon_vcvt_imm32 : Operand<i32> { 430 let EncoderMethod = "getNEONVcvtImm32OpValue"; 431 let DecoderMethod = "DecodeVCVTImmOperand"; 432} 433 434// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24. 435def rot_imm_XFORM: SDNodeXForm<imm, [{ 436 switch (N->getZExtValue()){ 437 default: assert(0); 438 case 0: return CurDAG->getTargetConstant(0, MVT::i32); 439 case 8: return CurDAG->getTargetConstant(1, MVT::i32); 440 case 16: return CurDAG->getTargetConstant(2, MVT::i32); 441 case 24: return CurDAG->getTargetConstant(3, MVT::i32); 442 } 443}]>; 444def RotImmAsmOperand : AsmOperandClass { 445 let Name = "RotImm"; 446 let ParserMethod = "parseRotImm"; 447} 448def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{ 449 int32_t v = N->getZExtValue(); 450 return v == 8 || v == 16 || v == 24; }], 451 rot_imm_XFORM> { 452 let PrintMethod = "printRotImmOperand"; 453 let ParserMatchClass = RotImmAsmOperand; 454} 455 456// shift_imm: An integer that encodes a shift amount and the type of shift 457// (asr or lsl). The 6-bit immediate encodes as: 458// {5} 0 ==> lsl 459// 1 asr 460// {4-0} imm5 shift amount. 461// asr #32 encoded as imm5 == 0. 462def ShifterImmAsmOperand : AsmOperandClass { 463 let Name = "ShifterImm"; 464 let ParserMethod = "parseShifterImm"; 465} 466def shift_imm : Operand<i32> { 467 let PrintMethod = "printShiftImmOperand"; 468 let ParserMatchClass = ShifterImmAsmOperand; 469} 470 471// shifter_operand operands: so_reg_reg, so_reg_imm, and so_imm. 472def ShiftedRegAsmOperand : AsmOperandClass { let Name = "RegShiftedReg"; } 473def so_reg_reg : Operand<i32>, // reg reg imm 474 ComplexPattern<i32, 3, "SelectRegShifterOperand", 475 [shl, srl, sra, rotr]> { 476 let EncoderMethod = "getSORegRegOpValue"; 477 let PrintMethod = "printSORegRegOperand"; 478 let DecoderMethod = "DecodeSORegRegOperand"; 479 let ParserMatchClass = ShiftedRegAsmOperand; 480 let MIOperandInfo = (ops GPRnopc, GPRnopc, i32imm); 481} 482 483def ShiftedImmAsmOperand : AsmOperandClass { let Name = "RegShiftedImm"; } 484def so_reg_imm : Operand<i32>, // reg imm 485 ComplexPattern<i32, 2, "SelectImmShifterOperand", 486 [shl, srl, sra, rotr]> { 487 let EncoderMethod = "getSORegImmOpValue"; 488 let PrintMethod = "printSORegImmOperand"; 489 let DecoderMethod = "DecodeSORegImmOperand"; 490 let ParserMatchClass = ShiftedImmAsmOperand; 491 let MIOperandInfo = (ops GPR, i32imm); 492} 493 494// FIXME: Does this need to be distinct from so_reg? 495def shift_so_reg_reg : Operand<i32>, // reg reg imm 496 ComplexPattern<i32, 3, "SelectShiftRegShifterOperand", 497 [shl,srl,sra,rotr]> { 498 let EncoderMethod = "getSORegRegOpValue"; 499 let PrintMethod = "printSORegRegOperand"; 500 let DecoderMethod = "DecodeSORegRegOperand"; 501 let ParserMatchClass = ShiftedRegAsmOperand; 502 let MIOperandInfo = (ops GPR, GPR, i32imm); 503} 504 505// FIXME: Does this need to be distinct from so_reg? 506def shift_so_reg_imm : Operand<i32>, // reg reg imm 507 ComplexPattern<i32, 2, "SelectShiftImmShifterOperand", 508 [shl,srl,sra,rotr]> { 509 let EncoderMethod = "getSORegImmOpValue"; 510 let PrintMethod = "printSORegImmOperand"; 511 let DecoderMethod = "DecodeSORegImmOperand"; 512 let ParserMatchClass = ShiftedImmAsmOperand; 513 let MIOperandInfo = (ops GPR, i32imm); 514} 515 516 517// so_imm - Match a 32-bit shifter_operand immediate operand, which is an 518// 8-bit immediate rotated by an arbitrary number of bits. 519def SOImmAsmOperand: ImmAsmOperand { let Name = "ARMSOImm"; } 520def so_imm : Operand<i32>, ImmLeaf<i32, [{ 521 return ARM_AM::getSOImmVal(Imm) != -1; 522 }]> { 523 let EncoderMethod = "getSOImmOpValue"; 524 let ParserMatchClass = SOImmAsmOperand; 525 let DecoderMethod = "DecodeSOImmOperand"; 526} 527 528// Break so_imm's up into two pieces. This handles immediates with up to 16 529// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to 530// get the first/second pieces. 531def so_imm2part : PatLeaf<(imm), [{ 532 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 533}]>; 534 535/// arm_i32imm - True for +V6T2, or true only if so_imm2part is true. 536/// 537def arm_i32imm : PatLeaf<(imm), [{ 538 if (Subtarget->hasV6T2Ops()) 539 return true; 540 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 541}]>; 542 543/// imm0_1 predicate - Immediate in the range [0,1]. 544def Imm0_1AsmOperand: ImmAsmOperand { let Name = "Imm0_1"; } 545def imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; } 546 547/// imm0_3 predicate - Immediate in the range [0,3]. 548def Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; } 549def imm0_3 : Operand<i32> { let ParserMatchClass = Imm0_3AsmOperand; } 550 551/// imm0_7 predicate - Immediate in the range [0,7]. 552def Imm0_7AsmOperand: ImmAsmOperand { let Name = "Imm0_7"; } 553def imm0_7 : Operand<i32>, ImmLeaf<i32, [{ 554 return Imm >= 0 && Imm < 8; 555}]> { 556 let ParserMatchClass = Imm0_7AsmOperand; 557} 558 559/// imm8 predicate - Immediate is exactly 8. 560def Imm8AsmOperand: ImmAsmOperand { let Name = "Imm8"; } 561def imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 8; }]> { 562 let ParserMatchClass = Imm8AsmOperand; 563} 564 565/// imm16 predicate - Immediate is exactly 16. 566def Imm16AsmOperand: ImmAsmOperand { let Name = "Imm16"; } 567def imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 16; }]> { 568 let ParserMatchClass = Imm16AsmOperand; 569} 570 571/// imm32 predicate - Immediate is exactly 32. 572def Imm32AsmOperand: ImmAsmOperand { let Name = "Imm32"; } 573def imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 32; }]> { 574 let ParserMatchClass = Imm32AsmOperand; 575} 576 577/// imm1_7 predicate - Immediate in the range [1,7]. 578def Imm1_7AsmOperand: ImmAsmOperand { let Name = "Imm1_7"; } 579def imm1_7 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 8; }]> { 580 let ParserMatchClass = Imm1_7AsmOperand; 581} 582 583/// imm1_15 predicate - Immediate in the range [1,15]. 584def Imm1_15AsmOperand: ImmAsmOperand { let Name = "Imm1_15"; } 585def imm1_15 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 16; }]> { 586 let ParserMatchClass = Imm1_15AsmOperand; 587} 588 589/// imm1_31 predicate - Immediate in the range [1,31]. 590def Imm1_31AsmOperand: ImmAsmOperand { let Name = "Imm1_31"; } 591def imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> { 592 let ParserMatchClass = Imm1_31AsmOperand; 593} 594 595/// imm0_15 predicate - Immediate in the range [0,15]. 596def Imm0_15AsmOperand: ImmAsmOperand { 597 let Name = "Imm0_15"; 598 let DiagnosticType = "ImmRange0_15"; 599} 600def imm0_15 : Operand<i32>, ImmLeaf<i32, [{ 601 return Imm >= 0 && Imm < 16; 602}]> { 603 let ParserMatchClass = Imm0_15AsmOperand; 604} 605 606/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31]. 607def Imm0_31AsmOperand: ImmAsmOperand { let Name = "Imm0_31"; } 608def imm0_31 : Operand<i32>, ImmLeaf<i32, [{ 609 return Imm >= 0 && Imm < 32; 610}]> { 611 let ParserMatchClass = Imm0_31AsmOperand; 612} 613 614/// imm0_32 predicate - True if the 32-bit immediate is in the range [0,32]. 615def Imm0_32AsmOperand: ImmAsmOperand { let Name = "Imm0_32"; } 616def imm0_32 : Operand<i32>, ImmLeaf<i32, [{ 617 return Imm >= 0 && Imm < 32; 618}]> { 619 let ParserMatchClass = Imm0_32AsmOperand; 620} 621 622/// imm0_63 predicate - True if the 32-bit immediate is in the range [0,63]. 623def Imm0_63AsmOperand: ImmAsmOperand { let Name = "Imm0_63"; } 624def imm0_63 : Operand<i32>, ImmLeaf<i32, [{ 625 return Imm >= 0 && Imm < 64; 626}]> { 627 let ParserMatchClass = Imm0_63AsmOperand; 628} 629 630/// imm0_255 predicate - Immediate in the range [0,255]. 631def Imm0_255AsmOperand : ImmAsmOperand { let Name = "Imm0_255"; } 632def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> { 633 let ParserMatchClass = Imm0_255AsmOperand; 634} 635 636/// imm0_65535 - An immediate is in the range [0.65535]. 637def Imm0_65535AsmOperand: ImmAsmOperand { let Name = "Imm0_65535"; } 638def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{ 639 return Imm >= 0 && Imm < 65536; 640}]> { 641 let ParserMatchClass = Imm0_65535AsmOperand; 642} 643 644// imm0_65535_neg - An immediate whose negative value is in the range [0.65535]. 645def imm0_65535_neg : Operand<i32>, ImmLeaf<i32, [{ 646 return -Imm >= 0 && -Imm < 65536; 647}]>; 648 649// imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference 650// a relocatable expression. 651// 652// FIXME: This really needs a Thumb version separate from the ARM version. 653// While the range is the same, and can thus use the same match class, 654// the encoding is different so it should have a different encoder method. 655def Imm0_65535ExprAsmOperand: ImmAsmOperand { let Name = "Imm0_65535Expr"; } 656def imm0_65535_expr : Operand<i32> { 657 let EncoderMethod = "getHiLo16ImmOpValue"; 658 let ParserMatchClass = Imm0_65535ExprAsmOperand; 659} 660 661/// imm24b - True if the 32-bit immediate is encodable in 24 bits. 662def Imm24bitAsmOperand: ImmAsmOperand { let Name = "Imm24bit"; } 663def imm24b : Operand<i32>, ImmLeaf<i32, [{ 664 return Imm >= 0 && Imm <= 0xffffff; 665}]> { 666 let ParserMatchClass = Imm24bitAsmOperand; 667} 668 669 670/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield 671/// e.g., 0xf000ffff 672def BitfieldAsmOperand : AsmOperandClass { 673 let Name = "Bitfield"; 674 let ParserMethod = "parseBitfield"; 675} 676 677def bf_inv_mask_imm : Operand<i32>, 678 PatLeaf<(imm), [{ 679 return ARM::isBitFieldInvertedMask(N->getZExtValue()); 680}] > { 681 let EncoderMethod = "getBitfieldInvertedMaskOpValue"; 682 let PrintMethod = "printBitfieldInvMaskImmOperand"; 683 let DecoderMethod = "DecodeBitfieldMaskOperand"; 684 let ParserMatchClass = BitfieldAsmOperand; 685} 686 687def imm1_32_XFORM: SDNodeXForm<imm, [{ 688 return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32); 689}]>; 690def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; } 691def imm1_32 : Operand<i32>, PatLeaf<(imm), [{ 692 uint64_t Imm = N->getZExtValue(); 693 return Imm > 0 && Imm <= 32; 694 }], 695 imm1_32_XFORM> { 696 let PrintMethod = "printImmPlusOneOperand"; 697 let ParserMatchClass = Imm1_32AsmOperand; 698} 699 700def imm1_16_XFORM: SDNodeXForm<imm, [{ 701 return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32); 702}]>; 703def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; } 704def imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }], 705 imm1_16_XFORM> { 706 let PrintMethod = "printImmPlusOneOperand"; 707 let ParserMatchClass = Imm1_16AsmOperand; 708} 709 710// Define ARM specific addressing modes. 711// addrmode_imm12 := reg +/- imm12 712// 713def MemImm12OffsetAsmOperand : AsmOperandClass { let Name = "MemImm12Offset"; } 714def addrmode_imm12 : Operand<i32>, 715 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> { 716 // 12-bit immediate operand. Note that instructions using this encode 717 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other 718 // immediate values are as normal. 719 720 let EncoderMethod = "getAddrModeImm12OpValue"; 721 let PrintMethod = "printAddrModeImm12Operand"; 722 let DecoderMethod = "DecodeAddrModeImm12Operand"; 723 let ParserMatchClass = MemImm12OffsetAsmOperand; 724 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 725} 726// ldst_so_reg := reg +/- reg shop imm 727// 728def MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; } 729def ldst_so_reg : Operand<i32>, 730 ComplexPattern<i32, 3, "SelectLdStSOReg", []> { 731 let EncoderMethod = "getLdStSORegOpValue"; 732 // FIXME: Simplify the printer 733 let PrintMethod = "printAddrMode2Operand"; 734 let DecoderMethod = "DecodeSORegMemOperand"; 735 let ParserMatchClass = MemRegOffsetAsmOperand; 736 let MIOperandInfo = (ops GPR:$base, GPRnopc:$offsreg, i32imm:$shift); 737} 738 739// postidx_imm8 := +/- [0,255] 740// 741// 9 bit value: 742// {8} 1 is imm8 is non-negative. 0 otherwise. 743// {7-0} [0,255] imm8 value. 744def PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; } 745def postidx_imm8 : Operand<i32> { 746 let PrintMethod = "printPostIdxImm8Operand"; 747 let ParserMatchClass = PostIdxImm8AsmOperand; 748 let MIOperandInfo = (ops i32imm); 749} 750 751// postidx_imm8s4 := +/- [0,1020] 752// 753// 9 bit value: 754// {8} 1 is imm8 is non-negative. 0 otherwise. 755// {7-0} [0,255] imm8 value, scaled by 4. 756def PostIdxImm8s4AsmOperand : AsmOperandClass { let Name = "PostIdxImm8s4"; } 757def postidx_imm8s4 : Operand<i32> { 758 let PrintMethod = "printPostIdxImm8s4Operand"; 759 let ParserMatchClass = PostIdxImm8s4AsmOperand; 760 let MIOperandInfo = (ops i32imm); 761} 762 763 764// postidx_reg := +/- reg 765// 766def PostIdxRegAsmOperand : AsmOperandClass { 767 let Name = "PostIdxReg"; 768 let ParserMethod = "parsePostIdxReg"; 769} 770def postidx_reg : Operand<i32> { 771 let EncoderMethod = "getPostIdxRegOpValue"; 772 let DecoderMethod = "DecodePostIdxReg"; 773 let PrintMethod = "printPostIdxRegOperand"; 774 let ParserMatchClass = PostIdxRegAsmOperand; 775 let MIOperandInfo = (ops GPRnopc, i32imm); 776} 777 778 779// addrmode2 := reg +/- imm12 780// := reg +/- reg shop imm 781// 782// FIXME: addrmode2 should be refactored the rest of the way to always 783// use explicit imm vs. reg versions above (addrmode_imm12 and ldst_so_reg). 784def AddrMode2AsmOperand : AsmOperandClass { let Name = "AddrMode2"; } 785def addrmode2 : Operand<i32>, 786 ComplexPattern<i32, 3, "SelectAddrMode2", []> { 787 let EncoderMethod = "getAddrMode2OpValue"; 788 let PrintMethod = "printAddrMode2Operand"; 789 let ParserMatchClass = AddrMode2AsmOperand; 790 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 791} 792 793def PostIdxRegShiftedAsmOperand : AsmOperandClass { 794 let Name = "PostIdxRegShifted"; 795 let ParserMethod = "parsePostIdxReg"; 796} 797def am2offset_reg : Operand<i32>, 798 ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg", 799 [], [SDNPWantRoot]> { 800 let EncoderMethod = "getAddrMode2OffsetOpValue"; 801 let PrintMethod = "printAddrMode2OffsetOperand"; 802 // When using this for assembly, it's always as a post-index offset. 803 let ParserMatchClass = PostIdxRegShiftedAsmOperand; 804 let MIOperandInfo = (ops GPRnopc, i32imm); 805} 806 807// FIXME: am2offset_imm should only need the immediate, not the GPR. Having 808// the GPR is purely vestigal at this point. 809def AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; } 810def am2offset_imm : Operand<i32>, 811 ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm", 812 [], [SDNPWantRoot]> { 813 let EncoderMethod = "getAddrMode2OffsetOpValue"; 814 let PrintMethod = "printAddrMode2OffsetOperand"; 815 let ParserMatchClass = AM2OffsetImmAsmOperand; 816 let MIOperandInfo = (ops GPRnopc, i32imm); 817} 818 819 820// addrmode3 := reg +/- reg 821// addrmode3 := reg +/- imm8 822// 823// FIXME: split into imm vs. reg versions. 824def AddrMode3AsmOperand : AsmOperandClass { let Name = "AddrMode3"; } 825def addrmode3 : Operand<i32>, 826 ComplexPattern<i32, 3, "SelectAddrMode3", []> { 827 let EncoderMethod = "getAddrMode3OpValue"; 828 let PrintMethod = "printAddrMode3Operand"; 829 let ParserMatchClass = AddrMode3AsmOperand; 830 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 831} 832 833// FIXME: split into imm vs. reg versions. 834// FIXME: parser method to handle +/- register. 835def AM3OffsetAsmOperand : AsmOperandClass { 836 let Name = "AM3Offset"; 837 let ParserMethod = "parseAM3Offset"; 838} 839def am3offset : Operand<i32>, 840 ComplexPattern<i32, 2, "SelectAddrMode3Offset", 841 [], [SDNPWantRoot]> { 842 let EncoderMethod = "getAddrMode3OffsetOpValue"; 843 let PrintMethod = "printAddrMode3OffsetOperand"; 844 let ParserMatchClass = AM3OffsetAsmOperand; 845 let MIOperandInfo = (ops GPR, i32imm); 846} 847 848// ldstm_mode := {ia, ib, da, db} 849// 850def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> { 851 let EncoderMethod = "getLdStmModeOpValue"; 852 let PrintMethod = "printLdStmModeOperand"; 853} 854 855// addrmode5 := reg +/- imm8*4 856// 857def AddrMode5AsmOperand : AsmOperandClass { let Name = "AddrMode5"; } 858def addrmode5 : Operand<i32>, 859 ComplexPattern<i32, 2, "SelectAddrMode5", []> { 860 let PrintMethod = "printAddrMode5Operand"; 861 let EncoderMethod = "getAddrMode5OpValue"; 862 let DecoderMethod = "DecodeAddrMode5Operand"; 863 let ParserMatchClass = AddrMode5AsmOperand; 864 let MIOperandInfo = (ops GPR:$base, i32imm); 865} 866 867// addrmode6 := reg with optional alignment 868// 869def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; } 870def addrmode6 : Operand<i32>, 871 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 872 let PrintMethod = "printAddrMode6Operand"; 873 let MIOperandInfo = (ops GPR:$addr, i32imm:$align); 874 let EncoderMethod = "getAddrMode6AddressOpValue"; 875 let DecoderMethod = "DecodeAddrMode6Operand"; 876 let ParserMatchClass = AddrMode6AsmOperand; 877} 878 879def am6offset : Operand<i32>, 880 ComplexPattern<i32, 1, "SelectAddrMode6Offset", 881 [], [SDNPWantRoot]> { 882 let PrintMethod = "printAddrMode6OffsetOperand"; 883 let MIOperandInfo = (ops GPR); 884 let EncoderMethod = "getAddrMode6OffsetOpValue"; 885 let DecoderMethod = "DecodeGPRRegisterClass"; 886} 887 888// Special version of addrmode6 to handle alignment encoding for VST1/VLD1 889// (single element from one lane) for size 32. 890def addrmode6oneL32 : Operand<i32>, 891 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 892 let PrintMethod = "printAddrMode6Operand"; 893 let MIOperandInfo = (ops GPR:$addr, i32imm); 894 let EncoderMethod = "getAddrMode6OneLane32AddressOpValue"; 895} 896 897// Special version of addrmode6 to handle alignment encoding for VLD-dup 898// instructions, specifically VLD4-dup. 899def addrmode6dup : Operand<i32>, 900 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 901 let PrintMethod = "printAddrMode6Operand"; 902 let MIOperandInfo = (ops GPR:$addr, i32imm); 903 let EncoderMethod = "getAddrMode6DupAddressOpValue"; 904 // FIXME: This is close, but not quite right. The alignment specifier is 905 // different. 906 let ParserMatchClass = AddrMode6AsmOperand; 907} 908 909// addrmodepc := pc + reg 910// 911def addrmodepc : Operand<i32>, 912 ComplexPattern<i32, 2, "SelectAddrModePC", []> { 913 let PrintMethod = "printAddrModePCOperand"; 914 let MIOperandInfo = (ops GPR, i32imm); 915} 916 917// addr_offset_none := reg 918// 919def MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; } 920def addr_offset_none : Operand<i32>, 921 ComplexPattern<i32, 1, "SelectAddrOffsetNone", []> { 922 let PrintMethod = "printAddrMode7Operand"; 923 let DecoderMethod = "DecodeAddrMode7Operand"; 924 let ParserMatchClass = MemNoOffsetAsmOperand; 925 let MIOperandInfo = (ops GPR:$base); 926} 927 928def nohash_imm : Operand<i32> { 929 let PrintMethod = "printNoHashImmediate"; 930} 931 932def CoprocNumAsmOperand : AsmOperandClass { 933 let Name = "CoprocNum"; 934 let ParserMethod = "parseCoprocNumOperand"; 935} 936def p_imm : Operand<i32> { 937 let PrintMethod = "printPImmediate"; 938 let ParserMatchClass = CoprocNumAsmOperand; 939 let DecoderMethod = "DecodeCoprocessor"; 940} 941 942def pf_imm : Operand<i32> { 943 let PrintMethod = "printPImmediate"; 944 let ParserMatchClass = CoprocNumAsmOperand; 945} 946 947def CoprocRegAsmOperand : AsmOperandClass { 948 let Name = "CoprocReg"; 949 let ParserMethod = "parseCoprocRegOperand"; 950} 951def c_imm : Operand<i32> { 952 let PrintMethod = "printCImmediate"; 953 let ParserMatchClass = CoprocRegAsmOperand; 954} 955def CoprocOptionAsmOperand : AsmOperandClass { 956 let Name = "CoprocOption"; 957 let ParserMethod = "parseCoprocOptionOperand"; 958} 959def coproc_option_imm : Operand<i32> { 960 let PrintMethod = "printCoprocOptionImm"; 961 let ParserMatchClass = CoprocOptionAsmOperand; 962} 963 964//===----------------------------------------------------------------------===// 965 966include "ARMInstrFormats.td" 967 968//===----------------------------------------------------------------------===// 969// Multiclass helpers... 970// 971 972/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a 973/// binop that produces a value. 974let TwoOperandAliasConstraint = "$Rn = $Rd" in 975multiclass AsI1_bin_irs<bits<4> opcod, string opc, 976 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 977 PatFrag opnode, bit Commutable = 0> { 978 // The register-immediate version is re-materializable. This is useful 979 // in particular for taking the address of a local. 980 let isReMaterializable = 1 in { 981 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, 982 iii, opc, "\t$Rd, $Rn, $imm", 983 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> { 984 bits<4> Rd; 985 bits<4> Rn; 986 bits<12> imm; 987 let Inst{25} = 1; 988 let Inst{19-16} = Rn; 989 let Inst{15-12} = Rd; 990 let Inst{11-0} = imm; 991 } 992 } 993 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 994 iir, opc, "\t$Rd, $Rn, $Rm", 995 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> { 996 bits<4> Rd; 997 bits<4> Rn; 998 bits<4> Rm; 999 let Inst{25} = 0; 1000 let isCommutable = Commutable; 1001 let Inst{19-16} = Rn; 1002 let Inst{15-12} = Rd; 1003 let Inst{11-4} = 0b00000000; 1004 let Inst{3-0} = Rm; 1005 } 1006 1007 def rsi : AsI1<opcod, (outs GPR:$Rd), 1008 (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, 1009 iis, opc, "\t$Rd, $Rn, $shift", 1010 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]> { 1011 bits<4> Rd; 1012 bits<4> Rn; 1013 bits<12> shift; 1014 let Inst{25} = 0; 1015 let Inst{19-16} = Rn; 1016 let Inst{15-12} = Rd; 1017 let Inst{11-5} = shift{11-5}; 1018 let Inst{4} = 0; 1019 let Inst{3-0} = shift{3-0}; 1020 } 1021 1022 def rsr : AsI1<opcod, (outs GPR:$Rd), 1023 (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, 1024 iis, opc, "\t$Rd, $Rn, $shift", 1025 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]> { 1026 bits<4> Rd; 1027 bits<4> Rn; 1028 bits<12> shift; 1029 let Inst{25} = 0; 1030 let Inst{19-16} = Rn; 1031 let Inst{15-12} = Rd; 1032 let Inst{11-8} = shift{11-8}; 1033 let Inst{7} = 0; 1034 let Inst{6-5} = shift{6-5}; 1035 let Inst{4} = 1; 1036 let Inst{3-0} = shift{3-0}; 1037 } 1038} 1039 1040/// AsI1_rbin_irs - Same as AsI1_bin_irs except the order of operands are 1041/// reversed. The 'rr' form is only defined for the disassembler; for codegen 1042/// it is equivalent to the AsI1_bin_irs counterpart. 1043let TwoOperandAliasConstraint = "$Rn = $Rd" in 1044multiclass AsI1_rbin_irs<bits<4> opcod, string opc, 1045 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 1046 PatFrag opnode, bit Commutable = 0> { 1047 // The register-immediate version is re-materializable. This is useful 1048 // in particular for taking the address of a local. 1049 let isReMaterializable = 1 in { 1050 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, 1051 iii, opc, "\t$Rd, $Rn, $imm", 1052 [(set GPR:$Rd, (opnode so_imm:$imm, GPR:$Rn))]> { 1053 bits<4> Rd; 1054 bits<4> Rn; 1055 bits<12> imm; 1056 let Inst{25} = 1; 1057 let Inst{19-16} = Rn; 1058 let Inst{15-12} = Rd; 1059 let Inst{11-0} = imm; 1060 } 1061 } 1062 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 1063 iir, opc, "\t$Rd, $Rn, $Rm", 1064 [/* pattern left blank */]> { 1065 bits<4> Rd; 1066 bits<4> Rn; 1067 bits<4> Rm; 1068 let Inst{11-4} = 0b00000000; 1069 let Inst{25} = 0; 1070 let Inst{3-0} = Rm; 1071 let Inst{15-12} = Rd; 1072 let Inst{19-16} = Rn; 1073 } 1074 1075 def rsi : AsI1<opcod, (outs GPR:$Rd), 1076 (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, 1077 iis, opc, "\t$Rd, $Rn, $shift", 1078 [(set GPR:$Rd, (opnode so_reg_imm:$shift, GPR:$Rn))]> { 1079 bits<4> Rd; 1080 bits<4> Rn; 1081 bits<12> shift; 1082 let Inst{25} = 0; 1083 let Inst{19-16} = Rn; 1084 let Inst{15-12} = Rd; 1085 let Inst{11-5} = shift{11-5}; 1086 let Inst{4} = 0; 1087 let Inst{3-0} = shift{3-0}; 1088 } 1089 1090 def rsr : AsI1<opcod, (outs GPR:$Rd), 1091 (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, 1092 iis, opc, "\t$Rd, $Rn, $shift", 1093 [(set GPR:$Rd, (opnode so_reg_reg:$shift, GPR:$Rn))]> { 1094 bits<4> Rd; 1095 bits<4> Rn; 1096 bits<12> shift; 1097 let Inst{25} = 0; 1098 let Inst{19-16} = Rn; 1099 let Inst{15-12} = Rd; 1100 let Inst{11-8} = shift{11-8}; 1101 let Inst{7} = 0; 1102 let Inst{6-5} = shift{6-5}; 1103 let Inst{4} = 1; 1104 let Inst{3-0} = shift{3-0}; 1105 } 1106} 1107 1108/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default. 1109/// 1110/// These opcodes will be converted to the real non-S opcodes by 1111/// AdjustInstrPostInstrSelection after giving them an optional CPSR operand. 1112let hasPostISelHook = 1, Defs = [CPSR] in { 1113multiclass AsI1_bin_s_irs<InstrItinClass iii, InstrItinClass iir, 1114 InstrItinClass iis, PatFrag opnode, 1115 bit Commutable = 0> { 1116 def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p), 1117 4, iii, 1118 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm))]>; 1119 1120 def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p), 1121 4, iir, 1122 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]> { 1123 let isCommutable = Commutable; 1124 } 1125 def rsi : ARMPseudoInst<(outs GPR:$Rd), 1126 (ins GPR:$Rn, so_reg_imm:$shift, pred:$p), 1127 4, iis, 1128 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, 1129 so_reg_imm:$shift))]>; 1130 1131 def rsr : ARMPseudoInst<(outs GPR:$Rd), 1132 (ins GPR:$Rn, so_reg_reg:$shift, pred:$p), 1133 4, iis, 1134 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, 1135 so_reg_reg:$shift))]>; 1136} 1137} 1138 1139/// AsI1_rbin_s_is - Same as AsI1_bin_s_irs, except selection DAG 1140/// operands are reversed. 1141let hasPostISelHook = 1, Defs = [CPSR] in { 1142multiclass AsI1_rbin_s_is<InstrItinClass iii, InstrItinClass iir, 1143 InstrItinClass iis, PatFrag opnode, 1144 bit Commutable = 0> { 1145 def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p), 1146 4, iii, 1147 [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn))]>; 1148 1149 def rsi : ARMPseudoInst<(outs GPR:$Rd), 1150 (ins GPR:$Rn, so_reg_imm:$shift, pred:$p), 1151 4, iis, 1152 [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, 1153 GPR:$Rn))]>; 1154 1155 def rsr : ARMPseudoInst<(outs GPR:$Rd), 1156 (ins GPR:$Rn, so_reg_reg:$shift, pred:$p), 1157 4, iis, 1158 [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, 1159 GPR:$Rn))]>; 1160} 1161} 1162 1163/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 1164/// patterns. Similar to AsI1_bin_irs except the instruction does not produce 1165/// a explicit result, only implicitly set CPSR. 1166let isCompare = 1, Defs = [CPSR] in { 1167multiclass AI1_cmp_irs<bits<4> opcod, string opc, 1168 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 1169 PatFrag opnode, bit Commutable = 0> { 1170 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii, 1171 opc, "\t$Rn, $imm", 1172 [(opnode GPR:$Rn, so_imm:$imm)]> { 1173 bits<4> Rn; 1174 bits<12> imm; 1175 let Inst{25} = 1; 1176 let Inst{20} = 1; 1177 let Inst{19-16} = Rn; 1178 let Inst{15-12} = 0b0000; 1179 let Inst{11-0} = imm; 1180 1181 let Unpredictable{15-12} = 0b1111; 1182 } 1183 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir, 1184 opc, "\t$Rn, $Rm", 1185 [(opnode GPR:$Rn, GPR:$Rm)]> { 1186 bits<4> Rn; 1187 bits<4> Rm; 1188 let isCommutable = Commutable; 1189 let Inst{25} = 0; 1190 let Inst{20} = 1; 1191 let Inst{19-16} = Rn; 1192 let Inst{15-12} = 0b0000; 1193 let Inst{11-4} = 0b00000000; 1194 let Inst{3-0} = Rm; 1195 1196 let Unpredictable{15-12} = 0b1111; 1197 } 1198 def rsi : AI1<opcod, (outs), 1199 (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, iis, 1200 opc, "\t$Rn, $shift", 1201 [(opnode GPR:$Rn, so_reg_imm:$shift)]> { 1202 bits<4> Rn; 1203 bits<12> shift; 1204 let Inst{25} = 0; 1205 let Inst{20} = 1; 1206 let Inst{19-16} = Rn; 1207 let Inst{15-12} = 0b0000; 1208 let Inst{11-5} = shift{11-5}; 1209 let Inst{4} = 0; 1210 let Inst{3-0} = shift{3-0}; 1211 1212 let Unpredictable{15-12} = 0b1111; 1213 } 1214 def rsr : AI1<opcod, (outs), 1215 (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis, 1216 opc, "\t$Rn, $shift", 1217 [(opnode GPRnopc:$Rn, so_reg_reg:$shift)]> { 1218 bits<4> Rn; 1219 bits<12> shift; 1220 let Inst{25} = 0; 1221 let Inst{20} = 1; 1222 let Inst{19-16} = Rn; 1223 let Inst{15-12} = 0b0000; 1224 let Inst{11-8} = shift{11-8}; 1225 let Inst{7} = 0; 1226 let Inst{6-5} = shift{6-5}; 1227 let Inst{4} = 1; 1228 let Inst{3-0} = shift{3-0}; 1229 1230 let Unpredictable{15-12} = 0b1111; 1231 } 1232 1233} 1234} 1235 1236/// AI_ext_rrot - A unary operation with two forms: one whose operand is a 1237/// register and one whose operand is a register rotated by 8/16/24. 1238/// FIXME: Remove the 'r' variant. Its rot_imm is zero. 1239class AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> 1240 : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot), 1241 IIC_iEXTr, opc, "\t$Rd, $Rm$rot", 1242 [(set GPRnopc:$Rd, (opnode (rotr GPRnopc:$Rm, rot_imm:$rot)))]>, 1243 Requires<[IsARM, HasV6]> { 1244 bits<4> Rd; 1245 bits<4> Rm; 1246 bits<2> rot; 1247 let Inst{19-16} = 0b1111; 1248 let Inst{15-12} = Rd; 1249 let Inst{11-10} = rot; 1250 let Inst{3-0} = Rm; 1251} 1252 1253class AI_ext_rrot_np<bits<8> opcod, string opc> 1254 : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot), 1255 IIC_iEXTr, opc, "\t$Rd, $Rm$rot", []>, 1256 Requires<[IsARM, HasV6]> { 1257 bits<2> rot; 1258 let Inst{19-16} = 0b1111; 1259 let Inst{11-10} = rot; 1260} 1261 1262/// AI_exta_rrot - A binary operation with two forms: one whose operand is a 1263/// register and one whose operand is a register rotated by 8/16/24. 1264class AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> 1265 : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot), 1266 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", 1267 [(set GPRnopc:$Rd, (opnode GPR:$Rn, 1268 (rotr GPRnopc:$Rm, rot_imm:$rot)))]>, 1269 Requires<[IsARM, HasV6]> { 1270 bits<4> Rd; 1271 bits<4> Rm; 1272 bits<4> Rn; 1273 bits<2> rot; 1274 let Inst{19-16} = Rn; 1275 let Inst{15-12} = Rd; 1276 let Inst{11-10} = rot; 1277 let Inst{9-4} = 0b000111; 1278 let Inst{3-0} = Rm; 1279} 1280 1281class AI_exta_rrot_np<bits<8> opcod, string opc> 1282 : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot), 1283 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", []>, 1284 Requires<[IsARM, HasV6]> { 1285 bits<4> Rn; 1286 bits<2> rot; 1287 let Inst{19-16} = Rn; 1288 let Inst{11-10} = rot; 1289} 1290 1291/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. 1292let TwoOperandAliasConstraint = "$Rn = $Rd" in 1293multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 1294 bit Commutable = 0> { 1295 let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { 1296 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 1297 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 1298 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm, CPSR))]>, 1299 Requires<[IsARM]> { 1300 bits<4> Rd; 1301 bits<4> Rn; 1302 bits<12> imm; 1303 let Inst{25} = 1; 1304 let Inst{15-12} = Rd; 1305 let Inst{19-16} = Rn; 1306 let Inst{11-0} = imm; 1307 } 1308 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 1309 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm", 1310 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm, CPSR))]>, 1311 Requires<[IsARM]> { 1312 bits<4> Rd; 1313 bits<4> Rn; 1314 bits<4> Rm; 1315 let Inst{11-4} = 0b00000000; 1316 let Inst{25} = 0; 1317 let isCommutable = Commutable; 1318 let Inst{3-0} = Rm; 1319 let Inst{15-12} = Rd; 1320 let Inst{19-16} = Rn; 1321 } 1322 def rsi : AsI1<opcod, (outs GPR:$Rd), 1323 (ins GPR:$Rn, so_reg_imm:$shift), 1324 DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 1325 [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_imm:$shift, CPSR))]>, 1326 Requires<[IsARM]> { 1327 bits<4> Rd; 1328 bits<4> Rn; 1329 bits<12> shift; 1330 let Inst{25} = 0; 1331 let Inst{19-16} = Rn; 1332 let Inst{15-12} = Rd; 1333 let Inst{11-5} = shift{11-5}; 1334 let Inst{4} = 0; 1335 let Inst{3-0} = shift{3-0}; 1336 } 1337 def rsr : AsI1<opcod, (outs GPRnopc:$Rd), 1338 (ins GPRnopc:$Rn, so_reg_reg:$shift), 1339 DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 1340 [(set GPRnopc:$Rd, CPSR, 1341 (opnode GPRnopc:$Rn, so_reg_reg:$shift, CPSR))]>, 1342 Requires<[IsARM]> { 1343 bits<4> Rd; 1344 bits<4> Rn; 1345 bits<12> shift; 1346 let Inst{25} = 0; 1347 let Inst{19-16} = Rn; 1348 let Inst{15-12} = Rd; 1349 let Inst{11-8} = shift{11-8}; 1350 let Inst{7} = 0; 1351 let Inst{6-5} = shift{6-5}; 1352 let Inst{4} = 1; 1353 let Inst{3-0} = shift{3-0}; 1354 } 1355 } 1356} 1357 1358/// AI1_rsc_irs - Define instructions and patterns for rsc 1359let TwoOperandAliasConstraint = "$Rn = $Rd" in 1360multiclass AI1_rsc_irs<bits<4> opcod, string opc, PatFrag opnode> { 1361 let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { 1362 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 1363 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 1364 [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn, CPSR))]>, 1365 Requires<[IsARM]> { 1366 bits<4> Rd; 1367 bits<4> Rn; 1368 bits<12> imm; 1369 let Inst{25} = 1; 1370 let Inst{15-12} = Rd; 1371 let Inst{19-16} = Rn; 1372 let Inst{11-0} = imm; 1373 } 1374 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 1375 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm", 1376 [/* pattern left blank */]> { 1377 bits<4> Rd; 1378 bits<4> Rn; 1379 bits<4> Rm; 1380 let Inst{11-4} = 0b00000000; 1381 let Inst{25} = 0; 1382 let Inst{3-0} = Rm; 1383 let Inst{15-12} = Rd; 1384 let Inst{19-16} = Rn; 1385 } 1386 def rsi : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift), 1387 DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 1388 [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, GPR:$Rn, CPSR))]>, 1389 Requires<[IsARM]> { 1390 bits<4> Rd; 1391 bits<4> Rn; 1392 bits<12> shift; 1393 let Inst{25} = 0; 1394 let Inst{19-16} = Rn; 1395 let Inst{15-12} = Rd; 1396 let Inst{11-5} = shift{11-5}; 1397 let Inst{4} = 0; 1398 let Inst{3-0} = shift{3-0}; 1399 } 1400 def rsr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift), 1401 DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 1402 [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, GPR:$Rn, CPSR))]>, 1403 Requires<[IsARM]> { 1404 bits<4> Rd; 1405 bits<4> Rn; 1406 bits<12> shift; 1407 let Inst{25} = 0; 1408 let Inst{19-16} = Rn; 1409 let Inst{15-12} = Rd; 1410 let Inst{11-8} = shift{11-8}; 1411 let Inst{7} = 0; 1412 let Inst{6-5} = shift{6-5}; 1413 let Inst{4} = 1; 1414 let Inst{3-0} = shift{3-0}; 1415 } 1416 } 1417} 1418 1419let canFoldAsLoad = 1, isReMaterializable = 1 in { 1420multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii, 1421 InstrItinClass iir, PatFrag opnode> { 1422 // Note: We use the complex addrmode_imm12 rather than just an input 1423 // GPR and a constrained immediate so that we can use this to match 1424 // frame index references and avoid matching constant pool references. 1425 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr), 1426 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", 1427 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> { 1428 bits<4> Rt; 1429 bits<17> addr; 1430 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1431 let Inst{19-16} = addr{16-13}; // Rn 1432 let Inst{15-12} = Rt; 1433 let Inst{11-0} = addr{11-0}; // imm12 1434 } 1435 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift), 1436 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", 1437 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> { 1438 bits<4> Rt; 1439 bits<17> shift; 1440 let shift{4} = 0; // Inst{4} = 0 1441 let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1442 let Inst{19-16} = shift{16-13}; // Rn 1443 let Inst{15-12} = Rt; 1444 let Inst{11-0} = shift{11-0}; 1445 } 1446} 1447} 1448 1449let canFoldAsLoad = 1, isReMaterializable = 1 in { 1450multiclass AI_ldr1nopc<bit isByte, string opc, InstrItinClass iii, 1451 InstrItinClass iir, PatFrag opnode> { 1452 // Note: We use the complex addrmode_imm12 rather than just an input 1453 // GPR and a constrained immediate so that we can use this to match 1454 // frame index references and avoid matching constant pool references. 1455 def i12: AI2ldst<0b010, 1, isByte, (outs GPRnopc:$Rt), 1456 (ins addrmode_imm12:$addr), 1457 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", 1458 [(set GPRnopc:$Rt, (opnode addrmode_imm12:$addr))]> { 1459 bits<4> Rt; 1460 bits<17> addr; 1461 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1462 let Inst{19-16} = addr{16-13}; // Rn 1463 let Inst{15-12} = Rt; 1464 let Inst{11-0} = addr{11-0}; // imm12 1465 } 1466 def rs : AI2ldst<0b011, 1, isByte, (outs GPRnopc:$Rt), 1467 (ins ldst_so_reg:$shift), 1468 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", 1469 [(set GPRnopc:$Rt, (opnode ldst_so_reg:$shift))]> { 1470 bits<4> Rt; 1471 bits<17> shift; 1472 let shift{4} = 0; // Inst{4} = 0 1473 let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1474 let Inst{19-16} = shift{16-13}; // Rn 1475 let Inst{15-12} = Rt; 1476 let Inst{11-0} = shift{11-0}; 1477 } 1478} 1479} 1480 1481 1482multiclass AI_str1<bit isByte, string opc, InstrItinClass iii, 1483 InstrItinClass iir, PatFrag opnode> { 1484 // Note: We use the complex addrmode_imm12 rather than just an input 1485 // GPR and a constrained immediate so that we can use this to match 1486 // frame index references and avoid matching constant pool references. 1487 def i12 : AI2ldst<0b010, 0, isByte, (outs), 1488 (ins GPR:$Rt, addrmode_imm12:$addr), 1489 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", 1490 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> { 1491 bits<4> Rt; 1492 bits<17> addr; 1493 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1494 let Inst{19-16} = addr{16-13}; // Rn 1495 let Inst{15-12} = Rt; 1496 let Inst{11-0} = addr{11-0}; // imm12 1497 } 1498 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift), 1499 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", 1500 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> { 1501 bits<4> Rt; 1502 bits<17> shift; 1503 let shift{4} = 0; // Inst{4} = 0 1504 let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1505 let Inst{19-16} = shift{16-13}; // Rn 1506 let Inst{15-12} = Rt; 1507 let Inst{11-0} = shift{11-0}; 1508 } 1509} 1510 1511multiclass AI_str1nopc<bit isByte, string opc, InstrItinClass iii, 1512 InstrItinClass iir, PatFrag opnode> { 1513 // Note: We use the complex addrmode_imm12 rather than just an input 1514 // GPR and a constrained immediate so that we can use this to match 1515 // frame index references and avoid matching constant pool references. 1516 def i12 : AI2ldst<0b010, 0, isByte, (outs), 1517 (ins GPRnopc:$Rt, addrmode_imm12:$addr), 1518 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", 1519 [(opnode GPRnopc:$Rt, addrmode_imm12:$addr)]> { 1520 bits<4> Rt; 1521 bits<17> addr; 1522 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1523 let Inst{19-16} = addr{16-13}; // Rn 1524 let Inst{15-12} = Rt; 1525 let Inst{11-0} = addr{11-0}; // imm12 1526 } 1527 def rs : AI2ldst<0b011, 0, isByte, (outs), 1528 (ins GPRnopc:$Rt, ldst_so_reg:$shift), 1529 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", 1530 [(opnode GPRnopc:$Rt, ldst_so_reg:$shift)]> { 1531 bits<4> Rt; 1532 bits<17> shift; 1533 let shift{4} = 0; // Inst{4} = 0 1534 let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1535 let Inst{19-16} = shift{16-13}; // Rn 1536 let Inst{15-12} = Rt; 1537 let Inst{11-0} = shift{11-0}; 1538 } 1539} 1540 1541 1542//===----------------------------------------------------------------------===// 1543// Instructions 1544//===----------------------------------------------------------------------===// 1545 1546//===----------------------------------------------------------------------===// 1547// Miscellaneous Instructions. 1548// 1549 1550/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in 1551/// the function. The first operand is the ID# for this instruction, the second 1552/// is the index into the MachineConstantPool that this is, the third is the 1553/// size in bytes of this constant pool entry. 1554let neverHasSideEffects = 1, isNotDuplicable = 1 in 1555def CONSTPOOL_ENTRY : 1556PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 1557 i32imm:$size), NoItinerary, []>; 1558 1559// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE 1560// from removing one half of the matched pairs. That breaks PEI, which assumes 1561// these will always be in pairs, and asserts if it finds otherwise. Better way? 1562let Defs = [SP], Uses = [SP], hasSideEffects = 1 in { 1563def ADJCALLSTACKUP : 1564PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, 1565 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; 1566 1567def ADJCALLSTACKDOWN : 1568PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, 1569 [(ARMcallseq_start timm:$amt)]>; 1570} 1571 1572// Atomic pseudo-insts which will be lowered to ldrexd/strexd loops. 1573// (These pseudos use a hand-written selection code). 1574let usesCustomInserter = 1, Defs = [CPSR], mayLoad = 1, mayStore = 1 in { 1575def ATOMOR6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), 1576 (ins GPR:$addr, GPR:$src1, GPR:$src2), 1577 NoItinerary, []>; 1578def ATOMXOR6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), 1579 (ins GPR:$addr, GPR:$src1, GPR:$src2), 1580 NoItinerary, []>; 1581def ATOMADD6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), 1582 (ins GPR:$addr, GPR:$src1, GPR:$src2), 1583 NoItinerary, []>; 1584def ATOMSUB6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), 1585 (ins GPR:$addr, GPR:$src1, GPR:$src2), 1586 NoItinerary, []>; 1587def ATOMNAND6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), 1588 (ins GPR:$addr, GPR:$src1, GPR:$src2), 1589 NoItinerary, []>; 1590def ATOMAND6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), 1591 (ins GPR:$addr, GPR:$src1, GPR:$src2), 1592 NoItinerary, []>; 1593def ATOMSWAP6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), 1594 (ins GPR:$addr, GPR:$src1, GPR:$src2), 1595 NoItinerary, []>; 1596def ATOMCMPXCHG6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), 1597 (ins GPR:$addr, GPR:$cmp1, GPR:$cmp2, 1598 GPR:$set1, GPR:$set2), 1599 NoItinerary, []>; 1600} 1601 1602def HINT : AI<(outs), (ins imm0_255:$imm), MiscFrm, NoItinerary, 1603 "hint", "\t$imm", []>, Requires<[IsARM, HasV6]> { 1604 bits<8> imm; 1605 let Inst{27-8} = 0b00110010000011110000; 1606 let Inst{7-0} = imm; 1607} 1608 1609def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1610def : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1611def : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1612def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1613def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1614 1615def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel", 1616 "\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> { 1617 bits<4> Rd; 1618 bits<4> Rn; 1619 bits<4> Rm; 1620 let Inst{3-0} = Rm; 1621 let Inst{15-12} = Rd; 1622 let Inst{19-16} = Rn; 1623 let Inst{27-20} = 0b01101000; 1624 let Inst{7-4} = 0b1011; 1625 let Inst{11-8} = 0b1111; 1626 let Unpredictable{11-8} = 0b1111; 1627} 1628 1629// The 16-bit operand $val can be used by a debugger to store more information 1630// about the breakpoint. 1631def BKPT : AI<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary, 1632 "bkpt", "\t$val", []>, Requires<[IsARM]> { 1633 bits<16> val; 1634 let Inst{3-0} = val{3-0}; 1635 let Inst{19-8} = val{15-4}; 1636 let Inst{27-20} = 0b00010010; 1637 let Inst{7-4} = 0b0111; 1638} 1639 1640// Change Processor State 1641// FIXME: We should use InstAlias to handle the optional operands. 1642class CPS<dag iops, string asm_ops> 1643 : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops), 1644 []>, Requires<[IsARM]> { 1645 bits<2> imod; 1646 bits<3> iflags; 1647 bits<5> mode; 1648 bit M; 1649 1650 let Inst{31-28} = 0b1111; 1651 let Inst{27-20} = 0b00010000; 1652 let Inst{19-18} = imod; 1653 let Inst{17} = M; // Enabled if mode is set; 1654 let Inst{16-9} = 0b00000000; 1655 let Inst{8-6} = iflags; 1656 let Inst{5} = 0; 1657 let Inst{4-0} = mode; 1658} 1659 1660let DecoderMethod = "DecodeCPSInstruction" in { 1661let M = 1 in 1662 def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, imm0_31:$mode), 1663 "$imod\t$iflags, $mode">; 1664let mode = 0, M = 0 in 1665 def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">; 1666 1667let imod = 0, iflags = 0, M = 1 in 1668 def CPS1p : CPS<(ins imm0_31:$mode), "\t$mode">; 1669} 1670 1671// Preload signals the memory system of possible future data/instruction access. 1672multiclass APreLoad<bits<1> read, bits<1> data, string opc> { 1673 1674 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload, 1675 !strconcat(opc, "\t$addr"), 1676 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> { 1677 bits<4> Rt; 1678 bits<17> addr; 1679 let Inst{31-26} = 0b111101; 1680 let Inst{25} = 0; // 0 for immediate form 1681 let Inst{24} = data; 1682 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1683 let Inst{22} = read; 1684 let Inst{21-20} = 0b01; 1685 let Inst{19-16} = addr{16-13}; // Rn 1686 let Inst{15-12} = 0b1111; 1687 let Inst{11-0} = addr{11-0}; // imm12 1688 } 1689 1690 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload, 1691 !strconcat(opc, "\t$shift"), 1692 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> { 1693 bits<17> shift; 1694 let Inst{31-26} = 0b111101; 1695 let Inst{25} = 1; // 1 for register form 1696 let Inst{24} = data; 1697 let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1698 let Inst{22} = read; 1699 let Inst{21-20} = 0b01; 1700 let Inst{19-16} = shift{16-13}; // Rn 1701 let Inst{15-12} = 0b1111; 1702 let Inst{11-0} = shift{11-0}; 1703 let Inst{4} = 0; 1704 } 1705} 1706 1707defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>; 1708defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>; 1709defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>; 1710 1711def SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary, 1712 "setend\t$end", []>, Requires<[IsARM]> { 1713 bits<1> end; 1714 let Inst{31-10} = 0b1111000100000001000000; 1715 let Inst{9} = end; 1716 let Inst{8-0} = 0; 1717} 1718 1719def DBG : AI<(outs), (ins imm0_15:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt", 1720 []>, Requires<[IsARM, HasV7]> { 1721 bits<4> opt; 1722 let Inst{27-4} = 0b001100100000111100001111; 1723 let Inst{3-0} = opt; 1724} 1725 1726// A5.4 Permanently UNDEFINED instructions. 1727let isBarrier = 1, isTerminator = 1 in 1728def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary, 1729 "trap", [(trap)]>, 1730 Requires<[IsARM]> { 1731 let Inst = 0xe7ffdefe; 1732} 1733 1734// Address computation and loads and stores in PIC mode. 1735let isNotDuplicable = 1 in { 1736def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p), 1737 4, IIC_iALUr, 1738 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>; 1739 1740let AddedComplexity = 10 in { 1741def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 1742 4, IIC_iLoad_r, 1743 [(set GPR:$dst, (load addrmodepc:$addr))]>; 1744 1745def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1746 4, IIC_iLoad_bh_r, 1747 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>; 1748 1749def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1750 4, IIC_iLoad_bh_r, 1751 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>; 1752 1753def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1754 4, IIC_iLoad_bh_r, 1755 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>; 1756 1757def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1758 4, IIC_iLoad_bh_r, 1759 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>; 1760} 1761let AddedComplexity = 10 in { 1762def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1763 4, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>; 1764 1765def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1766 4, IIC_iStore_bh_r, [(truncstorei16 GPR:$src, 1767 addrmodepc:$addr)]>; 1768 1769def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1770 4, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; 1771} 1772} // isNotDuplicable = 1 1773 1774 1775// LEApcrel - Load a pc-relative address into a register without offending the 1776// assembler. 1777let neverHasSideEffects = 1, isReMaterializable = 1 in 1778// The 'adr' mnemonic encodes differently if the label is before or after 1779// the instruction. The {24-21} opcode bits are set by the fixup, as we don't 1780// know until then which form of the instruction will be used. 1781def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label), 1782 MiscFrm, IIC_iALUi, "adr", "\t$Rd, $label", []> { 1783 bits<4> Rd; 1784 bits<14> label; 1785 let Inst{27-25} = 0b001; 1786 let Inst{24} = 0; 1787 let Inst{23-22} = label{13-12}; 1788 let Inst{21} = 0; 1789 let Inst{20} = 0; 1790 let Inst{19-16} = 0b1111; 1791 let Inst{15-12} = Rd; 1792 let Inst{11-0} = label{11-0}; 1793} 1794def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p), 1795 4, IIC_iALUi, []>; 1796 1797def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd), 1798 (ins i32imm:$label, nohash_imm:$id, pred:$p), 1799 4, IIC_iALUi, []>; 1800 1801//===----------------------------------------------------------------------===// 1802// Control Flow Instructions. 1803// 1804 1805let isReturn = 1, isTerminator = 1, isBarrier = 1 in { 1806 // ARMV4T and above 1807 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 1808 "bx", "\tlr", [(ARMretflag)]>, 1809 Requires<[IsARM, HasV4T]> { 1810 let Inst{27-0} = 0b0001001011111111111100011110; 1811 } 1812 1813 // ARMV4 only 1814 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br, 1815 "mov", "\tpc, lr", [(ARMretflag)]>, 1816 Requires<[IsARM, NoV4T]> { 1817 let Inst{27-0} = 0b0001101000001111000000001110; 1818 } 1819} 1820 1821// Indirect branches 1822let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 1823 // ARMV4T and above 1824 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", 1825 [(brind GPR:$dst)]>, 1826 Requires<[IsARM, HasV4T]> { 1827 bits<4> dst; 1828 let Inst{31-4} = 0b1110000100101111111111110001; 1829 let Inst{3-0} = dst; 1830 } 1831 1832 def BX_pred : AI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, 1833 "bx", "\t$dst", [/* pattern left blank */]>, 1834 Requires<[IsARM, HasV4T]> { 1835 bits<4> dst; 1836 let Inst{27-4} = 0b000100101111111111110001; 1837 let Inst{3-0} = dst; 1838 } 1839} 1840 1841// SP is marked as a use to prevent stack-pointer assignments that appear 1842// immediately before calls from potentially appearing dead. 1843let isCall = 1, 1844 // FIXME: Do we really need a non-predicated version? If so, it should 1845 // at least be a pseudo instruction expanding to the predicated version 1846 // at MC lowering time. 1847 Defs = [LR], Uses = [SP] in { 1848 def BL : ABXI<0b1011, (outs), (ins bl_target:$func), 1849 IIC_Br, "bl\t$func", 1850 [(ARMcall tglobaladdr:$func)]>, 1851 Requires<[IsARM]> { 1852 let Inst{31-28} = 0b1110; 1853 bits<24> func; 1854 let Inst{23-0} = func; 1855 let DecoderMethod = "DecodeBranchImmInstruction"; 1856 } 1857 1858 def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func), 1859 IIC_Br, "bl", "\t$func", 1860 [(ARMcall_pred tglobaladdr:$func)]>, 1861 Requires<[IsARM]> { 1862 bits<24> func; 1863 let Inst{23-0} = func; 1864 let DecoderMethod = "DecodeBranchImmInstruction"; 1865 } 1866 1867 // ARMv5T and above 1868 def BLX : AXI<(outs), (ins GPR:$func), BrMiscFrm, 1869 IIC_Br, "blx\t$func", 1870 [(ARMcall GPR:$func)]>, 1871 Requires<[IsARM, HasV5T]> { 1872 bits<4> func; 1873 let Inst{31-4} = 0b1110000100101111111111110011; 1874 let Inst{3-0} = func; 1875 } 1876 1877 def BLX_pred : AI<(outs), (ins GPR:$func), BrMiscFrm, 1878 IIC_Br, "blx", "\t$func", 1879 [(ARMcall_pred GPR:$func)]>, 1880 Requires<[IsARM, HasV5T]> { 1881 bits<4> func; 1882 let Inst{27-4} = 0b000100101111111111110011; 1883 let Inst{3-0} = func; 1884 } 1885 1886 // ARMv4T 1887 // Note: Restrict $func to the tGPR regclass to prevent it being in LR. 1888 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func), 1889 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 1890 Requires<[IsARM, HasV4T]>; 1891 1892 // ARMv4 1893 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func), 1894 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 1895 Requires<[IsARM, NoV4T]>; 1896 1897 // mov lr, pc; b if callee is marked noreturn to avoid confusing the 1898 // return stack predictor. 1899 def BMOVPCB_CALL : ARMPseudoInst<(outs), (ins bl_target:$func), 1900 8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>, 1901 Requires<[IsARM]>; 1902} 1903 1904let isBranch = 1, isTerminator = 1 in { 1905 // FIXME: should be able to write a pattern for ARMBrcond, but can't use 1906 // a two-value operand where a dag node expects two operands. :( 1907 def Bcc : ABI<0b1010, (outs), (ins br_target:$target), 1908 IIC_Br, "b", "\t$target", 1909 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> { 1910 bits<24> target; 1911 let Inst{23-0} = target; 1912 let DecoderMethod = "DecodeBranchImmInstruction"; 1913 } 1914 1915 let isBarrier = 1 in { 1916 // B is "predicable" since it's just a Bcc with an 'always' condition. 1917 let isPredicable = 1 in 1918 // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly 1919 // should be sufficient. 1920 // FIXME: Is B really a Barrier? That doesn't seem right. 1921 def B : ARMPseudoExpand<(outs), (ins br_target:$target), 4, IIC_Br, 1922 [(br bb:$target)], (Bcc br_target:$target, (ops 14, zero_reg))>; 1923 1924 let isNotDuplicable = 1, isIndirectBranch = 1 in { 1925 def BR_JTr : ARMPseudoInst<(outs), 1926 (ins GPR:$target, i32imm:$jt, i32imm:$id), 1927 0, IIC_Br, 1928 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>; 1929 // FIXME: This shouldn't use the generic "addrmode2," but rather be split 1930 // into i12 and rs suffixed versions. 1931 def BR_JTm : ARMPseudoInst<(outs), 1932 (ins addrmode2:$target, i32imm:$jt, i32imm:$id), 1933 0, IIC_Br, 1934 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt, 1935 imm:$id)]>; 1936 def BR_JTadd : ARMPseudoInst<(outs), 1937 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id), 1938 0, IIC_Br, 1939 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, 1940 imm:$id)]>; 1941 } // isNotDuplicable = 1, isIndirectBranch = 1 1942 } // isBarrier = 1 1943 1944} 1945 1946// BLX (immediate) 1947def BLXi : AXI<(outs), (ins blx_target:$target), BrMiscFrm, NoItinerary, 1948 "blx\t$target", []>, 1949 Requires<[IsARM, HasV5T]> { 1950 let Inst{31-25} = 0b1111101; 1951 bits<25> target; 1952 let Inst{23-0} = target{24-1}; 1953 let Inst{24} = target{0}; 1954} 1955 1956// Branch and Exchange Jazelle 1957def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func", 1958 [/* pattern left blank */]> { 1959 bits<4> func; 1960 let Inst{23-20} = 0b0010; 1961 let Inst{19-8} = 0xfff; 1962 let Inst{7-4} = 0b0010; 1963 let Inst{3-0} = func; 1964} 1965 1966// Tail calls. 1967 1968let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in { 1969 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst), IIC_Br, []>; 1970 1971 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst), IIC_Br, []>; 1972 1973 def TAILJMPd : ARMPseudoExpand<(outs), (ins br_target:$dst), 1974 4, IIC_Br, [], 1975 (Bcc br_target:$dst, (ops 14, zero_reg))>, 1976 Requires<[IsARM]>; 1977 1978 def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst), 1979 4, IIC_Br, [], 1980 (BX GPR:$dst)>, 1981 Requires<[IsARM]>; 1982} 1983 1984// Secure Monitor Call is a system instruction. 1985def SMC : ABI<0b0001, (outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt", 1986 []> { 1987 bits<4> opt; 1988 let Inst{23-4} = 0b01100000000000000111; 1989 let Inst{3-0} = opt; 1990} 1991 1992// Supervisor Call (Software Interrupt) 1993let isCall = 1, Uses = [SP] in { 1994def SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []> { 1995 bits<24> svc; 1996 let Inst{23-0} = svc; 1997} 1998} 1999 2000// Store Return State 2001class SRSI<bit wb, string asm> 2002 : XI<(outs), (ins imm0_31:$mode), AddrModeNone, 4, IndexModeNone, BrFrm, 2003 NoItinerary, asm, "", []> { 2004 bits<5> mode; 2005 let Inst{31-28} = 0b1111; 2006 let Inst{27-25} = 0b100; 2007 let Inst{22} = 1; 2008 let Inst{21} = wb; 2009 let Inst{20} = 0; 2010 let Inst{19-16} = 0b1101; // SP 2011 let Inst{15-5} = 0b00000101000; 2012 let Inst{4-0} = mode; 2013} 2014 2015def SRSDA : SRSI<0, "srsda\tsp, $mode"> { 2016 let Inst{24-23} = 0; 2017} 2018def SRSDA_UPD : SRSI<1, "srsda\tsp!, $mode"> { 2019 let Inst{24-23} = 0; 2020} 2021def SRSDB : SRSI<0, "srsdb\tsp, $mode"> { 2022 let Inst{24-23} = 0b10; 2023} 2024def SRSDB_UPD : SRSI<1, "srsdb\tsp!, $mode"> { 2025 let Inst{24-23} = 0b10; 2026} 2027def SRSIA : SRSI<0, "srsia\tsp, $mode"> { 2028 let Inst{24-23} = 0b01; 2029} 2030def SRSIA_UPD : SRSI<1, "srsia\tsp!, $mode"> { 2031 let Inst{24-23} = 0b01; 2032} 2033def SRSIB : SRSI<0, "srsib\tsp, $mode"> { 2034 let Inst{24-23} = 0b11; 2035} 2036def SRSIB_UPD : SRSI<1, "srsib\tsp!, $mode"> { 2037 let Inst{24-23} = 0b11; 2038} 2039 2040// Return From Exception 2041class RFEI<bit wb, string asm> 2042 : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm, 2043 NoItinerary, asm, "", []> { 2044 bits<4> Rn; 2045 let Inst{31-28} = 0b1111; 2046 let Inst{27-25} = 0b100; 2047 let Inst{22} = 0; 2048 let Inst{21} = wb; 2049 let Inst{20} = 1; 2050 let Inst{19-16} = Rn; 2051 let Inst{15-0} = 0xa00; 2052} 2053 2054def RFEDA : RFEI<0, "rfeda\t$Rn"> { 2055 let Inst{24-23} = 0; 2056} 2057def RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> { 2058 let Inst{24-23} = 0; 2059} 2060def RFEDB : RFEI<0, "rfedb\t$Rn"> { 2061 let Inst{24-23} = 0b10; 2062} 2063def RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> { 2064 let Inst{24-23} = 0b10; 2065} 2066def RFEIA : RFEI<0, "rfeia\t$Rn"> { 2067 let Inst{24-23} = 0b01; 2068} 2069def RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> { 2070 let Inst{24-23} = 0b01; 2071} 2072def RFEIB : RFEI<0, "rfeib\t$Rn"> { 2073 let Inst{24-23} = 0b11; 2074} 2075def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> { 2076 let Inst{24-23} = 0b11; 2077} 2078 2079//===----------------------------------------------------------------------===// 2080// Load / Store Instructions. 2081// 2082 2083// Load 2084 2085 2086defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si, 2087 UnOpFrag<(load node:$Src)>>; 2088defm LDRB : AI_ldr1nopc<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si, 2089 UnOpFrag<(zextloadi8 node:$Src)>>; 2090defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si, 2091 BinOpFrag<(store node:$LHS, node:$RHS)>>; 2092defm STRB : AI_str1nopc<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si, 2093 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; 2094 2095// Special LDR for loads from non-pc-relative constpools. 2096let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, 2097 isReMaterializable = 1, isCodeGenOnly = 1 in 2098def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr), 2099 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", 2100 []> { 2101 bits<4> Rt; 2102 bits<17> addr; 2103 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 2104 let Inst{19-16} = 0b1111; 2105 let Inst{15-12} = Rt; 2106 let Inst{11-0} = addr{11-0}; // imm12 2107} 2108 2109// Loads with zero extension 2110def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 2111 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr", 2112 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>; 2113 2114// Loads with sign extension 2115def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 2116 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr", 2117 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>; 2118 2119def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 2120 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr", 2121 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>; 2122 2123let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 2124// Load doubleword 2125def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2), 2126 (ins addrmode3:$addr), LdMiscFrm, 2127 IIC_iLoad_d_r, "ldrd", "\t$Rd, $dst2, $addr", 2128 []>, Requires<[IsARM, HasV5TE]>; 2129} 2130 2131// Indexed loads 2132multiclass AI2_ldridx<bit isByte, string opc, 2133 InstrItinClass iii, InstrItinClass iir> { 2134 def _PRE_IMM : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), 2135 (ins addrmode_imm12:$addr), IndexModePre, LdFrm, iii, 2136 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2137 bits<17> addr; 2138 let Inst{25} = 0; 2139 let Inst{23} = addr{12}; 2140 let Inst{19-16} = addr{16-13}; 2141 let Inst{11-0} = addr{11-0}; 2142 let DecoderMethod = "DecodeLDRPreImm"; 2143 let AsmMatchConverter = "cvtLdWriteBackRegAddrModeImm12"; 2144 } 2145 2146 def _PRE_REG : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), 2147 (ins ldst_so_reg:$addr), IndexModePre, LdFrm, iir, 2148 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2149 bits<17> addr; 2150 let Inst{25} = 1; 2151 let Inst{23} = addr{12}; 2152 let Inst{19-16} = addr{16-13}; 2153 let Inst{11-0} = addr{11-0}; 2154 let Inst{4} = 0; 2155 let DecoderMethod = "DecodeLDRPreReg"; 2156 let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2"; 2157 } 2158 2159 def _POST_REG : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2160 (ins addr_offset_none:$addr, am2offset_reg:$offset), 2161 IndexModePost, LdFrm, iir, 2162 opc, "\t$Rt, $addr, $offset", 2163 "$addr.base = $Rn_wb", []> { 2164 // {12} isAdd 2165 // {11-0} imm12/Rm 2166 bits<14> offset; 2167 bits<4> addr; 2168 let Inst{25} = 1; 2169 let Inst{23} = offset{12}; 2170 let Inst{19-16} = addr; 2171 let Inst{11-0} = offset{11-0}; 2172 2173 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2174 } 2175 2176 def _POST_IMM : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2177 (ins addr_offset_none:$addr, am2offset_imm:$offset), 2178 IndexModePost, LdFrm, iii, 2179 opc, "\t$Rt, $addr, $offset", 2180 "$addr.base = $Rn_wb", []> { 2181 // {12} isAdd 2182 // {11-0} imm12/Rm 2183 bits<14> offset; 2184 bits<4> addr; 2185 let Inst{25} = 0; 2186 let Inst{23} = offset{12}; 2187 let Inst{19-16} = addr; 2188 let Inst{11-0} = offset{11-0}; 2189 2190 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2191 } 2192 2193} 2194 2195let mayLoad = 1, neverHasSideEffects = 1 in { 2196// FIXME: for LDR_PRE_REG etc. the itineray should be either IIC_iLoad_ru or 2197// IIC_iLoad_siu depending on whether it the offset register is shifted. 2198defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_iu, IIC_iLoad_ru>; 2199defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_iu, IIC_iLoad_bh_ru>; 2200} 2201 2202multiclass AI3_ldridx<bits<4> op, string opc, InstrItinClass itin> { 2203 def _PRE : AI3ldstidx<op, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 2204 (ins addrmode3:$addr), IndexModePre, 2205 LdMiscFrm, itin, 2206 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2207 bits<14> addr; 2208 let Inst{23} = addr{8}; // U bit 2209 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 2210 let Inst{19-16} = addr{12-9}; // Rn 2211 let Inst{11-8} = addr{7-4}; // imm7_4/zero 2212 let Inst{3-0} = addr{3-0}; // imm3_0/Rm 2213 let AsmMatchConverter = "cvtLdWriteBackRegAddrMode3"; 2214 let DecoderMethod = "DecodeAddrMode3Instruction"; 2215 } 2216 def _POST : AI3ldstidx<op, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2217 (ins addr_offset_none:$addr, am3offset:$offset), 2218 IndexModePost, LdMiscFrm, itin, 2219 opc, "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", 2220 []> { 2221 bits<10> offset; 2222 bits<4> addr; 2223 let Inst{23} = offset{8}; // U bit 2224 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 2225 let Inst{19-16} = addr; 2226 let Inst{11-8} = offset{7-4}; // imm7_4/zero 2227 let Inst{3-0} = offset{3-0}; // imm3_0/Rm 2228 let DecoderMethod = "DecodeAddrMode3Instruction"; 2229 } 2230} 2231 2232let mayLoad = 1, neverHasSideEffects = 1 in { 2233defm LDRH : AI3_ldridx<0b1011, "ldrh", IIC_iLoad_bh_ru>; 2234defm LDRSH : AI3_ldridx<0b1111, "ldrsh", IIC_iLoad_bh_ru>; 2235defm LDRSB : AI3_ldridx<0b1101, "ldrsb", IIC_iLoad_bh_ru>; 2236let hasExtraDefRegAllocReq = 1 in { 2237def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 2238 (ins addrmode3:$addr), IndexModePre, 2239 LdMiscFrm, IIC_iLoad_d_ru, 2240 "ldrd", "\t$Rt, $Rt2, $addr!", 2241 "$addr.base = $Rn_wb", []> { 2242 bits<14> addr; 2243 let Inst{23} = addr{8}; // U bit 2244 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 2245 let Inst{19-16} = addr{12-9}; // Rn 2246 let Inst{11-8} = addr{7-4}; // imm7_4/zero 2247 let Inst{3-0} = addr{3-0}; // imm3_0/Rm 2248 let DecoderMethod = "DecodeAddrMode3Instruction"; 2249 let AsmMatchConverter = "cvtLdrdPre"; 2250} 2251def LDRD_POST: AI3ldstidx<0b1101, 0, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 2252 (ins addr_offset_none:$addr, am3offset:$offset), 2253 IndexModePost, LdMiscFrm, IIC_iLoad_d_ru, 2254 "ldrd", "\t$Rt, $Rt2, $addr, $offset", 2255 "$addr.base = $Rn_wb", []> { 2256 bits<10> offset; 2257 bits<4> addr; 2258 let Inst{23} = offset{8}; // U bit 2259 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 2260 let Inst{19-16} = addr; 2261 let Inst{11-8} = offset{7-4}; // imm7_4/zero 2262 let Inst{3-0} = offset{3-0}; // imm3_0/Rm 2263 let DecoderMethod = "DecodeAddrMode3Instruction"; 2264} 2265} // hasExtraDefRegAllocReq = 1 2266} // mayLoad = 1, neverHasSideEffects = 1 2267 2268// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT. 2269let mayLoad = 1, neverHasSideEffects = 1 in { 2270def LDRT_POST_REG : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2271 (ins addr_offset_none:$addr, am2offset_reg:$offset), 2272 IndexModePost, LdFrm, IIC_iLoad_ru, 2273 "ldrt", "\t$Rt, $addr, $offset", 2274 "$addr.base = $Rn_wb", []> { 2275 // {12} isAdd 2276 // {11-0} imm12/Rm 2277 bits<14> offset; 2278 bits<4> addr; 2279 let Inst{25} = 1; 2280 let Inst{23} = offset{12}; 2281 let Inst{21} = 1; // overwrite 2282 let Inst{19-16} = addr; 2283 let Inst{11-5} = offset{11-5}; 2284 let Inst{4} = 0; 2285 let Inst{3-0} = offset{3-0}; 2286 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2287} 2288 2289def LDRT_POST_IMM : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2290 (ins addr_offset_none:$addr, am2offset_imm:$offset), 2291 IndexModePost, LdFrm, IIC_iLoad_ru, 2292 "ldrt", "\t$Rt, $addr, $offset", 2293 "$addr.base = $Rn_wb", []> { 2294 // {12} isAdd 2295 // {11-0} imm12/Rm 2296 bits<14> offset; 2297 bits<4> addr; 2298 let Inst{25} = 0; 2299 let Inst{23} = offset{12}; 2300 let Inst{21} = 1; // overwrite 2301 let Inst{19-16} = addr; 2302 let Inst{11-0} = offset{11-0}; 2303 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2304} 2305 2306def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2307 (ins addr_offset_none:$addr, am2offset_reg:$offset), 2308 IndexModePost, LdFrm, IIC_iLoad_bh_ru, 2309 "ldrbt", "\t$Rt, $addr, $offset", 2310 "$addr.base = $Rn_wb", []> { 2311 // {12} isAdd 2312 // {11-0} imm12/Rm 2313 bits<14> offset; 2314 bits<4> addr; 2315 let Inst{25} = 1; 2316 let Inst{23} = offset{12}; 2317 let Inst{21} = 1; // overwrite 2318 let Inst{19-16} = addr; 2319 let Inst{11-5} = offset{11-5}; 2320 let Inst{4} = 0; 2321 let Inst{3-0} = offset{3-0}; 2322 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2323} 2324 2325def LDRBT_POST_IMM : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2326 (ins addr_offset_none:$addr, am2offset_imm:$offset), 2327 IndexModePost, LdFrm, IIC_iLoad_bh_ru, 2328 "ldrbt", "\t$Rt, $addr, $offset", 2329 "$addr.base = $Rn_wb", []> { 2330 // {12} isAdd 2331 // {11-0} imm12/Rm 2332 bits<14> offset; 2333 bits<4> addr; 2334 let Inst{25} = 0; 2335 let Inst{23} = offset{12}; 2336 let Inst{21} = 1; // overwrite 2337 let Inst{19-16} = addr; 2338 let Inst{11-0} = offset{11-0}; 2339 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2340} 2341 2342multiclass AI3ldrT<bits<4> op, string opc> { 2343 def i : AI3ldstidxT<op, 1, (outs GPR:$Rt, GPR:$base_wb), 2344 (ins addr_offset_none:$addr, postidx_imm8:$offset), 2345 IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc, 2346 "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> { 2347 bits<9> offset; 2348 let Inst{23} = offset{8}; 2349 let Inst{22} = 1; 2350 let Inst{11-8} = offset{7-4}; 2351 let Inst{3-0} = offset{3-0}; 2352 let AsmMatchConverter = "cvtLdExtTWriteBackImm"; 2353 } 2354 def r : AI3ldstidxT<op, 1, (outs GPRnopc:$Rt, GPRnopc:$base_wb), 2355 (ins addr_offset_none:$addr, postidx_reg:$Rm), 2356 IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc, 2357 "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> { 2358 bits<5> Rm; 2359 let Inst{23} = Rm{4}; 2360 let Inst{22} = 0; 2361 let Inst{11-8} = 0; 2362 let Unpredictable{11-8} = 0b1111; 2363 let Inst{3-0} = Rm{3-0}; 2364 let AsmMatchConverter = "cvtLdExtTWriteBackReg"; 2365 let DecoderMethod = "DecodeLDR"; 2366 } 2367} 2368 2369defm LDRSBT : AI3ldrT<0b1101, "ldrsbt">; 2370defm LDRHT : AI3ldrT<0b1011, "ldrht">; 2371defm LDRSHT : AI3ldrT<0b1111, "ldrsht">; 2372} 2373 2374// Store 2375 2376// Stores with truncate 2377def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm, 2378 IIC_iStore_bh_r, "strh", "\t$Rt, $addr", 2379 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>; 2380 2381// Store doubleword 2382let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in 2383def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr), 2384 StMiscFrm, IIC_iStore_d_r, 2385 "strd", "\t$Rt, $src2, $addr", []>, 2386 Requires<[IsARM, HasV5TE]> { 2387 let Inst{21} = 0; 2388} 2389 2390// Indexed stores 2391multiclass AI2_stridx<bit isByte, string opc, 2392 InstrItinClass iii, InstrItinClass iir> { 2393 def _PRE_IMM : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), 2394 (ins GPR:$Rt, addrmode_imm12:$addr), IndexModePre, 2395 StFrm, iii, 2396 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2397 bits<17> addr; 2398 let Inst{25} = 0; 2399 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 2400 let Inst{19-16} = addr{16-13}; // Rn 2401 let Inst{11-0} = addr{11-0}; // imm12 2402 let AsmMatchConverter = "cvtStWriteBackRegAddrModeImm12"; 2403 let DecoderMethod = "DecodeSTRPreImm"; 2404 } 2405 2406 def _PRE_REG : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), 2407 (ins GPR:$Rt, ldst_so_reg:$addr), 2408 IndexModePre, StFrm, iir, 2409 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2410 bits<17> addr; 2411 let Inst{25} = 1; 2412 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 2413 let Inst{19-16} = addr{16-13}; // Rn 2414 let Inst{11-0} = addr{11-0}; 2415 let Inst{4} = 0; // Inst{4} = 0 2416 let AsmMatchConverter = "cvtStWriteBackRegAddrMode2"; 2417 let DecoderMethod = "DecodeSTRPreReg"; 2418 } 2419 def _POST_REG : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), 2420 (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 2421 IndexModePost, StFrm, iir, 2422 opc, "\t$Rt, $addr, $offset", 2423 "$addr.base = $Rn_wb", []> { 2424 // {12} isAdd 2425 // {11-0} imm12/Rm 2426 bits<14> offset; 2427 bits<4> addr; 2428 let Inst{25} = 1; 2429 let Inst{23} = offset{12}; 2430 let Inst{19-16} = addr; 2431 let Inst{11-0} = offset{11-0}; 2432 let Inst{4} = 0; 2433 2434 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2435 } 2436 2437 def _POST_IMM : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), 2438 (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 2439 IndexModePost, StFrm, iii, 2440 opc, "\t$Rt, $addr, $offset", 2441 "$addr.base = $Rn_wb", []> { 2442 // {12} isAdd 2443 // {11-0} imm12/Rm 2444 bits<14> offset; 2445 bits<4> addr; 2446 let Inst{25} = 0; 2447 let Inst{23} = offset{12}; 2448 let Inst{19-16} = addr; 2449 let Inst{11-0} = offset{11-0}; 2450 2451 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2452 } 2453} 2454 2455let mayStore = 1, neverHasSideEffects = 1 in { 2456// FIXME: for STR_PRE_REG etc. the itineray should be either IIC_iStore_ru or 2457// IIC_iStore_siu depending on whether it the offset register is shifted. 2458defm STR : AI2_stridx<0, "str", IIC_iStore_iu, IIC_iStore_ru>; 2459defm STRB : AI2_stridx<1, "strb", IIC_iStore_bh_iu, IIC_iStore_bh_ru>; 2460} 2461 2462def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr, 2463 am2offset_reg:$offset), 2464 (STR_POST_REG GPR:$Rt, addr_offset_none:$addr, 2465 am2offset_reg:$offset)>; 2466def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr, 2467 am2offset_imm:$offset), 2468 (STR_POST_IMM GPR:$Rt, addr_offset_none:$addr, 2469 am2offset_imm:$offset)>; 2470def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr, 2471 am2offset_reg:$offset), 2472 (STRB_POST_REG GPR:$Rt, addr_offset_none:$addr, 2473 am2offset_reg:$offset)>; 2474def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr, 2475 am2offset_imm:$offset), 2476 (STRB_POST_IMM GPR:$Rt, addr_offset_none:$addr, 2477 am2offset_imm:$offset)>; 2478 2479// Pseudo-instructions for pattern matching the pre-indexed stores. We can't 2480// put the patterns on the instruction definitions directly as ISel wants 2481// the address base and offset to be separate operands, not a single 2482// complex operand like we represent the instructions themselves. The 2483// pseudos map between the two. 2484let usesCustomInserter = 1, 2485 Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in { 2486def STRi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2487 (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p), 2488 4, IIC_iStore_ru, 2489 [(set GPR:$Rn_wb, 2490 (pre_store GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>; 2491def STRr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2492 (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p), 2493 4, IIC_iStore_ru, 2494 [(set GPR:$Rn_wb, 2495 (pre_store GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; 2496def STRBi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2497 (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p), 2498 4, IIC_iStore_ru, 2499 [(set GPR:$Rn_wb, 2500 (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>; 2501def STRBr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2502 (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p), 2503 4, IIC_iStore_ru, 2504 [(set GPR:$Rn_wb, 2505 (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; 2506def STRH_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2507 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset, pred:$p), 2508 4, IIC_iStore_ru, 2509 [(set GPR:$Rn_wb, 2510 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>; 2511} 2512 2513 2514 2515def STRH_PRE : AI3ldstidx<0b1011, 0, 1, (outs GPR:$Rn_wb), 2516 (ins GPR:$Rt, addrmode3:$addr), IndexModePre, 2517 StMiscFrm, IIC_iStore_bh_ru, 2518 "strh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2519 bits<14> addr; 2520 let Inst{23} = addr{8}; // U bit 2521 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 2522 let Inst{19-16} = addr{12-9}; // Rn 2523 let Inst{11-8} = addr{7-4}; // imm7_4/zero 2524 let Inst{3-0} = addr{3-0}; // imm3_0/Rm 2525 let AsmMatchConverter = "cvtStWriteBackRegAddrMode3"; 2526 let DecoderMethod = "DecodeAddrMode3Instruction"; 2527} 2528 2529def STRH_POST : AI3ldstidx<0b1011, 0, 0, (outs GPR:$Rn_wb), 2530 (ins GPR:$Rt, addr_offset_none:$addr, am3offset:$offset), 2531 IndexModePost, StMiscFrm, IIC_iStore_bh_ru, 2532 "strh", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", 2533 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt, 2534 addr_offset_none:$addr, 2535 am3offset:$offset))]> { 2536 bits<10> offset; 2537 bits<4> addr; 2538 let Inst{23} = offset{8}; // U bit 2539 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 2540 let Inst{19-16} = addr; 2541 let Inst{11-8} = offset{7-4}; // imm7_4/zero 2542 let Inst{3-0} = offset{3-0}; // imm3_0/Rm 2543 let DecoderMethod = "DecodeAddrMode3Instruction"; 2544} 2545 2546let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { 2547def STRD_PRE : AI3ldstidx<0b1111, 0, 1, (outs GPR:$Rn_wb), 2548 (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr), 2549 IndexModePre, StMiscFrm, IIC_iStore_d_ru, 2550 "strd", "\t$Rt, $Rt2, $addr!", 2551 "$addr.base = $Rn_wb", []> { 2552 bits<14> addr; 2553 let Inst{23} = addr{8}; // U bit 2554 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 2555 let Inst{19-16} = addr{12-9}; // Rn 2556 let Inst{11-8} = addr{7-4}; // imm7_4/zero 2557 let Inst{3-0} = addr{3-0}; // imm3_0/Rm 2558 let DecoderMethod = "DecodeAddrMode3Instruction"; 2559 let AsmMatchConverter = "cvtStrdPre"; 2560} 2561 2562def STRD_POST: AI3ldstidx<0b1111, 0, 0, (outs GPR:$Rn_wb), 2563 (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr, 2564 am3offset:$offset), 2565 IndexModePost, StMiscFrm, IIC_iStore_d_ru, 2566 "strd", "\t$Rt, $Rt2, $addr, $offset", 2567 "$addr.base = $Rn_wb", []> { 2568 bits<10> offset; 2569 bits<4> addr; 2570 let Inst{23} = offset{8}; // U bit 2571 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 2572 let Inst{19-16} = addr; 2573 let Inst{11-8} = offset{7-4}; // imm7_4/zero 2574 let Inst{3-0} = offset{3-0}; // imm3_0/Rm 2575 let DecoderMethod = "DecodeAddrMode3Instruction"; 2576} 2577} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 2578 2579// STRT, STRBT, and STRHT 2580 2581def STRBT_POST_REG : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), 2582 (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 2583 IndexModePost, StFrm, IIC_iStore_bh_ru, 2584 "strbt", "\t$Rt, $addr, $offset", 2585 "$addr.base = $Rn_wb", []> { 2586 // {12} isAdd 2587 // {11-0} imm12/Rm 2588 bits<14> offset; 2589 bits<4> addr; 2590 let Inst{25} = 1; 2591 let Inst{23} = offset{12}; 2592 let Inst{21} = 1; // overwrite 2593 let Inst{19-16} = addr; 2594 let Inst{11-5} = offset{11-5}; 2595 let Inst{4} = 0; 2596 let Inst{3-0} = offset{3-0}; 2597 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2598} 2599 2600def STRBT_POST_IMM : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), 2601 (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 2602 IndexModePost, StFrm, IIC_iStore_bh_ru, 2603 "strbt", "\t$Rt, $addr, $offset", 2604 "$addr.base = $Rn_wb", []> { 2605 // {12} isAdd 2606 // {11-0} imm12/Rm 2607 bits<14> offset; 2608 bits<4> addr; 2609 let Inst{25} = 0; 2610 let Inst{23} = offset{12}; 2611 let Inst{21} = 1; // overwrite 2612 let Inst{19-16} = addr; 2613 let Inst{11-0} = offset{11-0}; 2614 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2615} 2616 2617let mayStore = 1, neverHasSideEffects = 1 in { 2618def STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), 2619 (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 2620 IndexModePost, StFrm, IIC_iStore_ru, 2621 "strt", "\t$Rt, $addr, $offset", 2622 "$addr.base = $Rn_wb", []> { 2623 // {12} isAdd 2624 // {11-0} imm12/Rm 2625 bits<14> offset; 2626 bits<4> addr; 2627 let Inst{25} = 1; 2628 let Inst{23} = offset{12}; 2629 let Inst{21} = 1; // overwrite 2630 let Inst{19-16} = addr; 2631 let Inst{11-5} = offset{11-5}; 2632 let Inst{4} = 0; 2633 let Inst{3-0} = offset{3-0}; 2634 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2635} 2636 2637def STRT_POST_IMM : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), 2638 (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 2639 IndexModePost, StFrm, IIC_iStore_ru, 2640 "strt", "\t$Rt, $addr, $offset", 2641 "$addr.base = $Rn_wb", []> { 2642 // {12} isAdd 2643 // {11-0} imm12/Rm 2644 bits<14> offset; 2645 bits<4> addr; 2646 let Inst{25} = 0; 2647 let Inst{23} = offset{12}; 2648 let Inst{21} = 1; // overwrite 2649 let Inst{19-16} = addr; 2650 let Inst{11-0} = offset{11-0}; 2651 let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2652} 2653} 2654 2655 2656multiclass AI3strT<bits<4> op, string opc> { 2657 def i : AI3ldstidxT<op, 0, (outs GPR:$base_wb), 2658 (ins GPR:$Rt, addr_offset_none:$addr, postidx_imm8:$offset), 2659 IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc, 2660 "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> { 2661 bits<9> offset; 2662 let Inst{23} = offset{8}; 2663 let Inst{22} = 1; 2664 let Inst{11-8} = offset{7-4}; 2665 let Inst{3-0} = offset{3-0}; 2666 let AsmMatchConverter = "cvtStExtTWriteBackImm"; 2667 } 2668 def r : AI3ldstidxT<op, 0, (outs GPR:$base_wb), 2669 (ins GPR:$Rt, addr_offset_none:$addr, postidx_reg:$Rm), 2670 IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc, 2671 "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> { 2672 bits<5> Rm; 2673 let Inst{23} = Rm{4}; 2674 let Inst{22} = 0; 2675 let Inst{11-8} = 0; 2676 let Inst{3-0} = Rm{3-0}; 2677 let AsmMatchConverter = "cvtStExtTWriteBackReg"; 2678 } 2679} 2680 2681 2682defm STRHT : AI3strT<0b1011, "strht">; 2683 2684 2685//===----------------------------------------------------------------------===// 2686// Load / store multiple Instructions. 2687// 2688 2689multiclass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f, 2690 InstrItinClass itin, InstrItinClass itin_upd> { 2691 // IA is the default, so no need for an explicit suffix on the 2692 // mnemonic here. Without it is the canonical spelling. 2693 def IA : 2694 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2695 IndexModeNone, f, itin, 2696 !strconcat(asm, "${p}\t$Rn, $regs", sfx), "", []> { 2697 let Inst{24-23} = 0b01; // Increment After 2698 let Inst{22} = P_bit; 2699 let Inst{21} = 0; // No writeback 2700 let Inst{20} = L_bit; 2701 } 2702 def IA_UPD : 2703 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2704 IndexModeUpd, f, itin_upd, 2705 !strconcat(asm, "${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 2706 let Inst{24-23} = 0b01; // Increment After 2707 let Inst{22} = P_bit; 2708 let Inst{21} = 1; // Writeback 2709 let Inst{20} = L_bit; 2710 2711 let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 2712 } 2713 def DA : 2714 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2715 IndexModeNone, f, itin, 2716 !strconcat(asm, "da${p}\t$Rn, $regs", sfx), "", []> { 2717 let Inst{24-23} = 0b00; // Decrement After 2718 let Inst{22} = P_bit; 2719 let Inst{21} = 0; // No writeback 2720 let Inst{20} = L_bit; 2721 } 2722 def DA_UPD : 2723 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2724 IndexModeUpd, f, itin_upd, 2725 !strconcat(asm, "da${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 2726 let Inst{24-23} = 0b00; // Decrement After 2727 let Inst{22} = P_bit; 2728 let Inst{21} = 1; // Writeback 2729 let Inst{20} = L_bit; 2730 2731 let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 2732 } 2733 def DB : 2734 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2735 IndexModeNone, f, itin, 2736 !strconcat(asm, "db${p}\t$Rn, $regs", sfx), "", []> { 2737 let Inst{24-23} = 0b10; // Decrement Before 2738 let Inst{22} = P_bit; 2739 let Inst{21} = 0; // No writeback 2740 let Inst{20} = L_bit; 2741 } 2742 def DB_UPD : 2743 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2744 IndexModeUpd, f, itin_upd, 2745 !strconcat(asm, "db${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 2746 let Inst{24-23} = 0b10; // Decrement Before 2747 let Inst{22} = P_bit; 2748 let Inst{21} = 1; // Writeback 2749 let Inst{20} = L_bit; 2750 2751 let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 2752 } 2753 def IB : 2754 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2755 IndexModeNone, f, itin, 2756 !strconcat(asm, "ib${p}\t$Rn, $regs", sfx), "", []> { 2757 let Inst{24-23} = 0b11; // Increment Before 2758 let Inst{22} = P_bit; 2759 let Inst{21} = 0; // No writeback 2760 let Inst{20} = L_bit; 2761 } 2762 def IB_UPD : 2763 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2764 IndexModeUpd, f, itin_upd, 2765 !strconcat(asm, "ib${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 2766 let Inst{24-23} = 0b11; // Increment Before 2767 let Inst{22} = P_bit; 2768 let Inst{21} = 1; // Writeback 2769 let Inst{20} = L_bit; 2770 2771 let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 2772 } 2773} 2774 2775let neverHasSideEffects = 1 in { 2776 2777let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 2778defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m, 2779 IIC_iLoad_mu>; 2780 2781let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 2782defm STM : arm_ldst_mult<"stm", "", 0, 0, LdStMulFrm, IIC_iStore_m, 2783 IIC_iStore_mu>; 2784 2785} // neverHasSideEffects 2786 2787// FIXME: remove when we have a way to marking a MI with these properties. 2788// FIXME: Should pc be an implicit operand like PICADD, etc? 2789let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 2790 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in 2791def LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, 2792 reglist:$regs, variable_ops), 2793 4, IIC_iLoad_mBr, [], 2794 (LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>, 2795 RegConstraint<"$Rn = $wb">; 2796 2797let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 2798defm sysLDM : arm_ldst_mult<"ldm", " ^", 1, 1, LdStMulFrm, IIC_iLoad_m, 2799 IIC_iLoad_mu>; 2800 2801let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 2802defm sysSTM : arm_ldst_mult<"stm", " ^", 0, 1, LdStMulFrm, IIC_iStore_m, 2803 IIC_iStore_mu>; 2804 2805 2806 2807//===----------------------------------------------------------------------===// 2808// Move Instructions. 2809// 2810 2811let neverHasSideEffects = 1 in 2812def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr, 2813 "mov", "\t$Rd, $Rm", []>, UnaryDP { 2814 bits<4> Rd; 2815 bits<4> Rm; 2816 2817 let Inst{19-16} = 0b0000; 2818 let Inst{11-4} = 0b00000000; 2819 let Inst{25} = 0; 2820 let Inst{3-0} = Rm; 2821 let Inst{15-12} = Rd; 2822} 2823 2824// A version for the smaller set of tail call registers. 2825let neverHasSideEffects = 1 in 2826def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm, 2827 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP { 2828 bits<4> Rd; 2829 bits<4> Rm; 2830 2831 let Inst{11-4} = 0b00000000; 2832 let Inst{25} = 0; 2833 let Inst{3-0} = Rm; 2834 let Inst{15-12} = Rd; 2835} 2836 2837def MOVsr : AsI1<0b1101, (outs GPRnopc:$Rd), (ins shift_so_reg_reg:$src), 2838 DPSoRegRegFrm, IIC_iMOVsr, 2839 "mov", "\t$Rd, $src", 2840 [(set GPRnopc:$Rd, shift_so_reg_reg:$src)]>, UnaryDP { 2841 bits<4> Rd; 2842 bits<12> src; 2843 let Inst{15-12} = Rd; 2844 let Inst{19-16} = 0b0000; 2845 let Inst{11-8} = src{11-8}; 2846 let Inst{7} = 0; 2847 let Inst{6-5} = src{6-5}; 2848 let Inst{4} = 1; 2849 let Inst{3-0} = src{3-0}; 2850 let Inst{25} = 0; 2851} 2852 2853def MOVsi : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_imm:$src), 2854 DPSoRegImmFrm, IIC_iMOVsr, 2855 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_imm:$src)]>, 2856 UnaryDP { 2857 bits<4> Rd; 2858 bits<12> src; 2859 let Inst{15-12} = Rd; 2860 let Inst{19-16} = 0b0000; 2861 let Inst{11-5} = src{11-5}; 2862 let Inst{4} = 0; 2863 let Inst{3-0} = src{3-0}; 2864 let Inst{25} = 0; 2865} 2866 2867let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 2868def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi, 2869 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP { 2870 bits<4> Rd; 2871 bits<12> imm; 2872 let Inst{25} = 1; 2873 let Inst{15-12} = Rd; 2874 let Inst{19-16} = 0b0000; 2875 let Inst{11-0} = imm; 2876} 2877 2878let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 2879def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins imm0_65535_expr:$imm), 2880 DPFrm, IIC_iMOVi, 2881 "movw", "\t$Rd, $imm", 2882 [(set GPR:$Rd, imm0_65535:$imm)]>, 2883 Requires<[IsARM, HasV6T2]>, UnaryDP { 2884 bits<4> Rd; 2885 bits<16> imm; 2886 let Inst{15-12} = Rd; 2887 let Inst{11-0} = imm{11-0}; 2888 let Inst{19-16} = imm{15-12}; 2889 let Inst{20} = 0; 2890 let Inst{25} = 1; 2891 let DecoderMethod = "DecodeArmMOVTWInstruction"; 2892} 2893 2894def : InstAlias<"mov${p} $Rd, $imm", 2895 (MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p)>, 2896 Requires<[IsARM]>; 2897 2898def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 2899 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; 2900 2901let Constraints = "$src = $Rd" in { 2902def MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd), 2903 (ins GPR:$src, imm0_65535_expr:$imm), 2904 DPFrm, IIC_iMOVi, 2905 "movt", "\t$Rd, $imm", 2906 [(set GPRnopc:$Rd, 2907 (or (and GPR:$src, 0xffff), 2908 lo16AllZero:$imm))]>, UnaryDP, 2909 Requires<[IsARM, HasV6T2]> { 2910 bits<4> Rd; 2911 bits<16> imm; 2912 let Inst{15-12} = Rd; 2913 let Inst{11-0} = imm{11-0}; 2914 let Inst{19-16} = imm{15-12}; 2915 let Inst{20} = 0; 2916 let Inst{25} = 1; 2917 let DecoderMethod = "DecodeArmMOVTWInstruction"; 2918} 2919 2920def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 2921 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; 2922 2923} // Constraints 2924 2925def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, 2926 Requires<[IsARM, HasV6T2]>; 2927 2928let Uses = [CPSR] in 2929def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, 2930 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP, 2931 Requires<[IsARM]>; 2932 2933// These aren't really mov instructions, but we have to define them this way 2934// due to flag operands. 2935 2936let Defs = [CPSR] in { 2937def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 2938 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP, 2939 Requires<[IsARM]>; 2940def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 2941 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP, 2942 Requires<[IsARM]>; 2943} 2944 2945//===----------------------------------------------------------------------===// 2946// Extend Instructions. 2947// 2948 2949// Sign extenders 2950 2951def SXTB : AI_ext_rrot<0b01101010, 2952 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; 2953def SXTH : AI_ext_rrot<0b01101011, 2954 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; 2955 2956def SXTAB : AI_exta_rrot<0b01101010, 2957 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 2958def SXTAH : AI_exta_rrot<0b01101011, 2959 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 2960 2961def SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">; 2962 2963def SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">; 2964 2965// Zero extenders 2966 2967let AddedComplexity = 16 in { 2968def UXTB : AI_ext_rrot<0b01101110, 2969 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; 2970def UXTH : AI_ext_rrot<0b01101111, 2971 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 2972def UXTB16 : AI_ext_rrot<0b01101100, 2973 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 2974 2975// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 2976// The transformation should probably be done as a combiner action 2977// instead so we can include a check for masking back in the upper 2978// eight bits of the source into the lower eight bits of the result. 2979//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), 2980// (UXTB16r_rot GPR:$Src, 3)>; 2981def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), 2982 (UXTB16 GPR:$Src, 1)>; 2983 2984def UXTAB : AI_exta_rrot<0b01101110, "uxtab", 2985 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 2986def UXTAH : AI_exta_rrot<0b01101111, "uxtah", 2987 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 2988} 2989 2990// This isn't safe in general, the add is two 16-bit units, not a 32-bit add. 2991def UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; 2992 2993 2994def SBFX : I<(outs GPRnopc:$Rd), 2995 (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width), 2996 AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 2997 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 2998 Requires<[IsARM, HasV6T2]> { 2999 bits<4> Rd; 3000 bits<4> Rn; 3001 bits<5> lsb; 3002 bits<5> width; 3003 let Inst{27-21} = 0b0111101; 3004 let Inst{6-4} = 0b101; 3005 let Inst{20-16} = width; 3006 let Inst{15-12} = Rd; 3007 let Inst{11-7} = lsb; 3008 let Inst{3-0} = Rn; 3009} 3010 3011def UBFX : I<(outs GPR:$Rd), 3012 (ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width), 3013 AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3014 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 3015 Requires<[IsARM, HasV6T2]> { 3016 bits<4> Rd; 3017 bits<4> Rn; 3018 bits<5> lsb; 3019 bits<5> width; 3020 let Inst{27-21} = 0b0111111; 3021 let Inst{6-4} = 0b101; 3022 let Inst{20-16} = width; 3023 let Inst{15-12} = Rd; 3024 let Inst{11-7} = lsb; 3025 let Inst{3-0} = Rn; 3026} 3027 3028//===----------------------------------------------------------------------===// 3029// Arithmetic Instructions. 3030// 3031 3032defm ADD : AsI1_bin_irs<0b0100, "add", 3033 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3034 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 3035defm SUB : AsI1_bin_irs<0b0010, "sub", 3036 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3037 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 3038 3039// ADD and SUB with 's' bit set. 3040// 3041// Currently, ADDS/SUBS are pseudo opcodes that exist only in the 3042// selection DAG. They are "lowered" to real ADD/SUB opcodes by 3043// AdjustInstrPostInstrSelection where we determine whether or not to 3044// set the "s" bit based on CPSR liveness. 3045// 3046// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen 3047// support for an optional CPSR definition that corresponds to the DAG 3048// node's second value. We can then eliminate the implicit def of CPSR. 3049defm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3050 BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>; 3051defm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3052 BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; 3053 3054defm ADC : AI1_adde_sube_irs<0b0101, "adc", 3055 BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>, 1>; 3056defm SBC : AI1_adde_sube_irs<0b0110, "sbc", 3057 BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>; 3058 3059defm RSB : AsI1_rbin_irs<0b0011, "rsb", 3060 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3061 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 3062 3063// FIXME: Eliminate them if we can write def : Pat patterns which defines 3064// CPSR and the implicit def of CPSR is not needed. 3065defm RSBS : AsI1_rbin_s_is<IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3066 BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; 3067 3068defm RSC : AI1_rsc_irs<0b0111, "rsc", 3069 BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>; 3070 3071// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 3072// The assume-no-carry-in form uses the negation of the input since add/sub 3073// assume opposite meanings of the carry flag (i.e., carry == !borrow). 3074// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 3075// details. 3076def : ARMPat<(add GPR:$src, so_imm_neg:$imm), 3077 (SUBri GPR:$src, so_imm_neg:$imm)>; 3078def : ARMPat<(ARMaddc GPR:$src, so_imm_neg:$imm), 3079 (SUBSri GPR:$src, so_imm_neg:$imm)>; 3080 3081def : ARMPat<(add GPR:$src, imm0_65535_neg:$imm), 3082 (SUBrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>; 3083def : ARMPat<(ARMaddc GPR:$src, imm0_65535_neg:$imm), 3084 (SUBSrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>; 3085 3086// The with-carry-in form matches bitwise not instead of the negation. 3087// Effectively, the inverse interpretation of the carry flag already accounts 3088// for part of the negation. 3089def : ARMPat<(ARMadde GPR:$src, so_imm_not:$imm, CPSR), 3090 (SBCri GPR:$src, so_imm_not:$imm)>; 3091 3092// Note: These are implemented in C++ code, because they have to generate 3093// ADD/SUBrs instructions, which use a complex pattern that a xform function 3094// cannot produce. 3095// (mul X, 2^n+1) -> (add (X << n), X) 3096// (mul X, 2^n-1) -> (rsb X, (X << n)) 3097 3098// ARM Arithmetic Instruction 3099// GPR:$dst = GPR:$a op GPR:$b 3100class AAI<bits<8> op27_20, bits<8> op11_4, string opc, 3101 list<dag> pattern = [], 3102 dag iops = (ins GPRnopc:$Rn, GPRnopc:$Rm), 3103 string asm = "\t$Rd, $Rn, $Rm"> 3104 : AI<(outs GPRnopc:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> { 3105 bits<4> Rn; 3106 bits<4> Rd; 3107 bits<4> Rm; 3108 let Inst{27-20} = op27_20; 3109 let Inst{11-4} = op11_4; 3110 let Inst{19-16} = Rn; 3111 let Inst{15-12} = Rd; 3112 let Inst{3-0} = Rm; 3113 3114 let Unpredictable{11-8} = 0b1111; 3115} 3116 3117// Saturating add/subtract 3118 3119def QADD : AAI<0b00010000, 0b00000101, "qadd", 3120 [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))], 3121 (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">; 3122def QSUB : AAI<0b00010010, 0b00000101, "qsub", 3123 [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))], 3124 (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">; 3125def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], 3126 (ins GPRnopc:$Rm, GPRnopc:$Rn), 3127 "\t$Rd, $Rm, $Rn">; 3128def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], 3129 (ins GPRnopc:$Rm, GPRnopc:$Rn), 3130 "\t$Rd, $Rm, $Rn">; 3131 3132def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">; 3133def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">; 3134def QASX : AAI<0b01100010, 0b11110011, "qasx">; 3135def QSAX : AAI<0b01100010, 0b11110101, "qsax">; 3136def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">; 3137def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">; 3138def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">; 3139def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">; 3140def UQASX : AAI<0b01100110, 0b11110011, "uqasx">; 3141def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">; 3142def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">; 3143def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">; 3144 3145// Signed/Unsigned add/subtract 3146 3147def SASX : AAI<0b01100001, 0b11110011, "sasx">; 3148def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">; 3149def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">; 3150def SSAX : AAI<0b01100001, 0b11110101, "ssax">; 3151def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">; 3152def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">; 3153def UASX : AAI<0b01100101, 0b11110011, "uasx">; 3154def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">; 3155def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">; 3156def USAX : AAI<0b01100101, 0b11110101, "usax">; 3157def USUB16 : AAI<0b01100101, 0b11110111, "usub16">; 3158def USUB8 : AAI<0b01100101, 0b11111111, "usub8">; 3159 3160// Signed/Unsigned halving add/subtract 3161 3162def SHASX : AAI<0b01100011, 0b11110011, "shasx">; 3163def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">; 3164def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">; 3165def SHSAX : AAI<0b01100011, 0b11110101, "shsax">; 3166def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">; 3167def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">; 3168def UHASX : AAI<0b01100111, 0b11110011, "uhasx">; 3169def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">; 3170def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">; 3171def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">; 3172def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">; 3173def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">; 3174 3175// Unsigned Sum of Absolute Differences [and Accumulate]. 3176 3177def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3178 MulFrm /* for convenience */, NoItinerary, "usad8", 3179 "\t$Rd, $Rn, $Rm", []>, 3180 Requires<[IsARM, HasV6]> { 3181 bits<4> Rd; 3182 bits<4> Rn; 3183 bits<4> Rm; 3184 let Inst{27-20} = 0b01111000; 3185 let Inst{15-12} = 0b1111; 3186 let Inst{7-4} = 0b0001; 3187 let Inst{19-16} = Rd; 3188 let Inst{11-8} = Rm; 3189 let Inst{3-0} = Rn; 3190} 3191def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3192 MulFrm /* for convenience */, NoItinerary, "usada8", 3193 "\t$Rd, $Rn, $Rm, $Ra", []>, 3194 Requires<[IsARM, HasV6]> { 3195 bits<4> Rd; 3196 bits<4> Rn; 3197 bits<4> Rm; 3198 bits<4> Ra; 3199 let Inst{27-20} = 0b01111000; 3200 let Inst{7-4} = 0b0001; 3201 let Inst{19-16} = Rd; 3202 let Inst{15-12} = Ra; 3203 let Inst{11-8} = Rm; 3204 let Inst{3-0} = Rn; 3205} 3206 3207// Signed/Unsigned saturate 3208 3209def SSAT : AI<(outs GPRnopc:$Rd), 3210 (ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), 3211 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> { 3212 bits<4> Rd; 3213 bits<5> sat_imm; 3214 bits<4> Rn; 3215 bits<8> sh; 3216 let Inst{27-21} = 0b0110101; 3217 let Inst{5-4} = 0b01; 3218 let Inst{20-16} = sat_imm; 3219 let Inst{15-12} = Rd; 3220 let Inst{11-7} = sh{4-0}; 3221 let Inst{6} = sh{5}; 3222 let Inst{3-0} = Rn; 3223} 3224 3225def SSAT16 : AI<(outs GPRnopc:$Rd), 3226 (ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm, 3227 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> { 3228 bits<4> Rd; 3229 bits<4> sat_imm; 3230 bits<4> Rn; 3231 let Inst{27-20} = 0b01101010; 3232 let Inst{11-4} = 0b11110011; 3233 let Inst{15-12} = Rd; 3234 let Inst{19-16} = sat_imm; 3235 let Inst{3-0} = Rn; 3236} 3237 3238def USAT : AI<(outs GPRnopc:$Rd), 3239 (ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), 3240 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> { 3241 bits<4> Rd; 3242 bits<5> sat_imm; 3243 bits<4> Rn; 3244 bits<8> sh; 3245 let Inst{27-21} = 0b0110111; 3246 let Inst{5-4} = 0b01; 3247 let Inst{15-12} = Rd; 3248 let Inst{11-7} = sh{4-0}; 3249 let Inst{6} = sh{5}; 3250 let Inst{20-16} = sat_imm; 3251 let Inst{3-0} = Rn; 3252} 3253 3254def USAT16 : AI<(outs GPRnopc:$Rd), 3255 (ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm, 3256 NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []> { 3257 bits<4> Rd; 3258 bits<4> sat_imm; 3259 bits<4> Rn; 3260 let Inst{27-20} = 0b01101110; 3261 let Inst{11-4} = 0b11110011; 3262 let Inst{15-12} = Rd; 3263 let Inst{19-16} = sat_imm; 3264 let Inst{3-0} = Rn; 3265} 3266 3267def : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm:$pos), 3268 (SSAT imm:$pos, GPRnopc:$a, 0)>; 3269def : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm:$pos), 3270 (USAT imm:$pos, GPRnopc:$a, 0)>; 3271 3272//===----------------------------------------------------------------------===// 3273// Bitwise Instructions. 3274// 3275 3276defm AND : AsI1_bin_irs<0b0000, "and", 3277 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 3278 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 3279defm ORR : AsI1_bin_irs<0b1100, "orr", 3280 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 3281 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 3282defm EOR : AsI1_bin_irs<0b0001, "eor", 3283 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 3284 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 3285defm BIC : AsI1_bin_irs<0b1110, "bic", 3286 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 3287 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 3288 3289// FIXME: bf_inv_mask_imm should be two operands, the lsb and the msb, just 3290// like in the actual instruction encoding. The complexity of mapping the mask 3291// to the lsb/msb pair should be handled by ISel, not encapsulated in the 3292// instruction description. 3293def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm), 3294 AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3295 "bfc", "\t$Rd, $imm", "$src = $Rd", 3296 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>, 3297 Requires<[IsARM, HasV6T2]> { 3298 bits<4> Rd; 3299 bits<10> imm; 3300 let Inst{27-21} = 0b0111110; 3301 let Inst{6-0} = 0b0011111; 3302 let Inst{15-12} = Rd; 3303 let Inst{11-7} = imm{4-0}; // lsb 3304 let Inst{20-16} = imm{9-5}; // msb 3305} 3306 3307// A8.6.18 BFI - Bitfield insert (Encoding A1) 3308def BFI:I<(outs GPRnopc:$Rd), (ins GPRnopc:$src, GPR:$Rn, bf_inv_mask_imm:$imm), 3309 AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3310 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd", 3311 [(set GPRnopc:$Rd, (ARMbfi GPRnopc:$src, GPR:$Rn, 3312 bf_inv_mask_imm:$imm))]>, 3313 Requires<[IsARM, HasV6T2]> { 3314 bits<4> Rd; 3315 bits<4> Rn; 3316 bits<10> imm; 3317 let Inst{27-21} = 0b0111110; 3318 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 3319 let Inst{15-12} = Rd; 3320 let Inst{11-7} = imm{4-0}; // lsb 3321 let Inst{20-16} = imm{9-5}; // width 3322 let Inst{3-0} = Rn; 3323} 3324 3325def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr, 3326 "mvn", "\t$Rd, $Rm", 3327 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP { 3328 bits<4> Rd; 3329 bits<4> Rm; 3330 let Inst{25} = 0; 3331 let Inst{19-16} = 0b0000; 3332 let Inst{11-4} = 0b00000000; 3333 let Inst{15-12} = Rd; 3334 let Inst{3-0} = Rm; 3335} 3336def MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), 3337 DPSoRegImmFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", 3338 [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP { 3339 bits<4> Rd; 3340 bits<12> shift; 3341 let Inst{25} = 0; 3342 let Inst{19-16} = 0b0000; 3343 let Inst{15-12} = Rd; 3344 let Inst{11-5} = shift{11-5}; 3345 let Inst{4} = 0; 3346 let Inst{3-0} = shift{3-0}; 3347} 3348def MVNsr : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_reg:$shift), 3349 DPSoRegRegFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", 3350 [(set GPR:$Rd, (not so_reg_reg:$shift))]>, UnaryDP { 3351 bits<4> Rd; 3352 bits<12> shift; 3353 let Inst{25} = 0; 3354 let Inst{19-16} = 0b0000; 3355 let Inst{15-12} = Rd; 3356 let Inst{11-8} = shift{11-8}; 3357 let Inst{7} = 0; 3358 let Inst{6-5} = shift{6-5}; 3359 let Inst{4} = 1; 3360 let Inst{3-0} = shift{3-0}; 3361} 3362let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 3363def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, 3364 IIC_iMVNi, "mvn", "\t$Rd, $imm", 3365 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP { 3366 bits<4> Rd; 3367 bits<12> imm; 3368 let Inst{25} = 1; 3369 let Inst{19-16} = 0b0000; 3370 let Inst{15-12} = Rd; 3371 let Inst{11-0} = imm; 3372} 3373 3374def : ARMPat<(and GPR:$src, so_imm_not:$imm), 3375 (BICri GPR:$src, so_imm_not:$imm)>; 3376 3377//===----------------------------------------------------------------------===// 3378// Multiply Instructions. 3379// 3380class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 3381 string opc, string asm, list<dag> pattern> 3382 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 3383 bits<4> Rd; 3384 bits<4> Rm; 3385 bits<4> Rn; 3386 let Inst{19-16} = Rd; 3387 let Inst{11-8} = Rm; 3388 let Inst{3-0} = Rn; 3389} 3390class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 3391 string opc, string asm, list<dag> pattern> 3392 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 3393 bits<4> RdLo; 3394 bits<4> RdHi; 3395 bits<4> Rm; 3396 bits<4> Rn; 3397 let Inst{19-16} = RdHi; 3398 let Inst{15-12} = RdLo; 3399 let Inst{11-8} = Rm; 3400 let Inst{3-0} = Rn; 3401} 3402 3403// FIXME: The v5 pseudos are only necessary for the additional Constraint 3404// property. Remove them when it's possible to add those properties 3405// on an individual MachineInstr, not just an instruction description. 3406let isCommutable = 1, TwoOperandAliasConstraint = "$Rn = $Rd" in { 3407def MUL : AsMul1I32<0b0000000, (outs GPRnopc:$Rd), 3408 (ins GPRnopc:$Rn, GPRnopc:$Rm), 3409 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", 3410 [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))]>, 3411 Requires<[IsARM, HasV6]> { 3412 let Inst{15-12} = 0b0000; 3413 let Unpredictable{15-12} = 0b1111; 3414} 3415 3416let Constraints = "@earlyclobber $Rd" in 3417def MULv5: ARMPseudoExpand<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm, 3418 pred:$p, cc_out:$s), 3419 4, IIC_iMUL32, 3420 [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))], 3421 (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s)>, 3422 Requires<[IsARM, NoV6]>; 3423} 3424 3425def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3426 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra", 3427 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 3428 Requires<[IsARM, HasV6]> { 3429 bits<4> Ra; 3430 let Inst{15-12} = Ra; 3431} 3432 3433let Constraints = "@earlyclobber $Rd" in 3434def MLAv5: ARMPseudoExpand<(outs GPR:$Rd), 3435 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s), 3436 4, IIC_iMAC32, 3437 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))], 3438 (MLA GPR:$Rd, GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s)>, 3439 Requires<[IsARM, NoV6]>; 3440 3441def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3442 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra", 3443 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>, 3444 Requires<[IsARM, HasV6T2]> { 3445 bits<4> Rd; 3446 bits<4> Rm; 3447 bits<4> Rn; 3448 bits<4> Ra; 3449 let Inst{19-16} = Rd; 3450 let Inst{15-12} = Ra; 3451 let Inst{11-8} = Rm; 3452 let Inst{3-0} = Rn; 3453} 3454 3455// Extra precision multiplies with low / high results 3456let neverHasSideEffects = 1 in { 3457let isCommutable = 1 in { 3458def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi), 3459 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 3460 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3461 Requires<[IsARM, HasV6]>; 3462 3463def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi), 3464 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 3465 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3466 Requires<[IsARM, HasV6]>; 3467 3468let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { 3469def SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3470 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 3471 4, IIC_iMUL64, [], 3472 (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 3473 Requires<[IsARM, NoV6]>; 3474 3475def UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3476 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 3477 4, IIC_iMUL64, [], 3478 (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 3479 Requires<[IsARM, NoV6]>; 3480} 3481} 3482 3483// Multiply + accumulate 3484def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi), 3485 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, 3486 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3487 Requires<[IsARM, HasV6]>; 3488def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi), 3489 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, 3490 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3491 Requires<[IsARM, HasV6]>; 3492 3493def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), 3494 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, 3495 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3496 Requires<[IsARM, HasV6]> { 3497 bits<4> RdLo; 3498 bits<4> RdHi; 3499 bits<4> Rm; 3500 bits<4> Rn; 3501 let Inst{19-16} = RdHi; 3502 let Inst{15-12} = RdLo; 3503 let Inst{11-8} = Rm; 3504 let Inst{3-0} = Rn; 3505} 3506 3507let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { 3508def SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3509 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 3510 4, IIC_iMAC64, [], 3511 (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 3512 Requires<[IsARM, NoV6]>; 3513def UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3514 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 3515 4, IIC_iMAC64, [], 3516 (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 3517 Requires<[IsARM, NoV6]>; 3518def UMAALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3519 (ins GPR:$Rn, GPR:$Rm, pred:$p), 3520 4, IIC_iMAC64, [], 3521 (UMAAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p)>, 3522 Requires<[IsARM, NoV6]>; 3523} 3524 3525} // neverHasSideEffects 3526 3527// Most significant word multiply 3528def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3529 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm", 3530 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>, 3531 Requires<[IsARM, HasV6]> { 3532 let Inst{15-12} = 0b1111; 3533} 3534 3535def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3536 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", []>, 3537 Requires<[IsARM, HasV6]> { 3538 let Inst{15-12} = 0b1111; 3539} 3540 3541def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd), 3542 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3543 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra", 3544 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 3545 Requires<[IsARM, HasV6]>; 3546 3547def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd), 3548 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3549 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>, 3550 Requires<[IsARM, HasV6]>; 3551 3552def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd), 3553 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3554 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", []>, 3555 Requires<[IsARM, HasV6]>; 3556 3557def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd), 3558 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3559 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>, 3560 Requires<[IsARM, HasV6]>; 3561 3562multiclass AI_smul<string opc, PatFrag opnode> { 3563 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3564 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm", 3565 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16), 3566 (sext_inreg GPR:$Rm, i16)))]>, 3567 Requires<[IsARM, HasV5TE]>; 3568 3569 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3570 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm", 3571 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16), 3572 (sra GPR:$Rm, (i32 16))))]>, 3573 Requires<[IsARM, HasV5TE]>; 3574 3575 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3576 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm", 3577 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)), 3578 (sext_inreg GPR:$Rm, i16)))]>, 3579 Requires<[IsARM, HasV5TE]>; 3580 3581 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3582 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm", 3583 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)), 3584 (sra GPR:$Rm, (i32 16))))]>, 3585 Requires<[IsARM, HasV5TE]>; 3586 3587 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3588 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm", 3589 [(set GPR:$Rd, (sra (opnode GPR:$Rn, 3590 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>, 3591 Requires<[IsARM, HasV5TE]>; 3592 3593 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3594 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm", 3595 [(set GPR:$Rd, (sra (opnode GPR:$Rn, 3596 (sra GPR:$Rm, (i32 16))), (i32 16)))]>, 3597 Requires<[IsARM, HasV5TE]>; 3598} 3599 3600 3601multiclass AI_smla<string opc, PatFrag opnode> { 3602 let DecoderMethod = "DecodeSMLAInstruction" in { 3603 def BB : AMulxyIa<0b0001000, 0b00, (outs GPRnopc:$Rd), 3604 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3605 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", 3606 [(set GPRnopc:$Rd, (add GPR:$Ra, 3607 (opnode (sext_inreg GPRnopc:$Rn, i16), 3608 (sext_inreg GPRnopc:$Rm, i16))))]>, 3609 Requires<[IsARM, HasV5TE]>; 3610 3611 def BT : AMulxyIa<0b0001000, 0b10, (outs GPRnopc:$Rd), 3612 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3613 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", 3614 [(set GPRnopc:$Rd, 3615 (add GPR:$Ra, (opnode (sext_inreg GPRnopc:$Rn, i16), 3616 (sra GPRnopc:$Rm, (i32 16)))))]>, 3617 Requires<[IsARM, HasV5TE]>; 3618 3619 def TB : AMulxyIa<0b0001000, 0b01, (outs GPRnopc:$Rd), 3620 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3621 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", 3622 [(set GPRnopc:$Rd, 3623 (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)), 3624 (sext_inreg GPRnopc:$Rm, i16))))]>, 3625 Requires<[IsARM, HasV5TE]>; 3626 3627 def TT : AMulxyIa<0b0001000, 0b11, (outs GPRnopc:$Rd), 3628 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3629 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", 3630 [(set GPRnopc:$Rd, 3631 (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)), 3632 (sra GPRnopc:$Rm, (i32 16)))))]>, 3633 Requires<[IsARM, HasV5TE]>; 3634 3635 def WB : AMulxyIa<0b0001001, 0b00, (outs GPRnopc:$Rd), 3636 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3637 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", 3638 [(set GPRnopc:$Rd, 3639 (add GPR:$Ra, (sra (opnode GPRnopc:$Rn, 3640 (sext_inreg GPRnopc:$Rm, i16)), (i32 16))))]>, 3641 Requires<[IsARM, HasV5TE]>; 3642 3643 def WT : AMulxyIa<0b0001001, 0b10, (outs GPRnopc:$Rd), 3644 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3645 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", 3646 [(set GPRnopc:$Rd, 3647 (add GPR:$Ra, (sra (opnode GPRnopc:$Rn, 3648 (sra GPRnopc:$Rm, (i32 16))), (i32 16))))]>, 3649 Requires<[IsARM, HasV5TE]>; 3650 } 3651} 3652 3653defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 3654defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 3655 3656// Halfword multiply accumulate long: SMLAL<x><y>. 3657def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3658 (ins GPRnopc:$Rn, GPRnopc:$Rm), 3659 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3660 Requires<[IsARM, HasV5TE]>; 3661 3662def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3663 (ins GPRnopc:$Rn, GPRnopc:$Rm), 3664 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3665 Requires<[IsARM, HasV5TE]>; 3666 3667def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3668 (ins GPRnopc:$Rn, GPRnopc:$Rm), 3669 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3670 Requires<[IsARM, HasV5TE]>; 3671 3672def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3673 (ins GPRnopc:$Rn, GPRnopc:$Rm), 3674 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3675 Requires<[IsARM, HasV5TE]>; 3676 3677// Helper class for AI_smld. 3678class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops, 3679 InstrItinClass itin, string opc, string asm> 3680 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> { 3681 bits<4> Rn; 3682 bits<4> Rm; 3683 let Inst{27-23} = 0b01110; 3684 let Inst{22} = long; 3685 let Inst{21-20} = 0b00; 3686 let Inst{11-8} = Rm; 3687 let Inst{7} = 0; 3688 let Inst{6} = sub; 3689 let Inst{5} = swap; 3690 let Inst{4} = 1; 3691 let Inst{3-0} = Rn; 3692} 3693class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops, 3694 InstrItinClass itin, string opc, string asm> 3695 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 3696 bits<4> Rd; 3697 let Inst{15-12} = 0b1111; 3698 let Inst{19-16} = Rd; 3699} 3700class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops, 3701 InstrItinClass itin, string opc, string asm> 3702 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 3703 bits<4> Ra; 3704 bits<4> Rd; 3705 let Inst{19-16} = Rd; 3706 let Inst{15-12} = Ra; 3707} 3708class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops, 3709 InstrItinClass itin, string opc, string asm> 3710 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 3711 bits<4> RdLo; 3712 bits<4> RdHi; 3713 let Inst{19-16} = RdHi; 3714 let Inst{15-12} = RdLo; 3715} 3716 3717multiclass AI_smld<bit sub, string opc> { 3718 3719 def D : AMulDualIa<0, sub, 0, (outs GPRnopc:$Rd), 3720 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3721 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">; 3722 3723 def DX: AMulDualIa<0, sub, 1, (outs GPRnopc:$Rd), 3724 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3725 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">; 3726 3727 def LD: AMulDualI64<1, sub, 0, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3728 (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary, 3729 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">; 3730 3731 def LDX : AMulDualI64<1, sub, 1, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3732 (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary, 3733 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">; 3734 3735} 3736 3737defm SMLA : AI_smld<0, "smla">; 3738defm SMLS : AI_smld<1, "smls">; 3739 3740multiclass AI_sdml<bit sub, string opc> { 3741 3742 def D:AMulDualI<0, sub, 0, (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), 3743 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">; 3744 def DX:AMulDualI<0, sub, 1, (outs GPRnopc:$Rd),(ins GPRnopc:$Rn, GPRnopc:$Rm), 3745 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">; 3746} 3747 3748defm SMUA : AI_sdml<0, "smua">; 3749defm SMUS : AI_sdml<1, "smus">; 3750 3751//===----------------------------------------------------------------------===// 3752// Misc. Arithmetic Instructions. 3753// 3754 3755def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm), 3756 IIC_iUNAr, "clz", "\t$Rd, $Rm", 3757 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>; 3758 3759def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 3760 IIC_iUNAr, "rbit", "\t$Rd, $Rm", 3761 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>, 3762 Requires<[IsARM, HasV6T2]>; 3763 3764def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 3765 IIC_iUNAr, "rev", "\t$Rd, $Rm", 3766 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>; 3767 3768let AddedComplexity = 5 in 3769def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 3770 IIC_iUNAr, "rev16", "\t$Rd, $Rm", 3771 [(set GPR:$Rd, (rotr (bswap GPR:$Rm), (i32 16)))]>, 3772 Requires<[IsARM, HasV6]>; 3773 3774let AddedComplexity = 5 in 3775def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 3776 IIC_iUNAr, "revsh", "\t$Rd, $Rm", 3777 [(set GPR:$Rd, (sra (bswap GPR:$Rm), (i32 16)))]>, 3778 Requires<[IsARM, HasV6]>; 3779 3780def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)), 3781 (and (srl GPR:$Rm, (i32 8)), 0xFF)), 3782 (REVSH GPR:$Rm)>; 3783 3784def PKHBT : APKHI<0b01101000, 0, (outs GPRnopc:$Rd), 3785 (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_lsl_amt:$sh), 3786 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", 3787 [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF), 3788 (and (shl GPRnopc:$Rm, pkh_lsl_amt:$sh), 3789 0xFFFF0000)))]>, 3790 Requires<[IsARM, HasV6]>; 3791 3792// Alternate cases for PKHBT where identities eliminate some nodes. 3793def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (and GPRnopc:$Rm, 0xFFFF0000)), 3794 (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, 0)>; 3795def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (shl GPRnopc:$Rm, imm16_31:$sh)), 3796 (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, imm16_31:$sh)>; 3797 3798// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 3799// will match the pattern below. 3800def PKHTB : APKHI<0b01101000, 1, (outs GPRnopc:$Rd), 3801 (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_asr_amt:$sh), 3802 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh", 3803 [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF0000), 3804 (and (sra GPRnopc:$Rm, pkh_asr_amt:$sh), 3805 0xFFFF)))]>, 3806 Requires<[IsARM, HasV6]>; 3807 3808// Alternate cases for PKHTB where identities eliminate some nodes. Note that 3809// a shift amount of 0 is *not legal* here, it is PKHBT instead. 3810def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 3811 (srl GPRnopc:$src2, imm16_31:$sh)), 3812 (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16_31:$sh)>; 3813def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 3814 (and (srl GPRnopc:$src2, imm1_15:$sh), 0xFFFF)), 3815 (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm1_15:$sh)>; 3816 3817//===----------------------------------------------------------------------===// 3818// Comparison Instructions... 3819// 3820 3821defm CMP : AI1_cmp_irs<0b1010, "cmp", 3822 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, 3823 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 3824 3825// ARMcmpZ can re-use the above instruction definitions. 3826def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm), 3827 (CMPri GPR:$src, so_imm:$imm)>; 3828def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs), 3829 (CMPrr GPR:$src, GPR:$rhs)>; 3830def : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs), 3831 (CMPrsi GPR:$src, so_reg_imm:$rhs)>; 3832def : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs), 3833 (CMPrsr GPR:$src, so_reg_reg:$rhs)>; 3834 3835// CMN register-integer 3836let isCompare = 1, Defs = [CPSR] in { 3837def CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, IIC_iCMPi, 3838 "cmn", "\t$Rn, $imm", 3839 [(ARMcmn GPR:$Rn, so_imm:$imm)]> { 3840 bits<4> Rn; 3841 bits<12> imm; 3842 let Inst{25} = 1; 3843 let Inst{20} = 1; 3844 let Inst{19-16} = Rn; 3845 let Inst{15-12} = 0b0000; 3846 let Inst{11-0} = imm; 3847 3848 let Unpredictable{15-12} = 0b1111; 3849} 3850 3851// CMN register-register/shift 3852def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr, 3853 "cmn", "\t$Rn, $Rm", 3854 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 3855 GPR:$Rn, GPR:$Rm)]> { 3856 bits<4> Rn; 3857 bits<4> Rm; 3858 let isCommutable = 1; 3859 let Inst{25} = 0; 3860 let Inst{20} = 1; 3861 let Inst{19-16} = Rn; 3862 let Inst{15-12} = 0b0000; 3863 let Inst{11-4} = 0b00000000; 3864 let Inst{3-0} = Rm; 3865 3866 let Unpredictable{15-12} = 0b1111; 3867} 3868 3869def CMNzrsi : AI1<0b1011, (outs), 3870 (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr, 3871 "cmn", "\t$Rn, $shift", 3872 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 3873 GPR:$Rn, so_reg_imm:$shift)]> { 3874 bits<4> Rn; 3875 bits<12> shift; 3876 let Inst{25} = 0; 3877 let Inst{20} = 1; 3878 let Inst{19-16} = Rn; 3879 let Inst{15-12} = 0b0000; 3880 let Inst{11-5} = shift{11-5}; 3881 let Inst{4} = 0; 3882 let Inst{3-0} = shift{3-0}; 3883 3884 let Unpredictable{15-12} = 0b1111; 3885} 3886 3887def CMNzrsr : AI1<0b1011, (outs), 3888 (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr, 3889 "cmn", "\t$Rn, $shift", 3890 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 3891 GPRnopc:$Rn, so_reg_reg:$shift)]> { 3892 bits<4> Rn; 3893 bits<12> shift; 3894 let Inst{25} = 0; 3895 let Inst{20} = 1; 3896 let Inst{19-16} = Rn; 3897 let Inst{15-12} = 0b0000; 3898 let Inst{11-8} = shift{11-8}; 3899 let Inst{7} = 0; 3900 let Inst{6-5} = shift{6-5}; 3901 let Inst{4} = 1; 3902 let Inst{3-0} = shift{3-0}; 3903 3904 let Unpredictable{15-12} = 0b1111; 3905} 3906 3907} 3908 3909def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), 3910 (CMNri GPR:$src, so_imm_neg:$imm)>; 3911 3912def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm), 3913 (CMNri GPR:$src, so_imm_neg:$imm)>; 3914 3915// Note that TST/TEQ don't set all the same flags that CMP does! 3916defm TST : AI1_cmp_irs<0b1000, "tst", 3917 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 3918 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>; 3919defm TEQ : AI1_cmp_irs<0b1001, "teq", 3920 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 3921 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>; 3922 3923// Pseudo i64 compares for some floating point compares. 3924let usesCustomInserter = 1, isBranch = 1, isTerminator = 1, 3925 Defs = [CPSR] in { 3926def BCCi64 : PseudoInst<(outs), 3927 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst), 3928 IIC_Br, 3929 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>; 3930 3931def BCCZi64 : PseudoInst<(outs), 3932 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, 3933 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>; 3934} // usesCustomInserter 3935 3936 3937// Conditional moves 3938// FIXME: should be able to write a pattern for ARMcmov, but can't use 3939// a two-value operand where a dag node expects two operands. :( 3940let neverHasSideEffects = 1 in { 3941 3942let isCommutable = 1, isSelect = 1 in 3943def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$false, GPR:$Rm, pred:$p), 3944 4, IIC_iCMOVr, 3945 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>, 3946 RegConstraint<"$false = $Rd">; 3947 3948def MOVCCsi : ARMPseudoInst<(outs GPR:$Rd), 3949 (ins GPR:$false, so_reg_imm:$shift, pred:$p), 3950 4, IIC_iCMOVsr, 3951 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_imm:$shift, 3952 imm:$cc, CCR:$ccr))*/]>, 3953 RegConstraint<"$false = $Rd">; 3954def MOVCCsr : ARMPseudoInst<(outs GPR:$Rd), 3955 (ins GPR:$false, so_reg_reg:$shift, pred:$p), 3956 4, IIC_iCMOVsr, 3957 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift, 3958 imm:$cc, CCR:$ccr))*/]>, 3959 RegConstraint<"$false = $Rd">; 3960 3961 3962let isMoveImm = 1 in 3963def MOVCCi16 : ARMPseudoInst<(outs GPR:$Rd), 3964 (ins GPR:$false, imm0_65535_expr:$imm, pred:$p), 3965 4, IIC_iMOVi, 3966 []>, 3967 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>; 3968 3969let isMoveImm = 1 in 3970def MOVCCi : ARMPseudoInst<(outs GPR:$Rd), 3971 (ins GPR:$false, so_imm:$imm, pred:$p), 3972 4, IIC_iCMOVi, 3973 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>, 3974 RegConstraint<"$false = $Rd">; 3975 3976// Two instruction predicate mov immediate. 3977let isMoveImm = 1 in 3978def MOVCCi32imm : ARMPseudoInst<(outs GPR:$Rd), 3979 (ins GPR:$false, i32imm:$src, pred:$p), 3980 8, IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">; 3981 3982let isMoveImm = 1 in 3983def MVNCCi : ARMPseudoInst<(outs GPR:$Rd), 3984 (ins GPR:$false, so_imm:$imm, pred:$p), 3985 4, IIC_iCMOVi, 3986 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>, 3987 RegConstraint<"$false = $Rd">; 3988 3989// Conditional instructions 3990multiclass AsI1_bincc_irs<Instruction iri, Instruction irr, Instruction irsi, 3991 Instruction irsr, 3992 InstrItinClass iii, InstrItinClass iir, 3993 InstrItinClass iis> { 3994 def ri : ARMPseudoExpand<(outs GPR:$Rd), 3995 (ins GPR:$Rfalse, GPR:$Rn, so_imm:$imm, 3996 pred:$p, cc_out:$s), 3997 4, iii, [], 3998 (iri GPR:$Rd, GPR:$Rn, so_imm:$imm, pred:$p, cc_out:$s)>, 3999 RegConstraint<"$Rfalse = $Rd">; 4000 def rr : ARMPseudoExpand<(outs GPR:$Rd), 4001 (ins GPR:$Rfalse, GPR:$Rn, GPR:$Rm, 4002 pred:$p, cc_out:$s), 4003 4, iir, [], 4004 (irr GPR:$Rd, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 4005 RegConstraint<"$Rfalse = $Rd">; 4006 def rsi : ARMPseudoExpand<(outs GPR:$Rd), 4007 (ins GPR:$Rfalse, GPR:$Rn, so_reg_imm:$shift, 4008 pred:$p, cc_out:$s), 4009 4, iis, [], 4010 (irsi GPR:$Rd, GPR:$Rn, so_reg_imm:$shift, pred:$p, cc_out:$s)>, 4011 RegConstraint<"$Rfalse = $Rd">; 4012 def rsr : ARMPseudoExpand<(outs GPRnopc:$Rd), 4013 (ins GPRnopc:$Rfalse, GPRnopc:$Rn, so_reg_reg:$shift, 4014 pred:$p, cc_out:$s), 4015 4, iis, [], 4016 (irsr GPR:$Rd, GPR:$Rn, so_reg_reg:$shift, pred:$p, cc_out:$s)>, 4017 RegConstraint<"$Rfalse = $Rd">; 4018} 4019 4020defm ANDCC : AsI1_bincc_irs<ANDri, ANDrr, ANDrsi, ANDrsr, 4021 IIC_iBITi, IIC_iBITr, IIC_iBITsr>; 4022defm ORRCC : AsI1_bincc_irs<ORRri, ORRrr, ORRrsi, ORRrsr, 4023 IIC_iBITi, IIC_iBITr, IIC_iBITsr>; 4024defm EORCC : AsI1_bincc_irs<EORri, EORrr, EORrsi, EORrsr, 4025 IIC_iBITi, IIC_iBITr, IIC_iBITsr>; 4026defm ADDCC : AsI1_bincc_irs<ADDri, ADDrr, ADDrsi, ADDrsr, 4027 IIC_iBITi, IIC_iBITr, IIC_iBITsr>; 4028defm SUBCC : AsI1_bincc_irs<SUBri, SUBrr, SUBrsi, SUBrsr, 4029 IIC_iBITi, IIC_iBITr, IIC_iBITsr>; 4030 4031} // neverHasSideEffects 4032 4033 4034//===----------------------------------------------------------------------===// 4035// Atomic operations intrinsics 4036// 4037 4038def MemBarrierOptOperand : AsmOperandClass { 4039 let Name = "MemBarrierOpt"; 4040 let ParserMethod = "parseMemBarrierOptOperand"; 4041} 4042def memb_opt : Operand<i32> { 4043 let PrintMethod = "printMemBOption"; 4044 let ParserMatchClass = MemBarrierOptOperand; 4045 let DecoderMethod = "DecodeMemBarrierOption"; 4046} 4047 4048// memory barriers protect the atomic sequences 4049let hasSideEffects = 1 in { 4050def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 4051 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>, 4052 Requires<[IsARM, HasDB]> { 4053 bits<4> opt; 4054 let Inst{31-4} = 0xf57ff05; 4055 let Inst{3-0} = opt; 4056} 4057} 4058 4059def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 4060 "dsb", "\t$opt", []>, 4061 Requires<[IsARM, HasDB]> { 4062 bits<4> opt; 4063 let Inst{31-4} = 0xf57ff04; 4064 let Inst{3-0} = opt; 4065} 4066 4067// ISB has only full system option 4068def ISB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 4069 "isb", "\t$opt", []>, 4070 Requires<[IsARM, HasDB]> { 4071 bits<4> opt; 4072 let Inst{31-4} = 0xf57ff06; 4073 let Inst{3-0} = opt; 4074} 4075 4076// Pseudo instruction that combines movs + predicated rsbmi 4077// to implement integer ABS 4078let usesCustomInserter = 1, Defs = [CPSR] in 4079def ABS : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$src), 8, NoItinerary, []>; 4080 4081let usesCustomInserter = 1 in { 4082 let Defs = [CPSR] in { 4083 def ATOMIC_LOAD_ADD_I8 : PseudoInst< 4084 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4085 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>; 4086 def ATOMIC_LOAD_SUB_I8 : PseudoInst< 4087 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4088 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>; 4089 def ATOMIC_LOAD_AND_I8 : PseudoInst< 4090 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4091 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>; 4092 def ATOMIC_LOAD_OR_I8 : PseudoInst< 4093 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4094 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>; 4095 def ATOMIC_LOAD_XOR_I8 : PseudoInst< 4096 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4097 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>; 4098 def ATOMIC_LOAD_NAND_I8 : PseudoInst< 4099 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4100 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>; 4101 def ATOMIC_LOAD_MIN_I8 : PseudoInst< 4102 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4103 [(set GPR:$dst, (atomic_load_min_8 GPR:$ptr, GPR:$val))]>; 4104 def ATOMIC_LOAD_MAX_I8 : PseudoInst< 4105 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4106 [(set GPR:$dst, (atomic_load_max_8 GPR:$ptr, GPR:$val))]>; 4107 def ATOMIC_LOAD_UMIN_I8 : PseudoInst< 4108 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4109 [(set GPR:$dst, (atomic_load_umin_8 GPR:$ptr, GPR:$val))]>; 4110 def ATOMIC_LOAD_UMAX_I8 : PseudoInst< 4111 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4112 [(set GPR:$dst, (atomic_load_umax_8 GPR:$ptr, GPR:$val))]>; 4113 def ATOMIC_LOAD_ADD_I16 : PseudoInst< 4114 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4115 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>; 4116 def ATOMIC_LOAD_SUB_I16 : PseudoInst< 4117 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4118 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>; 4119 def ATOMIC_LOAD_AND_I16 : PseudoInst< 4120 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4121 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>; 4122 def ATOMIC_LOAD_OR_I16 : PseudoInst< 4123 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4124 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>; 4125 def ATOMIC_LOAD_XOR_I16 : PseudoInst< 4126 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4127 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>; 4128 def ATOMIC_LOAD_NAND_I16 : PseudoInst< 4129 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4130 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>; 4131 def ATOMIC_LOAD_MIN_I16 : PseudoInst< 4132 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4133 [(set GPR:$dst, (atomic_load_min_16 GPR:$ptr, GPR:$val))]>; 4134 def ATOMIC_LOAD_MAX_I16 : PseudoInst< 4135 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4136 [(set GPR:$dst, (atomic_load_max_16 GPR:$ptr, GPR:$val))]>; 4137 def ATOMIC_LOAD_UMIN_I16 : PseudoInst< 4138 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4139 [(set GPR:$dst, (atomic_load_umin_16 GPR:$ptr, GPR:$val))]>; 4140 def ATOMIC_LOAD_UMAX_I16 : PseudoInst< 4141 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4142 [(set GPR:$dst, (atomic_load_umax_16 GPR:$ptr, GPR:$val))]>; 4143 def ATOMIC_LOAD_ADD_I32 : PseudoInst< 4144 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4145 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>; 4146 def ATOMIC_LOAD_SUB_I32 : PseudoInst< 4147 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4148 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>; 4149 def ATOMIC_LOAD_AND_I32 : PseudoInst< 4150 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4151 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>; 4152 def ATOMIC_LOAD_OR_I32 : PseudoInst< 4153 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4154 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>; 4155 def ATOMIC_LOAD_XOR_I32 : PseudoInst< 4156 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4157 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>; 4158 def ATOMIC_LOAD_NAND_I32 : PseudoInst< 4159 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 4160 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>; 4161 def ATOMIC_LOAD_MIN_I32 : PseudoInst< 4162 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4163 [(set GPR:$dst, (atomic_load_min_32 GPR:$ptr, GPR:$val))]>; 4164 def ATOMIC_LOAD_MAX_I32 : PseudoInst< 4165 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4166 [(set GPR:$dst, (atomic_load_max_32 GPR:$ptr, GPR:$val))]>; 4167 def ATOMIC_LOAD_UMIN_I32 : PseudoInst< 4168 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4169 [(set GPR:$dst, (atomic_load_umin_32 GPR:$ptr, GPR:$val))]>; 4170 def ATOMIC_LOAD_UMAX_I32 : PseudoInst< 4171 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 4172 [(set GPR:$dst, (atomic_load_umax_32 GPR:$ptr, GPR:$val))]>; 4173 4174 def ATOMIC_SWAP_I8 : PseudoInst< 4175 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 4176 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>; 4177 def ATOMIC_SWAP_I16 : PseudoInst< 4178 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 4179 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>; 4180 def ATOMIC_SWAP_I32 : PseudoInst< 4181 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 4182 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>; 4183 4184 def ATOMIC_CMP_SWAP_I8 : PseudoInst< 4185 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 4186 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>; 4187 def ATOMIC_CMP_SWAP_I16 : PseudoInst< 4188 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 4189 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>; 4190 def ATOMIC_CMP_SWAP_I32 : PseudoInst< 4191 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 4192 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>; 4193} 4194} 4195 4196let usesCustomInserter = 1 in { 4197 def COPY_STRUCT_BYVAL_I32 : PseudoInst< 4198 (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment), 4199 NoItinerary, 4200 [(ARMcopystructbyval GPR:$dst, GPR:$src, imm:$size, imm:$alignment)]>; 4201} 4202 4203let mayLoad = 1 in { 4204def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4205 NoItinerary, 4206 "ldrexb", "\t$Rt, $addr", []>; 4207def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4208 NoItinerary, "ldrexh", "\t$Rt, $addr", []>; 4209def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4210 NoItinerary, "ldrex", "\t$Rt, $addr", []>; 4211let hasExtraDefRegAllocReq = 1 in 4212def LDREXD: AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2),(ins addr_offset_none:$addr), 4213 NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []> { 4214 let DecoderMethod = "DecodeDoubleRegLoad"; 4215} 4216} 4217 4218let mayStore = 1, Constraints = "@earlyclobber $Rd" in { 4219def STREXB: AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4220 NoItinerary, "strexb", "\t$Rd, $Rt, $addr", []>; 4221def STREXH: AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4222 NoItinerary, "strexh", "\t$Rd, $Rt, $addr", []>; 4223def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4224 NoItinerary, "strex", "\t$Rd, $Rt, $addr", []>; 4225let hasExtraSrcRegAllocReq = 1 in 4226def STREXD : AIstrex<0b01, (outs GPR:$Rd), 4227 (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr), 4228 NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []> { 4229 let DecoderMethod = "DecodeDoubleRegStore"; 4230} 4231} 4232 4233 4234def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", []>, 4235 Requires<[IsARM, HasV7]> { 4236 let Inst{31-0} = 0b11110101011111111111000000011111; 4237} 4238 4239// SWP/SWPB are deprecated in V6/V7. 4240let mayLoad = 1, mayStore = 1 in { 4241def SWP : AIswp<0, (outs GPRnopc:$Rt), 4242 (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swp", []>; 4243def SWPB: AIswp<1, (outs GPRnopc:$Rt), 4244 (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swpb", []>; 4245} 4246 4247//===----------------------------------------------------------------------===// 4248// Coprocessor Instructions. 4249// 4250 4251def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 4252 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 4253 NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 4254 [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 4255 imm:$CRm, imm:$opc2)]> { 4256 bits<4> opc1; 4257 bits<4> CRn; 4258 bits<4> CRd; 4259 bits<4> cop; 4260 bits<3> opc2; 4261 bits<4> CRm; 4262 4263 let Inst{3-0} = CRm; 4264 let Inst{4} = 0; 4265 let Inst{7-5} = opc2; 4266 let Inst{11-8} = cop; 4267 let Inst{15-12} = CRd; 4268 let Inst{19-16} = CRn; 4269 let Inst{23-20} = opc1; 4270} 4271 4272def CDP2 : ABXI<0b1110, (outs), (ins pf_imm:$cop, imm0_15:$opc1, 4273 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 4274 NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 4275 [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 4276 imm:$CRm, imm:$opc2)]> { 4277 let Inst{31-28} = 0b1111; 4278 bits<4> opc1; 4279 bits<4> CRn; 4280 bits<4> CRd; 4281 bits<4> cop; 4282 bits<3> opc2; 4283 bits<4> CRm; 4284 4285 let Inst{3-0} = CRm; 4286 let Inst{4} = 0; 4287 let Inst{7-5} = opc2; 4288 let Inst{11-8} = cop; 4289 let Inst{15-12} = CRd; 4290 let Inst{19-16} = CRn; 4291 let Inst{23-20} = opc1; 4292} 4293 4294class ACI<dag oops, dag iops, string opc, string asm, 4295 IndexMode im = IndexModeNone> 4296 : I<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary, 4297 opc, asm, "", []> { 4298 let Inst{27-25} = 0b110; 4299} 4300class ACInoP<dag oops, dag iops, string opc, string asm, 4301 IndexMode im = IndexModeNone> 4302 : InoP<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary, 4303 opc, asm, "", []> { 4304 let Inst{31-28} = 0b1111; 4305 let Inst{27-25} = 0b110; 4306} 4307multiclass LdStCop<bit load, bit Dbit, string asm> { 4308 def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 4309 asm, "\t$cop, $CRd, $addr"> { 4310 bits<13> addr; 4311 bits<4> cop; 4312 bits<4> CRd; 4313 let Inst{24} = 1; // P = 1 4314 let Inst{23} = addr{8}; 4315 let Inst{22} = Dbit; 4316 let Inst{21} = 0; // W = 0 4317 let Inst{20} = load; 4318 let Inst{19-16} = addr{12-9}; 4319 let Inst{15-12} = CRd; 4320 let Inst{11-8} = cop; 4321 let Inst{7-0} = addr{7-0}; 4322 let DecoderMethod = "DecodeCopMemInstruction"; 4323 } 4324 def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 4325 asm, "\t$cop, $CRd, $addr!", IndexModePre> { 4326 bits<13> addr; 4327 bits<4> cop; 4328 bits<4> CRd; 4329 let Inst{24} = 1; // P = 1 4330 let Inst{23} = addr{8}; 4331 let Inst{22} = Dbit; 4332 let Inst{21} = 1; // W = 1 4333 let Inst{20} = load; 4334 let Inst{19-16} = addr{12-9}; 4335 let Inst{15-12} = CRd; 4336 let Inst{11-8} = cop; 4337 let Inst{7-0} = addr{7-0}; 4338 let DecoderMethod = "DecodeCopMemInstruction"; 4339 } 4340 def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 4341 postidx_imm8s4:$offset), 4342 asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> { 4343 bits<9> offset; 4344 bits<4> addr; 4345 bits<4> cop; 4346 bits<4> CRd; 4347 let Inst{24} = 0; // P = 0 4348 let Inst{23} = offset{8}; 4349 let Inst{22} = Dbit; 4350 let Inst{21} = 1; // W = 1 4351 let Inst{20} = load; 4352 let Inst{19-16} = addr; 4353 let Inst{15-12} = CRd; 4354 let Inst{11-8} = cop; 4355 let Inst{7-0} = offset{7-0}; 4356 let DecoderMethod = "DecodeCopMemInstruction"; 4357 } 4358 def _OPTION : ACI<(outs), 4359 (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 4360 coproc_option_imm:$option), 4361 asm, "\t$cop, $CRd, $addr, $option"> { 4362 bits<8> option; 4363 bits<4> addr; 4364 bits<4> cop; 4365 bits<4> CRd; 4366 let Inst{24} = 0; // P = 0 4367 let Inst{23} = 1; // U = 1 4368 let Inst{22} = Dbit; 4369 let Inst{21} = 0; // W = 0 4370 let Inst{20} = load; 4371 let Inst{19-16} = addr; 4372 let Inst{15-12} = CRd; 4373 let Inst{11-8} = cop; 4374 let Inst{7-0} = option; 4375 let DecoderMethod = "DecodeCopMemInstruction"; 4376 } 4377} 4378multiclass LdSt2Cop<bit load, bit Dbit, string asm> { 4379 def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 4380 asm, "\t$cop, $CRd, $addr"> { 4381 bits<13> addr; 4382 bits<4> cop; 4383 bits<4> CRd; 4384 let Inst{24} = 1; // P = 1 4385 let Inst{23} = addr{8}; 4386 let Inst{22} = Dbit; 4387 let Inst{21} = 0; // W = 0 4388 let Inst{20} = load; 4389 let Inst{19-16} = addr{12-9}; 4390 let Inst{15-12} = CRd; 4391 let Inst{11-8} = cop; 4392 let Inst{7-0} = addr{7-0}; 4393 let DecoderMethod = "DecodeCopMemInstruction"; 4394 } 4395 def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 4396 asm, "\t$cop, $CRd, $addr!", IndexModePre> { 4397 bits<13> addr; 4398 bits<4> cop; 4399 bits<4> CRd; 4400 let Inst{24} = 1; // P = 1 4401 let Inst{23} = addr{8}; 4402 let Inst{22} = Dbit; 4403 let Inst{21} = 1; // W = 1 4404 let Inst{20} = load; 4405 let Inst{19-16} = addr{12-9}; 4406 let Inst{15-12} = CRd; 4407 let Inst{11-8} = cop; 4408 let Inst{7-0} = addr{7-0}; 4409 let DecoderMethod = "DecodeCopMemInstruction"; 4410 } 4411 def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 4412 postidx_imm8s4:$offset), 4413 asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> { 4414 bits<9> offset; 4415 bits<4> addr; 4416 bits<4> cop; 4417 bits<4> CRd; 4418 let Inst{24} = 0; // P = 0 4419 let Inst{23} = offset{8}; 4420 let Inst{22} = Dbit; 4421 let Inst{21} = 1; // W = 1 4422 let Inst{20} = load; 4423 let Inst{19-16} = addr; 4424 let Inst{15-12} = CRd; 4425 let Inst{11-8} = cop; 4426 let Inst{7-0} = offset{7-0}; 4427 let DecoderMethod = "DecodeCopMemInstruction"; 4428 } 4429 def _OPTION : ACInoP<(outs), 4430 (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 4431 coproc_option_imm:$option), 4432 asm, "\t$cop, $CRd, $addr, $option"> { 4433 bits<8> option; 4434 bits<4> addr; 4435 bits<4> cop; 4436 bits<4> CRd; 4437 let Inst{24} = 0; // P = 0 4438 let Inst{23} = 1; // U = 1 4439 let Inst{22} = Dbit; 4440 let Inst{21} = 0; // W = 0 4441 let Inst{20} = load; 4442 let Inst{19-16} = addr; 4443 let Inst{15-12} = CRd; 4444 let Inst{11-8} = cop; 4445 let Inst{7-0} = option; 4446 let DecoderMethod = "DecodeCopMemInstruction"; 4447 } 4448} 4449 4450defm LDC : LdStCop <1, 0, "ldc">; 4451defm LDCL : LdStCop <1, 1, "ldcl">; 4452defm STC : LdStCop <0, 0, "stc">; 4453defm STCL : LdStCop <0, 1, "stcl">; 4454defm LDC2 : LdSt2Cop<1, 0, "ldc2">; 4455defm LDC2L : LdSt2Cop<1, 1, "ldc2l">; 4456defm STC2 : LdSt2Cop<0, 0, "stc2">; 4457defm STC2L : LdSt2Cop<0, 1, "stc2l">; 4458 4459//===----------------------------------------------------------------------===// 4460// Move between coprocessor and ARM core register. 4461// 4462 4463class MovRCopro<string opc, bit direction, dag oops, dag iops, 4464 list<dag> pattern> 4465 : ABI<0b1110, oops, iops, NoItinerary, opc, 4466 "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", pattern> { 4467 let Inst{20} = direction; 4468 let Inst{4} = 1; 4469 4470 bits<4> Rt; 4471 bits<4> cop; 4472 bits<3> opc1; 4473 bits<3> opc2; 4474 bits<4> CRm; 4475 bits<4> CRn; 4476 4477 let Inst{15-12} = Rt; 4478 let Inst{11-8} = cop; 4479 let Inst{23-21} = opc1; 4480 let Inst{7-5} = opc2; 4481 let Inst{3-0} = CRm; 4482 let Inst{19-16} = CRn; 4483} 4484 4485def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */, 4486 (outs), 4487 (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4488 c_imm:$CRm, imm0_7:$opc2), 4489 [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 4490 imm:$CRm, imm:$opc2)]>; 4491def : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm", 4492 (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4493 c_imm:$CRm, 0, pred:$p)>; 4494def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */, 4495 (outs GPR:$Rt), 4496 (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 4497 imm0_7:$opc2), []>; 4498def : ARMInstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm", 4499 (MRC GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 4500 c_imm:$CRm, 0, pred:$p)>; 4501 4502def : ARMPat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), 4503 (MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 4504 4505class MovRCopro2<string opc, bit direction, dag oops, dag iops, 4506 list<dag> pattern> 4507 : ABXI<0b1110, oops, iops, NoItinerary, 4508 !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), pattern> { 4509 let Inst{31-28} = 0b1111; 4510 let Inst{20} = direction; 4511 let Inst{4} = 1; 4512 4513 bits<4> Rt; 4514 bits<4> cop; 4515 bits<3> opc1; 4516 bits<3> opc2; 4517 bits<4> CRm; 4518 bits<4> CRn; 4519 4520 let Inst{15-12} = Rt; 4521 let Inst{11-8} = cop; 4522 let Inst{23-21} = opc1; 4523 let Inst{7-5} = opc2; 4524 let Inst{3-0} = CRm; 4525 let Inst{19-16} = CRn; 4526} 4527 4528def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */, 4529 (outs), 4530 (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4531 c_imm:$CRm, imm0_7:$opc2), 4532 [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 4533 imm:$CRm, imm:$opc2)]>; 4534def : ARMInstAlias<"mcr2$ $cop, $opc1, $Rt, $CRn, $CRm", 4535 (MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4536 c_imm:$CRm, 0)>; 4537def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */, 4538 (outs GPR:$Rt), 4539 (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 4540 imm0_7:$opc2), []>; 4541def : ARMInstAlias<"mrc2$ $cop, $opc1, $Rt, $CRn, $CRm", 4542 (MRC2 GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 4543 c_imm:$CRm, 0)>; 4544 4545def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, 4546 imm:$CRm, imm:$opc2), 4547 (MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 4548 4549class MovRRCopro<string opc, bit direction, list<dag> pattern = []> 4550 : ABI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, 4551 GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), 4552 NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { 4553 let Inst{23-21} = 0b010; 4554 let Inst{20} = direction; 4555 4556 bits<4> Rt; 4557 bits<4> Rt2; 4558 bits<4> cop; 4559 bits<4> opc1; 4560 bits<4> CRm; 4561 4562 let Inst{15-12} = Rt; 4563 let Inst{19-16} = Rt2; 4564 let Inst{11-8} = cop; 4565 let Inst{7-4} = opc1; 4566 let Inst{3-0} = CRm; 4567} 4568 4569def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, 4570 [(int_arm_mcrr imm:$cop, imm:$opc1, GPRnopc:$Rt, 4571 GPRnopc:$Rt2, imm:$CRm)]>; 4572def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>; 4573 4574class MovRRCopro2<string opc, bit direction, list<dag> pattern = []> 4575 : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, 4576 GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary, 4577 !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> { 4578 let Inst{31-28} = 0b1111; 4579 let Inst{23-21} = 0b010; 4580 let Inst{20} = direction; 4581 4582 bits<4> Rt; 4583 bits<4> Rt2; 4584 bits<4> cop; 4585 bits<4> opc1; 4586 bits<4> CRm; 4587 4588 let Inst{15-12} = Rt; 4589 let Inst{19-16} = Rt2; 4590 let Inst{11-8} = cop; 4591 let Inst{7-4} = opc1; 4592 let Inst{3-0} = CRm; 4593 4594 let DecoderMethod = "DecodeMRRC2"; 4595} 4596 4597def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */, 4598 [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPRnopc:$Rt, 4599 GPRnopc:$Rt2, imm:$CRm)]>; 4600def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>; 4601 4602//===----------------------------------------------------------------------===// 4603// Move between special register and ARM core register 4604// 4605 4606// Move to ARM core register from Special Register 4607def MRS : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, 4608 "mrs", "\t$Rd, apsr", []> { 4609 bits<4> Rd; 4610 let Inst{23-16} = 0b00001111; 4611 let Unpredictable{19-17} = 0b111; 4612 4613 let Inst{15-12} = Rd; 4614 4615 let Inst{11-0} = 0b000000000000; 4616 let Unpredictable{11-0} = 0b110100001111; 4617} 4618 4619def : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPRnopc:$Rd, pred:$p)>, 4620 Requires<[IsARM]>; 4621 4622// The MRSsys instruction is the MRS instruction from the ARM ARM, 4623// section B9.3.9, with the R bit set to 1. 4624def MRSsys : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, 4625 "mrs", "\t$Rd, spsr", []> { 4626 bits<4> Rd; 4627 let Inst{23-16} = 0b01001111; 4628 let Unpredictable{19-16} = 0b1111; 4629 4630 let Inst{15-12} = Rd; 4631 4632 let Inst{11-0} = 0b000000000000; 4633 let Unpredictable{11-0} = 0b110100001111; 4634} 4635 4636// Move from ARM core register to Special Register 4637// 4638// No need to have both system and application versions, the encodings are the 4639// same and the assembly parser has no way to distinguish between them. The mask 4640// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains 4641// the mask with the fields to be accessed in the special register. 4642def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary, 4643 "msr", "\t$mask, $Rn", []> { 4644 bits<5> mask; 4645 bits<4> Rn; 4646 4647 let Inst{23} = 0; 4648 let Inst{22} = mask{4}; // R bit 4649 let Inst{21-20} = 0b10; 4650 let Inst{19-16} = mask{3-0}; 4651 let Inst{15-12} = 0b1111; 4652 let Inst{11-4} = 0b00000000; 4653 let Inst{3-0} = Rn; 4654} 4655 4656def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, so_imm:$a), NoItinerary, 4657 "msr", "\t$mask, $a", []> { 4658 bits<5> mask; 4659 bits<12> a; 4660 4661 let Inst{23} = 0; 4662 let Inst{22} = mask{4}; // R bit 4663 let Inst{21-20} = 0b10; 4664 let Inst{19-16} = mask{3-0}; 4665 let Inst{15-12} = 0b1111; 4666 let Inst{11-0} = a; 4667} 4668 4669//===----------------------------------------------------------------------===// 4670// TLS Instructions 4671// 4672 4673// __aeabi_read_tp preserves the registers r1-r3. 4674// This is a pseudo inst so that we can get the encoding right, 4675// complete with fixup for the aeabi_read_tp function. 4676let isCall = 1, 4677 Defs = [R0, R12, LR, CPSR], Uses = [SP] in { 4678 def TPsoft : PseudoInst<(outs), (ins), IIC_Br, 4679 [(set R0, ARMthread_pointer)]>; 4680} 4681 4682//===----------------------------------------------------------------------===// 4683// SJLJ Exception handling intrinsics 4684// eh_sjlj_setjmp() is an instruction sequence to store the return 4685// address and save #0 in R0 for the non-longjmp case. 4686// Since by its nature we may be coming from some other function to get 4687// here, and we're using the stack frame for the containing function to 4688// save/restore registers, we can't keep anything live in regs across 4689// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 4690// when we get here from a longjmp(). We force everything out of registers 4691// except for our own input by listing the relevant registers in Defs. By 4692// doing so, we also cause the prologue/epilogue code to actively preserve 4693// all of the callee-saved resgisters, which is exactly what we want. 4694// A constant value is passed in $val, and we use the location as a scratch. 4695// 4696// These are pseudo-instructions and are lowered to individual MC-insts, so 4697// no encoding information is necessary. 4698let Defs = 4699 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, 4700 Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ], 4701 hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in { 4702 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 4703 NoItinerary, 4704 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 4705 Requires<[IsARM, HasVFP2]>; 4706} 4707 4708let Defs = 4709 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], 4710 hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in { 4711 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 4712 NoItinerary, 4713 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 4714 Requires<[IsARM, NoVFP]>; 4715} 4716 4717// FIXME: Non-IOS version(s) 4718let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, 4719 Defs = [ R7, LR, SP ] in { 4720def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch), 4721 NoItinerary, 4722 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, 4723 Requires<[IsARM, IsIOS]>; 4724} 4725 4726// eh.sjlj.dispatchsetup pseudo-instructions. 4727// These pseudos are used for both ARM and Thumb2. Any differences are 4728// handled when the pseudo is expanded (which happens before any passes 4729// that need the instruction size). 4730let Defs = 4731 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, 4732 Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ], 4733 isBarrier = 1 in 4734def Int_eh_sjlj_dispatchsetup : PseudoInst<(outs), (ins), NoItinerary, []>; 4735 4736let Defs = 4737 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], 4738 isBarrier = 1 in 4739def Int_eh_sjlj_dispatchsetup_nofp : PseudoInst<(outs), (ins), NoItinerary, []>; 4740 4741 4742//===----------------------------------------------------------------------===// 4743// Non-Instruction Patterns 4744// 4745 4746// ARMv4 indirect branch using (MOVr PC, dst) 4747let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in 4748 def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst), 4749 4, IIC_Br, [(brind GPR:$dst)], 4750 (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, 4751 Requires<[IsARM, NoV4T]>; 4752 4753// Large immediate handling. 4754 4755// 32-bit immediate using two piece so_imms or movw + movt. 4756// This is a single pseudo instruction, the benefit is that it can be remat'd 4757// as a single unit instead of having to handle reg inputs. 4758// FIXME: Remove this when we can do generalized remat. 4759let isReMaterializable = 1, isMoveImm = 1 in 4760def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 4761 [(set GPR:$dst, (arm_i32imm:$src))]>, 4762 Requires<[IsARM]>; 4763 4764// Pseudo instruction that combines movw + movt + add pc (if PIC). 4765// It also makes it possible to rematerialize the instructions. 4766// FIXME: Remove this when we can do generalized remat and when machine licm 4767// can properly the instructions. 4768let isReMaterializable = 1 in { 4769def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 4770 IIC_iMOVix2addpc, 4771 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, 4772 Requires<[IsARM, UseMovt]>; 4773 4774def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 4775 IIC_iMOVix2, 4776 [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>, 4777 Requires<[IsARM, UseMovt]>; 4778 4779let AddedComplexity = 10 in 4780def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 4781 IIC_iMOVix2ld, 4782 [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, 4783 Requires<[IsARM, UseMovt]>; 4784} // isReMaterializable 4785 4786// ConstantPool, GlobalAddress, and JumpTable 4787def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>, 4788 Requires<[IsARM, DontUseMovt]>; 4789def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; 4790def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>, 4791 Requires<[IsARM, UseMovt]>; 4792def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), 4793 (LEApcrelJT tjumptable:$dst, imm:$id)>; 4794 4795// TODO: add,sub,and, 3-instr forms? 4796 4797// Tail calls. These patterns also apply to Thumb mode. 4798def : Pat<(ARMtcret tcGPR:$dst), (TCRETURNri tcGPR:$dst)>; 4799def : Pat<(ARMtcret (i32 tglobaladdr:$dst)), (TCRETURNdi texternalsym:$dst)>; 4800def : Pat<(ARMtcret (i32 texternalsym:$dst)), (TCRETURNdi texternalsym:$dst)>; 4801 4802// Direct calls 4803def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>; 4804def : ARMPat<(ARMcall_nolink texternalsym:$func), 4805 (BMOVPCB_CALL texternalsym:$func)>; 4806 4807// zextload i1 -> zextload i8 4808def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 4809def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 4810 4811// extload -> zextload 4812def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 4813def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 4814def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 4815def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 4816 4817def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; 4818 4819def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; 4820def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>; 4821 4822// smul* and smla* 4823def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 4824 (sra (shl GPR:$b, (i32 16)), (i32 16))), 4825 (SMULBB GPR:$a, GPR:$b)>; 4826def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b), 4827 (SMULBB GPR:$a, GPR:$b)>; 4828def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 4829 (sra GPR:$b, (i32 16))), 4830 (SMULBT GPR:$a, GPR:$b)>; 4831def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))), 4832 (SMULBT GPR:$a, GPR:$b)>; 4833def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), 4834 (sra (shl GPR:$b, (i32 16)), (i32 16))), 4835 (SMULTB GPR:$a, GPR:$b)>; 4836def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b), 4837 (SMULTB GPR:$a, GPR:$b)>; 4838def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 4839 (i32 16)), 4840 (SMULWB GPR:$a, GPR:$b)>; 4841def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)), 4842 (SMULWB GPR:$a, GPR:$b)>; 4843 4844def : ARMV5TEPat<(add GPR:$acc, 4845 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 4846 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 4847 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 4848def : ARMV5TEPat<(add GPR:$acc, 4849 (mul sext_16_node:$a, sext_16_node:$b)), 4850 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 4851def : ARMV5TEPat<(add GPR:$acc, 4852 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 4853 (sra GPR:$b, (i32 16)))), 4854 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 4855def : ARMV5TEPat<(add GPR:$acc, 4856 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))), 4857 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 4858def : ARMV5TEPat<(add GPR:$acc, 4859 (mul (sra GPR:$a, (i32 16)), 4860 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 4861 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 4862def : ARMV5TEPat<(add GPR:$acc, 4863 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)), 4864 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 4865def : ARMV5TEPat<(add GPR:$acc, 4866 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 4867 (i32 16))), 4868 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 4869def : ARMV5TEPat<(add GPR:$acc, 4870 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))), 4871 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 4872 4873 4874// Pre-v7 uses MCR for synchronization barriers. 4875def : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>, 4876 Requires<[IsARM, HasV6]>; 4877 4878// SXT/UXT with no rotate 4879let AddedComplexity = 16 in { 4880def : ARMV6Pat<(and GPR:$Src, 0x000000FF), (UXTB GPR:$Src, 0)>; 4881def : ARMV6Pat<(and GPR:$Src, 0x0000FFFF), (UXTH GPR:$Src, 0)>; 4882def : ARMV6Pat<(and GPR:$Src, 0x00FF00FF), (UXTB16 GPR:$Src, 0)>; 4883def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0x00FF)), 4884 (UXTAB GPR:$Rn, GPR:$Rm, 0)>; 4885def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0xFFFF)), 4886 (UXTAH GPR:$Rn, GPR:$Rm, 0)>; 4887} 4888 4889def : ARMV6Pat<(sext_inreg GPR:$Src, i8), (SXTB GPR:$Src, 0)>; 4890def : ARMV6Pat<(sext_inreg GPR:$Src, i16), (SXTH GPR:$Src, 0)>; 4891 4892def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i8)), 4893 (SXTAB GPR:$Rn, GPRnopc:$Rm, 0)>; 4894def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)), 4895 (SXTAH GPR:$Rn, GPRnopc:$Rm, 0)>; 4896 4897// Atomic load/store patterns 4898def : ARMPat<(atomic_load_8 ldst_so_reg:$src), 4899 (LDRBrs ldst_so_reg:$src)>; 4900def : ARMPat<(atomic_load_8 addrmode_imm12:$src), 4901 (LDRBi12 addrmode_imm12:$src)>; 4902def : ARMPat<(atomic_load_16 addrmode3:$src), 4903 (LDRH addrmode3:$src)>; 4904def : ARMPat<(atomic_load_32 ldst_so_reg:$src), 4905 (LDRrs ldst_so_reg:$src)>; 4906def : ARMPat<(atomic_load_32 addrmode_imm12:$src), 4907 (LDRi12 addrmode_imm12:$src)>; 4908def : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val), 4909 (STRBrs GPR:$val, ldst_so_reg:$ptr)>; 4910def : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val), 4911 (STRBi12 GPR:$val, addrmode_imm12:$ptr)>; 4912def : ARMPat<(atomic_store_16 addrmode3:$ptr, GPR:$val), 4913 (STRH GPR:$val, addrmode3:$ptr)>; 4914def : ARMPat<(atomic_store_32 ldst_so_reg:$ptr, GPR:$val), 4915 (STRrs GPR:$val, ldst_so_reg:$ptr)>; 4916def : ARMPat<(atomic_store_32 addrmode_imm12:$ptr, GPR:$val), 4917 (STRi12 GPR:$val, addrmode_imm12:$ptr)>; 4918 4919 4920//===----------------------------------------------------------------------===// 4921// Thumb Support 4922// 4923 4924include "ARMInstrThumb.td" 4925 4926//===----------------------------------------------------------------------===// 4927// Thumb2 Support 4928// 4929 4930include "ARMInstrThumb2.td" 4931 4932//===----------------------------------------------------------------------===// 4933// Floating Point Support 4934// 4935 4936include "ARMInstrVFP.td" 4937 4938//===----------------------------------------------------------------------===// 4939// Advanced SIMD (NEON) Support 4940// 4941 4942include "ARMInstrNEON.td" 4943 4944//===----------------------------------------------------------------------===// 4945// Assembler aliases 4946// 4947 4948// Memory barriers 4949def : InstAlias<"dmb", (DMB 0xf)>, Requires<[IsARM, HasDB]>; 4950def : InstAlias<"dsb", (DSB 0xf)>, Requires<[IsARM, HasDB]>; 4951def : InstAlias<"isb", (ISB 0xf)>, Requires<[IsARM, HasDB]>; 4952 4953// System instructions 4954def : MnemonicAlias<"swi", "svc">; 4955 4956// Load / Store Multiple 4957def : MnemonicAlias<"ldmfd", "ldm">; 4958def : MnemonicAlias<"ldmia", "ldm">; 4959def : MnemonicAlias<"ldmea", "ldmdb">; 4960def : MnemonicAlias<"stmfd", "stmdb">; 4961def : MnemonicAlias<"stmia", "stm">; 4962def : MnemonicAlias<"stmea", "stm">; 4963 4964// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT when the 4965// shift amount is zero (i.e., unspecified). 4966def : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm", 4967 (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>, 4968 Requires<[IsARM, HasV6]>; 4969def : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm", 4970 (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>, 4971 Requires<[IsARM, HasV6]>; 4972 4973// PUSH/POP aliases for STM/LDM 4974def : ARMInstAlias<"push${p} $regs", (STMDB_UPD SP, pred:$p, reglist:$regs)>; 4975def : ARMInstAlias<"pop${p} $regs", (LDMIA_UPD SP, pred:$p, reglist:$regs)>; 4976 4977// SSAT/USAT optional shift operand. 4978def : ARMInstAlias<"ssat${p} $Rd, $sat_imm, $Rn", 4979 (SSAT GPRnopc:$Rd, imm1_32:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; 4980def : ARMInstAlias<"usat${p} $Rd, $sat_imm, $Rn", 4981 (USAT GPRnopc:$Rd, imm0_31:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; 4982 4983 4984// Extend instruction optional rotate operand. 4985def : ARMInstAlias<"sxtab${p} $Rd, $Rn, $Rm", 4986 (SXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 4987def : ARMInstAlias<"sxtah${p} $Rd, $Rn, $Rm", 4988 (SXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 4989def : ARMInstAlias<"sxtab16${p} $Rd, $Rn, $Rm", 4990 (SXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 4991def : ARMInstAlias<"sxtb${p} $Rd, $Rm", 4992 (SXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 4993def : ARMInstAlias<"sxtb16${p} $Rd, $Rm", 4994 (SXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 4995def : ARMInstAlias<"sxth${p} $Rd, $Rm", 4996 (SXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 4997 4998def : ARMInstAlias<"uxtab${p} $Rd, $Rn, $Rm", 4999 (UXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5000def : ARMInstAlias<"uxtah${p} $Rd, $Rn, $Rm", 5001 (UXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5002def : ARMInstAlias<"uxtab16${p} $Rd, $Rn, $Rm", 5003 (UXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5004def : ARMInstAlias<"uxtb${p} $Rd, $Rm", 5005 (UXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5006def : ARMInstAlias<"uxtb16${p} $Rd, $Rm", 5007 (UXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5008def : ARMInstAlias<"uxth${p} $Rd, $Rm", 5009 (UXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5010 5011 5012// RFE aliases 5013def : MnemonicAlias<"rfefa", "rfeda">; 5014def : MnemonicAlias<"rfeea", "rfedb">; 5015def : MnemonicAlias<"rfefd", "rfeia">; 5016def : MnemonicAlias<"rfeed", "rfeib">; 5017def : MnemonicAlias<"rfe", "rfeia">; 5018 5019// SRS aliases 5020def : MnemonicAlias<"srsfa", "srsda">; 5021def : MnemonicAlias<"srsea", "srsdb">; 5022def : MnemonicAlias<"srsfd", "srsia">; 5023def : MnemonicAlias<"srsed", "srsib">; 5024def : MnemonicAlias<"srs", "srsia">; 5025 5026// QSAX == QSUBADDX 5027def : MnemonicAlias<"qsubaddx", "qsax">; 5028// SASX == SADDSUBX 5029def : MnemonicAlias<"saddsubx", "sasx">; 5030// SHASX == SHADDSUBX 5031def : MnemonicAlias<"shaddsubx", "shasx">; 5032// SHSAX == SHSUBADDX 5033def : MnemonicAlias<"shsubaddx", "shsax">; 5034// SSAX == SSUBADDX 5035def : MnemonicAlias<"ssubaddx", "ssax">; 5036// UASX == UADDSUBX 5037def : MnemonicAlias<"uaddsubx", "uasx">; 5038// UHASX == UHADDSUBX 5039def : MnemonicAlias<"uhaddsubx", "uhasx">; 5040// UHSAX == UHSUBADDX 5041def : MnemonicAlias<"uhsubaddx", "uhsax">; 5042// UQASX == UQADDSUBX 5043def : MnemonicAlias<"uqaddsubx", "uqasx">; 5044// UQSAX == UQSUBADDX 5045def : MnemonicAlias<"uqsubaddx", "uqsax">; 5046// USAX == USUBADDX 5047def : MnemonicAlias<"usubaddx", "usax">; 5048 5049// "mov Rd, so_imm_not" can be handled via "mvn" in assembly, just like 5050// for isel. 5051def : ARMInstAlias<"mov${s}${p} $Rd, $imm", 5052 (MVNi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>; 5053def : ARMInstAlias<"mvn${s}${p} $Rd, $imm", 5054 (MOVi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>; 5055// Same for AND <--> BIC 5056def : ARMInstAlias<"bic${s}${p} $Rd, $Rn, $imm", 5057 (ANDri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm, 5058 pred:$p, cc_out:$s)>; 5059def : ARMInstAlias<"bic${s}${p} $Rdn, $imm", 5060 (ANDri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm, 5061 pred:$p, cc_out:$s)>; 5062def : ARMInstAlias<"and${s}${p} $Rd, $Rn, $imm", 5063 (BICri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm, 5064 pred:$p, cc_out:$s)>; 5065def : ARMInstAlias<"and${s}${p} $Rdn, $imm", 5066 (BICri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm, 5067 pred:$p, cc_out:$s)>; 5068 5069// Likewise, "add Rd, so_imm_neg" -> sub 5070def : ARMInstAlias<"add${s}${p} $Rd, $Rn, $imm", 5071 (SUBri GPR:$Rd, GPR:$Rn, so_imm_neg:$imm, pred:$p, cc_out:$s)>; 5072def : ARMInstAlias<"add${s}${p} $Rd, $imm", 5073 (SUBri GPR:$Rd, GPR:$Rd, so_imm_neg:$imm, pred:$p, cc_out:$s)>; 5074// Same for CMP <--> CMN via so_imm_neg 5075def : ARMInstAlias<"cmp${p} $Rd, $imm", 5076 (CMNri rGPR:$Rd, so_imm_neg:$imm, pred:$p)>; 5077def : ARMInstAlias<"cmn${p} $Rd, $imm", 5078 (CMPri rGPR:$Rd, so_imm_neg:$imm, pred:$p)>; 5079 5080// The shifter forms of the MOV instruction are aliased to the ASR, LSL, 5081// LSR, ROR, and RRX instructions. 5082// FIXME: We need C++ parser hooks to map the alias to the MOV 5083// encoding. It seems we should be able to do that sort of thing 5084// in tblgen, but it could get ugly. 5085let TwoOperandAliasConstraint = "$Rm = $Rd" in { 5086def ASRi : ARMAsmPseudo<"asr${s}${p} $Rd, $Rm, $imm", 5087 (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p, 5088 cc_out:$s)>; 5089def LSRi : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rm, $imm", 5090 (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p, 5091 cc_out:$s)>; 5092def LSLi : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rm, $imm", 5093 (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p, 5094 cc_out:$s)>; 5095def RORi : ARMAsmPseudo<"ror${s}${p} $Rd, $Rm, $imm", 5096 (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p, 5097 cc_out:$s)>; 5098} 5099def RRXi : ARMAsmPseudo<"rrx${s}${p} $Rd, $Rm", 5100 (ins GPRnopc:$Rd, GPRnopc:$Rm, pred:$p, cc_out:$s)>; 5101let TwoOperandAliasConstraint = "$Rn = $Rd" in { 5102def ASRr : ARMAsmPseudo<"asr${s}${p} $Rd, $Rn, $Rm", 5103 (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 5104 cc_out:$s)>; 5105def LSRr : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rn, $Rm", 5106 (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 5107 cc_out:$s)>; 5108def LSLr : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rn, $Rm", 5109 (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 5110 cc_out:$s)>; 5111def RORr : ARMAsmPseudo<"ror${s}${p} $Rd, $Rn, $Rm", 5112 (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 5113 cc_out:$s)>; 5114} 5115 5116// "neg" is and alias for "rsb rd, rn, #0" 5117def : ARMInstAlias<"neg${s}${p} $Rd, $Rm", 5118 (RSBri GPR:$Rd, GPR:$Rm, 0, pred:$p, cc_out:$s)>; 5119 5120// Pre-v6, 'mov r0, r0' was used as a NOP encoding. 5121def : InstAlias<"nop${p}", (MOVr R0, R0, pred:$p, zero_reg)>, 5122 Requires<[IsARM, NoV6]>; 5123 5124// UMULL/SMULL are available on all arches, but the instruction definitions 5125// need difference constraints pre-v6. Use these aliases for the assembly 5126// parsing on pre-v6. 5127def : InstAlias<"smull${s}${p} $RdLo, $RdHi, $Rn, $Rm", 5128 (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 5129 Requires<[IsARM, NoV6]>; 5130def : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm", 5131 (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 5132 Requires<[IsARM, NoV6]>; 5133 5134// 'it' blocks in ARM mode just validate the predicates. The IT itself 5135// is discarded. 5136def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>; 5137