aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-11-23 15:57:22 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-11-23 15:57:22 -0800
commit562fc7029bc18be016cdac0e29a8aaa3263bce10 (patch)
treee8f5801780a6bd9796154980722e5e14e25dbedf /gcc
parent870faaf6ab21fe1f4b2809693730f0dacbf6b19b (diff)
downloadgcc-562fc7029bc18be016cdac0e29a8aaa3263bce10.zip
gcc-562fc7029bc18be016cdac0e29a8aaa3263bce10.tar.gz
gcc-562fc7029bc18be016cdac0e29a8aaa3263bce10.tar.bz2
expmed.c (extract_bit_field): Use simplify_gen_subreg instead of hard-coding avoiding calls to gen_rtx_SUBREG.
* expmed.c (extract_bit_field): Use simplify_gen_subreg instead of hard-coding avoiding calls to gen_rtx_SUBREG. Split complex return modes to CONCAT. From-SVN: r91124
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/expmed.c56
2 files changed, 42 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cb666a9..8a31513 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-11-23 Richard Henderson <rth@redhat.com>
+
+ * expmed.c (extract_bit_field): Use simplify_gen_subreg instead of
+ hard-coding avoiding calls to gen_rtx_SUBREG. Split complex return
+ modes to CONCAT.
+
2004-11-23 Diego Novillo <dnovillo@redhat.com>
PR tree-optimization/18618
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 23ae551..eeab02f 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1233,22 +1233,16 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
{
if (mode1 != GET_MODE (op0))
{
- if (GET_CODE (op0) == SUBREG)
+ if (MEM_P (op0))
+ op0 = adjust_address (op0, mode1, offset);
+ else
{
- if (GET_MODE (SUBREG_REG (op0)) == mode1
- || GET_MODE_CLASS (mode1) == MODE_INT
- || GET_MODE_CLASS (mode1) == MODE_PARTIAL_INT)
- op0 = SUBREG_REG (op0);
- else
- /* Else we've got some float mode source being extracted into
- a different float mode destination -- this combination of
- subregs results in Severe Tire Damage. */
+ rtx sub = simplify_gen_subreg (mode1, op0, GET_MODE (op0),
+ byte_offset);
+ if (sub == NULL)
goto no_subreg_mode_swap;
+ op0 = sub;
}
- if (REG_P (op0))
- op0 = gen_rtx_SUBREG (mode1, op0, byte_offset);
- else
- op0 = adjust_address (op0, mode1, offset);
}
if (mode1 != mode)
return convert_to_mode (tmode, op0, unsignedp);
@@ -1628,19 +1622,41 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
return spec_target;
if (GET_MODE (target) != tmode && GET_MODE (target) != mode)
{
- /* If the target mode is floating-point, first convert to the
- integer mode of that size and then access it as a floating-point
- value via a SUBREG. */
- if (GET_MODE_CLASS (tmode) != MODE_INT
- && GET_MODE_CLASS (tmode) != MODE_PARTIAL_INT)
+ /* If the target mode is complex, then extract the two scalar elements
+ from the value now. Creating (subreg:SC (reg:DI) 0), as we would do
+ with the clause below, will cause gen_realpart or gen_imagpart to
+ fail, since those functions must return lvalues. */
+ if (COMPLEX_MODE_P (tmode))
{
+ rtx realpart, imagpart;
+ enum machine_mode itmode = GET_MODE_INNER (tmode);
+
target = convert_to_mode (mode_for_size (GET_MODE_BITSIZE (tmode),
MODE_INT, 0),
target, unsignedp);
+
+ realpart = extract_bit_field (target, GET_MODE_BITSIZE (itmode), 0,
+ unsignedp, NULL, itmode, itmode);
+ imagpart = extract_bit_field (target, GET_MODE_BITSIZE (itmode),
+ GET_MODE_BITSIZE (itmode), unsignedp,
+ NULL, itmode, itmode);
+
+ return gen_rtx_CONCAT (tmode, realpart, imagpart);
+ }
+
+ /* If the target mode is not a scalar integral, first convert to the
+ integer mode of that size and then access it as a floating-point
+ value via a SUBREG. */
+ if (!SCALAR_INT_MODE_P (tmode))
+ {
+ enum machine_mode smode
+ = mode_for_size (GET_MODE_BITSIZE (tmode), MODE_INT, 0);
+ target = convert_to_mode (smode, target, unsignedp);
+ target = force_reg (smode, target);
return gen_lowpart (tmode, target);
}
- else
- return convert_to_mode (tmode, target, unsignedp);
+
+ return convert_to_mode (tmode, target, unsignedp);
}
return target;
}