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