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
23522352 .fntype => return self.analyzeInstFnType(scope, old_inst.castTag(.fntype).?),
23532353 .intcast => return self.analyzeInstIntCast(scope, old_inst.castTag(.intcast).?),
23542354 .bitcast => return self.analyzeInstBitCast(scope, old_inst.castTag(.bitcast).?),
2355 .floatcast => return self.analyzeInstFloatCast(scope, old_inst.castTag(.floatcast).?),
23552356 .elemptr => return self.analyzeInstElemPtr(scope, old_inst.castTag(.elemptr).?),
23562357 .add => return self.analyzeInstAdd(scope, old_inst.castTag(.add).?),
23572358 .sub => return self.analyzeInstSub(scope, old_inst.castTag(.sub).?),
......@@ -2796,16 +2797,16 @@ fn analyzeInstFieldPtr(self: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPt
27962797 }
27972798}
27982799
2799fn analyzeInstIntCast(self: *Module, scope: *Scope, intcast: *zir.Inst.IntCast) InnerError!*Inst {
2800 const dest_type = try self.resolveType(scope, intcast.positionals.dest_type);
2801 const new_inst = try self.resolveInst(scope, intcast.positionals.value);
2800fn analyzeInstIntCast(self: *Module, scope: *Scope, inst: *zir.Inst.IntCast) InnerError!*Inst {
2801 const dest_type = try self.resolveType(scope, inst.positionals.dest_type);
2802 const operand = try self.resolveInst(scope, inst.positionals.operand);
28022803
28032804 const dest_is_comptime_int = switch (dest_type.zigTypeTag()) {
28042805 .ComptimeInt => true,
28052806 .Int => false,
28062807 else => return self.fail(
28072808 scope,
2808 intcast.positionals.dest_type.src,
2809 inst.positionals.dest_type.src,
28092810 "expected integer type, found '{}'",
28102811 .{
28112812 dest_type,
......@@ -2813,21 +2814,23 @@ fn analyzeInstIntCast(self: *Module, scope: *Scope, intcast: *zir.Inst.IntCast)
28132814 ),
28142815 };
28152816
2816 switch (new_inst.ty.zigTypeTag()) {
2817 switch (operand.ty.zigTypeTag()) {
28172818 .ComptimeInt, .Int => {},
28182819 else => return self.fail(
28192820 scope,
2820 intcast.positionals.value.src,
2821 inst.positionals.operand.src,
28212822 "expected integer type, found '{}'",
2822 .{new_inst.ty},
2823 .{operand.ty},
28232824 ),
28242825 }
28252826
2826 if (dest_is_comptime_int or new_inst.value() != null) {
2827 return self.coerce(scope, dest_type, new_inst);
2827 if (operand.value() != null) {
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'", .{});
28282831 }
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", .{});
28312834}
28322835
28332836fn 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
28362839 return self.bitcast(scope, dest_type, operand);
28372840}
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
28392878fn analyzeInstElemPtr(self: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) InnerError!*Inst {
28402879 const array_ptr = try self.resolveInst(scope, inst.positionals.array_ptr);
28412880 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 {
34113450
34123451 const src_info = inst.ty.intInfo(self.target());
34133452 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 {
34153457 const b = try self.requireRuntimeBlock(scope, inst.src);
3416 return self.addNewInstArgs(b, inst.src, dest_type, Inst.WidenOrShorten, .{ .operand = inst });
3417 } else {
3418 return self.fail(scope, inst.src, "TODO implement more int widening {} to {}", .{ inst.ty, dest_type });
3458 return self.addUnOp(b, inst.src, dest_type, .intcast, inst);
34193459 }
34203460 }
34213461
......@@ -3427,7 +3467,7 @@ fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst {
34273467 const dst_bits = dest_type.floatBits(self.target());
34283468 if (dst_bits >= src_bits) {
34293469 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);
34313471 }
34323472 }
34333473
src-self-hosted/codegen.zig+13-3
......@@ -459,16 +459,26 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
459459 .sub => return self.genSub(inst.castTag(.sub).?),
460460 .unreach => return MCValue{ .unreach = {} },
461461 .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).?),
463464 }
464465 }
465466
466 fn genWidenOrShorten(self: *Self, inst: *ir.Inst.WidenOrShorten) !MCValue {
467 fn genFloatCast(self: *Self, inst: *ir.Inst.UnOp) !MCValue {
467468 // No side effects, so if it's unreferenced, do nothing.
468469 if (inst.base.isUnused())
469470 return MCValue.dead;
470471 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}),
472482 }
473483 }
474484
src-self-hosted/ir.zig+4-11
......@@ -71,7 +71,8 @@ pub const Inst = struct {
7171 sub,
7272 unreach,
7373 not,
74 widenorshorten,
74 floatcast,
75 intcast,
7576
7677 /// There is one-to-one correspondence between tag and type for now,
7778 /// but this will not always be the case. For example, binary operations
......@@ -90,6 +91,8 @@ pub const Inst = struct {
9091 .isnonnull,
9192 .isnull,
9293 .ptrtoint,
94 .floatcast,
95 .intcast,
9396 => UnOp,
9497
9598 .add,
......@@ -109,7 +112,6 @@ pub const Inst = struct {
109112 .call => Call,
110113 .condbr => CondBr,
111114 .constant => Constant,
112 .widenorshorten => WidenOrShorten,
113115 };
114116 }
115117
......@@ -376,15 +378,6 @@ pub const Inst = struct {
376378 return null;
377379 }
378380 };
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 };
388381};
389382
390383pub const Body = struct {
src-self-hosted/value.zig+7-17
......@@ -80,7 +80,6 @@ pub const Value = extern union {
8080 elem_ptr,
8181 bytes,
8282 repeated, // the value is a value repeated some number of times
83 float,
8483 float_16,
8584 float_32,
8685 float_64,
......@@ -221,7 +220,7 @@ pub const Value = extern union {
221220 .float_16 => return self.copyPayloadShallow(allocator, Payload.Float_16),
222221 .float_32 => return self.copyPayloadShallow(allocator, Payload.Float_32),
223222 .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),
225224 }
226225 }
227226
......@@ -312,7 +311,7 @@ pub const Value = extern union {
312311 .float_16 => return out_stream.print("{}", .{val.cast(Payload.Float_16).?.val}),
313312 .float_32 => return out_stream.print("{}", .{val.cast(Payload.Float_32).?.val}),
314313 .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}),
316315 };
317316 }
318317
......@@ -393,7 +392,6 @@ pub const Value = extern union {
393392 .elem_ptr,
394393 .bytes,
395394 .repeated,
396 .float,
397395 .float_16,
398396 .float_32,
399397 .float_64,
......@@ -453,7 +451,6 @@ pub const Value = extern union {
453451 .bytes,
454452 .undef,
455453 .repeated,
456 .float,
457454 .float_16,
458455 .float_32,
459456 .float_64,
......@@ -525,7 +522,6 @@ pub const Value = extern union {
525522 .bytes,
526523 .undef,
527524 .repeated,
528 .float,
529525 .float_16,
530526 .float_32,
531527 .float_64,
......@@ -560,7 +556,7 @@ pub const Value = extern union {
560556 .float_16 => self.cast(Payload.Float_16).?.val,
561557 .float_32 => self.cast(Payload.Float_32).?.val,
562558 .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
565561 .zero, .the_one_possible_value => 0,
566562 .int_u64 => @intToFloat(f128, self.cast(Payload.Int_u64).?.int),
......@@ -624,7 +620,6 @@ pub const Value = extern union {
624620 .bytes,
625621 .undef,
626622 .repeated,
627 .float,
628623 .float_16,
629624 .float_32,
630625 .float_64,
......@@ -701,7 +696,6 @@ pub const Value = extern union {
701696 .elem_ptr,
702697 .bytes,
703698 .repeated,
704 .float,
705699 .float_16,
706700 .float_32,
707701 .float_64,
......@@ -830,8 +824,8 @@ pub const Value = extern union {
830824 .float_16 => @rem(self.cast(Payload.Float_16).?.val, 1) != 0,
831825 .float_32 => @rem(self.cast(Payload.Float_32).?.val, 1) != 0,
832826 .float_64 => @rem(self.cast(Payload.Float_64).?.val, 1) != 0,
833 // .float_128, .float => @rem(self.cast(Payload.Float_128).?.val, 1) != 0,
834 .float_128, .float => @panic("TODO lld: error: undefined symbol: fmodl"),
827 // .float_128 => @rem(self.cast(Payload.Float_128).?.val, 1) != 0,
828 .float_128 => @panic("TODO lld: error: undefined symbol: fmodl"),
835829 };
836830 }
837831
......@@ -902,7 +896,7 @@ pub const Value = extern union {
902896 .float_16 => std.math.order(lhs.cast(Payload.Float_16).?.val, 0),
903897 .float_32 => std.math.order(lhs.cast(Payload.Float_32).?.val, 0),
904898 .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),
906900 };
907901 }
908902
......@@ -923,7 +917,7 @@ pub const Value = extern union {
923917 .float_16 => return std.math.order(lhs.cast(Payload.Float_16).?.val, rhs.cast(Payload.Float_16).?.val),
924918 .float_32 => return std.math.order(lhs.cast(Payload.Float_32).?.val, rhs.cast(Payload.Float_32).?.val),
925919 .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),
927921 else => unreachable,
928922 };
929923 }
......@@ -1012,7 +1006,6 @@ pub const Value = extern union {
10121006 .bytes,
10131007 .undef,
10141008 .repeated,
1015 .float,
10161009 .float_16,
10171010 .float_32,
10181011 .float_64,
......@@ -1088,7 +1081,6 @@ pub const Value = extern union {
10881081 .elem_ptr,
10891082 .ref_val,
10901083 .decl_ref,
1091 .float,
10921084 .float_16,
10931085 .float_32,
10941086 .float_64,
......@@ -1179,7 +1171,6 @@ pub const Value = extern union {
11791171 .elem_ptr,
11801172 .bytes,
11811173 .repeated,
1182 .float,
11831174 .float_16,
11841175 .float_32,
11851176 .float_64,
......@@ -1196,7 +1187,6 @@ pub const Value = extern union {
11961187 return switch (self.tag()) {
11971188 .undef => unreachable,
11981189
1199 .float,
12001190 .float_16,
12011191 .float_32,
12021192 .float_64,
src-self-hosted/zir.zig+41-21
......@@ -76,6 +76,7 @@ pub const Inst = struct {
7676 primitive,
7777 intcast,
7878 bitcast,
79 floatcast,
7980 elemptr,
8081 add,
8182 sub,
......@@ -137,6 +138,7 @@ pub const Inst = struct {
137138 .fntype => FnType,
138139 .intcast => IntCast,
139140 .bitcast => BitCast,
141 .floatcast => FloatCast,
140142 .elemptr => ElemPtr,
141143 .condbr => CondBr,
142144 };
......@@ -169,6 +171,7 @@ pub const Inst = struct {
169171 .primitive,
170172 .intcast,
171173 .bitcast,
174 .floatcast,
172175 .elemptr,
173176 .add,
174177 .sub,
......@@ -556,6 +559,18 @@ pub const Inst = struct {
556559 };
557560 };
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
559574 pub const IntCast = struct {
560575 pub const base_tag = Tag.intcast;
561576 pub const builtin_name = "@intCast";
......@@ -563,7 +578,7 @@ pub const Inst = struct {
563578
564579 positionals: struct {
565580 dest_type: *Inst,
566 value: *Inst,
581 operand: *Inst,
567582 },
568583 kw_args: struct {},
569584 };
......@@ -1620,6 +1635,28 @@ const EmitZIR = struct {
16201635 return &new_inst.base;
16211636 }
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
16231660 fn emitBody(
16241661 self: *EmitZIR,
16251662 body: ir.Body,
......@@ -1654,22 +1691,9 @@ const EmitZIR = struct {
16541691 .cmp_gt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gt).?, .cmp_gt),
16551692 .cmp_neq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_neq).?, .cmp_neq),
16561693
1657 .bitcast => blk: {
1658 const old_inst = inst.castTag(.bitcast).?;
1659 const new_inst = try self.arena.allocator.create(Inst.BitCast);
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 },
1694 .bitcast => try self.emitCast(inst.src, new_body, inst.castTag(.bitcast).?, Inst.BitCast),
1695 .intcast => try self.emitCast(inst.src, new_body, inst.castTag(.intcast).?, Inst.IntCast),
1696 .floatcast => try self.emitCast(inst.src, new_body, inst.castTag(.floatcast).?, Inst.FloatCast),
16731697
16741698 .block => blk: {
16751699 const old_inst = inst.castTag(.block).?;
......@@ -1822,10 +1846,6 @@ const EmitZIR = struct {
18221846 };
18231847 break :blk &new_inst.base;
18241848 },
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 },
18291849 };
18301850 try instructions.append(new_inst);
18311851 try inst_table.put(inst, new_inst);