diff mbox

Improve the mode which is used for insertion

Message ID CA+=Sn1mvqiugW9V4Jb3s9PXhy0VFo-Xz8h6oC7EL65PyPQeAzQ@mail.gmail.com
State New
Headers show

Commit Message

Andrew Pinski Sept. 3, 2012, 10:33 p.m. UTC
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.
diff mbox

Patch

Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 190863)
+++ doc/tm.texi	(working copy)
@@ -8853,6 +8853,10 @@  The default is that no label is emitted.
 If the target implements @code{TARGET_ASM_UNWIND_EMIT}, this hook may be used to emit a directive to install a personality hook into the unwind info.  This hook should not be used if dwarf2 unwind info is used.
 @end deftypefn
 
+@deftypefn {Target Hook} {enum machine_mode *} TARGET_MODE_FOR_EXTRACTION_INSV (void)
+Returns a list of the modes to try for doing a bitfield insertation
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_ASM_UNWIND_EMIT (FILE *@var{stream}, rtx @var{insn})
 This target hook emits assembly directives required to unwind the
 given instruction.  This is only used when @code{TARGET_EXCEPT_UNWIND_INFO}
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in	(revision 190863)
+++ doc/tm.texi.in	(working copy)
@@ -8734,6 +8734,8 @@  The default is that no label is emitted.
 
 @hook TARGET_ASM_EMIT_EXCEPT_PERSONALITY
 
+@hook TARGET_MODE_FOR_EXTRACTION_INSV
+
 @hook TARGET_ASM_UNWIND_EMIT
 This target hook emits assembly directives required to unwind the
 given instruction.  This is only used when @code{TARGET_EXCEPT_UNWIND_INFO}
Index: target.def
===================================================================
--- target.def	(revision 190863)
+++ target.def	(working copy)
@@ -2765,6 +2765,13 @@  DEFHOOKPOD
  @code{bool} @code{true}.",
  unsigned char, 1)
  
+/* Returns a list to the modes to try for doing a bitfield insertation. */
+DEFHOOK
+(mode_for_extraction_insv,
+ "Returns a list of the modes to try for doing a bitfield insertation",
+ enum machine_mode *, (void),
+ NULL)
+
 /* Leave the boolean fields at the end.  */
 
 /* True if we can create zeroed data by switching to a BSS section
Index: expmed.c
===================================================================
--- expmed.c	(revision 190863)
+++ expmed.c	(working copy)
@@ -394,29 +394,35 @@  mode_for_extraction (enum extraction_pat
   return data->operand[opno].mode;
 }
 
-/* A subroutine of store_bit_field, with the same arguments.  Return true
-   if the operation could be implemented.
+static bool
+store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
+		   unsigned HOST_WIDE_INT bitnum, 
+		   unsigned HOST_WIDE_INT bitregion_start,
+		   unsigned HOST_WIDE_INT bitregion_end,
+		   enum machine_mode fieldmode,
+		   rtx value, bool fallback_p);
+
+/* A subroutine of store_bit_field, with the same arguments, except OP_MODE is the
+   mode which tried to use for the inseration.  Return true if the operation
+   could be implemented.
 
    If FALLBACK_P is true, fall back to store_fixed_bit_field if we have
    no other way of implementing the operation.  If FALLBACK_P is false,
    return false instead.  */
 
 static bool
-store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
+store_bit_field_2 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 		   unsigned HOST_WIDE_INT bitnum,
 		   unsigned HOST_WIDE_INT bitregion_start,
 		   unsigned HOST_WIDE_INT bitregion_end,
 		   enum machine_mode fieldmode,
-		   rtx value, bool fallback_p)
+		   rtx value, enum machine_mode op_mode, bool fallback_p)
 {
-  unsigned int unit
-    = (MEM_P (str_rtx)) ? BITS_PER_UNIT : BITS_PER_WORD;
   unsigned HOST_WIDE_INT offset, bitpos;
   rtx op0 = str_rtx;
   int byte_offset;
   rtx orig_value;
-
-  enum machine_mode op_mode = mode_for_extraction (EP_insv, 3);
+  unsigned int unit = (MEM_P (str_rtx)) ? BITS_PER_UNIT : GET_MODE_BITSIZE (op_mode);
 
   while (GET_CODE (op0) == SUBREG)
     {
@@ -876,6 +882,46 @@  store_bit_field_1 (rtx str_rtx, unsigned
   return true;
 }
 
+/* A subroutine of store_bit_field, with the same arguments.  Return true
+   if the operation could be implemented.
+
+   If FALLBACK_P is true, fall back to store_fixed_bit_field if we have
+   no other way of implementing the operation.  If FALLBACK_P is false,
+   return false instead.  */
+static bool
+store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
+		   unsigned HOST_WIDE_INT bitnum, 
+		   unsigned HOST_WIDE_INT bitregion_start,
+		   unsigned HOST_WIDE_INT bitregion_end,
+		   enum machine_mode fieldmode,
+		   rtx value, bool fallback_p)
+{
+  enum machine_mode *modes;
+  enum machine_mode op_mode = mode_for_extraction (EP_insv, 3);
+  if (MEM_P (str_rtx) || targetm.mode_for_extraction_insv == NULL)
+    return store_bit_field_2 (str_rtx, bitsize,
+		   bitnum, bitregion_start,
+		   bitregion_end, fieldmode,
+		   value, op_mode, fallback_p);
+  modes = targetm.mode_for_extraction_insv();
+  gcc_assert (*modes != BLKmode);
+  while (modes[1] != BLKmode)
+    {
+      if (GET_MODE (str_rtx) == *modes)
+	if (store_bit_field_2 (str_rtx, bitsize,
+			       bitnum, bitregion_start,
+			       bitregion_end, fieldmode,
+			       value, *modes, false))
+	  return true;
+      modes++;
+    }
+  
+  return store_bit_field_2 (str_rtx, bitsize,
+			    bitnum, bitregion_start,
+			    bitregion_end, fieldmode,
+			    value, *modes, fallback_p);
+}
+
 /* Generate code to store value from rtx VALUE
    into a bit-field within structure STR_RTX
    containing BITSIZE bits starting at bit BITNUM.
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c	(revision 190863)
+++ config/mips/mips.c	(working copy)
@@ -16752,6 +16752,16 @@  mips_mulsidi3_gen_fn (enum rtx_code ext_
       return signed_p ? gen_mulsidi3_32bit : gen_umulsidi3_32bit;
     }
 }
+
+/* Return a list of modes that can be used for insv and extv.  */
+static enum machine_mode *
+mips_mode_for_extraction_insv (void)
+{
+  static enum machine_mode modes64[] = {SImode, DImode, BLKmode};
+  static enum machine_mode modes32[] = {SImode, BLKmode};
+  return TARGET_64BIT ? modes64 : modes32;
+}
+
 
 /* Return the size in bytes of the trampoline code, padded to
    TRAMPOLINE_ALIGNMENT bits.  The static chain pointer and target
@@ -17867,6 +17877,9 @@  mips_expand_vec_minmax (rtx target, rtx
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span
 
+#undef TARGET_MODE_FOR_EXTRACTION_INSV
+#define TARGET_MODE_FOR_EXTRACTION_INSV mips_mode_for_extraction_insv
+
 #undef TARGET_ASM_FINAL_POSTSCAN_INSN
 #define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn