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 3660// This gets lowered to a single 4-byte instructions 3661let Size = 4 in 3662def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 3663 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>, 3664 Sched<[WriteALU]>; 3665 3666let Constraints = "$src = $Rd" in { 3667def MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd), 3668 (ins GPR:$src, imm0_65535_expr:$imm), 3669 DPFrm, IIC_iMOVi, 3670 "movt", "\t$Rd, $imm", 3671 [(set GPRnopc:$Rd, 3672 (or (and GPR:$src, 0xffff), 3673 lo16AllZero:$imm))]>, UnaryDP, 3674 Requires<[IsARM, HasV6T2]>, Sched<[WriteALU]> { 3675 bits<4> Rd; 3676 bits<16> imm; 3677 let Inst{15-12} = Rd; 3678 let Inst{11-0} = imm{11-0}; 3679 let Inst{19-16} = imm{15-12}; 3680 let Inst{20} = 0; 3681 let Inst{25} = 1; 3682 let DecoderMethod = "DecodeArmMOVTWInstruction"; 3683} 3684 3685// This gets lowered to a single 4-byte instructions 3686let Size = 4 in 3687def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 3688 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>, 3689 Sched<[WriteALU]>; 3690 3691} // Constraints 3692 3693def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, 3694 Requires<[IsARM, HasV6T2]>; 3695 3696let Uses = [CPSR] in 3697def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, 3698 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP, 3699 Requires<[IsARM]>, Sched<[WriteALU]>; 3700 3701// These aren't really mov instructions, but we have to define them this way 3702// due to flag operands. 3703 3704let Defs = [CPSR] in { 3705def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 3706 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP, 3707 Sched<[WriteALU]>, Requires<[IsARM]>; 3708def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 3709 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP, 3710 Sched<[WriteALU]>, Requires<[IsARM]>; 3711} 3712 3713//===----------------------------------------------------------------------===// 3714// Extend Instructions. 3715// 3716 3717// Sign extenders 3718 3719def SXTB : AI_ext_rrot<0b01101010, 3720 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; 3721def SXTH : AI_ext_rrot<0b01101011, 3722 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; 3723 3724def SXTAB : AI_exta_rrot<0b01101010, 3725 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 3726def SXTAH : AI_exta_rrot<0b01101011, 3727 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 3728 3729def : ARMV6Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, rot_imm:$rot), i8)), 3730 (SXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; 3731def : ARMV6Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, imm8_or_16:$rot), 3732 i16)), 3733 (SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; 3734 3735def SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">; 3736def : ARMV6Pat<(int_arm_sxtb16 GPR:$Src), 3737 (SXTB16 GPR:$Src, 0)>; 3738def : ARMV6Pat<(int_arm_sxtb16 (rotr GPR:$Src, rot_imm:$rot)), 3739 (SXTB16 GPR:$Src, rot_imm:$rot)>; 3740 3741def SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">; 3742def : ARMV6Pat<(int_arm_sxtab16 GPR:$LHS, GPR:$RHS), 3743 (SXTAB16 GPR:$LHS, GPR:$RHS, 0)>; 3744def : ARMV6Pat<(int_arm_sxtab16 GPR:$LHS, (rotr GPR:$RHS, rot_imm:$rot)), 3745 (SXTAB16 GPR:$LHS, GPR:$RHS, rot_imm:$rot)>; 3746 3747// Zero extenders 3748 3749let AddedComplexity = 16 in { 3750def UXTB : AI_ext_rrot<0b01101110, 3751 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; 3752def UXTH : AI_ext_rrot<0b01101111, 3753 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 3754def UXTB16 : AI_ext_rrot<0b01101100, 3755 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 3756 3757// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 3758// The transformation should probably be done as a combiner action 3759// instead so we can include a check for masking back in the upper 3760// eight bits of the source into the lower eight bits of the result. 3761//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), 3762// (UXTB16r_rot GPR:$Src, 3)>; 3763def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), 3764 (UXTB16 GPR:$Src, 1)>; 3765def : ARMV6Pat<(int_arm_uxtb16 GPR:$Src), 3766 (UXTB16 GPR:$Src, 0)>; 3767def : ARMV6Pat<(int_arm_uxtb16 (rotr GPR:$Src, rot_imm:$rot)), 3768 (UXTB16 GPR:$Src, rot_imm:$rot)>; 3769 3770def UXTAB : AI_exta_rrot<0b01101110, "uxtab", 3771 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 3772def UXTAH : AI_exta_rrot<0b01101111, "uxtah", 3773 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 3774 3775def : ARMV6Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, rot_imm:$rot), 0xFF)), 3776 (UXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; 3777def : ARMV6Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot), 0xFFFF)), 3778 (UXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; 3779} 3780 3781// This isn't safe in general, the add is two 16-bit units, not a 32-bit add. 3782def UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; 3783def : ARMV6Pat<(int_arm_uxtab16 GPR:$LHS, GPR:$RHS), 3784 (UXTAB16 GPR:$LHS, GPR:$RHS, 0)>; 3785def : ARMV6Pat<(int_arm_uxtab16 GPR:$LHS, (rotr GPR:$RHS, rot_imm:$rot)), 3786 (UXTAB16 GPR:$LHS, GPR:$RHS, rot_imm:$rot)>; 3787 3788 3789def SBFX : I<(outs GPRnopc:$Rd), 3790 (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width), 3791 AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3792 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 3793 Requires<[IsARM, HasV6T2]> { 3794 bits<4> Rd; 3795 bits<4> Rn; 3796 bits<5> lsb; 3797 bits<5> width; 3798 let Inst{27-21} = 0b0111101; 3799 let Inst{6-4} = 0b101; 3800 let Inst{20-16} = width; 3801 let Inst{15-12} = Rd; 3802 let Inst{11-7} = lsb; 3803 let Inst{3-0} = Rn; 3804} 3805 3806def UBFX : I<(outs GPRnopc:$Rd), 3807 (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width), 3808 AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 3809 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 3810 Requires<[IsARM, HasV6T2]> { 3811 bits<4> Rd; 3812 bits<4> Rn; 3813 bits<5> lsb; 3814 bits<5> width; 3815 let Inst{27-21} = 0b0111111; 3816 let Inst{6-4} = 0b101; 3817 let Inst{20-16} = width; 3818 let Inst{15-12} = Rd; 3819 let Inst{11-7} = lsb; 3820 let Inst{3-0} = Rn; 3821} 3822 3823//===----------------------------------------------------------------------===// 3824// Arithmetic Instructions. 3825// 3826 3827let isAdd = 1 in 3828defm ADD : AsI1_bin_irs<0b0100, "add", 3829 IIC_iALUi, IIC_iALUr, IIC_iALUsr, add, 1>; 3830defm SUB : AsI1_bin_irs<0b0010, "sub", 3831 IIC_iALUi, IIC_iALUr, IIC_iALUsr, sub>; 3832 3833// ADD and SUB with 's' bit set. 3834// 3835// Currently, ADDS/SUBS are pseudo opcodes that exist only in the 3836// selection DAG. They are "lowered" to real ADD/SUB opcodes by 3837// AdjustInstrPostInstrSelection where we determine whether or not to 3838// set the "s" bit based on CPSR liveness. 3839// 3840// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen 3841// support for an optional CPSR definition that corresponds to the DAG 3842// node's second value. We can then eliminate the implicit def of CPSR. 3843let isAdd = 1 in 3844defm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMaddc, 1>; 3845defm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMsubc>; 3846 3847def : ARMPat<(ARMsubs GPR:$Rn, mod_imm:$imm), (SUBSri $Rn, mod_imm:$imm)>; 3848def : ARMPat<(ARMsubs GPR:$Rn, GPR:$Rm), (SUBSrr $Rn, $Rm)>; 3849def : ARMPat<(ARMsubs GPR:$Rn, so_reg_imm:$shift), 3850 (SUBSrsi $Rn, so_reg_imm:$shift)>; 3851def : ARMPat<(ARMsubs GPR:$Rn, so_reg_reg:$shift), 3852 (SUBSrsr $Rn, so_reg_reg:$shift)>; 3853 3854 3855let isAdd = 1 in 3856defm ADC : AI1_adde_sube_irs<0b0101, "adc", ARMadde, 1>; 3857defm SBC : AI1_adde_sube_irs<0b0110, "sbc", ARMsube>; 3858 3859defm RSB : AsI1_rbin_irs<0b0011, "rsb", 3860 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 3861 sub>; 3862 3863// FIXME: Eliminate them if we can write def : Pat patterns which defines 3864// CPSR and the implicit def of CPSR is not needed. 3865defm RSBS : AsI1_rbin_s_is<IIC_iALUi, IIC_iALUsr, ARMsubc>; 3866 3867defm RSC : AI1_rsc_irs<0b0111, "rsc", ARMsube>; 3868 3869// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 3870// The assume-no-carry-in form uses the negation of the input since add/sub 3871// assume opposite meanings of the carry flag (i.e., carry == !borrow). 3872// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 3873// details. 3874def : ARMPat<(add GPR:$src, mod_imm_neg:$imm), 3875 (SUBri GPR:$src, mod_imm_neg:$imm)>; 3876def : ARMPat<(ARMaddc GPR:$src, mod_imm_neg:$imm), 3877 (SUBSri GPR:$src, mod_imm_neg:$imm)>; 3878 3879def : ARMPat<(add GPR:$src, imm0_65535_neg:$imm), 3880 (SUBrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>, 3881 Requires<[IsARM, HasV6T2]>; 3882def : ARMPat<(ARMaddc GPR:$src, imm0_65535_neg:$imm), 3883 (SUBSrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>, 3884 Requires<[IsARM, HasV6T2]>; 3885 3886// The with-carry-in form matches bitwise not instead of the negation. 3887// Effectively, the inverse interpretation of the carry flag already accounts 3888// for part of the negation. 3889def : ARMPat<(ARMadde GPR:$src, mod_imm_not:$imm, CPSR), 3890 (SBCri GPR:$src, mod_imm_not:$imm)>; 3891def : ARMPat<(ARMadde GPR:$src, imm0_65535_neg:$imm, CPSR), 3892 (SBCrr GPR:$src, (MOVi16 (imm_not_XFORM imm:$imm)))>, 3893 Requires<[IsARM, HasV6T2]>; 3894 3895// Note: These are implemented in C++ code, because they have to generate 3896// ADD/SUBrs instructions, which use a complex pattern that a xform function 3897// cannot produce. 3898// (mul X, 2^n+1) -> (add (X << n), X) 3899// (mul X, 2^n-1) -> (rsb X, (X << n)) 3900 3901// ARM Arithmetic Instruction 3902// GPR:$dst = GPR:$a op GPR:$b 3903class AAI<bits<8> op27_20, bits<8> op11_4, string opc, 3904 list<dag> pattern = [], 3905 dag iops = (ins GPRnopc:$Rn, GPRnopc:$Rm), 3906 string asm = "\t$Rd, $Rn, $Rm"> 3907 : AI<(outs GPRnopc:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern>, 3908 Sched<[WriteALU, ReadALU, ReadALU]> { 3909 bits<4> Rn; 3910 bits<4> Rd; 3911 bits<4> Rm; 3912 let Inst{27-20} = op27_20; 3913 let Inst{11-4} = op11_4; 3914 let Inst{19-16} = Rn; 3915 let Inst{15-12} = Rd; 3916 let Inst{3-0} = Rm; 3917 3918 let Unpredictable{11-8} = 0b1111; 3919} 3920 3921// Wrappers around the AAI class 3922class AAIRevOpr<bits<8> op27_20, bits<8> op11_4, string opc, 3923 list<dag> pattern = []> 3924 : AAI<op27_20, op11_4, opc, 3925 pattern, 3926 (ins GPRnopc:$Rm, GPRnopc:$Rn), 3927 "\t$Rd, $Rm, $Rn">; 3928 3929class AAIIntrinsic<bits<8> op27_20, bits<8> op11_4, string opc, 3930 Intrinsic intrinsic> 3931 : AAI<op27_20, op11_4, opc, 3932 [(set GPRnopc:$Rd, (intrinsic GPRnopc:$Rn, GPRnopc:$Rm))]>; 3933 3934// Saturating add/subtract 3935let hasSideEffects = 1 in { 3936def QADD8 : AAIIntrinsic<0b01100010, 0b11111001, "qadd8", int_arm_qadd8>; 3937def QADD16 : AAIIntrinsic<0b01100010, 0b11110001, "qadd16", int_arm_qadd16>; 3938def QSUB16 : AAIIntrinsic<0b01100010, 0b11110111, "qsub16", int_arm_qsub16>; 3939def QSUB8 : AAIIntrinsic<0b01100010, 0b11111111, "qsub8", int_arm_qsub8>; 3940 3941def QDADD : AAIRevOpr<0b00010100, 0b00000101, "qdadd", 3942 [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, 3943 (int_arm_qadd GPRnopc:$Rn, GPRnopc:$Rn)))]>; 3944def QDSUB : AAIRevOpr<0b00010110, 0b00000101, "qdsub", 3945 [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, 3946 (int_arm_qadd GPRnopc:$Rn, GPRnopc:$Rn)))]>; 3947def QSUB : AAIRevOpr<0b00010010, 0b00000101, "qsub", 3948 [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))]>; 3949let DecoderMethod = "DecodeQADDInstruction" in 3950 def QADD : AAIRevOpr<0b00010000, 0b00000101, "qadd", 3951 [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))]>; 3952} 3953 3954def : ARMV5TEPat<(saddsat GPR:$a, GPR:$b), 3955 (QADD GPR:$a, GPR:$b)>; 3956def : ARMV5TEPat<(ssubsat GPR:$a, GPR:$b), 3957 (QSUB GPR:$a, GPR:$b)>; 3958def : ARMV5TEPat<(saddsat rGPR:$Rm, (saddsat rGPR:$Rn, rGPR:$Rn)), 3959 (QDADD rGPR:$Rm, rGPR:$Rn)>; 3960def : ARMV5TEPat<(ssubsat rGPR:$Rm, (saddsat rGPR:$Rn, rGPR:$Rn)), 3961 (QDSUB rGPR:$Rm, rGPR:$Rn)>; 3962 3963def : ARMV6Pat<(ARMqadd8b rGPR:$Rm, rGPR:$Rn), 3964 (QADD8 rGPR:$Rm, rGPR:$Rn)>; 3965def : ARMV6Pat<(ARMqsub8b rGPR:$Rm, rGPR:$Rn), 3966 (QSUB8 rGPR:$Rm, rGPR:$Rn)>; 3967def : ARMV6Pat<(ARMqadd16b rGPR:$Rm, rGPR:$Rn), 3968 (QADD16 rGPR:$Rm, rGPR:$Rn)>; 3969def : ARMV6Pat<(ARMqsub16b rGPR:$Rm, rGPR:$Rn), 3970 (QSUB16 rGPR:$Rm, rGPR:$Rn)>; 3971 3972def UQADD16 : AAIIntrinsic<0b01100110, 0b11110001, "uqadd16", int_arm_uqadd16>; 3973def UQADD8 : AAIIntrinsic<0b01100110, 0b11111001, "uqadd8", int_arm_uqadd8>; 3974def UQSUB16 : AAIIntrinsic<0b01100110, 0b11110111, "uqsub16", int_arm_uqsub16>; 3975def UQSUB8 : AAIIntrinsic<0b01100110, 0b11111111, "uqsub8", int_arm_uqsub8>; 3976def QASX : AAIIntrinsic<0b01100010, 0b11110011, "qasx", int_arm_qasx>; 3977def QSAX : AAIIntrinsic<0b01100010, 0b11110101, "qsax", int_arm_qsax>; 3978def UQASX : AAIIntrinsic<0b01100110, 0b11110011, "uqasx", int_arm_uqasx>; 3979def UQSAX : AAIIntrinsic<0b01100110, 0b11110101, "uqsax", int_arm_uqsax>; 3980 3981def : ARMV6Pat<(ARMuqadd8b rGPR:$Rm, rGPR:$Rn), 3982 (UQADD8 rGPR:$Rm, rGPR:$Rn)>; 3983def : ARMV6Pat<(ARMuqsub8b rGPR:$Rm, rGPR:$Rn), 3984 (UQSUB8 rGPR:$Rm, rGPR:$Rn)>; 3985def : ARMV6Pat<(ARMuqadd16b rGPR:$Rm, rGPR:$Rn), 3986 (UQADD16 rGPR:$Rm, rGPR:$Rn)>; 3987def : ARMV6Pat<(ARMuqsub16b rGPR:$Rm, rGPR:$Rn), 3988 (UQSUB16 rGPR:$Rm, rGPR:$Rn)>; 3989 3990 3991// Signed/Unsigned add/subtract 3992 3993def SASX : AAIIntrinsic<0b01100001, 0b11110011, "sasx", int_arm_sasx>; 3994def SADD16 : AAIIntrinsic<0b01100001, 0b11110001, "sadd16", int_arm_sadd16>; 3995def SADD8 : AAIIntrinsic<0b01100001, 0b11111001, "sadd8", int_arm_sadd8>; 3996def SSAX : AAIIntrinsic<0b01100001, 0b11110101, "ssax", int_arm_ssax>; 3997def SSUB16 : AAIIntrinsic<0b01100001, 0b11110111, "ssub16", int_arm_ssub16>; 3998def SSUB8 : AAIIntrinsic<0b01100001, 0b11111111, "ssub8", int_arm_ssub8>; 3999def UASX : AAIIntrinsic<0b01100101, 0b11110011, "uasx", int_arm_uasx>; 4000def UADD16 : AAIIntrinsic<0b01100101, 0b11110001, "uadd16", int_arm_uadd16>; 4001def UADD8 : AAIIntrinsic<0b01100101, 0b11111001, "uadd8", int_arm_uadd8>; 4002def USAX : AAIIntrinsic<0b01100101, 0b11110101, "usax", int_arm_usax>; 4003def USUB16 : AAIIntrinsic<0b01100101, 0b11110111, "usub16", int_arm_usub16>; 4004def USUB8 : AAIIntrinsic<0b01100101, 0b11111111, "usub8", int_arm_usub8>; 4005 4006// Signed/Unsigned halving add/subtract 4007 4008def SHASX : AAIIntrinsic<0b01100011, 0b11110011, "shasx", int_arm_shasx>; 4009def SHADD16 : AAIIntrinsic<0b01100011, 0b11110001, "shadd16", int_arm_shadd16>; 4010def SHADD8 : AAIIntrinsic<0b01100011, 0b11111001, "shadd8", int_arm_shadd8>; 4011def SHSAX : AAIIntrinsic<0b01100011, 0b11110101, "shsax", int_arm_shsax>; 4012def SHSUB16 : AAIIntrinsic<0b01100011, 0b11110111, "shsub16", int_arm_shsub16>; 4013def SHSUB8 : AAIIntrinsic<0b01100011, 0b11111111, "shsub8", int_arm_shsub8>; 4014def UHASX : AAIIntrinsic<0b01100111, 0b11110011, "uhasx", int_arm_uhasx>; 4015def UHADD16 : AAIIntrinsic<0b01100111, 0b11110001, "uhadd16", int_arm_uhadd16>; 4016def UHADD8 : AAIIntrinsic<0b01100111, 0b11111001, "uhadd8", int_arm_uhadd8>; 4017def UHSAX : AAIIntrinsic<0b01100111, 0b11110101, "uhsax", int_arm_uhsax>; 4018def UHSUB16 : AAIIntrinsic<0b01100111, 0b11110111, "uhsub16", int_arm_uhsub16>; 4019def UHSUB8 : AAIIntrinsic<0b01100111, 0b11111111, "uhsub8", int_arm_uhsub8>; 4020 4021// Unsigned Sum of Absolute Differences [and Accumulate]. 4022 4023def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4024 MulFrm /* for convenience */, NoItinerary, "usad8", 4025 "\t$Rd, $Rn, $Rm", 4026 [(set GPR:$Rd, (int_arm_usad8 GPR:$Rn, GPR:$Rm))]>, 4027 Requires<[IsARM, HasV6]>, Sched<[WriteALU, ReadALU, ReadALU]> { 4028 bits<4> Rd; 4029 bits<4> Rn; 4030 bits<4> Rm; 4031 let Inst{27-20} = 0b01111000; 4032 let Inst{15-12} = 0b1111; 4033 let Inst{7-4} = 0b0001; 4034 let Inst{19-16} = Rd; 4035 let Inst{11-8} = Rm; 4036 let Inst{3-0} = Rn; 4037} 4038def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 4039 MulFrm /* for convenience */, NoItinerary, "usada8", 4040 "\t$Rd, $Rn, $Rm, $Ra", 4041 [(set GPR:$Rd, (int_arm_usada8 GPR:$Rn, GPR:$Rm, GPR:$Ra))]>, 4042 Requires<[IsARM, HasV6]>, Sched<[WriteALU, ReadALU, ReadALU]>{ 4043 bits<4> Rd; 4044 bits<4> Rn; 4045 bits<4> Rm; 4046 bits<4> Ra; 4047 let Inst{27-20} = 0b01111000; 4048 let Inst{7-4} = 0b0001; 4049 let Inst{19-16} = Rd; 4050 let Inst{15-12} = Ra; 4051 let Inst{11-8} = Rm; 4052 let Inst{3-0} = Rn; 4053} 4054 4055// Signed/Unsigned saturate 4056def SSAT : AI<(outs GPRnopc:$Rd), 4057 (ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), 4058 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []>, 4059 Requires<[IsARM,HasV6]>{ 4060 bits<4> Rd; 4061 bits<5> sat_imm; 4062 bits<4> Rn; 4063 bits<8> sh; 4064 let Inst{27-21} = 0b0110101; 4065 let Inst{5-4} = 0b01; 4066 let Inst{20-16} = sat_imm; 4067 let Inst{15-12} = Rd; 4068 let Inst{11-7} = sh{4-0}; 4069 let Inst{6} = sh{5}; 4070 let Inst{3-0} = Rn; 4071} 4072 4073def SSAT16 : AI<(outs GPRnopc:$Rd), 4074 (ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm, 4075 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []>, 4076 Requires<[IsARM,HasV6]>{ 4077 bits<4> Rd; 4078 bits<4> sat_imm; 4079 bits<4> Rn; 4080 let Inst{27-20} = 0b01101010; 4081 let Inst{11-4} = 0b11110011; 4082 let Inst{15-12} = Rd; 4083 let Inst{19-16} = sat_imm; 4084 let Inst{3-0} = Rn; 4085} 4086 4087def USAT : AI<(outs GPRnopc:$Rd), 4088 (ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), 4089 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []>, 4090 Requires<[IsARM,HasV6]> { 4091 bits<4> Rd; 4092 bits<5> sat_imm; 4093 bits<4> Rn; 4094 bits<8> sh; 4095 let Inst{27-21} = 0b0110111; 4096 let Inst{5-4} = 0b01; 4097 let Inst{15-12} = Rd; 4098 let Inst{11-7} = sh{4-0}; 4099 let Inst{6} = sh{5}; 4100 let Inst{20-16} = sat_imm; 4101 let Inst{3-0} = Rn; 4102} 4103 4104def USAT16 : AI<(outs GPRnopc:$Rd), 4105 (ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm, 4106 NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []>, 4107 Requires<[IsARM,HasV6]>{ 4108 bits<4> Rd; 4109 bits<4> sat_imm; 4110 bits<4> Rn; 4111 let Inst{27-20} = 0b01101110; 4112 let Inst{11-4} = 0b11110011; 4113 let Inst{15-12} = Rd; 4114 let Inst{19-16} = sat_imm; 4115 let Inst{3-0} = Rn; 4116} 4117 4118def : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm1_32:$pos), 4119 (SSAT imm1_32:$pos, GPRnopc:$a, 0)>; 4120def : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm0_31:$pos), 4121 (USAT imm0_31:$pos, GPRnopc:$a, 0)>; 4122def : ARMPat<(ARMssat GPRnopc:$Rn, imm0_31:$imm), 4123 (SSAT imm0_31:$imm, GPRnopc:$Rn, 0)>; 4124def : ARMPat<(ARMusat GPRnopc:$Rn, imm0_31:$imm), 4125 (USAT imm0_31:$imm, GPRnopc:$Rn, 0)>; 4126def : ARMV6Pat<(int_arm_ssat16 GPRnopc:$a, imm1_16:$pos), 4127 (SSAT16 imm1_16:$pos, GPRnopc:$a)>; 4128def : ARMV6Pat<(int_arm_usat16 GPRnopc:$a, imm0_15:$pos), 4129 (USAT16 imm0_15:$pos, GPRnopc:$a)>; 4130def : ARMV6Pat<(int_arm_ssat (shl GPRnopc:$a, imm0_31:$shft), imm1_32:$pos), 4131 (SSAT imm1_32:$pos, GPRnopc:$a, imm0_31:$shft)>; 4132def : ARMV6Pat<(int_arm_ssat (sra GPRnopc:$a, asr_imm:$shft), imm1_32:$pos), 4133 (SSAT imm1_32:$pos, GPRnopc:$a, asr_imm:$shft)>; 4134def : ARMV6Pat<(int_arm_usat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos), 4135 (USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>; 4136def : ARMV6Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos), 4137 (USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>; 4138def : ARMPat<(ARMssat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos), 4139 (SSAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>; 4140def : ARMPat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos), 4141 (SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>; 4142def : ARMPat<(ARMusat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos), 4143 (USAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>; 4144def : ARMPat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos), 4145 (USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>; 4146 4147 4148//===----------------------------------------------------------------------===// 4149// Bitwise Instructions. 4150// 4151 4152defm AND : AsI1_bin_irs<0b0000, "and", 4153 IIC_iBITi, IIC_iBITr, IIC_iBITsr, and, 1>; 4154defm ORR : AsI1_bin_irs<0b1100, "orr", 4155 IIC_iBITi, IIC_iBITr, IIC_iBITsr, or, 1>; 4156defm EOR : AsI1_bin_irs<0b0001, "eor", 4157 IIC_iBITi, IIC_iBITr, IIC_iBITsr, xor, 1>; 4158defm BIC : AsI1_bin_irs<0b1110, "bic", 4159 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 4160 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 4161 4162// FIXME: bf_inv_mask_imm should be two operands, the lsb and the msb, just 4163// like in the actual instruction encoding. The complexity of mapping the mask 4164// to the lsb/msb pair should be handled by ISel, not encapsulated in the 4165// instruction description. 4166def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm), 4167 AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 4168 "bfc", "\t$Rd, $imm", "$src = $Rd", 4169 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>, 4170 Requires<[IsARM, HasV6T2]> { 4171 bits<4> Rd; 4172 bits<10> imm; 4173 let Inst{27-21} = 0b0111110; 4174 let Inst{6-0} = 0b0011111; 4175 let Inst{15-12} = Rd; 4176 let Inst{11-7} = imm{4-0}; // lsb 4177 let Inst{20-16} = imm{9-5}; // msb 4178} 4179 4180// A8.6.18 BFI - Bitfield insert (Encoding A1) 4181def BFI:I<(outs GPRnopc:$Rd), (ins GPRnopc:$src, GPR:$Rn, bf_inv_mask_imm:$imm), 4182 AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 4183 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd", 4184 [(set GPRnopc:$Rd, (ARMbfi GPRnopc:$src, GPR:$Rn, 4185 bf_inv_mask_imm:$imm))]>, 4186 Requires<[IsARM, HasV6T2]> { 4187 bits<4> Rd; 4188 bits<4> Rn; 4189 bits<10> imm; 4190 let Inst{27-21} = 0b0111110; 4191 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 4192 let Inst{15-12} = Rd; 4193 let Inst{11-7} = imm{4-0}; // lsb 4194 let Inst{20-16} = imm{9-5}; // width 4195 let Inst{3-0} = Rn; 4196} 4197 4198def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr, 4199 "mvn", "\t$Rd, $Rm", 4200 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP, Sched<[WriteALU]> { 4201 bits<4> Rd; 4202 bits<4> Rm; 4203 let Inst{25} = 0; 4204 let Inst{19-16} = 0b0000; 4205 let Inst{11-4} = 0b00000000; 4206 let Inst{15-12} = Rd; 4207 let Inst{3-0} = Rm; 4208 4209 let Unpredictable{19-16} = 0b1111; 4210} 4211def MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), 4212 DPSoRegImmFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", 4213 [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP, 4214 Sched<[WriteALU]> { 4215 bits<4> Rd; 4216 bits<12> shift; 4217 let Inst{25} = 0; 4218 let Inst{19-16} = 0b0000; 4219 let Inst{15-12} = Rd; 4220 let Inst{11-5} = shift{11-5}; 4221 let Inst{4} = 0; 4222 let Inst{3-0} = shift{3-0}; 4223 4224 let Unpredictable{19-16} = 0b1111; 4225} 4226def MVNsr : AsI1<0b1111, (outs GPRnopc:$Rd), (ins so_reg_reg:$shift), 4227 DPSoRegRegFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", 4228 [(set GPRnopc:$Rd, (not so_reg_reg:$shift))]>, UnaryDP, 4229 Sched<[WriteALU]> { 4230 bits<4> Rd; 4231 bits<12> shift; 4232 let Inst{25} = 0; 4233 let Inst{19-16} = 0b0000; 4234 let Inst{15-12} = Rd; 4235 let Inst{11-8} = shift{11-8}; 4236 let Inst{7} = 0; 4237 let Inst{6-5} = shift{6-5}; 4238 let Inst{4} = 1; 4239 let Inst{3-0} = shift{3-0}; 4240 4241 let Unpredictable{19-16} = 0b1111; 4242} 4243let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 4244def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins mod_imm:$imm), DPFrm, 4245 IIC_iMVNi, "mvn", "\t$Rd, $imm", 4246 [(set GPR:$Rd, mod_imm_not:$imm)]>,UnaryDP, Sched<[WriteALU]> { 4247 bits<4> Rd; 4248 bits<12> imm; 4249 let Inst{25} = 1; 4250 let Inst{19-16} = 0b0000; 4251 let Inst{15-12} = Rd; 4252 let Inst{11-0} = imm; 4253} 4254 4255let AddedComplexity = 1 in 4256def : ARMPat<(and GPR:$src, mod_imm_not:$imm), 4257 (BICri GPR:$src, mod_imm_not:$imm)>; 4258 4259//===----------------------------------------------------------------------===// 4260// Multiply Instructions. 4261// 4262class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 4263 string opc, string asm, list<dag> pattern> 4264 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 4265 bits<4> Rd; 4266 bits<4> Rm; 4267 bits<4> Rn; 4268 let Inst{19-16} = Rd; 4269 let Inst{11-8} = Rm; 4270 let Inst{3-0} = Rn; 4271} 4272class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 4273 string opc, string asm, list<dag> pattern> 4274 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 4275 bits<4> RdLo; 4276 bits<4> RdHi; 4277 bits<4> Rm; 4278 bits<4> Rn; 4279 let Inst{19-16} = RdHi; 4280 let Inst{15-12} = RdLo; 4281 let Inst{11-8} = Rm; 4282 let Inst{3-0} = Rn; 4283} 4284class AsMla1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 4285 string opc, string asm, list<dag> pattern> 4286 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 4287 bits<4> RdLo; 4288 bits<4> RdHi; 4289 bits<4> Rm; 4290 bits<4> Rn; 4291 let Inst{19-16} = RdHi; 4292 let Inst{15-12} = RdLo; 4293 let Inst{11-8} = Rm; 4294 let Inst{3-0} = Rn; 4295} 4296 4297// FIXME: The v5 pseudos are only necessary for the additional Constraint 4298// property. Remove them when it's possible to add those properties 4299// on an individual MachineInstr, not just an instruction description. 4300let isCommutable = 1, TwoOperandAliasConstraint = "$Rn = $Rd" in { 4301def MUL : AsMul1I32<0b0000000, (outs GPRnopc:$Rd), 4302 (ins GPRnopc:$Rn, GPRnopc:$Rm), 4303 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", 4304 [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))]>, 4305 Requires<[IsARM, HasV6]>, 4306 Sched<[WriteMUL32, ReadMUL, ReadMUL]> { 4307 let Inst{15-12} = 0b0000; 4308 let Unpredictable{15-12} = 0b1111; 4309} 4310 4311let Constraints = "@earlyclobber $Rd" in 4312def MULv5: ARMPseudoExpand<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm, 4313 pred:$p, cc_out:$s), 4314 4, IIC_iMUL32, 4315 [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))], 4316 (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s)>, 4317 Requires<[IsARM, NoV6, UseMulOps]>, 4318 Sched<[WriteMUL32, ReadMUL, ReadMUL]>; 4319} 4320 4321def MLA : AsMul1I32<0b0000001, (outs GPRnopc:$Rd), 4322 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra), 4323 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra", 4324 [(set GPRnopc:$Rd, (add (mul GPRnopc:$Rn, GPRnopc:$Rm), GPRnopc:$Ra))]>, 4325 Requires<[IsARM, HasV6, UseMulOps]>, 4326 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]> { 4327 bits<4> Ra; 4328 let Inst{15-12} = Ra; 4329} 4330 4331let Constraints = "@earlyclobber $Rd" in 4332def MLAv5: ARMPseudoExpand<(outs GPRnopc:$Rd), 4333 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra, 4334 pred:$p, cc_out:$s), 4, IIC_iMAC32, 4335 [(set GPRnopc:$Rd, (add (mul GPRnopc:$Rn, GPRnopc:$Rm), GPRnopc:$Ra))], 4336 (MLA GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra, pred:$p, cc_out:$s)>, 4337 Requires<[IsARM, NoV6]>, 4338 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 4339 4340def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 4341 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra", 4342 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>, 4343 Requires<[IsARM, HasV6T2, UseMulOps]>, 4344 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]> { 4345 bits<4> Rd; 4346 bits<4> Rm; 4347 bits<4> Rn; 4348 bits<4> Ra; 4349 let Inst{19-16} = Rd; 4350 let Inst{15-12} = Ra; 4351 let Inst{11-8} = Rm; 4352 let Inst{3-0} = Rn; 4353} 4354 4355// Extra precision multiplies with low / high results 4356let hasSideEffects = 0 in { 4357let isCommutable = 1 in { 4358def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi), 4359 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 4360 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", 4361 [(set GPR:$RdLo, GPR:$RdHi, 4362 (smullohi GPR:$Rn, GPR:$Rm))]>, 4363 Requires<[IsARM, HasV6]>, 4364 Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>; 4365 4366def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi), 4367 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 4368 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", 4369 [(set GPR:$RdLo, GPR:$RdHi, 4370 (umullohi GPR:$Rn, GPR:$Rm))]>, 4371 Requires<[IsARM, HasV6]>, 4372 Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL]>; 4373 4374let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { 4375def SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 4376 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 4377 4, IIC_iMUL64, 4378 [(set GPR:$RdLo, GPR:$RdHi, 4379 (smullohi GPR:$Rn, GPR:$Rm))], 4380 (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 4381 Requires<[IsARM, NoV6]>, 4382 Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>; 4383 4384def UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 4385 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 4386 4, IIC_iMUL64, 4387 [(set GPR:$RdLo, GPR:$RdHi, 4388 (umullohi GPR:$Rn, GPR:$Rm))], 4389 (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 4390 Requires<[IsARM, NoV6]>, 4391 Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>; 4392} 4393} 4394 4395// Multiply + accumulate 4396def SMLAL : AsMla1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi), 4397 (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64, 4398 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 4399 RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>, 4400 Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 4401def UMLAL : AsMla1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi), 4402 (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64, 4403 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 4404 RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>, 4405 Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 4406 4407def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), 4408 (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 4409 IIC_iMAC64, 4410 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 4411 RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>, 4412 Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]> { 4413 bits<4> RdLo; 4414 bits<4> RdHi; 4415 bits<4> Rm; 4416 bits<4> Rn; 4417 let Inst{19-16} = RdHi; 4418 let Inst{15-12} = RdLo; 4419 let Inst{11-8} = Rm; 4420 let Inst{3-0} = Rn; 4421} 4422 4423let Constraints = 4424 "@earlyclobber $RdLo,@earlyclobber $RdHi,$RLo = $RdLo,$RHi = $RdHi" in { 4425def SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 4426 (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s), 4427 4, IIC_iMAC64, [], 4428 (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, 4429 pred:$p, cc_out:$s)>, 4430 Requires<[IsARM, NoV6]>, 4431 Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 4432def UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 4433 (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s), 4434 4, IIC_iMAC64, [], 4435 (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, 4436 pred:$p, cc_out:$s)>, 4437 Requires<[IsARM, NoV6]>, 4438 Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 4439} 4440 4441} // hasSideEffects 4442 4443// Most significant word multiply 4444def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4445 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm", 4446 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>, 4447 Requires<[IsARM, HasV6]>, 4448 Sched<[WriteMUL32, ReadMUL, ReadMUL]> { 4449 let Inst{15-12} = 0b1111; 4450} 4451 4452def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4453 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", 4454 [(set GPR:$Rd, (ARMsmmlar GPR:$Rn, GPR:$Rm, (i32 0)))]>, 4455 Requires<[IsARM, HasV6]>, 4456 Sched<[WriteMUL32, ReadMUL, ReadMUL]> { 4457 let Inst{15-12} = 0b1111; 4458} 4459 4460def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd), 4461 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 4462 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra", 4463 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 4464 Requires<[IsARM, HasV6, UseMulOps]>, 4465 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 4466 4467def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd), 4468 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 4469 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", 4470 [(set GPR:$Rd, (ARMsmmlar GPR:$Rn, GPR:$Rm, GPR:$Ra))]>, 4471 Requires<[IsARM, HasV6]>, 4472 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 4473 4474def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd), 4475 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 4476 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", []>, 4477 Requires<[IsARM, HasV6, UseMulOps]>, 4478 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 4479 4480def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd), 4481 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 4482 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", 4483 [(set GPR:$Rd, (ARMsmmlsr GPR:$Rn, GPR:$Rm, GPR:$Ra))]>, 4484 Requires<[IsARM, HasV6]>, 4485 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 4486 4487multiclass AI_smul<string opc> { 4488 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4489 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm", 4490 [(set GPR:$Rd, (bb_mul GPR:$Rn, GPR:$Rm))]>, 4491 Requires<[IsARM, HasV5TE]>, 4492 Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 4493 4494 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4495 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm", 4496 [(set GPR:$Rd, (bt_mul GPR:$Rn, GPR:$Rm))]>, 4497 Requires<[IsARM, HasV5TE]>, 4498 Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 4499 4500 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4501 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm", 4502 [(set GPR:$Rd, (tb_mul GPR:$Rn, GPR:$Rm))]>, 4503 Requires<[IsARM, HasV5TE]>, 4504 Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 4505 4506 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4507 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm", 4508 [(set GPR:$Rd, (tt_mul GPR:$Rn, GPR:$Rm))]>, 4509 Requires<[IsARM, HasV5TE]>, 4510 Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 4511 4512 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4513 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm", 4514 [(set GPR:$Rd, (ARMsmulwb GPR:$Rn, GPR:$Rm))]>, 4515 Requires<[IsARM, HasV5TE]>, 4516 Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 4517 4518 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 4519 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm", 4520 [(set GPR:$Rd, (ARMsmulwt GPR:$Rn, GPR:$Rm))]>, 4521 Requires<[IsARM, HasV5TE]>, 4522 Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 4523} 4524 4525 4526multiclass AI_smla<string opc> { 4527 let DecoderMethod = "DecodeSMLAInstruction" in { 4528 def BB : AMulxyIa<0b0001000, 0b00, (outs GPRnopc:$Rd), 4529 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4530 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", 4531 [(set GPRnopc:$Rd, (add GPR:$Ra, 4532 (bb_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>, 4533 Requires<[IsARM, HasV5TE, UseMulOps]>, 4534 Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 4535 4536 def BT : AMulxyIa<0b0001000, 0b10, (outs GPRnopc:$Rd), 4537 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4538 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", 4539 [(set GPRnopc:$Rd, (add GPR:$Ra, 4540 (bt_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>, 4541 Requires<[IsARM, HasV5TE, UseMulOps]>, 4542 Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 4543 4544 def TB : AMulxyIa<0b0001000, 0b01, (outs GPRnopc:$Rd), 4545 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4546 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", 4547 [(set GPRnopc:$Rd, (add GPR:$Ra, 4548 (tb_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>, 4549 Requires<[IsARM, HasV5TE, UseMulOps]>, 4550 Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 4551 4552 def TT : AMulxyIa<0b0001000, 0b11, (outs GPRnopc:$Rd), 4553 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4554 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", 4555 [(set GPRnopc:$Rd, (add GPR:$Ra, 4556 (tt_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>, 4557 Requires<[IsARM, HasV5TE, UseMulOps]>, 4558 Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 4559 4560 def WB : AMulxyIa<0b0001001, 0b00, (outs GPRnopc:$Rd), 4561 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4562 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", 4563 [(set GPRnopc:$Rd, 4564 (add GPR:$Ra, (ARMsmulwb GPRnopc:$Rn, GPRnopc:$Rm)))]>, 4565 Requires<[IsARM, HasV5TE, UseMulOps]>, 4566 Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 4567 4568 def WT : AMulxyIa<0b0001001, 0b10, (outs GPRnopc:$Rd), 4569 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4570 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", 4571 [(set GPRnopc:$Rd, 4572 (add GPR:$Ra, (ARMsmulwt GPRnopc:$Rn, GPRnopc:$Rm)))]>, 4573 Requires<[IsARM, HasV5TE, UseMulOps]>, 4574 Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 4575 } 4576} 4577 4578defm SMUL : AI_smul<"smul">; 4579defm SMLA : AI_smla<"smla">; 4580 4581// Halfword multiply accumulate long: SMLAL<x><y>. 4582class SMLAL<bits<2> opc1, string asm> 4583 : AMulxyI64<0b0001010, opc1, 4584 (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 4585 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 4586 IIC_iMAC64, asm, "\t$RdLo, $RdHi, $Rn, $Rm", []>, 4587 RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, 4588 Requires<[IsARM, HasV5TE]>, 4589 Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 4590 4591def SMLALBB : SMLAL<0b00, "smlalbb">; 4592def SMLALBT : SMLAL<0b10, "smlalbt">; 4593def SMLALTB : SMLAL<0b01, "smlaltb">; 4594def SMLALTT : SMLAL<0b11, "smlaltt">; 4595 4596def : ARMV5TEPat<(ARMsmlalbb GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 4597 (SMLALBB $Rn, $Rm, $RLo, $RHi)>; 4598def : ARMV5TEPat<(ARMsmlalbt GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 4599 (SMLALBT $Rn, $Rm, $RLo, $RHi)>; 4600def : ARMV5TEPat<(ARMsmlaltb GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 4601 (SMLALTB $Rn, $Rm, $RLo, $RHi)>; 4602def : ARMV5TEPat<(ARMsmlaltt GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 4603 (SMLALTT $Rn, $Rm, $RLo, $RHi)>; 4604 4605// Helper class for AI_smld. 4606class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops, 4607 InstrItinClass itin, string opc, string asm> 4608 : AI<oops, iops, MulFrm, itin, opc, asm, []>, 4609 Requires<[IsARM, HasV6]> { 4610 bits<4> Rn; 4611 bits<4> Rm; 4612 let Inst{27-23} = 0b01110; 4613 let Inst{22} = long; 4614 let Inst{21-20} = 0b00; 4615 let Inst{11-8} = Rm; 4616 let Inst{7} = 0; 4617 let Inst{6} = sub; 4618 let Inst{5} = swap; 4619 let Inst{4} = 1; 4620 let Inst{3-0} = Rn; 4621} 4622class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops, 4623 InstrItinClass itin, string opc, string asm> 4624 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 4625 bits<4> Rd; 4626 let Inst{15-12} = 0b1111; 4627 let Inst{19-16} = Rd; 4628} 4629class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops, 4630 InstrItinClass itin, string opc, string asm> 4631 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 4632 bits<4> Ra; 4633 bits<4> Rd; 4634 let Inst{19-16} = Rd; 4635 let Inst{15-12} = Ra; 4636} 4637class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops, 4638 InstrItinClass itin, string opc, string asm> 4639 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 4640 bits<4> RdLo; 4641 bits<4> RdHi; 4642 let Inst{19-16} = RdHi; 4643 let Inst{15-12} = RdLo; 4644} 4645 4646multiclass AI_smld<bit sub, string opc> { 4647 4648 def D : AMulDualIa<0, sub, 0, (outs GPRnopc:$Rd), 4649 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4650 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">, 4651 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 4652 4653 def DX: AMulDualIa<0, sub, 1, (outs GPRnopc:$Rd), 4654 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4655 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">, 4656 Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 4657 4658 def LD: AMulDualI64<1, sub, 0, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 4659 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 4660 NoItinerary, 4661 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">, 4662 RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, 4663 Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 4664 4665 def LDX : AMulDualI64<1, sub, 1, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 4666 (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 4667 NoItinerary, 4668 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">, 4669 RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, 4670 Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>; 4671} 4672 4673defm SMLA : AI_smld<0, "smla">; 4674defm SMLS : AI_smld<1, "smls">; 4675 4676def : ARMV6Pat<(int_arm_smlad GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4677 (SMLAD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>; 4678def : ARMV6Pat<(int_arm_smladx GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4679 (SMLADX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>; 4680def : ARMV6Pat<(int_arm_smlsd GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4681 (SMLSD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>; 4682def : ARMV6Pat<(int_arm_smlsdx GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 4683 (SMLSDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>; 4684def : ARMV6Pat<(ARMSmlald GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 4685 (SMLALD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>; 4686def : ARMV6Pat<(ARMSmlaldx GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 4687 (SMLALDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>; 4688def : ARMV6Pat<(ARMSmlsld GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 4689 (SMLSLD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>; 4690def : ARMV6Pat<(ARMSmlsldx GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 4691 (SMLSLDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>; 4692 4693multiclass AI_sdml<bit sub, string opc> { 4694 4695 def D:AMulDualI<0, sub, 0, (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), 4696 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">, 4697 Sched<[WriteMUL32, ReadMUL, ReadMUL]>; 4698 def DX:AMulDualI<0, sub, 1, (outs GPRnopc:$Rd),(ins GPRnopc:$Rn, GPRnopc:$Rm), 4699 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">, 4700 Sched<[WriteMUL32, ReadMUL, ReadMUL]>; 4701} 4702 4703defm SMUA : AI_sdml<0, "smua">; 4704defm SMUS : AI_sdml<1, "smus">; 4705 4706def : ARMV6Pat<(int_arm_smuad GPRnopc:$Rn, GPRnopc:$Rm), 4707 (SMUAD GPRnopc:$Rn, GPRnopc:$Rm)>; 4708def : ARMV6Pat<(int_arm_smuadx GPRnopc:$Rn, GPRnopc:$Rm), 4709 (SMUADX GPRnopc:$Rn, GPRnopc:$Rm)>; 4710def : ARMV6Pat<(int_arm_smusd GPRnopc:$Rn, GPRnopc:$Rm), 4711 (SMUSD GPRnopc:$Rn, GPRnopc:$Rm)>; 4712def : ARMV6Pat<(int_arm_smusdx GPRnopc:$Rn, GPRnopc:$Rm), 4713 (SMUSDX GPRnopc:$Rn, GPRnopc:$Rm)>; 4714 4715//===----------------------------------------------------------------------===// 4716// Division Instructions (ARMv7-A with virtualization extension) 4717// 4718def SDIV : ADivA1I<0b001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iDIV, 4719 "sdiv", "\t$Rd, $Rn, $Rm", 4720 [(set GPR:$Rd, (sdiv GPR:$Rn, GPR:$Rm))]>, 4721 Requires<[IsARM, HasDivideInARM]>, 4722 Sched<[WriteDIV]>; 4723 4724def UDIV : ADivA1I<0b011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iDIV, 4725 "udiv", "\t$Rd, $Rn, $Rm", 4726 [(set GPR:$Rd, (udiv GPR:$Rn, GPR:$Rm))]>, 4727 Requires<[IsARM, HasDivideInARM]>, 4728 Sched<[WriteDIV]>; 4729 4730//===----------------------------------------------------------------------===// 4731// Misc. Arithmetic Instructions. 4732// 4733 4734def CLZ : AMiscA1I<0b00010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm), 4735 IIC_iUNAr, "clz", "\t$Rd, $Rm", 4736 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>, 4737 Sched<[WriteALU]>; 4738 4739def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 4740 IIC_iUNAr, "rbit", "\t$Rd, $Rm", 4741 [(set GPR:$Rd, (bitreverse GPR:$Rm))]>, 4742 Requires<[IsARM, HasV6T2]>, 4743 Sched<[WriteALU]>; 4744 4745def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 4746 IIC_iUNAr, "rev", "\t$Rd, $Rm", 4747 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>, 4748 Sched<[WriteALU]>; 4749 4750let AddedComplexity = 5 in 4751def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 4752 IIC_iUNAr, "rev16", "\t$Rd, $Rm", 4753 [(set GPR:$Rd, (rotr (bswap GPR:$Rm), (i32 16)))]>, 4754 Requires<[IsARM, HasV6]>, 4755 Sched<[WriteALU]>; 4756 4757def : ARMV6Pat<(srl (bswap (extloadi16 addrmode3:$addr)), (i32 16)), 4758 (REV16 (LDRH addrmode3:$addr))>; 4759def : ARMV6Pat<(truncstorei16 (srl (bswap GPR:$Rn), (i32 16)), addrmode3:$addr), 4760 (STRH (REV16 GPR:$Rn), addrmode3:$addr)>; 4761def : ARMV6Pat<(srl (bswap top16Zero:$Rn), (i32 16)), 4762 (REV16 GPR:$Rn)>; 4763 4764let AddedComplexity = 5 in 4765def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 4766 IIC_iUNAr, "revsh", "\t$Rd, $Rm", 4767 [(set GPR:$Rd, (sra (bswap GPR:$Rm), (i32 16)))]>, 4768 Requires<[IsARM, HasV6]>, 4769 Sched<[WriteALU]>; 4770 4771def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)), 4772 (and (srl GPR:$Rm, (i32 8)), 0xFF)), 4773 (REVSH GPR:$Rm)>; 4774 4775def PKHBT : APKHI<0b01101000, 0, (outs GPRnopc:$Rd), 4776 (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_lsl_amt:$sh), 4777 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", 4778 [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF), 4779 (and (shl GPRnopc:$Rm, pkh_lsl_amt:$sh), 4780 0xFFFF0000)))]>, 4781 Requires<[IsARM, HasV6]>, 4782 Sched<[WriteALUsi, ReadALU]>; 4783 4784// Alternate cases for PKHBT where identities eliminate some nodes. 4785def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (and GPRnopc:$Rm, 0xFFFF0000)), 4786 (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, 0)>; 4787def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (shl GPRnopc:$Rm, imm16_31:$sh)), 4788 (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, imm16_31:$sh)>; 4789 4790// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 4791// will match the pattern below. 4792def PKHTB : APKHI<0b01101000, 1, (outs GPRnopc:$Rd), 4793 (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_asr_amt:$sh), 4794 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh", 4795 [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF0000), 4796 (and (sra GPRnopc:$Rm, pkh_asr_amt:$sh), 4797 0xFFFF)))]>, 4798 Requires<[IsARM, HasV6]>, 4799 Sched<[WriteALUsi, ReadALU]>; 4800 4801// Alternate cases for PKHTB where identities eliminate some nodes. Note that 4802// a shift amount of 0 is *not legal* here, it is PKHBT instead. 4803// We also can not replace a srl (17..31) by an arithmetic shift we would use in 4804// pkhtb src1, src2, asr (17..31). 4805def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 4806 (srl GPRnopc:$src2, imm16:$sh)), 4807 (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16:$sh)>; 4808def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 4809 (sra GPRnopc:$src2, imm16_31:$sh)), 4810 (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16_31:$sh)>; 4811def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 4812 (and (srl GPRnopc:$src2, imm1_15:$sh), 0xFFFF)), 4813 (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm1_15:$sh)>; 4814 4815//===----------------------------------------------------------------------===// 4816// CRC Instructions 4817// 4818// Polynomials: 4819// + CRC32{B,H,W} 0x04C11DB7 4820// + CRC32C{B,H,W} 0x1EDC6F41 4821// 4822 4823class AI_crc32<bit C, bits<2> sz, string suffix, SDPatternOperator builtin> 4824 : AInoP<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), MiscFrm, NoItinerary, 4825 !strconcat("crc32", suffix), "\t$Rd, $Rn, $Rm", 4826 [(set GPRnopc:$Rd, (builtin GPRnopc:$Rn, GPRnopc:$Rm))]>, 4827 Requires<[IsARM, HasV8, HasCRC]> { 4828 bits<4> Rd; 4829 bits<4> Rn; 4830 bits<4> Rm; 4831 4832 let Inst{31-28} = 0b1110; 4833 let Inst{27-23} = 0b00010; 4834 let Inst{22-21} = sz; 4835 let Inst{20} = 0; 4836 let Inst{19-16} = Rn; 4837 let Inst{15-12} = Rd; 4838 let Inst{11-10} = 0b00; 4839 let Inst{9} = C; 4840 let Inst{8} = 0; 4841 let Inst{7-4} = 0b0100; 4842 let Inst{3-0} = Rm; 4843 4844 let Unpredictable{11-8} = 0b1101; 4845} 4846 4847def CRC32B : AI_crc32<0, 0b00, "b", int_arm_crc32b>; 4848def CRC32CB : AI_crc32<1, 0b00, "cb", int_arm_crc32cb>; 4849def CRC32H : AI_crc32<0, 0b01, "h", int_arm_crc32h>; 4850def CRC32CH : AI_crc32<1, 0b01, "ch", int_arm_crc32ch>; 4851def CRC32W : AI_crc32<0, 0b10, "w", int_arm_crc32w>; 4852def CRC32CW : AI_crc32<1, 0b10, "cw", int_arm_crc32cw>; 4853 4854//===----------------------------------------------------------------------===// 4855// ARMv8.1a Privilege Access Never extension 4856// 4857// SETPAN #imm1 4858 4859def SETPAN : AInoP<(outs), (ins imm0_1:$imm), MiscFrm, NoItinerary, "setpan", 4860 "\t$imm", []>, Requires<[IsARM, HasV8, HasV8_1a]> { 4861 bits<1> imm; 4862 4863 let Inst{31-28} = 0b1111; 4864 let Inst{27-20} = 0b00010001; 4865 let Inst{19-16} = 0b0000; 4866 let Inst{15-10} = 0b000000; 4867 let Inst{9} = imm; 4868 let Inst{8} = 0b0; 4869 let Inst{7-4} = 0b0000; 4870 let Inst{3-0} = 0b0000; 4871 4872 let Unpredictable{19-16} = 0b1111; 4873 let Unpredictable{15-10} = 0b111111; 4874 let Unpredictable{8} = 0b1; 4875 let Unpredictable{3-0} = 0b1111; 4876} 4877 4878//===----------------------------------------------------------------------===// 4879// Comparison Instructions... 4880// 4881 4882defm CMP : AI1_cmp_irs<0b1010, "cmp", 4883 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, ARMcmp>; 4884 4885// ARMcmpZ can re-use the above instruction definitions. 4886def : ARMPat<(ARMcmpZ GPR:$src, mod_imm:$imm), 4887 (CMPri GPR:$src, mod_imm:$imm)>; 4888def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs), 4889 (CMPrr GPR:$src, GPR:$rhs)>; 4890def : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs), 4891 (CMPrsi GPR:$src, so_reg_imm:$rhs)>; 4892def : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs), 4893 (CMPrsr GPR:$src, so_reg_reg:$rhs)>; 4894 4895// CMN register-integer 4896let isCompare = 1, Defs = [CPSR] in { 4897def CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, mod_imm:$imm), DPFrm, IIC_iCMPi, 4898 "cmn", "\t$Rn, $imm", 4899 [(ARMcmn GPR:$Rn, mod_imm:$imm)]>, 4900 Sched<[WriteCMP, ReadALU]> { 4901 bits<4> Rn; 4902 bits<12> imm; 4903 let Inst{25} = 1; 4904 let Inst{20} = 1; 4905 let Inst{19-16} = Rn; 4906 let Inst{15-12} = 0b0000; 4907 let Inst{11-0} = imm; 4908 4909 let Unpredictable{15-12} = 0b1111; 4910} 4911 4912// CMN register-register/shift 4913def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr, 4914 "cmn", "\t$Rn, $Rm", 4915 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 4916 GPR:$Rn, GPR:$Rm)]>, Sched<[WriteCMP, ReadALU, ReadALU]> { 4917 bits<4> Rn; 4918 bits<4> Rm; 4919 let isCommutable = 1; 4920 let Inst{25} = 0; 4921 let Inst{20} = 1; 4922 let Inst{19-16} = Rn; 4923 let Inst{15-12} = 0b0000; 4924 let Inst{11-4} = 0b00000000; 4925 let Inst{3-0} = Rm; 4926 4927 let Unpredictable{15-12} = 0b1111; 4928} 4929 4930def CMNzrsi : AI1<0b1011, (outs), 4931 (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr, 4932 "cmn", "\t$Rn, $shift", 4933 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 4934 GPR:$Rn, so_reg_imm:$shift)]>, 4935 Sched<[WriteCMPsi, ReadALU]> { 4936 bits<4> Rn; 4937 bits<12> shift; 4938 let Inst{25} = 0; 4939 let Inst{20} = 1; 4940 let Inst{19-16} = Rn; 4941 let Inst{15-12} = 0b0000; 4942 let Inst{11-5} = shift{11-5}; 4943 let Inst{4} = 0; 4944 let Inst{3-0} = shift{3-0}; 4945 4946 let Unpredictable{15-12} = 0b1111; 4947} 4948 4949def CMNzrsr : AI1<0b1011, (outs), 4950 (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr, 4951 "cmn", "\t$Rn, $shift", 4952 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 4953 GPRnopc:$Rn, so_reg_reg:$shift)]>, 4954 Sched<[WriteCMPsr, ReadALU]> { 4955 bits<4> Rn; 4956 bits<12> shift; 4957 let Inst{25} = 0; 4958 let Inst{20} = 1; 4959 let Inst{19-16} = Rn; 4960 let Inst{15-12} = 0b0000; 4961 let Inst{11-8} = shift{11-8}; 4962 let Inst{7} = 0; 4963 let Inst{6-5} = shift{6-5}; 4964 let Inst{4} = 1; 4965 let Inst{3-0} = shift{3-0}; 4966 4967 let Unpredictable{15-12} = 0b1111; 4968} 4969 4970} 4971 4972def : ARMPat<(ARMcmp GPR:$src, mod_imm_neg:$imm), 4973 (CMNri GPR:$src, mod_imm_neg:$imm)>; 4974 4975def : ARMPat<(ARMcmpZ GPR:$src, mod_imm_neg:$imm), 4976 (CMNri GPR:$src, mod_imm_neg:$imm)>; 4977 4978// Note that TST/TEQ don't set all the same flags that CMP does! 4979defm TST : AI1_cmp_irs<0b1000, "tst", 4980 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 4981 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1, 4982 "DecodeTSTInstruction">; 4983defm TEQ : AI1_cmp_irs<0b1001, "teq", 4984 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 4985 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>; 4986 4987// Pseudo i64 compares for some floating point compares. 4988let usesCustomInserter = 1, isBranch = 1, isTerminator = 1, 4989 Defs = [CPSR] in { 4990def BCCi64 : PseudoInst<(outs), 4991 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst), 4992 IIC_Br, 4993 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>, 4994 Sched<[WriteBr]>; 4995 4996def BCCZi64 : PseudoInst<(outs), 4997 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, 4998 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>, 4999 Sched<[WriteBr]>; 5000} // usesCustomInserter 5001 5002 5003// Conditional moves 5004let hasSideEffects = 0 in { 5005 5006let isCommutable = 1, isSelect = 1 in 5007def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), 5008 (ins GPR:$false, GPR:$Rm, cmovpred:$p), 5009 4, IIC_iCMOVr, 5010 [(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, 5011 cmovpred:$p))]>, 5012 RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 5013 5014def MOVCCsi : ARMPseudoInst<(outs GPR:$Rd), 5015 (ins GPR:$false, so_reg_imm:$shift, cmovpred:$p), 5016 4, IIC_iCMOVsr, 5017 [(set GPR:$Rd, 5018 (ARMcmov GPR:$false, so_reg_imm:$shift, 5019 cmovpred:$p))]>, 5020 RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 5021def MOVCCsr : ARMPseudoInst<(outs GPR:$Rd), 5022 (ins GPR:$false, so_reg_reg:$shift, cmovpred:$p), 5023 4, IIC_iCMOVsr, 5024 [(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift, 5025 cmovpred:$p))]>, 5026 RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 5027 5028 5029let isMoveImm = 1 in 5030def MOVCCi16 5031 : ARMPseudoInst<(outs GPR:$Rd), 5032 (ins GPR:$false, imm0_65535_expr:$imm, cmovpred:$p), 5033 4, IIC_iMOVi, 5034 [(set GPR:$Rd, (ARMcmov GPR:$false, imm0_65535:$imm, 5035 cmovpred:$p))]>, 5036 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>, 5037 Sched<[WriteALU]>; 5038 5039let isMoveImm = 1 in 5040def MOVCCi : ARMPseudoInst<(outs GPR:$Rd), 5041 (ins GPR:$false, mod_imm:$imm, cmovpred:$p), 5042 4, IIC_iCMOVi, 5043 [(set GPR:$Rd, (ARMcmov GPR:$false, mod_imm:$imm, 5044 cmovpred:$p))]>, 5045 RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 5046 5047// Two instruction predicate mov immediate. 5048let isMoveImm = 1 in 5049def MOVCCi32imm 5050 : ARMPseudoInst<(outs GPR:$Rd), 5051 (ins GPR:$false, i32imm:$src, cmovpred:$p), 5052 8, IIC_iCMOVix2, 5053 [(set GPR:$Rd, (ARMcmov GPR:$false, imm:$src, 5054 cmovpred:$p))]>, 5055 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>; 5056 5057let isMoveImm = 1 in 5058def MVNCCi : ARMPseudoInst<(outs GPR:$Rd), 5059 (ins GPR:$false, mod_imm:$imm, cmovpred:$p), 5060 4, IIC_iCMOVi, 5061 [(set GPR:$Rd, (ARMcmov GPR:$false, mod_imm_not:$imm, 5062 cmovpred:$p))]>, 5063 RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 5064 5065} // hasSideEffects 5066 5067 5068//===----------------------------------------------------------------------===// 5069// Atomic operations intrinsics 5070// 5071 5072def MemBarrierOptOperand : AsmOperandClass { 5073 let Name = "MemBarrierOpt"; 5074 let ParserMethod = "parseMemBarrierOptOperand"; 5075} 5076def memb_opt : Operand<i32> { 5077 let PrintMethod = "printMemBOption"; 5078 let ParserMatchClass = MemBarrierOptOperand; 5079 let DecoderMethod = "DecodeMemBarrierOption"; 5080} 5081 5082def InstSyncBarrierOptOperand : AsmOperandClass { 5083 let Name = "InstSyncBarrierOpt"; 5084 let ParserMethod = "parseInstSyncBarrierOptOperand"; 5085} 5086def instsyncb_opt : Operand<i32> { 5087 let PrintMethod = "printInstSyncBOption"; 5088 let ParserMatchClass = InstSyncBarrierOptOperand; 5089 let DecoderMethod = "DecodeInstSyncBarrierOption"; 5090} 5091 5092def TraceSyncBarrierOptOperand : AsmOperandClass { 5093 let Name = "TraceSyncBarrierOpt"; 5094 let ParserMethod = "parseTraceSyncBarrierOptOperand"; 5095} 5096def tsb_opt : Operand<i32> { 5097 let PrintMethod = "printTraceSyncBOption"; 5098 let ParserMatchClass = TraceSyncBarrierOptOperand; 5099} 5100 5101// Memory barriers protect the atomic sequences 5102let hasSideEffects = 1 in { 5103def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 5104 "dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>, 5105 Requires<[IsARM, HasDB]> { 5106 bits<4> opt; 5107 let Inst{31-4} = 0xf57ff05; 5108 let Inst{3-0} = opt; 5109} 5110 5111def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 5112 "dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>, 5113 Requires<[IsARM, HasDB]> { 5114 bits<4> opt; 5115 let Inst{31-4} = 0xf57ff04; 5116 let Inst{3-0} = opt; 5117} 5118 5119// ISB has only full system option 5120def ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary, 5121 "isb", "\t$opt", [(int_arm_isb (i32 imm0_15:$opt))]>, 5122 Requires<[IsARM, HasDB]> { 5123 bits<4> opt; 5124 let Inst{31-4} = 0xf57ff06; 5125 let Inst{3-0} = opt; 5126} 5127 5128let hasNoSchedulingInfo = 1 in 5129def TSB : AInoP<(outs), (ins tsb_opt:$opt), MiscFrm, NoItinerary, 5130 "tsb", "\t$opt", []>, Requires<[IsARM, HasV8_4a]> { 5131 let Inst{31-0} = 0xe320f012; 5132} 5133 5134} 5135 5136// Armv8.5-A speculation barrier 5137def SB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "sb", "", []>, 5138 Requires<[IsARM, HasSB]>, Sched<[]> { 5139 let Inst{31-0} = 0xf57ff070; 5140 let Unpredictable = 0x000fff0f; 5141 let hasSideEffects = 1; 5142} 5143 5144let usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in { 5145 // Pseudo instruction that combines movs + predicated rsbmi 5146 // to implement integer ABS 5147 def ABS : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$src), 8, NoItinerary, []>; 5148} 5149 5150let usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in { 5151 def COPY_STRUCT_BYVAL_I32 : PseudoInst< 5152 (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment), 5153 NoItinerary, 5154 [(ARMcopystructbyval GPR:$dst, GPR:$src, imm:$size, imm:$alignment)]>; 5155} 5156 5157let hasPostISelHook = 1, Constraints = "$newdst = $dst, $newsrc = $src" in { 5158 // %newsrc, %newdst = MEMCPY %dst, %src, N, ...N scratch regs... 5159 // Copies N registers worth of memory from address %src to address %dst 5160 // and returns the incremented addresses. N scratch register will 5161 // be attached for the copy to use. 5162 def MEMCPY : PseudoInst< 5163 (outs GPR:$newdst, GPR:$newsrc), 5164 (ins GPR:$dst, GPR:$src, i32imm:$nreg, variable_ops), 5165 NoItinerary, 5166 [(set GPR:$newdst, GPR:$newsrc, 5167 (ARMmemcopy GPR:$dst, GPR:$src, imm:$nreg))]>; 5168} 5169 5170def ldrex_1 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 5171 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 5172}]>; 5173 5174def ldrex_2 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 5175 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 5176}]>; 5177 5178def ldrex_4 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 5179 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 5180}]>; 5181 5182def strex_1 : PatFrag<(ops node:$val, node:$ptr), 5183 (int_arm_strex node:$val, node:$ptr), [{ 5184 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 5185}]>; 5186 5187def strex_2 : PatFrag<(ops node:$val, node:$ptr), 5188 (int_arm_strex node:$val, node:$ptr), [{ 5189 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 5190}]>; 5191 5192def strex_4 : PatFrag<(ops node:$val, node:$ptr), 5193 (int_arm_strex node:$val, node:$ptr), [{ 5194 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 5195}]>; 5196 5197def ldaex_1 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{ 5198 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 5199}]>; 5200 5201def ldaex_2 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{ 5202 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 5203}]>; 5204 5205def ldaex_4 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{ 5206 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 5207}]>; 5208 5209def stlex_1 : PatFrag<(ops node:$val, node:$ptr), 5210 (int_arm_stlex node:$val, node:$ptr), [{ 5211 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 5212}]>; 5213 5214def stlex_2 : PatFrag<(ops node:$val, node:$ptr), 5215 (int_arm_stlex node:$val, node:$ptr), [{ 5216 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 5217}]>; 5218 5219def stlex_4 : PatFrag<(ops node:$val, node:$ptr), 5220 (int_arm_stlex node:$val, node:$ptr), [{ 5221 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 5222}]>; 5223 5224let mayLoad = 1 in { 5225def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 5226 NoItinerary, "ldrexb", "\t$Rt, $addr", 5227 [(set GPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>; 5228def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 5229 NoItinerary, "ldrexh", "\t$Rt, $addr", 5230 [(set GPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>; 5231def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 5232 NoItinerary, "ldrex", "\t$Rt, $addr", 5233 [(set GPR:$Rt, (ldrex_4 addr_offset_none:$addr))]>; 5234let hasExtraDefRegAllocReq = 1 in 5235def LDREXD : AIldrex<0b01, (outs GPRPairOp:$Rt),(ins addr_offset_none:$addr), 5236 NoItinerary, "ldrexd", "\t$Rt, $addr", []> { 5237 let DecoderMethod = "DecodeDoubleRegLoad"; 5238} 5239 5240def LDAEXB : AIldaex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 5241 NoItinerary, "ldaexb", "\t$Rt, $addr", 5242 [(set GPR:$Rt, (ldaex_1 addr_offset_none:$addr))]>; 5243def LDAEXH : AIldaex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 5244 NoItinerary, "ldaexh", "\t$Rt, $addr", 5245 [(set GPR:$Rt, (ldaex_2 addr_offset_none:$addr))]>; 5246def LDAEX : AIldaex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 5247 NoItinerary, "ldaex", "\t$Rt, $addr", 5248 [(set GPR:$Rt, (ldaex_4 addr_offset_none:$addr))]>; 5249let hasExtraDefRegAllocReq = 1 in 5250def LDAEXD : AIldaex<0b01, (outs GPRPairOp:$Rt),(ins addr_offset_none:$addr), 5251 NoItinerary, "ldaexd", "\t$Rt, $addr", []> { 5252 let DecoderMethod = "DecodeDoubleRegLoad"; 5253} 5254} 5255 5256let mayStore = 1, Constraints = "@earlyclobber $Rd" in { 5257def STREXB: AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 5258 NoItinerary, "strexb", "\t$Rd, $Rt, $addr", 5259 [(set GPR:$Rd, (strex_1 GPR:$Rt, 5260 addr_offset_none:$addr))]>; 5261def STREXH: AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 5262 NoItinerary, "strexh", "\t$Rd, $Rt, $addr", 5263 [(set GPR:$Rd, (strex_2 GPR:$Rt, 5264 addr_offset_none:$addr))]>; 5265def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 5266 NoItinerary, "strex", "\t$Rd, $Rt, $addr", 5267 [(set GPR:$Rd, (strex_4 GPR:$Rt, 5268 addr_offset_none:$addr))]>; 5269let hasExtraSrcRegAllocReq = 1 in 5270def STREXD : AIstrex<0b01, (outs GPR:$Rd), 5271 (ins GPRPairOp:$Rt, addr_offset_none:$addr), 5272 NoItinerary, "strexd", "\t$Rd, $Rt, $addr", []> { 5273 let DecoderMethod = "DecodeDoubleRegStore"; 5274} 5275def STLEXB: AIstlex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 5276 NoItinerary, "stlexb", "\t$Rd, $Rt, $addr", 5277 [(set GPR:$Rd, 5278 (stlex_1 GPR:$Rt, addr_offset_none:$addr))]>; 5279def STLEXH: AIstlex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 5280 NoItinerary, "stlexh", "\t$Rd, $Rt, $addr", 5281 [(set GPR:$Rd, 5282 (stlex_2 GPR:$Rt, addr_offset_none:$addr))]>; 5283def STLEX : AIstlex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 5284 NoItinerary, "stlex", "\t$Rd, $Rt, $addr", 5285 [(set GPR:$Rd, 5286 (stlex_4 GPR:$Rt, addr_offset_none:$addr))]>; 5287let hasExtraSrcRegAllocReq = 1 in 5288def STLEXD : AIstlex<0b01, (outs GPR:$Rd), 5289 (ins GPRPairOp:$Rt, addr_offset_none:$addr), 5290 NoItinerary, "stlexd", "\t$Rd, $Rt, $addr", []> { 5291 let DecoderMethod = "DecodeDoubleRegStore"; 5292} 5293} 5294 5295def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", 5296 [(int_arm_clrex)]>, 5297 Requires<[IsARM, HasV6K]> { 5298 let Inst{31-0} = 0b11110101011111111111000000011111; 5299} 5300 5301def : ARMPat<(strex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr), 5302 (STREXB GPR:$Rt, addr_offset_none:$addr)>; 5303def : ARMPat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), 5304 (STREXH GPR:$Rt, addr_offset_none:$addr)>; 5305 5306def : ARMPat<(stlex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr), 5307 (STLEXB GPR:$Rt, addr_offset_none:$addr)>; 5308def : ARMPat<(stlex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), 5309 (STLEXH GPR:$Rt, addr_offset_none:$addr)>; 5310 5311class acquiring_load<PatFrag base> 5312 : PatFrag<(ops node:$ptr), (base node:$ptr), [{ 5313 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering(); 5314 return isAcquireOrStronger(Ordering); 5315}]>; 5316 5317def atomic_load_acquire_8 : acquiring_load<atomic_load_8>; 5318def atomic_load_acquire_16 : acquiring_load<atomic_load_16>; 5319def atomic_load_acquire_32 : acquiring_load<atomic_load_32>; 5320 5321class releasing_store<PatFrag base> 5322 : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{ 5323 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering(); 5324 return isReleaseOrStronger(Ordering); 5325}]>; 5326 5327def atomic_store_release_8 : releasing_store<atomic_store_8>; 5328def atomic_store_release_16 : releasing_store<atomic_store_16>; 5329def atomic_store_release_32 : releasing_store<atomic_store_32>; 5330 5331let AddedComplexity = 8 in { 5332 def : ARMPat<(atomic_load_acquire_8 addr_offset_none:$addr), (LDAB addr_offset_none:$addr)>; 5333 def : ARMPat<(atomic_load_acquire_16 addr_offset_none:$addr), (LDAH addr_offset_none:$addr)>; 5334 def : ARMPat<(atomic_load_acquire_32 addr_offset_none:$addr), (LDA addr_offset_none:$addr)>; 5335 def : ARMPat<(atomic_store_release_8 addr_offset_none:$addr, GPR:$val), (STLB GPR:$val, addr_offset_none:$addr)>; 5336 def : ARMPat<(atomic_store_release_16 addr_offset_none:$addr, GPR:$val), (STLH GPR:$val, addr_offset_none:$addr)>; 5337 def : ARMPat<(atomic_store_release_32 addr_offset_none:$addr, GPR:$val), (STL GPR:$val, addr_offset_none:$addr)>; 5338} 5339 5340// SWP/SWPB are deprecated in V6/V7 and optional in v7VE. 5341// FIXME Use InstAlias to generate LDREX/STREX pairs instead. 5342let mayLoad = 1, mayStore = 1 in { 5343def SWP : AIswp<0, (outs GPRnopc:$Rt), 5344 (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swp", []>, 5345 Requires<[IsARM,PreV8]>; 5346def SWPB: AIswp<1, (outs GPRnopc:$Rt), 5347 (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swpb", []>, 5348 Requires<[IsARM,PreV8]>; 5349} 5350 5351//===----------------------------------------------------------------------===// 5352// Coprocessor Instructions. 5353// 5354 5355def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 5356 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 5357 NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 5358 [(int_arm_cdp timm:$cop, timm:$opc1, timm:$CRd, timm:$CRn, 5359 timm:$CRm, timm:$opc2)]>, 5360 Requires<[IsARM,PreV8]> { 5361 bits<4> opc1; 5362 bits<4> CRn; 5363 bits<4> CRd; 5364 bits<4> cop; 5365 bits<3> opc2; 5366 bits<4> CRm; 5367 5368 let Inst{3-0} = CRm; 5369 let Inst{4} = 0; 5370 let Inst{7-5} = opc2; 5371 let Inst{11-8} = cop; 5372 let Inst{15-12} = CRd; 5373 let Inst{19-16} = CRn; 5374 let Inst{23-20} = opc1; 5375 5376 let DecoderNamespace = "CoProc"; 5377} 5378 5379def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 5380 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 5381 NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 5382 [(int_arm_cdp2 timm:$cop, timm:$opc1, timm:$CRd, timm:$CRn, 5383 timm:$CRm, timm:$opc2)]>, 5384 Requires<[IsARM,PreV8]> { 5385 let Inst{31-28} = 0b1111; 5386 bits<4> opc1; 5387 bits<4> CRn; 5388 bits<4> CRd; 5389 bits<4> cop; 5390 bits<3> opc2; 5391 bits<4> CRm; 5392 5393 let Inst{3-0} = CRm; 5394 let Inst{4} = 0; 5395 let Inst{7-5} = opc2; 5396 let Inst{11-8} = cop; 5397 let Inst{15-12} = CRd; 5398 let Inst{19-16} = CRn; 5399 let Inst{23-20} = opc1; 5400 5401 let DecoderNamespace = "CoProc"; 5402} 5403 5404class ACI<dag oops, dag iops, string opc, string asm, 5405 list<dag> pattern, IndexMode im = IndexModeNone, 5406 AddrMode am = AddrModeNone> 5407 : I<oops, iops, am, 4, im, BrFrm, NoItinerary, 5408 opc, asm, "", pattern> { 5409 let Inst{27-25} = 0b110; 5410} 5411class ACInoP<dag oops, dag iops, string opc, string asm, 5412 list<dag> pattern, IndexMode im = IndexModeNone, 5413 AddrMode am = AddrModeNone> 5414 : InoP<oops, iops, am, 4, im, BrFrm, NoItinerary, 5415 opc, asm, "", pattern> { 5416 let Inst{31-28} = 0b1111; 5417 let Inst{27-25} = 0b110; 5418} 5419 5420let DecoderNamespace = "CoProc" in { 5421multiclass LdStCop<bit load, bit Dbit, string asm, list<dag> pattern> { 5422 def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 5423 asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone, 5424 AddrMode5> { 5425 bits<13> addr; 5426 bits<4> cop; 5427 bits<4> CRd; 5428 let Inst{24} = 1; // P = 1 5429 let Inst{23} = addr{8}; 5430 let Inst{22} = Dbit; 5431 let Inst{21} = 0; // W = 0 5432 let Inst{20} = load; 5433 let Inst{19-16} = addr{12-9}; 5434 let Inst{15-12} = CRd; 5435 let Inst{11-8} = cop; 5436 let Inst{7-0} = addr{7-0}; 5437 let DecoderMethod = "DecodeCopMemInstruction"; 5438 } 5439 def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), 5440 asm, "\t$cop, $CRd, $addr!", [], IndexModePre> { 5441 bits<13> addr; 5442 bits<4> cop; 5443 bits<4> CRd; 5444 let Inst{24} = 1; // P = 1 5445 let Inst{23} = addr{8}; 5446 let Inst{22} = Dbit; 5447 let Inst{21} = 1; // W = 1 5448 let Inst{20} = load; 5449 let Inst{19-16} = addr{12-9}; 5450 let Inst{15-12} = CRd; 5451 let Inst{11-8} = cop; 5452 let Inst{7-0} = addr{7-0}; 5453 let DecoderMethod = "DecodeCopMemInstruction"; 5454 } 5455 def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 5456 postidx_imm8s4:$offset), 5457 asm, "\t$cop, $CRd, $addr, $offset", [], IndexModePost> { 5458 bits<9> offset; 5459 bits<4> addr; 5460 bits<4> cop; 5461 bits<4> CRd; 5462 let Inst{24} = 0; // P = 0 5463 let Inst{23} = offset{8}; 5464 let Inst{22} = Dbit; 5465 let Inst{21} = 1; // W = 1 5466 let Inst{20} = load; 5467 let Inst{19-16} = addr; 5468 let Inst{15-12} = CRd; 5469 let Inst{11-8} = cop; 5470 let Inst{7-0} = offset{7-0}; 5471 let DecoderMethod = "DecodeCopMemInstruction"; 5472 } 5473 def _OPTION : ACI<(outs), 5474 (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 5475 coproc_option_imm:$option), 5476 asm, "\t$cop, $CRd, $addr, $option", []> { 5477 bits<8> option; 5478 bits<4> addr; 5479 bits<4> cop; 5480 bits<4> CRd; 5481 let Inst{24} = 0; // P = 0 5482 let Inst{23} = 1; // U = 1 5483 let Inst{22} = Dbit; 5484 let Inst{21} = 0; // W = 0 5485 let Inst{20} = load; 5486 let Inst{19-16} = addr; 5487 let Inst{15-12} = CRd; 5488 let Inst{11-8} = cop; 5489 let Inst{7-0} = option; 5490 let DecoderMethod = "DecodeCopMemInstruction"; 5491 } 5492} 5493multiclass LdSt2Cop<bit load, bit Dbit, string asm, list<dag> pattern> { 5494 def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 5495 asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone, 5496 AddrMode5> { 5497 bits<13> addr; 5498 bits<4> cop; 5499 bits<4> CRd; 5500 let Inst{24} = 1; // P = 1 5501 let Inst{23} = addr{8}; 5502 let Inst{22} = Dbit; 5503 let Inst{21} = 0; // W = 0 5504 let Inst{20} = load; 5505 let Inst{19-16} = addr{12-9}; 5506 let Inst{15-12} = CRd; 5507 let Inst{11-8} = cop; 5508 let Inst{7-0} = addr{7-0}; 5509 let DecoderMethod = "DecodeCopMemInstruction"; 5510 } 5511 def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), 5512 asm, "\t$cop, $CRd, $addr!", [], IndexModePre> { 5513 bits<13> addr; 5514 bits<4> cop; 5515 bits<4> CRd; 5516 let Inst{24} = 1; // P = 1 5517 let Inst{23} = addr{8}; 5518 let Inst{22} = Dbit; 5519 let Inst{21} = 1; // W = 1 5520 let Inst{20} = load; 5521 let Inst{19-16} = addr{12-9}; 5522 let Inst{15-12} = CRd; 5523 let Inst{11-8} = cop; 5524 let Inst{7-0} = addr{7-0}; 5525 let DecoderMethod = "DecodeCopMemInstruction"; 5526 } 5527 def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 5528 postidx_imm8s4:$offset), 5529 asm, "\t$cop, $CRd, $addr, $offset", [], IndexModePost> { 5530 bits<9> offset; 5531 bits<4> addr; 5532 bits<4> cop; 5533 bits<4> CRd; 5534 let Inst{24} = 0; // P = 0 5535 let Inst{23} = offset{8}; 5536 let Inst{22} = Dbit; 5537 let Inst{21} = 1; // W = 1 5538 let Inst{20} = load; 5539 let Inst{19-16} = addr; 5540 let Inst{15-12} = CRd; 5541 let Inst{11-8} = cop; 5542 let Inst{7-0} = offset{7-0}; 5543 let DecoderMethod = "DecodeCopMemInstruction"; 5544 } 5545 def _OPTION : ACInoP<(outs), 5546 (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 5547 coproc_option_imm:$option), 5548 asm, "\t$cop, $CRd, $addr, $option", []> { 5549 bits<8> option; 5550 bits<4> addr; 5551 bits<4> cop; 5552 bits<4> CRd; 5553 let Inst{24} = 0; // P = 0 5554 let Inst{23} = 1; // U = 1 5555 let Inst{22} = Dbit; 5556 let Inst{21} = 0; // W = 0 5557 let Inst{20} = load; 5558 let Inst{19-16} = addr; 5559 let Inst{15-12} = CRd; 5560 let Inst{11-8} = cop; 5561 let Inst{7-0} = option; 5562 let DecoderMethod = "DecodeCopMemInstruction"; 5563 } 5564} 5565 5566defm LDC : LdStCop <1, 0, "ldc", [(int_arm_ldc timm:$cop, timm:$CRd, addrmode5:$addr)]>; 5567defm LDCL : LdStCop <1, 1, "ldcl", [(int_arm_ldcl timm:$cop, timm:$CRd, addrmode5:$addr)]>; 5568defm LDC2 : LdSt2Cop<1, 0, "ldc2", [(int_arm_ldc2 timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; 5569defm LDC2L : LdSt2Cop<1, 1, "ldc2l", [(int_arm_ldc2l timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; 5570 5571defm STC : LdStCop <0, 0, "stc", [(int_arm_stc timm:$cop, timm:$CRd, addrmode5:$addr)]>; 5572defm STCL : LdStCop <0, 1, "stcl", [(int_arm_stcl timm:$cop, timm:$CRd, addrmode5:$addr)]>; 5573defm STC2 : LdSt2Cop<0, 0, "stc2", [(int_arm_stc2 timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; 5574defm STC2L : LdSt2Cop<0, 1, "stc2l", [(int_arm_stc2l timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; 5575 5576} // DecoderNamespace = "CoProc" 5577 5578//===----------------------------------------------------------------------===// 5579// Move between coprocessor and ARM core register. 5580// 5581 5582class MovRCopro<string opc, bit direction, dag oops, dag iops, 5583 list<dag> pattern> 5584 : ABI<0b1110, oops, iops, NoItinerary, opc, 5585 "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", pattern> { 5586 let Inst{20} = direction; 5587 let Inst{4} = 1; 5588 5589 bits<4> Rt; 5590 bits<4> cop; 5591 bits<3> opc1; 5592 bits<3> opc2; 5593 bits<4> CRm; 5594 bits<4> CRn; 5595 5596 let Inst{15-12} = Rt; 5597 let Inst{11-8} = cop; 5598 let Inst{23-21} = opc1; 5599 let Inst{7-5} = opc2; 5600 let Inst{3-0} = CRm; 5601 let Inst{19-16} = CRn; 5602 5603 let DecoderNamespace = "CoProc"; 5604} 5605 5606def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */, 5607 (outs), 5608 (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 5609 c_imm:$CRm, imm0_7:$opc2), 5610 [(int_arm_mcr timm:$cop, timm:$opc1, GPR:$Rt, timm:$CRn, 5611 timm:$CRm, timm:$opc2)]>, 5612 ComplexDeprecationPredicate<"MCR">; 5613def : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm", 5614 (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 5615 c_imm:$CRm, 0, pred:$p)>; 5616def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */, 5617 (outs GPRwithAPSR:$Rt), 5618 (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 5619 imm0_7:$opc2), []>, 5620 ComplexDeprecationPredicate<"MRC">; 5621def : ARMInstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm", 5622 (MRC GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 5623 c_imm:$CRm, 0, pred:$p)>; 5624 5625def : ARMPat<(int_arm_mrc timm:$cop, timm:$opc1, timm:$CRn, timm:$CRm, timm:$opc2), 5626 (MRC p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2)>; 5627 5628class MovRCopro2<string opc, bit direction, dag oops, dag iops, 5629 list<dag> pattern> 5630 : ABXI<0b1110, oops, iops, NoItinerary, 5631 !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), pattern> { 5632 let Inst{31-24} = 0b11111110; 5633 let Inst{20} = direction; 5634 let Inst{4} = 1; 5635 5636 bits<4> Rt; 5637 bits<4> cop; 5638 bits<3> opc1; 5639 bits<3> opc2; 5640 bits<4> CRm; 5641 bits<4> CRn; 5642 5643 let Inst{15-12} = Rt; 5644 let Inst{11-8} = cop; 5645 let Inst{23-21} = opc1; 5646 let Inst{7-5} = opc2; 5647 let Inst{3-0} = CRm; 5648 let Inst{19-16} = CRn; 5649 5650 let DecoderNamespace = "CoProc"; 5651} 5652 5653def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */, 5654 (outs), 5655 (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 5656 c_imm:$CRm, imm0_7:$opc2), 5657 [(int_arm_mcr2 timm:$cop, timm:$opc1, GPR:$Rt, timm:$CRn, 5658 timm:$CRm, timm:$opc2)]>, 5659 Requires<[IsARM,PreV8]>; 5660def : ARMInstAlias<"mcr2 $cop, $opc1, $Rt, $CRn, $CRm", 5661 (MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 5662 c_imm:$CRm, 0)>; 5663def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */, 5664 (outs GPRwithAPSR:$Rt), 5665 (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 5666 imm0_7:$opc2), []>, 5667 Requires<[IsARM,PreV8]>; 5668def : ARMInstAlias<"mrc2 $cop, $opc1, $Rt, $CRn, $CRm", 5669 (MRC2 GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 5670 c_imm:$CRm, 0)>; 5671 5672def : ARMV5TPat<(int_arm_mrc2 timm:$cop, timm:$opc1, timm:$CRn, 5673 timm:$CRm, timm:$opc2), 5674 (MRC2 p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2)>; 5675 5676class MovRRCopro<string opc, bit direction, dag oops, dag iops, list<dag> 5677 pattern = []> 5678 : ABI<0b1100, oops, iops, NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", 5679 pattern> { 5680 5681 let Inst{23-21} = 0b010; 5682 let Inst{20} = direction; 5683 5684 bits<4> Rt; 5685 bits<4> Rt2; 5686 bits<4> cop; 5687 bits<4> opc1; 5688 bits<4> CRm; 5689 5690 let Inst{15-12} = Rt; 5691 let Inst{19-16} = Rt2; 5692 let Inst{11-8} = cop; 5693 let Inst{7-4} = opc1; 5694 let Inst{3-0} = CRm; 5695} 5696 5697def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, 5698 (outs), (ins p_imm:$cop, imm0_15:$opc1, GPRnopc:$Rt, 5699 GPRnopc:$Rt2, c_imm:$CRm), 5700 [(int_arm_mcrr timm:$cop, timm:$opc1, GPRnopc:$Rt, 5701 GPRnopc:$Rt2, timm:$CRm)]>; 5702def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */, 5703 (outs GPRnopc:$Rt, GPRnopc:$Rt2), 5704 (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>; 5705 5706class MovRRCopro2<string opc, bit direction, dag oops, dag iops, 5707 list<dag> pattern = []> 5708 : ABXI<0b1100, oops, iops, NoItinerary, 5709 !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern>, 5710 Requires<[IsARM,PreV8]> { 5711 let Inst{31-28} = 0b1111; 5712 let Inst{23-21} = 0b010; 5713 let Inst{20} = direction; 5714 5715 bits<4> Rt; 5716 bits<4> Rt2; 5717 bits<4> cop; 5718 bits<4> opc1; 5719 bits<4> CRm; 5720 5721 let Inst{15-12} = Rt; 5722 let Inst{19-16} = Rt2; 5723 let Inst{11-8} = cop; 5724 let Inst{7-4} = opc1; 5725 let Inst{3-0} = CRm; 5726 5727 let DecoderMethod = "DecoderForMRRC2AndMCRR2"; 5728} 5729 5730def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */, 5731 (outs), (ins p_imm:$cop, imm0_15:$opc1, GPRnopc:$Rt, 5732 GPRnopc:$Rt2, c_imm:$CRm), 5733 [(int_arm_mcrr2 timm:$cop, timm:$opc1, GPRnopc:$Rt, 5734 GPRnopc:$Rt2, timm:$CRm)]>; 5735 5736def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */, 5737 (outs GPRnopc:$Rt, GPRnopc:$Rt2), 5738 (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>; 5739 5740//===----------------------------------------------------------------------===// 5741// Move between special register and ARM core register 5742// 5743 5744// Move to ARM core register from Special Register 5745def MRS : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, 5746 "mrs", "\t$Rd, apsr", []> { 5747 bits<4> Rd; 5748 let Inst{23-16} = 0b00001111; 5749 let Unpredictable{19-17} = 0b111; 5750 5751 let Inst{15-12} = Rd; 5752 5753 let Inst{11-0} = 0b000000000000; 5754 let Unpredictable{11-0} = 0b110100001111; 5755} 5756 5757def : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPRnopc:$Rd, pred:$p), 0>, 5758 Requires<[IsARM]>; 5759 5760// The MRSsys instruction is the MRS instruction from the ARM ARM, 5761// section B9.3.9, with the R bit set to 1. 5762def MRSsys : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, 5763 "mrs", "\t$Rd, spsr", []> { 5764 bits<4> Rd; 5765 let Inst{23-16} = 0b01001111; 5766 let Unpredictable{19-16} = 0b1111; 5767 5768 let Inst{15-12} = Rd; 5769 5770 let Inst{11-0} = 0b000000000000; 5771 let Unpredictable{11-0} = 0b110100001111; 5772} 5773 5774// However, the MRS (banked register) system instruction (ARMv7VE) *does* have a 5775// separate encoding (distinguished by bit 5. 5776def MRSbanked : ABI<0b0001, (outs GPRnopc:$Rd), (ins banked_reg:$banked), 5777 NoItinerary, "mrs", "\t$Rd, $banked", []>, 5778 Requires<[IsARM, HasVirtualization]> { 5779 bits<6> banked; 5780 bits<4> Rd; 5781 5782 let Inst{23} = 0; 5783 let Inst{22} = banked{5}; // R bit 5784 let Inst{21-20} = 0b00; 5785 let Inst{19-16} = banked{3-0}; 5786 let Inst{15-12} = Rd; 5787 let Inst{11-9} = 0b001; 5788 let Inst{8} = banked{4}; 5789 let Inst{7-0} = 0b00000000; 5790} 5791 5792// Move from ARM core register to Special Register 5793// 5794// No need to have both system and application versions of MSR (immediate) or 5795// MSR (register), the encodings are the same and the assembly parser has no way 5796// to distinguish between them. The mask operand contains the special register 5797// (R Bit) in bit 4 and bits 3-0 contains the mask with the fields to be 5798// accessed in the special register. 5799let Defs = [CPSR] in 5800def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary, 5801 "msr", "\t$mask, $Rn", []> { 5802 bits<5> mask; 5803 bits<4> Rn; 5804 5805 let Inst{23} = 0; 5806 let Inst{22} = mask{4}; // R bit 5807 let Inst{21-20} = 0b10; 5808 let Inst{19-16} = mask{3-0}; 5809 let Inst{15-12} = 0b1111; 5810 let Inst{11-4} = 0b00000000; 5811 let Inst{3-0} = Rn; 5812} 5813 5814let Defs = [CPSR] in 5815def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, mod_imm:$imm), NoItinerary, 5816 "msr", "\t$mask, $imm", []> { 5817 bits<5> mask; 5818 bits<12> imm; 5819 5820 let Inst{23} = 0; 5821 let Inst{22} = mask{4}; // R bit 5822 let Inst{21-20} = 0b10; 5823 let Inst{19-16} = mask{3-0}; 5824 let Inst{15-12} = 0b1111; 5825 let Inst{11-0} = imm; 5826} 5827 5828// However, the MSR (banked register) system instruction (ARMv7VE) *does* have a 5829// separate encoding (distinguished by bit 5. 5830def MSRbanked : ABI<0b0001, (outs), (ins banked_reg:$banked, GPRnopc:$Rn), 5831 NoItinerary, "msr", "\t$banked, $Rn", []>, 5832 Requires<[IsARM, HasVirtualization]> { 5833 bits<6> banked; 5834 bits<4> Rn; 5835 5836 let Inst{23} = 0; 5837 let Inst{22} = banked{5}; // R bit 5838 let Inst{21-20} = 0b10; 5839 let Inst{19-16} = banked{3-0}; 5840 let Inst{15-12} = 0b1111; 5841 let Inst{11-9} = 0b001; 5842 let Inst{8} = banked{4}; 5843 let Inst{7-4} = 0b0000; 5844 let Inst{3-0} = Rn; 5845} 5846 5847// Dynamic stack allocation yields a _chkstk for Windows targets. These calls 5848// are needed to probe the stack when allocating more than 5849// 4k bytes in one go. Touching the stack at 4K increments is necessary to 5850// ensure that the guard pages used by the OS virtual memory manager are 5851// allocated in correct sequence. 5852// The main point of having separate instruction are extra unmodelled effects 5853// (compared to ordinary calls) like stack pointer change. 5854 5855def win__chkstk : SDNode<"ARMISD::WIN__CHKSTK", SDTNone, 5856 [SDNPHasChain, SDNPSideEffect]>; 5857let usesCustomInserter = 1, Uses = [R4], Defs = [R4, SP], hasNoSchedulingInfo = 1 in 5858 def WIN__CHKSTK : PseudoInst<(outs), (ins), NoItinerary, [(win__chkstk)]>; 5859 5860def win__dbzchk : SDNode<"ARMISD::WIN__DBZCHK", SDT_WIN__DBZCHK, 5861 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; 5862let usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in 5863 def WIN__DBZCHK : PseudoInst<(outs), (ins tGPR:$divisor), NoItinerary, 5864 [(win__dbzchk tGPR:$divisor)]>; 5865 5866//===----------------------------------------------------------------------===// 5867// TLS Instructions 5868// 5869 5870// __aeabi_read_tp preserves the registers r1-r3. 5871// This is a pseudo inst so that we can get the encoding right, 5872// complete with fixup for the aeabi_read_tp function. 5873// TPsoft is valid for ARM mode only, in case of Thumb mode a tTPsoft pattern 5874// is defined in "ARMInstrThumb.td". 5875let isCall = 1, 5876 Defs = [R0, R12, LR, CPSR], Uses = [SP] in { 5877 def TPsoft : ARMPseudoInst<(outs), (ins), 4, IIC_Br, 5878 [(set R0, ARMthread_pointer)]>, Sched<[WriteBr]>, 5879 Requires<[IsARM, IsReadTPSoft]>; 5880} 5881 5882// Reading thread pointer from coprocessor register 5883def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 3)>, 5884 Requires<[IsARM, IsReadTPHard]>; 5885 5886//===----------------------------------------------------------------------===// 5887// SJLJ Exception handling intrinsics 5888// eh_sjlj_setjmp() is an instruction sequence to store the return 5889// address and save #0 in R0 for the non-longjmp case. 5890// Since by its nature we may be coming from some other function to get 5891// here, and we're using the stack frame for the containing function to 5892// save/restore registers, we can't keep anything live in regs across 5893// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 5894// when we get here from a longjmp(). We force everything out of registers 5895// except for our own input by listing the relevant registers in Defs. By 5896// doing so, we also cause the prologue/epilogue code to actively preserve 5897// all of the callee-saved registers, which is exactly what we want. 5898// A constant value is passed in $val, and we use the location as a scratch. 5899// 5900// These are pseudo-instructions and are lowered to individual MC-insts, so 5901// no encoding information is necessary. 5902// This gets lowered to an instruction sequence of 20 bytes 5903let Defs = 5904 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, 5905 Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ], 5906 hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in { 5907 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 5908 NoItinerary, 5909 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 5910 Requires<[IsARM, HasVFP2]>; 5911} 5912 5913// This gets lowered to an instruction sequence of 20 bytes 5914let Defs = 5915 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], 5916 hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in { 5917 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 5918 NoItinerary, 5919 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 5920 Requires<[IsARM, NoVFP]>; 5921} 5922 5923// This gets lowered to an instruction sequence of 16 bytes 5924// FIXME: Non-IOS version(s) 5925let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, Size = 16, 5926 Defs = [ R7, LR, SP ] in { 5927def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch), 5928 NoItinerary, 5929 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, 5930 Requires<[IsARM]>; 5931} 5932 5933let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in 5934def Int_eh_sjlj_setup_dispatch : PseudoInst<(outs), (ins), NoItinerary, 5935 [(ARMeh_sjlj_setup_dispatch)]>; 5936 5937// eh.sjlj.dispatchsetup pseudo-instruction. 5938// This pseudo is used for both ARM and Thumb. Any differences are handled when 5939// the pseudo is expanded (which happens before any passes that need the 5940// instruction size). 5941let isBarrier = 1 in 5942def Int_eh_sjlj_dispatchsetup : PseudoInst<(outs), (ins), NoItinerary, []>; 5943 5944 5945//===----------------------------------------------------------------------===// 5946// Non-Instruction Patterns 5947// 5948 5949// ARMv4 indirect branch using (MOVr PC, dst) 5950let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in 5951 def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst), 5952 4, IIC_Br, [(brind GPR:$dst)], 5953 (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, 5954 Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; 5955 5956let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in 5957 def TAILJMPr4 : ARMPseudoExpand<(outs), (ins GPR:$dst), 5958 4, IIC_Br, [], 5959 (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, 5960 Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; 5961 5962// Large immediate handling. 5963 5964// 32-bit immediate using two piece mod_imms or movw + movt. 5965// This is a single pseudo instruction, the benefit is that it can be remat'd 5966// as a single unit instead of having to handle reg inputs. 5967// FIXME: Remove this when we can do generalized remat. 5968let isReMaterializable = 1, isMoveImm = 1, Size = 8 in 5969def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 5970 [(set GPR:$dst, (arm_i32imm:$src))]>, 5971 Requires<[IsARM]>; 5972 5973def LDRLIT_ga_abs : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iLoad_i, 5974 [(set GPR:$dst, (ARMWrapper tglobaladdr:$src))]>, 5975 Requires<[IsARM, DontUseMovt]>; 5976 5977// Pseudo instruction that combines movw + movt + add pc (if PIC). 5978// It also makes it possible to rematerialize the instructions. 5979// FIXME: Remove this when we can do generalized remat and when machine licm 5980// can properly the instructions. 5981let isReMaterializable = 1 in { 5982def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 5983 IIC_iMOVix2addpc, 5984 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, 5985 Requires<[IsARM, UseMovtInPic]>; 5986 5987def LDRLIT_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 5988 IIC_iLoadiALU, 5989 [(set GPR:$dst, 5990 (ARMWrapperPIC tglobaladdr:$addr))]>, 5991 Requires<[IsARM, DontUseMovtInPic]>; 5992 5993let AddedComplexity = 10 in 5994def LDRLIT_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 5995 NoItinerary, 5996 [(set GPR:$dst, 5997 (load (ARMWrapperPIC tglobaladdr:$addr)))]>, 5998 Requires<[IsARM, DontUseMovtInPic]>; 5999 6000let AddedComplexity = 10 in 6001def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 6002 IIC_iMOVix2ld, 6003 [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, 6004 Requires<[IsARM, UseMovtInPic]>; 6005} // isReMaterializable 6006 6007// The many different faces of TLS access. 6008def : ARMPat<(ARMWrapper tglobaltlsaddr :$dst), 6009 (MOVi32imm tglobaltlsaddr :$dst)>, 6010 Requires<[IsARM, UseMovt]>; 6011 6012def : Pat<(ARMWrapper tglobaltlsaddr:$src), 6013 (LDRLIT_ga_abs tglobaltlsaddr:$src)>, 6014 Requires<[IsARM, DontUseMovt]>; 6015 6016def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), 6017 (MOV_ga_pcrel tglobaltlsaddr:$addr)>, Requires<[IsARM, UseMovtInPic]>; 6018 6019def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), 6020 (LDRLIT_ga_pcrel tglobaltlsaddr:$addr)>, 6021 Requires<[IsARM, DontUseMovtInPic]>; 6022let AddedComplexity = 10 in 6023def : Pat<(load (ARMWrapperPIC tglobaltlsaddr:$addr)), 6024 (MOV_ga_pcrel_ldr tglobaltlsaddr:$addr)>, 6025 Requires<[IsARM, UseMovtInPic]>; 6026 6027 6028// ConstantPool, GlobalAddress, and JumpTable 6029def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; 6030def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>, 6031 Requires<[IsARM, UseMovt]>; 6032def : ARMPat<(ARMWrapper texternalsym :$dst), (MOVi32imm texternalsym :$dst)>, 6033 Requires<[IsARM, UseMovt]>; 6034def : ARMPat<(ARMWrapperJT tjumptable:$dst), 6035 (LEApcrelJT tjumptable:$dst)>; 6036 6037// TODO: add,sub,and, 3-instr forms? 6038 6039// Tail calls. These patterns also apply to Thumb mode. 6040def : Pat<(ARMtcret tcGPR:$dst, (i32 timm:$SPDiff)), 6041 (TCRETURNri tcGPR:$dst, timm:$SPDiff)>; 6042def : Pat<(ARMtcret (i32 tglobaladdr:$dst), (i32 timm:$SPDiff)), 6043 (TCRETURNdi texternalsym:$dst, (i32 timm:$SPDiff))>; 6044def : Pat<(ARMtcret (i32 texternalsym:$dst), (i32 timm:$SPDiff)), 6045 (TCRETURNdi texternalsym:$dst, i32imm:$SPDiff)>; 6046 6047// Direct calls 6048def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>; 6049def : ARMPat<(ARMcall_nolink texternalsym:$func), 6050 (BMOVPCB_CALL texternalsym:$func)>; 6051 6052// zextload i1 -> zextload i8 6053def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 6054def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 6055 6056// extload -> zextload 6057def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 6058def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 6059def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 6060def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 6061 6062def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; 6063 6064def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; 6065def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>; 6066 6067// smul* and smla* 6068def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b), 6069 (SMULBB GPR:$a, GPR:$b)>; 6070def : ARMV5TEPat<(mul sext_16_node:$a, (sext_bottom_16 GPR:$b)), 6071 (SMULBB GPR:$a, GPR:$b)>; 6072def : ARMV5TEPat<(mul sext_16_node:$a, (sext_top_16 GPR:$b)), 6073 (SMULBT GPR:$a, GPR:$b)>; 6074def : ARMV5TEPat<(mul (sext_top_16 GPR:$a), sext_16_node:$b), 6075 (SMULTB GPR:$a, GPR:$b)>; 6076def : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, sext_16_node:$b)), 6077 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 6078def : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, (sext_bottom_16 GPR:$b))), 6079 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 6080def : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, (sext_top_16 GPR:$b))), 6081 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 6082def : ARMV5MOPat<(add GPR:$acc, (mul (sext_top_16 GPR:$a), sext_16_node:$b)), 6083 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 6084 6085def : ARMV5TEPat<(int_arm_smulbb GPR:$a, GPR:$b), 6086 (SMULBB GPR:$a, GPR:$b)>; 6087def : ARMV5TEPat<(int_arm_smulbt GPR:$a, GPR:$b), 6088 (SMULBT GPR:$a, GPR:$b)>; 6089def : ARMV5TEPat<(int_arm_smultb GPR:$a, GPR:$b), 6090 (SMULTB GPR:$a, GPR:$b)>; 6091def : ARMV5TEPat<(int_arm_smultt GPR:$a, GPR:$b), 6092 (SMULTT GPR:$a, GPR:$b)>; 6093def : ARMV5TEPat<(int_arm_smulwb GPR:$a, GPR:$b), 6094 (SMULWB GPR:$a, GPR:$b)>; 6095def : ARMV5TEPat<(int_arm_smulwt GPR:$a, GPR:$b), 6096 (SMULWT GPR:$a, GPR:$b)>; 6097 6098def : ARMV5TEPat<(int_arm_smlabb GPR:$a, GPR:$b, GPR:$acc), 6099 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 6100def : ARMV5TEPat<(int_arm_smlabt GPR:$a, GPR:$b, GPR:$acc), 6101 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 6102def : ARMV5TEPat<(int_arm_smlatb GPR:$a, GPR:$b, GPR:$acc), 6103 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 6104def : ARMV5TEPat<(int_arm_smlatt GPR:$a, GPR:$b, GPR:$acc), 6105 (SMLATT GPR:$a, GPR:$b, GPR:$acc)>; 6106def : ARMV5TEPat<(int_arm_smlawb GPR:$a, GPR:$b, GPR:$acc), 6107 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 6108def : ARMV5TEPat<(int_arm_smlawt GPR:$a, GPR:$b, GPR:$acc), 6109 (SMLAWT GPR:$a, GPR:$b, GPR:$acc)>; 6110 6111// Pre-v7 uses MCR for synchronization barriers. 6112def : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>, 6113 Requires<[IsARM, HasV6]>; 6114 6115// SXT/UXT with no rotate 6116let AddedComplexity = 16 in { 6117def : ARMV6Pat<(and GPR:$Src, 0x000000FF), (UXTB GPR:$Src, 0)>; 6118def : ARMV6Pat<(and GPR:$Src, 0x0000FFFF), (UXTH GPR:$Src, 0)>; 6119def : ARMV6Pat<(and GPR:$Src, 0x00FF00FF), (UXTB16 GPR:$Src, 0)>; 6120def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0x00FF)), 6121 (UXTAB GPR:$Rn, GPR:$Rm, 0)>; 6122def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0xFFFF)), 6123 (UXTAH GPR:$Rn, GPR:$Rm, 0)>; 6124} 6125 6126def : ARMV6Pat<(sext_inreg GPR:$Src, i8), (SXTB GPR:$Src, 0)>; 6127def : ARMV6Pat<(sext_inreg GPR:$Src, i16), (SXTH GPR:$Src, 0)>; 6128 6129def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i8)), 6130 (SXTAB GPR:$Rn, GPRnopc:$Rm, 0)>; 6131def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)), 6132 (SXTAH GPR:$Rn, GPRnopc:$Rm, 0)>; 6133 6134// Atomic load/store patterns 6135def : ARMPat<(atomic_load_8 ldst_so_reg:$src), 6136 (LDRBrs ldst_so_reg:$src)>; 6137def : ARMPat<(atomic_load_8 addrmode_imm12:$src), 6138 (LDRBi12 addrmode_imm12:$src)>; 6139def : ARMPat<(atomic_load_16 addrmode3:$src), 6140 (LDRH addrmode3:$src)>; 6141def : ARMPat<(atomic_load_32 ldst_so_reg:$src), 6142 (LDRrs ldst_so_reg:$src)>; 6143def : ARMPat<(atomic_load_32 addrmode_imm12:$src), 6144 (LDRi12 addrmode_imm12:$src)>; 6145def : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val), 6146 (STRBrs GPR:$val, ldst_so_reg:$ptr)>; 6147def : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val), 6148 (STRBi12 GPR:$val, addrmode_imm12:$ptr)>; 6149def : ARMPat<(atomic_store_16 addrmode3:$ptr, GPR:$val), 6150 (STRH GPR:$val, addrmode3:$ptr)>; 6151def : ARMPat<(atomic_store_32 ldst_so_reg:$ptr, GPR:$val), 6152 (STRrs GPR:$val, ldst_so_reg:$ptr)>; 6153def : ARMPat<(atomic_store_32 addrmode_imm12:$ptr, GPR:$val), 6154 (STRi12 GPR:$val, addrmode_imm12:$ptr)>; 6155 6156 6157//===----------------------------------------------------------------------===// 6158// Thumb Support 6159// 6160 6161include "ARMInstrThumb.td" 6162 6163//===----------------------------------------------------------------------===// 6164// Thumb2 Support 6165// 6166 6167include "ARMInstrThumb2.td" 6168 6169//===----------------------------------------------------------------------===// 6170// Floating Point Support 6171// 6172 6173include "ARMInstrVFP.td" 6174 6175//===----------------------------------------------------------------------===// 6176// Advanced SIMD (NEON) Support 6177// 6178 6179include "ARMInstrNEON.td" 6180 6181//===----------------------------------------------------------------------===// 6182// MVE Support 6183// 6184 6185include "ARMInstrMVE.td" 6186 6187//===----------------------------------------------------------------------===// 6188// CDE (Custom Datapath Extension) 6189// 6190 6191include "ARMInstrCDE.td" 6192 6193//===----------------------------------------------------------------------===// 6194// Assembler aliases 6195// 6196 6197// Memory barriers 6198def : InstAlias<"dmb", (DMB 0xf), 0>, Requires<[IsARM, HasDB]>; 6199def : InstAlias<"dsb", (DSB 0xf), 0>, Requires<[IsARM, HasDB]>; 6200def : InstAlias<"ssbb", (DSB 0x0), 1>, Requires<[IsARM, HasDB]>; 6201def : InstAlias<"pssbb", (DSB 0x4), 1>, Requires<[IsARM, HasDB]>; 6202def : InstAlias<"isb", (ISB 0xf), 0>, Requires<[IsARM, HasDB]>; 6203// Armv8-R 'Data Full Barrier' 6204def : InstAlias<"dfb", (DSB 0xc), 1>, Requires<[IsARM, HasDFB]>; 6205 6206// System instructions 6207def : MnemonicAlias<"swi", "svc">; 6208 6209// Load / Store Multiple 6210def : MnemonicAlias<"ldmfd", "ldm">; 6211def : MnemonicAlias<"ldmia", "ldm">; 6212def : MnemonicAlias<"ldmea", "ldmdb">; 6213def : MnemonicAlias<"stmfd", "stmdb">; 6214def : MnemonicAlias<"stmia", "stm">; 6215def : MnemonicAlias<"stmea", "stm">; 6216 6217// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT with the 6218// input operands swapped when the shift amount is zero (i.e., unspecified). 6219def : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm", 6220 (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p), 0>, 6221 Requires<[IsARM, HasV6]>; 6222def : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm", 6223 (PKHBT GPRnopc:$Rd, GPRnopc:$Rm, GPRnopc:$Rn, 0, pred:$p), 0>, 6224 Requires<[IsARM, HasV6]>; 6225 6226// PUSH/POP aliases for STM/LDM 6227def : ARMInstAlias<"push${p} $regs", (STMDB_UPD SP, pred:$p, reglist:$regs)>; 6228def : ARMInstAlias<"pop${p} $regs", (LDMIA_UPD SP, pred:$p, reglist:$regs)>; 6229 6230// SSAT/USAT optional shift operand. 6231def : ARMInstAlias<"ssat${p} $Rd, $sat_imm, $Rn", 6232 (SSAT GPRnopc:$Rd, imm1_32:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; 6233def : ARMInstAlias<"usat${p} $Rd, $sat_imm, $Rn", 6234 (USAT GPRnopc:$Rd, imm0_31:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; 6235 6236 6237// Extend instruction optional rotate operand. 6238def : ARMInstAlias<"sxtab${p} $Rd, $Rn, $Rm", 6239 (SXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 6240def : ARMInstAlias<"sxtah${p} $Rd, $Rn, $Rm", 6241 (SXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 6242def : ARMInstAlias<"sxtab16${p} $Rd, $Rn, $Rm", 6243 (SXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 6244def : ARMInstAlias<"sxtb${p} $Rd, $Rm", 6245 (SXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 6246def : ARMInstAlias<"sxtb16${p} $Rd, $Rm", 6247 (SXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 6248def : ARMInstAlias<"sxth${p} $Rd, $Rm", 6249 (SXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 6250 6251def : ARMInstAlias<"uxtab${p} $Rd, $Rn, $Rm", 6252 (UXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 6253def : ARMInstAlias<"uxtah${p} $Rd, $Rn, $Rm", 6254 (UXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 6255def : ARMInstAlias<"uxtab16${p} $Rd, $Rn, $Rm", 6256 (UXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 6257def : ARMInstAlias<"uxtb${p} $Rd, $Rm", 6258 (UXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 6259def : ARMInstAlias<"uxtb16${p} $Rd, $Rm", 6260 (UXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 6261def : ARMInstAlias<"uxth${p} $Rd, $Rm", 6262 (UXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 6263 6264 6265// RFE aliases 6266def : MnemonicAlias<"rfefa", "rfeda">; 6267def : MnemonicAlias<"rfeea", "rfedb">; 6268def : MnemonicAlias<"rfefd", "rfeia">; 6269def : MnemonicAlias<"rfeed", "rfeib">; 6270def : MnemonicAlias<"rfe", "rfeia">; 6271 6272// SRS aliases 6273def : MnemonicAlias<"srsfa", "srsib">; 6274def : MnemonicAlias<"srsea", "srsia">; 6275def : MnemonicAlias<"srsfd", "srsdb">; 6276def : MnemonicAlias<"srsed", "srsda">; 6277def : MnemonicAlias<"srs", "srsia">; 6278 6279// QSAX == QSUBADDX 6280def : MnemonicAlias<"qsubaddx", "qsax">; 6281// SASX == SADDSUBX 6282def : MnemonicAlias<"saddsubx", "sasx">; 6283// SHASX == SHADDSUBX 6284def : MnemonicAlias<"shaddsubx", "shasx">; 6285// SHSAX == SHSUBADDX 6286def : MnemonicAlias<"shsubaddx", "shsax">; 6287// SSAX == SSUBADDX 6288def : MnemonicAlias<"ssubaddx", "ssax">; 6289// UASX == UADDSUBX 6290def : MnemonicAlias<"uaddsubx", "uasx">; 6291// UHASX == UHADDSUBX 6292def : MnemonicAlias<"uhaddsubx", "uhasx">; 6293// UHSAX == UHSUBADDX 6294def : MnemonicAlias<"uhsubaddx", "uhsax">; 6295// UQASX == UQADDSUBX 6296def : MnemonicAlias<"uqaddsubx", "uqasx">; 6297// UQSAX == UQSUBADDX 6298def : MnemonicAlias<"uqsubaddx", "uqsax">; 6299// USAX == USUBADDX 6300def : MnemonicAlias<"usubaddx", "usax">; 6301 6302// "mov Rd, mod_imm_not" can be handled via "mvn" in assembly, just like 6303// for isel. 6304def : ARMInstSubst<"mov${s}${p} $Rd, $imm", 6305 (MVNi rGPR:$Rd, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 6306def : ARMInstSubst<"mvn${s}${p} $Rd, $imm", 6307 (MOVi rGPR:$Rd, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 6308// Same for AND <--> BIC 6309def : ARMInstSubst<"bic${s}${p} $Rd, $Rn, $imm", 6310 (ANDri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, 6311 pred:$p, cc_out:$s)>; 6312def : ARMInstSubst<"bic${s}${p} $Rdn, $imm", 6313 (ANDri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, 6314 pred:$p, cc_out:$s)>; 6315def : ARMInstSubst<"and${s}${p} $Rd, $Rn, $imm", 6316 (BICri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, 6317 pred:$p, cc_out:$s)>; 6318def : ARMInstSubst<"and${s}${p} $Rdn, $imm", 6319 (BICri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, 6320 pred:$p, cc_out:$s)>; 6321 6322// Likewise, "add Rd, mod_imm_neg" -> sub 6323def : ARMInstSubst<"add${s}${p} $Rd, $Rn, $imm", 6324 (SUBri GPR:$Rd, GPR:$Rn, mod_imm_neg:$imm, pred:$p, cc_out:$s)>; 6325def : ARMInstSubst<"add${s}${p} $Rd, $imm", 6326 (SUBri GPR:$Rd, GPR:$Rd, mod_imm_neg:$imm, pred:$p, cc_out:$s)>; 6327// Likewise, "sub Rd, mod_imm_neg" -> add 6328def : ARMInstSubst<"sub${s}${p} $Rd, $Rn, $imm", 6329 (ADDri GPR:$Rd, GPR:$Rn, mod_imm_neg:$imm, pred:$p, cc_out:$s)>; 6330def : ARMInstSubst<"sub${s}${p} $Rd, $imm", 6331 (ADDri GPR:$Rd, GPR:$Rd, mod_imm_neg:$imm, pred:$p, cc_out:$s)>; 6332 6333 6334def : ARMInstSubst<"adc${s}${p} $Rd, $Rn, $imm", 6335 (SBCri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 6336def : ARMInstSubst<"adc${s}${p} $Rdn, $imm", 6337 (SBCri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 6338def : ARMInstSubst<"sbc${s}${p} $Rd, $Rn, $imm", 6339 (ADCri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 6340def : ARMInstSubst<"sbc${s}${p} $Rdn, $imm", 6341 (ADCri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 6342 6343// Same for CMP <--> CMN via mod_imm_neg 6344def : ARMInstSubst<"cmp${p} $Rd, $imm", 6345 (CMNri rGPR:$Rd, mod_imm_neg:$imm, pred:$p)>; 6346def : ARMInstSubst<"cmn${p} $Rd, $imm", 6347 (CMPri rGPR:$Rd, mod_imm_neg:$imm, pred:$p)>; 6348 6349// The shifter forms of the MOV instruction are aliased to the ASR, LSL, 6350// LSR, ROR, and RRX instructions. 6351// FIXME: We need C++ parser hooks to map the alias to the MOV 6352// encoding. It seems we should be able to do that sort of thing 6353// in tblgen, but it could get ugly. 6354let TwoOperandAliasConstraint = "$Rm = $Rd" in { 6355def ASRi : ARMAsmPseudo<"asr${s}${p} $Rd, $Rm, $imm", 6356 (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p, 6357 cc_out:$s)>; 6358def LSRi : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rm, $imm", 6359 (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p, 6360 cc_out:$s)>; 6361def LSLi : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rm, $imm", 6362 (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p, 6363 cc_out:$s)>; 6364def RORi : ARMAsmPseudo<"ror${s}${p} $Rd, $Rm, $imm", 6365 (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p, 6366 cc_out:$s)>; 6367} 6368def RRXi : ARMAsmPseudo<"rrx${s}${p} $Rd, $Rm", 6369 (ins GPR:$Rd, GPR:$Rm, pred:$p, cc_out:$s)>; 6370let TwoOperandAliasConstraint = "$Rn = $Rd" in { 6371def ASRr : ARMAsmPseudo<"asr${s}${p} $Rd, $Rn, $Rm", 6372 (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 6373 cc_out:$s)>; 6374def LSRr : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rn, $Rm", 6375 (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 6376 cc_out:$s)>; 6377def LSLr : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rn, $Rm", 6378 (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 6379 cc_out:$s)>; 6380def RORr : ARMAsmPseudo<"ror${s}${p} $Rd, $Rn, $Rm", 6381 (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 6382 cc_out:$s)>; 6383} 6384 6385// "neg" is and alias for "rsb rd, rn, #0" 6386def : ARMInstAlias<"neg${s}${p} $Rd, $Rm", 6387 (RSBri GPR:$Rd, GPR:$Rm, 0, pred:$p, cc_out:$s)>; 6388 6389// Pre-v6, 'mov r0, r0' was used as a NOP encoding. 6390def : InstAlias<"nop${p}", (MOVr R0, R0, pred:$p, zero_reg)>, 6391 Requires<[IsARM, NoV6]>; 6392 6393// MUL/UMLAL/SMLAL/UMULL/SMULL are available on all arches, but 6394// the instruction definitions need difference constraints pre-v6. 6395// Use these aliases for the assembly parsing on pre-v6. 6396def : InstAlias<"mul${s}${p} $Rd, $Rn, $Rm", 6397 (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s), 0>, 6398 Requires<[IsARM, NoV6]>; 6399def : InstAlias<"mla${s}${p} $Rd, $Rn, $Rm, $Ra", 6400 (MLA GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra, 6401 pred:$p, cc_out:$s), 0>, 6402 Requires<[IsARM, NoV6]>; 6403def : InstAlias<"smlal${s}${p} $RdLo, $RdHi, $Rn, $Rm", 6404 (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>, 6405 Requires<[IsARM, NoV6]>; 6406def : InstAlias<"umlal${s}${p} $RdLo, $RdHi, $Rn, $Rm", 6407 (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>, 6408 Requires<[IsARM, NoV6]>; 6409def : InstAlias<"smull${s}${p} $RdLo, $RdHi, $Rn, $Rm", 6410 (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>, 6411 Requires<[IsARM, NoV6]>; 6412def : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm", 6413 (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>, 6414 Requires<[IsARM, NoV6]>; 6415 6416// 'it' blocks in ARM mode just validate the predicates. The IT itself 6417// is discarded. 6418def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>, 6419 ComplexDeprecationPredicate<"IT">; 6420 6421let mayLoad = 1, mayStore =1, hasSideEffects = 1, hasNoSchedulingInfo = 1 in 6422def SPACE : PseudoInst<(outs GPR:$Rd), (ins i32imm:$size, GPR:$Rn), 6423 NoItinerary, 6424 [(set GPR:$Rd, (int_arm_space timm:$size, GPR:$Rn))]>; 6425 6426// SpeculationBarrierEndBB must only be used after an unconditional control 6427// flow, i.e. after a terminator for which isBarrier is True. 6428let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in { 6429 // This gets lowered to a pair of 4-byte instructions 6430 let Size = 8 in 6431 def SpeculationBarrierISBDSBEndBB 6432 : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>; 6433 // This gets lowered to a single 4-byte instructions 6434 let Size = 4 in 6435 def SpeculationBarrierSBEndBB 6436 : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>; 6437} 6438 6439//===---------------------------------- 6440// Atomic cmpxchg for -O0 6441//===---------------------------------- 6442 6443// The fast register allocator used during -O0 inserts spills to cover any VRegs 6444// live across basic block boundaries. When this happens between an LDXR and an 6445// STXR it can clear the exclusive monitor, causing all cmpxchg attempts to 6446// fail. 6447 6448// Unfortunately, this means we have to have an alternative (expanded 6449// post-regalloc) path for -O0 compilations. Fortunately this path can be 6450// significantly more naive than the standard expansion: we conservatively 6451// assume seq_cst, strong cmpxchg and omit clrex on failure. 6452 6453let Constraints = "@earlyclobber $Rd,@earlyclobber $temp", 6454 mayLoad = 1, mayStore = 1 in { 6455def CMP_SWAP_8 : PseudoInst<(outs GPR:$Rd, GPR:$temp), 6456 (ins GPR:$addr, GPR:$desired, GPR:$new), 6457 NoItinerary, []>, Sched<[]>; 6458 6459def CMP_SWAP_16 : PseudoInst<(outs GPR:$Rd, GPR:$temp), 6460 (ins GPR:$addr, GPR:$desired, GPR:$new), 6461 NoItinerary, []>, Sched<[]>; 6462 6463def CMP_SWAP_32 : PseudoInst<(outs GPR:$Rd, GPR:$temp), 6464 (ins GPR:$addr, GPR:$desired, GPR:$new), 6465 NoItinerary, []>, Sched<[]>; 6466 6467def CMP_SWAP_64 : PseudoInst<(outs GPRPair:$Rd, GPR:$temp), 6468 (ins GPR:$addr, GPRPair:$desired, GPRPair:$new), 6469 NoItinerary, []>, Sched<[]>; 6470} 6471 6472def CompilerBarrier : PseudoInst<(outs), (ins i32imm:$ordering), NoItinerary, 6473 [(atomic_fence timm:$ordering, 0)]> { 6474 let hasSideEffects = 1; 6475 let Size = 0; 6476 let AsmString = "@ COMPILER BARRIER"; 6477 let hasNoSchedulingInfo = 1; 6478} 6479