diff mbox

Basic support for MIPS r5900

Message ID 87zjv77ygt.fsf@talisman.default
State New
Headers show

Commit Message

Richard Sandiford June 3, 2013, 8:04 p.m. UTC
"Jürgen Urban" <JuergenUrban@gmx.de> writes:
> after some months I reworked the patch for r5900. It would be nice if
> this could be accepted. The patch contains only changes to get basic
> support for MIPS r5900. It can be used to compile a working Linux kernel
> for the Playstation 2. It is also possible to get Linux programs working
> with software floating point and ABI o32. Other stuff like hardware
> floating point and ABI n32 is not fully supported yet.

Thanks, looks good.  The comments I have are only minor and seemed easier
to spell out as a revised patch, attached below.  The changes are:

* removing the config.sub bit, which looked redundant.  We already have
  the up-to-date upstream config.sub.

* removing the target_cpu_default setting.  I realise this was taken
  from mips64-elf, but it was redundant here, there, and elsewhere.
  I've just committed a patch to remove the existing cases.

* removing the TUNE_5900 definition.  I prefer not to define these
  kinds of macro until they're used.

* 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.

* tweaking the mips_reorg_process_insns comment slightly

* fixing a few minor formatting issues

Does this version look OK to you?  I'll commit it if so.

> How much other changes will be currently accepted here? There is other
> stuff which I want to prepare and submit here, e.g.:
> 1. disable use of dmult and ddiv (ABI n32).
> 2. use trunc.w.s instead of cvt.w.s (to get single float working for
> normal range calculations; i.e. calculating without inf or nan).
> 3. fix use of ll/sc in libgomp, either increase mips ISA level or use
> syscall (which is broken in Linux 2.6.35.4).
> 4. fix libgcc to build a real muldi3 function for ABI n32 (not the
> multi3 function which is stored in muldi3.o file).
> 5. add support for configure parameters --float=single and
> --float=double in addition to --float=soft and --float=hard.
> 6. rework floating point to support single float with ABI n32 (either
> break the ABI or store floating point values in general purpose
> registers like soft float).
> 7. change libgcc or mips.md in way so that the non IEEE 754 compatible
> FPU of the r5900 gets compatible.

Well, I'm afraid that's hard to say in advance.  It really depends
on what the changes look like.  (1) and (2) sound harmless enough,
although (1) should probably only be done in conjunction with (4).
I'm not sure what (3) involves.  (5) sounds like a good idea.
(6) is worth doing, but anything ABI-related gets extra-paranoid
treatment. :-)

I'm not sure about (7) though.  I'd imagine trying to get true IEEE
conformance out of the R5900 FPU would be pretty difficult and carry
quite a bit of runtime overhead, especially with the subnormal handling.
Is it really worth it?  Do you have any particular use cases in mind?

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.

Thanks,
Richard


gcc/
2013-06-03  Jürgen Urban  <JuergenUrban@gmx.de>

	* config.gcc (mipsr5900-*-elf*, mipsr5900el-*-elf*, mips64r5900-*-elf*)
	(mips64r5900el-*-elf*): New configurations.
	* config/mips/mips-cpus.def (r5900): New processor.
	* config/mips/mips-tables.opt: Regenerate.
	* config/mips/mips.c (mips_rtx_cost_data): Add an R5900 entry.
	(mips_issue_rate): Handle PROCESSOR_R5900.
	(mips_reorg_process_insns): Force reorder mode for the R5900.
	* config/mips/mips.h (TARGET_MIPS5900): Define.
	(ISA_HAS_CONDMOVE, ISA_HAS_PREFETCH, ISA_HAS_HILO_INTERLOCKS): Include
	TARGET_MIPS5900.
	(ISA_HAS_LOAD_DELAY, ISA_HAS_XFER_DELAY, ISA_HAS_FCMP_DELAY): Exclude
	TARGET_MIPS5900.
	* config/mips/mips.md (processor): Add r5900.
	(MOVECC): Disallow CCmode conditions for TARGET_MIPS5900.

libgcc/
2013-06-03  Jürgen Urban  <JuergenUrban@gmx.de>

	* config.host (mipsr5900-*-elf*, mipsr5900el-*-elf*, mips64r5900-*-elf*)
	(mips64r5900el-*-elf*): New configurations.

Comments

Jürgen Urban June 3, 2013, 11:31 p.m. UTC | #1
Hello Richard,

> Thanks, looks good.  The comments I have are only minor and seemed easier
> to spell out as a revised patch, attached below.  The changes are:
>
> * removing the config.sub bit, which looked redundant.  We already have
>   the up-to-date upstream config.sub.
>
> * removing the target_cpu_default setting.  I realise this was taken
>   from mips64-elf, but it was redundant here, there, and elsewhere.
>   I've just committed a patch to remove the existing cases.
>
> * removing the TUNE_5900 definition.  I prefer not to define these
>   kinds of macro until they're used.
>
> * 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.
>
> * tweaking the mips_reorg_process_insns comment slightly
>
> * fixing a few minor formatting issues
>
> Does this version look OK to you?  I'll commit it if so.

