This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch]: MIPS: Add mfhc1/mthc1 patterns for MIPS32R2 64bit fpu



This extends my previous patch for adding -mfp64 for MIPS32R2 to allow the use of mfhc1/mthc1 instructions to access the high half of the FPU register.
Bootstrapped on linux.


David.

	* config/mips/mips.md (define_constants): Add UNSPEC_MFHC1,
	UNSPEC_MTHC1.
	(mthc1): New pattern to generate MTHC1 instruction.
	(mfhc1): New pattern to generate MFHC1 instruction.
	* config/mips/mips.c (mips_split_64bit_move): Use gen_mthc1 to set
	high part of FP register when in 64-bit FP register mode.
	Similarly use gen_mfhc1 to load high part of FP register.
	* config/mips/mips.h (ISA_HAS_MXHC1): True is ISA supports mfhc1
	and mthc1 opcodes.


Index: gcc/gcc/gcc/config/mips/mips.md
===================================================================
--- gcc.orig/gcc/gcc/config/mips/mips.md	2006-11-06 17:39:00.000000000 +0000
+++ gcc/gcc/gcc/config/mips/mips.md	2006-11-07 19:34:56.000000000 +0000
@@ -47,6 +47,8 @@
    (UNSPEC_MFHILO		26)
    (UNSPEC_TLS_LDM		27)
    (UNSPEC_TLS_GET_TP		28)
+   (UNSPEC_MFHC1		31)
+   (UNSPEC_MTHC1		32)
 
    (UNSPEC_ADDRESS_FIRST	100)
 
@@ -4003,6 +4005,29 @@
   [(set_attr "type"	"xfer,fpstore")
    (set_attr "mode"	"SF")])
 
+;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
+;; value in the low word.
+(define_insn "mthc1"
+  [(set (match_operand 0 "register_operand" "=f")
+	(unspec [(match_operand:SI 1 "general_operand" "dJ")
+		 (match_operand 2 "register_operand" "0")]
+		UNSPEC_MTHC1))]
+  "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
+  "mthc1\t%z1,%0"
+  [(set_attr "type"	"xfer")
+   (set_attr "mode"	"SF")])
+
+;; Move high word of operand 1 to operand 0 using mfhc1.  The corresponding
+;; low-word move is done in the normal way.
+(define_insn "mfhc1"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+	(unspec:SI [(match_operand 1 "register_operand" "f")]
+		   UNSPEC_MFHC1))]
+  "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
+  "mfhc1\t%0,%1"
+  [(set_attr "type"	"xfer")
+   (set_attr "mode"	"SF")])
+
 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
 ;; of _gp from the start of this function.  Operand 1 is the incoming
 ;; function address.
Index: gcc/gcc/gcc/config/mips/mips.c
===================================================================
--- gcc.orig/gcc/gcc/config/mips/mips.c	2006-11-06 17:39:00.000000000 +0000
+++ gcc/gcc/gcc/config/mips/mips.c	2006-11-07 19:34:56.000000000 +0000
@@ -2840,14 +2840,21 @@
     {
       /* Loading an FPR from memory or from GPRs.  */
       emit_insn (gen_load_df_low (copy_rtx (dest), mips_subword (src, 0)));
-      emit_insn (gen_load_df_high (dest, mips_subword (src, 1),
-				   copy_rtx (dest)));
+      if (ISA_HAS_MXHC1 && GET_CODE (src) != MEM)
+	emit_insn (gen_mthc1 (dest, mips_subword (src, 1),
+			      copy_rtx (dest)));
+      else
+	emit_insn (gen_load_df_high (dest, mips_subword (src, 1),
+				     copy_rtx (dest)));
     }
   else if (FP_REG_RTX_P (src))
     {
       /* Storing an FPR into memory or GPRs.  */
       emit_move_insn (mips_subword (dest, 0), mips_subword (src, 0));
-      emit_insn (gen_store_df_high (mips_subword (dest, 1), src));
+      if (ISA_HAS_MXHC1 && GET_CODE (dest) != MEM)
+	emit_insn (gen_mfhc1 (mips_subword (dest, 1), src));
+      else
+	emit_insn (gen_store_df_high (mips_subword (dest, 1), src));
     }
   else
     {
Index: gcc/gcc/gcc/config/mips/mips.h
===================================================================
--- gcc.orig/gcc/gcc/config/mips/mips.h	2006-11-06 17:39:00.000000000 +0000
+++ gcc/gcc/gcc/config/mips/mips.h	2006-11-07 19:34:56.000000000 +0000
@@ -723,6 +723,9 @@
                                  && (ISA_MIPS32R2                      \
                                      ))
 
+/* ISA has instructions for accessing top part of 64 bit fp regs */
+#define ISA_HAS_MXHC1		(TARGET_FLOAT64 && ISA_MIPS32R2)
+
 /* True if the result of a load is not available to the next instruction.
    A nop will then be needed between instructions like "lw $4,..."
    and "addiu $4,$4,1".  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]