diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cee1ea449cb..5626de2cd95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2012-09-08 John David Anglin + + * config/pa/pa.c (hppa_rtx_costs): Update costs for large integer modes. + 2012-09-08 Andi Kleen * gcc/lto/lto.c (do_whole_program_analysis): diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index bb54c6e1bfe..cba8e781722 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -1422,6 +1422,8 @@ static bool hppa_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, int *total, bool speed ATTRIBUTE_UNUSED) { + int factor; + switch (code) { case CONST_INT: @@ -1453,11 +1455,20 @@ hppa_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, case MULT: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) - *total = COSTS_N_INSNS (3); - else if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT) - *total = COSTS_N_INSNS (8); + { + *total = COSTS_N_INSNS (3); + return true; + } + + /* A mode size N times larger than SImode needs O(N*N) more insns. */ + factor = GET_MODE_SIZE (GET_MODE (x)) / 4; + if (factor == 0) + factor = 1; + + if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT) + *total = factor * factor * COSTS_N_INSNS (8); else - *total = COSTS_N_INSNS (20); + *total = factor * factor * COSTS_N_INSNS (20); return true; case DIV: @@ -1471,15 +1482,28 @@ hppa_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, case UDIV: case MOD: case UMOD: - *total = COSTS_N_INSNS (60); + /* A mode size N times larger than SImode needs O(N*N) more insns. */ + factor = GET_MODE_SIZE (GET_MODE (x)) / 4; + if (factor == 0) + factor = 1; + + *total = factor * factor * COSTS_N_INSNS (60); return true; case PLUS: /* this includes shNadd insns */ case MINUS: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) - *total = COSTS_N_INSNS (3); - else - *total = COSTS_N_INSNS (1); + { + *total = COSTS_N_INSNS (3); + return true; + } + + /* A size N times larger than UNITS_PER_WORD needs N times as + many insns, taking N times as long. */ + factor = GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD; + if (factor == 0) + factor = 1; + *total = factor * COSTS_N_INSNS (1); return true; case ASHIFT: