Why does the code add 7 if the number is not> = 0

I have this program in the MIPS assembly that comes from C code that executes a simple middle of the arguments of an eigth 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 positive, we divide by 8 (shift by 3 bits), but when the number is negative, first addu 7 performs 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: a possible loss in division, since we use ints instead of float or double, is not important in this case.

+6
source share
2 answers

The difference seems to account for different types of behavior / 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 optimization >> 3 , but this is not the same as / 8 , so it adds some code to fix it.

+10
source

After Owen saw the answer, adding to his answer, this explains the difference at the binary level:

The rounding issue happens at the binary level:

 50; // 0011 0010 50 >> 3 // 0000 0110 which is 6 -50; // 1100 1110 -50 >> 3; // 1111 1001 -> which is -7 

Thus, to fix the problem, we must have 2E (rightShift -1) for the number to fix the rounding problem.

 -50 + 7; // 1101 0101 -43 >> 3; // 1111 1010 -> which is -6 (and this is what was expected) 

But what if the number can be divided by 8? Well, there will be no problems!

 -32; // 1110 0000 -32 >> 3; // 1111 1100 -> which is -4 (that already the good answer) -32+7; // 1110 0111 -25 >> 3; // 1111 1100 -> which is still -4. 

Please note that adding 7 to the answer, when the number can be divided by 8, does not change any of the 3 LSBs, so the right logical shift 3 remains unchanged.

0
source

Source: https://habr.com/ru/post/924401/


All Articles