This is OK and the generated code is still working on the PS2 in my test run.

> > How much other changes will be currently accepted here? There is other
> > stuff which I want to prepare and submit here, e.g.:
> > 1. disable use of dmult and ddiv (ABI n32).
> > 2. use trunc.w.s instead of cvt.w.s (to get single float working for
> > normal range calculations; i.e. calculating without inf or nan).
> > 3. fix use of ll/sc in libgomp, either increase mips ISA level or use
> > syscall (which is broken in Linux 2.6.35.4).
> > 4. fix libgcc to build a real muldi3 function for ABI n32 (not the
> > multi3 function which is stored in muldi3.o file).
> > 5. add support for configure parameters --float=single and
> > --float=double in addition to --float=soft and --float=hard.
> > 6. rework floating point to support single float with ABI n32 (either
> > break the ABI or store floating point values in general purpose
> > registers like soft float).
> > 7. change libgcc or mips.md in way so that the non IEEE 754 compatible
> > FPU of the r5900 gets compatible.
>
> Well, I'm afraid that's hard to say in advance.  It really depends
> on what the changes look like.  (1) and (2) sound harmless enough,
> although (1) should probably only be done in conjunction with (4).
> I'm not sure what (3) involves.  (5) sounds like a good idea.
> (6) is worth doing, but anything ABI-related gets extra-paranoid
> treatment. :-)
>
> I'm not sure about (7) though.  I'd imagine trying to get true IEEE
> conformance out of the R5900 FPU would be pretty difficult and carry
> quite a bit of runtime overhead, especially with the subnormal handling.
> Is it really worth it?  Do you have any particular use cases in mind?

My target was to get existing C programs working (e.g. all mipsel programs from Debian 5 or 6, all mips64el programs from Fedora 12 or 13). The programs should work like programs on normal mipsel or mips64el Linux. I don't know what in the different programs is used.

> 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.

Best regards
Jürgen
Richard Sandiford June 4, 2013, 6:06 p.m. UTC | #2
"Jürgen Urban" <JuergenUrban@gmx.de> writes:
> Hello Richard,
>
>> Thanks, looks good.  The comments I have are only minor and seemed easier
>> to spell out as a revised patch, attached below.  The changes are:
>>
>> * removing the config.sub bit, which looked redundant.  We already have
>>   the up-to-date upstream config.sub.
>>
>> * removing the target_cpu_default setting.  I realise this was taken
>>   from mips64-elf, but it was redundant here, there, and elsewhere.
>>   I've just committed a patch to remove the existing cases.
>>
>> * removing the TUNE_5900 definition.  I prefer not to define these
>>   kinds of macro until they're used.
>>
>> * 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.
>>
>> * tweaking the mips_reorg_process_insns comment slightly
>>
>> * fixing a few minor formatting issues
>>
>> Does this version look OK to you?  I'll commit it if so.
>
> This is OK and the generated code is still working on the PS2 in my test run.

Thanks, now applied.

>> 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.

Richard
diff mbox

Patch

Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	2013-06-03 20:28:18.959933736 +0100
+++ gcc/config.gcc	2013-06-03 20:30:19.110139050 +0100
@@ -1935,10 +1935,15 @@  mipsisa64sb1-*-elf* | mipsisa64sb1el-*-e
 	tmake_file="mips/t-elf mips/t-sb1"
 	tm_defines="${tm_defines} MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sb1\\\" MIPS_ABI_DEFAULT=ABI_O64"
 	;;
-mips-*-elf* | mipsel-*-elf*)
+mips-*-elf* | mipsel-*-elf* | mipsr5900-*-elf* | mipsr5900el-*-elf*)
 	tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
 	tmake_file="mips/t-elf"
 	;;
+mips64r5900-*-elf* | mips64r5900el-*-elf*)
+	tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
+	tmake_file="mips/t-elf"
+	tm_defines="${tm_defines} MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_N32"
+	;;
 mips64-*-elf* | mips64el-*-elf*)
 	tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
 	tmake_file="mips/t-elf"
@@ -2977,6 +2982,19 @@  if test x$with_cpu = x ; then
 	  ;;
       esac
       ;;
+    mips64r5900-*-* | mips64r5900el-*-* | mipsr5900-*-* | mipsr5900el-*-*)
+      with_arch=r5900
+      with_tune=r5900
+      if test x$with_llsc = x; then
+	# r5900 doesn't support ll, sc, lld and scd instructions:
+	with_llsc=no
+      fi
+      if test x$with_float = x; then
+	# r5900 doesn't support 64 bit float:
+	# 32 bit float doesn't comply with IEEE 754.
+	with_float=soft
+      fi
+      ;;
     mips*-*-vxworks)
       with_arch=mips2
       ;;
