Skip to content

Commit defead4

Browse files
authored
[clang][bytecode] Implement fixed-point add (llvm#110405)
1 parent 31dd29c commit defead4

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,9 @@ bool Compiler<Emitter>::VisitFixedPointBinOp(const BinaryOperator *E) {
15281528
case BO_GE:
15291529
return this->emitGEFixedPoint(E);
15301530
#endif
1531+
case BO_Add:
1532+
return this->emitAddFixedPoint(E);
1533+
15311534
default:
15321535
return this->emitInvalid(E);
15331536
}

clang/lib/AST/ByteCode/FixedPoint.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,28 @@ class FixedPoint final {
4747
void print(llvm::raw_ostream &OS) const { OS << V; }
4848

4949
APValue toAPValue(const ASTContext &) const { return APValue(V); }
50-
APSInt toAPSInt(unsigned BitWidth) const { return V.getValue(); }
50+
APSInt toAPSInt(unsigned BitWidth = 0) const { return V.getValue(); }
5151

5252
unsigned bitWidth() const { return V.getWidth(); }
5353
bool isSigned() const { return V.isSigned(); }
54+
bool isZero() const { return V.getValue().isZero(); }
55+
bool isNegative() const { return V.getValue().isNegative(); }
56+
bool isPositive() const { return V.getValue().isNonNegative(); }
57+
bool isMin() const {
58+
return V.getValue() == APSInt::getMinValue(V.getSemantics().getWidth(),
59+
!V.getSemantics().isSigned());
60+
}
61+
62+
FixedPoint truncate(unsigned BitWidth) const { return *this; }
5463

5564
llvm::APFloat toFloat(const llvm::fltSemantics *Sem) const {
5665
return V.convertToFloat(*Sem);
5766
}
5867

68+
std::string toDiagnosticString(const ASTContext &Ctx) const {
69+
return V.toString();
70+
}
71+
5972
ComparisonCategoryResult compare(const FixedPoint &Other) const {
6073
if (Other.V == V)
6174
return ComparisonCategoryResult::Equal;
@@ -67,6 +80,27 @@ class FixedPoint final {
6780
*R = FixedPoint(A.V.negate(&Overflow));
6881
return Overflow;
6982
}
83+
84+
static bool add(const FixedPoint A, const FixedPoint B, unsigned Bits,
85+
FixedPoint *R) {
86+
bool Overflow = false;
87+
*R = FixedPoint(A.V.add(B.V, &Overflow));
88+
return Overflow;
89+
}
90+
static bool sub(const FixedPoint A, const FixedPoint B, unsigned Bits,
91+
FixedPoint *R) {
92+
return true;
93+
}
94+
static bool mul(const FixedPoint A, const FixedPoint B, unsigned Bits,
95+
FixedPoint *R) {
96+
return true;
97+
}
98+
static bool div(const FixedPoint A, const FixedPoint B, unsigned Bits,
99+
FixedPoint *R) {
100+
return true;
101+
}
102+
static bool increment(const FixedPoint &A, FixedPoint *R) { return true; }
103+
static bool decrement(const FixedPoint &A, FixedPoint *R) { return true; }
70104
};
71105

72106
inline FixedPoint getSwappedBytes(FixedPoint F) { return F; }

clang/lib/AST/ByteCode/Opcodes.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def FloatTypeClass : TypeClass {
9898
}
9999

100100
def AluTypeClass : TypeClass {
101-
let Types = !listconcat(IntegerTypeClass.Types, [Bool]);
101+
let Types = !listconcat(IntegerTypeClass.Types, [Bool], [FixedPoint]);
102102
}
103103

104104
def PtrTypeClass : TypeClass {
@@ -110,7 +110,7 @@ def NonPtrTypeClass : TypeClass {
110110
}
111111

112112
def AllTypeClass : TypeClass {
113-
let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types, FloatTypeClass.Types, [FixedPoint]);
113+
let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types, FloatTypeClass.Types);
114114
}
115115

116116
def ComparableTypeClass : TypeClass {

clang/test/AST/ByteCode/fixed-point.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,15 @@ namespace FloatToFixedPointCast {
3535
constexpr float sf2f = sf2;
3636
static_assert(sf2f == 0.5);
3737
}
38+
39+
namespace BinOps {
40+
constexpr _Accum A = 13;
41+
static_assert(A + 1 == 14.0k);
42+
static_assert(1 + A == 14.0k);
43+
static_assert((A + A) == 26);
44+
45+
/// FIXME: Conversion between fixed point semantics.
46+
static_assert(A + 100000 == 14.0k); // expected-error {{static assertion failed}} \
47+
// ref-error {{is not an integral constant expression}} \
48+
// ref-note {{is outside the range of representable values}}
49+
}

0 commit comments

Comments
 (0)