From b649c04eecaa9beab9c741a3010d4c3c0e8364b2 Mon Sep 17 00:00:00 2001 From: hubicka Date: Sun, 9 Feb 2003 12:35:28 +0000 Subject: [PATCH] * i386.md (ahi?v*3): Set third operand type to TImode. * i386.c (ix86_expand_binop_builtin): Extend operand when needed. * simplify-rtx.c (simplify_subreg): Fix conversion from vector into integer mode. * rtl.def (VEC_MERGE, VEC_SELECT, VEC_CONCAT, VEC_DUPLICATE): Change code so they are arithmetic expressions now. * simplify-rtx.c (simplify_unary_operation, simplify_binary_operation, simplify_ternary_operation): Deal with VEC_* expressions. * i386.md (vmaskcmp, pinsrw, movd patterns): Fix RTL representation. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@62600 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 15 +++++++++++ gcc/config/i386/i386.c | 7 +++++ gcc/config/i386/i386.md | 25 ++++++++--------- gcc/rtl.def | 8 +++--- gcc/simplify-rtx.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 109 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b078754b890..85981b36788 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +Sun Feb 9 13:33:34 CET 2003 Jan Hubicka + + * i386.md (ahi?v*3): Set third operand type to TImode. + * i386.c (ix86_expand_binop_builtin): Extend operand when needed. + + * simplify-rtx.c (simplify_subreg): Fix conversion from vector into + integer mode. + + * rtl.def (VEC_MERGE, VEC_SELECT, VEC_CONCAT, VEC_DUPLICATE): + Change code so they are arithmetic expressions now. + * simplify-rtx.c (simplify_unary_operation, simplify_binary_operation, + simplify_ternary_operation): Deal with VEC_* expressions. + + * i386.md (vmaskcmp, pinsrw, movd patterns): Fix RTL representation. + Sat Feb 8 00:21:22 CET 2003 Jan Hubicka * cfgrtl.c (verify_flow_info): Use control_flow_insn_p. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index def53d052d0..b9b2c32d3da 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13434,6 +13434,13 @@ ix86_expand_binop_builtin (icode, arglist, target) || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) target = gen_reg_rtx (tmode); + if (GET_MODE (op1) == SImode && mode1 == TImode) + { + rtx x = gen_reg_rtx (V4SImode); + emit_insn (gen_sse2_loadd (x, op1)); + op1 = gen_lowpart (TImode, x); + } + /* In case the insn wants input operands in modes different from the result, abort. */ if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2db17890011..97c6d9e6a75 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -19917,7 +19917,7 @@ (match_operator:V4SI 3 "sse_comparison_operator" [(match_operand:V4SF 1 "register_operand" "0") (match_operand:V4SF 2 "register_operand" "x")]) - (match_dup 1) + (subreg:V4SI (match_dup 1) 0) (const_int 1)))] "TARGET_SSE" "cmp%D3ss\t{%2, %0|%0, %2}" @@ -21496,7 +21496,7 @@ (match_operator:V2DI 3 "sse_comparison_operator" [(match_operand:V2DF 1 "register_operand" "0") (match_operand:V2DF 2 "nonimmediate_operand" "x")]) - (match_dup 1) + (subreg:V2DI (match_dup 1) 0) (const_int 1)))] "TARGET_SSE2" "cmp%D3sd\t{%2, %0|%0, %2}" @@ -22107,7 +22107,8 @@ [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0") (vec_duplicate:V8HI - (match_operand:SI 2 "nonimmediate_operand" "rm")) + (truncate:HI + (match_operand:SI 2 "nonimmediate_operand" "rm"))) (match_operand:SI 3 "immediate_operand" "i")))] "TARGET_SSE2" "pinsrw\t{%3, %2, %0|%0, %2, %3}" @@ -22256,7 +22257,7 @@ (define_insn "ashrv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "xi")))] + (match_operand:TI 2 "nonmemory_operand" "xi")))] "TARGET_SSE2" "psraw\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") @@ -22265,7 +22266,7 @@ (define_insn "ashrv4si3" [(set (match_operand:V4SI 0 "register_operand" "=x") (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "xi")))] + (match_operand:TI 2 "nonmemory_operand" "xi")))] "TARGET_SSE2" "psrad\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") @@ -22274,7 +22275,7 @@ (define_insn "lshrv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "xi")))] + (match_operand:TI 2 "nonmemory_operand" "xi")))] "TARGET_SSE2" "psrlw\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") @@ -22283,7 +22284,7 @@ (define_insn "lshrv4si3" [(set (match_operand:V4SI 0 "register_operand" "=x") (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "xi")))] + (match_operand:TI 2 "nonmemory_operand" "xi")))] "TARGET_SSE2" "psrld\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") @@ -22292,7 +22293,7 @@ (define_insn "lshrv2di3" [(set (match_operand:V2DI 0 "register_operand" "=x") (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "xi")))] + (match_operand:TI 2 "nonmemory_operand" "xi")))] "TARGET_SSE2" "psrlq\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") @@ -22301,7 +22302,7 @@ (define_insn "ashlv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "xi")))] + (match_operand:TI 2 "nonmemory_operand" "xi")))] "TARGET_SSE2" "psllw\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") @@ -22310,7 +22311,7 @@ (define_insn "ashlv4si3" [(set (match_operand:V4SI 0 "register_operand" "=x") (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "xi")))] + (match_operand:TI 2 "nonmemory_operand" "xi")))] "TARGET_SSE2" "pslld\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") @@ -22319,7 +22320,7 @@ (define_insn "ashlv2di3" [(set (match_operand:V2DI 0 "register_operand" "=x") (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "xi")))] + (match_operand:TI 2 "nonmemory_operand" "xi")))] "TARGET_SSE2" "psllq\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") @@ -22707,7 +22708,7 @@ (define_insn "sse2_loadd" [(set (match_operand:V4SI 0 "register_operand" "=x") (vec_merge:V4SI - (vec_duplicate:V4HI (match_operand:SI 1 "nonimmediate_operand" "mr")) + (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr")) (const_vector:V4SI [(const_int 0) (const_int 0) (const_int 0) diff --git a/gcc/rtl.def b/gcc/rtl.def index ff19dd95d65..b2087241e17 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -1174,24 +1174,24 @@ DEF_RTL_EXPR(CALL_PLACEHOLDER, "call_placeholder", "uuuu", 'x') that specifies where the parts of the result are taken from. Set bits indicate operand 0, clear bits indicate operand 1. The parts are defined by the mode of the vectors. */ -DEF_RTL_EXPR(VEC_MERGE, "vec_merge", "eee", 'x') +DEF_RTL_EXPR(VEC_MERGE, "vec_merge", "eee", '3') /* Describes an operation that selects parts of a vector. Operands 0 is the source vector, operand 1 is a PARALLEL that contains a CONST_INT for each of the subparts of the result vector, giving the number of the source subpart that should be stored into it. */ -DEF_RTL_EXPR(VEC_SELECT, "vec_select", "ee", 'x') +DEF_RTL_EXPR(VEC_SELECT, "vec_select", "ee", '2') /* Describes a vector concat operation. Operands 0 and 1 are the source vectors, the result is a vector that is as long as operands 0 and 1 combined and is the concatenation of the two source vectors. */ -DEF_RTL_EXPR(VEC_CONCAT, "vec_concat", "ee", 'x') +DEF_RTL_EXPR(VEC_CONCAT, "vec_concat", "ee", '2') /* Describes an operation that converts a small vector into a larger one by duplicating the input values. The output vector mode must have the same submodes as the input vector mode, and the number of output parts must be an integer multiple of the number of input parts. */ -DEF_RTL_EXPR(VEC_DUPLICATE, "vec_duplicate", "e", 'x') +DEF_RTL_EXPR(VEC_DUPLICATE, "vec_duplicate", "e", '1') /* Addition with signed saturation */ DEF_RTL_EXPR(SS_PLUS, "ss_plus", "ee", 'c') diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 0298b79e8ce..9685de0b693 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -372,6 +372,44 @@ simplify_unary_operation (code, mode, op, op_mode) unsigned int width = GET_MODE_BITSIZE (mode); rtx trueop = avoid_constant_pool_reference (op); + if (code == VEC_DUPLICATE) + { + if (!VECTOR_MODE_P (mode)) + abort (); + if (GET_MODE (trueop) != VOIDmode + && !VECTOR_MODE_P (GET_MODE (trueop)) + && GET_MODE_INNER (mode) != GET_MODE (trueop)) + abort (); + if (GET_MODE (trueop) != VOIDmode + && VECTOR_MODE_P (GET_MODE (trueop)) + && GET_MODE_INNER (mode) != GET_MODE_INNER (GET_MODE (trueop))) + abort (); + if (GET_CODE (trueop) == CONST_INT || GET_CODE (trueop) == CONST_DOUBLE + || GET_CODE (trueop) == 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 (GET_CODE (trueop) != CONST_VECTOR) + for (i = 0; i < n_elts; i++) + RTVEC_ELT (v, i) = trueop; + else + { + enum machine_mode inmode = GET_MODE (trueop); + int in_elt_size = GET_MODE_SIZE (GET_MODE_INNER (inmode)); + unsigned in_n_elts = (GET_MODE_SIZE (inmode) / in_elt_size); + + if (in_n_elts >= n_elts || n_elts % in_n_elts) + abort (); + for (i = 0; i < n_elts; i++) + RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop, i % in_n_elts); + } + 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. */ @@ -1476,6 +1514,10 @@ simplify_binary_operation (code, mode, op0, op1) /* ??? There are simplifications that can be done. */ return 0; + case VEC_SELECT: + case VEC_CONCAT: + return 0; + default: abort (); } @@ -2332,6 +2374,30 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2) } } break; + case VEC_MERGE: + if (GET_MODE (op0) != mode + || 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) + { + 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; + + 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; default: abort (); @@ -2413,13 +2479,16 @@ simplify_subreg (outermode, op, innermode, byte) } if (GET_CODE (elt) != CONST_INT) return NULL_RTX; + /* Avoid overflow. */ + if (high >> (HOST_BITS_PER_WIDE_INT - shift)) + return NULL_RTX; high = high << shift | sum >> (HOST_BITS_PER_WIDE_INT - shift); sum = (sum << shift) + INTVAL (elt); } if (GET_MODE_BITSIZE (outermode) <= HOST_BITS_PER_WIDE_INT) return GEN_INT (trunc_int_for_mode (sum, outermode)); else if (GET_MODE_BITSIZE (outermode) == 2* HOST_BITS_PER_WIDE_INT) - return immed_double_const (high, sum, outermode); + return immed_double_const (sum, high, outermode); else return NULL_RTX; } -- 2.11.4.GIT