[NDS32] Add intrinsic functions for particular instructions.
[official-gcc.git] / gcc / config / nds32 / nds32.md
blob99731fecb7abc2737d606c45bf95e394df199092
1 ;; Machine 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 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 ;; Include predicates definition.
24 (include "predicates.md")
26 ;; Include constraints definition.
27 (include "constraints.md")
29 ;; Include iterators definition.
30 (include "iterators.md")
32 ;; Include pipelines definition.
33 (include "pipelines.md")
36 ;; Include constants definition.
37 (include "constants.md")
40 ;; Include intrinsic functions definition.
41 (include "nds32-intrinsic.md")
43 ;; Include block move for nds32 multiple load/store behavior.
44 (include "nds32-multiple.md")
46 ;; Include DImode/DFmode operations.
47 (include "nds32-doubleword.md")
49 ;; Include floating-point patterns.
50 (include "nds32-fpu.md")
52 ;; Include peephole patterns.
53 (include "nds32-peephole2.md")
56 ;; Insn type, it is used to default other attribute values.
57 (define_attr "type"
58   "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\
59    falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore"
60   (const_string "unknown"))
62 ;; Insn sub-type
63 (define_attr "subtype"
64   "simple,shift"
65   (const_string "simple"))
67 ;; Length, in bytes, default is 4-bytes.
68 (define_attr "length" "" (const_int 4))
70 ;; Indicate the amount of micro instructions.
71 (define_attr "combo"
72   "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25"
73   (const_string "1"))
75 ;; Insn in which feature set, it is used to enable/disable insn alternatives.
76 ;; v1  : Baseline Instructions
77 ;; v2  : Baseline Version 2 Instructions
78 ;; v3m : Baseline Version 3m Instructions
79 ;; v3  : Baseline Version 3 Instructions
80 ;; pe1 : Performance Extension Instructions
81 ;; pe2 : Performance Extension Version 2 Instructions
82 ;; se  : String Extension instructions
83 (define_attr "feature"
84   "v1,v2,v3m,v3,pe1,pe2,se,fpu"
85   (const_string "v1"))
87 ;; Enabled, which is used to enable/disable insn alternatives.
88 ;; Note that we use length and TARGET_16_BIT here as criteria.
89 ;; If the instruction pattern already check TARGET_16_BIT to determine
90 ;; the length by itself, its enabled attribute should be customized to
91 ;; avoid the conflict between length attribute and this default setting.
92 (define_attr "enabled" "no,yes"
93   (if_then_else
94     (and (eq_attr "length" "2")
95          (match_test "!TARGET_16_BIT"))
96     (const_string "no")
97     (cond [(eq_attr "feature" "v1")   (const_string "yes")
98            (eq_attr "feature" "v2")   (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M")
99                                                     (const_string "yes")
100                                                     (const_string "no"))
101            (eq_attr "feature" "v3")   (if_then_else (match_test "TARGET_ISA_V3")
102                                                     (const_string "yes")
103                                                     (const_string "no"))
104            (eq_attr "feature" "v3m")  (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M")
105                                                     (const_string "yes")
106                                                     (const_string "no"))
107            (eq_attr "feature" "pe1")  (if_then_else (match_test "TARGET_EXT_PERF")
108                                                     (const_string "yes")
109                                                     (const_string "no"))
110            (eq_attr "feature" "pe2")  (if_then_else (match_test "TARGET_EXT_PERF2")
111                                                     (const_string "yes")
112                                                     (const_string "no"))
113            (eq_attr "feature" "se")   (if_then_else (match_test "TARGET_EXT_STRING")
114                                                     (const_string "yes")
115                                                     (const_string "no"))
116            (eq_attr "feature" "fpu")  (if_then_else (match_test "TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE")
117                                                     (const_string "yes")
118                                                     (const_string "no"))]
119            (const_string "yes"))))
122 ;; ----------------------------------------------------------------------------
125 ;; Move instructions.
127 ;; For QImode and HImode, the immediate value can be fit in imm20s.
128 ;; So there is no need to split rtx for QI and HI patterns.
130 (define_expand "mov<mode>"
131   [(set (match_operand:QIHI 0 "general_operand" "")
132         (match_operand:QIHI 1 "general_operand" ""))]
133   ""
135   /* Need to force register if mem <- !reg.  */
136   if (MEM_P (operands[0]) && !REG_P (operands[1]))
137     operands[1] = force_reg (<MODE>mode, operands[1]);
139   if (MEM_P (operands[1]) && optimize > 0)
140     {
141       rtx reg = gen_reg_rtx (SImode);
143       emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
144       operands[1] = gen_lowpart (<MODE>mode, reg);
145     }
148 (define_expand "movmisalign<mode>"
149   [(set (match_operand:SIDI 0 "general_operand" "")
150         (match_operand:SIDI 1 "general_operand" ""))]
151   ""
153   rtx addr;
154   if (MEM_P (operands[0]) && !REG_P (operands[1]))
155     operands[1] = force_reg (<MODE>mode, operands[1]);
157   if (MEM_P (operands[0]))
158     {
159       addr = force_reg (Pmode, XEXP (operands[0], 0));
160       emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
161     }
162   else
163     {
164       addr = force_reg (Pmode, XEXP (operands[1], 0));
165       emit_insn (gen_unaligned_load<mode> (operands[0], addr));
166     }
167   DONE;
170 (define_expand "movsi"
171   [(set (match_operand:SI 0 "general_operand" "")
172         (match_operand:SI 1 "general_operand" ""))]
173   ""
175   /* Need to force register if mem <- !reg.  */
176   if (MEM_P (operands[0]) && !REG_P (operands[1]))
177     operands[1] = force_reg (SImode, operands[1]);
179   /* If operands[1] is a large constant and cannot be performed
180      by a single instruction, we need to split it.  */
181   if (CONST_INT_P (operands[1])
182       && !satisfies_constraint_Is20 (operands[1])
183       && !satisfies_constraint_Ihig (operands[1]))
184     {
185       rtx high20_rtx;
186       HOST_WIDE_INT low12_int;
187       rtx tmp_rtx;
189       tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
191       high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
192       low12_int = INTVAL (operands[1]) & 0xfff;
194       emit_move_insn (tmp_rtx, high20_rtx);
195       emit_move_insn (operands[0], plus_constant (SImode,
196                                                   tmp_rtx,
197                                                   low12_int));
198       DONE;
199     }
202 (define_insn "*mov<mode>"
203   [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r,U45,U33,U37,U45, m,  l,  l,  l,  d,  d, r,   d,    r,    r,    r, *f, *f,  r, *f,  Q")
204         (match_operand:QIHISI 1 "nds32_move_operand"   " r, r,  l,  l,  l,  d, r,U45,U33,U37,U45,Ufe, m,Ip05, Is05, Is20, Ihig, *f,  r, *f,  Q, *f"))]
205   "register_operand(operands[0], <MODE>mode)
206    || register_operand(operands[1], <MODE>mode)"
208   switch (which_alternative)
209     {
210     case 0:
211       return "mov55\t%0, %1";
212     case 1:
213       return "ori\t%0, %1, 0";
214     case 2:
215     case 3:
216     case 4:
217     case 5:
218       return nds32_output_16bit_store (operands, <byte>);
219     case 6:
220       return nds32_output_32bit_store (operands, <byte>);
221     case 7:
222     case 8:
223     case 9:
224     case 10:
225     case 11:
226       return nds32_output_16bit_load (operands, <byte>);
227     case 12:
228       return nds32_output_32bit_load (operands, <byte>);
229     case 13:
230       return "movpi45\t%0, %1";
231     case 14:
232       return "movi55\t%0, %1";
233     case 15:
234       return "movi\t%0, %1";
235     case 16:
236       return "sethi\t%0, hi20(%1)";
237     case 17:
238       if (TARGET_FPU_SINGLE)
239         return "fcpyss\t%0, %1, %1";
240       else
241         return "#";
242     case 18:
243       return "fmtsr\t%1, %0";
244     case 19:
245       return "fmfsr\t%0, %1";
246     case 20:
247       return nds32_output_float_load (operands);
248     case 21:
249       return nds32_output_float_store (operands);
250     default:
251       gcc_unreachable ();
252     }
254   [(set_attr "type"    "alu,alu,store,store,store,store,store,load,load,load,load,load,load,alu,alu,alu,alu,fcpy,fmtsr,fmfsr,fload,fstore")
255    (set_attr "length"  "  2,  4,    2,    2,    2,    2,    4,   2,   2,   2,   2,   2,   4,  2,  2,  4,  4,   4,    4,    4,    4,     4")
256    (set_attr "feature" " v1, v1,   v1,   v1,   v1,   v1,   v1,  v1,  v1,  v1,  v1, v3m,  v1, v1, v1, v1, v1, fpu,  fpu,  fpu,  fpu,   fpu")])
259 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
260 ;; are able to match such instruction template.
261 (define_insn "move_addr"
262   [(set (match_operand:SI 0 "register_operand"       "=l, r")
263         (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
264   ""
265   "la\t%0, %1"
266   [(set_attr "type"  "alu")
267    (set_attr "length"  "8")])
270 (define_insn "sethi"
271   [(set (match_operand:SI 0 "register_operand"                "=r")
272         (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
273   ""
274   "sethi\t%0, hi20(%1)"
275   [(set_attr "type" "alu")
276    (set_attr "length" "4")])
279 (define_insn "lo_sum"
280   [(set (match_operand:SI 0 "register_operand"                  "=r")
281         (lo_sum:SI (match_operand:SI 1 "register_operand"       " r")
282                    (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
283   ""
284   "ori\t%0, %1, lo12(%2)"
285   [(set_attr "type" "alu")
286    (set_attr "length" "4")])
289 ;; ----------------------------------------------------------------------------
291 ;; Zero extension instructions.
293 (define_insn "zero_extend<mode>si2"
294   [(set (match_operand:SI 0 "register_operand"                       "=l, r,   l, *r")
295         (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33,  m")))]
296   ""
298   switch (which_alternative)
299     {
300     case 0:
301       return "ze<size>33\t%0, %1";
302     case 1:
303       return "ze<size>\t%0, %1";
304     case 2:
305       return nds32_output_16bit_load (operands, <byte>);
306     case 3:
307       return nds32_output_32bit_load (operands, <byte>);
309     default:
310       gcc_unreachable ();
311     }
313   [(set_attr "type"   "alu,alu,load,load")
314    (set_attr "length" "  2,  4,   2,   4")])
317 ;; Sign extension instructions.
319 (define_insn "extend<mode>si2"
320   [(set (match_operand:SI 0 "register_operand"                       "=l, r, r")
321         (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
322   ""
324   switch (which_alternative)
325     {
326     case 0:
327       return "se<size>33\t%0, %1";
328     case 1:
329       return "se<size>\t%0, %1";
330     case 2:
331       return nds32_output_32bit_load_s (operands, <byte>);
333     default:
334       gcc_unreachable ();
335     }
337   [(set_attr "type"   "alu,alu,load")
338    (set_attr "length" "  2,  4,   4")])
341 ;; ----------------------------------------------------------------------------
343 ;; Arithmetic instructions.
345 (define_insn "addsi3"
346   [(set (match_operand:SI 0 "register_operand"               "=   d,   l,   d,   l, d, l,   k,   l,    r, r")
347         (plus:SI (match_operand:SI 1 "register_operand"      "%   0,   l,   0,   l, 0, l,   0,   k,    r, r")
348                  (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,Iu06, Is15, r")))]
349   ""
351   switch (which_alternative)
352     {
353     case 0:
354       /* addi Rt4,Rt4,-x  ==>  subi45 Rt4,x
355          where 0 <= x <= 31 */
356       operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
357       return "subi45\t%0, %2";
358     case 1:
359       /* addi Rt3,Ra3,-x  ==>  subi333 Rt3,Ra3,x
360          where 0 <= x <= 7 */
361       operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
362       return "subi333\t%0, %1, %2";
363     case 2:
364       return "addi45\t%0, %2";
365     case 3:
366       return "addi333\t%0, %1, %2";
367     case 4:
368       return "add45\t%0, %2";
369     case 5:
370       return "add333\t%0, %1, %2";
371     case 6:
372       return "addi10.sp\t%2";
373     case 7:
374       return "addri36.sp\t%0, %2";
375     case 8:
376       return "addi\t%0, %1, %2";
377     case 9:
378       return "add\t%0, %1, %2";
380     default:
381       gcc_unreachable ();
382     }
384   [(set_attr "type"    "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
385    (set_attr "length"  "  2,  2,  2,  2,  2,  2,  2,  2,  4,  4")
386    (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")])
388 (define_insn "subsi3"
389   [(set (match_operand:SI 0 "register_operand"                "=d, l,    r, r")
390         (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
391                   (match_operand:SI 2 "register_operand"      " r, l,    r, r")))]
392   ""
393   "@
394    sub45\t%0, %2
395    sub333\t%0, %1, %2
396    subri\t%0, %2, %1
397    sub\t%0, %1, %2"
398   [(set_attr "type"   "alu,alu,alu,alu")
399    (set_attr "length" "  2,  2,  4,  4")])
402 ;; GCC intends to simplify (plus (ashift ...) (reg))
403 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
404 ;; and needs to ensure it is exact_log2 value.
405 (define_insn "*add_slli"
406   [(set (match_operand:SI 0 "register_operand"                    "=r")
407         (plus:SI (mult:SI (match_operand:SI 1 "register_operand"  " r")
408                           (match_operand:SI 2 "immediate_operand" " i"))
409                  (match_operand:SI 3 "register_operand"           " r")))]
410   "TARGET_ISA_V3 && optimize_size
411    && (exact_log2 (INTVAL (operands[2])) != -1)
412    && (exact_log2 (INTVAL (operands[2])) <= 31)"
414   /* Get floor_log2 of the immediate value
415      so that we can generate 'add_slli' instruction.  */
416   operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
418   return "add_slli\t%0, %3, %1, %2";
420   [(set_attr "type" "alu_shift")
421    (set_attr "combo"        "2")
422    (set_attr "length"       "4")])
424 (define_insn "*add_srli"
425   [(set (match_operand:SI 0 "register_operand"                          "=   r")
426         (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
427                               (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
428                  (match_operand:SI 3 "register_operand"                 "    r")))]
429   "TARGET_ISA_V3 && optimize_size"
430   "add_srli\t%0, %3, %1, %2"
431   [(set_attr "type" "alu_shift")
432    (set_attr "combo"        "2")
433    (set_attr "length"       "4")])
436 ;; GCC intends to simplify (minus (reg) (ashift ...))
437 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
438 ;; and needs to ensure it is exact_log2 value.
439 (define_insn "*sub_slli"
440   [(set (match_operand:SI 0 "register_operand"                     "=r")
441         (minus:SI (match_operand:SI 1 "register_operand"           " r")
442                   (mult:SI (match_operand:SI 2 "register_operand"  " r")
443                            (match_operand:SI 3 "immediate_operand" " i"))))]
444   "TARGET_ISA_V3 && optimize_size
445    && (exact_log2 (INTVAL (operands[3])) != -1)
446    && (exact_log2 (INTVAL (operands[3])) <= 31)"
448   /* Get floor_log2 of the immediate value
449      so that we can generate 'sub_slli' instruction.  */
450   operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
452   return "sub_slli\t%0, %1, %2, %3";
454   [(set_attr "type" "alu_shift")
455    (set_attr "combo"        "2")
456    (set_attr "length"       "4")])
458 (define_insn "*sub_srli"
459   [(set (match_operand:SI 0 "register_operand"                           "=   r")
460         (minus:SI (match_operand:SI 1 "register_operand"                 "    r")
461                   (lshiftrt:SI (match_operand:SI 2 "register_operand"    "    r")
462                                (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))]
463   "TARGET_ISA_V3 && optimize_size"
464   "sub_srli\t%0, %1, %2, %3"
465   [(set_attr "type" "alu_shift")
466    (set_attr "combo"        "2")
467    (set_attr "length"       "4")])
470 ;; Multiplication instructions.
472 (define_insn "mulsi3"
473   [(set (match_operand:SI 0 "register_operand"          "=w, r")
474         (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
475                  (match_operand:SI 2 "register_operand" " w, r")))]
476   ""
477   "@
478    mul33\t%0, %2
479    mul\t%0, %1, %2"
480   [(set_attr "type"    "mul,mul")
481    (set_attr "length"  "  2,  4")
482    (set_attr "feature" "v3m, v1")])
484 (define_insn "mulsidi3"
485   [(set (match_operand:DI 0 "register_operand"                          "=r")
486         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
487                  (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
488   "TARGET_ISA_V2 || TARGET_ISA_V3"
489   "mulsr64\t%0, %1, %2"
490   [(set_attr "type"   "mul")
491    (set_attr "length"   "4")])
493 (define_insn "umulsidi3"
494   [(set (match_operand:DI 0 "register_operand"                          "=r")
495         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
496                  (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
497   "TARGET_ISA_V2 || TARGET_ISA_V3"
498   "mulr64\t%0, %1, %2"
499   [(set_attr "type"   "mul")
500    (set_attr "length"   "4")])
503 ;; Multiply-accumulate instructions.
505 (define_insn "*maddr32_0"
506   [(set (match_operand:SI 0 "register_operand"                   "=r")
507         (plus:SI (match_operand:SI 3 "register_operand"          " 0")
508                  (mult:SI (match_operand:SI 1 "register_operand" " r")
509                           (match_operand:SI 2 "register_operand" " r"))))]
510   ""
511   "maddr32\t%0, %1, %2"
512   [(set_attr "type"   "mac")
513    (set_attr "length"   "4")])
515 (define_insn "*maddr32_1"
516   [(set (match_operand:SI 0 "register_operand"                   "=r")
517         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
518                           (match_operand:SI 2 "register_operand" " r"))
519                  (match_operand:SI 3 "register_operand"          " 0")))]
520   ""
521   "maddr32\t%0, %1, %2"
522   [(set_attr "type"   "mac")
523    (set_attr "length"   "4")])
525 (define_insn "*msubr32"
526   [(set (match_operand:SI 0 "register_operand"                    "=r")
527         (minus:SI (match_operand:SI 3 "register_operand"          " 0")
528                   (mult:SI (match_operand:SI 1 "register_operand" " r")
529                            (match_operand:SI 2 "register_operand" " r"))))]
530   ""
531   "msubr32\t%0, %1, %2"
532   [(set_attr "type"   "mac")
533    (set_attr "length"   "4")])
536 ;; Div Instructions.
538 (define_insn "divmodsi4"
539   [(set (match_operand:SI 0 "register_operand"         "=r")
540         (div:SI (match_operand:SI 1 "register_operand" " r")
541                 (match_operand:SI 2 "register_operand" " r")))
542    (set (match_operand:SI 3 "register_operand"         "=r")
543         (mod:SI (match_dup 1) (match_dup 2)))]
544   ""
545   "divsr\t%0, %3, %1, %2"
546   [(set_attr "type"   "div")
547    (set_attr "length"   "4")])
549 (define_insn "udivmodsi4"
550   [(set (match_operand:SI 0 "register_operand"          "=r")
551         (udiv:SI (match_operand:SI 1 "register_operand" " r")
552                  (match_operand:SI 2 "register_operand"  " r")))
553    (set (match_operand:SI 3 "register_operand"          "=r")
554         (umod:SI (match_dup 1) (match_dup 2)))]
555   ""
556   "divr\t%0, %3, %1, %2"
557   [(set_attr "type"   "div")
558    (set_attr "length"   "4")])
560 ;; divsr/divr will keep quotient only when quotient and remainder is the same
561 ;; register in our ISA spec, it's can reduce 1 register presure if we don't
562 ;; want remainder.
563 (define_insn "divsi4"
564   [(set (match_operand:SI 0 "register_operand"         "=r")
565         (div:SI (match_operand:SI 1 "register_operand" " r")
566                 (match_operand:SI 2 "register_operand" " r")))]
567   ""
568   "divsr\t%0, %0, %1, %2"
569   [(set_attr "type"   "div")
570    (set_attr "length"   "4")])
572 (define_insn "udivsi4"
573   [(set (match_operand:SI 0 "register_operand"          "=r")
574         (udiv:SI (match_operand:SI 1 "register_operand" " r")
575                  (match_operand:SI 2 "register_operand"  " r")))]
576   ""
577   "divr\t%0, %0, %1, %2"
578   [(set_attr "type"   "div")
579    (set_attr "length"   "4")])
581 ;; ----------------------------------------------------------------------------
583 ;; Boolean instructions.
584 ;; Note: We define the DImode versions in nds32-doubleword.md.
586 ;; ----------------------------------------------------------------------------
587 ;; 'AND' operation
588 ;; ----------------------------------------------------------------------------
590 (define_insn "bitc"
591   [(set (match_operand:SI 0 "register_operand"                 "=r")
592         (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
593                 (match_operand:SI 2 "register_operand"         " r")))]
594   "TARGET_ISA_V3"
595   "bitc\t%0, %2, %1"
596   [(set_attr "type" "alu")
597    (set_attr "length" "4")]
600 (define_expand "andsi3"
601   [(set (match_operand:SI 0 "register_operand" "")
602         (and:SI (match_operand:SI 1 "register_operand" "")
603                 (match_operand:SI 2 "nds32_reg_constant_operand" "")))]
604   ""
606   if (CONST_INT_P (operands[2])
607       && !nds32_and_operand (operands[2], SImode))
608     {
609       nds32_expand_constant (SImode, INTVAL (operands[2]),
610                              operands[0], operands[1]);
611       DONE;
612     }
615 (define_insn "*andsi3"
616   [(set (match_operand:SI 0 "register_operand"          "=l, r,   l,   l,   l,   l,   l,   l,    r,   r,     r,    r,    r")
617         (and:SI (match_operand:SI 1 "register_operand"  "%0, r,   l,   l,   l,   l,   0,   0,    r,   r,     r,    r,    r")
618                 (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
619   ""
621   HOST_WIDE_INT mask = INTVAL (operands[2]);
623   /* 16-bit andi instructions:
624      andi Rt3,Ra3,0xff   -> zeb33  Rt3,Ra3
625      andi Rt3,Ra3,0xffff -> zeh33  Rt3,Ra3
626      andi Rt3,Ra3,0x01   -> xlsb33 Rt3,Ra3
627      andi Rt3,Ra3,0x7ff  -> x11b33 Rt3,Ra3
628      andi Rt3,Rt3,2^imm3u          -> bmski33 Rt3,imm3u
629      andi Rt3,Rt3,(2^(imm3u+1))-1  -> fexti33 Rt3,imm3u.  */
631   switch (which_alternative)
632     {
633     case 0:
634       return "and33\t%0, %2";
635     case 1:
636       return "and\t%0, %1, %2";
637     case 2:
638       return "zeb33\t%0, %1";
639     case 3:
640       return "zeh33\t%0, %1";
641     case 4:
642       return "xlsb33\t%0, %1";
643     case 5:
644       return "x11b33\t%0, %1";
645     case 6:
646       return "bmski33\t%0, %B2";
647     case 7:
648       operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
649       return "fexti33\t%0, %2";
650     case 8:
651       return "zeb\t%0, %1";
652     case 9:
653       return "zeh\t%0, %1";
654     case 10:
655       return "andi\t%0, %1, %2";
656     case 11:
657       operands[2] = GEN_INT (~mask);
658       return "bitci\t%0, %1, %2";
659     case 12:
660       return "bclr\t%0, %1, %b2";
662     default:
663       gcc_unreachable ();
664     }
666   [(set_attr "type"    "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
667    (set_attr "length"  "  2,  4,  2,  2,  2,  2,  2,  2,  4,  4,  4,  4,  4")
668    (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")])
670 (define_insn "*and_slli"
671   [(set (match_operand:SI 0 "register_operand"                        "=   r")
672         (and:SI (ashift:SI (match_operand:SI 1 "register_operand"     "    r")
673                             (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
674                 (match_operand:SI 3 "register_operand"                "    r")))]
675   "TARGET_ISA_V3 && optimize_size"
676   "and_slli\t%0, %3, %1, %2"
677   [(set_attr "type" "alu_shift")
678    (set_attr "length"       "4")])
680 (define_insn "*and_srli"
681   [(set (match_operand:SI 0 "register_operand"                         "=   r")
682         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
683                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
684                 (match_operand:SI 3 "register_operand"                 "    r")))]
685   "TARGET_ISA_V3 && optimize_size"
686   "and_srli\t%0, %3, %1, %2"
687   [(set_attr "type" "alu_shift")
688    (set_attr "length"       "4")])
691 ;; ----------------------------------------------------------------------------
692 ;; 'OR' operation
693 ;; ----------------------------------------------------------------------------
695 ;; For V3/V3M ISA, we have 'or33' instruction.
696 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
698 (define_expand "iorsi3"
699   [(set (match_operand:SI 0 "register_operand"         "")
700         (ior:SI (match_operand:SI 1 "register_operand" "")
701                 (match_operand:SI 2 "general_operand"  "")))]
702   ""
704   if (!nds32_ior_operand (operands[2], SImode))
705     operands[2] = force_reg (SImode, operands[2]);
708 (define_insn "*iorsi3"
709   [(set (match_operand:SI 0 "register_operand"          "=l, r,    r,    r")
710         (ior:SI (match_operand:SI 1 "register_operand"  "%0, r,    r,    r")
711                 (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))]
712   ""
713   "@
714    or33\t%0, %2
715    or\t%0, %1, %2
716    ori\t%0, %1, %2
717    bset\t%0, %1, %B2"
718   [(set_attr "type"    "alu,alu,alu,alu")
719    (set_attr "length"  "  2,  4,  4,  4")
720    (set_attr "feature" "v3m, v1, v1,pe1")])
722 (define_insn "*or_slli"
723   [(set (match_operand:SI 0 "register_operand"                       "=   r")
724         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand"    "    r")
725                            (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
726                 (match_operand:SI 3 "register_operand"               "    r")))]
727   "TARGET_ISA_V3 && optimize_size"
728   "or_slli\t%0, %3, %1, %2"
729   [(set_attr "type" "alu_shift")
730    (set_attr "length"       "4")])
732 (define_insn "*or_srli"
733   [(set (match_operand:SI 0 "register_operand"                         "=   r")
734         (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
735                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
736                 (match_operand:SI 3 "register_operand"                 "    r")))]
737   "TARGET_ISA_V3 && optimize_size"
738   "or_srli\t%0, %3, %1, %2"
739   [(set_attr "type" "alu_shift")
740    (set_attr "length"       "4")])
743 ;; ----------------------------------------------------------------------------
744 ;; 'XOR' operation
745 ;; ----------------------------------------------------------------------------
747 ;; For V3/V3M ISA, we have 'xor33' instruction.
748 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
750 (define_expand "xorsi3"
751   [(set (match_operand:SI 0 "register_operand"         "")
752         (xor:SI (match_operand:SI 1 "register_operand" "")
753                 (match_operand:SI 2 "general_operand"  "")))]
754   ""
756   if (!nds32_xor_operand (operands[2], SImode))
757     operands[2] = force_reg (SImode, operands[2]);
760 (define_insn "*xorsi3"
761   [(set (match_operand:SI 0 "register_operand"          "=l, r,    r,    r")
762         (xor:SI (match_operand:SI 1 "register_operand"  "%0, r,    r,    r")
763                 (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))]
764   ""
765   "@
766    xor33\t%0, %2
767    xor\t%0, %1, %2
768    xori\t%0, %1, %2
769    btgl\t%0, %1, %B2"
770   [(set_attr "type"    "alu,alu,alu,alu")
771    (set_attr "length"  "  2,  4,  4,  4")
772    (set_attr "feature" "v3m, v1, v1,pe1")])
774 (define_insn "*xor_slli"
775   [(set (match_operand:SI 0 "register_operand"                     "=   r")
776         (xor:SI (ashift:SI (match_operand:SI 1 "register_operand"  "    r")
777                            (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
778                 (match_operand:SI 3 "register_operand"             "    r")))]
779   "TARGET_ISA_V3 && optimize_size"
780   "xor_slli\t%0, %3, %1, %2"
781   [(set_attr "type" "alu_shift")
782    (set_attr "length"       "4")])
784 (define_insn "*xor_srli"
785   [(set (match_operand:SI 0 "register_operand"                         "=   r")
786         (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
787                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
788                 (match_operand:SI 3 "register_operand"                 "    r")))]
789   "TARGET_ISA_V3 && optimize_size"
790   "xor_srli\t%0, %3, %1, %2"
791   [(set_attr "type" "alu_shift")
792    (set_attr "length"       "4")])
794 ;; Rotate Right Instructions.
796 (define_insn "*rotrsi3"
797   [(set (match_operand:SI 0 "register_operand"                    "=   r, r")
798           (rotatert:SI (match_operand:SI 1 "register_operand"     "    r, r")
799                        (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
800   ""
801   "@
802    rotri\t%0, %1, %2
803    rotr\t%0, %1, %2"
804   [(set_attr "type"    "  alu,  alu")
805    (set_attr "subtype" "shift,shift")
806    (set_attr "length"  "    4,    4")])
809 ;; ----------------------------------------------------------------------------
810 ;; 'NEG' operation
811 ;; ----------------------------------------------------------------------------
813 ;; For V3/V3M ISA, we have 'neg33' instruction.
814 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
815 ;; And for V2 ISA, there is NO 'neg33' instruction.
816 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
817 (define_insn "negsi2"
818   [(set (match_operand:SI 0 "register_operand"         "=l, r")
819         (neg:SI (match_operand:SI 1 "register_operand" " l, r")))]
820   ""
821   "@
822    neg33\t%0, %1
823    subri\t%0, %1, 0"
824   [(set_attr "type"    "alu,alu")
825    (set_attr "length"  "  2,  4")
826    (set_attr "feature" "v3m, v1")])
828 (define_expand "negsf2"
829   [(set (match_operand:SF 0 "register_operand" "")
830         (neg:SF (match_operand:SF 1 "register_operand" "")))]
831   ""
833   if (!TARGET_FPU_SINGLE && !TARGET_EXT_PERF)
834     {
835       rtx new_dst = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
836       rtx new_src = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
838       emit_insn (gen_xorsi3 (new_dst,
839                              new_src,
840                              gen_int_mode (0x80000000, SImode)));
842       DONE;
843     }
846 (define_expand "negdf2"
847   [(set (match_operand:DF 0 "register_operand" "")
848         (neg:DF (match_operand:DF 1 "register_operand" "")))]
849   ""
853 (define_insn_and_split "soft_negdf2"
854   [(set (match_operand:DF 0 "register_operand" "")
855         (neg:DF (match_operand:DF 1 "register_operand" "")))]
856   "!TARGET_FPU_DOUBLE"
857   "#"
858   "!TARGET_FPU_DOUBLE"
859   [(const_int 1)]
861     rtx src = operands[1];
862     rtx dst = operands[0];
863     rtx ori_dst = operands[0];
865     bool need_extra_move_for_dst_p;
866     /* FPU register can't change mode to SI directly, so we need create a
867        tmp register to handle it, and FPU register can't do `xor` or btgl.  */
868     if (HARD_REGISTER_P (src)
869         && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (src)))
870       {
871         rtx tmp = gen_reg_rtx (DFmode);
872         emit_move_insn (tmp, src);
873         src = tmp;
874       }
876     if (HARD_REGISTER_P (dst)
877         && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (dst)))
878       {
879         need_extra_move_for_dst_p = true;
880         rtx tmp = gen_reg_rtx (DFmode);
881         dst = tmp;
882       }
884     rtx dst_high_part = simplify_gen_subreg (
885                           SImode, dst,
886                           DFmode, subreg_highpart_offset (SImode, DFmode));
887     rtx dst_low_part = simplify_gen_subreg (
888                           SImode, dst,
889                           DFmode, subreg_lowpart_offset (SImode, DFmode));
890     rtx src_high_part = simplify_gen_subreg (
891                           SImode, src,
892                           DFmode, subreg_highpart_offset (SImode, DFmode));
893     rtx src_low_part = simplify_gen_subreg (
894                           SImode, src,
895                           DFmode, subreg_lowpart_offset (SImode, DFmode));
897     emit_insn (gen_xorsi3 (dst_high_part,
898                            src_high_part,
899                            gen_int_mode (0x80000000, SImode)));
900     emit_move_insn (dst_low_part, src_low_part);
902     if (need_extra_move_for_dst_p)
903       emit_move_insn (ori_dst, dst);
905     DONE;
909 ;; ----------------------------------------------------------------------------
910 ;; 'ONE_COMPLIMENT' operation
911 ;; ----------------------------------------------------------------------------
913 ;; For V3/V3M ISA, we have 'not33' instruction.
914 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
915 (define_insn "one_cmplsi2"
916   [(set (match_operand:SI 0 "register_operand"         "=w, r")
917         (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
918   ""
919   "@
920    not33\t%0, %1
921    nor\t%0, %1, %1"
922   [(set_attr "type"    "alu,alu")
923    (set_attr "length"  "  2,  4")
924    (set_attr "feature" "v3m, v1")])
927 ;; ----------------------------------------------------------------------------
929 ;; Shift instructions.
931 (define_expand "<shift>si3"
932   [(set (match_operand:SI 0 "register_operand"                      "")
933         (shift_rotate:SI (match_operand:SI 1 "register_operand"     "")
934                          (match_operand:SI 2 "nds32_rimm5u_operand" "")))]
935   ""
937   if (operands[2] == const0_rtx)
938     {
939       emit_move_insn (operands[0], operands[1]);
940       DONE;
941     }
944 (define_insn "*ashlsi3"
945   [(set (match_operand:SI 0 "register_operand"                "=   l,    r, r")
946         (ashift:SI (match_operand:SI 1 "register_operand"     "    l,    r, r")
947                    (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))]
948   ""
949   "@
950    slli333\t%0, %1, %2
951    slli\t%0, %1, %2
952    sll\t%0, %1, %2"
953   [(set_attr "type"    "  alu,  alu,  alu")
954    (set_attr "subtype" "shift,shift,shift")
955    (set_attr "length"  "    2,    4,    4")])
957 (define_insn "*ashrsi3"
958   [(set (match_operand:SI 0 "register_operand"                  "=   d,    r, r")
959         (ashiftrt:SI (match_operand:SI 1 "register_operand"     "    0,    r, r")
960                      (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
961   ""
962   "@
963    srai45\t%0, %2
964    srai\t%0, %1, %2
965    sra\t%0, %1, %2"
966   [(set_attr "type"    "  alu,  alu,  alu")
967    (set_attr "subtype" "shift,shift,shift")
968    (set_attr "length"  "    2,    4,    4")])
970 (define_insn "*lshrsi3"
971   [(set (match_operand:SI 0 "register_operand"                  "=   d,    r, r")
972         (lshiftrt:SI (match_operand:SI 1 "register_operand"     "    0,    r, r")
973                      (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
974   ""
975   "@
976    srli45\t%0, %2
977    srli\t%0, %1, %2
978    srl\t%0, %1, %2"
979   [(set_attr "type"    "  alu,  alu,  alu")
980    (set_attr "subtype" "shift,shift,shift")
981    (set_attr "length"  "    2,    4,    4")])
984 ;; ----------------------------------------------------------------------------
986 ;; ----------------------------------------------------------------------------
987 ;; Conditional Move patterns
988 ;; ----------------------------------------------------------------------------
990 (define_expand "mov<mode>cc"
991   [(set (match_operand:QIHISI 0 "register_operand" "")
992         (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
993                          (match_operand:QIHISI 2 "register_operand" "")
994                          (match_operand:QIHISI 3 "register_operand" "")))]
995   "TARGET_CMOV && !optimize_size"
997   enum nds32_expand_result_type result = nds32_expand_movcc (operands);
998   switch (result)
999     {
1000     case EXPAND_DONE:
1001       DONE;
1002       break;
1003     case EXPAND_FAIL:
1004       FAIL;
1005       break;
1006     case EXPAND_CREATE_TEMPLATE:
1007       break;
1008     default:
1009       gcc_unreachable ();
1010     }
1013 (define_insn "cmovz<mode>"
1014   [(set (match_operand:QIHISI 0 "register_operand"                      "=r, r")
1015         (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
1016                              (const_int 0))
1017                          (match_operand:QIHISI 2 "register_operand"     " r, 0")
1018                          (match_operand:QIHISI 3 "register_operand"     " 0, r")))]
1019   "TARGET_CMOV"
1020   "@
1021    cmovz\t%0, %2, %1
1022    cmovn\t%0, %3, %1"
1023   [(set_attr "type"  "alu")
1024    (set_attr "length"  "4")])
1026 (define_insn "cmovn<mode>"
1027   [(set (match_operand:QIHISI 0 "register_operand"                      "=r, r")
1028         (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
1029                              (const_int 0))
1030                          (match_operand:QIHISI 2 "register_operand"     " r, 0")
1031                          (match_operand:QIHISI 3 "register_operand"     " 0, r")))]
1032   "TARGET_CMOV"
1033   "@
1034    cmovn\t%0, %2, %1
1035    cmovz\t%0, %3, %1"
1036   [(set_attr "type"  "alu")
1037    (set_attr "length"  "4")])
1039 ;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
1040 ;; It should be removed once after we change the expansion form of the cmovn.
1041 (define_insn "*cmovn_simplified_<mode>"
1042   [(set (match_operand:QIHISI 0 "register_operand" "=r")
1043         (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
1044                          (match_operand:QIHISI 2 "register_operand" "r")
1045                          (match_operand:QIHISI 3 "register_operand" "0")))]
1046   ""
1047   "cmovn\t%0, %2, %1"
1048   [(set_attr "type" "alu")])
1050 ;; ----------------------------------------------------------------------------
1051 ;; Conditional Branch patterns
1052 ;; ----------------------------------------------------------------------------
1054 (define_expand "cbranchsi4"
1055   [(set (pc)
1056         (if_then_else (match_operator 0 "comparison_operator"
1057                         [(match_operand:SI 1 "register_operand"           "")
1058                          (match_operand:SI 2 "nds32_reg_constant_operand" "")])
1059                       (label_ref (match_operand 3 "" ""))
1060                       (pc)))]
1061   ""
1063   enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
1064   switch (result)
1065     {
1066     case EXPAND_DONE:
1067       DONE;
1068       break;
1069     case EXPAND_FAIL:
1070       FAIL;
1071       break;
1072     case EXPAND_CREATE_TEMPLATE:
1073       break;
1074     default:
1075       gcc_unreachable ();
1076     }
1080 (define_insn "cbranchsi4_equality_zero"
1081   [(set (pc)
1082         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1083                         [(match_operand:SI 1 "register_operand"  "t,l, r")
1084                          (const_int 0)])
1085                       (label_ref (match_operand 2 "" ""))
1086                       (pc)))]
1087   ""
1089   return nds32_output_cbranchsi4_equality_zero (insn, operands);
1091   [(set_attr "type" "branch")
1092    (set_attr_alternative "enabled"
1093      [
1094        ;; Alternative 0
1095        (if_then_else (match_test "TARGET_16_BIT")
1096                      (const_string "yes")
1097                      (const_string "no"))
1098        ;; Alternative 1
1099        (if_then_else (match_test "TARGET_16_BIT")
1100                      (const_string "yes")
1101                      (const_string "no"))
1102        ;; Alternative 2
1103        (const_string "yes")
1104      ])
1105    (set_attr_alternative "length"
1106      [
1107        ;; Alternative 0
1108        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1109                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1110                                         (le (minus (match_dup 2) (pc)) (const_int  250)))
1111                                    (if_then_else (match_test "TARGET_16_BIT")
1112                                                  (const_int 2)
1113                                                  (const_int 4))
1114                                    (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1115                                                       (le (minus (match_dup 2) (pc)) (const_int  65500)))
1116                                                  (const_int 4)
1117                                                  (if_then_else (match_test "TARGET_16_BIT")
1118                                                                (const_int 8)
1119                                                                (const_int 10))))
1120                      (const_int 10))
1121        ;; Alternative 1
1122        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1123                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1124                                         (le (minus (match_dup 2) (pc)) (const_int  250)))
1125                                    (if_then_else (match_test "TARGET_16_BIT")
1126                                                  (const_int 2)
1127                                                  (const_int 4))
1128                                    (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1129                                                       (le (minus (match_dup 2) (pc)) (const_int  65500)))
1130                                                  (const_int 4)
1131                                                  (if_then_else (match_test "TARGET_16_BIT")
1132                                                                (const_int 8)
1133                                                                (const_int 10))))
1134                      (const_int 10))
1135        ;; Alternative 2
1136        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1137                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1138                                         (le (minus (match_dup 2) (pc)) (const_int  65500)))
1139                                    (const_int 4)
1140                                    (const_int 10))
1141                      (const_int 10))
1142      ])])
1145 ;; This pattern is dedicated to V2 ISA,
1146 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
1147 (define_insn "cbranchsi4_equality_reg"
1148   [(set (pc)
1149         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1150                         [(match_operand:SI 1 "register_operand" "v, r")
1151                          (match_operand:SI 2 "register_operand" "l, r")])
1152                       (label_ref (match_operand 3 "" ""))
1153                       (pc)))]
1154   "TARGET_ISA_V2"
1156   return nds32_output_cbranchsi4_equality_reg (insn, operands);
1158   [(set_attr "type"   "branch")
1159    (set_attr_alternative "enabled"
1160      [
1161        ;; Alternative 0
1162        (if_then_else (match_test "TARGET_16_BIT")
1163                      (const_string "yes")
1164                      (const_string "no"))
1165        ;; Alternative 1
1166        (const_string "yes")
1167      ])
1168    (set_attr_alternative "length"
1169      [
1170        ;; Alternative 0
1171        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1172                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1173                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1174                                    (const_int 2)
1175                                    (if_then_else (and (ge (minus (match_dup 3) (pc))
1176                                                           (const_int -16350))
1177                                                       (le (minus (match_dup 3) (pc))
1178                                                           (const_int  16350)))
1179                                                  (const_int 4)
1180                                                  (const_int 8)))
1181                      (const_int 8))
1182        ;; Alternative 1
1183        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1184                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1185                                         (le (minus (match_dup 3) (pc)) (const_int  16350)))
1186                                    (const_int 4)
1187                                    (const_int 10))
1188                      (const_int 10))
1189      ])])
1192 ;; This pattern is dedicated to V3/V3M,
1193 ;; because V3/V3M DO HAVE beqc/bnec instruction.
1194 (define_insn "cbranchsi4_equality_reg_or_const_int"
1195   [(set (pc)
1196         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1197                         [(match_operand:SI 1 "register_operand"      "v, r,    r")
1198                          (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
1199                       (label_ref (match_operand 3 "" ""))
1200                       (pc)))]
1201   "TARGET_ISA_V3 || TARGET_ISA_V3M"
1203   return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
1205   [(set_attr "type"   "branch")
1206    (set_attr_alternative "enabled"
1207      [
1208        ;; Alternative 0
1209        (if_then_else (match_test "TARGET_16_BIT")
1210                      (const_string "yes")
1211                      (const_string "no"))
1212        ;; Alternative 1
1213        (const_string "yes")
1214        ;; Alternative 2
1215        (const_string "yes")
1216      ])
1217    (set_attr_alternative "length"
1218      [
1219        ;; Alternative 0
1220        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1221                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1222                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1223                                    (const_int 2)
1224                                    (if_then_else (and (ge (minus (match_dup 3) (pc))
1225                                                           (const_int -16350))
1226                                                       (le (minus (match_dup 3) (pc))
1227                                                           (const_int  16350)))
1228                                                  (const_int 4)
1229                                                  (const_int 8)))
1230                     (const_int 8))
1231        ;; Alternative 1
1232        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1233                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1234                                         (le (minus (match_dup 3) (pc)) (const_int  16350)))
1235                                    (const_int 4)
1236                                    (const_int 10))
1237                     (const_int 10))
1238        ;; Alternative 2
1239        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1240                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1241                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1242                                    (const_int 4)
1243                                    (const_int 10))
1244                     (const_int 10))
1245      ])])
1248 (define_insn "*cbranchsi4_greater_less_zero"
1249   [(set (pc)
1250         (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1251                         [(match_operand:SI 1 "register_operand" "r")
1252                          (const_int 0)])
1253                       (label_ref (match_operand 2 "" ""))
1254                       (pc)))]
1255   ""
1257   return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
1259   [(set_attr "type"   "branch")
1260    (set (attr "length")
1261         (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1262                       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1263                                          (le (minus (match_dup 2) (pc)) (const_int  65500)))
1264                                     (const_int 4)
1265                                     (const_int 10))
1266                       (const_int 10)))])
1269 (define_expand "cstoresi4"
1270   [(set (match_operand:SI 0 "register_operand" "")
1271         (match_operator:SI 1 "comparison_operator"
1272           [(match_operand:SI 2 "register_operand" "")
1273            (match_operand:SI 3 "nonmemory_operand" "")]))]
1274   ""
1276   enum nds32_expand_result_type result = nds32_expand_cstore (operands);
1277   switch (result)
1278     {
1279     case EXPAND_DONE:
1280       DONE;
1281       break;
1282     case EXPAND_FAIL:
1283       FAIL;
1284       break;
1285     case EXPAND_CREATE_TEMPLATE:
1286       break;
1287     default:
1288       gcc_unreachable ();
1289     }
1293 (define_expand "slts_compare"
1294   [(set (match_operand:SI 0 "register_operand"       "")
1295         (lt:SI (match_operand:SI 1 "general_operand" "")
1296                (match_operand:SI 2 "general_operand" "")))]
1297   ""
1299   if (!REG_P (operands[1]))
1300     operands[1] = force_reg (SImode, operands[1]);
1302   if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1303     operands[2] = force_reg (SImode, operands[2]);
1306 (define_insn "slts_compare_impl"
1307   [(set (match_operand:SI 0 "register_operand"             "=t,   t, r,    r")
1308         (lt:SI (match_operand:SI 1 "register_operand"      " d,   d, r,    r")
1309                (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
1310   ""
1311   "@
1312    slts45\t%1, %2
1313    sltsi45\t%1, %2
1314    slts\t%0, %1, %2
1315    sltsi\t%0, %1, %2"
1316   [(set_attr "type"   "alu,    alu,    alu,    alu")
1317    (set_attr "length" "  2,      2,      4,      4")])
1319 (define_insn "slt_eq0"
1320   [(set (match_operand:SI 0 "register_operand"        "=t, r")
1321         (eq:SI (match_operand:SI 1 "register_operand" " d, r")
1322                (const_int 0)))]
1323   ""
1324   "@
1325    slti45\t%1, 1
1326    slti\t%0, %1, 1"
1327   [(set_attr "type"   "alu, alu")
1328    (set_attr "length" "  2,   4")])
1330 (define_expand "slt_compare"
1331   [(set (match_operand:SI 0 "register_operand"        "")
1332         (ltu:SI (match_operand:SI 1 "general_operand" "")
1333                 (match_operand:SI 2 "general_operand" "")))]
1334   ""
1336   if (!REG_P (operands[1]))
1337     operands[1] = force_reg (SImode, operands[1]);
1339   if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1340     operands[2] = force_reg (SImode, operands[2]);
1343 (define_insn "slt_compare_impl"
1344   [(set (match_operand:SI 0 "register_operand"              "=t,    t, r,    r")
1345         (ltu:SI (match_operand:SI 1 "register_operand"      " d,    d, r,    r")
1346                 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
1347   ""
1348   "@
1349    slt45\t%1, %2
1350    slti45\t%1, %2
1351    slt\t%0, %1, %2
1352    slti\t%0, %1, %2"
1353   [(set_attr "type"   "alu,    alu,    alu,    alu")
1354    (set_attr "length" "  2,      2,      4,      4")])
1357 ;; ----------------------------------------------------------------------------
1359 ;; Unconditional and other jump instructions.
1361 (define_insn "jump"
1362   [(set (pc) (label_ref (match_operand 0 "" "")))]
1363   ""
1365   /* This unconditional jump has two forms:
1366        32-bit instruction => j   imm24s << 1
1367        16-bit instruction => j8  imm8s << 1
1369      For 32-bit case,
1370      we assume it is always reachable.
1371      For 16-bit case,
1372      it must satisfy { 255 >= (label - pc) >= -256 } condition.
1373      However, since the $pc for nds32 is at the beginning of the instruction,
1374      we should leave some length space for current insn.
1375      So we use range -250 ~ 250.  */
1376   switch (get_attr_length (insn))
1377     {
1378     case 2:
1379       return "j8\t%0";
1380     case 4:
1381       return "j\t%0";
1382     default:
1383       gcc_unreachable ();
1384     }
1386   [(set_attr "type" "branch")
1387    (set_attr "enabled" "yes")
1388    (set (attr "length")
1389         (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1390                       (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1391                                          (le (minus (match_dup 0) (pc)) (const_int  250)))
1392                                     (if_then_else (match_test "TARGET_16_BIT")
1393                                                   (const_int 2)
1394                                                   (const_int 4))
1395                                     (const_int 4))
1396                       (const_int 4)))])
1398 (define_insn "indirect_jump"
1399   [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1400   ""
1401   "@
1402    jr5\t%0
1403    jr\t%0"
1404   [(set_attr "type"   "branch,branch")
1405    (set_attr "length" "     2,     4")])
1407 ;; Subroutine call instruction returning no value.
1408 ;;   operands[0]: It should be a mem RTX whose address is
1409 ;;                the address of the function.
1410 ;;   operands[1]: It is the number of bytes of arguments pushed as a const_int.
1411 ;;   operands[2]: It is the number of registers used as operands.
1413 (define_expand "call"
1414   [(parallel [(call (match_operand 0 "memory_operand" "")
1415                     (match_operand 1))
1416               (clobber (reg:SI LP_REGNUM))
1417               (clobber (reg:SI TA_REGNUM))])]
1418   ""
1419   ""
1422 (define_insn "call_internal"
1423   [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
1424                     (match_operand 1))
1425               (clobber (reg:SI LP_REGNUM))
1426               (clobber (reg:SI TA_REGNUM))])]
1427   ""
1429   switch (which_alternative)
1430     {
1431     case 0:
1432       if (TARGET_16_BIT)
1433         return "jral5\t%0";
1434       else
1435         return "jral\t%0";
1436     case 1:
1437       return nds32_output_call (insn, operands, operands[0],
1438                                 "bal\t%0", "jal\t%0", false);
1439     default:
1440       gcc_unreachable ();
1441     }
1443   [(set_attr "enabled" "yes")
1444    (set_attr "type" "branch")
1445    (set_attr_alternative "length"
1446      [
1447        ;; Alternative 0
1448        (if_then_else (match_test "TARGET_16_BIT")
1449                      (const_int 2)
1450                      (const_int 4))
1451        ;; Alternative 1
1452        (if_then_else (match_test "nds32_long_call_p (operands[0])")
1453                      (const_int 12)
1454                      (const_int 4))
1455      ])]
1458 ;; Subroutine call instruction returning a value.
1459 ;;   operands[0]: It is the hard regiser in which the value is returned.
1460 ;;   The rest three operands are the same as the
1461 ;;   three operands of the 'call' instruction.
1462 ;;   (but with numbers increased by one)
1464 (define_expand "call_value"
1465   [(parallel [(set (match_operand 0)
1466                    (call (match_operand 1 "memory_operand" "")
1467                          (match_operand 2)))
1468               (clobber (reg:SI LP_REGNUM))
1469               (clobber (reg:SI TA_REGNUM))])]
1470   "")
1472 (define_insn "call_value_internal"
1473   [(parallel [(set (match_operand 0)
1474                    (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
1475                          (match_operand 2)))
1476               (clobber (reg:SI LP_REGNUM))
1477               (clobber (reg:SI TA_REGNUM))])]
1478   ""
1480   switch (which_alternative)
1481     {
1482     case 0:
1483       if (TARGET_16_BIT)
1484         return "jral5\t%1";
1485       else
1486         return "jral\t%1";
1487     case 1:
1488       return nds32_output_call (insn, operands, operands[1],
1489                                 "bal\t%1", "jal\t%1", false);
1490     default:
1491       gcc_unreachable ();
1492     }
1494   [(set_attr "enabled" "yes")
1495    (set_attr "type" "branch")
1496    (set_attr_alternative "length"
1497      [
1498        ;; Alternative 0
1499        (if_then_else (match_test "TARGET_16_BIT")
1500                      (const_int 2)
1501                      (const_int 4))
1502        ;; Alternative 1
1503        (if_then_else (match_test "nds32_long_call_p (operands[1])")
1504                      (const_int 12)
1505                      (const_int 4))
1506      ])]
1509 ;; Call subroutine returning any type.
1511 (define_expand "untyped_call"
1512   [(parallel [(call (match_operand 0 "" "")
1513                     (const_int 0))
1514               (match_operand 1 "" "")
1515               (match_operand 2 "" "")])]
1516   ""
1518   int i;
1520   emit_call_insn (gen_call (operands[0], const0_rtx));
1522   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1523     {
1524       rtx set = XVECEXP (operands[2], 0, i);
1525       emit_move_insn (SET_DEST (set), SET_SRC (set));
1526     }
1528   /* The optimizer does not know that the call sets the function value
1529      registers we stored in the result block.  We avoid problems by
1530      claiming that all hard registers are used and clobbered at this
1531      point.  */
1532   emit_insn (gen_blockage ());
1533   DONE;
1536 ;; ----------------------------------------------------------------------------
1538 ;; The sibcall patterns.
1540 ;; sibcall
1541 ;; sibcall_internal
1543 (define_expand "sibcall"
1544   [(parallel [(call (match_operand 0 "memory_operand" "")
1545                     (const_int 0))
1546               (clobber (reg:SI TA_REGNUM))
1547               (return)])]
1548   "")
1550 (define_insn "sibcall_internal"
1551   [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
1552                     (match_operand 1))
1553               (clobber (reg:SI TA_REGNUM))
1554               (return)])]
1555   ""
1557   switch (which_alternative)
1558     {
1559     case 0:
1560       if (TARGET_16_BIT)
1561         return "jr5\t%0";
1562       else
1563         return "jr\t%0";
1564     case 1:
1565       if (nds32_long_call_p (operands[0]))
1566         return "b\t%0";
1567       else
1568         return "j\t%0";
1569     default:
1570       gcc_unreachable ();
1571     }
1573   [(set_attr "enabled" "yes")
1574    (set_attr "type" "branch")
1575    (set_attr_alternative "length"
1576      [
1577        ;; Alternative 0
1578        (if_then_else (match_test "TARGET_16_BIT")
1579                      (const_int 2)
1580                      (const_int 4))
1581        ;; Alternative 1
1582        (if_then_else (match_test "nds32_long_call_p (operands[0])")
1583                      (const_int 12)
1584                      (const_int 4))
1585      ])]
1588 ;; sibcall_value
1589 ;; sibcall_value_internal
1590 ;; sibcall_value_immediate
1592 (define_expand "sibcall_value"
1593   [(parallel [(set (match_operand 0)
1594                    (call (match_operand 1 "memory_operand" "")
1595                          (const_int 0)))
1596               (clobber (reg:SI TA_REGNUM))
1597               (return)])]
1598   "")
1600 (define_insn "sibcall_value_internal"
1601   [(parallel [(set (match_operand 0)
1602                    (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
1603                          (match_operand 2)))
1604               (clobber (reg:SI TA_REGNUM))
1605               (return)])]
1606   ""
1608   switch (which_alternative)
1609     {
1610     case 0:
1611       if (TARGET_16_BIT)
1612         return "jr5\t%1";
1613       else
1614         return "jr\t%1";
1615     case 1:
1616       if (nds32_long_call_p (operands[1]))
1617         return "b\t%1";
1618       else
1619         return "j\t%1";
1620     default:
1621       gcc_unreachable ();
1622     }
1624   [(set_attr "enabled" "yes")
1625    (set_attr "type" "branch")
1626    (set_attr_alternative "length"
1627      [
1628        ;; Alternative 0
1629        (if_then_else (match_test "TARGET_16_BIT")
1630                      (const_int 2)
1631                      (const_int 4))
1632        ;; Alternative 1
1633        (if_then_else (match_test "nds32_long_call_p (operands[1])")
1634                      (const_int 12)
1635                      (const_int 4))
1636      ])]
1639 ;; ----------------------------------------------------------------------------
1641 ;; prologue and epilogue.
1643 (define_expand "prologue" [(const_int 0)]
1644   ""
1646   /* Note that only under V3/V3M ISA, we could use v3push prologue.
1647      In addition, we need to check if v3push is indeed available.  */
1648   if (NDS32_V3PUSH_AVAILABLE_P)
1649     nds32_expand_prologue_v3push ();
1650   else
1651     nds32_expand_prologue ();
1652   DONE;
1655 (define_expand "epilogue" [(const_int 0)]
1656   ""
1658   /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
1659      In addition, we need to check if v3push is indeed available.  */
1660   if (NDS32_V3PUSH_AVAILABLE_P)
1661     nds32_expand_epilogue_v3pop (false);
1662   else
1663     nds32_expand_epilogue (false);
1664   DONE;
1667 (define_expand "sibcall_epilogue" [(const_int 0)]
1668   ""
1670   /* Pass true to indicate that this is sibcall epilogue and
1671      exit from a function without the final branch back to the
1672      calling function.  */
1673   nds32_expand_epilogue (true);
1675   DONE;
1679 ;; nop instruction.
1681 (define_insn "nop"
1682   [(const_int 0)]
1683   ""
1685   if (TARGET_16_BIT)
1686     return "nop16";
1687   else
1688     return "nop";
1690   [(set_attr "type" "misc")
1691    (set_attr "enabled" "yes")
1692    (set (attr "length")
1693         (if_then_else (match_test "TARGET_16_BIT")
1694                       (const_int 2)
1695                       (const_int 4)))])
1698 ;; ----------------------------------------------------------------------------
1699 ;; Stack push/pop operations
1700 ;; ----------------------------------------------------------------------------
1702 ;; The pattern for stack push.
1703 ;; Both stack_push_multiple and stack_v3push use the following pattern.
1704 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1705 (define_insn "*stack_push"
1706   [(match_parallel 0 "nds32_stack_push_operation"
1707      [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1708                             (match_operand:SI 1 "const_int_operand" "")))
1709            (match_operand:SI 2 "register_operand" ""))
1710      ])]
1711   ""
1713   return nds32_output_stack_push (operands[0]);
1715   [(set_attr "type" "store_multiple")
1716    (set_attr "combo" "12")
1717    (set_attr "enabled" "yes")
1718    (set (attr "length")
1719         (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1720                       (const_int 2)
1721                       (const_int 4)))])
1724 ;; The pattern for stack pop.
1725 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1726 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1727 (define_insn "*stack_pop"
1728   [(match_parallel 0 "nds32_stack_pop_operation"
1729      [(set (match_operand:SI 1 "register_operand" "")
1730            (mem:SI (reg:SI SP_REGNUM)))
1731      ])]
1732   ""
1734   return nds32_output_stack_pop (operands[0]);
1736   [(set_attr "type" "load_multiple")
1737    (set_attr "combo" "12")
1738    (set_attr "enabled" "yes")
1739    (set (attr "length")
1740         (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1741                       (const_int 2)
1742                       (const_int 4)))])
1745 ;; ----------------------------------------------------------------------------
1746 ;; Return operation patterns
1747 ;; ----------------------------------------------------------------------------
1749 ;; Use this pattern to expand a return instruction
1750 ;; with simple_return rtx if no epilogue is required.
1751 (define_expand "return"
1752   [(parallel [(return)
1753               (clobber (reg:SI FP_REGNUM))])]
1754   "nds32_can_use_return_insn ()"
1756   /* Emit as the simple return.  */
1757   if (cfun->machine->naked_p
1758       && (cfun->machine->va_args_size == 0))
1759     {
1760       emit_jump_insn (gen_return_internal ());
1761       DONE;
1762     }
1765 ;; This pattern is expanded only by the shrink-wrapping optimization
1766 ;; on paths where the function prologue has not been executed.
1767 (define_expand "simple_return"
1768   [(simple_return)]
1769   ""
1770   ""
1773 (define_insn "*nds32_return"
1774   [(parallel [(return)
1775    (clobber (reg:SI FP_REGNUM))])]
1776   ""
1778   return nds32_output_return ();
1780   [(set_attr "type" "branch")
1781    (set_attr "enabled" "yes")
1782    (set_attr "length" "4")])
1784 (define_insn "return_internal"
1785   [(simple_return)]
1786   ""
1788   if (TARGET_16_BIT)
1789     return "ret5";
1790   else
1791     return "ret";
1793   [(set_attr "type" "branch")
1794    (set_attr "enabled" "yes")
1795    (set (attr "length")
1796         (if_then_else (match_test "TARGET_16_BIT")
1797                       (const_int 2)
1798                       (const_int 4)))])
1801 ;; ----------------------------------------------------------------------------
1802 ;; Jump Table patterns
1803 ;; ----------------------------------------------------------------------------
1804 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
1805 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
1807 ;; operands[0]: The index to dispatch on.
1808 ;; operands[1]: The lower bound for indices in the table.
1809 ;; operands[2]: The total range of indices int the table.
1810 ;;              i.e. The largest index minus the smallest one.
1811 ;; operands[3]: A label that precedes the table itself.
1812 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
1814 ;; We need to create following sequences for jump table code generation:
1815 ;;   A) k <-- (plus (operands[0]) (-operands[1]))
1816 ;;   B) if (gtu k operands[2]) then goto operands[4]
1817 ;;   C) t <-- operands[3]
1818 ;;   D) z <-- (mem (plus (k << 0 or 1 or 2) t))
1819 ;;   E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
1820 ;;   F) jump to target with register t or z
1822 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
1823 (define_expand "casesi"
1824   [(match_operand:SI 0 "register_operand"  "r") ; index to jump on
1825    (match_operand:SI 1 "immediate_operand" "i") ; lower bound
1826    (match_operand:SI 2 "immediate_operand" "i") ; total range
1827    (match_operand:SI 3 "" "")                   ; table label
1828    (match_operand:SI 4 "" "")]                  ; Out of range label
1829   ""
1831   rtx add_tmp;
1832   rtx reg, test;
1834   /* Step A: "k <-- (plus (operands[0]) (-operands[1]))".  */
1835   if (operands[1] != const0_rtx)
1836     {
1837       reg = gen_reg_rtx (SImode);
1838       add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
1840       /* If the integer value is not in the range of imm15s,
1841          we need to force register first because our addsi3 pattern
1842          only accept nds32_rimm15s_operand predicate.  */
1843       add_tmp = force_reg (SImode, add_tmp);
1845       emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
1846       operands[0] = reg;
1847     }
1849   /* Step B: "if (gtu k operands[2]) then goto operands[4]".  */
1850   test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
1851   emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
1852                                   operands[4]));
1854   /* Step C, D, E, and F, using another temporary register.  */
1855   rtx tmp = gen_reg_rtx (SImode);
1856   emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
1857   DONE;
1860 ;; We are receiving operands from casesi pattern:
1862 ;; operands[0]: The index that have been substracted with lower bound.
1863 ;; operands[1]: A label that precedes the table itself.
1864 ;; operands[2]: A temporary register to retrieve value in table.
1866 ;; We need to perform steps C, D, E, and F:
1868 ;;   C) t <-- operands[1]
1869 ;;   D) z <-- (mem (plus (operands[0] << m) t))
1870 ;;            m is 2 for normal jump table.
1871 ;;            m is 0, 1, or 2 for pc relative jump table based on diff size.
1872 ;;   E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
1873 ;;   F) Jump to target with register t or z.
1875 ;; The USE in this pattern is needed to tell flow analysis that this is
1876 ;; a CASESI insn.  It has no other purpose.
1877 (define_insn "casesi_internal"
1878   [(parallel [(set (pc)
1879                    (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1880                                              (const_int 4))
1881                                     (label_ref (match_operand 1 "" "")))))
1882               (use (label_ref (match_dup 1)))
1883               (clobber (match_operand:SI 2 "register_operand" "=r"))
1884               (clobber (reg:SI TA_REGNUM))])]
1885   ""
1887   if (CASE_VECTOR_PC_RELATIVE)
1888     return nds32_output_casesi_pc_relative (operands);
1889   else
1890     return nds32_output_casesi (operands);
1892   [(set_attr "length" "20")
1893    (set_attr "type" "branch")])
1895 ;; ----------------------------------------------------------------------------
1897 ;; Performance Extension
1899 (define_insn "clzsi2"
1900   [(set (match_operand:SI 0 "register_operand"         "=r")
1901         (clz:SI (match_operand:SI 1 "register_operand" " r")))]
1902   "TARGET_EXT_PERF"
1903   "clz\t%0, %1"
1904   [(set_attr "type" "alu")
1905    (set_attr "length" "4")])
1907 (define_insn "smaxsi3"
1908   [(set (match_operand:SI 0 "register_operand"          "=r")
1909         (smax:SI (match_operand:SI 1 "register_operand" " r")
1910                  (match_operand:SI 2 "register_operand" " r")))]
1911   "TARGET_EXT_PERF"
1912   "max\t%0, %1, %2"
1913   [(set_attr "type" "alu")
1914    (set_attr "length" "4")])
1916 (define_insn "sminsi3"
1917   [(set (match_operand:SI 0 "register_operand"          "=r")
1918         (smin:SI (match_operand:SI 1 "register_operand" " r")
1919                  (match_operand:SI 2 "register_operand" " r")))]
1920   "TARGET_EXT_PERF"
1921   "min\t%0, %1, %2"
1922   [(set_attr "type" "alu")
1923    (set_attr "length" "4")])
1925 (define_insn "btst"
1926   [(set (match_operand:SI 0 "register_operand"                     "=   r")
1927         (zero_extract:SI (match_operand:SI 1 "register_operand"    "    r")
1928                          (const_int 1)
1929                          (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")))]
1930   "TARGET_EXT_PERF"
1931   "btst\t%0, %1, %2"
1932   [(set_attr "type" "alu")
1933    (set_attr "length" "4")])
1935 (define_insn "ave"
1936   [(set (match_operand:SI 0 "register_operand" "=r")
1937         (truncate:SI
1938           (ashiftrt:DI
1939             (plus:DI
1940               (plus:DI
1941                 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1942                 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
1943               (const_int 1))
1944           (const_int 1))))]
1945   "TARGET_EXT_PERF"
1946   "ave\t%0, %1, %2"
1947   [(set_attr "type" "alu")
1948    (set_attr "length" "4")])
1950 ;; ----------------------------------------------------------------------------
1952 ;; Pseudo NOPs
1954 (define_insn "relax_group"
1955   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
1956   ""
1957   ".relax_hint %0"
1958   [(set_attr "length" "0")]
1961 (define_insn "pop25return"
1962   [(return)
1963    (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
1964   ""
1965   "! return for pop 25"
1966   [(set_attr "length" "0")]
1969 ;; ----------------------------------------------------------------------------