aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>2002-09-04 18:09:32 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2002-09-04 18:09:32 +0000
commit015b1ad1dfa8fbd7323691515a5c1c38c4c1541d (patch)
treea78c678a10eb1a59228782c1360a8910ed4f8e9f /gcc/expr.c
parentb10f218708c0cc0f878ff4a474e46196bc30e3b5 (diff)
downloadgcc-015b1ad1dfa8fbd7323691515a5c1c38c4c1541d.zip
gcc-015b1ad1dfa8fbd7323691515a5c1c38c4c1541d.tar.gz
gcc-015b1ad1dfa8fbd7323691515a5c1c38c4c1541d.tar.bz2
expr.c (emit_group_load): Revise to allow splitting TCmode source into DImode pieces.
* expr.c (emit_group_load): Revise to allow splitting TCmode source into DImode pieces. * pa-64.h (LONG_DOUBLE_TYPE_SIZE): Define to 128. * pa64-regs.h (CLASS_CANNOT_CHANGE_MODE_P): Inhibit changes from SImode for floating-point register class. * pa.c (function_arg): Fix handling of modes wider than one word for TARGET_64BIT. From-SVN: r56805
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index ca8952b..5872ab0 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2265,21 +2265,26 @@ emit_group_load (dst, orig_src, ssize)
}
else if (GET_CODE (src) == CONCAT)
{
- if ((bytepos == 0
- && bytelen == GET_MODE_SIZE (GET_MODE (XEXP (src, 0))))
- || (bytepos == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
- && bytelen == GET_MODE_SIZE (GET_MODE (XEXP (src, 1)))))
+ unsigned int slen = GET_MODE_SIZE (GET_MODE (src));
+ unsigned int slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
+
+ if ((bytepos == 0 && bytelen == slen0)
+ || (bytepos != 0 && bytepos + bytelen <= slen))
{
- tmps[i] = XEXP (src, bytepos != 0);
+ /* The following assumes that the concatenated objects all
+ have the same size. In this case, a simple calculation
+ can be used to determine the object and the bit field
+ to be extracted. */
+ tmps[i] = XEXP (src, bytepos / slen0);
if (! CONSTANT_P (tmps[i])
&& (GET_CODE (tmps[i]) != REG || GET_MODE (tmps[i]) != mode))
tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
- 0, 1, NULL_RTX, mode, mode, ssize);
+ (bytepos % slen0) * BITS_PER_UNIT,
+ 1, NULL_RTX, mode, mode, ssize);
}
else if (bytepos == 0)
{
- rtx mem = assign_stack_temp (GET_MODE (src),
- GET_MODE_SIZE (GET_MODE (src)), 0);
+ rtx mem = assign_stack_temp (GET_MODE (src), slen, 0);
emit_move_insn (mem, src);
tmps[i] = adjust_address (mem, mode, 0);
}