The attached patch improves the cost estimate for multiplication, etc, on parisc. It was noted debugging various PRs that the cost for multiplication of long longs was seriously underestimated.
Tested on hppa2.0w-hp-hpux11.11, hppa64-hp-hpux11.11 and hppa-unknown-linux-gnu. Committed to trunk. Dave -- J. David Anglin dave.ang...@nrc-cnrc.gc.ca National Research Council of Canada (613) 990-0752 (FAX: 952-6602) 2012-09-08 John David Anglin <dave.ang...@nrc-cnrc.gc.ca> * config/pa/pa.c (hppa_rtx_costs): Update costs for large integer modes. Index: config/pa/pa.c =================================================================== --- config/pa/pa.c (revision 191079) +++ config/pa/pa.c (working copy) @@ -1422,6 +1422,8 @@ 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 @@ 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 @@ 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: