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-ow...@gcc.gnu.org [mailto:gcc-patches- > ow...@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.c...@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
9-gen-ccmp.patch
Description: Binary data