This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: unsigned int multiply, x86-64
- From: Andrew Haley <aph at redhat dot com>
- To: Bob Plantz <plantz at cds1 dot net>
- Cc: gcc-help <gcc-help at gcc dot gnu dot org>
- Date: Tue, 15 Apr 2008 18:10:35 +0100
- Subject: Re: unsigned int multiply, x86-64
- References: <1208279125.6327.7.camel@localhost>
Bob Plantz wrote:
> I wrote some C code to multiply two unsigned (32-bit) ints and store the
> result in a 64-bit unsigned int.
>
> int main(void)
> {
> unsigned int x, y;
> unsigned long int z;
>
> printf("Enter two integers: ");
> scanf("%u %u", &x, &y);
>
> z = (long int)(x * y);
>
> printf("%u * %u = %lu\n", x , y, z);
>
> exit(0);
> }
>
> For the multiply, gcc produces (with -O0):
> movl -4(%rbp), %edx
> movl -8(%rbp), %eax
> imull %edx, %eax
> mov %eax, %eax
> movq %rax, -16(%rbp)
>
> First, it uses signed multiply (imull). Second, it only keeps the
> low-order 32 bits of the result.
>
> I would do something like:
> movl -4(%rbp), %edx
> movl -8(%rbp), %eax # zeros high-order 32 bits
> mull %edx # 64-bit result in edx:eax
> shlq $32, %rdx # shift to high-order
> addq %rdx, %rax # combine into 64-bit result
> movq %rax, -16(%rbp)
>
> Am I missing something here?
Knowledge of C, I think.
try
z = (long int)x * y;
Andrew.