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> 2002-05-04 Neil Booth <neil@daikokuya.demon.co.uk>
* c-lex.c (lex_string): Let cpp_parse_escape handles truncation * c-lex.c (lex_string): Let cpp_parse_escape handles truncation
......
...@@ -5432,16 +5432,13 @@ rtx ...@@ -5432,16 +5432,13 @@ rtx
force_operand (value, target) force_operand (value, target)
rtx value, target; rtx value, target;
{ {
optab binoptab = 0; rtx op1, op2;
/* Use a temporary to force order of execution of calls to
`force_operand'. */
rtx tmp;
rtx op2;
/* Use subtarget as the target for operand 0 of a binary operation. */ /* Use subtarget as the target for operand 0 of a binary operation. */
rtx subtarget = get_subtarget (target); rtx subtarget = get_subtarget (target);
enum rtx_code code = GET_CODE (value);
/* Check for a PIC address load. */ /* 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 && XEXP (value, 0) == pic_offset_table_rtx
&& (GET_CODE (XEXP (value, 1)) == SYMBOL_REF && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
|| GET_CODE (XEXP (value, 1)) == LABEL_REF || GET_CODE (XEXP (value, 1)) == LABEL_REF
...@@ -5453,60 +5450,88 @@ force_operand (value, target) ...@@ -5453,60 +5450,88 @@ force_operand (value, target)
return subtarget; return subtarget;
} }
if (GET_CODE (value) == PLUS) if (code == ZERO_EXTEND || code == SIGN_EXTEND)
binoptab = add_optab;
else if (GET_CODE (value) == MINUS)
binoptab = sub_optab;
else if (GET_CODE (value) == MULT)
{ {
op2 = XEXP (value, 1); if (!target)
if (!CONSTANT_P (op2) target = gen_reg_rtx (GET_MODE (value));
&& !(GET_CODE (op2) == REG && op2 != subtarget)) convert_move (force_operand (XEXP (value, 0), NULL), target,
subtarget = 0; code == ZERO_EXTEND);
tmp = force_operand (XEXP (value, 0), subtarget); return target;
return expand_mult (GET_MODE (value), tmp,
force_operand (op2, NULL_RTX),
target, 1);
} }
if (binoptab) if (GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c')
{ {
op2 = XEXP (value, 1); op2 = XEXP (value, 1);
if (!CONSTANT_P (op2) if (!CONSTANT_P (op2) && !(GET_CODE (op2) == REG && op2 != subtarget))
&& !(GET_CODE (op2) == REG && op2 != subtarget))
subtarget = 0; 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); op2 = negate_rtx (GET_MODE (value), op2);
} }
/* Check for an addition with OP2 a constant integer and our first /* Check for an addition with OP2 a constant integer and our first
operand a PLUS of a virtual register and something else. In that 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 case, we want to emit the sum of the virtual register and the
constant first and then add the other value. This allows virtual constant first and then add the other value. This allows virtual
register instantiation to simply modify the constant rather than register instantiation to simply modify the constant rather than
creating another one around this addition. */ 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 (value, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (value, 0), 0)) == REG && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
&& REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
&& REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_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, XEXP (XEXP (value, 0), 0), op2,
subtarget, 0, OPTAB_LIB_WIDEN); subtarget, 0, OPTAB_LIB_WIDEN);
return expand_binop (GET_MODE (value), binoptab, temp, return expand_simple_binop (GET_MODE (value), code, temp,
force_operand (XEXP (XEXP (value, 0), 1), 0), force_operand (XEXP (XEXP (value,
target, 0, OPTAB_LIB_WIDEN); 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); if (GET_RTX_CLASS (code) == '1')
return expand_binop (GET_MODE (value), binoptab, tmp, {
force_operand (op2, NULL_RTX), op1 = force_operand (XEXP (value, 0), NULL_RTX);
target, 0, OPTAB_LIB_WIDEN); return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
/* We give UNSIGNEDP = 0 to expand_binop
because the only operations we are expanding here are signed ones. */
} }
#ifdef INSN_SCHEDULING #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