Author | Message | Time |
---|---|---|
Eibro | mul -- unsigned multiply. I want to convert the following into C++ [code]mov eax, bufdata mul factor add eax, tableval adc edx, 0x0 mov bufdata, eax mov tableval, edx[/code] 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) [code] unsigned bufdata = pbuf[buflen - i - 1]; unsigned __int64 result = bufdata * factor + tableval; tableval = ( result >> 32 ); pbuf[buflen - i - 1] = result & 0xffffffff;[/code]I don't understand why it is doing this. | November 18, 2004, 4:19 AM |
Kp | 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: [code]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; } [/code] Produces:[code]_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[/code] | November 18, 2004, 5:02 AM |
Skywing | [quote author=Eibro[yL] link=topic=9594.msg89212#msg89212 date=1100751583] mul -- unsigned multiply. I want to convert the following into C++ [code]mov eax, bufdata mul factor add eax, tableval adc edx, 0x0 mov bufdata, eax mov tableval, edx[/code] 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) [code] unsigned bufdata = pbuf[buflen - i - 1]; unsigned __int64 result = bufdata * factor + tableval; tableval = ( result >> 32 ); pbuf[buflen - i - 1] = result & 0xffffffff;[/code]I don't understand why it is doing this. [/quote] Try casting the * operands to 64-bit numbers. | November 18, 2004, 5:55 AM |
Eibro | [quote author=Skywing link=topic=9594.msg89225#msg89225 date=1100757314] [quote author=Eibro[yL] link=topic=9594.msg89212#msg89212 date=1100751583] mul -- unsigned multiply. I want to convert the following into C++ [code]mov eax, bufdata mul factor add eax, tableval adc edx, 0x0 mov bufdata, eax mov tableval, edx[/code] 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) [code] unsigned bufdata = pbuf[buflen - i - 1]; unsigned __int64 result = bufdata * factor + tableval; tableval = ( result >> 32 ); pbuf[buflen - i - 1] = result & 0xffffffff;[/code]I don't understand why it is doing this. [/quote] Try casting the * operands to 64-bit numbers. [/quote]Yep. That did it. Thanks Skywing & Kp. | November 18, 2004, 12:13 PM |
Eibro | [quote author=Kp link=topic=9594.msg89221#msg89221 date=1100754158] 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: [code]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; } [/code] Produces:[code]_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[/code] [/quote]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. | November 18, 2004, 12:37 PM |
Skywing | For future reference, you might want to compare the code generated by the compiler there and the UInt32x32To64 macro. | November 18, 2004, 7:00 PM |
Kp | [quote author=Eibro[yL] link=topic=9594.msg89235#msg89235 date=1100781421]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.[/quote] 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. | November 20, 2004, 12:26 AM |
Eibro | [quote author=Kp link=topic=9594.msg89426#msg89426 date=1100910373] [quote author=Eibro[yL] link=topic=9594.msg89235#msg89235 date=1100781421]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.[/quote] 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]The code you posted, less the casting. | November 20, 2004, 4:27 AM |