This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: MIPS patch: allow ints in FPRs, rework some float patterns
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: echristo at redhat dot com
- Date: 22 Jul 2002 09:54:26 +0100
- Subject: Re: MIPS patch: allow ints in FPRs, rework some float patterns
- References: <wvn3cutghms.fsf@talisman.cambridge.redhat.com>
Richard Sandiford <rsandifo@redhat.com> writes:
> Patch tested by bootstrapping on mips-sgi-irix6.5, and on a customised
> mipsisa32-elf build, with -mhard-float the default, and with EABI
> multlibs. Test pattern was {-mabi=eabi}{-mips32,-mips64}{-EL,-EB}.
Unfortunately, I didn't customise the thing properly, so that test
pattern ended up testing the soft-float multilibs. The patch was also
tested on mips64-elf, but 32-bit targets weren't tested like I thought.
The upshot being that the patch caused a miscompilation of libm in
32-bit mode. The lowest-numbered register in a float pair always holds
the low word, so (subreg:SI (reg:DI $f0) 0) will get the wrong word on a
big endian target. Kind of like the reverse of the HI_REGS situation on
little-endian targets.
Sorry for the screw-up. Will just stick to stock targets from now on.
Patch tested on mips-elf and mips64-elf (in both cases using
{-EL,-EB}{-msoft-float,-mhard-float}). OK to install?
Richard
* config/mips/mips.h (CLASS_CANNOT_CHANGE_MODE): Include FP_REGS
on big-endian targets.
Index: config/mips/mips.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v
retrieving revision 1.200
diff -c -p -d -r1.200 mips.h
*** config/mips/mips.h 17 Jul 2002 21:31:39 -0000 1.200
--- config/mips/mips.h 20 Jul 2002 10:48:24 -0000
*************** extern enum reg_class mips_char_to_class
*** 2249,2262 ****
so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low
word as intended.
Also, loading a 32-bit value into a 64-bit floating-point register
will not sign-extend the value, despite what LOAD_EXTEND_OP says.
We can't allow 64-bit float registers to change from a 32-bit
mode to a 64-bit mode. */
#define CLASS_CANNOT_CHANGE_MODE \
! (TARGET_BIG_ENDIAN \
! ? (TARGET_FLOAT64 ? FP_REGS : NO_REGS) \
: (TARGET_FLOAT64 ? HI_AND_FP_REGS : HI_REG))
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
--- 2249,2266 ----
so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low
word as intended.
+ Similarly, when using paired floating-point registers, the first
+ register holds the low word, regardless of endianness. So in big
+ endian mode, (subreg:SI (reg:DF $f0) 0) does not get the high word
+ as intended.
+
Also, loading a 32-bit value into a 64-bit floating-point register
will not sign-extend the value, despite what LOAD_EXTEND_OP says.
We can't allow 64-bit float registers to change from a 32-bit
mode to a 64-bit mode. */
#define CLASS_CANNOT_CHANGE_MODE \
! (TARGET_BIG_ENDIAN ? FP_REGS \
: (TARGET_FLOAT64 ? HI_AND_FP_REGS : HI_REG))
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */