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