[PATCH 2/4] riscv: use memory operands for inline assembly load/store
Jussi Kivilinna <[email protected]> Wed, 29 Jul 2026 19:34:22 +0300
| Newsgroups | gmane.comp.encryption.gpg.libgcrypt.devel |
|---|---|
| Message-ID | <[email protected]> |
* cipher/cipher-gcm-riscv-zbb-zbc.c (load_aligned_u64x2) (store_aligned_u64x2): Use memory operand instead of register operand with offset in assembly template and 'memory' clobber. (load_unaligned_u64x2): Skip alignment check when Zicclsm is enabled. * cipher/crc-riscv-zbb-zbc.c (load_aligned_u32, load_aligned_u64x2): Use memory operand instead of register operand with offset in assembly template and 'memory' clobber. -- 'memory' clobber forced compiler to spill values around every load and store. Memory operand describes accessed object exactly, so clobber is not needed and compiler can select addressing mode itself. Signed-off-by: Jussi Kivilinna <[email protected]> --- cipher/cipher-gcm-riscv-zbb-zbc.c | 36 ++++++++++++++----------------- cipher/crc-riscv-zbb-zbc.c | 15 ++++++------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/cipher/cipher-gcm-riscv-zbb-zbc.c b/cipher/cipher-gcm-riscv-zbb-zbc.c index e32bfafe..1e97cb5c 100644 --- a/cipher/cipher-gcm-riscv-zbb-zbc.c +++ b/cipher/cipher-gcm-riscv-zbb-zbc.c @@ -43,14 +43,12 @@ load_aligned_u64x2(const void *ptr) { u64x2 vec; - asm ("ld %0, 0(%1)" + asm ("ld %0, %1" : "=r" (vec.val[0]) - : "r" (ptr) - : "memory"); - asm ("ld %0, 8(%1)" + : "m" (((const bufhelp_u64_t *)ptr)[0])); + asm ("ld %0, %1" : "=r" (vec.val[1]) - : "r" (ptr) - : "memory"); + : "m" (((const bufhelp_u64_t *)ptr)[1])); return vec; } @@ -58,12 +56,8 @@ load_aligned_u64x2(const void *ptr) static ASM_FUNC_ATTR_INLINE u64x2 load_unaligned_u64x2(const void *ptr) { - if (((uintptr_t)ptr & 7) == 0) - { - /* aligned load */ - return load_aligned_u64x2(ptr); - } - else +#if !(defined(__riscv_zicclsm) && (__riscv_zicclsm >= 1000000)) + if (UNLIKELY(((uintptr_t)ptr & 7) != 0)) { /* unaligned load */ const bufhelp_u64_t *ptr_u64 = ptr; @@ -72,19 +66,21 @@ load_unaligned_u64x2(const void *ptr) vec.val[1] = ptr_u64[1].a; return vec; } +#endif + + /* aligned load */ + return load_aligned_u64x2(ptr); } static ASM_FUNC_ATTR_INLINE void store_aligned_u64x2(void *ptr, u64x2 vec) { - asm ("sd %0, 0(%1)" - : - : "r" (vec.val[0]), "r" (ptr) - : "memory"); - asm ("sd %0, 8(%1)" - : - : "r" (vec.val[1]), "r" (ptr) - : "memory"); + asm ("sd %1, %0" + : "=m" (((bufhelp_u64_t *)ptr)[0]) + : "r" (vec.val[0])); + asm ("sd %1, %0" + : "=m" (((bufhelp_u64_t *)ptr)[1]) + : "r" (vec.val[1])); } static ASM_FUNC_ATTR_INLINE u64 diff --git a/cipher/crc-riscv-zbb-zbc.c b/cipher/crc-riscv-zbb-zbc.c index 0915fa6c..bec6806f 100644 --- a/cipher/crc-riscv-zbb-zbc.c +++ b/cipher/crc-riscv-zbb-zbc.c @@ -152,10 +152,9 @@ static ASM_FUNC_ATTR_INLINE u64 load_aligned_u32(const void *ptr) { u64 out; - asm ("lw %0, 0(%1)" + asm ("lw %0, %1" : "=r" (out) - : "r" (ptr) - : "memory"); + : "m" (((const bufhelp_u32_t *)ptr)[0])); return out; } @@ -164,14 +163,12 @@ load_aligned_u64x2(const void *ptr) { u64x2 vec; - asm ("ld %0, 0(%1)" + asm ("ld %0, %1" : "=r" (vec.lo) - : "r" (ptr) - : "memory"); - asm ("ld %0, 8(%1)" + : "m" (((const bufhelp_u64_t *)ptr)[0])); + asm ("ld %0, %1" : "=r" (vec.hi) - : "r" (ptr) - : "memory"); + : "m" (((const bufhelp_u64_t *)ptr)[1])); return vec; } -- 2.53.0