Skip to content

Commit dcfb896

Browse files
committed
add vec_add_u128, vec_addc_u128, vec_adde_u128 and vec_addce_u128
1 parent dd7d710 commit dcfb896

File tree

2 files changed

+122
-1
lines changed

2 files changed

+122
-1
lines changed

crates/core_arch/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
x86_amx_intrinsics,
3939
f16,
4040
keylocker_x86,
41-
aarch64_unstable_target_feature
41+
aarch64_unstable_target_feature,
42+
bigint_helper_methods
4243
)]
4344
#![cfg_attr(test, feature(test, abi_vectorcall, stdarch_internal))]
4445
#![deny(clippy::missing_inline_in_public_items)]

crates/core_arch/src/s390x/vector.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ unsafe extern "unadjusted" {
122122
#[link_name = "llvm.s390.vsbiq"] fn vsbiq(a: u128, b: u128, c: u128) -> u128;
123123
#[link_name = "llvm.s390.vsbcbiq"] fn vsbcbiq(a: u128, b: u128, c: u128) -> u128;
124124

125+
#[link_name = "llvm.s390.vacq"] fn vacq(a: u128, b: u128, c: u128) -> u128;
126+
125127
#[link_name = "llvm.s390.vscbib"] fn vscbib(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
126128
#[link_name = "llvm.s390.vscbih"] fn vscbih(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
127129
#[link_name = "llvm.s390.vscbif"] fn vscbif(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
@@ -3085,6 +3087,24 @@ pub unsafe fn vec_sum4<T: sealed::VectorSum4>(a: T, b: T) -> vector_unsigned_int
30853087
a.vec_sum4(b)
30863088
}
30873089

3090+
/// Vector Addition unsigned 128-bits
3091+
///
3092+
/// Adds unsigned quadword values.
3093+
///
3094+
/// This function operates on the vectors as 128-bit unsigned integers. It returns low 128 bits of a + b.
3095+
#[inline]
3096+
#[target_feature(enable = "vector")]
3097+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3098+
#[cfg_attr(test, assert_instr(vaq))]
3099+
pub unsafe fn vec_add_u128(
3100+
a: vector_unsigned_char,
3101+
b: vector_unsigned_char,
3102+
) -> vector_unsigned_char {
3103+
let a: u128 = transmute(a);
3104+
let b: u128 = transmute(b);
3105+
transmute(a.wrapping_add(b))
3106+
}
3107+
30883108
/// Vector Subtract unsigned 128-bits
30893109
///
30903110
/// Subtracts unsigned quadword values.
@@ -3130,9 +3150,63 @@ pub unsafe fn vec_subc_u128(
31303150
a: vector_unsigned_char,
31313151
b: vector_unsigned_char,
31323152
) -> vector_unsigned_char {
3153+
// FIXME(llvm) sadly this does not work https://github.com/llvm/llvm-project/issues/129608
3154+
// let a: u128 = transmute(a);
3155+
// let b: u128 = transmute(b);
3156+
// transmute(!a.overflowing_sub(b).1 as u128)
31333157
transmute(vscbiq(transmute(a), transmute(b)))
31343158
}
31353159

