Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention

From: Peter Zijlstra
Date: Thu May 12 2016 - 08:15:39 EST


On Thu, May 12, 2016 at 01:57:38PM +0200, Borislav Petkov wrote:
> #ifdef CONFIG_X86_32
> # define PUSH_DX "pushl %%edx\n\t"
> # define POP_DX "popl %%edx\n\t"
> #else
> # define PUSH_DX "pushq %%rdx\n\t"
> # define POP_DX "popq %%rdx\n\t"
> #endif
>
> unsigned int __sw_hweight32(unsigned int w)
> {
> asm volatile(PUSH_DX
> "movl %[w], %%edx\n\t" /* w -> t */
> "shrl %%edx\n\t" /* t >> 1 */
> "andl $0x55555555, %%edx\n\t" /* t & 0x55555555 */
> "subl %%edx, %[w]\n" /* w -= t */
> "\n\t"
> "movl %[w], %%edx\n\t" /* w -> t */
> "shrl $2, %[w]\n\t" /* w_tmp >> 2 */
> "andl $0x33333333, %%edx\n\t" /* t & 0x33333333 */
> "andl $0x33333333, %[w]\n\t" /* w_tmp & 0x33333333 */
> "addl %%edx, %[w]\n" /* w = w_tmp + t */
> "\n\t"
> "movl %[w], %%edx\n\t" /* w -> t */
> "shrl $4, %%edx\n\t" /* t >> 4 */
> "addl %%edx, %[w]\n\t" /* w_tmp += t */
> "andl $0x0f0f0f0f, %[w]\n\t" /* w_tmp &= 0x0f0f0f0f */
> "imull $0x01010101, %[w], %[w]\n\t" /* w_tmp *= 0x01010101 */
> "shrl $24, %[w]\n\t" /* w = w_tmp >> 24 */
> POP_DX
> : [w] "+r" (w));
>
> return w;
> }

But this is a C function, with C calling convention. You're now assuming
GCC doesn't clobber anything with its prologue/epilogue.

I think hpa meant to put it in an .S file and avoid all that.