[NDS32] Add divsi4 and udivsi4 patterns.
[official-gcc.git] / gcc / config / nds32 / nds32.md
blob2d0f1d3e91bf70507b5f210ab6731b40713b5365
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 peephole patterns.
50 (include "nds32-peephole2.md")
53 ;; Insn type, it is used to default other attribute values.
54 (define_attr "type"
55   "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,call,misc"
56   (const_string "unknown"))
58 ;; Insn sub-type
59 (define_attr "subtype"
60   "simple,shift"
61   (const_string "simple"))
63 ;; Length, in bytes, default is 4-bytes.
64 (define_attr "length" "" (const_int 4))
66 ;; Indicate the amount of micro instructions.
67 (define_attr "combo"
68   "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"
69   (const_string "1"))
71 ;; Insn in which feature set, it is used to enable/disable insn alternatives.
72 ;; v1  : Baseline Instructions
73 ;; v2  : Baseline Version 2 Instructions
74 ;; v3m : Baseline Version 3m Instructions
75 ;; v3  : Baseline Version 3 Instructions
76 ;; pe1 : Performance Extension Instructions
77 ;; pe2 : Performance Extension Version 2 Instructions
78 ;; se  : String Extension instructions
79 (define_attr "feature"
80   "v1,v2,v3m,v3,pe1,pe2,se"
81   (const_string "v1"))
83 ;; Enabled, which is used to enable/disable insn alternatives.
84 ;; Note that we use length and TARGET_16_BIT here as criteria.
85 ;; If the instruction pattern already check TARGET_16_BIT to determine
86 ;; the length by itself, its enabled attribute should be customized to
87 ;; avoid the conflict between length attribute and this default setting.
88 (define_attr "enabled" "no,yes"
89   (if_then_else
90     (and (eq_attr "length" "2")
91          (match_test "!TARGET_16_BIT"))
92     (const_string "no")
93     (cond [(eq_attr "feature" "v1")   (const_string "yes")
94            (eq_attr "feature" "v2")   (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M")
95                                                     (const_string "yes")
96                                                     (const_string "no"))
97            (eq_attr "feature" "v3")   (if_then_else (match_test "TARGET_ISA_V3")
98                                                     (const_string "yes")
99                                                     (const_string "no"))
100            (eq_attr "feature" "v3m")  (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M")
101                                                     (const_string "yes")
102                                                     (const_string "no"))
103            (eq_attr "feature" "pe1")  (if_then_else (match_test "TARGET_EXT_PERF")
104                                                     (const_string "yes")
105                                                     (const_string "no"))
106            (eq_attr "feature" "pe2")  (if_then_else (match_test "TARGET_EXT_PERF2")
107                                                     (const_string "yes")
108                                                     (const_string "no"))
109            (eq_attr "feature" "se")   (if_then_else (match_test "TARGET_EXT_STRING")
110                                                     (const_string "yes")
111                                                     (const_string "no"))]
112            (const_string "yes"))))
115 ;; ----------------------------------------------------------------------------
118 ;; Move instructions.
120 ;; For QImode and HImode, the immediate value can be fit in imm20s.
121 ;; So there is no need to split rtx for QI and HI patterns.
123 (define_expand "mov<mode>"
124   [(set (match_operand:QIHI 0 "general_operand" "")
125         (match_operand:QIHI 1 "general_operand" ""))]
126   ""
128   /* Need to force register if mem <- !reg.  */
129   if (MEM_P (operands[0]) && !REG_P (operands[1]))
130     operands[1] = force_reg (<MODE>mode, operands[1]);
132   if (MEM_P (operands[1]) && optimize > 0)
133     {
134       rtx reg = gen_reg_rtx (SImode);
136       emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
137       operands[1] = gen_lowpart (<MODE>mode, reg);
138     }
141 (define_expand "movmisalign<mode>"
142   [(set (match_operand:SIDI 0 "general_operand" "")
143         (match_operand:SIDI 1 "general_operand" ""))]
144   ""
146   rtx addr;
147   if (MEM_P (operands[0]) && !REG_P (operands[1]))
148     operands[1] = force_reg (<MODE>mode, operands[1]);
150   if (MEM_P (operands[0]))
151     {
152       addr = force_reg (Pmode, XEXP (operands[0], 0));
153       emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
154     }
155   else
156     {
157       addr = force_reg (Pmode, XEXP (operands[1], 0));
158       emit_insn (gen_unaligned_load<mode> (operands[0], addr));
159     }
160   DONE;
163 (define_expand "movsi"
164   [(set (match_operand:SI 0 "general_operand" "")
165         (match_operand:SI 1 "general_operand" ""))]
166   ""
168   /* Need to force register if mem <- !reg.  */
169   if (MEM_P (operands[0]) && !REG_P (operands[1]))
170     operands[1] = force_reg (SImode, operands[1]);
172   /* If operands[1] is a large constant and cannot be performed
173      by a single instruction, we need to split it.  */
174   if (CONST_INT_P (operands[1])
175       && !satisfies_constraint_Is20 (operands[1])
176       && !satisfies_constraint_Ihig (operands[1]))
177     {
178       rtx high20_rtx;
179       HOST_WIDE_INT low12_int;
180       rtx tmp_rtx;
182       tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
184       high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
185       low12_int = INTVAL (operands[1]) & 0xfff;
187       emit_move_insn (tmp_rtx, high20_rtx);
188       emit_move_insn (operands[0], plus_constant (SImode,
189                                                   tmp_rtx,
190                                                   low12_int));
191       DONE;
192     }
195 (define_insn "*mov<mode>"
196   [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r, U45, U33, U37, U45, m,   l,   l,   l,   d, r,    d,    r,    r,    r")
197         (match_operand:QIHISI 1 "nds32_move_operand"   " r, r,   l,   l,   l,   d, r, U45, U33, U37, U45, m, Ip05, Is05, Is20, Ihig"))]
198   "register_operand(operands[0], <MODE>mode)
199    || register_operand(operands[1], <MODE>mode)"
201   switch (which_alternative)
202     {
203     case 0:
204       return "mov55\t%0, %1";
205     case 1:
206       return "ori\t%0, %1, 0";
207     case 2:
208     case 3:
209     case 4:
210     case 5:
211       return nds32_output_16bit_store (operands, <byte>);
212     case 6:
213       return nds32_output_32bit_store (operands, <byte>);
214     case 7:
215     case 8:
216     case 9:
217     case 10:
218       return nds32_output_16bit_load (operands, <byte>);
219     case 11:
220       return nds32_output_32bit_load (operands, <byte>);
221     case 12:
222       return "movpi45\t%0, %1";
223     case 13:
224       return "movi55\t%0, %1";
225     case 14:
226       return "movi\t%0, %1";
227     case 15:
228       return "sethi\t%0, hi20(%1)";
229     default:
230       gcc_unreachable ();
231     }
233   [(set_attr "type"   "alu,alu,store,store,store,store,store,load,load,load,load,load,alu,alu,alu,alu")
234    (set_attr "length" "  2,  4,    2,    2,    2,    2,    4,   2,   2,   2,   2,   4,  2,  2,  4,  4")])
237 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
238 ;; are able to match such instruction template.
239 (define_insn "move_addr"
240   [(set (match_operand:SI 0 "register_operand"       "=l, r")
241         (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
242   ""
243   "la\t%0, %1"
244   [(set_attr "type"  "alu")
245    (set_attr "length"  "8")])
248 (define_insn "sethi"
249   [(set (match_operand:SI 0 "register_operand"                "=r")
250         (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
251   ""
252   "sethi\t%0, hi20(%1)"
253   [(set_attr "type" "alu")
254    (set_attr "length" "4")])
257 (define_insn "lo_sum"
258   [(set (match_operand:SI 0 "register_operand"                  "=r")
259         (lo_sum:SI (match_operand:SI 1 "register_operand"       " r")
260                    (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
261   ""
262   "ori\t%0, %1, lo12(%2)"
263   [(set_attr "type" "alu")
264    (set_attr "length" "4")])
267 ;; ----------------------------------------------------------------------------
269 ;; Zero extension instructions.
271 (define_insn "zero_extend<mode>si2"
272   [(set (match_operand:SI 0 "register_operand"                       "=l, r,   l, *r")
273         (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33,  m")))]
274   ""
276   switch (which_alternative)
277     {
278     case 0:
279       return "ze<size>33\t%0, %1";
280     case 1:
281       return "ze<size>\t%0, %1";
282     case 2:
283       return nds32_output_16bit_load (operands, <byte>);
284     case 3:
285       return nds32_output_32bit_load (operands, <byte>);
287     default:
288       gcc_unreachable ();
289     }
291   [(set_attr "type"   "alu,alu,load,load")
292    (set_attr "length" "  2,  4,   2,   4")])
295 ;; Sign extension instructions.
297 (define_insn "extend<mode>si2"
298   [(set (match_operand:SI 0 "register_operand"                       "=l, r, r")
299         (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
300   ""
302   switch (which_alternative)
303     {
304     case 0:
305       return "se<size>33\t%0, %1";
306     case 1:
307       return "se<size>\t%0, %1";
308     case 2:
309       return nds32_output_32bit_load_s (operands, <byte>);
311     default:
312       gcc_unreachable ();
313     }
315   [(set_attr "type"   "alu,alu,load")
316    (set_attr "length" "  2,  4,   4")])
319 ;; ----------------------------------------------------------------------------
321 ;; Arithmetic instructions.
323 (define_insn "addsi3"
324   [(set (match_operand:SI 0 "register_operand"               "=   d,   l,   d,   l, d, l,   k,   l,    r, r")
325         (plus:SI (match_operand:SI 1 "register_operand"      "%   0,   l,   0,   l, 0, l,   0,   k,    r, r")
326                  (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,Iu06, Is15, r")))]
327   ""
329   switch (which_alternative)
330     {
331     case 0:
332       /* addi Rt4,Rt4,-x  ==>  subi45 Rt4,x
333          where 0 <= x <= 31 */
334       operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
335       return "subi45\t%0, %2";
336     case 1:
337       /* addi Rt3,Ra3,-x  ==>  subi333 Rt3,Ra3,x
338          where 0 <= x <= 7 */
339       operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
340       return "subi333\t%0, %1, %2";
341     case 2:
342       return "addi45\t%0, %2";
343     case 3:
344       return "addi333\t%0, %1, %2";
345     case 4:
346       return "add45\t%0, %2";
347     case 5:
348       return "add333\t%0, %1, %2";
349     case 6:
350       return "addi10.sp\t%2";
351     case 7:
352       return "addri36.sp\t%0, %2";
353     case 8:
354       return "addi\t%0, %1, %2";
355     case 9:
356       return "add\t%0, %1, %2";
358     default:
359       gcc_unreachable ();
360     }
362   [(set_attr "type"    "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
363    (set_attr "length"  "  2,  2,  2,  2,  2,  2,  2,  2,  4,  4")
364    (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")])
366 (define_insn "subsi3"
367   [(set (match_operand:SI 0 "register_operand"                "=d, l,    r, r")
368         (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
369                   (match_operand:SI 2 "register_operand"      " r, l,    r, r")))]
370   ""
371   "@
372    sub45\t%0, %2
373    sub333\t%0, %1, %2
374    subri\t%0, %2, %1
375    sub\t%0, %1, %2"
376   [(set_attr "type"   "alu,alu,alu,alu")
377    (set_attr "length" "  2,  2,  4,  4")])
380 ;; GCC intends to simplify (plus (ashift ...) (reg))
381 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
382 ;; and needs to ensure it is exact_log2 value.
383 (define_insn "*add_slli"
384   [(set (match_operand:SI 0 "register_operand"                    "=r")
385         (plus:SI (mult:SI (match_operand:SI 1 "register_operand"  " r")
386                           (match_operand:SI 2 "immediate_operand" " i"))
387                  (match_operand:SI 3 "register_operand"           " r")))]
388   "TARGET_ISA_V3
389    && (exact_log2 (INTVAL (operands[2])) != -1)
390    && (exact_log2 (INTVAL (operands[2])) <= 31)"
392   /* Get floor_log2 of the immediate value
393      so that we can generate 'add_slli' instruction.  */
394   operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
396   return "add_slli\t%0, %3, %1, %2";
398   [(set_attr "type" "alu_shift")
399    (set_attr "combo"        "2")
400    (set_attr "length"       "4")])
402 (define_insn "*add_srli"
403   [(set (match_operand:SI 0 "register_operand"                          "=   r")
404         (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
405                               (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
406                  (match_operand:SI 3 "register_operand"                 "    r")))]
407   "TARGET_ISA_V3"
408   "add_srli\t%0, %3, %1, %2"
409   [(set_attr "type" "alu_shift")
410    (set_attr "combo"        "2")
411    (set_attr "length"       "4")])
414 ;; GCC intends to simplify (minus (reg) (ashift ...))
415 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
416 ;; and needs to ensure it is exact_log2 value.
417 (define_insn "*sub_slli"
418   [(set (match_operand:SI 0 "register_operand"                     "=r")
419         (minus:SI (match_operand:SI 1 "register_operand"           " r")
420                   (mult:SI (match_operand:SI 2 "register_operand"  " r")
421                            (match_operand:SI 3 "immediate_operand" " i"))))]
422   "TARGET_ISA_V3
423    && (exact_log2 (INTVAL (operands[3])) != -1)
424    && (exact_log2 (INTVAL (operands[3])) <= 31)"
426   /* Get floor_log2 of the immediate value
427      so that we can generate 'sub_slli' instruction.  */
428   operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
430   return "sub_slli\t%0, %1, %2, %3";
432   [(set_attr "type" "alu_shift")
433    (set_attr "combo"        "2")
434    (set_attr "length"       "4")])
436 (define_insn "*sub_srli"
437   [(set (match_operand:SI 0 "register_operand"                           "=   r")
438         (minus:SI (match_operand:SI 1 "register_operand"                 "    r")
439                   (lshiftrt:SI (match_operand:SI 2 "register_operand"    "    r")
440                                (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))]
441   "TARGET_ISA_V3"
442   "sub_srli\t%0, %1, %2, %3"
443   [(set_attr "type" "alu_shift")
444    (set_attr "combo"        "2")
445    (set_attr "length"       "4")])
448 ;; Multiplication instructions.
450 (define_insn "mulsi3"
451   [(set (match_operand:SI 0 "register_operand"          "=w, r")
452         (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
453                  (match_operand:SI 2 "register_operand" " w, r")))]
454   ""
455   "@
456    mul33\t%0, %2
457    mul\t%0, %1, %2"
458   [(set_attr "type"    "mul,mul")
459    (set_attr "length"  "  2,  4")
460    (set_attr "feature" "v3m, v1")])
462 (define_insn "mulsidi3"
463   [(set (match_operand:DI 0 "register_operand"                          "=r")
464         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
465                  (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
466   "TARGET_ISA_V2 || TARGET_ISA_V3"
467   "mulsr64\t%0, %1, %2"
468   [(set_attr "type"   "mul")
469    (set_attr "length"   "4")])
471 (define_insn "umulsidi3"
472   [(set (match_operand:DI 0 "register_operand"                          "=r")
473         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
474                  (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
475   "TARGET_ISA_V2 || TARGET_ISA_V3"
476   "mulr64\t%0, %1, %2"
477   [(set_attr "type"   "mul")
478    (set_attr "length"   "4")])
481 ;; Multiply-accumulate instructions.
483 (define_insn "*maddr32_0"
484   [(set (match_operand:SI 0 "register_operand"                   "=r")
485         (plus:SI (match_operand:SI 3 "register_operand"          " 0")
486                  (mult:SI (match_operand:SI 1 "register_operand" " r")
487                           (match_operand:SI 2 "register_operand" " r"))))]
488   ""
489   "maddr32\t%0, %1, %2"
490   [(set_attr "type"   "mac")
491    (set_attr "length"   "4")])
493 (define_insn "*maddr32_1"
494   [(set (match_operand:SI 0 "register_operand"                   "=r")
495         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
496                           (match_operand:SI 2 "register_operand" " r"))
497                  (match_operand:SI 3 "register_operand"          " 0")))]
498   ""
499   "maddr32\t%0, %1, %2"
500   [(set_attr "type"   "mac")
501    (set_attr "length"   "4")])
503 (define_insn "*msubr32"
504   [(set (match_operand:SI 0 "register_operand"                    "=r")
505         (minus:SI (match_operand:SI 3 "register_operand"          " 0")
506                   (mult:SI (match_operand:SI 1 "register_operand" " r")
507                            (match_operand:SI 2 "register_operand" " r"))))]
508   ""
509   "msubr32\t%0, %1, %2"
510   [(set_attr "type"   "mac")
511    (set_attr "length"   "4")])
514 ;; Div Instructions.
516 (define_insn "divmodsi4"
517   [(set (match_operand:SI 0 "register_operand"         "=r")
518         (div:SI (match_operand:SI 1 "register_operand" " r")
519                 (match_operand:SI 2 "register_operand" " r")))
520    (set (match_operand:SI 3 "register_operand"         "=r")
521         (mod:SI (match_dup 1) (match_dup 2)))]
522   ""
523   "divsr\t%0, %3, %1, %2"
524   [(set_attr "type"   "div")
525    (set_attr "length"   "4")])
527 (define_insn "udivmodsi4"
528   [(set (match_operand:SI 0 "register_operand"          "=r")
529         (udiv:SI (match_operand:SI 1 "register_operand" " r")
530                  (match_operand:SI 2 "register_operand"  " r")))
531    (set (match_operand:SI 3 "register_operand"          "=r")
532         (umod:SI (match_dup 1) (match_dup 2)))]
533   ""
534   "divr\t%0, %3, %1, %2"
535   [(set_attr "type"   "div")
536    (set_attr "length"   "4")])
538 ;; divsr/divr will keep quotient only when quotient and remainder is the same
539 ;; register in our ISA spec, it's can reduce 1 register presure if we don't
540 ;; want remainder.
541 (define_insn "divsi4"
542   [(set (match_operand:SI 0 "register_operand"         "=r")
543         (div:SI (match_operand:SI 1 "register_operand" " r")
544                 (match_operand:SI 2 "register_operand" " r")))]
545   ""
546   "divsr\t%0, %0, %1, %2"
547   [(set_attr "type"   "div")
548    (set_attr "length"   "4")])
550 (define_insn "udivsi4"
551   [(set (match_operand:SI 0 "register_operand"          "=r")
552         (udiv:SI (match_operand:SI 1 "register_operand" " r")
553                  (match_operand:SI 2 "register_operand"  " r")))]
554   ""
555   "divr\t%0, %0, %1, %2"
556   [(set_attr "type"   "div")
557    (set_attr "length"   "4")])
559 ;; ----------------------------------------------------------------------------
561 ;; Boolean instructions.
562 ;; Note: We define the DImode versions in nds32-doubleword.md.
564 ;; ----------------------------------------------------------------------------
565 ;; 'AND' operation
566 ;; ----------------------------------------------------------------------------
568 (define_insn "bitc"
569   [(set (match_operand:SI 0 "register_operand"                 "=r")
570         (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
571                 (match_operand:SI 2 "register_operand"         " r")))]
572   "TARGET_ISA_V3"
573   "bitc\t%0, %2, %1"
574   [(set_attr "type" "alu")
575    (set_attr "length" "4")]
578 (define_expand "andsi3"
579   [(set (match_operand:SI 0 "register_operand" "")
580         (and:SI (match_operand:SI 1 "register_operand" "")
581                 (match_operand:SI 2 "nds32_reg_constant_operand" "")))]
582   ""
584   if (CONST_INT_P (operands[2])
585       && !nds32_and_operand (operands[2], SImode))
586     {
587       nds32_expand_constant (SImode, INTVAL (operands[2]),
588                              operands[0], operands[1]);
589       DONE;
590     }
593 (define_insn "*andsi3"
594   [(set (match_operand:SI 0 "register_operand"          "=l, r,   l,   l,   l,   l,   l,   l,    r,   r,     r,    r,    r")
595         (and:SI (match_operand:SI 1 "register_operand"  "%0, r,   l,   l,   l,   l,   0,   0,    r,   r,     r,    r,    r")
596                 (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
597   ""
599   HOST_WIDE_INT mask = INTVAL (operands[2]);
601   /* 16-bit andi instructions:
602      andi Rt3,Ra3,0xff   -> zeb33  Rt3,Ra3
603      andi Rt3,Ra3,0xffff -> zeh33  Rt3,Ra3
604      andi Rt3,Ra3,0x01   -> xlsb33 Rt3,Ra3
605      andi Rt3,Ra3,0x7ff  -> x11b33 Rt3,Ra3
606      andi Rt3,Rt3,2^imm3u          -> bmski33 Rt3,imm3u
607      andi Rt3,Rt3,(2^(imm3u+1))-1  -> fexti33 Rt3,imm3u.  */
609   switch (which_alternative)
610     {
611     case 0:
612       return "and33\t%0, %2";
613     case 1:
614       return "and\t%0, %1, %2";
615     case 2:
616       return "zeb33\t%0, %1";
617     case 3:
618       return "zeh33\t%0, %1";
619     case 4:
620       return "xlsb33\t%0, %1";
621     case 5:
622       return "x11b33\t%0, %1";
623     case 6:
624       return "bmski33\t%0, %B2";
625     case 7:
626       operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
627       return "fexti33\t%0, %2";
628     case 8:
629       return "zeb\t%0, %1";
630     case 9:
631       return "zeh\t%0, %1";
632     case 10:
633       return "andi\t%0, %1, %2";
634     case 11:
635       operands[2] = GEN_INT (~mask);
636       return "bitci\t%0, %1, %2";
637     case 12:
638       return "bclr\t%0, %1, %b2";
640     default:
641       gcc_unreachable ();
642     }
644   [(set_attr "type"    "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
645    (set_attr "length"  "  2,  4,  2,  2,  2,  2,  2,  2,  4,  4,  4,  4,  4")
646    (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")])
648 (define_insn "*and_slli"
649   [(set (match_operand:SI 0 "register_operand"                        "=   r")
650         (and:SI (ashift:SI (match_operand:SI 1 "register_operand"     "    r")
651                             (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
652                 (match_operand:SI 3 "register_operand"                "    r")))]
653   "TARGET_ISA_V3"
654   "and_slli\t%0, %3, %1, %2"
655   [(set_attr "type" "alu_shift")
656    (set_attr "length"       "4")])
658 (define_insn "*and_srli"
659   [(set (match_operand:SI 0 "register_operand"                         "=   r")
660         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
661                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
662                 (match_operand:SI 3 "register_operand"                 "    r")))]
663   "TARGET_ISA_V3"
664   "and_srli\t%0, %3, %1, %2"
665   [(set_attr "type" "alu_shift")
666    (set_attr "length"       "4")])
669 ;; ----------------------------------------------------------------------------
670 ;; 'OR' operation
671 ;; ----------------------------------------------------------------------------
673 ;; For V3/V3M ISA, we have 'or33' instruction.
674 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
676 (define_expand "iorsi3"
677   [(set (match_operand:SI 0 "register_operand"         "")
678         (ior:SI (match_operand:SI 1 "register_operand" "")
679                 (match_operand:SI 2 "general_operand"  "")))]
680   ""
682   if (!nds32_ior_operand (operands[2], SImode))
683     operands[2] = force_reg (SImode, operands[2]);
686 (define_insn "*iorsi3"
687   [(set (match_operand:SI 0 "register_operand"          "=l, r,    r,    r")
688         (ior:SI (match_operand:SI 1 "register_operand"  "%0, r,    r,    r")
689                 (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))]
690   ""
691   "@
692    or33\t%0, %2
693    or\t%0, %1, %2
694    ori\t%0, %1, %2
695    bset\t%0, %1, %B2"
696   [(set_attr "type"    "alu,alu,alu,alu")
697    (set_attr "length"  "  2,  4,  4,  4")
698    (set_attr "feature" "v3m, v1, v1,pe1")])
700 (define_insn "*or_slli"
701   [(set (match_operand:SI 0 "register_operand"                       "=   r")
702         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand"    "    r")
703                            (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
704                 (match_operand:SI 3 "register_operand"               "    r")))]
705   "TARGET_ISA_V3"
706   "or_slli\t%0, %3, %1, %2"
707   [(set_attr "type" "alu_shift")
708    (set_attr "length"       "4")])
710 (define_insn "*or_srli"
711   [(set (match_operand:SI 0 "register_operand"                         "=   r")
712         (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
713                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
714                 (match_operand:SI 3 "register_operand"                 "    r")))]
715   "TARGET_ISA_V3"
716   "or_srli\t%0, %3, %1, %2"
717   [(set_attr "type" "alu_shift")
718    (set_attr "length"       "4")])
721 ;; ----------------------------------------------------------------------------
722 ;; 'XOR' operation
723 ;; ----------------------------------------------------------------------------
725 ;; For V3/V3M ISA, we have 'xor33' instruction.
726 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
728 (define_expand "xorsi3"
729   [(set (match_operand:SI 0 "register_operand"         "")
730         (xor:SI (match_operand:SI 1 "register_operand" "")
731                 (match_operand:SI 2 "general_operand"  "")))]
732   ""
734   if (!nds32_xor_operand (operands[2], SImode))
735     operands[2] = force_reg (SImode, operands[2]);
738 (define_insn "*xorsi3"
739   [(set (match_operand:SI 0 "register_operand"          "=l, r,    r,    r")
740         (xor:SI (match_operand:SI 1 "register_operand"  "%0, r,    r,    r")
741                 (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))]
742   ""
743   "@
744    xor33\t%0, %2
745    xor\t%0, %1, %2
746    xori\t%0, %1, %2
747    btgl\t%0, %1, %B2"
748   [(set_attr "type"    "alu,alu,alu,alu")
749    (set_attr "length"  "  2,  4,  4,  4")
750    (set_attr "feature" "v3m, v1, v1,pe1")])
752 (define_insn "*xor_slli"
753   [(set (match_operand:SI 0 "register_operand"                     "=   r")
754         (xor:SI (ashift:SI (match_operand:SI 1 "register_operand"  "    r")
755                            (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
756                 (match_operand:SI 3 "register_operand"             "    r")))]
757   "TARGET_ISA_V3"
758   "xor_slli\t%0, %3, %1, %2"
759   [(set_attr "type" "alu_shift")
760    (set_attr "length"       "4")])
762 (define_insn "*xor_srli"
763   [(set (match_operand:SI 0 "register_operand"                         "=   r")
764         (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
765                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
766                 (match_operand:SI 3 "register_operand"                 "    r")))]
767   "TARGET_ISA_V3"
768   "xor_srli\t%0, %3, %1, %2"
769   [(set_attr "type" "alu_shift")
770    (set_attr "length"       "4")])
772 ;; Rotate Right Instructions.
774 (define_insn "*rotrsi3"
775   [(set (match_operand:SI 0 "register_operand"                    "=   r, r")
776           (rotatert:SI (match_operand:SI 1 "register_operand"     "    r, r")
777                        (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
778   ""
779   "@
780    rotri\t%0, %1, %2
781    rotr\t%0, %1, %2"
782   [(set_attr "type"    "  alu,  alu")
783    (set_attr "subtype" "shift,shift")
784    (set_attr "length"  "    4,    4")])
787 ;; ----------------------------------------------------------------------------
788 ;; 'NEG' operation
789 ;; ----------------------------------------------------------------------------
791 ;; For V3/V3M ISA, we have 'neg33' instruction.
792 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
793 ;; And for V2 ISA, there is NO 'neg33' instruction.
794 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
795 (define_insn "negsi2"
796   [(set (match_operand:SI 0 "register_operand"         "=l, r")
797         (neg:SI (match_operand:SI 1 "register_operand" " l, r")))]
798   ""
799   "@
800    neg33\t%0, %1
801    subri\t%0, %1, 0"
802   [(set_attr "type"    "alu,alu")
803    (set_attr "length"  "  2,  4")
804    (set_attr "feature" "v3m, v1")])
806 ;; ----------------------------------------------------------------------------
807 ;; 'ONE_COMPLIMENT' operation
808 ;; ----------------------------------------------------------------------------
810 ;; For V3/V3M ISA, we have 'not33' instruction.
811 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
812 (define_insn "one_cmplsi2"
813   [(set (match_operand:SI 0 "register_operand"         "=w, r")
814         (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
815   ""
816   "@
817    not33\t%0, %1
818    nor\t%0, %1, %1"
819   [(set_attr "type"    "alu,alu")
820    (set_attr "length"  "  2,  4")
821    (set_attr "feature" "v3m, v1")])
824 ;; ----------------------------------------------------------------------------
826 ;; Shift instructions.
828 (define_expand "<shift>si3"
829   [(set (match_operand:SI 0 "register_operand"                      "")
830         (shift_rotate:SI (match_operand:SI 1 "register_operand"     "")
831                          (match_operand:SI 2 "nds32_rimm5u_operand" "")))]
832   ""
834   if (operands[2] == const0_rtx)
835     {
836       emit_move_insn (operands[0], operands[1]);
837       DONE;
838     }
841 (define_insn "*ashlsi3"
842   [(set (match_operand:SI 0 "register_operand"                "=   l,    r, r")
843         (ashift:SI (match_operand:SI 1 "register_operand"     "    l,    r, r")
844                    (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))]
845   ""
846   "@
847    slli333\t%0, %1, %2
848    slli\t%0, %1, %2
849    sll\t%0, %1, %2"
850   [(set_attr "type"    "  alu,  alu,  alu")
851    (set_attr "subtype" "shift,shift,shift")
852    (set_attr "length"  "    2,    4,    4")])
854 (define_insn "*ashrsi3"
855   [(set (match_operand:SI 0 "register_operand"                  "=   d,    r, r")
856         (ashiftrt:SI (match_operand:SI 1 "register_operand"     "    0,    r, r")
857                      (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
858   ""
859   "@
860    srai45\t%0, %2
861    srai\t%0, %1, %2
862    sra\t%0, %1, %2"
863   [(set_attr "type"    "  alu,  alu,  alu")
864    (set_attr "subtype" "shift,shift,shift")
865    (set_attr "length"  "    2,    4,    4")])
867 (define_insn "*lshrsi3"
868   [(set (match_operand:SI 0 "register_operand"                  "=   d,    r, r")
869         (lshiftrt:SI (match_operand:SI 1 "register_operand"     "    0,    r, r")
870                      (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
871   ""
872   "@
873    srli45\t%0, %2
874    srli\t%0, %1, %2
875    srl\t%0, %1, %2"
876   [(set_attr "type"    "  alu,  alu,  alu")
877    (set_attr "subtype" "shift,shift,shift")
878    (set_attr "length"  "    2,    4,    4")])
881 ;; ----------------------------------------------------------------------------
883 ;; ----------------------------------------------------------------------------
884 ;; Conditional Move patterns
885 ;; ----------------------------------------------------------------------------
887 (define_expand "mov<mode>cc"
888   [(set (match_operand:QIHISI 0 "register_operand" "")
889         (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
890                          (match_operand:QIHISI 2 "register_operand" "")
891                          (match_operand:QIHISI 3 "register_operand" "")))]
892   "TARGET_CMOV && !optimize_size"
894   enum nds32_expand_result_type result = nds32_expand_movcc (operands);
895   switch (result)
896     {
897     case EXPAND_DONE:
898       DONE;
899       break;
900     case EXPAND_FAIL:
901       FAIL;
902       break;
903     case EXPAND_CREATE_TEMPLATE:
904       break;
905     default:
906       gcc_unreachable ();
907     }
910 (define_insn "cmovz<mode>"
911   [(set (match_operand:QIHISI 0 "register_operand"                      "=r, r")
912         (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
913                              (const_int 0))
914                          (match_operand:QIHISI 2 "register_operand"     " r, 0")
915                          (match_operand:QIHISI 3 "register_operand"     " 0, r")))]
916   "TARGET_CMOV"
917   "@
918    cmovz\t%0, %2, %1
919    cmovn\t%0, %3, %1"
920   [(set_attr "type"  "alu")
921    (set_attr "length"  "4")])
923 (define_insn "cmovn<mode>"
924   [(set (match_operand:QIHISI 0 "register_operand"                      "=r, r")
925         (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
926                              (const_int 0))
927                          (match_operand:QIHISI 2 "register_operand"     " r, 0")
928                          (match_operand:QIHISI 3 "register_operand"     " 0, r")))]
929   "TARGET_CMOV"
930   "@
931    cmovn\t%0, %2, %1
932    cmovz\t%0, %3, %1"
933   [(set_attr "type"  "alu")
934    (set_attr "length"  "4")])
936 ;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
937 ;; It should be removed once after we change the expansion form of the cmovn.
938 (define_insn "*cmovn_simplified_<mode>"
939   [(set (match_operand:QIHISI 0 "register_operand" "=r")
940         (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
941                          (match_operand:QIHISI 2 "register_operand" "r")
942                          (match_operand:QIHISI 3 "register_operand" "0")))]
943   ""
944   "cmovn\t%0, %2, %1"
945   [(set_attr "type" "alu")])
947 ;; ----------------------------------------------------------------------------
948 ;; Conditional Branch patterns
949 ;; ----------------------------------------------------------------------------
951 (define_expand "cbranchsi4"
952   [(set (pc)
953         (if_then_else (match_operator 0 "comparison_operator"
954                         [(match_operand:SI 1 "register_operand"           "")
955                          (match_operand:SI 2 "nds32_reg_constant_operand" "")])
956                       (label_ref (match_operand 3 "" ""))
957                       (pc)))]
958   ""
960   enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
961   switch (result)
962     {
963     case EXPAND_DONE:
964       DONE;
965       break;
966     case EXPAND_FAIL:
967       FAIL;
968       break;
969     case EXPAND_CREATE_TEMPLATE:
970       break;
971     default:
972       gcc_unreachable ();
973     }
977 (define_insn "cbranchsi4_equality_zero"
978   [(set (pc)
979         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
980                         [(match_operand:SI 1 "register_operand"  "t,l, r")
981                          (const_int 0)])
982                       (label_ref (match_operand 2 "" ""))
983                       (pc)))]
984   ""
986   return nds32_output_cbranchsi4_equality_zero (insn, operands);
988   [(set_attr "type" "branch")
989    (set_attr_alternative "enabled"
990      [
991        ;; Alternative 0
992        (if_then_else (match_test "TARGET_16_BIT")
993                      (const_string "yes")
994                      (const_string "no"))
995        ;; Alternative 1
996        (if_then_else (match_test "TARGET_16_BIT")
997                      (const_string "yes")
998                      (const_string "no"))
999        ;; Alternative 2
1000        (const_string "yes")
1001      ])
1002    (set_attr_alternative "length"
1003      [
1004        ;; Alternative 0
1005        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1006                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1007                                         (le (minus (match_dup 2) (pc)) (const_int  250)))
1008                                    (if_then_else (match_test "TARGET_16_BIT")
1009                                                  (const_int 2)
1010                                                  (const_int 4))
1011                                    (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1012                                                       (le (minus (match_dup 2) (pc)) (const_int  65500)))
1013                                                  (const_int 4)
1014                                                  (if_then_else (match_test "TARGET_16_BIT")
1015                                                                (const_int 8)
1016                                                                (const_int 10))))
1017                      (const_int 10))
1018        ;; Alternative 1
1019        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1020                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1021                                         (le (minus (match_dup 2) (pc)) (const_int  250)))
1022                                    (if_then_else (match_test "TARGET_16_BIT")
1023                                                  (const_int 2)
1024                                                  (const_int 4))
1025                                    (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1026                                                       (le (minus (match_dup 2) (pc)) (const_int  65500)))
1027                                                  (const_int 4)
1028                                                  (if_then_else (match_test "TARGET_16_BIT")
1029                                                                (const_int 8)
1030                                                                (const_int 10))))
1031                      (const_int 10))
1032        ;; Alternative 2
1033        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1034                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1035                                         (le (minus (match_dup 2) (pc)) (const_int  65500)))
1036                                    (const_int 4)
1037                                    (const_int 10))
1038                      (const_int 10))
1039      ])])
1042 ;; This pattern is dedicated to V2 ISA,
1043 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
1044 (define_insn "cbranchsi4_equality_reg"
1045   [(set (pc)
1046         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1047                         [(match_operand:SI 1 "register_operand" "v, r")
1048                          (match_operand:SI 2 "register_operand" "l, r")])
1049                       (label_ref (match_operand 3 "" ""))
1050                       (pc)))]
1051   "TARGET_ISA_V2"
1053   return nds32_output_cbranchsi4_equality_reg (insn, operands);
1055   [(set_attr "type"   "branch")
1056    (set_attr_alternative "enabled"
1057      [
1058        ;; Alternative 0
1059        (if_then_else (match_test "TARGET_16_BIT")
1060                      (const_string "yes")
1061                      (const_string "no"))
1062        ;; Alternative 1
1063        (const_string "yes")
1064      ])
1065    (set_attr_alternative "length"
1066      [
1067        ;; Alternative 0
1068        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1069                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1070                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1071                                    (const_int 2)
1072                                    (if_then_else (and (ge (minus (match_dup 3) (pc))
1073                                                           (const_int -16350))
1074                                                       (le (minus (match_dup 3) (pc))
1075                                                           (const_int  16350)))
1076                                                  (const_int 4)
1077                                                  (const_int 8)))
1078                      (const_int 8))
1079        ;; Alternative 1
1080        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1081                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1082                                         (le (minus (match_dup 3) (pc)) (const_int  16350)))
1083                                    (const_int 4)
1084                                    (const_int 10))
1085                      (const_int 10))
1086      ])])
1089 ;; This pattern is dedicated to V3/V3M,
1090 ;; because V3/V3M DO HAVE beqc/bnec instruction.
1091 (define_insn "cbranchsi4_equality_reg_or_const_int"
1092   [(set (pc)
1093         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1094                         [(match_operand:SI 1 "register_operand"      "v, r,    r")
1095                          (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
1096                       (label_ref (match_operand 3 "" ""))
1097                       (pc)))]
1098   "TARGET_ISA_V3 || TARGET_ISA_V3M"
1100   return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
1102   [(set_attr "type"   "branch")
1103    (set_attr_alternative "enabled"
1104      [
1105        ;; Alternative 0
1106        (if_then_else (match_test "TARGET_16_BIT")
1107                      (const_string "yes")
1108                      (const_string "no"))
1109        ;; Alternative 1
1110        (const_string "yes")
1111        ;; Alternative 2
1112        (const_string "yes")
1113      ])
1114    (set_attr_alternative "length"
1115      [
1116        ;; Alternative 0
1117        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1118                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1119                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1120                                    (const_int 2)
1121                                    (if_then_else (and (ge (minus (match_dup 3) (pc))
1122                                                           (const_int -16350))
1123                                                       (le (minus (match_dup 3) (pc))
1124                                                           (const_int  16350)))
1125                                                  (const_int 4)
1126                                                  (const_int 8)))
1127                     (const_int 8))
1128        ;; Alternative 1
1129        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1130                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1131                                         (le (minus (match_dup 3) (pc)) (const_int  16350)))
1132                                    (const_int 4)
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 3) (pc)) (const_int -250))
1138                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1139                                    (const_int 4)
1140                                    (const_int 10))
1141                     (const_int 10))
1142      ])])
1145 (define_insn "*cbranchsi4_greater_less_zero"
1146   [(set (pc)
1147         (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1148                         [(match_operand:SI 1 "register_operand" "r")
1149                          (const_int 0)])
1150                       (label_ref (match_operand 2 "" ""))
1151                       (pc)))]
1152   ""
1154   return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
1156   [(set_attr "type"   "branch")
1157    (set (attr "length")
1158         (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1159                       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1160                                          (le (minus (match_dup 2) (pc)) (const_int  65500)))
1161                                     (const_int 4)
1162                                     (const_int 10))
1163                       (const_int 10)))])
1166 (define_expand "cstoresi4"
1167   [(set (match_operand:SI 0 "register_operand" "")
1168         (match_operator:SI 1 "comparison_operator"
1169           [(match_operand:SI 2 "register_operand" "")
1170            (match_operand:SI 3 "nonmemory_operand" "")]))]
1171   ""
1173   enum nds32_expand_result_type result = nds32_expand_cstore (operands);
1174   switch (result)
1175     {
1176     case EXPAND_DONE:
1177       DONE;
1178       break;
1179     case EXPAND_FAIL:
1180       FAIL;
1181       break;
1182     case EXPAND_CREATE_TEMPLATE:
1183       break;
1184     default:
1185       gcc_unreachable ();
1186     }
1190 (define_expand "slts_compare"
1191   [(set (match_operand:SI 0 "register_operand"       "")
1192         (lt:SI (match_operand:SI 1 "general_operand" "")
1193                (match_operand:SI 2 "general_operand" "")))]
1194   ""
1196   if (!REG_P (operands[1]))
1197     operands[1] = force_reg (SImode, operands[1]);
1199   if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1200     operands[2] = force_reg (SImode, operands[2]);
1203 (define_insn "slts_compare_impl"
1204   [(set (match_operand:SI 0 "register_operand"             "=t,   t, r,    r")
1205         (lt:SI (match_operand:SI 1 "register_operand"      " d,   d, r,    r")
1206                (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
1207   ""
1208   "@
1209    slts45\t%1, %2
1210    sltsi45\t%1, %2
1211    slts\t%0, %1, %2
1212    sltsi\t%0, %1, %2"
1213   [(set_attr "type"   "alu,    alu,    alu,    alu")
1214    (set_attr "length" "  2,      2,      4,      4")])
1216 (define_insn "slt_eq0"
1217   [(set (match_operand:SI 0 "register_operand"        "=t, r")
1218         (eq:SI (match_operand:SI 1 "register_operand" " d, r")
1219                (const_int 0)))]
1220   ""
1221   "@
1222    slti45\t%1, 1
1223    slti\t%0, %1, 1"
1224   [(set_attr "type"   "alu, alu")
1225    (set_attr "length" "  2,   4")])
1227 (define_expand "slt_compare"
1228   [(set (match_operand:SI 0 "register_operand"        "")
1229         (ltu:SI (match_operand:SI 1 "general_operand" "")
1230                 (match_operand:SI 2 "general_operand" "")))]
1231   ""
1233   if (!REG_P (operands[1]))
1234     operands[1] = force_reg (SImode, operands[1]);
1236   if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1237     operands[2] = force_reg (SImode, operands[2]);
1240 (define_insn "slt_compare_impl"
1241   [(set (match_operand:SI 0 "register_operand"              "=t,    t, r,    r")
1242         (ltu:SI (match_operand:SI 1 "register_operand"      " d,    d, r,    r")
1243                 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
1244   ""
1245   "@
1246    slt45\t%1, %2
1247    slti45\t%1, %2
1248    slt\t%0, %1, %2
1249    slti\t%0, %1, %2"
1250   [(set_attr "type"   "alu,    alu,    alu,    alu")
1251    (set_attr "length" "  2,      2,      4,      4")])
1254 ;; ----------------------------------------------------------------------------
1256 ;; Unconditional and other jump instructions.
1258 (define_insn "jump"
1259   [(set (pc) (label_ref (match_operand 0 "" "")))]
1260   ""
1262   /* This unconditional jump has two forms:
1263        32-bit instruction => j   imm24s << 1
1264        16-bit instruction => j8  imm8s << 1
1266      For 32-bit case,
1267      we assume it is always reachable.
1268      For 16-bit case,
1269      it must satisfy { 255 >= (label - pc) >= -256 } condition.
1270      However, since the $pc for nds32 is at the beginning of the instruction,
1271      we should leave some length space for current insn.
1272      So we use range -250 ~ 250.  */
1273   switch (get_attr_length (insn))
1274     {
1275     case 2:
1276       return "j8\t%0";
1277     case 4:
1278       return "j\t%0";
1279     default:
1280       gcc_unreachable ();
1281     }
1283   [(set_attr "type" "branch")
1284    (set_attr "enabled" "yes")
1285    (set (attr "length")
1286         (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1287                       (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1288                                          (le (minus (match_dup 0) (pc)) (const_int  250)))
1289                                     (if_then_else (match_test "TARGET_16_BIT")
1290                                                   (const_int 2)
1291                                                   (const_int 4))
1292                                     (const_int 4))
1293                       (const_int 4)))])
1295 (define_insn "indirect_jump"
1296   [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1297   ""
1298   "@
1299    jr5\t%0
1300    jr\t%0"
1301   [(set_attr "type"   "branch,branch")
1302    (set_attr "length" "     2,     4")])
1304 ;; Subroutine call instruction returning no value.
1305 ;;   operands[0]: It should be a mem RTX whose address is
1306 ;;                the address of the function.
1307 ;;   operands[1]: It is the number of bytes of arguments pushed as a const_int.
1308 ;;   operands[2]: It is the number of registers used as operands.
1310 (define_expand "call"
1311   [(parallel [(call (match_operand 0 "memory_operand" "")
1312                     (match_operand 1))
1313               (clobber (reg:SI LP_REGNUM))
1314               (clobber (reg:SI TA_REGNUM))])]
1315   ""
1316   ""
1319 (define_insn "*call_register"
1320   [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
1321                     (match_operand 1))
1322               (clobber (reg:SI LP_REGNUM))
1323               (clobber (reg:SI TA_REGNUM))])]
1324   ""
1325   "@
1326   jral5\t%0
1327   jral\t%0"
1328   [(set_attr "type"   "branch,branch")
1329    (set_attr "length" "     2,     4")])
1331 (define_insn "*call_immediate"
1332   [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
1333                     (match_operand 1))
1334               (clobber (reg:SI LP_REGNUM))
1335               (clobber (reg:SI TA_REGNUM))])]
1336   ""
1338   if (TARGET_CMODEL_LARGE)
1339     return "bal\t%0";
1340   else
1341     return "jal\t%0";
1343   [(set_attr "type"   "branch")
1344    (set (attr "length")
1345         (if_then_else (match_test "TARGET_CMODEL_LARGE")
1346                       (const_int 12)
1347                       (const_int 4)))])
1350 ;; Subroutine call instruction returning a value.
1351 ;;   operands[0]: It is the hard regiser in which the value is returned.
1352 ;;   The rest three operands are the same as the
1353 ;;   three operands of the 'call' instruction.
1354 ;;   (but with numbers increased by one)
1356 (define_expand "call_value"
1357   [(parallel [(set (match_operand 0)
1358                    (call (match_operand 1 "memory_operand" "")
1359                          (match_operand 2)))
1360               (clobber (reg:SI LP_REGNUM))
1361               (clobber (reg:SI TA_REGNUM))])]
1362   ""
1363   ""
1366 (define_insn "*call_value_register"
1367   [(parallel [(set (match_operand 0)
1368                    (call (mem (match_operand:SI 1 "register_operand" "r, r"))
1369                          (match_operand 2)))
1370               (clobber (reg:SI LP_REGNUM))
1371               (clobber (reg:SI TA_REGNUM))])]
1372   ""
1373   "@
1374   jral5\t%1
1375   jral\t%1"
1376   [(set_attr "type"   "branch,branch")
1377    (set_attr "length" "     2,     4")])
1379 (define_insn "*call_value_immediate"
1380   [(parallel [(set (match_operand 0)
1381                    (call (mem (match_operand:SI 1 "immediate_operand" "i"))
1382                          (match_operand 2)))
1383               (clobber (reg:SI LP_REGNUM))
1384               (clobber (reg:SI TA_REGNUM))])]
1385   ""
1387   if (TARGET_CMODEL_LARGE)
1388     return "bal\t%1";
1389   else
1390     return "jal\t%1";
1392   [(set_attr "type"   "branch")
1393    (set (attr "length")
1394         (if_then_else (match_test "TARGET_CMODEL_LARGE")
1395                       (const_int 12)
1396                       (const_int 4)))])
1399 ;; ----------------------------------------------------------------------------
1401 ;; The sibcall patterns.
1403 ;; sibcall
1404 ;; sibcall_internal
1406 (define_expand "sibcall"
1407   [(parallel [(call (match_operand 0 "memory_operand" "")
1408                     (const_int 0))
1409               (clobber (reg:SI TA_REGNUM))
1410               (return)])]
1411   "")
1413 (define_insn "sibcall_internal"
1414   [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
1415                     (match_operand 1))
1416               (clobber (reg:SI TA_REGNUM))
1417               (return)])]
1418   ""
1420   switch (which_alternative)
1421     {
1422     case 0:
1423       if (TARGET_16_BIT)
1424         return "jr5\t%0";
1425       else
1426         return "jr\t%0";
1427     case 1:
1428       if (nds32_long_call_p (operands[0]))
1429         return "b\t%0";
1430       else
1431         return "j\t%0";
1432     default:
1433       gcc_unreachable ();
1434     }
1436   [(set_attr "enabled" "yes")
1437    (set_attr "type" "branch")
1438    (set_attr_alternative "length"
1439      [
1440        ;; Alternative 0
1441        (if_then_else (match_test "TARGET_16_BIT")
1442                      (const_int 2)
1443                      (const_int 4))
1444        ;; Alternative 1
1445        (if_then_else (match_test "nds32_long_call_p (operands[0])")
1446                      (const_int 12)
1447                      (const_int 4))
1448      ])]
1451 ;; sibcall_value
1452 ;; sibcall_value_internal
1453 ;; sibcall_value_immediate
1455 (define_expand "sibcall_value"
1456   [(parallel [(set (match_operand 0)
1457                    (call (match_operand 1 "memory_operand" "")
1458                          (const_int 0)))
1459               (clobber (reg:SI TA_REGNUM))
1460               (return)])]
1461   "")
1463 (define_insn "sibcall_value_internal"
1464   [(parallel [(set (match_operand 0)
1465                    (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
1466                          (match_operand 2)))
1467               (clobber (reg:SI TA_REGNUM))
1468               (return)])]
1469   ""
1471   switch (which_alternative)
1472     {
1473     case 0:
1474       if (TARGET_16_BIT)
1475         return "jr5\t%1";
1476       else
1477         return "jr\t%1";
1478     case 1:
1479       if (nds32_long_call_p (operands[1]))
1480         return "b\t%1";
1481       else
1482         return "j\t%1";
1483     default:
1484       gcc_unreachable ();
1485     }
1487   [(set_attr "enabled" "yes")
1488    (set_attr "type" "branch")
1489    (set_attr_alternative "length"
1490      [
1491        ;; Alternative 0
1492        (if_then_else (match_test "TARGET_16_BIT")
1493                      (const_int 2)
1494                      (const_int 4))
1495        ;; Alternative 1
1496        (if_then_else (match_test "nds32_long_call_p (operands[1])")
1497                      (const_int 12)
1498                      (const_int 4))
1499      ])]
1502 ;; ----------------------------------------------------------------------------
1504 ;; prologue and epilogue.
1506 (define_expand "prologue" [(const_int 0)]
1507   ""
1509   /* Note that only under V3/V3M ISA, we could use v3push prologue.
1510      In addition, we need to check if v3push is indeed available.  */
1511   if (NDS32_V3PUSH_AVAILABLE_P)
1512     nds32_expand_prologue_v3push ();
1513   else
1514     nds32_expand_prologue ();
1515   DONE;
1518 (define_expand "epilogue" [(const_int 0)]
1519   ""
1521   /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
1522      In addition, we need to check if v3push is indeed available.  */
1523   if (NDS32_V3PUSH_AVAILABLE_P)
1524     nds32_expand_epilogue_v3pop (false);
1525   else
1526     nds32_expand_epilogue (false);
1527   DONE;
1530 (define_expand "sibcall_epilogue" [(const_int 0)]
1531   ""
1533   /* Pass true to indicate that this is sibcall epilogue and
1534      exit from a function without the final branch back to the
1535      calling function.  */
1536   nds32_expand_epilogue (true);
1538   DONE;
1542 ;; nop instruction.
1544 (define_insn "nop"
1545   [(const_int 0)]
1546   ""
1548   if (TARGET_16_BIT)
1549     return "nop16";
1550   else
1551     return "nop";
1553   [(set_attr "type" "misc")
1554    (set_attr "enabled" "yes")
1555    (set (attr "length")
1556         (if_then_else (match_test "TARGET_16_BIT")
1557                       (const_int 2)
1558                       (const_int 4)))])
1561 ;; ----------------------------------------------------------------------------
1562 ;; Stack push/pop operations
1563 ;; ----------------------------------------------------------------------------
1565 ;; The pattern for stack push.
1566 ;; Both stack_push_multiple and stack_v3push use the following pattern.
1567 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1568 (define_insn "*stack_push"
1569   [(match_parallel 0 "nds32_stack_push_operation"
1570      [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1571                             (match_operand:SI 1 "const_int_operand" "")))
1572            (match_operand:SI 2 "register_operand" ""))
1573      ])]
1574   ""
1576   return nds32_output_stack_push (operands[0]);
1578   [(set_attr "type" "store_multiple")
1579    (set_attr "combo" "12")
1580    (set_attr "enabled" "yes")
1581    (set (attr "length")
1582         (if_then_else (match_test "TARGET_V3PUSH
1583                                    && !nds32_isr_function_p (cfun->decl)
1584                                    && (cfun->machine->va_args_size == 0)")
1585                       (const_int 2)
1586                       (const_int 4)))])
1589 ;; The pattern for stack pop.
1590 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1591 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1592 (define_insn "*stack_pop"
1593   [(match_parallel 0 "nds32_stack_pop_operation"
1594      [(set (match_operand:SI 1 "register_operand" "")
1595            (mem:SI (reg:SI SP_REGNUM)))
1596      ])]
1597   ""
1599   return nds32_output_stack_pop (operands[0]);
1601   [(set_attr "type" "load_multiple")
1602    (set_attr "combo" "12")
1603    (set_attr "enabled" "yes")
1604    (set (attr "length")
1605         (if_then_else (match_test "TARGET_V3PUSH
1606                                    && !nds32_isr_function_p (cfun->decl)
1607                                    && (cfun->machine->va_args_size == 0)")
1608                       (const_int 2)
1609                       (const_int 4)))])
1612 ;; ----------------------------------------------------------------------------
1613 ;; Return operation patterns
1614 ;; ----------------------------------------------------------------------------
1616 ;; Use this pattern to expand a return instruction
1617 ;; with simple_return rtx if no epilogue is required.
1618 (define_expand "return"
1619   [(simple_return)]
1620   "nds32_can_use_return_insn ()"
1621   ""
1624 ;; This pattern is expanded only by the shrink-wrapping optimization
1625 ;; on paths where the function prologue has not been executed.
1626 (define_expand "simple_return"
1627   [(simple_return)]
1628   ""
1629   ""
1632 (define_insn "return_internal"
1633   [(simple_return)]
1634   ""
1636   if (TARGET_16_BIT)
1637     return "ret5";
1638   else
1639     return "ret";
1641   [(set_attr "type" "branch")
1642    (set_attr "enabled" "yes")
1643    (set (attr "length")
1644         (if_then_else (match_test "TARGET_16_BIT")
1645                       (const_int 2)
1646                       (const_int 4)))])
1649 ;; ----------------------------------------------------------------------------
1650 ;; Jump Table patterns
1651 ;; ----------------------------------------------------------------------------
1652 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
1653 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
1655 ;; operands[0]: The index to dispatch on.
1656 ;; operands[1]: The lower bound for indices in the table.
1657 ;; operands[2]: The total range of indices int the table.
1658 ;;              i.e. The largest index minus the smallest one.
1659 ;; operands[3]: A label that precedes the table itself.
1660 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
1662 ;; We need to create following sequences for jump table code generation:
1663 ;;   A) k <-- (plus (operands[0]) (-operands[1]))
1664 ;;   B) if (gtu k operands[2]) then goto operands[4]
1665 ;;   C) t <-- operands[3]
1666 ;;   D) z <-- (mem (plus (k << 0 or 1 or 2) t))
1667 ;;   E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
1668 ;;   F) jump to target with register t or z
1670 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
1671 (define_expand "casesi"
1672   [(match_operand:SI 0 "register_operand"  "r") ; index to jump on
1673    (match_operand:SI 1 "immediate_operand" "i") ; lower bound
1674    (match_operand:SI 2 "immediate_operand" "i") ; total range
1675    (match_operand:SI 3 "" "")                   ; table label
1676    (match_operand:SI 4 "" "")]                  ; Out of range label
1677   ""
1679   rtx add_tmp;
1680   rtx reg, test;
1682   /* Step A: "k <-- (plus (operands[0]) (-operands[1]))".  */
1683   if (operands[1] != const0_rtx)
1684     {
1685       reg = gen_reg_rtx (SImode);
1686       add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
1688       /* If the integer value is not in the range of imm15s,
1689          we need to force register first because our addsi3 pattern
1690          only accept nds32_rimm15s_operand predicate.  */
1691       add_tmp = force_reg (SImode, add_tmp);
1693       emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
1694       operands[0] = reg;
1695     }
1697   /* Step B: "if (gtu k operands[2]) then goto operands[4]".  */
1698   test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
1699   emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
1700                                   operands[4]));
1702   /* Step C, D, E, and F, using another temporary register.  */
1703   rtx tmp = gen_reg_rtx (SImode);
1704   emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
1705   DONE;
1708 ;; We are receiving operands from casesi pattern:
1710 ;; operands[0]: The index that have been substracted with lower bound.
1711 ;; operands[1]: A label that precedes the table itself.
1712 ;; operands[2]: A temporary register to retrieve value in table.
1714 ;; We need to perform steps C, D, E, and F:
1716 ;;   C) t <-- operands[1]
1717 ;;   D) z <-- (mem (plus (operands[0] << m) t))
1718 ;;            m is 2 for normal jump table.
1719 ;;            m is 0, 1, or 2 for pc relative jump table based on diff size.
1720 ;;   E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
1721 ;;   F) Jump to target with register t or z.
1723 ;; The USE in this pattern is needed to tell flow analysis that this is
1724 ;; a CASESI insn.  It has no other purpose.
1725 (define_insn "casesi_internal"
1726   [(parallel [(set (pc)
1727                    (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1728                                              (const_int 4))
1729                                     (label_ref (match_operand 1 "" "")))))
1730               (use (label_ref (match_dup 1)))
1731               (clobber (match_operand:SI 2 "register_operand" "=r"))
1732               (clobber (reg:SI TA_REGNUM))])]
1733   ""
1735   if (CASE_VECTOR_PC_RELATIVE)
1736     return nds32_output_casesi_pc_relative (operands);
1737   else
1738     return nds32_output_casesi (operands);
1740   [(set_attr "length" "20")
1741    (set_attr "type" "branch")])
1743 ;; ----------------------------------------------------------------------------
1745 ;; Performance Extension
1747 (define_insn "clzsi2"
1748   [(set (match_operand:SI 0 "register_operand"         "=r")
1749         (clz:SI (match_operand:SI 1 "register_operand" " r")))]
1750   "TARGET_EXT_PERF"
1751   "clz\t%0, %1"
1752   [(set_attr "type" "alu")
1753    (set_attr "length" "4")])
1755 (define_insn "smaxsi3"
1756   [(set (match_operand:SI 0 "register_operand"          "=r")
1757         (smax:SI (match_operand:SI 1 "register_operand" " r")
1758                  (match_operand:SI 2 "register_operand" " r")))]
1759   "TARGET_EXT_PERF"
1760   "max\t%0, %1, %2"
1761   [(set_attr "type" "alu")
1762    (set_attr "length" "4")])
1764 (define_insn "sminsi3"
1765   [(set (match_operand:SI 0 "register_operand"          "=r")
1766         (smin:SI (match_operand:SI 1 "register_operand" " r")
1767                  (match_operand:SI 2 "register_operand" " r")))]
1768   "TARGET_EXT_PERF"
1769   "min\t%0, %1, %2"
1770   [(set_attr "type" "alu")
1771    (set_attr "length" "4")])
1773 (define_insn "*btst"
1774   [(set (match_operand:SI 0 "register_operand"                   "=   r")
1775         (zero_extract:SI (match_operand:SI 1 "register_operand"  "    r")
1776                          (const_int 1)
1777                          (match_operand:SI 2 "immediate_operand" " Iu05")))]
1778   "TARGET_EXT_PERF"
1779   "btst\t%0, %1, %2"
1780   [(set_attr "type" "alu")
1781    (set_attr "length" "4")])
1783 ;; ----------------------------------------------------------------------------
1785 ;; Pseudo NOPs
1787 (define_insn "relax_group"
1788   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
1789   ""
1790   ".relax_hint %0"
1791   [(set_attr "length" "0")]
1794 (define_insn "pop25return"
1795   [(return)
1796    (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
1797   ""
1798   "! return for pop 25"
1799   [(set_attr "length" "0")]
1802 ;; ----------------------------------------------------------------------------