1 /* Intrinsic functions of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2014 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"
28 #include "stor-layout.h"
33 #include "hard-reg-set.h"
34 #include "insn-config.h" /* Required by recog.h. */
35 #include "conditions.h"
37 #include "insn-attr.h" /* For DFA state_t. */
38 #include "insn-codes.h" /* For CODE_FOR_xxx. */
39 #include "reload.h" /* For push_reload(). */
49 #include "diagnostic-core.h"
52 #include "tm-constrs.h"
53 #include "optabs.h" /* For GEN_FCN. */
55 #include "target-def.h"
56 #include "langhooks.h" /* For add_builtin_function(). */
60 /* ------------------------------------------------------------------------ */
62 /* Function to expand builtin function for
63 '[(unspec_volatile [(reg)])]'. */
65 nds32_expand_builtin_null_ftype_reg (enum insn_code icode
,
69 ops[0] <--> value0 <--> arg0 */
70 struct expand_operand ops
[1];
74 /* Grab the incoming arguments and extract its rtx. */
75 arg0
= CALL_EXPR_ARG (exp
, 0);
76 value0
= expand_normal (arg0
);
78 /* Create operands. */
79 create_input_operand (&ops
[0], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
81 /* Emit new instruction. */
82 if (!maybe_expand_insn (icode
, 1, ops
))
83 error ("invalid argument to built-in function");
88 /* Function to expand builtin function for
89 '[(set (reg) (unspec_volatile [(imm)]))]'. */
91 nds32_expand_builtin_reg_ftype_imm (enum insn_code icode
,
95 ops[0] <--> target <--> exp
96 ops[1] <--> value0 <--> arg0 */
97 struct expand_operand ops
[2];
101 /* Grab the incoming arguments and extract its rtx. */
102 arg0
= CALL_EXPR_ARG (exp
, 0);
103 value0
= expand_normal (arg0
);
105 /* Create operands. */
106 create_output_operand (&ops
[0], target
, TYPE_MODE (TREE_TYPE (exp
)));
107 create_input_operand (&ops
[1], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
109 /* Emit new instruction. */
110 if (!maybe_expand_insn (icode
, 2, ops
))
111 error ("invalid argument to built-in function");
116 /* Function to expand builtin function for
117 '[(unspec_volatile [(reg) (imm)])]' pattern. */
119 nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode
,
120 tree exp
, rtx target
)
123 ops[0] <--> value0 <--> arg0
124 ops[1] <--> value1 <--> arg1 */
125 struct expand_operand ops
[2];
129 /* Grab the incoming arguments and extract its rtx. */
130 arg0
= CALL_EXPR_ARG (exp
, 0);
131 arg1
= CALL_EXPR_ARG (exp
, 1);
132 value0
= expand_normal (arg0
);
133 value1
= expand_normal (arg1
);
135 /* Create operands. */
136 create_input_operand (&ops
[0], value0
, TYPE_MODE (TREE_TYPE (arg0
)));
137 create_input_operand (&ops
[1], value1
, TYPE_MODE (TREE_TYPE (arg1
)));
139 /* Emit new instruction. */
140 if (!maybe_expand_insn (icode
, 2, ops
))
141 error ("invalid argument to built-in function");
146 /* ------------------------------------------------------------------------ */
149 nds32_init_builtins_impl (void)
151 tree pointer_type_node
= build_pointer_type (integer_type_node
);
153 tree void_ftype_void
= build_function_type (void_type_node
,
156 tree void_ftype_pint
= build_function_type_list (void_type_node
,
160 tree int_ftype_int
= build_function_type_list (integer_type_node
,
164 tree void_ftype_int_int
= build_function_type_list (void_type_node
,
170 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint
,
172 BUILT_IN_MD
, NULL
, NULL_TREE
);
173 add_builtin_function ("__builtin_nds32_isb", void_ftype_void
,
175 BUILT_IN_MD
, NULL
, NULL_TREE
);
177 /* Register Transfer. */
178 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int
,
180 BUILT_IN_MD
, NULL
, NULL_TREE
);
181 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int
,
183 BUILT_IN_MD
, NULL
, NULL_TREE
);
184 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int
,
186 BUILT_IN_MD
, NULL
, NULL_TREE
);
187 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int
,
189 BUILT_IN_MD
, NULL
, NULL_TREE
);
192 add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void
,
193 NDS32_BUILTIN_SETGIE_EN
,
194 BUILT_IN_MD
, NULL
, NULL_TREE
);
195 add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void
,
196 NDS32_BUILTIN_SETGIE_DIS
,
197 BUILT_IN_MD
, NULL
, NULL_TREE
);
202 nds32_expand_builtin_impl (tree exp
,
204 rtx subtarget ATTRIBUTE_UNUSED
,
205 enum machine_mode mode ATTRIBUTE_UNUSED
,
206 int ignore ATTRIBUTE_UNUSED
)
208 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
210 int fcode
= DECL_FUNCTION_CODE (fndecl
);
215 case NDS32_BUILTIN_ISYNC
:
216 return nds32_expand_builtin_null_ftype_reg
217 (CODE_FOR_unspec_volatile_isync
, exp
, target
);
218 case NDS32_BUILTIN_ISB
:
219 /* Since there are no result and operands for isb instruciton,
220 we can simply emit this rtx. */
221 emit_insn (gen_unspec_volatile_isb ());
224 /* Register Transfer. */
225 case NDS32_BUILTIN_MFSR
:
226 return nds32_expand_builtin_reg_ftype_imm
227 (CODE_FOR_unspec_volatile_mfsr
, exp
, target
);
228 case NDS32_BUILTIN_MFUSR
:
229 return nds32_expand_builtin_reg_ftype_imm
230 (CODE_FOR_unspec_volatile_mfusr
, exp
, target
);
231 case NDS32_BUILTIN_MTSR
:
232 return nds32_expand_builtin_null_ftype_reg_imm
233 (CODE_FOR_unspec_volatile_mtsr
, exp
, target
);
234 case NDS32_BUILTIN_MTUSR
:
235 return nds32_expand_builtin_null_ftype_reg_imm
236 (CODE_FOR_unspec_volatile_mtusr
, exp
, target
);
239 case NDS32_BUILTIN_SETGIE_EN
:
240 /* Since there are no result and operands for setgie.e instruciton,
241 we can simply emit this rtx. */
242 emit_insn (gen_unspec_volatile_setgie_en ());
244 case NDS32_BUILTIN_SETGIE_DIS
:
245 /* Since there are no result and operands for setgie.d instruciton,
246 we can simply emit this rtx. */
247 emit_insn (gen_unspec_volatile_setgie_dis ());
257 /* ------------------------------------------------------------------------ */