Skip to content

Commit c2a37e4

Browse files
authored
[clang][bytecode] Implement fixed point casts (#110409)
1 parent 26df43f commit c2a37e4

File tree

5 files changed

+48
-0
lines changed

5 files changed

+48
-0
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,14 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
697697
const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
698698
return this->emitCastFixedPointFloating(TargetSemantics, CE);
699699
}
700+
case CK_FixedPointCast: {
701+
if (!this->visit(SubExpr))
702+
return false;
703+
auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType());
704+
uint32_t I;
705+
std::memcpy(&I, &Sem, sizeof(Sem));
706+
return this->emitCastFixedPoint(I, CE);
707+
}
700708

701709
case CK_ToVoid:
702710
return discard(SubExpr);

clang/lib/AST/ByteCode/FixedPoint.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ class FixedPoint final {
6161

6262
FixedPoint truncate(unsigned BitWidth) const { return *this; }
6363

64+
FixedPoint toSemantics(const llvm::FixedPointSemantics &Sem,
65+
bool *Overflow) const {
66+
return FixedPoint(V.convert(Sem, Overflow));
67+
}
68+
6469
llvm::APFloat toFloat(const llvm::fltSemantics *Sem) const {
6570
return V.convertToFloat(*Sem);
6671
}

clang/lib/AST/ByteCode/Interp.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,31 @@ inline bool CastFP(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem,
21612161
return true;
21622162
}
21632163

2164+
inline bool CastFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS) {
2165+
FixedPointSemantics TargetSemantics(0, 0, false, false, false);
2166+
std::memcpy(&TargetSemantics, &FPS, sizeof(TargetSemantics));
2167+
2168+
const auto &Source = S.Stk.pop<FixedPoint>();
2169+
2170+
bool Overflow;
2171+
FixedPoint Result = Source.toSemantics(TargetSemantics, &Overflow);
2172+
2173+
if (Overflow) {
2174+
const Expr *E = S.Current->getExpr(OpPC);
2175+
if (S.checkingForUndefinedBehavior()) {
2176+
S.getASTContext().getDiagnostics().Report(
2177+
E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
2178+
<< Result.toDiagnosticString(S.getASTContext()) << E->getType();
2179+
}
2180+
S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType();
2181+
if (!S.noteUndefinedBehavior())
2182+
return false;
2183+
}
2184+
2185+
S.Stk.push<FixedPoint>(Result);
2186+
return true;
2187+
}
2188+
21642189
/// Like Cast(), but we cast to an arbitrary-bitwidth integral, so we need
21652190
/// to know what bitwidth the result should be.
21662191
template <PrimType Name, class T = typename PrimConv<Name>::T>

clang/lib/AST/ByteCode/Opcodes.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,10 @@ def CastFP : Opcode {
626626
let Args = [ArgFltSemantics, ArgRoundingMode];
627627
}
628628

629+
def CastFixedPoint : Opcode {
630+
let Args = [ArgUint32];
631+
}
632+
629633
def FixedSizeIntegralTypes : TypeClass {
630634
let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
631635
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,9 @@ namespace BinOps {
4747
// ref-error {{is not an integral constant expression}} \
4848
// ref-note {{is outside the range of representable values}}
4949
}
50+
51+
namespace FixedPointCasts {
52+
constexpr _Fract B = 0.3;
53+
constexpr _Accum A = B;
54+
constexpr _Fract C = A;
55+
}

0 commit comments

Comments
 (0)