Files
clang-p2996/llvm/test/TableGen/VarLenEncoder.td
Erik Jonsson fabcadf2eb Let M68kMCCodeEmitter set Scratch size. (#69898)
The Scratch buffer passed to getBinaryCodeForInst needs to be able to
hold any value returned by getMachineOpValue or other custom encoders.
It's better to let the caller of getBinaryCodeForInst set the size of
Scratch as it's impossible for VarLenCodeEmitterGen to know what the
smallest needed size is.

VarLenCodeEmitterGen now calculates its smallest needed Scratch bit
width based on the slice operations and zero extends Scratch if it's too
small. This only guarantees that Scratch has enough bits for the
generated code not for getMachineOpValue or custom encoders.

The smallest internal APInt representation uses one uint64_t word so
there is no point in using a smaller size.
2023-10-26 14:43:38 +02:00

102 lines
3.4 KiB
TableGen

// RUN: llvm-tblgen -gen-emitter -I %p/../../include %s | FileCheck %s
// Check if VarLenCodeEmitterGen works correctly.
include "llvm/Target/Target.td"
def ArchInstrInfo : InstrInfo { }
def Arch : Target {
let InstructionSet = ArchInstrInfo;
}
def Reg : Register<"reg">;
def RegClass : RegisterClass<"foo", [i64], 0, (add Reg)>;
def GR64 : RegisterOperand<RegClass>;
class MyMemOperand<dag sub_ops> : Operand<iPTR> {
let MIOperandInfo = sub_ops;
dag Base;
dag Extension;
}
class MyVarInst<MyMemOperand memory_op> : Instruction {
dag Inst;
let OutOperandList = (outs GR64:$dst);
let InOperandList = (ins memory_op:$src);
// Testing `ascend` and `descend`
let Inst = (ascend
(descend 0b10110111, memory_op.Base),
memory_op.Extension,
// Testing operand referencing.
(operand "$dst", 4),
// Testing operand referencing with a certain bit range.
(slice "$dst", 3, 1),
// Testing custom encoder
(operand "$dst", 2, (encoder "myCustomEncoder"))
);
}
class MemOp16<string op_name> : MyMemOperand<(ops GR64:$reg, i16imm:$offset)> {
// Testing sub-operand referencing.
let Base = (operand "$"#op_name#".reg", 8);
let Extension = (operand "$"#op_name#".offset", 16);
}
class MemOp32<string op_name> : MyMemOperand<(ops GR64:$reg, i32imm:$offset)> {
let Base = (operand "$"#op_name#".reg", 8);
// Testing variable-length instruction encoding.
let Extension = (operand "$"#op_name#".offset", 32);
}
def FOO16 : MyVarInst<MemOp16<"src">>;
def FOO32 : MyVarInst<MemOp32<"src">>;
// The fixed bits part
// CHECK: {/*NumBits*/41,
// CHECK-SAME: // FOO16
// CHECK: {/*NumBits*/57,
// CHECK-SAME: // FOO32
// CHECK: UINT64_C(46848), // FOO16
// CHECK: UINT64_C(46848), // FOO32
// CHECK-LABEL: case ::FOO16: {
// CHECK: Scratch.getBitWidth() < 16
// src.reg
// CHECK: getMachineOpValue(MI, MI.getOperand(1), /*Pos=*/0, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(8, 0), 0);
// src.offset
// CHECK: getMachineOpValue(MI, MI.getOperand(2), /*Pos=*/16, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(16, 0), 16);
// 1st dst
// CHECK: getMachineOpValue(MI, MI.getOperand(0), /*Pos=*/32, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(4, 0), 32);
// 2nd dst
// CHECK: getMachineOpValue(MI, MI.getOperand(0), /*Pos=*/36, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(3, 1), 36);
// dst w/ custom encoder
// CHECK: myCustomEncoder(MI, /*OpIdx=*/0, /*Pos=*/39, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(2, 0), 39);
// CHECK-LABEL: case ::FOO32: {
// CHECK: Scratch.getBitWidth() < 32
// src.reg
// CHECK: getMachineOpValue(MI, MI.getOperand(1), /*Pos=*/0, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(8, 0), 0);
// src.offset
// CHECK: getMachineOpValue(MI, MI.getOperand(2), /*Pos=*/16, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(32, 0), 16);
// 1st dst
// CHECK: getMachineOpValue(MI, MI.getOperand(0), /*Pos=*/48, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(4, 0), 48);
// 2nd dst
// CHECK: getMachineOpValue(MI, MI.getOperand(0), /*Pos=*/52, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(3, 1), 52);
// dst w/ custom encoder
// CHECK: myCustomEncoder(MI, /*OpIdx=*/0, /*Pos=*/55, Scratch, Fixups, STI);
// CHECK: Inst.insertBits(Scratch.extractBits(2, 0), 55);