1 /* Intrinsic functions of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
23 #define IN_TARGET_CODE 1
27 #include "coretypes.h"
33 #include "optabs.h" /* For GEN_FCN. */
34 #include "diagnostic-core.h"
35 #include "stor-layout.h"
37 #include "langhooks.h" /* For add_builtin_function(). */
39 /* ------------------------------------------------------------------------ */
41 /* Function to expand builtin function for
42 '[(unspec_volatile [(reg)])]'. */
44 nds32_expand_builtin_null_ftype_reg (enum insn_code icode
,
48 ops[0] <--> value0 <--> arg0 */
49 struct expand_operand ops
[1];
53 /* Grab the incoming arguments and extract its rtx. */
54 arg0
= CALL_EXPR_ARG (exp
, 0);
55 value0
= expand_normal (arg0
);
57 /* Create operands. */
58 create_input_operand (&ops
[0], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
60 /* Emit new instruction. */
61 if (!maybe_expand_insn (icode
, 1, ops
))
62 error ("invalid argument to built-in function");
67 /* Function to expand builtin function for
68 '[(set (reg) (unspec_volatile [(imm)]))]'. */
70 nds32_expand_builtin_reg_ftype_imm (enum insn_code icode
,
74 ops[0] <--> target <--> exp
75 ops[1] <--> value0 <--> arg0 */
76 struct expand_operand ops
[2];
80 /* Grab the incoming arguments and extract its rtx. */
81 arg0
= CALL_EXPR_ARG (exp
, 0);
82 value0
= expand_normal (arg0
);
84 /* Create operands. */
85 create_output_operand (&ops
[0], target
, TYPE_MODE (TREE_TYPE (exp
)));
86 create_input_operand (&ops
[1], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
88 /* Emit new instruction. */
89 if (!maybe_expand_insn (icode
, 2, ops
))
90 error ("invalid argument to built-in function");
95 /* Function to expand builtin function for
96 '[(unspec_volatile [(reg) (imm)])]' pattern. */
98 nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode
,
102 ops[0] <--> value0 <--> arg0
103 ops[1] <--> value1 <--> arg1 */
104 struct expand_operand ops
[2];
108 /* Grab the incoming arguments and extract its rtx. */
109 arg0
= CALL_EXPR_ARG (exp
, 0);
110 arg1
= CALL_EXPR_ARG (exp
, 1);
111 value0
= expand_normal (arg0
);
112 value1
= expand_normal (arg1
);
114 /* Create operands. */
115 create_input_operand (&ops
[0], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
116 create_input_operand (&ops
[1], value1
, TYPE_MODE (TREE_TYPE (arg1
)));
118 /* Emit new instruction. */
119 if (!maybe_expand_insn (icode
, 2, ops
))
120 error ("invalid argument to built-in function");
125 /* ------------------------------------------------------------------------ */
128 nds32_init_builtins_impl (void)
130 tree pointer_type_node
= build_pointer_type (integer_type_node
);
132 tree void_ftype_void
= build_function_type (void_type_node
,
135 tree void_ftype_pint
= build_function_type_list (void_type_node
,
139 tree int_ftype_int
= build_function_type_list (integer_type_node
,
143 tree void_ftype_int_int
= build_function_type_list (void_type_node
,
149 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint
,
151 BUILT_IN_MD
, NULL
, NULL_TREE
);
152 add_builtin_function ("__builtin_nds32_isb", void_ftype_void
,
154 BUILT_IN_MD
, NULL
, NULL_TREE
);
156 /* Register Transfer. */
157 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int
,
159 BUILT_IN_MD
, NULL
, NULL_TREE
);
160 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int
,
162 BUILT_IN_MD
, NULL
, NULL_TREE
);
163 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int
,
165 BUILT_IN_MD
, NULL
, NULL_TREE
);
166 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int
,
168 BUILT_IN_MD
, NULL
, NULL_TREE
);
171 add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void
,
172 NDS32_BUILTIN_SETGIE_EN
,
173 BUILT_IN_MD
, NULL
, NULL_TREE
);
174 add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void
,
175 NDS32_BUILTIN_SETGIE_DIS
,
176 BUILT_IN_MD
, NULL
, NULL_TREE
);
181 nds32_expand_builtin_impl (tree exp
,
183 rtx subtarget ATTRIBUTE_UNUSED
,
184 machine_mode mode ATTRIBUTE_UNUSED
,
185 int ignore ATTRIBUTE_UNUSED
)
187 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
189 int fcode
= DECL_FUNCTION_CODE (fndecl
);
194 case NDS32_BUILTIN_ISYNC
:
195 return nds32_expand_builtin_null_ftype_reg
196 (CODE_FOR_unspec_volatile_isync
, exp
, target
);
197 case NDS32_BUILTIN_ISB
:
198 /* Since there are no result and operands for isb instruciton,
199 we can simply emit this rtx. */
200 emit_insn (gen_unspec_volatile_isb ());
203 /* Register Transfer. */
204 case NDS32_BUILTIN_MFSR
:
205 return nds32_expand_builtin_reg_ftype_imm
206 (CODE_FOR_unspec_volatile_mfsr
, exp
, target
);
207 case NDS32_BUILTIN_MFUSR
:
208 return nds32_expand_builtin_reg_ftype_imm
209 (CODE_FOR_unspec_volatile_mfusr
, exp
, target
);
210 case NDS32_BUILTIN_MTSR
:
211 return nds32_expand_builtin_null_ftype_reg_imm
212 (CODE_FOR_unspec_volatile_mtsr
, exp
, target
);
213 case NDS32_BUILTIN_MTUSR
:
214 return nds32_expand_builtin_null_ftype_reg_imm
215 (CODE_FOR_unspec_volatile_mtusr
, exp
, target
);
218 case NDS32_BUILTIN_SETGIE_EN
:
219 /* Since there are no result and operands for setgie.e instruciton,
220 we can simply emit this rtx. */
221 emit_insn (gen_unspec_volatile_setgie_en ());
223 case NDS32_BUILTIN_SETGIE_DIS
:
224 /* Since there are no result and operands for setgie.d instruciton,
225 we can simply emit this rtx. */
226 emit_insn (gen_unspec_volatile_setgie_dis ());
236 /* ------------------------------------------------------------------------ */