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.
This commit is contained in:
15
lib/zig.h
15
lib/zig.h
@@ -1340,6 +1340,9 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
|
||||
// TODO: Implement
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user