diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/config.sub gcc-svn-20130105-mips64r5900el-linux-patched/config.sub
--- ../gcc-svn-20130105.orig/config.sub	2013-01-05 20:06:32.859960482 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/config.sub	2013-01-06 19:11:56.332755480 +0100
@@ -284,6 +284,8 @@ case $basic_machine in
 	| mips64vr4300 | mips64vr4300el \
 	| mips64vr5000 | mips64vr5000el \
 	| mips64vr5900 | mips64vr5900el \
+	| mips64r5900 | mips64r5900el \
+	| mipsr5900 | mipsr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
 	| mipsisa64 | mipsisa64el \
@@ -401,6 +403,8 @@ case $basic_machine in
 	| mips64vr4300-* | mips64vr4300el-* \
 	| mips64vr5000-* | mips64vr5000el-* \
 	| mips64vr5900-* | mips64vr5900el-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mipsr5900-* | mipsr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
 	| mipsisa64-* | mipsisa64el-* \
diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/gcc/config/mips/mips.c gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config/mips/mips.c
--- ../gcc-svn-20130105.orig/gcc/config/mips/mips.c	2013-01-05 20:03:24.231962472 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config/mips/mips.c	2013-01-06 19:11:56.336755480 +0100
@@ -1025,6 +1025,19 @@ static const struct mips_rtx_cost_data
 		     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.  */
@@ -12793,6 +12806,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:
@@ -15573,6 +15587,7 @@ vr4130_align_insns (void)
     }
   dfa_finish ();
 }
+
 
 /* This structure records that the current function has a LO_SUM
    involving SYMBOL_REF or LABEL_REF BASE and that MAX_OFFSET is
@@ -15801,6 +15816,11 @@ mips_reorg_process_insns (void)
   if (TARGET_FIX_VR4120 || TARGET_FIX_24K)
     cfun->machine->all_noreorder_p = false;
 
+  /* Code compiled for R5900 can't be all noreorder because
+     we rely on the assembler to work around some errata.  */
+  if (TARGET_MIPS5900)
+    cfun->machine->all_noreorder_p = false;
+
   /* The same is true for -mfix-vr4130 if we might generate MFLO or
      MFHI instructions.  Note that we avoid using MFLO and MFHI if
      the VR4130 MACC and DMACC instructions are available instead;
diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/gcc/config/mips/mips-cpus.def gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config/mips/mips-cpus.def
--- ../gcc-svn-20130105.orig/gcc/config/mips/mips-cpus.def	2013-01-05 20:03:24.227962471 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config/mips/mips-cpus.def	2013-01-06 19:11:56.336755480 +0100
@@ -71,6 +71,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)
diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/gcc/config/mips/mips.h gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config/mips/mips.h
--- ../gcc-svn-20130105.orig/gcc/config/mips/mips.h	2013-01-05 20:03:24.231962472 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config/mips/mips.h	2013-01-06 19:11:56.336755480 +0100
@@ -215,6 +215,7 @@ struct mips_cpu_info {
 #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	\
@@ -245,6 +246,7 @@ struct mips_cpu_info {
 #define TUNE_MIPS5000               (mips_tune == PROCESSOR_R5000)
 #define TUNE_MIPS5400               (mips_tune == PROCESSOR_R5400)
 #define TUNE_MIPS5500               (mips_tune == PROCESSOR_R5500)
+#define TUNE_MIPS5900               (mips_tune == PROCESSOR_R5900)
 #define TUNE_MIPS6000               (mips_tune == PROCESSOR_R6000)
 #define TUNE_MIPS7000               (mips_tune == PROCESSOR_R7000)
 #define TUNE_MIPS9000               (mips_tune == PROCESSOR_R9000)
@@ -815,6 +817,7 @@ struct mips_cpu_info {
 #define ISA_HAS_MUL3		((TARGET_MIPS3900                       \
 				  || TARGET_MIPS5400			\
 				  || TARGET_MIPS5500			\
+				  || TARGET_MIPS5900			\
 				  || TARGET_MIPS7000			\
 				  || TARGET_MIPS9000			\
 				  || TARGET_MAD				\
@@ -829,6 +832,21 @@ struct mips_cpu_info {
 				 && TARGET_OCTEON			\
 				 && !TARGET_MIPS16)
 
+/* Target supports instructions dmult and dmultu (integer). */
+#define TARGET_HAS_DMULT	(TARGET_64BIT				\
+				 && !TARGET_MIPS5900)
+
+/* Target supports instructions mult and multu in 32 bit mode (integer). */
+#define TARGET_HAS_MULT		(mips_isa >= 1)
+
+/* Target supports instructions dmult and dmultu (integer). */
+#define TARGET_HAS_DDIV		(TARGET_64BIT				\
+				 && !TARGET_MIPS5900)
+
+/* Target supports instructions mult and multu in 32 bit mode (integer). */
+#define TARGET_HAS_DIV		(mips_isa >= 1)
+
+
 /* ISA has the floating-point conditional move instructions introduced
    in mips4.  */
 #define ISA_HAS_FP_CONDMOVE	((ISA_MIPS4				\
