Daily bump.
[official-gcc.git] / gcc / config / nds32 / nds32.md
blob63e4efe23da175145aeaed2ce9d0d6a1976edb03
1 ;; Machine description of Andes NDS32 cpu for GNU compiler
2 ;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 ;; Contributed by Andes Technology Corporation.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 ;; Include predicates definition.
24 (include "predicates.md")
26 ;; Include constraints definition.
27 (include "constraints.md")
29 ;; Include iterators definition.
30 (include "iterators.md")
32 ;; Include pipelines definition.
33 (include "pipelines.md")
36 ;; Include constants definition.
37 (include "constants.md")
40 ;; Include intrinsic functions definition.
41 (include "nds32-intrinsic.md")
43 ;; Include block move for nds32 multiple load/store behavior.
44 (include "nds32-multiple.md")
46 ;; Include DImode/DFmode operations.
47 (include "nds32-doubleword.md")
49 ;; Include floating-point patterns.
50 (include "nds32-fpu.md")
52 ;; Include peephole patterns.
53 (include "nds32-peephole2.md")
56 ;; ------------------------------------------------------------------------
58 ;; CPU pipeline model.
59 (define_attr "pipeline_model" "n7,n8,e8,n9,n10,graywolf,n13,simple"
60   (const
61     (cond [(match_test "nds32_cpu_option == CPU_N7")  (const_string "n7")
62            (match_test "nds32_cpu_option == CPU_E8")  (const_string "e8")
63            (match_test "nds32_cpu_option == CPU_N6 || nds32_cpu_option == CPU_N8")  (const_string "n8")
64            (match_test "nds32_cpu_option == CPU_N9")  (const_string "n9")
65            (match_test "nds32_cpu_option == CPU_N10") (const_string "n10")
66            (match_test "nds32_cpu_option == CPU_GRAYWOLF") (const_string "graywolf")
67            (match_test "nds32_cpu_option == CPU_N12") (const_string "n13")
68            (match_test "nds32_cpu_option == CPU_N13") (const_string "n13")
69            (match_test "nds32_cpu_option == CPU_SIMPLE") (const_string "simple")]
70           (const_string "n9"))))
72 ;; Insn type, it is used to default other attribute values.
73 (define_attr "type"
74   "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\
75    falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore,\
76    dalu,dalu64,daluround,dcmp,dclip,dmul,dmac,dinsb,dpack,dbpick,dwext"
77   (const_string "unknown"))
79 ;; Insn sub-type
80 (define_attr "subtype"
81   "simple,shift,saturation"
82   (const_string "simple"))
84 ;; Length, in bytes, default is 4-bytes.
85 (define_attr "length" "" (const_int 4))
87 ;; Indicate the amount of micro instructions.
88 (define_attr "combo"
89   "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"
90   (const_string "1"))
92 ;; Insn in which feature set, it is used to enable/disable insn alternatives.
93 ;; v1  : Baseline Instructions
94 ;; v2  : Baseline Version 2 Instructions
95 ;; v3m : Baseline Version 3m Instructions
96 ;; v3  : Baseline Version 3 Instructions
97 ;; pe1 : Performance Extension Instructions
98 ;; pe2 : Performance Extension Version 2 Instructions
99 ;; se  : String Extension instructions
100 (define_attr "feature"
101   "v1,v2,v3m,v3,pe1,pe2,se,fpu"
102   (const_string "v1"))
104 ;; Enabled, which is used to enable/disable insn alternatives.
105 ;; Note that we use length and TARGET_16_BIT here as criteria.
106 ;; If the instruction pattern already check TARGET_16_BIT to determine
107 ;; the length by itself, its enabled attribute should be customized to
108 ;; avoid the conflict between length attribute and this default setting.
109 (define_attr "enabled" "no,yes"
110   (if_then_else
111     (and (eq_attr "length" "2")
112          (match_test "!TARGET_16_BIT"))
113     (const_string "no")
114     (cond [(eq_attr "feature" "v1")   (const_string "yes")
115            (eq_attr "feature" "v2")   (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M")
116                                                     (const_string "yes")
117                                                     (const_string "no"))
118            (eq_attr "feature" "v3")   (if_then_else (match_test "TARGET_ISA_V3")
119                                                     (const_string "yes")
120                                                     (const_string "no"))
121            (eq_attr "feature" "v3m")  (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M")
122                                                     (const_string "yes")
123                                                     (const_string "no"))
124            (eq_attr "feature" "pe1")  (if_then_else (match_test "TARGET_EXT_PERF")
125                                                     (const_string "yes")
126                                                     (const_string "no"))
127            (eq_attr "feature" "pe2")  (if_then_else (match_test "TARGET_EXT_PERF2")
128                                                     (const_string "yes")
129                                                     (const_string "no"))
130            (eq_attr "feature" "se")   (if_then_else (match_test "TARGET_EXT_STRING")
131                                                     (const_string "yes")
132                                                     (const_string "no"))
133            (eq_attr "feature" "fpu")  (if_then_else (match_test "TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE")
134                                                     (const_string "yes")
135                                                     (const_string "no"))]
136            (const_string "yes"))))
139 ;; ----------------------------------------------------------------------------
141 (include "nds32-dspext.md")
143 ;; Move instructions.
145 ;; For QImode and HImode, the immediate value can be fit in imm20s.
146 ;; So there is no need to split rtx for QI and HI patterns.
148 (define_expand "mov<mode>"
149   [(set (match_operand:QIHI 0 "general_operand" "")
150         (match_operand:QIHI 1 "general_operand" ""))]
151   ""
153   /* Need to force register if mem <- !reg.  */
154   if (MEM_P (operands[0]) && !REG_P (operands[1]))
155     operands[1] = force_reg (<MODE>mode, operands[1]);
157   if (MEM_P (operands[1]) && optimize > 0)
158     {
159       rtx reg = gen_reg_rtx (SImode);
161       emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
162       operands[1] = gen_lowpart (<MODE>mode, reg);
163     }
166 (define_expand "movmisalign<mode>"
167   [(set (match_operand:SIDI 0 "general_operand" "")
168         (match_operand:SIDI 1 "general_operand" ""))]
169   ""
171   rtx addr;
172   if (MEM_P (operands[0]) && !REG_P (operands[1]))
173     operands[1] = force_reg (<MODE>mode, operands[1]);
175   if (MEM_P (operands[0]))
176     {
177       addr = force_reg (Pmode, XEXP (operands[0], 0));
178       emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
179     }
180   else
181     {
182       addr = force_reg (Pmode, XEXP (operands[1], 0));
183       emit_insn (gen_unaligned_load<mode> (operands[0], addr));
184     }
185   DONE;
188 (define_expand "movsi"
189   [(set (match_operand:SI 0 "general_operand" "")
190         (match_operand:SI 1 "general_operand" ""))]
191   ""
193   /* Need to force register if mem <- !reg.  */
194   if (MEM_P (operands[0]) && !REG_P (operands[1]))
195     operands[1] = force_reg (SImode, operands[1]);
197   /* If operands[1] is a large constant and cannot be performed
198      by a single instruction, we need to split it.  */
199   if (CONST_INT_P (operands[1])
200       && !satisfies_constraint_Is20 (operands[1])
201       && !satisfies_constraint_Ihig (operands[1]))
202     {
203       rtx high20_rtx;
204       HOST_WIDE_INT low12_int;
205       rtx tmp_rtx;
207       tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
209       high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
210       low12_int = INTVAL (operands[1]) & 0xfff;
212       emit_move_insn (tmp_rtx, high20_rtx);
213       emit_move_insn (operands[0], plus_constant (SImode,
214                                                   tmp_rtx,
215                                                   low12_int));
216       DONE;
217     }
219   if ((REG_P (operands[0]) || GET_CODE (operands[0]) == SUBREG)
220        && SYMBOLIC_CONST_P (operands[1]))
221     {
222       if (TARGET_ICT_MODEL_LARGE
223           && nds32_indirect_call_referenced_p (operands[1]))
224         {
225           nds32_expand_ict_move (operands);
226           DONE;
227         }
228       else if (nds32_tls_referenced_p (operands [1]))
229         {
230           nds32_expand_tls_move (operands);
231           DONE;
232         }
233       else if (flag_pic)
234         {
235           nds32_expand_pic_move (operands);
236           DONE;
237         }
238     }
241 (define_insn "*mov<mode>"
242   [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r,U45,U33,U37,U45, m,  l,  l,  l,  d,  d, r,   d,    r,    r,    r, *f, *f,  r, *f,  Q")
243         (match_operand:QIHISI 1 "nds32_move_operand"   " r, r,  l,  l,  l,  d, r,U45,U33,U37,U45,Ufe, m,Ip05, Is05, Is20, Ihig, *f,  r, *f,  Q, *f"))]
244   "register_operand(operands[0], <MODE>mode)
245    || register_operand(operands[1], <MODE>mode)"
247   switch (which_alternative)
248     {
249     case 0:
250       return "mov55\t%0, %1";
251     case 1:
252       return "ori\t%0, %1, 0";
253     case 2:
254     case 3:
255     case 4:
256     case 5:
257       return nds32_output_16bit_store (operands, <byte>);
258     case 6:
259       return nds32_output_32bit_store (operands, <byte>);
260     case 7:
261     case 8:
262     case 9:
263     case 10:
264     case 11:
265       return nds32_output_16bit_load (operands, <byte>);
266     case 12:
267       return nds32_output_32bit_load (operands, <byte>);
268     case 13:
269       return "movpi45\t%0, %1";
270     case 14:
271       return "movi55\t%0, %1";
272     case 15:
273       return "movi\t%0, %1";
274     case 16:
275       return "sethi\t%0, hi20(%1)";
276     case 17:
277       if (TARGET_FPU_SINGLE)
278         return "fcpyss\t%0, %1, %1";
279       else
280         return "#";
281     case 18:
282       return "fmtsr\t%1, %0";
283     case 19:
284       return "fmfsr\t%0, %1";
285     case 20:
286       return nds32_output_float_load (operands);
287     case 21:
288       return nds32_output_float_store (operands);
289     default:
290       gcc_unreachable ();
291     }
293   [(set_attr "type"    "alu,alu,store,store,store,store,store,load,load,load,load,load,load,alu,alu,alu,alu,fcpy,fmtsr,fmfsr,fload,fstore")
294    (set_attr "length"  "  2,  4,    2,    2,    2,    2,    4,   2,   2,   2,   2,   2,   4,  2,  2,  4,  4,   4,    4,    4,    4,     4")
295    (set_attr "feature" " v1, v1,   v1,   v1,   v1,   v1,   v1,  v1,  v1,  v1,  v1, v3m,  v1, v1, v1, v1, v1, fpu,  fpu,  fpu,  fpu,   fpu")])
298 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
299 ;; are able to match such instruction template.
300 (define_insn "move_addr"
301   [(set (match_operand:SI 0 "nds32_general_register_operand"   "=l, r")
302         (match_operand:SI 1 "nds32_nonunspec_symbolic_operand" " i, i"))]
303   ""
304   "la\t%0, %1"
305   [(set_attr "type"  "alu")
306    (set_attr "length"  "8")])
309 (define_insn "sethi"
310   [(set (match_operand:SI 0 "register_operand"                "=r")
311         (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
312   ""
313   "sethi\t%0, hi20(%1)"
314   [(set_attr "type" "alu")
315    (set_attr "length" "4")])
318 (define_insn "lo_sum"
319   [(set (match_operand:SI 0 "register_operand"                  "=r")
320         (lo_sum:SI (match_operand:SI 1 "register_operand"       " r")
321                    (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
322   ""
323   "ori\t%0, %1, lo12(%2)"
324   [(set_attr "type" "alu")
325    (set_attr "length" "4")])
328 ;; ----------------------------------------------------------------------------
330 ;; Zero extension instructions.
332 (define_insn "zero_extend<mode>si2"
333   [(set (match_operand:SI 0 "register_operand"                       "=l, r,   l, *r")
334         (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33,  m")))]
335   ""
337   switch (which_alternative)
338     {
339     case 0:
340       return "ze<size>33\t%0, %1";
341     case 1:
342       return "ze<size>\t%0, %1";
343     case 2:
344       return nds32_output_16bit_load (operands, <byte>);
345     case 3:
346       return nds32_output_32bit_load (operands, <byte>);
348     default:
349       gcc_unreachable ();
350     }
352   [(set_attr "type"   "alu,alu,load,load")
353    (set_attr "length" "  2,  4,   2,   4")])
356 ;; Sign extension instructions.
358 (define_insn "extend<mode>si2"
359   [(set (match_operand:SI 0 "register_operand"                       "=l, r, r")
360         (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
361   ""
363   switch (which_alternative)
364     {
365     case 0:
366       return "se<size>33\t%0, %1";
367     case 1:
368       return "se<size>\t%0, %1";
369     case 2:
370       return nds32_output_32bit_load_s (operands, <byte>);
372     default:
373       gcc_unreachable ();
374     }
376   [(set_attr "type"   "alu,alu,load")
377    (set_attr "length" "  2,  4,   4")])
380 ;; ----------------------------------------------------------------------------
381 (define_expand "extv"
382   [(set (match_operand 0 "register_operand" "")
383         (sign_extract (match_operand 1 "nonimmediate_operand" "")
384                       (match_operand 2 "const_int_operand" "")
385                       (match_operand 3 "const_int_operand" "")))]
386   ""
388   enum nds32_expand_result_type result = nds32_expand_extv (operands);
389   switch (result)
390     {
391     case EXPAND_DONE:
392       DONE;
393       break;
394     case EXPAND_FAIL:
395       FAIL;
396       break;
397     case EXPAND_CREATE_TEMPLATE:
398       break;
399     default:
400       gcc_unreachable ();
401     }
404 (define_expand "insv"
405   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
406                       (match_operand 1 "const_int_operand" "")
407                       (match_operand 2 "const_int_operand" ""))
408         (match_operand 3 "register_operand" ""))]
409   ""
411   enum nds32_expand_result_type result = nds32_expand_insv (operands);
412   switch (result)
413     {
414     case EXPAND_DONE:
415       DONE;
416       break;
417     case EXPAND_FAIL:
418       FAIL;
419       break;
420     case EXPAND_CREATE_TEMPLATE:
421       break;
422     default:
423       gcc_unreachable ();
424     }
427 ;; Arithmetic instructions.
429 (define_insn "addsi3"
430   [(set (match_operand:SI 0 "register_operand"               "=   d,   l,   d,   l, d, l,   k,   l,    r, r")
431         (plus:SI (match_operand:SI 1 "register_operand"      "%   0,   l,   0,   l, 0, l,   0,   k,    r, r")
432                  (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,IU06, Is15, r")))]
433   ""
435   switch (which_alternative)
436     {
437     case 0:
438       /* addi Rt4,Rt4,-x  ==>  subi45 Rt4,x
439          where 0 <= x <= 31 */
440       operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
441       return "subi45\t%0, %2";
442     case 1:
443       /* addi Rt3,Ra3,-x  ==>  subi333 Rt3,Ra3,x
444          where 0 <= x <= 7 */
445       operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
446       return "subi333\t%0, %1, %2";
447     case 2:
448       return "addi45\t%0, %2";
449     case 3:
450       return "addi333\t%0, %1, %2";
451     case 4:
452       return "add45\t%0, %2";
453     case 5:
454       return "add333\t%0, %1, %2";
455     case 6:
456       return "addi10.sp\t%2";
457     case 7:
458       return "addri36.sp\t%0, %2";
459     case 8:
460       return "addi\t%0, %1, %2";
461     case 9:
462       return "add\t%0, %1, %2";
464     default:
465       gcc_unreachable ();
466     }
468   [(set_attr "type"    "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
469    (set_attr "length"  "  2,  2,  2,  2,  2,  2,  2,  2,  4,  4")
470    (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")])
472 (define_insn "subsi3"
473   [(set (match_operand:SI 0 "register_operand"                "=d, l,    r, r")
474         (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
475                   (match_operand:SI 2 "register_operand"      " r, l,    r, r")))]
476   ""
477   "@
478    sub45\t%0, %2
479    sub333\t%0, %1, %2
480    subri\t%0, %2, %1
481    sub\t%0, %1, %2"
482   [(set_attr "type"   "alu,alu,alu,alu")
483    (set_attr "length" "  2,  2,  4,  4")])
486 ;; GCC intends to simplify (plus (ashift ...) (reg))
487 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
488 ;; and needs to ensure it is exact_log2 value.
489 (define_insn "*add_slli"
490   [(set (match_operand:SI 0 "register_operand"                    "=r")
491         (plus:SI (mult:SI (match_operand:SI 1 "register_operand"  " r")
492                           (match_operand:SI 2 "immediate_operand" " i"))
493                  (match_operand:SI 3 "register_operand"           " r")))]
494   "TARGET_ISA_V3 && optimize_size
495    && (exact_log2 (INTVAL (operands[2])) != -1)
496    && (exact_log2 (INTVAL (operands[2])) <= 31)"
498   /* Get floor_log2 of the immediate value
499      so that we can generate 'add_slli' instruction.  */
500   operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
502   return "add_slli\t%0, %3, %1, %2";
504   [(set_attr "type" "alu_shift")
505    (set_attr "combo"        "2")
506    (set_attr "length"       "4")])
508 (define_insn "*add_srli"
509   [(set (match_operand:SI 0 "register_operand"                          "=   r")
510         (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
511                               (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
512                  (match_operand:SI 3 "register_operand"                 "    r")))]
513   "TARGET_ISA_V3 && optimize_size"
514   "add_srli\t%0, %3, %1, %2"
515   [(set_attr "type" "alu_shift")
516    (set_attr "combo"        "2")
517    (set_attr "length"       "4")])
520 ;; GCC intends to simplify (minus (reg) (ashift ...))
521 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
522 ;; and needs to ensure it is exact_log2 value.
523 (define_insn "*sub_slli"
524   [(set (match_operand:SI 0 "register_operand"                     "=r")
525         (minus:SI (match_operand:SI 1 "register_operand"           " r")
526                   (mult:SI (match_operand:SI 2 "register_operand"  " r")
527                            (match_operand:SI 3 "immediate_operand" " i"))))]
528   "TARGET_ISA_V3 && optimize_size
529    && (exact_log2 (INTVAL (operands[3])) != -1)
530    && (exact_log2 (INTVAL (operands[3])) <= 31)"
532   /* Get floor_log2 of the immediate value
533      so that we can generate 'sub_slli' instruction.  */
534   operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
536   return "sub_slli\t%0, %1, %2, %3";
538   [(set_attr "type" "alu_shift")
539    (set_attr "combo"        "2")
540    (set_attr "length"       "4")])
542 (define_insn "*sub_srli"
543   [(set (match_operand:SI 0 "register_operand"                           "=   r")
544         (minus:SI (match_operand:SI 1 "register_operand"                 "    r")
545                   (lshiftrt:SI (match_operand:SI 2 "register_operand"    "    r")
546                                (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))]
547   "TARGET_ISA_V3 && optimize_size"
548   "sub_srli\t%0, %1, %2, %3"
549   [(set_attr "type" "alu_shift")
550    (set_attr "combo"        "2")
551    (set_attr "length"       "4")])
554 ;; Multiplication instructions.
556 (define_insn "mulsi3"
557   [(set (match_operand:SI 0 "register_operand"          "=w, r")
558         (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
559                  (match_operand:SI 2 "register_operand" " w, r")))]
560   ""
561   "@
562    mul33\t%0, %2
563    mul\t%0, %1, %2"
564   [(set_attr "type"    "mul,mul")
565    (set_attr "length"  "  2,  4")
566    (set_attr "feature" "v3m, v1")])
568 (define_insn "mulsidi3"
569   [(set (match_operand:DI 0 "register_operand"                          "=r")
570         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
571                  (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
572   "TARGET_ISA_V2 || TARGET_ISA_V3"
573   "mulsr64\t%0, %1, %2"
574   [(set_attr "type"   "mul")
575    (set_attr "length"   "4")])
577 (define_insn "umulsidi3"
578   [(set (match_operand:DI 0 "register_operand"                          "=r")
579         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
580                  (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
581   "TARGET_ISA_V2 || TARGET_ISA_V3"
582   "mulr64\t%0, %1, %2"
583   [(set_attr "type"   "mul")
584    (set_attr "length"   "4")])
587 ;; Multiply-accumulate instructions.
589 (define_insn "*maddr32_0"
590   [(set (match_operand:SI 0 "register_operand"                   "=r")
591         (plus:SI (match_operand:SI 3 "register_operand"          " 0")
592                  (mult:SI (match_operand:SI 1 "register_operand" " r")
593                           (match_operand:SI 2 "register_operand" " r"))))]
594   ""
595   "maddr32\t%0, %1, %2"
596   [(set_attr "type"   "mac")
597    (set_attr "length"   "4")])
599 (define_insn "*maddr32_1"
600   [(set (match_operand:SI 0 "register_operand"                   "=r")
601         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
602                           (match_operand:SI 2 "register_operand" " r"))
603                  (match_operand:SI 3 "register_operand"          " 0")))]
604   ""
605   "maddr32\t%0, %1, %2"
606   [(set_attr "type"   "mac")
607    (set_attr "length"   "4")])
609 (define_insn "*msubr32"
610   [(set (match_operand:SI 0 "register_operand"                    "=r")
611         (minus:SI (match_operand:SI 3 "register_operand"          " 0")
612                   (mult:SI (match_operand:SI 1 "register_operand" " r")
613                            (match_operand:SI 2 "register_operand" " r"))))]
614   ""
615   "msubr32\t%0, %1, %2"
616   [(set_attr "type"   "mac")
617    (set_attr "length"   "4")])
620 ;; Div Instructions.
622 (define_insn "divmodsi4"
623   [(set (match_operand:SI 0 "register_operand"         "=r")
624         (div:SI (match_operand:SI 1 "register_operand" " r")
625                 (match_operand:SI 2 "register_operand" " r")))
626    (set (match_operand:SI 3 "register_operand"         "=r")
627         (mod:SI (match_dup 1) (match_dup 2)))]
628   ""
629   "divsr\t%0, %3, %1, %2"
630   [(set_attr "type"   "div")
631    (set_attr "length"   "4")])
633 (define_insn "udivmodsi4"
634   [(set (match_operand:SI 0 "register_operand"          "=r")
635         (udiv:SI (match_operand:SI 1 "register_operand" " r")
636                  (match_operand:SI 2 "register_operand"  " r")))
637    (set (match_operand:SI 3 "register_operand"          "=r")
638         (umod:SI (match_dup 1) (match_dup 2)))]
639   ""
640   "divr\t%0, %3, %1, %2"
641   [(set_attr "type"   "div")
642    (set_attr "length"   "4")])
644 ;; divsr/divr will keep quotient only when quotient and remainder is the same
645 ;; register in our ISA spec, it's can reduce 1 register presure if we don't
646 ;; want remainder.
647 (define_insn "divsi4"
648   [(set (match_operand:SI 0 "register_operand"         "=r")
649         (div:SI (match_operand:SI 1 "register_operand" " r")
650                 (match_operand:SI 2 "register_operand" " r")))]
651   ""
652   "divsr\t%0, %0, %1, %2"
653   [(set_attr "type"   "div")
654    (set_attr "length"   "4")])
656 (define_insn "udivsi4"
657   [(set (match_operand:SI 0 "register_operand"          "=r")
658         (udiv:SI (match_operand:SI 1 "register_operand" " r")
659                  (match_operand:SI 2 "register_operand"  " r")))]
660   ""
661   "divr\t%0, %0, %1, %2"
662   [(set_attr "type"   "div")
663    (set_attr "length"   "4")])
665 ;; ----------------------------------------------------------------------------
667 ;; Boolean instructions.
668 ;; Note: We define the DImode versions in nds32-doubleword.md.
670 ;; ----------------------------------------------------------------------------
671 ;; 'AND' operation
672 ;; ----------------------------------------------------------------------------
674 (define_insn "bitc"
675   [(set (match_operand:SI 0 "register_operand"                 "=r")
676         (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
677                 (match_operand:SI 2 "register_operand"         " r")))]
678   "TARGET_ISA_V3"
679   "bitc\t%0, %2, %1"
680   [(set_attr "type" "alu")
681    (set_attr "length" "4")]
684 (define_expand "andsi3"
685   [(set (match_operand:SI 0 "register_operand" "")
686         (and:SI (match_operand:SI 1 "register_operand" "")
687                 (match_operand:SI 2 "nds32_reg_constant_operand" "")))]
688   ""
690   if (CONST_INT_P (operands[2])
691       && !nds32_and_operand (operands[2], SImode))
692     {
693       nds32_expand_constant (SImode, INTVAL (operands[2]),
694                              operands[0], operands[1]);
695       DONE;
696     }
699 (define_insn "*andsi3"
700   [(set (match_operand:SI 0 "register_operand"          "=l, r,   l,   l,   l,   l,   l,   l,    r,   r,     r,    r,    r")
701         (and:SI (match_operand:SI 1 "register_operand"  "%0, r,   l,   l,   l,   l,   0,   0,    r,   r,     r,    r,    r")
702                 (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
703   ""
705   HOST_WIDE_INT mask = INTVAL (operands[2]);
707   /* 16-bit andi instructions:
708      andi Rt3,Ra3,0xff   -> zeb33  Rt3,Ra3
709      andi Rt3,Ra3,0xffff -> zeh33  Rt3,Ra3
710      andi Rt3,Ra3,0x01   -> xlsb33 Rt3,Ra3
711      andi Rt3,Ra3,0x7ff  -> x11b33 Rt3,Ra3
712      andi Rt3,Rt3,2^imm3u          -> bmski33 Rt3,imm3u
713      andi Rt3,Rt3,(2^(imm3u+1))-1  -> fexti33 Rt3,imm3u.  */
715   switch (which_alternative)
716     {
717     case 0:
718       return "and33\t%0, %2";
719     case 1:
720       return "and\t%0, %1, %2";
721     case 2:
722       return "zeb33\t%0, %1";
723     case 3:
724       return "zeh33\t%0, %1";
725     case 4:
726       return "xlsb33\t%0, %1";
727     case 5:
728       return "x11b33\t%0, %1";
729     case 6:
730       return "bmski33\t%0, %B2";
731     case 7:
732       operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
733       return "fexti33\t%0, %2";
734     case 8:
735       return "zeb\t%0, %1";
736     case 9:
737       return "zeh\t%0, %1";
738     case 10:
739       return "andi\t%0, %1, %2";
740     case 11:
741       operands[2] = GEN_INT (~mask);
742       return "bitci\t%0, %1, %2";
743     case 12:
744       return "bclr\t%0, %1, %b2";
746     default:
747       gcc_unreachable ();
748     }
750   [(set_attr "type"    "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
751    (set_attr "length"  "  2,  4,  2,  2,  2,  2,  2,  2,  4,  4,  4,  4,  4")
752    (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")])
754 (define_insn "*and_slli"
755   [(set (match_operand:SI 0 "register_operand"                        "=   r")
756         (and:SI (ashift:SI (match_operand:SI 1 "register_operand"     "    r")
757                             (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
758                 (match_operand:SI 3 "register_operand"                "    r")))]
759   "TARGET_ISA_V3 && optimize_size"
760   "and_slli\t%0, %3, %1, %2"
761   [(set_attr "type" "alu_shift")
762    (set_attr "length"       "4")])
764 (define_insn "*and_srli"
765   [(set (match_operand:SI 0 "register_operand"                         "=   r")
766         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
767                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
768                 (match_operand:SI 3 "register_operand"                 "    r")))]
769   "TARGET_ISA_V3 && optimize_size"
770   "and_srli\t%0, %3, %1, %2"
771   [(set_attr "type" "alu_shift")
772    (set_attr "length"       "4")])
775 ;; ----------------------------------------------------------------------------
776 ;; 'OR' operation
777 ;; ----------------------------------------------------------------------------
779 ;; For V3/V3M ISA, we have 'or33' instruction.
780 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
782 (define_expand "iorsi3"
783   [(set (match_operand:SI 0 "register_operand"         "")
784         (ior:SI (match_operand:SI 1 "register_operand" "")
785                 (match_operand:SI 2 "general_operand"  "")))]
786   ""
788   if (!nds32_ior_operand (operands[2], SImode))
789     operands[2] = force_reg (SImode, operands[2]);
792 (define_insn "*iorsi3"
793   [(set (match_operand:SI 0 "register_operand"          "=l, r,    r,    r")
794         (ior:SI (match_operand:SI 1 "register_operand"  "%0, r,    r,    r")
795                 (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))]
796   ""
797   "@
798    or33\t%0, %2
799    or\t%0, %1, %2
800    ori\t%0, %1, %2
801    bset\t%0, %1, %B2"
802   [(set_attr "type"    "alu,alu,alu,alu")
803    (set_attr "length"  "  2,  4,  4,  4")
804    (set_attr "feature" "v3m, v1, v1,pe1")])
806 (define_insn "*or_slli"
807   [(set (match_operand:SI 0 "register_operand"                       "=   r")
808         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand"    "    r")
809                            (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
810                 (match_operand:SI 3 "register_operand"               "    r")))]
811   "TARGET_ISA_V3 && optimize_size"
812   "or_slli\t%0, %3, %1, %2"
813   [(set_attr "type" "alu_shift")
814    (set_attr "length"       "4")])
816 (define_insn "*or_srli"
817   [(set (match_operand:SI 0 "register_operand"                         "=   r")
818         (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
819                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
820                 (match_operand:SI 3 "register_operand"                 "    r")))]
821   "TARGET_ISA_V3 && optimize_size"
822   "or_srli\t%0, %3, %1, %2"
823   [(set_attr "type" "alu_shift")
824    (set_attr "length"       "4")])
827 ;; ----------------------------------------------------------------------------
828 ;; 'XOR' operation
829 ;; ----------------------------------------------------------------------------
831 ;; For V3/V3M ISA, we have 'xor33' instruction.
832 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
834 (define_expand "xorsi3"
835   [(set (match_operand:SI 0 "register_operand"         "")
836         (xor:SI (match_operand:SI 1 "register_operand" "")
837                 (match_operand:SI 2 "general_operand"  "")))]
838   ""
840   if (!nds32_xor_operand (operands[2], SImode))
841     operands[2] = force_reg (SImode, operands[2]);
844 (define_insn "*xorsi3"
845   [(set (match_operand:SI 0 "register_operand"          "=l, r,    r,    r")
846         (xor:SI (match_operand:SI 1 "register_operand"  "%0, r,    r,    r")
847                 (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))]
848   ""
849   "@
850    xor33\t%0, %2
851    xor\t%0, %1, %2
852    xori\t%0, %1, %2
853    btgl\t%0, %1, %B2"
854   [(set_attr "type"    "alu,alu,alu,alu")
855    (set_attr "length"  "  2,  4,  4,  4")
856    (set_attr "feature" "v3m, v1, v1,pe1")])
858 (define_insn "*xor_slli"
859   [(set (match_operand:SI 0 "register_operand"                     "=   r")
860         (xor:SI (ashift:SI (match_operand:SI 1 "register_operand"  "    r")
861                            (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
862                 (match_operand:SI 3 "register_operand"             "    r")))]
863   "TARGET_ISA_V3 && optimize_size"
864   "xor_slli\t%0, %3, %1, %2"
865   [(set_attr "type" "alu_shift")
866    (set_attr "length"       "4")])
868 (define_insn "*xor_srli"
869   [(set (match_operand:SI 0 "register_operand"                         "=   r")
870         (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand"    "    r")
871                              (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
872                 (match_operand:SI 3 "register_operand"                 "    r")))]
873   "TARGET_ISA_V3 && optimize_size"
874   "xor_srli\t%0, %3, %1, %2"
875   [(set_attr "type" "alu_shift")
876    (set_attr "length"       "4")])
878 ;; Rotate Right Instructions.
880 (define_insn "*rotrsi3"
881   [(set (match_operand:SI 0 "register_operand"                    "=   r, r")
882           (rotatert:SI (match_operand:SI 1 "register_operand"     "    r, r")
883                        (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
884   ""
885   "@
886    rotri\t%0, %1, %2
887    rotr\t%0, %1, %2"
888   [(set_attr "type"    "  alu,  alu")
889    (set_attr "subtype" "shift,shift")
890    (set_attr "length"  "    4,    4")])
893 ;; ----------------------------------------------------------------------------
894 ;; 'NEG' operation
895 ;; ----------------------------------------------------------------------------
897 ;; For V3/V3M ISA, we have 'neg33' instruction.
898 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
899 ;; And for V2 ISA, there is NO 'neg33' instruction.
900 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
901 (define_insn "negsi2"
902   [(set (match_operand:SI 0 "register_operand"         "=l, r")
903         (neg:SI (match_operand:SI 1 "register_operand" " l, r")))]
904   ""
905   "@
906    neg33\t%0, %1
907    subri\t%0, %1, 0"
908   [(set_attr "type"    "alu,alu")
909    (set_attr "length"  "  2,  4")
910    (set_attr "feature" "v3m, v1")])
912 (define_expand "negsf2"
913   [(set (match_operand:SF 0 "register_operand" "")
914         (neg:SF (match_operand:SF 1 "register_operand" "")))]
915   ""
917   if (!TARGET_FPU_SINGLE && !TARGET_EXT_PERF)
918     {
919       rtx new_dst = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
920       rtx new_src = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
922       emit_insn (gen_xorsi3 (new_dst,
923                              new_src,
924                              gen_int_mode (0x80000000, SImode)));
926       DONE;
927     }
930 (define_expand "negdf2"
931   [(set (match_operand:DF 0 "register_operand" "")
932         (neg:DF (match_operand:DF 1 "register_operand" "")))]
933   ""
937 (define_insn_and_split "soft_negdf2"
938   [(set (match_operand:DF 0 "register_operand" "")
939         (neg:DF (match_operand:DF 1 "register_operand" "")))]
940   "!TARGET_FPU_DOUBLE"
941   "#"
942   "!TARGET_FPU_DOUBLE"
943   [(const_int 1)]
945     rtx src = operands[1];
946     rtx dst = operands[0];
947     rtx ori_dst = operands[0];
949     bool need_extra_move_for_dst_p;
950     /* FPU register can't change mode to SI directly, so we need create a
951        tmp register to handle it, and FPU register can't do `xor` or btgl.  */
952     if (HARD_REGISTER_P (src)
953         && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (src)))
954       {
955         rtx tmp = gen_reg_rtx (DFmode);
956         emit_move_insn (tmp, src);
957         src = tmp;
958       }
960     if (HARD_REGISTER_P (dst)
961         && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (dst)))
962       {
963         need_extra_move_for_dst_p = true;
964         rtx tmp = gen_reg_rtx (DFmode);
965         dst = tmp;
966       }
968     rtx dst_high_part = simplify_gen_subreg (
969                           SImode, dst,
970                           DFmode, subreg_highpart_offset (SImode, DFmode));
971     rtx dst_low_part = simplify_gen_subreg (
972                           SImode, dst,
973                           DFmode, subreg_lowpart_offset (SImode, DFmode));
974     rtx src_high_part = simplify_gen_subreg (
975                           SImode, src,
976                           DFmode, subreg_highpart_offset (SImode, DFmode));
977     rtx src_low_part = simplify_gen_subreg (
978                           SImode, src,
979                           DFmode, subreg_lowpart_offset (SImode, DFmode));
981     emit_insn (gen_xorsi3 (dst_high_part,
982                            src_high_part,
983                            gen_int_mode (0x80000000, SImode)));
984     emit_move_insn (dst_low_part, src_low_part);
986     if (need_extra_move_for_dst_p)
987       emit_move_insn (ori_dst, dst);
989     DONE;
993 ;; ----------------------------------------------------------------------------
994 ;; 'ONE_COMPLIMENT' operation
995 ;; ----------------------------------------------------------------------------
997 ;; For V3/V3M ISA, we have 'not33' instruction.
998 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
999 (define_insn "one_cmplsi2"
1000   [(set (match_operand:SI 0 "register_operand"         "=w, r")
1001         (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
1002   ""
1003   "@
1004    not33\t%0, %1
1005    nor\t%0, %1, %1"
1006   [(set_attr "type"    "alu,alu")
1007    (set_attr "length"  "  2,  4")
1008    (set_attr "feature" "v3m, v1")])
1011 ;; ----------------------------------------------------------------------------
1013 ;; Shift instructions.
1015 (define_expand "<shift>si3"
1016   [(set (match_operand:SI 0 "register_operand"                      "")
1017         (shift_rotate:SI (match_operand:SI 1 "register_operand"     "")
1018                          (match_operand:SI 2 "nds32_rimm5u_operand" "")))]
1019   ""
1021   if (operands[2] == const0_rtx)
1022     {
1023       emit_move_insn (operands[0], operands[1]);
1024       DONE;
1025     }
1028 (define_insn "*ashlsi3"
1029   [(set (match_operand:SI 0 "register_operand"                "=   l,    r, r")
1030         (ashift:SI (match_operand:SI 1 "register_operand"     "    l,    r, r")
1031                    (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))]
1032   ""
1033   "@
1034    slli333\t%0, %1, %2
1035    slli\t%0, %1, %2
1036    sll\t%0, %1, %2"
1037   [(set_attr "type"    "  alu,  alu,  alu")
1038    (set_attr "subtype" "shift,shift,shift")
1039    (set_attr "length"  "    2,    4,    4")])
1041 (define_insn "*ashrsi3"
1042   [(set (match_operand:SI 0 "register_operand"                  "=   d,    r, r")
1043         (ashiftrt:SI (match_operand:SI 1 "register_operand"     "    0,    r, r")
1044                      (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
1045   ""
1046   "@
1047    srai45\t%0, %2
1048    srai\t%0, %1, %2
1049    sra\t%0, %1, %2"
1050   [(set_attr "type"    "  alu,  alu,  alu")
1051    (set_attr "subtype" "shift,shift,shift")
1052    (set_attr "length"  "    2,    4,    4")])
1054 (define_insn "*lshrsi3"
1055   [(set (match_operand:SI 0 "register_operand"                  "=   d,    r, r")
1056         (lshiftrt:SI (match_operand:SI 1 "register_operand"     "    0,    r, r")
1057                      (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
1058   ""
1059   "@
1060    srli45\t%0, %2
1061    srli\t%0, %1, %2
1062    srl\t%0, %1, %2"
1063   [(set_attr "type"    "  alu,  alu,  alu")
1064    (set_attr "subtype" "shift,shift,shift")
1065    (set_attr "length"  "    2,    4,    4")])
1068 ;; ----------------------------------------------------------------------------
1070 ;; ----------------------------------------------------------------------------
1071 ;; Conditional Move patterns
1072 ;; ----------------------------------------------------------------------------
1074 (define_expand "mov<mode>cc"
1075   [(set (match_operand:QIHISI 0 "register_operand" "")
1076         (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
1077                          (match_operand:QIHISI 2 "register_operand" "")
1078                          (match_operand:QIHISI 3 "register_operand" "")))]
1079   "TARGET_CMOV && !optimize_size"
1081   enum nds32_expand_result_type result = nds32_expand_movcc (operands);
1082   switch (result)
1083     {
1084     case EXPAND_DONE:
1085       DONE;
1086       break;
1087     case EXPAND_FAIL:
1088       FAIL;
1089       break;
1090     case EXPAND_CREATE_TEMPLATE:
1091       break;
1092     default:
1093       gcc_unreachable ();
1094     }
1097 (define_insn "cmovz<mode>"
1098   [(set (match_operand:QIHISI 0 "register_operand"                      "=r, r")
1099         (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
1100                              (const_int 0))
1101                          (match_operand:QIHISI 2 "register_operand"     " r, 0")
1102                          (match_operand:QIHISI 3 "register_operand"     " 0, r")))]
1103   "TARGET_CMOV"
1104   "@
1105    cmovz\t%0, %2, %1
1106    cmovn\t%0, %3, %1"
1107   [(set_attr "type"  "alu")
1108    (set_attr "length"  "4")])
1110 (define_insn "cmovn<mode>"
1111   [(set (match_operand:QIHISI 0 "register_operand"                      "=r, r")
1112         (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
1113                              (const_int 0))
1114                          (match_operand:QIHISI 2 "register_operand"     " r, 0")
1115                          (match_operand:QIHISI 3 "register_operand"     " 0, r")))]
1116   "TARGET_CMOV"
1117   "@
1118    cmovn\t%0, %2, %1
1119    cmovz\t%0, %3, %1"
1120   [(set_attr "type"  "alu")
1121    (set_attr "length"  "4")])
1123 ;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
1124 ;; It should be removed once after we change the expansion form of the cmovn.
1125 (define_insn "*cmovn_simplified_<mode>"
1126   [(set (match_operand:QIHISI 0 "register_operand" "=r")
1127         (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
1128                          (match_operand:QIHISI 2 "register_operand" "r")
1129                          (match_operand:QIHISI 3 "register_operand" "0")))]
1130   ""
1131   "cmovn\t%0, %2, %1"
1132   [(set_attr "type" "alu")])
1134 ;; ----------------------------------------------------------------------------
1135 ;; Conditional Branch patterns
1136 ;; ----------------------------------------------------------------------------
1138 (define_expand "cbranchsi4"
1139   [(set (pc)
1140         (if_then_else (match_operator 0 "comparison_operator"
1141                         [(match_operand:SI 1 "register_operand"           "")
1142                          (match_operand:SI 2 "nds32_reg_constant_operand" "")])
1143                       (label_ref (match_operand 3 "" ""))
1144                       (pc)))]
1145   ""
1147   enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
1148   switch (result)
1149     {
1150     case EXPAND_DONE:
1151       DONE;
1152       break;
1153     case EXPAND_FAIL:
1154       FAIL;
1155       break;
1156     case EXPAND_CREATE_TEMPLATE:
1157       break;
1158     default:
1159       gcc_unreachable ();
1160     }
1164 (define_insn "cbranchsi4_equality_zero"
1165   [(set (pc)
1166         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1167                         [(match_operand:SI 1 "register_operand"  "t,l, r")
1168                          (const_int 0)])
1169                       (label_ref (match_operand 2 "" ""))
1170                       (pc)))]
1171   ""
1173   return nds32_output_cbranchsi4_equality_zero (insn, operands);
1175   [(set_attr "type" "branch")
1176    (set_attr_alternative "enabled"
1177      [
1178        ;; Alternative 0
1179        (if_then_else (match_test "TARGET_16_BIT")
1180                      (const_string "yes")
1181                      (const_string "no"))
1182        ;; Alternative 1
1183        (if_then_else (match_test "TARGET_16_BIT")
1184                      (const_string "yes")
1185                      (const_string "no"))
1186        ;; Alternative 2
1187        (const_string "yes")
1188      ])
1189    (set_attr_alternative "length"
1190      [
1191        ;; Alternative 0
1192        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1193                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1194                                         (le (minus (match_dup 2) (pc)) (const_int  250)))
1195                                    (if_then_else (match_test "TARGET_16_BIT")
1196                                                  (const_int 2)
1197                                                  (const_int 4))
1198                                    (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1199                                                       (le (minus (match_dup 2) (pc)) (const_int  65500)))
1200                                                  (const_int 4)
1201                                                  (if_then_else (match_test "TARGET_16_BIT")
1202                                                                (const_int 8)
1203                                                                (const_int 10))))
1204                      (const_int 10))
1205        ;; Alternative 1
1206        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1207                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1208                                         (le (minus (match_dup 2) (pc)) (const_int  250)))
1209                                    (if_then_else (match_test "TARGET_16_BIT")
1210                                                  (const_int 2)
1211                                                  (const_int 4))
1212                                    (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1213                                                       (le (minus (match_dup 2) (pc)) (const_int  65500)))
1214                                                  (const_int 4)
1215                                                  (if_then_else (match_test "TARGET_16_BIT")
1216                                                                (const_int 8)
1217                                                                (const_int 10))))
1218                      (const_int 10))
1219        ;; Alternative 2
1220        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1221                      (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1222                                         (le (minus (match_dup 2) (pc)) (const_int  65500)))
1223                                    (const_int 4)
1224                                    (const_int 10))
1225                      (const_int 10))
1226      ])])
1229 ;; This pattern is dedicated to V2 ISA,
1230 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
1231 (define_insn "cbranchsi4_equality_reg"
1232   [(set (pc)
1233         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1234                         [(match_operand:SI 1 "register_operand" "v, r")
1235                          (match_operand:SI 2 "register_operand" "l, r")])
1236                       (label_ref (match_operand 3 "" ""))
1237                       (pc)))]
1238   "TARGET_ISA_V2"
1240   return nds32_output_cbranchsi4_equality_reg (insn, operands);
1242   [(set_attr "type"   "branch")
1243    (set_attr_alternative "enabled"
1244      [
1245        ;; Alternative 0
1246        (if_then_else (match_test "TARGET_16_BIT")
1247                      (const_string "yes")
1248                      (const_string "no"))
1249        ;; Alternative 1
1250        (const_string "yes")
1251      ])
1252    (set_attr_alternative "length"
1253      [
1254        ;; Alternative 0
1255        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1256                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1257                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1258                                    (const_int 2)
1259                                    (if_then_else (and (ge (minus (match_dup 3) (pc))
1260                                                           (const_int -16350))
1261                                                       (le (minus (match_dup 3) (pc))
1262                                                           (const_int  16350)))
1263                                                  (const_int 4)
1264                                                  (const_int 8)))
1265                      (const_int 8))
1266        ;; Alternative 1
1267        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1268                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1269                                         (le (minus (match_dup 3) (pc)) (const_int  16350)))
1270                                    (const_int 4)
1271                                    (const_int 10))
1272                      (const_int 10))
1273      ])])
1276 ;; This pattern is dedicated to V3/V3M,
1277 ;; because V3/V3M DO HAVE beqc/bnec instruction.
1278 (define_insn "cbranchsi4_equality_reg_or_const_int"
1279   [(set (pc)
1280         (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1281                         [(match_operand:SI 1 "register_operand"      "v, r,    r")
1282                          (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
1283                       (label_ref (match_operand 3 "" ""))
1284                       (pc)))]
1285   "TARGET_ISA_V3 || TARGET_ISA_V3M"
1287   return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
1289   [(set_attr "type"   "branch")
1290    (set_attr_alternative "enabled"
1291      [
1292        ;; Alternative 0
1293        (if_then_else (match_test "TARGET_16_BIT")
1294                      (const_string "yes")
1295                      (const_string "no"))
1296        ;; Alternative 1
1297        (const_string "yes")
1298        ;; Alternative 2
1299        (const_string "yes")
1300      ])
1301    (set_attr_alternative "length"
1302      [
1303        ;; Alternative 0
1304        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1305                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1306                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1307                                    (const_int 2)
1308                                    (if_then_else (and (ge (minus (match_dup 3) (pc))
1309                                                           (const_int -16350))
1310                                                       (le (minus (match_dup 3) (pc))
1311                                                           (const_int  16350)))
1312                                                  (const_int 4)
1313                                                  (const_int 8)))
1314                     (const_int 8))
1315        ;; Alternative 1
1316        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1317                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1318                                         (le (minus (match_dup 3) (pc)) (const_int  16350)))
1319                                    (const_int 4)
1320                                    (const_int 10))
1321                     (const_int 10))
1322        ;; Alternative 2
1323        (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1324                      (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1325                                         (le (minus (match_dup 3) (pc)) (const_int  250)))
1326                                    (const_int 4)
1327                                    (const_int 10))
1328                     (const_int 10))
1329      ])])
1332 (define_insn "*cbranchsi4_greater_less_zero"
1333   [(set (pc)
1334         (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1335                         [(match_operand:SI 1 "register_operand" "r")
1336                          (const_int 0)])
1337                       (label_ref (match_operand 2 "" ""))
1338                       (pc)))]
1339   ""
1341   return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
1343   [(set_attr "type"   "branch")
1344    (set (attr "length")
1345         (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1346                       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1347                                          (le (minus (match_dup 2) (pc)) (const_int  65500)))
1348                                     (const_int 4)
1349                                     (const_int 10))
1350                       (const_int 10)))])
1353 (define_expand "cstoresi4"
1354   [(set (match_operand:SI 0 "register_operand" "")
1355         (match_operator:SI 1 "comparison_operator"
1356           [(match_operand:SI 2 "register_operand" "")
1357            (match_operand:SI 3 "nonmemory_operand" "")]))]
1358   ""
1360   enum nds32_expand_result_type result = nds32_expand_cstore (operands);
1361   switch (result)
1362     {
1363     case EXPAND_DONE:
1364       DONE;
1365       break;
1366     case EXPAND_FAIL:
1367       FAIL;
1368       break;
1369     case EXPAND_CREATE_TEMPLATE:
1370       break;
1371     default:
1372       gcc_unreachable ();
1373     }
1377 (define_expand "slts_compare"
1378   [(set (match_operand:SI 0 "register_operand"       "")
1379         (lt:SI (match_operand:SI 1 "general_operand" "")
1380                (match_operand:SI 2 "general_operand" "")))]
1381   ""
1383   if (!REG_P (operands[1]))
1384     operands[1] = force_reg (SImode, operands[1]);
1386   if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1387     operands[2] = force_reg (SImode, operands[2]);
1390 (define_insn "slts_compare_impl"
1391   [(set (match_operand:SI 0 "register_operand"             "=t,   t, r,    r")
1392         (lt:SI (match_operand:SI 1 "register_operand"      " d,   d, r,    r")
1393                (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
1394   ""
1395   "@
1396    slts45\t%1, %2
1397    sltsi45\t%1, %2
1398    slts\t%0, %1, %2
1399    sltsi\t%0, %1, %2"
1400   [(set_attr "type"   "alu,    alu,    alu,    alu")
1401    (set_attr "length" "  2,      2,      4,      4")])
1403 (define_insn "slt_eq0"
1404   [(set (match_operand:SI 0 "register_operand"        "=t, r")
1405         (eq:SI (match_operand:SI 1 "register_operand" " d, r")
1406                (const_int 0)))]
1407   ""
1408   "@
1409    slti45\t%1, 1
1410    slti\t%0, %1, 1"
1411   [(set_attr "type"   "alu, alu")
1412    (set_attr "length" "  2,   4")])
1414 (define_expand "slt_compare"
1415   [(set (match_operand:SI 0 "register_operand"        "")
1416         (ltu:SI (match_operand:SI 1 "general_operand" "")
1417                 (match_operand:SI 2 "general_operand" "")))]
1418   ""
1420   if (!REG_P (operands[1]))
1421     operands[1] = force_reg (SImode, operands[1]);
1423   if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1424     operands[2] = force_reg (SImode, operands[2]);
1427 (define_insn "slt_compare_impl"
1428   [(set (match_operand:SI 0 "register_operand"              "=t,    t, r,    r")
1429         (ltu:SI (match_operand:SI 1 "register_operand"      " d,    d, r,    r")
1430                 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
1431   ""
1432   "@
1433    slt45\t%1, %2
1434    slti45\t%1, %2
1435    slt\t%0, %1, %2
1436    slti\t%0, %1, %2"
1437   [(set_attr "type"   "alu,    alu,    alu,    alu")
1438    (set_attr "length" "  2,      2,      4,      4")])
1441 ;; ----------------------------------------------------------------------------
1443 ;; Unconditional and other jump instructions.
1445 (define_insn "jump"
1446   [(set (pc) (label_ref (match_operand 0 "" "")))]
1447   ""
1449   /* This unconditional jump has two forms:
1450        32-bit instruction => j   imm24s << 1
1451        16-bit instruction => j8  imm8s << 1
1453      For 32-bit case,
1454      we assume it is always reachable.
1455      For 16-bit case,
1456      it must satisfy { 255 >= (label - pc) >= -256 } condition.
1457      However, since the $pc for nds32 is at the beginning of the instruction,
1458      we should leave some length space for current insn.
1459      So we use range -250 ~ 250.  */
1460   switch (get_attr_length (insn))
1461     {
1462     case 2:
1463       return "j8\t%0";
1464     case 4:
1465       return "j\t%0";
1466     default:
1467       gcc_unreachable ();
1468     }
1470   [(set_attr "type" "branch")
1471    (set_attr "enabled" "yes")
1472    (set (attr "length")
1473         (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1474                       (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1475                                          (le (minus (match_dup 0) (pc)) (const_int  250)))
1476                                     (if_then_else (match_test "TARGET_16_BIT")
1477                                                   (const_int 2)
1478                                                   (const_int 4))
1479                                     (const_int 4))
1480                       (const_int 4)))])
1482 (define_insn "indirect_jump"
1483   [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1484   ""
1485   "@
1486    jr5\t%0
1487    jr\t%0"
1488   [(set_attr "type"   "branch,branch")
1489    (set_attr "length" "     2,     4")])
1491 ;; Subroutine call instruction returning no value.
1492 ;;   operands[0]: It should be a mem RTX whose address is
1493 ;;                the address of the function.
1494 ;;   operands[1]: It is the number of bytes of arguments pushed as a const_int.
1495 ;;   operands[2]: It is the number of registers used as operands.
1497 (define_expand "call"
1498   [(parallel [(call (match_operand 0 "memory_operand" "")
1499                     (match_operand 1))
1500               (clobber (reg:SI LP_REGNUM))
1501               (clobber (reg:SI TA_REGNUM))])]
1502   ""
1503   {
1504     rtx insn;
1505     rtx sym = XEXP (operands[0], 0);
1507     if (TARGET_ICT_MODEL_LARGE
1508         && nds32_indirect_call_referenced_p (sym))
1509       {
1510         rtx reg = gen_reg_rtx (Pmode);
1511         emit_move_insn (reg, sym);
1512         operands[0] = gen_const_mem (Pmode, reg);
1513       }
1515     if (flag_pic)
1516       {
1517         insn = emit_call_insn (gen_call_internal
1518                                (XEXP (operands[0], 0), GEN_INT (0)));
1519         use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
1520         DONE;
1521       }
1522   }
1525 (define_insn "call_internal"
1526   [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S"))
1527                     (match_operand 1))
1528               (clobber (reg:SI LP_REGNUM))
1529               (clobber (reg:SI TA_REGNUM))])]
1530   ""
1532   rtx_insn *next_insn = next_active_insn (insn);
1533   bool align_p = (!(next_insn && get_attr_length (next_insn) == 2))
1534                  && NDS32_ALIGN_P ();
1535   switch (which_alternative)
1536     {
1537     case 0:
1538       if (TARGET_16_BIT)
1539         {
1540           if (align_p)
1541             return "jral5\t%0\;.align 2";
1542           else
1543             return "jral5\t%0";
1544         }
1545       else
1546         {
1547           if (align_p)
1548             return "jral\t%0\;.align 2";
1549           else
1550             return "jral\t%0";
1551         }
1552     case 1:
1553       return nds32_output_call (insn, operands, operands[0],
1554                                 "bal\t%0", "jal\t%0", align_p);
1555     default:
1556       gcc_unreachable ();
1557     }
1559   [(set_attr "enabled" "yes")
1560    (set_attr "type" "branch")
1561    (set_attr_alternative "length"
1562      [
1563        ;; Alternative 0
1564        (if_then_else (match_test "TARGET_16_BIT")
1565                      (const_int 2)
1566                      (const_int 4))
1567        ;; Alternative 1
1568        (if_then_else (match_test "flag_pic")
1569                      (const_int 16)
1570                      (if_then_else (match_test "nds32_long_call_p (operands[0])")
1571                                    (const_int 12)
1572                                    (const_int 4)))
1573      ])]
1576 ;; Subroutine call instruction returning a value.
1577 ;;   operands[0]: It is the hard regiser in which the value is returned.
1578 ;;   The rest three operands are the same as the
1579 ;;   three operands of the 'call' instruction.
1580 ;;   (but with numbers increased by one)
1582 (define_expand "call_value"
1583   [(parallel [(set (match_operand 0)
1584                    (call (match_operand 1 "memory_operand" "")
1585                          (match_operand 2)))
1586               (clobber (reg:SI LP_REGNUM))
1587               (clobber (reg:SI TA_REGNUM))])]
1588   ""
1589   {
1590     rtx insn;
1591     rtx sym = XEXP (operands[1], 0);
1593     if (TARGET_ICT_MODEL_LARGE
1594         && nds32_indirect_call_referenced_p (sym))
1595       {
1596         rtx reg = gen_reg_rtx (Pmode);
1597         emit_move_insn (reg, sym);
1598         operands[1] = gen_const_mem (Pmode, reg);
1599       }
1601     if (flag_pic)
1602       {
1603         insn =
1604           emit_call_insn (gen_call_value_internal
1605                           (operands[0], XEXP (operands[1], 0), GEN_INT (0)));
1606         use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
1607         DONE;
1608       }
1609   }
1612 (define_insn "call_value_internal"
1613   [(parallel [(set (match_operand 0)
1614                    (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S"))
1615                          (match_operand 2)))
1616               (clobber (reg:SI LP_REGNUM))
1617               (clobber (reg:SI TA_REGNUM))])]
1618   ""
1620   rtx_insn *next_insn = next_active_insn (insn);
1621   bool align_p = (!(next_insn && get_attr_length (next_insn) == 2))
1622                  && NDS32_ALIGN_P ();
1623   switch (which_alternative)
1624     {
1625     case 0:
1626       if (TARGET_16_BIT)
1627         {
1628           if (align_p)
1629             return "jral5\t%1\;.align 2";
1630           else
1631             return "jral5\t%1";
1632         }
1633       else
1634         {
1635           if (align_p)
1636             return "jral\t%1\;.align 2";
1637           else
1638             return "jral\t%1";
1639         }
1640     case 1:
1641       return nds32_output_call (insn, operands, operands[1],
1642                                 "bal\t%1", "jal\t%1", align_p);
1643     default:
1644       gcc_unreachable ();
1645     }
1647   [(set_attr "enabled" "yes")
1648    (set_attr "type" "branch")
1649    (set_attr_alternative "length"
1650      [
1651        ;; Alternative 0
1652        (if_then_else (match_test "TARGET_16_BIT")
1653                      (const_int 2)
1654                      (const_int 4))
1655        ;; Alternative 1
1656        (if_then_else (match_test "flag_pic")
1657                      (const_int 16)
1658                      (if_then_else (match_test "nds32_long_call_p (operands[1])")
1659                                    (const_int 12)
1660                                    (const_int 4)))
1661      ])]
1664 ;; Call subroutine returning any type.
1666 (define_expand "untyped_call"
1667   [(parallel [(call (match_operand 0 "" "")
1668                     (const_int 0))
1669               (match_operand 1 "" "")
1670               (match_operand 2 "" "")])]
1671   ""
1673   int i;
1675   emit_call_insn (gen_call (operands[0], const0_rtx));
1677   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1678     {
1679       rtx set = XVECEXP (operands[2], 0, i);
1680       emit_move_insn (SET_DEST (set), SET_SRC (set));
1681     }
1683   /* The optimizer does not know that the call sets the function value
1684      registers we stored in the result block.  We avoid problems by
1685      claiming that all hard registers are used and clobbered at this
1686      point.  */
1687   emit_insn (gen_blockage ());
1688   DONE;
1691 ;; ----------------------------------------------------------------------------
1693 ;; The sibcall patterns.
1695 ;; sibcall
1696 ;; sibcall_internal
1698 (define_expand "sibcall"
1699   [(parallel [(call (match_operand 0 "memory_operand" "")
1700                     (const_int 0))
1701               (clobber (reg:SI TA_REGNUM))
1702               (return)])]
1703   ""
1705     rtx sym = XEXP (operands[0], 0);
1707     if (TARGET_ICT_MODEL_LARGE
1708         && nds32_indirect_call_referenced_p (sym))
1709       {
1710         rtx reg = gen_reg_rtx (Pmode);
1711         emit_move_insn (reg, sym);
1712         operands[0] = gen_const_mem (Pmode, reg);
1713       }
1716 (define_insn "sibcall_internal"
1717   [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S"))
1718                     (match_operand 1))
1719               (clobber (reg:SI TA_REGNUM))
1720               (return)])]
1721   ""
1723   switch (which_alternative)
1724     {
1725     case 0:
1726       if (TARGET_16_BIT)
1727         return "jr5\t%0";
1728       else
1729         return "jr\t%0";
1730     case 1:
1731       if (nds32_long_call_p (operands[0]))
1732         return "b\t%0";
1733       else
1734         return "j\t%0";
1735     default:
1736       gcc_unreachable ();
1737     }
1739   [(set_attr "enabled" "yes")
1740    (set_attr "type" "branch")
1741    (set_attr_alternative "length"
1742      [
1743        ;; Alternative 0
1744        (if_then_else (match_test "TARGET_16_BIT")
1745                      (const_int 2)
1746                      (const_int 4))
1747        ;; Alternative 1
1748        (if_then_else (match_test "flag_pic")
1749                      (const_int 16)
1750                      (if_then_else (match_test "nds32_long_call_p (operands[0])")
1751                                    (const_int 12)
1752                                    (const_int 4)))
1753      ])]
1756 ;; sibcall_value
1757 ;; sibcall_value_internal
1758 ;; sibcall_value_immediate
1760 (define_expand "sibcall_value"
1761   [(parallel [(set (match_operand 0)
1762                    (call (match_operand 1 "memory_operand" "")
1763                          (const_int 0)))
1764               (clobber (reg:SI TA_REGNUM))
1765               (return)])]
1766   ""
1768     rtx sym = XEXP (operands[1], 0);
1770     if (TARGET_ICT_MODEL_LARGE
1771         && nds32_indirect_call_referenced_p (sym))
1772       {
1773         rtx reg = gen_reg_rtx (Pmode);
1774         emit_move_insn (reg, sym);
1775         operands[1] = gen_const_mem (Pmode, reg);
1776       }
1779 (define_insn "sibcall_value_internal"
1780   [(parallel [(set (match_operand 0)
1781                    (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S"))
1782                          (match_operand 2)))
1783               (clobber (reg:SI TA_REGNUM))
1784               (return)])]
1785   ""
1787   switch (which_alternative)
1788     {
1789     case 0:
1790       if (TARGET_16_BIT)
1791         return "jr5\t%1";
1792       else
1793         return "jr\t%1";
1794     case 1:
1795       if (nds32_long_call_p (operands[1]))
1796         return "b\t%1";
1797       else
1798         return "j\t%1";
1799     default:
1800       gcc_unreachable ();
1801     }
1803   [(set_attr "enabled" "yes")
1804    (set_attr "type" "branch")
1805    (set_attr_alternative "length"
1806      [
1807        ;; Alternative 0
1808        (if_then_else (match_test "TARGET_16_BIT")
1809                      (const_int 2)
1810                      (const_int 4))
1811        ;; Alternative 1
1812        (if_then_else (match_test "flag_pic")
1813                      (const_int 16)
1814                      (if_then_else (match_test "nds32_long_call_p (operands[1])")
1815                                    (const_int 12)
1816                                    (const_int 4)))
1817      ])]
1820 ;; ----------------------------------------------------------------------------
1822 ;; prologue and epilogue.
1824 (define_expand "prologue" [(const_int 0)]
1825   ""
1827   /* Note that only under V3/V3M ISA, we could use v3push prologue.
1828      In addition, we need to check if v3push is indeed available.  */
1829   if (NDS32_V3PUSH_AVAILABLE_P)
1830     nds32_expand_prologue_v3push ();
1831   else
1832     nds32_expand_prologue ();
1833   DONE;
1836 (define_expand "epilogue" [(const_int 0)]
1837   ""
1839   /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
1840      In addition, we need to check if v3push is indeed available.  */
1841   if (NDS32_V3PUSH_AVAILABLE_P)
1842     nds32_expand_epilogue_v3pop (false);
1843   else
1844     nds32_expand_epilogue (false);
1845   DONE;
1848 (define_expand "sibcall_epilogue" [(const_int 0)]
1849   ""
1851   /* Pass true to indicate that this is sibcall epilogue and
1852      exit from a function without the final branch back to the
1853      calling function.  */
1854   nds32_expand_epilogue (true);
1856   DONE;
1860 ;; nop instruction.
1862 (define_insn "nop"
1863   [(const_int 0)]
1864   ""
1866   if (TARGET_16_BIT)
1867     return "nop16";
1868   else
1869     return "nop";
1871   [(set_attr "type" "misc")
1872    (set_attr "enabled" "yes")
1873    (set (attr "length")
1874         (if_then_else (match_test "TARGET_16_BIT")
1875                       (const_int 2)
1876                       (const_int 4)))])
1879 ;; ----------------------------------------------------------------------------
1880 ;; Stack push/pop operations
1881 ;; ----------------------------------------------------------------------------
1883 ;; The pattern for stack push.
1884 ;; Both stack_push_multiple and stack_v3push use the following pattern.
1885 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1886 (define_insn "*stack_push"
1887   [(match_parallel 0 "nds32_stack_push_operation"
1888      [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1889                             (match_operand:SI 1 "const_int_operand" "")))
1890            (match_operand:SI 2 "register_operand" ""))
1891      ])]
1892   ""
1894   return nds32_output_stack_push (operands[0]);
1896   [(set_attr "type" "store_multiple")
1897    (set_attr "combo" "12")
1898    (set_attr "enabled" "yes")
1899    (set (attr "length")
1900         (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1901                       (const_int 2)
1902                       (const_int 4)))])
1905 ;; The pattern for stack pop.
1906 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1907 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1908 (define_insn "*stack_pop"
1909   [(match_parallel 0 "nds32_stack_pop_operation"
1910      [(set (match_operand:SI 1 "register_operand" "")
1911            (mem:SI (reg:SI SP_REGNUM)))
1912      ])]
1913   ""
1915   return nds32_output_stack_pop (operands[0]);
1917   [(set_attr "type" "load_multiple")
1918    (set_attr "combo" "12")
1919    (set_attr "enabled" "yes")
1920    (set (attr "length")
1921         (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1922                       (const_int 2)
1923                       (const_int 4)))])
1926 ;; ----------------------------------------------------------------------------
1927 ;; Return operation patterns
1928 ;; ----------------------------------------------------------------------------
1930 ;; Use this pattern to expand a return instruction
1931 ;; with simple_return rtx if no epilogue is required.
1932 (define_expand "return"
1933   [(parallel [(return)
1934               (clobber (reg:SI FP_REGNUM))])]
1935   "nds32_can_use_return_insn ()"
1937   /* Emit as the simple return.  */
1938   if (cfun->machine->naked_p
1939       && (cfun->machine->va_args_size == 0))
1940     {
1941       emit_jump_insn (gen_return_internal ());
1942       DONE;
1943     }
1946 ;; This pattern is expanded only by the shrink-wrapping optimization
1947 ;; on paths where the function prologue has not been executed.
1948 (define_expand "simple_return"
1949   [(simple_return)]
1950   ""
1951   ""
1954 (define_insn "*nds32_return"
1955   [(parallel [(return)
1956    (clobber (reg:SI FP_REGNUM))])]
1957   ""
1959   return nds32_output_return ();
1961   [(set_attr "type" "branch")
1962    (set_attr "enabled" "yes")
1963    (set_attr "length" "4")])
1965 (define_insn "return_internal"
1966   [(simple_return)]
1967   ""
1969   if (TARGET_16_BIT)
1970     return "ret5";
1971   else
1972     return "ret";
1974   [(set_attr "type" "branch")
1975    (set_attr "enabled" "yes")
1976    (set (attr "length")
1977         (if_then_else (match_test "TARGET_16_BIT")
1978                       (const_int 2)
1979                       (const_int 4)))])
1982 ;; ----------------------------------------------------------------------------
1983 ;; Jump Table patterns
1984 ;; ----------------------------------------------------------------------------
1985 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
1986 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
1988 ;; operands[0]: The index to dispatch on.
1989 ;; operands[1]: The lower bound for indices in the table.
1990 ;; operands[2]: The total range of indices int the table.
1991 ;;              i.e. The largest index minus the smallest one.
1992 ;; operands[3]: A label that precedes the table itself.
1993 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
1995 ;; We need to create following sequences for jump table code generation:
1996 ;;   A) k <-- (plus (operands[0]) (-operands[1]))
1997 ;;   B) if (gtu k operands[2]) then goto operands[4]
1998 ;;   C) t <-- operands[3]
1999 ;;   D) z <-- (mem (plus (k << 0 or 1 or 2) t))
2000 ;;   E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
2001 ;;   F) jump to target with register t or z
2003 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
2004 (define_expand "casesi"
2005   [(match_operand:SI 0 "register_operand"  "r") ; index to jump on
2006    (match_operand:SI 1 "immediate_operand" "i") ; lower bound
2007    (match_operand:SI 2 "immediate_operand" "i") ; total range
2008    (match_operand:SI 3 "" "")                   ; table label
2009    (match_operand:SI 4 "" "")]                  ; Out of range label
2010   ""
2012   rtx add_tmp;
2013   rtx reg, test;
2014   rtx tmp_reg;
2016   /* Step A: "k <-- (plus (operands[0]) (-operands[1]))".  */
2017   if (operands[1] != const0_rtx)
2018     {
2019       reg = gen_reg_rtx (SImode);
2020       add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
2022       /* If the integer value is not in the range of imm15s,
2023          we need to force register first because our addsi3 pattern
2024          only accept nds32_rimm15s_operand predicate.  */
2025       add_tmp = force_reg (SImode, add_tmp);
2027       emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
2028       operands[0] = reg;
2029     }
2031   /* Step B: "if (gtu k operands[2]) then goto operands[4]".  */
2032   test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
2033   emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
2034                                   operands[4]));
2036   tmp_reg = gen_reg_rtx (SImode);
2037   /* Step C, D, E, and F, using another temporary register tmp_reg.  */
2038   if (flag_pic)
2039     emit_use (pic_offset_table_rtx);
2041   emit_jump_insn (gen_casesi_internal (operands[0],
2042                                        operands[3],
2043                                        tmp_reg));
2044   DONE;
2047 ;; We are receiving operands from casesi pattern:
2049 ;; operands[0]: The index that have been substracted with lower bound.
2050 ;; operands[1]: A label that precedes the table itself.
2051 ;; operands[2]: A temporary register to retrieve value in table.
2053 ;; We need to perform steps C, D, E, and F:
2055 ;;   C) t <-- operands[1]
2056 ;;   D) z <-- (mem (plus (operands[0] << m) t))
2057 ;;            m is 2 for normal jump table.
2058 ;;            m is 0, 1, or 2 for pc relative jump table based on diff size.
2059 ;;   E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
2060 ;;   F) Jump to target with register t or z.
2062 ;; The USE in this pattern is needed to tell flow analysis that this is
2063 ;; a CASESI insn.  It has no other purpose.
2064 (define_insn "casesi_internal"
2065   [(parallel [(set (pc)
2066                    (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
2067                                              (const_int 4))
2068                                     (label_ref (match_operand 1 "" "")))))
2069               (use (label_ref (match_dup 1)))
2070               (clobber (match_operand:SI 2 "register_operand" "=r"))
2071               (clobber (reg:SI TA_REGNUM))])]
2072   ""
2074   if (CASE_VECTOR_PC_RELATIVE)
2075     return nds32_output_casesi_pc_relative (operands);
2076   else
2077     return nds32_output_casesi (operands);
2079   [(set_attr "type" "branch")
2080    (set (attr "length")
2081         (if_then_else (match_test "flag_pic")
2082                       (const_int 28)
2083                       (const_int 20)))])
2085 ;; ----------------------------------------------------------------------------
2087 ;; Performance Extension
2089 ; If -fwrapv option is issued, GCC expects there will be
2090 ; signed overflow situation.  So the ABS(INT_MIN) is still INT_MIN
2091 ; (e.g. ABS(0x80000000)=0x80000000).
2092 ; However, the hardware ABS instruction of nds32 target
2093 ; always performs saturation: abs 0x80000000 -> 0x7fffffff.
2094 ; So that we can only enable abssi2 pattern if flag_wrapv is NOT presented.
2095 (define_insn "abssi2"
2096   [(set (match_operand:SI 0 "register_operand"         "=r")
2097         (abs:SI (match_operand:SI 1 "register_operand" " r")))]
2098   "TARGET_EXT_PERF && TARGET_HW_ABS && !flag_wrapv"
2099   "abs\t%0, %1"
2100   [(set_attr "type" "alu")
2101    (set_attr "length" "4")])
2103 (define_insn "clzsi2"
2104   [(set (match_operand:SI 0 "register_operand"         "=r")
2105         (clz:SI (match_operand:SI 1 "register_operand" " r")))]
2106   "TARGET_EXT_PERF"
2107   "clz\t%0, %1"
2108   [(set_attr "type" "alu")
2109    (set_attr "length" "4")])
2111 (define_insn "smaxsi3"
2112   [(set (match_operand:SI 0 "register_operand"          "=r")
2113         (smax:SI (match_operand:SI 1 "register_operand" " r")
2114                  (match_operand:SI 2 "register_operand" " r")))]
2115   "TARGET_EXT_PERF"
2116   "max\t%0, %1, %2"
2117   [(set_attr "type" "alu")
2118    (set_attr "length" "4")])
2120 (define_insn "sminsi3"
2121   [(set (match_operand:SI 0 "register_operand"          "=r")
2122         (smin:SI (match_operand:SI 1 "register_operand" " r")
2123                  (match_operand:SI 2 "register_operand" " r")))]
2124   "TARGET_EXT_PERF"
2125   "min\t%0, %1, %2"
2126   [(set_attr "type" "alu")
2127    (set_attr "length" "4")])
2129 (define_insn "btst"
2130   [(set (match_operand:SI 0 "register_operand"                     "=   r")
2131         (zero_extract:SI (match_operand:SI 1 "register_operand"    "    r")
2132                          (const_int 1)
2133                          (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")))]
2134   "TARGET_EXT_PERF"
2135   "btst\t%0, %1, %2"
2136   [(set_attr "type" "alu")
2137    (set_attr "length" "4")])
2139 (define_insn "ave"
2140   [(set (match_operand:SI 0 "register_operand" "=r")
2141         (truncate:SI
2142           (ashiftrt:DI
2143             (plus:DI
2144               (plus:DI
2145                 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
2146                 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
2147               (const_int 1))
2148           (const_int 1))))]
2149   "TARGET_EXT_PERF"
2150   "ave\t%0, %1, %2"
2151   [(set_attr "type" "alu")
2152    (set_attr "length" "4")])
2154 ;; ----------------------------------------------------------------------------
2156 ;; Pseudo NOPs
2158 (define_insn "relax_group"
2159   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
2160   ""
2161   ".relax_hint %0"
2162   [(set_attr "length" "0")]
2165 (define_insn "pop25return"
2166   [(return)
2167    (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
2168   ""
2169   "! return for pop 25"
2170   [(set_attr "length" "0")]
2173 ;; Add pc
2174 (define_insn "add_pc"
2175   [(set (match_operand:SI 0 "register_operand"          "=r")
2176         (plus:SI (match_operand:SI 1 "register_operand"  "0")
2177                  (pc)))]
2178   "flag_pic"
2179   "add5.pc\t%0"
2180   [(set_attr "type"    "alu")
2181    (set_attr "length"    "4")]
2183 ;; ----------------------------------------------------------------------------
2185 ;; Patterns for exception handling
2187 (define_expand "eh_return"
2188   [(use (match_operand 0 "general_operand"))]
2189   ""
2191   emit_insn (gen_nds32_eh_return (operands[0]));
2192   DONE;
2195 (define_insn_and_split "nds32_eh_return"
2196   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_EH_RETURN)]
2197   ""
2198   "#"
2199   "reload_completed"
2200   [(const_int 0)]
2202   rtx place;
2203   rtx addr;
2205   /* The operands[0] is the handler address.  We need to assign it
2206      to return address rtx so that we can jump to exception handler
2207      when returning from current function.  */
2209   if (cfun->machine->lp_size == 0)
2210     {
2211       /* If $lp is not saved in the stack frame, we can take $lp directly.  */
2212       place = gen_rtx_REG (SImode, LP_REGNUM);
2213     }
2214   else
2215     {
2216       /* Otherwise, we need to locate the stack slot of return address.
2217          The return address is generally saved in [$fp-4] location.
2218          However, DSE (dead store elimination) does not detect an alias
2219          between [$fp-x] and [$sp+y].  This can result in a store to save
2220          $lp introduced by builtin_eh_return() being incorrectly deleted
2221          if it is based on $fp.  The solution we take here is to compute
2222          the offset relative to stack pointer and then use $sp to access
2223          location so that the alias can be detected.
2224          FIXME: What if the immediate value "offset" is too large to be
2225                 fit in a single addi instruction?  */
2226       HOST_WIDE_INT offset;
2228       offset = (cfun->machine->fp_size
2229                 + cfun->machine->gp_size
2230                 + cfun->machine->lp_size
2231                 + cfun->machine->callee_saved_gpr_regs_size
2232                 + cfun->machine->callee_saved_area_gpr_padding_bytes
2233                 + cfun->machine->callee_saved_fpr_regs_size
2234                 + cfun->machine->eh_return_data_regs_size
2235                 + cfun->machine->local_size
2236                 + cfun->machine->out_args_size);
2238       addr = plus_constant (Pmode, stack_pointer_rtx, offset - 4);
2239       place = gen_frame_mem (SImode, addr);
2240     }
2242   emit_move_insn (place, operands[0]);
2243   DONE;
2246 ;; ----------------------------------------------------------------------------
2248 ;; Patterns for TLS.
2249 ;; The following two tls patterns don't be expanded directly because the
2250 ;; intermediate value may be spilled into the stack.  As a result, it is
2251 ;; hard to analyze the define-use chain in the relax_opt pass.
2254 ;; There is a unspec operand to record RELAX_GROUP number because each
2255 ;; emitted instruction need a relax_hint above it.
2256 (define_insn "tls_desc"
2257   [(set (reg:SI 0)
2258         (call (unspec_volatile:SI [(match_operand:SI 0 "nds32_symbolic_operand" "i")] UNSPEC_TLS_DESC)
2259               (const_int 1)))
2260    (use (unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
2261    (use (reg:SI GP_REGNUM))
2262    (clobber (reg:SI LP_REGNUM))
2263    (clobber (reg:SI TA_REGNUM))]
2264   ""
2265   {
2266     return nds32_output_tls_desc (operands);
2267   }
2268   [(set_attr "length" "20")
2269    (set_attr "type" "branch")]
2272 ;; There is a unspec operand to record RELAX_GROUP number because each
2273 ;; emitted instruction need a relax_hint above it.
2274 (define_insn "tls_ie"
2275   [(set (match_operand:SI 0 "register_operand" "=r")
2276         (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_TLS_IE))
2277    (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
2278    (use (reg:SI GP_REGNUM))]
2279   ""
2280   {
2281     return nds32_output_tls_ie (operands);
2282   }
2283   [(set (attr "length") (if_then_else (match_test "flag_pic")
2284                                       (const_int 12)
2285                                       (const_int 8)))
2286    (set_attr "type" "misc")]
2289 ;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode.
2290 (define_insn "addsi3_32bit"
2291   [(set (match_operand:SI 0 "register_operand"             "=r")
2292         (unspec:SI [(match_operand:SI 1 "register_operand" "%r")
2293                     (match_operand:SI 2 "register_operand" " r")] UNSPEC_ADD32))]
2294   ""
2295   "add\t%0, %1, %2";
2296   [(set_attr "type"    "alu")
2297    (set_attr "length"  "4")
2298    (set_attr "feature" "v1")])
2300 ;; ----------------------------------------------------------------------------