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