I've got this program in MIPS assembly which comes from a C code that does the simple average of the eigth arguments of the function.
average8:
addu $4,$4,$5
addu $4,$4,$6
addu $4,$4,$7
lw $2,16($sp)
#nop
addu $4,$4,$2
lw $2,20($sp)
#nop
addu $4,$4,$2
lw $2,24($sp)
#nop
addu $4,$4,$2
lw $2,28($sp)
#nop
addu $2,$4,$2
bgez $2,$L2
addu $2,$2,7
$L2:
sra $2,$2,3
j $31
When the number is positve, we directly divided by 8 (shift by 3 bits), but when the number is negative, we first addu 7
then do the division.
My question is why do we add 7
to $2
when $2 is not >= 0
?
EDIT : Here is the C code :
int average8(int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8)
{
return (x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8) / 8;
}
note : the possible loss in the division since we are using ints instead of floats or doubles is not important in this case.
The difference appears to be accounting for the different behaviors of / 8
and >> 3
when negative numbers are involved:
int main() {
printf("%d\n", (-50) / 8);
printf("%d\n", (-50) >> 3);
printf("%d\n", (-50 + 7) >> 3);
}
gives
-6
-7
-6
So, the compiler wants to use the >> 3
optimization, but it's not exactly the same as / 8
, so it adds some code to correct for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With