* gcc-interface/trans.c (process_freeze_entity): Be prepared for a
[official-gcc.git] / gcc / config / ft32 / ft32.md
blob2e772faf72fd588a0d3bc5eba5d48bff2efb9bd2
1 ;; Machine description for FT32
2 ;; Copyright (C) 2015-2017 Free Software Foundation, Inc.
3 ;; Contributed by FTDI <support@ftdi.com>
5 ;; This file is part of GCC.
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 ;; -------------------------------------------------------------------------
22 ;; FT32 specific constraints, predicates and attributes
23 ;; -------------------------------------------------------------------------
25 (include "constraints.md")
26 (include "predicates.md")
28 (define_constants [
29   (FP_REG 0)
30   (SP_REG 1)
31   (CC_REG 35)
34 (define_c_enum "unspec"
35   [UNSPEC_STRLEN
36    UNSPEC_MOVMEM
37    UNSPEC_SETMEM
38    UNSPEC_STPCPY
39    UNSPEC_INDEX_JMP
40    UNSPEC_LPM
41    UNSPEC_FMUL
42    UNSPEC_FMULS
43    UNSPEC_FMULSU
44    UNSPEC_COPYSIGN
45    UNSPEC_IDENTITY
46    UNSPEC_INSERT_BITS
47    UNSPEC_JMP_EPILOG
48    UNSPEC_JMP_EPILOG24
49    UNSPEC_JMP_PROLOG
50    UNSPEC_XCHG
51    ])
53 ;; -------------------------------------------------------------------------
54 ;; nop instruction
55 ;; -------------------------------------------------------------------------
57 (define_insn "nop"
58   [(const_int 0)]
59   ""
60   "nop")
62 ;; -------------------------------------------------------------------------
63 ;; Arithmetic instructions
64 ;; -------------------------------------------------------------------------
66 (define_insn "addsi3"
67   [(set (match_operand:SI 0 "register_operand" "=r,r")
68           (plus:SI
69            (match_operand:SI 1 "register_operand" "r,r")
70            (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))
71    ]
72   ""
73   "add.l  %0,%1,%2")
75 (define_insn "subsi3"
76   [(set (match_operand:SI 0 "register_operand" "=r,r")
77           (minus:SI
78            (match_operand:SI 1 "register_operand" "r,r")
79            (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))]
80   ""
81   "sub.l  %0,%1,%2")
83 (define_insn "mulsi3"
84   [(set (match_operand:SI 0 "register_operand" "=r,r")
85           (mult:SI
86            (match_operand:SI 1 "register_operand" "r,r")
87            (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))]
88   ""
89   "mul.l  %0,%1,%2")
91 (define_insn "umulsidi3"
92   [(set (match_operand:DI 0 "register_operand" "=r,r")
93     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
94          (zero_extend:DI (match_operand:SI 2 "ft32_rimm_operand" "r,KA"))))
95    (clobber (reg:CC CC_REG))]
96   ""
97   "mul.l  $cc,%1,%2\;muluh.l %h0,%1,%2\;move.l   %0,$cc")
99 (define_insn "divsi3"
100   [(set (match_operand:SI 0 "register_operand" "=r,r")
101           (div:SI
102            (match_operand:SI 1 "register_operand" "r,r")
103            (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
104   "!TARGET_NODIV"
105   "div.l  %0,%1,%2")
107 (define_insn "modsi3"
108   [(set (match_operand:SI 0 "register_operand" "=r,r")
109           (mod:SI
110            (match_operand:SI 1 "register_operand" "r,r")
111            (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
112   "!TARGET_NODIV"
113   "mod.l  %0,%1,%2")
115 (define_insn "udivsi3"
116   [(set (match_operand:SI 0 "register_operand" "=r,r")
117           (udiv:SI
118            (match_operand:SI 1 "register_operand" "r,r")
119            (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
120   "!TARGET_NODIV"
121   "udiv.l %0,%1,%2")
123 (define_insn "umodsi3"
124   [(set (match_operand:SI 0 "register_operand" "=r,r")
125           (umod:SI
126            (match_operand:SI 1 "register_operand" "r,r")
127            (match_operand:SI 2 "register_operand" "r,KA")))]
128   "!TARGET_NODIV"
129   "umod.l %0,%1,%2")
131 (define_insn "extvsi"
132   [(set (match_operand:SI 0 "register_operand" "=r")
133         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
134                       (match_operand:SI 2 "ft32_bwidth_operand" "b")
135                       (match_operand:SI 3 "const_int_operand" "i")))]
136   ""
137   "bexts.l %0,%1,((15 & %2) << 5) | (%3)")
139 (define_insn "extzvsi"
140   [(set (match_operand:SI 0 "register_operand" "=r")
141         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
142                       (match_operand:SI 2 "ft32_bwidth_operand" "b")
143                       (match_operand:SI 3 "const_int_operand" "i")))]
144   ""
145   "bextu.l %0,%1,((15 & %2) << 5) | (%3)")
147 (define_insn "insvsi"
148   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
149                          (match_operand:SI 1 "ft32_bwidth_operand" "b,b")
150                          (match_operand:SI 2 "const_int_operand" "i,i"))
151         (match_operand:SI 3 "general_operand" "r,O"))
152    (clobber (match_scratch:SI 4 "=&r,r"))]
153   ""
154   {
155     if (which_alternative == 0)
156       {
157         return \"ldl.l %4,%3,((%1&15)<<5)|(%2)\;bins.l %0,%0,%4\";
158       }
159     else
160       {
161         if ((INTVAL(operands[3]) == 0) || (INTVAL(operands[1]) == 1))
162           return \"bins.l %0,%0,(%3<<9)|((%1&15)<<5)|(%2)\";
163         else
164           return \"ldk.l %4,(%3<<10)|((%1&15)<<5)|(%2)\;bins.l %0,%0,%4\";
165       }
166   })
168 ;; -------------------------------------------------------------------------
169 ;; Unary arithmetic instructions
170 ;; -------------------------------------------------------------------------
172 (define_insn "one_cmplsi2"
173   [(set (match_operand:SI 0 "register_operand" "=r")
174         (not:SI (match_operand:SI 1 "register_operand" "r")))]
175   ""
176   "xor.l    %0,%1,-1")
178 ;; -------------------------------------------------------------------------
179 ;; Logical operators
180 ;; -------------------------------------------------------------------------
182 (define_insn "andsi3"
183   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
184         (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
185                 (match_operand:SI 2 "general_operand"  "r,x,KA")))]
186   ""
187   "@
188   and.l  %0,%1,%2
189   bins.l %0,%1,%g2
190   and.l  %0,%1,%2")
192 (define_insn "andqi3"
193   [(set (match_operand:QI 0 "register_operand" "=r,r,r")
194         (and:QI (match_operand:QI 1 "register_operand" "r,r,r")
195                 (match_operand:QI 2 "general_operand"  "r,x,KA")))]
196   ""
197   "@
198   and.b  %0,%1,%2
199   bins.b %0,%1,%g2
200   and.b  %0,%1,%2")
202 (define_insn "xorsi3"
203   [(set (match_operand:SI 0 "register_operand" "=r,r")
204         (xor:SI (match_operand:SI 1 "register_operand" "r,r")
205                 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
206   ""
208   return "xor.l  %0,%1,%2";
211 (define_insn "iorsi3"
212   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
213         (ior:SI (match_operand:SI 1 "register_operand" "r,r,r")
214                 (match_operand:SI 2 "general_operand"  "r,w,KA")))]
215   ""
216   "@
217   or.l   %0,%1,%2
218   bins.l %0,%1,%f2
219   or.l   %0,%1,%2")
221 ;; -------------------------------------------------------------------------
222 ;; Shifters
223 ;; -------------------------------------------------------------------------
225 (define_insn "ashlsi3"
226   [(set (match_operand:SI 0 "register_operand" "=r,r")
227         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
228                    (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
229   ""
231   return "ashl.l %0,%1,%2";
234 (define_insn "ashrsi3"
235   [(set (match_operand:SI 0 "register_operand" "=r,r")
236         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
237                      (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
238   ""
240   return "ashr.l %0,%1,%2";
243 (define_insn "lshrsi3"
244   [(set (match_operand:SI 0 "register_operand" "=r,r")
245         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
246                      (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
247   ""
249   return "lshr.l %0,%1,%2";
252 ;; -------------------------------------------------------------------------
253 ;; Move instructions
254 ;; -------------------------------------------------------------------------
256 ;; SImode
258 (define_insn "*sne"
259    [(set (match_operand:SI 0 "register_operand" "=r")
260          (reg:SI CC_REG))]
261    ""
262    "bextu.l %0,$cc,32|0\;xor.l %0,%0,-1"
265 ;; Push a register onto the stack
266 (define_insn "movsi_push"
267   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
268         (match_operand:SI 0 "register_operand" "r"))]
269   ""
270   "push.l %0")
272 ;; Pop a register from the stack
273 (define_insn "movsi_pop"
274   [(set (match_operand:SI 0 "register_operand" "=r")
275         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
276   ""
277   "pop.l  %0")
279 (define_expand "movsi"
280    [(set (match_operand:SI 0 "general_operand" "")
281         (match_operand:SI 1 "general_operand" ""))]
282    ""
284   /* If this is a store, force the value into a register.  */
285   if (!(reload_in_progress || reload_completed))
286     {
287       if (MEM_P (operands[0]))
288         {
289           operands[1] = force_reg (SImode, operands[1]);
290           if (MEM_P (XEXP (operands[0], 0)))
291             operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
292         }
293       else
294         {
295           if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
296             operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0)));
297         }
298       /*
299       if (MEM_P (operands[0])) {
300         rtx o = XEXP (operands[0], 0);
301         if (!REG_P(o) &&
302             !CONST_INT_P(o) &&
303             GET_CODE(o) != SYMBOL_REF &&
304             GET_CODE(o) != LABEL_REF) {
305           operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
306         }
307       }
308       */
309     }
312 (define_insn "*rtestsi"
313   [(set (reg:SI CC_REG)
314         (match_operand:SI 0 "register_operand" "r"))]
315   ""
316   "cmp.l  %0,0"
319 (define_insn "*rtestqi"
320   [(set (reg:QI CC_REG)
321         (match_operand:QI 0 "register_operand" "r"))]
322   ""
323   "cmp.b  %0,0"
326 (define_insn "*movsi"
327   [(set (match_operand:SI 0 "nonimmediate_operand"         "=r,BW,r,r,r,r,A,r,r")
328         (match_operand:SI 1 "ft32_general_movsrc_operand"   "r,r,BW,A,S,i,r,e,f"))]
329   "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
330   "@
331    move.l %0,%1
332    sti.l  %0,%1
333    ldi.l  %0,%1
334    lda.l  %0,%1
335    ldk.l  %0,%1
336    *return ft32_load_immediate(operands[0], INTVAL(operands[1]));
337    sta.l  %0,%1
338    lpm.l  %0,%1
339    lpmi.l %0,%1"
342 (define_expand "movqi"
343   [(set (match_operand:QI 0 "general_operand" "")
344         (match_operand:QI 1 "general_operand" ""))]
345   ""
347   /* If this is a store, force the value into a register.  */
348   if (!(reload_in_progress || reload_completed))
349     {
350       if (MEM_P (operands[0]))
351         {
352           operands[1] = force_reg (QImode, operands[1]);
353           if (MEM_P (XEXP (operands[0], 0)))
354             operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0)));
355         }
356       else
357         {
358           if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
359             operands[1] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[1], 0)));
360         }
361       if (MEM_P (operands[0]) && !REG_P(XEXP (operands[0], 0)))
362         {
363           operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0)));
364         }
365     }
368 (define_insn "zero_extendqisi2"
369   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r")
370     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "BW,r,f")))]
371   ""
372   "@
373   ldi.b  %0,%1
374   and.l  %0,%1,255
375   lpmi.b %0,%1"
378 (define_insn "extendqisi2"
379   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
380     (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r")))]
381   ""
382   "bexts.l %0,%1,(8<<5)|0"
385 (define_insn "zero_extendhisi2"
386   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r")
387     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "BW,r,f")))]
388   ""
389   "@
390   ldi.s  %0,%1
391   bextu.l %0,%1,(0<<5)|0
392   lpmi.s %0,%1"
395 (define_insn "extendhisi2"
396   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
397     (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
398   ""
399   "bexts.l %0,%1,(0<<5)|0"
402 (define_insn "*movqi"
403   [(set (match_operand:QI 0 "nonimmediate_operand"           "=r,BW,r,r,A,r,r,r")
404         (match_operand:QI 1 "ft32_general_movsrc_operand"  "r,r,BW,A,r,I,e,f"))]
405   "register_operand (operands[0], QImode)
406    || register_operand (operands[1], QImode)"
407   "@
408    move.b %0,%1
409    sti.b  %0,%1
410    ldi.b  %0,%1
411    lda.b  %0,%1
412    sta.b  %0,%1
413    ldk.b  %0,%1
414    lpm.b  %0,%1
415    lpmi.b %0,%1"
418 (define_expand "movhi"
419   [(set (match_operand:HI 0 "general_operand" "")
420         (match_operand:HI 1 "general_operand" ""))]
421   ""
423   /* If this is a store, force the value into a register.  */
424   if (!(reload_in_progress || reload_completed))
425     {
426       if (MEM_P (operands[0]))
427         {
428           operands[1] = force_reg (HImode, operands[1]);
429           if (MEM_P (XEXP (operands[0], 0)))
430             operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0)));
431         }
432       else
433         {
434           if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0)))
435             operands[1] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[1], 0)));
436         }
437       if (MEM_P (operands[0]))
438         {
439           rtx o = XEXP (operands[0], 0);
440           if (!REG_P(o) &&
441               !CONST_INT_P(o) &&
442               GET_CODE(o) != SYMBOL_REF &&
443               GET_CODE(o) != LABEL_REF) {
444             operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0)));
445           }
446         }
447     }
450 (define_insn "*movhi"
451   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r")
452         (match_operand:HI 1 "ft32_general_movsrc_operand"  "r,r,BW,A,r,I,e,f"))]
453   "(register_operand (operands[0], HImode)
454     || register_operand (operands[1], HImode))"
455   "@
456    move.s %0,%1
457    sti.s  %0,%1
458    ldi.s  %0,%1
459    lda.s  %0,%1
460    sta.s  %0,%1
461    ldk.s  %0,%1
462    lpm.s  %0,%1
463    lpmi.s %0,%1"
466 (define_expand "movsf"
467   [(set (match_operand:SF 0 "general_operand" "")
468         (match_operand:SF 1 "general_operand" ""))]
469   ""
471   /* If this is a store, force the value into a register.  */
472   if (MEM_P (operands[0]))
473     operands[1] = force_reg (SFmode, operands[1]);
474   if (CONST_DOUBLE_P(operands[1]))
475     operands[1] = force_const_mem(SFmode, operands[1]);
478 (define_insn "*movsf"
479   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r")
480         (match_operand:SF 1 "ft32_general_movsrc_operand"  "r,r,BW,A,r,I,f"))]
481   "(register_operand (operands[0], SFmode)
482     || register_operand (operands[1], SFmode))"
483   "@
484    move.l %0,%1
485    sti.l  %0,%1
486    ldi.l  %0,%1
487    lda.l  %0,%1
488    sta.l  %0,%1
489    ldk.l  %0,%1
490    lpmi.l %0,%1"
493 ;; -------------------------------------------------------------------------
494 ;; Compare instructions
495 ;; -------------------------------------------------------------------------
497 (define_expand "cbranchsi4"
498   [(set (reg:CC CC_REG)
499         (compare:CC
500          (match_operand:SI 1 "register_operand" "")
501          (match_operand:SI 2 "ft32_rimm_operand" "")))
502    (set (pc)
503         (if_then_else (match_operator 0 "comparison_operator"
504                        [(reg:CC CC_REG) (const_int 0)])
505                       (label_ref (match_operand 3 "" ""))
506                       (pc)))]
507   ""
508   "")
510 (define_insn "cmpsi"
511   [(set (reg:CC CC_REG)
512         (compare:CC
513          (match_operand:SI 0 "register_operand" "r,r")
514          (match_operand:SI 1 "ft32_rimm_operand" "r,KA")))]
515   ""
516   "cmp.l  %0,%1")
518 (define_insn ""
519   [(set (pc)
520         (if_then_else
521          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
522                               (const_int 1)
523                               (match_operand:SI 1 "const_int_operand" "i"))
524              (const_int 0))
525          (label_ref (match_operand 2 "" ""))
526          (pc)))
527    (clobber (reg:CC CC_REG))]
528   ""
529   "btst.l %0,(1<<5)|%1\;jmpc   nz,%l2")
531 (define_insn ""
532   [(set (pc)
533         (if_then_else
534          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
535                               (const_int 1)
536                               (match_operand:SI 1 "const_int_operand" "i"))
537              (const_int 0))
538          (label_ref (match_operand 2 "" ""))
539          (pc)))
540    (clobber (reg:CC CC_REG))]
541   ""
542   "btst.l %0,(1<<5)|%1\;jmpc   z,%l2")
544 (define_expand "cbranchqi4"
545   [(set (reg:CC CC_REG)
546         (compare:CC
547          (match_operand:QI 1 "register_operand" "")
548          (match_operand:QI 2 "ft32_rimm_operand" "")))
549    (set (pc)
550         (if_then_else (match_operator 0 "comparison_operator"
551                        [(reg:CC CC_REG) (const_int 0)])
552                       (label_ref (match_operand 3 "" ""))
553                       (pc)))]
554   ""
555   "")
557 (define_insn "*cmpqi"
558   [(set (reg:CC CC_REG)
559         (compare:CC
560          (match_operand:QI 0 "register_operand" "r,r")
561          (match_operand:QI 1 "ft32_rimm_operand" "r,KA")))]
562   ""
563   "cmp.b  %0,%1")
565 ;; -------------------------------------------------------------------------
566 ;; Branch instructions
567 ;; -------------------------------------------------------------------------
569 (define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu])
570 (define_code_attr CC [(ne "nz") (eq "z") (lt "lt") (ltu "b")
571                       (gt "gt") (gtu "a") (ge "gte") (le "lte")
572                       (geu "ae") (leu "be") ])
573 (define_code_attr rCC [(ne "z") (eq "nz") (lt "gte") (ltu "ae")
574                        (gt "lte") (gtu "be") (ge "lt") (le "gt")
575                        (geu "b") (leu "a") ])
577 (define_insn "*b<cond:code>"
578   [(set (pc)
579         (if_then_else (cond (reg:CC CC_REG)
580                             (const_int 0))
581                       (label_ref (match_operand 0 "" ""))
582                       (pc)))]
583   ""
585   return "jmpc   <CC>,%l0";
589 (define_expand "cstoresi4"
590   [(set (reg:CC CC_REG)
591         (compare:CC (match_operand:SI 2 "register_operand" "r,r")
592                     (match_operand:SI 3 "ft32_rimm_operand" "r,KA")))
593    (set (match_operand:SI 0 "register_operand")
594         (match_operator:SI 1 "ordered_comparison_operator"
595         [(reg:CC CC_REG) (const_int 0)]))]
596   ""
598   rtx test;
600   switch (GET_CODE (operands[1])) {
601   case NE:
602   case GEU:
603   case LT:
604   case LE:
605   case LEU:
606     test = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
607                      SImode, operands[2], operands[3]);
608     emit_insn(gen_cstoresi4(operands[0], test, operands[2], operands[3]));
609     emit_insn(gen_xorsi3(operands[0], operands[0], gen_int_mode(1, SImode)));
610     DONE;
611   default:
612     ;
613   }
616 (define_insn "*seq"
617   [(set (match_operand:SI 0 "register_operand" "=r")
618         (eq:SI (reg CC_REG) (const_int 0)))]
619   ""
620   "bextu.l %0,$cc,32|0"
623 (define_insn "*sltu"
624   [(set (match_operand:SI 0 "register_operand" "=r")
625         (ltu:SI (reg CC_REG) (const_int 0)))]
626   ""
627   "bextu.l %0,$cc,32|1"
630 (define_insn "*sge"
631   [(set (match_operand:SI 0 "register_operand" "=r")
632         (ge:SI (reg CC_REG) (const_int 0)))]
633   ""
634   "bextu.l %0,$cc,32|4"
637 (define_insn "*sgt"
638   [(set (match_operand:SI 0 "register_operand" "=r")
639         (gt:SI (reg CC_REG) (const_int 0)))]
640   ""
641   "bextu.l %0,$cc,32|5"
644 (define_insn "*sgtu"
645   [(set (match_operand:SI 0 "register_operand" "=r")
646         (gtu:SI (reg CC_REG) (const_int 0)))]
647   ""
648   "bextu.l %0,$cc,32|6"
651 ;; -------------------------------------------------------------------------
652 ;; Call and Jump instructions
653 ;; -------------------------------------------------------------------------
655 (define_expand "call"
656   [(call (match_operand:QI 0 "memory_operand" "")
657                 (match_operand 1 "general_operand" ""))]
658   ""
660   gcc_assert (MEM_P (operands[0]));
663 (define_insn "*call"
664   [(call (mem:QI (match_operand:SI
665                   0 "nonmemory_operand" "i,r"))
666          (match_operand 1 "" ""))]
667   ""
668   "@
669    call   %0
670    calli  %0"
673 (define_expand "call_value"
674   [(set (match_operand 0 "" "")
675                 (call (match_operand:QI 1 "memory_operand" "")
676                  (match_operand 2 "" "")))]
677   ""
679   gcc_assert (MEM_P (operands[1]));
682 (define_insn "*call_value"
683   [(set (match_operand 0 "register_operand" "=r")
684         (call (mem:QI (match_operand:SI
685                        1 "immediate_operand" "i"))
686               (match_operand 2 "" "")))]
687   ""
688   "call   %1"
691 (define_insn "*call_value_indirect"
692   [(set (match_operand 0 "register_operand" "=r")
693         (call (mem:QI (match_operand:SI
694                        1 "register_operand" "r"))
695               (match_operand 2 "" "")))]
696   ""
697   "calli  %1"
700 (define_insn "indirect_jump"
701   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
702   ""
703   "jmpi   %0")
705 (define_insn "jump"
706   [(set (pc)
707         (label_ref (match_operand 0 "" "")))]
708   ""
709   "jmp    %l0"
712 (define_insn "call_prolog"
713   [(unspec:SI [(match_operand 0 "" "")]
714                    UNSPEC_JMP_PROLOG)]
715   ""
716   "call   __prolog_%0"
719 (define_insn "jump_epilog"
720   [(unspec:SI [(match_operand 0 "" "")]
721                    UNSPEC_JMP_EPILOG)]
722   ""
723   "jmp    __epilog_%0"
726 (define_insn "jump_epilog24"
727   [(unspec:SI [(match_operand 0 "" "")]
728                    UNSPEC_JMP_EPILOG24)]
729   ""
730   "jmp    __epilog24_%0"
734 ;; Subroutines of "casesi".
735 ;; operand 0 is index
736 ;; operand 1 is the minimum bound
737 ;; operand 2 is the maximum bound - minimum bound + 1
738 ;; operand 3 is CODE_LABEL for the table;
739 ;; operand 4 is the CODE_LABEL to go to if index out of range.
741 (define_expand "casesi"
742   [(match_operand:SI 0 "general_operand" "")
743    (match_operand:SI 1 "const_int_operand" "")
744    (match_operand:SI 2 "const_int_operand" "")
745    (match_operand 3 "" "")
746    (match_operand 4 "" "")]
747   ""
748   "
750   if (GET_CODE (operands[0]) != REG)
751     operands[0] = force_reg (SImode, operands[0]);
753   if (operands[1] != const0_rtx)
754     {
755       rtx index = gen_reg_rtx (SImode);
756       rtx offset = gen_reg_rtx (SImode);
758       emit_insn (gen_movsi (offset, operands[1]));
759       emit_insn (gen_subsi3 (index, operands[0], offset));
760       operands[0] = index;
761     }
763   {
764     rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
765     emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
766   }
768   emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
769   DONE;
772 (define_insn "casesi0"
773   [(set (pc) (mem:SI (plus:SI
774                        (mult:SI (match_operand:SI 0 "register_operand" "r")
775                                 (const_int 4))
776                        (label_ref (match_operand 1 "" "")))))
777    (clobber (match_scratch:SI 2 "=&r"))
778   ]
779   ""
780   {
781     if (TARGET_NOPM)
782       return \"ldk.l\t$cc,%l1\;ashl.l\t%2,%0,2\;add.l\t%2,%2,$cc\;ldi.l\t%2,%2,0\;jmpi\t%2\";
783     else
784       return \"ldk.l\t$cc,%l1\;ashl.l\t%2,%0,2\;add.l\t%2,%2,$cc\;lpmi.l\t%2,%2,0\;jmpi\t%2\";
785   })
787 ;; -------------------------------------------------------------------------
788 ;; Atomic exchange instruction
789 ;; -------------------------------------------------------------------------
791 (define_insn "atomic_exchangesi"
792   [(set (match_operand:SI 0 "register_operand" "=&r,r") ;; output
793         (match_operand:SI 1 "memory_operand" "+BW,A"))  ;; memory
794    (set (match_dup 1)
795         (unspec:SI
796           [(match_operand:SI 2 "register_operand" "0,0")        ;; input
797            (match_operand:SI 3 "const_int_operand")]            ;; model
798           UNSPEC_XCHG))]
799   ""
800   "@
801    exi.l  %0,%1
802    exa.l  %0,%1")
804 (define_insn "atomic_exchangehi"
805   [(set (match_operand:HI 0 "register_operand" "=&r,r") ;; output
806         (match_operand:HI 1 "memory_operand" "+BW,A"))  ;; memory
807    (set (match_dup 1)
808         (unspec:HI
809           [(match_operand:HI 2 "register_operand" "0,0")        ;; input
810            (match_operand:HI 3 "const_int_operand")]            ;; model
811           UNSPEC_XCHG))]
812   ""
813   "@
814    exi.s  %0,%1
815    exa.s  %0,%1")
817 (define_insn "atomic_exchangeqi"
818   [(set (match_operand:QI 0 "register_operand" "=&r,r") ;; output
819         (match_operand:QI 1 "memory_operand" "+BW,A"))  ;; memory
820    (set (match_dup 1)
821         (unspec:QI
822           [(match_operand:QI 2 "register_operand" "0,0")        ;; input
823            (match_operand:QI 3 "const_int_operand")]            ;; model
824           UNSPEC_XCHG))]
825   ""
826   "@
827    exi.b  %0,%1
828    exa.b  %0,%1")
830 ;; -------------------------------------------------------------------------
831 ;; String instructions
832 ;; -------------------------------------------------------------------------
834 (define_insn "cmpstrsi"
835   [(set (match_operand:SI 0 "register_operand" "=r,r")
836         (compare:SI (match_operand:BLK 1 "memory_operand" "W,BW")
837                     (match_operand:BLK 2 "memory_operand" "W,BW")))
838    (clobber (match_operand:SI 3))
839    ]
840   ""
841   "strcmp.%d3 %0,%b1,%b2"
844 (define_insn "movstr"
845 [(set (match_operand:BLK 1 "memory_operand" "=W")
846       (match_operand:BLK 2 "memory_operand" "W"))
847       (use (match_operand:SI 0))
848       (clobber (match_dup 0))
851 "stpcpy %b1,%b2 # %0 %b1 %b2"
854 (define_insn "movmemsi"
855   [(set (match_operand:BLK 0 "memory_operand" "=W,BW")
856         (match_operand:BLK 1 "memory_operand" "W,BW"))
857         (use (match_operand:SI 2 "ft32_imm_operand" "KA,KA"))
858         (use (match_operand:SI 3))
859    ]
860   ""
861   "memcpy.%d3 %b0,%b1,%2 "
864 (define_insn "setmemsi"
865   [(set (match_operand:BLK 0 "memory_operand" "=BW") (unspec:BLK [
866      (use (match_operand:QI 2 "register_operand" "r"))
867      (use (match_operand:SI 1 "ft32_imm_operand" "KA"))
868    ] UNSPEC_SETMEM))
869    (use (match_operand:SI 3))
870    ]
871   ""
872   "memset.%d3 %b0,%2,%1"
875 (define_insn "strlensi"
876   [(set (match_operand:SI 0 "register_operand" "=r")
877         (unspec:SI [(match_operand:BLK 1 "memory_operand" "W")
878                     (match_operand:QI 2 "const_int_operand" "")
879                     (match_operand:SI 3 "ft32_rimm_operand" "")]
880                    UNSPEC_STRLEN))]
881   ""
882   "strlen.%d3 %0,%b1 # %2 %3"
885 ;; -------------------------------------------------------------------------
886 ;; Prologue & Epilogue
887 ;; -------------------------------------------------------------------------
889 (define_expand "prologue"
890   [(clobber (const_int 0))]
891   ""
893   extern void ft32_expand_prologue();
894   ft32_expand_prologue ();
895   DONE;
899 (define_expand "epilogue"
900   [(return)]
901   ""
903   extern void ft32_expand_epilogue();
904   ft32_expand_epilogue ();
905   DONE;
908 (define_insn "link"
909   [
910 ;;   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
911 ;;        (reg:SI FP_REG))
912    (set (match_operand:SI 0)
913         (reg:SI SP_REG))
914    (set (reg:SI SP_REG)
915         (plus:SI (reg:SI SP_REG)
916                  (match_operand:SI 1 "general_operand" "L")))]
917   ""
918   "link   %0,%m1"
921 (define_insn "unlink"
922   [(set (reg:SI FP_REG)
923         (mem:SI (reg:SI FP_REG)))
924    (set (reg:SI SP_REG)
925         (plus:SI (reg:SI FP_REG)
926                  (const_int 4)))]
927   ""
928   "unlink $r29"
931 (define_insn "returner"
932   [(return)]
933   "reload_completed"
934   "return")
936 (define_insn "pretend_returner"
937   [(set (reg:SI SP_REG)
938         (plus:SI (reg:SI SP_REG)
939                  (match_operand:SI 0)))
940    (return)]
941   "reload_completed"
942   "pop.l  $cc\;add.l  $sp,$sp,%0\;jmpi   $cc")
944 (define_insn "returner24"
945   [
946   (set (reg:SI SP_REG)
947           (plus:SI
948            (reg:SI SP_REG)
949            (const_int 24)))
950   (return)]
951   ""
952   "jmp    __epilog24")