Index: gcc/config/mips/mips-cpus.def
===================================================================
--- gcc/config/mips/mips-cpus.def	2013-06-03 20:28:18.969933837 +0100
+++ gcc/config/mips/mips-cpus.def	2013-06-03 20:29:09.489440911 +0100
@@ -68,6 +68,7 @@  MIPS_CPU ("r4600", PROCESSOR_R4600, 3, 0
 MIPS_CPU ("orion", PROCESSOR_R4600, 3, 0)
 MIPS_CPU ("r4650", PROCESSOR_R4650, 3, 0)
 MIPS_CPU ("r4700", PROCESSOR_R4700, 3, 0)
+MIPS_CPU ("r5900", PROCESSOR_R5900, 3, 0)
 /* ST Loongson 2E/2F processors.  */
 MIPS_CPU ("loongson2e", PROCESSOR_LOONGSON_2E, 3, PTF_AVOID_BRANCHLIKELY)
 MIPS_CPU ("loongson2f", PROCESSOR_LOONGSON_2F, 3, PTF_AVOID_BRANCHLIKELY)
Index: gcc/config/mips/mips-tables.opt
===================================================================
--- gcc/config/mips/mips-tables.opt	2013-04-22 21:42:47.665569750 +0100
+++ gcc/config/mips/mips-tables.opt	2013-06-03 20:32:52.393673887 +0100
@@ -208,425 +208,431 @@  EnumValue
 Enum(mips_arch_opt_value) String(4700) Value(22)
 
 EnumValue
-Enum(mips_arch_opt_value) String(loongson2e) Value(23) Canonical
+Enum(mips_arch_opt_value) String(r5900) Value(23) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(loongson2f) Value(24) Canonical
+Enum(mips_arch_opt_value) String(5900) Value(23)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r8000) Value(25) Canonical
+Enum(mips_arch_opt_value) String(loongson2e) Value(24) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r8k) Value(25)
+Enum(mips_arch_opt_value) String(loongson2f) Value(25) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(8000) Value(25)
+Enum(mips_arch_opt_value) String(r8000) Value(26) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(8k) Value(25)
+Enum(mips_arch_opt_value) String(r8k) Value(26)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r10000) Value(26) Canonical
+Enum(mips_arch_opt_value) String(8000) Value(26)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r10k) Value(26)
+Enum(mips_arch_opt_value) String(8k) Value(26)
 
 EnumValue
-Enum(mips_arch_opt_value) String(10000) Value(26)
+Enum(mips_arch_opt_value) String(r10000) Value(27) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(10k) Value(26)
+Enum(mips_arch_opt_value) String(r10k) Value(27)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r12000) Value(27) Canonical
+Enum(mips_arch_opt_value) String(10000) Value(27)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r12k) Value(27)
+Enum(mips_arch_opt_value) String(10k) Value(27)
 
 EnumValue
-Enum(mips_arch_opt_value) String(12000) Value(27)
+Enum(mips_arch_opt_value) String(r12000) Value(28) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(12k) Value(27)
+Enum(mips_arch_opt_value) String(r12k) Value(28)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r14000) Value(28) Canonical
+Enum(mips_arch_opt_value) String(12000) Value(28)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r14k) Value(28)
+Enum(mips_arch_opt_value) String(12k) Value(28)
 
 EnumValue
-Enum(mips_arch_opt_value) String(14000) Value(28)
+Enum(mips_arch_opt_value) String(r14000) Value(29) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(14k) Value(28)
+Enum(mips_arch_opt_value) String(r14k) Value(29)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r16000) Value(29) Canonical
+Enum(mips_arch_opt_value) String(14000) Value(29)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r16k) Value(29)
+Enum(mips_arch_opt_value) String(14k) Value(29)
 
 EnumValue
-Enum(mips_arch_opt_value) String(16000) Value(29)
+Enum(mips_arch_opt_value) String(r16000) Value(30) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(16k) Value(29)
+Enum(mips_arch_opt_value) String(r16k) Value(30)
 
 EnumValue
-Enum(mips_arch_opt_value) String(vr5000) Value(30) Canonical
+Enum(mips_arch_opt_value) String(16000) Value(30)
 
 EnumValue
-Enum(mips_arch_opt_value) String(vr5k) Value(30)
+Enum(mips_arch_opt_value) String(16k) Value(30)
 
 EnumValue
