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