From: Jan Hubicka Date: Sun, 9 Feb 2003 22:55:35 +0000 (+0100) Subject: simplify-rtx.c (simplify_unary_operation, [...]): Deal with vector modes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=852c8ba12e7824f881bd52a16af2a033a798cb23;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 826f092ea62..e7449de84be 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Sun Feb 9 23:54:59 CET 2003 Jan Hubicka + + * 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 * toplev.c (rest_of_compilation): Recompute register usage after 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<