| ... | ... | @@ -2961,7 +2961,8 @@ pub const Value = extern union { |
| 2961 | 2961 | } |
| 2962 | 2962 | |
| 2963 | 2963 | pub const OverflowArithmeticResult = struct { |
| 2964 | | overflowed: bool, |
| 2964 | /// TODO: Rename to `overflow_bit` and make of type `u1`. |
| 2965 | overflowed: Value, |
| 2965 | 2966 | wrapped_result: Value, |
| 2966 | 2967 | }; |
| 2967 | 2968 | |
| ... | ... | @@ -2971,6 +2972,29 @@ pub const Value = extern union { |
| 2971 | 2972 | ty: Type, |
| 2972 | 2973 | arena: Allocator, |
| 2973 | 2974 | target: Target, |
| 2975 | ) !OverflowArithmeticResult { |
| 2976 | if (ty.zigTypeTag() == .Vector) { |
| 2977 | const overflowed_data = try arena.alloc(Value, ty.vectorLen()); |
| 2978 | const result_data = try arena.alloc(Value, ty.vectorLen()); |
| 2979 | for (result_data) |*scalar, i| { |
| 2980 | const of_math_result = try intAddWithOverflowScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType(), arena, target); |
| 2981 | overflowed_data[i] = of_math_result.overflowed; |
| 2982 | scalar.* = of_math_result.wrapped_result; |
| 2983 | } |
| 2984 | return OverflowArithmeticResult{ |
| 2985 | .overflowed = try Value.Tag.aggregate.create(arena, overflowed_data), |
| 2986 | .wrapped_result = try Value.Tag.aggregate.create(arena, result_data), |
| 2987 | }; |
| 2988 | } |
| 2989 | return intAddWithOverflowScalar(lhs, rhs, ty, arena, target); |
| 2990 | } |
| 2991 | |
| 2992 | pub fn intAddWithOverflowScalar( |
| 2993 | lhs: Value, |
| 2994 | rhs: Value, |
| 2995 | ty: Type, |
| 2996 | arena: Allocator, |
| 2997 | target: Target, |
| 2974 | 2998 | ) !OverflowArithmeticResult { |
| 2975 | 2999 | const info = ty.intInfo(target); |
| 2976 | 3000 | |
| ... | ... | @@ -2986,7 +3010,7 @@ pub const Value = extern union { |
| 2986 | 3010 | const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 2987 | 3011 | const result = try fromBigInt(arena, result_bigint.toConst()); |
| 2988 | 3012 | return OverflowArithmeticResult{ |
| 2989 | | .overflowed = overflowed, |
| 3013 | .overflowed = makeBool(overflowed), |
| 2990 | 3014 | .wrapped_result = result, |
| 2991 | 3015 | }; |
| 2992 | 3016 | } |
| ... | ... | @@ -3097,6 +3121,29 @@ pub const Value = extern union { |
| 3097 | 3121 | ty: Type, |
| 3098 | 3122 | arena: Allocator, |
| 3099 | 3123 | target: Target, |
| 3124 | ) !OverflowArithmeticResult { |
| 3125 | if (ty.zigTypeTag() == .Vector) { |
| 3126 | const overflowed_data = try arena.alloc(Value, ty.vectorLen()); |
| 3127 | const result_data = try arena.alloc(Value, ty.vectorLen()); |
| 3128 | for (result_data) |*scalar, i| { |
| 3129 | const of_math_result = try intSubWithOverflowScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType(), arena, target); |
| 3130 | overflowed_data[i] = of_math_result.overflowed; |
| 3131 | scalar.* = of_math_result.wrapped_result; |
| 3132 | } |
| 3133 | return OverflowArithmeticResult{ |
| 3134 | .overflowed = try Value.Tag.aggregate.create(arena, overflowed_data), |
| 3135 | .wrapped_result = try Value.Tag.aggregate.create(arena, result_data), |
| 3136 | }; |
| 3137 | } |
| 3138 | return intSubWithOverflowScalar(lhs, rhs, ty, arena, target); |
| 3139 | } |
| 3140 | |
| 3141 | pub fn intSubWithOverflowScalar( |
| 3142 | lhs: Value, |
| 3143 | rhs: Value, |
| 3144 | ty: Type, |
| 3145 | arena: Allocator, |
| 3146 | target: Target, |
| 3100 | 3147 | ) !OverflowArithmeticResult { |
| 3101 | 3148 | const info = ty.intInfo(target); |
| 3102 | 3149 | |
| ... | ... | @@ -3112,7 +3159,7 @@ pub const Value = extern union { |
| 3112 | 3159 | const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 3113 | 3160 | const wrapped_result = try fromBigInt(arena, result_bigint.toConst()); |
| 3114 | 3161 | return OverflowArithmeticResult{ |
| 3115 | | .overflowed = overflowed, |
| 3162 | .overflowed = makeBool(overflowed), |
| 3116 | 3163 | .wrapped_result = wrapped_result, |
| 3117 | 3164 | }; |
| 3118 | 3165 | } |
| ... | ... | @@ -3207,6 +3254,29 @@ pub const Value = extern union { |
| 3207 | 3254 | ty: Type, |
| 3208 | 3255 | arena: Allocator, |
| 3209 | 3256 | target: Target, |
| 3257 | ) !OverflowArithmeticResult { |
| 3258 | if (ty.zigTypeTag() == .Vector) { |
| 3259 | const overflowed_data = try arena.alloc(Value, ty.vectorLen()); |
| 3260 | const result_data = try arena.alloc(Value, ty.vectorLen()); |
| 3261 | for (result_data) |*scalar, i| { |
| 3262 | const of_math_result = try intMulWithOverflowScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType(), arena, target); |
| 3263 | overflowed_data[i] = of_math_result.overflowed; |
| 3264 | scalar.* = of_math_result.wrapped_result; |
| 3265 | } |
| 3266 | return OverflowArithmeticResult{ |
| 3267 | .overflowed = try Value.Tag.aggregate.create(arena, overflowed_data), |
| 3268 | .wrapped_result = try Value.Tag.aggregate.create(arena, result_data), |
| 3269 | }; |
| 3270 | } |
| 3271 | return intMulWithOverflowScalar(lhs, rhs, ty, arena, target); |
| 3272 | } |
| 3273 | |
| 3274 | pub fn intMulWithOverflowScalar( |
| 3275 | lhs: Value, |
| 3276 | rhs: Value, |
| 3277 | ty: Type, |
| 3278 | arena: Allocator, |
| 3279 | target: Target, |
| 3210 | 3280 | ) !OverflowArithmeticResult { |
| 3211 | 3281 | const info = ty.intInfo(target); |
| 3212 | 3282 | |
| ... | ... | @@ -3231,7 +3301,7 @@ pub const Value = extern union { |
| 3231 | 3301 | } |
| 3232 | 3302 | |
| 3233 | 3303 | return OverflowArithmeticResult{ |
| 3234 | | .overflowed = overflowed, |
| 3304 | .overflowed = makeBool(overflowed), |
| 3235 | 3305 | .wrapped_result = try fromBigInt(arena, result_bigint.toConst()), |
| 3236 | 3306 | }; |
| 3237 | 3307 | } |
| ... | ... | @@ -3921,6 +3991,29 @@ pub const Value = extern union { |
| 3921 | 3991 | ty: Type, |
| 3922 | 3992 | allocator: Allocator, |
| 3923 | 3993 | target: Target, |
| 3994 | ) !OverflowArithmeticResult { |
| 3995 | if (ty.zigTypeTag() == .Vector) { |
| 3996 | const overflowed_data = try allocator.alloc(Value, ty.vectorLen()); |
| 3997 | const result_data = try allocator.alloc(Value, ty.vectorLen()); |
| 3998 | for (result_data) |*scalar, i| { |
| 3999 | const of_math_result = try shlWithOverflowScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType(), allocator, target); |
| 4000 | overflowed_data[i] = of_math_result.overflowed; |
| 4001 | scalar.* = of_math_result.wrapped_result; |
| 4002 | } |
| 4003 | return OverflowArithmeticResult{ |
| 4004 | .overflowed = try Value.Tag.aggregate.create(allocator, overflowed_data), |
| 4005 | .wrapped_result = try Value.Tag.aggregate.create(allocator, result_data), |
| 4006 | }; |
| 4007 | } |
| 4008 | return shlWithOverflowScalar(lhs, rhs, ty, allocator, target); |
| 4009 | } |
| 4010 | |
| 4011 | pub fn shlWithOverflowScalar( |
| 4012 | lhs: Value, |
| 4013 | rhs: Value, |
| 4014 | ty: Type, |
| 4015 | allocator: Allocator, |
| 4016 | target: Target, |
| 3924 | 4017 | ) !OverflowArithmeticResult { |
| 3925 | 4018 | const info = ty.intInfo(target); |
| 3926 | 4019 | var lhs_space: Value.BigIntSpace = undefined; |
| ... | ... | @@ -3941,7 +4034,7 @@ pub const Value = extern union { |
| 3941 | 4034 | result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits); |
| 3942 | 4035 | } |
| 3943 | 4036 | return OverflowArithmeticResult{ |
| 3944 | | .overflowed = overflowed, |
| 4037 | .overflowed = makeBool(overflowed), |
| 3945 | 4038 | .wrapped_result = try fromBigInt(allocator, result_bigint.toConst()), |
| 3946 | 4039 | }; |
| 3947 | 4040 | } |