Re: [PATCH] Teach VRP about __builtin_{ffs,parity,popcount,clz,ctz,clrsb}{,l,ll,imax} (PR target/29776)

2013-07-06 Thread Richard Biener
Jakub Jelinek  wrote:

>Hi!
>
>Attached are two versions of a patch to teach VRP about the int bitop
>builtins.  Both patches are identical for all builtins but
>__builtin_c[lt]z*, which are the only two from these that are
>documented
>to have undefined behavior on some argument (0).
>
>The first version is strict, it assumes __builtin_c[lt]z* (0) doesn't
>happen
>in valid programs, while the second one attempts to be less strict to
>avoid
>breaking stuff too much.
>
>The reason for writing the second patch is that longlong.h on various
>targets has stuff like:
>#ifdef __alpha_cix__
>#define count_leading_zeros(COUNT,X)((COUNT) = __builtin_clzl (X))
>#define count_trailing_zeros(COUNT,X)   ((COUNT) = __builtin_ctzl (X))
>#define COUNT_LEADING_ZEROS_0 64
>#else
>and documents that if COUNT_LEADING_ZEROS_0 is defined, then
>count_leading_zeros (cnt, 0) should be well defined and set
>cnt to COUNT_LEADING_ZEROS_0.  While neither gcc nor glibc use
>COUNT_LEADING_ZEROS_0 macro, I'm a little bit afraid some code in the
>wild
>might do, and it might even have its own copy of longlong.h, so even if
>we've removed those COUNT_LEADING_ZEROS_0 macros for targets that
>use the builtins, something could stay broken.  So, what the patch does
>is if an optab exists for the mode of the builtin's argument and
>C?Z_DEFINED_VALUE_AT_ZERO is defined, then it will add that value to
>the
>range unless VR of argument is non-zero (well, it handles only a few
>interesting commonly used values, for CLZ only precision of the mode
>(seems right now when CLZ_DEFINED_VALUE_AT_ZERO is non-zero, it sets
>it always to bitsize of the mode, and even widening or double word
>narrowing expansion should maintain this property), for CTZ -1 and
>bitsize).  If there isn't an optab for it, for CLZ it still assumes
>it might be bitsize, for CTZ it just assumes it is undefined behavior
>otherwise, because if I understand the code right, for CTZ we really
>could
>return various values for 0 without hw support for the mode, e.g. when
>CTZ is implemented using CLZ, it might return something, if we use
>wider
>mode hw CTZ and it would return bitsize, that would be bitsize of the
>wider
>mode etc.  I bet longlong.h only uses __builtin_c?z builtins for modes
>actually implemented in hw anyway (otherwise it couldn't be used safely
>in
>libgcc implementation of those libcalls).
>
>Both patches have been bootstrapped/regtested on x86_64-linux and
>i686-linux, which one do you prefer?

The less strict variant.

Thanks 
Richard.

>   Jakub




[PATCH, i386]: Fix PR57807, -masm=intel pointer size fixes

2013-07-06 Thread Uros Bizjak
Hello!

While ATT dialect doesn't care about pointer sizes, Intel dialect
requires correct pointer size decorations.

Attached patch introduces correct pointer size overrides, and fixes
all instructions, so gcc.target/i386/sse-13.c mega-testcase compiles
without problems with -masm=intel. Unfortunately, this also uncovers
gas bug [1] with cvttps2pi.

[1] http://sourceware.org/bugzilla/show_bug.cgi?id=13572

2013-07-06  Uros Bizjak  

