stage2: perform comptime vectorization of *_with_overflow in Value

This commit is contained in:
William Sengir 2022-03-26 15:50:55 -07:00 committed by Andrew Kelley
parent e8117bab6f
commit 86a928ce61

View File

@ -2961,7 +2961,8 @@ pub const Value = extern union {
}
pub const OverflowArithmeticResult = struct {
overflowed: bool,
/// TODO: Rename to `overflow_bit` and make of type `u1`.
overflowed: Value,
wrapped_result: Value,
};
@ -2971,6 +2972,29 @@ pub const Value = extern union {
ty: Type,
arena: Allocator,
target: Target,
) !OverflowArithmeticResult {
if (ty.zigTypeTag() == .Vector) {
const overflowed_data = try arena.alloc(Value, ty.vectorLen());
const result_data = try arena.alloc(Value, ty.vectorLen());
for (result_data) |*scalar, i| {
const of_math_result = try intAddWithOverflowScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType(), arena, target);
overflowed_data[i] = of_math_result.overflowed;
scalar.* = of_math_result.wrapped_result;
}
return OverflowArithmeticResult{
.overflowed = try Value.Tag.aggregate.create(arena, overflowed_data),
.wrapped_result = try Value.Tag.aggregate.create(arena, result_data),
};
}
return intAddWithOverflowScalar(lhs, rhs, ty, arena, target);
}
pub fn intAddWithOverflowScalar(
lhs: Value,
rhs: Value,
ty: Type,
arena: Allocator,
target: Target,
) !OverflowArithmeticResult {
const info = ty.intInfo(target);
@ -2986,7 +3010,7 @@ pub const Value = extern union {
const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
const result = try fromBigInt(arena, result_bigint.toConst());
return OverflowArithmeticResult{
.overflowed = overflowed,
.overflowed = makeBool(overflowed),
.wrapped_result = result,
};
}
@ -3097,6 +3121,29 @@ pub const Value = extern union {
ty: Type,
arena: Allocator,
target: Target,
) !OverflowArithmeticResult {
if (ty.zigTypeTag() == .Vector) {
const overflowed_data = try arena.alloc(Value, ty.vectorLen());
const result_data = try arena.alloc(Value, ty.vectorLen());
for (result_data) |*scalar, i| {
const of_math_result = try intSubWithOverflowScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType(), arena, target);
overflowed_data[i] = of_math_result.overflowed;
scalar.* = of_math_result.wrapped_result;
}
return OverflowArithmeticResult{
.overflowed = try Value.Tag.aggregate.create(arena, overflowed_data),
.wrapped_result = try Value.Tag.aggregate.create(arena, result_data),
};
}
return intSubWithOverflowScalar(lhs, rhs, ty, arena, target);
}
pub fn intSubWithOverflowScalar(
lhs: Value,
rhs: Value,
ty: Type,
arena: Allocator,
target: Target,
) !OverflowArithmeticResult {
const info = ty.intInfo(target);
@ -3112,7 +3159,7 @@ pub const Value = extern union {
const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
const wrapped_result = try fromBigInt(arena, result_bigint.toConst());
return OverflowArithmeticResult{
.overflowed = overflowed,
.overflowed = makeBool(overflowed),
.wrapped_result = wrapped_result,
};
}
@ -3207,6 +3254,29 @@ pub const Value = extern union {
ty: Type,
arena: Allocator,
target: Target,
) !OverflowArithmeticResult {
if (ty.zigTypeTag() == .Vector) {
const overflowed_data = try arena.alloc(Value, ty.vectorLen());
const result_data = try arena.alloc(Value, ty.vectorLen());
for (result_data) |*scalar, i| {
const of_math_result = try intMulWithOverflowScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType(), arena, target);
overflowed_data[i] = of_math_result.overflowed;
scalar.* = of_math_result.wrapped_result;
}
return OverflowArithmeticResult{
.overflowed = try Value.Tag.aggregate.create(arena, overflowed_data),
.wrapped_result = try Value.Tag.aggregate.create(arena, result_data),
};
}
return intMulWithOverflowScalar(lhs, rhs, ty, arena, target);
}
pub fn intMulWithOverflowScalar(
lhs: Value,
rhs: Value,
ty: Type,
arena: Allocator,
target: Target,
) !OverflowArithmeticResult {
const info = ty.intInfo(target);
@ -3231,7 +3301,7 @@ pub const Value = extern union {
}
return OverflowArithmeticResult{
.overflowed = overflowed,
.overflowed = makeBool(overflowed),
.wrapped_result = try fromBigInt(arena, result_bigint.toConst()),
};
}
@ -3921,6 +3991,29 @@ pub const Value = extern union {
ty: Type,
allocator: Allocator,
target: Target,
) !OverflowArithmeticResult {
if (ty.zigTypeTag() == .Vector) {
const overflowed_data = try allocator.alloc(Value, ty.vectorLen());
const result_data = try allocator.alloc(Value, ty.vectorLen());
for (result_data) |*scalar, i| {
const of_math_result = try shlWithOverflowScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType(), allocator, target);
overflowed_data[i] = of_math_result.overflowed;
scalar.* = of_math_result.wrapped_result;
}
return OverflowArithmeticResult{
.overflowed = try Value.Tag.aggregate.create(allocator, overflowed_data),
.wrapped_result = try Value.Tag.aggregate.create(allocator, result_data),
};
}
return shlWithOverflowScalar(lhs, rhs, ty, allocator, target);
}
pub fn shlWithOverflowScalar(
lhs: Value,
rhs: Value,
ty: Type,
allocator: Allocator,
target: Target,
) !OverflowArithmeticResult {
const info = ty.intInfo(target);
var lhs_space: Value.BigIntSpace = undefined;
@ -3941,7 +4034,7 @@ pub const Value = extern union {
result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits);
}
return OverflowArithmeticResult{
.overflowed = overflowed,
.overflowed = makeBool(overflowed),
.wrapped_result = try fromBigInt(allocator, result_bigint.toConst()),
};
}