From mattst88 at gmail.com Wed Sep 2 15:17:20 2026 From: mattst88 at gmail.com (Matt Turner) Date: Wed, 2 Sep 2026 09:17:20 -0400 Subject: [PATCH] mpi: Drop casts from inline asm output operands. Message-ID: <20260902131720.409681-1-mattst88@gmail.com> * mpi/longlong.h [__a29k__, __alpha, __gmicro__, __hppa, __i960__, __mc68000__, __m88000__, __mips__, __mips, __ns32000__, __pyr__, __ibm032__, __sh2__, __sparc__, __vax__, __z8000__]: Drop the casts on asm output operands. -- Using a cast as an lvalue is a GCC extension that clang does not implement. Clang rejects it with -Winvalid-gnu-asm-cast, which is an error by default, so these blocks fail to build with clang. The casts do nothing. GCC accepts a cast in an asm output only when it is a no-op, and rejects it with "lvalue required in 'asm' statement" otherwise, so any code that compiles today already passes an operand of the right type. GMP's longlong.h dropped these long ago. The Z8000 block is the exception. There W_TYPE_SIZE is 16, so the cast to unsigned int is not a no-op and GCC would reject it too; that block has been dead for a long time and is fixed here for consistency. Casts on *input* operands are left alone: those are ordinary rvalue conversions, and on x86 count_leading_zeros/count_trailing_zeros the "rm" ((USItype)(x)) cast is what selects the operand width. Checked with the cross toolchains available here. GCC generates identical assembly before and after for alpha, hppa, mc68000, sh4, 32-bit sparc and mips. Clang builds the sparc block only after this change; it has no back end for alpha, hppa or mc68000, so those could not be checked with clang. The blocks with no compiler to test against (a29k, gmicro, i960, m88k, ns32000, pyr, RT/ROMP, vax, z8000) are changed mechanically. The MIPS asm blocks are unreachable in practice: any compiler new enough to matter takes the preceding __GNUC__ >= 5 branch, which uses a plain wide multiply, and the asm variants no longer assemble anyway now that GCC has removed the "h" constraint ("impossible constraint in 'asm'"). Signed-off-by: Matt Turner --- mpi/longlong.h | 174 ++++++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git ./mpi/longlong.h ./mpi/longlong.h index 453f2704..b27d0b88 100644 --- ./mpi/longlong.h +++ ./mpi/longlong.h @@ -133,8 +133,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %1,%4,%5\n" \ "addc %0,%2,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ @@ -142,8 +142,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %1,%4,%5\n" \ "subc %0,%2,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "r" ((USItype)(al)), \ @@ -152,24 +152,24 @@ SPDX-License-Identifier: LGPL-2.1-or-later do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("multiplu %0,%1,%2" \ - : "=r" ((USItype)(xl)) \ + : "=r" (xl) \ : "r" (__m0), \ "r" (__m1)); \ __asm__ ("multmu %0,%1,%2" \ - : "=r" ((USItype)(xh)) \ + : "=r" (xh) \ : "r" (__m0), \ "r" (__m1)); \ } while (0) # define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("dividu %0,%3,%4" \ - : "=r" ((USItype)(q)), \ - "=q" ((USItype)(r)) \ + : "=r" (q), \ + "=q" (r) \ : "1" ((USItype)(n1)), \ "r" ((USItype)(n0)), \ "r" ((USItype)(d))) # define count_leading_zeros(count, x) \ __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ + : "=r" (count) \ : "r" ((USItype)(x))) # define COUNT_LEADING_ZEROS_0 32 #endif /* __a29k__ */ @@ -180,7 +180,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later do { \ UDItype __m0 = (m0), __m1 = (m1); \ __asm__ ("umulh %r1,%2,%0" \ - : "=r" ((UDItype)(ph)) \ + : "=r" (ph) \ : "%rJ" (__m0), \ "rI" (__m1)); \ (pl) = __m0 * __m1; \ @@ -365,8 +365,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add.w %5,%1\n" \ "addx %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ + : "=g" (sh), \ + "=&g" (sl) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -374,22 +374,22 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub.w %5,%1\n" \ "subx %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ + : "=g" (sh), \ + "=&g" (sl) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ "g" ((USItype)(bl))) # define umul_ppmm(ph, pl, m0, m1) \ __asm__ ("mulx %3,%0,%1" \ - : "=g" ((USItype)(ph)), \ - "=r" ((USItype)(pl)) \ + : "=g" (ph), \ + "=r" (pl) \ : "%0" ((USItype)(m0)), \ "g" ((USItype)(m1))) # define udiv_qrnnd(q, r, nh, nl, d) \ __asm__ ("divx %4,%0,%1" \ - : "=g" ((USItype)(q)), \ - "=r" ((USItype)(r)) \ + : "=g" (q), \ + "=r" (r) \ : "1" ((USItype)(nh)), \ "0" ((USItype)(nl)), \ "g" ((USItype)(d))) @@ -408,8 +408,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %4,%5,%1\n\t" \ "addc %2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%rM" ((USItype)(ah)), \ "rM" ((USItype)(bh)), \ "%rM" ((USItype)(al)), \ @@ -417,8 +417,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %4,%5,%1\n\t" \ "subb %2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "rM" ((USItype)(ah)), \ "rM" ((USItype)(bh)), \ "rM" ((USItype)(al)), \ @@ -658,8 +658,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); __asm__ ("cmpo 1,0\n" \ "addc %5,%4,%1\n" \ "addc %3,%2,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%dI" ((USItype)(ah)), \ "dI" ((USItype)(bh)), \ "%dI" ((USItype)(al)), \ @@ -668,8 +668,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); __asm__ ("cmpo 0,0\n" \ "subc %5,%4,%1\n" \ "subc %3,%2,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "dI" ((USItype)(ah)), \ "dI" ((USItype)(bh)), \ "dI" ((USItype)(al)), \ @@ -733,8 +733,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add%.l %5,%1\n" \ "addx%.l %3,%0" \ - : "=d" ((USItype)(sh)), \ - "=&d" ((USItype)(sl)) \ + : "=d" (sh), \ + "=&d" (sl) \ : "%0" ((USItype)(ah)), \ "d" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -742,8 +742,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub%.l %5,%1\n" \ "subx%.l %3,%0" \ - : "=d" ((USItype)(sh)), \ - "=&d" ((USItype)(sl)) \ + : "=d" (sh), \ + "=&d" (sl) \ : "0" ((USItype)(ah)), \ "d" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -751,29 +751,29 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) # define umul_ppmm(w1, w0, u, v) \ __asm__ ("mulu%.l %3,%1:%0" \ - : "=d" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ + : "=d" (w0), \ + "=d" (w1) \ : "%0" ((USItype)(u)), \ "dmi" ((USItype)(v))) # define UMUL_TIME 45 # define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divu%.l %4,%1:%0" \ - : "=d" ((USItype)(q)), \ - "=d" ((USItype)(r)) \ + : "=d" (q), \ + "=d" (r) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "dmi" ((USItype)(d))) # define UDIV_TIME 90 # define sdiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divs%.l %4,%1:%0" \ - : "=d" ((USItype)(q)), \ - "=d" ((USItype)(r)) \ + : "=d" (q), \ + "=d" (r) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "dmi" ((USItype)(d))) # define count_leading_zeros(count, x) \ __asm__ ("bfffo %1{%b2:%b2},%0" \ - : "=d" ((USItype)(count)) \ + : "=d" (count) \ : "od" ((USItype)(x)), "n" (0)) # define COUNT_LEADING_ZEROS_0 32 # else /* not mc68020 */ @@ -801,7 +801,7 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); " add%.l %3,%1 \n" \ " addx%.l %2,%0 \n" \ " | End inlined umul_ppmm" \ - : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \ + : "=&d" (xh), "=&d" (xl), \ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \ } while (0) @@ -818,8 +818,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addu.co %1,%r4,%r5\n" \ "addu.ci %0,%r2,%r3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%rJ" ((USItype)(ah)), \ "rJ" ((USItype)(bh)), \ "%rJ" ((USItype)(al)), \ @@ -827,8 +827,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subu.co %1,%r4,%r5\n" \ "subu.ci %0,%r2,%r3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "rJ" ((USItype)(ah)), \ "rJ" ((USItype)(bh)), \ "rJ" ((USItype)(al)), \ @@ -884,8 +884,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 # define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3" \ - : "=l" ((USItype)(w0)), \ - "=h" ((USItype)(w1)) \ + : "=l" (w0), \ + "=h" (w1) \ : "d" ((USItype)(u)), \ "d" ((USItype)(v))) # else @@ -893,8 +893,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); __asm__ ("multu %2,%3 \n" \ "mflo %0 \n" \ "mfhi %1" \ - : "=d" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ + : "=d" (w0), \ + "=d" (w1) \ : "d" ((USItype)(u)), \ "d" ((USItype)(v))) # endif @@ -919,8 +919,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 # define umul_ppmm(w1, w0, u, v) \ __asm__ ("dmultu %2,%3" \ - : "=l" ((UDItype)(w0)), \ - "=h" ((UDItype)(w1)) \ + : "=l" (w0), \ + "=h" (w1) \ : "d" ((UDItype)(u)), \ "d" ((UDItype)(v))) # else @@ -928,8 +928,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); __asm__ ("dmultu %2,%3 \n" \ "mflo %0 \n" \ "mfhi %1" \ - : "=d" ((UDItype)(w0)), \ - "=d" ((UDItype)(w1)) \ + : "=d" (w0), \ + "=d" (w1) \ : "d" ((UDItype)(u)), \ "d" ((UDItype)(v))) # endif @@ -971,7 +971,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define count_trailing_zeros(count,x) \ do { __asm__ ("ffsd %2,%0" \ - : "=r" ((USItype) (count)) \ + : "=r" (count) \ : "0" ((USItype) 0), \ "r" ((USItype) (x))); \ } while (0) @@ -1120,8 +1120,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addw %5,%1 \n" \ "addwc %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -1129,8 +1129,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subw %5,%1 \n" \ "subwb %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -1156,8 +1156,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("a %1,%5 \n" \ "ae %0,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%0" ((USItype)(ah)), \ "r" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -1165,8 +1165,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("s %1,%5\n" \ "se %0,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "0" ((USItype)(ah)), \ "r" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -1195,8 +1195,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "m r2,%3 \n" \ "cas %0,r2,r0 \n" \ "mfs r10,%1" \ - : "=r" ((USItype)(ph)), \ - "=r" ((USItype)(pl)) \ + : "=r" (ph), \ + "=r" (pl) \ : "%r" (__m0), \ "r" (__m1) \ : "r2"); \ @@ -1209,12 +1209,12 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); do { \ if ((x) >= 0x10000) \ __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ + : "=r" (count) \ : "r" ((USItype)(x) >> 16)); \ else \ { \ __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ + : "=r" (count) \ : "r" ((USItype)(x))); \ (count) += 16; \ } \ @@ -1232,8 +1232,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "dmulu.l %2,%3\n" \ "sts macl,%1\n" \ "sts mach,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ + : "=r" (w1), \ + "=r" (w0) \ : "r" ((USItype)(u)), \ "r" ((USItype)(v)) \ : "macl", "mach") @@ -1247,8 +1247,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addcc %r4,%5,%1\n" \ "addx %r2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%rJ" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "%rJ" ((USItype)(al)), \ @@ -1257,8 +1257,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subcc %r4,%5,%1\n" \ "subx %r2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "rJ" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "rJ" ((USItype)(al)), \ @@ -1271,8 +1271,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); but INTERPRETED AS UNSIGNED. */ # define umul_ppmm(w1, w0, u, v) \ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ + : "=r" (w1), \ + "=r" (w0) \ : "r" ((USItype)(u)), \ "r" ((USItype)(v))) # define UMUL_TIME 5 @@ -1281,7 +1281,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); do { \ USItype __q; \ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \ - : "=r" ((USItype)(__q)) \ + : "=r" (__q) \ : "r" ((USItype)(n1)), \ "r" ((USItype)(n0)), \ "r" ((USItype)(d))); \ @@ -1296,8 +1296,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); instructions scan (ffs from high bit) and divscc. */ # define umul_ppmm(w1, w0, u, v) \ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ + : "=r" (w1), \ + "=r" (w0) \ : "r" ((USItype)(u)), \ "r" ((USItype)(v))) # define UMUL_TIME 5 @@ -1341,8 +1341,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); " bl,a 1f \n" \ " add %1,%4,%1 \n" \ "1: ! End of inline udiv_qrnnd" \ - : "=r" ((USItype)(q)), \ - "=r" ((USItype)(r)) \ + : "=r" (q), \ + "=r" (r) \ : "r" ((USItype)(n1)), \ "r" ((USItype)(n0)), \ "rI" ((USItype)(d)) \ @@ -1350,7 +1350,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define UDIV_TIME 37 # define count_leading_zeros(count, x) \ __asm__ ("scan %1,0,%0" \ - : "=r" ((USItype)(x)) \ + : "=r" (x) \ : "r" ((USItype)(count))) /* Early sparclites return 63 for an argument of 0, but they warn that future implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 @@ -1400,8 +1400,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); " mulscc %%g1,0,%%g1 \n" \ " add %%g1,%%g2,%0 \n" \ " rd %%y,%1" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ + : "=r" (w1), \ + "=r" (w0) \ : "%rI" ((USItype)(u)), \ "r" ((USItype)(v)) \ : "%g1", "%g2" __AND_CLOBBER_CC) @@ -1428,8 +1428,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addl2 %5,%1\n" \ "adwc %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ + : "=g" (sh), \ + "=&g" (sl) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -1437,8 +1437,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subl2 %5,%1\n" \ "sbwc %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ + : "=g" (sh), \ + "=&g" (sl) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -1476,16 +1476,16 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); #if defined (__z8000__) && W_TYPE_SIZE == 16 # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ - : "=r" ((unsigned int)(sh)), \ - "=&r" ((unsigned int)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%0" ((unsigned int)(ah)), \ "r" ((unsigned int)(bh)), \ "%1" ((unsigned int)(al)), \ "rQR" ((unsigned int)(bl))) # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ - : "=r" ((unsigned int)(sh)), \ - "=&r" ((unsigned int)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "0" ((unsigned int)(ah)), \ "r" ((unsigned int)(bh)), \ "1" ((unsigned int)(al)), \ -- 2.54.0 From gniibe at fsij.org Thu Sep 3 09:22:50 2026 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 03 Sep 2026 16:22:50 +0900 Subject: [PATCH] mpi: Drop casts from inline asm output operands. In-Reply-To: <20260902131720.409681-1-mattst88@gmail.com> References: <20260902131720.409681-1-mattst88@gmail.com> Message-ID: <87bjaekddh.fsf@haruna.fsij.org> Hello, Matt Turner wrote: > Using a cast as an lvalue is a GCC extension that clang does not > implement. Clang rejects it with -Winvalid-gnu-asm-cast, which is an > error by default, so these blocks fail to build with clang. Please find a workaround for Clang. IIUC, please use -Wno-invalid-gnu-asm-cast option. If really needed, we could consider adding the option for Clang in libgcrypt/configure.ac. For longlong.h, the upstream used to be GNU C library. It is GCC now (gcc/include/longlong.h). We don't want further differences of our own from upstream. -- From mattst88 at gmail.com Thu Sep 3 20:32:57 2026 From: mattst88 at gmail.com (Matt Turner) Date: Thu, 3 Sep 2026 14:32:57 -0400 Subject: [PATCH] mpi: Drop casts from inline asm output operands. In-Reply-To: <87bjaekddh.fsf@haruna.fsij.org> References: <20260902131720.409681-1-mattst88@gmail.com> <87bjaekddh.fsf@haruna.fsij.org> Message-ID: On Thu, Sep 3, 2026 at 3:22 AM NIIBE Yutaka wrote: > > Hello, > > Matt Turner wrote: > > Using a cast as an lvalue is a GCC extension that clang does not > > implement. Clang rejects it with -Winvalid-gnu-asm-cast, which is an > > error by default, so these blocks fail to build with clang. > > Please find a workaround for Clang. IIUC, please use > -Wno-invalid-gnu-asm-cast option. If really needed, we could consider > adding the option for Clang in libgcrypt/configure.ac. > > For longlong.h, the upstream used to be GNU C library. It is GCC now > (gcc/include/longlong.h). > > We don't want further differences of our own from upstream. Ah, thank you. I'll fix this in GCC first and then return to this. From jussi.kivilinna at iki.fi Tue Sep 8 13:46:41 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:41 +0300 Subject: [PATCH 5/6] tests/basic: deduplicate vector cluttering hwf detection In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-5-jussi.kivilinna@iki.fi> * tests/basic.c (clutter_vector_registers): Replace per-architecture hwflist parsing with table driven detection. -- Each architecture had own copy of hwflist parsing and init handling. Signed-off-by: Jussi Kivilinna --- tests/basic.c | 121 ++++++++++++++++++-------------------------------- 1 file changed, 42 insertions(+), 79 deletions(-) diff --git a/tests/basic.c b/tests/basic.c index 4c5f6038..405f9861 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -307,95 +307,58 @@ clutter_vector_registers(void) static unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; static int data_init; #endif +#if defined(CLUTTER_VECTOR_REGISTER_AMD64) || \ + defined(CLUTTER_VECTOR_REGISTER_I386) + static int have_ymm; + static int have_zmm; +#endif + static int have_vectors; + static struct + { + const char *match; + int *out_have; + int required; + int have; + } hwfeatures[] = + { #if defined(CLUTTER_VECTOR_REGISTER_AARCH64) || \ defined(CLUTTER_VECTOR_REGISTER_NEON) - static int init; - static int have_neon; - - if (!init) - { - char *string; - - string = gcry_get_config (0, "hwflist"); - if (string) - { - have_neon = (strstr(string, "arm-neon:") != NULL); - xfree(string); - } - init = 1; - } - - if (!have_neon) - return; + { "arm-neon:", &have_vectors, 1, 0 }, #elif defined(CLUTTER_VECTOR_REGISTER_AMD64) || \ defined(CLUTTER_VECTOR_REGISTER_I386) - static int init; - static int have_sse2; - static int have_avx; - static int have_avx512; - - if (!init) - { - char *string; - - string = gcry_get_config (0, "hwflist"); - if (string) - { - int have_ssse3 = (strstr(string, "intel-ssse3:") != NULL); - have_sse2 = have_ssse3; /* XMM registers supported */ - have_avx = (strstr(string, "intel-avx:") != NULL); /* YMM */ - have_avx512 = (strstr(string, "intel-avx512:") != NULL); /* ZMM */ - xfree(string); - } - -#ifdef CLUTTER_VECTOR_REGISTER_AMD64 - have_sse2 = 1; -#endif - - init = 1; - } - - if (!have_sse2) - return; + { "intel-ssse3:", &have_vectors, 1, 0 }, + { "intel-avx:", &have_ymm, 0, 0 }, + { "intel-avx512:", &have_zmm, 0, 0 }, #elif defined(CLUTTER_VECTOR_REGISTER_RISCV) - static int init; - static int have_rvv; + { "riscv-v:", &have_vectors, 1, 0 }, +#elif defined(CLUTTER_VECTOR_REGISTER_PPC) + { "ppc-arch_2_07:", &have_vectors, 1, 0 }, +#endif + }; + static int hwf_init = ((int)DIM(hwfeatures) == 0); - if (!init) + if (!hwf_init) { - char *string; - - string = gcry_get_config (0, "hwflist"); - if (string) + char *hwflist = gcry_get_config (0, "hwflist"); + if (hwflist) { - have_rvv = (strstr(string, "riscv-v:") != NULL); - xfree(string); - } - init = 1; - } + int i; - if (!have_rvv) - return; -#elif defined(CLUTTER_VECTOR_REGISTER_PPC) - static int init; - static int have_ppc_vec; - - if (!init) - { - char *string; + for (i = 0; i < (int)DIM(hwfeatures); i++) + { + int have = (strstr(hwflist, hwfeatures[i].match) != NULL); + hwfeatures[i].have = have; + *hwfeatures[i].out_have |= have; + } - string = gcry_get_config (0, "hwflist"); - if (string) - { - have_ppc_vec = (strstr(string, "ppc-arch_2_07:") != NULL); - xfree(string); + xfree(hwflist); } - init = 1; + + hwf_init = 1; } - if (!have_ppc_vec) + if (!have_vectors) return; -#endif #ifdef CLUTTER_VECTOR_REGISTER_COUNT if (!data_init) @@ -409,7 +372,7 @@ clutter_vector_registers(void) if (0) { } # ifdef HAVE_GCC_INLINE_ASM_AVX512 - else if (have_avx512) + else if (have_zmm) asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n" "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n" "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n" @@ -455,7 +418,7 @@ clutter_vector_registers(void) ); # endif # ifdef HAVE_GCC_INLINE_ASM_AVX - else if (have_avx) + else if (have_ymm) asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n" "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n" "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n" @@ -506,7 +469,7 @@ clutter_vector_registers(void) if (0) { } # ifdef HAVE_GCC_INLINE_ASM_AVX512 - else if (have_avx512) + else if (have_zmm) asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n" "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n" "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n" @@ -522,7 +485,7 @@ clutter_vector_registers(void) ); # endif # ifdef HAVE_GCC_INLINE_ASM_AVX - else if (have_avx) + else if (have_ymm) asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n" "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n" "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n" -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:38 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:38 +0300 Subject: [PATCH 2/6] tests/basic: clutter YMM and ZMM registers on i386 and AMD64 In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-2-jussi.kivilinna@iki.fi> * tests/basic.c (CLUTTER_VECTOR_REGISTER_COUNT) [CLUTTER_VECTOR_REGISTER_AMD64]: Increase to 32. (clutter_vector_registers): Make clutter data static and prepare it only once. [CLUTTER_VECTOR_REGISTER_AMD64, CLUTTER_VECTOR_REGISTER_I386]: Detect AVX and AVX512 from hwflist; add YMM and ZMM register cluttering. -- Cluttering only XMM registers left upper halfs of YMM and ZMM registers untouched, so bugs in AVX and AVX512 implementations could pass unnoticed. Signed-off-by: Jussi Kivilinna --- tests/basic.c | 209 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 167 insertions(+), 42 deletions(-) diff --git a/tests/basic.c b/tests/basic.c index 9ec1b596..00d6586d 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -246,7 +246,7 @@ progress_handler (void *cb_data, const char *what, int printchar, defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \ defined(__SSE2__) # define CLUTTER_VECTOR_REGISTER_AMD64 1 -# define CLUTTER_VECTOR_REGISTER_COUNT 16 +# define CLUTTER_VECTOR_REGISTER_COUNT 32 #elif defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 && \ defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(__SSE2__) # define CLUTTER_VECTOR_REGISTER_I386 1 @@ -295,7 +295,8 @@ static inline ALWAYS_INLINE void clutter_vector_registers(void) { #ifdef CLUTTER_VECTOR_REGISTER_COUNT - unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; + static unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; + static int data_init; #if defined(CLUTTER_VECTOR_REGISTER_AARCH64) || \ defined(CLUTTER_VECTOR_REGISTER_NEON) static int init; @@ -316,9 +317,12 @@ clutter_vector_registers(void) if (!have_neon) return; -#elif defined(CLUTTER_VECTOR_REGISTER_I386) +#elif defined(CLUTTER_VECTOR_REGISTER_AMD64) || \ + defined(CLUTTER_VECTOR_REGISTER_I386) static int init; - static int have_ssse3; + static int have_sse2; + static int have_avx; + static int have_avx512; if (!init) { @@ -327,55 +331,176 @@ clutter_vector_registers(void) string = gcry_get_config (0, "hwflist"); if (string) { - have_ssse3 = (strstr(string, "intel-ssse3:") != NULL); + int have_ssse3 = (strstr(string, "intel-ssse3:") != NULL); + have_sse2 = have_ssse3; /* XMM registers supported */ + have_avx = (strstr(string, "intel-avx:") != NULL); /* YMM */ + have_avx512 = (strstr(string, "intel-avx512:") != NULL); /* ZMM */ xfree(string); } + +#ifdef CLUTTER_VECTOR_REGISTER_AMD64 + have_sse2 = 1; +#endif + init = 1; } - if (!have_ssse3) + if (!have_sse2) return; #endif - prepare_vector_data(data); + if (!data_init) + { + prepare_vector_data(data); + data_init = 1; + } #if defined(CLUTTER_VECTOR_REGISTER_AMD64) - asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n" - "movdqu (1 * 16)(%[data]), %%xmm1\n" - "movdqu (2 * 16)(%[data]), %%xmm2\n" - "movdqu (3 * 16)(%[data]), %%xmm3\n" - "movdqu (4 * 16)(%[data]), %%xmm4\n" - "movdqu (5 * 16)(%[data]), %%xmm5\n" - "movdqu (6 * 16)(%[data]), %%xmm6\n" - "movdqu (7 * 16)(%[data]), %%xmm7\n" - "movdqu (8 * 16)(%[data]), %%xmm8\n" - "movdqu (9 * 16)(%[data]), %%xmm9\n" - "movdqu (10 * 16)(%[data]), %%xmm10\n" - "movdqu (11 * 16)(%[data]), %%xmm11\n" - "movdqu (12 * 16)(%[data]), %%xmm12\n" - "movdqu (13 * 16)(%[data]), %%xmm13\n" - "movdqu (14 * 16)(%[data]), %%xmm14\n" - "movdqu (15 * 16)(%[data]), %%xmm15\n" - : - : [data] "r" (&data[0]) - : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", - "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", - "xmm13", "xmm14", "xmm15" - ); + if (0) + { } +# ifdef HAVE_GCC_INLINE_ASM_AVX512 + else if (have_avx512) + asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n" + "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n" + "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n" + "vbroadcasti32x4 (3 * 16)(%[data]), %%zmm3\n" + "vbroadcasti32x4 (4 * 16)(%[data]), %%zmm4\n" + "vbroadcasti32x4 (5 * 16)(%[data]), %%zmm5\n" + "vbroadcasti32x4 (6 * 16)(%[data]), %%zmm6\n" + "vbroadcasti32x4 (7 * 16)(%[data]), %%zmm7\n" + "vbroadcasti32x4 (8 * 16)(%[data]), %%zmm8\n" + "vbroadcasti32x4 (9 * 16)(%[data]), %%zmm9\n" + "vbroadcasti32x4 (10 * 16)(%[data]), %%zmm10\n" + "vbroadcasti32x4 (11 * 16)(%[data]), %%zmm11\n" + "vbroadcasti32x4 (12 * 16)(%[data]), %%zmm12\n" + "vbroadcasti32x4 (13 * 16)(%[data]), %%zmm13\n" + "vbroadcasti32x4 (14 * 16)(%[data]), %%zmm14\n" + "vbroadcasti32x4 (15 * 16)(%[data]), %%zmm15\n" + "vbroadcasti32x4 (16 * 16)(%[data]), %%zmm16\n" + "vbroadcasti32x4 (17 * 16)(%[data]), %%zmm17\n" + "vbroadcasti32x4 (18 * 16)(%[data]), %%zmm18\n" + "vbroadcasti32x4 (19 * 16)(%[data]), %%zmm19\n" + "vbroadcasti32x4 (20 * 16)(%[data]), %%zmm20\n" + "vbroadcasti32x4 (21 * 16)(%[data]), %%zmm21\n" + "vbroadcasti32x4 (22 * 16)(%[data]), %%zmm22\n" + "vbroadcasti32x4 (23 * 16)(%[data]), %%zmm23\n" + "vbroadcasti32x4 (24 * 16)(%[data]), %%zmm24\n" + "vbroadcasti32x4 (25 * 16)(%[data]), %%zmm25\n" + "vbroadcasti32x4 (26 * 16)(%[data]), %%zmm26\n" + "vbroadcasti32x4 (27 * 16)(%[data]), %%zmm27\n" + "vbroadcasti32x4 (28 * 16)(%[data]), %%zmm28\n" + "vbroadcasti32x4 (29 * 16)(%[data]), %%zmm29\n" + "vbroadcasti32x4 (30 * 16)(%[data]), %%zmm30\n" + "vbroadcasti32x4 (31 * 16)(%[data]), %%zmm31\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", + "xmm13", "xmm14", "xmm15" +# ifdef __AVX512F__ + , "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", + "xmm22", "xmm23", "xmm24", "xmm25", "xmm26", "xmm27", + "xmm28", "xmm29", "xmm30", "xmm31" +# endif + ); +# endif +# ifdef HAVE_GCC_INLINE_ASM_AVX + else if (have_avx) + asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n" + "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n" + "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n" + "vbroadcastf128 (3 * 16)(%[data]), %%ymm3\n" + "vbroadcastf128 (4 * 16)(%[data]), %%ymm4\n" + "vbroadcastf128 (5 * 16)(%[data]), %%ymm5\n" + "vbroadcastf128 (6 * 16)(%[data]), %%ymm6\n" + "vbroadcastf128 (7 * 16)(%[data]), %%ymm7\n" + "vbroadcastf128 (8 * 16)(%[data]), %%ymm8\n" + "vbroadcastf128 (9 * 16)(%[data]), %%ymm9\n" + "vbroadcastf128 (10 * 16)(%[data]), %%ymm10\n" + "vbroadcastf128 (11 * 16)(%[data]), %%ymm11\n" + "vbroadcastf128 (12 * 16)(%[data]), %%ymm12\n" + "vbroadcastf128 (13 * 16)(%[data]), %%ymm13\n" + "vbroadcastf128 (14 * 16)(%[data]), %%ymm14\n" + "vbroadcastf128 (15 * 16)(%[data]), %%ymm15\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", + "xmm13", "xmm14", "xmm15" + ); +# endif + else + asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n" + "movdqu (1 * 16)(%[data]), %%xmm1\n" + "movdqu (2 * 16)(%[data]), %%xmm2\n" + "movdqu (3 * 16)(%[data]), %%xmm3\n" + "movdqu (4 * 16)(%[data]), %%xmm4\n" + "movdqu (5 * 16)(%[data]), %%xmm5\n" + "movdqu (6 * 16)(%[data]), %%xmm6\n" + "movdqu (7 * 16)(%[data]), %%xmm7\n" + "movdqu (8 * 16)(%[data]), %%xmm8\n" + "movdqu (9 * 16)(%[data]), %%xmm9\n" + "movdqu (10 * 16)(%[data]), %%xmm10\n" + "movdqu (11 * 16)(%[data]), %%xmm11\n" + "movdqu (12 * 16)(%[data]), %%xmm12\n" + "movdqu (13 * 16)(%[data]), %%xmm13\n" + "movdqu (14 * 16)(%[data]), %%xmm14\n" + "movdqu (15 * 16)(%[data]), %%xmm15\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", + "xmm13", "xmm14", "xmm15" + ); #elif defined(CLUTTER_VECTOR_REGISTER_I386) - asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n" - "movdqu (1 * 16)(%[data]), %%xmm1\n" - "movdqu (2 * 16)(%[data]), %%xmm2\n" - "movdqu (3 * 16)(%[data]), %%xmm3\n" - "movdqu (4 * 16)(%[data]), %%xmm4\n" - "movdqu (5 * 16)(%[data]), %%xmm5\n" - "movdqu (6 * 16)(%[data]), %%xmm6\n" - "movdqu (7 * 16)(%[data]), %%xmm7\n" - : - : [data] "r" (&data[0]) - : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", - "xmm6", "xmm7" - ); + if (0) + { } +# ifdef HAVE_GCC_INLINE_ASM_AVX512 + else if (have_avx512) + asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n" + "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n" + "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n" + "vbroadcasti32x4 (3 * 16)(%[data]), %%zmm3\n" + "vbroadcasti32x4 (4 * 16)(%[data]), %%zmm4\n" + "vbroadcasti32x4 (5 * 16)(%[data]), %%zmm5\n" + "vbroadcasti32x4 (6 * 16)(%[data]), %%zmm6\n" + "vbroadcasti32x4 (7 * 16)(%[data]), %%zmm7\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7" + ); +# endif +# ifdef HAVE_GCC_INLINE_ASM_AVX + else if (have_avx) + asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n" + "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n" + "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n" + "vbroadcastf128 (3 * 16)(%[data]), %%ymm3\n" + "vbroadcastf128 (4 * 16)(%[data]), %%ymm4\n" + "vbroadcastf128 (5 * 16)(%[data]), %%ymm5\n" + "vbroadcastf128 (6 * 16)(%[data]), %%ymm6\n" + "vbroadcastf128 (7 * 16)(%[data]), %%ymm7\n" + : + : [data] "r" (&data[0]) + : "memory", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", + "ymm6", "ymm7" + ); +# endif + else + asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n" + "movdqu (1 * 16)(%[data]), %%xmm1\n" + "movdqu (2 * 16)(%[data]), %%xmm2\n" + "movdqu (3 * 16)(%[data]), %%xmm3\n" + "movdqu (4 * 16)(%[data]), %%xmm4\n" + "movdqu (5 * 16)(%[data]), %%xmm5\n" + "movdqu (6 * 16)(%[data]), %%xmm6\n" + "movdqu (7 * 16)(%[data]), %%xmm7\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7" + ); #elif defined(CLUTTER_VECTOR_REGISTER_AARCH64) asm volatile("mov x0, %[ptr]\n" "ld1 {v0.16b}, [x0], #16\n" -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:39 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:39 +0300 Subject: [PATCH 3/6] tests/basic: add vector cluttering for riscv In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-3-jussi.kivilinna@iki.fi> * tests/basic.c (CLUTTER_VECTOR_REGISTER_RISCV): New. (clutter_vector_registers): Guard clutter data with CLUTTER_VECTOR_REGISTER_COUNT. [CLUTTER_VECTOR_REGISTER_RISCV]: Detect RVV from hwflist; fill v0-v31 with vid.v generated values. -- Vector register width is not known at compile time on RISC-V, so registers are filled with generated values instead of loading from data buffer. Signed-off-by: Jussi Kivilinna --- tests/basic.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/tests/basic.c b/tests/basic.c index 00d6586d..d9664d3c 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -261,6 +261,10 @@ progress_handler (void *cb_data, const char *what, int printchar, defined(__ARM_NEON) # define CLUTTER_VECTOR_REGISTER_NEON 1 # define CLUTTER_VECTOR_REGISTER_COUNT 16 +#elif defined(HAVE_GCC_INLINE_ASM_RISCV_V) && \ + defined(__riscv) +# define CLUTTER_VECTOR_REGISTER_RISCV 1 +# undef CLUTTER_VECTOR_REGISTER_COUNT #endif @@ -297,6 +301,7 @@ clutter_vector_registers(void) #ifdef CLUTTER_VECTOR_REGISTER_COUNT static unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; static int data_init; +#endif #if defined(CLUTTER_VECTOR_REGISTER_AARCH64) || \ defined(CLUTTER_VECTOR_REGISTER_NEON) static int init; @@ -347,13 +352,34 @@ clutter_vector_registers(void) if (!have_sse2) return; +#elif defined(CLUTTER_VECTOR_REGISTER_RISCV) + static int init; + static int have_rvv; + + if (!init) + { + char *string; + + string = gcry_get_config (0, "hwflist"); + if (string) + { + have_rvv = (strstr(string, "riscv-v:") != NULL); + xfree(string); + } + init = 1; + } + + if (!have_rvv) + return; #endif +#ifdef CLUTTER_VECTOR_REGISTER_COUNT if (!data_init) { prepare_vector_data(data); data_init = 1; } +#endif #if defined(CLUTTER_VECTOR_REGISTER_AMD64) if (0) @@ -565,9 +591,44 @@ clutter_vector_registers(void) : "r0", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"); +#elif defined(CLUTTER_VECTOR_REGISTER_RISCV) + asm volatile(".option push;\n" + ".option arch, +v;\n" + "vsetvli t0, %0, e8, m4, ta, ma;\n" + "vid.v v0;\n" + "vid.v v4;\n" + "vid.v v8;\n" + "vid.v v12;\n" + "vid.v v16;\n" + "vid.v v20;\n" + "vid.v v24;\n" + "vid.v v28;\n" + "vadd.vx v4, v4, t0;\n" + "add t1, t0, t0;\n" + "vadd.vx v8, v8, t1;\n" + "add t1, t1, t0;\n" + "vadd.vx v12, v12, t1;\n" + "add t1, t1, t0;\n" + "vadd.vx v16, v16, t1;\n" + "add t1, t1, t0;\n" + "vadd.vx v20, v20, t1;\n" + "add t1, t1, t0;\n" + "add t0, t1, t0;\n" + "vadd.vx v24, v24, t1;\n" + "vadd.vx v28, v28, t0;\n" + ".option pop;\n" + : + : "r" (~0) + : "memory", "vl", "vtype", "t0", "t1", + "v0", "v1", "v2", "v3", + "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", + "v12", "v13", "v14", "v15", + "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", + "v24", "v25", "v26", "v27", + "v28", "v29", "v30", "v31"); #endif - -#endif /* CLUTTER_VECTOR_REGISTER_COUNT */ } -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:40 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:40 +0300 Subject: [PATCH 4/6] tests/basic: add vector cluttering for ppc64 In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-4-jussi.kivilinna@iki.fi> * tests/basic.c (CLUTTER_VECTOR_REGISTER_PPC): New. (clutter_vector_registers) [CLUTTER_VECTOR_REGISTER_PPC]: Detect ppc-arch_2_07 from hwflist; load all 64 VSX registers. -- Signed-off-by: Jussi Kivilinna --- tests/basic.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/basic.c b/tests/basic.c index d9664d3c..4c5f6038 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -265,6 +265,11 @@ progress_handler (void *cb_data, const char *what, int printchar, defined(__riscv) # define CLUTTER_VECTOR_REGISTER_RISCV 1 # undef CLUTTER_VECTOR_REGISTER_COUNT +#elif defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \ + defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) && \ + defined(__POWER8_VECTOR__) +# define CLUTTER_VECTOR_REGISTER_PPC 1 +# define CLUTTER_VECTOR_REGISTER_COUNT 64 #endif @@ -371,6 +376,25 @@ clutter_vector_registers(void) if (!have_rvv) return; +#elif defined(CLUTTER_VECTOR_REGISTER_PPC) + static int init; + static int have_ppc_vec; + + if (!init) + { + char *string; + + string = gcry_get_config (0, "hwflist"); + if (string) + { + have_ppc_vec = (strstr(string, "ppc-arch_2_07:") != NULL); + xfree(string); + } + init = 1; + } + + if (!have_ppc_vec) + return; #endif #ifdef CLUTTER_VECTOR_REGISTER_COUNT @@ -628,6 +652,46 @@ clutter_vector_registers(void) "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); +#elif defined(CLUTTER_VECTOR_REGISTER_PPC) + #define FILL_VECS_10(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) \ + asm volatile("lxvd2x "#v0", %y0\n" \ + "lxvd2x "#v1", %y1\n" \ + "lxvd2x "#v2", %y2\n" \ + "lxvd2x "#v3", %y3\n" \ + "lxvd2x "#v4", %y4\n" \ + "lxvd2x "#v5", %y5\n" \ + "lxvd2x "#v6", %y6\n" \ + "lxvd2x "#v7", %y7\n" \ + "lxvd2x "#v8", %y8\n" \ + "lxvd2x "#v9", %y9\n" \ + : \ + : "Z" (data[v0][0]), "Z" (data[v1][0]), \ + "Z" (data[v2][0]), "Z" (data[v3][0]), \ + "Z" (data[v4][0]), "Z" (data[v5][0]), \ + "Z" (data[v6][0]), "Z" (data[v7][0]), \ + "Z" (data[v8][0]), "Z" (data[v9][0]) \ + : "vs" #v0, "vs" #v1, "vs" #v2, "vs" #v3, \ + "vs" #v4, "vs" #v5, "vs" #v6, "vs" #v7, \ + "vs" #v8, "vs" #v9, "memory"); + #define FILL_VECS_4(v0, v1, v2, v3) \ + asm volatile("lxvd2x "#v0", %y0\n" \ + "lxvd2x "#v1", %y1\n" \ + "lxvd2x "#v2", %y2\n" \ + "lxvd2x "#v3", %y3\n" \ + : \ + : "Z" (data[v0][0]), "Z" (data[v1][0]), \ + "Z" (data[v2][0]), "Z" (data[v3][0]) \ + : "vs" #v0, "vs" #v1, "vs" #v2, "vs" #v3, \ + "memory"); + FILL_VECS_10(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + FILL_VECS_10(10, 11, 12, 13, 14, 15, 16, 17, 18, 19); + FILL_VECS_10(20, 21, 22, 23, 24, 25, 26, 27, 28, 29); + FILL_VECS_10(30, 31, 32, 33, 34, 35, 36, 37, 38, 39); + FILL_VECS_10(40, 41, 42, 43, 44, 45, 46, 47, 48, 49); + FILL_VECS_10(50, 51, 52, 53, 54, 55, 56, 57, 58, 59); + FILL_VECS_4(60, 61, 62, 63); + #undef FILL_VECS_10 + #undef FILL_VECS_4 #endif } -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:42 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:42 +0300 Subject: [PATCH 6/6] tests/basic: add MAC verify API test for bad tag length In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-6-jussi.kivilinna@iki.fi> * cipher/cipher-cmac.c (cmac_tag): Return GPG_ERR_INV_LENGTH for invalid tag length. * cipher/cipher-gcm.c (_gcry_cipher_gcm_tag): Likewise. * tests/basic.c (check_one_mac): Check that gcry_mac_verify rejects oversized tag length. -- CMAC returned GPG_ERR_INV_ARG and GCM returned GPG_ERR_CHECKSUM for wrong tag length, while HMAC and Poly1305 return GPG_ERR_INV_LENGTH. Signed-off-by: Jussi Kivilinna --- cipher/cipher-cmac.c | 4 +++- cipher/cipher-gcm.c | 5 +++-- tests/basic.c | 9 +++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/cipher/cipher-cmac.c b/cipher/cipher-cmac.c index c8bedc08..aab4b042 100644 --- a/cipher/cipher-cmac.c +++ b/cipher/cipher-cmac.c @@ -216,8 +216,10 @@ cmac_tag (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx, { gcry_err_code_t ret; - if (!tag || taglen == 0 || taglen > c->spec->blocksize) + if (!tag) return GPG_ERR_INV_ARG; + if (taglen == 0 || taglen > c->spec->blocksize) + return GPG_ERR_INV_LENGTH; if (!ctx->tag) { diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c index e6a4df0f..ed04951b 100644 --- a/cipher/cipher-gcm.c +++ b/cipher/cipher-gcm.c @@ -1283,8 +1283,9 @@ _gcry_cipher_gcm_tag (gcry_cipher_hd_t c, { /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF * and thus we need to compare its length first. */ - if (!is_tag_length_valid (outbuflen) - || !buf_eq_const (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen)) + if (!is_tag_length_valid (outbuflen)) + return GPG_ERR_INV_LENGTH; + if (!buf_eq_const (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen)) return GPG_ERR_CHECKSUM; } diff --git a/tests/basic.c b/tests/basic.c index 405f9861..7b8c73f3 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -16405,6 +16405,7 @@ check_one_mac (int algo, const char *data, int datalen, const char *key, int keylen, const char *iv, int ivlen, const char *expect, int test_buffering) { + unsigned char big_bad_tag[64 * 2]; gcry_mac_hd_t hd; unsigned char *p; unsigned int maclen; @@ -16558,6 +16559,14 @@ check_one_mac (int algo, const char *data, int datalen, if (err) fail("algo %d, mac gcry_mac_verify failed: %s\n", algo, gpg_strerror (err)); + clutter_vector_registers(); + err = gcry_mac_verify (hd, big_bad_tag, sizeof(big_bad_tag)); + if (gcry_err_code (err) != GPG_ERR_INV_LENGTH) + fail ("algo %d, gcry_mac_verify: oversized len %d not rejected: %s\n", algo, + (int)sizeof(big_bad_tag), gpg_strerror (err)); + if (err) + goto out; + macoutlen = maclen; clutter_vector_registers(); err = gcry_mac_read (hd, p, &macoutlen); -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:37 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:37 +0300 Subject: [PATCH 1/6] cipher: remove unneeded vzeroupper from AVX implementations Message-ID: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> * cipher/blake2b-amd64-avx2.S (_gcry_blake2b_transform_amd64_avx2): Remove vzeroupper from function entry. * cipher/blake2s-amd64-avx.S (_gcry_blake2s_transform_amd64_avx): Likewise. * cipher/camellia-aesni-avx-amd64.S (_gcry_camellia_aesni_avx_ctr_enc) (_gcry_camellia_aesni_avx_ecb_enc, _gcry_camellia_aesni_avx_ecb_dec) (_gcry_camellia_aesni_avx_cbc_dec, _gcry_camellia_aesni_avx_cfb_dec) (_gcry_camellia_aesni_avx_ocb_enc, _gcry_camellia_aesni_avx_ocb_dec) (_gcry_camellia_aesni_avx_ocb_auth, _gcry_camellia_aesni_avx_keygen): Likewise. * cipher/chacha20-amd64-avx2.S (_gcry_chacha20_amd64_avx2_blocks8) (_gcry_chacha20_poly1305_amd64_avx2_blocks8): Likewise. * cipher/serpent-avx2-amd64.S (_gcry_serpent_avx2_ctr_enc) (_gcry_serpent_avx2_cbc_dec, _gcry_serpent_avx2_cfb_dec) (_gcry_serpent_avx2_ocb_enc, _gcry_serpent_avx2_ocb_dec) (_gcry_serpent_avx2_ocb_auth): Likewise. * cipher/sha1-avx-amd64.S (_gcry_sha1_transform_amd64_avx): Likewise. * cipher/sha1-avx-bmi2-amd64.S (_gcry_sha1_transform_amd64_avx_bmi2): Likewise. * cipher/sha1-avx2-bmi2-amd64.S (_gcry_sha1_transform_amd64_avx2_bmi2): Likewise. * cipher/sha256-avx-amd64.S (_gcry_sha256_transform_amd64_avx): Likewise. * cipher/sha256-avx2-bmi2-amd64.S (_gcry_sha256_transform_amd64_avx2): Likewise. * cipher/sha512-avx-amd64.S (_gcry_sha512_transform_amd64_avx): Likewise. * cipher/sha512-avx2-bmi2-amd64.S (_gcry_sha512_transform_amd64_avx2): Likewise. * cipher/sm3-avx-bmi2-amd64.S (_gcry_sm3_transform_amd64_avx_bmi2): Likewise. * cipher/twofish-avx2-amd64.S (_gcry_twofish_avx2_blk16) (_gcry_twofish_avx2_ctr_enc, _gcry_twofish_avx2_cbc_dec) (_gcry_twofish_avx2_cfb_dec, _gcry_twofish_avx2_ocb_enc) (_gcry_twofish_avx2_ocb_dec, _gcry_twofish_avx2_ocb_auth): Likewise. * cipher/chacha20-amd64-avx512.S (_gcry_chacha20_amd64_avx512_blocks): Remove vzeroupper from register clearing. -- vzeroupper is needed only ahead of legacy SSE code, to avoid AVX-SSE transition penalty. These implementations use VEX/EVEX encoding throughout and clear upper register state with vzeroall before return. Measured on Tiger Lake, leaving upper register state dirty costs 1.54x for legacy SSE loop, but nothing for VEX encoded xmm/ymm code. Zen5 shows no penalty for either. Signed-off-by: Jussi Kivilinna --- cipher/blake2b-amd64-avx2.S | 2 -- cipher/blake2s-amd64-avx.S | 2 -- cipher/camellia-aesni-avx-amd64.S | 18 ------------------ cipher/chacha20-amd64-avx2.S | 4 ---- cipher/chacha20-amd64-avx512.S | 1 - cipher/serpent-avx2-amd64.S | 12 ------------ cipher/sha1-avx-amd64.S | 2 -- cipher/sha1-avx-bmi2-amd64.S | 2 -- cipher/sha1-avx2-bmi2-amd64.S | 2 -- cipher/sha256-avx-amd64.S | 1 - cipher/sha256-avx2-bmi2-amd64.S | 2 -- cipher/sha512-avx-amd64.S | 2 -- cipher/sha512-avx2-bmi2-amd64.S | 2 -- cipher/sm3-avx-bmi2-amd64.S | 2 -- cipher/twofish-avx2-amd64.S | 14 -------------- 15 files changed, 68 deletions(-) diff --git a/cipher/blake2b-amd64-avx2.S b/cipher/blake2b-amd64-avx2.S index 43c2cce1..02ee80a4 100644 --- a/cipher/blake2b-amd64-avx2.S +++ b/cipher/blake2b-amd64-avx2.S @@ -210,8 +210,6 @@ _gcry_blake2b_transform_amd64_avx2: */ CFI_STARTPROC(); - vzeroupper; - addq $128, (STATE_T + 0)(RSTATE); adcq $0, (STATE_T + 8)(RSTATE); diff --git a/cipher/blake2s-amd64-avx.S b/cipher/blake2s-amd64-avx.S index 44b82ab2..d2df67d6 100644 --- a/cipher/blake2s-amd64-avx.S +++ b/cipher/blake2s-amd64-avx.S @@ -196,8 +196,6 @@ _gcry_blake2s_transform_amd64_avx: */ CFI_STARTPROC(); - vzeroupper; - addq $64, (STATE_T + 0)(RSTATE); vmovdqa .Lshuf_ror16 rRIP, R16; diff --git a/cipher/camellia-aesni-avx-amd64.S b/cipher/camellia-aesni-avx-amd64.S index a29b9023..14e11d18 100644 --- a/cipher/camellia-aesni-avx-amd64.S +++ b/cipher/camellia-aesni-avx-amd64.S @@ -896,8 +896,6 @@ _gcry_camellia_aesni_avx_ctr_enc: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - cmpl $128, key_bitlength(CTX); movl $32, %r8d; movl $24, %eax; @@ -1053,8 +1051,6 @@ _gcry_camellia_aesni_avx_ecb_enc: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - cmpl $128, key_bitlength(CTX); movl $32, %r8d; movl $24, %eax; @@ -1099,8 +1095,6 @@ _gcry_camellia_aesni_avx_ecb_dec: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - cmpl $128, key_bitlength(CTX); movl $32, %r8d; movl $24, %eax; @@ -1146,8 +1140,6 @@ _gcry_camellia_aesni_avx_cbc_dec: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - movq %rcx, %r9; cmpl $128, key_bitlength(CTX); @@ -1219,8 +1211,6 @@ _gcry_camellia_aesni_avx_cfb_dec: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - cmpl $128, key_bitlength(CTX); movl $32, %r8d; movl $24, %eax; @@ -1303,8 +1293,6 @@ _gcry_camellia_aesni_avx_ocb_enc: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - subq $(16 * 16 + 4 * 8), %rsp; andq $~31, %rsp; movq %rsp, %rax; @@ -1455,8 +1443,6 @@ _gcry_camellia_aesni_avx_ocb_dec: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - subq $(16 * 16 + 4 * 8), %rsp; andq $~31, %rsp; movq %rsp, %rax; @@ -1625,8 +1611,6 @@ _gcry_camellia_aesni_avx_ocb_auth: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - subq $(16 * 16 + 4 * 8), %rsp; andq $~31, %rsp; movq %rsp, %rax; @@ -2720,8 +2704,6 @@ _gcry_camellia_aesni_avx_keygen: */ CFI_STARTPROC(); - vzeroupper; - vmovdqu (%rsi), %xmm0; cmpl $24, %edx; jb __camellia_avx_setup128; diff --git a/cipher/chacha20-amd64-avx2.S b/cipher/chacha20-amd64-avx2.S index 54e2ffab..b2311ab5 100644 --- a/cipher/chacha20-amd64-avx2.S +++ b/cipher/chacha20-amd64-avx2.S @@ -184,8 +184,6 @@ _gcry_chacha20_amd64_avx2_blocks8: */ CFI_STARTPROC(); - vzeroupper; - pushq %rbp; CFI_PUSH(%rbp); movq %rsp, %rbp; @@ -356,8 +354,6 @@ _gcry_chacha20_poly1305_amd64_avx2_blocks8: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - subq $(9 * 8) + STACK_MAX + 32, %rsp; andq $~31, %rsp; diff --git a/cipher/chacha20-amd64-avx512.S b/cipher/chacha20-amd64-avx512.S index 2d140815..6d421bf2 100644 --- a/cipher/chacha20-amd64-avx512.S +++ b/cipher/chacha20-amd64-avx512.S @@ -625,7 +625,6 @@ _gcry_chacha20_amd64_avx512_blocks: .Lskip4v: /* clear AVX512 registers */ kxorq %k2, %k2, %k2; - vzeroupper; clear_zmm16_zmm31(); .align 16 diff --git a/cipher/serpent-avx2-amd64.S b/cipher/serpent-avx2-amd64.S index a419eb29..9ec31f17 100644 --- a/cipher/serpent-avx2-amd64.S +++ b/cipher/serpent-avx2-amd64.S @@ -645,8 +645,6 @@ _gcry_serpent_avx2_ctr_enc: */ CFI_STARTPROC(); - vzeroupper; - vbroadcasti128 .Lbswap128_mask rRIP, RTMP3; vpcmpeqd RNOT, RNOT, RNOT; vpsrldq $14, RNOT, RNOT; /* ab: -1:0 ; cd: -1:0 */ @@ -718,8 +716,6 @@ _gcry_serpent_avx2_cbc_dec: */ CFI_STARTPROC(); - vzeroupper; - vmovdqu (0 * 32)(%rdx), RA0; vmovdqu (1 * 32)(%rdx), RA1; vmovdqu (2 * 32)(%rdx), RA2; @@ -771,8 +767,6 @@ _gcry_serpent_avx2_cfb_dec: */ CFI_STARTPROC(); - vzeroupper; - /* Load input */ vmovdqu (%rcx), RNOTx; vinserti128 $1, (%rdx), RNOT, RA0; @@ -829,8 +823,6 @@ _gcry_serpent_avx2_ocb_enc: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); @@ -943,8 +935,6 @@ _gcry_serpent_avx2_ocb_dec: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); @@ -1066,8 +1056,6 @@ _gcry_serpent_avx2_ocb_auth: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); diff --git a/cipher/sha1-avx-amd64.S b/cipher/sha1-avx-amd64.S index e5e55684..ca81506c 100644 --- a/cipher/sha1-avx-amd64.S +++ b/cipher/sha1-avx-amd64.S @@ -222,8 +222,6 @@ _gcry_sha1_transform_amd64_avx: cmpq $0, %rdx; jz .Lret; - vzeroupper; - movq %rdx, RNBLKS; movq %rdi, RSTATE; movq %rsi, RDATA; diff --git a/cipher/sha1-avx-bmi2-amd64.S b/cipher/sha1-avx-bmi2-amd64.S index 16a01bfd..85ba22b0 100644 --- a/cipher/sha1-avx-bmi2-amd64.S +++ b/cipher/sha1-avx-bmi2-amd64.S @@ -222,8 +222,6 @@ _gcry_sha1_transform_amd64_avx_bmi2: cmpq $0, %rdx; jz .Lret; - vzeroupper; - movq %rdx, RNBLKS; movq %rdi, RSTATE; movq %rsi, RDATA; diff --git a/cipher/sha1-avx2-bmi2-amd64.S b/cipher/sha1-avx2-bmi2-amd64.S index 06ff92f0..190b9731 100644 --- a/cipher/sha1-avx2-bmi2-amd64.S +++ b/cipher/sha1-avx2-bmi2-amd64.S @@ -224,8 +224,6 @@ _gcry_sha1_transform_amd64_avx2_bmi2: */ CFI_STARTPROC(); - vzeroupper; - movq %rdx, RNBLKS; movq %rdi, RSTATE; movq %rsi, RDATA; diff --git a/cipher/sha256-avx-amd64.S b/cipher/sha256-avx-amd64.S index 8cfd0880..9c15f481 100644 --- a/cipher/sha256-avx-amd64.S +++ b/cipher/sha256-avx-amd64.S @@ -345,7 +345,6 @@ ELF(.type _gcry_sha256_transform_amd64_avx, at function;) .align 16 _gcry_sha256_transform_amd64_avx: CFI_STARTPROC() - vzeroupper push rbx CFI_PUSH(rbx) diff --git a/cipher/sha256-avx2-bmi2-amd64.S b/cipher/sha256-avx2-bmi2-amd64.S index e2a5454c..ec99e57f 100644 --- a/cipher/sha256-avx2-bmi2-amd64.S +++ b/cipher/sha256-avx2-bmi2-amd64.S @@ -268,8 +268,6 @@ _gcry_sha256_transform_amd64_avx2: push r15 CFI_PUSH(r15) - vzeroupper - vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP] vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP] vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP] diff --git a/cipher/sha512-avx-amd64.S b/cipher/sha512-avx-amd64.S index 1bd38060..22b1058e 100644 --- a/cipher/sha512-avx-amd64.S +++ b/cipher/sha512-avx-amd64.S @@ -254,8 +254,6 @@ _gcry_sha512_transform_amd64_avx: cmp msglen, 0 je .Lnowork - vzeroupper - /* Allocate Stack Space */ sub rsp, frame_size CFI_ADJUST_CFA_OFFSET(frame_size); diff --git a/cipher/sha512-avx2-bmi2-amd64.S b/cipher/sha512-avx2-bmi2-amd64.S index 7b60bf1d..c2275bb5 100644 --- a/cipher/sha512-avx2-bmi2-amd64.S +++ b/cipher/sha512-avx2-bmi2-amd64.S @@ -282,8 +282,6 @@ _gcry_sha512_transform_amd64_avx2: cmp rdx, 0 je .Lnowork - vzeroupper - /* Allocate Stack Space */ mov rax, rsp CFI_DEF_CFA_REGISTER(rax); diff --git a/cipher/sm3-avx-bmi2-amd64.S b/cipher/sm3-avx-bmi2-amd64.S index ef923165..9252e279 100644 --- a/cipher/sm3-avx-bmi2-amd64.S +++ b/cipher/sm3-avx-bmi2-amd64.S @@ -354,8 +354,6 @@ _gcry_sm3_transform_amd64_avx_bmi2: */ CFI_STARTPROC(); - vzeroupper; - pushq %rbp; CFI_PUSH(%rbp); movq %rsp, %rbp; diff --git a/cipher/twofish-avx2-amd64.S b/cipher/twofish-avx2-amd64.S index 72a39d17..c448dfae 100644 --- a/cipher/twofish-avx2-amd64.S +++ b/cipher/twofish-avx2-amd64.S @@ -519,8 +519,6 @@ _gcry_twofish_avx2_blk16: */ CFI_STARTPROC(); - vzeroupper; - vmovdqu (0 * 32)(%rdx), RA0; vmovdqu (1 * 32)(%rdx), RB0; vmovdqu (2 * 32)(%rdx), RC0; @@ -565,8 +563,6 @@ _gcry_twofish_avx2_ctr_enc: */ CFI_STARTPROC(); - vzeroupper; - vbroadcasti128 .Lbswap128_mask rRIP, RTMP3; vpcmpeqd RNOT, RNOT, RNOT; vpsrldq $14, RNOT, RNOT; /* ab: -1:0 ; cd: -1:0 */ @@ -638,8 +634,6 @@ _gcry_twofish_avx2_cbc_dec: */ CFI_STARTPROC(); - vzeroupper; - vmovdqu (0 * 32)(%rdx), RA0; vmovdqu (1 * 32)(%rdx), RB0; vmovdqu (2 * 32)(%rdx), RC0; @@ -691,8 +685,6 @@ _gcry_twofish_avx2_cfb_dec: */ CFI_STARTPROC(); - vzeroupper; - /* Load input */ vmovdqu (%rcx), RNOTx; vinserti128 $1, (%rdx), RNOT, RA0; @@ -749,8 +741,6 @@ _gcry_twofish_avx2_ocb_enc: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); @@ -863,8 +853,6 @@ _gcry_twofish_avx2_ocb_dec: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); @@ -987,8 +975,6 @@ _gcry_twofish_avx2_ocb_auth: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); -- 2.53.0 From jonathan.plata at lightshipsec.com Wed Sep 9 16:12:25 2026 From: jonathan.plata at lightshipsec.com (Jonathan Plata) Date: Wed, 9 Sep 2026 14:12:25 +0000 Subject: PATCH: Padding bug in cSHAKE-128/256 Message-ID: Hello! cshake_input_s()'s padlen computation, padlen = ctx->blocksize - (len_written % ctx->blocksize); does not handle the case where len_written is already an exact multiple of ctx->blocksize: the modulo evaluates to 0, so padlen comes out as ctx->blocksize (a full block) instead of 0. SP 800-185's bytepad (sec. 2.3.3) specifies padding with zero bytes only until the total length becomes a multiple of the rate -- when it already is, no padding bytes should be added at all. The bug results in a full extra block of zero bytes added to the Keccak sponge, producing a wrong cSHAKE digest whenever the encoded N (function-name string) + S (customization string) length lands exactly on a rate boundary (168 bytes for cSHAKE128, 136 for cSHAKE256). Concretely: cSHAKE128 with an empty N and a 161-byte S (2-byte rate prefix + 2-byte encode_string(empty N) + 3-byte encode_string(S) length-prefix + 161 == 168 == the cSHAKE128 rate) triggers it; cSHAKE256 with an empty N and a 129-byte S hits the same condition against its 136-byte rate. Found via NIST ACVP cSHAKE-128/256 conformance vectors: a fixture covering random S lengths reliably produces a wrong digest at S = 161 (cSHAKE128) and S = 129 (cSHAKE256), and only those lengths (adjacent lengths pass), consistent with this exact rate-boundary condition. Confirmed against libgcrypt 1.11.2 and 1.12.0 (unchanged between the two). Signed-off-by: Jonathan Plata --- cipher/keccak.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/keccak.c b/cipher/keccak.c index a0ba1fbb..1351da16 100644 --- a/cipher/keccak.c +++ b/cipher/keccak.c @@ -1694,7 +1694,7 @@ cshake_input_s (KECCAK_CONTEXT *ctx, const void *s, unsigned int s_len, keccak_write (ctx, s, s_len); len_written += buf[0] + 1 + s_len; - padlen = ctx->blocksize - (len_written % ctx->blocksize); + padlen = (ctx->blocksize - (len_written % ctx->blocksize)) % ctx->blocksize; memset (buf, 0, padlen); keccak_write (ctx, buf, padlen); } -- 2.34.1 [cid:image001.png at 01DD4040.AC77CD40] Jonathan Plata | Software Developer Lightship Security, Inc. Tel: 512-362-6594 https://lightshipsec.com This email and attachments are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you are not the named addressee, you may not disseminate, distribute or copy this email. Please notify the sender immediately if you have received this email in error and delete it from your system. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.png Type: image/png Size: 4162 bytes Desc: image001.png URL: From gniibe at fsij.org Thu Sep 10 07:26:04 2026 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 10 Sep 2026 14:26:04 +0900 Subject: PATCH: Padding bug in cSHAKE-128/256 In-Reply-To: References: Message-ID: <87ecf1brtf.fsf@haruna.fsij.org> Hello, Jonathan Plata wrote: > cshake_input_s()'s padlen computation, > > padlen = ctx->blocksize - (len_written % ctx->blocksize); Thank you for your report. > --- a/cipher/keccak.c > +++ b/cipher/keccak.c > @@ -1694,7 +1694,7 @@ cshake_input_s (KECCAK_CONTEXT *ctx, const void *s, unsigned int s_len, > keccak_write (ctx, s, s_len); > > len_written += buf[0] + 1 + s_len; > - padlen = ctx->blocksize - (len_written % ctx->blocksize); > + padlen = (ctx->blocksize - (len_written % ctx->blocksize)) % ctx->blocksize; > memset (buf, 0, padlen); > keccak_write (ctx, buf, padlen); > } While the expression is correct, I'm not sure if multiple %-operations can be optimized well by compiler. Just in case, I think that it's better to use a single %-operation in the expression. Attached is a patch with a single %-operation. If no objections, I will push this to 1.11, 1.12 and master. -- -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-cipher-keccak-Fix-padding-in-cSHAKE.patch Type: text/x-diff Size: 1529 bytes Desc: not available URL: From mattst88 at gmail.com Wed Sep 2 15:17:20 2026 From: mattst88 at gmail.com (Matt Turner) Date: Wed, 2 Sep 2026 09:17:20 -0400 Subject: [PATCH] mpi: Drop casts from inline asm output operands. Message-ID: <20260902131720.409681-1-mattst88@gmail.com> * mpi/longlong.h [__a29k__, __alpha, __gmicro__, __hppa, __i960__, __mc68000__, __m88000__, __mips__, __mips, __ns32000__, __pyr__, __ibm032__, __sh2__, __sparc__, __vax__, __z8000__]: Drop the casts on asm output operands. -- Using a cast as an lvalue is a GCC extension that clang does not implement. Clang rejects it with -Winvalid-gnu-asm-cast, which is an error by default, so these blocks fail to build with clang. The casts do nothing. GCC accepts a cast in an asm output only when it is a no-op, and rejects it with "lvalue required in 'asm' statement" otherwise, so any code that compiles today already passes an operand of the right type. GMP's longlong.h dropped these long ago. The Z8000 block is the exception. There W_TYPE_SIZE is 16, so the cast to unsigned int is not a no-op and GCC would reject it too; that block has been dead for a long time and is fixed here for consistency. Casts on *input* operands are left alone: those are ordinary rvalue conversions, and on x86 count_leading_zeros/count_trailing_zeros the "rm" ((USItype)(x)) cast is what selects the operand width. Checked with the cross toolchains available here. GCC generates identical assembly before and after for alpha, hppa, mc68000, sh4, 32-bit sparc and mips. Clang builds the sparc block only after this change; it has no back end for alpha, hppa or mc68000, so those could not be checked with clang. The blocks with no compiler to test against (a29k, gmicro, i960, m88k, ns32000, pyr, RT/ROMP, vax, z8000) are changed mechanically. The MIPS asm blocks are unreachable in practice: any compiler new enough to matter takes the preceding __GNUC__ >= 5 branch, which uses a plain wide multiply, and the asm variants no longer assemble anyway now that GCC has removed the "h" constraint ("impossible constraint in 'asm'"). Signed-off-by: Matt Turner --- mpi/longlong.h | 174 ++++++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git ./mpi/longlong.h ./mpi/longlong.h index 453f2704..b27d0b88 100644 --- ./mpi/longlong.h +++ ./mpi/longlong.h @@ -133,8 +133,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %1,%4,%5\n" \ "addc %0,%2,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ @@ -142,8 +142,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %1,%4,%5\n" \ "subc %0,%2,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "r" ((USItype)(al)), \ @@ -152,24 +152,24 @@ SPDX-License-Identifier: LGPL-2.1-or-later do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("multiplu %0,%1,%2" \ - : "=r" ((USItype)(xl)) \ + : "=r" (xl) \ : "r" (__m0), \ "r" (__m1)); \ __asm__ ("multmu %0,%1,%2" \ - : "=r" ((USItype)(xh)) \ + : "=r" (xh) \ : "r" (__m0), \ "r" (__m1)); \ } while (0) # define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("dividu %0,%3,%4" \ - : "=r" ((USItype)(q)), \ - "=q" ((USItype)(r)) \ + : "=r" (q), \ + "=q" (r) \ : "1" ((USItype)(n1)), \ "r" ((USItype)(n0)), \ "r" ((USItype)(d))) # define count_leading_zeros(count, x) \ __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ + : "=r" (count) \ : "r" ((USItype)(x))) # define COUNT_LEADING_ZEROS_0 32 #endif /* __a29k__ */ @@ -180,7 +180,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later do { \ UDItype __m0 = (m0), __m1 = (m1); \ __asm__ ("umulh %r1,%2,%0" \ - : "=r" ((UDItype)(ph)) \ + : "=r" (ph) \ : "%rJ" (__m0), \ "rI" (__m1)); \ (pl) = __m0 * __m1; \ @@ -365,8 +365,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add.w %5,%1\n" \ "addx %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ + : "=g" (sh), \ + "=&g" (sl) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -374,22 +374,22 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub.w %5,%1\n" \ "subx %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ + : "=g" (sh), \ + "=&g" (sl) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ "g" ((USItype)(bl))) # define umul_ppmm(ph, pl, m0, m1) \ __asm__ ("mulx %3,%0,%1" \ - : "=g" ((USItype)(ph)), \ - "=r" ((USItype)(pl)) \ + : "=g" (ph), \ + "=r" (pl) \ : "%0" ((USItype)(m0)), \ "g" ((USItype)(m1))) # define udiv_qrnnd(q, r, nh, nl, d) \ __asm__ ("divx %4,%0,%1" \ - : "=g" ((USItype)(q)), \ - "=r" ((USItype)(r)) \ + : "=g" (q), \ + "=r" (r) \ : "1" ((USItype)(nh)), \ "0" ((USItype)(nl)), \ "g" ((USItype)(d))) @@ -408,8 +408,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %4,%5,%1\n\t" \ "addc %2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%rM" ((USItype)(ah)), \ "rM" ((USItype)(bh)), \ "%rM" ((USItype)(al)), \ @@ -417,8 +417,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %4,%5,%1\n\t" \ "subb %2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "rM" ((USItype)(ah)), \ "rM" ((USItype)(bh)), \ "rM" ((USItype)(al)), \ @@ -658,8 +658,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); __asm__ ("cmpo 1,0\n" \ "addc %5,%4,%1\n" \ "addc %3,%2,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%dI" ((USItype)(ah)), \ "dI" ((USItype)(bh)), \ "%dI" ((USItype)(al)), \ @@ -668,8 +668,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); __asm__ ("cmpo 0,0\n" \ "subc %5,%4,%1\n" \ "subc %3,%2,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "dI" ((USItype)(ah)), \ "dI" ((USItype)(bh)), \ "dI" ((USItype)(al)), \ @@ -733,8 +733,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add%.l %5,%1\n" \ "addx%.l %3,%0" \ - : "=d" ((USItype)(sh)), \ - "=&d" ((USItype)(sl)) \ + : "=d" (sh), \ + "=&d" (sl) \ : "%0" ((USItype)(ah)), \ "d" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -742,8 +742,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub%.l %5,%1\n" \ "subx%.l %3,%0" \ - : "=d" ((USItype)(sh)), \ - "=&d" ((USItype)(sl)) \ + : "=d" (sh), \ + "=&d" (sl) \ : "0" ((USItype)(ah)), \ "d" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -751,29 +751,29 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) # define umul_ppmm(w1, w0, u, v) \ __asm__ ("mulu%.l %3,%1:%0" \ - : "=d" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ + : "=d" (w0), \ + "=d" (w1) \ : "%0" ((USItype)(u)), \ "dmi" ((USItype)(v))) # define UMUL_TIME 45 # define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divu%.l %4,%1:%0" \ - : "=d" ((USItype)(q)), \ - "=d" ((USItype)(r)) \ + : "=d" (q), \ + "=d" (r) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "dmi" ((USItype)(d))) # define UDIV_TIME 90 # define sdiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divs%.l %4,%1:%0" \ - : "=d" ((USItype)(q)), \ - "=d" ((USItype)(r)) \ + : "=d" (q), \ + "=d" (r) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "dmi" ((USItype)(d))) # define count_leading_zeros(count, x) \ __asm__ ("bfffo %1{%b2:%b2},%0" \ - : "=d" ((USItype)(count)) \ + : "=d" (count) \ : "od" ((USItype)(x)), "n" (0)) # define COUNT_LEADING_ZEROS_0 32 # else /* not mc68020 */ @@ -801,7 +801,7 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); " add%.l %3,%1 \n" \ " addx%.l %2,%0 \n" \ " | End inlined umul_ppmm" \ - : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \ + : "=&d" (xh), "=&d" (xl), \ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \ } while (0) @@ -818,8 +818,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addu.co %1,%r4,%r5\n" \ "addu.ci %0,%r2,%r3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%rJ" ((USItype)(ah)), \ "rJ" ((USItype)(bh)), \ "%rJ" ((USItype)(al)), \ @@ -827,8 +827,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subu.co %1,%r4,%r5\n" \ "subu.ci %0,%r2,%r3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "rJ" ((USItype)(ah)), \ "rJ" ((USItype)(bh)), \ "rJ" ((USItype)(al)), \ @@ -884,8 +884,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 # define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3" \ - : "=l" ((USItype)(w0)), \ - "=h" ((USItype)(w1)) \ + : "=l" (w0), \ + "=h" (w1) \ : "d" ((USItype)(u)), \ "d" ((USItype)(v))) # else @@ -893,8 +893,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); __asm__ ("multu %2,%3 \n" \ "mflo %0 \n" \ "mfhi %1" \ - : "=d" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ + : "=d" (w0), \ + "=d" (w1) \ : "d" ((USItype)(u)), \ "d" ((USItype)(v))) # endif @@ -919,8 +919,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 # define umul_ppmm(w1, w0, u, v) \ __asm__ ("dmultu %2,%3" \ - : "=l" ((UDItype)(w0)), \ - "=h" ((UDItype)(w1)) \ + : "=l" (w0), \ + "=h" (w1) \ : "d" ((UDItype)(u)), \ "d" ((UDItype)(v))) # else @@ -928,8 +928,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); __asm__ ("dmultu %2,%3 \n" \ "mflo %0 \n" \ "mfhi %1" \ - : "=d" ((UDItype)(w0)), \ - "=d" ((UDItype)(w1)) \ + : "=d" (w0), \ + "=d" (w1) \ : "d" ((UDItype)(u)), \ "d" ((UDItype)(v))) # endif @@ -971,7 +971,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define count_trailing_zeros(count,x) \ do { __asm__ ("ffsd %2,%0" \ - : "=r" ((USItype) (count)) \ + : "=r" (count) \ : "0" ((USItype) 0), \ "r" ((USItype) (x))); \ } while (0) @@ -1120,8 +1120,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addw %5,%1 \n" \ "addwc %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -1129,8 +1129,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subw %5,%1 \n" \ "subwb %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -1156,8 +1156,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("a %1,%5 \n" \ "ae %0,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%0" ((USItype)(ah)), \ "r" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -1165,8 +1165,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("s %1,%5\n" \ "se %0,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "0" ((USItype)(ah)), \ "r" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -1195,8 +1195,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "m r2,%3 \n" \ "cas %0,r2,r0 \n" \ "mfs r10,%1" \ - : "=r" ((USItype)(ph)), \ - "=r" ((USItype)(pl)) \ + : "=r" (ph), \ + "=r" (pl) \ : "%r" (__m0), \ "r" (__m1) \ : "r2"); \ @@ -1209,12 +1209,12 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); do { \ if ((x) >= 0x10000) \ __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ + : "=r" (count) \ : "r" ((USItype)(x) >> 16)); \ else \ { \ __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ + : "=r" (count) \ : "r" ((USItype)(x))); \ (count) += 16; \ } \ @@ -1232,8 +1232,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "dmulu.l %2,%3\n" \ "sts macl,%1\n" \ "sts mach,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ + : "=r" (w1), \ + "=r" (w0) \ : "r" ((USItype)(u)), \ "r" ((USItype)(v)) \ : "macl", "mach") @@ -1247,8 +1247,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addcc %r4,%5,%1\n" \ "addx %r2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%rJ" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "%rJ" ((USItype)(al)), \ @@ -1257,8 +1257,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subcc %r4,%5,%1\n" \ "subx %r2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "rJ" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "rJ" ((USItype)(al)), \ @@ -1271,8 +1271,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); but INTERPRETED AS UNSIGNED. */ # define umul_ppmm(w1, w0, u, v) \ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ + : "=r" (w1), \ + "=r" (w0) \ : "r" ((USItype)(u)), \ "r" ((USItype)(v))) # define UMUL_TIME 5 @@ -1281,7 +1281,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); do { \ USItype __q; \ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \ - : "=r" ((USItype)(__q)) \ + : "=r" (__q) \ : "r" ((USItype)(n1)), \ "r" ((USItype)(n0)), \ "r" ((USItype)(d))); \ @@ -1296,8 +1296,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); instructions scan (ffs from high bit) and divscc. */ # define umul_ppmm(w1, w0, u, v) \ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ + : "=r" (w1), \ + "=r" (w0) \ : "r" ((USItype)(u)), \ "r" ((USItype)(v))) # define UMUL_TIME 5 @@ -1341,8 +1341,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); " bl,a 1f \n" \ " add %1,%4,%1 \n" \ "1: ! End of inline udiv_qrnnd" \ - : "=r" ((USItype)(q)), \ - "=r" ((USItype)(r)) \ + : "=r" (q), \ + "=r" (r) \ : "r" ((USItype)(n1)), \ "r" ((USItype)(n0)), \ "rI" ((USItype)(d)) \ @@ -1350,7 +1350,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); # define UDIV_TIME 37 # define count_leading_zeros(count, x) \ __asm__ ("scan %1,0,%0" \ - : "=r" ((USItype)(x)) \ + : "=r" (x) \ : "r" ((USItype)(count))) /* Early sparclites return 63 for an argument of 0, but they warn that future implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 @@ -1400,8 +1400,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); " mulscc %%g1,0,%%g1 \n" \ " add %%g1,%%g2,%0 \n" \ " rd %%y,%1" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ + : "=r" (w1), \ + "=r" (w0) \ : "%rI" ((USItype)(u)), \ "r" ((USItype)(v)) \ : "%g1", "%g2" __AND_CLOBBER_CC) @@ -1428,8 +1428,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addl2 %5,%1\n" \ "adwc %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ + : "=g" (sh), \ + "=&g" (sl) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ @@ -1437,8 +1437,8 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subl2 %5,%1\n" \ "sbwc %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ + : "=g" (sh), \ + "=&g" (sl) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ @@ -1476,16 +1476,16 @@ extern USItype __udiv_qrnnd (USItype *, USItype, USItype, USItype); #if defined (__z8000__) && W_TYPE_SIZE == 16 # define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ - : "=r" ((unsigned int)(sh)), \ - "=&r" ((unsigned int)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%0" ((unsigned int)(ah)), \ "r" ((unsigned int)(bh)), \ "%1" ((unsigned int)(al)), \ "rQR" ((unsigned int)(bl))) # define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ - : "=r" ((unsigned int)(sh)), \ - "=&r" ((unsigned int)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "0" ((unsigned int)(ah)), \ "r" ((unsigned int)(bh)), \ "1" ((unsigned int)(al)), \ -- 2.54.0 From gniibe at fsij.org Thu Sep 3 09:22:50 2026 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 03 Sep 2026 16:22:50 +0900 Subject: [PATCH] mpi: Drop casts from inline asm output operands. In-Reply-To: <20260902131720.409681-1-mattst88@gmail.com> References: <20260902131720.409681-1-mattst88@gmail.com> Message-ID: <87bjaekddh.fsf@haruna.fsij.org> Hello, Matt Turner wrote: > Using a cast as an lvalue is a GCC extension that clang does not > implement. Clang rejects it with -Winvalid-gnu-asm-cast, which is an > error by default, so these blocks fail to build with clang. Please find a workaround for Clang. IIUC, please use -Wno-invalid-gnu-asm-cast option. If really needed, we could consider adding the option for Clang in libgcrypt/configure.ac. For longlong.h, the upstream used to be GNU C library. It is GCC now (gcc/include/longlong.h). We don't want further differences of our own from upstream. -- From mattst88 at gmail.com Thu Sep 3 20:32:57 2026 From: mattst88 at gmail.com (Matt Turner) Date: Thu, 3 Sep 2026 14:32:57 -0400 Subject: [PATCH] mpi: Drop casts from inline asm output operands. In-Reply-To: <87bjaekddh.fsf@haruna.fsij.org> References: <20260902131720.409681-1-mattst88@gmail.com> <87bjaekddh.fsf@haruna.fsij.org> Message-ID: On Thu, Sep 3, 2026 at 3:22 AM NIIBE Yutaka wrote: > > Hello, > > Matt Turner wrote: > > Using a cast as an lvalue is a GCC extension that clang does not > > implement. Clang rejects it with -Winvalid-gnu-asm-cast, which is an > > error by default, so these blocks fail to build with clang. > > Please find a workaround for Clang. IIUC, please use > -Wno-invalid-gnu-asm-cast option. If really needed, we could consider > adding the option for Clang in libgcrypt/configure.ac. > > For longlong.h, the upstream used to be GNU C library. It is GCC now > (gcc/include/longlong.h). > > We don't want further differences of our own from upstream. Ah, thank you. I'll fix this in GCC first and then return to this. From jussi.kivilinna at iki.fi Tue Sep 8 13:46:41 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:41 +0300 Subject: [PATCH 5/6] tests/basic: deduplicate vector cluttering hwf detection In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-5-jussi.kivilinna@iki.fi> * tests/basic.c (clutter_vector_registers): Replace per-architecture hwflist parsing with table driven detection. -- Each architecture had own copy of hwflist parsing and init handling. Signed-off-by: Jussi Kivilinna --- tests/basic.c | 121 ++++++++++++++++++-------------------------------- 1 file changed, 42 insertions(+), 79 deletions(-) diff --git a/tests/basic.c b/tests/basic.c index 4c5f6038..405f9861 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -307,95 +307,58 @@ clutter_vector_registers(void) static unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; static int data_init; #endif +#if defined(CLUTTER_VECTOR_REGISTER_AMD64) || \ + defined(CLUTTER_VECTOR_REGISTER_I386) + static int have_ymm; + static int have_zmm; +#endif + static int have_vectors; + static struct + { + const char *match; + int *out_have; + int required; + int have; + } hwfeatures[] = + { #if defined(CLUTTER_VECTOR_REGISTER_AARCH64) || \ defined(CLUTTER_VECTOR_REGISTER_NEON) - static int init; - static int have_neon; - - if (!init) - { - char *string; - - string = gcry_get_config (0, "hwflist"); - if (string) - { - have_neon = (strstr(string, "arm-neon:") != NULL); - xfree(string); - } - init = 1; - } - - if (!have_neon) - return; + { "arm-neon:", &have_vectors, 1, 0 }, #elif defined(CLUTTER_VECTOR_REGISTER_AMD64) || \ defined(CLUTTER_VECTOR_REGISTER_I386) - static int init; - static int have_sse2; - static int have_avx; - static int have_avx512; - - if (!init) - { - char *string; - - string = gcry_get_config (0, "hwflist"); - if (string) - { - int have_ssse3 = (strstr(string, "intel-ssse3:") != NULL); - have_sse2 = have_ssse3; /* XMM registers supported */ - have_avx = (strstr(string, "intel-avx:") != NULL); /* YMM */ - have_avx512 = (strstr(string, "intel-avx512:") != NULL); /* ZMM */ - xfree(string); - } - -#ifdef CLUTTER_VECTOR_REGISTER_AMD64 - have_sse2 = 1; -#endif - - init = 1; - } - - if (!have_sse2) - return; + { "intel-ssse3:", &have_vectors, 1, 0 }, + { "intel-avx:", &have_ymm, 0, 0 }, + { "intel-avx512:", &have_zmm, 0, 0 }, #elif defined(CLUTTER_VECTOR_REGISTER_RISCV) - static int init; - static int have_rvv; + { "riscv-v:", &have_vectors, 1, 0 }, +#elif defined(CLUTTER_VECTOR_REGISTER_PPC) + { "ppc-arch_2_07:", &have_vectors, 1, 0 }, +#endif + }; + static int hwf_init = ((int)DIM(hwfeatures) == 0); - if (!init) + if (!hwf_init) { - char *string; - - string = gcry_get_config (0, "hwflist"); - if (string) + char *hwflist = gcry_get_config (0, "hwflist"); + if (hwflist) { - have_rvv = (strstr(string, "riscv-v:") != NULL); - xfree(string); - } - init = 1; - } + int i; - if (!have_rvv) - return; -#elif defined(CLUTTER_VECTOR_REGISTER_PPC) - static int init; - static int have_ppc_vec; - - if (!init) - { - char *string; + for (i = 0; i < (int)DIM(hwfeatures); i++) + { + int have = (strstr(hwflist, hwfeatures[i].match) != NULL); + hwfeatures[i].have = have; + *hwfeatures[i].out_have |= have; + } - string = gcry_get_config (0, "hwflist"); - if (string) - { - have_ppc_vec = (strstr(string, "ppc-arch_2_07:") != NULL); - xfree(string); + xfree(hwflist); } - init = 1; + + hwf_init = 1; } - if (!have_ppc_vec) + if (!have_vectors) return; -#endif #ifdef CLUTTER_VECTOR_REGISTER_COUNT if (!data_init) @@ -409,7 +372,7 @@ clutter_vector_registers(void) if (0) { } # ifdef HAVE_GCC_INLINE_ASM_AVX512 - else if (have_avx512) + else if (have_zmm) asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n" "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n" "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n" @@ -455,7 +418,7 @@ clutter_vector_registers(void) ); # endif # ifdef HAVE_GCC_INLINE_ASM_AVX - else if (have_avx) + else if (have_ymm) asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n" "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n" "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n" @@ -506,7 +469,7 @@ clutter_vector_registers(void) if (0) { } # ifdef HAVE_GCC_INLINE_ASM_AVX512 - else if (have_avx512) + else if (have_zmm) asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n" "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n" "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n" @@ -522,7 +485,7 @@ clutter_vector_registers(void) ); # endif # ifdef HAVE_GCC_INLINE_ASM_AVX - else if (have_avx) + else if (have_ymm) asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n" "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n" "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n" -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:38 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:38 +0300 Subject: [PATCH 2/6] tests/basic: clutter YMM and ZMM registers on i386 and AMD64 In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-2-jussi.kivilinna@iki.fi> * tests/basic.c (CLUTTER_VECTOR_REGISTER_COUNT) [CLUTTER_VECTOR_REGISTER_AMD64]: Increase to 32. (clutter_vector_registers): Make clutter data static and prepare it only once. [CLUTTER_VECTOR_REGISTER_AMD64, CLUTTER_VECTOR_REGISTER_I386]: Detect AVX and AVX512 from hwflist; add YMM and ZMM register cluttering. -- Cluttering only XMM registers left upper halfs of YMM and ZMM registers untouched, so bugs in AVX and AVX512 implementations could pass unnoticed. Signed-off-by: Jussi Kivilinna --- tests/basic.c | 209 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 167 insertions(+), 42 deletions(-) diff --git a/tests/basic.c b/tests/basic.c index 9ec1b596..00d6586d 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -246,7 +246,7 @@ progress_handler (void *cb_data, const char *what, int printchar, defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \ defined(__SSE2__) # define CLUTTER_VECTOR_REGISTER_AMD64 1 -# define CLUTTER_VECTOR_REGISTER_COUNT 16 +# define CLUTTER_VECTOR_REGISTER_COUNT 32 #elif defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 && \ defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(__SSE2__) # define CLUTTER_VECTOR_REGISTER_I386 1 @@ -295,7 +295,8 @@ static inline ALWAYS_INLINE void clutter_vector_registers(void) { #ifdef CLUTTER_VECTOR_REGISTER_COUNT - unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; + static unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; + static int data_init; #if defined(CLUTTER_VECTOR_REGISTER_AARCH64) || \ defined(CLUTTER_VECTOR_REGISTER_NEON) static int init; @@ -316,9 +317,12 @@ clutter_vector_registers(void) if (!have_neon) return; -#elif defined(CLUTTER_VECTOR_REGISTER_I386) +#elif defined(CLUTTER_VECTOR_REGISTER_AMD64) || \ + defined(CLUTTER_VECTOR_REGISTER_I386) static int init; - static int have_ssse3; + static int have_sse2; + static int have_avx; + static int have_avx512; if (!init) { @@ -327,55 +331,176 @@ clutter_vector_registers(void) string = gcry_get_config (0, "hwflist"); if (string) { - have_ssse3 = (strstr(string, "intel-ssse3:") != NULL); + int have_ssse3 = (strstr(string, "intel-ssse3:") != NULL); + have_sse2 = have_ssse3; /* XMM registers supported */ + have_avx = (strstr(string, "intel-avx:") != NULL); /* YMM */ + have_avx512 = (strstr(string, "intel-avx512:") != NULL); /* ZMM */ xfree(string); } + +#ifdef CLUTTER_VECTOR_REGISTER_AMD64 + have_sse2 = 1; +#endif + init = 1; } - if (!have_ssse3) + if (!have_sse2) return; #endif - prepare_vector_data(data); + if (!data_init) + { + prepare_vector_data(data); + data_init = 1; + } #if defined(CLUTTER_VECTOR_REGISTER_AMD64) - asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n" - "movdqu (1 * 16)(%[data]), %%xmm1\n" - "movdqu (2 * 16)(%[data]), %%xmm2\n" - "movdqu (3 * 16)(%[data]), %%xmm3\n" - "movdqu (4 * 16)(%[data]), %%xmm4\n" - "movdqu (5 * 16)(%[data]), %%xmm5\n" - "movdqu (6 * 16)(%[data]), %%xmm6\n" - "movdqu (7 * 16)(%[data]), %%xmm7\n" - "movdqu (8 * 16)(%[data]), %%xmm8\n" - "movdqu (9 * 16)(%[data]), %%xmm9\n" - "movdqu (10 * 16)(%[data]), %%xmm10\n" - "movdqu (11 * 16)(%[data]), %%xmm11\n" - "movdqu (12 * 16)(%[data]), %%xmm12\n" - "movdqu (13 * 16)(%[data]), %%xmm13\n" - "movdqu (14 * 16)(%[data]), %%xmm14\n" - "movdqu (15 * 16)(%[data]), %%xmm15\n" - : - : [data] "r" (&data[0]) - : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", - "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", - "xmm13", "xmm14", "xmm15" - ); + if (0) + { } +# ifdef HAVE_GCC_INLINE_ASM_AVX512 + else if (have_avx512) + asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n" + "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n" + "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n" + "vbroadcasti32x4 (3 * 16)(%[data]), %%zmm3\n" + "vbroadcasti32x4 (4 * 16)(%[data]), %%zmm4\n" + "vbroadcasti32x4 (5 * 16)(%[data]), %%zmm5\n" + "vbroadcasti32x4 (6 * 16)(%[data]), %%zmm6\n" + "vbroadcasti32x4 (7 * 16)(%[data]), %%zmm7\n" + "vbroadcasti32x4 (8 * 16)(%[data]), %%zmm8\n" + "vbroadcasti32x4 (9 * 16)(%[data]), %%zmm9\n" + "vbroadcasti32x4 (10 * 16)(%[data]), %%zmm10\n" + "vbroadcasti32x4 (11 * 16)(%[data]), %%zmm11\n" + "vbroadcasti32x4 (12 * 16)(%[data]), %%zmm12\n" + "vbroadcasti32x4 (13 * 16)(%[data]), %%zmm13\n" + "vbroadcasti32x4 (14 * 16)(%[data]), %%zmm14\n" + "vbroadcasti32x4 (15 * 16)(%[data]), %%zmm15\n" + "vbroadcasti32x4 (16 * 16)(%[data]), %%zmm16\n" + "vbroadcasti32x4 (17 * 16)(%[data]), %%zmm17\n" + "vbroadcasti32x4 (18 * 16)(%[data]), %%zmm18\n" + "vbroadcasti32x4 (19 * 16)(%[data]), %%zmm19\n" + "vbroadcasti32x4 (20 * 16)(%[data]), %%zmm20\n" + "vbroadcasti32x4 (21 * 16)(%[data]), %%zmm21\n" + "vbroadcasti32x4 (22 * 16)(%[data]), %%zmm22\n" + "vbroadcasti32x4 (23 * 16)(%[data]), %%zmm23\n" + "vbroadcasti32x4 (24 * 16)(%[data]), %%zmm24\n" + "vbroadcasti32x4 (25 * 16)(%[data]), %%zmm25\n" + "vbroadcasti32x4 (26 * 16)(%[data]), %%zmm26\n" + "vbroadcasti32x4 (27 * 16)(%[data]), %%zmm27\n" + "vbroadcasti32x4 (28 * 16)(%[data]), %%zmm28\n" + "vbroadcasti32x4 (29 * 16)(%[data]), %%zmm29\n" + "vbroadcasti32x4 (30 * 16)(%[data]), %%zmm30\n" + "vbroadcasti32x4 (31 * 16)(%[data]), %%zmm31\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", + "xmm13", "xmm14", "xmm15" +# ifdef __AVX512F__ + , "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", + "xmm22", "xmm23", "xmm24", "xmm25", "xmm26", "xmm27", + "xmm28", "xmm29", "xmm30", "xmm31" +# endif + ); +# endif +# ifdef HAVE_GCC_INLINE_ASM_AVX + else if (have_avx) + asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n" + "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n" + "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n" + "vbroadcastf128 (3 * 16)(%[data]), %%ymm3\n" + "vbroadcastf128 (4 * 16)(%[data]), %%ymm4\n" + "vbroadcastf128 (5 * 16)(%[data]), %%ymm5\n" + "vbroadcastf128 (6 * 16)(%[data]), %%ymm6\n" + "vbroadcastf128 (7 * 16)(%[data]), %%ymm7\n" + "vbroadcastf128 (8 * 16)(%[data]), %%ymm8\n" + "vbroadcastf128 (9 * 16)(%[data]), %%ymm9\n" + "vbroadcastf128 (10 * 16)(%[data]), %%ymm10\n" + "vbroadcastf128 (11 * 16)(%[data]), %%ymm11\n" + "vbroadcastf128 (12 * 16)(%[data]), %%ymm12\n" + "vbroadcastf128 (13 * 16)(%[data]), %%ymm13\n" + "vbroadcastf128 (14 * 16)(%[data]), %%ymm14\n" + "vbroadcastf128 (15 * 16)(%[data]), %%ymm15\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", + "xmm13", "xmm14", "xmm15" + ); +# endif + else + asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n" + "movdqu (1 * 16)(%[data]), %%xmm1\n" + "movdqu (2 * 16)(%[data]), %%xmm2\n" + "movdqu (3 * 16)(%[data]), %%xmm3\n" + "movdqu (4 * 16)(%[data]), %%xmm4\n" + "movdqu (5 * 16)(%[data]), %%xmm5\n" + "movdqu (6 * 16)(%[data]), %%xmm6\n" + "movdqu (7 * 16)(%[data]), %%xmm7\n" + "movdqu (8 * 16)(%[data]), %%xmm8\n" + "movdqu (9 * 16)(%[data]), %%xmm9\n" + "movdqu (10 * 16)(%[data]), %%xmm10\n" + "movdqu (11 * 16)(%[data]), %%xmm11\n" + "movdqu (12 * 16)(%[data]), %%xmm12\n" + "movdqu (13 * 16)(%[data]), %%xmm13\n" + "movdqu (14 * 16)(%[data]), %%xmm14\n" + "movdqu (15 * 16)(%[data]), %%xmm15\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", + "xmm13", "xmm14", "xmm15" + ); #elif defined(CLUTTER_VECTOR_REGISTER_I386) - asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n" - "movdqu (1 * 16)(%[data]), %%xmm1\n" - "movdqu (2 * 16)(%[data]), %%xmm2\n" - "movdqu (3 * 16)(%[data]), %%xmm3\n" - "movdqu (4 * 16)(%[data]), %%xmm4\n" - "movdqu (5 * 16)(%[data]), %%xmm5\n" - "movdqu (6 * 16)(%[data]), %%xmm6\n" - "movdqu (7 * 16)(%[data]), %%xmm7\n" - : - : [data] "r" (&data[0]) - : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", - "xmm6", "xmm7" - ); + if (0) + { } +# ifdef HAVE_GCC_INLINE_ASM_AVX512 + else if (have_avx512) + asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n" + "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n" + "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n" + "vbroadcasti32x4 (3 * 16)(%[data]), %%zmm3\n" + "vbroadcasti32x4 (4 * 16)(%[data]), %%zmm4\n" + "vbroadcasti32x4 (5 * 16)(%[data]), %%zmm5\n" + "vbroadcasti32x4 (6 * 16)(%[data]), %%zmm6\n" + "vbroadcasti32x4 (7 * 16)(%[data]), %%zmm7\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7" + ); +# endif +# ifdef HAVE_GCC_INLINE_ASM_AVX + else if (have_avx) + asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n" + "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n" + "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n" + "vbroadcastf128 (3 * 16)(%[data]), %%ymm3\n" + "vbroadcastf128 (4 * 16)(%[data]), %%ymm4\n" + "vbroadcastf128 (5 * 16)(%[data]), %%ymm5\n" + "vbroadcastf128 (6 * 16)(%[data]), %%ymm6\n" + "vbroadcastf128 (7 * 16)(%[data]), %%ymm7\n" + : + : [data] "r" (&data[0]) + : "memory", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", + "ymm6", "ymm7" + ); +# endif + else + asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n" + "movdqu (1 * 16)(%[data]), %%xmm1\n" + "movdqu (2 * 16)(%[data]), %%xmm2\n" + "movdqu (3 * 16)(%[data]), %%xmm3\n" + "movdqu (4 * 16)(%[data]), %%xmm4\n" + "movdqu (5 * 16)(%[data]), %%xmm5\n" + "movdqu (6 * 16)(%[data]), %%xmm6\n" + "movdqu (7 * 16)(%[data]), %%xmm7\n" + : + : [data] "r" (&data[0]) + : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7" + ); #elif defined(CLUTTER_VECTOR_REGISTER_AARCH64) asm volatile("mov x0, %[ptr]\n" "ld1 {v0.16b}, [x0], #16\n" -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:39 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:39 +0300 Subject: [PATCH 3/6] tests/basic: add vector cluttering for riscv In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-3-jussi.kivilinna@iki.fi> * tests/basic.c (CLUTTER_VECTOR_REGISTER_RISCV): New. (clutter_vector_registers): Guard clutter data with CLUTTER_VECTOR_REGISTER_COUNT. [CLUTTER_VECTOR_REGISTER_RISCV]: Detect RVV from hwflist; fill v0-v31 with vid.v generated values. -- Vector register width is not known at compile time on RISC-V, so registers are filled with generated values instead of loading from data buffer. Signed-off-by: Jussi Kivilinna --- tests/basic.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/tests/basic.c b/tests/basic.c index 00d6586d..d9664d3c 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -261,6 +261,10 @@ progress_handler (void *cb_data, const char *what, int printchar, defined(__ARM_NEON) # define CLUTTER_VECTOR_REGISTER_NEON 1 # define CLUTTER_VECTOR_REGISTER_COUNT 16 +#elif defined(HAVE_GCC_INLINE_ASM_RISCV_V) && \ + defined(__riscv) +# define CLUTTER_VECTOR_REGISTER_RISCV 1 +# undef CLUTTER_VECTOR_REGISTER_COUNT #endif @@ -297,6 +301,7 @@ clutter_vector_registers(void) #ifdef CLUTTER_VECTOR_REGISTER_COUNT static unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; static int data_init; +#endif #if defined(CLUTTER_VECTOR_REGISTER_AARCH64) || \ defined(CLUTTER_VECTOR_REGISTER_NEON) static int init; @@ -347,13 +352,34 @@ clutter_vector_registers(void) if (!have_sse2) return; +#elif defined(CLUTTER_VECTOR_REGISTER_RISCV) + static int init; + static int have_rvv; + + if (!init) + { + char *string; + + string = gcry_get_config (0, "hwflist"); + if (string) + { + have_rvv = (strstr(string, "riscv-v:") != NULL); + xfree(string); + } + init = 1; + } + + if (!have_rvv) + return; #endif +#ifdef CLUTTER_VECTOR_REGISTER_COUNT if (!data_init) { prepare_vector_data(data); data_init = 1; } +#endif #if defined(CLUTTER_VECTOR_REGISTER_AMD64) if (0) @@ -565,9 +591,44 @@ clutter_vector_registers(void) : "r0", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"); +#elif defined(CLUTTER_VECTOR_REGISTER_RISCV) + asm volatile(".option push;\n" + ".option arch, +v;\n" + "vsetvli t0, %0, e8, m4, ta, ma;\n" + "vid.v v0;\n" + "vid.v v4;\n" + "vid.v v8;\n" + "vid.v v12;\n" + "vid.v v16;\n" + "vid.v v20;\n" + "vid.v v24;\n" + "vid.v v28;\n" + "vadd.vx v4, v4, t0;\n" + "add t1, t0, t0;\n" + "vadd.vx v8, v8, t1;\n" + "add t1, t1, t0;\n" + "vadd.vx v12, v12, t1;\n" + "add t1, t1, t0;\n" + "vadd.vx v16, v16, t1;\n" + "add t1, t1, t0;\n" + "vadd.vx v20, v20, t1;\n" + "add t1, t1, t0;\n" + "add t0, t1, t0;\n" + "vadd.vx v24, v24, t1;\n" + "vadd.vx v28, v28, t0;\n" + ".option pop;\n" + : + : "r" (~0) + : "memory", "vl", "vtype", "t0", "t1", + "v0", "v1", "v2", "v3", + "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", + "v12", "v13", "v14", "v15", + "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", + "v24", "v25", "v26", "v27", + "v28", "v29", "v30", "v31"); #endif - -#endif /* CLUTTER_VECTOR_REGISTER_COUNT */ } -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:40 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:40 +0300 Subject: [PATCH 4/6] tests/basic: add vector cluttering for ppc64 In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-4-jussi.kivilinna@iki.fi> * tests/basic.c (CLUTTER_VECTOR_REGISTER_PPC): New. (clutter_vector_registers) [CLUTTER_VECTOR_REGISTER_PPC]: Detect ppc-arch_2_07 from hwflist; load all 64 VSX registers. -- Signed-off-by: Jussi Kivilinna --- tests/basic.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/basic.c b/tests/basic.c index d9664d3c..4c5f6038 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -265,6 +265,11 @@ progress_handler (void *cb_data, const char *what, int printchar, defined(__riscv) # define CLUTTER_VECTOR_REGISTER_RISCV 1 # undef CLUTTER_VECTOR_REGISTER_COUNT +#elif defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \ + defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) && \ + defined(__POWER8_VECTOR__) +# define CLUTTER_VECTOR_REGISTER_PPC 1 +# define CLUTTER_VECTOR_REGISTER_COUNT 64 #endif @@ -371,6 +376,25 @@ clutter_vector_registers(void) if (!have_rvv) return; +#elif defined(CLUTTER_VECTOR_REGISTER_PPC) + static int init; + static int have_ppc_vec; + + if (!init) + { + char *string; + + string = gcry_get_config (0, "hwflist"); + if (string) + { + have_ppc_vec = (strstr(string, "ppc-arch_2_07:") != NULL); + xfree(string); + } + init = 1; + } + + if (!have_ppc_vec) + return; #endif #ifdef CLUTTER_VECTOR_REGISTER_COUNT @@ -628,6 +652,46 @@ clutter_vector_registers(void) "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); +#elif defined(CLUTTER_VECTOR_REGISTER_PPC) + #define FILL_VECS_10(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) \ + asm volatile("lxvd2x "#v0", %y0\n" \ + "lxvd2x "#v1", %y1\n" \ + "lxvd2x "#v2", %y2\n" \ + "lxvd2x "#v3", %y3\n" \ + "lxvd2x "#v4", %y4\n" \ + "lxvd2x "#v5", %y5\n" \ + "lxvd2x "#v6", %y6\n" \ + "lxvd2x "#v7", %y7\n" \ + "lxvd2x "#v8", %y8\n" \ + "lxvd2x "#v9", %y9\n" \ + : \ + : "Z" (data[v0][0]), "Z" (data[v1][0]), \ + "Z" (data[v2][0]), "Z" (data[v3][0]), \ + "Z" (data[v4][0]), "Z" (data[v5][0]), \ + "Z" (data[v6][0]), "Z" (data[v7][0]), \ + "Z" (data[v8][0]), "Z" (data[v9][0]) \ + : "vs" #v0, "vs" #v1, "vs" #v2, "vs" #v3, \ + "vs" #v4, "vs" #v5, "vs" #v6, "vs" #v7, \ + "vs" #v8, "vs" #v9, "memory"); + #define FILL_VECS_4(v0, v1, v2, v3) \ + asm volatile("lxvd2x "#v0", %y0\n" \ + "lxvd2x "#v1", %y1\n" \ + "lxvd2x "#v2", %y2\n" \ + "lxvd2x "#v3", %y3\n" \ + : \ + : "Z" (data[v0][0]), "Z" (data[v1][0]), \ + "Z" (data[v2][0]), "Z" (data[v3][0]) \ + : "vs" #v0, "vs" #v1, "vs" #v2, "vs" #v3, \ + "memory"); + FILL_VECS_10(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + FILL_VECS_10(10, 11, 12, 13, 14, 15, 16, 17, 18, 19); + FILL_VECS_10(20, 21, 22, 23, 24, 25, 26, 27, 28, 29); + FILL_VECS_10(30, 31, 32, 33, 34, 35, 36, 37, 38, 39); + FILL_VECS_10(40, 41, 42, 43, 44, 45, 46, 47, 48, 49); + FILL_VECS_10(50, 51, 52, 53, 54, 55, 56, 57, 58, 59); + FILL_VECS_4(60, 61, 62, 63); + #undef FILL_VECS_10 + #undef FILL_VECS_4 #endif } -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:42 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:42 +0300 Subject: [PATCH 6/6] tests/basic: add MAC verify API test for bad tag length In-Reply-To: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> References: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> Message-ID: <20260908114642.1031933-6-jussi.kivilinna@iki.fi> * cipher/cipher-cmac.c (cmac_tag): Return GPG_ERR_INV_LENGTH for invalid tag length. * cipher/cipher-gcm.c (_gcry_cipher_gcm_tag): Likewise. * tests/basic.c (check_one_mac): Check that gcry_mac_verify rejects oversized tag length. -- CMAC returned GPG_ERR_INV_ARG and GCM returned GPG_ERR_CHECKSUM for wrong tag length, while HMAC and Poly1305 return GPG_ERR_INV_LENGTH. Signed-off-by: Jussi Kivilinna --- cipher/cipher-cmac.c | 4 +++- cipher/cipher-gcm.c | 5 +++-- tests/basic.c | 9 +++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/cipher/cipher-cmac.c b/cipher/cipher-cmac.c index c8bedc08..aab4b042 100644 --- a/cipher/cipher-cmac.c +++ b/cipher/cipher-cmac.c @@ -216,8 +216,10 @@ cmac_tag (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx, { gcry_err_code_t ret; - if (!tag || taglen == 0 || taglen > c->spec->blocksize) + if (!tag) return GPG_ERR_INV_ARG; + if (taglen == 0 || taglen > c->spec->blocksize) + return GPG_ERR_INV_LENGTH; if (!ctx->tag) { diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c index e6a4df0f..ed04951b 100644 --- a/cipher/cipher-gcm.c +++ b/cipher/cipher-gcm.c @@ -1283,8 +1283,9 @@ _gcry_cipher_gcm_tag (gcry_cipher_hd_t c, { /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF * and thus we need to compare its length first. */ - if (!is_tag_length_valid (outbuflen) - || !buf_eq_const (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen)) + if (!is_tag_length_valid (outbuflen)) + return GPG_ERR_INV_LENGTH; + if (!buf_eq_const (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen)) return GPG_ERR_CHECKSUM; } diff --git a/tests/basic.c b/tests/basic.c index 405f9861..7b8c73f3 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -16405,6 +16405,7 @@ check_one_mac (int algo, const char *data, int datalen, const char *key, int keylen, const char *iv, int ivlen, const char *expect, int test_buffering) { + unsigned char big_bad_tag[64 * 2]; gcry_mac_hd_t hd; unsigned char *p; unsigned int maclen; @@ -16558,6 +16559,14 @@ check_one_mac (int algo, const char *data, int datalen, if (err) fail("algo %d, mac gcry_mac_verify failed: %s\n", algo, gpg_strerror (err)); + clutter_vector_registers(); + err = gcry_mac_verify (hd, big_bad_tag, sizeof(big_bad_tag)); + if (gcry_err_code (err) != GPG_ERR_INV_LENGTH) + fail ("algo %d, gcry_mac_verify: oversized len %d not rejected: %s\n", algo, + (int)sizeof(big_bad_tag), gpg_strerror (err)); + if (err) + goto out; + macoutlen = maclen; clutter_vector_registers(); err = gcry_mac_read (hd, p, &macoutlen); -- 2.53.0 From jussi.kivilinna at iki.fi Tue Sep 8 13:46:37 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 8 Sep 2026 14:46:37 +0300 Subject: [PATCH 1/6] cipher: remove unneeded vzeroupper from AVX implementations Message-ID: <20260908114642.1031933-1-jussi.kivilinna@iki.fi> * cipher/blake2b-amd64-avx2.S (_gcry_blake2b_transform_amd64_avx2): Remove vzeroupper from function entry. * cipher/blake2s-amd64-avx.S (_gcry_blake2s_transform_amd64_avx): Likewise. * cipher/camellia-aesni-avx-amd64.S (_gcry_camellia_aesni_avx_ctr_enc) (_gcry_camellia_aesni_avx_ecb_enc, _gcry_camellia_aesni_avx_ecb_dec) (_gcry_camellia_aesni_avx_cbc_dec, _gcry_camellia_aesni_avx_cfb_dec) (_gcry_camellia_aesni_avx_ocb_enc, _gcry_camellia_aesni_avx_ocb_dec) (_gcry_camellia_aesni_avx_ocb_auth, _gcry_camellia_aesni_avx_keygen): Likewise. * cipher/chacha20-amd64-avx2.S (_gcry_chacha20_amd64_avx2_blocks8) (_gcry_chacha20_poly1305_amd64_avx2_blocks8): Likewise. * cipher/serpent-avx2-amd64.S (_gcry_serpent_avx2_ctr_enc) (_gcry_serpent_avx2_cbc_dec, _gcry_serpent_avx2_cfb_dec) (_gcry_serpent_avx2_ocb_enc, _gcry_serpent_avx2_ocb_dec) (_gcry_serpent_avx2_ocb_auth): Likewise. * cipher/sha1-avx-amd64.S (_gcry_sha1_transform_amd64_avx): Likewise. * cipher/sha1-avx-bmi2-amd64.S (_gcry_sha1_transform_amd64_avx_bmi2): Likewise. * cipher/sha1-avx2-bmi2-amd64.S (_gcry_sha1_transform_amd64_avx2_bmi2): Likewise. * cipher/sha256-avx-amd64.S (_gcry_sha256_transform_amd64_avx): Likewise. * cipher/sha256-avx2-bmi2-amd64.S (_gcry_sha256_transform_amd64_avx2): Likewise. * cipher/sha512-avx-amd64.S (_gcry_sha512_transform_amd64_avx): Likewise. * cipher/sha512-avx2-bmi2-amd64.S (_gcry_sha512_transform_amd64_avx2): Likewise. * cipher/sm3-avx-bmi2-amd64.S (_gcry_sm3_transform_amd64_avx_bmi2): Likewise. * cipher/twofish-avx2-amd64.S (_gcry_twofish_avx2_blk16) (_gcry_twofish_avx2_ctr_enc, _gcry_twofish_avx2_cbc_dec) (_gcry_twofish_avx2_cfb_dec, _gcry_twofish_avx2_ocb_enc) (_gcry_twofish_avx2_ocb_dec, _gcry_twofish_avx2_ocb_auth): Likewise. * cipher/chacha20-amd64-avx512.S (_gcry_chacha20_amd64_avx512_blocks): Remove vzeroupper from register clearing. -- vzeroupper is needed only ahead of legacy SSE code, to avoid AVX-SSE transition penalty. These implementations use VEX/EVEX encoding throughout and clear upper register state with vzeroall before return. Measured on Tiger Lake, leaving upper register state dirty costs 1.54x for legacy SSE loop, but nothing for VEX encoded xmm/ymm code. Zen5 shows no penalty for either. Signed-off-by: Jussi Kivilinna --- cipher/blake2b-amd64-avx2.S | 2 -- cipher/blake2s-amd64-avx.S | 2 -- cipher/camellia-aesni-avx-amd64.S | 18 ------------------ cipher/chacha20-amd64-avx2.S | 4 ---- cipher/chacha20-amd64-avx512.S | 1 - cipher/serpent-avx2-amd64.S | 12 ------------ cipher/sha1-avx-amd64.S | 2 -- cipher/sha1-avx-bmi2-amd64.S | 2 -- cipher/sha1-avx2-bmi2-amd64.S | 2 -- cipher/sha256-avx-amd64.S | 1 - cipher/sha256-avx2-bmi2-amd64.S | 2 -- cipher/sha512-avx-amd64.S | 2 -- cipher/sha512-avx2-bmi2-amd64.S | 2 -- cipher/sm3-avx-bmi2-amd64.S | 2 -- cipher/twofish-avx2-amd64.S | 14 -------------- 15 files changed, 68 deletions(-) diff --git a/cipher/blake2b-amd64-avx2.S b/cipher/blake2b-amd64-avx2.S index 43c2cce1..02ee80a4 100644 --- a/cipher/blake2b-amd64-avx2.S +++ b/cipher/blake2b-amd64-avx2.S @@ -210,8 +210,6 @@ _gcry_blake2b_transform_amd64_avx2: */ CFI_STARTPROC(); - vzeroupper; - addq $128, (STATE_T + 0)(RSTATE); adcq $0, (STATE_T + 8)(RSTATE); diff --git a/cipher/blake2s-amd64-avx.S b/cipher/blake2s-amd64-avx.S index 44b82ab2..d2df67d6 100644 --- a/cipher/blake2s-amd64-avx.S +++ b/cipher/blake2s-amd64-avx.S @@ -196,8 +196,6 @@ _gcry_blake2s_transform_amd64_avx: */ CFI_STARTPROC(); - vzeroupper; - addq $64, (STATE_T + 0)(RSTATE); vmovdqa .Lshuf_ror16 rRIP, R16; diff --git a/cipher/camellia-aesni-avx-amd64.S b/cipher/camellia-aesni-avx-amd64.S index a29b9023..14e11d18 100644 --- a/cipher/camellia-aesni-avx-amd64.S +++ b/cipher/camellia-aesni-avx-amd64.S @@ -896,8 +896,6 @@ _gcry_camellia_aesni_avx_ctr_enc: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - cmpl $128, key_bitlength(CTX); movl $32, %r8d; movl $24, %eax; @@ -1053,8 +1051,6 @@ _gcry_camellia_aesni_avx_ecb_enc: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - cmpl $128, key_bitlength(CTX); movl $32, %r8d; movl $24, %eax; @@ -1099,8 +1095,6 @@ _gcry_camellia_aesni_avx_ecb_dec: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - cmpl $128, key_bitlength(CTX); movl $32, %r8d; movl $24, %eax; @@ -1146,8 +1140,6 @@ _gcry_camellia_aesni_avx_cbc_dec: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - movq %rcx, %r9; cmpl $128, key_bitlength(CTX); @@ -1219,8 +1211,6 @@ _gcry_camellia_aesni_avx_cfb_dec: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - cmpl $128, key_bitlength(CTX); movl $32, %r8d; movl $24, %eax; @@ -1303,8 +1293,6 @@ _gcry_camellia_aesni_avx_ocb_enc: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - subq $(16 * 16 + 4 * 8), %rsp; andq $~31, %rsp; movq %rsp, %rax; @@ -1455,8 +1443,6 @@ _gcry_camellia_aesni_avx_ocb_dec: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - subq $(16 * 16 + 4 * 8), %rsp; andq $~31, %rsp; movq %rsp, %rax; @@ -1625,8 +1611,6 @@ _gcry_camellia_aesni_avx_ocb_auth: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - subq $(16 * 16 + 4 * 8), %rsp; andq $~31, %rsp; movq %rsp, %rax; @@ -2720,8 +2704,6 @@ _gcry_camellia_aesni_avx_keygen: */ CFI_STARTPROC(); - vzeroupper; - vmovdqu (%rsi), %xmm0; cmpl $24, %edx; jb __camellia_avx_setup128; diff --git a/cipher/chacha20-amd64-avx2.S b/cipher/chacha20-amd64-avx2.S index 54e2ffab..b2311ab5 100644 --- a/cipher/chacha20-amd64-avx2.S +++ b/cipher/chacha20-amd64-avx2.S @@ -184,8 +184,6 @@ _gcry_chacha20_amd64_avx2_blocks8: */ CFI_STARTPROC(); - vzeroupper; - pushq %rbp; CFI_PUSH(%rbp); movq %rsp, %rbp; @@ -356,8 +354,6 @@ _gcry_chacha20_poly1305_amd64_avx2_blocks8: movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); - vzeroupper; - subq $(9 * 8) + STACK_MAX + 32, %rsp; andq $~31, %rsp; diff --git a/cipher/chacha20-amd64-avx512.S b/cipher/chacha20-amd64-avx512.S index 2d140815..6d421bf2 100644 --- a/cipher/chacha20-amd64-avx512.S +++ b/cipher/chacha20-amd64-avx512.S @@ -625,7 +625,6 @@ _gcry_chacha20_amd64_avx512_blocks: .Lskip4v: /* clear AVX512 registers */ kxorq %k2, %k2, %k2; - vzeroupper; clear_zmm16_zmm31(); .align 16 diff --git a/cipher/serpent-avx2-amd64.S b/cipher/serpent-avx2-amd64.S index a419eb29..9ec31f17 100644 --- a/cipher/serpent-avx2-amd64.S +++ b/cipher/serpent-avx2-amd64.S @@ -645,8 +645,6 @@ _gcry_serpent_avx2_ctr_enc: */ CFI_STARTPROC(); - vzeroupper; - vbroadcasti128 .Lbswap128_mask rRIP, RTMP3; vpcmpeqd RNOT, RNOT, RNOT; vpsrldq $14, RNOT, RNOT; /* ab: -1:0 ; cd: -1:0 */ @@ -718,8 +716,6 @@ _gcry_serpent_avx2_cbc_dec: */ CFI_STARTPROC(); - vzeroupper; - vmovdqu (0 * 32)(%rdx), RA0; vmovdqu (1 * 32)(%rdx), RA1; vmovdqu (2 * 32)(%rdx), RA2; @@ -771,8 +767,6 @@ _gcry_serpent_avx2_cfb_dec: */ CFI_STARTPROC(); - vzeroupper; - /* Load input */ vmovdqu (%rcx), RNOTx; vinserti128 $1, (%rdx), RNOT, RA0; @@ -829,8 +823,6 @@ _gcry_serpent_avx2_ocb_enc: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); @@ -943,8 +935,6 @@ _gcry_serpent_avx2_ocb_dec: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); @@ -1066,8 +1056,6 @@ _gcry_serpent_avx2_ocb_auth: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); diff --git a/cipher/sha1-avx-amd64.S b/cipher/sha1-avx-amd64.S index e5e55684..ca81506c 100644 --- a/cipher/sha1-avx-amd64.S +++ b/cipher/sha1-avx-amd64.S @@ -222,8 +222,6 @@ _gcry_sha1_transform_amd64_avx: cmpq $0, %rdx; jz .Lret; - vzeroupper; - movq %rdx, RNBLKS; movq %rdi, RSTATE; movq %rsi, RDATA; diff --git a/cipher/sha1-avx-bmi2-amd64.S b/cipher/sha1-avx-bmi2-amd64.S index 16a01bfd..85ba22b0 100644 --- a/cipher/sha1-avx-bmi2-amd64.S +++ b/cipher/sha1-avx-bmi2-amd64.S @@ -222,8 +222,6 @@ _gcry_sha1_transform_amd64_avx_bmi2: cmpq $0, %rdx; jz .Lret; - vzeroupper; - movq %rdx, RNBLKS; movq %rdi, RSTATE; movq %rsi, RDATA; diff --git a/cipher/sha1-avx2-bmi2-amd64.S b/cipher/sha1-avx2-bmi2-amd64.S index 06ff92f0..190b9731 100644 --- a/cipher/sha1-avx2-bmi2-amd64.S +++ b/cipher/sha1-avx2-bmi2-amd64.S @@ -224,8 +224,6 @@ _gcry_sha1_transform_amd64_avx2_bmi2: */ CFI_STARTPROC(); - vzeroupper; - movq %rdx, RNBLKS; movq %rdi, RSTATE; movq %rsi, RDATA; diff --git a/cipher/sha256-avx-amd64.S b/cipher/sha256-avx-amd64.S index 8cfd0880..9c15f481 100644 --- a/cipher/sha256-avx-amd64.S +++ b/cipher/sha256-avx-amd64.S @@ -345,7 +345,6 @@ ELF(.type _gcry_sha256_transform_amd64_avx, at function;) .align 16 _gcry_sha256_transform_amd64_avx: CFI_STARTPROC() - vzeroupper push rbx CFI_PUSH(rbx) diff --git a/cipher/sha256-avx2-bmi2-amd64.S b/cipher/sha256-avx2-bmi2-amd64.S index e2a5454c..ec99e57f 100644 --- a/cipher/sha256-avx2-bmi2-amd64.S +++ b/cipher/sha256-avx2-bmi2-amd64.S @@ -268,8 +268,6 @@ _gcry_sha256_transform_amd64_avx2: push r15 CFI_PUSH(r15) - vzeroupper - vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP] vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP] vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP] diff --git a/cipher/sha512-avx-amd64.S b/cipher/sha512-avx-amd64.S index 1bd38060..22b1058e 100644 --- a/cipher/sha512-avx-amd64.S +++ b/cipher/sha512-avx-amd64.S @@ -254,8 +254,6 @@ _gcry_sha512_transform_amd64_avx: cmp msglen, 0 je .Lnowork - vzeroupper - /* Allocate Stack Space */ sub rsp, frame_size CFI_ADJUST_CFA_OFFSET(frame_size); diff --git a/cipher/sha512-avx2-bmi2-amd64.S b/cipher/sha512-avx2-bmi2-amd64.S index 7b60bf1d..c2275bb5 100644 --- a/cipher/sha512-avx2-bmi2-amd64.S +++ b/cipher/sha512-avx2-bmi2-amd64.S @@ -282,8 +282,6 @@ _gcry_sha512_transform_amd64_avx2: cmp rdx, 0 je .Lnowork - vzeroupper - /* Allocate Stack Space */ mov rax, rsp CFI_DEF_CFA_REGISTER(rax); diff --git a/cipher/sm3-avx-bmi2-amd64.S b/cipher/sm3-avx-bmi2-amd64.S index ef923165..9252e279 100644 --- a/cipher/sm3-avx-bmi2-amd64.S +++ b/cipher/sm3-avx-bmi2-amd64.S @@ -354,8 +354,6 @@ _gcry_sm3_transform_amd64_avx_bmi2: */ CFI_STARTPROC(); - vzeroupper; - pushq %rbp; CFI_PUSH(%rbp); movq %rsp, %rbp; diff --git a/cipher/twofish-avx2-amd64.S b/cipher/twofish-avx2-amd64.S index 72a39d17..c448dfae 100644 --- a/cipher/twofish-avx2-amd64.S +++ b/cipher/twofish-avx2-amd64.S @@ -519,8 +519,6 @@ _gcry_twofish_avx2_blk16: */ CFI_STARTPROC(); - vzeroupper; - vmovdqu (0 * 32)(%rdx), RA0; vmovdqu (1 * 32)(%rdx), RB0; vmovdqu (2 * 32)(%rdx), RC0; @@ -565,8 +563,6 @@ _gcry_twofish_avx2_ctr_enc: */ CFI_STARTPROC(); - vzeroupper; - vbroadcasti128 .Lbswap128_mask rRIP, RTMP3; vpcmpeqd RNOT, RNOT, RNOT; vpsrldq $14, RNOT, RNOT; /* ab: -1:0 ; cd: -1:0 */ @@ -638,8 +634,6 @@ _gcry_twofish_avx2_cbc_dec: */ CFI_STARTPROC(); - vzeroupper; - vmovdqu (0 * 32)(%rdx), RA0; vmovdqu (1 * 32)(%rdx), RB0; vmovdqu (2 * 32)(%rdx), RC0; @@ -691,8 +685,6 @@ _gcry_twofish_avx2_cfb_dec: */ CFI_STARTPROC(); - vzeroupper; - /* Load input */ vmovdqu (%rcx), RNOTx; vinserti128 $1, (%rdx), RNOT, RA0; @@ -749,8 +741,6 @@ _gcry_twofish_avx2_ocb_enc: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); @@ -863,8 +853,6 @@ _gcry_twofish_avx2_ocb_dec: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); @@ -987,8 +975,6 @@ _gcry_twofish_avx2_ocb_auth: */ CFI_STARTPROC(); - vzeroupper; - subq $(4 * 8), %rsp; CFI_ADJUST_CFA_OFFSET(4 * 8); -- 2.53.0 From jonathan.plata at lightshipsec.com Wed Sep 9 16:12:25 2026 From: jonathan.plata at lightshipsec.com (Jonathan Plata) Date: Wed, 9 Sep 2026 14:12:25 +0000 Subject: PATCH: Padding bug in cSHAKE-128/256 Message-ID: Hello! cshake_input_s()'s padlen computation, padlen = ctx->blocksize - (len_written % ctx->blocksize); does not handle the case where len_written is already an exact multiple of ctx->blocksize: the modulo evaluates to 0, so padlen comes out as ctx->blocksize (a full block) instead of 0. SP 800-185's bytepad (sec. 2.3.3) specifies padding with zero bytes only until the total length becomes a multiple of the rate -- when it already is, no padding bytes should be added at all. The bug results in a full extra block of zero bytes added to the Keccak sponge, producing a wrong cSHAKE digest whenever the encoded N (function-name string) + S (customization string) length lands exactly on a rate boundary (168 bytes for cSHAKE128, 136 for cSHAKE256). Concretely: cSHAKE128 with an empty N and a 161-byte S (2-byte rate prefix + 2-byte encode_string(empty N) + 3-byte encode_string(S) length-prefix + 161 == 168 == the cSHAKE128 rate) triggers it; cSHAKE256 with an empty N and a 129-byte S hits the same condition against its 136-byte rate. Found via NIST ACVP cSHAKE-128/256 conformance vectors: a fixture covering random S lengths reliably produces a wrong digest at S = 161 (cSHAKE128) and S = 129 (cSHAKE256), and only those lengths (adjacent lengths pass), consistent with this exact rate-boundary condition. Confirmed against libgcrypt 1.11.2 and 1.12.0 (unchanged between the two). Signed-off-by: Jonathan Plata --- cipher/keccak.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/keccak.c b/cipher/keccak.c index a0ba1fbb..1351da16 100644 --- a/cipher/keccak.c +++ b/cipher/keccak.c @@ -1694,7 +1694,7 @@ cshake_input_s (KECCAK_CONTEXT *ctx, const void *s, unsigned int s_len, keccak_write (ctx, s, s_len); len_written += buf[0] + 1 + s_len; - padlen = ctx->blocksize - (len_written % ctx->blocksize); + padlen = (ctx->blocksize - (len_written % ctx->blocksize)) % ctx->blocksize; memset (buf, 0, padlen); keccak_write (ctx, buf, padlen); } -- 2.34.1 [cid:image001.png at 01DD4040.AC77CD40] Jonathan Plata | Software Developer Lightship Security, Inc. Tel: 512-362-6594 https://lightshipsec.com This email and attachments are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you are not the named addressee, you may not disseminate, distribute or copy this email. Please notify the sender immediately if you have received this email in error and delete it from your system. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.png Type: image/png Size: 4162 bytes Desc: image001.png URL: From gniibe at fsij.org Thu Sep 10 07:26:04 2026 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 10 Sep 2026 14:26:04 +0900 Subject: PATCH: Padding bug in cSHAKE-128/256 In-Reply-To: References: Message-ID: <87ecf1brtf.fsf@haruna.fsij.org> Hello, Jonathan Plata wrote: > cshake_input_s()'s padlen computation, > > padlen = ctx->blocksize - (len_written % ctx->blocksize); Thank you for your report. > --- a/cipher/keccak.c > +++ b/cipher/keccak.c > @@ -1694,7 +1694,7 @@ cshake_input_s (KECCAK_CONTEXT *ctx, const void *s, unsigned int s_len, > keccak_write (ctx, s, s_len); > > len_written += buf[0] + 1 + s_len; > - padlen = ctx->blocksize - (len_written % ctx->blocksize); > + padlen = (ctx->blocksize - (len_written % ctx->blocksize)) % ctx->blocksize; > memset (buf, 0, padlen); > keccak_write (ctx, buf, padlen); > } While the expression is correct, I'm not sure if multiple %-operations can be optimized well by compiler. Just in case, I think that it's better to use a single %-operation in the expression. Attached is a patch with a single %-operation. If no objections, I will push this to 1.11, 1.12 and master. -- -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-cipher-keccak-Fix-padding-in-cSHAKE.patch Type: text/x-diff Size: 1529 bytes Desc: not available URL: From jussi.kivilinna at iki.fi Mon Sep 28 18:43:38 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 28 Sep 2026 19:43:38 +0300 Subject: [PATCH 1/3] aarch64-asm: fix macOS build and enable asm implementations Message-ID: <20260928164340.3724227-1-jussi.kivilinna@iki.fi> * build-aux/darwin-aarch64-as.sh: New. * Makefile.am (EXTRA_DIST): Add 'build-aux/darwin-aarch64-as.sh'. * cipher/Makefile.am (CLEANFILES): Add '*-darwin.s'. * mpi/Makefile.am (CLEANFILES): New. * configure.ac [*-apple-darwin*] (CCAS): Use 'darwin-aarch64-as.sh' wrapper on macOS AArch64. (GNUPG_SYS_SYMBOL_UNDERSCORE): Move before assembler checks. (symbol_prefix): New. (gcry_cv_gcc_aarch64_platform_as_ok) (gcry_cv_gcc_inline_asm_aarch64_neon) (gcry_cv_gcc_inline_asm_aarch64_crypto) (gcry_cv_gcc_inline_asm_aarch64_sve) (gcry_cv_gcc_inline_asm_aarch64_sve2) (gcry_cv_gcc_inline_asm_aarch64_sha3_sha512_sm3_sm4): Add symbol prefix to test function label. * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Set underscore prefix for AArch64 Darwin. * cipher/asm-common-aarch64.h [__APPLE__] (SECTION_RODATA): New. [__APPLE__] (GET_DATA_POINTER): Use '@PAGE' and '@PAGEOFF'. -- Darwin assembler uses ';' as comment character, so statements after first ';' in macro expansions were silently dropped. Commit 9b684f4a added ';' separator in 'CFI_ENDPROC' and then caused macOS builds fail with "Unfinished frame!" error in mpi/aarch64. Also AArch64 cipher assembly was never built on macOS as configure checks failed to link test function because of missing '_' symbol prefix. Patch adds assembler wrapper for AArch64 Darwin that is used as CCAS. Wrapper runs C preprocessor on .S source, splits ';' separated statements to separate lines, converts '.L' local labels to Darwin 'L' prefix and adds '_' prefix to _gcry symbols, and then assembles the result. Darwin variant of 'GET_DATA_POINTER' used GOT relocation with 'add' instruction, which assembler rejects, and 'SECTION_RODATA' did not have Darwin variant. Benchmark on Apple M1 Mac Mini: Hash: | nanosecs/byte mebibytes/sec cycles/byte auto Mhz SHA1 | 0.408 ns/B 2336 MiB/s 1.30 c/B 3192 SHA256 | 0.411 ns/B 2321 MiB/s 1.31 c/B 3192 SHA512 | 0.693 ns/B 1377 MiB/s 2.21 c/B 3192 = Cipher: AES | nanosecs/byte mebibytes/sec cycles/byte auto Mhz ECB enc | 0.077 ns/B 12370 MiB/s 0.246 c/B 3192 ECB dec | 0.077 ns/B 12307 MiB/s 0.247 c/B 3192 CBC enc | 0.634 ns/B 1505 MiB/s 2.02 c/B 3192 CBC dec | 0.076 ns/B 12540 MiB/s 0.243 c/B 3192 CFB enc | 0.637 ns/B 1498 MiB/s 2.03 c/B 3192 CFB dec | 0.070 ns/B 13594 MiB/s 0.224 c/B 3192 OFB enc | 0.751 ns/B 1270 MiB/s 2.40 c/B 3192 OFB dec | 0.751 ns/B 1269 MiB/s 2.40 c/B 3192 CTR enc | 0.078 ns/B 12192 MiB/s 0.250 c/B 3192 CTR dec | 0.078 ns/B 12206 MiB/s 0.249 c/B 3192 XTS enc | 0.124 ns/B 7714 MiB/s 0.395 c/B 3192 XTS dec | 0.124 ns/B 7715 MiB/s 0.395 c/B 3192 CCM enc | 0.710 ns/B 1343 MiB/s 2.27 c/B 3192 CCM dec | 0.712 ns/B 1339 MiB/s 2.27 c/B 3192 CCM auth | 0.632 ns/B 1509 MiB/s 2.02 c/B 3192 EAX enc | 0.712 ns/B 1340 MiB/s 2.27 c/B 3192 EAX dec | 0.715 ns/B 1334 MiB/s 2.28 c/B 3192 EAX auth | 0.635 ns/B 1501 MiB/s 2.03 c/B 3192 GCM enc | 0.180 ns/B 5292 MiB/s 0.575 c/B 3192 GCM dec | 0.181 ns/B 5278 MiB/s 0.577 c/B 3192 GCM auth | 0.101 ns/B 9420 MiB/s 0.323 c/B 3192 OCB enc | 0.074 ns/B 12847 MiB/s 0.237 c/B 3192 OCB dec | 0.072 ns/B 13155 MiB/s 0.231 c/B 3192 OCB auth | 0.102 ns/B 9372 MiB/s 0.325 c/B 3192 SIV enc | 0.713 ns/B 1337 MiB/s 2.28 c/B 3192 SIV dec | 0.725 ns/B 1315 MiB/s 2.31 c/B 3192 SIV auth | 0.633 ns/B 1506 MiB/s 2.02 c/B 3192 GCM-SIV enc | 0.184 ns/B 5191 MiB/s 0.586 c/B 3192 GCM-SIV dec | 0.191 ns/B 4991 MiB/s 0.610 c/B 3192 GCM-SIV auth | 0.100 ns/B 9490 MiB/s 0.321 c/B 3192 = CHACHA20 | nanosecs/byte mebibytes/sec cycles/byte auto Mhz STREAM enc | 0.709 ns/B 1346 MiB/s 2.26 c/B 3192 STREAM dec | 0.708 ns/B 1346 MiB/s 2.26 c/B 3192 POLY1305 enc | 0.721 ns/B 1322 MiB/s 2.30 c/B 3192 POLY1305 dec | 0.705 ns/B 1353 MiB/s 2.25 c/B 3192 POLY1305 auth | 0.291 ns/B 3274 MiB/s 0.930 c/B 3192 = GnuPG-bug-id: 8463 Signed-off-by: Jussi Kivilinna --- Makefile.am | 1 + acinclude.m4 | 3 + build-aux/darwin-aarch64-as.sh | 114 +++++++++++++++++++++++++++++++++ cipher/Makefile.am | 2 +- cipher/asm-common-aarch64.h | 6 +- configure.ac | 38 +++++++---- mpi/Makefile.am | 1 + 7 files changed, 149 insertions(+), 16 deletions(-) create mode 100644 build-aux/darwin-aarch64-as.sh diff --git a/Makefile.am b/Makefile.am index f4da0905..14520bc5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -49,6 +49,7 @@ EXTRA_DIST = autogen.sh autogen.rc README.GIT LICENSES \ m4/ChangeLog-2011 cipher/ChangeLog-2011 src/ChangeLog-2011 \ random/ChangeLog-2011 tests/ChangeLog-2011 mpi/ChangeLog-2011 \ build-aux/libtool-patch.sed \ + build-aux/darwin-aarch64-as.sh \ build-aux/git-log-footer build-aux/git-log-fix VERSION DISTCLEANFILES = diff --git a/acinclude.m4 b/acinclude.m4 index 43e0e906..1054d074 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -73,6 +73,9 @@ case "${host}" in i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp) ac_cv_sys_symbol_underscore=yes ;; + aarch64-apple-darwin*) + ac_cv_sys_symbol_underscore=yes + ;; *) if test "$cross_compiling" != yes; then tmp_do_check="yes" diff --git a/build-aux/darwin-aarch64-as.sh b/build-aux/darwin-aarch64-as.sh new file mode 100644 index 00000000..83f80dcb --- /dev/null +++ b/build-aux/darwin-aarch64-as.sh @@ -0,0 +1,114 @@ +#!/bin/sh +# Assembler wrapper for AArch64 Darwin. +# Copyright (C) 2026 Jussi Kivilinna +# +# This file is part of Libgcrypt. +# +# Libgcrypt is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# Libgcrypt is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, see . + +# Darwin assembler uses ';' as comment character, treats only 'L' prefixed +# labels as assembler local and C symbols have '_' prefix. +# +# Run C preprocessor on the .S source, then split ';' separated +# statements to separate lines, convert '.L' labels to 'L' and add +# prefix to _gcry symbols, and assemble the result. +# +# Usage: darwin-aarch64-as.sh CC [CCFLAGS...] ARGS... + +# Preprocess only: '-c' becomes '-E' and output goes to "$pp". +run_cpp () +{ + n=$# + skip= + for a in "$@"; do + if test -n "$skip"; then + skip= + a="$pp" + else + case "$a" in + -c) a=-E ;; + -o) skip=1 ;; + esac + fi + set -- "$@" "$a" + done + shift $n + "$@" +} + +# Assemble "$asm" in place of "$src", without dependency generation. +run_as () +{ + n=$# + skip= + for a in "$@"; do + if test -n "$skip"; then + skip= + continue + fi + case "$a" in + -MT|-MF|-MQ) skip=1; continue ;; + -MD|-MMD|-MP) continue ;; + "$src") a="$asm" ;; + esac + set -- "$@" "$a" + done + shift $n + "$@" +} + +# Find .S source and output object; pass through non-.S compiles as is. +src= +out= +prev= +for a in "$@"; do + case "$prev" in + -o) out="$a" ;; + esac + case "$a" in + *.S) src="$a" ;; + esac + prev="$a" +done + +if test -z "$src"; then + exec "$@" +fi + +# Place converted source next to output object, as libtool compiles +# PIC and non-PIC objects to separate directories. +base="${src##*/}" +if test -n "$out"; then + asm="$(dirname "$out")/${base%.S}-darwin.s" +else + asm="${base%.S}-darwin.s" +fi +pp="$asm.i" + +trap 'rm -f "$pp"' EXIT + +run_cpp "$@" || exit 1 + +# Convert to Darwin syntax +# * ; separator to newline +# * .L local symbol prefix to L +# * _gcry_ global symbol prefix to __gcry_ +tr ';' '\n' < "$pp" | \ + sed -e 's/^\.L/L/' \ + -e 's/\([^A-Za-z0-9_.]\)\.L/\1L/g' \ + -e 's/^_gcry_/__gcry_/' \ + -e 's/\([^A-Za-z0-9_]\)_gcry_/\1__gcry_/g' \ + > "$asm" || exit 1 + +run_as "$@" diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 0c00d181..486bd99e 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -29,7 +29,7 @@ AM_CCASFLAGS = $(NOEXECSTACK_FLAGS) EXTRA_DIST = gost-s-box.c kyber-common.c kyber-kdep.c \ dilithium-common.c dilithium-dep.c -CLEANFILES = gost-s-box$(EXEEXT_FOR_BUILD) +CLEANFILES = gost-s-box$(EXEEXT_FOR_BUILD) *-darwin.s DISTCLEANFILES = gost-sb.h noinst_LTLIBRARIES = libcipher.la diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h index ec9b9b92..821eeda5 100644 --- a/cipher/asm-common-aarch64.h +++ b/cipher/asm-common-aarch64.h @@ -31,14 +31,16 @@ #ifdef _WIN32 # define SECTION_RODATA .section .rdata +#elif defined(__APPLE__) +# define SECTION_RODATA .section __TEXT,__const #else # define SECTION_RODATA .section .rodata #endif #ifdef __APPLE__ #define GET_DATA_POINTER(reg, name) \ - adrp reg, name at GOTPAGE ; \ - add reg, reg, name at GOTPAGEOFF ; + adrp reg, name at PAGE ; \ + add reg, reg, name at PAGEOFF ; #else #define GET_DATA_POINTER(reg, name) \ adrp reg, name ; \ diff --git a/configure.ac b/configure.ac index ea7ea7ae..d9cbf5d2 100644 --- a/configure.ac +++ b/configure.ac @@ -297,6 +297,11 @@ case "${host}" in AC_DEFINE(USE_POSIX_SPAWN_FOR_TESTS, 1, [defined if we use posix_spawn in test program]) AC_CHECK_HEADERS(spawn.h) + + if test "$host_cpu" = aarch64; then + CCAS="\$(SHELL) \$(top_srcdir)/build-aux/darwin-aarch64-as.sh $CCAS" + fi + ;; *-openedition*) @@ -874,6 +879,20 @@ AC_TYPE_PID_T AC_CHECK_TYPES([byte, ushort, u16, u32, u64]) + +# +# Check whether underscores in symbols are required. This needs to be +# done before setting up the assembler stuff. +# +GNUPG_SYS_SYMBOL_UNDERSCORE() + +if test "$ac_cv_sys_symbol_underscore" = "yes" ; then + symbol_prefix=_ +else + symbol_prefix= +fi + + # # Check for __builtin_bswap32 intrinsic. # @@ -1247,7 +1266,7 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARMv8/Aarch64 assembly i AC_LINK_IFELSE([AC_LANG_PROGRAM( [[__asm__( ".text\n\t" - "asmfunc:\n\t" + "$symbol_prefix" "asmfunc:\n\t" "eor x0, x0, x30, ror #12;\n\t" "add x0, x0, x30, asr #12;\n\t" "eor v0.16b, v0.16b, v31.16b;\n\t" @@ -1310,13 +1329,6 @@ if test "$gcry_cv_gcc_asm_elf_directives" = "yes" ; then fi -# -# Check whether underscores in symbols are required. This needs to be -# done before setting up the assembler stuff. -# -GNUPG_SYS_SYMBOL_UNDERSCORE() - - ################################# #### #### #### Setup assembler stuff. #### @@ -2200,7 +2212,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 NEON instructions] [[__asm__( ".cpu generic+simd\n\t" ".text\n\t" - "testfn:\n\t" + "$symbol_prefix" "testfn:\n\t" "mov w0, \#42;\n\t" "dup v0.8b, w0;\n\t" "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t" @@ -2229,7 +2241,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 Crypto Extension i [[__asm__( ".cpu generic+simd+crypto\n\t" ".text\n\t" - "testfn:\n\t" + "$symbol_prefix" "testfn:\n\t" "mov w0, \#42;\n\t" "dup v0.8b, w0;\n\t" "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t" @@ -2278,7 +2290,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 SVE instructions], [[__asm__( ".cpu generic+simd+sve\n\t" ".text\n\t" - "testfn:\n\t" + "$symbol_prefix" "testfn:\n\t" "mov x0, \#60;\n\t" "whilelo p0.s, xzr, x0;\n\t" "mov z0.s, p0/z, \#55;\n\t" @@ -2308,7 +2320,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 SVE2 instructions] [[__asm__( ".cpu generic+simd+sve2\n\t" ".text\n\t" - "testfn:\n\t" + "$symbol_prefix" "testfn:\n\t" ";\n\t" "eor3 z0.d, z0.d, z1.d, z2.d;\n\t" "ext z8.b, {z20.b, z21.b}, \#3;\n\t" @@ -2342,7 +2354,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 SHA3/SHA512/SM3/SM [[__asm__( ".arch armv8.2-a+sha3+sm4\n\t" ".text\n\t" - "testfn:\n\t" + "$symbol_prefix" "testfn:\n\t" /* Test for SHA512 instructions */ "sha512h q0, q0, v0.2d;\n\t" diff --git a/mpi/Makefile.am b/mpi/Makefile.am index a7268e2b..960a73ad 100644 --- a/mpi/Makefile.am +++ b/mpi/Makefile.am @@ -30,6 +30,7 @@ AM_ASFLAGS = $(MPI_SFLAGS) AM_CCASFLAGS = $(NOEXECSTACK_FLAGS) EXTRA_DIST = config.links +CLEANFILES = *-darwin.s DISTCLEANFILES = mpi-asm-defs.h \ mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \ mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \ -- 2.53.0 From jussi.kivilinna at iki.fi Mon Sep 28 18:43:40 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 28 Sep 2026 19:43:40 +0300 Subject: [PATCH 3/3] aarch64-asm: use common CLEAR_REG definition In-Reply-To: <20260928164340.3724227-1-jussi.kivilinna@iki.fi> References: <20260928164340.3724227-1-jussi.kivilinna@iki.fi> Message-ID: <20260928164340.3724227-3-jussi.kivilinna@iki.fi> * cipher/asm-common-aarch64.h (CLEAR_REG): Accept variadic arguments. * cipher/chacha20-aarch64.S (clear): Remove; use CLEAR_REG. * cipher/rijndael-armv8-aarch64-ce.S (CLEAR_REG): Remove. * cipher/sha1-armv8-aarch64-ce.S: Likewise. * cipher/sha256-armv8-aarch64-ce.S: Likewise. * cipher/sha512-armv8-aarch64-ce.S: Likewise. * cipher/sm3-aarch64.S (clear_vec): Remove; use CLEAR_REG. -- Signed-off-by: Jussi Kivilinna --- cipher/asm-common-aarch64.h | 2 +- cipher/chacha20-aarch64.S | 91 +++++++++++++++--------------- cipher/rijndael-armv8-aarch64-ce.S | 2 - cipher/sha1-armv8-aarch64-ce.S | 5 -- cipher/sha256-armv8-aarch64-ce.S | 5 -- cipher/sha512-armv8-aarch64-ce.S | 6 -- cipher/sm3-aarch64.S | 29 +++++----- 7 files changed, 58 insertions(+), 82 deletions(-) diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h index 821eeda5..d3da14e4 100644 --- a/cipher/asm-common-aarch64.h +++ b/cipher/asm-common-aarch64.h @@ -128,7 +128,7 @@ #define ret_spec_stop \ ret; SPEC_STOP; -#define CLEAR_REG(reg) movi reg.16b, #0; +#define CLEAR_REG(reg, ...) movi reg.16b, #0; #define CLEAR_ALL_REGS() \ CLEAR_REG(v0); CLEAR_REG(v1); CLEAR_REG(v2); CLEAR_REG(v3); \ diff --git a/cipher/chacha20-aarch64.S b/cipher/chacha20-aarch64.S index 692f0f6a..060e0243 100644 --- a/cipher/chacha20-aarch64.S +++ b/cipher/chacha20-aarch64.S @@ -107,9 +107,6 @@ vpunpckhqdq(x2, t2, x3); \ vpunpcklqdq(x2, t2, x2); -#define clear(x) \ - movi x.16b, #0; - /********************************************************************** 4-way chacha20 **********************************************************************/ @@ -334,28 +331,28 @@ _gcry_chacha20_aarch64_blocks4: b.ne .Loop4; /* clear the used vector registers and stack */ - clear(VTMP0); - clear(VTMP1); - clear(VTMP2); - clear(VTMP3); - clear(X12_TMP); - clear(X13_TMP); - clear(X0); - clear(X1); - clear(X2); - clear(X3); - clear(X4); - clear(X5); - clear(X6); - clear(X7); - clear(X8); - clear(X9); - clear(X10); - clear(X11); - clear(X12); - clear(X13); - clear(X14); - clear(X15); + CLEAR_REG(VTMP0); + CLEAR_REG(VTMP1); + CLEAR_REG(VTMP2); + CLEAR_REG(VTMP3); + CLEAR_REG(X12_TMP); + CLEAR_REG(X13_TMP); + CLEAR_REG(X0); + CLEAR_REG(X1); + CLEAR_REG(X2); + CLEAR_REG(X3); + CLEAR_REG(X4); + CLEAR_REG(X5); + CLEAR_REG(X6); + CLEAR_REG(X7); + CLEAR_REG(X8); + CLEAR_REG(X9); + CLEAR_REG(X10); + CLEAR_REG(X11); + CLEAR_REG(X12); + CLEAR_REG(X13); + CLEAR_REG(X14); + CLEAR_REG(X15); eor x0, x0, x0 ret_spec_stop @@ -618,28 +615,28 @@ _gcry_chacha20_poly1305_aarch64_blocks4: POLY1305_STORE_STATE() /* clear the used vector registers and stack */ - clear(VTMP0); - clear(VTMP1); - clear(VTMP2); - clear(VTMP3); - clear(X12_TMP); - clear(X13_TMP); - clear(X0); - clear(X1); - clear(X2); - clear(X3); - clear(X4); - clear(X5); - clear(X6); - clear(X7); - clear(X8); - clear(X9); - clear(X10); - clear(X11); - clear(X12); - clear(X13); - clear(X14); - clear(X15); + CLEAR_REG(VTMP0); + CLEAR_REG(VTMP1); + CLEAR_REG(VTMP2); + CLEAR_REG(VTMP3); + CLEAR_REG(X12_TMP); + CLEAR_REG(X13_TMP); + CLEAR_REG(X0); + CLEAR_REG(X1); + CLEAR_REG(X2); + CLEAR_REG(X3); + CLEAR_REG(X4); + CLEAR_REG(X5); + CLEAR_REG(X6); + CLEAR_REG(X7); + CLEAR_REG(X8); + CLEAR_REG(X9); + CLEAR_REG(X10); + CLEAR_REG(X11); + CLEAR_REG(X12); + CLEAR_REG(X13); + CLEAR_REG(X14); + CLEAR_REG(X15); eor x0, x0, x0 POLY1305_POP_REGS() diff --git a/cipher/rijndael-armv8-aarch64-ce.S b/cipher/rijndael-armv8-aarch64-ce.S index 5152fab7..ffff766e 100644 --- a/cipher/rijndael-armv8-aarch64-ce.S +++ b/cipher/rijndael-armv8-aarch64-ce.S @@ -237,8 +237,6 @@ /* Other functional macros */ -#define CLEAR_REG(reg) movi reg.16b, #0; - #define aes_clear_keys(nrounds) \ CLEAR_REG(vk0); \ CLEAR_REG(vk1); \ diff --git a/cipher/sha1-armv8-aarch64-ce.S b/cipher/sha1-armv8-aarch64-ce.S index e309c08c..0eae3401 100644 --- a/cipher/sha1-armv8-aarch64-ce.S +++ b/cipher/sha1-armv8-aarch64-ce.S @@ -87,11 +87,6 @@ gcry_sha1_aarch64_ce_K_VEC: sha1su0_fn( v##w0, v##w1, v##w2 ); -/* Other functional macros */ - -#define CLEAR_REG(reg) movi reg.16b, #0; - - .text /* diff --git a/cipher/sha256-armv8-aarch64-ce.S b/cipher/sha256-armv8-aarch64-ce.S index 333e792d..bfe1c62c 100644 --- a/cipher/sha256-armv8-aarch64-ce.S +++ b/cipher/sha256-armv8-aarch64-ce.S @@ -97,11 +97,6 @@ gcry_sha256_aarch64_ce_K: su1_fn( v##w0, v##w2, v##w3 ); -/* Other functional macros */ - -#define CLEAR_REG(reg) movi reg.16b, #0; - - .text /* diff --git a/cipher/sha512-armv8-aarch64-ce.S b/cipher/sha512-armv8-aarch64-ce.S index fa225192..9be37a99 100644 --- a/cipher/sha512-armv8-aarch64-ce.S +++ b/cipher/sha512-armv8-aarch64-ce.S @@ -124,12 +124,6 @@ sha512h2 Q##gh, Q##cd, ab.2d; \ -/* Other functional macros */ - -#undef CLEAR_REG -#define CLEAR_REG(reg, ...) movi reg.16b, #0; - - /* * unsigned int * _gcry_sha512_transform_armv8_ce (u64 state[8], const void *input_data, diff --git a/cipher/sm3-aarch64.S b/cipher/sm3-aarch64.S index 7ef64666..9939c815 100644 --- a/cipher/sm3-aarch64.S +++ b/cipher/sm3-aarch64.S @@ -125,9 +125,6 @@ ELF(.size _gcry_sm3_aarch64_consts,.-_gcry_sm3_aarch64_consts) #define _(...) /*_*/ -#define clear_vec(x) \ - movi x.8h, #0; - #define rolw(o, a, n) \ ror o, a, #(32 - n); @@ -596,31 +593,31 @@ _gcry_sm3_transform_aarch64: /* Update the chaining variables. */ eor ra, ra, s0; - clear_vec(W0); + CLEAR_REG(W0); eor rb, rb, s1; - clear_vec(W1); + CLEAR_REG(W1); ldp s0, s1, [RSTATE, #16]; - clear_vec(W2); + CLEAR_REG(W2); eor rc, rc, s2; - clear_vec(W3); + CLEAR_REG(W3); ldp k_even, k_odd, [RSTATE, #24]; - clear_vec(W4); + CLEAR_REG(W4); eor rd, rd, s3; - clear_vec(W5); + CLEAR_REG(W5); eor re, re, s0; - clear_vec(XTMP0); + CLEAR_REG(XTMP0); stp ra, rb, [RSTATE, #0]; - clear_vec(XTMP1); + CLEAR_REG(XTMP1); eor rf, rf, s1; - clear_vec(XTMP2); + CLEAR_REG(XTMP2); stp rc, rd, [RSTATE, #8]; - clear_vec(XTMP3); + CLEAR_REG(XTMP3); eor rg, rg, k_even; - clear_vec(XTMP4); + CLEAR_REG(XTMP4); stp re, rf, [RSTATE, #16]; - clear_vec(XTMP5); + CLEAR_REG(XTMP5); eor rh, rh, k_odd; - clear_vec(XTMP6); + CLEAR_REG(XTMP6); stp rg, rh, [RSTATE, #24]; /* Clear message expansion area */ -- 2.53.0 From jussi.kivilinna at iki.fi Mon Sep 28 18:43:39 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 28 Sep 2026 19:43:39 +0300 Subject: [PATCH 2/3] build: set symbol underscore prefix for all Darwin hosts In-Reply-To: <20260928164340.3724227-1-jussi.kivilinna@iki.fi> References: <20260928164340.3724227-1-jussi.kivilinna@iki.fi> Message-ID: <20260928164340.3724227-2-jussi.kivilinna@iki.fi> * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Set underscore prefix for all Darwin hosts. -- Symbol underscore check is skipped when cross-compiling, so x86-64 and PowerPC macOS cross-builds were also missing the prefix. Signed-off-by: Jussi Kivilinna --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 1054d074..7b35bcb0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -73,7 +73,7 @@ case "${host}" in i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp) ac_cv_sys_symbol_underscore=yes ;; - aarch64-apple-darwin*) + *-apple-darwin*) ac_cv_sys_symbol_underscore=yes ;; *) -- 2.53.0