aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-12-09 20:28:14 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-12-09 20:28:14 +0000
commit4f1da2e923a3e7d00d92bb9bc865266246b5f2ca (patch)
tree17c387c65a3e8f4e3f41a72dac3abe9fb8d0a892 /gcc
parent36cea8702321ef08783a85f0512c1cc7c30f8bb0 (diff)
downloadgcc-4f1da2e923a3e7d00d92bb9bc865266246b5f2ca.zip
gcc-4f1da2e923a3e7d00d92bb9bc865266246b5f2ca.tar.gz
gcc-4f1da2e923a3e7d00d92bb9bc865266246b5f2ca.tar.bz2
simplify-rtx.c (simplify_subreg): In the CONCAT case...
* simplify-rtx.c (simplify_subreg): In the CONCAT case, check whether the request subreg is entirely contained in the requested component. (simplify_gen_subreg): Return null for CONCATs that are rejected by simplify_subreg. * expmed.c (store_bit_field): Create a temporary when changing the value to an integer mode. From-SVN: r91965
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/expmed.c18
-rw-r--r--gcc/simplify-rtx.c19
3 files changed, 31 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3c3f735..d63fe39 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2004-12-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * simplify-rtx.c (simplify_subreg): In the CONCAT case, check whether
+ the request subreg is entirely contained in the requested component.
+ (simplify_gen_subreg): Return null for CONCATs that are rejected
+ by simplify_subreg.
+ * expmed.c (store_bit_field): Create a temporary when changing the
+ value to an integer mode.
+
2004-12-09 David Edelsohn <edelsohn@gnu.org>
* real.c (ibm_extended): Correct comment.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 47fc2d2..10a95b3 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -591,16 +591,18 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
offset = 0;
}
- /* 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
- that uses SFmode for float. This can also occur for unaligned float
- structure fields. */
+ /* If VALUE has a floating-point or complex mode, access it as an
+ integer of the corresponding size. This can occur on a machine
+ with 64 bit registers that uses SFmode for float. It can also
+ occur for unaligned float or complex fields. */
orig_value = value;
- if (GET_MODE_CLASS (GET_MODE (value)) != MODE_INT
+ if (GET_MODE (value) != VOIDmode
+ && GET_MODE_CLASS (GET_MODE (value)) != MODE_INT
&& GET_MODE_CLASS (GET_MODE (value)) != MODE_PARTIAL_INT)
- value = gen_lowpart ((GET_MODE (value) == VOIDmode
- ? word_mode : int_mode_for_mode (GET_MODE (value))),
- value);
+ {
+ value = gen_reg_rtx (int_mode_for_mode (GET_MODE (value)));
+ emit_move_insn (gen_lowpart (GET_MODE (orig_value), value), orig_value);
+ }
/* Now OFFSET is nonzero only if OP0 is memory
and is therefore always measured in bytes. */
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 580782d..2ac5661 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -3722,17 +3722,20 @@ simplify_subreg (enum machine_mode outermode, rtx op,
of real and imaginary part. */
if (GET_CODE (op) == CONCAT)
{
- int is_realpart = byte < (unsigned int) GET_MODE_UNIT_SIZE (innermode);
- rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1);
- unsigned int final_offset;
- rtx res;
+ unsigned int inner_size, final_offset;
+ rtx part, res;
+
+ inner_size = GET_MODE_UNIT_SIZE (innermode);
+ part = byte < inner_size ? XEXP (op, 0) : XEXP (op, 1);
+ final_offset = byte % inner_size;
+ if (final_offset + GET_MODE_SIZE (outermode) > inner_size)
+ return NULL_RTX;
- final_offset = byte % (GET_MODE_UNIT_SIZE (innermode));
res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
if (res)
return res;
if (validate_subreg (outermode, GET_MODE (part), part, final_offset))
- return gen_rtx_SUBREG (outermode, part, final_offset);
+ return gen_rtx_SUBREG (outermode, part, final_offset);
return NULL_RTX;
}
@@ -3786,7 +3789,9 @@ simplify_gen_subreg (enum machine_mode outermode, rtx op,
if (newx)
return newx;
- if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode)
+ if (GET_CODE (op) == SUBREG
+ || GET_CODE (op) == CONCAT
+ || GET_MODE (op) == VOIDmode)
return NULL_RTX;
if (validate_subreg (outermode, innermode, op, byte))