Fuzix-Compiler-Kit
Fuzix-Compiler-Kit copied to clipboard
be-code-6800.c: gen_fast_div() does not calculate correct value when dividend is negative
The following program returns -1 and 0. 0 is correct. Division always truncates toward 0 (C99). But shifting truncates toward negative infinity, so the values may differ for negative numbers.
Before the right shift (ASRA/RORB), the program must pre-add the remainder that will be truncated. This issue may occur on other architectures as well.
/*
* Signed integer divide by 2
*/
void
print(int a)
{
char *d = (char *)(0xFEFC);
d[0] = a>>8;
d[1] = a&0xff;
}
static unsigned x = 12;
int main(int argc, char *argv[])
{
int a=-1;
int b=2;
print(a/2);
print(a/b);
return 0;
}
--- be-code-6800.c.old 2024-10-11 01:47:18
+++ be-code-6800.c 2024-10-11 01:45:50
@@ -1058,6 +1058,8 @@
unsigned gen_fast_div(unsigned n, unsigned s, unsigned u)
{
+ int m = n-1;
+
u &= UNSIGNED;
if (s != 2)
return 0;
@@ -1076,6 +1078,8 @@
n >>= 1;
}
} else {
+ printf("\taddb #%u\n", m & 0xFF);
+ printf("\tadca #%u\n", m >> 8);
while(n > 1) {
printf("\tasra\n\trorb\n");
n >>= 1;