15ef59e75Smrg /* Subroutines used for calculate rtx costs of Andes NDS32 cpu for GNU compiler
2*dd083157Smrg Copyright (C) 2012-2020 Free Software Foundation, Inc.
35ef59e75Smrg Contributed by Andes Technology Corporation.
45ef59e75Smrg
55ef59e75Smrg This file is part of GCC.
65ef59e75Smrg
75ef59e75Smrg GCC is free software; you can redistribute it and/or modify it
85ef59e75Smrg under the terms of the GNU General Public License as published
95ef59e75Smrg by the Free Software Foundation; either version 3, or (at your
105ef59e75Smrg option) any later version.
115ef59e75Smrg
125ef59e75Smrg GCC is distributed in the hope that it will be useful, but WITHOUT
135ef59e75Smrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
145ef59e75Smrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
155ef59e75Smrg License for more details.
165ef59e75Smrg
175ef59e75Smrg You should have received a copy of the GNU General Public License
185ef59e75Smrg along with GCC; see the file COPYING3. If not see
195ef59e75Smrg <http://www.gnu.org/licenses/>. */
205ef59e75Smrg
215ef59e75Smrg /* ------------------------------------------------------------------------ */
225ef59e75Smrg
233903d7f3Smrg #define IN_TARGET_CODE 1
243903d7f3Smrg
255ef59e75Smrg #include "config.h"
265ef59e75Smrg #include "system.h"
275ef59e75Smrg #include "coretypes.h"
2863aace61Smrg #include "backend.h"
295ef59e75Smrg #include "target.h"
3063aace61Smrg #include "rtl.h"
3163aace61Smrg #include "tree.h"
326a5c9aabSmrg #include "memmodel.h"
3363aace61Smrg #include "tm_p.h"
3463aace61Smrg #include "optabs.h" /* For GEN_FCN. */
3563aace61Smrg #include "recog.h"
3663aace61Smrg #include "tm-constrs.h"
3781418a27Smrg #include "tree-pass.h"
385ef59e75Smrg
395ef59e75Smrg /* ------------------------------------------------------------------------ */
405ef59e75Smrg
4181418a27Smrg typedef bool (*rtx_cost_func) (rtx, int, int, int, int*);
4281418a27Smrg
4381418a27Smrg struct rtx_cost_model_t {
4481418a27Smrg rtx_cost_func speed_prefer;
4581418a27Smrg rtx_cost_func size_prefer;
4681418a27Smrg };
4781418a27Smrg
4881418a27Smrg static rtx_cost_model_t rtx_cost_model;
4981418a27Smrg
5081418a27Smrg static int insn_size_16bit; /* Initial at nds32_init_rtx_costs. */
5181418a27Smrg static const int insn_size_32bit = 4;
5281418a27Smrg
5381418a27Smrg static bool
nds32_rtx_costs_speed_prefer(rtx x ATTRIBUTE_UNUSED,int code,int outer_code ATTRIBUTE_UNUSED,int opno ATTRIBUTE_UNUSED,int * total)5481418a27Smrg nds32_rtx_costs_speed_prefer (rtx x ATTRIBUTE_UNUSED,
5581418a27Smrg int code,
5681418a27Smrg int outer_code ATTRIBUTE_UNUSED,
575ef59e75Smrg int opno ATTRIBUTE_UNUSED,
5881418a27Smrg int *total)
595ef59e75Smrg {
6081418a27Smrg rtx op0;
6181418a27Smrg rtx op1;
6281418a27Smrg machine_mode mode = GET_MODE (x);
6381418a27Smrg /* Scale cost by mode size. */
6481418a27Smrg int cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode));
6563aace61Smrg
665ef59e75Smrg switch (code)
675ef59e75Smrg {
685ef59e75Smrg case USE:
695ef59e75Smrg /* Used in combine.c as a marker. */
705ef59e75Smrg *total = 0;
7181418a27Smrg return true;
7281418a27Smrg
7381418a27Smrg case CONST_INT:
7481418a27Smrg /* When not optimizing for size, we care more about the cost
7581418a27Smrg of hot code, and hot code is often in a loop. If a constant
7681418a27Smrg operand needs to be forced into a register, we will often be
7781418a27Smrg able to hoist the constant load out of the loop, so the load
7881418a27Smrg should not contribute to the cost. */
7981418a27Smrg if (outer_code == SET || outer_code == PLUS)
8081418a27Smrg *total = satisfies_constraint_Is20 (x) ? 0 : 4;
8181418a27Smrg else if (outer_code == AND || outer_code == IOR || outer_code == XOR
8281418a27Smrg || outer_code == MINUS)
8381418a27Smrg *total = satisfies_constraint_Iu15 (x) ? 0 : 4;
8481418a27Smrg else if (outer_code == ASHIFT || outer_code == ASHIFTRT
8581418a27Smrg || outer_code == LSHIFTRT)
8681418a27Smrg *total = satisfies_constraint_Iu05 (x) ? 0 : 4;
8781418a27Smrg else if (GET_RTX_CLASS (outer_code) == RTX_COMPARE
8881418a27Smrg || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE)
8981418a27Smrg *total = satisfies_constraint_Is16 (x) ? 0 : 4;
9081418a27Smrg else
9181418a27Smrg *total = COSTS_N_INSNS (1);
9281418a27Smrg return true;
9381418a27Smrg
9481418a27Smrg case CONST:
9581418a27Smrg case LO_SUM:
9681418a27Smrg case HIGH:
9781418a27Smrg case SYMBOL_REF:
9881418a27Smrg *total = COSTS_N_INSNS (1);
9981418a27Smrg return true;
10081418a27Smrg
10181418a27Smrg case MEM:
10281418a27Smrg *total = COSTS_N_INSNS (1);
10381418a27Smrg return true;
10481418a27Smrg
10581418a27Smrg case SET:
10681418a27Smrg op0 = SET_DEST (x);
10781418a27Smrg op1 = SET_SRC (x);
10881418a27Smrg mode = GET_MODE (op0);
10981418a27Smrg /* Scale cost by mode size. */
11081418a27Smrg cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode));
11181418a27Smrg
11281418a27Smrg switch (GET_CODE (op1))
11381418a27Smrg {
11481418a27Smrg case REG:
11581418a27Smrg case SUBREG:
11681418a27Smrg /* Register move and Store instructions. */
11781418a27Smrg if ((REG_P (op0) || MEM_P (op0))
11881418a27Smrg && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode))
11981418a27Smrg *total = COSTS_N_INSNS (1);
12081418a27Smrg else
12181418a27Smrg *total = cost;
12281418a27Smrg return true;
12381418a27Smrg
12481418a27Smrg case MEM:
12581418a27Smrg /* Load instructions. */
12681418a27Smrg if (REG_P (op0) && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode))
12781418a27Smrg *total = COSTS_N_INSNS (1);
12881418a27Smrg else
12981418a27Smrg *total = cost;
13081418a27Smrg return true;
13181418a27Smrg
13281418a27Smrg case CONST_INT:
13381418a27Smrg /* movi instruction. */
13481418a27Smrg if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode))
13581418a27Smrg {
13681418a27Smrg if (satisfies_constraint_Is20 (op1))
13781418a27Smrg *total = COSTS_N_INSNS (1) - 1;
13881418a27Smrg else
13981418a27Smrg *total = COSTS_N_INSNS (2);
14081418a27Smrg }
14181418a27Smrg else
14281418a27Smrg *total = cost;
14381418a27Smrg return true;
14481418a27Smrg
14581418a27Smrg case CONST:
14681418a27Smrg case SYMBOL_REF:
14781418a27Smrg case LABEL_REF:
14881418a27Smrg /* la instruction. */
14981418a27Smrg if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode))
15081418a27Smrg *total = COSTS_N_INSNS (1) - 1;
15181418a27Smrg else
15281418a27Smrg *total = cost;
15381418a27Smrg return true;
15481418a27Smrg case VEC_SELECT:
15581418a27Smrg *total = cost;
15681418a27Smrg return true;
15781418a27Smrg
15881418a27Smrg default:
15981418a27Smrg *total = cost;
16081418a27Smrg return true;
16181418a27Smrg }
16281418a27Smrg
16381418a27Smrg case PLUS:
16481418a27Smrg op0 = XEXP (x, 0);
16581418a27Smrg op1 = XEXP (x, 1);
16681418a27Smrg
16781418a27Smrg if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
16881418a27Smrg *total = cost;
16981418a27Smrg else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT
17081418a27Smrg || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT)
17181418a27Smrg /* ALU_SHIFT */
17281418a27Smrg *total = COSTS_N_INSNS (2);
17381418a27Smrg
17481418a27Smrg else if ((GET_CODE (op1) == CONST_INT
17581418a27Smrg && satisfies_constraint_Is15 (op1))
17681418a27Smrg || REG_P (op1))
17781418a27Smrg /* ADD instructions */
17881418a27Smrg *total = COSTS_N_INSNS (1);
17981418a27Smrg else
18081418a27Smrg /* ADD instructions: IMM out of range. */
18181418a27Smrg *total = COSTS_N_INSNS (2);
18281418a27Smrg return true;
18381418a27Smrg
18481418a27Smrg case MINUS:
18581418a27Smrg op0 = XEXP (x, 0);
18681418a27Smrg op1 = XEXP (x, 1);
18781418a27Smrg
18881418a27Smrg if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
18981418a27Smrg *total = cost;
19081418a27Smrg else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT
19181418a27Smrg || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT)
19281418a27Smrg /* ALU_SHIFT */
19381418a27Smrg *total = COSTS_N_INSNS (2);
19481418a27Smrg else if ((GET_CODE (op0) == CONST_INT
19581418a27Smrg && satisfies_constraint_Is15 (op0))
19681418a27Smrg || REG_P (op0))
19781418a27Smrg /* SUB instructions */
19881418a27Smrg *total = COSTS_N_INSNS (1);
19981418a27Smrg else
20081418a27Smrg /* SUB instructions: IMM out of range. */
20181418a27Smrg *total = COSTS_N_INSNS (2);
20281418a27Smrg return true;
20381418a27Smrg
20481418a27Smrg case TRUNCATE:
20581418a27Smrg /* TRUNCATE and AND behavior is same. */
20681418a27Smrg *total = COSTS_N_INSNS (1);
20781418a27Smrg return true;
20881418a27Smrg
20981418a27Smrg case AND:
21081418a27Smrg case IOR:
21181418a27Smrg case XOR:
21281418a27Smrg op0 = XEXP (x, 0);
21381418a27Smrg op1 = XEXP (x, 1);
21481418a27Smrg
21581418a27Smrg if (NDS32_EXT_DSP_P ())
21681418a27Smrg {
21781418a27Smrg /* We prefer (and (ior) (ior)) than (ior (and) (and)) for
21881418a27Smrg synthetize pk** and insb instruction. */
21981418a27Smrg if (code == AND && GET_CODE (op0) == IOR && GET_CODE (op1) == IOR)
22081418a27Smrg return COSTS_N_INSNS (1);
22181418a27Smrg
22281418a27Smrg if (code == IOR && GET_CODE (op0) == AND && GET_CODE (op1) == AND)
22381418a27Smrg return COSTS_N_INSNS (10);
22481418a27Smrg }
22581418a27Smrg
22681418a27Smrg if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
22781418a27Smrg *total = cost;
22881418a27Smrg else if (GET_CODE (op0) == ASHIFT || GET_CODE (op0) == LSHIFTRT)
22981418a27Smrg *total = COSTS_N_INSNS (2);
23081418a27Smrg else if ((GET_CODE (op1) == CONST_INT
23181418a27Smrg && satisfies_constraint_Iu15 (op1))
23281418a27Smrg || REG_P (op1))
23381418a27Smrg /* AND, OR, XOR instructions */
23481418a27Smrg *total = COSTS_N_INSNS (1);
23581418a27Smrg else if (code == AND || GET_CODE (op0) == NOT)
23681418a27Smrg /* BITC instruction */
23781418a27Smrg *total = COSTS_N_INSNS (1);
23881418a27Smrg else
23981418a27Smrg /* AND, OR, XOR instructions: IMM out of range. */
24081418a27Smrg *total = COSTS_N_INSNS (2);
24181418a27Smrg return true;
2425ef59e75Smrg
2435ef59e75Smrg case MULT:
24481418a27Smrg if (GET_MODE (x) == DImode
24581418a27Smrg || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND
24681418a27Smrg || GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
24781418a27Smrg /* MUL instructions */
2485ef59e75Smrg *total = COSTS_N_INSNS (1);
24981418a27Smrg else if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
25081418a27Smrg *total = cost;
25181418a27Smrg else if (outer_code == PLUS || outer_code == MINUS)
25281418a27Smrg *total = COSTS_N_INSNS (2);
25381418a27Smrg else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
25481418a27Smrg && satisfies_constraint_Iu05 (XEXP (x, 1)))
25581418a27Smrg || REG_P (XEXP (x, 1)))
25681418a27Smrg /* MUL instructions */
25781418a27Smrg *total = COSTS_N_INSNS (1);
25881418a27Smrg else
25981418a27Smrg /* MUL instructions: IMM out of range. */
26081418a27Smrg *total = COSTS_N_INSNS (2);
26181418a27Smrg
26281418a27Smrg if (TARGET_MUL_SLOW)
26381418a27Smrg *total += COSTS_N_INSNS (4);
26481418a27Smrg
26581418a27Smrg return true;
26681418a27Smrg
26781418a27Smrg case LSHIFTRT:
26881418a27Smrg if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
26981418a27Smrg *total = cost;
27081418a27Smrg else if (outer_code == PLUS || outer_code == MINUS
27181418a27Smrg || outer_code == AND || outer_code == IOR
27281418a27Smrg || outer_code == XOR)
27381418a27Smrg *total = COSTS_N_INSNS (2);
27481418a27Smrg else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
27581418a27Smrg && satisfies_constraint_Iu05 (XEXP (x, 1)))
27681418a27Smrg || REG_P (XEXP (x, 1)))
27781418a27Smrg /* SRL instructions */
27881418a27Smrg *total = COSTS_N_INSNS (1);
27981418a27Smrg else
28081418a27Smrg /* SRL instructions: IMM out of range. */
28181418a27Smrg *total = COSTS_N_INSNS (2);
28281418a27Smrg return true;
28381418a27Smrg
28481418a27Smrg case ASHIFT:
28581418a27Smrg if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
28681418a27Smrg *total = cost;
28781418a27Smrg else if (outer_code == AND || outer_code == IOR
28881418a27Smrg || outer_code == XOR)
28981418a27Smrg *total = COSTS_N_INSNS (2);
29081418a27Smrg else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
29181418a27Smrg && satisfies_constraint_Iu05 (XEXP (x, 1)))
29281418a27Smrg || REG_P (XEXP (x, 1)))
29381418a27Smrg /* SLL instructions */
29481418a27Smrg *total = COSTS_N_INSNS (1);
29581418a27Smrg else
29681418a27Smrg /* SLL instructions: IMM out of range. */
29781418a27Smrg *total = COSTS_N_INSNS (2);
29881418a27Smrg return true;
29981418a27Smrg
30081418a27Smrg case ASHIFTRT:
30181418a27Smrg case ROTATERT:
30281418a27Smrg if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
30381418a27Smrg *total = cost;
30481418a27Smrg else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
30581418a27Smrg && satisfies_constraint_Iu05 (XEXP (x, 1)))
30681418a27Smrg || REG_P (XEXP (x, 1)))
30781418a27Smrg /* ROTR, SLL instructions */
30881418a27Smrg *total = COSTS_N_INSNS (1);
30981418a27Smrg else
31081418a27Smrg /* ROTR, SLL instructions: IMM out of range. */
31181418a27Smrg *total = COSTS_N_INSNS (2);
31281418a27Smrg return true;
31381418a27Smrg
31481418a27Smrg case LT:
31581418a27Smrg case LTU:
31681418a27Smrg if (outer_code == SET)
31781418a27Smrg {
31881418a27Smrg if ((GET_CODE (XEXP (x, 1)) == CONST_INT
31981418a27Smrg && satisfies_constraint_Iu15 (XEXP (x, 1)))
32081418a27Smrg || REG_P (XEXP (x, 1)))
32181418a27Smrg /* SLT, SLTI instructions */
32281418a27Smrg *total = COSTS_N_INSNS (1);
32381418a27Smrg else
32481418a27Smrg /* SLT, SLT instructions: IMM out of range. */
32581418a27Smrg *total = COSTS_N_INSNS (2);
32681418a27Smrg }
32781418a27Smrg else
32881418a27Smrg /* branch */
32981418a27Smrg *total = COSTS_N_INSNS (2);
33081418a27Smrg return true;
33181418a27Smrg
33281418a27Smrg case EQ:
33381418a27Smrg case NE:
33481418a27Smrg case GE:
33581418a27Smrg case LE:
33681418a27Smrg case GT:
33781418a27Smrg /* branch */
33881418a27Smrg *total = COSTS_N_INSNS (2);
33981418a27Smrg return true;
34081418a27Smrg
34181418a27Smrg case IF_THEN_ELSE:
34281418a27Smrg if (GET_CODE (XEXP (x, 1)) == LABEL_REF)
34381418a27Smrg /* branch */
34481418a27Smrg *total = COSTS_N_INSNS (2);
34581418a27Smrg else
34681418a27Smrg /* cmovz, cmovn instructions */
34781418a27Smrg *total = COSTS_N_INSNS (1);
34881418a27Smrg return true;
34981418a27Smrg
35081418a27Smrg case LABEL_REF:
35181418a27Smrg if (outer_code == IF_THEN_ELSE)
35281418a27Smrg /* branch */
35381418a27Smrg *total = COSTS_N_INSNS (2);
35481418a27Smrg else
35581418a27Smrg *total = COSTS_N_INSNS (1);
35681418a27Smrg return true;
35781418a27Smrg
35881418a27Smrg case ZERO_EXTEND:
35981418a27Smrg case SIGN_EXTEND:
36081418a27Smrg if (MEM_P (XEXP (x, 0)))
36181418a27Smrg /* Using memory access. */
36281418a27Smrg *total = COSTS_N_INSNS (1);
36381418a27Smrg else
36481418a27Smrg /* Zero extend and sign extend instructions. */
36581418a27Smrg *total = COSTS_N_INSNS (1);
36681418a27Smrg return true;
36781418a27Smrg
36881418a27Smrg case NEG:
36981418a27Smrg case NOT:
37081418a27Smrg *total = COSTS_N_INSNS (1);
37181418a27Smrg return true;
3725ef59e75Smrg
3735ef59e75Smrg case DIV:
3745ef59e75Smrg case UDIV:
3755ef59e75Smrg case MOD:
3765ef59e75Smrg case UMOD:
37781418a27Smrg *total = COSTS_N_INSNS (20);
3785ef59e75Smrg return true;
3795ef59e75Smrg
38081418a27Smrg case CALL:
38181418a27Smrg *total = COSTS_N_INSNS (2);
38281418a27Smrg return true;
3835ef59e75Smrg
38481418a27Smrg case CLZ:
38581418a27Smrg case SMIN:
38681418a27Smrg case SMAX:
38781418a27Smrg case ZERO_EXTRACT:
38881418a27Smrg if (TARGET_EXT_PERF)
38981418a27Smrg *total = COSTS_N_INSNS (1);
39081418a27Smrg else
39181418a27Smrg *total = COSTS_N_INSNS (3);
39281418a27Smrg return true;
39381418a27Smrg case VEC_SELECT:
39481418a27Smrg *total = COSTS_N_INSNS (1);
39581418a27Smrg return true;
3965ef59e75Smrg
39781418a27Smrg default:
39881418a27Smrg *total = COSTS_N_INSNS (3);
39981418a27Smrg return true;
40081418a27Smrg }
40181418a27Smrg }
40281418a27Smrg
40381418a27Smrg static bool
nds32_rtx_costs_size_prefer(rtx x,int code,int outer_code,int opno ATTRIBUTE_UNUSED,int * total)40481418a27Smrg nds32_rtx_costs_size_prefer (rtx x,
40581418a27Smrg int code,
40681418a27Smrg int outer_code,
40781418a27Smrg int opno ATTRIBUTE_UNUSED,
40881418a27Smrg int *total)
40981418a27Smrg {
4105ef59e75Smrg /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
4115ef59e75Smrg We treat it as 4-byte cost for each instruction
4125ef59e75Smrg under code size consideration. */
4135ef59e75Smrg switch (code)
4145ef59e75Smrg {
4155ef59e75Smrg case SET:
4165ef59e75Smrg /* For 'SET' rtx, we need to return false
4175ef59e75Smrg so that it can recursively calculate costs. */
4185ef59e75Smrg return false;
4195ef59e75Smrg
4205ef59e75Smrg case USE:
4215ef59e75Smrg /* Used in combine.c as a marker. */
4225ef59e75Smrg *total = 0;
4235ef59e75Smrg break;
4245ef59e75Smrg
4255ef59e75Smrg case CONST_INT:
4265ef59e75Smrg /* All instructions involving constant operation
4275ef59e75Smrg need to be considered for cost evaluation. */
4285ef59e75Smrg if (outer_code == SET)
4295ef59e75Smrg {
4305ef59e75Smrg /* (set X imm5s), use movi55, 2-byte cost.
4315ef59e75Smrg (set X imm20s), use movi, 4-byte cost.
4325ef59e75Smrg (set X BIG_INT), use sethi/ori, 8-byte cost. */
4335ef59e75Smrg if (satisfies_constraint_Is05 (x))
43481418a27Smrg *total = insn_size_16bit;
4355ef59e75Smrg else if (satisfies_constraint_Is20 (x))
43681418a27Smrg *total = insn_size_32bit;
4375ef59e75Smrg else
43881418a27Smrg *total = insn_size_32bit * 2;
4395ef59e75Smrg }
4405ef59e75Smrg else if (outer_code == PLUS || outer_code == MINUS)
4415ef59e75Smrg {
4425ef59e75Smrg /* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
4435ef59e75Smrg General case, cost 1 instruction with 4-byte. */
4445ef59e75Smrg if (satisfies_constraint_Iu05 (x))
44581418a27Smrg *total = insn_size_16bit;
4465ef59e75Smrg else
44781418a27Smrg *total = insn_size_32bit;
4485ef59e75Smrg }
4495ef59e75Smrg else if (outer_code == ASHIFT)
4505ef59e75Smrg {
4515ef59e75Smrg /* Possible slli333, 2-byte cost.
4525ef59e75Smrg General case, cost 1 instruction with 4-byte. */
4535ef59e75Smrg if (satisfies_constraint_Iu03 (x))
45481418a27Smrg *total = insn_size_16bit;
4555ef59e75Smrg else
45681418a27Smrg *total = insn_size_32bit;
4575ef59e75Smrg }
4585ef59e75Smrg else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
4595ef59e75Smrg {
4605ef59e75Smrg /* Possible srai45 or srli45, 2-byte cost.
4615ef59e75Smrg General case, cost 1 instruction with 4-byte. */
4625ef59e75Smrg if (satisfies_constraint_Iu05 (x))
46381418a27Smrg *total = insn_size_16bit;
4645ef59e75Smrg else
46581418a27Smrg *total = insn_size_32bit;
4665ef59e75Smrg }
4675ef59e75Smrg else
4685ef59e75Smrg {
4695ef59e75Smrg /* For other cases, simply set it 4-byte cost. */
47081418a27Smrg *total = insn_size_32bit;
4715ef59e75Smrg }
4725ef59e75Smrg break;
4735ef59e75Smrg
4745ef59e75Smrg case CONST_DOUBLE:
4755ef59e75Smrg /* It requires high part and low part processing, set it 8-byte cost. */
47681418a27Smrg *total = insn_size_32bit * 2;
47781418a27Smrg break;
47881418a27Smrg
47981418a27Smrg case CONST:
48081418a27Smrg case SYMBOL_REF:
48181418a27Smrg *total = insn_size_32bit * 2;
4825ef59e75Smrg break;
4835ef59e75Smrg
4845ef59e75Smrg default:
4855ef59e75Smrg /* For other cases, generally we set it 4-byte cost
4865ef59e75Smrg and stop resurively traversing. */
48781418a27Smrg *total = insn_size_32bit;
4885ef59e75Smrg break;
4895ef59e75Smrg }
4905ef59e75Smrg
4915ef59e75Smrg return true;
4925ef59e75Smrg }
4935ef59e75Smrg
49481418a27Smrg void
nds32_init_rtx_costs(void)49581418a27Smrg nds32_init_rtx_costs (void)
49681418a27Smrg {
49781418a27Smrg rtx_cost_model.speed_prefer = nds32_rtx_costs_speed_prefer;
49881418a27Smrg rtx_cost_model.size_prefer = nds32_rtx_costs_size_prefer;
49981418a27Smrg
50081418a27Smrg if (TARGET_16_BIT)
50181418a27Smrg insn_size_16bit = 2;
50281418a27Smrg else
50381418a27Smrg insn_size_16bit = 4;
50481418a27Smrg }
50581418a27Smrg
50681418a27Smrg /* This target hook describes the relative costs of RTL expressions.
50781418a27Smrg Return 'true' when all subexpressions of x have been processed.
50881418a27Smrg Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
50981418a27Smrg Refer to gcc/rtlanal.c for more information. */
51081418a27Smrg bool
nds32_rtx_costs_impl(rtx x,machine_mode mode ATTRIBUTE_UNUSED,int outer_code,int opno,int * total,bool speed)51181418a27Smrg nds32_rtx_costs_impl (rtx x,
5125ef59e75Smrg machine_mode mode ATTRIBUTE_UNUSED,
51381418a27Smrg int outer_code,
51481418a27Smrg int opno,
51581418a27Smrg int *total,
5165ef59e75Smrg bool speed)
5175ef59e75Smrg {
51881418a27Smrg int code = GET_CODE (x);
51981418a27Smrg
52081418a27Smrg /* According to 'speed', use suitable cost model section. */
52181418a27Smrg if (speed)
52281418a27Smrg return rtx_cost_model.speed_prefer(x, code, outer_code, opno, total);
52381418a27Smrg else
52481418a27Smrg return rtx_cost_model.size_prefer(x, code, outer_code, opno, total);
52581418a27Smrg }
52681418a27Smrg
52781418a27Smrg
nds32_address_cost_speed_prefer(rtx address)52881418a27Smrg int nds32_address_cost_speed_prefer (rtx address)
52981418a27Smrg {
5305ef59e75Smrg rtx plus0, plus1;
5315ef59e75Smrg enum rtx_code code;
5325ef59e75Smrg
5335ef59e75Smrg code = GET_CODE (address);
5345ef59e75Smrg
53581418a27Smrg switch (code)
53681418a27Smrg {
53781418a27Smrg case POST_MODIFY:
53881418a27Smrg case POST_INC:
53981418a27Smrg case POST_DEC:
54081418a27Smrg /* We encourage that rtx contains
54181418a27Smrg POST_MODIFY/POST_INC/POST_DEC behavior. */
54281418a27Smrg return COSTS_N_INSNS (1) - 2;
5435ef59e75Smrg
54481418a27Smrg case SYMBOL_REF:
54581418a27Smrg /* We can have gp-relative load/store for symbol_ref.
54681418a27Smrg Have it 4-byte cost. */
54781418a27Smrg return COSTS_N_INSNS (2);
5485ef59e75Smrg
54981418a27Smrg case CONST:
55081418a27Smrg /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
55181418a27Smrg Have it 4-byte cost. */
55281418a27Smrg return COSTS_N_INSNS (2);
5535ef59e75Smrg
55481418a27Smrg case REG:
55581418a27Smrg /* Simply return 4-byte costs. */
55681418a27Smrg return COSTS_N_INSNS (1) - 2;
55781418a27Smrg
55881418a27Smrg case PLUS:
55981418a27Smrg /* We do not need to check if the address is a legitimate address,
56081418a27Smrg because this hook is never called with an invalid address.
56181418a27Smrg But we better check the range of
56281418a27Smrg const_int value for cost, if it exists. */
56381418a27Smrg plus0 = XEXP (address, 0);
56481418a27Smrg plus1 = XEXP (address, 1);
56581418a27Smrg
56681418a27Smrg if (REG_P (plus0) && CONST_INT_P (plus1))
56781418a27Smrg return COSTS_N_INSNS (1) - 2;
56881418a27Smrg else if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
56981418a27Smrg return COSTS_N_INSNS (1) - 1;
57081418a27Smrg else if (REG_P (plus0) && REG_P (plus1))
57181418a27Smrg return COSTS_N_INSNS (1);
57281418a27Smrg
57381418a27Smrg /* For other 'plus' situation, make it cost 4-byte. */
57481418a27Smrg return COSTS_N_INSNS (1);
57581418a27Smrg
57681418a27Smrg default:
57781418a27Smrg break;
57881418a27Smrg }
57981418a27Smrg
58081418a27Smrg return COSTS_N_INSNS (4);
58181418a27Smrg
58281418a27Smrg }
58381418a27Smrg
nds32_address_cost_speed_fwprop(rtx address)58481418a27Smrg int nds32_address_cost_speed_fwprop (rtx address)
58581418a27Smrg {
58681418a27Smrg rtx plus0, plus1;
58781418a27Smrg enum rtx_code code;
58881418a27Smrg
58981418a27Smrg code = GET_CODE (address);
5905ef59e75Smrg
5915ef59e75Smrg switch (code)
5925ef59e75Smrg {
5935ef59e75Smrg case POST_MODIFY:
5945ef59e75Smrg case POST_INC:
5955ef59e75Smrg case POST_DEC:
5965ef59e75Smrg /* We encourage that rtx contains
5975ef59e75Smrg POST_MODIFY/POST_INC/POST_DEC behavior. */
5985ef59e75Smrg return 0;
5995ef59e75Smrg
6005ef59e75Smrg case SYMBOL_REF:
6015ef59e75Smrg /* We can have gp-relative load/store for symbol_ref.
6025ef59e75Smrg Have it 4-byte cost. */
60381418a27Smrg return COSTS_N_INSNS (2);
6045ef59e75Smrg
6055ef59e75Smrg case CONST:
6065ef59e75Smrg /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
6075ef59e75Smrg Have it 4-byte cost. */
60881418a27Smrg return COSTS_N_INSNS (2);
6095ef59e75Smrg
6105ef59e75Smrg case REG:
6115ef59e75Smrg /* Simply return 4-byte costs. */
6125ef59e75Smrg return COSTS_N_INSNS (1);
6135ef59e75Smrg
6145ef59e75Smrg case PLUS:
6155ef59e75Smrg /* We do not need to check if the address is a legitimate address,
6165ef59e75Smrg because this hook is never called with an invalid address.
6175ef59e75Smrg But we better check the range of
6185ef59e75Smrg const_int value for cost, if it exists. */
6195ef59e75Smrg plus0 = XEXP (address, 0);
6205ef59e75Smrg plus1 = XEXP (address, 1);
6215ef59e75Smrg
6225ef59e75Smrg if (REG_P (plus0) && CONST_INT_P (plus1))
6235ef59e75Smrg {
6245ef59e75Smrg /* If it is possible to be lwi333/swi333 form,
6255ef59e75Smrg make it 2-byte cost. */
62681418a27Smrg if (satisfies_constraint_Iu03 (plus1))
6275ef59e75Smrg return (COSTS_N_INSNS (1) - 2);
6285ef59e75Smrg else
6295ef59e75Smrg return COSTS_N_INSNS (1);
6305ef59e75Smrg }
63181418a27Smrg if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
63281418a27Smrg return COSTS_N_INSNS (1) - 2;
63381418a27Smrg else if (REG_P (plus0) && REG_P (plus1))
63481418a27Smrg return COSTS_N_INSNS (1);
6355ef59e75Smrg
6365ef59e75Smrg /* For other 'plus' situation, make it cost 4-byte. */
6375ef59e75Smrg return COSTS_N_INSNS (1);
6385ef59e75Smrg
6395ef59e75Smrg default:
6405ef59e75Smrg break;
6415ef59e75Smrg }
6425ef59e75Smrg
6435ef59e75Smrg return COSTS_N_INSNS (4);
6445ef59e75Smrg }
6455ef59e75Smrg
64681418a27Smrg
nds32_address_cost_size_prefer(rtx address)64781418a27Smrg int nds32_address_cost_size_prefer (rtx address)
64881418a27Smrg {
64981418a27Smrg rtx plus0, plus1;
65081418a27Smrg enum rtx_code code;
65181418a27Smrg
65281418a27Smrg code = GET_CODE (address);
65381418a27Smrg
65481418a27Smrg switch (code)
65581418a27Smrg {
65681418a27Smrg case POST_MODIFY:
65781418a27Smrg case POST_INC:
65881418a27Smrg case POST_DEC:
65981418a27Smrg /* We encourage that rtx contains
66081418a27Smrg POST_MODIFY/POST_INC/POST_DEC behavior. */
66181418a27Smrg return 0;
66281418a27Smrg
66381418a27Smrg case SYMBOL_REF:
66481418a27Smrg /* We can have gp-relative load/store for symbol_ref.
66581418a27Smrg Have it 4-byte cost. */
66681418a27Smrg return COSTS_N_INSNS (2);
66781418a27Smrg
66881418a27Smrg case CONST:
66981418a27Smrg /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
67081418a27Smrg Have it 4-byte cost. */
67181418a27Smrg return COSTS_N_INSNS (2);
67281418a27Smrg
67381418a27Smrg case REG:
67481418a27Smrg /* Simply return 4-byte costs. */
67581418a27Smrg return COSTS_N_INSNS (1) - 1;
67681418a27Smrg
67781418a27Smrg case PLUS:
67881418a27Smrg /* We do not need to check if the address is a legitimate address,
67981418a27Smrg because this hook is never called with an invalid address.
68081418a27Smrg But we better check the range of
68181418a27Smrg const_int value for cost, if it exists. */
68281418a27Smrg plus0 = XEXP (address, 0);
68381418a27Smrg plus1 = XEXP (address, 1);
68481418a27Smrg
68581418a27Smrg if (REG_P (plus0) && CONST_INT_P (plus1))
68681418a27Smrg {
68781418a27Smrg /* If it is possible to be lwi333/swi333 form,
68881418a27Smrg make it 2-byte cost. */
68981418a27Smrg if (satisfies_constraint_Iu03 (plus1))
69081418a27Smrg return (COSTS_N_INSNS (1) - 2);
69181418a27Smrg else
69281418a27Smrg return COSTS_N_INSNS (1) - 1;
69381418a27Smrg }
69481418a27Smrg
69581418a27Smrg /* (plus (reg) (mult (reg) (const))) */
69681418a27Smrg if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
69781418a27Smrg return (COSTS_N_INSNS (1) - 1);
69881418a27Smrg
69981418a27Smrg /* For other 'plus' situation, make it cost 4-byte. */
70081418a27Smrg return COSTS_N_INSNS (1);
70181418a27Smrg
70281418a27Smrg default:
70381418a27Smrg break;
70481418a27Smrg }
70581418a27Smrg
70681418a27Smrg return COSTS_N_INSNS (4);
70781418a27Smrg
70881418a27Smrg }
70981418a27Smrg
nds32_address_cost_impl(rtx address,machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as ATTRIBUTE_UNUSED,bool speed_p)71081418a27Smrg int nds32_address_cost_impl (rtx address,
71181418a27Smrg machine_mode mode ATTRIBUTE_UNUSED,
71281418a27Smrg addr_space_t as ATTRIBUTE_UNUSED,
71381418a27Smrg bool speed_p)
71481418a27Smrg {
71581418a27Smrg if (speed_p)
71681418a27Smrg {
71781418a27Smrg if (current_pass->tv_id == TV_FWPROP)
71881418a27Smrg return nds32_address_cost_speed_fwprop (address);
71981418a27Smrg else
72081418a27Smrg return nds32_address_cost_speed_prefer (address);
72181418a27Smrg }
72281418a27Smrg else
72381418a27Smrg return nds32_address_cost_size_prefer (address);
72481418a27Smrg }
72581418a27Smrg
7265ef59e75Smrg /* ------------------------------------------------------------------------ */
727