-Enum(mips_arch_opt_value) String(5000) Value(30)
+Enum(mips_arch_opt_value) String(vr5000) Value(31) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(5k) Value(30)
+Enum(mips_arch_opt_value) String(vr5k) Value(31)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r5000) Value(30)
+Enum(mips_arch_opt_value) String(5000) Value(31)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r5k) Value(30)
+Enum(mips_arch_opt_value) String(5k) Value(31)
 
 EnumValue
-Enum(mips_arch_opt_value) String(vr5400) Value(31) Canonical
+Enum(mips_arch_opt_value) String(r5000) Value(31)
 
 EnumValue
-Enum(mips_arch_opt_value) String(5400) Value(31)
+Enum(mips_arch_opt_value) String(r5k) Value(31)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r5400) Value(31)
+Enum(mips_arch_opt_value) String(vr5400) Value(32) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(vr5500) Value(32) Canonical
+Enum(mips_arch_opt_value) String(5400) Value(32)
 
 EnumValue
-Enum(mips_arch_opt_value) String(5500) Value(32)
+Enum(mips_arch_opt_value) String(r5400) Value(32)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r5500) Value(32)
+Enum(mips_arch_opt_value) String(vr5500) Value(33) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(rm7000) Value(33) Canonical
+Enum(mips_arch_opt_value) String(5500) Value(33)
 
 EnumValue
-Enum(mips_arch_opt_value) String(rm7k) Value(33)
+Enum(mips_arch_opt_value) String(r5500) Value(33)
 
 EnumValue
-Enum(mips_arch_opt_value) String(7000) Value(33)
+Enum(mips_arch_opt_value) String(rm7000) Value(34) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(7k) Value(33)
+Enum(mips_arch_opt_value) String(rm7k) Value(34)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r7000) Value(33)
+Enum(mips_arch_opt_value) String(7000) Value(34)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r7k) Value(33)
+Enum(mips_arch_opt_value) String(7k) Value(34)
 
 EnumValue
-Enum(mips_arch_opt_value) String(rm9000) Value(34) Canonical
+Enum(mips_arch_opt_value) String(r7000) Value(34)
 
 EnumValue
-Enum(mips_arch_opt_value) String(rm9k) Value(34)
+Enum(mips_arch_opt_value) String(r7k) Value(34)
 
 EnumValue
-Enum(mips_arch_opt_value) String(9000) Value(34)
+Enum(mips_arch_opt_value) String(rm9000) Value(35) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(9k) Value(34)
+Enum(mips_arch_opt_value) String(rm9k) Value(35)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r9000) Value(34)
+Enum(mips_arch_opt_value) String(9000) Value(35)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r9k) Value(34)
+Enum(mips_arch_opt_value) String(9k) Value(35)
 
 EnumValue
-Enum(mips_arch_opt_value) String(4kc) Value(35) Canonical
+Enum(mips_arch_opt_value) String(r9000) Value(35)
 
 EnumValue
-Enum(mips_arch_opt_value) String(r4kc) Value(35)
+Enum(mips_arch_opt_value) String(r9k) Value(35)
 
 EnumValue
-Enum(mips_arch_opt_value) String(4km) Value(36) Canonical
+Enum(mips_arch_opt_value) String(4kc) Value(36) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r4km) Value(36)
+Enum(mips_arch_opt_value) String(r4kc) Value(36)
 
 EnumValue
-Enum(mips_arch_opt_value) String(4kp) Value(37) Canonical
+Enum(mips_arch_opt_value) String(4km) Value(37) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r4kp) Value(37)
+Enum(mips_arch_opt_value) String(r4km) Value(37)
 
 EnumValue
-Enum(mips_arch_opt_value) String(4ksc) Value(38) Canonical
+Enum(mips_arch_opt_value) String(4kp) Value(38) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r4ksc) Value(38)
+Enum(mips_arch_opt_value) String(r4kp) Value(38)
 
 EnumValue
-Enum(mips_arch_opt_value) String(m4k) Value(39) Canonical
+Enum(mips_arch_opt_value) String(4ksc) Value(39) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(m14kc) Value(40) Canonical
+Enum(mips_arch_opt_value) String(r4ksc) Value(39)
 
 EnumValue
-Enum(mips_arch_opt_value) String(m14k) Value(41) Canonical
+Enum(mips_arch_opt_value) String(m4k) Value(40) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(4kec) Value(42) Canonical
+Enum(mips_arch_opt_value) String(m14kc) Value(41) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r4kec) Value(42)
+Enum(mips_arch_opt_value) String(m14k) Value(42) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(4kem) Value(43) Canonical
+Enum(mips_arch_opt_value) String(4kec) Value(43) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r4kem) Value(43)
+Enum(mips_arch_opt_value) String(r4kec) Value(43)
 
 EnumValue
-Enum(mips_arch_opt_value) String(4kep) Value(44) Canonical
+Enum(mips_arch_opt_value) String(4kem) Value(44) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r4kep) Value(44)
+Enum(mips_arch_opt_value) String(r4kem) Value(44)
 
 EnumValue
