
Introduce `OrFail` variants for all MCD Decoder Ops that have `NumToSKip` encoded with them. This is intended to capture the common case of jumps to the end of the decoder table which has a `OP_Fail` at the end. Using the `OrFail` variants of these ops avoid encoding the `NumToSkip` jump offset for these cases, resulting in a reduction in the size of the decoder tables (from 5 - 17%). Additionally, for the AArch64 target, the table size reduces enough to switch to using 2-byte `NumToSkip` encoding instead of existing 3-bytes, resulting in a net 30% reduction in the size of the decoder table. The total reduction in the size of the decoder tables for different targets is as follows (computed using the following command: `for i in *.inc; do echo -n ``basename $i: ``; grep "MCD::OPC_Fail," $i | awk '{sum += $2} END { print sum}'; done`) ``` Target Old Size New Size % Reduction ================================================ AArch64 153268 106987 30.20 AMDGPU 412056 340856 17.28 ARC 5061 4605 9.01 ARM 73831 60847 17.59 AVR 1306 1158 11.33 BPF 1927 1795 6.85 CSKY 8692 6922 20.36 Hexagon 41965 34759 17.17 Lanai 982 924 5.91 LoongArch 21629 20035 7.37 M68k 13461 11689 13.16 MSP430 3716 3384 8.93 Mips 31415 25771 17.97 PPC 28931 24771 14.38 RISCV 34800 28352 18.53 Sparc 7432 6236 16.09 SystemZ 32248 29716 7.85 VE 42873 36923 13.88 XCore 2316 2196 5.18 Xtensa 3443 2793 18.88 ```
55 lines
2.1 KiB
TableGen
55 lines
2.1 KiB
TableGen
// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s
|
|
// RUN: llvm-tblgen -gen-disassembler --large-decoder-table -I %p/../../include %s | FileCheck %s --check-prefix=CHECK-LARGE
|
|
|
|
// Test for OPC_ExtractField/OPC_CheckField with start bit > 255.
|
|
// These large start values may arise for architectures with long instruction
|
|
// words.
|
|
|
|
include "llvm/Target/Target.td"
|
|
|
|
def archInstrInfo : InstrInfo { }
|
|
|
|
def arch : Target {
|
|
let InstructionSet = archInstrInfo;
|
|
}
|
|
|
|
class TestInstruction : Instruction {
|
|
let Size = 64;
|
|
let OutOperandList = (outs);
|
|
let InOperandList = (ins);
|
|
field bits<512> Inst;
|
|
field bits<512> SoftFail = 0;
|
|
}
|
|
|
|
def InstA : TestInstruction {
|
|
let Inst{509-502} = {0,0,0,0,?,?,?,?};
|
|
let AsmString = "InstA";
|
|
}
|
|
|
|
def InstB : TestInstruction {
|
|
let Inst{509-502} = {0,0,0,0,0,0,?,?};
|
|
let AsmString = "InstB";
|
|
let DecoderMethod = "DecodeInstB";
|
|
let hasCompleteDecoder = 0;
|
|
}
|
|
|
|
// CHECK: /* 0 */ MCD::OPC_ExtractField, 250, 3, 4, // Inst{509-506} ...
|
|
// CHECK-NEXT: /* 4 */ MCD::OPC_FilterValueOrFail, 0,
|
|
// CHECK-NEXT: /* 6 */ MCD::OPC_CheckField, 248, 3, 2, 0, 6, 0, // Skip to: 19
|
|
// CHECK-NEXT: /* 13 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 19
|
|
// CHECK-NEXT: /* 19 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
|
|
// CHECK-NEXT: /* 23 */ MCD::OPC_Fail,
|
|
|
|
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
|
|
|
|
|
|
// CHECK-LARGE: /* 0 */ MCD::OPC_ExtractField, 250, 3, 4, // Inst{509-506} ...
|
|
// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_FilterValueOrFail, 0,
|
|
// CHECK-LARGE-NEXT: /* 6 */ MCD::OPC_CheckField, 248, 3, 2, 0, 7, 0, 0, // Skip to: 21
|
|
// CHECK-LARGE-NEXT: /* 14 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 21
|
|
// CHECK-LARGE-NEXT: /* 21 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
|
|
// CHECK-LARGE-NEXT: /* 25 */ MCD::OPC_Fail,
|
|
|
|
// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
|
|
|