[RTGTest] Switch to new immediate types (#8315)

This commit is contained in:
Martin Erhart 2025-04-01 10:12:31 +01:00 committed by GitHub
parent 1db8b4dec7
commit 908e29e58a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 132 additions and 619 deletions

View File

@ -37,39 +37,6 @@ MLIR_CAPI_EXPORTED bool rtgtestTypeIsAIntegerRegister(MlirType type);
/// Creates an RTGTest IntegerRegisterType in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestIntegerRegisterTypeGet(MlirContext ctxt);
// Immediates.
//===----------------------------------------------------------------------===//
/// If the type is an RTGTest Imm5Type.
MLIR_CAPI_EXPORTED bool rtgtestTypeIsAImm5(MlirType type);
/// Creates an RTGTest Imm5 type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestImm5TypeGet(MlirContext ctxt);
/// If the type is an RTGTest Imm12Type.
MLIR_CAPI_EXPORTED bool rtgtestTypeIsAImm12(MlirType type);
/// Creates an RTGTest Imm12 type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestImm12TypeGet(MlirContext ctxt);
/// If the type is an RTGTest Imm13Type.
MLIR_CAPI_EXPORTED bool rtgtestTypeIsAImm13(MlirType type);
/// Creates an RTGTest Imm13 type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestImm13TypeGet(MlirContext ctxt);
/// If the type is an RTGTest Imm21Type.
MLIR_CAPI_EXPORTED bool rtgtestTypeIsAImm21(MlirType type);
/// Creates an RTGTest Imm21 type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestImm21TypeGet(MlirContext ctxt);
/// If the type is an RTGTest Imm32Type.
MLIR_CAPI_EXPORTED bool rtgtestTypeIsAImm32(MlirType type);
/// Creates an RTGTest Imm32 type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestImm32TypeGet(MlirContext ctxt);
//===----------------------------------------------------------------------===//
// Attribute API.
//===----------------------------------------------------------------------===//
@ -279,59 +246,6 @@ MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT6(MlirAttribute attr);
/// Creates an RTGTest RegT6 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT6AttrGet(MlirContext ctxt);
// Immediates.
//===----------------------------------------------------------------------===//
/// If the attribute is an RTGTest Imm5Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsAImm5(MlirAttribute attr);
/// Creates an RTGTest Imm5 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm5AttrGet(MlirContext ctxt,
unsigned value);
/// Returns the value represented by the Imm5 attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestImm5AttrGetValue(MlirAttribute attr);
/// If the attribute is an RTGTest Imm12Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsAImm12(MlirAttribute attr);
/// Creates an RTGTest Imm12 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm12AttrGet(MlirContext ctxt,
unsigned value);
/// Returns the value represented by the Imm12 attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestImm12AttrGetValue(MlirAttribute attr);
/// If the attribute is an RTGTest Imm13Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsAImm13(MlirAttribute attr);
/// Creates an RTGTest Imm13 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm13AttrGet(MlirContext ctxt,
unsigned value);
/// Returns the value represented by the Imm13 attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestImm13AttrGetValue(MlirAttribute attr);
/// If the attribute is an RTGTest Imm21Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsAImm21(MlirAttribute attr);
/// Creates an RTGTest Imm21 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm21AttrGet(MlirContext ctxt,
unsigned value);
/// Returns the value represented by the Imm21 attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestImm21AttrGetValue(MlirAttribute attr);
/// If the attribute is an RTGTest Imm32Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsAImm32(MlirAttribute attr);
/// Creates an RTGTest Imm32 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm32AttrGet(MlirContext ctxt,
unsigned value);
/// Returns the value represented by the Imm32 attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestImm32AttrGetValue(MlirAttribute attr);
#ifdef __cplusplus
}
#endif

View File

@ -14,6 +14,16 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributes.h"
namespace circt {
namespace rtg {
namespace detail {
struct ImmediateAttrStorage;
} // namespace detail
} // namespace rtg
} // namespace circt
#define GET_ATTRDEF_CLASSES
#include "circt/Dialect/RTG/IR/RTGAttributes.h.inc"

View File

@ -21,43 +21,6 @@ include "mlir/IR/Interfaces.td"
class RTGAttrDef<string name, list<Trait> traits = []>
: AttrDef<RTGDialect, name, traits>;
class ImmediateAttrBase<int width> : RTGAttrDef<"Imm" # width, [
DeclareAttrInterfaceMethods<TypedAttrInterface>,
]> {
let summary = "represents a " # width # "-bit immediate value";
let mnemonic = "imm" # width;
let parameters = (ins "uint32_t":$value);
let assemblyFormat = "`<` $value `>`";
let extraClassDeclaration = [{
llvm::APInt getAPInt() const {
return llvm::APInt(}] # width # [{, getValue());
}
}];
let extraClassDefinition = [{
Type $cppClass::getType() const {
return Imm}] # width # [{Type::get(getContext());
}
LogicalResult $cppClass::verify(
::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError,
uint32_t value) {
if (32 - llvm::countl_zero(value) > }] # width # [{)
return emitError() << "cannot represent " << value << " with }] #
width # [{ bits";
return success();
}
}];
let genVerifyDecl = 1;
}
def DefaultContextAttr : RTGAttrDef<"DefaultContext", [
DeclareAttrInterfaceMethods<ContextResourceAttrInterface>,
]> {
@ -94,6 +57,7 @@ def ImmediateAttr : RTGISAAttrDef<"Immediate", [
let parameters = (ins "llvm::APInt":$value);
let hasCustomAssemblyFormat = true;
let genStorageClass = false;
}
#endif // CIRCT_DIALECT_RTG_IR_RTGATTRIBUTES_TD

View File

@ -157,9 +157,4 @@ class ImmediateOfWidth<int width> : Type<
"a " # width # "-bit immediate">,
BuildableType<"::circt::rtg::ImmediateType::get($_builder.getContext(), " # width # ")">;
class ImmTypeBase<int width> : TypeDef<RTGDialect, "Imm" # width, []> {
let summary = "represents a " # width # "-bit immediate";
let mnemonic = "imm" # width;
}
#endif // CIRCT_DIALECT_RTG_IR_RTGTYPES_TD

View File

