Commit 04050c69 by Richard Kenner Committed by Richard Kenner

expmed.c (extract_bit_field): No longer pass in alignment.

	* expmed.c (extract_bit_field): No longer pass in alignment.
	(extract_fixed_bit_field, extract_split_bit_field): Likewise.
	(store_bit_field, store_fixed_bit_field, store_split_bit_field):
	Likewise.
	* expr.c (store_constructor, store_constructor_field): Likewise.
	(store_field, emit_group_load, emit_group_store): Likewise.
	* expr.h (emit_group_load, emit_group_store): Delete ALIGN parm.
	(store_bit_field, extract_bit_field): Likewise.
	* calls.c, expr.c, function.c: Change calls to above functions.
	* ifcvt.c, stmt.c: Likewise.

From-SVN: r46926
parent d746694a
Sun Nov 11 05:56:01 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> Sun Nov 11 05:56:01 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expmed.c (extract_bit_field): No longer pass in alignment.
(extract_fixed_bit_field, extract_split_bit_field): Likewise.
(store_bit_field, store_fixed_bit_field, store_split_bit_field):
Likewise.
* expr.c (store_constructor, store_constructor_field): Likewise.
(store_field, emit_group_load, emit_group_store): Likewise.
* expr.h (emit_group_load, emit_group_store): Delete ALIGN parm.
(store_bit_field, extract_bit_field): Likewise.
* calls.c, expr.c, function.c: Change calls to above functions.
* ifcvt.c, stmt.c: Likewise.
* alias.c (nonoverlapping_memrefs_p): Not overlapping if one base is * alias.c (nonoverlapping_memrefs_p): Not overlapping if one base is
constant and one is on frame. constant and one is on frame.
If know memref offset, adjust size from decl. If know memref offset, adjust size from decl.
......
...@@ -1037,7 +1037,6 @@ store_unaligned_arguments_into_pseudos (args, num_actuals) ...@@ -1037,7 +1037,6 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
rtx reg = gen_reg_rtx (word_mode); rtx reg = gen_reg_rtx (word_mode);
rtx word = operand_subword_force (args[i].value, j, BLKmode); rtx word = operand_subword_force (args[i].value, j, BLKmode);
int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD); int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
int bitalign = TYPE_ALIGN (TREE_TYPE (args[i].tree_value));
args[i].aligned_regs[j] = reg; args[i].aligned_regs[j] = reg;
...@@ -1057,9 +1056,9 @@ store_unaligned_arguments_into_pseudos (args, num_actuals) ...@@ -1057,9 +1056,9 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
bytes -= bitsize / BITS_PER_UNIT; bytes -= bitsize / BITS_PER_UNIT;
store_bit_field (reg, bitsize, big_endian_correction, word_mode, store_bit_field (reg, bitsize, big_endian_correction, word_mode,
extract_bit_field (word, bitsize, 0, 1, NULL_RTX, extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
word_mode, word_mode, bitalign, word_mode, word_mode,
BITS_PER_WORD), BITS_PER_WORD),
bitalign, BITS_PER_WORD); BITS_PER_WORD);
} }
} }
} }
...@@ -1736,8 +1735,7 @@ load_register_parameters (args, num_actuals, call_fusage, flags) ...@@ -1736,8 +1735,7 @@ load_register_parameters (args, num_actuals, call_fusage, flags)
if (GET_CODE (reg) == PARALLEL) if (GET_CODE (reg) == PARALLEL)
emit_group_load (reg, args[i].value, emit_group_load (reg, args[i].value,
int_size_in_bytes (TREE_TYPE (args[i].tree_value)), int_size_in_bytes (TREE_TYPE (args[i].tree_value)));
TYPE_ALIGN (TREE_TYPE (args[i].tree_value)));
/* If simple case, just do move. If normal partial, store_one_arg /* If simple case, just do move. If normal partial, store_one_arg
has already loaded the register for us. In all other cases, has already loaded the register for us. In all other cases,
...@@ -3225,8 +3223,7 @@ expand_call (exp, target, ignore) ...@@ -3225,8 +3223,7 @@ expand_call (exp, target, ignore)
if (! rtx_equal_p (target, valreg)) if (! rtx_equal_p (target, valreg))
emit_group_store (target, valreg, emit_group_store (target, valreg,
int_size_in_bytes (TREE_TYPE (exp)), int_size_in_bytes (TREE_TYPE (exp)));
TYPE_ALIGN (TREE_TYPE (exp)));
/* We can not support sibling calls for this case. */ /* We can not support sibling calls for this case. */
sibcall_failure = 1; sibcall_failure = 1;
...@@ -4004,9 +4001,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -4004,9 +4001,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
/* Handle calls that pass values in multiple non-contiguous /* Handle calls that pass values in multiple non-contiguous
locations. The PA64 has examples of this for library calls. */ locations. The PA64 has examples of this for library calls. */
if (reg != 0 && GET_CODE (reg) == PARALLEL) if (reg != 0 && GET_CODE (reg) == PARALLEL)
emit_group_load (reg, val, emit_group_load (reg, val, GET_MODE_SIZE (GET_MODE (val)));
GET_MODE_SIZE (GET_MODE (val)),
GET_MODE_ALIGNMENT (GET_MODE (val)));
else if (reg != 0 && partial == 0) else if (reg != 0 && partial == 0)
emit_move_insn (reg, val); emit_move_insn (reg, val);
......
...@@ -36,23 +36,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -36,23 +36,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static void store_fixed_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT, static void store_fixed_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, rtx, unsigned HOST_WIDE_INT, rtx));
unsigned int));
static void store_split_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT, static void store_split_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, rtx, unsigned HOST_WIDE_INT, rtx));
unsigned int));
static rtx extract_fixed_bit_field PARAMS ((enum machine_mode, rtx, static rtx extract_fixed_bit_field PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
rtx, int, unsigned int)); rtx, int));
static rtx mask_rtx PARAMS ((enum machine_mode, int, static rtx mask_rtx PARAMS ((enum machine_mode, int,
int, int)); int, int));
static rtx lshift_value PARAMS ((enum machine_mode, rtx, static rtx lshift_value PARAMS ((enum machine_mode, rtx,
int, int)); int, int));
static rtx extract_split_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT, static rtx extract_split_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, int, unsigned HOST_WIDE_INT, int));
unsigned int));
static void do_cmp_and_jump PARAMS ((rtx, rtx, enum rtx_code, static void do_cmp_and_jump PARAMS ((rtx, rtx, enum rtx_code,
enum machine_mode, rtx)); enum machine_mode, rtx));
...@@ -289,13 +286,12 @@ mode_for_extraction (pattern, opno) ...@@ -289,13 +286,12 @@ mode_for_extraction (pattern, opno)
else, we use the mode of operand 3. */ else, we use the mode of operand 3. */
rtx rtx
store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
rtx str_rtx; rtx str_rtx;
unsigned HOST_WIDE_INT bitsize; unsigned HOST_WIDE_INT bitsize;
unsigned HOST_WIDE_INT bitnum; unsigned HOST_WIDE_INT bitnum;
enum machine_mode fieldmode; enum machine_mode fieldmode;
rtx value; rtx value;
unsigned int align;
HOST_WIDE_INT total_size; HOST_WIDE_INT total_size;
{ {
unsigned int unit unsigned int unit
...@@ -306,11 +302,6 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -306,11 +302,6 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
enum machine_mode op_mode = mode_for_extraction (EP_insv, 3); enum machine_mode op_mode = mode_for_extraction (EP_insv, 3);
/* It is wrong to have align==0, since every object is aligned at
least at a bit boundary. This usually means a bug elsewhere. */
if (align == 0)
abort ();
/* Discount the part of the structure before the desired byte. /* Discount the part of the structure before the desired byte.
We need to know how many bytes are safe to reference after it. */ We need to know how many bytes are safe to reference after it. */
if (total_size >= 0) if (total_size >= 0)
...@@ -347,9 +338,9 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -347,9 +338,9 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
&& (GET_CODE (op0) != MEM && (GET_CODE (op0) != MEM
? (GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD ? (GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
|| GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode)) || GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode))
: (! SLOW_UNALIGNED_ACCESS (fieldmode, align) : (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
|| (offset * BITS_PER_UNIT % bitsize == 0 || (offset * BITS_PER_UNIT % bitsize == 0
&& align % GET_MODE_BITSIZE (fieldmode) == 0)))) && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
{ {
if (GET_MODE (op0) != fieldmode) if (GET_MODE (op0) != fieldmode)
{ {
...@@ -472,10 +463,10 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -472,10 +463,10 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
if I is 1, use the next to lowest word; and so on. */ if I is 1, use the next to lowest word; and so on. */
unsigned int wordnum = (backwards ? nwords - i - 1 : i); unsigned int wordnum = (backwards ? nwords - i - 1 : i);
unsigned int bit_offset = (backwards unsigned int bit_offset = (backwards
? MAX ((int) bitsize - ((int) i + 1) ? MAX ((int) bitsize - ((int) i + 1)
* BITS_PER_WORD, * BITS_PER_WORD,
0) 0)
: (int) i * BITS_PER_WORD); : (int) i * BITS_PER_WORD);
store_bit_field (op0, MIN (BITS_PER_WORD, store_bit_field (op0, MIN (BITS_PER_WORD,
bitsize - i * BITS_PER_WORD), bitsize - i * BITS_PER_WORD),
...@@ -484,7 +475,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -484,7 +475,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
(GET_MODE (value) == VOIDmode (GET_MODE (value) == VOIDmode
? fieldmode ? fieldmode
: GET_MODE (value))), : GET_MODE (value))),
align, total_size); total_size);
} }
return value; return value;
} }
...@@ -519,9 +510,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -519,9 +510,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
offset = 0; offset = 0;
} }
else else
{ op0 = protect_from_queue (op0, 1);
op0 = protect_from_queue (op0, 1);
}
/* If VALUE is a floating-point mode, access it as an integer of the /* If VALUE is a floating-point mode, access it as an integer of the
corresponding size. This can occur on a machine with 64 bit registers corresponding size. This can occur on a machine with 64 bit registers
...@@ -574,19 +563,19 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -574,19 +563,19 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
if (GET_MODE (op0) == BLKmode if (GET_MODE (op0) == BLKmode
|| GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (maxmode)) || GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (maxmode))
bestmode bestmode
= get_best_mode (bitsize, bitnum, align, maxmode, = get_best_mode (bitsize, bitnum, MEM_ALIGN (op0), maxmode,
MEM_VOLATILE_P (op0)); MEM_VOLATILE_P (op0));
else else
bestmode = GET_MODE (op0); bestmode = GET_MODE (op0);
if (bestmode == VOIDmode if (bestmode == VOIDmode
|| (SLOW_UNALIGNED_ACCESS (bestmode, align) || (SLOW_UNALIGNED_ACCESS (bestmode, MEM_ALIGN (op0))
&& GET_MODE_BITSIZE (bestmode) > align)) && GET_MODE_BITSIZE (bestmode) > MEM_ALIGN (op0)))
goto insv_loses; goto insv_loses;
/* Adjust address to point to the containing unit of that mode. */ /* Adjust address to point to the containing unit of that mode.
Compute offset as multiple of this unit, counting in bytes. */
unit = GET_MODE_BITSIZE (bestmode); unit = GET_MODE_BITSIZE (bestmode);
/* Compute offset as multiple of this unit, counting in bytes. */
offset = (bitnum / unit) * GET_MODE_SIZE (bestmode); offset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
bitpos = bitnum % unit; bitpos = bitnum % unit;
op0 = adjust_address (op0, bestmode, offset); op0 = adjust_address (op0, bestmode, offset);
...@@ -595,7 +584,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -595,7 +584,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
the unit. */ the unit. */
tempreg = copy_to_reg (op0); tempreg = copy_to_reg (op0);
store_bit_field (tempreg, bitsize, bitpos, fieldmode, value, store_bit_field (tempreg, bitsize, bitpos, fieldmode, value,
align, total_size); total_size);
emit_move_insn (op0, tempreg); emit_move_insn (op0, tempreg);
return value; return value;
} }
...@@ -638,7 +627,8 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -638,7 +627,8 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
if we must narrow it, be sure we do it correctly. */ if we must narrow it, be sure we do it correctly. */
if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode)) if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode))
value1 = simplify_gen_subreg (maxmode, value1, GET_MODE (value1), 0); value1 = simplify_gen_subreg (maxmode, value1,
GET_MODE (value1), 0);
else else
value1 = gen_lowpart (maxmode, value1); value1 = gen_lowpart (maxmode, value1);
} }
...@@ -664,13 +654,13 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -664,13 +654,13 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
else else
{ {
delete_insns_since (last); delete_insns_since (last);
store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align); store_fixed_bit_field (op0, offset, bitsize, bitpos, value);
} }
} }
else else
insv_loses: insv_loses:
/* Insv is not available; store using shifts and boolean ops. */ /* Insv is not available; store using shifts and boolean ops. */
store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align); store_fixed_bit_field (op0, offset, bitsize, bitpos, value);
return value; return value;
} }
...@@ -682,16 +672,14 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -682,16 +672,14 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
(If OP0 is a register, it may be a full word or a narrower mode, (If OP0 is a register, it may be a full word or a narrower mode,
but BITPOS still counts within a full word, but BITPOS still counts within a full word,
which is significant on bigendian machines.) which is significant on bigendian machines.)
STRUCT_ALIGN is the alignment the structure is known to have.
Note that protect_from_queue has already been done on OP0 and VALUE. */ Note that protect_from_queue has already been done on OP0 and VALUE. */
static void static void
store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align) store_fixed_bit_field (op0, offset, bitsize, bitpos, value)
rtx op0; rtx op0;
unsigned HOST_WIDE_INT offset, bitsize, bitpos; unsigned HOST_WIDE_INT offset, bitsize, bitpos;
rtx value; rtx value;
unsigned int struct_align;
{ {
enum machine_mode mode; enum machine_mode mode;
unsigned int total_bits = BITS_PER_WORD; unsigned int total_bits = BITS_PER_WORD;
...@@ -699,9 +687,6 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align) ...@@ -699,9 +687,6 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
int all_zero = 0; int all_zero = 0;
int all_one = 0; int all_one = 0;
if (! SLOW_UNALIGNED_ACCESS (word_mode, struct_align))
struct_align = BIGGEST_ALIGNMENT;
/* There is a case not handled here: /* There is a case not handled here:
a structure with a known alignment of just a halfword a structure with a known alignment of just a halfword
and a field split across two aligned halfwords within the structure. and a field split across two aligned halfwords within the structure.
...@@ -716,8 +701,7 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align) ...@@ -716,8 +701,7 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
/* Special treatment for a bit field split across two registers. */ /* Special treatment for a bit field split across two registers. */
if (bitsize + bitpos > BITS_PER_WORD) if (bitsize + bitpos > BITS_PER_WORD)
{ {
store_split_bit_field (op0, bitsize, bitpos, store_split_bit_field (op0, bitsize, bitpos, value);
value, BITS_PER_WORD);
return; return;
} }
} }
...@@ -733,16 +717,14 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align) ...@@ -733,16 +717,14 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
|| GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode)) || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode))
mode = word_mode; mode = word_mode;
mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
struct_align, mode, MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0));
GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
if (mode == VOIDmode) if (mode == VOIDmode)
{ {
/* The only way this should occur is if the field spans word /* The only way this should occur is if the field spans word
boundaries. */ boundaries. */
store_split_bit_field (op0, store_split_bit_field (op0, bitsize, bitpos + offset * BITS_PER_UNIT,
bitsize, bitpos + offset * BITS_PER_UNIT, value);
value, struct_align);
return; return;
} }
...@@ -856,17 +838,14 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align) ...@@ -856,17 +838,14 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
BITSIZE is the field width; BITPOS the position of its first bit BITSIZE is the field width; BITPOS the position of its first bit
(within the word). (within the word).
VALUE is the value to store. VALUE is the value to store.
ALIGN is the known alignment of OP0.
This is also the size of the memory objects to be used.
This does not yet handle fields wider than BITS_PER_WORD. */ This does not yet handle fields wider than BITS_PER_WORD. */
static void static void
store_split_bit_field (op0, bitsize, bitpos, value, align) store_split_bit_field (op0, bitsize, bitpos, value)
rtx op0; rtx op0;
unsigned HOST_WIDE_INT bitsize, bitpos; unsigned HOST_WIDE_INT bitsize, bitpos;
rtx value; rtx value;
unsigned int align;
{ {
unsigned int unit; unsigned int unit;
unsigned int bitsdone = 0; unsigned int bitsdone = 0;
...@@ -876,7 +855,7 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -876,7 +855,7 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
unit = BITS_PER_WORD; unit = BITS_PER_WORD;
else else
unit = MIN (align, BITS_PER_WORD); unit = MIN (MEM_ALIGN (op0), BITS_PER_WORD);
/* If VALUE is a constant other than a CONST_INT, get it into a register in /* If VALUE is a constant other than a CONST_INT, get it into a register in
WORD_MODE. If we can do this using gen_lowpart_common, do so. Note WORD_MODE. If we can do this using gen_lowpart_common, do so. Note
...@@ -932,18 +911,10 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -932,18 +911,10 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
else else
/* The args are chosen so that the last part includes the /* The args are chosen so that the last part includes the
lsb. Give extract_bit_field the value it needs (with lsb. Give extract_bit_field the value it needs (with
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,
??? We have no idea what the alignment of VALUE is, so total_bits - bitsize + bitsdone,
we have to use a guess. */ NULL_RTX, 1);
part
= extract_fixed_bit_field
(word_mode, value, 0, thissize,
total_bits - bitsize + bitsdone, NULL_RTX, 1,
GET_MODE (value) == VOIDmode
? UNITS_PER_WORD
: (GET_MODE (value) == BLKmode
? 1 : GET_MODE_ALIGNMENT (GET_MODE (value))));
} }
else else
{ {
...@@ -953,13 +924,8 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -953,13 +924,8 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
>> bitsdone) >> bitsdone)
& (((HOST_WIDE_INT) 1 << thissize) - 1)); & (((HOST_WIDE_INT) 1 << thissize) - 1));
else else
part part = extract_fixed_bit_field (word_mode, value, 0, thissize,
= extract_fixed_bit_field bitsdone, NULL_RTX, 1);
(word_mode, value, 0, thissize, bitsdone, NULL_RTX, 1,
GET_MODE (value) == VOIDmode
? UNITS_PER_WORD
: (GET_MODE (value) == BLKmode
? 1 : GET_MODE_ALIGNMENT (GET_MODE (value))));
} }
/* If OP0 is a register, then handle OFFSET here. /* If OP0 is a register, then handle OFFSET here.
...@@ -985,8 +951,8 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -985,8 +951,8 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
/* OFFSET is in UNITs, and UNIT is in bits. /* OFFSET is in UNITs, and UNIT is in bits.
store_fixed_bit_field wants offset in bytes. */ store_fixed_bit_field wants offset in bytes. */
store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT, store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT, thissize,
thissize, thispos, part, align); thispos, part);
bitsdone += thissize; bitsdone += thissize;
} }
} }
...@@ -1003,7 +969,6 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -1003,7 +969,6 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
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.
ALIGN is the alignment that STR_RTX is known to have.
TOTAL_SIZE is the size in bytes of the containing structure, TOTAL_SIZE is the size in bytes of the containing structure,
or -1 if varying. or -1 if varying.
...@@ -1014,14 +979,13 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -1014,14 +979,13 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
rtx rtx
extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
target, mode, tmode, align, total_size) target, mode, tmode, total_size)
rtx str_rtx; rtx str_rtx;
unsigned HOST_WIDE_INT bitsize; unsigned HOST_WIDE_INT bitsize;
unsigned HOST_WIDE_INT bitnum; unsigned HOST_WIDE_INT bitnum;
int unsignedp; int unsignedp;
rtx target; rtx target;
enum machine_mode mode, tmode; enum machine_mode mode, tmode;
unsigned int align;
HOST_WIDE_INT total_size; HOST_WIDE_INT total_size;
{ {
unsigned int unit unsigned int unit
...@@ -1111,9 +1075,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1111,9 +1075,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode), && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (GET_MODE (op0)))) GET_MODE_BITSIZE (GET_MODE (op0))))
|| (GET_CODE (op0) == MEM || (GET_CODE (op0) == MEM
&& (! SLOW_UNALIGNED_ACCESS (mode, align) && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (op0))
|| (offset * BITS_PER_UNIT % bitsize == 0 || (offset * BITS_PER_UNIT % bitsize == 0
&& align % bitsize == 0)))) && MEM_ALIGN (op0) % bitsize == 0))))
&& ((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode) && ((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
&& bitpos % BITS_PER_WORD == 0) && bitpos % BITS_PER_WORD == 0)
|| (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != BLKmode || (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != BLKmode
...@@ -1192,7 +1156,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1192,7 +1156,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
= 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, target_part, mode,
word_mode, align, total_size); word_mode, total_size);
if (target_part == 0) if (target_part == 0)
abort (); abort ();
...@@ -1211,11 +1175,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1211,11 +1175,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
total_words = GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD; total_words = GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD;
for (i = nwords; i < total_words; i++) for (i = nwords; i < total_words; i++)
{ emit_move_insn
int wordnum = WORDS_BIG_ENDIAN ? total_words - i - 1 : i; (operand_subword (target,
rtx target_part = operand_subword (target, wordnum, 1, VOIDmode); WORDS_BIG_ENDIAN ? total_words - i - 1 : i,
emit_move_insn (target_part, const0_rtx); 1, VOIDmode),
} const0_rtx);
} }
return target; return target;
} }
...@@ -1259,9 +1223,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1259,9 +1223,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
offset = 0; offset = 0;
} }
else else
{ op0 = protect_from_queue (str_rtx, 1);
op0 = protect_from_queue (str_rtx, 1);
}
/* Now OFFSET is nonzero only for memory operands. */ /* Now OFFSET is nonzero only for memory operands. */
...@@ -1303,14 +1265,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1303,14 +1265,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
if (GET_MODE (xop0) == BLKmode if (GET_MODE (xop0) == BLKmode
|| (GET_MODE_SIZE (GET_MODE (op0)) || (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (maxmode))) > GET_MODE_SIZE (maxmode)))
bestmode = get_best_mode (bitsize, bitnum, align, maxmode, bestmode = get_best_mode (bitsize, bitnum,
MEM_ALIGN (xop0), maxmode,
MEM_VOLATILE_P (xop0)); MEM_VOLATILE_P (xop0));
else else
bestmode = GET_MODE (xop0); bestmode = GET_MODE (xop0);
if (bestmode == VOIDmode if (bestmode == VOIDmode
|| (SLOW_UNALIGNED_ACCESS (bestmode, align) || (SLOW_UNALIGNED_ACCESS (bestmode, MEM_ALIGN (xop0))
&& GET_MODE_BITSIZE (bestmode) > align)) && GET_MODE_BITSIZE (bestmode) > MEM_ALIGN (xop0)))
goto extzv_loses; goto extzv_loses;
/* Compute offset as multiple of this unit, /* Compute offset as multiple of this unit,
...@@ -1390,13 +1353,13 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1390,13 +1353,13 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
{ {
delete_insns_since (last); delete_insns_since (last);
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
bitpos, target, 1, align); bitpos, target, 1);
} }
} }
else else
extzv_loses: extzv_loses:
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
bitpos, target, 1, align); bitpos, target, 1);
} }
else else
{ {
...@@ -1432,14 +1395,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1432,14 +1395,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
if (GET_MODE (xop0) == BLKmode if (GET_MODE (xop0) == BLKmode
|| (GET_MODE_SIZE (GET_MODE (op0)) || (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (maxmode))) > GET_MODE_SIZE (maxmode)))
bestmode = get_best_mode (bitsize, bitnum, align, maxmode, bestmode = get_best_mode (bitsize, bitnum,
MEM_ALIGN (xop0), maxmode,
MEM_VOLATILE_P (xop0)); MEM_VOLATILE_P (xop0));
else else
bestmode = GET_MODE (xop0); bestmode = GET_MODE (xop0);
if (bestmode == VOIDmode if (bestmode == VOIDmode
|| (SLOW_UNALIGNED_ACCESS (bestmode, align) || (SLOW_UNALIGNED_ACCESS (bestmode, MEM_ALIGN (xop0))
&& GET_MODE_BITSIZE (bestmode) > align)) && GET_MODE_BITSIZE (bestmode) > MEM_ALIGN (xop0)))
goto extv_loses; goto extv_loses;
/* Compute offset as multiple of this unit, /* Compute offset as multiple of this unit,
...@@ -1518,13 +1482,13 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1518,13 +1482,13 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
{ {
delete_insns_since (last); delete_insns_since (last);
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
bitpos, target, 0, align); bitpos, target, 0);
} }
} }
else else
extv_loses: extv_loses:
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
bitpos, target, 0, align); bitpos, target, 0);
} }
if (target == spec_target) if (target == spec_target)
return target; return target;
...@@ -1564,18 +1528,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1564,18 +1528,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
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).
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. */
ALIGN is the alignment that STR_RTX is known to have. */
static rtx static rtx
extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
target, unsignedp, align) target, unsignedp)
enum machine_mode tmode; enum machine_mode tmode;
rtx op0, target; rtx op0, target;
unsigned HOST_WIDE_INT offset, bitsize, bitpos; unsigned HOST_WIDE_INT offset, bitsize, bitpos;
int unsignedp; int unsignedp;
unsigned int align;
{ {
unsigned int total_bits = BITS_PER_WORD; unsigned int total_bits = BITS_PER_WORD;
enum machine_mode mode; enum machine_mode mode;
...@@ -1584,8 +1545,7 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, ...@@ -1584,8 +1545,7 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
{ {
/* Special treatment for a bit field split across two registers. */ /* Special treatment for a bit field split across two registers. */
if (bitsize + bitpos > BITS_PER_WORD) if (bitsize + bitpos > BITS_PER_WORD)
return extract_split_bit_field (op0, bitsize, bitpos, return extract_split_bit_field (op0, bitsize, bitpos, unsignedp);
unsignedp, align);
} }
else else
{ {
...@@ -1593,16 +1553,15 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, ...@@ -1593,16 +1553,15 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
includes the entire field. If such a mode would be larger than includes the entire field. If such a mode would be larger than
a word, we won't be doing the extraction the normal way. */ a word, we won't be doing the extraction the normal way. */
mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, align, mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
word_mode, MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0));
GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
if (mode == VOIDmode) if (mode == VOIDmode)
/* The only way this should occur is if the field spans word /* The only way this should occur is if the field spans word
boundaries. */ boundaries. */
return extract_split_bit_field (op0, bitsize, return extract_split_bit_field (op0, bitsize,
bitpos + offset * BITS_PER_UNIT, bitpos + offset * BITS_PER_UNIT,
unsignedp, align); unsignedp);
total_bits = GET_MODE_BITSIZE (mode); total_bits = GET_MODE_BITSIZE (mode);
...@@ -1628,12 +1587,9 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, ...@@ -1628,12 +1587,9 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
mode = GET_MODE (op0); mode = GET_MODE (op0);
if (BYTES_BIG_ENDIAN) if (BYTES_BIG_ENDIAN)
{ /* BITPOS is the distance between our msb and that of OP0.
/* BITPOS is the distance between our msb and that of OP0. Convert it to the distance from the lsb. */
Convert it to the distance from the lsb. */ bitpos = total_bits - bitsize - bitpos;
bitpos = total_bits - bitsize - bitpos;
}
/* Now BITPOS is always the distance between the field's lsb and that of OP0. /* Now BITPOS is always the distance between the field's lsb and that of OP0.
We have reduced the big-endian case to the little-endian case. */ We have reduced the big-endian case to the little-endian case. */
...@@ -1694,7 +1650,8 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, ...@@ -1694,7 +1650,8 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
if (GET_MODE_BITSIZE (mode) != (bitsize + bitpos)) if (GET_MODE_BITSIZE (mode) != (bitsize + bitpos))
{ {
tree amount = build_int_2 (GET_MODE_BITSIZE (mode) - (bitsize + bitpos), 0); tree amount
= build_int_2 (GET_MODE_BITSIZE (mode) - (bitsize + bitpos), 0);
/* Maybe propagate the target for the shift. */ /* Maybe propagate the target for the shift. */
/* But not if we will return the result--could confuse integrate.c. */ /* But not if we will return the result--could confuse integrate.c. */
rtx subtarget = (target != 0 && GET_CODE (target) == REG rtx subtarget = (target != 0 && GET_CODE (target) == REG
...@@ -1784,17 +1741,13 @@ lshift_value (mode, value, bitpos, bitsize) ...@@ -1784,17 +1741,13 @@ lshift_value (mode, value, bitpos, bitsize)
OP0 is the REG, SUBREG or MEM rtx for the first of the two words. OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
BITSIZE is the field width; BITPOS, position of its first bit, in the word. BITSIZE is the field width; BITPOS, position of its first bit, in the word.
UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend. UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend. */
ALIGN is the known alignment of OP0. This is also the size of the
memory objects to be used. */
static rtx static rtx
extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align) extract_split_bit_field (op0, bitsize, bitpos, unsignedp)
rtx op0; rtx op0;
unsigned HOST_WIDE_INT bitsize, bitpos; unsigned HOST_WIDE_INT bitsize, bitpos;
int unsignedp; int unsignedp;
unsigned int align;
{ {
unsigned int unit; unsigned int unit;
unsigned int bitsdone = 0; unsigned int bitsdone = 0;
...@@ -1806,7 +1759,7 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align) ...@@ -1806,7 +1759,7 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
unit = BITS_PER_WORD; unit = BITS_PER_WORD;
else else
unit = MIN (align, BITS_PER_WORD); unit = MIN (MEM_ALIGN (op0), BITS_PER_WORD);
while (bitsdone < bitsize) while (bitsdone < bitsize)
{ {
...@@ -1851,7 +1804,7 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align) ...@@ -1851,7 +1804,7 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
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, align); thissize, thispos, 0, 1);
bitsdone += thissize; bitsdone += thissize;
/* Shift this part into place for the result. */ /* Shift this part into place for the result. */
......
...@@ -153,14 +153,12 @@ static int is_zeros_p PARAMS ((tree)); ...@@ -153,14 +153,12 @@ static int is_zeros_p PARAMS ((tree));
static int mostly_zeros_p PARAMS ((tree)); static int mostly_zeros_p PARAMS ((tree));
static void store_constructor_field PARAMS ((rtx, unsigned HOST_WIDE_INT, static void store_constructor_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, enum machine_mode, HOST_WIDE_INT, enum machine_mode,
tree, tree, unsigned int, int, tree, tree, int, int));
int)); static void store_constructor PARAMS ((tree, rtx, int, HOST_WIDE_INT));
static void store_constructor PARAMS ((tree, rtx, unsigned int, int,
HOST_WIDE_INT));
static rtx store_field PARAMS ((rtx, HOST_WIDE_INT, static rtx store_field PARAMS ((rtx, HOST_WIDE_INT,
HOST_WIDE_INT, enum machine_mode, HOST_WIDE_INT, enum machine_mode,
tree, enum machine_mode, int, tree, enum machine_mode, int,
unsigned int, HOST_WIDE_INT, int)); HOST_WIDE_INT, int));
static enum memory_use_mode static enum memory_use_mode
get_memory_usage_from_modifier PARAMS ((enum expand_modifier)); get_memory_usage_from_modifier PARAMS ((enum expand_modifier));
static rtx var_rtx PARAMS ((tree)); static rtx var_rtx PARAMS ((tree));
...@@ -1946,8 +1944,7 @@ move_block_from_reg (regno, x, nregs, size) ...@@ -1946,8 +1944,7 @@ move_block_from_reg (regno, x, nregs, size)
/* Emit code to move a block SRC to a block DST, where DST is non-consecutive /* Emit code to move a block SRC to a block DST, where DST is non-consecutive
registers represented by a PARALLEL. SSIZE represents the total size of registers represented by a PARALLEL. SSIZE represents the total size of
block SRC in bytes, or -1 if not known. ALIGN is the known alignment of block SRC in bytes, or -1 if not known. */
SRC in bits. */
/* ??? If SSIZE % UNITS_PER_WORD != 0, we make the blatent assumption that /* ??? If SSIZE % UNITS_PER_WORD != 0, we make the blatent assumption that
the balance will be in what would be the low-order memory addresses, i.e. the balance will be in what would be the low-order memory addresses, i.e.
left justified for big endian, right justified for little endian. This left justified for big endian, right justified for little endian. This
...@@ -1956,9 +1953,8 @@ move_block_from_reg (regno, x, nregs, size) ...@@ -1956,9 +1953,8 @@ move_block_from_reg (regno, x, nregs, size)
would be needed. */ would be needed. */
void void
emit_group_load (dst, orig_src, ssize, align) emit_group_load (dst, orig_src, ssize)
rtx dst, orig_src; rtx dst, orig_src;
unsigned int align;
int ssize; int ssize;
{ {
rtx *tmps, src; rtx *tmps, src;
...@@ -2006,12 +2002,13 @@ emit_group_load (dst, orig_src, ssize, align) ...@@ -2006,12 +2002,13 @@ emit_group_load (dst, orig_src, ssize, align)
src = gen_reg_rtx (mode); src = gen_reg_rtx (mode);
else else
src = gen_reg_rtx (GET_MODE (orig_src)); src = gen_reg_rtx (GET_MODE (orig_src));
emit_move_insn (src, orig_src); emit_move_insn (src, orig_src);
} }
/* Optimize the access just a bit. */ /* Optimize the access just a bit. */
if (GET_CODE (src) == MEM if (GET_CODE (src) == MEM
&& align >= GET_MODE_ALIGNMENT (mode) && MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode)
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0 && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode)) && bytelen == GET_MODE_SIZE (mode))
{ {
...@@ -2028,11 +2025,10 @@ emit_group_load (dst, orig_src, ssize, align) ...@@ -2028,11 +2025,10 @@ emit_group_load (dst, orig_src, ssize, align)
tmps[i] = XEXP (src, 1); tmps[i] = XEXP (src, 1);
else if (bytepos == 0) else if (bytepos == 0)
{ {
rtx mem; rtx mem = assign_stack_temp (GET_MODE (src),
mem = assign_stack_temp (GET_MODE (src), GET_MODE_SIZE (GET_MODE (src)), 0);
GET_MODE_SIZE (GET_MODE (src)), 0);
emit_move_insn (mem, src); emit_move_insn (mem, src);
tmps[i] = change_address (mem, mode, XEXP (mem, 0)); tmps[i] = adjust_address (mem, mode, 0);
} }
else else
abort (); abort ();
...@@ -2043,7 +2039,7 @@ emit_group_load (dst, orig_src, ssize, align) ...@@ -2043,7 +2039,7 @@ emit_group_load (dst, orig_src, ssize, align)
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, NULL_RTX,
mode, mode, align, ssize); mode, mode, ssize);
if (BYTES_BIG_ENDIAN && shift) if (BYTES_BIG_ENDIAN && shift)
expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift), expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift),
...@@ -2059,13 +2055,12 @@ emit_group_load (dst, orig_src, ssize, align) ...@@ -2059,13 +2055,12 @@ emit_group_load (dst, orig_src, ssize, align)
/* Emit code to move a block SRC to a block DST, where SRC is non-consecutive /* Emit code to move a block SRC to a block DST, where SRC is non-consecutive
registers represented by a PARALLEL. SSIZE represents the total size of registers represented by a PARALLEL. SSIZE represents the total size of
block DST, or -1 if not known. ALIGN is the known alignment of DST. */ block DST, or -1 if not known. */
void void
emit_group_store (orig_dst, src, ssize, align) emit_group_store (orig_dst, src, ssize)
rtx orig_dst, src; rtx orig_dst, src;
int ssize; int ssize;
unsigned int align;
{ {
rtx *tmps, dst; rtx *tmps, dst;
int start, i; int start, i;
...@@ -2109,8 +2104,8 @@ emit_group_store (orig_dst, src, ssize, align) ...@@ -2109,8 +2104,8 @@ emit_group_store (orig_dst, src, ssize, align)
the temporary. */ the temporary. */
temp = assign_stack_temp (GET_MODE (dst), ssize, 0); temp = assign_stack_temp (GET_MODE (dst), ssize, 0);
emit_group_store (temp, src, ssize, align); emit_group_store (temp, src, ssize);
emit_group_load (dst, temp, ssize, align); emit_group_load (dst, temp, ssize);
return; return;
} }
else if (GET_CODE (dst) != MEM) else if (GET_CODE (dst) != MEM)
...@@ -2141,13 +2136,13 @@ emit_group_store (orig_dst, src, ssize, align) ...@@ -2141,13 +2136,13 @@ emit_group_store (orig_dst, src, ssize, align)
/* Optimize the access just a bit. */ /* Optimize the access just a bit. */
if (GET_CODE (dst) == MEM if (GET_CODE (dst) == MEM
&& align >= GET_MODE_ALIGNMENT (mode) && MEM_ALIGN (dst) >= GET_MODE_ALIGNMENT (mode)
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0 && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode)) && bytelen == GET_MODE_SIZE (mode))
emit_move_insn (adjust_address (dst, mode, bytepos), tmps[i]); emit_move_insn (adjust_address (dst, mode, bytepos), tmps[i]);
else else
store_bit_field (dst, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT, store_bit_field (dst, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
mode, tmps[i], align, ssize); mode, tmps[i], ssize);
} }
emit_queue (); emit_queue ();
...@@ -2228,8 +2223,8 @@ copy_blkmode_from_reg (tgtblk, srcreg, type) ...@@ -2228,8 +2223,8 @@ copy_blkmode_from_reg (tgtblk, srcreg, type)
extract_bit_field (src, bitsize, extract_bit_field (src, bitsize,
xbitpos % BITS_PER_WORD, 1, xbitpos % BITS_PER_WORD, 1,
NULL_RTX, word_mode, word_mode, NULL_RTX, word_mode, word_mode,
bitsize, BITS_PER_WORD), BITS_PER_WORD),
bitsize, BITS_PER_WORD); BITS_PER_WORD);
} }
return tgtblk; return tgtblk;
...@@ -3655,7 +3650,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, ...@@ -3655,7 +3650,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
/* Handle calls that pass values in multiple non-contiguous locations. /* Handle calls that pass values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */ The Irix 6 ABI has examples of this. */
if (GET_CODE (reg) == PARALLEL) if (GET_CODE (reg) == PARALLEL)
emit_group_load (reg, x, -1, align); /* ??? size? */ emit_group_load (reg, x, -1); /* ??? size? */
else else
move_block_to_reg (REGNO (reg), x, partial, mode); move_block_to_reg (REGNO (reg), x, partial, mode);
} }
...@@ -3872,9 +3867,7 @@ expand_assignment (to, from, want_value, suggest_reg) ...@@ -3872,9 +3867,7 @@ expand_assignment (to, from, want_value, suggest_reg)
? ((enum machine_mode) ? ((enum machine_mode)
TYPE_MODE (TREE_TYPE (to))) TYPE_MODE (TREE_TYPE (to)))
: VOIDmode), : VOIDmode),
unsignedp, unsignedp, int_size_in_bytes (TREE_TYPE (tem)),
alignment,
int_size_in_bytes (TREE_TYPE (tem)),
get_alias_set (to)); get_alias_set (to));
preserve_temp_slots (result); preserve_temp_slots (result);
...@@ -3916,8 +3909,7 @@ expand_assignment (to, from, want_value, suggest_reg) ...@@ -3916,8 +3909,7 @@ expand_assignment (to, from, want_value, suggest_reg)
/* Handle calls that return values in multiple non-contiguous locations. /* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */ The Irix 6 ABI has examples of this. */
if (GET_CODE (to_rtx) == PARALLEL) if (GET_CODE (to_rtx) == PARALLEL)
emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)), emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)));
TYPE_ALIGN (TREE_TYPE (from)));
else if (GET_MODE (to_rtx) == BLKmode) else if (GET_MODE (to_rtx) == BLKmode)
emit_block_move (to_rtx, value, expr_size (from)); emit_block_move (to_rtx, value, expr_size (from));
else else
...@@ -3951,8 +3943,7 @@ expand_assignment (to, from, want_value, suggest_reg) ...@@ -3951,8 +3943,7 @@ expand_assignment (to, from, want_value, suggest_reg)
temp = expand_expr (from, 0, GET_MODE (to_rtx), 0); temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
if (GET_CODE (to_rtx) == PARALLEL) if (GET_CODE (to_rtx) == PARALLEL)
emit_group_load (to_rtx, temp, int_size_in_bytes (TREE_TYPE (from)), emit_group_load (to_rtx, temp, int_size_in_bytes (TREE_TYPE (from)));
TYPE_ALIGN (TREE_TYPE (from)));
else else
emit_move_insn (to_rtx, temp); emit_move_insn (to_rtx, temp);
...@@ -4362,8 +4353,7 @@ store_expr (exp, target, want_value) ...@@ -4362,8 +4353,7 @@ store_expr (exp, target, want_value)
/* Handle calls that return values in multiple non-contiguous locations. /* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */ The Irix 6 ABI has examples of this. */
else if (GET_CODE (target) == PARALLEL) else if (GET_CODE (target) == PARALLEL)
emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)), emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)));
TYPE_ALIGN (TREE_TYPE (exp)));
else if (GET_MODE (temp) == BLKmode) else if (GET_MODE (temp) == BLKmode)
emit_block_move (target, temp, expr_size (exp)); emit_block_move (target, temp, expr_size (exp));
else else
...@@ -4464,7 +4454,7 @@ mostly_zeros_p (exp) ...@@ -4464,7 +4454,7 @@ mostly_zeros_p (exp)
/* Helper function for store_constructor. /* Helper function for store_constructor.
TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field. TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
TYPE is the type of the CONSTRUCTOR, not the element type. TYPE is the type of the CONSTRUCTOR, not the element type.
ALIGN and CLEARED are as for store_constructor. CLEARED is as for store_constructor.
ALIAS_SET is the alias set to use for any stores. ALIAS_SET is the alias set to use for any stores.
This provides a recursive shortcut back to store_constructor when it isn't This provides a recursive shortcut back to store_constructor when it isn't
...@@ -4473,14 +4463,13 @@ mostly_zeros_p (exp) ...@@ -4473,14 +4463,13 @@ mostly_zeros_p (exp)
clear a substructure if the outer structure has already been cleared. */ clear a substructure if the outer structure has already been cleared. */
static void static void
store_constructor_field (target, bitsize, bitpos, store_constructor_field (target, bitsize, bitpos, mode, exp, type, cleared,
mode, exp, type, align, cleared, alias_set) alias_set)
rtx target; rtx target;
unsigned HOST_WIDE_INT bitsize; unsigned HOST_WIDE_INT bitsize;
HOST_WIDE_INT bitpos; HOST_WIDE_INT bitpos;
enum machine_mode mode; enum machine_mode mode;
tree exp, type; tree exp, type;
unsigned int align;
int cleared; int cleared;
int alias_set; int alias_set;
{ {
...@@ -4500,11 +4489,7 @@ store_constructor_field (target, bitsize, bitpos, ...@@ -4500,11 +4489,7 @@ store_constructor_field (target, bitsize, bitpos,
? BLKmode : VOIDmode, bitpos / BITS_PER_UNIT); ? BLKmode : VOIDmode, bitpos / BITS_PER_UNIT);
/* Show the alignment may no longer be what it was and update the alias /* Update the alias set, if required. */
set, if required. */
if (bitpos != 0)
align = MIN (align, (unsigned int) bitpos & - bitpos);
if (GET_CODE (target) == MEM && ! MEM_KEEP_ALIAS_SET_P (target) if (GET_CODE (target) == MEM && ! MEM_KEEP_ALIAS_SET_P (target)
&& MEM_ALIAS_SET (target) != 0) && MEM_ALIAS_SET (target) != 0)
{ {
...@@ -4512,26 +4497,25 @@ store_constructor_field (target, bitsize, bitpos, ...@@ -4512,26 +4497,25 @@ store_constructor_field (target, bitsize, bitpos,
set_mem_alias_set (target, alias_set); set_mem_alias_set (target, alias_set);
} }
store_constructor (exp, target, align, cleared, bitsize / BITS_PER_UNIT); store_constructor (exp, target, cleared, bitsize / BITS_PER_UNIT);
} }
else else
store_field (target, bitsize, bitpos, mode, exp, VOIDmode, 0, align, store_field (target, bitsize, bitpos, mode, exp, VOIDmode, 0,
int_size_in_bytes (type), alias_set); int_size_in_bytes (type), alias_set);
} }
/* Store the value of constructor EXP into the rtx TARGET. /* Store the value of constructor EXP into the rtx TARGET.
TARGET is either a REG or a MEM. TARGET is either a REG or a MEM; we know it cannot conflict, since
ALIGN is the maximum known alignment for TARGET. safe_from_p has been called.
CLEARED is true if TARGET is known to have been zero'd. CLEARED is true if TARGET is known to have been zero'd.
SIZE is the number of bytes of TARGET we are allowed to modify: this SIZE is the number of bytes of TARGET we are allowed to modify: this
may not be the same as the size of EXP if we are assigning to a field may not be the same as the size of EXP if we are assigning to a field
which has been packed to exclude padding bits. */ which has been packed to exclude padding bits. */
static void static void
store_constructor (exp, target, align, cleared, size) store_constructor (exp, target, cleared, size)
tree exp; tree exp;
rtx target; rtx target;
unsigned int align;
int cleared; int cleared;
HOST_WIDE_INT size; HOST_WIDE_INT size;
{ {
...@@ -4540,47 +4524,30 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4540,47 +4524,30 @@ store_constructor (exp, target, align, cleared, size)
HOST_WIDE_INT exp_size = int_size_in_bytes (type); HOST_WIDE_INT exp_size = int_size_in_bytes (type);
#endif #endif
/* We know our target cannot conflict, since safe_from_p has been called. */
#if 0
/* Don't try copying piece by piece into a hard register
since that is vulnerable to being clobbered by EXP.
Instead, construct in a pseudo register and then copy it all. */
if (GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER)
{
rtx temp = gen_reg_rtx (GET_MODE (target));
store_constructor (exp, temp, align, cleared, size);
emit_move_insn (target, temp);
return;
}
#endif
if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE) || TREE_CODE (type) == QUAL_UNION_TYPE)
{ {
tree elt; tree elt;
/* Inform later passes that the whole union value is dead. */ /* We either clear the aggregate or indicate the value is dead. */
if ((TREE_CODE (type) == UNION_TYPE if ((TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE) || TREE_CODE (type) == QUAL_UNION_TYPE)
&& ! cleared) && ! cleared
&& ! CONSTRUCTOR_ELTS (exp))
/* If the constructor is empty, clear the union. */
{ {
emit_insn (gen_rtx_CLOBBER (VOIDmode, target)); clear_storage (target, expr_size (exp));
cleared = 1;
/* If the constructor is empty, clear the union. */
if (! CONSTRUCTOR_ELTS (exp) && ! cleared)
clear_storage (target, expr_size (exp));
} }
/* If we are building a static constructor into a register, /* If we are building a static constructor into a register,
set the initial value as zero so we can fold the value into set the initial value as zero so we can fold the value into
a constant. But if more than one register is involved, a constant. But if more than one register is involved,
this probably loses. */ this probably loses. */
else if (GET_CODE (target) == REG && TREE_STATIC (exp) else if (! cleared && GET_CODE (target) == REG && TREE_STATIC (exp)
&& GET_MODE_SIZE (GET_MODE (target)) <= UNITS_PER_WORD) && GET_MODE_SIZE (GET_MODE (target)) <= UNITS_PER_WORD)
{ {
if (! cleared) emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
cleared = 1; cleared = 1;
} }
...@@ -4589,20 +4556,19 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4589,20 +4556,19 @@ store_constructor (exp, target, align, cleared, size)
clear the whole structure first. Don't do this if TARGET is a clear the whole structure first. Don't do this if TARGET is a
register whose mode size isn't equal to SIZE since clear_storage register whose mode size isn't equal to SIZE since clear_storage
can't handle this case. */ can't handle this case. */
else if (size > 0 else if (! cleared && size > 0
&& ((list_length (CONSTRUCTOR_ELTS (exp)) && ((list_length (CONSTRUCTOR_ELTS (exp))
!= fields_length (type)) != fields_length (type))
|| mostly_zeros_p (exp)) || mostly_zeros_p (exp))
&& (GET_CODE (target) != REG && (GET_CODE (target) != REG
|| (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target)) == size)) || ((HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target))
== size)))
{ {
if (! cleared) clear_storage (target, GEN_INT (size));
clear_storage (target, GEN_INT (size));
cleared = 1; cleared = 1;
} }
else if (! cleared)
/* Inform later passes that the old value is dead. */ if (! cleared)
emit_insn (gen_rtx_CLOBBER (VOIDmode, target)); emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
/* Store each element of the constructor into /* Store each element of the constructor into
...@@ -4672,8 +4638,6 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4672,8 +4638,6 @@ store_constructor (exp, target, align, cleared, size)
to_rtx = offset_address (to_rtx, offset_rtx, to_rtx = offset_address (to_rtx, offset_rtx,
highest_pow2_factor (offset)); highest_pow2_factor (offset));
align = DECL_OFFSET_ALIGN (field);
} }
if (TREE_READONLY (field)) if (TREE_READONLY (field))
...@@ -4698,11 +4662,13 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4698,11 +4662,13 @@ store_constructor (exp, target, align, cleared, size)
&& bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT) && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
{ {
tree type = TREE_TYPE (value); tree type = TREE_TYPE (value);
if (TYPE_PRECISION (type) < BITS_PER_WORD) if (TYPE_PRECISION (type) < BITS_PER_WORD)
{ {
type = type_for_size (BITS_PER_WORD, TREE_UNSIGNED (type)); type = type_for_size (BITS_PER_WORD, TREE_UNSIGNED (type));
value = convert (type, value); value = convert (type, value);
} }
if (BYTES_BIG_ENDIAN) if (BYTES_BIG_ENDIAN)
value value
= fold (build (LSHIFT_EXPR, type, value, = fold (build (LSHIFT_EXPR, type, value,
...@@ -4720,7 +4686,7 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4720,7 +4686,7 @@ store_constructor (exp, target, align, cleared, size)
} }
store_constructor_field (to_rtx, bitsize, bitpos, mode, store_constructor_field (to_rtx, bitsize, bitpos, mode,
TREE_VALUE (elt), type, align, cleared, TREE_VALUE (elt), type, cleared,
get_alias_set (TREE_TYPE (field))); get_alias_set (TREE_TYPE (field)));
} }
} }
...@@ -4817,7 +4783,6 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4817,7 +4783,6 @@ store_constructor (exp, target, align, cleared, size)
HOST_WIDE_INT bitpos; HOST_WIDE_INT bitpos;
int unsignedp; int unsignedp;
tree value = TREE_VALUE (elt); tree value = TREE_VALUE (elt);
unsigned int align = TYPE_ALIGN (TREE_TYPE (value));
tree index = TREE_PURPOSE (elt); tree index = TREE_PURPOSE (elt);
rtx xtarget = target; rtx xtarget = target;
...@@ -4869,8 +4834,8 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4869,8 +4834,8 @@ store_constructor (exp, target, align, cleared, size)
} }
store_constructor_field store_constructor_field
(target, bitsize, bitpos, mode, value, type, align, (target, bitsize, bitpos, mode, value, type, cleared,
cleared, get_alias_set (elttype)); get_alias_set (elttype));
} }
} }
else else
...@@ -4912,7 +4877,7 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4912,7 +4877,7 @@ store_constructor (exp, target, align, cleared, size)
highest_pow2_factor (position)); highest_pow2_factor (position));
xtarget = adjust_address (xtarget, mode, 0); xtarget = adjust_address (xtarget, mode, 0);
if (TREE_CODE (value) == CONSTRUCTOR) if (TREE_CODE (value) == CONSTRUCTOR)
store_constructor (value, xtarget, align, cleared, store_constructor (value, xtarget, cleared,
bitsize / BITS_PER_UNIT); bitsize / BITS_PER_UNIT);
else else
store_expr (value, xtarget, 0); store_expr (value, xtarget, 0);
...@@ -4966,8 +4931,7 @@ store_constructor (exp, target, align, cleared, size) ...@@ -4966,8 +4931,7 @@ store_constructor (exp, target, align, cleared, size)
} }
store_constructor_field (target, bitsize, bitpos, mode, value, store_constructor_field (target, bitsize, bitpos, mode, value,
type, align, cleared, type, cleared, get_alias_set (elttype));
get_alias_set (elttype));
} }
} }
...@@ -5167,7 +5131,6 @@ store_constructor (exp, target, align, cleared, size) ...@@ -5167,7 +5131,6 @@ store_constructor (exp, target, align, cleared, size)
has mode VALUE_MODE if that is convenient to do. has mode VALUE_MODE if that is convenient to do.
In this case, UNSIGNEDP must be nonzero if the value is an unsigned type. In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
ALIGN is the alignment that TARGET is known to have.
TOTAL_SIZE is the size in bytes of the structure, or -1 if varying. TOTAL_SIZE is the size in bytes of the structure, or -1 if varying.
ALIAS_SET is the alias set for the destination. This value will ALIAS_SET is the alias set for the destination. This value will
...@@ -5175,8 +5138,8 @@ store_constructor (exp, target, align, cleared, size) ...@@ -5175,8 +5138,8 @@ store_constructor (exp, target, align, cleared, size)
reference to the containing structure. */ reference to the containing structure. */
static rtx static rtx
store_field (target, bitsize, bitpos, mode, exp, value_mode, store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp,
unsignedp, align, total_size, alias_set) total_size, alias_set)
rtx target; rtx target;
HOST_WIDE_INT bitsize; HOST_WIDE_INT bitsize;
HOST_WIDE_INT bitpos; HOST_WIDE_INT bitpos;
...@@ -5184,7 +5147,6 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, ...@@ -5184,7 +5147,6 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
tree exp; tree exp;
enum machine_mode value_mode; enum machine_mode value_mode;
int unsignedp; int unsignedp;
unsigned int align;
HOST_WIDE_INT total_size; HOST_WIDE_INT total_size;
int alias_set; int alias_set;
{ {
...@@ -5229,7 +5191,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, ...@@ -5229,7 +5191,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
emit_move_insn (object, target); emit_move_insn (object, target);
store_field (blk_object, bitsize, bitpos, mode, exp, VOIDmode, 0, store_field (blk_object, bitsize, bitpos, mode, exp, VOIDmode, 0,
align, total_size, alias_set); total_size, alias_set);
/* Even though we aren't returning target, we need to /* Even though we aren't returning target, we need to
give it the updated value. */ give it the updated value. */
...@@ -5259,11 +5221,11 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, ...@@ -5259,11 +5221,11 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
|| GET_CODE (target) == SUBREG || GET_CODE (target) == SUBREG
/* If the field isn't aligned enough to store as an ordinary memref, /* If the field isn't aligned enough to store as an ordinary memref,
store it as a bit field. */ store it as a bit field. */
|| (mode != BLKmode && SLOW_UNALIGNED_ACCESS (mode, align) || (mode != BLKmode && SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (target))
&& (align < GET_MODE_ALIGNMENT (mode) && (MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode)
|| bitpos % GET_MODE_ALIGNMENT (mode))) || bitpos % GET_MODE_ALIGNMENT (mode)))
|| (mode == BLKmode && SLOW_UNALIGNED_ACCESS (mode, align) || (mode == BLKmode && SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (target))
&& (TYPE_ALIGN (TREE_TYPE (exp)) > align && (TYPE_ALIGN (TREE_TYPE (exp)) > MEM_ALIGN (target)
|| bitpos % TYPE_ALIGN (TREE_TYPE (exp)) != 0)) || bitpos % TYPE_ALIGN (TREE_TYPE (exp)) != 0))
/* If the RHS and field are a constant size and the size of the /* If the RHS and field are a constant size and the size of the
RHS isn't the same size as the bitfield, we must use bitfield RHS isn't the same size as the bitfield, we must use bitfield
...@@ -5297,21 +5259,11 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, ...@@ -5297,21 +5259,11 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
boundary. If so, we simply do a block copy. */ boundary. If so, we simply do a block copy. */
if (GET_MODE (target) == BLKmode && GET_MODE (temp) == BLKmode) if (GET_MODE (target) == BLKmode && GET_MODE (temp) == BLKmode)
{ {
unsigned int exp_align = expr_align (exp);
if (GET_CODE (target) != MEM || GET_CODE (temp) != MEM if (GET_CODE (target) != MEM || GET_CODE (temp) != MEM
|| bitpos % BITS_PER_UNIT != 0) || bitpos % BITS_PER_UNIT != 0)
abort (); abort ();
target = adjust_address (target, VOIDmode, bitpos / BITS_PER_UNIT); target = adjust_address (target, VOIDmode, bitpos / BITS_PER_UNIT);
/* Make sure that ALIGN is no stricter than the alignment of EXP. */
align = MIN (exp_align, align);
/* Find an alignment that is consistent with the bit position. */
while ((bitpos % align) != 0)
align >>= 1;
emit_block_move (target, temp, emit_block_move (target, temp,
bitsize == -1 ? expr_size (exp) bitsize == -1 ? expr_size (exp)
: GEN_INT ((bitsize + BITS_PER_UNIT - 1) : GEN_INT ((bitsize + BITS_PER_UNIT - 1)
...@@ -5321,11 +5273,11 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, ...@@ -5321,11 +5273,11 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
} }
/* Store the value in the bitfield. */ /* Store the value in the bitfield. */
store_bit_field (target, bitsize, bitpos, mode, temp, align, total_size); store_bit_field (target, bitsize, bitpos, mode, temp, total_size);
if (value_mode != VOIDmode) if (value_mode != VOIDmode)
{ {
/* The caller wants an rtx for the value. */ /* The caller wants an rtx for the value.
/* If possible, avoid refetching from the bitfield itself. */ If possible, avoid refetching from the bitfield itself. */
if (width_mask != 0 if (width_mask != 0
&& ! (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))) && ! (GET_CODE (target) == MEM && MEM_VOLATILE_P (target)))
{ {
...@@ -5340,6 +5292,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, ...@@ -5340,6 +5292,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
GET_MODE (temp) == VOIDmode GET_MODE (temp) == VOIDmode
? value_mode ? value_mode
: GET_MODE (temp))), NULL_RTX); : GET_MODE (temp))), NULL_RTX);
tmode = GET_MODE (temp); tmode = GET_MODE (temp);
if (tmode == VOIDmode) if (tmode == VOIDmode)
tmode = value_mode; tmode = value_mode;
...@@ -5347,8 +5300,9 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, ...@@ -5347,8 +5300,9 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
temp = expand_shift (LSHIFT_EXPR, tmode, temp, count, 0, 0); temp = expand_shift (LSHIFT_EXPR, tmode, temp, count, 0, 0);
return expand_shift (RSHIFT_EXPR, tmode, temp, count, 0, 0); return expand_shift (RSHIFT_EXPR, tmode, temp, count, 0, 0);
} }
return extract_bit_field (target, bitsize, bitpos, unsignedp, return extract_bit_field (target, bitsize, bitpos, unsignedp,
NULL_RTX, value_mode, 0, align, NULL_RTX, value_mode, VOIDmode,
total_size); total_size);
} }
return const0_rtx; return const0_rtx;
...@@ -6823,7 +6777,7 @@ expand_expr (exp, target, tmode, modifier) ...@@ -6823,7 +6777,7 @@ expand_expr (exp, target, tmode, modifier)
* TYPE_QUAL_CONST))), * TYPE_QUAL_CONST))),
TREE_ADDRESSABLE (exp), 1, 1); TREE_ADDRESSABLE (exp), 1, 1);
store_constructor (exp, target, TYPE_ALIGN (TREE_TYPE (exp)), 0, store_constructor (exp, target, 0,
int_size_in_bytes (TREE_TYPE (exp))); int_size_in_bytes (TREE_TYPE (exp)));
return target; return target;
} }
...@@ -7256,11 +7210,10 @@ expand_expr (exp, target, tmode, modifier) ...@@ -7256,11 +7210,10 @@ expand_expr (exp, target, tmode, modifier)
op0 = validize_mem (op0); op0 = validize_mem (op0);
if (GET_CODE (op0) == MEM && GET_CODE (XEXP (op0, 0)) == REG) if (GET_CODE (op0) == MEM && GET_CODE (XEXP (op0, 0)) == REG)
mark_reg_pointer (XEXP (op0, 0), alignment); mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
op0 = extract_bit_field (op0, bitsize, bitpos, op0 = extract_bit_field (op0, bitsize, bitpos,
unsignedp, target, ext_mode, ext_mode, unsignedp, target, ext_mode, ext_mode,
alignment,
int_size_in_bytes (TREE_TYPE (tem))); int_size_in_bytes (TREE_TYPE (tem)));
/* If the result is a record type and BITSIZE is narrower than /* If the result is a record type and BITSIZE is narrower than
...@@ -7548,8 +7501,7 @@ expand_expr (exp, target, tmode, modifier) ...@@ -7548,8 +7501,7 @@ expand_expr (exp, target, tmode, modifier)
* BITS_PER_UNIT), * BITS_PER_UNIT),
(HOST_WIDE_INT) GET_MODE_BITSIZE (mode)), (HOST_WIDE_INT) GET_MODE_BITSIZE (mode)),
0, TYPE_MODE (valtype), TREE_OPERAND (exp, 0), 0, TYPE_MODE (valtype), TREE_OPERAND (exp, 0),
VOIDmode, 0, BITS_PER_UNIT, VOIDmode, 0, int_size_in_bytes (type), 0);
int_size_in_bytes (type), 0);
else else
abort (); abort ();
...@@ -8740,9 +8692,7 @@ expand_expr (exp, target, tmode, modifier) ...@@ -8740,9 +8692,7 @@ expand_expr (exp, target, tmode, modifier)
if (GET_CODE (op0) == PARALLEL) if (GET_CODE (op0) == PARALLEL)
/* Handle calls that pass values in multiple non-contiguous /* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */ locations. The Irix 6 ABI has examples of this. */
emit_group_store (memloc, op0, emit_group_store (memloc, op0, int_size_in_bytes (inner_type));
int_size_in_bytes (inner_type),
TYPE_ALIGN (inner_type));
else else
emit_move_insn (memloc, op0); emit_move_insn (memloc, op0);
op0 = memloc; op0 = memloc;
...@@ -9215,7 +9165,7 @@ expand_expr_unaligned (exp, palign) ...@@ -9215,7 +9165,7 @@ expand_expr_unaligned (exp, palign)
op0 = extract_bit_field (validize_mem (op0), bitsize, bitpos, op0 = extract_bit_field (validize_mem (op0), bitsize, bitpos,
unsignedp, NULL_RTX, ext_mode, unsignedp, NULL_RTX, ext_mode,
ext_mode, alignment, ext_mode,
int_size_in_bytes (TREE_TYPE (tem))); int_size_in_bytes (TREE_TYPE (tem)));
/* If the result is a record type and BITSIZE is narrower than /* If the result is a record type and BITSIZE is narrower than
......
...@@ -423,11 +423,11 @@ extern void move_block_from_reg PARAMS ((int, rtx, int, int)); ...@@ -423,11 +423,11 @@ extern void move_block_from_reg PARAMS ((int, rtx, int, int));
/* Load a BLKmode value into non-consecutive registers represented by a /* Load a BLKmode value into non-consecutive registers represented by a
PARALLEL. */ PARALLEL. */
extern void emit_group_load PARAMS ((rtx, rtx, int, unsigned int)); extern void emit_group_load PARAMS ((rtx, rtx, int));
/* Store a BLKmode value from non-consecutive registers represented by a /* Store a BLKmode value from non-consecutive registers represented by a
PARALLEL. */ PARALLEL. */
extern void emit_group_store PARAMS ((rtx, rtx, int, unsigned int)); extern void emit_group_store PARAMS ((rtx, rtx, int));
#ifdef TREE_CODE #ifdef TREE_CODE
/* Copy BLKmode object from a set of registers. */ /* Copy BLKmode object from a set of registers. */
...@@ -746,12 +746,11 @@ mode_for_extraction PARAMS ((enum extraction_pattern, int)); ...@@ -746,12 +746,11 @@ mode_for_extraction PARAMS ((enum extraction_pattern, int));
extern rtx store_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT, extern rtx store_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
enum machine_mode, rtx, enum machine_mode, rtx, HOST_WIDE_INT));
unsigned int, HOST_WIDE_INT));
extern rtx extract_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT, extern rtx extract_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, int, rtx, unsigned HOST_WIDE_INT, int, rtx,
enum machine_mode, enum machine_mode, enum machine_mode, enum machine_mode,
unsigned int, HOST_WIDE_INT)); HOST_WIDE_INT));
extern rtx expand_mult PARAMS ((enum machine_mode, rtx, rtx, rtx, int)); extern rtx expand_mult PARAMS ((enum machine_mode, rtx, rtx, rtx, int));
extern rtx expand_mult_add PARAMS ((rtx, rtx, rtx, rtx,enum machine_mode, int)); extern rtx expand_mult_add PARAMS ((rtx, rtx, rtx, rtx,enum machine_mode, int));
extern rtx expand_mult_highpart_adjust PARAMS ((enum machine_mode, rtx, rtx, rtx, rtx, int)); extern rtx expand_mult_highpart_adjust PARAMS ((enum machine_mode, rtx, rtx, rtx, rtx, int));
......
...@@ -3117,8 +3117,7 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -3117,8 +3117,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
start_sequence (); start_sequence ();
store_bit_field (sub, size_x, 0, GET_MODE (x), store_bit_field (sub, size_x, 0, GET_MODE (x),
val, GET_MODE_SIZE (GET_MODE (sub)), val, GET_MODE_SIZE (GET_MODE (sub)));
GET_MODE_ALIGNMENT (GET_MODE (sub)));
/* Make sure to unshare any shared rtl that store_bit_field /* Make sure to unshare any shared rtl that store_bit_field
might have created. */ might have created. */
...@@ -3139,7 +3138,6 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -3139,7 +3138,6 @@ purge_addressof_1 (loc, insn, force, store, ht)
start_sequence (); start_sequence ();
val = extract_bit_field (sub, size_x, 0, 1, NULL_RTX, val = extract_bit_field (sub, size_x, 0, 1, NULL_RTX,
GET_MODE (x), GET_MODE (x), GET_MODE (x), GET_MODE (x),
GET_MODE_SIZE (GET_MODE (sub)),
GET_MODE_SIZE (GET_MODE (sub))); GET_MODE_SIZE (GET_MODE (sub)));
if (! validate_change (insn, loc, val, 0)) if (! validate_change (insn, loc, val, 0))
...@@ -4493,8 +4491,7 @@ assign_parms (fndecl) ...@@ -4493,8 +4491,7 @@ assign_parms (fndecl)
locations. The Irix 6 ABI has examples of this. */ locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL) if (GET_CODE (entry_parm) == PARALLEL)
emit_group_store (validize_mem (stack_parm), entry_parm, emit_group_store (validize_mem (stack_parm), entry_parm,
int_size_in_bytes (TREE_TYPE (parm)), int_size_in_bytes (TREE_TYPE (parm)));
TYPE_ALIGN (TREE_TYPE (parm)));
else else
move_block_from_reg (REGNO (entry_parm), move_block_from_reg (REGNO (entry_parm),
...@@ -4635,8 +4632,7 @@ assign_parms (fndecl) ...@@ -4635,8 +4632,7 @@ assign_parms (fndecl)
locations. The Irix 6 ABI has examples of this. */ locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL) if (GET_CODE (entry_parm) == PARALLEL)
emit_group_store (validize_mem (stack_parm), entry_parm, emit_group_store (validize_mem (stack_parm), entry_parm,
int_size_in_bytes (TREE_TYPE (parm)), int_size_in_bytes (TREE_TYPE (parm)));
TYPE_ALIGN (TREE_TYPE (parm)));
else else
move_block_from_reg (REGNO (entry_parm), move_block_from_reg (REGNO (entry_parm),
validize_mem (stack_parm), validize_mem (stack_parm),
...@@ -6909,8 +6905,7 @@ expand_function_end (filename, line, end_bindings) ...@@ -6909,8 +6905,7 @@ expand_function_end (filename, line, end_bindings)
} }
else if (GET_CODE (real_decl_rtl) == PARALLEL) else if (GET_CODE (real_decl_rtl) == PARALLEL)
emit_group_load (real_decl_rtl, decl_rtl, emit_group_load (real_decl_rtl, decl_rtl,
int_size_in_bytes (TREE_TYPE (decl_result)), int_size_in_bytes (TREE_TYPE (decl_result)));
TYPE_ALIGN (TREE_TYPE (decl_result)));
else else
emit_move_insn (real_decl_rtl, decl_rtl); emit_move_insn (real_decl_rtl, decl_rtl);
......
...@@ -580,8 +580,7 @@ noce_emit_move_insn (x, y) ...@@ -580,8 +580,7 @@ noce_emit_move_insn (x, y)
outmode = GET_MODE (outer); outmode = GET_MODE (outer);
inmode = GET_MODE (inner); inmode = GET_MODE (inner);
bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT; bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
store_bit_field (inner, GET_MODE_BITSIZE (outmode), store_bit_field (inner, GET_MODE_BITSIZE (outmode), bitpos, outmode, y,
bitpos, outmode, y, GET_MODE_BITSIZE (inmode),
GET_MODE_BITSIZE (inmode)); GET_MODE_BITSIZE (inmode));
} }
......
...@@ -3071,8 +3071,7 @@ expand_value_return (val) ...@@ -3071,8 +3071,7 @@ expand_value_return (val)
val = convert_modes (mode, old_mode, val, unsignedp); val = convert_modes (mode, old_mode, val, unsignedp);
#endif #endif
if (GET_CODE (return_reg) == PARALLEL) if (GET_CODE (return_reg) == PARALLEL)
emit_group_load (return_reg, val, int_size_in_bytes (type), emit_group_load (return_reg, val, int_size_in_bytes (type));
TYPE_ALIGN (type));
else else
emit_move_insn (return_reg, val); emit_move_insn (return_reg, val);
} }
...@@ -3253,8 +3252,8 @@ expand_return (retval) ...@@ -3253,8 +3252,8 @@ expand_return (retval)
extract_bit_field (src, bitsize, extract_bit_field (src, bitsize,
bitpos % BITS_PER_WORD, 1, bitpos % BITS_PER_WORD, 1,
NULL_RTX, word_mode, word_mode, NULL_RTX, word_mode, word_mode,
bitsize, BITS_PER_WORD), BITS_PER_WORD),
bitsize, BITS_PER_WORD); BITS_PER_WORD);
} }
/* Find the smallest integer mode large enough to hold the /* Find the smallest integer mode large enough to hold the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment