// RUN: llvm-tblgen -gen-instr-info -I %p/../../include %s | FileCheck %s // Check that OpName enum and getNamedOperandIdx are as expected. include "llvm/Target/Target.td" def archInstrInfo : InstrInfo { } def arch : Target { let InstructionSet = archInstrInfo; } class InstBase : Instruction { let Namespace = "MyNamespace"; let UseNamedOperandTable = 1; let Size = 1; field bits<8> Inst; } def Reg : Register<"reg">; def RegClass : RegisterClass<"foo", [i32], 0, (add Reg)>; def OpA : Operand; def OpB : Operand; def RegOp : RegisterOperand; def InstA : InstBase { let OutOperandList = (outs OpA:$a); let InOperandList = (ins OpB:$b, i32imm:$c); } def InstB : InstBase { let OutOperandList = (outs i32imm:$d); let InOperandList = (ins unknown:$x); } def InstC : InstBase { let OutOperandList = (outs RegClass:$d); let InOperandList = (ins RegOp:$x); } // InstD has UseNamedOperandTable = 0, so it won't be handled in // getNamedOperandIdx(). def InstD : InstBase { let OutOperandList = (outs RegClass:$e); let InOperandList = (ins RegOp:$f); let UseNamedOperandTable = 0; } defm : RemapAllTargetPseudoPointerOperands; // CHECK-LABEL: #ifdef GET_INSTRINFO_OPERAND_ENUM // CHECK-NEXT: #undef GET_INSTRINFO_OPERAND_ENUM // CHECK-EMPTY: // CHECK-NEXT: namespace llvm::MyNamespace { // CHECK-EMPTY: // CHECK-NEXT: enum class OpName : uint8_t { // CHECK-NEXT: a = 0, // CHECK-NEXT: b = 1, // CHECK-NEXT: c = 2, // CHECK-NEXT: d = 3, // CHECK-NEXT: x = 4, // CHECK-NEXT: NUM_OPERAND_NAMES = 5, // CHECK-NEXT: }; // enum class OpName // CHECK-EMPTY: // CHECK-NEXT: LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName Name); // CHECK-NEXT: LLVM_READONLY OpName getOperandIdxName(uint32_t Opcode, int16_t Idx); // CHECK-EMPTY: // CHECK-NEXT: } // namespace llvm::MyNamespace // CHECK-EMPTY: // CHECK-NEXT: #endif // GET_INSTRINFO_OPERAND_ENUM // CHECK-LABEL: #ifdef GET_INSTRINFO_NAMED_OPS // CHECK-NEXT: #undef GET_INSTRINFO_NAMED_OPS // CHECK-EMPTY: // CHECK-NEXT: namespace llvm::MyNamespace { // CHECK-EMPTY: // CHECK-NEXT: LLVM_READONLY static uint8_t getInstructionIndexForOpLookup(uint32_t Opcode) { // CHECK-NEXT: static constexpr uint8_t InstructionIndex[] = { // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 1, 2, 2, 0, // CHECK-NEXT: }; // CHECK-NEXT: return InstructionIndex[Opcode]; // CHECK-NEXT: } // CHECK-NEXT: LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName Name) { // CHECK-NEXT: assert(Name != OpName::NUM_OPERAND_NAMES); // CHECK-NEXT: static constexpr int8_t OperandMap[][5] = { // CHECK-NEXT: {-1, -1, -1, -1, -1, }, // CHECK-NEXT: {0, 1, 2, -1, -1, }, // CHECK-NEXT: {-1, -1, -1, 0, 1, }, // CHECK-NEXT: }; // CHECK-NEXT: unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode); // CHECK-NEXT: return OperandMap[InstrIdx][(unsigned)Name]; // CHECK-NEXT: } // CHECK-NEXT: LLVM_READONLY OpName getOperandIdxName(uint32_t Opcode, int16_t Idx) { // CHECK-NEXT: assert(Idx >= 0 && Idx < 3); // CHECK-NEXT: static constexpr OpName OperandMap[][3] = { // CHECK-NEXT: {OpName::NUM_OPERAND_NAMES, OpName::NUM_OPERAND_NAMES, OpName::NUM_OPERAND_NAMES, }, // CHECK-NEXT: {OpName::a, OpName::b, OpName::c, }, // CHECK-NEXT: {OpName::d, OpName::x, OpName::NUM_OPERAND_NAMES, }, // CHECK-NEXT: }; // CHECK-NEXT: unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode); // CHECK-NEXT: return OperandMap[InstrIdx][(unsigned)Idx]; // CHECK-NEXT: } // CHECK-EMPTY: // CHECK-NEXT: } // namespace llvm::MyNamespace // CHECK-EMPTY: // CHECK-NEXT: #endif // GET_INSTRINFO_NAMED_OPS