aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/c.zig
diff options
context:
space:
mode:
authorkcbanner <kcbanner@gmail.com>2022-12-10 02:22:52 -0500
committerkcbanner <kcbanner@gmail.com>2023-01-01 16:44:27 -0500
commit7225a0043e1d1c0e6f3a0ac2bf9fbe0d48354071 (patch)
treec5219d823d04300935e18594577a6aa6906cda58 /src/codegen/c.zig
parente6ef57960914aa0e727ccd37ccd3913df3ae6ab4 (diff)
downloadzig-7225a0043e1d1c0e6f3a0ac2bf9fbe0d48354071.tar.gz
zig-7225a0043e1d1c0e6f3a0ac2bf9fbe0d48354071.zip
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 (limited to 'src/codegen/c.zig')
-rw-r--r--src/codegen/c.zig23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 5343977ba3..75864669c9 100644
--- 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;
}