This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ping] [PATCH, 9/10] aarch64: generate conditional compare instructions


Ping?

Patch is attached for easy to apply.

Bootstrap on AARCH64 qemu.
Test cases: test_frame_*.c need update after the patch.

Thanks!
-Zhenqiang

> -----Original Message-----
> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
> owner@gcc.gnu.org] On Behalf Of Zhenqiang Chen
> Sent: Monday, June 23, 2014 3:01 PM
> To: gcc-patches@gcc.gnu.org
> Subject: [PATCH, 9/10] aarch64: generate conditional compare instructions
> 
> Hi,
> 
> The patches implements the two hooks for AARCH64 to generate ccmp
> instructions.
> 
> Bootstrap and no make check regression on qemu.
> 
> OK for trunk?
> 
> Thanks!
> -Zhenqiang
> 
> ChangeLog:
> 2014-06-23  Zhenqiang Chen  <zhenqiang.chen@linaro.org>
> 
>         * config/aarch64/aarch64.c (aarch64_code_to_ccmode): New function.
>         (aarch64_convert_mode, aarch64_convert_mode): New functions.
>         (aarch64_gen_ccmp_first, aarch64_gen_ccmp_next): New functions.
>         (TARGET_GEN_CCMP_FIRST, TARGET_GEN_CCMP_NEXT): Define the
> two hooks.
> 
> 
> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
> index 4e8d55b..6f08e38 100644
> --- a/gcc/config/aarch64/aarch64.c
> +++ b/gcc/config/aarch64/aarch64.c
> @@ -9601,6 +9601,137 @@ aarch64_uimm5 (HOST_WIDE_INT val)
>    return (val & (HOST_WIDE_INT) 0x1f) == val;  }
> 
> +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;
> +
> +  /* Make op0 and op1 are legal operands for cmp.  */  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, VOIDmode,
> +                                          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

Attachment: 9-gen-ccmp.patch
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]