[NDS32] Implement fp-as-gp optimization.
[official-gcc.git] / gcc / config / nds32 / nds32.md
blobcf1ad9bd1b078fc2f50eb4befde80736286c6c49
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 ();
1834   /* If cfun->machine->fp_as_gp_p is true, we can generate special
1835      directive to guide linker doing fp-as-gp optimization.
1836      However, for a naked function, which means
1837      it should not have prologue/epilogue,
1838      using fp-as-gp still requires saving $fp by push/pop behavior and
1839      there is no benefit to use fp-as-gp on such small function.
1840      So we need to make sure this function is NOT naked as well.  */
1841   if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p)
1842     emit_insn (gen_omit_fp_begin (gen_rtx_REG (SImode, FP_REGNUM)));
1844   DONE;
1847 (define_expand "epilogue" [(const_int 0)]
1848   ""
1850   /* If cfun->machine->fp_as_gp_p is true, we can generate special
1851      directive to guide linker doing fp-as-gp optimization.
1852      However, for a naked function, which means
1853      it should not have prologue/epilogue,
1854      using fp-as-gp still requires saving $fp by push/pop behavior and
1855      there is no benefit to use fp-as-gp on such small function.
1856      So we need to make sure this function is NOT naked as well.  */
1857   if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p)
1858     emit_insn (gen_omit_fp_end (gen_rtx_REG (SImode, FP_REGNUM)));
1860   /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
1861      In addition, we need to check if v3push is indeed available.  */
1862   if (NDS32_V3PUSH_AVAILABLE_P)
1863     nds32_expand_epilogue_v3pop (false);
1864   else
1865     nds32_expand_epilogue (false);
1866   DONE;
1869 (define_expand "sibcall_epilogue" [(const_int 0)]
1870   ""
1872   /* Pass true to indicate that this is sibcall epilogue and
1873      exit from a function without the final branch back to the
1874      calling function.  */
1875   nds32_expand_epilogue (true);
1877   DONE;
1881 ;; nop instruction.
1883 (define_insn "nop"
1884   [(const_int 0)]
1885   ""
1887   if (TARGET_16_BIT)
1888     return "nop16";
1889   else
1890     return "nop";
1892   [(set_attr "type" "misc")
1893    (set_attr "enabled" "yes")
1894    (set (attr "length")
1895         (if_then_else (match_test "TARGET_16_BIT")
1896                       (const_int 2)
1897                       (const_int 4)))])
1900 ;; ----------------------------------------------------------------------------
1901 ;; Stack push/pop operations
1902 ;; ----------------------------------------------------------------------------
1904 ;; The pattern for stack push.
1905 ;; Both stack_push_multiple and stack_v3push use the following pattern.
1906 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1907 (define_insn "*stack_push"
1908   [(match_parallel 0 "nds32_stack_push_operation"
1909      [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1910                             (match_operand:SI 1 "const_int_operand" "")))
1911            (match_operand:SI 2 "register_operand" ""))
1912      ])]
1913   ""
1915   return nds32_output_stack_push (operands[0]);
1917   [(set_attr "type" "store_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 ;; The pattern for stack pop.
1927 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1928 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1929 (define_insn "*stack_pop"
1930   [(match_parallel 0 "nds32_stack_pop_operation"
1931      [(set (match_operand:SI 1 "register_operand" "")
1932            (mem:SI (reg:SI SP_REGNUM)))
1933      ])]
1934   ""
1936   return nds32_output_stack_pop (operands[0]);
1938   [(set_attr "type" "load_multiple")
1939    (set_attr "combo" "12")
1940    (set_attr "enabled" "yes")
1941    (set (attr "length")
1942         (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1943                       (const_int 2)
1944                       (const_int 4)))])
1947 ;; ----------------------------------------------------------------------------
1948 ;; Return operation patterns
1949 ;; ----------------------------------------------------------------------------
1951 ;; Use this pattern to expand a return instruction
1952 ;; with simple_return rtx if no epilogue is required.
1953 (define_expand "return"
1954   [(parallel [(return)
1955               (clobber (reg:SI FP_REGNUM))])]
1956   "nds32_can_use_return_insn ()"
1958   /* Emit as the simple return.  */
1959   if (!cfun->machine->fp_as_gp_p
1960       && cfun->machine->naked_p
1961       && (cfun->machine->va_args_size == 0))
1962     {
1963       emit_jump_insn (gen_return_internal ());
1964       DONE;
1965     }
1968 ;; This pattern is expanded only by the shrink-wrapping optimization
1969 ;; on paths where the function prologue has not been executed.
1970 ;; However, such optimization may reorder the prologue/epilogue blocks
1971 ;; together with basic blocks within function body.
1972 ;; So we must disable this pattern if we have already decided
1973 ;; to perform fp_as_gp optimization, which requires prologue to be
1974 ;; first block and epilogue to be last block.
1975 (define_expand "simple_return"
1976   [(simple_return)]
1977   "!cfun->machine->fp_as_gp_p"
1978   ""
1981 (define_insn "*nds32_return"
1982   [(parallel [(return)
1983    (clobber (reg:SI FP_REGNUM))])]
1984   ""
1986   return nds32_output_return ();
1988   [(set_attr "type" "branch")
1989    (set_attr "enabled" "yes")
1990    (set_attr "length" "4")])
1992 (define_insn "return_internal"
1993   [(simple_return)]
1994   ""
1996   if (TARGET_16_BIT)
1997     return "ret5";
1998   else
1999     return "ret";
2001   [(set_attr "type" "branch")
2002    (set_attr "enabled" "yes")
2003    (set (attr "length")
2004         (if_then_else (match_test "TARGET_16_BIT")
2005                       (const_int 2)
2006                       (const_int 4)))])
2009 ;; ----------------------------------------------------------------------------
2010 ;; Jump Table patterns
2011 ;; ----------------------------------------------------------------------------
2012 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
2013 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
2015 ;; operands[0]: The index to dispatch on.
2016 ;; operands[1]: The lower bound for indices in the table.
2017 ;; operands[2]: The total range of indices int the table.
2018 ;;              i.e. The largest index minus the smallest one.
2019 ;; operands[3]: A label that precedes the table itself.
2020 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
2022 ;; We need to create following sequences for jump table code generation:
2023 ;;   A) k <-- (plus (operands[0]) (-operands[1]))
2024 ;;   B) if (gtu k operands[2]) then goto operands[4]
2025 ;;   C) t <-- operands[3]
2026 ;;   D) z <-- (mem (plus (k << 0 or 1 or 2) t))
2027 ;;   E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
2028 ;;   F) jump to target with register t or z
2030 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
2031 (define_expand "casesi"
2032   [(match_operand:SI 0 "register_operand"  "r") ; index to jump on
2033    (match_operand:SI 1 "immediate_operand" "i") ; lower bound
2034    (match_operand:SI 2 "immediate_operand" "i") ; total range
2035    (match_operand:SI 3 "" "")                   ; table label
2036    (match_operand:SI 4 "" "")]                  ; Out of range label
2037   ""
2039   rtx add_tmp;
2040   rtx reg, test;
2041   rtx tmp_reg;
2043   /* Step A: "k <-- (plus (operands[0]) (-operands[1]))".  */
2044   if (operands[1] != const0_rtx)
2045     {
2046       reg = gen_reg_rtx (SImode);
2047       add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
2049       /* If the integer value is not in the range of imm15s,
2050          we need to force register first because our addsi3 pattern
2051          only accept nds32_rimm15s_operand predicate.  */
2052       add_tmp = force_reg (SImode, add_tmp);
2054       emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
2055       operands[0] = reg;
2056     }
2058   /* Step B: "if (gtu k operands[2]) then goto operands[4]".  */
2059   test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
2060   emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
2061                                   operands[4]));
2063   tmp_reg = gen_reg_rtx (SImode);
2064   /* Step C, D, E, and F, using another temporary register tmp_reg.  */
2065   if (flag_pic)
2066     emit_use (pic_offset_table_rtx);
2068   emit_jump_insn (gen_casesi_internal (operands[0],
2069                                        operands[3],
2070                                        tmp_reg));
2071   DONE;
2074 ;; We are receiving operands from casesi pattern:
2076 ;; operands[0]: The index that have been substracted with lower bound.
2077 ;; operands[1]: A label that precedes the table itself.
2078 ;; operands[2]: A temporary register to retrieve value in table.
2080 ;; We need to perform steps C, D, E, and F:
2082 ;;   C) t <-- operands[1]
2083 ;;   D) z <-- (mem (plus (operands[0] << m) t))
2084 ;;            m is 2 for normal jump table.
2085 ;;            m is 0, 1, or 2 for pc relative jump table based on diff size.
2086 ;;   E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
2087 ;;   F) Jump to target with register t or z.
2089 ;; The USE in this pattern is needed to tell flow analysis that this is
2090 ;; a CASESI insn.  It has no other purpose.
2091 (define_insn "casesi_internal"
2092   [(parallel [(set (pc)
2093                    (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
2094                                              (const_int 4))
2095                                     (label_ref (match_operand 1 "" "")))))
2096               (use (label_ref (match_dup 1)))
2097               (clobber (match_operand:SI 2 "register_operand" "=r"))
2098               (clobber (reg:SI TA_REGNUM))])]
2099   ""
2101   if (CASE_VECTOR_PC_RELATIVE)
2102     return nds32_output_casesi_pc_relative (operands);
2103   else
2104     return nds32_output_casesi (operands);
2106   [(set_attr "type" "branch")
2107    (set (attr "length")
2108         (if_then_else (match_test "flag_pic")
2109                       (const_int 28)
2110                       (const_int 20)))])
2112 ;; ----------------------------------------------------------------------------
2114 ;; Performance Extension
2116 ; If -fwrapv option is issued, GCC expects there will be
2117 ; signed overflow situation.  So the ABS(INT_MIN) is still INT_MIN
2118 ; (e.g. ABS(0x80000000)=0x80000000).
2119 ; However, the hardware ABS instruction of nds32 target
2120 ; always performs saturation: abs 0x80000000 -> 0x7fffffff.
2121 ; So that we can only enable abssi2 pattern if flag_wrapv is NOT presented.
2122 (define_insn "abssi2"
2123   [(set (match_operand:SI 0 "register_operand"         "=r")
2124         (abs:SI (match_operand:SI 1 "register_operand" " r")))]
2125   "TARGET_EXT_PERF && TARGET_HW_ABS && !flag_wrapv"
2126   "abs\t%0, %1"
2127   [(set_attr "type" "alu")
2128    (set_attr "length" "4")])
2130 (define_insn "clzsi2"
2131   [(set (match_operand:SI 0 "register_operand"         "=r")
2132         (clz:SI (match_operand:SI 1 "register_operand" " r")))]
2133   "TARGET_EXT_PERF"
2134   "clz\t%0, %1"
2135   [(set_attr "type" "alu")
2136    (set_attr "length" "4")])
2138 (define_insn "smaxsi3"
2139   [(set (match_operand:SI 0 "register_operand"          "=r")
2140         (smax:SI (match_operand:SI 1 "register_operand" " r")
2141                  (match_operand:SI 2 "register_operand" " r")))]
2142   "TARGET_EXT_PERF"
2143   "max\t%0, %1, %2"
2144   [(set_attr "type" "alu")
2145    (set_attr "length" "4")])
2147 (define_insn "sminsi3"
2148   [(set (match_operand:SI 0 "register_operand"          "=r")
2149         (smin:SI (match_operand:SI 1 "register_operand" " r")
2150                  (match_operand:SI 2 "register_operand" " r")))]
2151   "TARGET_EXT_PERF"
2152   "min\t%0, %1, %2"
2153   [(set_attr "type" "alu")
2154    (set_attr "length" "4")])
2156 (define_insn "btst"
2157   [(set (match_operand:SI 0 "register_operand"                     "=   r")
2158         (zero_extract:SI (match_operand:SI 1 "register_operand"    "    r")
2159                          (const_int 1)
2160                          (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")))]
2161   "TARGET_EXT_PERF"
2162   "btst\t%0, %1, %2"
2163   [(set_attr "type" "alu")
2164    (set_attr "length" "4")])
2166 (define_insn "ave"
2167   [(set (match_operand:SI 0 "register_operand" "=r")
2168         (truncate:SI
2169           (ashiftrt:DI
2170             (plus:DI
2171               (plus:DI
2172                 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
2173                 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
2174               (const_int 1))
2175           (const_int 1))))]
2176   "TARGET_EXT_PERF"
2177   "ave\t%0, %1, %2"
2178   [(set_attr "type" "alu")
2179    (set_attr "length" "4")])
2181 ;; ----------------------------------------------------------------------------
2183 ;; Pseudo NOPs
2185 (define_insn "relax_group"
2186   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
2187   ""
2188   ".relax_hint %0"
2189   [(set_attr "length" "0")]
2192 ;; Output .omit_fp_begin for fp-as-gp optimization.
2193 ;; Also we have to set $fp register.
2194 (define_insn "omit_fp_begin"
2195   [(set (match_operand:SI 0 "register_operand" "=x")
2196         (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_OMIT_FP_BEGIN))]
2197   ""
2198   "! -----\;.omit_fp_begin\;la\t$fp,_FP_BASE_\;! -----"
2199   [(set_attr "length" "8")]
2202 ;; Output .omit_fp_end for fp-as-gp optimization.
2203 ;; Claim that we have to use $fp register.
2204 (define_insn "omit_fp_end"
2205   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "x")] UNSPEC_VOLATILE_OMIT_FP_END)]
2206   ""
2207   "! -----\;.omit_fp_end\;! -----"
2208   [(set_attr "length" "0")]
2211 (define_insn "pop25return"
2212   [(return)
2213    (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
2214   ""
2215   "! return for pop 25"
2216   [(set_attr "length" "0")]
2219 ;; Add pc
2220 (define_insn "add_pc"
2221   [(set (match_operand:SI 0 "register_operand"          "=r")
2222         (plus:SI (match_operand:SI 1 "register_operand"  "0")
2223                  (pc)))]
2224   "flag_pic"
2225   "add5.pc\t%0"
2226   [(set_attr "type"    "alu")
2227    (set_attr "length"    "4")]
2230 (define_expand "bswapsi2"
2231   [(set (match_operand:SI 0 "register_operand" "=r")
2232         (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
2233   ""
2235   emit_insn (gen_unspec_wsbh (operands[0], operands[1]));
2236   emit_insn (gen_rotrsi3 (operands[0], operands[0], GEN_INT (16)));
2237   DONE;
2240 (define_insn "bswaphi2"
2241   [(set (match_operand:HI 0 "register_operand" "=r")
2242         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
2243   ""
2244   "wsbh\t%0, %1"
2245   [(set_attr "type"    "alu")
2246    (set_attr "length"    "4")]
2249 ;; ----------------------------------------------------------------------------
2251 ;; Patterns for exception handling
2253 (define_expand "eh_return"
2254   [(use (match_operand 0 "general_operand"))]
2255   ""
2257   emit_insn (gen_nds32_eh_return (operands[0]));
2258   DONE;
2261 (define_insn_and_split "nds32_eh_return"
2262   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_EH_RETURN)]
2263   ""
2264   "#"
2265   "reload_completed"
2266   [(const_int 0)]
2268   rtx place;
2269   rtx addr;
2271   /* The operands[0] is the handler address.  We need to assign it
2272      to return address rtx so that we can jump to exception handler
2273      when returning from current function.  */
2275   if (cfun->machine->lp_size == 0)
2276     {
2277       /* If $lp is not saved in the stack frame, we can take $lp directly.  */
2278       place = gen_rtx_REG (SImode, LP_REGNUM);
2279     }
2280   else
2281     {
2282       /* Otherwise, we need to locate the stack slot of return address.
2283          The return address is generally saved in [$fp-4] location.
2284          However, DSE (dead store elimination) does not detect an alias
2285          between [$fp-x] and [$sp+y].  This can result in a store to save
2286          $lp introduced by builtin_eh_return() being incorrectly deleted
2287          if it is based on $fp.  The solution we take here is to compute
2288          the offset relative to stack pointer and then use $sp to access
2289          location so that the alias can be detected.
2290          FIXME: What if the immediate value "offset" is too large to be
2291                 fit in a single addi instruction?  */
2292       HOST_WIDE_INT offset;
2294       offset = (cfun->machine->fp_size
2295                 + cfun->machine->gp_size
2296                 + cfun->machine->lp_size
2297                 + cfun->machine->callee_saved_gpr_regs_size
2298                 + cfun->machine->callee_saved_area_gpr_padding_bytes
2299                 + cfun->machine->callee_saved_fpr_regs_size
2300                 + cfun->machine->eh_return_data_regs_size
2301                 + cfun->machine->local_size
2302                 + cfun->machine->out_args_size);
2304       addr = plus_constant (Pmode, stack_pointer_rtx, offset - 4);
2305       place = gen_frame_mem (SImode, addr);
2306     }
2308   emit_move_insn (place, operands[0]);
2309   DONE;
2312 ;; ----------------------------------------------------------------------------
2314 ;; Patterns for TLS.
2315 ;; The following two tls patterns don't be expanded directly because the
2316 ;; intermediate value may be spilled into the stack.  As a result, it is
2317 ;; hard to analyze the define-use chain in the relax_opt pass.
2320 ;; There is a unspec operand to record RELAX_GROUP number because each
2321 ;; emitted instruction need a relax_hint above it.
2322 (define_insn "tls_desc"
2323   [(set (reg:SI 0)
2324         (call (unspec_volatile:SI [(match_operand:SI 0 "nds32_symbolic_operand" "i")] UNSPEC_TLS_DESC)
2325               (const_int 1)))
2326    (use (unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
2327    (use (reg:SI GP_REGNUM))
2328    (clobber (reg:SI LP_REGNUM))
2329    (clobber (reg:SI TA_REGNUM))]
2330   ""
2331   {
2332     return nds32_output_tls_desc (operands);
2333   }
2334   [(set_attr "length" "20")
2335    (set_attr "type" "branch")]
2338 ;; There is a unspec operand to record RELAX_GROUP number because each
2339 ;; emitted instruction need a relax_hint above it.
2340 (define_insn "tls_ie"
2341   [(set (match_operand:SI 0 "register_operand" "=r")
2342         (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_TLS_IE))
2343    (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
2344    (use (reg:SI GP_REGNUM))]
2345   ""
2346   {
2347     return nds32_output_tls_ie (operands);
2348   }
2349   [(set (attr "length") (if_then_else (match_test "flag_pic")
2350                                       (const_int 12)
2351                                       (const_int 8)))
2352    (set_attr "type" "misc")]
2355 ;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode.
2356 (define_insn "addsi3_32bit"
2357   [(set (match_operand:SI 0 "register_operand"             "=r")
2358         (unspec:SI [(match_operand:SI 1 "register_operand" "%r")
2359                     (match_operand:SI 2 "register_operand" " r")] UNSPEC_ADD32))]
2360   ""
2361   "add\t%0, %1, %2";
2362   [(set_attr "type"    "alu")
2363    (set_attr "length"  "4")
2364    (set_attr "feature" "v1")])
2366 ;; ----------------------------------------------------------------------------