diff options
author | Adam Nemet <anemet@caviumnetworks.com> | 2009-07-01 21:22:28 +0000 |
---|---|---|
committer | Adam Nemet <nemet@gcc.gnu.org> | 2009-07-01 21:22:28 +0000 |
commit | c600a15524cc3200cd4ee3997e162e9205b79a70 (patch) | |
tree | f22fa7b6d9b6ffed269294835667cdcee38cb8ef /gcc/expmed.c | |
parent | bf92f919e997d8c7da797723fa46c56bcc19baa8 (diff) | |
download | gcc-c600a15524cc3200cd4ee3997e162e9205b79a70.tar.gz |
revert: expmed.c (store_bit_field_1): Properly truncate the paradoxical subreg of op0 to the original op0.
Revert:
2009-01-11 Adam Nemet <anemet@caviumnetworks.com>
* expmed.c (store_bit_field_1): Properly truncate the paradoxical
subreg of op0 to the original op0.
* expmed.c (store_bit_field_1): Use a temporary as the destination
instead of a paradoxical subreg when we need to truncate the result.
From-SVN: r149153
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 3f94ac779b9..c5405376808 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -685,6 +685,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, rtx xop0 = op0; rtx last = get_last_insn (); rtx pat; + bool copy_back = false; /* Add OFFSET into OP0's address. */ if (MEM_P (xop0)) @@ -699,6 +700,23 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, if (REG_P (xop0) && GET_MODE (xop0) != op_mode) xop0 = gen_rtx_SUBREG (op_mode, xop0, 0); + /* If the destination is a paradoxical subreg such that we need a + truncate to the inner mode, perform the insertion on a temporary and + truncate the result to the original destination. Note that we can't + just truncate the paradoxical subreg as (truncate:N (subreg:W (reg:N + X) 0)) is (reg:N X). */ + if (GET_CODE (xop0) == SUBREG + && REG_P (SUBREG_REG (xop0)) + && (!TRULY_NOOP_TRUNCATION + (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (xop0))), + GET_MODE_BITSIZE (op_mode)))) + { + rtx tem = gen_reg_rtx (op_mode); + emit_move_insn (tem, xop0); + xop0 = tem; + copy_back = true; + } + /* On big-endian machines, we count bits from the most significant. If the bit field insn does not, we must invert. */ @@ -758,15 +776,8 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, { emit_insn (pat); - /* If the mode of the insertion is wider than the mode of the - target register we created a paradoxical subreg for the - target. Truncate the paradoxical subreg of the target to - itself properly. */ - if (!TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (op0)), - GET_MODE_BITSIZE (op_mode)) - && (REG_P (xop0) - || GET_CODE (xop0) == SUBREG)) - convert_move (op0, xop0, true); + if (copy_back) + convert_move (op0, xop0, true); return true; } delete_insns_since (last); |