diff mbox

Convert SPARC to LRA

Message ID 20150917.011159.819766758265264674.davem@davemloft.net
State New
Headers show

Commit Message

David Miller Sept. 17, 2015, 8:11 a.m. UTC
From: David Miller <davem@davemloft.net>
Date: Mon, 14 Sep 2015 11:30:29 -0700 (PDT)

> There are some other issues I'm having troubles resolving for 64-bit
> native bootstraps as well, and I am probably going to revert the LRA
> sparc changes unless I can resolve them by the end of today.

So I was actually able to resolve these problems, and committed the
following patch.

The big take-aways are:

1) Since we can only access SFmode/SImode/etc. in FP_REGS but not
   necessarily in EXTRA_FP_REGS, we have to tell LRA that secondary
   memory is needed when moving such a mode between those two classes.

2) HARD_REGNO_CALLER_SAVE_MODE's default should really be reconsidered.
   If the caller has an explicit mode in mind we should just use it
   instead just going to choose_hard_reg_mode().  That causes stupid
   things like using a DFmode register to spill an SFmode value and
   all the subregging that results from that.

3) It's amazing how much we get away with in RELOAD, particular wrt.
   to addressing.  Here all of the "(set x (HIGH (SYMBOLIC...)))"
   were always available even when flag_pic and this was never
   noticed before.
diff mbox

Patch

====================
[PATCH] Fix LRA regressions on 64-bit SPARC.

gcc/
	* config/sparc/sparc-protos.h (sparc_secondary_memory_needed):
	Declare.
	* config/sparc/sparc.c (sparc_secondary_memory_needed): New
	function.
	* config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED): Use it.
	(HARD_REGNO_CALLER_SAVE_MODE): Define.
	* config/sparc/sparc.md (sethi_di_medlow, losum_di_medlow, seth44)
	(setm44, setl44, sethh, setlm, sethm, setlo, embmedany_sethi)
	(embmedany_losum, embmedany_brsum, embmedany_textuhi)
	(embmedany_texthi, embmedany_textulo, embmedany_textlo): Do not
	provide when flag_pic.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227847 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                   | 14 ++++++++++++++
 gcc/config/sparc/sparc-protos.h |  2 ++
 gcc/config/sparc/sparc.c        | 20 ++++++++++++++++++++
 gcc/config/sparc/sparc.h        | 14 +++++++++-----
 gcc/config/sparc/sparc.md       | 32 ++++++++++++++++----------------
 5 files changed, 61 insertions(+), 21 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 76566ca..42faf2e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@ 
+2015-09-17  David S. Miller  <davem@davemloft.net>
+
+	* config/sparc/sparc-protos.h (sparc_secondary_memory_needed):
+	Declare.
+	* config/sparc/sparc.c (sparc_secondary_memory_needed): New
+	function.
+	* config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED): Use it.
+	(HARD_REGNO_CALLER_SAVE_MODE): Define.
+	* config/sparc/sparc.md (sethi_di_medlow, losum_di_medlow, seth44)
+	(setm44, setl44, sethh, setlm, sethm, setlo, embmedany_sethi)
+	(embmedany_losum, embmedany_brsum, embmedany_textuhi)
+	(embmedany_texthi, embmedany_textulo, embmedany_textlo): Do not
+	provide when flag_pic.
+
 2015-09-17  Kaz Kojima  <kkojima@gcc.gnu.org>
 
 	* config/sh/sh.c (label_ref_list_d_pool): Adjust to
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index 1431437..18192fd 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -62,6 +62,8 @@  extern bool constant_address_p (rtx);
 extern bool legitimate_pic_operand_p (rtx);
 extern rtx sparc_legitimize_reload_address (rtx, machine_mode, int, int,
 					    int, int *win);
+extern bool sparc_secondary_memory_needed (enum reg_class, enum reg_class,
+					   machine_mode);
 extern void load_got_register (void);
 extern void sparc_emit_call_insn (rtx, rtx);
 extern void sparc_defer_case_vector (rtx, rtx, int);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index b41800c..f4ad68d 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -12283,6 +12283,26 @@  sparc_expand_vector_init (rtx target, rtx vals)
   emit_move_insn (target, mem);
 }
 
+bool sparc_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
+				    machine_mode mode)
+{
+  if (FP_REG_CLASS_P (class1) != FP_REG_CLASS_P (class2))
+    {
+      if (! TARGET_VIS3
+	  || GET_MODE_SIZE (mode) > 8
+	  || GET_MODE_SIZE (mode) < 4)
+	return true;
+      return false;
+    }
+
+  if (GET_MODE_SIZE (mode) == 4
+      && ((class1 == FP_REGS && class2 == EXTRA_FP_REGS)
+	  || (class1 == EXTRA_FP_REGS && class2 == FP_REGS)))
+    return true;
+
+  return false;
+}
+
 /* Implement TARGET_SECONDARY_RELOAD.  */
 
 static reg_class_t
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 8343671..1f26232 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -747,6 +747,12 @@  extern int sparc_mode_class[];
    register window instruction in the prologue.  */
 #define HARD_REGNO_RENAME_OK(FROM, TO) ((FROM) != 1)
 
