15 #include "mlir/IR/Builders.h"
16 #include "mlir/IR/PatternMatch.h"
17 #include "llvm/ADT/APSInt.h"
19 using namespace circt;
24 #include "circt/Dialect/HWArith/HWArithCanonicalizations.h.inc"
34 auto inType = getIn().getType();
35 auto outType = getOut().getType();
39 if (isInSignless && isOutSignless)
40 return emitError(
"at least one type needs to carry sign semantics (ui/si)");
43 unsigned inBitWidth = inType.getIntOrFloatBitWidth();
44 unsigned outBitWidth = outType.getIntOrFloatBitWidth();
45 if (inBitWidth < outBitWidth)
46 return emitError(
"bit extension is undefined for a signless type");
52 void CastOp::getCanonicalizationPatterns(RewritePatternSet &results,
53 MLIRContext *context) {
54 results.insert<EliminateCast>(context);
63 OpFoldResult ConstantOp::fold(FoldAdaptor adaptor) {
64 assert(adaptor.getOperands().empty() &&
"constant has no operands");
65 return getRawValueAttr();
68 void ConstantOp::print(OpAsmPrinter &p) {
70 p.printAttribute(getRawValueAttr());
71 p.printOptionalAttrDict(getOperation()->getAttrs(),
72 {getRawValueAttrName()});
75 ParseResult ConstantOp::parse(OpAsmParser &parser, OperationState &result) {
76 IntegerAttr valueAttr;
78 if (parser.parseAttribute(valueAttr, getRawValueAttrName(result.name),
80 parser.parseOptionalAttrDict(result.attributes))
83 result.addTypes(valueAttr.getType());
91 LogicalResult AddOp::inferReturnTypes(MLIRContext *context,
92 std::optional<Location> loc,
93 ValueRange operands, DictionaryAttr attrs,
94 mlir::OpaqueProperties properties,
95 mlir::RegionRange regions,
96 SmallVectorImpl<Type> &results) {
97 auto lhs = cast<IntegerType>(operands[0].getType());
98 auto rhs = cast<IntegerType>(operands[1].getType());
99 IntegerType::SignednessSemantics signedness;
110 LogicalResult SubOp::inferReturnTypes(MLIRContext *context,
111 std::optional<Location> loc,
112 ValueRange operands, DictionaryAttr attrs,
113 mlir::OpaqueProperties properties,
114 mlir::RegionRange regions,
115 SmallVectorImpl<Type> &results) {
116 auto lhs = cast<IntegerType>(operands[0].getType());
117 auto rhs = cast<IntegerType>(operands[1].getType());
120 IntegerType::SignednessSemantics signedness;
122 signedness = IntegerType::Signed;
132 static IntegerType::SignednessSemantics
135 if (lhs.getSignedness() == rhs.getSignedness()) {
137 return lhs.getSignedness();
140 return IntegerType::Signed;
144 LogicalResult MulOp::inferReturnTypes(MLIRContext *context,
145 std::optional<Location> loc,
146 ValueRange operands, DictionaryAttr attrs,
147 mlir::OpaqueProperties properties,
148 mlir::RegionRange regions,
149 SmallVectorImpl<Type> &results) {
150 auto lhs = cast<IntegerType>(operands[0].getType());
151 auto rhs = cast<IntegerType>(operands[1].getType());
153 unsigned resultWidth = lhs.getWidth() + rhs.getWidth();
154 IntegerType::SignednessSemantics signedness =
165 LogicalResult DivOp::inferReturnTypes(MLIRContext *context,
166 std::optional<Location> loc,
167 ValueRange operands, DictionaryAttr attrs,
168 mlir::OpaqueProperties properties,
169 mlir::RegionRange regions,
170 SmallVectorImpl<Type> &results) {
171 auto lhs = cast<IntegerType>(operands[0].getType());
172 auto rhs = cast<IntegerType>(operands[1].getType());
174 unsigned resultWidth = lhs.getWidth();
180 IntegerType::SignednessSemantics signedness =
195 IntegerType lhs, IntegerType rhs) {
197 unsigned resultWidth = std::max(lhs.getWidth(), rhs.getWidth()) + 1;
199 if (lhs.getSignedness() == rhs.getSignedness()) {
202 signedness = lhs.getSignedness();
205 signedness = IntegerType::Signed;
208 if ((lhs.isUnsigned() && lhs.getWidth() >= rhs.getWidth()) ||
209 (rhs.isUnsigned() && rhs.getWidth() >= lhs.getWidth())) {
221 auto ops = binOp->getOperands();
223 return binOp->emitError() <<
"expected 2 operands but got " << ops.size();
236 #define GET_OP_CLASSES
237 #include "circt/Dialect/HWArith/HWArith.cpp.inc"
assert(baseType &&"element must be base type")
static std::optional< APInt > getConstantValue(Value value)
static IntegerType::SignednessSemantics getSignedInheritedSignedness(IntegerType lhs, IntegerType rhs)
static LogicalResult verify(Value clock, bool eventExists, mlir::Location loc)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
static LogicalResult verifyBinOp(Operation *binOp)
bool isHWArithIntegerType(::mlir::Type type)
unsigned inferAddResultType(IntegerType::SignednessSemantics &signedness, IntegerType lhs, IntegerType rhs)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.