#include "stdlib.h"
// this is an useful operation, it's a safe
// unsigned product with overflow-safety test
unsigned int mul(unsigned int a, unsigned int b) {
if ((unsigned long long)a * b > 0xffffffff)
exit(1);
return a * b;
}
/*
Args used to compile with gcc and llvm-gcc:
-Wall -O3 -fomit-frame-pointer -msse3 -march=native -S
On Windows
gcc: version 4.3.3-dw2-tdm-1 (GCC)
llvm-gcc: gcc version 4.2.1 (Based on Apple Inc. build 5636) (LLVM build)
----------------------------------
This is how the same thing may be done:
mov %esi, %eax
mul %edi
jo .L1
ret
----------------------------------
GCC:
_mul:
subl $28, %esp
movl %ebx, 16(%esp)
movl 36(%esp), %ecx
movl 32(%esp), %ebx
movl %ecx, %eax
movl %esi, 20(%esp)
mull %ebx
movl %edi, 24(%esp)
cmpl $0, %edx
ja L5
imull %ebx, %ecx
movl 20(%esp), %esi
movl %ecx, %eax
movl 16(%esp), %ebx
movl 24(%esp), %edi
addl $28, %esp
ret
L5:
movl $1, (%esp)
call _exit
-----------------------
LLVM-GCC:
_mul:
pushl %esi
subl $8, %esp
movl 20(%esp), %ecx
movl 16(%esp), %esi
movl %ecx, %eax
mull %esi
testl %edx, %edx
jne LBB1_2 # bb
LBB1_1: # bb1
movl %ecx, %eax
imull %esi, %eax
addl $8, %esp
popl %esi
ret
LBB1_2: # bb
movl $1, (%esp)
call _exit
*/