-Enum(mips_arch_opt_value) String(4ksd) Value(45) Canonical
+Enum(mips_arch_opt_value) String(4kep) Value(45) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r4ksd) Value(45)
+Enum(mips_arch_opt_value) String(r4kep) Value(45)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kc) Value(46) Canonical
+Enum(mips_arch_opt_value) String(4ksd) Value(46) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kc) Value(46)
+Enum(mips_arch_opt_value) String(r4ksd) Value(46)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kf2_1) Value(47) Canonical
+Enum(mips_arch_opt_value) String(24kc) Value(47) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kf2_1) Value(47)
+Enum(mips_arch_opt_value) String(r24kc) Value(47)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kf) Value(48) Canonical
+Enum(mips_arch_opt_value) String(24kf2_1) Value(48) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kf) Value(48)
+Enum(mips_arch_opt_value) String(r24kf2_1) Value(48)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kf1_1) Value(49) Canonical
+Enum(mips_arch_opt_value) String(24kf) Value(49) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kf1_1) Value(49)
+Enum(mips_arch_opt_value) String(r24kf) Value(49)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kfx) Value(50) Canonical
+Enum(mips_arch_opt_value) String(24kf1_1) Value(50) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kfx) Value(50)
+Enum(mips_arch_opt_value) String(r24kf1_1) Value(50)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kx) Value(51) Canonical
+Enum(mips_arch_opt_value) String(24kfx) Value(51) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kx) Value(51)
+Enum(mips_arch_opt_value) String(r24kfx) Value(51)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kec) Value(52) Canonical
+Enum(mips_arch_opt_value) String(24kx) Value(52) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kec) Value(52)
+Enum(mips_arch_opt_value) String(r24kx) Value(52)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kef2_1) Value(53) Canonical
+Enum(mips_arch_opt_value) String(24kec) Value(53) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kef2_1) Value(53)
+Enum(mips_arch_opt_value) String(r24kec) Value(53)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kef) Value(54) Canonical
+Enum(mips_arch_opt_value) String(24kef2_1) Value(54) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kef) Value(54)
+Enum(mips_arch_opt_value) String(r24kef2_1) Value(54)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kef1_1) Value(55) Canonical
+Enum(mips_arch_opt_value) String(24kef) Value(55) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kef1_1) Value(55)
+Enum(mips_arch_opt_value) String(r24kef) Value(55)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kefx) Value(56) Canonical
+Enum(mips_arch_opt_value) String(24kef1_1) Value(56) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kefx) Value(56)
+Enum(mips_arch_opt_value) String(r24kef1_1) Value(56)
 
 EnumValue
-Enum(mips_arch_opt_value) String(24kex) Value(57) Canonical
+Enum(mips_arch_opt_value) String(24kefx) Value(57) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r24kex) Value(57)
+Enum(mips_arch_opt_value) String(r24kefx) Value(57)
 
 EnumValue
-Enum(mips_arch_opt_value) String(34kc) Value(58) Canonical
+Enum(mips_arch_opt_value) String(24kex) Value(58) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r34kc) Value(58)
+Enum(mips_arch_opt_value) String(r24kex) Value(58)
 
 EnumValue
-Enum(mips_arch_opt_value) String(34kf2_1) Value(59) Canonical
+Enum(mips_arch_opt_value) String(34kc) Value(59) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r34kf2_1) Value(59)
+Enum(mips_arch_opt_value) String(r34kc) Value(59)
 
 EnumValue
-Enum(mips_arch_opt_value) String(34kf) Value(60) Canonical
+Enum(mips_arch_opt_value) String(34kf2_1) Value(60) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r34kf) Value(60)
+Enum(mips_arch_opt_value) String(r34kf2_1) Value(60)
 
 EnumValue
-Enum(mips_arch_opt_value) String(34kf1_1) Value(61) Canonical
+Enum(mips_arch_opt_value) String(34kf) Value(61) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r34kf1_1) Value(61)
+Enum(mips_arch_opt_value) String(r34kf) Value(61)
 
 EnumValue
-Enum(mips_arch_opt_value) String(34kfx) Value(62) Canonical
+Enum(mips_arch_opt_value) String(34kf1_1) Value(62) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r34kfx) Value(62)
+Enum(mips_arch_opt_value) String(r34kf1_1) Value(62)
 
 EnumValue
-Enum(mips_arch_opt_value) String(34kx) Value(63) Canonical
+Enum(mips_arch_opt_value) String(34kfx) Value(63) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r34kx) Value(63)
+Enum(mips_arch_opt_value) String(r34kfx) Value(63)
 
 EnumValue
-Enum(mips_arch_opt_value) String(34kn) Value(64) Canonical
+Enum(mips_arch_opt_value) String(34kx) Value(64) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r34kn) Value(64)
+Enum(mips_arch_opt_value) String(r34kx) Value(64)
 
 EnumValue
-Enum(mips_arch_opt_value) String(74kc) Value(65) Canonical
+Enum(mips_arch_opt_value) String(34kn) Value(65) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r74kc) Value(65)
+Enum(mips_arch_opt_value) String(r34kn) Value(65)
 
 EnumValue
-Enum(mips_arch_opt_value) String(74kf2_1) Value(66) Canonical
+Enum(mips_arch_opt_value) String(74kc) Value(66) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r74kf2_1) Value(66)
+Enum(mips_arch_opt_value) String(r74kc) Value(66)
 
 EnumValue
-Enum(mips_arch_opt_value) String(74kf) Value(67) Canonical
+Enum(mips_arch_opt_value) String(74kf2_1) Value(67) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r74kf) Value(67)
+Enum(mips_arch_opt_value) String(r74kf2_1) Value(67)
 
 EnumValue
-Enum(mips_arch_opt_value) String(74kf1_1) Value(68) Canonical
+Enum(mips_arch_opt_value) String(74kf) Value(68) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r74kf1_1) Value(68)
+Enum(mips_arch_opt_value) String(r74kf) Value(68)
 
 EnumValue
-Enum(mips_arch_opt_value) String(74kfx) Value(69) Canonical
+Enum(mips_arch_opt_value) String(74kf1_1) Value(69) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r74kfx) Value(69)
+Enum(mips_arch_opt_value) String(r74kf1_1) Value(69)
 
 EnumValue
-Enum(mips_arch_opt_value) String(74kx) Value(70) Canonical
+Enum(mips_arch_opt_value) String(74kfx) Value(70) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r74kx) Value(70)
+Enum(mips_arch_opt_value) String(r74kfx) Value(70)
 
 EnumValue
-Enum(mips_arch_opt_value) String(74kf3_2) Value(71) Canonical
+Enum(mips_arch_opt_value) String(74kx) Value(71) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r74kf3_2) Value(71)
+Enum(mips_arch_opt_value) String(r74kx) Value(71)
 
 EnumValue
-Enum(mips_arch_opt_value) String(1004kc) Value(72) Canonical
+Enum(mips_arch_opt_value) String(74kf3_2) Value(72) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r1004kc) Value(72)
+Enum(mips_arch_opt_value) String(r74kf3_2) Value(72)
 
 EnumValue
-Enum(mips_arch_opt_value) String(1004kf2_1) Value(73) Canonical
+Enum(mips_arch_opt_value) String(1004kc) Value(73) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r1004kf2_1) Value(73)
+Enum(mips_arch_opt_value) String(r1004kc) Value(73)
 
 EnumValue
-Enum(mips_arch_opt_value) String(1004kf) Value(74) Canonical
+Enum(mips_arch_opt_value) String(1004kf2_1) Value(74) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r1004kf) Value(74)
+Enum(mips_arch_opt_value) String(r1004kf2_1) Value(74)
 
 EnumValue
-Enum(mips_arch_opt_value) String(1004kf1_1) Value(75) Canonical
+Enum(mips_arch_opt_value) String(1004kf) Value(75) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r1004kf1_1) Value(75)
+Enum(mips_arch_opt_value) String(r1004kf) Value(75)
 
 EnumValue
-Enum(mips_arch_opt_value) String(5kc) Value(76) Canonical
+Enum(mips_arch_opt_value) String(1004kf1_1) Value(76) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r5kc) Value(76)
+Enum(mips_arch_opt_value) String(r1004kf1_1) Value(76)
 
 EnumValue
-Enum(mips_arch_opt_value) String(5kf) Value(77) Canonical
+Enum(mips_arch_opt_value) String(5kc) Value(77) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r5kf) Value(77)
+Enum(mips_arch_opt_value) String(r5kc) Value(77)
 
 EnumValue
-Enum(mips_arch_opt_value) String(20kc) Value(78) Canonical
+Enum(mips_arch_opt_value) String(5kf) Value(78) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(r20kc) Value(78)
+Enum(mips_arch_opt_value) String(r5kf) Value(78)
 
 EnumValue
-Enum(mips_arch_opt_value) String(sb1) Value(79) Canonical
+Enum(mips_arch_opt_value) String(20kc) Value(79) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(sb1a) Value(80) Canonical
+Enum(mips_arch_opt_value) String(r20kc) Value(79)
 
 EnumValue
-Enum(mips_arch_opt_value) String(sr71000) Value(81) Canonical
+Enum(mips_arch_opt_value) String(sb1) Value(80) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(sr71k) Value(81)
+Enum(mips_arch_opt_value) String(sb1a) Value(81) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(xlr) Value(82) Canonical
+Enum(mips_arch_opt_value) String(sr71000) Value(82) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(loongson3a) Value(83) Canonical
+Enum(mips_arch_opt_value) String(sr71k) Value(82)
 
 EnumValue
