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.