* ginclude/stdarg.h: Include va-mn10300.h.
[official-gcc.git] / gcc / config / mn10300 / mn10300.md
blob5db2a944b92f791b9d3ccc8836d3a5d9a4bbf7c8
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   "*
188   long val[2];
189   REAL_VALUE_TYPE rv;
191   switch (which_alternative)
192     {
193       case 0:
194       case 1:
195         return \"nop\";
197       case 2:
198         return \"clr %L0\;clr %H0\";
200       case 3:
201       case 4:
202       case 5:
203       case 6:
204       case 7:
205       case 8:
206       case 9:
207       case 10:
208         if (GET_CODE (operands[1]) == CONST_INT)
209           {
210             val[0] = INTVAL (operands[1]);
211             val[1] = val[0] < 0 ? -1 : 0;
212           }
213         if (GET_CODE (operands[1]) == CONST_DOUBLE)
214           {
215             if (GET_MODE (operands[1]) == DFmode)
216               {
217                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
218                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
219               }
220             else if (GET_MODE (operands[1]) == VOIDmode
221                      || GET_MODE (operands[1]) == DImode)
222               {
223                 val[0] = CONST_DOUBLE_LOW (operands[1]);
224                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
225               }
226           }
228         if (GET_CODE (operands[1]) == MEM
229             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
230           {
231             rtx temp = operands[0];
233             while (GET_CODE (temp) == SUBREG)
234               temp = SUBREG_REG (temp);
236             if (GET_CODE (temp) != REG)
237               abort ();
239             if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
240                                          XEXP (operands[1], 0)))
241               return \"mov %H1,%H0\;mov %L1,%L0\";
242             else
243               return \"mov %L1,%L0\;mov %H1,%H0\";
244               
245           }
246         else
247           {
248             if ((GET_CODE (operands[1]) == CONST_INT
249                  || GET_CODE (operands[1]) == CONST_DOUBLE)
250                 && val[0] == 0
251                 && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
252               output_asm_insn (\"clr %L0\", operands);
253             else
254               output_asm_insn (\"mov %L1,%L0\", operands);
256             if ((GET_CODE (operands[1]) == CONST_INT
257                  || GET_CODE (operands[1]) == CONST_DOUBLE)
258                 && val[1] == 0
259                 && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
260               output_asm_insn (\"clr %H0\", operands);
261             else
262               output_asm_insn (\"mov %H1,%H0\", operands);
263             return \"\";
264           }
265     }
267   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
269 (define_expand "movdf"
270   [(set (match_operand:DF 0 "general_operand" "")
271         (match_operand:DF 1 "general_operand" ""))]
272   ""
273   "
275   /* One of the ops has to be in a register */
276   if (!register_operand (operand1, DFmode)
277       && !register_operand (operand0, DFmode))
278     operands[1] = copy_to_mode_reg (DFmode, operand1);
281 (define_insn ""
282   [(set (match_operand:DF 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a")
283         (match_operand:DF 1 "general_operand" "0,0,G,d,a,d,a,dim,aim,dim,aim"))]
284   "register_operand (operands[0], DFmode)
285    || register_operand (operands[1], DFmode)"
286   "*
288   long val[2];
289   REAL_VALUE_TYPE rv;
291   switch (which_alternative)
292     {
293       case 0:
294       case 1:
295         return \"nop\";
297       case 2:
298         return \"clr %L0\;clr %H0\";
300       case 3:
301       case 4:
302       case 5:
303       case 6:
304       case 7:
305       case 8:
306       case 9:
307       case 10:
308         if (GET_CODE (operands[1]) == CONST_INT)
309           {
310             val[0] = INTVAL (operands[1]);
311             val[1] = val[0] < 0 ? -1 : 0;
312           }
313         if (GET_CODE (operands[1]) == CONST_DOUBLE)
314           {
315             if (GET_MODE (operands[1]) == DFmode)
316               {
317                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
318                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
319               }
320             else if (GET_MODE (operands[1]) == VOIDmode
321                      || GET_MODE (operands[1]) == DImode)
322               {
323                 val[0] = CONST_DOUBLE_LOW (operands[1]);
324                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
325               }
326           }
328         if (GET_CODE (operands[1]) == MEM
329             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
330           {
331             rtx temp = operands[0];
333             while (GET_CODE (temp) == SUBREG)
334               temp = SUBREG_REG (temp);
336             if (GET_CODE (temp) != REG)
337               abort ();
339             if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
340                                          XEXP (operands[1], 0)))
341               return \"mov %H1,%H0\;mov %L1,%L0\";
342             else
343               return \"mov %L1,%L0\;mov %H1,%H0\";
344               
345           }
346         else
347           {
348             if ((GET_CODE (operands[1]) == CONST_INT
349                  || GET_CODE (operands[1]) == CONST_DOUBLE)
350                 && val[0] == 0
351                 && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
352               output_asm_insn (\"clr %L0\", operands);
353             else
354               output_asm_insn (\"mov %L1,%L0\", operands);
356             if ((GET_CODE (operands[1]) == CONST_INT
357                  || GET_CODE (operands[1]) == CONST_DOUBLE)
358                 && val[1] == 0
359                 && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
360               output_asm_insn (\"clr %H0\", operands);
361             else
362               output_asm_insn (\"mov %H1,%H0\", operands);
363             return \"\";
364           }
365     }
367   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
368   
371 ;; ----------------------------------------------------------------------
372 ;; TEST INSTRUCTIONS
373 ;; ----------------------------------------------------------------------
375 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
376 ;; when we start trying to optimize this port.
377 (define_insn "tstsi"
378   [(set (cc0) (match_operand:SI 0 "register_operand" "da"))]
379   ""
380   "* return output_tst (operands[0], insn);"
381   [(set_attr "cc" "tst")])
383 (define_insn ""
384   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "d")))]
385   ""
386   "* return output_tst (operands[0], insn);"
387   [(set_attr "cc" "tst")])
389 (define_insn ""
390   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "d")))]
391   ""
392   "* return output_tst (operands[0], insn);"
393   [(set_attr "cc" "tst")])
396 (define_insn "cmpsi"
397   [(set (cc0)
398         (compare (match_operand:SI 0 "register_operand" "!*d*a,da")
399                  (match_operand:SI 1 "nonmemory_operand" "!*0,dai")))]
400   ""
401   "@
402   add 0,%0
403   cmp %1,%0"
404   [(set_attr "cc" "invert,compare")])
406 ;; ----------------------------------------------------------------------
407 ;; ADD INSTRUCTIONS
408 ;; ----------------------------------------------------------------------
410 (define_expand "addsi3"
411   [(set (match_operand:SI 0 "register_operand" "")
412         (plus:SI (match_operand:SI 1 "register_operand" "")
413                  (match_operand:SI 2 "nonmemory_operand" "")))]
414   ""
415   "
417   /* We can't add a variable amount directly to the stack pointer;
418      so do so via a temporary register.  */
419   if (operands[0] == stack_pointer_rtx
420       && GET_CODE (operands[1]) != CONST_INT
421       && GET_CODE (operands[2]) != CONST_INT)
422    {
423      rtx temp = gen_reg_rtx (SImode);
424      emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2]));
425      emit_move_insn (operands[0], temp);
426      DONE;
427    }
430 (define_insn ""
431   [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x")
432         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0")
433                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i")))]
434   ""
435   "@
436   inc %0
437   inc %0
438   inc4 %0
439   add %2,%0
440   add %2,%0"
441   [(set_attr "cc" "set_zn_c0,none_0hit,none_0hit,set_zn_c0,none_0hit")])
443 (define_expand "adddi3"
444   [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
445    (set (reg:DI 2) (match_operand:DI 2 "nonmemory_operand" ""))
446    (set (reg:DI 0) (plus:DI (reg:DI 0) (reg:DI 2)))
447    (set (match_operand:DI 0 "register_operand" "") (reg:DI 0))]
448   ""
449   "
451   if (GET_CODE (operands[2]) == CONST_INT)
452     {
453       rtx reg0 = gen_rtx (REG, DImode, 0);
455       emit_move_insn (reg0, operands[1]);
456       emit_insn (gen_adddi3_const (operands[2]));
457       emit_move_insn (operands[0], reg0);
458       DONE;
459     }
462 ;; The general adddi3 pattern.
463 (define_insn ""
464   [(set (reg:DI 0) (plus:DI (reg:DI 0) (reg:DI 2)))]
465   ""
466   "add d2,d0\;addc d3,d1"
467   [(set_attr "cc" "clobber")])
469 ;; adddi3 with on operand being a constant.
470 (define_insn "adddi3_const"
471   [(set (reg:DI 0)
472         (plus:DI (reg:DI 0) (match_operand:DI 0 "const_int_operand" "i")))
473    (clobber (reg:DI 2))]
474   ""
475   "*
477   long value = INTVAL (operands[0]);
479   if (value < 0)
480     return \"mov -1,d2\;add %0,d0\;addc d2,d1\";
481   else
482     return \"clr d2\;add %0,d0\;addc d2,d1\";
484   [(set_attr "cc" "clobber")])
485 ;; ----------------------------------------------------------------------
486 ;; SUBTRACT INSTRUCTIONS
487 ;; ----------------------------------------------------------------------
489 (define_insn "subsi3"
490   [(set (match_operand:SI 0 "register_operand" "=da")
491         (minus:SI (match_operand:SI 1 "register_operand" "0")
492                   (match_operand:SI 2 "nonmemory_operand" "dai")))]
493   ""
494   "sub %2,%0"
495   [(set_attr "cc" "set_zn_c0")])
497 (define_expand "negsi2"
498   [(set (match_operand:SI 0 "register_operand" "")
499         (neg:SI (match_operand:SI 1 "register_operand" "")))]
500   ""
501   "
503   rtx target = gen_reg_rtx (SImode);
505   emit_move_insn (target, GEN_INT (0));
506   emit_insn (gen_subsi3 (target, target, operands[1]));
507   emit_move_insn (operands[0], target);
508   DONE;
511 (define_expand "subdi3"
512   [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
513    (set (reg:DI 2) (match_operand:DI 2 "nonmemory_operand" ""))
514    (set (reg:DI 0) (minus:DI (reg:DI 0) (reg:DI 2)))
515    (set (match_operand:DI 0 "register_operand" "") (reg:DI 0))]
516   ""
517   "")
519 (define_insn ""
520   [(set (reg:DI 0) (minus:DI (reg:DI 0) (reg:DI 2)))]
521   ""
522   "sub d2,d0\;subc d3,d1"
523   [(set_attr "cc" "clobber")])
525 ;; ----------------------------------------------------------------------
526 ;; MULTIPLY INSTRUCTIONS
527 ;; ----------------------------------------------------------------------
529 (define_insn "mulsi3"
530   [(set (match_operand:SI 0 "register_operand" "=d")
531         (mult:SI (match_operand:SI 1 "register_operand" "%0")
532                  (match_operand:SI 2 "register_operand" "d")))]
533   ""
534   "mul %2,%0"
535   [(set_attr "cc" "set_zn_c0")])
537 (define_expand "udivmodsi4"
538   [(parallel [(set (match_operand:SI 0 "register_operand" "")
539                    (udiv:SI (match_operand:SI 1 "register_operand" "")
540                             (match_operand:SI 2 "register_operand" "")))
541               (set (match_operand:SI 3 "register_operand" "")
542                    (umod:SI (match_dup 1) (match_dup 2)))])]
543   ""
544   "
546   rtx reg = gen_reg_rtx (SImode);
547   emit_move_insn (reg, GEN_INT (0));
548   emit_insn (gen_clear_mdr (reg));
551 (define_insn ""
552   [(set (match_operand:SI 0 "general_operand" "=d")
553         (udiv:SI (match_operand:SI 1 "general_operand" "0")
554                  (match_operand:SI 2 "general_operand" "d")))
555    (set (match_operand:SI 3 "general_operand" "=d")
556         (umod:SI (match_dup 1) (match_dup 2)))]
557   ""
558   "*
560   if (find_reg_note (insn, REG_UNUSED, operands[3]))
561     return \"divu %2,%0\";
562   else
563     return \"divu %2,%0\;mov mdr,%3\";
565   [(set_attr "cc" "set_zn_c0")])
567 (define_expand "divmodsi4"
568   [(parallel [(set (match_operand:SI 0 "register_operand" "")
569                    (div:SI (match_operand:SI 1 "register_operand" "")
570                             (match_operand:SI 2 "register_operand" "")))
571               (set (match_operand:SI 3 "register_operand" "")
572                    (mod:SI (match_dup 1) (match_dup 2)))])]
573   ""
574   "")
576 (define_insn ""
577   [(set (match_operand:SI 0 "general_operand" "=d")
578         (div:SI (match_operand:SI 1 "general_operand" "0")
579                  (match_operand:SI 2 "general_operand" "d")))
580    (set (match_operand:SI 3 "general_operand" "=d")
581         (mod:SI (match_dup 1) (match_dup 2)))]
582   ""
583   "*
585   if (find_reg_note (insn, REG_UNUSED, operands[3]))
586     return \"ext %0\;div %2,%0\";
587   else
588     return \"ext %0\;div %2,%0\;mov mdr,%3\";
590   [(set_attr "cc" "set_zn_c0")])
592 (define_insn "clear_mdr"
593   [(unspec_volatile [(const_int 2)] 0)
594    (use (match_operand:SI 0 "register_operand" "d"))]
595   ""
596   "mov %0,mdr"
597   [(set_attr "cc" "none")])
599 ;; ----------------------------------------------------------------------
600 ;; AND INSTRUCTIONS
601 ;; ----------------------------------------------------------------------
603 (define_insn "andsi3"
604   [(set (match_operand:SI 0 "register_operand" "=d,d")
605         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
606                 (match_operand:SI 2 "nonmemory_operand" "N,di")))]
607   ""
608   "*
610   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
611     return \"extbu %0\";
612   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
613     return \"exthu %0\";
614   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
615     return \"add %0,%0\;lsr 1,%0\";
616   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
617     return \"asl2 %0\;lsr 2,%0\";
618   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
619     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
620   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
621     return \"asl2 %0,%0\;asl2 %0\;lsr 4,%0\";
622   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
623     return \"lsr 1,%0\;add %0,%0\";
624   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
625     return \"lsr 2,%0\;asl2 %0\";
626   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
627     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
628   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
629     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
630   return \"and %2,%0\";
632   [(set_attr "cc" "none_0hit,set_zn_c0")])
634 ;; ----------------------------------------------------------------------
635 ;; OR INSTRUCTIONS
636 ;; ----------------------------------------------------------------------
638 (define_insn "iorsi3"
639   [(set (match_operand:SI 0 "register_operand" "=d")
640         (ior:SI (match_operand:SI 1 "register_operand" "%0")
641                 (match_operand:SI 2 "nonmemory_operand" "di")))]
642   ""
643   "or %2,%0"
644   [(set_attr "cc" "set_zn_c0")])
646 ;; ----------------------------------------------------------------------
647 ;; XOR INSTRUCTIONS
648 ;; ----------------------------------------------------------------------
650 (define_insn "xorsi3"
651   [(set (match_operand:SI 0 "register_operand" "=d")
652         (xor:SI (match_operand:SI 1 "register_operand" "%0")
653                 (match_operand:SI 2 "nonmemory_operand" "di")))]
654   ""
655   "xor %2,%0"
656   [(set_attr "cc" "set_zn_c0")])
658 ;; ----------------------------------------------------------------------
659 ;; NOT INSTRUCTIONS
660 ;; ----------------------------------------------------------------------
662 (define_insn "one_cmplsi2"
663   [(set (match_operand:SI 0 "register_operand" "=d")
664         (not:SI (match_operand:SI 1 "register_operand" "0")))]
665   ""
666   "not %0"
667   [(set_attr "cc" "set_zn_c0")])
669 ;; -----------------------------------------------------------------
670 ;; BIT FIELDS
671 ;; -----------------------------------------------------------------
674 ;; These set/clear memory in byte sized chunks.
676 ;; They are no smaller/faster than loading the value into a register
677 ;; and storing the register, but they don't need a scratch register
678 ;; which may allow for better code generation.
679 (define_insn ""
680   [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
681   ""
682   "@
683   bclr 255,%A0
684   clr %0"
685   [(set_attr "cc" "clobber")])
687 (define_insn ""
688   [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
689   ""
690   "@
691   bset 255,%A0
692   mov -1,%0"
693   [(set_attr "cc" "clobber,none_0hit")])
695 (define_insn ""
696   [(set (match_operand:QI 0 "general_operand" "=R,d")
697         (subreg:QI
698           (and:SI (subreg:SI (match_dup 0) 0)
699                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
700   ""
701   "@
702   bclr %N1,%A0
703   and %1,%0"
704   [(set_attr "cc" "clobber,set_zn_c0")])
706 (define_insn ""
707   [(set (match_operand:QI 0 "general_operand" "=R,d")
708         (subreg:QI
709           (ior:SI (subreg:SI (match_dup 0) 0)
710                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
711   ""
712   "@
713   bset %1,%A0
714   or %1,%0"
715   [(set_attr "cc" "clobber")])
717 (define_insn ""
718   [(set (cc0)
719      (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
720                       (match_operand 1 "const_int_operand" "")
721                       (match_operand 2 "const_int_operand" "")))]
722   ""
723   "*
725   int len = INTVAL (operands[1]);
726   int bit = INTVAL (operands[2]);
727   int mask = 0;
728   rtx xoperands[2];
730   while (len > 0)
731     {
732       mask |= (1 << bit);
733       bit++;
734       len--;
735     }
737   xoperands[0] = operands[0];
738   xoperands[1] = GEN_INT (mask);
739   output_asm_insn (\"btst %1,%0\", xoperands);
740   return \"\";
742   [(set_attr "cc" "set_zn_c0")])
744 (define_insn ""
745   [(set (cc0)
746      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
747                       (match_operand 1 "const_int_operand" "")
748                       (match_operand 2 "const_int_operand" "")))]
749   "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
750   "*
752   int len = INTVAL (operands[1]);
753   int bit = INTVAL (operands[2]);
754   int mask = 0;
755   rtx xoperands[2];
757   while (len > 0)
758     {
759       mask |= (1 << bit);
760       bit++;
761       len--;
762     }
764   xoperands[0] = operands[0];
765   xoperands[1] = GEN_INT (mask);
766   if (GET_CODE (operands[0]) == REG)
767     output_asm_insn (\"btst %1,%0\", xoperands);
768   else
769     output_asm_insn (\"btst %1,%A0\", xoperands);
770   return \"\";
772   [(set_attr "cc" "set_zn_c0")])
774 (define_insn ""
775   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "d")
776                       (match_operand:SI 1 "const_int_operand" "")))]
777   ""
778   "btst %1,%0"
779   [(set_attr "cc" "set_zn_c0")])
781 (define_insn ""
782   [(set (cc0)
783      (and:SI
784        (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
785        (match_operand:SI 1 "const_int_operand" "")))]
786   ""
787   "@
788   btst %1,%A0
789   btst %1,%0"
790   [(set_attr "cc" "set_zn_c0")])
792 ;; -----------------------------------------------------------------
793 ;; -----------------------------------------------------------------
794 ;; Scc INSTRUCTIONS
795 ;; -----------------------------------------------------------------
796 ;; It's probably worth the time to define setcc type insns too
799 ;; ----------------------------------------------------------------------
800 ;; JUMP INSTRUCTIONS
801 ;; ----------------------------------------------------------------------
803 ;; Conditional jump instructions
805 (define_expand "ble"
806   [(set (pc)
807         (if_then_else (le (cc0)
808                           (const_int 0))
809                       (label_ref (match_operand 0 "" ""))
810                       (pc)))]
811   ""
812   "")
814 (define_expand "bleu"
815   [(set (pc)
816         (if_then_else (leu (cc0)
817                            (const_int 0))
818                       (label_ref (match_operand 0 "" ""))
819                       (pc)))]
820   ""
821   "")
823 (define_expand "bge"
824   [(set (pc)
825         (if_then_else (ge (cc0)
826                           (const_int 0))
827                       (label_ref (match_operand 0 "" ""))
828                       (pc)))]
829   ""
830   "")
832 (define_expand "bgeu"
833   [(set (pc)
834         (if_then_else (geu (cc0)
835                            (const_int 0))
836                       (label_ref (match_operand 0 "" ""))
837                       (pc)))]
838   ""
839   "")
841 (define_expand "blt"
842   [(set (pc)
843         (if_then_else (lt (cc0)
844                           (const_int 0))
845                       (label_ref (match_operand 0 "" ""))
846                       (pc)))]
847   ""
848   "")
850 (define_expand "bltu"
851   [(set (pc)
852         (if_then_else (ltu (cc0)
853                            (const_int 0))
854                       (label_ref (match_operand 0 "" ""))
855                       (pc)))]
856   ""
857   "")
859 (define_expand "bgt"
860   [(set (pc)
861         (if_then_else (gt (cc0)
862                           (const_int 0))
863                       (label_ref (match_operand 0 "" ""))
864                       (pc)))]
865   ""
866   "")
868 (define_expand "bgtu"
869   [(set (pc)
870         (if_then_else (gtu (cc0)
871                            (const_int 0))
872                       (label_ref (match_operand 0 "" ""))
873                       (pc)))]
874   ""
875   "")
877 (define_expand "beq"
878   [(set (pc)
879         (if_then_else (eq (cc0)
880                           (const_int 0))
881                       (label_ref (match_operand 0 "" ""))
882                       (pc)))]
883   ""
884   "")
886 (define_expand "bne"
887   [(set (pc)
888         (if_then_else (ne (cc0)
889                           (const_int 0))
890                       (label_ref (match_operand 0 "" ""))
891                       (pc)))]
892   ""
893   "")
895 (define_insn ""
896   [(set (pc)
897         (if_then_else (match_operator 1 "comparison_operator"
898                                       [(cc0) (const_int 0)])
899                       (label_ref (match_operand 0 "" ""))
900                       (pc)))]
901   ""
902   "*
904   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
905       && (GET_CODE (operands[1]) == GT
906           || GET_CODE (operands[1]) == GE
907           || GET_CODE (operands[1]) == LE
908           || GET_CODE (operands[1]) == LT))
909     return 0;
910   return \"b%b1 %0\";
912  [(set_attr "cc" "none")])
914 (define_insn ""
915   [(set (pc)
916         (if_then_else (match_operator 1 "comparison_operator"
917                                       [(cc0) (const_int 0)])
918                       (pc)
919                       (label_ref (match_operand 0 "" ""))))]
920   ""
921   "*
923   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
924       && (GET_CODE (operands[1]) == GT
925           || GET_CODE (operands[1]) == GE
926           || GET_CODE (operands[1]) == LE
927           || GET_CODE (operands[1]) == LT))
928     return 0;
929   return \"b%B1 %0\";
931  [(set_attr "cc" "none")])
933 ;; Unconditional and other jump instructions.
935 (define_insn "jump"
936   [(set (pc)
937         (label_ref (match_operand 0 "" "")))]
938   ""
939   "jmp %l0"
940  [(set_attr "cc" "none")])
942 (define_insn "indirect_jump"
943   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
944   ""
945   "jmp (%0)"
946   [(set_attr "cc" "none")])
948 (define_insn "tablejump"
949   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
950    (use (label_ref (match_operand 1 "" "")))]
951   ""
952   "jmp  (%0)"
953   [(set_attr "cc" "none")])
955 ;; Call subroutine with no return value.
957 (define_expand "call"
958   [(call (match_operand:QI 0 "general_operand" "")
959          (match_operand:SI 1 "general_operand" ""))]
960   ""
961   "
963   if (! call_address_operand (XEXP (operands[0], 0)))
964     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
965   emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
966   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
967   emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4)));
968   DONE;
971 (define_insn "call_internal"
972   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
973          (match_operand:SI 1 "general_operand" "g"))]
974   ""
975   "calls %C0"
976   [(set_attr "cc" "clobber")])
978 ;; Call subroutine, returning value in operand 0
979 ;; (which must be a hard register).
981 (define_expand "call_value"
982   [(set (match_operand 0 "" "")
983         (call (match_operand:QI 1 "general_operand" "")
984               (match_operand:SI 2 "general_operand" "")))]
985   ""
986   "
988   if (! call_address_operand (XEXP (operands[1], 0)))
989     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
990   emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
991   emit_call_insn (gen_call_value_internal (operands[0],
992                                            XEXP (operands[1], 0),
993                                            operands[2]));
994   emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4)));
995   DONE;
998 (define_insn "call_value_internal"
999   [(set (match_operand 0 "" "=d")
1000         (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1001               (match_operand:SI 2 "general_operand" "g")))]
1002   ""
1003   "calls %C1"
1004   [(set_attr "cc" "clobber")])
1006 (define_insn "nop"
1007   [(const_int 0)]
1008   ""
1009   "nop"
1010   [(set_attr "cc" "none")])
1012 ;; ----------------------------------------------------------------------
1013 ;; EXTEND INSTRUCTIONS
1014 ;; ----------------------------------------------------------------------
1016 (define_insn "zero_extendqisi2"
1017   [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1018         (zero_extend:SI
1019          (match_operand:QI 1 "general_operand" "0,d,m")))]
1020   ""
1021   "@
1022   extbu %0
1023   mov %1,%0\;extbu %0
1024   movbu %1,%0"
1025   [(set_attr "cc" "none_0hit")])
1027 (define_insn "zero_extendhisi2"
1028   [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1029         (zero_extend:SI
1030          (match_operand:HI 1 "general_operand" "0,d,m")))]
1031   ""
1032   "@
1033   exthu %0
1034   mov %1,%0\;exthu %0
1035   movhu %1,%0"
1036   [(set_attr "cc" "none_0hit")])
1038 ;;- sign extension instructions
1040 (define_insn "extendqisi2"
1041   [(set (match_operand:SI 0 "general_operand" "=d,d")
1042         (sign_extend:SI
1043          (match_operand:QI 1 "general_operand" "0,d")))]
1044   ""
1045   "@
1046   extb %0
1047   mov %1,%0\;extb %0"
1048   [(set_attr "cc" "none_0hit")])
1050 (define_insn "extendhisi2"
1051   [(set (match_operand:SI 0 "general_operand" "=d,d")
1052         (sign_extend:SI
1053          (match_operand:HI 1 "general_operand" "0,d")))]
1054   ""
1055   "@
1056   exth %0
1057   mov %1,%0\;exth %0"
1058   [(set_attr "cc" "none_0hit")])
1060 ;; ----------------------------------------------------------------------
1061 ;; SHIFTS
1062 ;; ----------------------------------------------------------------------
1064 (define_insn "ashlsi3"
1065   [(set (match_operand:SI 0 "register_operand" "=da,d,a,d,a,d,a,d")
1066         (ashift:SI
1067          (match_operand:SI 1 "register_operand" "0,0,0,0,0,0,0,0")
1068          (match_operand:QI 2 "nonmemory_operand" "J,K,K,M,M,L,L,di")))]
1069   ""
1070   "@
1071   add %0,%0
1072   asl2 %0
1073   add %0,%0\;add %0,%0
1074   asl2 %0\;add %0,%0
1075   add %0,%0\;add %0,%0\;add %0,%0
1076   asl2 %0\;asl2 %0
1077   add %0,%0\;add %0,%0\;add %0,%0\;add %0,%0
1078   asl %2,%0"
1079   [(set_attr "cc" "set_zn_c0")])
1081 (define_insn "lshrsi3"
1082   [(set (match_operand:SI 0 "register_operand" "=d")
1083         (lshiftrt:SI
1084          (match_operand:SI 1 "register_operand" "0")
1085          (match_operand:QI 2 "nonmemory_operand" "di")))]
1086   ""
1087   "lsr %2,%0"
1088   [(set_attr "cc" "set_zn_c0")])
1090 (define_insn "ashrsi3"
1091   [(set (match_operand:SI 0 "register_operand" "=d")
1092         (ashiftrt:SI
1093          (match_operand:SI 1 "register_operand" "0")
1094          (match_operand:QI 2 "nonmemory_operand" "di")))]
1095   ""
1096   "asr %2,%0"
1097   [(set_attr "cc" "set_zn_c0")])
1099 ;; ----------------------------------------------------------------------
1100 ;; PROLOGUE/EPILOGUE
1101 ;; ----------------------------------------------------------------------
1102 (define_expand "prologue"
1103   [(const_int 0)]
1104   ""
1105   "expand_prologue (); DONE;")
1107 (define_expand "epilogue"
1108   [(return)]
1109   ""
1110   "
1112   expand_epilogue ();
1113   DONE;
1116 (define_insn "return_internal"
1117   [(const_int 2)]
1118   ""
1119   "rets"
1120   [(set_attr "cc" "clobber")])
1122 ;; This insn restores the callee saved registers and does a return, it
1123 ;; can also deallocate stack space.
1124 (define_insn "return_internal_regs"
1125   [(const_int 0)
1126    (match_operand:SI 0  "const_int_operand" "i")
1127    (return)]
1128   ""
1129   "ret [d2,d3,a2,a3],%0"
1130   [(set_attr "cc" "clobber")])
1132 (define_insn "store_movm"
1133   [(const_int 1)]
1134   ""
1135   "movm [d2,d3,a2,a3],(sp)"
1136   [(set_attr "cc" "clobber")])
1138 (define_insn "return"
1139   [(return)]
1140   "can_use_return_insn ()"
1141   "rets"
1142   [(set_attr "cc" "clobber")])
1144 ;; Try to combine consecutive updates of the stack pointer (or any
1145 ;; other register for that matter).
1146 (define_peephole
1147   [(set (match_operand:SI 0 "register_operand" "=dax")
1148         (plus:SI (match_dup 0)
1149                  (match_operand 1 "const_int_operand" "")))
1150    (set (match_dup 0)
1151         (plus:SI (match_dup 0)
1152                  (match_operand 2 "const_int_operand" "")))]
1153   ""
1154   "*
1156   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1157   return \"add %1,%0\";
1159   [(set_attr "cc" "clobber")])
1162 ;; We had patterns to check eq/ne, but the they don't work because
1163 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1165 ;; The Z flag and C flag would be set, and we have no way to
1166 ;; check for the Z flag set and C flag clear.
1168 ;; This will work on the mn10200 because we can check the ZX flag
1169 ;; if the comparison is in HImode.
1170 (define_peephole
1171   [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1172    (set (pc) (if_then_else (ge (cc0) (const_int 0))
1173                            (match_operand 1 "" "")
1174                            (pc)))]
1175   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1176   "add %0,%0\;bcc %1"
1177   [(set_attr "cc" "clobber")])
1179 (define_peephole
1180   [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1181    (set (pc) (if_then_else (lt (cc0) (const_int 0))
1182                            (match_operand 1 "" "")
1183                            (pc)))]
1184   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1185   "add %0,%0\;bcs %1"
1186   [(set_attr "cc" "clobber")])
1188 (define_peephole
1189   [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1190    (set (pc) (if_then_else (ge (cc0) (const_int 0))
1191                            (pc)
1192                            (match_operand 1 "" "")))]
1193   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1194   "add %0,%0\;bcs %1"
1195   [(set_attr "cc" "clobber")])
1197 (define_peephole
1198   [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1199    (set (pc) (if_then_else (lt (cc0) (const_int 0))
1200                            (pc)
1201                            (match_operand 1 "" "")))]
1202   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1203   "add %0,%0\;bcc %1"
1204   [(set_attr "cc" "clobber")])