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,60 +5450,88 @@ 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);
}
/* Check for an addition with OP2 a constant integer and our first
operand a PLUS of a virtual register and something else. In that
case, we want to emit the sum of the virtual register and the
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
operand a PLUS of a virtual register and something else. In that
case, we want to emit the sum of the virtual register and the
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 (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,
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),
target, 0, OPTAB_LIB_WIDEN);
rtx temp = expand_simple_binop (GET_MODE (value), code,
XEXP (XEXP (value, 0), 0), op2,
subtarget, 0, OPTAB_LIB_WIDEN);
return expand_simple_binop (GET_MODE (value), code, temp,
force_operand (XEXP (XEXP (value,
0), 1), 0),
target, 0, OPTAB_LIB_WIDEN);
}
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);
break;
default:
return expand_simple_binop (GET_MODE (value), code, op1, op2,
target, 1, OPTAB_LIB_WIDEN);
}
tmp = force_operand (XEXP (value, 0), subtarget);
return expand_binop (GET_MODE (value), binoptab, tmp,
force_operand (op2, NULL_RTX),
target, 0, OPTAB_LIB_WIDEN);
/* We give UNSIGNEDP = 0 to expand_binop
because the only operations we are expanding here are signed ones. */
}
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