@ -36,14 +36,6 @@ def CPUAttr : RTGTestAttrDef<"CPU", [ContextResourceAttrInterface]> {
}];
}
let dialect = RTGTestDialect in {
def Imm5 : ImmediateAttrBase<5>;
def Imm12 : ImmediateAttrBase<12>;
def Imm13 : ImmediateAttrBase<13>;
def Imm21 : ImmediateAttrBase<21>;
def Imm32 : ImmediateAttrBase<32>;
}
class IntegerRegisterAttrBase<string cppName, string name, int classIndex>
: RTGTestAttrDef<cppName, [RegisterAttrInterface]> {

View File

@ -13,6 +13,7 @@
#ifndef CIRCT_DIALECT_RTGTEST_IR_RTGTESTOPS_H
#define CIRCT_DIALECT_RTGTEST_IR_RTGTESTOPS_H
#include "circt/Dialect/RTG/IR/RTGAttributes.h"
#include "circt/Dialect/RTG/IR/RTGISAAssemblyOpInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGOpInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGOps.h"

View File

@ -21,40 +21,6 @@ class RTGTestOp<string mnemonic, list<Trait> traits = []> :
Op<RTGTestDialect, mnemonic, traits>;
def CPUDeclOp : RTGTestOp<"cpu_decl", [
Pure,
ConstantLike,
ContextResourceDefining,
FirstAttrDerivedResultType,
]> {
let summary = "declare a CPU";
let description = [{
This operation is used to test the `ContextResourceAttrInterface` and
`ContextResourceTypeInterface` passes taking advantage of it.
}];
let arguments = (ins CPUAttr:$id);
let results = (outs CPUType:$cpu);
let assemblyFormat = "$id attr-dict";
let hasFolder = 1;
}
def ImmediateOp : RTGTestOp<"immediate", [
Pure,
ConstantLike,
FirstAttrDerivedResultType,
DeclareOpInterfaceMethods<InferTypeOpInterface>,
]> {
let summary = "declare an immediate value";
let arguments = (ins AnyAttrOf<[Imm5, Imm12, Imm13, Imm21, Imm32]>:$imm);
let results = (outs AnyType:$result);
let assemblyFormat = "$imm attr-dict";
let hasFolder = 1;
}
def ConstantTestOp : RTGTestOp<"constant_test", [
Pure, ConstantLike,
]> {
@ -72,14 +38,14 @@ class InstFormatIOpBase<string mnemonic, int opcode7, int funct3>
let arguments = (ins IntegerRegisterType:$rd,
IntegerRegisterType:$rs,
Imm12Type:$imm);
ImmediateOfWidth<12>:$imm);
let assemblyFormat = "$rd `,` $rs `,` $imm attr-dict";
let extraClassDefinition = [{
void $cppClass::printInstructionBinary(llvm::raw_ostream &os,
FoldAdaptor adaptor) {
auto binary = cast<Imm12Attr>(adaptor.getImm()).getAPInt()
auto binary = cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue()
.concat(APInt(5, cast<rtg::RegisterAttrInterface>(
adaptor.getRs()).getClassIndex()))
.concat(APInt(3, }] # funct3 # [{))
@ -99,7 +65,7 @@ class InstFormatIOpBase<string mnemonic, int opcode7, int funct3>
.getRegisterAssembly()
<< ", "
// The assembler only accepts signed values here.
<< cast<Imm12Attr>(adaptor.getImm()).getAPInt().getSExtValue()
<< cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue()
<< "("
<< cast<rtg::RegisterAttrInterface>(adaptor.getRs())
.getRegisterAssembly()
@ -137,7 +103,7 @@ class InstFormatBOpBase<string mnemonic, int opcode7, int funct3>
let arguments = (ins IntegerRegisterType:$rs1,
IntegerRegisterType:$rs2,
AnyTypeOf<[Imm13Type, LabelType]>:$imm);
AnyTypeOf<[ImmediateOfWidth<13>, LabelType]>:$imm);
let assemblyFormat = [{
$rs1 `,` $rs2 `,` $imm `:` qualified(type($imm)) attr-dict
@ -146,10 +112,10 @@ class InstFormatBOpBase<string mnemonic, int opcode7, int funct3>
let extraClassDefinition = [{
void $cppClass::printInstructionBinary(llvm::raw_ostream &os,
FoldAdaptor adaptor) {
assert (isa<Imm13Attr>(adaptor.getImm()) &&
assert (isa<rtg::ImmediateAttr>(adaptor.getImm()) &&
"binary of labels not supported");
auto imm = cast<Imm13Attr>(adaptor.getImm()).getAPInt();
auto imm = cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue();
auto rs1 = cast<rtg::RegisterAttrInterface>(adaptor.getRs1());
auto rs2 = cast<rtg::RegisterAttrInterface>(adaptor.getRs2());
@ -184,7 +150,7 @@ class InstFormatBOpBase<string mnemonic, int opcode7, int funct3>
}
// The assembler is fine with unsigned and signed values here.
os << cast<Imm13Attr>(adaptor.getImm()).getValue();
cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue().print(os, /*isSigned=*/false);
}
}];
}
@ -238,7 +204,7 @@ class InstFormatSOpBase<string mnemonic, int opcode7, int funct3>
let arguments = (ins IntegerRegisterType:$rs1,
IntegerRegisterType:$rs2,
Imm12Type:$imm);
ImmediateOfWidth<12>:$imm);
let assemblyFormat = "$rs1 `,` $rs2 `,` $imm attr-dict";
@ -247,7 +213,7 @@ class InstFormatSOpBase<string mnemonic, int opcode7, int funct3>
FoldAdaptor adaptor) {
auto rs1 = cast<rtg::RegisterAttrInterface>(adaptor.getRs1());
auto rs2 = cast<rtg::RegisterAttrInterface>(adaptor.getRs2());
auto imm = cast<Imm12Attr>(adaptor.getImm()).getAPInt();
auto imm = cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue();
auto binary = imm.extractBits(7, 5)
.concat(llvm::APInt(5, rs2.getClassIndex()))
@ -269,7 +235,7 @@ class InstFormatSOpBase<string mnemonic, int opcode7, int funct3>
.getRegisterAssembly()
<< ", "
// The assembler only accepts signed values here.
<< cast<Imm12Attr>(adaptor.getImm()).getAPInt().getSExtValue()
<< cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue()
<< "("
<< cast<rtg::RegisterAttrInterface>(adaptor.getRs2())
.getRegisterAssembly()
@ -282,18 +248,18 @@ class InstFormatUOpBase<string mnemonic, int opcode7>
: RTGTestOp<"rv32i." # mnemonic, [InstructionOpAdaptor]> {
let arguments = (ins IntegerRegisterType:$rd,
AnyTypeOf<[Imm32Type, LabelType]>:$imm);
AnyTypeOf<[ImmediateOfWidth<32>, LabelType]>:$imm);
let assemblyFormat = "$rd `,` $imm `:` type($imm) attr-dict";
let extraClassDefinition = [{
void $cppClass::printInstructionBinary(llvm::raw_ostream &os,
FoldAdaptor adaptor) {
assert (isa<Imm32Attr>(adaptor.getImm()) &&
assert (isa<rtg::ImmediateAttr>(adaptor.getImm()) &&
"binary of labels not supported");
auto rd = cast<rtg::RegisterAttrInterface>(adaptor.getRd());
auto imm = cast<Imm32Attr>(adaptor.getImm()).getAPInt();
auto imm = cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue();
auto binary = imm.extractBits(20, 12)
.concat(llvm::APInt(5, rd.getClassIndex()))
@ -318,7 +284,7 @@ class InstFormatUOpBase<string mnemonic, int opcode7>
}
// The assembler wants an unsigned value here.
os << cast<Imm32Attr>(adaptor.getImm()).getValue();
cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue().print(os, /*isSigned=*/false);
}
}];
}
@ -327,18 +293,18 @@ class InstFormatJOpBase<string mnemonic, int opcode7>
: RTGTestOp<"rv32i." # mnemonic, [InstructionOpAdaptor]> {
let arguments = (ins IntegerRegisterType:$rd,
AnyTypeOf<[Imm21Type, LabelType]>:$imm);
AnyTypeOf<[ImmediateOfWidth<21>, LabelType]>:$imm);
let assemblyFormat = "$rd `,` $imm `:` type($imm) attr-dict";
let extraClassDefinition = [{
void $cppClass::printInstructionBinary(llvm::raw_ostream &os,
FoldAdaptor adaptor) {
assert (isa<Imm21Attr>(adaptor.getImm()) &&
assert (isa<rtg::ImmediateAttr>(adaptor.getImm()) &&
"binary of labels not supported");
auto rd = cast<rtg::RegisterAttrInterface>(adaptor.getRd());
auto imm = cast<Imm21Attr>(adaptor.getImm()).getAPInt();
auto imm = cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue();
auto binary = imm.extractBits(1, 20)
.concat(imm.extractBits(10, 1))
@ -366,7 +332,7 @@ class InstFormatJOpBase<string mnemonic, int opcode7>
}
// The assembler is fine with signed and unsigned values here.
os << cast<Imm21Attr>(adaptor.getImm()).getAPInt().getSExtValue();
os << cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue();
}
}];
}
@ -376,7 +342,7 @@ class InstFormatIAOpBase<string mnemonic, int opcode7, int funct3>
let arguments = (ins IntegerRegisterType:$rd,
IntegerRegisterType:$rs,
Imm12Type:$imm);
ImmediateOfWidth<12>:$imm);
let assemblyFormat = "$rd `,` $rs `,` $imm attr-dict";
@ -385,7 +351,7 @@ class InstFormatIAOpBase<string mnemonic, int opcode7, int funct3>
FoldAdaptor adaptor) {
auto rd = cast<rtg::RegisterAttrInterface>(adaptor.getRd());
auto rs = cast<rtg::RegisterAttrInterface>(adaptor.getRs());
auto imm = cast<Imm12Attr>(adaptor.getImm()).getAPInt();
auto imm = cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue();
auto binary = imm
.concat(llvm::APInt(5, rs.getClassIndex()))
@ -409,7 +375,7 @@ class InstFormatIAOpBase<string mnemonic, int opcode7, int funct3>
.getRegisterAssembly()
<< ", "
// The assembler only accepts signed values here.
<< cast<Imm12Attr>(adaptor.getImm()).getAPInt().getSExtValue();
<< cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue();
}
}];
}
@ -420,7 +386,7 @@ class InstFormatShiftOpBase<string mnemonic, int opcode7,
let arguments = (ins IntegerRegisterType:$rd,
IntegerRegisterType:$rs,
Imm5Type:$imm);
ImmediateOfWidth<5>:$imm);
let assemblyFormat = "$rd `,` $rs `,` $imm attr-dict";
@ -429,7 +395,7 @@ class InstFormatShiftOpBase<string mnemonic, int opcode7,
FoldAdaptor adaptor) {
auto rd = cast<rtg::RegisterAttrInterface>(adaptor.getRd());
auto rs = cast<rtg::RegisterAttrInterface>(adaptor.getRs());
auto imm = cast<Imm5Attr>(adaptor.getImm()).getAPInt();
auto imm = cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue();
auto binary = llvm::APInt(7, }] # funct7 # [{)
.concat(imm.extractBits(5, 0))
@ -452,9 +418,9 @@ class InstFormatShiftOpBase<string mnemonic, int opcode7,
<< ", "
<< cast<rtg::RegisterAttrInterface>(adaptor.getRs())
.getRegisterAssembly()
<< ", "
// The assembler only accepts an unsigned value here.
<< cast<Imm5Attr>(adaptor.getImm()).getValue();
<< ", ";
// The assembler only accepts an unsigned value here.
cast<rtg::ImmediateAttr>(adaptor.getImm()).getValue().print(os, /*isSigned=*/false);
}
}];
}

View File

@ -34,14 +34,6 @@ def CPUType : RTGTestTypeDef<"CPU", [ContextResourceTypeInterface]> {
let assemblyFormat = "";
}
let dialect = RTGTestDialect in {
def Imm5Type : ImmTypeBase<5>;
def Imm12Type : ImmTypeBase<12>;
def Imm13Type : ImmTypeBase<13>;
def Imm21Type : ImmTypeBase<21>;
def Imm32Type : ImmTypeBase<32>;
}
def IntegerRegisterType : TypeDef<RTGTestDialect, "IntegerRegister", [
RegisterTypeInterface
]> {

View File

@ -20,16 +20,16 @@ with Context() as ctx, Location.unknown():
targetBlock = Block.create_at_start(target.bodyRegion, [])
with InsertionPoint(targetBlock):
cpuAttr = rtgtest.CPUAttr.get(0)
cpu0 = rtgtest.CPUDeclOp(cpuAttr)
cpu1 = rtgtest.CPUDeclOp(rtgtest.CPUAttr.get(cpuAttr.id + 1))
cpu0 = rtg.ConstantOp(cpuAttr)
cpu1 = rtg.ConstantOp(rtgtest.CPUAttr.get(cpuAttr.id + 1))
rtg.YieldOp([cpu0, cpu1])
test = rtg.TestOp('test_name', TypeAttr.get(dictTy))
Block.create_at_start(test.bodyRegion, [cpuTy, cpuTy])
# CHECK: rtg.target @target_name : !rtg.dict<cpu0: !rtgtest.cpu, cpu1: !rtgtest.cpu> {
# CHECK: [[V0:%.+]] = rtgtest.cpu_decl <0>
# CHECK: [[V1:%.+]] = rtgtest.cpu_decl <1>
# CHECK: [[V0:%.+]] = rtg.constant #rtgtest.cpu<0>
# CHECK: [[V1:%.+]] = rtg.constant #rtgtest.cpu<1>
# CHECK: rtg.yield [[V0]], [[V1]] : !rtgtest.cpu, !rtgtest.cpu
# CHECK: }
# CHECK: rtg.test @test_name(cpu0 = %cpu0: !rtgtest.cpu, cpu1 = %cpu1: !rtgtest.cpu) {
@ -180,23 +180,6 @@ with Context() as ctx, Location.unknown():
print(m)
with Context() as ctx, Location.unknown():
circt.register_dialects(ctx)
m = Module.create()
with InsertionPoint(m.body):
# CHECK: rtgtest.immediate #rtgtest.imm5<3> : !rtgtest.imm5
rtgtest.ImmediateOp(rtgtest.Imm5Attr.get(3))
# CHECK: rtgtest.immediate #rtgtest.imm12<3> : !rtgtest.imm12
rtgtest.ImmediateOp(rtgtest.Imm12Attr.get(3))
# CHECK: rtgtest.immediate #rtgtest.imm13<3> : !rtgtest.imm13
rtgtest.ImmediateOp(rtgtest.Imm13Attr.get(3))
# CHECK: rtgtest.immediate #rtgtest.imm21<3> : !rtgtest.imm21
rtgtest.ImmediateOp(rtgtest.Imm21Attr.get(3))
# CHECK: rtgtest.immediate #rtgtest.imm32<3> : !rtgtest.imm32
rtgtest.ImmediateOp(rtgtest.Imm32Attr.get(3))
print(m)
with Context() as ctx, Location.unknown():
circt.register_dialects(ctx)
m = Module.create()

View File

@ -38,46 +38,6 @@ void circt::python::populateDialectRTGTestSubmodule(nb::module_ &m) {
},
nb::arg("self"), nb::arg("ctxt") = nullptr);
mlir_type_subclass(m, "Imm5Type", rtgtestTypeIsAImm5)
.def_classmethod(
"get",
[](nb::object cls, MlirContext ctxt) {
return cls(rtgtestImm5TypeGet(ctxt));
},
nb::arg("self"), nb::arg("ctxt") = nullptr);
mlir_type_subclass(m, "Imm12Type", rtgtestTypeIsAImm12)
.def_classmethod(
"get",
[](nb::object cls, MlirContext ctxt) {
return cls(rtgtestImm12TypeGet(ctxt));
},
nb::arg("self"), nb::arg("ctxt") = nullptr);
mlir_type_subclass(m, "Imm13Type", rtgtestTypeIsAImm13)
.def_classmethod(
"get",
[](nb::object cls, MlirContext ctxt) {
return cls(rtgtestImm13TypeGet(ctxt));
},
nb::arg("self"), nb::arg("ctxt") = nullptr);
mlir_type_subclass(m, "Imm21Type", rtgtestTypeIsAImm21)
.def_classmethod(
"get",
[](nb::object cls, MlirContext ctxt) {
return cls(rtgtestImm21TypeGet(ctxt));
},
nb::arg("self"), nb::arg("ctxt") = nullptr);
mlir_type_subclass(m, "Imm32Type", rtgtestTypeIsAImm32)
.def_classmethod(
"get",
[](nb::object cls, MlirContext ctxt) {
return cls(rtgtestImm32TypeGet(ctxt));
},
nb::arg("self"), nb::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "CPUAttr", rtgtestAttrIsACPU)
.def_classmethod(
"get",
@ -343,59 +303,4 @@ void circt::python::populateDialectRTGTestSubmodule(nb::module_ &m) {
return cls(rtgtestRegT6AttrGet(ctxt));
},
nb::arg("self"), nb::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "Imm5Attr", rtgtestAttrIsAImm5)
.def_classmethod(
"get",
[](nb::object cls, unsigned value, MlirContext ctxt) {
return cls(rtgtestImm5AttrGet(ctxt, value));
},
nb::arg("self"), nb::arg("value"), nb::arg("ctxt") = nullptr)
.def_property_readonly("value", [](MlirAttribute self) {
return rtgtestImm5AttrGetValue(self);
});
mlir_attribute_subclass(m, "Imm12Attr", rtgtestAttrIsAImm12)
.def_classmethod(
"get",
[](nb::object cls, unsigned value, MlirContext ctxt) {
return cls(rtgtestImm12AttrGet(ctxt, value));
},
nb::arg("self"), nb::arg("value"), nb::arg("ctxt") = nullptr)
.def_property_readonly("value", [](MlirAttribute self) {
return rtgtestImm12AttrGetValue(self);
});
mlir_attribute_subclass(m, "Imm13Attr", rtgtestAttrIsAImm13)
.def_classmethod(
"get",
[](nb::object cls, unsigned value, MlirContext ctxt) {
return cls(rtgtestImm13AttrGet(ctxt, value));
},
nb::arg("self"), nb::arg("value"), nb::arg("ctxt") = nullptr)
.def_property_readonly("value", [](MlirAttribute self) {
return rtgtestImm13AttrGetValue(self);
});
mlir_attribute_subclass(m, "Imm21Attr", rtgtestAttrIsAImm21)
.def_classmethod(
"get",
[](nb::object cls, unsigned value, MlirContext ctxt) {
return cls(rtgtestImm21AttrGet(ctxt, value));
},
nb::arg("self"), nb::arg("value"), nb::arg("ctxt") = nullptr)
.def_property_readonly("value", [](MlirAttribute self) {
return rtgtestImm21AttrGetValue(self);
});
mlir_attribute_subclass(m, "Imm32Attr", rtgtestAttrIsAImm32)
.def_classmethod(
"get",
[](nb::object cls, unsigned value, MlirContext ctxt) {
return cls(rtgtestImm32AttrGet(ctxt, value));
},
nb::arg("self"), nb::arg("value"), nb::arg("ctxt") = nullptr)
.def_property_readonly("value", [](MlirAttribute self) {
return rtgtestImm32AttrGetValue(self);
});
}

