authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2022-12-10 02:22:52-05:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-01-01 16:44:27-05:00
log7225a0043e1d1c0e6f3a0ac2bf9fbe0d48354071
treec5219d823d04300935e18594577a6aa6906cda58
parente6ef57960914aa0e727ccd37ccd3913df3ae6ab4

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.

2 files changed, 32 insertions(+), 6 deletions(-)

lib/zig.h+15
......@@ -1340,6 +1340,9 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
13401340// TODO: Implement
13411341static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs);
13421342
1343// TODO: Implement
1344static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs);
1345
13431346// TODO: Implement
13441347static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs);
13451348
......@@ -1783,6 +1786,18 @@ typedef zig_i128 zig_f128;
17831786#define zig_as_special_f128(sign, name, arg, repr) repr
17841787#endif
17851788
1789#define zig_cast_f16 (zig_f16)
1790#define zig_cast_f32 (zig_f32)
1791#define zig_cast_f64 (zig_f64)
1792#define zig_cast_f80 (zig_f80)
1793#define zig_cast_c_longdouble (zig_c_longdouble)
1794
1795#if _MSC_VER && !zig_has_f128
1796#define zig_cast_f128
1797#else
1798#define zig_cast_f128 (zig_f128)
1799#endif
1800
17861801#define zig_has_c_longdouble 1
17871802typedef long double zig_c_longdouble;
17881803#define zig_as_c_longdouble(fp, repr) fp##l
src/codegen/c.zig+17-6
......@@ -927,9 +927,9 @@ pub const DeclGen = struct {
927927 };
928928 const int_val = Value.initPayload(&int_val_pl.base);
929929
930 try writer.writeByte('(');
931 try dg.renderTypecast(writer, ty);
932 try writer.writeByte(')');
930 try writer.writeAll("zig_cast_");
931 try dg.renderTypeForBuiltinFnName(writer, ty);
932 try writer.writeByte(' ');
933933 if (std.math.isFinite(f128_val)) {
934934 try writer.writeAll("zig_as_");
935935 try dg.renderTypeForBuiltinFnName(writer, ty);
......@@ -3344,16 +3344,27 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
33443344 return CValue.none;
33453345 }
33463346
3347 const target = f.object.dg.module.getTarget();
33473348 const operand = try f.resolveInst(ty_op.operand);
33483349 try reap(f, inst, &.{ty_op.operand});
33493350 const writer = f.object.writer();
33503351 const inst_ty = f.air.typeOfIndex(inst);
33513352 const local = try f.allocLocal(inst, inst_ty);
33523353 try f.writeCValue(writer, local, .Other);
3353 try writer.writeAll(" = (");
3354 try f.renderTypecast(writer, inst_ty);
3355 try writer.writeByte(')');
3354 try writer.writeAll(" = ");
3355 const cant_cast = inst_ty.isInt() and inst_ty.bitSize(target) > 64;
3356 if (cant_cast) {
3357 if (f.air.typeOf(ty_op.operand).bitSize(target) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
3358 try writer.writeAll("zig_as_");
3359 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
3360 try writer.writeAll("(0, ");
3361 } else {
3362 try writer.writeByte('(');
3363 try f.renderTypecast(writer, inst_ty);
3364 try writer.writeByte(')');
3365 }
33563366 try f.writeCValue(writer, operand, .Other);
3367 if (cant_cast) try writer.writeByte(')');
33573368 try writer.writeAll(";\n");
33583369 return local;
33593370}