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