simplify-rtx.c (simplify_unary_operation, [...]): Deal with vector modes
* simplify-rtx.c (simplify_unary_operation, simplify_binary_operation): Deal with vector modes (simplify_ternary_operation): Deal with no-op VEC_MERGE. From-SVN: r62610
This commit is contained in:
parent
2382b79f35
commit
852c8ba12e
|
@ -1,3 +1,9 @@
|
|||
Sun Feb 9 23:54:59 CET 2003 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* simplify-rtx.c (simplify_unary_operation,
|
||||
simplify_binary_operation): Deal with vector modes
|
||||
(simplify_ternary_operation): Deal with no-op VEC_MERGE.
|
||||
|
||||
2002-02-09 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
* toplev.c (rest_of_compilation): Recompute register usage after
|
||||
|
|
|
@ -410,6 +410,31 @@ simplify_unary_operation (code, mode, op, op_mode)
|
|||
}
|
||||
}
|
||||
|
||||
if (VECTOR_MODE_P (mode) && GET_CODE (trueop) == CONST_VECTOR)
|
||||
{
|
||||
int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
|
||||
unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
|
||||
enum machine_mode opmode = GET_MODE (trueop);
|
||||
int op_elt_size = GET_MODE_SIZE (GET_MODE_INNER (opmode));
|
||||
unsigned op_n_elts = (GET_MODE_SIZE (opmode) / op_elt_size);
|
||||
rtvec v = rtvec_alloc (n_elts);
|
||||
unsigned int i;
|
||||
|
||||
if (op_n_elts != n_elts)
|
||||
abort ();
|
||||
|
||||
for (i = 0; i < n_elts; i++)
|
||||
{
|
||||
rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
|
||||
CONST_VECTOR_ELT (trueop, i),
|
||||
GET_MODE_INNER (opmode));
|
||||
if (!x)
|
||||
return 0;
|
||||
RTVEC_ELT (v, i) = x;
|
||||
}
|
||||
return gen_rtx_CONST_VECTOR (mode, v);
|
||||
}
|
||||
|
||||
/* The order of these tests is critical so that, for example, we don't
|
||||
check the wrong mode (input vs. output) for a conversion operation,
|
||||
such as FIX. At some point, this should be simplified. */
|
||||
|
@ -875,6 +900,37 @@ simplify_binary_operation (code, mode, op0, op1)
|
|||
tem = trueop0, trueop0 = trueop1, trueop1 = tem;
|
||||
}
|
||||
|
||||
if (VECTOR_MODE_P (mode)
|
||||
&& GET_CODE (trueop0) == CONST_VECTOR
|
||||
&& GET_CODE (trueop1) == CONST_VECTOR)
|
||||
{
|
||||
int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
|
||||
unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
|
||||
enum machine_mode op0mode = GET_MODE (trueop0);
|
||||
int op0_elt_size = GET_MODE_SIZE (GET_MODE_INNER (op0mode));
|
||||
unsigned op0_n_elts = (GET_MODE_SIZE (op0mode) / op0_elt_size);
|
||||
enum machine_mode op1mode = GET_MODE (trueop1);
|
||||
int op1_elt_size = GET_MODE_SIZE (GET_MODE_INNER (op1mode));
|
||||
unsigned op1_n_elts = (GET_MODE_SIZE (op1mode) / op1_elt_size);
|
||||
rtvec v = rtvec_alloc (n_elts);
|
||||
unsigned int i;
|
||||
|
||||
if (op0_n_elts != n_elts || op1_n_elts != n_elts)
|
||||
abort ();
|
||||
|
||||
for (i = 0; i < n_elts; i++)
|
||||
{
|
||||
rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
|
||||
CONST_VECTOR_ELT (trueop0, i),
|
||||
CONST_VECTOR_ELT (trueop1, i));
|
||||
if (!x)
|
||||
return 0;
|
||||
RTVEC_ELT (v, i) = x;
|
||||
}
|
||||
|
||||
return gen_rtx_CONST_VECTOR (mode, v);
|
||||
}
|
||||
|
||||
if (GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
&& GET_CODE (trueop0) == CONST_DOUBLE
|
||||
&& GET_CODE (trueop1) == CONST_DOUBLE
|
||||
|
@ -1515,7 +1571,114 @@ simplify_binary_operation (code, mode, op0, op1)
|
|||
return 0;
|
||||
|
||||
case VEC_SELECT:
|
||||
if (!VECTOR_MODE_P (mode))
|
||||
{
|
||||
if (!VECTOR_MODE_P (GET_MODE (trueop0))
|
||||
|| (mode
|
||||
!= GET_MODE_INNER (GET_MODE (trueop0)))
|
||||
|| GET_CODE (trueop1) != PARALLEL
|
||||
|| XVECLEN (trueop1, 0) != 1
|
||||
|| GET_CODE (XVECEXP (trueop1, 0, 0)) != CONST_INT)
|
||||
abort ();
|
||||
|
||||
if (GET_CODE (trueop0) == CONST_VECTOR)
|
||||
return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP (trueop1, 0, 0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!VECTOR_MODE_P (GET_MODE (trueop0))
|
||||
|| (GET_MODE_INNER (mode)
|
||||
!= GET_MODE_INNER (GET_MODE (trueop0)))
|
||||
|| GET_CODE (trueop1) != PARALLEL)
|
||||
abort ();
|
||||
|
||||
if (GET_CODE (trueop0) == CONST_VECTOR)
|
||||
{
|
||||
int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
|
||||
unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
|
||||
rtvec v = rtvec_alloc (n_elts);
|
||||
unsigned int i;
|
||||
|
||||
if (XVECLEN (trueop1, 0) != (int)n_elts)
|
||||
abort ();
|
||||
for (i = 0; i < n_elts; i++)
|
||||
{
|
||||
rtx x = XVECEXP (trueop1, 0, i);
|
||||
|
||||
if (GET_CODE (x) != CONST_INT)
|
||||
abort ();
|
||||
RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, INTVAL (x));
|
||||
}
|
||||
|
||||
return gen_rtx_CONST_VECTOR (mode, v);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case VEC_CONCAT:
|
||||
{
|
||||
enum machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
|
||||
? GET_MODE (trueop0)
|
||||
: GET_MODE_INNER (mode));
|
||||
enum machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
|
||||
? GET_MODE (trueop1)
|
||||
: GET_MODE_INNER (mode));
|
||||
|
||||
if (!VECTOR_MODE_P (mode)
|
||||
|| (GET_MODE_SIZE (op0_mode) + GET_MODE_SIZE (op1_mode)
|
||||
!= GET_MODE_SIZE (mode)))
|
||||
abort ();
|
||||
|
||||
if ((VECTOR_MODE_P (op0_mode)
|
||||
&& (GET_MODE_INNER (mode)
|
||||
!= GET_MODE_INNER (op0_mode)))
|
||||
|| (!VECTOR_MODE_P (op0_mode)
|
||||
&& GET_MODE_INNER (mode) != op0_mode))
|
||||
abort ();
|
||||
|
||||
if ((VECTOR_MODE_P (op1_mode)
|
||||
&& (GET_MODE_INNER (mode)
|
||||
!= GET_MODE_INNER (op1_mode)))
|
||||
|| (!VECTOR_MODE_P (op1_mode)
|
||||
&& GET_MODE_INNER (mode) != op1_mode))
|
||||
abort ();
|
||||
|
||||
if ((GET_CODE (trueop0) == CONST_VECTOR
|
||||
|| GET_CODE (trueop0) == CONST_INT
|
||||
|| GET_CODE (trueop0) == CONST_DOUBLE)
|
||||
&& (GET_CODE (trueop1) == CONST_VECTOR
|
||||
|| GET_CODE (trueop1) == CONST_INT
|
||||
|| GET_CODE (trueop1) == CONST_DOUBLE))
|
||||
{
|
||||
int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
|
||||
unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
|
||||
rtvec v = rtvec_alloc (n_elts);
|
||||
unsigned int i;
|
||||
unsigned in_n_elts = 1;
|
||||
|
||||
if (VECTOR_MODE_P (op0_mode))
|
||||
in_n_elts = (GET_MODE_SIZE (op0_mode) / elt_size);
|
||||
for (i = 0; i < n_elts; i++)
|
||||
{
|
||||
if (i < in_n_elts)
|
||||
{
|
||||
if (!VECTOR_MODE_P (op0_mode))
|
||||
RTVEC_ELT (v, i) = trueop0;
|
||||
else
|
||||
RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!VECTOR_MODE_P (op1_mode))
|
||||
RTVEC_ELT (v, i) = trueop1;
|
||||
else
|
||||
RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
|
||||
i - in_n_elts);
|
||||
}
|
||||
}
|
||||
|
||||
return gen_rtx_CONST_VECTOR (mode, v);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
default:
|
||||
|
@ -2379,23 +2542,32 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
|
|||
|| GET_MODE (op1) != mode
|
||||
|| !VECTOR_MODE_P (mode))
|
||||
abort ();
|
||||
op0 = avoid_constant_pool_reference (op0);
|
||||
op1 = avoid_constant_pool_reference (op1);
|
||||
op2 = avoid_constant_pool_reference (op2);
|
||||
if (GET_CODE (op0) == CONST_VECTOR
|
||||
&& GET_CODE (op1) == CONST_VECTOR
|
||||
&& GET_CODE (op2) == CONST_INT)
|
||||
if (GET_CODE (op2) == CONST_INT)
|
||||
{
|
||||
int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
|
||||
unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
|
||||
rtvec v = rtvec_alloc (n_elts);
|
||||
unsigned int i;
|
||||
int mask = (1<<n_elts) - 1;
|
||||
|
||||
for (i = 0; i < n_elts; i++)
|
||||
RTVEC_ELT (v, i) = (INTVAL (op2) & (1 << i)
|
||||
? CONST_VECTOR_ELT (op0, i)
|
||||
: CONST_VECTOR_ELT (op1, i));
|
||||
return gen_rtx_CONST_VECTOR (mode, v);
|
||||
if (!(INTVAL (op2) & mask))
|
||||
return op1;
|
||||
if ((INTVAL (op2) & mask) == mask)
|
||||
return op0;
|
||||
|
||||
op0 = avoid_constant_pool_reference (op0);
|
||||
op1 = avoid_constant_pool_reference (op1);
|
||||
if (GET_CODE (op0) == CONST_VECTOR
|
||||
&& GET_CODE (op1) == CONST_VECTOR)
|
||||
{
|
||||
rtvec v = rtvec_alloc (n_elts);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < n_elts; i++)
|
||||
RTVEC_ELT (v, i) = (INTVAL (op2) & (1 << i)
|
||||
? CONST_VECTOR_ELT (op0, i)
|
||||
: CONST_VECTOR_ELT (op1, i));
|
||||
return gen_rtx_CONST_VECTOR (mode, v);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue