i386.c (bdesc_ptest): Removed.
2008-05-10 H.J. Lu <hongjiu.lu@intel.com> * config/i386/i386.c (bdesc_ptest): Removed. (ix86_builtin_type): Add INT_FTYPE_V2DI_V2DI_PTEST. (bdesc_args): Add __builtin_ia32_ptestz128, __builtin_ia32_ptestc128 and __builtin_ia32_ptestnzc128. (ix86_init_mmx_sse_builtins): Updated. (ix86_expand_args_builtin): Handle INT_FTYPE_V2DI_V2DI_PTEST. (ix86_expand_builtin): Updated. From-SVN: r135144
This commit is contained in:
parent
17d23165ff
commit
b282a8d3ec
@ -1,3 +1,13 @@
|
||||
2008-05-10 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* config/i386/i386.c (bdesc_ptest): Removed.
|
||||
(ix86_builtin_type): Add INT_FTYPE_V2DI_V2DI_PTEST.
|
||||
(bdesc_args): Add __builtin_ia32_ptestz128,
|
||||
__builtin_ia32_ptestc128 and __builtin_ia32_ptestnzc128.
|
||||
(ix86_init_mmx_sse_builtins): Updated.
|
||||
(ix86_expand_args_builtin): Handle INT_FTYPE_V2DI_V2DI_PTEST.
|
||||
(ix86_expand_builtin): Updated.
|
||||
|
||||
2008-05-10 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* tree-cfg.c (valid_fixed_convert_types_p): New function.
|
||||
|
@ -17989,14 +17989,6 @@ static const struct builtin_description bdesc_comi[] =
|
||||
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdneq", IX86_BUILTIN_UCOMINEQSD, LTGT, 0 },
|
||||
};
|
||||
|
||||
static const struct builtin_description bdesc_ptest[] =
|
||||
{
|
||||
/* SSE4.1 */
|
||||
{ OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestz128", IX86_BUILTIN_PTESTZ, EQ, 0 },
|
||||
{ OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestc128", IX86_BUILTIN_PTESTC, LTU, 0 },
|
||||
{ OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestnzc128", IX86_BUILTIN_PTESTNZC, GTU, 0 },
|
||||
};
|
||||
|
||||
static const struct builtin_description bdesc_pcmpestr[] =
|
||||
{
|
||||
/* SSE4.2 */
|
||||
@ -18048,6 +18040,7 @@ enum ix86_builtin_type
|
||||
FLOAT128_FTYPE_FLOAT128,
|
||||
FLOAT_FTYPE_FLOAT,
|
||||
FLOAT128_FTYPE_FLOAT128_FLOAT128,
|
||||
INT_FTYPE_V2DI_V2DI_PTEST,
|
||||
INT64_FTYPE_V4SF,
|
||||
INT64_FTYPE_V2DF,
|
||||
INT_FTYPE_V16QI,
|
||||
@ -18655,6 +18648,10 @@ static const struct builtin_description bdesc_args[] =
|
||||
{ OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundsd, "__builtin_ia32_roundsd", IX86_BUILTIN_ROUNDSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
|
||||
{ OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundss, "__builtin_ia32_roundss", IX86_BUILTIN_ROUNDSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
|
||||
|
||||
{ OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestz128", IX86_BUILTIN_PTESTZ, EQ, (int) INT_FTYPE_V2DI_V2DI_PTEST },
|
||||
{ OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestc128", IX86_BUILTIN_PTESTC, LTU, (int) INT_FTYPE_V2DI_V2DI_PTEST },
|
||||
{ OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestnzc128", IX86_BUILTIN_PTESTNZC, GTU, (int) INT_FTYPE_V2DI_V2DI_PTEST },
|
||||
|
||||
/* SSE4.2 */
|
||||
{ OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_gtv2di3, "__builtin_ia32_pcmpgtq", IX86_BUILTIN_PCMPGTQ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
|
||||
{ OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_crc32qi, "__builtin_ia32_crc32qi", IX86_BUILTIN_CRC32QI, UNKNOWN, (int) UINT_FTYPE_UINT_UCHAR },
|
||||
@ -19597,6 +19594,9 @@ ix86_init_mmx_sse_builtins (void)
|
||||
case FLOAT_FTYPE_FLOAT:
|
||||
type = float_ftype_float;
|
||||
break;
|
||||
case INT_FTYPE_V2DI_V2DI_PTEST:
|
||||
type = int_ftype_v2di_v2di;
|
||||
break;
|
||||
case INT64_FTYPE_V4SF:
|
||||
type = int64_ftype_v4sf;
|
||||
break;
|
||||
@ -19935,10 +19935,6 @@ ix86_init_mmx_sse_builtins (void)
|
||||
else
|
||||
def_builtin_const (d->mask, d->name, int_ftype_v4sf_v4sf, d->code);
|
||||
|
||||
/* ptest insns. */
|
||||
for (i = 0, d = bdesc_ptest; i < ARRAY_SIZE (bdesc_ptest); i++, d++)
|
||||
def_builtin_const (d->mask, d->name, int_ftype_v2di_v2di, d->code);
|
||||
|
||||
/* SSE */
|
||||
def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_ldmxcsr", void_ftype_unsigned, IX86_BUILTIN_LDMXCSR);
|
||||
def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_stmxcsr", unsigned_ftype_void, IX86_BUILTIN_STMXCSR);
|
||||
@ -20451,6 +20447,302 @@ ix86_expand_sse_compare (const struct builtin_description *d,
|
||||
return target;
|
||||
}
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of comi insns. */
|
||||
|
||||
static rtx
|
||||
ix86_expand_sse_comi (const struct builtin_description *d, tree exp,
|
||||
rtx target)
|
||||
{
|
||||
rtx pat;
|
||||
tree arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
tree arg1 = CALL_EXPR_ARG (exp, 1);
|
||||
rtx op0 = expand_normal (arg0);
|
||||
rtx op1 = expand_normal (arg1);
|
||||
enum machine_mode mode0 = insn_data[d->icode].operand[0].mode;
|
||||
enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
|
||||
enum rtx_code comparison = d->comparison;
|
||||
|
||||
if (VECTOR_MODE_P (mode0))
|
||||
op0 = safe_vector_operand (op0, mode0);
|
||||
if (VECTOR_MODE_P (mode1))
|
||||
op1 = safe_vector_operand (op1, mode1);
|
||||
|
||||
/* Swap operands if we have a comparison that isn't available in
|
||||
hardware. */
|
||||
if (d->flag & BUILTIN_DESC_SWAP_OPERANDS)
|
||||
{
|
||||
rtx tmp = op1;
|
||||
op1 = op0;
|
||||
op0 = tmp;
|
||||
}
|
||||
|
||||
target = gen_reg_rtx (SImode);
|
||||
emit_move_insn (target, const0_rtx);
|
||||
target = gen_rtx_SUBREG (QImode, target, 0);
|
||||
|
||||
if ((optimize && !register_operand (op0, mode0))
|
||||
|| !(*insn_data[d->icode].operand[0].predicate) (op0, mode0))
|
||||
op0 = copy_to_mode_reg (mode0, op0);
|
||||
if ((optimize && !register_operand (op1, mode1))
|
||||
|| !(*insn_data[d->icode].operand[1].predicate) (op1, mode1))
|
||||
op1 = copy_to_mode_reg (mode1, op1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (op0, op1);
|
||||
if (! pat)
|
||||
return 0;
|
||||
emit_insn (pat);
|
||||
emit_insn (gen_rtx_SET (VOIDmode,
|
||||
gen_rtx_STRICT_LOW_PART (VOIDmode, target),
|
||||
gen_rtx_fmt_ee (comparison, QImode,
|
||||
SET_DEST (pat),
|
||||
const0_rtx)));
|
||||
|
||||
return SUBREG_REG (target);
|
||||
}
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of ptest insns. */
|
||||
|
||||
static rtx
|
||||
ix86_expand_sse_ptest (const struct builtin_description *d, tree exp,
|
||||
rtx target)
|
||||
{
|
||||
rtx pat;
|
||||
tree arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
tree arg1 = CALL_EXPR_ARG (exp, 1);
|
||||
rtx op0 = expand_normal (arg0);
|
||||
rtx op1 = expand_normal (arg1);
|
||||
enum machine_mode mode0 = insn_data[d->icode].operand[0].mode;
|
||||
enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
|
||||
enum rtx_code comparison = d->comparison;
|
||||
|
||||
if (VECTOR_MODE_P (mode0))
|
||||
op0 = safe_vector_operand (op0, mode0);
|
||||
if (VECTOR_MODE_P (mode1))
|
||||
op1 = safe_vector_operand (op1, mode1);
|
||||
|
||||
target = gen_reg_rtx (SImode);
|
||||
emit_move_insn (target, const0_rtx);
|
||||
target = gen_rtx_SUBREG (QImode, target, 0);
|
||||
|
||||
if ((optimize && !register_operand (op0, mode0))
|
||||
|| !(*insn_data[d->icode].operand[0].predicate) (op0, mode0))
|
||||
op0 = copy_to_mode_reg (mode0, op0);
|
||||
if ((optimize && !register_operand (op1, mode1))
|
||||
|| !(*insn_data[d->icode].operand[1].predicate) (op1, mode1))
|
||||
op1 = copy_to_mode_reg (mode1, op1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (op0, op1);
|
||||
if (! pat)
|
||||
return 0;
|
||||
emit_insn (pat);
|
||||
emit_insn (gen_rtx_SET (VOIDmode,
|
||||
gen_rtx_STRICT_LOW_PART (VOIDmode, target),
|
||||
gen_rtx_fmt_ee (comparison, QImode,
|
||||
SET_DEST (pat),
|
||||
const0_rtx)));
|
||||
|
||||
return SUBREG_REG (target);
|
||||
}
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of pcmpestr[im] insns. */
|
||||
|
||||
static rtx
|
||||
ix86_expand_sse_pcmpestr (const struct builtin_description *d,
|
||||
tree exp, rtx target)
|
||||
{
|
||||
rtx pat;
|
||||
tree arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
tree arg1 = CALL_EXPR_ARG (exp, 1);
|
||||
tree arg2 = CALL_EXPR_ARG (exp, 2);
|
||||
tree arg3 = CALL_EXPR_ARG (exp, 3);
|
||||
tree arg4 = CALL_EXPR_ARG (exp, 4);
|
||||
rtx scratch0, scratch1;
|
||||
rtx op0 = expand_normal (arg0);
|
||||
rtx op1 = expand_normal (arg1);
|
||||
rtx op2 = expand_normal (arg2);
|
||||
rtx op3 = expand_normal (arg3);
|
||||
rtx op4 = expand_normal (arg4);
|
||||
enum machine_mode tmode0, tmode1, modev2, modei3, modev4, modei5, modeimm;
|
||||
|
||||
tmode0 = insn_data[d->icode].operand[0].mode;
|
||||
tmode1 = insn_data[d->icode].operand[1].mode;
|
||||
modev2 = insn_data[d->icode].operand[2].mode;
|
||||
modei3 = insn_data[d->icode].operand[3].mode;
|
||||
modev4 = insn_data[d->icode].operand[4].mode;
|
||||
modei5 = insn_data[d->icode].operand[5].mode;
|
||||
modeimm = insn_data[d->icode].operand[6].mode;
|
||||
|
||||
if (VECTOR_MODE_P (modev2))
|
||||
op0 = safe_vector_operand (op0, modev2);
|
||||
if (VECTOR_MODE_P (modev4))
|
||||
op2 = safe_vector_operand (op2, modev4);
|
||||
|
||||
if (! (*insn_data[d->icode].operand[2].predicate) (op0, modev2))
|
||||
op0 = copy_to_mode_reg (modev2, op0);
|
||||
if (! (*insn_data[d->icode].operand[3].predicate) (op1, modei3))
|
||||
op1 = copy_to_mode_reg (modei3, op1);
|
||||
if ((optimize && !register_operand (op2, modev4))
|
||||
|| !(*insn_data[d->icode].operand[4].predicate) (op2, modev4))
|
||||
op2 = copy_to_mode_reg (modev4, op2);
|
||||
if (! (*insn_data[d->icode].operand[5].predicate) (op3, modei5))
|
||||
op3 = copy_to_mode_reg (modei5, op3);
|
||||
|
||||
if (! (*insn_data[d->icode].operand[6].predicate) (op4, modeimm))
|
||||
{
|
||||
error ("the fifth argument must be a 8-bit immediate");
|
||||
return const0_rtx;
|
||||
}
|
||||
|
||||
if (d->code == IX86_BUILTIN_PCMPESTRI128)
|
||||
{
|
||||
if (optimize || !target
|
||||
|| GET_MODE (target) != tmode0
|
||||
|| ! (*insn_data[d->icode].operand[0].predicate) (target, tmode0))
|
||||
target = gen_reg_rtx (tmode0);
|
||||
|
||||
scratch1 = gen_reg_rtx (tmode1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (target, scratch1, op0, op1, op2, op3, op4);
|
||||
}
|
||||
else if (d->code == IX86_BUILTIN_PCMPESTRM128)
|
||||
{
|
||||
if (optimize || !target
|
||||
|| GET_MODE (target) != tmode1
|
||||
|| ! (*insn_data[d->icode].operand[1].predicate) (target, tmode1))
|
||||
target = gen_reg_rtx (tmode1);
|
||||
|
||||
scratch0 = gen_reg_rtx (tmode0);
|
||||
|
||||
pat = GEN_FCN (d->icode) (scratch0, target, op0, op1, op2, op3, op4);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (d->flag);
|
||||
|
||||
scratch0 = gen_reg_rtx (tmode0);
|
||||
scratch1 = gen_reg_rtx (tmode1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (scratch0, scratch1, op0, op1, op2, op3, op4);
|
||||
}
|
||||
|
||||
if (! pat)
|
||||
return 0;
|
||||
|
||||
emit_insn (pat);
|
||||
|
||||
if (d->flag)
|
||||
{
|
||||
target = gen_reg_rtx (SImode);
|
||||
emit_move_insn (target, const0_rtx);
|
||||
target = gen_rtx_SUBREG (QImode, target, 0);
|
||||
|
||||
emit_insn
|
||||
(gen_rtx_SET (VOIDmode, gen_rtx_STRICT_LOW_PART (VOIDmode, target),
|
||||
gen_rtx_fmt_ee (EQ, QImode,
|
||||
gen_rtx_REG ((enum machine_mode) d->flag,
|
||||
FLAGS_REG),
|
||||
const0_rtx)));
|
||||
return SUBREG_REG (target);
|
||||
}
|
||||
else
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of pcmpistr[im] insns. */
|
||||
|
||||
static rtx
|
||||
ix86_expand_sse_pcmpistr (const struct builtin_description *d,
|
||||
tree exp, rtx target)
|
||||
{
|
||||
rtx pat;
|
||||
tree arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
tree arg1 = CALL_EXPR_ARG (exp, 1);
|
||||
tree arg2 = CALL_EXPR_ARG (exp, 2);
|
||||
rtx scratch0, scratch1;
|
||||
rtx op0 = expand_normal (arg0);
|
||||
rtx op1 = expand_normal (arg1);
|
||||
rtx op2 = expand_normal (arg2);
|
||||
enum machine_mode tmode0, tmode1, modev2, modev3, modeimm;
|
||||
|
||||
tmode0 = insn_data[d->icode].operand[0].mode;
|
||||
tmode1 = insn_data[d->icode].operand[1].mode;
|
||||
modev2 = insn_data[d->icode].operand[2].mode;
|
||||
modev3 = insn_data[d->icode].operand[3].mode;
|
||||
modeimm = insn_data[d->icode].operand[4].mode;
|
||||
|
||||
if (VECTOR_MODE_P (modev2))
|
||||
op0 = safe_vector_operand (op0, modev2);
|
||||
if (VECTOR_MODE_P (modev3))
|
||||
op1 = safe_vector_operand (op1, modev3);
|
||||
|
||||
if (! (*insn_data[d->icode].operand[2].predicate) (op0, modev2))
|
||||
op0 = copy_to_mode_reg (modev2, op0);
|
||||
if ((optimize && !register_operand (op1, modev3))
|
||||
|| !(*insn_data[d->icode].operand[3].predicate) (op1, modev3))
|
||||
op1 = copy_to_mode_reg (modev3, op1);
|
||||
|
||||
if (! (*insn_data[d->icode].operand[4].predicate) (op2, modeimm))
|
||||
{
|
||||
error ("the third argument must be a 8-bit immediate");
|
||||
return const0_rtx;
|
||||
}
|
||||
|
||||
if (d->code == IX86_BUILTIN_PCMPISTRI128)
|
||||
{
|
||||
if (optimize || !target
|
||||
|| GET_MODE (target) != tmode0
|
||||
|| ! (*insn_data[d->icode].operand[0].predicate) (target, tmode0))
|
||||
target = gen_reg_rtx (tmode0);
|
||||
|
||||
scratch1 = gen_reg_rtx (tmode1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (target, scratch1, op0, op1, op2);
|
||||
}
|
||||
else if (d->code == IX86_BUILTIN_PCMPISTRM128)
|
||||
{
|
||||
if (optimize || !target
|
||||
|| GET_MODE (target) != tmode1
|
||||
|| ! (*insn_data[d->icode].operand[1].predicate) (target, tmode1))
|
||||
target = gen_reg_rtx (tmode1);
|
||||
|
||||
scratch0 = gen_reg_rtx (tmode0);
|
||||
|
||||
pat = GEN_FCN (d->icode) (scratch0, target, op0, op1, op2);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (d->flag);
|
||||
|
||||
scratch0 = gen_reg_rtx (tmode0);
|
||||
scratch1 = gen_reg_rtx (tmode1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (scratch0, scratch1, op0, op1, op2);
|
||||
}
|
||||
|
||||
if (! pat)
|
||||
return 0;
|
||||
|
||||
emit_insn (pat);
|
||||
|
||||
if (d->flag)
|
||||
{
|
||||
target = gen_reg_rtx (SImode);
|
||||
emit_move_insn (target, const0_rtx);
|
||||
target = gen_rtx_SUBREG (QImode, target, 0);
|
||||
|
||||
emit_insn
|
||||
(gen_rtx_SET (VOIDmode, gen_rtx_STRICT_LOW_PART (VOIDmode, target),
|
||||
gen_rtx_fmt_ee (EQ, QImode,
|
||||
gen_rtx_REG ((enum machine_mode) d->flag,
|
||||
FLAGS_REG),
|
||||
const0_rtx)));
|
||||
return SUBREG_REG (target);
|
||||
}
|
||||
else
|
||||
return target;
|
||||
}
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of insns with
|
||||
variable number of operands. */
|
||||
|
||||
@ -20477,6 +20769,8 @@ ix86_expand_args_builtin (const struct builtin_description *d,
|
||||
|
||||
switch ((enum ix86_builtin_type) d->flag)
|
||||
{
|
||||
case INT_FTYPE_V2DI_V2DI_PTEST:
|
||||
return ix86_expand_sse_ptest (d, exp, target);
|
||||
case FLOAT128_FTYPE_FLOAT128:
|
||||
case FLOAT_FTYPE_FLOAT:
|
||||
case INT64_FTYPE_V4SF:
|
||||
@ -20902,302 +21196,6 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
|
||||
return class == store ? 0 : target;
|
||||
}
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of comi insns. */
|
||||
|
||||
static rtx
|
||||
ix86_expand_sse_comi (const struct builtin_description *d, tree exp,
|
||||
rtx target)
|
||||
{
|
||||
rtx pat;
|
||||
tree arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
tree arg1 = CALL_EXPR_ARG (exp, 1);
|
||||
rtx op0 = expand_normal (arg0);
|
||||
rtx op1 = expand_normal (arg1);
|
||||
enum machine_mode mode0 = insn_data[d->icode].operand[0].mode;
|
||||
enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
|
||||
enum rtx_code comparison = d->comparison;
|
||||
|
||||
if (VECTOR_MODE_P (mode0))
|
||||
op0 = safe_vector_operand (op0, mode0);
|
||||
if (VECTOR_MODE_P (mode1))
|
||||
op1 = safe_vector_operand (op1, mode1);
|
||||
|
||||
/* Swap operands if we have a comparison that isn't available in
|
||||
hardware. */
|
||||
if (d->flag & BUILTIN_DESC_SWAP_OPERANDS)
|
||||
{
|
||||
rtx tmp = op1;
|
||||
op1 = op0;
|
||||
op0 = tmp;
|
||||
}
|
||||
|
||||
target = gen_reg_rtx (SImode);
|
||||
emit_move_insn (target, const0_rtx);
|
||||
target = gen_rtx_SUBREG (QImode, target, 0);
|
||||
|
||||
if ((optimize && !register_operand (op0, mode0))
|
||||
|| !(*insn_data[d->icode].operand[0].predicate) (op0, mode0))
|
||||
op0 = copy_to_mode_reg (mode0, op0);
|
||||
if ((optimize && !register_operand (op1, mode1))
|
||||
|| !(*insn_data[d->icode].operand[1].predicate) (op1, mode1))
|
||||
op1 = copy_to_mode_reg (mode1, op1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (op0, op1);
|
||||
if (! pat)
|
||||
return 0;
|
||||
emit_insn (pat);
|
||||
emit_insn (gen_rtx_SET (VOIDmode,
|
||||
gen_rtx_STRICT_LOW_PART (VOIDmode, target),
|
||||
gen_rtx_fmt_ee (comparison, QImode,
|
||||
SET_DEST (pat),
|
||||
const0_rtx)));
|
||||
|
||||
return SUBREG_REG (target);
|
||||
}
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of ptest insns. */
|
||||
|
||||
static rtx
|
||||
ix86_expand_sse_ptest (const struct builtin_description *d, tree exp,
|
||||
rtx target)
|
||||
{
|
||||
rtx pat;
|
||||
tree arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
tree arg1 = CALL_EXPR_ARG (exp, 1);
|
||||
rtx op0 = expand_normal (arg0);
|
||||
rtx op1 = expand_normal (arg1);
|
||||
enum machine_mode mode0 = insn_data[d->icode].operand[0].mode;
|
||||
enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
|
||||
enum rtx_code comparison = d->comparison;
|
||||
|
||||
if (VECTOR_MODE_P (mode0))
|
||||
op0 = safe_vector_operand (op0, mode0);
|
||||
if (VECTOR_MODE_P (mode1))
|
||||
op1 = safe_vector_operand (op1, mode1);
|
||||
|
||||
target = gen_reg_rtx (SImode);
|
||||
emit_move_insn (target, const0_rtx);
|
||||
target = gen_rtx_SUBREG (QImode, target, 0);
|
||||
|
||||
if ((optimize && !register_operand (op0, mode0))
|
||||
|| !(*insn_data[d->icode].operand[0].predicate) (op0, mode0))
|
||||
op0 = copy_to_mode_reg (mode0, op0);
|
||||
if ((optimize && !register_operand (op1, mode1))
|
||||
|| !(*insn_data[d->icode].operand[1].predicate) (op1, mode1))
|
||||
op1 = copy_to_mode_reg (mode1, op1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (op0, op1);
|
||||
if (! pat)
|
||||
return 0;
|
||||
emit_insn (pat);
|
||||
emit_insn (gen_rtx_SET (VOIDmode,
|
||||
gen_rtx_STRICT_LOW_PART (VOIDmode, target),
|
||||
gen_rtx_fmt_ee (comparison, QImode,
|
||||
SET_DEST (pat),
|
||||
const0_rtx)));
|
||||
|
||||
return SUBREG_REG (target);
|
||||
}
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of pcmpestr[im] insns. */
|
||||
|
||||
static rtx
|
||||
ix86_expand_sse_pcmpestr (const struct builtin_description *d,
|
||||
tree exp, rtx target)
|
||||
{
|
||||
rtx pat;
|
||||
tree arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
tree arg1 = CALL_EXPR_ARG (exp, 1);
|
||||
tree arg2 = CALL_EXPR_ARG (exp, 2);
|
||||
tree arg3 = CALL_EXPR_ARG (exp, 3);
|
||||
tree arg4 = CALL_EXPR_ARG (exp, 4);
|
||||
rtx scratch0, scratch1;
|
||||
rtx op0 = expand_normal (arg0);
|
||||
rtx op1 = expand_normal (arg1);
|
||||
rtx op2 = expand_normal (arg2);
|
||||
rtx op3 = expand_normal (arg3);
|
||||
rtx op4 = expand_normal (arg4);
|
||||
enum machine_mode tmode0, tmode1, modev2, modei3, modev4, modei5, modeimm;
|
||||
|
||||
tmode0 = insn_data[d->icode].operand[0].mode;
|
||||
tmode1 = insn_data[d->icode].operand[1].mode;
|
||||
modev2 = insn_data[d->icode].operand[2].mode;
|
||||
modei3 = insn_data[d->icode].operand[3].mode;
|
||||
modev4 = insn_data[d->icode].operand[4].mode;
|
||||
modei5 = insn_data[d->icode].operand[5].mode;
|
||||
modeimm = insn_data[d->icode].operand[6].mode;
|
||||
|
||||
if (VECTOR_MODE_P (modev2))
|
||||
op0 = safe_vector_operand (op0, modev2);
|
||||
if (VECTOR_MODE_P (modev4))
|
||||
op2 = safe_vector_operand (op2, modev4);
|
||||
|
||||
if (! (*insn_data[d->icode].operand[2].predicate) (op0, modev2))
|
||||
op0 = copy_to_mode_reg (modev2, op0);
|
||||
if (! (*insn_data[d->icode].operand[3].predicate) (op1, modei3))
|
||||
op1 = copy_to_mode_reg (modei3, op1);
|
||||
if ((optimize && !register_operand (op2, modev4))
|
||||
|| !(*insn_data[d->icode].operand[4].predicate) (op2, modev4))
|
||||
op2 = copy_to_mode_reg (modev4, op2);
|
||||
if (! (*insn_data[d->icode].operand[5].predicate) (op3, modei5))
|
||||
op3 = copy_to_mode_reg (modei5, op3);
|
||||
|
||||
if (! (*insn_data[d->icode].operand[6].predicate) (op4, modeimm))
|
||||
{
|
||||
error ("the fifth argument must be a 8-bit immediate");
|
||||
return const0_rtx;
|
||||
}
|
||||
|
||||
if (d->code == IX86_BUILTIN_PCMPESTRI128)
|
||||
{
|
||||
if (optimize || !target
|
||||
|| GET_MODE (target) != tmode0
|
||||
|| ! (*insn_data[d->icode].operand[0].predicate) (target, tmode0))
|
||||
target = gen_reg_rtx (tmode0);
|
||||
|
||||
scratch1 = gen_reg_rtx (tmode1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (target, scratch1, op0, op1, op2, op3, op4);
|
||||
}
|
||||
else if (d->code == IX86_BUILTIN_PCMPESTRM128)
|
||||
{
|
||||
if (optimize || !target
|
||||
|| GET_MODE (target) != tmode1
|
||||
|| ! (*insn_data[d->icode].operand[1].predicate) (target, tmode1))
|
||||
target = gen_reg_rtx (tmode1);
|
||||
|
||||
scratch0 = gen_reg_rtx (tmode0);
|
||||
|
||||
pat = GEN_FCN (d->icode) (scratch0, target, op0, op1, op2, op3, op4);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (d->flag);
|
||||
|
||||
scratch0 = gen_reg_rtx (tmode0);
|
||||
scratch1 = gen_reg_rtx (tmode1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (scratch0, scratch1, op0, op1, op2, op3, op4);
|
||||
}
|
||||
|
||||
if (! pat)
|
||||
return 0;
|
||||
|
||||
emit_insn (pat);
|
||||
|
||||
if (d->flag)
|
||||
{
|
||||
target = gen_reg_rtx (SImode);
|
||||
emit_move_insn (target, const0_rtx);
|
||||
target = gen_rtx_SUBREG (QImode, target, 0);
|
||||
|
||||
emit_insn
|
||||
(gen_rtx_SET (VOIDmode, gen_rtx_STRICT_LOW_PART (VOIDmode, target),
|
||||
gen_rtx_fmt_ee (EQ, QImode,
|
||||
gen_rtx_REG ((enum machine_mode) d->flag,
|
||||
FLAGS_REG),
|
||||
const0_rtx)));
|
||||
return SUBREG_REG (target);
|
||||
}
|
||||
else
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
/* Subroutine of ix86_expand_builtin to take care of pcmpistr[im] insns. */
|
||||
|
||||
static rtx
|
||||
ix86_expand_sse_pcmpistr (const struct builtin_description *d,
|
||||
tree exp, rtx target)
|
||||
{
|
||||
rtx pat;
|
||||
tree arg0 = CALL_EXPR_ARG (exp, 0);
|
||||
tree arg1 = CALL_EXPR_ARG (exp, 1);
|
||||
tree arg2 = CALL_EXPR_ARG (exp, 2);
|
||||
rtx scratch0, scratch1;
|
||||
rtx op0 = expand_normal (arg0);
|
||||
rtx op1 = expand_normal (arg1);
|
||||
rtx op2 = expand_normal (arg2);
|
||||
enum machine_mode tmode0, tmode1, modev2, modev3, modeimm;
|
||||
|
||||
tmode0 = insn_data[d->icode].operand[0].mode;
|
||||
tmode1 = insn_data[d->icode].operand[1].mode;
|
||||
modev2 = insn_data[d->icode].operand[2].mode;
|
||||
modev3 = insn_data[d->icode].operand[3].mode;
|
||||
modeimm = insn_data[d->icode].operand[4].mode;
|
||||
|
||||
if (VECTOR_MODE_P (modev2))
|
||||
op0 = safe_vector_operand (op0, modev2);
|
||||
if (VECTOR_MODE_P (modev3))
|
||||
op1 = safe_vector_operand (op1, modev3);
|
||||
|
||||
if (! (*insn_data[d->icode].operand[2].predicate) (op0, modev2))
|
||||
op0 = copy_to_mode_reg (modev2, op0);
|
||||
if ((optimize && !register_operand (op1, modev3))
|
||||
|| !(*insn_data[d->icode].operand[3].predicate) (op1, modev3))
|
||||
op1 = copy_to_mode_reg (modev3, op1);
|
||||
|
||||
if (! (*insn_data[d->icode].operand[4].predicate) (op2, modeimm))
|
||||
{
|
||||
error ("the third argument must be a 8-bit immediate");
|
||||
return const0_rtx;
|
||||
}
|
||||
|
||||
if (d->code == IX86_BUILTIN_PCMPISTRI128)
|
||||
{
|
||||
if (optimize || !target
|
||||
|| GET_MODE (target) != tmode0
|
||||
|| ! (*insn_data[d->icode].operand[0].predicate) (target, tmode0))
|
||||
target = gen_reg_rtx (tmode0);
|
||||
|
||||
scratch1 = gen_reg_rtx (tmode1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (target, scratch1, op0, op1, op2);
|
||||
}
|
||||
else if (d->code == IX86_BUILTIN_PCMPISTRM128)
|
||||
{
|
||||
if (optimize || !target
|
||||
|| GET_MODE (target) != tmode1
|
||||
|| ! (*insn_data[d->icode].operand[1].predicate) (target, tmode1))
|
||||
target = gen_reg_rtx (tmode1);
|
||||
|
||||
scratch0 = gen_reg_rtx (tmode0);
|
||||
|
||||
pat = GEN_FCN (d->icode) (scratch0, target, op0, op1, op2);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (d->flag);
|
||||
|
||||
scratch0 = gen_reg_rtx (tmode0);
|
||||
scratch1 = gen_reg_rtx (tmode1);
|
||||
|
||||
pat = GEN_FCN (d->icode) (scratch0, scratch1, op0, op1, op2);
|
||||
}
|
||||
|
||||
if (! pat)
|
||||
return 0;
|
||||
|
||||
emit_insn (pat);
|
||||
|
||||
if (d->flag)
|
||||
{
|
||||
target = gen_reg_rtx (SImode);
|
||||
emit_move_insn (target, const0_rtx);
|
||||
target = gen_rtx_SUBREG (QImode, target, 0);
|
||||
|
||||
emit_insn
|
||||
(gen_rtx_SET (VOIDmode, gen_rtx_STRICT_LOW_PART (VOIDmode, target),
|
||||
gen_rtx_fmt_ee (EQ, QImode,
|
||||
gen_rtx_REG ((enum machine_mode) d->flag,
|
||||
FLAGS_REG),
|
||||
const0_rtx)));
|
||||
return SUBREG_REG (target);
|
||||
}
|
||||
else
|
||||
return target;
|
||||
}
|
||||
|
||||
/* Return the integer constant in ARG. Constrain it to be in the range
|
||||
of the subparts of VEC_TYPE; issue an error if not. */
|
||||
|
||||
@ -21486,10 +21484,6 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
|
||||
if (d->code == fcode)
|
||||
return ix86_expand_sse_comi (d, exp, target);
|
||||
|
||||
for (i = 0, d = bdesc_ptest; i < ARRAY_SIZE (bdesc_ptest); i++, d++)
|
||||
if (d->code == fcode)
|
||||
return ix86_expand_sse_ptest (d, exp, target);
|
||||
|
||||
for (i = 0, d = bdesc_pcmpestr;
|
||||
i < ARRAY_SIZE (bdesc_pcmpestr);
|
||||
i++, d++)
|
||||
|
Loading…
Reference in New Issue
Block a user