[RTGTest] Improved register representation (#8052)

This commit is contained in:
Martin Erhart 2025-01-24 13:47:34 +00:00 committed by GitHub
parent 65ae4bd9b6
commit 0bf7f7d841
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 1384 additions and 285 deletions

View File

@ -45,6 +45,201 @@ MLIR_CAPI_EXPORTED MlirAttribute rtgtestCPUAttrGet(MlirContext ctxt,
/// Returns the core ID represented by the CPU attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestCPUAttrGetId(MlirAttribute attr);
// Registers.
//===----------------------------------------------------------------------===//
/// If the type is an RTGTest RegZeroAttr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegZero(MlirAttribute attr);
/// Creates an RTGTest RegZero attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegZeroAttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegRaAttr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegRa(MlirAttribute attr);
/// Creates an RTGTest RegRa attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegRaAttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegSpAttr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegSp(MlirAttribute attr);
/// Creates an RTGTest RegSp attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegSpAttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegGpAttr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegGp(MlirAttribute attr);
/// Creates an RTGTest RegGp attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegGpAttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegTpAttr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegTp(MlirAttribute attr);
/// Creates an RTGTest RegTp attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegTpAttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegT0Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT0(MlirAttribute attr);
/// Creates an RTGTest RegT0 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT0AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegT1Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT1(MlirAttribute attr);
/// Creates an RTGTest RegT1 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT1AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegT2Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT2(MlirAttribute attr);
/// Creates an RTGTest RegT2 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT2AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS0Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS0(MlirAttribute attr);
/// Creates an RTGTest RegS0 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS0AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS1Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS1(MlirAttribute attr);
/// Creates an RTGTest RegS1 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS1AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegA0Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA0(MlirAttribute attr);
/// Creates an RTGTest RegA0 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA0AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegA1Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA1(MlirAttribute attr);
/// Creates an RTGTest RegA1 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA1AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegA2Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA2(MlirAttribute attr);
/// Creates an RTGTest RegA2 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA2AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegA3Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA3(MlirAttribute attr);
/// Creates an RTGTest RegA3 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA3AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegA4Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA4(MlirAttribute attr);
/// Creates an RTGTest RegA4 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA4AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegA5Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA5(MlirAttribute attr);
/// Creates an RTGTest RegA5 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA5AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegA6Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA6(MlirAttribute attr);
/// Creates an RTGTest RegA6 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA6AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegA7Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA7(MlirAttribute attr);
/// Creates an RTGTest RegA7 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA7AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS2Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS2(MlirAttribute attr);
/// Creates an RTGTest RegS2 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS2AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS3Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS3(MlirAttribute attr);
/// Creates an RTGTest RegS3 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS3AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS4Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS4(MlirAttribute attr);
/// Creates an RTGTest RegS4 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS4AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS5Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS5(MlirAttribute attr);
/// Creates an RTGTest RegS5 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS5AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS6Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS6(MlirAttribute attr);
/// Creates an RTGTest RegS6 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS6AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS7Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS7(MlirAttribute attr);
/// Creates an RTGTest RegS7 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS7AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS8Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS8(MlirAttribute attr);
/// Creates an RTGTest RegS8 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS8AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS9Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS9(MlirAttribute attr);
/// Creates an RTGTest RegS9 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS9AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS10Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS10(MlirAttribute attr);
/// Creates an RTGTest RegS10 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS10AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegS11Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS11(MlirAttribute attr);
/// Creates an RTGTest RegS11 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS11AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegT3Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT3(MlirAttribute attr);
/// Creates an RTGTest RegT3 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT3AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegT4Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT4(MlirAttribute attr);
/// Creates an RTGTest RegT4 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT4AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegT5Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT5(MlirAttribute attr);
/// Creates an RTGTest RegT5 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT5AttrGet(MlirContext ctxt);
/// If the attribute is an RTGTest RegT6Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT6(MlirAttribute attr);
/// Creates an RTGTest RegT6 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT6AttrGet(MlirContext ctxt);
#ifdef __cplusplus
}
#endif

View File

@ -24,6 +24,16 @@ add_public_tablegen_target(CIRCTRTGAttrInterfacesIncGen)
add_dependencies(circt-headers CIRCTRTGAttrInterfacesIncGen)
set(LLVM_TARGET_DEFINITIONS RTGISAAssemblyInterfaces.td)
mlir_tablegen(RTGISAAssemblyAttrInterfaces.h.inc -gen-attr-interface-decls)
mlir_tablegen(RTGISAAssemblyAttrInterfaces.cpp.inc -gen-attr-interface-defs)
add_public_tablegen_target(CIRCTRTGISAAssemblyAttrInterfacesIncGen)
add_dependencies(circt-headers CIRCTRTGISAAssemblyAttrInterfacesIncGen)
mlir_tablegen(RTGISAAssemblyTypeInterfaces.h.inc -gen-type-interface-decls)
mlir_tablegen(RTGISAAssemblyTypeInterfaces.cpp.inc -gen-type-interface-defs)
add_public_tablegen_target(CIRCTRTGISAAssemblyTypeInterfacesIncGen)
add_dependencies(circt-headers CIRCTRTGISAAssemblyTypeInterfacesIncGen)
mlir_tablegen(RTGISAAssemblyOpInterfaces.h.inc -gen-op-interface-decls)
mlir_tablegen(RTGISAAssemblyOpInterfaces.cpp.inc -gen-op-interface-defs)
add_public_tablegen_target(CIRCTRTGISAAssemblyOpInterfacesIncGen)

View File

@ -0,0 +1,24 @@
//===- RTGISAAssemblyAttrInterfaces.h - Interf. for ISA ASM RTG -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares attr interfaces for the RTG Dialect that are specific to
// ISA Assembly tests.
//
//===----------------------------------------------------------------------===//
#ifndef CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYATTRINTERFACES_H
#define CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYATTRINTERFACES_H
#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributeInterfaces.h"
#include "llvm/ADT/APInt.h"
#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h.inc"
#endif // CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYATTRINTERFACES_H

View File

@ -10,51 +10,38 @@
#define CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYINTERFACES_TD
include "mlir/IR/Interfaces.td"
include "mlir/IR/OpBase.td"
include "mlir/IR/BuiltinAttributeInterfaces.td"
def RegisterOpInterface : OpInterface<"RegisterOpInterface"> {
def RegisterAttrInterface : AttrInterface<"RegisterAttrInterface", [TypedAttrInterface]> {
let description = [{
This interface should be implemented by operations that represent
ISA registers. It is used for register allocation, emission, etc.
Virtual registers are indicated by a register index of ~0.
This interface should be implemented by attributes that represent
ISA registers. It is used for elaboration, register allocation, emission,
etc.
}];
let cppNamespace = "::circt::rtg";
let methods = [
InterfaceMethod<[{
Returns the bitvector of the Dialect's canonical register indices for
which this operation allows.
}],
"::llvm::BitVector", "getAllowedRegs">,
InterfaceMethod<[{
Returns the Dialect's canonical register index of the register if it
selects a specific one, or ~0 if it isn't fixed yet.
}],
"unsigned", "getFixedReg">,
InterfaceMethod<[{
Sets this operation to use a specific register given by the Dialect's
canonical register index.
}],
"void", "setFixedReg", (ins "unsigned":$reg)>,
InterfaceMethod<[{
Returns the class specific index of the register. This translates from
the flat internal representation to the architectural representation.
}],
"unsigned", "getClassIndex">,
InterfaceMethod<[{
Returns the class specific index of the register. This translates from
the flat internal representation to the architectural representation.
This returns an APInt for the common binary encoding.
}],
"llvm::APInt", "getClassIndexBinary">,
InterfaceMethod<[{
Returns a suitable string for use in assembly format.
}],
"std::string", "getRegisterAssembly">,
"llvm::StringLiteral", "getRegisterAssembly">,
];
}
def RegisterTypeInterface : TypeInterface<"RegisterTypeInterface"> {
let description = [{
This interface should be implemented by types that represent
ISA registers. It is used for elaboration, register allocation, emission,
etc.
}];
let cppNamespace = "::circt::rtg";
}
def InstructionOpInterface : OpInterface<"InstructionOpInterface"> {
let description = [{
This interface should be implemented by operations that represent

View File

@ -0,0 +1,22 @@
//===- RTGISAAssemblyTypeInterfaces.h - Interf. for ISA ASM RTG -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares type interfaces for the RTG Dialect that are specific to
// ISA Assembly tests.
//
//===----------------------------------------------------------------------===//
#ifndef CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYTYPEINTERFACES_H
#define CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYTYPEINTERFACES_H
#include "circt/Support/LLVM.h"
#include "mlir/IR/Types.h"
#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h.inc"
#endif // CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYTYPEINTERFACES_H

View File

@ -15,6 +15,8 @@
#include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGDialect.h"
#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGTypeInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGTypes.h"
#include "circt/Support/LLVM.h"

View File

@ -19,6 +19,7 @@ include "mlir/Interfaces/InferTypeOpInterface.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/Interfaces/InferTypeOpInterface.td"
include "circt/Dialect/RTG/IR/RTGInterfaces.td"
include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td"
// Base class for the operation in this dialect.
class RTGOp<string mnemonic, list<Trait> traits = []> :
@ -324,6 +325,44 @@ def BagUniqueSizeOp : RTGOp<"bag_unique_size", [Pure]> {
}];
}
//===- ISA Register Handling Operations -----------------------------------===//
def FixedRegisterOp : RTGOp<"fixed_reg", [
Pure, ConstantLike,
DeclareOpInterfaceMethods<InferTypeOpInterface>,
]> {
let summary = "returns a value representing a fixed register";
let description = [{
This operation creates a value representing the register given as the 'reg'
attribute. This is always a concrete ISA register.
The return type always matches the register attribute type.
}];
let arguments = (ins RegisterAttrInterface:$reg);
let results = (outs RegisterTypeInterface:$result);
let assemblyFormat = "$reg attr-dict";
let hasFolder = 1;
}
def VirtualRegisterOp : RTGOp<"virtual_reg", [
DeclareOpInterfaceMethods<InferTypeOpInterface>,
]> {
let summary = "returns a value representing a virtual register";
let description = [{
This operation creates a value representing a virtual register. The
'allowedRegisters' attribute specifies the concrete registers that may be
chosen during register allocation.
}];
// ArrayAttr of RegisterAttrInterfaces
let arguments = (ins ArrayAttr:$allowedRegs);
let results = (outs RegisterTypeInterface:$result);
let assemblyFormat = "$allowedRegs attr-dict";
let hasVerifier = 1;
}
//===- Test Specification Operations --------------------------------------===//
def TestOp : RTGOp<"test", [

View File

@ -31,17 +31,23 @@ public:
ResultType dispatchOpVisitor(Operation *op, ExtraArgs... args) {
auto *thisCast = static_cast<ConcreteType *>(this);
return TypeSwitch<Operation *, ResultType>(op)
.template Case<SequenceOp, SequenceClosureOp, SetCreateOp,
SetSelectRandomOp, SetDifferenceOp, SetUnionOp,
SetSizeOp, TestOp, InvokeSequenceOp, BagCreateOp,
BagSelectRandomOp, BagDifferenceOp, BagUnionOp,
BagUniqueSizeOp, LabelDeclOp, LabelUniqueDeclOp, LabelOp,
TargetOp, YieldOp>([&](auto expr) -> ResultType {
.template Case<
// Bags
BagCreateOp, BagSelectRandomOp, BagDifferenceOp, BagUnionOp,
BagUniqueSizeOp,
// Labels
LabelDeclOp, LabelUniqueDeclOp, LabelOp,
// Registers
FixedRegisterOp, VirtualRegisterOp,
// RTG tests
TestOp, TargetOp, YieldOp,
// Sequences
SequenceOp, SequenceClosureOp, InvokeSequenceOp,
// Sets
SetCreateOp, SetSelectRandomOp, SetDifferenceOp, SetUnionOp,
SetSizeOp>([&](auto expr) -> ResultType {
return thisCast->visitOp(expr, args...);
})
.template Case<RegisterOpInterface>([&](auto expr) -> ResultType {
return thisCast->visitRegisterOp(expr, args...);
})
.template Case<ContextResourceOpInterface>(
[&](auto expr) -> ResultType {
return thisCast->visitContextResourceOp(expr, args...);
@ -66,10 +72,6 @@ public:
/// handled by the concrete visitor.
ResultType visitUnhandledOp(Operation *op, ExtraArgs... args);
ResultType visitRegisterOp(RegisterOpInterface op, ExtraArgs... args) {
return static_cast<ConcreteType *>(this)->visitUnhandledOp(op, args...);
}
ResultType visitContextResourceOp(ContextResourceOpInterface op,
ExtraArgs... args) {
return static_cast<ConcreteType *>(this)->visitUnhandledOp(op, args...);
@ -103,6 +105,8 @@ public:
HANDLE(TestOp, Unhandled);
HANDLE(TargetOp, Unhandled);
HANDLE(YieldOp, Unhandled);
HANDLE(FixedRegisterOp, Unhandled);
HANDLE(VirtualRegisterOp, Unhandled);
#undef HANDLE
};

View File

@ -18,6 +18,7 @@ include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/IR/OpAsmInterface.td"
include "circt/Dialect/RTG/IR/RTGInterfaces.td"
include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td"
include "circt/Dialect/RTGTest/IR/RTGTestDialect.td"
include "circt/Dialect/RTGTest/IR/RTGTestAttributes.td"

View File

@ -14,6 +14,7 @@
#include "mlir/IR/BuiltinAttributes.h"
#include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h"
#define GET_ATTRDEF_CLASSES
#include "circt/Dialect/RTGTest/IR/RTGTestAttributes.h.inc"

View File

@ -15,49 +15,8 @@
include "circt/Dialect/RTGTest/IR/RTGTestDialect.td"
include "circt/Dialect/RTG/IR/RTGInterfaces.td"
include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/EnumAttr.td"
// Flat allocation of unique IDs to all registers. The actual ID value does not
// matter.
def RegisterAttr : I32EnumAttr<
"Registers", "Unique IDs for all RTGTest registers", [
I32EnumAttrCase<"zero", 0>,
I32EnumAttrCase<"ra", 1>,
I32EnumAttrCase<"sp", 2>,
I32EnumAttrCase<"gp", 3>,
I32EnumAttrCase<"tp", 4>,
I32EnumAttrCase<"t0", 5>,
I32EnumAttrCase<"t1", 6>,
I32EnumAttrCase<"t2", 7>,
I32EnumAttrCase<"s0", 8>,
I32EnumAttrCase<"s1", 9>,
I32EnumAttrCase<"a0", 10>,
I32EnumAttrCase<"a1", 11>,
I32EnumAttrCase<"a2", 12>,
I32EnumAttrCase<"a3", 13>,
I32EnumAttrCase<"a4", 14>,
I32EnumAttrCase<"a5", 15>,
I32EnumAttrCase<"a6", 16>,
I32EnumAttrCase<"a7", 17>,
I32EnumAttrCase<"s2", 18>,
I32EnumAttrCase<"s3", 19>,
I32EnumAttrCase<"s4", 20>,
I32EnumAttrCase<"s5", 21>,
I32EnumAttrCase<"s6", 22>,
I32EnumAttrCase<"s7", 23>,
I32EnumAttrCase<"s8", 24>,
I32EnumAttrCase<"s9", 25>,
I32EnumAttrCase<"s10", 26>,
I32EnumAttrCase<"s11", 27>,
I32EnumAttrCase<"t3", 28>,
I32EnumAttrCase<"t4", 29>,
I32EnumAttrCase<"t5", 30>,
I32EnumAttrCase<"t6", 31>,
I32EnumAttrCase<"Virtual", 32>
]> {
let cppNamespace = "::circt::rtgtest";
}
class RTGTestAttrDef<string name, list<Trait> traits = []>
: AttrDef<RTGTestDialect, name, traits>;
@ -76,4 +35,57 @@ def CPUAttr : RTGTestAttrDef<"CPU", [ContextResourceAttrInterface]> {
}];
}
class IntegerRegisterAttrBase<string cppName, string name, int classIndex>
: RTGTestAttrDef<cppName, [RegisterAttrInterface]> {
let mnemonic = name;
let extraClassDeclaration = [{
unsigned getClassIndex() const {
return }] # classIndex # [{;
}
llvm::StringLiteral getRegisterAssembly() const {
return "}] # name # [{";
}
Type getType() const {
return IntegerRegisterType::get(getContext());
}
}];
}
def RegZeroAttr : IntegerRegisterAttrBase<"RegZero", "zero", 0>;
def RegRaAttr : IntegerRegisterAttrBase<"RegRa", "ra", 1>;
def RegSpAttr : IntegerRegisterAttrBase<"RegSp", "sp", 2>;
def RegGpAttr : IntegerRegisterAttrBase<"RegGp", "gp", 3>;
def RegTpAttr : IntegerRegisterAttrBase<"RegTp", "tp", 4>;
def RegT0Attr : IntegerRegisterAttrBase<"RegT0", "t0", 5>;
def RegT1Attr : IntegerRegisterAttrBase<"RegT1", "t1", 6>;
def RegT2Attr : IntegerRegisterAttrBase<"RegT2", "t2", 7>;
def RegS0Attr : IntegerRegisterAttrBase<"RegS0", "s0", 8>;
def RegS1Attr : IntegerRegisterAttrBase<"RegS1", "s1", 9>;
def RegA0Attr : IntegerRegisterAttrBase<"RegA0", "a0", 10>;
def RegA1Attr : IntegerRegisterAttrBase<"RegA1", "a1", 11>;
def RegA2Attr : IntegerRegisterAttrBase<"RegA2", "a2", 12>;
def RegA3Attr : IntegerRegisterAttrBase<"RegA3", "a3", 13>;
def RegA4Attr : IntegerRegisterAttrBase<"RegA4", "a4", 14>;
def RegA5Attr : IntegerRegisterAttrBase<"RegA5", "a5", 15>;
def RegA6Attr : IntegerRegisterAttrBase<"RegA6", "a6", 16>;
def RegA7Attr : IntegerRegisterAttrBase<"RegA7", "a7", 17>;
def RegS2Attr : IntegerRegisterAttrBase<"RegS2", "s2", 18>;
def RegS3Attr : IntegerRegisterAttrBase<"RegS3", "s3", 19>;
def RegS4Attr : IntegerRegisterAttrBase<"RegS4", "s4", 20>;
def RegS5Attr : IntegerRegisterAttrBase<"RegS5", "s5", 21>;
def RegS6Attr : IntegerRegisterAttrBase<"RegS6", "s6", 22>;
def RegS7Attr : IntegerRegisterAttrBase<"RegS7", "s7", 23>;
def RegS8Attr : IntegerRegisterAttrBase<"RegS8", "s8", 24>;
def RegS9Attr : IntegerRegisterAttrBase<"RegS9", "s9", 25>;
def RegS10Attr : IntegerRegisterAttrBase<"RegS10", "s10", 26>;
def RegS11Attr : IntegerRegisterAttrBase<"RegS11", "s11", 27>;
def RegT3Attr : IntegerRegisterAttrBase<"RegT3", "t3", 28>;
def RegT4Attr : IntegerRegisterAttrBase<"RegT4", "t4", 29>;
def RegT5Attr : IntegerRegisterAttrBase<"RegT5", "t5", 30>;
def RegT6Attr : IntegerRegisterAttrBase<"RegT6", "t6", 31>;
#endif // CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_TD

View File

@ -48,21 +48,3 @@ def ConstantTestOp : RTGTestOp<"constant_test", [
let assemblyFormat = "type($result) attr-dict";
let hasFolder = 1;
}
def RegisterOp : RTGTestOp<"reg", [
DeclareOpInterfaceMethods<RegisterOpInterface>,
DeclareOpInterfaceMethods<InferTypeOpInterface>,
]> {
let summary = "returns a value representing a register";
let description = [{
This operation creates a value representing the register given as the 'reg'
attribute. A register can be a concrete register or a virtual register.
Virtual registers will be assigned a concrete register when running register
allocation.
}];
let arguments = (ins RegisterAttr:$reg);
let results = (outs RegisterType:$result);
let assemblyFormat = "$reg attr-dict";
}

View File

@ -13,6 +13,7 @@
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Types.h"
#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGTypeInterfaces.h"
#define GET_TYPEDEF_CLASSES

View File

@ -15,6 +15,7 @@
include "circt/Dialect/RTGTest/IR/RTGTestDialect.td"
include "circt/Dialect/RTG/IR/RTGInterfaces.td"
include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
class RTGTestTypeDef<string name, list<Trait> traits = []>
@ -32,7 +33,9 @@ def CPUType : RTGTestTypeDef<"CPU", [ContextResourceTypeInterface]> {
let assemblyFormat = "";
}
def IntegerRegisterType : TypeDef<RTGTestDialect, "IntegerRegister", []> {
def IntegerRegisterType : TypeDef<RTGTestDialect, "IntegerRegister", [
RegisterTypeInterface
]> {
let summary = "represents an integer register";
let mnemonic = "ireg";

View File

@ -94,3 +94,74 @@ with Context() as ctx, Location.unknown():
# CHECK: rtg.sequence @seq
# CHECK: (%{{.*}}: !rtg.sequence, %{{.*}}: !rtg.label, %{{.*}}: !rtg.set<index>, %{{.*}}: !rtg.bag<index>):
print(m)
with Context() as ctx, Location.unknown():
circt.register_dialects(ctx)
m = Module.create()
with InsertionPoint(m.body):
# CHECK: rtg.fixed_reg #rtgtest.zero
rtg.FixedRegisterOp(rtgtest.RegZeroAttr.get())
# CHECK: rtg.fixed_reg #rtgtest.ra
rtg.FixedRegisterOp(rtgtest.RegRaAttr.get())
# CHECK: rtg.fixed_reg #rtgtest.sp
rtg.FixedRegisterOp(rtgtest.RegSpAttr.get())
# CHECK: rtg.fixed_reg #rtgtest.gp
rtg.FixedRegisterOp(rtgtest.RegGpAttr.get())
# CHECK: rtg.fixed_reg #rtgtest.tp
rtg.FixedRegisterOp(rtgtest.RegTpAttr.get())
# CHECK: rtg.fixed_reg #rtgtest.t0
rtg.FixedRegisterOp(rtgtest.RegT0Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.t1
rtg.FixedRegisterOp(rtgtest.RegT1Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.t2
rtg.FixedRegisterOp(rtgtest.RegT2Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s0
rtg.FixedRegisterOp(rtgtest.RegS0Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s1
rtg.FixedRegisterOp(rtgtest.RegS1Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.a0
rtg.FixedRegisterOp(rtgtest.RegA0Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.a1
rtg.FixedRegisterOp(rtgtest.RegA1Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.a2
rtg.FixedRegisterOp(rtgtest.RegA2Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.a3
rtg.FixedRegisterOp(rtgtest.RegA3Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.a4
rtg.FixedRegisterOp(rtgtest.RegA4Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.a5
rtg.FixedRegisterOp(rtgtest.RegA5Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.a6
rtg.FixedRegisterOp(rtgtest.RegA6Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.a7
rtg.FixedRegisterOp(rtgtest.RegA7Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s2
rtg.FixedRegisterOp(rtgtest.RegS2Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s3
rtg.FixedRegisterOp(rtgtest.RegS3Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s4
rtg.FixedRegisterOp(rtgtest.RegS4Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s5
rtg.FixedRegisterOp(rtgtest.RegS5Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s6
rtg.FixedRegisterOp(rtgtest.RegS6Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s7
rtg.FixedRegisterOp(rtgtest.RegS7Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s8
rtg.FixedRegisterOp(rtgtest.RegS8Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s9
rtg.FixedRegisterOp(rtgtest.RegS9Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s10
rtg.FixedRegisterOp(rtgtest.RegS10Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.s11
rtg.FixedRegisterOp(rtgtest.RegS11Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.t3
rtg.FixedRegisterOp(rtgtest.RegT3Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.t4
rtg.FixedRegisterOp(rtgtest.RegT4Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.t5
rtg.FixedRegisterOp(rtgtest.RegT5Attr.get())
# CHECK: rtg.fixed_reg #rtgtest.t6
rtg.FixedRegisterOp(rtgtest.RegT6Attr.get())
print(m)

View File

@ -39,4 +39,260 @@ void circt::python::populateDialectRTGTestSubmodule(nb::module_ &m) {
nb::arg("self"), nb::arg("id"), nb::arg("ctxt") = nullptr)
.def_property_readonly(
"id", [](MlirAttribute self) { return rtgtestCPUAttrGetId(self); });
mlir_attribute_subclass(m, "RegZeroAttr", rtgtestAttrIsARegZero)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegZeroAttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegRaAttr", rtgtestAttrIsARegRa)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegRaAttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegSpAttr", rtgtestAttrIsARegSp)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegSpAttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegGpAttr", rtgtestAttrIsARegGp)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegGpAttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegTpAttr", rtgtestAttrIsARegTp)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegTpAttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegT0Attr", rtgtestAttrIsARegT0)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegT0AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegT1Attr", rtgtestAttrIsARegT1)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegT1AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegT2Attr", rtgtestAttrIsARegT2)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegT2AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS0Attr", rtgtestAttrIsARegS0)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS0AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS1Attr", rtgtestAttrIsARegS1)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS1AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegA0Attr", rtgtestAttrIsARegA0)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegA0AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegA1Attr", rtgtestAttrIsARegA1)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegA1AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegA2Attr", rtgtestAttrIsARegA2)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegA2AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegA3Attr", rtgtestAttrIsARegA3)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegA3AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegA4Attr", rtgtestAttrIsARegA4)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegA4AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegA5Attr", rtgtestAttrIsARegA5)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegA5AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegA6Attr", rtgtestAttrIsARegA6)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegA6AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegA7Attr", rtgtestAttrIsARegA7)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegA7AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS2Attr", rtgtestAttrIsARegS2)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS2AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS3Attr", rtgtestAttrIsARegS3)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS3AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS4Attr", rtgtestAttrIsARegS4)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS4AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS5Attr", rtgtestAttrIsARegS5)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS5AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS6Attr", rtgtestAttrIsARegS6)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS6AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS7Attr", rtgtestAttrIsARegS7)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS7AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS8Attr", rtgtestAttrIsARegS8)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS8AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS9Attr", rtgtestAttrIsARegS9)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS9AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS10Attr", rtgtestAttrIsARegS10)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS10AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegS11Attr", rtgtestAttrIsARegS11)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegS11AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegT3Attr", rtgtestAttrIsARegT3)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegT3AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegT4Attr", rtgtestAttrIsARegT4)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegT4AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegT5Attr", rtgtestAttrIsARegT5)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegT5AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "RegT6Attr", rtgtestAttrIsARegT6)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestRegT6AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
}

View File

@ -47,3 +47,262 @@ MlirAttribute rtgtestCPUAttrGet(MlirContext ctxt, unsigned id) {
unsigned rtgtestCPUAttrGetId(MlirAttribute attr) {
return cast<CPUAttr>(unwrap(attr)).getId();
}
// Registers
//===----------------------------------------------------------------------===//
bool rtgtestAttrIsARegZero(MlirAttribute attr) {
return isa<RegZeroAttr>(unwrap(attr));
}
MlirAttribute rtgtestRegZeroAttrGet(MlirContext ctxt) {
return wrap(RegZeroAttr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegRa(MlirAttribute attr) {
return isa<RegRaAttr>(unwrap(attr));
}
MlirAttribute rtgtestRegRaAttrGet(MlirContext ctxt) {
return wrap(RegRaAttr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegSp(MlirAttribute attr) {
return isa<RegSpAttr>(unwrap(attr));
}
MlirAttribute rtgtestRegSpAttrGet(MlirContext ctxt) {
return wrap(RegSpAttr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegGp(MlirAttribute attr) {
return isa<RegGpAttr>(unwrap(attr));
}
MlirAttribute rtgtestRegGpAttrGet(MlirContext ctxt) {
return wrap(RegGpAttr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegTp(MlirAttribute attr) {
return isa<RegTpAttr>(unwrap(attr));
}
MlirAttribute rtgtestRegTpAttrGet(MlirContext ctxt) {
return wrap(RegTpAttr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegT0(MlirAttribute attr) {
return isa<RegT0Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegT0AttrGet(MlirContext ctxt) {
return wrap(RegT0Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegT1(MlirAttribute attr) {
return isa<RegT1Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegT1AttrGet(MlirContext ctxt) {
return wrap(RegT1Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegT2(MlirAttribute attr) {
return isa<RegT2Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegT2AttrGet(MlirContext ctxt) {
return wrap(RegT2Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS0(MlirAttribute attr) {
return isa<RegS0Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS0AttrGet(MlirContext ctxt) {
return wrap(RegS0Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS1(MlirAttribute attr) {
return isa<RegS1Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS1AttrGet(MlirContext ctxt) {
return wrap(RegS1Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegA0(MlirAttribute attr) {
return isa<RegA0Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegA0AttrGet(MlirContext ctxt) {
return wrap(RegA0Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegA1(MlirAttribute attr) {
return isa<RegA1Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegA1AttrGet(MlirContext ctxt) {
return wrap(RegA1Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegA2(MlirAttribute attr) {
return isa<RegA2Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegA2AttrGet(MlirContext ctxt) {
return wrap(RegA2Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegA3(MlirAttribute attr) {
return isa<RegA3Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegA3AttrGet(MlirContext ctxt) {
return wrap(RegA3Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegA4(MlirAttribute attr) {
return isa<RegA4Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegA4AttrGet(MlirContext ctxt) {
return wrap(RegA4Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegA5(MlirAttribute attr) {
return isa<RegA5Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegA5AttrGet(MlirContext ctxt) {
return wrap(RegA5Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegA6(MlirAttribute attr) {
return isa<RegA6Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegA6AttrGet(MlirContext ctxt) {
return wrap(RegA6Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegA7(MlirAttribute attr) {
return isa<RegA7Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegA7AttrGet(MlirContext ctxt) {
return wrap(RegA7Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS2(MlirAttribute attr) {
return isa<RegS2Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS2AttrGet(MlirContext ctxt) {
return wrap(RegS2Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS3(MlirAttribute attr) {
return isa<RegS3Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS3AttrGet(MlirContext ctxt) {
return wrap(RegS3Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS4(MlirAttribute attr) {
return isa<RegS4Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS4AttrGet(MlirContext ctxt) {
return wrap(RegS4Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS5(MlirAttribute attr) {
return isa<RegS5Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS5AttrGet(MlirContext ctxt) {
return wrap(RegS5Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS6(MlirAttribute attr) {
return isa<RegS6Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS6AttrGet(MlirContext ctxt) {
return wrap(RegS6Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS7(MlirAttribute attr) {
return isa<RegS7Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS7AttrGet(MlirContext ctxt) {
return wrap(RegS7Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS8(MlirAttribute attr) {
return isa<RegS8Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS8AttrGet(MlirContext ctxt) {
return wrap(RegS8Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS9(MlirAttribute attr) {
return isa<RegS9Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS9AttrGet(MlirContext ctxt) {
return wrap(RegS9Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS10(MlirAttribute attr) {
return isa<RegS10Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS10AttrGet(MlirContext ctxt) {
return wrap(RegS10Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegS11(MlirAttribute attr) {
return isa<RegS11Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegS11AttrGet(MlirContext ctxt) {
return wrap(RegS11Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegT3(MlirAttribute attr) {
return isa<RegT3Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegT3AttrGet(MlirContext ctxt) {
return wrap(RegT3Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegT4(MlirAttribute attr) {
return isa<RegT4Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegT4AttrGet(MlirContext ctxt) {
return wrap(RegT4Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegT5(MlirAttribute attr) {
return isa<RegT5Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegT5AttrGet(MlirContext ctxt) {
return wrap(RegT5Attr::get(unwrap(ctxt)));
}
bool rtgtestAttrIsARegT6(MlirAttribute attr) {
return isa<RegT6Attr>(unwrap(attr));
}
MlirAttribute rtgtestRegT6AttrGet(MlirContext ctxt) {
return wrap(RegT6Attr::get(unwrap(ctxt)));
}

View File

@ -1,6 +1,8 @@
add_circt_dialect_library(CIRCTRTGDialect
RTGAttrInterfaces.cpp
RTGDialect.cpp
RTGISAAssemblyAttrInterfaces.cpp
RTGISAAssemblyTypeInterfaces.cpp
RTGISAAssemblyOpInterfaces.cpp
RTGOpInterfaces.cpp
RTGOps.cpp
@ -13,7 +15,9 @@ add_circt_dialect_library(CIRCTRTGDialect
DEPENDS
CIRCTRTGAttrInterfacesIncGen
CIRCTRTGEnumsIncGen
CIRCTRTGISAAssemblyAttrInterfacesIncGen
CIRCTRTGISAAssemblyOpInterfacesIncGen
CIRCTRTGISAAssemblyTypeInterfacesIncGen
CIRCTRTGOpInterfacesIncGen
CIRCTRTGTypeInterfacesIncGen
MLIRRTGIncGen

View File

@ -0,0 +1,19 @@
//===- RTGISAAssemblyAttrInterfaces.cpp - Interfaces for ISA Assembly RTG -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the RTG attr interfaces specific to ISA Assembly tests.
//
//===----------------------------------------------------------------------===//
#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h"
//===----------------------------------------------------------------------===//
// TableGen generated logic.
//===----------------------------------------------------------------------===//
#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.cpp.inc"

View File

@ -0,0 +1,19 @@
//===- RTGISAAssemblyTypeInterfaces.cpp - Interfaces for ISA Assembly RTG -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the RTG type interfaces specific to ISA Assembly tests.
//
//===----------------------------------------------------------------------===//
#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h"
//===----------------------------------------------------------------------===//
// TableGen generated logic.
//===----------------------------------------------------------------------===//
#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.cpp.inc"

View File

@ -150,6 +150,66 @@ LogicalResult BagCreateOp::verify() {
return success();
}
//===----------------------------------------------------------------------===//
// FixedRegisterOp
//===----------------------------------------------------------------------===//
LogicalResult FixedRegisterOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attributes, OpaqueProperties properties, RegionRange regions,
SmallVectorImpl<Type> &inferredReturnTypes) {
inferredReturnTypes.push_back(
properties.as<Properties *>()->getReg().getType());
return success();
}
OpFoldResult FixedRegisterOp::fold(FoldAdaptor adaptor) { return getRegAttr(); }
//===----------------------------------------------------------------------===//
// VirtualRegisterOp
//===----------------------------------------------------------------------===//
LogicalResult VirtualRegisterOp::verify() {
if (getAllowedRegs().empty())
return emitOpError("must have at least one allowed register");
if (llvm::any_of(getAllowedRegs(), [](Attribute attr) {
return !isa<RegisterAttrInterface>(attr);
}))
return emitOpError("all elements must be of RegisterAttrInterface");
if (!llvm::all_equal(
llvm::map_range(getAllowedRegs().getAsRange<RegisterAttrInterface>(),
[](auto attr) { return attr.getType(); })))
return emitOpError("all allowed registers must be of the same type");
return success();
}
LogicalResult VirtualRegisterOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attributes, OpaqueProperties properties, RegionRange regions,
SmallVectorImpl<Type> &inferredReturnTypes) {
auto allowedRegs = properties.as<Properties *>()->getAllowedRegs();
if (allowedRegs.empty()) {
if (loc)
return mlir::emitError(*loc, "must have at least one allowed register");
return failure();
}
auto regAttr = dyn_cast<RegisterAttrInterface>(allowedRegs[0]);
if (!regAttr) {
if (loc)
return mlir::emitError(
*loc, "allowed register attributes must be of RegisterAttrInterface");
return failure();
}
inferredReturnTypes.push_back(regAttr.getType());
return success();
}
//===----------------------------------------------------------------------===//
// TestOp
//===----------------------------------------------------------------------===//

View File

@ -674,7 +674,6 @@ class Elaborator : public RTGOpVisitor<Elaborator, FailureOr<DeletionKind>> {
public:
using RTGBase = RTGOpVisitor<Elaborator, FailureOr<DeletionKind>>;
using RTGBase::visitOp;
using RTGBase::visitRegisterOp;
Elaborator(ElaboratorSharedState &sharedState, Materializer &materializer)
: sharedState(sharedState), materializer(materializer) {}

View File

@ -33,53 +33,6 @@ mlir::OpFoldResult ConstantTestOp::fold(FoldAdaptor adaptor) {
return getValueAttr();
}
//===----------------------------------------------------------------------===//
// RegisterOp
//===----------------------------------------------------------------------===//
LogicalResult RegisterOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> location, ValueRange operands,
DictionaryAttr attributes, OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &inferredReturnTypes) {
Registers reg = properties.as<Properties *>()->getReg().getValue();
if (static_cast<uint32_t>(reg) >= 32 && reg != Registers::Virtual) {
if (location)
return mlir::emitError(*location) << "unsupported register";
return failure();
}
inferredReturnTypes.push_back(IntegerRegisterType::get(context));
return success();
}
unsigned RegisterOp::getClassIndex() { return static_cast<uint32_t>(getReg()); }
APInt RegisterOp::getClassIndexBinary() { return APInt(5, getClassIndex()); }
std::string RegisterOp::getRegisterAssembly() {
return stringifyRegisters(getReg()).str();
}
llvm::BitVector RegisterOp::getAllowedRegs() {
llvm::BitVector retval(getMaxEnumValForRegisters(), false);
if (getReg() == Registers::Virtual)
return retval.set(0, 32);
return retval.set(static_cast<uint32_t>(getReg()));
}
unsigned RegisterOp::getFixedReg() {
if (getReg() == Registers::Virtual)
return ~0U;
return static_cast<uint32_t>(getReg());
}
void RegisterOp::setFixedReg(unsigned reg) {
auto sym = symbolizeRegisters(reg);
assert(sym.has_value() && sym.value() != Registers::Virtual);
setReg(sym.value());
}
//===----------------------------------------------------------------------===//
// TableGen generated logic.
//===----------------------------------------------------------------------===//

View File

@ -32,12 +32,241 @@ static void testCPUAttr(MlirContext ctx) {
mlirAttributeDump(cpuAttr);
}
static void testRegisters(MlirContext ctx) {
{
MlirAttribute regAttr = rtgtestRegZeroAttrGet(ctx);
// CHECK: is_zero
fprintf(stderr,
rtgtestAttrIsARegZero(regAttr) ? "is_zero\n" : "isnot_zero\n");
// CHECK: #rtgtest.zero
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegRaAttrGet(ctx);
// CHECK: is_ra
fprintf(stderr, rtgtestAttrIsARegRa(regAttr) ? "is_ra\n" : "isnot_ra\n");
// CHECK: #rtgtest.ra
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegSpAttrGet(ctx);
// CHECK: is_sp
fprintf(stderr, rtgtestAttrIsARegSp(regAttr) ? "is_sp\n" : "isnot_sp\n");
// CHECK: #rtgtest.sp
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegGpAttrGet(ctx);
// CHECK: is_gp
fprintf(stderr, rtgtestAttrIsARegGp(regAttr) ? "is_gp\n" : "isnot_gp\n");
// CHECK: #rtgtest.gp
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegTpAttrGet(ctx);
// CHECK: is_tp
fprintf(stderr, rtgtestAttrIsARegTp(regAttr) ? "is_tp\n" : "isnot_tp\n");
// CHECK: #rtgtest.tp
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegT0AttrGet(ctx);
// CHECK: is_t0
fprintf(stderr, rtgtestAttrIsARegT0(regAttr) ? "is_t0\n" : "isnot_t0\n");
// CHECK: #rtgtest.t0
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegT1AttrGet(ctx);
// CHECK: is_t1
fprintf(stderr, rtgtestAttrIsARegT1(regAttr) ? "is_t1\n" : "isnot_t1\n");
// CHECK: #rtgtest.t1
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegT2AttrGet(ctx);
// CHECK: is_t2
fprintf(stderr, rtgtestAttrIsARegT2(regAttr) ? "is_t2\n" : "isnot_t2\n");
// CHECK: #rtgtest.t2
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS0AttrGet(ctx);
// CHECK: is_s0
fprintf(stderr, rtgtestAttrIsARegS0(regAttr) ? "is_s0\n" : "isnot_s0\n");
// CHECK: #rtgtest.s0
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS1AttrGet(ctx);
// CHECK: is_s1
fprintf(stderr, rtgtestAttrIsARegS1(regAttr) ? "is_s1\n" : "isnot_s1\n");
// CHECK: #rtgtest.s1
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegA0AttrGet(ctx);
// CHECK: is_a0
fprintf(stderr, rtgtestAttrIsARegA0(regAttr) ? "is_a0\n" : "isnot_a0\n");
// CHECK: #rtgtest.a0
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegA1AttrGet(ctx);
// CHECK: is_a1
fprintf(stderr, rtgtestAttrIsARegA1(regAttr) ? "is_a1\n" : "isnot_a1\n");
// CHECK: #rtgtest.a1
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegA2AttrGet(ctx);
// CHECK: is_a2
fprintf(stderr, rtgtestAttrIsARegA2(regAttr) ? "is_a2\n" : "isnot_a2\n");
// CHECK: #rtgtest.a2
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegA3AttrGet(ctx);
// CHECK: is_a3
fprintf(stderr, rtgtestAttrIsARegA3(regAttr) ? "is_a3\n" : "isnot_a3\n");
// CHECK: #rtgtest.a3
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegA4AttrGet(ctx);
// CHECK: is_a4
fprintf(stderr, rtgtestAttrIsARegA4(regAttr) ? "is_a4\n" : "isnot_a4\n");
// CHECK: #rtgtest.a4
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegA5AttrGet(ctx);
// CHECK: is_a5
fprintf(stderr, rtgtestAttrIsARegA5(regAttr) ? "is_a5\n" : "isnot_a5\n");
// CHECK: #rtgtest.a5
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegA6AttrGet(ctx);
// CHECK: is_a6
fprintf(stderr, rtgtestAttrIsARegA6(regAttr) ? "is_a6\n" : "isnot_a6\n");
// CHECK: #rtgtest.a6
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegA7AttrGet(ctx);
// CHECK: is_a7
fprintf(stderr, rtgtestAttrIsARegA7(regAttr) ? "is_a7\n" : "isnot_a7\n");
// CHECK: #rtgtest.a7
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS2AttrGet(ctx);
// CHECK: is_s2
fprintf(stderr, rtgtestAttrIsARegS2(regAttr) ? "is_s2\n" : "isnot_s2\n");
// CHECK: #rtgtest.s2
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS3AttrGet(ctx);
// CHECK: is_s3
fprintf(stderr, rtgtestAttrIsARegS3(regAttr) ? "is_s3\n" : "isnot_s3\n");
// CHECK: #rtgtest.s3
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS4AttrGet(ctx);
// CHECK: is_s4
fprintf(stderr, rtgtestAttrIsARegS4(regAttr) ? "is_s4\n" : "isnot_s4\n");
// CHECK: #rtgtest.s4
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS5AttrGet(ctx);
// CHECK: is_s5
fprintf(stderr, rtgtestAttrIsARegS5(regAttr) ? "is_s5\n" : "isnot_s5\n");
// CHECK: #rtgtest.s5
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS6AttrGet(ctx);
// CHECK: is_s6
fprintf(stderr, rtgtestAttrIsARegS6(regAttr) ? "is_s6\n" : "isnot_s6\n");
// CHECK: #rtgtest.s6
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS7AttrGet(ctx);
// CHECK: is_s7
fprintf(stderr, rtgtestAttrIsARegS7(regAttr) ? "is_s7\n" : "isnot_s7\n");
// CHECK: #rtgtest.s7
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS8AttrGet(ctx);
// CHECK: is_s8
fprintf(stderr, rtgtestAttrIsARegS8(regAttr) ? "is_s8\n" : "isnot_s8\n");
// CHECK: #rtgtest.s8
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS9AttrGet(ctx);
// CHECK: is_s9
fprintf(stderr, rtgtestAttrIsARegS9(regAttr) ? "is_s9\n" : "isnot_s9\n");
// CHECK: #rtgtest.s9
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS10AttrGet(ctx);
// CHECK: is_s10
fprintf(stderr, rtgtestAttrIsARegS10(regAttr) ? "is_s10\n" : "isnot_s10\n");
// CHECK: #rtgtest.s10
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegS11AttrGet(ctx);
// CHECK: is_s11
fprintf(stderr, rtgtestAttrIsARegS11(regAttr) ? "is_s11\n" : "isnot_s11\n");
// CHECK: #rtgtest.s11
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegT3AttrGet(ctx);
// CHECK: is_t3
fprintf(stderr, rtgtestAttrIsARegT3(regAttr) ? "is_t3\n" : "isnot_t3\n");
// CHECK: #rtgtest.t3
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegT4AttrGet(ctx);
// CHECK: is_t4
fprintf(stderr, rtgtestAttrIsARegT4(regAttr) ? "is_t4\n" : "isnot_t4\n");
// CHECK: #rtgtest.t4
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegT5AttrGet(ctx);
// CHECK: is_t5
fprintf(stderr, rtgtestAttrIsARegT5(regAttr) ? "is_t5\n" : "isnot_t5\n");
// CHECK: #rtgtest.t5
mlirAttributeDump(regAttr);
}
{
MlirAttribute regAttr = rtgtestRegT6AttrGet(ctx);
// CHECK: is_t6
fprintf(stderr, rtgtestAttrIsARegT6(regAttr) ? "is_t6\n" : "isnot_t6\n");
// CHECK: #rtgtest.t6
mlirAttributeDump(regAttr);
}
}
int main(int argc, char **argv) {
MlirContext ctx = mlirContextCreate();
mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtgtest__(), ctx);
testCPUType(ctx);
testCPUAttr(ctx);
testRegisters(ctx);
mlirContextDestroy(ctx);

View File

@ -1,4 +1,4 @@
// RUN: circt-opt %s | FileCheck %s
// RUN: circt-opt %s --split-input-file --verify-diagnostics | FileCheck %s
// CHECK-LABEL: @cpus
// CHECK-SAME: !rtgtest.cpu
@ -17,70 +17,85 @@ rtg.test @misc : !rtg.dict<> {
// CHECK-SAME: !rtgtest.ireg
rtg.test @registers : !rtg.dict<reg: !rtgtest.ireg> {
^bb0(%reg: !rtgtest.ireg):
// CHECK: rtgtest.reg zero
// CHECK: rtgtest.reg ra
// CHECK: rtgtest.reg sp
// CHECK: rtgtest.reg gp
// CHECK: rtgtest.reg tp
// CHECK: rtgtest.reg t0
// CHECK: rtgtest.reg t1
// CHECK: rtgtest.reg t2
// CHECK: rtgtest.reg s0
// CHECK: rtgtest.reg s1
// CHECK: rtgtest.reg a0
// CHECK: rtgtest.reg a1
// CHECK: rtgtest.reg a2
// CHECK: rtgtest.reg a3
// CHECK: rtgtest.reg a4
// CHECK: rtgtest.reg a5
// CHECK: rtgtest.reg a6
// CHECK: rtgtest.reg a7
// CHECK: rtgtest.reg s2
// CHECK: rtgtest.reg s3
// CHECK: rtgtest.reg s4
// CHECK: rtgtest.reg s5
// CHECK: rtgtest.reg s6
// CHECK: rtgtest.reg s7
// CHECK: rtgtest.reg s8
// CHECK: rtgtest.reg s9
// CHECK: rtgtest.reg s10
// CHECK: rtgtest.reg s11
// CHECK: rtgtest.reg t3
// CHECK: rtgtest.reg t4
// CHECK: rtgtest.reg t5
// CHECK: rtgtest.reg t6
// CHECK: rtgtest.reg Virtual
%1 = rtgtest.reg zero
%2 = rtgtest.reg ra
%3 = rtgtest.reg sp
%4 = rtgtest.reg gp
%5 = rtgtest.reg tp
%6 = rtgtest.reg t0
%7 = rtgtest.reg t1
%8 = rtgtest.reg t2
%9 = rtgtest.reg s0
%10 = rtgtest.reg s1
%11 = rtgtest.reg a0
%12 = rtgtest.reg a1
%13 = rtgtest.reg a2
%14 = rtgtest.reg a3
%15 = rtgtest.reg a4
%16 = rtgtest.reg a5
%17 = rtgtest.reg a6
%18 = rtgtest.reg a7
%19 = rtgtest.reg s2
%20 = rtgtest.reg s3
%21 = rtgtest.reg s4
%22 = rtgtest.reg s5
%23 = rtgtest.reg s6
%24 = rtgtest.reg s7
%25 = rtgtest.reg s8
%26 = rtgtest.reg s9
%27 = rtgtest.reg s10
%28 = rtgtest.reg s11
%29 = rtgtest.reg t3
%30 = rtgtest.reg t4
%31 = rtgtest.reg t5
%32 = rtgtest.reg t6
%33 = rtgtest.reg Virtual
// CHECK: rtg.fixed_reg #rtgtest.zero : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.ra : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.sp : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.gp : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.tp : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.t0 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.t1 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.t2 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s0 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s1 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.a0 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.a1 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.a2 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.a3 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.a4 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.a5 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.a6 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.a7 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s2 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s3 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s4 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s5 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s6 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s7 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s8 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s9 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s10 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.s11 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.t3 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.t4 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.t5 : !rtgtest.ireg
// CHECK: rtg.fixed_reg #rtgtest.t6 : !rtgtest.ireg
rtg.fixed_reg #rtgtest.zero
rtg.fixed_reg #rtgtest.ra
rtg.fixed_reg #rtgtest.sp
rtg.fixed_reg #rtgtest.gp
rtg.fixed_reg #rtgtest.tp
rtg.fixed_reg #rtgtest.t0
rtg.fixed_reg #rtgtest.t1
rtg.fixed_reg #rtgtest.t2
rtg.fixed_reg #rtgtest.s0
rtg.fixed_reg #rtgtest.s1
rtg.fixed_reg #rtgtest.a0
rtg.fixed_reg #rtgtest.a1
rtg.fixed_reg #rtgtest.a2
rtg.fixed_reg #rtgtest.a3
rtg.fixed_reg #rtgtest.a4
rtg.fixed_reg #rtgtest.a5
rtg.fixed_reg #rtgtest.a6
rtg.fixed_reg #rtgtest.a7
rtg.fixed_reg #rtgtest.s2
rtg.fixed_reg #rtgtest.s3
rtg.fixed_reg #rtgtest.s4
rtg.fixed_reg #rtgtest.s5
rtg.fixed_reg #rtgtest.s6
rtg.fixed_reg #rtgtest.s7
rtg.fixed_reg #rtgtest.s8
rtg.fixed_reg #rtgtest.s9
rtg.fixed_reg #rtgtest.s10
rtg.fixed_reg #rtgtest.s11
rtg.fixed_reg #rtgtest.t3
rtg.fixed_reg #rtgtest.t4
rtg.fixed_reg #rtgtest.t5
rtg.fixed_reg #rtgtest.t6
// CHECK: rtg.virtual_reg [#rtgtest.ra : !rtgtest.ireg, #rtgtest.sp : !rtgtest.ireg]
rtg.virtual_reg [#rtgtest.ra, #rtgtest.sp]
}
// -----
rtg.test @emptyAllowed : !rtg.dict<> {
// expected-error @below {{must have at least one allowed register}}
rtg.virtual_reg []
}
// -----
rtg.test @invalidAllowedAttr : !rtg.dict<> {
// expected-error @below {{allowed register attributes must be of RegisterAttrInterface}}
rtg.virtual_reg ["invalid"]
}

View File

@ -3,5 +3,4 @@ add_subdirectory(FIRRTL)
add_subdirectory(ESI)
add_subdirectory(HW)
add_subdirectory(OM)
add_subdirectory(RTGTest)
add_subdirectory(SMT)

View File

@ -1,8 +0,0 @@
add_circt_unittest(CIRCTRTGTestTests
RegisterTest.cpp
)
target_link_libraries(CIRCTRTGTestTests
PRIVATE
CIRCTRTGTestDialect
)

View File

@ -1,59 +0,0 @@
//===- RegisterTest.cpp - RTGTest register unit tests ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "circt/Dialect/RTGTest/IR/RTGTestOps.h"
#include "gtest/gtest.h"
using namespace mlir;
using namespace circt;
using namespace rtgtest;
namespace {
TEST(RegisterInterfaceTest, IntegerRegisters) {
MLIRContext context;
context.loadDialect<RTGTestDialect>();
Location loc(UnknownLoc::get(&context));
SmallVector<std::tuple<Registers, std::string, unsigned>> regs{
{Registers::zero, "zero", 0}, {Registers::ra, "ra", 1},
{Registers::sp, "sp", 2}, {Registers::gp, "gp", 3},
{Registers::tp, "tp", 4}, {Registers::t0, "t0", 5},
{Registers::t1, "t1", 6}, {Registers::t2, "t2", 7},
{Registers::s0, "s0", 8}, {Registers::s1, "s1", 9},
{Registers::a0, "a0", 10}, {Registers::a1, "a1", 11},
{Registers::a2, "a2", 12}, {Registers::a3, "a3", 13},
{Registers::a4, "a4", 14}, {Registers::a5, "a5", 15},
{Registers::a6, "a6", 16}, {Registers::a7, "a7", 17},
{Registers::s2, "s2", 18}, {Registers::s3, "s3", 19},
{Registers::s4, "s4", 20}, {Registers::s5, "s5", 21},
{Registers::s6, "s6", 22}, {Registers::s7, "s7", 23},
{Registers::s8, "s8", 24}, {Registers::s9, "s9", 25},
{Registers::s10, "s10", 26}, {Registers::s11, "s11", 27},
{Registers::t3, "t3", 28}, {Registers::t4, "t4", 29},
{Registers::t5, "t5", 30}, {Registers::t6, "t6", 31}};
auto moduleOp = ModuleOp::create(loc);
OpBuilder builder = OpBuilder::atBlockBegin(moduleOp.getBody());
auto regOp = builder.create<RegisterOp>(loc, Registers::Virtual);
ASSERT_EQ(regOp.getAllowedRegs(),
llvm::BitVector(getMaxEnumValForRegisters(), true));
ASSERT_EQ(regOp.getFixedReg(), ~0U);
for (auto [reg, str, idx] : regs) {
regOp.setFixedReg(idx);
ASSERT_EQ(regOp.getClassIndex(), idx);
ASSERT_EQ(regOp.getClassIndexBinary(), APInt(5, idx));
ASSERT_EQ(regOp.getRegisterAssembly(), str);
ASSERT_EQ(regOp.getAllowedRegs(),
llvm::BitVector(getMaxEnumValForRegisters(), false).set(idx));
ASSERT_EQ(regOp.getFixedReg(), idx);
}
}
} // namespace