aarch64.c (aarch64_code_to_ccmode, [...]): New functions.
2014-11-17 Zhenqiang Chen <zhenqiang.chen@linaro.org> * config/aarch64/aarch64.c (aarch64_code_to_ccmode, aarch64_convert_mode, aarch64_gen_ccmp_first, aarch64_gen_ccmp_next): New functions. (TARGET_GEN_CCMP_FIRST, TARGET_GEN_CCMP_NEXT): Define. From-SVN: r217645
This commit is contained in:
parent
cf67050334
commit
7dd236702d
|
@ -1,3 +1,10 @@
|
|||
2014-11-17 Zhenqiang Chen <zhenqiang.chen@linaro.org>
|
||||
|
||||
* config/aarch64/aarch64.c (aarch64_code_to_ccmode,
|
||||
aarch64_convert_mode, aarch64_gen_ccmp_first,
|
||||
aarch64_gen_ccmp_next): New functions.
|
||||
(TARGET_GEN_CCMP_FIRST, TARGET_GEN_CCMP_NEXT): Define.
|
||||
|
||||
2014-11-17 Zhenqiang Chen <zhenqiang.chen@linaro.org>
|
||||
|
||||
* config/aarch64/aarch64-protos.h (aarch64_ccmp_mode_to_code): New.
|
||||
|
|
|
@ -10211,6 +10211,144 @@ aarch64_use_by_pieces_infrastructure_p (unsigned int size,
|
|||
return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
|
||||
}
|
||||
|
||||
static enum machine_mode
|
||||
aarch64_code_to_ccmode (enum rtx_code code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case NE:
|
||||
return CC_DNEmode;
|
||||
|
||||
case EQ:
|
||||
return CC_DEQmode;
|
||||
|
||||
case LE:
|
||||
return CC_DLEmode;
|
||||
|
||||
case LT:
|
||||
return CC_DLTmode;
|
||||
|
||||
case GE:
|
||||
return CC_DGEmode;
|
||||
|
||||
case GT:
|
||||
return CC_DGTmode;
|
||||
|
||||
case LEU:
|
||||
return CC_DLEUmode;
|
||||
|
||||
case LTU:
|
||||
return CC_DLTUmode;
|
||||
|
||||
case GEU:
|
||||
return CC_DGEUmode;
|
||||
|
||||
case GTU:
|
||||
return CC_DGTUmode;
|
||||
|
||||
default:
|
||||
return CCmode;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
aarch64_convert_mode (rtx* op0, rtx* op1, int unsignedp)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
|
||||
mode = GET_MODE (*op0);
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (*op1);
|
||||
|
||||
if (mode == QImode || mode == HImode)
|
||||
{
|
||||
*op0 = convert_modes (SImode, mode, *op0, unsignedp);
|
||||
*op1 = convert_modes (SImode, mode, *op1, unsignedp);
|
||||
}
|
||||
else if (mode != SImode && mode != DImode)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static rtx
|
||||
aarch64_gen_ccmp_first (int code, rtx op0, rtx op1)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
rtx cmp, target;
|
||||
int unsignedp = code == LTU || code == LEU || code == GTU || code == GEU;
|
||||
|
||||
mode = GET_MODE (op0);
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (op1);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
return NULL_RTX;
|
||||
|
||||
if (!register_operand (op0, GET_MODE (op0)))
|
||||
op0 = force_reg (mode, op0);
|
||||
if (!aarch64_plus_operand (op1, GET_MODE (op1)))
|
||||
op1 = force_reg (mode, op1);
|
||||
|
||||
if (!aarch64_convert_mode (&op0, &op1, unsignedp))
|
||||
return NULL_RTX;
|
||||
|
||||
mode = aarch64_code_to_ccmode ((enum rtx_code) code);
|
||||
if (mode == CCmode)
|
||||
return NULL_RTX;
|
||||
|
||||
cmp = gen_rtx_fmt_ee (COMPARE, CCmode, op0, op1);
|
||||
target = gen_rtx_REG (mode, CC_REGNUM);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), cmp));
|
||||
return target;
|
||||
}
|
||||
|
||||
static rtx
|
||||
aarch64_gen_ccmp_next (rtx prev, int cmp_code, rtx op0, rtx op1, int bit_code)
|
||||
{
|
||||
rtx cmp0, cmp1, target, bit_op;
|
||||
enum machine_mode mode;
|
||||
int unsignedp = cmp_code == LTU || cmp_code == LEU
|
||||
|| cmp_code == GTU || cmp_code == GEU;
|
||||
|
||||
mode = GET_MODE (op0);
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (op1);
|
||||
if (mode == VOIDmode)
|
||||
return NULL_RTX;
|
||||
|
||||
/* Give up if the operand is illegal since force_reg will introduce
|
||||
additional overhead. */
|
||||
if (!register_operand (op0, GET_MODE (op0))
|
||||
|| !aarch64_ccmp_operand (op1, GET_MODE (op1)))
|
||||
return NULL_RTX;
|
||||
|
||||
if (!aarch64_convert_mode (&op0, &op1, unsignedp))
|
||||
return NULL_RTX;
|
||||
|
||||
mode = aarch64_code_to_ccmode ((enum rtx_code) cmp_code);
|
||||
if (mode == CCmode)
|
||||
return NULL_RTX;
|
||||
|
||||
cmp1 = gen_rtx_fmt_ee ((enum rtx_code) cmp_code, SImode, op0, op1);
|
||||
cmp0 = gen_rtx_fmt_ee (NE, SImode, prev, const0_rtx);
|
||||
|
||||
bit_op = gen_rtx_fmt_ee ((enum rtx_code) bit_code, SImode, cmp0, cmp1);
|
||||
|
||||
/* Generate insn to match ccmp_and/ccmp_ior. */
|
||||
target = gen_rtx_REG (mode, CC_REGNUM);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target,
|
||||
gen_rtx_fmt_ee (COMPARE, mode,
|
||||
bit_op, const0_rtx)));
|
||||
return target;
|
||||
}
|
||||
|
||||
#undef TARGET_GEN_CCMP_FIRST
|
||||
#define TARGET_GEN_CCMP_FIRST aarch64_gen_ccmp_first
|
||||
|
||||
#undef TARGET_GEN_CCMP_NEXT
|
||||
#define TARGET_GEN_CCMP_NEXT aarch64_gen_ccmp_next
|
||||
|
||||
#undef TARGET_ADDRESS_COST
|
||||
#define TARGET_ADDRESS_COST aarch64_address_cost
|
||||
|
||||
|
|
Loading…
Reference in New Issue