nds32: Fix casesi (PR70668)
[official-gcc.git] / gcc / config / nds32 / nds32.md
blob494a78d91e58fba231698ab72732e3cf50f2f186
1 ;; Machine description of Andes NDS32 cpu for GNU compiler
2 ;; Copyright (C) 2012-2016 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 peephole patterns.
50 (include "nds32-peephole2.md")
53 ;; Insn type, it is used to default other attribute values.
54 (define_attr "type"
55   "unknown,move,load,store,alu,compare,branch,call,misc"
56   (const_string "unknown"))
59 ;; Length, in bytes, default is 4-bytes.
60 (define_attr "length" "" (const_int 4))
63 ;; Enabled, which is used to enable/disable insn alternatives.
64 ;; Note that we use length and TARGET_16_BIT here as criteria.
65 ;; If the instruction pattern already check TARGET_16_BIT to
66 ;; determine the length by itself, its enabled attribute should be
67 ;; always 1 to avoid the conflict with the settings here.
68 (define_attr "enabled" ""
69   (cond [(and (eq_attr "length" "2")
70               (match_test "!TARGET_16_BIT"))
71          (const_int 0)]
72         (const_int 1)))
75 ;; ----------------------------------------------------------------------------
78 ;; Move instructions.
80 ;; For QImode and HImode, the immediate value can be fit in imm20s.
81 ;; So there is no need to split rtx for QI and HI patterns.
83 (define_expand "movqi"
84   [(set (match_operand:QI 0 "general_operand" "")
85         (match_operand:QI 1 "general_operand" ""))]
86   ""
88   /* Need to force register if mem <- !reg.  */
89   if (MEM_P (operands[0]) && !REG_P (operands[1]))
90     operands[1] = force_reg (QImode, operands[1]);
93 (define_expand "movhi"
94   [(set (match_operand:HI 0 "general_operand" "")
95         (match_operand:HI 1 "general_operand" ""))]
96   ""
98   /* Need to force register if mem <- !reg.  */
99   if (MEM_P (operands[0]) && !REG_P (operands[1]))
100     operands[1] = force_reg (HImode, operands[1]);
103 (define_expand "movsi"
104   [(set (match_operand:SI 0 "general_operand" "")
105         (match_operand:SI 1 "general_operand" ""))]
106   ""
108   /* Need to force register if mem <- !reg.  */
109   if (MEM_P (operands[0]) && !REG_P (operands[1]))
110     operands[1] = force_reg (SImode, operands[1]);
112   /* If operands[1] is a large constant and cannot be performed
113      by a single instruction, we need to split it.  */
114   if (CONST_INT_P (operands[1])
115       && !satisfies_constraint_Is20 (operands[1])
116       && !satisfies_constraint_Ihig (operands[1]))
117     {
118       rtx high20_rtx;
119       HOST_WIDE_INT low12_int;
120       rtx tmp_rtx;
122       tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
124       high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
125       low12_int = INTVAL (operands[1]) & 0xfff;
127       emit_move_insn (tmp_rtx, high20_rtx);
128       emit_move_insn (operands[0], plus_constant (SImode,
129                                                   tmp_rtx,
130                                                   low12_int));
131       DONE;
132     }
135 (define_insn "*mov<mode>"
136   [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r, U45, U33, U37, U45, m,   l,   l,   l,   d, r,    d,    r,    r,    r")
137         (match_operand:QIHISI 1 "nds32_move_operand"   " r, r,   l,   l,   l,   d, r, U45, U33, U37, U45, m, Ip05, Is05, Is20, Ihig"))]
138   ""
140   switch (which_alternative)
141     {
142     case 0:
143       return "mov55\t%0, %1";
144     case 1:
145       return "ori\t%0, %1, 0";
146     case 2:
147     case 3:
148     case 4:
149     case 5:
150       return nds32_output_16bit_store (operands, <byte>);
151     case 6:
152       return nds32_output_32bit_store (operands, <byte>);
153     case 7:
154     case 8:
155     case 9:
156     case 10:
157       return nds32_output_16bit_load (operands, <byte>);
158     case 11:
159       return nds32_output_32bit_load (operands, <byte>);
160     case 12:
161       return "movpi45\t%0, %1";
162     case 13:
163       return "movi55\t%0, %1";
164     case 14:
165       return "movi\t%0, %1";
166     case 15:
167       return "sethi\t%0, hi20(%1)";
168     default:
169       gcc_unreachable ();
170     }
172   [(set_attr "type"   "alu,alu,store,store,store,store,store,load,load,load,load,load,alu,alu,alu,alu")
173    (set_attr "length" "  2,  4,    2,    2,    2,    2,    4,   2,   2,   2,   2,   4,  2,  2,  4,  4")])
176 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
177 ;; are able to match such instruction template.
178 (define_insn "*move_addr"
179   [(set (match_operand:SI 0 "register_operand"       "=l, r")
180         (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
181   ""
182   "la\t%0, %1"
183   [(set_attr "type" "move")
184    (set_attr "length"  "8")])
187 (define_insn "*sethi"
188   [(set (match_operand:SI 0 "register_operand"                "=r")
189         (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
190   ""
191   "sethi\t%0, hi20(%1)"
192   [(set_attr "type" "alu")
193    (set_attr "length" "4")])
196 (define_insn "*lo_sum"
197   [(set (match_operand:SI 0 "register_operand"                  "=r")
198         (lo_sum:SI (match_operand:SI 1 "register_operand"       " r")
199                    (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
200   ""
201   "ori\t%0, %1, lo12(%2)"
202   [(set_attr "type" "alu")
203    (set_attr "length" "4")])
206 ;; ----------------------------------------------------------------------------
208 ;; Zero extension instructions.
210 (define_insn "zero_extend<mode>si2"
211   [(set (match_operand:SI 0 "register_operand"                       "=l, r,   l, *r")
212         (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33,  m")))]
213   ""
215   switch (which_alternative)
216     {
217     case 0:
218       return "ze<size>33\t%0, %1";
219     case 1:
220       return "ze<size>\t%0, %1";
221     case 2:
222       return nds32_output_16bit_load (operands, <byte>);
223     case 3:
224       return nds32_output_32bit_load (operands, <byte>);
226     default:
227       gcc_unreachable ();
228     }
230   [(set_attr "type"   "alu,alu,load,load")
231    (set_attr "length" "  2,  4,   2,   4")])
234 ;; Sign extension instructions.
236 (define_insn "extend<mode>si2"
237   [(set (match_operand:SI 0 "register_operand"                       "=l, r, r")
238         (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
239   ""
241   switch (which_alternative)
242     {
243     case 0:
244       return "se<size>33\t%0, %1";
245     case 1:
246       return "se<size>\t%0, %1";
247     case 2:
248       return nds32_output_32bit_load_s (operands, <byte>);
250     default:
251       gcc_unreachable ();
252     }
254   [(set_attr "type"   "alu,alu,load")
255    (set_attr "length" "  2,  4,   4")])
258 ;; ----------------------------------------------------------------------------
260 ;; Arithmetic instructions.
262 (define_insn "add<mode>3"
263   [(set (match_operand:QIHISI 0 "register_operand"                   "=   d,    l,    d,    l,  d, l,    k,    l,    r, r")
264         (plus:QIHISI (match_operand:QIHISI 1 "register_operand"      "%   0,    l,    0,    l,  0, l,    0,    k,    r, r")
265                      (match_operand:QIHISI 2 "nds32_rimm15s_operand" " In05, In03, Iu05, Iu03,  r, l, Is10, Iu06, Is15, r")))]
266   ""
268   switch (which_alternative)
269     {
270     case 0:
271       /* addi Rt4,Rt4,-x  ==>  subi45 Rt4,x
272          where 0 <= x <= 31 */
273       operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
274       return "subi45\t%0, %2";
275     case 1:
276       /* addi Rt3,Ra3,-x  ==>  subi333 Rt3,Ra3,x
277          where 0 <= x <= 7 */
278       operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
279       return "subi333\t%0, %1, %2";
280     case 2:
281       return "addi45\t%0, %2";
282     case 3:
283       return "addi333\t%0, %1, %2";
284     case 4:
285       return "add45\t%0, %2";
286     case 5:
287       return "add333\t%0, %1, %2";
288     case 6:
289       return "addi10.sp\t%2";
290     case 7:
291       return "addri36.sp\t%0, %2";
292     case 8:
293       return "addi\t%0, %1, %2";
294     case 9:
295       return "add\t%0, %1, %2";
297     default:
298       gcc_unreachable ();
299     }
301   [(set_attr "type"   "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
302    (set_attr "length" "  2,  2,  2,  2,  2,  2,  2,  2,  4,  4")])
304 (define_insn "sub<mode>3"
305   [(set (match_operand:QIHISI 0 "register_operand"                    "=d, l,    r, r")
306         (minus:QIHISI (match_operand:QIHISI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
307                       (match_operand:QIHISI 2 "register_operand"      " r, l,    r, r")))]
308   ""
309   "@
310   sub45\t%0, %2
311   sub333\t%0, %1, %2
312   subri\t%0, %2, %1
313   sub\t%0, %1, %2"
314   [(set_attr "type"   "alu,alu,alu,alu")
315    (set_attr "length" "  2,  2,  4,  4")])
318 ;; GCC intends to simplify (plus (ashift ...) (reg))
319 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
320 ;; and needs to ensure it is exact_log2 value.
321 (define_insn "*add_slli"
322   [(set (match_operand:SI 0 "register_operand"                    "=r")
323         (plus:SI (mult:SI (match_operand:SI 1 "register_operand"  " r")
324                           (match_operand:SI 2 "immediate_operand" " i"))
325                  (match_operand:SI 3 "register_operand"           " r")))]
326   "TARGET_ISA_V3
327    && (exact_log2 (INTVAL (operands[2])) != -1)
328    && (exact_log2 (INTVAL (operands[2])) <= 31)"
330   /* Get floor_log2 of the immediate value
331      so that we can generate 'add_slli' instruction.  */
332   operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
334   return "add_slli\t%0, %3, %1, %2";
336   [(set_attr "type" "alu")
337    (set_attr "length" "4")])
339 (define_insn "*add_srli"
340   [(set (match_operand:SI 0 "register_operand"                        "=   r")
341         (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"  "    r")
342                               (match_operand:SI 2 "immediate_operand" " Iu05"))
343                  (match_operand:SI 3 "register_operand"               "    r")))]
344   "TARGET_ISA_V3"
345   "add_srli\t%0, %3, %1, %2"
346   [(set_attr "type" "alu")
347    (set_attr "length" "4")])
350 ;; GCC intends to simplify (minus (reg) (ashift ...))
351 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
352 ;; and needs to ensure it is exact_log2 value.
353 (define_insn "*sub_slli"
354   [(set (match_operand:SI 0 "register_operand"                     "=r")
355         (minus:SI (match_operand:SI 1 "register_operand"           " r")
356                   (mult:SI (match_operand:SI 2 "register_operand"  " r")
357                            (match_operand:SI 3 "immediate_operand" " i"))))]
358   "TARGET_ISA_V3
359    && (exact_log2 (INTVAL (operands[3])) != -1)
360    && (exact_log2 (INTVAL (operands[3])) <= 31)"
362   /* Get floor_log2 of the immediate value
363      so that we can generate 'sub_slli' instruction.  */
364   operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
366   return "sub_slli\t%0, %1, %2, %3";
368   [(set_attr "type" "alu")
369    (set_attr "length" "4")])
371 (define_insn "*sub_srli"
372   [(set (match_operand:SI 0 "register_operand"                         "=   r")
373         (minus:SI (match_operand:SI 1 "register_operand"               "    r")
374                   (lshiftrt:SI (match_operand:SI 2 "register_operand"  "    r")
375                                (match_operand:SI 3 "immediate_operand" " Iu05"))))]
376   "TARGET_ISA_V3"
377   "sub_srli\t%0, %1, %2, %3"
378   [(set_attr "type" "alu")
379    (set_attr "length" "4")])
382 ;; Multiplication instructions.
384 (define_insn "mulsi3"
385   [(set (match_operand:SI 0 "register_operand"          "=w, r")
386         (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
387                  (match_operand:SI 2 "register_operand" " w, r")))]
388   ""
389   "@
390   mul33\t%0, %2
391   mul\t%0, %1, %2"
392   [(set_attr "type"   "alu,alu")
393    (set_attr "length" "  2,  4")])
395 (define_insn "mulsidi3"
396   [(set (match_operand:DI 0 "register_operand"                          "=r")
397         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
398                  (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
399   "TARGET_ISA_V2 || TARGET_ISA_V3"
400   "mulsr64\t%0, %1, %2"
401   [(set_attr "type"   "alu")
402    (set_attr "length"   "4")])
404 (define_insn "umulsidi3"
405   [(set (match_operand:DI 0 "register_operand"                          "=r")
406         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
407                  (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
408   "TARGET_ISA_V2 || TARGET_ISA_V3"
409   "mulr64\t%0, %1, %2"
410   [(set_attr "type"   "alu")
411    (set_attr "length"   "4")])
414 ;; Multiply-accumulate instructions.
416 (define_insn "*maddr32_0"
417   [(set (match_operand:SI 0 "register_operand"                   "=r")
418         (plus:SI (match_operand:SI 3 "register_operand"          " 0")
419                  (mult:SI (match_operand:SI 1 "register_operand" " r")
420                           (match_operand:SI 2 "register_operand" " r"))))]
421   ""
422   "maddr32\t%0, %1, %2"
423   [(set_attr "type"   "alu")
424    (set_attr "length"   "4")])
426 (define_insn "*maddr32_1"
427   [(set (match_operand:SI 0 "register_operand"                   "=r")
428         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
429                           (match_operand:SI 2 "register_operand" " r"))
430                  (match_operand:SI 3 "register_operand"          " 0")))]
431   ""
432   "maddr32\t%0, %1, %2"
433   [(set_attr "type"   "alu")
434    (set_attr "length"   "4")])
436 (define_insn "*msubr32"
437   [(set (match_operand:SI 0 "register_operand"                    "=r")
438         (minus:SI (match_operand:SI 3 "register_operand"          " 0")
439                   (mult:SI (match_operand:SI 1 "register_operand" " r")
440                            (match_operand:SI 2 "register_operand" " r"))))]
441   ""
442   "msubr32\t%0, %1, %2"
443   [(set_attr "type"   "alu")
444    (set_attr "length"   "4")])
447 ;; Div Instructions.
449 (define_insn "divmodsi4"
450   [(set (match_operand:SI 0 "register_operand"         "=r")
451         (div:SI (match_operand:SI 1 "register_operand" " r")
452                 (match_operand:SI 2 "register_operand" " r")))
453    (set (match_operand:SI 3 "register_operand"         "=r")
454         (mod:SI (match_dup 1) (match_dup 2)))]
455   ""
456   "divsr\t%0, %3, %1, %2"
457   [(set_attr "type"   "alu")
458    (set_attr "length"   "4")])
460 (define_insn "udivmodsi4"
461   [(set (match_operand:SI 0 "register_operand"          "=r")
462         (udiv:SI (match_operand:SI 1 "register_operand" " r")
463                 (match_operand:SI 2 "register_operand"  " r")))
464    (set (match_operand:SI 3 "register_operand"          "=r")
465         (umod:SI (match_dup 1) (match_dup 2)))]
466   ""
467   "divr\t%0, %3, %1, %2"
468   [(set_attr "type"   "alu")
469    (set_attr "length"   "4")])
472 ;; ----------------------------------------------------------------------------
474 ;; Boolean instructions.
475 ;; Note: We define the DImode versions in nds32-doubleword.md.
477 ;; ----------------------------------------------------------------------------
478 ;; 'AND' operation
479 ;; ----------------------------------------------------------------------------
481 (define_insn "bitc"
482   [(set (match_operand:SI 0 "register_operand"                 "=r")
483         (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
484                 (match_operand:SI 2 "register_operand"         " r")))]
485   "TARGET_ISA_V3"
486   "bitc\t%0, %2, %1"
487   [(set_attr "type" "alu")
488    (set_attr "length" "4")]
491 (define_insn "andsi3"
492   [(set (match_operand:SI 0 "register_operand"         "=w, r,    l,    l,    l,    l,    l,    l,    r,   r,     r,    r,    r")
493         (and:SI (match_operand:SI 1 "register_operand" "%0, r,    l,    l,    l,    l,    0,    0,    r,   r,     r,    r,    r")
494                 (match_operand:SI 2 "general_operand"  " w, r, Izeb, Izeh, Ixls, Ix11, Ibms, Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
495   ""
497   HOST_WIDE_INT mask = INTVAL (operands[2]);
498   int zero_position;
500   /* 16-bit andi instructions:
501      andi Rt3,Ra3,0xff   -> zeb33  Rt3,Ra3
502      andi Rt3,Ra3,0xffff -> zeh33  Rt3,Ra3
503      andi Rt3,Ra3,0x01   -> xlsb33 Rt3,Ra3
504      andi Rt3,Ra3,0x7ff  -> x11b33 Rt3,Ra3
505      andi Rt3,Rt3,2^imm3u          -> bmski33 Rt3,imm3u
506      andi Rt3,Rt3,(2^(imm3u+1))-1  -> fexti33 Rt3,imm3u.  */
508   switch (which_alternative)
509     {
510     case 0:
511       return "and33\t%0, %2";
512     case 1:
513       return "and\t%0, %1, %2";
514     case 2:
515       return "zeb33\t%0, %1";
516     case 3:
517       return "zeh33\t%0, %1";
518     case 4:
519       return "xlsb33\t%0, %1";
520     case 5:
521       return "x11b33\t%0, %1";
522     case 6:
523       operands[2] = GEN_INT (floor_log2 (mask));
524       return "bmski33\t%0, %2";
525     case 7:
526       operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
527       return "fexti33\t%0, %2";
528     case 8:
529       return "zeb\t%0, %1";
530     case 9:
531       return "zeh\t%0, %1";
532     case 10:
533       return "andi\t%0, %1, %2";
534     case 11:
535       operands[2] = GEN_INT (~mask);
536       return "bitci\t%0, %1, %2";
537     case 12:
538       /* If we reach this alternative,
539          it must pass the nds32_can_use_bclr_p() test,
540          so that we can guarantee there is only one 0-bit
541          within the immediate value.  */
542       for (zero_position = 31; zero_position >= 0; zero_position--)
543         {
544           if ((INTVAL (operands[2]) & (1 << zero_position)) == 0)
545             {
546               /* Found the 0-bit position.  */
547               operands[2] = GEN_INT (zero_position);
548               break;
549             }
550         }
551       return "bclr\t%0, %1, %2";
553     default:
554       gcc_unreachable ();
555     }
557   [(set_attr "type"   "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
558    (set_attr "length" "  2,  4,  2,  2,  2,  2,  2,  2,  4,  4,  4,  4,  4")])
560 (define_insn "*and_slli"
561   [(set (match_operand:SI 0 "register_operand"                      "=   r")
562         (and:SI (ashift:SI (match_operand:SI 1 "register_operand"   "    r")
563                             (match_operand:SI 2 "immediate_operand" " Iu05"))
564                 (match_operand:SI 3 "register_operand"              "    r")))]
565   "TARGET_ISA_V3"
566   "and_slli\t%0, %3, %1, %2"
567   [(set_attr "type" "alu")
568    (set_attr "length" "4")])
570 (define_insn "*and_srli"
571   [(set (match_operand:SI 0 "register_operand"                       "=   r")
572         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"  "    r")
573                              (match_operand:SI 2 "immediate_operand" " Iu05"))
574                 (match_operand:SI 3 "register_operand"               "    r")))]
575   "TARGET_ISA_V3"
576   "and_srli\t%0, %3, %1, %2"
577   [(set_attr "type" "alu")
578    (set_attr "length" "4")])
581 ;; ----------------------------------------------------------------------------
582 ;; 'OR' operation
583 ;; ----------------------------------------------------------------------------
585 ;; For V3/V3M ISA, we have 'or33' instruction.
586 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
587 (define_insn "iorsi3"
588   [(set (match_operand:SI 0 "register_operand"         "=w, r,    r,    r")
589         (ior:SI (match_operand:SI 1 "register_operand" "%0, r,    r,    r")
590                 (match_operand:SI 2 "general_operand"  " w, r, Iu15, Ie15")))]
591   ""
593   int one_position;
595   switch (which_alternative)
596     {
597     case 0:
598       return "or33\t%0, %2";
599     case 1:
600       return "or\t%0, %1, %2";
601     case 2:
602       return "ori\t%0, %1, %2";
603     case 3:
604       /* If we reach this alternative,
605          it must pass the nds32_can_use_bset_p() test,
606          so that we can guarantee there is only one 1-bit
607          within the immediate value.  */
608       /* Use exact_log2() to search the 1-bit position.  */
609       one_position = exact_log2 (INTVAL (operands[2]));
610       operands[2] = GEN_INT (one_position);
611       return "bset\t%0, %1, %2";
613     default:
614       gcc_unreachable ();
615     }
617   [(set_attr "type"   "alu,alu,alu,alu")
618    (set_attr "length" "  2,  4,  4,  4")])
620 (define_insn "*or_slli"
621   [(set (match_operand:SI 0 "register_operand"                     "=   r")
622         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand"  "    r")
623                            (match_operand:SI 2 "immediate_operand" " Iu05"))
624                 (match_operand:SI 3 "register_operand"             "    r")))]
625   "TARGET_ISA_V3"
626   "or_slli\t%0, %3, %1, %2"
627   [(set_attr "type" "alu")
628    (set_attr "length" "4")])
630 (define_insn "*or_srli"
631   [(set (match_operand:SI 0 "register_operand"                       "=   r")
632         (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"  "    r")
633                              (match_operand:SI 2 "immediate_operand" " Iu05"))
634                 (match_operand:SI 3 "register_operand"               "    r")))]
635   "TARGET_ISA_V3"
636   "or_srli\t%0, %3, %1, %2"
637   [(set_attr "type" "alu")
638    (set_attr "length" "4")])
641 ;; ----------------------------------------------------------------------------
642 ;; 'XOR' operation
643 ;; ----------------------------------------------------------------------------
645 ;; For V3/V3M ISA, we have 'xor33' instruction.
646 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
647 (define_insn "xorsi3"
648   [(set (match_operand:SI 0 "register_operand"         "=w, r,    r,    r")
649         (xor:SI (match_operand:SI 1 "register_operand" "%0, r,    r,    r")
650                 (match_operand:SI 2 "general_operand"  " w, r, Iu15, It15")))]
651   ""
653   int one_position;
655   switch (which_alternative)
656     {
657     case 0:
658       return "xor33\t%0, %2";
659     case 1:
660       return "xor\t%0, %1, %2";
661     case 2:
662       return "xori\t%0, %1, %2";
663     case 3:
664       /* If we reach this alternative,
665          it must pass the nds32_can_use_btgl_p() test,
666          so that we can guarantee there is only one 1-bit
667          within the immediate value.  */
668       /* Use exact_log2() to search the 1-bit position.  */
669       one_position = exact_log2 (INTVAL (operands[2]));
670       operands[2] = GEN_INT (one_position);
671       return "btgl\t%0, %1, %2";
673     default:
674       gcc_unreachable ();
675     }
677   [(set_attr "type"   "alu,alu,alu,alu")
678    (set_attr "length" "  2,  4,  4,  4")])
680 (define_insn "*xor_slli"
681   [(set (match_operand:SI 0 "register_operand"                     "=   r")
682         (xor:SI (ashift:SI (match_operand:SI 1 "register_operand"  "    r")
683                            (match_operand:SI 2 "immediate_operand" " Iu05"))
684                 (match_operand:SI 3 "register_operand"             "    r")))]
685   "TARGET_ISA_V3"
686   "xor_slli\t%0, %3, %1, %2"
687   [(set_attr "type" "alu")
688    (set_attr "length" "4")])
690 (define_insn "*xor_srli"
691   [(set (match_operand:SI 0 "register_operand"                       "=   r")
692         (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"  "    r")
693                              (match_operand:SI 2 "immediate_operand" " Iu05"))
694                 (match_operand:SI 3 "register_operand"               "    r")))]
695   "TARGET_ISA_V3"
696   "xor_srli\t%0, %3, %1, %2"
697   [(set_attr "type" "alu")
698    (set_attr "length" "4")])
700 ;; Rotate Right Instructions.
702 (define_insn "rotrsi3"
703   [(set (match_operand:SI 0 "register_operand"                 "=   r, r")
704           (rotatert:SI (match_operand:SI 1 "register_operand"  "    r, r")
705                        (match_operand:SI 2 "nonmemory_operand" " Iu05, r")))]
706   ""
707   "@
708   rotri\t%0, %1, %2
709   rotr\t%0, %1, %2"
710   [(set_attr "type"   "alu,alu")
711    (set_attr "length" "  4,  4")])
714 ;; ----------------------------------------------------------------------------
715 ;; 'NEG' operation
716 ;; ----------------------------------------------------------------------------
718 ;; For V3/V3M ISA, we have 'neg33' instruction.
719 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
720 ;; And for V2 ISA, there is NO 'neg33' instruction.
721 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
722 (define_insn "negsi2"
723   [(set (match_operand:SI 0 "register_operand"         "=w, r")
724         (neg:SI (match_operand:SI 1 "register_operand" " w, r")))]
725   ""
726   "@
727    neg33\t%0, %1
728    subri\t%0, %1, 0"
729   [(set_attr "type"   "alu,alu")
730    (set_attr "length" "  2,  4")])
733 ;; ----------------------------------------------------------------------------
734 ;; 'ONE_COMPLIMENT' operation
735 ;; ----------------------------------------------------------------------------
737 ;; For V3/V3M ISA, we have 'not33' instruction.
738 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
739 (define_insn "one_cmplsi2"
740   [(set (match_operand:SI 0 "register_operand"         "=w, r")
741         (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
742   ""
743   "@
744    not33\t%0, %1
745    nor\t%0, %1, %1"
746   [(set_attr "type"   "alu,alu")
747    (set_attr "length" "  2,  4")])
750 ;; ----------------------------------------------------------------------------
752 ;; Shift instructions.
754 (define_insn "ashlsi3"
755   [(set (match_operand:SI 0 "register_operand"             "=   l,    r, r")
756         (ashift:SI (match_operand:SI 1 "register_operand"  "    l,    r, r")
757                    (match_operand:SI 2 "nonmemory_operand" " Iu03, Iu05, r")))]
758   ""
759   "@
760   slli333\t%0, %1, %2
761   slli\t%0, %1, %2
762   sll\t%0, %1, %2"
763   [(set_attr "type"   "alu,alu,alu")
764    (set_attr "length" "  2,  4,  4")])
766 (define_insn "ashrsi3"
767   [(set (match_operand:SI 0 "register_operand"               "=   d,    r, r")
768         (ashiftrt:SI (match_operand:SI 1 "register_operand"  "    0,    r, r")
769                      (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))]
770   ""
771   "@
772   srai45\t%0, %2
773   srai\t%0, %1, %2
774   sra\t%0, %1, %2"
775   [(set_attr "type"   "alu,alu,alu")
776    (set_attr "length" "  2,  4,  4")])
778 (define_insn "lshrsi3"
779   [(set (match_operand:SI 0 "register_operand"               "=   d,    r, r")
780         (lshiftrt:SI (match_operand:SI 1 "register_operand"  "    0,    r, r")
781                      (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))]
782   ""
783   "@
784   srli45\t%0, %2
785   srli\t%0, %1, %2
786   srl\t%0, %1, %2"
787   [(set_attr "type"   "alu,alu,alu")
788    (set_attr "length" "  2,  4,  4")])
791 ;; ----------------------------------------------------------------------------
793 ;; ----------------------------------------------------------------------------
794 ;; Conditional Move patterns
795 ;; ----------------------------------------------------------------------------
797 (define_expand "movsicc"
798   [(set (match_operand:SI 0 "register_operand" "")
799         (if_then_else:SI (match_operand 1 "comparison_operator" "")
800                          (match_operand:SI 2 "register_operand" "")
801                          (match_operand:SI 3 "register_operand" "")))]
802   "TARGET_CMOV"
804   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
805       && GET_MODE (XEXP (operands[1], 0)) == SImode
806       && XEXP (operands[1], 1) == const0_rtx)
807     {
808       /* If the operands[1] rtx is already (eq X 0) or (ne X 0),
809          we have gcc generate original template rtx.  */
810       goto create_template;
811     }
812   else
813     {
814       /* Since there is only 'slt'(Set when Less Than) instruction for
815          comparison in Andes ISA, the major strategy we use here is to
816          convert conditional move into 'LT + EQ' or 'LT + NE' rtx combination.
817          We design constraints properly so that the reload phase will assist
818          to make one source operand to use same register as result operand.
819          Then we can use cmovz/cmovn to catch the other source operand
820          which has different register.  */
821       enum rtx_code code = GET_CODE (operands[1]);
822       enum rtx_code new_code = code;
823       rtx cmp_op0 = XEXP (operands[1], 0);
824       rtx cmp_op1 = XEXP (operands[1], 1);
825       rtx tmp;
826       int reverse = 0;
828       /* Main Goal: Use 'LT + EQ' or 'LT + NE' to target "then" part
829          Strategy : Reverse condition and swap comparison operands
831          For example:
833              a <= b ? P : Q   (LE or LEU)
834          --> a >  b ? Q : P   (reverse condition)
835          --> b <  a ? Q : P   (swap comparison operands to achieve 'LT/LTU')
837              a >= b ? P : Q   (GE or GEU)
838          --> a <  b ? Q : P   (reverse condition to achieve 'LT/LTU')
840              a <  b ? P : Q   (LT or LTU)
841          --> (NO NEED TO CHANGE, it is already 'LT/LTU')
843              a >  b ? P : Q   (GT or GTU)
844          --> b <  a ? P : Q   (swap comparison operands to achieve 'LT/LTU') */
845       switch (code)
846         {
847         case NE:
848           /*   (a != b ? P : Q)
849              can be expressed as
850                (a == b ? Q : P)
851              so, fall through to reverse condition */
852         case GE: case GEU: case LE: case LEU:
853           new_code = reverse_condition (code);
854           reverse = 1;
855           break;
856         case EQ: case GT: case GTU: case LT: case LTU:
857           /* no need to reverse condition */
858           break;
859         default:
860           FAIL;
861         }
863       /* For '>' comparison operator, we swap operands
864          so that we can have 'LT/LTU' operator.  */
865       if (new_code == GT || new_code == GTU)
866         {
867           tmp     = cmp_op0;
868           cmp_op0 = cmp_op1;
869           cmp_op1 = tmp;
871           new_code = swap_condition (new_code);
872         }
874       /* Use a temporary register to store slt/slts result.  */
875       tmp = gen_reg_rtx (SImode);
877       /* Split EQ and NE because we don't have direct comparison of EQ and NE.
878          If we don't split it, the conditional move transformation will fail
879          when producing (SET A (EQ B C)) or (SET A (NE B C)).  */
880       if (new_code == EQ)
881         {
882           emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1));
883           emit_insn (gen_slt_compare (tmp, tmp, GEN_INT (1)));
884         }
885       else if (new_code == NE)
886         {
887           emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1));
888           emit_insn (gen_slt_compare (tmp, GEN_INT (0), tmp));
889         }
890       else
891         /* This emit_insn will create corresponding 'slt/slts' insturction.  */
892         emit_insn (gen_rtx_SET (tmp, gen_rtx_fmt_ee (new_code, SImode,
893                                                      cmp_op0, cmp_op1)));
895       /* Change comparison semantic into (eq X 0) or (ne X 0) behavior
896          so that cmovz or cmovn will be matched later.
898          For reverse condition cases, we want to create a semantic that:
899            (eq X 0) --> pick up "else" part
900          For normal cases, we want to create a semantic that:
901            (ne X 0) --> pick up "then" part
903          Later we will have cmovz/cmovn instruction pattern to
904          match corresponding behavior and output instruction.  */
905       operands[1] = gen_rtx_fmt_ee (reverse ? EQ : NE,
906                                     VOIDmode, tmp, const0_rtx);
907     }
909 create_template:
910   do {} while(0); /* dummy line */
913 (define_insn "cmovz"
914   [(set (match_operand:SI 0 "register_operand"                      "=r, r")
915         (if_then_else:SI (eq (match_operand:SI 1 "register_operand" " r, r")
916                              (const_int 0))
917                          (match_operand:SI 2 "register_operand"     " r, 0")
918                          (match_operand:SI 3 "register_operand"     " 0, r")))]
919   "TARGET_CMOV"
920   "@
921    cmovz\t%0, %2, %1
922    cmovn\t%0, %3, %1"
923   [(set_attr "type" "move")
924    (set_attr "length"  "4")])
926 (define_insn "cmovn"
927   [(set (match_operand:SI 0 "register_operand"                      "=r, r")
928         (if_then_else:SI (ne (match_operand:SI 1 "register_operand" " r, r")
929                              (const_int 0))
930                          (match_operand:SI 2 "register_operand"     " r, 0")
931                          (match_operand:SI 3 "register_operand"     " 0, r")))]
932   "TARGET_CMOV"
933   "@
934    cmovn\t%0, %2, %1
935    cmovz\t%0, %3, %1"
936   [(set_attr "type" "move")
937    (set_attr "length"  "4")])
940 ;; ----------------------------------------------------------------------------
941 ;; Conditional Branch patterns
942 ;; ----------------------------------------------------------------------------
944 (define_expand "cbranchsi4"
945   [(set (pc)
946         (if_then_else (match_operator 0 "comparison_operator"
947                         [(match_operand:SI 1 "register_operand"           "")
948                          (match_operand:SI 2 "nds32_reg_constant_operand" "")])
949                       (label_ref (match_operand 3 "" ""))
950                       (pc)))]
951   ""
953   rtx tmp_reg;
954   enum rtx_code code;
956   code = GET_CODE (operands[0]);
958   /* If operands[2] is (const_int 0),
959      we can use beqz,bnez,bgtz,bgez,bltz,or blez instructions.
960      So we have gcc generate original template rtx.  */
961   if (GET_CODE (operands[2]) == CONST_INT)
962     if (INTVAL (operands[2]) == 0)
963       if ((code != GTU)
964           && (code != GEU)
965           && (code != LTU)
966           && (code != LEU))
967         goto create_template;
969   /* For other comparison, NDS32 ISA only has slt (Set-on-Less-Than)
970      behavior for the comparison, we might need to generate other
971      rtx patterns to achieve same semantic.  */
972   switch (code)
973     {
974     case GT:
975     case GTU:
976       if (GET_CODE (operands[2]) == CONST_INT)
977         {
978           /* GT  reg_A, const_int  =>  !(LT  reg_A, const_int + 1) */
979           tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
981           /* We want to plus 1 into the integer value
982              of operands[2] to create 'slt' instruction.
983              This caculation is performed on the host machine,
984              which may be 64-bit integer.
985              So the meaning of caculation result may be
986              different from the 32-bit nds32 target.
988              For example:
989                0x7fffffff + 0x1 -> 0x80000000,
990                this value is POSITIVE on 64-bit machine,
991                but the expected value on 32-bit nds32 target
992                should be NEGATIVE value.
994              Hence, instead of using GEN_INT(), we use gen_int_mode() to
995              explicitly create SImode constant rtx.  */
996           operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode);
998           if (code == GT)
999             {
1000               /* GT, use slts instruction */
1001               emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1002             }
1003           else
1004             {
1005               /* GTU, use slt instruction */
1006               emit_insn (gen_slt_compare  (tmp_reg, operands[1], operands[2]));
1007             }
1009           PUT_CODE (operands[0], EQ);
1010           operands[1] = tmp_reg;
1011           operands[2] = const0_rtx;
1012           emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1013                                      operands[2], operands[3]));
1015           DONE;
1016         }
1017       else
1018         {
1019           /* GT  reg_A, reg_B  =>  LT  reg_B, reg_A */
1020           tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1022           if (code == GT)
1023             {
1024               /* GT, use slts instruction */
1025               emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1]));
1026             }
1027           else
1028             {
1029               /* GTU, use slt instruction */
1030               emit_insn (gen_slt_compare  (tmp_reg, operands[2], operands[1]));
1031             }
1033           PUT_CODE (operands[0], NE);
1034           operands[1] = tmp_reg;
1035           operands[2] = const0_rtx;
1036           emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1037                                      operands[2], operands[3]));
1039           DONE;
1040         }
1042     case GE:
1043     case GEU:
1044       /* GE  reg_A, reg_B      =>  !(LT  reg_A, reg_B) */
1045       /* GE  reg_A, const_int  =>  !(LT  reg_A, const_int) */
1046       tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1048       if (code == GE)
1049         {
1050           /* GE, use slts instruction */
1051           emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1052         }
1053       else
1054         {
1055           /* GEU, use slt instruction */
1056           emit_insn (gen_slt_compare  (tmp_reg, operands[1], operands[2]));
1057         }
1059       PUT_CODE (operands[0], EQ);
1060       operands[1] = tmp_reg;
1061       operands[2] = const0_rtx;
1062       emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1063                                  operands[2], operands[3]));
1065       DONE;
1067     case LT:
1068     case LTU:
1069       /* LT  reg_A, reg_B      =>  LT  reg_A, reg_B */
1070       /* LT  reg_A, const_int  =>  LT  reg_A, const_int */
1071       tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1073       if (code == LT)
1074         {
1075           /* LT, use slts instruction */
1076           emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1077         }
1078       else
1079         {
1080           /* LTU, use slt instruction */
1081           emit_insn (gen_slt_compare  (tmp_reg, operands[1], operands[2]));
1082         }
1084       PUT_CODE (operands[0], NE);
1085       operands[1] = tmp_reg;
1086       operands[2] = const0_rtx;
1087       emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1088                                  operands[2], operands[3]));
1090       DONE;
1092     case LE:
1093     case LEU:
1094       if (GET_CODE (operands[2]) == CONST_INT)
1095         {
1096           /* LE  reg_A, const_int  =>  LT  reg_A, const_int + 1 */
1097           tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1099           /* Note that (le:SI X INT_MAX) is not the same as (lt:SI X INT_MIN).
1100              We better have an assert here in case GCC does not properly
1101              optimize it away.  The INT_MAX here is 0x7fffffff for target.  */
1102           gcc_assert (code != LE || INTVAL (operands[2]) != 0x7fffffff);
1103           operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode);
1105           if (code == LE)
1106             {
1107               /* LE, use slts instruction */
1108               emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1109             }
1110           else
1111             {
1112               /* LEU, use slt instruction */
1113               emit_insn (gen_slt_compare  (tmp_reg, operands[1], operands[2]));
1114             }
1116           PUT_CODE (operands[0], NE);
1117           operands[1] = tmp_reg;
1118           operands[2] = const0_rtx;
1119           emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1120                                      operands[2], operands[3]));
1122           DONE;
1123         }
1124       else
1125         {
1126           /* LE  reg_A, reg_B  =>  !(LT  reg_B, reg_A) */
1127           tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1129           if (code == LE)
1130             {
1131               /* LE, use slts instruction */
1132               emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1]));
1133             }
1134           else
1135             {
1136               /* LEU, use slt instruction */
1137               emit_insn (gen_slt_compare  (tmp_reg, operands[2], operands[1]));
1138             }
1140           PUT_CODE (operands[0], EQ);
1141           operands[1] = tmp_reg;
1142           operands[2] = const0_rtx;
1143           emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1144                                      operands[2], operands[3]));
1146           DONE;
1147         }
1149     case EQ:
1150     case NE:
1151       /* NDS32 ISA has various form for eq/ne behavior no matter
1152          what kind of the operand is.
1153          So just generate original template rtx.  */
1154       goto create_template;
1156     default:
1157       FAIL;
1158     }
1160 create_template:
1161   do {} while(0); /* dummy line */
1165 (define_insn "*cbranchsi4_equality_zero"
1166   [(set (pc)
1167         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1168                         [(match_operand:SI 1 "register_operand"  "t, l, r")
1169                          (const_int 0)])
1170                       (label_ref (match_operand 2 "" ""))
1171                       (pc)))]
1172   ""
1174   enum rtx_code code;
1176   code = GET_CODE (operands[0]);
1178   /* This zero-comparison conditional branch has two forms:
1179        32-bit instruction =>          beqz/bnez           imm16s << 1
1180        16-bit instruction => beqzs8/bnezs8/beqz38/bnez38  imm8s << 1
1182      For 32-bit case,
1183      we assume it is always reachable. (but check range -65500 ~ 65500)
1185      For 16-bit case,
1186      it must satisfy { 255 >= (label - pc) >= -256 } condition.
1187      However, since the $pc for nds32 is at the beginning of the instruction,
1188      we should leave some length space for current insn.
1189      So we use range -250 ~ 250.  */
1191   switch (get_attr_length (insn))
1192     {
1193     case 2:
1194       if (which_alternative == 0)
1195         {
1196           /* constraint: t */
1197           return (code == EQ) ? "beqzs8\t%2" : "bnezs8\t%2";
1198         }
1199       else if (which_alternative == 1)
1200         {
1201           /* constraint: l */
1202           return (code == EQ) ? "beqz38\t%1, %2" : "bnez38\t%1, %2";
1203         }
1204       else
1205         {
1206           /* constraint: r */
1207           /* For which_alternative==2, it should not be here.  */
1208           gcc_unreachable ();
1209         }
1210     case 4:
1211       /* including constraints: t, l, and r */
1212       return (code == EQ) ? "beqz\t%1, %2" : "bnez\t%1, %2";
1213     case 6:
1214       if (which_alternative == 0)
1215         {
1216           /* constraint: t */
1217           if (code == EQ)
1218             {
1219               /*    beqzs8  .L0
1220                   =>
1221                     bnezs8  .LCB0
1222                     j  .L0
1223                   .LCB0:
1224                */
1225               return "bnezs8\t.LCB%=\;j\t%2\n.LCB%=:";
1226             }
1227           else
1228             {
1229               /*    bnezs8  .L0
1230                   =>
1231                     beqzs8  .LCB0
1232                     j  .L0
1233                   .LCB0:
1234                */
1235               return "beqzs8\t.LCB%=\;j\t%2\n.LCB%=:";
1236             }
1237         }
1238       else if (which_alternative == 1)
1239         {
1240           /* constraint: l */
1241           if (code == EQ)
1242             {
1243               /*    beqz38  $r0, .L0
1244                   =>
1245                     bnez38  $r0, .LCB0
1246                     j  .L0
1247                   .LCB0:
1248                */
1249               return "bnez38\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1250             }
1251           else
1252             {
1253               /*    bnez38  $r0, .L0
1254                   =>
1255                     beqz38  $r0, .LCB0
1256                     j  .L0
1257                   .LCB0:
1258                */
1259               return "beqz38\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1260             }
1261         }
1262       else
1263         {
1264           /* constraint: r */
1265           /* For which_alternative==2, it should not be here.  */
1266           gcc_unreachable ();
1267         }
1268     case 8:
1269       /* constraint: t, l, r.  */
1270       if (code == EQ)
1271         {
1272           /*    beqz  $r8, .L0
1273               =>
1274                 bnez  $r8, .LCB0
1275                 j  .L0
1276               .LCB0:
1277            */
1278           return "bnez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1279         }
1280       else
1281         {
1282           /*    bnez  $r8, .L0
1283               =>
1284                 beqz  $r8, .LCB0
1285                 j  .L0
1286               .LCB0:
1287            */
1288           return "beqz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1289         }
1290     default:
1291       gcc_unreachable ();
1292     }
1294   [(set_attr "type" "branch")
1295    (set_attr "enabled" "1")
1296    (set_attr_alternative "length"
1297      [
1298        ;; Alternative 0
1299        (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1300                           (le (minus (match_dup 2) (pc)) (const_int  250)))
1301                      (if_then_else (match_test "TARGET_16_BIT")
1302                                    (const_int 2)
1303                                    (const_int 4))
1304                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1305                                         (le (minus (match_dup 2) (pc)) (const_int  65500)))
1306                                    (const_int 4)
1307                                    (if_then_else (match_test "TARGET_16_BIT")
1308                                                  (const_int 6)
1309                                                  (const_int 8))))
1310        ;; Alternative 1
1311        (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1312                           (le (minus (match_dup 2) (pc)) (const_int  250)))
1313                      (if_then_else (match_test "TARGET_16_BIT")
1314                                    (const_int 2)
1315                                    (const_int 4))
1316                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1317                                         (le (minus (match_dup 2) (pc)) (const_int  65500)))
1318                                    (const_int 4)
1319                                    (if_then_else (match_test "TARGET_16_BIT")
1320                                                  (const_int 6)
1321                                                  (const_int 8))))
1322        ;; Alternative 2
1323        (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1324                           (le (minus (match_dup 2) (pc)) (const_int  65500)))
1325                      (const_int 4)
1326                      (const_int 8))
1327      ])])
1330 ;; This pattern is dedicated to V2 ISA,
1331 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
1332 (define_insn "*cbranchsi4_equality_reg"
1333   [(set (pc)
1334         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1335                         [(match_operand:SI 1 "register_operand"           "r")
1336                          (match_operand:SI 2 "nds32_reg_constant_operand" "r")])
1337                       (label_ref (match_operand 3 "" ""))
1338                       (pc)))]
1339   "TARGET_ISA_V2"
1341   enum rtx_code code;
1343   code = GET_CODE (operands[0]);
1345   /* This register-comparison conditional branch has one form:
1346        32-bit instruction =>          beq/bne           imm14s << 1
1348      For 32-bit case,
1349      we assume it is always reachable. (but check range -16350 ~ 16350).  */
1351   switch (code)
1352     {
1353     case EQ:
1354       /* r, r */
1355       switch (get_attr_length (insn))
1356         {
1357         case 4:
1358           return "beq\t%1, %2, %3";
1359         case 8:
1360           /*    beq  $r0, $r1, .L0
1361               =>
1362                 bne  $r0, $r1, .LCB0
1363                 j  .L0
1364               .LCB0:
1365            */
1366           return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1367         default:
1368           gcc_unreachable ();
1369         }
1371     case NE:
1372       /* r, r */
1373       switch (get_attr_length (insn))
1374         {
1375         case 4:
1376           return "bne\t%1, %2, %3";
1377         case 8:
1378           /*    bne  $r0, $r1, .L0
1379               =>
1380                 beq  $r0, $r1, .LCB0
1381                 j  .L0
1382               .LCB0:
1383            */
1384           return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1385         default:
1386           gcc_unreachable ();
1387         }
1389     default:
1390       gcc_unreachable ();
1391     }
1393   [(set_attr "type"   "branch")
1394    (set (attr "length")
1395         (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1396                            (le (minus (match_dup 3) (pc)) (const_int  16350)))
1397                       (const_int 4)
1398                       (const_int 8)))])
1401 ;; This pattern is dedicated to V3/V3M,
1402 ;; because V3/V3M DO HAVE beqc/bnec instruction.
1403 (define_insn "*cbranchsi4_equality_reg_or_const_int"
1404   [(set (pc)
1405         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1406                         [(match_operand:SI 1 "register_operand"           "r,    r")
1407                          (match_operand:SI 2 "nds32_reg_constant_operand" "r, Is11")])
1408                       (label_ref (match_operand 3 "" ""))
1409                       (pc)))]
1410   "TARGET_ISA_V3 || TARGET_ISA_V3M"
1412   enum rtx_code code;
1414   code = GET_CODE (operands[0]);
1416   /* This register-comparison conditional branch has one form:
1417        32-bit instruction =>          beq/bne           imm14s << 1
1418        32-bit instruction =>         beqc/bnec          imm8s << 1
1420      For 32-bit case, we assume it is always reachable.
1421      (but check range -16350 ~ 16350 and -250 ~ 250).  */
1423   switch (code)
1424     {
1425     case EQ:
1426       if (which_alternative == 0)
1427         {
1428           /* r, r */
1429           switch (get_attr_length (insn))
1430             {
1431             case 4:
1432               return "beq\t%1, %2, %3";
1433             case 8:
1434               /*    beq  $r0, $r1, .L0
1435                   =>
1436                     bne  $r0, $r1, .LCB0
1437                     j  .L0
1438                   .LCB0:
1439                */
1440               return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1441             default:
1442               gcc_unreachable ();
1443             }
1444         }
1445       else
1446         {
1447           /* r, Is11 */
1448           switch (get_attr_length (insn))
1449             {
1450             case 4:
1451               return "beqc\t%1, %2, %3";
1452             case 8:
1453               /*    beqc  $r0, constant, .L0
1454                   =>
1455                     bnec  $r0, constant, .LCB0
1456                     j  .L0
1457                   .LCB0:
1458                */
1459               return "bnec\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1460             default:
1461               gcc_unreachable ();
1462             }
1463         }
1464     case NE:
1465       if (which_alternative == 0)
1466         {
1467           /* r, r */
1468           switch (get_attr_length (insn))
1469             {
1470             case 4:
1471               return "bne\t%1, %2, %3";
1472             case 8:
1473               /*    bne  $r0, $r1, .L0
1474                   =>
1475                     beq  $r0, $r1, .LCB0
1476                     j  .L0
1477                   .LCB0:
1478                */
1479               return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1480             default:
1481               gcc_unreachable ();
1482             }
1483         }
1484       else
1485         {
1486           /* r, Is11 */
1487           switch (get_attr_length (insn))
1488             {
1489             case 4:
1490               return "bnec\t%1, %2, %3";
1491             case 8:
1492               /*    bnec  $r0, constant, .L0
1493                   =>
1494                     beqc  $r0, constant, .LCB0
1495                     j  .L0
1496                   .LCB0:
1497                */
1498               return "beqc\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1499             default:
1500               gcc_unreachable ();
1501             }
1502         }
1503     default:
1504       gcc_unreachable ();
1505     }
1507   [(set_attr "type"   "branch")
1508    (set_attr_alternative "length"
1509      [
1510        ;; Alternative 0
1511        (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1512                           (le (minus (match_dup 3) (pc)) (const_int  16350)))
1513                      (const_int 4)
1514                      (const_int 8))
1515        ;; Alternative 1
1516        (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1517                           (le (minus (match_dup 3) (pc)) (const_int  250)))
1518                      (const_int 4)
1519                      (const_int 8))
1520      ])])
1523 (define_insn "*cbranchsi4_greater_less_zero"
1524   [(set (pc)
1525         (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1526                         [(match_operand:SI 1 "register_operand" "r")
1527                          (const_int 0)])
1528                       (label_ref (match_operand 2 "" ""))
1529                       (pc)))]
1530   ""
1532   enum rtx_code code;
1534   code = GET_CODE (operands[0]);
1536   /* This zero-greater-less-comparison conditional branch has one form:
1537        32-bit instruction =>      bgtz/bgez/bltz/blez     imm16s << 1
1539      For 32-bit case, we assume it is always reachable.
1540      (but check range -65500 ~ 65500).  */
1542   if (get_attr_length (insn) == 8)
1543     {
1544       /* The branch target is too far to simply use one
1545          bgtz/bgez/bltz/blez instruction.
1546          We need to reverse condition and use 'j' to jump to the target.  */
1547       switch (code)
1548         {
1549         case GT:
1550           /*   bgtz  $r8, .L0
1551              =>
1552                blez  $r8, .LCB0
1553                j  .L0
1554              .LCB0:
1555            */
1556           return "blez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1557         case GE:
1558           /*   bgez  $r8, .L0
1559              =>
1560                bltz  $r8, .LCB0
1561                j  .L0
1562              .LCB0:
1563            */
1564           return "bltz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1565         case LT:
1566           /*   bltz  $r8, .L0
1567              =>
1568                bgez  $r8, .LCB0
1569                j  .L0
1570              .LCB0:
1571            */
1572           return "bgez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1573         case LE:
1574           /*   blez  $r8, .L0
1575              =>
1576                bgtz  $r8, .LCB0
1577                j  .L0
1578              .LCB0:
1579            */
1580           return "bgtz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1581         default:
1582           gcc_unreachable ();
1583         }
1584     }
1586   switch (code)
1587     {
1588     case GT:
1589       return "bgtz\t%1, %2";
1590     case GE:
1591       return "bgez\t%1, %2";
1592     case LT:
1593       return "bltz\t%1, %2";
1594     case LE:
1595       return "blez\t%1, %2";
1596     default:
1597       gcc_unreachable ();
1598     }
1600   [(set_attr "type"   "branch")
1601    (set (attr "length")
1602         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1603                            (le (minus (match_dup 2) (pc)) (const_int  65500)))
1604                       (const_int 4)
1605                       (const_int 8)))])
1608 (define_expand "cstoresi4"
1609   [(set (match_operand:SI 0 "register_operand" "")
1610         (match_operator:SI 1 "comparison_operator"
1611           [(match_operand:SI 2 "register_operand" "")
1612            (match_operand:SI 3 "nonmemory_operand" "")]))]
1613   ""
1615   rtx tmp_reg;
1616   enum rtx_code code;
1618   code = GET_CODE (operands[1]);
1620   switch (code)
1621     {
1622     case EQ:
1623       if (GET_CODE (operands[3]) == CONST_INT)
1624         {
1625           /* reg_R = (reg_A == const_int_B)
1626              --> addi reg_C, reg_A, -const_int_B
1627                  slti reg_R, reg_C, const_int_1 */
1628           tmp_reg = gen_reg_rtx (SImode);
1629           operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode);
1630           /* If the integer value is not in the range of imm15s,
1631              we need to force register first because our addsi3 pattern
1632              only accept nds32_rimm15s_operand predicate.  */
1633           if (!satisfies_constraint_Is15 (operands[3]))
1634             operands[3] = force_reg (SImode, operands[3]);
1635           emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3]));
1636           emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx));
1638           DONE;
1639         }
1640       else
1641         {
1642           /* reg_R = (reg_A == reg_B)
1643              --> xor  reg_C, reg_A, reg_B
1644                  slti reg_R, reg_C, const_int_1 */
1645           tmp_reg = gen_reg_rtx (SImode);
1646           emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3]));
1647           emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx));
1649           DONE;
1650         }
1652     case NE:
1653       if (GET_CODE (operands[3]) == CONST_INT)
1654         {
1655           /* reg_R = (reg_A != const_int_B)
1656              --> addi reg_C, reg_A, -const_int_B
1657                  slti reg_R, const_int_0, reg_C */
1658           tmp_reg = gen_reg_rtx (SImode);
1659           operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode);
1660           /* If the integer value is not in the range of imm15s,
1661              we need to force register first because our addsi3 pattern
1662              only accept nds32_rimm15s_operand predicate.  */
1663           if (!satisfies_constraint_Is15 (operands[3]))
1664             operands[3] = force_reg (SImode, operands[3]);
1665           emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3]));
1666           emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg));
1668           DONE;
1669         }
1670       else
1671         {
1672           /* reg_R = (reg_A != reg_B)
1673              --> xor  reg_C, reg_A, reg_B
1674                  slti reg_R, const_int_0, reg_C */
1675           tmp_reg = gen_reg_rtx (SImode);
1676           emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3]));
1677           emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg));
1679           DONE;
1680         }
1682     case GT:
1683     case GTU:
1684       /* reg_R = (reg_A > reg_B)       --> slt reg_R, reg_B, reg_A */
1685       /* reg_R = (reg_A > const_int_B) --> slt reg_R, const_int_B, reg_A */
1686       if (code == GT)
1687         {
1688           /* GT, use slts instruction */
1689           emit_insn (gen_slts_compare (operands[0], operands[3], operands[2]));
1690         }
1691       else
1692         {
1693           /* GTU, use slt instruction */
1694           emit_insn (gen_slt_compare  (operands[0], operands[3], operands[2]));
1695         }
1697       DONE;
1699     case GE:
1700     case GEU:
1701       if (GET_CODE (operands[3]) == CONST_INT)
1702         {
1703           /* reg_R = (reg_A >= const_int_B)
1704              --> movi reg_C, const_int_B - 1
1705                  slt  reg_R, reg_C, reg_A */
1706           tmp_reg = gen_reg_rtx (SImode);
1708           emit_insn (gen_movsi (tmp_reg,
1709                                 gen_int_mode (INTVAL (operands[3]) - 1,
1710                                               SImode)));
1711           if (code == GE)
1712             {
1713               /* GE, use slts instruction */
1714               emit_insn (gen_slts_compare (operands[0], tmp_reg, operands[2]));
1715             }
1716           else
1717             {
1718               /* GEU, use slt instruction */
1719               emit_insn (gen_slt_compare  (operands[0], tmp_reg, operands[2]));
1720             }
1722           DONE;
1723         }
1724       else
1725         {
1726           /* reg_R = (reg_A >= reg_B)
1727              --> slt  reg_R, reg_A, reg_B
1728                  xori reg_R, reg_R, const_int_1 */
1729           if (code == GE)
1730             {
1731               /* GE, use slts instruction */
1732               emit_insn (gen_slts_compare (operands[0],
1733                                            operands[2], operands[3]));
1734             }
1735           else
1736             {
1737               /* GEU, use slt instruction */
1738               emit_insn (gen_slt_compare  (operands[0],
1739                                            operands[2], operands[3]));
1740             }
1742           /* perform 'not' behavior */
1743           emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
1745           DONE;
1746         }
1748     case LT:
1749     case LTU:
1750       /* reg_R = (reg_A < reg_B)       --> slt reg_R, reg_A, reg_B */
1751       /* reg_R = (reg_A < const_int_B) --> slt reg_R, reg_A, const_int_B */
1752       if (code == LT)
1753         {
1754           /* LT, use slts instruction */
1755           emit_insn (gen_slts_compare (operands[0], operands[2], operands[3]));
1756         }
1757       else
1758         {
1759           /* LTU, use slt instruction */
1760           emit_insn (gen_slt_compare  (operands[0], operands[2], operands[3]));
1761         }
1763       DONE;
1765     case LE:
1766     case LEU:
1767       if (GET_CODE (operands[3]) == CONST_INT)
1768         {
1769           /* reg_R = (reg_A <= const_int_B)
1770              --> movi reg_C, const_int_B + 1
1771                  slt  reg_R, reg_A, reg_C */
1772           tmp_reg = gen_reg_rtx (SImode);
1774           emit_insn (gen_movsi (tmp_reg,
1775                                 gen_int_mode (INTVAL (operands[3]) + 1,
1776                                                       SImode)));
1777           if (code == LE)
1778             {
1779               /* LE, use slts instruction */
1780               emit_insn (gen_slts_compare (operands[0], operands[2], tmp_reg));
1781             }
1782           else
1783             {
1784               /* LEU, use slt instruction */
1785               emit_insn (gen_slt_compare  (operands[0], operands[2], tmp_reg));
1786             }
1788           DONE;
1789         }
1790       else
1791         {
1792           /* reg_R = (reg_A <= reg_B) --> slt  reg_R, reg_B, reg_A
1793                                           xori reg_R, reg_R, const_int_1 */
1794           if (code == LE)
1795             {
1796               /* LE, use slts instruction */
1797               emit_insn (gen_slts_compare (operands[0],
1798                                            operands[3], operands[2]));
1799             }
1800           else
1801             {
1802               /* LEU, use slt instruction */
1803               emit_insn (gen_slt_compare  (operands[0],
1804                                            operands[3], operands[2]));
1805             }
1807           /* perform 'not' behavior */
1808           emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
1810           DONE;
1811         }
1814     default:
1815       gcc_unreachable ();
1816     }
1820 (define_insn "slts_compare"
1821   [(set (match_operand:SI 0 "register_operand"         "=t,    t, r,    r")
1822         (lt:SI (match_operand:SI 1 "nonmemory_operand" " d,    d, r,    r")
1823                (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))]
1824   ""
1825   "@
1826    slts45\t%1, %2
1827    sltsi45\t%1, %2
1828    slts\t%0, %1, %2
1829    sltsi\t%0, %1, %2"
1830   [(set_attr "type"   "compare,compare,compare,compare")
1831    (set_attr "length" "      2,      2,      4,      4")])
1833 (define_insn "slt_compare"
1834   [(set (match_operand:SI 0 "register_operand"          "=t,    t, r,    r")
1835         (ltu:SI (match_operand:SI 1 "nonmemory_operand" " d,    d, r,    r")
1836                 (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))]
1837   ""
1838   "@
1839    slt45\t%1, %2
1840    slti45\t%1, %2
1841    slt\t%0, %1, %2
1842    slti\t%0, %1, %2"
1843   [(set_attr "type"   "compare,compare,compare,compare")
1844    (set_attr "length" "      2,      2,      4,      4")])
1847 ;; ----------------------------------------------------------------------------
1849 ;; Unconditional and other jump instructions.
1851 (define_insn "jump"
1852   [(set (pc) (label_ref (match_operand 0 "" "")))]
1853   ""
1855   /* This unconditional jump has two forms:
1856        32-bit instruction => j   imm24s << 1
1857        16-bit instruction => j8  imm8s << 1
1859      For 32-bit case,
1860      we assume it is always reachable.
1861      For 16-bit case,
1862      it must satisfy { 255 >= (label - pc) >= -256 } condition.
1863      However, since the $pc for nds32 is at the beginning of the instruction,
1864      we should leave some length space for current insn.
1865      So we use range -250 ~ 250.  */
1866   switch (get_attr_length (insn))
1867     {
1868     case 2:
1869       return "j8\t%0";
1870     case 4:
1871       return "j\t%0";
1872     default:
1873       gcc_unreachable ();
1874     }
1876   [(set_attr "type" "branch")
1877    (set_attr "enabled" "1")
1878    (set (attr "length")
1879         (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1880                            (le (minus (match_dup 0) (pc)) (const_int  250)))
1881                       (if_then_else (match_test "TARGET_16_BIT")
1882                                     (const_int 2)
1883                                     (const_int 4))
1884                       (const_int 4)))])
1886 (define_insn "indirect_jump"
1887   [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1888   ""
1889   "@
1890   jr5\t%0
1891   jr\t%0"
1892   [(set_attr "type"   "branch,branch")
1893    (set_attr "length" "     2,     4")])
1895 ;; Subroutine call instruction returning no value.
1896 ;;   operands[0]: It should be a mem RTX whose address is
1897 ;;                the address of the function.
1898 ;;   operands[1]: It is the number of bytes of arguments pushed as a const_int.
1899 ;;   operands[2]: It is the number of registers used as operands.
1901 (define_expand "call"
1902   [(parallel [(call (match_operand 0 "memory_operand" "")
1903                     (match_operand 1))
1904               (clobber (reg:SI LP_REGNUM))
1905               (clobber (reg:SI TA_REGNUM))])]
1906   ""
1907   ""
1910 (define_insn "*call_register"
1911   [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
1912                     (match_operand 1))
1913               (clobber (reg:SI LP_REGNUM))
1914               (clobber (reg:SI TA_REGNUM))])]
1915   ""
1916   "@
1917   jral5\t%0
1918   jral\t%0"
1919   [(set_attr "type"   "branch,branch")
1920    (set_attr "length" "     2,     4")])
1922 (define_insn "*call_immediate"
1923   [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
1924                     (match_operand 1))
1925               (clobber (reg:SI LP_REGNUM))
1926               (clobber (reg:SI TA_REGNUM))])]
1927   ""
1929   if (TARGET_CMODEL_LARGE)
1930     return "bal\t%0";
1931   else
1932     return "jal\t%0";
1934   [(set_attr "type"   "branch")
1935    (set (attr "length")
1936         (if_then_else (match_test "TARGET_CMODEL_LARGE")
1937                       (const_int 12)
1938                       (const_int 4)))])
1941 ;; Subroutine call instruction returning a value.
1942 ;;   operands[0]: It is the hard regiser in which the value is returned.
1943 ;;   The rest three operands are the same as the
1944 ;;   three operands of the 'call' instruction.
1945 ;;   (but with numbers increased by one)
1947 (define_expand "call_value"
1948   [(parallel [(set (match_operand 0)
1949                    (call (match_operand 1 "memory_operand" "")
1950                          (match_operand 2)))
1951               (clobber (reg:SI LP_REGNUM))
1952               (clobber (reg:SI TA_REGNUM))])]
1953   ""
1954   ""
1957 (define_insn "*call_value_register"
1958   [(parallel [(set (match_operand 0)
1959                    (call (mem (match_operand:SI 1 "register_operand" "r, r"))
1960                          (match_operand 2)))
1961               (clobber (reg:SI LP_REGNUM))
1962               (clobber (reg:SI TA_REGNUM))])]
1963   ""
1964   "@
1965   jral5\t%1
1966   jral\t%1"
1967   [(set_attr "type"   "branch,branch")
1968    (set_attr "length" "     2,     4")])
1970 (define_insn "*call_value_immediate"
1971   [(parallel [(set (match_operand 0)
1972                    (call (mem (match_operand:SI 1 "immediate_operand" "i"))
1973                          (match_operand 2)))
1974               (clobber (reg:SI LP_REGNUM))
1975               (clobber (reg:SI TA_REGNUM))])]
1976   ""
1978   if (TARGET_CMODEL_LARGE)
1979     return "bal\t%1";
1980   else
1981     return "jal\t%1";
1983   [(set_attr "type"   "branch")
1984    (set (attr "length")
1985         (if_then_else (match_test "TARGET_CMODEL_LARGE")
1986                       (const_int 12)
1987                       (const_int 4)))])
1990 ;; ----------------------------------------------------------------------------
1992 ;; The sibcall patterns.
1994 ;; sibcall
1995 ;; sibcall_register
1996 ;; sibcall_immediate
1998 (define_expand "sibcall"
1999   [(parallel [(call (match_operand 0 "memory_operand" "")
2000                     (const_int 0))
2001               (clobber (reg:SI TA_REGNUM))
2002               (return)])]
2003   ""
2004   ""
2007 (define_insn "*sibcall_register"
2008   [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
2009                     (match_operand 1))
2010               (clobber (reg:SI TA_REGNUM))
2011               (return)])]
2012   ""
2013   "@
2014    jr5\t%0
2015    jr\t%0"
2016   [(set_attr "type"   "branch,branch")
2017    (set_attr "length" "     2,     4")])
2019 (define_insn "*sibcall_immediate"
2020   [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
2021                     (match_operand 1))
2022               (clobber (reg:SI TA_REGNUM))
2023               (return)])]
2024   ""
2026   if (TARGET_CMODEL_LARGE)
2027     return "b\t%0";
2028   else
2029     return "j\t%0";
2031   [(set_attr "type"   "branch")
2032    (set (attr "length")
2033         (if_then_else (match_test "TARGET_CMODEL_LARGE")
2034                       (const_int 12)
2035                       (const_int 4)))])
2037 ;; sibcall_value
2038 ;; sibcall_value_register
2039 ;; sibcall_value_immediate
2041 (define_expand "sibcall_value"
2042   [(parallel [(set (match_operand 0)
2043                    (call (match_operand 1 "memory_operand" "")
2044                          (const_int 0)))
2045               (clobber (reg:SI TA_REGNUM))
2046               (return)])]
2047   ""
2048   ""
2051 (define_insn "*sibcall_value_register"
2052   [(parallel [(set (match_operand 0)
2053                    (call (mem (match_operand:SI 1 "register_operand" "r, r"))
2054                          (match_operand 2)))
2055               (clobber (reg:SI TA_REGNUM))
2056               (return)])]
2057   ""
2058   "@
2059    jr5\t%1
2060    jr\t%1"
2061   [(set_attr "type"   "branch,branch")
2062    (set_attr "length" "     2,     4")])
2064 (define_insn "*sibcall_value_immediate"
2065   [(parallel [(set (match_operand 0)
2066                    (call (mem (match_operand:SI 1 "immediate_operand" "i"))
2067                          (match_operand 2)))
2068               (clobber (reg:SI TA_REGNUM))
2069               (return)])]
2070   ""
2072   if (TARGET_CMODEL_LARGE)
2073     return "b\t%1";
2074   else
2075     return "j\t%1";
2077   [(set_attr "type"   "branch")
2078    (set (attr "length")
2079         (if_then_else (match_test "TARGET_CMODEL_LARGE")
2080                       (const_int 12)
2081                       (const_int 4)))])
2084 ;; ----------------------------------------------------------------------------
2086 ;; prologue and epilogue.
2088 (define_expand "prologue" [(const_int 0)]
2089   ""
2091   /* Note that only under V3/V3M ISA, we could use v3push prologue.
2092      In addition, we do not want to use v3push for isr function
2093      and variadic function.  */
2094   if (TARGET_V3PUSH
2095       && !nds32_isr_function_p (current_function_decl)
2096       && (cfun->machine->va_args_size == 0))
2097     nds32_expand_prologue_v3push ();
2098   else
2099     nds32_expand_prologue ();
2100   DONE;
2103 (define_expand "epilogue" [(const_int 0)]
2104   ""
2106   /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
2107      In addition, we do not want to use v3pop for isr function
2108      and variadic function.  */
2109   if (TARGET_V3PUSH
2110       && !nds32_isr_function_p (current_function_decl)
2111       && (cfun->machine->va_args_size == 0))
2112     nds32_expand_epilogue_v3pop (false);
2113   else
2114     nds32_expand_epilogue (false);
2115   DONE;
2118 (define_expand "sibcall_epilogue" [(const_int 0)]
2119   ""
2121   /* Pass true to indicate that this is sibcall epilogue and
2122      exit from a function without the final branch back to the
2123      calling function.  */
2124   if (TARGET_V3PUSH && !nds32_isr_function_p (current_function_decl))
2125     nds32_expand_epilogue_v3pop (true);
2126   else
2127     nds32_expand_epilogue (true);
2129   DONE;
2133 ;; nop instruction.
2135 (define_insn "nop"
2136   [(const_int 0)]
2137   ""
2139   if (TARGET_16_BIT)
2140     return "nop16";
2141   else
2142     return "nop";
2144   [(set_attr "type" "misc")
2145    (set_attr "enabled" "1")
2146    (set (attr "length")
2147         (if_then_else (match_test "TARGET_16_BIT")
2148                       (const_int 2)
2149                       (const_int 4)))])
2152 ;; ----------------------------------------------------------------------------
2153 ;; Stack push/pop operations
2154 ;; ----------------------------------------------------------------------------
2156 ;; The pattern for stack push.
2157 ;; Both stack_push_multiple and stack_v3push use the following pattern.
2158 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
2159 (define_insn "*stack_push"
2160   [(match_parallel 0 "nds32_stack_push_operation"
2161      [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
2162                             (match_operand:SI 1 "const_int_operand" "")))
2163            (match_operand:SI 2 "register_operand" ""))
2164      ])]
2165   ""
2167   return nds32_output_stack_push (operands[0]);
2169   [(set_attr "type" "misc")
2170    (set_attr "enabled" "1")
2171    (set (attr "length")
2172         (if_then_else (match_test "TARGET_V3PUSH
2173                                    && !nds32_isr_function_p (cfun->decl)
2174                                    && (cfun->machine->va_args_size == 0)")
2175                       (const_int 2)
2176                       (const_int 4)))])
2179 ;; The pattern for stack pop.
2180 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
2181 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
2182 (define_insn "*stack_pop"
2183   [(match_parallel 0 "nds32_stack_pop_operation"
2184      [(set (match_operand:SI 1 "register_operand" "")
2185            (mem:SI (reg:SI SP_REGNUM)))
2186      ])]
2187   ""
2189   return nds32_output_stack_pop (operands[0]);
2191   [(set_attr "type" "misc")
2192    (set_attr "enabled" "1")
2193    (set (attr "length")
2194         (if_then_else (match_test "TARGET_V3PUSH
2195                                    && !nds32_isr_function_p (cfun->decl)
2196                                    && (cfun->machine->va_args_size == 0)")
2197                       (const_int 2)
2198                       (const_int 4)))])
2201 ;; ----------------------------------------------------------------------------
2202 ;; Return operation patterns
2203 ;; ----------------------------------------------------------------------------
2205 ;; Use this pattern to expand a return instruction
2206 ;; with simple_return rtx if no epilogue is required.
2207 (define_expand "return"
2208   [(simple_return)]
2209   "nds32_can_use_return_insn ()"
2210   ""
2213 ;; This pattern is expanded only by the shrink-wrapping optimization
2214 ;; on paths where the function prologue has not been executed.
2215 (define_expand "simple_return"
2216   [(simple_return)]
2217   ""
2218   ""
2221 (define_insn "return_internal"
2222   [(simple_return)]
2223   ""
2225   if (TARGET_16_BIT)
2226     return "ret5";
2227   else
2228     return "ret";
2230   [(set_attr "type" "branch")
2231    (set_attr "enabled" "1")
2232    (set (attr "length")
2233         (if_then_else (match_test "TARGET_16_BIT")
2234                       (const_int 2)
2235                       (const_int 4)))])
2238 ;; ----------------------------------------------------------------------------
2239 ;; Jump Table patterns
2240 ;; ----------------------------------------------------------------------------
2241 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
2242 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
2244 ;; operands[0]: The index to dispatch on.
2245 ;; operands[1]: The lower bound for indices in the table.
2246 ;; operands[2]: The total range of indices int the table.
2247 ;;              i.e. The largest index minus the smallest one.
2248 ;; operands[3]: A label that precedes the table itself.
2249 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
2251 ;; We need to create following sequences for jump table code generation:
2252 ;;   A) k <-- (plus (operands[0]) (-operands[1]))
2253 ;;   B) if (gtu k operands[2]) then goto operands[4]
2254 ;;   C) t <-- operands[3]
2255 ;;   D) z <-- (mem (plus (k << 0 or 1 or 2) t))
2256 ;;   E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
2257 ;;   F) jump to target with register t or z
2259 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
2260 (define_expand "casesi"
2261   [(match_operand:SI 0 "register_operand"  "r") ; index to jump on
2262    (match_operand:SI 1 "immediate_operand" "i") ; lower bound
2263    (match_operand:SI 2 "immediate_operand" "i") ; total range
2264    (match_operand:SI 3 "" "")                   ; table label
2265    (match_operand:SI 4 "" "")]                  ; Out of range label
2266   ""
2268   rtx add_tmp;
2269   rtx reg, test;
2271   /* Step A: "k <-- (plus (operands[0]) (-operands[1]))".  */
2272   if (operands[1] != const0_rtx)
2273     {
2274       reg = gen_reg_rtx (SImode);
2275       add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
2277       /* If the integer value is not in the range of imm15s,
2278          we need to force register first because our addsi3 pattern
2279          only accept nds32_rimm15s_operand predicate.  */
2280       add_tmp = force_reg (SImode, add_tmp);
2282       emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
2283       operands[0] = reg;
2284     }
2286   /* Step B: "if (gtu k operands[2]) then goto operands[4]".  */
2287   test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
2288   emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
2289                                   operands[4]));
2291   /* Step C, D, E, and F, using another temporary register.  */
2292   rtx tmp = gen_reg_rtx (SImode);
2293   emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
2294   DONE;
2297 ;; We are receiving operands from casesi pattern:
2299 ;; operands[0]: The index that have been substracted with lower bound.
2300 ;; operands[1]: A label that precedes the table itself.
2301 ;; operands[2]: A temporary register to retrieve value in table.
2303 ;; We need to perform steps C, D, E, and F:
2305 ;;   C) t <-- operands[1]
2306 ;;   D) z <-- (mem (plus (operands[0] << m) t))
2307 ;;            m is 2 for normal jump table.
2308 ;;            m is 0, 1, or 2 for pc relative jump table based on diff size.
2309 ;;   E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
2310 ;;   F) Jump to target with register t or z.
2312 ;; The USE in this pattern is needed to tell flow analysis that this is
2313 ;; a CASESI insn.  It has no other purpose.
2314 (define_insn "casesi_internal"
2315   [(parallel [(set (pc)
2316                    (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
2317                                              (const_int 4))
2318                                     (label_ref (match_operand 1 "" "")))))
2319               (use (label_ref (match_dup 1)))
2320               (clobber (match_operand:SI 2 "register_operand" "=r"))
2321               (clobber (reg:SI TA_REGNUM))])]
2322   ""
2324   if (CASE_VECTOR_PC_RELATIVE)
2325     return nds32_output_casesi_pc_relative (operands);
2326   else
2327     return nds32_output_casesi (operands);
2329   [(set_attr "length" "20")
2330    (set_attr "type" "alu")])
2332 ;; ----------------------------------------------------------------------------
2334 ;; Performance Extension
2336 (define_insn "clzsi2"
2337   [(set (match_operand:SI 0 "register_operand"         "=r")
2338         (clz:SI (match_operand:SI 1 "register_operand" " r")))]
2339   "TARGET_PERF_EXT"
2340   "clz\t%0, %1"
2341   [(set_attr "type" "alu")
2342    (set_attr "length" "4")])
2344 (define_insn "smaxsi3"
2345   [(set (match_operand:SI 0 "register_operand"          "=r")
2346         (smax:SI (match_operand:SI 1 "register_operand" " r")
2347                  (match_operand:SI 2 "register_operand" " r")))]
2348   "TARGET_PERF_EXT"
2349   "max\t%0, %1, %2"
2350   [(set_attr "type" "alu")
2351    (set_attr "length" "4")])
2353 (define_insn "sminsi3"
2354   [(set (match_operand:SI 0 "register_operand"          "=r")
2355         (smin:SI (match_operand:SI 1 "register_operand" " r")
2356                  (match_operand:SI 2 "register_operand" " r")))]
2357   "TARGET_PERF_EXT"
2358   "min\t%0, %1, %2"
2359   [(set_attr "type" "alu")
2360    (set_attr "length" "4")])
2362 (define_insn "*btst"
2363   [(set (match_operand:SI 0 "register_operand"                   "=   r")
2364         (zero_extract:SI (match_operand:SI 1 "register_operand"  "    r")
2365                          (const_int 1)
2366                          (match_operand:SI 2 "immediate_operand" " Iu05")))]
2367   "TARGET_PERF_EXT"
2368   "btst\t%0, %1, %2"
2369   [(set_attr "type" "alu")
2370    (set_attr "length" "4")])
2372 ;; ----------------------------------------------------------------------------
2374 ;; Pseudo NOPs
2376 (define_insn "pop25return"
2377   [(return)
2378    (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
2379   ""
2380   "! return for pop 25"
2381   [(set_attr "length" "0")]
2384 ;; ----------------------------------------------------------------------------