import of gcc-2.8
[official-gcc.git] / gcc / config / mn10200 / mn10200.md
blob9dc753c3023ddd04d30726adceb221425c62bd8f
1 ;; GCC machine description for Matsushita MN10200
2 ;; Copyright (C) 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_znv - sets z,n,v to usable values; c is unknown.
34 ;; set_zn  - sets z,n to usable values; v,c is unknown.
35 ;; compare - compare instruction
36 ;; clobber - value of cc is unknown
37 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
38   (const_string "clobber"))
40 ;; ----------------------------------------------------------------------
41 ;; MOVE INSTRUCTIONS
42 ;; ----------------------------------------------------------------------
44 ;; Some general notes on move instructions.
46 ;; The hardware can't encode nop moves involving data registers, so
47 ;; we catch them and emit a nop instead.
49 ;; Loads/stores to/from address registers must be 16bit aligned,
50 ;; thus we avoid them for QImode.
52 ;; Stores from address registers always store 24bits, so avoid
53 ;; stores from address registers in HImode, SImode, and SFmode.
55 ;; As a result of the various problems using address registers in
56 ;; QImode, HImode, SImode, and SFmode, we discourage their use via
57 ;; '*' in their constraints.  They're still allowed, but they're never
58 ;; the preferred class for for insns with those modes.
60 ;; movqi
62 (define_expand "movqi"
63   [(set (match_operand:QI 0 "general_operand" "")
64         (match_operand:QI 1 "general_operand" ""))]
65   ""
66   "
68   /* One of the ops has to be in a register */
69   if (!register_operand (operand0, QImode)
70       && !register_operand (operand1, QImode))
71     operands[1] = copy_to_mode_reg (QImode, operand1);
72 }")
74 ;; We avoid memory operations involving address registers because we
75 ;; can't be sure they'll be suitably aligned.
77 ;; We also discourage holding QImode values in address registers.
78 (define_insn ""
79   [(set (match_operand:QI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a")
80         (match_operand:QI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a"))]
81   "register_operand (operands[0], QImode)
82    || register_operand (operands[1], QImode)"
83   "@
84   nop
85   sub %0,%0
86   sub %0,%0
87   mov %S1,%0
88   movbu %1,%0
89   movb %1,%0
90   mov %1,%0
91   mov %1,%0
92   mov %1,%0"
93   [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
95 ;; movhi
97 (define_expand "movhi"
98   [(set (match_operand:HI 0 "general_operand" "")
99         (match_operand:HI 1 "general_operand" ""))]
100   ""
101   "
103   /* One of the ops has to be in a register */
104   if (!register_operand (operand1, HImode)
105       && !register_operand (operand0, HImode))
106     operands[1] = copy_to_mode_reg (HImode, operand1);
109 (define_insn ""
110   [(set (match_operand:HI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a,*a")
111         (match_operand:HI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a,m"))]
112   "register_operand (operands[0], HImode)
113    || register_operand (operands[1], HImode)"
114   "@
115   nop
116   sub %0,%0
117   sub %0,%0
118   mov %s1,%0
119   mov %1,%0
120   mov %1,%0
121   mov %1,%0
122   mov %1,%0
123   mov %1,%0
124   mov %A1,%0"
125   [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
127 ;; movpsi and helpers
129 (define_expand "movpsi"
130   [(set (match_operand:PSI 0 "general_operand" "")
131         (match_operand:PSI 1 "general_operand" ""))]
132   ""
133   "
135   /* One of the ops has to be in a register */
136   if (!register_operand (operand1, PSImode)
137       && !register_operand (operand0, PSImode))
138     operands[1] = copy_to_mode_reg (PSImode, operand1);
142 ;; Constant and indexed addresses are not valid addresses for PSImode,
143 ;; therefore they won't be matched by the general movpsi pattern below.
144 ;; ??? We had patterns to handle indexed addresses, but they kept making
145 ;; us run out of regs, so they were eliminated.
147 (define_insn ""
148   [(set (match_operand:PSI 0 "register_operand" "=a")
149         (match_operand:PSI 1 "constant_memory_operand" ""))]
150   ""
151   "mov %A1,%0"
152   [(set_attr "cc" "none_0hit")])
154 (define_insn ""
155   [(set (match_operand:PSI 0 "constant_memory_operand" "=X")
156         (match_operand:PSI 1 "register_operand" "a"))]
157   ""
158   "mov %1,%A0"
159   [(set_attr "cc" "none_0hit")])
161 ;; We want to prefer address registers here because 24bit moves to/from
162 ;; memory are shorter and faster when done via address registers.
163 (define_insn ""
164   [(set (match_operand:PSI 0 "general_operand" "=d,a?d,?da,a,m,?d,m")
165         (match_operand:PSI 1 "general_operand" "0,I,?dai,m,a,m,?d"))]
166   "register_operand (operands[0], PSImode)
167    || register_operand (operands[1], PSImode)"
168   "@
169   nop
170   sub %0,%0
171   mov %1,%0
172   mov %A1,%0
173   mov %1,%A0
174   movx %A1,%0
175   movx %1,%A0"
176   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
178 (define_expand "movsi"
179   [(set (match_operand:SI 0 "general_operand" "")
180         (match_operand:SI 1 "general_operand" ""))]
181   ""
182   "
184   /* One of the ops has to be in a register */
185   if (!register_operand (operand1, SImode)
186       && !register_operand (operand0, SImode))
187     operands[1] = copy_to_mode_reg (SImode, operand1);
190 (define_insn ""
191   [(set (match_operand:SI 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a")
192         (match_operand:SI 1 "general_operand" "0,I,I,d,dim,*a,d,*a,i"))]
193   "register_operand (operands[0], SImode)
194    || register_operand (operands[1], SImode)"
195   "*
197   switch (which_alternative)
198     {
199     case 0:
200       return \"nop\";
201     case 1:
202     case 2:
203       return \"sub %H0,%H0\;sub %L0,%L0\";
204     case 3:
205     case 5:
206     case 6:
207     case 7:
208       return \"mov %H1,%H0\;mov %L1,%L0\";
210     /* The next two cases try to optimize cases where one half
211        of the constant is all zeros, or when the two halves are
212        the same.  */
213     case 4:
214     case 8:
215       if (REG_P (operands[0])
216           && GET_CODE (operands[1]) == CONST_INT
217           && (INTVAL (operands[1]) & 0xffff0000) == 0)
218         output_asm_insn (\"sub %H0,%H0\", operands);
219       else
220         output_asm_insn (\"mov %h1,%H0\", operands);
222       if (GET_CODE (operands[1]) == CONST_INT
223           && ((INTVAL (operands[1]) & 0xffff)
224               == ((INTVAL (operands[1]) >> 16) & 0xffff)))
225         output_asm_insn (\"mov %H0,%L0\", operands);
226       else if (GET_CODE (operands[1]) == CONST_INT
227                && (INTVAL (operands[1]) & 0xffff) == 0)
228         output_asm_insn (\"sub %L0,%L0\", operands);
229       else
230         output_asm_insn (\"mov %o1,%L0\", operands);
231       return \"\";
232     }
234   [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
236 (define_expand "movsf"
237   [(set (match_operand:SF 0 "general_operand" "")
238         (match_operand:SF 1 "general_operand" ""))]
239   ""
240   "
242   /* One of the ops has to be in a register */
243   if (!register_operand (operand1, SFmode)
244       && !register_operand (operand0, SFmode))
245     operands[1] = copy_to_mode_reg (SFmode, operand1);
248 (define_insn ""
249   [(set (match_operand:SF 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a")
250         (match_operand:SF 1 "general_operand" "0,G,G,d,dim,*a,d,*a,i"))]
251   "register_operand (operands[0], SFmode)
252    || register_operand (operands[1], SFmode)"
253   "*
255   switch (which_alternative)
256     {
257     case 0:
258       return \"nop\";
260     case 1:
261     case 2:
262       return \"sub %H0,%H0\;sub %L0,%L0\";
264     default:
265       {
266         long val;
267         REAL_VALUE_TYPE rv;
269         if (GET_CODE (operands[1]) == CONST_DOUBLE)
270           {
271             REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
272             REAL_VALUE_TO_TARGET_SINGLE (rv, val);
273           }
275         if (GET_CODE (operands[1]) == CONST_INT)
276           val = INTVAL (operands[1]);
278         if ((GET_CODE (operands[1]) == CONST_INT
279              || GET_CODE (operands[1]) == CONST_DOUBLE)
280             && (val & 0xffff0000) == 0)
281           output_asm_insn (\"sub %H0,%H0\", operands);
282         else
283           output_asm_insn (\"mov %h1,%H0\", operands);
284         
285         if (GET_CODE (operands[1]) == CONST_INT
286             && ((INTVAL (operands[1]) & 0xffff)
287                  == ((INTVAL (operands[1]) >> 16) & 0xffff)))
288           output_asm_insn (\"mov %H0,%L0\", operands);
289         else if ((GET_CODE (operands[1]) == CONST_INT
290                   || GET_CODE (operands[1]) == CONST_DOUBLE)
291                  && (val & 0x0000ffff) == 0)
292           output_asm_insn (\"sub %L0,%L0\", operands);
293         else
294           output_asm_insn (\"mov %o1,%L0\", operands);
295         return \"\";
296       }
297     }
299   [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
302 ;; ----------------------------------------------------------------------
303 ;; TEST INSTRUCTIONS
304 ;; ----------------------------------------------------------------------
306 ;; Go ahead and define tsthi and tstpsi so we can eliminate redundant tst insns
307 ;; when we start trying to optimize this port.
308 (define_insn "tsthi"
309   [(set (cc0) (match_operand:HI 0 "general_operand" "da"))]
310   ""
311   "* return output_tst (operands[0], insn);"
312   [(set_attr "cc" "set_znv")])
314 (define_insn "tstpsi"
315   [(set (cc0) (match_operand:PSI 0 "general_operand" "da"))]
316   ""
317   "* return output_tst (operands[0], insn);"
318   [(set_attr "cc" "set_znv")])
320 (define_insn ""
321   [(set (cc0) (zero_extend:HI (match_operand:QI 0 "memory_operand" "d")))]
322   ""
323   "* return output_tst (operands[0], insn);"
324   [(set_attr "cc" "set_znv")])
326 (define_insn ""
327   [(set (cc0) (zero_extend:PSI (match_operand:QI 0 "memory_operand" "d")))]
328   ""
329   "* return output_tst (operands[0], insn);"
330   [(set_attr "cc" "set_znv")])
332 (define_insn "cmphi"
333   [(set (cc0)
334         (compare:HI (match_operand:HI 0 "general_operand" "da")
335                     (match_operand:HI 1 "general_operand" "dai")))]
336   ""
337   "cmp %1,%0"
338   [(set_attr "cc" "compare")])
340 (define_insn "cmppsi"
341   [(set (cc0)
342         (compare:PSI (match_operand:PSI 0 "general_operand" "da")
343                      (match_operand:PSI 1 "general_operand" "dai")))]
344   ""
345   "cmp %1,%0"
346   [(set_attr "cc" "compare")])
348 ;; ----------------------------------------------------------------------
349 ;; ADD INSTRUCTIONS
350 ;; ----------------------------------------------------------------------
352 (define_insn "addhi3"
353   [(set (match_operand:HI 0 "general_operand" "=d")
354         (plus:HI (match_operand:HI 1 "general_operand" "%0")
355                  (match_operand:HI 2 "general_operand" "dai")))]
356   ""
357   "add %2,%0"
358   [(set_attr "cc" "set_zn")])
360 (define_insn "addpsi3"
361   [(set (match_operand:PSI 0 "general_operand" "=da")
362         (plus:PSI (match_operand:PSI 1 "general_operand" "%0")
363                   (match_operand:PSI 2 "general_operand" "dai")))]
364   ""
365   "add %2,%0"
366   [(set_attr "cc" "set_zn")])
368 ;; We want to avoid using explicit registers; reload won't tell us
369 ;; if it has to spill them and may generate incorrect code in such
370 ;; cases.
372 ;; So we call out to a library routine to perform 32bit add or
373 ;; subtract operations.
374 (define_expand "addsi3"
375   [(set (match_operand:SI 0 "general_operand" "")
376         (plus:SI (match_operand:SI 1 "general_operand" "")
377                  (match_operand:SI 2 "general_operand" "")))]
378   ""
379   "
381   /* If adding a CONST_INT, we are better off generating code ourselves.
383      During RTL generation we call out to library routines.
385      After RTL generation we can not call the library routines as
386      they need to push arguments via virtual_outgoing_args_rtx which
387      has already been instantiated.  So, after RTL generation we just
388      FAIL and open code the operation.  */
389   if (GET_CODE (operands[2]) == CONST_INT)
390     {
391       if (!rtx_equal_p (operands[0], operands[1]))
392         emit_move_insn (operands[0], operands[1]);
393       emit_insn (gen_addsi3_const (operands[0], operands[0], operands[2]));
394       DONE;
395     }
396   else if (rtx_equal_function_value_matters)
397     {
398       rtx ret, insns;
399       extern rtx emit_library_call_value ();
401       start_sequence ();
402       ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__addsi3\"),
403                                      NULL_RTX, 1, SImode, 2, operands[1],
404                                      SImode, operands[2], SImode);
405       insns = get_insns ();
406       end_sequence ();
407       emit_libcall_block (insns, operands[0], ret,
408                           gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
409       DONE;
410     }
411   else
412     FAIL;
415 (define_insn "addsi3_const"
416   [(set (match_operand:SI 0 "general_operand" "=d")
417         (plus:SI (match_operand:SI 1 "general_operand" "0")
418                  (match_operand:SI 2 "const_int_operand" "i")))
419    (clobber (match_scratch:SI 3 "=&d"))]
420   ""
421   "*
423   unsigned long value = INTVAL (operands[2]);
425   /* If only the high bits are set in the constant, then we only
426      need a single add operation.  It might be better to catch this
427      at RTL expansion time.  */
428   if ((value & 0xffff) == 0)
429     return \"add %h2,%H0\";
431   value >>= 16;
432   value &= 0xffff;
434   if (value == 0)
435     return \"sub %3,%3\;add %o2,%L0\;addc %3,%H0\";
436   else
437     return \"mov %h2,%3\;add %o2,%L0\;addc %3,%H0\";
439   [(set_attr "cc" "clobber")])
441 ;; ----------------------------------------------------------------------
442 ;; SUBTRACT INSTRUCTIONS
443 ;; ----------------------------------------------------------------------
445 (define_insn "subhi3"
446   [(set (match_operand:HI 0 "general_operand" "=d")
447         (minus:HI (match_operand:HI 1 "general_operand" "0")
448                   (match_operand:HI 2 "general_operand" "dai")))]
449   ""
450   "sub %2,%0"
451   [(set_attr "cc" "set_zn")])
453 (define_insn "subpsi3"
454   [(set (match_operand:PSI 0 "general_operand" "=da")
455         (minus:PSI (match_operand:PSI 1 "general_operand" "0")
456                   (match_operand:PSI 2 "general_operand" "dai")))]
457   ""
458   "sub %2,%0"
459   [(set_attr "cc" "set_zn")])
461 (define_expand "subsi3"
462   [(set (match_operand:SI 0 "general_operand" "")
463         (minus:SI (match_operand:SI 1 "general_operand" "")
464                   (match_operand:SI 2 "general_operand" "")))]
465   ""
466   "
468   /* During RTL generation we call out to library routines.
470      After RTL generation we can not call the library routines as
471      they need to push arguments via virtual_outgoing_args_rtx which
472      has already been instantiated.  So, after RTL generation we just
473      FAIL and open code the operation.  */
474   if (rtx_equal_function_value_matters)
475     {
476       rtx ret, insns;
477       extern rtx emit_library_call_value ();
479       start_sequence ();
480       ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__subsi3\"),
481                                      NULL_RTX, 1, SImode, 2, operands[1],
482                                      SImode, operands[2], SImode);
483       insns = get_insns ();
484       end_sequence ();
485       emit_libcall_block (insns, operands[0], ret,
486                           gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
487       DONE;
488     }
489   else
490     FAIL;
493 ;; There isn't a negate instruction, so we fake it.
495 ;; We used to expand this into patterns, but a single pattern
496 ;; actually generates better overall code.
497 ;; 
498 ;; We could do HImode negations with a "not;add" sequence, but
499 ;; generally it's generated slightly worse code.
501 ;; The second alternative is not strictly necesasry, but helps
502 ;; when the register allocators start running short of registers.
503 (define_insn "neghi2"
504   [(set (match_operand:HI 0 "general_operand" "=&d,d")
505         (neg:HI (match_operand:HI 1 "general_operand" "d,0")))]
506   ""
507   "@
508   sub %0,%0\;sub %1,%0
509   not %0\;add 1,%0"
510   [(set_attr "cc" "set_zn")])
512 ;; The not/and sequence won't work here.  It's not clear if we'll
513 ;; ever need to provide an alternate sequence since this should
514 ;; be used much less frequently than neghi2.
515 (define_insn "negpsi2"
516   [(set (match_operand:PSI 0 "general_operand" "=&d")
517         (neg:PSI (match_operand:PSI 1 "general_operand" "d")))]
518   ""
519   "sub %0,%0\;sub %1,%0"
520   [(set_attr "cc" "set_zn")])
522 ;; Using a magic libcall that accepts its arguments in any
523 ;; data register pair has proven to be the most efficient
524 ;; and most compact way to represent negsi2.
525 (define_insn "negsi2"
526   [(set (match_operand:SI 0 "general_operand" "=d")
527         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
528   ""
529   "jsr ___negsi2_%0"
530   [(set_attr "cc" "clobber")])
532 ;; ----------------------------------------------------------------------
533 ;; MULTIPLY INSTRUCTIONS
534 ;; ----------------------------------------------------------------------
536 ;; The mn10200 has HIxHI->SI widening multiply, but we get _severe_
537 ;; code density regressions if we enable such a pattern.
539 (define_insn "mulhi3"
540   [(set (match_operand:HI 0 "general_operand" "=d")
541         (mult:HI (match_operand:HI 1 "general_operand" "%0")
542                  (match_operand:HI 2 "general_operand" "d")))]
543   ""
544   "mul %2,%0"
545   [(set_attr "cc" "set_zn")])
547 (define_insn "udivmodhi4"
548   [(set (match_operand:HI 0 "general_operand" "=d")
549         (udiv:HI (match_operand:HI 1 "general_operand" "0")
550                  (match_operand:HI 2 "general_operand" "d")))
551    (set (match_operand:HI 3 "general_operand" "=&d")
552         (umod:HI (match_dup 1) (match_dup 2)))]
553   ""
554   "*
556   if (zero_dreg)
557     output_asm_insn (\"mov %0,mdr\", &zero_dreg);
558   else
559     output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
560     
561   if (find_reg_note (insn, REG_UNUSED, operands[3]))
562     return \"divu %2,%0\";
563   else
564     return \"divu %2,%0\;mov mdr,%3\";
566   [(set_attr "cc" "set_zn")])
569 ;; ----------------------------------------------------------------------
570 ;; AND INSTRUCTIONS
571 ;; ----------------------------------------------------------------------
573 (define_insn "andhi3"
574   [(set (match_operand:HI 0 "general_operand" "=d,d")
575         (and:HI (match_operand:HI 1 "general_operand" "%0,0")
576                 (match_operand:HI 2 "general_operand" "M,di")))]
577   ""
578   "*
580   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
581     return \"extxbu %0\";
582   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fff)
583     return \"add %0,%0\;lsr %0\";
584   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffe)
585     return \"lsr %0\;add %0,%0\";
586   return \"and %2,%0\";
588   [(set_attr "cc" "none_0hit,set_znv")])
590 ;; This expander + pattern exist only to allow trampolines to be aligned
591 ;; in the stack.
592 (define_expand "andpsi3"
593   [(set (match_operand:PSI 0 "general_operand" "")
594         (and:PSI (match_operand:PSI 1 "general_operand" "")
595                 (match_operand:PSI 2 "const_int_operand" "")))]
596   ""
597   "
599   if (GET_CODE (operands[2]) != CONST_INT
600       || (INTVAL (operands[2]) & 0xff0000) != 0xff0000)
601     FAIL;
604 (define_insn ""
605   [(set (match_operand:PSI 0 "general_operand" "=d")
606         (and:PSI (match_operand:PSI 1 "general_operand" "%0")
607                 (match_operand:PSI 2 "const_int_operand" "i")))]
608   "GET_CODE (operands[2]) == CONST_INT
609    && (INTVAL (operands[2]) & 0xff0000) == 0xff0000"
610   "and %2,%0"
611   [(set_attr "cc" "clobber")])
613 ;; ----------------------------------------------------------------------
614 ;; OR INSTRUCTIONS
615 ;; ----------------------------------------------------------------------
617 (define_insn "iorhi3"
618   [(set (match_operand:HI 0 "general_operand" "=d")
619         (ior:HI (match_operand:HI 1 "general_operand" "%0")
620                 (match_operand:HI 2 "general_operand" "di")))]
621   ""
622   "or %2,%0"
623   [(set_attr "cc" "set_znv")])
625 ;; ----------------------------------------------------------------------
626 ;; XOR INSTRUCTIONS
627 ;; ----------------------------------------------------------------------
629 (define_insn "xorhi3"
630   [(set (match_operand:HI 0 "general_operand" "=d")
631         (xor:HI (match_operand:HI 1 "general_operand" "%0")
632                 (match_operand:HI 2 "general_operand" "di")))]
633   ""
634   "xor %2,%0"
635   [(set_attr "cc" "set_znv")])
637 ;; ----------------------------------------------------------------------
638 ;; NOT INSTRUCTIONS
639 ;; ----------------------------------------------------------------------
641 (define_insn "one_cmplhi2"
642   [(set (match_operand:HI 0 "general_operand" "=d")
643         (not:HI (match_operand:HI 1 "general_operand" "0")))]
644   ""
645   "not %0"
646   [(set_attr "cc" "set_znv")])
649 ;; -----------------------------------------------------------------
650 ;; BIT INSTRUCTIONS
651 ;; -----------------------------------------------------------------
653 ;; These clears a constant set of bits in memory or in a register.
654 ;; We must support register destinations to make reload happy.
655 (define_insn ""
656   [(set (match_operand:QI 0 "general_operand" "R,d")
657         (subreg:QI
658           (and:HI (subreg:HI (match_dup 0) 0)
659                   (match_operand 1 "const_int_operand" "")) 0))
660    (clobber (match_scratch:HI 2 "=&d,X"))]
661   ""
662   "@
663   mov %N1,%2\;bclr %2,%0
664   and %1,%0"
665   [(set_attr "cc" "clobber")])
667 ;; This clears a variable set of bits in memory or in a register.
668 (define_insn ""
669   [(set (match_operand:QI 0 "general_operand" "R,d")
670         (subreg:QI
671           (and:HI (subreg:HI (match_dup 0) 0)
672                   (not:HI (match_operand:HI 1 "general_operand" "d,d"))) 0))
673    (clobber (match_scratch:HI 2 "=X,&d"))]
674   ""
675   "@
676   bclr %1,%0
677   mov %1,%2\;not %2\;and %2,%0"
678   [(set_attr "cc" "clobber")])
680 (define_insn ""
681   [(set (match_operand:QI 0 "general_operand" "R,d")
682         (subreg:QI
683           (and:HI (not:HI (match_operand:HI 1 "general_operand" "d,d"))
684                   (subreg:HI (match_dup 0) 0)) 0))
685    (clobber (match_scratch:HI 2 "=X,&d"))]
686   ""
687   "@
688   bclr %1,%0
689   mov %1,%2\;not %2\;and %2,%0"
690   [(set_attr "cc" "clobber")])
692 ;; These set bits in memory.
693 (define_insn ""
694   [(set (match_operand:QI 0 "general_operand" "R,d")
695         (subreg:QI
696           (ior:HI (subreg:HI (match_dup 0) 0)
697                   (match_operand:HI 1 "general_operand" "d,d")) 0))]
698   ""
699   "@
700   bset %1,%0
701   or %1,%0"
702   [(set_attr "cc" "clobber")])
704 (define_insn ""
705   [(set (match_operand:QI 0 "general_operand" "R,d")
706         (subreg:QI
707           (ior:HI (match_operand:HI 1 "general_operand" "d,d")
708                   (subreg:HI (match_dup 0) 0)) 0))]
709   ""
710   "@
711   bset %1,%0
712   or %1,%0"
713   [(set_attr "cc" "clobber")])
715 ;; Not any shorter/faster than using cmp, but it might save a
716 ;; register if the result of the AND isn't ever used.
718 (define_insn ""
719   [(set (cc0)
720      (zero_extract:HI (match_operand:HI 0 "general_operand" "d")
721                       (match_operand 1 "const_int_operand" "")
722                       (match_operand 2 "const_int_operand" "")))]
723   ""
724   "*
726   int len = INTVAL (operands[1]);
727   int bit = INTVAL (operands[2]);
728   int mask = 0;
729   rtx xoperands[2];
731   while (len > 0)
732     {
733       mask |= (1 << bit);
734       bit++;
735       len--;
736     }
738   xoperands[0] = operands[0];
739   xoperands[1] = GEN_INT (mask);
740   output_asm_insn (\"btst %1,%0\", xoperands);
741   return \"\";
743   [(set_attr "cc" "set_znv")])
745 (define_insn ""
746   [(set (cc0) (and:HI (match_operand:HI 0 "general_operand" "d")
747                       (match_operand:HI 1 "const_int_operand" "i")))]
748   ""
749   "btst %1,%0"
750   [(set_attr "cc" "set_znv")])
753 ;; ----------------------------------------------------------------------
754 ;; JUMP INSTRUCTIONS
755 ;; ----------------------------------------------------------------------
757 ;; Conditional jump instructions
759 (define_expand "ble"
760   [(set (pc)
761         (if_then_else (le (cc0)
762                           (const_int 0))
763                       (label_ref (match_operand 0 "" ""))
764                       (pc)))]
765   ""
766   "")
768 (define_expand "bleu"
769   [(set (pc)
770         (if_then_else (leu (cc0)
771                            (const_int 0))
772                       (label_ref (match_operand 0 "" ""))
773                       (pc)))]
774   ""
775   "")
777 (define_expand "bge"
778   [(set (pc)
779         (if_then_else (ge (cc0)
780                           (const_int 0))
781                       (label_ref (match_operand 0 "" ""))
782                       (pc)))]
783   ""
784   "")
786 (define_expand "bgeu"
787   [(set (pc)
788         (if_then_else (geu (cc0)
789                            (const_int 0))
790                       (label_ref (match_operand 0 "" ""))
791                       (pc)))]
792   ""
793   "")
795 (define_expand "blt"
796   [(set (pc)
797         (if_then_else (lt (cc0)
798                           (const_int 0))
799                       (label_ref (match_operand 0 "" ""))
800                       (pc)))]
801   ""
802   "")
804 (define_expand "bltu"
805   [(set (pc)
806         (if_then_else (ltu (cc0)
807                            (const_int 0))
808                       (label_ref (match_operand 0 "" ""))
809                       (pc)))]
810   ""
811   "")
813 (define_expand "bgt"
814   [(set (pc)
815         (if_then_else (gt (cc0)
816                           (const_int 0))
817                       (label_ref (match_operand 0 "" ""))
818                       (pc)))]
819   ""
820   "")
822 (define_expand "bgtu"
823   [(set (pc)
824         (if_then_else (gtu (cc0)
825                            (const_int 0))
826                       (label_ref (match_operand 0 "" ""))
827                       (pc)))]
828   ""
829   "")
831 (define_expand "beq"
832   [(set (pc)
833         (if_then_else (eq (cc0)
834                           (const_int 0))
835                       (label_ref (match_operand 0 "" ""))
836                       (pc)))]
837   ""
838   "")
840 (define_expand "bne"
841   [(set (pc)
842         (if_then_else (ne (cc0)
843                           (const_int 0))
844                       (label_ref (match_operand 0 "" ""))
845                       (pc)))]
846   ""
847   "")
849 (define_insn ""
850   [(set (pc)
851         (if_then_else (match_operator 1 "comparison_operator"
852                                       [(cc0) (const_int 0)])
853                       (label_ref (match_operand 0 "" ""))
854                       (pc)))]
855   ""
856   "*
858   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
859       && (GET_CODE (operands[1]) == GT
860           || GET_CODE (operands[1]) == GE
861           || GET_CODE (operands[1]) == LE
862           || GET_CODE (operands[1]) == LT))
863     return 0;
865   if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode)
866     return \"b%b1x %0\";
867   else
868     return \"b%b1 %0\";
870  [(set_attr "cc" "none")])
872 (define_insn ""
873   [(set (pc)
874         (if_then_else (match_operator 1 "comparison_operator"
875                                       [(cc0) (const_int 0)])
876                       (pc)
877                       (label_ref (match_operand 0 "" ""))))]
878   ""
879   "*
881   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
882       && (GET_CODE (operands[1]) == GT
883           || GET_CODE (operands[1]) == GE
884           || GET_CODE (operands[1]) == LE
885           || GET_CODE (operands[1]) == LT))
886     return 0;
888   if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode)
889     return \"b%B1x %0\";
890   else
891     return \"b%B1 %0\";
893  [(set_attr "cc" "none")])
895 (define_insn "jump"
896   [(set (pc)
897         (label_ref (match_operand 0 "" "")))]
898   ""
899   "jmp %l0"
900  [(set_attr "cc" "none")])
902 (define_insn "indirect_jump"
903   [(set (pc) (match_operand:PSI 0 "general_operand" "a"))]
904   ""
905   "jmp (%0)"
906   [(set_attr "cc" "none")])
908 (define_insn "tablejump"
909   [(set (pc) (match_operand:PSI 0 "general_operand" "a"))
910    (use (label_ref (match_operand 1 "" "")))]
911   ""
912   "jmp  (%0)"
913   [(set_attr "cc" "none")])
915 ;; Call subroutine with no return value.
917 (define_expand "call"
918   [(call (match_operand:QI 0 "general_operand" "")
919          (match_operand:HI 1 "general_operand" ""))]
920   ""
921   "
923   if (! call_address_operand (XEXP (operands[0], 0)))
924     XEXP (operands[0], 0) = force_reg (PSImode, XEXP (operands[0], 0));
925   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
926   DONE;
929 (define_insn "call_internal"
930   [(call (mem:QI (match_operand:PSI 0 "call_address_operand" "aS"))
931          (match_operand:HI 1 "general_operand" "g"))]
932   ""
933   "jsr %C0"
934   [(set_attr "cc" "clobber")])
936 ;; Call subroutine, returning value in operand 0
937 ;; (which must be a hard register).
939 (define_expand "call_value"
940   [(set (match_operand 0 "" "")
941         (call (match_operand:QI 1 "general_operand" "")
942               (match_operand:HI 2 "general_operand" "")))]
943   ""
944   "
946   if (! call_address_operand (XEXP (operands[1], 0)))
947     XEXP (operands[1], 0) = force_reg (PSImode, XEXP (operands[1], 0));
948   emit_call_insn (gen_call_value_internal (operands[0],
949                                            XEXP (operands[1], 0),
950                                            operands[2]));
951   DONE;
954 (define_insn "call_value_internal"
955   [(set (match_operand 0 "" "=da")
956         (call (mem:QI (match_operand:PSI 1 "call_address_operand" "aS"))
957               (match_operand:HI 2 "general_operand" "g")))]
958   ""
959   "jsr %C1"
960   [(set_attr "cc" "clobber")])
962 (define_expand "untyped_call"
963   [(parallel [(call (match_operand 0 "" "")
964                     (const_int 0))
965               (match_operand 1 "" "")
966               (match_operand 2 "" "")])]
967   ""
968   "
970   int i;
972   emit_call_insn (gen_call (operands[0], const0_rtx));
974   for (i = 0; i < XVECLEN (operands[2], 0); i++)
975     {
976       rtx set = XVECEXP (operands[2], 0, i);
977       emit_move_insn (SET_DEST (set), SET_SRC (set));
978     }
979   DONE;
982 (define_insn "nop"
983   [(const_int 0)]
984   ""
985   "nop"
986   [(set_attr "cc" "none")])
988 ;; ----------------------------------------------------------------------
989 ;; EXTEND INSTRUCTIONS
990 ;; ----------------------------------------------------------------------
992 (define_insn "zero_extendqihi2"
993   [(set (match_operand:HI 0 "general_operand" "=d,d,d")
994         (zero_extend:HI
995          (match_operand:QI 1 "general_operand" "0,di,m")))]
996   ""
997   "@
998   extxbu %0
999   mov %1,%0\;extxbu %0
1000   movbu %1,%0"
1001   [(set_attr "cc" "none_0hit")])
1003 (define_insn "zero_extendqipsi2"
1004   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1005         (zero_extend:PSI
1006          (match_operand:QI 1 "general_operand" "0,di,m")))]
1007   ""
1008   "@
1009   extxbu %0
1010   mov %1,%0\;extxbu %0
1011   movbu %1,%0"
1012   [(set_attr "cc" "none_0hit")])
1014 (define_insn "zero_extendqisi2"
1015   [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1016         (zero_extend:SI
1017          (match_operand:QI 1 "general_operand" "0,di,m")))]
1018   ""
1019   "@
1020   extxbu %L0\;sub %H0,%H0
1021   mov %1,%L0\;extxbu %L0\;sub %H0,%H0
1022   movbu %1,%L0\;sub %H0,%H0"
1023   [(set_attr "cc" "none_0hit")])
1025 (define_insn "zero_extendhipsi2"
1026   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1027         (zero_extend:PSI
1028          (match_operand:HI 1 "general_operand" "0,di,m")))]
1029   ""
1030   "@
1031   extxu %0
1032   mov %1,%0\;extxu %0
1033   mov %1,%0\;extxu %0"
1034   [(set_attr "cc" "none_0hit")])
1036 (define_insn "zero_extendhisi2"
1037   [(set (match_operand:SI 0 "general_operand" "=d,d")
1038         (zero_extend:SI
1039          (match_operand:HI 1 "general_operand" "0,dim")))]
1040   ""
1041   "@
1042   sub %H0,%H0
1043   mov %1,%L0\;sub %H0,%H0"
1044   [(set_attr "cc" "none_0hit")])
1046 ;; The last alternative is necessary because the second operand might
1047 ;; have been the frame pointer.  The frame pointer would get replaced
1048 ;; by (plus (stack_pointer) (const_int)).
1050 ;; Reload would think that it only needed a PSImode register in
1051 ;; push_reload and at the start of allocate_reload_regs.  However,
1052 ;; at the end of allocate_reload_reg it would realize that the
1053 ;; reload register must also be valid for SImode, and if it was
1054 ;; not valid reload would abort.
1055 (define_insn "zero_extendpsisi2"
1056   [(set (match_operand:SI 0 "register_operand" "=d,?d,?*d,?*d")
1057         (zero_extend:SI (match_operand:PSI 1 "extendpsi_operand"
1058                                                 "m,?0,?*dai,Q")))]
1059   ""
1060   "@
1061   mov %L1,%L0\;movbu %H1,%H0
1062   jsr ___zero_extendpsisi2_%0
1063   mov %1,%L0\;jsr ___zero_extendpsisi2_%0
1064   mov a3,%L0\;add %Z1,%L0\;jsr ___zero_extendpsisi2_%0"
1065   [(set_attr "cc" "clobber")])
1067 ;;- sign extension instructions
1069 (define_insn "extendqihi2"
1070   [(set (match_operand:HI 0 "general_operand" "=d,d,d")
1071         (sign_extend:HI
1072          (match_operand:QI 1 "general_operand" "0,di,m")))]
1073   ""
1074   "*
1076   if (which_alternative == 0)
1077     return \"extxb %0\";
1078   else if (which_alternative == 1)
1079     return \"mov %1,%0\;extxb %0\";
1080   else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1081     return \"movbu %1,%0\;extxb %0\";
1082   else
1083     return \"movb %1,%0\";
1085   [(set_attr "cc" "none_0hit")])
1087 (define_insn "extendqipsi2"
1088   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1089         (sign_extend:PSI
1090          (match_operand:QI 1 "general_operand" "0,di,m")))]
1091   ""
1092   "*
1094   if (which_alternative == 0)
1095     return \"extxb %0\";
1096   else if (which_alternative == 1)
1097     return \"mov %1,%0\;extxb %0\";
1098   else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1099     return \"movbu %1,%0\;extxb %0\";
1100   else
1101     return \"movb %1,%0\";
1103   [(set_attr "cc" "none_0hit")])
1105 (define_insn "extendqisi2"
1106   [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1107         (sign_extend:SI
1108          (match_operand:QI 1 "general_operand" "0,di,m")))]
1109   ""
1110   "*
1112   if (which_alternative == 0)
1113     return \"extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1114   else if (which_alternative == 1)
1115     return \"mov %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1116   else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1117     return \"movbu %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1118   else
1119     return \"movb %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1121   [(set_attr "cc" "none_0hit")])
1123 (define_insn "extendhipsi2"
1124   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1125         (sign_extend:PSI
1126          (match_operand:HI 1 "general_operand" "0,di,m")))]
1127   ""
1128   "@
1129   extx %0
1130   mov %1,%0\;extx %0
1131   mov %1,%0"
1132   [(set_attr "cc" "none_0hit")])
1134 (define_insn "extendhisi2"
1135   [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1136         (sign_extend:SI
1137          (match_operand:HI 1 "general_operand" "0,di,m")))]
1138   ""
1139   "@
1140   mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0
1141   mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0
1142   mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0"
1143   [(set_attr "cc" "none_0hit")])
1145 ;; The last alternative is necessary because the second operand might
1146 ;; have been the frame pointer.  The frame pointer would get replaced
1147 ;; by (plus (stack_pointer) (const_int)).
1149 ;; Reload would think that it only needed a PSImode register in
1150 ;; push_reload and at the start of allocate_reload_regs.  However,
1151 ;; at the end of allocate_reload_reg it would realize that the
1152 ;; reload register must also be valid for SImode, and if it was
1153 ;; not valid reload would abort.
1154 (define_insn "extendpsisi2"
1155   [(set (match_operand:SI 0 "general_operand" "=d,?d,?*d,?*d")
1156         (sign_extend:SI (match_operand:PSI 1 "extendpsi_operand"
1157                                                 "m,?0,?*dai,Q")))]
1158   ""
1159   "@
1160   mov %L1,%L0\;movb %H1,%H0
1161   jsr ___sign_extendpsisi2_%0
1162   mov %1,%L0\;jsr ___sign_extendpsisi2_%0
1163   mov a3,%L0\;add %Z1,%L0\;jsr ___sign_extendpsisi2_%0"
1164   [(set_attr "cc" "clobber")])
1166 (define_insn "truncsipsi2"
1167   [(set (match_operand:PSI 0 "general_operand" "=a,?d,?*d,da")
1168         (truncate:PSI (match_operand:SI 1 "general_operand" "m,?m,?*d,i")))]
1169    ""
1170    "@
1171    mov %1,%0
1172    movx %A1,%0
1173    jsr ___truncsipsi2_%1_%0
1174    mov %1,%0"
1175   [(set_attr "cc" "clobber")])
1178 ;; Combine should be simplifying this stuff, but isn't.
1180 (define_insn ""
1181   [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1182         (sign_extend:SI
1183           (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1184   ""
1185   "@
1186   extxbu %L0\;sub %H0,%H0
1187   mov %1,%L0\;extxbu %L0\;sub %H0,%H0
1188   movbu %1,%L0\;sub %H0,%H0"
1189   [(set_attr "cc" "none_0hit")])
1191 (define_insn ""
1192   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1193         (truncate:PSI
1194           (sign_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1195   ""
1196   "*
1198   if (which_alternative == 0)
1199     return \"extxb %0\";
1200   else if (which_alternative == 1)
1201     return \"mov %1,%0\;extxb %0\";
1202   else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1203     return \"movbu %1,%0\;extxb %0\";
1204   else
1205     return \"movb %1,%0\";
1207   [(set_attr "cc" "none_0hit")])
1209 (define_insn ""
1210   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1211         (truncate:PSI
1212           (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))]
1213   ""
1214   "@
1215   extx %0
1216   mov %1,%0\;extx %0
1217   mov %1,%0"
1218   [(set_attr "cc" "none_0hit")])
1220 (define_insn ""
1221   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1222         (truncate:PSI
1223           (sign_extend:SI
1224             (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))))]
1225   ""
1226   "@
1227   extxbu %0
1228   mov %1,%0\;extxbu %0
1229   movbu %1,%0"
1230   [(set_attr "cc" "none_0hit")])
1232 (define_insn ""
1233   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1234         (truncate:PSI
1235           (zero_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))]
1236   ""
1237   "@
1238   extxu %0
1239   mov %1,%0\;extxu %0
1240   mov %1,%0\;extxu %0"
1241   [(set_attr "cc" "none_0hit")])
1243 (define_insn ""
1244   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1245         (truncate:PSI
1246           (zero_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1247   ""
1248   "@
1249   extxbu %0
1250   mov %1,%0\;extxbu %0
1251   movbu %1,%0"
1252   [(set_attr "cc" "none_0hit")])
1254 ;; ----------------------------------------------------------------------
1255 ;; SHIFTS
1256 ;; ----------------------------------------------------------------------
1258 ;; If the shift count is small, we expand it into several single bit
1259 ;; shift insns.  Otherwise we expand into a generic shift insn which
1260 ;; handles larger shift counts, shift by variable amounts, etc.
1261 (define_expand "ashlhi3"
1262   [(set (match_operand:HI 0 "general_operand" "")
1263         (ashift:HI (match_operand:HI 1 "general_operand" "")
1264                    (match_operand:HI 2 "general_operand" "")))]
1265   ""
1266   "
1268   /* This is an experiment to see if exposing more of the underlying
1269      operations results in better code.  */
1270   if (GET_CODE (operands[2]) == CONST_INT
1271       && INTVAL (operands[2]) <= 4)
1272     {
1273       int count = INTVAL (operands[2]);
1274       emit_move_insn (operands[0], operands[1]);
1275       while (count > 0)
1276         {
1277           emit_insn (gen_rtx (SET, HImode, operands[0],
1278                               gen_rtx (ASHIFT, HImode,
1279                                        operands[0], GEN_INT (1))));
1280           count--;
1281         }
1282       DONE;
1283     }
1284   else
1285     {
1286       expand_a_shift (HImode, ASHIFT, operands);
1287       DONE;
1288     }
1291 ;; ASHIFT one bit.
1292 (define_insn ""
1293   [(set (match_operand:HI 0 "general_operand" "=d")
1294         (ashift:HI (match_operand:HI 1 "general_operand" "0")
1295                    (const_int 1)))]
1296   ""
1297   "add %0,%0"
1298   [(set_attr "cc" "set_zn")])
1300 (define_expand "lshrhi3"
1301   [(set (match_operand:HI 0 "general_operand" "")
1302         (lshiftrt:HI (match_operand:HI 1 "general_operand" "")
1303                      (match_operand:HI 2 "general_operand" "")))]
1304   ""
1305   "
1307   /* This is an experiment to see if exposing more of the underlying
1308      operations results in better code.  */
1309   if (GET_CODE (operands[2]) == CONST_INT
1310       && INTVAL (operands[2]) <= 4)
1311     {
1312       int count = INTVAL (operands[2]);
1313       emit_move_insn (operands[0], operands[1]);
1314       while (count > 0)
1315         {
1316           emit_insn (gen_rtx (SET, HImode, operands[0],
1317                               gen_rtx (LSHIFTRT, HImode,
1318                                        operands[0], GEN_INT (1))));
1319           count--;
1320         }
1321       DONE;
1322     }
1323   else
1324     {
1325       expand_a_shift (HImode, LSHIFTRT, operands);
1326       DONE;
1327     }
1330 ;; LSHIFTRT one bit.
1331 (define_insn ""
1332   [(set (match_operand:HI 0 "general_operand" "=d")
1333         (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1334                      (const_int 1)))]
1335   ""
1336   "lsr %0"
1337   [(set_attr "cc" "set_znv")])
1339 (define_expand "ashrhi3"
1340   [(set (match_operand:HI 0 "general_operand" "")
1341         (ashiftrt:HI (match_operand:HI 1 "general_operand" "")
1342                      (match_operand:HI 2 "general_operand" "")))]
1343   ""
1344   "
1346   /* This is an experiment to see if exposing more of the underlying
1347      operations results in better code.  */
1348   if (GET_CODE (operands[2]) == CONST_INT
1349       && INTVAL (operands[2]) <= 4)
1350     {
1351       int count = INTVAL (operands[2]);
1352       emit_move_insn (operands[0], operands[1]);
1353       while (count > 0)
1354         {
1355           emit_insn (gen_rtx (SET, HImode, operands[0],
1356                               gen_rtx (ASHIFTRT, HImode,
1357                                        operands[0], GEN_INT (1))));
1358           count--;
1359         }
1360       DONE;
1361     }
1362   else
1363     {
1364       expand_a_shift (HImode, ASHIFTRT, operands);
1365       DONE;
1366     }
1369 ;; ASHIFTRT one bit.
1370 (define_insn ""
1371   [(set (match_operand:HI 0 "general_operand" "=d")
1372         (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1373                      (const_int 1)))]
1374   ""
1375   "asr %0"
1376   [(set_attr "cc" "set_znv")])
1378 ;; And the general HImode shift pattern.  Handles both shift by constants
1379 ;; and shift by variable counts.
1380 (define_insn ""
1381   [(set (match_operand:HI 0 "general_operand" "=d,d")
1382         (match_operator:HI 3 "nshift_operator" 
1383                         [ (match_operand:HI 1 "general_operand" "0,0")
1384                           (match_operand:HI 2 "general_operand" "KL,dan")]))
1385    (clobber (match_scratch:HI 4 "=X,&d"))]
1386   ""
1387   "* return emit_a_shift (insn, operands);"
1388   [(set_attr "cc" "clobber")])
1390 ;; We expect only ASHIFT with constant shift counts to be common for
1391 ;; PSImode, so we optimize just that case.  For all other cases we
1392 ;; extend the value to SImode and perform the shift in SImode.
1393 (define_expand "ashlpsi3"
1394   [(set (match_operand:PSI 0 "general_operand" "")
1395         (ashift:PSI (match_operand:PSI 1 "general_operand" "")
1396                    (match_operand:HI 2 "general_operand" "")))]
1397   ""
1398   "
1400   /* This is an experiment to see if exposing more of the underlying
1401      operations results in better code.  */
1402   if (GET_CODE (operands[2]) == CONST_INT
1403       && INTVAL (operands[2]) <= 7)
1404     {
1405       int count = INTVAL (operands[2]);
1406       emit_move_insn (operands[0], operands[1]);
1407       while (count > 0)
1408         {
1409           emit_insn (gen_rtx (SET, PSImode, operands[0],
1410                               gen_rtx (ASHIFT, PSImode,
1411                                        operands[0], GEN_INT (1))));
1412           count--;
1413         }
1414       DONE;
1415     }
1416   else
1417     {
1418       expand_a_shift (PSImode, ASHIFT, operands);
1419       DONE;
1420     }
1423 ;; ASHIFT one bit.
1424 (define_insn ""
1425   [(set (match_operand:PSI 0 "general_operand" "=d")
1426         (ashift:PSI (match_operand:PSI 1 "general_operand" "0")
1427                     (const_int 1)))]
1428   ""
1429   "add %0,%0"
1430   [(set_attr "cc" "set_zn")])
1432 (define_expand "lshrpsi3"
1433   [(set (match_operand:PSI 0 "general_operand" "")
1434         (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "")
1435                      (match_operand:HI 2 "general_operand" "")))]
1436   ""
1437   "
1439   rtx reg = gen_reg_rtx (SImode);
1441   emit_insn (gen_zero_extendpsisi2 (reg, operands[1]));
1442   reg = expand_binop (SImode, lshr_optab, reg,
1443                       operands[2], reg, 1, OPTAB_WIDEN);
1444   emit_insn (gen_truncsipsi2 (operands[0], reg));
1445   DONE;
1448 (define_expand "ashrpsi3"
1449   [(set (match_operand:PSI 0 "general_operand" "")
1450         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "")
1451                      (match_operand:HI 2 "general_operand" "")))]
1452   ""
1453   "
1455   rtx reg = gen_reg_rtx (SImode);
1457   emit_insn (gen_extendpsisi2 (reg, operands[1]));
1458   reg = expand_binop (SImode, ashr_optab, reg,
1459                       operands[2], reg, 0, OPTAB_WIDEN);
1460   emit_insn (gen_truncsipsi2 (operands[0], reg));
1461   DONE;
1464 (define_expand "ashlsi3"
1465   [(set (match_operand:SI 0 "register_operand" "")
1466         (ashift:SI (match_operand:SI 1 "nonmemory_operand" "")
1467                    (match_operand:HI 2 "general_operand" "")))]
1468   ""
1469   "
1471   /* For small shifts, just emit a series of single bit shifts inline.
1473      For other constant shift counts smaller than a word or non-constant
1474      shift counts we call out to a library call during RTL generation time;
1475      after RTL generation time we allow optabs.c to open code the operation.
1476      See comments in addsi3/subsi3 expanders.
1478      Otherwise we allow optabs.c to open code the operation.  */
1479   if (GET_CODE (operands[2]) == CONST_INT
1480       && (INTVAL (operands[2]) <= 3))
1481     {
1482       int count = INTVAL (operands[2]);
1483       emit_move_insn (operands[0], operands[1]);
1484       while (count > 0)
1485         {
1486           emit_insn (gen_rtx (SET, SImode, operands[0],
1487                                    gen_rtx (ASHIFT, SImode,
1488                                             operands[0], GEN_INT (1))));
1489           count--;
1490         }
1491       DONE;
1492     }
1493   else if (rtx_equal_function_value_matters
1494            && (GET_CODE (operands[2]) != CONST_INT
1495                || INTVAL (operands[2]) <= 15))
1496     {
1497       rtx ret, insns;
1498       extern rtx emit_library_call_value ();
1500       start_sequence ();
1501       ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashlsi3\"),
1502                                      NULL_RTX, 1, SImode, 2, operands[1],
1503                                      SImode, operands[2], HImode);
1504       insns = get_insns ();
1505       end_sequence ();
1506       emit_libcall_block (insns, operands[0], ret,
1507                           gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
1508       DONE;
1509     }
1510   else
1511     FAIL;
1514 ;; ASHIFT one bit.
1515 (define_insn ""
1516   [(set (match_operand:SI 0 "general_operand" "=d")
1517         (ashift:SI (match_operand:SI 1 "general_operand" "0")
1518                      (const_int 1)))]
1519   ""
1520   "add %L0,%L0\;addc %H0,%H0"
1521   [(set_attr "cc" "clobber")])
1523 (define_expand "lshrsi3"
1524   [(set (match_operand:SI 0 "register_operand" "")
1525         (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
1526                      (match_operand:HI 2 "general_operand" "")))]
1527   ""
1528   "
1530   /* For small shifts, just emit a series of single bit shifts inline.
1532      For other constant shift counts smaller than a word or non-constant
1533      shift counts we call out to a library call during RTL generation time;
1534      after RTL generation time we allow optabs.c to open code the operation.
1535      See comments in addsi3/subsi3 expanders.
1537      Otherwise we allow optabs.c to open code the operation.  */
1538   if (GET_CODE (operands[2]) == CONST_INT
1539       && (INTVAL (operands[2]) <= 2))
1540     {
1541       int count = INTVAL (operands[2]);
1542       emit_move_insn (operands[0], operands[1]);
1543       while (count > 0)
1544         {
1545           emit_insn (gen_rtx (SET, SImode, operands[0],
1546                                    gen_rtx (LSHIFTRT, SImode,
1547                                             operands[0], GEN_INT (1))));
1548           count--;
1549         }
1550       DONE;
1551     }
1552   else if (rtx_equal_function_value_matters
1553            && (GET_CODE (operands[2]) != CONST_INT
1554                || INTVAL (operands[2]) <= 15))
1555     {
1556       rtx ret, insns;
1557       extern rtx emit_library_call_value ();
1559       start_sequence ();
1560       ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__lshrsi3\"),
1561                                      NULL_RTX, 1, SImode, 2, operands[1],
1562                                      SImode, operands[2], HImode);
1563       insns = get_insns ();
1564       end_sequence ();
1565       emit_libcall_block (insns, operands[0], ret,
1566                           gen_rtx (LSHIFTRT, SImode, operands[1], operands[2]));
1567       DONE;
1568     }
1569   else
1570     FAIL;
1573 ;; LSHIFTRT one bit.
1574 (define_insn ""
1575   [(set (match_operand:SI 0 "general_operand" "=d")
1576         (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1577                      (const_int 1)))]
1578   ""
1579   "lsr %H0\;ror %L0"
1580   [(set_attr "cc" "clobber")])
1582 (define_expand "ashrsi3"
1583   [(set (match_operand:SI 0 "register_operand" "")
1584         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1585                      (match_operand:HI 2 "general_operand" "")))]
1586   ""
1587   "
1589   /* For small shifts, just emit a series of single bit shifts inline.
1591      For other constant shift counts smaller than a word or non-constant
1592      shift counts we call out to a library call during RTL generation time;
1593      after RTL generation time we allow optabs.c to open code the operation.
1594      See comments in addsi3/subsi3 expanders.
1596      Otherwise we allow optabs.c to open code the operation.  */
1597   if (GET_CODE (operands[2]) == CONST_INT
1598       && (INTVAL (operands[2]) <= 2))
1599     {
1600       int count = INTVAL (operands[2]);
1601       emit_move_insn (operands[0], operands[1]);
1602       while (count > 0)
1603         {
1604           emit_insn (gen_rtx (SET, SImode, operands[0],
1605                                    gen_rtx (ASHIFTRT, SImode,
1606                                             operands[0], GEN_INT (1))));
1607           count--;
1608         }
1609       DONE;
1610     }
1611   else if (rtx_equal_function_value_matters
1612            && (GET_CODE (operands[2]) != CONST_INT
1613                || INTVAL (operands[2]) <= 15))
1614     {
1615       rtx ret, insns;
1616       extern rtx emit_library_call_value ();
1618       start_sequence ();
1619       ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashrsi3\"),
1620                                      NULL_RTX, 1, SImode, 2, operands[1],
1621                                      SImode, operands[2], HImode);
1622       insns = get_insns ();
1623       end_sequence ();
1624       emit_libcall_block (insns, operands[0], ret,
1625                           gen_rtx (ASHIFTRT, SImode, operands[1], operands[2]));
1626       DONE;
1627     }
1628   else
1629     FAIL;
1632 ;; ASHIFTRT one bit.
1633 (define_insn ""
1634   [(set (match_operand:SI 0 "general_operand" "=d")
1635         (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1636                      (const_int 1)))]
1637   ""
1638   "asr %H0\;ror %L0"
1639   [(set_attr "cc" "clobber")])
1641 ;; ----------------------------------------------------------------------
1642 ;; PROLOGUE/EPILOGUE
1643 ;; ----------------------------------------------------------------------
1644 (define_expand "prologue"
1645   [(const_int 0)]
1646   ""
1647   "expand_prologue (); DONE;")
1649 (define_insn "outline_prologue_call"
1650   [(const_int 1)]
1651   ""
1652   "jsr ___prologue"
1653   [(set_attr "cc" "clobber")])
1655 (define_expand "epilogue"
1656   [(return)]
1657   ""
1658   "
1660   expand_epilogue ();
1661   DONE;
1664 (define_insn "outline_epilogue_call_a0"
1665   [(const_int 2)]
1666   ""
1667   "jsr ___epilogue_a0"
1668   [(set_attr "cc" "clobber")])
1670 (define_insn "outline_epilogue_call_d0"
1671   [(const_int 3)]
1672   ""
1673   "jsr ___epilogue_d0"
1674   [(set_attr "cc" "clobber")])
1676 (define_insn "outline_epilogue_jump"
1677   [(const_int 4)]
1678   ""
1679   "jmp ___epilogue_noreturn"
1680   [(set_attr "cc" "clobber")])
1682 (define_insn "return"
1683   [(return)]
1684   "reload_completed && total_frame_size () == 0
1685    && !current_function_needs_context"
1686   "*
1688   rtx next = next_active_insn (insn);
1690   if (next
1691       && GET_CODE (next) == JUMP_INSN
1692       && GET_CODE (PATTERN (next)) == RETURN)
1693     return \"\";
1694   return \"rts\";
1696   [(set_attr "cc" "clobber")])
1698 (define_insn "return_internal"
1699   [(const_int 0)
1700    (return)]
1701   ""
1702   "rts"
1703   [(set_attr "cc" "clobber")])
1705 ;; These are special combiner patterns to improve array/pointer accesses.
1707 ;; A typical sequence involves extending an integer/char, shifting it left
1708 ;; a few times, then truncating the value to PSImode.
1710 ;; This first pattern combines the shifting & truncation operations, by
1711 ;; itself it is a win because the shifts end up occurring in PSImode instead
1712 ;; of SImode.  However, it has the secondary effect of giving us the
1713 ;; opportunity to match patterns which allow us to remove the initial
1714 ;; extension completely, which is a big win.
1715 (define_insn ""
1716   [(set (match_operand:PSI 0 "general_operand" "=d,d,a")
1717         (truncate:PSI
1718           (ashift:SI (match_operand:SI 1 "general_operand" "d,m,m")
1719                      (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1720   ""
1721   "*
1723   int count = INTVAL (operands[2]);
1724   if (which_alternative == 0)
1725     output_asm_insn (\"jsr ___truncsipsi2_%1_%0\", operands);
1726   else if (which_alternative == 1)
1727     output_asm_insn (\"movx %A1,%0\", operands);
1728   else
1729     output_asm_insn (\" mov %1,%0\", operands);
1731   while (count)
1732     {
1733       output_asm_insn (\"add %0,%0\", operands);
1734       count--;
1735     }
1736   return \"\";
1738   [(set_attr "cc" "clobber")])
1740 ;; Similarly, except that we also have zero/sign extension of the
1741 ;; original operand.  */
1742 (define_insn ""
1743   [(set (match_operand:PSI 0 "general_operand" "=d,d")
1744         (truncate:PSI
1745           (ashift:SI
1746             (zero_extend:SI (match_operand:HI 1 "general_operand" "0,dim"))
1747             (match_operand:HI 2 "const_int_operand" "i,i"))))]
1748   ""
1749   "*
1751   int count = INTVAL (operands[2]);
1753   /* First extend operand 1 to PSImode.  */
1754   if (which_alternative == 0)
1755     output_asm_insn (\"extxu %0\", operands);
1756   else
1757     output_asm_insn (\"mov %1,%0\;extxu %0\", operands);
1759   /* Now do the shifting.  */
1760   while (count)
1761     {
1762       output_asm_insn (\"add %0,%0\", operands);
1763       count--;
1764     }
1765   return \"\";
1767   [(set_attr "cc" "clobber")])
1769 (define_insn ""
1770   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1771         (truncate:PSI
1772           (ashift:SI
1773             (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))
1774             (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1775   ""
1776   "*
1778   int count = INTVAL (operands[2]);
1780   /* First extend operand 1 to PSImode.  */
1781   if (which_alternative == 0)
1782     output_asm_insn (\"extx %0\", operands);
1783   else if (which_alternative == 1)
1784     output_asm_insn (\"mov %1,%0\;extx %0\", operands);
1785   else
1786     output_asm_insn (\"mov %1,%0\", operands);
1788   /* Now do the shifting.  */
1789   while (count)
1790     {
1791       output_asm_insn (\"add %0,%0\", operands);
1792       count--;
1793     }
1794   return \"\";
1796   [(set_attr "cc" "clobber")])
1798 (define_insn ""
1799   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1800         (truncate:PSI
1801           (ashift:SI
1802             (sign_extend:SI
1803               (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))
1804             (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1805   ""
1806   "*
1808   int count = INTVAL (operands[2]);
1810   /* First extend operand 1 to PSImode.  */
1811   if (which_alternative == 0)
1812     output_asm_insn (\"extxbu %0\", operands);
1813   else if (which_alternative == 1)
1814     output_asm_insn (\"mov %1,%0\;extxbu %0\", operands);
1815   else
1816     output_asm_insn (\"movbu %1,%0\", operands);
1818   /* Now do the shifting.  */
1819   while (count)
1820     {
1821       output_asm_insn (\"add %0,%0\", operands);
1822       count--;
1823     }
1824   return \"\";
1826   [(set_attr "cc" "clobber")])
1828 (define_insn ""
1829   [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1830         (truncate:PSI
1831           (ashift:SI
1832             (sign_extend:SI
1833               (match_operand:QI 1 "general_operand" "0,di,m"))
1834             (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1835   ""
1836   "*
1838   int count = INTVAL (operands[2]);
1840   /* First extend operand 1 to PSImode.  */
1841   if (which_alternative == 0)
1842     output_asm_insn (\"extxb %0\", operands);
1843   else if (which_alternative == 1)
1844     output_asm_insn (\"mov %1,%0\;extxb %0\", operands);
1845   else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1846     output_asm_insn (\"movbu %1,%0\;extxb %0\", operands);
1847   else
1848     output_asm_insn (\"movb %1,%0\", operands);
1850   /* Now do the shifting.  */
1851   while (count)
1852     {
1853       output_asm_insn (\"add %0,%0\", operands);
1854       count--;
1855     }
1856   return \"\";
1858   [(set_attr "cc" "clobber")])
1860 ;; Try to combine consecutive updates of the stack pointer (or any
1861 ;; other register for that matter).
1862 (define_peephole
1863   [(set (match_operand:PSI 0 "register_operand" "=da")
1864         (plus:PSI (match_dup 0)
1865                   (match_operand 1 "const_int_operand" "")))
1866    (set (match_dup 0)
1867         (plus:PSI (match_dup 0)
1868                   (match_operand 2 "const_int_operand" "")))]
1869   ""
1870   "*
1872   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1873   return \"add %1,%0\";
1875   [(set_attr "cc" "clobber")])
1878 ;; We had patterns to check eq/ne, but the they don't work because
1879 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1881 ;; The Z flag and C flag would be set, and we have no way to
1882 ;; check for the Z flag set and C flag clear.
1884 ;; This will work on the mn10200 because we can check the ZX flag
1885 ;; if the comparison is in HImode.
1886 (define_peephole
1887   [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1888    (set (pc) (if_then_else (ge (cc0) (const_int 0))
1889                            (match_operand 1 "" "")
1890                            (pc)))]
1891   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1892   "add %0,%0\;bcc %1"
1893   [(set_attr "cc" "clobber")])
1895 (define_peephole
1896   [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1897    (set (pc) (if_then_else (lt (cc0) (const_int 0))
1898                            (match_operand 1 "" "")
1899                            (pc)))]
1900   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1901   "add %0,%0\;bcs %1"
1902   [(set_attr "cc" "clobber")])
1904 (define_peephole
1905   [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1906    (set (pc) (if_then_else (ge (cc0) (const_int 0))
1907                            (pc)
1908                            (match_operand 1 "" "")))]
1909   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1910   "add %0,%0\;bcs %1"
1911   [(set_attr "cc" "clobber")])
1913 (define_peephole
1914   [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1915    (set (pc) (if_then_else (lt (cc0) (const_int 0))
1916                            (pc)
1917                            (match_operand 1 "" "")))]
1918   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1919   "add %0,%0\;bcc %1"
1920   [(set_attr "cc" "clobber")])
1922 (define_peephole
1923   [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1924    (set (pc) (if_then_else (ge (cc0) (const_int 0))
1925                            (match_operand 1 "" "")
1926                            (pc)))]
1927   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1928   "add %0,%0\;bccx %1"
1929   [(set_attr "cc" "clobber")])
1931 (define_peephole
1932   [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1933    (set (pc) (if_then_else (lt (cc0) (const_int 0))
1934                            (match_operand 1 "" "")
1935                            (pc)))]
1936   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1937   "add %0,%0\;bcsx %1"
1938   [(set_attr "cc" "clobber")])
1940 (define_peephole
1941   [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1942    (set (pc) (if_then_else (ge (cc0) (const_int 0))
1943                            (pc)
1944                            (match_operand 1 "" "")))]
1945   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1946   "add %0,%0\;bcsx %1"
1947   [(set_attr "cc" "clobber")])
1949 (define_peephole
1950   [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1951    (set (pc) (if_then_else (lt (cc0) (const_int 0))
1952                            (pc)
1953                            (match_operand 1 "" "")))]
1954   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1955   "add %0,%0\;bccx %1"
1956   [(set_attr "cc" "clobber")])
1958 ;; We call out to library routines to perform 32bit addition and subtraction
1959 ;; operations (see addsi3/subsi3 expanders for why).  These peepholes catch
1960 ;; the trivial case where the operation could be done with an add;addc or
1961 ;; sub;subc sequence.
1962 (define_peephole
1963   [(set (mem:SI (reg:PSI 7)) (reg:SI 2))
1964    (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")
1965                          (match_operand:HI 2 "general_operand" "")))]
1966   "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1967    && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__addsi3\") == 0"
1968   "add d2,d0\;addc d3,d1"
1969   [(set_attr "cc" "clobber")])
1971 (define_peephole
1972   [(set (mem:SI (reg:PSI 7)) (reg:SI 2))
1973    (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")
1974                          (match_operand:HI 2 "general_operand" "")))]
1975   "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1976    && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__subsi3\") == 0"
1977   "sub d2,d0\;subc d3,d1"
1978   [(set_attr "cc" "clobber")])