xref: /llvm-project/llvm/test/TableGen/VarLenDecoder.td (revision f25c7751ceed2ecbe79949f859a1460170656ee0)
1// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s
2
3include "llvm/Target/Target.td"
4
5def ArchInstrInfo : InstrInfo { }
6
7def Arch : Target {
8  let InstructionSet = ArchInstrInfo;
9}
10
11def Reg : Register<"reg">;
12
13def RegClass : RegisterClass<"foo", [i64], 0, (add Reg)>;
14
15def GR64 : RegisterOperand<RegClass>;
16
17class MyMemOperand<dag sub_ops> : Operand<iPTR> {
18  let MIOperandInfo = sub_ops;
19  dag Base;
20  dag Extension;
21}
22
23def MemOp16: MyMemOperand<(ops GR64:$reg, i16imm:$offset)>;
24
25def MemOp32: MyMemOperand<(ops GR64:$reg, i32imm:$offset)>;
26
27class MyVarInst<MyMemOperand memory_op> : Instruction {
28  dag Inst;
29
30  let OutOperandList = (outs GR64:$dst);
31  let InOperandList  = (ins memory_op:$src);
32}
33
34def FOO16 : MyVarInst<MemOp16> {
35  let Inst = (ascend
36      (descend (operand "$dst", 3), 0b01000, (operand "$src.reg", 3)),
37      (slice "$src.offset", 15, 0, (decoder "myCustomDecoder"))
38  );
39}
40def FOO32 : MyVarInst<MemOp32> {
41  let Inst = (ascend
42      (descend (operand "$dst", 3), 0b01001,
43      (operand "$src.reg", 3, (decoder "myCustomDecoder"))),
44      (slice "$src.offset", 31, 16),
45      (slice "$src.offset", 15, 0)
46  );
47}
48
49// CHECK:      MCD::OPC_ExtractField, 3, 5,  // Inst{7-3} ...
50// CHECK-NEXT: MCD::OPC_FilterValue, 8, 4, 0, 0, // Skip to: 12
51// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
52// CHECK-NEXT: MCD::OPC_FilterValue, 9, 4, 0, 0, // Skip to: 21
53// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
54// CHECK-NEXT: MCD::OPC_Fail,
55
56// Instruction length table
57// CHECK: 27,
58// CHECK-NEXT: 43,
59// CHECK-NEXT: };
60
61// CHECK:      case 0:
62// CHECK-NEXT: tmp = fieldFromInstruction(insn, 8, 3);
63// CHECK-NEXT: if (!Check(S, DecodeRegClassRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
64// CHECK-NEXT: tmp = fieldFromInstruction(insn, 0, 3);
65// CHECK-NEXT: if (!Check(S, DecodeRegClassRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
66// CHECK-NEXT: tmp = fieldFromInstruction(insn, 11, 16);
67// CHECK-NEXT: if (!Check(S, myCustomDecoder(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
68// CHECK-NEXT: return S;
69// CHECK-NEXT: case 1:
70// CHECK-NEXT: tmp = fieldFromInstruction(insn, 8, 3);
71// CHECK-NEXT: if (!Check(S, DecodeRegClassRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
72// CHECK-NEXT: tmp = fieldFromInstruction(insn, 0, 3);
73// CHECK-NEXT: if (!Check(S, myCustomDecoder(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
74// CHECK-NEXT: tmp = 0x0;
75// CHECK-NEXT: insertBits(tmp, fieldFromInstruction(insn, 11, 16), 16, 16);
76// CHECK-NEXT: insertBits(tmp, fieldFromInstruction(insn, 27, 16), 0, 16);
77// CHECK-NEXT: MI.addOperand(MCOperand::createImm(tmp));
78// CHECK-NEXT: return S;
79
80// CHECK-LABEL: case MCD::OPC_ExtractField: {
81// CHECK: makeUp(insn, Start + Len);
82
83// CHECK-LABEL: case MCD::OPC_CheckField: {
84// CHECK: makeUp(insn, Start + Len);
85
86// CHECK-LABEL: case MCD::OPC_Decode: {
87// CHECK: Len = InstrLenTable[Opc];
88// CHECK-NEXT: makeUp(insn, Len);
89