diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp index 3f2bc46664a4ae..19e2416c4c9422 100644 --- a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp +++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp @@ -332,6 +332,12 @@ void emit(Program &P, std::vector &Code, const IntegralAP &Val, emitSerialized(Code, Val, Success); } +template <> +void emit(Program &P, std::vector &Code, const FixedPoint &Val, + bool &Success) { + emitSerialized(Code, Val, Success); +} + template bool ByteCodeEmitter::emitOp(Opcode Op, const Tys &...Args, const SourceInfo &SI) { diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp index 1aba778eaf7b90..3c55c884a3507c 100644 --- a/clang/lib/AST/ByteCode/Disasm.cpp +++ b/clang/lib/AST/ByteCode/Disasm.cpp @@ -62,6 +62,12 @@ inline IntegralAP ReadArg>(Program &P, CodePtr &OpPC) { return I; } +template <> inline FixedPoint ReadArg(Program &P, CodePtr &OpPC) { + FixedPoint I = FixedPoint::deserialize(*OpPC); + OpPC += align(I.bytesToSerialize()); + return I; +} + LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); } LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const { diff --git a/clang/lib/AST/ByteCode/FixedPoint.h b/clang/lib/AST/ByteCode/FixedPoint.h index ab8d6d7f02b52f..fcb3c79cc10978 100644 --- a/clang/lib/AST/ByteCode/FixedPoint.h +++ b/clang/lib/AST/ByteCode/FixedPoint.h @@ -91,6 +91,32 @@ class FixedPoint final { return ComparisonCategoryResult::Greater; } + size_t bytesToSerialize() const { + return sizeof(uint32_t) + (V.getValue().getBitWidth() / CHAR_BIT); + } + + void serialize(std::byte *Buff) const { + // Semantics followed by APInt. + uint32_t SemI = V.getSemantics().toOpaqueInt(); + std::memcpy(Buff, &SemI, sizeof(SemI)); + + llvm::APInt API = V.getValue(); + llvm::StoreIntToMemory(API, (uint8_t *)(Buff + sizeof(SemI)), + bitWidth() / 8); + } + + static FixedPoint deserialize(const std::byte *Buff) { + auto Sem = llvm::FixedPointSemantics::getFromOpaqueInt( + *reinterpret_cast(Buff)); + unsigned BitWidth = Sem.getWidth(); + APInt I(BitWidth, 0ull, !Sem.isSigned()); + llvm::LoadIntFromMemory( + I, reinterpret_cast(Buff + sizeof(uint32_t)), + BitWidth / CHAR_BIT); + + return FixedPoint(I, Sem); + } + static bool neg(const FixedPoint &A, FixedPoint *R) { bool Overflow = false; *R = FixedPoint(A.V.negate(&Overflow)); diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 58c0256c7d7df8..510ff88e07f938 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3070,6 +3070,13 @@ inline IntegralAP ReadArg>(InterpState &S, return I; } +template <> +inline FixedPoint ReadArg(InterpState &S, CodePtr &OpPC) { + FixedPoint FP = FixedPoint::deserialize(*OpPC); + OpPC += align(FP.bytesToSerialize()); + return FP; +} + } // namespace interp } // namespace clang