[patch] MIPS: 64bit floating point support for MIPS32R2

David Ung davidu@mips.com
Tue Nov 7 19:51:00 GMT 2006


MIPS32 rev 2 optionally supports 64bit floating unit.  This patch allows the use
of 64bit floats by passing the -mfp64 option when used along with a MIPS32R2 cpu
(the 24k/34k family with float point all have 64bit floating point units).
Since the default o32 abi assume 32bit float with 32bit integer unit, it 
slightly modifies it that the float parameters $f12/$14 etc are 64bit.

This option is has been tested by building seperate multilibs with -mfp64.
Regression had been ran under GNU sim with -mip32r2 -mfp64.
Bootstrapped native on linux.

OK for mainline?

David.

	* config/mips/mips.md (movdi_32bit): Add !TARGET_FLOAT64 to
	condition pattern.
	(movdi_32bit_mips32r2): New pattern for MIPS32R2 which optionally
	supports a full 64-bit fpu.
	(movdf_hardfloat_64bit, movdf_hardfloat_32bit): Change condition
	from TARGET_64BIT to TARGET_FLOAT64 to allow for cpus with 64bit
	fpu.
	(load_df_low, load_df_high): Remove DF mode from template such
	that DI mode works for these patterns.
	* config/mips/mips.c (override_options): Change test for new
	combination.
	(mips_cannot_change_mode_class): Add test for TARGET_FLOAT64.
	* config/mips/mips.h (ISA_HAS_FP4): Add MIPS32R2 + 64bit fpu
	combination.
	(ASM_SPEC): Pass along -mfp64.

Index: gcc/gcc/gcc/config/mips/mips.md
===================================================================
--- gcc.orig/gcc/gcc/config/mips/mips.md        2006-11-01 15:41:41.000000000 +0000
+++ gcc/gcc/gcc/config/mips/mips.md     2006-11-06 17:39:00.000000000 +0000
@@ -3261,7 +3261,7 @@
  (define_insn "*movdi_32bit"
    [(set (match_operand:DI 0 "nonimmediate_operand" 
"=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
-  "!TARGET_64BIT && !TARGET_MIPS16
+  "!TARGET_64BIT && !TARGET_FLOAT64 && !TARGET_MIPS16
     && (register_operand (operands[0], DImode)
         || reg_or_0_operand (operands[1], DImode))"
    { return mips_output_move (operands[0], operands[1]); }
@@ -3269,6 +3269,18 @@
     (set_attr "mode"    "DI")
     (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])

+;; mips32r2 optionally supports a full 64-bit fpu
+(define_insn "*movdi_32bit_mips32r2"
+  [(set (match_operand:DI 0 "nonimmediate_operand" 
"=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m,*f,*f,*f,*d,*m")
+       (match_operand:DI 1 "move_operand" 
"d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D,*f,*J*d,*m,*f,*f"))]
+  "!TARGET_64BIT && TARGET_FLOAT64 && !TARGET_MIPS16
+   && (register_operand (operands[0], DImode)
+       || reg_or_0_operand (operands[1], DImode))"
+  { return mips_output_move (operands[0], operands[1]); }
+  [(set_attr "type" 
"arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store,fmove,xfer,fpload,xfer,fpstore")
+   (set_attr "mode"    "DI")
+   (set_attr "length"   "8,16,*,*,8,8,8,*,8,*,4,8,*,8,*")])
+
  (define_insn "*movdi_32bit_mips16"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
@@ -3802,7 +3814,7 @@
  (define_insn "*movdf_hardfloat_64bit"
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
         (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FLOAT64
     && (register_operand (operands[0], DFmode)
         || reg_or_0_operand (operands[1], DFmode))"
    { return mips_output_move (operands[0], operands[1]); }
@@ -3813,7 +3825,7 @@
  (define_insn "*movdf_hardfloat_32bit"
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
         (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64
     && (register_operand (operands[0], DFmode)
         || reg_or_0_operand (operands[1], DFmode))"
    { return mips_output_move (operands[0], operands[1]); }
@@ -3951,9 +3963,9 @@

  ;; Load the low word of operand 0 with operand 1.
  (define_insn "load_df_low"
-  [(set (match_operand:DF 0 "register_operand" "=f,f")
-       (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
-                  UNSPEC_LOAD_DF_LOW))]
+  [(set (match_operand 0 "register_operand" "=f,f")
+       (unspec [(match_operand:SI 1 "general_operand" "dJ,m")]
+               UNSPEC_LOAD_DF_LOW))]
    "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
  {
    operands[0] = mips_subword (operands[0], 0);
@@ -3965,10 +3977,10 @@
  ;; Load the high word of operand 0 from operand 1, preserving the value
  ;; in the low word.
  (define_insn "load_df_high"
-  [(set (match_operand:DF 0 "register_operand" "=f,f")
-       (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
-                   (match_operand:DF 2 "register_operand" "0,0")]
-                  UNSPEC_LOAD_DF_HIGH))]
+  [(set (match_operand 0 "register_operand" "=f,f")
+       (unspec [(match_operand:SI 1 "general_operand" "dJ,m")
+               (match_operand:DF 2 "register_operand" "0,0")]
+               UNSPEC_LOAD_DF_HIGH))]
    "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
  {
    operands[0] = mips_subword (operands[0], 1);
Index: gcc/gcc/gcc/config/mips/mips.c
===================================================================
--- gcc.orig/gcc/gcc/config/mips/mips.c 2006-11-03 18:21:38.000000000 +0000
+++ gcc/gcc/gcc/config/mips/mips.c      2006-11-06 17:39:00.000000000 +0000
@@ -4797,7 +4797,7 @@
          only one right answer here.  */
        if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64)
         error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float");
-      else if (!TARGET_64BIT && TARGET_FLOAT64)
+      else if (!TARGET_64BIT && TARGET_FLOAT64 && !ISA_MIPS32R2)
         error ("unsupported combination: %s", "-mgp32 -mfp64");
        else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64)
         error ("unsupported combination: %s", "-mfp64 -msingle-float");
@@ -7632,6 +7632,8 @@
    if (MIN (GET_MODE_SIZE (from), GET_MODE_SIZE (to)) <= UNITS_PER_WORD
        && MAX (GET_MODE_SIZE (from), GET_MODE_SIZE (to)) > UNITS_PER_WORD)
      {
+      if (TARGET_FLOAT64)
+       return reg_classes_intersect_p (FP_REGS, class);
        if (TARGET_BIG_ENDIAN)
         {
           /* When a multi-word value is stored in paired floating-point
Index: gcc/gcc/gcc/config/mips/mips.h
===================================================================
--- gcc.orig/gcc/gcc/config/mips/mips.h 2006-11-06 17:20:29.000000000 +0000
+++ gcc/gcc/gcc/config/mips/mips.h      2006-11-06 17:39:00.000000000 +0000
@@ -611,6 +611,7 @@
     FP madd and msub instructions, and the FP recip and recip sqrt
     instructions.  */
  #define ISA_HAS_FP4             ((ISA_MIPS4                            \
+                                 || (ISA_MIPS32R2 && TARGET_FLOAT64)   \
                                   || ISA_MIPS64)                        \
                                  && !TARGET_MIPS16)

@@ -840,6 +841,7 @@
  %(subtarget_asm_debugging_spec) \
  %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} \
  %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
+%{mfp32} %{mfp64} \
  %{mshared} %{mno-shared} \
  %{msym32} %{mno-sym32} \
  %{mtune=*} %{v} \



More information about the Gcc-patches mailing list