commit 6b07a31943bcbca2a4f6fae707cf3d7ae283d4dc Author: Richard Henderson Date: Wed Aug 1 16:10:37 2012 -0700 fixup insv diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 8259e2b..35c7fb5 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -4551,7 +4551,8 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) int bitsize = INTVAL (op1); int bitpos = INTVAL (op2); enum machine_mode mode = GET_MODE (dest); - enum machine_mode smode = smallest_mode_for_size (bitsize, MODE_INT); + enum machine_mode smode; + int smode_bsize, mode_bsize; rtx op, clobber; /* Generate INSERT IMMEDIATE (IILL et al). */ @@ -4587,6 +4588,10 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) return true; } + smode = smallest_mode_for_size (bitsize, MODE_INT); + smode_bsize = GET_MODE_BITSIZE (smode); + mode_bsize = GET_MODE_BITSIZE (mode); + /* Generate STORE CHARACTERS UNDER MASK (STCM et al). */ if (bitpos == 0 && (bitsize % BITS_PER_UNIT) == 0 @@ -4595,7 +4600,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) || const_int_operand (src, VOIDmode))) { /* Emit standard pattern if possible. */ - if (GET_MODE_BITSIZE (smode) == bitsize) + if (smode_bsize == bitsize) { emit_move_insn (adjust_address (dest, smode, 0), gen_lowpart (smode, src)); @@ -4608,7 +4613,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) int size = bitsize / BITS_PER_UNIT; rtx src_mem = adjust_address (force_const_mem (word_mode, src), BLKmode, - GET_MODE_SIZE (word_mode) - size); + UNITS_PER_WORD - size); dest = adjust_address (dest, BLKmode, 0); set_mem_size (dest, size); @@ -4619,22 +4624,22 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) /* (set (ze (mem)) (reg)). */ else if (register_operand (src, word_mode)) { - if (bitsize <= GET_MODE_BITSIZE (SImode)) + if (bitsize <= 32) emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1, const0_rtx), src); else { /* Emit st,stcmh sequence. */ - int stcmh_width = bitsize - GET_MODE_BITSIZE (SImode); + int stcmh_width = bitsize - 32; int size = stcmh_width / BITS_PER_UNIT; emit_move_insn (adjust_address (dest, SImode, size), gen_lowpart (SImode, src)); set_mem_size (dest, size); - emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, GEN_INT - (stcmh_width), const0_rtx), - gen_rtx_LSHIFTRT (word_mode, src, GEN_INT - (GET_MODE_BITSIZE (SImode)))); + emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, + GEN_INT (stcmh_width), + const0_rtx), + gen_rtx_LSHIFTRT (word_mode, src, GEN_INT (32))); } return true; } @@ -4649,7 +4654,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) && register_operand (dest, mode)) { /* Emit a strict_low_part pattern if possible. */ - if (bitpos == 0 && GET_MODE_BITSIZE (smode) == bitsize) + if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize) { op = gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (smode, dest)); op = gen_rtx_SET (VOIDmode, op, gen_lowpart (smode, src)); @@ -4728,7 +4733,12 @@ init_alignment_context (struct alignment_context *ac, rtx mem, ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode)); if (ac->aligned) - ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */ + { + ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */ + ac->shift = const0_rtx; + ac->modemask = GEN_INT (GET_MODE_MASK (mode)); + ac->modemaski = GEN_INT (~GET_MODE_MASK (mode)); + } else { /* Alignment is unknown. */ @@ -4755,15 +4765,17 @@ init_alignment_context (struct alignment_context *ac, rtx mem, ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset, NULL_RTX, 1, OPTAB_DIRECT); + /* Shift is the byte count, but we need the bitcount. */ + ac->shift = expand_simple_binop (SImode, ASHIFT, ac->shift, GEN_INT (3), + NULL_RTX, 1, OPTAB_DIRECT); + + /* Calculate masks. */ + ac->modemask = expand_simple_binop (SImode, ASHIFT, + GEN_INT (GET_MODE_MASK (mode)), + ac->shift, NULL_RTX, 1, OPTAB_DIRECT); + ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, + NULL_RTX, 1); } - /* Shift is the byte count, but we need the bitcount. */ - ac->shift = expand_simple_binop (SImode, MULT, ac->shift, GEN_INT (BITS_PER_UNIT), - NULL_RTX, 1, OPTAB_DIRECT); - /* Calculate masks. */ - ac->modemask = expand_simple_binop (SImode, ASHIFT, - GEN_INT (GET_MODE_MASK (mode)), ac->shift, - NULL_RTX, 1, OPTAB_DIRECT); - ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1); } /* A subroutine of s390_expand_cs_hqi. Insert INS into VAL. If possible, @@ -4781,7 +4793,7 @@ s390_two_part_insv (struct alignment_context *ac, rtx *seq1, rtx *seq2, start_sequence (); tmp = copy_to_mode_reg (SImode, val); if (s390_expand_insv (tmp, GEN_INT (GET_MODE_BITSIZE (mode)), - const0_rtx, ins)) + GEN_INT (32 - GET_MODE_BITSIZE (mode)), ins)) { *seq1 = NULL; *seq2 = get_insns ();