Thread View: gnu.gcc.bug
1 messages
1 total messages
Started by Andreas Schwab
Mon, 16 Nov 1992 12:42
GCC 2.3.1/m68k: incorrect output
Author: Andreas Schwab
Date: Mon, 16 Nov 1992 12:42
Date: Mon, 16 Nov 1992 12:42
277 lines
6964 bytes
6964 bytes
GCC 2.3.1/m68k (Atari ST) generates incorrect output for the file test.c
(see below), if compiled with
gcc -O2 -fomit-frame-pointer -m68000 -msoft-float -S test.c
(-m68000 and -msoft-float are not generally required to trigger the
bug; they only make the function more complex)
Here are the relevant parts of the output:
---------- test.s
#NO_APP
gcc2_compiled.:
.text
.even
_ston:
addw #-24,sp
moveml #0x3f3e,sp@-
movel sp@(72),a3
clrl sp@(60)
moveb #43,sp@(59) | char msign = '+';
moveb sp@(59),sp@(57) | char esign = '+';
| lines deleted
moveq #43,d7 | if (c == '+' || c == '-')
cmpl a2,d7
jeq L6
moveq #45,d7
cmpl a2,d7
jne L5
L6:
movew a2,sp@- | msign = c;
moveb sp@(1),sp@(59) | <---- should be sp@(61)
addqw #2,sp
moveb a3@+,d7 | c = *s++;
extw d7
movew d7,a0
movew a0,a2
| many lines deleted
moveq #101,d7 | if (c == 'e' || c == 'E')
cmpl a2,d7
jeq L23
moveq #69,d7
cmpl a2,d7
jne L22
L23:
addql #1,sp@(60) | realflag++;
moveb a3@+,d7 | c = *s++;
extw d7
movew d7,a0
movew a0,a2
moveq #43,d7 | if (c == '+' || c == '-')
cmpl a2,d7
jeq L25
moveq #45,d7
cmpl a2,d7
jne L24
L25:
movew a2,sp@- | esign = c;
moveb sp@(1),sp@(57) | <---- should be sp@(59)
addqw #2,sp
moveb a3@+,d7 | c = *s++;
extw d7
movew d7,a0
movew a0,a2
| rest deleted
----------
Here is the test file:
---------- test.c
double ldexp (double, int);
typedef int word;
typedef struct descrip *dptr;
struct descrip
{
word dword;
word integr;
};
int makereal (double r, dptr dp);
word bigradix (int sign, int r, char *s, dptr dx);
extern unsigned char *_ctype;
static int
ston (s, dp)
register char *s;
dptr dp;
{
register int c;
int realflag = 0;
char msign = '+';
char esign = '+';
double mantissa = 0;
long lresult = 0;
int scale = 0;
int digits = 0;
int sdigits = 0;
int exponent = 0;
double fiveto;
double power;
int err_no;
char *ssave;
c = *s++;
while ((_ctype[(unsigned char) (c)] & 0x10))
c = *s++;
if (c == '+' || c == '-')
{
msign = c;
c = *s++;
}
ssave = s - 1;
while ((_ctype[(unsigned char) (c)] & 0x02))
{
digits++;
if (mantissa < 9007199254740992.)
{
mantissa = mantissa * 10 + (c - '0');
lresult = lresult * 10 + (c - '0');
if (mantissa > 0.0)
sdigits++;
}
else
scale++;
c = *s++;
}
if (c == 'r' || c == 'R')
return bigradix (msign, (int) mantissa, s, dp);
if (c == '.')
{
realflag++;
c = *s++;
while ((_ctype[(unsigned char) (c)] & 0x02))
{
digits++;
if (mantissa < 9007199254740992.)
{
mantissa = mantissa * 10 + (c - '0');
lresult = lresult * 10 + (c - '0');
scale--;
if (mantissa > 0.0)
sdigits++;
}
c = *s++;
}
}
if (digits == 0)
return -2;
if (c == 'e' || c == 'E')
{
realflag++;
c = *s++;
if (c == '+' || c == '-')
{
esign = c;
c = *s++;
}
if (!(_ctype[(unsigned char) (c)] & 0x02))
return -2;
while ((_ctype[(unsigned char) (c)] & 0x02))
{
exponent = exponent * 10 + (c - '0');
c = *s++;
}
scale += (esign == '+') ? exponent : -exponent;
}
while ((_ctype[(unsigned char) (c)] & 0x10))
c = *s++;
if (c != '\0')
return -2;
if (!realflag && !scale && mantissa >= ((long int) 020000000000L)
&& mantissa <= ((long int) 017777777777L))
{
dp->dword = (word) (1 | 0x80000000);
dp->integr = (msign == '+' ? lresult : -lresult);
return 1;
}
if (!realflag)
return bigradix (msign, 10, ssave, dp);
if (!realflag)
return -2;
if (sdigits + scale > 309)
return -2;
if (sdigits + scale < -309)
{
makereal (0.0, dp);
return 3;
}
exponent = (scale > 0) ? scale : -scale;
fiveto = 1.0;
power = 5.0;
for (;;)
{
if (exponent & 01)
fiveto *= power;
exponent >>= 1;
if (exponent == 0)
break;
power *= power;
}
if (scale > 0)
mantissa *= fiveto;
else
mantissa /= fiveto;
err_no = 0;
mantissa = ldexp (mantissa, scale);
if (err_no > 0 && mantissa > 0)
return -2;
if (msign == '-')
mantissa = -mantissa;
makereal (mantissa, dp);
return 3;
}
----------
This patch tries to correct the bug.
--- m68k.md~ Fri Nov 13 22:16:12 1992
+++ m68k.md Sun Nov 15 18:01:18 1992
@@ -921,7 +921,15 @@
&& GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
&& XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
{
- xoperands[1] = operands[1];
+ if (GET_CODE (operands[1]) == MEM
+ && (XEXP (operands[1], 0) == stack_pointer_rtx
+ || (GET_CODE (XEXP (operands[1], 0)) == PLUS
+ && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx)))
+ xoperands[1]
+ = gen_rtx (MEM, GET_MODE (operands[1]),
+ plus_constant (XEXP (operands[1], 0), 2));
+ else
+ xoperands[1] = operands[1];
xoperands[2]
= gen_rtx (MEM, QImode,
gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
@@ -934,7 +942,14 @@
if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
{
- xoperands[1] = operands[1];
+ if (XEXP (operands[1], 0) == stack_pointer_rtx
+ || (GET_CODE (XEXP (operands[1], 0)) == PLUS
+ && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx))
+ xoperands[1]
+ = gen_rtx (MEM, GET_MODE (operands[1]),
+ plus_constant (XEXP (operands[1], 0), 2));
+ else
+ xoperands[1] = operands[1];
xoperands[2]
= gen_rtx (MEM, QImode,
gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
@@ -946,7 +961,14 @@
}
if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
{
- xoperands[0] = operands[0];
+ if (XEXP (operands[0], 0) == stack_pointer_rtx
+ || (GET_CODE (XEXP (operands[0], 0)) == PLUS
+ && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx))
+ xoperands[0]
+ = gen_rtx (MEM, GET_MODE (operands[0]),
+ plus_constant (XEXP (operands[0], 0), 2));
+ else
+ xoperands[0] = operands[0];
xoperands[1] = operands[1];
xoperands[2]
= gen_rtx (MEM, QImode,
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads