10b57cec5SDimitry Andric//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric// 90b57cec5SDimitry Andric// This file describes the ARM instructions in TableGen format. 100b57cec5SDimitry Andric// 110b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric// ARM specific DAG Nodes. 150b57cec5SDimitry Andric// 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric// Type profiles. 180b57cec5SDimitry Andricdef SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>, 190b57cec5SDimitry Andric SDTCisVT<1, i32> ]>; 200b57cec5SDimitry Andricdef SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; 210b57cec5SDimitry Andricdef SDT_ARMStructByVal : SDTypeProfile<0, 4, 220b57cec5SDimitry Andric [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 230b57cec5SDimitry Andric SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 240b57cec5SDimitry Andric 250b57cec5SDimitry Andricdef SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>; 260b57cec5SDimitry Andric 270b57cec5SDimitry Andricdef SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andricdef SDT_ARMCMov : SDTypeProfile<1, 3, 300b57cec5SDimitry Andric [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 310b57cec5SDimitry Andric SDTCisVT<3, i32>]>; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andricdef SDT_ARMBrcond : SDTypeProfile<0, 2, 340b57cec5SDimitry Andric [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andricdef SDT_ARMBrJT : SDTypeProfile<0, 2, 370b57cec5SDimitry Andric [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andricdef SDT_ARMBr2JT : SDTypeProfile<0, 3, 400b57cec5SDimitry Andric [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 410b57cec5SDimitry Andric SDTCisVT<2, i32>]>; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andricdef SDT_ARMBCC_i64 : SDTypeProfile<0, 6, 440b57cec5SDimitry Andric [SDTCisVT<0, i32>, 450b57cec5SDimitry Andric SDTCisVT<1, i32>, SDTCisVT<2, i32>, 460b57cec5SDimitry Andric SDTCisVT<3, i32>, SDTCisVT<4, i32>, 470b57cec5SDimitry Andric SDTCisVT<5, OtherVT>]>; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andricdef SDT_ARMAnd : SDTypeProfile<1, 2, 500b57cec5SDimitry Andric [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 510b57cec5SDimitry Andric SDTCisVT<2, i32>]>; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andricdef SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andricdef SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, 560b57cec5SDimitry Andric SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andricdef SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; 590b57cec5SDimitry Andricdef SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>, 600b57cec5SDimitry Andric SDTCisInt<2>]>; 610b57cec5SDimitry Andricdef SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>; 620b57cec5SDimitry Andricdef SDT_ARMEH_SJLJ_SetupDispatch: SDTypeProfile<0, 0, []>; 630b57cec5SDimitry Andric 640b57cec5SDimitry Andricdef SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andricdef SDT_ARMPREFETCH : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, 670b57cec5SDimitry Andric SDTCisInt<1>]>; 680b57cec5SDimitry Andric 69fe6060f1SDimitry Andricdef SDT_ARMTCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>]>; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andricdef SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 720b57cec5SDimitry Andric SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andricdef SDT_WIN__DBZCHK : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andricdef SDT_ARMMEMCPY : SDTypeProfile<2, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 770b57cec5SDimitry Andric SDTCisVT<2, i32>, SDTCisVT<3, i32>, 780b57cec5SDimitry Andric SDTCisVT<4, i32>]>; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andricdef SDTBinaryArithWithFlags : SDTypeProfile<2, 2, 810b57cec5SDimitry Andric [SDTCisSameAs<0, 2>, 820b57cec5SDimitry Andric SDTCisSameAs<0, 3>, 830b57cec5SDimitry Andric SDTCisInt<0>, SDTCisVT<1, i32>]>; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric// SDTBinaryArithWithFlagsInOut - RES1, CPSR = op LHS, RHS, CPSR 860b57cec5SDimitry Andricdef SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3, 870b57cec5SDimitry Andric [SDTCisSameAs<0, 2>, 880b57cec5SDimitry Andric SDTCisSameAs<0, 3>, 890b57cec5SDimitry Andric SDTCisInt<0>, 900b57cec5SDimitry Andric SDTCisVT<1, i32>, 910b57cec5SDimitry Andric SDTCisVT<4, i32>]>; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andricdef SDT_LongMac : SDTypeProfile<2, 4, [SDTCisVT<0, i32>, 940b57cec5SDimitry Andric SDTCisSameAs<0, 1>, 950b57cec5SDimitry Andric SDTCisSameAs<0, 2>, 960b57cec5SDimitry Andric SDTCisSameAs<0, 3>, 970b57cec5SDimitry Andric SDTCisSameAs<0, 4>, 980b57cec5SDimitry Andric SDTCisSameAs<0, 5>]>; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric// ARMlsll, ARMlsrl, ARMasrl 1010b57cec5SDimitry Andricdef SDT_ARMIntShiftParts : SDTypeProfile<2, 3, [SDTCisSameAs<0, 1>, 1020b57cec5SDimitry Andric SDTCisSameAs<0, 2>, 1030b57cec5SDimitry Andric SDTCisSameAs<0, 3>, 1040b57cec5SDimitry Andric SDTCisInt<0>, 1050b57cec5SDimitry Andric SDTCisInt<4>]>; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andricdef ARMSmlald : SDNode<"ARMISD::SMLALD", SDT_LongMac>; 1080b57cec5SDimitry Andricdef ARMSmlaldx : SDNode<"ARMISD::SMLALDX", SDT_LongMac>; 1090b57cec5SDimitry Andricdef ARMSmlsld : SDNode<"ARMISD::SMLSLD", SDT_LongMac>; 1100b57cec5SDimitry Andricdef ARMSmlsldx : SDNode<"ARMISD::SMLSLDX", SDT_LongMac>; 1110b57cec5SDimitry Andric 1128bcb0991SDimitry Andricdef SDT_ARMCSel : SDTypeProfile<1, 3, 1138bcb0991SDimitry Andric [SDTCisSameAs<0, 1>, 1148bcb0991SDimitry Andric SDTCisSameAs<0, 2>, 1158bcb0991SDimitry Andric SDTCisInt<3>, 1168bcb0991SDimitry Andric SDTCisVT<3, i32>]>; 1178bcb0991SDimitry Andric 1188bcb0991SDimitry Andricdef ARMcsinv : SDNode<"ARMISD::CSINV", SDT_ARMCSel, [SDNPOptInGlue]>; 1198bcb0991SDimitry Andricdef ARMcsneg : SDNode<"ARMISD::CSNEG", SDT_ARMCSel, [SDNPOptInGlue]>; 1208bcb0991SDimitry Andricdef ARMcsinc : SDNode<"ARMISD::CSINC", SDT_ARMCSel, [SDNPOptInGlue]>; 1218bcb0991SDimitry Andric 1220b57cec5SDimitry Andricdef SDT_MulHSR : SDTypeProfile<1, 3, [SDTCisVT<0,i32>, 1230b57cec5SDimitry Andric SDTCisSameAs<0, 1>, 1240b57cec5SDimitry Andric SDTCisSameAs<0, 2>, 1250b57cec5SDimitry Andric SDTCisSameAs<0, 3>]>; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andricdef ARMsmmlar : SDNode<"ARMISD::SMMLAR", SDT_MulHSR>; 1280b57cec5SDimitry Andricdef ARMsmmlsr : SDNode<"ARMISD::SMMLSR", SDT_MulHSR>; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric// Node definitions. 1310b57cec5SDimitry Andricdef ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; 1320b57cec5SDimitry Andricdef ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>; 1330b57cec5SDimitry Andricdef ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntUnaryOp>; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andricdef ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, 1360b57cec5SDimitry Andric [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; 1370b57cec5SDimitry Andricdef ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd, 1380b57cec5SDimitry Andric [SDNPHasChain, SDNPSideEffect, 1390b57cec5SDimitry Andric SDNPOptInGlue, SDNPOutGlue]>; 1400b57cec5SDimitry Andricdef ARMcopystructbyval : SDNode<"ARMISD::COPY_STRUCT_BYVAL" , 1410b57cec5SDimitry Andric SDT_ARMStructByVal, 1420b57cec5SDimitry Andric [SDNPHasChain, SDNPInGlue, SDNPOutGlue, 1430b57cec5SDimitry Andric SDNPMayStore, SDNPMayLoad]>; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andricdef ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall, 1460b57cec5SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 1470b57cec5SDimitry Andric SDNPVariadic]>; 1480b57cec5SDimitry Andricdef ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall, 1490b57cec5SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 1500b57cec5SDimitry Andric SDNPVariadic]>; 1510b57cec5SDimitry Andricdef ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall, 1520b57cec5SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 1530b57cec5SDimitry Andric SDNPVariadic]>; 1540b57cec5SDimitry Andric 15506c3fb27SDimitry Andricdef ARMretglue : SDNode<"ARMISD::RET_GLUE", SDTNone, 1560b57cec5SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 15706c3fb27SDimitry Andricdef ARMseretglue : SDNode<"ARMISD::SERET_GLUE", SDTNone, 1585ffd83dbSDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 15906c3fb27SDimitry Andricdef ARMintretglue : SDNode<"ARMISD::INTRET_GLUE", SDT_ARMcall, 1600b57cec5SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 1610b57cec5SDimitry Andricdef ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, 1620b57cec5SDimitry Andric [SDNPInGlue]>; 1630b57cec5SDimitry Andric 164e8d8bef9SDimitry Andricdef ARMssat : SDNode<"ARMISD::SSAT", SDTIntSatNoShOp, []>; 1650b57cec5SDimitry Andric 166e8d8bef9SDimitry Andricdef ARMusat : SDNode<"ARMISD::USAT", SDTIntSatNoShOp, []>; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andricdef ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, 1690b57cec5SDimitry Andric [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andricdef ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, 1720b57cec5SDimitry Andric [SDNPHasChain]>; 1730b57cec5SDimitry Andricdef ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT, 1740b57cec5SDimitry Andric [SDNPHasChain]>; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andricdef ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64, 1770b57cec5SDimitry Andric [SDNPHasChain]>; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andricdef ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, 1800b57cec5SDimitry Andric [SDNPOutGlue]>; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andricdef ARMcmn : SDNode<"ARMISD::CMN", SDT_ARMCmp, 1830b57cec5SDimitry Andric [SDNPOutGlue]>; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andricdef ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, 1860b57cec5SDimitry Andric [SDNPOutGlue, SDNPCommutative]>; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andricdef ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andricdef ARMasrl : SDNode<"ARMISD::ASRL", SDT_ARMIntShiftParts, []>; 1910b57cec5SDimitry Andricdef ARMlsrl : SDNode<"ARMISD::LSRL", SDT_ARMIntShiftParts, []>; 1920b57cec5SDimitry Andricdef ARMlsll : SDNode<"ARMISD::LSLL", SDT_ARMIntShiftParts, []>; 1930b57cec5SDimitry Andric 19406c3fb27SDimitry Andricdef ARMsrl_glue : SDNode<"ARMISD::SRL_GLUE", SDTIntUnaryOp, [SDNPOutGlue]>; 19506c3fb27SDimitry Andricdef ARMsra_glue : SDNode<"ARMISD::SRA_GLUE", SDTIntUnaryOp, [SDNPOutGlue]>; 1960b57cec5SDimitry Andricdef ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andricdef ARMaddc : SDNode<"ARMISD::ADDC", SDTBinaryArithWithFlags, 1990b57cec5SDimitry Andric [SDNPCommutative]>; 2000b57cec5SDimitry Andricdef ARMsubc : SDNode<"ARMISD::SUBC", SDTBinaryArithWithFlags>; 2018bcb0991SDimitry Andricdef ARMlsls : SDNode<"ARMISD::LSLS", SDTBinaryArithWithFlags>; 2020b57cec5SDimitry Andricdef ARMadde : SDNode<"ARMISD::ADDE", SDTBinaryArithWithFlagsInOut>; 2030b57cec5SDimitry Andricdef ARMsube : SDNode<"ARMISD::SUBE", SDTBinaryArithWithFlagsInOut>; 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andricdef ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; 2060b57cec5SDimitry Andricdef ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", 2070b57cec5SDimitry Andric SDT_ARMEH_SJLJ_Setjmp, 2080b57cec5SDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 2090b57cec5SDimitry Andricdef ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP", 2100b57cec5SDimitry Andric SDT_ARMEH_SJLJ_Longjmp, 2110b57cec5SDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 2120b57cec5SDimitry Andricdef ARMeh_sjlj_setup_dispatch: SDNode<"ARMISD::EH_SJLJ_SETUP_DISPATCH", 2130b57cec5SDimitry Andric SDT_ARMEH_SJLJ_SetupDispatch, 2140b57cec5SDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andricdef ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER, 2170b57cec5SDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 2180b57cec5SDimitry Andricdef ARMPreload : SDNode<"ARMISD::PRELOAD", SDT_ARMPREFETCH, 2190b57cec5SDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andricdef ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET, 2220b57cec5SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andricdef ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andricdef ARMmemcopy : SDNode<"ARMISD::MEMCPY", SDT_ARMMEMCPY, 2270b57cec5SDimitry Andric [SDNPHasChain, SDNPInGlue, SDNPOutGlue, 2280b57cec5SDimitry Andric SDNPMayStore, SDNPMayLoad]>; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andricdef ARMsmulwb : SDNode<"ARMISD::SMULWB", SDTIntBinOp, []>; 2310b57cec5SDimitry Andricdef ARMsmulwt : SDNode<"ARMISD::SMULWT", SDTIntBinOp, []>; 2320b57cec5SDimitry Andricdef ARMsmlalbb : SDNode<"ARMISD::SMLALBB", SDT_LongMac, []>; 2330b57cec5SDimitry Andricdef ARMsmlalbt : SDNode<"ARMISD::SMLALBT", SDT_LongMac, []>; 2340b57cec5SDimitry Andricdef ARMsmlaltb : SDNode<"ARMISD::SMLALTB", SDT_LongMac, []>; 2350b57cec5SDimitry Andricdef ARMsmlaltt : SDNode<"ARMISD::SMLALTT", SDT_LongMac, []>; 2360b57cec5SDimitry Andric 2378bcb0991SDimitry Andricdef ARMqadd8b : SDNode<"ARMISD::QADD8b", SDT_ARMAnd, []>; 2388bcb0991SDimitry Andricdef ARMqsub8b : SDNode<"ARMISD::QSUB8b", SDT_ARMAnd, []>; 2398bcb0991SDimitry Andricdef ARMqadd16b : SDNode<"ARMISD::QADD16b", SDT_ARMAnd, []>; 2408bcb0991SDimitry Andricdef ARMqsub16b : SDNode<"ARMISD::QSUB16b", SDT_ARMAnd, []>; 2418bcb0991SDimitry Andric 242fe6060f1SDimitry Andricdef ARMuqadd8b : SDNode<"ARMISD::UQADD8b", SDT_ARMAnd, []>; 243fe6060f1SDimitry Andricdef ARMuqsub8b : SDNode<"ARMISD::UQSUB8b", SDT_ARMAnd, []>; 244fe6060f1SDimitry Andricdef ARMuqadd16b : SDNode<"ARMISD::UQADD16b", SDT_ARMAnd, []>; 245fe6060f1SDimitry Andricdef ARMuqsub16b : SDNode<"ARMISD::UQSUB16b", SDT_ARMAnd, []>; 246fe6060f1SDimitry Andric 2475ffd83dbSDimitry Andricdef SDT_ARMldrd : SDTypeProfile<2, 1, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>; 2485ffd83dbSDimitry Andricdef ARMldrd : SDNode<"ARMISD::LDRD", SDT_ARMldrd, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 2495ffd83dbSDimitry Andric 2505ffd83dbSDimitry Andricdef SDT_ARMstrd : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>; 2515ffd83dbSDimitry Andricdef ARMstrd : SDNode<"ARMISD::STRD", SDT_ARMstrd, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 2525ffd83dbSDimitry Andric 2530b57cec5SDimitry Andric// Vector operations shared between NEON and MVE 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andricdef ARMvdup : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>; 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric// VDUPLANE can produce a quad-register result from a double-register source, 2580b57cec5SDimitry Andric// so the result is not constrained to match the source. 2590b57cec5SDimitry Andricdef ARMvduplane : SDNode<"ARMISD::VDUPLANE", 2600b57cec5SDimitry Andric SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, 2610b57cec5SDimitry Andric SDTCisVT<2, i32>]>>; 2620b57cec5SDimitry Andric 263fe6060f1SDimitry Andricdef SDTARMVIDUP : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisVT<1, i32>, 264fe6060f1SDimitry Andric SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 265fe6060f1SDimitry Andricdef ARMvidup : SDNode<"ARMISD::VIDUP", SDTARMVIDUP>; 266fe6060f1SDimitry Andric 2670b57cec5SDimitry Andricdef SDTARMVSHUF : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>; 2680b57cec5SDimitry Andricdef ARMvrev64 : SDNode<"ARMISD::VREV64", SDTARMVSHUF>; 2690b57cec5SDimitry Andricdef ARMvrev32 : SDNode<"ARMISD::VREV32", SDTARMVSHUF>; 2700b57cec5SDimitry Andricdef ARMvrev16 : SDNode<"ARMISD::VREV16", SDTARMVSHUF>; 2710b57cec5SDimitry Andric 2725ffd83dbSDimitry Andricdef SDTARMVGETLN : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVec<1>, 2730b57cec5SDimitry Andric SDTCisVT<2, i32>]>; 2740b57cec5SDimitry Andricdef ARMvgetlaneu : SDNode<"ARMISD::VGETLANEu", SDTARMVGETLN>; 2750b57cec5SDimitry Andricdef ARMvgetlanes : SDNode<"ARMISD::VGETLANEs", SDTARMVGETLN>; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andricdef SDTARMVMOVIMM : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>; 2780b57cec5SDimitry Andricdef ARMvmovImm : SDNode<"ARMISD::VMOVIMM", SDTARMVMOVIMM>; 2790b57cec5SDimitry Andricdef ARMvmvnImm : SDNode<"ARMISD::VMVNIMM", SDTARMVMOVIMM>; 2800b57cec5SDimitry Andricdef ARMvmovFPImm : SDNode<"ARMISD::VMOVFPIMM", SDTARMVMOVIMM>; 2810b57cec5SDimitry Andric 2825ffd83dbSDimitry Andricdef SDTARMVORRIMM : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, 2835ffd83dbSDimitry Andric SDTCisVT<2, i32>]>; 2845ffd83dbSDimitry Andricdef ARMvorrImm : SDNode<"ARMISD::VORRIMM", SDTARMVORRIMM>; 2855ffd83dbSDimitry Andricdef ARMvbicImm : SDNode<"ARMISD::VBICIMM", SDTARMVORRIMM>; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andricdef SDTARMVSHIMM : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 2880b57cec5SDimitry Andric SDTCisVT<2, i32>]>; 2890b57cec5SDimitry Andricdef SDTARMVSH : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 2900b57cec5SDimitry Andric SDTCisSameAs<0, 2>,]>; 2910b57cec5SDimitry Andricdef ARMvshlImm : SDNode<"ARMISD::VSHLIMM", SDTARMVSHIMM>; 2920b57cec5SDimitry Andricdef ARMvshrsImm : SDNode<"ARMISD::VSHRsIMM", SDTARMVSHIMM>; 2930b57cec5SDimitry Andricdef ARMvshruImm : SDNode<"ARMISD::VSHRuIMM", SDTARMVSHIMM>; 2940b57cec5SDimitry Andricdef ARMvshls : SDNode<"ARMISD::VSHLs", SDTARMVSH>; 2950b57cec5SDimitry Andricdef ARMvshlu : SDNode<"ARMISD::VSHLu", SDTARMVSH>; 2960b57cec5SDimitry Andric 2975ffd83dbSDimitry Andricdef SDTARMVMULL : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, 2985ffd83dbSDimitry Andric SDTCisSameAs<1, 2>]>; 2995ffd83dbSDimitry Andricdef ARMvmulls : SDNode<"ARMISD::VMULLs", SDTARMVMULL>; 3005ffd83dbSDimitry Andricdef ARMvmullu : SDNode<"ARMISD::VMULLu", SDTARMVMULL>; 3015ffd83dbSDimitry Andric 3028bcb0991SDimitry Andricdef SDTARMVCMP : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<1, 2>, 3038bcb0991SDimitry Andric SDTCisInt<3>]>; 3048bcb0991SDimitry Andricdef SDTARMVCMPZ : SDTypeProfile<1, 2, [SDTCisInt<2>]>; 3058bcb0991SDimitry Andric 3068bcb0991SDimitry Andricdef ARMvcmp : SDNode<"ARMISD::VCMP", SDTARMVCMP>; 3078bcb0991SDimitry Andricdef ARMvcmpz : SDNode<"ARMISD::VCMPZ", SDTARMVCMPZ>; 3088bcb0991SDimitry Andric 3095ffd83dbSDimitry Andric// 'VECTOR_REG_CAST' is an operation that reinterprets the contents of a 3105ffd83dbSDimitry Andric// vector register as a different vector type, without changing the contents of 3115ffd83dbSDimitry Andric// the register. It differs from 'bitconvert' in that bitconvert reinterprets 3125ffd83dbSDimitry Andric// the _memory_ storage format of the vector, whereas VECTOR_REG_CAST 3135ffd83dbSDimitry Andric// reinterprets the _register_ format - and in big-endian, the memory and 3145ffd83dbSDimitry Andric// register formats are different, so they are different operations. 3155ffd83dbSDimitry Andric// 3165ffd83dbSDimitry Andric// For example, 'VECTOR_REG_CAST' between v8i16 and v16i8 will map the LSB of 3175ffd83dbSDimitry Andric// the zeroth i16 lane to the zeroth i8 lane, regardless of system endianness, 3185ffd83dbSDimitry Andric// whereas 'bitconvert' will map it to the high byte in big-endian mode, 3195ffd83dbSDimitry Andric// because that's what (MVE) VSTRH.16 followed by VLDRB.8 would do. So the 3205ffd83dbSDimitry Andric// bitconvert would have to emit a VREV16.8 instruction, whereas the 3215ffd83dbSDimitry Andric// VECTOR_REG_CAST emits no code at all if the vector is already in a register. 3225ffd83dbSDimitry Andricdef ARMVectorRegCastImpl : SDNode<"ARMISD::VECTOR_REG_CAST", SDTUnaryOp>; 3235ffd83dbSDimitry Andric 3245ffd83dbSDimitry Andric// In little-endian, VECTOR_REG_CAST is often turned into bitconvert during 3255ffd83dbSDimitry Andric// lowering (because in that situation they're identical). So an isel pattern 3265ffd83dbSDimitry Andric// that needs to match something that's _logically_ a VECTOR_REG_CAST must 3275ffd83dbSDimitry Andric// _physically_ match a different node type depending on endianness. 3285ffd83dbSDimitry Andric// 3295ffd83dbSDimitry Andric// This 'PatFrags' instance is a centralized facility to make that easy. It 3305ffd83dbSDimitry Andric// matches VECTOR_REG_CAST in either endianness, and also bitconvert in the 3315ffd83dbSDimitry Andric// endianness where it's equivalent. 3325ffd83dbSDimitry Andricdef ARMVectorRegCast: PatFrags< 3335ffd83dbSDimitry Andric (ops node:$x), [(ARMVectorRegCastImpl node:$x), (bitconvert node:$x)], [{ 3345ffd83dbSDimitry Andric // Reject a match against bitconvert (aka ISD::BITCAST) if big-endian 3355ffd83dbSDimitry Andric return !(CurDAG->getDataLayout().isBigEndian() && 3365ffd83dbSDimitry Andric N->getOpcode() == ISD::BITCAST); 3375ffd83dbSDimitry Andric }]>; 3385ffd83dbSDimitry Andric 3390b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 3400b57cec5SDimitry Andric// ARM Flag Definitions. 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andricclass RegConstraint<string C> { 3430b57cec5SDimitry Andric string Constraints = C; 3440b57cec5SDimitry Andric} 3450b57cec5SDimitry Andric 346480093f4SDimitry Andric// ARMCC condition codes. See ARMCC::CondCodes 347480093f4SDimitry Andricdef ARMCCeq : PatLeaf<(i32 0)>; 348480093f4SDimitry Andricdef ARMCCne : PatLeaf<(i32 1)>; 349480093f4SDimitry Andricdef ARMCChs : PatLeaf<(i32 2)>; 350480093f4SDimitry Andricdef ARMCClo : PatLeaf<(i32 3)>; 351480093f4SDimitry Andricdef ARMCCmi : PatLeaf<(i32 4)>; 352480093f4SDimitry Andricdef ARMCCpl : PatLeaf<(i32 5)>; 353480093f4SDimitry Andricdef ARMCCvs : PatLeaf<(i32 6)>; 354480093f4SDimitry Andricdef ARMCCvc : PatLeaf<(i32 7)>; 355480093f4SDimitry Andricdef ARMCChi : PatLeaf<(i32 8)>; 356480093f4SDimitry Andricdef ARMCCls : PatLeaf<(i32 9)>; 357480093f4SDimitry Andricdef ARMCCge : PatLeaf<(i32 10)>; 358480093f4SDimitry Andricdef ARMCClt : PatLeaf<(i32 11)>; 359480093f4SDimitry Andricdef ARMCCgt : PatLeaf<(i32 12)>; 360480093f4SDimitry Andricdef ARMCCle : PatLeaf<(i32 13)>; 361480093f4SDimitry Andricdef ARMCCal : PatLeaf<(i32 14)>; 362480093f4SDimitry Andric 363480093f4SDimitry Andric// VCC predicates. See ARMVCC::VPTCodes 364480093f4SDimitry Andricdef ARMVCCNone : PatLeaf<(i32 0)>; 365480093f4SDimitry Andricdef ARMVCCThen : PatLeaf<(i32 1)>; 366480093f4SDimitry Andricdef ARMVCCElse : PatLeaf<(i32 2)>; 367480093f4SDimitry Andric 3680b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 3690b57cec5SDimitry Andric// ARM specific transformation functions and pattern fragments. 3700b57cec5SDimitry Andric// 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric// imm_neg_XFORM - Return the negation of an i32 immediate value. 3730b57cec5SDimitry Andricdef imm_neg_XFORM : SDNodeXForm<imm, [{ 3740b57cec5SDimitry Andric return CurDAG->getTargetConstant(-(int)N->getZExtValue(), SDLoc(N), MVT::i32); 3750b57cec5SDimitry Andric}]>; 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric// imm_not_XFORM - Return the complement of a i32 immediate value. 3780b57cec5SDimitry Andricdef imm_not_XFORM : SDNodeXForm<imm, [{ 3790b57cec5SDimitry Andric return CurDAG->getTargetConstant(~(int)N->getZExtValue(), SDLoc(N), MVT::i32); 3800b57cec5SDimitry Andric}]>; 381*0fca6ea1SDimitry Andricdef gi_imm_not_XFORM : GICustomOperandRenderer<"renderInvertedImm">, 382*0fca6ea1SDimitry Andric GISDNodeXFormEquiv<imm_not_XFORM>; 3830b57cec5SDimitry Andric 384e8d8bef9SDimitry Andric// asr_imm_XFORM - Returns a shift immediate with bit {5} set to 1 385e8d8bef9SDimitry Andricdef asr_imm_XFORM : SDNodeXForm<imm, [{ 386e8d8bef9SDimitry Andric return CurDAG->getTargetConstant(0x20 | N->getZExtValue(), SDLoc(N), MVT:: i32); 387e8d8bef9SDimitry Andric}]>; 388e8d8bef9SDimitry Andric 3890b57cec5SDimitry Andric/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31]. 3900b57cec5SDimitry Andricdef imm16_31 : ImmLeaf<i32, [{ 3910b57cec5SDimitry Andric return (int32_t)Imm >= 16 && (int32_t)Imm < 32; 3920b57cec5SDimitry Andric}]>; 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits. 3950b57cec5SDimitry Andricdef sext_16_node : PatLeaf<(i32 GPR:$a), [{ 3960b57cec5SDimitry Andric return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17; 3970b57cec5SDimitry Andric}]>; 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andricdef sext_bottom_16 : PatFrag<(ops node:$a), 4000b57cec5SDimitry Andric (sext_inreg node:$a, i16)>; 4010b57cec5SDimitry Andricdef sext_top_16 : PatFrag<(ops node:$a), 4020b57cec5SDimitry Andric (i32 (sra node:$a, (i32 16)))>; 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andricdef bb_mul : PatFrag<(ops node:$a, node:$b), 4050b57cec5SDimitry Andric (mul (sext_bottom_16 node:$a), (sext_bottom_16 node:$b))>; 4060b57cec5SDimitry Andricdef bt_mul : PatFrag<(ops node:$a, node:$b), 4070b57cec5SDimitry Andric (mul (sext_bottom_16 node:$a), (sra node:$b, (i32 16)))>; 4080b57cec5SDimitry Andricdef tb_mul : PatFrag<(ops node:$a, node:$b), 4090b57cec5SDimitry Andric (mul (sra node:$a, (i32 16)), (sext_bottom_16 node:$b))>; 4100b57cec5SDimitry Andricdef tt_mul : PatFrag<(ops node:$a, node:$b), 4110b57cec5SDimitry Andric (mul (sra node:$a, (i32 16)), (sra node:$b, (i32 16)))>; 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric/// Split a 32-bit immediate into two 16 bit parts. 4140b57cec5SDimitry Andricdef hi16 : SDNodeXForm<imm, [{ 4150b57cec5SDimitry Andric return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, SDLoc(N), 4160b57cec5SDimitry Andric MVT::i32); 4170b57cec5SDimitry Andric}]>; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andricdef lo16AllZero : PatLeaf<(i32 imm), [{ 4200b57cec5SDimitry Andric // Returns true if all low 16-bits are 0. 4210b57cec5SDimitry Andric return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0; 4220b57cec5SDimitry Andric}], hi16>; 4230b57cec5SDimitry Andric 4244824e7fdSDimitry Andric// top16Zero - answer true if the upper 16 bits of $src are 0, false otherwise 4254824e7fdSDimitry Andricdef top16Zero: PatLeaf<(i32 GPR:$src), [{ 4264824e7fdSDimitry Andric return !SDValue(N,0)->getValueType(0).isVector() && 4274824e7fdSDimitry Andric CurDAG->MaskedValueIsZero(SDValue(N,0), APInt::getHighBitsSet(32, 16)); 4284824e7fdSDimitry Andric }]>; 4294824e7fdSDimitry Andric 430bdd1243dSDimitry Andric// topbitsallzero - Return true if all bits except the lowest bit are known zero 431bdd1243dSDimitry Andricdef topbitsallzero32 : PatLeaf<(i32 GPRwithZR:$src), [{ 432bdd1243dSDimitry Andric return SDValue(N,0)->getValueType(0) == MVT::i32 && 433bdd1243dSDimitry Andric CurDAG->MaskedValueIsZero(SDValue(N,0), APInt::getHighBitsSet(32, 31)); 434bdd1243dSDimitry Andric }]>; 435bdd1243dSDimitry Andric 4360b57cec5SDimitry Andricclass BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 4370b57cec5SDimitry Andricclass UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>; 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric// An 'and' node with a single use. 4400b57cec5SDimitry Andricdef and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ 4410b57cec5SDimitry Andric return N->hasOneUse(); 4420b57cec5SDimitry Andric}]>; 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric// An 'xor' node with a single use. 4450b57cec5SDimitry Andricdef xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{ 4460b57cec5SDimitry Andric return N->hasOneUse(); 4470b57cec5SDimitry Andric}]>; 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric// An 'fmul' node with a single use. 4500b57cec5SDimitry Andricdef fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{ 4510b57cec5SDimitry Andric return N->hasOneUse(); 4520b57cec5SDimitry Andric}]>; 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric// An 'fadd' node which checks for single non-hazardous use. 4550b57cec5SDimitry Andricdef fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{ 4560b57cec5SDimitry Andric return hasNoVMLxHazardUse(N); 4570b57cec5SDimitry Andric}]>; 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric// An 'fsub' node which checks for single non-hazardous use. 4600b57cec5SDimitry Andricdef fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{ 4610b57cec5SDimitry Andric return hasNoVMLxHazardUse(N); 4620b57cec5SDimitry Andric}]>; 4630b57cec5SDimitry Andric 46406c3fb27SDimitry Andric// An 'fadd' node which can be contracted into a fma 46506c3fb27SDimitry Andricdef fadd_contract : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{ 46606c3fb27SDimitry Andric return N->getFlags().hasAllowContract(); 46706c3fb27SDimitry Andric}]>; 46806c3fb27SDimitry Andric 4695ffd83dbSDimitry Andricdef imm_even : ImmLeaf<i32, [{ return (Imm & 1) == 0; }]>; 4705ffd83dbSDimitry Andricdef imm_odd : ImmLeaf<i32, [{ return (Imm & 1) == 1; }]>; 4715ffd83dbSDimitry Andric 472e8d8bef9SDimitry Andricdef asr_imm : ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }], asr_imm_XFORM>; 473e8d8bef9SDimitry Andric 4745ffd83dbSDimitry Andric//===----------------------------------------------------------------------===// 4755ffd83dbSDimitry Andric// NEON/MVE pattern fragments 4765ffd83dbSDimitry Andric// 4775ffd83dbSDimitry Andric 4785ffd83dbSDimitry Andric// Extract D sub-registers of Q registers. 4795ffd83dbSDimitry Andricdef DSubReg_i8_reg : SDNodeXForm<imm, [{ 4805ffd83dbSDimitry Andric assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 4815ffd83dbSDimitry Andric return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/8, SDLoc(N), 4825ffd83dbSDimitry Andric MVT::i32); 4835ffd83dbSDimitry Andric}]>; 4845ffd83dbSDimitry Andricdef DSubReg_i16_reg : SDNodeXForm<imm, [{ 4855ffd83dbSDimitry Andric assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 4865ffd83dbSDimitry Andric return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/4, SDLoc(N), 4875ffd83dbSDimitry Andric MVT::i32); 4885ffd83dbSDimitry Andric}]>; 4895ffd83dbSDimitry Andricdef DSubReg_i32_reg : SDNodeXForm<imm, [{ 4905ffd83dbSDimitry Andric assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 4915ffd83dbSDimitry Andric return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/2, SDLoc(N), 4925ffd83dbSDimitry Andric MVT::i32); 4935ffd83dbSDimitry Andric}]>; 4945ffd83dbSDimitry Andricdef DSubReg_f64_reg : SDNodeXForm<imm, [{ 4955ffd83dbSDimitry Andric assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 4965ffd83dbSDimitry Andric return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue(), SDLoc(N), 4975ffd83dbSDimitry Andric MVT::i32); 4985ffd83dbSDimitry Andric}]>; 4995ffd83dbSDimitry Andric 5005ffd83dbSDimitry Andric// Extract S sub-registers of Q/D registers. 5015ffd83dbSDimitry Andricdef SSubReg_f32_reg : SDNodeXForm<imm, [{ 5025ffd83dbSDimitry Andric assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering"); 5035ffd83dbSDimitry Andric return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue(), SDLoc(N), 5045ffd83dbSDimitry Andric MVT::i32); 5055ffd83dbSDimitry Andric}]>; 5065ffd83dbSDimitry Andric 5075ffd83dbSDimitry Andric// Extract S sub-registers of Q/D registers containing a given f16/bf16 lane. 5085ffd83dbSDimitry Andricdef SSubReg_f16_reg : SDNodeXForm<imm, [{ 5095ffd83dbSDimitry Andric assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering"); 5105ffd83dbSDimitry Andric return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue()/2, SDLoc(N), 5115ffd83dbSDimitry Andric MVT::i32); 5125ffd83dbSDimitry Andric}]>; 5135ffd83dbSDimitry Andric 5145ffd83dbSDimitry Andric// Translate lane numbers from Q registers to D subregs. 5155ffd83dbSDimitry Andricdef SubReg_i8_lane : SDNodeXForm<imm, [{ 5165ffd83dbSDimitry Andric return CurDAG->getTargetConstant(N->getZExtValue() & 7, SDLoc(N), MVT::i32); 5175ffd83dbSDimitry Andric}]>; 5185ffd83dbSDimitry Andricdef SubReg_i16_lane : SDNodeXForm<imm, [{ 5195ffd83dbSDimitry Andric return CurDAG->getTargetConstant(N->getZExtValue() & 3, SDLoc(N), MVT::i32); 5205ffd83dbSDimitry Andric}]>; 5215ffd83dbSDimitry Andricdef SubReg_i32_lane : SDNodeXForm<imm, [{ 5225ffd83dbSDimitry Andric return CurDAG->getTargetConstant(N->getZExtValue() & 1, SDLoc(N), MVT::i32); 5235ffd83dbSDimitry Andric}]>; 5245ffd83dbSDimitry Andric 5255ffd83dbSDimitry Andric 526e8d8bef9SDimitry Andricdef ARMimmAllZerosV: PatLeaf<(bitconvert (v4i32 (ARMvmovImm (i32 0))))>; 527e8d8bef9SDimitry Andricdef ARMimmAllZerosD: PatLeaf<(bitconvert (v2i32 (ARMvmovImm (i32 0))))>; 528e8d8bef9SDimitry Andricdef ARMimmAllOnesV: PatLeaf<(bitconvert (v16i8 (ARMvmovImm (i32 0xEFF))))>; 529e8d8bef9SDimitry Andricdef ARMimmAllOnesD: PatLeaf<(bitconvert (v8i8 (ARMvmovImm (i32 0xEFF))))>; 530e8d8bef9SDimitry Andric 531e8d8bef9SDimitry Andricdef ARMimmOneV: PatLeaf<(ARMvmovImm (i32 timm)), [{ 532e8d8bef9SDimitry Andric ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0)); 533e8d8bef9SDimitry Andric unsigned EltBits = 0; 534e8d8bef9SDimitry Andric uint64_t EltVal = ARM_AM::decodeVMOVModImm(ConstVal->getZExtValue(), EltBits); 535e8d8bef9SDimitry Andric return (EltBits == N->getValueType(0).getScalarSizeInBits() && EltVal == 0x01); 536e8d8bef9SDimitry Andric}]>; 537e8d8bef9SDimitry Andric 5385ffd83dbSDimitry Andric 5390b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 5400b57cec5SDimitry Andric// Operand Definitions. 5410b57cec5SDimitry Andric// 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric// Immediate operands with a shared generic asm render method. 5440b57cec5SDimitry Andricclass ImmAsmOperand<int Low, int High> : AsmOperandClass { 5450b57cec5SDimitry Andric let RenderMethod = "addImmOperands"; 5460b57cec5SDimitry Andric let PredicateMethod = "isImmediate<" # Low # "," # High # ">"; 5470b57cec5SDimitry Andric let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]"; 5480b57cec5SDimitry Andric} 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andricclass ImmAsmOperandMinusOne<int Low, int High> : AsmOperandClass { 5510b57cec5SDimitry Andric let PredicateMethod = "isImmediate<" # Low # "," # High # ">"; 5520b57cec5SDimitry Andric let DiagnosticType = "ImmRange" # Low # "_" # High; 5530b57cec5SDimitry Andric let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]"; 5540b57cec5SDimitry Andric} 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric// Operands that are part of a memory addressing mode. 5570b57cec5SDimitry Andricclass MemOperand : Operand<i32> { let OperandType = "OPERAND_MEMORY"; } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric// Branch target. 5600b57cec5SDimitry Andric// FIXME: rename brtarget to t2_brtarget 5610b57cec5SDimitry Andricdef brtarget : Operand<OtherVT> { 5620b57cec5SDimitry Andric let EncoderMethod = "getBranchTargetOpValue"; 5630b57cec5SDimitry Andric let OperandType = "OPERAND_PCREL"; 5640b57cec5SDimitry Andric let DecoderMethod = "DecodeT2BROperand"; 5650b57cec5SDimitry Andric} 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric// Branches targeting ARM-mode must be divisible by 4 if they're a raw 5680b57cec5SDimitry Andric// immediate. 5690b57cec5SDimitry Andricdef ARMBranchTarget : AsmOperandClass { 5700b57cec5SDimitry Andric let Name = "ARMBranchTarget"; 5710b57cec5SDimitry Andric} 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric// Branches targeting Thumb-mode must be divisible by 2 if they're a raw 5740b57cec5SDimitry Andric// immediate. 5750b57cec5SDimitry Andricdef ThumbBranchTarget : AsmOperandClass { 5760b57cec5SDimitry Andric let Name = "ThumbBranchTarget"; 5770b57cec5SDimitry Andric} 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andricdef arm_br_target : Operand<OtherVT> { 5800b57cec5SDimitry Andric let ParserMatchClass = ARMBranchTarget; 5810b57cec5SDimitry Andric let EncoderMethod = "getARMBranchTargetOpValue"; 5820b57cec5SDimitry Andric let OperandType = "OPERAND_PCREL"; 5830b57cec5SDimitry Andric} 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric// Call target for ARM. Handles conditional/unconditional 5860b57cec5SDimitry Andric// FIXME: rename bl_target to t2_bltarget? 5870b57cec5SDimitry Andricdef arm_bl_target : Operand<i32> { 5880b57cec5SDimitry Andric let ParserMatchClass = ARMBranchTarget; 5890b57cec5SDimitry Andric let EncoderMethod = "getARMBLTargetOpValue"; 5900b57cec5SDimitry Andric let OperandType = "OPERAND_PCREL"; 5910b57cec5SDimitry Andric} 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric// Target for BLX *from* ARM mode. 5940b57cec5SDimitry Andricdef arm_blx_target : Operand<i32> { 5950b57cec5SDimitry Andric let ParserMatchClass = ThumbBranchTarget; 5960b57cec5SDimitry Andric let EncoderMethod = "getARMBLXTargetOpValue"; 5970b57cec5SDimitry Andric let OperandType = "OPERAND_PCREL"; 5980b57cec5SDimitry Andric} 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric// A list of registers separated by comma. Used by load/store multiple. 6010b57cec5SDimitry Andricdef RegListAsmOperand : AsmOperandClass { let Name = "RegList"; } 6020b57cec5SDimitry Andricdef reglist : Operand<i32> { 6030b57cec5SDimitry Andric let EncoderMethod = "getRegisterListOpValue"; 6040b57cec5SDimitry Andric let ParserMatchClass = RegListAsmOperand; 6050b57cec5SDimitry Andric let PrintMethod = "printRegisterList"; 6060b57cec5SDimitry Andric let DecoderMethod = "DecodeRegListOperand"; 6070b57cec5SDimitry Andric} 6080b57cec5SDimitry Andric 6090b57cec5SDimitry Andric// A list of general purpose registers and APSR separated by comma. 6100b57cec5SDimitry Andric// Used by CLRM 6110b57cec5SDimitry Andricdef RegListWithAPSRAsmOperand : AsmOperandClass { let Name = "RegListWithAPSR"; } 6120b57cec5SDimitry Andricdef reglist_with_apsr : Operand<i32> { 6130b57cec5SDimitry Andric let EncoderMethod = "getRegisterListOpValue"; 6140b57cec5SDimitry Andric let ParserMatchClass = RegListWithAPSRAsmOperand; 6150b57cec5SDimitry Andric let PrintMethod = "printRegisterList"; 6160b57cec5SDimitry Andric let DecoderMethod = "DecodeRegListOperand"; 6170b57cec5SDimitry Andric} 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andricdef GPRPairOp : RegisterOperand<GPRPair, "printGPRPairOperand">; 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andricdef DPRRegListAsmOperand : AsmOperandClass { 6220b57cec5SDimitry Andric let Name = "DPRRegList"; 6230b57cec5SDimitry Andric let DiagnosticType = "DPR_RegList"; 6240b57cec5SDimitry Andric} 6250b57cec5SDimitry Andricdef dpr_reglist : Operand<i32> { 6260b57cec5SDimitry Andric let EncoderMethod = "getRegisterListOpValue"; 6270b57cec5SDimitry Andric let ParserMatchClass = DPRRegListAsmOperand; 6280b57cec5SDimitry Andric let PrintMethod = "printRegisterList"; 6290b57cec5SDimitry Andric let DecoderMethod = "DecodeDPRRegListOperand"; 6300b57cec5SDimitry Andric} 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andricdef SPRRegListAsmOperand : AsmOperandClass { 6330b57cec5SDimitry Andric let Name = "SPRRegList"; 6340b57cec5SDimitry Andric let DiagnosticString = "operand must be a list of registers in range [s0, s31]"; 6350b57cec5SDimitry Andric} 6360b57cec5SDimitry Andricdef spr_reglist : Operand<i32> { 6370b57cec5SDimitry Andric let EncoderMethod = "getRegisterListOpValue"; 6380b57cec5SDimitry Andric let ParserMatchClass = SPRRegListAsmOperand; 6390b57cec5SDimitry Andric let PrintMethod = "printRegisterList"; 6400b57cec5SDimitry Andric let DecoderMethod = "DecodeSPRRegListOperand"; 6410b57cec5SDimitry Andric} 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andricdef FPSRegListWithVPRAsmOperand : AsmOperandClass { let Name = 6440b57cec5SDimitry Andric "FPSRegListWithVPR"; } 6450b57cec5SDimitry Andricdef fp_sreglist_with_vpr : Operand<i32> { 6460b57cec5SDimitry Andric let EncoderMethod = "getRegisterListOpValue"; 6470b57cec5SDimitry Andric let ParserMatchClass = FPSRegListWithVPRAsmOperand; 6480b57cec5SDimitry Andric let PrintMethod = "printRegisterList"; 6490b57cec5SDimitry Andric} 6500b57cec5SDimitry Andricdef FPDRegListWithVPRAsmOperand : AsmOperandClass { let Name = 6510b57cec5SDimitry Andric "FPDRegListWithVPR"; } 6520b57cec5SDimitry Andricdef fp_dreglist_with_vpr : Operand<i32> { 6530b57cec5SDimitry Andric let EncoderMethod = "getRegisterListOpValue"; 6540b57cec5SDimitry Andric let ParserMatchClass = FPDRegListWithVPRAsmOperand; 6550b57cec5SDimitry Andric let PrintMethod = "printRegisterList"; 6560b57cec5SDimitry Andric} 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric// An operand for the CONSTPOOL_ENTRY pseudo-instruction. 6590b57cec5SDimitry Andricdef cpinst_operand : Operand<i32> { 6600b57cec5SDimitry Andric let PrintMethod = "printCPInstOperand"; 6610b57cec5SDimitry Andric} 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric// Local PC labels. 6640b57cec5SDimitry Andricdef pclabel : Operand<i32> { 6650b57cec5SDimitry Andric let PrintMethod = "printPCLabel"; 6660b57cec5SDimitry Andric} 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andric// ADR instruction labels. 6690b57cec5SDimitry Andricdef AdrLabelAsmOperand : AsmOperandClass { let Name = "AdrLabel"; } 6700b57cec5SDimitry Andricdef adrlabel : Operand<i32> { 6710b57cec5SDimitry Andric let EncoderMethod = "getAdrLabelOpValue"; 6720b57cec5SDimitry Andric let ParserMatchClass = AdrLabelAsmOperand; 6730b57cec5SDimitry Andric let PrintMethod = "printAdrLabelOperand<0>"; 6740b57cec5SDimitry Andric} 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andricdef neon_vcvt_imm32 : Operand<i32> { 6770b57cec5SDimitry Andric let EncoderMethod = "getNEONVcvtImm32OpValue"; 6780b57cec5SDimitry Andric let DecoderMethod = "DecodeVCVTImmOperand"; 6790b57cec5SDimitry Andric} 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24. 6820b57cec5SDimitry Andricdef rot_imm_XFORM: SDNodeXForm<imm, [{ 6830b57cec5SDimitry Andric switch (N->getZExtValue()){ 6840b57cec5SDimitry Andric default: llvm_unreachable(nullptr); 6850b57cec5SDimitry Andric case 0: return CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 6860b57cec5SDimitry Andric case 8: return CurDAG->getTargetConstant(1, SDLoc(N), MVT::i32); 6870b57cec5SDimitry Andric case 16: return CurDAG->getTargetConstant(2, SDLoc(N), MVT::i32); 6880b57cec5SDimitry Andric case 24: return CurDAG->getTargetConstant(3, SDLoc(N), MVT::i32); 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric}]>; 6910b57cec5SDimitry Andricdef RotImmAsmOperand : AsmOperandClass { 6920b57cec5SDimitry Andric let Name = "RotImm"; 6930b57cec5SDimitry Andric let ParserMethod = "parseRotImm"; 6940b57cec5SDimitry Andric} 6950b57cec5SDimitry Andricdef rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{ 6960b57cec5SDimitry Andric int32_t v = N->getZExtValue(); 6970b57cec5SDimitry Andric return v == 8 || v == 16 || v == 24; }], 6980b57cec5SDimitry Andric rot_imm_XFORM> { 6990b57cec5SDimitry Andric let PrintMethod = "printRotImmOperand"; 7000b57cec5SDimitry Andric let ParserMatchClass = RotImmAsmOperand; 7010b57cec5SDimitry Andric} 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric// Power-of-two operand for MVE VIDUP and friends, which encode 7040b57cec5SDimitry Andric// {1,2,4,8} as its log to base 2, i.e. as {0,1,2,3} respectively 7050b57cec5SDimitry Andricdef MVE_VIDUP_imm_asmoperand : AsmOperandClass { 7060b57cec5SDimitry Andric let Name = "VIDUP_imm"; 7070b57cec5SDimitry Andric let PredicateMethod = "isPowerTwoInRange<1,8>"; 7080b57cec5SDimitry Andric let RenderMethod = "addPowerTwoOperands"; 7090b57cec5SDimitry Andric let DiagnosticString = "vector increment immediate must be 1, 2, 4 or 8"; 7100b57cec5SDimitry Andric} 7110b57cec5SDimitry Andricdef MVE_VIDUP_imm : Operand<i32> { 7120b57cec5SDimitry Andric let EncoderMethod = "getPowerTwoOpValue"; 7130b57cec5SDimitry Andric let DecoderMethod = "DecodePowerTwoOperand<0,3>"; 7140b57cec5SDimitry Andric let ParserMatchClass = MVE_VIDUP_imm_asmoperand; 7150b57cec5SDimitry Andric} 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric// Pair vector indexing 7180b57cec5SDimitry Andricclass MVEPairVectorIndexOperand<string start, string end> : AsmOperandClass { 7190b57cec5SDimitry Andric let Name = "MVEPairVectorIndex"#start; 7200b57cec5SDimitry Andric let RenderMethod = "addMVEPairVectorIndexOperands"; 7210b57cec5SDimitry Andric let PredicateMethod = "isMVEPairVectorIndex<"#start#", "#end#">"; 7220b57cec5SDimitry Andric} 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andricclass MVEPairVectorIndex<string opval> : Operand<i32> { 7250b57cec5SDimitry Andric let PrintMethod = "printVectorIndex"; 7260b57cec5SDimitry Andric let EncoderMethod = "getMVEPairVectorIndexOpValue<"#opval#">"; 7270b57cec5SDimitry Andric let DecoderMethod = "DecodeMVEPairVectorIndexOperand<"#opval#">"; 7280b57cec5SDimitry Andric let MIOperandInfo = (ops i32imm); 7290b57cec5SDimitry Andric} 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andricdef MVEPairVectorIndex0 : MVEPairVectorIndex<"0"> { 7320b57cec5SDimitry Andric let ParserMatchClass = MVEPairVectorIndexOperand<"0", "1">; 7330b57cec5SDimitry Andric} 7340b57cec5SDimitry Andric 7350b57cec5SDimitry Andricdef MVEPairVectorIndex2 : MVEPairVectorIndex<"2"> { 7360b57cec5SDimitry Andric let ParserMatchClass = MVEPairVectorIndexOperand<"2", "3">; 7370b57cec5SDimitry Andric} 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andric// Vector indexing 7400b57cec5SDimitry Andricclass MVEVectorIndexOperand<int NumLanes> : AsmOperandClass { 7410b57cec5SDimitry Andric let Name = "MVEVectorIndex"#NumLanes; 7420b57cec5SDimitry Andric let RenderMethod = "addMVEVectorIndexOperands"; 7430b57cec5SDimitry Andric let PredicateMethod = "isVectorIndexInRange<"#NumLanes#">"; 7440b57cec5SDimitry Andric} 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andricclass MVEVectorIndex<int NumLanes> : Operand<i32> { 7470b57cec5SDimitry Andric let PrintMethod = "printVectorIndex"; 7480b57cec5SDimitry Andric let ParserMatchClass = MVEVectorIndexOperand<NumLanes>; 7490b57cec5SDimitry Andric let MIOperandInfo = (ops i32imm); 7500b57cec5SDimitry Andric} 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric// shift_imm: An integer that encodes a shift amount and the type of shift 7530b57cec5SDimitry Andric// (asr or lsl). The 6-bit immediate encodes as: 7540b57cec5SDimitry Andric// {5} 0 ==> lsl 7550b57cec5SDimitry Andric// 1 asr 7560b57cec5SDimitry Andric// {4-0} imm5 shift amount. 7570b57cec5SDimitry Andric// asr #32 encoded as imm5 == 0. 7580b57cec5SDimitry Andricdef ShifterImmAsmOperand : AsmOperandClass { 7590b57cec5SDimitry Andric let Name = "ShifterImm"; 7600b57cec5SDimitry Andric let ParserMethod = "parseShifterImm"; 7610b57cec5SDimitry Andric} 7620b57cec5SDimitry Andricdef shift_imm : Operand<i32> { 7630b57cec5SDimitry Andric let PrintMethod = "printShiftImmOperand"; 7640b57cec5SDimitry Andric let ParserMatchClass = ShifterImmAsmOperand; 7650b57cec5SDimitry Andric} 7660b57cec5SDimitry Andric 7670b57cec5SDimitry Andric// shifter_operand operands: so_reg_reg, so_reg_imm, and mod_imm. 7680b57cec5SDimitry Andricdef ShiftedRegAsmOperand : AsmOperandClass { let Name = "RegShiftedReg"; } 7690b57cec5SDimitry Andricdef so_reg_reg : Operand<i32>, // reg reg imm 7700b57cec5SDimitry Andric ComplexPattern<i32, 3, "SelectRegShifterOperand", 7710b57cec5SDimitry Andric [shl, srl, sra, rotr]> { 7720b57cec5SDimitry Andric let EncoderMethod = "getSORegRegOpValue"; 7730b57cec5SDimitry Andric let PrintMethod = "printSORegRegOperand"; 7740b57cec5SDimitry Andric let DecoderMethod = "DecodeSORegRegOperand"; 7750b57cec5SDimitry Andric let ParserMatchClass = ShiftedRegAsmOperand; 7760b57cec5SDimitry Andric let MIOperandInfo = (ops GPRnopc, GPRnopc, i32imm); 7770b57cec5SDimitry Andric} 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andricdef ShiftedImmAsmOperand : AsmOperandClass { let Name = "RegShiftedImm"; } 7800b57cec5SDimitry Andricdef so_reg_imm : Operand<i32>, // reg imm 7810b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectImmShifterOperand", 7820b57cec5SDimitry Andric [shl, srl, sra, rotr]> { 7830b57cec5SDimitry Andric let EncoderMethod = "getSORegImmOpValue"; 7840b57cec5SDimitry Andric let PrintMethod = "printSORegImmOperand"; 7850b57cec5SDimitry Andric let DecoderMethod = "DecodeSORegImmOperand"; 7860b57cec5SDimitry Andric let ParserMatchClass = ShiftedImmAsmOperand; 7870b57cec5SDimitry Andric let MIOperandInfo = (ops GPR, i32imm); 7880b57cec5SDimitry Andric} 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric// FIXME: Does this need to be distinct from so_reg? 7910b57cec5SDimitry Andricdef shift_so_reg_reg : Operand<i32>, // reg reg imm 7920b57cec5SDimitry Andric ComplexPattern<i32, 3, "SelectShiftRegShifterOperand", 7930b57cec5SDimitry Andric [shl,srl,sra,rotr]> { 7940b57cec5SDimitry Andric let EncoderMethod = "getSORegRegOpValue"; 7950b57cec5SDimitry Andric let PrintMethod = "printSORegRegOperand"; 7960b57cec5SDimitry Andric let DecoderMethod = "DecodeSORegRegOperand"; 7970b57cec5SDimitry Andric let ParserMatchClass = ShiftedRegAsmOperand; 7980b57cec5SDimitry Andric let MIOperandInfo = (ops GPR, GPR, i32imm); 7990b57cec5SDimitry Andric} 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric// FIXME: Does this need to be distinct from so_reg? 8020b57cec5SDimitry Andricdef shift_so_reg_imm : Operand<i32>, // reg reg imm 8030b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectShiftImmShifterOperand", 8040b57cec5SDimitry Andric [shl,srl,sra,rotr]> { 8050b57cec5SDimitry Andric let EncoderMethod = "getSORegImmOpValue"; 8060b57cec5SDimitry Andric let PrintMethod = "printSORegImmOperand"; 8070b57cec5SDimitry Andric let DecoderMethod = "DecodeSORegImmOperand"; 8080b57cec5SDimitry Andric let ParserMatchClass = ShiftedImmAsmOperand; 8090b57cec5SDimitry Andric let MIOperandInfo = (ops GPR, i32imm); 8100b57cec5SDimitry Andric} 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric// mod_imm: match a 32-bit immediate operand, which can be encoded into 8130b57cec5SDimitry Andric// a 12-bit immediate; an 8-bit integer and a 4-bit rotator (See ARMARM 8140b57cec5SDimitry Andric// - "Modified Immediate Constants"). Within the MC layer we keep this 8150b57cec5SDimitry Andric// immediate in its encoded form. 8160b57cec5SDimitry Andricdef ModImmAsmOperand: AsmOperandClass { 8170b57cec5SDimitry Andric let Name = "ModImm"; 8180b57cec5SDimitry Andric let ParserMethod = "parseModImm"; 8190b57cec5SDimitry Andric} 8200b57cec5SDimitry Andricdef mod_imm : Operand<i32>, ImmLeaf<i32, [{ 8210b57cec5SDimitry Andric return ARM_AM::getSOImmVal(Imm) != -1; 8220b57cec5SDimitry Andric }]> { 8230b57cec5SDimitry Andric let EncoderMethod = "getModImmOpValue"; 8240b57cec5SDimitry Andric let PrintMethod = "printModImmOperand"; 8250b57cec5SDimitry Andric let ParserMatchClass = ModImmAsmOperand; 8260b57cec5SDimitry Andric} 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric// Note: the patterns mod_imm_not and mod_imm_neg do not require an encoder 8290b57cec5SDimitry Andric// method and such, as they are only used on aliases (Pat<> and InstAlias<>). 8300b57cec5SDimitry Andric// The actual parsing, encoding, decoding are handled by the destination 8310b57cec5SDimitry Andric// instructions, which use mod_imm. 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andricdef ModImmNotAsmOperand : AsmOperandClass { let Name = "ModImmNot"; } 834*0fca6ea1SDimitry Andricdef mod_imm_not : Operand<i32>, ImmLeaf<i32, [{ 835*0fca6ea1SDimitry Andric return ARM_AM::getSOImmVal(~(uint32_t)Imm) != -1; 8360b57cec5SDimitry Andric }], imm_not_XFORM> { 8370b57cec5SDimitry Andric let ParserMatchClass = ModImmNotAsmOperand; 8380b57cec5SDimitry Andric} 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andricdef ModImmNegAsmOperand : AsmOperandClass { let Name = "ModImmNeg"; } 8410b57cec5SDimitry Andricdef mod_imm_neg : Operand<i32>, PatLeaf<(imm), [{ 8420b57cec5SDimitry Andric unsigned Value = -(unsigned)N->getZExtValue(); 8430b57cec5SDimitry Andric return Value && ARM_AM::getSOImmVal(Value) != -1; 8440b57cec5SDimitry Andric }], imm_neg_XFORM> { 8450b57cec5SDimitry Andric let ParserMatchClass = ModImmNegAsmOperand; 8460b57cec5SDimitry Andric} 8470b57cec5SDimitry Andric 8480b57cec5SDimitry Andric/// arm_i32imm - True for +V6T2, or when isSOImmTwoParVal() 8490b57cec5SDimitry Andricdef arm_i32imm : IntImmLeaf<i32, [{ 8500b57cec5SDimitry Andric if (Subtarget->useMovt()) 8510b57cec5SDimitry Andric return true; 852e8d8bef9SDimitry Andric if (ARM_AM::isSOImmTwoPartVal(Imm.getZExtValue())) 853e8d8bef9SDimitry Andric return true; 854e8d8bef9SDimitry Andric return ARM_AM::isSOImmTwoPartValNeg(Imm.getZExtValue()); 8550b57cec5SDimitry Andric}]>; 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric/// imm0_1 predicate - Immediate in the range [0,1]. 8580b57cec5SDimitry Andricdef Imm0_1AsmOperand: ImmAsmOperand<0,1> { let Name = "Imm0_1"; } 8590b57cec5SDimitry Andricdef imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; } 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric/// imm0_3 predicate - Immediate in the range [0,3]. 8620b57cec5SDimitry Andricdef Imm0_3AsmOperand: ImmAsmOperand<0,3> { let Name = "Imm0_3"; } 8630b57cec5SDimitry Andricdef imm0_3 : Operand<i32> { let ParserMatchClass = Imm0_3AsmOperand; } 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric/// imm0_7 predicate - Immediate in the range [0,7]. 8660b57cec5SDimitry Andricdef Imm0_7AsmOperand: ImmAsmOperand<0,7> { 8670b57cec5SDimitry Andric let Name = "Imm0_7"; 8680b57cec5SDimitry Andric} 8690b57cec5SDimitry Andricdef imm0_7 : Operand<i32>, ImmLeaf<i32, [{ 8700b57cec5SDimitry Andric return Imm >= 0 && Imm < 8; 8710b57cec5SDimitry Andric}]> { 8720b57cec5SDimitry Andric let ParserMatchClass = Imm0_7AsmOperand; 8730b57cec5SDimitry Andric} 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric/// imm8_255 predicate - Immediate in the range [8,255]. 8760b57cec5SDimitry Andricdef Imm8_255AsmOperand: ImmAsmOperand<8,255> { let Name = "Imm8_255"; } 8770b57cec5SDimitry Andricdef imm8_255 : Operand<i32>, ImmLeaf<i32, [{ 8780b57cec5SDimitry Andric return Imm >= 8 && Imm < 256; 8790b57cec5SDimitry Andric}]> { 8800b57cec5SDimitry Andric let ParserMatchClass = Imm8_255AsmOperand; 8810b57cec5SDimitry Andric} 8820b57cec5SDimitry Andric 8830b57cec5SDimitry Andric/// imm8 predicate - Immediate is exactly 8. 8840b57cec5SDimitry Andricdef Imm8AsmOperand: ImmAsmOperand<8,8> { let Name = "Imm8"; } 8850b57cec5SDimitry Andricdef imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 8; }]> { 8860b57cec5SDimitry Andric let ParserMatchClass = Imm8AsmOperand; 8870b57cec5SDimitry Andric} 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andric/// imm16 predicate - Immediate is exactly 16. 8900b57cec5SDimitry Andricdef Imm16AsmOperand: ImmAsmOperand<16,16> { let Name = "Imm16"; } 8910b57cec5SDimitry Andricdef imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 16; }]> { 8920b57cec5SDimitry Andric let ParserMatchClass = Imm16AsmOperand; 8930b57cec5SDimitry Andric} 8940b57cec5SDimitry Andric 8950b57cec5SDimitry Andric/// imm32 predicate - Immediate is exactly 32. 8960b57cec5SDimitry Andricdef Imm32AsmOperand: ImmAsmOperand<32,32> { let Name = "Imm32"; } 8970b57cec5SDimitry Andricdef imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 32; }]> { 8980b57cec5SDimitry Andric let ParserMatchClass = Imm32AsmOperand; 8990b57cec5SDimitry Andric} 9000b57cec5SDimitry Andric 9010b57cec5SDimitry Andricdef imm8_or_16 : ImmLeaf<i32, [{ return Imm == 8 || Imm == 16;}]>; 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric/// imm1_7 predicate - Immediate in the range [1,7]. 9040b57cec5SDimitry Andricdef Imm1_7AsmOperand: ImmAsmOperand<1,7> { let Name = "Imm1_7"; } 9050b57cec5SDimitry Andricdef imm1_7 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 8; }]> { 9060b57cec5SDimitry Andric let ParserMatchClass = Imm1_7AsmOperand; 9070b57cec5SDimitry Andric} 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric/// imm1_15 predicate - Immediate in the range [1,15]. 9100b57cec5SDimitry Andricdef Imm1_15AsmOperand: ImmAsmOperand<1,15> { let Name = "Imm1_15"; } 9110b57cec5SDimitry Andricdef imm1_15 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 16; }]> { 9120b57cec5SDimitry Andric let ParserMatchClass = Imm1_15AsmOperand; 9130b57cec5SDimitry Andric} 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric/// imm1_31 predicate - Immediate in the range [1,31]. 9160b57cec5SDimitry Andricdef Imm1_31AsmOperand: ImmAsmOperand<1,31> { let Name = "Imm1_31"; } 9170b57cec5SDimitry Andricdef imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> { 9180b57cec5SDimitry Andric let ParserMatchClass = Imm1_31AsmOperand; 9190b57cec5SDimitry Andric} 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric/// imm0_15 predicate - Immediate in the range [0,15]. 9220b57cec5SDimitry Andricdef Imm0_15AsmOperand: ImmAsmOperand<0,15> { 9230b57cec5SDimitry Andric let Name = "Imm0_15"; 9240b57cec5SDimitry Andric} 9250b57cec5SDimitry Andricdef imm0_15 : Operand<i32>, ImmLeaf<i32, [{ 9260b57cec5SDimitry Andric return Imm >= 0 && Imm < 16; 9270b57cec5SDimitry Andric}]> { 9280b57cec5SDimitry Andric let ParserMatchClass = Imm0_15AsmOperand; 9290b57cec5SDimitry Andric} 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31]. 9320b57cec5SDimitry Andricdef Imm0_31AsmOperand: ImmAsmOperand<0,31> { let Name = "Imm0_31"; } 9330b57cec5SDimitry Andricdef imm0_31 : Operand<i32>, ImmLeaf<i32, [{ 9340b57cec5SDimitry Andric return Imm >= 0 && Imm < 32; 9350b57cec5SDimitry Andric}]> { 9360b57cec5SDimitry Andric let ParserMatchClass = Imm0_31AsmOperand; 9370b57cec5SDimitry Andric} 9380b57cec5SDimitry Andric 9390b57cec5SDimitry Andric/// imm0_32 predicate - True if the 32-bit immediate is in the range [0,32]. 9400b57cec5SDimitry Andricdef Imm0_32AsmOperand: ImmAsmOperand<0,32> { let Name = "Imm0_32"; } 9410b57cec5SDimitry Andricdef imm0_32 : Operand<i32>, ImmLeaf<i32, [{ 9420b57cec5SDimitry Andric return Imm >= 0 && Imm < 33; 9430b57cec5SDimitry Andric}]> { 9440b57cec5SDimitry Andric let ParserMatchClass = Imm0_32AsmOperand; 9450b57cec5SDimitry Andric} 9460b57cec5SDimitry Andric 9470b57cec5SDimitry Andric/// imm0_63 predicate - True if the 32-bit immediate is in the range [0,63]. 9480b57cec5SDimitry Andricdef Imm0_63AsmOperand: ImmAsmOperand<0,63> { let Name = "Imm0_63"; } 9490b57cec5SDimitry Andricdef imm0_63 : Operand<i32>, ImmLeaf<i32, [{ 9500b57cec5SDimitry Andric return Imm >= 0 && Imm < 64; 9510b57cec5SDimitry Andric}]> { 9520b57cec5SDimitry Andric let ParserMatchClass = Imm0_63AsmOperand; 9530b57cec5SDimitry Andric} 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric/// imm0_239 predicate - Immediate in the range [0,239]. 9560b57cec5SDimitry Andricdef Imm0_239AsmOperand : ImmAsmOperand<0,239> { 9570b57cec5SDimitry Andric let Name = "Imm0_239"; 9580b57cec5SDimitry Andric} 9590b57cec5SDimitry Andricdef imm0_239 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 240; }]> { 9600b57cec5SDimitry Andric let ParserMatchClass = Imm0_239AsmOperand; 9610b57cec5SDimitry Andric} 9620b57cec5SDimitry Andric 9630b57cec5SDimitry Andric/// imm0_255 predicate - Immediate in the range [0,255]. 9640b57cec5SDimitry Andricdef Imm0_255AsmOperand : ImmAsmOperand<0,255> { let Name = "Imm0_255"; } 9650b57cec5SDimitry Andricdef imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> { 9660b57cec5SDimitry Andric let ParserMatchClass = Imm0_255AsmOperand; 9670b57cec5SDimitry Andric} 9680b57cec5SDimitry Andric 96906c3fb27SDimitry Andric// imm0_255_expr - For Thumb1 movs/adds - 8-bit immediate that can also reference 97006c3fb27SDimitry Andric// a relocatable expression. 97106c3fb27SDimitry Andricdef Imm0_255ExprAsmOperand: AsmOperandClass { 97206c3fb27SDimitry Andric let Name = "Imm0_255Expr"; 97306c3fb27SDimitry Andric let RenderMethod = "addImmOperands"; 97406c3fb27SDimitry Andric let DiagnosticString = "operand must be an immediate in the range [0,255] or a relocatable expression"; 97506c3fb27SDimitry Andric} 97606c3fb27SDimitry Andric 97706c3fb27SDimitry Andricdef imm0_255_expr : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> { 97806c3fb27SDimitry Andric let EncoderMethod = "getHiLoImmOpValue"; 97906c3fb27SDimitry Andric let ParserMatchClass = Imm0_255ExprAsmOperand; 98006c3fb27SDimitry Andric} 98106c3fb27SDimitry Andric 9820b57cec5SDimitry Andric/// imm0_65535 - An immediate is in the range [0,65535]. 9830b57cec5SDimitry Andricdef Imm0_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; } 9840b57cec5SDimitry Andricdef imm0_65535 : Operand<i32>, ImmLeaf<i32, [{ 9850b57cec5SDimitry Andric return Imm >= 0 && Imm < 65536; 9860b57cec5SDimitry Andric}]> { 9870b57cec5SDimitry Andric let ParserMatchClass = Imm0_65535AsmOperand; 9880b57cec5SDimitry Andric} 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric// imm0_65535_neg - An immediate whose negative value is in the range [0.65535]. 9910b57cec5SDimitry Andricdef imm0_65535_neg : Operand<i32>, ImmLeaf<i32, [{ 9920b57cec5SDimitry Andric return -Imm >= 0 && -Imm < 65536; 9930b57cec5SDimitry Andric}]>; 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric// imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference 9960b57cec5SDimitry Andric// a relocatable expression. 9970b57cec5SDimitry Andric// 9980b57cec5SDimitry Andric// FIXME: This really needs a Thumb version separate from the ARM version. 9990b57cec5SDimitry Andric// While the range is the same, and can thus use the same match class, 10000b57cec5SDimitry Andric// the encoding is different so it should have a different encoder method. 10010b57cec5SDimitry Andricdef Imm0_65535ExprAsmOperand: AsmOperandClass { 10020b57cec5SDimitry Andric let Name = "Imm0_65535Expr"; 10030b57cec5SDimitry Andric let RenderMethod = "addImmOperands"; 10040b57cec5SDimitry Andric let DiagnosticString = "operand must be an immediate in the range [0,0xffff] or a relocatable expression"; 10050b57cec5SDimitry Andric} 10060b57cec5SDimitry Andric 100706c3fb27SDimitry Andricdef imm0_65535_expr : Operand<i32>, ImmLeaf<i32, [{ 100806c3fb27SDimitry Andric return Imm >= 0 && Imm < 65536; 100906c3fb27SDimitry Andric}]> { 101006c3fb27SDimitry Andric let EncoderMethod = "getHiLoImmOpValue"; 10110b57cec5SDimitry Andric let ParserMatchClass = Imm0_65535ExprAsmOperand; 10120b57cec5SDimitry Andric} 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andricdef Imm256_65535ExprAsmOperand: ImmAsmOperand<256,65535> { let Name = "Imm256_65535Expr"; } 10150b57cec5SDimitry Andricdef imm256_65535_expr : Operand<i32> { 10160b57cec5SDimitry Andric let ParserMatchClass = Imm256_65535ExprAsmOperand; 10170b57cec5SDimitry Andric} 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric/// imm24b - True if the 32-bit immediate is encodable in 24 bits. 10200b57cec5SDimitry Andricdef Imm24bitAsmOperand: ImmAsmOperand<0,0xffffff> { 10210b57cec5SDimitry Andric let Name = "Imm24bit"; 10220b57cec5SDimitry Andric let DiagnosticString = "operand must be an immediate in the range [0,0xffffff]"; 10230b57cec5SDimitry Andric} 10240b57cec5SDimitry Andricdef imm24b : Operand<i32>, ImmLeaf<i32, [{ 10250b57cec5SDimitry Andric return Imm >= 0 && Imm <= 0xffffff; 10260b57cec5SDimitry Andric}]> { 10270b57cec5SDimitry Andric let ParserMatchClass = Imm24bitAsmOperand; 10280b57cec5SDimitry Andric} 10290b57cec5SDimitry Andric 10300b57cec5SDimitry Andric 10310b57cec5SDimitry Andric/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield 10320b57cec5SDimitry Andric/// e.g., 0xf000ffff 10330b57cec5SDimitry Andricdef BitfieldAsmOperand : AsmOperandClass { 10340b57cec5SDimitry Andric let Name = "Bitfield"; 10350b57cec5SDimitry Andric let ParserMethod = "parseBitfield"; 10360b57cec5SDimitry Andric} 10370b57cec5SDimitry Andric 10380b57cec5SDimitry Andricdef bf_inv_mask_imm : Operand<i32>, 10390b57cec5SDimitry Andric PatLeaf<(imm), [{ 10400b57cec5SDimitry Andric return ARM::isBitFieldInvertedMask(N->getZExtValue()); 10410b57cec5SDimitry Andric}] > { 10420b57cec5SDimitry Andric let EncoderMethod = "getBitfieldInvertedMaskOpValue"; 10430b57cec5SDimitry Andric let PrintMethod = "printBitfieldInvMaskImmOperand"; 10440b57cec5SDimitry Andric let DecoderMethod = "DecodeBitfieldMaskOperand"; 10450b57cec5SDimitry Andric let ParserMatchClass = BitfieldAsmOperand; 10460b57cec5SDimitry Andric let GISelPredicateCode = [{ 10470b57cec5SDimitry Andric // There's better methods of implementing this check. IntImmLeaf<> would be 10480b57cec5SDimitry Andric // equivalent and have less boilerplate but we need a test for C++ 10490b57cec5SDimitry Andric // predicates and this one causes new rules to be imported into GlobalISel 10500b57cec5SDimitry Andric // without requiring additional features first. 10510b57cec5SDimitry Andric const auto &MO = MI.getOperand(1); 10520b57cec5SDimitry Andric if (!MO.isCImm()) 10530b57cec5SDimitry Andric return false; 10540b57cec5SDimitry Andric return ARM::isBitFieldInvertedMask(MO.getCImm()->getZExtValue()); 10550b57cec5SDimitry Andric }]; 10560b57cec5SDimitry Andric} 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andricdef imm1_32_XFORM: SDNodeXForm<imm, [{ 10590b57cec5SDimitry Andric return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, SDLoc(N), 10600b57cec5SDimitry Andric MVT::i32); 10610b57cec5SDimitry Andric}]>; 10620b57cec5SDimitry Andricdef Imm1_32AsmOperand: ImmAsmOperandMinusOne<1,32> { 10630b57cec5SDimitry Andric let Name = "Imm1_32"; 10640b57cec5SDimitry Andric} 10650b57cec5SDimitry Andricdef imm1_32 : Operand<i32>, PatLeaf<(imm), [{ 10660b57cec5SDimitry Andric uint64_t Imm = N->getZExtValue(); 10670b57cec5SDimitry Andric return Imm > 0 && Imm <= 32; 10680b57cec5SDimitry Andric }], 10690b57cec5SDimitry Andric imm1_32_XFORM> { 10700b57cec5SDimitry Andric let PrintMethod = "printImmPlusOneOperand"; 10710b57cec5SDimitry Andric let ParserMatchClass = Imm1_32AsmOperand; 10720b57cec5SDimitry Andric} 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andricdef imm1_16_XFORM: SDNodeXForm<imm, [{ 10750b57cec5SDimitry Andric return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, SDLoc(N), 10760b57cec5SDimitry Andric MVT::i32); 10770b57cec5SDimitry Andric}]>; 10780b57cec5SDimitry Andricdef Imm1_16AsmOperand: ImmAsmOperandMinusOne<1,16> { let Name = "Imm1_16"; } 10790b57cec5SDimitry Andricdef imm1_16 : Operand<i32>, ImmLeaf<i32, [{ 10800b57cec5SDimitry Andric return Imm > 0 && Imm <= 16; 10810b57cec5SDimitry Andric }], 10820b57cec5SDimitry Andric imm1_16_XFORM> { 10830b57cec5SDimitry Andric let PrintMethod = "printImmPlusOneOperand"; 10840b57cec5SDimitry Andric let ParserMatchClass = Imm1_16AsmOperand; 10850b57cec5SDimitry Andric} 10860b57cec5SDimitry Andric 10870b57cec5SDimitry Andricdef MVEShiftImm1_7AsmOperand: ImmAsmOperand<1,7> { 10880b57cec5SDimitry Andric let Name = "MVEShiftImm1_7"; 10890b57cec5SDimitry Andric // Reason we're doing this is because instruction vshll.s8 t1 encoding 10900b57cec5SDimitry Andric // accepts 1,7 but the t2 encoding accepts 8. By doing this we can get a 10910b57cec5SDimitry Andric // better diagnostic message if someone uses bigger immediate than the t1/t2 10920b57cec5SDimitry Andric // encodings allow. 10930b57cec5SDimitry Andric let DiagnosticString = "operand must be an immediate in the range [1,8]"; 10940b57cec5SDimitry Andric} 1095480093f4SDimitry Andricdef mve_shift_imm1_7 : Operand<i32>, 1096480093f4SDimitry Andric // SelectImmediateInRange / isScaledConstantInRange uses a 1097480093f4SDimitry Andric // half-open interval, so the parameters <1,8> mean 1-7 inclusive 1098480093f4SDimitry Andric ComplexPattern<i32, 1, "SelectImmediateInRange<1,8>", [], []> { 10990b57cec5SDimitry Andric let ParserMatchClass = MVEShiftImm1_7AsmOperand; 11000b57cec5SDimitry Andric let EncoderMethod = "getMVEShiftImmOpValue"; 11010b57cec5SDimitry Andric} 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andricdef MVEShiftImm1_15AsmOperand: ImmAsmOperand<1,15> { 11040b57cec5SDimitry Andric let Name = "MVEShiftImm1_15"; 11050b57cec5SDimitry Andric // Reason we're doing this is because instruction vshll.s16 t1 encoding 11060b57cec5SDimitry Andric // accepts 1,15 but the t2 encoding accepts 16. By doing this we can get a 11070b57cec5SDimitry Andric // better diagnostic message if someone uses bigger immediate than the t1/t2 11080b57cec5SDimitry Andric // encodings allow. 11090b57cec5SDimitry Andric let DiagnosticString = "operand must be an immediate in the range [1,16]"; 11100b57cec5SDimitry Andric} 1111480093f4SDimitry Andricdef mve_shift_imm1_15 : Operand<i32>, 1112480093f4SDimitry Andric // SelectImmediateInRange / isScaledConstantInRange uses a 1113480093f4SDimitry Andric // half-open interval, so the parameters <1,16> mean 1-15 inclusive 1114480093f4SDimitry Andric ComplexPattern<i32, 1, "SelectImmediateInRange<1,16>", [], []> { 11150b57cec5SDimitry Andric let ParserMatchClass = MVEShiftImm1_15AsmOperand; 11160b57cec5SDimitry Andric let EncoderMethod = "getMVEShiftImmOpValue"; 11170b57cec5SDimitry Andric} 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric// Define ARM specific addressing modes. 11200b57cec5SDimitry Andric// addrmode_imm12 := reg +/- imm12 11210b57cec5SDimitry Andric// 11220b57cec5SDimitry Andricdef MemImm12OffsetAsmOperand : AsmOperandClass { let Name = "MemImm12Offset"; } 11230b57cec5SDimitry Andricclass AddrMode_Imm12 : MemOperand, 11240b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrModeImm12", []> { 11250b57cec5SDimitry Andric // 12-bit immediate operand. Note that instructions using this encode 11260b57cec5SDimitry Andric // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other 11270b57cec5SDimitry Andric // immediate values are as normal. 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric let EncoderMethod = "getAddrModeImm12OpValue"; 11300b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrModeImm12Operand"; 11310b57cec5SDimitry Andric let ParserMatchClass = MemImm12OffsetAsmOperand; 11320b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 11330b57cec5SDimitry Andric} 11340b57cec5SDimitry Andric 11350b57cec5SDimitry Andricdef addrmode_imm12 : AddrMode_Imm12 { 11360b57cec5SDimitry Andric let PrintMethod = "printAddrModeImm12Operand<false>"; 11370b57cec5SDimitry Andric} 11380b57cec5SDimitry Andric 11390b57cec5SDimitry Andricdef addrmode_imm12_pre : AddrMode_Imm12 { 11400b57cec5SDimitry Andric let PrintMethod = "printAddrModeImm12Operand<true>"; 11410b57cec5SDimitry Andric} 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric// ldst_so_reg := reg +/- reg shop imm 11440b57cec5SDimitry Andric// 11450b57cec5SDimitry Andricdef MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; } 11460b57cec5SDimitry Andricdef ldst_so_reg : MemOperand, 11470b57cec5SDimitry Andric ComplexPattern<i32, 3, "SelectLdStSOReg", []> { 11480b57cec5SDimitry Andric let EncoderMethod = "getLdStSORegOpValue"; 11490b57cec5SDimitry Andric // FIXME: Simplify the printer 11500b57cec5SDimitry Andric let PrintMethod = "printAddrMode2Operand"; 11510b57cec5SDimitry Andric let DecoderMethod = "DecodeSORegMemOperand"; 11520b57cec5SDimitry Andric let ParserMatchClass = MemRegOffsetAsmOperand; 11530b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$base, GPRnopc:$offsreg, i32imm:$shift); 11540b57cec5SDimitry Andric} 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric// postidx_imm8 := +/- [0,255] 11570b57cec5SDimitry Andric// 11580b57cec5SDimitry Andric// 9 bit value: 11590b57cec5SDimitry Andric// {8} 1 is imm8 is non-negative. 0 otherwise. 11600b57cec5SDimitry Andric// {7-0} [0,255] imm8 value. 11610b57cec5SDimitry Andricdef PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; } 11620b57cec5SDimitry Andricdef postidx_imm8 : MemOperand { 11630b57cec5SDimitry Andric let PrintMethod = "printPostIdxImm8Operand"; 11640b57cec5SDimitry Andric let ParserMatchClass = PostIdxImm8AsmOperand; 11650b57cec5SDimitry Andric let MIOperandInfo = (ops i32imm); 11660b57cec5SDimitry Andric} 11670b57cec5SDimitry Andric 11680b57cec5SDimitry Andric// postidx_imm8s4 := +/- [0,1020] 11690b57cec5SDimitry Andric// 11700b57cec5SDimitry Andric// 9 bit value: 11710b57cec5SDimitry Andric// {8} 1 is imm8 is non-negative. 0 otherwise. 11720b57cec5SDimitry Andric// {7-0} [0,255] imm8 value, scaled by 4. 11730b57cec5SDimitry Andricdef PostIdxImm8s4AsmOperand : AsmOperandClass { let Name = "PostIdxImm8s4"; } 11740b57cec5SDimitry Andricdef postidx_imm8s4 : MemOperand { 11750b57cec5SDimitry Andric let PrintMethod = "printPostIdxImm8s4Operand"; 11760b57cec5SDimitry Andric let ParserMatchClass = PostIdxImm8s4AsmOperand; 11770b57cec5SDimitry Andric let MIOperandInfo = (ops i32imm); 11780b57cec5SDimitry Andric} 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andric// postidx_reg := +/- reg 11820b57cec5SDimitry Andric// 11830b57cec5SDimitry Andricdef PostIdxRegAsmOperand : AsmOperandClass { 11840b57cec5SDimitry Andric let Name = "PostIdxReg"; 11850b57cec5SDimitry Andric let ParserMethod = "parsePostIdxReg"; 11860b57cec5SDimitry Andric} 11870b57cec5SDimitry Andricdef postidx_reg : MemOperand { 11880b57cec5SDimitry Andric let EncoderMethod = "getPostIdxRegOpValue"; 11890b57cec5SDimitry Andric let DecoderMethod = "DecodePostIdxReg"; 11900b57cec5SDimitry Andric let PrintMethod = "printPostIdxRegOperand"; 11910b57cec5SDimitry Andric let ParserMatchClass = PostIdxRegAsmOperand; 11920b57cec5SDimitry Andric let MIOperandInfo = (ops GPRnopc, i32imm); 11930b57cec5SDimitry Andric} 11940b57cec5SDimitry Andric 11950b57cec5SDimitry Andricdef PostIdxRegShiftedAsmOperand : AsmOperandClass { 11960b57cec5SDimitry Andric let Name = "PostIdxRegShifted"; 11970b57cec5SDimitry Andric let ParserMethod = "parsePostIdxReg"; 11980b57cec5SDimitry Andric} 11990b57cec5SDimitry Andricdef am2offset_reg : MemOperand, 12000b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg", 12010b57cec5SDimitry Andric [], [SDNPWantRoot]> { 12020b57cec5SDimitry Andric let EncoderMethod = "getAddrMode2OffsetOpValue"; 12030b57cec5SDimitry Andric let PrintMethod = "printAddrMode2OffsetOperand"; 12040b57cec5SDimitry Andric // When using this for assembly, it's always as a post-index offset. 12050b57cec5SDimitry Andric let ParserMatchClass = PostIdxRegShiftedAsmOperand; 12060b57cec5SDimitry Andric let MIOperandInfo = (ops GPRnopc, i32imm); 12070b57cec5SDimitry Andric} 12080b57cec5SDimitry Andric 12090b57cec5SDimitry Andric// FIXME: am2offset_imm should only need the immediate, not the GPR. Having 12100b57cec5SDimitry Andric// the GPR is purely vestigal at this point. 12110b57cec5SDimitry Andricdef AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; } 12120b57cec5SDimitry Andricdef am2offset_imm : MemOperand, 12130b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm", 12140b57cec5SDimitry Andric [], [SDNPWantRoot]> { 12150b57cec5SDimitry Andric let EncoderMethod = "getAddrMode2OffsetOpValue"; 12160b57cec5SDimitry Andric let PrintMethod = "printAddrMode2OffsetOperand"; 12170b57cec5SDimitry Andric let ParserMatchClass = AM2OffsetImmAsmOperand; 12180b57cec5SDimitry Andric let MIOperandInfo = (ops GPRnopc, i32imm); 12190b57cec5SDimitry Andric} 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric// addrmode3 := reg +/- reg 12230b57cec5SDimitry Andric// addrmode3 := reg +/- imm8 12240b57cec5SDimitry Andric// 12250b57cec5SDimitry Andric// FIXME: split into imm vs. reg versions. 12260b57cec5SDimitry Andricdef AddrMode3AsmOperand : AsmOperandClass { let Name = "AddrMode3"; } 12270b57cec5SDimitry Andricclass AddrMode3 : MemOperand, 12280b57cec5SDimitry Andric ComplexPattern<i32, 3, "SelectAddrMode3", []> { 12290b57cec5SDimitry Andric let EncoderMethod = "getAddrMode3OpValue"; 12300b57cec5SDimitry Andric let ParserMatchClass = AddrMode3AsmOperand; 12310b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 12320b57cec5SDimitry Andric} 12330b57cec5SDimitry Andric 12340b57cec5SDimitry Andricdef addrmode3 : AddrMode3 12350b57cec5SDimitry Andric{ 12360b57cec5SDimitry Andric let PrintMethod = "printAddrMode3Operand<false>"; 12370b57cec5SDimitry Andric} 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andricdef addrmode3_pre : AddrMode3 12400b57cec5SDimitry Andric{ 12410b57cec5SDimitry Andric let PrintMethod = "printAddrMode3Operand<true>"; 12420b57cec5SDimitry Andric} 12430b57cec5SDimitry Andric 12440b57cec5SDimitry Andric// FIXME: split into imm vs. reg versions. 12450b57cec5SDimitry Andric// FIXME: parser method to handle +/- register. 12460b57cec5SDimitry Andricdef AM3OffsetAsmOperand : AsmOperandClass { 12470b57cec5SDimitry Andric let Name = "AM3Offset"; 12480b57cec5SDimitry Andric let ParserMethod = "parseAM3Offset"; 12490b57cec5SDimitry Andric} 12500b57cec5SDimitry Andricdef am3offset : MemOperand, 12510b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode3Offset", 12520b57cec5SDimitry Andric [], [SDNPWantRoot]> { 12530b57cec5SDimitry Andric let EncoderMethod = "getAddrMode3OffsetOpValue"; 12540b57cec5SDimitry Andric let PrintMethod = "printAddrMode3OffsetOperand"; 12550b57cec5SDimitry Andric let ParserMatchClass = AM3OffsetAsmOperand; 12560b57cec5SDimitry Andric let MIOperandInfo = (ops GPR, i32imm); 12570b57cec5SDimitry Andric} 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric// ldstm_mode := {ia, ib, da, db} 12600b57cec5SDimitry Andric// 12610b57cec5SDimitry Andricdef ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> { 12620b57cec5SDimitry Andric let EncoderMethod = "getLdStmModeOpValue"; 12630b57cec5SDimitry Andric let PrintMethod = "printLdStmModeOperand"; 12640b57cec5SDimitry Andric} 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric// addrmode5 := reg +/- imm8*4 12670b57cec5SDimitry Andric// 12680b57cec5SDimitry Andricdef AddrMode5AsmOperand : AsmOperandClass { let Name = "AddrMode5"; } 12690b57cec5SDimitry Andricclass AddrMode5 : MemOperand, 12700b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode5", []> { 12710b57cec5SDimitry Andric let EncoderMethod = "getAddrMode5OpValue"; 12720b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode5Operand"; 12730b57cec5SDimitry Andric let ParserMatchClass = AddrMode5AsmOperand; 12740b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$base, i32imm); 12750b57cec5SDimitry Andric} 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andricdef addrmode5 : AddrMode5 { 12780b57cec5SDimitry Andric let PrintMethod = "printAddrMode5Operand<false>"; 12790b57cec5SDimitry Andric} 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andricdef addrmode5_pre : AddrMode5 { 12820b57cec5SDimitry Andric let PrintMethod = "printAddrMode5Operand<true>"; 12830b57cec5SDimitry Andric} 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric// addrmode5fp16 := reg +/- imm8*2 12860b57cec5SDimitry Andric// 12870b57cec5SDimitry Andricdef AddrMode5FP16AsmOperand : AsmOperandClass { let Name = "AddrMode5FP16"; } 1288349cc55cSDimitry Andricclass AddrMode5FP16 : MemOperand, 12890b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode5FP16", []> { 12900b57cec5SDimitry Andric let EncoderMethod = "getAddrMode5FP16OpValue"; 12910b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode5FP16Operand"; 12920b57cec5SDimitry Andric let ParserMatchClass = AddrMode5FP16AsmOperand; 12930b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$base, i32imm); 12940b57cec5SDimitry Andric} 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andricdef addrmode5fp16 : AddrMode5FP16 { 12970b57cec5SDimitry Andric let PrintMethod = "printAddrMode5FP16Operand<false>"; 12980b57cec5SDimitry Andric} 12990b57cec5SDimitry Andric 13000b57cec5SDimitry Andric// addrmode6 := reg with optional alignment 13010b57cec5SDimitry Andric// 13020b57cec5SDimitry Andricdef AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; } 13030b57cec5SDimitry Andricdef addrmode6 : MemOperand, 13040b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 13050b57cec5SDimitry Andric let PrintMethod = "printAddrMode6Operand"; 13060b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$addr, i32imm:$align); 13070b57cec5SDimitry Andric let EncoderMethod = "getAddrMode6AddressOpValue"; 13080b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode6Operand"; 13090b57cec5SDimitry Andric let ParserMatchClass = AddrMode6AsmOperand; 13100b57cec5SDimitry Andric} 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andricdef am6offset : MemOperand, 13130b57cec5SDimitry Andric ComplexPattern<i32, 1, "SelectAddrMode6Offset", 13140b57cec5SDimitry Andric [], [SDNPWantRoot]> { 13150b57cec5SDimitry Andric let PrintMethod = "printAddrMode6OffsetOperand"; 13160b57cec5SDimitry Andric let MIOperandInfo = (ops GPR); 13170b57cec5SDimitry Andric let EncoderMethod = "getAddrMode6OffsetOpValue"; 13180b57cec5SDimitry Andric let DecoderMethod = "DecodeGPRRegisterClass"; 13190b57cec5SDimitry Andric} 13200b57cec5SDimitry Andric 13210b57cec5SDimitry Andric// Special version of addrmode6 to handle alignment encoding for VST1/VLD1 13220b57cec5SDimitry Andric// (single element from one lane) for size 32. 13230b57cec5SDimitry Andricdef addrmode6oneL32 : MemOperand, 13240b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 13250b57cec5SDimitry Andric let PrintMethod = "printAddrMode6Operand"; 13260b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$addr, i32imm); 13270b57cec5SDimitry Andric let EncoderMethod = "getAddrMode6OneLane32AddressOpValue"; 13280b57cec5SDimitry Andric} 13290b57cec5SDimitry Andric 13300b57cec5SDimitry Andric// Base class for addrmode6 with specific alignment restrictions. 13310b57cec5SDimitry Andricclass AddrMode6Align : MemOperand, 13320b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 13330b57cec5SDimitry Andric let PrintMethod = "printAddrMode6Operand"; 13340b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$addr, i32imm:$align); 13350b57cec5SDimitry Andric let EncoderMethod = "getAddrMode6AddressOpValue"; 13360b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode6Operand"; 13370b57cec5SDimitry Andric} 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andric// Special version of addrmode6 to handle no allowed alignment encoding for 13400b57cec5SDimitry Andric// VLD/VST instructions and checking the alignment is not specified. 13410b57cec5SDimitry Andricdef AddrMode6AlignNoneAsmOperand : AsmOperandClass { 13420b57cec5SDimitry Andric let Name = "AlignedMemoryNone"; 13430b57cec5SDimitry Andric let DiagnosticString = "alignment must be omitted"; 13440b57cec5SDimitry Andric} 13450b57cec5SDimitry Andricdef addrmode6alignNone : AddrMode6Align { 13460b57cec5SDimitry Andric // The alignment specifier can only be omitted. 13470b57cec5SDimitry Andric let ParserMatchClass = AddrMode6AlignNoneAsmOperand; 13480b57cec5SDimitry Andric} 13490b57cec5SDimitry Andric 13500b57cec5SDimitry Andric// Special version of addrmode6 to handle 16-bit alignment encoding for 13510b57cec5SDimitry Andric// VLD/VST instructions and checking the alignment value. 13520b57cec5SDimitry Andricdef AddrMode6Align16AsmOperand : AsmOperandClass { 13530b57cec5SDimitry Andric let Name = "AlignedMemory16"; 13540b57cec5SDimitry Andric let DiagnosticString = "alignment must be 16 or omitted"; 13550b57cec5SDimitry Andric} 13560b57cec5SDimitry Andricdef addrmode6align16 : AddrMode6Align { 13570b57cec5SDimitry Andric // The alignment specifier can only be 16 or omitted. 13580b57cec5SDimitry Andric let ParserMatchClass = AddrMode6Align16AsmOperand; 13590b57cec5SDimitry Andric} 13600b57cec5SDimitry Andric 13610b57cec5SDimitry Andric// Special version of addrmode6 to handle 32-bit alignment encoding for 13620b57cec5SDimitry Andric// VLD/VST instructions and checking the alignment value. 13630b57cec5SDimitry Andricdef AddrMode6Align32AsmOperand : AsmOperandClass { 13640b57cec5SDimitry Andric let Name = "AlignedMemory32"; 13650b57cec5SDimitry Andric let DiagnosticString = "alignment must be 32 or omitted"; 13660b57cec5SDimitry Andric} 13670b57cec5SDimitry Andricdef addrmode6align32 : AddrMode6Align { 13680b57cec5SDimitry Andric // The alignment specifier can only be 32 or omitted. 13690b57cec5SDimitry Andric let ParserMatchClass = AddrMode6Align32AsmOperand; 13700b57cec5SDimitry Andric} 13710b57cec5SDimitry Andric 13720b57cec5SDimitry Andric// Special version of addrmode6 to handle 64-bit alignment encoding for 13730b57cec5SDimitry Andric// VLD/VST instructions and checking the alignment value. 13740b57cec5SDimitry Andricdef AddrMode6Align64AsmOperand : AsmOperandClass { 13750b57cec5SDimitry Andric let Name = "AlignedMemory64"; 13760b57cec5SDimitry Andric let DiagnosticString = "alignment must be 64 or omitted"; 13770b57cec5SDimitry Andric} 13780b57cec5SDimitry Andricdef addrmode6align64 : AddrMode6Align { 13790b57cec5SDimitry Andric // The alignment specifier can only be 64 or omitted. 13800b57cec5SDimitry Andric let ParserMatchClass = AddrMode6Align64AsmOperand; 13810b57cec5SDimitry Andric} 13820b57cec5SDimitry Andric 13830b57cec5SDimitry Andric// Special version of addrmode6 to handle 64-bit or 128-bit alignment encoding 13840b57cec5SDimitry Andric// for VLD/VST instructions and checking the alignment value. 13850b57cec5SDimitry Andricdef AddrMode6Align64or128AsmOperand : AsmOperandClass { 13860b57cec5SDimitry Andric let Name = "AlignedMemory64or128"; 13870b57cec5SDimitry Andric let DiagnosticString = "alignment must be 64, 128 or omitted"; 13880b57cec5SDimitry Andric} 13890b57cec5SDimitry Andricdef addrmode6align64or128 : AddrMode6Align { 13900b57cec5SDimitry Andric // The alignment specifier can only be 64, 128 or omitted. 13910b57cec5SDimitry Andric let ParserMatchClass = AddrMode6Align64or128AsmOperand; 13920b57cec5SDimitry Andric} 13930b57cec5SDimitry Andric 13940b57cec5SDimitry Andric// Special version of addrmode6 to handle 64-bit, 128-bit or 256-bit alignment 13950b57cec5SDimitry Andric// encoding for VLD/VST instructions and checking the alignment value. 13960b57cec5SDimitry Andricdef AddrMode6Align64or128or256AsmOperand : AsmOperandClass { 13970b57cec5SDimitry Andric let Name = "AlignedMemory64or128or256"; 13980b57cec5SDimitry Andric let DiagnosticString = "alignment must be 64, 128, 256 or omitted"; 13990b57cec5SDimitry Andric} 14000b57cec5SDimitry Andricdef addrmode6align64or128or256 : AddrMode6Align { 14010b57cec5SDimitry Andric // The alignment specifier can only be 64, 128, 256 or omitted. 14020b57cec5SDimitry Andric let ParserMatchClass = AddrMode6Align64or128or256AsmOperand; 14030b57cec5SDimitry Andric} 14040b57cec5SDimitry Andric 14050b57cec5SDimitry Andric// Special version of addrmode6 to handle alignment encoding for VLD-dup 14060b57cec5SDimitry Andric// instructions, specifically VLD4-dup. 14070b57cec5SDimitry Andricdef addrmode6dup : MemOperand, 14080b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 14090b57cec5SDimitry Andric let PrintMethod = "printAddrMode6Operand"; 14100b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$addr, i32imm); 14110b57cec5SDimitry Andric let EncoderMethod = "getAddrMode6DupAddressOpValue"; 14120b57cec5SDimitry Andric // FIXME: This is close, but not quite right. The alignment specifier is 14130b57cec5SDimitry Andric // different. 14140b57cec5SDimitry Andric let ParserMatchClass = AddrMode6AsmOperand; 14150b57cec5SDimitry Andric} 14160b57cec5SDimitry Andric 14170b57cec5SDimitry Andric// Base class for addrmode6dup with specific alignment restrictions. 14180b57cec5SDimitry Andricclass AddrMode6DupAlign : MemOperand, 14190b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 14200b57cec5SDimitry Andric let PrintMethod = "printAddrMode6Operand"; 14210b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$addr, i32imm); 14220b57cec5SDimitry Andric let EncoderMethod = "getAddrMode6DupAddressOpValue"; 14230b57cec5SDimitry Andric} 14240b57cec5SDimitry Andric 14250b57cec5SDimitry Andric// Special version of addrmode6 to handle no allowed alignment encoding for 14260b57cec5SDimitry Andric// VLD-dup instruction and checking the alignment is not specified. 14270b57cec5SDimitry Andricdef AddrMode6dupAlignNoneAsmOperand : AsmOperandClass { 14280b57cec5SDimitry Andric let Name = "DupAlignedMemoryNone"; 14290b57cec5SDimitry Andric let DiagnosticString = "alignment must be omitted"; 14300b57cec5SDimitry Andric} 14310b57cec5SDimitry Andricdef addrmode6dupalignNone : AddrMode6DupAlign { 14320b57cec5SDimitry Andric // The alignment specifier can only be omitted. 14330b57cec5SDimitry Andric let ParserMatchClass = AddrMode6dupAlignNoneAsmOperand; 14340b57cec5SDimitry Andric} 14350b57cec5SDimitry Andric 14360b57cec5SDimitry Andric// Special version of addrmode6 to handle 16-bit alignment encoding for VLD-dup 14370b57cec5SDimitry Andric// instruction and checking the alignment value. 14380b57cec5SDimitry Andricdef AddrMode6dupAlign16AsmOperand : AsmOperandClass { 14390b57cec5SDimitry Andric let Name = "DupAlignedMemory16"; 14400b57cec5SDimitry Andric let DiagnosticString = "alignment must be 16 or omitted"; 14410b57cec5SDimitry Andric} 14420b57cec5SDimitry Andricdef addrmode6dupalign16 : AddrMode6DupAlign { 14430b57cec5SDimitry Andric // The alignment specifier can only be 16 or omitted. 14440b57cec5SDimitry Andric let ParserMatchClass = AddrMode6dupAlign16AsmOperand; 14450b57cec5SDimitry Andric} 14460b57cec5SDimitry Andric 14470b57cec5SDimitry Andric// Special version of addrmode6 to handle 32-bit alignment encoding for VLD-dup 14480b57cec5SDimitry Andric// instruction and checking the alignment value. 14490b57cec5SDimitry Andricdef AddrMode6dupAlign32AsmOperand : AsmOperandClass { 14500b57cec5SDimitry Andric let Name = "DupAlignedMemory32"; 14510b57cec5SDimitry Andric let DiagnosticString = "alignment must be 32 or omitted"; 14520b57cec5SDimitry Andric} 14530b57cec5SDimitry Andricdef addrmode6dupalign32 : AddrMode6DupAlign { 14540b57cec5SDimitry Andric // The alignment specifier can only be 32 or omitted. 14550b57cec5SDimitry Andric let ParserMatchClass = AddrMode6dupAlign32AsmOperand; 14560b57cec5SDimitry Andric} 14570b57cec5SDimitry Andric 14580b57cec5SDimitry Andric// Special version of addrmode6 to handle 64-bit alignment encoding for VLD 14590b57cec5SDimitry Andric// instructions and checking the alignment value. 14600b57cec5SDimitry Andricdef AddrMode6dupAlign64AsmOperand : AsmOperandClass { 14610b57cec5SDimitry Andric let Name = "DupAlignedMemory64"; 14620b57cec5SDimitry Andric let DiagnosticString = "alignment must be 64 or omitted"; 14630b57cec5SDimitry Andric} 14640b57cec5SDimitry Andricdef addrmode6dupalign64 : AddrMode6DupAlign { 14650b57cec5SDimitry Andric // The alignment specifier can only be 64 or omitted. 14660b57cec5SDimitry Andric let ParserMatchClass = AddrMode6dupAlign64AsmOperand; 14670b57cec5SDimitry Andric} 14680b57cec5SDimitry Andric 14690b57cec5SDimitry Andric// Special version of addrmode6 to handle 64-bit or 128-bit alignment encoding 14700b57cec5SDimitry Andric// for VLD instructions and checking the alignment value. 14710b57cec5SDimitry Andricdef AddrMode6dupAlign64or128AsmOperand : AsmOperandClass { 14720b57cec5SDimitry Andric let Name = "DupAlignedMemory64or128"; 14730b57cec5SDimitry Andric let DiagnosticString = "alignment must be 64, 128 or omitted"; 14740b57cec5SDimitry Andric} 14750b57cec5SDimitry Andricdef addrmode6dupalign64or128 : AddrMode6DupAlign { 14760b57cec5SDimitry Andric // The alignment specifier can only be 64, 128 or omitted. 14770b57cec5SDimitry Andric let ParserMatchClass = AddrMode6dupAlign64or128AsmOperand; 14780b57cec5SDimitry Andric} 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric// addrmodepc := pc + reg 14810b57cec5SDimitry Andric// 14820b57cec5SDimitry Andricdef addrmodepc : MemOperand, 14830b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectAddrModePC", []> { 14840b57cec5SDimitry Andric let PrintMethod = "printAddrModePCOperand"; 14850b57cec5SDimitry Andric let MIOperandInfo = (ops GPR, i32imm); 14860b57cec5SDimitry Andric} 14870b57cec5SDimitry Andric 14880b57cec5SDimitry Andric// addr_offset_none := reg 14890b57cec5SDimitry Andric// 14900b57cec5SDimitry Andricdef MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; } 14910b57cec5SDimitry Andricdef addr_offset_none : MemOperand, 14920b57cec5SDimitry Andric ComplexPattern<i32, 1, "SelectAddrOffsetNone", []> { 14930b57cec5SDimitry Andric let PrintMethod = "printAddrMode7Operand"; 14940b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode7Operand"; 14950b57cec5SDimitry Andric let ParserMatchClass = MemNoOffsetAsmOperand; 14960b57cec5SDimitry Andric let MIOperandInfo = (ops GPR:$base); 14970b57cec5SDimitry Andric} 14980b57cec5SDimitry Andric 14990b57cec5SDimitry Andric// t_addr_offset_none := reg [r0-r7] 15000b57cec5SDimitry Andricdef MemNoOffsetTAsmOperand : AsmOperandClass { let Name = "MemNoOffsetT"; } 15010b57cec5SDimitry Andricdef t_addr_offset_none : MemOperand { 15020b57cec5SDimitry Andric let PrintMethod = "printAddrMode7Operand"; 15030b57cec5SDimitry Andric let DecoderMethod = "DecodetGPRRegisterClass"; 15040b57cec5SDimitry Andric let ParserMatchClass = MemNoOffsetTAsmOperand; 15050b57cec5SDimitry Andric let MIOperandInfo = (ops tGPR:$base); 15060b57cec5SDimitry Andric} 15070b57cec5SDimitry Andric 15080b57cec5SDimitry Andricdef nohash_imm : Operand<i32> { 15090b57cec5SDimitry Andric let PrintMethod = "printNoHashImmediate"; 15100b57cec5SDimitry Andric} 15110b57cec5SDimitry Andric 15120b57cec5SDimitry Andricdef CoprocNumAsmOperand : AsmOperandClass { 15130b57cec5SDimitry Andric let Name = "CoprocNum"; 15140b57cec5SDimitry Andric let ParserMethod = "parseCoprocNumOperand"; 15150b57cec5SDimitry Andric} 15160b57cec5SDimitry Andricdef p_imm : Operand<i32> { 15170b57cec5SDimitry Andric let PrintMethod = "printPImmediate"; 15180b57cec5SDimitry Andric let ParserMatchClass = CoprocNumAsmOperand; 15190b57cec5SDimitry Andric let DecoderMethod = "DecodeCoprocessor"; 15200b57cec5SDimitry Andric} 15210b57cec5SDimitry Andric 15220b57cec5SDimitry Andricdef CoprocRegAsmOperand : AsmOperandClass { 15230b57cec5SDimitry Andric let Name = "CoprocReg"; 15240b57cec5SDimitry Andric let ParserMethod = "parseCoprocRegOperand"; 15250b57cec5SDimitry Andric} 15260b57cec5SDimitry Andricdef c_imm : Operand<i32> { 15270b57cec5SDimitry Andric let PrintMethod = "printCImmediate"; 15280b57cec5SDimitry Andric let ParserMatchClass = CoprocRegAsmOperand; 15290b57cec5SDimitry Andric} 15300b57cec5SDimitry Andricdef CoprocOptionAsmOperand : AsmOperandClass { 15310b57cec5SDimitry Andric let Name = "CoprocOption"; 15320b57cec5SDimitry Andric let ParserMethod = "parseCoprocOptionOperand"; 15330b57cec5SDimitry Andric} 15340b57cec5SDimitry Andricdef coproc_option_imm : Operand<i32> { 15350b57cec5SDimitry Andric let PrintMethod = "printCoprocOptionImm"; 15360b57cec5SDimitry Andric let ParserMatchClass = CoprocOptionAsmOperand; 15370b57cec5SDimitry Andric} 15380b57cec5SDimitry Andric 15390b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 15400b57cec5SDimitry Andric 15410b57cec5SDimitry Andricinclude "ARMInstrFormats.td" 15420b57cec5SDimitry Andric 15430b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 15440b57cec5SDimitry Andric// Multiclass helpers... 15450b57cec5SDimitry Andric// 15460b57cec5SDimitry Andric 15470b57cec5SDimitry Andric/// AsI1_bin_irs - Defines a set of (op r, {mod_imm|r|so_reg}) patterns for a 15480b57cec5SDimitry Andric/// binop that produces a value. 15490b57cec5SDimitry Andriclet TwoOperandAliasConstraint = "$Rn = $Rd" in 15500b57cec5SDimitry Andricmulticlass AsI1_bin_irs<bits<4> opcod, string opc, 15510b57cec5SDimitry Andric InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 15520b57cec5SDimitry Andric SDPatternOperator opnode, bit Commutable = 0> { 15530b57cec5SDimitry Andric // The register-immediate version is re-materializable. This is useful 15540b57cec5SDimitry Andric // in particular for taking the address of a local. 15550b57cec5SDimitry Andric let isReMaterializable = 1 in { 15560b57cec5SDimitry Andric def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm), DPFrm, 15570b57cec5SDimitry Andric iii, opc, "\t$Rd, $Rn, $imm", 15580b57cec5SDimitry Andric [(set GPR:$Rd, (opnode GPR:$Rn, mod_imm:$imm))]>, 15590b57cec5SDimitry Andric Sched<[WriteALU, ReadALU]> { 15600b57cec5SDimitry Andric bits<4> Rd; 15610b57cec5SDimitry Andric bits<4> Rn; 15620b57cec5SDimitry Andric bits<12> imm; 15630b57cec5SDimitry Andric let Inst{25} = 1; 15640b57cec5SDimitry Andric let Inst{19-16} = Rn; 15650b57cec5SDimitry Andric let Inst{15-12} = Rd; 15660b57cec5SDimitry Andric let Inst{11-0} = imm; 15670b57cec5SDimitry Andric } 15680b57cec5SDimitry Andric } 15690b57cec5SDimitry Andric def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 15700b57cec5SDimitry Andric iir, opc, "\t$Rd, $Rn, $Rm", 15710b57cec5SDimitry Andric [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>, 15720b57cec5SDimitry Andric Sched<[WriteALU, ReadALU, ReadALU]> { 15730b57cec5SDimitry Andric bits<4> Rd; 15740b57cec5SDimitry Andric bits<4> Rn; 15750b57cec5SDimitry Andric bits<4> Rm; 15760b57cec5SDimitry Andric let Inst{25} = 0; 15770b57cec5SDimitry Andric let isCommutable = Commutable; 15780b57cec5SDimitry Andric let Inst{19-16} = Rn; 15790b57cec5SDimitry Andric let Inst{15-12} = Rd; 15800b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 15810b57cec5SDimitry Andric let Inst{3-0} = Rm; 15820b57cec5SDimitry Andric } 15830b57cec5SDimitry Andric 15840b57cec5SDimitry Andric def rsi : AsI1<opcod, (outs GPR:$Rd), 15850b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, 15860b57cec5SDimitry Andric iis, opc, "\t$Rd, $Rn, $shift", 15870b57cec5SDimitry Andric [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]>, 15880b57cec5SDimitry Andric Sched<[WriteALUsi, ReadALU]> { 15890b57cec5SDimitry Andric bits<4> Rd; 15900b57cec5SDimitry Andric bits<4> Rn; 15910b57cec5SDimitry Andric bits<12> shift; 15920b57cec5SDimitry Andric let Inst{25} = 0; 15930b57cec5SDimitry Andric let Inst{19-16} = Rn; 15940b57cec5SDimitry Andric let Inst{15-12} = Rd; 15950b57cec5SDimitry Andric let Inst{11-5} = shift{11-5}; 15960b57cec5SDimitry Andric let Inst{4} = 0; 15970b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 15980b57cec5SDimitry Andric } 15990b57cec5SDimitry Andric 16000b57cec5SDimitry Andric def rsr : AsI1<opcod, (outs GPR:$Rd), 16010b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, 16020b57cec5SDimitry Andric iis, opc, "\t$Rd, $Rn, $shift", 16030b57cec5SDimitry Andric [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]>, 16040b57cec5SDimitry Andric Sched<[WriteALUsr, ReadALUsr]> { 16050b57cec5SDimitry Andric bits<4> Rd; 16060b57cec5SDimitry Andric bits<4> Rn; 16070b57cec5SDimitry Andric bits<12> shift; 16080b57cec5SDimitry Andric let Inst{25} = 0; 16090b57cec5SDimitry Andric let Inst{19-16} = Rn; 16100b57cec5SDimitry Andric let Inst{15-12} = Rd; 16110b57cec5SDimitry Andric let Inst{11-8} = shift{11-8}; 16120b57cec5SDimitry Andric let Inst{7} = 0; 16130b57cec5SDimitry Andric let Inst{6-5} = shift{6-5}; 16140b57cec5SDimitry Andric let Inst{4} = 1; 16150b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 16160b57cec5SDimitry Andric } 16170b57cec5SDimitry Andric} 16180b57cec5SDimitry Andric 16190b57cec5SDimitry Andric/// AsI1_rbin_irs - Same as AsI1_bin_irs except the order of operands are 16200b57cec5SDimitry Andric/// reversed. The 'rr' form is only defined for the disassembler; for codegen 16210b57cec5SDimitry Andric/// it is equivalent to the AsI1_bin_irs counterpart. 16220b57cec5SDimitry Andriclet TwoOperandAliasConstraint = "$Rn = $Rd" in 16230b57cec5SDimitry Andricmulticlass AsI1_rbin_irs<bits<4> opcod, string opc, 16240b57cec5SDimitry Andric InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 1625349cc55cSDimitry Andric SDNode opnode> { 16260b57cec5SDimitry Andric // The register-immediate version is re-materializable. This is useful 16270b57cec5SDimitry Andric // in particular for taking the address of a local. 16280b57cec5SDimitry Andric let isReMaterializable = 1 in { 16290b57cec5SDimitry Andric def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm), DPFrm, 16300b57cec5SDimitry Andric iii, opc, "\t$Rd, $Rn, $imm", 16310b57cec5SDimitry Andric [(set GPR:$Rd, (opnode mod_imm:$imm, GPR:$Rn))]>, 16320b57cec5SDimitry Andric Sched<[WriteALU, ReadALU]> { 16330b57cec5SDimitry Andric bits<4> Rd; 16340b57cec5SDimitry Andric bits<4> Rn; 16350b57cec5SDimitry Andric bits<12> imm; 16360b57cec5SDimitry Andric let Inst{25} = 1; 16370b57cec5SDimitry Andric let Inst{19-16} = Rn; 16380b57cec5SDimitry Andric let Inst{15-12} = Rd; 16390b57cec5SDimitry Andric let Inst{11-0} = imm; 16400b57cec5SDimitry Andric } 16410b57cec5SDimitry Andric } 16420b57cec5SDimitry Andric def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 16430b57cec5SDimitry Andric iir, opc, "\t$Rd, $Rn, $Rm", 16440b57cec5SDimitry Andric [/* pattern left blank */]>, 16450b57cec5SDimitry Andric Sched<[WriteALU, ReadALU, ReadALU]> { 16460b57cec5SDimitry Andric bits<4> Rd; 16470b57cec5SDimitry Andric bits<4> Rn; 16480b57cec5SDimitry Andric bits<4> Rm; 16490b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 16500b57cec5SDimitry Andric let Inst{25} = 0; 16510b57cec5SDimitry Andric let Inst{3-0} = Rm; 16520b57cec5SDimitry Andric let Inst{15-12} = Rd; 16530b57cec5SDimitry Andric let Inst{19-16} = Rn; 16540b57cec5SDimitry Andric } 16550b57cec5SDimitry Andric 16560b57cec5SDimitry Andric def rsi : AsI1<opcod, (outs GPR:$Rd), 16570b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, 16580b57cec5SDimitry Andric iis, opc, "\t$Rd, $Rn, $shift", 16590b57cec5SDimitry Andric [(set GPR:$Rd, (opnode so_reg_imm:$shift, GPR:$Rn))]>, 16600b57cec5SDimitry Andric Sched<[WriteALUsi, ReadALU]> { 16610b57cec5SDimitry Andric bits<4> Rd; 16620b57cec5SDimitry Andric bits<4> Rn; 16630b57cec5SDimitry Andric bits<12> shift; 16640b57cec5SDimitry Andric let Inst{25} = 0; 16650b57cec5SDimitry Andric let Inst{19-16} = Rn; 16660b57cec5SDimitry Andric let Inst{15-12} = Rd; 16670b57cec5SDimitry Andric let Inst{11-5} = shift{11-5}; 16680b57cec5SDimitry Andric let Inst{4} = 0; 16690b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 16700b57cec5SDimitry Andric } 16710b57cec5SDimitry Andric 16720b57cec5SDimitry Andric def rsr : AsI1<opcod, (outs GPR:$Rd), 16730b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, 16740b57cec5SDimitry Andric iis, opc, "\t$Rd, $Rn, $shift", 16750b57cec5SDimitry Andric [(set GPR:$Rd, (opnode so_reg_reg:$shift, GPR:$Rn))]>, 16760b57cec5SDimitry Andric Sched<[WriteALUsr, ReadALUsr]> { 16770b57cec5SDimitry Andric bits<4> Rd; 16780b57cec5SDimitry Andric bits<4> Rn; 16790b57cec5SDimitry Andric bits<12> shift; 16800b57cec5SDimitry Andric let Inst{25} = 0; 16810b57cec5SDimitry Andric let Inst{19-16} = Rn; 16820b57cec5SDimitry Andric let Inst{15-12} = Rd; 16830b57cec5SDimitry Andric let Inst{11-8} = shift{11-8}; 16840b57cec5SDimitry Andric let Inst{7} = 0; 16850b57cec5SDimitry Andric let Inst{6-5} = shift{6-5}; 16860b57cec5SDimitry Andric let Inst{4} = 1; 16870b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 16880b57cec5SDimitry Andric } 16890b57cec5SDimitry Andric} 16900b57cec5SDimitry Andric 16910b57cec5SDimitry Andric/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default. 16920b57cec5SDimitry Andric/// 16930b57cec5SDimitry Andric/// These opcodes will be converted to the real non-S opcodes by 16940b57cec5SDimitry Andric/// AdjustInstrPostInstrSelection after giving them an optional CPSR operand. 16950b57cec5SDimitry Andriclet hasPostISelHook = 1, Defs = [CPSR] in { 16960b57cec5SDimitry Andricmulticlass AsI1_bin_s_irs<InstrItinClass iii, InstrItinClass iir, 16970b57cec5SDimitry Andric InstrItinClass iis, SDNode opnode, 16980b57cec5SDimitry Andric bit Commutable = 0> { 16990b57cec5SDimitry Andric def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm, pred:$p), 17000b57cec5SDimitry Andric 4, iii, 17010b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, mod_imm:$imm))]>, 17020b57cec5SDimitry Andric Sched<[WriteALU, ReadALU]>; 17030b57cec5SDimitry Andric 17040b57cec5SDimitry Andric def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p), 17050b57cec5SDimitry Andric 4, iir, 17060b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]>, 17070b57cec5SDimitry Andric Sched<[WriteALU, ReadALU, ReadALU]> { 17080b57cec5SDimitry Andric let isCommutable = Commutable; 17090b57cec5SDimitry Andric } 17100b57cec5SDimitry Andric def rsi : ARMPseudoInst<(outs GPR:$Rd), 17110b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_imm:$shift, pred:$p), 17120b57cec5SDimitry Andric 4, iis, 17130b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, 17140b57cec5SDimitry Andric so_reg_imm:$shift))]>, 17150b57cec5SDimitry Andric Sched<[WriteALUsi, ReadALU]>; 17160b57cec5SDimitry Andric 17170b57cec5SDimitry Andric def rsr : ARMPseudoInst<(outs GPR:$Rd), 17180b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_reg:$shift, pred:$p), 17190b57cec5SDimitry Andric 4, iis, 17200b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, 17210b57cec5SDimitry Andric so_reg_reg:$shift))]>, 17220b57cec5SDimitry Andric Sched<[WriteALUSsr, ReadALUsr]>; 17230b57cec5SDimitry Andric} 17240b57cec5SDimitry Andric} 17250b57cec5SDimitry Andric 17260b57cec5SDimitry Andric/// AsI1_rbin_s_is - Same as AsI1_bin_s_irs, except selection DAG 17270b57cec5SDimitry Andric/// operands are reversed. 17280b57cec5SDimitry Andriclet hasPostISelHook = 1, Defs = [CPSR] in { 1729349cc55cSDimitry Andricmulticlass AsI1_rbin_s_is<InstrItinClass iii, 1730349cc55cSDimitry Andric InstrItinClass iis, SDNode opnode> { 17310b57cec5SDimitry Andric def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm, pred:$p), 17320b57cec5SDimitry Andric 4, iii, 17330b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode mod_imm:$imm, GPR:$Rn))]>, 17340b57cec5SDimitry Andric Sched<[WriteALU, ReadALU]>; 17350b57cec5SDimitry Andric 17360b57cec5SDimitry Andric def rsi : ARMPseudoInst<(outs GPR:$Rd), 17370b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_imm:$shift, pred:$p), 17380b57cec5SDimitry Andric 4, iis, 17390b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, 17400b57cec5SDimitry Andric GPR:$Rn))]>, 17410b57cec5SDimitry Andric Sched<[WriteALUsi, ReadALU]>; 17420b57cec5SDimitry Andric 17430b57cec5SDimitry Andric def rsr : ARMPseudoInst<(outs GPR:$Rd), 17440b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_reg:$shift, pred:$p), 17450b57cec5SDimitry Andric 4, iis, 17460b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, 17470b57cec5SDimitry Andric GPR:$Rn))]>, 17480b57cec5SDimitry Andric Sched<[WriteALUSsr, ReadALUsr]>; 17490b57cec5SDimitry Andric} 17500b57cec5SDimitry Andric} 17510b57cec5SDimitry Andric 17520b57cec5SDimitry Andric/// AI1_cmp_irs - Defines a set of (op r, {mod_imm|r|so_reg}) cmp / test 17530b57cec5SDimitry Andric/// patterns. Similar to AsI1_bin_irs except the instruction does not produce 17540b57cec5SDimitry Andric/// a explicit result, only implicitly set CPSR. 17550b57cec5SDimitry Andriclet isCompare = 1, Defs = [CPSR] in { 17560b57cec5SDimitry Andricmulticlass AI1_cmp_irs<bits<4> opcod, string opc, 17570b57cec5SDimitry Andric InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 17580b57cec5SDimitry Andric SDPatternOperator opnode, bit Commutable = 0, 17590b57cec5SDimitry Andric string rrDecoderMethod = ""> { 17600b57cec5SDimitry Andric def ri : AI1<opcod, (outs), (ins GPR:$Rn, mod_imm:$imm), DPFrm, iii, 17610b57cec5SDimitry Andric opc, "\t$Rn, $imm", 17620b57cec5SDimitry Andric [(opnode GPR:$Rn, mod_imm:$imm)]>, 17630b57cec5SDimitry Andric Sched<[WriteCMP, ReadALU]> { 17640b57cec5SDimitry Andric bits<4> Rn; 17650b57cec5SDimitry Andric bits<12> imm; 17660b57cec5SDimitry Andric let Inst{25} = 1; 17670b57cec5SDimitry Andric let Inst{20} = 1; 17680b57cec5SDimitry Andric let Inst{19-16} = Rn; 17690b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 17700b57cec5SDimitry Andric let Inst{11-0} = imm; 17710b57cec5SDimitry Andric 17720b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 17730b57cec5SDimitry Andric } 17740b57cec5SDimitry Andric def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir, 17750b57cec5SDimitry Andric opc, "\t$Rn, $Rm", 17760b57cec5SDimitry Andric [(opnode GPR:$Rn, GPR:$Rm)]>, 17770b57cec5SDimitry Andric Sched<[WriteCMP, ReadALU, ReadALU]> { 17780b57cec5SDimitry Andric bits<4> Rn; 17790b57cec5SDimitry Andric bits<4> Rm; 17800b57cec5SDimitry Andric let isCommutable = Commutable; 17810b57cec5SDimitry Andric let Inst{25} = 0; 17820b57cec5SDimitry Andric let Inst{20} = 1; 17830b57cec5SDimitry Andric let Inst{19-16} = Rn; 17840b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 17850b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 17860b57cec5SDimitry Andric let Inst{3-0} = Rm; 17870b57cec5SDimitry Andric let DecoderMethod = rrDecoderMethod; 17880b57cec5SDimitry Andric 17890b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 17900b57cec5SDimitry Andric } 17910b57cec5SDimitry Andric def rsi : AI1<opcod, (outs), 17920b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, iis, 17930b57cec5SDimitry Andric opc, "\t$Rn, $shift", 17940b57cec5SDimitry Andric [(opnode GPR:$Rn, so_reg_imm:$shift)]>, 17950b57cec5SDimitry Andric Sched<[WriteCMPsi, ReadALU]> { 17960b57cec5SDimitry Andric bits<4> Rn; 17970b57cec5SDimitry Andric bits<12> shift; 17980b57cec5SDimitry Andric let Inst{25} = 0; 17990b57cec5SDimitry Andric let Inst{20} = 1; 18000b57cec5SDimitry Andric let Inst{19-16} = Rn; 18010b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 18020b57cec5SDimitry Andric let Inst{11-5} = shift{11-5}; 18030b57cec5SDimitry Andric let Inst{4} = 0; 18040b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 18050b57cec5SDimitry Andric 18060b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 18070b57cec5SDimitry Andric } 18080b57cec5SDimitry Andric def rsr : AI1<opcod, (outs), 18090b57cec5SDimitry Andric (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis, 18100b57cec5SDimitry Andric opc, "\t$Rn, $shift", 18110b57cec5SDimitry Andric [(opnode GPRnopc:$Rn, so_reg_reg:$shift)]>, 18120b57cec5SDimitry Andric Sched<[WriteCMPsr, ReadALU]> { 18130b57cec5SDimitry Andric bits<4> Rn; 18140b57cec5SDimitry Andric bits<12> shift; 18150b57cec5SDimitry Andric let Inst{25} = 0; 18160b57cec5SDimitry Andric let Inst{20} = 1; 18170b57cec5SDimitry Andric let Inst{19-16} = Rn; 18180b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 18190b57cec5SDimitry Andric let Inst{11-8} = shift{11-8}; 18200b57cec5SDimitry Andric let Inst{7} = 0; 18210b57cec5SDimitry Andric let Inst{6-5} = shift{6-5}; 18220b57cec5SDimitry Andric let Inst{4} = 1; 18230b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 18240b57cec5SDimitry Andric 18250b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 18260b57cec5SDimitry Andric } 18270b57cec5SDimitry Andric 18280b57cec5SDimitry Andric} 18290b57cec5SDimitry Andric} 18300b57cec5SDimitry Andric 18310b57cec5SDimitry Andric/// AI_ext_rrot - A unary operation with two forms: one whose operand is a 18320b57cec5SDimitry Andric/// register and one whose operand is a register rotated by 8/16/24. 18330b57cec5SDimitry Andric/// FIXME: Remove the 'r' variant. Its rot_imm is zero. 18340b57cec5SDimitry Andricclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> 18350b57cec5SDimitry Andric : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot), 18360b57cec5SDimitry Andric IIC_iEXTr, opc, "\t$Rd, $Rm$rot", 18370b57cec5SDimitry Andric [(set GPRnopc:$Rd, (opnode (rotr GPRnopc:$Rm, rot_imm:$rot)))]>, 18380b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, Sched<[WriteALUsi]> { 18390b57cec5SDimitry Andric bits<4> Rd; 18400b57cec5SDimitry Andric bits<4> Rm; 18410b57cec5SDimitry Andric bits<2> rot; 18420b57cec5SDimitry Andric let Inst{19-16} = 0b1111; 18430b57cec5SDimitry Andric let Inst{15-12} = Rd; 18440b57cec5SDimitry Andric let Inst{11-10} = rot; 18450b57cec5SDimitry Andric let Inst{3-0} = Rm; 18460b57cec5SDimitry Andric} 18470b57cec5SDimitry Andric 18480b57cec5SDimitry Andricclass AI_ext_rrot_np<bits<8> opcod, string opc> 18490b57cec5SDimitry Andric : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPRnopc:$Rm, rot_imm:$rot), 18500b57cec5SDimitry Andric IIC_iEXTr, opc, "\t$Rd, $Rm$rot", []>, 18510b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, Sched<[WriteALUsi]> { 18520b57cec5SDimitry Andric bits<2> rot; 18530b57cec5SDimitry Andric let Inst{19-16} = 0b1111; 18540b57cec5SDimitry Andric let Inst{11-10} = rot; 18550b57cec5SDimitry Andric } 18560b57cec5SDimitry Andric 18570b57cec5SDimitry Andric/// AI_exta_rrot - A binary operation with two forms: one whose operand is a 18580b57cec5SDimitry Andric/// register and one whose operand is a register rotated by 8/16/24. 18590b57cec5SDimitry Andricclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> 18600b57cec5SDimitry Andric : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot), 18610b57cec5SDimitry Andric IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", 18620b57cec5SDimitry Andric [(set GPRnopc:$Rd, (opnode GPR:$Rn, 18630b57cec5SDimitry Andric (rotr GPRnopc:$Rm, rot_imm:$rot)))]>, 18640b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, Sched<[WriteALUsr]> { 18650b57cec5SDimitry Andric bits<4> Rd; 18660b57cec5SDimitry Andric bits<4> Rm; 18670b57cec5SDimitry Andric bits<4> Rn; 18680b57cec5SDimitry Andric bits<2> rot; 18690b57cec5SDimitry Andric let Inst{19-16} = Rn; 18700b57cec5SDimitry Andric let Inst{15-12} = Rd; 18710b57cec5SDimitry Andric let Inst{11-10} = rot; 18720b57cec5SDimitry Andric let Inst{9-4} = 0b000111; 18730b57cec5SDimitry Andric let Inst{3-0} = Rm; 18740b57cec5SDimitry Andric} 18750b57cec5SDimitry Andric 18760b57cec5SDimitry Andricclass AI_exta_rrot_np<bits<8> opcod, string opc> 18770b57cec5SDimitry Andric : AExtI<opcod, (outs GPRnopc:$Rd), (ins GPR:$Rn, GPRnopc:$Rm, rot_imm:$rot), 18780b57cec5SDimitry Andric IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm$rot", []>, 18790b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, Sched<[WriteALUsr]> { 18800b57cec5SDimitry Andric bits<4> Rn; 18810b57cec5SDimitry Andric bits<2> rot; 18820b57cec5SDimitry Andric let Inst{19-16} = Rn; 18830b57cec5SDimitry Andric let Inst{11-10} = rot; 18840b57cec5SDimitry Andric} 18850b57cec5SDimitry Andric 18860b57cec5SDimitry Andric/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. 18870b57cec5SDimitry Andriclet TwoOperandAliasConstraint = "$Rn = $Rd" in 18880b57cec5SDimitry Andricmulticlass AI1_adde_sube_irs<bits<4> opcod, string opc, SDNode opnode, 18890b57cec5SDimitry Andric bit Commutable = 0> { 18900b57cec5SDimitry Andric let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { 18910b57cec5SDimitry Andric def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm), 18920b57cec5SDimitry Andric DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 18930b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, mod_imm:$imm, CPSR))]>, 18940b57cec5SDimitry Andric Requires<[IsARM]>, 18950b57cec5SDimitry Andric Sched<[WriteALU, ReadALU]> { 18960b57cec5SDimitry Andric bits<4> Rd; 18970b57cec5SDimitry Andric bits<4> Rn; 18980b57cec5SDimitry Andric bits<12> imm; 18990b57cec5SDimitry Andric let Inst{25} = 1; 19000b57cec5SDimitry Andric let Inst{15-12} = Rd; 19010b57cec5SDimitry Andric let Inst{19-16} = Rn; 19020b57cec5SDimitry Andric let Inst{11-0} = imm; 19030b57cec5SDimitry Andric } 19040b57cec5SDimitry Andric def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 19050b57cec5SDimitry Andric DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm", 19060b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm, CPSR))]>, 19070b57cec5SDimitry Andric Requires<[IsARM]>, 19080b57cec5SDimitry Andric Sched<[WriteALU, ReadALU, ReadALU]> { 19090b57cec5SDimitry Andric bits<4> Rd; 19100b57cec5SDimitry Andric bits<4> Rn; 19110b57cec5SDimitry Andric bits<4> Rm; 19120b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 19130b57cec5SDimitry Andric let Inst{25} = 0; 19140b57cec5SDimitry Andric let isCommutable = Commutable; 19150b57cec5SDimitry Andric let Inst{3-0} = Rm; 19160b57cec5SDimitry Andric let Inst{15-12} = Rd; 19170b57cec5SDimitry Andric let Inst{19-16} = Rn; 19180b57cec5SDimitry Andric } 19190b57cec5SDimitry Andric def rsi : AsI1<opcod, (outs GPR:$Rd), 19200b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_imm:$shift), 19210b57cec5SDimitry Andric DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 19220b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_imm:$shift, CPSR))]>, 19230b57cec5SDimitry Andric Requires<[IsARM]>, 19240b57cec5SDimitry Andric Sched<[WriteALUsi, ReadALU]> { 19250b57cec5SDimitry Andric bits<4> Rd; 19260b57cec5SDimitry Andric bits<4> Rn; 19270b57cec5SDimitry Andric bits<12> shift; 19280b57cec5SDimitry Andric let Inst{25} = 0; 19290b57cec5SDimitry Andric let Inst{19-16} = Rn; 19300b57cec5SDimitry Andric let Inst{15-12} = Rd; 19310b57cec5SDimitry Andric let Inst{11-5} = shift{11-5}; 19320b57cec5SDimitry Andric let Inst{4} = 0; 19330b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 19340b57cec5SDimitry Andric } 19350b57cec5SDimitry Andric def rsr : AsI1<opcod, (outs GPRnopc:$Rd), 19360b57cec5SDimitry Andric (ins GPRnopc:$Rn, so_reg_reg:$shift), 19370b57cec5SDimitry Andric DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 19380b57cec5SDimitry Andric [(set GPRnopc:$Rd, CPSR, 19390b57cec5SDimitry Andric (opnode GPRnopc:$Rn, so_reg_reg:$shift, CPSR))]>, 19400b57cec5SDimitry Andric Requires<[IsARM]>, 19410b57cec5SDimitry Andric Sched<[WriteALUsr, ReadALUsr]> { 19420b57cec5SDimitry Andric bits<4> Rd; 19430b57cec5SDimitry Andric bits<4> Rn; 19440b57cec5SDimitry Andric bits<12> shift; 19450b57cec5SDimitry Andric let Inst{25} = 0; 19460b57cec5SDimitry Andric let Inst{19-16} = Rn; 19470b57cec5SDimitry Andric let Inst{15-12} = Rd; 19480b57cec5SDimitry Andric let Inst{11-8} = shift{11-8}; 19490b57cec5SDimitry Andric let Inst{7} = 0; 19500b57cec5SDimitry Andric let Inst{6-5} = shift{6-5}; 19510b57cec5SDimitry Andric let Inst{4} = 1; 19520b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 19530b57cec5SDimitry Andric } 19540b57cec5SDimitry Andric } 19550b57cec5SDimitry Andric} 19560b57cec5SDimitry Andric 19570b57cec5SDimitry Andric/// AI1_rsc_irs - Define instructions and patterns for rsc 19580b57cec5SDimitry Andriclet TwoOperandAliasConstraint = "$Rn = $Rd" in 19590b57cec5SDimitry Andricmulticlass AI1_rsc_irs<bits<4> opcod, string opc, SDNode opnode> { 19600b57cec5SDimitry Andric let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { 19610b57cec5SDimitry Andric def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, mod_imm:$imm), 19620b57cec5SDimitry Andric DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 19630b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode mod_imm:$imm, GPR:$Rn, CPSR))]>, 19640b57cec5SDimitry Andric Requires<[IsARM]>, 19650b57cec5SDimitry Andric Sched<[WriteALU, ReadALU]> { 19660b57cec5SDimitry Andric bits<4> Rd; 19670b57cec5SDimitry Andric bits<4> Rn; 19680b57cec5SDimitry Andric bits<12> imm; 19690b57cec5SDimitry Andric let Inst{25} = 1; 19700b57cec5SDimitry Andric let Inst{15-12} = Rd; 19710b57cec5SDimitry Andric let Inst{19-16} = Rn; 19720b57cec5SDimitry Andric let Inst{11-0} = imm; 19730b57cec5SDimitry Andric } 19740b57cec5SDimitry Andric def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 19750b57cec5SDimitry Andric DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm", 19760b57cec5SDimitry Andric [/* pattern left blank */]>, 19770b57cec5SDimitry Andric Sched<[WriteALU, ReadALU, ReadALU]> { 19780b57cec5SDimitry Andric bits<4> Rd; 19790b57cec5SDimitry Andric bits<4> Rn; 19800b57cec5SDimitry Andric bits<4> Rm; 19810b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 19820b57cec5SDimitry Andric let Inst{25} = 0; 19830b57cec5SDimitry Andric let Inst{3-0} = Rm; 19840b57cec5SDimitry Andric let Inst{15-12} = Rd; 19850b57cec5SDimitry Andric let Inst{19-16} = Rn; 19860b57cec5SDimitry Andric } 19870b57cec5SDimitry Andric def rsi : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift), 19880b57cec5SDimitry Andric DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 19890b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, GPR:$Rn, CPSR))]>, 19900b57cec5SDimitry Andric Requires<[IsARM]>, 19910b57cec5SDimitry Andric Sched<[WriteALUsi, ReadALU]> { 19920b57cec5SDimitry Andric bits<4> Rd; 19930b57cec5SDimitry Andric bits<4> Rn; 19940b57cec5SDimitry Andric bits<12> shift; 19950b57cec5SDimitry Andric let Inst{25} = 0; 19960b57cec5SDimitry Andric let Inst{19-16} = Rn; 19970b57cec5SDimitry Andric let Inst{15-12} = Rd; 19980b57cec5SDimitry Andric let Inst{11-5} = shift{11-5}; 19990b57cec5SDimitry Andric let Inst{4} = 0; 20000b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 20010b57cec5SDimitry Andric } 20020b57cec5SDimitry Andric def rsr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift), 20030b57cec5SDimitry Andric DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 20040b57cec5SDimitry Andric [(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, GPR:$Rn, CPSR))]>, 20050b57cec5SDimitry Andric Requires<[IsARM]>, 20060b57cec5SDimitry Andric Sched<[WriteALUsr, ReadALUsr]> { 20070b57cec5SDimitry Andric bits<4> Rd; 20080b57cec5SDimitry Andric bits<4> Rn; 20090b57cec5SDimitry Andric bits<12> shift; 20100b57cec5SDimitry Andric let Inst{25} = 0; 20110b57cec5SDimitry Andric let Inst{19-16} = Rn; 20120b57cec5SDimitry Andric let Inst{15-12} = Rd; 20130b57cec5SDimitry Andric let Inst{11-8} = shift{11-8}; 20140b57cec5SDimitry Andric let Inst{7} = 0; 20150b57cec5SDimitry Andric let Inst{6-5} = shift{6-5}; 20160b57cec5SDimitry Andric let Inst{4} = 1; 20170b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 20180b57cec5SDimitry Andric } 20190b57cec5SDimitry Andric } 20200b57cec5SDimitry Andric} 20210b57cec5SDimitry Andric 20220b57cec5SDimitry Andriclet canFoldAsLoad = 1, isReMaterializable = 1 in { 20230b57cec5SDimitry Andricmulticlass AI_ldr1<bit isByte, string opc, InstrItinClass iii, 20240b57cec5SDimitry Andric InstrItinClass iir, PatFrag opnode> { 20250b57cec5SDimitry Andric // Note: We use the complex addrmode_imm12 rather than just an input 20260b57cec5SDimitry Andric // GPR and a constrained immediate so that we can use this to match 20270b57cec5SDimitry Andric // frame index references and avoid matching constant pool references. 20280b57cec5SDimitry Andric def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr), 20290b57cec5SDimitry Andric AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", 20300b57cec5SDimitry Andric [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> { 20310b57cec5SDimitry Andric bits<4> Rt; 20320b57cec5SDimitry Andric bits<17> addr; 20330b57cec5SDimitry Andric let Inst{23} = addr{12}; // U (add = ('U' == 1)) 20340b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; // Rn 20350b57cec5SDimitry Andric let Inst{15-12} = Rt; 20360b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; // imm12 20370b57cec5SDimitry Andric } 20380b57cec5SDimitry Andric def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift), 20390b57cec5SDimitry Andric AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", 20400b57cec5SDimitry Andric [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> { 20410b57cec5SDimitry Andric bits<4> Rt; 20420b57cec5SDimitry Andric bits<17> shift; 20430b57cec5SDimitry Andric let shift{4} = 0; // Inst{4} = 0 20440b57cec5SDimitry Andric let Inst{23} = shift{12}; // U (add = ('U' == 1)) 20450b57cec5SDimitry Andric let Inst{19-16} = shift{16-13}; // Rn 20460b57cec5SDimitry Andric let Inst{15-12} = Rt; 20470b57cec5SDimitry Andric let Inst{11-0} = shift{11-0}; 20480b57cec5SDimitry Andric } 20490b57cec5SDimitry Andric} 20500b57cec5SDimitry Andric} 20510b57cec5SDimitry Andric 20520b57cec5SDimitry Andriclet canFoldAsLoad = 1, isReMaterializable = 1 in { 20530b57cec5SDimitry Andricmulticlass AI_ldr1nopc<bit isByte, string opc, InstrItinClass iii, 20540b57cec5SDimitry Andric InstrItinClass iir, PatFrag opnode> { 20550b57cec5SDimitry Andric // Note: We use the complex addrmode_imm12 rather than just an input 20560b57cec5SDimitry Andric // GPR and a constrained immediate so that we can use this to match 20570b57cec5SDimitry Andric // frame index references and avoid matching constant pool references. 20580b57cec5SDimitry Andric def i12: AI2ldst<0b010, 1, isByte, (outs GPRnopc:$Rt), 20590b57cec5SDimitry Andric (ins addrmode_imm12:$addr), 20600b57cec5SDimitry Andric AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", 20610b57cec5SDimitry Andric [(set GPRnopc:$Rt, (opnode addrmode_imm12:$addr))]> { 20620b57cec5SDimitry Andric bits<4> Rt; 20630b57cec5SDimitry Andric bits<17> addr; 20640b57cec5SDimitry Andric let Inst{23} = addr{12}; // U (add = ('U' == 1)) 20650b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; // Rn 20660b57cec5SDimitry Andric let Inst{15-12} = Rt; 20670b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; // imm12 20680b57cec5SDimitry Andric } 20690b57cec5SDimitry Andric def rs : AI2ldst<0b011, 1, isByte, (outs GPRnopc:$Rt), 20700b57cec5SDimitry Andric (ins ldst_so_reg:$shift), 20710b57cec5SDimitry Andric AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", 20720b57cec5SDimitry Andric [(set GPRnopc:$Rt, (opnode ldst_so_reg:$shift))]> { 20730b57cec5SDimitry Andric bits<4> Rt; 20740b57cec5SDimitry Andric bits<17> shift; 20750b57cec5SDimitry Andric let shift{4} = 0; // Inst{4} = 0 20760b57cec5SDimitry Andric let Inst{23} = shift{12}; // U (add = ('U' == 1)) 20770b57cec5SDimitry Andric let Inst{19-16} = shift{16-13}; // Rn 20780b57cec5SDimitry Andric let Inst{15-12} = Rt; 20790b57cec5SDimitry Andric let Inst{11-0} = shift{11-0}; 20800b57cec5SDimitry Andric } 20810b57cec5SDimitry Andric} 20820b57cec5SDimitry Andric} 20830b57cec5SDimitry Andric 20840b57cec5SDimitry Andric 20850b57cec5SDimitry Andricmulticlass AI_str1<bit isByte, string opc, InstrItinClass iii, 20860b57cec5SDimitry Andric InstrItinClass iir, PatFrag opnode> { 20870b57cec5SDimitry Andric // Note: We use the complex addrmode_imm12 rather than just an input 20880b57cec5SDimitry Andric // GPR and a constrained immediate so that we can use this to match 20890b57cec5SDimitry Andric // frame index references and avoid matching constant pool references. 20900b57cec5SDimitry Andric def i12 : AI2ldst<0b010, 0, isByte, (outs), 20910b57cec5SDimitry Andric (ins GPR:$Rt, addrmode_imm12:$addr), 20920b57cec5SDimitry Andric AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", 20930b57cec5SDimitry Andric [(opnode GPR:$Rt, addrmode_imm12:$addr)]> { 20940b57cec5SDimitry Andric bits<4> Rt; 20950b57cec5SDimitry Andric bits<17> addr; 20960b57cec5SDimitry Andric let Inst{23} = addr{12}; // U (add = ('U' == 1)) 20970b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; // Rn 20980b57cec5SDimitry Andric let Inst{15-12} = Rt; 20990b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; // imm12 21000b57cec5SDimitry Andric } 21010b57cec5SDimitry Andric def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift), 21020b57cec5SDimitry Andric AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", 21030b57cec5SDimitry Andric [(opnode GPR:$Rt, ldst_so_reg:$shift)]> { 21040b57cec5SDimitry Andric bits<4> Rt; 21050b57cec5SDimitry Andric bits<17> shift; 21060b57cec5SDimitry Andric let shift{4} = 0; // Inst{4} = 0 21070b57cec5SDimitry Andric let Inst{23} = shift{12}; // U (add = ('U' == 1)) 21080b57cec5SDimitry Andric let Inst{19-16} = shift{16-13}; // Rn 21090b57cec5SDimitry Andric let Inst{15-12} = Rt; 21100b57cec5SDimitry Andric let Inst{11-0} = shift{11-0}; 21110b57cec5SDimitry Andric } 21120b57cec5SDimitry Andric} 21130b57cec5SDimitry Andric 21140b57cec5SDimitry Andricmulticlass AI_str1nopc<bit isByte, string opc, InstrItinClass iii, 21150b57cec5SDimitry Andric InstrItinClass iir, PatFrag opnode> { 21160b57cec5SDimitry Andric // Note: We use the complex addrmode_imm12 rather than just an input 21170b57cec5SDimitry Andric // GPR and a constrained immediate so that we can use this to match 21180b57cec5SDimitry Andric // frame index references and avoid matching constant pool references. 21190b57cec5SDimitry Andric def i12 : AI2ldst<0b010, 0, isByte, (outs), 21200b57cec5SDimitry Andric (ins GPRnopc:$Rt, addrmode_imm12:$addr), 21210b57cec5SDimitry Andric AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", 21220b57cec5SDimitry Andric [(opnode GPRnopc:$Rt, addrmode_imm12:$addr)]> { 21230b57cec5SDimitry Andric bits<4> Rt; 21240b57cec5SDimitry Andric bits<17> addr; 21250b57cec5SDimitry Andric let Inst{23} = addr{12}; // U (add = ('U' == 1)) 21260b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; // Rn 21270b57cec5SDimitry Andric let Inst{15-12} = Rt; 21280b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; // imm12 21290b57cec5SDimitry Andric } 21300b57cec5SDimitry Andric def rs : AI2ldst<0b011, 0, isByte, (outs), 21310b57cec5SDimitry Andric (ins GPRnopc:$Rt, ldst_so_reg:$shift), 21320b57cec5SDimitry Andric AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", 21330b57cec5SDimitry Andric [(opnode GPRnopc:$Rt, ldst_so_reg:$shift)]> { 21340b57cec5SDimitry Andric bits<4> Rt; 21350b57cec5SDimitry Andric bits<17> shift; 21360b57cec5SDimitry Andric let shift{4} = 0; // Inst{4} = 0 21370b57cec5SDimitry Andric let Inst{23} = shift{12}; // U (add = ('U' == 1)) 21380b57cec5SDimitry Andric let Inst{19-16} = shift{16-13}; // Rn 21390b57cec5SDimitry Andric let Inst{15-12} = Rt; 21400b57cec5SDimitry Andric let Inst{11-0} = shift{11-0}; 21410b57cec5SDimitry Andric } 21420b57cec5SDimitry Andric} 21430b57cec5SDimitry Andric 21440b57cec5SDimitry Andric 21450b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 21460b57cec5SDimitry Andric// Instructions 21470b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 21480b57cec5SDimitry Andric 21490b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 21500b57cec5SDimitry Andric// Miscellaneous Instructions. 21510b57cec5SDimitry Andric// 21520b57cec5SDimitry Andric 21530b57cec5SDimitry Andric/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in 21540b57cec5SDimitry Andric/// the function. The first operand is the ID# for this instruction, the second 21550b57cec5SDimitry Andric/// is the index into the MachineConstantPool that this is, the third is the 21560b57cec5SDimitry Andric/// size in bytes of this constant pool entry. 21578bcb0991SDimitry Andriclet hasSideEffects = 0, isNotDuplicable = 1, hasNoSchedulingInfo = 1 in 21580b57cec5SDimitry Andricdef CONSTPOOL_ENTRY : 21590b57cec5SDimitry AndricPseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 21600b57cec5SDimitry Andric i32imm:$size), NoItinerary, []>; 21610b57cec5SDimitry Andric 21620b57cec5SDimitry Andric/// A jumptable consisting of direct 32-bit addresses of the destination basic 21630b57cec5SDimitry Andric/// blocks (either absolute, or relative to the start of the jump-table in PIC 21640b57cec5SDimitry Andric/// mode). Used mostly in ARM and Thumb-1 modes. 21650b57cec5SDimitry Andricdef JUMPTABLE_ADDRS : 21660b57cec5SDimitry AndricPseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 21670b57cec5SDimitry Andric i32imm:$size), NoItinerary, []>; 21680b57cec5SDimitry Andric 21690b57cec5SDimitry Andric/// A jumptable consisting of 32-bit jump instructions. Used for Thumb-2 tables 21700b57cec5SDimitry Andric/// that cannot be optimised to use TBB or TBH. 21710b57cec5SDimitry Andricdef JUMPTABLE_INSTS : 21720b57cec5SDimitry AndricPseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 21730b57cec5SDimitry Andric i32imm:$size), NoItinerary, []>; 21740b57cec5SDimitry Andric 21750b57cec5SDimitry Andric/// A jumptable consisting of 8-bit unsigned integers representing offsets from 21760b57cec5SDimitry Andric/// a TBB instruction. 21770b57cec5SDimitry Andricdef JUMPTABLE_TBB : 21780b57cec5SDimitry AndricPseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 21790b57cec5SDimitry Andric i32imm:$size), NoItinerary, []>; 21800b57cec5SDimitry Andric 21810b57cec5SDimitry Andric/// A jumptable consisting of 16-bit unsigned integers representing offsets from 21820b57cec5SDimitry Andric/// a TBH instruction. 21830b57cec5SDimitry Andricdef JUMPTABLE_TBH : 21840b57cec5SDimitry AndricPseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 21850b57cec5SDimitry Andric i32imm:$size), NoItinerary, []>; 21860b57cec5SDimitry Andric 21870b57cec5SDimitry Andric 21880b57cec5SDimitry Andric// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE 21890b57cec5SDimitry Andric// from removing one half of the matched pairs. That breaks PEI, which assumes 21900b57cec5SDimitry Andric// these will always be in pairs, and asserts if it finds otherwise. Better way? 21910b57cec5SDimitry Andriclet Defs = [SP], Uses = [SP], hasSideEffects = 1 in { 21920b57cec5SDimitry Andricdef ADJCALLSTACKUP : 21930b57cec5SDimitry AndricPseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, 21940b57cec5SDimitry Andric [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; 21950b57cec5SDimitry Andric 21960b57cec5SDimitry Andricdef ADJCALLSTACKDOWN : 21970b57cec5SDimitry AndricPseudoInst<(outs), (ins i32imm:$amt, i32imm:$amt2, pred:$p), NoItinerary, 21980b57cec5SDimitry Andric [(ARMcallseq_start timm:$amt, timm:$amt2)]>; 21990b57cec5SDimitry Andric} 22000b57cec5SDimitry Andric 22010b57cec5SDimitry Andricdef HINT : AI<(outs), (ins imm0_239:$imm), MiscFrm, NoItinerary, 22020b57cec5SDimitry Andric "hint", "\t$imm", [(int_arm_hint imm0_239:$imm)]>, 22030b57cec5SDimitry Andric Requires<[IsARM, HasV6]> { 22040b57cec5SDimitry Andric bits<8> imm; 22050b57cec5SDimitry Andric let Inst{27-8} = 0b00110010000011110000; 22060b57cec5SDimitry Andric let Inst{7-0} = imm; 22070b57cec5SDimitry Andric let DecoderMethod = "DecodeHINTInstruction"; 22080b57cec5SDimitry Andric} 22090b57cec5SDimitry Andric 22100b57cec5SDimitry Andricdef : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6K]>; 22110b57cec5SDimitry Andricdef : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6K]>; 22120b57cec5SDimitry Andricdef : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6K]>; 22130b57cec5SDimitry Andricdef : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6K]>; 22140b57cec5SDimitry Andricdef : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6K]>; 22150b57cec5SDimitry Andricdef : InstAlias<"sevl$p", (HINT 5, pred:$p)>, Requires<[IsARM, HasV8]>; 22160b57cec5SDimitry Andricdef : InstAlias<"esb$p", (HINT 16, pred:$p)>, Requires<[IsARM, HasRAS]>; 22170b57cec5SDimitry Andricdef : InstAlias<"csdb$p", (HINT 20, pred:$p)>, Requires<[IsARM, HasV6K]>; 22180b57cec5SDimitry Andric 2219bdd1243dSDimitry Andric// Clear BHB instruction 2220bdd1243dSDimitry Andricdef : InstAlias<"clrbhb$p", (HINT 22, pred:$p), 0>, Requires<[IsARM, HasV8]>; 2221bdd1243dSDimitry Andricdef : InstAlias<"clrbhb$p", (HINT 22, pred:$p), 1>, Requires<[IsARM, HasV8, HasCLRBHB]>; 2222bdd1243dSDimitry Andric 22230b57cec5SDimitry Andricdef SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel", 22240b57cec5SDimitry Andric "\t$Rd, $Rn, $Rm", 22250b57cec5SDimitry Andric [(set GPR:$Rd, (int_arm_sel GPR:$Rn, GPR:$Rm))]>, 22260b57cec5SDimitry Andric Requires<[IsARM, HasV6]> { 22270b57cec5SDimitry Andric bits<4> Rd; 22280b57cec5SDimitry Andric bits<4> Rn; 22290b57cec5SDimitry Andric bits<4> Rm; 22300b57cec5SDimitry Andric let Inst{3-0} = Rm; 22310b57cec5SDimitry Andric let Inst{15-12} = Rd; 22320b57cec5SDimitry Andric let Inst{19-16} = Rn; 22330b57cec5SDimitry Andric let Inst{27-20} = 0b01101000; 22340b57cec5SDimitry Andric let Inst{7-4} = 0b1011; 22350b57cec5SDimitry Andric let Inst{11-8} = 0b1111; 22360b57cec5SDimitry Andric let Unpredictable{11-8} = 0b1111; 22370b57cec5SDimitry Andric} 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andric// The 16-bit operand $val can be used by a debugger to store more information 22400b57cec5SDimitry Andric// about the breakpoint. 22410b57cec5SDimitry Andricdef BKPT : AInoP<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary, 22420b57cec5SDimitry Andric "bkpt", "\t$val", []>, Requires<[IsARM]> { 22430b57cec5SDimitry Andric bits<16> val; 22440b57cec5SDimitry Andric let Inst{3-0} = val{3-0}; 22450b57cec5SDimitry Andric let Inst{19-8} = val{15-4}; 22460b57cec5SDimitry Andric let Inst{27-20} = 0b00010010; 22470b57cec5SDimitry Andric let Inst{31-28} = 0xe; // AL 22480b57cec5SDimitry Andric let Inst{7-4} = 0b0111; 22490b57cec5SDimitry Andric} 22500b57cec5SDimitry Andric// default immediate for breakpoint mnemonic 22510b57cec5SDimitry Andricdef : InstAlias<"bkpt", (BKPT 0), 0>, Requires<[IsARM]>; 22520b57cec5SDimitry Andric 22530b57cec5SDimitry Andricdef HLT : AInoP<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary, 22540b57cec5SDimitry Andric "hlt", "\t$val", []>, Requires<[IsARM, HasV8]> { 22550b57cec5SDimitry Andric bits<16> val; 22560b57cec5SDimitry Andric let Inst{3-0} = val{3-0}; 22570b57cec5SDimitry Andric let Inst{19-8} = val{15-4}; 22580b57cec5SDimitry Andric let Inst{27-20} = 0b00010000; 22590b57cec5SDimitry Andric let Inst{31-28} = 0xe; // AL 22600b57cec5SDimitry Andric let Inst{7-4} = 0b0111; 22610b57cec5SDimitry Andric} 22620b57cec5SDimitry Andric 22630b57cec5SDimitry Andric// Change Processor State 22640b57cec5SDimitry Andric// FIXME: We should use InstAlias to handle the optional operands. 22650b57cec5SDimitry Andricclass CPS<dag iops, string asm_ops> 22660b57cec5SDimitry Andric : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops), 22670b57cec5SDimitry Andric []>, Requires<[IsARM]> { 22680b57cec5SDimitry Andric bits<2> imod; 22690b57cec5SDimitry Andric bits<3> iflags; 22700b57cec5SDimitry Andric bits<5> mode; 22710b57cec5SDimitry Andric bit M; 22720b57cec5SDimitry Andric 22730b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 22740b57cec5SDimitry Andric let Inst{27-20} = 0b00010000; 22750b57cec5SDimitry Andric let Inst{19-18} = imod; 22760b57cec5SDimitry Andric let Inst{17} = M; // Enabled if mode is set; 22770b57cec5SDimitry Andric let Inst{16-9} = 0b00000000; 22780b57cec5SDimitry Andric let Inst{8-6} = iflags; 22790b57cec5SDimitry Andric let Inst{5} = 0; 22800b57cec5SDimitry Andric let Inst{4-0} = mode; 22810b57cec5SDimitry Andric} 22820b57cec5SDimitry Andric 22830b57cec5SDimitry Andriclet DecoderMethod = "DecodeCPSInstruction" in { 22840b57cec5SDimitry Andriclet M = 1 in 22850b57cec5SDimitry Andric def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, imm0_31:$mode), 22860b57cec5SDimitry Andric "$imod\t$iflags, $mode">; 22870b57cec5SDimitry Andriclet mode = 0, M = 0 in 22880b57cec5SDimitry Andric def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">; 22890b57cec5SDimitry Andric 22900b57cec5SDimitry Andriclet imod = 0, iflags = 0, M = 1 in 22910b57cec5SDimitry Andric def CPS1p : CPS<(ins imm0_31:$mode), "\t$mode">; 22920b57cec5SDimitry Andric} 22930b57cec5SDimitry Andric 22940b57cec5SDimitry Andric// Preload signals the memory system of possible future data/instruction access. 22950b57cec5SDimitry Andricmulticlass APreLoad<bits<1> read, bits<1> data, string opc> { 22960b57cec5SDimitry Andric 22970b57cec5SDimitry Andric def i12 : AXIM<(outs), (ins addrmode_imm12:$addr), AddrMode_i12, MiscFrm, 22980b57cec5SDimitry Andric IIC_Preload, !strconcat(opc, "\t$addr"), 22990b57cec5SDimitry Andric [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]>, 23000b57cec5SDimitry Andric Sched<[WritePreLd]> { 23010b57cec5SDimitry Andric bits<4> Rt; 23020b57cec5SDimitry Andric bits<17> addr; 23030b57cec5SDimitry Andric let Inst{31-26} = 0b111101; 23040b57cec5SDimitry Andric let Inst{25} = 0; // 0 for immediate form 23050b57cec5SDimitry Andric let Inst{24} = data; 23060b57cec5SDimitry Andric let Inst{23} = addr{12}; // U (add = ('U' == 1)) 23070b57cec5SDimitry Andric let Inst{22} = read; 23080b57cec5SDimitry Andric let Inst{21-20} = 0b01; 23090b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; // Rn 23100b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 23110b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; // imm12 23120b57cec5SDimitry Andric } 23130b57cec5SDimitry Andric 23140b57cec5SDimitry Andric def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload, 23150b57cec5SDimitry Andric !strconcat(opc, "\t$shift"), 23160b57cec5SDimitry Andric [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]>, 23170b57cec5SDimitry Andric Sched<[WritePreLd]> { 23180b57cec5SDimitry Andric bits<17> shift; 23190b57cec5SDimitry Andric let Inst{31-26} = 0b111101; 23200b57cec5SDimitry Andric let Inst{25} = 1; // 1 for register form 23210b57cec5SDimitry Andric let Inst{24} = data; 23220b57cec5SDimitry Andric let Inst{23} = shift{12}; // U (add = ('U' == 1)) 23230b57cec5SDimitry Andric let Inst{22} = read; 23240b57cec5SDimitry Andric let Inst{21-20} = 0b01; 23250b57cec5SDimitry Andric let Inst{19-16} = shift{16-13}; // Rn 23260b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 23270b57cec5SDimitry Andric let Inst{11-0} = shift{11-0}; 23280b57cec5SDimitry Andric let Inst{4} = 0; 23290b57cec5SDimitry Andric } 23300b57cec5SDimitry Andric} 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andricdefm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>; 23330b57cec5SDimitry Andricdefm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>; 23340b57cec5SDimitry Andricdefm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>; 23350b57cec5SDimitry Andric 23360b57cec5SDimitry Andricdef SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary, 23370b57cec5SDimitry Andric "setend\t$end", []>, Requires<[IsARM]>, Deprecated<HasV8Ops> { 23380b57cec5SDimitry Andric bits<1> end; 23390b57cec5SDimitry Andric let Inst{31-10} = 0b1111000100000001000000; 23400b57cec5SDimitry Andric let Inst{9} = end; 23410b57cec5SDimitry Andric let Inst{8-0} = 0; 23420b57cec5SDimitry Andric} 23430b57cec5SDimitry Andric 23440b57cec5SDimitry Andricdef DBG : AI<(outs), (ins imm0_15:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt", 23450b57cec5SDimitry Andric [(int_arm_dbg imm0_15:$opt)]>, Requires<[IsARM, HasV7]> { 23460b57cec5SDimitry Andric bits<4> opt; 23470b57cec5SDimitry Andric let Inst{27-4} = 0b001100100000111100001111; 23480b57cec5SDimitry Andric let Inst{3-0} = opt; 23490b57cec5SDimitry Andric} 23500b57cec5SDimitry Andric 23510b57cec5SDimitry Andric// A8.8.247 UDF - Undefined (Encoding A1) 23520b57cec5SDimitry Andricdef UDF : AInoP<(outs), (ins imm0_65535:$imm16), MiscFrm, NoItinerary, 23530b57cec5SDimitry Andric "udf", "\t$imm16", [(int_arm_undefined imm0_65535:$imm16)]> { 23540b57cec5SDimitry Andric bits<16> imm16; 23550b57cec5SDimitry Andric let Inst{31-28} = 0b1110; // AL 23560b57cec5SDimitry Andric let Inst{27-25} = 0b011; 23570b57cec5SDimitry Andric let Inst{24-20} = 0b11111; 23580b57cec5SDimitry Andric let Inst{19-8} = imm16{15-4}; 23590b57cec5SDimitry Andric let Inst{7-4} = 0b1111; 23600b57cec5SDimitry Andric let Inst{3-0} = imm16{3-0}; 23610b57cec5SDimitry Andric} 23620b57cec5SDimitry Andric 23630b57cec5SDimitry Andric/* 23640b57cec5SDimitry Andric * A5.4 Permanently UNDEFINED instructions. 23650b57cec5SDimitry Andric * 23660b57cec5SDimitry Andric * For most targets use UDF #65006, for which the OS will generate SIGTRAP. 23670b57cec5SDimitry Andric * Other UDF encodings generate SIGILL. 23680b57cec5SDimitry Andric * 23690b57cec5SDimitry Andric * NaCl's OS instead chooses an ARM UDF encoding that's also a UDF in Thumb. 23700b57cec5SDimitry Andric * Encoding A1: 23710b57cec5SDimitry Andric * 1110 0111 1111 iiii iiii iiii 1111 iiii 23720b57cec5SDimitry Andric * Encoding T1: 23730b57cec5SDimitry Andric * 1101 1110 iiii iiii 23740b57cec5SDimitry Andric * It uses the following encoding: 23750b57cec5SDimitry Andric * 1110 0111 1111 1110 1101 1110 1111 0000 23760b57cec5SDimitry Andric * - In ARM: UDF #60896; 23770b57cec5SDimitry Andric * - In Thumb: UDF #254 followed by a branch-to-self. 23780b57cec5SDimitry Andric */ 23790b57cec5SDimitry Andriclet isBarrier = 1, isTerminator = 1 in 23800b57cec5SDimitry Andricdef TRAPNaCl : AXI<(outs), (ins), MiscFrm, NoItinerary, 23810b57cec5SDimitry Andric "trap", [(trap)]>, 23820b57cec5SDimitry Andric Requires<[IsARM,UseNaClTrap]> { 23830b57cec5SDimitry Andric let Inst = 0xe7fedef0; 23840b57cec5SDimitry Andric} 23850b57cec5SDimitry Andriclet isBarrier = 1, isTerminator = 1 in 23860b57cec5SDimitry Andricdef TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary, 23870b57cec5SDimitry Andric "trap", [(trap)]>, 23880b57cec5SDimitry Andric Requires<[IsARM,DontUseNaClTrap]> { 23890b57cec5SDimitry Andric let Inst = 0xe7ffdefe; 23900b57cec5SDimitry Andric} 23910b57cec5SDimitry Andric 23920b57cec5SDimitry Andricdef : Pat<(debugtrap), (BKPT 0)>, Requires<[IsARM, HasV5T]>; 23930b57cec5SDimitry Andricdef : Pat<(debugtrap), (UDF 254)>, Requires<[IsARM, NoV5T]>; 23940b57cec5SDimitry Andric 23950b57cec5SDimitry Andric// Address computation and loads and stores in PIC mode. 23960b57cec5SDimitry Andriclet isNotDuplicable = 1 in { 23970b57cec5SDimitry Andricdef PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p), 23980b57cec5SDimitry Andric 4, IIC_iALUr, 23990b57cec5SDimitry Andric [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>, 24000b57cec5SDimitry Andric Sched<[WriteALU, ReadALU]>; 24010b57cec5SDimitry Andric 24020b57cec5SDimitry Andriclet AddedComplexity = 10 in { 24030b57cec5SDimitry Andricdef PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 24040b57cec5SDimitry Andric 4, IIC_iLoad_r, 24050b57cec5SDimitry Andric [(set GPR:$dst, (load addrmodepc:$addr))]>; 24060b57cec5SDimitry Andric 24070b57cec5SDimitry Andricdef PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 24080b57cec5SDimitry Andric 4, IIC_iLoad_bh_r, 24090b57cec5SDimitry Andric [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>; 24100b57cec5SDimitry Andric 24110b57cec5SDimitry Andricdef PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 24120b57cec5SDimitry Andric 4, IIC_iLoad_bh_r, 24130b57cec5SDimitry Andric [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>; 24140b57cec5SDimitry Andric 24150b57cec5SDimitry Andricdef PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 24160b57cec5SDimitry Andric 4, IIC_iLoad_bh_r, 24170b57cec5SDimitry Andric [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>; 24180b57cec5SDimitry Andric 24190b57cec5SDimitry Andricdef PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 24200b57cec5SDimitry Andric 4, IIC_iLoad_bh_r, 24210b57cec5SDimitry Andric [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>; 24220b57cec5SDimitry Andric} 24230b57cec5SDimitry Andriclet AddedComplexity = 10 in { 24240b57cec5SDimitry Andricdef PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 24250b57cec5SDimitry Andric 4, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>; 24260b57cec5SDimitry Andric 24270b57cec5SDimitry Andricdef PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 24280b57cec5SDimitry Andric 4, IIC_iStore_bh_r, [(truncstorei16 GPR:$src, 24290b57cec5SDimitry Andric addrmodepc:$addr)]>; 24300b57cec5SDimitry Andric 24310b57cec5SDimitry Andricdef PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 24320b57cec5SDimitry Andric 4, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; 24330b57cec5SDimitry Andric} 24340b57cec5SDimitry Andric} // isNotDuplicable = 1 24350b57cec5SDimitry Andric 24360b57cec5SDimitry Andric 24370b57cec5SDimitry Andric// LEApcrel - Load a pc-relative address into a register without offending the 24380b57cec5SDimitry Andric// assembler. 24390b57cec5SDimitry Andriclet hasSideEffects = 0, isReMaterializable = 1 in 24400b57cec5SDimitry Andric// The 'adr' mnemonic encodes differently if the label is before or after 24410b57cec5SDimitry Andric// the instruction. The {24-21} opcode bits are set by the fixup, as we don't 24420b57cec5SDimitry Andric// know until then which form of the instruction will be used. 24430b57cec5SDimitry Andricdef ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label), 24440b57cec5SDimitry Andric MiscFrm, IIC_iALUi, "adr", "\t$Rd, $label", []>, 24450b57cec5SDimitry Andric Sched<[WriteALU, ReadALU]> { 24460b57cec5SDimitry Andric bits<4> Rd; 24470b57cec5SDimitry Andric bits<14> label; 24480b57cec5SDimitry Andric let Inst{27-25} = 0b001; 24490b57cec5SDimitry Andric let Inst{24} = 0; 24500b57cec5SDimitry Andric let Inst{23-22} = label{13-12}; 24510b57cec5SDimitry Andric let Inst{21} = 0; 24520b57cec5SDimitry Andric let Inst{20} = 0; 24530b57cec5SDimitry Andric let Inst{19-16} = 0b1111; 24540b57cec5SDimitry Andric let Inst{15-12} = Rd; 24550b57cec5SDimitry Andric let Inst{11-0} = label{11-0}; 24560b57cec5SDimitry Andric} 24570b57cec5SDimitry Andric 24580b57cec5SDimitry Andriclet hasSideEffects = 1 in { 24590b57cec5SDimitry Andricdef LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p), 24600b57cec5SDimitry Andric 4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>; 24610b57cec5SDimitry Andric 24620b57cec5SDimitry Andricdef LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd), 24630b57cec5SDimitry Andric (ins i32imm:$label, pred:$p), 24640b57cec5SDimitry Andric 4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>; 24650b57cec5SDimitry Andric} 24660b57cec5SDimitry Andric 24670b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 24680b57cec5SDimitry Andric// Control Flow Instructions. 24690b57cec5SDimitry Andric// 24700b57cec5SDimitry Andric 24710b57cec5SDimitry Andriclet isReturn = 1, isTerminator = 1, isBarrier = 1 in { 24720b57cec5SDimitry Andric // ARMV4T and above 24730b57cec5SDimitry Andric def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 247406c3fb27SDimitry Andric "bx", "\tlr", [(ARMretglue)]>, 24750b57cec5SDimitry Andric Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> { 24760b57cec5SDimitry Andric let Inst{27-0} = 0b0001001011111111111100011110; 24770b57cec5SDimitry Andric } 24780b57cec5SDimitry Andric 24790b57cec5SDimitry Andric // ARMV4 only 24800b57cec5SDimitry Andric def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br, 248106c3fb27SDimitry Andric "mov", "\tpc, lr", [(ARMretglue)]>, 24820b57cec5SDimitry Andric Requires<[IsARM, NoV4T]>, Sched<[WriteBr]> { 24830b57cec5SDimitry Andric let Inst{27-0} = 0b0001101000001111000000001110; 24840b57cec5SDimitry Andric } 24850b57cec5SDimitry Andric 24860b57cec5SDimitry Andric // Exception return: N.b. doesn't set CPSR as far as we're concerned (it sets 24870b57cec5SDimitry Andric // the user-space one). 24880b57cec5SDimitry Andric def SUBS_PC_LR : ARMPseudoInst<(outs), (ins i32imm:$offset, pred:$p), 24890b57cec5SDimitry Andric 4, IIC_Br, 249006c3fb27SDimitry Andric [(ARMintretglue imm:$offset)]>; 24910b57cec5SDimitry Andric} 24920b57cec5SDimitry Andric 24930b57cec5SDimitry Andric// Indirect branches 24940b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 24950b57cec5SDimitry Andric // ARMV4T and above 24960b57cec5SDimitry Andric def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", 24970b57cec5SDimitry Andric [(brind GPR:$dst)]>, 24980b57cec5SDimitry Andric Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> { 24990b57cec5SDimitry Andric bits<4> dst; 25000b57cec5SDimitry Andric let Inst{31-4} = 0b1110000100101111111111110001; 25010b57cec5SDimitry Andric let Inst{3-0} = dst; 25020b57cec5SDimitry Andric } 25030b57cec5SDimitry Andric 25040b57cec5SDimitry Andric def BX_pred : AI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, 25050b57cec5SDimitry Andric "bx", "\t$dst", [/* pattern left blank */]>, 25060b57cec5SDimitry Andric Requires<[IsARM, HasV4T]>, Sched<[WriteBr]> { 25070b57cec5SDimitry Andric bits<4> dst; 25080b57cec5SDimitry Andric let Inst{27-4} = 0b000100101111111111110001; 25090b57cec5SDimitry Andric let Inst{3-0} = dst; 25100b57cec5SDimitry Andric } 25110b57cec5SDimitry Andric} 25120b57cec5SDimitry Andric 25130b57cec5SDimitry Andric// SP is marked as a use to prevent stack-pointer assignments that appear 25140b57cec5SDimitry Andric// immediately before calls from potentially appearing dead. 25150b57cec5SDimitry Andriclet isCall = 1, 25160b57cec5SDimitry Andric // FIXME: Do we really need a non-predicated version? If so, it should 25170b57cec5SDimitry Andric // at least be a pseudo instruction expanding to the predicated version 25180b57cec5SDimitry Andric // at MC lowering time. 25190b57cec5SDimitry Andric Defs = [LR], Uses = [SP] in { 25200b57cec5SDimitry Andric def BL : ABXI<0b1011, (outs), (ins arm_bl_target:$func), 25210b57cec5SDimitry Andric IIC_Br, "bl\t$func", 25220b57cec5SDimitry Andric [(ARMcall tglobaladdr:$func)]>, 25230b57cec5SDimitry Andric Requires<[IsARM]>, Sched<[WriteBrL]> { 25240b57cec5SDimitry Andric let Inst{31-28} = 0b1110; 25250b57cec5SDimitry Andric bits<24> func; 25260b57cec5SDimitry Andric let Inst{23-0} = func; 25270b57cec5SDimitry Andric let DecoderMethod = "DecodeBranchImmInstruction"; 25280b57cec5SDimitry Andric } 25290b57cec5SDimitry Andric 25300b57cec5SDimitry Andric def BL_pred : ABI<0b1011, (outs), (ins arm_bl_target:$func), 25310b57cec5SDimitry Andric IIC_Br, "bl", "\t$func", 25320b57cec5SDimitry Andric [(ARMcall_pred tglobaladdr:$func)]>, 25330b57cec5SDimitry Andric Requires<[IsARM]>, Sched<[WriteBrL]> { 25340b57cec5SDimitry Andric bits<24> func; 25350b57cec5SDimitry Andric let Inst{23-0} = func; 25360b57cec5SDimitry Andric let DecoderMethod = "DecodeBranchImmInstruction"; 25370b57cec5SDimitry Andric } 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andric // ARMv5T and above 2540e8d8bef9SDimitry Andric def BLX : AXI<(outs), (ins GPR:$func), BrMiscFrm, IIC_Br, "blx\t$func", []>, 25410b57cec5SDimitry Andric Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> { 25420b57cec5SDimitry Andric bits<4> func; 25430b57cec5SDimitry Andric let Inst{31-4} = 0b1110000100101111111111110011; 25440b57cec5SDimitry Andric let Inst{3-0} = func; 25450b57cec5SDimitry Andric } 2546e8d8bef9SDimitry Andric def BLX_noip : ARMPseudoExpand<(outs), (ins GPRnoip:$func), 2547e8d8bef9SDimitry Andric 4, IIC_Br, [], (BLX GPR:$func)>, 2548e8d8bef9SDimitry Andric Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]>; 2549e8d8bef9SDimitry Andric 25500b57cec5SDimitry Andric 25510b57cec5SDimitry Andric def BLX_pred : AI<(outs), (ins GPR:$func), BrMiscFrm, 2552e8d8bef9SDimitry Andric IIC_Br, "blx", "\t$func", []>, 25530b57cec5SDimitry Andric Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> { 25540b57cec5SDimitry Andric bits<4> func; 25550b57cec5SDimitry Andric let Inst{27-4} = 0b000100101111111111110011; 25560b57cec5SDimitry Andric let Inst{3-0} = func; 25570b57cec5SDimitry Andric } 2558e8d8bef9SDimitry Andric def BLX_pred_noip : ARMPseudoExpand<(outs), (ins GPRnoip:$func), 2559e8d8bef9SDimitry Andric 4, IIC_Br, [], 2560e8d8bef9SDimitry Andric (BLX_pred GPR:$func, (ops 14, zero_reg))>, 2561e8d8bef9SDimitry Andric Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]>; 2562e8d8bef9SDimitry Andric 25630b57cec5SDimitry Andric 25640b57cec5SDimitry Andric // ARMv4T 25650b57cec5SDimitry Andric // Note: Restrict $func to the tGPR regclass to prevent it being in LR. 25660b57cec5SDimitry Andric def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func), 25670b57cec5SDimitry Andric 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 25680b57cec5SDimitry Andric Requires<[IsARM, HasV4T]>, Sched<[WriteBr]>; 25690b57cec5SDimitry Andric 25700b57cec5SDimitry Andric // ARMv4 25710b57cec5SDimitry Andric def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func), 25720b57cec5SDimitry Andric 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 25730b57cec5SDimitry Andric Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; 25740b57cec5SDimitry Andric 25750b57cec5SDimitry Andric // mov lr, pc; b if callee is marked noreturn to avoid confusing the 25760b57cec5SDimitry Andric // return stack predictor. 25770b57cec5SDimitry Andric def BMOVPCB_CALL : ARMPseudoInst<(outs), (ins arm_bl_target:$func), 25780b57cec5SDimitry Andric 8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>, 25790b57cec5SDimitry Andric Requires<[IsARM]>, Sched<[WriteBr]>; 25808bcb0991SDimitry Andric 25818bcb0991SDimitry Andric // push lr before the call 25828bcb0991SDimitry Andric def BL_PUSHLR : ARMPseudoInst<(outs), (ins GPRlr:$ra, arm_bl_target:$func), 25838bcb0991SDimitry Andric 4, IIC_Br, 25848bcb0991SDimitry Andric []>, 25858bcb0991SDimitry Andric Requires<[IsARM]>, Sched<[WriteBr]>; 25860b57cec5SDimitry Andric} 25870b57cec5SDimitry Andric 2588e8d8bef9SDimitry Andricdef : ARMPat<(ARMcall GPR:$func), (BLX $func)>, 2589e8d8bef9SDimitry Andric Requires<[IsARM, HasV5T, NoSLSBLRMitigation]>; 2590e8d8bef9SDimitry Andricdef : ARMPat<(ARMcall GPRnoip:$func), (BLX_noip $func)>, 2591e8d8bef9SDimitry Andric Requires<[IsARM, HasV5T, SLSBLRMitigation]>; 2592e8d8bef9SDimitry Andricdef : ARMPat<(ARMcall_pred GPR:$func), (BLX_pred $func)>, 2593e8d8bef9SDimitry Andric Requires<[IsARM, HasV5T, NoSLSBLRMitigation]>; 2594e8d8bef9SDimitry Andricdef : ARMPat<(ARMcall_pred GPRnoip:$func), (BLX_pred_noip $func)>, 2595e8d8bef9SDimitry Andric Requires<[IsARM, HasV5T, SLSBLRMitigation]>; 2596e8d8bef9SDimitry Andric 2597e8d8bef9SDimitry Andric 25980b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1 in { 25990b57cec5SDimitry Andric // FIXME: should be able to write a pattern for ARMBrcond, but can't use 26000b57cec5SDimitry Andric // a two-value operand where a dag node expects two operands. :( 26010b57cec5SDimitry Andric def Bcc : ABI<0b1010, (outs), (ins arm_br_target:$target), 26020b57cec5SDimitry Andric IIC_Br, "b", "\t$target", 26030b57cec5SDimitry Andric [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>, 26040b57cec5SDimitry Andric Sched<[WriteBr]> { 26050b57cec5SDimitry Andric bits<24> target; 26060b57cec5SDimitry Andric let Inst{23-0} = target; 26070b57cec5SDimitry Andric let DecoderMethod = "DecodeBranchImmInstruction"; 26080b57cec5SDimitry Andric } 26090b57cec5SDimitry Andric 26100b57cec5SDimitry Andric let isBarrier = 1 in { 26110b57cec5SDimitry Andric // B is "predicable" since it's just a Bcc with an 'always' condition. 26120b57cec5SDimitry Andric let isPredicable = 1 in 26130b57cec5SDimitry Andric // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly 26140b57cec5SDimitry Andric // should be sufficient. 26150b57cec5SDimitry Andric // FIXME: Is B really a Barrier? That doesn't seem right. 26160b57cec5SDimitry Andric def B : ARMPseudoExpand<(outs), (ins arm_br_target:$target), 4, IIC_Br, 26170b57cec5SDimitry Andric [(br bb:$target)], (Bcc arm_br_target:$target, 26180b57cec5SDimitry Andric (ops 14, zero_reg))>, 26190b57cec5SDimitry Andric Sched<[WriteBr]>; 26200b57cec5SDimitry Andric 26210b57cec5SDimitry Andric let Size = 4, isNotDuplicable = 1, isIndirectBranch = 1 in { 26220b57cec5SDimitry Andric def BR_JTr : ARMPseudoInst<(outs), 26230b57cec5SDimitry Andric (ins GPR:$target, i32imm:$jt), 26240b57cec5SDimitry Andric 0, IIC_Br, 26250b57cec5SDimitry Andric [(ARMbrjt GPR:$target, tjumptable:$jt)]>, 26260b57cec5SDimitry Andric Sched<[WriteBr]>; 26270b57cec5SDimitry Andric def BR_JTm_i12 : ARMPseudoInst<(outs), 26280b57cec5SDimitry Andric (ins addrmode_imm12:$target, i32imm:$jt), 26290b57cec5SDimitry Andric 0, IIC_Br, 26300b57cec5SDimitry Andric [(ARMbrjt (i32 (load addrmode_imm12:$target)), 26310b57cec5SDimitry Andric tjumptable:$jt)]>, Sched<[WriteBrTbl]>; 26320b57cec5SDimitry Andric def BR_JTm_rs : ARMPseudoInst<(outs), 26330b57cec5SDimitry Andric (ins ldst_so_reg:$target, i32imm:$jt), 26340b57cec5SDimitry Andric 0, IIC_Br, 26350b57cec5SDimitry Andric [(ARMbrjt (i32 (load ldst_so_reg:$target)), 26360b57cec5SDimitry Andric tjumptable:$jt)]>, Sched<[WriteBrTbl]>; 26370b57cec5SDimitry Andric def BR_JTadd : ARMPseudoInst<(outs), 26380b57cec5SDimitry Andric (ins GPR:$target, GPR:$idx, i32imm:$jt), 26390b57cec5SDimitry Andric 0, IIC_Br, 26400b57cec5SDimitry Andric [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt)]>, 26410b57cec5SDimitry Andric Sched<[WriteBrTbl]>; 26420b57cec5SDimitry Andric } // isNotDuplicable = 1, isIndirectBranch = 1 26430b57cec5SDimitry Andric } // isBarrier = 1 26440b57cec5SDimitry Andric 26450b57cec5SDimitry Andric} 26460b57cec5SDimitry Andric 26470b57cec5SDimitry Andric// BLX (immediate) 26480b57cec5SDimitry Andricdef BLXi : AXI<(outs), (ins arm_blx_target:$target), BrMiscFrm, NoItinerary, 26490b57cec5SDimitry Andric "blx\t$target", []>, 26500b57cec5SDimitry Andric Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> { 26510b57cec5SDimitry Andric let Inst{31-25} = 0b1111101; 26520b57cec5SDimitry Andric bits<25> target; 26530b57cec5SDimitry Andric let Inst{23-0} = target{24-1}; 26540b57cec5SDimitry Andric let Inst{24} = target{0}; 26550b57cec5SDimitry Andric let isCall = 1; 26560b57cec5SDimitry Andric} 26570b57cec5SDimitry Andric 26580b57cec5SDimitry Andric// Branch and Exchange Jazelle 26590b57cec5SDimitry Andricdef BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func", 26600b57cec5SDimitry Andric [/* pattern left blank */]>, Sched<[WriteBr]> { 26610b57cec5SDimitry Andric bits<4> func; 26620b57cec5SDimitry Andric let Inst{23-20} = 0b0010; 26630b57cec5SDimitry Andric let Inst{19-8} = 0xfff; 26640b57cec5SDimitry Andric let Inst{7-4} = 0b0010; 26650b57cec5SDimitry Andric let Inst{3-0} = func; 26660b57cec5SDimitry Andric let isBranch = 1; 2667fe6060f1SDimitry Andric let isIndirectBranch = 1; 26680b57cec5SDimitry Andric} 26690b57cec5SDimitry Andric 26700b57cec5SDimitry Andric// Tail calls. 26710b57cec5SDimitry Andric 26720b57cec5SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in { 2673fe6060f1SDimitry Andric def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, i32imm:$SPDiff), IIC_Br, []>, 26740b57cec5SDimitry Andric Sched<[WriteBr]>; 26750b57cec5SDimitry Andric 2676fe6060f1SDimitry Andric def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, i32imm:$SPDiff), IIC_Br, []>, 26770b57cec5SDimitry Andric Sched<[WriteBr]>; 26780b57cec5SDimitry Andric 2679*0fca6ea1SDimitry Andric def TCRETURNrinotr12 : PseudoInst<(outs), (ins tcGPRnotr12:$dst, i32imm:$SPDiff), IIC_Br, []>, 2680*0fca6ea1SDimitry Andric Sched<[WriteBr]>; 2681*0fca6ea1SDimitry Andric 26820b57cec5SDimitry Andric def TAILJMPd : ARMPseudoExpand<(outs), (ins arm_br_target:$dst), 26830b57cec5SDimitry Andric 4, IIC_Br, [], 26840b57cec5SDimitry Andric (Bcc arm_br_target:$dst, (ops 14, zero_reg))>, 26850b57cec5SDimitry Andric Requires<[IsARM]>, Sched<[WriteBr]>; 26860b57cec5SDimitry Andric 26870b57cec5SDimitry Andric def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst), 26880b57cec5SDimitry Andric 4, IIC_Br, [], 26890b57cec5SDimitry Andric (BX GPR:$dst)>, Sched<[WriteBr]>, 26900b57cec5SDimitry Andric Requires<[IsARM, HasV4T]>; 26910b57cec5SDimitry Andric} 26920b57cec5SDimitry Andric 26930b57cec5SDimitry Andric// Secure Monitor Call is a system instruction. 26940b57cec5SDimitry Andricdef SMC : ABI<0b0001, (outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt", 26950b57cec5SDimitry Andric []>, Requires<[IsARM, HasTrustZone]> { 26960b57cec5SDimitry Andric bits<4> opt; 26970b57cec5SDimitry Andric let Inst{23-4} = 0b01100000000000000111; 26980b57cec5SDimitry Andric let Inst{3-0} = opt; 26990b57cec5SDimitry Andric} 27000b57cec5SDimitry Andricdef : MnemonicAlias<"smi", "smc">; 27010b57cec5SDimitry Andric 27020b57cec5SDimitry Andric// Supervisor Call (Software Interrupt) 27030b57cec5SDimitry Andriclet isCall = 1, Uses = [SP] in { 27040b57cec5SDimitry Andricdef SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []>, 27050b57cec5SDimitry Andric Sched<[WriteBr]> { 27060b57cec5SDimitry Andric bits<24> svc; 27070b57cec5SDimitry Andric let Inst{23-0} = svc; 27080b57cec5SDimitry Andric} 27090b57cec5SDimitry Andric} 27100b57cec5SDimitry Andric 27110b57cec5SDimitry Andric// Store Return State 27120b57cec5SDimitry Andricclass SRSI<bit wb, string asm> 27130b57cec5SDimitry Andric : XI<(outs), (ins imm0_31:$mode), AddrModeNone, 4, IndexModeNone, BrFrm, 27140b57cec5SDimitry Andric NoItinerary, asm, "", []> { 27150b57cec5SDimitry Andric bits<5> mode; 27160b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 27170b57cec5SDimitry Andric let Inst{27-25} = 0b100; 27180b57cec5SDimitry Andric let Inst{22} = 1; 27190b57cec5SDimitry Andric let Inst{21} = wb; 27200b57cec5SDimitry Andric let Inst{20} = 0; 27210b57cec5SDimitry Andric let Inst{19-16} = 0b1101; // SP 27220b57cec5SDimitry Andric let Inst{15-5} = 0b00000101000; 27230b57cec5SDimitry Andric let Inst{4-0} = mode; 27240b57cec5SDimitry Andric} 27250b57cec5SDimitry Andric 27260b57cec5SDimitry Andricdef SRSDA : SRSI<0, "srsda\tsp, $mode"> { 27270b57cec5SDimitry Andric let Inst{24-23} = 0; 27280b57cec5SDimitry Andric} 27290b57cec5SDimitry Andricdef SRSDA_UPD : SRSI<1, "srsda\tsp!, $mode"> { 27300b57cec5SDimitry Andric let Inst{24-23} = 0; 27310b57cec5SDimitry Andric} 27320b57cec5SDimitry Andricdef SRSDB : SRSI<0, "srsdb\tsp, $mode"> { 27330b57cec5SDimitry Andric let Inst{24-23} = 0b10; 27340b57cec5SDimitry Andric} 27350b57cec5SDimitry Andricdef SRSDB_UPD : SRSI<1, "srsdb\tsp!, $mode"> { 27360b57cec5SDimitry Andric let Inst{24-23} = 0b10; 27370b57cec5SDimitry Andric} 27380b57cec5SDimitry Andricdef SRSIA : SRSI<0, "srsia\tsp, $mode"> { 27390b57cec5SDimitry Andric let Inst{24-23} = 0b01; 27400b57cec5SDimitry Andric} 27410b57cec5SDimitry Andricdef SRSIA_UPD : SRSI<1, "srsia\tsp!, $mode"> { 27420b57cec5SDimitry Andric let Inst{24-23} = 0b01; 27430b57cec5SDimitry Andric} 27440b57cec5SDimitry Andricdef SRSIB : SRSI<0, "srsib\tsp, $mode"> { 27450b57cec5SDimitry Andric let Inst{24-23} = 0b11; 27460b57cec5SDimitry Andric} 27470b57cec5SDimitry Andricdef SRSIB_UPD : SRSI<1, "srsib\tsp!, $mode"> { 27480b57cec5SDimitry Andric let Inst{24-23} = 0b11; 27490b57cec5SDimitry Andric} 27500b57cec5SDimitry Andric 27510b57cec5SDimitry Andricdef : ARMInstAlias<"srsda $mode", (SRSDA imm0_31:$mode)>; 27520b57cec5SDimitry Andricdef : ARMInstAlias<"srsda $mode!", (SRSDA_UPD imm0_31:$mode)>; 27530b57cec5SDimitry Andric 27540b57cec5SDimitry Andricdef : ARMInstAlias<"srsdb $mode", (SRSDB imm0_31:$mode)>; 27550b57cec5SDimitry Andricdef : ARMInstAlias<"srsdb $mode!", (SRSDB_UPD imm0_31:$mode)>; 27560b57cec5SDimitry Andric 27570b57cec5SDimitry Andricdef : ARMInstAlias<"srsia $mode", (SRSIA imm0_31:$mode)>; 27580b57cec5SDimitry Andricdef : ARMInstAlias<"srsia $mode!", (SRSIA_UPD imm0_31:$mode)>; 27590b57cec5SDimitry Andric 27600b57cec5SDimitry Andricdef : ARMInstAlias<"srsib $mode", (SRSIB imm0_31:$mode)>; 27610b57cec5SDimitry Andricdef : ARMInstAlias<"srsib $mode!", (SRSIB_UPD imm0_31:$mode)>; 27620b57cec5SDimitry Andric 27630b57cec5SDimitry Andric// Return From Exception 27640b57cec5SDimitry Andricclass RFEI<bit wb, string asm> 27650b57cec5SDimitry Andric : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm, 27660b57cec5SDimitry Andric NoItinerary, asm, "", []> { 27670b57cec5SDimitry Andric bits<4> Rn; 27680b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 27690b57cec5SDimitry Andric let Inst{27-25} = 0b100; 27700b57cec5SDimitry Andric let Inst{22} = 0; 27710b57cec5SDimitry Andric let Inst{21} = wb; 27720b57cec5SDimitry Andric let Inst{20} = 1; 27730b57cec5SDimitry Andric let Inst{19-16} = Rn; 27740b57cec5SDimitry Andric let Inst{15-0} = 0xa00; 27750b57cec5SDimitry Andric} 27760b57cec5SDimitry Andric 27770b57cec5SDimitry Andricdef RFEDA : RFEI<0, "rfeda\t$Rn"> { 27780b57cec5SDimitry Andric let Inst{24-23} = 0; 27790b57cec5SDimitry Andric} 27800b57cec5SDimitry Andricdef RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> { 27810b57cec5SDimitry Andric let Inst{24-23} = 0; 27820b57cec5SDimitry Andric} 27830b57cec5SDimitry Andricdef RFEDB : RFEI<0, "rfedb\t$Rn"> { 27840b57cec5SDimitry Andric let Inst{24-23} = 0b10; 27850b57cec5SDimitry Andric} 27860b57cec5SDimitry Andricdef RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> { 27870b57cec5SDimitry Andric let Inst{24-23} = 0b10; 27880b57cec5SDimitry Andric} 27890b57cec5SDimitry Andricdef RFEIA : RFEI<0, "rfeia\t$Rn"> { 27900b57cec5SDimitry Andric let Inst{24-23} = 0b01; 27910b57cec5SDimitry Andric} 27920b57cec5SDimitry Andricdef RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> { 27930b57cec5SDimitry Andric let Inst{24-23} = 0b01; 27940b57cec5SDimitry Andric} 27950b57cec5SDimitry Andricdef RFEIB : RFEI<0, "rfeib\t$Rn"> { 27960b57cec5SDimitry Andric let Inst{24-23} = 0b11; 27970b57cec5SDimitry Andric} 27980b57cec5SDimitry Andricdef RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> { 27990b57cec5SDimitry Andric let Inst{24-23} = 0b11; 28000b57cec5SDimitry Andric} 28010b57cec5SDimitry Andric 28020b57cec5SDimitry Andric// Hypervisor Call is a system instruction 28030b57cec5SDimitry Andriclet isCall = 1 in { 28040b57cec5SDimitry Andricdef HVC : AInoP< (outs), (ins imm0_65535:$imm), BrFrm, NoItinerary, 28050b57cec5SDimitry Andric "hvc", "\t$imm", []>, 28060b57cec5SDimitry Andric Requires<[IsARM, HasVirtualization]> { 28070b57cec5SDimitry Andric bits<16> imm; 28080b57cec5SDimitry Andric 28090b57cec5SDimitry Andric // Even though HVC isn't predicable, it's encoding includes a condition field. 28100b57cec5SDimitry Andric // The instruction is undefined if the condition field is 0xf otherwise it is 28110b57cec5SDimitry Andric // unpredictable if it isn't condition AL (0xe). 28120b57cec5SDimitry Andric let Inst{31-28} = 0b1110; 28130b57cec5SDimitry Andric let Unpredictable{31-28} = 0b1111; 28140b57cec5SDimitry Andric let Inst{27-24} = 0b0001; 28150b57cec5SDimitry Andric let Inst{23-20} = 0b0100; 28160b57cec5SDimitry Andric let Inst{19-8} = imm{15-4}; 28170b57cec5SDimitry Andric let Inst{7-4} = 0b0111; 28180b57cec5SDimitry Andric let Inst{3-0} = imm{3-0}; 28190b57cec5SDimitry Andric} 28200b57cec5SDimitry Andric} 28210b57cec5SDimitry Andric 28220b57cec5SDimitry Andric// Return from exception in Hypervisor mode. 28230b57cec5SDimitry Andriclet isReturn = 1, isBarrier = 1, isTerminator = 1, Defs = [PC] in 28240b57cec5SDimitry Andricdef ERET : ABI<0b0001, (outs), (ins), NoItinerary, "eret", "", []>, 28250b57cec5SDimitry Andric Requires<[IsARM, HasVirtualization]> { 28260b57cec5SDimitry Andric let Inst{23-0} = 0b011000000000000001101110; 28270b57cec5SDimitry Andric} 28280b57cec5SDimitry Andric 28290b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 28300b57cec5SDimitry Andric// Load / Store Instructions. 28310b57cec5SDimitry Andric// 28320b57cec5SDimitry Andric 28330b57cec5SDimitry Andric// Load 28340b57cec5SDimitry Andric 28350b57cec5SDimitry Andric 28360b57cec5SDimitry Andricdefm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si, load>; 28370b57cec5SDimitry Andricdefm LDRB : AI_ldr1nopc<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si, 28380b57cec5SDimitry Andric zextloadi8>; 28390b57cec5SDimitry Andricdefm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si, store>; 28400b57cec5SDimitry Andricdefm STRB : AI_str1nopc<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si, 28410b57cec5SDimitry Andric truncstorei8>; 28420b57cec5SDimitry Andric 28430b57cec5SDimitry Andric// Special LDR for loads from non-pc-relative constpools. 28440b57cec5SDimitry Andriclet canFoldAsLoad = 1, mayLoad = 1, hasSideEffects = 0, 28450b57cec5SDimitry Andric isReMaterializable = 1, isCodeGenOnly = 1 in 28460b57cec5SDimitry Andricdef LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr), 28470b57cec5SDimitry Andric AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", 28480b57cec5SDimitry Andric []> { 28490b57cec5SDimitry Andric bits<4> Rt; 28500b57cec5SDimitry Andric bits<17> addr; 28510b57cec5SDimitry Andric let Inst{23} = addr{12}; // U (add = ('U' == 1)) 28520b57cec5SDimitry Andric let Inst{19-16} = 0b1111; 28530b57cec5SDimitry Andric let Inst{15-12} = Rt; 28540b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; // imm12 28550b57cec5SDimitry Andric} 28560b57cec5SDimitry Andric 28570b57cec5SDimitry Andric// Loads with zero extension 28580b57cec5SDimitry Andricdef LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 28590b57cec5SDimitry Andric IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr", 28600b57cec5SDimitry Andric [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>; 28610b57cec5SDimitry Andric 28620b57cec5SDimitry Andric// Loads with sign extension 28630b57cec5SDimitry Andricdef LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 28640b57cec5SDimitry Andric IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr", 28650b57cec5SDimitry Andric [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>; 28660b57cec5SDimitry Andric 28670b57cec5SDimitry Andricdef LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 28680b57cec5SDimitry Andric IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr", 28690b57cec5SDimitry Andric [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>; 28700b57cec5SDimitry Andric 28710b57cec5SDimitry Andriclet mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in { 28720b57cec5SDimitry Andric // Load doubleword 28730b57cec5SDimitry Andric def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode3:$addr), 28740b57cec5SDimitry Andric LdMiscFrm, IIC_iLoad_d_r, "ldrd", "\t$Rt, $Rt2, $addr", []>, 28750b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]>; 28760b57cec5SDimitry Andric} 28770b57cec5SDimitry Andric 28785ffd83dbSDimitry Andriclet mayLoad = 1, hasSideEffects = 0, hasNoSchedulingInfo = 1 in { 28795ffd83dbSDimitry Andricdef LOADDUAL : ARMPseudoInst<(outs GPRPairOp:$Rt), (ins addrmode3:$addr), 28805ffd83dbSDimitry Andric 64, IIC_iLoad_d_r, []>, 28815ffd83dbSDimitry Andric Requires<[IsARM, HasV5TE]> { 28825ffd83dbSDimitry Andric let AM = AddrMode3; 28835ffd83dbSDimitry Andric} 28845ffd83dbSDimitry Andric} 28855ffd83dbSDimitry Andric 28860b57cec5SDimitry Andricdef LDA : AIldracq<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 28870b57cec5SDimitry Andric NoItinerary, "lda", "\t$Rt, $addr", []>; 28880b57cec5SDimitry Andricdef LDAB : AIldracq<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 28890b57cec5SDimitry Andric NoItinerary, "ldab", "\t$Rt, $addr", []>; 28900b57cec5SDimitry Andricdef LDAH : AIldracq<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 28910b57cec5SDimitry Andric NoItinerary, "ldah", "\t$Rt, $addr", []>; 28920b57cec5SDimitry Andric 28930b57cec5SDimitry Andric// Indexed loads 28940b57cec5SDimitry Andricmulticlass AI2_ldridx<bit isByte, string opc, 28950b57cec5SDimitry Andric InstrItinClass iii, InstrItinClass iir> { 28960b57cec5SDimitry Andric def _PRE_IMM : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), 28970b57cec5SDimitry Andric (ins addrmode_imm12_pre:$addr), IndexModePre, LdFrm, iii, 28980b57cec5SDimitry Andric opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 28990b57cec5SDimitry Andric bits<17> addr; 29000b57cec5SDimitry Andric let Inst{25} = 0; 29010b57cec5SDimitry Andric let Inst{23} = addr{12}; 29020b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; 29030b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; 29040b57cec5SDimitry Andric let DecoderMethod = "DecodeLDRPreImm"; 29050b57cec5SDimitry Andric } 29060b57cec5SDimitry Andric 29070b57cec5SDimitry Andric def _PRE_REG : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), 29080b57cec5SDimitry Andric (ins ldst_so_reg:$addr), IndexModePre, LdFrm, iir, 29090b57cec5SDimitry Andric opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 29100b57cec5SDimitry Andric bits<17> addr; 29110b57cec5SDimitry Andric let Inst{25} = 1; 29120b57cec5SDimitry Andric let Inst{23} = addr{12}; 29130b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; 29140b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; 29150b57cec5SDimitry Andric let Inst{4} = 0; 29160b57cec5SDimitry Andric let DecoderMethod = "DecodeLDRPreReg"; 29170b57cec5SDimitry Andric } 29180b57cec5SDimitry Andric 29190b57cec5SDimitry Andric def _POST_REG : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), 29200b57cec5SDimitry Andric (ins addr_offset_none:$addr, am2offset_reg:$offset), 29210b57cec5SDimitry Andric IndexModePost, LdFrm, iir, 29220b57cec5SDimitry Andric opc, "\t$Rt, $addr, $offset", 29230b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 29240b57cec5SDimitry Andric // {12} isAdd 29250b57cec5SDimitry Andric // {11-0} imm12/Rm 29260b57cec5SDimitry Andric bits<14> offset; 29270b57cec5SDimitry Andric bits<4> addr; 29280b57cec5SDimitry Andric let Inst{25} = 1; 29290b57cec5SDimitry Andric let Inst{23} = offset{12}; 29300b57cec5SDimitry Andric let Inst{19-16} = addr; 29310b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 29320b57cec5SDimitry Andric let Inst{4} = 0; 29330b57cec5SDimitry Andric 29340b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 29350b57cec5SDimitry Andric } 29360b57cec5SDimitry Andric 29370b57cec5SDimitry Andric def _POST_IMM : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), 29380b57cec5SDimitry Andric (ins addr_offset_none:$addr, am2offset_imm:$offset), 29390b57cec5SDimitry Andric IndexModePost, LdFrm, iii, 29400b57cec5SDimitry Andric opc, "\t$Rt, $addr, $offset", 29410b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 29420b57cec5SDimitry Andric // {12} isAdd 29430b57cec5SDimitry Andric // {11-0} imm12/Rm 29440b57cec5SDimitry Andric bits<14> offset; 29450b57cec5SDimitry Andric bits<4> addr; 29460b57cec5SDimitry Andric let Inst{25} = 0; 29470b57cec5SDimitry Andric let Inst{23} = offset{12}; 29480b57cec5SDimitry Andric let Inst{19-16} = addr; 29490b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 29500b57cec5SDimitry Andric 29510b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 29520b57cec5SDimitry Andric } 29530b57cec5SDimitry Andric 29540b57cec5SDimitry Andric} 29550b57cec5SDimitry Andric 29560b57cec5SDimitry Andriclet mayLoad = 1, hasSideEffects = 0 in { 29575ffd83dbSDimitry Andric// FIXME: for LDR_PRE_REG etc. the itinerary should be either IIC_iLoad_ru or 29580b57cec5SDimitry Andric// IIC_iLoad_siu depending on whether it the offset register is shifted. 29590b57cec5SDimitry Andricdefm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_iu, IIC_iLoad_ru>; 29600b57cec5SDimitry Andricdefm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_iu, IIC_iLoad_bh_ru>; 29610b57cec5SDimitry Andric} 29620b57cec5SDimitry Andric 29630b57cec5SDimitry Andricmulticlass AI3_ldridx<bits<4> op, string opc, InstrItinClass itin> { 29640b57cec5SDimitry Andric def _PRE : AI3ldstidx<op, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 29650b57cec5SDimitry Andric (ins addrmode3_pre:$addr), IndexModePre, 29660b57cec5SDimitry Andric LdMiscFrm, itin, 29670b57cec5SDimitry Andric opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 29680b57cec5SDimitry Andric bits<14> addr; 29690b57cec5SDimitry Andric let Inst{23} = addr{8}; // U bit 29700b57cec5SDimitry Andric let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 29710b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 29720b57cec5SDimitry Andric let Inst{11-8} = addr{7-4}; // imm7_4/zero 29730b57cec5SDimitry Andric let Inst{3-0} = addr{3-0}; // imm3_0/Rm 29740b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 29750b57cec5SDimitry Andric } 29760b57cec5SDimitry Andric def _POST : AI3ldstidx<op, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 29770b57cec5SDimitry Andric (ins addr_offset_none:$addr, am3offset:$offset), 29780b57cec5SDimitry Andric IndexModePost, LdMiscFrm, itin, 29790b57cec5SDimitry Andric opc, "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", 29800b57cec5SDimitry Andric []> { 29810b57cec5SDimitry Andric bits<10> offset; 29820b57cec5SDimitry Andric bits<4> addr; 29830b57cec5SDimitry Andric let Inst{23} = offset{8}; // U bit 29840b57cec5SDimitry Andric let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 29850b57cec5SDimitry Andric let Inst{19-16} = addr; 29860b57cec5SDimitry Andric let Inst{11-8} = offset{7-4}; // imm7_4/zero 29870b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; // imm3_0/Rm 29880b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 29890b57cec5SDimitry Andric } 29900b57cec5SDimitry Andric} 29910b57cec5SDimitry Andric 29920b57cec5SDimitry Andriclet mayLoad = 1, hasSideEffects = 0 in { 29930b57cec5SDimitry Andricdefm LDRH : AI3_ldridx<0b1011, "ldrh", IIC_iLoad_bh_ru>; 29940b57cec5SDimitry Andricdefm LDRSH : AI3_ldridx<0b1111, "ldrsh", IIC_iLoad_bh_ru>; 29950b57cec5SDimitry Andricdefm LDRSB : AI3_ldridx<0b1101, "ldrsb", IIC_iLoad_bh_ru>; 29960b57cec5SDimitry Andriclet hasExtraDefRegAllocReq = 1 in { 29970b57cec5SDimitry Andricdef LDRD_PRE : AI3ldstidx<0b1101, 0, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 29980b57cec5SDimitry Andric (ins addrmode3_pre:$addr), IndexModePre, 29990b57cec5SDimitry Andric LdMiscFrm, IIC_iLoad_d_ru, 30000b57cec5SDimitry Andric "ldrd", "\t$Rt, $Rt2, $addr!", 30010b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 30020b57cec5SDimitry Andric bits<14> addr; 30030b57cec5SDimitry Andric let Inst{23} = addr{8}; // U bit 30040b57cec5SDimitry Andric let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 30050b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 30060b57cec5SDimitry Andric let Inst{11-8} = addr{7-4}; // imm7_4/zero 30070b57cec5SDimitry Andric let Inst{3-0} = addr{3-0}; // imm3_0/Rm 30080b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 30090b57cec5SDimitry Andric} 30100b57cec5SDimitry Andricdef LDRD_POST: AI3ldstidx<0b1101, 0, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 30110b57cec5SDimitry Andric (ins addr_offset_none:$addr, am3offset:$offset), 30120b57cec5SDimitry Andric IndexModePost, LdMiscFrm, IIC_iLoad_d_ru, 30130b57cec5SDimitry Andric "ldrd", "\t$Rt, $Rt2, $addr, $offset", 30140b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 30150b57cec5SDimitry Andric bits<10> offset; 30160b57cec5SDimitry Andric bits<4> addr; 30170b57cec5SDimitry Andric let Inst{23} = offset{8}; // U bit 30180b57cec5SDimitry Andric let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 30190b57cec5SDimitry Andric let Inst{19-16} = addr; 30200b57cec5SDimitry Andric let Inst{11-8} = offset{7-4}; // imm7_4/zero 30210b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; // imm3_0/Rm 30220b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 30230b57cec5SDimitry Andric} 30240b57cec5SDimitry Andric} // hasExtraDefRegAllocReq = 1 30250b57cec5SDimitry Andric} // mayLoad = 1, hasSideEffects = 0 30260b57cec5SDimitry Andric 30270b57cec5SDimitry Andric// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT. 30280b57cec5SDimitry Andriclet mayLoad = 1, hasSideEffects = 0 in { 30290b57cec5SDimitry Andricdef LDRT_POST_REG : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), 30300b57cec5SDimitry Andric (ins addr_offset_none:$addr, am2offset_reg:$offset), 30310b57cec5SDimitry Andric IndexModePost, LdFrm, IIC_iLoad_ru, 30320b57cec5SDimitry Andric "ldrt", "\t$Rt, $addr, $offset", 30330b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 30340b57cec5SDimitry Andric // {12} isAdd 30350b57cec5SDimitry Andric // {11-0} imm12/Rm 30360b57cec5SDimitry Andric bits<14> offset; 30370b57cec5SDimitry Andric bits<4> addr; 30380b57cec5SDimitry Andric let Inst{25} = 1; 30390b57cec5SDimitry Andric let Inst{23} = offset{12}; 30400b57cec5SDimitry Andric let Inst{21} = 1; // overwrite 30410b57cec5SDimitry Andric let Inst{19-16} = addr; 30420b57cec5SDimitry Andric let Inst{11-5} = offset{11-5}; 30430b57cec5SDimitry Andric let Inst{4} = 0; 30440b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; 30450b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 30460b57cec5SDimitry Andric} 30470b57cec5SDimitry Andric 30480b57cec5SDimitry Andricdef LDRT_POST_IMM 30490b57cec5SDimitry Andric : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), 30500b57cec5SDimitry Andric (ins addr_offset_none:$addr, am2offset_imm:$offset), 30510b57cec5SDimitry Andric IndexModePost, LdFrm, IIC_iLoad_ru, 30520b57cec5SDimitry Andric "ldrt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> { 30530b57cec5SDimitry Andric // {12} isAdd 30540b57cec5SDimitry Andric // {11-0} imm12/Rm 30550b57cec5SDimitry Andric bits<14> offset; 30560b57cec5SDimitry Andric bits<4> addr; 30570b57cec5SDimitry Andric let Inst{25} = 0; 30580b57cec5SDimitry Andric let Inst{23} = offset{12}; 30590b57cec5SDimitry Andric let Inst{21} = 1; // overwrite 30600b57cec5SDimitry Andric let Inst{19-16} = addr; 30610b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 30620b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 30630b57cec5SDimitry Andric} 30640b57cec5SDimitry Andric 30650b57cec5SDimitry Andricdef LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 30660b57cec5SDimitry Andric (ins addr_offset_none:$addr, am2offset_reg:$offset), 30670b57cec5SDimitry Andric IndexModePost, LdFrm, IIC_iLoad_bh_ru, 30680b57cec5SDimitry Andric "ldrbt", "\t$Rt, $addr, $offset", 30690b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 30700b57cec5SDimitry Andric // {12} isAdd 30710b57cec5SDimitry Andric // {11-0} imm12/Rm 30720b57cec5SDimitry Andric bits<14> offset; 30730b57cec5SDimitry Andric bits<4> addr; 30740b57cec5SDimitry Andric let Inst{25} = 1; 30750b57cec5SDimitry Andric let Inst{23} = offset{12}; 30760b57cec5SDimitry Andric let Inst{21} = 1; // overwrite 30770b57cec5SDimitry Andric let Inst{19-16} = addr; 30780b57cec5SDimitry Andric let Inst{11-5} = offset{11-5}; 30790b57cec5SDimitry Andric let Inst{4} = 0; 30800b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; 30810b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 30820b57cec5SDimitry Andric} 30830b57cec5SDimitry Andric 30840b57cec5SDimitry Andricdef LDRBT_POST_IMM 30850b57cec5SDimitry Andric : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 30860b57cec5SDimitry Andric (ins addr_offset_none:$addr, am2offset_imm:$offset), 30870b57cec5SDimitry Andric IndexModePost, LdFrm, IIC_iLoad_bh_ru, 30880b57cec5SDimitry Andric "ldrbt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> { 30890b57cec5SDimitry Andric // {12} isAdd 30900b57cec5SDimitry Andric // {11-0} imm12/Rm 30910b57cec5SDimitry Andric bits<14> offset; 30920b57cec5SDimitry Andric bits<4> addr; 30930b57cec5SDimitry Andric let Inst{25} = 0; 30940b57cec5SDimitry Andric let Inst{23} = offset{12}; 30950b57cec5SDimitry Andric let Inst{21} = 1; // overwrite 30960b57cec5SDimitry Andric let Inst{19-16} = addr; 30970b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 30980b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 30990b57cec5SDimitry Andric} 31000b57cec5SDimitry Andric 31010b57cec5SDimitry Andricmulticlass AI3ldrT<bits<4> op, string opc> { 31020b57cec5SDimitry Andric def i : AI3ldstidxT<op, 1, (outs GPR:$Rt, GPR:$base_wb), 31030b57cec5SDimitry Andric (ins addr_offset_none:$addr, postidx_imm8:$offset), 31040b57cec5SDimitry Andric IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc, 31050b57cec5SDimitry Andric "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> { 31060b57cec5SDimitry Andric bits<9> offset; 31070b57cec5SDimitry Andric let Inst{23} = offset{8}; 31080b57cec5SDimitry Andric let Inst{22} = 1; 31090b57cec5SDimitry Andric let Inst{11-8} = offset{7-4}; 31100b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; 31110b57cec5SDimitry Andric } 31120b57cec5SDimitry Andric def r : AI3ldstidxT<op, 1, (outs GPRnopc:$Rt, GPRnopc:$base_wb), 31130b57cec5SDimitry Andric (ins addr_offset_none:$addr, postidx_reg:$Rm), 31140b57cec5SDimitry Andric IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, opc, 31150b57cec5SDimitry Andric "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> { 31160b57cec5SDimitry Andric bits<5> Rm; 31170b57cec5SDimitry Andric let Inst{23} = Rm{4}; 31180b57cec5SDimitry Andric let Inst{22} = 0; 31190b57cec5SDimitry Andric let Inst{11-8} = 0; 31200b57cec5SDimitry Andric let Unpredictable{11-8} = 0b1111; 31210b57cec5SDimitry Andric let Inst{3-0} = Rm{3-0}; 31220b57cec5SDimitry Andric let DecoderMethod = "DecodeLDR"; 31230b57cec5SDimitry Andric } 31245ffd83dbSDimitry Andric 31255ffd83dbSDimitry Andric def ii : ARMAsmPseudo<!strconcat(opc, "${p} $Rt, $addr"), 31265ffd83dbSDimitry Andric (ins addr_offset_none:$addr, pred:$p), (outs GPR:$Rt)>; 31270b57cec5SDimitry Andric} 31280b57cec5SDimitry Andric 31290b57cec5SDimitry Andricdefm LDRSBT : AI3ldrT<0b1101, "ldrsbt">; 31300b57cec5SDimitry Andricdefm LDRHT : AI3ldrT<0b1011, "ldrht">; 31310b57cec5SDimitry Andricdefm LDRSHT : AI3ldrT<0b1111, "ldrsht">; 31320b57cec5SDimitry Andric} 31330b57cec5SDimitry Andric 31340b57cec5SDimitry Andricdef LDRT_POST 31350b57cec5SDimitry Andric : ARMAsmPseudo<"ldrt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q), 31360b57cec5SDimitry Andric (outs GPR:$Rt)>; 31370b57cec5SDimitry Andric 31380b57cec5SDimitry Andricdef LDRBT_POST 31390b57cec5SDimitry Andric : ARMAsmPseudo<"ldrbt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q), 31400b57cec5SDimitry Andric (outs GPR:$Rt)>; 31410b57cec5SDimitry Andric 31420b57cec5SDimitry Andric// Pseudo instruction ldr Rt, =immediate 31430b57cec5SDimitry Andricdef LDRConstPool 31440b57cec5SDimitry Andric : ARMAsmPseudo<"ldr${q} $Rt, $immediate", 31450b57cec5SDimitry Andric (ins const_pool_asm_imm:$immediate, pred:$q), 31460b57cec5SDimitry Andric (outs GPR:$Rt)>; 31470b57cec5SDimitry Andric 31480b57cec5SDimitry Andric// Store 31490b57cec5SDimitry Andric 31500b57cec5SDimitry Andric// Stores with truncate 31510b57cec5SDimitry Andricdef STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm, 31520b57cec5SDimitry Andric IIC_iStore_bh_r, "strh", "\t$Rt, $addr", 31530b57cec5SDimitry Andric [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>; 31540b57cec5SDimitry Andric 31550b57cec5SDimitry Andric// Store doubleword 31560b57cec5SDimitry Andriclet mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in { 31570b57cec5SDimitry Andric def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr), 31580b57cec5SDimitry Andric StMiscFrm, IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>, 31590b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]> { 31600b57cec5SDimitry Andric let Inst{21} = 0; 31610b57cec5SDimitry Andric } 31620b57cec5SDimitry Andric} 31630b57cec5SDimitry Andric 31645ffd83dbSDimitry Andriclet mayStore = 1, hasSideEffects = 0, hasNoSchedulingInfo = 1 in { 31655ffd83dbSDimitry Andricdef STOREDUAL : ARMPseudoInst<(outs), (ins GPRPairOp:$Rt, addrmode3:$addr), 31665ffd83dbSDimitry Andric 64, IIC_iStore_d_r, []>, 31675ffd83dbSDimitry Andric Requires<[IsARM, HasV5TE]> { 31685ffd83dbSDimitry Andric let AM = AddrMode3; 31695ffd83dbSDimitry Andric} 31705ffd83dbSDimitry Andric} 31715ffd83dbSDimitry Andric 31720b57cec5SDimitry Andric// Indexed stores 31730b57cec5SDimitry Andricmulticlass AI2_stridx<bit isByte, string opc, 31740b57cec5SDimitry Andric InstrItinClass iii, InstrItinClass iir> { 31750b57cec5SDimitry Andric def _PRE_IMM : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), 31760b57cec5SDimitry Andric (ins GPR:$Rt, addrmode_imm12_pre:$addr), IndexModePre, 31770b57cec5SDimitry Andric StFrm, iii, 31780b57cec5SDimitry Andric opc, "\t$Rt, $addr!", 31790b57cec5SDimitry Andric "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { 31800b57cec5SDimitry Andric bits<17> addr; 31810b57cec5SDimitry Andric let Inst{25} = 0; 31820b57cec5SDimitry Andric let Inst{23} = addr{12}; // U (add = ('U' == 1)) 31830b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; // Rn 31840b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; // imm12 31850b57cec5SDimitry Andric let DecoderMethod = "DecodeSTRPreImm"; 31860b57cec5SDimitry Andric } 31870b57cec5SDimitry Andric 31880b57cec5SDimitry Andric def _PRE_REG : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), 31890b57cec5SDimitry Andric (ins GPR:$Rt, ldst_so_reg:$addr), 31900b57cec5SDimitry Andric IndexModePre, StFrm, iir, 31910b57cec5SDimitry Andric opc, "\t$Rt, $addr!", 31920b57cec5SDimitry Andric "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { 31930b57cec5SDimitry Andric bits<17> addr; 31940b57cec5SDimitry Andric let Inst{25} = 1; 31950b57cec5SDimitry Andric let Inst{23} = addr{12}; // U (add = ('U' == 1)) 31960b57cec5SDimitry Andric let Inst{19-16} = addr{16-13}; // Rn 31970b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; 31980b57cec5SDimitry Andric let Inst{4} = 0; // Inst{4} = 0 31990b57cec5SDimitry Andric let DecoderMethod = "DecodeSTRPreReg"; 32000b57cec5SDimitry Andric } 32010b57cec5SDimitry Andric def _POST_REG : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), 32020b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 32030b57cec5SDimitry Andric IndexModePost, StFrm, iir, 32040b57cec5SDimitry Andric opc, "\t$Rt, $addr, $offset", 32050b57cec5SDimitry Andric "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { 32060b57cec5SDimitry Andric // {12} isAdd 32070b57cec5SDimitry Andric // {11-0} imm12/Rm 32080b57cec5SDimitry Andric bits<14> offset; 32090b57cec5SDimitry Andric bits<4> addr; 32100b57cec5SDimitry Andric let Inst{25} = 1; 32110b57cec5SDimitry Andric let Inst{23} = offset{12}; 32120b57cec5SDimitry Andric let Inst{19-16} = addr; 32130b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 32140b57cec5SDimitry Andric let Inst{4} = 0; 32150b57cec5SDimitry Andric 32160b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 32170b57cec5SDimitry Andric } 32180b57cec5SDimitry Andric 32190b57cec5SDimitry Andric def _POST_IMM : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), 32200b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 32210b57cec5SDimitry Andric IndexModePost, StFrm, iii, 32220b57cec5SDimitry Andric opc, "\t$Rt, $addr, $offset", 32230b57cec5SDimitry Andric "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { 32240b57cec5SDimitry Andric // {12} isAdd 32250b57cec5SDimitry Andric // {11-0} imm12/Rm 32260b57cec5SDimitry Andric bits<14> offset; 32270b57cec5SDimitry Andric bits<4> addr; 32280b57cec5SDimitry Andric let Inst{25} = 0; 32290b57cec5SDimitry Andric let Inst{23} = offset{12}; 32300b57cec5SDimitry Andric let Inst{19-16} = addr; 32310b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 32320b57cec5SDimitry Andric 32330b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 32340b57cec5SDimitry Andric } 32350b57cec5SDimitry Andric} 32360b57cec5SDimitry Andric 32370b57cec5SDimitry Andriclet mayStore = 1, hasSideEffects = 0 in { 32385ffd83dbSDimitry Andric// FIXME: for STR_PRE_REG etc. the itinerary should be either IIC_iStore_ru or 32390b57cec5SDimitry Andric// IIC_iStore_siu depending on whether it the offset register is shifted. 32400b57cec5SDimitry Andricdefm STR : AI2_stridx<0, "str", IIC_iStore_iu, IIC_iStore_ru>; 32410b57cec5SDimitry Andricdefm STRB : AI2_stridx<1, "strb", IIC_iStore_bh_iu, IIC_iStore_bh_ru>; 32420b57cec5SDimitry Andric} 32430b57cec5SDimitry Andric 32440b57cec5SDimitry Andricdef : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr, 32450b57cec5SDimitry Andric am2offset_reg:$offset), 32460b57cec5SDimitry Andric (STR_POST_REG GPR:$Rt, addr_offset_none:$addr, 32470b57cec5SDimitry Andric am2offset_reg:$offset)>; 32480b57cec5SDimitry Andricdef : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr, 32490b57cec5SDimitry Andric am2offset_imm:$offset), 32500b57cec5SDimitry Andric (STR_POST_IMM GPR:$Rt, addr_offset_none:$addr, 32510b57cec5SDimitry Andric am2offset_imm:$offset)>; 32520b57cec5SDimitry Andricdef : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr, 32530b57cec5SDimitry Andric am2offset_reg:$offset), 32540b57cec5SDimitry Andric (STRB_POST_REG GPR:$Rt, addr_offset_none:$addr, 32550b57cec5SDimitry Andric am2offset_reg:$offset)>; 32560b57cec5SDimitry Andricdef : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr, 32570b57cec5SDimitry Andric am2offset_imm:$offset), 32580b57cec5SDimitry Andric (STRB_POST_IMM GPR:$Rt, addr_offset_none:$addr, 32590b57cec5SDimitry Andric am2offset_imm:$offset)>; 32600b57cec5SDimitry Andric 32610b57cec5SDimitry Andric// Pseudo-instructions for pattern matching the pre-indexed stores. We can't 32620b57cec5SDimitry Andric// put the patterns on the instruction definitions directly as ISel wants 32630b57cec5SDimitry Andric// the address base and offset to be separate operands, not a single 32640b57cec5SDimitry Andric// complex operand like we represent the instructions themselves. The 32650b57cec5SDimitry Andric// pseudos map between the two. 32660b57cec5SDimitry Andriclet usesCustomInserter = 1, 32670b57cec5SDimitry Andric Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in { 32680b57cec5SDimitry Andricdef STRi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 32690b57cec5SDimitry Andric (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p), 32700b57cec5SDimitry Andric 4, IIC_iStore_ru, 32710b57cec5SDimitry Andric [(set GPR:$Rn_wb, 32720b57cec5SDimitry Andric (pre_store GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>; 32730b57cec5SDimitry Andricdef STRr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 32740b57cec5SDimitry Andric (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p), 32750b57cec5SDimitry Andric 4, IIC_iStore_ru, 32760b57cec5SDimitry Andric [(set GPR:$Rn_wb, 32770b57cec5SDimitry Andric (pre_store GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; 32780b57cec5SDimitry Andricdef STRBi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 32790b57cec5SDimitry Andric (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p), 32800b57cec5SDimitry Andric 4, IIC_iStore_ru, 32810b57cec5SDimitry Andric [(set GPR:$Rn_wb, 32820b57cec5SDimitry Andric (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>; 32830b57cec5SDimitry Andricdef STRBr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 32840b57cec5SDimitry Andric (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p), 32850b57cec5SDimitry Andric 4, IIC_iStore_ru, 32860b57cec5SDimitry Andric [(set GPR:$Rn_wb, 32870b57cec5SDimitry Andric (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; 32880b57cec5SDimitry Andricdef STRH_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 32890b57cec5SDimitry Andric (ins GPR:$Rt, GPR:$Rn, am3offset:$offset, pred:$p), 32900b57cec5SDimitry Andric 4, IIC_iStore_ru, 32910b57cec5SDimitry Andric [(set GPR:$Rn_wb, 32920b57cec5SDimitry Andric (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>; 32930b57cec5SDimitry Andric} 32940b57cec5SDimitry Andric 32950b57cec5SDimitry Andric 32960b57cec5SDimitry Andric 32970b57cec5SDimitry Andricdef STRH_PRE : AI3ldstidx<0b1011, 0, 1, (outs GPR:$Rn_wb), 32980b57cec5SDimitry Andric (ins GPR:$Rt, addrmode3_pre:$addr), IndexModePre, 32990b57cec5SDimitry Andric StMiscFrm, IIC_iStore_bh_ru, 33000b57cec5SDimitry Andric "strh", "\t$Rt, $addr!", 33010b57cec5SDimitry Andric "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { 33020b57cec5SDimitry Andric bits<14> addr; 33030b57cec5SDimitry Andric let Inst{23} = addr{8}; // U bit 33040b57cec5SDimitry Andric let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 33050b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 33060b57cec5SDimitry Andric let Inst{11-8} = addr{7-4}; // imm7_4/zero 33070b57cec5SDimitry Andric let Inst{3-0} = addr{3-0}; // imm3_0/Rm 33080b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 33090b57cec5SDimitry Andric} 33100b57cec5SDimitry Andric 33110b57cec5SDimitry Andricdef STRH_POST : AI3ldstidx<0b1011, 0, 0, (outs GPR:$Rn_wb), 33120b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, am3offset:$offset), 33130b57cec5SDimitry Andric IndexModePost, StMiscFrm, IIC_iStore_bh_ru, 33140b57cec5SDimitry Andric "strh", "\t$Rt, $addr, $offset", 33150b57cec5SDimitry Andric "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", 33160b57cec5SDimitry Andric [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt, 33170b57cec5SDimitry Andric addr_offset_none:$addr, 33180b57cec5SDimitry Andric am3offset:$offset))]> { 33190b57cec5SDimitry Andric bits<10> offset; 33200b57cec5SDimitry Andric bits<4> addr; 33210b57cec5SDimitry Andric let Inst{23} = offset{8}; // U bit 33220b57cec5SDimitry Andric let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 33230b57cec5SDimitry Andric let Inst{19-16} = addr; 33240b57cec5SDimitry Andric let Inst{11-8} = offset{7-4}; // imm7_4/zero 33250b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; // imm3_0/Rm 33260b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 33270b57cec5SDimitry Andric} 33280b57cec5SDimitry Andric 33290b57cec5SDimitry Andriclet mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in { 33300b57cec5SDimitry Andricdef STRD_PRE : AI3ldstidx<0b1111, 0, 1, (outs GPR:$Rn_wb), 33310b57cec5SDimitry Andric (ins GPR:$Rt, GPR:$Rt2, addrmode3_pre:$addr), 33320b57cec5SDimitry Andric IndexModePre, StMiscFrm, IIC_iStore_d_ru, 33330b57cec5SDimitry Andric "strd", "\t$Rt, $Rt2, $addr!", 33340b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 33350b57cec5SDimitry Andric bits<14> addr; 33360b57cec5SDimitry Andric let Inst{23} = addr{8}; // U bit 33370b57cec5SDimitry Andric let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 33380b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 33390b57cec5SDimitry Andric let Inst{11-8} = addr{7-4}; // imm7_4/zero 33400b57cec5SDimitry Andric let Inst{3-0} = addr{3-0}; // imm3_0/Rm 33410b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 33420b57cec5SDimitry Andric} 33430b57cec5SDimitry Andric 33440b57cec5SDimitry Andricdef STRD_POST: AI3ldstidx<0b1111, 0, 0, (outs GPR:$Rn_wb), 33450b57cec5SDimitry Andric (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr, 33460b57cec5SDimitry Andric am3offset:$offset), 33470b57cec5SDimitry Andric IndexModePost, StMiscFrm, IIC_iStore_d_ru, 33480b57cec5SDimitry Andric "strd", "\t$Rt, $Rt2, $addr, $offset", 33490b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 33500b57cec5SDimitry Andric bits<10> offset; 33510b57cec5SDimitry Andric bits<4> addr; 33520b57cec5SDimitry Andric let Inst{23} = offset{8}; // U bit 33530b57cec5SDimitry Andric let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 33540b57cec5SDimitry Andric let Inst{19-16} = addr; 33550b57cec5SDimitry Andric let Inst{11-8} = offset{7-4}; // imm7_4/zero 33560b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; // imm3_0/Rm 33570b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 33580b57cec5SDimitry Andric} 33590b57cec5SDimitry Andric} // mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 33600b57cec5SDimitry Andric 33610b57cec5SDimitry Andric// STRT, STRBT, and STRHT 33620b57cec5SDimitry Andric 33630b57cec5SDimitry Andricdef STRBT_POST_REG : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), 33640b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 33650b57cec5SDimitry Andric IndexModePost, StFrm, IIC_iStore_bh_ru, 33660b57cec5SDimitry Andric "strbt", "\t$Rt, $addr, $offset", 33670b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 33680b57cec5SDimitry Andric // {12} isAdd 33690b57cec5SDimitry Andric // {11-0} imm12/Rm 33700b57cec5SDimitry Andric bits<14> offset; 33710b57cec5SDimitry Andric bits<4> addr; 33720b57cec5SDimitry Andric let Inst{25} = 1; 33730b57cec5SDimitry Andric let Inst{23} = offset{12}; 33740b57cec5SDimitry Andric let Inst{21} = 1; // overwrite 33750b57cec5SDimitry Andric let Inst{19-16} = addr; 33760b57cec5SDimitry Andric let Inst{11-5} = offset{11-5}; 33770b57cec5SDimitry Andric let Inst{4} = 0; 33780b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; 33790b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 33800b57cec5SDimitry Andric} 33810b57cec5SDimitry Andric 33820b57cec5SDimitry Andricdef STRBT_POST_IMM 33830b57cec5SDimitry Andric : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), 33840b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 33850b57cec5SDimitry Andric IndexModePost, StFrm, IIC_iStore_bh_ru, 33860b57cec5SDimitry Andric "strbt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> { 33870b57cec5SDimitry Andric // {12} isAdd 33880b57cec5SDimitry Andric // {11-0} imm12/Rm 33890b57cec5SDimitry Andric bits<14> offset; 33900b57cec5SDimitry Andric bits<4> addr; 33910b57cec5SDimitry Andric let Inst{25} = 0; 33920b57cec5SDimitry Andric let Inst{23} = offset{12}; 33930b57cec5SDimitry Andric let Inst{21} = 1; // overwrite 33940b57cec5SDimitry Andric let Inst{19-16} = addr; 33950b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 33960b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 33970b57cec5SDimitry Andric} 33980b57cec5SDimitry Andric 33990b57cec5SDimitry Andricdef STRBT_POST 34000b57cec5SDimitry Andric : ARMAsmPseudo<"strbt${q} $Rt, $addr", 34010b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, pred:$q)>; 34020b57cec5SDimitry Andric 34030b57cec5SDimitry Andriclet mayStore = 1, hasSideEffects = 0 in { 34040b57cec5SDimitry Andricdef STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), 34050b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), 34060b57cec5SDimitry Andric IndexModePost, StFrm, IIC_iStore_ru, 34070b57cec5SDimitry Andric "strt", "\t$Rt, $addr, $offset", 34080b57cec5SDimitry Andric "$addr.base = $Rn_wb", []> { 34090b57cec5SDimitry Andric // {12} isAdd 34100b57cec5SDimitry Andric // {11-0} imm12/Rm 34110b57cec5SDimitry Andric bits<14> offset; 34120b57cec5SDimitry Andric bits<4> addr; 34130b57cec5SDimitry Andric let Inst{25} = 1; 34140b57cec5SDimitry Andric let Inst{23} = offset{12}; 34150b57cec5SDimitry Andric let Inst{21} = 1; // overwrite 34160b57cec5SDimitry Andric let Inst{19-16} = addr; 34170b57cec5SDimitry Andric let Inst{11-5} = offset{11-5}; 34180b57cec5SDimitry Andric let Inst{4} = 0; 34190b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; 34200b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 34210b57cec5SDimitry Andric} 34220b57cec5SDimitry Andric 34230b57cec5SDimitry Andricdef STRT_POST_IMM 34240b57cec5SDimitry Andric : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), 34250b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), 34260b57cec5SDimitry Andric IndexModePost, StFrm, IIC_iStore_ru, 34270b57cec5SDimitry Andric "strt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> { 34280b57cec5SDimitry Andric // {12} isAdd 34290b57cec5SDimitry Andric // {11-0} imm12/Rm 34300b57cec5SDimitry Andric bits<14> offset; 34310b57cec5SDimitry Andric bits<4> addr; 34320b57cec5SDimitry Andric let Inst{25} = 0; 34330b57cec5SDimitry Andric let Inst{23} = offset{12}; 34340b57cec5SDimitry Andric let Inst{21} = 1; // overwrite 34350b57cec5SDimitry Andric let Inst{19-16} = addr; 34360b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 34370b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode2IdxInstruction"; 34380b57cec5SDimitry Andric} 34390b57cec5SDimitry Andric} 34400b57cec5SDimitry Andric 34410b57cec5SDimitry Andricdef STRT_POST 34420b57cec5SDimitry Andric : ARMAsmPseudo<"strt${q} $Rt, $addr", 34430b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, pred:$q)>; 34440b57cec5SDimitry Andric 34450b57cec5SDimitry Andricmulticlass AI3strT<bits<4> op, string opc> { 34460b57cec5SDimitry Andric def i : AI3ldstidxT<op, 0, (outs GPR:$base_wb), 34470b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, postidx_imm8:$offset), 34480b57cec5SDimitry Andric IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc, 34490b57cec5SDimitry Andric "\t$Rt, $addr, $offset", "$addr.base = $base_wb", []> { 34500b57cec5SDimitry Andric bits<9> offset; 34510b57cec5SDimitry Andric let Inst{23} = offset{8}; 34520b57cec5SDimitry Andric let Inst{22} = 1; 34530b57cec5SDimitry Andric let Inst{11-8} = offset{7-4}; 34540b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; 34550b57cec5SDimitry Andric } 34560b57cec5SDimitry Andric def r : AI3ldstidxT<op, 0, (outs GPR:$base_wb), 34570b57cec5SDimitry Andric (ins GPR:$Rt, addr_offset_none:$addr, postidx_reg:$Rm), 34580b57cec5SDimitry Andric IndexModePost, StMiscFrm, IIC_iStore_bh_ru, opc, 34590b57cec5SDimitry Andric "\t$Rt, $addr, $Rm", "$addr.base = $base_wb", []> { 34600b57cec5SDimitry Andric bits<5> Rm; 34610b57cec5SDimitry Andric let Inst{23} = Rm{4}; 34620b57cec5SDimitry Andric let Inst{22} = 0; 34630b57cec5SDimitry Andric let Inst{11-8} = 0; 34640b57cec5SDimitry Andric let Inst{3-0} = Rm{3-0}; 34650b57cec5SDimitry Andric } 34660b57cec5SDimitry Andric} 34670b57cec5SDimitry Andric 34680b57cec5SDimitry Andric 34690b57cec5SDimitry Andricdefm STRHT : AI3strT<0b1011, "strht">; 34700b57cec5SDimitry Andric 34710b57cec5SDimitry Andricdef STL : AIstrrel<0b00, (outs), (ins GPR:$Rt, addr_offset_none:$addr), 34720b57cec5SDimitry Andric NoItinerary, "stl", "\t$Rt, $addr", []>; 34730b57cec5SDimitry Andricdef STLB : AIstrrel<0b10, (outs), (ins GPR:$Rt, addr_offset_none:$addr), 34740b57cec5SDimitry Andric NoItinerary, "stlb", "\t$Rt, $addr", []>; 34750b57cec5SDimitry Andricdef STLH : AIstrrel<0b11, (outs), (ins GPR:$Rt, addr_offset_none:$addr), 34760b57cec5SDimitry Andric NoItinerary, "stlh", "\t$Rt, $addr", []>; 34770b57cec5SDimitry Andric 34780b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 34790b57cec5SDimitry Andric// Load / store multiple Instructions. 34800b57cec5SDimitry Andric// 34810b57cec5SDimitry Andric 34820b57cec5SDimitry Andricmulticlass arm_ldst_mult<string asm, string sfx, bit L_bit, bit P_bit, Format f, 34830b57cec5SDimitry Andric InstrItinClass itin, InstrItinClass itin_upd> { 34840b57cec5SDimitry Andric // IA is the default, so no need for an explicit suffix on the 34850b57cec5SDimitry Andric // mnemonic here. Without it is the canonical spelling. 34860b57cec5SDimitry Andric def IA : 34870b57cec5SDimitry Andric AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 34880b57cec5SDimitry Andric IndexModeNone, f, itin, 34890b57cec5SDimitry Andric !strconcat(asm, "${p}\t$Rn, $regs", sfx), "", []> { 34900b57cec5SDimitry Andric let Inst{24-23} = 0b01; // Increment After 34910b57cec5SDimitry Andric let Inst{22} = P_bit; 34920b57cec5SDimitry Andric let Inst{21} = 0; // No writeback 34930b57cec5SDimitry Andric let Inst{20} = L_bit; 34940b57cec5SDimitry Andric } 34950b57cec5SDimitry Andric def IA_UPD : 34960b57cec5SDimitry Andric AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 34970b57cec5SDimitry Andric IndexModeUpd, f, itin_upd, 34980b57cec5SDimitry Andric !strconcat(asm, "${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 34990b57cec5SDimitry Andric let Inst{24-23} = 0b01; // Increment After 35000b57cec5SDimitry Andric let Inst{22} = P_bit; 35010b57cec5SDimitry Andric let Inst{21} = 1; // Writeback 35020b57cec5SDimitry Andric let Inst{20} = L_bit; 35030b57cec5SDimitry Andric 35040b57cec5SDimitry Andric let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 35050b57cec5SDimitry Andric } 35060b57cec5SDimitry Andric def DA : 35070b57cec5SDimitry Andric AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 35080b57cec5SDimitry Andric IndexModeNone, f, itin, 35090b57cec5SDimitry Andric !strconcat(asm, "da${p}\t$Rn, $regs", sfx), "", []> { 35100b57cec5SDimitry Andric let Inst{24-23} = 0b00; // Decrement After 35110b57cec5SDimitry Andric let Inst{22} = P_bit; 35120b57cec5SDimitry Andric let Inst{21} = 0; // No writeback 35130b57cec5SDimitry Andric let Inst{20} = L_bit; 35140b57cec5SDimitry Andric } 35150b57cec5SDimitry Andric def DA_UPD : 35160b57cec5SDimitry Andric AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 35170b57cec5SDimitry Andric IndexModeUpd, f, itin_upd, 35180b57cec5SDimitry Andric !strconcat(asm, "da${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 35190b57cec5SDimitry Andric let Inst{24-23} = 0b00; // Decrement After 35200b57cec5SDimitry Andric let Inst{22} = P_bit; 35210b57cec5SDimitry Andric let Inst{21} = 1; // Writeback 35220b57cec5SDimitry Andric let Inst{20} = L_bit; 35230b57cec5SDimitry Andric 35240b57cec5SDimitry Andric let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 35250b57cec5SDimitry Andric } 35260b57cec5SDimitry Andric def DB : 35270b57cec5SDimitry Andric AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 35280b57cec5SDimitry Andric IndexModeNone, f, itin, 35290b57cec5SDimitry Andric !strconcat(asm, "db${p}\t$Rn, $regs", sfx), "", []> { 35300b57cec5SDimitry Andric let Inst{24-23} = 0b10; // Decrement Before 35310b57cec5SDimitry Andric let Inst{22} = P_bit; 35320b57cec5SDimitry Andric let Inst{21} = 0; // No writeback 35330b57cec5SDimitry Andric let Inst{20} = L_bit; 35340b57cec5SDimitry Andric } 35350b57cec5SDimitry Andric def DB_UPD : 35360b57cec5SDimitry Andric AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 35370b57cec5SDimitry Andric IndexModeUpd, f, itin_upd, 35380b57cec5SDimitry Andric !strconcat(asm, "db${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 35390b57cec5SDimitry Andric let Inst{24-23} = 0b10; // Decrement Before 35400b57cec5SDimitry Andric let Inst{22} = P_bit; 35410b57cec5SDimitry Andric let Inst{21} = 1; // Writeback 35420b57cec5SDimitry Andric let Inst{20} = L_bit; 35430b57cec5SDimitry Andric 35440b57cec5SDimitry Andric let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 35450b57cec5SDimitry Andric } 35460b57cec5SDimitry Andric def IB : 35470b57cec5SDimitry Andric AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 35480b57cec5SDimitry Andric IndexModeNone, f, itin, 35490b57cec5SDimitry Andric !strconcat(asm, "ib${p}\t$Rn, $regs", sfx), "", []> { 35500b57cec5SDimitry Andric let Inst{24-23} = 0b11; // Increment Before 35510b57cec5SDimitry Andric let Inst{22} = P_bit; 35520b57cec5SDimitry Andric let Inst{21} = 0; // No writeback 35530b57cec5SDimitry Andric let Inst{20} = L_bit; 35540b57cec5SDimitry Andric } 35550b57cec5SDimitry Andric def IB_UPD : 35560b57cec5SDimitry Andric AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 35570b57cec5SDimitry Andric IndexModeUpd, f, itin_upd, 35580b57cec5SDimitry Andric !strconcat(asm, "ib${p}\t$Rn!, $regs", sfx), "$Rn = $wb", []> { 35590b57cec5SDimitry Andric let Inst{24-23} = 0b11; // Increment Before 35600b57cec5SDimitry Andric let Inst{22} = P_bit; 35610b57cec5SDimitry Andric let Inst{21} = 1; // Writeback 35620b57cec5SDimitry Andric let Inst{20} = L_bit; 35630b57cec5SDimitry Andric 35640b57cec5SDimitry Andric let DecoderMethod = "DecodeMemMultipleWritebackInstruction"; 35650b57cec5SDimitry Andric } 35660b57cec5SDimitry Andric} 35670b57cec5SDimitry Andric 35680b57cec5SDimitry Andriclet hasSideEffects = 0 in { 35690b57cec5SDimitry Andric 35700b57cec5SDimitry Andriclet mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in 35710b57cec5SDimitry Andricdefm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m, 35720b57cec5SDimitry Andric IIC_iLoad_mu>, ComplexDeprecationPredicate<"ARMLoad">; 35730b57cec5SDimitry Andric 35740b57cec5SDimitry Andriclet mayStore = 1, hasExtraSrcRegAllocReq = 1 in 35750b57cec5SDimitry Andricdefm STM : arm_ldst_mult<"stm", "", 0, 0, LdStMulFrm, IIC_iStore_m, 35760b57cec5SDimitry Andric IIC_iStore_mu>, 35770b57cec5SDimitry Andric ComplexDeprecationPredicate<"ARMStore">; 35780b57cec5SDimitry Andric 35790b57cec5SDimitry Andric} // hasSideEffects 35800b57cec5SDimitry Andric 35810b57cec5SDimitry Andric// FIXME: remove when we have a way to marking a MI with these properties. 35820b57cec5SDimitry Andric// FIXME: Should pc be an implicit operand like PICADD, etc? 35830b57cec5SDimitry Andriclet isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 35840b57cec5SDimitry Andric hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in 35850b57cec5SDimitry Andricdef LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, 35860b57cec5SDimitry Andric reglist:$regs, variable_ops), 35870b57cec5SDimitry Andric 4, IIC_iLoad_mBr, [], 35880b57cec5SDimitry Andric (LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>, 35890b57cec5SDimitry Andric RegConstraint<"$Rn = $wb">; 35900b57cec5SDimitry Andric 35910b57cec5SDimitry Andriclet mayLoad = 1, hasExtraDefRegAllocReq = 1 in 35920b57cec5SDimitry Andricdefm sysLDM : arm_ldst_mult<"ldm", " ^", 1, 1, LdStMulFrm, IIC_iLoad_m, 35930b57cec5SDimitry Andric IIC_iLoad_mu>; 35940b57cec5SDimitry Andric 35950b57cec5SDimitry Andriclet mayStore = 1, hasExtraSrcRegAllocReq = 1 in 35960b57cec5SDimitry Andricdefm sysSTM : arm_ldst_mult<"stm", " ^", 0, 1, LdStMulFrm, IIC_iStore_m, 35970b57cec5SDimitry Andric IIC_iStore_mu>; 35980b57cec5SDimitry Andric 35990b57cec5SDimitry Andric 36000b57cec5SDimitry Andric 36010b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 36020b57cec5SDimitry Andric// Move Instructions. 36030b57cec5SDimitry Andric// 36040b57cec5SDimitry Andric 36050b57cec5SDimitry Andriclet hasSideEffects = 0, isMoveReg = 1 in 36060b57cec5SDimitry Andricdef MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr, 36070b57cec5SDimitry Andric "mov", "\t$Rd, $Rm", []>, UnaryDP, Sched<[WriteALU]> { 36080b57cec5SDimitry Andric bits<4> Rd; 36090b57cec5SDimitry Andric bits<4> Rm; 36100b57cec5SDimitry Andric 36110b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 36120b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 36130b57cec5SDimitry Andric let Inst{25} = 0; 36140b57cec5SDimitry Andric let Inst{3-0} = Rm; 36150b57cec5SDimitry Andric let Inst{15-12} = Rd; 36160b57cec5SDimitry Andric} 36170b57cec5SDimitry Andric 36180b57cec5SDimitry Andric// A version for the smaller set of tail call registers. 36190b57cec5SDimitry Andriclet hasSideEffects = 0 in 36200b57cec5SDimitry Andricdef MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm, 36210b57cec5SDimitry Andric IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP, Sched<[WriteALU]> { 36220b57cec5SDimitry Andric bits<4> Rd; 36230b57cec5SDimitry Andric bits<4> Rm; 36240b57cec5SDimitry Andric 36250b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 36260b57cec5SDimitry Andric let Inst{25} = 0; 36270b57cec5SDimitry Andric let Inst{3-0} = Rm; 36280b57cec5SDimitry Andric let Inst{15-12} = Rd; 36290b57cec5SDimitry Andric} 36300b57cec5SDimitry Andric 36310b57cec5SDimitry Andricdef MOVsr : AsI1<0b1101, (outs GPRnopc:$Rd), (ins shift_so_reg_reg:$src), 36320b57cec5SDimitry Andric DPSoRegRegFrm, IIC_iMOVsr, 36330b57cec5SDimitry Andric "mov", "\t$Rd, $src", 36340b57cec5SDimitry Andric [(set GPRnopc:$Rd, shift_so_reg_reg:$src)]>, UnaryDP, 36350b57cec5SDimitry Andric Sched<[WriteALU]> { 36360b57cec5SDimitry Andric bits<4> Rd; 36370b57cec5SDimitry Andric bits<12> src; 36380b57cec5SDimitry Andric let Inst{15-12} = Rd; 36390b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 36400b57cec5SDimitry Andric let Inst{11-8} = src{11-8}; 36410b57cec5SDimitry Andric let Inst{7} = 0; 36420b57cec5SDimitry Andric let Inst{6-5} = src{6-5}; 36430b57cec5SDimitry Andric let Inst{4} = 1; 36440b57cec5SDimitry Andric let Inst{3-0} = src{3-0}; 36450b57cec5SDimitry Andric let Inst{25} = 0; 36460b57cec5SDimitry Andric} 36470b57cec5SDimitry Andric 36480b57cec5SDimitry Andricdef MOVsi : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_imm:$src), 36490b57cec5SDimitry Andric DPSoRegImmFrm, IIC_iMOVsr, 36500b57cec5SDimitry Andric "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_imm:$src)]>, 36510b57cec5SDimitry Andric UnaryDP, Sched<[WriteALU]> { 36520b57cec5SDimitry Andric bits<4> Rd; 36530b57cec5SDimitry Andric bits<12> src; 36540b57cec5SDimitry Andric let Inst{15-12} = Rd; 36550b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 36560b57cec5SDimitry Andric let Inst{11-5} = src{11-5}; 36570b57cec5SDimitry Andric let Inst{4} = 0; 36580b57cec5SDimitry Andric let Inst{3-0} = src{3-0}; 36590b57cec5SDimitry Andric let Inst{25} = 0; 36600b57cec5SDimitry Andric} 36610b57cec5SDimitry Andric 36620b57cec5SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 36630b57cec5SDimitry Andricdef MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins mod_imm:$imm), DPFrm, IIC_iMOVi, 36640b57cec5SDimitry Andric "mov", "\t$Rd, $imm", [(set GPR:$Rd, mod_imm:$imm)]>, UnaryDP, 36650b57cec5SDimitry Andric Sched<[WriteALU]> { 36660b57cec5SDimitry Andric bits<4> Rd; 36670b57cec5SDimitry Andric bits<12> imm; 36680b57cec5SDimitry Andric let Inst{25} = 1; 36690b57cec5SDimitry Andric let Inst{15-12} = Rd; 36700b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 36710b57cec5SDimitry Andric let Inst{11-0} = imm; 36720b57cec5SDimitry Andric} 36730b57cec5SDimitry Andric 36740b57cec5SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 36750b57cec5SDimitry Andricdef MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins imm0_65535_expr:$imm), 36760b57cec5SDimitry Andric DPFrm, IIC_iMOVi, 36770b57cec5SDimitry Andric "movw", "\t$Rd, $imm", 36780b57cec5SDimitry Andric [(set GPR:$Rd, imm0_65535:$imm)]>, 36790b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]>, UnaryDP, Sched<[WriteALU]> { 36800b57cec5SDimitry Andric bits<4> Rd; 36810b57cec5SDimitry Andric bits<16> imm; 36820b57cec5SDimitry Andric let Inst{15-12} = Rd; 36830b57cec5SDimitry Andric let Inst{11-0} = imm{11-0}; 36840b57cec5SDimitry Andric let Inst{19-16} = imm{15-12}; 36850b57cec5SDimitry Andric let Inst{20} = 0; 36860b57cec5SDimitry Andric let Inst{25} = 1; 36870b57cec5SDimitry Andric let DecoderMethod = "DecodeArmMOVTWInstruction"; 36880b57cec5SDimitry Andric} 36890b57cec5SDimitry Andric 36900b57cec5SDimitry Andricdef : InstAlias<"mov${p} $Rd, $imm", 36910b57cec5SDimitry Andric (MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p), 0>, 36920b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]>; 36930b57cec5SDimitry Andric 36941fd87a68SDimitry Andric// This gets lowered to a single 4-byte instructions 36951fd87a68SDimitry Andriclet Size = 4 in 36960b57cec5SDimitry Andricdef MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 36970b57cec5SDimitry Andric (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>, 36980b57cec5SDimitry Andric Sched<[WriteALU]>; 36990b57cec5SDimitry Andric 37000b57cec5SDimitry Andriclet Constraints = "$src = $Rd" in { 37010b57cec5SDimitry Andricdef MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd), 37020b57cec5SDimitry Andric (ins GPR:$src, imm0_65535_expr:$imm), 37030b57cec5SDimitry Andric DPFrm, IIC_iMOVi, 37040b57cec5SDimitry Andric "movt", "\t$Rd, $imm", 37050b57cec5SDimitry Andric [(set GPRnopc:$Rd, 37060b57cec5SDimitry Andric (or (and GPR:$src, 0xffff), 37070b57cec5SDimitry Andric lo16AllZero:$imm))]>, UnaryDP, 37080b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]>, Sched<[WriteALU]> { 37090b57cec5SDimitry Andric bits<4> Rd; 37100b57cec5SDimitry Andric bits<16> imm; 37110b57cec5SDimitry Andric let Inst{15-12} = Rd; 37120b57cec5SDimitry Andric let Inst{11-0} = imm{11-0}; 37130b57cec5SDimitry Andric let Inst{19-16} = imm{15-12}; 37140b57cec5SDimitry Andric let Inst{20} = 0; 37150b57cec5SDimitry Andric let Inst{25} = 1; 37160b57cec5SDimitry Andric let DecoderMethod = "DecodeArmMOVTWInstruction"; 37170b57cec5SDimitry Andric} 37180b57cec5SDimitry Andric 37191fd87a68SDimitry Andric// This gets lowered to a single 4-byte instructions 37201fd87a68SDimitry Andriclet Size = 4 in 37210b57cec5SDimitry Andricdef MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 37220b57cec5SDimitry Andric (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>, 37230b57cec5SDimitry Andric Sched<[WriteALU]>; 37240b57cec5SDimitry Andric 37250b57cec5SDimitry Andric} // Constraints 37260b57cec5SDimitry Andric 37270b57cec5SDimitry Andricdef : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, 37280b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]>; 37290b57cec5SDimitry Andric 37300b57cec5SDimitry Andriclet Uses = [CPSR] in 37310b57cec5SDimitry Andricdef RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, 37320b57cec5SDimitry Andric [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP, 37330b57cec5SDimitry Andric Requires<[IsARM]>, Sched<[WriteALU]>; 37340b57cec5SDimitry Andric 37350b57cec5SDimitry Andric// These aren't really mov instructions, but we have to define them this way 373606c3fb27SDimitry Andric// due to glue operands. 37370b57cec5SDimitry Andric 37380b57cec5SDimitry Andriclet Defs = [CPSR] in { 373906c3fb27SDimitry Andricdef MOVsrl_glue : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 374006c3fb27SDimitry Andric [(set GPR:$dst, (ARMsrl_glue GPR:$src))]>, UnaryDP, 37410b57cec5SDimitry Andric Sched<[WriteALU]>, Requires<[IsARM]>; 374206c3fb27SDimitry Andricdef MOVsra_glue : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 374306c3fb27SDimitry Andric [(set GPR:$dst, (ARMsra_glue GPR:$src))]>, UnaryDP, 37440b57cec5SDimitry Andric Sched<[WriteALU]>, Requires<[IsARM]>; 37450b57cec5SDimitry Andric} 37460b57cec5SDimitry Andric 37470b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 37480b57cec5SDimitry Andric// Extend Instructions. 37490b57cec5SDimitry Andric// 37500b57cec5SDimitry Andric 37510b57cec5SDimitry Andric// Sign extenders 37520b57cec5SDimitry Andric 37530b57cec5SDimitry Andricdef SXTB : AI_ext_rrot<0b01101010, 37540b57cec5SDimitry Andric "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; 37550b57cec5SDimitry Andricdef SXTH : AI_ext_rrot<0b01101011, 37560b57cec5SDimitry Andric "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; 37570b57cec5SDimitry Andric 37580b57cec5SDimitry Andricdef SXTAB : AI_exta_rrot<0b01101010, 37590b57cec5SDimitry Andric "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 37600b57cec5SDimitry Andricdef SXTAH : AI_exta_rrot<0b01101011, 37610b57cec5SDimitry Andric "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 37620b57cec5SDimitry Andric 37630b57cec5SDimitry Andricdef : ARMV6Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, rot_imm:$rot), i8)), 37640b57cec5SDimitry Andric (SXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; 37650b57cec5SDimitry Andricdef : ARMV6Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, imm8_or_16:$rot), 37660b57cec5SDimitry Andric i16)), 37670b57cec5SDimitry Andric (SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; 37680b57cec5SDimitry Andric 37690b57cec5SDimitry Andricdef SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">; 37700b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_sxtb16 GPR:$Src), 37710b57cec5SDimitry Andric (SXTB16 GPR:$Src, 0)>; 37720b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_sxtb16 (rotr GPR:$Src, rot_imm:$rot)), 37730b57cec5SDimitry Andric (SXTB16 GPR:$Src, rot_imm:$rot)>; 37740b57cec5SDimitry Andric 37750b57cec5SDimitry Andricdef SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">; 37760b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_sxtab16 GPR:$LHS, GPR:$RHS), 37770b57cec5SDimitry Andric (SXTAB16 GPR:$LHS, GPR:$RHS, 0)>; 37780b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_sxtab16 GPR:$LHS, (rotr GPR:$RHS, rot_imm:$rot)), 37790b57cec5SDimitry Andric (SXTAB16 GPR:$LHS, GPR:$RHS, rot_imm:$rot)>; 37800b57cec5SDimitry Andric 37810b57cec5SDimitry Andric// Zero extenders 37820b57cec5SDimitry Andric 37830b57cec5SDimitry Andriclet AddedComplexity = 16 in { 37840b57cec5SDimitry Andricdef UXTB : AI_ext_rrot<0b01101110, 37850b57cec5SDimitry Andric "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; 37860b57cec5SDimitry Andricdef UXTH : AI_ext_rrot<0b01101111, 37870b57cec5SDimitry Andric "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 37880b57cec5SDimitry Andricdef UXTB16 : AI_ext_rrot<0b01101100, 37890b57cec5SDimitry Andric "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 37900b57cec5SDimitry Andric 37910b57cec5SDimitry Andric// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 37920b57cec5SDimitry Andric// The transformation should probably be done as a combiner action 37930b57cec5SDimitry Andric// instead so we can include a check for masking back in the upper 37940b57cec5SDimitry Andric// eight bits of the source into the lower eight bits of the result. 37950b57cec5SDimitry Andric//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), 37960b57cec5SDimitry Andric// (UXTB16r_rot GPR:$Src, 3)>; 37970b57cec5SDimitry Andricdef : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), 37980b57cec5SDimitry Andric (UXTB16 GPR:$Src, 1)>; 37990b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_uxtb16 GPR:$Src), 38000b57cec5SDimitry Andric (UXTB16 GPR:$Src, 0)>; 38010b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_uxtb16 (rotr GPR:$Src, rot_imm:$rot)), 38020b57cec5SDimitry Andric (UXTB16 GPR:$Src, rot_imm:$rot)>; 38030b57cec5SDimitry Andric 38040b57cec5SDimitry Andricdef UXTAB : AI_exta_rrot<0b01101110, "uxtab", 38050b57cec5SDimitry Andric BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 38060b57cec5SDimitry Andricdef UXTAH : AI_exta_rrot<0b01101111, "uxtah", 38070b57cec5SDimitry Andric BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 38080b57cec5SDimitry Andric 38090b57cec5SDimitry Andricdef : ARMV6Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, rot_imm:$rot), 0xFF)), 38100b57cec5SDimitry Andric (UXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; 38110b57cec5SDimitry Andricdef : ARMV6Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot), 0xFFFF)), 38120b57cec5SDimitry Andric (UXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; 38130b57cec5SDimitry Andric} 38140b57cec5SDimitry Andric 38150b57cec5SDimitry Andric// This isn't safe in general, the add is two 16-bit units, not a 32-bit add. 38160b57cec5SDimitry Andricdef UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; 38170b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_uxtab16 GPR:$LHS, GPR:$RHS), 38180b57cec5SDimitry Andric (UXTAB16 GPR:$LHS, GPR:$RHS, 0)>; 38190b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_uxtab16 GPR:$LHS, (rotr GPR:$RHS, rot_imm:$rot)), 38200b57cec5SDimitry Andric (UXTAB16 GPR:$LHS, GPR:$RHS, rot_imm:$rot)>; 38210b57cec5SDimitry Andric 38220b57cec5SDimitry Andric 38230b57cec5SDimitry Andricdef SBFX : I<(outs GPRnopc:$Rd), 38240b57cec5SDimitry Andric (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width), 38250b57cec5SDimitry Andric AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 38260b57cec5SDimitry Andric "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 38270b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]> { 38280b57cec5SDimitry Andric bits<4> Rd; 38290b57cec5SDimitry Andric bits<4> Rn; 38300b57cec5SDimitry Andric bits<5> lsb; 38310b57cec5SDimitry Andric bits<5> width; 38320b57cec5SDimitry Andric let Inst{27-21} = 0b0111101; 38330b57cec5SDimitry Andric let Inst{6-4} = 0b101; 38340b57cec5SDimitry Andric let Inst{20-16} = width; 38350b57cec5SDimitry Andric let Inst{15-12} = Rd; 38360b57cec5SDimitry Andric let Inst{11-7} = lsb; 38370b57cec5SDimitry Andric let Inst{3-0} = Rn; 38380b57cec5SDimitry Andric} 38390b57cec5SDimitry Andric 38400b57cec5SDimitry Andricdef UBFX : I<(outs GPRnopc:$Rd), 38410b57cec5SDimitry Andric (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width), 38420b57cec5SDimitry Andric AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 38430b57cec5SDimitry Andric "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 38440b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]> { 38450b57cec5SDimitry Andric bits<4> Rd; 38460b57cec5SDimitry Andric bits<4> Rn; 38470b57cec5SDimitry Andric bits<5> lsb; 38480b57cec5SDimitry Andric bits<5> width; 38490b57cec5SDimitry Andric let Inst{27-21} = 0b0111111; 38500b57cec5SDimitry Andric let Inst{6-4} = 0b101; 38510b57cec5SDimitry Andric let Inst{20-16} = width; 38520b57cec5SDimitry Andric let Inst{15-12} = Rd; 38530b57cec5SDimitry Andric let Inst{11-7} = lsb; 38540b57cec5SDimitry Andric let Inst{3-0} = Rn; 38550b57cec5SDimitry Andric} 38560b57cec5SDimitry Andric 38570b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 38580b57cec5SDimitry Andric// Arithmetic Instructions. 38590b57cec5SDimitry Andric// 38600b57cec5SDimitry Andric 38610b57cec5SDimitry Andriclet isAdd = 1 in 38620b57cec5SDimitry Andricdefm ADD : AsI1_bin_irs<0b0100, "add", 38630b57cec5SDimitry Andric IIC_iALUi, IIC_iALUr, IIC_iALUsr, add, 1>; 38640b57cec5SDimitry Andricdefm SUB : AsI1_bin_irs<0b0010, "sub", 38650b57cec5SDimitry Andric IIC_iALUi, IIC_iALUr, IIC_iALUsr, sub>; 38660b57cec5SDimitry Andric 38670b57cec5SDimitry Andric// ADD and SUB with 's' bit set. 38680b57cec5SDimitry Andric// 38690b57cec5SDimitry Andric// Currently, ADDS/SUBS are pseudo opcodes that exist only in the 38700b57cec5SDimitry Andric// selection DAG. They are "lowered" to real ADD/SUB opcodes by 38710b57cec5SDimitry Andric// AdjustInstrPostInstrSelection where we determine whether or not to 38720b57cec5SDimitry Andric// set the "s" bit based on CPSR liveness. 38730b57cec5SDimitry Andric// 38740b57cec5SDimitry Andric// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen 38750b57cec5SDimitry Andric// support for an optional CPSR definition that corresponds to the DAG 38760b57cec5SDimitry Andric// node's second value. We can then eliminate the implicit def of CPSR. 38770b57cec5SDimitry Andriclet isAdd = 1 in 38780b57cec5SDimitry Andricdefm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMaddc, 1>; 38790b57cec5SDimitry Andricdefm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMsubc>; 38800b57cec5SDimitry Andric 38810b57cec5SDimitry Andriclet isAdd = 1 in 38820b57cec5SDimitry Andricdefm ADC : AI1_adde_sube_irs<0b0101, "adc", ARMadde, 1>; 38830b57cec5SDimitry Andricdefm SBC : AI1_adde_sube_irs<0b0110, "sbc", ARMsube>; 38840b57cec5SDimitry Andric 38850b57cec5SDimitry Andricdefm RSB : AsI1_rbin_irs<0b0011, "rsb", 38860b57cec5SDimitry Andric IIC_iALUi, IIC_iALUr, IIC_iALUsr, 38870b57cec5SDimitry Andric sub>; 38880b57cec5SDimitry Andric 38890b57cec5SDimitry Andric// FIXME: Eliminate them if we can write def : Pat patterns which defines 38900b57cec5SDimitry Andric// CPSR and the implicit def of CPSR is not needed. 3891349cc55cSDimitry Andricdefm RSBS : AsI1_rbin_s_is<IIC_iALUi, IIC_iALUsr, ARMsubc>; 38920b57cec5SDimitry Andric 38930b57cec5SDimitry Andricdefm RSC : AI1_rsc_irs<0b0111, "rsc", ARMsube>; 38940b57cec5SDimitry Andric 38950b57cec5SDimitry Andric// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 38960b57cec5SDimitry Andric// The assume-no-carry-in form uses the negation of the input since add/sub 38970b57cec5SDimitry Andric// assume opposite meanings of the carry flag (i.e., carry == !borrow). 38980b57cec5SDimitry Andric// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 38990b57cec5SDimitry Andric// details. 39000b57cec5SDimitry Andricdef : ARMPat<(add GPR:$src, mod_imm_neg:$imm), 39010b57cec5SDimitry Andric (SUBri GPR:$src, mod_imm_neg:$imm)>; 39020b57cec5SDimitry Andricdef : ARMPat<(ARMaddc GPR:$src, mod_imm_neg:$imm), 39030b57cec5SDimitry Andric (SUBSri GPR:$src, mod_imm_neg:$imm)>; 39040b57cec5SDimitry Andric 39050b57cec5SDimitry Andricdef : ARMPat<(add GPR:$src, imm0_65535_neg:$imm), 39060b57cec5SDimitry Andric (SUBrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>, 39070b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]>; 39080b57cec5SDimitry Andricdef : ARMPat<(ARMaddc GPR:$src, imm0_65535_neg:$imm), 39090b57cec5SDimitry Andric (SUBSrr GPR:$src, (MOVi16 (imm_neg_XFORM imm:$imm)))>, 39100b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]>; 39110b57cec5SDimitry Andric 39120b57cec5SDimitry Andric// The with-carry-in form matches bitwise not instead of the negation. 39130b57cec5SDimitry Andric// Effectively, the inverse interpretation of the carry flag already accounts 39140b57cec5SDimitry Andric// for part of the negation. 39150b57cec5SDimitry Andricdef : ARMPat<(ARMadde GPR:$src, mod_imm_not:$imm, CPSR), 39160b57cec5SDimitry Andric (SBCri GPR:$src, mod_imm_not:$imm)>; 39170b57cec5SDimitry Andricdef : ARMPat<(ARMadde GPR:$src, imm0_65535_neg:$imm, CPSR), 39180b57cec5SDimitry Andric (SBCrr GPR:$src, (MOVi16 (imm_not_XFORM imm:$imm)))>, 39190b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]>; 39200b57cec5SDimitry Andric 39210b57cec5SDimitry Andric// Note: These are implemented in C++ code, because they have to generate 39220b57cec5SDimitry Andric// ADD/SUBrs instructions, which use a complex pattern that a xform function 39230b57cec5SDimitry Andric// cannot produce. 39240b57cec5SDimitry Andric// (mul X, 2^n+1) -> (add (X << n), X) 39250b57cec5SDimitry Andric// (mul X, 2^n-1) -> (rsb X, (X << n)) 39260b57cec5SDimitry Andric 39270b57cec5SDimitry Andric// ARM Arithmetic Instruction 39280b57cec5SDimitry Andric// GPR:$dst = GPR:$a op GPR:$b 39290b57cec5SDimitry Andricclass AAI<bits<8> op27_20, bits<8> op11_4, string opc, 39300b57cec5SDimitry Andric list<dag> pattern = [], 39310b57cec5SDimitry Andric dag iops = (ins GPRnopc:$Rn, GPRnopc:$Rm), 39320b57cec5SDimitry Andric string asm = "\t$Rd, $Rn, $Rm"> 39330b57cec5SDimitry Andric : AI<(outs GPRnopc:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern>, 39340b57cec5SDimitry Andric Sched<[WriteALU, ReadALU, ReadALU]> { 39350b57cec5SDimitry Andric bits<4> Rn; 39360b57cec5SDimitry Andric bits<4> Rd; 39370b57cec5SDimitry Andric bits<4> Rm; 39380b57cec5SDimitry Andric let Inst{27-20} = op27_20; 39390b57cec5SDimitry Andric let Inst{11-4} = op11_4; 39400b57cec5SDimitry Andric let Inst{19-16} = Rn; 39410b57cec5SDimitry Andric let Inst{15-12} = Rd; 39420b57cec5SDimitry Andric let Inst{3-0} = Rm; 39430b57cec5SDimitry Andric 39440b57cec5SDimitry Andric let Unpredictable{11-8} = 0b1111; 39450b57cec5SDimitry Andric} 39460b57cec5SDimitry Andric 39470b57cec5SDimitry Andric// Wrappers around the AAI class 39480b57cec5SDimitry Andricclass AAIRevOpr<bits<8> op27_20, bits<8> op11_4, string opc, 39490b57cec5SDimitry Andric list<dag> pattern = []> 39500b57cec5SDimitry Andric : AAI<op27_20, op11_4, opc, 39510b57cec5SDimitry Andric pattern, 39520b57cec5SDimitry Andric (ins GPRnopc:$Rm, GPRnopc:$Rn), 39530b57cec5SDimitry Andric "\t$Rd, $Rm, $Rn">; 39540b57cec5SDimitry Andric 39550b57cec5SDimitry Andricclass AAIIntrinsic<bits<8> op27_20, bits<8> op11_4, string opc, 39560b57cec5SDimitry Andric Intrinsic intrinsic> 39570b57cec5SDimitry Andric : AAI<op27_20, op11_4, opc, 39580b57cec5SDimitry Andric [(set GPRnopc:$Rd, (intrinsic GPRnopc:$Rn, GPRnopc:$Rm))]>; 39590b57cec5SDimitry Andric 39600b57cec5SDimitry Andric// Saturating add/subtract 39610b57cec5SDimitry Andriclet hasSideEffects = 1 in { 39620b57cec5SDimitry Andricdef QADD8 : AAIIntrinsic<0b01100010, 0b11111001, "qadd8", int_arm_qadd8>; 39630b57cec5SDimitry Andricdef QADD16 : AAIIntrinsic<0b01100010, 0b11110001, "qadd16", int_arm_qadd16>; 39640b57cec5SDimitry Andricdef QSUB16 : AAIIntrinsic<0b01100010, 0b11110111, "qsub16", int_arm_qsub16>; 39650b57cec5SDimitry Andricdef QSUB8 : AAIIntrinsic<0b01100010, 0b11111111, "qsub8", int_arm_qsub8>; 39660b57cec5SDimitry Andric 39670b57cec5SDimitry Andricdef QDADD : AAIRevOpr<0b00010100, 0b00000101, "qdadd", 39685ffd83dbSDimitry Andric [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, 39695ffd83dbSDimitry Andric (int_arm_qadd GPRnopc:$Rn, GPRnopc:$Rn)))]>; 39700b57cec5SDimitry Andricdef QDSUB : AAIRevOpr<0b00010110, 0b00000101, "qdsub", 39710b57cec5SDimitry Andric [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, 39720b57cec5SDimitry Andric (int_arm_qadd GPRnopc:$Rn, GPRnopc:$Rn)))]>; 39730b57cec5SDimitry Andricdef QSUB : AAIRevOpr<0b00010010, 0b00000101, "qsub", 39740b57cec5SDimitry Andric [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))]>; 39750b57cec5SDimitry Andriclet DecoderMethod = "DecodeQADDInstruction" in 39760b57cec5SDimitry Andric def QADD : AAIRevOpr<0b00010000, 0b00000101, "qadd", 39770b57cec5SDimitry Andric [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))]>; 39780b57cec5SDimitry Andric} 39790b57cec5SDimitry Andric 39808bcb0991SDimitry Andricdef : ARMV5TEPat<(saddsat GPR:$a, GPR:$b), 39818bcb0991SDimitry Andric (QADD GPR:$a, GPR:$b)>; 39828bcb0991SDimitry Andricdef : ARMV5TEPat<(ssubsat GPR:$a, GPR:$b), 39838bcb0991SDimitry Andric (QSUB GPR:$a, GPR:$b)>; 39845ffd83dbSDimitry Andricdef : ARMV5TEPat<(saddsat rGPR:$Rm, (saddsat rGPR:$Rn, rGPR:$Rn)), 39858bcb0991SDimitry Andric (QDADD rGPR:$Rm, rGPR:$Rn)>; 39868bcb0991SDimitry Andricdef : ARMV5TEPat<(ssubsat rGPR:$Rm, (saddsat rGPR:$Rn, rGPR:$Rn)), 39878bcb0991SDimitry Andric (QDSUB rGPR:$Rm, rGPR:$Rn)>; 3988fe6060f1SDimitry Andric 39898bcb0991SDimitry Andricdef : ARMV6Pat<(ARMqadd8b rGPR:$Rm, rGPR:$Rn), 39908bcb0991SDimitry Andric (QADD8 rGPR:$Rm, rGPR:$Rn)>; 39918bcb0991SDimitry Andricdef : ARMV6Pat<(ARMqsub8b rGPR:$Rm, rGPR:$Rn), 39928bcb0991SDimitry Andric (QSUB8 rGPR:$Rm, rGPR:$Rn)>; 39938bcb0991SDimitry Andricdef : ARMV6Pat<(ARMqadd16b rGPR:$Rm, rGPR:$Rn), 39948bcb0991SDimitry Andric (QADD16 rGPR:$Rm, rGPR:$Rn)>; 39958bcb0991SDimitry Andricdef : ARMV6Pat<(ARMqsub16b rGPR:$Rm, rGPR:$Rn), 39968bcb0991SDimitry Andric (QSUB16 rGPR:$Rm, rGPR:$Rn)>; 39978bcb0991SDimitry Andric 39980b57cec5SDimitry Andricdef UQADD16 : AAIIntrinsic<0b01100110, 0b11110001, "uqadd16", int_arm_uqadd16>; 39990b57cec5SDimitry Andricdef UQADD8 : AAIIntrinsic<0b01100110, 0b11111001, "uqadd8", int_arm_uqadd8>; 40000b57cec5SDimitry Andricdef UQSUB16 : AAIIntrinsic<0b01100110, 0b11110111, "uqsub16", int_arm_uqsub16>; 40010b57cec5SDimitry Andricdef UQSUB8 : AAIIntrinsic<0b01100110, 0b11111111, "uqsub8", int_arm_uqsub8>; 40020b57cec5SDimitry Andricdef QASX : AAIIntrinsic<0b01100010, 0b11110011, "qasx", int_arm_qasx>; 40030b57cec5SDimitry Andricdef QSAX : AAIIntrinsic<0b01100010, 0b11110101, "qsax", int_arm_qsax>; 40040b57cec5SDimitry Andricdef UQASX : AAIIntrinsic<0b01100110, 0b11110011, "uqasx", int_arm_uqasx>; 40050b57cec5SDimitry Andricdef UQSAX : AAIIntrinsic<0b01100110, 0b11110101, "uqsax", int_arm_uqsax>; 40060b57cec5SDimitry Andric 4007fe6060f1SDimitry Andricdef : ARMV6Pat<(ARMuqadd8b rGPR:$Rm, rGPR:$Rn), 4008fe6060f1SDimitry Andric (UQADD8 rGPR:$Rm, rGPR:$Rn)>; 4009fe6060f1SDimitry Andricdef : ARMV6Pat<(ARMuqsub8b rGPR:$Rm, rGPR:$Rn), 4010fe6060f1SDimitry Andric (UQSUB8 rGPR:$Rm, rGPR:$Rn)>; 4011fe6060f1SDimitry Andricdef : ARMV6Pat<(ARMuqadd16b rGPR:$Rm, rGPR:$Rn), 4012fe6060f1SDimitry Andric (UQADD16 rGPR:$Rm, rGPR:$Rn)>; 4013fe6060f1SDimitry Andricdef : ARMV6Pat<(ARMuqsub16b rGPR:$Rm, rGPR:$Rn), 4014fe6060f1SDimitry Andric (UQSUB16 rGPR:$Rm, rGPR:$Rn)>; 4015fe6060f1SDimitry Andric 4016fe6060f1SDimitry Andric 40170b57cec5SDimitry Andric// Signed/Unsigned add/subtract 40180b57cec5SDimitry Andric 40190b57cec5SDimitry Andricdef SASX : AAIIntrinsic<0b01100001, 0b11110011, "sasx", int_arm_sasx>; 40200b57cec5SDimitry Andricdef SADD16 : AAIIntrinsic<0b01100001, 0b11110001, "sadd16", int_arm_sadd16>; 40210b57cec5SDimitry Andricdef SADD8 : AAIIntrinsic<0b01100001, 0b11111001, "sadd8", int_arm_sadd8>; 40220b57cec5SDimitry Andricdef SSAX : AAIIntrinsic<0b01100001, 0b11110101, "ssax", int_arm_ssax>; 40230b57cec5SDimitry Andricdef SSUB16 : AAIIntrinsic<0b01100001, 0b11110111, "ssub16", int_arm_ssub16>; 40240b57cec5SDimitry Andricdef SSUB8 : AAIIntrinsic<0b01100001, 0b11111111, "ssub8", int_arm_ssub8>; 40250b57cec5SDimitry Andricdef UASX : AAIIntrinsic<0b01100101, 0b11110011, "uasx", int_arm_uasx>; 40260b57cec5SDimitry Andricdef UADD16 : AAIIntrinsic<0b01100101, 0b11110001, "uadd16", int_arm_uadd16>; 40270b57cec5SDimitry Andricdef UADD8 : AAIIntrinsic<0b01100101, 0b11111001, "uadd8", int_arm_uadd8>; 40280b57cec5SDimitry Andricdef USAX : AAIIntrinsic<0b01100101, 0b11110101, "usax", int_arm_usax>; 40290b57cec5SDimitry Andricdef USUB16 : AAIIntrinsic<0b01100101, 0b11110111, "usub16", int_arm_usub16>; 40300b57cec5SDimitry Andricdef USUB8 : AAIIntrinsic<0b01100101, 0b11111111, "usub8", int_arm_usub8>; 40310b57cec5SDimitry Andric 40320b57cec5SDimitry Andric// Signed/Unsigned halving add/subtract 40330b57cec5SDimitry Andric 40340b57cec5SDimitry Andricdef SHASX : AAIIntrinsic<0b01100011, 0b11110011, "shasx", int_arm_shasx>; 40350b57cec5SDimitry Andricdef SHADD16 : AAIIntrinsic<0b01100011, 0b11110001, "shadd16", int_arm_shadd16>; 40360b57cec5SDimitry Andricdef SHADD8 : AAIIntrinsic<0b01100011, 0b11111001, "shadd8", int_arm_shadd8>; 40370b57cec5SDimitry Andricdef SHSAX : AAIIntrinsic<0b01100011, 0b11110101, "shsax", int_arm_shsax>; 40380b57cec5SDimitry Andricdef SHSUB16 : AAIIntrinsic<0b01100011, 0b11110111, "shsub16", int_arm_shsub16>; 40390b57cec5SDimitry Andricdef SHSUB8 : AAIIntrinsic<0b01100011, 0b11111111, "shsub8", int_arm_shsub8>; 40400b57cec5SDimitry Andricdef UHASX : AAIIntrinsic<0b01100111, 0b11110011, "uhasx", int_arm_uhasx>; 40410b57cec5SDimitry Andricdef UHADD16 : AAIIntrinsic<0b01100111, 0b11110001, "uhadd16", int_arm_uhadd16>; 40420b57cec5SDimitry Andricdef UHADD8 : AAIIntrinsic<0b01100111, 0b11111001, "uhadd8", int_arm_uhadd8>; 40430b57cec5SDimitry Andricdef UHSAX : AAIIntrinsic<0b01100111, 0b11110101, "uhsax", int_arm_uhsax>; 40440b57cec5SDimitry Andricdef UHSUB16 : AAIIntrinsic<0b01100111, 0b11110111, "uhsub16", int_arm_uhsub16>; 40450b57cec5SDimitry Andricdef UHSUB8 : AAIIntrinsic<0b01100111, 0b11111111, "uhsub8", int_arm_uhsub8>; 40460b57cec5SDimitry Andric 40470b57cec5SDimitry Andric// Unsigned Sum of Absolute Differences [and Accumulate]. 40480b57cec5SDimitry Andric 40490b57cec5SDimitry Andricdef USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 40500b57cec5SDimitry Andric MulFrm /* for convenience */, NoItinerary, "usad8", 40510b57cec5SDimitry Andric "\t$Rd, $Rn, $Rm", 40520b57cec5SDimitry Andric [(set GPR:$Rd, (int_arm_usad8 GPR:$Rn, GPR:$Rm))]>, 40530b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, Sched<[WriteALU, ReadALU, ReadALU]> { 40540b57cec5SDimitry Andric bits<4> Rd; 40550b57cec5SDimitry Andric bits<4> Rn; 40560b57cec5SDimitry Andric bits<4> Rm; 40570b57cec5SDimitry Andric let Inst{27-20} = 0b01111000; 40580b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 40590b57cec5SDimitry Andric let Inst{7-4} = 0b0001; 40600b57cec5SDimitry Andric let Inst{19-16} = Rd; 40610b57cec5SDimitry Andric let Inst{11-8} = Rm; 40620b57cec5SDimitry Andric let Inst{3-0} = Rn; 40630b57cec5SDimitry Andric} 40640b57cec5SDimitry Andricdef USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 40650b57cec5SDimitry Andric MulFrm /* for convenience */, NoItinerary, "usada8", 40660b57cec5SDimitry Andric "\t$Rd, $Rn, $Rm, $Ra", 40670b57cec5SDimitry Andric [(set GPR:$Rd, (int_arm_usada8 GPR:$Rn, GPR:$Rm, GPR:$Ra))]>, 40680b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, Sched<[WriteALU, ReadALU, ReadALU]>{ 40690b57cec5SDimitry Andric bits<4> Rd; 40700b57cec5SDimitry Andric bits<4> Rn; 40710b57cec5SDimitry Andric bits<4> Rm; 40720b57cec5SDimitry Andric bits<4> Ra; 40730b57cec5SDimitry Andric let Inst{27-20} = 0b01111000; 40740b57cec5SDimitry Andric let Inst{7-4} = 0b0001; 40750b57cec5SDimitry Andric let Inst{19-16} = Rd; 40760b57cec5SDimitry Andric let Inst{15-12} = Ra; 40770b57cec5SDimitry Andric let Inst{11-8} = Rm; 40780b57cec5SDimitry Andric let Inst{3-0} = Rn; 40790b57cec5SDimitry Andric} 40800b57cec5SDimitry Andric 40810b57cec5SDimitry Andric// Signed/Unsigned saturate 40820b57cec5SDimitry Andricdef SSAT : AI<(outs GPRnopc:$Rd), 40830b57cec5SDimitry Andric (ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), 40840b57cec5SDimitry Andric SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []>, 40850b57cec5SDimitry Andric Requires<[IsARM,HasV6]>{ 40860b57cec5SDimitry Andric bits<4> Rd; 40870b57cec5SDimitry Andric bits<5> sat_imm; 40880b57cec5SDimitry Andric bits<4> Rn; 40890b57cec5SDimitry Andric bits<8> sh; 40900b57cec5SDimitry Andric let Inst{27-21} = 0b0110101; 40910b57cec5SDimitry Andric let Inst{5-4} = 0b01; 40920b57cec5SDimitry Andric let Inst{20-16} = sat_imm; 40930b57cec5SDimitry Andric let Inst{15-12} = Rd; 40940b57cec5SDimitry Andric let Inst{11-7} = sh{4-0}; 40950b57cec5SDimitry Andric let Inst{6} = sh{5}; 40960b57cec5SDimitry Andric let Inst{3-0} = Rn; 40970b57cec5SDimitry Andric} 40980b57cec5SDimitry Andric 40990b57cec5SDimitry Andricdef SSAT16 : AI<(outs GPRnopc:$Rd), 41000b57cec5SDimitry Andric (ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm, 41010b57cec5SDimitry Andric NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []>, 41020b57cec5SDimitry Andric Requires<[IsARM,HasV6]>{ 41030b57cec5SDimitry Andric bits<4> Rd; 41040b57cec5SDimitry Andric bits<4> sat_imm; 41050b57cec5SDimitry Andric bits<4> Rn; 41060b57cec5SDimitry Andric let Inst{27-20} = 0b01101010; 41070b57cec5SDimitry Andric let Inst{11-4} = 0b11110011; 41080b57cec5SDimitry Andric let Inst{15-12} = Rd; 41090b57cec5SDimitry Andric let Inst{19-16} = sat_imm; 41100b57cec5SDimitry Andric let Inst{3-0} = Rn; 41110b57cec5SDimitry Andric} 41120b57cec5SDimitry Andric 41130b57cec5SDimitry Andricdef USAT : AI<(outs GPRnopc:$Rd), 41140b57cec5SDimitry Andric (ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), 41150b57cec5SDimitry Andric SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []>, 41160b57cec5SDimitry Andric Requires<[IsARM,HasV6]> { 41170b57cec5SDimitry Andric bits<4> Rd; 41180b57cec5SDimitry Andric bits<5> sat_imm; 41190b57cec5SDimitry Andric bits<4> Rn; 41200b57cec5SDimitry Andric bits<8> sh; 41210b57cec5SDimitry Andric let Inst{27-21} = 0b0110111; 41220b57cec5SDimitry Andric let Inst{5-4} = 0b01; 41230b57cec5SDimitry Andric let Inst{15-12} = Rd; 41240b57cec5SDimitry Andric let Inst{11-7} = sh{4-0}; 41250b57cec5SDimitry Andric let Inst{6} = sh{5}; 41260b57cec5SDimitry Andric let Inst{20-16} = sat_imm; 41270b57cec5SDimitry Andric let Inst{3-0} = Rn; 41280b57cec5SDimitry Andric} 41290b57cec5SDimitry Andric 41300b57cec5SDimitry Andricdef USAT16 : AI<(outs GPRnopc:$Rd), 41310b57cec5SDimitry Andric (ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm, 41320b57cec5SDimitry Andric NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []>, 41330b57cec5SDimitry Andric Requires<[IsARM,HasV6]>{ 41340b57cec5SDimitry Andric bits<4> Rd; 41350b57cec5SDimitry Andric bits<4> sat_imm; 41360b57cec5SDimitry Andric bits<4> Rn; 41370b57cec5SDimitry Andric let Inst{27-20} = 0b01101110; 41380b57cec5SDimitry Andric let Inst{11-4} = 0b11110011; 41390b57cec5SDimitry Andric let Inst{15-12} = Rd; 41400b57cec5SDimitry Andric let Inst{19-16} = sat_imm; 41410b57cec5SDimitry Andric let Inst{3-0} = Rn; 41420b57cec5SDimitry Andric} 41430b57cec5SDimitry Andric 41440b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm1_32:$pos), 41450b57cec5SDimitry Andric (SSAT imm1_32:$pos, GPRnopc:$a, 0)>; 41460b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm0_31:$pos), 41470b57cec5SDimitry Andric (USAT imm0_31:$pos, GPRnopc:$a, 0)>; 4148e8d8bef9SDimitry Andricdef : ARMPat<(ARMssat GPRnopc:$Rn, imm0_31:$imm), 41490b57cec5SDimitry Andric (SSAT imm0_31:$imm, GPRnopc:$Rn, 0)>; 4150e8d8bef9SDimitry Andricdef : ARMPat<(ARMusat GPRnopc:$Rn, imm0_31:$imm), 41510b57cec5SDimitry Andric (USAT imm0_31:$imm, GPRnopc:$Rn, 0)>; 41520b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_ssat16 GPRnopc:$a, imm1_16:$pos), 41530b57cec5SDimitry Andric (SSAT16 imm1_16:$pos, GPRnopc:$a)>; 41540b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_usat16 GPRnopc:$a, imm0_15:$pos), 41550b57cec5SDimitry Andric (USAT16 imm0_15:$pos, GPRnopc:$a)>; 4156e8d8bef9SDimitry Andricdef : ARMV6Pat<(int_arm_ssat (shl GPRnopc:$a, imm0_31:$shft), imm1_32:$pos), 4157e8d8bef9SDimitry Andric (SSAT imm1_32:$pos, GPRnopc:$a, imm0_31:$shft)>; 4158e8d8bef9SDimitry Andricdef : ARMV6Pat<(int_arm_ssat (sra GPRnopc:$a, asr_imm:$shft), imm1_32:$pos), 4159e8d8bef9SDimitry Andric (SSAT imm1_32:$pos, GPRnopc:$a, asr_imm:$shft)>; 4160e8d8bef9SDimitry Andricdef : ARMV6Pat<(int_arm_usat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos), 4161e8d8bef9SDimitry Andric (USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>; 4162e8d8bef9SDimitry Andricdef : ARMV6Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos), 4163e8d8bef9SDimitry Andric (USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>; 4164e8d8bef9SDimitry Andricdef : ARMPat<(ARMssat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos), 4165e8d8bef9SDimitry Andric (SSAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>; 4166e8d8bef9SDimitry Andricdef : ARMPat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos), 4167e8d8bef9SDimitry Andric (SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>; 4168e8d8bef9SDimitry Andricdef : ARMPat<(ARMusat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos), 4169e8d8bef9SDimitry Andric (USAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>; 4170e8d8bef9SDimitry Andricdef : ARMPat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos), 4171e8d8bef9SDimitry Andric (USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>; 4172e8d8bef9SDimitry Andric 41730b57cec5SDimitry Andric 41740b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 41750b57cec5SDimitry Andric// Bitwise Instructions. 41760b57cec5SDimitry Andric// 41770b57cec5SDimitry Andric 41780b57cec5SDimitry Andricdefm AND : AsI1_bin_irs<0b0000, "and", 41790b57cec5SDimitry Andric IIC_iBITi, IIC_iBITr, IIC_iBITsr, and, 1>; 41800b57cec5SDimitry Andricdefm ORR : AsI1_bin_irs<0b1100, "orr", 41810b57cec5SDimitry Andric IIC_iBITi, IIC_iBITr, IIC_iBITsr, or, 1>; 41820b57cec5SDimitry Andricdefm EOR : AsI1_bin_irs<0b0001, "eor", 41830b57cec5SDimitry Andric IIC_iBITi, IIC_iBITr, IIC_iBITsr, xor, 1>; 41840b57cec5SDimitry Andricdefm BIC : AsI1_bin_irs<0b1110, "bic", 41850b57cec5SDimitry Andric IIC_iBITi, IIC_iBITr, IIC_iBITsr, 41860b57cec5SDimitry Andric BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 41870b57cec5SDimitry Andric 41880b57cec5SDimitry Andric// FIXME: bf_inv_mask_imm should be two operands, the lsb and the msb, just 41890b57cec5SDimitry Andric// like in the actual instruction encoding. The complexity of mapping the mask 41900b57cec5SDimitry Andric// to the lsb/msb pair should be handled by ISel, not encapsulated in the 41910b57cec5SDimitry Andric// instruction description. 41920b57cec5SDimitry Andricdef BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm), 41930b57cec5SDimitry Andric AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 41940b57cec5SDimitry Andric "bfc", "\t$Rd, $imm", "$src = $Rd", 41950b57cec5SDimitry Andric [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>, 41960b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]> { 41970b57cec5SDimitry Andric bits<4> Rd; 41980b57cec5SDimitry Andric bits<10> imm; 41990b57cec5SDimitry Andric let Inst{27-21} = 0b0111110; 42000b57cec5SDimitry Andric let Inst{6-0} = 0b0011111; 42010b57cec5SDimitry Andric let Inst{15-12} = Rd; 42020b57cec5SDimitry Andric let Inst{11-7} = imm{4-0}; // lsb 42030b57cec5SDimitry Andric let Inst{20-16} = imm{9-5}; // msb 42040b57cec5SDimitry Andric} 42050b57cec5SDimitry Andric 42060b57cec5SDimitry Andric// A8.6.18 BFI - Bitfield insert (Encoding A1) 42070b57cec5SDimitry Andricdef BFI:I<(outs GPRnopc:$Rd), (ins GPRnopc:$src, GPR:$Rn, bf_inv_mask_imm:$imm), 42080b57cec5SDimitry Andric AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, 42090b57cec5SDimitry Andric "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd", 42100b57cec5SDimitry Andric [(set GPRnopc:$Rd, (ARMbfi GPRnopc:$src, GPR:$Rn, 42110b57cec5SDimitry Andric bf_inv_mask_imm:$imm))]>, 42120b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]> { 42130b57cec5SDimitry Andric bits<4> Rd; 42140b57cec5SDimitry Andric bits<4> Rn; 42150b57cec5SDimitry Andric bits<10> imm; 42160b57cec5SDimitry Andric let Inst{27-21} = 0b0111110; 42170b57cec5SDimitry Andric let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 42180b57cec5SDimitry Andric let Inst{15-12} = Rd; 42190b57cec5SDimitry Andric let Inst{11-7} = imm{4-0}; // lsb 42200b57cec5SDimitry Andric let Inst{20-16} = imm{9-5}; // width 42210b57cec5SDimitry Andric let Inst{3-0} = Rn; 42220b57cec5SDimitry Andric} 42230b57cec5SDimitry Andric 42240b57cec5SDimitry Andricdef MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr, 42250b57cec5SDimitry Andric "mvn", "\t$Rd, $Rm", 42260b57cec5SDimitry Andric [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP, Sched<[WriteALU]> { 42270b57cec5SDimitry Andric bits<4> Rd; 42280b57cec5SDimitry Andric bits<4> Rm; 42290b57cec5SDimitry Andric let Inst{25} = 0; 42300b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 42310b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 42320b57cec5SDimitry Andric let Inst{15-12} = Rd; 42330b57cec5SDimitry Andric let Inst{3-0} = Rm; 42340b57cec5SDimitry Andric 42350b57cec5SDimitry Andric let Unpredictable{19-16} = 0b1111; 42360b57cec5SDimitry Andric} 42370b57cec5SDimitry Andricdef MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), 42380b57cec5SDimitry Andric DPSoRegImmFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", 42390b57cec5SDimitry Andric [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP, 42400b57cec5SDimitry Andric Sched<[WriteALU]> { 42410b57cec5SDimitry Andric bits<4> Rd; 42420b57cec5SDimitry Andric bits<12> shift; 42430b57cec5SDimitry Andric let Inst{25} = 0; 42440b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 42450b57cec5SDimitry Andric let Inst{15-12} = Rd; 42460b57cec5SDimitry Andric let Inst{11-5} = shift{11-5}; 42470b57cec5SDimitry Andric let Inst{4} = 0; 42480b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 42490b57cec5SDimitry Andric 42500b57cec5SDimitry Andric let Unpredictable{19-16} = 0b1111; 42510b57cec5SDimitry Andric} 42520b57cec5SDimitry Andricdef MVNsr : AsI1<0b1111, (outs GPRnopc:$Rd), (ins so_reg_reg:$shift), 42530b57cec5SDimitry Andric DPSoRegRegFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", 42540b57cec5SDimitry Andric [(set GPRnopc:$Rd, (not so_reg_reg:$shift))]>, UnaryDP, 42550b57cec5SDimitry Andric Sched<[WriteALU]> { 42560b57cec5SDimitry Andric bits<4> Rd; 42570b57cec5SDimitry Andric bits<12> shift; 42580b57cec5SDimitry Andric let Inst{25} = 0; 42590b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 42600b57cec5SDimitry Andric let Inst{15-12} = Rd; 42610b57cec5SDimitry Andric let Inst{11-8} = shift{11-8}; 42620b57cec5SDimitry Andric let Inst{7} = 0; 42630b57cec5SDimitry Andric let Inst{6-5} = shift{6-5}; 42640b57cec5SDimitry Andric let Inst{4} = 1; 42650b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 42660b57cec5SDimitry Andric 42670b57cec5SDimitry Andric let Unpredictable{19-16} = 0b1111; 42680b57cec5SDimitry Andric} 42690b57cec5SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 42700b57cec5SDimitry Andricdef MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins mod_imm:$imm), DPFrm, 42710b57cec5SDimitry Andric IIC_iMVNi, "mvn", "\t$Rd, $imm", 42720b57cec5SDimitry Andric [(set GPR:$Rd, mod_imm_not:$imm)]>,UnaryDP, Sched<[WriteALU]> { 42730b57cec5SDimitry Andric bits<4> Rd; 42740b57cec5SDimitry Andric bits<12> imm; 42750b57cec5SDimitry Andric let Inst{25} = 1; 42760b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 42770b57cec5SDimitry Andric let Inst{15-12} = Rd; 42780b57cec5SDimitry Andric let Inst{11-0} = imm; 42790b57cec5SDimitry Andric} 42800b57cec5SDimitry Andric 42810b57cec5SDimitry Andriclet AddedComplexity = 1 in 42820b57cec5SDimitry Andricdef : ARMPat<(and GPR:$src, mod_imm_not:$imm), 42830b57cec5SDimitry Andric (BICri GPR:$src, mod_imm_not:$imm)>; 42840b57cec5SDimitry Andric 42850b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 42860b57cec5SDimitry Andric// Multiply Instructions. 42870b57cec5SDimitry Andric// 42880b57cec5SDimitry Andricclass AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 42890b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 42900b57cec5SDimitry Andric : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 42910b57cec5SDimitry Andric bits<4> Rd; 42920b57cec5SDimitry Andric bits<4> Rm; 42930b57cec5SDimitry Andric bits<4> Rn; 42940b57cec5SDimitry Andric let Inst{19-16} = Rd; 42950b57cec5SDimitry Andric let Inst{11-8} = Rm; 42960b57cec5SDimitry Andric let Inst{3-0} = Rn; 42970b57cec5SDimitry Andric} 42980b57cec5SDimitry Andricclass AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 42990b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 43000b57cec5SDimitry Andric : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 43010b57cec5SDimitry Andric bits<4> RdLo; 43020b57cec5SDimitry Andric bits<4> RdHi; 43030b57cec5SDimitry Andric bits<4> Rm; 43040b57cec5SDimitry Andric bits<4> Rn; 43050b57cec5SDimitry Andric let Inst{19-16} = RdHi; 43060b57cec5SDimitry Andric let Inst{15-12} = RdLo; 43070b57cec5SDimitry Andric let Inst{11-8} = Rm; 43080b57cec5SDimitry Andric let Inst{3-0} = Rn; 43090b57cec5SDimitry Andric} 43100b57cec5SDimitry Andricclass AsMla1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 43110b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 43120b57cec5SDimitry Andric : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 43130b57cec5SDimitry Andric bits<4> RdLo; 43140b57cec5SDimitry Andric bits<4> RdHi; 43150b57cec5SDimitry Andric bits<4> Rm; 43160b57cec5SDimitry Andric bits<4> Rn; 43170b57cec5SDimitry Andric let Inst{19-16} = RdHi; 43180b57cec5SDimitry Andric let Inst{15-12} = RdLo; 43190b57cec5SDimitry Andric let Inst{11-8} = Rm; 43200b57cec5SDimitry Andric let Inst{3-0} = Rn; 43210b57cec5SDimitry Andric} 43220b57cec5SDimitry Andric 43230b57cec5SDimitry Andric// FIXME: The v5 pseudos are only necessary for the additional Constraint 43240b57cec5SDimitry Andric// property. Remove them when it's possible to add those properties 43250b57cec5SDimitry Andric// on an individual MachineInstr, not just an instruction description. 43260b57cec5SDimitry Andriclet isCommutable = 1, TwoOperandAliasConstraint = "$Rn = $Rd" in { 43270b57cec5SDimitry Andricdef MUL : AsMul1I32<0b0000000, (outs GPRnopc:$Rd), 43280b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm), 43290b57cec5SDimitry Andric IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", 43300b57cec5SDimitry Andric [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))]>, 43310b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 43320b57cec5SDimitry Andric Sched<[WriteMUL32, ReadMUL, ReadMUL]> { 43330b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 43340b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 43350b57cec5SDimitry Andric} 43360b57cec5SDimitry Andric 43370b57cec5SDimitry Andriclet Constraints = "@earlyclobber $Rd" in 43380b57cec5SDimitry Andricdef MULv5: ARMPseudoExpand<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm, 43390b57cec5SDimitry Andric pred:$p, cc_out:$s), 43400b57cec5SDimitry Andric 4, IIC_iMUL32, 43410b57cec5SDimitry Andric [(set GPRnopc:$Rd, (mul GPRnopc:$Rn, GPRnopc:$Rm))], 43420b57cec5SDimitry Andric (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s)>, 43430b57cec5SDimitry Andric Requires<[IsARM, NoV6, UseMulOps]>, 43440b57cec5SDimitry Andric Sched<[WriteMUL32, ReadMUL, ReadMUL]>; 43450b57cec5SDimitry Andric} 43460b57cec5SDimitry Andric 43470b57cec5SDimitry Andricdef MLA : AsMul1I32<0b0000001, (outs GPRnopc:$Rd), 43480b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra), 43490b57cec5SDimitry Andric IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra", 43500b57cec5SDimitry Andric [(set GPRnopc:$Rd, (add (mul GPRnopc:$Rn, GPRnopc:$Rm), GPRnopc:$Ra))]>, 43510b57cec5SDimitry Andric Requires<[IsARM, HasV6, UseMulOps]>, 43520b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]> { 43530b57cec5SDimitry Andric bits<4> Ra; 43540b57cec5SDimitry Andric let Inst{15-12} = Ra; 43550b57cec5SDimitry Andric} 43560b57cec5SDimitry Andric 43570b57cec5SDimitry Andriclet Constraints = "@earlyclobber $Rd" in 43580b57cec5SDimitry Andricdef MLAv5: ARMPseudoExpand<(outs GPRnopc:$Rd), 43590b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra, 43600b57cec5SDimitry Andric pred:$p, cc_out:$s), 4, IIC_iMAC32, 43610b57cec5SDimitry Andric [(set GPRnopc:$Rd, (add (mul GPRnopc:$Rn, GPRnopc:$Rm), GPRnopc:$Ra))], 43620b57cec5SDimitry Andric (MLA GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra, pred:$p, cc_out:$s)>, 43630b57cec5SDimitry Andric Requires<[IsARM, NoV6]>, 43640b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 43650b57cec5SDimitry Andric 43660b57cec5SDimitry Andricdef MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 43670b57cec5SDimitry Andric IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra", 43680b57cec5SDimitry Andric [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>, 43690b57cec5SDimitry Andric Requires<[IsARM, HasV6T2, UseMulOps]>, 43700b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]> { 43710b57cec5SDimitry Andric bits<4> Rd; 43720b57cec5SDimitry Andric bits<4> Rm; 43730b57cec5SDimitry Andric bits<4> Rn; 43740b57cec5SDimitry Andric bits<4> Ra; 43750b57cec5SDimitry Andric let Inst{19-16} = Rd; 43760b57cec5SDimitry Andric let Inst{15-12} = Ra; 43770b57cec5SDimitry Andric let Inst{11-8} = Rm; 43780b57cec5SDimitry Andric let Inst{3-0} = Rn; 43790b57cec5SDimitry Andric} 43800b57cec5SDimitry Andric 43810b57cec5SDimitry Andric// Extra precision multiplies with low / high results 43820b57cec5SDimitry Andriclet hasSideEffects = 0 in { 43830b57cec5SDimitry Andriclet isCommutable = 1 in { 43840b57cec5SDimitry Andricdef SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi), 43850b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 43860b57cec5SDimitry Andric "smull", "\t$RdLo, $RdHi, $Rn, $Rm", 43870b57cec5SDimitry Andric [(set GPR:$RdLo, GPR:$RdHi, 43880b57cec5SDimitry Andric (smullohi GPR:$Rn, GPR:$Rm))]>, 43890b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 43900b57cec5SDimitry Andric Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>; 43910b57cec5SDimitry Andric 43920b57cec5SDimitry Andricdef UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi), 43930b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 43940b57cec5SDimitry Andric "umull", "\t$RdLo, $RdHi, $Rn, $Rm", 43950b57cec5SDimitry Andric [(set GPR:$RdLo, GPR:$RdHi, 43960b57cec5SDimitry Andric (umullohi GPR:$Rn, GPR:$Rm))]>, 43970b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 43980b57cec5SDimitry Andric Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL]>; 43990b57cec5SDimitry Andric 44000b57cec5SDimitry Andriclet Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { 44010b57cec5SDimitry Andricdef SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 44020b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 44030b57cec5SDimitry Andric 4, IIC_iMUL64, 44040b57cec5SDimitry Andric [(set GPR:$RdLo, GPR:$RdHi, 44050b57cec5SDimitry Andric (smullohi GPR:$Rn, GPR:$Rm))], 44060b57cec5SDimitry Andric (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 44070b57cec5SDimitry Andric Requires<[IsARM, NoV6]>, 44080b57cec5SDimitry Andric Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>; 44090b57cec5SDimitry Andric 44100b57cec5SDimitry Andricdef UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 44110b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 44120b57cec5SDimitry Andric 4, IIC_iMUL64, 44130b57cec5SDimitry Andric [(set GPR:$RdLo, GPR:$RdHi, 44140b57cec5SDimitry Andric (umullohi GPR:$Rn, GPR:$Rm))], 44150b57cec5SDimitry Andric (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, 44160b57cec5SDimitry Andric Requires<[IsARM, NoV6]>, 44170b57cec5SDimitry Andric Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>; 44180b57cec5SDimitry Andric} 44190b57cec5SDimitry Andric} 44200b57cec5SDimitry Andric 44210b57cec5SDimitry Andric// Multiply + accumulate 44220b57cec5SDimitry Andricdef SMLAL : AsMla1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi), 44230b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64, 44240b57cec5SDimitry Andric "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 44250b57cec5SDimitry Andric RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>, 44260b57cec5SDimitry Andric Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 44270b57cec5SDimitry Andricdef UMLAL : AsMla1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi), 44280b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), IIC_iMAC64, 44290b57cec5SDimitry Andric "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 44300b57cec5SDimitry Andric RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>, 44310b57cec5SDimitry Andric Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 44320b57cec5SDimitry Andric 44330b57cec5SDimitry Andricdef UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), 44340b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 44350b57cec5SDimitry Andric IIC_iMAC64, 44360b57cec5SDimitry Andric "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 44370b57cec5SDimitry Andric RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, Requires<[IsARM, HasV6]>, 44380b57cec5SDimitry Andric Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]> { 44390b57cec5SDimitry Andric bits<4> RdLo; 44400b57cec5SDimitry Andric bits<4> RdHi; 44410b57cec5SDimitry Andric bits<4> Rm; 44420b57cec5SDimitry Andric bits<4> Rn; 44430b57cec5SDimitry Andric let Inst{19-16} = RdHi; 44440b57cec5SDimitry Andric let Inst{15-12} = RdLo; 44450b57cec5SDimitry Andric let Inst{11-8} = Rm; 44460b57cec5SDimitry Andric let Inst{3-0} = Rn; 44470b57cec5SDimitry Andric} 44480b57cec5SDimitry Andric 44490b57cec5SDimitry Andriclet Constraints = 44500b57cec5SDimitry Andric "@earlyclobber $RdLo,@earlyclobber $RdHi,$RLo = $RdLo,$RHi = $RdHi" in { 44510b57cec5SDimitry Andricdef SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 44520b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s), 44530b57cec5SDimitry Andric 4, IIC_iMAC64, [], 44540b57cec5SDimitry Andric (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, 44550b57cec5SDimitry Andric pred:$p, cc_out:$s)>, 44560b57cec5SDimitry Andric Requires<[IsARM, NoV6]>, 44570b57cec5SDimitry Andric Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 44580b57cec5SDimitry Andricdef UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi), 44590b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, pred:$p, cc_out:$s), 44600b57cec5SDimitry Andric 4, IIC_iMAC64, [], 44610b57cec5SDimitry Andric (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi, 44620b57cec5SDimitry Andric pred:$p, cc_out:$s)>, 44630b57cec5SDimitry Andric Requires<[IsARM, NoV6]>, 44640b57cec5SDimitry Andric Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 44650b57cec5SDimitry Andric} 44660b57cec5SDimitry Andric 44670b57cec5SDimitry Andric} // hasSideEffects 44680b57cec5SDimitry Andric 44690b57cec5SDimitry Andric// Most significant word multiply 44700b57cec5SDimitry Andricdef SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 44710b57cec5SDimitry Andric IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm", 44720b57cec5SDimitry Andric [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>, 44730b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 44740b57cec5SDimitry Andric Sched<[WriteMUL32, ReadMUL, ReadMUL]> { 44750b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 44760b57cec5SDimitry Andric} 44770b57cec5SDimitry Andric 44780b57cec5SDimitry Andricdef SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 44790b57cec5SDimitry Andric IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", 44800b57cec5SDimitry Andric [(set GPR:$Rd, (ARMsmmlar GPR:$Rn, GPR:$Rm, (i32 0)))]>, 44810b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 44820b57cec5SDimitry Andric Sched<[WriteMUL32, ReadMUL, ReadMUL]> { 44830b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 44840b57cec5SDimitry Andric} 44850b57cec5SDimitry Andric 44860b57cec5SDimitry Andricdef SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd), 44870b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 44880b57cec5SDimitry Andric IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra", 44890b57cec5SDimitry Andric [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 44900b57cec5SDimitry Andric Requires<[IsARM, HasV6, UseMulOps]>, 44910b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 44920b57cec5SDimitry Andric 44930b57cec5SDimitry Andricdef SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd), 44940b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 44950b57cec5SDimitry Andric IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", 44960b57cec5SDimitry Andric [(set GPR:$Rd, (ARMsmmlar GPR:$Rn, GPR:$Rm, GPR:$Ra))]>, 44970b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 44980b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 44990b57cec5SDimitry Andric 45000b57cec5SDimitry Andricdef SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd), 45010b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 45020b57cec5SDimitry Andric IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", []>, 45030b57cec5SDimitry Andric Requires<[IsARM, HasV6, UseMulOps]>, 45040b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 45050b57cec5SDimitry Andric 45060b57cec5SDimitry Andricdef SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd), 45070b57cec5SDimitry Andric (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 45080b57cec5SDimitry Andric IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", 45090b57cec5SDimitry Andric [(set GPR:$Rd, (ARMsmmlsr GPR:$Rn, GPR:$Rm, GPR:$Ra))]>, 45100b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 45110b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 45120b57cec5SDimitry Andric 45130b57cec5SDimitry Andricmulticlass AI_smul<string opc> { 45140b57cec5SDimitry Andric def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 45150b57cec5SDimitry Andric IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm", 45160b57cec5SDimitry Andric [(set GPR:$Rd, (bb_mul GPR:$Rn, GPR:$Rm))]>, 45170b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]>, 45180b57cec5SDimitry Andric Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 45190b57cec5SDimitry Andric 45200b57cec5SDimitry Andric def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 45210b57cec5SDimitry Andric IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm", 45220b57cec5SDimitry Andric [(set GPR:$Rd, (bt_mul GPR:$Rn, GPR:$Rm))]>, 45230b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]>, 45240b57cec5SDimitry Andric Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 45250b57cec5SDimitry Andric 45260b57cec5SDimitry Andric def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 45270b57cec5SDimitry Andric IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm", 45280b57cec5SDimitry Andric [(set GPR:$Rd, (tb_mul GPR:$Rn, GPR:$Rm))]>, 45290b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]>, 45300b57cec5SDimitry Andric Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 45310b57cec5SDimitry Andric 45320b57cec5SDimitry Andric def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 45330b57cec5SDimitry Andric IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm", 45340b57cec5SDimitry Andric [(set GPR:$Rd, (tt_mul GPR:$Rn, GPR:$Rm))]>, 45350b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]>, 45360b57cec5SDimitry Andric Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 45370b57cec5SDimitry Andric 45380b57cec5SDimitry Andric def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 45390b57cec5SDimitry Andric IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm", 45400b57cec5SDimitry Andric [(set GPR:$Rd, (ARMsmulwb GPR:$Rn, GPR:$Rm))]>, 45410b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]>, 45420b57cec5SDimitry Andric Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 45430b57cec5SDimitry Andric 45440b57cec5SDimitry Andric def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 45450b57cec5SDimitry Andric IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm", 45460b57cec5SDimitry Andric [(set GPR:$Rd, (ARMsmulwt GPR:$Rn, GPR:$Rm))]>, 45470b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]>, 45480b57cec5SDimitry Andric Sched<[WriteMUL16, ReadMUL, ReadMUL]>; 45490b57cec5SDimitry Andric} 45500b57cec5SDimitry Andric 45510b57cec5SDimitry Andric 45520b57cec5SDimitry Andricmulticlass AI_smla<string opc> { 45530b57cec5SDimitry Andric let DecoderMethod = "DecodeSMLAInstruction" in { 45540b57cec5SDimitry Andric def BB : AMulxyIa<0b0001000, 0b00, (outs GPRnopc:$Rd), 45550b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 45560b57cec5SDimitry Andric IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", 45570b57cec5SDimitry Andric [(set GPRnopc:$Rd, (add GPR:$Ra, 45580b57cec5SDimitry Andric (bb_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>, 45590b57cec5SDimitry Andric Requires<[IsARM, HasV5TE, UseMulOps]>, 45600b57cec5SDimitry Andric Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 45610b57cec5SDimitry Andric 45620b57cec5SDimitry Andric def BT : AMulxyIa<0b0001000, 0b10, (outs GPRnopc:$Rd), 45630b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 45640b57cec5SDimitry Andric IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", 45650b57cec5SDimitry Andric [(set GPRnopc:$Rd, (add GPR:$Ra, 45660b57cec5SDimitry Andric (bt_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>, 45670b57cec5SDimitry Andric Requires<[IsARM, HasV5TE, UseMulOps]>, 45680b57cec5SDimitry Andric Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 45690b57cec5SDimitry Andric 45700b57cec5SDimitry Andric def TB : AMulxyIa<0b0001000, 0b01, (outs GPRnopc:$Rd), 45710b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 45720b57cec5SDimitry Andric IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", 45730b57cec5SDimitry Andric [(set GPRnopc:$Rd, (add GPR:$Ra, 45740b57cec5SDimitry Andric (tb_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>, 45750b57cec5SDimitry Andric Requires<[IsARM, HasV5TE, UseMulOps]>, 45760b57cec5SDimitry Andric Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 45770b57cec5SDimitry Andric 45780b57cec5SDimitry Andric def TT : AMulxyIa<0b0001000, 0b11, (outs GPRnopc:$Rd), 45790b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 45800b57cec5SDimitry Andric IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", 45810b57cec5SDimitry Andric [(set GPRnopc:$Rd, (add GPR:$Ra, 45820b57cec5SDimitry Andric (tt_mul GPRnopc:$Rn, GPRnopc:$Rm)))]>, 45830b57cec5SDimitry Andric Requires<[IsARM, HasV5TE, UseMulOps]>, 45840b57cec5SDimitry Andric Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 45850b57cec5SDimitry Andric 45860b57cec5SDimitry Andric def WB : AMulxyIa<0b0001001, 0b00, (outs GPRnopc:$Rd), 45870b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 45880b57cec5SDimitry Andric IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", 45890b57cec5SDimitry Andric [(set GPRnopc:$Rd, 45900b57cec5SDimitry Andric (add GPR:$Ra, (ARMsmulwb GPRnopc:$Rn, GPRnopc:$Rm)))]>, 45910b57cec5SDimitry Andric Requires<[IsARM, HasV5TE, UseMulOps]>, 45920b57cec5SDimitry Andric Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 45930b57cec5SDimitry Andric 45940b57cec5SDimitry Andric def WT : AMulxyIa<0b0001001, 0b10, (outs GPRnopc:$Rd), 45950b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 45960b57cec5SDimitry Andric IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", 45970b57cec5SDimitry Andric [(set GPRnopc:$Rd, 45980b57cec5SDimitry Andric (add GPR:$Ra, (ARMsmulwt GPRnopc:$Rn, GPRnopc:$Rm)))]>, 45990b57cec5SDimitry Andric Requires<[IsARM, HasV5TE, UseMulOps]>, 46000b57cec5SDimitry Andric Sched<[WriteMAC16, ReadMUL, ReadMUL, ReadMAC]>; 46010b57cec5SDimitry Andric } 46020b57cec5SDimitry Andric} 46030b57cec5SDimitry Andric 46040b57cec5SDimitry Andricdefm SMUL : AI_smul<"smul">; 46050b57cec5SDimitry Andricdefm SMLA : AI_smla<"smla">; 46060b57cec5SDimitry Andric 46070b57cec5SDimitry Andric// Halfword multiply accumulate long: SMLAL<x><y>. 46080b57cec5SDimitry Andricclass SMLAL<bits<2> opc1, string asm> 46090b57cec5SDimitry Andric : AMulxyI64<0b0001010, opc1, 46100b57cec5SDimitry Andric (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 46110b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 46120b57cec5SDimitry Andric IIC_iMAC64, asm, "\t$RdLo, $RdHi, $Rn, $Rm", []>, 46130b57cec5SDimitry Andric RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, 46140b57cec5SDimitry Andric Requires<[IsARM, HasV5TE]>, 46150b57cec5SDimitry Andric Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 46160b57cec5SDimitry Andric 46170b57cec5SDimitry Andricdef SMLALBB : SMLAL<0b00, "smlalbb">; 46180b57cec5SDimitry Andricdef SMLALBT : SMLAL<0b10, "smlalbt">; 46190b57cec5SDimitry Andricdef SMLALTB : SMLAL<0b01, "smlaltb">; 46200b57cec5SDimitry Andricdef SMLALTT : SMLAL<0b11, "smlaltt">; 46210b57cec5SDimitry Andric 46220b57cec5SDimitry Andricdef : ARMV5TEPat<(ARMsmlalbb GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 46230b57cec5SDimitry Andric (SMLALBB $Rn, $Rm, $RLo, $RHi)>; 46240b57cec5SDimitry Andricdef : ARMV5TEPat<(ARMsmlalbt GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 46250b57cec5SDimitry Andric (SMLALBT $Rn, $Rm, $RLo, $RHi)>; 46260b57cec5SDimitry Andricdef : ARMV5TEPat<(ARMsmlaltb GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 46270b57cec5SDimitry Andric (SMLALTB $Rn, $Rm, $RLo, $RHi)>; 46280b57cec5SDimitry Andricdef : ARMV5TEPat<(ARMsmlaltt GPR:$Rn, GPR:$Rm, GPR:$RLo, GPR:$RHi), 46290b57cec5SDimitry Andric (SMLALTT $Rn, $Rm, $RLo, $RHi)>; 46300b57cec5SDimitry Andric 46310b57cec5SDimitry Andric// Helper class for AI_smld. 46320b57cec5SDimitry Andricclass AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops, 46330b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm> 46340b57cec5SDimitry Andric : AI<oops, iops, MulFrm, itin, opc, asm, []>, 46350b57cec5SDimitry Andric Requires<[IsARM, HasV6]> { 46360b57cec5SDimitry Andric bits<4> Rn; 46370b57cec5SDimitry Andric bits<4> Rm; 46380b57cec5SDimitry Andric let Inst{27-23} = 0b01110; 46390b57cec5SDimitry Andric let Inst{22} = long; 46400b57cec5SDimitry Andric let Inst{21-20} = 0b00; 46410b57cec5SDimitry Andric let Inst{11-8} = Rm; 46420b57cec5SDimitry Andric let Inst{7} = 0; 46430b57cec5SDimitry Andric let Inst{6} = sub; 46440b57cec5SDimitry Andric let Inst{5} = swap; 46450b57cec5SDimitry Andric let Inst{4} = 1; 46460b57cec5SDimitry Andric let Inst{3-0} = Rn; 46470b57cec5SDimitry Andric} 46480b57cec5SDimitry Andricclass AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops, 46490b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm> 46500b57cec5SDimitry Andric : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 46510b57cec5SDimitry Andric bits<4> Rd; 46520b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 46530b57cec5SDimitry Andric let Inst{19-16} = Rd; 46540b57cec5SDimitry Andric} 46550b57cec5SDimitry Andricclass AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops, 46560b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm> 46570b57cec5SDimitry Andric : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 46580b57cec5SDimitry Andric bits<4> Ra; 46590b57cec5SDimitry Andric bits<4> Rd; 46600b57cec5SDimitry Andric let Inst{19-16} = Rd; 46610b57cec5SDimitry Andric let Inst{15-12} = Ra; 46620b57cec5SDimitry Andric} 46630b57cec5SDimitry Andricclass AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops, 46640b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm> 46650b57cec5SDimitry Andric : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 46660b57cec5SDimitry Andric bits<4> RdLo; 46670b57cec5SDimitry Andric bits<4> RdHi; 46680b57cec5SDimitry Andric let Inst{19-16} = RdHi; 46690b57cec5SDimitry Andric let Inst{15-12} = RdLo; 46700b57cec5SDimitry Andric} 46710b57cec5SDimitry Andric 46720b57cec5SDimitry Andricmulticlass AI_smld<bit sub, string opc> { 46730b57cec5SDimitry Andric 46740b57cec5SDimitry Andric def D : AMulDualIa<0, sub, 0, (outs GPRnopc:$Rd), 46750b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 46760b57cec5SDimitry Andric NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">, 46770b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 46780b57cec5SDimitry Andric 46790b57cec5SDimitry Andric def DX: AMulDualIa<0, sub, 1, (outs GPRnopc:$Rd), 46800b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 46810b57cec5SDimitry Andric NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">, 46820b57cec5SDimitry Andric Sched<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC]>; 46830b57cec5SDimitry Andric 46840b57cec5SDimitry Andric def LD: AMulDualI64<1, sub, 0, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 46850b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 46860b57cec5SDimitry Andric NoItinerary, 46870b57cec5SDimitry Andric !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">, 46880b57cec5SDimitry Andric RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, 46890b57cec5SDimitry Andric Sched<[WriteMAC64Lo, WriteMAC64Hi, ReadMUL, ReadMUL, ReadMAC, ReadMAC]>; 46900b57cec5SDimitry Andric 46910b57cec5SDimitry Andric def LDX : AMulDualI64<1, sub, 1, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), 46920b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 46930b57cec5SDimitry Andric NoItinerary, 46940b57cec5SDimitry Andric !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">, 46950b57cec5SDimitry Andric RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, 46960b57cec5SDimitry Andric Sched<[WriteMUL64Lo, WriteMUL64Hi, ReadMUL, ReadMUL]>; 46970b57cec5SDimitry Andric} 46980b57cec5SDimitry Andric 46990b57cec5SDimitry Andricdefm SMLA : AI_smld<0, "smla">; 47000b57cec5SDimitry Andricdefm SMLS : AI_smld<1, "smls">; 47010b57cec5SDimitry Andric 47020b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_smlad GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 47030b57cec5SDimitry Andric (SMLAD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>; 47040b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_smladx GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 47050b57cec5SDimitry Andric (SMLADX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>; 47060b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_smlsd GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 47070b57cec5SDimitry Andric (SMLSD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>; 47080b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_smlsdx GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), 47090b57cec5SDimitry Andric (SMLSDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra)>; 47100b57cec5SDimitry Andricdef : ARMV6Pat<(ARMSmlald GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 47110b57cec5SDimitry Andric (SMLALD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>; 47120b57cec5SDimitry Andricdef : ARMV6Pat<(ARMSmlaldx GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 47130b57cec5SDimitry Andric (SMLALDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>; 47140b57cec5SDimitry Andricdef : ARMV6Pat<(ARMSmlsld GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 47150b57cec5SDimitry Andric (SMLSLD GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>; 47160b57cec5SDimitry Andricdef : ARMV6Pat<(ARMSmlsldx GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi), 47170b57cec5SDimitry Andric (SMLSLDX GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$RLo, GPRnopc:$RHi)>; 47180b57cec5SDimitry Andric 47190b57cec5SDimitry Andricmulticlass AI_sdml<bit sub, string opc> { 47200b57cec5SDimitry Andric 47210b57cec5SDimitry Andric def D:AMulDualI<0, sub, 0, (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), 47220b57cec5SDimitry Andric NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">, 47230b57cec5SDimitry Andric Sched<[WriteMUL32, ReadMUL, ReadMUL]>; 47240b57cec5SDimitry Andric def DX:AMulDualI<0, sub, 1, (outs GPRnopc:$Rd),(ins GPRnopc:$Rn, GPRnopc:$Rm), 47250b57cec5SDimitry Andric NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">, 47260b57cec5SDimitry Andric Sched<[WriteMUL32, ReadMUL, ReadMUL]>; 47270b57cec5SDimitry Andric} 47280b57cec5SDimitry Andric 47290b57cec5SDimitry Andricdefm SMUA : AI_sdml<0, "smua">; 47300b57cec5SDimitry Andricdefm SMUS : AI_sdml<1, "smus">; 47310b57cec5SDimitry Andric 47320b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_smuad GPRnopc:$Rn, GPRnopc:$Rm), 47330b57cec5SDimitry Andric (SMUAD GPRnopc:$Rn, GPRnopc:$Rm)>; 47340b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_smuadx GPRnopc:$Rn, GPRnopc:$Rm), 47350b57cec5SDimitry Andric (SMUADX GPRnopc:$Rn, GPRnopc:$Rm)>; 47360b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_smusd GPRnopc:$Rn, GPRnopc:$Rm), 47370b57cec5SDimitry Andric (SMUSD GPRnopc:$Rn, GPRnopc:$Rm)>; 47380b57cec5SDimitry Andricdef : ARMV6Pat<(int_arm_smusdx GPRnopc:$Rn, GPRnopc:$Rm), 47390b57cec5SDimitry Andric (SMUSDX GPRnopc:$Rn, GPRnopc:$Rm)>; 47400b57cec5SDimitry Andric 47410b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 47420b57cec5SDimitry Andric// Division Instructions (ARMv7-A with virtualization extension) 47430b57cec5SDimitry Andric// 47440b57cec5SDimitry Andricdef SDIV : ADivA1I<0b001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iDIV, 47450b57cec5SDimitry Andric "sdiv", "\t$Rd, $Rn, $Rm", 47460b57cec5SDimitry Andric [(set GPR:$Rd, (sdiv GPR:$Rn, GPR:$Rm))]>, 47470b57cec5SDimitry Andric Requires<[IsARM, HasDivideInARM]>, 47480b57cec5SDimitry Andric Sched<[WriteDIV]>; 47490b57cec5SDimitry Andric 47500b57cec5SDimitry Andricdef UDIV : ADivA1I<0b011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), IIC_iDIV, 47510b57cec5SDimitry Andric "udiv", "\t$Rd, $Rn, $Rm", 47520b57cec5SDimitry Andric [(set GPR:$Rd, (udiv GPR:$Rn, GPR:$Rm))]>, 47530b57cec5SDimitry Andric Requires<[IsARM, HasDivideInARM]>, 47540b57cec5SDimitry Andric Sched<[WriteDIV]>; 47550b57cec5SDimitry Andric 47560b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 47570b57cec5SDimitry Andric// Misc. Arithmetic Instructions. 47580b57cec5SDimitry Andric// 47590b57cec5SDimitry Andric 47600b57cec5SDimitry Andricdef CLZ : AMiscA1I<0b00010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm), 47610b57cec5SDimitry Andric IIC_iUNAr, "clz", "\t$Rd, $Rm", 47620b57cec5SDimitry Andric [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>, 47630b57cec5SDimitry Andric Sched<[WriteALU]>; 47640b57cec5SDimitry Andric 47650b57cec5SDimitry Andricdef RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 47660b57cec5SDimitry Andric IIC_iUNAr, "rbit", "\t$Rd, $Rm", 47670b57cec5SDimitry Andric [(set GPR:$Rd, (bitreverse GPR:$Rm))]>, 47680b57cec5SDimitry Andric Requires<[IsARM, HasV6T2]>, 47690b57cec5SDimitry Andric Sched<[WriteALU]>; 47700b57cec5SDimitry Andric 47710b57cec5SDimitry Andricdef REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 47720b57cec5SDimitry Andric IIC_iUNAr, "rev", "\t$Rd, $Rm", 47730b57cec5SDimitry Andric [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>, 47740b57cec5SDimitry Andric Sched<[WriteALU]>; 47750b57cec5SDimitry Andric 47760b57cec5SDimitry Andriclet AddedComplexity = 5 in 47770b57cec5SDimitry Andricdef REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 47780b57cec5SDimitry Andric IIC_iUNAr, "rev16", "\t$Rd, $Rm", 47790b57cec5SDimitry Andric [(set GPR:$Rd, (rotr (bswap GPR:$Rm), (i32 16)))]>, 47800b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 47810b57cec5SDimitry Andric Sched<[WriteALU]>; 47820b57cec5SDimitry Andric 47830b57cec5SDimitry Andricdef : ARMV6Pat<(srl (bswap (extloadi16 addrmode3:$addr)), (i32 16)), 47840b57cec5SDimitry Andric (REV16 (LDRH addrmode3:$addr))>; 47850b57cec5SDimitry Andricdef : ARMV6Pat<(truncstorei16 (srl (bswap GPR:$Rn), (i32 16)), addrmode3:$addr), 47860b57cec5SDimitry Andric (STRH (REV16 GPR:$Rn), addrmode3:$addr)>; 47874824e7fdSDimitry Andricdef : ARMV6Pat<(srl (bswap top16Zero:$Rn), (i32 16)), 47884824e7fdSDimitry Andric (REV16 GPR:$Rn)>; 47890b57cec5SDimitry Andric 47900b57cec5SDimitry Andriclet AddedComplexity = 5 in 47910b57cec5SDimitry Andricdef REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 47920b57cec5SDimitry Andric IIC_iUNAr, "revsh", "\t$Rd, $Rm", 47930b57cec5SDimitry Andric [(set GPR:$Rd, (sra (bswap GPR:$Rm), (i32 16)))]>, 47940b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 47950b57cec5SDimitry Andric Sched<[WriteALU]>; 47960b57cec5SDimitry Andric 47970b57cec5SDimitry Andricdef : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)), 47980b57cec5SDimitry Andric (and (srl GPR:$Rm, (i32 8)), 0xFF)), 47990b57cec5SDimitry Andric (REVSH GPR:$Rm)>; 48000b57cec5SDimitry Andric 48010b57cec5SDimitry Andricdef PKHBT : APKHI<0b01101000, 0, (outs GPRnopc:$Rd), 48020b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_lsl_amt:$sh), 48030b57cec5SDimitry Andric IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", 48040b57cec5SDimitry Andric [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF), 48050b57cec5SDimitry Andric (and (shl GPRnopc:$Rm, pkh_lsl_amt:$sh), 48060b57cec5SDimitry Andric 0xFFFF0000)))]>, 48070b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 48080b57cec5SDimitry Andric Sched<[WriteALUsi, ReadALU]>; 48090b57cec5SDimitry Andric 48100b57cec5SDimitry Andric// Alternate cases for PKHBT where identities eliminate some nodes. 48110b57cec5SDimitry Andricdef : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (and GPRnopc:$Rm, 0xFFFF0000)), 48120b57cec5SDimitry Andric (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, 0)>; 48130b57cec5SDimitry Andricdef : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (shl GPRnopc:$Rm, imm16_31:$sh)), 48140b57cec5SDimitry Andric (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, imm16_31:$sh)>; 48150b57cec5SDimitry Andric 48160b57cec5SDimitry Andric// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 48170b57cec5SDimitry Andric// will match the pattern below. 48180b57cec5SDimitry Andricdef PKHTB : APKHI<0b01101000, 1, (outs GPRnopc:$Rd), 48190b57cec5SDimitry Andric (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_asr_amt:$sh), 48200b57cec5SDimitry Andric IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh", 48210b57cec5SDimitry Andric [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF0000), 48220b57cec5SDimitry Andric (and (sra GPRnopc:$Rm, pkh_asr_amt:$sh), 48230b57cec5SDimitry Andric 0xFFFF)))]>, 48240b57cec5SDimitry Andric Requires<[IsARM, HasV6]>, 48250b57cec5SDimitry Andric Sched<[WriteALUsi, ReadALU]>; 48260b57cec5SDimitry Andric 48270b57cec5SDimitry Andric// Alternate cases for PKHTB where identities eliminate some nodes. Note that 48280b57cec5SDimitry Andric// a shift amount of 0 is *not legal* here, it is PKHBT instead. 48290b57cec5SDimitry Andric// We also can not replace a srl (17..31) by an arithmetic shift we would use in 48300b57cec5SDimitry Andric// pkhtb src1, src2, asr (17..31). 48310b57cec5SDimitry Andricdef : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 48320b57cec5SDimitry Andric (srl GPRnopc:$src2, imm16:$sh)), 48330b57cec5SDimitry Andric (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16:$sh)>; 48340b57cec5SDimitry Andricdef : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 48350b57cec5SDimitry Andric (sra GPRnopc:$src2, imm16_31:$sh)), 48360b57cec5SDimitry Andric (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16_31:$sh)>; 48370b57cec5SDimitry Andricdef : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), 48380b57cec5SDimitry Andric (and (srl GPRnopc:$src2, imm1_15:$sh), 0xFFFF)), 48390b57cec5SDimitry Andric (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm1_15:$sh)>; 48400b57cec5SDimitry Andric 48410b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 48420b57cec5SDimitry Andric// CRC Instructions 48430b57cec5SDimitry Andric// 48440b57cec5SDimitry Andric// Polynomials: 48450b57cec5SDimitry Andric// + CRC32{B,H,W} 0x04C11DB7 48460b57cec5SDimitry Andric// + CRC32C{B,H,W} 0x1EDC6F41 48470b57cec5SDimitry Andric// 48480b57cec5SDimitry Andric 48490b57cec5SDimitry Andricclass AI_crc32<bit C, bits<2> sz, string suffix, SDPatternOperator builtin> 48500b57cec5SDimitry Andric : AInoP<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), MiscFrm, NoItinerary, 48510b57cec5SDimitry Andric !strconcat("crc32", suffix), "\t$Rd, $Rn, $Rm", 48520b57cec5SDimitry Andric [(set GPRnopc:$Rd, (builtin GPRnopc:$Rn, GPRnopc:$Rm))]>, 48534542f901SDimitry Andric Requires<[IsARM, HasCRC]> { 48540b57cec5SDimitry Andric bits<4> Rd; 48550b57cec5SDimitry Andric bits<4> Rn; 48560b57cec5SDimitry Andric bits<4> Rm; 48570b57cec5SDimitry Andric 48580b57cec5SDimitry Andric let Inst{31-28} = 0b1110; 48590b57cec5SDimitry Andric let Inst{27-23} = 0b00010; 48600b57cec5SDimitry Andric let Inst{22-21} = sz; 48610b57cec5SDimitry Andric let Inst{20} = 0; 48620b57cec5SDimitry Andric let Inst{19-16} = Rn; 48630b57cec5SDimitry Andric let Inst{15-12} = Rd; 48640b57cec5SDimitry Andric let Inst{11-10} = 0b00; 48650b57cec5SDimitry Andric let Inst{9} = C; 48660b57cec5SDimitry Andric let Inst{8} = 0; 48670b57cec5SDimitry Andric let Inst{7-4} = 0b0100; 48680b57cec5SDimitry Andric let Inst{3-0} = Rm; 48690b57cec5SDimitry Andric 48700b57cec5SDimitry Andric let Unpredictable{11-8} = 0b1101; 48710b57cec5SDimitry Andric} 48720b57cec5SDimitry Andric 48730b57cec5SDimitry Andricdef CRC32B : AI_crc32<0, 0b00, "b", int_arm_crc32b>; 48740b57cec5SDimitry Andricdef CRC32CB : AI_crc32<1, 0b00, "cb", int_arm_crc32cb>; 48750b57cec5SDimitry Andricdef CRC32H : AI_crc32<0, 0b01, "h", int_arm_crc32h>; 48760b57cec5SDimitry Andricdef CRC32CH : AI_crc32<1, 0b01, "ch", int_arm_crc32ch>; 48770b57cec5SDimitry Andricdef CRC32W : AI_crc32<0, 0b10, "w", int_arm_crc32w>; 48780b57cec5SDimitry Andricdef CRC32CW : AI_crc32<1, 0b10, "cw", int_arm_crc32cw>; 48790b57cec5SDimitry Andric 48800b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 48810b57cec5SDimitry Andric// ARMv8.1a Privilege Access Never extension 48820b57cec5SDimitry Andric// 48830b57cec5SDimitry Andric// SETPAN #imm1 48840b57cec5SDimitry Andric 48850b57cec5SDimitry Andricdef SETPAN : AInoP<(outs), (ins imm0_1:$imm), MiscFrm, NoItinerary, "setpan", 48860b57cec5SDimitry Andric "\t$imm", []>, Requires<[IsARM, HasV8, HasV8_1a]> { 48870b57cec5SDimitry Andric bits<1> imm; 48880b57cec5SDimitry Andric 48890b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 48900b57cec5SDimitry Andric let Inst{27-20} = 0b00010001; 48910b57cec5SDimitry Andric let Inst{19-16} = 0b0000; 48920b57cec5SDimitry Andric let Inst{15-10} = 0b000000; 48930b57cec5SDimitry Andric let Inst{9} = imm; 48940b57cec5SDimitry Andric let Inst{8} = 0b0; 48950b57cec5SDimitry Andric let Inst{7-4} = 0b0000; 48960b57cec5SDimitry Andric let Inst{3-0} = 0b0000; 48970b57cec5SDimitry Andric 48980b57cec5SDimitry Andric let Unpredictable{19-16} = 0b1111; 48990b57cec5SDimitry Andric let Unpredictable{15-10} = 0b111111; 49000b57cec5SDimitry Andric let Unpredictable{8} = 0b1; 49010b57cec5SDimitry Andric let Unpredictable{3-0} = 0b1111; 49020b57cec5SDimitry Andric} 49030b57cec5SDimitry Andric 49040b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 49050b57cec5SDimitry Andric// Comparison Instructions... 49060b57cec5SDimitry Andric// 49070b57cec5SDimitry Andric 49080b57cec5SDimitry Andricdefm CMP : AI1_cmp_irs<0b1010, "cmp", 49090b57cec5SDimitry Andric IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, ARMcmp>; 49100b57cec5SDimitry Andric 49110b57cec5SDimitry Andric// ARMcmpZ can re-use the above instruction definitions. 49120b57cec5SDimitry Andricdef : ARMPat<(ARMcmpZ GPR:$src, mod_imm:$imm), 49130b57cec5SDimitry Andric (CMPri GPR:$src, mod_imm:$imm)>; 49140b57cec5SDimitry Andricdef : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs), 49150b57cec5SDimitry Andric (CMPrr GPR:$src, GPR:$rhs)>; 49160b57cec5SDimitry Andricdef : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs), 49170b57cec5SDimitry Andric (CMPrsi GPR:$src, so_reg_imm:$rhs)>; 49180b57cec5SDimitry Andricdef : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs), 49190b57cec5SDimitry Andric (CMPrsr GPR:$src, so_reg_reg:$rhs)>; 4920bdd1243dSDimitry Andric// Following patterns aimed to prevent usage of CMPrsi and CMPrsr for a comparison 4921bdd1243dSDimitry Andric// with zero. Usage of CMPri in these cases helps to replace cmp with S-versions of 4922bdd1243dSDimitry Andric// shift instructions during peephole optimizations pass. 4923bdd1243dSDimitry Andricdef : ARMPat<(ARMcmpZ so_reg_imm:$rhs, 0), 4924bdd1243dSDimitry Andric (CMPri (MOVsi so_reg_imm:$rhs), 0)>; 4925bdd1243dSDimitry Andricdef : ARMPat<(ARMcmpZ so_reg_reg:$rhs, 0), 4926bdd1243dSDimitry Andric (CMPri (MOVsr so_reg_reg:$rhs), 0)>; 49270b57cec5SDimitry Andric 49280b57cec5SDimitry Andric// CMN register-integer 49290b57cec5SDimitry Andriclet isCompare = 1, Defs = [CPSR] in { 49300b57cec5SDimitry Andricdef CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, mod_imm:$imm), DPFrm, IIC_iCMPi, 49310b57cec5SDimitry Andric "cmn", "\t$Rn, $imm", 49320b57cec5SDimitry Andric [(ARMcmn GPR:$Rn, mod_imm:$imm)]>, 49330b57cec5SDimitry Andric Sched<[WriteCMP, ReadALU]> { 49340b57cec5SDimitry Andric bits<4> Rn; 49350b57cec5SDimitry Andric bits<12> imm; 49360b57cec5SDimitry Andric let Inst{25} = 1; 49370b57cec5SDimitry Andric let Inst{20} = 1; 49380b57cec5SDimitry Andric let Inst{19-16} = Rn; 49390b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 49400b57cec5SDimitry Andric let Inst{11-0} = imm; 49410b57cec5SDimitry Andric 49420b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 49430b57cec5SDimitry Andric} 49440b57cec5SDimitry Andric 49450b57cec5SDimitry Andric// CMN register-register/shift 49460b57cec5SDimitry Andricdef CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr, 49470b57cec5SDimitry Andric "cmn", "\t$Rn, $Rm", 49480b57cec5SDimitry Andric [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 49490b57cec5SDimitry Andric GPR:$Rn, GPR:$Rm)]>, Sched<[WriteCMP, ReadALU, ReadALU]> { 49500b57cec5SDimitry Andric bits<4> Rn; 49510b57cec5SDimitry Andric bits<4> Rm; 49520b57cec5SDimitry Andric let isCommutable = 1; 49530b57cec5SDimitry Andric let Inst{25} = 0; 49540b57cec5SDimitry Andric let Inst{20} = 1; 49550b57cec5SDimitry Andric let Inst{19-16} = Rn; 49560b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 49570b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 49580b57cec5SDimitry Andric let Inst{3-0} = Rm; 49590b57cec5SDimitry Andric 49600b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 49610b57cec5SDimitry Andric} 49620b57cec5SDimitry Andric 49630b57cec5SDimitry Andricdef CMNzrsi : AI1<0b1011, (outs), 49640b57cec5SDimitry Andric (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr, 49650b57cec5SDimitry Andric "cmn", "\t$Rn, $shift", 49660b57cec5SDimitry Andric [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 49670b57cec5SDimitry Andric GPR:$Rn, so_reg_imm:$shift)]>, 49680b57cec5SDimitry Andric Sched<[WriteCMPsi, ReadALU]> { 49690b57cec5SDimitry Andric bits<4> Rn; 49700b57cec5SDimitry Andric bits<12> shift; 49710b57cec5SDimitry Andric let Inst{25} = 0; 49720b57cec5SDimitry Andric let Inst{20} = 1; 49730b57cec5SDimitry Andric let Inst{19-16} = Rn; 49740b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 49750b57cec5SDimitry Andric let Inst{11-5} = shift{11-5}; 49760b57cec5SDimitry Andric let Inst{4} = 0; 49770b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 49780b57cec5SDimitry Andric 49790b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 49800b57cec5SDimitry Andric} 49810b57cec5SDimitry Andric 49820b57cec5SDimitry Andricdef CMNzrsr : AI1<0b1011, (outs), 49830b57cec5SDimitry Andric (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr, 49840b57cec5SDimitry Andric "cmn", "\t$Rn, $shift", 49850b57cec5SDimitry Andric [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 49860b57cec5SDimitry Andric GPRnopc:$Rn, so_reg_reg:$shift)]>, 49870b57cec5SDimitry Andric Sched<[WriteCMPsr, ReadALU]> { 49880b57cec5SDimitry Andric bits<4> Rn; 49890b57cec5SDimitry Andric bits<12> shift; 49900b57cec5SDimitry Andric let Inst{25} = 0; 49910b57cec5SDimitry Andric let Inst{20} = 1; 49920b57cec5SDimitry Andric let Inst{19-16} = Rn; 49930b57cec5SDimitry Andric let Inst{15-12} = 0b0000; 49940b57cec5SDimitry Andric let Inst{11-8} = shift{11-8}; 49950b57cec5SDimitry Andric let Inst{7} = 0; 49960b57cec5SDimitry Andric let Inst{6-5} = shift{6-5}; 49970b57cec5SDimitry Andric let Inst{4} = 1; 49980b57cec5SDimitry Andric let Inst{3-0} = shift{3-0}; 49990b57cec5SDimitry Andric 50000b57cec5SDimitry Andric let Unpredictable{15-12} = 0b1111; 50010b57cec5SDimitry Andric} 50020b57cec5SDimitry Andric 50030b57cec5SDimitry Andric} 50040b57cec5SDimitry Andric 50050b57cec5SDimitry Andricdef : ARMPat<(ARMcmp GPR:$src, mod_imm_neg:$imm), 50060b57cec5SDimitry Andric (CMNri GPR:$src, mod_imm_neg:$imm)>; 50070b57cec5SDimitry Andric 50080b57cec5SDimitry Andricdef : ARMPat<(ARMcmpZ GPR:$src, mod_imm_neg:$imm), 50090b57cec5SDimitry Andric (CMNri GPR:$src, mod_imm_neg:$imm)>; 50100b57cec5SDimitry Andric 50110b57cec5SDimitry Andric// Note that TST/TEQ don't set all the same flags that CMP does! 50120b57cec5SDimitry Andricdefm TST : AI1_cmp_irs<0b1000, "tst", 50130b57cec5SDimitry Andric IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 50140b57cec5SDimitry Andric BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1, 50150b57cec5SDimitry Andric "DecodeTSTInstruction">; 50160b57cec5SDimitry Andricdefm TEQ : AI1_cmp_irs<0b1001, "teq", 50170b57cec5SDimitry Andric IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 50180b57cec5SDimitry Andric BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>; 50190b57cec5SDimitry Andric 50200b57cec5SDimitry Andric// Pseudo i64 compares for some floating point compares. 50210b57cec5SDimitry Andriclet usesCustomInserter = 1, isBranch = 1, isTerminator = 1, 50220b57cec5SDimitry Andric Defs = [CPSR] in { 50230b57cec5SDimitry Andricdef BCCi64 : PseudoInst<(outs), 50240b57cec5SDimitry Andric (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst), 50250b57cec5SDimitry Andric IIC_Br, 50260b57cec5SDimitry Andric [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>, 50270b57cec5SDimitry Andric Sched<[WriteBr]>; 50280b57cec5SDimitry Andric 50290b57cec5SDimitry Andricdef BCCZi64 : PseudoInst<(outs), 50300b57cec5SDimitry Andric (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, 50310b57cec5SDimitry Andric [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>, 50320b57cec5SDimitry Andric Sched<[WriteBr]>; 50330b57cec5SDimitry Andric} // usesCustomInserter 50340b57cec5SDimitry Andric 50350b57cec5SDimitry Andric 50360b57cec5SDimitry Andric// Conditional moves 50370b57cec5SDimitry Andriclet hasSideEffects = 0 in { 50380b57cec5SDimitry Andric 50390b57cec5SDimitry Andriclet isCommutable = 1, isSelect = 1 in 50400b57cec5SDimitry Andricdef MOVCCr : ARMPseudoInst<(outs GPR:$Rd), 50410b57cec5SDimitry Andric (ins GPR:$false, GPR:$Rm, cmovpred:$p), 50420b57cec5SDimitry Andric 4, IIC_iCMOVr, 50430b57cec5SDimitry Andric [(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, 50440b57cec5SDimitry Andric cmovpred:$p))]>, 50450b57cec5SDimitry Andric RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 50460b57cec5SDimitry Andric 50470b57cec5SDimitry Andricdef MOVCCsi : ARMPseudoInst<(outs GPR:$Rd), 50480b57cec5SDimitry Andric (ins GPR:$false, so_reg_imm:$shift, cmovpred:$p), 50490b57cec5SDimitry Andric 4, IIC_iCMOVsr, 50500b57cec5SDimitry Andric [(set GPR:$Rd, 50510b57cec5SDimitry Andric (ARMcmov GPR:$false, so_reg_imm:$shift, 50520b57cec5SDimitry Andric cmovpred:$p))]>, 50530b57cec5SDimitry Andric RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 50540b57cec5SDimitry Andricdef MOVCCsr : ARMPseudoInst<(outs GPR:$Rd), 50550b57cec5SDimitry Andric (ins GPR:$false, so_reg_reg:$shift, cmovpred:$p), 50560b57cec5SDimitry Andric 4, IIC_iCMOVsr, 50570b57cec5SDimitry Andric [(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift, 50580b57cec5SDimitry Andric cmovpred:$p))]>, 50590b57cec5SDimitry Andric RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 50600b57cec5SDimitry Andric 50610b57cec5SDimitry Andric 50620b57cec5SDimitry Andriclet isMoveImm = 1 in 50630b57cec5SDimitry Andricdef MOVCCi16 50640b57cec5SDimitry Andric : ARMPseudoInst<(outs GPR:$Rd), 50650b57cec5SDimitry Andric (ins GPR:$false, imm0_65535_expr:$imm, cmovpred:$p), 50660b57cec5SDimitry Andric 4, IIC_iMOVi, 50670b57cec5SDimitry Andric [(set GPR:$Rd, (ARMcmov GPR:$false, imm0_65535:$imm, 50680b57cec5SDimitry Andric cmovpred:$p))]>, 50690b57cec5SDimitry Andric RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>, 50700b57cec5SDimitry Andric Sched<[WriteALU]>; 50710b57cec5SDimitry Andric 50720b57cec5SDimitry Andriclet isMoveImm = 1 in 50730b57cec5SDimitry Andricdef MOVCCi : ARMPseudoInst<(outs GPR:$Rd), 50740b57cec5SDimitry Andric (ins GPR:$false, mod_imm:$imm, cmovpred:$p), 50750b57cec5SDimitry Andric 4, IIC_iCMOVi, 50760b57cec5SDimitry Andric [(set GPR:$Rd, (ARMcmov GPR:$false, mod_imm:$imm, 50770b57cec5SDimitry Andric cmovpred:$p))]>, 50780b57cec5SDimitry Andric RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 50790b57cec5SDimitry Andric 50800b57cec5SDimitry Andric// Two instruction predicate mov immediate. 50810b57cec5SDimitry Andriclet isMoveImm = 1 in 50820b57cec5SDimitry Andricdef MOVCCi32imm 50830b57cec5SDimitry Andric : ARMPseudoInst<(outs GPR:$Rd), 50840b57cec5SDimitry Andric (ins GPR:$false, i32imm:$src, cmovpred:$p), 50850b57cec5SDimitry Andric 8, IIC_iCMOVix2, 50860b57cec5SDimitry Andric [(set GPR:$Rd, (ARMcmov GPR:$false, imm:$src, 50870b57cec5SDimitry Andric cmovpred:$p))]>, 50880b57cec5SDimitry Andric RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>; 50890b57cec5SDimitry Andric 50900b57cec5SDimitry Andriclet isMoveImm = 1 in 50910b57cec5SDimitry Andricdef MVNCCi : ARMPseudoInst<(outs GPR:$Rd), 50920b57cec5SDimitry Andric (ins GPR:$false, mod_imm:$imm, cmovpred:$p), 50930b57cec5SDimitry Andric 4, IIC_iCMOVi, 50940b57cec5SDimitry Andric [(set GPR:$Rd, (ARMcmov GPR:$false, mod_imm_not:$imm, 50950b57cec5SDimitry Andric cmovpred:$p))]>, 50960b57cec5SDimitry Andric RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 50970b57cec5SDimitry Andric 50980b57cec5SDimitry Andric} // hasSideEffects 50990b57cec5SDimitry Andric 51000b57cec5SDimitry Andric 51010b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 51020b57cec5SDimitry Andric// Atomic operations intrinsics 51030b57cec5SDimitry Andric// 51040b57cec5SDimitry Andric 51050b57cec5SDimitry Andricdef MemBarrierOptOperand : AsmOperandClass { 51060b57cec5SDimitry Andric let Name = "MemBarrierOpt"; 51070b57cec5SDimitry Andric let ParserMethod = "parseMemBarrierOptOperand"; 51080b57cec5SDimitry Andric} 51090b57cec5SDimitry Andricdef memb_opt : Operand<i32> { 51100b57cec5SDimitry Andric let PrintMethod = "printMemBOption"; 51110b57cec5SDimitry Andric let ParserMatchClass = MemBarrierOptOperand; 51120b57cec5SDimitry Andric let DecoderMethod = "DecodeMemBarrierOption"; 51130b57cec5SDimitry Andric} 51140b57cec5SDimitry Andric 51150b57cec5SDimitry Andricdef InstSyncBarrierOptOperand : AsmOperandClass { 51160b57cec5SDimitry Andric let Name = "InstSyncBarrierOpt"; 51170b57cec5SDimitry Andric let ParserMethod = "parseInstSyncBarrierOptOperand"; 51180b57cec5SDimitry Andric} 51190b57cec5SDimitry Andricdef instsyncb_opt : Operand<i32> { 51200b57cec5SDimitry Andric let PrintMethod = "printInstSyncBOption"; 51210b57cec5SDimitry Andric let ParserMatchClass = InstSyncBarrierOptOperand; 51220b57cec5SDimitry Andric let DecoderMethod = "DecodeInstSyncBarrierOption"; 51230b57cec5SDimitry Andric} 51240b57cec5SDimitry Andric 51250b57cec5SDimitry Andricdef TraceSyncBarrierOptOperand : AsmOperandClass { 51260b57cec5SDimitry Andric let Name = "TraceSyncBarrierOpt"; 51270b57cec5SDimitry Andric let ParserMethod = "parseTraceSyncBarrierOptOperand"; 51280b57cec5SDimitry Andric} 51290b57cec5SDimitry Andricdef tsb_opt : Operand<i32> { 51300b57cec5SDimitry Andric let PrintMethod = "printTraceSyncBOption"; 51310b57cec5SDimitry Andric let ParserMatchClass = TraceSyncBarrierOptOperand; 51320b57cec5SDimitry Andric} 51330b57cec5SDimitry Andric 51340b57cec5SDimitry Andric// Memory barriers protect the atomic sequences 51350b57cec5SDimitry Andriclet hasSideEffects = 1 in { 51360b57cec5SDimitry Andricdef DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 51370b57cec5SDimitry Andric "dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>, 51380b57cec5SDimitry Andric Requires<[IsARM, HasDB]> { 51390b57cec5SDimitry Andric bits<4> opt; 51400b57cec5SDimitry Andric let Inst{31-4} = 0xf57ff05; 51410b57cec5SDimitry Andric let Inst{3-0} = opt; 51420b57cec5SDimitry Andric} 51430b57cec5SDimitry Andric 51440b57cec5SDimitry Andricdef DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 51450b57cec5SDimitry Andric "dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>, 51460b57cec5SDimitry Andric Requires<[IsARM, HasDB]> { 51470b57cec5SDimitry Andric bits<4> opt; 51480b57cec5SDimitry Andric let Inst{31-4} = 0xf57ff04; 51490b57cec5SDimitry Andric let Inst{3-0} = opt; 51500b57cec5SDimitry Andric} 51510b57cec5SDimitry Andric 51520b57cec5SDimitry Andric// ISB has only full system option 51530b57cec5SDimitry Andricdef ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary, 51540b57cec5SDimitry Andric "isb", "\t$opt", [(int_arm_isb (i32 imm0_15:$opt))]>, 51550b57cec5SDimitry Andric Requires<[IsARM, HasDB]> { 51560b57cec5SDimitry Andric bits<4> opt; 51570b57cec5SDimitry Andric let Inst{31-4} = 0xf57ff06; 51580b57cec5SDimitry Andric let Inst{3-0} = opt; 51590b57cec5SDimitry Andric} 51600b57cec5SDimitry Andric 51610b57cec5SDimitry Andriclet hasNoSchedulingInfo = 1 in 51620b57cec5SDimitry Andricdef TSB : AInoP<(outs), (ins tsb_opt:$opt), MiscFrm, NoItinerary, 51630b57cec5SDimitry Andric "tsb", "\t$opt", []>, Requires<[IsARM, HasV8_4a]> { 51640b57cec5SDimitry Andric let Inst{31-0} = 0xe320f012; 516581ad6265SDimitry Andric let DecoderMethod = "DecodeTSBInstruction"; 51660b57cec5SDimitry Andric} 51670b57cec5SDimitry Andric 51680b57cec5SDimitry Andric} 51690b57cec5SDimitry Andric 51700b57cec5SDimitry Andric// Armv8.5-A speculation barrier 51710b57cec5SDimitry Andricdef SB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "sb", "", []>, 51720b57cec5SDimitry Andric Requires<[IsARM, HasSB]>, Sched<[]> { 51730b57cec5SDimitry Andric let Inst{31-0} = 0xf57ff070; 51740b57cec5SDimitry Andric let Unpredictable = 0x000fff0f; 51750b57cec5SDimitry Andric let hasSideEffects = 1; 51760b57cec5SDimitry Andric} 51770b57cec5SDimitry Andric 51788bcb0991SDimitry Andriclet usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in { 51790b57cec5SDimitry Andric // Pseudo instruction that combines movs + predicated rsbmi 51800b57cec5SDimitry Andric // to implement integer ABS 51810b57cec5SDimitry Andric def ABS : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$src), 8, NoItinerary, []>; 51820b57cec5SDimitry Andric} 51830b57cec5SDimitry Andric 51848bcb0991SDimitry Andriclet usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in { 51850b57cec5SDimitry Andric def COPY_STRUCT_BYVAL_I32 : PseudoInst< 51860b57cec5SDimitry Andric (outs), (ins GPR:$dst, GPR:$src, i32imm:$size, i32imm:$alignment), 51870b57cec5SDimitry Andric NoItinerary, 51880b57cec5SDimitry Andric [(ARMcopystructbyval GPR:$dst, GPR:$src, imm:$size, imm:$alignment)]>; 51890b57cec5SDimitry Andric} 51900b57cec5SDimitry Andric 51910b57cec5SDimitry Andriclet hasPostISelHook = 1, Constraints = "$newdst = $dst, $newsrc = $src" in { 51920b57cec5SDimitry Andric // %newsrc, %newdst = MEMCPY %dst, %src, N, ...N scratch regs... 51930b57cec5SDimitry Andric // Copies N registers worth of memory from address %src to address %dst 51940b57cec5SDimitry Andric // and returns the incremented addresses. N scratch register will 51950b57cec5SDimitry Andric // be attached for the copy to use. 51960b57cec5SDimitry Andric def MEMCPY : PseudoInst< 51970b57cec5SDimitry Andric (outs GPR:$newdst, GPR:$newsrc), 51980b57cec5SDimitry Andric (ins GPR:$dst, GPR:$src, i32imm:$nreg, variable_ops), 51990b57cec5SDimitry Andric NoItinerary, 52000b57cec5SDimitry Andric [(set GPR:$newdst, GPR:$newsrc, 52010b57cec5SDimitry Andric (ARMmemcopy GPR:$dst, GPR:$src, imm:$nreg))]>; 52020b57cec5SDimitry Andric} 52030b57cec5SDimitry Andric 52040b57cec5SDimitry Andricdef ldrex_1 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 52050b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 52060b57cec5SDimitry Andric}]>; 52070b57cec5SDimitry Andric 52080b57cec5SDimitry Andricdef ldrex_2 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 52090b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 52100b57cec5SDimitry Andric}]>; 52110b57cec5SDimitry Andric 52120b57cec5SDimitry Andricdef ldrex_4 : PatFrag<(ops node:$ptr), (int_arm_ldrex node:$ptr), [{ 52130b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 52140b57cec5SDimitry Andric}]>; 52150b57cec5SDimitry Andric 52160b57cec5SDimitry Andricdef strex_1 : PatFrag<(ops node:$val, node:$ptr), 52170b57cec5SDimitry Andric (int_arm_strex node:$val, node:$ptr), [{ 52180b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 52190b57cec5SDimitry Andric}]>; 52200b57cec5SDimitry Andric 52210b57cec5SDimitry Andricdef strex_2 : PatFrag<(ops node:$val, node:$ptr), 52220b57cec5SDimitry Andric (int_arm_strex node:$val, node:$ptr), [{ 52230b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 52240b57cec5SDimitry Andric}]>; 52250b57cec5SDimitry Andric 52260b57cec5SDimitry Andricdef strex_4 : PatFrag<(ops node:$val, node:$ptr), 52270b57cec5SDimitry Andric (int_arm_strex node:$val, node:$ptr), [{ 52280b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 52290b57cec5SDimitry Andric}]>; 52300b57cec5SDimitry Andric 52310b57cec5SDimitry Andricdef ldaex_1 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{ 52320b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 52330b57cec5SDimitry Andric}]>; 52340b57cec5SDimitry Andric 52350b57cec5SDimitry Andricdef ldaex_2 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{ 52360b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 52370b57cec5SDimitry Andric}]>; 52380b57cec5SDimitry Andric 52390b57cec5SDimitry Andricdef ldaex_4 : PatFrag<(ops node:$ptr), (int_arm_ldaex node:$ptr), [{ 52400b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 52410b57cec5SDimitry Andric}]>; 52420b57cec5SDimitry Andric 52430b57cec5SDimitry Andricdef stlex_1 : PatFrag<(ops node:$val, node:$ptr), 52440b57cec5SDimitry Andric (int_arm_stlex node:$val, node:$ptr), [{ 52450b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 52460b57cec5SDimitry Andric}]>; 52470b57cec5SDimitry Andric 52480b57cec5SDimitry Andricdef stlex_2 : PatFrag<(ops node:$val, node:$ptr), 52490b57cec5SDimitry Andric (int_arm_stlex node:$val, node:$ptr), [{ 52500b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 52510b57cec5SDimitry Andric}]>; 52520b57cec5SDimitry Andric 52530b57cec5SDimitry Andricdef stlex_4 : PatFrag<(ops node:$val, node:$ptr), 52540b57cec5SDimitry Andric (int_arm_stlex node:$val, node:$ptr), [{ 52550b57cec5SDimitry Andric return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 52560b57cec5SDimitry Andric}]>; 52570b57cec5SDimitry Andric 52580b57cec5SDimitry Andriclet mayLoad = 1 in { 52590b57cec5SDimitry Andricdef LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 52600b57cec5SDimitry Andric NoItinerary, "ldrexb", "\t$Rt, $addr", 52610b57cec5SDimitry Andric [(set GPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>; 52620b57cec5SDimitry Andricdef LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 52630b57cec5SDimitry Andric NoItinerary, "ldrexh", "\t$Rt, $addr", 52640b57cec5SDimitry Andric [(set GPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>; 52650b57cec5SDimitry Andricdef LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 52660b57cec5SDimitry Andric NoItinerary, "ldrex", "\t$Rt, $addr", 52670b57cec5SDimitry Andric [(set GPR:$Rt, (ldrex_4 addr_offset_none:$addr))]>; 52680b57cec5SDimitry Andriclet hasExtraDefRegAllocReq = 1 in 52690b57cec5SDimitry Andricdef LDREXD : AIldrex<0b01, (outs GPRPairOp:$Rt),(ins addr_offset_none:$addr), 52700b57cec5SDimitry Andric NoItinerary, "ldrexd", "\t$Rt, $addr", []> { 52710b57cec5SDimitry Andric let DecoderMethod = "DecodeDoubleRegLoad"; 52720b57cec5SDimitry Andric} 52730b57cec5SDimitry Andric 52740b57cec5SDimitry Andricdef LDAEXB : AIldaex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), 52750b57cec5SDimitry Andric NoItinerary, "ldaexb", "\t$Rt, $addr", 52760b57cec5SDimitry Andric [(set GPR:$Rt, (ldaex_1 addr_offset_none:$addr))]>; 52770b57cec5SDimitry Andricdef LDAEXH : AIldaex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), 52780b57cec5SDimitry Andric NoItinerary, "ldaexh", "\t$Rt, $addr", 52790b57cec5SDimitry Andric [(set GPR:$Rt, (ldaex_2 addr_offset_none:$addr))]>; 52800b57cec5SDimitry Andricdef LDAEX : AIldaex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), 52810b57cec5SDimitry Andric NoItinerary, "ldaex", "\t$Rt, $addr", 52820b57cec5SDimitry Andric [(set GPR:$Rt, (ldaex_4 addr_offset_none:$addr))]>; 52830b57cec5SDimitry Andriclet hasExtraDefRegAllocReq = 1 in 52840b57cec5SDimitry Andricdef LDAEXD : AIldaex<0b01, (outs GPRPairOp:$Rt),(ins addr_offset_none:$addr), 52850b57cec5SDimitry Andric NoItinerary, "ldaexd", "\t$Rt, $addr", []> { 52860b57cec5SDimitry Andric let DecoderMethod = "DecodeDoubleRegLoad"; 52870b57cec5SDimitry Andric} 52880b57cec5SDimitry Andric} 52890b57cec5SDimitry Andric 52900b57cec5SDimitry Andriclet mayStore = 1, Constraints = "@earlyclobber $Rd" in { 52910b57cec5SDimitry Andricdef STREXB: AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 52920b57cec5SDimitry Andric NoItinerary, "strexb", "\t$Rd, $Rt, $addr", 52930b57cec5SDimitry Andric [(set GPR:$Rd, (strex_1 GPR:$Rt, 52940b57cec5SDimitry Andric addr_offset_none:$addr))]>; 52950b57cec5SDimitry Andricdef STREXH: AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 52960b57cec5SDimitry Andric NoItinerary, "strexh", "\t$Rd, $Rt, $addr", 52970b57cec5SDimitry Andric [(set GPR:$Rd, (strex_2 GPR:$Rt, 52980b57cec5SDimitry Andric addr_offset_none:$addr))]>; 52990b57cec5SDimitry Andricdef STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 53000b57cec5SDimitry Andric NoItinerary, "strex", "\t$Rd, $Rt, $addr", 53010b57cec5SDimitry Andric [(set GPR:$Rd, (strex_4 GPR:$Rt, 53020b57cec5SDimitry Andric addr_offset_none:$addr))]>; 53030b57cec5SDimitry Andriclet hasExtraSrcRegAllocReq = 1 in 53040b57cec5SDimitry Andricdef STREXD : AIstrex<0b01, (outs GPR:$Rd), 53050b57cec5SDimitry Andric (ins GPRPairOp:$Rt, addr_offset_none:$addr), 53060b57cec5SDimitry Andric NoItinerary, "strexd", "\t$Rd, $Rt, $addr", []> { 53070b57cec5SDimitry Andric let DecoderMethod = "DecodeDoubleRegStore"; 53080b57cec5SDimitry Andric} 53090b57cec5SDimitry Andricdef STLEXB: AIstlex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 53100b57cec5SDimitry Andric NoItinerary, "stlexb", "\t$Rd, $Rt, $addr", 53110b57cec5SDimitry Andric [(set GPR:$Rd, 53120b57cec5SDimitry Andric (stlex_1 GPR:$Rt, addr_offset_none:$addr))]>; 53130b57cec5SDimitry Andricdef STLEXH: AIstlex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 53140b57cec5SDimitry Andric NoItinerary, "stlexh", "\t$Rd, $Rt, $addr", 53150b57cec5SDimitry Andric [(set GPR:$Rd, 53160b57cec5SDimitry Andric (stlex_2 GPR:$Rt, addr_offset_none:$addr))]>; 53170b57cec5SDimitry Andricdef STLEX : AIstlex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), 53180b57cec5SDimitry Andric NoItinerary, "stlex", "\t$Rd, $Rt, $addr", 53190b57cec5SDimitry Andric [(set GPR:$Rd, 53200b57cec5SDimitry Andric (stlex_4 GPR:$Rt, addr_offset_none:$addr))]>; 53210b57cec5SDimitry Andriclet hasExtraSrcRegAllocReq = 1 in 53220b57cec5SDimitry Andricdef STLEXD : AIstlex<0b01, (outs GPR:$Rd), 53230b57cec5SDimitry Andric (ins GPRPairOp:$Rt, addr_offset_none:$addr), 53240b57cec5SDimitry Andric NoItinerary, "stlexd", "\t$Rd, $Rt, $addr", []> { 53250b57cec5SDimitry Andric let DecoderMethod = "DecodeDoubleRegStore"; 53260b57cec5SDimitry Andric} 53270b57cec5SDimitry Andric} 53280b57cec5SDimitry Andric 53290b57cec5SDimitry Andricdef CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", 53300b57cec5SDimitry Andric [(int_arm_clrex)]>, 53310b57cec5SDimitry Andric Requires<[IsARM, HasV6K]> { 53320b57cec5SDimitry Andric let Inst{31-0} = 0b11110101011111111111000000011111; 53330b57cec5SDimitry Andric} 53340b57cec5SDimitry Andric 53350b57cec5SDimitry Andricdef : ARMPat<(strex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr), 53360b57cec5SDimitry Andric (STREXB GPR:$Rt, addr_offset_none:$addr)>; 53370b57cec5SDimitry Andricdef : ARMPat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), 53380b57cec5SDimitry Andric (STREXH GPR:$Rt, addr_offset_none:$addr)>; 53390b57cec5SDimitry Andric 53400b57cec5SDimitry Andricdef : ARMPat<(stlex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr), 53410b57cec5SDimitry Andric (STLEXB GPR:$Rt, addr_offset_none:$addr)>; 53420b57cec5SDimitry Andricdef : ARMPat<(stlex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), 53430b57cec5SDimitry Andric (STLEXH GPR:$Rt, addr_offset_none:$addr)>; 53440b57cec5SDimitry Andric 53450b57cec5SDimitry Andricclass acquiring_load<PatFrag base> 53460b57cec5SDimitry Andric : PatFrag<(ops node:$ptr), (base node:$ptr), [{ 5347fe6060f1SDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering(); 53480b57cec5SDimitry Andric return isAcquireOrStronger(Ordering); 53490b57cec5SDimitry Andric}]>; 53500b57cec5SDimitry Andric 53510b57cec5SDimitry Andricdef atomic_load_acquire_8 : acquiring_load<atomic_load_8>; 53520b57cec5SDimitry Andricdef atomic_load_acquire_16 : acquiring_load<atomic_load_16>; 53530b57cec5SDimitry Andricdef atomic_load_acquire_32 : acquiring_load<atomic_load_32>; 53540b57cec5SDimitry Andric 53550b57cec5SDimitry Andricclass releasing_store<PatFrag base> 53565f757f3fSDimitry Andric : PatFrag<(ops node:$ptr, node:$val), (base node:$val, node:$ptr), [{ 5357fe6060f1SDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering(); 53580b57cec5SDimitry Andric return isReleaseOrStronger(Ordering); 53590b57cec5SDimitry Andric}]>; 53600b57cec5SDimitry Andric 53610b57cec5SDimitry Andricdef atomic_store_release_8 : releasing_store<atomic_store_8>; 53620b57cec5SDimitry Andricdef atomic_store_release_16 : releasing_store<atomic_store_16>; 53630b57cec5SDimitry Andricdef atomic_store_release_32 : releasing_store<atomic_store_32>; 53640b57cec5SDimitry Andric 53650b57cec5SDimitry Andriclet AddedComplexity = 8 in { 53660b57cec5SDimitry Andric def : ARMPat<(atomic_load_acquire_8 addr_offset_none:$addr), (LDAB addr_offset_none:$addr)>; 53670b57cec5SDimitry Andric def : ARMPat<(atomic_load_acquire_16 addr_offset_none:$addr), (LDAH addr_offset_none:$addr)>; 53680b57cec5SDimitry Andric def : ARMPat<(atomic_load_acquire_32 addr_offset_none:$addr), (LDA addr_offset_none:$addr)>; 53690b57cec5SDimitry Andric def : ARMPat<(atomic_store_release_8 addr_offset_none:$addr, GPR:$val), (STLB GPR:$val, addr_offset_none:$addr)>; 53700b57cec5SDimitry Andric def : ARMPat<(atomic_store_release_16 addr_offset_none:$addr, GPR:$val), (STLH GPR:$val, addr_offset_none:$addr)>; 53710b57cec5SDimitry Andric def : ARMPat<(atomic_store_release_32 addr_offset_none:$addr, GPR:$val), (STL GPR:$val, addr_offset_none:$addr)>; 53720b57cec5SDimitry Andric} 53730b57cec5SDimitry Andric 53740b57cec5SDimitry Andric// SWP/SWPB are deprecated in V6/V7 and optional in v7VE. 53750b57cec5SDimitry Andric// FIXME Use InstAlias to generate LDREX/STREX pairs instead. 53760b57cec5SDimitry Andriclet mayLoad = 1, mayStore = 1 in { 53770b57cec5SDimitry Andricdef SWP : AIswp<0, (outs GPRnopc:$Rt), 53780b57cec5SDimitry Andric (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swp", []>, 53790b57cec5SDimitry Andric Requires<[IsARM,PreV8]>; 53800b57cec5SDimitry Andricdef SWPB: AIswp<1, (outs GPRnopc:$Rt), 53810b57cec5SDimitry Andric (ins GPRnopc:$Rt2, addr_offset_none:$addr), "swpb", []>, 53820b57cec5SDimitry Andric Requires<[IsARM,PreV8]>; 53830b57cec5SDimitry Andric} 53840b57cec5SDimitry Andric 53850b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 53860b57cec5SDimitry Andric// Coprocessor Instructions. 53870b57cec5SDimitry Andric// 53880b57cec5SDimitry Andric 53890b57cec5SDimitry Andricdef CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 53900b57cec5SDimitry Andric c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 53910b57cec5SDimitry Andric NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 53928bcb0991SDimitry Andric [(int_arm_cdp timm:$cop, timm:$opc1, timm:$CRd, timm:$CRn, 53938bcb0991SDimitry Andric timm:$CRm, timm:$opc2)]>, 53940b57cec5SDimitry Andric Requires<[IsARM,PreV8]> { 53950b57cec5SDimitry Andric bits<4> opc1; 53960b57cec5SDimitry Andric bits<4> CRn; 53970b57cec5SDimitry Andric bits<4> CRd; 53980b57cec5SDimitry Andric bits<4> cop; 53990b57cec5SDimitry Andric bits<3> opc2; 54000b57cec5SDimitry Andric bits<4> CRm; 54010b57cec5SDimitry Andric 54020b57cec5SDimitry Andric let Inst{3-0} = CRm; 54030b57cec5SDimitry Andric let Inst{4} = 0; 54040b57cec5SDimitry Andric let Inst{7-5} = opc2; 54050b57cec5SDimitry Andric let Inst{11-8} = cop; 54060b57cec5SDimitry Andric let Inst{15-12} = CRd; 54070b57cec5SDimitry Andric let Inst{19-16} = CRn; 54080b57cec5SDimitry Andric let Inst{23-20} = opc1; 54090b57cec5SDimitry Andric 54100b57cec5SDimitry Andric let DecoderNamespace = "CoProc"; 54110b57cec5SDimitry Andric} 54120b57cec5SDimitry Andric 54130b57cec5SDimitry Andricdef CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 54140b57cec5SDimitry Andric c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 54150b57cec5SDimitry Andric NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 54168bcb0991SDimitry Andric [(int_arm_cdp2 timm:$cop, timm:$opc1, timm:$CRd, timm:$CRn, 54178bcb0991SDimitry Andric timm:$CRm, timm:$opc2)]>, 54180b57cec5SDimitry Andric Requires<[IsARM,PreV8]> { 54190b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 54200b57cec5SDimitry Andric bits<4> opc1; 54210b57cec5SDimitry Andric bits<4> CRn; 54220b57cec5SDimitry Andric bits<4> CRd; 54230b57cec5SDimitry Andric bits<4> cop; 54240b57cec5SDimitry Andric bits<3> opc2; 54250b57cec5SDimitry Andric bits<4> CRm; 54260b57cec5SDimitry Andric 54270b57cec5SDimitry Andric let Inst{3-0} = CRm; 54280b57cec5SDimitry Andric let Inst{4} = 0; 54290b57cec5SDimitry Andric let Inst{7-5} = opc2; 54300b57cec5SDimitry Andric let Inst{11-8} = cop; 54310b57cec5SDimitry Andric let Inst{15-12} = CRd; 54320b57cec5SDimitry Andric let Inst{19-16} = CRn; 54330b57cec5SDimitry Andric let Inst{23-20} = opc1; 54340b57cec5SDimitry Andric 54350b57cec5SDimitry Andric let DecoderNamespace = "CoProc"; 54360b57cec5SDimitry Andric} 54370b57cec5SDimitry Andric 54380b57cec5SDimitry Andricclass ACI<dag oops, dag iops, string opc, string asm, 5439349cc55cSDimitry Andric list<dag> pattern, IndexMode im = IndexModeNone, 5440349cc55cSDimitry Andric AddrMode am = AddrModeNone> 5441349cc55cSDimitry Andric : I<oops, iops, am, 4, im, BrFrm, NoItinerary, 54420b57cec5SDimitry Andric opc, asm, "", pattern> { 54430b57cec5SDimitry Andric let Inst{27-25} = 0b110; 54440b57cec5SDimitry Andric} 54450b57cec5SDimitry Andricclass ACInoP<dag oops, dag iops, string opc, string asm, 5446349cc55cSDimitry Andric list<dag> pattern, IndexMode im = IndexModeNone, 5447349cc55cSDimitry Andric AddrMode am = AddrModeNone> 5448349cc55cSDimitry Andric : InoP<oops, iops, am, 4, im, BrFrm, NoItinerary, 54490b57cec5SDimitry Andric opc, asm, "", pattern> { 54500b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 54510b57cec5SDimitry Andric let Inst{27-25} = 0b110; 54520b57cec5SDimitry Andric} 54530b57cec5SDimitry Andric 54540b57cec5SDimitry Andriclet DecoderNamespace = "CoProc" in { 54550b57cec5SDimitry Andricmulticlass LdStCop<bit load, bit Dbit, string asm, list<dag> pattern> { 54560b57cec5SDimitry Andric def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 5457349cc55cSDimitry Andric asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone, 5458349cc55cSDimitry Andric AddrMode5> { 54590b57cec5SDimitry Andric bits<13> addr; 54600b57cec5SDimitry Andric bits<4> cop; 54610b57cec5SDimitry Andric bits<4> CRd; 54620b57cec5SDimitry Andric let Inst{24} = 1; // P = 1 54630b57cec5SDimitry Andric let Inst{23} = addr{8}; 54640b57cec5SDimitry Andric let Inst{22} = Dbit; 54650b57cec5SDimitry Andric let Inst{21} = 0; // W = 0 54660b57cec5SDimitry Andric let Inst{20} = load; 54670b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; 54680b57cec5SDimitry Andric let Inst{15-12} = CRd; 54690b57cec5SDimitry Andric let Inst{11-8} = cop; 54700b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; 54710b57cec5SDimitry Andric let DecoderMethod = "DecodeCopMemInstruction"; 54720b57cec5SDimitry Andric } 54730b57cec5SDimitry Andric def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), 54740b57cec5SDimitry Andric asm, "\t$cop, $CRd, $addr!", [], IndexModePre> { 54750b57cec5SDimitry Andric bits<13> addr; 54760b57cec5SDimitry Andric bits<4> cop; 54770b57cec5SDimitry Andric bits<4> CRd; 54780b57cec5SDimitry Andric let Inst{24} = 1; // P = 1 54790b57cec5SDimitry Andric let Inst{23} = addr{8}; 54800b57cec5SDimitry Andric let Inst{22} = Dbit; 54810b57cec5SDimitry Andric let Inst{21} = 1; // W = 1 54820b57cec5SDimitry Andric let Inst{20} = load; 54830b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; 54840b57cec5SDimitry Andric let Inst{15-12} = CRd; 54850b57cec5SDimitry Andric let Inst{11-8} = cop; 54860b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; 54870b57cec5SDimitry Andric let DecoderMethod = "DecodeCopMemInstruction"; 54880b57cec5SDimitry Andric } 54890b57cec5SDimitry Andric def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 54900b57cec5SDimitry Andric postidx_imm8s4:$offset), 54910b57cec5SDimitry Andric asm, "\t$cop, $CRd, $addr, $offset", [], IndexModePost> { 54920b57cec5SDimitry Andric bits<9> offset; 54930b57cec5SDimitry Andric bits<4> addr; 54940b57cec5SDimitry Andric bits<4> cop; 54950b57cec5SDimitry Andric bits<4> CRd; 54960b57cec5SDimitry Andric let Inst{24} = 0; // P = 0 54970b57cec5SDimitry Andric let Inst{23} = offset{8}; 54980b57cec5SDimitry Andric let Inst{22} = Dbit; 54990b57cec5SDimitry Andric let Inst{21} = 1; // W = 1 55000b57cec5SDimitry Andric let Inst{20} = load; 55010b57cec5SDimitry Andric let Inst{19-16} = addr; 55020b57cec5SDimitry Andric let Inst{15-12} = CRd; 55030b57cec5SDimitry Andric let Inst{11-8} = cop; 55040b57cec5SDimitry Andric let Inst{7-0} = offset{7-0}; 55050b57cec5SDimitry Andric let DecoderMethod = "DecodeCopMemInstruction"; 55060b57cec5SDimitry Andric } 55070b57cec5SDimitry Andric def _OPTION : ACI<(outs), 55080b57cec5SDimitry Andric (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 55090b57cec5SDimitry Andric coproc_option_imm:$option), 55100b57cec5SDimitry Andric asm, "\t$cop, $CRd, $addr, $option", []> { 55110b57cec5SDimitry Andric bits<8> option; 55120b57cec5SDimitry Andric bits<4> addr; 55130b57cec5SDimitry Andric bits<4> cop; 55140b57cec5SDimitry Andric bits<4> CRd; 55150b57cec5SDimitry Andric let Inst{24} = 0; // P = 0 55160b57cec5SDimitry Andric let Inst{23} = 1; // U = 1 55170b57cec5SDimitry Andric let Inst{22} = Dbit; 55180b57cec5SDimitry Andric let Inst{21} = 0; // W = 0 55190b57cec5SDimitry Andric let Inst{20} = load; 55200b57cec5SDimitry Andric let Inst{19-16} = addr; 55210b57cec5SDimitry Andric let Inst{15-12} = CRd; 55220b57cec5SDimitry Andric let Inst{11-8} = cop; 55230b57cec5SDimitry Andric let Inst{7-0} = option; 55240b57cec5SDimitry Andric let DecoderMethod = "DecodeCopMemInstruction"; 55250b57cec5SDimitry Andric } 55260b57cec5SDimitry Andric} 55270b57cec5SDimitry Andricmulticlass LdSt2Cop<bit load, bit Dbit, string asm, list<dag> pattern> { 55280b57cec5SDimitry Andric def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 5529349cc55cSDimitry Andric asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone, 5530349cc55cSDimitry Andric AddrMode5> { 55310b57cec5SDimitry Andric bits<13> addr; 55320b57cec5SDimitry Andric bits<4> cop; 55330b57cec5SDimitry Andric bits<4> CRd; 55340b57cec5SDimitry Andric let Inst{24} = 1; // P = 1 55350b57cec5SDimitry Andric let Inst{23} = addr{8}; 55360b57cec5SDimitry Andric let Inst{22} = Dbit; 55370b57cec5SDimitry Andric let Inst{21} = 0; // W = 0 55380b57cec5SDimitry Andric let Inst{20} = load; 55390b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; 55400b57cec5SDimitry Andric let Inst{15-12} = CRd; 55410b57cec5SDimitry Andric let Inst{11-8} = cop; 55420b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; 55430b57cec5SDimitry Andric let DecoderMethod = "DecodeCopMemInstruction"; 55440b57cec5SDimitry Andric } 55450b57cec5SDimitry Andric def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), 55460b57cec5SDimitry Andric asm, "\t$cop, $CRd, $addr!", [], IndexModePre> { 55470b57cec5SDimitry Andric bits<13> addr; 55480b57cec5SDimitry Andric bits<4> cop; 55490b57cec5SDimitry Andric bits<4> CRd; 55500b57cec5SDimitry Andric let Inst{24} = 1; // P = 1 55510b57cec5SDimitry Andric let Inst{23} = addr{8}; 55520b57cec5SDimitry Andric let Inst{22} = Dbit; 55530b57cec5SDimitry Andric let Inst{21} = 1; // W = 1 55540b57cec5SDimitry Andric let Inst{20} = load; 55550b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; 55560b57cec5SDimitry Andric let Inst{15-12} = CRd; 55570b57cec5SDimitry Andric let Inst{11-8} = cop; 55580b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; 55590b57cec5SDimitry Andric let DecoderMethod = "DecodeCopMemInstruction"; 55600b57cec5SDimitry Andric } 55610b57cec5SDimitry Andric def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 55620b57cec5SDimitry Andric postidx_imm8s4:$offset), 55630b57cec5SDimitry Andric asm, "\t$cop, $CRd, $addr, $offset", [], IndexModePost> { 55640b57cec5SDimitry Andric bits<9> offset; 55650b57cec5SDimitry Andric bits<4> addr; 55660b57cec5SDimitry Andric bits<4> cop; 55670b57cec5SDimitry Andric bits<4> CRd; 55680b57cec5SDimitry Andric let Inst{24} = 0; // P = 0 55690b57cec5SDimitry Andric let Inst{23} = offset{8}; 55700b57cec5SDimitry Andric let Inst{22} = Dbit; 55710b57cec5SDimitry Andric let Inst{21} = 1; // W = 1 55720b57cec5SDimitry Andric let Inst{20} = load; 55730b57cec5SDimitry Andric let Inst{19-16} = addr; 55740b57cec5SDimitry Andric let Inst{15-12} = CRd; 55750b57cec5SDimitry Andric let Inst{11-8} = cop; 55760b57cec5SDimitry Andric let Inst{7-0} = offset{7-0}; 55770b57cec5SDimitry Andric let DecoderMethod = "DecodeCopMemInstruction"; 55780b57cec5SDimitry Andric } 55790b57cec5SDimitry Andric def _OPTION : ACInoP<(outs), 55800b57cec5SDimitry Andric (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 55810b57cec5SDimitry Andric coproc_option_imm:$option), 55820b57cec5SDimitry Andric asm, "\t$cop, $CRd, $addr, $option", []> { 55830b57cec5SDimitry Andric bits<8> option; 55840b57cec5SDimitry Andric bits<4> addr; 55850b57cec5SDimitry Andric bits<4> cop; 55860b57cec5SDimitry Andric bits<4> CRd; 55870b57cec5SDimitry Andric let Inst{24} = 0; // P = 0 55880b57cec5SDimitry Andric let Inst{23} = 1; // U = 1 55890b57cec5SDimitry Andric let Inst{22} = Dbit; 55900b57cec5SDimitry Andric let Inst{21} = 0; // W = 0 55910b57cec5SDimitry Andric let Inst{20} = load; 55920b57cec5SDimitry Andric let Inst{19-16} = addr; 55930b57cec5SDimitry Andric let Inst{15-12} = CRd; 55940b57cec5SDimitry Andric let Inst{11-8} = cop; 55950b57cec5SDimitry Andric let Inst{7-0} = option; 55960b57cec5SDimitry Andric let DecoderMethod = "DecodeCopMemInstruction"; 55970b57cec5SDimitry Andric } 55980b57cec5SDimitry Andric} 55990b57cec5SDimitry Andric 56008bcb0991SDimitry Andricdefm LDC : LdStCop <1, 0, "ldc", [(int_arm_ldc timm:$cop, timm:$CRd, addrmode5:$addr)]>; 56018bcb0991SDimitry Andricdefm LDCL : LdStCop <1, 1, "ldcl", [(int_arm_ldcl timm:$cop, timm:$CRd, addrmode5:$addr)]>; 56028bcb0991SDimitry Andricdefm LDC2 : LdSt2Cop<1, 0, "ldc2", [(int_arm_ldc2 timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; 56038bcb0991SDimitry Andricdefm LDC2L : LdSt2Cop<1, 1, "ldc2l", [(int_arm_ldc2l timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; 56040b57cec5SDimitry Andric 56058bcb0991SDimitry Andricdefm STC : LdStCop <0, 0, "stc", [(int_arm_stc timm:$cop, timm:$CRd, addrmode5:$addr)]>; 56068bcb0991SDimitry Andricdefm STCL : LdStCop <0, 1, "stcl", [(int_arm_stcl timm:$cop, timm:$CRd, addrmode5:$addr)]>; 56078bcb0991SDimitry Andricdefm STC2 : LdSt2Cop<0, 0, "stc2", [(int_arm_stc2 timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; 56088bcb0991SDimitry Andricdefm STC2L : LdSt2Cop<0, 1, "stc2l", [(int_arm_stc2l timm:$cop, timm:$CRd, addrmode5:$addr)]>, Requires<[IsARM,PreV8]>; 56090b57cec5SDimitry Andric 56100b57cec5SDimitry Andric} // DecoderNamespace = "CoProc" 56110b57cec5SDimitry Andric 56120b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 56130b57cec5SDimitry Andric// Move between coprocessor and ARM core register. 56140b57cec5SDimitry Andric// 56150b57cec5SDimitry Andric 56160b57cec5SDimitry Andricclass MovRCopro<string opc, bit direction, dag oops, dag iops, 56170b57cec5SDimitry Andric list<dag> pattern> 56180b57cec5SDimitry Andric : ABI<0b1110, oops, iops, NoItinerary, opc, 56190b57cec5SDimitry Andric "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", pattern> { 56200b57cec5SDimitry Andric let Inst{20} = direction; 56210b57cec5SDimitry Andric let Inst{4} = 1; 56220b57cec5SDimitry Andric 56230b57cec5SDimitry Andric bits<4> Rt; 56240b57cec5SDimitry Andric bits<4> cop; 56250b57cec5SDimitry Andric bits<3> opc1; 56260b57cec5SDimitry Andric bits<3> opc2; 56270b57cec5SDimitry Andric bits<4> CRm; 56280b57cec5SDimitry Andric bits<4> CRn; 56290b57cec5SDimitry Andric 56300b57cec5SDimitry Andric let Inst{15-12} = Rt; 56310b57cec5SDimitry Andric let Inst{11-8} = cop; 56320b57cec5SDimitry Andric let Inst{23-21} = opc1; 56330b57cec5SDimitry Andric let Inst{7-5} = opc2; 56340b57cec5SDimitry Andric let Inst{3-0} = CRm; 56350b57cec5SDimitry Andric let Inst{19-16} = CRn; 56360b57cec5SDimitry Andric 56370b57cec5SDimitry Andric let DecoderNamespace = "CoProc"; 56380b57cec5SDimitry Andric} 56390b57cec5SDimitry Andric 56400b57cec5SDimitry Andricdef MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */, 56410b57cec5SDimitry Andric (outs), 56420b57cec5SDimitry Andric (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 56430b57cec5SDimitry Andric c_imm:$CRm, imm0_7:$opc2), 56448bcb0991SDimitry Andric [(int_arm_mcr timm:$cop, timm:$opc1, GPR:$Rt, timm:$CRn, 56458bcb0991SDimitry Andric timm:$CRm, timm:$opc2)]>, 56460b57cec5SDimitry Andric ComplexDeprecationPredicate<"MCR">; 56470b57cec5SDimitry Andricdef : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm", 56480b57cec5SDimitry Andric (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 56490b57cec5SDimitry Andric c_imm:$CRm, 0, pred:$p)>; 56500b57cec5SDimitry Andricdef MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */, 56510b57cec5SDimitry Andric (outs GPRwithAPSR:$Rt), 56520b57cec5SDimitry Andric (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 56535ffd83dbSDimitry Andric imm0_7:$opc2), []>, 56545ffd83dbSDimitry Andric ComplexDeprecationPredicate<"MRC">; 56550b57cec5SDimitry Andricdef : ARMInstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm", 56560b57cec5SDimitry Andric (MRC GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 56570b57cec5SDimitry Andric c_imm:$CRm, 0, pred:$p)>; 56580b57cec5SDimitry Andric 56598bcb0991SDimitry Andricdef : ARMPat<(int_arm_mrc timm:$cop, timm:$opc1, timm:$CRn, timm:$CRm, timm:$opc2), 56608bcb0991SDimitry Andric (MRC p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2)>; 56610b57cec5SDimitry Andric 56620b57cec5SDimitry Andricclass MovRCopro2<string opc, bit direction, dag oops, dag iops, 56630b57cec5SDimitry Andric list<dag> pattern> 56640b57cec5SDimitry Andric : ABXI<0b1110, oops, iops, NoItinerary, 56650b57cec5SDimitry Andric !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), pattern> { 56660b57cec5SDimitry Andric let Inst{31-24} = 0b11111110; 56670b57cec5SDimitry Andric let Inst{20} = direction; 56680b57cec5SDimitry Andric let Inst{4} = 1; 56690b57cec5SDimitry Andric 56700b57cec5SDimitry Andric bits<4> Rt; 56710b57cec5SDimitry Andric bits<4> cop; 56720b57cec5SDimitry Andric bits<3> opc1; 56730b57cec5SDimitry Andric bits<3> opc2; 56740b57cec5SDimitry Andric bits<4> CRm; 56750b57cec5SDimitry Andric bits<4> CRn; 56760b57cec5SDimitry Andric 56770b57cec5SDimitry Andric let Inst{15-12} = Rt; 56780b57cec5SDimitry Andric let Inst{11-8} = cop; 56790b57cec5SDimitry Andric let Inst{23-21} = opc1; 56800b57cec5SDimitry Andric let Inst{7-5} = opc2; 56810b57cec5SDimitry Andric let Inst{3-0} = CRm; 56820b57cec5SDimitry Andric let Inst{19-16} = CRn; 56830b57cec5SDimitry Andric 56840b57cec5SDimitry Andric let DecoderNamespace = "CoProc"; 56850b57cec5SDimitry Andric} 56860b57cec5SDimitry Andric 56870b57cec5SDimitry Andricdef MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */, 56880b57cec5SDimitry Andric (outs), 56890b57cec5SDimitry Andric (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 56900b57cec5SDimitry Andric c_imm:$CRm, imm0_7:$opc2), 56918bcb0991SDimitry Andric [(int_arm_mcr2 timm:$cop, timm:$opc1, GPR:$Rt, timm:$CRn, 56928bcb0991SDimitry Andric timm:$CRm, timm:$opc2)]>, 56930b57cec5SDimitry Andric Requires<[IsARM,PreV8]>; 56940b57cec5SDimitry Andricdef : ARMInstAlias<"mcr2 $cop, $opc1, $Rt, $CRn, $CRm", 56950b57cec5SDimitry Andric (MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 56960b57cec5SDimitry Andric c_imm:$CRm, 0)>; 56970b57cec5SDimitry Andricdef MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */, 56980b57cec5SDimitry Andric (outs GPRwithAPSR:$Rt), 56990b57cec5SDimitry Andric (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 57000b57cec5SDimitry Andric imm0_7:$opc2), []>, 57010b57cec5SDimitry Andric Requires<[IsARM,PreV8]>; 57020b57cec5SDimitry Andricdef : ARMInstAlias<"mrc2 $cop, $opc1, $Rt, $CRn, $CRm", 57030b57cec5SDimitry Andric (MRC2 GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 57040b57cec5SDimitry Andric c_imm:$CRm, 0)>; 57050b57cec5SDimitry Andric 57068bcb0991SDimitry Andricdef : ARMV5TPat<(int_arm_mrc2 timm:$cop, timm:$opc1, timm:$CRn, 57078bcb0991SDimitry Andric timm:$CRm, timm:$opc2), 57088bcb0991SDimitry Andric (MRC2 p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2)>; 57090b57cec5SDimitry Andric 57100b57cec5SDimitry Andricclass MovRRCopro<string opc, bit direction, dag oops, dag iops, list<dag> 57110b57cec5SDimitry Andric pattern = []> 57120b57cec5SDimitry Andric : ABI<0b1100, oops, iops, NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", 57130b57cec5SDimitry Andric pattern> { 57140b57cec5SDimitry Andric 57150b57cec5SDimitry Andric let Inst{23-21} = 0b010; 57160b57cec5SDimitry Andric let Inst{20} = direction; 57170b57cec5SDimitry Andric 57180b57cec5SDimitry Andric bits<4> Rt; 57190b57cec5SDimitry Andric bits<4> Rt2; 57200b57cec5SDimitry Andric bits<4> cop; 57210b57cec5SDimitry Andric bits<4> opc1; 57220b57cec5SDimitry Andric bits<4> CRm; 57230b57cec5SDimitry Andric 57240b57cec5SDimitry Andric let Inst{15-12} = Rt; 57250b57cec5SDimitry Andric let Inst{19-16} = Rt2; 57260b57cec5SDimitry Andric let Inst{11-8} = cop; 57270b57cec5SDimitry Andric let Inst{7-4} = opc1; 57280b57cec5SDimitry Andric let Inst{3-0} = CRm; 57290b57cec5SDimitry Andric} 57300b57cec5SDimitry Andric 57310b57cec5SDimitry Andricdef MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, 57320b57cec5SDimitry Andric (outs), (ins p_imm:$cop, imm0_15:$opc1, GPRnopc:$Rt, 57330b57cec5SDimitry Andric GPRnopc:$Rt2, c_imm:$CRm), 57348bcb0991SDimitry Andric [(int_arm_mcrr timm:$cop, timm:$opc1, GPRnopc:$Rt, 57358bcb0991SDimitry Andric GPRnopc:$Rt2, timm:$CRm)]>; 57360b57cec5SDimitry Andricdef MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */, 57370b57cec5SDimitry Andric (outs GPRnopc:$Rt, GPRnopc:$Rt2), 57380b57cec5SDimitry Andric (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>; 57390b57cec5SDimitry Andric 57400b57cec5SDimitry Andricclass MovRRCopro2<string opc, bit direction, dag oops, dag iops, 57410b57cec5SDimitry Andric list<dag> pattern = []> 57420b57cec5SDimitry Andric : ABXI<0b1100, oops, iops, NoItinerary, 57430b57cec5SDimitry Andric !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern>, 57440b57cec5SDimitry Andric Requires<[IsARM,PreV8]> { 57450b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 57460b57cec5SDimitry Andric let Inst{23-21} = 0b010; 57470b57cec5SDimitry Andric let Inst{20} = direction; 57480b57cec5SDimitry Andric 57490b57cec5SDimitry Andric bits<4> Rt; 57500b57cec5SDimitry Andric bits<4> Rt2; 57510b57cec5SDimitry Andric bits<4> cop; 57520b57cec5SDimitry Andric bits<4> opc1; 57530b57cec5SDimitry Andric bits<4> CRm; 57540b57cec5SDimitry Andric 57550b57cec5SDimitry Andric let Inst{15-12} = Rt; 57560b57cec5SDimitry Andric let Inst{19-16} = Rt2; 57570b57cec5SDimitry Andric let Inst{11-8} = cop; 57580b57cec5SDimitry Andric let Inst{7-4} = opc1; 57590b57cec5SDimitry Andric let Inst{3-0} = CRm; 57600b57cec5SDimitry Andric 57610b57cec5SDimitry Andric let DecoderMethod = "DecoderForMRRC2AndMCRR2"; 57620b57cec5SDimitry Andric} 57630b57cec5SDimitry Andric 57640b57cec5SDimitry Andricdef MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */, 57650b57cec5SDimitry Andric (outs), (ins p_imm:$cop, imm0_15:$opc1, GPRnopc:$Rt, 57660b57cec5SDimitry Andric GPRnopc:$Rt2, c_imm:$CRm), 57678bcb0991SDimitry Andric [(int_arm_mcrr2 timm:$cop, timm:$opc1, GPRnopc:$Rt, 57688bcb0991SDimitry Andric GPRnopc:$Rt2, timm:$CRm)]>; 57690b57cec5SDimitry Andric 57700b57cec5SDimitry Andricdef MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */, 57710b57cec5SDimitry Andric (outs GPRnopc:$Rt, GPRnopc:$Rt2), 57720b57cec5SDimitry Andric (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>; 57730b57cec5SDimitry Andric 57740b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 57750b57cec5SDimitry Andric// Move between special register and ARM core register 57760b57cec5SDimitry Andric// 57770b57cec5SDimitry Andric 57780b57cec5SDimitry Andric// Move to ARM core register from Special Register 57790b57cec5SDimitry Andricdef MRS : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, 57800b57cec5SDimitry Andric "mrs", "\t$Rd, apsr", []> { 57810b57cec5SDimitry Andric bits<4> Rd; 57820b57cec5SDimitry Andric let Inst{23-16} = 0b00001111; 57830b57cec5SDimitry Andric let Unpredictable{19-17} = 0b111; 57840b57cec5SDimitry Andric 57850b57cec5SDimitry Andric let Inst{15-12} = Rd; 57860b57cec5SDimitry Andric 57870b57cec5SDimitry Andric let Inst{11-0} = 0b000000000000; 57880b57cec5SDimitry Andric let Unpredictable{11-0} = 0b110100001111; 57890b57cec5SDimitry Andric} 57900b57cec5SDimitry Andric 57910b57cec5SDimitry Andricdef : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPRnopc:$Rd, pred:$p), 0>, 57920b57cec5SDimitry Andric Requires<[IsARM]>; 57930b57cec5SDimitry Andric 57940b57cec5SDimitry Andric// The MRSsys instruction is the MRS instruction from the ARM ARM, 57950b57cec5SDimitry Andric// section B9.3.9, with the R bit set to 1. 57960b57cec5SDimitry Andricdef MRSsys : ABI<0b0001, (outs GPRnopc:$Rd), (ins), NoItinerary, 57970b57cec5SDimitry Andric "mrs", "\t$Rd, spsr", []> { 57980b57cec5SDimitry Andric bits<4> Rd; 57990b57cec5SDimitry Andric let Inst{23-16} = 0b01001111; 58000b57cec5SDimitry Andric let Unpredictable{19-16} = 0b1111; 58010b57cec5SDimitry Andric 58020b57cec5SDimitry Andric let Inst{15-12} = Rd; 58030b57cec5SDimitry Andric 58040b57cec5SDimitry Andric let Inst{11-0} = 0b000000000000; 58050b57cec5SDimitry Andric let Unpredictable{11-0} = 0b110100001111; 58060b57cec5SDimitry Andric} 58070b57cec5SDimitry Andric 58080b57cec5SDimitry Andric// However, the MRS (banked register) system instruction (ARMv7VE) *does* have a 58090b57cec5SDimitry Andric// separate encoding (distinguished by bit 5. 58100b57cec5SDimitry Andricdef MRSbanked : ABI<0b0001, (outs GPRnopc:$Rd), (ins banked_reg:$banked), 58110b57cec5SDimitry Andric NoItinerary, "mrs", "\t$Rd, $banked", []>, 58120b57cec5SDimitry Andric Requires<[IsARM, HasVirtualization]> { 58130b57cec5SDimitry Andric bits<6> banked; 58140b57cec5SDimitry Andric bits<4> Rd; 58150b57cec5SDimitry Andric 58160b57cec5SDimitry Andric let Inst{23} = 0; 58170b57cec5SDimitry Andric let Inst{22} = banked{5}; // R bit 58180b57cec5SDimitry Andric let Inst{21-20} = 0b00; 58190b57cec5SDimitry Andric let Inst{19-16} = banked{3-0}; 58200b57cec5SDimitry Andric let Inst{15-12} = Rd; 58210b57cec5SDimitry Andric let Inst{11-9} = 0b001; 58220b57cec5SDimitry Andric let Inst{8} = banked{4}; 58230b57cec5SDimitry Andric let Inst{7-0} = 0b00000000; 58240b57cec5SDimitry Andric} 58250b57cec5SDimitry Andric 58260b57cec5SDimitry Andric// Move from ARM core register to Special Register 58270b57cec5SDimitry Andric// 58280b57cec5SDimitry Andric// No need to have both system and application versions of MSR (immediate) or 58290b57cec5SDimitry Andric// MSR (register), the encodings are the same and the assembly parser has no way 58300b57cec5SDimitry Andric// to distinguish between them. The mask operand contains the special register 58310b57cec5SDimitry Andric// (R Bit) in bit 4 and bits 3-0 contains the mask with the fields to be 58320b57cec5SDimitry Andric// accessed in the special register. 58330b57cec5SDimitry Andriclet Defs = [CPSR] in 58340b57cec5SDimitry Andricdef MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary, 58350b57cec5SDimitry Andric "msr", "\t$mask, $Rn", []> { 58360b57cec5SDimitry Andric bits<5> mask; 58370b57cec5SDimitry Andric bits<4> Rn; 58380b57cec5SDimitry Andric 58390b57cec5SDimitry Andric let Inst{23} = 0; 58400b57cec5SDimitry Andric let Inst{22} = mask{4}; // R bit 58410b57cec5SDimitry Andric let Inst{21-20} = 0b10; 58420b57cec5SDimitry Andric let Inst{19-16} = mask{3-0}; 58430b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 58440b57cec5SDimitry Andric let Inst{11-4} = 0b00000000; 58450b57cec5SDimitry Andric let Inst{3-0} = Rn; 58460b57cec5SDimitry Andric} 58470b57cec5SDimitry Andric 58480b57cec5SDimitry Andriclet Defs = [CPSR] in 58490b57cec5SDimitry Andricdef MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, mod_imm:$imm), NoItinerary, 58500b57cec5SDimitry Andric "msr", "\t$mask, $imm", []> { 58510b57cec5SDimitry Andric bits<5> mask; 58520b57cec5SDimitry Andric bits<12> imm; 58530b57cec5SDimitry Andric 58540b57cec5SDimitry Andric let Inst{23} = 0; 58550b57cec5SDimitry Andric let Inst{22} = mask{4}; // R bit 58560b57cec5SDimitry Andric let Inst{21-20} = 0b10; 58570b57cec5SDimitry Andric let Inst{19-16} = mask{3-0}; 58580b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 58590b57cec5SDimitry Andric let Inst{11-0} = imm; 58600b57cec5SDimitry Andric} 58610b57cec5SDimitry Andric 58620b57cec5SDimitry Andric// However, the MSR (banked register) system instruction (ARMv7VE) *does* have a 58630b57cec5SDimitry Andric// separate encoding (distinguished by bit 5. 58640b57cec5SDimitry Andricdef MSRbanked : ABI<0b0001, (outs), (ins banked_reg:$banked, GPRnopc:$Rn), 58650b57cec5SDimitry Andric NoItinerary, "msr", "\t$banked, $Rn", []>, 58660b57cec5SDimitry Andric Requires<[IsARM, HasVirtualization]> { 58670b57cec5SDimitry Andric bits<6> banked; 58680b57cec5SDimitry Andric bits<4> Rn; 58690b57cec5SDimitry Andric 58700b57cec5SDimitry Andric let Inst{23} = 0; 58710b57cec5SDimitry Andric let Inst{22} = banked{5}; // R bit 58720b57cec5SDimitry Andric let Inst{21-20} = 0b10; 58730b57cec5SDimitry Andric let Inst{19-16} = banked{3-0}; 58740b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 58750b57cec5SDimitry Andric let Inst{11-9} = 0b001; 58760b57cec5SDimitry Andric let Inst{8} = banked{4}; 58770b57cec5SDimitry Andric let Inst{7-4} = 0b0000; 58780b57cec5SDimitry Andric let Inst{3-0} = Rn; 58790b57cec5SDimitry Andric} 58800b57cec5SDimitry Andric 58810b57cec5SDimitry Andric// Dynamic stack allocation yields a _chkstk for Windows targets. These calls 58820b57cec5SDimitry Andric// are needed to probe the stack when allocating more than 58830b57cec5SDimitry Andric// 4k bytes in one go. Touching the stack at 4K increments is necessary to 58840b57cec5SDimitry Andric// ensure that the guard pages used by the OS virtual memory manager are 58850b57cec5SDimitry Andric// allocated in correct sequence. 58860b57cec5SDimitry Andric// The main point of having separate instruction are extra unmodelled effects 58870b57cec5SDimitry Andric// (compared to ordinary calls) like stack pointer change. 58880b57cec5SDimitry Andric 58890b57cec5SDimitry Andricdef win__chkstk : SDNode<"ARMISD::WIN__CHKSTK", SDTNone, 58900b57cec5SDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 58918bcb0991SDimitry Andriclet usesCustomInserter = 1, Uses = [R4], Defs = [R4, SP], hasNoSchedulingInfo = 1 in 58920b57cec5SDimitry Andric def WIN__CHKSTK : PseudoInst<(outs), (ins), NoItinerary, [(win__chkstk)]>; 58930b57cec5SDimitry Andric 58940b57cec5SDimitry Andricdef win__dbzchk : SDNode<"ARMISD::WIN__DBZCHK", SDT_WIN__DBZCHK, 58950b57cec5SDimitry Andric [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; 58968bcb0991SDimitry Andriclet usesCustomInserter = 1, Defs = [CPSR], hasNoSchedulingInfo = 1 in 58970b57cec5SDimitry Andric def WIN__DBZCHK : PseudoInst<(outs), (ins tGPR:$divisor), NoItinerary, 58980b57cec5SDimitry Andric [(win__dbzchk tGPR:$divisor)]>; 58990b57cec5SDimitry Andric 59000b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 59010b57cec5SDimitry Andric// TLS Instructions 59020b57cec5SDimitry Andric// 59030b57cec5SDimitry Andric 59040b57cec5SDimitry Andric// __aeabi_read_tp preserves the registers r1-r3. 59050b57cec5SDimitry Andric// This is a pseudo inst so that we can get the encoding right, 59060b57cec5SDimitry Andric// complete with fixup for the aeabi_read_tp function. 59070b57cec5SDimitry Andric// TPsoft is valid for ARM mode only, in case of Thumb mode a tTPsoft pattern 59080b57cec5SDimitry Andric// is defined in "ARMInstrThumb.td". 59090b57cec5SDimitry Andriclet isCall = 1, 59100b57cec5SDimitry Andric Defs = [R0, R12, LR, CPSR], Uses = [SP] in { 59110b57cec5SDimitry Andric def TPsoft : ARMPseudoInst<(outs), (ins), 4, IIC_Br, 59120b57cec5SDimitry Andric [(set R0, ARMthread_pointer)]>, Sched<[WriteBr]>, 59130b57cec5SDimitry Andric Requires<[IsARM, IsReadTPSoft]>; 59140b57cec5SDimitry Andric} 59150b57cec5SDimitry Andric 59160b57cec5SDimitry Andric// Reading thread pointer from coprocessor register 591706c3fb27SDimitry Andricdef : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 2)>, 591806c3fb27SDimitry Andric Requires<[IsARM, IsReadTPTPIDRURW]>; 59190b57cec5SDimitry Andricdef : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 3)>, 592006c3fb27SDimitry Andric Requires<[IsARM, IsReadTPTPIDRURO]>; 592106c3fb27SDimitry Andricdef : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 4)>, 592206c3fb27SDimitry Andric Requires<[IsARM, IsReadTPTPIDRPRW]>; 59230b57cec5SDimitry Andric 59240b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 59250b57cec5SDimitry Andric// SJLJ Exception handling intrinsics 59260b57cec5SDimitry Andric// eh_sjlj_setjmp() is an instruction sequence to store the return 59270b57cec5SDimitry Andric// address and save #0 in R0 for the non-longjmp case. 59280b57cec5SDimitry Andric// Since by its nature we may be coming from some other function to get 59290b57cec5SDimitry Andric// here, and we're using the stack frame for the containing function to 59300b57cec5SDimitry Andric// save/restore registers, we can't keep anything live in regs across 59310b57cec5SDimitry Andric// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 59320b57cec5SDimitry Andric// when we get here from a longjmp(). We force everything out of registers 59330b57cec5SDimitry Andric// except for our own input by listing the relevant registers in Defs. By 59340b57cec5SDimitry Andric// doing so, we also cause the prologue/epilogue code to actively preserve 59355ffd83dbSDimitry Andric// all of the callee-saved registers, which is exactly what we want. 59360b57cec5SDimitry Andric// A constant value is passed in $val, and we use the location as a scratch. 59370b57cec5SDimitry Andric// 59380b57cec5SDimitry Andric// These are pseudo-instructions and are lowered to individual MC-insts, so 59390b57cec5SDimitry Andric// no encoding information is necessary. 59401fd87a68SDimitry Andric// This gets lowered to an instruction sequence of 20 bytes 59410b57cec5SDimitry Andriclet Defs = 59420b57cec5SDimitry Andric [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, 59430b57cec5SDimitry Andric Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ], 59441fd87a68SDimitry Andric hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in { 59450b57cec5SDimitry Andric def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 59460b57cec5SDimitry Andric NoItinerary, 59470b57cec5SDimitry Andric [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 59480b57cec5SDimitry Andric Requires<[IsARM, HasVFP2]>; 59490b57cec5SDimitry Andric} 59500b57cec5SDimitry Andric 59511fd87a68SDimitry Andric// This gets lowered to an instruction sequence of 20 bytes 59520b57cec5SDimitry Andriclet Defs = 59530b57cec5SDimitry Andric [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], 59541fd87a68SDimitry Andric hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in { 59550b57cec5SDimitry Andric def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 59560b57cec5SDimitry Andric NoItinerary, 59570b57cec5SDimitry Andric [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 59580b57cec5SDimitry Andric Requires<[IsARM, NoVFP]>; 59590b57cec5SDimitry Andric} 59600b57cec5SDimitry Andric 59611fd87a68SDimitry Andric// This gets lowered to an instruction sequence of 16 bytes 59620b57cec5SDimitry Andric// FIXME: Non-IOS version(s) 59631fd87a68SDimitry Andriclet isBarrier = 1, hasSideEffects = 1, isTerminator = 1, Size = 16, 59640b57cec5SDimitry Andric Defs = [ R7, LR, SP ] in { 59650b57cec5SDimitry Andricdef Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch), 59660b57cec5SDimitry Andric NoItinerary, 59670b57cec5SDimitry Andric [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, 59680b57cec5SDimitry Andric Requires<[IsARM]>; 59690b57cec5SDimitry Andric} 59700b57cec5SDimitry Andric 59710b57cec5SDimitry Andriclet isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in 59720b57cec5SDimitry Andricdef Int_eh_sjlj_setup_dispatch : PseudoInst<(outs), (ins), NoItinerary, 59730b57cec5SDimitry Andric [(ARMeh_sjlj_setup_dispatch)]>; 59740b57cec5SDimitry Andric 59750b57cec5SDimitry Andric// eh.sjlj.dispatchsetup pseudo-instruction. 59760b57cec5SDimitry Andric// This pseudo is used for both ARM and Thumb. Any differences are handled when 59770b57cec5SDimitry Andric// the pseudo is expanded (which happens before any passes that need the 59780b57cec5SDimitry Andric// instruction size). 59790b57cec5SDimitry Andriclet isBarrier = 1 in 59800b57cec5SDimitry Andricdef Int_eh_sjlj_dispatchsetup : PseudoInst<(outs), (ins), NoItinerary, []>; 59810b57cec5SDimitry Andric 59820b57cec5SDimitry Andric 59830b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 59840b57cec5SDimitry Andric// Non-Instruction Patterns 59850b57cec5SDimitry Andric// 59860b57cec5SDimitry Andric 59870b57cec5SDimitry Andric// ARMv4 indirect branch using (MOVr PC, dst) 59880b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in 59890b57cec5SDimitry Andric def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst), 59900b57cec5SDimitry Andric 4, IIC_Br, [(brind GPR:$dst)], 59910b57cec5SDimitry Andric (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, 59920b57cec5SDimitry Andric Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; 59930b57cec5SDimitry Andric 59940b57cec5SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in 59950b57cec5SDimitry Andric def TAILJMPr4 : ARMPseudoExpand<(outs), (ins GPR:$dst), 59960b57cec5SDimitry Andric 4, IIC_Br, [], 59970b57cec5SDimitry Andric (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>, 59980b57cec5SDimitry Andric Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>; 59990b57cec5SDimitry Andric 60000b57cec5SDimitry Andric// Large immediate handling. 60010b57cec5SDimitry Andric 60020b57cec5SDimitry Andric// 32-bit immediate using two piece mod_imms or movw + movt. 60030b57cec5SDimitry Andric// This is a single pseudo instruction, the benefit is that it can be remat'd 60040b57cec5SDimitry Andric// as a single unit instead of having to handle reg inputs. 60050b57cec5SDimitry Andric// FIXME: Remove this when we can do generalized remat. 60061fd87a68SDimitry Andriclet isReMaterializable = 1, isMoveImm = 1, Size = 8 in 60070b57cec5SDimitry Andricdef MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 60080b57cec5SDimitry Andric [(set GPR:$dst, (arm_i32imm:$src))]>, 60090b57cec5SDimitry Andric Requires<[IsARM]>; 60100b57cec5SDimitry Andric 60110b57cec5SDimitry Andricdef LDRLIT_ga_abs : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iLoad_i, 60120b57cec5SDimitry Andric [(set GPR:$dst, (ARMWrapper tglobaladdr:$src))]>, 60130b57cec5SDimitry Andric Requires<[IsARM, DontUseMovt]>; 60140b57cec5SDimitry Andric 60150b57cec5SDimitry Andric// Pseudo instruction that combines movw + movt + add pc (if PIC). 60160b57cec5SDimitry Andric// It also makes it possible to rematerialize the instructions. 60170b57cec5SDimitry Andric// FIXME: Remove this when we can do generalized remat and when machine licm 60180b57cec5SDimitry Andric// can properly the instructions. 60190b57cec5SDimitry Andriclet isReMaterializable = 1 in { 60200b57cec5SDimitry Andricdef MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 60210b57cec5SDimitry Andric IIC_iMOVix2addpc, 60220b57cec5SDimitry Andric [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, 60230b57cec5SDimitry Andric Requires<[IsARM, UseMovtInPic]>; 60240b57cec5SDimitry Andric 60250b57cec5SDimitry Andricdef LDRLIT_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 60260b57cec5SDimitry Andric IIC_iLoadiALU, 60270b57cec5SDimitry Andric [(set GPR:$dst, 60280b57cec5SDimitry Andric (ARMWrapperPIC tglobaladdr:$addr))]>, 60290b57cec5SDimitry Andric Requires<[IsARM, DontUseMovtInPic]>; 60300b57cec5SDimitry Andric 60310b57cec5SDimitry Andriclet AddedComplexity = 10 in 60320b57cec5SDimitry Andricdef LDRLIT_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 60330b57cec5SDimitry Andric NoItinerary, 60340b57cec5SDimitry Andric [(set GPR:$dst, 60350b57cec5SDimitry Andric (load (ARMWrapperPIC tglobaladdr:$addr)))]>, 60360b57cec5SDimitry Andric Requires<[IsARM, DontUseMovtInPic]>; 60370b57cec5SDimitry Andric 60380b57cec5SDimitry Andriclet AddedComplexity = 10 in 60390b57cec5SDimitry Andricdef MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 60400b57cec5SDimitry Andric IIC_iMOVix2ld, 60410b57cec5SDimitry Andric [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, 60420b57cec5SDimitry Andric Requires<[IsARM, UseMovtInPic]>; 60430b57cec5SDimitry Andric} // isReMaterializable 60440b57cec5SDimitry Andric 60450b57cec5SDimitry Andric// The many different faces of TLS access. 60460b57cec5SDimitry Andricdef : ARMPat<(ARMWrapper tglobaltlsaddr :$dst), 60470b57cec5SDimitry Andric (MOVi32imm tglobaltlsaddr :$dst)>, 60480b57cec5SDimitry Andric Requires<[IsARM, UseMovt]>; 60490b57cec5SDimitry Andric 60500b57cec5SDimitry Andricdef : Pat<(ARMWrapper tglobaltlsaddr:$src), 60510b57cec5SDimitry Andric (LDRLIT_ga_abs tglobaltlsaddr:$src)>, 60520b57cec5SDimitry Andric Requires<[IsARM, DontUseMovt]>; 60530b57cec5SDimitry Andric 60540b57cec5SDimitry Andricdef : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), 60550b57cec5SDimitry Andric (MOV_ga_pcrel tglobaltlsaddr:$addr)>, Requires<[IsARM, UseMovtInPic]>; 60560b57cec5SDimitry Andric 60570b57cec5SDimitry Andricdef : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), 60580b57cec5SDimitry Andric (LDRLIT_ga_pcrel tglobaltlsaddr:$addr)>, 60590b57cec5SDimitry Andric Requires<[IsARM, DontUseMovtInPic]>; 60600b57cec5SDimitry Andriclet AddedComplexity = 10 in 60610b57cec5SDimitry Andricdef : Pat<(load (ARMWrapperPIC tglobaltlsaddr:$addr)), 60620b57cec5SDimitry Andric (MOV_ga_pcrel_ldr tglobaltlsaddr:$addr)>, 60630b57cec5SDimitry Andric Requires<[IsARM, UseMovtInPic]>; 60640b57cec5SDimitry Andric 60650b57cec5SDimitry Andric 60660b57cec5SDimitry Andric// ConstantPool, GlobalAddress, and JumpTable 60670b57cec5SDimitry Andricdef : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; 60680b57cec5SDimitry Andricdef : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>, 60690b57cec5SDimitry Andric Requires<[IsARM, UseMovt]>; 60700b57cec5SDimitry Andricdef : ARMPat<(ARMWrapper texternalsym :$dst), (MOVi32imm texternalsym :$dst)>, 60710b57cec5SDimitry Andric Requires<[IsARM, UseMovt]>; 60720b57cec5SDimitry Andricdef : ARMPat<(ARMWrapperJT tjumptable:$dst), 60730b57cec5SDimitry Andric (LEApcrelJT tjumptable:$dst)>; 60740b57cec5SDimitry Andric 60750b57cec5SDimitry Andric// TODO: add,sub,and, 3-instr forms? 60760b57cec5SDimitry Andric 60770b57cec5SDimitry Andric// Tail calls. These patterns also apply to Thumb mode. 6078*0fca6ea1SDimitry Andric// Regular indirect tail call 6079fe6060f1SDimitry Andricdef : Pat<(ARMtcret tcGPR:$dst, (i32 timm:$SPDiff)), 6080*0fca6ea1SDimitry Andric (TCRETURNri tcGPR:$dst, timm:$SPDiff)>, 6081*0fca6ea1SDimitry Andric Requires<[NoSignRetAddr]>; 6082*0fca6ea1SDimitry Andric// Indirect tail call when PACBTI is enabled 6083*0fca6ea1SDimitry Andricdef : Pat<(ARMtcret tcGPRnotr12:$dst, (i32 timm:$SPDiff)), 6084*0fca6ea1SDimitry Andric (TCRETURNrinotr12 tcGPRnotr12:$dst, timm:$SPDiff)>, 6085*0fca6ea1SDimitry Andric Requires<[SignRetAddr]>; 6086fe6060f1SDimitry Andricdef : Pat<(ARMtcret (i32 tglobaladdr:$dst), (i32 timm:$SPDiff)), 6087fe6060f1SDimitry Andric (TCRETURNdi texternalsym:$dst, (i32 timm:$SPDiff))>; 6088fe6060f1SDimitry Andricdef : Pat<(ARMtcret (i32 texternalsym:$dst), (i32 timm:$SPDiff)), 6089fe6060f1SDimitry Andric (TCRETURNdi texternalsym:$dst, i32imm:$SPDiff)>; 60900b57cec5SDimitry Andric 60910b57cec5SDimitry Andric// Direct calls 60920b57cec5SDimitry Andricdef : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>; 60930b57cec5SDimitry Andricdef : ARMPat<(ARMcall_nolink texternalsym:$func), 60940b57cec5SDimitry Andric (BMOVPCB_CALL texternalsym:$func)>; 60950b57cec5SDimitry Andric 60960b57cec5SDimitry Andric// zextload i1 -> zextload i8 60970b57cec5SDimitry Andricdef : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 60980b57cec5SDimitry Andricdef : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 60990b57cec5SDimitry Andric 61000b57cec5SDimitry Andric// extload -> zextload 61010b57cec5SDimitry Andricdef : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 61020b57cec5SDimitry Andricdef : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 61030b57cec5SDimitry Andricdef : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 61040b57cec5SDimitry Andricdef : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 61050b57cec5SDimitry Andric 61060b57cec5SDimitry Andricdef : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; 61070b57cec5SDimitry Andric 61080b57cec5SDimitry Andricdef : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; 61090b57cec5SDimitry Andricdef : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>; 61100b57cec5SDimitry Andric 61110b57cec5SDimitry Andric// smul* and smla* 61120b57cec5SDimitry Andricdef : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b), 61130b57cec5SDimitry Andric (SMULBB GPR:$a, GPR:$b)>; 61140b57cec5SDimitry Andricdef : ARMV5TEPat<(mul sext_16_node:$a, (sext_bottom_16 GPR:$b)), 61150b57cec5SDimitry Andric (SMULBB GPR:$a, GPR:$b)>; 61160b57cec5SDimitry Andricdef : ARMV5TEPat<(mul sext_16_node:$a, (sext_top_16 GPR:$b)), 61170b57cec5SDimitry Andric (SMULBT GPR:$a, GPR:$b)>; 61180b57cec5SDimitry Andricdef : ARMV5TEPat<(mul (sext_top_16 GPR:$a), sext_16_node:$b), 61190b57cec5SDimitry Andric (SMULTB GPR:$a, GPR:$b)>; 61200b57cec5SDimitry Andricdef : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, sext_16_node:$b)), 61210b57cec5SDimitry Andric (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 61220b57cec5SDimitry Andricdef : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, (sext_bottom_16 GPR:$b))), 61230b57cec5SDimitry Andric (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 61240b57cec5SDimitry Andricdef : ARMV5MOPat<(add GPR:$acc, (mul sext_16_node:$a, (sext_top_16 GPR:$b))), 61250b57cec5SDimitry Andric (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 61260b57cec5SDimitry Andricdef : ARMV5MOPat<(add GPR:$acc, (mul (sext_top_16 GPR:$a), sext_16_node:$b)), 61270b57cec5SDimitry Andric (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 61280b57cec5SDimitry Andric 61290b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smulbb GPR:$a, GPR:$b), 61300b57cec5SDimitry Andric (SMULBB GPR:$a, GPR:$b)>; 61310b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smulbt GPR:$a, GPR:$b), 61320b57cec5SDimitry Andric (SMULBT GPR:$a, GPR:$b)>; 61330b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smultb GPR:$a, GPR:$b), 61340b57cec5SDimitry Andric (SMULTB GPR:$a, GPR:$b)>; 61350b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smultt GPR:$a, GPR:$b), 61360b57cec5SDimitry Andric (SMULTT GPR:$a, GPR:$b)>; 61370b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smulwb GPR:$a, GPR:$b), 61380b57cec5SDimitry Andric (SMULWB GPR:$a, GPR:$b)>; 61390b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smulwt GPR:$a, GPR:$b), 61400b57cec5SDimitry Andric (SMULWT GPR:$a, GPR:$b)>; 61410b57cec5SDimitry Andric 61420b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smlabb GPR:$a, GPR:$b, GPR:$acc), 61430b57cec5SDimitry Andric (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 61440b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smlabt GPR:$a, GPR:$b, GPR:$acc), 61450b57cec5SDimitry Andric (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 61460b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smlatb GPR:$a, GPR:$b, GPR:$acc), 61470b57cec5SDimitry Andric (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 61480b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smlatt GPR:$a, GPR:$b, GPR:$acc), 61490b57cec5SDimitry Andric (SMLATT GPR:$a, GPR:$b, GPR:$acc)>; 61500b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smlawb GPR:$a, GPR:$b, GPR:$acc), 61510b57cec5SDimitry Andric (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 61520b57cec5SDimitry Andricdef : ARMV5TEPat<(int_arm_smlawt GPR:$a, GPR:$b, GPR:$acc), 61530b57cec5SDimitry Andric (SMLAWT GPR:$a, GPR:$b, GPR:$acc)>; 61540b57cec5SDimitry Andric 61550b57cec5SDimitry Andric// Pre-v7 uses MCR for synchronization barriers. 61560b57cec5SDimitry Andricdef : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>, 61570b57cec5SDimitry Andric Requires<[IsARM, HasV6]>; 61580b57cec5SDimitry Andric 61590b57cec5SDimitry Andric// SXT/UXT with no rotate 61600b57cec5SDimitry Andriclet AddedComplexity = 16 in { 61610b57cec5SDimitry Andricdef : ARMV6Pat<(and GPR:$Src, 0x000000FF), (UXTB GPR:$Src, 0)>; 61620b57cec5SDimitry Andricdef : ARMV6Pat<(and GPR:$Src, 0x0000FFFF), (UXTH GPR:$Src, 0)>; 61630b57cec5SDimitry Andricdef : ARMV6Pat<(and GPR:$Src, 0x00FF00FF), (UXTB16 GPR:$Src, 0)>; 61640b57cec5SDimitry Andricdef : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0x00FF)), 61650b57cec5SDimitry Andric (UXTAB GPR:$Rn, GPR:$Rm, 0)>; 61660b57cec5SDimitry Andricdef : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0xFFFF)), 61670b57cec5SDimitry Andric (UXTAH GPR:$Rn, GPR:$Rm, 0)>; 61680b57cec5SDimitry Andric} 61690b57cec5SDimitry Andric 61700b57cec5SDimitry Andricdef : ARMV6Pat<(sext_inreg GPR:$Src, i8), (SXTB GPR:$Src, 0)>; 61710b57cec5SDimitry Andricdef : ARMV6Pat<(sext_inreg GPR:$Src, i16), (SXTH GPR:$Src, 0)>; 61720b57cec5SDimitry Andric 61730b57cec5SDimitry Andricdef : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i8)), 61740b57cec5SDimitry Andric (SXTAB GPR:$Rn, GPRnopc:$Rm, 0)>; 61750b57cec5SDimitry Andricdef : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)), 61760b57cec5SDimitry Andric (SXTAH GPR:$Rn, GPRnopc:$Rm, 0)>; 61770b57cec5SDimitry Andric 61780b57cec5SDimitry Andric// Atomic load/store patterns 61790b57cec5SDimitry Andricdef : ARMPat<(atomic_load_8 ldst_so_reg:$src), 61800b57cec5SDimitry Andric (LDRBrs ldst_so_reg:$src)>; 61810b57cec5SDimitry Andricdef : ARMPat<(atomic_load_8 addrmode_imm12:$src), 61820b57cec5SDimitry Andric (LDRBi12 addrmode_imm12:$src)>; 61830b57cec5SDimitry Andricdef : ARMPat<(atomic_load_16 addrmode3:$src), 61840b57cec5SDimitry Andric (LDRH addrmode3:$src)>; 61850b57cec5SDimitry Andricdef : ARMPat<(atomic_load_32 ldst_so_reg:$src), 61860b57cec5SDimitry Andric (LDRrs ldst_so_reg:$src)>; 61870b57cec5SDimitry Andricdef : ARMPat<(atomic_load_32 addrmode_imm12:$src), 61880b57cec5SDimitry Andric (LDRi12 addrmode_imm12:$src)>; 61895f757f3fSDimitry Andricdef : ARMPat<(atomic_store_8 GPR:$val, ldst_so_reg:$ptr), 61900b57cec5SDimitry Andric (STRBrs GPR:$val, ldst_so_reg:$ptr)>; 61915f757f3fSDimitry Andricdef : ARMPat<(atomic_store_8 GPR:$val, addrmode_imm12:$ptr), 61920b57cec5SDimitry Andric (STRBi12 GPR:$val, addrmode_imm12:$ptr)>; 61935f757f3fSDimitry Andricdef : ARMPat<(atomic_store_16 GPR:$val, addrmode3:$ptr), 61940b57cec5SDimitry Andric (STRH GPR:$val, addrmode3:$ptr)>; 61955f757f3fSDimitry Andricdef : ARMPat<(atomic_store_32 GPR:$val, ldst_so_reg:$ptr), 61960b57cec5SDimitry Andric (STRrs GPR:$val, ldst_so_reg:$ptr)>; 61975f757f3fSDimitry Andricdef : ARMPat<(atomic_store_32 GPR:$val, addrmode_imm12:$ptr), 61980b57cec5SDimitry Andric (STRi12 GPR:$val, addrmode_imm12:$ptr)>; 61990b57cec5SDimitry Andric 62000b57cec5SDimitry Andric 62010b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 62020b57cec5SDimitry Andric// Thumb Support 62030b57cec5SDimitry Andric// 62040b57cec5SDimitry Andric 62050b57cec5SDimitry Andricinclude "ARMInstrThumb.td" 62060b57cec5SDimitry Andric 62070b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 62080b57cec5SDimitry Andric// Thumb2 Support 62090b57cec5SDimitry Andric// 62100b57cec5SDimitry Andric 62110b57cec5SDimitry Andricinclude "ARMInstrThumb2.td" 62120b57cec5SDimitry Andric 62130b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 62140b57cec5SDimitry Andric// Floating Point Support 62150b57cec5SDimitry Andric// 62160b57cec5SDimitry Andric 62170b57cec5SDimitry Andricinclude "ARMInstrVFP.td" 62180b57cec5SDimitry Andric 62190b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 62200b57cec5SDimitry Andric// Advanced SIMD (NEON) Support 62210b57cec5SDimitry Andric// 62220b57cec5SDimitry Andric 62230b57cec5SDimitry Andricinclude "ARMInstrNEON.td" 62240b57cec5SDimitry Andric 62250b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 62260b57cec5SDimitry Andric// MVE Support 62270b57cec5SDimitry Andric// 62280b57cec5SDimitry Andric 62290b57cec5SDimitry Andricinclude "ARMInstrMVE.td" 62300b57cec5SDimitry Andric 62310b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 62325ffd83dbSDimitry Andric// CDE (Custom Datapath Extension) 62335ffd83dbSDimitry Andric// 62345ffd83dbSDimitry Andric 62355ffd83dbSDimitry Andricinclude "ARMInstrCDE.td" 62365ffd83dbSDimitry Andric 62375ffd83dbSDimitry Andric//===----------------------------------------------------------------------===// 62380b57cec5SDimitry Andric// Assembler aliases 62390b57cec5SDimitry Andric// 62400b57cec5SDimitry Andric 62410b57cec5SDimitry Andric// Memory barriers 62420b57cec5SDimitry Andricdef : InstAlias<"dmb", (DMB 0xf), 0>, Requires<[IsARM, HasDB]>; 62430b57cec5SDimitry Andricdef : InstAlias<"dsb", (DSB 0xf), 0>, Requires<[IsARM, HasDB]>; 62440b57cec5SDimitry Andricdef : InstAlias<"ssbb", (DSB 0x0), 1>, Requires<[IsARM, HasDB]>; 62450b57cec5SDimitry Andricdef : InstAlias<"pssbb", (DSB 0x4), 1>, Requires<[IsARM, HasDB]>; 62460b57cec5SDimitry Andricdef : InstAlias<"isb", (ISB 0xf), 0>, Requires<[IsARM, HasDB]>; 62470b57cec5SDimitry Andric// Armv8-R 'Data Full Barrier' 62480b57cec5SDimitry Andricdef : InstAlias<"dfb", (DSB 0xc), 1>, Requires<[IsARM, HasDFB]>; 62490b57cec5SDimitry Andric 62500b57cec5SDimitry Andric// System instructions 62510b57cec5SDimitry Andricdef : MnemonicAlias<"swi", "svc">; 62520b57cec5SDimitry Andric 62530b57cec5SDimitry Andric// Load / Store Multiple 62540b57cec5SDimitry Andricdef : MnemonicAlias<"ldmfd", "ldm">; 62550b57cec5SDimitry Andricdef : MnemonicAlias<"ldmia", "ldm">; 62560b57cec5SDimitry Andricdef : MnemonicAlias<"ldmea", "ldmdb">; 62570b57cec5SDimitry Andricdef : MnemonicAlias<"stmfd", "stmdb">; 62580b57cec5SDimitry Andricdef : MnemonicAlias<"stmia", "stm">; 62590b57cec5SDimitry Andricdef : MnemonicAlias<"stmea", "stm">; 62600b57cec5SDimitry Andric 62610b57cec5SDimitry Andric// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT with the 62620b57cec5SDimitry Andric// input operands swapped when the shift amount is zero (i.e., unspecified). 62630b57cec5SDimitry Andricdef : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm", 62640b57cec5SDimitry Andric (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p), 0>, 62650b57cec5SDimitry Andric Requires<[IsARM, HasV6]>; 62660b57cec5SDimitry Andricdef : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm", 62670b57cec5SDimitry Andric (PKHBT GPRnopc:$Rd, GPRnopc:$Rm, GPRnopc:$Rn, 0, pred:$p), 0>, 62680b57cec5SDimitry Andric Requires<[IsARM, HasV6]>; 62690b57cec5SDimitry Andric 62700b57cec5SDimitry Andric// PUSH/POP aliases for STM/LDM 62710b57cec5SDimitry Andricdef : ARMInstAlias<"push${p} $regs", (STMDB_UPD SP, pred:$p, reglist:$regs)>; 62720b57cec5SDimitry Andricdef : ARMInstAlias<"pop${p} $regs", (LDMIA_UPD SP, pred:$p, reglist:$regs)>; 62730b57cec5SDimitry Andric 62740b57cec5SDimitry Andric// SSAT/USAT optional shift operand. 62750b57cec5SDimitry Andricdef : ARMInstAlias<"ssat${p} $Rd, $sat_imm, $Rn", 62760b57cec5SDimitry Andric (SSAT GPRnopc:$Rd, imm1_32:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; 62770b57cec5SDimitry Andricdef : ARMInstAlias<"usat${p} $Rd, $sat_imm, $Rn", 62780b57cec5SDimitry Andric (USAT GPRnopc:$Rd, imm0_31:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; 62790b57cec5SDimitry Andric 62800b57cec5SDimitry Andric 62810b57cec5SDimitry Andric// Extend instruction optional rotate operand. 62820b57cec5SDimitry Andricdef : ARMInstAlias<"sxtab${p} $Rd, $Rn, $Rm", 62830b57cec5SDimitry Andric (SXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 62840b57cec5SDimitry Andricdef : ARMInstAlias<"sxtah${p} $Rd, $Rn, $Rm", 62850b57cec5SDimitry Andric (SXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 62860b57cec5SDimitry Andricdef : ARMInstAlias<"sxtab16${p} $Rd, $Rn, $Rm", 62870b57cec5SDimitry Andric (SXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 62880b57cec5SDimitry Andricdef : ARMInstAlias<"sxtb${p} $Rd, $Rm", 62890b57cec5SDimitry Andric (SXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 62900b57cec5SDimitry Andricdef : ARMInstAlias<"sxtb16${p} $Rd, $Rm", 62910b57cec5SDimitry Andric (SXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 62920b57cec5SDimitry Andricdef : ARMInstAlias<"sxth${p} $Rd, $Rm", 62930b57cec5SDimitry Andric (SXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 62940b57cec5SDimitry Andric 62950b57cec5SDimitry Andricdef : ARMInstAlias<"uxtab${p} $Rd, $Rn, $Rm", 62960b57cec5SDimitry Andric (UXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 62970b57cec5SDimitry Andricdef : ARMInstAlias<"uxtah${p} $Rd, $Rn, $Rm", 62980b57cec5SDimitry Andric (UXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 62990b57cec5SDimitry Andricdef : ARMInstAlias<"uxtab16${p} $Rd, $Rn, $Rm", 63000b57cec5SDimitry Andric (UXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; 63010b57cec5SDimitry Andricdef : ARMInstAlias<"uxtb${p} $Rd, $Rm", 63020b57cec5SDimitry Andric (UXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 63030b57cec5SDimitry Andricdef : ARMInstAlias<"uxtb16${p} $Rd, $Rm", 63040b57cec5SDimitry Andric (UXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 63050b57cec5SDimitry Andricdef : ARMInstAlias<"uxth${p} $Rd, $Rm", 63060b57cec5SDimitry Andric (UXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; 63070b57cec5SDimitry Andric 63080b57cec5SDimitry Andric 63090b57cec5SDimitry Andric// RFE aliases 63100b57cec5SDimitry Andricdef : MnemonicAlias<"rfefa", "rfeda">; 63110b57cec5SDimitry Andricdef : MnemonicAlias<"rfeea", "rfedb">; 63120b57cec5SDimitry Andricdef : MnemonicAlias<"rfefd", "rfeia">; 63130b57cec5SDimitry Andricdef : MnemonicAlias<"rfeed", "rfeib">; 63140b57cec5SDimitry Andricdef : MnemonicAlias<"rfe", "rfeia">; 63150b57cec5SDimitry Andric 63160b57cec5SDimitry Andric// SRS aliases 63170b57cec5SDimitry Andricdef : MnemonicAlias<"srsfa", "srsib">; 63180b57cec5SDimitry Andricdef : MnemonicAlias<"srsea", "srsia">; 63190b57cec5SDimitry Andricdef : MnemonicAlias<"srsfd", "srsdb">; 63200b57cec5SDimitry Andricdef : MnemonicAlias<"srsed", "srsda">; 63210b57cec5SDimitry Andricdef : MnemonicAlias<"srs", "srsia">; 63220b57cec5SDimitry Andric 63230b57cec5SDimitry Andric// QSAX == QSUBADDX 63240b57cec5SDimitry Andricdef : MnemonicAlias<"qsubaddx", "qsax">; 63250b57cec5SDimitry Andric// SASX == SADDSUBX 63260b57cec5SDimitry Andricdef : MnemonicAlias<"saddsubx", "sasx">; 63270b57cec5SDimitry Andric// SHASX == SHADDSUBX 63280b57cec5SDimitry Andricdef : MnemonicAlias<"shaddsubx", "shasx">; 63290b57cec5SDimitry Andric// SHSAX == SHSUBADDX 63300b57cec5SDimitry Andricdef : MnemonicAlias<"shsubaddx", "shsax">; 63310b57cec5SDimitry Andric// SSAX == SSUBADDX 63320b57cec5SDimitry Andricdef : MnemonicAlias<"ssubaddx", "ssax">; 63330b57cec5SDimitry Andric// UASX == UADDSUBX 63340b57cec5SDimitry Andricdef : MnemonicAlias<"uaddsubx", "uasx">; 63350b57cec5SDimitry Andric// UHASX == UHADDSUBX 63360b57cec5SDimitry Andricdef : MnemonicAlias<"uhaddsubx", "uhasx">; 63370b57cec5SDimitry Andric// UHSAX == UHSUBADDX 63380b57cec5SDimitry Andricdef : MnemonicAlias<"uhsubaddx", "uhsax">; 63390b57cec5SDimitry Andric// UQASX == UQADDSUBX 63400b57cec5SDimitry Andricdef : MnemonicAlias<"uqaddsubx", "uqasx">; 63410b57cec5SDimitry Andric// UQSAX == UQSUBADDX 63420b57cec5SDimitry Andricdef : MnemonicAlias<"uqsubaddx", "uqsax">; 63430b57cec5SDimitry Andric// USAX == USUBADDX 63440b57cec5SDimitry Andricdef : MnemonicAlias<"usubaddx", "usax">; 63450b57cec5SDimitry Andric 63460b57cec5SDimitry Andric// "mov Rd, mod_imm_not" can be handled via "mvn" in assembly, just like 63470b57cec5SDimitry Andric// for isel. 63480b57cec5SDimitry Andricdef : ARMInstSubst<"mov${s}${p} $Rd, $imm", 63490b57cec5SDimitry Andric (MVNi rGPR:$Rd, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 63500b57cec5SDimitry Andricdef : ARMInstSubst<"mvn${s}${p} $Rd, $imm", 63510b57cec5SDimitry Andric (MOVi rGPR:$Rd, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 63520b57cec5SDimitry Andric// Same for AND <--> BIC 63530b57cec5SDimitry Andricdef : ARMInstSubst<"bic${s}${p} $Rd, $Rn, $imm", 63540b57cec5SDimitry Andric (ANDri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, 63550b57cec5SDimitry Andric pred:$p, cc_out:$s)>; 63560b57cec5SDimitry Andricdef : ARMInstSubst<"bic${s}${p} $Rdn, $imm", 63570b57cec5SDimitry Andric (ANDri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, 63580b57cec5SDimitry Andric pred:$p, cc_out:$s)>; 63590b57cec5SDimitry Andricdef : ARMInstSubst<"and${s}${p} $Rd, $Rn, $imm", 63600b57cec5SDimitry Andric (BICri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, 63610b57cec5SDimitry Andric pred:$p, cc_out:$s)>; 63620b57cec5SDimitry Andricdef : ARMInstSubst<"and${s}${p} $Rdn, $imm", 63630b57cec5SDimitry Andric (BICri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, 63640b57cec5SDimitry Andric pred:$p, cc_out:$s)>; 63650b57cec5SDimitry Andric 63660b57cec5SDimitry Andric// Likewise, "add Rd, mod_imm_neg" -> sub 63670b57cec5SDimitry Andricdef : ARMInstSubst<"add${s}${p} $Rd, $Rn, $imm", 63680b57cec5SDimitry Andric (SUBri GPR:$Rd, GPR:$Rn, mod_imm_neg:$imm, pred:$p, cc_out:$s)>; 63690b57cec5SDimitry Andricdef : ARMInstSubst<"add${s}${p} $Rd, $imm", 63700b57cec5SDimitry Andric (SUBri GPR:$Rd, GPR:$Rd, mod_imm_neg:$imm, pred:$p, cc_out:$s)>; 63710b57cec5SDimitry Andric// Likewise, "sub Rd, mod_imm_neg" -> add 63720b57cec5SDimitry Andricdef : ARMInstSubst<"sub${s}${p} $Rd, $Rn, $imm", 63730b57cec5SDimitry Andric (ADDri GPR:$Rd, GPR:$Rn, mod_imm_neg:$imm, pred:$p, cc_out:$s)>; 63740b57cec5SDimitry Andricdef : ARMInstSubst<"sub${s}${p} $Rd, $imm", 63750b57cec5SDimitry Andric (ADDri GPR:$Rd, GPR:$Rd, mod_imm_neg:$imm, pred:$p, cc_out:$s)>; 63760b57cec5SDimitry Andric 63770b57cec5SDimitry Andric 63780b57cec5SDimitry Andricdef : ARMInstSubst<"adc${s}${p} $Rd, $Rn, $imm", 63790b57cec5SDimitry Andric (SBCri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 63800b57cec5SDimitry Andricdef : ARMInstSubst<"adc${s}${p} $Rdn, $imm", 63810b57cec5SDimitry Andric (SBCri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 63820b57cec5SDimitry Andricdef : ARMInstSubst<"sbc${s}${p} $Rd, $Rn, $imm", 63830b57cec5SDimitry Andric (ADCri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 63840b57cec5SDimitry Andricdef : ARMInstSubst<"sbc${s}${p} $Rdn, $imm", 63850b57cec5SDimitry Andric (ADCri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, pred:$p, cc_out:$s)>; 63860b57cec5SDimitry Andric 63870b57cec5SDimitry Andric// Same for CMP <--> CMN via mod_imm_neg 63880b57cec5SDimitry Andricdef : ARMInstSubst<"cmp${p} $Rd, $imm", 63890b57cec5SDimitry Andric (CMNri rGPR:$Rd, mod_imm_neg:$imm, pred:$p)>; 63900b57cec5SDimitry Andricdef : ARMInstSubst<"cmn${p} $Rd, $imm", 63910b57cec5SDimitry Andric (CMPri rGPR:$Rd, mod_imm_neg:$imm, pred:$p)>; 63920b57cec5SDimitry Andric 63930b57cec5SDimitry Andric// The shifter forms of the MOV instruction are aliased to the ASR, LSL, 63940b57cec5SDimitry Andric// LSR, ROR, and RRX instructions. 63950b57cec5SDimitry Andric// FIXME: We need C++ parser hooks to map the alias to the MOV 63960b57cec5SDimitry Andric// encoding. It seems we should be able to do that sort of thing 63970b57cec5SDimitry Andric// in tblgen, but it could get ugly. 63980b57cec5SDimitry Andriclet TwoOperandAliasConstraint = "$Rm = $Rd" in { 63990b57cec5SDimitry Andricdef ASRi : ARMAsmPseudo<"asr${s}${p} $Rd, $Rm, $imm", 64000b57cec5SDimitry Andric (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p, 64010b57cec5SDimitry Andric cc_out:$s)>; 64020b57cec5SDimitry Andricdef LSRi : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rm, $imm", 64030b57cec5SDimitry Andric (ins GPR:$Rd, GPR:$Rm, imm0_32:$imm, pred:$p, 64040b57cec5SDimitry Andric cc_out:$s)>; 64050b57cec5SDimitry Andricdef LSLi : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rm, $imm", 64060b57cec5SDimitry Andric (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p, 64070b57cec5SDimitry Andric cc_out:$s)>; 64080b57cec5SDimitry Andricdef RORi : ARMAsmPseudo<"ror${s}${p} $Rd, $Rm, $imm", 64090b57cec5SDimitry Andric (ins GPR:$Rd, GPR:$Rm, imm0_31:$imm, pred:$p, 64100b57cec5SDimitry Andric cc_out:$s)>; 64110b57cec5SDimitry Andric} 64120b57cec5SDimitry Andricdef RRXi : ARMAsmPseudo<"rrx${s}${p} $Rd, $Rm", 64130b57cec5SDimitry Andric (ins GPR:$Rd, GPR:$Rm, pred:$p, cc_out:$s)>; 64140b57cec5SDimitry Andriclet TwoOperandAliasConstraint = "$Rn = $Rd" in { 64150b57cec5SDimitry Andricdef ASRr : ARMAsmPseudo<"asr${s}${p} $Rd, $Rn, $Rm", 64160b57cec5SDimitry Andric (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 64170b57cec5SDimitry Andric cc_out:$s)>; 64180b57cec5SDimitry Andricdef LSRr : ARMAsmPseudo<"lsr${s}${p} $Rd, $Rn, $Rm", 64190b57cec5SDimitry Andric (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 64200b57cec5SDimitry Andric cc_out:$s)>; 64210b57cec5SDimitry Andricdef LSLr : ARMAsmPseudo<"lsl${s}${p} $Rd, $Rn, $Rm", 64220b57cec5SDimitry Andric (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 64230b57cec5SDimitry Andric cc_out:$s)>; 64240b57cec5SDimitry Andricdef RORr : ARMAsmPseudo<"ror${s}${p} $Rd, $Rn, $Rm", 64250b57cec5SDimitry Andric (ins GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, 64260b57cec5SDimitry Andric cc_out:$s)>; 64270b57cec5SDimitry Andric} 64280b57cec5SDimitry Andric 64290b57cec5SDimitry Andric// "neg" is and alias for "rsb rd, rn, #0" 64300b57cec5SDimitry Andricdef : ARMInstAlias<"neg${s}${p} $Rd, $Rm", 64310b57cec5SDimitry Andric (RSBri GPR:$Rd, GPR:$Rm, 0, pred:$p, cc_out:$s)>; 64320b57cec5SDimitry Andric 64330b57cec5SDimitry Andric// Pre-v6, 'mov r0, r0' was used as a NOP encoding. 643481ad6265SDimitry Andricdef : InstAlias<"nop${p}", (MOVr R0, R0, pred:$p, zero_reg), 0>, 64350b57cec5SDimitry Andric Requires<[IsARM, NoV6]>; 64360b57cec5SDimitry Andric 64370b57cec5SDimitry Andric// MUL/UMLAL/SMLAL/UMULL/SMULL are available on all arches, but 64380b57cec5SDimitry Andric// the instruction definitions need difference constraints pre-v6. 64390b57cec5SDimitry Andric// Use these aliases for the assembly parsing on pre-v6. 64400b57cec5SDimitry Andricdef : InstAlias<"mul${s}${p} $Rd, $Rn, $Rm", 64410b57cec5SDimitry Andric (MUL GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, pred:$p, cc_out:$s), 0>, 64420b57cec5SDimitry Andric Requires<[IsARM, NoV6]>; 64430b57cec5SDimitry Andricdef : InstAlias<"mla${s}${p} $Rd, $Rn, $Rm, $Ra", 64440b57cec5SDimitry Andric (MLA GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, GPRnopc:$Ra, 64450b57cec5SDimitry Andric pred:$p, cc_out:$s), 0>, 64460b57cec5SDimitry Andric Requires<[IsARM, NoV6]>; 64470b57cec5SDimitry Andricdef : InstAlias<"smlal${s}${p} $RdLo, $RdHi, $Rn, $Rm", 64480b57cec5SDimitry Andric (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>, 64490b57cec5SDimitry Andric Requires<[IsARM, NoV6]>; 64500b57cec5SDimitry Andricdef : InstAlias<"umlal${s}${p} $RdLo, $RdHi, $Rn, $Rm", 64510b57cec5SDimitry Andric (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>, 64520b57cec5SDimitry Andric Requires<[IsARM, NoV6]>; 64530b57cec5SDimitry Andricdef : InstAlias<"smull${s}${p} $RdLo, $RdHi, $Rn, $Rm", 64540b57cec5SDimitry Andric (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>, 64550b57cec5SDimitry Andric Requires<[IsARM, NoV6]>; 64560b57cec5SDimitry Andricdef : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm", 64570b57cec5SDimitry Andric (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 0>, 64580b57cec5SDimitry Andric Requires<[IsARM, NoV6]>; 64590b57cec5SDimitry Andric 64600b57cec5SDimitry Andric// 'it' blocks in ARM mode just validate the predicates. The IT itself 64610b57cec5SDimitry Andric// is discarded. 646281ad6265SDimitry Andricdef ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>; 64630b57cec5SDimitry Andric 64648bcb0991SDimitry Andriclet mayLoad = 1, mayStore =1, hasSideEffects = 1, hasNoSchedulingInfo = 1 in 64650b57cec5SDimitry Andricdef SPACE : PseudoInst<(outs GPR:$Rd), (ins i32imm:$size, GPR:$Rn), 64660b57cec5SDimitry Andric NoItinerary, 64678bcb0991SDimitry Andric [(set GPR:$Rd, (int_arm_space timm:$size, GPR:$Rn))]>; 64680b57cec5SDimitry Andric 6469e8d8bef9SDimitry Andric// SpeculationBarrierEndBB must only be used after an unconditional control 6470e8d8bef9SDimitry Andric// flow, i.e. after a terminator for which isBarrier is True. 6471e8d8bef9SDimitry Andriclet hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in { 64721fd87a68SDimitry Andric // This gets lowered to a pair of 4-byte instructions 64731fd87a68SDimitry Andric let Size = 8 in 6474e8d8bef9SDimitry Andric def SpeculationBarrierISBDSBEndBB 6475e8d8bef9SDimitry Andric : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>; 64761fd87a68SDimitry Andric // This gets lowered to a single 4-byte instructions 64771fd87a68SDimitry Andric let Size = 4 in 6478e8d8bef9SDimitry Andric def SpeculationBarrierSBEndBB 6479e8d8bef9SDimitry Andric : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>; 6480e8d8bef9SDimitry Andric} 6481e8d8bef9SDimitry Andric 64820b57cec5SDimitry Andric//===---------------------------------- 64830b57cec5SDimitry Andric// Atomic cmpxchg for -O0 64840b57cec5SDimitry Andric//===---------------------------------- 64850b57cec5SDimitry Andric 64860b57cec5SDimitry Andric// The fast register allocator used during -O0 inserts spills to cover any VRegs 64870b57cec5SDimitry Andric// live across basic block boundaries. When this happens between an LDXR and an 64880b57cec5SDimitry Andric// STXR it can clear the exclusive monitor, causing all cmpxchg attempts to 64890b57cec5SDimitry Andric// fail. 64900b57cec5SDimitry Andric 64910b57cec5SDimitry Andric// Unfortunately, this means we have to have an alternative (expanded 64920b57cec5SDimitry Andric// post-regalloc) path for -O0 compilations. Fortunately this path can be 64930b57cec5SDimitry Andric// significantly more naive than the standard expansion: we conservatively 64940b57cec5SDimitry Andric// assume seq_cst, strong cmpxchg and omit clrex on failure. 64950b57cec5SDimitry Andric 64960b57cec5SDimitry Andriclet Constraints = "@earlyclobber $Rd,@earlyclobber $temp", 64970b57cec5SDimitry Andric mayLoad = 1, mayStore = 1 in { 64980b57cec5SDimitry Andricdef CMP_SWAP_8 : PseudoInst<(outs GPR:$Rd, GPR:$temp), 64990b57cec5SDimitry Andric (ins GPR:$addr, GPR:$desired, GPR:$new), 65000b57cec5SDimitry Andric NoItinerary, []>, Sched<[]>; 65010b57cec5SDimitry Andric 65020b57cec5SDimitry Andricdef CMP_SWAP_16 : PseudoInst<(outs GPR:$Rd, GPR:$temp), 65030b57cec5SDimitry Andric (ins GPR:$addr, GPR:$desired, GPR:$new), 65040b57cec5SDimitry Andric NoItinerary, []>, Sched<[]>; 65050b57cec5SDimitry Andric 65060b57cec5SDimitry Andricdef CMP_SWAP_32 : PseudoInst<(outs GPR:$Rd, GPR:$temp), 65070b57cec5SDimitry Andric (ins GPR:$addr, GPR:$desired, GPR:$new), 65080b57cec5SDimitry Andric NoItinerary, []>, Sched<[]>; 65090b57cec5SDimitry Andric 65100b57cec5SDimitry Andricdef CMP_SWAP_64 : PseudoInst<(outs GPRPair:$Rd, GPR:$temp), 65110b57cec5SDimitry Andric (ins GPR:$addr, GPRPair:$desired, GPRPair:$new), 65120b57cec5SDimitry Andric NoItinerary, []>, Sched<[]>; 65130b57cec5SDimitry Andric} 65140b57cec5SDimitry Andric 6515bdd1243dSDimitry Andricdef : Pat<(atomic_fence (timm), 0), (MEMBARRIER)>; 651681ad6265SDimitry Andric 651781ad6265SDimitry Andric//===----------------------------------------------------------------------===// 651881ad6265SDimitry Andric// Instructions used for emitting unwind opcodes on Windows. 651981ad6265SDimitry Andric//===----------------------------------------------------------------------===// 652081ad6265SDimitry Andriclet isPseudo = 1 in { 652181ad6265SDimitry Andric def SEH_StackAlloc : PseudoInst<(outs), (ins i32imm:$size, i32imm:$wide), NoItinerary, []>, Sched<[]>; 652281ad6265SDimitry Andric def SEH_SaveRegs : PseudoInst<(outs), (ins i32imm:$mask, i32imm:$wide), NoItinerary, []>, Sched<[]>; 652381ad6265SDimitry Andric let isTerminator = 1 in 652481ad6265SDimitry Andric def SEH_SaveRegs_Ret : PseudoInst<(outs), (ins i32imm:$mask, i32imm:$wide), NoItinerary, []>, Sched<[]>; 652581ad6265SDimitry Andric def SEH_SaveSP : PseudoInst<(outs), (ins i32imm:$reg), NoItinerary, []>, Sched<[]>; 652681ad6265SDimitry Andric def SEH_SaveFRegs : PseudoInst<(outs), (ins i32imm:$first, i32imm:$last), NoItinerary, []>, Sched<[]>; 652781ad6265SDimitry Andric let isTerminator = 1 in 652881ad6265SDimitry Andric def SEH_SaveLR : PseudoInst<(outs), (ins i32imm:$offst), NoItinerary, []>, Sched<[]>; 652981ad6265SDimitry Andric def SEH_Nop : PseudoInst<(outs), (ins i32imm:$wide), NoItinerary, []>, Sched<[]>; 653081ad6265SDimitry Andric let isTerminator = 1 in 653181ad6265SDimitry Andric def SEH_Nop_Ret : PseudoInst<(outs), (ins i32imm:$wide), NoItinerary, []>, Sched<[]>; 653281ad6265SDimitry Andric def SEH_PrologEnd : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>; 653381ad6265SDimitry Andric def SEH_EpilogStart : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>; 653481ad6265SDimitry Andric let isTerminator = 1 in 653581ad6265SDimitry Andric def SEH_EpilogEnd : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>; 653681ad6265SDimitry Andric} 6537*0fca6ea1SDimitry Andric 6538*0fca6ea1SDimitry Andric 6539*0fca6ea1SDimitry Andric//===----------------------------------------------------------------------===// 6540*0fca6ea1SDimitry Andric// Pseudo Instructions for use when early-clobber is defined and Greedy Register 6541*0fca6ea1SDimitry Andric// Allocation is used. This ensures the constraint is used properly. 6542*0fca6ea1SDimitry Andric//===----------------------------------------------------------------------===// 6543*0fca6ea1SDimitry Andriclet isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in { 6544*0fca6ea1SDimitry Andric def PseudoARMInitUndefMQPR : PseudoInst<(outs MQPR:$vd), (ins), NoItinerary, []>; 6545*0fca6ea1SDimitry Andric def PseudoARMInitUndefSPR : PseudoInst<(outs SPR:$sd), (ins), NoItinerary, []>; 6546*0fca6ea1SDimitry Andric def PseudoARMInitUndefDPR_VFP2 : PseudoInst<(outs DPR_VFP2:$dd), (ins), NoItinerary, []>; 6547*0fca6ea1SDimitry Andric def PseudoARMInitUndefGPR : PseudoInst<(outs GPR:$rd), (ins), NoItinerary, []>; 6548*0fca6ea1SDimitry Andric} 6549