-Enum(mips_arch_opt_value) String(octeon) Value(84) Canonical
+Enum(mips_arch_opt_value) String(xlr) Value(83) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(octeon+) Value(85) Canonical
+Enum(mips_arch_opt_value) String(loongson3a) Value(84) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(octeon2) Value(86) Canonical
+Enum(mips_arch_opt_value) String(octeon) Value(85) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(xlp) Value(87) Canonical
+Enum(mips_arch_opt_value) String(octeon+) Value(86) Canonical
+
+EnumValue
+Enum(mips_arch_opt_value) String(octeon2) Value(87) Canonical
+
+EnumValue
+Enum(mips_arch_opt_value) String(xlp) Value(88) Canonical
 
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2013-06-03 20:28:18.966933807 +0100
+++ gcc/config/mips/mips.c	2013-06-03 20:29:09.488440901 +0100
@@ -1029,6 +1029,19 @@  static const struct mips_rtx_cost_data m
 		     1,           /* branch_cost */
 		     4            /* memory_latency */
   },
+  { /* R5900 */
+    COSTS_N_INSNS (4),            /* fp_add */
+    COSTS_N_INSNS (4),            /* fp_mult_sf */
+    COSTS_N_INSNS (256),          /* fp_mult_df */
+    COSTS_N_INSNS (8),            /* fp_div_sf */
+    COSTS_N_INSNS (256),          /* fp_div_df */
+    COSTS_N_INSNS (4),            /* int_mult_si */
+    COSTS_N_INSNS (256),          /* int_mult_di */
+    COSTS_N_INSNS (37),           /* int_div_si */
+    COSTS_N_INSNS (256),          /* int_div_di */
+		     1,           /* branch_cost */
+		     4            /* memory_latency */
+  },
   { /* R7000 */
     /* The only costs that are changed here are
        integer multiplication.  */
@@ -13005,6 +13018,7 @@  mips_issue_rate (void)
     case PROCESSOR_R4130:
     case PROCESSOR_R5400:
     case PROCESSOR_R5500:
+    case PROCESSOR_R5900:
     case PROCESSOR_R7000:
     case PROCESSOR_R9000:
     case PROCESSOR_OCTEON:
@@ -16025,8 +16039,9 @@  mips_reorg_process_insns (void)
     cfun->machine->all_noreorder_p = false;
 
   /* Code compiled with -mfix-vr4120 or -mfix-24k can't be all noreorder
-     because we rely on the assembler to work around some errata.  */
-  if (TARGET_FIX_VR4120 || TARGET_FIX_24K)
+     because we rely on the assembler to work around some errata.
+     The r5900 too has several bugs.  */
+  if (TARGET_FIX_VR4120 || TARGET_FIX_24K || TARGET_MIPS5900)
     cfun->machine->all_noreorder_p = false;
 
   /* The same is true for -mfix-vr4130 if we might generate MFLO or
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h	2013-06-03 20:28:18.968933827 +0100
+++ gcc/config/mips/mips.h	2013-06-03 20:34:39.106740933 +0100
@@ -222,6 +222,7 @@  #define TARGET_MIPS4120             (mip
 #define TARGET_MIPS4130             (mips_arch == PROCESSOR_R4130)
 #define TARGET_MIPS5400             (mips_arch == PROCESSOR_R5400)
 #define TARGET_MIPS5500             (mips_arch == PROCESSOR_R5500)
+#define TARGET_MIPS5900             (mips_arch == PROCESSOR_R5900)
 #define TARGET_MIPS7000             (mips_arch == PROCESSOR_R7000)
 #define TARGET_MIPS9000             (mips_arch == PROCESSOR_R9000)
 #define TARGET_OCTEON		    (mips_arch == PROCESSOR_OCTEON	\
@@ -833,7 +834,9 @@  #define ISA_HAS_FP_CONDMOVE	((ISA_MIPS4
 
 /* ISA has the integer conditional move instructions introduced in mips4 and
    ST Loongson 2E/2F.  */
-#define ISA_HAS_CONDMOVE        (ISA_HAS_FP_CONDMOVE || TARGET_LOONGSON_2EF)
+#define ISA_HAS_CONDMOVE        (ISA_HAS_FP_CONDMOVE			\
+				 || TARGET_MIPS5900			\
+				 || TARGET_LOONGSON_2EF)
 
 /* ISA has LDC1 and SDC1.  */
 #define ISA_HAS_LDC1_SDC1	(!ISA_MIPS1 && !TARGET_MIPS16)
