diff options
author | Steve Ellcey <sje@cup.hp.com> | 2001-12-11 23:04:36 +0000 |
---|---|---|
committer | Janis Johnson <janis@gcc.gnu.org> | 2001-12-11 23:04:36 +0000 |
commit | 0d7839daeef826108df3788cc82c198df2e56b2d (patch) | |
tree | 204c988a001cb54478276500f93ea95df61d9865 /gcc/expr.c | |
parent | 81deb0a3e6fc4528d84b11356a470c4054b171a1 (diff) | |
download | gcc-0d7839daeef826108df3788cc82c198df2e56b2d.tar.gz |
tm.texi (FUNCTION_ARG_REG_LITTLE_ENDIAN): New.
2001-12-11 Steve Ellcey <sje@cup.hp.com>
* doc/tm.texi (FUNCTION_ARG_REG_LITTLE_ENDIAN): New.
* defaults.h (FUNCTION_ARG_REG_LITTLE_ENDIAN): New.
* calls.c (store_unaligned_arguments_into_pseudos): Check
FUNCTION_ARG_REG_LITTLE_ENDIAN to see how structures
are passed/returned.
* expr.c (move_block_from_reg): Ditto.
(move_block_from_reg): Ditto.
(copy_blkmode_from_reg): Ditto.
* stmt.c (expand_return): Ditto.
* stor-layout.c (compute_record_mode): If
FUNCTION_ARG_REG_LITTLE_ENDIAN is set then check
MEMBER_TYPE_FORCES_BLK even if mode == VOIDmode.
* config/ia64/hpux.h (MEMBER_TYPE_FORCES_BLK): Set to true
so that Structures of one field are still treated as structures.
(FUNCTION_ARG_REG_LITTLE_ENDIAN): New, set it to true.
(FUNCTION_ARG_PADDING): Set to ia64_hpux_function_arg_padding().
(PAD_VARARGS_DOWN): Modify from default to not pad structures down.
* config/ia64/ia64-protos.h (ia64_hpux_function_arg_padding): New.
* config/ia64/ia64.c (ia64_hpux_function_arg_padding): New function
to special case handling of structure padding.
From-SVN: r47904
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index 051dc20a71b..53208057eb7 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1868,7 +1868,8 @@ move_block_from_reg (regno, x, nregs, size) /* If SIZE is that of a mode no bigger than a word, just use that mode's store operation. */ if (size <= UNITS_PER_WORD - && (mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0)) != BLKmode) + && (mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0)) != BLKmode + && !FUNCTION_ARG_REG_LITTLE_ENDIAN) { emit_move_insn (adjust_address (x, mode, 0), gen_rtx_REG (mode, regno)); return; @@ -1877,7 +1878,9 @@ move_block_from_reg (regno, x, nregs, size) /* Blocks smaller than a word on a BYTES_BIG_ENDIAN machine must be aligned to the left before storing to memory. Note that the previous test doesn't handle all cases (e.g. SIZE == 3). */ - if (size < UNITS_PER_WORD && BYTES_BIG_ENDIAN) + if (size < UNITS_PER_WORD + && BYTES_BIG_ENDIAN + && !FUNCTION_ARG_REG_LITTLE_ENDIAN) { rtx tem = operand_subword (x, 0, 1, BLKmode); rtx shift; @@ -2162,15 +2165,25 @@ copy_blkmode_from_reg (tgtblk, srcreg, type) /* This code assumes srcreg is at least a full word. If it isn't, copy it into a new pseudo which is a full word. */ + + /* If FUNCTION_ARG_REG_LITTLE_ENDIAN is set and convert_to_mode does + a copy, the wrong part of the register gets copied so we fake + a type conversion in place. */ + if (GET_MODE (srcreg) != BLKmode && GET_MODE_SIZE (GET_MODE (srcreg)) < UNITS_PER_WORD) - srcreg = convert_to_mode (word_mode, srcreg, TREE_UNSIGNED (type)); + if (FUNCTION_ARG_REG_LITTLE_ENDIAN) + srcreg = simplify_gen_subreg (word_mode, srcreg, GET_MODE (srcreg), 0); + else + srcreg = convert_to_mode (word_mode, srcreg, TREE_UNSIGNED (type)); /* Structures whose size is not a multiple of a word are aligned to the least significant byte (to the right). On a BYTES_BIG_ENDIAN machine, this means we must skip the empty high order bytes when calculating the bit offset. */ - if (BYTES_BIG_ENDIAN && bytes % UNITS_PER_WORD) + if (BYTES_BIG_ENDIAN + && !FUNCTION_ARG_REG_LITTLE_ENDIAN + && bytes % UNITS_PER_WORD) big_endian_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT)); |