Commit ccb527e4 by John David Anglin Committed by John David Anglin

re PR target/15491 (ICE (Internal compiler error) while compiling glibc to vax-linux target)

	PR target/15491
        * vax.c (vax_rtx_costs_1): Merge with vax_rtx_costs.
	(vax_rtx_costs): Return false when passed unsupported rtx's.  Handle
	FLOAT_EXTEND, FLOAT_TRUNCATE and TRUNCATE.  Fix costs for POST_INC,
	PRE_DEC, NEG and NOT.

From-SVN: r97050
parent c3861e7a
2005-03-25 John David Anglin <dave.anglin@nrc-crnc.gc.ca>
PR target/15491
* vax.c (vax_rtx_costs_1): Merge with vax_rtx_costs.
(vax_rtx_costs): Return false when passed unsupported rtx's. Handle
FLOAT_EXTEND, FLOAT_TRUNCATE and TRUNCATE. Fix costs for POST_INC,
PRE_DEC, NEG and NOT.
2005-03-25 Kazu Hirata <kazu@cs.umass.edu> 2005-03-25 Kazu Hirata <kazu@cs.umass.edu>
* fold-const.c: Convert uses of fold (build (...)) to * fold-const.c: Convert uses of fold (build (...)) to
......
...@@ -50,7 +50,6 @@ static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, ...@@ -50,7 +50,6 @@ static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree); HOST_WIDE_INT, tree);
static int vax_address_cost_1 (rtx); static int vax_address_cost_1 (rtx);
static int vax_address_cost (rtx); static int vax_address_cost (rtx);
static int vax_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
static bool vax_rtx_costs (rtx, int, int, int *); static bool vax_rtx_costs (rtx, int, int, int *);
static rtx vax_struct_value_rtx (tree, int); static rtx vax_struct_value_rtx (tree, int);
...@@ -529,179 +528,228 @@ vax_address_cost (rtx x) ...@@ -529,179 +528,228 @@ vax_address_cost (rtx x)
/* Cost of an expression on a VAX. This version has costs tuned for the /* Cost of an expression on a VAX. This version has costs tuned for the
CVAX chip (found in the VAX 3 series) with comments for variations on CVAX chip (found in the VAX 3 series) with comments for variations on
other models. */ other models.
static int FIXME: The costs need review, particularly for TRUNCATE, FLOAT_EXTEND
vax_rtx_costs_1 (register rtx x, enum rtx_code code, enum rtx_code outer_code) and FLOAT_TRUNCATE. We need a -mcpu option to allow provision of
costs on a per cpu basis. */
static bool
vax_rtx_costs (rtx x, int code, int outer_code, int *total)
{ {
enum machine_mode mode = GET_MODE (x); enum machine_mode mode = GET_MODE (x);
register int c; int i = 0; /* may be modified in switch */
int i = 0; /* may be modified in switch */
const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */ const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
switch (code) switch (code)
{ {
/* On a VAX, constants from 0..63 are cheap because they can use the /* On a VAX, constants from 0..63 are cheap because they can use the
1 byte literal constant format. compare to -1 should be made cheap 1 byte literal constant format. Compare to -1 should be made cheap
so that decrement-and-branch insns can be formed more easily (if so that decrement-and-branch insns can be formed more easily (if
the value -1 is copied to a register some decrement-and-branch the value -1 is copied to a register some decrement-and-branch
patterns will not match). */ patterns will not match). */
case CONST_INT: case CONST_INT:
if (INTVAL (x) == 0) if (INTVAL (x) == 0)
return 0; return true;
if (outer_code == AND) if (outer_code == AND)
return ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2; {
if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077) *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2;
return 1; return true;
if (outer_code == COMPARE && INTVAL (x) == -1) }
return 1; if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077
if (outer_code == PLUS && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077) || (outer_code == COMPARE
return 1; && INTVAL (x) == -1)
|| ((outer_code == PLUS || outer_code == MINUS)
&& (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077))
{
*total = 1;
return true;
}
/* FALLTHRU */ /* FALLTHRU */
case CONST: case CONST:
case LABEL_REF: case LABEL_REF:
case SYMBOL_REF: case SYMBOL_REF:
return 3; *total = 3;
return true;
case CONST_DOUBLE: case CONST_DOUBLE:
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
return vax_float_literal (x) ? 5 : 8; *total = vax_float_literal (x) ? 5 : 8;
else else
return (((CONST_DOUBLE_HIGH (x) == 0 *total = ((CONST_DOUBLE_HIGH (x) == 0
&& (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64) && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
|| (outer_code == PLUS || (outer_code == PLUS
&& CONST_DOUBLE_HIGH (x) == -1 \ && CONST_DOUBLE_HIGH (x) == -1
&& (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64)) && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64))
? 2 : 5); ? 2 : 5;
return true;
case POST_INC: case POST_INC:
return 2; *total = 2;
return true; /* Implies register operand. */
case PRE_DEC: case PRE_DEC:
return 3; *total = 3;
return true; /* Implies register operand. */
case MULT: case MULT:
switch (mode) switch (mode)
{ {
case DFmode: case DFmode:
c = 16; /* 4 on VAX 9000 */ *total = 16; /* 4 on VAX 9000 */
break; break;
case SFmode: case SFmode:
c = 9; /* 4 on VAX 9000, 12 on VAX 2 */ *total = 9; /* 4 on VAX 9000, 12 on VAX 2 */
break; break;
case DImode: case DImode:
c = 16; /* 6 on VAX 9000, 28 on VAX 2 */ *total = 16; /* 6 on VAX 9000, 28 on VAX 2 */
break; break;
case SImode: case SImode:
case HImode: case HImode:
case QImode: case QImode:
c = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */ *total = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
break; break;
default: default:
return MAX_COST; /* Mode is not supported. */ *total = MAX_COST; /* Mode is not supported. */
return true;
} }
break; break;
case UDIV: case UDIV:
if (mode != SImode) if (mode != SImode)
return MAX_COST; /* Mode is not supported. */ {
c = 17; *total = MAX_COST; /* Mode is not supported. */
return true;
}
*total = 17;
break; break;
case DIV: case DIV:
if (mode == DImode) if (mode == DImode)
c = 30; /* highly variable */ *total = 30; /* Highly variable. */
else if (mode == DFmode) else if (mode == DFmode)
/* divide takes 28 cycles if the result is not zero, 13 otherwise */ /* divide takes 28 cycles if the result is not zero, 13 otherwise */
c = 24; *total = 24;
else else
c = 11; /* 25 on VAX 2 */ *total = 11; /* 25 on VAX 2 */
break; break;
case MOD: case MOD:
c = 23; *total = 23;
break; break;
case UMOD: case UMOD:
if (mode != SImode) if (mode != SImode)
return MAX_COST; /* Mode is not supported. */ {
c = 29; *total = MAX_COST; /* Mode is not supported. */
return true;
}
*total = 29;
break; break;
case FLOAT: case FLOAT:
c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode); *total = (6 /* 4 on VAX 9000 */
/* 4 on VAX 9000 */ + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode));
break; break;
case FIX: case FIX:
c = 7; /* 17 on VAX 2 */ *total = 7; /* 17 on VAX 2 */
break; break;
case ASHIFT: case ASHIFT:
case LSHIFTRT: case LSHIFTRT:
case ASHIFTRT: case ASHIFTRT:
if (mode == DImode) if (mode == DImode)
c = 12; *total = 12;
else else
c = 10; /* 6 on VAX 9000 */ *total = 10; /* 6 on VAX 9000 */
break; break;
case ROTATE: case ROTATE:
case ROTATERT: case ROTATERT:
c = 6; /* 5 on VAX 2, 4 on VAX 9000 */ *total = 6; /* 5 on VAX 2, 4 on VAX 9000 */
if (GET_CODE (XEXP (x, 1)) == CONST_INT) if (GET_CODE (XEXP (x, 1)) == CONST_INT)
fmt = "e"; /* all constant rotate counts are short */ fmt = "e"; /* all constant rotate counts are short */
break; break;
case PLUS: case PLUS:
case MINUS: case MINUS:
c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */ *total = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
/* Small integer operands can use subl2 and addl2. */ /* Small integer operands can use subl2 and addl2. */
if ((GET_CODE (XEXP (x, 1)) == CONST_INT) if ((GET_CODE (XEXP (x, 1)) == CONST_INT)
&& (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127) && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127)
fmt = "e"; fmt = "e";
break; break;
case IOR: case IOR:
case XOR: case XOR:
c = 3; *total = 3;
break; break;
case AND: case AND:
/* AND is special because the first operand is complemented. */ /* AND is special because the first operand is complemented. */
c = 3; *total = 3;
if (GET_CODE (XEXP (x, 0)) == CONST_INT) if (GET_CODE (XEXP (x, 0)) == CONST_INT)
{ {
if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63) if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63)
c = 4; *total = 4;
fmt = "e"; fmt = "e";
i = 1; i = 1;
} }
break; break;
case NEG: case NEG:
if (mode == DFmode) if (mode == DFmode)
return 9; *total = 9;
else if (mode == SFmode) else if (mode == SFmode)
return 6; *total = 6;
else if (mode == DImode) else if (mode == DImode)
return 4; *total = 4;
else
*total = 2;
break;
case NOT: case NOT:
return 2; *total = 2;
break;
case ZERO_EXTRACT: case ZERO_EXTRACT:
case SIGN_EXTRACT: case SIGN_EXTRACT:
c = 15; *total = 15;
break; break;
case MEM: case MEM:
if (mode == DImode || mode == DFmode) if (mode == DImode || mode == DFmode)
c = 5; /* 7 on VAX 2 */ *total = 5; /* 7 on VAX 2 */
else else
c = 3; /* 4 on VAX 2 */ *total = 3; /* 4 on VAX 2 */
x = XEXP (x, 0); x = XEXP (x, 0);
if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC) if (GET_CODE (x) != REG && GET_CODE (x) != POST_INC)
return c; *total += vax_address_cost_1 (x);
return c + vax_address_cost_1 (x); return true;
default:
c = 3; case FLOAT_EXTEND:
case FLOAT_TRUNCATE:
case TRUNCATE:
*total = 3; /* FIXME: Costs need to be checked */
break; break;
default:
return false;
} }
/* Now look inside the expression. Operands which are not registers or /* Now look inside the expression. Operands which are not registers or
short constants add to the cost. short constants add to the cost.
FMT and I may have been adjusted in the switch above for instructions FMT and I may have been adjusted in the switch above for instructions
which require special handling */ which require special handling. */
while (*fmt++ == 'e') while (*fmt++ == 'e')
{ {
register rtx op = XEXP (x, i++); rtx op = XEXP (x, i);
i += 1;
code = GET_CODE (op); code = GET_CODE (op);
/* A NOT is likely to be found as the first operand of an AND /* A NOT is likely to be found as the first operand of an AND
...@@ -715,12 +763,12 @@ vax_rtx_costs_1 (register rtx x, enum rtx_code code, enum rtx_code outer_code) ...@@ -715,12 +763,12 @@ vax_rtx_costs_1 (register rtx x, enum rtx_code code, enum rtx_code outer_code)
case CONST_INT: case CONST_INT:
if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63 if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63
&& GET_MODE (x) != QImode) && GET_MODE (x) != QImode)
c += 1; /* 2 on VAX 2 */ *total += 1; /* 2 on VAX 2 */
break; break;
case CONST: case CONST:
case LABEL_REF: case LABEL_REF:
case SYMBOL_REF: case SYMBOL_REF:
c += 1; /* 2 on VAX 2 */ *total += 1; /* 2 on VAX 2 */
break; break;
case CONST_DOUBLE: case CONST_DOUBLE:
if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT) if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
...@@ -728,37 +776,30 @@ vax_rtx_costs_1 (register rtx x, enum rtx_code code, enum rtx_code outer_code) ...@@ -728,37 +776,30 @@ vax_rtx_costs_1 (register rtx x, enum rtx_code code, enum rtx_code outer_code)
/* Registers are faster than floating point constants -- even /* Registers are faster than floating point constants -- even
those constants which can be encoded in a single byte. */ those constants which can be encoded in a single byte. */
if (vax_float_literal (op)) if (vax_float_literal (op))
c++; *total += 1;
else else
c += (GET_MODE (x) == DFmode) ? 3 : 2; *total += (GET_MODE (x) == DFmode) ? 3 : 2;
} }
else else
{ {
if (CONST_DOUBLE_HIGH (op) != 0 if (CONST_DOUBLE_HIGH (op) != 0
|| (unsigned)CONST_DOUBLE_LOW (op) > 63) || (unsigned)CONST_DOUBLE_LOW (op) > 63)
c += 2; *total += 2;
} }
break; break;
case MEM: case MEM:
c += 1; /* 2 on VAX 2 */ *total += 1; /* 2 on VAX 2 */
if (GET_CODE (XEXP (op, 0)) != REG) if (GET_CODE (XEXP (op, 0)) != REG)
c += vax_address_cost_1 (XEXP (op, 0)); *total += vax_address_cost_1 (XEXP (op, 0));
break; break;
case REG: case REG:
case SUBREG: case SUBREG:
break; break;
default: default:
c += 1; *total += 1;
break; break;
} }
} }
return c;
}
static bool
vax_rtx_costs (rtx x, int code, int outer_code, int * total)
{
*total = vax_rtx_costs_1 (x, code, outer_code);
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment