[NDS32] Add intrinsic functions for interrupt control.
[official-gcc.git] / gcc / config / nds32 / nds32-intrinsic.c
bloba835029fd52c0d29068b383c2eae8cf8ca6ea3fb
1 /* Intrinsic functions of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2018 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 #define IN_TARGET_CODE 1
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "backend.h"
29 #include "target.h"
30 #include "rtl.h"
31 #include "memmodel.h"
32 #include "emit-rtl.h"
33 #include "tree.h"
34 #include "memmodel.h"
35 #include "optabs.h" /* For GEN_FCN. */
36 #include "diagnostic-core.h"
37 #include "stor-layout.h"
38 #include "expr.h"
39 #include "langhooks.h" /* For add_builtin_function(). */
40 #include "recog.h"
41 #include "explow.h"
43 /* ------------------------------------------------------------------------ */
45 /* Read the requested argument from the EXP given by INDEX.
46 Return the value as an rtx. */
47 static rtx
48 nds32_read_argument (tree exp, unsigned int index)
50 return expand_normal (CALL_EXPR_ARG (exp, index));
53 /* Return a legitimate rtx for instruction ICODE's return value. Use TARGET
54 if it's not null, has the right mode, and satisfies operand 0's
55 predicate. */
56 static rtx
57 nds32_legitimize_target (enum insn_code icode, rtx target)
59 enum machine_mode mode = insn_data[icode].operand[0].mode;
61 if (! target
62 || GET_MODE (target) != mode
63 || ! (*insn_data[icode].operand[0].predicate) (target, mode))
64 return gen_reg_rtx (mode);
65 else
66 return target;
69 /* Given that ARG is being passed as operand OPNUM to instruction ICODE,
70 check whether ARG satisfies the operand's constraints. If it doesn't,
71 copy ARG to a temporary register and return that. Otherwise return ARG
72 itself. */
73 static rtx
74 nds32_legitimize_argument (enum insn_code icode, int opnum, rtx arg)
76 enum machine_mode mode = insn_data[icode].operand[opnum].mode;
78 if ((*insn_data[icode].operand[opnum].predicate) (arg, mode))
79 return arg;
80 else if (VECTOR_MODE_P (mode) && CONST_INT_P (arg))
82 /* Handle CONST_INT covert to CONST_VECTOR. */
83 int nunits = GET_MODE_NUNITS (mode);
84 int i, shift = 0;
85 rtvec v = rtvec_alloc (nunits);
86 int val = INTVAL (arg);
87 enum machine_mode val_mode = (mode == V4QImode) ? QImode : HImode;
88 int shift_acc = (val_mode == QImode) ? 8 : 16;
89 int mask = (val_mode == QImode) ? 0xff : 0xffff;
90 int tmp_val = val;
92 if (TARGET_BIG_ENDIAN)
93 for (i = 0; i < nunits; i++)
95 tmp_val = (val >> shift) & mask;
96 RTVEC_ELT (v, nunits - i - 1) = gen_int_mode (tmp_val, val_mode);
97 shift += shift_acc;
99 else
100 for (i = 0; i < nunits; i++)
102 tmp_val = (val >> shift) & mask;
103 RTVEC_ELT (v, i) = gen_int_mode (tmp_val, val_mode);
104 shift += shift_acc;
107 return copy_to_mode_reg (mode, gen_rtx_CONST_VECTOR (mode, v));
109 else
111 rtx tmp_rtx = gen_reg_rtx (mode);
112 convert_move (tmp_rtx, arg, false);
113 return tmp_rtx;
117 /* Return true if OPVAL can be used for operand OPNUM of instruction ICODE.
118 The instruction should require a constant operand of some sort. The
119 function prints an error if OPVAL is not valid. */
120 static int
121 nds32_check_constant_argument (enum insn_code icode, int opnum, rtx opval,
122 const char *name)
124 if (GET_CODE (opval) != CONST_INT)
126 error ("invalid argument to built-in function %s", name);
127 return false;
129 if (! (*insn_data[icode].operand[opnum].predicate) (opval, VOIDmode))
131 error ("constant argument out of range for %s", name);
133 return false;
135 return true;
138 /* Expand builtins that return target. */
139 static rtx
140 nds32_expand_noarg_builtin (enum insn_code icode, rtx target)
142 rtx pat;
144 target = nds32_legitimize_target (icode, target);
146 /* Emit and return the new instruction. */
147 pat = GEN_FCN (icode) (target);
148 if (! pat)
149 return NULL_RTX;
151 emit_insn (pat);
152 return target;
155 /* Expand builtins that take one operand. */
156 static rtx
157 nds32_expand_unop_builtin (enum insn_code icode, tree exp, rtx target,
158 bool return_p)
160 rtx pat;
161 rtx op0 = nds32_read_argument (exp, 0);
162 int op0_num = return_p ? 1 : 0;
164 if (return_p)
165 target = nds32_legitimize_target (icode, target);
167 op0 = nds32_legitimize_argument (icode, op0_num, op0);
169 /* Emit and return the new instruction. */
170 if (return_p)
171 pat = GEN_FCN (icode) (target, op0);
172 else
173 pat = GEN_FCN (icode) (op0);
175 if (! pat)
176 return NULL_RTX;
178 emit_insn (pat);
179 return target;
182 /* Expand builtins that take one operands and the first is immediate. */
183 static rtx
184 nds32_expand_unopimm_builtin (enum insn_code icode, tree exp, rtx target,
185 bool return_p, const char *name)
187 rtx pat;
188 rtx op0 = nds32_read_argument (exp, 0);
189 int op0_num = return_p ? 1 : 0;
191 if (return_p)
192 target = nds32_legitimize_target (icode, target);
194 if (!nds32_check_constant_argument (icode, op0_num, op0, name))
195 return NULL_RTX;
197 op0 = nds32_legitimize_argument (icode, op0_num, op0);
199 /* Emit and return the new instruction. */
200 if (return_p)
201 pat = GEN_FCN (icode) (target, op0);
202 else
203 pat = GEN_FCN (icode) (op0);
205 if (! pat)
206 return NULL_RTX;
208 emit_insn (pat);
209 return target;
212 /* Expand builtins that take two operands. */
213 static rtx
214 nds32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target,
215 bool return_p)
217 rtx pat;
218 rtx op0 = nds32_read_argument (exp, 0);
219 rtx op1 = nds32_read_argument (exp, 1);
220 int op0_num = return_p ? 1 : 0;
221 int op1_num = return_p ? 2 : 1;
223 if (return_p)
224 target = nds32_legitimize_target (icode, target);
226 op0 = nds32_legitimize_argument (icode, op0_num, op0);
227 op1 = nds32_legitimize_argument (icode, op1_num, op1);
229 /* Emit and return the new instruction. */
230 if (return_p)
231 pat = GEN_FCN (icode) (target, op0, op1);
232 else
233 pat = GEN_FCN (icode) (op0, op1);
235 if (! pat)
236 return NULL_RTX;
238 emit_insn (pat);
239 return target;
242 /* Expand builtins that take two operands and the second is immediate. */
243 static rtx
244 nds32_expand_binopimm_builtin (enum insn_code icode, tree exp, rtx target,
245 bool return_p, const char *name)
247 rtx pat;
248 rtx op0 = nds32_read_argument (exp, 0);
249 rtx op1 = nds32_read_argument (exp, 1);
250 int op0_num = return_p ? 1 : 0;
251 int op1_num = return_p ? 2 : 1;
253 if (return_p)
254 target = nds32_legitimize_target (icode, target);
256 if (!nds32_check_constant_argument (icode, op1_num, op1, name))
257 return NULL_RTX;
259 op0 = nds32_legitimize_argument (icode, op0_num, op0);
260 op1 = nds32_legitimize_argument (icode, op1_num, op1);
262 /* Emit and return the new instruction. */
263 if (return_p)
264 pat = GEN_FCN (icode) (target, op0, op1);
265 else
266 pat = GEN_FCN (icode) (op0, op1);
268 if (! pat)
269 return NULL_RTX;
271 emit_insn (pat);
272 return target;
275 /* Expand builtins that take three operands. */
276 static rtx
277 nds32_expand_triop_builtin (enum insn_code icode, tree exp, rtx target,
278 bool return_p)
280 rtx pat;
281 rtx op0 = nds32_read_argument (exp, 0);
282 rtx op1 = nds32_read_argument (exp, 1);
283 rtx op2 = nds32_read_argument (exp, 2);
284 int op0_num = return_p ? 1 : 0;
285 int op1_num = return_p ? 2 : 1;
286 int op2_num = return_p ? 3 : 2;
288 if (return_p)
289 target = nds32_legitimize_target (icode, target);
291 op0 = nds32_legitimize_argument (icode, op0_num, op0);
292 op1 = nds32_legitimize_argument (icode, op1_num, op1);
293 op2 = nds32_legitimize_argument (icode, op2_num, op2);
295 /* Emit and return the new instruction. */
296 if (return_p)
297 pat = GEN_FCN (icode) (target, op0, op1, op2);
298 else
299 pat = GEN_FCN (icode) (op0, op1, op2);
301 if (! pat)
302 return NULL_RTX;
304 emit_insn (pat);
305 return target;
308 /* Expand builtins that take three operands and the third is immediate. */
309 static rtx
310 nds32_expand_triopimm_builtin (enum insn_code icode, tree exp, rtx target,
311 bool return_p, const char *name)
313 rtx pat;
314 rtx op0 = nds32_read_argument (exp, 0);
315 rtx op1 = nds32_read_argument (exp, 1);
316 rtx op2 = nds32_read_argument (exp, 2);
317 int op0_num = return_p ? 1 : 0;
318 int op1_num = return_p ? 2 : 1;
319 int op2_num = return_p ? 3 : 2;
321 if (return_p)
322 target = nds32_legitimize_target (icode, target);
324 if (!nds32_check_constant_argument (icode, op2_num, op2, name))
325 return NULL_RTX;
327 op0 = nds32_legitimize_argument (icode, op0_num, op0);
328 op1 = nds32_legitimize_argument (icode, op1_num, op1);
329 op2 = nds32_legitimize_argument (icode, op2_num, op2);
331 /* Emit and return the new instruction. */
332 if (return_p)
333 pat = GEN_FCN (icode) (target, op0, op1, op2);
334 else
335 pat = GEN_FCN (icode) (op0, op1, op2);
337 if (! pat)
338 return NULL_RTX;
340 emit_insn (pat);
341 return target;
344 /* Expand builtins for load. */
345 static rtx
346 nds32_expand_builtin_load (enum insn_code icode, tree exp, rtx target)
348 /* Load address format is [$ra + $rb],
349 but input arguments not enough,
350 so we need another temp register as $rb.
351 Generating assembly code:
352 movi $temp, 0
353 llw $rt, [$ra + $temp] */
354 rtx pat;
355 rtx op0 = nds32_read_argument (exp, 0);
356 rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode);
358 target = nds32_legitimize_target (icode, target);
359 op0 = nds32_legitimize_argument (icode, 1, op0);
361 /* Emit and return the new instruction. */
362 pat = GEN_FCN (icode) (target, op0, addr_helper);
363 if (!pat)
364 return NULL_RTX;
366 emit_move_insn (addr_helper, GEN_INT (0));
367 emit_insn (pat);
368 return target;
371 /* Expand builtins for store. */
372 static rtx
373 nds32_expand_builtin_store (enum insn_code icode, tree exp, rtx target)
375 /* Store address format is [$ra + $rb],
376 but input arguments not enough,
377 so we need another temp register as $rb.
378 Generating assembly code:
379 movi $temp, 0
380 store $rt, [$ra + $temp] */
381 rtx pat;
382 rtx op0 = nds32_read_argument (exp, 0);
383 rtx op1 = nds32_read_argument (exp, 1);
384 rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode);
386 op0 = nds32_legitimize_argument (icode, 0, op0);
387 op1 = nds32_legitimize_argument (icode, 2, op1);
389 /* Emit and return the new instruction. */
390 pat = GEN_FCN (icode) (op0, addr_helper, op1);
391 if (! pat)
392 return NULL_RTX;
394 emit_move_insn (addr_helper, GEN_INT (0));
395 emit_insn (pat);
396 return target;
399 /* Expand cctl builtins. */
400 static rtx
401 nds32_expand_cctl_builtin (enum insn_code icode, tree exp, rtx target,
402 bool return_p, const char *name)
404 rtx pat;
405 rtx op0 = nds32_read_argument (exp, 0);
406 rtx op1 = nds32_read_argument (exp, 1);
407 int op0_num = return_p ? 1 : 0;
408 int op1_num = return_p ? 2 : 1;
410 if (return_p)
411 target = nds32_legitimize_target (icode, target);
413 if (!nds32_check_constant_argument (icode, op0_num, op0, name))
414 return NULL_RTX;
416 op0 = nds32_legitimize_argument (icode, op0_num, op0);
417 op1 = nds32_legitimize_argument (icode, op1_num, op1);
419 /* Emit and return the new instruction. */
420 if (icode == CODE_FOR_cctl_idx_write)
422 /* cctl_idx_write is three argument,
423 so create operand2 for cctl_idx_write pattern. */
424 rtx op2 = nds32_read_argument (exp, 2);
425 op2 = nds32_legitimize_argument (icode, 2, op2);
426 pat = GEN_FCN (icode) (op0, op1, op2);
428 else if (return_p)
429 pat = GEN_FCN (icode) (target, op0, op1);
430 else
431 pat = GEN_FCN (icode) (op0, op1);
433 if (! pat)
434 return NULL_RTX;
436 emit_insn (pat);
437 return target;
440 /* Expand scw builtins. */
441 static rtx
442 nds32_expand_scw_builtin (enum insn_code icode, tree exp, rtx target)
444 /* SCW address format is [$ra + $rb], but input arguments not enough,
445 so we need another temp register as $rb.
446 Generating assembly code:
447 movi $temp, 0
448 scw $rt, [$ra + $temp] */
449 rtx pat;
450 rtx op0 = nds32_read_argument (exp, 0);
451 rtx op1 = nds32_read_argument (exp, 1);
452 rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode);
454 target = nds32_legitimize_target (icode, target);
455 op0 = nds32_legitimize_argument (icode, 1, op0);
456 op1 = nds32_legitimize_argument (icode, 2, op1);
458 /* Emit and return the new instruction. */
459 pat = GEN_FCN (icode) (target, op0, addr_helper, target);
461 if (!pat)
462 return NULL_RTX;
464 emit_move_insn (addr_helper, GEN_INT (0));
465 emit_move_insn (target, op1);
466 emit_insn (pat);
467 return target;
470 /* Expand set int priority builtins. */
471 static rtx
472 nds32_expand_priority_builtin (enum insn_code icode, tree exp, rtx target,
473 const char *name)
475 rtx pat;
476 rtx op0 = nds32_read_argument (exp, 0);
477 rtx op1 = nds32_read_argument (exp, 1);
479 /* set_int_priority intrinsic function that two arguments are immediate,
480 so check whether auguments are immedite. */
482 if (!nds32_check_constant_argument (icode, 0, op0, name))
483 return NULL_RTX;
485 if (!nds32_check_constant_argument (icode, 1, op1, name))
486 return NULL_RTX;
488 op0 = nds32_legitimize_argument (icode, 0, op0);
489 op1 = nds32_legitimize_argument (icode, 1, op1);
491 /* Emit and return the new instruction. */
492 pat = GEN_FCN (icode) (op0, op1);
494 if (! pat)
495 return NULL_RTX;
497 emit_insn (pat);
498 return target;
501 struct builtin_description
503 const enum insn_code icode;
504 const char *name;
505 enum nds32_builtins code;
506 bool return_p;
509 #define NDS32_BUILTIN(code, string, builtin) \
510 { CODE_FOR_##code, "__nds32__" string, \
511 NDS32_BUILTIN_##builtin, true },
513 #define NDS32_NO_TARGET_BUILTIN(code, string, builtin) \
514 { CODE_FOR_##code, "__nds32__" string, \
515 NDS32_BUILTIN_##builtin, false },
517 /* Intrinsics that no argument, and that return value. */
518 static struct builtin_description bdesc_noarg[] =
520 NDS32_BUILTIN(unspec_fmfcfg, "fmfcfg", FMFCFG)
521 NDS32_BUILTIN(unspec_fmfcsr, "fmfcsr", FMFCSR)
522 NDS32_BUILTIN(unspec_get_current_sp, "get_current_sp", GET_CURRENT_SP)
523 NDS32_BUILTIN(unspec_return_address, "return_address", RETURN_ADDRESS)
524 NDS32_BUILTIN(unspec_get_all_pending_int, "get_all_pending_int",
525 GET_ALL_PENDING_INT)
528 /* Intrinsics that take just one argument. */
529 static struct builtin_description bdesc_1arg[] =
531 NDS32_BUILTIN(unspec_ssabssi2, "abs", ABS)
532 NDS32_BUILTIN(clzsi2, "clz", CLZ)
533 NDS32_BUILTIN(unspec_clo, "clo", CLO)
534 NDS32_BUILTIN(unspec_wsbh, "wsbh", WSBH)
535 NDS32_BUILTIN(unspec_tlbop_pb, "tlbop_pb",TLBOP_PB)
536 NDS32_BUILTIN(unaligned_load_hw, "unaligned_load_hw", UALOAD_HW)
537 NDS32_BUILTIN(unaligned_loadsi, "unaligned_load_w", UALOAD_W)
538 NDS32_BUILTIN(unaligned_loaddi, "unaligned_load_dw", UALOAD_DW)
539 NDS32_NO_TARGET_BUILTIN(unspec_volatile_isync, "isync", ISYNC)
540 NDS32_NO_TARGET_BUILTIN(unspec_fmtcsr, "fmtcsr", FMTCSR)
541 NDS32_NO_TARGET_BUILTIN(unspec_jr_itoff, "jr_itoff", JR_ITOFF)
542 NDS32_NO_TARGET_BUILTIN(unspec_jr_toff, "jr_toff", JR_TOFF)
543 NDS32_NO_TARGET_BUILTIN(unspec_jral_ton, "jral_ton", JRAL_TON)
544 NDS32_NO_TARGET_BUILTIN(unspec_ret_toff, "ret_toff", RET_TOFF)
545 NDS32_NO_TARGET_BUILTIN(unspec_jral_iton, "jral_iton",JRAL_ITON)
546 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_trd, "tlbop_trd", TLBOP_TRD)
547 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_twr, "tlbop_twr", TLBOP_TWR)
548 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_rwr, "tlbop_rwr", TLBOP_RWR)
549 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_rwlk, "tlbop_rwlk", TLBOP_RWLK)
550 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_unlk, "tlbop_unlk", TLBOP_UNLK)
551 NDS32_NO_TARGET_BUILTIN(unspec_tlbop_inv, "tlbop_inv", TLBOP_INV)
552 NDS32_NO_TARGET_BUILTIN(unspec_ret_itoff, "ret_itoff", RET_ITOFF)
553 NDS32_NO_TARGET_BUILTIN(unspec_set_current_sp,
554 "set_current_sp", SET_CURRENT_SP)
557 /* Intrinsics that take just one argument. and the argument is immediate. */
558 static struct builtin_description bdesc_1argimm[] =
560 NDS32_BUILTIN(unspec_volatile_mfsr, "mfsr", MFSR)
561 NDS32_BUILTIN(unspec_volatile_mfusr, "mfsr", MFUSR)
562 NDS32_BUILTIN(unspec_get_pending_int, "get_pending_int", GET_PENDING_INT)
563 NDS32_BUILTIN(unspec_get_int_priority, "get_int_priority", GET_INT_PRIORITY)
564 NDS32_NO_TARGET_BUILTIN(unspec_trap, "trap", TRAP)
565 NDS32_NO_TARGET_BUILTIN(unspec_break, "break", BREAK)
566 NDS32_NO_TARGET_BUILTIN(unspec_syscall, "syscall", SYSCALL)
567 NDS32_NO_TARGET_BUILTIN(unspec_enable_int, "enable_int", ENABLE_INT)
568 NDS32_NO_TARGET_BUILTIN(unspec_disable_int, "disable_int", DISABLE_INT)
569 NDS32_NO_TARGET_BUILTIN(unspec_clr_pending_hwint, "clr_pending_hwint",
570 CLR_PENDING_HWINT)
571 NDS32_NO_TARGET_BUILTIN(unspec_set_trig_level, "set_trig_level",
572 SET_TRIG_LEVEL)
573 NDS32_NO_TARGET_BUILTIN(unspec_set_trig_edge, "set_trig_edge",
574 SET_TRIG_EDGE)
575 NDS32_BUILTIN(unspec_get_trig_type, "get_trig_type", GET_TRIG_TYPE)
578 /* Intrinsics that take two arguments. */
579 static struct builtin_description bdesc_2arg[] =
581 NDS32_BUILTIN(unspec_fcpynss, "fcpynss", FCPYNSS)
582 NDS32_BUILTIN(unspec_fcpyss, "fcpyss", FCPYSS)
583 NDS32_BUILTIN(unspec_fcpynsd, "fcpynsd", FCPYNSD)
584 NDS32_BUILTIN(unspec_fcpysd, "fcpysd", FCPYSD)
585 NDS32_BUILTIN(unspec_ave, "ave", AVE)
586 NDS32_BUILTIN(unspec_pbsad, "pbsad", PBSAD)
587 NDS32_BUILTIN(unspec_ffb, "ffb", FFB)
588 NDS32_BUILTIN(unspec_ffmism, "ffmsim", FFMISM)
589 NDS32_BUILTIN(unspec_flmism, "flmism", FLMISM)
590 NDS32_BUILTIN(rotrsi3, "rotr", ROTR)
591 NDS32_BUILTIN(unspec_sva, "sva", SVA)
592 NDS32_BUILTIN(unspec_svs, "svs", SVS)
593 NDS32_NO_TARGET_BUILTIN(mtsr_isb, "mtsr_isb", MTSR_ISB)
594 NDS32_NO_TARGET_BUILTIN(mtsr_dsb, "mtsr_dsb", MTSR_DSB)
595 NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtsr, "mtsr", MTSR)
596 NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtusr, "mtusr", MTUSR)
597 NDS32_NO_TARGET_BUILTIN(unaligned_store_hw, "unaligned_store_hw", UASTORE_HW)
598 NDS32_NO_TARGET_BUILTIN(unaligned_storesi, "unaligned_store_hw", UASTORE_W)
599 NDS32_NO_TARGET_BUILTIN(unaligned_storedi, "unaligned_store_hw", UASTORE_DW)
603 /* Two-argument intrinsics with an immediate second argument. */
604 static struct builtin_description bdesc_2argimm[] =
606 NDS32_BUILTIN(unspec_bclr, "bclr", BCLR)
607 NDS32_BUILTIN(unspec_bset, "bset", BSET)
608 NDS32_BUILTIN(unspec_btgl, "btgl", BTGL)
609 NDS32_BUILTIN(unspec_btst, "btst", BTST)
610 NDS32_BUILTIN(unspec_clip, "clip", CLIP)
611 NDS32_BUILTIN(unspec_clips, "clips", CLIPS)
612 NDS32_NO_TARGET_BUILTIN(unspec_teqz, "teqz", TEQZ)
613 NDS32_NO_TARGET_BUILTIN(unspec_tnez, "tnez", TNEZ)
616 /* Intrinsics that take three arguments. */
617 static struct builtin_description bdesc_3arg[] =
619 NDS32_BUILTIN(unspec_pbsada, "pbsada", PBSADA)
620 NDS32_NO_TARGET_BUILTIN(bse, "bse", BSE)
621 NDS32_NO_TARGET_BUILTIN(bsp, "bsp", BSP)
624 /* Three-argument intrinsics with an immediate third argument. */
625 static struct builtin_description bdesc_3argimm[] =
627 NDS32_NO_TARGET_BUILTIN(prefetch_qw, "prefetch_qw", DPREF_QW)
628 NDS32_NO_TARGET_BUILTIN(prefetch_hw, "prefetch_hw", DPREF_HW)
629 NDS32_NO_TARGET_BUILTIN(prefetch_w, "prefetch_w", DPREF_W)
630 NDS32_NO_TARGET_BUILTIN(prefetch_dw, "prefetch_dw", DPREF_DW)
633 /* Intrinsics that load a value. */
634 static struct builtin_description bdesc_load[] =
636 NDS32_BUILTIN(unspec_volatile_llw, "llw", LLW)
637 NDS32_BUILTIN(unspec_lwup, "lwup", LWUP)
638 NDS32_BUILTIN(unspec_lbup, "lbup", LBUP)
641 /* Intrinsics that store a value. */
642 static struct builtin_description bdesc_store[] =
644 NDS32_BUILTIN(unspec_swup, "swup", SWUP)
645 NDS32_BUILTIN(unspec_sbup, "sbup", SBUP)
648 static struct builtin_description bdesc_cctl[] =
650 NDS32_BUILTIN(cctl_idx_read, "cctl_idx_read", CCTL_IDX_READ)
651 NDS32_NO_TARGET_BUILTIN(cctl_idx_write, "cctl_idx_write", CCTL_IDX_WRITE)
652 NDS32_NO_TARGET_BUILTIN(cctl_va_lck, "cctl_va_lck", CCTL_VA_LCK)
653 NDS32_NO_TARGET_BUILTIN(cctl_idx_wbinval,
654 "cctl_idx_wbinval", CCTL_IDX_WBINVAL)
655 NDS32_NO_TARGET_BUILTIN(cctl_va_wbinval_l1,
656 "cctl_va_wbinval_l1", CCTL_VA_WBINVAL_L1)
657 NDS32_NO_TARGET_BUILTIN(cctl_va_wbinval_la,
658 "cctl_va_wbinval_la", CCTL_VA_WBINVAL_LA)
662 nds32_expand_builtin_impl (tree exp,
663 rtx target,
664 rtx subtarget ATTRIBUTE_UNUSED,
665 enum machine_mode mode ATTRIBUTE_UNUSED,
666 int ignore ATTRIBUTE_UNUSED)
668 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
669 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
670 unsigned i;
671 struct builtin_description *d;
673 switch (fcode)
675 /* FPU Register Transfer. */
676 case NDS32_BUILTIN_FMFCFG:
677 case NDS32_BUILTIN_FMFCSR:
678 case NDS32_BUILTIN_FMTCSR:
679 case NDS32_BUILTIN_FCPYNSS:
680 case NDS32_BUILTIN_FCPYSS:
681 /* Both v3s and v3f toolchains define TARGET_FPU_SINGLE. */
682 if (!TARGET_FPU_SINGLE)
684 error ("this builtin function is only available "
685 "on the v3s or v3f toolchain");
686 return NULL_RTX;
688 break;
690 /* FPU Register Transfer. */
691 case NDS32_BUILTIN_FCPYNSD:
692 case NDS32_BUILTIN_FCPYSD:
693 /* Only v3f toolchain defines TARGET_FPU_DOUBLE. */
694 if (!TARGET_FPU_DOUBLE)
696 error ("this builtin function is only available "
697 "on the v3f toolchain");
698 return NULL_RTX;
700 break;
702 /* Load and Store */
703 case NDS32_BUILTIN_LLW:
704 case NDS32_BUILTIN_LWUP:
705 case NDS32_BUILTIN_LBUP:
706 case NDS32_BUILTIN_SCW:
707 case NDS32_BUILTIN_SWUP:
708 case NDS32_BUILTIN_SBUP:
709 if (TARGET_ISA_V3M)
711 error ("this builtin function not support "
712 "on the v3m toolchain");
713 return NULL_RTX;
715 break;
717 /* Performance Extension */
718 case NDS32_BUILTIN_ABS:
719 case NDS32_BUILTIN_AVE:
720 case NDS32_BUILTIN_BCLR:
721 case NDS32_BUILTIN_BSET:
722 case NDS32_BUILTIN_BTGL:
723 case NDS32_BUILTIN_BTST:
724 case NDS32_BUILTIN_CLIP:
725 case NDS32_BUILTIN_CLIPS:
726 case NDS32_BUILTIN_CLZ:
727 case NDS32_BUILTIN_CLO:
728 if (!TARGET_EXT_PERF)
730 error ("don't support performance extension instructions");
731 return NULL_RTX;
733 break;
735 /* Performance Extension 2 */
736 case NDS32_BUILTIN_PBSAD:
737 case NDS32_BUILTIN_PBSADA:
738 case NDS32_BUILTIN_BSE:
739 case NDS32_BUILTIN_BSP:
740 if (!TARGET_EXT_PERF2)
742 error ("don't support performance extension "
743 "version 2 instructions");
744 return NULL_RTX;
746 break;
748 /* String Extension */
749 case NDS32_BUILTIN_FFB:
750 case NDS32_BUILTIN_FFMISM:
751 case NDS32_BUILTIN_FLMISM:
752 if (!TARGET_EXT_STRING)
754 error ("don't support string extension instructions");
755 return NULL_RTX;
757 break;
759 default:
760 break;
763 /* Since there are no result and operands, we can simply emit this rtx. */
764 switch (fcode)
766 case NDS32_BUILTIN_ISB:
767 emit_insn (gen_unspec_volatile_isb ());
768 return target;
769 case NDS32_BUILTIN_DSB:
770 emit_insn (gen_unspec_dsb ());
771 return target;
772 case NDS32_BUILTIN_MSYNC_ALL:
773 emit_insn (gen_unspec_msync_all ());
774 return target;
775 case NDS32_BUILTIN_MSYNC_STORE:
776 emit_insn (gen_unspec_msync_store ());
777 return target;
778 case NDS32_BUILTIN_SETGIE_EN:
779 emit_insn (gen_unspec_volatile_setgie_en ());
780 emit_insn (gen_unspec_dsb ());
781 return target;
782 case NDS32_BUILTIN_SETGIE_DIS:
783 emit_insn (gen_unspec_volatile_setgie_dis ());
784 emit_insn (gen_unspec_dsb ());
785 return target;
786 case NDS32_BUILTIN_GIE_DIS:
787 emit_insn (gen_unspec_volatile_setgie_dis ());
788 emit_insn (gen_unspec_dsb ());
789 return target;
790 case NDS32_BUILTIN_GIE_EN:
791 emit_insn (gen_unspec_volatile_setgie_en ());
792 emit_insn (gen_unspec_dsb ());
793 return target;
794 case NDS32_BUILTIN_SET_PENDING_SWINT:
795 emit_insn (gen_unspec_set_pending_swint ());
796 return target;
797 case NDS32_BUILTIN_CLR_PENDING_SWINT:
798 emit_insn (gen_unspec_clr_pending_swint ());
799 return target;
800 case NDS32_BUILTIN_CCTL_L1D_INVALALL:
801 emit_insn (gen_cctl_l1d_invalall());
802 return target;
803 case NDS32_BUILTIN_CCTL_L1D_WBALL_ALVL:
804 emit_insn (gen_cctl_l1d_wball_alvl());
805 return target;
806 case NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL:
807 emit_insn (gen_cctl_l1d_wball_one_lvl());
808 return target;
809 case NDS32_BUILTIN_STANDBY_NO_WAKE_GRANT:
810 emit_insn (gen_unspec_standby_no_wake_grant ());
811 return target;
812 case NDS32_BUILTIN_STANDBY_WAKE_GRANT:
813 emit_insn (gen_unspec_standby_wake_grant ());
814 return target;
815 case NDS32_BUILTIN_STANDBY_WAKE_DONE:
816 emit_insn (gen_unspec_standby_wait_done ());
817 return target;
818 case NDS32_BUILTIN_SETEND_BIG:
819 emit_insn (gen_unspec_setend_big ());
820 return target;
821 case NDS32_BUILTIN_SETEND_LITTLE:
822 emit_insn (gen_unspec_setend_little ());
823 return target;
824 case NDS32_BUILTIN_NOP:
825 emit_insn (gen_unspec_nop ());
826 return target;
827 case NDS32_BUILTIN_SCHE_BARRIER:
828 emit_insn (gen_blockage ());
829 return target;
830 case NDS32_BUILTIN_TLBOP_FLUA:
831 emit_insn (gen_unspec_tlbop_flua ());
832 return target;
833 case NDS32_BUILTIN_SCW:
834 return nds32_expand_scw_builtin (CODE_FOR_unspec_volatile_scw,
835 exp, target);
836 case NDS32_BUILTIN_SET_INT_PRIORITY:
837 return nds32_expand_priority_builtin (CODE_FOR_unspec_set_int_priority,
838 exp, target,
839 "__nds32__set_int_priority");
840 return target;
841 default:
842 break;
845 /* Expand groups of builtins. */
846 for (i = 0, d = bdesc_noarg; i < ARRAY_SIZE (bdesc_noarg); i++, d++)
847 if (d->code == fcode)
848 return nds32_expand_noarg_builtin (d->icode, target);
850 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
851 if (d->code == fcode)
852 return nds32_expand_unop_builtin (d->icode, exp, target, d->return_p);
854 for (i = 0, d = bdesc_1argimm; i < ARRAY_SIZE (bdesc_1argimm); i++, d++)
855 if (d->code == fcode)
856 return nds32_expand_unopimm_builtin (d->icode, exp, target,
857 d->return_p, d->name);
859 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
860 if (d->code == fcode)
861 return nds32_expand_binop_builtin (d->icode, exp, target, d->return_p);
863 for (i = 0, d = bdesc_2argimm; i < ARRAY_SIZE (bdesc_2argimm); i++, d++)
864 if (d->code == fcode)
865 return nds32_expand_binopimm_builtin (d->icode, exp, target,
866 d->return_p, d->name);
868 for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
869 if (d->code == fcode)
870 return nds32_expand_triop_builtin (d->icode, exp, target, d->return_p);
872 for (i = 0, d = bdesc_3argimm; i < ARRAY_SIZE (bdesc_3argimm); i++, d++)
873 if (d->code == fcode)
874 return nds32_expand_triopimm_builtin (d->icode, exp, target,
875 d->return_p, d->name);
877 for (i = 0, d = bdesc_load; i < ARRAY_SIZE (bdesc_load); i++, d++)
878 if (d->code == fcode)
879 return nds32_expand_builtin_load (d->icode, exp, target);
881 for (i = 0, d = bdesc_store; i < ARRAY_SIZE (bdesc_store); i++, d++)
882 if (d->code == fcode)
883 return nds32_expand_builtin_store (d->icode, exp, target);
885 for (i = 0, d = bdesc_cctl; i < ARRAY_SIZE (bdesc_cctl); i++, d++)
886 if (d->code == fcode)
887 return nds32_expand_cctl_builtin (d->icode, exp, target,
888 d->return_p, d->name);
890 return NULL_RTX;
893 static GTY(()) tree nds32_builtin_decls[NDS32_BUILTIN_COUNT];
895 /* Return the NDS32 builtin for CODE. */
896 tree
897 nds32_builtin_decl_impl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
899 if (code >= NDS32_BUILTIN_COUNT)
900 return error_mark_node;
902 return nds32_builtin_decls[code];
905 void
906 nds32_init_builtins_impl (void)
908 #define ADD_NDS32_BUILTIN0(NAME, RET_TYPE, CODE) \
909 nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \
910 add_builtin_function ("__builtin_nds32_" NAME, \
911 build_function_type_list (RET_TYPE##_type_node, \
912 NULL_TREE), \
913 NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
915 #define ADD_NDS32_BUILTIN1(NAME, RET_TYPE, ARG_TYPE, CODE) \
916 nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \
917 add_builtin_function ("__builtin_nds32_" NAME, \
918 build_function_type_list (RET_TYPE##_type_node, \
919 ARG_TYPE##_type_node, \
920 NULL_TREE), \
921 NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
923 #define ADD_NDS32_BUILTIN2(NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2, CODE) \
924 nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \
925 add_builtin_function ("__builtin_nds32_" NAME, \
926 build_function_type_list (RET_TYPE##_type_node, \
927 ARG_TYPE1##_type_node,\
928 ARG_TYPE2##_type_node,\
929 NULL_TREE), \
930 NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
932 #define ADD_NDS32_BUILTIN3(NAME, RET_TYPE, \
933 ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, CODE) \
934 nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \
935 add_builtin_function ("__builtin_nds32_" NAME, \
936 build_function_type_list (RET_TYPE##_type_node, \
937 ARG_TYPE1##_type_node,\
938 ARG_TYPE2##_type_node,\
939 ARG_TYPE3##_type_node,\
940 NULL_TREE), \
941 NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
943 /* Looking for return type and argument can be found in tree.h file. */
944 tree ptr_uchar_type_node = build_pointer_type (unsigned_char_type_node);
945 tree ptr_ushort_type_node = build_pointer_type (short_unsigned_type_node);
946 tree ptr_uint_type_node = build_pointer_type (unsigned_type_node);
947 tree ptr_ulong_type_node = build_pointer_type (long_long_unsigned_type_node);
949 /* Cache. */
950 ADD_NDS32_BUILTIN1 ("isync", void, ptr_uint, ISYNC);
951 ADD_NDS32_BUILTIN0 ("isb", void, ISB);
952 ADD_NDS32_BUILTIN0 ("dsb", void, DSB);
953 ADD_NDS32_BUILTIN0 ("msync_all", void, MSYNC_ALL);
954 ADD_NDS32_BUILTIN0 ("msync_store", void, MSYNC_STORE);
956 /* Register Transfer. */
957 ADD_NDS32_BUILTIN1 ("mfsr", unsigned, integer, MFSR);
958 ADD_NDS32_BUILTIN1 ("mfusr", unsigned, integer, MFUSR);
959 ADD_NDS32_BUILTIN2 ("mtsr", void, unsigned, integer, MTSR);
960 ADD_NDS32_BUILTIN2 ("mtsr_isb", void, unsigned, integer, MTSR_ISB);
961 ADD_NDS32_BUILTIN2 ("mtsr_dsb", void, unsigned, integer, MTSR_DSB);
962 ADD_NDS32_BUILTIN2 ("mtusr", void, unsigned, integer, MTUSR);
964 /* FPU Register Transfer. */
965 ADD_NDS32_BUILTIN0 ("fmfcsr", unsigned, FMFCSR);
966 ADD_NDS32_BUILTIN1 ("fmtcsr", void, unsigned, FMTCSR);
967 ADD_NDS32_BUILTIN0 ("fmfcfg", unsigned, FMFCFG);
968 ADD_NDS32_BUILTIN2 ("fcpyss", float, float, float, FCPYSS);
969 ADD_NDS32_BUILTIN2 ("fcpynss", float, float, float, FCPYNSS);
970 ADD_NDS32_BUILTIN2 ("fcpysd", double, double, double, FCPYSD);
971 ADD_NDS32_BUILTIN2 ("fcpynsd", double, double, double, FCPYNSD);
973 /* Interrupt. */
974 ADD_NDS32_BUILTIN0 ("setgie_en", void, SETGIE_EN);
975 ADD_NDS32_BUILTIN0 ("setgie_dis", void, SETGIE_DIS);
976 ADD_NDS32_BUILTIN0 ("gie_en", void, GIE_EN);
977 ADD_NDS32_BUILTIN0 ("gie_dis", void, GIE_DIS);
978 ADD_NDS32_BUILTIN1 ("enable_int", void, integer, ENABLE_INT);
979 ADD_NDS32_BUILTIN1 ("disable_int", void, integer, DISABLE_INT);
980 ADD_NDS32_BUILTIN0 ("set_pending_swint", void, SET_PENDING_SWINT);
981 ADD_NDS32_BUILTIN0 ("clr_pending_swint", void, CLR_PENDING_SWINT);
982 ADD_NDS32_BUILTIN0 ("get_all_pending_int", unsigned, GET_ALL_PENDING_INT);
983 ADD_NDS32_BUILTIN1 ("get_pending_int", unsigned, integer, GET_PENDING_INT);
984 ADD_NDS32_BUILTIN1 ("get_int_priority", unsigned, integer, GET_INT_PRIORITY);
985 ADD_NDS32_BUILTIN2 ("set_int_priority", void, integer, integer,
986 SET_INT_PRIORITY);
987 ADD_NDS32_BUILTIN1 ("clr_pending_hwint", void, integer, CLR_PENDING_HWINT);
988 ADD_NDS32_BUILTIN1 ("set_trig_level", void, integer, SET_TRIG_LEVEL);
989 ADD_NDS32_BUILTIN1 ("set_trig_edge", void, integer, SET_TRIG_EDGE);
990 ADD_NDS32_BUILTIN1 ("get_trig_type", unsigned, integer, GET_TRIG_TYPE);
992 /* Load and Store */
993 ADD_NDS32_BUILTIN1 ("llw", unsigned, ptr_uint, LLW);
994 ADD_NDS32_BUILTIN1 ("lwup", unsigned, ptr_uint, LWUP);
995 ADD_NDS32_BUILTIN1 ("lbup", char, ptr_uchar, LBUP);
996 ADD_NDS32_BUILTIN2 ("scw", unsigned, ptr_uint, unsigned, SCW);
997 ADD_NDS32_BUILTIN2 ("swup", void, ptr_uint, unsigned, SWUP);
998 ADD_NDS32_BUILTIN2 ("sbup", void, ptr_uchar, char, SBUP);
1000 /* CCTL */
1001 ADD_NDS32_BUILTIN0 ("cctl_l1d_invalall", void, CCTL_L1D_INVALALL);
1002 ADD_NDS32_BUILTIN0 ("cctl_l1d_wball_alvl", void, CCTL_L1D_WBALL_ALVL);
1003 ADD_NDS32_BUILTIN0 ("cctl_l1d_wball_one_lvl", void, CCTL_L1D_WBALL_ONE_LVL);
1004 ADD_NDS32_BUILTIN2 ("cctl_va_lck", void, integer, ptr_uint, CCTL_VA_LCK);
1005 ADD_NDS32_BUILTIN2 ("cctl_idx_wbinval", void, integer, unsigned,
1006 CCTL_IDX_WBINVAL);
1007 ADD_NDS32_BUILTIN2 ("cctl_va_wbinval_l1", void, integer, ptr_uint,
1008 CCTL_VA_WBINVAL_L1);
1009 ADD_NDS32_BUILTIN2 ("cctl_va_wbinval_la", void, integer, ptr_uint,
1010 CCTL_VA_WBINVAL_LA);
1011 ADD_NDS32_BUILTIN2 ("cctl_idx_read", unsigned, integer, unsigned,
1012 CCTL_IDX_READ);
1013 ADD_NDS32_BUILTIN3 ("cctl_idx_write", void, integer, unsigned, unsigned,
1014 CCTL_IDX_WRITE);
1016 /* PREFETCH */
1017 ADD_NDS32_BUILTIN3 ("dpref_qw", void, ptr_uchar, unsigned, integer, DPREF_QW);
1018 ADD_NDS32_BUILTIN3 ("dpref_hw", void, ptr_ushort, unsigned, integer,
1019 DPREF_HW);
1020 ADD_NDS32_BUILTIN3 ("dpref_w", void, ptr_uint, unsigned, integer, DPREF_W);
1021 ADD_NDS32_BUILTIN3 ("dpref_dw", void, ptr_ulong, unsigned, integer, DPREF_DW);
1023 /* Performance Extension */
1024 ADD_NDS32_BUILTIN1 ("pe_abs", integer, integer, ABS);
1025 ADD_NDS32_BUILTIN2 ("pe_ave", integer, integer, integer, AVE);
1026 ADD_NDS32_BUILTIN2 ("pe_bclr", unsigned, unsigned, unsigned, BCLR);
1027 ADD_NDS32_BUILTIN2 ("pe_bset", unsigned, unsigned, unsigned, BSET);
1028 ADD_NDS32_BUILTIN2 ("pe_btgl", unsigned, unsigned, unsigned, BTGL);
1029 ADD_NDS32_BUILTIN2 ("pe_btst", unsigned, unsigned, unsigned, BTST);
1030 ADD_NDS32_BUILTIN2 ("pe_clip", unsigned, integer, unsigned, CLIP);
1031 ADD_NDS32_BUILTIN2 ("pe_clips", integer, integer, unsigned, CLIPS);
1032 ADD_NDS32_BUILTIN1 ("pe_clz", unsigned, unsigned, CLZ);
1033 ADD_NDS32_BUILTIN1 ("pe_clo", unsigned, unsigned, CLO);
1035 /* Performance Extension 2 */
1036 ADD_NDS32_BUILTIN3 ("pe2_bse", void, ptr_uint, unsigned, ptr_uint, BSE);
1037 ADD_NDS32_BUILTIN3 ("pe2_bsp", void, ptr_uint, unsigned, ptr_uint, BSP);
1038 ADD_NDS32_BUILTIN2 ("pe2_pbsad", unsigned, unsigned, unsigned, PBSAD);
1039 ADD_NDS32_BUILTIN3 ("pe2_pbsada", unsigned, unsigned, unsigned, unsigned,
1040 PBSADA);
1042 /* String Extension */
1043 ADD_NDS32_BUILTIN2 ("se_ffb", integer, unsigned, unsigned, FFB);
1044 ADD_NDS32_BUILTIN2 ("se_ffmism", integer, unsigned, unsigned, FFMISM);
1045 ADD_NDS32_BUILTIN2 ("se_flmism", integer, unsigned, unsigned, FLMISM);
1048 /* ROTR */
1049 ADD_NDS32_BUILTIN2 ("rotr", unsigned, unsigned, unsigned, ROTR);
1051 /* Swap */
1052 ADD_NDS32_BUILTIN1 ("wsbh", unsigned, unsigned, WSBH);
1054 /* System */
1055 ADD_NDS32_BUILTIN2 ("svs", unsigned, integer, integer, SVS);
1056 ADD_NDS32_BUILTIN2 ("sva", unsigned, integer, integer, SVA);
1057 ADD_NDS32_BUILTIN1 ("jr_itoff", void, unsigned, JR_ITOFF);
1058 ADD_NDS32_BUILTIN1 ("jr_toff", void, unsigned, JR_TOFF);
1059 ADD_NDS32_BUILTIN1 ("jral_iton", void, unsigned, JRAL_ITON);
1060 ADD_NDS32_BUILTIN1 ("jral_ton", void, unsigned, JRAL_TON);
1061 ADD_NDS32_BUILTIN1 ("ret_itoff", void, unsigned, RET_ITOFF);
1062 ADD_NDS32_BUILTIN1 ("ret_toff", void, unsigned, RET_TOFF);
1063 ADD_NDS32_BUILTIN0 ("standby_no_wake_grant", void, STANDBY_NO_WAKE_GRANT);
1064 ADD_NDS32_BUILTIN0 ("standby_wake_grant", void, STANDBY_WAKE_GRANT);
1065 ADD_NDS32_BUILTIN0 ("standby_wait_done", void, STANDBY_WAKE_DONE);
1066 ADD_NDS32_BUILTIN1 ("break", void, unsigned, BREAK);
1067 ADD_NDS32_BUILTIN1 ("syscall", void, unsigned, SYSCALL);
1068 ADD_NDS32_BUILTIN0 ("nop", void, NOP);
1069 ADD_NDS32_BUILTIN0 ("get_current_sp", unsigned, GET_CURRENT_SP);
1070 ADD_NDS32_BUILTIN1 ("set_current_sp", void, unsigned, SET_CURRENT_SP);
1071 ADD_NDS32_BUILTIN2 ("teqz", void, unsigned, unsigned, TEQZ);
1072 ADD_NDS32_BUILTIN2 ("tnez", void, unsigned, unsigned, TNEZ);
1073 ADD_NDS32_BUILTIN1 ("trap", void, unsigned, TRAP);
1074 ADD_NDS32_BUILTIN0 ("return_address", unsigned, RETURN_ADDRESS);
1075 ADD_NDS32_BUILTIN0 ("setend_big", void, SETEND_BIG);
1076 ADD_NDS32_BUILTIN0 ("setend_little", void, SETEND_LITTLE);
1078 /* Schedule Barrier */
1079 ADD_NDS32_BUILTIN0 ("schedule_barrier", void, SCHE_BARRIER);
1081 /* TLBOP */
1082 ADD_NDS32_BUILTIN1 ("tlbop_trd", void, unsigned, TLBOP_TRD);
1083 ADD_NDS32_BUILTIN1 ("tlbop_twr", void, unsigned, TLBOP_TWR);
1084 ADD_NDS32_BUILTIN1 ("tlbop_rwr", void, unsigned, TLBOP_RWR);
1085 ADD_NDS32_BUILTIN1 ("tlbop_rwlk", void, unsigned, TLBOP_RWLK);
1086 ADD_NDS32_BUILTIN1 ("tlbop_unlk", void, unsigned, TLBOP_UNLK);
1087 ADD_NDS32_BUILTIN1 ("tlbop_pb", unsigned, unsigned, TLBOP_PB);
1088 ADD_NDS32_BUILTIN1 ("tlbop_inv", void, unsigned, TLBOP_INV);
1089 ADD_NDS32_BUILTIN0 ("tlbop_flua", void, TLBOP_FLUA);
1091 /* Unaligned Load/Store */
1092 ADD_NDS32_BUILTIN1 ("unaligned_load_hw", short_unsigned, ptr_ushort,
1093 UALOAD_HW);
1094 ADD_NDS32_BUILTIN1 ("unaligned_load_w", unsigned, ptr_uint, UALOAD_W);
1095 ADD_NDS32_BUILTIN1 ("unaligned_load_dw", long_long_unsigned, ptr_ulong,
1096 UALOAD_DW);
1097 ADD_NDS32_BUILTIN2 ("unaligned_store_hw", void, ptr_ushort, short_unsigned,
1098 UASTORE_HW);
1099 ADD_NDS32_BUILTIN2 ("unaligned_store_w", void, ptr_uint, unsigned, UASTORE_W);
1100 ADD_NDS32_BUILTIN2 ("unaligned_store_dw", void, ptr_ulong, long_long_unsigned,
1101 UASTORE_DW);