summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMInstrFormats.td
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMInstrFormats.td')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrFormats.td80
1 files changed, 80 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td
index 133c3d1e451..faa33731cc6 100644
--- a/llvm/lib/Target/ARM/ARMInstrFormats.td
+++ b/llvm/lib/Target/ARM/ARMInstrFormats.td
@@ -186,6 +186,86 @@ def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
let DecoderMethod = "DecodeCCOutOperand";
}
+// VPT predicate
+
+def VPTPredNOperand : AsmOperandClass {
+ let Name = "VPTPredN";
+ let PredicateMethod = "isVPTPred";
+}
+def VPTPredROperand : AsmOperandClass {
+ let Name = "VPTPredR";
+ let PredicateMethod = "isVPTPred";
+}
+def undef_tied_input;
+
+// Operand classes for the cluster of MC operands describing a
+// VPT-predicated MVE instruction.
+//
+// There are two of these classes. Both of them have the same first
+// two options:
+//
+// $cond (an integer) indicates the instruction's predication status:
+// * ARMVCC::None means it's unpredicated
+// * ARMVCC::Then means it's in a VPT block and appears with the T suffix
+// * ARMVCC::Else means it's in a VPT block and appears with the E suffix.
+// During code generation, unpredicated and predicated instructions
+// are indicated by setting this parameter to 'None' or to 'Then'; the
+// third value 'Else' is only used for assembly and disassembly.
+//
+// $cond_reg (type VCCR) gives the input predicate register. This is
+// always either zero_reg or VPR, but needs to be modelled as an
+// explicit operand so that it can be register-allocated and spilled
+// when these operands are used in code generation).
+//
+// For 'vpred_r', there's an extra operand $inactive, which specifies
+// the vector register which will supply any lanes of the output
+// register that the predication mask prevents from being written by
+// this instruction. It's always tied to the actual output register
+// (i.e. must be allocated into the same physical reg), but again,
+// code generation will need to model it as a separate input value.
+//
+// 'vpred_n' doesn't have that extra operand: it only has $cond and
+// $cond_reg. This variant is used for any instruction that can't, or
+// doesn't want to, tie $inactive to the output register. Sometimes
+// that's because another input parameter is already tied to it (e.g.
+// instructions that both read and write their Qd register even when
+// unpredicated, either because they only partially overwrite it like
+// a narrowing integer conversion, or simply because the instruction
+// encoding doesn't have enough register fields to make the output
+// independent of all inputs). It can also be because the instruction
+// is defined to set disabled output lanes to zero rather than leaving
+// them unchanged (vector loads), or because it doesn't output a
+// vector register at all (stores, compares). In any of these
+// situations it's unnecessary to have an extra operand tied to the
+// output, and inconvenient to leave it there unused.
+
+// Base class for both kinds of vpred.
+class vpred_ops<dag extra_op, dag extra_mi> : OperandWithDefaultOps<OtherVT,
+ !con((ops (i32 0), (i32 zero_reg)), extra_op)> {
+ let PrintMethod = "printVPTPredicateOperand";
+ let OperandNamespace = "ARM";
+ let MIOperandInfo = !con((ops i32imm:$cond, VCCR:$cond_reg), extra_mi);
+
+ // For convenience, we provide a string value that can be appended
+ // to the constraints string. It's empty for vpred_n, and for
+ // vpred_r it ties the $inactive operand to the output q-register
+ // (which by convention will be called $Qd).
+ string vpred_constraint;
+}
+
+def vpred_r : vpred_ops<(ops (v4i32 undef_tied_input)), (ops MQPR:$inactive)> {
+ let ParserMatchClass = VPTPredROperand;
+ let OperandType = "OPERAND_VPRED_R";
+ let DecoderMethod = "DecodeVpredROperand";
+ let vpred_constraint = ",$Qd = $vp.inactive";
+}
+
+def vpred_n : vpred_ops<(ops), (ops)> {
+ let ParserMatchClass = VPTPredNOperand;
+ let OperandType = "OPERAND_VPRED_N";
+ let vpred_constraint = "";
+}
+
// ARM special operands for disassembly only.
//
def SetEndAsmOperand : ImmAsmOperand<0,1> {
OpenPOWER on IntegriCloud