+/* Select a register mode required for caller save of hard regno REGNO.  */
+#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
+    (((MODE) == VOIDmode) ? \
+     choose_hard_reg_mode ((REGNO), (NREGS), false) : \
+     (MODE))
+
 #define MODES_TIEABLE_P(MODE1, MODE2) sparc_modes_tieable_p (MODE1, MODE2)
 
 /* Specify the registers used for certain standard purposes.
@@ -1044,12 +1050,10 @@  extern char leaf_reg_remap[];
   (SPARC_SETHI_P ((unsigned HOST_WIDE_INT) (X) & GET_MODE_MASK (SImode)))
 
 /* On SPARC when not VIS3 it is not possible to directly move data
-   between GENERAL_REGS and FP_REGS.  */
+   between GENERAL_REGS and FP_REGS.  We also cannot move 4-byte values
+   between FP_REGS and EXTRA_FP_REGS.  */
 #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
-  ((FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2)) \
-   && (! TARGET_VIS3 \
-       || GET_MODE_SIZE (MODE) > 8 \
-       || GET_MODE_SIZE (MODE) < 4))
+  sparc_secondary_memory_needed (CLASS1, CLASS2, MODE)
 
 /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9
    because the movsi and movsf patterns don't handle r/f moves.
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index f514d9f..e6a1831 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -1745,105 +1745,105 @@ 
 (define_insn "*sethi_di_medlow"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
-  "TARGET_CM_MEDLOW && check_pic (1)"
+  "TARGET_CM_MEDLOW && !flag_pic"
   "sethi\t%%hi(%a1), %0")
 
 (define_insn "*losum_di_medlow"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (match_operand:DI 2 "symbolic_operand" "")))]
-  "TARGET_CM_MEDLOW"
+  "TARGET_CM_MEDLOW && !flag_pic"
   "or\t%1, %%lo(%a2), %0")
 
 (define_insn "seth44"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
-  "TARGET_CM_MEDMID"
+  "TARGET_CM_MEDMID && !flag_pic"
   "sethi\t%%h44(%a1), %0")
 
 (define_insn "setm44"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
-  "TARGET_CM_MEDMID"
+  "TARGET_CM_MEDMID && !flag_pic"
   "or\t%1, %%m44(%a2), %0")
 
 (define_insn "setl44"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (match_operand:DI 2 "symbolic_operand" "")))]
-  "TARGET_CM_MEDMID"
+  "TARGET_CM_MEDMID && !flag_pic"
   "or\t%1, %%l44(%a2), %0")
 
 (define_insn "sethh"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
-  "TARGET_CM_MEDANY"
+  "TARGET_CM_MEDANY && !flag_pic"
   "sethi\t%%hh(%a1), %0")
 
 (define_insn "setlm"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
-  "TARGET_CM_MEDANY"
+  "TARGET_CM_MEDANY && !flag_pic"
   "sethi\t%%lm(%a1), %0")
 
 (define_insn "sethm"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
-  "TARGET_CM_MEDANY"
+  "TARGET_CM_MEDANY && !flag_pic"
   "or\t%1, %%hm(%a2), %0")
 
 (define_insn "setlo"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (match_operand:DI 2 "symbolic_operand" "")))]
-  "TARGET_CM_MEDANY"
+  "TARGET_CM_MEDANY && !flag_pic"
   "or\t%1, %%lo(%a2), %0")
 
 (define_insn "embmedany_sethi"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
-  "TARGET_CM_EMBMEDANY && check_pic (1)"
+  "TARGET_CM_EMBMEDANY && !flag_pic"
   "sethi\t%%hi(%a1), %0")
 
 (define_insn "embmedany_losum"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (match_operand:DI 2 "data_segment_operand" "")))]
-  "TARGET_CM_EMBMEDANY"
+  "TARGET_CM_EMBMEDANY && !flag_pic"
   "add\t%1, %%lo(%a2), %0")
 
 (define_insn "embmedany_brsum"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
-  "TARGET_CM_EMBMEDANY"
+  "TARGET_CM_EMBMEDANY && !flag_pic"
   "add\t%1, %_, %0")
 
 (define_insn "embmedany_textuhi"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
-  "TARGET_CM_EMBMEDANY && check_pic (1)"
+  "TARGET_CM_EMBMEDANY && !flag_pic"
   "sethi\t%%uhi(%a1), %0")
 
 (define_insn "embmedany_texthi"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
-  "TARGET_CM_EMBMEDANY && check_pic (1)"
+  "TARGET_CM_EMBMEDANY && !flag_pic"
   "sethi\t%%hi(%a1), %0")
 
 (define_insn "embmedany_textulo"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
-  "TARGET_CM_EMBMEDANY"
+  "TARGET_CM_EMBMEDANY && !flag_pic"
   "or\t%1, %%ulo(%a2), %0")
 
 (define_insn "embmedany_textlo"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (match_operand:DI 2 "text_segment_operand" "")))]
-  "TARGET_CM_EMBMEDANY"
+  "TARGET_CM_EMBMEDANY && !flag_pic"
   "or\t%1, %%lo(%a2), %0")
 
 ;; Now some patterns to help reload out a bit.