]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/nds32/nds32-intrinsic.c
genattrtab.c (write_header): Include hash-set.h...
[thirdparty/gcc.git] / gcc / config / nds32 / nds32-intrinsic.c
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.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21 /* ------------------------------------------------------------------------ */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "hash-set.h"
28 #include "machmode.h"
29 #include "vec.h"
30 #include "double-int.h"
31 #include "input.h"
32 #include "alias.h"
33 #include "symtab.h"
34 #include "wide-int.h"
35 #include "inchash.h"
36 #include "tree.h"
37 #include "stor-layout.h"
38 #include "varasm.h"
39 #include "calls.h"
40 #include "rtl.h"
41 #include "regs.h"
42 #include "hard-reg-set.h"
43 #include "insn-config.h" /* Required by recog.h. */
44 #include "conditions.h"
45 #include "output.h"
46 #include "insn-attr.h" /* For DFA state_t. */
47 #include "insn-codes.h" /* For CODE_FOR_xxx. */
48 #include "reload.h" /* For push_reload(). */
49 #include "flags.h"
50 #include "input.h"
51 #include "function.h"
52 #include "expr.h"
53 #include "recog.h"
54 #include "diagnostic-core.h"
55 #include "dominance.h"
56 #include "cfg.h"
57 #include "cfgrtl.h"
58 #include "cfganal.h"
59 #include "lcm.h"
60 #include "cfgbuild.h"
61 #include "cfgcleanup.h"
62 #include "predict.h"
63 #include "basic-block.h"
64 #include "df.h"
65 #include "tm_p.h"
66 #include "tm-constrs.h"
67 #include "optabs.h" /* For GEN_FCN. */
68 #include "target.h"
69 #include "target-def.h"
70 #include "langhooks.h" /* For add_builtin_function(). */
71 #include "ggc.h"
72 #include "builtins.h"
73
74 /* ------------------------------------------------------------------------ */
75
76 /* Function to expand builtin function for
77 '[(unspec_volatile [(reg)])]'. */
78 static rtx
79 nds32_expand_builtin_null_ftype_reg (enum insn_code icode,
80 tree exp, rtx target)
81 {
82 /* Mapping:
83 ops[0] <--> value0 <--> arg0 */
84 struct expand_operand ops[1];
85 tree arg0;
86 rtx value0;
87
88 /* Grab the incoming arguments and extract its rtx. */
89 arg0 = CALL_EXPR_ARG (exp, 0);
90 value0 = expand_normal (arg0);
91
92 /* Create operands. */
93 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
94
95 /* Emit new instruction. */
96 if (!maybe_expand_insn (icode, 1, ops))
97 error ("invalid argument to built-in function");
98
99 return target;
100 }
101
102 /* Function to expand builtin function for
103 '[(set (reg) (unspec_volatile [(imm)]))]'. */
104 static rtx
105 nds32_expand_builtin_reg_ftype_imm (enum insn_code icode,
106 tree exp, rtx target)
107 {
108 /* Mapping:
109 ops[0] <--> target <--> exp
110 ops[1] <--> value0 <--> arg0 */
111 struct expand_operand ops[2];
112 tree arg0;
113 rtx value0;
114
115 /* Grab the incoming arguments and extract its rtx. */
116 arg0 = CALL_EXPR_ARG (exp, 0);
117 value0 = expand_normal (arg0);
118
119 /* Create operands. */
120 create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
121 create_input_operand (&ops[1], value0, TYPE_MODE (TREE_TYPE (arg0)));
122
123 /* Emit new instruction. */
124 if (!maybe_expand_insn (icode, 2, ops))
125 error ("invalid argument to built-in function");
126
127 return target;
128 }
129
130 /* Function to expand builtin function for
131 '[(unspec_volatile [(reg) (imm)])]' pattern. */
132 static rtx
133 nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode,
134 tree exp, rtx target)
135 {
136 /* Mapping:
137 ops[0] <--> value0 <--> arg0
138 ops[1] <--> value1 <--> arg1 */
139 struct expand_operand ops[2];
140 tree arg0, arg1;
141 rtx value0, value1;
142
143 /* Grab the incoming arguments and extract its rtx. */
144 arg0 = CALL_EXPR_ARG (exp, 0);
145 arg1 = CALL_EXPR_ARG (exp, 1);
146 value0 = expand_normal (arg0);
147 value1 = expand_normal (arg1);
148
149 /* Create operands. */
150 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
151 create_input_operand (&ops[1], value1, TYPE_MODE (TREE_TYPE (arg1)));
152
153 /* Emit new instruction. */
154 if (!maybe_expand_insn (icode, 2, ops))
155 error ("invalid argument to built-in function");
156
157 return target;
158 }
159
160 /* ------------------------------------------------------------------------ */
161
162 void
163 nds32_init_builtins_impl (void)
164 {
165 tree pointer_type_node = build_pointer_type (integer_type_node);
166
167 tree void_ftype_void = build_function_type (void_type_node,
168 void_list_node);
169
170 tree void_ftype_pint = build_function_type_list (void_type_node,
171 pointer_type_node,
172 NULL_TREE);
173
174 tree int_ftype_int = build_function_type_list (integer_type_node,
175 integer_type_node,
176 NULL_TREE);
177
178 tree void_ftype_int_int = build_function_type_list (void_type_node,
179 integer_type_node,
180 integer_type_node,
181 NULL_TREE);
182
183 /* Cache. */
184 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint,
185 NDS32_BUILTIN_ISYNC,
186 BUILT_IN_MD, NULL, NULL_TREE);
187 add_builtin_function ("__builtin_nds32_isb", void_ftype_void,
188 NDS32_BUILTIN_ISB,
189 BUILT_IN_MD, NULL, NULL_TREE);
190
191 /* Register Transfer. */
192 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int,
193 NDS32_BUILTIN_MFSR,
194 BUILT_IN_MD, NULL, NULL_TREE);
195 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int,
196 NDS32_BUILTIN_MFUSR,
197 BUILT_IN_MD, NULL, NULL_TREE);
198 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int,
199 NDS32_BUILTIN_MTSR,
200 BUILT_IN_MD, NULL, NULL_TREE);
201 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int,
202 NDS32_BUILTIN_MTUSR,
203 BUILT_IN_MD, NULL, NULL_TREE);
204
205 /* Interrupt. */
206 add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void,
207 NDS32_BUILTIN_SETGIE_EN,
208 BUILT_IN_MD, NULL, NULL_TREE);
209 add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void,
210 NDS32_BUILTIN_SETGIE_DIS,
211 BUILT_IN_MD, NULL, NULL_TREE);
212 }
213
214
215 rtx
216 nds32_expand_builtin_impl (tree exp,
217 rtx target,
218 rtx subtarget ATTRIBUTE_UNUSED,
219 machine_mode mode ATTRIBUTE_UNUSED,
220 int ignore ATTRIBUTE_UNUSED)
221 {
222 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
223
224 int fcode = DECL_FUNCTION_CODE (fndecl);
225
226 switch (fcode)
227 {
228 /* Cache. */
229 case NDS32_BUILTIN_ISYNC:
230 return nds32_expand_builtin_null_ftype_reg
231 (CODE_FOR_unspec_volatile_isync, exp, target);
232 case NDS32_BUILTIN_ISB:
233 /* Since there are no result and operands for isb instruciton,
234 we can simply emit this rtx. */
235 emit_insn (gen_unspec_volatile_isb ());
236 return target;
237
238 /* Register Transfer. */
239 case NDS32_BUILTIN_MFSR:
240 return nds32_expand_builtin_reg_ftype_imm
241 (CODE_FOR_unspec_volatile_mfsr, exp, target);
242 case NDS32_BUILTIN_MFUSR:
243 return nds32_expand_builtin_reg_ftype_imm
244 (CODE_FOR_unspec_volatile_mfusr, exp, target);
245 case NDS32_BUILTIN_MTSR:
246 return nds32_expand_builtin_null_ftype_reg_imm
247 (CODE_FOR_unspec_volatile_mtsr, exp, target);
248 case NDS32_BUILTIN_MTUSR:
249 return nds32_expand_builtin_null_ftype_reg_imm
250 (CODE_FOR_unspec_volatile_mtusr, exp, target);
251
252 /* Interrupt. */
253 case NDS32_BUILTIN_SETGIE_EN:
254 /* Since there are no result and operands for setgie.e instruciton,
255 we can simply emit this rtx. */
256 emit_insn (gen_unspec_volatile_setgie_en ());
257 return target;
258 case NDS32_BUILTIN_SETGIE_DIS:
259 /* Since there are no result and operands for setgie.d instruciton,
260 we can simply emit this rtx. */
261 emit_insn (gen_unspec_volatile_setgie_dis ());
262 return target;
263
264 default:
265 gcc_unreachable ();
266 }
267
268 return NULL_RTX;
269 }
270
271 /* ------------------------------------------------------------------------ */