[NDS32] Add unaligned access support.
[official-gcc.git] / gcc / config / nds32 / nds32-intrinsic.md
blob24e7c0bf4a12207dff18a5402e90ed67d7ebb7b8
1 ;; Intrinsic patterns description of Andes NDS32 cpu for GNU compiler
2 ;; Copyright (C) 2012-2018 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.
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 ;; Register Transfer.
25 (define_insn "unspec_volatile_mfsr"
26   [(set (match_operand:SI 0 "register_operand" "=r")
27         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MFSR))]
28   ""
29   "mfsr\t%0, %V1"
30   [(set_attr "type"   "misc")
31    (set_attr "length"    "4")]
34 (define_insn "unspec_volatile_mfusr"
35   [(set (match_operand:SI 0 "register_operand" "=r")
36         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MFUSR))]
37   ""
38   "mfusr\t%0, %V1"
39   [(set_attr "type"   "misc")
40    (set_attr "length"    "4")]
43 (define_expand "mtsr_isb"
44   [(set (match_operand:SI 0 "register_operand" "")
45         (match_operand:SI 1 "immediate_operand" ""))]
46   ""
48   emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1]));
49   emit_insn (gen_unspec_volatile_isb());
50   DONE;
53 (define_expand "mtsr_dsb"
54   [(set (match_operand:SI 0 "register_operand" "")
55         (match_operand:SI 1 "immediate_operand" ""))]
56   ""
58   emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1]));
59   emit_insn (gen_unspec_dsb());
60   DONE;
63 (define_insn "unspec_volatile_mtsr"
64   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
65                         (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTSR)]
66   ""
67   "mtsr\t%0, %V1"
68   [(set_attr "type"   "misc")
69    (set_attr "length"    "4")]
72 (define_insn "unspec_volatile_mtusr"
73   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
74                         (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTUSR)]
75   ""
76   "mtusr\t%0, %V1"
77   [(set_attr "type"   "misc")
78    (set_attr "length"    "4")]
81 ;; FPU Register Transfer.
83 (define_insn "unspec_fcpynsd"
84    [(set (match_operand:DF 0 "register_operand" "=f")
85          (unspec:DF [(match_operand:DF 1 "register_operand" "f")
86                      (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYNSD))]
87   ""
88   "fcpynsd\t%0, %1, %2"
89   [(set_attr "type"   "misc")
90    (set_attr "length"    "4")]
93 (define_insn "unspec_fcpynss"
94    [(set (match_operand:SF 0 "register_operand" "=f")
95          (unspec:SF [(match_operand:SF 1 "register_operand" "f")
96                      (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYNSS))]
97   ""
98   "fcpynss\t%0, %1, %2"
99   [(set_attr "type"   "misc")
100    (set_attr "length"    "4")]
103 (define_insn "unspec_fcpysd"
104    [(set (match_operand:DF 0 "register_operand" "=f")
105          (unspec:DF [(match_operand:DF 1 "register_operand" "f")
106                      (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYSD))]
107   ""
108   "fcpysd\t%0, %1, %2"
109   [(set_attr "type"   "misc")
110    (set_attr "length"    "4")]
113 (define_insn "unspec_fcpyss"
114    [(set (match_operand:SF 0 "register_operand" "=f")
115          (unspec:SF [(match_operand:SF 1 "register_operand" "f")
116                      (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYSS))]
117   ""
118   "fcpyss\t%0, %1, %2"
119   [(set_attr "type"   "misc")
120    (set_attr "length"    "4")]
123 (define_insn "unspec_fmfcsr"
124    [(set (match_operand:SI 0 "register_operand" "=r")
125          (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCSR))]
126   ""
127   "fmfcsr\t%0"
128   [(set_attr "type"   "misc")
129    (set_attr "length"    "4")]
132 (define_insn "unspec_fmtcsr"
133   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_FMTCSR)]
134   ""
135   "fmtcsr\t%0"
136   [(set_attr "type"   "misc")
137    (set_attr "length"    "4")]
140 (define_insn "unspec_fmfcfg"
141   [(set (match_operand:SI 0 "register_operand" "=r")
142         (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCFG))]
143   ""
144   "fmfcfg\t%0"
145   [(set_attr "type"   "misc")
146    (set_attr "length"    "4")]
149 ;; ------------------------------------------------------------------------
151 ;; Interrupt Instructions.
153 (define_insn "unspec_volatile_setgie_en"
154   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETGIE_EN)]
155   ""
156   "setgie.e"
157   [(set_attr "type" "misc")]
160 (define_insn "unspec_volatile_setgie_dis"
161   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETGIE_DIS)]
162   ""
163   "setgie.d"
164   [(set_attr "type" "misc")]
167 (define_expand "unspec_enable_int"
168   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_ENABLE_INT)]
169   ""
171   rtx system_reg;
172   rtx temp_reg = gen_reg_rtx (SImode);
174   /* Set system register form nds32_intrinsic_register_names[].  */
175   if ((INTVAL (operands[0]) >= NDS32_INT_H16)
176       && (INTVAL (operands[0]) <= NDS32_INT_H31))
177     {
178       system_reg =  GEN_INT (__NDS32_REG_INT_MASK2__);
179       operands[0] = GEN_INT (1 << (INTVAL (operands[0])));
180     }
181   else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
182            && (INTVAL (operands[0]) <= NDS32_INT_H63))
183     {
184       system_reg =  GEN_INT (__NDS32_REG_INT_MASK3__);
185       operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 32));
186     }
187   else
188     {
189       system_reg =  GEN_INT (__NDS32_REG_INT_MASK__);
191       if (INTVAL (operands[0]) == NDS32_INT_SWI)
192         operands[0] = GEN_INT (1 << 16);
193       else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ)
194                && (INTVAL (operands[0]) <= NDS32_INT_DSSIM))
195         operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 4));
196       else
197         operands[0] = GEN_INT (1 << (INTVAL (operands[0])));
198     }
200   emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
201   emit_insn (gen_iorsi3 (temp_reg, temp_reg, operands[0]));
202   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
203   emit_insn (gen_unspec_dsb ());
204   DONE;
207 (define_expand "unspec_disable_int"
208   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_DISABLE_INT)]
209   ""
211   rtx system_reg;
212   rtx temp_reg = gen_reg_rtx (SImode);
214   /* Set system register form nds32_intrinsic_register_names[].  */
215   if ((INTVAL (operands[0]) >= NDS32_INT_H16)
216       && (INTVAL (operands[0]) <= NDS32_INT_H31))
217     {
218       system_reg =  GEN_INT (__NDS32_REG_INT_MASK2__);
219       operands[0] = GEN_INT (~(1 << INTVAL (operands[0])));
220     }
221   else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
222            && (INTVAL (operands[0]) <= NDS32_INT_H63))
223     {
224       system_reg =  GEN_INT (__NDS32_REG_INT_MASK3__);
225       operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 32)));
226     }
227   else
228     {
229       system_reg =  GEN_INT (__NDS32_REG_INT_MASK__);
231       if (INTVAL (operands[0]) == NDS32_INT_SWI)
232         operands[0] = GEN_INT (~(1 << 16));
233       else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ)
234                && (INTVAL (operands[0]) <= NDS32_INT_DSSIM))
235         operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 4)));
236       else
237         operands[0] = GEN_INT (~(1 << INTVAL (operands[0])));
238     }
240   emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
241   emit_insn (gen_andsi3 (temp_reg, temp_reg, operands[0]));
242   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
243   emit_insn (gen_unspec_dsb ());
244   DONE;
247 (define_expand "unspec_set_pending_swint"
248   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SET_PENDING_SWINT)]
249   ""
251   /* Get $INT_PEND system register form nds32_intrinsic_register_names[]  */
252   rtx system_reg =  GEN_INT (__NDS32_REG_INT_PEND__);
253   rtx temp_reg = gen_reg_rtx (SImode);
255   emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
256   emit_insn (gen_iorsi3 (temp_reg, temp_reg, GEN_INT (65536)));
257   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
258   emit_insn (gen_unspec_dsb ());
259   DONE;
262 (define_expand "unspec_clr_pending_swint"
263   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLR_PENDING_SWINT)]
264   ""
266   /* Get $INT_PEND system register form nds32_intrinsic_register_names[]  */
267   rtx system_reg =  GEN_INT (__NDS32_REG_INT_PEND__);
268   rtx temp_reg = gen_reg_rtx (SImode);
270   emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
271   emit_insn (gen_andsi3 (temp_reg, temp_reg, GEN_INT (~(1 << 16))));
272   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
273   emit_insn (gen_unspec_dsb ());
274   DONE;
277 (define_expand "unspec_clr_pending_hwint"
278   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_CLR_PENDING_HWINT)]
279   ""
281   rtx system_reg = NULL_RTX;
282   rtx temp_reg = gen_reg_rtx (SImode);
283   rtx clr_hwint;
284   unsigned offset = 0;
286   /* Set system register form nds32_intrinsic_register_names[].  */
287   if ((INTVAL (operands[0]) >= NDS32_INT_H0)
288       && (INTVAL (operands[0]) <= NDS32_INT_H15))
289     {
290       system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
291     }
292   else if ((INTVAL (operands[0]) >= NDS32_INT_H16)
293            && (INTVAL (operands[0]) <= NDS32_INT_H31))
294     {
295       system_reg = GEN_INT (__NDS32_REG_INT_PEND2__);
296     }
297   else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
298            && (INTVAL (operands[0]) <= NDS32_INT_H63))
299     {
300       system_reg = GEN_INT (__NDS32_REG_INT_PEND3__);
301       offset = 32;
302     }
303   else
304     error ("__nds32__clr_pending_hwint not support NDS32_INT_SWI,"
305            " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
307   /* $INT_PEND type is write one clear.  */
308   clr_hwint = GEN_INT (1 << (INTVAL (operands[0]) - offset));
310   if (system_reg != NULL_RTX)
311     {
312       emit_move_insn (temp_reg, clr_hwint);
313       emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
314       emit_insn (gen_unspec_dsb ());
315     }
316   DONE;
319 (define_expand "unspec_get_all_pending_int"
320   [(set (match_operand:SI 0 "register_operand" "")
321         (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_GET_ALL_PENDING_INT))]
322   ""
324   rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
325   emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
326   emit_insn (gen_unspec_dsb ());
327   DONE;
330 (define_expand "unspec_get_pending_int"
331   [(set (match_operand:SI 0 "register_operand" "")
332         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_PENDING_INT))]
333   ""
335   rtx system_reg = NULL_RTX;
337   /* Set system register form nds32_intrinsic_register_names[].  */
338   if ((INTVAL (operands[1]) >= NDS32_INT_H0)
339       && (INTVAL (operands[1]) <= NDS32_INT_H15))
340     {
341       system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
342       operands[2] = GEN_INT (31 - INTVAL (operands[1]));
343     }
344   else if (INTVAL (operands[1]) == NDS32_INT_SWI)
345     {
346       system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
347       operands[2] = GEN_INT (15);
348     }
349   else if ((INTVAL (operands[1]) >= NDS32_INT_H16)
350            && (INTVAL (operands[1]) <= NDS32_INT_H31))
351     {
352       system_reg = GEN_INT (__NDS32_REG_INT_PEND2__);
353       operands[2] = GEN_INT (31 - INTVAL (operands[1]));
354     }
355   else if ((INTVAL (operands[1]) >= NDS32_INT_H32)
356            && (INTVAL (operands[1]) <= NDS32_INT_H63))
357     {
358       system_reg = GEN_INT (__NDS32_REG_INT_PEND3__);
359       operands[2] = GEN_INT (31 - (INTVAL (operands[1]) - 32));
360     }
361   else
362     error ("get_pending_int not support NDS32_INT_ALZ,"
363            " NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
365   /* mfsr op0, sytem_reg  */
366   if (system_reg != NULL_RTX)
367     {
368       emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
369       emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
370       emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
371       emit_insn (gen_unspec_dsb ());
372     }
373   DONE;
376 (define_expand "unspec_set_int_priority"
377   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")
378                         (match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_SET_INT_PRIORITY)]
379   ""
381   rtx system_reg = NULL_RTX;
382   rtx priority = NULL_RTX;
383   rtx mask = NULL_RTX;
384   rtx temp_reg = gen_reg_rtx (SImode);
385   rtx mask_reg = gen_reg_rtx (SImode);
386   rtx set_reg = gen_reg_rtx (SImode);
387   unsigned offset = 0;
389   /* Get system register form nds32_intrinsic_register_names[].  */
390   if (INTVAL (operands[0]) <= NDS32_INT_H15)
391     {
392       system_reg =  GEN_INT (__NDS32_REG_INT_PRI__);
393       offset = 0;
394     }
395   else if (INTVAL (operands[0]) >= NDS32_INT_H16
396            && INTVAL (operands[0]) <= NDS32_INT_H31)
397     {
398       system_reg =  GEN_INT (__NDS32_REG_INT_PRI2__);
399       /* The $INT_PRI2 first bit correspond to H16, so need
400          subtract 16.  */
401       offset = 16;
402     }
403   else if (INTVAL (operands[0]) >= NDS32_INT_H32
404            && INTVAL (operands[0]) <= NDS32_INT_H47)
405     {
406       system_reg =  GEN_INT (__NDS32_REG_INT_PRI3__);
407       /* The $INT_PRI3 first bit correspond to H32, so need
408          subtract 32.  */
409       offset = 32;
410     }
411   else if (INTVAL (operands[0]) >= NDS32_INT_H48
412            && INTVAL (operands[0]) <= NDS32_INT_H63)
413     {
414       system_reg =  GEN_INT (__NDS32_REG_INT_PRI4__);
415       /* The $INT_PRI3 first bit correspond to H48, so need
416          subtract 48.  */
417       offset = 48;
418     }
419   else
420     error ("set_int_priority not support NDS32_INT_SWI,"
421            " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
423   mask = GEN_INT (~(3 << 2 * (INTVAL (operands[0]) - offset)));
424   priority = GEN_INT ((int) (INTVAL (operands[1])
425                              << ((INTVAL (operands[0]) - offset) * 2)));
427   if (system_reg != NULL_RTX)
428     {
429       emit_move_insn (mask_reg, mask);
430       emit_move_insn (set_reg, priority);
431       emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
432       emit_insn (gen_andsi3 (temp_reg, temp_reg, mask_reg));
433       emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_reg));
434       emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
435       emit_insn (gen_unspec_dsb ());
436     }
437   DONE;
440 (define_expand "unspec_get_int_priority"
441   [(set (match_operand:SI 0 "register_operand" "")
442         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_INT_PRIORITY))]
443   ""
445   rtx system_reg = NULL_RTX;
446   rtx priority = NULL_RTX;
447   unsigned offset = 0;
449   /* Get system register form nds32_intrinsic_register_names[]  */
450   if (INTVAL (operands[1]) <= NDS32_INT_H15)
451     {
452       system_reg =  GEN_INT (__NDS32_REG_INT_PRI__);
453       offset = 0;
454     }
455   else if (INTVAL (operands[1]) >= NDS32_INT_H16
456            && INTVAL (operands[1]) <= NDS32_INT_H31)
457     {
458       system_reg =  GEN_INT (__NDS32_REG_INT_PRI2__);
459       /* The $INT_PRI2 first bit correspond to H16, so need
460          subtract 16.  */
461       offset = 16;
462     }
463   else if (INTVAL (operands[1]) >= NDS32_INT_H32
464            && INTVAL (operands[1]) <= NDS32_INT_H47)
465     {
466       system_reg =  GEN_INT (__NDS32_REG_INT_PRI3__);
467       /* The $INT_PRI3 first bit correspond to H32, so need
468          subtract 32.  */
469       offset = 32;
470     }
471   else if (INTVAL (operands[1]) >= NDS32_INT_H48
472            && INTVAL (operands[1]) <= NDS32_INT_H63)
473     {
474       system_reg =  GEN_INT (__NDS32_REG_INT_PRI4__);
475       /* The $INT_PRI4 first bit correspond to H48, so need
476          subtract 48.  */
477       offset = 48;
478     }
479   else
480     error ("set_int_priority not support NDS32_INT_SWI,"
481            " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
483   priority = GEN_INT (31 - 2 * (INTVAL (operands[1]) - offset));
485   if (system_reg != NULL_RTX)
486     {
487       emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
488       emit_insn (gen_ashlsi3 (operands[0], operands[0], priority));
489       emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (30)));
490       emit_insn (gen_unspec_dsb ());
491     }
492   DONE;
495 (define_expand "unspec_set_trig_level"
496   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_LEVEL)]
497   ""
499   rtx system_reg = NULL_RTX;
500   rtx temp_reg = gen_reg_rtx (SImode);
501   rtx set_level;
502   unsigned offset = 0;
504   if (INTVAL (operands[0]) >= NDS32_INT_H0
505       && INTVAL (operands[0]) <= NDS32_INT_H31)
506     {
507       system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
508       offset = 0;
509     }
510   else if (INTVAL (operands[0]) >= NDS32_INT_H32
511            && INTVAL (operands[0]) <= NDS32_INT_H63)
512     {
513       system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
514       offset = 32;
515     }
516   else
517     error ("__nds32__set_trig_type_level not support NDS32_INT_SWI,"
518            " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
520   if (system_reg != NULL_RTX)
521     {
522       /* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */
523       set_level = GEN_INT (~(1 << (INTVAL (operands[0]) - offset)));
525       emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
526       emit_insn (gen_andsi3 (temp_reg, temp_reg, set_level));
527       emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
528     }
529   DONE;
532 (define_expand "unspec_set_trig_edge"
533   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_EDGE)]
534   ""
536   rtx system_reg = NULL_RTX;
537   rtx temp_reg = gen_reg_rtx (SImode);
538   rtx set_level;
539   unsigned offset = 0;
541   if (INTVAL (operands[0]) >= NDS32_INT_H0
542       && INTVAL (operands[0]) <= NDS32_INT_H31)
543     {
544       system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
545       offset = 0;
546     }
547   else if (INTVAL (operands[0]) >= NDS32_INT_H32
548            && INTVAL (operands[0]) <= NDS32_INT_H63)
549     {
550       system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
551       offset = 32;
552     }
553   else
554     error ("__nds32__set_trig_type_edge not support NDS32_INT_SWI,"
555            " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
557   if (system_reg != NULL_RTX)
558     {
559       /* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */
560       set_level = GEN_INT ((1 << (INTVAL (operands[0]) - offset)));
562       emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
563       emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_level));
564       emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
565     }
566   DONE;
569 (define_expand "unspec_get_trig_type"
570   [(set (match_operand:SI 0 "register_operand" "")
571         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_TRIG_TYPE))]
572   ""
574   rtx system_reg = NULL_RTX;
575   rtx trig_type;
576   unsigned offset = 0;
578   if (INTVAL (operands[1]) >= NDS32_INT_H0
579       && INTVAL (operands[1]) <= NDS32_INT_H31)
580     {
581       system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
582       offset = 0;
583     }
584   else if (INTVAL (operands[1]) >= NDS32_INT_H32
585            && INTVAL (operands[1]) <= NDS32_INT_H63)
586     {
587       system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
588       offset = 32;
589     }
590   else
591     error ("__nds32__get_trig_type not support NDS32_INT_SWI,"
592            " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
594   if (system_reg != NULL_RTX)
595     {
596       trig_type = GEN_INT (31 - (INTVAL (operands[1]) - offset));
598       emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
599       emit_insn (gen_ashlsi3 (operands[0], operands[0], trig_type));
600       emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
601       emit_insn (gen_unspec_dsb ());
602     }
603   DONE;
606 ;; ------------------------------------------------------------------------
608 ;; Cache Synchronization Instructions
610 (define_insn "unspec_volatile_isync"
611   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_ISYNC)]
612   ""
613   "isync\t%0"
614   [(set_attr "type" "misc")]
617 (define_insn "unspec_volatile_isb"
618   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_ISB)]
619   ""
620   "isb"
621   [(set_attr "type" "misc")]
624 (define_insn "unspec_dsb"
625   [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_DSB)]
626   ""
627   "dsb"
628   [(set_attr "type" "misc")]
631 (define_insn "unspec_msync"
632   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_MSYNC)]
633   ""
634   "msync\t%0"
635   [(set_attr "type" "misc")]
638 (define_insn "unspec_msync_all"
639   [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_ALL)]
640   ""
641   "msync\tall"
642   [(set_attr "type" "misc")]
645 (define_insn "unspec_msync_store"
646   [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_STORE)]
647   ""
648   "msync\tstore"
649   [(set_attr "type" "misc")]
652 ;; Load and Store
654 (define_insn "unspec_volatile_llw"
655   [(set (match_operand:SI 0 "register_operand" "=r")
656         (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
657                                               (match_operand:SI 2 "register_operand" "r")))] UNSPEC_VOLATILE_LLW))]
658   ""
659   "llw\t%0, [%1 + %2]"
660   [(set_attr "length"    "4")]
663 (define_insn "unspec_lwup"
664   [(set (match_operand:SI 0 "register_operand" "=r")
665         (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
666                                               (match_operand:SI 2 "register_operand" "r")))] UNSPEC_LWUP))]
667   ""
668   "lwup\t%0, [%1 + %2]"
669   [(set_attr "length"    "4")]
672 (define_insn "unspec_lbup"
673   [(set (match_operand:SI 0 "register_operand" "=r")
674         (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
675                                               (match_operand:SI 2 "register_operand" "r")))] UNSPEC_LBUP))]
676   ""
677   "lbup\t%0, [%1 + %2]"
678   [(set_attr "length"    "4")]
681 (define_insn "unspec_volatile_scw"
682   [(set (match_operand:SI 0 "register_operand" "=r")
683         (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
684                                               (match_operand:SI 2 "register_operand" "r")))
685                              (match_operand:SI 3 "register_operand" "0")] UNSPEC_VOLATILE_SCW))]
686   ""
687   "scw\t%0, [%1 + %2]"
688   [(set_attr "length"     "4")]
691 (define_insn "unspec_swup"
692   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
693                          (match_operand:SI 1 "register_operand" "r")))
694         (unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SWUP))]
695   ""
696   "swup\t%2, [%0 + %1]"
697   [(set_attr "length"     "4")]
700 (define_insn "unspec_sbup"
701   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
702                          (match_operand:SI 1 "register_operand" "r")))
703         (unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SBUP))]
704   ""
705   "sbup\t%2, [%0 + %1]"
706   [(set_attr "length"     "4")]
709 ;; CCTL
711 (define_insn "cctl_l1d_invalall"
712   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_INVALALL)]
713   ""
714   "cctl\tL1D_INVALALL"
715   [(set_attr "type" "mmu")]
718 (define_insn "cctl_l1d_wball_alvl"
719   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ALVL)]
720   ""
721   "cctl\tL1D_WBALL, alevel"
722   [(set_attr "type" "mmu")]
725 (define_insn "cctl_l1d_wball_one_lvl"
726   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ONE_LVL)]
727   ""
728   "cctl\tL1D_WBALL, 1level"
729   [(set_attr "type" "mmu")]
732 (define_insn "cctl_idx_read"
733   [(set (match_operand:SI 0 "register_operand" "=r")
734         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")
735                              (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_READ))]
736   ""
737   "cctl\t%0, %2, %X1"
738   [(set_attr "type" "mmu")]
741 (define_insn "cctl_idx_write"
742   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
743                         (match_operand:SI 1 "register_operand" "r")
744                         (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WRITE)]
745   ""
746   "cctl\t%1, %2, %W0"
747   [(set_attr "type" "mmu")]
750 (define_insn "cctl_va_wbinval_l1"
751   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
752                         (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_L1)]
753   ""
754   "cctl\t%1, %U0, 1level"
755   [(set_attr "type" "mmu")]
758 (define_insn "cctl_va_wbinval_la"
759   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
760                         (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_LA)]
761   ""
762   "cctl\t%1, %U0, alevel"
763   [(set_attr "type" "mmu")]
766 (define_insn "cctl_idx_wbinval"
767   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
768                         (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WBINVAL)]
769   ""
770   "cctl\t%1, %T0"
771   [(set_attr "type" "mmu")]
774 (define_insn "cctl_va_lck"
775   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
776                         (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_LCK)]
777   ""
778   "cctl\t%1, %R0"
779   [(set_attr "type" "mmu")]
782 ;;PREFETCH
784 (define_insn "prefetch_qw"
785   [(unspec_volatile:QI [(match_operand:SI 0 "register_operand" "r")
786                         (match_operand:SI 1 "nonmemory_operand" "r")
787                         (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_QW)]
788   ""
789   "dpref\t%Z2, [%0 + %1]"
790   [(set_attr "type" "misc")]
793 (define_insn "prefetch_hw"
794   [(unspec_volatile:HI [(match_operand:SI 0 "register_operand" "r")
795                         (match_operand:SI 1 "nonmemory_operand" "r")
796                         (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_HW)]
797   ""
798   "dpref\t%Z2, [%0 + (%1<<1)]"
799   [(set_attr "type" "misc")]
802 (define_insn "prefetch_w"
803   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "    r, r")
804                         (match_operand:SI 1 "nonmemory_operand" "Is15, r")
805                         (match_operand:SI 2 "immediate_operand" "   i, i")] UNSPEC_VOLATILE_DPREF_W)]
806   ""
807   "@
808   dprefi.w\t%Z2, [%0 + %1]
809   dpref\t%Z2, [%0 + (%1<<2)]"
810   [(set_attr "type" "misc")]
813 (define_insn "prefetch_dw"
814   [(unspec_volatile:DI [(match_operand:SI 0 "register_operand"  "   r, r")
815                         (match_operand:SI 1 "nonmemory_operand" "Is15, r")
816                         (match_operand:SI 2 "immediate_operand" "   i, i")] UNSPEC_VOLATILE_DPREF_DW)]
817   ""
818   "@
819   dprefi.d\t%Z2, [%0 + %1]
820   dpref\t%Z2, [%0 + (%1<<3)]"
821   [(set_attr "type" "misc")]
824 ;; Performance Extension
826 (define_expand "unspec_ave"
827   [(match_operand:SI 0 "register_operand" "")
828    (match_operand:SI 1 "register_operand" "")
829    (match_operand:SI 2 "register_operand" "")]
830   ""
832   emit_insn (gen_ave (operands[0], operands[1], operands[2]));
833   DONE;
836 (define_expand "unspec_bclr"
837   [(match_operand:SI 0 "register_operand" "")
838    (match_operand:SI 1 "register_operand" "")
839    (match_operand:SI 2 "immediate_operand" "")]
840   ""
842   unsigned HOST_WIDE_INT val = ~(1u << UINTVAL (operands[2]));
843   emit_insn (gen_andsi3 (operands[0], operands[1], gen_int_mode (val, SImode)));
844   DONE;
847 (define_expand "unspec_bset"
848   [(match_operand:SI 0 "register_operand" "")
849    (match_operand:SI 1 "register_operand" "")
850    (match_operand:SI 2 "immediate_operand" "")]
851   ""
853   unsigned HOST_WIDE_INT val = 1u << UINTVAL (operands[2]);
854   emit_insn (gen_iorsi3 (operands[0], operands[1], gen_int_mode (val, SImode)));
855   DONE;
858 (define_expand "unspec_btgl"
859   [(match_operand:SI 0 "register_operand" "")
860    (match_operand:SI 1 "register_operand" "")
861    (match_operand:SI 2 "immediate_operand" "")]
862   ""
864   unsigned HOST_WIDE_INT val = 1u << UINTVAL (operands[2]);
865   emit_insn (gen_xorsi3 (operands[0], operands[1], gen_int_mode (val, SImode)));
866   DONE;
869 (define_expand "unspec_btst"
870   [(match_operand:SI 0 "register_operand" "")
871    (match_operand:SI 1 "register_operand" "")
872    (match_operand:SI 2 "immediate_operand" "")]
873   ""
875   emit_insn (gen_btst (operands[0], operands[1], operands[2]));
876   DONE;
879 (define_insn "unspec_clip"
880   [(set (match_operand:SI 0 "register_operand" "=r")
881         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
882                     (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIP))]
883   ""
884   "clip\t%0, %1, %2"
885   [(set_attr "type" "alu")
886    (set_attr "length" "4")]
889 (define_insn "unspec_clips"
890   [(set (match_operand:SI 0 "register_operand" "=r")
891         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
892                     (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIPS))]
893   ""
894   "clips\t%0, %1, %2"
895   [(set_attr "type" "alu")
896    (set_attr "length" "4")]
899 (define_insn "unspec_clo"
900   [(set (match_operand:SI 0 "register_operand" "=r")
901         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_CLO))]
902   ""
903   "clo\t%0, %1"
904   [(set_attr "type" "alu")
905    (set_attr "length" "4")]
908 (define_insn "unspec_ssabssi2"
909   [(set (match_operand:SI 0 "register_operand" "=r")
910         (ss_abs:SI (match_operand:SI 1 "register_operand" "r")))]
911   ""
912   "abs\t%0, %1"
913   [(set_attr "type" "alu")
914    (set_attr "length" "4")]
917 ;; Performance extension 2
919 (define_insn "unspec_pbsad"
920   [(set (match_operand:SI 0 "register_operand" "=r")
921         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
922                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_PBSAD))]
923   ""
924   "pbsad\t%0, %1, %2"
925   [(set_attr "type" "pbsad")
926    (set_attr "length"   "4")]
929 (define_insn "unspec_pbsada"
930   [(set (match_operand:SI 0 "register_operand" "=r")
931         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
932                     (match_operand:SI 2 "register_operand" "r")
933                     (match_operand:SI 3 "register_operand" "r")] UNSPEC_PBSADA))]
934   ""
935   "pbsada\t%0, %2, %3"
936   [(set_attr "type" "pbsada")
937    (set_attr "length"    "4")]
940 (define_expand "bse"
941   [(match_operand:SI 0 "register_operand" "")
942    (match_operand:SI 1 "register_operand" "")
943    (match_operand:SI 2 "register_operand" "")]
944   ""
945   {
946     rtx temp0 = gen_reg_rtx (SImode);
947     rtx temp2 = gen_reg_rtx (SImode);
949     emit_move_insn (temp0, gen_rtx_MEM (Pmode, operands[0]));
950     emit_move_insn (temp2, gen_rtx_MEM (Pmode, operands[2]));
951     emit_insn (gen_unspec_bse (temp0, operands[1], temp2, temp0, temp2));
952     emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp0);
953     emit_move_insn (gen_rtx_MEM (Pmode, operands[2]), temp2);
954     DONE;
955   }
958 (define_insn "unspec_bse"
959   [(set (match_operand:SI 0 "register_operand" "=r")
960         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
961                     (match_operand:SI 2 "register_operand" "r")
962                     (match_operand:SI 3 "register_operand" "0")] UNSPEC_BSE))
963    (set (match_operand:SI 4 "register_operand" "=2")
964         (unspec:SI [(match_dup 1)
965                     (match_dup 2)
966                     (match_dup 0)] UNSPEC_BSE_2))]
967   ""
968   "bse\t%0, %1, %2"
969   [(set_attr "type" "alu")
970    (set_attr "length" "4")]
973 (define_expand "bsp"
974   [(match_operand:SI 0 "register_operand" "")
975    (match_operand:SI 1 "register_operand" "")
976    (match_operand:SI 2 "register_operand" "")]
977   ""
978   {
979     rtx temp0 = gen_reg_rtx (SImode);
980     rtx temp2 = gen_reg_rtx (SImode);
982     emit_move_insn (temp0, gen_rtx_MEM (Pmode, operands[0]));
983     emit_move_insn (temp2, gen_rtx_MEM (Pmode, operands[2]));
984     emit_insn (gen_unspec_bsp (temp0, operands[1], temp2, temp0, temp2));
985     emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp0);
986     emit_move_insn (gen_rtx_MEM (Pmode, operands[2]), temp2);
987     DONE;
988   }
991 (define_insn "unspec_bsp"
992   [(set (match_operand:SI 0 "register_operand" "=r")
993         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
994                     (match_operand:SI 2 "register_operand" "r")
995                     (match_operand:SI 3 "register_operand" "0")] UNSPEC_BSP))
996    (set (match_operand:SI 4 "register_operand" "=2")
997         (unspec:SI [(match_dup 1)
998                     (match_dup 2)
999                     (match_dup 0)] UNSPEC_BSP_2))]
1000   ""
1001   "bsp\t%0, %1, %2"
1002   [(set_attr "type" "alu")
1003    (set_attr "length" "4")]
1006 ;; String Extension
1008 (define_insn "unspec_ffb"
1009   [(set (match_operand:SI 0 "register_operand" "=r, r")
1010         (unspec:SI [(match_operand:SI 1 "register_operand" "r, r")
1011                     (match_operand:SI 2 "nonmemory_operand" "Iu08, r")] UNSPEC_FFB))]
1012   ""
1013   "@
1014   ffbi\t%0, %1, %2
1015   ffb\t%0, %1, %2"
1016   [(set_attr "type" "alu")
1017    (set_attr "length" "4")]
1020 (define_insn "unspec_ffmism"
1021   [(set (match_operand:SI 0 "register_operand" "=r")
1022         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1023                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_FFMISM))]
1024   ""
1025   "ffmism\t%0, %1, %2"
1026   [(set_attr "type" "alu")
1027    (set_attr "length" "4")]
1030 (define_insn "unspec_flmism"
1031   [(set (match_operand:SI 0 "register_operand" "=r")
1032         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1033                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_FLMISM))]
1034   ""
1035   "flmism\t%0, %1, %2"
1036   [(set_attr "type" "alu")
1037    (set_attr "length" "4")]
1040 ;; System
1042 (define_insn "unspec_sva"
1043   [(set (match_operand:SI 0 "register_operand" "=r")
1044         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1045                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_SVA))]
1046   ""
1047   "sva\t%0, %1, %2"
1048   [(set_attr "type"    "alu")
1049    (set_attr "length"    "4")]
1052 (define_insn "unspec_svs"
1053   [(set (match_operand:SI 0 "register_operand" "=r")
1054         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1055                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_SVS))]
1056   ""
1057   "svs\t%0, %1, %2"
1058   [(set_attr "type"    "alu")
1059    (set_attr "length"    "4")]
1062 (define_insn "unspec_jr_itoff"
1063   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_ITOFF)]
1064   ""
1065   "jr.itoff\t%0"
1066   [(set_attr "type" "misc")]
1069 (define_insn "unspec_jr_toff"
1070   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_TOFF)]
1071   ""
1072   "jr.toff\t%0"
1073   [(set_attr "type" "branch")]
1076 (define_insn "unspec_jral_iton"
1077   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_ITON)]
1078   ""
1079   "jral.iton\t%0"
1080   [(set_attr "type" "branch")]
1083 (define_insn "unspec_jral_ton"
1084   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_TON)]
1085   ""
1086   "jral.ton\t%0"
1087   [(set_attr "type" "branch")]
1090 (define_insn "unspec_ret_itoff"
1091   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_ITOFF)]
1092   ""
1093   "ret.itoff\t%0"
1094   [(set_attr "type" "branch")]
1097 (define_insn "unspec_ret_toff"
1098   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_TOFF)]
1099   ""
1100   "ret.toff\t%0"
1101   [(set_attr "type" "branch")]
1104 (define_insn "unspec_standby_no_wake_grant"
1105   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_NO_WAKE_GRANT)]
1106   ""
1107   "standby\tno_wake_grant"
1108   [(set_attr "type" "misc")]
1111 (define_insn "unspec_standby_wake_grant"
1112   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_GRANT)]
1113   ""
1114   "standby\twake_grant"
1115   [(set_attr "type" "misc")]
1118 (define_insn "unspec_standby_wait_done"
1119   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_DONE)]
1120   ""
1121   "standby\twait_done"
1122   [(set_attr "type" "misc")]
1125 (define_insn "unspec_teqz"
1126   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1127                         (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TEQZ)]
1128   ""
1129   "teqz\t%0, %1"
1130   [(set_attr "type" "misc")]
1133 (define_insn "unspec_tnez"
1134   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1135                         (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TNEZ)]
1136   ""
1137   "tnez\t%0, %1"
1138   [(set_attr "type" "misc")]
1141 (define_insn "unspec_trap"
1142   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_TRAP)]
1143   ""
1144   "trap\t%0"
1145   [(set_attr "type" "misc")]
1148 (define_insn "unspec_setend_big"
1149   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_BIG)]
1150   ""
1151   "setend.b"
1152   [(set_attr "type" "misc")]
1155 (define_insn "unspec_setend_little"
1156   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_LITTLE)]
1157   ""
1158   "setend.l"
1159   [(set_attr "type" "misc")]
1162 (define_insn "unspec_break"
1163   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_BREAK)]
1164   ""
1165   "break\t%0"
1166   [(set_attr "type" "misc")]
1169 (define_insn "unspec_syscall"
1170   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_SYSCALL)]
1171   ""
1172   "syscall\t%0"
1173   [(set_attr "type" "misc")]
1176 (define_insn "unspec_nop"
1177   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NOP)]
1178   ""
1179   "nop"
1180   [(set_attr "type" "misc")]
1183 (define_expand "unspec_get_current_sp"
1184   [(match_operand:SI 0 "register_operand" "")]
1185   ""
1187   emit_move_insn (operands[0], gen_rtx_REG (SImode, SP_REGNUM));
1188   DONE;
1191 (define_expand "unspec_set_current_sp"
1192   [(match_operand:SI 0 "register_operand" "")]
1193   ""
1195   emit_move_insn (gen_rtx_REG (SImode, SP_REGNUM), operands[0]);
1196   DONE;
1199 (define_expand "unspec_return_address"
1200   [(match_operand:SI 0 "register_operand" "")]
1201   ""
1203   emit_move_insn (operands[0], gen_rtx_REG (SImode, LP_REGNUM));
1204   DONE;
1207 ;; Swap
1209 (define_insn "unspec_wsbh"
1210   [(set (match_operand:SI 0 "register_operand" "=r")
1211         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_WSBH))]
1212   ""
1213   "wsbh\t%0, %1"
1214   [(set_attr "type"    "alu")
1215    (set_attr "length"    "4")]
1218 ;; TLBOP Intrinsic
1220 (define_insn "unspec_tlbop_trd"
1221   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TRD)]
1222   ""
1223   "tlbop\t%0, TRD"
1224   [(set_attr "type" "mmu")]
1227 (define_insn "unspec_tlbop_twr"
1228   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TWR)]
1229   ""
1230   "tlbop\t%0, TWR"
1231   [(set_attr "type" "mmu")]
1234 (define_insn "unspec_tlbop_rwr"
1235   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWR)]
1236   ""
1237   "tlbop\t%0, RWR"
1238   [(set_attr "type" "mmu")]
1241 (define_insn "unspec_tlbop_rwlk"
1242   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWLK)]
1243   ""
1244   "tlbop\t%0, RWLK"
1245   [(set_attr "type" "mmu")]
1248 (define_insn "unspec_tlbop_unlk"
1249   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_UNLK)]
1250   ""
1251   "tlbop\t%0, UNLK"
1252   [(set_attr "type" "mmu")]
1255 (define_insn "unspec_tlbop_pb"
1256   [(set (match_operand:SI 0 "register_operand" "=r")
1257         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_PB))]
1258   ""
1259   "tlbop\t%0, %1, PB"
1260   [(set_attr "type" "mmu")]
1263 (define_insn "unspec_tlbop_inv"
1264   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_INV)]
1265   ""
1266   "tlbop\t%0, INV"
1267   [(set_attr "type" "mmu")]
1270 (define_insn "unspec_tlbop_flua"
1271   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_TLBOP_FLUA)]
1272   ""
1273   "tlbop\tFLUA"
1274   [(set_attr "type" "mmu")]
1277 ;;Unaligned Load/Store
1279 (define_expand "unaligned_load_hw"
1280   [(set (match_operand:HI 0 "register_operand" "")
1281         (unspec:HI [(mem:HI (match_operand:SI 1 "register_operand" ""))] UNSPEC_UALOAD_HW))]
1282   ""
1284   operands[0] = simplify_gen_subreg (SImode, operands[0],
1285                                      GET_MODE (operands[0]), 0);
1286   if (TARGET_ISA_V3M)
1287     {
1288       nds32_expand_unaligned_load (operands, HImode);
1289     }
1290   else
1291     {
1292       emit_insn (gen_unaligned_load_w (operands[0],
1293                                        gen_rtx_MEM (SImode, operands[1])));
1295       if (WORDS_BIG_ENDIAN)
1296         emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT(16)));
1297       else
1298         emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0xffff)));
1299     }
1301   DONE;
1304 (define_expand "unaligned_loadsi"
1305   [(set (match_operand:SI 0 "register_operand" "=r")
1306         (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))]
1307   ""
1309   if (flag_unaligned_access)
1310     {
1311       rtx mem = gen_rtx_MEM (SImode, operands[1]);
1312       emit_move_insn (operands[0], mem);
1313     }
1314   else
1315     {
1316       if (TARGET_ISA_V3M)
1317         nds32_expand_unaligned_load (operands, SImode);
1318       else
1319         emit_insn (gen_unaligned_load_w (operands[0],
1320                                          gen_rtx_MEM (SImode, (operands[1]))));
1321     }
1322   DONE;
1325 (define_insn "unaligned_load_w"
1326   [(set (match_operand:SI 0 "register_operand"                       "=  r")
1327         (unspec:SI [(match_operand:SI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))]
1328   ""
1330   return nds32_output_lmw_single_word (operands);
1332   [(set_attr "type"   "load")
1333    (set_attr "length"    "4")]
1336 (define_expand "unaligned_loaddi"
1337   [(set (match_operand:DI 0 "register_operand" "=r")
1338         (unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))]
1339   ""
1341   if (TARGET_ISA_V3M)
1342     {
1343       nds32_expand_unaligned_load (operands, DImode);
1344     }
1345   else
1346     emit_insn (gen_unaligned_load_dw (operands[0], operands[1]));
1347   DONE;
1350 (define_insn "unaligned_load_dw"
1351   [(set (match_operand:DI 0 "register_operand" "=r")
1352         (unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))]
1353   ""
1355   rtx otherops[3];
1356   otherops[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
1357   otherops[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1358   otherops[2] = operands[1];
1360   output_asm_insn ("lmw.bi\t%0, [%2], %1, 0", otherops);
1361   return "";
1363   [(set_attr "type"   "load")
1364    (set_attr "length"    "4")]
1367 (define_expand "unaligned_store_hw"
1368   [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
1369         (unspec:HI [(match_operand:HI 1 "register_operand" "")] UNSPEC_UASTORE_HW))]
1370   ""
1372   operands[1] = simplify_gen_subreg (SImode, operands[1],
1373                                      GET_MODE (operands[1]), 0);
1374   nds32_expand_unaligned_store (operands, HImode);
1375   DONE;
1378 (define_expand "unaligned_storesi"
1379   [(set (mem:SI (match_operand:SI 0 "register_operand" "r"))
1380         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_UASTORE_W))]
1381   ""
1383   if (flag_unaligned_access)
1384     {
1385       rtx mem = gen_rtx_MEM (SImode, operands[0]);
1386       emit_move_insn (mem, operands[1]);
1387     }
1388   else
1389     {
1390       if (TARGET_ISA_V3M)
1391         nds32_expand_unaligned_store (operands, SImode);
1392       else
1393         emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[0]),
1394                                           operands[1]));
1395     }
1396   DONE;
1399 (define_insn "unaligned_store_w"
1400   [(set (match_operand:SI 0 "nds32_lmw_smw_base_operand"   "=Umw")
1401         (unspec:SI [(match_operand:SI 1 "register_operand" "   r")] UNSPEC_UASTORE_W))]
1402   ""
1404   return nds32_output_smw_single_word (operands);
1406   [(set_attr "type"   "store")
1407    (set_attr "length"     "4")]
1410 (define_expand "unaligned_storedi"
1411   [(set (mem:DI (match_operand:SI 0 "register_operand" "r"))
1412         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))]
1413   ""
1415   if (TARGET_ISA_V3M)
1416     nds32_expand_unaligned_store (operands, DImode);
1417   else
1418     emit_insn (gen_unaligned_store_dw (operands[0], operands[1]));
1419   DONE;
1422 (define_insn "unaligned_store_dw"
1423   [(set (mem:DI (match_operand:SI 0 "register_operand" "r"))
1424         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))]
1425   ""
1427   rtx otherops[3];
1428   otherops[0] = gen_rtx_REG (SImode, REGNO (operands[1]));
1429   otherops[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1430   otherops[2] = operands[0];
1432   output_asm_insn ("smw.bi\t%0, [%2], %1, 0", otherops);
1433   return "";
1435   [(set_attr "type"   "store")
1436    (set_attr "length"     "4")]
1439 (define_expand "unspec_unaligned_feature"
1440   [(set (match_operand:SI 0 "register_operand" "")
1441         (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE))]
1442   ""
1444   /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
1445   rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
1446   rtx temp_reg = gen_reg_rtx (SImode);
1447   rtx temp2_reg = gen_reg_rtx (SImode);
1449   emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
1450   emit_move_insn (temp_reg, operands[0]);
1451   emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
1452   emit_insn (gen_iorsi3 (operands[0], operands[0], temp2_reg));
1453   emit_insn (gen_unspec_volatile_mtsr (operands[0], system_reg));
1454   emit_insn (gen_unspec_dsb ());
1456   emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
1457   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
1458   emit_insn (gen_unspec_dsb ());
1460   emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (8)));
1461   emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
1462   DONE;
1465 (define_expand "unspec_enable_unaligned"
1466   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
1467   ""
1469   /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
1470   rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
1471   rtx temp_reg = gen_reg_rtx (SImode);
1472   rtx temp2_reg = gen_reg_rtx (SImode);
1473   emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
1474   emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
1475   emit_insn (gen_iorsi3 (temp_reg, temp_reg, temp2_reg));
1476   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
1477   emit_insn (gen_unspec_dsb ());
1478   DONE;
1481 (define_expand "unspec_disable_unaligned"
1482   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
1483   ""
1485   /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
1486   rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
1487   rtx temp_reg = gen_reg_rtx (SImode);
1488   rtx temp2_reg = gen_reg_rtx (SImode);
1489   emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
1490   emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
1491   emit_insn (gen_one_cmplsi2 (temp2_reg, temp2_reg));
1492   emit_insn (gen_andsi3 (temp_reg, temp_reg, temp2_reg));
1493   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
1494   emit_insn (gen_unspec_dsb ());
1495   DONE;
1498 ;; ------------------------------------------------------------------------