From b58a42aac28becb118a8482d41c4188e00ad0c3a Mon Sep 17 00:00:00 2001 From: "yilun.xie" Date: Thu, 18 Nov 2021 14:55:04 +0800 Subject: [PATCH 18/26] Cost model for zba extension --- gcc/config/riscv/riscv.c | 82 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 17cdf705c32..7d5e22d9fe2 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -1680,6 +1680,10 @@ riscv_extend_cost (rtx op, bool unsigned_p) /* We can use ANDI. */ return COSTS_N_INSNS (1); + /* ZBA provide zext.w. */ + if (TARGET_ZBA && TARGET_64BIT && unsigned_p && GET_MODE (op) == SImode) + return COSTS_N_INSNS (1); + if (!unsigned_p && GET_MODE (op) == SImode) /* We can use SEXT.W. */ return COSTS_N_INSNS (1); @@ -1753,6 +1757,22 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN return false; case AND: + /* slli.uw pattern for zba. */ + if (TARGET_ZBA && TARGET_64BIT && mode == DImode + && GET_CODE (XEXP (x, 0)) == ASHIFT) + { + rtx and_rhs = XEXP (x, 1); + rtx ashift_lhs = XEXP (XEXP (x, 0), 0); + rtx ashift_rhs = XEXP (XEXP (x, 0), 1); + if (REG_P (ashift_lhs) + && CONST_INT_P (ashift_rhs) + && CONST_INT_P (and_rhs) + && ((INTVAL (and_rhs) >> INTVAL (ashift_rhs)) == 0xffffffff)) + *total = COSTS_N_INSNS (1); + return true; + } + gcc_fallthrough (); + case IOR: case XOR: /* Double-word operations use two single-word operations. */ @@ -1844,6 +1864,68 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN case MINUS: case PLUS: + /* add.uw pattern for zba. */ + if (TARGET_ZBA + && (TARGET_64BIT && (mode == DImode)) + && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND + && REG_P (XEXP (XEXP (x, 0), 0)) + && GET_MODE (XEXP (XEXP (x, 0), 0)) == SImode) + { + *total = COSTS_N_INSNS (1); + return true; + } + /* shNadd pattern for zba. */ + if (TARGET_ZBA + && ((!TARGET_64BIT && (mode == SImode)) || + (TARGET_64BIT && (mode == DImode))) + && (GET_CODE (XEXP (x, 0)) == ASHIFT) + && REG_P (XEXP (XEXP (x, 0), 0)) + && CONST_INT_P (XEXP (XEXP (x, 0), 0)) + && IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 0)), 1, 3)) + { + *total = COSTS_N_INSNS (1); + return true; + } + /* shNadd.uw pattern for zba. + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI + (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "I")) + (match_operand 3 "immediate_operand" "")) + (match_operand:DI 4 "register_operand" "r")))] + "TARGET_64BIT && TARGET_ZBA + && (INTVAL (operands[2]) >= 1) && (INTVAL (operands[2]) <= 3) + && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff" + */ + if (TARGET_ZBA + && (TARGET_64BIT && (mode == DImode)) + && (GET_CODE (XEXP (x, 0)) == AND) + && (REG_P (XEXP (x, 1)))) + { + do { + rtx and_lhs = XEXP (XEXP (x, 0), 0); + rtx and_rhs = XEXP (XEXP (x, 0), 1); + if (GET_CODE (and_lhs) != ASHIFT) + break; + if (!CONST_INT_P (and_rhs)) + break; + + rtx ashift_lhs = XEXP (and_lhs, 0); + rtx ashift_rhs = XEXP (and_lhs, 1); + + if (!CONST_INT_P (ashift_rhs) + || !IN_RANGE (INTVAL (ashift_rhs), 1, 3)) + break; + + if (CONST_INT_P (and_rhs) + && ((INTVAL (and_rhs) >> INTVAL (ashift_rhs)) == 0xffffffff)) + { + *total = COSTS_N_INSNS (1); + return true; + } + } while (false); + } + if (float_mode_p) *total = tune_param->fp_add[mode == DFmode]; else -- 2.33.1