* mn10300/mn10300.md (cmpsi): Handle comparing a register with
[official-gcc.git] / gcc / config / mn10300 / mn10300.md
blob477e99f3c9ccad41ed909487d54902e0bb1af664
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
4 ;;   Contributed by Jeff Law (law@cygnus.com).
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; Condition code settings.
29 ;; none - insn does not affect cc
30 ;; none_0hit - insn does not affect cc but it does modify operand 0
31 ;;      This attribute is used to keep track of when operand 0 changes.
32 ;;      See the description of NOTICE_UPDATE_CC for more info.
33 ;; set - insn sets flags z,n.  v is unusable c is set to 0.
34 ;;      (c may not really be set to 0 but that's ok, we don't need it anyway).
35 ;; set_zn_c0 - insn sets z,n to usable values.  v is unknown.  c may or may not
36 ;;      be known (if it isn't that's ok, we don't need it anyway).
37 ;; compare - compare instruction
38 ;; invert -- like compare, but flags are inverted.
39 ;; clobber - value of cc is unknown
40 (define_attr "cc" "none,none_0hit,tst,set_zn_c0,compare,clobber,invert"
41   (const_string "clobber"))
43 ;; ----------------------------------------------------------------------
44 ;; MOVE INSTRUCTIONS
45 ;; ----------------------------------------------------------------------
47 ;; movqi
49 (define_expand "movqi"
50   [(set (match_operand:QI 0 "general_operand" "")
51         (match_operand:QI 1 "general_operand" ""))]
52   ""
53   "
55   /* One of the ops has to be in a register */
56   if (!register_operand (operand0, QImode)
57       && !register_operand (operand1, QImode))
58     operands[1] = copy_to_mode_reg (QImode, operand1);
59 }")
61 (define_insn ""
62   [(set (match_operand:QI 0 "general_operand" "=d,a,d,d,a,d,a,d,m")
63         (match_operand:QI 1 "general_operand" "0,0,I,a,d,di,ia,m,d"))]
64   "register_operand (operands[0], QImode)
65    || register_operand (operands[1], QImode)"
66   "@
67   nop
68   nop
69   clr %0
70   mov %1,%0
71   mov %1,%0
72   mov %1,%0
73   mov %1,%0
74   movbu %1,%0
75   movbu %1,%0"
76   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
78 ;; movhi
80 (define_expand "movhi"
81   [(set (match_operand:HI 0 "general_operand" "")
82         (match_operand:HI 1 "general_operand" ""))]
83   ""
84   "
86   /* One of the ops has to be in a register */
87   if (!register_operand (operand1, HImode)
88       && !register_operand (operand0, HImode))
89     operands[1] = copy_to_mode_reg (HImode, operand1);
90 }")
92 (define_insn ""
93   [(set (match_operand:HI 0 "general_operand" "=d,a,d,d,a,d,a,d,m")
94         (match_operand:HI 1 "general_operand" "0,0,I,a,d,di,ia,m,d"))]
95   "register_operand (operands[0], HImode)
96    || register_operand (operands[1], HImode)"
97   "@
98   nop
99   nop
100   clr %0
101   mov %1,%0
102   mov %1,%0
103   mov %1,%0
104   mov %1,%0
105   movhu %1,%0
106   movhu %1,%0"
107   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
109 ;; movsi and helpers
111 (define_expand "movsi"
112   [(set (match_operand:SI 0 "general_operand" "")
113         (match_operand:SI 1 "general_operand" ""))]
114   ""
115   "
117   /* One of the ops has to be in a register */
118   if (!register_operand (operand1, SImode)
119       && !register_operand (operand0, SImode))
120     operands[1] = copy_to_mode_reg (SImode, operand1);
123 (define_insn ""
124   [(set (match_operand:SI 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a,aR,x")
125         (match_operand:SI 1 "general_operand" "0,0,I,d,a,d,a,dim,aim,dim,aim,x,aR"))]
126   "register_operand (operands[0], SImode)
127    || register_operand (operands[1], SImode)"
128   "@
129   nop
130   nop
131   clr %0
132   mov %1,%0
133   mov %1,%0
134   mov %1,%0
135   mov %1,%0
136   mov %1,%0
137   mov %1,%0
138   mov %1,%0
139   mov %1,%0
140   mov %1,%0
141   mov %1,%0"
142   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
144 (define_expand "movsf"
145   [(set (match_operand:SF 0 "general_operand" "")
146         (match_operand:SF 1 "general_operand" ""))]
147   ""
148   "
150   /* One of the ops has to be in a register */
151   if (!register_operand (operand1, SFmode)
152       && !register_operand (operand0, SFmode))
153     operands[1] = copy_to_mode_reg (SFmode, operand1);
156 (define_insn ""
157   [(set (match_operand:SF 0 "general_operand" "=d,a,d,dam,da")
158         (match_operand:SF 1 "general_operand" "0,0,G,da,daim"))]
159   "register_operand (operands[0], SFmode)
160    || register_operand (operands[1], SFmode)"
161   "@
162   nop
163   nop
164   clr %0
165   mov %1,%0
166   mov %1,%0"
167   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit")])
169 (define_expand "movdi"
170   [(set (match_operand:DI 0 "general_operand" "")
171         (match_operand:DI 1 "general_operand" ""))]
172   ""
173   "
175   /* One of the ops has to be in a register */
176   if (!register_operand (operand1, DImode)
177       && !register_operand (operand0, DImode))
178     operands[1] = copy_to_mode_reg (DImode, operand1);
181 (define_insn ""
182   [(set (match_operand:DI 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a")
183         (match_operand:DI 1 "general_operand" "0,0,I,d,a,d,a,dim,aim,dim,aim"))]
184   "register_operand (operands[0], DImode)
185    || register_operand (operands[1], DImode)"
186   "@
187   nop
188   nop
189   clr %L0\;clr %H0
190   mov %L1,%L0\;mov %H1,%H0
191   mov %L1,%L0\;mov %H1,%H0
192   mov %L1,%L0\;mov %H1,%H0
193   mov %L1,%L0\;mov %H1,%H0
194   mov %L1,%L0\;mov %H1,%H0
195   mov %L1,%L0\;mov %H1,%H0
196   mov %L1,%L0\;mov %H1,%H0
197   mov %L1,%L0\;mov %H1,%H0"
198   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
200 (define_expand "movdf"
201   [(set (match_operand:DF 0 "general_operand" "")
202         (match_operand:DF 1 "general_operand" ""))]
203   ""
204   "
206   /* One of the ops has to be in a register */
207   if (!register_operand (operand1, DFmode)
208       && !register_operand (operand0, DFmode))
209     operands[1] = copy_to_mode_reg (DFmode, operand1);
212 (define_insn ""
213   [(set (match_operand:DF 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a")
214         (match_operand:DF 1 "general_operand" "0,0,G,d,a,d,a,dim,aim,dim,aim"))]
215   "register_operand (operands[0], DFmode)
216    || register_operand (operands[1], DFmode)"
217   "@
218   nop
219   nop
220   clr %L0\;clr %H0
221   mov %L1,%L0\;mov %H1,%H0
222   mov %L1,%L0\;mov %H1,%H0
223   mov %L1,%L0\;mov %H1,%H0
224   mov %L1,%L0\;mov %H1,%H0
225   mov %L1,%L0\;mov %H1,%H0
226   mov %L1,%L0\;mov %H1,%H0
227   mov %L1,%L0\;mov %H1,%H0
228   mov %L1,%L0\;mov %H1,%H0"
229   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
230   
233 ;; ----------------------------------------------------------------------
234 ;; TEST INSTRUCTIONS
235 ;; ----------------------------------------------------------------------
237 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
238 ;; when we start trying to optimize this port.
239 (define_insn "tstsi"
240   [(set (cc0) (match_operand:SI 0 "register_operand" "da"))]
241   ""
242   "cmp 0,%0"
243   [(set_attr "cc" "tst")])
245 (define_insn "cmpsi"
246   [(set (cc0)
247         (compare (match_operand:SI 0 "register_operand" "!*d*a,da")
248                  (match_operand:SI 1 "nonmemory_operand" "!*0,dai")))]
249   ""
250   "@
251   add 0,%0
252   cmp %1,%0"
253   [(set_attr "cc" "invert,compare")])
255 ;; ----------------------------------------------------------------------
256 ;; ADD INSTRUCTIONS
257 ;; ----------------------------------------------------------------------
259 (define_expand "addsi3"
260   [(set (match_operand:SI 0 "register_operand" "")
261         (plus:SI (match_operand:SI 1 "register_operand" "")
262                  (match_operand:SI 2 "nonmemory_operand" "")))]
263   ""
264   "
266   /* We can't add a variable amount directly to the stack pointer;
267      so do so via a temporary register.  */
268   if (operands[0] == stack_pointer_rtx
269       && GET_CODE (operands[1]) != CONST_INT
270       && GET_CODE (operands[2]) != CONST_INT)
271    {
272      rtx temp = gen_reg_rtx (SImode);
273      emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2]));
274      emit_move_insn (operands[0], temp);
275      DONE;
276    }
279 (define_insn ""
280   [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x")
281         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0")
282                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i")))]
283   ""
284   "@
285   inc %0
286   inc %0
287   inc4 %0
288   add %2,%0
289   add %2,%0"
290   [(set_attr "cc" "set_zn_c0,none_0hit,none_0hit,set_zn_c0,none_0hit")])
292 (define_expand "adddi3"
293   [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
294    (set (reg:DI 2) (match_operand:DI 2 "nonmemory_operand" ""))
295    (set (reg:DI 0) (plus:DI (reg:DI 0) (reg:DI 2)))
296    (set (match_operand:DI 0 "register_operand" "") (reg:DI 0))]
297   ""
298   "
300   if (GET_CODE (operands[2]) == CONST_INT)
301     {
302       rtx reg0 = gen_rtx (REG, DImode, 0);
304       emit_move_insn (reg0, operands[1]);
305       emit_insn (gen_adddi3_const (operands[2]));
306       emit_move_insn (operands[0], reg0);
307       DONE;
308     }
311 ;; The general adddi3 pattern.
312 (define_insn ""
313   [(set (reg:DI 0) (plus:DI (reg:DI 0) (reg:DI 2)))]
314   ""
315   "add d2,d0\;addc d3,d1"
316   [(set_attr "cc" "clobber")])
318 ;; adddi3 with on operand being a constant.
319 (define_insn "adddi3_const"
320   [(set (reg:DI 0)
321         (plus:DI (reg:DI 0) (match_operand:DI 0 "const_int_operand" "i")))
322    (clobber (reg:DI 2))]
323   ""
324   "*
326   long value = INTVAL (operands[0]);
328   if (value < 0)
329     return \"mov -1,d2\;add %0,d0\;addc d2,d1\";
330   else
331     return \"clr d2\;add %0,d0\;addc d2,d1\";
333   [(set_attr "cc" "clobber")])
334 ;; ----------------------------------------------------------------------
335 ;; SUBTRACT INSTRUCTIONS
336 ;; ----------------------------------------------------------------------
338 (define_insn "subsi3"
339   [(set (match_operand:SI 0 "register_operand" "=da")
340         (minus:SI (match_operand:SI 1 "register_operand" "0")
341                   (match_operand:SI 2 "nonmemory_operand" "dai")))]
342   ""
343   "sub %2,%0"
344   [(set_attr "cc" "set_zn_c0")])
346 (define_expand "negsi2"
347   [(set (match_operand:SI 0 "register_operand" "")
348         (neg:SI (match_operand:SI 1 "register_operand" "")))]
349   ""
350   "
352   rtx target = gen_reg_rtx (SImode);
354   emit_move_insn (target, GEN_INT (0));
355   emit_insn (gen_subsi3 (target, target, operands[1]));
356   emit_move_insn (operands[0], target);
357   DONE;
360 (define_expand "subdi3"
361   [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
362    (set (reg:DI 2) (match_operand:DI 2 "nonmemory_operand" ""))
363    (set (reg:DI 0) (minus:DI (reg:DI 0) (reg:DI 2)))
364    (set (match_operand:DI 0 "register_operand" "") (reg:DI 0))]
365   ""
366   "")
368 (define_insn ""
369   [(set (reg:DI 0) (minus:DI (reg:DI 0) (reg:DI 2)))]
370   ""
371   "sub d2,d0\;subc d3,d1"
372   [(set_attr "cc" "clobber")])
374 ;; ----------------------------------------------------------------------
375 ;; MULTIPLY INSTRUCTIONS
376 ;; ----------------------------------------------------------------------
378 (define_insn "mulsi3"
379   [(set (match_operand:SI 0 "register_operand" "=d")
380         (mult:SI (match_operand:SI 1 "register_operand" "%0")
381                  (match_operand:SI 2 "register_operand" "d")))]
382   ""
383   "mul %2,%0"
384   [(set_attr "cc" "set_zn_c0")])
386 (define_insn "divsi3"
387   [(set (match_operand:SI 0 "register_operand" "=d")
388         (div:SI (match_operand:SI 1 "register_operand" "0")
389                  (match_operand:SI 2 "register_operand" "d")))]
390   ""
391   "ext %0\;div %2,%0"
392   [(set_attr "cc" "set_zn_c0")])
394 (define_expand "udivsi3"
395   [(set (match_operand:SI 0 "register_operand" "")
396         (udiv:SI (match_operand:SI 1 "register_operand" "")
397                  (match_operand:SI 2 "register_operand" "")))]
398   ""
399   "
401   rtx reg = gen_reg_rtx (SImode);
402   emit_move_insn (reg, GEN_INT (0));
403   emit_insn (gen_clear_mdr (reg));
406 (define_insn ""
407   [(set (match_operand:SI 0 "register_operand" "=d")
408         (udiv:SI (match_operand:SI 1 "register_operand" "0")
409                  (match_operand:SI 2 "register_operand" "d")))]
410   ""
411   "divu %2,%0"
412   [(set_attr "cc" "set_zn_c0")])
414 (define_insn "clear_mdr"
415   [(unspec_volatile [(const_int 2)] 0)
416    (use (match_operand:SI 0 "register_operand" "d"))]
417   ""
418   "mov %0,mdr"
419   [(set_attr "cc" "none")])
421 ;; ----------------------------------------------------------------------
422 ;; AND INSTRUCTIONS
423 ;; ----------------------------------------------------------------------
425 (define_insn "andsi3"
426   [(set (match_operand:SI 0 "register_operand" "=d,d")
427         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
428                 (match_operand:SI 2 "nonmemory_operand" "N,di")))]
429   ""
430   "*
432   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
433     return \"extbu %0\";
434   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
435     return \"exthu %0\";
436   return \"and %2,%0\";
438   [(set_attr "cc" "none_0hit,set_zn_c0")])
440 ;; ----------------------------------------------------------------------
441 ;; OR INSTRUCTIONS
442 ;; ----------------------------------------------------------------------
444 (define_insn "iorsi3"
445   [(set (match_operand:SI 0 "register_operand" "=d")
446         (ior:SI (match_operand:SI 1 "register_operand" "%0")
447                 (match_operand:SI 2 "nonmemory_operand" "di")))]
448   ""
449   "or %2,%0"
450   [(set_attr "cc" "set_zn_c0")])
452 ;; ----------------------------------------------------------------------
453 ;; XOR INSTRUCTIONS
454 ;; ----------------------------------------------------------------------
456 (define_insn "xorsi3"
457   [(set (match_operand:SI 0 "register_operand" "=d")
458         (xor:SI (match_operand:SI 1 "register_operand" "%0")
459                 (match_operand:SI 2 "nonmemory_operand" "di")))]
460   ""
461   "xor %2,%0"
462   [(set_attr "cc" "set_zn_c0")])
464 ;; ----------------------------------------------------------------------
465 ;; NOT INSTRUCTIONS
466 ;; ----------------------------------------------------------------------
468 (define_insn "one_cmplsi2"
469   [(set (match_operand:SI 0 "register_operand" "=d")
470         (not:SI (match_operand:SI 1 "register_operand" "0")))]
471   ""
472   "not %0"
473   [(set_attr "cc" "set_zn_c0")])
475 ;; -----------------------------------------------------------------
476 ;; BIT FIELDS
477 ;; -----------------------------------------------------------------
480 ;; These set/clear memory in byte sized chunks.
482 ;; They are no smaller/faster than loading the value into a register
483 ;; and storing the register, but they don't need a scratch register
484 ;; which may allow for better code generation.
485 (define_insn ""
486   [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
487   ""
488   "@
489   bclr 255,%A0
490   clr %0"
491   [(set_attr "cc" "clobber")])
493 (define_insn ""
494   [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
495   ""
496   "@
497   bset 255,%A0
498   mov -1,%0"
499   [(set_attr "cc" "clobber,none_0hit")])
501 (define_insn ""
502   [(set (match_operand:QI 0 "general_operand" "=R,d")
503         (subreg:QI
504           (and:SI (subreg:SI (match_dup 0) 0)
505                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
506   ""
507   "@
508   bclr %N1,%A0
509   and %1,%0"
510   [(set_attr "cc" "clobber,set_zn_c0")])
512 (define_insn ""
513   [(set (match_operand:QI 0 "general_operand" "=R,d")
514         (subreg:QI
515           (ior:SI (subreg:SI (match_dup 0) 0)
516                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
517   ""
518   "@
519   bset %1,%A0
520   or %1,%0"
521   [(set_attr "cc" "clobber")])
523 (define_insn ""
524   [(set (cc0)
525      (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
526                       (match_operand 1 "const_int_operand" "")
527                       (match_operand 2 "const_int_operand" "")))]
528   ""
529   "*
531   int len = INTVAL (operands[1]);
532   int bit = INTVAL (operands[2]);
533   int mask = 0;
534   rtx xoperands[2];
536   while (len > 0)
537     {
538       mask |= (1 << bit);
539       bit++;
540       len--;
541     }
543   xoperands[0] = operands[0];
544   xoperands[1] = GEN_INT (mask);
545   output_asm_insn (\"btst %1,%0\", xoperands);
546   return \"\";
548   [(set_attr "cc" "set_zn_c0")])
550 (define_insn ""
551   [(set (cc0)
552      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
553                       (match_operand 1 "const_int_operand" "")
554                       (match_operand 2 "const_int_operand" "")))]
555   "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
556   "*
558   int len = INTVAL (operands[1]);
559   int bit = INTVAL (operands[2]);
560   int mask = 0;
561   rtx xoperands[2];
563   while (len > 0)
564     {
565       mask |= (1 << bit);
566       bit++;
567       len--;
568     }
570   xoperands[0] = operands[0];
571   xoperands[1] = GEN_INT (mask);
572   if (GET_CODE (operands[0]) == REG)
573     output_asm_insn (\"btst %1,%0\", xoperands);
574   else
575     output_asm_insn (\"btst %1,%A0\", xoperands);
576   return \"\";
578   [(set_attr "cc" "set_zn_c0")])
580 (define_insn ""
581   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "d")
582                       (match_operand:SI 1 "const_int_operand" "")))]
583   ""
584   "btst %1,%0"
585   [(set_attr "cc" "set_zn_c0")])
587 (define_insn ""
588   [(set (cc0)
589      (and:SI
590        (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
591        (match_operand:SI 1 "const_int_operand" "")))]
592   ""
593   "@
594   btst %1,%A0
595   btst %1,%0"
596   [(set_attr "cc" "set_zn_c0")])
598 ;; -----------------------------------------------------------------
599 ;; -----------------------------------------------------------------
600 ;; Scc INSTRUCTIONS
601 ;; -----------------------------------------------------------------
602 ;; It's probably worth the time to define setcc type insns too
605 ;; ----------------------------------------------------------------------
606 ;; JUMP INSTRUCTIONS
607 ;; ----------------------------------------------------------------------
609 ;; Conditional jump instructions
611 (define_expand "ble"
612   [(set (pc)
613         (if_then_else (le (cc0)
614                           (const_int 0))
615                       (label_ref (match_operand 0 "" ""))
616                       (pc)))]
617   ""
618   "")
620 (define_expand "bleu"
621   [(set (pc)
622         (if_then_else (leu (cc0)
623                            (const_int 0))
624                       (label_ref (match_operand 0 "" ""))
625                       (pc)))]
626   ""
627   "")
629 (define_expand "bge"
630   [(set (pc)
631         (if_then_else (ge (cc0)
632                           (const_int 0))
633                       (label_ref (match_operand 0 "" ""))
634                       (pc)))]
635   ""
636   "")
638 (define_expand "bgeu"
639   [(set (pc)
640         (if_then_else (geu (cc0)
641                            (const_int 0))
642                       (label_ref (match_operand 0 "" ""))
643                       (pc)))]
644   ""
645   "")
647 (define_expand "blt"
648   [(set (pc)
649         (if_then_else (lt (cc0)
650                           (const_int 0))
651                       (label_ref (match_operand 0 "" ""))
652                       (pc)))]
653   ""
654   "")
656 (define_expand "bltu"
657   [(set (pc)
658         (if_then_else (ltu (cc0)
659                            (const_int 0))
660                       (label_ref (match_operand 0 "" ""))
661                       (pc)))]
662   ""
663   "")
665 (define_expand "bgt"
666   [(set (pc)
667         (if_then_else (gt (cc0)
668                           (const_int 0))
669                       (label_ref (match_operand 0 "" ""))
670                       (pc)))]
671   ""
672   "")
674 (define_expand "bgtu"
675   [(set (pc)
676         (if_then_else (gtu (cc0)
677                            (const_int 0))
678                       (label_ref (match_operand 0 "" ""))
679                       (pc)))]
680   ""
681   "")
683 (define_expand "beq"
684   [(set (pc)
685         (if_then_else (eq (cc0)
686                           (const_int 0))
687                       (label_ref (match_operand 0 "" ""))
688                       (pc)))]
689   ""
690   "")
692 (define_expand "bne"
693   [(set (pc)
694         (if_then_else (ne (cc0)
695                           (const_int 0))
696                       (label_ref (match_operand 0 "" ""))
697                       (pc)))]
698   ""
699   "")
701 (define_insn ""
702   [(set (pc)
703         (if_then_else (match_operator 1 "comparison_operator"
704                                       [(cc0) (const_int 0)])
705                       (label_ref (match_operand 0 "" ""))
706                       (pc)))]
707   ""
708   "*
710   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
711       && (GET_CODE (operands[1]) == GT
712           || GET_CODE (operands[1]) == GE
713           || GET_CODE (operands[1]) == LE
714           || GET_CODE (operands[1]) == LT))
715     return 0;
716   return \"b%b1 %0\";
718  [(set_attr "cc" "none")])
720 (define_insn ""
721   [(set (pc)
722         (if_then_else (match_operator 1 "comparison_operator"
723                                       [(cc0) (const_int 0)])
724                       (pc)
725                       (label_ref (match_operand 0 "" ""))))]
726   ""
727   "*
729   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
730       && (GET_CODE (operands[1]) == GT
731           || GET_CODE (operands[1]) == GE
732           || GET_CODE (operands[1]) == LE
733           || GET_CODE (operands[1]) == LT))
734     return 0;
735   return \"b%B1 %0\";
737  [(set_attr "cc" "none")])
739 ;; Unconditional and other jump instructions.
741 (define_insn "jump"
742   [(set (pc)
743         (label_ref (match_operand 0 "" "")))]
744   ""
745   "jmp %l0"
746  [(set_attr "cc" "none")])
748 (define_insn "indirect_jump"
749   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
750   ""
751   "jmp (%0)"
752   [(set_attr "cc" "none")])
754 (define_insn "tablejump"
755   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
756    (use (label_ref (match_operand 1 "" "")))]
757   ""
758   "jmp  (%0)"
759   [(set_attr "cc" "none")])
761 ;; Call subroutine with no return value.
763 (define_expand "call"
764   [(call (match_operand:QI 0 "general_operand" "")
765          (match_operand:SI 1 "general_operand" ""))]
766   ""
767   "
769   if (! call_address_operand (XEXP (operands[0], 0)))
770     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
771   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
772   DONE;
775 (define_insn "call_internal"
776   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
777          (match_operand:SI 1 "general_operand" "g"))]
778   ""
779   "calls %C0"
780   [(set_attr "cc" "clobber")])
782 ;; Call subroutine, returning value in operand 0
783 ;; (which must be a hard register).
785 (define_expand "call_value"
786   [(set (match_operand 0 "" "")
787         (call (match_operand:QI 1 "general_operand" "")
788               (match_operand:SI 2 "general_operand" "")))]
789   ""
790   "
792   if (! call_address_operand (XEXP (operands[1], 0)))
793     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
794   emit_call_insn (gen_call_value_internal (operands[0],
795                                            XEXP (operands[1], 0),
796                                            operands[2]));
797   DONE;
800 (define_insn "call_value_internal"
801   [(set (match_operand 0 "" "=d")
802         (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
803               (match_operand:SI 2 "general_operand" "g")))]
804   ""
805   "calls %C1"
806   [(set_attr "cc" "clobber")])
808 (define_insn "nop"
809   [(const_int 0)]
810   ""
811   "nop"
812   [(set_attr "cc" "none")])
814 ;; ----------------------------------------------------------------------
815 ;; EXTEND INSTRUCTIONS
816 ;; ----------------------------------------------------------------------
818 (define_insn "zero_extendqisi2"
819   [(set (match_operand:SI 0 "general_operand" "=d,d,d")
820         (zero_extend:SI
821          (match_operand:QI 1 "general_operand" "0,d,m")))]
822   ""
823   "@
824   extbu %0
825   mov %1,%0\;extbu %0
826   movbu %1,%0"
827   [(set_attr "cc" "none_0hit")])
829 (define_insn "zero_extendhisi2"
830   [(set (match_operand:SI 0 "general_operand" "=d,d,d")
831         (zero_extend:SI
832          (match_operand:HI 1 "general_operand" "0,d,m")))]
833   ""
834   "@
835   exthu %0
836   mov %1,%0\;exthu %0
837   movhu %1,%0"
838   [(set_attr "cc" "none_0hit")])
840 ;;- sign extension instructions
842 (define_insn "extendqisi2"
843   [(set (match_operand:SI 0 "general_operand" "=d,d")
844         (sign_extend:SI
845          (match_operand:QI 1 "general_operand" "0,d")))]
846   ""
847   "@
848   extb %0
849   mov %1,%0\;extb %0"
850   [(set_attr "cc" "none_0hit")])
852 (define_insn "extendhisi2"
853   [(set (match_operand:SI 0 "general_operand" "=d,d")
854         (sign_extend:SI
855          (match_operand:HI 1 "general_operand" "0,d")))]
856   ""
857   "@
858   exth %0
859   mov %1,%0\;exth %0"
860   [(set_attr "cc" "none_0hit")])
862 ;; ----------------------------------------------------------------------
863 ;; SHIFTS
864 ;; ----------------------------------------------------------------------
866 (define_insn "ashlsi3"
867   [(set (match_operand:SI 0 "register_operand" "=da,d,a,d,a,d,a,d")
868         (ashift:SI
869          (match_operand:SI 1 "register_operand" "0,0,0,0,0,0,0,0")
870          (match_operand:QI 2 "nonmemory_operand" "J,K,K,M,M,L,L,di")))]
871   ""
872   "@
873   add %0,%0
874   asl2 %0
875   add %0,%0\;add %0,%0
876   asl2 %0\;add %0,%0
877   add %0,%0\;add %0,%0\;add %0,%0
878   asl2 %0\;asl2 %0
879   add %0,%0\;add %0,%0\;add %0,%0\;add %0,%0
880   asl %2,%0"
881   [(set_attr "cc" "set_zn_c0")])
883 (define_insn "lshrsi3"
884   [(set (match_operand:SI 0 "register_operand" "=d")
885         (lshiftrt:SI
886          (match_operand:SI 1 "register_operand" "0")
887          (match_operand:QI 2 "nonmemory_operand" "di")))]
888   ""
889   "lsr %2,%0"
890   [(set_attr "cc" "set_zn_c0")])
892 (define_insn "ashrsi3"
893   [(set (match_operand:SI 0 "register_operand" "=d")
894         (ashiftrt:SI
895          (match_operand:SI 1 "register_operand" "0")
896          (match_operand:QI 2 "nonmemory_operand" "di")))]
897   ""
898   "asr %2,%0"
899   [(set_attr "cc" "set_zn_c0")])
901 ;; ----------------------------------------------------------------------
902 ;; PROLOGUE/EPILOGUE
903 ;; ----------------------------------------------------------------------
904 (define_expand "prologue"
905   [(const_int 0)]
906   ""
907   "expand_prologue (); DONE;")
909 (define_expand "epilogue"
910   [(return)]
911   ""
912   "
914   expand_epilogue ();
915   DONE;
918 (define_insn "return_internal"
919   [(const_int 2)]
920   ""
921   "rets"
922   [(set_attr "cc" "clobber")])
924 ;; This insn restores the callee saved registers and does a return, it
925 ;; can also deallocate stack space.
926 (define_insn "return_internal_regs"
927   [(const_int 0)
928    (match_operand:SI 0  "const_int_operand" "i")
929    (return)]
930   ""
931   "ret [d2,d3,a2,a3],%0"
932   [(set_attr "cc" "clobber")])
934 (define_insn "store_movm"
935   [(const_int 1)]
936   ""
937   "movm [d2,d3,a2,a3],(sp)"
938   [(set_attr "cc" "clobber")])
940 (define_insn "return"
941   [(return)]
942   "can_use_return_insn ()"
943   "rets"
944   [(set_attr "cc" "clobber")])
946 ;; Try to combine consecutive updates of the stack pointer (or any
947 ;; other register for that matter).
948 (define_peephole
949   [(set (match_operand:SI 0 "register_operand" "=dax")
950         (plus:SI (match_dup 0)
951                  (match_operand 1 "const_int_operand" "")))
952    (set (match_dup 0)
953         (plus:SI (match_dup 0)
954                  (match_operand 2 "const_int_operand" "")))]
955   ""
956   "*
958   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
959   return \"add %1,%0\";
961   [(set_attr "cc" "clobber")])
964 ;; We had patterns to check eq/ne, but the they don't work because
965 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
967 ;; The Z flag and C flag would be set, and we have no way to
968 ;; check for the Z flag set and C flag clear.
970 ;; This will work on the mn10200 because we can check the ZX flag
971 ;; if the comparison is in HImode.
972 (define_peephole
973   [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
974    (set (pc) (if_then_else (ge (cc0) (const_int 0))
975                            (match_operand 1 "" "")
976                            (pc)))]
977   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
978   "add %0,%0\;bcc %1"
979   [(set_attr "cc" "clobber")])
981 (define_peephole
982   [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
983    (set (pc) (if_then_else (lt (cc0) (const_int 0))
984                            (match_operand 1 "" "")
985                            (pc)))]
986   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
987   "add %0,%0\;bcs %1"
988   [(set_attr "cc" "clobber")])
990 (define_peephole
991   [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
992    (set (pc) (if_then_else (ge (cc0) (const_int 0))
993                            (pc)
994                            (match_operand 1 "" "")))]
995   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
996   "add %0,%0\;bcs %1"
997   [(set_attr "cc" "clobber")])
999 (define_peephole
1000   [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1001    (set (pc) (if_then_else (lt (cc0) (const_int 0))
1002                            (pc)
1003                            (match_operand 1 "" "")))]
1004   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1005   "add %0,%0\;bcc %1"
1006   [(set_attr "cc" "clobber")])