Article View: gnu.gcc.bug
Article #1341gcc-2.3.1 -mno-fp-ret-in-387
From: Bruce Evans
Date: Tue, 10 Nov 1992 06:53
Date: Tue, 10 Nov 1992 06:53
292 lines
9697 bytes
9697 bytes
gcc-2.3.1 dumped core while compiling the library function __fixunsdfdi ()
under Minix-386. This was because the new support for no-fp-ret-in-387
doesn't quite work.
This is a reduced form of the input file showing the bug:
---
fixu.c
---
typedef int SItype;
typedef unsigned int USItype;
typedef long long DItype;
typedef unsigned long long UDItype;
typedef double DFtype;
DItype
__fixunsdfdi (a)
DFtype a;
{
DFtype b;
UDItype v;
if (a < 0)
return 0;
b = (a / (((UDItype) 1) << (sizeof (SItype) * 8 ) ) );
v = (USItype) b;
v <<= (sizeof (SItype) * 8 ) ;
a -= (DFtype)v;
if (a < 0)
v -= (USItype) (- a);
else
v += (USItype) a;
return v;
}
---
This is the error output from
gcc -mno-80387 -mno-ieee-fp -mno-fp-ret-in-387 -O -S -v fixu.c
The -m flags are here to show my nonstandard defaults.
---
Reading specs from /usr/gnu/gcc/lib/gcc-lib/i386-minix/2.3.1/specs
gcc version 2.3.1
/usr/gnu/gcc/lib/gcc-lib/i386-minix/2.3.1/cpp -lang-c -v -undef -D__GNUC__=2 -D__OPTIMIZE__ fixu.c /usr/tmp/cca07941.i
GNU CPP version 2.3.1 (80386, BSD syntax)
/usr/gnu/gcc/lib/gcc-lib/i386-minix/2.3.1/cc1 /usr/tmp/cca07941.i -quiet -dumpbase fixu.c -mno-80387 -mno-ieee-fp -mno-fp-ret-in-387 -O -version -o fixu.s
GNU C version 2.3.1 (80386, BSD syntax) compiled by GNU C version 2.3.1.
[Abort]
---
The abort is from this code around line 1172 in reload1.c.
---
/* Crash if two dissimilar machine modes both need
groups of consecutive regs of the same class. */
if (other_mode != VOIDmode
&& other_mode != allocate_mode
&& ! modes_equiv_for_class_p (allocate_mode,
other_mode,
class))
abort ();
}
---
gdb says that
other_mode = DImode
allocate_mode = DFmode
class = GENERAL_REGS
---
Here is a possible fix. I've been using variants of it in gcc-1.38 to
1.40 and gcc-2.2.x. 387 registers are not OK if there are no 387 registers.
However, there's something wrong with either the fix or the documentation.
tm.texi says that it is not necessary for HARD_REGNO_MODE_OK() to check
for the numbers of fixed registers, and the -mno-80387 -mno-fp-ret-in-387
flags are supposed to hide all 387 registers by making them fixed.
---
*** orig/i386.h Sat Nov 7 22:15:57 1992
--- i386.h Sun Nov 8 04:20:04 1992
***************
*** 284,287 ****
--- 284,296 ----
: (MODE) != QImode)
+ #undef HARD_REGNO_MODE_OK(REGNO, MODE)
+ #define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ ((REGNO) < 4 ? 1 \
+ : (REGNO) >= 8 ? ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
+ && TARGET_80387 \
+ && GET_MODE_UNIT_SIZE (MODE) <= 8) \
+ : (MODE) != QImode)
+
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
---
config/i386sco.h and config/seq386.h contain old no-387 code can now be
done better using by the new 387 target flags. I don't think the old code
is complete enough to actually work. It is #ifdef'ed out in i386sco.h.
---
CONST_DOUBLE_OK_FOR_LETTER_P() seems to have the opposite problem to
HARD_REGNO_MODE_OK(). The document doesn't say anything about whether
it should check letters that "can't happen", but the letter never seems
to be a 387-related letter in practice. I used to use the following
redefinition.
***************
*** 507,510 ****
--- 516,527 ----
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'G' ? standard_80387_constant_p (VALUE) : 0)
+
+ #if 0
+ /* Also change above comment. */
+ #undef CONST_DOUBLE_OK_FOR_LETTER_P
+ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'G' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387)
+ && standard_80387_constant_p (VALUE) : 0)
+ #endif
/* Place additional restrictions on the register class to use when it
---
Here are my local changes to gcc. Please put the Minix support in gcc.
Makefile.in:
enquire needs -lm, and ENQUIRE_LDFLAGS is in the wrong order to
put it. Add macro ENQUIRE_LIBS.
c-typeck.c:
In the format checker, ignoring differences in signedness is not
done very well. The difference between integral types was also
ignored if the types happen to have the same size on the target
machine. I would like to have a new -W flag to control error
reports about type mismatches that only matter on some targets.
Signedness differences are usually bugs but old code has too many
of them to warn about them by default. Many of the signedness
warnings that my change produced were due to sizeof being unsigned.
Perhaps the checker could easily ignore the unsignedness for this
case.
configure:
config/i386minix.h
config/x-i386minix
config/xm-i386min.h
Support Minix.
There is nothing special except the change to TARGET_FLAGS to get
soft-float. Hard-float works too, but only on my system.
It's annoying to have to define USG and then take countermeasures
against it.
---
diff -rc2 orig/Makefile.in ./Makefile.in
*** orig/Makefile.in Sat Nov 7 22:14:02 1992
--- ./Makefile.in Sun Nov 8 00:54:09 1992
***************
*** 102,105 ****
--- 102,106 ----
ENQUIRE_CFLAGS = -DNO_MEM -DNO_STDDEF -DNO_LONG_DOUBLE_IO -O0
ENQUIRE_LDFLAGS = $(LDFLAGS)
+ ENQUIRE_LIBS =
# Tools to use when building a cross-compiler.
***************
*** 507,511 ****
# Let's try with GCC.
enquire: enquire.o $(GCC_PARTS)
! $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(ENQUIRE_LDFLAGS) enquire.o -o $@
enquire.o: $(srcdir)/enquire.c $(GCC_PASSES)
# -if [ "$(srcdir)" != "." ]; then rm -f ./enquire.c; else true; fi
--- 508,513 ----
# Let's try with GCC.
enquire: enquire.o $(GCC_PARTS)
! $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(ENQUIRE_LDFLAGS) enquire.o -o $@ \
! $(ENQUIRE_LIBS)
enquire.o: $(srcdir)/enquire.c $(GCC_PASSES)
# -if [ "$(srcdir)" != "." ]; then rm -f ./enquire.c; else true; fi
diff -rc2 orig/c-typeck.c ./c-typeck.c
*** orig/c-typeck.c Sat Nov 7 22:14:19 1992
--- ./c-typeck.c Mon Nov 9 11:56:50 1992
***************
*** 1729,1732 ****
--- 1729,1733 ----
&& ! (wanted_type == void_type_node
&& fci->pointer_count > 0)
+ #if 0
/* Don't warn about differences merely in signedness. */
&& !(TREE_CODE (wanted_type) == INTEGER_TYPE
***************
*** 1733,1736 ****
--- 1734,1740 ----
&& TREE_CODE (cur_type) == INTEGER_TYPE
&& TYPE_PRECISION (wanted_type) == TYPE_PRECISION (cur_type)))
+ #else
+ )
+ #endif
{
register char *this;
diff -rc2 orig/configure ./configure
*** orig/configure Sat Nov 7 22:17:14 1992
--- ./configure Sun Nov 8 00:59:56 1992
***************
*** 375,378 ****
--- 375,385 ----
use_collect2=yes
;;
+ i[3-4]86-*-minix*) # Intel 80386's running Minix
+ cpu_type=i386
+ xm_file=xm-i386min.h
+ xmake_file=x-i386minix
+ tm_file=i386minix.h
+ broken_install=yes
+ ;;
i[34]86-*-linux*) # Intel 80386's running Linux
cpu_type=i386
diff -rc2 null/i386minix.h config/i386minix.h
*** null/i386minix.h Tue Nov 10 15:25:19 1992
--- config/i386minix.h Mon Nov 9 12:31:37 1992
***************
*** 0 ****
--- 1,28 ----
+ /* Definitions for Intel 386 running Minix
+ * Copyright (C) 1988 Free Software Foundation, Inc.
+ */
+
+ /* This is tested by i386gas.h. */
+ #define YES_UNDERSCORES
+
+ #include "i386gstabs.h"
+
+ #undef CPP_PREDEFINES
+ #define CPP_PREDEFINES "" /* no -Dunix -Di386 */
+
+ #undef TARGET_DEFAULT
+ #define TARGET_DEFAULT 0 /* no 80387, no ieee-fp, no fp-ret-in-387 */
+
+ #define HAVE_ATEXIT
+
+ #undef SIZE_TYPE
+ #define SIZE_TYPE "unsigned int"
+
+ #undef PTRDIFF_TYPE
+ #define PTRDIFF_TYPE "int"
+
+ #undef WCHAR_TYPE
+ #define WCHAR_TYPE "char"
+
+ #undef WCHAR_TYPE_SIZE
+ #define WCHAR_TYPE_SIZE BITS_PER_UNIT
diff -rc2 null/x-i386minix config/x-i386minix
*** null/x-i386minix Tue Nov 10 15:25:19 1992
--- config/x-i386minix Mon Nov 9 12:35:53 1992
***************
*** 0 ****
--- 1,6 ----
+ CC = gcc
+ CCLIBFLAGS = -O -G
+ CLIB = -lm
+ ENQUIRE_LIBS = -lm
+ LANGUAGES = c proto
+ X_CFLAGS = -O -D_MINIX -D_POSIX_SOURCE -D_POSIX_1_SOURCE=2
diff -rc2 null/xm-i386min.h config/xm-i386min.h
*** null/xm-i386min.h Tue Nov 10 15:25:19 1992
--- config/xm-i386min.h Mon Nov 9 12:42:39 1992
***************
*** 0 ****
--- 1,23 ----
+ /* Configuration for GCC for Intel i386 running Minix 1.6.16++. */
+
+ #include "xm-i386.h"
+
+ /* Minix isn't USG, but it isn't BSD either, and gcc treats !USG as BSD. */
+
+ #define USG
+
+ /* Defining USG causes various braindamage. Some of it can be avoided: */
+
+ /* Stop cccp.c from providing slow versions of bcopy () etc. */
+
+ #define BSTRING
+
+ /* USG forces the use of gstab.h, but prepare for when USG is not defined. */
+
+ #define NO_STAB_H
+
+ /* gcc uses the ancient sys_errlist[] and sys_nerr instead of the ANSI
+ strerror(). */
+
+ #define sys_errlist _sys_errlist
+ #define sys_nerr _sys_nerr
--
--
Bruce Evans (bde@runx.oz.au)
Technical Details
Message-ID:
<1992Nov10.065333.19564@runx.oz.au>Path:
arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!ames!saimiri.primate.wisc.edu!caen!uwm.edu!linac!pacific.mps.ohio-state.edu!cis.ohio-state.edu!runx.oz.AU!bdeShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!ames!saimiri.primate.wisc.edu!caen!uwm.edu!linac!pacific.mps.ohio-state.edu!cis.ohio-state.edu!runx.oz.AU!bde From: bde@runx.oz.AU (Bruce Evans) Subject: gcc-2.3.1 -mno-fp-ret-in-387 Message-ID: <1992Nov10.065333.19564@runx.oz.au> Sender: gnulists@ai.mit.edu Organization: RUNX Un*x Timeshare. Sydney, Australia. Distribution: gnu Date: Tue, 10 Nov 1992 06:53:33 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 293