Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ class ISAInstructionFormat {

/// ISA extension/namespace this instruction belongs to.
string extension = "";

// XLENs this instruction is valid for.
list<int> xlen = [];
}

//===----------------------------------------------------------------------===//
Expand Down
29 changes: 29 additions & 0 deletions test/Tools/circt-tblgen/rtg-instruction-list.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: circt-tblgen -gen-rtg-instruction-list -I %S/../../../include -I %S/../../../llvm/mlir/include %s | FileCheck %s

include "mlir/IR/OpBase.td"
include "mlir/IR/AttrTypeBase.td"
include "circt/Dialect/RTG/IR/RTGDialect.td"
include "circt/Dialect/RTG/IR/RTGTypes.td"
include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td"

def TestDialect : Dialect {
let name = "test";
let cppNamespace = "::test";
}

class TestOp<string mnemonic, list<Trait> traits = []> :
Op<TestDialect, mnemonic, traits>, ISAInstructionFormat;

def Test1Op : TestOp<"test1"> {
let isaAssemblyFormat = "`test1`";
}

def Test2Op : TestOp<"test2"> {
let isaAssemblyFormat = "`test2`";
}

def NonInstructionOp : Op<TestDialect, "non_instruction"> {}

// CHECK-NOT: test.non_instruction
// CHECK: test.test1,
// CHECK-NEXT: test.test2,
22 changes: 22 additions & 0 deletions test/Tools/circt-tblgen/rtg-instruction-python-wrappers.td
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,25 @@ def FilterTestOp : TestOp<"filter_test">, ISAInstructionFormat {
let extension = "extension_name";
}
#endif

#ifdef TEST_XLEN_FILTER
// RUN: circt-tblgen -gen-rtg-instruction-python-wrappers --return-val-func=test_func --xlen=128 -I %S/../../../include -I %S/../../../llvm/mlir/include %s -DTEST_XLEN_FILTER 2>&1 | FileCheck %s --check-prefix=XLEN-NO-MATCH --allow-empty
// XLEN-NO-MATCH-NOT: xlen_filter_test_both
// XLEN-NO-MATCH-NOT: xlen_filter_test_32_only

// RUN: circt-tblgen -gen-rtg-instruction-python-wrappers --return-val-func=test_func --xlen=32 -I %S/../../../include -I %S/../../../llvm/mlir/include %s -DTEST_XLEN_FILTER 2>&1 | FileCheck %s --check-prefix=XLEN-MATCH
// XLEN-MATCH-DAG: xlen_filter_test_both
// XLEN-MATCH-DAG: xlen_filter_test_32_only

// RUN: circt-tblgen -gen-rtg-instruction-python-wrappers --return-val-func=test_func --xlen=32,64 -I %S/../../../include -I %S/../../../llvm/mlir/include %s -DTEST_XLEN_FILTER 2>&1 | FileCheck %s --check-prefix=XLEN-BOTH-MATCH
// XLEN-BOTH-MATCH: xlen_filter_test_both
// XLEN-BOTH-MATCH-NOT: xlen_filter_test_32_only

def XlenFilterTestBothOp : TestOp<"xlen_filter_test_both">, ISAInstructionFormat {
let xlen = [32, 64];
}

def XlenFilterTest32OnlyOp : TestOp<"xlen_filter_test_32_only">, ISAInstructionFormat {
let xlen = [32];
}
#endif
17 changes: 17 additions & 0 deletions tools/circt-tblgen/RTGInstructionMethodsGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,26 @@ static bool genRTGInstructionMethods(const RecordKeeper &records,
return false;
}

static bool genRTGInstructionList(const RecordKeeper &records,
raw_ostream &os) {
for (const Record *opDef : records.getAllDerivedDefinitions("Op")) {
if (opDef->isSubClassOf("ISAInstructionFormat")) {
Operator op(opDef);
os << op.getOperationName() << ",\n";
}
}

return false;
}

// Generator registration for RTG instruction-related methods.
static mlir::GenRegistration
genRTGInstructionMethodsReg("gen-rtg-instruction-methods",
"Generate RTG instruction-related methods from "
"decorators",
genRTGInstructionMethods);

static mlir::GenRegistration genRTGInstructionListReg(
"gen-rtg-instruction-list",
"Generate a comma-separated list of all instructions",
genRTGInstructionList);
18 changes: 18 additions & 0 deletions tools/circt-tblgen/RTGInstructionPythonWrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ static cl::opt<std::string>
"matching extension field"),
cl::cat(rtgPythonWrapperCat));

static cl::list<int> xlen("xlen",
cl::desc("Only generate wrappers for instructions "
"valid on all specified xlens"),
cl::cat(rtgPythonWrapperCat), cl::CommaSeparated);

//===----------------------------------------------------------------------===//
// Helpers
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -370,6 +375,19 @@ static void genPythonWrapperForOp(const Operator &op, raw_ostream &os) {
return;
}

// If the xlen filter is enabled, check if the instruction is valid on all
// specified xlens.
if (!xlen.empty()) {
if (!op.getDef().getValue("xlen"))
return;
auto opXlenList = op.getDef().getValueAsListOfInts("xlen");
for (int requiredXlen : xlen) {
if (llvm::none_of(opXlenList,
[&](int64_t val) { return val == requiredXlen; }))
return;
}
}

SmallVector<OperandTypeSet> operandKinds;
SmallVector<SideEffect> operandSideEffect;
SmallVector<StringRef> operandNames;
Expand Down
Loading