diff options
author | Richard Henderson <rth@redhat.com> | 2004-11-13 22:22:56 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-11-13 22:22:56 -0800 |
commit | 27e29549a03c1c71c56abb27767d8393f7d0e65e (patch) | |
tree | 289c94268246a21e58d4318a10556bfb945f4896 /gcc/expr.c | |
parent | eaf0dc0254ab1fafb2a22b12ad336a23eae0197b (diff) | |
download | gcc-27e29549a03c1c71c56abb27767d8393f7d0e65e.zip gcc-27e29549a03c1c71c56abb27767d8393f7d0e65e.tar.gz gcc-27e29549a03c1c71c56abb27767d8393f7d0e65e.tar.bz2 |
calls.c (precompute_register_parameters): Force all PARALLELs into pseudo registers.
* calls.c (precompute_register_parameters): Force all PARALLELs
into pseudo registers.
(load_register_parameters): Copy PARALLELs into hard registers.
* function.c (assign_parm_setup_block): Copy PARALLELS into
pseudo registers. Do emit_group_store in conversion_insns.
* expr.c (emit_group_load_1): Rename from emit_group_load, take
tmps as an argument. Move final copy loop ...
(emit_group_load): ... here. New function.
(emit_group_load_into_temps, emit_group_move_into_temps): New.
* expr.h: Declare them.
From-SVN: r90613
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 93 |
1 files changed, 81 insertions, 12 deletions
@@ -1557,15 +1557,14 @@ gen_group_rtx (rtx orig) return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps)); } -/* Emit code to move a block ORIG_SRC of type TYPE to a block DST, - where DST is non-consecutive registers represented by a PARALLEL. - SSIZE represents the total size of block ORIG_SRC in bytes, or -1 - if not known. */ +/* A subroutine of emit_group_load. Arguments as for emit_group_load, + except that values are placed in TMPS[i], and must later be moved + into corrosponding XEXP (XVECEXP (DST, 0, i), 0) element. */ -void -emit_group_load (rtx dst, rtx orig_src, tree type ATTRIBUTE_UNUSED, int ssize) +static void +emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize) { - rtx *tmps, src; + rtx src; int start, i; enum machine_mode m = GET_MODE (orig_src); @@ -1585,7 +1584,7 @@ emit_group_load (rtx dst, rtx orig_src, tree type ATTRIBUTE_UNUSED, int ssize) /* ...and back again. */ if (imode != BLKmode) src = gen_lowpart (imode, src); - emit_group_load (dst, src, type, ssize); + emit_group_load_1 (tmps, dst, src, type, ssize); return; } @@ -1596,8 +1595,6 @@ emit_group_load (rtx dst, rtx orig_src, tree type ATTRIBUTE_UNUSED, int ssize) else start = 1; - tmps = alloca (sizeof (rtx) * XVECLEN (dst, 0)); - /* Process the pieces. */ for (i = start; i < XVECLEN (dst, 0); i++) { @@ -1709,10 +1706,61 @@ emit_group_load (rtx dst, rtx orig_src, tree type ATTRIBUTE_UNUSED, int ssize) tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i], build_int_cst (NULL_TREE, shift), tmps[i], 0); } +} + +/* Emit code to move a block SRC of type TYPE to a block DST, + where DST is non-consecutive registers represented by a PARALLEL. + SSIZE represents the total size of block ORIG_SRC in bytes, or -1 + if not known. */ + +void +emit_group_load (rtx dst, rtx src, tree type, int ssize) +{ + rtx *tmps; + int i; + + tmps = alloca (sizeof (rtx) * XVECLEN (dst, 0)); + emit_group_load_1 (tmps, dst, src, type, ssize); /* Copy the extracted pieces into the proper (probable) hard regs. */ - for (i = start; i < XVECLEN (dst, 0); i++) - emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0), tmps[i]); + for (i = 0; i < XVECLEN (dst, 0); i++) + { + rtx d = XEXP (XVECEXP (dst, 0, i), 0); + if (d == NULL) + continue; + emit_move_insn (d, tmps[i]); + } +} + +/* Similar, but load SRC into new pseudos in a format that looks like + PARALLEL. This can later be fed to emit_group_move to get things + in the right place. */ + +rtx +emit_group_load_into_temps (rtx parallel, rtx src, tree type, int ssize) +{ + rtvec vec; + int i; + + vec = rtvec_alloc (XVECLEN (parallel, 0)); + emit_group_load_1 (&RTVEC_ELT (vec, 0), parallel, src, type, ssize); + + /* Convert the vector to look just like the original PARALLEL, except + with the computed values. */ + for (i = 0; i < XVECLEN (parallel, 0); i++) + { + rtx e = XVECEXP (parallel, 0, i); + rtx d = XEXP (e, 0); + + if (d) + { + d = force_reg (GET_MODE (d), RTVEC_ELT (vec, i)); + e = alloc_EXPR_LIST (REG_NOTE_KIND (e), d, XEXP (e, 1)); + } + RTVEC_ELT (vec, i) = e; + } + + return gen_rtx_PARALLEL (GET_MODE (parallel), vec); } /* Emit code to move a block SRC to block DST, where SRC and DST are @@ -1733,6 +1781,27 @@ emit_group_move (rtx dst, rtx src) XEXP (XVECEXP (src, 0, i), 0)); } +/* Move a group of registers represented by a PARALLEL into pseudos. */ + +rtx +emit_group_move_into_temps (rtx src) +{ + rtvec vec = rtvec_alloc (XVECLEN (src, 0)); + int i; + + for (i = 0; i < XVECLEN (src, 0); i++) + { + rtx e = XVECEXP (src, 0, i); + rtx d = XEXP (e, 0); + + if (d) + e = alloc_EXPR_LIST (REG_NOTE_KIND (e), copy_to_reg (d), XEXP (e, 1)); + RTVEC_ELT (vec, i) = e; + } + + return gen_rtx_PARALLEL (GET_MODE (src), vec); +} + /* Emit code to move a block SRC to a block ORIG_DST of type TYPE, where SRC is non-consecutive registers represented by a PARALLEL. SSIZE represents the total size of block ORIG_DST, or -1 if not |