xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/ARM/ARMInstrFormats.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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