PR target/57807
* config/i386/sse.md (iptr): New mode attribute.
(sse2_movq128): Add pointer size overrides for Intel asm dialect.
(_vm3): Ditto.
(_vmmul3): Ditto.
(_vmdiv3): Ditto.
(sse_vmrcpv4sf2): Ditto.
(_vmsqrt2): Ditto.
(sse_vmrsqrtv4sf2): Ditto.
(_vm3): Ditto.
(avx_vmcmp3): Ditto.
(_vmmaskcmp3): Ditto.
(_comi): Ditto.
(_ucomi): Ditto.
(*xop_vmfrcz_): Ditto.
(*fmai_fmadd_): Ditto.
(*fmai_fmsub_): Ditto.
(*fmai_fnmadd_): Ditto.
(*fmai_fnmsub_): Ditto.
(*fma4i_vmfmadd_): Ditto.
(*fma4i_vmfmsub_): Ditto.
(*fma4i_vmfnmadd_): Ditto.
(*fma4i_vmfnmsub_): Ditto.
(*xop_vmfrcz_): Ditto.
(sse_cvtps2pi): Ditto.
(sse_cvttps2pi): Ditto.
(sse_cvtss2si): Ditto.
(sse_cvtss2si_2): Ditto.
(sse_cvtss2siq_2): Ditto.
(sse_cvttss2si): Ditto.
(sse_cvttss2siq): Ditto.
(sse_cvtsd2si): Ditto.
(sse_cvtsd2si_2): Ditto.
(sse_cvtsd2siq_2): Ditto.
(sse_cvttsd2si): Ditto.
(sse_cvttsd2siq): Ditto.
(sse_cvtsd2ss): Ditto.
(sse_cvtss2sd): Ditto.
(avx2_pbroadcast): Ditto.
(avx2_pbroadcast_1): Ditto.
(*avx_vperm_broadcast_v4sf): Ditto.

(sse_movhlps): Ditto for movlp[sd]/movhp[sd] alternatives.
(sse_movlhps): Ditto.
(sse_storehps): Ditto.
(sse_loadhps): Ditto.
(sse_storelps): Ditto.
(sse_loadlps): Ditto.
(*vec_concatv4sf): Ditto.
(*vec_interleave_highv2df): Ditto.
(*vec_interleave_lowv2df): Ditto.
(*vec_extractv2df_1_sse): Ditto.
(*vec_extractv2df_0_sse): Ditto.
(sse2_storelpd): Ditto.
(sse2_loadlpd): Ditto.
(sse2_movsd): Ditto.
(*vec_concatv4si): Ditto.
(vec_concatv2di): Ditto.

* config/i386/mmx.md (mmx_punpcklbw): Add pointer size overrides
for Intel asm dialect.
(mmx_punpcklwd): Ditto.
(mmx_punpckldq): Ditto.

* config/i386/i386.c (ix86_print_operand) ['H']: Output 'qword ptr'
for intel assembler dialect.

testsuite/ChangeLog:

2013-07-06  Uros Bizjak  

PR target/57807
* gcc.target/i386/pr57807.c: New test.

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu
{,-m32}. Patch was committed to mainline SVN, but due to its size, I
think it is not appropriate for release branches.
Index: config/i386/i386.c
===
--- config/i386/i386.c  (revision 200728)
+++ config/i386/i386.c  (working copy)
@@ -14670,6 +14670,9 @@ ix86_print_operand (FILE *file, rtx x, int code)
  /* It doesn't actually matter what mode we use here, as we're
 only going to use this for printing.  */
  x = adjust_address_nv (x, DImode, 8);
+ /* Output 'qword ptr' for intel assembler dialect.  */
+ if (ASSEMBLER_DIALECT == ASM_INTEL)
+   code = 'q';
  break;
 
case 'K':
Index: config/i386/mmx.md
===
--- config/i386/mmx.md  (revision 200728)
+++ config/i386/mmx.md  (working copy)
@@ -1078,7 +1078,7 @@
  (const_int 2) (const_int 10)
  (const_int 3) (const_int 11)])))]
   "TARGET_MMX"
-  "punpcklbw\t{%2, %0|%0, %2}"
+  "punpcklbw\t{%2, %0|%0, %k2}"
   [(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
 
@@ -1104,7 +1104,7 @@
   (parallel [(const_int 0) (const_int 4)
  (const_int 1) (const_int 5)])))]
   "TARGET_MMX"
