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
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 = 0;
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
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
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
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
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
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
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
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")])
2051