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