| ... | ... | @@ -219,11 +219,36 @@ pub const DeclGen = struct { |
| 219 | 219 | val: Value, |
| 220 | 220 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 221 | 221 | if (val.isUndef()) { |
| 222 | | // This should lower to 0xaa bytes in safe modes, and for unsafe modes should |
| 223 | | // lower to leaving variables uninitialized (that might need to be implemented |
| 224 | | // outside of this function). |
| 225 | | return writer.writeAll("{}"); |
| 226 | | //return dg.fail("TODO: C backend: implement renderValue undef", .{}); |
| 222 | switch (ty.zigTypeTag()) { |
| 223 | // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang) |
| 224 | // with 'error: expected expression' (including when built with 'zig cc') |
| 225 | .Int => { |
| 226 | const c_bits = toCIntBits(ty.intInfo(dg.module.getTarget()).bits) orelse |
| 227 | return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); |
| 228 | switch (c_bits) { |
| 229 | 8 => return writer.writeAll("0xaaU"), |
| 230 | 16 => return writer.writeAll("0xaaaaU"), |
| 231 | 32 => return writer.writeAll("0xaaaaaaaaU"), |
| 232 | 64 => return writer.writeAll("0xaaaaaaaaaaaaaaaaUL"), |
| 233 | 128 => return writer.writeAll("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaULL"), |
| 234 | else => unreachable, |
| 235 | } |
| 236 | }, |
| 237 | .Float => { |
| 238 | switch (ty.floatBits(dg.module.getTarget())) { |
| 239 | 32 => return writer.writeAll("zig_bitcast_f32_u32(0xaaaaaaaa)"), |
| 240 | 64 => return writer.writeAll("zig_bitcast_f64_u64(0xaaaaaaaaaaaaaaaa)"), |
| 241 | else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}), |
| 242 | } |
| 243 | }, |
| 244 | |
| 245 | else => { |
| 246 | // This should lower to 0xaa bytes in safe modes, and for unsafe modes should |
| 247 | // lower to leaving variables uninitialized (that might need to be implemented |
| 248 | // outside of this function). |
| 249 | return writer.writeAll("{}"); |
| 250 | }, |
| 251 | } |
| 227 | 252 | } |
| 228 | 253 | switch (ty.zigTypeTag()) { |
| 229 | 254 | .Int => { |
| ... | ... | @@ -233,7 +258,16 @@ pub const DeclGen = struct { |
| 233 | 258 | }, |
| 234 | 259 | .Float => { |
| 235 | 260 | if (ty.floatBits(dg.module.getTarget()) <= 64) { |
| 236 | | return writer.print("{x}", .{val.toFloat(f64)}); |
| 261 | if (std.math.isNan(val.toFloat(f64)) or std.math.isInf(val.toFloat(f64))) { |
| 262 | // just generate a bit cast (exactly like we do in airBitcast) |
| 263 | switch (ty.tag()) { |
| 264 | .f32 => return writer.print("zig_bitcast_f32_u32(0x{x})", .{@bitCast(u32, val.toFloat(f32))}), |
| 265 | .f64 => return writer.print("zig_bitcast_f64_u64(0x{x})", .{@bitCast(u64, val.toFloat(f64))}), |
| 266 | else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}), |
| 267 | } |
| 268 | } else { |
| 269 | return writer.print("{x}", .{val.toFloat(f64)}); |
| 270 | } |
| 237 | 271 | } |
| 238 | 272 | return dg.fail("TODO: C backend: implement lowering large float values", .{}); |
| 239 | 273 | }, |
| ... | ... | @@ -521,7 +555,16 @@ pub const DeclGen = struct { |
| 521 | 555 | } |
| 522 | 556 | }, |
| 523 | 557 | |
| 524 | | .Float => return dg.fail("TODO: C backend: implement type Float", .{}), |
| 558 | .Float => { |
| 559 | switch (t.tag()) { |
| 560 | .f32 => try w.writeAll("float"), |
| 561 | .f64 => try w.writeAll("double"), |
| 562 | .c_longdouble => try w.writeAll("long double"), |
| 563 | .f16 => return dg.fail("TODO: C backend: implement float type f16", .{}), |
| 564 | .f128 => return dg.fail("TODO: C backend: implement float type f128", .{}), |
| 565 | else => unreachable, |
| 566 | } |
| 567 | }, |
| 525 | 568 | |
| 526 | 569 | .Pointer => { |
| 527 | 570 | if (t.isSlice()) { |