Boon said:
*What* is a joke? *What* is completely unusable?
(There is no room for hand-waving in a technical forum.)
How does your implementation check for signed overflow on multiplication?
lcc-win generates for the "mymult" function this code:
; 1 int mymul(int a)
.data
mymul__labelname:
; "mymul\x0"
.byte 109,121,109,117,108,0
.text
_mymul:
; 2 {
; 3 return a*2;
imul $2,4(%esp),%eax
jno _$L2
pusha
pushl $3
pushl $mymul__labelname
call __overflow
addl $8,%esp
popa
_$L2:
; 4 }
ret
In the normal case the (no overflow) the only cost to the user is
a mispredicted forward branch, i.e. 1 instruction.
The cost for gcc is:
(1) Push the arguments (2 instructions)
(2) Make a call (1 instruction)
(3) Adjust the stack (1 instruction)
The "mulvsi3" function is even worst. Since it is a machine independent
function it tests for overflow by checking the result instead of using
the overflow flag. In 64 bit linux is 11 instructions!
So we have for gcc a total cost of 11+1+1+2-->15 instructions.
Note that under lcc-win you can define a function called _overflow()
that will replace the library function with your own function that can
take *other* measures than just aborting the program. It will receive
2 arguments:
o the file name and
o the line number
where the overflow occurred.
You can call abort() in your function, or make a longjmp somewhere,
or ignore the overflow and return.
Gcc will always call abort() without any hint as to *where* in your code
the overflow occurred, so that you have no clue as to what went wrong.
Imagine the pleasure of getting a call from your client:
"Your program aborted without warning! I lost all I was doing you
stupid!"
And you have no clue as to what caused the abort() call!
jacob