summaryrefslogtreecommitdiff
path: root/gcc/config/ip2k/ip2k.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/ip2k/ip2k.c')
-rw-r--r--gcc/config/ip2k/ip2k.c98
1 files changed, 61 insertions, 37 deletions
diff --git a/gcc/config/ip2k/ip2k.c b/gcc/config/ip2k/ip2k.c
index 6b2bc33729c..cb1a0952c5f 100644
--- a/gcc/config/ip2k/ip2k.c
+++ b/gcc/config/ip2k/ip2k.c
@@ -78,6 +78,8 @@ static tree ip2k_handle_progmem_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree ip2k_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int,
bool *));
+static bool ip2k_rtx_costs PARAMS ((rtx, int, int, int *));
+
const struct attribute_spec ip2k_attribute_table[];
@@ -100,6 +102,9 @@ const struct attribute_spec ip2k_attribute_table[];
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE ip2k_attribute_table
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ip2k_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Commands in the functions prologues in the compiled file. */
@@ -3273,23 +3278,34 @@ asm_file_end (file)
/* Cost functions. */
-/* Calculate the cost of X code of the expression in which it is contained,
- found in OUTER_CODE. */
+/* Compute a (partial) cost for rtx X. Return true if the complete
+ cost has been computed, and false if subexpressions should be
+ scanned. In either case, *TOTAL contains the cost result. */
-int
-default_rtx_costs (x, code, outer_code)
+static bool
+ip2k_rtx_costs (x, code, outer_code, total)
rtx x;
- enum rtx_code code;
- enum rtx_code outer_code;
+ int code, outer_code;
+ int *total;
{
enum machine_mode mode = GET_MODE (x);
int extra_cost = 0;
- int total;
switch (code)
{
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case LABEL_REF:
+ *total = 0;
+ return true;
+ case CONST:
+ case SYMBOL_REF:
+ *total = 8;
+ return true;
+
case MEM:
- return ip2k_address_cost (XEXP (x, 0));
+ *total = ip2k_address_cost (XEXP (x, 0));
+ return true;
case ROTATE:
case ROTATERT:
@@ -3311,45 +3327,47 @@ default_rtx_costs (x, code, outer_code)
/* Sign-preserving shifts require 2 extra instructions. */
if (code == ASHIFT)
cost += COSTS_N_INSNS (2);
- return cost;
+
+ *total = cost;
+ return true;
}
- total = rtx_cost (XEXP (x, 0), code);
- total += COSTS_N_INSNS (GET_MODE_SIZE (mode) * 8);
- return total;
+ *total = rtx_cost (XEXP (x, 0), code);
+ *total += COSTS_N_INSNS (GET_MODE_SIZE (mode) * 8);
+ return true;
case MINUS:
case PLUS:
case AND:
case XOR:
case IOR:
- total = rtx_cost (XEXP (x, 0), code)
- + rtx_cost (XEXP (x, 1), code);
- total += COSTS_N_INSNS (GET_MODE_SIZE (mode) * 3);
- return total;
+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) * 3);
+ return false;
case MOD:
case DIV:
if (mode == QImode)
- return COSTS_N_INSNS (20);
- if (mode == HImode)
- return COSTS_N_INSNS (60);
+ *total = COSTS_N_INSNS (20);
+ else if (mode == HImode)
+ *total = COSTS_N_INSNS (60);
else if (mode == SImode)
- return COSTS_N_INSNS (180);
+ *total = COSTS_N_INSNS (180);
else
- return COSTS_N_INSNS (540);
+ *total = COSTS_N_INSNS (540);
+ return true;
case MULT:
/* These costs are OK, but should really handle subtle cases
where we're using sign or zero extended args as these are
*much* cheaper than those given below! */
if (mode == QImode)
- return COSTS_N_INSNS (4);
- if (mode == HImode)
- return COSTS_N_INSNS (12);
- if (mode == SImode)
- return COSTS_N_INSNS (36);
+ *total = COSTS_N_INSNS (4);
+ else if (mode == HImode)
+ *total = COSTS_N_INSNS (12);
+ else if (mode == SImode)
+ *total = COSTS_N_INSNS (36);
else
- return COSTS_N_INSNS (108);
+ *total = COSTS_N_INSNS (108);
+ return true;
case NEG:
case SIGN_EXTEND:
@@ -3359,20 +3377,25 @@ default_rtx_costs (x, code, outer_code)
case NOT:
case COMPARE:
case ABS:
- total = rtx_cost (XEXP (x, 0), code);
- return total + extra_cost + COSTS_N_INSNS (GET_MODE_SIZE (mode) * 2);
+ *total = extra_cost + COSTS_N_INSNS (GET_MODE_SIZE (mode) * 2);
+ return false;
case TRUNCATE:
case ZERO_EXTEND:
if (outer_code == SET)
- return rtx_cost (XEXP (x, 0), code)
- + COSTS_N_INSNS (GET_MODE_SIZE (mode) * 3 / 2);
+ {
+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) * 3 / 2);
+ return false;
+ }
else
- return -(COSTS_N_INSNS (GET_MODE_SIZE (mode)) / 2);
+ {
+ *total = -(COSTS_N_INSNS (GET_MODE_SIZE (mode)) / 2);
+ return true;
+ }
case IF_THEN_ELSE:
- return rtx_cost (XEXP (x, 0), code)
- + COSTS_N_INSNS (2);
+ *total = rtx_cost (XEXP (x, 0), code) + COSTS_N_INSNS (2);
+ return true;
case EQ:
case NE:
@@ -3384,11 +3407,12 @@ default_rtx_costs (x, code, outer_code)
case GT:
case LE:
case GE:
- return rtx_cost (XEXP (x, 0), code)
- + rtx_cost (XEXP (x, 1), code);
+ *total = 0;
+ return false;
default:
- return COSTS_N_INSNS (4);
+ *total = COSTS_N_INSNS (4);
+ return true;
}
}