OSDN Git Service

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