Hi all,This patch adds rtx costing code for the round-to-integer instructions in AArch64. Some of them are implemented as UNSPECs, so I've added the appropriate case to the big switch that can be
expanded upon to handle other unspecs in the future. Tested aarch64-none-elf and bootstrapped on aarch64-none-linux-gnu.
Ok for trunk? Thanks, Kyrill 2014-07-10 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * config/aarch64/aarch64.c (aarch64_frint_unspec_p): New function. (aarch64_rtx_costs): Handle FIX, UNSIGNED_FIX, UNSPEC.
commit 32fcdbfebf209ac3fce9af3b891e874feef1bdf7 Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com> Date: Fri Jul 4 14:49:58 2014 +0100 [AArch64] RTX costs for FIX and UNSIGNED_FIX diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 3aba204..4b34dce 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4841,6 +4841,25 @@ aarch64_rtx_arith_op_extract_p (rtx x, enum machine_mode mode) return false; } +static bool +aarch64_frint_unspec_p (unsigned int u) +{ + switch (u) + { + case UNSPEC_FRINTZ: + case UNSPEC_FRINTP: + case UNSPEC_FRINTM: + case UNSPEC_FRINTA: + case UNSPEC_FRINTN: + case UNSPEC_FRINTX: + case UNSPEC_FRINTI: + return true; + + default: + return false; + } +} + /* Calculate the cost of calculating (if_then_else (OP0) (OP1) (OP2)), storing it in *COST. Result is true if the total cost of the operation has now been calculated. */ @@ -5021,7 +5040,7 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED, default: /* We can't make sense of this, assume default cost. */ *cost = COSTS_N_INSNS (1); - break; + return false; } return false; @@ -5719,6 +5738,29 @@ cost_plus: *cost += extra_cost->fp[mode == DFmode].narrow; return false; + case FIX: + case UNSIGNED_FIX: + x = XEXP (x, 0); + /* Strip the rounding part. They will all be implemented + by the fcvt* family of instructions anyway. */ + if (GET_CODE (x) == UNSPEC) + { + unsigned int uns_code = XINT (x, 1); + + if (uns_code == UNSPEC_FRINTA + || uns_code == UNSPEC_FRINTM + || uns_code == UNSPEC_FRINTN + || uns_code == UNSPEC_FRINTP + || uns_code == UNSPEC_FRINTZ) + x = XVECEXP (x, 0, 0); + } + + if (speed) + *cost += extra_cost->fp[GET_MODE (x) == DFmode].toint; + + *cost += rtx_cost (x, (enum rtx_code) code, 0, speed); + return true; + case ABS: if (GET_MODE_CLASS (mode) == MODE_FLOAT) { @@ -5748,6 +5790,17 @@ cost_plus: } return false; + case UNSPEC: + /* The floating point round to integer frint* instructions. */ + if (aarch64_frint_unspec_p (XINT (x, 1))) + { + if (speed) + *cost += extra_cost->fp[mode == DFmode].roundint; + + return false; + } + break; + case TRUNCATE: /* Decompose <su>muldi3_highpart. */ @@ -5782,13 +5835,14 @@ cost_plus: /* Fall through. */ default: - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "\nFailed to cost RTX. Assuming default cost.\n"); - - return true; + break; } - return false; + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "\nFailed to cost RTX. Assuming default cost.\n"); + + return true; } /* Wrapper around aarch64_rtx_costs, dumps the partial, or total cost