From: Eric Christopher Date: Fri, 22 Feb 2002 00:07:06 +0000 (+0000) Subject: expmed.c (store_bit_field): Try to simplify the subreg before generating a new one... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c410d49e434d06e93c9163eda0a26891e6116a7e;p=gcc.git expmed.c (store_bit_field): Try to simplify the subreg before generating a new one when... 2002-02-21 Eric Christopher * expmed.c (store_bit_field): Try to simplify the subreg before generating a new one when when the mode size of value is less than maxmode. From-SVN: r49946 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8a8dcac21e7..e4b437ceb2f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-02-21 Eric Christopher + + * expmed.c (store_bit_field): Try to simplify the subreg + before generating a new one when when the mode size of + value is less than maxmode. + 2002-02-21 Richard Henderson * emit-rtl.c (offset_address): Use simplify_gen_binary rather @@ -95,7 +101,7 @@ Thu Feb 21 15:35:46 2002 J"orn Rennecke bits of SImode const_int. (includes_rshift_p): Likewise. (print_operand): Call mask_operand and mask64_operand with correct - mode. + mode. (rs6000_output_function_epilogue): Pad traceback table to word. * config/rs6000/rs6000.h (MASK_64BIT): Correct comment. (EXTRA_CONSTRAINT, 'S' and 'T'): Call mask_operand and @@ -161,7 +167,7 @@ Thu Feb 21 15:35:46 2002 J"orn Rennecke (ix86_expand_unop1_builtin): Likewise. 2002-02-20 Philip Blundell - + PR 5705 * config/arm/arm.h (HARD_REGNO_RENAME_OK): New macro. @@ -203,7 +209,7 @@ Wed Feb 20 00:03:25 EST 2002 Alan Matsuoka * cppinit.c (init_dependency_output): Take deps output file from -o if none given with -MF. Suppress normal output. - * gcc.c (cpp_unique_options): Have -M and -MM imply -E. + * gcc.c (cpp_unique_options): Have -M and -MM imply -E. * doc/cpp.texi, doc/invoke.texi: Update. 2002-02-19 Zack Weinberg @@ -217,7 +223,7 @@ Wed Feb 20 00:03:25 EST 2002 Alan Matsuoka really_call_used[VRSAVE_REGNO] if not Altivec. 2002-02-19 Alan Modra - + * config/rs6000/rs6000.c (u_short_cint_operand): Mask op with MODE_MASK. (constant_pool_expr_1): Fix formatting. @@ -283,7 +289,7 @@ Tue Feb 19 20:13:57 2002 Richard Kenner (arm_assemble_integer): Likewise. * config/arm/arm.h (ARM_ENCODE_CALL_TYPE): Allow any decl to be marked local. - + 2002-02-19 matthew green * config.gcc (sparc-*-netbsdelf*): Enable target. @@ -465,7 +471,7 @@ Tue Feb 19 12:37:23 CET 2002 Jan Hubicka (decode_rtx_const): Add case for vector. * config/rs6000/rs6000-protos.h: Add zero_constant. - + * config/rs6000/rs6000.c (rs6000_emit_move): Handle vector constants. Force easy vector constants into memory. (easy_vector_constant): New. @@ -537,7 +543,7 @@ Mon Feb 18 11:55:55 CET 2002 Jan Hubicka 2002-02-18 David Billinghurst * objc/objc-act.c (handle_impent): Remove leading '*' - from objc_class_name. + from objc_class_name. 2002-02-17 Richard Henderson @@ -593,7 +599,7 @@ Mon Feb 18 11:55:55 CET 2002 Jan Hubicka * config/arc/arc.c config/fr30/fr30.c config/m32r/m32r.c config/m88k/m88k.c : Adapt all calls to output_operand_lossage. Update copyright date where necessary. - + * config/i386/i386.c (print_operand): Likewise. Remove use of sprintf. @@ -662,15 +668,15 @@ Sat Feb 16 13:39:09 2002 Richard Kenner 2002-02-16 Ulrich Weigand - * config/s390/s390.c (pool_stop_uid, other_chunk, far_away, + * config/s390/s390.c (pool_stop_uid, other_chunk, far_away, check_and_change_labels, s390_final_chunkify): Delete. (s390_split_branches, s390_chunkify_pool): New functions. (s390_function_prologue): Call them. - + * config/s390/s390.h (S390_REL_MAX): Delete. (S390_CHUNK_MAX, S390_CHUNK_OV): Adjust values. - * config/s390/s390.md (cjump, icjump, jump): Fix length + * config/s390/s390.md (cjump, icjump, jump): Fix length attribute calculation. diff --git a/gcc/expmed.c b/gcc/expmed.c index 11304618aa1..b3d94c2376f 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -54,7 +54,7 @@ static void do_cmp_and_jump PARAMS ((rtx, rtx, enum rtx_code, enum machine_mode, rtx)); /* Non-zero means divides or modulus operations are relatively cheap for - powers of two, so don't use branches; emit the operation instead. + powers of two, so don't use branches; emit the operation instead. Usually, this will mean that the MD file will emit non-branch sequences. */ @@ -333,7 +333,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size) If the target is memory, storing any naturally aligned field can be done with a simple store. For targets that support fast unaligned memory, any naturally sized, unit aligned field can be done directly. */ - + byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT + (offset * UNITS_PER_WORD); @@ -576,7 +576,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size) && GET_MODE_BITSIZE (bestmode) > MEM_ALIGN (op0))) goto insv_loses; - /* Adjust address to point to the containing unit of that mode. + /* Adjust address to point to the containing unit of that mode. Compute offset as multiple of this unit, counting in bytes. */ unit = GET_MODE_BITSIZE (bestmode); offset = (bitnum / unit) * GET_MODE_SIZE (bestmode); @@ -630,8 +630,17 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size) if we must narrow it, be sure we do it correctly. */ if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode)) - value1 = simplify_gen_subreg (maxmode, value1, - GET_MODE (value1), 0); + { + rtx tmp; + + tmp = simplify_subreg (maxmode, value1, GET_MODE (value), 0); + if (! tmp) + tmp = simplify_gen_subreg (maxmode, + force_reg (GET_MODE (value), + value1), + GET_MODE (value), 0); + value1 = tmp; + } else value1 = gen_lowpart (maxmode, value1); } @@ -712,7 +721,7 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value) { /* Get the proper mode to use for this field. We want a mode that includes the entire field. If such a mode would be larger than - a word, we won't be doing the extraction the normal way. + a word, we won't be doing the extraction the normal way. We don't want a mode bigger than the destination. */ mode = GET_MODE (op0); @@ -1061,7 +1070,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, /* ??? We currently assume TARGET is at least as big as BITSIZE. If that's wrong, the solution is to test for it and set TARGET to 0 if needed. */ - + /* If OP0 is a register, BITPOS must count within a word. But as we have it, it counts within whatever size OP0 now has. On a bigendian machine, these are not the same, so convert. */ @@ -1128,7 +1137,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, } /* Handle fields bigger than a word. */ - + if (bitsize > BITS_PER_WORD) { /* Here we transfer the words of the field @@ -1200,14 +1209,14 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0), NULL_RTX, 0); } - + /* From here on we know the desired field is smaller than a word. */ /* Check if there is a correspondingly-sized integer field, so we can safely extract it as one size of integer, if necessary; then truncate or extend to the size that is wanted; then use SUBREGs or convert_to_mode to get one of the modes we really wanted. */ - + int_mode = int_mode_for_mode (tmode); if (int_mode == BLKmode) int_mode = int_mode_for_mode (mode); @@ -1366,7 +1375,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, } else extzv_loses: - target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, + target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, bitpos, target, 1); } else @@ -1492,10 +1501,10 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, bitpos, target, 0); } - } + } else extv_loses: - target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, + target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, bitpos, target, 0); } if (target == spec_target) @@ -1660,7 +1669,7 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, } return expand_shift (RSHIFT_EXPR, mode, op0, - build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0), + build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0), target, 0); } @@ -1685,7 +1694,7 @@ mask_rtx (mode, bitpos, bitsize, complement) if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT) masklow &= ((unsigned HOST_WIDE_INT) -1 >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize)); - + if (bitpos <= HOST_BITS_PER_WIDE_INT) maskhigh = -1; else @@ -1975,7 +1984,7 @@ expand_shift (code, mode, shifted, amount, target, unsignedp) && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode)) temp = expand_binop (mode, left ? rotr_optab : rotl_optab, - shifted, + shifted, GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1)), target, unsignedp, methods); @@ -2006,7 +2015,7 @@ expand_shift (code, mode, shifted, amount, target, unsignedp) } /* We used to try extzv here for logical right shifts, but that was - only useful for one machine, the VAX, and caused poor code + only useful for one machine, the VAX, and caused poor code generation there for lshrdi3, so the code was deleted and a define_expand for lshrsi3 was added to vax.md. */ } @@ -2147,7 +2156,7 @@ synth_mult (alg_out, t, cost_limit) for (w = 1; (w & t) != 0; w <<= 1) ; /* If T was -1, then W will be zero after the loop. This is another - case where T ends with ...111. Handling this with (T + 1) and + case where T ends with ...111. Handling this with (T + 1) and subtract 1 produces slightly better code and results in algorithm selection much faster than treating it like the ...0111 case below. */ @@ -2427,7 +2436,7 @@ expand_mult (mode, op0, op1, target, unsignedp) && ! preserve) ? target : 0; rtx accum_target = preserve ? 0 : accum; - + switch (alg.op[opno]) { case alg_shift: @@ -2509,7 +2518,7 @@ expand_mult (mode, op0, op1, target, unsignedp) } insn = get_last_insn (); - set_unique_reg_note (insn, + set_unique_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, GEN_INT (val_so_far))); @@ -2535,7 +2544,7 @@ expand_mult (mode, op0, op1, target, unsignedp) /* This used to use umul_optab if unsigned, but for non-widening multiply there is no difference between signed and unsigned. */ - op0 = expand_binop (mode, + op0 = expand_binop (mode, ! unsignedp && flag_trapv && (GET_MODE_CLASS(mode) == MODE_INT) ? smulv_optab : smul_optab, @@ -2823,7 +2832,7 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost) { op1 = force_reg (mode, op1); goto try; - } + } /* Try widening the mode and perform a non-widening multiplication. */ moptab = smul_optab; @@ -3230,7 +3239,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) if (insn != last && (set = single_set (insn)) != 0 && SET_DEST (set) == quotient) - set_unique_reg_note (insn, + set_unique_reg_note (insn, REG_EQUAL, gen_rtx_UDIV (compute_mode, op0, op1)); } @@ -3318,7 +3327,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) && SET_DEST (set) == quotient && abs_d < ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))) - set_unique_reg_note (insn, + set_unique_reg_note (insn, REG_EQUAL, gen_rtx_DIV (compute_mode, op0, @@ -3409,7 +3418,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) if (insn != last && (set = single_set (insn)) != 0 && SET_DEST (set) == quotient) - set_unique_reg_note (insn, + set_unique_reg_note (insn, REG_EQUAL, gen_rtx_DIV (compute_mode, op0, op1)); } @@ -3902,7 +3911,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) emit_label (label); } return gen_lowpart (mode, rem_flag ? remainder : quotient); - + default: abort (); } @@ -4056,42 +4065,42 @@ make_tree (type, x) elt = CONST_VECTOR_ELT (x, i); t = tree_cons (NULL_TREE, make_tree (type, elt), t); } - + return build_vector (type, t); } case PLUS: return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)), make_tree (type, XEXP (x, 1)))); - + case MINUS: return fold (build (MINUS_EXPR, type, make_tree (type, XEXP (x, 0)), make_tree (type, XEXP (x, 1)))); - + case NEG: return fold (build1 (NEGATE_EXPR, type, make_tree (type, XEXP (x, 0)))); case MULT: return fold (build (MULT_EXPR, type, make_tree (type, XEXP (x, 0)), make_tree (type, XEXP (x, 1)))); - + case ASHIFT: return fold (build (LSHIFT_EXPR, type, make_tree (type, XEXP (x, 0)), make_tree (type, XEXP (x, 1)))); - + case LSHIFTRT: return fold (convert (type, build (RSHIFT_EXPR, unsigned_type (type), make_tree (unsigned_type (type), XEXP (x, 0)), make_tree (type, XEXP (x, 1))))); - + case ASHIFTRT: return fold (convert (type, build (RSHIFT_EXPR, signed_type (type), make_tree (signed_type (type), XEXP (x, 0)), make_tree (type, XEXP (x, 1))))); - + case DIV: if (TREE_CODE (type) != REAL_TYPE) t = signed_type (type); @@ -4182,7 +4191,7 @@ expand_and (mode, op0, op1, target) Return 0 if that cannot be done. MODE is the mode to use for OP0 and OP1 should they be CONST_INTs. If - it is VOIDmode, they cannot both be CONST_INT. + it is VOIDmode, they cannot both be CONST_INT. UNSIGNEDP is for the case where we have to widen the operands to perform the operation. It says to use zero-extension. @@ -4230,7 +4239,7 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep) if (mode == VOIDmode) mode = GET_MODE (op0); - /* For some comparisons with 1 and -1, we can convert this to + /* For some comparisons with 1 and -1, we can convert this to comparisons with zero. This will often produce more opportunities for store-flag insns. */ @@ -4433,7 +4442,7 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep) else abort (); - /* If we were converting to a smaller mode, do the + /* If we were converting to a smaller mode, do the conversion now. */ if (target_mode != compare_mode) { @@ -4478,7 +4487,7 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep) return tem; } - /* Some other cases we can do are EQ, NE, LE, and GT comparisons with + /* Some other cases we can do are EQ, NE, LE, and GT comparisons with the constant zero. Reject all other comparisons at this point. Only do LE and GT if branches are expensive since they are expensive on 2-operand machines. */ @@ -4540,22 +4549,22 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep) tem = expand_binop (mode, sub_optab, tem, op0, subtarget, 0, OPTAB_WIDEN); } - + if (code == EQ || code == NE) { /* For EQ or NE, one way to do the comparison is to apply an operation that converts the operand into a positive number if it is non-zero or zero if it was originally zero. Then, for EQ, we subtract 1 and for NE we negate. This puts the result in the sign bit. Then we - normalize with a shift, if needed. + normalize with a shift, if needed. Two operations that can do the above actions are ABS and FFS, so try them. If that doesn't work, and MODE is smaller than a full word, we can use zero-extension to the wider mode (an unsigned conversion) as the operation. */ - /* Note that ABS doesn't yield a positive number for INT_MIN, but - that is compensated by the subsequent overflow when subtracting + /* Note that ABS doesn't yield a positive number for INT_MIN, but + that is compensated by the subsequent overflow when subtracting one / negating. */ if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)