home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.gcc.bug
- Path: sparky!uunet!convex!linac!pacific.mps.ohio-state.edu!cis.ohio-state.edu!lamothe.informatik.uni-dortmund.de!schwab
- From: schwab@lamothe.informatik.uni-dortmund.de (Andreas Schwab)
- Subject: GCC 2.3.1/m68k: incorrect output
- Message-ID: <9211161042.AA11690@lamothe.informatik.uni-dortmund.de>
- Sender: gnulists@ai.mit.edu
- Reply-To: schwab@ls5.informatik.uni-dortmund.de (Andreas Schwab)
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Mon, 16 Nov 1992 12:42:11 GMT
- Approved: bug-gcc@prep.ai.mit.edu
- Lines: 278
-
- 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,
-
-