@@ -946,6 +949,7 @@  #define ISA_HAS_ROR		((ISA_MIPS32R2				\
 /* ISA has data prefetch instructions.  This controls use of 'pref'.  */
 #define ISA_HAS_PREFETCH	((ISA_MIPS4				\
 				  || TARGET_LOONGSON_2EF		\
+				  || TARGET_MIPS5900			\
 				  || ISA_MIPS32				\
 				  || ISA_MIPS32R2			\
 				  || ISA_MIPS64				\
@@ -1007,15 +1011,18 @@  #define ISA_HAS_DSPR2		(TARGET_DSPR2 &&
    and "addiu $4,$4,1".  */
 #define ISA_HAS_LOAD_DELAY	(ISA_MIPS1				\
 				 && !TARGET_MIPS3900			\
+				 && !TARGET_MIPS5900			\
 				 && !TARGET_MIPS16			\
 				 && !TARGET_MICROMIPS)
 
 /* Likewise mtc1 and mfc1.  */
 #define ISA_HAS_XFER_DELAY	(mips_isa <= 3			\
+				 && !TARGET_MIPS5900		\
 				 && !TARGET_LOONGSON_2EF)
 
 /* Likewise floating-point comparisons.  */
 #define ISA_HAS_FCMP_DELAY	(mips_isa <= 3			\
+				 && !TARGET_MIPS5900		\
 				 && !TARGET_LOONGSON_2EF)
 
 /* True if mflo and mfhi can be immediately followed by instructions
@@ -1035,6 +1042,7 @@  #define ISA_HAS_HILO_INTERLOCKS	(ISA_MIP
 				 || ISA_MIPS64				\
 				 || ISA_MIPS64R2			\
 				 || TARGET_MIPS5500			\
+				 || TARGET_MIPS5900			\
 				 || TARGET_LOONGSON_2EF)
 
 /* ISA includes synci, jr.hb and jalr.hb.  */
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md	2013-06-03 20:28:18.971933857 +0100
+++ gcc/config/mips/mips.md	2013-06-03 20:29:09.490440921 +0100
@@ -55,6 +55,7 @@  (define_enum "processor" [
   r5000
   r5400
   r5500
+  r5900
   r7000
   r8000
   r9000
@@ -755,7 +756,9 @@  (define_mode_iterator P [(SI "Pmode == S
 ;; This mode iterator allows :MOVECC to be used anywhere that a
 ;; conditional-move-type condition is needed.
 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT")
-                              (CC "TARGET_HARD_FLOAT && !TARGET_LOONGSON_2EF")])
+                              (CC "TARGET_HARD_FLOAT
+				   && !TARGET_LOONGSON_2EF
+				   && !TARGET_MIPS5900")])
 
 ;; 32-bit integer moves for which we provide move patterns.
 (define_mode_iterator IMOVE32
Index: libgcc/config.host
===================================================================
--- libgcc/config.host	2013-06-03 20:28:18.958933726 +0100
+++ libgcc/config.host	2013-06-03 20:29:09.485440871 +0100
@@ -739,7 +739,17 @@  mips*-*-netbsd*)			# NetBSD/mips, either
 	;;
 mips*-*-linux*)				# Linux MIPS, either endian.
 	extra_parts="$extra_parts crtfastmath.o"
-	tmake_file="${tmake_file} t-crtfm mips/t-mips16"
+	tmake_file="${tmake_file} t-crtfm"
+	# Check for MicroMIPS support.
+	case ${host} in
+		mips64r5900* | mipsr5900*)
+			# The MIPS16 support code uses floating point
+			# instructions that are not supported on r5900.
+			;;
+		*)
+			tmake_file="${tmake_file} mips/t-mips16"
+			;;
+	esac
 	md_unwind_header=mips/linux-unwind.h
 	if test "${ac_cv_sizeof_long_double}" = 16; then
 		tmake_file="${tmake_file} mips/t-tpbit"
@@ -777,10 +787,18 @@  mips-*-elf* | mipsel-*-elf*)
 	tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
 	extra_parts="$extra_parts crti.o crtn.o"
 	;;
+mipsr5900-*-elf* | mipsr5900el-*-elf*)
+	tmake_file="$tmake_file mips/t-elf mips/t-crtstuff"
+	extra_parts="$extra_parts crti.o crtn.o"
+	;;
 mips64-*-elf* | mips64el-*-elf*)
 	tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
 	extra_parts="$extra_parts crti.o crtn.o"
 	;;
+mips64r5900-*-elf* | mips64r5900el-*-elf*)
+	tmake_file="$tmake_file mips/t-elf mips/t-crtstuff"
+	extra_parts="$extra_parts crti.o crtn.o"
+	;;
 mips64vr-*-elf* | mips64vrel-*-elf*)
 	tmake_file="$tmake_file mips/t-elf mips/t-vr mips/t-crtstuff"
 	extra_parts="$extra_parts crti.o crtn.o"