Commit 1272914c by Richard Henderson Committed by Richard Henderson

re PR target/21101 (ICE: could not find a spill register on MMX intrinsics)

        PR target/21101
        * config/i386/i386.h (CANNOT_CHANGE_MODE_CLASS): Move guts to ...
        * config/i386/i386.c (ix86_cannot_change_mode_class): ... here.
        Deny modes smaller than 4 bytes.
        * config/i386/i386-protos.h: Update.

From-SVN: r98650
parent d076e5d2
2005-04-24 Richard Henderson <rth@redhat.com>
PR target/21101
* config/i386/i386.h (CANNOT_CHANGE_MODE_CLASS): Move guts to ...
* config/i386/i386.c (ix86_cannot_change_mode_class): ... here.
Deny modes smaller than 4 bytes.
* config/i386/i386-protos.h: Update.
2005-04-24 Ralf Corsepius <ralf.corsepius@rtems.org>
* config.gcc (h8300-*-rtems*): Add h8300-*-rtemscoff*.
......@@ -74,9 +82,9 @@
2005-04-23 Richard Henderson <rth@redhat.com>
PR rtl-opt/21102
* simplify-rtx.c (simplify_binary_operation): Fix mode check before
performing some integral scalar simplifications.
PR rtl-opt/21102
* simplify-rtx.c (simplify_binary_operation): Fix mode check before
performing some integral scalar simplifications.
2005-04-23 Richard Henderson <rth@redhat.com>
......
......@@ -187,6 +187,8 @@ extern int ix86_register_move_cost (enum machine_mode, enum reg_class,
enum reg_class);
extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class,
enum machine_mode, int);
extern bool ix86_cannot_change_mode_class (enum machine_mode,
enum machine_mode, enum reg_class);
extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
extern void emit_i387_cw_initialization (rtx, rtx, int);
......
......@@ -15297,6 +15297,41 @@ ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
return false;
}
/* Return true if the registers in CLASS cannot represent the change from
modes FROM to TO. */
bool
ix86_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
enum reg_class class)
{
if (from == to)
return false;
/* x87 registers can't do subreg at all, as all values are reformated
to extended precision. */
if (MAYBE_FLOAT_CLASS_P (class))
return true;
if (MAYBE_SSE_CLASS_P (class) || MAYBE_MMX_CLASS_P (class))
{
/* Vector registers do not support QI or HImode loads. If we don't
disallow a change to these modes, reload will assume it's ok to
drop the subreg from (subreg:SI (reg:HI 100) 0). This affects
the vec_dupv4hi pattern. */
if (GET_MODE_SIZE (from) < 4)
return true;
/* Vector registers do not support subreg with nonzero offsets, which
are otherwise valid for integer registers. Since we can't see
whether we have a nonzero offset from here, prohibit all
nonparadoxical subregs changing size. */
if (GET_MODE_SIZE (to) < GET_MODE_SIZE (from))
return true;
}
return false;
}
/* Return the cost of moving data from a register in class CLASS1 to
one in class CLASS2.
......
......@@ -1338,19 +1338,10 @@ enum reg_class
|| ((CLASS) == FP_TOP_REG) \
|| ((CLASS) == FP_SECOND_REG))
/* Return a class of registers that cannot change FROM mode to TO mode.
x87 registers can't do subreg as all values are reformated to extended
precision. XMM registers does not support with nonzero offsets equal
to 4, 8 and 12 otherwise valid for integer registers. Since we can't
determine these, prohibit all nonparadoxical subregs changing size. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
(GET_MODE_SIZE (TO) < GET_MODE_SIZE (FROM) \
? reg_classes_intersect_p (FLOAT_SSE_REGS, (CLASS)) \
|| MAYBE_MMX_CLASS_P (CLASS) \
: GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
? reg_classes_intersect_p (FLOAT_REGS, (CLASS)) : 0)
/* Return a class of registers that cannot change FROM mode to TO mode. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
ix86_cannot_change_mode_class (FROM, TO, CLASS)
/* Stack layout; function entry, exit and calling. */
......
/* { dg-do compile } */
/* { dg-options "-O2 -funroll-loops -march=nocona" } */
#include <mmintrin.h>
int W;
void f()
{
int j;
int B, C;
unsigned char* S;
__m64 *T = (__m64 *) &W;
for (j = 0; j < 16; j++, T++)
{
T[0] = T[1] = _mm_set1_pi8(*S);
S += W;
}
C = 3 * B;
__m64 E = _mm_set_pi16(3 * B, 3 * B, 3 * B, 5 * B);
__m64 G = _mm_set1_pi16(3 * B);
for (j = 0; j < 16; j++)
{
__m64 R = _mm_set1_pi16(B + j * C);
R = _m_paddw(R, E);
R = _m_paddw(R, G);
T[0] = _mm_srai_pi16(R, 3);
}
}
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