@@ -841,10 +859,10 @@ struct mips_cpu_info {
 
 /* 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_LOONGSON_2EF || TARGET_MIPS5900)
 
 /* ISA has LDC1 and SDC1.  */
-#define ISA_HAS_LDC1_SDC1	(!ISA_MIPS1 && !TARGET_MIPS16)
+#define ISA_HAS_LDC1_SDC1	(!ISA_MIPS1 && !TARGET_MIPS16 && !TARGET_MIPS5900)
 
 /* ISA has the mips4 FP condition code instructions: FP-compare to CC,
    branch on CC, and move (both FP and non-FP) on CC.  */
@@ -884,7 +902,7 @@ struct mips_cpu_info {
 #define ISA_HAS_FP_MADD4_MSUB4  ISA_HAS_FP4
 
 /* ISA has floating-point madd and msub instructions 'c = a * b [+-] c'.  */
-#define ISA_HAS_FP_MADD3_MSUB3  TARGET_LOONGSON_2EF
+#define ISA_HAS_FP_MADD3_MSUB3  (TARGET_LOONGSON_2EF || TARGET_MIPS5900)
 
 /* ISA has floating-point nmadd and nmsub instructions
    'd = -((a * b) [+-] c)'.  */
@@ -955,6 +973,7 @@ struct mips_cpu_info {
 /* 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				\
@@ -974,7 +993,11 @@ struct mips_cpu_info {
 /* True if trunc.w.s and trunc.w.d are real (not synthetic)
    instructions.  Both require TARGET_HARD_FLOAT, and trunc.w.d
    also requires TARGET_DOUBLE_FLOAT.  */
-#define ISA_HAS_TRUNC_W		(!ISA_MIPS1)
+#define ISA_HAS_TRUNC_W_D	(!ISA_MIPS1)
+
+/* True if trunc.w.s is real (not synthetic) instructions.
+   Requires TARGET_HARD_FLOAT.  */
+#define ISA_HAS_TRUNC_W_S	(ISA_HAS_TRUNC_W_D || TARGET_MIPS5900)
 
 /* ISA includes the MIPS32r2 seb and seh instructions.  */
 #define ISA_HAS_SEB_SEH		((ISA_MIPS32R2		\
@@ -1015,15 +1038,18 @@ struct mips_cpu_info {
    and "addiu $4,$4,1".  */
 #define ISA_HAS_LOAD_DELAY	(ISA_MIPS1				\
 				 && !TARGET_MIPS3900			\
-				 && !TARGET_MIPS16)
+				 && !TARGET_MIPS16			\
+				 && !TARGET_MIPS5900)
 
 /* Likewise mtc1 and mfc1.  */
 #define ISA_HAS_XFER_DELAY	(mips_isa <= 3			\
-				 && !TARGET_LOONGSON_2EF)
+				 && !TARGET_LOONGSON_2EF	\
+				 && !TARGET_MIPS5900)
 
 /* Likewise floating-point comparisons.  */
 #define ISA_HAS_FCMP_DELAY	(mips_isa <= 3			\
