diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-02-09 22:55:35 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-02-09 22:55:35 +0000 |
commit | a7e829221f280a3b0aba61e4498622b1ea493ef5 (patch) | |
tree | 64162b5387c0a25095855244c8e0a85d395c9bfa /gcc/simplify-rtx.c | |
parent | b9acd9ea67b1a6646ed0bd2344cfd84e6dd94d43 (diff) | |
download | gcc-a7e829221f280a3b0aba61e4498622b1ea493ef5.tar.gz |
* simplify-rtx.c (simplify_unary_operation,
simplify_binary_operation): Deal with vector modes
(simplify_ternary_operation): Deal with no-op VEC_MERGE.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@62610 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 196 |
1 files changed, 184 insertions, 12 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 9685de0b693..e874c2a2883 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -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; |