mul -- unsigned multiply.
I want to convert the following into C++
mov eax, bufdata
mul factor
add eax, tableval
adc edx, 0x0
mov bufdata, eax
mov tableval, edx
Yet everytime I try the compiler generates an imul (signed multiply) instruction even though both the operands are unsigned. eg. This will generate an imul (using cl)
unsigned bufdata = pbuf[buflen - i - 1];
unsigned __int64 result = bufdata * factor + tableval;
tableval = ( result >> 32 );
pbuf[buflen - i - 1] = result & 0xffffffff;
I don't understand why it is doing this.
Maybe 'unsigned __int64' is confusing cl (since int64 is an MSVC extension). Try using unsigned long long (under gcc). The following code produces a 64bit mull for me:
extern unsigned pbuf[];
unsigned tableval, factor;
typedef unsigned long long uint64_t;
int m(int a, char **b) {
(void)(a&&b);
unsigned bufdata = pbuf[0];
unsigned long long result = ((uint64_t)bufdata) * ((uint64_t)factor) + ((uint64_t)tableval);
tableval = ( result >> 32 );
pbuf[1] = result & 0xffffffff;
return 0;
}
Produces:_m:
movl _factor, %ecx
movl _pbuf, %eax
pushl %ebx
mull %ecx
movl %eax, %ecx
movl %edx, %ebx
movl _tableval, %eax
xorl %edx, %edx
addl %eax, %ecx
adcl %edx, %ebx
movl %ecx, _pbuf+4
xorl %eax, %eax
movl %ebx, _tableval
popl %ebx
ret
Quote from: Eibro[yL] on November 17, 2004, 10:19 PM
mul -- unsigned multiply.
I want to convert the following into C++
mov eax, bufdata
mul factor
add eax, tableval
adc edx, 0x0
mov bufdata, eax
mov tableval, edx
Yet everytime I try the compiler generates an imul (signed multiply) instruction even though both the operands are unsigned. eg. This will generate an imul (using cl)
unsigned bufdata = pbuf[buflen - i - 1];
unsigned __int64 result = bufdata * factor + tableval;
tableval = ( result >> 32 );
pbuf[buflen - i - 1] = result & 0xffffffff;
I don't understand why it is doing this.
Try casting the * operands to 64-bit numbers.
Quote from: Skywing on November 17, 2004, 11:55 PM
Quote from: Eibro[yL] on November 17, 2004, 10:19 PM
mul -- unsigned multiply.
I want to convert the following into C++
mov eax, bufdata
mul factor
add eax, tableval
adc edx, 0x0
mov bufdata, eax
mov tableval, edx
Yet everytime I try the compiler generates an imul (signed multiply) instruction even though both the operands are unsigned. eg. This will generate an imul (using cl)
unsigned bufdata = pbuf[buflen - i - 1];
unsigned __int64 result = bufdata * factor + tableval;
tableval = ( result >> 32 );
pbuf[buflen - i - 1] = result & 0xffffffff;
I don't understand why it is doing this.
Try casting the * operands to 64-bit numbers.
Yep. That did it.
Thanks Skywing & Kp.
Quote from: Kp on November 17, 2004, 11:02 PM
Maybe 'unsigned __int64' is confusing cl (since int64 is an MSVC extension). Try using unsigned long long (under gcc). The following code produces a 64bit mull for me:
extern unsigned pbuf[];
unsigned tableval, factor;
typedef unsigned long long uint64_t;
int m(int a, char **b) {
(void)(a&&b);
unsigned bufdata = pbuf[0];
unsigned long long result = ((uint64_t)bufdata) * ((uint64_t)factor) + ((uint64_t)tableval);
tableval = ( result >> 32 );
pbuf[1] = result & 0xffffffff;
return 0;
}
Produces:_m:
movl _factor, %ecx
movl _pbuf, %eax
pushl %ebx
mull %ecx
movl %eax, %ecx
movl %edx, %ebx
movl _tableval, %eax
xorl %edx, %edx
addl %eax, %ecx
adcl %edx, %ebx
movl %ecx, _pbuf+4
xorl %eax, %eax
movl %ebx, _tableval
popl %ebx
ret
Hmm it doesn't seem as if cl was confused (unless gcc is too). gcc emitted the same imul if the operands were 32 bits wide.
For future reference, you might want to compare the code generated by the compiler there and the UInt32x32To64 macro.
Quote from: Eibro[yL] on November 18, 2004, 06:37 AMHmm it doesn't seem as if cl was confused (unless gcc is too). gcc emitted the same imul if the operands were 32 bits wide.
What C code did you feed to gcc? Your MSVC code won't work verbatim due to the difference over what to name a 64bit number.
Quote from: Kp on November 19, 2004, 06:26 PM
Quote from: Eibro[yL] on November 18, 2004, 06:37 AMHmm it doesn't seem as if cl was confused (unless gcc is too). gcc emitted the same imul if the operands were 32 bits wide.
What C code did you feed to gcc? Your MSVC code won't work verbatim due to the difference over what to name a 64bit number.
The code you posted, less the casting.