brintos

brintos / llvm-project-archived public Read only

0
0
Text · 255.8 KiB · ddc8941 Raw
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