2018-07-13 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / config / nds32 / nds32-intrinsic.md
blobc70a6fcc99b9a008039eaad77d6ad07da2f99e46
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 ;; SATURATION
1042 (define_insn "unspec_kaddw"
1043   [(set (match_operand:SI 0 "register_operand" "=r")
1044         (ss_plus:SI (match_operand:SI 1 "register_operand" "r")
1045                     (match_operand:SI 2 "register_operand" "r")))]
1046   ""
1047   "kaddw\t%0, %1, %2"
1048   [(set_attr "type"    "alu")
1049    (set_attr "length"    "4")]
1052 (define_insn "unspec_ksubw"
1053   [(set (match_operand:SI 0 "register_operand" "=r")
1054         (ss_minus:SI (match_operand:SI 1 "register_operand" "r")
1055                      (match_operand:SI 2 "register_operand" "r")))]
1056   ""
1057   "ksubw\t%0, %1, %2"
1058   [(set_attr "type"    "alu")
1059    (set_attr "length"    "4")]
1062 (define_insn "unspec_kaddh"
1063   [(set (match_operand:SI 0 "register_operand" "=r")
1064         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1065                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_KADDH))]
1066   ""
1067   "kaddh\t%0, %1, %2"
1068   [(set_attr "type"    "alu")
1069    (set_attr "length"    "4")]
1072 (define_insn "unspec_ksubh"
1073   [(set (match_operand:SI 0 "register_operand" "=r")
1074         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1075                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSUBH))]
1076   ""
1077   "ksubh\t%0, %1, %2"
1078   [(set_attr "type"    "alu")
1079    (set_attr "length"    "4")]
1082 (define_insn "unspec_kaddh_dsp"
1083   [(set (match_operand:SI 0 "register_operand" "=r")
1084         (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
1085                              (match_operand:SI 2 "register_operand" "r"))
1086                     (const_int 15)] UNSPEC_CLIPS))]
1087   "NDS32_EXT_DSP_P ()"
1088   "kaddh\t%0, %1, %2"
1089   [(set_attr "type"    "alu")
1090    (set_attr "length"    "4")]
1093 (define_insn "unspec_ksubh_dsp"
1094   [(set (match_operand:SI 0 "register_operand" "=r")
1095         (unspec:SI [(minus:SI (match_operand:SI 1 "register_operand" "r")
1096                               (match_operand:SI 2 "register_operand" "r"))
1097                     (const_int 15)] UNSPEC_CLIPS))]
1098   "NDS32_EXT_DSP_P ()"
1099   "ksubh\t%0, %1, %2"
1100   [(set_attr "type"    "alu")
1101    (set_attr "length"    "4")]
1104 (define_insn "unspec_kdmbb"
1105   [(set (match_operand:V2HI 0 "register_operand" "=r")
1106         (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
1107                       (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBB))]
1108   ""
1109   "kdmbb\t%0, %1, %2"
1110   [(set_attr "type"    "mul")
1111    (set_attr "length"    "4")]
1114 (define_insn "unspec_kdmbt"
1115   [(set (match_operand:V2HI 0 "register_operand" "=r")
1116         (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
1117                       (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBT))]
1118   ""
1119   "kdmbt\t%0, %1, %2"
1120   [(set_attr "type"    "mul")
1121    (set_attr "length"    "4")]
1124 (define_insn "unspec_kdmtb"
1125   [(set (match_operand:V2HI 0 "register_operand" "=r")
1126         (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
1127                       (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTB))]
1128   ""
1129   "kdmtb\t%0, %1, %2"
1130   [(set_attr "type"    "mul")
1131    (set_attr "length"    "4")]
1134 (define_insn "unspec_kdmtt"
1135   [(set (match_operand:V2HI 0 "register_operand" "=r")
1136         (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
1137                       (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTT))]
1138   ""
1139   "kdmtt\t%0, %1, %2"
1140   [(set_attr "type"    "mul")
1141    (set_attr "length"    "4")]
1144 (define_insn "unspec_khmbb"
1145   [(set (match_operand:V2HI 0 "register_operand" "=r")
1146         (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
1147                       (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBB))]
1148   ""
1149   "khmbb\t%0, %1, %2"
1150   [(set_attr "type"    "mul")
1151    (set_attr "length"    "4")]
1154 (define_insn "unspec_khmbt"
1155   [(set (match_operand:V2HI 0 "register_operand" "=r")
1156         (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
1157                       (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBT))]
1158   ""
1159   "khmbt\t%0, %1, %2"
1160   [(set_attr "type"    "mul")
1161    (set_attr "length"    "4")]
1164 (define_insn "unspec_khmtb"
1165   [(set (match_operand:V2HI 0 "register_operand" "=r")
1166         (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
1167                       (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTB))]
1168   ""
1169   "khmtb\t%0, %1, %2"
1170   [(set_attr "type"    "mul")
1171    (set_attr "length"    "4")]
1174 (define_insn "unspec_khmtt"
1175   [(set (match_operand:V2HI 0 "register_operand" "=r")
1176         (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
1177                       (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTT))]
1178   ""
1179   "khmtt\t%0, %1, %2"
1180   [(set_attr "type"    "mul")
1181    (set_attr "length"    "4")]
1184 (define_insn "unspec_kslraw"
1185   [(set (match_operand:SI 0 "register_operand" "=r")
1186         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1187                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAW))]
1188   ""
1189   "kslraw\t%0, %1, %2"
1190   [(set_attr "type"    "alu")
1191    (set_attr "length"    "4")]
1194 (define_insn "unspec_kslrawu"
1195   [(set (match_operand:SI 0 "register_operand" "=r")
1196         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1197                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAWU))]
1198   ""
1199   "kslraw.u\t%0, %1, %2"
1200   [(set_attr "type"    "alu")
1201    (set_attr "length"    "4")]
1204 (define_insn "unspec_volatile_rdov"
1205   [(set (match_operand:SI 0 "register_operand" "=r")
1206         (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_RDOV))]
1207   ""
1208   "rdov\t%0"
1209   [(set_attr "type"   "misc")
1210    (set_attr "length"    "4")]
1213 (define_insn "unspec_volatile_clrov"
1214   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLROV)]
1215   ""
1216   "clrov"
1217   [(set_attr "type"   "misc")
1218    (set_attr "length"    "4")]
1221 ;; System
1223 (define_insn "unspec_sva"
1224   [(set (match_operand:SI 0 "register_operand" "=r")
1225         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1226                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_SVA))]
1227   ""
1228   "sva\t%0, %1, %2"
1229   [(set_attr "type"    "alu")
1230    (set_attr "length"    "4")]
1233 (define_insn "unspec_svs"
1234   [(set (match_operand:SI 0 "register_operand" "=r")
1235         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1236                     (match_operand:SI 2 "register_operand" "r")] UNSPEC_SVS))]
1237   ""
1238   "svs\t%0, %1, %2"
1239   [(set_attr "type"    "alu")
1240    (set_attr "length"    "4")]
1243 (define_insn "unspec_jr_itoff"
1244   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_ITOFF)]
1245   ""
1246   "jr.itoff\t%0"
1247   [(set_attr "type" "misc")]
1250 (define_insn "unspec_jr_toff"
1251   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_TOFF)]
1252   ""
1253   "jr.toff\t%0"
1254   [(set_attr "type" "branch")]
1257 (define_insn "unspec_jral_iton"
1258   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_ITON)]
1259   ""
1260   "jral.iton\t%0"
1261   [(set_attr "type" "branch")]
1264 (define_insn "unspec_jral_ton"
1265   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_TON)]
1266   ""
1267   "jral.ton\t%0"
1268   [(set_attr "type" "branch")]
1271 (define_insn "unspec_ret_itoff"
1272   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_ITOFF)]
1273   ""
1274   "ret.itoff\t%0"
1275   [(set_attr "type" "branch")]
1278 (define_insn "unspec_ret_toff"
1279   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_TOFF)]
1280   ""
1281   "ret.toff\t%0"
1282   [(set_attr "type" "branch")]
1285 (define_insn "unspec_standby_no_wake_grant"
1286   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_NO_WAKE_GRANT)]
1287   ""
1288   "standby\tno_wake_grant"
1289   [(set_attr "type" "misc")]
1292 (define_insn "unspec_standby_wake_grant"
1293   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_GRANT)]
1294   ""
1295   "standby\twake_grant"
1296   [(set_attr "type" "misc")]
1299 (define_insn "unspec_standby_wait_done"
1300   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_DONE)]
1301   ""
1302   "standby\twait_done"
1303   [(set_attr "type" "misc")]
1306 (define_insn "unspec_teqz"
1307   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1308                         (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TEQZ)]
1309   ""
1310   "teqz\t%0, %1"
1311   [(set_attr "type" "misc")]
1314 (define_insn "unspec_tnez"
1315   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1316                         (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TNEZ)]
1317   ""
1318   "tnez\t%0, %1"
1319   [(set_attr "type" "misc")]
1322 (define_insn "unspec_trap"
1323   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_TRAP)]
1324   ""
1325   "trap\t%0"
1326   [(set_attr "type" "misc")]
1329 (define_insn "unspec_setend_big"
1330   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_BIG)]
1331   ""
1332   "setend.b"
1333   [(set_attr "type" "misc")]
1336 (define_insn "unspec_setend_little"
1337   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_LITTLE)]
1338   ""
1339   "setend.l"
1340   [(set_attr "type" "misc")]
1343 (define_insn "unspec_break"
1344   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_BREAK)]
1345   ""
1346   "break\t%0"
1347   [(set_attr "type" "misc")]
1350 (define_insn "unspec_syscall"
1351   [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_SYSCALL)]
1352   ""
1353   "syscall\t%0"
1354   [(set_attr "type" "misc")]
1357 (define_insn "unspec_nop"
1358   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NOP)]
1359   ""
1360   "nop"
1361   [(set_attr "type" "misc")]
1364 (define_expand "unspec_get_current_sp"
1365   [(match_operand:SI 0 "register_operand" "")]
1366   ""
1368   emit_move_insn (operands[0], gen_rtx_REG (SImode, SP_REGNUM));
1369   DONE;
1372 (define_expand "unspec_set_current_sp"
1373   [(match_operand:SI 0 "register_operand" "")]
1374   ""
1376   emit_move_insn (gen_rtx_REG (SImode, SP_REGNUM), operands[0]);
1377   DONE;
1380 (define_expand "unspec_return_address"
1381   [(match_operand:SI 0 "register_operand" "")]
1382   ""
1384   emit_move_insn (operands[0], gen_rtx_REG (SImode, LP_REGNUM));
1385   DONE;
1388 ;; Swap
1390 (define_insn "unspec_wsbh"
1391   [(set (match_operand:SI 0 "register_operand" "=r")
1392         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_WSBH))]
1393   ""
1394   "wsbh\t%0, %1"
1395   [(set_attr "type"    "alu")
1396    (set_attr "length"    "4")]
1399 ;; TLBOP Intrinsic
1401 (define_insn "unspec_tlbop_trd"
1402   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TRD)]
1403   ""
1404   "tlbop\t%0, TRD"
1405   [(set_attr "type" "mmu")]
1408 (define_insn "unspec_tlbop_twr"
1409   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TWR)]
1410   ""
1411   "tlbop\t%0, TWR"
1412   [(set_attr "type" "mmu")]
1415 (define_insn "unspec_tlbop_rwr"
1416   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWR)]
1417   ""
1418   "tlbop\t%0, RWR"
1419   [(set_attr "type" "mmu")]
1422 (define_insn "unspec_tlbop_rwlk"
1423   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWLK)]
1424   ""
1425   "tlbop\t%0, RWLK"
1426   [(set_attr "type" "mmu")]
1429 (define_insn "unspec_tlbop_unlk"
1430   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_UNLK)]
1431   ""
1432   "tlbop\t%0, UNLK"
1433   [(set_attr "type" "mmu")]
1436 (define_insn "unspec_tlbop_pb"
1437   [(set (match_operand:SI 0 "register_operand" "=r")
1438         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_PB))]
1439   ""
1440   "tlbop\t%0, %1, PB"
1441   [(set_attr "type" "mmu")]
1444 (define_insn "unspec_tlbop_inv"
1445   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_INV)]
1446   ""
1447   "tlbop\t%0, INV"
1448   [(set_attr "type" "mmu")]
1451 (define_insn "unspec_tlbop_flua"
1452   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_TLBOP_FLUA)]
1453   ""
1454   "tlbop\tFLUA"
1455   [(set_attr "type" "mmu")]
1458 ;;Unaligned Load/Store
1460 (define_expand "unaligned_load_hw"
1461   [(set (match_operand:HI 0 "register_operand" "")
1462         (unspec:HI [(mem:HI (match_operand:SI 1 "register_operand" ""))] UNSPEC_UALOAD_HW))]
1463   ""
1465   operands[0] = simplify_gen_subreg (SImode, operands[0],
1466                                      GET_MODE (operands[0]), 0);
1467   if (TARGET_ISA_V3M)
1468     {
1469       nds32_expand_unaligned_load (operands, HImode);
1470     }
1471   else
1472     {
1473       emit_insn (gen_unaligned_load_w (operands[0],
1474                                        gen_rtx_MEM (SImode, operands[1])));
1476       if (WORDS_BIG_ENDIAN)
1477         emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT(16)));
1478       else
1479         emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0xffff)));
1480     }
1482   DONE;
1485 (define_expand "unaligned_loadsi"
1486   [(set (match_operand:SI 0 "register_operand" "=r")
1487         (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))]
1488   ""
1490   if (flag_unaligned_access)
1491     {
1492       rtx mem = gen_rtx_MEM (SImode, operands[1]);
1493       emit_move_insn (operands[0], mem);
1494     }
1495   else
1496     {
1497       if (TARGET_ISA_V3M)
1498         nds32_expand_unaligned_load (operands, SImode);
1499       else
1500         emit_insn (gen_unaligned_load_w (operands[0],
1501                                          gen_rtx_MEM (SImode, (operands[1]))));
1502     }
1503   DONE;
1506 (define_insn "unaligned_load_w"
1507   [(set (match_operand:SI 0 "register_operand"                       "=  r")
1508         (unspec:SI [(match_operand:SI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))]
1509   ""
1511   return nds32_output_lmw_single_word (operands);
1513   [(set_attr "type"   "load")
1514    (set_attr "length"    "4")]
1517 (define_expand "unaligned_loaddi"
1518   [(set (match_operand:DI 0 "register_operand" "=r")
1519         (unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))]
1520   ""
1522   if (TARGET_ISA_V3M)
1523     {
1524       nds32_expand_unaligned_load (operands, DImode);
1525     }
1526   else
1527     emit_insn (gen_unaligned_load_dw (operands[0], operands[1]));
1528   DONE;
1531 (define_insn "unaligned_load_dw"
1532   [(set (match_operand:DI 0 "register_operand" "=r")
1533         (unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))]
1534   ""
1536   rtx otherops[3];
1537   otherops[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
1538   otherops[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1539   otherops[2] = operands[1];
1541   output_asm_insn ("lmw.bi\t%0, [%2], %1, 0", otherops);
1542   return "";
1544   [(set_attr "type"   "load")
1545    (set_attr "length"    "4")]
1548 (define_expand "unaligned_store_hw"
1549   [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
1550         (unspec:HI [(match_operand:HI 1 "register_operand" "")] UNSPEC_UASTORE_HW))]
1551   ""
1553   operands[1] = simplify_gen_subreg (SImode, operands[1],
1554                                      GET_MODE (operands[1]), 0);
1555   nds32_expand_unaligned_store (operands, HImode);
1556   DONE;
1559 (define_expand "unaligned_storesi"
1560   [(set (mem:SI (match_operand:SI 0 "register_operand" "r"))
1561         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_UASTORE_W))]
1562   ""
1564   if (flag_unaligned_access)
1565     {
1566       rtx mem = gen_rtx_MEM (SImode, operands[0]);
1567       emit_move_insn (mem, operands[1]);
1568     }
1569   else
1570     {
1571       if (TARGET_ISA_V3M)
1572         nds32_expand_unaligned_store (operands, SImode);
1573       else
1574         emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[0]),
1575                                           operands[1]));
1576     }
1577   DONE;
1580 (define_insn "unaligned_store_w"
1581   [(set (match_operand:SI 0 "nds32_lmw_smw_base_operand"   "=Umw")
1582         (unspec:SI [(match_operand:SI 1 "register_operand" "   r")] UNSPEC_UASTORE_W))]
1583   ""
1585   return nds32_output_smw_single_word (operands);
1587   [(set_attr "type"   "store")
1588    (set_attr "length"     "4")]
1591 (define_expand "unaligned_storedi"
1592   [(set (mem:DI (match_operand:SI 0 "register_operand" "r"))
1593         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))]
1594   ""
1596   if (TARGET_ISA_V3M)
1597     nds32_expand_unaligned_store (operands, DImode);
1598   else
1599     emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[0]),
1600                                        operands[1]));
1601   DONE;
1604 (define_insn "unaligned_store_dw"
1605   [(set (match_operand:DI 0 "nds32_lmw_smw_base_operand"   "=Umw")
1606         (unspec:DI [(match_operand:DI 1 "register_operand" "   r")] UNSPEC_UASTORE_DW))]
1607   ""
1609   return nds32_output_smw_double_word (operands);
1611   [(set_attr "type"   "store")
1612    (set_attr "length"     "4")]
1615 (define_expand "unspec_unaligned_feature"
1616   [(set (match_operand:SI 0 "register_operand" "")
1617         (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE))]
1618   ""
1620   /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
1621   rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
1622   rtx temp_reg = gen_reg_rtx (SImode);
1623   rtx temp2_reg = gen_reg_rtx (SImode);
1625   emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
1626   emit_move_insn (temp_reg, operands[0]);
1627   emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
1628   emit_insn (gen_iorsi3 (operands[0], operands[0], temp2_reg));
1629   emit_insn (gen_unspec_volatile_mtsr (operands[0], system_reg));
1630   emit_insn (gen_unspec_dsb ());
1632   emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
1633   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
1634   emit_insn (gen_unspec_dsb ());
1636   emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (8)));
1637   emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
1638   DONE;
1641 (define_expand "unspec_enable_unaligned"
1642   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
1643   ""
1645   /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
1646   rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
1647   rtx temp_reg = gen_reg_rtx (SImode);
1648   rtx temp2_reg = gen_reg_rtx (SImode);
1649   emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
1650   emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
1651   emit_insn (gen_iorsi3 (temp_reg, temp_reg, temp2_reg));
1652   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
1653   emit_insn (gen_unspec_dsb ());
1654   DONE;
1657 (define_expand "unspec_disable_unaligned"
1658   [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
1659   ""
1661   /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
1662   rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
1663   rtx temp_reg = gen_reg_rtx (SImode);
1664   rtx temp2_reg = gen_reg_rtx (SImode);
1665   emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
1666   emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
1667   emit_insn (gen_one_cmplsi2 (temp2_reg, temp2_reg));
1668   emit_insn (gen_andsi3 (temp_reg, temp_reg, temp2_reg));
1669   emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
1670   emit_insn (gen_unspec_dsb ());
1671   DONE;
1674 ;; abs alias kabs
1676 (define_insn "unspec_kabs"
1677   [(set (match_operand:SI 0 "register_operand" "=r")
1678         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_KABS))]
1679   ""
1680   "kabs\t%0, %1"
1681   [(set_attr "type" "alu")
1682    (set_attr "length" "4")]
1685 ;; ------------------------------------------------------------------------