With Richard Sandiford's address decomposition patch, Sparc
looks really good on the 32-bit side.  This is the patch I
am using.

2012-10-25  David S. Miller  <da...@davemloft.net>

        * config/sparc/sparc.c (sparc_lra_p): New function.
        (sparc_spill_class): New function.
        (TARGET_LRA_P): Define.
        (TARGET_SPILL_CLASS): Define.
        (sparc_legitimate_address_p): Reject LO_SUM of SYMBOL_REF when
        PIC.

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 272632e..8422bcb 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -593,6 +593,9 @@ static const char *sparc_mangle_type (const_tree);
 #endif
 static void sparc_trampoline_init (rtx, tree, rtx);
 static enum machine_mode sparc_preferred_simd_mode (enum machine_mode);
+static bool sparc_lra_p (void);
+static reg_class_t sparc_spill_class (reg_class_t rclass,
+                                     enum machine_mode mode);
 static reg_class_t sparc_preferred_reload_class (rtx x, reg_class_t rclass);
 static bool sparc_print_operand_punct_valid_p (unsigned char);
 static void sparc_print_operand (FILE *, rtx, int);
@@ -771,6 +774,12 @@ char sparc_hard_reg_printed[8];
 #undef TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE sparc_can_eliminate
 
+#undef TARGET_LRA_P
+#define TARGET_LRA_P sparc_lra_p
+
+#undef TARGET_SPILL_CLASS
+#define TARGET_SPILL_CLASS sparc_spill_class
+
 #undef  TARGET_PREFERRED_RELOAD_CLASS
 #define TARGET_PREFERRED_RELOAD_CLASS sparc_preferred_reload_class
 
@@ -3543,6 +3552,10 @@ sparc_legitimate_address_p (enum machine_mode mode, rtx 
addr, bool strict)
         than the alignment (8) may cause the LO_SUM to overflow.  */
       if (mode == TFmode && TARGET_ARCH32)
        return 0;
+
+      /* When PIC, we should never see LO_SUM references to symbols.  */
+      if (flag_pic && GET_CODE (imm1) == SYMBOL_REF)
+       return 0;
     }
   else if (GET_CODE (addr) == CONST_INT && SMALL_INT (addr))
     return 1;
@@ -11355,6 +11368,33 @@ sparc_conditional_register_usage (void)
     global_regs[SPARC_GSR_REG] = 1;
 }
 
+/* Return true if we use LRA instead of reload pass.  */
+static bool
+sparc_lra_p (void)
+{
+  return true;
+}
+
+/* Return class of registers which could be used for pseudo of MODE
+   and of class RCLASS for spilling instead of memory.  Return NO_REGS
+   if it is not possible or non-profitable.  */
+static reg_class_t
+sparc_spill_class (reg_class_t rclass, enum machine_mode mode)
+{
+  /* If we have VIS3 available, we can very cheaply spill integer
+     registers into the floating point register file.  */
+  if (TARGET_VIS3
+      && (mode == SImode || (TARGET_ARCH64 && mode == DImode))
+      && hard_reg_set_subset_p (reg_class_contents[rclass],
+                               reg_class_contents[GENERAL_REGS]))
+    {
+      if (mode == SImode)
+       return FP_REGS;
+      return EXTRA_FP_REGS;
+    }
+  return NO_REGS;
+}
+
 /* Implement TARGET_PREFERRED_RELOAD_CLASS:
 
    - We can't load constants into FP registers.

Reply via email to