3160+
/// Vector Add Compute Carryout unsigned 128-bits
3161+
#[inline]
3162+
#[target_feature(enable = "vector")]
3163+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3164+
#[cfg_attr(test, assert_instr(vaccq))]
3165+
pub unsafe fn vec_addc_u128(
3166+
a: vector_unsigned_char,
3167+
b: vector_unsigned_char,
3168+
) -> vector_unsigned_char {
3169+
let a: u128 = transmute(a);
3170+
let b: u128 = transmute(b);
3171+
transmute(a.overflowing_add(b).1 as u128)
3172+
}
3173+
3174+
/// Vector Add With Carry unsigned 128-bits
3175+
#[inline]
3176+
#[target_feature(enable = "vector")]
3177+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3178+
#[cfg_attr(test, assert_instr(vacq))]
3179+
pub unsafe fn vec_adde_u128(
3180+
a: vector_unsigned_char,
3181+
b: vector_unsigned_char,
3182+
c: vector_unsigned_char,
3183+
) -> vector_unsigned_char {
3184+
let a: u128 = transmute(a);
3185+
let b: u128 = transmute(b);
3186+
let c: u128 = transmute(c);
3187+
// FIXME(llvm) sadly this does not work
3188+
// let (d, _carry) = a.carrying_add(b, c & 1 != 0);
3189+
// transmute(d)
3190+
transmute(vacq(a, b, c))
3191+
}
3192+
3193+
/// Vector Add With Carry Compute Carry unsigned 128-bits
3194+
#[inline]
3195+
#[target_feature(enable = "vector")]
3196+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3197+
#[cfg_attr(test, assert_instr(vacccq))]
3198+
pub unsafe fn vec_addec_u128(
3199+
a: vector_unsigned_char,
3200+
b: vector_unsigned_char,
3201+
c: vector_unsigned_char,
3202+
) -> vector_unsigned_char {
3203+
let a: u128 = transmute(a);
3204+
let b: u128 = transmute(b);
3205+
let c: u128 = transmute(c);
3206+
let (_d, carry) = a.carrying_add(b, c & 1 != 0);
3207+
transmute(carry as u128)
3208+
}
3209+
31363210
/// Subtracts unsigned quadword values with carry bit from a previous operation.
31373211
///
31383212
/// This function operates on the vectors as 128-bit unsigned integers. It returns a vector containing the result of subtracting of b from a,
@@ -4246,4 +4320,50 @@ mod tests {
42464320
[5, 6, 7, 8],
42474321
[0, 12, 0, 0]
42484322
}
4323+
4324+
test_vec_2! { test_vec_add_u128, vec_add_u128, u8x16,
4325+
[0x01, 0x05, 0x0F, 0x1A, 0x2F, 0x3F, 0x50, 0x65,
4326+
0x7A, 0x8F, 0x9A, 0xAD, 0xB0, 0xC3, 0xD5, 0xE8],
4327+
[0xF0, 0xEF, 0xC3, 0xB1, 0x92, 0x71, 0x5A, 0x43,
4328+
0x3B, 0x29, 0x13, 0x04, 0xD7, 0xA1, 0x8C, 0x76],
4329+
[0xF1, 0xF4, 0xD2, 0xCB, 0xC1, 0xB0, 0xAA, 0xA8, 0xB5, 0xB8, 0xAD, 0xB2, 0x88, 0x65, 0x62, 0x5E]
4330+
}
4331+
4332+
#[simd_test(enable = "vector")]
4333+
fn test_vec_addc_u128() {
4334+
unsafe {
4335+
let a = u128::MAX;
4336+
let b = 1u128;
4337+
4338+
let d: u128 = transmute(vec_addc_u128(transmute(a), transmute(b)));
4339+
assert!(a.checked_add(b).is_none());
4340+
assert_eq!(d, 1);
4341+
4342+
let a = 1u128;
4343+
let b = 1u128;
4344+
4345+
let d: u128 = transmute(vec_addc_u128(transmute(a), transmute(b)));
4346+
assert!(a.checked_add(b).is_some());
4347+
assert_eq!(d, 0);
4348+
}
4349+
}
4350+
4351+
#[simd_test(enable = "vector")]
4352+
fn test_vec_subc_u128() {
4353+
unsafe {
4354+
let a = 0u128;
4355+
let b = 1u128;
4356+
4357+
let d: u128 = transmute(vec_subc_u128(transmute(a), transmute(b)));
4358+
assert!(a.checked_sub(b).is_none());
4359+
assert_eq!(d, 0);
4360+
4361+
let a = 1u128;
4362+
let b = 1u128;
4363+
4364+
let d: u128 = transmute(vec_subc_u128(transmute(a), transmute(b)));
4365+
assert!(a.checked_sub(b).is_some());
4366+
assert_eq!(d, 1);
4367+
}
4368+
}
42494369
}

0 commit comments

Comments
 (0)