diff options
author | Jan Hubicka <jh@suse.cz> | 2003-02-09 13:35:28 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2003-02-09 12:35:28 +0000 |
commit | d9deed68d467546014f23e54e630cf596c42ff5d (patch) | |
tree | 703dc561ba11a34e2a0c453032326a663273f8bc | |
parent | 83fd323c4c5fd8f067803028a71870b0dfd8ae30 (diff) | |
download | gcc-d9deed68d467546014f23e54e630cf596c42ff5d.zip gcc-d9deed68d467546014f23e54e630cf596c42ff5d.tar.gz gcc-d9deed68d467546014f23e54e630cf596c42ff5d.tar.bz2 |
i386.md (ahi?v*3): Set third operand type to TImode.
* 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.
From-SVN: r62600
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 25 | ||||
-rw-r--r-- | gcc/rtl.def | 8 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 71 |
5 files changed, 109 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b078754..85981b3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +Sun Feb 9 13:33:34 CET 2003 Jan Hubicka <jh@suse.cz> + + * 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 <jh@suse.cz> * 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 def53d0..b9b2c32 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 2db1789..97c6d9e 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 ff19dd9..b208724 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 0298b79e..9685de0 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; } |