i386-protos.h (ix86_expand_adjust_ufix_to_sfix_si): New prototype.
* config/i386/i386-protos.h (ix86_expand_adjust_ufix_to_sfix_si): New prototype. * config/i386/i386.c (ix86_expand_adjust_ufix_to_sfix_si): New function. * config/i386/sse.md (fixuns_trunc<mode><sseintvecmodelower>2): Use it. (ssepackfltmode): New mode attr. (vec_pack_ufix_trunc_<mode>): New expander. From-SVN: r180743
This commit is contained in:
parent
8d1788f2e1
commit
6bf39801d4
@ -1,3 +1,14 @@
|
||||
2011-11-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/i386/i386-protos.h (ix86_expand_adjust_ufix_to_sfix_si): New
|
||||
prototype.
|
||||
* config/i386/i386.c (ix86_expand_adjust_ufix_to_sfix_si): New
|
||||
function.
|
||||
* config/i386/sse.md (fixuns_trunc<mode><sseintvecmodelower>2): Use
|
||||
it.
|
||||
(ssepackfltmode): New mode attr.
|
||||
(vec_pack_ufix_trunc_<mode>): New expander.
|
||||
|
||||
2011-10-30 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* config/i386/i386.md (floatsi<mode>2_vector_sse_with_temp splitter):
|
||||
|
@ -109,6 +109,7 @@ extern void ix86_expand_convert_uns_sixf_sse (rtx, rtx);
|
||||
extern void ix86_expand_convert_uns_sidf_sse (rtx, rtx);
|
||||
extern void ix86_expand_convert_uns_sisf_sse (rtx, rtx);
|
||||
extern void ix86_expand_convert_sign_didf_sse (rtx, rtx);
|
||||
extern rtx ix86_expand_adjust_ufix_to_sfix_si (rtx);
|
||||
extern enum ix86_fpcmp_strategy ix86_fp_comparison_strategy (enum rtx_code);
|
||||
extern void ix86_expand_fp_absneg_operator (enum rtx_code, enum machine_mode,
|
||||
rtx[]);
|
||||
|
@ -17016,6 +17016,46 @@ ix86_expand_convert_uns_sisf_sse (rtx target, rtx input)
|
||||
emit_move_insn (target, fp_hi);
|
||||
}
|
||||
|
||||
/* Adjust a V*SFmode/V*DFmode value VAL so that *sfix_trunc* resp. fix_trunc*
|
||||
pattern can be used on it instead of *ufix_trunc* resp. fixuns_trunc*.
|
||||
This is done by subtracting 0x1p32 from VAL if VAL is greater or equal
|
||||
(non-signalling) than 0x1p31. */
|
||||
|
||||
rtx
|
||||
ix86_expand_adjust_ufix_to_sfix_si (rtx val)
|
||||
{
|
||||
REAL_VALUE_TYPE MTWO32r, TWO31r;
|
||||
rtx two31r, mtwo32r, tmp[3];
|
||||
enum machine_mode mode = GET_MODE (val);
|
||||
enum machine_mode scalarmode = GET_MODE_INNER (mode);
|
||||
rtx (*cmp) (rtx, rtx, rtx, rtx);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
tmp[i] = gen_reg_rtx (mode);
|
||||
real_ldexp (&TWO31r, &dconst1, 31);
|
||||
two31r = const_double_from_real_value (TWO31r, scalarmode);
|
||||
two31r = ix86_build_const_vector (mode, 1, two31r);
|
||||
two31r = force_reg (mode, two31r);
|
||||
real_ldexp (&MTWO32r, &dconstm1, 32);
|
||||
mtwo32r = const_double_from_real_value (MTWO32r, scalarmode);
|
||||
mtwo32r = ix86_build_const_vector (mode, 1, mtwo32r);
|
||||
mtwo32r = force_reg (mode, mtwo32r);
|
||||
switch (mode)
|
||||
{
|
||||
case V8SFmode: cmp = gen_avx_cmpv8sf3; break;
|
||||
case V4SFmode: cmp = gen_avx_cmpv4sf3; break;
|
||||
case V4DFmode: cmp = gen_avx_cmpv4df3; break;
|
||||
case V2DFmode: cmp = gen_avx_cmpv2df3; break;
|
||||
default: gcc_unreachable ();
|
||||
}
|
||||
emit_insn (cmp (tmp[0], val, two31r, GEN_INT (29)));
|
||||
tmp[1] = expand_simple_binop (mode, AND, tmp[0], mtwo32r, tmp[1],
|
||||
0, OPTAB_DIRECT);
|
||||
return expand_simple_binop (mode, PLUS, val, tmp[1], tmp[2],
|
||||
0, OPTAB_DIRECT);
|
||||
}
|
||||
|
||||
/* A subroutine of ix86_build_signbit_mask. If VECT is true,
|
||||
then replicate the value for all elements of the vector
|
||||
register. */
|
||||
|
@ -2323,32 +2323,13 @@
|
||||
(set_attr "mode" "TI")])
|
||||
|
||||
(define_expand "fixuns_trunc<mode><sseintvecmodelower>2"
|
||||
[(set (match_dup 4)
|
||||
(unspec:VF1
|
||||
[(match_operand:VF1 1 "register_operand" "")
|
||||
(match_dup 2)
|
||||
(const_int 29)] UNSPEC_PCMP))
|
||||
(set (match_dup 5)
|
||||
(and:VF1 (match_dup 4) (match_dup 3)))
|
||||
(set (match_dup 6)
|
||||
(plus:VF1 (match_dup 1) (match_dup 5)))
|
||||
(set (match_operand:<sseintvecmode> 0 "register_operand" "")
|
||||
(fix:<sseintvecmode> (match_dup 6)))]
|
||||
[(match_operand:<sseintvecmode> 0 "register_operand" "")
|
||||
(match_operand:VF1 1 "register_operand" "")]
|
||||
"TARGET_AVX"
|
||||
{
|
||||
REAL_VALUE_TYPE MTWO32r, TWO31r;
|
||||
int i;
|
||||
|
||||
real_ldexp (&TWO31r, &dconst1, 31);
|
||||
operands[2] = const_double_from_real_value (TWO31r, SFmode);
|
||||
operands[2] = ix86_build_const_vector (<MODE>mode, 1, operands[2]);
|
||||
operands[2] = force_reg (<MODE>mode, operands[2]);
|
||||
real_ldexp (&MTWO32r, &dconstm1, 32);
|
||||
operands[3] = const_double_from_real_value (MTWO32r, SFmode);
|
||||
operands[3] = ix86_build_const_vector (<MODE>mode, 1, operands[3]);
|
||||
operands[3] = force_reg (<MODE>mode, operands[3]);
|
||||
for (i = 4; i < 7; i++)
|
||||
operands[i] = gen_reg_rtx (<MODE>mode);
|
||||
rtx tmp = ix86_expand_adjust_ufix_to_sfix_si (operands[1]);
|
||||
emit_insn (gen_fix_trunc<mode><sseintvecmodelower>2 (operands[0], tmp));
|
||||
DONE;
|
||||
})
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -3127,6 +3108,22 @@
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_mode_attr ssepackfltmode
|
||||
[(V4DF "V8SI") (V2DF "V4SI")])
|
||||
|
||||
(define_expand "vec_pack_ufix_trunc_<mode>"
|
||||
[(match_operand:<ssepackfltmode> 0 "register_operand" "")
|
||||
(match_operand:VF2 1 "register_operand" "")
|
||||
(match_operand:VF2 2 "register_operand" "")]
|
||||
"TARGET_AVX"
|
||||
{
|
||||
rtx tmp[2];
|
||||
tmp[0] = ix86_expand_adjust_ufix_to_sfix_si (operands[1]);
|
||||
tmp[1] = ix86_expand_adjust_ufix_to_sfix_si (operands[2]);
|
||||
emit_insn (gen_vec_pack_sfix_trunc_<mode> (operands[0], tmp[0], tmp[1]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "vec_pack_sfix_v4df"
|
||||
[(match_operand:V8SI 0 "register_operand" "")
|
||||
(match_operand:V4DF 1 "nonimmediate_operand" "")
|
||||
|
Loading…
Reference in New Issue
Block a user