-  "punpcklwd\t{%2, %0|%0, %2}"
+  "punpcklwd\t{%2, %0|%0, %k2}"
   [(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
 
@@ -1130,7 +1130,7 @@
  (parallel [(const_int 0)
 (const_int 2)])))]
   "TARGET_MMX"
-  "punpckldq\t{%2, %0|%0, %2}"
+  "punpckldq\t{%2, %0|%0, %k2}"
   [(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
 
Index: config/i386/sse.md
===
--- config/i386/sse.md  (revision 200728)
+++ config/i386/sse.md  (working copy)
@@ -355,6 +355,14 @@
(V8SF "SF") (V4DF "DF")
(V4SF "SF") (V2DF "DF")])
 
+;; Pointer size override for scalar modes (Intel asm dialect)
+(define_mode_attr iptr
+  [(V32QI "b") (V16HI "w") (V8SI "k") (V4DI "q")
+   (V16QI "b") (V8HI "w") (V4SI "k") (V2DI "q")
+   (V8SF "k") (V4DF "q")
+   (V4SF "k") (V2DF "q")
+   (SF "k") (DF "q")])
+
 ;; Number of scalar elements in each vector type
 (define_mode_attr ssescalarnum
   [(V32QI "32") (V16HI "16") (V8SI "8") (V4DI "4")
@@ -511,7 +519,7 @@
(parallel [(const_int 0)]))
  (const_int 0)))]
   "TARGET

Fix Bug 51776 (finally...)

2013-07-06 Thread Bruce Korb
 Index: ChangeLog
===
--- ChangeLog	(revision 200737)
+++ ChangeLog	(working copy)
@@ -1,3 +1,7 @@
+2013-07-06  Bruce Korb  
+
+	* inclhack.def (cdef_cplusplus): removed, per Bug 51776
+
 2013-05-23  Alexander Ivchenko 
 
 	* inclhack.def (complier_h_tradcpp): New.
Index: fixincl.x
===
--- fixincl.x	(revision 200737)
+++ fixincl.x	(working copy)
@@ -1,12 +1,12 @@
 /*  -*- buffer-read-only: t -*- vi: set ro:
- * 
+ *
  * DO NOT EDIT THIS FILE   (fixincl.x)
- * 
- * It has been AutoGen-ed  May 23, 2013 at 04:44:10 PM by AutoGen 5.12
+ *
+ * It has been AutoGen-ed  July  6, 2013 at 10:40:53 AM by AutoGen 5.17.5pre10
  * From the definitionsinclhack.def
  * and the template file   fixincl
  */
-/* DO NOT SVN-MERGE THIS FILE, EITHER Thu May 23 16:44:10 MSK 2013
+/* DO NOT SVN-MERGE THIS FILE, EITHER Sat Jul  6 10:40:53 PDT 2013
  *
  * You must regenerate it.  Use the ./genfixes script.
  *
@@ -15,7 +15,7 @@
  * certain ANSI-incompatible system header files which are fixed to work
  * correctly with ANSI C and placed in a directory that GNU C will search.
  *
- * This file contains 228 fixup descriptions.
+ * This file contains 227 fixup descriptions.
  *
  * See README for more information.
  *
@@ -2072,41 +2072,6 @@
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * *
  *
- *  Description of Cdef_Cplusplus fix
- */
-tSCC zCdef_CplusplusName[] =
- "cdef_cplusplus";
-
-/*
- *  File name selection pattern
- */
-tSCC zCdef_CplusplusList[] =
-  "sys/cdefs.h\0";
-/*
- *  Machine/OS name selection pattern
- */
-#define apzCdef_CplusplusMachs (const char**)NULL
-
-/*
- *  content selection pattern - do fix if pattern found
- */
-tSCC zCdef_CplusplusSelect0[] =
-   "\\[\\[noreturn\\]\\]";
-
-#defineCDEF_CPLUSPLUS_TEST_CT  1
-static tTestDesc aCdef_CplusplusTests[] = {
-  { TT_EGREP,zCdef_CplusplusSelect0, (regex_t*)NULL }, };
-
-/*
- *  Fix Command Arguments for Cdef_Cplusplus
- */
-static const char* apzCdef_CplusplusPatch[] = {
-"format",
-"__attribute__((__noreturn__))",
-(char*)NULL };
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * *
- *
  *  Description of Ctrl_Quotes_Def fix
  */
 tSCC zCtrl_Quotes_DefName[] =
