| ... | ... | @@ -3087,7 +3087,7 @@ fn analyzeInstArithmetic(self: *Module, scope: *Scope, inst: *zir.Inst.BinOp) In |
| 3087 | 3087 | |
| 3088 | 3088 | if (casted_lhs.value()) |lhs_val| { |
| 3089 | 3089 | if (casted_rhs.value()) |rhs_val| { |
| 3090 | | return self.analyzeInstScalar(scope, scalar_type, inst, lhs_val, rhs_val); |
| 3090 | return self.analyzeInstComptimeOp(scope, scalar_type, inst, lhs_val, rhs_val); |
| 3091 | 3091 | } |
| 3092 | 3092 | } |
| 3093 | 3093 | |
| ... | ... | @@ -3102,7 +3102,7 @@ fn analyzeInstArithmetic(self: *Module, scope: *Scope, inst: *zir.Inst.BinOp) In |
| 3102 | 3102 | } |
| 3103 | 3103 | |
| 3104 | 3104 | /// Analyzes operands that are known at comptime |
| 3105 | | fn analyzeInstScalar(self: *Module, scope: *Scope, res_type: Type, inst: *zir.Inst.BinOp, lhs_val: Value, rhs_val: Value) InnerError!*Inst { |
| 3105 | fn analyzeInstComptimeOp(self: *Module, scope: *Scope, res_type: Type, inst: *zir.Inst.BinOp, lhs_val: Value, rhs_val: Value) InnerError!*Inst { |
| 3106 | 3106 | // incase rhs is 0, simply return lhs without doing any calculations |
| 3107 | 3107 | // TODO Once division is implemented we should throw an error when dividing by 0. |
| 3108 | 3108 | if (rhs_val.tag() == .zero or rhs_val.tag() == .the_one_possible_value) { |
| ... | ... | @@ -3116,16 +3116,16 @@ fn analyzeInstScalar(self: *Module, scope: *Scope, res_type: Type, inst: *zir.In |
| 3116 | 3116 | const value = try switch (inst.base.tag) { |
| 3117 | 3117 | .add => blk: { |
| 3118 | 3118 | const val = if (is_int) |
| 3119 | | bigIntAdd(scope.arena(), lhs_val, rhs_val) |
| 3119 | intAdd(scope.arena(), lhs_val, rhs_val) |
| 3120 | 3120 | else |
| 3121 | | floatAdd(self.target(), scope.arena(), res_type, lhs_val, rhs_val); |
| 3121 | self.floatAdd(scope, res_type, inst, lhs_val, rhs_val); |
| 3122 | 3122 | break :blk val; |
| 3123 | 3123 | }, |
| 3124 | 3124 | .sub => blk: { |
| 3125 | 3125 | const val = if (is_int) |
| 3126 | | bigIntSub(scope.arena(), lhs_val, rhs_val) |
| 3126 | intSub(scope.arena(), lhs_val, rhs_val) |
| 3127 | 3127 | else |
| 3128 | | floatSub(self.target(), scope.arena(), res_type, lhs_val, rhs_val); |
| 3128 | self.floatSub(scope, res_type, inst, lhs_val, rhs_val); |
| 3129 | 3129 | break :blk val; |
| 3130 | 3130 | }, |
| 3131 | 3131 | else => return self.fail(scope, inst.base.src, "TODO Implement arithmetic operand '{}'", .{@tagName(inst.base.tag)}), |
| ... | ... | @@ -3556,7 +3556,10 @@ fn resolvePeerTypes(self: *Module, scope: *Scope, instructions: []*Inst) !Type { |
| 3556 | 3556 | prev_inst = next_inst; |
| 3557 | 3557 | continue; |
| 3558 | 3558 | } |
| 3559 | | if (prev_inst.ty.isInt() and next_inst.ty.isInt()) { |
| 3559 | if (prev_inst.ty.isInt() and |
| 3560 | next_inst.ty.isInt() and |
| 3561 | prev_inst.ty.isSignedInt() == next_inst.ty.isSignedInt()) |
| 3562 | { |
| 3560 | 3563 | if (prev_inst.ty.intInfo(self.target()).bits < next_inst.ty.intInfo(self.target()).bits) { |
| 3561 | 3564 | prev_inst = next_inst; |
| 3562 | 3565 | } |
| ... | ... | @@ -3819,7 +3822,7 @@ fn srcHashEql(a: std.zig.SrcHash, b: std.zig.SrcHash) bool { |
| 3819 | 3822 | return @bitCast(u128, a) == @bitCast(u128, b); |
| 3820 | 3823 | } |
| 3821 | 3824 | |
| 3822 | | fn bigIntAdd(allocator: *Allocator, lhs: Value, rhs: Value) !Value { |
| 3825 | fn intAdd(allocator: *Allocator, lhs: Value, rhs: Value) !Value { |
| 3823 | 3826 | // TODO is this a performance issue? maybe we should try the operation without |
| 3824 | 3827 | // resorting to BigInt first. |
| 3825 | 3828 | var lhs_space: Value.BigIntSpace = undefined; |
| ... | ... | @@ -3847,7 +3850,7 @@ fn bigIntAdd(allocator: *Allocator, lhs: Value, rhs: Value) !Value { |
| 3847 | 3850 | return Value.initPayload(val_payload); |
| 3848 | 3851 | } |
| 3849 | 3852 | |
| 3850 | | fn bigIntSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value { |
| 3853 | fn intSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value { |
| 3851 | 3854 | // TODO is this a performance issue? maybe we should try the operation without |
| 3852 | 3855 | // resorting to BigInt first. |
| 3853 | 3856 | var lhs_space: Value.BigIntSpace = undefined; |
| ... | ... | @@ -3875,15 +3878,16 @@ fn bigIntSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value { |
| 3875 | 3878 | return Value.initPayload(val_payload); |
| 3876 | 3879 | } |
| 3877 | 3880 | |
| 3878 | | fn floatAdd(cur_target: Target, allocator: *Allocator, float_type: Type, lhs: Value, rhs: Value) !Value { |
| 3881 | fn floatAdd(self: *Module, scope: *Scope, float_type: Type, inst: *zir.Inst.BinOp, lhs: Value, rhs: Value) !Value { |
| 3879 | 3882 | var bit_count = switch (float_type.tag()) { |
| 3880 | 3883 | .comptime_float => 128, |
| 3881 | | else => float_type.floatBits(cur_target), |
| 3884 | else => float_type.floatBits(self.target()), |
| 3882 | 3885 | }; |
| 3883 | 3886 | |
| 3887 | const allocator = scope.arena(); |
| 3884 | 3888 | const val_payload = switch (bit_count) { |
| 3885 | 3889 | 16 => { |
| 3886 | | @panic("TODO soft float"); |
| 3890 | return self.fail(scope, inst.base.src, "TODO Implement addition for soft floats", .{}); |
| 3887 | 3891 | }, |
| 3888 | 3892 | 32 => blk: { |
| 3889 | 3893 | const lhs_val = lhs.toFloat(f32); |
| ... | ... | @@ -3900,7 +3904,7 @@ fn floatAdd(cur_target: Target, allocator: *Allocator, float_type: Type, lhs: Va |
| 3900 | 3904 | break :blk &val_payload.base; |
| 3901 | 3905 | }, |
| 3902 | 3906 | 128 => blk: { |
| 3903 | | @panic("TODO Big float"); |
| 3907 | return self.fail(scope, inst.base.src, "TODO Implement addition for big floats", .{}); |
| 3904 | 3908 | }, |
| 3905 | 3909 | else => unreachable, |
| 3906 | 3910 | }; |
| ... | ... | @@ -3908,15 +3912,16 @@ fn floatAdd(cur_target: Target, allocator: *Allocator, float_type: Type, lhs: Va |
| 3908 | 3912 | return Value.initPayload(val_payload); |
| 3909 | 3913 | } |
| 3910 | 3914 | |
| 3911 | | fn floatSub(cur_target: Target, allocator: *Allocator, float_type: Type, lhs: Value, rhs: Value) !Value { |
| 3915 | fn floatSub(self: *Module, scope: *Scope, float_type: Type, inst: *zir.Inst.BinOp, lhs: Value, rhs: Value) !Value { |
| 3912 | 3916 | var bit_count = switch (float_type.tag()) { |
| 3913 | 3917 | .comptime_float => 128, |
| 3914 | | else => float_type.floatBits(cur_target), |
| 3918 | else => float_type.floatBits(self.target()), |
| 3915 | 3919 | }; |
| 3916 | 3920 | |
| 3921 | const allocator = scope.arena(); |
| 3917 | 3922 | const val_payload = switch (bit_count) { |
| 3918 | 3923 | 16 => { |
| 3919 | | @panic("TODO soft float"); |
| 3924 | return self.fail(scope, inst.base.src, "TODO Implement substraction for soft floats", .{}); |
| 3920 | 3925 | }, |
| 3921 | 3926 | 32 => blk: { |
| 3922 | 3927 | const lhs_val = lhs.toFloat(f32); |
| ... | ... | @@ -3933,7 +3938,7 @@ fn floatSub(cur_target: Target, allocator: *Allocator, float_type: Type, lhs: Va |
| 3933 | 3938 | break :blk &val_payload.base; |
| 3934 | 3939 | }, |
| 3935 | 3940 | 128 => blk: { |
| 3936 | | @panic("TODO Big float"); |
| 3941 | return self.fail(scope, inst.base.src, "TODO Implement substraction for big floats", .{}); |
| 3937 | 3942 | }, |
| 3938 | 3943 | else => unreachable, |
| 3939 | 3944 | }; |