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