-				 && !TARGET_LOONGSON_2EF)
+				 && !TARGET_LOONGSON_2EF	\
+				 && !TARGET_MIPS5900)
 
 /* True if mflo and mfhi can be immediately followed by instructions
    which write to the HI and LO registers.
@@ -1042,6 +1068,7 @@ struct mips_cpu_info {
 				 || ISA_MIPS64				\
 				 || ISA_MIPS64R2			\
 				 || TARGET_MIPS5500			\
+				 || TARGET_MIPS5900			\
 				 || TARGET_LOONGSON_2EF)
 
 /* ISA includes synci, jr.hb and jalr.hb.  */
diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/gcc/config/mips/mips.md gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config/mips/mips.md
--- ../gcc-svn-20130105.orig/gcc/config/mips/mips.md	2013-01-05 20:03:24.227962471 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config/mips/mips.md	2013-01-06 20:08:35.056750990 +0100
@@ -58,6 +58,7 @@
   r5000
   r5400
   r5500
+  r5900
   r7000
   r8000
   r9000
@@ -726,7 +727,7 @@
 ;; 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
@@ -1448,7 +1449,7 @@
   [(set (match_operand:GPR 0 "register_operand")
 	(mult:GPR (match_operand:GPR 1 "register_operand")
 		  (match_operand:GPR 2 "register_operand")))]
-  ""
+  "TARGET_HAS_<D>MULT"
 {
   rtx lo;
 
@@ -1490,11 +1491,11 @@
 	(mult:GPR (match_operand:GPR 1 "register_operand" "d,d")
 		  (match_operand:GPR 2 "register_operand" "d,d")))
    (clobber (match_scratch:GPR 3 "=l,X"))]
-  "ISA_HAS_<D>MUL3"
+  "ISA_HAS_<D>MUL3 && TARGET_HAS_<D>MULT"
 {
   if (which_alternative == 1)
     return "<d>mult\t%1,%2";
-  if (<MODE>mode == SImode && TARGET_MIPS3900)
+  if (<MODE>mode == SImode && (TARGET_MIPS3900 || TARGET_MIPS5900))
     return "mult\t%0,%1,%2";
   return "<d>mul\t%0,%1,%2";
 }
@@ -1528,7 +1529,7 @@
   [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
 	(mult:GPR (match_operand:GPR 1 "register_operand" "d")
 		  (match_operand:GPR 2 "register_operand" "d")))]
-  "!TARGET_FIX_R4000"
+  "!TARGET_FIX_R4000 && TARGET_HAS_<D>MULT"
   "<d>mult\t%1,%2"
   [(set_attr "type" "imul")
    (set_attr "mode" "<MODE>")])
@@ -1538,7 +1539,7 @@
 	(mult:GPR (match_operand:GPR 1 "register_operand" "d")
 		  (match_operand:GPR 2 "register_operand" "d")))
    (clobber (match_scratch:GPR 3 "=l"))]