@@ -9364,9 +9329,9 @@
  *
  *  List of all fixes
  */
-#define REGEX_COUNT  267
+#define REGEX_COUNT  266
 #define MACH_LIST_SIZE_LIMIT 187
-#define FIX_COUNT228
+#define FIX_COUNT227
 
 /*
  *  Enumerate the fixes
@@ -9418,7 +9383,6 @@
 BROKEN_CABS_FIXIDX,
 BROKEN_NAN_FIXIDX,
 BSD_STDIO_ATTRS_CONFLICT_FIXIDX,
-CDEF_CPLUSPLUS_FIXIDX,
 CTRL_QUOTES_DEF_FIXIDX,
 CTRL_QUOTES_USE_FIXIDX,
 CXX_UNREADY_FIXIDX,
@@ -9833,11 +9797,6 @@
  BSD_STDIO_ATTRS_CONFLICT_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
  aBsd_Stdio_Attrs_ConflictTests,   apzBsd_Stdio_Attrs_ConflictPatch, 0 },
 
-  {  zCdef_CplusplusName,zCdef_CplusplusList,
- apzCdef_CplusplusMachs,
- CDEF_CPLUSPLUS_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
- aCdef_CplusplusTests,   apzCdef_CplusplusPatch, 0 },
-
   {  zCtrl_Quotes_DefName,zCtrl_Quotes_DefList,
  apzCtrl_Quotes_DefMachs,
  CTRL_QUOTES_DEF_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
Index: inclhack.def
===
--- inclhack.def	(revision 200737)
+++ inclhack.def	(working copy)
@@ -64,7 +64,6 @@
 	_EOArg_;
 };
 
-
 /* On AIX when _LARGE_FILES is defined fcntl.h defines open to
  * open64 and creat to creat64.  This fixes fcntl.h to
  * undef those defines and use __asm__ to alias the symbols if
@@ -103,7 +102,6 @@
 	_EOArg_;
 };
 
-
 /*
  *  On Mac OS 10.3.9, the 'long double' functions are available in
  *  libSystem, but are not prototyped in math.h.
@@ -237,7 +235,6 @@
 	_EndOfHeader_;
 };
 
-
 /*
  *  This fixes __FD_ZERO bug for glibc-1.x
  */
@@ -275,7 +272,6 @@
 	_EndOfHeader_;
 };
 
-
 /*
  *  This fixes __FD_ZERO bug for glibc-2.0.x
  */
@@ -317,7 +313,6 @@
 	_EndOfHeader_;
 };
 
-
 /*
  * Solaris  is a DDK (aka kernel-land) header providing
  * the same interface as .  No idea why they couldn't have just
@@ -336,7 +331,6 @@
 	_EndOfHeader_;
 };
 
-
 /*
  *  Fix non-ANSI memcpy declaration that conflicts with gcc's builtin
  *  declaration on Sun OS 4.x.  We must only fix this on Sun OS 4.x, because
@@ -574,7 +568,6 @@
 	_EndOfHeader_;
 };
 
-
 /*
  * complex.h on AIX 5 and AIX 6 define _Complex_I and I in terms of __I,
  * which only is provided by AIX xlc C99.
@@ -727,7 +720,6 @@
 "{...init stuff...}";
 };
 
-
 /*
  *  AIX stdint.h fixes.
  */
@@ -744,7 +736,9 @@
 		"#define UINT16_MAX	(65535U)";
 };
 
-
+/*
+ * aix_stdint_2
+ */
 fix = {
 hackname  = aix_stdint_2;
 mach  = "*-*-aix*";
@@ -773,7 +767,9 @@
 		"#define UINTPTR_MAX	UINT32_MAX";
 };
 
