diff options
author | lloyd <[email protected]> | 2009-10-29 02:04:05 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-10-29 02:04:05 +0000 |
commit | e9cb78ddb6ad81e562fd466481b8d93e5144e7a6 (patch) | |
tree | 88c862961ba5edc788762a63244d5a39be7668b7 /src | |
parent | ec71a46cfe5e4f975ec2ff5936809983a47849c8 (diff) |
Use register writes in the Altivec code for stores because Altivec's handling
for unaligned writes is messy as hell.
If writes are batched this is somewhat easier to deal with (somewhat).
Diffstat (limited to 'src')
-rw-r--r-- | src/utils/simd_32/simd_altivec.h | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/utils/simd_32/simd_altivec.h b/src/utils/simd_32/simd_altivec.h index a925f6dbc..e63b9bdcc 100644 --- a/src/utils/simd_32/simd_altivec.h +++ b/src/utils/simd_32/simd_altivec.h @@ -65,21 +65,30 @@ class SIMD_Altivec void store_le(byte out[]) const { - u32bit* out_32 = reinterpret_cast<u32bit*>(out); - - __vector unsigned char perm = vec_lvsl(0, (int*)0); + __vector unsigned char perm = vec_lvsl(0, (u32bit*)0); perm = vec_xor(perm, vec_splat_u8(3)); - __vector unsigned int swapped = vec_perm(reg, reg, perm); + union { + __vector unsigned int V; + u32bit R[4]; + } vec; + + vec.V = vec_perm(reg, reg, perm); - vec_st(swapped, 0, out_32); + Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]); } void store_be(byte out[]) const { - u32bit* out_32 = reinterpret_cast<u32bit*>(out); - vec_st(reg, 0, out_32); + union { + __vector unsigned int V; + u32bit R[4]; + } vec; + + vec.V = reg; + + Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]); } void rotate_left(u32bit rot) |