-  "TARGET_FIX_R4000"
+  "TARGET_FIX_R4000 && TARGET_HAS_<D>MULT"
   "<d>mult\t%1,%2\;mflo\t%0"
   [(set_attr "type" "imul")
    (set_attr "mode" "<MODE>")
@@ -1872,7 +1873,7 @@
   [(set (match_operand:DI 0 "register_operand")
 	(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
 		 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
-  "mips_mulsidi3_gen_fn (<CODE>) != NULL"
+  "mips_mulsidi3_gen_fn (<CODE>) != NULL && TARGET_HAS_DMULT"
 {
   mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn (<CODE>);
   emit_insn (fn (operands[0], operands[1], operands[2]));
@@ -1900,7 +1901,7 @@
   [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
 	(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
 		 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
-  "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP)"
+  "(!TARGET_64BIT || (TARGET_64BIT && !TARGET_HAS_DMULT)) && (!TARGET_FIX_R4000 || ISA_HAS_DSP)"
 {
   if (ISA_HAS_DSP_MULT)
     return "mult<u>\t%q0,%1,%2";
@@ -1927,7 +1928,7 @@
 		 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
    (clobber (match_scratch:TI 3 "=x"))
    (clobber (match_scratch:DI 4 "=d"))]
-  "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16"
+  "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16 && TARGET_HAS_DMULT"
   "#"
   "&& reload_completed"
   [(const_int 0)]
@@ -2105,7 +2106,7 @@
 {
   rtx hilo;
 
-  if (TARGET_64BIT)
+  if (TARGET_64BIT && TARGET_HAS_DMULT)
     {
       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
       emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
@@ -2159,7 +2160,7 @@
 	  (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
 		   (any_extend:TI (match_operand:DI 2 "register_operand")))
 	  (const_int 64))))]
-  "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
+  "TARGET_64BIT && TARGET_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
 {
   if (TARGET_MIPS16)
     emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
@@ -2180,6 +2181,7 @@
    (clobber (match_scratch:DI 3 "=l"))]
   "TARGET_64BIT
    && !TARGET_MIPS16
+   && TARGET_HAS_DMULT
    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
   { return TARGET_FIX_R4000 ? "dmult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
   "&& reload_completed && !TARGET_FIX_R4000"
@@ -2200,7 +2202,7 @@
 	  (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
 		   (any_extend:TI (match_operand:DI 2 "register_operand")))
 	  (const_int 64))))]
-  ""
+  "TARGET_HAS_DMULT"
 {
   rtx hilo;
 
@@ -2214,7 +2216,7 @@
   [(set (match_operand:TI 0 "register_operand")
 	(mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
 		 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
-  "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
+  "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120) && TARGET_HAS_DMULT"
 {
   rtx hilo;
 
@@ -2237,6 +2239,7 @@
 	(mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
 		 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))]
   "TARGET_64BIT
+   && TARGET_HAS_DMULT
    && !TARGET_FIX_R4000
    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
   "dmult<u>\t%1,%2"
@@ -2250,6 +2253,7 @@
    (clobber (match_scratch:TI 3 "=x"))]
   "TARGET_64BIT
    && TARGET_FIX_R4000
+   && TARGET_HAS_DMULT
    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
   "dmult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
   [(set_attr "type" "imul")
@@ -2537,7 +2541,7 @@
    (set (match_operand:GPR 3 "register_operand")
 	(mod:GPR (match_dup 1)
 		 (match_dup 2)))]
-  "!TARGET_FIX_VR4120"
+  "!TARGET_FIX_VR4120 && TARGET_HAS_<D>DIV"
 {
   if (TARGET_MIPS16)
     {
@@ -2558,7 +2562,7 @@
    (set (match_operand:GPR 3 "register_operand" "=d")
 	(mod:GPR (match_dup 1)
 		 (match_dup 2)))]
-  "!TARGET_FIX_VR4120 && !TARGET_MIPS16"
+  "!TARGET_FIX_VR4120 && !TARGET_MIPS16 && TARGET_HAS_<D>DIV"
   "#"
   "&& reload_completed"
   [(const_int 0)]
@@ -2577,7 +2581,7 @@
    (set (match_operand:GPR 3 "register_operand")
 	(umod:GPR (match_dup 1)
 		  (match_dup 2)))]
-  ""
+  "TARGET_HAS_<D>DIV"
 {
   if (TARGET_MIPS16)
     {
@@ -2598,7 +2602,7 @@
    (set (match_operand:GPR 3 "register_operand" "=d")
 	(umod:GPR (match_dup 1)
 		  (match_dup 2)))]
-  "!TARGET_MIPS16"
+  "!TARGET_MIPS16 && TARGET_HAS_<D>DIV"
   "#"
   "reload_completed"
   [(const_int 0)]
@@ -2614,7 +2618,7 @@
   [(set (match_operand:GPR 0 "register_operand")
 	(any_mod:GPR (match_operand:GPR 1 "register_operand")
 		     (match_operand:GPR 2 "register_operand")))]
-  ""
+  "TARGET_HAS_<D>DIV"
 {
   rtx hilo;
 
@@ -2641,7 +2645,7 @@
 	  [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
 			(match_operand:GPR 2 "register_operand" "d"))]
 	  UNSPEC_SET_HILO))]
-  ""
+  "TARGET_HAS_<D>DIV"
   { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); }
   [(set_attr "type" "idiv")
    (set_attr "mode" "<GPR:MODE>")])
