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