-
+/*
+ * aix_stdint_3
+ */
 fix = {
 hackname  = aix_stdint_3;
 mach  = "*-*-aix*";
@@ 

fixincludes 2013-05-23 Alexander Ivchenko

2013-07-06 Thread Bruce Korb

Alexander Ivchenko Mon, 29 Apr 2013 23:24:55 -0700

2013/4/29 Mike Stump :

On Jan 9, 2013, at 7:14 AM, Alexander Ivchenko  wrote:

 We have test fail for gcc.dg/cpp/trad/include.c on Android. The
reason for that is that
-ftraditional-cpp is not expected to work on Android due to variadic
macro (like #define __builtin_warning(x, y...))
in standard headers and traditional preprocessor cannot handle them.
 The attached patch disables that test.


Be sure to ask, Ok? in your patch submittals.

Ok.


thank you! I thought I did ask..


...
in standard headers and traditional preprocessor cannot handle them."

is it ok for trunk?


could someone commit that patch please? I don't have commit access.


Actually, Alexander, you did not ask.  And Kirill, you didn't verify
before applying the patch.  Patches to fixincludes are generally safe,
but it is protocol to ask.  Also, I prefer that the hacks get inserted
alphabetically.  So, actually, there are a few small complaints.


$ fgrep -i fixincludes ../MAINTAINERS
fixincludes Bruce Korb  bk...@gnu.org


The patch looks pretty reasonable, but I think someone else
should verify the obsolescence.  I also think it should be renamed to
something like "obsolete_builtin_warning" because the current
name gives no clue about what it really is.

/*
 *  Old Linux kernel's  header breaks Traditional CPP
 */
fix = {
hackname  = complier_h_tradcpp;
files = linux/compiler.h;

select= "#define __builtin_warning\\(x, y\\.\\.\\.\\) \\(1\\)";
c_fix = format;
c_fix_arg = "/* __builtin_warning(x, y...) is obsolete */";

test_text = "#define __builtin_warning(x, y...) (1)";
};


folding (vec_)cond_expr in a binary operation

2013-07-06 Thread Marc Glisse

Hello,

the first attached patch does not bootstrap and has at least 2 main 
issues. The second patch does pass bootstrap+testsuite, but I liked the 
first more...


First, the fold-const bit causes an assertion failure (building libjava) 
in combine_cond_expr_cond, which calls:


  t = fold_binary_loc (gimple_location (stmt), code, type, op0, op1);

and then checks:

  /* Require that we got a boolean type out if we put one in.  */
  gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));

which makes sense... Note that the 2 relevant types are:

(gdb) call debug_tree((tree)0x75e78930)
  constant 8>
unit size  constant 1>
align 8 symtab -169408800 alias set -1 canonical type 0x76635c78 precision 1 min 
 max 
pointer_to_this  chain >
(gdb) call debug_tree(type)
  constant 8>
unit size  constant 1>
align 8 symtab -170348640 alias set 19 canonical type 0x764f69d8 precision 1 min 
 max 
pointer_to_this >

I need to relax the conditions on the vec?-1:0 optimization because with 
vectors we often end up with several types that are equivalent. Can you 
think of a good way to do it? In the second patch I limit the 
transformation to vectors and hope it doesn't cause as much trouble 
there...




Second, the way the forwprop transformation is done, it can be necessary 
to run the forwprop pass several times in a row, which is not nice. It 
takes:


stmt_cond
stmt_binop

and produces:

stmt_folded
stmt_cond2

But one of the arguments of stmt_folded could be an ssa_name defined by a 
cond_expr, which could now be propagated into stmt_folded (there may be 
other new possible transformations). However, that cond_expr has already 
been visited and won't be again. The combine part of the pass uses a PLF 
to revisit statements, but the forwprop part doesn't have any specific 
mechanism.


The workarounds I can think of are:
- manually check if some of the arguments of stmt_folded are cond_expr and 
recursively call the function on them;

- move the transformation to the combine part of the pass;
- setup some system to revisit all earlier statements?