View File

@ -40,39 +40,6 @@ MlirType rtgtestIntegerRegisterTypeGet(MlirContext ctxt) {
return wrap(IntegerRegisterType::get(unwrap(ctxt)));
}
// Immediates.
//===----------------------------------------------------------------------===//
bool rtgtestTypeIsAImm5(MlirType type) { return isa<Imm5Type>(unwrap(type)); }
MlirType rtgtestImm5TypeGet(MlirContext ctxt) {
return wrap(Imm5Type::get(unwrap(ctxt)));
}
bool rtgtestTypeIsAImm12(MlirType type) { return isa<Imm12Type>(unwrap(type)); }
MlirType rtgtestImm12TypeGet(MlirContext ctxt) {
return wrap(Imm12Type::get(unwrap(ctxt)));
}
bool rtgtestTypeIsAImm13(MlirType type) { return isa<Imm13Type>(unwrap(type)); }
MlirType rtgtestImm13TypeGet(MlirContext ctxt) {
return wrap(Imm13Type::get(unwrap(ctxt)));
}
bool rtgtestTypeIsAImm21(MlirType type) { return isa<Imm21Type>(unwrap(type)); }
MlirType rtgtestImm21TypeGet(MlirContext ctxt) {
return wrap(Imm21Type::get(unwrap(ctxt)));
}
bool rtgtestTypeIsAImm32(MlirType type) { return isa<Imm32Type>(unwrap(type)); }
MlirType rtgtestImm32TypeGet(MlirContext ctxt) {
return wrap(Imm32Type::get(unwrap(ctxt)));
}
//===----------------------------------------------------------------------===//
// Attribute API.
//===----------------------------------------------------------------------===//
@ -347,66 +314,3 @@ bool rtgtestAttrIsARegT6(MlirAttribute attr) {
MlirAttribute rtgtestRegT6AttrGet(MlirContext ctxt) {
return wrap(RegT6Attr::get(unwrap(ctxt)));
}
// Immediates.
//===----------------------------------------------------------------------===//
bool rtgtestAttrIsAImm5(MlirAttribute attr) {
return isa<Imm5Attr>(unwrap(attr));
}
MlirAttribute rtgtestImm5AttrGet(MlirContext ctxt, unsigned value) {
return wrap(Imm5Attr::get(unwrap(ctxt), value));
}
unsigned rtgtestImm5AttrGetValue(MlirAttribute attr) {
return cast<Imm5Attr>(unwrap(attr)).getValue();
}
bool rtgtestAttrIsAImm12(MlirAttribute attr) {
return isa<Imm12Attr>(unwrap(attr));
}
MlirAttribute rtgtestImm12AttrGet(MlirContext ctxt, unsigned value) {
return wrap(Imm12Attr::get(unwrap(ctxt), value));
}
unsigned rtgtestImm12AttrGetValue(MlirAttribute attr) {
return cast<Imm12Attr>(unwrap(attr)).getValue();
}
bool rtgtestAttrIsAImm13(MlirAttribute attr) {
return isa<Imm13Attr>(unwrap(attr));
}
MlirAttribute rtgtestImm13AttrGet(MlirContext ctxt, unsigned value) {
return wrap(Imm13Attr::get(unwrap(ctxt), value));
}
unsigned rtgtestImm13AttrGetValue(MlirAttribute attr) {
return cast<Imm13Attr>(unwrap(attr)).getValue();
}
bool rtgtestAttrIsAImm21(MlirAttribute attr) {
return isa<Imm21Attr>(unwrap(attr));
}
MlirAttribute rtgtestImm21AttrGet(MlirContext ctxt, unsigned value) {
return wrap(Imm21Attr::get(unwrap(ctxt), value));
}
unsigned rtgtestImm21AttrGetValue(MlirAttribute attr) {
return cast<Imm21Attr>(unwrap(attr)).getValue();
}
bool rtgtestAttrIsAImm32(MlirAttribute attr) {
return isa<Imm32Attr>(unwrap(attr));
}
MlirAttribute rtgtestImm32AttrGet(MlirContext ctxt, unsigned value) {
return wrap(Imm32Attr::get(unwrap(ctxt), value));
}
unsigned rtgtestImm32AttrGetValue(MlirAttribute attr) {
return cast<Imm32Attr>(unwrap(attr)).getValue();
}

View File

@ -19,10 +19,46 @@ using namespace rtg;
// ImmediateAttr
//===----------------------------------------------------------------------===//
namespace circt {
namespace rtg {
namespace detail {
struct ImmediateAttrStorage : public mlir::AttributeStorage {
using KeyTy = APInt;
ImmediateAttrStorage(APInt value) : value(std::move(value)) {}
KeyTy getAsKey() const { return value; }
// NOTE: the implementation of this operator is the reason we need to define
// the storage manually. The auto-generated version would just do the direct
// equality check of the APInt, but that asserts the bitwidth of both to be
// the same, leading to a crash. This implementation, therefore, checks for
// matching bit-width beforehand.
bool operator==(const KeyTy &key) const {
return (value.getBitWidth() == key.getBitWidth() && value == key);
}
static llvm::hash_code hashKey(const KeyTy &key) {
return llvm::hash_value(key);
}
static ImmediateAttrStorage *
construct(mlir::AttributeStorageAllocator &allocator, KeyTy &&key) {
return new (allocator.allocate<ImmediateAttrStorage>())
ImmediateAttrStorage(std::move(key));
}
APInt value;
};
} // namespace detail
} // namespace rtg
} // namespace circt
Type ImmediateAttr::getType() const {
return ImmediateType::get(getContext(), getValue().getBitWidth());
}
APInt ImmediateAttr::getValue() const { return getImpl()->value; }
Attribute ImmediateAttr::parse(AsmParser &odsParser, Type odsType) {
llvm::SMLoc loc = odsParser.getCurrentLocation();

View File

@ -49,7 +49,7 @@ Operation *RTGTestDialect::materializeConstant(OpBuilder &builder,
return TypeSwitch<Attribute, Operation *>(value)
.Case<CPUAttr>([&](auto attr) -> Operation * {
if (isa<CPUType>(type))
return builder.create<CPUDeclOp>(loc, type, attr);
return builder.create<rtg::ConstantOp>(loc, attr);
return nullptr;
})
.Case<rtg::RegisterAttrInterface>([&](auto attr) -> Operation * {
@ -57,8 +57,6 @@ Operation *RTGTestDialect::materializeConstant(OpBuilder &builder,
return builder.create<rtg::FixedRegisterOp>(loc, attr);
return nullptr;
})
.Case<Imm5Attr, Imm12Attr, Imm13Attr, Imm21Attr, Imm32Attr>(
[&](auto attr) { return builder.create<ImmediateOp>(loc, attr); })
.Default([](auto attr) { return nullptr; });
}

View File

@ -17,29 +17,6 @@
using namespace circt;
using namespace rtgtest;
//===----------------------------------------------------------------------===//
// CPUDeclOp
//===----------------------------------------------------------------------===//
mlir::OpFoldResult CPUDeclOp::fold(FoldAdaptor adaptor) { return getId(); }
//===----------------------------------------------------------------------===//
// ImmediateOp
//===----------------------------------------------------------------------===//
mlir::OpFoldResult ImmediateOp::fold(FoldAdaptor adaptor) {
return getImmAttr();
}
LogicalResult ImmediateOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attributes, OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &inferredReturnTypes) {
inferredReturnTypes.push_back(
cast<TypedAttr>(properties.as<Properties *>()->getImm()).getType());
return success();
}
//===----------------------------------------------------------------------===//
// ConstantTestOp
//===----------------------------------------------------------------------===//

View File

@ -270,77 +270,6 @@ static void testRegisters(MlirContext ctx) {
}
}
static void testImmediates(MlirContext ctx) {
MlirType imm5Type = rtgtestImm5TypeGet(ctx);
// CHECK: is_imm5
fprintf(stderr, rtgtestTypeIsAImm5(imm5Type) ? "is_imm5\n" : "isnot_imm5\n");
// CHECK: !rtgtest.imm5
mlirTypeDump(imm5Type);
MlirType imm12Type = rtgtestImm12TypeGet(ctx);
// CHECK: is_imm12
fprintf(stderr,
rtgtestTypeIsAImm12(imm12Type) ? "is_imm12\n" : "isnot_imm12\n");
// CHECK: !rtgtest.imm12
mlirTypeDump(imm12Type);
MlirType imm13Type = rtgtestImm13TypeGet(ctx);
// CHECK: is_imm13
fprintf(stderr,
rtgtestTypeIsAImm13(imm13Type) ? "is_imm13\n" : "isnot_imm13\n");
// CHECK: !rtgtest.imm13
mlirTypeDump(imm13Type);
MlirType imm21Type = rtgtestImm21TypeGet(ctx);
// CHECK: is_imm21
fprintf(stderr,
rtgtestTypeIsAImm21(imm21Type) ? "is_imm21\n" : "isnot_imm21\n");
// CHECK: !rtgtest.imm21
mlirTypeDump(imm21Type);
MlirType imm32Type = rtgtestImm32TypeGet(ctx);
// CHECK: is_imm32
fprintf(stderr,
rtgtestTypeIsAImm32(imm32Type) ? "is_imm32\n" : "isnot_imm32\n");
// CHECK: !rtgtest.imm32
mlirTypeDump(imm32Type);
MlirAttribute imm5Attr = rtgtestImm5AttrGet(ctx, 3);
// CHECK: is_imm5
fprintf(stderr, rtgtestAttrIsAImm5(imm5Attr) ? "is_imm5\n" : "isnot_imm5\n");
// CHECK: 3
fprintf(stderr, "%u\n", rtgtestImm5AttrGetValue(imm5Attr));
// CHECK: #rtgtest.imm5<3>
mlirAttributeDump(imm5Attr);
MlirAttribute imm12Attr = rtgtestImm12AttrGet(ctx, 3);
// CHECK: is_imm12
fprintf(stderr,
rtgtestAttrIsAImm12(imm12Attr) ? "is_imm12\n" : "isnot_imm12\n");
// CHECK: 3
fprintf(stderr, "%u\n", rtgtestImm12AttrGetValue(imm12Attr));
// CHECK: #rtgtest.imm12<3>
mlirAttributeDump(imm12Attr);
MlirAttribute imm21Attr = rtgtestImm21AttrGet(ctx, 3);
// CHECK: is_imm21
fprintf(stderr,
rtgtestAttrIsAImm21(imm21Attr) ? "is_imm21\n" : "isnot_imm21\n");
// CHECK: 3
fprintf(stderr, "%u\n", rtgtestImm21AttrGetValue(imm21Attr));
// CHECK: #rtgtest.imm21<3>
mlirAttributeDump(imm21Attr);
MlirAttribute imm32Attr = rtgtestImm32AttrGet(ctx, 3);
// CHECK: is_imm32
fprintf(stderr,
rtgtestAttrIsAImm32(imm32Attr) ? "is_imm32\n" : "isnot_imm32\n");
// CHECK: 3
fprintf(stderr, "%u\n", rtgtestImm32AttrGetValue(imm32Attr));
// CHECK: #rtgtest.imm32<3>
mlirAttributeDump(imm32Attr);
}
int main(int argc, char **argv) {
MlirContext ctx = mlirContextCreate();
mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtgtest__(), ctx);
@ -349,7 +278,6 @@ int main(int argc, char **argv) {
testIntegerRegisterType(ctx);
testCPUAttr(ctx);
testRegisters(ctx);
testImmediates(ctx);
mlirContextDestroy(ctx);

View File

@ -314,11 +314,11 @@ rtg.test @scfFor() {
rtg.test @fixedRegisters() {
// CHECK-NEXT: [[RA:%.+]] = rtg.fixed_reg #rtgtest.ra
// CHECK-NEXT: [[SP:%.+]] = rtg.fixed_reg #rtgtest.sp
// CHECK-NEXT: [[IMM:%.+]] = rtgtest.immediate #rtgtest.imm12<0>
// CHECK-NEXT: [[IMM:%.+]] = rtg.constant #rtg.isa.immediate<12, 0>
// CHECK-NEXT: rtgtest.rv32i.jalr [[RA]], [[SP]], [[IMM]]
%ra = rtg.fixed_reg #rtgtest.ra
%sp = rtg.fixed_reg #rtgtest.sp
%imm = rtgtest.immediate #rtgtest.imm12<0>
%imm = rtg.constant #rtg.isa.immediate<12, 0>
rtgtest.rv32i.jalr %ra, %sp, %imm
}
@ -326,12 +326,12 @@ rtg.test @fixedRegisters() {
rtg.test @virtualRegisters() {
// CHECK-NEXT: [[R0:%.+]] = rtg.virtual_reg [#rtgtest.a0 : !rtgtest.ireg, #rtgtest.a1 : !rtgtest.ireg]
// CHECK-NEXT: [[R1:%.+]] = rtg.virtual_reg [#rtgtest.s0 : !rtgtest.ireg, #rtgtest.s1 : !rtgtest.ireg]
// CHECK-NEXT: [[IMM:%.+]] = rtgtest.immediate #rtgtest.imm12<0>
// CHECK-NEXT: [[IMM:%.+]] = rtg.constant #rtg.isa.immediate<12, 0>
// CHECK-NEXT: rtgtest.rv32i.jalr [[R0]], [[R1]], [[IMM]]
// CHECK-NEXT: rtgtest.rv32i.jalr [[R0]], [[R1]], [[IMM]]
%r0 = rtg.virtual_reg [#rtgtest.a0, #rtgtest.a1]
%r1 = rtg.virtual_reg [#rtgtest.s0, #rtgtest.s1]
%imm = rtgtest.immediate #rtgtest.imm12<0>
%imm = rtg.constant #rtg.isa.immediate<12, 0>
rtgtest.rv32i.jalr %r0, %r1, %imm
rtgtest.rv32i.jalr %r0, %r1, %imm
@ -400,8 +400,8 @@ rtg.test @contexts(cpu0 = %cpu0: !rtgtest.cpu, cpu1 = %cpu1: !rtgtest.cpu) {
}
rtg.target @contextCpu : !rtg.dict<cpu0: !rtgtest.cpu, cpu1: !rtgtest.cpu> {
%cpu0 = rtgtest.cpu_decl <0>
%cpu1 = rtgtest.cpu_decl <1>
%cpu0 = rtg.constant #rtgtest.cpu<0>
%cpu1 = rtg.constant #rtgtest.cpu<1>
%0 = rtg.get_sequence @switchCpuSeq : !rtg.sequence<!rtgtest.cpu, !rtgtest.cpu, !rtg.sequence>
%1 = rtg.get_sequence @switchNestedCpuSeq : !rtg.sequence<!rtgtest.cpu, !rtgtest.cpu, !rtg.sequence>
rtg.context_switch #rtg.default : !rtgtest.cpu -> #rtgtest.cpu<0> : !rtgtest.cpu, %0 : !rtg.sequence<!rtgtest.cpu, !rtgtest.cpu, !rtg.sequence>
@ -553,7 +553,7 @@ rtg.sequence @seq(%arg0: !rtgtest.cpu, %arg1: !rtgtest.cpu, %seq: !rtg.sequence)
rtg.target @invalidRandomizationTarget : !rtg.dict<cpu: !rtgtest.cpu> {
%0 = rtg.get_sequence @seq : !rtg.sequence<!rtgtest.cpu, !rtgtest.cpu, !rtg.sequence>
rtg.context_switch #rtg.default : !rtgtest.cpu -> #rtgtest.cpu<0>, %0 : !rtg.sequence<!rtgtest.cpu, !rtgtest.cpu, !rtg.sequence>
%1 = rtgtest.cpu_decl <0>
%1 = rtg.constant #rtgtest.cpu<0>
rtg.yield %1 : !rtgtest.cpu
}
@ -570,7 +570,7 @@ rtg.test @invalidRandomization(cpu = %cpu: !rtgtest.cpu) {
rtg.sequence @seq() {}
rtg.target @target : !rtg.dict<cpu: !rtgtest.cpu> {
%0 = rtgtest.cpu_decl <0>
%0 = rtg.constant #rtgtest.cpu<0>
rtg.yield %0 : !rtgtest.cpu
}

View File

@ -9,12 +9,12 @@
rtg.test @test0() {
%rd = rtg.fixed_reg #rtgtest.ra
%rs = rtg.fixed_reg #rtgtest.s0
%imm = rtgtest.immediate #rtgtest.imm12<0>
%imm5 = rtgtest.immediate #rtgtest.imm5<31>
%imm21 = rtgtest.immediate #rtgtest.imm21<0>
%imm32 = rtgtest.immediate #rtgtest.imm32<0>
%neg_imm = rtgtest.immediate #rtgtest.imm12<4080>
%imm13 = rtgtest.immediate #rtgtest.imm13<6144>
%imm = rtg.constant #rtg.isa.immediate<12, 0>
%imm5 = rtg.constant #rtg.isa.immediate<5, 31>
%imm21 = rtg.constant #rtg.isa.immediate<21, 0>
%imm32 = rtg.constant #rtg.isa.immediate<32, 0>
%neg_imm = rtg.constant #rtg.isa.immediate<12, 4080>
%imm13 = rtg.constant #rtg.isa.immediate<13, 6144>
// CHECK-ALLOWED-NEXT: jalr ra, -16(s0)
// CHECK-NEXT: # jalr ra, -16(s0)
@ -59,32 +59,32 @@ rtg.test @test0() {
// CHECK-ALLOWED-NEXT: beq ra, s0, 6144
// CHECK-NEXT: # beq ra, s0, 6144
// CHECK-NEXT: .word 0x808080E3
rtgtest.rv32i.beq %rd, %rs, %imm13 : !rtgtest.imm13
rtgtest.rv32i.beq %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK-ALLOWED-NEXT: bne ra, s0, 6144
// CHECK-NEXT: # bne ra, s0, 6144
// CHECK-NEXT: .word 0x808090E3
rtgtest.rv32i.bne %rd, %rs, %imm13 : !rtgtest.imm13
rtgtest.rv32i.bne %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK-ALLOWED-NEXT: blt ra, s0, 6144
// CHECK-NEXT: # blt ra, s0, 6144
// CHECK-NEXT: .word 0x8080C0E3
rtgtest.rv32i.blt %rd, %rs, %imm13 : !rtgtest.imm13
rtgtest.rv32i.blt %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK-ALLOWED-NEXT: bge ra, s0, 6144
// CHECK-NEXT: # bge ra, s0, 6144
// CHECK-NEXT: .word 0x8080D0E3
rtgtest.rv32i.bge %rd, %rs, %imm13 : !rtgtest.imm13
rtgtest.rv32i.bge %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK-ALLOWED-NEXT: bltu ra, s0, 6144
// CHECK-NEXT: # bltu ra, s0, 6144
// CHECK-NEXT: .word 0x8080E0E3
rtgtest.rv32i.bltu %rd, %rs, %imm13 : !rtgtest.imm13
rtgtest.rv32i.bltu %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK-ALLOWED-NEXT: bgeu ra, s0, 6144
// CHECK-NEXT: # bgeu ra, s0, 6144
// CHECK-NEXT: .word 0x8080F0E3
rtgtest.rv32i.bgeu %rd, %rs, %imm13 : !rtgtest.imm13
rtgtest.rv32i.bgeu %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK-ALLOWED-NEXT: add ra, s0, s0
// CHECK-NEXT: # add ra, s0, s0
@ -154,17 +154,17 @@ rtg.test @test0() {
// CHECK-ALLOWED-NEXT: lui ra, 0
// CHECK-NEXT: # lui ra, 0
// CHECK-NEXT: .word 0xB7
rtgtest.rv32i.lui %rd, %imm32 : !rtgtest.imm32
rtgtest.rv32i.lui %rd, %imm32 : !rtg.isa.immediate<32>
// CHECK-ALLOWED-NEXT: auipc ra, 0
// CHECK-NEXT: # auipc ra, 0
// CHECK-NEXT: .word 0x97
rtgtest.rv32i.auipc %rd, %imm32 : !rtgtest.imm32
rtgtest.rv32i.auipc %rd, %imm32 : !rtg.isa.immediate<32>
// CHECK-ALLOWED-NEXT: jal ra, 0
// CHECK-NEXT: # jal ra, 0
// CHECK-NEXT: .word 0xEF
rtgtest.rv32i.jal %rd, %imm21 : !rtgtest.imm21
rtgtest.rv32i.jal %rd, %imm21 : !rtg.isa.immediate<21>
// CHECK-ALLOWED-NEXT: addi ra, s0, -16
// CHECK-NEXT: # addi ra, s0, -16

View File

@ -62,7 +62,7 @@ rtg.test @interleaveSequences() {
rtg.sequence @nested0() {
%ra = rtg.fixed_reg #rtgtest.ra
%sp = rtg.fixed_reg #rtgtest.s0
%imm = rtgtest.immediate #rtgtest.imm12<1>
%imm = rtg.constant #rtg.isa.immediate<12, 1>
rtgtest.rv32i.jalr %ra, %sp, %imm
}
@ -72,7 +72,7 @@ rtg.sequence @nested1() {
rtg.embed_sequence %1
%ra = rtg.fixed_reg #rtgtest.ra
%sp = rtg.fixed_reg #rtgtest.sp
%imm = rtgtest.immediate #rtgtest.imm12<0>
%imm = rtg.constant #rtg.isa.immediate<12, 0>
rtgtest.rv32i.jalr %ra, %sp, %imm
}
@ -80,11 +80,11 @@ rtg.sequence @nested1() {
rtg.test @nestedSequences() {
// CHECK-NEXT: [[RA0:%.+]] = rtg.fixed_reg #rtgtest.ra : !rtgtest.ireg
// CHECK-NEXT: [[S0:%.+]] = rtg.fixed_reg #rtgtest.s0 : !rtgtest.ireg
// CHECK-NEXT: [[IMM1:%.+]] = rtgtest.immediate #rtgtest.imm12<1> : !rtgtest.imm12
// CHECK-NEXT: [[IMM1:%.+]] = rtg.constant #rtg.isa.immediate<12, 1>
// CHECK-NEXT: rtgtest.rv32i.jalr [[RA0]], [[S0]], [[IMM1]]
// CHECK-NEXT: [[RA1:%.+]] = rtg.fixed_reg #rtgtest.ra : !rtgtest.ireg
// CHECK-NEXT: [[SP:%.+]] = rtg.fixed_reg #rtgtest.sp : !rtgtest.ireg
// CHECK-NEXT: [[IMM0:%.+]] = rtgtest.immediate #rtgtest.imm12<0> : !rtgtest.imm12
// CHECK-NEXT: [[IMM0:%.+]] = rtg.constant #rtg.isa.immediate<12, 0>
// CHECK-NEXT: rtgtest.rv32i.jalr [[RA1]], [[SP]], [[IMM0]]
%0 = rtg.get_sequence @nested1 : !rtg.sequence
%1 = rtg.randomize_sequence %0

View File

@ -14,7 +14,7 @@ rtg.test @test0() {
%1 = rtg.virtual_reg [#rtgtest.ra, #rtgtest.s0, #rtgtest.s1]
%2 = rtg.virtual_reg [#rtgtest.ra, #rtgtest.s0, #rtgtest.s1]
%3 = rtg.virtual_reg [#rtgtest.ra, #rtgtest.s0, #rtgtest.s1]
%imm = rtgtest.immediate #rtgtest.imm12<0>
%imm = rtg.constant #rtg.isa.immediate<12, 0>
rtgtest.rv32i.jalr %0, %2, %imm
rtgtest.rv32i.jalr %1, %0, %imm
rtgtest.rv32i.jalr %3, %1, %imm
@ -35,7 +35,7 @@ rtg.test @withFixedRegs() {
%1 = rtg.virtual_reg [#rtgtest.ra, #rtgtest.s0, #rtgtest.s1]
%2 = rtg.fixed_reg #rtgtest.s0
%3 = rtg.virtual_reg [#rtgtest.ra, #rtgtest.s0, #rtgtest.s1]
%imm = rtgtest.immediate #rtgtest.imm12<0>
%imm = rtg.constant #rtg.isa.immediate<12, 0>
rtgtest.rv32i.jalr %0, %2, %imm
rtgtest.rv32i.jalr %1, %0, %imm
rtgtest.rv32i.jalr %3, %1, %imm
@ -48,7 +48,7 @@ rtg.test @spilling() {
%0 = rtg.virtual_reg [#rtgtest.ra]
// expected-error @below {{need to spill this register, but not supported yet}}
%1 = rtg.virtual_reg [#rtgtest.ra]
%imm = rtgtest.immediate #rtgtest.imm12<0>
%imm = rtg.constant #rtg.isa.immediate<12, 0>
rtgtest.rv32i.jalr %0, %1, %imm
}

View File

@ -3,8 +3,8 @@
// CHECK-LABEL: @cpus
// CHECK-SAME: !rtgtest.cpu
rtg.target @cpus : !rtg.dict<cpu: !rtgtest.cpu> {
// CHECK: rtgtest.cpu_decl <0>
%0 = rtgtest.cpu_decl <0>
// CHECK: rtg.constant #rtgtest.cpu<0> : !rtgtest.cpu
%0 = rtg.constant #rtgtest.cpu<0>
rtg.yield %0 : !rtgtest.cpu
}
@ -85,23 +85,9 @@ rtg.test @registers(reg = %reg: !rtgtest.ireg) {
rtg.virtual_reg [#rtgtest.ra, #rtgtest.sp]
}
// CHECK-LABEL: @immediates
rtg.test @immediates() {
// CHECK: rtgtest.immediate #rtgtest.imm5<3> : !rtgtest.imm5
rtgtest.immediate #rtgtest.imm5<3> : !rtgtest.imm5
// CHECK: rtgtest.immediate #rtgtest.imm12<3> : !rtgtest.imm12
rtgtest.immediate #rtgtest.imm12<3> : !rtgtest.imm12
// CHECK: rtgtest.immediate #rtgtest.imm13<3> : !rtgtest.imm13
rtgtest.immediate #rtgtest.imm13<3> : !rtgtest.imm13
// CHECK: rtgtest.immediate #rtgtest.imm21<3> : !rtgtest.imm21
rtgtest.immediate #rtgtest.imm21<3> : !rtgtest.imm21
// CHECK: rtgtest.immediate #rtgtest.imm32<3> : !rtgtest.imm32
rtgtest.immediate #rtgtest.imm32<3> : !rtgtest.imm32
}
// CHECK-LABEL: @instructions
// CHECK-SAME: (imm = [[IMM:%.+]]: !rtgtest.imm12, imm13 = [[IMM13:%.+]]: !rtgtest.imm13, imm21 = [[IMM21:%.+]]: !rtgtest.imm21, imm32 = [[IMM32:%.+]]: !rtgtest.imm32, imm5 = [[IMM5:%.+]]: !rtgtest.imm5, label = [[LABEL:%.+]]: !rtg.isa.label, rd = [[RD:%.+]]: !rtgtest.ireg, rs = [[RS:%.+]]: !rtgtest.ireg)
rtg.test @instructions(imm = %imm: !rtgtest.imm12, imm13 = %imm13: !rtgtest.imm13, imm21 = %imm21: !rtgtest.imm21, imm32 = %imm32: !rtgtest.imm32, imm5 = %imm5: !rtgtest.imm5, label = %label: !rtg.isa.label, rd = %rd: !rtgtest.ireg, rs = %rs: !rtgtest.ireg) {
// CHECK-SAME: (imm = [[IMM:%.+]]: !rtg.isa.immediate<12>, imm13 = [[IMM13:%.+]]: !rtg.isa.immediate<13>, imm21 = [[IMM21:%.+]]: !rtg.isa.immediate<21>, imm32 = [[IMM32:%.+]]: !rtg.isa.immediate<32>, imm5 = [[IMM5:%.+]]: !rtg.isa.immediate<5>, label = [[LABEL:%.+]]: !rtg.isa.label, rd = [[RD:%.+]]: !rtgtest.ireg, rs = [[RS:%.+]]: !rtgtest.ireg)
rtg.test @instructions(imm = %imm: !rtg.isa.immediate<12>, imm13 = %imm13: !rtg.isa.immediate<13>, imm21 = %imm21: !rtg.isa.immediate<21>, imm32 = %imm32: !rtg.isa.immediate<32>, imm5 = %imm5: !rtg.isa.immediate<5>, label = %label: !rtg.isa.label, rd = %rd: !rtgtest.ireg, rs = %rs: !rtgtest.ireg) {
// CHECK: rtgtest.rv32i.jalr [[RD]], [[RS]], [[IMM]]
rtgtest.rv32i.jalr %rd, %rs, %imm
// CHECK: rtgtest.rv32i.lb [[RD]], [[RS]], [[IMM]]
@ -118,18 +104,18 @@ rtg.test @instructions(imm = %imm: !rtgtest.imm12, imm13 = %imm13: !rtgtest.imm1
rtgtest.rv32i.ecall
// CHECK: rtgtest.rv32i.ebreak
rtgtest.rv32i.ebreak
// CHECK: rtgtest.rv32i.beq [[RD]], [[RS]], [[IMM13]] : !rtgtest.imm13
rtgtest.rv32i.beq %rd, %rs, %imm13 : !rtgtest.imm13
// CHECK: rtgtest.rv32i.bne [[RD]], [[RS]], [[IMM13]] : !rtgtest.imm13
rtgtest.rv32i.bne %rd, %rs, %imm13 : !rtgtest.imm13
// CHECK: rtgtest.rv32i.blt [[RD]], [[RS]], [[IMM13]] : !rtgtest.imm13
rtgtest.rv32i.blt %rd, %rs, %imm13 : !rtgtest.imm13
// CHECK: rtgtest.rv32i.bge [[RD]], [[RS]], [[IMM13]] : !rtgtest.imm13
rtgtest.rv32i.bge %rd, %rs, %imm13 : !rtgtest.imm13
// CHECK: rtgtest.rv32i.bltu [[RD]], [[RS]], [[IMM13]] : !rtgtest.imm13
rtgtest.rv32i.bltu %rd, %rs, %imm13 : !rtgtest.imm13
// CHECK: rtgtest.rv32i.bgeu [[RD]], [[RS]], [[IMM13]] : !rtgtest.imm13
rtgtest.rv32i.bgeu %rd, %rs, %imm13 : !rtgtest.imm13
// CHECK: rtgtest.rv32i.beq [[RD]], [[RS]], [[IMM13]] : !rtg.isa.immediate<13>
rtgtest.rv32i.beq %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK: rtgtest.rv32i.bne [[RD]], [[RS]], [[IMM13]] : !rtg.isa.immediate<13>
rtgtest.rv32i.bne %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK: rtgtest.rv32i.blt [[RD]], [[RS]], [[IMM13]] : !rtg.isa.immediate<13>
rtgtest.rv32i.blt %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK: rtgtest.rv32i.bge [[RD]], [[RS]], [[IMM13]] : !rtg.isa.immediate<13>
rtgtest.rv32i.bge %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK: rtgtest.rv32i.bltu [[RD]], [[RS]], [[IMM13]] : !rtg.isa.immediate<13>
rtgtest.rv32i.bltu %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK: rtgtest.rv32i.bgeu [[RD]], [[RS]], [[IMM13]] : !rtg.isa.immediate<13>
rtgtest.rv32i.bgeu %rd, %rs, %imm13 : !rtg.isa.immediate<13>
// CHECK: rtgtest.rv32i.beq [[RD]], [[RS]], [[LABEL]] : !rtg.isa.label
rtgtest.rv32i.beq %rd, %rs, %label : !rtg.isa.label
// CHECK: rtgtest.rv32i.bne [[RD]], [[RS]], [[LABEL]] : !rtg.isa.label
@ -171,12 +157,12 @@ rtg.test @instructions(imm = %imm: !rtgtest.imm12, imm13 = %imm13: !rtgtest.imm1
// CHECK: rtgtest.rv32i.sw [[RD]], [[RS]], [[IMM]] {rtg.some_attr}
rtgtest.rv32i.sw %rd, %rs, %imm {rtg.some_attr}
// CHECK: rtgtest.rv32i.lui [[RD]], [[IMM32]] : !rtgtest.imm32 {rtg.some_attr}
rtgtest.rv32i.lui %rd, %imm32 : !rtgtest.imm32 {rtg.some_attr}
// CHECK: rtgtest.rv32i.auipc [[RD]], [[IMM32]] : !rtgtest.imm32 {rtg.some_attr}
rtgtest.rv32i.auipc %rd, %imm32 : !rtgtest.imm32 {rtg.some_attr}
// CHECK: rtgtest.rv32i.jal [[RD]], [[IMM21]] : !rtgtest.imm21 {rtg.some_attr}
rtgtest.rv32i.jal %rd, %imm21 : !rtgtest.imm21 {rtg.some_attr}
// CHECK: rtgtest.rv32i.lui [[RD]], [[IMM32]] : !rtg.isa.immediate<32> {rtg.some_attr}
rtgtest.rv32i.lui %rd, %imm32 : !rtg.isa.immediate<32> {rtg.some_attr}
// CHECK: rtgtest.rv32i.auipc [[RD]], [[IMM32]] : !rtg.isa.immediate<32> {rtg.some_attr}
rtgtest.rv32i.auipc %rd, %imm32 : !rtg.isa.immediate<32> {rtg.some_attr}
// CHECK: rtgtest.rv32i.jal [[RD]], [[IMM21]] : !rtg.isa.immediate<21> {rtg.some_attr}
rtgtest.rv32i.jal %rd, %imm21 : !rtg.isa.immediate<21> {rtg.some_attr}
// CHECK: rtgtest.rv32i.lui [[RD]], [[LABEL]] : !rtg.isa.label {rtg.some_attr}
rtgtest.rv32i.lui %rd, %label : !rtg.isa.label {rtg.some_attr}
@ -208,13 +194,6 @@ rtg.test @instructions(imm = %imm: !rtgtest.imm12, imm13 = %imm13: !rtgtest.imm1
// -----
rtg.test @immediateTooBig() {
// expected-error @below {{cannot represent 2000000 with 12 bits}}
rtgtest.immediate #rtgtest.imm12<2000000> : !rtgtest.imm12
}
// -----
rtg.test @emptyAllowed() {
// expected-error @below {{must have at least one allowed register}}
rtg.virtual_reg []

View File

@ -29,38 +29,7 @@ TEST(MaterializerTest, CPUAttr) {
auto attr = CPUAttr::get(&context, 0);
auto *op = context.getLoadedDialect<RTGTestDialect>()->materializeConstant(
builder, attr, attr.getType(), loc);
ASSERT_TRUE(op && isa<CPUDeclOp>(op));
}
TEST(MaterializerTest, ImmediateAttr) {
MLIRContext context;
context.loadDialect<RTGTestDialect>();
Location loc(UnknownLoc::get(&context));
auto moduleOp = ModuleOp::create(loc);
OpBuilder builder = OpBuilder::atBlockBegin(moduleOp.getBody());
auto attr5 = Imm5Attr::get(&context, 0);
auto attr12 = Imm12Attr::get(&context, 0);
auto attr13 = Imm13Attr::get(&context, 0);
auto attr21 = Imm32Attr::get(&context, 0);
auto attr32 = Imm21Attr::get(&context, 0);
auto *op5 = context.getLoadedDialect<RTGTestDialect>()->materializeConstant(
builder, attr5, attr5.getType(), loc);
auto *op12 = context.getLoadedDialect<RTGTestDialect>()->materializeConstant(
builder, attr12, attr12.getType(), loc);
auto *op13 = context.getLoadedDialect<RTGTestDialect>()->materializeConstant(
builder, attr13, attr13.getType(), loc);
auto *op21 = context.getLoadedDialect<RTGTestDialect>()->materializeConstant(
builder, attr21, attr21.getType(), loc);
auto *op32 = context.getLoadedDialect<RTGTestDialect>()->materializeConstant(
builder, attr32, attr32.getType(), loc);
ASSERT_TRUE(op5 && isa<ImmediateOp>(op5));
ASSERT_TRUE(op12 && isa<ImmediateOp>(op12));
ASSERT_TRUE(op13 && isa<ImmediateOp>(op13));
ASSERT_TRUE(op21 && isa<ImmediateOp>(op21));
ASSERT_TRUE(op32 && isa<ImmediateOp>(op32));
ASSERT_TRUE(op && isa<rtg::ConstantOp>(op));
}
TEST(MaterializerTest, RegisterAttr) {