]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/nds32/nds32-intrinsic.c
2014-10-16 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / config / nds32 / nds32-intrinsic.c
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.
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 "tree.h"
28 #include "stor-layout.h"
29 #include "varasm.h"
30 #include "calls.h"
31 #include "rtl.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "insn-config.h" /* Required by recog.h. */
35 #include "conditions.h"
36 #include "output.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(). */
40 #include "flags.h"
41 #include "hashtab.h"
42 #include "hash-set.h"
43 #include "vec.h"
44 #include "machmode.h"
45 #include "input.h"
46 #include "function.h"
47 #include "expr.h"
48 #include "recog.h"
49 #include "diagnostic-core.h"
50 #include "df.h"
51 #include "tm_p.h"
52 #include "tm-constrs.h"
53 #include "optabs.h" /* For GEN_FCN. */
54 #include "target.h"
55 #include "target-def.h"
56 #include "langhooks.h" /* For add_builtin_function(). */
57 #include "ggc.h"
58 #include "builtins.h"
59
60 /* ------------------------------------------------------------------------ */
61
62 /* Function to expand builtin function for
63 '[(unspec_volatile [(reg)])]'. */
64 static rtx
65 nds32_expand_builtin_null_ftype_reg (enum insn_code icode,
66 tree exp, rtx target)
67 {
68 /* Mapping:
69 ops[0] <--> value0 <--> arg0 */
70 struct expand_operand ops[1];
71 tree arg0;
72 rtx value0;
73
74 /* Grab the incoming arguments and extract its rtx. */
75 arg0 = CALL_EXPR_ARG (exp, 0);
76 value0 = expand_normal (arg0);
77
78 /* Create operands. */
79 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
80
81 /* Emit new instruction. */
82 if (!maybe_expand_insn (icode, 1, ops))
83 error ("invalid argument to built-in function");
84
85 return target;
86 }
87
88 /* Function to expand builtin function for
89 '[(set (reg) (unspec_volatile [(imm)]))]'. */
90 static rtx
91 nds32_expand_builtin_reg_ftype_imm (enum insn_code icode,
92 tree exp, rtx target)
93 {
94 /* Mapping:
95 ops[0] <--> target <--> exp
96 ops[1] <--> value0 <--> arg0 */
97 struct expand_operand ops[2];
98 tree arg0;
99 rtx value0;
100
101 /* Grab the incoming arguments and extract its rtx. */
102 arg0 = CALL_EXPR_ARG (exp, 0);
103 value0 = expand_normal (arg0);
104
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)));
108
109 /* Emit new instruction. */
110 if (!maybe_expand_insn (icode, 2, ops))
111 error ("invalid argument to built-in function");
112
113 return target;
114 }
115
116 /* Function to expand builtin function for
117 '[(unspec_volatile [(reg) (imm)])]' pattern. */
118 static rtx
119 nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode,
120 tree exp, rtx target)
121 {
122 /* Mapping:
123 ops[0] <--> value0 <--> arg0
124 ops[1] <--> value1 <--> arg1 */
125 struct expand_operand ops[2];
126 tree arg0, arg1;
127 rtx value0, value1;
128
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);
134
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)));
138
139 /* Emit new instruction. */
140 if (!maybe_expand_insn (icode, 2, ops))
141 error ("invalid argument to built-in function");
142
143 return target;
144 }
145
146 /* ------------------------------------------------------------------------ */
147
148 void
149 nds32_init_builtins_impl (void)
150 {
151 tree pointer_type_node = build_pointer_type (integer_type_node);
152
153 tree void_ftype_void = build_function_type (void_type_node,
154 void_list_node);
155
156 tree void_ftype_pint = build_function_type_list (void_type_node,
157 pointer_type_node,
158 NULL_TREE);
159
160 tree int_ftype_int = build_function_type_list (integer_type_node,
161 integer_type_node,
162 NULL_TREE);
163
164 tree void_ftype_int_int = build_function_type_list (void_type_node,
165 integer_type_node,
166 integer_type_node,
167 NULL_TREE);
168
169 /* Cache. */
170 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint,
171 NDS32_BUILTIN_ISYNC,
172 BUILT_IN_MD, NULL, NULL_TREE);
173 add_builtin_function ("__builtin_nds32_isb", void_ftype_void,
174 NDS32_BUILTIN_ISB,
175 BUILT_IN_MD, NULL, NULL_TREE);
176
177 /* Register Transfer. */
178 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int,
179 NDS32_BUILTIN_MFSR,
180 BUILT_IN_MD, NULL, NULL_TREE);
181 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int,
182 NDS32_BUILTIN_MFUSR,
183 BUILT_IN_MD, NULL, NULL_TREE);
184 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int,
185 NDS32_BUILTIN_MTSR,
186 BUILT_IN_MD, NULL, NULL_TREE);
187 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int,
188 NDS32_BUILTIN_MTUSR,
189 BUILT_IN_MD, NULL, NULL_TREE);
190
191 /* Interrupt. */
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);
198 }
199
200
201 rtx
202 nds32_expand_builtin_impl (tree exp,
203 rtx target,
204 rtx subtarget ATTRIBUTE_UNUSED,
205 enum machine_mode mode ATTRIBUTE_UNUSED,
206 int ignore ATTRIBUTE_UNUSED)
207 {
208 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
209
210 int fcode = DECL_FUNCTION_CODE (fndecl);
211
212 switch (fcode)
213 {
214 /* Cache. */
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 ());
222 return target;
223
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);
237
238 /* Interrupt. */
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 ());
243 return target;
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 ());
248 return target;
249
250 default:
251 gcc_unreachable ();
252 }
253
254 return NULL_RTX;
255 }
256
257 /* ------------------------------------------------------------------------ */