Commit 8a28dbcc by Jan Hubicka Committed by Jan Hubicka

expr.c (force_operand): Use expand_simple_* to handle more cases.

	* expr.c (force_operand): Use expand_simple_* to handle more
	cases.

From-SVN: r53154
parent ae1a07e0
Sat May 4 13:20:54 CEST 2002 Jan Hubicka <jh@suse.cz>
* expr.c (force_operand): Use expand_simple_* to handle more
cases.
2002-05-04 Neil Booth <neil@daikokuya.demon.co.uk>
* c-lex.c (lex_string): Let cpp_parse_escape handles truncation
......
......@@ -5432,16 +5432,13 @@ rtx
force_operand (value, target)
rtx value, target;
{
optab binoptab = 0;
/* Use a temporary to force order of execution of calls to
`force_operand'. */
rtx tmp;
rtx op2;
rtx op1, op2;
/* Use subtarget as the target for operand 0 of a binary operation. */
rtx subtarget = get_subtarget (target);
enum rtx_code code = GET_CODE (value);
/* Check for a PIC address load. */
if ((GET_CODE (value) == PLUS || GET_CODE (value) == MINUS)
if ((code == PLUS || code == MINUS)
&& XEXP (value, 0) == pic_offset_table_rtx
&& (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
|| GET_CODE (XEXP (value, 1)) == LABEL_REF
......@@ -5453,31 +5450,23 @@ force_operand (value, target)
return subtarget;
}
if (GET_CODE (value) == PLUS)
binoptab = add_optab;
else if (GET_CODE (value) == MINUS)
binoptab = sub_optab;
else if (GET_CODE (value) == MULT)
if (code == ZERO_EXTEND || code == SIGN_EXTEND)
{
op2 = XEXP (value, 1);
if (!CONSTANT_P (op2)
&& !(GET_CODE (op2) == REG && op2 != subtarget))
subtarget = 0;
tmp = force_operand (XEXP (value, 0), subtarget);
return expand_mult (GET_MODE (value), tmp,
force_operand (op2, NULL_RTX),
target, 1);
if (!target)
target = gen_reg_rtx (GET_MODE (value));
convert_move (force_operand (XEXP (value, 0), NULL), target,
code == ZERO_EXTEND);
return target;
}
if (binoptab)
if (GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c')
{
op2 = XEXP (value, 1);
if (!CONSTANT_P (op2)
&& !(GET_CODE (op2) == REG && op2 != subtarget))
if (!CONSTANT_P (op2) && !(GET_CODE (op2) == REG && op2 != subtarget))
subtarget = 0;
if (binoptab == sub_optab && GET_CODE (op2) == CONST_INT)
if (code == MINUS && GET_CODE (op2) == CONST_INT)
{
binoptab = add_optab;
code = PLUS;
op2 = negate_rtx (GET_MODE (value), op2);
}
......@@ -5487,26 +5476,62 @@ force_operand (value, target)
constant first and then add the other value. This allows virtual
register instantiation to simply modify the constant rather than
creating another one around this addition. */
if (binoptab == add_optab && GET_CODE (op2) == CONST_INT
if (code == PLUS && GET_CODE (op2) == CONST_INT
&& GET_CODE (XEXP (value, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
&& REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
&& REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
{
rtx temp = expand_binop (GET_MODE (value), binoptab,
rtx temp = expand_simple_binop (GET_MODE (value), code,
XEXP (XEXP (value, 0), 0), op2,
subtarget, 0, OPTAB_LIB_WIDEN);
return expand_binop (GET_MODE (value), binoptab, temp,
force_operand (XEXP (XEXP (value, 0), 1), 0),
return expand_simple_binop (GET_MODE (value), code, temp,
force_operand (XEXP (XEXP (value,
0), 1), 0),
target, 0, OPTAB_LIB_WIDEN);
}
tmp = force_operand (XEXP (value, 0), subtarget);
return expand_binop (GET_MODE (value), binoptab, tmp,
force_operand (op2, NULL_RTX),
op1 = force_operand (XEXP (value, 0), subtarget);
op2 = force_operand (op2, NULL_RTX);
switch (code)
{
case MULT:
return expand_mult (GET_MODE (value), op1, op2, target, 1);
case DIV:
if (!INTEGRAL_MODE_P (GET_MODE (value)))
return expand_simple_binop (GET_MODE (value), code, op1, op2,
target, 1, OPTAB_LIB_WIDEN);
else
return expand_divmod (0,
FLOAT_MODE_P (GET_MODE (value))
? RDIV_EXPR : TRUNC_DIV_EXPR,
GET_MODE (value), op1, op2, target, 0);
break;
case MOD:
return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
target, 0);
break;
case UDIV:
return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
target, 1);
break;
case UMOD:
return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
target, 1);
break;
case ASHIFTRT:
return expand_simple_binop (GET_MODE (value), code, op1, op2,
target, 0, OPTAB_LIB_WIDEN);
/* We give UNSIGNEDP = 0 to expand_binop
because the only operations we are expanding here are signed ones. */
break;
default:
return expand_simple_binop (GET_MODE (value), code, op1, op2,
target, 1, OPTAB_LIB_WIDEN);
}
}
if (GET_RTX_CLASS (code) == '1')
{
op1 = force_operand (XEXP (value, 0), NULL_RTX);
return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
}
#ifdef INSN_SCHEDULING
......
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