aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonk Chiang <sh.chiang04@gmail.com>2018-03-03 16:05:25 +0000
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>2018-03-03 16:05:25 +0000
commit7a12ea32b2cf7ee53d0c43e26e12eb41e9853db1 (patch)
treef1ebb05bea89f7805a76ff8ed2289d81ebaa4f23
parentc8bd326c4794fc26b4385a5736dd72a721fd5983 (diff)
downloadgcc-7a12ea32b2cf7ee53d0c43e26e12eb41e9853db1.zip
gcc-7a12ea32b2cf7ee53d0c43e26e12eb41e9853db1.tar.gz
gcc-7a12ea32b2cf7ee53d0c43e26e12eb41e9853db1.tar.bz2
[NDS32] Rewrite infrastructure for intrinsic.
gcc/ * config/nds32/nds32-intrinsic.c (nds32_expand_builtin_null_ftype_reg): Delete. (nds32_expand_builtin_reg_ftype_imm): Ditto. (nds32_expand_builtin_null_ftype_reg_imm): Ditto. (nds32_read_argument): New. (nds32_legitimize_target): Ditto. (nds32_legitimize_argument): Ditto. (nds32_check_constant_argument): Ditto. (nds32_expand_unop_builtin): Ditto. (nds32_expand_unopimm_builtin): Ditto. (nds32_expand_binop_builtin): Ditto. (nds32_builtin_decl_impl): Ditto. (builtin_description): Ditto. (nds32_expand_builtin_impl): Rewrite with new infrastructure. (nds32_init_builtins_impl): Ditto. * config/nds32/nds32.c (TARGET_BUILTIN_DECL): Define. (nds32_builtin_decl): New. * config/nds32/nds32.h (nds32_builtins): Add NDS32_BUILTIN_COUNT. * config/nds32/nds32-protos.h (nds32_builtin_decl_impl): Declare. Co-Authored-By: Chung-Ju Wu <jasonwucj@gmail.com> Co-Authored-By: Kito Cheng <kito.cheng@gmail.com> From-SVN: r258211
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/config/nds32/nds32-intrinsic.c413
-rw-r--r--gcc/config/nds32/nds32-protos.h1
-rw-r--r--gcc/config/nds32/nds32.c10
-rw-r--r--gcc/config/nds32/nds32.h3
5 files changed, 312 insertions, 139 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ef80452..e5aa19d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2018-03-03 Monk Chiang <sh.chiang04@gmail.com>
+ Kito Cheng <kito.cheng@gmail.com>
+ Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * config/nds32/nds32-intrinsic.c
+ (nds32_expand_builtin_null_ftype_reg): Delete.
+ (nds32_expand_builtin_reg_ftype_imm): Ditto.
+ (nds32_expand_builtin_null_ftype_reg_imm): Ditto.
+ (nds32_read_argument): New.
+ (nds32_legitimize_target): Ditto.
+ (nds32_legitimize_argument): Ditto.
+ (nds32_check_constant_argument): Ditto.
+ (nds32_expand_unop_builtin): Ditto.
+ (nds32_expand_unopimm_builtin): Ditto.
+ (nds32_expand_binop_builtin): Ditto.
+ (nds32_builtin_decl_impl): Ditto.
+ (builtin_description): Ditto.
+ (nds32_expand_builtin_impl): Rewrite with new infrastructure.
+ (nds32_init_builtins_impl): Ditto.
+ * config/nds32/nds32.c (TARGET_BUILTIN_DECL): Define.
+ (nds32_builtin_decl): New.
+ * config/nds32/nds32.h (nds32_builtins): Add NDS32_BUILTIN_COUNT.
+ * config/nds32/nds32-protos.h (nds32_builtin_decl_impl): Declare.
+
2018-03-02 Jeff Law <law@redhat.com>
* reorg.c (stop_search_p): Handle DEBUG_INSN.
diff --git a/gcc/config/nds32/nds32-intrinsic.c b/gcc/config/nds32/nds32-intrinsic.c
index 5a1b92d..ad744c8 100644
--- a/gcc/config/nds32/nds32-intrinsic.c
+++ b/gcc/config/nds32/nds32-intrinsic.c
@@ -28,6 +28,8 @@
#include "backend.h"
#include "target.h"
#include "rtl.h"
+#include "memmodel.h"
+#include "emit-rtl.h"
#include "tree.h"
#include "memmodel.h"
#include "optabs.h" /* For GEN_FCN. */
@@ -35,202 +37,337 @@
#include "stor-layout.h"
#include "expr.h"
#include "langhooks.h" /* For add_builtin_function(). */
+#include "recog.h"
+#include "explow.h"
/* ------------------------------------------------------------------------ */
-/* Function to expand builtin function for
- '[(unspec_volatile [(reg)])]'. */
+/* Read the requested argument from the EXP given by INDEX.
+ Return the value as an rtx. */
static rtx
-nds32_expand_builtin_null_ftype_reg (enum insn_code icode,
- tree exp, rtx target)
+nds32_read_argument (tree exp, unsigned int index)
{
- /* Mapping:
- ops[0] <--> value0 <--> arg0 */
- struct expand_operand ops[1];
- tree arg0;
- rtx value0;
+ return expand_normal (CALL_EXPR_ARG (exp, index));
+}
- /* Grab the incoming arguments and extract its rtx. */
- arg0 = CALL_EXPR_ARG (exp, 0);
- value0 = expand_normal (arg0);
+/* Return a legitimate rtx for instruction ICODE's return value. Use TARGET
+ if it's not null, has the right mode, and satisfies operand 0's
+ predicate. */
+static rtx
+nds32_legitimize_target (enum insn_code icode, rtx target)
+{
+ enum machine_mode mode = insn_data[icode].operand[0].mode;
+
+ if (! target
+ || GET_MODE (target) != mode
+ || ! (*insn_data[icode].operand[0].predicate) (target, mode))
+ return gen_reg_rtx (mode);
+ else
+ return target;
+}
- /* Create operands. */
- create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
+/* Given that ARG is being passed as operand OPNUM to instruction ICODE,
+ check whether ARG satisfies the operand's constraints. If it doesn't,
+ copy ARG to a temporary register and return that. Otherwise return ARG
+ itself. */
+static rtx
+nds32_legitimize_argument (enum insn_code icode, int opnum, rtx arg)
+{
+ enum machine_mode mode = insn_data[icode].operand[opnum].mode;
- /* Emit new instruction. */
- if (!maybe_expand_insn (icode, 1, ops))
- error ("invalid argument to built-in function");
+ if ((*insn_data[icode].operand[opnum].predicate) (arg, mode))
+ return arg;
+ else if (VECTOR_MODE_P (mode) && CONST_INT_P (arg))
+ {
+ /* Handle CONST_INT covert to CONST_VECTOR. */
+ int nunits = GET_MODE_NUNITS (mode);
+ int i, shift = 0;
+ rtvec v = rtvec_alloc (nunits);
+ int val = INTVAL (arg);
+ enum machine_mode val_mode = (mode == V4QImode) ? QImode : HImode;
+ int shift_acc = (val_mode == QImode) ? 8 : 16;
+ int mask = (val_mode == QImode) ? 0xff : 0xffff;
+ int tmp_val = val;
+
+ if (TARGET_BIG_ENDIAN)
+ for (i = 0; i < nunits; i++)
+ {
+ tmp_val = (val >> shift) & mask;
+ RTVEC_ELT (v, nunits - i - 1) = gen_int_mode (tmp_val, val_mode);
+ shift += shift_acc;
+ }
+ else
+ for (i = 0; i < nunits; i++)
+ {
+ tmp_val = (val >> shift) & mask;
+ RTVEC_ELT (v, i) = gen_int_mode (tmp_val, val_mode);
+ shift += shift_acc;
+ }
+
+ return copy_to_mode_reg (mode, gen_rtx_CONST_VECTOR (mode, v));
+ }
+ else
+ {
+ rtx tmp_rtx = gen_reg_rtx (mode);
+ convert_move (tmp_rtx, arg, false);
+ return tmp_rtx;
+ }
+}
- return target;
+/* Return true if OPVAL can be used for operand OPNUM of instruction ICODE.
+ The instruction should require a constant operand of some sort. The
+ function prints an error if OPVAL is not valid. */
+static int
+nds32_check_constant_argument (enum insn_code icode, int opnum, rtx opval,
+ const char *name)
+{
+ if (GET_CODE (opval) != CONST_INT)
+ {
+ error ("invalid argument to built-in function %s", name);
+ return false;
+ }
+ if (! (*insn_data[icode].operand[opnum].predicate) (opval, VOIDmode))
+ {
+ error ("constant argument out of range for %s", name);
+
+ return false;
+ }
+ return true;
}
-/* Function to expand builtin function for
- '[(set (reg) (unspec_volatile [(imm)]))]'. */
+/* Expand builtins that take one operand. */
static rtx
-nds32_expand_builtin_reg_ftype_imm (enum insn_code icode,
- tree exp, rtx target)
+nds32_expand_unop_builtin (enum insn_code icode, tree exp, rtx target,
+ bool return_p)
{
- /* Mapping:
- ops[0] <--> target <--> exp
- ops[1] <--> value0 <--> arg0 */
- struct expand_operand ops[2];
- tree arg0;
- rtx value0;
+ rtx pat;
+ rtx op0 = nds32_read_argument (exp, 0);
+ int op0_num = return_p ? 1 : 0;
+
+ if (return_p)
+ target = nds32_legitimize_target (icode, target);
- /* Grab the incoming arguments and extract its rtx. */
- arg0 = CALL_EXPR_ARG (exp, 0);
- value0 = expand_normal (arg0);
+ op0 = nds32_legitimize_argument (icode, op0_num, op0);
- /* Create operands. */
- create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
- create_input_operand (&ops[1], value0, TYPE_MODE (TREE_TYPE (arg0)));
+ /* Emit and return the new instruction. */
+ if (return_p)
+ pat = GEN_FCN (icode) (target, op0);
+ else
+ pat = GEN_FCN (icode) (op0);
- /* Emit new instruction. */
- if (!maybe_expand_insn (icode, 2, ops))
- error ("invalid argument to built-in function");
+ if (! pat)
+ return NULL_RTX;
+ emit_insn (pat);
return target;
}
-/* Function to expand builtin function for
- '[(unspec_volatile [(reg) (imm)])]' pattern. */
+/* Expand builtins that take one operands and the first is immediate. */
static rtx
-nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode,
- tree exp, rtx target)
+nds32_expand_unopimm_builtin (enum insn_code icode, tree exp, rtx target,
+ bool return_p, const char *name)
{
- /* Mapping:
- ops[0] <--> value0 <--> arg0
- ops[1] <--> value1 <--> arg1 */
- struct expand_operand ops[2];
- tree arg0, arg1;
- rtx value0, value1;
-
- /* Grab the incoming arguments and extract its rtx. */
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
- value0 = expand_normal (arg0);
- value1 = expand_normal (arg1);
-
- /* Create operands. */
- create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
- create_input_operand (&ops[1], value1, TYPE_MODE (TREE_TYPE (arg1)));
-
- /* Emit new instruction. */
- if (!maybe_expand_insn (icode, 2, ops))
- error ("invalid argument to built-in function");
+ rtx pat;
+ rtx op0 = nds32_read_argument (exp, 0);
+ int op0_num = return_p ? 1 : 0;
+
+ if (return_p)
+ target = nds32_legitimize_target (icode, target);
+
+ if (!nds32_check_constant_argument (icode, op0_num, op0, name))
+ return NULL_RTX;
+
+ op0 = nds32_legitimize_argument (icode, op0_num, op0);
+
+ /* Emit and return the new instruction. */
+ if (return_p)
+ pat = GEN_FCN (icode) (target, op0);
+ else
+ pat = GEN_FCN (icode) (op0);
+ if (! pat)
+ return NULL_RTX;
+
+ emit_insn (pat);
return target;
}
-/* ------------------------------------------------------------------------ */
-
-void
-nds32_init_builtins_impl (void)
+/* Expand builtins that take two operands. */
+static rtx
+nds32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target,
+ bool return_p)
{
- tree pointer_type_node = build_pointer_type (integer_type_node);
+ rtx pat;
+ rtx op0 = nds32_read_argument (exp, 0);
+ rtx op1 = nds32_read_argument (exp, 1);
+ int op0_num = return_p ? 1 : 0;
+ int op1_num = return_p ? 2 : 1;
- tree void_ftype_void = build_function_type (void_type_node,
- void_list_node);
+ if (return_p)
+ target = nds32_legitimize_target (icode, target);
- tree void_ftype_pint = build_function_type_list (void_type_node,
- pointer_type_node,
- NULL_TREE);
+ op0 = nds32_legitimize_argument (icode, op0_num, op0);
+ op1 = nds32_legitimize_argument (icode, op1_num, op1);
- tree int_ftype_int = build_function_type_list (integer_type_node,
- integer_type_node,
- NULL_TREE);
+ /* Emit and return the new instruction. */
+ if (return_p)
+ pat = GEN_FCN (icode) (target, op0, op1);
+ else
+ pat = GEN_FCN (icode) (op0, op1);
- tree void_ftype_int_int = build_function_type_list (void_type_node,
- integer_type_node,
- integer_type_node,
- NULL_TREE);
+ if (! pat)
+ return NULL_RTX;
- /* Cache. */
- add_builtin_function ("__builtin_nds32_isync", void_ftype_pint,
- NDS32_BUILTIN_ISYNC,
- BUILT_IN_MD, NULL, NULL_TREE);
- add_builtin_function ("__builtin_nds32_isb", void_ftype_void,
- NDS32_BUILTIN_ISB,
- BUILT_IN_MD, NULL, NULL_TREE);
+ emit_insn (pat);
+ return target;
+}
- /* Register Transfer. */
- add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int,
- NDS32_BUILTIN_MFSR,
- BUILT_IN_MD, NULL, NULL_TREE);
- add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int,
- NDS32_BUILTIN_MFUSR,
- BUILT_IN_MD, NULL, NULL_TREE);
- add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int,
- NDS32_BUILTIN_MTSR,
- BUILT_IN_MD, NULL, NULL_TREE);
- add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int,
- NDS32_BUILTIN_MTUSR,
- BUILT_IN_MD, NULL, NULL_TREE);
+struct builtin_description
+{
+ const enum insn_code icode;
+ const char *name;
+ enum nds32_builtins code;
+ bool return_p;
+};
+
+#define NDS32_BUILTIN(code, string, builtin) \
+ { CODE_FOR_##code, "__nds32__" string, \
+ NDS32_BUILTIN_##builtin, true },
+
+#define NDS32_NO_TARGET_BUILTIN(code, string, builtin) \
+ { CODE_FOR_##code, "__nds32__" string, \
+ NDS32_BUILTIN_##builtin, false },
+
+/* Intrinsics that take just one argument. */
+static struct builtin_description bdesc_1arg[] =
+{
+ NDS32_NO_TARGET_BUILTIN(unspec_volatile_isync, "isync", ISYNC)
+};
- /* Interrupt. */
- add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void,
- NDS32_BUILTIN_SETGIE_EN,
- BUILT_IN_MD, NULL, NULL_TREE);
- add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void,
- NDS32_BUILTIN_SETGIE_DIS,
- BUILT_IN_MD, NULL, NULL_TREE);
-}
+/* Intrinsics that take just one argument. and the argument is immediate. */
+static struct builtin_description bdesc_1argimm[] =
+{
+ NDS32_BUILTIN(unspec_volatile_mfsr, "mfsr", MFSR)
+ NDS32_BUILTIN(unspec_volatile_mfusr, "mfsr", MFUSR)
+};
+/* Intrinsics that take two arguments. */
+static struct builtin_description bdesc_2arg[] =
+{
+ NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtsr, "mtsr", MTSR)
+ NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtusr, "mtusr", MTUSR)
+};
rtx
nds32_expand_builtin_impl (tree exp,
rtx target,
rtx subtarget ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned i;
+ struct builtin_description *d;
- int fcode = DECL_FUNCTION_CODE (fndecl);
-
+ /* Since there are no result and operands, we can simply emit this rtx. */
switch (fcode)
{
- /* Cache. */
- case NDS32_BUILTIN_ISYNC:
- return nds32_expand_builtin_null_ftype_reg
- (CODE_FOR_unspec_volatile_isync, exp, target);
case NDS32_BUILTIN_ISB:
- /* Since there are no result and operands for isb instruciton,
- we can simply emit this rtx. */
emit_insn (gen_unspec_volatile_isb ());
return target;
-
- /* Register Transfer. */
- case NDS32_BUILTIN_MFSR:
- return nds32_expand_builtin_reg_ftype_imm
- (CODE_FOR_unspec_volatile_mfsr, exp, target);
- case NDS32_BUILTIN_MFUSR:
- return nds32_expand_builtin_reg_ftype_imm
- (CODE_FOR_unspec_volatile_mfusr, exp, target);
- case NDS32_BUILTIN_MTSR:
- return nds32_expand_builtin_null_ftype_reg_imm
- (CODE_FOR_unspec_volatile_mtsr, exp, target);
- case NDS32_BUILTIN_MTUSR:
- return nds32_expand_builtin_null_ftype_reg_imm
- (CODE_FOR_unspec_volatile_mtusr, exp, target);
-
- /* Interrupt. */
case NDS32_BUILTIN_SETGIE_EN:
- /* Since there are no result and operands for setgie.e instruciton,
- we can simply emit this rtx. */
emit_insn (gen_unspec_volatile_setgie_en ());
return target;
case NDS32_BUILTIN_SETGIE_DIS:
- /* Since there are no result and operands for setgie.d instruciton,
- we can simply emit this rtx. */
emit_insn (gen_unspec_volatile_setgie_dis ());
return target;
-
default:
- gcc_unreachable ();
+ break;
}
+ /* Expand groups of builtins. */
+ for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
+ if (d->code == fcode)
+ return nds32_expand_unop_builtin (d->icode, exp, target, d->return_p);
+
+ for (i = 0, d = bdesc_1argimm; i < ARRAY_SIZE (bdesc_1argimm); i++, d++)
+ if (d->code == fcode)
+ return nds32_expand_unopimm_builtin (d->icode, exp, target,
+ d->return_p, d->name);
+
+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
+ if (d->code == fcode)
+ return nds32_expand_binop_builtin (d->icode, exp, target, d->return_p);
+
+
return NULL_RTX;
}
-/* ------------------------------------------------------------------------ */
+static GTY(()) tree nds32_builtin_decls[NDS32_BUILTIN_COUNT];
+
+/* Return the NDS32 builtin for CODE. */
+tree
+nds32_builtin_decl_impl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+{
+ if (code >= NDS32_BUILTIN_COUNT)
+ return error_mark_node;
+
+ return nds32_builtin_decls[code];
+}
+
+void
+nds32_init_builtins_impl (void)
+{
+#define ADD_NDS32_BUILTIN0(NAME, RET_TYPE, CODE) \
+ nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \
+ add_builtin_function ("__builtin_nds32_" NAME, \
+ build_function_type_list (RET_TYPE##_type_node, \
+ NULL_TREE), \
+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
+
+#define ADD_NDS32_BUILTIN1(NAME, RET_TYPE, ARG_TYPE, CODE) \
+ nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \
+ add_builtin_function ("__builtin_nds32_" NAME, \
+ build_function_type_list (RET_TYPE##_type_node, \
+ ARG_TYPE##_type_node, \
+ NULL_TREE), \
+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
+
+#define ADD_NDS32_BUILTIN2(NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2, CODE) \
+ nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \
+ add_builtin_function ("__builtin_nds32_" NAME, \
+ build_function_type_list (RET_TYPE##_type_node, \
+ ARG_TYPE1##_type_node,\
+ ARG_TYPE2##_type_node,\
+ NULL_TREE), \
+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
+
+#define ADD_NDS32_BUILTIN3(NAME, RET_TYPE, \
+ ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, CODE) \
+ nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \
+ add_builtin_function ("__builtin_nds32_" NAME, \
+ build_function_type_list (RET_TYPE##_type_node, \
+ ARG_TYPE1##_type_node,\
+ ARG_TYPE2##_type_node,\
+ ARG_TYPE3##_type_node,\
+ NULL_TREE), \
+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
+
+ /* Looking for return type and argument can be found in tree.h file. */
+ tree ptr_uint_type_node = build_pointer_type (unsigned_type_node);
+
+ /* Cache. */
+ ADD_NDS32_BUILTIN1 ("isync", void, ptr_uint, ISYNC);
+ ADD_NDS32_BUILTIN0 ("isb", void, ISB);
+
+ /* Register Transfer. */
+ ADD_NDS32_BUILTIN1 ("mfsr", unsigned, integer, MFSR);
+ ADD_NDS32_BUILTIN1 ("mfusr", unsigned, integer, MFUSR);
+ ADD_NDS32_BUILTIN2 ("mtsr", void, unsigned, integer, MTSR);
+ ADD_NDS32_BUILTIN2 ("mtusr", void, unsigned, integer, MTUSR);
+
+ /* Interrupt. */
+ ADD_NDS32_BUILTIN0 ("setgie_en", void, SETGIE_EN);
+ ADD_NDS32_BUILTIN0 ("setgie_dis", void, SETGIE_DIS);
+}
diff --git a/gcc/config/nds32/nds32-protos.h b/gcc/config/nds32/nds32-protos.h
index 7549613..a989c3f 100644
--- a/gcc/config/nds32/nds32-protos.h
+++ b/gcc/config/nds32/nds32-protos.h
@@ -125,6 +125,7 @@ extern int nds32_target_alignment (rtx_insn *);
extern void nds32_init_builtins_impl (void);
extern rtx nds32_expand_builtin_impl (tree, rtx, rtx,
machine_mode, int);
+extern tree nds32_builtin_decl_impl (unsigned, bool);
/* Auxiliary functions for ISR implementation. */
diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c
index 08331f3..085a7b8 100644
--- a/gcc/config/nds32/nds32.c
+++ b/gcc/config/nds32/nds32.c
@@ -2728,6 +2728,13 @@ nds32_init_builtins (void)
nds32_init_builtins_impl ();
}
+static tree
+nds32_builtin_decl (unsigned code, bool initialize_p)
+{
+ /* Implement in nds32-intrinsic.c. */
+ return nds32_builtin_decl_impl (code, initialize_p);
+}
+
static rtx
nds32_expand_builtin (tree exp,
rtx target,
@@ -3825,6 +3832,9 @@ nds32_target_alignment (rtx_insn *label)
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS nds32_init_builtins
+#undef TARGET_BUILTIN_DECL
+#define TARGET_BUILTIN_DECL nds32_builtin_decl
+
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN nds32_expand_builtin
diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h
index 66f692a..5b33e3c 100644
--- a/gcc/config/nds32/nds32.h
+++ b/gcc/config/nds32/nds32.h
@@ -345,7 +345,8 @@ enum nds32_builtins
NDS32_BUILTIN_MTSR,
NDS32_BUILTIN_MTUSR,
NDS32_BUILTIN_SETGIE_EN,
- NDS32_BUILTIN_SETGIE_DIS
+ NDS32_BUILTIN_SETGIE_DIS,
+ NDS32_BUILTIN_COUNT
};
/* ------------------------------------------------------------------------ */