[RTGTest] Add branch instructions (#8105)

This commit is contained in:
Martin Erhart 2025-01-31 19:11:28 +00:00 committed by GitHub
parent 671dec5161
commit bbe57d8014
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 165 additions and 5 deletions

View File

@ -40,6 +40,12 @@ 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);
@ -274,6 +280,16 @@ MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm12AttrGet(MlirContext ctxt,
/// 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);

View File

@ -45,6 +45,12 @@ class ImmediateAttrBase<int width> : RTGTestAttrDef<"Imm" # width, [
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());
@ -66,6 +72,7 @@ class ImmediateAttrBase<int width> : RTGTestAttrDef<"Imm" # width, [
}
def Imm12 : ImmediateAttrBase<12>;
def Imm13 : ImmediateAttrBase<13>;
def Imm21 : ImmediateAttrBase<21>;
def Imm32 : ImmediateAttrBase<32>;

View File

@ -12,6 +12,7 @@
include "mlir/IR/CommonAttrConstraints.td"
include "mlir/Interfaces/InferTypeOpInterface.td"
include "circt/Dialect/RTG/IR/RTGTypes.td"
include "circt/Dialect/RTG/IR/RTGInterfaces.td"
include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td"
@ -47,7 +48,7 @@ def ImmediateOp : RTGTestOp<"immediate", [
]> {
let summary = "declare an immediate value";
let arguments = (ins AnyAttrOf<[Imm12, Imm21, Imm32]>:$imm);
let arguments = (ins AnyAttrOf<[Imm12, Imm13, Imm21, Imm32]>:$imm);
let results = (outs AnyType:$result);
let assemblyFormat = "$imm attr-dict";
@ -78,7 +79,7 @@ class InstFormatIOpBase<string mnemonic, int opcode7, int funct3>
let extraClassDefinition = [{
void $cppClass::printInstructionBinary(llvm::raw_ostream &os,
FoldAdaptor adaptor) {
auto binary = APInt(12, cast<Imm12Attr>(adaptor.getImm()).getValue())
auto binary = cast<Imm12Attr>(adaptor.getImm()).getAPInt()
.concat(APInt(5, cast<rtg::RegisterAttrInterface>(
adaptor.getRs()).getClassIndex()))
.concat(APInt(3, }] # funct3 # [{))
@ -130,10 +131,73 @@ class InstFormatIImmOpBase<string mnemonic, int opcode7, int funct12>
}];
}
class InstFormatBOpBase<string mnemonic, int opcode7, int funct3>
: RTGTestOp<"rv32i." # mnemonic, [InstructionOpAdaptor]> {
let arguments = (ins IntegerRegisterType:$rs1,
IntegerRegisterType:$rs2,
AnyTypeOf<[Imm13Type, LabelType]>:$imm);
let assemblyFormat = [{
$rs1 `,` $rs2 `,` $imm `:` qualified(type($imm)) attr-dict
}];
let extraClassDefinition = [{
void $cppClass::printInstructionBinary(llvm::raw_ostream &os,
FoldAdaptor adaptor) {
assert (isa<Imm13Attr>(adaptor.getImm()) &&
"binary of labels not supported");
auto imm = cast<Imm13Attr>(adaptor.getImm()).getAPInt();
auto rs1 = cast<rtg::RegisterAttrInterface>(adaptor.getRs1());
auto rs2 = cast<rtg::RegisterAttrInterface>(adaptor.getRs2());
auto binary = imm.extractBits(1, 12)
.concat(imm.extractBits(6, 5))
.concat(llvm::APInt(5, rs2.getClassIndex()))
.concat(llvm::APInt(5, rs1.getClassIndex()))
.concat(llvm::APInt(3, }] # funct3 # [{))
.concat(imm.extractBits(4, 1))
.concat(imm.extractBits(1, 11))
.concat(llvm::APInt(7, }] # opcode7 # [{));
SmallVector<char> str;
binary.toStringUnsigned(str, 16);
os << str;
}
void $cppClass::printInstructionAssembly(llvm::raw_ostream &os,
FoldAdaptor adaptor) {
os << getOperationName().rsplit('.').second
<< " "
<< cast<rtg::RegisterAttrInterface>(adaptor.getRs1())
.getRegisterAssembly()
<< ", "
<< cast<rtg::RegisterAttrInterface>(adaptor.getRs2())
.getRegisterAssembly()
<< ", ";
if (auto label = dyn_cast<StringAttr>(adaptor.getImm())) {
os << label.getValue();
return;
}
os << cast<Imm13Attr>(adaptor.getImm()).getValue();
}
}];
}
//===- Instructions -------------------------------------------------------===//
def RV32I_JALROp : InstFormatIOpBase<"jalr", 0b1100111, 0b000>;
def RV32I_BEQ : InstFormatBOpBase<"beq", 0b1100011, 0b000>;
def RV32I_BNE : InstFormatBOpBase<"bne", 0b1100011, 0b001>;
def RV32I_BLT : InstFormatBOpBase<"blt", 0b1100011, 0b100>;
def RV32I_BGE : InstFormatBOpBase<"bge", 0b1100011, 0b101>;
def RV32I_BLTU : InstFormatBOpBase<"bltu", 0b1100011, 0b110>;
def RV32I_BGEU : InstFormatBOpBase<"bgeu", 0b1100011, 0b111>;
def RV32I_LBOp : InstFormatIOpBase<"lb", 0b0000011, 0b000>;
def RV32I_LHOp : InstFormatIOpBase<"lh", 0b0000011, 0b001>;
def RV32I_LWOp : InstFormatIOpBase<"lw", 0b0000011, 0b010>;

