===================================================================
@@ -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}
===================================================================
@@ -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}
===================================================================
@@ -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
===================================================================
@@ -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.
===================================================================
@@ -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