Hi, On Tue, Sep 4, 2012 at 12:33 AM, Andrew Pinski <andrew.pin...@caviumnetworks.com> wrote: > Hi, > On MIPS it is better sometimes not to use the word mode (DImode) but > rather SImode. The main reason is for 32bits, the value has to be > sign extended to 64bits so using the 32bit instruction for insertion > is allows for that to happen automatically. > > This patch implements this by adding a target hook which returns the > modes which are valid for doing the insertion and modifying > store_bit_field_1 to use them if they exists. > > OK? Bootstrapped and tested on both x86_64-linux-gnu and > mips64-linux-gnu with no regressions. > > Thanks, > Andrew Pinski > > > * target.h (gcc_target): Add mode_for_extraction_insv. > * expmed.c (store_bit_field_1): Use mode_for_extraction_insv > and split out into ... > (store_bit_field_2): Here. > * target-def.h (TARGET_MODE_FOR_EXTRACTION_INSV): Define. > (TARGET_INITIALIZER): Add TARGET_MODE_FOR_EXTRACTION_INSV. > * config/mips/mips.c (mips_mode_for_extraction_insv): New function. > (TARGET_MODE_FOR_EXTRACTION_INSV): Define.
This one has a problem for targets with !HAVE_insv since on those mode_for_extraction (EP_insv, 3) returns an invalid machine_mode and thus GET_MODE_BITSIZE (op_mode) is undefined since a value outside array boundaries is accessed. To fix this I put the following change on top: diff --git a/gcc/expmed.c b/gcc/expmed.c index 6afafd3..a55b2a8 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -361,7 +361,8 @@ store_bit_field_2 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, rtx op0 = str_rtx; int byte_offset; rtx orig_value; - unsigned int unit = (MEM_P (str_rtx)) ? BITS_PER_UNIT : GET_MODE_BITSIZE (op_mode); + unsigned int unit = (MEM_P (str_rtx)) ? BITS_PER_UNIT : + (HAVE_insv ? GET_MODE_BITSIZE (op_mode) : BITS_PER_WORD); while (GET_CODE (op0) == SUBREG) { Robert