1 /* Intrinsic functions of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2015 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 /* ------------------------------------------------------------------------ */
25 #include "coretypes.h"
30 #include "stor-layout.h"
35 #include "hard-reg-set.h"
36 #include "insn-config.h" /* Required by recog.h. */
37 #include "conditions.h"
39 #include "insn-attr.h" /* For DFA state_t. */
40 #include "insn-codes.h" /* For CODE_FOR_xxx. */
41 #include "reload.h" /* For push_reload(). */
44 #include "insn-config.h"
52 #include "diagnostic-core.h"
53 #include "dominance.h"
59 #include "cfgcleanup.h"
61 #include "basic-block.h"
64 #include "tm-constrs.h"
65 #include "optabs.h" /* For GEN_FCN. */
67 #include "langhooks.h" /* For add_builtin_function(). */
70 /* ------------------------------------------------------------------------ */
72 /* Function to expand builtin function for
73 '[(unspec_volatile [(reg)])]'. */
75 nds32_expand_builtin_null_ftype_reg (enum insn_code icode
,
79 ops[0] <--> value0 <--> arg0 */
80 struct expand_operand ops
[1];
84 /* Grab the incoming arguments and extract its rtx. */
85 arg0
= CALL_EXPR_ARG (exp
, 0);
86 value0
= expand_normal (arg0
);
88 /* Create operands. */
89 create_input_operand (&ops
[0], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
91 /* Emit new instruction. */
92 if (!maybe_expand_insn (icode
, 1, ops
))
93 error ("invalid argument to built-in function");
98 /* Function to expand builtin function for
99 '[(set (reg) (unspec_volatile [(imm)]))]'. */
101 nds32_expand_builtin_reg_ftype_imm (enum insn_code icode
,
102 tree exp
, rtx target
)
105 ops[0] <--> target <--> exp
106 ops[1] <--> value0 <--> arg0 */
107 struct expand_operand ops
[2];
111 /* Grab the incoming arguments and extract its rtx. */
112 arg0
= CALL_EXPR_ARG (exp
, 0);
113 value0
= expand_normal (arg0
);
115 /* Create operands. */
116 create_output_operand (&ops
[0], target
, TYPE_MODE (TREE_TYPE (exp
)));
117 create_input_operand (&ops
[1], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
119 /* Emit new instruction. */
120 if (!maybe_expand_insn (icode
, 2, ops
))
121 error ("invalid argument to built-in function");
126 /* Function to expand builtin function for
127 '[(unspec_volatile [(reg) (imm)])]' pattern. */
129 nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode
,
130 tree exp
, rtx target
)
133 ops[0] <--> value0 <--> arg0
134 ops[1] <--> value1 <--> arg1 */
135 struct expand_operand ops
[2];
139 /* Grab the incoming arguments and extract its rtx. */
140 arg0
= CALL_EXPR_ARG (exp
, 0);
141 arg1
= CALL_EXPR_ARG (exp
, 1);
142 value0
= expand_normal (arg0
);
143 value1
= expand_normal (arg1
);
145 /* Create operands. */
146 create_input_operand (&ops
[0], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
147 create_input_operand (&ops
[1], value1
, TYPE_MODE (TREE_TYPE (arg1
)));
149 /* Emit new instruction. */
150 if (!maybe_expand_insn (icode
, 2, ops
))
151 error ("invalid argument to built-in function");
156 /* ------------------------------------------------------------------------ */
159 nds32_init_builtins_impl (void)
161 tree pointer_type_node
= build_pointer_type (integer_type_node
);
163 tree void_ftype_void
= build_function_type (void_type_node
,
166 tree void_ftype_pint
= build_function_type_list (void_type_node
,
170 tree int_ftype_int
= build_function_type_list (integer_type_node
,
174 tree void_ftype_int_int
= build_function_type_list (void_type_node
,
180 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint
,
182 BUILT_IN_MD
, NULL
, NULL_TREE
);
183 add_builtin_function ("__builtin_nds32_isb", void_ftype_void
,
185 BUILT_IN_MD
, NULL
, NULL_TREE
);
187 /* Register Transfer. */
188 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int
,
190 BUILT_IN_MD
, NULL
, NULL_TREE
);
191 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int
,
193 BUILT_IN_MD
, NULL
, NULL_TREE
);
194 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int
,
196 BUILT_IN_MD
, NULL
, NULL_TREE
);
197 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int
,
199 BUILT_IN_MD
, NULL
, NULL_TREE
);
202 add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void
,
203 NDS32_BUILTIN_SETGIE_EN
,
204 BUILT_IN_MD
, NULL
, NULL_TREE
);
205 add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void
,
206 NDS32_BUILTIN_SETGIE_DIS
,
207 BUILT_IN_MD
, NULL
, NULL_TREE
);
212 nds32_expand_builtin_impl (tree exp
,
214 rtx subtarget ATTRIBUTE_UNUSED
,
215 machine_mode mode ATTRIBUTE_UNUSED
,
216 int ignore ATTRIBUTE_UNUSED
)
218 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
220 int fcode
= DECL_FUNCTION_CODE (fndecl
);
225 case NDS32_BUILTIN_ISYNC
:
226 return nds32_expand_builtin_null_ftype_reg
227 (CODE_FOR_unspec_volatile_isync
, exp
, target
);
228 case NDS32_BUILTIN_ISB
:
229 /* Since there are no result and operands for isb instruciton,
230 we can simply emit this rtx. */
231 emit_insn (gen_unspec_volatile_isb ());
234 /* Register Transfer. */
235 case NDS32_BUILTIN_MFSR
:
236 return nds32_expand_builtin_reg_ftype_imm
237 (CODE_FOR_unspec_volatile_mfsr
, exp
, target
);
238 case NDS32_BUILTIN_MFUSR
:
239 return nds32_expand_builtin_reg_ftype_imm
240 (CODE_FOR_unspec_volatile_mfusr
, exp
, target
);
241 case NDS32_BUILTIN_MTSR
:
242 return nds32_expand_builtin_null_ftype_reg_imm
243 (CODE_FOR_unspec_volatile_mtsr
, exp
, target
);
244 case NDS32_BUILTIN_MTUSR
:
245 return nds32_expand_builtin_null_ftype_reg_imm
246 (CODE_FOR_unspec_volatile_mtusr
, exp
, target
);
249 case NDS32_BUILTIN_SETGIE_EN
:
250 /* Since there are no result and operands for setgie.e instruciton,
251 we can simply emit this rtx. */
252 emit_insn (gen_unspec_volatile_setgie_en ());
254 case NDS32_BUILTIN_SETGIE_DIS
:
255 /* Since there are no result and operands for setgie.d instruciton,
256 we can simply emit this rtx. */
257 emit_insn (gen_unspec_volatile_setgie_dis ());
267 /* ------------------------------------------------------------------------ */