| /* Subroutines used for calculate rtx costs of Andes NDS32 cpu for GNU compiler |
| Copyright (C) 2012-2021 Free Software Foundation, Inc. |
| Contributed by Andes Technology Corporation. |
| |
| This file is part of GCC. |
| |
| GCC is free software; you can redistribute it and/or modify it |
| under the terms of the GNU General Public License as published |
| by the Free Software Foundation; either version 3, or (at your |
| option) any later version. |
| |
| GCC is distributed in the hope that it will be useful, but WITHOUT |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
| or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
| License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| /* ------------------------------------------------------------------------ */ |
| |
| #define IN_TARGET_CODE 1 |
| |
| #include "config.h" |
| #include "system.h" |
| #include "coretypes.h" |
| #include "backend.h" |
| #include "target.h" |
| #include "rtl.h" |
| #include "tree.h" |
| #include "memmodel.h" |
| #include "tm_p.h" |
| #include "optabs.h" /* For GEN_FCN. */ |
| #include "recog.h" |
| #include "tm-constrs.h" |
| #include "tree-pass.h" |
| |
| /* ------------------------------------------------------------------------ */ |
| |
| typedef bool (*rtx_cost_func) (rtx, int, int, int, int*); |
| |
| struct rtx_cost_model_t { |
| rtx_cost_func speed_prefer; |
| rtx_cost_func size_prefer; |
| }; |
| |
| static rtx_cost_model_t rtx_cost_model; |
| |
| static int insn_size_16bit; /* Initial at nds32_init_rtx_costs. */ |
| static const int insn_size_32bit = 4; |
| |
| static bool |
| nds32_rtx_costs_speed_prefer (rtx x ATTRIBUTE_UNUSED, |
| int code, |
| int outer_code ATTRIBUTE_UNUSED, |
| int opno ATTRIBUTE_UNUSED, |
| int *total) |
| { |
| rtx op0; |
| rtx op1; |
| machine_mode mode = GET_MODE (x); |
| /* Scale cost by mode size. */ |
| int cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)); |
| |
| switch (code) |
| { |
| case USE: |
| /* Used in combine.c as a marker. */ |
| *total = 0; |
| return true; |
| |
| case CONST_INT: |
| /* When not optimizing for size, we care more about the cost |
| of hot code, and hot code is often in a loop. If a constant |
| operand needs to be forced into a register, we will often be |
| able to hoist the constant load out of the loop, so the load |
| should not contribute to the cost. */ |
| if (outer_code == SET || outer_code == PLUS) |
| *total = satisfies_constraint_Is20 (x) ? 0 : 4; |
| else if (outer_code == AND || outer_code == IOR || outer_code == XOR |
| || outer_code == MINUS) |
| *total = satisfies_constraint_Iu15 (x) ? 0 : 4; |
| else if (outer_code == ASHIFT || outer_code == ASHIFTRT |
| || outer_code == LSHIFTRT) |
| *total = satisfies_constraint_Iu05 (x) ? 0 : 4; |
| else if (GET_RTX_CLASS (outer_code) == RTX_COMPARE |
| || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE) |
| *total = satisfies_constraint_Is16 (x) ? 0 : 4; |
| else |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| case CONST: |
| case LO_SUM: |
| case HIGH: |
| case SYMBOL_REF: |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| case MEM: |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| case SET: |
| op0 = SET_DEST (x); |
| op1 = SET_SRC (x); |
| mode = GET_MODE (op0); |
| /* Scale cost by mode size. */ |
| cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)); |
| |
| switch (GET_CODE (op1)) |
| { |
| case REG: |
| case SUBREG: |
| /* Register move and Store instructions. */ |
| if ((REG_P (op0) || MEM_P (op0)) |
| && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode)) |
| *total = COSTS_N_INSNS (1); |
| else |
| *total = cost; |
| return true; |
| |
| case MEM: |
| /* Load instructions. */ |
| if (REG_P (op0) && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode)) |
| *total = COSTS_N_INSNS (1); |
| else |
| *total = cost; |
| return true; |
| |
| case CONST_INT: |
| /* movi instruction. */ |
| if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode)) |
| { |
| if (satisfies_constraint_Is20 (op1)) |
| *total = COSTS_N_INSNS (1) - 1; |
| else |
| *total = COSTS_N_INSNS (2); |
| } |
| else |
| *total = cost; |
| return true; |
| |
| case CONST: |
| case SYMBOL_REF: |
| case LABEL_REF: |
| /* la instruction. */ |
| if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode)) |
| *total = COSTS_N_INSNS (1) - 1; |
| else |
| *total = cost; |
| return true; |
| case VEC_SELECT: |
| *total = cost; |
| return true; |
| |
| default: |
| *total = cost; |
| return true; |
| } |
| |
| case PLUS: |
| op0 = XEXP (x, 0); |
| op1 = XEXP (x, 1); |
| |
| if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) |
| *total = cost; |
| else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT |
| || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT) |
| /* ALU_SHIFT */ |
| *total = COSTS_N_INSNS (2); |
| |
| else if ((GET_CODE (op1) == CONST_INT |
| && satisfies_constraint_Is15 (op1)) |
| || REG_P (op1)) |
| /* ADD instructions */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* ADD instructions: IMM out of range. */ |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case MINUS: |
| op0 = XEXP (x, 0); |
| op1 = XEXP (x, 1); |
| |
| if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) |
| *total = cost; |
| else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT |
| || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT) |
| /* ALU_SHIFT */ |
| *total = COSTS_N_INSNS (2); |
| else if ((GET_CODE (op0) == CONST_INT |
| && satisfies_constraint_Is15 (op0)) |
| || REG_P (op0)) |
| /* SUB instructions */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* SUB instructions: IMM out of range. */ |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case TRUNCATE: |
| /* TRUNCATE and AND behavior is same. */ |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| case AND: |
| case IOR: |
| case XOR: |
| op0 = XEXP (x, 0); |
| op1 = XEXP (x, 1); |
| |
| if (NDS32_EXT_DSP_P ()) |
| { |
| /* We prefer (and (ior) (ior)) than (ior (and) (and)) for |
| synthetize pk** and insb instruction. */ |
| if (code == AND && GET_CODE (op0) == IOR && GET_CODE (op1) == IOR) |
| return COSTS_N_INSNS (1); |
| |
| if (code == IOR && GET_CODE (op0) == AND && GET_CODE (op1) == AND) |
| return COSTS_N_INSNS (10); |
| } |
| |
| if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) |
| *total = cost; |
| else if (GET_CODE (op0) == ASHIFT || GET_CODE (op0) == LSHIFTRT) |
| *total = COSTS_N_INSNS (2); |
| else if ((GET_CODE (op1) == CONST_INT |
| && satisfies_constraint_Iu15 (op1)) |
| || REG_P (op1)) |
| /* AND, OR, XOR instructions */ |
| *total = COSTS_N_INSNS (1); |
| else if (code == AND || GET_CODE (op0) == NOT) |
| /* BITC instruction */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* AND, OR, XOR instructions: IMM out of range. */ |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case MULT: |
| if (GET_MODE (x) == DImode |
| || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND |
| || GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) |
| /* MUL instructions */ |
| *total = COSTS_N_INSNS (1); |
| else if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) |
| *total = cost; |
| else if (outer_code == PLUS || outer_code == MINUS) |
| *total = COSTS_N_INSNS (2); |
| else if ((GET_CODE (XEXP (x, 1)) == CONST_INT |
| && satisfies_constraint_Iu05 (XEXP (x, 1))) |
| || REG_P (XEXP (x, 1))) |
| /* MUL instructions */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* MUL instructions: IMM out of range. */ |
| *total = COSTS_N_INSNS (2); |
| |
| if (TARGET_MUL_SLOW) |
| *total += COSTS_N_INSNS (4); |
| |
| return true; |
| |
| case LSHIFTRT: |
| if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) |
| *total = cost; |
| else if (outer_code == PLUS || outer_code == MINUS |
| || outer_code == AND || outer_code == IOR |
| || outer_code == XOR) |
| *total = COSTS_N_INSNS (2); |
| else if ((GET_CODE (XEXP (x, 1)) == CONST_INT |
| && satisfies_constraint_Iu05 (XEXP (x, 1))) |
| || REG_P (XEXP (x, 1))) |
| /* SRL instructions */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* SRL instructions: IMM out of range. */ |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case ASHIFT: |
| if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) |
| *total = cost; |
| else if (outer_code == AND || outer_code == IOR |
| || outer_code == XOR) |
| *total = COSTS_N_INSNS (2); |
| else if ((GET_CODE (XEXP (x, 1)) == CONST_INT |
| && satisfies_constraint_Iu05 (XEXP (x, 1))) |
| || REG_P (XEXP (x, 1))) |
| /* SLL instructions */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* SLL instructions: IMM out of range. */ |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case ASHIFTRT: |
| case ROTATERT: |
| if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) |
| *total = cost; |
| else if ((GET_CODE (XEXP (x, 1)) == CONST_INT |
| && satisfies_constraint_Iu05 (XEXP (x, 1))) |
| || REG_P (XEXP (x, 1))) |
| /* ROTR, SLL instructions */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* ROTR, SLL instructions: IMM out of range. */ |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case LT: |
| case LTU: |
| if (outer_code == SET) |
| { |
| if ((GET_CODE (XEXP (x, 1)) == CONST_INT |
| && satisfies_constraint_Iu15 (XEXP (x, 1))) |
| || REG_P (XEXP (x, 1))) |
| /* SLT, SLTI instructions */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* SLT, SLT instructions: IMM out of range. */ |
| *total = COSTS_N_INSNS (2); |
| } |
| else |
| /* branch */ |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case EQ: |
| case NE: |
| case GE: |
| case LE: |
| case GT: |
| /* branch */ |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case IF_THEN_ELSE: |
| if (GET_CODE (XEXP (x, 1)) == LABEL_REF) |
| /* branch */ |
| *total = COSTS_N_INSNS (2); |
| else |
| /* cmovz, cmovn instructions */ |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| case LABEL_REF: |
| if (outer_code == IF_THEN_ELSE) |
| /* branch */ |
| *total = COSTS_N_INSNS (2); |
| else |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| case ZERO_EXTEND: |
| case SIGN_EXTEND: |
| if (MEM_P (XEXP (x, 0))) |
| /* Using memory access. */ |
| *total = COSTS_N_INSNS (1); |
| else |
| /* Zero extend and sign extend instructions. */ |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| case NEG: |
| case NOT: |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| case DIV: |
| case UDIV: |
| case MOD: |
| case UMOD: |
| *total = COSTS_N_INSNS (20); |
| return true; |
| |
| case CALL: |
| *total = COSTS_N_INSNS (2); |
| return true; |
| |
| case CLZ: |
| case SMIN: |
| case SMAX: |
| case ZERO_EXTRACT: |
| if (TARGET_EXT_PERF) |
| *total = COSTS_N_INSNS (1); |
| else |
| *total = COSTS_N_INSNS (3); |
| return true; |
| case VEC_SELECT: |
| *total = COSTS_N_INSNS (1); |
| return true; |
| |
| default: |
| *total = COSTS_N_INSNS (3); |
| return true; |
| } |
| } |
| |
| static bool |
| nds32_rtx_costs_size_prefer (rtx x, |
| int code, |
| int outer_code, |
| int opno ATTRIBUTE_UNUSED, |
| int *total) |
| { |
| /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4. |
| We treat it as 4-byte cost for each instruction |
| under code size consideration. */ |
| switch (code) |
| { |
| case SET: |
| /* For 'SET' rtx, we need to return false |
| so that it can recursively calculate costs. */ |
| return false; |
| |
| case USE: |
| /* Used in combine.c as a marker. */ |
| *total = 0; |
| break; |
| |
| case CONST_INT: |
| /* All instructions involving constant operation |
| need to be considered for cost evaluation. */ |
| if (outer_code == SET) |
| { |
| /* (set X imm5s), use movi55, 2-byte cost. |
| (set X imm20s), use movi, 4-byte cost. |
| (set X BIG_INT), use sethi/ori, 8-byte cost. */ |
| if (satisfies_constraint_Is05 (x)) |
| *total = insn_size_16bit; |
| else if (satisfies_constraint_Is20 (x)) |
| *total = insn_size_32bit; |
| else |
| *total = insn_size_32bit * 2; |
| } |
| else if (outer_code == PLUS || outer_code == MINUS) |
| { |
| /* Possible addi333/subi333 or subi45/addi45, 2-byte cost. |
| General case, cost 1 instruction with 4-byte. */ |
| if (satisfies_constraint_Iu05 (x)) |
| *total = insn_size_16bit; |
| else |
| *total = insn_size_32bit; |
| } |
| else if (outer_code == ASHIFT) |
| { |
| /* Possible slli333, 2-byte cost. |
| General case, cost 1 instruction with 4-byte. */ |
| if (satisfies_constraint_Iu03 (x)) |
| *total = insn_size_16bit; |
| else |
| *total = insn_size_32bit; |
| } |
| else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT) |
| { |
| /* Possible srai45 or srli45, 2-byte cost. |
| General case, cost 1 instruction with 4-byte. */ |
| if (satisfies_constraint_Iu05 (x)) |
| *total = insn_size_16bit; |
| else |
| *total = insn_size_32bit; |
| } |
| else |
| { |
| /* For other cases, simply set it 4-byte cost. */ |
| *total = insn_size_32bit; |
| } |
| break; |
| |
| case CONST_DOUBLE: |
| /* It requires high part and low part processing, set it 8-byte cost. */ |
| *total = insn_size_32bit * 2; |
| break; |
| |
| case CONST: |
| case SYMBOL_REF: |
| *total = insn_size_32bit * 2; |
| break; |
| |
| default: |
| /* For other cases, generally we set it 4-byte cost |
| and stop resurively traversing. */ |
| *total = insn_size_32bit; |
| break; |
| } |
| |
| return true; |
| } |
| |
| void |
| nds32_init_rtx_costs (void) |
| { |
| rtx_cost_model.speed_prefer = nds32_rtx_costs_speed_prefer; |
| rtx_cost_model.size_prefer = nds32_rtx_costs_size_prefer; |
| |
| if (TARGET_16_BIT) |
| insn_size_16bit = 2; |
| else |
| insn_size_16bit = 4; |
| } |
| |
| /* This target hook describes the relative costs of RTL expressions. |
| Return 'true' when all subexpressions of x have been processed. |
| Return 'false' to sum the costs of sub-rtx, plus cost of this operation. |
| Refer to gcc/rtlanal.c for more information. */ |
| bool |
| nds32_rtx_costs_impl (rtx x, |
| machine_mode mode ATTRIBUTE_UNUSED, |
| int outer_code, |
| int opno, |
| int *total, |
| bool speed) |
| { |
| int code = GET_CODE (x); |
| |
| /* According to 'speed', use suitable cost model section. */ |
| if (speed) |
| return rtx_cost_model.speed_prefer(x, code, outer_code, opno, total); |
| else |
| return rtx_cost_model.size_prefer(x, code, outer_code, opno, total); |
| } |
| |
| |
| int nds32_address_cost_speed_prefer (rtx address) |
| { |
| rtx plus0, plus1; |
| enum rtx_code code; |
| |
| code = GET_CODE (address); |
| |
| switch (code) |
| { |
| case POST_MODIFY: |
| case POST_INC: |
| case POST_DEC: |
| /* We encourage that rtx contains |
| POST_MODIFY/POST_INC/POST_DEC behavior. */ |
| return COSTS_N_INSNS (1) - 2; |
| |
| case SYMBOL_REF: |
| /* We can have gp-relative load/store for symbol_ref. |
| Have it 4-byte cost. */ |
| return COSTS_N_INSNS (2); |
| |
| case CONST: |
| /* It is supposed to be the pattern (const (plus symbol_ref const_int)). |
| Have it 4-byte cost. */ |
| return COSTS_N_INSNS (2); |
| |
| case REG: |
| /* Simply return 4-byte costs. */ |
| return COSTS_N_INSNS (1) - 2; |
| |
| case PLUS: |
| /* We do not need to check if the address is a legitimate address, |
| because this hook is never called with an invalid address. |
| But we better check the range of |
| const_int value for cost, if it exists. */ |
| plus0 = XEXP (address, 0); |
| plus1 = XEXP (address, 1); |
| |
| if (REG_P (plus0) && CONST_INT_P (plus1)) |
| return COSTS_N_INSNS (1) - 2; |
| else if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) |
| return COSTS_N_INSNS (1) - 1; |
| else if (REG_P (plus0) && REG_P (plus1)) |
| return COSTS_N_INSNS (1); |
| |
| /* For other 'plus' situation, make it cost 4-byte. */ |
| return COSTS_N_INSNS (1); |
| |
| default: |
| break; |
| } |
| |
| return COSTS_N_INSNS (4); |
| |
| } |
| |
| int nds32_address_cost_speed_fwprop (rtx address) |
| { |
| rtx plus0, plus1; |
| enum rtx_code code; |
| |
| code = GET_CODE (address); |
| |
| switch (code) |
| { |
| case POST_MODIFY: |
| case POST_INC: |
| case POST_DEC: |
| /* We encourage that rtx contains |
| POST_MODIFY/POST_INC/POST_DEC behavior. */ |
| return 0; |
| |
| case SYMBOL_REF: |
| /* We can have gp-relative load/store for symbol_ref. |
| Have it 4-byte cost. */ |
| return COSTS_N_INSNS (2); |
| |
| case CONST: |
| /* It is supposed to be the pattern (const (plus symbol_ref const_int)). |
| Have it 4-byte cost. */ |
| return COSTS_N_INSNS (2); |
| |
| case REG: |
| /* Simply return 4-byte costs. */ |
| return COSTS_N_INSNS (1); |
| |
| case PLUS: |
| /* We do not need to check if the address is a legitimate address, |
| because this hook is never called with an invalid address. |
| But we better check the range of |
| const_int value for cost, if it exists. */ |
| plus0 = XEXP (address, 0); |
| plus1 = XEXP (address, 1); |
| |
| if (REG_P (plus0) && CONST_INT_P (plus1)) |
| { |
| /* If it is possible to be lwi333/swi333 form, |
| make it 2-byte cost. */ |
| if (satisfies_constraint_Iu03 (plus1)) |
| return (COSTS_N_INSNS (1) - 2); |
| else |
| return COSTS_N_INSNS (1); |
| } |
| if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) |
| return COSTS_N_INSNS (1) - 2; |
| else if (REG_P (plus0) && REG_P (plus1)) |
| return COSTS_N_INSNS (1); |
| |
| /* For other 'plus' situation, make it cost 4-byte. */ |
| return COSTS_N_INSNS (1); |
| |
| default: |
| break; |
| } |
| |
| return COSTS_N_INSNS (4); |
| } |
| |
| |
| int nds32_address_cost_size_prefer (rtx address) |
| { |
| rtx plus0, plus1; |
| enum rtx_code code; |
| |
| code = GET_CODE (address); |
| |
| switch (code) |
| { |
| case POST_MODIFY: |
| case POST_INC: |
| case POST_DEC: |
| /* We encourage that rtx contains |
| POST_MODIFY/POST_INC/POST_DEC behavior. */ |
| return 0; |
| |
| case SYMBOL_REF: |
| /* We can have gp-relative load/store for symbol_ref. |
| Have it 4-byte cost. */ |
| return COSTS_N_INSNS (2); |
| |
| case CONST: |
| /* It is supposed to be the pattern (const (plus symbol_ref const_int)). |
| Have it 4-byte cost. */ |
| return COSTS_N_INSNS (2); |
| |
| case REG: |
| /* Simply return 4-byte costs. */ |
| return COSTS_N_INSNS (1) - 1; |
| |
| case PLUS: |
| /* We do not need to check if the address is a legitimate address, |
| because this hook is never called with an invalid address. |
| But we better check the range of |
| const_int value for cost, if it exists. */ |
| plus0 = XEXP (address, 0); |
| plus1 = XEXP (address, 1); |
| |
| if (REG_P (plus0) && CONST_INT_P (plus1)) |
| { |
| /* If it is possible to be lwi333/swi333 form, |
| make it 2-byte cost. */ |
| if (satisfies_constraint_Iu03 (plus1)) |
| return (COSTS_N_INSNS (1) - 2); |
| else |
| return COSTS_N_INSNS (1) - 1; |
| } |
| |
| /* (plus (reg) (mult (reg) (const))) */ |
| if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) |
| return (COSTS_N_INSNS (1) - 1); |
| |
| /* For other 'plus' situation, make it cost 4-byte. */ |
| return COSTS_N_INSNS (1); |
| |
| default: |
| break; |
| } |
| |
| return COSTS_N_INSNS (4); |
| |
| } |
| |
| int nds32_address_cost_impl (rtx address, |
| machine_mode mode ATTRIBUTE_UNUSED, |
| addr_space_t as ATTRIBUTE_UNUSED, |
| bool speed_p) |
| { |
| if (speed_p) |
| { |
| if (current_pass->tv_id == TV_FWPROP) |
| return nds32_address_cost_speed_fwprop (address); |
| else |
| return nds32_address_cost_speed_prefer (address); |
| } |
| else |
| return nds32_address_cost_size_prefer (address); |
| } |
| |
| /* ------------------------------------------------------------------------ */ |