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