xref: /llvm-project/llvm/test/TableGen/VarLenEncoder.td (revision fabcadf2eb20dcc2fa262a5a1c6752ac93544e9d)
1// RUN: llvm-tblgen -gen-emitter -I %p/../../include %s | FileCheck %s
2
3// Check if VarLenCodeEmitterGen works correctly.
4
5include "llvm/Target/Target.td"
6
7def ArchInstrInfo : InstrInfo { }
8
9def Arch : Target {
10  let InstructionSet = ArchInstrInfo;
11}
12
13def Reg : Register<"reg">;
14
15def RegClass : RegisterClass<"foo", [i64], 0, (add Reg)>;
16
17def GR64 : RegisterOperand<RegClass>;
18
19class MyMemOperand<dag sub_ops> : Operand<iPTR> {
20  let MIOperandInfo = sub_ops;
21  dag Base;
22  dag Extension;
23}
24
25class MyVarInst<MyMemOperand memory_op> : Instruction {
26  dag Inst;
27
28  let OutOperandList = (outs GR64:$dst);
29  let InOperandList  = (ins memory_op:$src);
30
31  // Testing `ascend` and `descend`
32  let Inst = (ascend
33    (descend 0b10110111, memory_op.Base),
34    memory_op.Extension,
35    // Testing operand referencing.
36    (operand "$dst", 4),
37    // Testing operand referencing with a certain bit range.
38    (slice "$dst", 3, 1),
39    // Testing custom encoder
40    (operand "$dst", 2, (encoder "myCustomEncoder"))
41  );
42}
43
44class MemOp16<string op_name> : MyMemOperand<(ops GR64:$reg, i16imm:$offset)> {
45  // Testing sub-operand referencing.
46  let Base = (operand "$"#op_name#".reg", 8);
47  let Extension = (operand "$"#op_name#".offset", 16);
48}
49
50class MemOp32<string op_name> : MyMemOperand<(ops GR64:$reg, i32imm:$offset)> {
51  let Base = (operand "$"#op_name#".reg", 8);
52  // Testing variable-length instruction encoding.
53  let Extension = (operand "$"#op_name#".offset", 32);
54}
55
56def FOO16 : MyVarInst<MemOp16<"src">>;
57def FOO32 : MyVarInst<MemOp32<"src">>;
58
59// The fixed bits part
60// CHECK: {/*NumBits*/41,
61// CHECK-SAME: // FOO16
62// CHECK: {/*NumBits*/57,
63// CHECK-SAME: // FOO32
64// CHECK: UINT64_C(46848), // FOO16
65// CHECK: UINT64_C(46848), // FOO32
66
67// CHECK-LABEL: case ::FOO16: {
68// CHECK: Scratch.getBitWidth() < 16
69// src.reg
70// CHECK: getMachineOpValue(MI, MI.getOperand(1), /*Pos=*/0, Scratch, Fixups, STI);
71// CHECK: Inst.insertBits(Scratch.extractBits(8, 0), 0);
72// src.offset
73// CHECK: getMachineOpValue(MI, MI.getOperand(2), /*Pos=*/16, Scratch, Fixups, STI);
74// CHECK: Inst.insertBits(Scratch.extractBits(16, 0), 16);
75// 1st dst
76// CHECK: getMachineOpValue(MI, MI.getOperand(0), /*Pos=*/32, Scratch, Fixups, STI);
77// CHECK: Inst.insertBits(Scratch.extractBits(4, 0), 32);
78// 2nd dst
79// CHECK: getMachineOpValue(MI, MI.getOperand(0), /*Pos=*/36, Scratch, Fixups, STI);
80// CHECK: Inst.insertBits(Scratch.extractBits(3, 1), 36);
81// dst w/ custom encoder
82// CHECK: myCustomEncoder(MI, /*OpIdx=*/0, /*Pos=*/39, Scratch, Fixups, STI);
83// CHECK: Inst.insertBits(Scratch.extractBits(2, 0), 39);
84
85// CHECK-LABEL: case ::FOO32: {
86// CHECK: Scratch.getBitWidth() < 32
87// src.reg
88// CHECK: getMachineOpValue(MI, MI.getOperand(1), /*Pos=*/0, Scratch, Fixups, STI);
89// CHECK: Inst.insertBits(Scratch.extractBits(8, 0), 0);
90// src.offset
91// CHECK: getMachineOpValue(MI, MI.getOperand(2), /*Pos=*/16, Scratch, Fixups, STI);
92// CHECK: Inst.insertBits(Scratch.extractBits(32, 0), 16);
93// 1st dst
94// CHECK: getMachineOpValue(MI, MI.getOperand(0), /*Pos=*/48, Scratch, Fixups, STI);
95// CHECK: Inst.insertBits(Scratch.extractBits(4, 0), 48);
96// 2nd dst
97// CHECK: getMachineOpValue(MI, MI.getOperand(0), /*Pos=*/52, Scratch, Fixups, STI);
98// CHECK: Inst.insertBits(Scratch.extractBits(3, 1), 52);
99// dst w/ custom encoder
100// CHECK: myCustomEncoder(MI, /*OpIdx=*/0, /*Pos=*/55, Scratch, Fixups, STI);
101// CHECK: Inst.insertBits(Scratch.extractBits(2, 0), 55);
102