From c600a15524cc3200cd4ee3997e162e9205b79a70 Mon Sep 17 00:00:00 2001 From: Adam Nemet Date: Wed, 1 Jul 2009 21:22:28 +0000 Subject: revert: expmed.c (store_bit_field_1): Properly truncate the paradoxical subreg of op0 to the original op0. Revert: 2009-01-11 Adam Nemet * 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 --- gcc/expmed.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'gcc/expmed.c') diff --git a/gcc/expmed.c b/gcc/expmed.c index 3f94ac7..c540537 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); -- cgit v1.1