I went with the second option in the second patch, but this limitation of 
forward propagation seems strange to me.



(s/combine_binop_with_condition/forward_propagate_condition/ for the first 
patch)


2013-07-06  Marc Glisse  

PR tree-optimization/57755
gcc/
* tree-ssa-forwprop.c (combine_binop_with_condition): New function.
(ssa_forward_propagate_and_combine): Call it.
* fold-const.c (fold_ternary_loc): In gimple form, don't check for
type equality.

gcc/testsuite/
* g++.dg/tree-ssa/pr57755.C: New testcase.

(this message does not supersede 
http://gcc.gnu.org/ml/gcc-patches/2013-06/msg01624.html )


--
Marc GlisseIndex: fold-const.c
===
--- fold-const.c(revision 200736)
+++ fold-const.c(working copy)
@@ -14124,21 +14124,23 @@ fold_ternary_loc (location_t loc, enum t
 
   /* Convert A ? 1 : 0 to simply A.  */
   if ((code == VEC_COND_EXPR ? integer_all_onesp (op1)
 : (integer_onep (op1)
&& !VECTOR_TYPE_P (type)))
  && integer_zerop (op2)
  /* If we try to convert OP0 to our type, the
 call to fold will try to move the conversion inside
 a COND, which will recurse.  In that case, the COND_EXPR
 is probably the best choice, so leave it alone.  */
- && type == TREE_TYPE (arg0))
+ && (type == TREE_TYPE (arg0)
+ || (in_gimple_form
+ && useless_type_conversion_p (type, TREE_TYPE (arg0)
return pedantic_non_lvalue_loc (loc, arg0);
 
   /* Convert A ? 0 : 1 to !A.  This prefers the use of NOT_EXPR
 over COND_EXPR in cases such as floating point comparisons.  */
   if (integer_zerop (op1)
  && (code == VEC_COND_EXPR ? integer_all_onesp (op2)
: (integer_onep (op2)
   && !VECTOR_TYPE_P (type)))
  && truth_value_p (TREE_CODE (arg0)))
return pedantic_non_lvalue_loc (loc,
Index: tree-ssa-forwprop.c
===
--- tree-ssa-forwprop.c (revision 200736)
+++ tree-ssa-forwprop.c (working copy)
@@ -1135,20 +1135,135 @@ forward_propagate_comparison (gimple_stm
 
   /* Remove defining statements.  */
   return remove_prop_source_from_use (name);
 
 bailout:
   gsi_next (defgsi);
   return false;
 }
 
 
+/* Forward propagate the condition defined in *DEFGSI to uses in
+   binary operations.
+   Returns true if stmt is now unused.  Advance DEFGSI to the next
+   statement.  */
+
+static bool
+forward_propagate_condition (gimple_stmt_iterator *defgsi)
+{
+  gimple stmt = gsi_stmt (*defgsi);
+  tree name = gimple_assign_lhs (stmt);
+  enum tree_code defcode = gimple_assign_rhs_code (s

[PATCH] FPU IEEE 754 for MIPS r5900

2013-07-06 Thread Jürgen Urban
Hello Richard,

I used the SPU code in GCC as example for creating an r5900_single_format 
structure. The patch is attached to the e-mail. I want to submit this patch.

> >> * removing the ISA_HAS_LDC1_SDC1 setting.  I realise what you did
> >>   describes the reality of the processor, but the problem is that
> >>   the patch doesn't provide an alternative for 64-bit loads and
> >>   stores when -mfp64 is used.  That combination also isn't rejected,
> >>   so we're likely to get an internal compiler error instead.
> >>
> >>   This change shouldn't affect the soft-float case you describe.
> >>   It also shouldn't be important for the single-float code.

I needed to patch ISA_HAS_LDC1_SDC1, because the GCC uses the instructions also 
for single float to store FPRs on the stack. To get around the missing 
alternative, I reject in the code the following combinations, because it would 
never work:
-march=r5900 -mfp64 -mhard-float
-march=r5900 -mdouble-float -mhard-float

> >> FWIW, the Cygnus/Red Hat version of the port just stuck with the R5900
> >> behaviour and made GCC understand it (MODE_HAS_* & various other bits).
> >> This code was then updated and extended for the SPU.  I'd have expected
> >> the support to be in reasonably good shape because of the SPU.
> >
> > I assume that you mean the cell processor of the PS3 and not the Sound
> > Processing Unit of the PS2.
>
> :-)
>
> > The macros MODE_HAS_* in the GCC look promising.
>
> You've probably already seen it, but there's also spu_single_format.

To be able to use it, you need to use mipsr5900el and "--with-float=single". 
"--with-float=hard" results in double float because of MIPS ISA III.
I didn't changed the default in config.gcc. It is still soft float, because 
floating point doesn't behave as defined by IEEE 754. I don't see much 
improvement. This is the case on the PS2 and the PS3. For example inf minus inf 
should be NaN, but on both systems it is 0. I tested it on r5900 and the PS3 
SPU. Both calculates the same result despite the MODE_HAS_* implementation. 
This means that there is a patch needed in the generic part (i.e. not  mips) of 
the GCC. Currently I only provide a simple patch, so that the GCC knows the 
missing stuff, even if it is not correctly handled in the generic GCC part. I 
thought that Linux is running on SPU, but this is not the case, because it just 
a simple coprocessor. It seems that SPU is not used for complex floating point 
calculations in homebrew software. I am pretty sure that nearly nobody knows 
that floating point in GCC behaves this way on SPU.

Best regards
JürgenIndex: gcc/real.c
===
--- gcc/real.c	(Revision 200583)
+++ gcc/real.c	(Arbeitskopie)
@@ -3028,6 +3028,34 @@
 true
   };
 
+/*  r5900 Single precision format is the same as IEEE
+single precision with the following differences:
+  - Infinities are not supported.  Instead MAX_FLOAT or MIN_FLOAT
+	are generated.
+  - NaNs are not supported.
+  - Denormals are not supported.
+  - the only supported rounding mode is trunction (towards zero).  */
+const struct real_format r5900_single_format =
+  {
+encode_ieee_single,
+decode_ieee_single,
+2,
+24,
+24,
+-125,
+128,
+31,
+31,
+true,
+true,
+false,
+false,
+false,
+true,
+false,
+true
+  };
+
 const struct real_format motorola_single_format =
   {
 encode_ieee_single,
Index: gcc/real.h
===
--- gcc/real.h	(Revision 200583)
+++ gcc/real.h	(Arbeitskopie)
@@ -303,6 +303,7 @@
 /* Target formats defined in real.c.  */
 extern const struct real_format ieee_single_format;
 extern const struct real_format mips_single_format;
+extern const struct real_format r5900_single_format;
 extern const struct real_format motorola_single_format;
 extern const struct real_format spu_single_format;
 extern const struct real_format ieee_double_format;
Index: gcc/config.gcc
===
--- gcc/config.gcc	(Revision 200583)
+++ gcc/config.gcc	(Arbeitskopie)
@@ -3472,7 +3475,7 @@
 		supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64 divide llsc mips-plt synci"
 
 		case ${with_float} in
-		"" | soft | hard)
+		"" | soft | hard | single | double)
 			# OK
 			;;
 		*)
Index: gcc/config/mips/mips.c
===
--- gcc/config/mips/mips.c	(Revision 200583)
+++ gcc/config/mips/mips.c	(Arbeitskopie)
@@ -16830,6 +16830,19 @@
 	target_flags &= ~MASK_FLOAT64;
 }
 
+  if (TARGET_HARD_FLOAT_ABI && TARGET_FLOAT64 && TARGET_MIPS5900)
+{
+  /* FPU of r5900 only supports 32 bit. */
+  error ("unsupported combination: %s", "-march=r5900 -mfp64 -mhard-float");
+}
+
+  if (TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FLOAT && TARGET_MIPS5900)
+{
+  /* FPU of r5900 only supports 32