aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2012-11-28 20:13:22 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2012-11-28 20:13:22 +0000
commitd9d7fb9451631dbe6b3a6fce2a8b9971efd80d44 (patch)
treeaaafc068a028daa1ab2ecddaa3afa63e83019d13 /gcc/expmed.c
parentaf0b051421432297cc23c6338f576b349509eb02 (diff)
gcc/
PR middle-end/55438 * expmed.c (simple_mem_bitfield_p): New function, extracted from store_bit_field_1 and extract_bit_field_1. Use GET_MODE_ALIGNMENT rather than bitsize when checking the alignment. (store_bit_field_1, extract_bit_field_1): Call it. * stor-layout.c (bit_field_mode_iterator::bit_field_mode_iterator): Don't limit ALIGN_. Assume that memory is mapped in chunks of at least word size, regardless of BIGGEST_ALIGNMENT. (bit_field_mode_iterator::get_mode): Use GET_MODE_ALIGNMENT rather than unit when checking the alignment. (get_best_mode): Use GET_MODE_ALIGNMENT. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@193905 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index fc29ac41d72..d75f031a8c3 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -416,6 +416,21 @@ lowpart_bit_field_p (unsigned HOST_WIDE_INT bitnum,
else
return bitnum % BITS_PER_WORD == 0;
}
+
+/* Return true if OP is a memory and if a bitfield of size BITSIZE at
+ bit number BITNUM can be treated as a simple value of mode MODE. */
+
+static bool
+simple_mem_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize,
+ unsigned HOST_WIDE_INT bitnum, enum machine_mode mode)
+{
+ return (MEM_P (op0)
+ && bitnum % BITS_PER_UNIT == 0
+ && bitsize == GET_MODE_BITSIZE (mode)
+ && (!SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (op0))
+ || (bitnum % GET_MODE_ALIGNMENT (mode) == 0
+ && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode))));
+}
/* Try to use instruction INSV to store VALUE into a field of OP0.
BITSIZE and BITNUM are as for store_bit_field. */
@@ -624,12 +639,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
/* 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. */
- if (MEM_P (op0)
- && bitnum % BITS_PER_UNIT == 0
- && bitsize == GET_MODE_BITSIZE (fieldmode)
- && (!SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
- || (bitnum % bitsize == 0
- && MEM_ALIGN (op0) % bitsize == 0)))
+ if (simple_mem_bitfield_p (op0, bitsize, bitnum, fieldmode))
{
op0 = adjust_bitfield_address (op0, fieldmode, bitnum / BITS_PER_UNIT);
emit_move_insn (op0, value);
@@ -1455,12 +1465,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
/* Extraction of a full MODE1 value can be done with a load as long as
the field is on a byte boundary and is sufficiently aligned. */
- if (MEM_P (op0)
- && bitnum % BITS_PER_UNIT == 0
- && bitsize == GET_MODE_BITSIZE (mode1)
- && (!SLOW_UNALIGNED_ACCESS (mode1, MEM_ALIGN (op0))
- || (bitnum % bitsize == 0
- && MEM_ALIGN (op0) % bitsize == 0)))
+ if (simple_mem_bitfield_p (op0, bitsize, bitnum, mode1))
{
op0 = adjust_bitfield_address (op0, mode1, bitnum / BITS_PER_UNIT);
return convert_extracted_bit_field (op0, mode, tmode, unsignedp);