Initial implementation of RTX_COSTS target function for rx-elf. Minor increase in coremark scores, and enables division by multiplication of reciprocals, tested on trunk and 4.7. Ok for trunk and/or 4.7 branch?
* config/rx/rx.c (TARGET_RTX_COSTS): Define. (rx_rtx_costs): New. Index: gcc/config/rx/rx.c =================================================================== --- gcc/config/rx/rx.c (revision 186534) +++ gcc/config/rx/rx.c (working copy) @@ -2738,12 +2738,65 @@ rx_address_cost (rtx addr, bool speed) /* Try to discourage REG + <large OFF> when optimizing for size. */ return COSTS_N_INSNS (2); return COSTS_N_INSNS (1); } +#undef TARGET_RTX_COSTS +#define TARGET_RTX_COSTS rx_rtx_costs + +static bool +rx_rtx_costs (rtx x, + int code, + int outer_code ATTRIBUTE_UNUSED, + int opno ATTRIBUTE_UNUSED, + int * total, + bool speed ATTRIBUTE_UNUSED) +{ + switch (code) + { + case MULT: + if (GET_MODE (x) == DImode) + { + *total = COSTS_N_INSNS (2); + return true; + } + /* fall through */ + case PLUS: + case MINUS: + case AND: + case COMPARE: + case IOR: + case XOR: + if (GET_CODE (XEXP (x, 0)) == MEM + || GET_CODE (XEXP (x, 1)) == MEM) + *total = COSTS_N_INSNS (3); + else + *total = COSTS_N_INSNS (1); + return true; + + case DIV: + /* This is worst case. */ + *total = COSTS_N_INSNS (20); + return true; + + case UDIV: + /* This is worst case. */ + *total = COSTS_N_INSNS (18); + return true; + + case IF_THEN_ELSE: + *total = COSTS_N_INSNS (3); + return true; + + default: + break; + } + return false; +} + static bool rx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) { /* We can always eliminate to the frame pointer. We can eliminate to the stack pointer unless a frame pointer is needed. */