This patch adds SET rtx costs to MIPS. Since "FPR modes" and "GPR modes" aren't tieable, the effect is to restore the original lower-subreg behaviour of splitting all multiword modes.
Tested by setting LOG_COSTS to 1 and checking that the costs looked sensible. Also tested by compiling cc1 .ii files for -mabi=n32, -mabi=64, -mabi=32 and -mabi=32 -mfp64. The output was the same as when FORCE_LOWERING was set to 1, but different from unmodified trunk. Applied. Richard gcc/ * config/mips/mips.c (mips_set_reg_reg_piece_cost): New function. (mips_set_reg_reg_cost): Likewise. (mips_rtx_costs): Handle SET. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2012-05-06 13:47:49.000000000 +0100 +++ gcc/config/mips/mips.c 2012-05-06 14:10:25.636105001 +0100 @@ -3490,6 +3490,37 @@ mips_zero_extend_cost (enum machine_mode return COSTS_N_INSNS (1); } +/* Return the cost of moving between two registers of mode MODE, + assuming that the move will be in pieces of at most UNITS bytes. */ + +static int +mips_set_reg_reg_piece_cost (enum machine_mode mode, unsigned int units) +{ + return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units); +} + +/* Return the cost of moving between two registers of mode MODE. */ + +static int +mips_set_reg_reg_cost (enum machine_mode mode) +{ + switch (GET_MODE_CLASS (mode)) + { + case MODE_CC: + return mips_set_reg_reg_piece_cost (mode, GET_MODE_SIZE (CCmode)); + + case MODE_FLOAT: + case MODE_COMPLEX_FLOAT: + case MODE_VECTOR_FLOAT: + if (TARGET_HARD_FLOAT) + return mips_set_reg_reg_piece_cost (mode, UNITS_PER_HWFPVALUE); + /* Fall through */ + + default: + return mips_set_reg_reg_piece_cost (mode, UNITS_PER_WORD); + } +} + /* Implement TARGET_RTX_COSTS. */ static bool @@ -3877,6 +3908,15 @@ mips_rtx_costs (rtx x, int code, int out *total = mips_cost->fp_add; return false; + case SET: + if (register_operand (SET_DEST (x), VOIDmode) + && reg_or_0_operand (SET_SRC (x), VOIDmode)) + { + *total = mips_set_reg_reg_cost (GET_MODE (SET_DEST (x))); + return true; + } + return false; + default: return false; }