Commit 1466e387 by Richard Henderson Committed by Richard Henderson

re PR rtl-optimization/15289 (reload error with non-lowpart subregs)

        PR rtl-opt/15289
        * emit-rtl.c (gen_complex_constant_part): Remove.
        (gen_realpart, gen_imagpart): Remove.
        * rtl.h (gen_realpart, gen_imagpart): Remove.
        * expmed.c (extract_bit_field): Remove CONCAT hack catering to
        gen_realpart/gen_imagpart.
        * expr.c (write_complex_part, read_complex_part): New.
        (emit_move_via_alt_mode, emit_move_via_integer, emit_move_resolve_push,
        emit_move_complex_push, emit_move_complex, emit_move_ccmode,
        emit_move_multi_word): Split out from ...
        (emit_move_insn_1): ... here.
        (expand_expr_real_1) <COMPLEX_EXPR>: Use write_complex_part.
        <REALPART_EXPR, IMAGPART_EXPR>: Use read_complex_part.
        * function.c (assign_parm_setup_reg): Hard-code transformations
        instead of using gen_realpart/gen_imagpart.

From-SVN: r91571
parent 8c1cfd5a
2004-12-01 Richard Henderson <rth@redhat.com>
PR rtl-opt/15289
* emit-rtl.c (gen_complex_constant_part): Remove.
(gen_realpart, gen_imagpart): Remove.
* rtl.h (gen_realpart, gen_imagpart): Remove.
* expmed.c (extract_bit_field): Remove CONCAT hack catering to
gen_realpart/gen_imagpart.
* expr.c (write_complex_part, read_complex_part): New.
(emit_move_via_alt_mode, emit_move_via_integer, emit_move_resolve_push,
emit_move_complex_push, emit_move_complex, emit_move_ccmode,
emit_move_multi_word): Split out from ...
(emit_move_insn_1): ... here.
(expand_expr_real_1) <COMPLEX_EXPR>: Use write_complex_part.
<REALPART_EXPR, IMAGPART_EXPR>: Use read_complex_part.
* function.c (assign_parm_setup_reg): Hard-code transformations
instead of using gen_realpart/gen_imagpart.
* expr.c (optimize_bitfield_assignment_op): Split out from ...
(expand_assignment): ... here. Use handled_component_p to gate
get_inner_reference code. Simplify MEM handling. Special case
......
......@@ -184,7 +184,6 @@ static int reg_attrs_htab_eq (const void *, const void *);
static reg_attrs *get_reg_attrs (tree, int);
static tree component_ref_for_mem_expr (tree);
static rtx gen_const_vector (enum machine_mode, int);
static rtx gen_complex_constant_part (enum machine_mode, rtx, int);
static void copy_rtx_if_shared_1 (rtx *orig);
/* Probability of the conditional branch currently proceeded by try_split.
......@@ -1169,81 +1168,6 @@ gen_lowpart_common (enum machine_mode mode, rtx x)
return 0;
}
/* Return the constant real or imaginary part (which has mode MODE)
of a complex value X. The IMAGPART_P argument determines whether
the real or complex component should be returned. This function
returns NULL_RTX if the component isn't a constant. */
static rtx
gen_complex_constant_part (enum machine_mode mode, rtx x, int imagpart_p)
{
tree decl, part;
if (MEM_P (x)
&& GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
{
decl = SYMBOL_REF_DECL (XEXP (x, 0));
if (decl != NULL_TREE && TREE_CODE (decl) == COMPLEX_CST)
{
part = imagpart_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
if (TREE_CODE (part) == REAL_CST
|| TREE_CODE (part) == INTEGER_CST)
return expand_expr (part, NULL_RTX, mode, 0);
}
}
return NULL_RTX;
}
/* Return the real part (which has mode MODE) of a complex value X.
This always comes at the low address in memory. */
rtx
gen_realpart (enum machine_mode mode, rtx x)
{
rtx part;
/* Handle complex constants. */
part = gen_complex_constant_part (mode, x, 0);
if (part != NULL_RTX)
return part;
if (WORDS_BIG_ENDIAN
&& GET_MODE_BITSIZE (mode) < BITS_PER_WORD
&& REG_P (x)
&& REGNO (x) < FIRST_PSEUDO_REGISTER)
internal_error
("can't access real part of complex value in hard register");
else if (WORDS_BIG_ENDIAN)
return gen_highpart (mode, x);
else
return gen_lowpart (mode, x);
}
/* Return the imaginary part (which has mode MODE) of a complex value X.
This always comes at the high address in memory. */
rtx
gen_imagpart (enum machine_mode mode, rtx x)
{
rtx part;
/* Handle complex constants. */
part = gen_complex_constant_part (mode, x, 1);
if (part != NULL_RTX)
return part;
if (WORDS_BIG_ENDIAN)
return gen_lowpart (mode, x);
else if (! WORDS_BIG_ENDIAN
&& GET_MODE_BITSIZE (mode) < BITS_PER_WORD
&& REG_P (x)
&& REGNO (x) < FIRST_PSEUDO_REGISTER)
internal_error
("can't access imaginary part of complex value in hard register");
else
return gen_highpart (mode, x);
}
rtx
gen_highpart (enum machine_mode mode, rtx x)
{
......
......@@ -1611,28 +1611,6 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
return spec_target;
if (GET_MODE (target) != tmode && GET_MODE (target) != mode)
{
/* If the target mode is complex, then extract the two scalar elements
from the value now. Creating (subreg:SC (reg:DI) 0), as we would do
with the clause below, will cause gen_realpart or gen_imagpart to
fail, since those functions must return lvalues. */
if (COMPLEX_MODE_P (tmode))
{
rtx realpart, imagpart;
enum machine_mode itmode = GET_MODE_INNER (tmode);
target = convert_to_mode (mode_for_size (GET_MODE_BITSIZE (tmode),
MODE_INT, 0),
target, unsignedp);
realpart = extract_bit_field (target, GET_MODE_BITSIZE (itmode), 0,
unsignedp, NULL, itmode, itmode);
imagpart = extract_bit_field (target, GET_MODE_BITSIZE (itmode),
GET_MODE_BITSIZE (itmode), unsignedp,
NULL, itmode, itmode);
return gen_rtx_CONCAT (tmode, realpart, imagpart);
}
/* If the target mode is not a scalar integral, first convert to the
integer mode of that size and then access it as a floating-point
value via a SUBREG. */
......
......@@ -2869,10 +2869,11 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
{
enum machine_mode submode
= GET_MODE_INNER (GET_MODE (parmreg));
int regnor = REGNO (gen_realpart (submode, parmreg));
int regnoi = REGNO (gen_imagpart (submode, parmreg));
rtx stackr = gen_realpart (submode, data->stack_parm);
rtx stacki = gen_imagpart (submode, data->stack_parm);
int regnor = REGNO (XEXP (parmreg, 0));
int regnoi = REGNO (XEXP (parmreg, 1));
rtx stackr = adjust_address_nv (data->stack_parm, submode, 0);
rtx stacki = adjust_address_nv (data->stack_parm, submode,
GET_MODE_SIZE (submode));
/* Scan backwards for the set of the real and
imaginary parts. */
......
......@@ -1383,8 +1383,6 @@ extern rtx gen_lowpart_if_possible (enum machine_mode, rtx);
/* In emit-rtl.c */
extern rtx gen_highpart (enum machine_mode, rtx);
extern rtx gen_highpart_mode (enum machine_mode, enum machine_mode, rtx);
extern rtx gen_realpart (enum machine_mode, rtx);
extern rtx gen_imagpart (enum machine_mode, rtx);
extern rtx operand_subword (rtx, unsigned int, int, enum machine_mode);
/* In emit-rtl.c */
......
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