summaryrefslogtreecommitdiff
path: root/test/TableGen/trydecode-emission3.td
diff options
context:
space:
mode:
authorPetr Pavlu <petr.pavlu@arm.com>2015-07-15 08:04:27 +0000
committerPetr Pavlu <petr.pavlu@arm.com>2015-07-15 08:04:27 +0000
commitd2e1e42c1a10d05067832eae990ddc1fa55c9c34 (patch)
tree8f79fd38b34f643dcb30509dea41ea3a4f92e3d4 /test/TableGen/trydecode-emission3.td
parentccadf0b1b4bcf244f85e0844c67ed50a37221422 (diff)
[TableGen] Improve decoding options for non-orthogonal instructions
When FixedLenDecoder matches an input bitpattern of form [01]+ with an instruction bitpattern of form [01?]+ (where 0/1 are static bits and ? are mixed/variable bits) it passes the input bitpattern to a specific instruction decoder method which then makes a final decision whether the bitpattern is a valid instruction or not. This means the decoder must handle all possible values of the variable bits which sometimes leads to opcode rewrites in the decoder method when the instructions are not fully orthogonal. The patch provides a way for the decoder method to say that when it returns Fail it does not necessarily mean the bitpattern is invalid, but rather that the bitpattern is definitely not an instruction that is recognized by the decoder method. The decoder can then try to match the input bitpattern with other possible instruction bitpatterns. For example, this allows to solve a situation on AArch64 where the `MSR (immediate)` instruction has form: 1101 0101 0000 0??? 0100 ???? ???1 1111 but not all values of the ? bits are allowed. The rejected values should be handled by the `extended MSR (register)` instruction: 1101 0101 000? ???? ???? ???? ???? ???? The decoder will first try to decode an input bitpattern that matches both bitpatterns as `MSR (immediate)` but currently this puts the decoder method of `MSR (immediate)` into a situation when it must be able to decode all possible values of the ? bits, i.e. it would need to rewrite the instruction to `MSR (register)` when it is not `MSR (immediate)`. The patch allows to specify that the decoder method cannot determine if the instruction is valid for all variable values. The decoder method can simply return Fail when it knows it is definitely not `MSR (immediate)`. The decoder will then backtrack the decoding and find that it can match the input bitpattern with the more generic `MSR (register)` bitpattern too. Differential Revision: http://reviews.llvm.org/D7174 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242274 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/TableGen/trydecode-emission3.td')
-rw-r--r--test/TableGen/trydecode-emission3.td44
1 files changed, 44 insertions, 0 deletions
diff --git a/test/TableGen/trydecode-emission3.td b/test/TableGen/trydecode-emission3.td
new file mode 100644
index 00000000000..ad21eefa897
--- /dev/null
+++ b/test/TableGen/trydecode-emission3.td
@@ -0,0 +1,44 @@
+// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s
+
+include "llvm/Target/Target.td"
+
+def archInstrInfo : InstrInfo { }
+
+def arch : Target {
+ let InstructionSet = archInstrInfo;
+}
+
+class TestInstruction : Instruction {
+ let Size = 1;
+ let OutOperandList = (outs);
+ let InOperandList = (ins);
+ field bits<8> Inst;
+ field bits<8> SoftFail = 0;
+}
+
+def InstA : TestInstruction {
+ let Inst = {0,0,0,0,?,?,?,?};
+ let AsmString = "InstA";
+}
+
+def InstBOp : Operand<i32> {
+ let DecoderMethod = "DecodeInstBOp";
+ let hasCompleteDecoder = 0;
+}
+
+def InstB : TestInstruction {
+ bits<2> op;
+ let Inst{7-2} = {0,0,0,0,0,0};
+ let Inst{1-0} = op;
+ let OutOperandList = (outs InstBOp:$op);
+ let AsmString = "InstB";
+}
+
+// CHECK: /* 0 */ MCD::OPC_ExtractField, 4, 4, // Inst{7-4} ...
+// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 14, 0, // Skip to: 21
+// CHECK-NEXT: /* 7 */ MCD::OPC_CheckField, 2, 2, 0, 5, 0, // Skip to: 18
+// CHECK-NEXT: /* 13 */ MCD::OPC_TryDecode, 24, 0, 0, 0, // Opcode: InstB, skip to: 18
+// CHECK-NEXT: /* 18 */ MCD::OPC_Decode, 23, 1, // Opcode: InstA
+// CHECK-NEXT: /* 21 */ MCD::OPC_Fail,
+
+// CHECK: if (DecodeInstBOp(MI, tmp, Address, Decoder) == MCDisassembler::Fail) { DecodeComplete = false; return MCDisassembler::Fail; }