authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-21 17:14:40+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-21 22:34:12+03:00
log7e7d1df4daedecf32d97ad21c85e23bcaac29e7a
treeb95d1d1a087b0517cfa708080510ee8d6644bf2b
parent7b52dbbf83ec89b9337e2be7328480e83489dc0d
signature Commit is signed but in an unrecognized format.

stage2: add floatCast to zir and ir


5 files changed, 120 insertions(+), 67 deletions(-)

src-self-hosted/Module.zig+55-15
...@@ -2352,6 +2352,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In...@@ -2352,6 +2352,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
2352 .fntype => return self.analyzeInstFnType(scope, old_inst.castTag(.fntype).?),2352 .fntype => return self.analyzeInstFnType(scope, old_inst.castTag(.fntype).?),
2353 .intcast => return self.analyzeInstIntCast(scope, old_inst.castTag(.intcast).?),2353 .intcast => return self.analyzeInstIntCast(scope, old_inst.castTag(.intcast).?),
2354 .bitcast => return self.analyzeInstBitCast(scope, old_inst.castTag(.bitcast).?),2354 .bitcast => return self.analyzeInstBitCast(scope, old_inst.castTag(.bitcast).?),
2355 .floatcast => return self.analyzeInstFloatCast(scope, old_inst.castTag(.floatcast).?),
2355 .elemptr => return self.analyzeInstElemPtr(scope, old_inst.castTag(.elemptr).?),2356 .elemptr => return self.analyzeInstElemPtr(scope, old_inst.castTag(.elemptr).?),
2356 .add => return self.analyzeInstAdd(scope, old_inst.castTag(.add).?),2357 .add => return self.analyzeInstAdd(scope, old_inst.castTag(.add).?),
2357 .sub => return self.analyzeInstSub(scope, old_inst.castTag(.sub).?),2358 .sub => return self.analyzeInstSub(scope, old_inst.castTag(.sub).?),
...@@ -2796,16 +2797,16 @@ fn analyzeInstFieldPtr(self: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPt...@@ -2796,16 +2797,16 @@ fn analyzeInstFieldPtr(self: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPt
2796 }2797 }
2797}2798}
27982799
2799fn analyzeInstIntCast(self: *Module, scope: *Scope, intcast: *zir.Inst.IntCast) InnerError!*Inst {2800fn analyzeInstIntCast(self: *Module, scope: *Scope, inst: *zir.Inst.IntCast) InnerError!*Inst {
2800 const dest_type = try self.resolveType(scope, intcast.positionals.dest_type);2801 const dest_type = try self.resolveType(scope, inst.positionals.dest_type);
2801 const new_inst = try self.resolveInst(scope, intcast.positionals.value);2802 const operand = try self.resolveInst(scope, inst.positionals.operand);
28022803
2803 const dest_is_comptime_int = switch (dest_type.zigTypeTag()) {2804 const dest_is_comptime_int = switch (dest_type.zigTypeTag()) {
2804 .ComptimeInt => true,2805 .ComptimeInt => true,
2805 .Int => false,2806 .Int => false,
2806 else => return self.fail(2807 else => return self.fail(
2807 scope,2808 scope,
2808 intcast.positionals.dest_type.src,2809 inst.positionals.dest_type.src,
2809 "expected integer type, found '{}'",2810 "expected integer type, found '{}'",
2810 .{2811 .{
2811 dest_type,2812 dest_type,
...@@ -2813,21 +2814,23 @@ fn analyzeInstIntCast(self: *Module, scope: *Scope, intcast: *zir.Inst.IntCast)...@@ -2813,21 +2814,23 @@ fn analyzeInstIntCast(self: *Module, scope: *Scope, intcast: *zir.Inst.IntCast)
2813 ),2814 ),
2814 };2815 };
28152816
2816 switch (new_inst.ty.zigTypeTag()) {2817 switch (operand.ty.zigTypeTag()) {
2817 .ComptimeInt, .Int => {},2818 .ComptimeInt, .Int => {},
2818 else => return self.fail(2819 else => return self.fail(
2819 scope,2820 scope,
2820 intcast.positionals.value.src,2821 inst.positionals.operand.src,
2821 "expected integer type, found '{}'",2822 "expected integer type, found '{}'",
2822 .{new_inst.ty},2823 .{operand.ty},
2823 ),2824 ),
2824 }2825 }
28252826
2826 if (dest_is_comptime_int or new_inst.value() != null) {2827 if (operand.value() != null) {
2827 return self.coerce(scope, dest_type, new_inst);2828 return self.coerce(scope, dest_type, operand);
2829 } else if (dest_is_comptime_int) {
2830 return self.fail(scope, inst.base.src, "unable to cast runtime value to 'comptime_int'", .{});
2828 }2831 }
28292832
2830 return self.fail(scope, intcast.base.src, "TODO implement analyze widen or shorten int", .{});2833 return self.fail(scope, inst.base.src, "TODO implement analyze widen or shorten int", .{});
2831}2834}
28322835
2833fn analyzeInstBitCast(self: *Module, scope: *Scope, inst: *zir.Inst.BitCast) InnerError!*Inst {2836fn analyzeInstBitCast(self: *Module, scope: *Scope, inst: *zir.Inst.BitCast) InnerError!*Inst {
...@@ -2836,6 +2839,42 @@ fn analyzeInstBitCast(self: *Module, scope: *Scope, inst: *zir.Inst.BitCast) Inn...@@ -2836,6 +2839,42 @@ fn analyzeInstBitCast(self: *Module, scope: *Scope, inst: *zir.Inst.BitCast) Inn
2836 return self.bitcast(scope, dest_type, operand);2839 return self.bitcast(scope, dest_type, operand);
2837}2840}
28382841
2842fn analyzeInstFloatCast(self: *Module, scope: *Scope, inst: *zir.Inst.FloatCast) InnerError!*Inst {
2843 const dest_type = try self.resolveType(scope, inst.positionals.dest_type);
2844 const operand = try self.resolveInst(scope, inst.positionals.operand);
2845
2846 const dest_is_comptime_float = switch (dest_type.zigTypeTag()) {
2847 .ComptimeFloat => true,
2848 .Float => false,
2849 else => return self.fail(
2850 scope,
2851 inst.positionals.dest_type.src,
2852 "expected float type, found '{}'",
2853 .{
2854 dest_type,
2855 },
2856 ),
2857 };
2858
2859 switch (operand.ty.zigTypeTag()) {
2860 .ComptimeFloat, .Float, .ComptimeInt => {},
2861 else => return self.fail(
2862 scope,
2863 inst.positionals.operand.src,
2864 "expected float type, found '{}'",
2865 .{operand.ty},
2866 ),
2867 }
2868
2869 if (operand.value() != null) {
2870 return self.coerce(scope, dest_type, operand);
2871 } else if (dest_is_comptime_float) {
2872 return self.fail(scope, inst.base.src, "unable to cast runtime value to 'comptime_float'", .{});
2873 }
2874
2875 return self.fail(scope, inst.base.src, "TODO implement analyze widen or shorten float", .{});
2876}
2877
2839fn analyzeInstElemPtr(self: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) InnerError!*Inst {2878fn analyzeInstElemPtr(self: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) InnerError!*Inst {
2840 const array_ptr = try self.resolveInst(scope, inst.positionals.array_ptr);2879 const array_ptr = try self.resolveInst(scope, inst.positionals.array_ptr);
2841 const uncasted_index = try self.resolveInst(scope, inst.positionals.index);2880 const uncasted_index = try self.resolveInst(scope, inst.positionals.index);
...@@ -3411,11 +3450,12 @@ fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {...@@ -3411,11 +3450,12 @@ fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {
34113450
3412 const src_info = inst.ty.intInfo(self.target());3451 const src_info = inst.ty.intInfo(self.target());
3413 const dst_info = dest_type.intInfo(self.target());3452 const dst_info = dest_type.intInfo(self.target());
3414 if (src_info.signed == dst_info.signed and dst_info.bits >= src_info.bits) {3453 if ((src_info.signed == dst_info.signed and dst_info.bits >= src_info.bits) or
3454 // small enough unsigned ints can get casted to large enough signed ints
3455 (src_info.signed and !dst_info.signed and dst_info.bits > src_info.bits))
3456 {
3415 const b = try self.requireRuntimeBlock(scope, inst.src);3457 const b = try self.requireRuntimeBlock(scope, inst.src);
3416 return self.addNewInstArgs(b, inst.src, dest_type, Inst.WidenOrShorten, .{ .operand = inst });3458 return self.addUnOp(b, inst.src, dest_type, .intcast, inst);
3417 } else {
3418 return self.fail(scope, inst.src, "TODO implement more int widening {} to {}", .{ inst.ty, dest_type });
3419 }3459 }
3420 }3460 }
34213461
...@@ -3427,7 +3467,7 @@ fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {...@@ -3427,7 +3467,7 @@ fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {
3427 const dst_bits = dest_type.floatBits(self.target());3467 const dst_bits = dest_type.floatBits(self.target());
3428 if (dst_bits >= src_bits) {3468 if (dst_bits >= src_bits) {
3429 const b = try self.requireRuntimeBlock(scope, inst.src);3469 const b = try self.requireRuntimeBlock(scope, inst.src);
3430 return self.addNewInstArgs(b, inst.src, dest_type, Inst.WidenOrShorten, .{ .operand = inst });3470 return self.addUnOp(b, inst.src, dest_type, .floatcast, inst);
3431 }3471 }
3432 }3472 }
34333473
src-self-hosted/codegen.zig+13-3
...@@ -459,16 +459,26 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -459,16 +459,26 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
459 .sub => return self.genSub(inst.castTag(.sub).?),459 .sub => return self.genSub(inst.castTag(.sub).?),
460 .unreach => return MCValue{ .unreach = {} },460 .unreach => return MCValue{ .unreach = {} },
461 .not => return self.genNot(inst.castTag(.not).?),461 .not => return self.genNot(inst.castTag(.not).?),
462 .widenorshorten => return self.genWidenOrShorten(isnt.castTag(.widenorshorten).?),462 .floatcast => return self.genFloatCast(inst.castTag(.floatcast).?),
463 .intcast => return self.genIntCast(inst.castTag(.intcast).?),
463 }464 }
464 }465 }
465466
466 fn genWidenOrShorten(self: *Self, inst: *ir.Inst.WidenOrShorten) !MCValue {467 fn genFloatCast(self: *Self, inst: *ir.Inst.UnOp) !MCValue {
467 // No side effects, so if it's unreferenced, do nothing.468 // No side effects, so if it's unreferenced, do nothing.
468 if (inst.base.isUnused())469 if (inst.base.isUnused())
469 return MCValue.dead;470 return MCValue.dead;
470 switch (arch) {471 switch (arch) {
471 else => return self.fail(inst.base.src, "TODO implement widen or shorten for {}", .{self.target.cpu.arch}),472 else => return self.fail(inst.base.src, "TODO implement floatCast for {}", .{self.target.cpu.arch}),
473 }
474 }
475
476 fn genIntCast(self: *Self, inst: *ir.Inst.UnOp) !MCValue {
477 // No side effects, so if it's unreferenced, do nothing.
478 if (inst.base.isUnused())
479 return MCValue.dead;
480 switch (arch) {
481 else => return self.fail(inst.base.src, "TODO implement intCast for {}", .{self.target.cpu.arch}),
472 }482 }
473 }483 }
474484
src-self-hosted/ir.zig+4-11
...@@ -71,7 +71,8 @@ pub const Inst = struct {...@@ -71,7 +71,8 @@ pub const Inst = struct {
71 sub,71 sub,
72 unreach,72 unreach,
73 not,73 not,
74 widenorshorten,74 floatcast,
75 intcast,
7576
76 /// There is one-to-one correspondence between tag and type for now,77 /// There is one-to-one correspondence between tag and type for now,
77 /// but this will not always be the case. For example, binary operations78 /// but this will not always be the case. For example, binary operations
...@@ -90,6 +91,8 @@ pub const Inst = struct {...@@ -90,6 +91,8 @@ pub const Inst = struct {
90 .isnonnull,91 .isnonnull,
91 .isnull,92 .isnull,
92 .ptrtoint,93 .ptrtoint,
94 .floatcast,
95 .intcast,
93 => UnOp,96 => UnOp,
9497
95 .add,98 .add,
...@@ -109,7 +112,6 @@ pub const Inst = struct {...@@ -109,7 +112,6 @@ pub const Inst = struct {
109 .call => Call,112 .call => Call,
110 .condbr => CondBr,113 .condbr => CondBr,
111 .constant => Constant,114 .constant => Constant,
112 .widenorshorten => WidenOrShorten,
113 };115 };
114 }116 }
115117
...@@ -376,15 +378,6 @@ pub const Inst = struct {...@@ -376,15 +378,6 @@ pub const Inst = struct {
376 return null;378 return null;
377 }379 }
378 };380 };
379
380 pub const WidenOrShorten = struct {
381 pub const base_tag = Tag.widenorshorten;
382
383 base: Inst,
384 args: struct {
385 operand: *Inst,
386 },
387 };
388};381};
389382
390pub const Body = struct {383pub const Body = struct {
src-self-hosted/value.zig+7-17
...@@ -80,7 +80,6 @@ pub const Value = extern union {...@@ -80,7 +80,6 @@ pub const Value = extern union {
80 elem_ptr,80 elem_ptr,
81 bytes,81 bytes,
82 repeated, // the value is a value repeated some number of times82 repeated, // the value is a value repeated some number of times
83 float,
84 float_16,83 float_16,
85 float_32,84 float_32,
86 float_64,85 float_64,
...@@ -221,7 +220,7 @@ pub const Value = extern union {...@@ -221,7 +220,7 @@ pub const Value = extern union {
221 .float_16 => return self.copyPayloadShallow(allocator, Payload.Float_16),220 .float_16 => return self.copyPayloadShallow(allocator, Payload.Float_16),
222 .float_32 => return self.copyPayloadShallow(allocator, Payload.Float_32),221 .float_32 => return self.copyPayloadShallow(allocator, Payload.Float_32),
223 .float_64 => return self.copyPayloadShallow(allocator, Payload.Float_64),222 .float_64 => return self.copyPayloadShallow(allocator, Payload.Float_64),
224 .float_128, .float => return self.copyPayloadShallow(allocator, Payload.Float_128),223 .float_128 => return self.copyPayloadShallow(allocator, Payload.Float_128),
225 }224 }
226 }225 }
227226
...@@ -312,7 +311,7 @@ pub const Value = extern union {...@@ -312,7 +311,7 @@ pub const Value = extern union {
312 .float_16 => return out_stream.print("{}", .{val.cast(Payload.Float_16).?.val}),311 .float_16 => return out_stream.print("{}", .{val.cast(Payload.Float_16).?.val}),
313 .float_32 => return out_stream.print("{}", .{val.cast(Payload.Float_32).?.val}),312 .float_32 => return out_stream.print("{}", .{val.cast(Payload.Float_32).?.val}),
314 .float_64 => return out_stream.print("{}", .{val.cast(Payload.Float_64).?.val}),313 .float_64 => return out_stream.print("{}", .{val.cast(Payload.Float_64).?.val}),
315 .float_128, .float => return out_stream.print("{}", .{val.cast(Payload.Float_128).?.val}),314 .float_128 => return out_stream.print("{}", .{val.cast(Payload.Float_128).?.val}),
316 };315 };
317 }316 }
318317
...@@ -393,7 +392,6 @@ pub const Value = extern union {...@@ -393,7 +392,6 @@ pub const Value = extern union {
393 .elem_ptr,392 .elem_ptr,
394 .bytes,393 .bytes,
395 .repeated,394 .repeated,
396 .float,
397 .float_16,395 .float_16,
398 .float_32,396 .float_32,
399 .float_64,397 .float_64,
...@@ -453,7 +451,6 @@ pub const Value = extern union {...@@ -453,7 +451,6 @@ pub const Value = extern union {
453 .bytes,451 .bytes,
454 .undef,452 .undef,
455 .repeated,453 .repeated,
456 .float,
457 .float_16,454 .float_16,
458 .float_32,455 .float_32,
459 .float_64,456 .float_64,
...@@ -525,7 +522,6 @@ pub const Value = extern union {...@@ -525,7 +522,6 @@ pub const Value = extern union {
525 .bytes,522 .bytes,
526 .undef,523 .undef,
527 .repeated,524 .repeated,
528 .float,
529 .float_16,525 .float_16,
530 .float_32,526 .float_32,
531 .float_64,527 .float_64,
...@@ -560,7 +556,7 @@ pub const Value = extern union {...@@ -560,7 +556,7 @@ pub const Value = extern union {
560 .float_16 => self.cast(Payload.Float_16).?.val,556 .float_16 => self.cast(Payload.Float_16).?.val,
561 .float_32 => self.cast(Payload.Float_32).?.val,557 .float_32 => self.cast(Payload.Float_32).?.val,
562 .float_64 => self.cast(Payload.Float_64).?.val,558 .float_64 => self.cast(Payload.Float_64).?.val,
563 .float_128, .float => self.cast(Payload.Float_128).?.val,559 .float_128 => self.cast(Payload.Float_128).?.val,
564560
565 .zero, .the_one_possible_value => 0,561 .zero, .the_one_possible_value => 0,
566 .int_u64 => @intToFloat(f128, self.cast(Payload.Int_u64).?.int),562 .int_u64 => @intToFloat(f128, self.cast(Payload.Int_u64).?.int),
...@@ -624,7 +620,6 @@ pub const Value = extern union {...@@ -624,7 +620,6 @@ pub const Value = extern union {
624 .bytes,620 .bytes,
625 .undef,621 .undef,
626 .repeated,622 .repeated,
627 .float,
628 .float_16,623 .float_16,
629 .float_32,624 .float_32,
630 .float_64,625 .float_64,
...@@ -701,7 +696,6 @@ pub const Value = extern union {...@@ -701,7 +696,6 @@ pub const Value = extern union {
701 .elem_ptr,696 .elem_ptr,
702 .bytes,697 .bytes,
703 .repeated,698 .repeated,
704 .float,
705 .float_16,699 .float_16,
706 .float_32,700 .float_32,
707 .float_64,701 .float_64,
...@@ -830,8 +824,8 @@ pub const Value = extern union {...@@ -830,8 +824,8 @@ pub const Value = extern union {
830 .float_16 => @rem(self.cast(Payload.Float_16).?.val, 1) != 0,824 .float_16 => @rem(self.cast(Payload.Float_16).?.val, 1) != 0,
831 .float_32 => @rem(self.cast(Payload.Float_32).?.val, 1) != 0,825 .float_32 => @rem(self.cast(Payload.Float_32).?.val, 1) != 0,
832 .float_64 => @rem(self.cast(Payload.Float_64).?.val, 1) != 0,826 .float_64 => @rem(self.cast(Payload.Float_64).?.val, 1) != 0,
833 // .float_128, .float => @rem(self.cast(Payload.Float_128).?.val, 1) != 0,827 // .float_128 => @rem(self.cast(Payload.Float_128).?.val, 1) != 0,
834 .float_128, .float => @panic("TODO lld: error: undefined symbol: fmodl"),828 .float_128 => @panic("TODO lld: error: undefined symbol: fmodl"),
835 };829 };
836 }830 }
837831
...@@ -902,7 +896,7 @@ pub const Value = extern union {...@@ -902,7 +896,7 @@ pub const Value = extern union {
902 .float_16 => std.math.order(lhs.cast(Payload.Float_16).?.val, 0),896 .float_16 => std.math.order(lhs.cast(Payload.Float_16).?.val, 0),
903 .float_32 => std.math.order(lhs.cast(Payload.Float_32).?.val, 0),897 .float_32 => std.math.order(lhs.cast(Payload.Float_32).?.val, 0),
904 .float_64 => std.math.order(lhs.cast(Payload.Float_64).?.val, 0),898 .float_64 => std.math.order(lhs.cast(Payload.Float_64).?.val, 0),
905 .float_128, .float => std.math.order(lhs.cast(Payload.Float_128).?.val, 0),899 .float_128 => std.math.order(lhs.cast(Payload.Float_128).?.val, 0),
906 };900 };
907 }901 }
908902
...@@ -923,7 +917,7 @@ pub const Value = extern union {...@@ -923,7 +917,7 @@ pub const Value = extern union {
923 .float_16 => return std.math.order(lhs.cast(Payload.Float_16).?.val, rhs.cast(Payload.Float_16).?.val),917 .float_16 => return std.math.order(lhs.cast(Payload.Float_16).?.val, rhs.cast(Payload.Float_16).?.val),
924 .float_32 => return std.math.order(lhs.cast(Payload.Float_32).?.val, rhs.cast(Payload.Float_32).?.val),918 .float_32 => return std.math.order(lhs.cast(Payload.Float_32).?.val, rhs.cast(Payload.Float_32).?.val),
925 .float_64 => return std.math.order(lhs.cast(Payload.Float_64).?.val, rhs.cast(Payload.Float_64).?.val),919 .float_64 => return std.math.order(lhs.cast(Payload.Float_64).?.val, rhs.cast(Payload.Float_64).?.val),
926 .float_128, .float => return std.math.order(lhs.cast(Payload.Float_128).?.val, rhs.cast(Payload.Float_128).?.val),920 .float_128 => return std.math.order(lhs.cast(Payload.Float_128).?.val, rhs.cast(Payload.Float_128).?.val),
927 else => unreachable,921 else => unreachable,
928 };922 };
929 }923 }
...@@ -1012,7 +1006,6 @@ pub const Value = extern union {...@@ -1012,7 +1006,6 @@ pub const Value = extern union {
1012 .bytes,1006 .bytes,
1013 .undef,1007 .undef,
1014 .repeated,1008 .repeated,
1015 .float,
1016 .float_16,1009 .float_16,
1017 .float_32,1010 .float_32,
1018 .float_64,1011 .float_64,
...@@ -1088,7 +1081,6 @@ pub const Value = extern union {...@@ -1088,7 +1081,6 @@ pub const Value = extern union {
1088 .elem_ptr,1081 .elem_ptr,
1089 .ref_val,1082 .ref_val,
1090 .decl_ref,1083 .decl_ref,
1091 .float,
1092 .float_16,1084 .float_16,
1093 .float_32,1085 .float_32,
1094 .float_64,1086 .float_64,
...@@ -1179,7 +1171,6 @@ pub const Value = extern union {...@@ -1179,7 +1171,6 @@ pub const Value = extern union {
1179 .elem_ptr,1171 .elem_ptr,
1180 .bytes,1172 .bytes,
1181 .repeated,1173 .repeated,
1182 .float,
1183 .float_16,1174 .float_16,
1184 .float_32,1175 .float_32,
1185 .float_64,1176 .float_64,
...@@ -1196,7 +1187,6 @@ pub const Value = extern union {...@@ -1196,7 +1187,6 @@ pub const Value = extern union {
1196 return switch (self.tag()) {1187 return switch (self.tag()) {
1197 .undef => unreachable,1188 .undef => unreachable,
11981189
1199 .float,
1200 .float_16,1190 .float_16,
1201 .float_32,1191 .float_32,
1202 .float_64,1192 .float_64,
src-self-hosted/zir.zig+41-21
...@@ -76,6 +76,7 @@ pub const Inst = struct {...@@ -76,6 +76,7 @@ pub const Inst = struct {
76 primitive,76 primitive,
77 intcast,77 intcast,
78 bitcast,78 bitcast,
79 floatcast,
79 elemptr,80 elemptr,
80 add,81 add,
81 sub,82 sub,
...@@ -137,6 +138,7 @@ pub const Inst = struct {...@@ -137,6 +138,7 @@ pub const Inst = struct {
137 .fntype => FnType,138 .fntype => FnType,
138 .intcast => IntCast,139 .intcast => IntCast,
139 .bitcast => BitCast,140 .bitcast => BitCast,
141 .floatcast => FloatCast,
140 .elemptr => ElemPtr,142 .elemptr => ElemPtr,
141 .condbr => CondBr,143 .condbr => CondBr,
142 };144 };
...@@ -169,6 +171,7 @@ pub const Inst = struct {...@@ -169,6 +171,7 @@ pub const Inst = struct {
169 .primitive,171 .primitive,
170 .intcast,172 .intcast,
171 .bitcast,173 .bitcast,
174 .floatcast,
172 .elemptr,175 .elemptr,
173 .add,176 .add,
174 .sub,177 .sub,
...@@ -556,6 +559,18 @@ pub const Inst = struct {...@@ -556,6 +559,18 @@ pub const Inst = struct {
556 };559 };
557 };560 };
558561
562 pub const FloatCast = struct {
563 pub const base_tag = Tag.floatcast;
564 pub const builtin_name = "@floatCast";
565 base: Inst,
566
567 positionals: struct {
568 dest_type: *Inst,
569 operand: *Inst,
570 },
571 kw_args: struct {},
572 };
573
559 pub const IntCast = struct {574 pub const IntCast = struct {
560 pub const base_tag = Tag.intcast;575 pub const base_tag = Tag.intcast;
561 pub const builtin_name = "@intCast";576 pub const builtin_name = "@intCast";
...@@ -563,7 +578,7 @@ pub const Inst = struct {...@@ -563,7 +578,7 @@ pub const Inst = struct {
563578
564 positionals: struct {579 positionals: struct {
565 dest_type: *Inst,580 dest_type: *Inst,
566 value: *Inst,581 operand: *Inst,
567 },582 },
568 kw_args: struct {},583 kw_args: struct {},
569 };584 };
...@@ -1620,6 +1635,28 @@ const EmitZIR = struct {...@@ -1620,6 +1635,28 @@ const EmitZIR = struct {
1620 return &new_inst.base;1635 return &new_inst.base;
1621 }1636 }
16221637
1638 fn emitCast(
1639 self: *EmitZIR,
1640 src: usize,
1641 new_body: ZirBody,
1642 old_inst: *ir.Inst.UnOp,
1643 comptime I: type,
1644 ) Allocator.Error!*Inst {
1645 const new_inst = try self.arena.allocator.create(I);
1646 new_inst.* = .{
1647 .base = .{
1648 .src = src,
1649 .tag = I.base_tag,
1650 },
1651 .positionals = .{
1652 .dest_type = (try self.emitType(src, old_inst.base.ty)).inst,
1653 .operand = try self.resolveInst(new_body, old_inst.operand),
1654 },
1655 .kw_args = .{},
1656 };
1657 return &new_inst.base;
1658 }
1659
1623 fn emitBody(1660 fn emitBody(
1624 self: *EmitZIR,1661 self: *EmitZIR,
1625 body: ir.Body,1662 body: ir.Body,
...@@ -1654,22 +1691,9 @@ const EmitZIR = struct {...@@ -1654,22 +1691,9 @@ const EmitZIR = struct {
1654 .cmp_gt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gt).?, .cmp_gt),1691 .cmp_gt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gt).?, .cmp_gt),
1655 .cmp_neq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_neq).?, .cmp_neq),1692 .cmp_neq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_neq).?, .cmp_neq),
16561693
1657 .bitcast => blk: {1694 .bitcast => try self.emitCast(inst.src, new_body, inst.castTag(.bitcast).?, Inst.BitCast),
1658 const old_inst = inst.castTag(.bitcast).?;1695 .intcast => try self.emitCast(inst.src, new_body, inst.castTag(.intcast).?, Inst.IntCast),
1659 const new_inst = try self.arena.allocator.create(Inst.BitCast);1696 .floatcast => try self.emitCast(inst.src, new_body, inst.castTag(.floatcast).?, Inst.FloatCast),
1660 new_inst.* = .{
1661 .base = .{
1662 .src = inst.src,
1663 .tag = Inst.BitCast.base_tag,
1664 },
1665 .positionals = .{
1666 .dest_type = (try self.emitType(inst.src, inst.ty)).inst,
1667 .operand = try self.resolveInst(new_body, old_inst.operand),
1668 },
1669 .kw_args = .{},
1670 };
1671 break :blk &new_inst.base;
1672 },
16731697
1674 .block => blk: {1698 .block => blk: {
1675 const old_inst = inst.castTag(.block).?;1699 const old_inst = inst.castTag(.block).?;
...@@ -1822,10 +1846,6 @@ const EmitZIR = struct {...@@ -1822,10 +1846,6 @@ const EmitZIR = struct {
1822 };1846 };
1823 break :blk &new_inst.base;1847 break :blk &new_inst.base;
1824 },1848 },
1825 .widenorshorten => blk: {
1826 const old_inst = inst.cast(ir.Inst.WidenOrShorten).?;
1827 break :blk try self.resolveInst(new_body, old_inst.args.operand);
1828 },
1829 };1849 };
1830 try instructions.append(new_inst);1850 try instructions.append(new_inst);
1831 try inst_table.put(inst, new_inst);1851 try inst_table.put(inst, new_inst);