zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 7225a0043e1d1c0e6f3a0ac2bf9fbe0d48354071 (tree)
parent e6ef57960914aa0e727ccd37ccd3913df3ae6ab4
Author: kcbanner <kcbanner@gmail.com>
Date:   Sat, 10 Dec 2022 02:22:52 -0500

cbe: handle msvc struct casting quirk

MSVC can't explicitly cast a struct to a typedef of itself (ie. f128 to i128). Added a
set of macros to handle float casting, and to not produce a cast for this specific
case on MSVC. A better approach would probably be to know if the cast is redundant
and not do it.

Diffstat:
Mlib/zig.h | 15+++++++++++++++
Msrc/codegen/c.zig | 23+++++++++++++++++------
2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/lib/zig.h b/lib/zig.h @@ -1341,6 +1341,9 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs); // TODO: Implement +static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs); + +// TODO: Implement static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs); static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) { @@ -1783,6 +1786,18 @@ typedef zig_i128 zig_f128; #define zig_as_special_f128(sign, name, arg, repr) repr #endif +#define zig_cast_f16 (zig_f16) +#define zig_cast_f32 (zig_f32) +#define zig_cast_f64 (zig_f64) +#define zig_cast_f80 (zig_f80) +#define zig_cast_c_longdouble (zig_c_longdouble) + +#if _MSC_VER && !zig_has_f128 +#define zig_cast_f128 +#else +#define zig_cast_f128 (zig_f128) +#endif + #define zig_has_c_longdouble 1 typedef long double zig_c_longdouble; #define zig_as_c_longdouble(fp, repr) fp##l diff --git a/src/codegen/c.zig b/src/codegen/c.zig @@ -927,9 +927,9 @@ pub const DeclGen = struct { }; const int_val = Value.initPayload(&int_val_pl.base); - try writer.writeByte('('); - try dg.renderTypecast(writer, ty); - try writer.writeByte(')'); + try writer.writeAll("zig_cast_"); + try dg.renderTypeForBuiltinFnName(writer, ty); + try writer.writeByte(' '); if (std.math.isFinite(f128_val)) { try writer.writeAll("zig_as_"); try dg.renderTypeForBuiltinFnName(writer, ty); @@ -3344,16 +3344,27 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { return CValue.none; } + const target = f.object.dg.module.getTarget(); const operand = try f.resolveInst(ty_op.operand); try reap(f, inst, &.{ty_op.operand}); const writer = f.object.writer(); const inst_ty = f.air.typeOfIndex(inst); const local = try f.allocLocal(inst, inst_ty); try f.writeCValue(writer, local, .Other); - try writer.writeAll(" = ("); - try f.renderTypecast(writer, inst_ty); - try writer.writeByte(')'); + try writer.writeAll(" = "); + const cant_cast = inst_ty.isInt() and inst_ty.bitSize(target) > 64; + if (cant_cast) { + if (f.air.typeOf(ty_op.operand).bitSize(target) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); + try writer.writeAll("zig_as_"); + try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); + try writer.writeAll("(0, "); + } else { + try writer.writeByte('('); + try f.renderTypecast(writer, inst_ty); + try writer.writeByte(')'); + } try f.writeCValue(writer, operand, .Other); + if (cant_cast) try writer.writeByte(')'); try writer.writeAll(";\n"); return local; }