mirror of https://github.com/llvm/circt.git
107 lines
3.2 KiB
C++
107 lines
3.2 KiB
C++
//===- FIRRTLAttributes.cpp - Implement FIRRTL dialect attributes ---------===//
|
|
//
|
|
// 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/FIRRTL/FIRRTLAttributes.h"
|
|
#include "circt/Dialect/FIRRTL/FIRRTLTypes.h"
|
|
|
|
#include "mlir/IR/Builders.h"
|
|
#include "mlir/IR/DialectImplementation.h"
|
|
#include "llvm/ADT/TypeSwitch.h"
|
|
#include <iterator>
|
|
|
|
using namespace circt;
|
|
using namespace firrtl;
|
|
|
|
#define GET_ATTRDEF_CLASSES
|
|
#include "circt/Dialect/FIRRTL/FIRRTLAttributes.cpp.inc"
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Utilities related to Direction
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
Direction direction::flip(Direction direction) {
|
|
switch (direction) {
|
|
case Direction::In:
|
|
return Direction::Out;
|
|
case Direction::Out:
|
|
return Direction::In;
|
|
}
|
|
llvm_unreachable("unknown direction");
|
|
}
|
|
|
|
IntegerAttr direction::packAttribute(MLIRContext *context,
|
|
ArrayRef<Direction> directions) {
|
|
// Pack the array of directions into an APInt. Input is zero, output is one.
|
|
auto size = directions.size();
|
|
APInt portDirections(size, 0);
|
|
for (size_t i = 0; i != size; ++i)
|
|
if (directions[i] == Direction::Out)
|
|
portDirections.setBit(i);
|
|
return IntegerAttr::get(IntegerType::get(context, size), portDirections);
|
|
}
|
|
|
|
SmallVector<Direction> direction::unpackAttribute(IntegerAttr directions) {
|
|
assert(directions.getType().isSignlessInteger() &&
|
|
"Direction attributes must be signless integers");
|
|
auto value = directions.getValue();
|
|
auto size = value.getBitWidth();
|
|
SmallVector<Direction> result;
|
|
result.reserve(size);
|
|
for (size_t i = 0; i != size; ++i)
|
|
result.push_back(direction::get(value[i]));
|
|
return result;
|
|
}
|
|
|
|
llvm::raw_ostream &circt::firrtl::operator<<(llvm::raw_ostream &os,
|
|
const Direction &dir) {
|
|
return os << direction::toString(dir);
|
|
}
|
|
|
|
void FIRRTLDialect::registerAttributes() {
|
|
addAttributes<
|
|
#define GET_ATTRDEF_LIST
|
|
#include "circt/Dialect/FIRRTL/FIRRTLAttributes.cpp.inc"
|
|
>();
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ParamDeclAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
Attribute ParamDeclAttr::parse(AsmParser &p, Type trailing) {
|
|
std::string name;
|
|
Type type;
|
|
TypedAttr value;
|
|
// < "FOO" : i32 > : i32
|
|
// < "FOO" : i32 = 0 > : i32
|
|
// < "FOO" : none >
|
|
if (p.parseLess() || p.parseString(&name) || p.parseColonType(type))
|
|
return Attribute();
|
|
|
|
if (succeeded(p.parseOptionalEqual())) {
|
|
if (p.parseAttribute(value, type))
|
|
return Attribute();
|
|
}
|
|
|
|
if (p.parseGreater())
|
|
return Attribute();
|
|
|
|
if (value)
|
|
return ParamDeclAttr::get(name, value);
|
|
return ParamDeclAttr::get(name, type);
|
|
}
|
|
|
|
void ParamDeclAttr::print(AsmPrinter &p) const {
|
|
p << "<" << getName() << ": " << getType();
|
|
if (getValue()) {
|
|
p << " = ";
|
|
p.printAttributeWithoutType(getValue());
|
|
}
|
|
p << ">";
|
|
}
|