1193323Sed//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file describes the ARM instructions in TableGen format. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed//===----------------------------------------------------------------------===// 15193323Sed// ARM specific DAG Nodes. 16193323Sed// 17193323Sed 18193323Sed// Type profiles. 19193323Seddef SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 20193323Seddef SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; 21245431Sdimdef SDT_ARMStructByVal : SDTypeProfile<0, 4, 22245431Sdim [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 23245431Sdim SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 24193323Sed 25193323Seddef SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>; 26193323Sed 27204961Srdivackydef SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 28193323Sed 29193323Seddef SDT_ARMCMov : SDTypeProfile<1, 3, 30193323Sed [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 31193323Sed SDTCisVT<3, i32>]>; 32193323Sed 33193323Seddef SDT_ARMBrcond : SDTypeProfile<0, 2, 34193323Sed [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 35193323Sed 36193323Seddef SDT_ARMBrJT : SDTypeProfile<0, 3, 37193323Sed [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 38193323Sed SDTCisVT<2, i32>]>; 39193323Sed 40198090Srdivackydef SDT_ARMBr2JT : SDTypeProfile<0, 4, 41198090Srdivacky [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 42198090Srdivacky SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 43198090Srdivacky 44210299Seddef SDT_ARMBCC_i64 : SDTypeProfile<0, 6, 45210299Sed [SDTCisVT<0, i32>, 46210299Sed SDTCisVT<1, i32>, SDTCisVT<2, i32>, 47210299Sed SDTCisVT<3, i32>, SDTCisVT<4, i32>, 48210299Sed SDTCisVT<5, OtherVT>]>; 49210299Sed 50212904Sdimdef SDT_ARMAnd : SDTypeProfile<1, 2, 51212904Sdim [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 52212904Sdim SDTCisVT<2, i32>]>; 53212904Sdim 54193323Seddef SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 55193323Sed 56193323Seddef SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, 57193323Sed SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; 58193323Sed 59193323Seddef SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; 60203954Srdivackydef SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>, 61203954Srdivacky SDTCisInt<2>]>; 62208599Srdivackydef SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>; 63193323Sed 64218893Sdimdef SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 65218893Sdim 66224145Sdimdef SDT_ARMPREFETCH : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, 67224145Sdim SDTCisInt<1>]>; 68224145Sdim 69210299Seddef SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 70210299Sed 71212904Sdimdef SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 72212904Sdim SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 73212904Sdim 74263509Sdimdef SDT_ARMVMAXNM : SDTypeProfile<1, 2, [SDTCisFP<0>, SDTCisFP<1>, SDTCisFP<2>]>; 75263509Sdimdef SDT_ARMVMINNM : SDTypeProfile<1, 2, [SDTCisFP<0>, SDTCisFP<1>, SDTCisFP<2>]>; 76263509Sdim 77226890Sdimdef SDTBinaryArithWithFlags : SDTypeProfile<2, 2, 78226890Sdim [SDTCisSameAs<0, 2>, 79226890Sdim SDTCisSameAs<0, 3>, 80226890Sdim SDTCisInt<0>, SDTCisVT<1, i32>]>; 81226890Sdim 82226890Sdim// SDTBinaryArithWithFlagsInOut - RES1, CPSR = op LHS, RHS, CPSR 83226890Sdimdef SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3, 84226890Sdim [SDTCisSameAs<0, 2>, 85226890Sdim SDTCisSameAs<0, 3>, 86226890Sdim SDTCisInt<0>, 87226890Sdim SDTCisVT<1, i32>, 88226890Sdim SDTCisVT<4, i32>]>; 89245431Sdim 90245431Sdimdef SDT_ARM64bitmlal : SDTypeProfile<2,4, [ SDTCisVT<0, i32>, SDTCisVT<1, i32>, 91245431Sdim SDTCisVT<2, i32>, SDTCisVT<3, i32>, 92245431Sdim SDTCisVT<4, i32>, SDTCisVT<5, i32> ] >; 93245431Sdimdef ARMUmlal : SDNode<"ARMISD::UMLAL", SDT_ARM64bitmlal>; 94245431Sdimdef ARMSmlal : SDNode<"ARMISD::SMLAL", SDT_ARM64bitmlal>; 95245431Sdim 96193323Sed// Node definitions. 97193323Seddef ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; 98218893Sdimdef ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>; 99218893Sdimdef ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>; 100193323Seddef ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; 101193323Sed 102193323Seddef ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, 103245431Sdim [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; 104193323Seddef ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd, 105245431Sdim [SDNPHasChain, SDNPSideEffect, 106245431Sdim SDNPOptInGlue, SDNPOutGlue]>; 107245431Sdimdef ARMcopystructbyval : SDNode<"ARMISD::COPY_STRUCT_BYVAL" , 108245431Sdim SDT_ARMStructByVal, 109245431Sdim [SDNPHasChain, SDNPInGlue, SDNPOutGlue, 110245431Sdim SDNPMayStore, SDNPMayLoad]>; 111193323Sed 112193323Seddef ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall, 113218893Sdim [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 114205407Srdivacky SDNPVariadic]>; 115193323Seddef ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall, 116218893Sdim [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 117205407Srdivacky SDNPVariadic]>; 118193323Seddef ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall, 119218893Sdim [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 120205407Srdivacky SDNPVariadic]>; 121193323Sed 122193323Seddef ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone, 123252723Sdim [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 124263509Sdimdef ARMintretflag : SDNode<"ARMISD::INTRET_FLAG", SDT_ARMcall, 125263509Sdim [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 126193323Seddef ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, 127218893Sdim [SDNPInGlue]>; 128193323Sed 129193323Seddef ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, 130218893Sdim [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; 131193323Sed 132193323Seddef ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, 133193323Sed [SDNPHasChain]>; 134198090Srdivackydef ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT, 135198090Srdivacky [SDNPHasChain]>; 136193323Sed 137210299Seddef ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64, 138210299Sed [SDNPHasChain]>; 139210299Sed 140193323Seddef ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, 141218893Sdim [SDNPOutGlue]>; 142193323Sed 143245431Sdimdef ARMcmn : SDNode<"ARMISD::CMN", SDT_ARMCmp, 144245431Sdim [SDNPOutGlue]>; 145245431Sdim 146195340Seddef ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, 147218893Sdim [SDNPOutGlue, SDNPCommutative]>; 148193323Sed 149193323Seddef ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; 150193323Sed 151218893Sdimdef ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; 152218893Sdimdef ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; 153218893Sdimdef ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>; 154193323Sed 155226890Sdimdef ARMaddc : SDNode<"ARMISD::ADDC", SDTBinaryArithWithFlags, 156226890Sdim [SDNPCommutative]>; 157226890Sdimdef ARMsubc : SDNode<"ARMISD::SUBC", SDTBinaryArithWithFlags>; 158226890Sdimdef ARMadde : SDNode<"ARMISD::ADDE", SDTBinaryArithWithFlagsInOut>; 159226890Sdimdef ARMsube : SDNode<"ARMISD::SUBE", SDTBinaryArithWithFlagsInOut>; 160226890Sdim 161193323Seddef ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; 162208599Srdivackydef ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", 163245431Sdim SDT_ARMEH_SJLJ_Setjmp, 164245431Sdim [SDNPHasChain, SDNPSideEffect]>; 165208599Srdivackydef ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP", 166245431Sdim SDT_ARMEH_SJLJ_Longjmp, 167245431Sdim [SDNPHasChain, SDNPSideEffect]>; 168193323Sed 169218893Sdimdef ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER, 170245431Sdim [SDNPHasChain, SDNPSideEffect]>; 171224145Sdimdef ARMPreload : SDNode<"ARMISD::PRELOAD", SDT_ARMPREFETCH, 172218893Sdim [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>; 173200581Srdivacky 174202878Srdivackydef ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>; 175202878Srdivacky 176218893Sdimdef ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET, 177218893Sdim [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 178210299Sed 179212904Sdimdef ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>; 180212904Sdim 181263509Sdimdef ARMvmaxnm : SDNode<"ARMISD::VMAXNM", SDT_ARMVMAXNM, []>; 182263509Sdimdef ARMvminnm : SDNode<"ARMISD::VMINNM", SDT_ARMVMINNM, []>; 183263509Sdim 184193323Sed//===----------------------------------------------------------------------===// 185193323Sed// ARM Instruction Predicate Definitions. 186193323Sed// 187224145Sdimdef HasV4T : Predicate<"Subtarget->hasV4TOps()">, 188245431Sdim AssemblerPredicate<"HasV4TOps", "armv4t">; 189212904Sdimdef NoV4T : Predicate<"!Subtarget->hasV4TOps()">; 190212904Sdimdef HasV5T : Predicate<"Subtarget->hasV5TOps()">; 191224145Sdimdef HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, 192245431Sdim AssemblerPredicate<"HasV5TEOps", "armv5te">; 193224145Sdimdef HasV6 : Predicate<"Subtarget->hasV6Ops()">, 194245431Sdim AssemblerPredicate<"HasV6Ops", "armv6">; 195218893Sdimdef NoV6 : Predicate<"!Subtarget->hasV6Ops()">; 196263509Sdimdef HasV6M : Predicate<"Subtarget->hasV6MOps()">, 197263509Sdim AssemblerPredicate<"HasV6MOps", 198263509Sdim "armv6m or armv6t2">; 199224145Sdimdef HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, 200245431Sdim AssemblerPredicate<"HasV6T2Ops", "armv6t2">; 201212904Sdimdef NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; 202224145Sdimdef HasV7 : Predicate<"Subtarget->hasV7Ops()">, 203245431Sdim AssemblerPredicate<"HasV7Ops", "armv7">; 204263509Sdimdef HasV8 : Predicate<"Subtarget->hasV8Ops()">, 205263509Sdim AssemblerPredicate<"HasV8Ops", "armv8">; 206263509Sdimdef PreV8 : Predicate<"!Subtarget->hasV8Ops()">, 207263509Sdim AssemblerPredicate<"!HasV8Ops", "armv7 or earlier">; 208212904Sdimdef NoVFP : Predicate<"!Subtarget->hasVFP2()">; 209224145Sdimdef HasVFP2 : Predicate<"Subtarget->hasVFP2()">, 210245431Sdim AssemblerPredicate<"FeatureVFP2", "VFP2">; 211224145Sdimdef HasVFP3 : Predicate<"Subtarget->hasVFP3()">, 212245431Sdim AssemblerPredicate<"FeatureVFP3", "VFP3">; 213235633Sdimdef HasVFP4 : Predicate<"Subtarget->hasVFP4()">, 214245431Sdim AssemblerPredicate<"FeatureVFP4", "VFP4">; 215263509Sdimdef HasDPVFP : Predicate<"!Subtarget->isFPOnlySP()">, 216263509Sdim AssemblerPredicate<"!FeatureVFPOnlySP", 217263509Sdim "double precision VFP">; 218263509Sdimdef HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8()">, 219263509Sdim AssemblerPredicate<"FeatureFPARMv8", "FPARMv8">; 220224145Sdimdef HasNEON : Predicate<"Subtarget->hasNEON()">, 221245431Sdim AssemblerPredicate<"FeatureNEON", "NEON">; 222263509Sdimdef HasCrypto : Predicate<"Subtarget->hasCrypto()">, 223263509Sdim AssemblerPredicate<"FeatureCrypto", "crypto">; 224263509Sdimdef HasCRC : Predicate<"Subtarget->hasCRC()">, 225263509Sdim AssemblerPredicate<"FeatureCRC", "crc">; 226224145Sdimdef HasFP16 : Predicate<"Subtarget->hasFP16()">, 227245431Sdim AssemblerPredicate<"FeatureFP16","half-float">; 228224145Sdimdef HasDivide : Predicate<"Subtarget->hasDivide()">, 229263509Sdim AssemblerPredicate<"FeatureHWDiv", "divide in THUMB">; 230245431Sdimdef HasDivideInARM : Predicate<"Subtarget->hasDivideInARMMode()">, 231263509Sdim AssemblerPredicate<"FeatureHWDivARM", "divide in ARM">; 232218893Sdimdef HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">, 233245431Sdim AssemblerPredicate<"FeatureT2XtPk", 234245431Sdim "pack/extract">; 235224145Sdimdef HasThumb2DSP : Predicate<"Subtarget->hasThumb2DSP()">, 236245431Sdim AssemblerPredicate<"FeatureDSPThumb2", 237245431Sdim "thumb2-dsp">; 238218893Sdimdef HasDB : Predicate<"Subtarget->hasDataBarrier()">, 239245431Sdim AssemblerPredicate<"FeatureDB", 240245431Sdim "data-barriers">; 241218893Sdimdef HasMP : Predicate<"Subtarget->hasMPExtension()">, 242245431Sdim AssemblerPredicate<"FeatureMP", 243245431Sdim "mp-extensions">; 244252723Sdimdef HasTrustZone : Predicate<"Subtarget->hasTrustZone()">, 245252723Sdim AssemblerPredicate<"FeatureTrustZone", 246252723Sdim "TrustZone">; 247212904Sdimdef UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; 248198090Srdivackydef DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; 249224145Sdimdef IsThumb : Predicate<"Subtarget->isThumb()">, 250245431Sdim AssemblerPredicate<"ModeThumb", "thumb">; 251212904Sdimdef IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; 252224145Sdimdef IsThumb2 : Predicate<"Subtarget->isThumb2()">, 253245431Sdim AssemblerPredicate<"ModeThumb,FeatureThumb2", 254245431Sdim "thumb2">; 255226890Sdimdef IsMClass : Predicate<"Subtarget->isMClass()">, 256263509Sdim AssemblerPredicate<"FeatureMClass", "armv*m">; 257263509Sdimdef IsNotMClass : Predicate<"!Subtarget->isMClass()">, 258245431Sdim AssemblerPredicate<"!FeatureMClass", 259263509Sdim "!armv*m">; 260224145Sdimdef IsARM : Predicate<"!Subtarget->isThumb()">, 261245431Sdim AssemblerPredicate<"!ModeThumb", "arm-mode">; 262235633Sdimdef IsIOS : Predicate<"Subtarget->isTargetIOS()">; 263235633Sdimdef IsNotIOS : Predicate<"!Subtarget->isTargetIOS()">; 264235633Sdimdef IsNaCl : Predicate<"Subtarget->isTargetNaCl()">; 265252723Sdimdef UseNaClTrap : Predicate<"Subtarget->useNaClTrap()">, 266252723Sdim AssemblerPredicate<"FeatureNaClTrap", "NaCl">; 267252723Sdimdef DontUseNaClTrap : Predicate<"!Subtarget->useNaClTrap()">; 268193323Sed 269199989Srdivacky// FIXME: Eventually this will be just "hasV6T2Ops". 270212904Sdimdef UseMovt : Predicate<"Subtarget->useMovt()">; 271212904Sdimdef DontUseMovt : Predicate<"!Subtarget->useMovt()">; 272218893Sdimdef UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">; 273245431Sdimdef UseMulOps : Predicate<"Subtarget->useMulOps()">; 274199989Srdivacky 275235633Sdim// Prefer fused MAC for fp mul + add over fp VMLA / VMLS if they are available. 276235633Sdim// But only select them if more precision in FP computation is allowed. 277235633Sdim// Do not use them for Darwin platforms. 278245431Sdimdef UseFusedMAC : Predicate<"(TM.Options.AllowFPOpFusion ==" 279245431Sdim " FPOpFusion::Fast) && " 280235633Sdim "!Subtarget->isTargetDarwin()">; 281263509Sdimdef DontUseFusedMAC : Predicate<"!(TM.Options.AllowFPOpFusion ==" 282263509Sdim " FPOpFusion::Fast &&" 283263509Sdim " Subtarget->hasVFP4()) || " 284235633Sdim "Subtarget->isTargetDarwin()">; 285235633Sdim 286245431Sdim// VGETLNi32 is microcoded on Swift - prefer VMOV. 287245431Sdimdef HasFastVGETLNi32 : Predicate<"!Subtarget->isSwift()">; 288245431Sdimdef HasSlowVGETLNi32 : Predicate<"Subtarget->isSwift()">; 289245431Sdim 290245431Sdim// VDUP.32 is microcoded on Swift - prefer VMOV. 291245431Sdimdef HasFastVDUP32 : Predicate<"!Subtarget->isSwift()">; 292245431Sdimdef HasSlowVDUP32 : Predicate<"Subtarget->isSwift()">; 293245431Sdim 294245431Sdim// Cortex-A9 prefers VMOVSR to VMOVDRR even when using NEON for scalar FP, as 295245431Sdim// this allows more effective execution domain optimization. See 296245431Sdim// setExecutionDomain(). 297245431Sdimdef UseVMOVSR : Predicate<"Subtarget->isCortexA9() || !Subtarget->useNEONForSinglePrecisionFP()">; 298245431Sdimdef DontUseVMOVSR : Predicate<"!Subtarget->isCortexA9() && Subtarget->useNEONForSinglePrecisionFP()">; 299245431Sdim 300263509Sdimdef IsLE : Predicate<"getTargetLowering()->isLittleEndian()">; 301263509Sdimdef IsBE : Predicate<"getTargetLowering()->isBigEndian()">; 302245431Sdim 303193323Sed//===----------------------------------------------------------------------===// 304193323Sed// ARM Flag Definitions. 305193323Sed 306193323Sedclass RegConstraint<string C> { 307193323Sed string Constraints = C; 308193323Sed} 309193323Sed 310193323Sed//===----------------------------------------------------------------------===// 311193323Sed// ARM specific transformation functions and pattern fragments. 312193323Sed// 313193323Sed 314245431Sdim// imm_neg_XFORM - Return the negation of an i32 immediate value. 315245431Sdimdef imm_neg_XFORM : SDNodeXForm<imm, [{ 316198090Srdivacky return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 317193323Sed}]>; 318193323Sed 319245431Sdim// imm_not_XFORM - Return the complement of a i32 immediate value. 320245431Sdimdef imm_not_XFORM : SDNodeXForm<imm, [{ 321198090Srdivacky return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32); 322193323Sed}]>; 323193323Sed 324193323Sed/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31]. 325221345Sdimdef imm16_31 : ImmLeaf<i32, [{ 326221345Sdim return (int32_t)Imm >= 16 && (int32_t)Imm < 32; 327193323Sed}]>; 328193323Sed 329235633Sdimdef so_imm_neg_asmoperand : AsmOperandClass { let Name = "ARMSOImmNeg"; } 330235633Sdimdef so_imm_neg : Operand<i32>, PatLeaf<(imm), [{ 331245431Sdim unsigned Value = -(unsigned)N->getZExtValue(); 332235633Sdim return Value && ARM_AM::getSOImmVal(Value) != -1; 333245431Sdim }], imm_neg_XFORM> { 334235633Sdim let ParserMatchClass = so_imm_neg_asmoperand; 335235633Sdim} 336193323Sed 337235633Sdim// Note: this pattern doesn't require an encoder method and such, as it's 338235633Sdim// only used on aliases (Pat<> and InstAlias<>). The actual encoding 339235633Sdim// is handled by the destination instructions, which use so_imm. 340235633Sdimdef so_imm_not_asmoperand : AsmOperandClass { let Name = "ARMSOImmNot"; } 341235633Sdimdef so_imm_not : Operand<i32>, PatLeaf<(imm), [{ 342218893Sdim return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1; 343245431Sdim }], imm_not_XFORM> { 344235633Sdim let ParserMatchClass = so_imm_not_asmoperand; 345235633Sdim} 346193323Sed 347193323Sed// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits. 348193323Seddef sext_16_node : PatLeaf<(i32 GPR:$a), [{ 349193323Sed return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17; 350193323Sed}]>; 351193323Sed 352198090Srdivacky/// Split a 32-bit immediate into two 16 bit parts. 353198090Srdivackydef hi16 : SDNodeXForm<imm, [{ 354198090Srdivacky return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32); 355198090Srdivacky}]>; 356198090Srdivacky 357198090Srdivackydef lo16AllZero : PatLeaf<(i32 imm), [{ 358198090Srdivacky // Returns true if all low 16-bits are 0. 359198090Srdivacky return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0; 360199989Srdivacky}], hi16>; 361198090Srdivacky 362226890Sdimclass BinOpWithFlagFrag<dag res> : 363226890Sdim PatFrag<(ops node:$LHS, node:$RHS, node:$FLAG), res>; 364193323Sedclass BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 365193323Sedclass UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>; 366193323Sed 367218893Sdim// An 'and' node with a single use. 368218893Sdimdef and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ 369218893Sdim return N->hasOneUse(); 370218893Sdim}]>; 371218893Sdim 372218893Sdim// An 'xor' node with a single use. 373218893Sdimdef xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{ 374218893Sdim return N->hasOneUse(); 375218893Sdim}]>; 376218893Sdim 377218893Sdim// An 'fmul' node with a single use. 378218893Sdimdef fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{ 379218893Sdim return N->hasOneUse(); 380218893Sdim}]>; 381218893Sdim 382218893Sdim// An 'fadd' node which checks for single non-hazardous use. 383218893Sdimdef fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{ 384218893Sdim return hasNoVMLxHazardUse(N); 385218893Sdim}]>; 386218893Sdim 387218893Sdim// An 'fsub' node which checks for single non-hazardous use. 388218893Sdimdef fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{ 389218893Sdim return hasNoVMLxHazardUse(N); 390218893Sdim}]>; 391218893Sdim 392193323Sed//===----------------------------------------------------------------------===// 393193323Sed// Operand Definitions. 394193323Sed// 395193323Sed 396235633Sdim// Immediate operands with a shared generic asm render method. 397235633Sdimclass ImmAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; } 398235633Sdim 399193323Sed// Branch target. 400218893Sdim// FIXME: rename brtarget to t2_brtarget 401218893Sdimdef brtarget : Operand<OtherVT> { 402218893Sdim let EncoderMethod = "getBranchTargetOpValue"; 403224145Sdim let OperandType = "OPERAND_PCREL"; 404226890Sdim let DecoderMethod = "DecodeT2BROperand"; 405218893Sdim} 406193323Sed 407218893Sdim// FIXME: get rid of this one? 408218893Sdimdef uncondbrtarget : Operand<OtherVT> { 409218893Sdim let EncoderMethod = "getUnconditionalBranchTargetOpValue"; 410224145Sdim let OperandType = "OPERAND_PCREL"; 411218893Sdim} 412218893Sdim 413218893Sdim// Branch target for ARM. Handles conditional/unconditional 414218893Sdimdef br_target : Operand<OtherVT> { 415218893Sdim let EncoderMethod = "getARMBranchTargetOpValue"; 416224145Sdim let OperandType = "OPERAND_PCREL"; 417218893Sdim} 418218893Sdim 419218893Sdim// Call target. 420218893Sdim// FIXME: rename bltarget to t2_bl_target? 421218893Sdimdef bltarget : Operand<i32> { 422218893Sdim // Encoded the same as branch targets. 423218893Sdim let EncoderMethod = "getBranchTargetOpValue"; 424224145Sdim let OperandType = "OPERAND_PCREL"; 425218893Sdim} 426218893Sdim 427218893Sdim// Call target for ARM. Handles conditional/unconditional 428218893Sdim// FIXME: rename bl_target to t2_bltarget? 429218893Sdimdef bl_target : Operand<i32> { 430235633Sdim let EncoderMethod = "getARMBLTargetOpValue"; 431224145Sdim let OperandType = "OPERAND_PCREL"; 432218893Sdim} 433218893Sdim 434226890Sdimdef blx_target : Operand<i32> { 435226890Sdim let EncoderMethod = "getARMBLXTargetOpValue"; 436226890Sdim let OperandType = "OPERAND_PCREL"; 437226890Sdim} 438218893Sdim 439193323Sed// A list of registers separated by comma. Used by load/store multiple. 440226890Sdimdef RegListAsmOperand : AsmOperandClass { let Name = "RegList"; } 441193323Seddef reglist : Operand<i32> { 442218893Sdim let EncoderMethod = "getRegisterListOpValue"; 443218893Sdim let ParserMatchClass = RegListAsmOperand; 444193323Sed let PrintMethod = "printRegisterList"; 445226890Sdim let DecoderMethod = "DecodeRegListOperand"; 446193323Sed} 447193323Sed 448252723Sdimdef GPRPairOp : RegisterOperand<GPRPair, "printGPRPairOperand">; 449252723Sdim 450226890Sdimdef DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; } 451218893Sdimdef dpr_reglist : Operand<i32> { 452218893Sdim let EncoderMethod = "getRegisterListOpValue"; 453218893Sdim let ParserMatchClass = DPRRegListAsmOperand; 454218893Sdim let PrintMethod = "printRegisterList"; 455226890Sdim let DecoderMethod = "DecodeDPRRegListOperand"; 456218893Sdim} 457218893Sdim 458226890Sdimdef SPRRegListAsmOperand : AsmOperandClass { let Name = "SPRRegList"; } 459218893Sdimdef spr_reglist : Operand<i32> { 460218893Sdim let EncoderMethod = "getRegisterListOpValue"; 461218893Sdim let ParserMatchClass = SPRRegListAsmOperand; 462218893Sdim let PrintMethod = "printRegisterList"; 463226890Sdim let DecoderMethod = "DecodeSPRRegListOperand"; 464218893Sdim} 465218893Sdim 466193323Sed// An operand for the CONSTPOOL_ENTRY pseudo-instruction. 467193323Seddef cpinst_operand : Operand<i32> { 468193323Sed let PrintMethod = "printCPInstOperand"; 469193323Sed} 470193323Sed 471193323Sed// Local PC labels. 472193323Seddef pclabel : Operand<i32> { 473193323Sed let PrintMethod = "printPCLabel"; 474193323Sed} 475193323Sed 476218893Sdim// ADR instruction labels. 477245431Sdimdef AdrLabelAsmOperand : AsmOperandClass { let Name = "AdrLabel"; } 478218893Sdimdef adrlabel : Operand<i32> { 479218893Sdim let EncoderMethod = "getAdrLabelOpValue"; 480245431Sdim let ParserMatchClass = AdrLabelAsmOperand; 481263509Sdim let PrintMethod = "printAdrLabelOperand<0>"; 482218893Sdim} 483218893Sdim 484218893Sdimdef neon_vcvt_imm32 : Operand<i32> { 485218893Sdim let EncoderMethod = "getNEONVcvtImm32OpValue"; 486226890Sdim let DecoderMethod = "DecodeVCVTImmOperand"; 487218893Sdim} 488218893Sdim 489218893Sdim// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24. 490226890Sdimdef rot_imm_XFORM: SDNodeXForm<imm, [{ 491226890Sdim switch (N->getZExtValue()){ 492226890Sdim default: assert(0); 493226890Sdim case 0: return CurDAG->getTargetConstant(0, MVT::i32); 494226890Sdim case 8: return CurDAG->getTargetConstant(1, MVT::i32); 495226890Sdim case 16: return CurDAG->getTargetConstant(2, MVT::i32); 496226890Sdim case 24: return CurDAG->getTargetConstant(3, MVT::i32); 497226890Sdim } 498226890Sdim}]>; 499226890Sdimdef RotImmAsmOperand : AsmOperandClass { 500226890Sdim let Name = "RotImm"; 501226890Sdim let ParserMethod = "parseRotImm"; 502218893Sdim} 503226890Sdimdef rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{ 504226890Sdim int32_t v = N->getZExtValue(); 505226890Sdim return v == 8 || v == 16 || v == 24; }], 506226890Sdim rot_imm_XFORM> { 507226890Sdim let PrintMethod = "printRotImmOperand"; 508226890Sdim let ParserMatchClass = RotImmAsmOperand; 509221345Sdim} 510221345Sdim 511212904Sdim// shift_imm: An integer that encodes a shift amount and the type of shift 512226890Sdim// (asr or lsl). The 6-bit immediate encodes as: 513226890Sdim// {5} 0 ==> lsl 514226890Sdim// 1 asr 515226890Sdim// {4-0} imm5 shift amount. 516226890Sdim// asr #32 encoded as imm5 == 0. 517226890Sdimdef ShifterImmAsmOperand : AsmOperandClass { 518226890Sdim let Name = "ShifterImm"; 519226890Sdim let ParserMethod = "parseShifterImm"; 520226890Sdim} 521212904Sdimdef shift_imm : Operand<i32> { 522212904Sdim let PrintMethod = "printShiftImmOperand"; 523226890Sdim let ParserMatchClass = ShifterImmAsmOperand; 524212904Sdim} 525212904Sdim 526226890Sdim// shifter_operand operands: so_reg_reg, so_reg_imm, and so_imm. 527226890Sdimdef ShiftedRegAsmOperand : AsmOperandClass { let Name = "RegShiftedReg"; } 528226890Sdimdef so_reg_reg : Operand<i32>, // reg reg imm 529226890Sdim ComplexPattern<i32, 3, "SelectRegShifterOperand", 530226890Sdim [shl, srl, sra, rotr]> { 531226890Sdim let EncoderMethod = "getSORegRegOpValue"; 532226890Sdim let PrintMethod = "printSORegRegOperand"; 533226890Sdim let DecoderMethod = "DecodeSORegRegOperand"; 534226890Sdim let ParserMatchClass = ShiftedRegAsmOperand; 535226890Sdim let MIOperandInfo = (ops GPRnopc, GPRnopc, i32imm); 536224145Sdim} 537224145Sdim 538226890Sdimdef ShiftedImmAsmOperand : AsmOperandClass { let Name = "RegShiftedImm"; } 539226890Sdimdef so_reg_imm : Operand<i32>, // reg imm 540226890Sdim ComplexPattern<i32, 2, "SelectImmShifterOperand", 541226890Sdim [shl, srl, sra, rotr]> { 542226890Sdim let EncoderMethod = "getSORegImmOpValue"; 543226890Sdim let PrintMethod = "printSORegImmOperand"; 544226890Sdim let DecoderMethod = "DecodeSORegImmOperand"; 545226890Sdim let ParserMatchClass = ShiftedImmAsmOperand; 546226890Sdim let MIOperandInfo = (ops GPR, i32imm); 547193323Sed} 548226890Sdim 549224145Sdim// FIXME: Does this need to be distinct from so_reg? 550226890Sdimdef shift_so_reg_reg : Operand<i32>, // reg reg imm 551226890Sdim ComplexPattern<i32, 3, "SelectShiftRegShifterOperand", 552218893Sdim [shl,srl,sra,rotr]> { 553226890Sdim let EncoderMethod = "getSORegRegOpValue"; 554226890Sdim let PrintMethod = "printSORegRegOperand"; 555226890Sdim let DecoderMethod = "DecodeSORegRegOperand"; 556235633Sdim let ParserMatchClass = ShiftedRegAsmOperand; 557226890Sdim let MIOperandInfo = (ops GPR, GPR, i32imm); 558218893Sdim} 559193323Sed 560226890Sdim// FIXME: Does this need to be distinct from so_reg? 561226890Sdimdef shift_so_reg_imm : Operand<i32>, // reg reg imm 562226890Sdim ComplexPattern<i32, 2, "SelectShiftImmShifterOperand", 563226890Sdim [shl,srl,sra,rotr]> { 564226890Sdim let EncoderMethod = "getSORegImmOpValue"; 565226890Sdim let PrintMethod = "printSORegImmOperand"; 566226890Sdim let DecoderMethod = "DecodeSORegImmOperand"; 567235633Sdim let ParserMatchClass = ShiftedImmAsmOperand; 568226890Sdim let MIOperandInfo = (ops GPR, i32imm); 569226890Sdim} 570226890Sdim 571226890Sdim 572193323Sed// so_imm - Match a 32-bit shifter_operand immediate operand, which is an 573218893Sdim// 8-bit immediate rotated by an arbitrary number of bits. 574235633Sdimdef SOImmAsmOperand: ImmAsmOperand { let Name = "ARMSOImm"; } 575221345Sdimdef so_imm : Operand<i32>, ImmLeaf<i32, [{ 576221345Sdim return ARM_AM::getSOImmVal(Imm) != -1; 577221345Sdim }]> { 578218893Sdim let EncoderMethod = "getSOImmOpValue"; 579226890Sdim let ParserMatchClass = SOImmAsmOperand; 580226890Sdim let DecoderMethod = "DecodeSOImmOperand"; 581193323Sed} 582193323Sed 583193323Sed// Break so_imm's up into two pieces. This handles immediates with up to 16 584193323Sed// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to 585193323Sed// get the first/second pieces. 586218893Sdimdef so_imm2part : PatLeaf<(imm), [{ 587193323Sed return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 588218893Sdim}]>; 589193323Sed 590218893Sdim/// arm_i32imm - True for +V6T2, or true only if so_imm2part is true. 591218893Sdim/// 592218893Sdimdef arm_i32imm : PatLeaf<(imm), [{ 593218893Sdim if (Subtarget->hasV6T2Ops()) 594218893Sdim return true; 595218893Sdim return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 596193323Sed}]>; 597193323Sed 598235633Sdim/// imm0_1 predicate - Immediate in the range [0,1]. 599235633Sdimdef Imm0_1AsmOperand: ImmAsmOperand { let Name = "Imm0_1"; } 600235633Sdimdef imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; } 601235633Sdim 602235633Sdim/// imm0_3 predicate - Immediate in the range [0,3]. 603235633Sdimdef Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; } 604235633Sdimdef imm0_3 : Operand<i32> { let ParserMatchClass = Imm0_3AsmOperand; } 605235633Sdim 606226890Sdim/// imm0_7 predicate - Immediate in the range [0,7]. 607235633Sdimdef Imm0_7AsmOperand: ImmAsmOperand { let Name = "Imm0_7"; } 608224145Sdimdef imm0_7 : Operand<i32>, ImmLeaf<i32, [{ 609224145Sdim return Imm >= 0 && Imm < 8; 610224145Sdim}]> { 611224145Sdim let ParserMatchClass = Imm0_7AsmOperand; 612224145Sdim} 613224145Sdim 614235633Sdim/// imm8 predicate - Immediate is exactly 8. 615235633Sdimdef Imm8AsmOperand: ImmAsmOperand { let Name = "Imm8"; } 616235633Sdimdef imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 8; }]> { 617235633Sdim let ParserMatchClass = Imm8AsmOperand; 618235633Sdim} 619235633Sdim 620235633Sdim/// imm16 predicate - Immediate is exactly 16. 621235633Sdimdef Imm16AsmOperand: ImmAsmOperand { let Name = "Imm16"; } 622235633Sdimdef imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 16; }]> { 623235633Sdim let ParserMatchClass = Imm16AsmOperand; 624235633Sdim} 625235633Sdim 626235633Sdim/// imm32 predicate - Immediate is exactly 32. 627235633Sdimdef Imm32AsmOperand: ImmAsmOperand { let Name = "Imm32"; } 628235633Sdimdef imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 32; }]> { 629235633Sdim let ParserMatchClass = Imm32AsmOperand; 630235633Sdim} 631235633Sdim 632235633Sdim/// imm1_7 predicate - Immediate in the range [1,7]. 633235633Sdimdef Imm1_7AsmOperand: ImmAsmOperand { let Name = "Imm1_7"; } 634235633Sdimdef imm1_7 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 8; }]> { 635235633Sdim let ParserMatchClass = Imm1_7AsmOperand; 636235633Sdim} 637235633Sdim 638235633Sdim/// imm1_15 predicate - Immediate in the range [1,15]. 639235633Sdimdef Imm1_15AsmOperand: ImmAsmOperand { let Name = "Imm1_15"; } 640235633Sdimdef imm1_15 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 16; }]> { 641235633Sdim let ParserMatchClass = Imm1_15AsmOperand; 642235633Sdim} 643235633Sdim 644235633Sdim/// imm1_31 predicate - Immediate in the range [1,31]. 645235633Sdimdef Imm1_31AsmOperand: ImmAsmOperand { let Name = "Imm1_31"; } 646235633Sdimdef imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> { 647235633Sdim let ParserMatchClass = Imm1_31AsmOperand; 648235633Sdim} 649235633Sdim 650226890Sdim/// imm0_15 predicate - Immediate in the range [0,15]. 651245431Sdimdef Imm0_15AsmOperand: ImmAsmOperand { 652245431Sdim let Name = "Imm0_15"; 653245431Sdim let DiagnosticType = "ImmRange0_15"; 654245431Sdim} 655224145Sdimdef imm0_15 : Operand<i32>, ImmLeaf<i32, [{ 656224145Sdim return Imm >= 0 && Imm < 16; 657224145Sdim}]> { 658224145Sdim let ParserMatchClass = Imm0_15AsmOperand; 659224145Sdim} 660224145Sdim 661218893Sdim/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31]. 662235633Sdimdef Imm0_31AsmOperand: ImmAsmOperand { let Name = "Imm0_31"; } 663221345Sdimdef imm0_31 : Operand<i32>, ImmLeaf<i32, [{ 664221345Sdim return Imm >= 0 && Imm < 32; 665218893Sdim}]> { 666226890Sdim let ParserMatchClass = Imm0_31AsmOperand; 667199989Srdivacky} 668199989Srdivacky 669235633Sdim/// imm0_32 predicate - True if the 32-bit immediate is in the range [0,32]. 670235633Sdimdef Imm0_32AsmOperand: ImmAsmOperand { let Name = "Imm0_32"; } 671235633Sdimdef imm0_32 : Operand<i32>, ImmLeaf<i32, [{ 672235633Sdim return Imm >= 0 && Imm < 32; 673235633Sdim}]> { 674235633Sdim let ParserMatchClass = Imm0_32AsmOperand; 675235633Sdim} 676235633Sdim 677235633Sdim/// imm0_63 predicate - True if the 32-bit immediate is in the range [0,63]. 678235633Sdimdef Imm0_63AsmOperand: ImmAsmOperand { let Name = "Imm0_63"; } 679235633Sdimdef imm0_63 : Operand<i32>, ImmLeaf<i32, [{ 680235633Sdim return Imm >= 0 && Imm < 64; 681235633Sdim}]> { 682235633Sdim let ParserMatchClass = Imm0_63AsmOperand; 683235633Sdim} 684235633Sdim 685263509Sdim/// imm0_239 predicate - Immediate in the range [0,239]. 686263509Sdimdef Imm0_239AsmOperand : ImmAsmOperand { 687263509Sdim let Name = "Imm0_239"; 688263509Sdim let DiagnosticType = "ImmRange0_239"; 689263509Sdim} 690263509Sdimdef imm0_239 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 240; }]> { 691263509Sdim let ParserMatchClass = Imm0_239AsmOperand; 692263509Sdim} 693263509Sdim 694226890Sdim/// imm0_255 predicate - Immediate in the range [0,255]. 695235633Sdimdef Imm0_255AsmOperand : ImmAsmOperand { let Name = "Imm0_255"; } 696226890Sdimdef imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> { 697226890Sdim let ParserMatchClass = Imm0_255AsmOperand; 698226890Sdim} 699226890Sdim 700235633Sdim/// imm0_65535 - An immediate is in the range [0.65535]. 701235633Sdimdef Imm0_65535AsmOperand: ImmAsmOperand { let Name = "Imm0_65535"; } 702235633Sdimdef imm0_65535 : Operand<i32>, ImmLeaf<i32, [{ 703235633Sdim return Imm >= 0 && Imm < 65536; 704235633Sdim}]> { 705235633Sdim let ParserMatchClass = Imm0_65535AsmOperand; 706235633Sdim} 707235633Sdim 708245431Sdim// imm0_65535_neg - An immediate whose negative value is in the range [0.65535]. 709245431Sdimdef imm0_65535_neg : Operand<i32>, ImmLeaf<i32, [{ 710245431Sdim return -Imm >= 0 && -Imm < 65536; 711245431Sdim}]>; 712245431Sdim 713226890Sdim// imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference 714226890Sdim// a relocatable expression. 715218893Sdim// 716226890Sdim// FIXME: This really needs a Thumb version separate from the ARM version. 717226890Sdim// While the range is the same, and can thus use the same match class, 718226890Sdim// the encoding is different so it should have a different encoder method. 719235633Sdimdef Imm0_65535ExprAsmOperand: ImmAsmOperand { let Name = "Imm0_65535Expr"; } 720226890Sdimdef imm0_65535_expr : Operand<i32> { 721218893Sdim let EncoderMethod = "getHiLo16ImmOpValue"; 722226890Sdim let ParserMatchClass = Imm0_65535ExprAsmOperand; 723218893Sdim} 724199989Srdivacky 725263509Sdimdef Imm256_65535ExprAsmOperand: ImmAsmOperand { let Name = "Imm256_65535Expr"; } 726263509Sdimdef imm256_65535_expr : Operand<i32> { 727263509Sdim let ParserMatchClass = Imm256_65535ExprAsmOperand; 728263509Sdim} 729263509Sdim 730226890Sdim/// imm24b - True if the 32-bit immediate is encodable in 24 bits. 731235633Sdimdef Imm24bitAsmOperand: ImmAsmOperand { let Name = "Imm24bit"; } 732226890Sdimdef imm24b : Operand<i32>, ImmLeaf<i32, [{ 733226890Sdim return Imm >= 0 && Imm <= 0xffffff; 734226890Sdim}]> { 735226890Sdim let ParserMatchClass = Imm24bitAsmOperand; 736226890Sdim} 737226890Sdim 738226890Sdim 739218893Sdim/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield 740218893Sdim/// e.g., 0xf000ffff 741226890Sdimdef BitfieldAsmOperand : AsmOperandClass { 742226890Sdim let Name = "Bitfield"; 743226890Sdim let ParserMethod = "parseBitfield"; 744226890Sdim} 745235633Sdim 746218893Sdimdef bf_inv_mask_imm : Operand<i32>, 747218893Sdim PatLeaf<(imm), [{ 748218893Sdim return ARM::isBitFieldInvertedMask(N->getZExtValue()); 749218893Sdim}] > { 750218893Sdim let EncoderMethod = "getBitfieldInvertedMaskOpValue"; 751218893Sdim let PrintMethod = "printBitfieldInvMaskImmOperand"; 752226890Sdim let DecoderMethod = "DecodeBitfieldMaskOperand"; 753226890Sdim let ParserMatchClass = BitfieldAsmOperand; 754218893Sdim} 755199989Srdivacky 756226890Sdimdef imm1_32_XFORM: SDNodeXForm<imm, [{ 757226890Sdim return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32); 758198090Srdivacky}]>; 759226890Sdimdef Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; } 760226890Sdimdef imm1_32 : Operand<i32>, PatLeaf<(imm), [{ 761226890Sdim uint64_t Imm = N->getZExtValue(); 762226890Sdim return Imm > 0 && Imm <= 32; 763226890Sdim }], 764226890Sdim imm1_32_XFORM> { 765226890Sdim let PrintMethod = "printImmPlusOneOperand"; 766226890Sdim let ParserMatchClass = Imm1_32AsmOperand; 767218893Sdim} 768218893Sdim 769226890Sdimdef imm1_16_XFORM: SDNodeXForm<imm, [{ 770226890Sdim return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32); 771226890Sdim}]>; 772226890Sdimdef Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; } 773226890Sdimdef imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }], 774226890Sdim imm1_16_XFORM> { 775226890Sdim let PrintMethod = "printImmPlusOneOperand"; 776226890Sdim let ParserMatchClass = Imm1_16AsmOperand; 777223017Sdim} 778223017Sdim 779193323Sed// Define ARM specific addressing modes. 780218893Sdim// addrmode_imm12 := reg +/- imm12 781218893Sdim// 782226890Sdimdef MemImm12OffsetAsmOperand : AsmOperandClass { let Name = "MemImm12Offset"; } 783252723Sdimclass AddrMode_Imm12 : Operand<i32>, 784218893Sdim ComplexPattern<i32, 2, "SelectAddrModeImm12", []> { 785218893Sdim // 12-bit immediate operand. Note that instructions using this encode 786218893Sdim // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other 787218893Sdim // immediate values are as normal. 788218893Sdim 789218893Sdim let EncoderMethod = "getAddrModeImm12OpValue"; 790226890Sdim let DecoderMethod = "DecodeAddrModeImm12Operand"; 791226890Sdim let ParserMatchClass = MemImm12OffsetAsmOperand; 792218893Sdim let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 793218893Sdim} 794252723Sdim 795252723Sdimdef addrmode_imm12 : AddrMode_Imm12 { 796252723Sdim let PrintMethod = "printAddrModeImm12Operand<false>"; 797252723Sdim} 798252723Sdim 799252723Sdimdef addrmode_imm12_pre : AddrMode_Imm12 { 800252723Sdim let PrintMethod = "printAddrModeImm12Operand<true>"; 801252723Sdim} 802252723Sdim 803218893Sdim// ldst_so_reg := reg +/- reg shop imm 804218893Sdim// 805226890Sdimdef MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; } 806218893Sdimdef ldst_so_reg : Operand<i32>, 807218893Sdim ComplexPattern<i32, 3, "SelectLdStSOReg", []> { 808218893Sdim let EncoderMethod = "getLdStSORegOpValue"; 809218893Sdim // FIXME: Simplify the printer 810218893Sdim let PrintMethod = "printAddrMode2Operand"; 811226890Sdim let DecoderMethod = "DecodeSORegMemOperand"; 812226890Sdim let ParserMatchClass = MemRegOffsetAsmOperand; 813226890Sdim let MIOperandInfo = (ops GPR:$base, GPRnopc:$offsreg, i32imm:$shift); 814218893Sdim} 815218893Sdim 816226890Sdim// postidx_imm8 := +/- [0,255] 817226890Sdim// 818226890Sdim// 9 bit value: 819226890Sdim// {8} 1 is imm8 is non-negative. 0 otherwise. 820226890Sdim// {7-0} [0,255] imm8 value. 821226890Sdimdef PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; } 822226890Sdimdef postidx_imm8 : Operand<i32> { 823226890Sdim let PrintMethod = "printPostIdxImm8Operand"; 824226890Sdim let ParserMatchClass = PostIdxImm8AsmOperand; 825226890Sdim let MIOperandInfo = (ops i32imm); 826226890Sdim} 827226890Sdim 828226890Sdim// postidx_imm8s4 := +/- [0,1020] 829226890Sdim// 830226890Sdim// 9 bit value: 831226890Sdim// {8} 1 is imm8 is non-negative. 0 otherwise. 832226890Sdim// {7-0} [0,255] imm8 value, scaled by 4. 833226890Sdimdef PostIdxImm8s4AsmOperand : AsmOperandClass { let Name = "PostIdxImm8s4"; } 834226890Sdimdef postidx_imm8s4 : Operand<i32> { 835226890Sdim let PrintMethod = "printPostIdxImm8s4Operand"; 836226890Sdim let ParserMatchClass = PostIdxImm8s4AsmOperand; 837226890Sdim let MIOperandInfo = (ops i32imm); 838226890Sdim} 839226890Sdim 840226890Sdim 841226890Sdim// postidx_reg := +/- reg 842226890Sdim// 843226890Sdimdef PostIdxRegAsmOperand : AsmOperandClass { 844226890Sdim let Name = "PostIdxReg"; 845226890Sdim let ParserMethod = "parsePostIdxReg"; 846226890Sdim} 847226890Sdimdef postidx_reg : Operand<i32> { 848226890Sdim let EncoderMethod = "getPostIdxRegOpValue"; 849226890Sdim let DecoderMethod = "DecodePostIdxReg"; 850226890Sdim let PrintMethod = "printPostIdxRegOperand"; 851226890Sdim let ParserMatchClass = PostIdxRegAsmOperand; 852235633Sdim let MIOperandInfo = (ops GPRnopc, i32imm); 853226890Sdim} 854226890Sdim 855226890Sdim 856193323Sed// addrmode2 := reg +/- imm12 857218893Sdim// := reg +/- reg shop imm 858193323Sed// 859226890Sdim// FIXME: addrmode2 should be refactored the rest of the way to always 860226890Sdim// use explicit imm vs. reg versions above (addrmode_imm12 and ldst_so_reg). 861226890Sdimdef AddrMode2AsmOperand : AsmOperandClass { let Name = "AddrMode2"; } 862193323Seddef addrmode2 : Operand<i32>, 863193323Sed ComplexPattern<i32, 3, "SelectAddrMode2", []> { 864218893Sdim let EncoderMethod = "getAddrMode2OpValue"; 865193323Sed let PrintMethod = "printAddrMode2Operand"; 866226890Sdim let ParserMatchClass = AddrMode2AsmOperand; 867193323Sed let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 868193323Sed} 869193323Sed 870226890Sdimdef PostIdxRegShiftedAsmOperand : AsmOperandClass { 871226890Sdim let Name = "PostIdxRegShifted"; 872226890Sdim let ParserMethod = "parsePostIdxReg"; 873226890Sdim} 874226890Sdimdef am2offset_reg : Operand<i32>, 875226890Sdim ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg", 876218893Sdim [], [SDNPWantRoot]> { 877218893Sdim let EncoderMethod = "getAddrMode2OffsetOpValue"; 878193323Sed let PrintMethod = "printAddrMode2OffsetOperand"; 879226890Sdim // When using this for assembly, it's always as a post-index offset. 880226890Sdim let ParserMatchClass = PostIdxRegShiftedAsmOperand; 881235633Sdim let MIOperandInfo = (ops GPRnopc, i32imm); 882193323Sed} 883193323Sed 884226890Sdim// FIXME: am2offset_imm should only need the immediate, not the GPR. Having 885226890Sdim// the GPR is purely vestigal at this point. 886226890Sdimdef AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; } 887226890Sdimdef am2offset_imm : Operand<i32>, 888226890Sdim ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm", 889226890Sdim [], [SDNPWantRoot]> { 890226890Sdim let EncoderMethod = "getAddrMode2OffsetOpValue"; 891226890Sdim let PrintMethod = "printAddrMode2OffsetOperand"; 892226890Sdim let ParserMatchClass = AM2OffsetImmAsmOperand; 893235633Sdim let MIOperandInfo = (ops GPRnopc, i32imm); 894226890Sdim} 895226890Sdim 896226890Sdim 897193323Sed// addrmode3 := reg +/- reg 898193323Sed// addrmode3 := reg +/- imm8 899193323Sed// 900226890Sdim// FIXME: split into imm vs. reg versions. 901226890Sdimdef AddrMode3AsmOperand : AsmOperandClass { let Name = "AddrMode3"; } 902252723Sdimclass AddrMode3 : Operand<i32>, 903252723Sdim ComplexPattern<i32, 3, "SelectAddrMode3", []> { 904218893Sdim let EncoderMethod = "getAddrMode3OpValue"; 905226890Sdim let ParserMatchClass = AddrMode3AsmOperand; 906193323Sed let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 907193323Sed} 908193323Sed 909252723Sdimdef addrmode3 : AddrMode3 910252723Sdim{ 911252723Sdim let PrintMethod = "printAddrMode3Operand<false>"; 912252723Sdim} 913252723Sdim 914252723Sdimdef addrmode3_pre : AddrMode3 915252723Sdim{ 916252723Sdim let PrintMethod = "printAddrMode3Operand<true>"; 917252723Sdim} 918252723Sdim 919226890Sdim// FIXME: split into imm vs. reg versions. 920226890Sdim// FIXME: parser method to handle +/- register. 921226890Sdimdef AM3OffsetAsmOperand : AsmOperandClass { 922226890Sdim let Name = "AM3Offset"; 923226890Sdim let ParserMethod = "parseAM3Offset"; 924226890Sdim} 925193323Seddef am3offset : Operand<i32>, 926218893Sdim ComplexPattern<i32, 2, "SelectAddrMode3Offset", 927218893Sdim [], [SDNPWantRoot]> { 928218893Sdim let EncoderMethod = "getAddrMode3OffsetOpValue"; 929193323Sed let PrintMethod = "printAddrMode3OffsetOperand"; 930226890Sdim let ParserMatchClass = AM3OffsetAsmOperand; 931193323Sed let MIOperandInfo = (ops GPR, i32imm); 932193323Sed} 933193323Sed 934218893Sdim// ldstm_mode := {ia, ib, da, db} 935193323Sed// 936218893Sdimdef ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> { 937218893Sdim let EncoderMethod = "getLdStmModeOpValue"; 938218893Sdim let PrintMethod = "printLdStmModeOperand"; 939193323Sed} 940193323Sed 941193323Sed// addrmode5 := reg +/- imm8*4 942193323Sed// 943226890Sdimdef AddrMode5AsmOperand : AsmOperandClass { let Name = "AddrMode5"; } 944252723Sdimclass AddrMode5 : Operand<i32>, 945252723Sdim ComplexPattern<i32, 2, "SelectAddrMode5", []> { 946226890Sdim let EncoderMethod = "getAddrMode5OpValue"; 947226890Sdim let DecoderMethod = "DecodeAddrMode5Operand"; 948226890Sdim let ParserMatchClass = AddrMode5AsmOperand; 949205218Srdivacky let MIOperandInfo = (ops GPR:$base, i32imm); 950193323Sed} 951193323Sed 952252723Sdimdef addrmode5 : AddrMode5 { 953252723Sdim let PrintMethod = "printAddrMode5Operand<false>"; 954252723Sdim} 955252723Sdim 956252723Sdimdef addrmode5_pre : AddrMode5 { 957252723Sdim let PrintMethod = "printAddrMode5Operand<true>"; 958252723Sdim} 959252723Sdim 960218893Sdim// addrmode6 := reg with optional alignment 961195340Sed// 962226890Sdimdef AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; } 963195340Seddef addrmode6 : Operand<i32>, 964218893Sdim ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 965195340Sed let PrintMethod = "printAddrMode6Operand"; 966226890Sdim let MIOperandInfo = (ops GPR:$addr, i32imm:$align); 967218893Sdim let EncoderMethod = "getAddrMode6AddressOpValue"; 968226890Sdim let DecoderMethod = "DecodeAddrMode6Operand"; 969226890Sdim let ParserMatchClass = AddrMode6AsmOperand; 970195340Sed} 971195340Sed 972219077Sdimdef am6offset : Operand<i32>, 973219077Sdim ComplexPattern<i32, 1, "SelectAddrMode6Offset", 974219077Sdim [], [SDNPWantRoot]> { 975205407Srdivacky let PrintMethod = "printAddrMode6OffsetOperand"; 976205407Srdivacky let MIOperandInfo = (ops GPR); 977218893Sdim let EncoderMethod = "getAddrMode6OffsetOpValue"; 978226890Sdim let DecoderMethod = "DecodeGPRRegisterClass"; 979205407Srdivacky} 980205407Srdivacky 981223017Sdim// Special version of addrmode6 to handle alignment encoding for VST1/VLD1 982223017Sdim// (single element from one lane) for size 32. 983223017Sdimdef addrmode6oneL32 : Operand<i32>, 984223017Sdim ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 985223017Sdim let PrintMethod = "printAddrMode6Operand"; 986223017Sdim let MIOperandInfo = (ops GPR:$addr, i32imm); 987223017Sdim let EncoderMethod = "getAddrMode6OneLane32AddressOpValue"; 988223017Sdim} 989223017Sdim 990218893Sdim// Special version of addrmode6 to handle alignment encoding for VLD-dup 991218893Sdim// instructions, specifically VLD4-dup. 992218893Sdimdef addrmode6dup : Operand<i32>, 993218893Sdim ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 994218893Sdim let PrintMethod = "printAddrMode6Operand"; 995218893Sdim let MIOperandInfo = (ops GPR:$addr, i32imm); 996218893Sdim let EncoderMethod = "getAddrMode6DupAddressOpValue"; 997235633Sdim // FIXME: This is close, but not quite right. The alignment specifier is 998235633Sdim // different. 999235633Sdim let ParserMatchClass = AddrMode6AsmOperand; 1000218893Sdim} 1001218893Sdim 1002193323Sed// addrmodepc := pc + reg 1003193323Sed// 1004193323Seddef addrmodepc : Operand<i32>, 1005193323Sed ComplexPattern<i32, 2, "SelectAddrModePC", []> { 1006193323Sed let PrintMethod = "printAddrModePCOperand"; 1007193323Sed let MIOperandInfo = (ops GPR, i32imm); 1008193323Sed} 1009193323Sed 1010226890Sdim// addr_offset_none := reg 1011221345Sdim// 1012226890Sdimdef MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; } 1013226890Sdimdef addr_offset_none : Operand<i32>, 1014226890Sdim ComplexPattern<i32, 1, "SelectAddrOffsetNone", []> { 1015221345Sdim let PrintMethod = "printAddrMode7Operand"; 1016226890Sdim let DecoderMethod = "DecodeAddrMode7Operand"; 1017226890Sdim let ParserMatchClass = MemNoOffsetAsmOperand; 1018226890Sdim let MIOperandInfo = (ops GPR:$base); 1019221345Sdim} 1020221345Sdim 1021198090Srdivackydef nohash_imm : Operand<i32> { 1022198090Srdivacky let PrintMethod = "printNoHashImmediate"; 1023193323Sed} 1024193323Sed 1025218893Sdimdef CoprocNumAsmOperand : AsmOperandClass { 1026218893Sdim let Name = "CoprocNum"; 1027226890Sdim let ParserMethod = "parseCoprocNumOperand"; 1028218893Sdim} 1029218893Sdimdef p_imm : Operand<i32> { 1030218893Sdim let PrintMethod = "printPImmediate"; 1031218893Sdim let ParserMatchClass = CoprocNumAsmOperand; 1032226890Sdim let DecoderMethod = "DecodeCoprocessor"; 1033218893Sdim} 1034218893Sdim 1035226890Sdimdef CoprocRegAsmOperand : AsmOperandClass { 1036226890Sdim let Name = "CoprocReg"; 1037226890Sdim let ParserMethod = "parseCoprocRegOperand"; 1038226890Sdim} 1039218893Sdimdef c_imm : Operand<i32> { 1040218893Sdim let PrintMethod = "printCImmediate"; 1041218893Sdim let ParserMatchClass = CoprocRegAsmOperand; 1042218893Sdim} 1043226890Sdimdef CoprocOptionAsmOperand : AsmOperandClass { 1044226890Sdim let Name = "CoprocOption"; 1045226890Sdim let ParserMethod = "parseCoprocOptionOperand"; 1046226890Sdim} 1047226890Sdimdef coproc_option_imm : Operand<i32> { 1048226890Sdim let PrintMethod = "printCoprocOptionImm"; 1049226890Sdim let ParserMatchClass = CoprocOptionAsmOperand; 1050226890Sdim} 1051218893Sdim 1052193323Sed//===----------------------------------------------------------------------===// 1053193323Sed 1054193323Sedinclude "ARMInstrFormats.td" 1055193323Sed 1056193323Sed//===----------------------------------------------------------------------===// 1057193323Sed// Multiclass helpers... 1058193323Sed// 1059193323Sed 1060193323Sed/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a 1061193323Sed/// binop that produces a value. 1062245431Sdimlet TwoOperandAliasConstraint = "$Rn = $Rd" in 1063218893Sdimmulticlass AsI1_bin_irs<bits<4> opcod, string opc, 1064218893Sdim InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 1065245431Sdim PatFrag opnode, bit Commutable = 0> { 1066212904Sdim // The register-immediate version is re-materializable. This is useful 1067212904Sdim // in particular for taking the address of a local. 1068212904Sdim let isReMaterializable = 1 in { 1069218893Sdim def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, 1070218893Sdim iii, opc, "\t$Rd, $Rn, $imm", 1071252723Sdim [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>, 1072252723Sdim Sched<[WriteALU, ReadALU]> { 1073218893Sdim bits<4> Rd; 1074218893Sdim bits<4> Rn; 1075218893Sdim bits<12> imm; 1076198090Srdivacky let Inst{25} = 1; 1077218893Sdim let Inst{19-16} = Rn; 1078218893Sdim let Inst{15-12} = Rd; 1079218893Sdim let Inst{11-0} = imm; 1080198090Srdivacky } 1081212904Sdim } 1082218893Sdim def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 1083218893Sdim iir, opc, "\t$Rd, $Rn, $Rm", 1084252723Sdim [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>, 1085252723Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 1086218893Sdim bits<4> Rd; 1087218893Sdim bits<4> Rn; 1088218893Sdim bits<4> Rm; 1089198090Srdivacky let Inst{25} = 0; 1090195098Sed let isCommutable = Commutable; 1091218893Sdim let Inst{19-16} = Rn; 1092218893Sdim let Inst{15-12} = Rd; 1093218893Sdim let Inst{11-4} = 0b00000000; 1094218893Sdim let Inst{3-0} = Rm; 1095195098Sed } 1096226890Sdim 1097226890Sdim def rsi : AsI1<opcod, (outs GPR:$Rd), 1098226890Sdim (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, 1099218893Sdim iis, opc, "\t$Rd, $Rn, $shift", 1100252723Sdim [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]>, 1101252723Sdim Sched<[WriteALUsi, ReadALU]> { 1102218893Sdim bits<4> Rd; 1103218893Sdim bits<4> Rn; 1104218893Sdim bits<12> shift; 1105198090Srdivacky let Inst{25} = 0; 1106218893Sdim let Inst{19-16} = Rn; 1107218893Sdim let Inst{15-12} = Rd; 1108226890Sdim let Inst{11-5} = shift{11-5}; 1109226890Sdim let Inst{4} = 0; 1110226890Sdim let Inst{3-0} = shift{3-0}; 1111198090Srdivacky } 1112224145Sdim 1113226890Sdim def rsr : AsI1<opcod, (outs GPR:$Rd), 1114226890Sdim (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, 1115226890Sdim iis, opc, "\t$Rd, $Rn, $shift", 1116252723Sdim [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]>, 1117252723Sdim Sched<[WriteALUsr, ReadALUsr]> { 1118226890Sdim bits<4> Rd; 1119226890Sdim bits<4> Rn; 1120226890Sdim bits<12> shift; 1121226890Sdim let Inst{25} = 0; 1122226890Sdim let Inst{19-16} = Rn; 1123226890Sdim let Inst{15-12} = Rd; 1124226890Sdim let Inst{11-8} = shift{11-8}; 1125226890Sdim let Inst{7} = 0; 1126226890Sdim let Inst{6-5} = shift{6-5}; 1127226890Sdim let Inst{4} = 1; 1128226890Sdim let Inst{3-0} = shift{3-0}; 1129226890Sdim } 1130193323Sed} 1131193323Sed 1132226890Sdim/// AsI1_rbin_irs - Same as AsI1_bin_irs except the order of operands are 1133226890Sdim/// reversed. The 'rr' form is only defined for the disassembler; for codegen 1134226890Sdim/// it is equivalent to the AsI1_bin_irs counterpart. 1135245431Sdimlet TwoOperandAliasConstraint = "$Rn = $Rd" in 1136226890Sdimmulticlass AsI1_rbin_irs<bits<4> opcod, string opc, 1137218893Sdim InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 1138245431Sdim PatFrag opnode, bit Commutable = 0> { 1139226890Sdim // The register-immediate version is re-materializable. This is useful 1140226890Sdim // in particular for taking the address of a local. 1141226890Sdim let isReMaterializable = 1 in { 1142226890Sdim def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, 1143218893Sdim iii, opc, "\t$Rd, $Rn, $imm", 1144252723Sdim [(set GPR:$Rd, (opnode so_imm:$imm, GPR:$Rn))]>, 1145252723Sdim Sched<[WriteALU, ReadALU]> { 1146218893Sdim bits<4> Rd; 1147218893Sdim bits<4> Rn; 1148218893Sdim bits<12> imm; 1149218893Sdim let Inst{25} = 1; 1150218893Sdim let Inst{19-16} = Rn; 1151218893Sdim let Inst{15-12} = Rd; 1152218893Sdim let Inst{11-0} = imm; 1153198090Srdivacky } 1154226890Sdim } 1155226890Sdim def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 1156218893Sdim iir, opc, "\t$Rd, $Rn, $Rm", 1157252723Sdim [/* pattern left blank */]>, 1158252723Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 1159218893Sdim bits<4> Rd; 1160218893Sdim bits<4> Rn; 1161218893Sdim bits<4> Rm; 1162226890Sdim let Inst{11-4} = 0b00000000; 1163218893Sdim let Inst{25} = 0; 1164226890Sdim let Inst{3-0} = Rm; 1165226890Sdim let Inst{15-12} = Rd; 1166218893Sdim let Inst{19-16} = Rn; 1167226890Sdim } 1168226890Sdim 1169226890Sdim def rsi : AsI1<opcod, (outs GPR:$Rd), 1170226890Sdim (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, 1171226890Sdim iis, opc, "\t$Rd, $Rn, $shift", 1172252723Sdim [(set GPR:$Rd, (opnode so_reg_imm:$shift, GPR:$Rn))]>, 1173252723Sdim Sched<[WriteALUsi, ReadALU]> { 1174226890Sdim bits<4> Rd; 1175226890Sdim bits<4> Rn; 1176226890Sdim bits<12> shift; 1177226890Sdim let Inst{25} = 0; 1178226890Sdim let Inst{19-16} = Rn; 1179218893Sdim let Inst{15-12} = Rd; 1180226890Sdim let Inst{11-5} = shift{11-5}; 1181226890Sdim let Inst{4} = 0; 1182226890Sdim let Inst{3-0} = shift{3-0}; 1183218893Sdim } 1184226890Sdim 1185226890Sdim def rsr : AsI1<opcod, (outs GPR:$Rd), 1186226890Sdim (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, 1187218893Sdim iis, opc, "\t$Rd, $Rn, $shift", 1188252723Sdim [(set GPR:$Rd, (opnode so_reg_reg:$shift, GPR:$Rn))]>, 1189252723Sdim Sched<[WriteALUsr, ReadALUsr]> { 1190218893Sdim bits<4> Rd; 1191218893Sdim bits<4> Rn; 1192218893Sdim bits<12> shift; 1193198090Srdivacky let Inst{25} = 0; 1194218893Sdim let Inst{19-16} = Rn; 1195218893Sdim let Inst{15-12} = Rd; 1196226890Sdim let Inst{11-8} = shift{11-8}; 1197226890Sdim let Inst{7} = 0; 1198226890Sdim let Inst{6-5} = shift{6-5}; 1199226890Sdim let Inst{4} = 1; 1200226890Sdim let Inst{3-0} = shift{3-0}; 1201198090Srdivacky } 1202193323Sed} 1203226890Sdim 1204235633Sdim/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default. 1205226890Sdim/// 1206226890Sdim/// These opcodes will be converted to the real non-S opcodes by 1207235633Sdim/// AdjustInstrPostInstrSelection after giving them an optional CPSR operand. 1208235633Sdimlet hasPostISelHook = 1, Defs = [CPSR] in { 1209235633Sdimmulticlass AsI1_bin_s_irs<InstrItinClass iii, InstrItinClass iir, 1210235633Sdim InstrItinClass iis, PatFrag opnode, 1211235633Sdim bit Commutable = 0> { 1212235633Sdim def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p), 1213235633Sdim 4, iii, 1214252723Sdim [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm))]>, 1215252723Sdim Sched<[WriteALU, ReadALU]>; 1216226890Sdim 1217235633Sdim def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p), 1218235633Sdim 4, iir, 1219252723Sdim [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]>, 1220252723Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 1221235633Sdim let isCommutable = Commutable; 1222235633Sdim } 1223235633Sdim def rsi : ARMPseudoInst<(outs GPR:$Rd), 1224235633Sdim (ins GPR:$Rn, so_reg_imm:$shift, pred:$p), 1225235633Sdim 4, iis, 1226235633Sdim [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, 1227252723Sdim so_reg_imm:$shift))]>, 1228252723Sdim Sched<[WriteALUsi, ReadALU]>; 1229226890Sdim 1230235633Sdim def rsr : ARMPseudoInst<(outs GPR:$Rd), 1231235633Sdim (ins GPR:$Rn, so_reg_reg:$shift, pred:$p), 1232235633Sdim 4, iis, 1233235633Sdim [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, 1234252723Sdim so_reg_reg:$shift))]>, 1235252723Sdim Sched<[WriteALUSsr, ReadALUsr]>; 1236193323Sed} 1237226890Sdim} 1238193323Sed 1239235633Sdim/// AsI1_rbin_s_is - Same as AsI1_bin_s_irs, except selection DAG 1240235633Sdim/// operands are reversed. 1241235633Sdimlet hasPostISelHook = 1, Defs = [CPSR] in { 1242235633Sdimmulticlass AsI1_rbin_s_is<InstrItinClass iii, InstrItinClass iir, 1243235633Sdim InstrItinClass iis, PatFrag opnode, 1244235633Sdim bit Commutable = 0> { 1245235633Sdim def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p), 1246235633Sdim 4, iii, 1247252723Sdim [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn))]>, 1248252723Sdim Sched<[WriteALU, ReadALU]>; 1249226890Sdim 1250235633Sdim def rsi : ARMPseudoInst<(outs GPR:$Rd), 1251235633Sdim (ins GPR:$Rn, so_reg_imm:$shift, pred:$p), 1252235633Sdim 4, iis, 1253235633Sdim [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, 1254252723Sdim GPR:$Rn))]>, 1255252723Sdim Sched<[WriteALUsi, ReadALU]>; 1256235633Sdim 1257235633Sdim def rsr : ARMPseudoInst<(outs GPR:$Rd), 1258235633Sdim (ins GPR:$Rn, so_reg_reg:$shift, pred:$p), 1259235633Sdim 4, iis, 1260235633Sdim [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, 1261252723Sdim GPR:$Rn))]>, 1262252723Sdim Sched<[WriteALUSsr, ReadALUsr]>; 1263226890Sdim} 1264226890Sdim} 1265226890Sdim 1266193323Sed/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 1267193323Sed/// patterns. Similar to AsI1_bin_irs except the instruction does not produce 1268193323Sed/// a explicit result, only implicitly set CPSR. 1269212904Sdimlet isCompare = 1, Defs = [CPSR] in { 1270218893Sdimmulticlass AI1_cmp_irs<bits<4> opcod, string opc, 1271218893Sdim InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 1272218893Sdim PatFrag opnode, bit Commutable = 0> { 1273218893Sdim def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii, 1274218893Sdim opc, "\t$Rn, $imm", 1275252723Sdim [(opnode GPR:$Rn, so_imm:$imm)]>, 1276252723Sdim Sched<[WriteCMP, ReadALU]> { 1277218893Sdim bits<4> Rn; 1278218893Sdim bits<12> imm; 1279218893Sdim let Inst{25} = 1; 1280198090Srdivacky let Inst{20} = 1; 1281218893Sdim let Inst{19-16} = Rn; 1282218893Sdim let Inst{15-12} = 0b0000; 1283218893Sdim let Inst{11-0} = imm; 1284235633Sdim 1285235633Sdim let Unpredictable{15-12} = 0b1111; 1286198090Srdivacky } 1287218893Sdim def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir, 1288218893Sdim opc, "\t$Rn, $Rm", 1289252723Sdim [(opnode GPR:$Rn, GPR:$Rm)]>, 1290252723Sdim Sched<[WriteCMP, ReadALU, ReadALU]> { 1291218893Sdim bits<4> Rn; 1292218893Sdim bits<4> Rm; 1293218893Sdim let isCommutable = Commutable; 1294218893Sdim let Inst{25} = 0; 1295218893Sdim let Inst{20} = 1; 1296218893Sdim let Inst{19-16} = Rn; 1297218893Sdim let Inst{15-12} = 0b0000; 1298199481Srdivacky let Inst{11-4} = 0b00000000; 1299218893Sdim let Inst{3-0} = Rm; 1300235633Sdim 1301235633Sdim let Unpredictable{15-12} = 0b1111; 1302218893Sdim } 1303226890Sdim def rsi : AI1<opcod, (outs), 1304226890Sdim (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, iis, 1305218893Sdim opc, "\t$Rn, $shift", 1306252723Sdim [(opnode GPR:$Rn, so_reg_imm:$shift)]>, 1307252723Sdim Sched<[WriteCMPsi, ReadALU]> { 1308218893Sdim bits<4> Rn; 1309218893Sdim bits<12> shift; 1310198090Srdivacky let Inst{25} = 0; 1311198090Srdivacky let Inst{20} = 1; 1312218893Sdim let Inst{19-16} = Rn; 1313218893Sdim let Inst{15-12} = 0b0000; 1314226890Sdim let Inst{11-5} = shift{11-5}; 1315226890Sdim let Inst{4} = 0; 1316226890Sdim let Inst{3-0} = shift{3-0}; 1317235633Sdim 1318235633Sdim let Unpredictable{15-12} = 0b1111; 1319198090Srdivacky } 1320226890Sdim def rsr : AI1<opcod, (outs), 1321235633Sdim (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis, 1322226890Sdim opc, "\t$Rn, $shift", 1323252723Sdim [(opnode GPRnopc:$Rn, so_reg_reg:$shift)]>, 1324252723Sdim Sched<[WriteCMPsr, ReadALU]> { 1325226890Sdim bits<4> Rn; 1326226890Sdim bits<12> shift; 1327226890Sdim let Inst{25} = 0; 1328226890Sdim let Inst{20} = 1; 1329226890Sdim let Inst{19-16} = Rn; 1330226890Sdim let Inst{15-12} = 0b0000; 1331226890Sdim let Inst{11-8} = shift{11-8}; 1332226890Sdim let Inst{7} = 0; 1333226890Sdim let Inst{6-5} = shift{6-5}; 1334226890Sdim let Inst{4} = 1; 1335226890Sdim let Inst{3-0} = shift{3-0}; 1336235633Sdim 1337235633Sdim let Unpredictable{15-12} = 0b1111; 1338226890Sdim } 1339226890Sdim 1340193323Sed} 1341193323Sed} 1342193323Sed 1343218893Sdim/// AI_ext_rrot - A unary operation with two forms: one whose operand is a 1344193323Sed/// register and one whose operand is a register rotated by 8/16/24. 1345193323Sed/// FIXME: Remove the 'r' variant. Its rot_imm is zero. 1346226890Sdimclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> 1347226890Sdim : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot), 1348226890Sdim IIC_iEXTr, opc, "\t$Rd, $Rm$rot", 1349226890Sdim [(set GPRnopc:$Rd, (opnode (rotr GPRnopc:$Rm, rot_imm:$rot)))]>, 1350263509Sdim Requires<[IsARM, HasV6]>, Sched<[WriteALUsi]> { 1351226890Sdim bits<4> Rd; 1352226890Sdim bits<4> Rm; 1353226890Sdim bits<2> rot; 1354226890Sdim let Inst{19-16} = 0b1111; 1355226890Sdim let Inst{15-12} = Rd; 1356226890Sdim let Inst{11-10} = rot; 1357226890Sdim let Inst{3-0} = Rm; 1358193323Sed} 1359193323Sed 1360226890Sdimclass AI_ext_rrot_np<bits<8> opcod, string opc> 1361226890Sdim : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot), 1362226890Sdim IIC_iEXTr, opc, "\t$Rd, $Rm$rot", []>, 1363263509Sdim Requires<[IsARM, HasV6]>, Sched<[WriteALUsi]> { 1364226890Sdim bits<2> rot; 1365226890Sdim let Inst{19-16} = 0b1111; 1366226890Sdim let Inst{11-10} = rot; 1367263509Sdim } 1368204642Srdivacky 1369218893Sdim/// AI_exta_rrot - A binary operation with two forms: one whose operand is a 1370193323Sed/// register and one whose operand is a register rotated by 8/16/24. 1371226890Sdimclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> 1372226890Sdim : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot), 1373226890Sdim IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", 1374226890Sdim [(set GPRnopc:$Rd, (opnode GPR:$Rn, 1375226890Sdim (rotr GPRnopc:$Rm, rot_imm:$rot)))]>, 1376263509Sdim Requires<[IsARM, HasV6]>, Sched<[WriteALUsr]> { 1377226890Sdim bits<4> Rd; 1378226890Sdim bits<4> Rm; 1379226890Sdim bits<4> Rn; 1380226890Sdim bits<2> rot; 1381226890Sdim let Inst{19-16} = Rn; 1382226890Sdim let Inst{15-12} = Rd; 1383226890Sdim let Inst{11-10} = rot; 1384226890Sdim let Inst{9-4} = 0b000111; 1385226890Sdim let Inst{3-0} = Rm; 1386226890Sdim} 1387226890Sdim 1388226890Sdimclass AI_exta_rrot_np<bits<8> opcod, string opc> 1389226890Sdim : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot), 1390226890Sdim IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", []>, 1391263509Sdim Requires<[IsARM, HasV6]>, Sched<[WriteALUsr]> { 1392226890Sdim bits<4> Rn; 1393226890Sdim bits<2> rot; 1394226890Sdim let Inst{19-16} = Rn; 1395226890Sdim let Inst{11-10} = rot; 1396226890Sdim} 1397226890Sdim 1398226890Sdim/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. 1399245431Sdimlet TwoOperandAliasConstraint = "$Rn = $Rd" in 1400226890Sdimmulticlass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 1401245431Sdim bit Commutable = 0> { 1402226890Sdim let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { 1403226890Sdim def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 1404226890Sdim DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 1405226890Sdim [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm, CPSR))]>, 1406252723Sdim Requires<[IsARM]>, 1407252723Sdim Sched<[WriteALU, ReadALU]> { 1408218893Sdim bits<4> Rd; 1409218893Sdim bits<4> Rn; 1410226890Sdim bits<12> imm; 1411226890Sdim let Inst{25} = 1; 1412226890Sdim let Inst{15-12} = Rd; 1413218893Sdim let Inst{19-16} = Rn; 1414226890Sdim let Inst{11-0} = imm; 1415226890Sdim } 1416226890Sdim def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 1417226890Sdim DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm", 1418226890Sdim [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm, CPSR))]>, 1419252723Sdim Requires<[IsARM]>, 1420252723Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 1421226890Sdim bits<4> Rd; 1422226890Sdim bits<4> Rn; 1423226890Sdim bits<4> Rm; 1424226890Sdim let Inst{11-4} = 0b00000000; 1425226890Sdim let Inst{25} = 0; 1426226890Sdim let isCommutable = Commutable; 1427226890Sdim let Inst{3-0} = Rm; 1428218893Sdim let Inst{15-12} = Rd; 1429226890Sdim let Inst{19-16} = Rn; 1430198892Srdivacky } 1431226890Sdim def rsi : AsI1<opcod, (outs GPR:$Rd), 1432226890Sdim (ins GPR:$Rn, so_reg_imm:$shift), 1433226890Sdim DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 1434226890Sdim [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_imm:$shift, CPSR))]>, 1435252723Sdim Requires<[IsARM]>, 1436252723Sdim Sched<[WriteALUsi, ReadALU]> { 1437218893Sdim bits<4> Rd; 1438218893Sdim bits<4> Rn; 1439226890Sdim bits<12> shift; 1440226890Sdim let Inst{25} = 0; 1441218893Sdim let Inst{19-16} = Rn; 1442218893Sdim let Inst{15-12} = Rd; 1443226890Sdim let Inst{11-5} = shift{11-5}; 1444226890Sdim let Inst{4} = 0; 1445226890Sdim let Inst{3-0} = shift{3-0}; 1446218893Sdim } 1447235633Sdim def rsr : AsI1<opcod, (outs GPRnopc:$Rd), 1448235633Sdim (ins GPRnopc:$Rn, so_reg_reg:$shift), 1449226890Sdim DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 1450245431Sdim [(set GPRnopc:$Rd, CPSR, 1451245431Sdim (opnode GPRnopc:$Rn, so_reg_reg:$shift, CPSR))]>, 1452252723Sdim Requires<[IsARM]>, 1453252723Sdim Sched<[WriteALUsr, ReadALUsr]> { 1454226890Sdim bits<4> Rd; 1455218893Sdim bits<4> Rn; 1456226890Sdim bits<12> shift; 1457226890Sdim let Inst{25} = 0; 1458218893Sdim let Inst{19-16} = Rn; 1459226890Sdim let Inst{15-12} = Rd; 1460226890Sdim let Inst{11-8} = shift{11-8}; 1461226890Sdim let Inst{7} = 0; 1462226890Sdim let Inst{6-5} = shift{6-5}; 1463226890Sdim let Inst{4} = 1; 1464226890Sdim let Inst{3-0} = shift{3-0}; 1465218893Sdim } 1466226890Sdim } 1467204642Srdivacky} 1468204642Srdivacky 1469226890Sdim/// AI1_rsc_irs - Define instructions and patterns for rsc 1470245431Sdimlet TwoOperandAliasConstraint = "$Rn = $Rd" in 1471245431Sdimmulticlass AI1_rsc_irs<bits<4> opcod, string opc, PatFrag opnode> { 1472226890Sdim let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { 1473218893Sdim def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 1474218893Sdim DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 1475226890Sdim [(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn, CPSR))]>, 1476252723Sdim Requires<[IsARM]>, 1477252723Sdim Sched<[WriteALU, ReadALU]> { 1478218893Sdim bits<4> Rd; 1479218893Sdim bits<4> Rn; 1480218893Sdim bits<12> imm; 1481198090Srdivacky let Inst{25} = 1; 1482218893Sdim let Inst{15-12} = Rd; 1483218893Sdim let Inst{19-16} = Rn; 1484218893Sdim let Inst{11-0} = imm; 1485198090Srdivacky } 1486218893Sdim def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 1487218893Sdim DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm", 1488252723Sdim [/* pattern left blank */]>, 1489252723Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 1490218893Sdim bits<4> Rd; 1491218893Sdim bits<4> Rn; 1492218893Sdim bits<4> Rm; 1493199481Srdivacky let Inst{11-4} = 0b00000000; 1494198090Srdivacky let Inst{25} = 0; 1495218893Sdim let Inst{3-0} = Rm; 1496218893Sdim let Inst{15-12} = Rd; 1497218893Sdim let Inst{19-16} = Rn; 1498195098Sed } 1499226890Sdim def rsi : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift), 1500226890Sdim DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 1501226890Sdim [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, GPR:$Rn, CPSR))]>, 1502252723Sdim Requires<[IsARM]>, 1503252723Sdim Sched<[WriteALUsi, ReadALU]> { 1504218893Sdim bits<4> Rd; 1505218893Sdim bits<4> Rn; 1506218893Sdim bits<12> shift; 1507198090Srdivacky let Inst{25} = 0; 1508226890Sdim let Inst{19-16} = Rn; 1509218893Sdim let Inst{15-12} = Rd; 1510226890Sdim let Inst{11-5} = shift{11-5}; 1511226890Sdim let Inst{4} = 0; 1512226890Sdim let Inst{3-0} = shift{3-0}; 1513226890Sdim } 1514226890Sdim def rsr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift), 1515226890Sdim DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 1516226890Sdim [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, GPR:$Rn, CPSR))]>, 1517252723Sdim Requires<[IsARM]>, 1518252723Sdim Sched<[WriteALUsr, ReadALUsr]> { 1519226890Sdim bits<4> Rd; 1520226890Sdim bits<4> Rn; 1521226890Sdim bits<12> shift; 1522226890Sdim let Inst{25} = 0; 1523218893Sdim let Inst{19-16} = Rn; 1524226890Sdim let Inst{15-12} = Rd; 1525226890Sdim let Inst{11-8} = shift{11-8}; 1526226890Sdim let Inst{7} = 0; 1527226890Sdim let Inst{6-5} = shift{6-5}; 1528226890Sdim let Inst{4} = 1; 1529226890Sdim let Inst{3-0} = shift{3-0}; 1530198090Srdivacky } 1531224145Sdim } 1532199481Srdivacky} 1533221345Sdim 1534218893Sdimlet canFoldAsLoad = 1, isReMaterializable = 1 in { 1535218893Sdimmulticlass AI_ldr1<bit isByte, string opc, InstrItinClass iii, 1536218893Sdim InstrItinClass iir, PatFrag opnode> { 1537218893Sdim // Note: We use the complex addrmode_imm12 rather than just an input 1538218893Sdim // GPR and a constrained immediate so that we can use this to match 1539218893Sdim // frame index references and avoid matching constant pool references. 1540218893Sdim def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr), 1541218893Sdim AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", 1542218893Sdim [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> { 1543218893Sdim bits<4> Rt; 1544218893Sdim bits<17> addr; 1545218893Sdim let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1546218893Sdim let Inst{19-16} = addr{16-13}; // Rn 1547218893Sdim let Inst{15-12} = Rt; 1548218893Sdim let Inst{11-0} = addr{11-0}; // imm12 1549218893Sdim } 1550218893Sdim def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift), 1551218893Sdim AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", 1552218893Sdim [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> { 1553218893Sdim bits<4> Rt; 1554218893Sdim bits<17> shift; 1555221345Sdim let shift{4} = 0; // Inst{4} = 0 1556218893Sdim let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1557218893Sdim let Inst{19-16} = shift{16-13}; // Rn 1558218893Sdim let Inst{15-12} = Rt; 1559218893Sdim let Inst{11-0} = shift{11-0}; 1560218893Sdim } 1561218893Sdim} 1562218893Sdim} 1563218893Sdim 1564226890Sdimlet canFoldAsLoad = 1, isReMaterializable = 1 in { 1565226890Sdimmulticlass AI_ldr1nopc<bit isByte, string opc, InstrItinClass iii, 1566226890Sdim InstrItinClass iir, PatFrag opnode> { 1567226890Sdim // Note: We use the complex addrmode_imm12 rather than just an input 1568226890Sdim // GPR and a constrained immediate so that we can use this to match 1569226890Sdim // frame index references and avoid matching constant pool references. 1570245431Sdim def i12: AI2ldst<0b010, 1, isByte, (outs GPRnopc:$Rt), 1571245431Sdim (ins addrmode_imm12:$addr), 1572226890Sdim AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", 1573245431Sdim [(set GPRnopc:$Rt, (opnode addrmode_imm12:$addr))]> { 1574226890Sdim bits<4> Rt; 1575226890Sdim bits<17> addr; 1576226890Sdim let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1577226890Sdim let Inst{19-16} = addr{16-13}; // Rn 1578226890Sdim let Inst{15-12} = Rt; 1579226890Sdim let Inst{11-0} = addr{11-0}; // imm12 1580226890Sdim } 1581245431Sdim def rs : AI2ldst<0b011, 1, isByte, (outs GPRnopc:$Rt), 1582245431Sdim (ins ldst_so_reg:$shift), 1583245431Sdim AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", 1584245431Sdim [(set GPRnopc:$Rt, (opnode ldst_so_reg:$shift))]> { 1585226890Sdim bits<4> Rt; 1586226890Sdim bits<17> shift; 1587226890Sdim let shift{4} = 0; // Inst{4} = 0 1588226890Sdim let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1589226890Sdim let Inst{19-16} = shift{16-13}; // Rn 1590226890Sdim let Inst{15-12} = Rt; 1591226890Sdim let Inst{11-0} = shift{11-0}; 1592226890Sdim } 1593226890Sdim} 1594226890Sdim} 1595226890Sdim 1596226890Sdim 1597218893Sdimmulticlass AI_str1<bit isByte, string opc, InstrItinClass iii, 1598218893Sdim InstrItinClass iir, PatFrag opnode> { 1599218893Sdim // Note: We use the complex addrmode_imm12 rather than just an input 1600218893Sdim // GPR and a constrained immediate so that we can use this to match 1601218893Sdim // frame index references and avoid matching constant pool references. 1602218893Sdim def i12 : AI2ldst<0b010, 0, isByte, (outs), 1603218893Sdim (ins GPR:$Rt, addrmode_imm12:$addr), 1604218893Sdim AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", 1605218893Sdim [(opnode GPR:$Rt, addrmode_imm12:$addr)]> { 1606218893Sdim bits<4> Rt; 1607218893Sdim bits<17> addr; 1608218893Sdim let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1609218893Sdim let Inst{19-16} = addr{16-13}; // Rn 1610218893Sdim let Inst{15-12} = Rt; 1611218893Sdim let Inst{11-0} = addr{11-0}; // imm12 1612218893Sdim } 1613218893Sdim def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift), 1614218893Sdim AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", 1615218893Sdim [(opnode GPR:$Rt, ldst_so_reg:$shift)]> { 1616218893Sdim bits<4> Rt; 1617218893Sdim bits<17> shift; 1618221345Sdim let shift{4} = 0; // Inst{4} = 0 1619218893Sdim let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1620218893Sdim let Inst{19-16} = shift{16-13}; // Rn 1621218893Sdim let Inst{15-12} = Rt; 1622218893Sdim let Inst{11-0} = shift{11-0}; 1623218893Sdim } 1624218893Sdim} 1625226890Sdim 1626226890Sdimmulticlass AI_str1nopc<bit isByte, string opc, InstrItinClass iii, 1627226890Sdim InstrItinClass iir, PatFrag opnode> { 1628226890Sdim // Note: We use the complex addrmode_imm12 rather than just an input 1629226890Sdim // GPR and a constrained immediate so that we can use this to match 1630226890Sdim // frame index references and avoid matching constant pool references. 1631226890Sdim def i12 : AI2ldst<0b010, 0, isByte, (outs), 1632226890Sdim (ins GPRnopc:$Rt, addrmode_imm12:$addr), 1633226890Sdim AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", 1634226890Sdim [(opnode GPRnopc:$Rt, addrmode_imm12:$addr)]> { 1635226890Sdim bits<4> Rt; 1636226890Sdim bits<17> addr; 1637226890Sdim let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1638226890Sdim let Inst{19-16} = addr{16-13}; // Rn 1639226890Sdim let Inst{15-12} = Rt; 1640226890Sdim let Inst{11-0} = addr{11-0}; // imm12 1641226890Sdim } 1642245431Sdim def rs : AI2ldst<0b011, 0, isByte, (outs), 1643245431Sdim (ins GPRnopc:$Rt, ldst_so_reg:$shift), 1644245431Sdim AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", 1645245431Sdim [(opnode GPRnopc:$Rt, ldst_so_reg:$shift)]> { 1646226890Sdim bits<4> Rt; 1647226890Sdim bits<17> shift; 1648226890Sdim let shift{4} = 0; // Inst{4} = 0 1649226890Sdim let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1650226890Sdim let Inst{19-16} = shift{16-13}; // Rn 1651226890Sdim let Inst{15-12} = Rt; 1652226890Sdim let Inst{11-0} = shift{11-0}; 1653226890Sdim } 1654226890Sdim} 1655226890Sdim 1656226890Sdim 1657193323Sed//===----------------------------------------------------------------------===// 1658193323Sed// Instructions 1659193323Sed//===----------------------------------------------------------------------===// 1660193323Sed 1661193323Sed//===----------------------------------------------------------------------===// 1662193323Sed// Miscellaneous Instructions. 1663193323Sed// 1664193323Sed 1665193323Sed/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in 1666193323Sed/// the function. The first operand is the ID# for this instruction, the second 1667193323Sed/// is the index into the MachineConstantPool that this is, the third is the 1668193323Sed/// size in bytes of this constant pool entry. 1669194178Sedlet neverHasSideEffects = 1, isNotDuplicable = 1 in 1670193323Seddef CONSTPOOL_ENTRY : 1671193323SedPseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 1672218893Sdim i32imm:$size), NoItinerary, []>; 1673193323Sed 1674204642Srdivacky// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE 1675204642Srdivacky// from removing one half of the matched pairs. That breaks PEI, which assumes 1676204642Srdivacky// these will always be in pairs, and asserts if it finds otherwise. Better way? 1677204642Srdivackylet Defs = [SP], Uses = [SP], hasSideEffects = 1 in { 1678193323Seddef ADJCALLSTACKUP : 1679198090SrdivackyPseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, 1680193323Sed [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; 1681193323Sed 1682204642Srdivackydef ADJCALLSTACKDOWN : 1683198090SrdivackyPseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, 1684193323Sed [(ARMcallseq_start timm:$amt)]>; 1685193323Sed} 1686193323Sed 1687263509Sdimdef HINT : AI<(outs), (ins imm0_239:$imm), MiscFrm, NoItinerary, 1688245431Sdim "hint", "\t$imm", []>, Requires<[IsARM, HasV6]> { 1689263509Sdim bits<8> imm; 1690263509Sdim let Inst{27-8} = 0b00110010000011110000; 1691263509Sdim let Inst{7-0} = imm; 1692203954Srdivacky} 1693203954Srdivacky 1694245431Sdimdef : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1695245431Sdimdef : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1696245431Sdimdef : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1697245431Sdimdef : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1698245431Sdimdef : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6T2]>; 1699263509Sdimdef : InstAlias<"sevl$p", (HINT 5, pred:$p)>, Requires<[IsARM, HasV8]>; 1700203954Srdivacky 1701263509Sdimdef : Pat<(int_arm_sevl), (HINT 5)>; 1702263509Sdim 1703226890Sdimdef SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel", 1704226890Sdim "\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> { 1705218893Sdim bits<4> Rd; 1706218893Sdim bits<4> Rn; 1707218893Sdim bits<4> Rm; 1708218893Sdim let Inst{3-0} = Rm; 1709218893Sdim let Inst{15-12} = Rd; 1710218893Sdim let Inst{19-16} = Rn; 1711204642Srdivacky let Inst{27-20} = 0b01101000; 1712204642Srdivacky let Inst{7-4} = 0b1011; 1713218893Sdim let Inst{11-8} = 0b1111; 1714245431Sdim let Unpredictable{11-8} = 0b1111; 1715204642Srdivacky} 1716204642Srdivacky 1717245431Sdim// The 16-bit operand $val can be used by a debugger to store more information 1718203954Srdivacky// about the breakpoint. 1719263509Sdimdef BKPT : AInoP<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary, 1720263509Sdim "bkpt", "\t$val", []>, Requires<[IsARM]> { 1721218893Sdim bits<16> val; 1722218893Sdim let Inst{3-0} = val{3-0}; 1723218893Sdim let Inst{19-8} = val{15-4}; 1724203954Srdivacky let Inst{27-20} = 0b00010010; 1725263509Sdim let Inst{31-28} = 0xe; // AL 1726203954Srdivacky let Inst{7-4} = 0b0111; 1727203954Srdivacky} 1728203954Srdivacky 1729263509Sdimdef HLT : AInoP<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary, 1730263509Sdim "hlt", "\t$val", []>, Requires<[IsARM, HasV8]> { 1731263509Sdim bits<16> val; 1732263509Sdim let Inst{3-0} = val{3-0}; 1733263509Sdim let Inst{19-8} = val{15-4}; 1734263509Sdim let Inst{27-20} = 0b00010000; 1735263509Sdim let Inst{31-28} = 0xe; // AL 1736263509Sdim let Inst{7-4} = 0b0111; 1737263509Sdim} 1738263509Sdim 1739226890Sdim// Change Processor State 1740226890Sdim// FIXME: We should use InstAlias to handle the optional operands. 1741218893Sdimclass CPS<dag iops, string asm_ops> 1742218893Sdim : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops), 1743226890Sdim []>, Requires<[IsARM]> { 1744218893Sdim bits<2> imod; 1745218893Sdim bits<3> iflags; 1746218893Sdim bits<5> mode; 1747218893Sdim bit M; 1748218893Sdim 1749203954Srdivacky let Inst{31-28} = 0b1111; 1750203954Srdivacky let Inst{27-20} = 0b00010000; 1751218893Sdim let Inst{19-18} = imod; 1752218893Sdim let Inst{17} = M; // Enabled if mode is set; 1753235633Sdim let Inst{16-9} = 0b00000000; 1754218893Sdim let Inst{8-6} = iflags; 1755218893Sdim let Inst{5} = 0; 1756218893Sdim let Inst{4-0} = mode; 1757203954Srdivacky} 1758203954Srdivacky 1759226890Sdimlet DecoderMethod = "DecodeCPSInstruction" in { 1760218893Sdimlet M = 1 in 1761226890Sdim def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, imm0_31:$mode), 1762218893Sdim "$imod\t$iflags, $mode">; 1763218893Sdimlet mode = 0, M = 0 in 1764218893Sdim def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">; 1765218893Sdim 1766218893Sdimlet imod = 0, iflags = 0, M = 1 in 1767226890Sdim def CPS1p : CPS<(ins imm0_31:$mode), "\t$mode">; 1768226890Sdim} 1769218893Sdim 1770204642Srdivacky// Preload signals the memory system of possible future data/instruction access. 1771218893Sdimmulticlass APreLoad<bits<1> read, bits<1> data, string opc> { 1772204642Srdivacky 1773218893Sdim def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload, 1774218893Sdim !strconcat(opc, "\t$addr"), 1775263509Sdim [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]>, 1776263509Sdim Sched<[WritePreLd]> { 1777218893Sdim bits<4> Rt; 1778218893Sdim bits<17> addr; 1779204642Srdivacky let Inst{31-26} = 0b111101; 1780204642Srdivacky let Inst{25} = 0; // 0 for immediate form 1781204642Srdivacky let Inst{24} = data; 1782218893Sdim let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1783204642Srdivacky let Inst{22} = read; 1784204642Srdivacky let Inst{21-20} = 0b01; 1785218893Sdim let Inst{19-16} = addr{16-13}; // Rn 1786218893Sdim let Inst{15-12} = 0b1111; 1787218893Sdim let Inst{11-0} = addr{11-0}; // imm12 1788204642Srdivacky } 1789204642Srdivacky 1790218893Sdim def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload, 1791218893Sdim !strconcat(opc, "\t$shift"), 1792263509Sdim [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]>, 1793263509Sdim Sched<[WritePreLd]> { 1794218893Sdim bits<17> shift; 1795204642Srdivacky let Inst{31-26} = 0b111101; 1796204642Srdivacky let Inst{25} = 1; // 1 for register form 1797204642Srdivacky let Inst{24} = data; 1798218893Sdim let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1799204642Srdivacky let Inst{22} = read; 1800204642Srdivacky let Inst{21-20} = 0b01; 1801218893Sdim let Inst{19-16} = shift{16-13}; // Rn 1802218893Sdim let Inst{15-12} = 0b1111; 1803218893Sdim let Inst{11-0} = shift{11-0}; 1804226890Sdim let Inst{4} = 0; 1805204642Srdivacky } 1806204642Srdivacky} 1807204642Srdivacky 1808218893Sdimdefm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>; 1809218893Sdimdefm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>; 1810218893Sdimdefm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>; 1811204642Srdivacky 1812226890Sdimdef SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary, 1813263509Sdim "setend\t$end", []>, Requires<[IsARM]>, Deprecated<HasV8Ops> { 1814218893Sdim bits<1> end; 1815218893Sdim let Inst{31-10} = 0b1111000100000001000000; 1816218893Sdim let Inst{9} = end; 1817218893Sdim let Inst{8-0} = 0; 1818203954Srdivacky} 1819203954Srdivacky 1820224145Sdimdef DBG : AI<(outs), (ins imm0_15:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt", 1821224145Sdim []>, Requires<[IsARM, HasV7]> { 1822218893Sdim bits<4> opt; 1823218893Sdim let Inst{27-4} = 0b001100100000111100001111; 1824218893Sdim let Inst{3-0} = opt; 1825203954Srdivacky} 1826203954Srdivacky 1827252723Sdim/* 1828252723Sdim * A5.4 Permanently UNDEFINED instructions. 1829252723Sdim * 1830252723Sdim * For most targets use UDF #65006, for which the OS will generate SIGTRAP. 1831252723Sdim * Other UDF encodings generate SIGILL. 1832252723Sdim * 1833252723Sdim * NaCl's OS instead chooses an ARM UDF encoding that's also a UDF in Thumb. 1834252723Sdim * Encoding A1: 1835252723Sdim * 1110 0111 1111 iiii iiii iiii 1111 iiii 1836252723Sdim * Encoding T1: 1837252723Sdim * 1101 1110 iiii iiii 1838252723Sdim * It uses the following encoding: 1839252723Sdim * 1110 0111 1111 1110 1101 1110 1111 0000 1840252723Sdim * - In ARM: UDF #60896; 1841252723Sdim * - In Thumb: UDF #254 followed by a branch-to-self. 1842252723Sdim */ 1843208599Srdivackylet isBarrier = 1, isTerminator = 1 in 1844252723Sdimdef TRAPNaCl : AXI<(outs), (ins), MiscFrm, NoItinerary, 1845252723Sdim "trap", [(trap)]>, 1846252723Sdim Requires<[IsARM,UseNaClTrap]> { 1847252723Sdim let Inst = 0xe7fedef0; 1848252723Sdim} 1849252723Sdimlet isBarrier = 1, isTerminator = 1 in 1850218893Sdimdef TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary, 1851218893Sdim "trap", [(trap)]>, 1852252723Sdim Requires<[IsARM,DontUseNaClTrap]> { 1853218893Sdim let Inst = 0xe7ffdefe; 1854203954Srdivacky} 1855203954Srdivacky 1856193323Sed// Address computation and loads and stores in PIC mode. 1857193323Sedlet isNotDuplicable = 1 in { 1858218893Sdimdef PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p), 1859224145Sdim 4, IIC_iALUr, 1860263509Sdim [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>, 1861263509Sdim Sched<[WriteALU, ReadALU]>; 1862193323Sed 1863193323Sedlet AddedComplexity = 10 in { 1864218893Sdimdef PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 1865224145Sdim 4, IIC_iLoad_r, 1866218893Sdim [(set GPR:$dst, (load addrmodepc:$addr))]>; 1867193323Sed 1868218893Sdimdef PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1869224145Sdim 4, IIC_iLoad_bh_r, 1870218893Sdim [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>; 1871193323Sed 1872218893Sdimdef PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1873224145Sdim 4, IIC_iLoad_bh_r, 1874218893Sdim [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>; 1875193323Sed 1876218893Sdimdef PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1877224145Sdim 4, IIC_iLoad_bh_r, 1878218893Sdim [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>; 1879193323Sed 1880218893Sdimdef PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1881224145Sdim 4, IIC_iLoad_bh_r, 1882218893Sdim [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>; 1883193323Sed} 1884193323Sedlet AddedComplexity = 10 in { 1885218893Sdimdef PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1886224145Sdim 4, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>; 1887193323Sed 1888218893Sdimdef PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1889224145Sdim 4, IIC_iStore_bh_r, [(truncstorei16 GPR:$src, 1890218893Sdim addrmodepc:$addr)]>; 1891193323Sed 1892218893Sdimdef PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1893224145Sdim 4, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; 1894193323Sed} 1895193323Sed} // isNotDuplicable = 1 1896193323Sed 1897194710Sed 1898194710Sed// LEApcrel - Load a pc-relative address into a register without offending the 1899194710Sed// assembler. 1900218893Sdimlet neverHasSideEffects = 1, isReMaterializable = 1 in 1901218893Sdim// The 'adr' mnemonic encodes differently if the label is before or after 1902218893Sdim// the instruction. The {24-21} opcode bits are set by the fixup, as we don't 1903218893Sdim// know until then which form of the instruction will be used. 1904221345Sdimdef ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label), 1905252723Sdim MiscFrm, IIC_iALUi, "adr", "\t$Rd, $label", []>, 1906252723Sdim Sched<[WriteALU, ReadALU]> { 1907218893Sdim bits<4> Rd; 1908226890Sdim bits<14> label; 1909218893Sdim let Inst{27-25} = 0b001; 1910226890Sdim let Inst{24} = 0; 1911226890Sdim let Inst{23-22} = label{13-12}; 1912226890Sdim let Inst{21} = 0; 1913218893Sdim let Inst{20} = 0; 1914218893Sdim let Inst{19-16} = 0b1111; 1915218893Sdim let Inst{15-12} = Rd; 1916226890Sdim let Inst{11-0} = label{11-0}; 1917198090Srdivacky} 1918245431Sdim 1919245431Sdimlet hasSideEffects = 1 in { 1920218893Sdimdef LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p), 1921263509Sdim 4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>; 1922194710Sed 1923218893Sdimdef LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd), 1924218893Sdim (ins i32imm:$label, nohash_imm:$id, pred:$p), 1925263509Sdim 4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>; 1926245431Sdim} 1927218893Sdim 1928193323Sed//===----------------------------------------------------------------------===// 1929193323Sed// Control Flow Instructions. 1930193323Sed// 1931193323Sed 1932204961Srdivackylet isReturn = 1, isTerminator = 1, isBarrier = 1 in { 1933204961Srdivacky // ARMV4T and above 1934204642Srdivacky def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 1935204961Srdivacky "bx", "\tlr", [(ARMretflag)]>, 1936263509Sdim Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> { 1937218893Sdim let Inst{27-0} = 0b0001001011111111111100011110; 1938204961Srdivacky } 1939204961Srdivacky 1940204961Srdivacky // ARMV4 only 1941218893Sdim def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br, 1942204961Srdivacky "mov", "\tpc, lr", [(ARMretflag)]>, 1943263509Sdim Requires<[IsARM, NoV4T]>, Sched<[WriteBr]> { 1944218893Sdim let Inst{27-0} = 0b0001101000001111000000001110; 1945204961Srdivacky } 1946263509Sdim 1947263509Sdim // Exception return: N.b. doesn't set CPSR as far as we're concerned (it sets 1948263509Sdim // the user-space one). 1949263509Sdim def SUBS_PC_LR : ARMPseudoInst<(outs), (ins i32imm:$offset, pred:$p), 1950263509Sdim 4, IIC_Br, 1951263509Sdim [(ARMintretflag imm:$offset)]>; 1952193323Sed} 1953193323Sed 1954198892Srdivacky// Indirect branches 1955198892Srdivackylet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 1956204961Srdivacky // ARMV4T and above 1957218893Sdim def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", 1958204961Srdivacky [(brind GPR:$dst)]>, 1959263509Sdim Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> { 1960218893Sdim bits<4> dst; 1961218893Sdim let Inst{31-4} = 0b1110000100101111111111110001; 1962218893Sdim let Inst{3-0} = dst; 1963198892Srdivacky } 1964204961Srdivacky 1965224145Sdim def BX_pred : AI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, 1966224145Sdim "bx", "\t$dst", [/* pattern left blank */]>, 1967263509Sdim Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> { 1968223017Sdim bits<4> dst; 1969223017Sdim let Inst{27-4} = 0b000100101111111111110001; 1970223017Sdim let Inst{3-0} = dst; 1971223017Sdim } 1972198892Srdivacky} 1973198892Srdivacky 1974235633Sdim// SP is marked as a use to prevent stack-pointer assignments that appear 1975235633Sdim// immediately before calls from potentially appearing dead. 1976198090Srdivackylet isCall = 1, 1977221345Sdim // FIXME: Do we really need a non-predicated version? If so, it should 1978221345Sdim // at least be a pseudo instruction expanding to the predicated version 1979221345Sdim // at MC lowering time. 1980235633Sdim Defs = [LR], Uses = [SP] in { 1981245431Sdim def BL : ABXI<0b1011, (outs), (ins bl_target:$func), 1982218893Sdim IIC_Br, "bl\t$func", 1983198090Srdivacky [(ARMcall tglobaladdr:$func)]>, 1984263509Sdim Requires<[IsARM]>, Sched<[WriteBrL]> { 1985198892Srdivacky let Inst{31-28} = 0b1110; 1986218893Sdim bits<24> func; 1987218893Sdim let Inst{23-0} = func; 1988226890Sdim let DecoderMethod = "DecodeBranchImmInstruction"; 1989198892Srdivacky } 1990193323Sed 1991245431Sdim def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func), 1992218893Sdim IIC_Br, "bl", "\t$func", 1993198090Srdivacky [(ARMcall_pred tglobaladdr:$func)]>, 1994263509Sdim Requires<[IsARM]>, Sched<[WriteBrL]> { 1995218893Sdim bits<24> func; 1996218893Sdim let Inst{23-0} = func; 1997226890Sdim let DecoderMethod = "DecodeBranchImmInstruction"; 1998218893Sdim } 1999193323Sed 2000193323Sed // ARMv5T and above 2001245431Sdim def BLX : AXI<(outs), (ins GPR:$func), BrMiscFrm, 2002198892Srdivacky IIC_Br, "blx\t$func", 2003198090Srdivacky [(ARMcall GPR:$func)]>, 2004263509Sdim Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> { 2005218893Sdim bits<4> func; 2006218893Sdim let Inst{31-4} = 0b1110000100101111111111110011; 2007221345Sdim let Inst{3-0} = func; 2008193323Sed } 2009193323Sed 2010245431Sdim def BLX_pred : AI<(outs), (ins GPR:$func), BrMiscFrm, 2011221345Sdim IIC_Br, "blx", "\t$func", 2012221345Sdim [(ARMcall_pred GPR:$func)]>, 2013263509Sdim Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> { 2014221345Sdim bits<4> func; 2015221345Sdim let Inst{27-4} = 0b000100101111111111110011; 2016221345Sdim let Inst{3-0} = func; 2017221345Sdim } 2018221345Sdim 2019198090Srdivacky // ARMv4T 2020204642Srdivacky // Note: Restrict $func to the tGPR regclass to prevent it being in LR. 2021245431Sdim def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func), 2022224145Sdim 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 2023263509Sdim Requires<[IsARM, HasV4T]>, Sched<[WriteBr]>; 2024204961Srdivacky 2025204961Srdivacky // ARMv4 2026245431Sdim def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func), 2027224145Sdim 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 2028263509Sdim Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; 2029193323Sed 2030235633Sdim // mov lr, pc; b if callee is marked noreturn to avoid confusing the 2031235633Sdim // return stack predictor. 2032245431Sdim def BMOVPCB_CALL : ARMPseudoInst<(outs), (ins bl_target:$func), 2033235633Sdim 8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>, 2034263509Sdim Requires<[IsARM]>, Sched<[WriteBr]>; 2035194710Sed} 2036194710Sed 2037224145Sdimlet isBranch = 1, isTerminator = 1 in { 2038224145Sdim // FIXME: should be able to write a pattern for ARMBrcond, but can't use 2039224145Sdim // a two-value operand where a dag node expects two operands. :( 2040224145Sdim def Bcc : ABI<0b1010, (outs), (ins br_target:$target), 2041224145Sdim IIC_Br, "b", "\t$target", 2042263509Sdim [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>, 2043263509Sdim Sched<[WriteBr]> { 2044224145Sdim bits<24> target; 2045224145Sdim let Inst{23-0} = target; 2046226890Sdim let DecoderMethod = "DecodeBranchImmInstruction"; 2047210299Sed } 2048210299Sed 2049193323Sed let isBarrier = 1 in { 2050224145Sdim // B is "predicable" since it's just a Bcc with an 'always' condition. 2051193323Sed let isPredicable = 1 in 2052221345Sdim // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly 2053221345Sdim // should be sufficient. 2054224145Sdim // FIXME: Is B really a Barrier? That doesn't seem right. 2055224145Sdim def B : ARMPseudoExpand<(outs), (ins br_target:$target), 4, IIC_Br, 2056263509Sdim [(br bb:$target)], (Bcc br_target:$target, (ops 14, zero_reg))>, 2057263509Sdim Sched<[WriteBr]>; 2058193323Sed 2059218893Sdim let isNotDuplicable = 1, isIndirectBranch = 1 in { 2060218893Sdim def BR_JTr : ARMPseudoInst<(outs), 2061218893Sdim (ins GPR:$target, i32imm:$jt, i32imm:$id), 2062224145Sdim 0, IIC_Br, 2063263509Sdim [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>, 2064263509Sdim Sched<[WriteBr]>; 2065218893Sdim // FIXME: This shouldn't use the generic "addrmode2," but rather be split 2066218893Sdim // into i12 and rs suffixed versions. 2067218893Sdim def BR_JTm : ARMPseudoInst<(outs), 2068218893Sdim (ins addrmode2:$target, i32imm:$jt, i32imm:$id), 2069224145Sdim 0, IIC_Br, 2070218893Sdim [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt, 2071263509Sdim imm:$id)]>, Sched<[WriteBrTbl]>; 2072218893Sdim def BR_JTadd : ARMPseudoInst<(outs), 2073218893Sdim (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id), 2074224145Sdim 0, IIC_Br, 2075218893Sdim [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, 2076263509Sdim imm:$id)]>, Sched<[WriteBrTbl]>; 2077218893Sdim } // isNotDuplicable = 1, isIndirectBranch = 1 2078193323Sed } // isBarrier = 1 2079193323Sed 2080193323Sed} 2081193323Sed 2082226890Sdim// BLX (immediate) 2083226890Sdimdef BLXi : AXI<(outs), (ins blx_target:$target), BrMiscFrm, NoItinerary, 2084226890Sdim "blx\t$target", []>, 2085263509Sdim Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> { 2086221345Sdim let Inst{31-25} = 0b1111101; 2087221345Sdim bits<25> target; 2088221345Sdim let Inst{23-0} = target{24-1}; 2089221345Sdim let Inst{24} = target{0}; 2090221345Sdim} 2091221345Sdim 2092224145Sdim// Branch and Exchange Jazelle 2093203954Srdivackydef BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func", 2094263509Sdim [/* pattern left blank */]>, Sched<[WriteBr]> { 2095224145Sdim bits<4> func; 2096203954Srdivacky let Inst{23-20} = 0b0010; 2097224145Sdim let Inst{19-8} = 0xfff; 2098203954Srdivacky let Inst{7-4} = 0b0010; 2099224145Sdim let Inst{3-0} = func; 2100203954Srdivacky} 2101203954Srdivacky 2102224145Sdim// Tail calls. 2103224145Sdim 2104235633Sdimlet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in { 2105263509Sdim def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst), IIC_Br, []>, 2106263509Sdim Sched<[WriteBr]>; 2107224145Sdim 2108263509Sdim def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst), IIC_Br, []>, 2109263509Sdim Sched<[WriteBr]>; 2110224145Sdim 2111245431Sdim def TAILJMPd : ARMPseudoExpand<(outs), (ins br_target:$dst), 2112235633Sdim 4, IIC_Br, [], 2113235633Sdim (Bcc br_target:$dst, (ops 14, zero_reg))>, 2114263509Sdim Requires<[IsARM]>, Sched<[WriteBr]>; 2115224145Sdim 2116245431Sdim def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst), 2117235633Sdim 4, IIC_Br, [], 2118263509Sdim (BX GPR:$dst)>, Sched<[WriteBr]>, 2119235633Sdim Requires<[IsARM]>; 2120224145Sdim} 2121224145Sdim 2122226890Sdim// Secure Monitor Call is a system instruction. 2123226890Sdimdef SMC : ABI<0b0001, (outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt", 2124252723Sdim []>, Requires<[IsARM, HasTrustZone]> { 2125218893Sdim bits<4> opt; 2126218893Sdim let Inst{23-4} = 0b01100000000000000111; 2127218893Sdim let Inst{3-0} = opt; 2128204642Srdivacky} 2129204642Srdivacky 2130226890Sdim// Supervisor Call (Software Interrupt) 2131218893Sdimlet isCall = 1, Uses = [SP] in { 2132263509Sdimdef SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []>, 2133263509Sdim Sched<[WriteBr]> { 2134218893Sdim bits<24> svc; 2135218893Sdim let Inst{23-0} = svc; 2136203954Srdivacky} 2137218893Sdim} 2138203954Srdivacky 2139226890Sdim// Store Return State 2140226890Sdimclass SRSI<bit wb, string asm> 2141226890Sdim : XI<(outs), (ins imm0_31:$mode), AddrModeNone, 4, IndexModeNone, BrFrm, 2142226890Sdim NoItinerary, asm, "", []> { 2143226890Sdim bits<5> mode; 2144204642Srdivacky let Inst{31-28} = 0b1111; 2145226890Sdim let Inst{27-25} = 0b100; 2146226890Sdim let Inst{22} = 1; 2147226890Sdim let Inst{21} = wb; 2148226890Sdim let Inst{20} = 0; 2149226890Sdim let Inst{19-16} = 0b1101; // SP 2150226890Sdim let Inst{15-5} = 0b00000101000; 2151226890Sdim let Inst{4-0} = mode; 2152204642Srdivacky} 2153204642Srdivacky 2154226890Sdimdef SRSDA : SRSI<0, "srsda\tsp, $mode"> { 2155226890Sdim let Inst{24-23} = 0; 2156204642Srdivacky} 2157226890Sdimdef SRSDA_UPD : SRSI<1, "srsda\tsp!, $mode"> { 2158226890Sdim let Inst{24-23} = 0; 2159226890Sdim} 2160226890Sdimdef SRSDB : SRSI<0, "srsdb\tsp, $mode"> { 2161226890Sdim let Inst{24-23} = 0b10; 2162226890Sdim} 2163226890Sdimdef SRSDB_UPD : SRSI<1, "srsdb\tsp!, $mode"> { 2164226890Sdim let Inst{24-23} = 0b10; 2165226890Sdim} 2166226890Sdimdef SRSIA : SRSI<0, "srsia\tsp, $mode"> { 2167226890Sdim let Inst{24-23} = 0b01; 2168226890Sdim} 2169226890Sdimdef SRSIA_UPD : SRSI<1, "srsia\tsp!, $mode"> { 2170226890Sdim let Inst{24-23} = 0b01; 2171226890Sdim} 2172226890Sdimdef SRSIB : SRSI<0, "srsib\tsp, $mode"> { 2173226890Sdim let Inst{24-23} = 0b11; 2174226890Sdim} 2175226890Sdimdef SRSIB_UPD : SRSI<1, "srsib\tsp!, $mode"> { 2176226890Sdim let Inst{24-23} = 0b11; 2177226890Sdim} 2178204642Srdivacky 2179252723Sdimdef : ARMInstAlias<"srsda $mode", (SRSDA imm0_31:$mode)>; 2180252723Sdimdef : ARMInstAlias<"srsda $mode!", (SRSDA_UPD imm0_31:$mode)>; 2181252723Sdim 2182252723Sdimdef : ARMInstAlias<"srsdb $mode", (SRSDB imm0_31:$mode)>; 2183252723Sdimdef : ARMInstAlias<"srsdb $mode!", (SRSDB_UPD imm0_31:$mode)>; 2184252723Sdim 2185252723Sdimdef : ARMInstAlias<"srsia $mode", (SRSIA imm0_31:$mode)>; 2186252723Sdimdef : ARMInstAlias<"srsia $mode!", (SRSIA_UPD imm0_31:$mode)>; 2187252723Sdim 2188252723Sdimdef : ARMInstAlias<"srsib $mode", (SRSIB imm0_31:$mode)>; 2189252723Sdimdef : ARMInstAlias<"srsib $mode!", (SRSIB_UPD imm0_31:$mode)>; 2190252723Sdim 2191226890Sdim// Return From Exception 2192226890Sdimclass RFEI<bit wb, string asm> 2193226890Sdim : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm, 2194226890Sdim NoItinerary, asm, "", []> { 2195226890Sdim bits<4> Rn; 2196204642Srdivacky let Inst{31-28} = 0b1111; 2197226890Sdim let Inst{27-25} = 0b100; 2198226890Sdim let Inst{22} = 0; 2199226890Sdim let Inst{21} = wb; 2200226890Sdim let Inst{20} = 1; 2201226890Sdim let Inst{19-16} = Rn; 2202226890Sdim let Inst{15-0} = 0xa00; 2203204642Srdivacky} 2204204642Srdivacky 2205226890Sdimdef RFEDA : RFEI<0, "rfeda\t$Rn"> { 2206226890Sdim let Inst{24-23} = 0; 2207204642Srdivacky} 2208226890Sdimdef RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> { 2209226890Sdim let Inst{24-23} = 0; 2210226890Sdim} 2211226890Sdimdef RFEDB : RFEI<0, "rfedb\t$Rn"> { 2212226890Sdim let Inst{24-23} = 0b10; 2213226890Sdim} 2214226890Sdimdef RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> { 2215226890Sdim let Inst{24-23} = 0b10; 2216226890Sdim} 2217226890Sdimdef RFEIA : RFEI<0, "rfeia\t$Rn"> { 2218226890Sdim let Inst{24-23} = 0b01; 2219226890Sdim} 2220226890Sdimdef RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> { 2221226890Sdim let Inst{24-23} = 0b01; 2222226890Sdim} 2223226890Sdimdef RFEIB : RFEI<0, "rfeib\t$Rn"> { 2224226890Sdim let Inst{24-23} = 0b11; 2225226890Sdim} 2226226890Sdimdef RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> { 2227226890Sdim let Inst{24-23} = 0b11; 2228226890Sdim} 2229204642Srdivacky 2230193323Sed//===----------------------------------------------------------------------===// 2231235633Sdim// Load / Store Instructions. 2232193323Sed// 2233193323Sed 2234193323Sed// Load 2235193323Sed 2236218893Sdim 2237218893Sdimdefm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si, 2238218893Sdim UnOpFrag<(load node:$Src)>>; 2239226890Sdimdefm LDRB : AI_ldr1nopc<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si, 2240218893Sdim UnOpFrag<(zextloadi8 node:$Src)>>; 2241218893Sdimdefm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si, 2242218893Sdim BinOpFrag<(store node:$LHS, node:$RHS)>>; 2243226890Sdimdefm STRB : AI_str1nopc<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si, 2244218893Sdim BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; 2245218893Sdim 2246193323Sed// Special LDR for loads from non-pc-relative constpools. 2247208599Srdivackylet canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, 2248226890Sdim isReMaterializable = 1, isCodeGenOnly = 1 in 2249218893Sdimdef LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr), 2250218893Sdim AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", 2251218893Sdim []> { 2252218893Sdim bits<4> Rt; 2253218893Sdim bits<17> addr; 2254218893Sdim let Inst{23} = addr{12}; // U (add = ('U' == 1)) 2255218893Sdim let Inst{19-16} = 0b1111; 2256218893Sdim let Inst{15-12} = Rt; 2257218893Sdim let Inst{11-0} = addr{11-0}; // imm12 2258218893Sdim} 2259193323Sed 2260193323Sed// Loads with zero extension 2261218893Sdimdef LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 2262218893Sdim IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr", 2263218893Sdim [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>; 2264193323Sed 2265193323Sed// Loads with sign extension 2266218893Sdimdef LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 2267218893Sdim IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr", 2268218893Sdim [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>; 2269193323Sed 2270218893Sdimdef LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 2271218893Sdim IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr", 2272218893Sdim [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>; 2273193323Sed 2274221345Sdimlet mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 2275193323Sed// Load doubleword 2276218893Sdimdef LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2), 2277218893Sdim (ins addrmode3:$addr), LdMiscFrm, 2278221345Sdim IIC_iLoad_d_r, "ldrd", "\t$Rd, $dst2, $addr", 2279198090Srdivacky []>, Requires<[IsARM, HasV5TE]>; 2280218893Sdim} 2281193323Sed 2282263509Sdimdef LDA : AIldracq<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 2283263509Sdim NoItinerary, "lda", "\t$Rt, $addr", []>; 2284263509Sdimdef LDAB : AIldracq<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 2285263509Sdim NoItinerary, "ldab", "\t$Rt, $addr", []>; 2286263509Sdimdef LDAH : AIldracq<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 2287263509Sdim NoItinerary, "ldah", "\t$Rt, $addr", []>; 2288263509Sdim 2289193323Sed// Indexed loads 2290235633Sdimmulticlass AI2_ldridx<bit isByte, string opc, 2291235633Sdim InstrItinClass iii, InstrItinClass iir> { 2292226890Sdim def _PRE_IMM : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), 2293252723Sdim (ins addrmode_imm12_pre:$addr), IndexModePre, LdFrm, iii, 2294218893Sdim opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2295226890Sdim bits<17> addr; 2296226890Sdim let Inst{25} = 0; 2297218893Sdim let Inst{23} = addr{12}; 2298226890Sdim let Inst{19-16} = addr{16-13}; 2299218893Sdim let Inst{11-0} = addr{11-0}; 2300226890Sdim let DecoderMethod = "DecodeLDRPreImm"; 2301218893Sdim } 2302226890Sdim 2303226890Sdim def _PRE_REG : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), 2304235633Sdim (ins ldst_so_reg:$addr), IndexModePre, LdFrm, iir, 2305226890Sdim opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2306226890Sdim bits<17> addr; 2307226890Sdim let Inst{25} = 1; 2308226890Sdim let Inst{23} = addr{12}; 2309226890Sdim let Inst{19-16} = addr{16-13}; 2310226890Sdim let Inst{11-0} = addr{11-0}; 2311226890Sdim let Inst{4} = 0; 2312226890Sdim let DecoderMethod = "DecodeLDRPreReg"; 2313226890Sdim } 2314226890Sdim 2315226890Sdim def _POST_REG : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2316226890Sdim (ins addr_offset_none:$addr, am2offset_reg:$offset), 2317235633Sdim IndexModePost, LdFrm, iir, 2318226890Sdim opc, "\t$Rt, $addr, $offset", 2319226890Sdim "$addr.base = $Rn_wb", []> { 2320226890Sdim // {12} isAdd 2321226890Sdim // {11-0} imm12/Rm 2322226890Sdim bits<14> offset; 2323226890Sdim bits<4> addr; 2324226890Sdim let Inst{25} = 1; 2325226890Sdim let Inst{23} = offset{12}; 2326226890Sdim let Inst{19-16} = addr; 2327226890Sdim let Inst{11-0} = offset{11-0}; 2328252723Sdim let Inst{4} = 0; 2329226890Sdim 2330226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2331226890Sdim } 2332226890Sdim 2333226890Sdim def _POST_IMM : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2334226890Sdim (ins addr_offset_none:$addr, am2offset_imm:$offset), 2335235633Sdim IndexModePost, LdFrm, iii, 2336226890Sdim opc, "\t$Rt, $addr, $offset", 2337226890Sdim "$addr.base = $Rn_wb", []> { 2338218893Sdim // {12} isAdd 2339218893Sdim // {11-0} imm12/Rm 2340218893Sdim bits<14> offset; 2341226890Sdim bits<4> addr; 2342226890Sdim let Inst{25} = 0; 2343218893Sdim let Inst{23} = offset{12}; 2344226890Sdim let Inst{19-16} = addr; 2345218893Sdim let Inst{11-0} = offset{11-0}; 2346226890Sdim 2347226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2348218893Sdim } 2349226890Sdim 2350218893Sdim} 2351193323Sed 2352218893Sdimlet mayLoad = 1, neverHasSideEffects = 1 in { 2353235633Sdim// FIXME: for LDR_PRE_REG etc. the itineray should be either IIC_iLoad_ru or 2354235633Sdim// IIC_iLoad_siu depending on whether it the offset register is shifted. 2355235633Sdimdefm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_iu, IIC_iLoad_ru>; 2356235633Sdimdefm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_iu, IIC_iLoad_bh_ru>; 2357218893Sdim} 2358193323Sed 2359226890Sdimmulticlass AI3_ldridx<bits<4> op, string opc, InstrItinClass itin> { 2360226890Sdim def _PRE : AI3ldstidx<op, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 2361252723Sdim (ins addrmode3_pre:$addr), IndexModePre, 2362218893Sdim LdMiscFrm, itin, 2363218893Sdim opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2364218893Sdim bits<14> addr; 2365218893Sdim let Inst{23} = addr{8}; // U bit 2366218893Sdim let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 2367218893Sdim let Inst{19-16} = addr{12-9}; // Rn 2368218893Sdim let Inst{11-8} = addr{7-4}; // imm7_4/zero 2369218893Sdim let Inst{3-0} = addr{3-0}; // imm3_0/Rm 2370226890Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 2371218893Sdim } 2372226890Sdim def _POST : AI3ldstidx<op, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2373226890Sdim (ins addr_offset_none:$addr, am3offset:$offset), 2374226890Sdim IndexModePost, LdMiscFrm, itin, 2375226890Sdim opc, "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", 2376226890Sdim []> { 2377218893Sdim bits<10> offset; 2378226890Sdim bits<4> addr; 2379218893Sdim let Inst{23} = offset{8}; // U bit 2380218893Sdim let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 2381226890Sdim let Inst{19-16} = addr; 2382218893Sdim let Inst{11-8} = offset{7-4}; // imm7_4/zero 2383218893Sdim let Inst{3-0} = offset{3-0}; // imm3_0/Rm 2384226890Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 2385218893Sdim } 2386218893Sdim} 2387193323Sed 2388218893Sdimlet mayLoad = 1, neverHasSideEffects = 1 in { 2389226890Sdimdefm LDRH : AI3_ldridx<0b1011, "ldrh", IIC_iLoad_bh_ru>; 2390226890Sdimdefm LDRSH : AI3_ldridx<0b1111, "ldrsh", IIC_iLoad_bh_ru>; 2391226890Sdimdefm LDRSB : AI3_ldridx<0b1101, "ldrsb", IIC_iLoad_bh_ru>; 2392221345Sdimlet hasExtraDefRegAllocReq = 1 in { 2393226890Sdimdef LDRD_PRE : AI3ldstidx<0b1101, 0, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 2394252723Sdim (ins addrmode3_pre:$addr), IndexModePre, 2395221345Sdim LdMiscFrm, IIC_iLoad_d_ru, 2396221345Sdim "ldrd", "\t$Rt, $Rt2, $addr!", 2397221345Sdim "$addr.base = $Rn_wb", []> { 2398221345Sdim bits<14> addr; 2399221345Sdim let Inst{23} = addr{8}; // U bit 2400221345Sdim let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 2401221345Sdim let Inst{19-16} = addr{12-9}; // Rn 2402221345Sdim let Inst{11-8} = addr{7-4}; // imm7_4/zero 2403221345Sdim let Inst{3-0} = addr{3-0}; // imm3_0/Rm 2404226890Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 2405221345Sdim} 2406226890Sdimdef LDRD_POST: AI3ldstidx<0b1101, 0, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 2407226890Sdim (ins addr_offset_none:$addr, am3offset:$offset), 2408226890Sdim IndexModePost, LdMiscFrm, IIC_iLoad_d_ru, 2409226890Sdim "ldrd", "\t$Rt, $Rt2, $addr, $offset", 2410226890Sdim "$addr.base = $Rn_wb", []> { 2411221345Sdim bits<10> offset; 2412226890Sdim bits<4> addr; 2413221345Sdim let Inst{23} = offset{8}; // U bit 2414221345Sdim let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 2415226890Sdim let Inst{19-16} = addr; 2416221345Sdim let Inst{11-8} = offset{7-4}; // imm7_4/zero 2417221345Sdim let Inst{3-0} = offset{3-0}; // imm3_0/Rm 2418226890Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 2419221345Sdim} 2420221345Sdim} // hasExtraDefRegAllocReq = 1 2421218893Sdim} // mayLoad = 1, neverHasSideEffects = 1 2422193323Sed 2423226890Sdim// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT. 2424218893Sdimlet mayLoad = 1, neverHasSideEffects = 1 in { 2425226890Sdimdef LDRT_POST_REG : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2426226890Sdim (ins addr_offset_none:$addr, am2offset_reg:$offset), 2427226890Sdim IndexModePost, LdFrm, IIC_iLoad_ru, 2428226890Sdim "ldrt", "\t$Rt, $addr, $offset", 2429226890Sdim "$addr.base = $Rn_wb", []> { 2430221345Sdim // {12} isAdd 2431221345Sdim // {11-0} imm12/Rm 2432226890Sdim bits<14> offset; 2433226890Sdim bits<4> addr; 2434226890Sdim let Inst{25} = 1; 2435226890Sdim let Inst{23} = offset{12}; 2436203954Srdivacky let Inst{21} = 1; // overwrite 2437226890Sdim let Inst{19-16} = addr; 2438226890Sdim let Inst{11-5} = offset{11-5}; 2439226890Sdim let Inst{4} = 0; 2440226890Sdim let Inst{3-0} = offset{3-0}; 2441226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2442203954Srdivacky} 2443226890Sdim 2444226890Sdimdef LDRT_POST_IMM : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2445226890Sdim (ins addr_offset_none:$addr, am2offset_imm:$offset), 2446226890Sdim IndexModePost, LdFrm, IIC_iLoad_ru, 2447226890Sdim "ldrt", "\t$Rt, $addr, $offset", 2448226890Sdim "$addr.base = $Rn_wb", []> { 2449221345Sdim // {12} isAdd 2450221345Sdim // {11-0} imm12/Rm 2451226890Sdim bits<14> offset; 2452226890Sdim bits<4> addr; 2453226890Sdim let Inst{25} = 0; 2454226890Sdim let Inst{23} = offset{12}; 2455203954Srdivacky let Inst{21} = 1; // overwrite 2456226890Sdim let Inst{19-16} = addr; 2457226890Sdim let Inst{11-0} = offset{11-0}; 2458226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2459203954Srdivacky} 2460226890Sdim 2461226890Sdimdef LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2462226890Sdim (ins addr_offset_none:$addr, am2offset_reg:$offset), 2463226890Sdim IndexModePost, LdFrm, IIC_iLoad_bh_ru, 2464226890Sdim "ldrbt", "\t$Rt, $addr, $offset", 2465226890Sdim "$addr.base = $Rn_wb", []> { 2466226890Sdim // {12} isAdd 2467226890Sdim // {11-0} imm12/Rm 2468226890Sdim bits<14> offset; 2469226890Sdim bits<4> addr; 2470226890Sdim let Inst{25} = 1; 2471226890Sdim let Inst{23} = offset{12}; 2472204642Srdivacky let Inst{21} = 1; // overwrite 2473226890Sdim let Inst{19-16} = addr; 2474226890Sdim let Inst{11-5} = offset{11-5}; 2475226890Sdim let Inst{4} = 0; 2476226890Sdim let Inst{3-0} = offset{3-0}; 2477226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2478204642Srdivacky} 2479226890Sdim 2480226890Sdimdef LDRBT_POST_IMM : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 2481226890Sdim (ins addr_offset_none:$addr, am2offset_imm:$offset), 2482226890Sdim IndexModePost, LdFrm, IIC_iLoad_bh_ru, 2483226890Sdim "ldrbt", "\t$Rt, $addr, $offset", 2484226890Sdim "$addr.base = $Rn_wb", []> { 2485226890Sdim // {12} isAdd 2486226890Sdim // {11-0} imm12/Rm 2487226890Sdim bits<14> offset; 2488226890Sdim bits<4> addr; 2489226890Sdim let Inst{25} = 0; 2490226890Sdim let Inst{23} = offset{12}; 2491204642Srdivacky let Inst{21} = 1; // overwrite 2492226890Sdim let Inst{19-16} = addr; 2493226890Sdim let Inst{11-0} = offset{11-0}; 2494226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2495204642Srdivacky} 2496226890Sdim 2497226890Sdimmulticlass AI3ldrT<bits<4> op, string opc> { 2498226890Sdim def i : AI3ldstidxT<op, 1, (outs GPR:$Rt, GPR:$base_wb), 2499226890Sdim (ins addr_offset_none:$addr, postidx_imm8:$offset), 2500226890Sdim IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc, 2501226890Sdim "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> { 2502226890Sdim bits<9> offset; 2503226890Sdim let Inst{23} = offset{8}; 2504226890Sdim let Inst{22} = 1; 2505226890Sdim let Inst{11-8} = offset{7-4}; 2506226890Sdim let Inst{3-0} = offset{3-0}; 2507226890Sdim } 2508235633Sdim def r : AI3ldstidxT<op, 1, (outs GPRnopc:$Rt, GPRnopc:$base_wb), 2509226890Sdim (ins addr_offset_none:$addr, postidx_reg:$Rm), 2510226890Sdim IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc, 2511226890Sdim "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> { 2512226890Sdim bits<5> Rm; 2513226890Sdim let Inst{23} = Rm{4}; 2514226890Sdim let Inst{22} = 0; 2515226890Sdim let Inst{11-8} = 0; 2516235633Sdim let Unpredictable{11-8} = 0b1111; 2517226890Sdim let Inst{3-0} = Rm{3-0}; 2518235633Sdim let DecoderMethod = "DecodeLDR"; 2519226890Sdim } 2520204642Srdivacky} 2521226890Sdim 2522226890Sdimdefm LDRSBT : AI3ldrT<0b1101, "ldrsbt">; 2523226890Sdimdefm LDRHT : AI3ldrT<0b1011, "ldrht">; 2524226890Sdimdefm LDRSHT : AI3ldrT<0b1111, "ldrsht">; 2525218893Sdim} 2526204642Srdivacky 2527193323Sed// Store 2528193323Sed 2529193323Sed// Stores with truncate 2530218893Sdimdef STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm, 2531218893Sdim IIC_iStore_bh_r, "strh", "\t$Rt, $addr", 2532218893Sdim [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>; 2533193323Sed 2534193323Sed// Store doubleword 2535221345Sdimlet mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in 2536221345Sdimdef STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr), 2537218893Sdim StMiscFrm, IIC_iStore_d_r, 2538226890Sdim "strd", "\t$Rt, $src2, $addr", []>, 2539226890Sdim Requires<[IsARM, HasV5TE]> { 2540226890Sdim let Inst{21} = 0; 2541226890Sdim} 2542193323Sed 2543193323Sed// Indexed stores 2544235633Sdimmulticlass AI2_stridx<bit isByte, string opc, 2545235633Sdim InstrItinClass iii, InstrItinClass iir> { 2546226890Sdim def _PRE_IMM : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), 2547252723Sdim (ins GPR:$Rt, addrmode_imm12_pre:$addr), IndexModePre, 2548235633Sdim StFrm, iii, 2549226890Sdim opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2550226890Sdim bits<17> addr; 2551226890Sdim let Inst{25} = 0; 2552226890Sdim let Inst{23} = addr{12}; // U (add = ('U' == 1)) 2553226890Sdim let Inst{19-16} = addr{16-13}; // Rn 2554226890Sdim let Inst{11-0} = addr{11-0}; // imm12 2555226890Sdim let DecoderMethod = "DecodeSTRPreImm"; 2556226890Sdim } 2557193323Sed 2558226890Sdim def _PRE_REG : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), 2559226890Sdim (ins GPR:$Rt, ldst_so_reg:$addr), 2560235633Sdim IndexModePre, StFrm, iir, 2561226890Sdim opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2562226890Sdim bits<17> addr; 2563226890Sdim let Inst{25} = 1; 2564226890Sdim let Inst{23} = addr{12}; // U (add = ('U' == 1)) 2565226890Sdim let Inst{19-16} = addr{16-13}; // Rn 2566226890Sdim let Inst{11-0} = addr{11-0}; 2567226890Sdim let Inst{4} = 0; // Inst{4} = 0 2568226890Sdim let DecoderMethod = "DecodeSTRPreReg"; 2569226890Sdim } 2570226890Sdim def _POST_REG : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), 2571226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 2572235633Sdim IndexModePost, StFrm, iir, 2573226890Sdim opc, "\t$Rt, $addr, $offset", 2574226890Sdim "$addr.base = $Rn_wb", []> { 2575226890Sdim // {12} isAdd 2576226890Sdim // {11-0} imm12/Rm 2577226890Sdim bits<14> offset; 2578226890Sdim bits<4> addr; 2579226890Sdim let Inst{25} = 1; 2580226890Sdim let Inst{23} = offset{12}; 2581226890Sdim let Inst{19-16} = addr; 2582226890Sdim let Inst{11-0} = offset{11-0}; 2583245431Sdim let Inst{4} = 0; 2584193323Sed 2585226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2586226890Sdim } 2587193323Sed 2588226890Sdim def _POST_IMM : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), 2589226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 2590235633Sdim IndexModePost, StFrm, iii, 2591226890Sdim opc, "\t$Rt, $addr, $offset", 2592226890Sdim "$addr.base = $Rn_wb", []> { 2593226890Sdim // {12} isAdd 2594226890Sdim // {11-0} imm12/Rm 2595226890Sdim bits<14> offset; 2596226890Sdim bits<4> addr; 2597226890Sdim let Inst{25} = 0; 2598226890Sdim let Inst{23} = offset{12}; 2599226890Sdim let Inst{19-16} = addr; 2600226890Sdim let Inst{11-0} = offset{11-0}; 2601193323Sed 2602226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2603226890Sdim } 2604226890Sdim} 2605193323Sed 2606226890Sdimlet mayStore = 1, neverHasSideEffects = 1 in { 2607235633Sdim// FIXME: for STR_PRE_REG etc. the itineray should be either IIC_iStore_ru or 2608235633Sdim// IIC_iStore_siu depending on whether it the offset register is shifted. 2609235633Sdimdefm STR : AI2_stridx<0, "str", IIC_iStore_iu, IIC_iStore_ru>; 2610235633Sdimdefm STRB : AI2_stridx<1, "strb", IIC_iStore_bh_iu, IIC_iStore_bh_ru>; 2611226890Sdim} 2612226890Sdim 2613226890Sdimdef : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr, 2614226890Sdim am2offset_reg:$offset), 2615226890Sdim (STR_POST_REG GPR:$Rt, addr_offset_none:$addr, 2616226890Sdim am2offset_reg:$offset)>; 2617226890Sdimdef : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr, 2618226890Sdim am2offset_imm:$offset), 2619226890Sdim (STR_POST_IMM GPR:$Rt, addr_offset_none:$addr, 2620226890Sdim am2offset_imm:$offset)>; 2621226890Sdimdef : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr, 2622226890Sdim am2offset_reg:$offset), 2623226890Sdim (STRB_POST_REG GPR:$Rt, addr_offset_none:$addr, 2624226890Sdim am2offset_reg:$offset)>; 2625226890Sdimdef : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr, 2626226890Sdim am2offset_imm:$offset), 2627226890Sdim (STRB_POST_IMM GPR:$Rt, addr_offset_none:$addr, 2628226890Sdim am2offset_imm:$offset)>; 2629226890Sdim 2630226890Sdim// Pseudo-instructions for pattern matching the pre-indexed stores. We can't 2631226890Sdim// put the patterns on the instruction definitions directly as ISel wants 2632226890Sdim// the address base and offset to be separate operands, not a single 2633226890Sdim// complex operand like we represent the instructions themselves. The 2634226890Sdim// pseudos map between the two. 2635226890Sdimlet usesCustomInserter = 1, 2636226890Sdim Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in { 2637226890Sdimdef STRi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2638226890Sdim (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p), 2639226890Sdim 4, IIC_iStore_ru, 2640226890Sdim [(set GPR:$Rn_wb, 2641226890Sdim (pre_store GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>; 2642226890Sdimdef STRr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2643226890Sdim (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p), 2644226890Sdim 4, IIC_iStore_ru, 2645226890Sdim [(set GPR:$Rn_wb, 2646226890Sdim (pre_store GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; 2647226890Sdimdef STRBi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2648226890Sdim (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p), 2649226890Sdim 4, IIC_iStore_ru, 2650226890Sdim [(set GPR:$Rn_wb, 2651226890Sdim (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>; 2652226890Sdimdef STRBr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2653226890Sdim (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p), 2654226890Sdim 4, IIC_iStore_ru, 2655226890Sdim [(set GPR:$Rn_wb, 2656226890Sdim (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; 2657226890Sdimdef STRH_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 2658226890Sdim (ins GPR:$Rt, GPR:$Rn, am3offset:$offset, pred:$p), 2659226890Sdim 4, IIC_iStore_ru, 2660226890Sdim [(set GPR:$Rn_wb, 2661226890Sdim (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>; 2662226890Sdim} 2663226890Sdim 2664226890Sdim 2665226890Sdim 2666226890Sdimdef STRH_PRE : AI3ldstidx<0b1011, 0, 1, (outs GPR:$Rn_wb), 2667252723Sdim (ins GPR:$Rt, addrmode3_pre:$addr), IndexModePre, 2668226890Sdim StMiscFrm, IIC_iStore_bh_ru, 2669226890Sdim "strh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 2670226890Sdim bits<14> addr; 2671226890Sdim let Inst{23} = addr{8}; // U bit 2672226890Sdim let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 2673226890Sdim let Inst{19-16} = addr{12-9}; // Rn 2674226890Sdim let Inst{11-8} = addr{7-4}; // imm7_4/zero 2675226890Sdim let Inst{3-0} = addr{3-0}; // imm3_0/Rm 2676226890Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 2677226890Sdim} 2678226890Sdim 2679226890Sdimdef STRH_POST : AI3ldstidx<0b1011, 0, 0, (outs GPR:$Rn_wb), 2680226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, am3offset:$offset), 2681226890Sdim IndexModePost, StMiscFrm, IIC_iStore_bh_ru, 2682226890Sdim "strh", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", 2683226890Sdim [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt, 2684226890Sdim addr_offset_none:$addr, 2685226890Sdim am3offset:$offset))]> { 2686226890Sdim bits<10> offset; 2687226890Sdim bits<4> addr; 2688226890Sdim let Inst{23} = offset{8}; // U bit 2689226890Sdim let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 2690226890Sdim let Inst{19-16} = addr; 2691226890Sdim let Inst{11-8} = offset{7-4}; // imm7_4/zero 2692226890Sdim let Inst{3-0} = offset{3-0}; // imm3_0/Rm 2693226890Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 2694226890Sdim} 2695226890Sdim 2696221345Sdimlet mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { 2697226890Sdimdef STRD_PRE : AI3ldstidx<0b1111, 0, 1, (outs GPR:$Rn_wb), 2698252723Sdim (ins GPR:$Rt, GPR:$Rt2, addrmode3_pre:$addr), 2699226890Sdim IndexModePre, StMiscFrm, IIC_iStore_d_ru, 2700226890Sdim "strd", "\t$Rt, $Rt2, $addr!", 2701226890Sdim "$addr.base = $Rn_wb", []> { 2702226890Sdim bits<14> addr; 2703226890Sdim let Inst{23} = addr{8}; // U bit 2704226890Sdim let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 2705226890Sdim let Inst{19-16} = addr{12-9}; // Rn 2706226890Sdim let Inst{11-8} = addr{7-4}; // imm7_4/zero 2707226890Sdim let Inst{3-0} = addr{3-0}; // imm3_0/Rm 2708226890Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 2709226890Sdim} 2710203954Srdivacky 2711226890Sdimdef STRD_POST: AI3ldstidx<0b1111, 0, 0, (outs GPR:$Rn_wb), 2712226890Sdim (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr, 2713226890Sdim am3offset:$offset), 2714226890Sdim IndexModePost, StMiscFrm, IIC_iStore_d_ru, 2715226890Sdim "strd", "\t$Rt, $Rt2, $addr, $offset", 2716226890Sdim "$addr.base = $Rn_wb", []> { 2717226890Sdim bits<10> offset; 2718226890Sdim bits<4> addr; 2719226890Sdim let Inst{23} = offset{8}; // U bit 2720226890Sdim let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 2721226890Sdim let Inst{19-16} = addr; 2722226890Sdim let Inst{11-8} = offset{7-4}; // imm7_4/zero 2723226890Sdim let Inst{3-0} = offset{3-0}; // imm3_0/Rm 2724226890Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 2725226890Sdim} 2726221345Sdim} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 2727204642Srdivacky 2728226890Sdim// STRT, STRBT, and STRHT 2729204642Srdivacky 2730226890Sdimdef STRBT_POST_REG : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), 2731226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 2732226890Sdim IndexModePost, StFrm, IIC_iStore_bh_ru, 2733226890Sdim "strbt", "\t$Rt, $addr, $offset", 2734226890Sdim "$addr.base = $Rn_wb", []> { 2735226890Sdim // {12} isAdd 2736226890Sdim // {11-0} imm12/Rm 2737226890Sdim bits<14> offset; 2738226890Sdim bits<4> addr; 2739226890Sdim let Inst{25} = 1; 2740226890Sdim let Inst{23} = offset{12}; 2741203954Srdivacky let Inst{21} = 1; // overwrite 2742226890Sdim let Inst{19-16} = addr; 2743226890Sdim let Inst{11-5} = offset{11-5}; 2744226890Sdim let Inst{4} = 0; 2745226890Sdim let Inst{3-0} = offset{3-0}; 2746226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2747203954Srdivacky} 2748203954Srdivacky 2749226890Sdimdef STRBT_POST_IMM : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), 2750226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 2751226890Sdim IndexModePost, StFrm, IIC_iStore_bh_ru, 2752226890Sdim "strbt", "\t$Rt, $addr, $offset", 2753226890Sdim "$addr.base = $Rn_wb", []> { 2754226890Sdim // {12} isAdd 2755226890Sdim // {11-0} imm12/Rm 2756226890Sdim bits<14> offset; 2757226890Sdim bits<4> addr; 2758226890Sdim let Inst{25} = 0; 2759226890Sdim let Inst{23} = offset{12}; 2760203954Srdivacky let Inst{21} = 1; // overwrite 2761226890Sdim let Inst{19-16} = addr; 2762226890Sdim let Inst{11-0} = offset{11-0}; 2763226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2764203954Srdivacky} 2765203954Srdivacky 2766226890Sdimlet mayStore = 1, neverHasSideEffects = 1 in { 2767226890Sdimdef STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), 2768226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 2769226890Sdim IndexModePost, StFrm, IIC_iStore_ru, 2770226890Sdim "strt", "\t$Rt, $addr, $offset", 2771226890Sdim "$addr.base = $Rn_wb", []> { 2772226890Sdim // {12} isAdd 2773226890Sdim // {11-0} imm12/Rm 2774226890Sdim bits<14> offset; 2775226890Sdim bits<4> addr; 2776226890Sdim let Inst{25} = 1; 2777226890Sdim let Inst{23} = offset{12}; 2778204642Srdivacky let Inst{21} = 1; // overwrite 2779226890Sdim let Inst{19-16} = addr; 2780226890Sdim let Inst{11-5} = offset{11-5}; 2781226890Sdim let Inst{4} = 0; 2782226890Sdim let Inst{3-0} = offset{3-0}; 2783226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2784204642Srdivacky} 2785204642Srdivacky 2786226890Sdimdef STRT_POST_IMM : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), 2787226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 2788226890Sdim IndexModePost, StFrm, IIC_iStore_ru, 2789226890Sdim "strt", "\t$Rt, $addr, $offset", 2790226890Sdim "$addr.base = $Rn_wb", []> { 2791226890Sdim // {12} isAdd 2792226890Sdim // {11-0} imm12/Rm 2793226890Sdim bits<14> offset; 2794226890Sdim bits<4> addr; 2795226890Sdim let Inst{25} = 0; 2796226890Sdim let Inst{23} = offset{12}; 2797226890Sdim let Inst{21} = 1; // overwrite 2798226890Sdim let Inst{19-16} = addr; 2799226890Sdim let Inst{11-0} = offset{11-0}; 2800226890Sdim let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 2801226890Sdim} 2802226890Sdim} 2803226890Sdim 2804226890Sdim 2805226890Sdimmulticlass AI3strT<bits<4> op, string opc> { 2806226890Sdim def i : AI3ldstidxT<op, 0, (outs GPR:$base_wb), 2807226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, postidx_imm8:$offset), 2808226890Sdim IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc, 2809226890Sdim "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> { 2810226890Sdim bits<9> offset; 2811226890Sdim let Inst{23} = offset{8}; 2812226890Sdim let Inst{22} = 1; 2813226890Sdim let Inst{11-8} = offset{7-4}; 2814226890Sdim let Inst{3-0} = offset{3-0}; 2815226890Sdim } 2816226890Sdim def r : AI3ldstidxT<op, 0, (outs GPR:$base_wb), 2817226890Sdim (ins GPR:$Rt, addr_offset_none:$addr, postidx_reg:$Rm), 2818226890Sdim IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc, 2819226890Sdim "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> { 2820226890Sdim bits<5> Rm; 2821226890Sdim let Inst{23} = Rm{4}; 2822226890Sdim let Inst{22} = 0; 2823226890Sdim let Inst{11-8} = 0; 2824226890Sdim let Inst{3-0} = Rm{3-0}; 2825226890Sdim } 2826226890Sdim} 2827226890Sdim 2828226890Sdim 2829226890Sdimdefm STRHT : AI3strT<0b1011, "strht">; 2830226890Sdim 2831263509Sdimdef STL : AIstrrel<0b00, (outs), (ins GPR:$Rt, addr_offset_none:$addr), 2832263509Sdim NoItinerary, "stl", "\t$Rt, $addr", []>; 2833263509Sdimdef STLB : AIstrrel<0b10, (outs), (ins GPR:$Rt, addr_offset_none:$addr), 2834263509Sdim NoItinerary, "stlb", "\t$Rt, $addr", []>; 2835263509Sdimdef STLH : AIstrrel<0b11, (outs), (ins GPR:$Rt, addr_offset_none:$addr), 2836263509Sdim NoItinerary, "stlh", "\t$Rt, $addr", []>; 2837226890Sdim 2838193323Sed//===----------------------------------------------------------------------===// 2839193323Sed// Load / store multiple Instructions. 2840193323Sed// 2841193323Sed 2842235633Sdimmulticlass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f, 2843218893Sdim InstrItinClass itin, InstrItinClass itin_upd> { 2844224145Sdim // IA is the default, so no need for an explicit suffix on the 2845245431Sdim // mnemonic here. Without it is the canonical spelling. 2846218893Sdim def IA : 2847218893Sdim AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2848218893Sdim IndexModeNone, f, itin, 2849235633Sdim !strconcat(asm, "${p}\t$Rn, $regs", sfx), "", []> { 2850218893Sdim let Inst{24-23} = 0b01; // Increment After 2851235633Sdim let Inst{22} = P_bit; 2852218893Sdim let Inst{21} = 0; // No writeback 2853218893Sdim let Inst{20} = L_bit; 2854218893Sdim } 2855218893Sdim def IA_UPD : 2856218893Sdim AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2857218893Sdim IndexModeUpd, f, itin_upd, 2858235633Sdim !strconcat(asm, "${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 2859218893Sdim let Inst{24-23} = 0b01; // Increment After 2860235633Sdim let Inst{22} = P_bit; 2861218893Sdim let Inst{21} = 1; // Writeback 2862218893Sdim let Inst{20} = L_bit; 2863226890Sdim 2864226890Sdim let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 2865218893Sdim } 2866218893Sdim def DA : 2867218893Sdim AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2868218893Sdim IndexModeNone, f, itin, 2869235633Sdim !strconcat(asm, "da${p}\t$Rn, $regs", sfx), "", []> { 2870218893Sdim let Inst{24-23} = 0b00; // Decrement After 2871235633Sdim let Inst{22} = P_bit; 2872218893Sdim let Inst{21} = 0; // No writeback 2873218893Sdim let Inst{20} = L_bit; 2874218893Sdim } 2875218893Sdim def DA_UPD : 2876218893Sdim AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2877218893Sdim IndexModeUpd, f, itin_upd, 2878235633Sdim !strconcat(asm, "da${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 2879218893Sdim let Inst{24-23} = 0b00; // Decrement After 2880235633Sdim let Inst{22} = P_bit; 2881218893Sdim let Inst{21} = 1; // Writeback 2882218893Sdim let Inst{20} = L_bit; 2883226890Sdim 2884226890Sdim let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 2885218893Sdim } 2886218893Sdim def DB : 2887218893Sdim AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2888218893Sdim IndexModeNone, f, itin, 2889235633Sdim !strconcat(asm, "db${p}\t$Rn, $regs", sfx), "", []> { 2890218893Sdim let Inst{24-23} = 0b10; // Decrement Before 2891235633Sdim let Inst{22} = P_bit; 2892218893Sdim let Inst{21} = 0; // No writeback 2893218893Sdim let Inst{20} = L_bit; 2894218893Sdim } 2895218893Sdim def DB_UPD : 2896218893Sdim AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2897218893Sdim IndexModeUpd, f, itin_upd, 2898235633Sdim !strconcat(asm, "db${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 2899218893Sdim let Inst{24-23} = 0b10; // Decrement Before 2900235633Sdim let Inst{22} = P_bit; 2901218893Sdim let Inst{21} = 1; // Writeback 2902218893Sdim let Inst{20} = L_bit; 2903226890Sdim 2904226890Sdim let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 2905218893Sdim } 2906218893Sdim def IB : 2907218893Sdim AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2908218893Sdim IndexModeNone, f, itin, 2909235633Sdim !strconcat(asm, "ib${p}\t$Rn, $regs", sfx), "", []> { 2910218893Sdim let Inst{24-23} = 0b11; // Increment Before 2911235633Sdim let Inst{22} = P_bit; 2912218893Sdim let Inst{21} = 0; // No writeback 2913218893Sdim let Inst{20} = L_bit; 2914218893Sdim } 2915218893Sdim def IB_UPD : 2916218893Sdim AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 2917218893Sdim IndexModeUpd, f, itin_upd, 2918235633Sdim !strconcat(asm, "ib${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 2919218893Sdim let Inst{24-23} = 0b11; // Increment Before 2920235633Sdim let Inst{22} = P_bit; 2921218893Sdim let Inst{21} = 1; // Writeback 2922218893Sdim let Inst{20} = L_bit; 2923226890Sdim 2924226890Sdim let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 2925218893Sdim } 2926221345Sdim} 2927193323Sed 2928218893Sdimlet neverHasSideEffects = 1 in { 2929193323Sed 2930218893Sdimlet mayLoad = 1, hasExtraDefRegAllocReq = 1 in 2931235633Sdimdefm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m, 2932235633Sdim IIC_iLoad_mu>; 2933205218Srdivacky 2934218893Sdimlet mayStore = 1, hasExtraSrcRegAllocReq = 1 in 2935235633Sdimdefm STM : arm_ldst_mult<"stm", "", 0, 0, LdStMulFrm, IIC_iStore_m, 2936235633Sdim IIC_iStore_mu>; 2937205218Srdivacky 2938218893Sdim} // neverHasSideEffects 2939218893Sdim 2940218893Sdim// FIXME: remove when we have a way to marking a MI with these properties. 2941218893Sdim// FIXME: Should pc be an implicit operand like PICADD, etc? 2942218893Sdimlet isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 2943218893Sdim hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in 2944224145Sdimdef LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, 2945224145Sdim reglist:$regs, variable_ops), 2946224145Sdim 4, IIC_iLoad_mBr, [], 2947224145Sdim (LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>, 2948221345Sdim RegConstraint<"$Rn = $wb">; 2949218893Sdim 2950235633Sdimlet mayLoad = 1, hasExtraDefRegAllocReq = 1 in 2951235633Sdimdefm sysLDM : arm_ldst_mult<"ldm", " ^", 1, 1, LdStMulFrm, IIC_iLoad_m, 2952235633Sdim IIC_iLoad_mu>; 2953235633Sdim 2954235633Sdimlet mayStore = 1, hasExtraSrcRegAllocReq = 1 in 2955235633Sdimdefm sysSTM : arm_ldst_mult<"stm", " ^", 0, 1, LdStMulFrm, IIC_iStore_m, 2956235633Sdim IIC_iStore_mu>; 2957235633Sdim 2958235633Sdim 2959235633Sdim 2960193323Sed//===----------------------------------------------------------------------===// 2961193323Sed// Move Instructions. 2962193323Sed// 2963193323Sed 2964194178Sedlet neverHasSideEffects = 1 in 2965218893Sdimdef MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr, 2966263509Sdim "mov", "\t$Rd, $Rm", []>, UnaryDP, Sched<[WriteALU]> { 2967218893Sdim bits<4> Rd; 2968218893Sdim bits<4> Rm; 2969218893Sdim 2970221345Sdim let Inst{19-16} = 0b0000; 2971199481Srdivacky let Inst{11-4} = 0b00000000; 2972198113Srdivacky let Inst{25} = 0; 2973218893Sdim let Inst{3-0} = Rm; 2974218893Sdim let Inst{15-12} = Rd; 2975198113Srdivacky} 2976198113Srdivacky 2977210299Sed// A version for the smaller set of tail call registers. 2978210299Sedlet neverHasSideEffects = 1 in 2979218893Sdimdef MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm, 2980263509Sdim IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP, Sched<[WriteALU]> { 2981218893Sdim bits<4> Rd; 2982218893Sdim bits<4> Rm; 2983218893Sdim 2984210299Sed let Inst{11-4} = 0b00000000; 2985210299Sed let Inst{25} = 0; 2986218893Sdim let Inst{3-0} = Rm; 2987218893Sdim let Inst{15-12} = Rd; 2988210299Sed} 2989210299Sed 2990226890Sdimdef MOVsr : AsI1<0b1101, (outs GPRnopc:$Rd), (ins shift_so_reg_reg:$src), 2991226890Sdim DPSoRegRegFrm, IIC_iMOVsr, 2992226890Sdim "mov", "\t$Rd, $src", 2993263509Sdim [(set GPRnopc:$Rd, shift_so_reg_reg:$src)]>, UnaryDP, 2994263509Sdim Sched<[WriteALU]> { 2995226890Sdim bits<4> Rd; 2996226890Sdim bits<12> src; 2997226890Sdim let Inst{15-12} = Rd; 2998226890Sdim let Inst{19-16} = 0b0000; 2999226890Sdim let Inst{11-8} = src{11-8}; 3000226890Sdim let Inst{7} = 0; 3001226890Sdim let Inst{6-5} = src{6-5}; 3002226890Sdim let Inst{4} = 1; 3003226890Sdim let Inst{3-0} = src{3-0}; 3004226890Sdim let Inst{25} = 0; 3005226890Sdim} 3006226890Sdim 3007226890Sdimdef MOVsi : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_imm:$src), 3008226890Sdim DPSoRegImmFrm, IIC_iMOVsr, 3009226890Sdim "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_imm:$src)]>, 3010263509Sdim UnaryDP, Sched<[WriteALU]> { 3011218893Sdim bits<4> Rd; 3012218893Sdim bits<12> src; 3013218893Sdim let Inst{15-12} = Rd; 3014221345Sdim let Inst{19-16} = 0b0000; 3015226890Sdim let Inst{11-5} = src{11-5}; 3016226890Sdim let Inst{4} = 0; 3017226890Sdim let Inst{3-0} = src{3-0}; 3018198113Srdivacky let Inst{25} = 0; 3019198113Srdivacky} 3020193323Sed 3021218893Sdimlet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 3022218893Sdimdef MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi, 3023263509Sdim "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP, 3024263509Sdim Sched<[WriteALU]> { 3025218893Sdim bits<4> Rd; 3026218893Sdim bits<12> imm; 3027198090Srdivacky let Inst{25} = 1; 3028218893Sdim let Inst{15-12} = Rd; 3029218893Sdim let Inst{19-16} = 0b0000; 3030218893Sdim let Inst{11-0} = imm; 3031198090Srdivacky} 3032193323Sed 3033218893Sdimlet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 3034226890Sdimdef MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins imm0_65535_expr:$imm), 3035198090Srdivacky DPFrm, IIC_iMOVi, 3036218893Sdim "movw", "\t$Rd, $imm", 3037218893Sdim [(set GPR:$Rd, imm0_65535:$imm)]>, 3038263509Sdim Requires<[IsARM, HasV6T2]>, UnaryDP, Sched<[WriteALU]> { 3039218893Sdim bits<4> Rd; 3040218893Sdim bits<16> imm; 3041218893Sdim let Inst{15-12} = Rd; 3042218893Sdim let Inst{11-0} = imm{11-0}; 3043218893Sdim let Inst{19-16} = imm{15-12}; 3044198090Srdivacky let Inst{20} = 0; 3045198090Srdivacky let Inst{25} = 1; 3046226890Sdim let DecoderMethod = "DecodeArmMOVTWInstruction"; 3047198090Srdivacky} 3048198090Srdivacky 3049226890Sdimdef : InstAlias<"mov${p} $Rd, $imm", 3050226890Sdim (MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p)>, 3051226890Sdim Requires<[IsARM]>; 3052226890Sdim 3053218893Sdimdef MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 3054263509Sdim (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>, 3055263509Sdim Sched<[WriteALU]>; 3056218893Sdim 3057218893Sdimlet Constraints = "$src = $Rd" in { 3058226890Sdimdef MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd), 3059226890Sdim (ins GPR:$src, imm0_65535_expr:$imm), 3060198090Srdivacky DPFrm, IIC_iMOVi, 3061218893Sdim "movt", "\t$Rd, $imm", 3062226890Sdim [(set GPRnopc:$Rd, 3063204642Srdivacky (or (and GPR:$src, 0xffff), 3064198090Srdivacky lo16AllZero:$imm))]>, UnaryDP, 3065263509Sdim Requires<[IsARM, HasV6T2]>, Sched<[WriteALU]> { 3066218893Sdim bits<4> Rd; 3067218893Sdim bits<16> imm; 3068218893Sdim let Inst{15-12} = Rd; 3069218893Sdim let Inst{11-0} = imm{11-0}; 3070218893Sdim let Inst{19-16} = imm{15-12}; 3071198090Srdivacky let Inst{20} = 0; 3072198090Srdivacky let Inst{25} = 1; 3073226890Sdim let DecoderMethod = "DecodeArmMOVTWInstruction"; 3074198090Srdivacky} 3075198090Srdivacky 3076218893Sdimdef MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 3077263509Sdim (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>, 3078263509Sdim Sched<[WriteALU]>; 3079218893Sdim 3080218893Sdim} // Constraints 3081218893Sdim 3082198396Srdivackydef : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, 3083198396Srdivacky Requires<[IsARM, HasV6T2]>; 3084198396Srdivacky 3085198090Srdivackylet Uses = [CPSR] in 3086218893Sdimdef RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, 3087218893Sdim [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP, 3088263509Sdim Requires<[IsARM]>, Sched<[WriteALU]>; 3089193323Sed 3090193323Sed// These aren't really mov instructions, but we have to define them this way 3091193323Sed// due to flag operands. 3092193323Sed 3093193323Sedlet Defs = [CPSR] in { 3094218893Sdimdef MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 3095218893Sdim [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP, 3096263509Sdim Sched<[WriteALU]>, Requires<[IsARM]>; 3097218893Sdimdef MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 3098218893Sdim [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP, 3099263509Sdim Sched<[WriteALU]>, Requires<[IsARM]>; 3100193323Sed} 3101193323Sed 3102193323Sed//===----------------------------------------------------------------------===// 3103193323Sed// Extend Instructions. 3104193323Sed// 3105193323Sed 3106193323Sed// Sign extenders 3107193323Sed 3108226890Sdimdef SXTB : AI_ext_rrot<0b01101010, 3109218893Sdim "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; 3110226890Sdimdef SXTH : AI_ext_rrot<0b01101011, 3111218893Sdim "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; 3112193323Sed 3113226890Sdimdef SXTAB : AI_exta_rrot<0b01101010, 3114193323Sed "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 3115226890Sdimdef SXTAH : AI_exta_rrot<0b01101011, 3116193323Sed "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 3117193323Sed 3118226890Sdimdef SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">; 3119193323Sed 3120226890Sdimdef SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">; 3121204642Srdivacky 3122193323Sed// Zero extenders 3123193323Sed 3124193323Sedlet AddedComplexity = 16 in { 3125226890Sdimdef UXTB : AI_ext_rrot<0b01101110, 3126218893Sdim "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; 3127226890Sdimdef UXTH : AI_ext_rrot<0b01101111, 3128218893Sdim "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 3129226890Sdimdef UXTB16 : AI_ext_rrot<0b01101100, 3130218893Sdim "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 3131193323Sed 3132212904Sdim// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 3133212904Sdim// The transformation should probably be done as a combiner action 3134212904Sdim// instead so we can include a check for masking back in the upper 3135212904Sdim// eight bits of the source into the lower eight bits of the result. 3136212904Sdim//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), 3137226890Sdim// (UXTB16r_rot GPR:$Src, 3)>; 3138194710Seddef : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), 3139226890Sdim (UXTB16 GPR:$Src, 1)>; 3140193323Sed 3141226890Sdimdef UXTAB : AI_exta_rrot<0b01101110, "uxtab", 3142193323Sed BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 3143226890Sdimdef UXTAH : AI_exta_rrot<0b01101111, "uxtah", 3144193323Sed BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 3145193323Sed} 3146193323Sed 3147193323Sed// This isn't safe in general, the add is two 16-bit units, not a 32-bit add. 3148226890Sdimdef UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; 3149193323Sed 3150193323Sed 3151226890Sdimdef SBFX : I<(outs GPRnopc:$Rd), 3152226890Sdim (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width), 3153224145Sdim AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3154218893Sdim "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 3155198090Srdivacky Requires<[IsARM, HasV6T2]> { 3156218893Sdim bits<4> Rd; 3157218893Sdim bits<4> Rn; 3158218893Sdim bits<5> lsb; 3159218893Sdim bits<5> width; 3160198090Srdivacky let Inst{27-21} = 0b0111101; 3161198090Srdivacky let Inst{6-4} = 0b101; 3162218893Sdim let Inst{20-16} = width; 3163218893Sdim let Inst{15-12} = Rd; 3164218893Sdim let Inst{11-7} = lsb; 3165218893Sdim let Inst{3-0} = Rn; 3166198090Srdivacky} 3167198090Srdivacky 3168218893Sdimdef UBFX : I<(outs GPR:$Rd), 3169226890Sdim (ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width), 3170224145Sdim AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3171218893Sdim "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 3172198090Srdivacky Requires<[IsARM, HasV6T2]> { 3173218893Sdim bits<4> Rd; 3174218893Sdim bits<4> Rn; 3175218893Sdim bits<5> lsb; 3176218893Sdim bits<5> width; 3177198090Srdivacky let Inst{27-21} = 0b0111111; 3178198090Srdivacky let Inst{6-4} = 0b101; 3179218893Sdim let Inst{20-16} = width; 3180218893Sdim let Inst{15-12} = Rd; 3181218893Sdim let Inst{11-7} = lsb; 3182218893Sdim let Inst{3-0} = Rn; 3183198090Srdivacky} 3184198090Srdivacky 3185193323Sed//===----------------------------------------------------------------------===// 3186193323Sed// Arithmetic Instructions. 3187193323Sed// 3188193323Sed 3189193323Seddefm ADD : AsI1_bin_irs<0b0100, "add", 3190218893Sdim IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3191245431Sdim BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 3192193323Seddefm SUB : AsI1_bin_irs<0b0010, "sub", 3193218893Sdim IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3194245431Sdim BinOpFrag<(sub node:$LHS, node:$RHS)>>; 3195193323Sed 3196193323Sed// ADD and SUB with 's' bit set. 3197226890Sdim// 3198235633Sdim// Currently, ADDS/SUBS are pseudo opcodes that exist only in the 3199235633Sdim// selection DAG. They are "lowered" to real ADD/SUB opcodes by 3200226890Sdim// AdjustInstrPostInstrSelection where we determine whether or not to 3201226890Sdim// set the "s" bit based on CPSR liveness. 3202226890Sdim// 3203235633Sdim// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen 3204226890Sdim// support for an optional CPSR definition that corresponds to the DAG 3205226890Sdim// node's second value. We can then eliminate the implicit def of CPSR. 3206235633Sdimdefm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3207235633Sdim BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>; 3208235633Sdimdefm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3209235633Sdim BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; 3210193323Sed 3211195098Seddefm ADC : AI1_adde_sube_irs<0b0101, "adc", 3212245431Sdim BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>, 1>; 3213195098Seddefm SBC : AI1_adde_sube_irs<0b0110, "sbc", 3214245431Sdim BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>; 3215218893Sdim 3216245431Sdimdefm RSB : AsI1_rbin_irs<0b0011, "rsb", 3217245431Sdim IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3218245431Sdim BinOpFrag<(sub node:$LHS, node:$RHS)>>; 3219193323Sed 3220226890Sdim// FIXME: Eliminate them if we can write def : Pat patterns which defines 3221226890Sdim// CPSR and the implicit def of CPSR is not needed. 3222235633Sdimdefm RSBS : AsI1_rbin_s_is<IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3223235633Sdim BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; 3224193323Sed 3225226890Sdimdefm RSC : AI1_rsc_irs<0b0111, "rsc", 3226245431Sdim BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>; 3227212904Sdim 3228193323Sed// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 3229210299Sed// The assume-no-carry-in form uses the negation of the input since add/sub 3230210299Sed// assume opposite meanings of the carry flag (i.e., carry == !borrow). 3231210299Sed// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 3232210299Sed// details. 3233226890Sdimdef : ARMPat<(add GPR:$src, so_imm_neg:$imm), 3234226890Sdim (SUBri GPR:$src, so_imm_neg:$imm)>; 3235226890Sdimdef : ARMPat<(ARMaddc GPR:$src, so_imm_neg:$imm), 3236226890Sdim (SUBSri GPR:$src, so_imm_neg:$imm)>; 3237226890Sdim 3238245431Sdimdef : ARMPat<(add GPR:$src, imm0_65535_neg:$imm), 3239245431Sdim (SUBrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>, 3240245431Sdim Requires<[IsARM, HasV6T2]>; 3241245431Sdimdef : ARMPat<(ARMaddc GPR:$src, imm0_65535_neg:$imm), 3242245431Sdim (SUBSrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>, 3243245431Sdim Requires<[IsARM, HasV6T2]>; 3244245431Sdim 3245210299Sed// The with-carry-in form matches bitwise not instead of the negation. 3246210299Sed// Effectively, the inverse interpretation of the carry flag already accounts 3247210299Sed// for part of the negation. 3248226890Sdimdef : ARMPat<(ARMadde GPR:$src, so_imm_not:$imm, CPSR), 3249226890Sdim (SBCri GPR:$src, so_imm_not:$imm)>; 3250245431Sdimdef : ARMPat<(ARMadde GPR:$src, imm0_65535_neg:$imm, CPSR), 3251245431Sdim (SBCrr GPR:$src, (MOVi16 (imm_not_XFORM imm:$imm)))>; 3252193323Sed 3253193323Sed// Note: These are implemented in C++ code, because they have to generate 3254193323Sed// ADD/SUBrs instructions, which use a complex pattern that a xform function 3255193323Sed// cannot produce. 3256193323Sed// (mul X, 2^n+1) -> (add (X << n), X) 3257193323Sed// (mul X, 2^n-1) -> (rsb X, (X << n)) 3258193323Sed 3259226890Sdim// ARM Arithmetic Instruction 3260203954Srdivacky// GPR:$dst = GPR:$a op GPR:$b 3261218893Sdimclass AAI<bits<8> op27_20, bits<8> op11_4, string opc, 3262226890Sdim list<dag> pattern = [], 3263226890Sdim dag iops = (ins GPRnopc:$Rn, GPRnopc:$Rm), 3264226890Sdim string asm = "\t$Rd, $Rn, $Rm"> 3265263509Sdim : AI<(outs GPRnopc:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern>, 3266263509Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 3267218893Sdim bits<4> Rn; 3268218893Sdim bits<4> Rd; 3269218893Sdim bits<4> Rm; 3270203954Srdivacky let Inst{27-20} = op27_20; 3271218893Sdim let Inst{11-4} = op11_4; 3272218893Sdim let Inst{19-16} = Rn; 3273218893Sdim let Inst{15-12} = Rd; 3274218893Sdim let Inst{3-0} = Rm; 3275245431Sdim 3276235633Sdim let Unpredictable{11-8} = 0b1111; 3277203954Srdivacky} 3278203954Srdivacky 3279226890Sdim// Saturating add/subtract 3280203954Srdivacky 3281263509Sdimlet DecoderMethod = "DecodeQADDInstruction" in 3282218893Sdimdef QADD : AAI<0b00010000, 0b00000101, "qadd", 3283226890Sdim [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))], 3284226890Sdim (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">; 3285263509Sdim 3286218893Sdimdef QSUB : AAI<0b00010010, 0b00000101, "qsub", 3287226890Sdim [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))], 3288226890Sdim (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">; 3289226890Sdimdef QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], 3290226890Sdim (ins GPRnopc:$Rm, GPRnopc:$Rn), 3291218893Sdim "\t$Rd, $Rm, $Rn">; 3292226890Sdimdef QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], 3293226890Sdim (ins GPRnopc:$Rm, GPRnopc:$Rn), 3294218893Sdim "\t$Rd, $Rm, $Rn">; 3295204642Srdivacky 3296218893Sdimdef QADD16 : AAI<0b01100010, 0b11110001, "qadd16">; 3297218893Sdimdef QADD8 : AAI<0b01100010, 0b11111001, "qadd8">; 3298218893Sdimdef QASX : AAI<0b01100010, 0b11110011, "qasx">; 3299218893Sdimdef QSAX : AAI<0b01100010, 0b11110101, "qsax">; 3300218893Sdimdef QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">; 3301218893Sdimdef QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">; 3302218893Sdimdef UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">; 3303218893Sdimdef UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">; 3304218893Sdimdef UQASX : AAI<0b01100110, 0b11110011, "uqasx">; 3305218893Sdimdef UQSAX : AAI<0b01100110, 0b11110101, "uqsax">; 3306218893Sdimdef UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">; 3307218893Sdimdef UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">; 3308218893Sdim 3309226890Sdim// Signed/Unsigned add/subtract 3310204642Srdivacky 3311218893Sdimdef SASX : AAI<0b01100001, 0b11110011, "sasx">; 3312218893Sdimdef SADD16 : AAI<0b01100001, 0b11110001, "sadd16">; 3313218893Sdimdef SADD8 : AAI<0b01100001, 0b11111001, "sadd8">; 3314218893Sdimdef SSAX : AAI<0b01100001, 0b11110101, "ssax">; 3315218893Sdimdef SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">; 3316218893Sdimdef SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">; 3317218893Sdimdef UASX : AAI<0b01100101, 0b11110011, "uasx">; 3318218893Sdimdef UADD16 : AAI<0b01100101, 0b11110001, "uadd16">; 3319218893Sdimdef UADD8 : AAI<0b01100101, 0b11111001, "uadd8">; 3320218893Sdimdef USAX : AAI<0b01100101, 0b11110101, "usax">; 3321218893Sdimdef USUB16 : AAI<0b01100101, 0b11110111, "usub16">; 3322218893Sdimdef USUB8 : AAI<0b01100101, 0b11111111, "usub8">; 3323204642Srdivacky 3324226890Sdim// Signed/Unsigned halving add/subtract 3325204642Srdivacky 3326218893Sdimdef SHASX : AAI<0b01100011, 0b11110011, "shasx">; 3327218893Sdimdef SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">; 3328218893Sdimdef SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">; 3329218893Sdimdef SHSAX : AAI<0b01100011, 0b11110101, "shsax">; 3330218893Sdimdef SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">; 3331218893Sdimdef SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">; 3332218893Sdimdef UHASX : AAI<0b01100111, 0b11110011, "uhasx">; 3333218893Sdimdef UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">; 3334218893Sdimdef UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">; 3335218893Sdimdef UHSAX : AAI<0b01100111, 0b11110101, "uhsax">; 3336218893Sdimdef UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">; 3337218893Sdimdef UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">; 3338204642Srdivacky 3339226890Sdim// Unsigned Sum of Absolute Differences [and Accumulate]. 3340204642Srdivacky 3341218893Sdimdef USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3342204642Srdivacky MulFrm /* for convenience */, NoItinerary, "usad8", 3343218893Sdim "\t$Rd, $Rn, $Rm", []>, 3344263509Sdim Requires<[IsARM, HasV6]>, Sched<[WriteALU, ReadALU, ReadALU]> { 3345218893Sdim bits<4> Rd; 3346218893Sdim bits<4> Rn; 3347218893Sdim bits<4> Rm; 3348204642Srdivacky let Inst{27-20} = 0b01111000; 3349204642Srdivacky let Inst{15-12} = 0b1111; 3350204642Srdivacky let Inst{7-4} = 0b0001; 3351218893Sdim let Inst{19-16} = Rd; 3352218893Sdim let Inst{11-8} = Rm; 3353218893Sdim let Inst{3-0} = Rn; 3354204642Srdivacky} 3355218893Sdimdef USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3356204642Srdivacky MulFrm /* for convenience */, NoItinerary, "usada8", 3357218893Sdim "\t$Rd, $Rn, $Rm, $Ra", []>, 3358263509Sdim Requires<[IsARM, HasV6]>, Sched<[WriteALU, ReadALU, ReadALU]>{ 3359218893Sdim bits<4> Rd; 3360218893Sdim bits<4> Rn; 3361218893Sdim bits<4> Rm; 3362218893Sdim bits<4> Ra; 3363204642Srdivacky let Inst{27-20} = 0b01111000; 3364204642Srdivacky let Inst{7-4} = 0b0001; 3365218893Sdim let Inst{19-16} = Rd; 3366218893Sdim let Inst{15-12} = Ra; 3367218893Sdim let Inst{11-8} = Rm; 3368218893Sdim let Inst{3-0} = Rn; 3369204642Srdivacky} 3370204642Srdivacky 3371226890Sdim// Signed/Unsigned saturate 3372204642Srdivacky 3373226890Sdimdef SSAT : AI<(outs GPRnopc:$Rd), 3374226890Sdim (ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), 3375226890Sdim SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> { 3376218893Sdim bits<4> Rd; 3377218893Sdim bits<5> sat_imm; 3378218893Sdim bits<4> Rn; 3379218893Sdim bits<8> sh; 3380204642Srdivacky let Inst{27-21} = 0b0110101; 3381212904Sdim let Inst{5-4} = 0b01; 3382218893Sdim let Inst{20-16} = sat_imm; 3383218893Sdim let Inst{15-12} = Rd; 3384226890Sdim let Inst{11-7} = sh{4-0}; 3385226890Sdim let Inst{6} = sh{5}; 3386218893Sdim let Inst{3-0} = Rn; 3387204642Srdivacky} 3388204642Srdivacky 3389226890Sdimdef SSAT16 : AI<(outs GPRnopc:$Rd), 3390226890Sdim (ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm, 3391226890Sdim NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> { 3392218893Sdim bits<4> Rd; 3393218893Sdim bits<4> sat_imm; 3394218893Sdim bits<4> Rn; 3395204642Srdivacky let Inst{27-20} = 0b01101010; 3396218893Sdim let Inst{11-4} = 0b11110011; 3397218893Sdim let Inst{15-12} = Rd; 3398218893Sdim let Inst{19-16} = sat_imm; 3399218893Sdim let Inst{3-0} = Rn; 3400204642Srdivacky} 3401204642Srdivacky 3402226890Sdimdef USAT : AI<(outs GPRnopc:$Rd), 3403226890Sdim (ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), 3404226890Sdim SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> { 3405218893Sdim bits<4> Rd; 3406218893Sdim bits<5> sat_imm; 3407218893Sdim bits<4> Rn; 3408218893Sdim bits<8> sh; 3409204642Srdivacky let Inst{27-21} = 0b0110111; 3410212904Sdim let Inst{5-4} = 0b01; 3411218893Sdim let Inst{15-12} = Rd; 3412226890Sdim let Inst{11-7} = sh{4-0}; 3413226890Sdim let Inst{6} = sh{5}; 3414218893Sdim let Inst{20-16} = sat_imm; 3415218893Sdim let Inst{3-0} = Rn; 3416204642Srdivacky} 3417204642Srdivacky 3418226890Sdimdef USAT16 : AI<(outs GPRnopc:$Rd), 3419226890Sdim (ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm, 3420226890Sdim NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []> { 3421218893Sdim bits<4> Rd; 3422218893Sdim bits<4> sat_imm; 3423218893Sdim bits<4> Rn; 3424204642Srdivacky let Inst{27-20} = 0b01101110; 3425218893Sdim let Inst{11-4} = 0b11110011; 3426218893Sdim let Inst{15-12} = Rd; 3427218893Sdim let Inst{19-16} = sat_imm; 3428218893Sdim let Inst{3-0} = Rn; 3429204642Srdivacky} 3430204642Srdivacky 3431226890Sdimdef : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm:$pos), 3432226890Sdim (SSAT imm:$pos, GPRnopc:$a, 0)>; 3433226890Sdimdef : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm:$pos), 3434226890Sdim (USAT imm:$pos, GPRnopc:$a, 0)>; 3435212904Sdim 3436193323Sed//===----------------------------------------------------------------------===// 3437193323Sed// Bitwise Instructions. 3438193323Sed// 3439193323Sed 3440193323Seddefm AND : AsI1_bin_irs<0b0000, "and", 3441218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsr, 3442245431Sdim BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 3443193323Seddefm ORR : AsI1_bin_irs<0b1100, "orr", 3444218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsr, 3445245431Sdim BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 3446193323Seddefm EOR : AsI1_bin_irs<0b0001, "eor", 3447218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsr, 3448245431Sdim BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 3449193323Seddefm BIC : AsI1_bin_irs<0b1110, "bic", 3450218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsr, 3451245431Sdim BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 3452193323Sed 3453226890Sdim// FIXME: bf_inv_mask_imm should be two operands, the lsb and the msb, just 3454226890Sdim// like in the actual instruction encoding. The complexity of mapping the mask 3455226890Sdim// to the lsb/msb pair should be handled by ISel, not encapsulated in the 3456226890Sdim// instruction description. 3457218893Sdimdef BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm), 3458224145Sdim AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3459218893Sdim "bfc", "\t$Rd, $imm", "$src = $Rd", 3460218893Sdim [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>, 3461198090Srdivacky Requires<[IsARM, HasV6T2]> { 3462218893Sdim bits<4> Rd; 3463218893Sdim bits<10> imm; 3464198090Srdivacky let Inst{27-21} = 0b0111110; 3465198090Srdivacky let Inst{6-0} = 0b0011111; 3466218893Sdim let Inst{15-12} = Rd; 3467218893Sdim let Inst{11-7} = imm{4-0}; // lsb 3468226890Sdim let Inst{20-16} = imm{9-5}; // msb 3469198090Srdivacky} 3470198090Srdivacky 3471204642Srdivacky// A8.6.18 BFI - Bitfield insert (Encoding A1) 3472226890Sdimdef BFI:I<(outs GPRnopc:$Rd), (ins GPRnopc:$src, GPR:$Rn, bf_inv_mask_imm:$imm), 3473226890Sdim AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3474226890Sdim "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd", 3475226890Sdim [(set GPRnopc:$Rd, (ARMbfi GPRnopc:$src, GPR:$Rn, 3476226890Sdim bf_inv_mask_imm:$imm))]>, 3477226890Sdim Requires<[IsARM, HasV6T2]> { 3478218893Sdim bits<4> Rd; 3479218893Sdim bits<4> Rn; 3480218893Sdim bits<10> imm; 3481204642Srdivacky let Inst{27-21} = 0b0111110; 3482204642Srdivacky let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 3483218893Sdim let Inst{15-12} = Rd; 3484218893Sdim let Inst{11-7} = imm{4-0}; // lsb 3485218893Sdim let Inst{20-16} = imm{9-5}; // width 3486218893Sdim let Inst{3-0} = Rn; 3487204642Srdivacky} 3488204642Srdivacky 3489218893Sdimdef MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr, 3490218893Sdim "mvn", "\t$Rd, $Rm", 3491263509Sdim [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP, Sched<[WriteALU]> { 3492218893Sdim bits<4> Rd; 3493218893Sdim bits<4> Rm; 3494203954Srdivacky let Inst{25} = 0; 3495218893Sdim let Inst{19-16} = 0b0000; 3496199481Srdivacky let Inst{11-4} = 0b00000000; 3497218893Sdim let Inst{15-12} = Rd; 3498218893Sdim let Inst{3-0} = Rm; 3499198113Srdivacky} 3500226890Sdimdef MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), 3501226890Sdim DPSoRegImmFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", 3502263509Sdim [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP, 3503263509Sdim Sched<[WriteALU]> { 3504218893Sdim bits<4> Rd; 3505218893Sdim bits<12> shift; 3506203954Srdivacky let Inst{25} = 0; 3507218893Sdim let Inst{19-16} = 0b0000; 3508218893Sdim let Inst{15-12} = Rd; 3509226890Sdim let Inst{11-5} = shift{11-5}; 3510226890Sdim let Inst{4} = 0; 3511226890Sdim let Inst{3-0} = shift{3-0}; 3512203954Srdivacky} 3513226890Sdimdef MVNsr : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_reg:$shift), 3514226890Sdim DPSoRegRegFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", 3515263509Sdim [(set GPR:$Rd, (not so_reg_reg:$shift))]>, UnaryDP, 3516263509Sdim Sched<[WriteALU]> { 3517226890Sdim bits<4> Rd; 3518226890Sdim bits<12> shift; 3519226890Sdim let Inst{25} = 0; 3520226890Sdim let Inst{19-16} = 0b0000; 3521226890Sdim let Inst{15-12} = Rd; 3522226890Sdim let Inst{11-8} = shift{11-8}; 3523226890Sdim let Inst{7} = 0; 3524226890Sdim let Inst{6-5} = shift{6-5}; 3525226890Sdim let Inst{4} = 1; 3526226890Sdim let Inst{3-0} = shift{3-0}; 3527226890Sdim} 3528218893Sdimlet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 3529218893Sdimdef MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, 3530218893Sdim IIC_iMVNi, "mvn", "\t$Rd, $imm", 3531263509Sdim [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP, Sched<[WriteALU]> { 3532218893Sdim bits<4> Rd; 3533218893Sdim bits<12> imm; 3534218893Sdim let Inst{25} = 1; 3535218893Sdim let Inst{19-16} = 0b0000; 3536218893Sdim let Inst{15-12} = Rd; 3537218893Sdim let Inst{11-0} = imm; 3538198090Srdivacky} 3539193323Sed 3540193323Seddef : ARMPat<(and GPR:$src, so_imm_not:$imm), 3541193323Sed (BICri GPR:$src, so_imm_not:$imm)>; 3542193323Sed 3543193323Sed//===----------------------------------------------------------------------===// 3544193323Sed// Multiply Instructions. 3545193323Sed// 3546218893Sdimclass AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 3547218893Sdim string opc, string asm, list<dag> pattern> 3548218893Sdim : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 3549218893Sdim bits<4> Rd; 3550218893Sdim bits<4> Rm; 3551218893Sdim bits<4> Rn; 3552218893Sdim let Inst{19-16} = Rd; 3553218893Sdim let Inst{11-8} = Rm; 3554218893Sdim let Inst{3-0} = Rn; 3555218893Sdim} 3556218893Sdimclass AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 3557218893Sdim string opc, string asm, list<dag> pattern> 3558218893Sdim : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 3559218893Sdim bits<4> RdLo; 3560218893Sdim bits<4> RdHi; 3561218893Sdim bits<4> Rm; 3562218893Sdim bits<4> Rn; 3563218893Sdim let Inst{19-16} = RdHi; 3564218893Sdim let Inst{15-12} = RdLo; 3565218893Sdim let Inst{11-8} = Rm; 3566218893Sdim let Inst{3-0} = Rn; 3567218893Sdim} 3568245431Sdimclass AsMla1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 3569245431Sdim string opc, string asm, list<dag> pattern> 3570245431Sdim : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 3571245431Sdim bits<4> RdLo; 3572245431Sdim bits<4> RdHi; 3573245431Sdim bits<4> Rm; 3574245431Sdim bits<4> Rn; 3575245431Sdim let Inst{19-16} = RdHi; 3576245431Sdim let Inst{15-12} = RdLo; 3577245431Sdim let Inst{11-8} = Rm; 3578245431Sdim let Inst{3-0} = Rn; 3579245431Sdim} 3580193323Sed 3581224145Sdim// FIXME: The v5 pseudos are only necessary for the additional Constraint 3582224145Sdim// property. Remove them when it's possible to add those properties 3583245431Sdim// on an individual MachineInstr, not just an instruction description. 3584245431Sdimlet isCommutable = 1, TwoOperandAliasConstraint = "$Rn = $Rd" in { 3585245431Sdimdef MUL : AsMul1I32<0b0000000, (outs GPRnopc:$Rd), 3586245431Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm), 3587245431Sdim IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", 3588245431Sdim [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))]>, 3589245431Sdim Requires<[IsARM, HasV6]> { 3590221345Sdim let Inst{15-12} = 0b0000; 3591235633Sdim let Unpredictable{15-12} = 0b1111; 3592218893Sdim} 3593193323Sed 3594218893Sdimlet Constraints = "@earlyclobber $Rd" in 3595235633Sdimdef MULv5: ARMPseudoExpand<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm, 3596245431Sdim pred:$p, cc_out:$s), 3597245431Sdim 4, IIC_iMUL32, 3598245431Sdim [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))], 3599245431Sdim (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s)>, 3600245431Sdim Requires<[IsARM, NoV6, UseMulOps]>; 3601218893Sdim} 3602224145Sdim 3603218893Sdimdef MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3604245431Sdim IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra", 3605218893Sdim [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 3606245431Sdim Requires<[IsARM, HasV6, UseMulOps]> { 3607218893Sdim bits<4> Ra; 3608218893Sdim let Inst{15-12} = Ra; 3609218893Sdim} 3610198090Srdivacky 3611224145Sdimlet Constraints = "@earlyclobber $Rd" in 3612224145Sdimdef MLAv5: ARMPseudoExpand<(outs GPR:$Rd), 3613245431Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s), 3614245431Sdim 4, IIC_iMAC32, 3615224145Sdim [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))], 3616224145Sdim (MLA GPR:$Rd, GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s)>, 3617224145Sdim Requires<[IsARM, NoV6]>; 3618224145Sdim 3619218893Sdimdef MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3620218893Sdim IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra", 3621218893Sdim [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>, 3622245431Sdim Requires<[IsARM, HasV6T2, UseMulOps]> { 3623218893Sdim bits<4> Rd; 3624218893Sdim bits<4> Rm; 3625218893Sdim bits<4> Rn; 3626218893Sdim bits<4> Ra; 3627218893Sdim let Inst{19-16} = Rd; 3628218893Sdim let Inst{15-12} = Ra; 3629218893Sdim let Inst{11-8} = Rm; 3630218893Sdim let Inst{3-0} = Rn; 3631218893Sdim} 3632218893Sdim 3633193323Sed// Extra precision multiplies with low / high results 3634194178Sedlet neverHasSideEffects = 1 in { 3635195098Sedlet isCommutable = 1 in { 3636218893Sdimdef SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi), 3637224145Sdim (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 3638218893Sdim "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3639218893Sdim Requires<[IsARM, HasV6]>; 3640218893Sdim 3641218893Sdimdef UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi), 3642224145Sdim (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 3643218893Sdim "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3644218893Sdim Requires<[IsARM, HasV6]>; 3645218893Sdim 3646218893Sdimlet Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { 3647224145Sdimdef SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3648221345Sdim (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 3649224145Sdim 4, IIC_iMUL64, [], 3650224145Sdim (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 3651218893Sdim Requires<[IsARM, NoV6]>; 3652224145Sdim 3653224145Sdimdef UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3654221345Sdim (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 3655224145Sdim 4, IIC_iMUL64, [], 3656224145Sdim (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 3657218893Sdim Requires<[IsARM, NoV6]>; 3658218893Sdim} 3659224145Sdim} 3660193323Sed 3661224145Sdim// Multiply + accumulate 3662245431Sdimdef SMLAL : AsMla1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi), 3663245431Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64, 3664218893Sdim "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3665245431Sdim RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>; 3666245431Sdimdef UMLAL : AsMla1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi), 3667245431Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64, 3668218893Sdim "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3669245431Sdim RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>; 3670218893Sdim 3671218893Sdimdef UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), 3672218893Sdim (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, 3673218893Sdim "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3674218893Sdim Requires<[IsARM, HasV6]> { 3675218893Sdim bits<4> RdLo; 3676218893Sdim bits<4> RdHi; 3677218893Sdim bits<4> Rm; 3678218893Sdim bits<4> Rn; 3679226890Sdim let Inst{19-16} = RdHi; 3680226890Sdim let Inst{15-12} = RdLo; 3681218893Sdim let Inst{11-8} = Rm; 3682218893Sdim let Inst{3-0} = Rn; 3683218893Sdim} 3684224145Sdim 3685245431Sdimlet Constraints = "$RLo = $RdLo,$RHi = $RdHi" in { 3686224145Sdimdef SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3687245431Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s), 3688224145Sdim 4, IIC_iMAC64, [], 3689245431Sdim (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, 3690245431Sdim pred:$p, cc_out:$s)>, 3691224145Sdim Requires<[IsARM, NoV6]>; 3692224145Sdimdef UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3693245431Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s), 3694224145Sdim 4, IIC_iMAC64, [], 3695245431Sdim (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, 3696245431Sdim pred:$p, cc_out:$s)>, 3697224145Sdim Requires<[IsARM, NoV6]>; 3698245431Sdim} 3699245431Sdim 3700245431Sdimlet Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { 3701224145Sdimdef UMAALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 3702224145Sdim (ins GPR:$Rn, GPR:$Rm, pred:$p), 3703224145Sdim 4, IIC_iMAC64, [], 3704224145Sdim (UMAAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p)>, 3705224145Sdim Requires<[IsARM, NoV6]>; 3706224145Sdim} 3707224145Sdim 3708194178Sed} // neverHasSideEffects 3709193323Sed 3710193323Sed// Most significant word multiply 3711218893Sdimdef SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3712218893Sdim IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm", 3713218893Sdim [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>, 3714193323Sed Requires<[IsARM, HasV6]> { 3715193323Sed let Inst{15-12} = 0b1111; 3716193323Sed} 3717193323Sed 3718218893Sdimdef SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3719226890Sdim IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", []>, 3720204642Srdivacky Requires<[IsARM, HasV6]> { 3721204642Srdivacky let Inst{15-12} = 0b1111; 3722204642Srdivacky} 3723204642Srdivacky 3724218893Sdimdef SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd), 3725218893Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3726218893Sdim IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra", 3727218893Sdim [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 3728245431Sdim Requires<[IsARM, HasV6, UseMulOps]>; 3729193323Sed 3730218893Sdimdef SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd), 3731218893Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3732226890Sdim IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>, 3733218893Sdim Requires<[IsARM, HasV6]>; 3734193323Sed 3735218893Sdimdef SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd), 3736218893Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3737245431Sdim IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", []>, 3738245431Sdim Requires<[IsARM, HasV6, UseMulOps]>; 3739193323Sed 3740218893Sdimdef SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd), 3741218893Sdim (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 3742226890Sdim IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>, 3743218893Sdim Requires<[IsARM, HasV6]>; 3744204642Srdivacky 3745193323Sedmulticlass AI_smul<string opc, PatFrag opnode> { 3746218893Sdim def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3747218893Sdim IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm", 3748218893Sdim [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16), 3749218893Sdim (sext_inreg GPR:$Rm, i16)))]>, 3750218893Sdim Requires<[IsARM, HasV5TE]>; 3751193323Sed 3752218893Sdim def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3753218893Sdim IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm", 3754218893Sdim [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16), 3755218893Sdim (sra GPR:$Rm, (i32 16))))]>, 3756218893Sdim Requires<[IsARM, HasV5TE]>; 3757193323Sed 3758218893Sdim def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3759218893Sdim IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm", 3760218893Sdim [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)), 3761218893Sdim (sext_inreg GPR:$Rm, i16)))]>, 3762218893Sdim Requires<[IsARM, HasV5TE]>; 3763193323Sed 3764218893Sdim def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3765218893Sdim IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm", 3766218893Sdim [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)), 3767218893Sdim (sra GPR:$Rm, (i32 16))))]>, 3768218893Sdim Requires<[IsARM, HasV5TE]>; 3769193323Sed 3770218893Sdim def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3771218893Sdim IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm", 3772218893Sdim [(set GPR:$Rd, (sra (opnode GPR:$Rn, 3773218893Sdim (sext_inreg GPR:$Rm, i16)), (i32 16)))]>, 3774218893Sdim Requires<[IsARM, HasV5TE]>; 3775193323Sed 3776218893Sdim def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 3777218893Sdim IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm", 3778218893Sdim [(set GPR:$Rd, (sra (opnode GPR:$Rn, 3779218893Sdim (sra GPR:$Rm, (i32 16))), (i32 16)))]>, 3780218893Sdim Requires<[IsARM, HasV5TE]>; 3781193323Sed} 3782193323Sed 3783193323Sed 3784193323Sedmulticlass AI_smla<string opc, PatFrag opnode> { 3785226890Sdim let DecoderMethod = "DecodeSMLAInstruction" in { 3786226890Sdim def BB : AMulxyIa<0b0001000, 0b00, (outs GPRnopc:$Rd), 3787226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3788218893Sdim IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", 3789226890Sdim [(set GPRnopc:$Rd, (add GPR:$Ra, 3790226890Sdim (opnode (sext_inreg GPRnopc:$Rn, i16), 3791226890Sdim (sext_inreg GPRnopc:$Rm, i16))))]>, 3792245431Sdim Requires<[IsARM, HasV5TE, UseMulOps]>; 3793193323Sed 3794226890Sdim def BT : AMulxyIa<0b0001000, 0b10, (outs GPRnopc:$Rd), 3795226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3796218893Sdim IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", 3797226890Sdim [(set GPRnopc:$Rd, 3798226890Sdim (add GPR:$Ra, (opnode (sext_inreg GPRnopc:$Rn, i16), 3799226890Sdim (sra GPRnopc:$Rm, (i32 16)))))]>, 3800245431Sdim Requires<[IsARM, HasV5TE, UseMulOps]>; 3801193323Sed 3802226890Sdim def TB : AMulxyIa<0b0001000, 0b01, (outs GPRnopc:$Rd), 3803226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3804218893Sdim IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", 3805226890Sdim [(set GPRnopc:$Rd, 3806226890Sdim (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)), 3807226890Sdim (sext_inreg GPRnopc:$Rm, i16))))]>, 3808245431Sdim Requires<[IsARM, HasV5TE, UseMulOps]>; 3809193323Sed 3810226890Sdim def TT : AMulxyIa<0b0001000, 0b11, (outs GPRnopc:$Rd), 3811226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3812218893Sdim IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", 3813226890Sdim [(set GPRnopc:$Rd, 3814226890Sdim (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)), 3815226890Sdim (sra GPRnopc:$Rm, (i32 16)))))]>, 3816245431Sdim Requires<[IsARM, HasV5TE, UseMulOps]>; 3817193323Sed 3818226890Sdim def WB : AMulxyIa<0b0001001, 0b00, (outs GPRnopc:$Rd), 3819226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3820218893Sdim IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", 3821226890Sdim [(set GPRnopc:$Rd, 3822226890Sdim (add GPR:$Ra, (sra (opnode GPRnopc:$Rn, 3823226890Sdim (sext_inreg GPRnopc:$Rm, i16)), (i32 16))))]>, 3824245431Sdim Requires<[IsARM, HasV5TE, UseMulOps]>; 3825193323Sed 3826226890Sdim def WT : AMulxyIa<0b0001001, 0b10, (outs GPRnopc:$Rd), 3827226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3828218893Sdim IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", 3829226890Sdim [(set GPRnopc:$Rd, 3830226890Sdim (add GPR:$Ra, (sra (opnode GPRnopc:$Rn, 3831226890Sdim (sra GPRnopc:$Rm, (i32 16))), (i32 16))))]>, 3832245431Sdim Requires<[IsARM, HasV5TE, UseMulOps]>; 3833226890Sdim } 3834193323Sed} 3835193323Sed 3836193323Seddefm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 3837193323Seddefm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 3838193323Sed 3839226890Sdim// Halfword multiply accumulate long: SMLAL<x><y>. 3840226890Sdimdef SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3841226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm), 3842226890Sdim IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3843218893Sdim Requires<[IsARM, HasV5TE]>; 3844203954Srdivacky 3845226890Sdimdef SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3846226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm), 3847226890Sdim IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3848218893Sdim Requires<[IsARM, HasV5TE]>; 3849203954Srdivacky 3850226890Sdimdef SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3851226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm), 3852226890Sdim IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3853218893Sdim Requires<[IsARM, HasV5TE]>; 3854203954Srdivacky 3855226890Sdimdef SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3856226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm), 3857226890Sdim IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 3858218893Sdim Requires<[IsARM, HasV5TE]>; 3859203954Srdivacky 3860226890Sdim// Helper class for AI_smld. 3861218893Sdimclass AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops, 3862218893Sdim InstrItinClass itin, string opc, string asm> 3863204642Srdivacky : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> { 3864218893Sdim bits<4> Rn; 3865218893Sdim bits<4> Rm; 3866226890Sdim let Inst{27-23} = 0b01110; 3867226890Sdim let Inst{22} = long; 3868204642Srdivacky let Inst{21-20} = 0b00; 3869218893Sdim let Inst{11-8} = Rm; 3870226890Sdim let Inst{7} = 0; 3871226890Sdim let Inst{6} = sub; 3872226890Sdim let Inst{5} = swap; 3873226890Sdim let Inst{4} = 1; 3874218893Sdim let Inst{3-0} = Rn; 3875204642Srdivacky} 3876218893Sdimclass AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops, 3877218893Sdim InstrItinClass itin, string opc, string asm> 3878218893Sdim : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 3879218893Sdim bits<4> Rd; 3880218893Sdim let Inst{15-12} = 0b1111; 3881218893Sdim let Inst{19-16} = Rd; 3882218893Sdim} 3883218893Sdimclass AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops, 3884218893Sdim InstrItinClass itin, string opc, string asm> 3885218893Sdim : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 3886218893Sdim bits<4> Ra; 3887226890Sdim bits<4> Rd; 3888226890Sdim let Inst{19-16} = Rd; 3889218893Sdim let Inst{15-12} = Ra; 3890218893Sdim} 3891218893Sdimclass AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops, 3892218893Sdim InstrItinClass itin, string opc, string asm> 3893218893Sdim : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 3894218893Sdim bits<4> RdLo; 3895218893Sdim bits<4> RdHi; 3896218893Sdim let Inst{19-16} = RdHi; 3897218893Sdim let Inst{15-12} = RdLo; 3898218893Sdim} 3899193323Sed 3900204642Srdivackymulticlass AI_smld<bit sub, string opc> { 3901204642Srdivacky 3902226890Sdim def D : AMulDualIa<0, sub, 0, (outs GPRnopc:$Rd), 3903226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3904218893Sdim NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">; 3905204642Srdivacky 3906226890Sdim def DX: AMulDualIa<0, sub, 1, (outs GPRnopc:$Rd), 3907226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 3908218893Sdim NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">; 3909204642Srdivacky 3910226890Sdim def LD: AMulDualI64<1, sub, 0, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3911226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary, 3912218893Sdim !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">; 3913204642Srdivacky 3914226890Sdim def LDX : AMulDualI64<1, sub, 1, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 3915226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary, 3916218893Sdim !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">; 3917204642Srdivacky 3918204642Srdivacky} 3919204642Srdivacky 3920204642Srdivackydefm SMLA : AI_smld<0, "smla">; 3921204642Srdivackydefm SMLS : AI_smld<1, "smls">; 3922204642Srdivacky 3923204642Srdivackymulticlass AI_sdml<bit sub, string opc> { 3924204642Srdivacky 3925226890Sdim def D:AMulDualI<0, sub, 0, (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), 3926226890Sdim NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">; 3927226890Sdim def DX:AMulDualI<0, sub, 1, (outs GPRnopc:$Rd),(ins GPRnopc:$Rn, GPRnopc:$Rm), 3928226890Sdim NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">; 3929204642Srdivacky} 3930204642Srdivacky 3931204642Srdivackydefm SMUA : AI_sdml<0, "smua">; 3932204642Srdivackydefm SMUS : AI_sdml<1, "smus">; 3933204642Srdivacky 3934193323Sed//===----------------------------------------------------------------------===// 3935245431Sdim// Division Instructions (ARMv7-A with virtualization extension) 3936245431Sdim// 3937245431Sdimdef SDIV : ADivA1I<0b001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iDIV, 3938245431Sdim "sdiv", "\t$Rd, $Rn, $Rm", 3939245431Sdim [(set GPR:$Rd, (sdiv GPR:$Rn, GPR:$Rm))]>, 3940245431Sdim Requires<[IsARM, HasDivideInARM]>; 3941245431Sdim 3942245431Sdimdef UDIV : ADivA1I<0b011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iDIV, 3943245431Sdim "udiv", "\t$Rd, $Rn, $Rm", 3944245431Sdim [(set GPR:$Rd, (udiv GPR:$Rn, GPR:$Rm))]>, 3945245431Sdim Requires<[IsARM, HasDivideInARM]>; 3946245431Sdim 3947245431Sdim//===----------------------------------------------------------------------===// 3948193323Sed// Misc. Arithmetic Instructions. 3949193323Sed// 3950193323Sed 3951218893Sdimdef CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm), 3952218893Sdim IIC_iUNAr, "clz", "\t$Rd, $Rm", 3953252723Sdim [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>, 3954252723Sdim Sched<[WriteALU]>; 3955193323Sed 3956218893Sdimdef RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 3957218893Sdim IIC_iUNAr, "rbit", "\t$Rd, $Rm", 3958218893Sdim [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>, 3959252723Sdim Requires<[IsARM, HasV6T2]>, 3960252723Sdim Sched<[WriteALU]>; 3961202878Srdivacky 3962218893Sdimdef REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 3963218893Sdim IIC_iUNAr, "rev", "\t$Rd, $Rm", 3964252723Sdim [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>, 3965252723Sdim Sched<[WriteALU]>; 3966193323Sed 3967224145Sdimlet AddedComplexity = 5 in 3968218893Sdimdef REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 3969218893Sdim IIC_iUNAr, "rev16", "\t$Rd, $Rm", 3970224145Sdim [(set GPR:$Rd, (rotr (bswap GPR:$Rm), (i32 16)))]>, 3971252723Sdim Requires<[IsARM, HasV6]>, 3972252723Sdim Sched<[WriteALU]>; 3973193323Sed 3974224145Sdimlet AddedComplexity = 5 in 3975218893Sdimdef REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 3976218893Sdim IIC_iUNAr, "revsh", "\t$Rd, $Rm", 3977224145Sdim [(set GPR:$Rd, (sra (bswap GPR:$Rm), (i32 16)))]>, 3978252723Sdim Requires<[IsARM, HasV6]>, 3979252723Sdim Sched<[WriteALU]>; 3980193323Sed 3981224145Sdimdef : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)), 3982224145Sdim (and (srl GPR:$Rm, (i32 8)), 0xFF)), 3983221345Sdim (REVSH GPR:$Rm)>; 3984221345Sdim 3985226890Sdimdef PKHBT : APKHI<0b01101000, 0, (outs GPRnopc:$Rd), 3986226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_lsl_amt:$sh), 3987218893Sdim IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", 3988226890Sdim [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF), 3989226890Sdim (and (shl GPRnopc:$Rm, pkh_lsl_amt:$sh), 3990226890Sdim 0xFFFF0000)))]>, 3991252723Sdim Requires<[IsARM, HasV6]>, 3992252723Sdim Sched<[WriteALUsi, ReadALU]>; 3993193323Sed 3994193323Sed// Alternate cases for PKHBT where identities eliminate some nodes. 3995226890Sdimdef : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (and GPRnopc:$Rm, 0xFFFF0000)), 3996226890Sdim (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, 0)>; 3997226890Sdimdef : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (shl GPRnopc:$Rm, imm16_31:$sh)), 3998226890Sdim (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, imm16_31:$sh)>; 3999193323Sed 4000212904Sdim// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 4001212904Sdim// will match the pattern below. 4002226890Sdimdef PKHTB : APKHI<0b01101000, 1, (outs GPRnopc:$Rd), 4003226890Sdim (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_asr_amt:$sh), 4004218893Sdim IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh", 4005226890Sdim [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF0000), 4006226890Sdim (and (sra GPRnopc:$Rm, pkh_asr_amt:$sh), 4007226890Sdim 0xFFFF)))]>, 4008252723Sdim Requires<[IsARM, HasV6]>, 4009252723Sdim Sched<[WriteALUsi, ReadALU]>; 4010193323Sed 4011193323Sed// Alternate cases for PKHTB where identities eliminate some nodes. Note that 4012193323Sed// a shift amount of 0 is *not legal* here, it is PKHBT instead. 4013263509Sdim// We also can not replace a srl (17..31) by an arithmetic shift we would use in 4014263509Sdim// pkhtb src1, src2, asr (17..31). 4015226890Sdimdef : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 4016263509Sdim (srl GPRnopc:$src2, imm16:$sh)), 4017263509Sdim (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16:$sh)>; 4018263509Sdimdef : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 4019263509Sdim (sra GPRnopc:$src2, imm16_31:$sh)), 4020226890Sdim (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16_31:$sh)>; 4021226890Sdimdef : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 4022226890Sdim (and (srl GPRnopc:$src2, imm1_15:$sh), 0xFFFF)), 4023226890Sdim (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm1_15:$sh)>; 4024193323Sed 4025193323Sed//===----------------------------------------------------------------------===// 4026263509Sdim// CRC Instructions 4027263509Sdim// 4028263509Sdim// Polynomials: 4029263509Sdim// + CRC32{B,H,W} 0x04C11DB7 4030263509Sdim// + CRC32C{B,H,W} 0x1EDC6F41 4031263509Sdim// 4032263509Sdim 4033263509Sdimclass AI_crc32<bit C, bits<2> sz, string suffix, SDPatternOperator builtin> 4034263509Sdim : AInoP<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), MiscFrm, NoItinerary, 4035263509Sdim !strconcat("crc32", suffix), "\t$Rd, $Rn, $Rm", 4036263509Sdim [(set GPRnopc:$Rd, (builtin GPRnopc:$Rn, GPRnopc:$Rm))]>, 4037263509Sdim Requires<[IsARM, HasV8, HasCRC]> { 4038263509Sdim bits<4> Rd; 4039263509Sdim bits<4> Rn; 4040263509Sdim bits<4> Rm; 4041263509Sdim 4042263509Sdim let Inst{31-28} = 0b1110; 4043263509Sdim let Inst{27-23} = 0b00010; 4044263509Sdim let Inst{22-21} = sz; 4045263509Sdim let Inst{20} = 0; 4046263509Sdim let Inst{19-16} = Rn; 4047263509Sdim let Inst{15-12} = Rd; 4048263509Sdim let Inst{11-10} = 0b00; 4049263509Sdim let Inst{9} = C; 4050263509Sdim let Inst{8} = 0; 4051263509Sdim let Inst{7-4} = 0b0100; 4052263509Sdim let Inst{3-0} = Rm; 4053263509Sdim 4054263509Sdim let Unpredictable{11-8} = 0b1101; 4055263509Sdim} 4056263509Sdim 4057263509Sdimdef CRC32B : AI_crc32<0, 0b00, "b", int_arm_crc32b>; 4058263509Sdimdef CRC32CB : AI_crc32<1, 0b00, "cb", int_arm_crc32cb>; 4059263509Sdimdef CRC32H : AI_crc32<0, 0b01, "h", int_arm_crc32h>; 4060263509Sdimdef CRC32CH : AI_crc32<1, 0b01, "ch", int_arm_crc32ch>; 4061263509Sdimdef CRC32W : AI_crc32<0, 0b10, "w", int_arm_crc32w>; 4062263509Sdimdef CRC32CW : AI_crc32<1, 0b10, "cw", int_arm_crc32cw>; 4063263509Sdim 4064263509Sdim//===----------------------------------------------------------------------===// 4065193323Sed// Comparison Instructions... 4066193323Sed// 4067193323Sed 4068193323Seddefm CMP : AI1_cmp_irs<0b1010, "cmp", 4069218893Sdim IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, 4070193323Sed BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 4071212904Sdim 4072218893Sdim// ARMcmpZ can re-use the above instruction definitions. 4073218893Sdimdef : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm), 4074218893Sdim (CMPri GPR:$src, so_imm:$imm)>; 4075218893Sdimdef : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs), 4076218893Sdim (CMPrr GPR:$src, GPR:$rhs)>; 4077226890Sdimdef : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs), 4078226890Sdim (CMPrsi GPR:$src, so_reg_imm:$rhs)>; 4079226890Sdimdef : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs), 4080226890Sdim (CMPrsr GPR:$src, so_reg_reg:$rhs)>; 4081218893Sdim 4082245431Sdim// CMN register-integer 4083245431Sdimlet isCompare = 1, Defs = [CPSR] in { 4084245431Sdimdef CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, IIC_iCMPi, 4085245431Sdim "cmn", "\t$Rn, $imm", 4086263509Sdim [(ARMcmn GPR:$Rn, so_imm:$imm)]>, 4087263509Sdim Sched<[WriteCMP, ReadALU]> { 4088245431Sdim bits<4> Rn; 4089245431Sdim bits<12> imm; 4090245431Sdim let Inst{25} = 1; 4091245431Sdim let Inst{20} = 1; 4092245431Sdim let Inst{19-16} = Rn; 4093245431Sdim let Inst{15-12} = 0b0000; 4094245431Sdim let Inst{11-0} = imm; 4095193323Sed 4096245431Sdim let Unpredictable{15-12} = 0b1111; 4097245431Sdim} 4098245431Sdim 4099245431Sdim// CMN register-register/shift 4100245431Sdimdef CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr, 4101245431Sdim "cmn", "\t$Rn, $Rm", 4102245431Sdim [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 4103263509Sdim GPR:$Rn, GPR:$Rm)]>, Sched<[WriteCMP, ReadALU, ReadALU]> { 4104245431Sdim bits<4> Rn; 4105245431Sdim bits<4> Rm; 4106245431Sdim let isCommutable = 1; 4107245431Sdim let Inst{25} = 0; 4108245431Sdim let Inst{20} = 1; 4109245431Sdim let Inst{19-16} = Rn; 4110245431Sdim let Inst{15-12} = 0b0000; 4111245431Sdim let Inst{11-4} = 0b00000000; 4112245431Sdim let Inst{3-0} = Rm; 4113245431Sdim 4114245431Sdim let Unpredictable{15-12} = 0b1111; 4115245431Sdim} 4116245431Sdim 4117245431Sdimdef CMNzrsi : AI1<0b1011, (outs), 4118245431Sdim (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr, 4119245431Sdim "cmn", "\t$Rn, $shift", 4120245431Sdim [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 4121263509Sdim GPR:$Rn, so_reg_imm:$shift)]>, 4122263509Sdim Sched<[WriteCMPsi, ReadALU]> { 4123245431Sdim bits<4> Rn; 4124245431Sdim bits<12> shift; 4125245431Sdim let Inst{25} = 0; 4126245431Sdim let Inst{20} = 1; 4127245431Sdim let Inst{19-16} = Rn; 4128245431Sdim let Inst{15-12} = 0b0000; 4129245431Sdim let Inst{11-5} = shift{11-5}; 4130245431Sdim let Inst{4} = 0; 4131245431Sdim let Inst{3-0} = shift{3-0}; 4132245431Sdim 4133245431Sdim let Unpredictable{15-12} = 0b1111; 4134245431Sdim} 4135245431Sdim 4136245431Sdimdef CMNzrsr : AI1<0b1011, (outs), 4137245431Sdim (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr, 4138245431Sdim "cmn", "\t$Rn, $shift", 4139245431Sdim [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 4140263509Sdim GPRnopc:$Rn, so_reg_reg:$shift)]>, 4141263509Sdim Sched<[WriteCMPsr, ReadALU]> { 4142245431Sdim bits<4> Rn; 4143245431Sdim bits<12> shift; 4144245431Sdim let Inst{25} = 0; 4145245431Sdim let Inst{20} = 1; 4146245431Sdim let Inst{19-16} = Rn; 4147245431Sdim let Inst{15-12} = 0b0000; 4148245431Sdim let Inst{11-8} = shift{11-8}; 4149245431Sdim let Inst{7} = 0; 4150245431Sdim let Inst{6-5} = shift{6-5}; 4151245431Sdim let Inst{4} = 1; 4152245431Sdim let Inst{3-0} = shift{3-0}; 4153245431Sdim 4154245431Sdim let Unpredictable{15-12} = 0b1111; 4155245431Sdim} 4156245431Sdim 4157245431Sdim} 4158245431Sdim 4159245431Sdimdef : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), 4160245431Sdim (CMNri GPR:$src, so_imm_neg:$imm)>; 4161245431Sdim 4162245431Sdimdef : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm), 4163245431Sdim (CMNri GPR:$src, so_imm_neg:$imm)>; 4164245431Sdim 4165193323Sed// Note that TST/TEQ don't set all the same flags that CMP does! 4166193323Seddefm TST : AI1_cmp_irs<0b1000, "tst", 4167218893Sdim IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 4168218893Sdim BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>; 4169193323Seddefm TEQ : AI1_cmp_irs<0b1001, "teq", 4170218893Sdim IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 4171218893Sdim BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>; 4172193323Sed 4173210299Sed// Pseudo i64 compares for some floating point compares. 4174210299Sedlet usesCustomInserter = 1, isBranch = 1, isTerminator = 1, 4175210299Sed Defs = [CPSR] in { 4176210299Seddef BCCi64 : PseudoInst<(outs), 4177212904Sdim (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst), 4178212904Sdim IIC_Br, 4179263509Sdim [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>, 4180263509Sdim Sched<[WriteBr]>; 4181193323Sed 4182210299Seddef BCCZi64 : PseudoInst<(outs), 4183218893Sdim (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, 4184263509Sdim [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>, 4185263509Sdim Sched<[WriteBr]>; 4186210299Sed} // usesCustomInserter 4187210299Sed 4188210299Sed 4189193323Sed// Conditional moves 4190208599Srdivackylet neverHasSideEffects = 1 in { 4191235633Sdim 4192245431Sdimlet isCommutable = 1, isSelect = 1 in 4193263509Sdimdef MOVCCr : ARMPseudoInst<(outs GPR:$Rd), 4194263509Sdim (ins GPR:$false, GPR:$Rm, cmovpred:$p), 4195224145Sdim 4, IIC_iCMOVr, 4196263509Sdim [(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, 4197263509Sdim cmovpred:$p))]>, 4198263509Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 4199235633Sdim 4200226890Sdimdef MOVCCsi : ARMPseudoInst<(outs GPR:$Rd), 4201263509Sdim (ins GPR:$false, so_reg_imm:$shift, cmovpred:$p), 4202263509Sdim 4, IIC_iCMOVsr, 4203263509Sdim [(set GPR:$Rd, 4204263509Sdim (ARMcmov GPR:$false, so_reg_imm:$shift, 4205263509Sdim cmovpred:$p))]>, 4206263509Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 4207226890Sdimdef MOVCCsr : ARMPseudoInst<(outs GPR:$Rd), 4208263509Sdim (ins GPR:$false, so_reg_reg:$shift, cmovpred:$p), 4209226890Sdim 4, IIC_iCMOVsr, 4210263509Sdim [(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift, 4211263509Sdim cmovpred:$p))]>, 4212263509Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 4213193323Sed 4214226890Sdim 4215218893Sdimlet isMoveImm = 1 in 4216263509Sdimdef MOVCCi16 4217263509Sdim : ARMPseudoInst<(outs GPR:$Rd), 4218263509Sdim (ins GPR:$false, imm0_65535_expr:$imm, cmovpred:$p), 4219263509Sdim 4, IIC_iMOVi, 4220263509Sdim [(set GPR:$Rd, (ARMcmov GPR:$false, imm0_65535:$imm, 4221263509Sdim cmovpred:$p))]>, 4222263509Sdim RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>, 4223263509Sdim Sched<[WriteALU]>; 4224218893Sdim 4225218893Sdimlet isMoveImm = 1 in 4226221345Sdimdef MOVCCi : ARMPseudoInst<(outs GPR:$Rd), 4227263509Sdim (ins GPR:$false, so_imm:$imm, cmovpred:$p), 4228224145Sdim 4, IIC_iCMOVi, 4229263509Sdim [(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, 4230263509Sdim cmovpred:$p))]>, 4231263509Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 4232218893Sdim 4233218893Sdim// Two instruction predicate mov immediate. 4234218893Sdimlet isMoveImm = 1 in 4235263509Sdimdef MOVCCi32imm 4236263509Sdim : ARMPseudoInst<(outs GPR:$Rd), 4237263509Sdim (ins GPR:$false, i32imm:$src, cmovpred:$p), 4238263509Sdim 8, IIC_iCMOVix2, 4239263509Sdim [(set GPR:$Rd, (ARMcmov GPR:$false, imm:$src, 4240263509Sdim cmovpred:$p))]>, 4241263509Sdim RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>; 4242218893Sdim 4243218893Sdimlet isMoveImm = 1 in 4244221345Sdimdef MVNCCi : ARMPseudoInst<(outs GPR:$Rd), 4245263509Sdim (ins GPR:$false, so_imm:$imm, cmovpred:$p), 4246224145Sdim 4, IIC_iCMOVi, 4247263509Sdim [(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, 4248263509Sdim cmovpred:$p))]>, 4249263509Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 4250235633Sdim 4251208599Srdivacky} // neverHasSideEffects 4252193323Sed 4253235633Sdim 4254200581Srdivacky//===----------------------------------------------------------------------===// 4255200581Srdivacky// Atomic operations intrinsics 4256200581Srdivacky// 4257193323Sed 4258226890Sdimdef MemBarrierOptOperand : AsmOperandClass { 4259226890Sdim let Name = "MemBarrierOpt"; 4260226890Sdim let ParserMethod = "parseMemBarrierOptOperand"; 4261226890Sdim} 4262218893Sdimdef memb_opt : Operand<i32> { 4263218893Sdim let PrintMethod = "printMemBOption"; 4264218893Sdim let ParserMatchClass = MemBarrierOptOperand; 4265226890Sdim let DecoderMethod = "DecodeMemBarrierOption"; 4266218893Sdim} 4267218893Sdim 4268263509Sdimdef InstSyncBarrierOptOperand : AsmOperandClass { 4269263509Sdim let Name = "InstSyncBarrierOpt"; 4270263509Sdim let ParserMethod = "parseInstSyncBarrierOptOperand"; 4271263509Sdim} 4272263509Sdimdef instsyncb_opt : Operand<i32> { 4273263509Sdim let PrintMethod = "printInstSyncBOption"; 4274263509Sdim let ParserMatchClass = InstSyncBarrierOptOperand; 4275263509Sdim let DecoderMethod = "DecodeInstSyncBarrierOption"; 4276263509Sdim} 4277263509Sdim 4278200581Srdivacky// memory barriers protect the atomic sequences 4279200581Srdivackylet hasSideEffects = 1 in { 4280218893Sdimdef DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 4281263509Sdim "dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>, 4282218893Sdim Requires<[IsARM, HasDB]> { 4283218893Sdim bits<4> opt; 4284200581Srdivacky let Inst{31-4} = 0xf57ff05; 4285218893Sdim let Inst{3-0} = opt; 4286200581Srdivacky} 4287200581Srdivacky} 4288200581Srdivacky 4289218893Sdimdef DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 4290263509Sdim "dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>, 4291218893Sdim Requires<[IsARM, HasDB]> { 4292218893Sdim bits<4> opt; 4293218893Sdim let Inst{31-4} = 0xf57ff04; 4294218893Sdim let Inst{3-0} = opt; 4295204642Srdivacky} 4296204642Srdivacky 4297224145Sdim// ISB has only full system option 4298263509Sdimdef ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary, 4299224145Sdim "isb", "\t$opt", []>, 4300218893Sdim Requires<[IsARM, HasDB]> { 4301224145Sdim bits<4> opt; 4302212904Sdim let Inst{31-4} = 0xf57ff06; 4303224145Sdim let Inst{3-0} = opt; 4304204642Srdivacky} 4305204642Srdivacky 4306263509Sdimlet usesCustomInserter = 1, Defs = [CPSR] in { 4307263509Sdim 4308235633Sdim// Pseudo instruction that combines movs + predicated rsbmi 4309226890Sdim// to implement integer ABS 4310263509Sdim def ABS : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$src), 8, NoItinerary, []>; 4311226890Sdim 4312263509Sdim// Atomic pseudo-insts which will be lowered to ldrex/strex loops. 4313263509Sdim// (64-bit pseudos use a hand-written selection code). 4314263509Sdim let mayLoad = 1, mayStore = 1 in { 4315200581Srdivacky def ATOMIC_LOAD_ADD_I8 : PseudoInst< 4316263509Sdim (outs GPR:$dst), 4317263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4318263509Sdim NoItinerary, []>; 4319200581Srdivacky def ATOMIC_LOAD_SUB_I8 : PseudoInst< 4320263509Sdim (outs GPR:$dst), 4321263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4322263509Sdim NoItinerary, []>; 4323200581Srdivacky def ATOMIC_LOAD_AND_I8 : PseudoInst< 4324263509Sdim (outs GPR:$dst), 4325263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4326263509Sdim NoItinerary, []>; 4327200581Srdivacky def ATOMIC_LOAD_OR_I8 : PseudoInst< 4328263509Sdim (outs GPR:$dst), 4329263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4330263509Sdim NoItinerary, []>; 4331200581Srdivacky def ATOMIC_LOAD_XOR_I8 : PseudoInst< 4332263509Sdim (outs GPR:$dst), 4333263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4334263509Sdim NoItinerary, []>; 4335200581Srdivacky def ATOMIC_LOAD_NAND_I8 : PseudoInst< 4336263509Sdim (outs GPR:$dst), 4337263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4338263509Sdim NoItinerary, []>; 4339221345Sdim def ATOMIC_LOAD_MIN_I8 : PseudoInst< 4340263509Sdim (outs GPR:$dst), 4341263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4342263509Sdim NoItinerary, []>; 4343221345Sdim def ATOMIC_LOAD_MAX_I8 : PseudoInst< 4344263509Sdim (outs GPR:$dst), 4345263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4346263509Sdim NoItinerary, []>; 4347221345Sdim def ATOMIC_LOAD_UMIN_I8 : PseudoInst< 4348263509Sdim (outs GPR:$dst), 4349263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4350263509Sdim NoItinerary, []>; 4351221345Sdim def ATOMIC_LOAD_UMAX_I8 : PseudoInst< 4352263509Sdim (outs GPR:$dst), 4353263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4354263509Sdim NoItinerary, []>; 4355263509Sdim def ATOMIC_SWAP_I8 : PseudoInst< 4356263509Sdim (outs GPR:$dst), 4357263509Sdim (ins GPR:$ptr, GPR:$new, i32imm:$ordering), 4358263509Sdim NoItinerary, []>; 4359263509Sdim def ATOMIC_CMP_SWAP_I8 : PseudoInst< 4360263509Sdim (outs GPR:$dst), 4361263509Sdim (ins GPR:$ptr, GPR:$old, GPR:$new, i32imm:$ordering), 4362263509Sdim NoItinerary, []>; 4363200581Srdivacky def ATOMIC_LOAD_ADD_I16 : PseudoInst< 4364263509Sdim (outs GPR:$dst), 4365263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4366263509Sdim NoItinerary, []>; 4367200581Srdivacky def ATOMIC_LOAD_SUB_I16 : PseudoInst< 4368263509Sdim (outs GPR:$dst), 4369263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4370263509Sdim NoItinerary, []>; 4371200581Srdivacky def ATOMIC_LOAD_AND_I16 : PseudoInst< 4372263509Sdim (outs GPR:$dst), 4373263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4374263509Sdim NoItinerary, []>; 4375200581Srdivacky def ATOMIC_LOAD_OR_I16 : PseudoInst< 4376263509Sdim (outs GPR:$dst), 4377263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4378263509Sdim NoItinerary, []>; 4379200581Srdivacky def ATOMIC_LOAD_XOR_I16 : PseudoInst< 4380263509Sdim (outs GPR:$dst), 4381263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4382263509Sdim NoItinerary, []>; 4383200581Srdivacky def ATOMIC_LOAD_NAND_I16 : PseudoInst< 4384263509Sdim (outs GPR:$dst), 4385263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4386263509Sdim NoItinerary, []>; 4387221345Sdim def ATOMIC_LOAD_MIN_I16 : PseudoInst< 4388263509Sdim (outs GPR:$dst), 4389263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4390263509Sdim NoItinerary, []>; 4391221345Sdim def ATOMIC_LOAD_MAX_I16 : PseudoInst< 4392263509Sdim (outs GPR:$dst), 4393263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4394263509Sdim NoItinerary, []>; 4395221345Sdim def ATOMIC_LOAD_UMIN_I16 : PseudoInst< 4396263509Sdim (outs GPR:$dst), 4397263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4398263509Sdim NoItinerary, []>; 4399221345Sdim def ATOMIC_LOAD_UMAX_I16 : PseudoInst< 4400263509Sdim (outs GPR:$dst), 4401263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4402263509Sdim NoItinerary, []>; 4403263509Sdim def ATOMIC_SWAP_I16 : PseudoInst< 4404263509Sdim (outs GPR:$dst), 4405263509Sdim (ins GPR:$ptr, GPR:$new, i32imm:$ordering), 4406263509Sdim NoItinerary, []>; 4407263509Sdim def ATOMIC_CMP_SWAP_I16 : PseudoInst< 4408263509Sdim (outs GPR:$dst), 4409263509Sdim (ins GPR:$ptr, GPR:$old, GPR:$new, i32imm:$ordering), 4410263509Sdim NoItinerary, []>; 4411200581Srdivacky def ATOMIC_LOAD_ADD_I32 : PseudoInst< 4412263509Sdim (outs GPR:$dst), 4413263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4414263509Sdim NoItinerary, []>; 4415200581Srdivacky def ATOMIC_LOAD_SUB_I32 : PseudoInst< 4416263509Sdim (outs GPR:$dst), 4417263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4418263509Sdim NoItinerary, []>; 4419200581Srdivacky def ATOMIC_LOAD_AND_I32 : PseudoInst< 4420263509Sdim (outs GPR:$dst), 4421263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4422263509Sdim NoItinerary, []>; 4423200581Srdivacky def ATOMIC_LOAD_OR_I32 : PseudoInst< 4424263509Sdim (outs GPR:$dst), 4425263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4426263509Sdim NoItinerary, []>; 4427200581Srdivacky def ATOMIC_LOAD_XOR_I32 : PseudoInst< 4428263509Sdim (outs GPR:$dst), 4429263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4430263509Sdim NoItinerary, []>; 4431200581Srdivacky def ATOMIC_LOAD_NAND_I32 : PseudoInst< 4432263509Sdim (outs GPR:$dst), 4433263509Sdim (ins GPR:$ptr, GPR:$incr, i32imm:$ordering), 4434263509Sdim NoItinerary, []>; 4435221345Sdim def ATOMIC_LOAD_MIN_I32 : PseudoInst< 4436263509Sdim (outs GPR:$dst), 4437263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4438263509Sdim NoItinerary, []>; 4439221345Sdim def ATOMIC_LOAD_MAX_I32 : PseudoInst< 4440263509Sdim (outs GPR:$dst), 4441263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4442263509Sdim NoItinerary, []>; 4443221345Sdim def ATOMIC_LOAD_UMIN_I32 : PseudoInst< 4444263509Sdim (outs GPR:$dst), 4445263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4446263509Sdim NoItinerary, []>; 4447221345Sdim def ATOMIC_LOAD_UMAX_I32 : PseudoInst< 4448263509Sdim (outs GPR:$dst), 4449263509Sdim (ins GPR:$ptr, GPR:$val, i32imm:$ordering), 4450263509Sdim NoItinerary, []>; 4451200581Srdivacky def ATOMIC_SWAP_I32 : PseudoInst< 4452263509Sdim (outs GPR:$dst), 4453263509Sdim (ins GPR:$ptr, GPR:$new, i32imm:$ordering), 4454263509Sdim NoItinerary, []>; 4455200581Srdivacky def ATOMIC_CMP_SWAP_I32 : PseudoInst< 4456263509Sdim (outs GPR:$dst), 4457263509Sdim (ins GPR:$ptr, GPR:$old, GPR:$new, i32imm:$ordering), 4458263509Sdim NoItinerary, []>; 4459263509Sdim def ATOMIC_LOAD_ADD_I64 : PseudoInst< 4460263509Sdim (outs GPR:$dst1, GPR:$dst2), 4461263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4462263509Sdim NoItinerary, []>; 4463263509Sdim def ATOMIC_LOAD_SUB_I64 : PseudoInst< 4464263509Sdim (outs GPR:$dst1, GPR:$dst2), 4465263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4466263509Sdim NoItinerary, []>; 4467263509Sdim def ATOMIC_LOAD_AND_I64 : PseudoInst< 4468263509Sdim (outs GPR:$dst1, GPR:$dst2), 4469263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4470263509Sdim NoItinerary, []>; 4471263509Sdim def ATOMIC_LOAD_OR_I64 : PseudoInst< 4472263509Sdim (outs GPR:$dst1, GPR:$dst2), 4473263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4474263509Sdim NoItinerary, []>; 4475263509Sdim def ATOMIC_LOAD_XOR_I64 : PseudoInst< 4476263509Sdim (outs GPR:$dst1, GPR:$dst2), 4477263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4478263509Sdim NoItinerary, []>; 4479263509Sdim def ATOMIC_LOAD_NAND_I64 : PseudoInst< 4480263509Sdim (outs GPR:$dst1, GPR:$dst2), 4481263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4482263509Sdim NoItinerary, []>; 4483263509Sdim def ATOMIC_LOAD_MIN_I64 : PseudoInst< 4484263509Sdim (outs GPR:$dst1, GPR:$dst2), 4485263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4486263509Sdim NoItinerary, []>; 4487263509Sdim def ATOMIC_LOAD_MAX_I64 : PseudoInst< 4488263509Sdim (outs GPR:$dst1, GPR:$dst2), 4489263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4490263509Sdim NoItinerary, []>; 4491263509Sdim def ATOMIC_LOAD_UMIN_I64 : PseudoInst< 4492263509Sdim (outs GPR:$dst1, GPR:$dst2), 4493263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4494263509Sdim NoItinerary, []>; 4495263509Sdim def ATOMIC_LOAD_UMAX_I64 : PseudoInst< 4496263509Sdim (outs GPR:$dst1, GPR:$dst2), 4497263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4498263509Sdim NoItinerary, []>; 4499263509Sdim def ATOMIC_SWAP_I64 : PseudoInst< 4500263509Sdim (outs GPR:$dst1, GPR:$dst2), 4501263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4502263509Sdim NoItinerary, []>; 4503263509Sdim def ATOMIC_CMP_SWAP_I64 : PseudoInst< 4504263509Sdim (outs GPR:$dst1, GPR:$dst2), 4505263509Sdim (ins GPR:$addr, GPR:$cmp1, GPR:$cmp2, 4506263509Sdim GPR:$set1, GPR:$set2, i32imm:$ordering), 4507263509Sdim NoItinerary, []>; 4508263509Sdim } 4509263509Sdim let mayLoad = 1 in 4510263509Sdim def ATOMIC_LOAD_I64 : PseudoInst< 4511263509Sdim (outs GPR:$dst1, GPR:$dst2), 4512263509Sdim (ins GPR:$addr, i32imm:$ordering), 4513263509Sdim NoItinerary, []>; 4514263509Sdim let mayStore = 1 in 4515263509Sdim def ATOMIC_STORE_I64 : PseudoInst< 4516263509Sdim (outs GPR:$dst1, GPR:$dst2), 4517263509Sdim (ins GPR:$addr, GPR:$src1, GPR:$src2, i32imm:$ordering), 4518263509Sdim NoItinerary, []>; 4519200581Srdivacky} 4520200581Srdivacky 4521245431Sdimlet usesCustomInserter = 1 in { 4522245431Sdim def COPY_STRUCT_BYVAL_I32 : PseudoInst< 4523245431Sdim (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment), 4524245431Sdim NoItinerary, 4525245431Sdim [(ARMcopystructbyval GPR:$dst, GPR:$src, imm:$size, imm:$alignment)]>; 4526245431Sdim} 4527245431Sdim 4528263509Sdimdef ldrex_1 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 4529263509Sdim return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 4530263509Sdim}]>; 4531263509Sdim 4532263509Sdimdef ldrex_2 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 4533263509Sdim return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 4534263509Sdim}]>; 4535263509Sdim 4536263509Sdimdef ldrex_4 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 4537263509Sdim return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 4538263509Sdim}]>; 4539263509Sdim 4540263509Sdimdef strex_1 : PatFrag<(ops node:$val, node:$ptr), 4541263509Sdim (int_arm_strex node:$val, node:$ptr), [{ 4542263509Sdim return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 4543263509Sdim}]>; 4544263509Sdim 4545263509Sdimdef strex_2 : PatFrag<(ops node:$val, node:$ptr), 4546263509Sdim (int_arm_strex node:$val, node:$ptr), [{ 4547263509Sdim return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 4548263509Sdim}]>; 4549263509Sdim 4550263509Sdimdef strex_4 : PatFrag<(ops node:$val, node:$ptr), 4551263509Sdim (int_arm_strex node:$val, node:$ptr), [{ 4552263509Sdim return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 4553263509Sdim}]>; 4554263509Sdim 4555200581Srdivackylet mayLoad = 1 in { 4556226890Sdimdef LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4557263509Sdim NoItinerary, "ldrexb", "\t$Rt, $addr", 4558263509Sdim [(set GPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>; 4559226890Sdimdef LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4560263509Sdim NoItinerary, "ldrexh", "\t$Rt, $addr", 4561263509Sdim [(set GPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>; 4562226890Sdimdef LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4563263509Sdim NoItinerary, "ldrex", "\t$Rt, $addr", 4564263509Sdim [(set GPR:$Rt, (ldrex_4 addr_offset_none:$addr))]>; 4565223017Sdimlet hasExtraDefRegAllocReq = 1 in 4566263509Sdimdef LDREXD : AIldrex<0b01, (outs GPRPairOp:$Rt),(ins addr_offset_none:$addr), 4567252723Sdim NoItinerary, "ldrexd", "\t$Rt, $addr", []> { 4568226890Sdim let DecoderMethod = "DecodeDoubleRegLoad"; 4569200581Srdivacky} 4570263509Sdim 4571263509Sdimdef LDAEXB : AIldaex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4572263509Sdim NoItinerary, "ldaexb", "\t$Rt, $addr", []>; 4573263509Sdimdef LDAEXH : AIldaex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4574263509Sdim NoItinerary, "ldaexh", "\t$Rt, $addr", []>; 4575263509Sdimdef LDAEX : AIldaex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 4576263509Sdim NoItinerary, "ldaex", "\t$Rt, $addr", []>; 4577263509Sdimlet hasExtraDefRegAllocReq = 1 in 4578263509Sdimdef LDAEXD : AIldaex<0b01, (outs GPRPairOp:$Rt),(ins addr_offset_none:$addr), 4579263509Sdim NoItinerary, "ldaexd", "\t$Rt, $addr", []> { 4580263509Sdim let DecoderMethod = "DecodeDoubleRegLoad"; 4581226890Sdim} 4582263509Sdim} 4583200581Srdivacky 4584218893Sdimlet mayStore = 1, Constraints = "@earlyclobber $Rd" in { 4585226890Sdimdef STREXB: AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4586263509Sdim NoItinerary, "strexb", "\t$Rd, $Rt, $addr", 4587263509Sdim [(set GPR:$Rd, (strex_1 GPR:$Rt, addr_offset_none:$addr))]>; 4588226890Sdimdef STREXH: AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4589263509Sdim NoItinerary, "strexh", "\t$Rd, $Rt, $addr", 4590263509Sdim [(set GPR:$Rd, (strex_2 GPR:$Rt, addr_offset_none:$addr))]>; 4591226890Sdimdef STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4592263509Sdim NoItinerary, "strex", "\t$Rd, $Rt, $addr", 4593263509Sdim [(set GPR:$Rd, (strex_4 GPR:$Rt, addr_offset_none:$addr))]>; 4594235633Sdimlet hasExtraSrcRegAllocReq = 1 in 4595218893Sdimdef STREXD : AIstrex<0b01, (outs GPR:$Rd), 4596252723Sdim (ins GPRPairOp:$Rt, addr_offset_none:$addr), 4597252723Sdim NoItinerary, "strexd", "\t$Rd, $Rt, $addr", []> { 4598226890Sdim let DecoderMethod = "DecodeDoubleRegStore"; 4599226890Sdim} 4600263509Sdimdef STLEXB: AIstlex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4601263509Sdim NoItinerary, "stlexb", "\t$Rd, $Rt, $addr", 4602263509Sdim []>; 4603263509Sdimdef STLEXH: AIstlex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4604263509Sdim NoItinerary, "stlexh", "\t$Rd, $Rt, $addr", 4605263509Sdim []>; 4606263509Sdimdef STLEX : AIstlex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 4607263509Sdim NoItinerary, "stlex", "\t$Rd, $Rt, $addr", 4608263509Sdim []>; 4609263509Sdimlet hasExtraSrcRegAllocReq = 1 in 4610263509Sdimdef STLEXD : AIstlex<0b01, (outs GPR:$Rd), 4611263509Sdim (ins GPRPairOp:$Rt, addr_offset_none:$addr), 4612263509Sdim NoItinerary, "stlexd", "\t$Rd, $Rt, $addr", []> { 4613263509Sdim let DecoderMethod = "DecodeDoubleRegStore"; 4614235633Sdim} 4615263509Sdim} 4616200581Srdivacky 4617263509Sdimdef CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", 4618263509Sdim [(int_arm_clrex)]>, 4619204642Srdivacky Requires<[IsARM, HasV7]> { 4620218893Sdim let Inst{31-0} = 0b11110101011111111111000000011111; 4621204642Srdivacky} 4622204642Srdivacky 4623263509Sdimdef : ARMPat<(and (ldrex_1 addr_offset_none:$addr), 0xff), 4624263509Sdim (LDREXB addr_offset_none:$addr)>; 4625263509Sdimdef : ARMPat<(and (ldrex_2 addr_offset_none:$addr), 0xffff), 4626263509Sdim (LDREXH addr_offset_none:$addr)>; 4627263509Sdimdef : ARMPat<(strex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr), 4628263509Sdim (STREXB GPR:$Rt, addr_offset_none:$addr)>; 4629263509Sdimdef : ARMPat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), 4630263509Sdim (STREXH GPR:$Rt, addr_offset_none:$addr)>; 4631263509Sdim 4632263509Sdimclass acquiring_load<PatFrag base> 4633263509Sdim : PatFrag<(ops node:$ptr), (base node:$ptr), [{ 4634263509Sdim AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering(); 4635263509Sdim return Ordering == Acquire || Ordering == SequentiallyConsistent; 4636263509Sdim}]>; 4637263509Sdim 4638263509Sdimdef atomic_load_acquire_8 : acquiring_load<atomic_load_8>; 4639263509Sdimdef atomic_load_acquire_16 : acquiring_load<atomic_load_16>; 4640263509Sdimdef atomic_load_acquire_32 : acquiring_load<atomic_load_32>; 4641263509Sdim 4642263509Sdimclass releasing_store<PatFrag base> 4643263509Sdim : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{ 4644263509Sdim AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering(); 4645263509Sdim return Ordering == Release || Ordering == SequentiallyConsistent; 4646263509Sdim}]>; 4647263509Sdim 4648263509Sdimdef atomic_store_release_8 : releasing_store<atomic_store_8>; 4649263509Sdimdef atomic_store_release_16 : releasing_store<atomic_store_16>; 4650263509Sdimdef atomic_store_release_32 : releasing_store<atomic_store_32>; 4651263509Sdim 4652263509Sdimlet AddedComplexity = 8 in { 4653263509Sdim def : ARMPat<(atomic_load_acquire_8 addr_offset_none:$addr), (LDAB addr_offset_none:$addr)>; 4654263509Sdim def : ARMPat<(atomic_load_acquire_16 addr_offset_none:$addr), (LDAH addr_offset_none:$addr)>; 4655263509Sdim def : ARMPat<(atomic_load_acquire_32 addr_offset_none:$addr), (LDA addr_offset_none:$addr)>; 4656263509Sdim def : ARMPat<(atomic_store_release_8 addr_offset_none:$addr, GPR:$val), (STLB GPR:$val, addr_offset_none:$addr)>; 4657263509Sdim def : ARMPat<(atomic_store_release_16 addr_offset_none:$addr, GPR:$val), (STLH GPR:$val, addr_offset_none:$addr)>; 4658263509Sdim def : ARMPat<(atomic_store_release_32 addr_offset_none:$addr, GPR:$val), (STL GPR:$val, addr_offset_none:$addr)>; 4659263509Sdim} 4660263509Sdim 4661226890Sdim// SWP/SWPB are deprecated in V6/V7. 4662226890Sdimlet mayLoad = 1, mayStore = 1 in { 4663245431Sdimdef SWP : AIswp<0, (outs GPRnopc:$Rt), 4664263509Sdim (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swp", []>, 4665263509Sdim Requires<[PreV8]>; 4666245431Sdimdef SWPB: AIswp<1, (outs GPRnopc:$Rt), 4667263509Sdim (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swpb", []>, 4668263509Sdim Requires<[PreV8]>; 4669203954Srdivacky} 4670203954Srdivacky 4671193323Sed//===----------------------------------------------------------------------===// 4672221345Sdim// Coprocessor Instructions. 4673193323Sed// 4674193323Sed 4675224145Sdimdef CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 4676224145Sdim c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 4677218893Sdim NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 4678223017Sdim [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 4679263509Sdim imm:$CRm, imm:$opc2)]>, 4680263509Sdim Requires<[PreV8]> { 4681218893Sdim bits<4> opc1; 4682218893Sdim bits<4> CRn; 4683218893Sdim bits<4> CRd; 4684218893Sdim bits<4> cop; 4685218893Sdim bits<3> opc2; 4686218893Sdim bits<4> CRm; 4687218893Sdim 4688218893Sdim let Inst{3-0} = CRm; 4689218893Sdim let Inst{4} = 0; 4690218893Sdim let Inst{7-5} = opc2; 4691218893Sdim let Inst{11-8} = cop; 4692218893Sdim let Inst{15-12} = CRd; 4693218893Sdim let Inst{19-16} = CRn; 4694218893Sdim let Inst{23-20} = opc1; 4695203954Srdivacky} 4696203954Srdivacky 4697263509Sdimdef CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 4698224145Sdim c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 4699218893Sdim NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 4700223017Sdim [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 4701263509Sdim imm:$CRm, imm:$opc2)]>, 4702263509Sdim Requires<[PreV8]> { 4703203954Srdivacky let Inst{31-28} = 0b1111; 4704218893Sdim bits<4> opc1; 4705218893Sdim bits<4> CRn; 4706218893Sdim bits<4> CRd; 4707218893Sdim bits<4> cop; 4708218893Sdim bits<3> opc2; 4709218893Sdim bits<4> CRm; 4710218893Sdim 4711218893Sdim let Inst{3-0} = CRm; 4712218893Sdim let Inst{4} = 0; 4713218893Sdim let Inst{7-5} = opc2; 4714218893Sdim let Inst{11-8} = cop; 4715218893Sdim let Inst{15-12} = CRd; 4716218893Sdim let Inst{19-16} = CRn; 4717218893Sdim let Inst{23-20} = opc1; 4718203954Srdivacky} 4719203954Srdivacky 4720221345Sdimclass ACI<dag oops, dag iops, string opc, string asm, 4721221345Sdim IndexMode im = IndexModeNone> 4722226890Sdim : I<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary, 4723226890Sdim opc, asm, "", []> { 4724226890Sdim let Inst{27-25} = 0b110; 4725226890Sdim} 4726226890Sdimclass ACInoP<dag oops, dag iops, string opc, string asm, 4727226890Sdim IndexMode im = IndexModeNone> 4728224145Sdim : InoP<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary, 4729226890Sdim opc, asm, "", []> { 4730226890Sdim let Inst{31-28} = 0b1111; 4731204642Srdivacky let Inst{27-25} = 0b110; 4732204642Srdivacky} 4733226890Sdimmulticlass LdStCop<bit load, bit Dbit, string asm> { 4734226890Sdim def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 4735226890Sdim asm, "\t$cop, $CRd, $addr"> { 4736226890Sdim bits<13> addr; 4737226890Sdim bits<4> cop; 4738226890Sdim bits<4> CRd; 4739204642Srdivacky let Inst{24} = 1; // P = 1 4740226890Sdim let Inst{23} = addr{8}; 4741226890Sdim let Inst{22} = Dbit; 4742204642Srdivacky let Inst{21} = 0; // W = 0 4743204642Srdivacky let Inst{20} = load; 4744226890Sdim let Inst{19-16} = addr{12-9}; 4745226890Sdim let Inst{15-12} = CRd; 4746226890Sdim let Inst{11-8} = cop; 4747226890Sdim let Inst{7-0} = addr{7-0}; 4748226890Sdim let DecoderMethod = "DecodeCopMemInstruction"; 4749204642Srdivacky } 4750252723Sdim def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), 4751226890Sdim asm, "\t$cop, $CRd, $addr!", IndexModePre> { 4752226890Sdim bits<13> addr; 4753226890Sdim bits<4> cop; 4754226890Sdim bits<4> CRd; 4755204642Srdivacky let Inst{24} = 1; // P = 1 4756226890Sdim let Inst{23} = addr{8}; 4757226890Sdim let Inst{22} = Dbit; 4758204642Srdivacky let Inst{21} = 1; // W = 1 4759204642Srdivacky let Inst{20} = load; 4760226890Sdim let Inst{19-16} = addr{12-9}; 4761226890Sdim let Inst{15-12} = CRd; 4762226890Sdim let Inst{11-8} = cop; 4763226890Sdim let Inst{7-0} = addr{7-0}; 4764226890Sdim let DecoderMethod = "DecodeCopMemInstruction"; 4765204642Srdivacky } 4766226890Sdim def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 4767226890Sdim postidx_imm8s4:$offset), 4768226890Sdim asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> { 4769226890Sdim bits<9> offset; 4770226890Sdim bits<4> addr; 4771226890Sdim bits<4> cop; 4772226890Sdim bits<4> CRd; 4773204642Srdivacky let Inst{24} = 0; // P = 0 4774226890Sdim let Inst{23} = offset{8}; 4775226890Sdim let Inst{22} = Dbit; 4776204642Srdivacky let Inst{21} = 1; // W = 1 4777204642Srdivacky let Inst{20} = load; 4778226890Sdim let Inst{19-16} = addr; 4779226890Sdim let Inst{15-12} = CRd; 4780226890Sdim let Inst{11-8} = cop; 4781226890Sdim let Inst{7-0} = offset{7-0}; 4782226890Sdim let DecoderMethod = "DecodeCopMemInstruction"; 4783204642Srdivacky } 4784204642Srdivacky def _OPTION : ACI<(outs), 4785226890Sdim (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 4786226890Sdim coproc_option_imm:$option), 4787226890Sdim asm, "\t$cop, $CRd, $addr, $option"> { 4788226890Sdim bits<8> option; 4789226890Sdim bits<4> addr; 4790226890Sdim bits<4> cop; 4791226890Sdim bits<4> CRd; 4792204642Srdivacky let Inst{24} = 0; // P = 0 4793204642Srdivacky let Inst{23} = 1; // U = 1 4794226890Sdim let Inst{22} = Dbit; 4795204642Srdivacky let Inst{21} = 0; // W = 0 4796204642Srdivacky let Inst{20} = load; 4797226890Sdim let Inst{19-16} = addr; 4798226890Sdim let Inst{15-12} = CRd; 4799226890Sdim let Inst{11-8} = cop; 4800226890Sdim let Inst{7-0} = option; 4801226890Sdim let DecoderMethod = "DecodeCopMemInstruction"; 4802204642Srdivacky } 4803226890Sdim} 4804226890Sdimmulticlass LdSt2Cop<bit load, bit Dbit, string asm> { 4805226890Sdim def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 4806226890Sdim asm, "\t$cop, $CRd, $addr"> { 4807226890Sdim bits<13> addr; 4808226890Sdim bits<4> cop; 4809226890Sdim bits<4> CRd; 4810204642Srdivacky let Inst{24} = 1; // P = 1 4811226890Sdim let Inst{23} = addr{8}; 4812226890Sdim let Inst{22} = Dbit; 4813204642Srdivacky let Inst{21} = 0; // W = 0 4814204642Srdivacky let Inst{20} = load; 4815226890Sdim let Inst{19-16} = addr{12-9}; 4816226890Sdim let Inst{15-12} = CRd; 4817226890Sdim let Inst{11-8} = cop; 4818226890Sdim let Inst{7-0} = addr{7-0}; 4819226890Sdim let DecoderMethod = "DecodeCopMemInstruction"; 4820204642Srdivacky } 4821252723Sdim def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), 4822226890Sdim asm, "\t$cop, $CRd, $addr!", IndexModePre> { 4823226890Sdim bits<13> addr; 4824226890Sdim bits<4> cop; 4825226890Sdim bits<4> CRd; 4826204642Srdivacky let Inst{24} = 1; // P = 1 4827226890Sdim let Inst{23} = addr{8}; 4828226890Sdim let Inst{22} = Dbit; 4829204642Srdivacky let Inst{21} = 1; // W = 1 4830204642Srdivacky let Inst{20} = load; 4831226890Sdim let Inst{19-16} = addr{12-9}; 4832226890Sdim let Inst{15-12} = CRd; 4833226890Sdim let Inst{11-8} = cop; 4834226890Sdim let Inst{7-0} = addr{7-0}; 4835226890Sdim let DecoderMethod = "DecodeCopMemInstruction"; 4836204642Srdivacky } 4837226890Sdim def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 4838226890Sdim postidx_imm8s4:$offset), 4839226890Sdim asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> { 4840226890Sdim bits<9> offset; 4841226890Sdim bits<4> addr; 4842226890Sdim bits<4> cop; 4843226890Sdim bits<4> CRd; 4844204642Srdivacky let Inst{24} = 0; // P = 0 4845226890Sdim let Inst{23} = offset{8}; 4846226890Sdim let Inst{22} = Dbit; 4847204642Srdivacky let Inst{21} = 1; // W = 1 4848204642Srdivacky let Inst{20} = load; 4849226890Sdim let Inst{19-16} = addr; 4850226890Sdim let Inst{15-12} = CRd; 4851226890Sdim let Inst{11-8} = cop; 4852226890Sdim let Inst{7-0} = offset{7-0}; 4853226890Sdim let DecoderMethod = "DecodeCopMemInstruction"; 4854204642Srdivacky } 4855226890Sdim def _OPTION : ACInoP<(outs), 4856226890Sdim (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 4857226890Sdim coproc_option_imm:$option), 4858226890Sdim asm, "\t$cop, $CRd, $addr, $option"> { 4859226890Sdim bits<8> option; 4860226890Sdim bits<4> addr; 4861226890Sdim bits<4> cop; 4862226890Sdim bits<4> CRd; 4863204642Srdivacky let Inst{24} = 0; // P = 0 4864204642Srdivacky let Inst{23} = 1; // U = 1 4865226890Sdim let Inst{22} = Dbit; 4866204642Srdivacky let Inst{21} = 0; // W = 0 4867204642Srdivacky let Inst{20} = load; 4868226890Sdim let Inst{19-16} = addr; 4869226890Sdim let Inst{15-12} = CRd; 4870226890Sdim let Inst{11-8} = cop; 4871226890Sdim let Inst{7-0} = option; 4872226890Sdim let DecoderMethod = "DecodeCopMemInstruction"; 4873204642Srdivacky } 4874204642Srdivacky} 4875204642Srdivacky 4876226890Sdimdefm LDC : LdStCop <1, 0, "ldc">; 4877226890Sdimdefm LDCL : LdStCop <1, 1, "ldcl">; 4878226890Sdimdefm STC : LdStCop <0, 0, "stc">; 4879226890Sdimdefm STCL : LdStCop <0, 1, "stcl">; 4880263509Sdimdefm LDC2 : LdSt2Cop<1, 0, "ldc2">, Requires<[PreV8]>; 4881263509Sdimdefm LDC2L : LdSt2Cop<1, 1, "ldc2l">, Requires<[PreV8]>; 4882263509Sdimdefm STC2 : LdSt2Cop<0, 0, "stc2">, Requires<[PreV8]>; 4883263509Sdimdefm STC2L : LdSt2Cop<0, 1, "stc2l">, Requires<[PreV8]>; 4884204642Srdivacky 4885218893Sdim//===----------------------------------------------------------------------===// 4886226890Sdim// Move between coprocessor and ARM core register. 4887218893Sdim// 4888218893Sdim 4889223017Sdimclass MovRCopro<string opc, bit direction, dag oops, dag iops, 4890223017Sdim list<dag> pattern> 4891221345Sdim : ABI<0b1110, oops, iops, NoItinerary, opc, 4892223017Sdim "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", pattern> { 4893218893Sdim let Inst{20} = direction; 4894203954Srdivacky let Inst{4} = 1; 4895218893Sdim 4896218893Sdim bits<4> Rt; 4897218893Sdim bits<4> cop; 4898218893Sdim bits<3> opc1; 4899218893Sdim bits<3> opc2; 4900218893Sdim bits<4> CRm; 4901218893Sdim bits<4> CRn; 4902218893Sdim 4903218893Sdim let Inst{15-12} = Rt; 4904218893Sdim let Inst{11-8} = cop; 4905218893Sdim let Inst{23-21} = opc1; 4906218893Sdim let Inst{7-5} = opc2; 4907218893Sdim let Inst{3-0} = CRm; 4908218893Sdim let Inst{19-16} = CRn; 4909203954Srdivacky} 4910203954Srdivacky 4911221345Sdimdef MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */, 4912223017Sdim (outs), 4913224145Sdim (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4914224145Sdim c_imm:$CRm, imm0_7:$opc2), 4915223017Sdim [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 4916263509Sdim imm:$CRm, imm:$opc2)]>, 4917263509Sdim ComplexDeprecationPredicate<"MCR">; 4918235633Sdimdef : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm", 4919235633Sdim (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4920235633Sdim c_imm:$CRm, 0, pred:$p)>; 4921221345Sdimdef MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */, 4922263509Sdim (outs GPRwithAPSR:$Rt), 4923226890Sdim (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 4924226890Sdim imm0_7:$opc2), []>; 4925235633Sdimdef : ARMInstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm", 4926263509Sdim (MRC GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 4927235633Sdim c_imm:$CRm, 0, pred:$p)>; 4928218893Sdim 4929223017Sdimdef : ARMPat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), 4930223017Sdim (MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 4931223017Sdim 4932223017Sdimclass MovRCopro2<string opc, bit direction, dag oops, dag iops, 4933223017Sdim list<dag> pattern> 4934221345Sdim : ABXI<0b1110, oops, iops, NoItinerary, 4935223017Sdim !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), pattern> { 4936263509Sdim let Inst{31-24} = 0b11111110; 4937218893Sdim let Inst{20} = direction; 4938203954Srdivacky let Inst{4} = 1; 4939203954Srdivacky 4940218893Sdim bits<4> Rt; 4941218893Sdim bits<4> cop; 4942218893Sdim bits<3> opc1; 4943218893Sdim bits<3> opc2; 4944218893Sdim bits<4> CRm; 4945218893Sdim bits<4> CRn; 4946203954Srdivacky 4947218893Sdim let Inst{15-12} = Rt; 4948218893Sdim let Inst{11-8} = cop; 4949218893Sdim let Inst{23-21} = opc1; 4950218893Sdim let Inst{7-5} = opc2; 4951218893Sdim let Inst{3-0} = CRm; 4952218893Sdim let Inst{19-16} = CRn; 4953203954Srdivacky} 4954203954Srdivacky 4955221345Sdimdef MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */, 4956223017Sdim (outs), 4957224145Sdim (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4958224145Sdim c_imm:$CRm, imm0_7:$opc2), 4959223017Sdim [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 4960263509Sdim imm:$CRm, imm:$opc2)]>, 4961263509Sdim Requires<[PreV8]>; 4962235633Sdimdef : ARMInstAlias<"mcr2$ $cop, $opc1, $Rt, $CRn, $CRm", 4963235633Sdim (MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4964235633Sdim c_imm:$CRm, 0)>; 4965221345Sdimdef MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */, 4966263509Sdim (outs GPRwithAPSR:$Rt), 4967226890Sdim (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 4968263509Sdim imm0_7:$opc2), []>, 4969263509Sdim Requires<[PreV8]>; 4970235633Sdimdef : ARMInstAlias<"mrc2$ $cop, $opc1, $Rt, $CRn, $CRm", 4971263509Sdim (MRC2 GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 4972235633Sdim c_imm:$CRm, 0)>; 4973218893Sdim 4974223017Sdimdef : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, 4975223017Sdim imm:$CRm, imm:$opc2), 4976223017Sdim (MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 4977223017Sdim 4978226890Sdimclass MovRRCopro<string opc, bit direction, list<dag> pattern = []> 4979224145Sdim : ABI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, 4980235633Sdim GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), 4981223017Sdim NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { 4982218893Sdim let Inst{23-21} = 0b010; 4983218893Sdim let Inst{20} = direction; 4984218893Sdim 4985218893Sdim bits<4> Rt; 4986218893Sdim bits<4> Rt2; 4987218893Sdim bits<4> cop; 4988218893Sdim bits<4> opc1; 4989218893Sdim bits<4> CRm; 4990218893Sdim 4991218893Sdim let Inst{15-12} = Rt; 4992218893Sdim let Inst{19-16} = Rt2; 4993218893Sdim let Inst{11-8} = cop; 4994218893Sdim let Inst{7-4} = opc1; 4995218893Sdim let Inst{3-0} = CRm; 4996203954Srdivacky} 4997203954Srdivacky 4998223017Sdimdef MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, 4999245431Sdim [(int_arm_mcrr imm:$cop, imm:$opc1, GPRnopc:$Rt, 5000245431Sdim GPRnopc:$Rt2, imm:$CRm)]>; 5001218893Sdimdef MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>; 5002218893Sdim 5003226890Sdimclass MovRRCopro2<string opc, bit direction, list<dag> pattern = []> 5004224145Sdim : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, 5005235633Sdim GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary, 5006263509Sdim !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern>, 5007263509Sdim Requires<[PreV8]> { 5008203954Srdivacky let Inst{31-28} = 0b1111; 5009218893Sdim let Inst{23-21} = 0b010; 5010218893Sdim let Inst{20} = direction; 5011203954Srdivacky 5012218893Sdim bits<4> Rt; 5013218893Sdim bits<4> Rt2; 5014218893Sdim bits<4> cop; 5015218893Sdim bits<4> opc1; 5016218893Sdim bits<4> CRm; 5017203954Srdivacky 5018218893Sdim let Inst{15-12} = Rt; 5019218893Sdim let Inst{19-16} = Rt2; 5020218893Sdim let Inst{11-8} = cop; 5021218893Sdim let Inst{7-4} = opc1; 5022218893Sdim let Inst{3-0} = CRm; 5023235633Sdim 5024235633Sdim let DecoderMethod = "DecodeMRRC2"; 5025203954Srdivacky} 5026203954Srdivacky 5027223017Sdimdef MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */, 5028245431Sdim [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPRnopc:$Rt, 5029245431Sdim GPRnopc:$Rt2, imm:$CRm)]>; 5030218893Sdimdef MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>; 5031218893Sdim 5032203954Srdivacky//===----------------------------------------------------------------------===// 5033226890Sdim// Move between special register and ARM core register 5034203954Srdivacky// 5035203954Srdivacky 5036218893Sdim// Move to ARM core register from Special Register 5037235633Sdimdef MRS : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, 5038226890Sdim "mrs", "\t$Rd, apsr", []> { 5039218893Sdim bits<4> Rd; 5040218893Sdim let Inst{23-16} = 0b00001111; 5041235633Sdim let Unpredictable{19-17} = 0b111; 5042235633Sdim 5043218893Sdim let Inst{15-12} = Rd; 5044235633Sdim 5045235633Sdim let Inst{11-0} = 0b000000000000; 5046235633Sdim let Unpredictable{11-0} = 0b110100001111; 5047203954Srdivacky} 5048203954Srdivacky 5049245431Sdimdef : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPRnopc:$Rd, pred:$p)>, 5050245431Sdim Requires<[IsARM]>; 5051226890Sdim 5052235633Sdim// The MRSsys instruction is the MRS instruction from the ARM ARM, 5053235633Sdim// section B9.3.9, with the R bit set to 1. 5054235633Sdimdef MRSsys : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, 5055226890Sdim "mrs", "\t$Rd, spsr", []> { 5056218893Sdim bits<4> Rd; 5057218893Sdim let Inst{23-16} = 0b01001111; 5058235633Sdim let Unpredictable{19-16} = 0b1111; 5059235633Sdim 5060218893Sdim let Inst{15-12} = Rd; 5061235633Sdim 5062235633Sdim let Inst{11-0} = 0b000000000000; 5063235633Sdim let Unpredictable{11-0} = 0b110100001111; 5064203954Srdivacky} 5065203954Srdivacky 5066218893Sdim// Move from ARM core register to Special Register 5067218893Sdim// 5068218893Sdim// No need to have both system and application versions, the encodings are the 5069218893Sdim// same and the assembly parser has no way to distinguish between them. The mask 5070218893Sdim// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains 5071218893Sdim// the mask with the fields to be accessed in the special register. 5072218893Sdimdef MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary, 5073226890Sdim "msr", "\t$mask, $Rn", []> { 5074218893Sdim bits<5> mask; 5075218893Sdim bits<4> Rn; 5076203954Srdivacky 5077218893Sdim let Inst{23} = 0; 5078218893Sdim let Inst{22} = mask{4}; // R bit 5079218893Sdim let Inst{21-20} = 0b10; 5080218893Sdim let Inst{19-16} = mask{3-0}; 5081218893Sdim let Inst{15-12} = 0b1111; 5082218893Sdim let Inst{11-4} = 0b00000000; 5083218893Sdim let Inst{3-0} = Rn; 5084204642Srdivacky} 5085204642Srdivacky 5086218893Sdimdef MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, so_imm:$a), NoItinerary, 5087226890Sdim "msr", "\t$mask, $a", []> { 5088218893Sdim bits<5> mask; 5089218893Sdim bits<12> a; 5090204642Srdivacky 5091218893Sdim let Inst{23} = 0; 5092218893Sdim let Inst{22} = mask{4}; // R bit 5093218893Sdim let Inst{21-20} = 0b10; 5094218893Sdim let Inst{19-16} = mask{3-0}; 5095218893Sdim let Inst{15-12} = 0b1111; 5096218893Sdim let Inst{11-0} = a; 5097204642Srdivacky} 5098221345Sdim 5099221345Sdim//===----------------------------------------------------------------------===// 5100221345Sdim// TLS Instructions 5101221345Sdim// 5102221345Sdim 5103221345Sdim// __aeabi_read_tp preserves the registers r1-r3. 5104221345Sdim// This is a pseudo inst so that we can get the encoding right, 5105221345Sdim// complete with fixup for the aeabi_read_tp function. 5106221345Sdimlet isCall = 1, 5107221345Sdim Defs = [R0, R12, LR, CPSR], Uses = [SP] in { 5108221345Sdim def TPsoft : PseudoInst<(outs), (ins), IIC_Br, 5109263509Sdim [(set R0, ARMthread_pointer)]>, Sched<[WriteBr]>; 5110221345Sdim} 5111221345Sdim 5112221345Sdim//===----------------------------------------------------------------------===// 5113221345Sdim// SJLJ Exception handling intrinsics 5114221345Sdim// eh_sjlj_setjmp() is an instruction sequence to store the return 5115221345Sdim// address and save #0 in R0 for the non-longjmp case. 5116221345Sdim// Since by its nature we may be coming from some other function to get 5117221345Sdim// here, and we're using the stack frame for the containing function to 5118221345Sdim// save/restore registers, we can't keep anything live in regs across 5119221345Sdim// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 5120221345Sdim// when we get here from a longjmp(). We force everything out of registers 5121221345Sdim// except for our own input by listing the relevant registers in Defs. By 5122221345Sdim// doing so, we also cause the prologue/epilogue code to actively preserve 5123221345Sdim// all of the callee-saved resgisters, which is exactly what we want. 5124221345Sdim// A constant value is passed in $val, and we use the location as a scratch. 5125221345Sdim// 5126221345Sdim// These are pseudo-instructions and are lowered to individual MC-insts, so 5127221345Sdim// no encoding information is necessary. 5128221345Sdimlet Defs = 5129223017Sdim [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, 5130235633Sdim Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ], 5131235633Sdim hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in { 5132221345Sdim def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 5133221345Sdim NoItinerary, 5134221345Sdim [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 5135221345Sdim Requires<[IsARM, HasVFP2]>; 5136221345Sdim} 5137221345Sdim 5138221345Sdimlet Defs = 5139223017Sdim [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], 5140235633Sdim hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in { 5141221345Sdim def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 5142221345Sdim NoItinerary, 5143221345Sdim [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 5144221345Sdim Requires<[IsARM, NoVFP]>; 5145221345Sdim} 5146221345Sdim 5147235633Sdim// FIXME: Non-IOS version(s) 5148221345Sdimlet isBarrier = 1, hasSideEffects = 1, isTerminator = 1, 5149221345Sdim Defs = [ R7, LR, SP ] in { 5150221345Sdimdef Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch), 5151221345Sdim NoItinerary, 5152221345Sdim [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, 5153235633Sdim Requires<[IsARM, IsIOS]>; 5154221345Sdim} 5155221345Sdim 5156245431Sdim// eh.sjlj.dispatchsetup pseudo-instruction. 5157245431Sdim// This pseudo is used for both ARM and Thumb. Any differences are handled when 5158245431Sdim// the pseudo is expanded (which happens before any passes that need the 5159245431Sdim// instruction size). 5160245431Sdimlet isBarrier = 1 in 5161235633Sdimdef Int_eh_sjlj_dispatchsetup : PseudoInst<(outs), (ins), NoItinerary, []>; 5162221345Sdim 5163235633Sdim 5164221345Sdim//===----------------------------------------------------------------------===// 5165221345Sdim// Non-Instruction Patterns 5166221345Sdim// 5167221345Sdim 5168224145Sdim// ARMv4 indirect branch using (MOVr PC, dst) 5169224145Sdimlet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in 5170224145Sdim def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst), 5171224145Sdim 4, IIC_Br, [(brind GPR:$dst)], 5172224145Sdim (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, 5173263509Sdim Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; 5174224145Sdim 5175221345Sdim// Large immediate handling. 5176221345Sdim 5177221345Sdim// 32-bit immediate using two piece so_imms or movw + movt. 5178221345Sdim// This is a single pseudo instruction, the benefit is that it can be remat'd 5179221345Sdim// as a single unit instead of having to handle reg inputs. 5180221345Sdim// FIXME: Remove this when we can do generalized remat. 5181221345Sdimlet isReMaterializable = 1, isMoveImm = 1 in 5182221345Sdimdef MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 5183221345Sdim [(set GPR:$dst, (arm_i32imm:$src))]>, 5184221345Sdim Requires<[IsARM]>; 5185221345Sdim 5186221345Sdim// Pseudo instruction that combines movw + movt + add pc (if PIC). 5187221345Sdim// It also makes it possible to rematerialize the instructions. 5188221345Sdim// FIXME: Remove this when we can do generalized remat and when machine licm 5189221345Sdim// can properly the instructions. 5190221345Sdimlet isReMaterializable = 1 in { 5191221345Sdimdef MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 5192221345Sdim IIC_iMOVix2addpc, 5193221345Sdim [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, 5194221345Sdim Requires<[IsARM, UseMovt]>; 5195221345Sdim 5196221345Sdimdef MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 5197221345Sdim IIC_iMOVix2, 5198221345Sdim [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>, 5199221345Sdim Requires<[IsARM, UseMovt]>; 5200221345Sdim 5201221345Sdimlet AddedComplexity = 10 in 5202221345Sdimdef MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 5203221345Sdim IIC_iMOVix2ld, 5204221345Sdim [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, 5205221345Sdim Requires<[IsARM, UseMovt]>; 5206221345Sdim} // isReMaterializable 5207221345Sdim 5208221345Sdim// ConstantPool, GlobalAddress, and JumpTable 5209221345Sdimdef : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>, 5210221345Sdim Requires<[IsARM, DontUseMovt]>; 5211221345Sdimdef : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; 5212221345Sdimdef : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>, 5213221345Sdim Requires<[IsARM, UseMovt]>; 5214221345Sdimdef : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), 5215221345Sdim (LEApcrelJT tjumptable:$dst, imm:$id)>; 5216221345Sdim 5217221345Sdim// TODO: add,sub,and, 3-instr forms? 5218221345Sdim 5219235633Sdim// Tail calls. These patterns also apply to Thumb mode. 5220235633Sdimdef : Pat<(ARMtcret tcGPR:$dst), (TCRETURNri tcGPR:$dst)>; 5221235633Sdimdef : Pat<(ARMtcret (i32 tglobaladdr:$dst)), (TCRETURNdi texternalsym:$dst)>; 5222235633Sdimdef : Pat<(ARMtcret (i32 texternalsym:$dst)), (TCRETURNdi texternalsym:$dst)>; 5223221345Sdim 5224221345Sdim// Direct calls 5225235633Sdimdef : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>; 5226235633Sdimdef : ARMPat<(ARMcall_nolink texternalsym:$func), 5227235633Sdim (BMOVPCB_CALL texternalsym:$func)>; 5228221345Sdim 5229221345Sdim// zextload i1 -> zextload i8 5230221345Sdimdef : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 5231221345Sdimdef : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 5232221345Sdim 5233221345Sdim// extload -> zextload 5234221345Sdimdef : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 5235221345Sdimdef : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 5236221345Sdimdef : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 5237221345Sdimdef : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 5238221345Sdim 5239221345Sdimdef : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; 5240221345Sdim 5241221345Sdimdef : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; 5242221345Sdimdef : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>; 5243221345Sdim 5244221345Sdim// smul* and smla* 5245221345Sdimdef : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 5246221345Sdim (sra (shl GPR:$b, (i32 16)), (i32 16))), 5247221345Sdim (SMULBB GPR:$a, GPR:$b)>; 5248221345Sdimdef : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b), 5249221345Sdim (SMULBB GPR:$a, GPR:$b)>; 5250221345Sdimdef : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 5251221345Sdim (sra GPR:$b, (i32 16))), 5252221345Sdim (SMULBT GPR:$a, GPR:$b)>; 5253221345Sdimdef : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))), 5254221345Sdim (SMULBT GPR:$a, GPR:$b)>; 5255221345Sdimdef : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), 5256221345Sdim (sra (shl GPR:$b, (i32 16)), (i32 16))), 5257221345Sdim (SMULTB GPR:$a, GPR:$b)>; 5258221345Sdimdef : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b), 5259221345Sdim (SMULTB GPR:$a, GPR:$b)>; 5260221345Sdimdef : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 5261221345Sdim (i32 16)), 5262221345Sdim (SMULWB GPR:$a, GPR:$b)>; 5263221345Sdimdef : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)), 5264221345Sdim (SMULWB GPR:$a, GPR:$b)>; 5265221345Sdim 5266245431Sdimdef : ARMV5MOPat<(add GPR:$acc, 5267221345Sdim (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 5268221345Sdim (sra (shl GPR:$b, (i32 16)), (i32 16)))), 5269221345Sdim (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 5270245431Sdimdef : ARMV5MOPat<(add GPR:$acc, 5271221345Sdim (mul sext_16_node:$a, sext_16_node:$b)), 5272221345Sdim (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 5273245431Sdimdef : ARMV5MOPat<(add GPR:$acc, 5274221345Sdim (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 5275221345Sdim (sra GPR:$b, (i32 16)))), 5276221345Sdim (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 5277245431Sdimdef : ARMV5MOPat<(add GPR:$acc, 5278221345Sdim (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))), 5279221345Sdim (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 5280245431Sdimdef : ARMV5MOPat<(add GPR:$acc, 5281221345Sdim (mul (sra GPR:$a, (i32 16)), 5282221345Sdim (sra (shl GPR:$b, (i32 16)), (i32 16)))), 5283221345Sdim (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 5284245431Sdimdef : ARMV5MOPat<(add GPR:$acc, 5285221345Sdim (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)), 5286221345Sdim (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 5287245431Sdimdef : ARMV5MOPat<(add GPR:$acc, 5288221345Sdim (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 5289221345Sdim (i32 16))), 5290221345Sdim (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 5291245431Sdimdef : ARMV5MOPat<(add GPR:$acc, 5292221345Sdim (sra (mul GPR:$a, sext_16_node:$b), (i32 16))), 5293221345Sdim (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 5294221345Sdim 5295221345Sdim 5296221345Sdim// Pre-v7 uses MCR for synchronization barriers. 5297221345Sdimdef : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>, 5298221345Sdim Requires<[IsARM, HasV6]>; 5299221345Sdim 5300226890Sdim// SXT/UXT with no rotate 5301226890Sdimlet AddedComplexity = 16 in { 5302226890Sdimdef : ARMV6Pat<(and GPR:$Src, 0x000000FF), (UXTB GPR:$Src, 0)>; 5303226890Sdimdef : ARMV6Pat<(and GPR:$Src, 0x0000FFFF), (UXTH GPR:$Src, 0)>; 5304226890Sdimdef : ARMV6Pat<(and GPR:$Src, 0x00FF00FF), (UXTB16 GPR:$Src, 0)>; 5305226890Sdimdef : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0x00FF)), 5306226890Sdim (UXTAB GPR:$Rn, GPR:$Rm, 0)>; 5307226890Sdimdef : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0xFFFF)), 5308226890Sdim (UXTAH GPR:$Rn, GPR:$Rm, 0)>; 5309226890Sdim} 5310221345Sdim 5311226890Sdimdef : ARMV6Pat<(sext_inreg GPR:$Src, i8), (SXTB GPR:$Src, 0)>; 5312226890Sdimdef : ARMV6Pat<(sext_inreg GPR:$Src, i16), (SXTH GPR:$Src, 0)>; 5313226890Sdim 5314226890Sdimdef : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i8)), 5315226890Sdim (SXTAB GPR:$Rn, GPRnopc:$Rm, 0)>; 5316226890Sdimdef : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)), 5317226890Sdim (SXTAH GPR:$Rn, GPRnopc:$Rm, 0)>; 5318226890Sdim 5319226890Sdim// Atomic load/store patterns 5320226890Sdimdef : ARMPat<(atomic_load_8 ldst_so_reg:$src), 5321226890Sdim (LDRBrs ldst_so_reg:$src)>; 5322226890Sdimdef : ARMPat<(atomic_load_8 addrmode_imm12:$src), 5323226890Sdim (LDRBi12 addrmode_imm12:$src)>; 5324226890Sdimdef : ARMPat<(atomic_load_16 addrmode3:$src), 5325226890Sdim (LDRH addrmode3:$src)>; 5326226890Sdimdef : ARMPat<(atomic_load_32 ldst_so_reg:$src), 5327226890Sdim (LDRrs ldst_so_reg:$src)>; 5328226890Sdimdef : ARMPat<(atomic_load_32 addrmode_imm12:$src), 5329226890Sdim (LDRi12 addrmode_imm12:$src)>; 5330226890Sdimdef : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val), 5331226890Sdim (STRBrs GPR:$val, ldst_so_reg:$ptr)>; 5332226890Sdimdef : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val), 5333226890Sdim (STRBi12 GPR:$val, addrmode_imm12:$ptr)>; 5334226890Sdimdef : ARMPat<(atomic_store_16 addrmode3:$ptr, GPR:$val), 5335226890Sdim (STRH GPR:$val, addrmode3:$ptr)>; 5336226890Sdimdef : ARMPat<(atomic_store_32 ldst_so_reg:$ptr, GPR:$val), 5337226890Sdim (STRrs GPR:$val, ldst_so_reg:$ptr)>; 5338226890Sdimdef : ARMPat<(atomic_store_32 addrmode_imm12:$ptr, GPR:$val), 5339226890Sdim (STRi12 GPR:$val, addrmode_imm12:$ptr)>; 5340226890Sdim 5341226890Sdim 5342221345Sdim//===----------------------------------------------------------------------===// 5343221345Sdim// Thumb Support 5344221345Sdim// 5345221345Sdim 5346221345Sdiminclude "ARMInstrThumb.td" 5347221345Sdim 5348221345Sdim//===----------------------------------------------------------------------===// 5349221345Sdim// Thumb2 Support 5350221345Sdim// 5351221345Sdim 5352221345Sdiminclude "ARMInstrThumb2.td" 5353221345Sdim 5354221345Sdim//===----------------------------------------------------------------------===// 5355221345Sdim// Floating Point Support 5356221345Sdim// 5357221345Sdim 5358221345Sdiminclude "ARMInstrVFP.td" 5359221345Sdim 5360221345Sdim//===----------------------------------------------------------------------===// 5361221345Sdim// Advanced SIMD (NEON) Support 5362221345Sdim// 5363221345Sdim 5364221345Sdiminclude "ARMInstrNEON.td" 5365221345Sdim 5366224145Sdim//===----------------------------------------------------------------------===// 5367224145Sdim// Assembler aliases 5368224145Sdim// 5369224145Sdim 5370224145Sdim// Memory barriers 5371224145Sdimdef : InstAlias<"dmb", (DMB 0xf)>, Requires<[IsARM, HasDB]>; 5372224145Sdimdef : InstAlias<"dsb", (DSB 0xf)>, Requires<[IsARM, HasDB]>; 5373224145Sdimdef : InstAlias<"isb", (ISB 0xf)>, Requires<[IsARM, HasDB]>; 5374224145Sdim 5375224145Sdim// System instructions 5376224145Sdimdef : MnemonicAlias<"swi", "svc">; 5377224145Sdim 5378224145Sdim// Load / Store Multiple 5379224145Sdimdef : MnemonicAlias<"ldmfd", "ldm">; 5380224145Sdimdef : MnemonicAlias<"ldmia", "ldm">; 5381226890Sdimdef : MnemonicAlias<"ldmea", "ldmdb">; 5382224145Sdimdef : MnemonicAlias<"stmfd", "stmdb">; 5383224145Sdimdef : MnemonicAlias<"stmia", "stm">; 5384224145Sdimdef : MnemonicAlias<"stmea", "stm">; 5385224145Sdim 5386226890Sdim// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT when the 5387226890Sdim// shift amount is zero (i.e., unspecified). 5388226890Sdimdef : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm", 5389226890Sdim (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>, 5390226890Sdim Requires<[IsARM, HasV6]>; 5391226890Sdimdef : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm", 5392226890Sdim (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>, 5393226890Sdim Requires<[IsARM, HasV6]>; 5394226890Sdim 5395226890Sdim// PUSH/POP aliases for STM/LDM 5396226890Sdimdef : ARMInstAlias<"push${p} $regs", (STMDB_UPD SP, pred:$p, reglist:$regs)>; 5397226890Sdimdef : ARMInstAlias<"pop${p} $regs", (LDMIA_UPD SP, pred:$p, reglist:$regs)>; 5398226890Sdim 5399226890Sdim// SSAT/USAT optional shift operand. 5400226890Sdimdef : ARMInstAlias<"ssat${p} $Rd, $sat_imm, $Rn", 5401226890Sdim (SSAT GPRnopc:$Rd, imm1_32:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; 5402226890Sdimdef : ARMInstAlias<"usat${p} $Rd, $sat_imm, $Rn", 5403226890Sdim (USAT GPRnopc:$Rd, imm0_31:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; 5404226890Sdim 5405226890Sdim 5406226890Sdim// Extend instruction optional rotate operand. 5407226890Sdimdef : ARMInstAlias<"sxtab${p} $Rd, $Rn, $Rm", 5408226890Sdim (SXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5409226890Sdimdef : ARMInstAlias<"sxtah${p} $Rd, $Rn, $Rm", 5410226890Sdim (SXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5411226890Sdimdef : ARMInstAlias<"sxtab16${p} $Rd, $Rn, $Rm", 5412226890Sdim (SXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5413226890Sdimdef : ARMInstAlias<"sxtb${p} $Rd, $Rm", 5414226890Sdim (SXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5415226890Sdimdef : ARMInstAlias<"sxtb16${p} $Rd, $Rm", 5416226890Sdim (SXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5417226890Sdimdef : ARMInstAlias<"sxth${p} $Rd, $Rm", 5418226890Sdim (SXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5419226890Sdim 5420226890Sdimdef : ARMInstAlias<"uxtab${p} $Rd, $Rn, $Rm", 5421226890Sdim (UXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5422226890Sdimdef : ARMInstAlias<"uxtah${p} $Rd, $Rn, $Rm", 5423226890Sdim (UXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5424226890Sdimdef : ARMInstAlias<"uxtab16${p} $Rd, $Rn, $Rm", 5425226890Sdim (UXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 5426226890Sdimdef : ARMInstAlias<"uxtb${p} $Rd, $Rm", 5427226890Sdim (UXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5428226890Sdimdef : ARMInstAlias<"uxtb16${p} $Rd, $Rm", 5429226890Sdim (UXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5430226890Sdimdef : ARMInstAlias<"uxth${p} $Rd, $Rm", 5431226890Sdim (UXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 5432226890Sdim 5433226890Sdim 5434226890Sdim// RFE aliases 5435226890Sdimdef : MnemonicAlias<"rfefa", "rfeda">; 5436226890Sdimdef : MnemonicAlias<"rfeea", "rfedb">; 5437226890Sdimdef : MnemonicAlias<"rfefd", "rfeia">; 5438226890Sdimdef : MnemonicAlias<"rfeed", "rfeib">; 5439226890Sdimdef : MnemonicAlias<"rfe", "rfeia">; 5440226890Sdim 5441226890Sdim// SRS aliases 5442263509Sdimdef : MnemonicAlias<"srsfa", "srsib">; 5443263509Sdimdef : MnemonicAlias<"srsea", "srsia">; 5444263509Sdimdef : MnemonicAlias<"srsfd", "srsdb">; 5445263509Sdimdef : MnemonicAlias<"srsed", "srsda">; 5446226890Sdimdef : MnemonicAlias<"srs", "srsia">; 5447226890Sdim 5448226890Sdim// QSAX == QSUBADDX 5449226890Sdimdef : MnemonicAlias<"qsubaddx", "qsax">; 5450226890Sdim// SASX == SADDSUBX 5451226890Sdimdef : MnemonicAlias<"saddsubx", "sasx">; 5452226890Sdim// SHASX == SHADDSUBX 5453226890Sdimdef : MnemonicAlias<"shaddsubx", "shasx">; 5454226890Sdim// SHSAX == SHSUBADDX 5455226890Sdimdef : MnemonicAlias<"shsubaddx", "shsax">; 5456226890Sdim// SSAX == SSUBADDX 5457226890Sdimdef : MnemonicAlias<"ssubaddx", "ssax">; 5458226890Sdim// UASX == UADDSUBX 5459226890Sdimdef : MnemonicAlias<"uaddsubx", "uasx">; 5460226890Sdim// UHASX == UHADDSUBX 5461226890Sdimdef : MnemonicAlias<"uhaddsubx", "uhasx">; 5462226890Sdim// UHSAX == UHSUBADDX 5463226890Sdimdef : MnemonicAlias<"uhsubaddx", "uhsax">; 5464226890Sdim// UQASX == UQADDSUBX 5465226890Sdimdef : MnemonicAlias<"uqaddsubx", "uqasx">; 5466226890Sdim// UQSAX == UQSUBADDX 5467226890Sdimdef : MnemonicAlias<"uqsubaddx", "uqsax">; 5468226890Sdim// USAX == USUBADDX 5469226890Sdimdef : MnemonicAlias<"usubaddx", "usax">; 5470226890Sdim 5471235633Sdim// "mov Rd, so_imm_not" can be handled via "mvn" in assembly, just like 5472235633Sdim// for isel. 5473235633Sdimdef : ARMInstAlias<"mov${s}${p} $Rd, $imm", 5474235633Sdim (MVNi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>; 5475235633Sdimdef : ARMInstAlias<"mvn${s}${p} $Rd, $imm", 5476235633Sdim (MOVi rGPR:$Rd, so_imm_not:$imm, pred:$p, cc_out:$s)>; 5477235633Sdim// Same for AND <--> BIC 5478235633Sdimdef : ARMInstAlias<"bic${s}${p} $Rd, $Rn, $imm", 5479235633Sdim (ANDri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm, 5480235633Sdim pred:$p, cc_out:$s)>; 5481235633Sdimdef : ARMInstAlias<"bic${s}${p} $Rdn, $imm", 5482235633Sdim (ANDri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm, 5483235633Sdim pred:$p, cc_out:$s)>; 5484235633Sdimdef : ARMInstAlias<"and${s}${p} $Rd, $Rn, $imm", 5485235633Sdim (BICri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm, 5486235633Sdim pred:$p, cc_out:$s)>; 5487235633Sdimdef : ARMInstAlias<"and${s}${p} $Rdn, $imm", 5488235633Sdim (BICri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm, 5489235633Sdim pred:$p, cc_out:$s)>; 5490235633Sdim 5491235633Sdim// Likewise, "add Rd, so_imm_neg" -> sub 5492235633Sdimdef : ARMInstAlias<"add${s}${p} $Rd, $Rn, $imm", 5493235633Sdim (SUBri GPR:$Rd, GPR:$Rn, so_imm_neg:$imm, pred:$p, cc_out:$s)>; 5494235633Sdimdef : ARMInstAlias<"add${s}${p} $Rd, $imm", 5495235633Sdim (SUBri GPR:$Rd, GPR:$Rd, so_imm_neg:$imm, pred:$p, cc_out:$s)>; 5496235633Sdim// Same for CMP <--> CMN via so_imm_neg 5497235633Sdimdef : ARMInstAlias<"cmp${p} $Rd, $imm", 5498245431Sdim (CMNri rGPR:$Rd, so_imm_neg:$imm, pred:$p)>; 5499235633Sdimdef : ARMInstAlias<"cmn${p} $Rd, $imm", 5500235633Sdim (CMPri rGPR:$Rd, so_imm_neg:$imm, pred:$p)>; 5501235633Sdim 5502235633Sdim// The shifter forms of the MOV instruction are aliased to the ASR, LSL, 5503235633Sdim// LSR, ROR, and RRX instructions. 5504235633Sdim// FIXME: We need C++ parser hooks to map the alias to the MOV 5505235633Sdim// encoding. It seems we should be able to do that sort of thing 5506235633Sdim// in tblgen, but it could get ugly. 5507245431Sdimlet TwoOperandAliasConstraint = "$Rm = $Rd" in { 5508235633Sdimdef ASRi : ARMAsmPseudo<"asr${s}${p} $Rd, $Rm, $imm", 5509235633Sdim (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p, 5510235633Sdim cc_out:$s)>; 5511235633Sdimdef LSRi : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rm, $imm", 5512235633Sdim (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p, 5513235633Sdim cc_out:$s)>; 5514235633Sdimdef LSLi : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rm, $imm", 5515235633Sdim (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p, 5516235633Sdim cc_out:$s)>; 5517235633Sdimdef RORi : ARMAsmPseudo<"ror${s}${p} $Rd, $Rm, $imm", 5518235633Sdim (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p, 5519235633Sdim cc_out:$s)>; 5520245431Sdim} 5521235633Sdimdef RRXi : ARMAsmPseudo<"rrx${s}${p} $Rd, $Rm", 5522263509Sdim (ins GPR:$Rd, GPR:$Rm, pred:$p, cc_out:$s)>; 5523245431Sdimlet TwoOperandAliasConstraint = "$Rn = $Rd" in { 5524235633Sdimdef ASRr : ARMAsmPseudo<"asr${s}${p} $Rd, $Rn, $Rm", 5525235633Sdim (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 5526235633Sdim cc_out:$s)>; 5527235633Sdimdef LSRr : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rn, $Rm", 5528235633Sdim (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 5529235633Sdim cc_out:$s)>; 5530235633Sdimdef LSLr : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rn, $Rm", 5531235633Sdim (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 5532235633Sdim cc_out:$s)>; 5533235633Sdimdef RORr : ARMAsmPseudo<"ror${s}${p} $Rd, $Rn, $Rm", 5534235633Sdim (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 5535235633Sdim cc_out:$s)>; 5536245431Sdim} 5537235633Sdim 5538235633Sdim// "neg" is and alias for "rsb rd, rn, #0" 5539235633Sdimdef : ARMInstAlias<"neg${s}${p} $Rd, $Rm", 5540235633Sdim (RSBri GPR:$Rd, GPR:$Rm, 0, pred:$p, cc_out:$s)>; 5541235633Sdim 5542235633Sdim// Pre-v6, 'mov r0, r0' was used as a NOP encoding. 5543235633Sdimdef : InstAlias<"nop${p}", (MOVr R0, R0, pred:$p, zero_reg)>, 5544235633Sdim Requires<[IsARM, NoV6]>; 5545235633Sdim 5546235633Sdim// UMULL/SMULL are available on all arches, but the instruction definitions 5547235633Sdim// need difference constraints pre-v6. Use these aliases for the assembly 5548235633Sdim// parsing on pre-v6. 5549235633Sdimdef : InstAlias<"smull${s}${p} $RdLo, $RdHi, $Rn, $Rm", 5550235633Sdim (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 5551235633Sdim Requires<[IsARM, NoV6]>; 5552235633Sdimdef : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm", 5553235633Sdim (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 5554235633Sdim Requires<[IsARM, NoV6]>; 5555235633Sdim 5556235633Sdim// 'it' blocks in ARM mode just validate the predicates. The IT itself 5557235633Sdim// is discarded. 5558263509Sdimdef ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>, 5559263509Sdim ComplexDeprecationPredicate<"IT">; 5560