@@ -3464,7 +3468,7 @@
 	(fix:SI (match_operand:DF 1 "register_operand")))]
   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
 {
-  if (!ISA_HAS_TRUNC_W)
+  if (!ISA_HAS_TRUNC_W_D)
     {
       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
       DONE;
@@ -3474,7 +3478,7 @@
 (define_insn "fix_truncdfsi2_insn"
   [(set (match_operand:SI 0 "register_operand" "=f")
 	(fix:SI (match_operand:DF 1 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W_D"
   "trunc.w.d %0,%1"
   [(set_attr "type"	"fcvt")
    (set_attr "mode"	"DF")
@@ -3484,7 +3488,7 @@
   [(set (match_operand:SI 0 "register_operand" "=f")
 	(fix:SI (match_operand:DF 1 "register_operand" "f")))
    (clobber (match_scratch:DF 2 "=d"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W_D"
 {
   if (mips_nomacro.nesting_level > 0)
     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
@@ -3501,7 +3505,7 @@
 	(fix:SI (match_operand:SF 1 "register_operand")))]
   "TARGET_HARD_FLOAT"
 {
-  if (!ISA_HAS_TRUNC_W)
+  if (!ISA_HAS_TRUNC_W_S)
     {
       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
       DONE;
@@ -3511,7 +3515,7 @@
 (define_insn "fix_truncsfsi2_insn"
   [(set (match_operand:SI 0 "register_operand" "=f")
 	(fix:SI (match_operand:SF 1 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
+  "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W_S"
   "trunc.w.s %0,%1"
   [(set_attr "type"	"fcvt")
    (set_attr "mode"	"SF")
@@ -3521,7 +3525,7 @@
   [(set (match_operand:SI 0 "register_operand" "=f")
 	(fix:SI (match_operand:SF 1 "register_operand" "f")))
    (clobber (match_scratch:SF 2 "=d"))]
-  "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
+  "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W_S"
 {
   if (mips_nomacro.nesting_level > 0)
     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/gcc/config.gcc gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config.gcc
--- ../gcc-svn-20130105.orig/gcc/config.gcc	2013-01-05 20:03:33.659962367 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/gcc/config.gcc	2013-01-06 19:11:56.340755480 +0100
@@ -1881,11 +1881,17 @@ mipsisa64sb1-*-elf* | mipsisa64sb1el-*-e
 	target_cpu_default="MASK_64BIT|MASK_FLOAT64"
 	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"
 	;;
-mips64-*-elf* | mips64el-*-elf*)
+mips64r5900-*-elf* | mips64r5900el-*-elf*)
+	tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
+	tmake_file="mips/t-elf"
+	target_cpu_default="MASK_64BIT"
+	tm_defines="${tm_defines} MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_N32"
+	;;
+mips64-*-elf* | mips64el-*-elf* | mips64r5900-*-elf* | mips64r5900el-*-elf*)
 	tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
 	tmake_file="mips/t-elf"
 	target_cpu_default="MASK_64BIT|MASK_FLOAT64"
@@ -2910,6 +2916,26 @@ if test x$with_cpu = x ; then
 	  ;;
       esac
       ;;
+    mips64r5900-*-*|mips64r5900el-*-*)
+      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:
+	with_float=soft
+      fi
+      ;;
+    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
+      ;;
     mips*-*-vxworks)
       with_arch=mips2
       ;;
@@ -3374,7 +3400,7 @@ case "${target}" in
 		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
 			;;
 		*)
diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/libgcc/config.host gcc-svn-20130105-mips64r5900el-linux-patched/libgcc/config.host
--- ../gcc-svn-20130105.orig/libgcc/config.host	2013-01-05 19:28:43.695984006 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/libgcc/config.host	2013-01-06 19:11:56.340755480 +0100
@@ -761,10 +761,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"
diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/libgcc/Makefile.in gcc-svn-20130105-mips64r5900el-linux-patched/libgcc/Makefile.in
--- ../gcc-svn-20130105.orig/libgcc/Makefile.in	2013-01-05 19:28:43.695984006 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/libgcc/Makefile.in	2013-01-06 19:51:13.488752493 +0100
@@ -293,6 +293,9 @@ MULTIOSSUBDIR := $(shell if test $(MULTI
 inst_libdir = $(libsubdir)$(MULTISUBDIR)
 inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)
 
+# Get mips type: __mips or __mips64 is defined as GCC macro:
+MIPSTYPE := $(shell $(CC) $(CFLAGS) -dM -E - < /dev/null | grep -e "\<__mips\>" -e "\<__mips64\>" | (read define type value; echo $$type))
+
 gcc_compile_bare = $(CC) $(INTERNAL_CFLAGS)
 compile_deps = -MT $@ -MD -MP -MF $(basename $@).dep
 gcc_compile = $(gcc_compile_bare) -o $@ $(compile_deps)
@@ -401,7 +404,8 @@ LIB2ADDEHSTATIC += $(srcdir)/emutls.c
 LIB2ADDEHSHARED += $(srcdir)/emutls.c
 
 # Library members defined in libgcc2.c.
-lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2	   \
+lib2difuncs = _muldi3
+lib2funcs = $(lib2difuncs) _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2 \
 	    _clear_cache _trampoline __main _absvsi2 \
 	    _absvdi2 _addvsi3 _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 \
 	    _negvsi2 _negvdi2 _ctors _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2  \
@@ -427,7 +431,8 @@ endif
 
 # These might cause a divide overflow trap and so are compiled with
 # unwinder info.
-LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udiv_w_sdiv _udivmoddi4
+LIB2_DIVMODDI_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udivmoddi4
+LIB2_DIVMOD_FUNCS = $(LIB2_DIVMODDI_FUNCS) _udiv_w_sdiv
 
 # Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
 # defined as optimized assembly code in LIB1ASMFUNCS or as C code
@@ -459,12 +464,26 @@ lib2funcs-o = $(patsubst %,%$(objext),$(
 $(lib2funcs-o): %$(objext): $(srcdir)/libgcc2.c
 	$(gcc_compile) -DL$* -c $< $(vis_hide)
 libgcc-objects += $(lib2funcs-o)
+ifeq ($(MIPSTYPE),__mips64)
+# Build functions needed by MIPS r5900.
+lib2difuncs-o = $(patsubst %,%$(objext),$(addsuffix _32bit,$(lib2difuncs)))
+$(lib2difuncs-o): %$(objext): $(srcdir)/libgcc2.c
+	$(gcc_compile) -DL$(subst _32bit,,$*) -DLIBGCC2_UNITS_PER_WORD=4 -c $< $(vis_hide)
+libgcc-objects += $(lib2difuncs-o)
+endif
 
 ifeq ($(enable_shared),yes)
 lib2funcs-s-o = $(patsubst %,%_s$(objext),$(lib2funcs))
 $(lib2funcs-s-o): %_s$(objext): $(srcdir)/libgcc2.c
 	$(gcc_s_compile) -DL$* -c $<
 libgcc-s-objects += $(lib2funcs-s-o)
+ifeq ($(MIPSTYPE),__mips64)
+# Build functions needed by MIPS r5900.
+lib2difuncs-s-o = $(patsubst %,%_s$(objext),$(addsuffix _32bit,$(lib2difuncs)))
+$(lib2difuncs-s-o): %_s$(objext): $(srcdir)/libgcc2.c
+	$(gcc_s_compile) -DL$(subst _32bit,,$*) -DLIBGCC2_UNITS_PER_WORD=4 -c $<
+libgcc-s-objects += $(lib2difuncs-s-o)
+endif
 endif
 
 ifneq ($(LIB2_SIDITI_CONV_FUNCS),)
@@ -501,6 +520,14 @@ $(lib2-divmod-o): %$(objext): $(srcdir)/
 	$(gcc_compile) -DL$* -c $< \
 	  $(LIB2_DIVMOD_EXCEPTION_FLAGS) $(vis_hide)
 libgcc-objects += $(lib2-divmod-o)
+ifeq ($(MIPSTYPE),__mips64)
+# Build functions needed by MIPS r5900.
+lib2-divmoddi-o = $(patsubst %,%$(objext),$(addsuffix _32bit,$(LIB2_DIVMODDI_FUNCS)))
+$(lib2-divmoddi-o): %$(objext): $(srcdir)/libgcc2.c
+	$(gcc_compile) -DL$(subst _32bit,,$*) -DLIBGCC2_UNITS_PER_WORD=4 -c $< \
+	  $(LIB2_DIVMOD_EXCEPTION_FLAGS) $(vis_hide)
+libgcc-objects += $(lib2-divmoddi-o)
+endif
 
 ifeq ($(enable_shared),yes)
 lib2-divmod-s-o = $(patsubst %,%_s$(objext),$(LIB2_DIVMOD_FUNCS))
@@ -508,6 +535,14 @@ $(lib2-divmod-s-o): %_s$(objext): $(srcd
 	$(gcc_s_compile) -DL$* -c $< \
 	  $(LIB2_DIVMOD_EXCEPTION_FLAGS)
 libgcc-s-objects += $(lib2-divmod-s-o)
+ifeq ($(MIPSTYPE),__mips64)
+# Build functions needed by MIPS r5900.
+lib2-divmoddi-s-o = $(patsubst %,%_s$(objext),$(addsuffix _32bit,$(LIB2_DIVMODDI_FUNCS)))
+$(lib2-divmoddi-s-o): %_s$(objext): $(srcdir)/libgcc2.c
+	$(gcc_s_compile) -DL$(subst _32bit,,$*) -DLIBGCC2_UNITS_PER_WORD=4 -c $< \
+	  $(LIB2_DIVMOD_EXCEPTION_FLAGS)
+libgcc-s-objects += $(lib2-divmoddi-s-o)
+endif
 endif
 
 ifeq ($(TPBIT),)
diff -Nurp '--exclude=build01' ../gcc-svn-20130105.orig/libstdc++-v3/configure.host gcc-svn-20130105-mips64r5900el-linux-patched/libstdc++-v3/configure.host
--- ../gcc-svn-20130105.orig/libstdc++-v3/configure.host	2013-01-05 19:09:50.603996241 +0100
+++ gcc-svn-20130105-mips64r5900el-linux-patched/libstdc++-v3/configure.host	2013-01-06 19:11:56.340755480 +0100
@@ -322,6 +322,11 @@ esac
 # Set any OS-dependent and CPU-dependent bits.
 # THIS TABLE IS SORTED.  KEEP IT THAT WAY.
 case "${host}" in
+	mips*)
+        atomicity_dir="cpu/generic"
+	;;
+esac
+case "${host}" in
   *-*-linux*)
     case "${host_cpu}" in
       i[567]86)
