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