View File

@ -39,6 +39,7 @@ class ImmTypeBase<int width> : TypeDef<RTGTestDialect, "Imm" # width, []> {
}
def Imm12Type : ImmTypeBase<12>;
def Imm13Type : ImmTypeBase<13>;
def Imm21Type : ImmTypeBase<21>;
def Imm32Type : ImmTypeBase<32>;

View File

@ -172,6 +172,8 @@ with Context() as ctx, Location.unknown():
with InsertionPoint(m.body):
# 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

View File

@ -38,6 +38,14 @@ void circt::python::populateDialectRTGTestSubmodule(nb::module_ &m) {
},
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",
@ -331,6 +339,17 @@ void circt::python::populateDialectRTGTestSubmodule(nb::module_ &m) {
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",

View File

@ -41,6 +41,12 @@ 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) {
@ -343,6 +349,18 @@ 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));
}

View File

@ -268,6 +268,13 @@ static void testImmediates(MlirContext ctx) {
// 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,

View File

@ -90,6 +90,8 @@ rtg.test @registers : !rtg.dict<reg: !rtgtest.ireg> {
rtg.test @immediates : !rtg.dict<> {
// 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
@ -97,9 +99,9 @@ rtg.test @immediates : !rtg.dict<> {
}
// CHECK-LABEL: @instructions
rtg.test @instructions : !rtg.dict<imm: !rtgtest.imm12, rd: !rtgtest.ireg, rs: !rtgtest.ireg> {
// CHECK: ([[IMM:%.+]]: !rtgtest.imm12, [[RD:%.+]]: !rtgtest.ireg, [[RS:%.+]]: !rtgtest.ireg)
^bb0(%imm: !rtgtest.imm12, %rd: !rtgtest.ireg, %rs: !rtgtest.ireg):
rtg.test @instructions : !rtg.dict<imm: !rtgtest.imm12, imm13: !rtgtest.imm13, label: !rtg.label, rd: !rtgtest.ireg, rs: !rtgtest.ireg> {
// CHECK: ([[IMM:%.+]]: !rtgtest.imm12, [[IMM13:%.+]]: !rtgtest.imm13, [[LABEL:%.+]]: !rtg.label, [[RD:%.+]]: !rtgtest.ireg, [[RS:%.+]]: !rtgtest.ireg)
^bb0(%imm: !rtgtest.imm12, %imm13: !rtgtest.imm13, %label: !rtg.label, %rd: !rtgtest.ireg, %rs: !rtgtest.ireg):
// CHECK: rtgtest.rv32i.jalr [[RD]], [[RS]], [[IMM]]
rtgtest.rv32i.jalr %rd, %rs, %imm
// CHECK: rtgtest.rv32i.lb [[RD]], [[RS]], [[IMM]]
@ -116,6 +118,30 @@ rtg.test @instructions : !rtg.dict<imm: !rtgtest.imm12, rd: !rtgtest.ireg, rs: !
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]], [[LABEL]] : !rtg.label
rtgtest.rv32i.beq %rd, %rs, %label : !rtg.label
// CHECK: rtgtest.rv32i.bne [[RD]], [[RS]], [[LABEL]] : !rtg.label
rtgtest.rv32i.bne %rd, %rs, %label : !rtg.label
// CHECK: rtgtest.rv32i.blt [[RD]], [[RS]], [[LABEL]] : !rtg.label
rtgtest.rv32i.blt %rd, %rs, %label : !rtg.label
// CHECK: rtgtest.rv32i.bge [[RD]], [[RS]], [[LABEL]] : !rtg.label
rtgtest.rv32i.bge %rd, %rs, %label : !rtg.label
// CHECK: rtgtest.rv32i.bltu [[RD]], [[RS]], [[LABEL]] : !rtg.label
rtgtest.rv32i.bltu %rd, %rs, %label : !rtg.label
// CHECK: rtgtest.rv32i.bgeu [[RD]], [[RS]], [[LABEL]] : !rtg.label
rtgtest.rv32i.bgeu %rd, %rs, %label : !rtg.label
}
// -----