mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 05:10:25 +08:00
re PR target/8322 (SSE2 intrinsics broken?)
* genopinit.c (optabs): Add addc_optab. * ifcvt.c (noce_try_store_flag): Rename to ... (noce_try_addcc): ... this one; handle generic conditional increment. (noce_process_if_block): Update noce_try_addcc call. * optabs.c (emit_conditional_add): New. (init_obtabs): Initialize addc_optab. * optabs.h (optab_index): Add OTI_addcc. (addcc_optab): New macro. * md.texi: Document addMcc PR target/8322 * i386.c (ix86_init_mmx_sse_builtins): Constify arguments of loads. * xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts. * xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts. * reload1.c (delete_output_reload): Avoid repeated attempts to delete insn. From-SVN: r61019
This commit is contained in:
parent
eb70d86d7e
commit
068f5deabf
@ -1,3 +1,23 @@
|
||||
Tue Jan 7 21:46:57 CET 2003 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* genopinit.c (optabs): Add addc_optab.
|
||||
* ifcvt.c (noce_try_store_flag): Rename to ...
|
||||
(noce_try_addcc): ... this one; handle generic conditional increment.
|
||||
(noce_process_if_block): Update noce_try_addcc call.
|
||||
* optabs.c (emit_conditional_add): New.
|
||||
(init_obtabs): Initialize addc_optab.
|
||||
* optabs.h (optab_index): Add OTI_addcc.
|
||||
(addcc_optab): New macro.
|
||||
* md.texi: Document addMcc
|
||||
|
||||
PR target/8322
|
||||
* i386.c (ix86_init_mmx_sse_builtins): Constify arguments of loads.
|
||||
* xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts.
|
||||
* xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts.
|
||||
|
||||
* reload1.c (delete_output_reload): Avoid repeated attempts
|
||||
to delete insn.
|
||||
|
||||
2003-01-07 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* configure.in: Restore CFLAGS before gcc_AC_INITFINI_ARRAY.
|
||||
|
@ -9584,11 +9584,11 @@ ix86_expand_int_movcc (operands)
|
||||
/* On x86_64 the lea instruction operates on Pmode, so we need
|
||||
to get arithmetics done in proper mode to match. */
|
||||
if (diff == 1)
|
||||
tmp = out;
|
||||
tmp = copy_rtx (out);
|
||||
else
|
||||
{
|
||||
rtx out1;
|
||||
out1 = out;
|
||||
out1 = copy_rtx (out);
|
||||
tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1));
|
||||
nops++;
|
||||
if (diff & 1)
|
||||
@ -12590,7 +12590,11 @@ ix86_init_mmx_sse_builtins ()
|
||||
size_t i;
|
||||
|
||||
tree pchar_type_node = build_pointer_type (char_type_node);
|
||||
tree pcchar_type_node = build_pointer_type (
|
||||
build_type_variant (char_type_node, 1, 0));
|
||||
tree pfloat_type_node = build_pointer_type (float_type_node);
|
||||
tree pcfloat_type_node = build_pointer_type (
|
||||
build_type_variant (float_type_node, 1, 0));
|
||||
tree pv2si_type_node = build_pointer_type (V2SI_type_node);
|
||||
tree pv2di_type_node = build_pointer_type (V2DI_type_node);
|
||||
tree pdi_type_node = build_pointer_type (long_long_unsigned_type_node);
|
||||
@ -12663,8 +12667,8 @@ ix86_init_mmx_sse_builtins ()
|
||||
= build_function_type_list (void_type_node,
|
||||
V8QI_type_node, V8QI_type_node,
|
||||
pchar_type_node, NULL_TREE);
|
||||
tree v4sf_ftype_pfloat
|
||||
= build_function_type_list (V4SF_type_node, pfloat_type_node, NULL_TREE);
|
||||
tree v4sf_ftype_pcfloat
|
||||
= build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
|
||||
/* @@@ the type is bogus */
|
||||
tree v4sf_ftype_v4sf_pv2si
|
||||
= build_function_type_list (V4SF_type_node,
|
||||
@ -12719,7 +12723,11 @@ ix86_init_mmx_sse_builtins ()
|
||||
= build_function_type_list (V2SI_type_node,
|
||||
V2SF_type_node, V2SF_type_node, NULL_TREE);
|
||||
tree pint_type_node = build_pointer_type (integer_type_node);
|
||||
tree pcint_type_node = build_pointer_type (
|
||||
build_type_variant (integer_type_node, 1, 0));
|
||||
tree pdouble_type_node = build_pointer_type (double_type_node);
|
||||
tree pcdouble_type_node = build_pointer_type (
|
||||
build_type_variant (double_type_node, 1, 0));
|
||||
tree int_ftype_v2df_v2df
|
||||
= build_function_type_list (integer_type_node,
|
||||
V2DF_type_node, V2DF_type_node, NULL_TREE);
|
||||
@ -12731,8 +12739,8 @@ ix86_init_mmx_sse_builtins ()
|
||||
tree ti_ftype_ti_ti
|
||||
= build_function_type_list (intTI_type_node,
|
||||
intTI_type_node, intTI_type_node, NULL_TREE);
|
||||
tree void_ftype_pvoid
|
||||
= build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
|
||||
tree void_ftype_pcvoid
|
||||
= build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE);
|
||||
tree v2di_ftype_di
|
||||
= build_function_type_list (V2DI_type_node,
|
||||
long_long_unsigned_type_node, NULL_TREE);
|
||||
@ -12787,8 +12795,8 @@ ix86_init_mmx_sse_builtins ()
|
||||
= build_function_type_list (void_type_node,
|
||||
V16QI_type_node, V16QI_type_node,
|
||||
pchar_type_node, NULL_TREE);
|
||||
tree v2df_ftype_pdouble
|
||||
= build_function_type_list (V2DF_type_node, pdouble_type_node, NULL_TREE);
|
||||
tree v2df_ftype_pcdouble
|
||||
= build_function_type_list (V2DF_type_node, pcdouble_type_node, NULL_TREE);
|
||||
tree v2df_ftype_v2df_v2df
|
||||
= build_function_type_list (V2DF_type_node,
|
||||
V2DF_type_node, V2DF_type_node, NULL_TREE);
|
||||
@ -12847,16 +12855,16 @@ ix86_init_mmx_sse_builtins ()
|
||||
V16QI_type_node, V16QI_type_node, NULL_TREE);
|
||||
tree int_ftype_v16qi
|
||||
= build_function_type_list (integer_type_node, V16QI_type_node, NULL_TREE);
|
||||
tree v16qi_ftype_pchar
|
||||
= build_function_type_list (V16QI_type_node, pchar_type_node, NULL_TREE);
|
||||
tree v16qi_ftype_pcchar
|
||||
= build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
|
||||
tree void_ftype_pchar_v16qi
|
||||
= build_function_type_list (void_type_node,
|
||||
pchar_type_node, V16QI_type_node, NULL_TREE);
|
||||
tree v4si_ftype_pchar
|
||||
= build_function_type_list (V4SI_type_node, pchar_type_node, NULL_TREE);
|
||||
tree void_ftype_pchar_v4si
|
||||
tree v4si_ftype_pcint
|
||||
= build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
|
||||
tree void_ftype_pcint_v4si
|
||||
= build_function_type_list (void_type_node,
|
||||
pchar_type_node, V4SI_type_node, NULL_TREE);
|
||||
pcint_type_node, V4SI_type_node, NULL_TREE);
|
||||
tree v2di_ftype_v2di
|
||||
= build_function_type_list (V2DI_type_node, V2DI_type_node, NULL_TREE);
|
||||
|
||||
@ -12971,9 +12979,9 @@ ix86_init_mmx_sse_builtins ()
|
||||
|
||||
def_builtin (MASK_SSE1 | MASK_3DNOW_A, "__builtin_ia32_maskmovq", void_ftype_v8qi_v8qi_pchar, IX86_BUILTIN_MASKMOVQ);
|
||||
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_loadaps", v4sf_ftype_pfloat, IX86_BUILTIN_LOADAPS);
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_loadups", v4sf_ftype_pfloat, IX86_BUILTIN_LOADUPS);
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_loadss", v4sf_ftype_pfloat, IX86_BUILTIN_LOADSS);
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_loadaps", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADAPS);
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_loadups", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADUPS);
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_loadss", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADSS);
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_storeaps", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREAPS);
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_storeups", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREUPS);
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_storess", void_ftype_pfloat_v4sf, IX86_BUILTIN_STORESS);
|
||||
@ -13041,9 +13049,9 @@ ix86_init_mmx_sse_builtins ()
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_movq2dq", v2di_ftype_di, IX86_BUILTIN_MOVQ2DQ);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_movdq2q", di_ftype_v2di, IX86_BUILTIN_MOVDQ2Q);
|
||||
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadapd", v2df_ftype_pdouble, IX86_BUILTIN_LOADAPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadupd", v2df_ftype_pdouble, IX86_BUILTIN_LOADUPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadsd", v2df_ftype_pdouble, IX86_BUILTIN_LOADSD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadapd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADAPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadupd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADUPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadsd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADSD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_storeapd", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREAPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_storeupd", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREUPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_storesd", void_ftype_pdouble_v2df, IX86_BUILTIN_STORESD);
|
||||
@ -13094,21 +13102,21 @@ ix86_init_mmx_sse_builtins ()
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_setpd1", v2df_ftype_double, IX86_BUILTIN_SETPD1);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_setpd", v2df_ftype_double_double, IX86_BUILTIN_SETPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_setzeropd", ti_ftype_void, IX86_BUILTIN_CLRPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadpd1", v2df_ftype_pdouble, IX86_BUILTIN_LOADPD1);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadrpd", v2df_ftype_pdouble, IX86_BUILTIN_LOADRPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadpd1", v2df_ftype_pcdouble, IX86_BUILTIN_LOADPD1);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadrpd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADRPD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_storepd1", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREPD1);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_storerpd", void_ftype_pdouble_v2df, IX86_BUILTIN_STORERPD);
|
||||
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_clflush", void_ftype_pvoid, IX86_BUILTIN_CLFLUSH);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_clflush", void_ftype_pcvoid, IX86_BUILTIN_CLFLUSH);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_lfence", void_ftype_void, IX86_BUILTIN_LFENCE);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_mfence", void_ftype_void, IX86_BUILTIN_MFENCE);
|
||||
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loaddqa", v16qi_ftype_pchar, IX86_BUILTIN_LOADDQA);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loaddqu", v16qi_ftype_pchar, IX86_BUILTIN_LOADDQU);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadd", v4si_ftype_pchar, IX86_BUILTIN_LOADD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loaddqa", v16qi_ftype_pcchar, IX86_BUILTIN_LOADDQA);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loaddqu", v16qi_ftype_pcchar, IX86_BUILTIN_LOADDQU);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_loadd", v4si_ftype_pcint, IX86_BUILTIN_LOADD);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_storedqa", void_ftype_pchar_v16qi, IX86_BUILTIN_STOREDQA);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_storedqu", void_ftype_pchar_v16qi, IX86_BUILTIN_STOREDQU);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_stored", void_ftype_pchar_v4si, IX86_BUILTIN_STORED);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_stored", void_ftype_pcint_v4si, IX86_BUILTIN_STORED);
|
||||
def_builtin (MASK_SSE2, "__builtin_ia32_movq", v2di_ftype_v2di, IX86_BUILTIN_MOVQ);
|
||||
|
||||
def_builtin (MASK_SSE1, "__builtin_ia32_setzero128", v2di_ftype_void, IX86_BUILTIN_CLRTI);
|
||||
|
@ -1586,13 +1586,13 @@ _mm_ucomineq_sd (__m128d __A, __m128d __B)
|
||||
static __inline __m128i
|
||||
_mm_load_si128 (__m128i const *__P)
|
||||
{
|
||||
return (__m128i) __builtin_ia32_loaddqa (__P);
|
||||
return (__m128i) __builtin_ia32_loaddqa ((char const *)__P);
|
||||
}
|
||||
|
||||
static __inline __m128i
|
||||
_mm_loadu_si128 (__m128i const *__P)
|
||||
{
|
||||
return (__m128i) __builtin_ia32_loaddqu (__P);
|
||||
return (__m128i) __builtin_ia32_loaddqu ((char const *)__P);
|
||||
}
|
||||
|
||||
static __inline __m128i
|
||||
@ -1604,13 +1604,13 @@ _mm_loadl_epi64 (__m128i const *__P)
|
||||
static __inline void
|
||||
_mm_store_si128 (__m128i *__P, __m128i __B)
|
||||
{
|
||||
__builtin_ia32_storedqa (__P, (__v16qi)__B);
|
||||
__builtin_ia32_storedqa ((char *)__P, (__v16qi)__B);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_mm_storeu_si128 (__m128i *__P, __m128i __B)
|
||||
{
|
||||
__builtin_ia32_storedqu (__P, (__v16qi)__B);
|
||||
__builtin_ia32_storedqu ((char *)__P, (__v16qi)__B);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
|
@ -2854,6 +2854,13 @@ codes and vice versa.
|
||||
If the machine does not have conditional move instructions, do not
|
||||
define these patterns.
|
||||
|
||||
@cindex @code{add@var{mode}cc} instruction pattern
|
||||
@item @samp{mov@var{mode}cc}
|
||||
Similar to @samp{mov@var{mode}cc} but for conditional addition. Conditionally
|
||||
move operand 2 or (operands 2 + operand 3) into operand 0 according to the
|
||||
comparison in operand 1. If the comparison is true, operand 2 is moved into
|
||||
operand 0, otherwise operand 3 is moved.
|
||||
|
||||
@cindex @code{s@var{cond}} instruction pattern
|
||||
@item @samp{s@var{cond}}
|
||||
Store zero or nonzero in the operand according to the condition codes.
|
||||
|
@ -130,6 +130,7 @@ static const char * const optabs[] =
|
||||
"movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
|
||||
"cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
|
||||
"tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
|
||||
"addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
|
||||
"bcc_gen_fctn[$C] = gen_$(b$c$)",
|
||||
"setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
|
||||
"movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
|
||||
|
88
gcc/ifcvt.c
88
gcc/ifcvt.c
@ -582,7 +582,7 @@ struct noce_if_info
|
||||
static rtx noce_emit_store_flag PARAMS ((struct noce_if_info *,
|
||||
rtx, int, int));
|
||||
static int noce_try_store_flag PARAMS ((struct noce_if_info *));
|
||||
static int noce_try_store_flag_inc PARAMS ((struct noce_if_info *));
|
||||
static int noce_try_addcc PARAMS ((struct noce_if_info *));
|
||||
static int noce_try_store_flag_constants PARAMS ((struct noce_if_info *));
|
||||
static int noce_try_store_flag_mask PARAMS ((struct noce_if_info *));
|
||||
static rtx noce_emit_cmove PARAMS ((struct noce_if_info *,
|
||||
@ -864,43 +864,32 @@ noce_try_store_flag_constants (if_info)
|
||||
similarly for "foo--". */
|
||||
|
||||
static int
|
||||
noce_try_store_flag_inc (if_info)
|
||||
noce_try_addcc (if_info)
|
||||
struct noce_if_info *if_info;
|
||||
{
|
||||
rtx target, seq;
|
||||
int subtract, normalize;
|
||||
|
||||
if (! no_new_pseudos
|
||||
&& (BRANCH_COST >= 2
|
||||
|| HAVE_incscc
|
||||
|| HAVE_decscc)
|
||||
/* Should be no `else' case to worry about. */
|
||||
&& if_info->b == if_info->x
|
||||
&& GET_CODE (if_info->a) == PLUS
|
||||
&& (XEXP (if_info->a, 1) == const1_rtx
|
||||
|| XEXP (if_info->a, 1) == constm1_rtx)
|
||||
&& rtx_equal_p (XEXP (if_info->a, 0), if_info->x)
|
||||
&& (reversed_comparison_code (if_info->cond, if_info->jump)
|
||||
!= UNKNOWN))
|
||||
{
|
||||
if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
|
||||
subtract = 0, normalize = 0;
|
||||
else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
|
||||
subtract = 1, normalize = 0;
|
||||
else
|
||||
subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
|
||||
|
||||
rtx cond = if_info->cond;
|
||||
enum rtx_code code = reversed_comparison_code (cond, if_info->jump);
|
||||
|
||||
/* First try to use addcc pattern. */
|
||||
start_sequence ();
|
||||
|
||||
target = noce_emit_store_flag (if_info,
|
||||
gen_reg_rtx (GET_MODE (if_info->x)),
|
||||
1, normalize);
|
||||
|
||||
if (target)
|
||||
target = expand_simple_binop (GET_MODE (if_info->x),
|
||||
subtract ? MINUS : PLUS,
|
||||
if_info->x, target, if_info->x,
|
||||
0, OPTAB_WIDEN);
|
||||
target = emit_conditional_add (if_info->x, code,
|
||||
XEXP (cond, 0), XEXP (cond, 1),
|
||||
VOIDmode,
|
||||
if_info->b, XEXP (if_info->a, 1),
|
||||
GET_MODE (if_info->x),
|
||||
(code == LTU || code == GEU
|
||||
|| code == LEU || code == GTU));
|
||||
if (target)
|
||||
{
|
||||
if (target != if_info->x)
|
||||
@ -908,17 +897,54 @@ noce_try_store_flag_inc (if_info)
|
||||
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
|
||||
if (seq_contains_jump (seq))
|
||||
return FALSE;
|
||||
|
||||
emit_insn_before_scope (seq, if_info->jump,
|
||||
INSN_SCOPE (if_info->insn_a));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
end_sequence ();
|
||||
|
||||
/* If that fails, construct conditional increment or decrement using
|
||||
setcc. */
|
||||
if (BRANCH_COST >= 2
|
||||
&& (XEXP (if_info->a, 1) == const1_rtx
|
||||
|| XEXP (if_info->a, 1) == constm1_rtx))
|
||||
{
|
||||
start_sequence ();
|
||||
if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
|
||||
subtract = 0, normalize = 0;
|
||||
else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
|
||||
subtract = 1, normalize = 0;
|
||||
else
|
||||
subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
|
||||
|
||||
|
||||
target = noce_emit_store_flag (if_info,
|
||||
gen_reg_rtx (GET_MODE (if_info->x)),
|
||||
1, normalize);
|
||||
|
||||
if (target)
|
||||
target = expand_simple_binop (GET_MODE (if_info->x),
|
||||
subtract ? MINUS : PLUS,
|
||||
if_info->x, target, if_info->x,
|
||||
0, OPTAB_WIDEN);
|
||||
if (target)
|
||||
{
|
||||
if (target != if_info->x)
|
||||
noce_emit_move_insn (if_info->x, target);
|
||||
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
|
||||
if (seq_contains_jump (seq))
|
||||
return FALSE;
|
||||
|
||||
emit_insn_before_scope (seq, if_info->jump,
|
||||
INSN_SCOPE (if_info->insn_a));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
end_sequence ();
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@ -1860,7 +1886,7 @@ noce_process_if_block (ce_info)
|
||||
{
|
||||
if (noce_try_store_flag_constants (&if_info))
|
||||
goto success;
|
||||
if (noce_try_store_flag_inc (&if_info))
|
||||
if (noce_try_addcc (&if_info))
|
||||
goto success;
|
||||
if (noce_try_store_flag_mask (&if_info))
|
||||
goto success;
|
||||
|
129
gcc/optabs.c
129
gcc/optabs.c
@ -4230,6 +4230,134 @@ can_conditionally_move_p (mode)
|
||||
}
|
||||
|
||||
#endif /* HAVE_conditional_move */
|
||||
|
||||
/* Emit a conditional addition instruction if the machine supports one for that
|
||||
condition and machine mode.
|
||||
|
||||
OP0 and OP1 are the operands that should be compared using CODE. CMODE is
|
||||
the mode to use should they be constants. If it is VOIDmode, they cannot
|
||||
both be constants.
|
||||
|
||||
OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
|
||||
should be stored there. MODE is the mode to use should they be constants.
|
||||
If it is VOIDmode, they cannot both be constants.
|
||||
|
||||
The result is either TARGET (perhaps modified) or NULL_RTX if the operation
|
||||
is not supported. */
|
||||
|
||||
rtx
|
||||
emit_conditional_add (target, code, op0, op1, cmode, op2, op3, mode,
|
||||
unsignedp)
|
||||
rtx target;
|
||||
enum rtx_code code;
|
||||
rtx op0, op1;
|
||||
enum machine_mode cmode;
|
||||
rtx op2, op3;
|
||||
enum machine_mode mode;
|
||||
int unsignedp;
|
||||
{
|
||||
rtx tem, subtarget, comparison, insn;
|
||||
enum insn_code icode;
|
||||
enum rtx_code reversed;
|
||||
|
||||
/* If one operand is constant, make it the second one. Only do this
|
||||
if the other operand is not constant as well. */
|
||||
|
||||
if (swap_commutative_operands_p (op0, op1))
|
||||
{
|
||||
tem = op0;
|
||||
op0 = op1;
|
||||
op1 = tem;
|
||||
code = swap_condition (code);
|
||||
}
|
||||
|
||||
/* get_condition will prefer to generate LT and GT even if the old
|
||||
comparison was against zero, so undo that canonicalization here since
|
||||
comparisons against zero are cheaper. */
|
||||
if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
|
||||
code = LE, op1 = const0_rtx;
|
||||
else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
|
||||
code = GE, op1 = const0_rtx;
|
||||
|
||||
if (cmode == VOIDmode)
|
||||
cmode = GET_MODE (op0);
|
||||
|
||||
if (swap_commutative_operands_p (op2, op3)
|
||||
&& ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
|
||||
!= UNKNOWN))
|
||||
{
|
||||
tem = op2;
|
||||
op2 = op3;
|
||||
op3 = tem;
|
||||
code = reversed;
|
||||
}
|
||||
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (op2);
|
||||
|
||||
icode = addcc_optab->handlers[(int) mode].insn_code;
|
||||
|
||||
if (icode == CODE_FOR_nothing)
|
||||
return 0;
|
||||
|
||||
if (flag_force_mem)
|
||||
{
|
||||
op2 = force_not_mem (op2);
|
||||
op3 = force_not_mem (op3);
|
||||
}
|
||||
|
||||
if (target)
|
||||
target = protect_from_queue (target, 1);
|
||||
else
|
||||
target = gen_reg_rtx (mode);
|
||||
|
||||
subtarget = target;
|
||||
|
||||
emit_queue ();
|
||||
|
||||
op2 = protect_from_queue (op2, 0);
|
||||
op3 = protect_from_queue (op3, 0);
|
||||
|
||||
/* If the insn doesn't accept these operands, put them in pseudos. */
|
||||
|
||||
if (! (*insn_data[icode].operand[0].predicate)
|
||||
(subtarget, insn_data[icode].operand[0].mode))
|
||||
subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
|
||||
|
||||
if (! (*insn_data[icode].operand[2].predicate)
|
||||
(op2, insn_data[icode].operand[2].mode))
|
||||
op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
|
||||
|
||||
if (! (*insn_data[icode].operand[3].predicate)
|
||||
(op3, insn_data[icode].operand[3].mode))
|
||||
op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
|
||||
|
||||
/* Everything should now be in the suitable form, so emit the compare insn
|
||||
and then the conditional move. */
|
||||
|
||||
comparison
|
||||
= compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
|
||||
|
||||
/* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
|
||||
/* We can get const0_rtx or const_true_rtx in some circumstances. Just
|
||||
return NULL and let the caller figure out how best to deal with this
|
||||
situation. */
|
||||
if (GET_CODE (comparison) != code)
|
||||
return NULL_RTX;
|
||||
|
||||
insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
|
||||
|
||||
/* If that failed, then give up. */
|
||||
if (insn == 0)
|
||||
return 0;
|
||||
|
||||
emit_insn (insn);
|
||||
|
||||
if (subtarget != target)
|
||||
convert_move (target, subtarget, 0);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
/* These functions generate an insn body and return it
|
||||
rather than emitting the insn.
|
||||
@ -5229,6 +5357,7 @@ init_optabs ()
|
||||
negv_optab = init_optabv (NEG);
|
||||
abs_optab = init_optab (ABS);
|
||||
absv_optab = init_optabv (ABS);
|
||||
addcc_optab = init_optab (UNKNOWN);
|
||||
one_cmpl_optab = init_optab (NOT);
|
||||
ffs_optab = init_optab (FFS);
|
||||
sqrt_optab = init_optab (SQRT);
|
||||
|
@ -160,6 +160,9 @@ enum optab_index
|
||||
/* Push instruction. */
|
||||
OTI_push,
|
||||
|
||||
/* Conditional add instruction. */
|
||||
OTI_addcc,
|
||||
|
||||
OTI_MAX
|
||||
};
|
||||
|
||||
@ -226,6 +229,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
|
||||
#define cmov_optab (optab_table[OTI_cmov])
|
||||
#define cstore_optab (optab_table[OTI_cstore])
|
||||
#define push_optab (optab_table[OTI_push])
|
||||
#define addcc_optab (optab_table[OTI_addcc])
|
||||
|
||||
/* Tables of patterns for extending one integer mode to another. */
|
||||
extern enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
|
||||
|
@ -7608,6 +7608,11 @@ delete_output_reload (insn, j, last_reload_reg)
|
||||
rtx i1;
|
||||
rtx substed;
|
||||
|
||||
/* It is possible that this reload has been only used to set another reload
|
||||
we eliminated earlier and thus deleted this instruction too. */
|
||||
if (INSN_DELETED_P (output_reload_insn))
|
||||
return;
|
||||
|
||||
/* Get the raw pseudo-register referred to. */
|
||||
|
||||
while (GET_CODE (reg) == SUBREG)
|
||||
|
Loading…
x
Reference in New Issue
Block a user