10b57cec5SDimitry Andric//===-- ARMInstrFormats.td - ARM Instruction Formats -------*- 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//===----------------------------------------------------------------------===// 100b57cec5SDimitry Andric// 110b57cec5SDimitry Andric// ARM Instruction Format Definitions. 120b57cec5SDimitry Andric// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric// Format specifies the encoding used by the instruction. This is part of the 150b57cec5SDimitry Andric// ad-hoc solution used to emit machine instruction encodings by our machine 160b57cec5SDimitry Andric// code emitter. 170b57cec5SDimitry Andricclass Format<bits<6> val> { 180b57cec5SDimitry Andric bits<6> Value = val; 190b57cec5SDimitry Andric} 200b57cec5SDimitry Andric 210b57cec5SDimitry Andricdef Pseudo : Format<0>; 220b57cec5SDimitry Andricdef MulFrm : Format<1>; 230b57cec5SDimitry Andricdef BrFrm : Format<2>; 240b57cec5SDimitry Andricdef BrMiscFrm : Format<3>; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andricdef DPFrm : Format<4>; 270b57cec5SDimitry Andricdef DPSoRegRegFrm : Format<5>; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andricdef LdFrm : Format<6>; 300b57cec5SDimitry Andricdef StFrm : Format<7>; 310b57cec5SDimitry Andricdef LdMiscFrm : Format<8>; 320b57cec5SDimitry Andricdef StMiscFrm : Format<9>; 330b57cec5SDimitry Andricdef LdStMulFrm : Format<10>; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andricdef LdStExFrm : Format<11>; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andricdef ArithMiscFrm : Format<12>; 380b57cec5SDimitry Andricdef SatFrm : Format<13>; 390b57cec5SDimitry Andricdef ExtFrm : Format<14>; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andricdef VFPUnaryFrm : Format<15>; 420b57cec5SDimitry Andricdef VFPBinaryFrm : Format<16>; 430b57cec5SDimitry Andricdef VFPConv1Frm : Format<17>; 440b57cec5SDimitry Andricdef VFPConv2Frm : Format<18>; 450b57cec5SDimitry Andricdef VFPConv3Frm : Format<19>; 460b57cec5SDimitry Andricdef VFPConv4Frm : Format<20>; 470b57cec5SDimitry Andricdef VFPConv5Frm : Format<21>; 480b57cec5SDimitry Andricdef VFPLdStFrm : Format<22>; 490b57cec5SDimitry Andricdef VFPLdStMulFrm : Format<23>; 500b57cec5SDimitry Andricdef VFPMiscFrm : Format<24>; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andricdef ThumbFrm : Format<25>; 530b57cec5SDimitry Andricdef MiscFrm : Format<26>; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andricdef NGetLnFrm : Format<27>; 560b57cec5SDimitry Andricdef NSetLnFrm : Format<28>; 570b57cec5SDimitry Andricdef NDupFrm : Format<29>; 580b57cec5SDimitry Andricdef NLdStFrm : Format<30>; 590b57cec5SDimitry Andricdef N1RegModImmFrm: Format<31>; 600b57cec5SDimitry Andricdef N2RegFrm : Format<32>; 610b57cec5SDimitry Andricdef NVCVTFrm : Format<33>; 620b57cec5SDimitry Andricdef NVDupLnFrm : Format<34>; 630b57cec5SDimitry Andricdef N2RegVShLFrm : Format<35>; 640b57cec5SDimitry Andricdef N2RegVShRFrm : Format<36>; 650b57cec5SDimitry Andricdef N3RegFrm : Format<37>; 660b57cec5SDimitry Andricdef N3RegVShFrm : Format<38>; 670b57cec5SDimitry Andricdef NVExtFrm : Format<39>; 680b57cec5SDimitry Andricdef NVMulSLFrm : Format<40>; 690b57cec5SDimitry Andricdef NVTBLFrm : Format<41>; 700b57cec5SDimitry Andricdef DPSoRegImmFrm : Format<42>; 710b57cec5SDimitry Andricdef N3RegCplxFrm : Format<43>; 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric// Misc flags. 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric// The instruction has an Rn register operand. 760b57cec5SDimitry Andric// UnaryDP - Indicates this is a unary data processing instruction, i.e. 770b57cec5SDimitry Andric// it doesn't have a Rn operand. 780b57cec5SDimitry Andricclass UnaryDP { bit isUnaryDataProc = 1; } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric// Xform16Bit - Indicates this Thumb2 instruction may be transformed into 810b57cec5SDimitry Andric// a 16-bit Thumb instruction if certain conditions are met. 820b57cec5SDimitry Andricclass Xform16Bit { bit canXformTo16Bit = 1; } 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 850b57cec5SDimitry Andric// ARM Instruction flags. These need to match ARMBaseInstrInfo.h. 860b57cec5SDimitry Andric// 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric// FIXME: Once the JIT is MC-ized, these can go away. 890b57cec5SDimitry Andric// Addressing mode. 900b57cec5SDimitry Andricclass AddrMode<bits<5> val> { 910b57cec5SDimitry Andric bits<5> Value = val; 920b57cec5SDimitry Andric} 930b57cec5SDimitry Andricdef AddrModeNone : AddrMode<0>; 940b57cec5SDimitry Andricdef AddrMode1 : AddrMode<1>; 950b57cec5SDimitry Andricdef AddrMode2 : AddrMode<2>; 960b57cec5SDimitry Andricdef AddrMode3 : AddrMode<3>; 970b57cec5SDimitry Andricdef AddrMode4 : AddrMode<4>; 980b57cec5SDimitry Andricdef AddrMode5 : AddrMode<5>; 990b57cec5SDimitry Andricdef AddrMode6 : AddrMode<6>; 1000b57cec5SDimitry Andricdef AddrModeT1_1 : AddrMode<7>; 1010b57cec5SDimitry Andricdef AddrModeT1_2 : AddrMode<8>; 1020b57cec5SDimitry Andricdef AddrModeT1_4 : AddrMode<9>; 1030b57cec5SDimitry Andricdef AddrModeT1_s : AddrMode<10>; 1040b57cec5SDimitry Andricdef AddrModeT2_i12 : AddrMode<11>; 1050b57cec5SDimitry Andricdef AddrModeT2_i8 : AddrMode<12>; 1064824e7fdSDimitry Andricdef AddrModeT2_i8pos : AddrMode<13>; 1074824e7fdSDimitry Andricdef AddrModeT2_i8neg : AddrMode<14>; 1084824e7fdSDimitry Andricdef AddrModeT2_so : AddrMode<15>; 1094824e7fdSDimitry Andricdef AddrModeT2_pc : AddrMode<16>; 1104824e7fdSDimitry Andricdef AddrModeT2_i8s4 : AddrMode<17>; 1114824e7fdSDimitry Andricdef AddrMode_i12 : AddrMode<18>; 1124824e7fdSDimitry Andricdef AddrMode5FP16 : AddrMode<19>; 1134824e7fdSDimitry Andricdef AddrModeT2_ldrex : AddrMode<20>; 1144824e7fdSDimitry Andricdef AddrModeT2_i7s4 : AddrMode<21>; 1154824e7fdSDimitry Andricdef AddrModeT2_i7s2 : AddrMode<22>; 1164824e7fdSDimitry Andricdef AddrModeT2_i7 : AddrMode<23>; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric// Load / store index mode. 1190b57cec5SDimitry Andricclass IndexMode<bits<2> val> { 1200b57cec5SDimitry Andric bits<2> Value = val; 1210b57cec5SDimitry Andric} 1220b57cec5SDimitry Andricdef IndexModeNone : IndexMode<0>; 1230b57cec5SDimitry Andricdef IndexModePre : IndexMode<1>; 1240b57cec5SDimitry Andricdef IndexModePost : IndexMode<2>; 1250b57cec5SDimitry Andricdef IndexModeUpd : IndexMode<3>; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric// Instruction execution domain. 1280b57cec5SDimitry Andricclass Domain<bits<4> val> { 1290b57cec5SDimitry Andric bits<4> Value = val; 1300b57cec5SDimitry Andric} 1310b57cec5SDimitry Andricdef GenericDomain : Domain<0>; 1320b57cec5SDimitry Andricdef VFPDomain : Domain<1>; // Instructions in VFP domain only 1330b57cec5SDimitry Andricdef NeonDomain : Domain<2>; // Instructions in Neon domain only 1340b57cec5SDimitry Andricdef VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains 1350b57cec5SDimitry Andricdef VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8 1360b57cec5SDimitry Andricdef MVEDomain : Domain<8>; // Instructions in MVE and ARMv8.1m 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 1390b57cec5SDimitry Andric// ARM special operands. 1400b57cec5SDimitry Andric// 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric// ARM imod and iflag operands, used only by the CPS instruction. 1430b57cec5SDimitry Andricdef imod_op : Operand<i32> { 1440b57cec5SDimitry Andric let PrintMethod = "printCPSIMod"; 1450b57cec5SDimitry Andric} 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andricdef ProcIFlagsOperand : AsmOperandClass { 1480b57cec5SDimitry Andric let Name = "ProcIFlags"; 1490b57cec5SDimitry Andric let ParserMethod = "parseProcIFlagsOperand"; 1500b57cec5SDimitry Andric} 1510b57cec5SDimitry Andricdef iflags_op : Operand<i32> { 1520b57cec5SDimitry Andric let PrintMethod = "printCPSIFlag"; 1530b57cec5SDimitry Andric let ParserMatchClass = ProcIFlagsOperand; 1540b57cec5SDimitry Andric} 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric// ARM Predicate operand. Default to 14 = always (AL). Second part is CC 1570b57cec5SDimitry Andric// register whose default is 0 (no register). 158*0fca6ea1SDimitry Andricdef CondCodeOperand : AsmOperandClass { 159*0fca6ea1SDimitry Andric let Name = "CondCode"; 160*0fca6ea1SDimitry Andric let DefaultMethod = "defaultCondCodeOp"; 161*0fca6ea1SDimitry Andric let IsOptional = true; 162*0fca6ea1SDimitry Andric} 1630b57cec5SDimitry Andricdef pred : PredicateOperand<OtherVT, (ops i32imm, i32imm), 1640b57cec5SDimitry Andric (ops (i32 14), (i32 zero_reg))> { 1650b57cec5SDimitry Andric let PrintMethod = "printPredicateOperand"; 1660b57cec5SDimitry Andric let ParserMatchClass = CondCodeOperand; 1670b57cec5SDimitry Andric let DecoderMethod = "DecodePredicateOperand"; 1680b57cec5SDimitry Andric} 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric// Selectable predicate operand for CMOV instructions. We can't use a normal 1710b57cec5SDimitry Andric// predicate because the default values interfere with instruction selection. In 1720b57cec5SDimitry Andric// all other respects it is identical though: pseudo-instruction expansion 1730b57cec5SDimitry Andric// relies on the MachineOperands being compatible. 1740b57cec5SDimitry Andricdef cmovpred : Operand<i32>, PredicateOp, 1750b57cec5SDimitry Andric ComplexPattern<i32, 2, "SelectCMOVPred"> { 1760b57cec5SDimitry Andric let MIOperandInfo = (ops i32imm, i32imm); 1770b57cec5SDimitry Andric let PrintMethod = "printPredicateOperand"; 1780b57cec5SDimitry Andric} 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric// Conditional code result for instructions whose 's' bit is set, e.g. subs. 181*0fca6ea1SDimitry Andricdef CCOutOperand : AsmOperandClass { 182*0fca6ea1SDimitry Andric let Name = "CCOut"; 183*0fca6ea1SDimitry Andric let DefaultMethod = "defaultCCOutOp"; 184*0fca6ea1SDimitry Andric let IsOptional = true; 185*0fca6ea1SDimitry Andric} 1860b57cec5SDimitry Andricdef cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> { 1870b57cec5SDimitry Andric let EncoderMethod = "getCCOutOpValue"; 1880b57cec5SDimitry Andric let PrintMethod = "printSBitModifierOperand"; 1890b57cec5SDimitry Andric let ParserMatchClass = CCOutOperand; 1900b57cec5SDimitry Andric let DecoderMethod = "DecodeCCOutOperand"; 1910b57cec5SDimitry Andric} 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric// Same as cc_out except it defaults to setting CPSR. 1940b57cec5SDimitry Andricdef s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> { 1950b57cec5SDimitry Andric let EncoderMethod = "getCCOutOpValue"; 1960b57cec5SDimitry Andric let PrintMethod = "printSBitModifierOperand"; 1970b57cec5SDimitry Andric let ParserMatchClass = CCOutOperand; 1980b57cec5SDimitry Andric let DecoderMethod = "DecodeCCOutOperand"; 1990b57cec5SDimitry Andric} 2000b57cec5SDimitry Andric 2018bcb0991SDimitry Andric// Transform to generate the inverse of a condition code during ISel 2028bcb0991SDimitry Andricdef inv_cond_XFORM : SDNodeXForm<imm, [{ 2038bcb0991SDimitry Andric ARMCC::CondCodes CC = static_cast<ARMCC::CondCodes>(N->getZExtValue()); 2048bcb0991SDimitry Andric return CurDAG->getTargetConstant(ARMCC::getOppositeCondition(CC), SDLoc(N), 2058bcb0991SDimitry Andric MVT::i32); 2068bcb0991SDimitry Andric}]>; 2078bcb0991SDimitry Andric 2080b57cec5SDimitry Andric// VPT predicate 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andricdef VPTPredNOperand : AsmOperandClass { 2110b57cec5SDimitry Andric let Name = "VPTPredN"; 2120b57cec5SDimitry Andric let PredicateMethod = "isVPTPred"; 213*0fca6ea1SDimitry Andric let DefaultMethod = "defaultVPTPredOp"; 214*0fca6ea1SDimitry Andric let IsOptional = true; 2150b57cec5SDimitry Andric} 2160b57cec5SDimitry Andricdef VPTPredROperand : AsmOperandClass { 2170b57cec5SDimitry Andric let Name = "VPTPredR"; 2180b57cec5SDimitry Andric let PredicateMethod = "isVPTPred"; 219*0fca6ea1SDimitry Andric let DefaultMethod = "defaultVPTPredOp"; 220*0fca6ea1SDimitry Andric let IsOptional = true; 2210b57cec5SDimitry Andric} 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric// Operand classes for the cluster of MC operands describing a 2240b57cec5SDimitry Andric// VPT-predicated MVE instruction. 2250b57cec5SDimitry Andric// 2260b57cec5SDimitry Andric// There are two of these classes. Both of them have the same first 2270b57cec5SDimitry Andric// two options: 2280b57cec5SDimitry Andric// 2290b57cec5SDimitry Andric// $cond (an integer) indicates the instruction's predication status: 2300b57cec5SDimitry Andric// * ARMVCC::None means it's unpredicated 2310b57cec5SDimitry Andric// * ARMVCC::Then means it's in a VPT block and appears with the T suffix 2320b57cec5SDimitry Andric// * ARMVCC::Else means it's in a VPT block and appears with the E suffix. 2330b57cec5SDimitry Andric// During code generation, unpredicated and predicated instructions 2340b57cec5SDimitry Andric// are indicated by setting this parameter to 'None' or to 'Then'; the 2350b57cec5SDimitry Andric// third value 'Else' is only used for assembly and disassembly. 2360b57cec5SDimitry Andric// 2370b57cec5SDimitry Andric// $cond_reg (type VCCR) gives the input predicate register. This is 2380b57cec5SDimitry Andric// always either zero_reg or VPR, but needs to be modelled as an 2390b57cec5SDimitry Andric// explicit operand so that it can be register-allocated and spilled 2400b57cec5SDimitry Andric// when these operands are used in code generation). 2410b57cec5SDimitry Andric// 2420b57cec5SDimitry Andric// For 'vpred_r', there's an extra operand $inactive, which specifies 2430b57cec5SDimitry Andric// the vector register which will supply any lanes of the output 2440b57cec5SDimitry Andric// register that the predication mask prevents from being written by 2450b57cec5SDimitry Andric// this instruction. It's always tied to the actual output register 2460b57cec5SDimitry Andric// (i.e. must be allocated into the same physical reg), but again, 2470b57cec5SDimitry Andric// code generation will need to model it as a separate input value. 2480b57cec5SDimitry Andric// 2490b57cec5SDimitry Andric// 'vpred_n' doesn't have that extra operand: it only has $cond and 2500b57cec5SDimitry Andric// $cond_reg. This variant is used for any instruction that can't, or 2510b57cec5SDimitry Andric// doesn't want to, tie $inactive to the output register. Sometimes 2520b57cec5SDimitry Andric// that's because another input parameter is already tied to it (e.g. 2530b57cec5SDimitry Andric// instructions that both read and write their Qd register even when 2540b57cec5SDimitry Andric// unpredicated, either because they only partially overwrite it like 2550b57cec5SDimitry Andric// a narrowing integer conversion, or simply because the instruction 2560b57cec5SDimitry Andric// encoding doesn't have enough register fields to make the output 2570b57cec5SDimitry Andric// independent of all inputs). It can also be because the instruction 2580b57cec5SDimitry Andric// is defined to set disabled output lanes to zero rather than leaving 2590b57cec5SDimitry Andric// them unchanged (vector loads), or because it doesn't output a 2600b57cec5SDimitry Andric// vector register at all (stores, compares). In any of these 2610b57cec5SDimitry Andric// situations it's unnecessary to have an extra operand tied to the 2620b57cec5SDimitry Andric// output, and inconvenient to leave it there unused. 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric// Base class for both kinds of vpred. 2650b57cec5SDimitry Andricclass vpred_ops<dag extra_op, dag extra_mi> : OperandWithDefaultOps<OtherVT, 266349cc55cSDimitry Andric !con((ops (i32 0), (i32 zero_reg), (i32 zero_reg)), extra_op)> { 2670b57cec5SDimitry Andric let PrintMethod = "printVPTPredicateOperand"; 2680b57cec5SDimitry Andric let OperandNamespace = "ARM"; 269349cc55cSDimitry Andric let MIOperandInfo = !con((ops i32imm:$cond, VCCR:$cond_reg, GPRlr:$tp_reg), extra_mi); 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric // For convenience, we provide a string value that can be appended 2720b57cec5SDimitry Andric // to the constraints string. It's empty for vpred_n, and for 2730b57cec5SDimitry Andric // vpred_r it ties the $inactive operand to the output q-register 2740b57cec5SDimitry Andric // (which by convention will be called $Qd). 2750b57cec5SDimitry Andric string vpred_constraint; 2760b57cec5SDimitry Andric} 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andricdef vpred_r : vpred_ops<(ops (v4i32 undef_tied_input)), (ops MQPR:$inactive)> { 2790b57cec5SDimitry Andric let ParserMatchClass = VPTPredROperand; 2800b57cec5SDimitry Andric let OperandType = "OPERAND_VPRED_R"; 2810b57cec5SDimitry Andric let DecoderMethod = "DecodeVpredROperand"; 2820b57cec5SDimitry Andric let vpred_constraint = ",$Qd = $vp.inactive"; 2830b57cec5SDimitry Andric} 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andricdef vpred_n : vpred_ops<(ops), (ops)> { 2860b57cec5SDimitry Andric let ParserMatchClass = VPTPredNOperand; 2870b57cec5SDimitry Andric let OperandType = "OPERAND_VPRED_N"; 288bdd1243dSDimitry Andric let DecoderMethod = "DecodeVpredNOperand"; 2890b57cec5SDimitry Andric let vpred_constraint = ""; 2900b57cec5SDimitry Andric} 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric// ARM special operands for disassembly only. 2930b57cec5SDimitry Andric// 2940b57cec5SDimitry Andricdef SetEndAsmOperand : ImmAsmOperand<0,1> { 2950b57cec5SDimitry Andric let Name = "SetEndImm"; 2960b57cec5SDimitry Andric let ParserMethod = "parseSetEndImm"; 2970b57cec5SDimitry Andric} 2980b57cec5SDimitry Andricdef setend_op : Operand<i32> { 2990b57cec5SDimitry Andric let PrintMethod = "printSetendOperand"; 3000b57cec5SDimitry Andric let ParserMatchClass = SetEndAsmOperand; 3010b57cec5SDimitry Andric} 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andricdef MSRMaskOperand : AsmOperandClass { 3040b57cec5SDimitry Andric let Name = "MSRMask"; 3050b57cec5SDimitry Andric let ParserMethod = "parseMSRMaskOperand"; 3060b57cec5SDimitry Andric} 3070b57cec5SDimitry Andricdef msr_mask : Operand<i32> { 3080b57cec5SDimitry Andric let PrintMethod = "printMSRMaskOperand"; 3090b57cec5SDimitry Andric let DecoderMethod = "DecodeMSRMask"; 3100b57cec5SDimitry Andric let ParserMatchClass = MSRMaskOperand; 3110b57cec5SDimitry Andric} 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andricdef BankedRegOperand : AsmOperandClass { 3140b57cec5SDimitry Andric let Name = "BankedReg"; 3150b57cec5SDimitry Andric let ParserMethod = "parseBankedRegOperand"; 3160b57cec5SDimitry Andric} 3170b57cec5SDimitry Andricdef banked_reg : Operand<i32> { 3180b57cec5SDimitry Andric let PrintMethod = "printBankedRegOperand"; 3190b57cec5SDimitry Andric let DecoderMethod = "DecodeBankedReg"; 3200b57cec5SDimitry Andric let ParserMatchClass = BankedRegOperand; 3210b57cec5SDimitry Andric} 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric// Shift Right Immediate - A shift right immediate is encoded differently from 3240b57cec5SDimitry Andric// other shift immediates. The imm6 field is encoded like so: 3250b57cec5SDimitry Andric// 3260b57cec5SDimitry Andric// Offset Encoding 3270b57cec5SDimitry Andric// 8 imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0> 3280b57cec5SDimitry Andric// 16 imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0> 3290b57cec5SDimitry Andric// 32 imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0> 3300b57cec5SDimitry Andric// 64 64 - <imm> is encoded in imm6<5:0> 3310b57cec5SDimitry Andricdef shr_imm8_asm_operand : ImmAsmOperand<1,8> { let Name = "ShrImm8"; } 3320b57cec5SDimitry Andricdef shr_imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 8; }]> { 3330b57cec5SDimitry Andric let EncoderMethod = "getShiftRight8Imm"; 3340b57cec5SDimitry Andric let DecoderMethod = "DecodeShiftRight8Imm"; 3350b57cec5SDimitry Andric let ParserMatchClass = shr_imm8_asm_operand; 3360b57cec5SDimitry Andric} 3370b57cec5SDimitry Andricdef shr_imm16_asm_operand : ImmAsmOperand<1,16> { let Name = "ShrImm16"; } 3380b57cec5SDimitry Andricdef shr_imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 16; }]> { 3390b57cec5SDimitry Andric let EncoderMethod = "getShiftRight16Imm"; 3400b57cec5SDimitry Andric let DecoderMethod = "DecodeShiftRight16Imm"; 3410b57cec5SDimitry Andric let ParserMatchClass = shr_imm16_asm_operand; 3420b57cec5SDimitry Andric} 3430b57cec5SDimitry Andricdef shr_imm32_asm_operand : ImmAsmOperand<1,32> { let Name = "ShrImm32"; } 3440b57cec5SDimitry Andricdef shr_imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]> { 3450b57cec5SDimitry Andric let EncoderMethod = "getShiftRight32Imm"; 3460b57cec5SDimitry Andric let DecoderMethod = "DecodeShiftRight32Imm"; 3470b57cec5SDimitry Andric let ParserMatchClass = shr_imm32_asm_operand; 3480b57cec5SDimitry Andric} 3490b57cec5SDimitry Andricdef shr_imm64_asm_operand : ImmAsmOperand<1,64> { let Name = "ShrImm64"; } 3500b57cec5SDimitry Andricdef shr_imm64 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 64; }]> { 3510b57cec5SDimitry Andric let EncoderMethod = "getShiftRight64Imm"; 3520b57cec5SDimitry Andric let DecoderMethod = "DecodeShiftRight64Imm"; 3530b57cec5SDimitry Andric let ParserMatchClass = shr_imm64_asm_operand; 3540b57cec5SDimitry Andric} 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric// ARM Assembler operand for ldr Rd, =expression which generates an offset 3580b57cec5SDimitry Andric// to a constant pool entry or a MOV depending on the value of expression 3590b57cec5SDimitry Andricdef const_pool_asm_operand : AsmOperandClass { let Name = "ConstPoolAsmImm"; } 3600b57cec5SDimitry Andricdef const_pool_asm_imm : Operand<i32> { 3610b57cec5SDimitry Andric let ParserMatchClass = const_pool_asm_operand; 3620b57cec5SDimitry Andric} 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 3660b57cec5SDimitry Andric// ARM Assembler alias templates. 3670b57cec5SDimitry Andric// 3680b57cec5SDimitry Andric// Note: When EmitPriority == 1, the alias will be used for printing 3690b57cec5SDimitry Andricclass ARMInstAlias<string Asm, dag Result, bit EmitPriority = 0> 3700b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, Requires<[IsARM]>; 3710b57cec5SDimitry Andricclass ARMInstSubst<string Asm, dag Result, bit EmitPriority = 0> 3720b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, 3730b57cec5SDimitry Andric Requires<[IsARM,UseNegativeImmediates]>; 3740b57cec5SDimitry Andricclass tInstAlias<string Asm, dag Result, bit EmitPriority = 0> 3750b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb]>; 3760b57cec5SDimitry Andricclass tInstSubst<string Asm, dag Result, bit EmitPriority = 0> 3770b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, 3780b57cec5SDimitry Andric Requires<[IsThumb,UseNegativeImmediates]>; 3790b57cec5SDimitry Andricclass t2InstAlias<string Asm, dag Result, bit EmitPriority = 0> 3800b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb2]>; 3810b57cec5SDimitry Andricclass t2InstSubst<string Asm, dag Result, bit EmitPriority = 0> 3820b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, 3830b57cec5SDimitry Andric Requires<[IsThumb2,UseNegativeImmediates]>; 3840b57cec5SDimitry Andricclass VFP2InstAlias<string Asm, dag Result, bit EmitPriority = 0> 3850b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2]>; 3860b57cec5SDimitry Andricclass VFP2DPInstAlias<string Asm, dag Result, bit EmitPriority = 0> 3870b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2,HasDPVFP]>; 3880b57cec5SDimitry Andricclass VFP3InstAlias<string Asm, dag Result, bit EmitPriority = 0> 3890b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP3]>; 3900b57cec5SDimitry Andricclass NEONInstAlias<string Asm, dag Result, bit EmitPriority = 0> 3910b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, Requires<[HasNEON]>; 3920b57cec5SDimitry Andricclass MVEInstAlias<string Asm, dag Result, bit EmitPriority = 1> 3930b57cec5SDimitry Andric : InstAlias<Asm, Result, EmitPriority>, Requires<[HasMVEInt, IsThumb]>; 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andricclass VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>, 3970b57cec5SDimitry Andric Requires<[HasVFP2]>; 3980b57cec5SDimitry Andricclass NEONMnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>, 3990b57cec5SDimitry Andric Requires<[HasNEON]>; 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 4020b57cec5SDimitry Andric// ARM Instruction templates. 4030b57cec5SDimitry Andric// 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andricclass InstTemplate<AddrMode am, int sz, IndexMode im, 4070b57cec5SDimitry Andric Format f, Domain d, string cstr, InstrItinClass itin> 4080b57cec5SDimitry Andric : Instruction { 4090b57cec5SDimitry Andric let Namespace = "ARM"; 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric AddrMode AM = am; 4120b57cec5SDimitry Andric int Size = sz; 4130b57cec5SDimitry Andric IndexMode IM = im; 4140b57cec5SDimitry Andric bits<2> IndexModeBits = IM.Value; 4150b57cec5SDimitry Andric Format F = f; 4160b57cec5SDimitry Andric bits<6> Form = F.Value; 4170b57cec5SDimitry Andric Domain D = d; 4180b57cec5SDimitry Andric bit isUnaryDataProc = 0; 4190b57cec5SDimitry Andric bit canXformTo16Bit = 0; 4200b57cec5SDimitry Andric // The instruction is a 16-bit flag setting Thumb instruction. Used 421e8d8bef9SDimitry Andric // by the parser and if-converter to determine whether to require the 'S' 422e8d8bef9SDimitry Andric // suffix on the mnemonic (when not in an IT block) or preclude it (when 423e8d8bef9SDimitry Andric // in an IT block). 4240b57cec5SDimitry Andric bit thumbArithFlagSetting = 0; 4250b57cec5SDimitry Andric 426349cc55cSDimitry Andric bits<2> VecSize = 0; 4278bcb0991SDimitry Andric bit validForTailPredication = 0; 4285ffd83dbSDimitry Andric bit retainsPreviousHalfElement = 0; 4295ffd83dbSDimitry Andric bit horizontalReduction = 0; 4305ffd83dbSDimitry Andric bit doubleWidthResult = 0; 4318bcb0991SDimitry Andric 4320b57cec5SDimitry Andric // If this is a pseudo instruction, mark it isCodeGenOnly. 4330b57cec5SDimitry Andric let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo"); 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric // The layout of TSFlags should be kept in sync with ARMBaseInfo.h. 4360b57cec5SDimitry Andric let TSFlags{4-0} = AM.Value; 4370b57cec5SDimitry Andric let TSFlags{6-5} = IndexModeBits; 4380b57cec5SDimitry Andric let TSFlags{12-7} = Form; 4390b57cec5SDimitry Andric let TSFlags{13} = isUnaryDataProc; 4400b57cec5SDimitry Andric let TSFlags{14} = canXformTo16Bit; 4410b57cec5SDimitry Andric let TSFlags{18-15} = D.Value; 4420b57cec5SDimitry Andric let TSFlags{19} = thumbArithFlagSetting; 4438bcb0991SDimitry Andric let TSFlags{20} = validForTailPredication; 4445ffd83dbSDimitry Andric let TSFlags{21} = retainsPreviousHalfElement; 4455ffd83dbSDimitry Andric let TSFlags{22} = horizontalReduction; 4465ffd83dbSDimitry Andric let TSFlags{23} = doubleWidthResult; 447349cc55cSDimitry Andric let TSFlags{25-24} = VecSize; 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric let Constraints = cstr; 4500b57cec5SDimitry Andric let Itinerary = itin; 4510b57cec5SDimitry Andric} 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andricclass Encoding { 4540b57cec5SDimitry Andric field bits<32> Inst; 4550b57cec5SDimitry Andric // Mask of bits that cause an encoding to be UNPREDICTABLE. 4560b57cec5SDimitry Andric // If a bit is set, then if the corresponding bit in the 4570b57cec5SDimitry Andric // target encoding differs from its value in the "Inst" field, 4580b57cec5SDimitry Andric // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 4590b57cec5SDimitry Andric field bits<32> Unpredictable = 0; 4600b57cec5SDimitry Andric // SoftFail is the generic name for this field, but we alias it so 4610b57cec5SDimitry Andric // as to make it more obvious what it means in ARM-land. 4620b57cec5SDimitry Andric field bits<32> SoftFail = Unpredictable; 4630b57cec5SDimitry Andric} 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andricclass InstARM<AddrMode am, int sz, IndexMode im, 4660b57cec5SDimitry Andric Format f, Domain d, string cstr, InstrItinClass itin> 4670b57cec5SDimitry Andric : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding { 4680b57cec5SDimitry Andric let DecoderNamespace = "ARM"; 4690b57cec5SDimitry Andric} 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric// This Encoding-less class is used by Thumb1 to specify the encoding bits later 4720b57cec5SDimitry Andric// on by adding flavors to specific instructions. 4730b57cec5SDimitry Andricclass InstThumb<AddrMode am, int sz, IndexMode im, 4740b57cec5SDimitry Andric Format f, Domain d, string cstr, InstrItinClass itin> 4750b57cec5SDimitry Andric : InstTemplate<am, sz, im, f, d, cstr, itin> { 4760b57cec5SDimitry Andric let DecoderNamespace = "Thumb"; 4770b57cec5SDimitry Andric} 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric// Pseudo-instructions for alternate assembly syntax (never used by codegen). 4800b57cec5SDimitry Andric// These are aliases that require C++ handling to convert to the target 4810b57cec5SDimitry Andric// instruction, while InstAliases can be handled directly by tblgen. 4820b57cec5SDimitry Andricclass AsmPseudoInst<string asm, dag iops, dag oops = (outs)> 483*0fca6ea1SDimitry Andric : InstTemplate<AddrModeNone, 4, IndexModeNone, Pseudo, GenericDomain, 4840b57cec5SDimitry Andric "", NoItinerary> { 4850b57cec5SDimitry Andric let OutOperandList = oops; 4860b57cec5SDimitry Andric let InOperandList = iops; 4870b57cec5SDimitry Andric let Pattern = []; 4880b57cec5SDimitry Andric let isCodeGenOnly = 0; // So we get asm matcher for it. 4890b57cec5SDimitry Andric let AsmString = asm; 4900b57cec5SDimitry Andric let isPseudo = 1; 4918bcb0991SDimitry Andric let hasNoSchedulingInfo = 1; 4920b57cec5SDimitry Andric} 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andricclass ARMAsmPseudo<string asm, dag iops, dag oops = (outs)> 4950b57cec5SDimitry Andric : AsmPseudoInst<asm, iops, oops>, Requires<[IsARM]>; 4960b57cec5SDimitry Andricclass tAsmPseudo<string asm, dag iops, dag oops = (outs)> 4970b57cec5SDimitry Andric : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb]>; 4980b57cec5SDimitry Andricclass t2AsmPseudo<string asm, dag iops, dag oops = (outs)> 4990b57cec5SDimitry Andric : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb2]>; 5000b57cec5SDimitry Andricclass VFP2AsmPseudo<string asm, dag iops, dag oops = (outs)> 5010b57cec5SDimitry Andric : AsmPseudoInst<asm, iops, oops>, Requires<[HasVFP2]>; 5020b57cec5SDimitry Andricclass NEONAsmPseudo<string asm, dag iops, dag oops = (outs)> 5030b57cec5SDimitry Andric : AsmPseudoInst<asm, iops, oops>, Requires<[HasNEON]>; 5040b57cec5SDimitry Andricclass MVEAsmPseudo<string asm, dag iops, dag oops = (outs)> 5050b57cec5SDimitry Andric : AsmPseudoInst<asm, iops, oops>, Requires<[HasMVEInt]>; 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric// Pseudo instructions for the code generator. 5080b57cec5SDimitry Andricclass PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern> 5090b57cec5SDimitry Andric : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, 5100b57cec5SDimitry Andric GenericDomain, "", itin> { 5110b57cec5SDimitry Andric let OutOperandList = oops; 5120b57cec5SDimitry Andric let InOperandList = iops; 5130b57cec5SDimitry Andric let Pattern = pattern; 5140b57cec5SDimitry Andric let isCodeGenOnly = 1; 5150b57cec5SDimitry Andric let isPseudo = 1; 5160b57cec5SDimitry Andric} 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric// PseudoInst that's ARM-mode only. 5190b57cec5SDimitry Andricclass ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 5200b57cec5SDimitry Andric list<dag> pattern> 5210b57cec5SDimitry Andric : PseudoInst<oops, iops, itin, pattern> { 5220b57cec5SDimitry Andric let Size = sz; 5230b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM]; 5240b57cec5SDimitry Andric} 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric// PseudoInst that's Thumb-mode only. 5270b57cec5SDimitry Andricclass tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 5280b57cec5SDimitry Andric list<dag> pattern> 5290b57cec5SDimitry Andric : PseudoInst<oops, iops, itin, pattern> { 5300b57cec5SDimitry Andric let Size = sz; 5310b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb]; 5320b57cec5SDimitry Andric} 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric// PseudoInst that's in ARMv8-M baseline (Somewhere between Thumb and Thumb2) 5350b57cec5SDimitry Andricclass t2basePseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 5360b57cec5SDimitry Andric list<dag> pattern> 5370b57cec5SDimitry Andric : PseudoInst<oops, iops, itin, pattern> { 5380b57cec5SDimitry Andric let Size = sz; 5390b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb,HasV8MBaseline]; 5400b57cec5SDimitry Andric} 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric// PseudoInst that's Thumb2-mode only. 5430b57cec5SDimitry Andricclass t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 5440b57cec5SDimitry Andric list<dag> pattern> 5450b57cec5SDimitry Andric : PseudoInst<oops, iops, itin, pattern> { 5460b57cec5SDimitry Andric let Size = sz; 5470b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2]; 5480b57cec5SDimitry Andric} 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andricclass ARMPseudoExpand<dag oops, dag iops, int sz, 5510b57cec5SDimitry Andric InstrItinClass itin, list<dag> pattern, 5520b57cec5SDimitry Andric dag Result> 5530b57cec5SDimitry Andric : ARMPseudoInst<oops, iops, sz, itin, pattern>, 5540b57cec5SDimitry Andric PseudoInstExpansion<Result>; 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andricclass tPseudoExpand<dag oops, dag iops, int sz, 5570b57cec5SDimitry Andric InstrItinClass itin, list<dag> pattern, 5580b57cec5SDimitry Andric dag Result> 5590b57cec5SDimitry Andric : tPseudoInst<oops, iops, sz, itin, pattern>, 5600b57cec5SDimitry Andric PseudoInstExpansion<Result>; 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andricclass t2PseudoExpand<dag oops, dag iops, int sz, 5630b57cec5SDimitry Andric InstrItinClass itin, list<dag> pattern, 5640b57cec5SDimitry Andric dag Result> 5650b57cec5SDimitry Andric : t2PseudoInst<oops, iops, sz, itin, pattern>, 5660b57cec5SDimitry Andric PseudoInstExpansion<Result>; 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric// Almost all ARM instructions are predicable. 5690b57cec5SDimitry Andricclass I<dag oops, dag iops, AddrMode am, int sz, 5700b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, 5710b57cec5SDimitry Andric string opc, string asm, string cstr, 5720b57cec5SDimitry Andric list<dag> pattern> 5730b57cec5SDimitry Andric : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 5740b57cec5SDimitry Andric bits<4> p; 5750b57cec5SDimitry Andric let Inst{31-28} = p; 5760b57cec5SDimitry Andric let OutOperandList = oops; 5770b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 5780b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", asm); 5790b57cec5SDimitry Andric let Pattern = pattern; 5800b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM]; 5810b57cec5SDimitry Andric} 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric// A few are not predicable 5840b57cec5SDimitry Andricclass InoP<dag oops, dag iops, AddrMode am, int sz, 5850b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, 5860b57cec5SDimitry Andric string opc, string asm, string cstr, 5870b57cec5SDimitry Andric list<dag> pattern> 5880b57cec5SDimitry Andric : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 5890b57cec5SDimitry Andric let OutOperandList = oops; 5900b57cec5SDimitry Andric let InOperandList = iops; 5910b57cec5SDimitry Andric let AsmString = !strconcat(opc, asm); 5920b57cec5SDimitry Andric let Pattern = pattern; 5930b57cec5SDimitry Andric let isPredicable = 0; 5940b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM]; 5950b57cec5SDimitry Andric} 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric// Same as I except it can optionally modify CPSR. Note it's modeled as an input 5980b57cec5SDimitry Andric// operand since by default it's a zero register. It will become an implicit def 5990b57cec5SDimitry Andric// once it's "flipped". 6000b57cec5SDimitry Andricclass sI<dag oops, dag iops, AddrMode am, int sz, 6010b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, 6020b57cec5SDimitry Andric string opc, string asm, string cstr, 6030b57cec5SDimitry Andric list<dag> pattern> 6040b57cec5SDimitry Andric : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 6050b57cec5SDimitry Andric bits<4> p; // Predicate operand 6060b57cec5SDimitry Andric bits<1> s; // condition-code set flag ('1' if the insn should set the flags) 6070b57cec5SDimitry Andric let Inst{31-28} = p; 6080b57cec5SDimitry Andric let Inst{20} = s; 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric let OutOperandList = oops; 6110b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); 6120b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${s}${p}", asm); 6130b57cec5SDimitry Andric let Pattern = pattern; 6140b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM]; 6150b57cec5SDimitry Andric} 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric// Special cases 6180b57cec5SDimitry Andricclass XI<dag oops, dag iops, AddrMode am, int sz, 6190b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, 6200b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 6210b57cec5SDimitry Andric : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 6220b57cec5SDimitry Andric let OutOperandList = oops; 6230b57cec5SDimitry Andric let InOperandList = iops; 6240b57cec5SDimitry Andric let AsmString = asm; 6250b57cec5SDimitry Andric let Pattern = pattern; 6260b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM]; 6270b57cec5SDimitry Andric} 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andricclass AI<dag oops, dag iops, Format f, InstrItinClass itin, 6300b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 6310b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 6320b57cec5SDimitry Andric opc, asm, "", pattern>; 6330b57cec5SDimitry Andricclass AsI<dag oops, dag iops, Format f, InstrItinClass itin, 6340b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 6350b57cec5SDimitry Andric : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 6360b57cec5SDimitry Andric opc, asm, "", pattern>; 6370b57cec5SDimitry Andricclass AXI<dag oops, dag iops, Format f, InstrItinClass itin, 6380b57cec5SDimitry Andric string asm, list<dag> pattern> 6390b57cec5SDimitry Andric : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 6400b57cec5SDimitry Andric asm, "", pattern>; 6410b57cec5SDimitry Andricclass AXIM<dag oops, dag iops, AddrMode am, Format f, InstrItinClass itin, 6420b57cec5SDimitry Andric string asm, list<dag> pattern> 6430b57cec5SDimitry Andric : XI<oops, iops, am, 4, IndexModeNone, f, itin, 6440b57cec5SDimitry Andric asm, "", pattern>; 6450b57cec5SDimitry Andricclass AInoP<dag oops, dag iops, Format f, InstrItinClass itin, 6460b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 6470b57cec5SDimitry Andric : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 6480b57cec5SDimitry Andric opc, asm, "", pattern>; 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric// Ctrl flow instructions 6510b57cec5SDimitry Andricclass ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 6520b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 6530b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin, 6540b57cec5SDimitry Andric opc, asm, "", pattern> { 6550b57cec5SDimitry Andric let Inst{27-24} = opcod; 6560b57cec5SDimitry Andric} 6570b57cec5SDimitry Andricclass ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 6580b57cec5SDimitry Andric string asm, list<dag> pattern> 6590b57cec5SDimitry Andric : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin, 6600b57cec5SDimitry Andric asm, "", pattern> { 6610b57cec5SDimitry Andric let Inst{27-24} = opcod; 6620b57cec5SDimitry Andric} 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric// BR_JT instructions 6650b57cec5SDimitry Andricclass JTI<dag oops, dag iops, InstrItinClass itin, 6660b57cec5SDimitry Andric string asm, list<dag> pattern> 6670b57cec5SDimitry Andric : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin, 6680b57cec5SDimitry Andric asm, "", pattern>; 6690b57cec5SDimitry Andric 6700b57cec5SDimitry Andricclass AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin, 6710b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 6720b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin, 6730b57cec5SDimitry Andric opc, asm, "", pattern> { 6740b57cec5SDimitry Andric bits<4> Rt; 6750b57cec5SDimitry Andric bits<4> addr; 6760b57cec5SDimitry Andric let Inst{27-23} = 0b00011; 6770b57cec5SDimitry Andric let Inst{22-21} = opcod; 6780b57cec5SDimitry Andric let Inst{20} = 1; 6790b57cec5SDimitry Andric let Inst{19-16} = addr; 6800b57cec5SDimitry Andric let Inst{15-12} = Rt; 6810b57cec5SDimitry Andric let Inst{11-10} = 0b11; 6820b57cec5SDimitry Andric let Inst{9-8} = opcod2; 6830b57cec5SDimitry Andric let Inst{7-0} = 0b10011111; 6840b57cec5SDimitry Andric} 6850b57cec5SDimitry Andricclass AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin, 6860b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 6870b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin, 6880b57cec5SDimitry Andric opc, asm, "", pattern> { 6890b57cec5SDimitry Andric bits<4> Rt; 6900b57cec5SDimitry Andric bits<4> addr; 6910b57cec5SDimitry Andric let Inst{27-23} = 0b00011; 6920b57cec5SDimitry Andric let Inst{22-21} = opcod; 6930b57cec5SDimitry Andric let Inst{20} = 0; 6940b57cec5SDimitry Andric let Inst{19-16} = addr; 6950b57cec5SDimitry Andric let Inst{11-10} = 0b11; 6960b57cec5SDimitry Andric let Inst{9-8} = opcod2; 6970b57cec5SDimitry Andric let Inst{7-4} = 0b1001; 6980b57cec5SDimitry Andric let Inst{3-0} = Rt; 6990b57cec5SDimitry Andric} 7000b57cec5SDimitry Andric// Atomic load/store instructions 7010b57cec5SDimitry Andricclass AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 7020b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 7030b57cec5SDimitry Andric : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>; 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andricclass AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 7060b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 7070b57cec5SDimitry Andric : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> { 7080b57cec5SDimitry Andric bits<4> Rd; 7090b57cec5SDimitry Andric let Inst{15-12} = Rd; 7100b57cec5SDimitry Andric} 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andric// Exclusive load/store instructions 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andricclass AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 7150b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 7160b57cec5SDimitry Andric : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, 7170b57cec5SDimitry Andric Requires<[IsARM, HasAcquireRelease, HasV7Clrex]>; 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andricclass AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 7200b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 7210b57cec5SDimitry Andric : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, 7220b57cec5SDimitry Andric Requires<[IsARM, HasAcquireRelease, HasV7Clrex]> { 7230b57cec5SDimitry Andric bits<4> Rd; 7240b57cec5SDimitry Andric let Inst{15-12} = Rd; 7250b57cec5SDimitry Andric} 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andricclass AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern> 7280b57cec5SDimitry Andric : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> { 7290b57cec5SDimitry Andric bits<4> Rt; 7300b57cec5SDimitry Andric bits<4> Rt2; 7310b57cec5SDimitry Andric bits<4> addr; 7320b57cec5SDimitry Andric let Inst{27-23} = 0b00010; 7330b57cec5SDimitry Andric let Inst{22} = b; 7340b57cec5SDimitry Andric let Inst{21-20} = 0b00; 7350b57cec5SDimitry Andric let Inst{19-16} = addr; 7360b57cec5SDimitry Andric let Inst{15-12} = Rt; 7370b57cec5SDimitry Andric let Inst{11-4} = 0b00001001; 7380b57cec5SDimitry Andric let Inst{3-0} = Rt2; 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric let Unpredictable{11-8} = 0b1111; 7410b57cec5SDimitry Andric let DecoderMethod = "DecodeSwap"; 7420b57cec5SDimitry Andric} 7430b57cec5SDimitry Andric// Acquire/Release load/store instructions 7440b57cec5SDimitry Andricclass AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 7450b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 7460b57cec5SDimitry Andric : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, 7470b57cec5SDimitry Andric Requires<[IsARM, HasAcquireRelease]>; 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andricclass AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 7500b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 7510b57cec5SDimitry Andric : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, 7520b57cec5SDimitry Andric Requires<[IsARM, HasAcquireRelease]> { 7530b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 7540b57cec5SDimitry Andric} 7550b57cec5SDimitry Andric 7560b57cec5SDimitry Andric// addrmode1 instructions 7570b57cec5SDimitry Andricclass AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 7580b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 7590b57cec5SDimitry Andric : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 7600b57cec5SDimitry Andric opc, asm, "", pattern> { 7610b57cec5SDimitry Andric let Inst{24-21} = opcod; 7620b57cec5SDimitry Andric let Inst{27-26} = 0b00; 7630b57cec5SDimitry Andric} 7640b57cec5SDimitry Andricclass AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 7650b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 7660b57cec5SDimitry Andric : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 7670b57cec5SDimitry Andric opc, asm, "", pattern> { 7680b57cec5SDimitry Andric let Inst{24-21} = opcod; 7690b57cec5SDimitry Andric let Inst{27-26} = 0b00; 7700b57cec5SDimitry Andric} 7710b57cec5SDimitry Andricclass AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 7720b57cec5SDimitry Andric string asm, list<dag> pattern> 7730b57cec5SDimitry Andric : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 7740b57cec5SDimitry Andric asm, "", pattern> { 7750b57cec5SDimitry Andric let Inst{24-21} = opcod; 7760b57cec5SDimitry Andric let Inst{27-26} = 0b00; 7770b57cec5SDimitry Andric} 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric// loads 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric// LDR/LDRB/STR/STRB/... 7820b57cec5SDimitry Andricclass AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am, 7830b57cec5SDimitry Andric Format f, InstrItinClass itin, string opc, string asm, 7840b57cec5SDimitry Andric list<dag> pattern> 7850b57cec5SDimitry Andric : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm, 7860b57cec5SDimitry Andric "", pattern> { 7870b57cec5SDimitry Andric let Inst{27-25} = op; 7880b57cec5SDimitry Andric let Inst{24} = 1; // 24 == P 7890b57cec5SDimitry Andric // 23 == U 7900b57cec5SDimitry Andric let Inst{22} = isByte; 7910b57cec5SDimitry Andric let Inst{21} = 0; // 21 == W 7920b57cec5SDimitry Andric let Inst{20} = isLd; 7930b57cec5SDimitry Andric} 7940b57cec5SDimitry Andric// Indexed load/stores 7950b57cec5SDimitry Andricclass AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops, 7960b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, string opc, 7970b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 7980b57cec5SDimitry Andric : I<oops, iops, AddrMode2, 4, im, f, itin, 7990b57cec5SDimitry Andric opc, asm, cstr, pattern> { 8000b57cec5SDimitry Andric bits<4> Rt; 8010b57cec5SDimitry Andric let Inst{27-26} = 0b01; 8020b57cec5SDimitry Andric let Inst{24} = isPre; // P bit 8030b57cec5SDimitry Andric let Inst{22} = isByte; // B bit 8040b57cec5SDimitry Andric let Inst{21} = isPre; // W bit 8050b57cec5SDimitry Andric let Inst{20} = isLd; // L bit 8060b57cec5SDimitry Andric let Inst{15-12} = Rt; 8070b57cec5SDimitry Andric} 8080b57cec5SDimitry Andricclass AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops, 8090b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, string opc, 8100b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 8110b57cec5SDimitry Andric : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 8120b57cec5SDimitry Andric pattern> { 8130b57cec5SDimitry Andric // AM2 store w/ two operands: (GPR, am2offset) 8140b57cec5SDimitry Andric // {12} isAdd 8150b57cec5SDimitry Andric // {11-0} imm12/Rm 8160b57cec5SDimitry Andric bits<14> offset; 8170b57cec5SDimitry Andric bits<4> Rn; 8180b57cec5SDimitry Andric let Inst{25} = 1; 8190b57cec5SDimitry Andric let Inst{23} = offset{12}; 8200b57cec5SDimitry Andric let Inst{19-16} = Rn; 8210b57cec5SDimitry Andric let Inst{11-5} = offset{11-5}; 8220b57cec5SDimitry Andric let Inst{4} = 0; 8230b57cec5SDimitry Andric let Inst{3-0} = offset{3-0}; 8240b57cec5SDimitry Andric} 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andricclass AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops, 8270b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, string opc, 8280b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 8290b57cec5SDimitry Andric : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 8300b57cec5SDimitry Andric pattern> { 8310b57cec5SDimitry Andric // AM2 store w/ two operands: (GPR, am2offset) 8320b57cec5SDimitry Andric // {12} isAdd 8330b57cec5SDimitry Andric // {11-0} imm12/Rm 8340b57cec5SDimitry Andric bits<14> offset; 8350b57cec5SDimitry Andric bits<4> Rn; 8360b57cec5SDimitry Andric let Inst{25} = 0; 8370b57cec5SDimitry Andric let Inst{23} = offset{12}; 8380b57cec5SDimitry Andric let Inst{19-16} = Rn; 8390b57cec5SDimitry Andric let Inst{11-0} = offset{11-0}; 8400b57cec5SDimitry Andric} 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric// FIXME: Merge with the above class when addrmode2 gets used for STR, STRB 8440b57cec5SDimitry Andric// but for now use this class for STRT and STRBT. 8450b57cec5SDimitry Andricclass AI2stridxT<bit isByte, bit isPre, dag oops, dag iops, 8460b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, string opc, 8470b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 8480b57cec5SDimitry Andric : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 8490b57cec5SDimitry Andric pattern> { 8500b57cec5SDimitry Andric // AM2 store w/ two operands: (GPR, am2offset) 8510b57cec5SDimitry Andric // {17-14} Rn 8520b57cec5SDimitry Andric // {13} 1 == Rm, 0 == imm12 8530b57cec5SDimitry Andric // {12} isAdd 8540b57cec5SDimitry Andric // {11-0} imm12/Rm 8550b57cec5SDimitry Andric bits<18> addr; 8560b57cec5SDimitry Andric let Inst{25} = addr{13}; 8570b57cec5SDimitry Andric let Inst{23} = addr{12}; 8580b57cec5SDimitry Andric let Inst{19-16} = addr{17-14}; 8590b57cec5SDimitry Andric let Inst{11-0} = addr{11-0}; 8600b57cec5SDimitry Andric} 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric// addrmode3 instructions 8630b57cec5SDimitry Andricclass AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f, 8640b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 8650b57cec5SDimitry Andric : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin, 8660b57cec5SDimitry Andric opc, asm, "", pattern> { 8670b57cec5SDimitry Andric bits<14> addr; 8680b57cec5SDimitry Andric bits<4> Rt; 8690b57cec5SDimitry Andric let Inst{27-25} = 0b000; 8700b57cec5SDimitry Andric let Inst{24} = 1; // P bit 8710b57cec5SDimitry Andric let Inst{23} = addr{8}; // U bit 8720b57cec5SDimitry Andric let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 8730b57cec5SDimitry Andric let Inst{21} = 0; // W bit 8740b57cec5SDimitry Andric let Inst{20} = op20; // L bit 8750b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 8760b57cec5SDimitry Andric let Inst{15-12} = Rt; // Rt 8770b57cec5SDimitry Andric let Inst{11-8} = addr{7-4}; // imm7_4/zero 8780b57cec5SDimitry Andric let Inst{7-4} = op; 8790b57cec5SDimitry Andric let Inst{3-0} = addr{3-0}; // imm3_0/Rm 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 8820b57cec5SDimitry Andric} 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andricclass AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops, 8850b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, string opc, 8860b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 8870b57cec5SDimitry Andric : I<oops, iops, AddrMode3, 4, im, f, itin, 8880b57cec5SDimitry Andric opc, asm, cstr, pattern> { 8890b57cec5SDimitry Andric bits<4> Rt; 8900b57cec5SDimitry Andric let Inst{27-25} = 0b000; 8910b57cec5SDimitry Andric let Inst{24} = isPre; // P bit 8920b57cec5SDimitry Andric let Inst{21} = isPre; // W bit 8930b57cec5SDimitry Andric let Inst{20} = op20; // L bit 8940b57cec5SDimitry Andric let Inst{15-12} = Rt; // Rt 8950b57cec5SDimitry Andric let Inst{7-4} = op; 8960b57cec5SDimitry Andric} 8970b57cec5SDimitry Andric 8980b57cec5SDimitry Andric// FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB 8990b57cec5SDimitry Andric// but for now use this class for LDRSBT, LDRHT, LDSHT. 9000b57cec5SDimitry Andricclass AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops, 9010b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, string opc, 9020b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 9030b57cec5SDimitry Andric : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> { 9040b57cec5SDimitry Andric // {13} 1 == imm8, 0 == Rm 9050b57cec5SDimitry Andric // {12-9} Rn 9060b57cec5SDimitry Andric // {8} isAdd 9070b57cec5SDimitry Andric // {7-4} imm7_4/zero 9080b57cec5SDimitry Andric // {3-0} imm3_0/Rm 9090b57cec5SDimitry Andric bits<4> addr; 9100b57cec5SDimitry Andric bits<4> Rt; 9110b57cec5SDimitry Andric let Inst{27-25} = 0b000; 9120b57cec5SDimitry Andric let Inst{24} = 0; // P bit 9130b57cec5SDimitry Andric let Inst{21} = 1; 9140b57cec5SDimitry Andric let Inst{20} = isLoad; // L bit 9150b57cec5SDimitry Andric let Inst{19-16} = addr; // Rn 9160b57cec5SDimitry Andric let Inst{15-12} = Rt; // Rt 9170b57cec5SDimitry Andric let Inst{7-4} = op; 9180b57cec5SDimitry Andric} 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric// stores 9210b57cec5SDimitry Andricclass AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin, 9220b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 9230b57cec5SDimitry Andric : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin, 9240b57cec5SDimitry Andric opc, asm, "", pattern> { 9250b57cec5SDimitry Andric bits<14> addr; 9260b57cec5SDimitry Andric bits<4> Rt; 9270b57cec5SDimitry Andric let Inst{27-25} = 0b000; 9280b57cec5SDimitry Andric let Inst{24} = 1; // P bit 9290b57cec5SDimitry Andric let Inst{23} = addr{8}; // U bit 9300b57cec5SDimitry Andric let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 9310b57cec5SDimitry Andric let Inst{21} = 0; // W bit 9320b57cec5SDimitry Andric let Inst{20} = 0; // L bit 9330b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 9340b57cec5SDimitry Andric let Inst{15-12} = Rt; // Rt 9350b57cec5SDimitry Andric let Inst{11-8} = addr{7-4}; // imm7_4/zero 9360b57cec5SDimitry Andric let Inst{7-4} = op; 9370b57cec5SDimitry Andric let Inst{3-0} = addr{3-0}; // imm3_0/Rm 9380b57cec5SDimitry Andric let DecoderMethod = "DecodeAddrMode3Instruction"; 9390b57cec5SDimitry Andric} 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric// addrmode4 instructions 9420b57cec5SDimitry Andricclass AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin, 9430b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 9440b57cec5SDimitry Andric : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> { 9450b57cec5SDimitry Andric bits<4> p; 9460b57cec5SDimitry Andric bits<16> regs; 9470b57cec5SDimitry Andric bits<4> Rn; 9480b57cec5SDimitry Andric let Inst{31-28} = p; 9490b57cec5SDimitry Andric let Inst{27-25} = 0b100; 9500b57cec5SDimitry Andric let Inst{22} = 0; // S bit 9510b57cec5SDimitry Andric let Inst{19-16} = Rn; 9520b57cec5SDimitry Andric let Inst{15-0} = regs; 9530b57cec5SDimitry Andric} 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric// Unsigned multiply, multiply-accumulate instructions. 9560b57cec5SDimitry Andricclass AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 9570b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 9580b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 9590b57cec5SDimitry Andric opc, asm, "", pattern> { 9600b57cec5SDimitry Andric let Inst{7-4} = 0b1001; 9610b57cec5SDimitry Andric let Inst{20} = 0; // S bit 9620b57cec5SDimitry Andric let Inst{27-21} = opcod; 9630b57cec5SDimitry Andric} 9640b57cec5SDimitry Andricclass AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 9650b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 9660b57cec5SDimitry Andric : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 9670b57cec5SDimitry Andric opc, asm, "", pattern> { 9680b57cec5SDimitry Andric let Inst{7-4} = 0b1001; 9690b57cec5SDimitry Andric let Inst{27-21} = opcod; 9700b57cec5SDimitry Andric} 9710b57cec5SDimitry Andric 9720b57cec5SDimitry Andric// Most significant word multiply 9730b57cec5SDimitry Andricclass AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops, 9740b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 9750b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 9760b57cec5SDimitry Andric opc, asm, "", pattern> { 9770b57cec5SDimitry Andric bits<4> Rd; 9780b57cec5SDimitry Andric bits<4> Rn; 9790b57cec5SDimitry Andric bits<4> Rm; 9800b57cec5SDimitry Andric let Inst{7-4} = opc7_4; 9810b57cec5SDimitry Andric let Inst{20} = 1; 9820b57cec5SDimitry Andric let Inst{27-21} = opcod; 9830b57cec5SDimitry Andric let Inst{19-16} = Rd; 9840b57cec5SDimitry Andric let Inst{11-8} = Rm; 9850b57cec5SDimitry Andric let Inst{3-0} = Rn; 9860b57cec5SDimitry Andric} 9870b57cec5SDimitry Andric// MSW multiple w/ Ra operand 9880b57cec5SDimitry Andricclass AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops, 9890b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 9900b57cec5SDimitry Andric : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> { 9910b57cec5SDimitry Andric bits<4> Ra; 9920b57cec5SDimitry Andric let Inst{15-12} = Ra; 9930b57cec5SDimitry Andric} 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric// SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y> 9960b57cec5SDimitry Andricclass AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 9970b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 9980b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 9990b57cec5SDimitry Andric opc, asm, "", pattern> { 10000b57cec5SDimitry Andric bits<4> Rn; 10010b57cec5SDimitry Andric bits<4> Rm; 10020b57cec5SDimitry Andric let Inst{4} = 0; 10030b57cec5SDimitry Andric let Inst{7} = 1; 10040b57cec5SDimitry Andric let Inst{20} = 0; 10050b57cec5SDimitry Andric let Inst{27-21} = opcod; 10060b57cec5SDimitry Andric let Inst{6-5} = bit6_5; 10070b57cec5SDimitry Andric let Inst{11-8} = Rm; 10080b57cec5SDimitry Andric let Inst{3-0} = Rn; 10090b57cec5SDimitry Andric} 10100b57cec5SDimitry Andricclass AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 10110b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 10120b57cec5SDimitry Andric : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 10130b57cec5SDimitry Andric bits<4> Rd; 10140b57cec5SDimitry Andric let Inst{19-16} = Rd; 10150b57cec5SDimitry Andric} 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric// AMulxyI with Ra operand 10180b57cec5SDimitry Andricclass AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 10190b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 10200b57cec5SDimitry Andric : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 10210b57cec5SDimitry Andric bits<4> Ra; 10220b57cec5SDimitry Andric let Inst{15-12} = Ra; 10230b57cec5SDimitry Andric} 10240b57cec5SDimitry Andric// SMLAL* 10250b57cec5SDimitry Andricclass AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 10260b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 10270b57cec5SDimitry Andric : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 10280b57cec5SDimitry Andric bits<4> RdLo; 10290b57cec5SDimitry Andric bits<4> RdHi; 10300b57cec5SDimitry Andric let Inst{19-16} = RdHi; 10310b57cec5SDimitry Andric let Inst{15-12} = RdLo; 10320b57cec5SDimitry Andric} 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric// Extend instructions. 10350b57cec5SDimitry Andricclass AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 10360b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 10370b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin, 10380b57cec5SDimitry Andric opc, asm, "", pattern> { 10390b57cec5SDimitry Andric // All AExtI instructions have Rd and Rm register operands. 10400b57cec5SDimitry Andric bits<4> Rd; 10410b57cec5SDimitry Andric bits<4> Rm; 10420b57cec5SDimitry Andric let Inst{15-12} = Rd; 10430b57cec5SDimitry Andric let Inst{3-0} = Rm; 10440b57cec5SDimitry Andric let Inst{7-4} = 0b0111; 10450b57cec5SDimitry Andric let Inst{9-8} = 0b00; 10460b57cec5SDimitry Andric let Inst{27-20} = opcod; 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric let Unpredictable{9-8} = 0b11; 10490b57cec5SDimitry Andric} 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric// Misc Arithmetic instructions. 10520b57cec5SDimitry Andricclass AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops, 10530b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 10540b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 10550b57cec5SDimitry Andric opc, asm, "", pattern> { 10560b57cec5SDimitry Andric bits<4> Rd; 10570b57cec5SDimitry Andric bits<4> Rm; 10580b57cec5SDimitry Andric let Inst{27-20} = opcod; 10590b57cec5SDimitry Andric let Inst{19-16} = 0b1111; 10600b57cec5SDimitry Andric let Inst{15-12} = Rd; 10610b57cec5SDimitry Andric let Inst{11-8} = 0b1111; 10620b57cec5SDimitry Andric let Inst{7-4} = opc7_4; 10630b57cec5SDimitry Andric let Inst{3-0} = Rm; 10640b57cec5SDimitry Andric} 10650b57cec5SDimitry Andric 10660b57cec5SDimitry Andric// Division instructions. 10670b57cec5SDimitry Andricclass ADivA1I<bits<3> opcod, dag oops, dag iops, 10680b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 10690b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 10700b57cec5SDimitry Andric opc, asm, "", pattern> { 10710b57cec5SDimitry Andric bits<4> Rd; 10720b57cec5SDimitry Andric bits<4> Rn; 10730b57cec5SDimitry Andric bits<4> Rm; 10740b57cec5SDimitry Andric let Inst{27-23} = 0b01110; 10750b57cec5SDimitry Andric let Inst{22-20} = opcod; 10760b57cec5SDimitry Andric let Inst{19-16} = Rd; 10770b57cec5SDimitry Andric let Inst{15-12} = 0b1111; 10780b57cec5SDimitry Andric let Inst{11-8} = Rm; 10790b57cec5SDimitry Andric let Inst{7-4} = 0b0001; 10800b57cec5SDimitry Andric let Inst{3-0} = Rn; 10810b57cec5SDimitry Andric} 10820b57cec5SDimitry Andric 10830b57cec5SDimitry Andric// PKH instructions 10840b57cec5SDimitry Andricdef PKHLSLAsmOperand : ImmAsmOperand<0,31> { 10850b57cec5SDimitry Andric let Name = "PKHLSLImm"; 10860b57cec5SDimitry Andric let ParserMethod = "parsePKHLSLImm"; 10870b57cec5SDimitry Andric} 10880b57cec5SDimitry Andricdef pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{ 10890b57cec5SDimitry Andric let PrintMethod = "printPKHLSLShiftImm"; 10900b57cec5SDimitry Andric let ParserMatchClass = PKHLSLAsmOperand; 10910b57cec5SDimitry Andric} 10920b57cec5SDimitry Andricdef PKHASRAsmOperand : AsmOperandClass { 10930b57cec5SDimitry Andric let Name = "PKHASRImm"; 10940b57cec5SDimitry Andric let ParserMethod = "parsePKHASRImm"; 10950b57cec5SDimitry Andric} 10960b57cec5SDimitry Andricdef pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{ 10970b57cec5SDimitry Andric let PrintMethod = "printPKHASRShiftImm"; 10980b57cec5SDimitry Andric let ParserMatchClass = PKHASRAsmOperand; 10990b57cec5SDimitry Andric} 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andricclass APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin, 11020b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 11030b57cec5SDimitry Andric : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 11040b57cec5SDimitry Andric opc, asm, "", pattern> { 11050b57cec5SDimitry Andric bits<4> Rd; 11060b57cec5SDimitry Andric bits<4> Rn; 11070b57cec5SDimitry Andric bits<4> Rm; 11080b57cec5SDimitry Andric bits<5> sh; 11090b57cec5SDimitry Andric let Inst{27-20} = opcod; 11100b57cec5SDimitry Andric let Inst{19-16} = Rn; 11110b57cec5SDimitry Andric let Inst{15-12} = Rd; 11120b57cec5SDimitry Andric let Inst{11-7} = sh; 11130b57cec5SDimitry Andric let Inst{6} = tb; 11140b57cec5SDimitry Andric let Inst{5-4} = 0b01; 11150b57cec5SDimitry Andric let Inst{3-0} = Rm; 11160b57cec5SDimitry Andric} 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode. 11210b57cec5SDimitry Andricclass ARMPat<dag pattern, dag result> : Pat<pattern, result> { 11220b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM]; 11230b57cec5SDimitry Andric} 11240b57cec5SDimitry Andricclass ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> { 11250b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM, HasV5T]; 11260b57cec5SDimitry Andric} 11270b57cec5SDimitry Andricclass ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> { 11280b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM, HasV5TE]; 11290b57cec5SDimitry Andric} 11300b57cec5SDimitry Andric// ARMV5MOPat - Same as ARMV5TEPat with UseMulOps. 11310b57cec5SDimitry Andricclass ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> { 11320b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps]; 11330b57cec5SDimitry Andric} 11340b57cec5SDimitry Andricclass ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> { 11350b57cec5SDimitry Andric list<Predicate> Predicates = [IsARM, HasV6]; 11360b57cec5SDimitry Andric} 11370b57cec5SDimitry Andricclass VFPPat<dag pattern, dag result> : Pat<pattern, result> { 11380b57cec5SDimitry Andric list<Predicate> Predicates = [HasVFP2]; 11390b57cec5SDimitry Andric} 11400b57cec5SDimitry Andricclass VFPNoNEONPat<dag pattern, dag result> : Pat<pattern, result> { 11410b57cec5SDimitry Andric list<Predicate> Predicates = [HasVFP2, DontUseNEONForFP]; 11420b57cec5SDimitry Andric} 11430b57cec5SDimitry Andricclass Thumb2DSPPat<dag pattern, dag result> : Pat<pattern, result> { 11440b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2, HasDSP]; 11450b57cec5SDimitry Andric} 11460b57cec5SDimitry Andricclass Thumb2DSPMulPat<dag pattern, dag result> : Pat<pattern, result> { 11470b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2, UseMulOps, HasDSP]; 11480b57cec5SDimitry Andric} 11495ffd83dbSDimitry Andricclass FPRegs16Pat<dag pattern, dag result> : Pat<pattern, result> { 11505ffd83dbSDimitry Andric list<Predicate> Predicates = [HasFPRegs16]; 11515ffd83dbSDimitry Andric} 11520b57cec5SDimitry Andricclass FP16Pat<dag pattern, dag result> : Pat<pattern, result> { 11530b57cec5SDimitry Andric list<Predicate> Predicates = [HasFP16]; 11540b57cec5SDimitry Andric} 11550b57cec5SDimitry Andricclass FullFP16Pat<dag pattern, dag result> : Pat<pattern, result> { 11560b57cec5SDimitry Andric list<Predicate> Predicates = [HasFullFP16]; 11570b57cec5SDimitry Andric} 11580b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 11590b57cec5SDimitry Andric// Thumb Instruction Format Definitions. 11600b57cec5SDimitry Andric// 11610b57cec5SDimitry Andric 11620b57cec5SDimitry Andricclass ThumbI<dag oops, dag iops, AddrMode am, int sz, 11630b57cec5SDimitry Andric InstrItinClass itin, string asm, string cstr, list<dag> pattern> 11640b57cec5SDimitry Andric : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 11650b57cec5SDimitry Andric let OutOperandList = oops; 11660b57cec5SDimitry Andric let InOperandList = iops; 11670b57cec5SDimitry Andric let AsmString = asm; 11680b57cec5SDimitry Andric let Pattern = pattern; 11690b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb]; 11700b57cec5SDimitry Andric} 11710b57cec5SDimitry Andric 11720b57cec5SDimitry Andric// TI - Thumb instruction. 11730b57cec5SDimitry Andricclass TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 11740b57cec5SDimitry Andric : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 11750b57cec5SDimitry Andric 11760b57cec5SDimitry Andric// Two-address instructions 11770b57cec5SDimitry Andricclass TIt<dag oops, dag iops, InstrItinClass itin, string asm, 11780b57cec5SDimitry Andric list<dag> pattern> 11790b57cec5SDimitry Andric : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst", 11800b57cec5SDimitry Andric pattern>; 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric// tBL, tBX 32-bit instructions 11830b57cec5SDimitry Andricclass TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3, 11840b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, string asm, 11850b57cec5SDimitry Andric list<dag> pattern> 11860b57cec5SDimitry Andric : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>, 11870b57cec5SDimitry Andric Encoding { 11880b57cec5SDimitry Andric let Inst{31-27} = opcod1; 11890b57cec5SDimitry Andric let Inst{15-14} = opcod2; 11900b57cec5SDimitry Andric let Inst{12} = opcod3; 11910b57cec5SDimitry Andric} 11920b57cec5SDimitry Andric 11930b57cec5SDimitry Andric// BR_JT instructions 11940b57cec5SDimitry Andricclass TJTI<dag oops, dag iops, InstrItinClass itin, string asm, 11950b57cec5SDimitry Andric list<dag> pattern> 11960b57cec5SDimitry Andric : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 11970b57cec5SDimitry Andric 11980b57cec5SDimitry Andric// Thumb1 only 11990b57cec5SDimitry Andricclass Thumb1I<dag oops, dag iops, AddrMode am, int sz, 12000b57cec5SDimitry Andric InstrItinClass itin, string asm, string cstr, list<dag> pattern> 12010b57cec5SDimitry Andric : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 12020b57cec5SDimitry Andric let OutOperandList = oops; 12030b57cec5SDimitry Andric let InOperandList = iops; 12040b57cec5SDimitry Andric let AsmString = asm; 12050b57cec5SDimitry Andric let Pattern = pattern; 12060b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 12070b57cec5SDimitry Andric} 12080b57cec5SDimitry Andric 12090b57cec5SDimitry Andricclass T1I<dag oops, dag iops, InstrItinClass itin, 12100b57cec5SDimitry Andric string asm, list<dag> pattern> 12110b57cec5SDimitry Andric : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 12120b57cec5SDimitry Andricclass T1Ix2<dag oops, dag iops, InstrItinClass itin, 12130b57cec5SDimitry Andric string asm, list<dag> pattern> 12140b57cec5SDimitry Andric : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 12150b57cec5SDimitry Andric 12160b57cec5SDimitry Andric// Two-address instructions 12170b57cec5SDimitry Andricclass T1It<dag oops, dag iops, InstrItinClass itin, 12180b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 12190b57cec5SDimitry Andric : Thumb1I<oops, iops, AddrModeNone, 2, itin, 12200b57cec5SDimitry Andric asm, cstr, pattern>; 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric// Thumb1 instruction that can either be predicated or set CPSR. 12230b57cec5SDimitry Andricclass Thumb1sI<dag oops, dag iops, AddrMode am, int sz, 12240b57cec5SDimitry Andric InstrItinClass itin, 12250b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 12260b57cec5SDimitry Andric : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 12270b57cec5SDimitry Andric let OutOperandList = !con(oops, (outs s_cc_out:$s)); 12280b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 12290b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${s}${p}", asm); 12300b57cec5SDimitry Andric let Pattern = pattern; 12310b57cec5SDimitry Andric let thumbArithFlagSetting = 1; 12320b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 12330b57cec5SDimitry Andric let DecoderNamespace = "ThumbSBit"; 12340b57cec5SDimitry Andric} 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andricclass T1sI<dag oops, dag iops, InstrItinClass itin, 12370b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 12380b57cec5SDimitry Andric : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric// Two-address instructions 12410b57cec5SDimitry Andricclass T1sIt<dag oops, dag iops, InstrItinClass itin, 12420b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 12430b57cec5SDimitry Andric : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, 12440b57cec5SDimitry Andric "$Rn = $Rdn", pattern>; 12450b57cec5SDimitry Andric 12460b57cec5SDimitry Andric// Thumb1 instruction that can be predicated. 12470b57cec5SDimitry Andricclass Thumb1pI<dag oops, dag iops, AddrMode am, int sz, 12480b57cec5SDimitry Andric InstrItinClass itin, 12490b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 12500b57cec5SDimitry Andric : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 12510b57cec5SDimitry Andric let OutOperandList = oops; 12520b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 12530b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", asm); 12540b57cec5SDimitry Andric let Pattern = pattern; 12550b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 12560b57cec5SDimitry Andric} 12570b57cec5SDimitry Andric 12580b57cec5SDimitry Andricclass T1pI<dag oops, dag iops, InstrItinClass itin, 12590b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 12600b57cec5SDimitry Andric : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 12610b57cec5SDimitry Andric 12620b57cec5SDimitry Andric// Two-address instructions 12630b57cec5SDimitry Andricclass T1pIt<dag oops, dag iops, InstrItinClass itin, 12640b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 12650b57cec5SDimitry Andric : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, 12660b57cec5SDimitry Andric "$Rn = $Rdn", pattern>; 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andricclass T1pIs<dag oops, dag iops, 12690b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 12700b57cec5SDimitry Andric : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>; 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andricclass Encoding16 : Encoding { 12730b57cec5SDimitry Andric let Inst{31-16} = 0x0000; 12740b57cec5SDimitry Andric} 12750b57cec5SDimitry Andric 12760b57cec5SDimitry Andric// A6.2 16-bit Thumb instruction encoding 12770b57cec5SDimitry Andricclass T1Encoding<bits<6> opcode> : Encoding16 { 12780b57cec5SDimitry Andric let Inst{15-10} = opcode; 12790b57cec5SDimitry Andric} 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andric// A6.2.1 Shift (immediate), add, subtract, move, and compare encoding. 12820b57cec5SDimitry Andricclass T1General<bits<5> opcode> : Encoding16 { 12830b57cec5SDimitry Andric let Inst{15-14} = 0b00; 12840b57cec5SDimitry Andric let Inst{13-9} = opcode; 12850b57cec5SDimitry Andric} 12860b57cec5SDimitry Andric 12870b57cec5SDimitry Andric// A6.2.2 Data-processing encoding. 12880b57cec5SDimitry Andricclass T1DataProcessing<bits<4> opcode> : Encoding16 { 12890b57cec5SDimitry Andric let Inst{15-10} = 0b010000; 12900b57cec5SDimitry Andric let Inst{9-6} = opcode; 12910b57cec5SDimitry Andric} 12920b57cec5SDimitry Andric 12930b57cec5SDimitry Andric// A6.2.3 Special data instructions and branch and exchange encoding. 12940b57cec5SDimitry Andricclass T1Special<bits<4> opcode> : Encoding16 { 12950b57cec5SDimitry Andric let Inst{15-10} = 0b010001; 12960b57cec5SDimitry Andric let Inst{9-6} = opcode; 12970b57cec5SDimitry Andric} 12980b57cec5SDimitry Andric 12990b57cec5SDimitry Andric// A6.2.4 Load/store single data item encoding. 13000b57cec5SDimitry Andricclass T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 { 13010b57cec5SDimitry Andric let Inst{15-12} = opA; 13020b57cec5SDimitry Andric let Inst{11-9} = opB; 13030b57cec5SDimitry Andric} 13040b57cec5SDimitry Andricclass T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andricclass T1BranchCond<bits<4> opcode> : Encoding16 { 13070b57cec5SDimitry Andric let Inst{15-12} = opcode; 13080b57cec5SDimitry Andric} 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric// Helper classes to encode Thumb1 loads and stores. For immediates, the 13110b57cec5SDimitry Andric// following bits are used for "opA" (see A6.2.4): 13120b57cec5SDimitry Andric// 13130b57cec5SDimitry Andric// 0b0110 => Immediate, 4 bytes 13140b57cec5SDimitry Andric// 0b1000 => Immediate, 2 bytes 13150b57cec5SDimitry Andric// 0b0111 => Immediate, 1 byte 13160b57cec5SDimitry Andricclass T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am, 13170b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, 13180b57cec5SDimitry Andric list<dag> pattern> 13190b57cec5SDimitry Andric : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 13200b57cec5SDimitry Andric T1LoadStore<0b0101, opcode> { 13210b57cec5SDimitry Andric bits<3> Rt; 13220b57cec5SDimitry Andric bits<8> addr; 13230b57cec5SDimitry Andric let Inst{8-6} = addr{5-3}; // Rm 13240b57cec5SDimitry Andric let Inst{5-3} = addr{2-0}; // Rn 13250b57cec5SDimitry Andric let Inst{2-0} = Rt; 13260b57cec5SDimitry Andric} 13270b57cec5SDimitry Andricclass T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am, 13280b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, 13290b57cec5SDimitry Andric list<dag> pattern> 13300b57cec5SDimitry Andric : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 13310b57cec5SDimitry Andric T1LoadStore<opA, {opB,?,?}> { 13320b57cec5SDimitry Andric bits<3> Rt; 13330b57cec5SDimitry Andric bits<8> addr; 13340b57cec5SDimitry Andric let Inst{10-6} = addr{7-3}; // imm5 13350b57cec5SDimitry Andric let Inst{5-3} = addr{2-0}; // Rn 13360b57cec5SDimitry Andric let Inst{2-0} = Rt; 13370b57cec5SDimitry Andric} 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andric// A6.2.5 Miscellaneous 16-bit instructions encoding. 13400b57cec5SDimitry Andricclass T1Misc<bits<7> opcode> : Encoding16 { 13410b57cec5SDimitry Andric let Inst{15-12} = 0b1011; 13420b57cec5SDimitry Andric let Inst{11-5} = opcode; 13430b57cec5SDimitry Andric} 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric// Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable. 13460b57cec5SDimitry Andricclass Thumb2I<dag oops, dag iops, AddrMode am, int sz, 13470b57cec5SDimitry Andric InstrItinClass itin, 13480b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 13490b57cec5SDimitry Andric : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 13500b57cec5SDimitry Andric let OutOperandList = oops; 13510b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 13520b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", asm); 13530b57cec5SDimitry Andric let Pattern = pattern; 13540b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2]; 13550b57cec5SDimitry Andric let DecoderNamespace = "Thumb2"; 13560b57cec5SDimitry Andric} 13570b57cec5SDimitry Andric 13580b57cec5SDimitry Andric// Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an 13590b57cec5SDimitry Andric// input operand since by default it's a zero register. It will become an 13600b57cec5SDimitry Andric// implicit def once it's "flipped". 13610b57cec5SDimitry Andric// 13620b57cec5SDimitry Andric// FIXME: This uses unified syntax so {s} comes before {p}. We should make it 13630b57cec5SDimitry Andric// more consistent. 13640b57cec5SDimitry Andricclass Thumb2sI<dag oops, dag iops, AddrMode am, int sz, 13650b57cec5SDimitry Andric InstrItinClass itin, 13660b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 13670b57cec5SDimitry Andric : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 13680b57cec5SDimitry Andric bits<1> s; // condition-code set flag ('1' if the insn should set the flags) 13690b57cec5SDimitry Andric let Inst{20} = s; 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andric let OutOperandList = oops; 13720b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); 13730b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${s}${p}", asm); 13740b57cec5SDimitry Andric let Pattern = pattern; 13750b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2]; 13760b57cec5SDimitry Andric let DecoderNamespace = "Thumb2"; 13770b57cec5SDimitry Andric} 13780b57cec5SDimitry Andric 13790b57cec5SDimitry Andric// Special cases 13800b57cec5SDimitry Andricclass Thumb2XI<dag oops, dag iops, AddrMode am, int sz, 13810b57cec5SDimitry Andric InstrItinClass itin, 13820b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 13830b57cec5SDimitry Andric : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 13840b57cec5SDimitry Andric let OutOperandList = oops; 13850b57cec5SDimitry Andric let InOperandList = iops; 13860b57cec5SDimitry Andric let AsmString = asm; 13870b57cec5SDimitry Andric let Pattern = pattern; 13880b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2]; 13890b57cec5SDimitry Andric let DecoderNamespace = "Thumb2"; 13900b57cec5SDimitry Andric} 13910b57cec5SDimitry Andric 13920b57cec5SDimitry Andricclass ThumbXI<dag oops, dag iops, AddrMode am, int sz, 13930b57cec5SDimitry Andric InstrItinClass itin, 13940b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 13950b57cec5SDimitry Andric : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 13960b57cec5SDimitry Andric let OutOperandList = oops; 13970b57cec5SDimitry Andric let InOperandList = iops; 13980b57cec5SDimitry Andric let AsmString = asm; 13990b57cec5SDimitry Andric let Pattern = pattern; 14000b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 14010b57cec5SDimitry Andric let DecoderNamespace = "Thumb"; 14020b57cec5SDimitry Andric} 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andricclass T2I<dag oops, dag iops, InstrItinClass itin, 1405349cc55cSDimitry Andric string opc, string asm, list<dag> pattern, AddrMode am = AddrModeNone> 1406349cc55cSDimitry Andric : Thumb2I<oops, iops, am, 4, itin, opc, asm, "", pattern>; 14070b57cec5SDimitry Andricclass T2Ii12<dag oops, dag iops, InstrItinClass itin, 14080b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 14090b57cec5SDimitry Andric : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>; 14104824e7fdSDimitry Andricclass T2Ii8p<dag oops, dag iops, InstrItinClass itin, 14110b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 14124824e7fdSDimitry Andric : Thumb2I<oops, iops, AddrModeT2_i8pos, 4, itin, opc, asm, "", pattern>; 14134824e7fdSDimitry Andricclass T2Ii8n<dag oops, dag iops, InstrItinClass itin, 14144824e7fdSDimitry Andric string opc, string asm, list<dag> pattern> 14154824e7fdSDimitry Andric : Thumb2I<oops, iops, AddrModeT2_i8neg, 4, itin, opc, asm, "", pattern>; 14160b57cec5SDimitry Andricclass T2Iso<dag oops, dag iops, InstrItinClass itin, 14170b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 14180b57cec5SDimitry Andric : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>; 14190b57cec5SDimitry Andricclass T2Ipc<dag oops, dag iops, InstrItinClass itin, 14200b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 14210b57cec5SDimitry Andric : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>; 14220b57cec5SDimitry Andricclass T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin, 14230b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 14240b57cec5SDimitry Andric : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 14250b57cec5SDimitry Andric pattern> { 14260b57cec5SDimitry Andric bits<4> Rt; 14270b57cec5SDimitry Andric bits<4> Rt2; 14280b57cec5SDimitry Andric bits<13> addr; 14290b57cec5SDimitry Andric let Inst{31-25} = 0b1110100; 14300b57cec5SDimitry Andric let Inst{24} = P; 14310b57cec5SDimitry Andric let Inst{23} = addr{8}; 14320b57cec5SDimitry Andric let Inst{22} = 1; 14330b57cec5SDimitry Andric let Inst{21} = W; 14340b57cec5SDimitry Andric let Inst{20} = isLoad; 14350b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; 14360b57cec5SDimitry Andric let Inst{15-12} = Rt{3-0}; 14370b57cec5SDimitry Andric let Inst{11-8} = Rt2{3-0}; 14380b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; 14390b57cec5SDimitry Andric} 14400b57cec5SDimitry Andricclass T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops, 14410b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, string cstr, 14420b57cec5SDimitry Andric list<dag> pattern> 14430b57cec5SDimitry Andric : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 14440b57cec5SDimitry Andric pattern> { 14450b57cec5SDimitry Andric bits<4> Rt; 14460b57cec5SDimitry Andric bits<4> Rt2; 14470b57cec5SDimitry Andric bits<4> addr; 14480b57cec5SDimitry Andric bits<9> imm; 14490b57cec5SDimitry Andric let Inst{31-25} = 0b1110100; 14500b57cec5SDimitry Andric let Inst{24} = P; 14510b57cec5SDimitry Andric let Inst{23} = imm{8}; 14520b57cec5SDimitry Andric let Inst{22} = 1; 14530b57cec5SDimitry Andric let Inst{21} = W; 14540b57cec5SDimitry Andric let Inst{20} = isLoad; 14550b57cec5SDimitry Andric let Inst{19-16} = addr; 14560b57cec5SDimitry Andric let Inst{15-12} = Rt{3-0}; 14570b57cec5SDimitry Andric let Inst{11-8} = Rt2{3-0}; 14580b57cec5SDimitry Andric let Inst{7-0} = imm{7-0}; 14590b57cec5SDimitry Andric} 14600b57cec5SDimitry Andric 14610b57cec5SDimitry Andricclass T2sI<dag oops, dag iops, InstrItinClass itin, 14620b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 14630b57cec5SDimitry Andric : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>; 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andricclass T2XI<dag oops, dag iops, InstrItinClass itin, 14660b57cec5SDimitry Andric string asm, list<dag> pattern> 14670b57cec5SDimitry Andric : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 14680b57cec5SDimitry Andricclass T2JTI<dag oops, dag iops, InstrItinClass itin, 14690b57cec5SDimitry Andric string asm, list<dag> pattern> 14700b57cec5SDimitry Andric : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 14710b57cec5SDimitry Andric 14720b57cec5SDimitry Andric// Move to/from coprocessor instructions 14730b57cec5SDimitry Andricclass T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm, 14740b57cec5SDimitry Andric list<dag> pattern> 14750b57cec5SDimitry Andric : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> { 14760b57cec5SDimitry Andric let Inst{31-28} = opc; 14770b57cec5SDimitry Andric} 14780b57cec5SDimitry Andric 14790b57cec5SDimitry Andric// Two-address instructions 14800b57cec5SDimitry Andricclass T2XIt<dag oops, dag iops, InstrItinClass itin, 14810b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 14820b57cec5SDimitry Andric : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>; 14830b57cec5SDimitry Andric 14840b57cec5SDimitry Andric// T2Ipreldst - Thumb2 pre-indexed load / store instructions. 14850b57cec5SDimitry Andricclass T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre, 14860b57cec5SDimitry Andric dag oops, dag iops, 14870b57cec5SDimitry Andric AddrMode am, IndexMode im, InstrItinClass itin, 14880b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 14890b57cec5SDimitry Andric : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 14900b57cec5SDimitry Andric let OutOperandList = oops; 14910b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 14920b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", asm); 14930b57cec5SDimitry Andric let Pattern = pattern; 14940b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2]; 14950b57cec5SDimitry Andric let DecoderNamespace = "Thumb2"; 14960b57cec5SDimitry Andric 14970b57cec5SDimitry Andric bits<4> Rt; 14980b57cec5SDimitry Andric bits<13> addr; 14990b57cec5SDimitry Andric let Inst{31-27} = 0b11111; 15000b57cec5SDimitry Andric let Inst{26-25} = 0b00; 15010b57cec5SDimitry Andric let Inst{24} = signed; 15020b57cec5SDimitry Andric let Inst{23} = 0; 15030b57cec5SDimitry Andric let Inst{22-21} = opcod; 15040b57cec5SDimitry Andric let Inst{20} = load; 15050b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; 15060b57cec5SDimitry Andric let Inst{15-12} = Rt{3-0}; 15070b57cec5SDimitry Andric let Inst{11} = 1; 15080b57cec5SDimitry Andric // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 15090b57cec5SDimitry Andric let Inst{10} = pre; // The P bit. 15100b57cec5SDimitry Andric let Inst{9} = addr{8}; // Sign bit 15110b57cec5SDimitry Andric let Inst{8} = 1; // The W bit. 15120b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; 15130b57cec5SDimitry Andric 15140b57cec5SDimitry Andric let DecoderMethod = "DecodeT2LdStPre"; 15150b57cec5SDimitry Andric} 15160b57cec5SDimitry Andric 15170b57cec5SDimitry Andric// T2Ipostldst - Thumb2 post-indexed load / store instructions. 15180b57cec5SDimitry Andricclass T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre, 15190b57cec5SDimitry Andric dag oops, dag iops, 15200b57cec5SDimitry Andric AddrMode am, IndexMode im, InstrItinClass itin, 15210b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 15220b57cec5SDimitry Andric : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 15230b57cec5SDimitry Andric let OutOperandList = oops; 15240b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 15250b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", asm); 15260b57cec5SDimitry Andric let Pattern = pattern; 15270b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2]; 15280b57cec5SDimitry Andric let DecoderNamespace = "Thumb2"; 15290b57cec5SDimitry Andric 15300b57cec5SDimitry Andric bits<4> Rt; 15310b57cec5SDimitry Andric bits<4> Rn; 15320b57cec5SDimitry Andric bits<9> offset; 15330b57cec5SDimitry Andric let Inst{31-27} = 0b11111; 15340b57cec5SDimitry Andric let Inst{26-25} = 0b00; 15350b57cec5SDimitry Andric let Inst{24} = signed; 15360b57cec5SDimitry Andric let Inst{23} = 0; 15370b57cec5SDimitry Andric let Inst{22-21} = opcod; 15380b57cec5SDimitry Andric let Inst{20} = load; 15390b57cec5SDimitry Andric let Inst{19-16} = Rn; 15400b57cec5SDimitry Andric let Inst{15-12} = Rt{3-0}; 15410b57cec5SDimitry Andric let Inst{11} = 1; 15420b57cec5SDimitry Andric // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 15430b57cec5SDimitry Andric let Inst{10} = pre; // The P bit. 15440b57cec5SDimitry Andric let Inst{9} = offset{8}; // Sign bit 15450b57cec5SDimitry Andric let Inst{8} = 1; // The W bit. 15460b57cec5SDimitry Andric let Inst{7-0} = offset{7-0}; 15470b57cec5SDimitry Andric 15480b57cec5SDimitry Andric let DecoderMethod = "DecodeT2LdStPre"; 15490b57cec5SDimitry Andric} 15500b57cec5SDimitry Andric 15510b57cec5SDimitry Andric// T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode. 15520b57cec5SDimitry Andricclass T1Pat<dag pattern, dag result> : Pat<pattern, result> { 15530b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 15540b57cec5SDimitry Andric} 15550b57cec5SDimitry Andric 15560b57cec5SDimitry Andric// T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode. 15570b57cec5SDimitry Andricclass T2v6Pat<dag pattern, dag result> : Pat<pattern, result> { 15580b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2, HasV6T2]; 15590b57cec5SDimitry Andric} 15600b57cec5SDimitry Andric 15610b57cec5SDimitry Andric// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode. 15620b57cec5SDimitry Andricclass T2Pat<dag pattern, dag result> : Pat<pattern, result> { 15630b57cec5SDimitry Andric list<Predicate> Predicates = [IsThumb2]; 15640b57cec5SDimitry Andric} 15650b57cec5SDimitry Andric 15660b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 15670b57cec5SDimitry Andric 15680b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 15690b57cec5SDimitry Andric// ARM VFP Instruction templates. 15700b57cec5SDimitry Andric// 15710b57cec5SDimitry Andric 15720b57cec5SDimitry Andric// Almost all VFP instructions are predicable. 15730b57cec5SDimitry Andricclass VFPI<dag oops, dag iops, AddrMode am, int sz, 15740b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, 15750b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 15760b57cec5SDimitry Andric : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 15770b57cec5SDimitry Andric bits<4> p; 15780b57cec5SDimitry Andric let Inst{31-28} = p; 15790b57cec5SDimitry Andric let OutOperandList = oops; 15800b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 15810b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", asm); 15820b57cec5SDimitry Andric let Pattern = pattern; 15830b57cec5SDimitry Andric let PostEncoderMethod = "VFPThumb2PostEncoder"; 15840b57cec5SDimitry Andric let DecoderNamespace = "VFP"; 15850b57cec5SDimitry Andric list<Predicate> Predicates = [HasVFP2]; 15860b57cec5SDimitry Andric} 15870b57cec5SDimitry Andric 15880b57cec5SDimitry Andric// Special cases 15890b57cec5SDimitry Andricclass VFPXI<dag oops, dag iops, AddrMode am, int sz, 15900b57cec5SDimitry Andric IndexMode im, Format f, InstrItinClass itin, 15910b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 15920b57cec5SDimitry Andric : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 15930b57cec5SDimitry Andric bits<4> p; 15940b57cec5SDimitry Andric let Inst{31-28} = p; 15950b57cec5SDimitry Andric let OutOperandList = oops; 15960b57cec5SDimitry Andric let InOperandList = iops; 15970b57cec5SDimitry Andric let AsmString = asm; 15980b57cec5SDimitry Andric let Pattern = pattern; 15990b57cec5SDimitry Andric let PostEncoderMethod = "VFPThumb2PostEncoder"; 16000b57cec5SDimitry Andric let DecoderNamespace = "VFP"; 16010b57cec5SDimitry Andric list<Predicate> Predicates = [HasVFP2]; 16020b57cec5SDimitry Andric} 16030b57cec5SDimitry Andric 16040b57cec5SDimitry Andricclass VFPAI<dag oops, dag iops, Format f, InstrItinClass itin, 160581ad6265SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 16060b57cec5SDimitry Andric : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 160781ad6265SDimitry Andric opc, asm, cstr, pattern> { 16080b57cec5SDimitry Andric let PostEncoderMethod = "VFPThumb2PostEncoder"; 16090b57cec5SDimitry Andric} 16100b57cec5SDimitry Andric 16110b57cec5SDimitry Andric// ARM VFP addrmode5 loads and stores 16120b57cec5SDimitry Andricclass ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 16130b57cec5SDimitry Andric InstrItinClass itin, 16140b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 16150b57cec5SDimitry Andric : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 16160b57cec5SDimitry Andric VFPLdStFrm, itin, opc, asm, "", pattern> { 16170b57cec5SDimitry Andric // Instruction operands. 16180b57cec5SDimitry Andric bits<5> Dd; 16190b57cec5SDimitry Andric bits<13> addr; 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric // Encode instruction operands. 16220b57cec5SDimitry Andric let Inst{23} = addr{8}; // U (add = (U == '1')) 16230b57cec5SDimitry Andric let Inst{22} = Dd{4}; 16240b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 16250b57cec5SDimitry Andric let Inst{15-12} = Dd{3-0}; 16260b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; // imm8 16270b57cec5SDimitry Andric 16280b57cec5SDimitry Andric let Inst{27-24} = opcod1; 16290b57cec5SDimitry Andric let Inst{21-20} = opcod2; 16300b57cec5SDimitry Andric let Inst{11-9} = 0b101; 16310b57cec5SDimitry Andric let Inst{8} = 1; // Double precision 16320b57cec5SDimitry Andric 16330b57cec5SDimitry Andric // Loads & stores operate on both NEON and VFP pipelines. 16340b57cec5SDimitry Andric let D = VFPNeonDomain; 16350b57cec5SDimitry Andric} 16360b57cec5SDimitry Andric 16370b57cec5SDimitry Andricclass ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 16380b57cec5SDimitry Andric InstrItinClass itin, 16390b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 16400b57cec5SDimitry Andric : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 16410b57cec5SDimitry Andric VFPLdStFrm, itin, opc, asm, "", pattern> { 16420b57cec5SDimitry Andric // Instruction operands. 16430b57cec5SDimitry Andric bits<5> Sd; 16440b57cec5SDimitry Andric bits<13> addr; 16450b57cec5SDimitry Andric 16460b57cec5SDimitry Andric // Encode instruction operands. 16470b57cec5SDimitry Andric let Inst{23} = addr{8}; // U (add = (U == '1')) 16480b57cec5SDimitry Andric let Inst{22} = Sd{0}; 16490b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 16500b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 16510b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; // imm8 16520b57cec5SDimitry Andric 16530b57cec5SDimitry Andric let Inst{27-24} = opcod1; 16540b57cec5SDimitry Andric let Inst{21-20} = opcod2; 16550b57cec5SDimitry Andric let Inst{11-9} = 0b101; 16560b57cec5SDimitry Andric let Inst{8} = 0; // Single precision 16570b57cec5SDimitry Andric 16580b57cec5SDimitry Andric // Loads & stores operate on both NEON and VFP pipelines. 16590b57cec5SDimitry Andric let D = VFPNeonDomain; 16600b57cec5SDimitry Andric} 16610b57cec5SDimitry Andric 16620b57cec5SDimitry Andricclass AHI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 16630b57cec5SDimitry Andric InstrItinClass itin, 16640b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 16650b57cec5SDimitry Andric : VFPI<oops, iops, AddrMode5FP16, 4, IndexModeNone, 16660b57cec5SDimitry Andric VFPLdStFrm, itin, opc, asm, "", pattern> { 16670b57cec5SDimitry Andric list<Predicate> Predicates = [HasFullFP16]; 16680b57cec5SDimitry Andric 16690b57cec5SDimitry Andric // Instruction operands. 16700b57cec5SDimitry Andric bits<5> Sd; 16710b57cec5SDimitry Andric bits<13> addr; 16720b57cec5SDimitry Andric 16730b57cec5SDimitry Andric // Encode instruction operands. 16740b57cec5SDimitry Andric let Inst{23} = addr{8}; // U (add = (U == '1')) 16750b57cec5SDimitry Andric let Inst{22} = Sd{0}; 16760b57cec5SDimitry Andric let Inst{19-16} = addr{12-9}; // Rn 16770b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 16780b57cec5SDimitry Andric let Inst{7-0} = addr{7-0}; // imm8 16790b57cec5SDimitry Andric 16800b57cec5SDimitry Andric let Inst{27-24} = opcod1; 16810b57cec5SDimitry Andric let Inst{21-20} = opcod2; 16820b57cec5SDimitry Andric let Inst{11-8} = 0b1001; // Half precision 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric // Loads & stores operate on both NEON and VFP pipelines. 16850b57cec5SDimitry Andric let D = VFPNeonDomain; 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 16880b57cec5SDimitry Andric} 16890b57cec5SDimitry Andric 16900b57cec5SDimitry Andric// VFP Load / store multiple pseudo instructions. 16910b57cec5SDimitry Andricclass PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr, 16920b57cec5SDimitry Andric list<dag> pattern> 16930b57cec5SDimitry Andric : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain, 16940b57cec5SDimitry Andric cstr, itin> { 16950b57cec5SDimitry Andric let OutOperandList = oops; 16960b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 16970b57cec5SDimitry Andric let Pattern = pattern; 16980b57cec5SDimitry Andric list<Predicate> Predicates = [HasVFP2]; 16990b57cec5SDimitry Andric} 17000b57cec5SDimitry Andric 17010b57cec5SDimitry Andric// Load / store multiple 17020b57cec5SDimitry Andric 17030b57cec5SDimitry Andric// Unknown precision 17040b57cec5SDimitry Andricclass AXXI4<dag oops, dag iops, IndexMode im, 17050b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 17060b57cec5SDimitry Andric : VFPXI<oops, iops, AddrMode4, 4, im, 17070b57cec5SDimitry Andric VFPLdStFrm, NoItinerary, asm, cstr, pattern> { 17080b57cec5SDimitry Andric // Instruction operands. 17090b57cec5SDimitry Andric bits<4> Rn; 17100b57cec5SDimitry Andric bits<13> regs; 17110b57cec5SDimitry Andric 17120b57cec5SDimitry Andric // Encode instruction operands. 17130b57cec5SDimitry Andric let Inst{19-16} = Rn; 17140b57cec5SDimitry Andric let Inst{22} = 0; 17150b57cec5SDimitry Andric let Inst{15-12} = regs{11-8}; 17160b57cec5SDimitry Andric let Inst{7-1} = regs{7-1}; 17170b57cec5SDimitry Andric 17180b57cec5SDimitry Andric let Inst{27-25} = 0b110; 17190b57cec5SDimitry Andric let Inst{11-8} = 0b1011; 17200b57cec5SDimitry Andric let Inst{0} = 1; 17210b57cec5SDimitry Andric} 17220b57cec5SDimitry Andric 17230b57cec5SDimitry Andric// Double precision 17240b57cec5SDimitry Andricclass AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 17250b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 17260b57cec5SDimitry Andric : VFPXI<oops, iops, AddrMode4, 4, im, 17270b57cec5SDimitry Andric VFPLdStMulFrm, itin, asm, cstr, pattern> { 17280b57cec5SDimitry Andric // Instruction operands. 17290b57cec5SDimitry Andric bits<4> Rn; 17300b57cec5SDimitry Andric bits<13> regs; 17310b57cec5SDimitry Andric 17320b57cec5SDimitry Andric // Encode instruction operands. 17330b57cec5SDimitry Andric let Inst{19-16} = Rn; 17340b57cec5SDimitry Andric let Inst{22} = regs{12}; 17350b57cec5SDimitry Andric let Inst{15-12} = regs{11-8}; 17360b57cec5SDimitry Andric let Inst{7-1} = regs{7-1}; 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric let Inst{27-25} = 0b110; 17390b57cec5SDimitry Andric let Inst{11-9} = 0b101; 17400b57cec5SDimitry Andric let Inst{8} = 1; // Double precision 17410b57cec5SDimitry Andric let Inst{0} = 0; 17420b57cec5SDimitry Andric} 17430b57cec5SDimitry Andric 17440b57cec5SDimitry Andric// Single Precision 17450b57cec5SDimitry Andricclass AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 17460b57cec5SDimitry Andric string asm, string cstr, list<dag> pattern> 17470b57cec5SDimitry Andric : VFPXI<oops, iops, AddrMode4, 4, im, 17480b57cec5SDimitry Andric VFPLdStMulFrm, itin, asm, cstr, pattern> { 17490b57cec5SDimitry Andric // Instruction operands. 17500b57cec5SDimitry Andric bits<4> Rn; 17510b57cec5SDimitry Andric bits<13> regs; 17520b57cec5SDimitry Andric 17530b57cec5SDimitry Andric // Encode instruction operands. 17540b57cec5SDimitry Andric let Inst{19-16} = Rn; 17550b57cec5SDimitry Andric let Inst{22} = regs{8}; 17560b57cec5SDimitry Andric let Inst{15-12} = regs{12-9}; 17570b57cec5SDimitry Andric let Inst{7-0} = regs{7-0}; 17580b57cec5SDimitry Andric 17590b57cec5SDimitry Andric let Inst{27-25} = 0b110; 17600b57cec5SDimitry Andric let Inst{11-9} = 0b101; 17610b57cec5SDimitry Andric let Inst{8} = 0; // Single precision 17620b57cec5SDimitry Andric} 17630b57cec5SDimitry Andric 1764*0fca6ea1SDimitry Andric// Single Precision with fixed registers. 1765*0fca6ea1SDimitry Andric// For when the registers-to-be-stored/loaded are fixed, e.g. VLLDM and VLSTM 1766*0fca6ea1SDimitry Andricclass AXSI4FR<string asm, bit et, bit load> 1767*0fca6ea1SDimitry Andric : InstARM<AddrMode4, 4, IndexModeNone, VFPLdStMulFrm, VFPDomain, "", NoItinerary> { 1768*0fca6ea1SDimitry Andric // Instruction operands. 1769*0fca6ea1SDimitry Andric bits<4> Rn; 1770*0fca6ea1SDimitry Andric bits<13> regs; // Does not affect encoding, for assembly/disassembly only. 1771*0fca6ea1SDimitry Andric list<Predicate> Predicates = [HasVFP2]; 1772*0fca6ea1SDimitry Andric let OutOperandList = (outs); 1773*0fca6ea1SDimitry Andric let InOperandList = (ins GPRnopc:$Rn, pred:$p, dpr_reglist:$regs); 1774*0fca6ea1SDimitry Andric let AsmString = asm; 1775*0fca6ea1SDimitry Andric let Pattern = []; 1776*0fca6ea1SDimitry Andric let DecoderNamespace = "VFP"; 1777*0fca6ea1SDimitry Andric // Encode instruction operands. 1778*0fca6ea1SDimitry Andric let Inst{19-16} = Rn; 1779*0fca6ea1SDimitry Andric let Inst{31-28} = 0b1110; 1780*0fca6ea1SDimitry Andric let Inst{27-25} = 0b110; 1781*0fca6ea1SDimitry Andric let Inst{24} = 0b0; 1782*0fca6ea1SDimitry Andric let Inst{23} = 0b0; 1783*0fca6ea1SDimitry Andric let Inst{22} = 0b0; 1784*0fca6ea1SDimitry Andric let Inst{21} = 0b1; 1785*0fca6ea1SDimitry Andric let Inst{20} = load; // Distinguishes vlldm from vlstm 1786*0fca6ea1SDimitry Andric let Inst{15-12} = 0b0000; 1787*0fca6ea1SDimitry Andric let Inst{11-9} = 0b101; 1788*0fca6ea1SDimitry Andric let Inst{8} = 0; // Single precision 1789*0fca6ea1SDimitry Andric let Inst{7} = et; // encoding type, 0 for T1 and 1 for T2. 1790*0fca6ea1SDimitry Andric let Inst{6-0} = 0b0000000; 1791*0fca6ea1SDimitry Andric let mayLoad = load; 1792*0fca6ea1SDimitry Andric let mayStore = !eq(load, 0); 1793*0fca6ea1SDimitry Andric} 1794*0fca6ea1SDimitry Andric 17950b57cec5SDimitry Andric// Double precision, unary 17960b57cec5SDimitry Andricclass ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 17970b57cec5SDimitry Andric bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 179881ad6265SDimitry Andric string asm, string cstr, list<dag> pattern> 179981ad6265SDimitry Andric : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, cstr, pattern> { 18000b57cec5SDimitry Andric // Instruction operands. 18010b57cec5SDimitry Andric bits<5> Dd; 18020b57cec5SDimitry Andric bits<5> Dm; 18030b57cec5SDimitry Andric 18040b57cec5SDimitry Andric // Encode instruction operands. 18050b57cec5SDimitry Andric let Inst{3-0} = Dm{3-0}; 18060b57cec5SDimitry Andric let Inst{5} = Dm{4}; 18070b57cec5SDimitry Andric let Inst{15-12} = Dd{3-0}; 18080b57cec5SDimitry Andric let Inst{22} = Dd{4}; 18090b57cec5SDimitry Andric 18100b57cec5SDimitry Andric let Inst{27-23} = opcod1; 18110b57cec5SDimitry Andric let Inst{21-20} = opcod2; 18120b57cec5SDimitry Andric let Inst{19-16} = opcod3; 18130b57cec5SDimitry Andric let Inst{11-9} = 0b101; 18140b57cec5SDimitry Andric let Inst{8} = 1; // Double precision 18150b57cec5SDimitry Andric let Inst{7-6} = opcod4; 18160b57cec5SDimitry Andric let Inst{4} = opcod5; 18170b57cec5SDimitry Andric 18180b57cec5SDimitry Andric let Predicates = [HasVFP2, HasDPVFP]; 18190b57cec5SDimitry Andric} 18200b57cec5SDimitry Andric 18210b57cec5SDimitry Andric// Double precision, unary, not-predicated 18220b57cec5SDimitry Andricclass ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 18230b57cec5SDimitry Andric bit opcod5, dag oops, dag iops, InstrItinClass itin, 18240b57cec5SDimitry Andric string asm, list<dag> pattern> 18250b57cec5SDimitry Andric : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> { 18260b57cec5SDimitry Andric // Instruction operands. 18270b57cec5SDimitry Andric bits<5> Dd; 18280b57cec5SDimitry Andric bits<5> Dm; 18290b57cec5SDimitry Andric 18300b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 18310b57cec5SDimitry Andric 18320b57cec5SDimitry Andric // Encode instruction operands. 18330b57cec5SDimitry Andric let Inst{3-0} = Dm{3-0}; 18340b57cec5SDimitry Andric let Inst{5} = Dm{4}; 18350b57cec5SDimitry Andric let Inst{15-12} = Dd{3-0}; 18360b57cec5SDimitry Andric let Inst{22} = Dd{4}; 18370b57cec5SDimitry Andric 18380b57cec5SDimitry Andric let Inst{27-23} = opcod1; 18390b57cec5SDimitry Andric let Inst{21-20} = opcod2; 18400b57cec5SDimitry Andric let Inst{19-16} = opcod3; 18410b57cec5SDimitry Andric let Inst{11-9} = 0b101; 18420b57cec5SDimitry Andric let Inst{8} = 1; // Double precision 18430b57cec5SDimitry Andric let Inst{7-6} = opcod4; 18440b57cec5SDimitry Andric let Inst{4} = opcod5; 18450b57cec5SDimitry Andric} 18460b57cec5SDimitry Andric 18470b57cec5SDimitry Andric// Double precision, binary 18480b57cec5SDimitry Andricclass ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 18490b57cec5SDimitry Andric dag iops, InstrItinClass itin, string opc, string asm, 18500b57cec5SDimitry Andric list<dag> pattern> 185181ad6265SDimitry Andric : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, "", pattern> { 18520b57cec5SDimitry Andric // Instruction operands. 18530b57cec5SDimitry Andric bits<5> Dd; 18540b57cec5SDimitry Andric bits<5> Dn; 18550b57cec5SDimitry Andric bits<5> Dm; 18560b57cec5SDimitry Andric 18570b57cec5SDimitry Andric // Encode instruction operands. 18580b57cec5SDimitry Andric let Inst{3-0} = Dm{3-0}; 18590b57cec5SDimitry Andric let Inst{5} = Dm{4}; 18600b57cec5SDimitry Andric let Inst{19-16} = Dn{3-0}; 18610b57cec5SDimitry Andric let Inst{7} = Dn{4}; 18620b57cec5SDimitry Andric let Inst{15-12} = Dd{3-0}; 18630b57cec5SDimitry Andric let Inst{22} = Dd{4}; 18640b57cec5SDimitry Andric 18650b57cec5SDimitry Andric let Inst{27-23} = opcod1; 18660b57cec5SDimitry Andric let Inst{21-20} = opcod2; 18670b57cec5SDimitry Andric let Inst{11-9} = 0b101; 18680b57cec5SDimitry Andric let Inst{8} = 1; // Double precision 18690b57cec5SDimitry Andric let Inst{6} = op6; 18700b57cec5SDimitry Andric let Inst{4} = op4; 18710b57cec5SDimitry Andric 18720b57cec5SDimitry Andric let Predicates = [HasVFP2, HasDPVFP]; 18730b57cec5SDimitry Andric} 18740b57cec5SDimitry Andric 18750b57cec5SDimitry Andric// FP, binary, not predicated 18760b57cec5SDimitry Andricclass ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 18770b57cec5SDimitry Andric InstrItinClass itin, string asm, list<dag> pattern> 18780b57cec5SDimitry Andric : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin, 18790b57cec5SDimitry Andric asm, "", pattern> 18800b57cec5SDimitry Andric{ 18810b57cec5SDimitry Andric // Instruction operands. 18820b57cec5SDimitry Andric bits<5> Dd; 18830b57cec5SDimitry Andric bits<5> Dn; 18840b57cec5SDimitry Andric bits<5> Dm; 18850b57cec5SDimitry Andric 18860b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 18870b57cec5SDimitry Andric 18880b57cec5SDimitry Andric // Encode instruction operands. 18890b57cec5SDimitry Andric let Inst{3-0} = Dm{3-0}; 18900b57cec5SDimitry Andric let Inst{5} = Dm{4}; 18910b57cec5SDimitry Andric let Inst{19-16} = Dn{3-0}; 18920b57cec5SDimitry Andric let Inst{7} = Dn{4}; 18930b57cec5SDimitry Andric let Inst{15-12} = Dd{3-0}; 18940b57cec5SDimitry Andric let Inst{22} = Dd{4}; 18950b57cec5SDimitry Andric 18960b57cec5SDimitry Andric let Inst{27-23} = opcod1; 18970b57cec5SDimitry Andric let Inst{21-20} = opcod2; 18980b57cec5SDimitry Andric let Inst{11-9} = 0b101; 18990b57cec5SDimitry Andric let Inst{8} = 1; // double precision 19000b57cec5SDimitry Andric let Inst{6} = opcod3; 19010b57cec5SDimitry Andric let Inst{4} = 0; 19020b57cec5SDimitry Andric 19030b57cec5SDimitry Andric let Predicates = [HasVFP2, HasDPVFP]; 19040b57cec5SDimitry Andric} 19050b57cec5SDimitry Andric 19060b57cec5SDimitry Andric// Single precision, unary, predicated 19070b57cec5SDimitry Andricclass ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 19080b57cec5SDimitry Andric bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 190981ad6265SDimitry Andric string asm, string cstr, list<dag> pattern> 191081ad6265SDimitry Andric : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, cstr, pattern> { 19110b57cec5SDimitry Andric // Instruction operands. 19120b57cec5SDimitry Andric bits<5> Sd; 19130b57cec5SDimitry Andric bits<5> Sm; 19140b57cec5SDimitry Andric 19150b57cec5SDimitry Andric // Encode instruction operands. 19160b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 19170b57cec5SDimitry Andric let Inst{5} = Sm{0}; 19180b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 19190b57cec5SDimitry Andric let Inst{22} = Sd{0}; 19200b57cec5SDimitry Andric 19210b57cec5SDimitry Andric let Inst{27-23} = opcod1; 19220b57cec5SDimitry Andric let Inst{21-20} = opcod2; 19230b57cec5SDimitry Andric let Inst{19-16} = opcod3; 19240b57cec5SDimitry Andric let Inst{11-9} = 0b101; 19250b57cec5SDimitry Andric let Inst{8} = 0; // Single precision 19260b57cec5SDimitry Andric let Inst{7-6} = opcod4; 19270b57cec5SDimitry Andric let Inst{4} = opcod5; 19280b57cec5SDimitry Andric} 19290b57cec5SDimitry Andric 19300b57cec5SDimitry Andric// Single precision, unary, non-predicated 19310b57cec5SDimitry Andricclass ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 19320b57cec5SDimitry Andric bit opcod5, dag oops, dag iops, InstrItinClass itin, 19330b57cec5SDimitry Andric string asm, list<dag> pattern> 19340b57cec5SDimitry Andric : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 19350b57cec5SDimitry Andric VFPUnaryFrm, itin, asm, "", pattern> { 19360b57cec5SDimitry Andric // Instruction operands. 19370b57cec5SDimitry Andric bits<5> Sd; 19380b57cec5SDimitry Andric bits<5> Sm; 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 19410b57cec5SDimitry Andric 19420b57cec5SDimitry Andric // Encode instruction operands. 19430b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 19440b57cec5SDimitry Andric let Inst{5} = Sm{0}; 19450b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 19460b57cec5SDimitry Andric let Inst{22} = Sd{0}; 19470b57cec5SDimitry Andric 19480b57cec5SDimitry Andric let Inst{27-23} = opcod1; 19490b57cec5SDimitry Andric let Inst{21-20} = opcod2; 19500b57cec5SDimitry Andric let Inst{19-16} = opcod3; 19510b57cec5SDimitry Andric let Inst{11-9} = 0b101; 19520b57cec5SDimitry Andric let Inst{8} = 0; // Single precision 19530b57cec5SDimitry Andric let Inst{7-6} = opcod4; 19540b57cec5SDimitry Andric let Inst{4} = opcod5; 19550b57cec5SDimitry Andric} 19560b57cec5SDimitry Andric 19570b57cec5SDimitry Andric// Single precision unary, if no NEON. Same as ASuI except not available if 19580b57cec5SDimitry Andric// NEON is enabled. 19590b57cec5SDimitry Andricclass ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 19600b57cec5SDimitry Andric bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 19610b57cec5SDimitry Andric string asm, list<dag> pattern> 19620b57cec5SDimitry Andric : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm, 196381ad6265SDimitry Andric "", pattern> { 19640b57cec5SDimitry Andric list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 19650b57cec5SDimitry Andric} 19660b57cec5SDimitry Andric 19670b57cec5SDimitry Andric// Single precision, binary 19680b57cec5SDimitry Andricclass ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, 19690b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 197081ad6265SDimitry Andric : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, "", pattern> { 19710b57cec5SDimitry Andric // Instruction operands. 19720b57cec5SDimitry Andric bits<5> Sd; 19730b57cec5SDimitry Andric bits<5> Sn; 19740b57cec5SDimitry Andric bits<5> Sm; 19750b57cec5SDimitry Andric 19760b57cec5SDimitry Andric // Encode instruction operands. 19770b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 19780b57cec5SDimitry Andric let Inst{5} = Sm{0}; 19790b57cec5SDimitry Andric let Inst{19-16} = Sn{4-1}; 19800b57cec5SDimitry Andric let Inst{7} = Sn{0}; 19810b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 19820b57cec5SDimitry Andric let Inst{22} = Sd{0}; 19830b57cec5SDimitry Andric 19840b57cec5SDimitry Andric let Inst{27-23} = opcod1; 19850b57cec5SDimitry Andric let Inst{21-20} = opcod2; 19860b57cec5SDimitry Andric let Inst{11-9} = 0b101; 19870b57cec5SDimitry Andric let Inst{8} = 0; // Single precision 19880b57cec5SDimitry Andric let Inst{6} = op6; 19890b57cec5SDimitry Andric let Inst{4} = op4; 19900b57cec5SDimitry Andric} 19910b57cec5SDimitry Andric 19920b57cec5SDimitry Andric// Single precision, binary, not predicated 19930b57cec5SDimitry Andricclass ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 19940b57cec5SDimitry Andric InstrItinClass itin, string asm, list<dag> pattern> 19950b57cec5SDimitry Andric : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 19960b57cec5SDimitry Andric VFPBinaryFrm, itin, asm, "", pattern> 19970b57cec5SDimitry Andric{ 19980b57cec5SDimitry Andric // Instruction operands. 19990b57cec5SDimitry Andric bits<5> Sd; 20000b57cec5SDimitry Andric bits<5> Sn; 20010b57cec5SDimitry Andric bits<5> Sm; 20020b57cec5SDimitry Andric 20030b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 20040b57cec5SDimitry Andric 20050b57cec5SDimitry Andric // Encode instruction operands. 20060b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 20070b57cec5SDimitry Andric let Inst{5} = Sm{0}; 20080b57cec5SDimitry Andric let Inst{19-16} = Sn{4-1}; 20090b57cec5SDimitry Andric let Inst{7} = Sn{0}; 20100b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 20110b57cec5SDimitry Andric let Inst{22} = Sd{0}; 20120b57cec5SDimitry Andric 20130b57cec5SDimitry Andric let Inst{27-23} = opcod1; 20140b57cec5SDimitry Andric let Inst{21-20} = opcod2; 20150b57cec5SDimitry Andric let Inst{11-9} = 0b101; 20160b57cec5SDimitry Andric let Inst{8} = 0; // Single precision 20170b57cec5SDimitry Andric let Inst{6} = opcod3; 20180b57cec5SDimitry Andric let Inst{4} = 0; 20190b57cec5SDimitry Andric} 20200b57cec5SDimitry Andric 20210b57cec5SDimitry Andric// Single precision binary, if no NEON. Same as ASbI except not available if 20220b57cec5SDimitry Andric// NEON is enabled. 20230b57cec5SDimitry Andricclass ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 20240b57cec5SDimitry Andric dag iops, InstrItinClass itin, string opc, string asm, 20250b57cec5SDimitry Andric list<dag> pattern> 20260b57cec5SDimitry Andric : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> { 20270b57cec5SDimitry Andric list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 20280b57cec5SDimitry Andric 20290b57cec5SDimitry Andric // Instruction operands. 20300b57cec5SDimitry Andric bits<5> Sd; 20310b57cec5SDimitry Andric bits<5> Sn; 20320b57cec5SDimitry Andric bits<5> Sm; 20330b57cec5SDimitry Andric 20340b57cec5SDimitry Andric // Encode instruction operands. 20350b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 20360b57cec5SDimitry Andric let Inst{5} = Sm{0}; 20370b57cec5SDimitry Andric let Inst{19-16} = Sn{4-1}; 20380b57cec5SDimitry Andric let Inst{7} = Sn{0}; 20390b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 20400b57cec5SDimitry Andric let Inst{22} = Sd{0}; 20410b57cec5SDimitry Andric} 20420b57cec5SDimitry Andric 20430b57cec5SDimitry Andric// Half precision, unary, predicated 20440b57cec5SDimitry Andricclass AHuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 20450b57cec5SDimitry Andric bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 20460b57cec5SDimitry Andric string asm, list<dag> pattern> 204781ad6265SDimitry Andric : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, "", pattern> { 20480b57cec5SDimitry Andric list<Predicate> Predicates = [HasFullFP16]; 20490b57cec5SDimitry Andric 20500b57cec5SDimitry Andric // Instruction operands. 20510b57cec5SDimitry Andric bits<5> Sd; 20520b57cec5SDimitry Andric bits<5> Sm; 20530b57cec5SDimitry Andric 20540b57cec5SDimitry Andric // Encode instruction operands. 20550b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 20560b57cec5SDimitry Andric let Inst{5} = Sm{0}; 20570b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 20580b57cec5SDimitry Andric let Inst{22} = Sd{0}; 20590b57cec5SDimitry Andric 20600b57cec5SDimitry Andric let Inst{27-23} = opcod1; 20610b57cec5SDimitry Andric let Inst{21-20} = opcod2; 20620b57cec5SDimitry Andric let Inst{19-16} = opcod3; 20630b57cec5SDimitry Andric let Inst{11-8} = 0b1001; // Half precision 20640b57cec5SDimitry Andric let Inst{7-6} = opcod4; 20650b57cec5SDimitry Andric let Inst{4} = opcod5; 20660b57cec5SDimitry Andric 20670b57cec5SDimitry Andric let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 20680b57cec5SDimitry Andric} 20690b57cec5SDimitry Andric 20700b57cec5SDimitry Andric// Half precision, unary, non-predicated 20710b57cec5SDimitry Andricclass AHuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 20720b57cec5SDimitry Andric bit opcod5, dag oops, dag iops, InstrItinClass itin, 20730b57cec5SDimitry Andric string asm, list<dag> pattern> 20740b57cec5SDimitry Andric : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 20750b57cec5SDimitry Andric VFPUnaryFrm, itin, asm, "", pattern> { 20760b57cec5SDimitry Andric list<Predicate> Predicates = [HasFullFP16]; 20770b57cec5SDimitry Andric 20780b57cec5SDimitry Andric // Instruction operands. 20790b57cec5SDimitry Andric bits<5> Sd; 20800b57cec5SDimitry Andric bits<5> Sm; 20810b57cec5SDimitry Andric 20820b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 20830b57cec5SDimitry Andric 20840b57cec5SDimitry Andric // Encode instruction operands. 20850b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 20860b57cec5SDimitry Andric let Inst{5} = Sm{0}; 20870b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 20880b57cec5SDimitry Andric let Inst{22} = Sd{0}; 20890b57cec5SDimitry Andric 20900b57cec5SDimitry Andric let Inst{27-23} = opcod1; 20910b57cec5SDimitry Andric let Inst{21-20} = opcod2; 20920b57cec5SDimitry Andric let Inst{19-16} = opcod3; 20930b57cec5SDimitry Andric let Inst{11-8} = 0b1001; // Half precision 20940b57cec5SDimitry Andric let Inst{7-6} = opcod4; 20950b57cec5SDimitry Andric let Inst{4} = opcod5; 20960b57cec5SDimitry Andric 20970b57cec5SDimitry Andric let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 20980b57cec5SDimitry Andric} 20990b57cec5SDimitry Andric 21000b57cec5SDimitry Andric// Half precision, binary 21010b57cec5SDimitry Andricclass AHbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, 21020b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 210381ad6265SDimitry Andric : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, "", pattern> { 21040b57cec5SDimitry Andric list<Predicate> Predicates = [HasFullFP16]; 21050b57cec5SDimitry Andric 21060b57cec5SDimitry Andric // Instruction operands. 21070b57cec5SDimitry Andric bits<5> Sd; 21080b57cec5SDimitry Andric bits<5> Sn; 21090b57cec5SDimitry Andric bits<5> Sm; 21100b57cec5SDimitry Andric 21110b57cec5SDimitry Andric // Encode instruction operands. 21120b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 21130b57cec5SDimitry Andric let Inst{5} = Sm{0}; 21140b57cec5SDimitry Andric let Inst{19-16} = Sn{4-1}; 21150b57cec5SDimitry Andric let Inst{7} = Sn{0}; 21160b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 21170b57cec5SDimitry Andric let Inst{22} = Sd{0}; 21180b57cec5SDimitry Andric 21190b57cec5SDimitry Andric let Inst{27-23} = opcod1; 21200b57cec5SDimitry Andric let Inst{21-20} = opcod2; 21210b57cec5SDimitry Andric let Inst{11-8} = 0b1001; // Half precision 21220b57cec5SDimitry Andric let Inst{6} = op6; 21230b57cec5SDimitry Andric let Inst{4} = op4; 21240b57cec5SDimitry Andric 21250b57cec5SDimitry Andric let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 21260b57cec5SDimitry Andric} 21270b57cec5SDimitry Andric 21280b57cec5SDimitry Andric// Half precision, binary, not predicated 21290b57cec5SDimitry Andricclass AHbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 21300b57cec5SDimitry Andric InstrItinClass itin, string asm, list<dag> pattern> 21310b57cec5SDimitry Andric : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 21320b57cec5SDimitry Andric VFPBinaryFrm, itin, asm, "", pattern> { 21330b57cec5SDimitry Andric list<Predicate> Predicates = [HasFullFP16]; 21340b57cec5SDimitry Andric 21350b57cec5SDimitry Andric // Instruction operands. 21360b57cec5SDimitry Andric bits<5> Sd; 21370b57cec5SDimitry Andric bits<5> Sn; 21380b57cec5SDimitry Andric bits<5> Sm; 21390b57cec5SDimitry Andric 21400b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 21410b57cec5SDimitry Andric 21420b57cec5SDimitry Andric // Encode instruction operands. 21430b57cec5SDimitry Andric let Inst{3-0} = Sm{4-1}; 21440b57cec5SDimitry Andric let Inst{5} = Sm{0}; 21450b57cec5SDimitry Andric let Inst{19-16} = Sn{4-1}; 21460b57cec5SDimitry Andric let Inst{7} = Sn{0}; 21470b57cec5SDimitry Andric let Inst{15-12} = Sd{4-1}; 21480b57cec5SDimitry Andric let Inst{22} = Sd{0}; 21490b57cec5SDimitry Andric 21500b57cec5SDimitry Andric let Inst{27-23} = opcod1; 21510b57cec5SDimitry Andric let Inst{21-20} = opcod2; 21520b57cec5SDimitry Andric let Inst{11-8} = 0b1001; // Half precision 21530b57cec5SDimitry Andric let Inst{6} = opcod3; 21540b57cec5SDimitry Andric let Inst{4} = 0; 21550b57cec5SDimitry Andric 21560b57cec5SDimitry Andric let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 21570b57cec5SDimitry Andric} 21580b57cec5SDimitry Andric 21590b57cec5SDimitry Andric// VFP conversion instructions 21600b57cec5SDimitry Andricclass AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 21610b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, string opc, string asm, 21620b57cec5SDimitry Andric list<dag> pattern> 216381ad6265SDimitry Andric : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, "", pattern> { 21640b57cec5SDimitry Andric let Inst{27-23} = opcod1; 21650b57cec5SDimitry Andric let Inst{21-20} = opcod2; 21660b57cec5SDimitry Andric let Inst{19-16} = opcod3; 21670b57cec5SDimitry Andric let Inst{11-8} = opcod4; 21680b57cec5SDimitry Andric let Inst{6} = 1; 21690b57cec5SDimitry Andric let Inst{4} = 0; 21700b57cec5SDimitry Andric} 21710b57cec5SDimitry Andric 21720b57cec5SDimitry Andric// VFP conversion between floating-point and fixed-point 21730b57cec5SDimitry Andricclass AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5, 21740b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, string opc, string asm, 21750b57cec5SDimitry Andric list<dag> pattern> 21760b57cec5SDimitry Andric : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> { 21770b57cec5SDimitry Andric bits<5> fbits; 21780b57cec5SDimitry Andric // size (fixed-point number): sx == 0 ? 16 : 32 21790b57cec5SDimitry Andric let Inst{7} = op5; // sx 21800b57cec5SDimitry Andric let Inst{5} = fbits{0}; 21810b57cec5SDimitry Andric let Inst{3-0} = fbits{4-1}; 21820b57cec5SDimitry Andric} 21830b57cec5SDimitry Andric 21840b57cec5SDimitry Andric// VFP conversion instructions, if no NEON 21850b57cec5SDimitry Andricclass AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 21860b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 21870b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 21880b57cec5SDimitry Andric : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 21890b57cec5SDimitry Andric pattern> { 21900b57cec5SDimitry Andric list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 21910b57cec5SDimitry Andric} 21920b57cec5SDimitry Andric 21930b57cec5SDimitry Andricclass AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f, 21940b57cec5SDimitry Andric InstrItinClass itin, 21950b57cec5SDimitry Andric string opc, string asm, list<dag> pattern> 219681ad6265SDimitry Andric : VFPAI<oops, iops, f, itin, opc, asm, "", pattern> { 21970b57cec5SDimitry Andric let Inst{27-20} = opcod1; 21980b57cec5SDimitry Andric let Inst{11-8} = opcod2; 21990b57cec5SDimitry Andric let Inst{4} = 1; 22000b57cec5SDimitry Andric} 22010b57cec5SDimitry Andric 22020b57cec5SDimitry Andricclass AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 22030b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 22040b57cec5SDimitry Andric : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>; 22050b57cec5SDimitry Andric 22060b57cec5SDimitry Andricclass AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 22070b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 22080b57cec5SDimitry Andric : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>; 22090b57cec5SDimitry Andric 22100b57cec5SDimitry Andricclass AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 22110b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 22120b57cec5SDimitry Andric : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>; 22130b57cec5SDimitry Andric 22140b57cec5SDimitry Andricclass AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 22150b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, list<dag> pattern> 22160b57cec5SDimitry Andric : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>; 22170b57cec5SDimitry Andric 22180b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 22190b57cec5SDimitry Andric 22200b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 22210b57cec5SDimitry Andric// ARM NEON Instruction templates. 22220b57cec5SDimitry Andric// 22230b57cec5SDimitry Andric 22240b57cec5SDimitry Andricclass NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 22250b57cec5SDimitry Andric InstrItinClass itin, string opc, string dt, string asm, string cstr, 22260b57cec5SDimitry Andric list<dag> pattern> 22270b57cec5SDimitry Andric : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 22280b57cec5SDimitry Andric let OutOperandList = oops; 22290b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 22300b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 22310b57cec5SDimitry Andric let Pattern = pattern; 22320b57cec5SDimitry Andric list<Predicate> Predicates = [HasNEON]; 22330b57cec5SDimitry Andric let DecoderNamespace = "NEON"; 22340b57cec5SDimitry Andric} 22350b57cec5SDimitry Andric 22360b57cec5SDimitry Andric// Same as NeonI except it does not have a "data type" specifier. 22370b57cec5SDimitry Andricclass NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 22380b57cec5SDimitry Andric InstrItinClass itin, string opc, string asm, string cstr, 22390b57cec5SDimitry Andric list<dag> pattern> 22400b57cec5SDimitry Andric : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 22410b57cec5SDimitry Andric let OutOperandList = oops; 22420b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 22430b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", "\t", asm); 22440b57cec5SDimitry Andric let Pattern = pattern; 22450b57cec5SDimitry Andric list<Predicate> Predicates = [HasNEON]; 22460b57cec5SDimitry Andric let DecoderNamespace = "NEON"; 22470b57cec5SDimitry Andric} 22480b57cec5SDimitry Andric 22490b57cec5SDimitry Andric// Same as NeonI except it is not predicated 22500b57cec5SDimitry Andricclass NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 22510b57cec5SDimitry Andric InstrItinClass itin, string opc, string dt, string asm, string cstr, 22520b57cec5SDimitry Andric list<dag> pattern> 22530b57cec5SDimitry Andric : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 22540b57cec5SDimitry Andric let OutOperandList = oops; 22550b57cec5SDimitry Andric let InOperandList = iops; 22560b57cec5SDimitry Andric let AsmString = !strconcat(opc, ".", dt, "\t", asm); 22570b57cec5SDimitry Andric let Pattern = pattern; 22580b57cec5SDimitry Andric list<Predicate> Predicates = [HasNEON]; 22590b57cec5SDimitry Andric let DecoderNamespace = "NEON"; 22600b57cec5SDimitry Andric 22610b57cec5SDimitry Andric let Inst{31-28} = 0b1111; 22620b57cec5SDimitry Andric} 22630b57cec5SDimitry Andric 22640b57cec5SDimitry Andricclass NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 22650b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 22660b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 22670b57cec5SDimitry Andric : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm, 22680b57cec5SDimitry Andric cstr, pattern> { 22690b57cec5SDimitry Andric let Inst{31-24} = 0b11110100; 22700b57cec5SDimitry Andric let Inst{23} = op23; 22710b57cec5SDimitry Andric let Inst{21-20} = op21_20; 22720b57cec5SDimitry Andric let Inst{11-8} = op11_8; 22730b57cec5SDimitry Andric let Inst{7-4} = op7_4; 22740b57cec5SDimitry Andric 22750b57cec5SDimitry Andric let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder"; 22760b57cec5SDimitry Andric let DecoderNamespace = "NEONLoadStore"; 22770b57cec5SDimitry Andric 22780b57cec5SDimitry Andric bits<5> Vd; 22790b57cec5SDimitry Andric bits<6> Rn; 22800b57cec5SDimitry Andric bits<4> Rm; 22810b57cec5SDimitry Andric 22820b57cec5SDimitry Andric let Inst{22} = Vd{4}; 22830b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 22840b57cec5SDimitry Andric let Inst{19-16} = Rn{3-0}; 22850b57cec5SDimitry Andric let Inst{3-0} = Rm{3-0}; 22860b57cec5SDimitry Andric} 22870b57cec5SDimitry Andric 22880b57cec5SDimitry Andricclass NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 22890b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 22900b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 22910b57cec5SDimitry Andric : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc, 22920b57cec5SDimitry Andric dt, asm, cstr, pattern> { 22930b57cec5SDimitry Andric bits<3> lane; 22940b57cec5SDimitry Andric} 22950b57cec5SDimitry Andric 22960b57cec5SDimitry Andricclass PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr> 22970b57cec5SDimitry Andric : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 22980b57cec5SDimitry Andric itin> { 22990b57cec5SDimitry Andric let OutOperandList = oops; 23000b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 23010b57cec5SDimitry Andric list<Predicate> Predicates = [HasNEON]; 23020b57cec5SDimitry Andric} 23030b57cec5SDimitry Andric 23040b57cec5SDimitry Andricclass PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr, 23050b57cec5SDimitry Andric list<dag> pattern> 23060b57cec5SDimitry Andric : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 23070b57cec5SDimitry Andric itin> { 23080b57cec5SDimitry Andric let OutOperandList = oops; 23090b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 23100b57cec5SDimitry Andric let Pattern = pattern; 23110b57cec5SDimitry Andric list<Predicate> Predicates = [HasNEON]; 23120b57cec5SDimitry Andric} 23130b57cec5SDimitry Andric 23140b57cec5SDimitry Andricclass NDataI<dag oops, dag iops, Format f, InstrItinClass itin, 23150b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 23160b57cec5SDimitry Andric : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr, 23170b57cec5SDimitry Andric pattern> { 23180b57cec5SDimitry Andric let Inst{31-25} = 0b1111001; 23190b57cec5SDimitry Andric let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 23200b57cec5SDimitry Andric let DecoderNamespace = "NEONData"; 23210b57cec5SDimitry Andric} 23220b57cec5SDimitry Andric 23230b57cec5SDimitry Andricclass NDataXI<dag oops, dag iops, Format f, InstrItinClass itin, 23240b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 23250b57cec5SDimitry Andric : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm, 23260b57cec5SDimitry Andric cstr, pattern> { 23270b57cec5SDimitry Andric let Inst{31-25} = 0b1111001; 23280b57cec5SDimitry Andric let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 23290b57cec5SDimitry Andric let DecoderNamespace = "NEONData"; 23300b57cec5SDimitry Andric} 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andric// NEON "one register and a modified immediate" format. 23330b57cec5SDimitry Andricclass N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6, 23340b57cec5SDimitry Andric bit op5, bit op4, 23350b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 23360b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, 23370b57cec5SDimitry Andric list<dag> pattern> 23380b57cec5SDimitry Andric : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> { 23390b57cec5SDimitry Andric let Inst{23} = op23; 23400b57cec5SDimitry Andric let Inst{21-19} = op21_19; 23410b57cec5SDimitry Andric let Inst{11-8} = op11_8; 23420b57cec5SDimitry Andric let Inst{7} = op7; 23430b57cec5SDimitry Andric let Inst{6} = op6; 23440b57cec5SDimitry Andric let Inst{5} = op5; 23450b57cec5SDimitry Andric let Inst{4} = op4; 23460b57cec5SDimitry Andric 23470b57cec5SDimitry Andric // Instruction operands. 23480b57cec5SDimitry Andric bits<5> Vd; 23490b57cec5SDimitry Andric bits<13> SIMM; 23500b57cec5SDimitry Andric 23510b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 23520b57cec5SDimitry Andric let Inst{22} = Vd{4}; 23530b57cec5SDimitry Andric let Inst{24} = SIMM{7}; 23540b57cec5SDimitry Andric let Inst{18-16} = SIMM{6-4}; 23550b57cec5SDimitry Andric let Inst{3-0} = SIMM{3-0}; 23568bcb0991SDimitry Andric let DecoderMethod = "DecodeVMOVModImmInstruction"; 23570b57cec5SDimitry Andric} 23580b57cec5SDimitry Andric 23590b57cec5SDimitry Andric// NEON 2 vector register format. 23600b57cec5SDimitry Andricclass N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 23610b57cec5SDimitry Andric bits<5> op11_7, bit op6, bit op4, 23620b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 23630b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 23640b57cec5SDimitry Andric : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> { 23650b57cec5SDimitry Andric let Inst{24-23} = op24_23; 23660b57cec5SDimitry Andric let Inst{21-20} = op21_20; 23670b57cec5SDimitry Andric let Inst{19-18} = op19_18; 23680b57cec5SDimitry Andric let Inst{17-16} = op17_16; 23690b57cec5SDimitry Andric let Inst{11-7} = op11_7; 23700b57cec5SDimitry Andric let Inst{6} = op6; 23710b57cec5SDimitry Andric let Inst{4} = op4; 23720b57cec5SDimitry Andric 23730b57cec5SDimitry Andric // Instruction operands. 23740b57cec5SDimitry Andric bits<5> Vd; 23750b57cec5SDimitry Andric bits<5> Vm; 23760b57cec5SDimitry Andric 23770b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 23780b57cec5SDimitry Andric let Inst{22} = Vd{4}; 23790b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 23800b57cec5SDimitry Andric let Inst{5} = Vm{4}; 23810b57cec5SDimitry Andric} 23820b57cec5SDimitry Andric 23830b57cec5SDimitry Andric// Same as N2V but not predicated. 23840b57cec5SDimitry Andricclass N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6, 23850b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, string OpcodeStr, 23860b57cec5SDimitry Andric string Dt, list<dag> pattern> 23870b57cec5SDimitry Andric : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin, 23880b57cec5SDimitry Andric OpcodeStr, Dt, "$Vd, $Vm", "", pattern> { 23890b57cec5SDimitry Andric bits<5> Vd; 23900b57cec5SDimitry Andric bits<5> Vm; 23910b57cec5SDimitry Andric 23920b57cec5SDimitry Andric // Encode instruction operands 23930b57cec5SDimitry Andric let Inst{22} = Vd{4}; 23940b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 23950b57cec5SDimitry Andric let Inst{5} = Vm{4}; 23960b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 23970b57cec5SDimitry Andric 23980b57cec5SDimitry Andric // Encode constant bits 23990b57cec5SDimitry Andric let Inst{27-23} = 0b00111; 24000b57cec5SDimitry Andric let Inst{21-20} = 0b11; 24010b57cec5SDimitry Andric let Inst{19-18} = op19_18; 24020b57cec5SDimitry Andric let Inst{17-16} = op17_16; 24030b57cec5SDimitry Andric let Inst{11} = 0; 24040b57cec5SDimitry Andric let Inst{10-8} = op10_8; 24050b57cec5SDimitry Andric let Inst{7} = op7; 24060b57cec5SDimitry Andric let Inst{6} = op6; 24070b57cec5SDimitry Andric let Inst{4} = 0; 24080b57cec5SDimitry Andric 24090b57cec5SDimitry Andric let DecoderNamespace = "NEON"; 24100b57cec5SDimitry Andric} 24110b57cec5SDimitry Andric 24120b57cec5SDimitry Andric// Same as N2V except it doesn't have a datatype suffix. 24130b57cec5SDimitry Andricclass N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 24140b57cec5SDimitry Andric bits<5> op11_7, bit op6, bit op4, 24150b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 24160b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 24170b57cec5SDimitry Andric : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> { 24180b57cec5SDimitry Andric let Inst{24-23} = op24_23; 24190b57cec5SDimitry Andric let Inst{21-20} = op21_20; 24200b57cec5SDimitry Andric let Inst{19-18} = op19_18; 24210b57cec5SDimitry Andric let Inst{17-16} = op17_16; 24220b57cec5SDimitry Andric let Inst{11-7} = op11_7; 24230b57cec5SDimitry Andric let Inst{6} = op6; 24240b57cec5SDimitry Andric let Inst{4} = op4; 24250b57cec5SDimitry Andric 24260b57cec5SDimitry Andric // Instruction operands. 24270b57cec5SDimitry Andric bits<5> Vd; 24280b57cec5SDimitry Andric bits<5> Vm; 24290b57cec5SDimitry Andric 24300b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 24310b57cec5SDimitry Andric let Inst{22} = Vd{4}; 24320b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 24330b57cec5SDimitry Andric let Inst{5} = Vm{4}; 24340b57cec5SDimitry Andric} 24350b57cec5SDimitry Andric 24360b57cec5SDimitry Andric// NEON 2 vector register with immediate. 24370b57cec5SDimitry Andricclass N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 24380b57cec5SDimitry Andric dag oops, dag iops, Format f, InstrItinClass itin, 24390b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 24400b57cec5SDimitry Andric : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 24410b57cec5SDimitry Andric let Inst{24} = op24; 24420b57cec5SDimitry Andric let Inst{23} = op23; 24430b57cec5SDimitry Andric let Inst{11-8} = op11_8; 24440b57cec5SDimitry Andric let Inst{7} = op7; 24450b57cec5SDimitry Andric let Inst{6} = op6; 24460b57cec5SDimitry Andric let Inst{4} = op4; 24470b57cec5SDimitry Andric 24480b57cec5SDimitry Andric // Instruction operands. 24490b57cec5SDimitry Andric bits<5> Vd; 24500b57cec5SDimitry Andric bits<5> Vm; 24510b57cec5SDimitry Andric bits<6> SIMM; 24520b57cec5SDimitry Andric 24530b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 24540b57cec5SDimitry Andric let Inst{22} = Vd{4}; 24550b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 24560b57cec5SDimitry Andric let Inst{5} = Vm{4}; 24570b57cec5SDimitry Andric let Inst{21-16} = SIMM{5-0}; 24580b57cec5SDimitry Andric} 24590b57cec5SDimitry Andric 24600b57cec5SDimitry Andric// NEON 3 vector register format. 24610b57cec5SDimitry Andric 24620b57cec5SDimitry Andricclass N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 24630b57cec5SDimitry Andric bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 24640b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, 24650b57cec5SDimitry Andric list<dag> pattern> 24660b57cec5SDimitry Andric : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 24670b57cec5SDimitry Andric let Inst{24} = op24; 24680b57cec5SDimitry Andric let Inst{23} = op23; 24690b57cec5SDimitry Andric let Inst{21-20} = op21_20; 24700b57cec5SDimitry Andric let Inst{11-8} = op11_8; 24710b57cec5SDimitry Andric let Inst{6} = op6; 24720b57cec5SDimitry Andric let Inst{4} = op4; 24730b57cec5SDimitry Andric} 24740b57cec5SDimitry Andric 24750b57cec5SDimitry Andricclass N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, 24760b57cec5SDimitry Andric dag oops, dag iops, Format f, InstrItinClass itin, 24770b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 24780b57cec5SDimitry Andric : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 24790b57cec5SDimitry Andric oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 24800b57cec5SDimitry Andric // Instruction operands. 24810b57cec5SDimitry Andric bits<5> Vd; 24820b57cec5SDimitry Andric bits<5> Vn; 24830b57cec5SDimitry Andric bits<5> Vm; 24840b57cec5SDimitry Andric 24850b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 24860b57cec5SDimitry Andric let Inst{22} = Vd{4}; 24870b57cec5SDimitry Andric let Inst{19-16} = Vn{3-0}; 24880b57cec5SDimitry Andric let Inst{7} = Vn{4}; 24890b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 24900b57cec5SDimitry Andric let Inst{5} = Vm{4}; 24910b57cec5SDimitry Andric} 24920b57cec5SDimitry Andric 24930b57cec5SDimitry Andricclass N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 24940b57cec5SDimitry Andric bit op4, dag oops, dag iops,Format f, InstrItinClass itin, 24950b57cec5SDimitry Andric string OpcodeStr, string Dt, list<dag> pattern> 24960b57cec5SDimitry Andric : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr, 24970b57cec5SDimitry Andric Dt, "$Vd, $Vn, $Vm", "", pattern> { 24980b57cec5SDimitry Andric bits<5> Vd; 24990b57cec5SDimitry Andric bits<5> Vn; 25000b57cec5SDimitry Andric bits<5> Vm; 25010b57cec5SDimitry Andric 25020b57cec5SDimitry Andric // Encode instruction operands 25030b57cec5SDimitry Andric let Inst{22} = Vd{4}; 25040b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 25050b57cec5SDimitry Andric let Inst{19-16} = Vn{3-0}; 25060b57cec5SDimitry Andric let Inst{7} = Vn{4}; 25070b57cec5SDimitry Andric let Inst{5} = Vm{4}; 25080b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 25090b57cec5SDimitry Andric 25100b57cec5SDimitry Andric // Encode constant bits 25110b57cec5SDimitry Andric let Inst{27-23} = op27_23; 25120b57cec5SDimitry Andric let Inst{21-20} = op21_20; 25130b57cec5SDimitry Andric let Inst{11-8} = op11_8; 25140b57cec5SDimitry Andric let Inst{6} = op6; 25150b57cec5SDimitry Andric let Inst{4} = op4; 25160b57cec5SDimitry Andric} 25170b57cec5SDimitry Andric 25180b57cec5SDimitry Andricclass N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 25190b57cec5SDimitry Andric bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 25200b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, 25210b57cec5SDimitry Andric list<dag> pattern> 25220b57cec5SDimitry Andric : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 25230b57cec5SDimitry Andric oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 25240b57cec5SDimitry Andric 25250b57cec5SDimitry Andric // Instruction operands. 25260b57cec5SDimitry Andric bits<5> Vd; 25270b57cec5SDimitry Andric bits<5> Vn; 25280b57cec5SDimitry Andric bits<5> Vm; 25290b57cec5SDimitry Andric bit lane; 25300b57cec5SDimitry Andric 25310b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 25320b57cec5SDimitry Andric let Inst{22} = Vd{4}; 25330b57cec5SDimitry Andric let Inst{19-16} = Vn{3-0}; 25340b57cec5SDimitry Andric let Inst{7} = Vn{4}; 25350b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 25360b57cec5SDimitry Andric let Inst{5} = lane; 25370b57cec5SDimitry Andric} 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andricclass N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 25400b57cec5SDimitry Andric bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 25410b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, 25420b57cec5SDimitry Andric list<dag> pattern> 25430b57cec5SDimitry Andric : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 25440b57cec5SDimitry Andric oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 25450b57cec5SDimitry Andric 25460b57cec5SDimitry Andric // Instruction operands. 25470b57cec5SDimitry Andric bits<5> Vd; 25480b57cec5SDimitry Andric bits<5> Vn; 25490b57cec5SDimitry Andric bits<5> Vm; 25500b57cec5SDimitry Andric bits<2> lane; 25510b57cec5SDimitry Andric 25520b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 25530b57cec5SDimitry Andric let Inst{22} = Vd{4}; 25540b57cec5SDimitry Andric let Inst{19-16} = Vn{3-0}; 25550b57cec5SDimitry Andric let Inst{7} = Vn{4}; 25560b57cec5SDimitry Andric let Inst{2-0} = Vm{2-0}; 25570b57cec5SDimitry Andric let Inst{5} = lane{1}; 25580b57cec5SDimitry Andric let Inst{3} = lane{0}; 25590b57cec5SDimitry Andric} 25600b57cec5SDimitry Andric 25610b57cec5SDimitry Andric// Same as N3V except it doesn't have a data type suffix. 25620b57cec5SDimitry Andricclass N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 25630b57cec5SDimitry Andric bit op4, 25640b57cec5SDimitry Andric dag oops, dag iops, Format f, InstrItinClass itin, 25650b57cec5SDimitry Andric string opc, string asm, string cstr, list<dag> pattern> 25660b57cec5SDimitry Andric : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> { 25670b57cec5SDimitry Andric let Inst{24} = op24; 25680b57cec5SDimitry Andric let Inst{23} = op23; 25690b57cec5SDimitry Andric let Inst{21-20} = op21_20; 25700b57cec5SDimitry Andric let Inst{11-8} = op11_8; 25710b57cec5SDimitry Andric let Inst{6} = op6; 25720b57cec5SDimitry Andric let Inst{4} = op4; 25730b57cec5SDimitry Andric 25740b57cec5SDimitry Andric // Instruction operands. 25750b57cec5SDimitry Andric bits<5> Vd; 25760b57cec5SDimitry Andric bits<5> Vn; 25770b57cec5SDimitry Andric bits<5> Vm; 25780b57cec5SDimitry Andric 25790b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 25800b57cec5SDimitry Andric let Inst{22} = Vd{4}; 25810b57cec5SDimitry Andric let Inst{19-16} = Vn{3-0}; 25820b57cec5SDimitry Andric let Inst{7} = Vn{4}; 25830b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 25840b57cec5SDimitry Andric let Inst{5} = Vm{4}; 25850b57cec5SDimitry Andric} 25860b57cec5SDimitry Andric 25870b57cec5SDimitry Andric// NEON VMOVs between scalar and core registers. 25880b57cec5SDimitry Andricclass NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 25890b57cec5SDimitry Andric dag oops, dag iops, Format f, InstrItinClass itin, 25900b57cec5SDimitry Andric string opc, string dt, string asm, list<dag> pattern> 25910b57cec5SDimitry Andric : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain, 25920b57cec5SDimitry Andric "", itin> { 25930b57cec5SDimitry Andric let Inst{27-20} = opcod1; 25940b57cec5SDimitry Andric let Inst{11-8} = opcod2; 25950b57cec5SDimitry Andric let Inst{6-5} = opcod3; 25960b57cec5SDimitry Andric let Inst{4} = 1; 25970b57cec5SDimitry Andric // A8.6.303, A8.6.328, A8.6.329 25980b57cec5SDimitry Andric let Inst{3-0} = 0b0000; 25990b57cec5SDimitry Andric 26000b57cec5SDimitry Andric let OutOperandList = oops; 26010b57cec5SDimitry Andric let InOperandList = !con(iops, (ins pred:$p)); 26020b57cec5SDimitry Andric let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 26030b57cec5SDimitry Andric let Pattern = pattern; 26040b57cec5SDimitry Andric list<Predicate> Predicates = [HasNEON]; 26050b57cec5SDimitry Andric 26060b57cec5SDimitry Andric let PostEncoderMethod = "NEONThumb2DupPostEncoder"; 26070b57cec5SDimitry Andric let DecoderNamespace = "NEONDup"; 26080b57cec5SDimitry Andric 26090b57cec5SDimitry Andric bits<5> V; 26100b57cec5SDimitry Andric bits<4> R; 26110b57cec5SDimitry Andric bits<4> p; 26120b57cec5SDimitry Andric bits<4> lane; 26130b57cec5SDimitry Andric 26140b57cec5SDimitry Andric let Inst{31-28} = p{3-0}; 26150b57cec5SDimitry Andric let Inst{7} = V{4}; 26160b57cec5SDimitry Andric let Inst{19-16} = V{3-0}; 26170b57cec5SDimitry Andric let Inst{15-12} = R{3-0}; 26180b57cec5SDimitry Andric} 26190b57cec5SDimitry Andricclass NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 26200b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 26210b57cec5SDimitry Andric string opc, string dt, string asm, list<dag> pattern> 26220b57cec5SDimitry Andric : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin, 26230b57cec5SDimitry Andric opc, dt, asm, pattern>; 26240b57cec5SDimitry Andricclass NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 26250b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 26260b57cec5SDimitry Andric string opc, string dt, string asm, list<dag> pattern> 26270b57cec5SDimitry Andric : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin, 26280b57cec5SDimitry Andric opc, dt, asm, pattern>; 26290b57cec5SDimitry Andricclass NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 26300b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 26310b57cec5SDimitry Andric string opc, string dt, string asm, list<dag> pattern> 26320b57cec5SDimitry Andric : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin, 26330b57cec5SDimitry Andric opc, dt, asm, pattern>; 26340b57cec5SDimitry Andric 26350b57cec5SDimitry Andric// Vector Duplicate Lane (from scalar to all elements) 26360b57cec5SDimitry Andricclass NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops, 26370b57cec5SDimitry Andric InstrItinClass itin, string opc, string dt, string asm, 26380b57cec5SDimitry Andric list<dag> pattern> 26390b57cec5SDimitry Andric : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> { 26400b57cec5SDimitry Andric let Inst{24-23} = 0b11; 26410b57cec5SDimitry Andric let Inst{21-20} = 0b11; 26420b57cec5SDimitry Andric let Inst{19-16} = op19_16; 26430b57cec5SDimitry Andric let Inst{11-7} = 0b11000; 26440b57cec5SDimitry Andric let Inst{6} = op6; 26450b57cec5SDimitry Andric let Inst{4} = 0; 26460b57cec5SDimitry Andric 26470b57cec5SDimitry Andric bits<5> Vd; 26480b57cec5SDimitry Andric bits<5> Vm; 26490b57cec5SDimitry Andric 26500b57cec5SDimitry Andric let Inst{22} = Vd{4}; 26510b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 26520b57cec5SDimitry Andric let Inst{5} = Vm{4}; 26530b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 26540b57cec5SDimitry Andric} 26550b57cec5SDimitry Andric 26560b57cec5SDimitry Andric// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON 26570b57cec5SDimitry Andric// for single-precision FP. 26580b57cec5SDimitry Andricclass NEONFPPat<dag pattern, dag result> : Pat<pattern, result> { 26590b57cec5SDimitry Andric list<Predicate> Predicates = [HasNEON,UseNEONForFP]; 26600b57cec5SDimitry Andric} 26610b57cec5SDimitry Andric 26620b57cec5SDimitry Andric// VFP/NEON Instruction aliases for type suffices. 26630b57cec5SDimitry Andric// Note: When EmitPriority == 1, the alias will be used for printing 26640b57cec5SDimitry Andricclass VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result, bit EmitPriority = 0> : 26650b57cec5SDimitry Andric InstAlias<!strconcat(opc, dt, "\t", asm), Result, EmitPriority>, Requires<[HasFPRegs]>; 26660b57cec5SDimitry Andric 26670b57cec5SDimitry Andric// Note: When EmitPriority == 1, the alias will be used for printing 26680b57cec5SDimitry Andricmulticlass VFPDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> { 26690b57cec5SDimitry Andric def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>; 26700b57cec5SDimitry Andric def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>; 26710b57cec5SDimitry Andric def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>; 26720b57cec5SDimitry Andric def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>; 26730b57cec5SDimitry Andric} 26740b57cec5SDimitry Andric 26750b57cec5SDimitry Andric// Note: When EmitPriority == 1, the alias will be used for printing 26760b57cec5SDimitry Andricmulticlass NEONDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> { 26770b57cec5SDimitry Andric let Predicates = [HasNEON] in { 26780b57cec5SDimitry Andric def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>; 26790b57cec5SDimitry Andric def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>; 26800b57cec5SDimitry Andric def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>; 26810b57cec5SDimitry Andric def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>; 26820b57cec5SDimitry Andric} 26830b57cec5SDimitry Andric} 26840b57cec5SDimitry Andric 26850b57cec5SDimitry Andric// The same alias classes using AsmPseudo instead, for the more complex 26860b57cec5SDimitry Andric// stuff in NEON that InstAlias can't quite handle. 26870b57cec5SDimitry Andric// Note that we can't use anonymous defm references here like we can 26880b57cec5SDimitry Andric// above, as we care about the ultimate instruction enum names generated, unlike 26890b57cec5SDimitry Andric// for instalias defs. 26900b57cec5SDimitry Andricclass NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> : 26910b57cec5SDimitry Andric AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>; 26920b57cec5SDimitry Andric 26930b57cec5SDimitry Andric// Extension of NEON 3-vector data processing instructions in coprocessor 8 26940b57cec5SDimitry Andric// encoding space, introduced in ARMv8.3-A. 26950b57cec5SDimitry Andricclass N3VCP8<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4, 26960b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 26970b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 26980b57cec5SDimitry Andric : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, 26990b57cec5SDimitry Andric dt, asm, cstr, pattern> { 27000b57cec5SDimitry Andric bits<5> Vd; 27010b57cec5SDimitry Andric bits<5> Vn; 27020b57cec5SDimitry Andric bits<5> Vm; 27030b57cec5SDimitry Andric 27040b57cec5SDimitry Andric let DecoderNamespace = "VFPV8"; 27050b57cec5SDimitry Andric // These have the same encodings in ARM and Thumb2 27060b57cec5SDimitry Andric let PostEncoderMethod = ""; 27070b57cec5SDimitry Andric 27080b57cec5SDimitry Andric let Inst{31-25} = 0b1111110; 27090b57cec5SDimitry Andric let Inst{24-23} = op24_23; 27100b57cec5SDimitry Andric let Inst{22} = Vd{4}; 27110b57cec5SDimitry Andric let Inst{21-20} = op21_20; 27120b57cec5SDimitry Andric let Inst{19-16} = Vn{3-0}; 27130b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 27140b57cec5SDimitry Andric let Inst{11-8} = 0b1000; 27150b57cec5SDimitry Andric let Inst{7} = Vn{4}; 27160b57cec5SDimitry Andric let Inst{6} = op6; 27170b57cec5SDimitry Andric let Inst{5} = Vm{4}; 27180b57cec5SDimitry Andric let Inst{4} = op4; 27190b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 27200b57cec5SDimitry Andric} 27210b57cec5SDimitry Andric 27220b57cec5SDimitry Andric// Extension of NEON 2-vector-and-scalar data processing instructions in 27230b57cec5SDimitry Andric// coprocessor 8 encoding space, introduced in ARMv8.3-A. 27240b57cec5SDimitry Andricclass N3VLaneCP8<bit op23, bits<2> op21_20, bit op6, bit op4, 27250b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 27260b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 27270b57cec5SDimitry Andric : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, 27280b57cec5SDimitry Andric dt, asm, cstr, pattern> { 27290b57cec5SDimitry Andric bits<5> Vd; 27300b57cec5SDimitry Andric bits<5> Vn; 27310b57cec5SDimitry Andric bits<5> Vm; 27320b57cec5SDimitry Andric 27330b57cec5SDimitry Andric let DecoderNamespace = "VFPV8"; 27340b57cec5SDimitry Andric // These have the same encodings in ARM and Thumb2 27350b57cec5SDimitry Andric let PostEncoderMethod = ""; 27360b57cec5SDimitry Andric 27370b57cec5SDimitry Andric let Inst{31-24} = 0b11111110; 27380b57cec5SDimitry Andric let Inst{23} = op23; 27390b57cec5SDimitry Andric let Inst{22} = Vd{4}; 27400b57cec5SDimitry Andric let Inst{21-20} = op21_20; 27410b57cec5SDimitry Andric let Inst{19-16} = Vn{3-0}; 27420b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 27430b57cec5SDimitry Andric let Inst{11-8} = 0b1000; 27440b57cec5SDimitry Andric let Inst{7} = Vn{4}; 27450b57cec5SDimitry Andric let Inst{6} = op6; 27460b57cec5SDimitry Andric // Bit 5 set by sub-classes 27470b57cec5SDimitry Andric let Inst{4} = op4; 27480b57cec5SDimitry Andric let Inst{3-0} = Vm{3-0}; 27490b57cec5SDimitry Andric} 27500b57cec5SDimitry Andric 27510b57cec5SDimitry Andric// In Armv8.2-A, some NEON instructions are added that encode Vn and Vm 27520b57cec5SDimitry Andric// differently: 27530b57cec5SDimitry Andric// if Q == ‘1’ then UInt(N:Vn) else UInt(Vn:N); 27540b57cec5SDimitry Andric// if Q == ‘1’ then UInt(M:Vm) else UInt(Vm:M); 27550b57cec5SDimitry Andric// Class N3VCP8 above describes the Q=1 case, and this class the Q=0 case. 27560b57cec5SDimitry Andricclass N3VCP8Q0<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4, 27570b57cec5SDimitry Andric dag oops, dag iops, InstrItinClass itin, 27580b57cec5SDimitry Andric string opc, string dt, string asm, string cstr, list<dag> pattern> 27590b57cec5SDimitry Andric : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, dt, asm, cstr, pattern> { 27600b57cec5SDimitry Andric bits<5> Vd; 27610b57cec5SDimitry Andric bits<5> Vn; 27620b57cec5SDimitry Andric bits<5> Vm; 27630b57cec5SDimitry Andric 27640b57cec5SDimitry Andric let DecoderNamespace = "VFPV8"; 27650b57cec5SDimitry Andric // These have the same encodings in ARM and Thumb2 27660b57cec5SDimitry Andric let PostEncoderMethod = ""; 27670b57cec5SDimitry Andric 27680b57cec5SDimitry Andric let Inst{31-25} = 0b1111110; 27690b57cec5SDimitry Andric let Inst{24-23} = op24_23; 27700b57cec5SDimitry Andric let Inst{22} = Vd{4}; 27710b57cec5SDimitry Andric let Inst{21-20} = op21_20; 27720b57cec5SDimitry Andric let Inst{19-16} = Vn{4-1}; 27730b57cec5SDimitry Andric let Inst{15-12} = Vd{3-0}; 27740b57cec5SDimitry Andric let Inst{11-8} = 0b1000; 27750b57cec5SDimitry Andric let Inst{7} = Vn{0}; 27760b57cec5SDimitry Andric let Inst{6} = op6; 27770b57cec5SDimitry Andric let Inst{5} = Vm{0}; 27780b57cec5SDimitry Andric let Inst{4} = op4; 27790b57cec5SDimitry Andric let Inst{3-0} = Vm{4-1}; 27800b57cec5SDimitry Andric} 27810b57cec5SDimitry Andric 27820b57cec5SDimitry Andric// Operand types for complex instructions 27830b57cec5SDimitry Andricclass ComplexRotationOperand<int Angle, int Remainder, string Type, string Diag> 27840b57cec5SDimitry Andric : AsmOperandClass { 27850b57cec5SDimitry Andric let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 27860b57cec5SDimitry Andric let DiagnosticString = "complex rotation must be " # Diag; 27870b57cec5SDimitry Andric let Name = "ComplexRotation" # Type; 27880b57cec5SDimitry Andric} 27890b57cec5SDimitry Andricdef complexrotateop : Operand<i32> { 27900b57cec5SDimitry Andric let ParserMatchClass = ComplexRotationOperand<90, 0, "Even", "0, 90, 180 or 270">; 27910b57cec5SDimitry Andric let PrintMethod = "printComplexRotationOp<90, 0>"; 27920b57cec5SDimitry Andric} 27930b57cec5SDimitry Andricdef complexrotateopodd : Operand<i32> { 27940b57cec5SDimitry Andric let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd", "90 or 270">; 27950b57cec5SDimitry Andric let PrintMethod = "printComplexRotationOp<180, 90>"; 27960b57cec5SDimitry Andric} 27970b57cec5SDimitry Andric 27988bcb0991SDimitry Andricdef MveSaturateOperand : AsmOperandClass { 27998bcb0991SDimitry Andric let PredicateMethod = "isMveSaturateOp"; 28008bcb0991SDimitry Andric let DiagnosticString = "saturate operand must be 48 or 64"; 28018bcb0991SDimitry Andric let Name = "MveSaturate"; 28028bcb0991SDimitry Andric} 28038bcb0991SDimitry Andricdef saturateop : Operand<i32> { 28048bcb0991SDimitry Andric let ParserMatchClass = MveSaturateOperand; 28058bcb0991SDimitry Andric let PrintMethod = "printMveSaturateOp"; 28068bcb0991SDimitry Andric} 28078bcb0991SDimitry Andric 28080b57cec5SDimitry Andric// Data type suffix token aliases. Implements Table A7-3 in the ARM ARM. 28090b57cec5SDimitry Andricdef : TokenAlias<".s8", ".i8">; 28100b57cec5SDimitry Andricdef : TokenAlias<".u8", ".i8">; 28110b57cec5SDimitry Andricdef : TokenAlias<".s16", ".i16">; 28120b57cec5SDimitry Andricdef : TokenAlias<".u16", ".i16">; 28130b57cec5SDimitry Andricdef : TokenAlias<".s32", ".i32">; 28140b57cec5SDimitry Andricdef : TokenAlias<".u32", ".i32">; 28150b57cec5SDimitry Andricdef : TokenAlias<".s64", ".i64">; 28160b57cec5SDimitry Andricdef : TokenAlias<".u64", ".i64">; 28170b57cec5SDimitry Andric 28180b57cec5SDimitry Andricdef : TokenAlias<".i8", ".8">; 28190b57cec5SDimitry Andricdef : TokenAlias<".i16", ".16">; 28200b57cec5SDimitry Andricdef : TokenAlias<".i32", ".32">; 28210b57cec5SDimitry Andricdef : TokenAlias<".i64", ".64">; 28220b57cec5SDimitry Andric 28230b57cec5SDimitry Andricdef : TokenAlias<".p8", ".8">; 28240b57cec5SDimitry Andricdef : TokenAlias<".p16", ".16">; 28250b57cec5SDimitry Andric 28260b57cec5SDimitry Andricdef : TokenAlias<".f32", ".32">; 28270b57cec5SDimitry Andricdef : TokenAlias<".f64", ".64">; 28280b57cec5SDimitry Andricdef : TokenAlias<".f", ".f32">; 28290b57cec5SDimitry Andricdef : TokenAlias<".d", ".f64">; 2830