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:
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:
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: