aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorChung-Ju Wu <jasonwucj@gmail.com>2018-04-01 10:07:40 +0000
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>2018-04-01 10:07:40 +0000
commitc4d8d0502ef162362e3fcb2fd249ce92b2fd031d (patch)
tree915ac14e84f80b187e396843dc44e8e84449d4a2 /gcc
parentaf08e51d09f41630023466e7135217ffd43f96c7 (diff)
downloadgcc-c4d8d0502ef162362e3fcb2fd249ce92b2fd031d.zip
gcc-c4d8d0502ef162362e3fcb2fd249ce92b2fd031d.tar.gz
gcc-c4d8d0502ef162362e3fcb2fd249ce92b2fd031d.tar.bz2
[NDS32] Add relax optimization as new pass.
gcc/ * config.gcc (nds32): Add nds32-relax-opt.o into extra_objs. * config/nds32/constants.md (unspec_volatile_element): Add UNSPEC_VOLATILE_RELAX_GROUP. * config/nds32/nds32-relax-opt.c: New file. * config/nds32/nds32-predicates.c (nds32_symbol_load_store_p): New function. * config/nds32/nds32-protos.h (nds32_symbol_load_store_p): Declare function. (make_pass_nds32_relax_opt): Declare new rtl pass function. * config/nds32/nds32.c (nds32_register_pass): New function to register pass. (nds32_register_passes): New function to register passes. * config/nds32/nds32.md (relax_group): New pattern. * config/nds32/nds32.opt (mrelax-hint): New option. * config/nds32/t-nds32 (nds32-relax-opt.o): New dependency. Co-Authored-By: Kito Cheng <kito.cheng@gmail.com> Co-Authored-By: Kuan-Lin Chen <kuanlinchentw@gmail.com> From-SVN: r258998
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config.gcc2
-rw-r--r--gcc/config/nds32/constants.md2
-rw-r--r--gcc/config/nds32/nds32-predicates.c34
-rw-r--r--gcc/config/nds32/nds32-protos.h5
-rw-r--r--gcc/config/nds32/nds32-relax-opt.c324
-rw-r--r--gcc/config/nds32/nds32.c34
-rw-r--r--gcc/config/nds32/nds32.md13
-rw-r--r--gcc/config/nds32/nds32.opt4
-rw-r--r--gcc/config/nds32/t-nds3213
10 files changed, 447 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 41b0da5..29c82d9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,23 @@
+2018-04-01 Chung-Ju Wu <jasonwucj@gmail.com>
+ Kito Cheng <kito.cheng@gmail.com>
+ Kuan-Lin Chen <kuanlinchentw@gmail.com>
+
+ * config.gcc (nds32): Add nds32-relax-opt.o into extra_objs.
+ * config/nds32/constants.md (unspec_volatile_element): Add
+ UNSPEC_VOLATILE_RELAX_GROUP.
+ * config/nds32/nds32-relax-opt.c: New file.
+ * config/nds32/nds32-predicates.c
+ (nds32_symbol_load_store_p): New function.
+ * config/nds32/nds32-protos.h
+ (nds32_symbol_load_store_p): Declare function.
+ (make_pass_nds32_relax_opt): Declare new rtl pass function.
+ * config/nds32/nds32.c
+ (nds32_register_pass): New function to register pass.
+ (nds32_register_passes): New function to register passes.
+ * config/nds32/nds32.md (relax_group): New pattern.
+ * config/nds32/nds32.opt (mrelax-hint): New option.
+ * config/nds32/t-nds32 (nds32-relax-opt.o): New dependency.
+
2018-04-01 Kito Cheng <kito.cheng@gmail.com>
* config/nds32/t-nds32: Modify files dependency.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 1b58c06..b8a9877 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -445,7 +445,7 @@ mips*-*-*)
nds32*)
cpu_type=nds32
extra_headers="nds32_intrinsic.h"
- extra_objs="nds32-cost.o nds32-intrinsic.o nds32-isr.o nds32-md-auxiliary.o nds32-pipelines-auxiliary.o nds32-predicates.o nds32-memory-manipulation.o nds32-fp-as-gp.o"
+ extra_objs="nds32-cost.o nds32-intrinsic.o nds32-isr.o nds32-md-auxiliary.o nds32-pipelines-auxiliary.o nds32-predicates.o nds32-memory-manipulation.o nds32-fp-as-gp.o nds32-relax-opt.o"
;;
nios2-*-*)
cpu_type=nios2
diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md
index 482e39e..77fb71c 100644
--- a/gcc/config/nds32/constants.md
+++ b/gcc/config/nds32/constants.md
@@ -53,6 +53,8 @@
UNSPEC_VOLATILE_MTUSR
UNSPEC_VOLATILE_SETGIE_EN
UNSPEC_VOLATILE_SETGIE_DIS
+
+ UNSPEC_VOLATILE_RELAX_GROUP
UNSPEC_VOLATILE_POP25_RETURN
])
diff --git a/gcc/config/nds32/nds32-predicates.c b/gcc/config/nds32/nds32-predicates.c
index c54eefb..c313efc 100644
--- a/gcc/config/nds32/nds32-predicates.c
+++ b/gcc/config/nds32/nds32-predicates.c
@@ -35,6 +35,7 @@
#include "emit-rtl.h"
#include "recog.h"
#include "tm-constrs.h"
+#include "insn-attr.h"
/* ------------------------------------------------------------------------ */
@@ -414,4 +415,37 @@ nds32_can_use_bitci_p (int ival)
&& satisfies_constraint_Iu15 (gen_int_mode (~ival, SImode)));
}
+/* Return true if is load/store with SYMBOL_REF addressing mode
+ and memory mode is SImode. */
+bool
+nds32_symbol_load_store_p (rtx_insn *insn)
+{
+ rtx mem_src = NULL_RTX;
+
+ switch (get_attr_type (insn))
+ {
+ case TYPE_LOAD:
+ mem_src = SET_SRC (PATTERN (insn));
+ break;
+ case TYPE_STORE:
+ mem_src = SET_DEST (PATTERN (insn));
+ break;
+ default:
+ break;
+ }
+
+ /* Find load/store insn with addressing mode is SYMBOL_REF. */
+ if (mem_src != NULL_RTX)
+ {
+ if ((GET_CODE (mem_src) == ZERO_EXTEND)
+ || (GET_CODE (mem_src) == SIGN_EXTEND))
+ mem_src = XEXP (mem_src, 0);
+
+ if ((GET_CODE (XEXP (mem_src, 0)) == SYMBOL_REF)
+ || (GET_CODE (XEXP (mem_src, 0)) == LO_SUM))
+ return true;
+ }
+
+ return false;
+}
/* ------------------------------------------------------------------------ */
diff --git a/gcc/config/nds32/nds32-protos.h b/gcc/config/nds32/nds32-protos.h
index 6110500..1387cca 100644
--- a/gcc/config/nds32/nds32-protos.h
+++ b/gcc/config/nds32/nds32-protos.h
@@ -109,6 +109,8 @@ extern int nds32_adjust_insn_length (rtx_insn *, int);
extern int nds32_fp_as_gp_check_available (void);
+extern bool nds32_symbol_load_store_p (rtx_insn *);
+
/* Auxiliary functions for jump table generation. */
extern const char *nds32_output_casesi_pc_relative (rtx *);
@@ -164,4 +166,7 @@ extern int nds32_address_cost_impl (rtx, machine_mode, addr_space_t, bool);
/* Auxiliary functions for pre-define marco. */
extern void nds32_cpu_cpp_builtins(struct cpp_reader *);
+/* Functions for create nds32 specific optimization pass. */
+extern rtl_opt_pass *make_pass_nds32_relax_opt (gcc::context *);
+
/* ------------------------------------------------------------------------ */
diff --git a/gcc/config/nds32/nds32-relax-opt.c b/gcc/config/nds32/nds32-relax-opt.c
new file mode 100644
index 0000000..0349be4
--- /dev/null
+++ b/gcc/config/nds32/nds32-relax-opt.c
@@ -0,0 +1,324 @@
+/* relax-opt pass of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2018 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 "stringpool.h"
+#include "attribs.h"
+#include "df.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "optabs.h" /* For GEN_FCN. */
+#include "regs.h"
+#include "emit-rtl.h"
+#include "recog.h"
+#include "diagnostic-core.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "calls.h"
+#include "output.h"
+#include "explow.h"
+#include "expr.h"
+#include "tm-constrs.h"
+#include "builtins.h"
+#include "cpplib.h"
+#include "insn-attr.h"
+#include "cfgrtl.h"
+#include "tree-pass.h"
+
+/* This is used to create unique relax hint id value.
+ The initial value is 0. */
+static int relax_group_id = 0;
+
+/* Group the following pattern as relax candidates:
+
+ 1. sethi $ra, hi20(sym)
+ ori $ra, $ra, lo12(sym)
+ ==>
+ addi.gp $ra, sym
+
+ 2. sethi $ra, hi20(sym)
+ lwi $rb, [$ra + lo12(sym)]
+ ==>
+ lwi.gp $rb, [(sym)]
+
+ 3. sethi $ra, hi20(sym)
+ ori $ra, $ra, lo12(sym)
+ lwi $rb, [$ra]
+ swi $rc, [$ra]
+ ==>
+ lwi37 $rb, [(sym)]
+ swi37 $rc, [(sym)] */
+
+/* Return true if is load/store with REG addressing mode
+ and memory mode is SImode. */
+static bool
+nds32_reg_base_load_store_p (rtx_insn *insn)
+{
+ rtx mem_src = NULL_RTX;
+
+ switch (get_attr_type (insn))
+ {
+ case TYPE_LOAD:
+ mem_src = SET_SRC (PATTERN (insn));
+ break;
+ case TYPE_STORE:
+ mem_src = SET_DEST (PATTERN (insn));
+ break;
+ default:
+ break;
+ }
+
+ /* Find load/store insn with addressing mode is REG. */
+ if (mem_src != NULL_RTX)
+ {
+ if ((GET_CODE (mem_src) == ZERO_EXTEND)
+ || (GET_CODE (mem_src) == SIGN_EXTEND))
+ mem_src = XEXP (mem_src, 0);
+
+ if (GET_CODE (XEXP (mem_src, 0)) == REG)
+ return true;
+ }
+
+ return false;
+}
+
+/* Return true if insn is a sp/fp base or sp/fp plus load-store instruction. */
+
+static bool
+nds32_sp_base_or_plus_load_store_p (rtx_insn *insn)
+{
+ rtx mem_src = NULL_RTX;
+
+ switch (get_attr_type (insn))
+ {
+ case TYPE_LOAD:
+ mem_src = SET_SRC (PATTERN (insn));
+ break;
+ case TYPE_STORE:
+ mem_src = SET_DEST (PATTERN (insn));
+ break;
+ default:
+ break;
+ }
+ /* Find load/store insn with addressing mode is REG. */
+ if (mem_src != NULL_RTX)
+ {
+ if ((GET_CODE (mem_src) == ZERO_EXTEND)
+ || (GET_CODE (mem_src) == SIGN_EXTEND))
+ mem_src = XEXP (mem_src, 0);
+
+ if ((GET_CODE (XEXP (mem_src, 0)) == PLUS))
+ mem_src = XEXP (mem_src, 0);
+
+ if (REG_P (XEXP (mem_src, 0))
+ && ((frame_pointer_needed
+ && REGNO (XEXP (mem_src, 0)) == FP_REGNUM)
+ || REGNO (XEXP (mem_src, 0)) == SP_REGNUM))
+ return true;
+ }
+
+ return false;
+}
+
+/* Return true if is load with [REG + REG/CONST_INT] addressing mode. */
+static bool
+nds32_plus_reg_load_store_p (rtx_insn *insn)
+{
+ rtx mem_src = NULL_RTX;
+
+ switch (get_attr_type (insn))
+ {
+ case TYPE_LOAD:
+ mem_src = SET_SRC (PATTERN (insn));
+ break;
+ case TYPE_STORE:
+ mem_src = SET_DEST (PATTERN (insn));
+ break;
+ default:
+ break;
+ }
+
+ /* Find load/store insn with addressing mode is [REG + REG/CONST]. */
+ if (mem_src != NULL_RTX)
+ {
+ if ((GET_CODE (mem_src) == ZERO_EXTEND)
+ || (GET_CODE (mem_src) == SIGN_EXTEND))
+ mem_src = XEXP (mem_src, 0);
+
+ if ((GET_CODE (XEXP (mem_src, 0)) == PLUS))
+ mem_src = XEXP (mem_src, 0);
+ else
+ return false;
+
+ if (GET_CODE (XEXP (mem_src, 0)) == REG)
+ return true;
+
+ }
+
+ return false;
+}
+
+/* Group the relax candidates with group id. */
+static void
+nds32_group_insns (rtx sethi)
+{
+ df_ref def_record, use_record;
+ df_link *link;
+ rtx_insn *use_insn = NULL;
+ rtx group_id;
+
+ def_record = DF_INSN_DEFS (sethi);
+
+ for (link = DF_REF_CHAIN (def_record); link; link = link->next)
+ {
+ if (!DF_REF_INSN_INFO (link->ref))
+ continue;
+
+ use_insn = DF_REF_INSN (link->ref);
+
+ /* Skip if define insn and use insn not in the same basic block. */
+ if (!dominated_by_p (CDI_DOMINATORS,
+ BLOCK_FOR_INSN (use_insn),
+ BLOCK_FOR_INSN (sethi)))
+ return;
+
+ /* Skip if the low-part used register is from different high-part
+ instructions. */
+ use_record = DF_INSN_USES (use_insn);
+ if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next)
+ return;
+
+ /* Skip if use_insn not active insn. */
+ if (!active_insn_p (use_insn))
+ return;
+
+ /* Initial use_insn_type. */
+ if (!(recog_memoized (use_insn) == CODE_FOR_lo_sum
+ || nds32_symbol_load_store_p (use_insn)
+ || (nds32_reg_base_load_store_p (use_insn)
+ &&!nds32_sp_base_or_plus_load_store_p (use_insn))))
+ return;
+ }
+
+ group_id = GEN_INT (relax_group_id);
+ /* Insert .relax_* directive for sethi. */
+ emit_insn_before (gen_relax_group (group_id), sethi);
+
+ /* Scan the use insns and insert the directive. */
+ for (link = DF_REF_CHAIN (def_record); link; link = link->next)
+ {
+ if (!DF_REF_INSN_INFO (link->ref))
+ continue;
+
+ use_insn = DF_REF_INSN (link->ref);
+
+ /* Insert .relax_* directive. */
+ if (active_insn_p (use_insn))
+ emit_insn_before (gen_relax_group (group_id), use_insn);
+ }
+
+ relax_group_id++;
+}
+
+/* Group the relax candidate instructions for linker. */
+static void
+nds32_relax_group (void)
+{
+ rtx_insn *insn;
+
+ compute_bb_for_insn ();
+
+ df_chain_add_problem (DF_DU_CHAIN | DF_UD_CHAIN);
+ df_insn_rescan_all ();
+ df_analyze ();
+ df_set_flags (DF_DEFER_INSN_RESCAN);
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ insn = get_insns ();
+ gcc_assert (NOTE_P (insn));
+
+ for (insn = next_active_insn (insn); insn; insn = next_active_insn (insn))
+ {
+ if (NONJUMP_INSN_P (insn))
+ {
+ /* Find sethi ra, symbol instruction. */
+ if (recog_memoized (insn) == CODE_FOR_sethi
+ && nds32_symbolic_operand (XEXP (SET_SRC (PATTERN (insn)), 0),
+ SImode))
+ nds32_group_insns (insn);
+ }
+ }
+
+ /* We must call df_finish_pass manually because it should be invoked before
+ BB information is destroyed. Hence we cannot set the TODO_df_finish flag
+ to the pass manager. */
+ df_insn_rescan_all ();
+ df_finish_pass (false);
+ free_dominance_info (CDI_DOMINATORS);
+}
+
+static unsigned int
+nds32_relax_opt (void)
+{
+ if (TARGET_RELAX_HINT)
+ nds32_relax_group ();
+ return 1;
+}
+
+const pass_data pass_data_nds32_relax_opt =
+{
+ RTL_PASS, /* type */
+ "relax_opt", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_MACH_DEP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_df_finish, /* todo_flags_finish */
+};
+
+class pass_nds32_relax_opt : public rtl_opt_pass
+{
+public:
+ pass_nds32_relax_opt (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_nds32_relax_opt, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate (function *) { return TARGET_RELAX_HINT; }
+ unsigned int execute (function *) { return nds32_relax_opt (); }
+};
+
+rtl_opt_pass *
+make_pass_nds32_relax_opt (gcc::context *ctxt)
+{
+ return new pass_nds32_relax_opt (ctxt);
+}
diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c
index f405ea1..bdbff14 100644
--- a/gcc/config/nds32/nds32.c
+++ b/gcc/config/nds32/nds32.c
@@ -29,6 +29,7 @@
#include "target.h"
#include "rtl.h"
#include "tree.h"
+#include "tree-pass.h"
#include "stringpool.h"
#include "attribs.h"
#include "df.h"
@@ -48,6 +49,7 @@
#include "tm-constrs.h"
#include "builtins.h"
#include "cpplib.h"
+#include "context.h"
/* This file should be included last. */
#include "target-def.h"
@@ -1227,6 +1229,36 @@ nds32_legitimate_index_p (machine_mode outer_mode,
}
}
+static void
+nds32_register_pass (
+ rtl_opt_pass *(*make_pass_func) (gcc::context *),
+ enum pass_positioning_ops pass_pos,
+ const char *ref_pass_name)
+{
+ opt_pass *new_opt_pass = make_pass_func (g);
+
+ struct register_pass_info insert_pass =
+ {
+ new_opt_pass, /* pass */
+ ref_pass_name, /* reference_pass_name */
+ 1, /* ref_pass_instance_number */
+ pass_pos /* po_op */
+ };
+
+ register_pass (&insert_pass);
+}
+
+/* This function is called from nds32_option_override ().
+ All new passes should be registered here. */
+static void
+nds32_register_passes (void)
+{
+ nds32_register_pass (
+ make_pass_nds32_relax_opt,
+ PASS_POS_INSERT_AFTER,
+ "mach");
+}
+
/* ------------------------------------------------------------------------ */
/* PART 3: Implement target hook stuff definitions. */
@@ -2776,6 +2808,8 @@ nds32_option_override (void)
/* Currently, we don't support PIC code generation yet. */
if (flag_pic)
sorry ("position-independent code not supported");
+
+ nds32_register_passes ();
}
diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md
index 58a13c1..e9bd791 100644
--- a/gcc/config/nds32/nds32.md
+++ b/gcc/config/nds32/nds32.md
@@ -179,7 +179,7 @@
;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
;; are able to match such instruction template.
-(define_insn "*move_addr"
+(define_insn "move_addr"
[(set (match_operand:SI 0 "register_operand" "=l, r")
(match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
""
@@ -188,7 +188,7 @@
(set_attr "length" "8")])
-(define_insn "*sethi"
+(define_insn "sethi"
[(set (match_operand:SI 0 "register_operand" "=r")
(high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
""
@@ -197,7 +197,7 @@
(set_attr "length" "4")])
-(define_insn "*lo_sum"
+(define_insn "lo_sum"
[(set (match_operand:SI 0 "register_operand" "=r")
(lo_sum:SI (match_operand:SI 1 "register_operand" " r")
(match_operand:SI 2 "nds32_symbolic_operand" " i")))]
@@ -2370,6 +2370,13 @@ create_template:
;; Pseudo NOPs
+(define_insn "relax_group"
+ [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
+ ""
+ ".relax_hint %0"
+ [(set_attr "length" "0")]
+)
+
(define_insn "pop25return"
[(return)
(unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
diff --git a/gcc/config/nds32/nds32.opt b/gcc/config/nds32/nds32.opt
index 876e841..d6d2f20 100644
--- a/gcc/config/nds32/nds32.opt
+++ b/gcc/config/nds32/nds32.opt
@@ -77,6 +77,10 @@ m16-bit
Target Report Mask(16_BIT)
Generate 16-bit instructions.
+mrelax-hint
+Target Report Mask(RELAX_HINT)
+Insert relax hint for linker to do relaxation.
+
mvh
Target Report Mask(VH)
Enable Virtual Hosting support.
diff --git a/gcc/config/nds32/t-nds32 b/gcc/config/nds32/t-nds32
index e2055ad..0f1c385 100644
--- a/gcc/config/nds32/t-nds32
+++ b/gcc/config/nds32/t-nds32
@@ -118,3 +118,16 @@ nds32-fp-as-gp.o: \
intl.h libfuncs.h $(PARAMS_H) $(OPTS_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/nds32/nds32-fp-as-gp.c
+
+nds32-relax-opt.o: \
+ $(srcdir)/config/nds32/nds32-relax-opt.c \
+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
+ insn-config.h conditions.h output.h dumpfile.h \
+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \
+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \
+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \
+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \
+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/nds32/nds32-relax-opt.c