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