expr.c (emit_group_load_1): Update calls to extract_bit_field.

* expr.c (emit_group_load_1): Update calls to extract_bit_field.
	(copy_blkmode_from_reg): Likewise.
	(read_complex_part): Likewise.
	(expand_expr_real_1): Calculate packedp and pass it to
	extract_bit_field.
	* expr.h (extract_bit_field): Update declaration.
	* calls.c (store_unaligned_arguments_into_pseudos): Update call
	to extract_bit_field.
	* expmed.c (extract_fixed_bit_field): Update calls to
	extract_fixed_bit_field.
	(store_split_bit_field): Likewise.
	(extract_bit_field_1): Add new argument packedp.
	(extract_bit_field): Add new argument packedp.
	(extract_fixed_bit_field): Add new argument packedp and let
	packed attribute override volatile.
	* stmt.c (expand_return): Update call to extract_bit_field.

From-SVN: r165799
This commit is contained in:
Jie Zhang 2010-10-22 00:40:15 +00:00 committed by Jie Zhang
parent f40872465c
commit 62519f7fed
6 changed files with 66 additions and 21 deletions

View File

@ -1,3 +1,22 @@
2010-10-22 Jie Zhang <jie@codesourcery.com>
* expr.c (emit_group_load_1): Update calls to extract_bit_field.
(copy_blkmode_from_reg): Likewise.
(read_complex_part): Likewise.
(expand_expr_real_1): Calculate packedp and pass it to
extract_bit_field.
* expr.h (extract_bit_field): Update declaration.
* calls.c (store_unaligned_arguments_into_pseudos): Update call
to extract_bit_field.
* expmed.c (extract_fixed_bit_field): Update calls to
extract_fixed_bit_field.
(store_split_bit_field): Likewise.
(extract_bit_field_1): Add new argument packedp.
(extract_bit_field): Add new argument packedp.
(extract_fixed_bit_field): Add new argument packedp and let
packed attribute override volatile.
* stmt.c (expand_return): Update call to extract_bit_field.
2010-10-21 Nathan Froyd <froydnj@codesourcery.com> 2010-10-21 Nathan Froyd <froydnj@codesourcery.com>
* config/spu/spu.c (spu_function_arg): Dereference CUM parameter. * config/spu/spu.c (spu_function_arg): Dereference CUM parameter.

View File

@ -886,7 +886,7 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD); int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
args[i].aligned_regs[j] = reg; args[i].aligned_regs[j] = reg;
word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX, word = extract_bit_field (word, bitsize, 0, 1, false, NULL_RTX,
word_mode, word_mode); word_mode, word_mode);
/* There is no need to restrict this code to loading items /* There is no need to restrict this code to loading items

View File

@ -53,7 +53,7 @@ static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT,
static rtx extract_fixed_bit_field (enum machine_mode, rtx, static rtx extract_fixed_bit_field (enum machine_mode, rtx,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, rtx, int); unsigned HOST_WIDE_INT, rtx, int, bool);
static rtx mask_rtx (enum machine_mode, int, int, int); static rtx mask_rtx (enum machine_mode, int, int, int);
static rtx lshift_value (enum machine_mode, rtx, int, int); static rtx lshift_value (enum machine_mode, rtx, int, int);
static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT, static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT,
@ -1083,7 +1083,7 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
endianness compensation) to fetch the piece we want. */ endianness compensation) to fetch the piece we want. */
part = extract_fixed_bit_field (word_mode, value, 0, thissize, part = extract_fixed_bit_field (word_mode, value, 0, thissize,
total_bits - bitsize + bitsdone, total_bits - bitsize + bitsdone,
NULL_RTX, 1); NULL_RTX, 1, false);
} }
else else
{ {
@ -1094,7 +1094,7 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
& (((HOST_WIDE_INT) 1 << thissize) - 1)); & (((HOST_WIDE_INT) 1 << thissize) - 1));
else else
part = extract_fixed_bit_field (word_mode, value, 0, thissize, part = extract_fixed_bit_field (word_mode, value, 0, thissize,
bitsdone, NULL_RTX, 1); bitsdone, NULL_RTX, 1, false);
} }
/* If OP0 is a register, then handle OFFSET here. /* If OP0 is a register, then handle OFFSET here.
@ -1160,7 +1160,8 @@ convert_extracted_bit_field (rtx x, enum machine_mode mode,
static rtx static rtx
extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, unsigned HOST_WIDE_INT bitnum,
int unsignedp, bool packedp, rtx target,
enum machine_mode mode, enum machine_mode tmode, enum machine_mode mode, enum machine_mode tmode,
bool fallback_p) bool fallback_p)
{ {
@ -1441,7 +1442,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
rtx result_part rtx result_part
= extract_bit_field (op0, MIN (BITS_PER_WORD, = extract_bit_field (op0, MIN (BITS_PER_WORD,
bitsize - i * BITS_PER_WORD), bitsize - i * BITS_PER_WORD),
bitnum + bit_offset, 1, target_part, mode, bitnum + bit_offset, 1, false, target_part, mode,
word_mode); word_mode);
gcc_assert (target_part); gcc_assert (target_part);
@ -1640,7 +1641,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
xop0 = adjust_address (op0, bestmode, xoffset); xop0 = adjust_address (op0, bestmode, xoffset);
xop0 = force_reg (bestmode, xop0); xop0 = force_reg (bestmode, xop0);
result = extract_bit_field_1 (xop0, bitsize, xbitpos, result = extract_bit_field_1 (xop0, bitsize, xbitpos,
unsignedp, target, unsignedp, packedp, target,
mode, tmode, false); mode, tmode, false);
if (result) if (result)
return result; return result;
@ -1654,7 +1655,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
return NULL; return NULL;
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
bitpos, target, unsignedp); bitpos, target, unsignedp, packedp);
return convert_extracted_bit_field (target, mode, tmode, unsignedp); return convert_extracted_bit_field (target, mode, tmode, unsignedp);
} }
@ -1665,6 +1666,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
STR_RTX is the structure containing the byte (a REG or MEM). STR_RTX is the structure containing the byte (a REG or MEM).
UNSIGNEDP is nonzero if this is an unsigned bit field. UNSIGNEDP is nonzero if this is an unsigned bit field.
PACKEDP is nonzero if the field has the packed attribute.
MODE is the natural mode of the field value once extracted. MODE is the natural mode of the field value once extracted.
TMODE is the mode the caller would like the value to have; TMODE is the mode the caller would like the value to have;
but the value may be returned with type MODE instead. but the value may be returned with type MODE instead.
@ -1676,10 +1678,10 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
rtx rtx
extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, unsigned HOST_WIDE_INT bitnum, int unsignedp, bool packedp,
enum machine_mode mode, enum machine_mode tmode) rtx target, enum machine_mode mode, enum machine_mode tmode)
{ {
return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, packedp,
target, mode, tmode, true); target, mode, tmode, true);
} }
@ -1695,6 +1697,8 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
which is significant on bigendian machines.) which is significant on bigendian machines.)
UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value). UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value).
PACKEDP is true if the field has the packed attribute.
If TARGET is nonzero, attempts to store the value there If TARGET is nonzero, attempts to store the value there
and return TARGET, but this is not guaranteed. and return TARGET, but this is not guaranteed.
If TARGET is not used, create a pseudo-reg of mode TMODE for the value. */ If TARGET is not used, create a pseudo-reg of mode TMODE for the value. */
@ -1704,7 +1708,7 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
unsigned HOST_WIDE_INT offset, unsigned HOST_WIDE_INT offset,
unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitsize,
unsigned HOST_WIDE_INT bitpos, rtx target, unsigned HOST_WIDE_INT bitpos, rtx target,
int unsignedp) int unsignedp, bool packedp)
{ {
unsigned int total_bits = BITS_PER_WORD; unsigned int total_bits = BITS_PER_WORD;
enum machine_mode mode; enum machine_mode mode;
@ -1769,6 +1773,22 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
static bool informed_about_misalignment = false; static bool informed_about_misalignment = false;
bool warned; bool warned;
if (packedp)
{
if (bitsize == total_bits)
warned = warning_at (input_location, OPT_fstrict_volatile_bitfields,
"multiple accesses to volatile structure member"
" because of packed attribute");
else
warned = warning_at (input_location, OPT_fstrict_volatile_bitfields,
"multiple accesses to volatile structure bitfield"
" because of packed attribute");
return extract_split_bit_field (op0, bitsize,
bitpos + offset * BITS_PER_UNIT,
unsignedp);
}
if (bitsize == total_bits) if (bitsize == total_bits)
warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, warned = warning_at (input_location, OPT_fstrict_volatile_bitfields,
"mis-aligned access used for structure member"); "mis-aligned access used for structure member");
@ -1971,7 +1991,7 @@ extract_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
extract_fixed_bit_field wants offset in bytes. */ extract_fixed_bit_field wants offset in bytes. */
part = extract_fixed_bit_field (word_mode, word, part = extract_fixed_bit_field (word_mode, word,
offset * unit / BITS_PER_UNIT, offset * unit / BITS_PER_UNIT,
thissize, thispos, 0, 1); thissize, thispos, 0, 1, false);
bitsdone += thissize; bitsdone += thissize;
/* Shift this part into place for the result. */ /* Shift this part into place for the result. */

View File

@ -1703,7 +1703,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
&& (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)) && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode))
tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT, tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
(bytepos % slen0) * BITS_PER_UNIT, (bytepos % slen0) * BITS_PER_UNIT,
1, NULL_RTX, mode, mode); 1, false, NULL_RTX, mode, mode);
} }
else else
{ {
@ -1713,7 +1713,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
mem = assign_stack_temp (GET_MODE (src), slen, 0); mem = assign_stack_temp (GET_MODE (src), slen, 0);
emit_move_insn (mem, src); emit_move_insn (mem, src);
tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT, tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
0, 1, NULL_RTX, mode, mode); 0, 1, false, NULL_RTX, mode, mode);
} }
} }
/* FIXME: A SIMD parallel will eventually lead to a subreg of a /* FIXME: A SIMD parallel will eventually lead to a subreg of a
@ -1754,7 +1754,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
tmps[i] = src; tmps[i] = src;
else else
tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT, tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
bytepos * BITS_PER_UNIT, 1, NULL_RTX, bytepos * BITS_PER_UNIT, 1, false, NULL_RTX,
mode, mode); mode, mode);
if (shift) if (shift)
@ -2167,7 +2167,7 @@ copy_blkmode_from_reg (rtx tgtblk, rtx srcreg, tree type)
bitpos for the destination store (left justified). */ bitpos for the destination store (left justified). */
store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, copy_mode, store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, copy_mode,
extract_bit_field (src, bitsize, extract_bit_field (src, bitsize,
xbitpos % BITS_PER_WORD, 1, xbitpos % BITS_PER_WORD, 1, false,
NULL_RTX, copy_mode, copy_mode)); NULL_RTX, copy_mode, copy_mode));
} }
@ -2924,7 +2924,7 @@ read_complex_part (rtx cplx, bool imag_p)
} }
return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
true, NULL_RTX, imode, imode); true, false, NULL_RTX, imode, imode);
} }
/* A subroutine of emit_move_insn_1. Yet another lowpart generator. /* A subroutine of emit_move_insn_1. Yet another lowpart generator.
@ -8938,6 +8938,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
HOST_WIDE_INT bitsize, bitpos; HOST_WIDE_INT bitsize, bitpos;
tree offset; tree offset;
int volatilep = 0, must_force_mem; int volatilep = 0, must_force_mem;
bool packedp = false;
tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset, tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
&mode1, &unsignedp, &volatilep, true); &mode1, &unsignedp, &volatilep, true);
rtx orig_op0, memloc; rtx orig_op0, memloc;
@ -8947,6 +8948,11 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
infinitely recurse. */ infinitely recurse. */
gcc_assert (tem != exp); gcc_assert (tem != exp);
if (TYPE_PACKED (TREE_TYPE (TREE_OPERAND (exp, 0)))
|| (TREE_CODE (TREE_OPERAND (exp, 1)) == FIELD_DECL
&& DECL_PACKED (TREE_OPERAND (exp, 1))))
packedp = true;
/* If TEM's type is a union of variable size, pass TARGET to the inner /* If TEM's type is a union of variable size, pass TARGET to the inner
computation, since it will need a temporary and TARGET is known computation, since it will need a temporary and TARGET is known
to have to do. This occurs in unchecked conversion in Ada. */ to have to do. This occurs in unchecked conversion in Ada. */
@ -9159,7 +9165,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
if (MEM_P (op0) && REG_P (XEXP (op0, 0))) if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0)); mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, packedp,
(modifier == EXPAND_STACK_PARM (modifier == EXPAND_STACK_PARM
? NULL_RTX : target), ? NULL_RTX : target),
ext_mode, ext_mode); ext_mode, ext_mode);

View File

@ -668,7 +668,7 @@ mode_for_extraction (enum extraction_pattern, int);
extern void store_bit_field (rtx, unsigned HOST_WIDE_INT, extern void store_bit_field (rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, enum machine_mode, rtx); unsigned HOST_WIDE_INT, enum machine_mode, rtx);
extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT, extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, int, rtx, unsigned HOST_WIDE_INT, int, bool, rtx,
enum machine_mode, enum machine_mode); enum machine_mode, enum machine_mode);
extern rtx extract_low_bits (enum machine_mode, enum machine_mode, rtx); extern rtx extract_low_bits (enum machine_mode, enum machine_mode, rtx);
extern rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int); extern rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int);

View File

@ -1739,7 +1739,7 @@ expand_return (tree retval)
xbitpos for the destination store (right justified). */ xbitpos for the destination store (right justified). */
store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode, store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode,
extract_bit_field (src, bitsize, extract_bit_field (src, bitsize,
bitpos % BITS_PER_WORD, 1, bitpos % BITS_PER_WORD, 1, false,
NULL_RTX, word_mode, word_mode)); NULL_RTX, word_mode, word_mode));
} }