2016-09-08 Steven G. Kargl <kargl@gcc.gnu.org>
[official-gcc.git] / gcc / config / nds32 / nds32-intrinsic.c
blobfabf262e3cb02f691854399ad5cba8b43746b8be
1 /* Intrinsic functions of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2016 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 /* ------------------------------------------------------------------------ */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "optabs.h" /* For GEN_FCN. */
31 #include "diagnostic-core.h"
32 #include "stor-layout.h"
33 #include "expr.h"
34 #include "langhooks.h" /* For add_builtin_function(). */
36 /* ------------------------------------------------------------------------ */
38 /* Function to expand builtin function for
39 '[(unspec_volatile [(reg)])]'. */
40 static rtx
41 nds32_expand_builtin_null_ftype_reg (enum insn_code icode,
42 tree exp, rtx target)
44 /* Mapping:
45 ops[0] <--> value0 <--> arg0 */
46 struct expand_operand ops[1];
47 tree arg0;
48 rtx value0;
50 /* Grab the incoming arguments and extract its rtx. */
51 arg0 = CALL_EXPR_ARG (exp, 0);
52 value0 = expand_normal (arg0);
54 /* Create operands. */
55 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
57 /* Emit new instruction. */
58 if (!maybe_expand_insn (icode, 1, ops))
59 error ("invalid argument to built-in function");
61 return target;
64 /* Function to expand builtin function for
65 '[(set (reg) (unspec_volatile [(imm)]))]'. */
66 static rtx
67 nds32_expand_builtin_reg_ftype_imm (enum insn_code icode,
68 tree exp, rtx target)
70 /* Mapping:
71 ops[0] <--> target <--> exp
72 ops[1] <--> value0 <--> arg0 */
73 struct expand_operand ops[2];
74 tree arg0;
75 rtx value0;
77 /* Grab the incoming arguments and extract its rtx. */
78 arg0 = CALL_EXPR_ARG (exp, 0);
79 value0 = expand_normal (arg0);
81 /* Create operands. */
82 create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
83 create_input_operand (&ops[1], value0, TYPE_MODE (TREE_TYPE (arg0)));
85 /* Emit new instruction. */
86 if (!maybe_expand_insn (icode, 2, ops))
87 error ("invalid argument to built-in function");
89 return target;
92 /* Function to expand builtin function for
93 '[(unspec_volatile [(reg) (imm)])]' pattern. */
94 static rtx
95 nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode,
96 tree exp, rtx target)
98 /* Mapping:
99 ops[0] <--> value0 <--> arg0
100 ops[1] <--> value1 <--> arg1 */
101 struct expand_operand ops[2];
102 tree arg0, arg1;
103 rtx value0, value1;
105 /* Grab the incoming arguments and extract its rtx. */
106 arg0 = CALL_EXPR_ARG (exp, 0);
107 arg1 = CALL_EXPR_ARG (exp, 1);
108 value0 = expand_normal (arg0);
109 value1 = expand_normal (arg1);
111 /* Create operands. */
112 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
113 create_input_operand (&ops[1], value1, TYPE_MODE (TREE_TYPE (arg1)));
115 /* Emit new instruction. */
116 if (!maybe_expand_insn (icode, 2, ops))
117 error ("invalid argument to built-in function");
119 return target;
122 /* ------------------------------------------------------------------------ */
124 void
125 nds32_init_builtins_impl (void)
127 tree pointer_type_node = build_pointer_type (integer_type_node);
129 tree void_ftype_void = build_function_type (void_type_node,
130 void_list_node);
132 tree void_ftype_pint = build_function_type_list (void_type_node,
133 pointer_type_node,
134 NULL_TREE);
136 tree int_ftype_int = build_function_type_list (integer_type_node,
137 integer_type_node,
138 NULL_TREE);
140 tree void_ftype_int_int = build_function_type_list (void_type_node,
141 integer_type_node,
142 integer_type_node,
143 NULL_TREE);
145 /* Cache. */
146 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint,
147 NDS32_BUILTIN_ISYNC,
148 BUILT_IN_MD, NULL, NULL_TREE);
149 add_builtin_function ("__builtin_nds32_isb", void_ftype_void,
150 NDS32_BUILTIN_ISB,
151 BUILT_IN_MD, NULL, NULL_TREE);
153 /* Register Transfer. */
154 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int,
155 NDS32_BUILTIN_MFSR,
156 BUILT_IN_MD, NULL, NULL_TREE);
157 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int,
158 NDS32_BUILTIN_MFUSR,
159 BUILT_IN_MD, NULL, NULL_TREE);
160 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int,
161 NDS32_BUILTIN_MTSR,
162 BUILT_IN_MD, NULL, NULL_TREE);
163 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int,
164 NDS32_BUILTIN_MTUSR,
165 BUILT_IN_MD, NULL, NULL_TREE);
167 /* Interrupt. */
168 add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void,
169 NDS32_BUILTIN_SETGIE_EN,
170 BUILT_IN_MD, NULL, NULL_TREE);
171 add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void,
172 NDS32_BUILTIN_SETGIE_DIS,
173 BUILT_IN_MD, NULL, NULL_TREE);
178 nds32_expand_builtin_impl (tree exp,
179 rtx target,
180 rtx subtarget ATTRIBUTE_UNUSED,
181 machine_mode mode ATTRIBUTE_UNUSED,
182 int ignore ATTRIBUTE_UNUSED)
184 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
186 int fcode = DECL_FUNCTION_CODE (fndecl);
188 switch (fcode)
190 /* Cache. */
191 case NDS32_BUILTIN_ISYNC:
192 return nds32_expand_builtin_null_ftype_reg
193 (CODE_FOR_unspec_volatile_isync, exp, target);
194 case NDS32_BUILTIN_ISB:
195 /* Since there are no result and operands for isb instruciton,
196 we can simply emit this rtx. */
197 emit_insn (gen_unspec_volatile_isb ());
198 return target;
200 /* Register Transfer. */
201 case NDS32_BUILTIN_MFSR:
202 return nds32_expand_builtin_reg_ftype_imm
203 (CODE_FOR_unspec_volatile_mfsr, exp, target);
204 case NDS32_BUILTIN_MFUSR:
205 return nds32_expand_builtin_reg_ftype_imm
206 (CODE_FOR_unspec_volatile_mfusr, exp, target);
207 case NDS32_BUILTIN_MTSR:
208 return nds32_expand_builtin_null_ftype_reg_imm
209 (CODE_FOR_unspec_volatile_mtsr, exp, target);
210 case NDS32_BUILTIN_MTUSR:
211 return nds32_expand_builtin_null_ftype_reg_imm
212 (CODE_FOR_unspec_volatile_mtusr, exp, target);
214 /* Interrupt. */
215 case NDS32_BUILTIN_SETGIE_EN:
216 /* Since there are no result and operands for setgie.e instruciton,
217 we can simply emit this rtx. */
218 emit_insn (gen_unspec_volatile_setgie_en ());
219 return target;
220 case NDS32_BUILTIN_SETGIE_DIS:
221 /* Since there are no result and operands for setgie.d instruciton,
222 we can simply emit this rtx. */
223 emit_insn (gen_unspec_volatile_setgie_dis ());
224 return target;
226 default:
227 gcc_unreachable ();
230 return NULL_RTX;
233 /* ------------------------------------------------------------------------ */