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
This commit is contained in:
Jan Hubicka 2003-02-09 13:35:28 +01:00 committed by Jan Hubicka
parent 83fd323c4c
commit d9deed68d4
5 changed files with 109 additions and 17 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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')

View File

@ -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;
}