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