OSDN Git Service

2006-01-22 Paul Brook <paul@codesourcery.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / m68k.md
1 ;;- Machine description for GNU compiler, Motorola 68000 Version
2 ;;  Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001,
3 ;;  2002, 2003, 2004, 2005, 2006
4 ;;  Free Software Foundation, Inc.
5
6 ;; This file is part of GCC.
7
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 ;; Boston, MA 02110-1301, USA.
22
23 ;;- Information about MCF5200 port.
24
25 ;;- The MCF5200 "ColdFire" architecture is a reduced version of the
26 ;;- 68k ISA.  Differences include reduced support for byte and word
27 ;;- operands and the removal of BCD, bitfield, rotate, and integer
28 ;;- divide instructions.  The TARGET_COLDFIRE flag turns the use of the
29 ;;- removed opcodes and addressing modes off.
30 ;;- 
31
32
33 ;;- instruction definitions
34
35 ;;- @@The original PO technology requires these to be ordered by speed,
36 ;;- @@    so that assigner will pick the fastest.
37
38 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
39
40 ;;- When naming insn's (operand 0 of define_insn) be careful about using
41 ;;- names from other targets machine descriptions.
42
43 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
44 ;;- updates for most instructions.
45
46 ;;- Operand classes for the register allocator:
47 ;;- 'a' one of the address registers can be used.
48 ;;- 'd' one of the data registers can be used.
49 ;;- 'f' one of the m68881/fpu registers can be used
50 ;;- 'r' either a data or an address register can be used.
51
52 ;;- Immediate Floating point operator constraints
53 ;;- 'G' a floating point constant that is *NOT* one of the standard
54 ;;   68881 constant values (to force calling output_move_const_double
55 ;;   to get it from rom if it is a 68881 constant).
56 ;;
57 ;;   See the functions standard_XXX_constant_p in output-m68k.c for more
58 ;; info.
59
60 ;;- Immediate integer operand constraints:
61 ;;- 'I'  1 .. 8
62 ;;- 'J'  -32768 .. 32767
63 ;;- 'K'  all integers EXCEPT -128 .. 127
64 ;;- 'L'  -8 .. -1
65 ;;- 'M'  all integers EXCEPT -256 .. 255
66 ;;- 'N'  24 .. 31
67 ;;- 'O'  16
68 ;;- 'P'  8 .. 15
69
70 ;;- Assembler specs:
71 ;;- "%."    size separator ("." or "")                  move%.l d0,d1
72 ;;- "%-"    push operand "sp@-"                         move%.l d0,%-
73 ;;- "%+"    pop operand "sp@+"                          move%.l d0,%+
74 ;;- "%@"    top of stack "sp@"                          move%.l d0,%@
75 ;;- "%!"    fpcr register
76 ;;- "%$"    single-precision fp specifier ("s" or "")   f%$add.x fp0,fp1
77 ;;- "%&"    double-precision fp specifier ("d" or "")   f%&add.x fp0,fp1
78
79 ;;- Information about 68040 port.
80
81 ;;- The 68040 executes all 68030 and 68881/2 instructions, but some must
82 ;;- be emulated in software by the OS.  It is faster to avoid these
83 ;;- instructions and issue a library call rather than trapping into
84 ;;- the kernel.  The affected instructions are fintrz and fscale.  The
85 ;;- TARGET_68040 flag turns the use of the opcodes off.
86
87 ;;- The '040 also implements a set of new floating-point instructions
88 ;;- which specify the rounding precision in the opcode.  This finally
89 ;;- permit the 68k series to be truly IEEE compliant, and solves all
90 ;;- issues of excess precision accumulating in the extended registers.
91 ;;- By default, GCC does not use these instructions, since such code will
92 ;;- not run on an '030.  To use these instructions, use the -m68040-only
93 ;;- switch.  By changing TARGET_DEFAULT to include TARGET_68040_ONLY,
94 ;;- you can make these instructions the default.
95
96 ;;- These new instructions aren't directly in the md.  They are brought
97 ;;- into play by defining "%$" and "%&" to expand to "s" and "d" rather
98 ;;- than "".
99
100 ;;- Information about 68060 port.
101
102 ;;- The 68060 executes all 68030 and 68881/2 instructions, but some must
103 ;;- be emulated in software by the OS.  It is faster to avoid these
104 ;;- instructions and issue a library call rather than trapping into
105 ;;- the kernel.  The affected instructions are: divs.l <ea>,Dr:Dq;
106 ;;- divu.l <ea>,Dr:Dq; muls.l <ea>,Dr:Dq; mulu.l <ea>,Dr:Dq; and
107 ;;- fscale.  The TARGET_68060 flag turns the use of the opcodes off.
108
109 ;;- Some of these insn's are composites of several m68000 op codes.
110 ;;- The assembler (or final @@??) insures that the appropriate one is
111 ;;- selected.
112
113 ;; UNSPEC usage:
114
115 (define_constants
116   [(UNSPEC_SIN  1)
117    (UNSPEC_COS  2)
118   ])
119
120 ;; UNSPEC_VOLATILE usage:
121
122 (define_constants
123   [(UNSPECV_BLOCKAGE    0)
124   ])
125
126 ;; Registers by name.
127 (define_constants
128   [(A0_REG              8)
129    (SP_REG              15)
130   ])
131
132 (include "predicates.md")
133 \f
134 ;; Mode macros for floating point operations.
135 ;; Valid floating point modes
136 (define_mode_macro FP [SF DF (XF "TARGET_68881")])
137 ;; Mnemonic infix to round result
138 (define_mode_attr round [(SF "%$") (DF "%&") (XF "")])
139 ;; Mnemonic infix to round result for mul or div instruction
140 (define_mode_attr round_mul [(SF "sgl") (DF "%&") (XF "")])
141 ;; Suffix specifiying source operand format
142 (define_mode_attr prec [(SF "s") (DF "d") (XF "x")])
143 ;; Allowable D registers
144 (define_mode_attr dreg [(SF "d") (DF "") (XF "")])
145 ;; Allowable 68881 constant constraints
146 (define_mode_attr const [(SF "F") (DF "G") (XF "")])
147 \f
148 (define_insn ""
149   [(set (match_operand:DF 0 "push_operand" "=m")
150         (match_operand:DF 1 "general_operand" "ro<>fyE"))]
151   ""
152 {
153   if (FP_REG_P (operands[1]))
154     return "fmove%.d %f1,%0";
155   return output_move_double (operands);
156 })
157
158 (define_insn "pushdi"
159   [(set (match_operand:DI 0 "push_operand" "=m")
160         (match_operand:DI 1 "general_operand" "ro<>Fyi"))]
161   ""
162 {
163   return output_move_double (operands);
164 })
165 \f
166 ;; We don't want to allow a constant operand for test insns because
167 ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
168 ;; be folded while optimizing anyway.
169
170 (define_expand "tstdi"
171   [(parallel [(set (cc0)
172                    (match_operand:DI 0 "nonimmediate_operand" ""))
173               (clobber (match_scratch:SI 1 ""))
174               (clobber (match_scratch:DI 2 ""))])]
175   ""
176   "m68k_last_compare_had_fp_operands = 0;")
177
178 (define_insn ""
179   [(set (cc0)
180         (match_operand:DI 0 "nonimmediate_operand" "am,d"))
181    (clobber (match_scratch:SI 1 "=X,d"))
182    (clobber (match_scratch:DI 2 "=d,X"))]
183   ""
184 {
185   if (which_alternative == 0)
186     {
187       rtx xoperands[2];
188
189       xoperands[0] = operands[2];
190       xoperands[1] = operands[0];
191       output_move_double (xoperands);
192       cc_status.flags |= CC_REVERSED;
193       return "neg%.l %R2\;negx%.l %2";
194     }
195   if (find_reg_note (insn, REG_DEAD, operands[0]))
196     {
197       cc_status.flags |= CC_REVERSED;
198       return "neg%.l %R0\;negx%.l %0";
199     }
200   else
201     /*
202        'sub' clears %1, and also clears the X cc bit
203        'tst' sets the Z cc bit according to the low part of the DImode operand
204        'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part.
205     */
206     return "sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0";
207 })
208
209 (define_expand "tstsi"
210   [(set (cc0)
211         (match_operand:SI 0 "nonimmediate_operand" ""))]
212   ""
213   "m68k_last_compare_had_fp_operands = 0;")
214
215 (define_insn ""
216   [(set (cc0)
217         (match_operand:SI 0 "nonimmediate_operand" "rm"))]
218   ""
219 {
220   if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0]))
221     return "tst%.l %0";
222   /* If you think that the 68020 does not support tstl a0,
223      reread page B-167 of the 68020 manual more carefully.  */
224   /* On an address reg, cmpw may replace cmpl.  */
225   return "cmp%.w #0,%0";
226 })
227
228 ;; This can't use an address register, because comparisons
229 ;; with address registers as second operand always test the whole word.
230 (define_expand "tsthi"
231   [(set (cc0)
232         (match_operand:HI 0 "nonimmediate_operand" ""))]
233   ""
234   "m68k_last_compare_had_fp_operands = 0;")
235
236 (define_insn ""
237   [(set (cc0)
238         (match_operand:HI 0 "nonimmediate_operand" "dm"))]
239   ""
240   "tst%.w %0")
241
242 (define_expand "tstqi"
243   [(set (cc0)
244         (match_operand:QI 0 "nonimmediate_operand" ""))]
245   ""
246   "m68k_last_compare_had_fp_operands = 0;")
247
248 (define_insn ""
249   [(set (cc0)
250         (match_operand:QI 0 "nonimmediate_operand" "dm"))]
251   ""
252   "tst%.b %0")
253
254 (define_expand "tst<mode>"
255   [(set (cc0)
256         (match_operand:FP 0 "general_operand" ""))]
257   "TARGET_HARD_FLOAT"
258 {
259   m68k_last_compare_had_fp_operands = 1;
260 })
261
262 (define_insn "tst<mode>_68881"
263   [(set (cc0)
264         (match_operand:FP 0 "general_operand" "f<FP:dreg>m"))]
265   "TARGET_68881"
266 {
267   cc_status.flags = CC_IN_68881;
268   if (FP_REG_P (operands[0]))
269     return "ftst%.x %0";
270   return "ftst%.<FP:prec> %0";
271 })
272
273 (define_insn "tst<mode>_cf"
274   [(set (cc0)
275         (match_operand:FP 0 "general_operand" "f<FP:dreg><Q>U"))]
276   "TARGET_COLDFIRE_FPU"
277 {
278   cc_status.flags = CC_IN_68881;
279   if (FP_REG_P (operands[0]))
280     return "ftst%.d %0";
281   return "ftst%.<FP:prec> %0";
282 })
283
284 \f
285 ;; compare instructions.
286
287 (define_expand "cmpdi"
288   [(parallel
289     [(set (cc0)
290           (compare (match_operand:DI 0 "nonimmediate_operand" "")
291                    (match_operand:DI 1 "general_operand" "")))
292      (clobber (match_dup 2))])]
293   ""
294   "m68k_last_compare_had_fp_operands = 0; operands[2] = gen_reg_rtx (DImode);")
295
296 (define_insn ""
297   [(set (cc0)
298         (compare (match_operand:DI 1 "nonimmediate_operand" "0,d")
299                  (match_operand:DI 2 "general_operand" "d,0")))
300    (clobber (match_operand:DI 0 "register_operand" "=d,d"))]
301   ""
302 {
303   if (rtx_equal_p (operands[0], operands[1]))
304     return "sub%.l %R2,%R0\;subx%.l %2,%0";
305   else
306     {
307       cc_status.flags |= CC_REVERSED;
308       return "sub%.l %R1,%R0\;subx%.l %1,%0";
309     }
310 })
311
312 ;; This is the second "hook" for PIC code (in addition to movsi). See
313 ;; comment of movsi for a description of PIC handling.
314 (define_expand "cmpsi"
315   [(set (cc0)
316         (compare (match_operand:SI 0 "nonimmediate_operand" "")
317                  (match_operand:SI 1 "general_operand" "")))]
318   ""
319 {
320   m68k_last_compare_had_fp_operands = 0;
321   if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
322     {
323       /* The source is an address which requires PIC relocation.
324          Call legitimize_pic_address with the source, mode, and a relocation
325          register (a new pseudo, or the final destination if reload_in_progress
326          is set).   Then fall through normally */
327       rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
328       operands[1] = legitimize_pic_address (operands[1], SImode, temp);
329     }
330 })
331
332 ;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
333 (define_insn ""
334   [(set (cc0)
335         (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mSr,mSa,>")
336                  (match_operand:SI 1 "general_src_operand" "mSr,mSa,KTr,Ksr,>")))]
337   "!TARGET_COLDFIRE"
338 {
339   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
340     return "cmpm%.l %1,%0";
341   if (REG_P (operands[1])
342       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
343     {
344       cc_status.flags |= CC_REVERSED;
345       return "cmp%.l %d0,%d1";
346     }
347   if (ADDRESS_REG_P (operands[0])
348       && GET_CODE (operands[1]) == CONST_INT
349       && INTVAL (operands[1]) < 0x8000
350       && INTVAL (operands[1]) >= -0x8000)
351     return "cmp%.w %1,%0";
352   return "cmp%.l %d1,%d0";
353 })
354
355 (define_insn ""
356   [(set (cc0)
357         (compare (match_operand:SI 0 "nonimmediate_operand" "mrKs,r")
358                  (match_operand:SI 1 "general_operand" "r,mrKs")))]
359   "TARGET_COLDFIRE"
360 {
361   if (REG_P (operands[1])
362       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
363     {
364       cc_status.flags |= CC_REVERSED;
365       return "cmp%.l %d0,%d1";
366     }
367   return "cmp%.l %d1,%d0";
368 })
369
370 (define_expand "cmphi"
371   [(set (cc0)
372         (compare (match_operand:HI 0 "nonimmediate_src_operand" "")
373                  (match_operand:HI 1 "general_src_operand" "")))]
374   "!TARGET_COLDFIRE"
375   "m68k_last_compare_had_fp_operands = 0;")
376
377 (define_insn ""
378   [(set (cc0)
379         (compare (match_operand:HI 0 "nonimmediate_src_operand" "rnmS,d,n,mS,>")
380                  (match_operand:HI 1 "general_src_operand" "d,rnmS,mS,n,>")))]
381   "!TARGET_COLDFIRE"
382 {
383   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
384     return "cmpm%.w %1,%0";
385   if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
386       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
387     {
388       cc_status.flags |= CC_REVERSED;
389       return "cmp%.w %d0,%d1";
390     }
391   return "cmp%.w %d1,%d0";
392 })
393
394 (define_expand "cmpqi"
395   [(set (cc0)
396         (compare (match_operand:QI 0 "nonimmediate_src_operand" "")
397                  (match_operand:QI 1 "general_src_operand" "")))]
398   "!TARGET_COLDFIRE"
399   "m68k_last_compare_had_fp_operands = 0;")
400
401 (define_insn ""
402   [(set (cc0)
403         (compare (match_operand:QI 0 "nonimmediate_src_operand" "dn,dmS,>")
404                  (match_operand:QI 1 "general_src_operand" "dmS,nd,>")))]
405   "!TARGET_COLDFIRE"
406 {
407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
408     return "cmpm%.b %1,%0";
409   if (REG_P (operands[1])
410       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
411     {
412       cc_status.flags |= CC_REVERSED;
413       return "cmp%.b %d0,%d1";
414     }
415   return "cmp%.b %d1,%d0";
416 })
417
418 (define_expand "cmp<mode>"
419   [(set (cc0)
420         (compare (match_operand:FP 0 "general_operand" "")
421                  (match_operand:FP 1 "general_operand" "")))]
422   "TARGET_HARD_FLOAT"
423 {
424   m68k_last_compare_had_fp_operands = 1;
425   if (TARGET_COLDFIRE && !reload_completed)
426     operands[1] = force_reg (<MODE>mode, operands[1]);
427 })
428
429 (define_insn "cmp<mode>_68881"
430   [(set (cc0)
431         (compare (match_operand:FP 0 "general_operand" "f,m<FP:const>")
432                  (match_operand:FP 1 "general_operand" "f<FP:dreg>m<FP:const>,f")))]
433   "TARGET_68881"
434 {
435   cc_status.flags = CC_IN_68881;
436   if (FP_REG_P (operands[0]))
437     {
438       if (FP_REG_P (operands[1]))
439         return "fcmp%.x %1,%0";
440       else
441         return "fcmp%.<FP:prec> %f1,%0";
442     }
443   cc_status.flags |= CC_REVERSED;
444   return "fcmp%.<FP:prec> %f0,%1";
445 })
446
447 (define_insn "cmp<mode>_cf"
448   [(set (cc0)
449         (compare (match_operand:FP 0 "general_operand" "f,<FP:dreg><Q>U")
450                  (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,f")))]
451   "TARGET_COLDFIRE_FPU"
452 {
453   cc_status.flags = CC_IN_68881;
454   if (FP_REG_P (operands[0]))
455     {
456       if (FP_REG_P (operands[1]))
457         return "fcmp%.d %1,%0";
458       else
459         return "fcmp%.<FP:prec> %f1,%0";
460     }
461   cc_status.flags |= CC_REVERSED;
462   return "fcmp%.<FP:prec> %f0,%1";
463 })
464 \f
465 ;; Recognizers for btst instructions.
466
467 ;; ColdFire/5200 only allows "<Q>" type addresses when the bit position is
468 ;; specified as a constant, so we must disable all patterns that may extract
469 ;; from a MEM at a constant bit position if we can't use this as a constraint.
470
471 (define_insn ""
472   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_src_operand" "oS")
473                             (const_int 1)
474                             (minus:SI (const_int 7)
475                                       (match_operand:SI 1 "general_operand" "di"))))]
476   "!TARGET_COLDFIRE"
477 {
478   return output_btst (operands, operands[1], operands[0], insn, 7);
479 })
480
481 ;; This is the same as the above pattern except for the constraints.  The 'i'
482 ;; has been deleted.
483
484 (define_insn ""
485   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
486                             (const_int 1)
487                             (minus:SI (const_int 7)
488                                       (match_operand:SI 1 "general_operand" "d"))))]
489   "TARGET_COLDFIRE"
490 {
491   return output_btst (operands, operands[1], operands[0], insn, 7);
492 })
493
494 (define_insn ""
495   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
496                             (const_int 1)
497                             (minus:SI (const_int 31)
498                                       (match_operand:SI 1 "general_operand" "di"))))]
499   ""
500 {
501   return output_btst (operands, operands[1], operands[0], insn, 31);
502 })
503
504 ;; The following two patterns are like the previous two
505 ;; except that they use the fact that bit-number operands
506 ;; are automatically masked to 3 or 5 bits.
507
508 (define_insn ""
509   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
510                             (const_int 1)
511                             (minus:SI (const_int 7)
512                                       (and:SI
513                                        (match_operand:SI 1 "register_operand" "d")
514                                        (const_int 7)))))]
515   ""
516 {
517   return output_btst (operands, operands[1], operands[0], insn, 7);
518 })
519
520 (define_insn ""
521   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
522                             (const_int 1)
523                             (minus:SI (const_int 31)
524                                       (and:SI
525                                        (match_operand:SI 1 "register_operand" "d")
526                                        (const_int 31)))))]
527   ""
528 {
529   return output_btst (operands, operands[1], operands[0], insn, 31);
530 })
531
532 ;; Nonoffsettable mem refs are ok in this one pattern
533 ;; since we don't try to adjust them.
534 (define_insn ""
535   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
536                             (const_int 1)
537                             (match_operand:SI 1 "const_int_operand" "n")))]
538   "(unsigned) INTVAL (operands[1]) < 8 && !TARGET_COLDFIRE"
539 {
540   operands[1] = GEN_INT (7 - INTVAL (operands[1]));
541   return output_btst (operands, operands[1], operands[0], insn, 7);
542 })
543
544 (define_insn ""
545   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "do")
546                             (const_int 1)
547                             (match_operand:SI 1 "const_int_operand" "n")))]
548   "!TARGET_COLDFIRE"
549 {
550   if (GET_CODE (operands[0]) == MEM)
551     {
552       operands[0] = adjust_address (operands[0], QImode,
553                                     INTVAL (operands[1]) / 8);
554       operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
555       return output_btst (operands, operands[1], operands[0], insn, 7);
556     }
557   operands[1] = GEN_INT (31 - INTVAL (operands[1]));
558   return output_btst (operands, operands[1], operands[0], insn, 31);
559 })
560
561 ;; This is the same as the above pattern except for the constraints.
562 ;; The 'o' has been replaced with 'Q'.
563
564 (define_insn ""
565   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "dQ")
566                             (const_int 1)
567                             (match_operand:SI 1 "const_int_operand" "n")))]
568   "TARGET_COLDFIRE"
569 {
570   if (GET_CODE (operands[0]) == MEM)
571     {
572       operands[0] = adjust_address (operands[0], QImode,
573                                     INTVAL (operands[1]) / 8);
574       operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
575       return output_btst (operands, operands[1], operands[0], insn, 7);
576     }
577   operands[1] = GEN_INT (31 - INTVAL (operands[1]));
578   return output_btst (operands, operands[1], operands[0], insn, 31);
579 })
580
581 \f
582 ;; move instructions
583
584 ;; A special case in which it is not desirable
585 ;; to reload the constant into a data register.
586 (define_insn "pushexthisi_const"
587   [(set (match_operand:SI 0 "push_operand" "=m")
588         (match_operand:SI 1 "const_int_operand" "J"))]
589   "INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000"
590 {
591   if (operands[1] == const0_rtx)
592     return "clr%.l %0";
593   if (valid_mov3q_const(operands[1]))
594     return "mov3q%.l %1,%-";
595   return "pea %a1";
596 })
597
598 ;This is never used.
599 ;(define_insn "swapsi"
600 ;  [(set (match_operand:SI 0 "nonimmediate_operand" "+r")
601 ;       (match_operand:SI 1 "general_operand" "+r"))
602 ;   (set (match_dup 1) (match_dup 0))]
603 ;  ""
604 ;  "exg %1,%0")
605
606 ;; Special case of fullword move when source is zero.
607 ;; The reason this is special is to avoid loading a zero
608 ;; into a data reg with moveq in order to store it elsewhere.
609
610 (define_insn "movsi_const0"
611   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
612         (const_int 0))]
613   ;; clr insns on 68000 read before writing.
614   ;; This isn't so on the 68010, but we have no TARGET_68010.
615   "((TARGET_68020 || TARGET_COLDFIRE)
616     || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))"
617 {
618   if (ADDRESS_REG_P (operands[0]))
619     {
620       /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
621       if (!TARGET_68040 && !TARGET_68060)
622         return "sub%.l %0,%0";
623       else
624         return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
625     }
626   /* moveq is faster on the 68000.  */
627   if (DATA_REG_P (operands[0]) && (!TARGET_68020 && !TARGET_COLDFIRE))
628     return "moveq #0,%0";
629   return "clr%.l %0";
630 })
631
632 ;; General case of fullword move.
633 ;;
634 ;; This is the main "hook" for PIC code.  When generating
635 ;; PIC, movsi is responsible for determining when the source address
636 ;; needs PIC relocation and appropriately calling legitimize_pic_address
637 ;; to perform the actual relocation.
638 ;;
639 ;; In both the PIC and non-PIC cases the patterns generated will
640 ;; matched by the next define_insn.
641 (define_expand "movsi"
642   [(set (match_operand:SI 0 "nonimmediate_operand" "")
643         (match_operand:SI 1 "general_operand" ""))]
644   ""
645 {
646   if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
647     {
648       /* The source is an address which requires PIC relocation.
649          Call legitimize_pic_address with the source, mode, and a relocation
650          register (a new pseudo, or the final destination if reload_in_progress
651          is set).   Then fall through normally */
652       rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
653       operands[1] = legitimize_pic_address (operands[1], SImode, temp);
654     }
655   else if (flag_pic && TARGET_PCREL && ! reload_in_progress)
656     {
657       /* Don't allow writes to memory except via a register;
658          the m68k doesn't consider PC-relative addresses to be writable.  */
659       if (symbolic_operand (operands[0], SImode))
660         operands[0] = force_reg (SImode, XEXP (operands[0], 0));
661       else if (GET_CODE (operands[0]) == MEM
662                && symbolic_operand (XEXP (operands[0], 0), SImode))
663         operands[0] = gen_rtx_MEM (SImode,
664                                force_reg (SImode, XEXP (operands[0], 0)));
665     }
666 })
667
668 ;; General case of fullword move.  The register constraints
669 ;; force integer constants in range for a moveq to be reloaded
670 ;; if they are headed for memory.
671 (define_insn ""
672   ;; Notes: make sure no alternative allows g vs g.
673   ;; We don't allow f-regs since fixed point cannot go in them.
674   [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
675         (match_operand:SI 1 "general_src_operand" "daymSKT,n,i"))]
676
677   "!TARGET_COLDFIRE"
678 {
679   return output_move_simode (operands);
680 })
681
682 (define_insn "*movsi_cf"
683   [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U")
684         (match_operand:SI 1 "general_operand" "g,r<Q>,U"))]
685   "TARGET_COLDFIRE && !TARGET_CFV4"
686   "* return output_move_simode (operands);")
687
688 (define_insn "*movsi_cfv4"
689   [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U")
690         (match_operand:SI 1 "general_operand" "Rg,Rr<Q>,U"))]
691   "TARGET_CFV4"
692   "* return output_move_simode (operands);")
693
694 ;; Special case of fullword move, where we need to get a non-GOT PIC
695 ;; reference into an address register.
696 (define_insn ""
697   [(set (match_operand:SI 0 "nonimmediate_operand" "=a<")
698         (match_operand:SI 1 "pcrel_address" ""))]
699   "TARGET_PCREL"
700 {
701   if (push_operand (operands[0], SImode))
702     return "pea %a1";
703   return "lea %a1,%0";
704 })
705
706 (define_expand "movhi"
707   [(set (match_operand:HI 0 "nonimmediate_operand" "")
708         (match_operand:HI 1 "general_operand" ""))]
709   ""
710   "")
711
712 (define_insn ""
713   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
714         (match_operand:HI 1 "general_src_operand" "gS"))]
715   "!TARGET_COLDFIRE"
716   "* return output_move_himode (operands);")
717
718 (define_insn ""
719   [(set (match_operand:HI 0 "nonimmediate_operand" "=r<Q>,g,U")
720         (match_operand:HI 1 "general_operand" "g,r<Q>,U"))]
721   "TARGET_COLDFIRE"
722   "* return output_move_himode (operands);")
723
724 (define_expand "movstricthi"
725   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
726         (match_operand:HI 1 "general_src_operand" ""))]
727   ""
728   "")
729
730 (define_insn ""
731   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
732         (match_operand:HI 1 "general_src_operand" "rmSn"))]
733   "!TARGET_COLDFIRE"
734   "* return output_move_stricthi (operands);")
735
736 (define_insn ""
737   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+d,m"))
738         (match_operand:HI 1 "general_src_operand" "rmn,r"))]
739   "TARGET_COLDFIRE"
740   "* return output_move_stricthi (operands);")
741
742 (define_expand "movqi"
743   [(set (match_operand:QI 0 "nonimmediate_operand" "")
744         (match_operand:QI 1 "general_src_operand" ""))]
745   ""
746   "")
747
748 (define_insn ""
749   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,*a,m")
750         (match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))]
751   "!TARGET_COLDFIRE"
752   "* return output_move_qimode (operands);")
753
754 (define_insn ""
755   [(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>,dm,U,d*a")
756         (match_operand:QI 1 "general_src_operand" "dmi,d<Q>,U,di*a"))]
757   "TARGET_COLDFIRE"
758   "* return output_move_qimode (operands);")
759
760 (define_expand "movstrictqi"
761   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
762         (match_operand:QI 1 "general_src_operand" ""))]
763   ""
764   "")
765
766 (define_insn ""
767   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
768         (match_operand:QI 1 "general_src_operand" "dmSn"))]
769   "!TARGET_COLDFIRE"
770   "* return output_move_strictqi (operands);")
771
772 (define_insn ""
773   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d,m"))
774         (match_operand:QI 1 "general_src_operand" "dmn,d"))]
775   "TARGET_COLDFIRE"
776   "* return output_move_strictqi (operands);")
777
778 (define_expand "pushqi1"
779   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))
780    (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int 1)))
781         (match_operand:QI 0 "general_operand" ""))]
782   "!TARGET_COLDFIRE"
783   "")
784
785 (define_expand "reload_insf"
786   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
787         (match_operand:SF 1 "general_operand" "mf"))
788    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
789   "TARGET_COLDFIRE_FPU"
790 {
791   if (emit_move_sequence (operands, SFmode, operands[2]))
792     DONE;
793
794   /* We don't want the clobber emitted, so handle this ourselves. */
795   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
796   DONE;
797 })
798
799 (define_expand "reload_outsf"
800   [(set (match_operand:SF 0 "general_operand" "")
801         (match_operand:SF 1 "register_operand" "f"))
802    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
803   "TARGET_COLDFIRE_FPU"
804 {
805   if (emit_move_sequence (operands, SFmode, operands[2]))
806     DONE;
807
808   /* We don't want the clobber emitted, so handle this ourselves. */
809   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
810   DONE;
811 })
812
813 (define_expand "movsf"
814   [(set (match_operand:SF 0 "nonimmediate_operand" "")
815         (match_operand:SF 1 "general_operand" ""))]
816   ""
817   "")
818
819 (define_insn ""
820   [(set (match_operand:SF 0 "nonimmediate_operand" "=rmf")
821         (match_operand:SF 1 "general_operand" "rmfF"))]
822   "!TARGET_COLDFIRE"
823 {
824   if (FP_REG_P (operands[0]))
825     {
826       if (FP_REG_P (operands[1]))
827         return "f%$move%.x %1,%0";
828       else if (ADDRESS_REG_P (operands[1]))
829         return "move%.l %1,%-\;f%$move%.s %+,%0";
830       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
831         return output_move_const_single (operands);
832       return "f%$move%.s %f1,%0";
833     }
834   if (FP_REG_P (operands[1]))
835     {
836       if (ADDRESS_REG_P (operands[0]))
837         return "fmove%.s %1,%-\;move%.l %+,%0";
838       return "fmove%.s %f1,%0";
839     }
840   if (operands[1] == CONST0_RTX (SFmode)
841       /* clr insns on 68000 read before writing.
842          This isn't so on the 68010, but we have no TARGET_68010.  */
843       && ((TARGET_68020 || TARGET_COLDFIRE)
844           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
845     {
846       if (ADDRESS_REG_P (operands[0]))
847         {
848           /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
849           if (!TARGET_68040 && !TARGET_68060)
850             return "sub%.l %0,%0";
851           else
852             return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
853         }
854       /* moveq is faster on the 68000.  */
855       if (DATA_REG_P (operands[0]) && !(TARGET_68020 || TARGET_COLDFIRE))
856         {
857           return "moveq #0,%0";
858         }
859       return "clr%.l %0";
860     }
861   return "move%.l %1,%0";
862 })
863
864 (define_insn "movsf_cf_soft"
865   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,g")
866         (match_operand:SF 1 "general_operand" "g,r"))]
867   "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
868 {
869   return "move%.l %1,%0";
870 })
871
872 (define_insn "movsf_cf_hard"
873   [(set (match_operand:SF 0 "nonimmediate_operand" "=r<Q>U, f,    f,mr,f,r<Q>,f
874 ,m")
875         (match_operand:SF 1 "general_operand"      " f,     r<Q>U,f,rm,F,F,   m
876 ,f"))]
877   "TARGET_COLDFIRE_FPU"
878 {
879   if (which_alternative == 4 || which_alternative == 5) {
880     rtx xoperands[2];
881     REAL_VALUE_TYPE r;
882     long l;
883     REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
884     REAL_VALUE_TO_TARGET_SINGLE (r, l);
885     xoperands[0] = operands[0];
886     xoperands[1] = GEN_INT (l);
887     if (which_alternative == 5) {
888       if (l == 0) {
889         if (ADDRESS_REG_P (xoperands[0]))
890           output_asm_insn ("sub%.l %0,%0", xoperands);
891         else
892           output_asm_insn ("clr%.l %0", xoperands);
893       } else
894         if (GET_CODE (operands[0]) == MEM
895             && symbolic_operand (XEXP (operands[0], 0), SImode))
896           output_asm_insn ("move%.l %1,%-;move%.l %+,%0", xoperands);
897         else
898           output_asm_insn ("move%.l %1,%0", xoperands);
899       return "";
900     }
901     if (l != 0)
902       output_asm_insn ("move%.l %1,%-;fsmove%.s %+,%0", xoperands);
903     else
904       output_asm_insn ("clr%.l %-;fsmove%.s %+,%0", xoperands);
905     return "";
906   }
907   if (FP_REG_P (operands[0]))
908     {
909       if (ADDRESS_REG_P (operands[1]))
910         return "move%.l %1,%-;f%$smove%.s %+,%0";
911       if (FP_REG_P (operands[1]))
912         return "f%$move%.d %1,%0";
913       if (GET_CODE (operands[1]) == CONST_DOUBLE)
914         return output_move_const_single (operands);
915       return "f%$move%.s %f1,%0";
916     }
917   if (FP_REG_P (operands[1]))
918     {
919       if (ADDRESS_REG_P (operands[0]))
920         return "fmove%.s %1,%-;move%.l %+,%0";
921       return "fmove%.s %f1,%0";
922     }
923   if (operands[1] == CONST0_RTX (SFmode))
924     {
925       if (ADDRESS_REG_P (operands[0]))
926         return "sub%.l %0,%0";
927       return "clr%.l %0";
928     }
929   return "move%.l %1,%0";
930 })
931
932 (define_expand "reload_indf"
933   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
934         (match_operand:DF 1 "general_operand" "mf"))
935    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
936   "TARGET_COLDFIRE_FPU"
937 {
938   if (emit_move_sequence (operands, DFmode, operands[2]))
939     DONE;
940
941   /* We don't want the clobber emitted, so handle this ourselves. */
942   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
943   DONE;
944 })
945
946 (define_expand "reload_outdf"
947   [(set (match_operand:DF 0 "general_operand" "")
948         (match_operand:DF 1 "register_operand" "f"))
949    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
950   "TARGET_COLDFIRE_FPU"
951 {
952   if (emit_move_sequence (operands, DFmode, operands[2]))
953     DONE;
954
955   /* We don't want the clobber emitted, so handle this ourselves. */
956   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
957   DONE;
958 })
959
960 (define_expand "movdf"
961   [(set (match_operand:DF 0 "nonimmediate_operand" "")
962         (match_operand:DF 1 "general_operand" ""))]
963   ""
964 {
965   if (TARGET_COLDFIRE_FPU)
966     if (emit_move_sequence (operands, DFmode, 0))
967       DONE;
968 })
969
970 (define_insn ""
971   [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,rf,rf,&rof<>")
972         (match_operand:DF 1 "general_operand" "*rf,m,0,*rofE<>"))]
973 ;  [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,&rf,&rof<>")
974 ;       (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
975   "!TARGET_COLDFIRE"
976 {
977   if (FP_REG_P (operands[0]))
978     {
979       if (FP_REG_P (operands[1]))
980         return "f%&move%.x %1,%0";
981       if (REG_P (operands[1]))
982         {
983           rtx xoperands[2];
984           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
985           output_asm_insn ("move%.l %1,%-", xoperands);
986           output_asm_insn ("move%.l %1,%-", operands);
987           return "f%&move%.d %+,%0";
988         }
989       if (GET_CODE (operands[1]) == CONST_DOUBLE)
990         return output_move_const_double (operands);
991       return "f%&move%.d %f1,%0";
992     }
993   else if (FP_REG_P (operands[1]))
994     {
995       if (REG_P (operands[0]))
996         {
997           output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
998           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
999           return "move%.l %+,%0";
1000         }
1001       else
1002         return "fmove%.d %f1,%0";
1003     }
1004   return output_move_double (operands);
1005 })
1006
1007 (define_insn "movdf_cf_soft"
1008   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,g")
1009         (match_operand:DF 1 "general_operand" "g,r"))]
1010   "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
1011 {
1012   return output_move_double (operands);
1013 })
1014
1015 (define_insn "movdf_cf_hard"
1016   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,    <Q>U,r,f,r,r,m,f")
1017         (match_operand:DF 1 "general_operand"      " f<Q>U,f,   f,r,r,m,r,E"))]
1018   "TARGET_COLDFIRE_FPU"
1019 {
1020   rtx xoperands[3];
1021   REAL_VALUE_TYPE r;
1022   long l[2];
1023
1024   switch (which_alternative)
1025     {
1026     default:
1027       return "fmove%.d %1,%0";
1028     case 2:
1029       return "fmove%.d %1,%-;move%.l %+,%0;move%.l %+,%R0";
1030     case 3:
1031       return "move%.l %R1,%-;move%.l %1,%-;f%&move%.d %+,%0";
1032     case 4:
1033       return "move%.l %1,%0;move%.l %R1,%R0";
1034     case 5: case 6:
1035       return output_move_double (operands);
1036     case 7:
1037       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1038       REAL_VALUE_TO_TARGET_DOUBLE (r, l);
1039       xoperands[0] = operands[0];
1040       xoperands[1] = GEN_INT (l[0]);
1041       xoperands[2] = GEN_INT (l[1]);
1042       if (operands[1] == CONST0_RTX (DFmode))
1043         output_asm_insn ("clr%.l %-;clr%.l %-;fdmove%.d %+,%0",
1044                         xoperands);
1045       else
1046         if (l[1] == 0)
1047           output_asm_insn ("clr%.l %-;move%.l %1,%-;fdmove%.d %+,%0",
1048                           xoperands);
1049         else
1050           output_asm_insn ("move%.l %2,%-;move%.l %1,%-;fdmove%.d %+,%0",
1051                           xoperands);
1052       return "";
1053     }
1054 })
1055
1056 ;; ??? The XFmode patterns are schizophrenic about whether constants are
1057 ;; allowed.  Most but not all have predicates and constraint that disallow
1058 ;; constants.  Most but not all have output templates that handle constants.
1059 ;; See also LEGITIMATE_CONSTANT_P.
1060
1061 (define_expand "movxf"
1062   [(set (match_operand:XF 0 "nonimmediate_operand" "")
1063         (match_operand:XF 1 "general_operand" ""))]
1064   ""
1065 {
1066   /* We can't rewrite operands during reload.  */
1067   if (! reload_in_progress)
1068     {
1069       if (CONSTANT_P (operands[1]))
1070         {
1071           operands[1] = force_const_mem (XFmode, operands[1]);
1072           if (! memory_address_p (XFmode, XEXP (operands[1], 0)))
1073             operands[1] = adjust_address (operands[1], XFmode, 0);
1074         }
1075       if (flag_pic && TARGET_PCREL)
1076         {
1077           /* Don't allow writes to memory except via a register; the
1078              m68k doesn't consider PC-relative addresses to be writable.  */
1079           if (GET_CODE (operands[0]) == MEM
1080               && symbolic_operand (XEXP (operands[0], 0), SImode))
1081             operands[0] = gen_rtx_MEM (XFmode,
1082                                    force_reg (SImode, XEXP (operands[0], 0)));
1083         }
1084     }
1085 })
1086
1087 (define_insn ""
1088   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f,!r")
1089         (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r,!r"))]
1090   "TARGET_68881"
1091 {
1092   if (FP_REG_P (operands[0]))
1093     {
1094       if (FP_REG_P (operands[1]))
1095         return "fmove%.x %1,%0";
1096       if (REG_P (operands[1]))
1097         {
1098           rtx xoperands[2];
1099           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1100           output_asm_insn ("move%.l %1,%-", xoperands);
1101           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1102           output_asm_insn ("move%.l %1,%-", xoperands);
1103           output_asm_insn ("move%.l %1,%-", operands);
1104           return "fmove%.x %+,%0";
1105         }
1106       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1107         return "fmove%.x %1,%0";
1108       return "fmove%.x %f1,%0";
1109     }
1110   if (FP_REG_P (operands[1]))
1111     {
1112       if (REG_P (operands[0]))
1113         {
1114           output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands);
1115           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1116           output_asm_insn ("move%.l %+,%0", operands);
1117           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1118           return "move%.l %+,%0";
1119         }
1120       /* Must be memory destination.  */
1121       return "fmove%.x %f1,%0";
1122     }
1123   return output_move_double (operands);
1124 })
1125
1126 (define_insn ""
1127   [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
1128         (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))]
1129   "! TARGET_68881 && ! TARGET_COLDFIRE"
1130 {
1131   if (FP_REG_P (operands[0]))
1132     {
1133       if (FP_REG_P (operands[1]))
1134         return "fmove%.x %1,%0";
1135       if (REG_P (operands[1]))
1136         {
1137           rtx xoperands[2];
1138           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1139           output_asm_insn ("move%.l %1,%-", xoperands);
1140           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1141           output_asm_insn ("move%.l %1,%-", xoperands);
1142           output_asm_insn ("move%.l %1,%-", operands);
1143           return "fmove%.x %+,%0";
1144         }
1145       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1146         return "fmove%.x %1,%0";
1147       return "fmove%.x %f1,%0";
1148     }
1149   if (FP_REG_P (operands[1]))
1150     {
1151       if (REG_P (operands[0]))
1152         {
1153           output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands);
1154           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1155           output_asm_insn ("move%.l %+,%0", operands);
1156           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1157           return "move%.l %+,%0";
1158         }
1159       else
1160         return "fmove%.x %f1,%0";
1161     }
1162   return output_move_double (operands);
1163 })
1164
1165 (define_insn ""
1166   [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g")
1167         (match_operand:XF 1 "nonimmediate_operand" "g,r"))]
1168   "! TARGET_68881 && TARGET_COLDFIRE"
1169   "* return output_move_double (operands);")
1170
1171 (define_expand "movdi"
1172   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1173   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1174         (match_operand:DI 1 "general_operand" ""))]
1175   ""
1176   "")
1177
1178 ;; movdi can apply to fp regs in some cases
1179 (define_insn ""
1180   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1181   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r,&ro<>")
1182         (match_operand:DI 1 "general_operand" "rF,m,roi<>F"))]
1183 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&r,&ro<>,!&rm,!&f")
1184 ;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF"))]
1185 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&rf,&ro<>,!&rm,!&f")
1186 ;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
1187   "!TARGET_COLDFIRE"
1188 {
1189   if (FP_REG_P (operands[0]))
1190     {
1191       if (FP_REG_P (operands[1]))
1192         return "fmove%.x %1,%0";
1193       if (REG_P (operands[1]))
1194         {
1195           rtx xoperands[2];
1196           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1197           output_asm_insn ("move%.l %1,%-", xoperands);
1198           output_asm_insn ("move%.l %1,%-", operands);
1199           return "fmove%.d %+,%0";
1200         }
1201       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1202         return output_move_const_double (operands);
1203       return "fmove%.d %f1,%0";
1204     }
1205   else if (FP_REG_P (operands[1]))
1206     {
1207       if (REG_P (operands[0]))
1208         {
1209           output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1210           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1211           return "move%.l %+,%0";
1212         }
1213       else
1214         return "fmove%.d %f1,%0";
1215     }
1216   return output_move_double (operands);
1217 })
1218
1219 (define_insn ""
1220   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,g")
1221         (match_operand:DI 1 "general_operand" "g,r"))]
1222   "TARGET_COLDFIRE"
1223   "* return output_move_double (operands);")
1224
1225 ;; Thus goes after the move instructions
1226 ;; because the move instructions are better (require no spilling)
1227 ;; when they can apply.  It goes before the add/sub insns
1228 ;; so we will prefer it to them.
1229
1230 (define_insn "pushasi"
1231   [(set (match_operand:SI 0 "push_operand" "=m")
1232         (match_operand:SI 1 "address_operand" "p"))]
1233   ""
1234   "pea %a1")
1235 \f
1236 ;; truncation instructions
1237 (define_insn "truncsiqi2"
1238   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
1239         (truncate:QI
1240          (match_operand:SI 1 "general_src_operand" "doJS,i")))]
1241   ""
1242 {
1243   if (GET_CODE (operands[0]) == REG)
1244     {
1245       /* Must clear condition codes, since the move.l bases them on
1246          the entire 32 bits, not just the desired 8 bits.  */
1247       CC_STATUS_INIT;
1248       return "move%.l %1,%0";
1249     }
1250   if (GET_CODE (operands[1]) == MEM)
1251     operands[1] = adjust_address (operands[1], QImode, 3);
1252   return "move%.b %1,%0";
1253 })
1254
1255 (define_insn "trunchiqi2"
1256   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
1257         (truncate:QI
1258          (match_operand:HI 1 "general_src_operand" "doJS,i")))]
1259   ""
1260 {
1261   if (GET_CODE (operands[0]) == REG
1262       && (GET_CODE (operands[1]) == MEM
1263           || GET_CODE (operands[1]) == CONST_INT))
1264     {
1265       /* Must clear condition codes, since the move.w bases them on
1266          the entire 16 bits, not just the desired 8 bits.  */
1267       CC_STATUS_INIT;
1268       return "move%.w %1,%0";
1269     }
1270   if (GET_CODE (operands[0]) == REG)
1271     {
1272       /* Must clear condition codes, since the move.l bases them on
1273          the entire 32 bits, not just the desired 8 bits.  */
1274       CC_STATUS_INIT;
1275       return "move%.l %1,%0";
1276     }
1277   if (GET_CODE (operands[1]) == MEM)
1278     operands[1] = adjust_address (operands[1], QImode, 1);
1279   return "move%.b %1,%0";
1280 })
1281
1282 (define_insn "truncsihi2"
1283   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm,d")
1284         (truncate:HI
1285          (match_operand:SI 1 "general_src_operand" "roJS,i")))]
1286   ""
1287 {
1288   if (GET_CODE (operands[0]) == REG)
1289     {
1290       /* Must clear condition codes, since the move.l bases them on
1291          the entire 32 bits, not just the desired 8 bits.  */
1292       CC_STATUS_INIT;
1293       return "move%.l %1,%0";
1294     }
1295   if (GET_CODE (operands[1]) == MEM)
1296     operands[1] = adjust_address (operands[1], QImode, 2);
1297   return "move%.w %1,%0";
1298 })
1299 \f
1300 ;; zero extension instructions
1301
1302 ;; two special patterns to match various post_inc/pre_dec patterns
1303 (define_insn_and_split "*zero_extend_inc"
1304   [(set (match_operand 0 "post_inc_operand" "")
1305         (zero_extend (match_operand 1 "register_operand" "")))]
1306   "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT &&
1307    GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT &&
1308    GET_MODE_SIZE (GET_MODE (operands[0])) == GET_MODE_SIZE (GET_MODE (operands[1])) * 2"
1309   "#"
1310   ""
1311   [(set (match_dup 0)
1312         (const_int 0))
1313    (set (match_dup 0)
1314         (match_dup 1))]
1315 {
1316   operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0);
1317 })
1318
1319 (define_insn_and_split "*zero_extend_dec"
1320   [(set (match_operand 0 "pre_dec_operand" "")
1321         (zero_extend (match_operand 1 "register_operand" "")))]
1322   "(GET_MODE (operands[0]) != HImode || XEXP (XEXP (operands[0], 0), 0) != stack_pointer_rtx) &&
1323    GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT &&
1324    GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT &&
1325    GET_MODE_SIZE (GET_MODE (operands[0])) == GET_MODE_SIZE (GET_MODE (operands[1])) * 2"
1326   "#"
1327   ""
1328   [(set (match_dup 0)
1329         (match_dup 1))
1330    (set (match_dup 0)
1331         (const_int 0))]
1332 {
1333   operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0);
1334 })
1335
1336 (define_insn_and_split "zero_extendqidi2"
1337   [(set (match_operand:DI 0 "register_operand" "")
1338         (zero_extend:DI (match_operand:QI 1 "nonimmediate_src_operand" "")))]
1339   ""
1340   "#"
1341   ""
1342   [(set (match_dup 2)
1343         (zero_extend:SI (match_dup 1)))
1344    (set (match_dup 3)
1345         (const_int 0))]
1346 {
1347   operands[2] = gen_lowpart (SImode, operands[0]);
1348   operands[3] = gen_highpart (SImode, operands[0]);
1349 })
1350
1351 (define_insn_and_split "zero_extendhidi2"
1352   [(set (match_operand:DI 0 "register_operand" "")
1353         (zero_extend:DI (match_operand:HI 1 "nonimmediate_src_operand" "")))]
1354   ""
1355   "#"
1356   ""
1357   [(set (match_dup 2)
1358         (zero_extend:SI (match_dup 1)))
1359    (set (match_dup 3)
1360         (const_int 0))]
1361 {
1362   operands[2] = gen_lowpart (SImode, operands[0]);
1363   operands[3] = gen_highpart (SImode, operands[0]);
1364 })
1365
1366 (define_expand "zero_extendsidi2"
1367   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1368         (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))]
1369   ""
1370 {
1371   if (GET_CODE (operands[0]) == MEM
1372       && GET_CODE (operands[1]) == MEM)
1373     operands[1] = force_reg (SImode, operands[1]);
1374 })
1375
1376 (define_insn_and_split "*zero_extendsidi2"
1377   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1378         (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))]
1379   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1380   "#"
1381   ""
1382   [(set (match_dup 2)
1383         (match_dup 1))
1384    (set (match_dup 3)
1385         (const_int 0))]
1386 {
1387   operands[2] = gen_lowpart (SImode, operands[0]);
1388   operands[3] = gen_highpart (SImode, operands[0]);
1389 })
1390
1391 (define_insn "*zero_extendhisi2_cf"
1392   [(set (match_operand:SI 0 "register_operand" "=d")
1393         (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
1394   "TARGET_CFV4"
1395   "mvz%.w %1,%0")
1396
1397 (define_insn "zero_extendhisi2"
1398   [(set (match_operand:SI 0 "register_operand" "=d")
1399         (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
1400   ""
1401   "#")
1402
1403 (define_expand "zero_extendqihi2"
1404   [(set (match_operand:HI 0 "register_operand" "")
1405         (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "")))]
1406   "!TARGET_COLDFIRE"
1407   "")
1408
1409 (define_insn "*zero_extendqihi2"
1410   [(set (match_operand:HI 0 "register_operand" "=d")
1411         (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
1412   "!TARGET_COLDFIRE"
1413   "#")
1414
1415 (define_insn "*zero_extendqisi2_cfv4"
1416   [(set (match_operand:SI 0 "register_operand" "=d")
1417         (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
1418   "TARGET_CFV4"
1419   "mvz%.b %1,%0")
1420
1421 (define_insn "zero_extendqisi2"
1422   [(set (match_operand:SI 0 "register_operand" "=d")
1423         (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
1424   ""
1425   "#")
1426
1427 ;; these two pattern split everything else which isn't matched by
1428 ;; something else above
1429 (define_split
1430   [(set (match_operand 0 "register_operand" "")
1431         (zero_extend (match_operand 1 "nonimmediate_src_operand" "")))]
1432   "!TARGET_CFV4 && reload_completed && reg_mentioned_p (operands[0], operands[1])"
1433   [(set (strict_low_part (match_dup 2))
1434         (match_dup 1))
1435    (set (match_dup 0)
1436         (match_op_dup 4 [(match_dup 0) (match_dup 3)]))]
1437 {
1438   operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]);
1439   operands[3] = GEN_INT (GET_MODE_MASK (GET_MODE (operands[1])));
1440   operands[4] = gen_rtx_AND (GET_MODE (operands[0]), operands[0], operands[3]);
1441 })
1442
1443 (define_split
1444   [(set (match_operand 0 "register_operand" "")
1445         (zero_extend (match_operand 1 "nonimmediate_src_operand" "")))]
1446   "!TARGET_CFV4 && reload_completed"
1447   [(set (match_dup 0)
1448         (const_int 0))
1449    (set (strict_low_part (match_dup 2))
1450         (match_dup 1))]
1451 {
1452   operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]);
1453 })
1454 \f
1455 ;; sign extension instructions
1456
1457 (define_insn "extendqidi2"
1458   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1459         (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))]
1460   ""
1461 {
1462   CC_STATUS_INIT;
1463   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1464   if (TARGET_CFV4)
1465     return "mvs%.b %1,%2\;smi %0\;extb%.l %0";
1466   if (TARGET_68020 || TARGET_COLDFIRE)
1467     {
1468       if (ADDRESS_REG_P (operands[1]))
1469         return "move%.w %1,%2\;extb%.l %2\;smi %0\;extb%.l %0";
1470       else
1471         return "move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0";
1472     }
1473   else
1474     {
1475       if (ADDRESS_REG_P (operands[1]))
1476         return "move%.w %1,%2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\;smi %0";
1477       else
1478         return "move%.b %1,%2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\;smi %0";
1479     }
1480 })
1481
1482 (define_insn "extendhidi2"
1483   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1484         (sign_extend:DI
1485          (match_operand:HI 1 "general_src_operand" "rmS")))]
1486   ""
1487 {
1488   CC_STATUS_INIT;
1489   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1490   if (TARGET_CFV4)
1491     return "mvs%.w %1,%2\;smi %0\;extb%.l %0";
1492   if (TARGET_68020 || TARGET_COLDFIRE)
1493     return "move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0";
1494   else
1495     return "move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0";
1496 })
1497
1498 (define_insn "extendsidi2"
1499   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1500         (sign_extend:DI
1501          (match_operand:SI 1 "general_operand" "rm")))]
1502   ""
1503 {
1504   CC_STATUS_INIT;
1505   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1506   if (TARGET_68020 || TARGET_COLDFIRE)
1507     return "move%.l %1,%2\;smi %0\;extb%.l %0";
1508   else
1509     return "move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0";
1510 })
1511
1512 ;; Special case when one can avoid register clobbering, copy and test
1513 ;; Maybe there is a way to make that the general case, by forcing the
1514 ;; result of the SI tree to be in the lower register of the DI target
1515
1516 (define_insn "extendplussidi"
1517   [(set (match_operand:DI 0 "register_operand" "=d")
1518     (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
1519             (match_operand:SI 2 "general_operand" "rmn"))))]
1520   ""
1521 {
1522   CC_STATUS_INIT;
1523   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1524   if (GET_CODE (operands[1]) == CONST_INT
1525   && (unsigned) INTVAL (operands[1]) > 8)
1526     {
1527       rtx tmp = operands[1];
1528
1529       operands[1] = operands[2];
1530       operands[2] = tmp;
1531     }
1532   if (GET_CODE (operands[1]) == REG
1533       && REGNO (operands[1]) == REGNO (operands[3]))
1534     output_asm_insn ("add%.l %2,%3", operands);
1535   else
1536     output_asm_insn ("move%.l %2,%3\;add%.l %1,%3", operands);
1537   if (TARGET_68020 || TARGET_COLDFIRE)
1538     return "smi %0\;extb%.l %0";
1539   else
1540     return "smi %0\;ext%.w %0\;ext%.l %0";
1541 })
1542
1543 (define_expand "extendhisi2"
1544   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1545         (sign_extend:SI
1546          (match_operand:HI 1 "nonimmediate_src_operand" "")))]
1547   ""
1548   "")
1549
1550 (define_insn "*cfv4_extendhisi2"
1551   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
1552         (sign_extend:SI
1553          (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
1554   "TARGET_CFV4"
1555   "mvs%.w %1,%0")
1556
1557 (define_insn "*68k_extendhisi2"
1558   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
1559         (sign_extend:SI
1560          (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
1561   "!TARGET_CFV4"
1562 {
1563   if (ADDRESS_REG_P (operands[0]))
1564     return "move%.w %1,%0";
1565   return "ext%.l %0";
1566 })
1567
1568 (define_insn "extendqihi2"
1569   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
1570         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1571   ""
1572   "ext%.w %0")
1573
1574 (define_expand "extendqisi2"
1575   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1576         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1577   "TARGET_68020 || TARGET_COLDFIRE"
1578   "")
1579
1580 (define_insn "*cfv4_extendqisi2"
1581   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
1582         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))]
1583   "TARGET_CFV4"
1584   "mvs%.b %1,%0")
1585
1586 (define_insn "*68k_extendqisi2"
1587   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
1588         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1589   "TARGET_68020 || (TARGET_COLDFIRE && !TARGET_CFV4)"
1590   "extb%.l %0")
1591 \f
1592 ;; Conversions between float and double.
1593
1594 (define_expand "extendsfdf2"
1595   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1596         (float_extend:DF
1597          (match_operand:SF 1 "general_operand" "")))]
1598   "TARGET_HARD_FLOAT"
1599   "")
1600
1601 (define_insn ""
1602   [(set (match_operand:DF 0 "nonimmediate_operand" "=*fdm,f")
1603         (float_extend:DF
1604           (match_operand:SF 1 "general_operand" "f,dmF")))]
1605   "TARGET_68881"
1606 {
1607   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1608     {
1609       if (REGNO (operands[0]) == REGNO (operands[1]))
1610         {
1611           /* Extending float to double in an fp-reg is a no-op.
1612              NOTICE_UPDATE_CC has already assumed that the
1613              cc will be set.  So cancel what it did.  */
1614           cc_status = cc_prev_status;
1615           return "";
1616         }
1617       return "f%&move%.x %1,%0";
1618     }
1619   if (FP_REG_P (operands[0]))
1620     return "f%&move%.s %f1,%0";
1621   if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
1622     {
1623       output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1624       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1625       return "move%.l %+,%0";
1626     }
1627   return "fmove%.d %f1,%0";
1628 })
1629
1630 (define_insn "extendsfdf2_cf"
1631   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f")
1632         (float_extend:DF
1633          (match_operand:SF 1 "general_operand" "f,<Q>U")))]
1634   "TARGET_COLDFIRE_FPU"
1635 {
1636   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1637     {
1638       if (REGNO (operands[0]) == REGNO (operands[1]))
1639         {
1640           /* Extending float to double in an fp-reg is a no-op.
1641              NOTICE_UPDATE_CC has already assumed that the
1642              cc will be set.  So cancel what it did.  */
1643           cc_status = cc_prev_status;
1644           return "";
1645         }
1646       return "f%&move%.d %1,%0";
1647     }
1648   return "f%&move%.s %f1,%0";
1649 })
1650
1651 ;; This cannot output into an f-reg because there is no way to be
1652 ;; sure of truncating in that case.
1653 (define_expand "truncdfsf2"
1654   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1655         (float_truncate:SF
1656           (match_operand:DF 1 "general_operand" "")))]
1657   "TARGET_HARD_FLOAT"
1658   "")
1659
1660 ;; On the '040 we can truncate in a register accurately and easily.
1661 (define_insn ""
1662   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1663         (float_truncate:SF
1664           (match_operand:DF 1 "general_operand" "fmG")))]
1665   "TARGET_68881 && TARGET_68040_ONLY"
1666 {
1667   if (FP_REG_P (operands[1]))
1668     return "f%$move%.x %1,%0";
1669   return "f%$move%.d %f1,%0";
1670 })
1671
1672 (define_insn "truncdfsf2_cf"
1673   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,d<Q>U")
1674         (float_truncate:SF
1675           (match_operand:DF 1 "general_operand" "<Q>U,f")))]
1676   "TARGET_COLDFIRE_FPU"
1677   "@
1678   f%$move%.d %1,%0
1679   fmove%.s %1,%0")
1680
1681 (define_insn ""
1682   [(set (match_operand:SF 0 "nonimmediate_operand" "=dm")
1683         (float_truncate:SF
1684           (match_operand:DF 1 "general_operand" "f")))]
1685   "TARGET_68881"
1686   "fmove%.s %f1,%0")
1687 \f
1688 ;; Conversion between fixed point and floating point.
1689 ;; Note that among the fix-to-float insns
1690 ;; the ones that start with SImode come first.
1691 ;; That is so that an operand that is a CONST_INT
1692 ;; (and therefore lacks a specific machine mode).
1693 ;; will be recognized as SImode (which is always valid)
1694 ;; rather than as QImode or HImode.
1695
1696 (define_expand "floatsi<mode>2"
1697   [(set (match_operand:FP 0 "nonimmediate_operand" "")
1698         (float:FP (match_operand:SI 1 "general_operand" "")))]
1699   "TARGET_HARD_FLOAT"
1700   "")
1701
1702 (define_insn "floatsi<mode>2_68881"
1703   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
1704         (float:FP (match_operand:SI 1 "general_operand" "dmi")))]
1705   "TARGET_68881"
1706   "f<FP:round>move%.l %1,%0")
1707
1708 (define_insn "floatsi<mode>2_cf"
1709   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
1710         (float:FP (match_operand:SI 1 "general_operand" "d<Q>U")))]
1711   "TARGET_COLDFIRE_FPU"
1712   "f<FP:prec>move%.l %1,%0")
1713
1714
1715 (define_expand "floathi<mode>2"
1716   [(set (match_operand:FP 0 "nonimmediate_operand" "")
1717         (float:FP (match_operand:HI 1 "general_operand" "")))]
1718   "TARGET_HARD_FLOAT"
1719   "")
1720
1721 (define_insn "floathi<mode>2_68881"
1722   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
1723         (float:FP (match_operand:HI 1 "general_operand" "dmn")))]
1724   "TARGET_68881"
1725   "fmove%.w %1,%0")
1726
1727 (define_insn "floathi<mode>2_cf"
1728   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
1729         (float:FP (match_operand:HI 1 "general_operand" "d<Q>U")))]
1730   "TARGET_COLDFIRE_FPU"
1731   "fmove%.w %1,%0")
1732
1733
1734 (define_expand "floatqi<mode>2"
1735   [(set (match_operand:FP 0 "nonimmediate_operand" "")
1736         (float:FP (match_operand:QI 1 "general_operand" "")))]
1737   "TARGET_HARD_FLOAT"
1738   "")
1739
1740 (define_insn "floatqi<mode>2_68881"
1741   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
1742         (float:FP (match_operand:QI 1 "general_operand" "dmn")))]
1743   "TARGET_68881"
1744   "fmove%.b %1,%0")
1745
1746 (define_insn "floatqi<mode>2_cf"
1747   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
1748         (float:FP (match_operand:QI 1 "general_operand" "d<Q>U")))]
1749   "TARGET_COLDFIRE_FPU"
1750   "fmove%.b %1,%0")
1751
1752
1753 ;; New routines to convert floating-point values to integers
1754 ;; to be used on the '040.  These should be faster than trapping
1755 ;; into the kernel to emulate fintrz.  They should also be faster
1756 ;; than calling the subroutines fixsfsi or fixdfsi.
1757
1758 (define_insn "fix_truncdfsi2"
1759   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
1760         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1761    (clobber (match_scratch:SI 2 "=d"))
1762    (clobber (match_scratch:SI 3 "=d"))]
1763   "TARGET_68881 && TARGET_68040"
1764 {
1765   CC_STATUS_INIT;
1766   return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.l %1,%0\;fmovem%.l %2,%!";
1767 })
1768
1769 (define_insn "fix_truncdfhi2"
1770   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
1771         (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1772    (clobber (match_scratch:SI 2 "=d"))
1773    (clobber (match_scratch:SI 3 "=d"))]
1774   "TARGET_68881 && TARGET_68040"
1775 {
1776   CC_STATUS_INIT;
1777   return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.w %1,%0\;fmovem%.l %2,%!";
1778 })
1779
1780 (define_insn "fix_truncdfqi2"
1781   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
1782         (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1783    (clobber (match_scratch:SI 2 "=d"))
1784    (clobber (match_scratch:SI 3 "=d"))]
1785   "TARGET_68881 && TARGET_68040"
1786 {
1787   CC_STATUS_INIT;
1788   return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.b %1,%0\;fmovem%.l %2,%!";
1789 })
1790
1791 ;; Convert a float to a float whose value is an integer.
1792 ;; This is the first stage of converting it to an integer type.
1793
1794 (define_expand "ftrunc<mode>2"
1795   [(set (match_operand:FP 0 "nonimmediate_operand" "")
1796         (fix:FP (match_operand:FP 1 "general_operand" "")))]
1797   "TARGET_HARD_FLOAT && !TARGET_68040"
1798   "")
1799
1800 (define_insn "ftrunc<mode>2_68881"
1801   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
1802         (fix:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m")))]
1803   "TARGET_68881 && !TARGET_68040"
1804 {
1805   if (FP_REG_P (operands[1]))
1806     return "fintrz%.x %f1,%0";
1807   return "fintrz%.<FP:prec> %f1,%0";
1808 })
1809
1810 (define_insn "ftrunc<mode>2_cf"
1811   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
1812         (fix:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U")))]
1813   "TARGET_COLDFIRE_FPU"
1814 {
1815   if (FP_REG_P (operands[1]))
1816     return "fintrz%.d %f1,%0";
1817   return "fintrz%.<FP:prec> %f1,%0";
1818 })
1819
1820 ;; Convert a float whose value is an integer
1821 ;; to an actual integer.  Second stage of converting float to integer type.
1822 (define_expand "fix<mode>qi2"
1823   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1824         (fix:QI (match_operand:FP 1 "general_operand" "")))]
1825   "TARGET_HARD_FLOAT"
1826   "")
1827
1828 (define_insn "fix<mode>qi2_68881"
1829   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
1830         (fix:QI (match_operand:FP 1 "general_operand" "f")))]
1831   "TARGET_68881"
1832   "fmove%.b %1,%0")
1833
1834 (define_insn "fix<mode>qi2_cf"
1835   [(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>U")
1836         (fix:QI (match_operand:FP 1 "general_operand" "f")))]
1837   "TARGET_COLDFIRE_FPU"
1838   "fmove%.b %1,%0")
1839
1840 (define_expand "fix<mode>hi2"
1841   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1842         (fix:HI (match_operand:FP 1 "general_operand" "")))]
1843   "TARGET_HARD_FLOAT"
1844   "")
1845
1846 (define_insn "fix<mode>hi2_68881"
1847   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
1848         (fix:HI (match_operand:FP 1 "general_operand" "f")))]
1849   "TARGET_68881"
1850   "fmove%.w %1,%0")
1851
1852 (define_insn "fix<mode>hi2_cf"
1853   [(set (match_operand:HI 0 "nonimmediate_operand" "=d<Q>U")
1854         (fix:HI (match_operand:FP 1 "general_operand" "f")))]
1855   "TARGET_COLDFIRE_FPU"
1856   "fmove%.w %1,%0")
1857
1858 (define_expand "fix<mode>si2"
1859   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1860         (fix:SI (match_operand:FP 1 "general_operand" "")))]
1861   "TARGET_HARD_FLOAT"
1862   "")
1863
1864 (define_insn "fix<mode>si2_68881"
1865   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
1866         (fix:SI (match_operand:FP 1 "general_operand" "f")))]
1867   "TARGET_68881"
1868   "fmove%.l %1,%0")
1869
1870 (define_insn "fix<mode>si2_cf"
1871   [(set (match_operand:SI 0 "nonimmediate_operand" "=d<Q>U")
1872         (fix:SI (match_operand:FP 1 "general_operand" "f")))]
1873   "TARGET_COLDFIRE_FPU"
1874   "fmove%.l %1,%0")
1875
1876 \f
1877 ;; add instructions
1878
1879 (define_insn "adddi_lshrdi_63"
1880   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1881     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm")
1882             (const_int 63))
1883         (match_dup 1)))
1884    (clobber (match_scratch:SI 2 "=d"))]
1885   ""
1886 {
1887   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1888   if (REG_P (operands[1]) && REGNO (operands[1]) == REGNO (operands[0]))
1889     return
1890     "move%.l %1,%2\;add%.l %2,%2\;subx%.l %2,%2\;sub%.l %2,%3\;subx%.l %2,%0";
1891   if (GET_CODE (operands[1]) == REG)
1892     operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1893   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
1894         || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1895     operands[4] = operands[1];
1896   else
1897     operands[4] = adjust_address (operands[1], SImode, 4);
1898   if (GET_CODE (operands[1]) == MEM
1899    && GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1900     output_asm_insn ("move%.l %4,%3", operands);
1901   output_asm_insn ("move%.l %1,%0\;smi %2", operands);
1902   if (TARGET_68020 || TARGET_COLDFIRE)
1903     output_asm_insn ("extb%.l %2", operands);
1904   else
1905     output_asm_insn ("ext%.w %2\;ext%.l %2", operands);
1906   if (GET_CODE (operands[1]) != MEM
1907    || GET_CODE (XEXP (operands[1], 0)) != PRE_DEC)
1908     output_asm_insn ("move%.l %4,%3", operands);
1909   return "sub%.l %2,%3\;subx%.l %2,%0";
1910 })
1911
1912 (define_insn "adddi_sexthishl32"
1913   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
1914     (plus:DI (ashift:DI (sign_extend:DI
1915           (match_operand:HI 1 "general_operand" "rm,rm,rm,rm"))
1916             (const_int 32))
1917         (match_operand:DI 2 "general_operand" "0,0,0,0")))
1918    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
1919   "!TARGET_COLDFIRE"
1920 {
1921   CC_STATUS_INIT;
1922   if (ADDRESS_REG_P (operands[0]))
1923     return "add%.w %1,%0";
1924   else if (ADDRESS_REG_P (operands[3]))
1925     return "move%.w %1,%3\;add%.l %3,%0";
1926   else
1927     return "move%.w %1,%3\;ext%.l %3\;add%.l %3,%0";
1928 })
1929
1930 (define_insn "adddi_dilshr32"
1931   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o")
1932 ;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
1933 ;;      (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
1934 ;;            (const_int 32))))]
1935     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,d")
1936             (const_int 32))
1937         (match_operand:DI 2 "general_operand" "0,0")))]
1938   ""
1939 {
1940   CC_STATUS_INIT;
1941   if (GET_CODE (operands[0]) == REG)
1942     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1943   else
1944     operands[2] = adjust_address (operands[0], SImode, 4);
1945   return "add%.l %1,%2\;negx%.l %0\;neg%.l %0";
1946 })
1947
1948 (define_insn "adddi_dishl32"
1949   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
1950 ;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
1951 ;;      (ashift:DI (match_operand:DI 1 "general_operand" "ro")
1952 ;;            (const_int 32))))]
1953     (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro,d")
1954             (const_int 32))
1955         (match_operand:DI 2 "general_operand" "0,0")))]
1956   ""
1957 {
1958   CC_STATUS_INIT;
1959   if (GET_CODE (operands[1]) == REG)
1960     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1961   else
1962     operands[1] = adjust_address (operands[1], SImode, 4);
1963   return "add%.l %1,%0";
1964 })
1965
1966 (define_insn "adddi3"
1967   [(set (match_operand:DI 0 "nonimmediate_operand" "=<,o<>,d,d,d")
1968         (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0,0")
1969                  (match_operand:DI 2 "general_operand" "<,d,no>,d,a")))
1970    (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
1971   ""
1972 {
1973   if (DATA_REG_P (operands[0]))
1974     {
1975       if (DATA_REG_P (operands[2]))
1976         return "add%.l %R2,%R0\;addx%.l %2,%0";
1977       else if (GET_CODE (operands[2]) == MEM
1978           && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
1979         return "move%.l %2,%3\;add%.l %2,%R0\;addx%.l %3,%0";
1980       else
1981         {
1982           rtx high, low;
1983           rtx xoperands[2];
1984
1985           if (GET_CODE (operands[2]) == REG)
1986             {
1987               low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
1988               high = operands[2];
1989             }
1990           else if (CONSTANT_P (operands[2]))
1991             split_double (operands[2], &high, &low);
1992           else
1993             {
1994               low = adjust_address (operands[2], SImode, 4);
1995               high = operands[2];
1996             }
1997
1998           operands[1] = low, operands[2] = high;
1999           xoperands[0] = operands[3];
2000           if (GET_CODE (operands[1]) == CONST_INT
2001               && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2002             xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
2003           else
2004             xoperands[1] = operands[2];
2005
2006           output_asm_insn (output_move_simode (xoperands), xoperands);
2007           if (GET_CODE (operands[1]) == CONST_INT)
2008             {
2009               if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
2010                 return "addq%.l %1,%R0\;addx%.l %3,%0";
2011               else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2012                 {
2013                   operands[1] = GEN_INT (-INTVAL (operands[1]));
2014                   return "subq%.l %1,%R0\;subx%.l %3,%0";
2015                 }
2016             }
2017           return "add%.l %1,%R0\;addx%.l %3,%0";
2018         }
2019     }
2020   else
2021     {
2022       gcc_assert (GET_CODE (operands[0]) == MEM);
2023       if (GET_CODE (operands[2]) == MEM
2024           && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
2025         return "add%.l %2,%0\;addx%.l %2,%0";
2026       CC_STATUS_INIT;
2027       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2028         {
2029           operands[1] = gen_rtx_MEM (SImode,
2030                                      plus_constant (XEXP(operands[0], 0), -8));
2031           return "move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1";
2032         }
2033       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2034         {
2035           operands[1] = XEXP(operands[0], 0);
2036           return "add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1";
2037         }
2038       else
2039         {
2040           operands[1] = adjust_address (operands[0], SImode, 4);
2041           return "add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0";
2042         }
2043     }
2044 })
2045
2046 (define_insn "addsi_lshrsi_31"
2047   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
2048     (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm")
2049             (const_int 31))
2050         (match_dup 1)))]
2051   ""
2052 {
2053   operands[2] = operands[0];
2054   operands[3] = gen_label_rtx();
2055   if (GET_CODE (operands[0]) == MEM)
2056     {
2057       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2058         operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2059       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2060         operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2061     }
2062   output_asm_insn ("move%.l %1,%0", operands);
2063   output_asm_insn (MOTOROLA ? "jbpl %l3" : "jpl %l3", operands);
2064   output_asm_insn ("addq%.l #1,%2", operands);
2065   (*targetm.asm_out.internal_label) (asm_out_file, "L",
2066                                 CODE_LABEL_NUMBER (operands[3]));
2067   return "";
2068 })
2069
2070 (define_expand "addsi3"
2071   [(set (match_operand:SI 0 "nonimmediate_operand" "")
2072         (plus:SI (match_operand:SI 1 "general_operand" "")
2073                  (match_operand:SI 2 "general_src_operand" "")))]
2074   ""
2075   "")
2076
2077 ;; Note that the middle two alternatives are near-duplicates
2078 ;; in order to handle insns generated by reload.
2079 ;; This is needed since they are not themselves reloaded,
2080 ;; so commutativity won't apply to them.
2081 (define_insn "*addsi3_internal"
2082   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,d,a")
2083         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0")
2084                  (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))]
2085
2086
2087   "! TARGET_COLDFIRE"
2088   "* return output_addsi3 (operands);")
2089
2090 (define_insn "*addsi3_5200"
2091   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,r")
2092         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
2093                  (match_operand:SI 2 "general_src_operand" "dIL,rJK,a,mrIKLi")))]
2094   "TARGET_COLDFIRE"
2095   "* return output_addsi3 (operands);")
2096
2097 (define_insn ""
2098   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
2099         (plus:SI (match_operand:SI 1 "general_operand" "0")
2100                  (sign_extend:SI
2101                   (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2102   "!TARGET_COLDFIRE"
2103   "add%.w %2,%0")
2104
2105 (define_insn "addhi3"
2106   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
2107         (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
2108                  (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2109   "!TARGET_COLDFIRE"
2110 {
2111   if (GET_CODE (operands[2]) == CONST_INT)
2112     {
2113       /* If the constant would be a negative number when interpreted as
2114          HImode, make it negative.  This is usually, but not always, done
2115          elsewhere in the compiler.  First check for constants out of range,
2116          which could confuse us.  */
2117
2118       if (INTVAL (operands[2]) >= 32768)
2119         operands[2] = GEN_INT (INTVAL (operands[2]) - 65536);
2120
2121       if (INTVAL (operands[2]) > 0
2122           && INTVAL (operands[2]) <= 8)
2123         return "addq%.w %2,%0";
2124       if (INTVAL (operands[2]) < 0
2125           && INTVAL (operands[2]) >= -8)
2126         {
2127           operands[2] = GEN_INT (- INTVAL (operands[2]));
2128           return "subq%.w %2,%0";
2129         }
2130       /* On the CPU32 it is faster to use two addqw instructions to
2131          add a small integer (8 < N <= 16) to a register.  
2132          Likewise for subqw.  */
2133       if (TARGET_CPU32 && REG_P (operands[0]))
2134         {
2135           if (INTVAL (operands[2]) > 8
2136               && INTVAL (operands[2]) <= 16)
2137             {
2138               operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2139               return "addq%.w #8,%0\;addq%.w %2,%0";
2140             }
2141           if (INTVAL (operands[2]) < -8
2142               && INTVAL (operands[2]) >= -16)
2143             {
2144               operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2145               return "subq%.w #8,%0\;subq%.w %2,%0";
2146             }
2147         }
2148       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2149         return MOTOROLA ? "lea (%c2,%0),%0" : "lea %0@(%c2),%0";
2150     }
2151   return "add%.w %2,%0";
2152 })
2153
2154 ;; These insns must use MATCH_DUP instead of the more expected
2155 ;; use of a matching constraint because the "output" here is also
2156 ;; an input, so you can't use the matching constraint.  That also means
2157 ;; that you can't use the "%", so you need patterns with the matched
2158 ;; operand in both positions.
2159
2160 (define_insn ""
2161   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2162         (plus:HI (match_dup 0)
2163                  (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2164   "!TARGET_COLDFIRE"
2165 {
2166   if (GET_CODE (operands[1]) == CONST_INT)
2167     {
2168       /* If the constant would be a negative number when interpreted as
2169          HImode, make it negative.  This is usually, but not always, done
2170          elsewhere in the compiler.  First check for constants out of range,
2171          which could confuse us.  */
2172
2173       if (INTVAL (operands[1]) >= 32768)
2174         operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2175
2176       if (INTVAL (operands[1]) > 0
2177           && INTVAL (operands[1]) <= 8)
2178         return "addq%.w %1,%0";
2179       if (INTVAL (operands[1]) < 0
2180           && INTVAL (operands[1]) >= -8)
2181         {
2182           operands[1] = GEN_INT (- INTVAL (operands[1]));
2183           return "subq%.w %1,%0";
2184         }
2185       /* On the CPU32 it is faster to use two addqw instructions to
2186          add a small integer (8 < N <= 16) to a register. 
2187          Likewise for subqw.  */
2188       if (TARGET_CPU32 && REG_P (operands[0]))
2189         {
2190           if (INTVAL (operands[1]) > 8
2191               && INTVAL (operands[1]) <= 16)
2192             {
2193               operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2194               return "addq%.w #8,%0\;addq%.w %1,%0";
2195             }
2196           if (INTVAL (operands[1]) < -8
2197               && INTVAL (operands[1]) >= -16)
2198             {
2199               operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
2200               return "subq%.w #8,%0\;subq%.w %1,%0";
2201             }
2202         }
2203       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2204         return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0";
2205     }
2206   return "add%.w %1,%0";
2207 })
2208
2209 (define_insn ""
2210   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2211         (plus:HI (match_operand:HI 1 "general_src_operand" "dn,rmSn")
2212                  (match_dup 0)))]
2213   "!TARGET_COLDFIRE"
2214 {
2215   if (GET_CODE (operands[1]) == CONST_INT)
2216     {
2217       /* If the constant would be a negative number when interpreted as
2218          HImode, make it negative.  This is usually, but not always, done
2219          elsewhere in the compiler.  First check for constants out of range,
2220          which could confuse us.  */
2221
2222       if (INTVAL (operands[1]) >= 32768)
2223         operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2224
2225       if (INTVAL (operands[1]) > 0
2226           && INTVAL (operands[1]) <= 8)
2227         return "addq%.w %1,%0";
2228       if (INTVAL (operands[1]) < 0
2229           && INTVAL (operands[1]) >= -8)
2230         {
2231           operands[1] = GEN_INT (- INTVAL (operands[1]));
2232           return "subq%.w %1,%0";
2233         }
2234       /* On the CPU32 it is faster to use two addqw instructions to
2235          add a small integer (8 < N <= 16) to a register.
2236          Likewise for subqw.  */
2237       if (TARGET_CPU32 && REG_P (operands[0])) 
2238         {
2239           if (INTVAL (operands[1]) > 8
2240               && INTVAL (operands[1]) <= 16)
2241             {
2242               operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2243               return "addq%.w #8,%0\;addq%.w %1,%0";
2244             }
2245           if (INTVAL (operands[1]) < -8
2246               && INTVAL (operands[1]) >= -16)
2247             {
2248               operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
2249               return "subq%.w #8,%0\;subq%.w %1,%0";
2250             }
2251         }
2252       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2253         return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0";
2254     }
2255   return "add%.w %1,%0";
2256 })
2257
2258 (define_insn "addqi3"
2259   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
2260         (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
2261                  (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2262   "!TARGET_COLDFIRE"
2263 {
2264   if (GET_CODE (operands[2]) == CONST_INT)
2265     {
2266       if (INTVAL (operands[2]) >= 128)
2267         operands[2] = GEN_INT (INTVAL (operands[2]) - 256);
2268
2269       if (INTVAL (operands[2]) > 0
2270           && INTVAL (operands[2]) <= 8)
2271         return "addq%.b %2,%0";
2272       if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
2273        {
2274          operands[2] = GEN_INT (- INTVAL (operands[2]));
2275          return "subq%.b %2,%0";
2276        }
2277     }
2278   return "add%.b %2,%0";
2279 })
2280
2281 (define_insn ""
2282   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2283         (plus:QI (match_dup 0)
2284                  (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2285   "!TARGET_COLDFIRE"
2286 {
2287   if (GET_CODE (operands[1]) == CONST_INT)
2288     {
2289       if (INTVAL (operands[1]) >= 128)
2290         operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2291
2292       if (INTVAL (operands[1]) > 0
2293           && INTVAL (operands[1]) <= 8)
2294         return "addq%.b %1,%0";
2295       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2296        {
2297          operands[1] = GEN_INT (- INTVAL (operands[1]));
2298          return "subq%.b %1,%0";
2299        }
2300     }
2301   return "add%.b %1,%0";
2302 })
2303
2304 (define_insn ""
2305   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2306         (plus:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
2307                  (match_dup 0)))]
2308   "!TARGET_COLDFIRE"
2309 {
2310   if (GET_CODE (operands[1]) == CONST_INT)
2311     {
2312       if (INTVAL (operands[1]) >= 128)
2313         operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2314
2315       if (INTVAL (operands[1]) > 0
2316           && INTVAL (operands[1]) <= 8)
2317         return "addq%.b %1,%0";
2318       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2319        {
2320          operands[1] = GEN_INT (- INTVAL (operands[1]));
2321          return "subq%.b %1,%0";
2322        }
2323     }
2324   return "add%.b %1,%0";
2325 })
2326
2327 (define_expand "add<mode>3"
2328   [(set (match_operand:FP 0 "nonimmediate_operand" "")
2329         (plus:FP (match_operand:FP 1 "general_operand" "")
2330                  (match_operand:FP 2 "general_operand" "")))]
2331   "TARGET_HARD_FLOAT"
2332   "")
2333
2334 (define_insn "add<mode>3_floatsi_68881"
2335   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2336         (plus:FP (float:FP (match_operand:SI 2 "general_operand" "dmi"))
2337                  (match_operand:FP 1 "general_operand" "0")))]
2338   "TARGET_68881"
2339   "f<FP:round>add%.l %2,%0")
2340
2341 (define_insn "add<mode>3_floathi_68881"
2342   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2343         (plus:FP (float:FP (match_operand:HI 2 "general_operand" "dmn"))
2344                  (match_operand:FP 1 "general_operand" "0")))]
2345   "TARGET_68881"
2346   "f<FP:round>add%.w %2,%0")
2347
2348 (define_insn "add<mode>3_floatqi_68881"
2349   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2350         (plus:FP (float:FP (match_operand:QI 2 "general_operand" "dmn"))
2351                  (match_operand:FP 1 "general_operand" "0")))]
2352   "TARGET_68881"
2353   "f<FP:round>add%.b %2,%0")
2354
2355 (define_insn "add<mode>3_68881"
2356   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2357         (plus:FP (match_operand:FP 1 "general_operand" "%0")
2358                  (match_operand:FP 2 "general_operand" "f<FP:dreg>m<FP:const>")))]
2359   "TARGET_68881"
2360 {
2361   if (FP_REG_P (operands[2]))
2362     return "f<FP:round>add%.x %2,%0";
2363   return "f<FP:round>add%.<FP:prec> %f2,%0";
2364 })
2365
2366 (define_insn "add<mode>3_cf"
2367   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2368         (plus:FP (match_operand:FP 1 "general_operand" "%0")
2369                  (match_operand:FP 2 "general_operand" "f<FP:dreg><Q>U")))]
2370   "TARGET_COLDFIRE_FPU"
2371 {
2372   if (FP_REG_P (operands[2]))
2373     return "f<FP:round>add%.d %2,%0";
2374   return "f<FP:round>add%.<FP:prec> %2,%0";
2375 })
2376 \f
2377 ;; subtract instructions
2378
2379 (define_insn "subdi_sexthishl32"
2380   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
2381     (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
2382         (ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm"))
2383             (const_int 32))))
2384    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
2385   "!TARGET_COLDFIRE"
2386 {
2387   CC_STATUS_INIT;
2388   if (ADDRESS_REG_P (operands[0]))
2389     return "sub%.w %2,%0";
2390   else if (ADDRESS_REG_P (operands[3]))
2391     return "move%.w %2,%3\;sub%.l %3,%0";
2392   else
2393     return "move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0";
2394 })
2395
2396 (define_insn "subdi_dishl32"
2397   [(set (match_operand:DI 0 "nonimmediate_operand" "+ro")
2398     (minus:DI (match_dup 0)
2399         (ashift:DI (match_operand:DI 1 "general_operand" "ro")
2400             (const_int 32))))]
2401   ""
2402 {
2403   CC_STATUS_INIT;
2404   if (GET_CODE (operands[1]) == REG)
2405     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2406   else
2407     operands[1] = adjust_address (operands[1], SImode, 4);
2408   return "sub%.l %1,%0";
2409 })
2410
2411 (define_insn "subdi3"
2412   [(set (match_operand:DI 0 "nonimmediate_operand" "=<,o<>,d,d,d")
2413         (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0,0")
2414                  (match_operand:DI 2 "general_operand" "<,d,no>,d,a")))
2415    (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
2416   ""
2417 {
2418   if (DATA_REG_P (operands[0]))
2419     {
2420       if (DATA_REG_P (operands[2]))
2421         return "sub%.l %R2,%R0\;subx%.l %2,%0";
2422       else if (GET_CODE (operands[2]) == MEM
2423           && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
2424         {
2425           return "move%.l %2,%3\;sub%.l %2,%R0\;subx%.l %3,%0";
2426         }
2427       else
2428         {
2429           rtx high, low;
2430           rtx xoperands[2];
2431
2432           if (GET_CODE (operands[2]) == REG)
2433             {
2434               low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2435               high = operands[2];
2436             }
2437           else if (CONSTANT_P (operands[2]))
2438             split_double (operands[2], &high, &low);
2439           else
2440             {
2441               low = adjust_address (operands[2], SImode, 4);
2442               high = operands[2];
2443             }
2444
2445           operands[1] = low, operands[2] = high;
2446           xoperands[0] = operands[3];
2447           if (GET_CODE (operands[1]) == CONST_INT
2448               && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2449             xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
2450           else
2451             xoperands[1] = operands[2];
2452
2453           output_asm_insn (output_move_simode (xoperands), xoperands);
2454           if (GET_CODE (operands[1]) == CONST_INT)
2455             {
2456               if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
2457                 return "subq%.l %1,%R0\;subx%.l %3,%0";
2458               else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2459                 {
2460                   operands[1] = GEN_INT (-INTVAL (operands[1]));
2461                   return "addq%.l %1,%R0\;addx%.l %3,%0";
2462                 }
2463             }
2464           return "sub%.l %1,%R0\;subx%.l %3,%0";
2465         }
2466     }
2467   else
2468     {
2469       gcc_assert (GET_CODE (operands[0]) == MEM);
2470       if (GET_CODE (operands[2]) == MEM
2471           && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
2472         return "sub%.l %2,%0\;subx%.l %2,%0";
2473       CC_STATUS_INIT;
2474       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2475         {
2476           operands[1]
2477             = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[0], 0), -8));
2478           return "move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1";
2479         }
2480       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2481         {
2482           operands[1] = XEXP(operands[0], 0);
2483           return "sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1";
2484         }
2485       else
2486         {
2487           operands[1] = adjust_address (operands[0], SImode, 4);
2488           return "sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0";
2489         }
2490     }
2491 })
2492
2493 (define_insn "subsi3"
2494   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d,a")
2495         (minus:SI (match_operand:SI 1 "general_operand" "0,0,0")
2496                   (match_operand:SI 2 "general_src_operand" "dT,mSrT,mSrs")))]
2497   ""
2498   "sub%.l %2,%0")
2499
2500 (define_insn ""
2501   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
2502         (minus:SI (match_operand:SI 1 "general_operand" "0")
2503                   (sign_extend:SI
2504                    (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2505   "!TARGET_COLDFIRE"
2506   "sub%.w %2,%0")
2507
2508 (define_insn "subhi3"
2509   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
2510         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2511                   (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2512   "!TARGET_COLDFIRE"
2513   "sub%.w %2,%0")
2514
2515 (define_insn ""
2516   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2517         (minus:HI (match_dup 0)
2518                   (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2519   "!TARGET_COLDFIRE"
2520   "sub%.w %1,%0")
2521
2522 (define_insn "subqi3"
2523   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
2524         (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2525                   (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2526   "!TARGET_COLDFIRE"
2527   "sub%.b %2,%0")
2528
2529 (define_insn ""
2530   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2531         (minus:QI (match_dup 0)
2532                   (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2533   "!TARGET_COLDFIRE"
2534   "sub%.b %1,%0")
2535
2536 (define_expand "sub<mode>3"
2537   [(set (match_operand:FP 0 "nonimmediate_operand" "")
2538         (minus:FP (match_operand:FP 1 "general_operand" "")
2539                   (match_operand:FP 2 "general_operand" "")))]
2540   "TARGET_HARD_FLOAT"
2541   "")
2542
2543 (define_insn "sub<mode>3_floatsi_68881"
2544   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2545         (minus:FP (match_operand:FP 1 "general_operand" "0")
2546                   (float:FP (match_operand:SI 2 "general_operand" "dmi"))))]
2547   "TARGET_68881"
2548   "f<FP:round>sub%.l %2,%0")
2549
2550 (define_insn "sub<mode>3_floathi_68881"
2551   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2552         (minus:FP (match_operand:FP 1 "general_operand" "0")
2553                   (float:FP (match_operand:HI 2 "general_operand" "dmn"))))]
2554   "TARGET_68881"
2555   "f<FP:round>sub%.w %2,%0")
2556
2557 (define_insn "sub<mode>3_floatqi_68881"
2558   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2559         (minus:FP (match_operand:FP 1 "general_operand" "0")
2560                   (float:FP (match_operand:QI 2 "general_operand" "dmn"))))]
2561   "TARGET_68881"
2562   "f<FP:round>sub%.b %2,%0")
2563
2564 (define_insn "sub<mode>3_68881"
2565   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2566         (minus:FP (match_operand:FP 1 "general_operand" "0")
2567                   (match_operand:FP 2 "general_operand" "f<FP:dreg>m<FP:const>")))]
2568   "TARGET_68881"
2569 {
2570   if (FP_REG_P (operands[2]))
2571     return "f<FP:round>sub%.x %2,%0";
2572   return "f<FP:round>sub%.<FP:prec> %f2,%0";
2573 })
2574
2575 (define_insn "sub<mode>3_cf"
2576   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2577         (minus:FP (match_operand:FP 1 "general_operand" "0")
2578                   (match_operand:FP 2 "general_operand" "f<FP:dreg><Q>U")))]
2579   "TARGET_COLDFIRE_FPU"
2580 {
2581   if (FP_REG_P (operands[2]))
2582     return "f<FP:round>sub%.d %2,%0";
2583   return "f<FP:round>sub%.<FP:prec> %2,%0";
2584 })
2585 \f
2586 ;; multiply instructions
2587
2588 (define_insn "mulhi3"
2589   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
2590         (mult:HI (match_operand:HI 1 "general_operand" "%0")
2591                  (match_operand:HI 2 "general_src_operand" "dmSn")))]
2592   ""
2593 {
2594   return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
2595 })
2596
2597 (define_insn "mulhisi3"
2598   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2599         (mult:SI (sign_extend:SI
2600                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2601                  (sign_extend:SI
2602                   (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
2603   ""
2604 {
2605   return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
2606 })
2607
2608 (define_insn ""
2609   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2610         (mult:SI (sign_extend:SI
2611                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2612                  (match_operand:SI 2 "const_int_operand" "n")))]
2613   "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
2614 {
2615   return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
2616 })
2617
2618 (define_expand "mulsi3"
2619   [(set (match_operand:SI 0 "nonimmediate_operand" "")
2620         (mult:SI (match_operand:SI 1 "general_operand" "")
2621                  (match_operand:SI 2 "general_operand" "")))]
2622   "TARGET_68020 || TARGET_COLDFIRE"
2623   "")
2624
2625 (define_insn ""
2626   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2627         (mult:SI (match_operand:SI 1 "general_operand" "%0")
2628                  (match_operand:SI 2 "general_src_operand" "dmSTK")))]
2629
2630   "TARGET_68020"
2631   "muls%.l %2,%0")
2632
2633 (define_insn ""
2634   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2635         (mult:SI (match_operand:SI 1 "general_operand" "%0")
2636                  (match_operand:SI 2 "general_operand" "d<Q>")))]
2637   "TARGET_COLDFIRE"
2638   "muls%.l %2,%0")
2639
2640 (define_insn "umulhisi3"
2641   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2642         (mult:SI (zero_extend:SI
2643                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2644                  (zero_extend:SI
2645                   (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
2646   ""
2647 {
2648   return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
2649 })
2650
2651 (define_insn ""
2652   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2653         (mult:SI (zero_extend:SI
2654                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2655                  (match_operand:SI 2 "const_int_operand" "n")))]
2656   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
2657 {
2658   return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
2659 })
2660
2661 ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
2662 ;; proper matching constraint.  This is because the matching is between
2663 ;; the high-numbered word of the DImode operand[0] and operand[1].
2664 (define_expand "umulsidi3"
2665   [(parallel
2666     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
2667           (mult:SI (match_operand:SI 1 "register_operand" "")
2668                    (match_operand:SI 2 "register_operand" "")))
2669      (set (subreg:SI (match_dup 0) 0)
2670           (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2671                                              (zero_extend:DI (match_dup 2)))
2672                                     (const_int 32))))])]
2673   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2674   "")
2675
2676 (define_insn ""
2677   [(set (match_operand:SI 0 "register_operand" "=d")
2678         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2679                   (match_operand:SI 2 "nonimmediate_operand" "dm")))
2680    (set (match_operand:SI 3 "register_operand" "=d")
2681         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2682                                            (zero_extend:DI (match_dup 2)))
2683                                   (const_int 32))))]
2684   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2685   "mulu%.l %2,%3:%0")
2686
2687 ; Match immediate case.  For 2.4 only match things < 2^31.
2688 ; It's tricky with larger values in these patterns since we need to match
2689 ; values between the two parallel multiplies, between a CONST_DOUBLE and
2690 ; a CONST_INT.
2691 (define_insn ""
2692   [(set (match_operand:SI 0 "register_operand" "=d")
2693         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2694                  (match_operand:SI 2 "const_int_operand" "n")))
2695    (set (match_operand:SI 3 "register_operand" "=d")
2696         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2697                                            (match_dup 2))
2698                                   (const_int 32))))]
2699   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE
2700    && (unsigned) INTVAL (operands[2]) <= 0x7fffffff"
2701   "mulu%.l %2,%3:%0")
2702
2703 (define_expand "mulsidi3"
2704   [(parallel
2705     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
2706           (mult:SI (match_operand:SI 1 "register_operand" "")
2707                    (match_operand:SI 2 "register_operand" "")))
2708      (set (subreg:SI (match_dup 0) 0)
2709           (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2710                                              (sign_extend:DI (match_dup 2)))
2711                                     (const_int 32))))])]
2712   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2713   "")
2714
2715 (define_insn ""
2716   [(set (match_operand:SI 0 "register_operand" "=d")
2717         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2718                  (match_operand:SI 2 "nonimmediate_operand" "dm")))
2719    (set (match_operand:SI 3 "register_operand" "=d")
2720         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2721                                            (sign_extend:DI (match_dup 2)))
2722                                   (const_int 32))))]
2723   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2724   "muls%.l %2,%3:%0")
2725
2726 (define_insn ""
2727   [(set (match_operand:SI 0 "register_operand" "=d")
2728         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2729                  (match_operand:SI 2 "const_int_operand" "n")))
2730    (set (match_operand:SI 3 "register_operand" "=d")
2731         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2732                                            (match_dup 2))
2733                                   (const_int 32))))]
2734   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2735   "muls%.l %2,%3:%0")
2736
2737 (define_expand "umulsi3_highpart"
2738   [(parallel
2739     [(set (match_operand:SI 0 "register_operand" "")
2740           (truncate:SI
2741            (lshiftrt:DI
2742             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2743                      (zero_extend:DI (match_operand:SI 2 "general_operand" "")))
2744             (const_int 32))))
2745      (clobber (match_dup 3))])]
2746   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2747 {
2748   operands[3] = gen_reg_rtx (SImode);
2749
2750   if (GET_CODE (operands[2]) == CONST_INT)
2751     {
2752       operands[2] = immed_double_const (INTVAL (operands[2]) & 0xffffffff,
2753                                         0, DImode);
2754
2755       /* We have to adjust the operand order for the matching constraints.  */
2756       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[3],
2757                                              operands[1], operands[2]));
2758       DONE;
2759     }
2760 })
2761
2762 (define_insn ""
2763   [(set (match_operand:SI 0 "register_operand" "=d")
2764         (truncate:SI
2765          (lshiftrt:DI
2766           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "%1"))
2767                    (zero_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
2768           (const_int 32))))
2769    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2770   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2771   "mulu%.l %3,%0:%1")
2772
2773 (define_insn "const_umulsi3_highpart"
2774   [(set (match_operand:SI 0 "register_operand" "=d")
2775         (truncate:SI
2776          (lshiftrt:DI
2777           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "1"))
2778                    (match_operand:DI 3 "const_uint32_operand" "n"))
2779           (const_int 32))))
2780    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2781   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2782   "mulu%.l %3,%0:%1")
2783
2784 (define_expand "smulsi3_highpart"
2785   [(parallel
2786     [(set (match_operand:SI 0 "register_operand" "")
2787           (truncate:SI
2788            (lshiftrt:DI
2789             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2790                      (sign_extend:DI (match_operand:SI 2 "general_operand" "")))
2791             (const_int 32))))
2792      (clobber (match_dup 3))])]
2793   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2794 {
2795   operands[3] = gen_reg_rtx (SImode);
2796   if (GET_CODE (operands[2]) == CONST_INT)
2797     {
2798       /* We have to adjust the operand order for the matching constraints.  */
2799       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[3],
2800                                              operands[1], operands[2]));
2801       DONE;
2802     }
2803 })
2804
2805 (define_insn ""
2806   [(set (match_operand:SI 0 "register_operand" "=d")
2807         (truncate:SI
2808          (lshiftrt:DI
2809           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "%1"))
2810                    (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
2811           (const_int 32))))
2812    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2813   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2814   "muls%.l %3,%0:%1")
2815
2816 (define_insn "const_smulsi3_highpart"
2817   [(set (match_operand:SI 0 "register_operand" "=d")
2818         (truncate:SI
2819          (lshiftrt:DI
2820           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1"))
2821                    (match_operand:DI 3 "const_sint32_operand" "n"))
2822           (const_int 32))))
2823    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2824   "TARGET_68020 && !TARGET_68060 && !TARGET_COLDFIRE"
2825   "muls%.l %3,%0:%1")
2826
2827 (define_expand "mul<mode>3"
2828   [(set (match_operand:FP 0 "nonimmediate_operand" "")
2829         (mult:FP (match_operand:FP 1 "general_operand" "")
2830                  (match_operand:FP 2 "general_operand" "")))]
2831   "TARGET_HARD_FLOAT"
2832   "")
2833
2834 (define_insn "mul<mode>3_floatsi_68881"
2835   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2836         (mult:FP (float:FP (match_operand:SI 2 "general_operand" "dmi"))
2837                  (match_operand:FP 1 "general_operand" "0")))]
2838   "TARGET_68881"
2839 {
2840   return TARGET_68040_ONLY
2841          ? "f<FP:round>mul%.l %2,%0"
2842          : "f<FP:round_mul>mul%.l %2,%0";
2843 })
2844
2845 (define_insn "mul<mode>3_floathi_68881"
2846   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2847         (mult:FP (float:FP (match_operand:HI 2 "general_operand" "dmn"))
2848                  (match_operand:FP 1 "general_operand" "0")))]
2849   "TARGET_68881"
2850 {
2851   return TARGET_68040_ONLY
2852          ? "f<FP:round>mul%.w %2,%0"
2853          : "f<FP:round_mul>mul%.w %2,%0";
2854 })
2855
2856 (define_insn "mul<mode>3_floatqi_68881"
2857   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2858         (mult:FP (float:FP (match_operand:QI 2 "general_operand" "dmn"))
2859                  (match_operand:FP 1 "general_operand" "0")))]
2860   "TARGET_68881"
2861 {
2862   return TARGET_68040_ONLY
2863          ? "f<FP:round>mul%.b %2,%0"
2864          : "f<FP:round_mul>mul%.b %2,%0";
2865 })
2866
2867 (define_insn "muldf_68881"
2868   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2869         (mult:DF (match_operand:DF 1 "general_operand" "%0")
2870                  (match_operand:DF 2 "general_operand" "fmG")))]
2871   "TARGET_68881"
2872 {
2873   if (GET_CODE (operands[2]) == CONST_DOUBLE
2874       && floating_exact_log2 (operands[2]) && !TARGET_68040 && !TARGET_68060)
2875     {
2876       int i = floating_exact_log2 (operands[2]);
2877       operands[2] = GEN_INT (i);
2878       return "fscale%.l %2,%0";
2879     }
2880   if (REG_P (operands[2]))
2881     return "f%&mul%.x %2,%0";
2882   return "f%&mul%.d %f2,%0";
2883 })
2884
2885 (define_insn "mulsf_68881"
2886   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2887         (mult:SF (match_operand:SF 1 "general_operand" "%0")
2888                  (match_operand:SF 2 "general_operand" "fdmF")))]
2889   "TARGET_68881"
2890 {
2891   if (FP_REG_P (operands[2]))
2892     return (TARGET_68040_ONLY
2893             ? "fsmul%.x %2,%0"
2894             : "fsglmul%.x %2,%0");
2895   return (TARGET_68040_ONLY
2896           ? "fsmul%.s %f2,%0"
2897           : "fsglmul%.s %f2,%0");
2898 })
2899
2900 (define_insn "mulxf3_68881"
2901   [(set (match_operand:XF 0 "nonimmediate_operand" "=f")
2902         (mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
2903                  (match_operand:XF 2 "nonimmediate_operand" "fm")))]
2904   "TARGET_68881"
2905 {
2906   return "fmul%.x %f2,%0";
2907 })
2908
2909 (define_insn "fmul<mode>3_cf"
2910   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2911         (mult:FP (match_operand:FP 1 "general_operand" "%0")
2912                  (match_operand:FP 2 "general_operand" "f<Q>U<FP:dreg>")))]
2913   "TARGET_COLDFIRE_FPU"
2914 {
2915   if (FP_REG_P (operands[2]))
2916     return "f<FP:prec>mul%.d %2,%0";
2917   return "f<FP:prec>mul%.<FP:prec> %2,%0";
2918 })
2919 \f
2920 ;; divide instructions
2921
2922 (define_expand "div<mode>3"
2923   [(set (match_operand:FP 0 "nonimmediate_operand" "")
2924         (div:FP (match_operand:FP 1 "general_operand" "")
2925                 (match_operand:FP 2 "general_operand" "")))]
2926   "TARGET_HARD_FLOAT"
2927   "")
2928
2929 (define_insn "div<mode>3_floatsi_68881"
2930   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2931         (div:FP (match_operand:FP 1 "general_operand" "0")
2932                 (float:FP (match_operand:SI 2 "general_operand" "dmi"))))]
2933   "TARGET_68881"
2934 {
2935   return TARGET_68040_ONLY
2936          ? "f<FP:round>div%.l %2,%0"
2937          : "f<FP:round_mul>div%.l %2,%0";
2938 })
2939
2940 (define_insn "div<mode>3_floathi_68881"
2941   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2942         (div:FP (match_operand:FP 1 "general_operand" "0")
2943                 (float:FP (match_operand:HI 2 "general_operand" "dmn"))))]
2944   "TARGET_68881"
2945 {
2946   return TARGET_68040_ONLY
2947          ? "f<FP:round>div%.w %2,%0"
2948          : "f<FP:round_mul>div%.w %2,%0";
2949 })
2950
2951 (define_insn "div<mode>3_floatqi_68881"
2952   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2953         (div:FP (match_operand:FP 1 "general_operand" "0")
2954                 (float:FP (match_operand:QI 2 "general_operand" "dmn"))))]
2955   "TARGET_68881"
2956 {
2957   return TARGET_68040_ONLY
2958          ? "f<FP:round>div%.b %2,%0"
2959          : "f<FP:round_mul>div%.b %2,%0";
2960 })
2961
2962 (define_insn "div<mode>3_68881"
2963   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2964         (div:FP (match_operand:FP 1 "general_operand" "0")
2965                 (match_operand:FP 2 "general_operand" "f<FP:dreg>m<FP:const>")))]
2966   "TARGET_68881"
2967 {
2968   if (FP_REG_P (operands[2]))
2969     return (TARGET_68040_ONLY
2970             ? "f<FP:round>div%.x %2,%0"
2971             : "f<FP:round_mul>div%.x %2,%0");
2972   return (TARGET_68040_ONLY
2973           ? "f<FP:round>div%.<FP:prec> %f2,%0"
2974           : "f<FP:round_mul>div%.<FP:prec> %f2,%0");
2975 })
2976
2977 (define_insn "div<mode>3_cf"
2978   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2979         (div:FP (match_operand:FP 1 "general_operand" "0")
2980                 (match_operand:FP 2 "general_operand" "f<Q>U<FP:dreg>")))]
2981   "TARGET_COLDFIRE_FPU"
2982 {
2983   if (FP_REG_P (operands[2]))
2984     return "f<FP:prec>div%.d %2,%0";
2985   return "f<FP:prec>div%.<FP:prec> %2,%0";
2986 })
2987 \f
2988 ;; Remainder instructions.
2989
2990 (define_expand "divmodsi4"
2991   [(parallel
2992     [(set (match_operand:SI 0 "nonimmediate_operand" "")
2993           (div:SI (match_operand:SI 1 "general_operand" "")
2994                   (match_operand:SI 2 "general_src_operand" "")))
2995      (set (match_operand:SI 3 "nonimmediate_operand" "")
2996           (mod:SI (match_dup 1) (match_dup 2)))])]
2997   "TARGET_68020 || TARGET_CF_HWDIV"
2998   "")
2999
3000 (define_insn ""
3001   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3002         (div:SI (match_operand:SI 1 "general_operand" "0")
3003                 (match_operand:SI 2 "general_src_operand" "d<Q>U")))
3004    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
3005         (mod:SI (match_dup 1) (match_dup 2)))]
3006   "TARGET_CF_HWDIV"
3007 {
3008   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3009     return "divs%.l %2,%0";
3010   else if (find_reg_note (insn, REG_UNUSED, operands[0]))
3011     return "rems%.l %2,%3:%0";
3012   else
3013     return "rems%.l %2,%3:%0\;divs%.l %2,%0";
3014 })
3015
3016 (define_insn ""
3017   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3018         (div:SI (match_operand:SI 1 "general_operand" "0")
3019                 (match_operand:SI 2 "general_src_operand" "dmSTK")))
3020    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3021         (mod:SI (match_dup 1) (match_dup 2)))]
3022   "TARGET_68020"
3023 {
3024   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3025     return "divs%.l %2,%0";
3026   else
3027     return "divsl%.l %2,%3:%0";
3028 })
3029
3030 (define_expand "udivmodsi4"
3031   [(parallel
3032     [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3033           (udiv:SI (match_operand:SI 1 "general_operand" "0")
3034                    (match_operand:SI 2 "general_src_operand" "dmSTK")))
3035      (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3036           (umod:SI (match_dup 1) (match_dup 2)))])]
3037   "TARGET_68020 || TARGET_CF_HWDIV"
3038   "")
3039
3040 (define_insn ""
3041   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3042         (udiv:SI (match_operand:SI 1 "general_operand" "0")
3043                  (match_operand:SI 2 "general_src_operand" "d<Q>U")))
3044    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
3045         (umod:SI (match_dup 1) (match_dup 2)))]
3046   "TARGET_CF_HWDIV"
3047 {
3048   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3049     return "divu%.l %2,%0";
3050   else if (find_reg_note (insn, REG_UNUSED, operands[0]))
3051     return "remu%.l %2,%3:%0";
3052   else
3053     return "remu%.l %2,%3:%0\;divu%.l %2,%0";
3054 })
3055
3056 (define_insn ""
3057   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3058         (udiv:SI (match_operand:SI 1 "general_operand" "0")
3059                  (match_operand:SI 2 "general_src_operand" "dmSTK")))
3060    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3061         (umod:SI (match_dup 1) (match_dup 2)))]
3062   "TARGET_68020 && !TARGET_COLDFIRE"
3063 {
3064   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3065     return "divu%.l %2,%0";
3066   else
3067     return "divul%.l %2,%3:%0";
3068 })
3069
3070 (define_insn "divmodhi4"
3071   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3072         (div:HI (match_operand:HI 1 "general_operand" "0")
3073                 (match_operand:HI 2 "general_src_operand" "dmSKT")))
3074    (set (match_operand:HI 3 "nonimmediate_operand" "=d")
3075         (mod:HI (match_dup 1) (match_dup 2)))]
3076   "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
3077 {
3078   output_asm_insn (MOTOROLA ?
3079     "ext%.l %0\;divs%.w %2,%0" :
3080     "extl %0\;divs %2,%0",
3081     operands);
3082   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3083     {
3084       CC_STATUS_INIT;
3085       return "move%.l %0,%3\;swap %3";
3086     }
3087   else
3088     return "";
3089 })
3090
3091 (define_insn "udivmodhi4"
3092   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3093         (udiv:HI (match_operand:HI 1 "general_operand" "0")
3094                  (match_operand:HI 2 "general_src_operand" "dmSKT")))
3095    (set (match_operand:HI 3 "nonimmediate_operand" "=d")
3096         (umod:HI (match_dup 1) (match_dup 2)))]
3097   "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
3098 {
3099   if (TARGET_CFV4)
3100     output_asm_insn (MOTOROLA ?
3101       "mvz%.w %0,%0\;divu%.w %2,%0" :
3102       "mvz%.w %0,%0\;divu %2,%0",
3103       operands);
3104   else
3105     output_asm_insn (MOTOROLA ?
3106       "and%.l #0xFFFF,%0\;divu%.w %2,%0" :
3107       "and%.l #0xFFFF,%0\;divu %2,%0",
3108       operands);
3109
3110   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3111     {
3112       CC_STATUS_INIT;
3113       return "move%.l %0,%3\;swap %3";
3114     }
3115   else
3116     return "";
3117 })
3118 \f
3119 ;; logical-and instructions
3120
3121 ;; "anddi3" is mainly here to help combine().
3122 (define_insn "anddi3"
3123   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3124         (and:DI (match_operand:DI 1 "general_operand" "%0,0")
3125                 (match_operand:DI 2 "general_operand" "dn,don")))]
3126   "!TARGET_COLDFIRE"
3127 {
3128   CC_STATUS_INIT;
3129   /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3130   if (CONSTANT_P (operands[2]))
3131     {
3132       rtx hi, lo;
3133
3134       split_double (operands[2], &hi, &lo);
3135
3136       switch (INTVAL (hi))
3137         {
3138           case 0 :
3139             output_asm_insn ("clr%.l %0", operands);
3140             break;
3141           case -1 :
3142             break;
3143           default :
3144             {
3145             rtx xoperands[3];
3146
3147             xoperands[0] = operands[0];
3148             xoperands[2] = hi;
3149             output_asm_insn (output_andsi3 (xoperands), xoperands);
3150             }
3151         }
3152       if (GET_CODE (operands[0]) == REG)
3153         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3154       else
3155         operands[0] = adjust_address (operands[0], SImode, 4);
3156       switch (INTVAL (lo))
3157         {
3158           case 0 :
3159             output_asm_insn ("clr%.l %0", operands);
3160             break;
3161           case -1 :
3162             break;
3163           default :
3164             {
3165             rtx xoperands[3];
3166
3167             xoperands[0] = operands[0];
3168             xoperands[2] = lo;
3169             output_asm_insn (output_andsi3 (xoperands), xoperands);
3170             }
3171         }
3172       return "";
3173     }
3174   if (GET_CODE (operands[0]) != REG)
3175     {
3176       operands[1] = adjust_address (operands[0], SImode, 4);
3177       return "and%.l %2,%0\;and%.l %R2,%1";
3178     }
3179   if (GET_CODE (operands[2]) != REG)
3180     {
3181       operands[1] = adjust_address (operands[2], SImode, 4);
3182       return "and%.l %2,%0\;and%.l %1,%R0";
3183     }
3184   return "and%.l %2,%0\;and%.l %R2,%R0";
3185 })
3186
3187 ;; Prevent AND from being made with sp.  This doesn't exist in the machine
3188 ;; and reload will cause inefficient code.  Since sp is a FIXED_REG, we
3189 ;; can't allocate pseudos into it.
3190
3191 (define_expand "andsi3"
3192   [(set (match_operand:SI 0 "not_sp_operand" "")
3193         (and:SI (match_operand:SI 1 "general_operand" "")
3194                 (match_operand:SI 2 "general_src_operand" "")))]
3195   ""
3196   "")
3197
3198 ;; produced by split operations after reload finished
3199 (define_insn "*andsi3_split"
3200   [(set (match_operand:SI 0 "register_operand" "=d")
3201         (and:SI (match_operand:SI 1 "register_operand" "0")
3202                 (match_operand:SI 2 "const_int_operand" "i")))]
3203   "reload_completed && !TARGET_COLDFIRE"
3204 {
3205   return output_andsi3 (operands);
3206 })
3207
3208 (define_insn "andsi3_internal"
3209   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3210         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3211                 (match_operand:SI 2 "general_src_operand" "dKT,dmSM")))]
3212   "!TARGET_COLDFIRE"
3213 {
3214   return output_andsi3 (operands);
3215 })
3216
3217 (define_insn "andsi3_5200"
3218   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3219         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3220                 (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
3221   "TARGET_COLDFIRE"
3222 {
3223   if (TARGET_CFV4 && DATA_REG_P (operands[0])
3224       && GET_CODE (operands[2]) == CONST_INT)
3225     {
3226       if (INTVAL (operands[2]) == 0x000000ff)
3227         return "mvz%.b %0,%0";
3228       else if (INTVAL (operands[2]) == 0x0000ffff)
3229         return "mvz%.w %0,%0";
3230     }
3231   return output_andsi3 (operands);
3232 })
3233
3234 (define_insn "andhi3"
3235   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
3236         (and:HI (match_operand:HI 1 "general_operand" "%0,0")
3237                 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
3238   "!TARGET_COLDFIRE"
3239   "and%.w %2,%0")
3240
3241 (define_insn ""
3242   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3243         (and:HI (match_dup 0)
3244                 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
3245   "!TARGET_COLDFIRE"
3246   "and%.w %1,%0")
3247
3248 (define_insn ""
3249   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3250         (and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
3251                 (match_dup 0)))]
3252   "!TARGET_COLDFIRE"
3253   "and%.w %1,%0")
3254
3255 (define_insn "andqi3"
3256   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
3257         (and:QI (match_operand:QI 1 "general_operand" "%0,0")
3258                 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
3259   "!TARGET_COLDFIRE"
3260   "and%.b %2,%0")
3261
3262 (define_insn ""
3263   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3264         (and:QI (match_dup 0)
3265                 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
3266   "!TARGET_COLDFIRE"
3267   "and%.b %1,%0")
3268
3269 (define_insn ""
3270   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3271         (and:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
3272                 (match_dup 0)))]
3273   "!TARGET_COLDFIRE"
3274   "and%.b %1,%0")
3275 \f
3276 ;; inclusive-or instructions
3277
3278 (define_insn "iordi_zext"
3279   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3280     (ior:DI (zero_extend:DI (match_operand 1 "general_operand" "dn,dmn"))
3281         (match_operand:DI 2 "general_operand" "0,0")))]
3282   "!TARGET_COLDFIRE"
3283 {
3284   int byte_mode;
3285
3286   CC_STATUS_INIT;
3287   if (GET_CODE (operands[0]) == REG)
3288     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3289   else
3290     operands[0] = adjust_address (operands[0], SImode, 4);
3291   if (GET_MODE (operands[1]) == SImode)
3292     return "or%.l %1,%0";
3293   byte_mode = (GET_MODE (operands[1]) == QImode);
3294   if (GET_CODE (operands[0]) == MEM)
3295     operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
3296                                   byte_mode ? 3 : 2);
3297   if (byte_mode)
3298     return "or%.b %1,%0";
3299   else
3300     return "or%.w %1,%0";
3301 })
3302
3303 ;; "iordi3" is mainly here to help combine().
3304 (define_insn "iordi3"
3305   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3306         (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
3307                 (match_operand:DI 2 "general_operand" "dn,don")))]
3308   "!TARGET_COLDFIRE"
3309 {
3310   CC_STATUS_INIT;
3311   /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3312   if (CONSTANT_P (operands[2]))
3313     {
3314       rtx hi, lo;
3315
3316       split_double (operands[2], &hi, &lo);
3317
3318       switch (INTVAL (hi))
3319         {
3320           case 0 :
3321             break;
3322           case -1 :
3323             /* FIXME : a scratch register would be welcome here if operand[0]
3324                is not a register */
3325             output_asm_insn ("move%.l #-1,%0", operands);
3326             break;
3327           default :
3328             {
3329             rtx xoperands[3];
3330
3331             xoperands[0] = operands[0];
3332             xoperands[2] = hi;
3333             output_asm_insn (output_iorsi3 (xoperands), xoperands);
3334             }
3335         }
3336       if (GET_CODE (operands[0]) == REG)
3337         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3338       else
3339         operands[0] = adjust_address (operands[0], SImode, 4);
3340       switch (INTVAL (lo))
3341         {
3342           case 0 :
3343             break;
3344           case -1 :
3345             /* FIXME : a scratch register would be welcome here if operand[0]
3346                is not a register */
3347             output_asm_insn ("move%.l #-1,%0", operands);
3348             break;
3349           default :
3350             {
3351             rtx xoperands[3];
3352
3353             xoperands[0] = operands[0];
3354             xoperands[2] = lo;
3355             output_asm_insn (output_iorsi3 (xoperands), xoperands);
3356             }
3357         }
3358       return "";
3359     }
3360   if (GET_CODE (operands[0]) != REG)
3361     {
3362       operands[1] = adjust_address (operands[0], SImode, 4);
3363       return "or%.l %2,%0\;or%.l %R2,%1";
3364     }
3365   if (GET_CODE (operands[2]) != REG)
3366     {
3367       operands[1] = adjust_address (operands[2], SImode, 4);
3368       return "or%.l %2,%0\;or%.l %1,%R0";
3369     }
3370   return "or%.l %2,%0\;or%.l %R2,%R0";
3371 })
3372
3373 (define_expand "iorsi3"
3374   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3375         (ior:SI (match_operand:SI 1 "general_operand" "")
3376                 (match_operand:SI 2 "general_src_operand" "")))]
3377   ""
3378   "")
3379
3380 (define_insn "iorsi3_internal"
3381   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d")
3382         (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3383                 (match_operand:SI 2 "general_src_operand" "dKT,dmSMT")))]
3384   "! TARGET_COLDFIRE"
3385 {
3386   return output_iorsi3 (operands);
3387 })
3388
3389 (define_insn "iorsi3_5200"
3390   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d")
3391         (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3392                 (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
3393   "TARGET_COLDFIRE"
3394 {
3395   return output_iorsi3 (operands);
3396 })
3397
3398 (define_insn "iorhi3"
3399   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
3400         (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
3401                 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
3402   "!TARGET_COLDFIRE"
3403   "or%.w %2,%0")
3404
3405 (define_insn ""
3406   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3407         (ior:HI (match_dup 0)
3408                 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
3409   "!TARGET_COLDFIRE"
3410   "or%.w %1,%0")
3411
3412 (define_insn ""
3413   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3414         (ior:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
3415                 (match_dup 0)))]
3416   "!TARGET_COLDFIRE"
3417   "or%.w %1,%0")
3418
3419 (define_insn "iorqi3"
3420   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
3421         (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
3422                 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
3423   "!TARGET_COLDFIRE"
3424   "or%.b %2,%0")
3425
3426 (define_insn ""
3427   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3428         (ior:QI (match_dup 0)
3429                 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
3430   "!TARGET_COLDFIRE"
3431   "or%.b %1,%0")
3432
3433 (define_insn ""
3434   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3435         (ior:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
3436                 (match_dup 0)))]
3437   "!TARGET_COLDFIRE"
3438   "or%.b %1,%0")
3439
3440 ;; On all 68k models, this makes faster code in a special case.
3441 ;; See also ashlsi_16, ashrsi_16 and lshrsi_16.
3442
3443 (define_insn "iorsi_zexthi_ashl16"
3444   [(set (match_operand:SI 0 "nonimmediate_operand" "=&d")
3445     (ior:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rmn"))
3446         (ashift:SI (match_operand:SI 2 "general_operand" "or")
3447             (const_int 16))))]
3448   ""
3449 {
3450   CC_STATUS_INIT;
3451   if (GET_CODE (operands[2]) != REG)
3452       operands[2] = adjust_address (operands[2], HImode, 2);
3453   if (GET_CODE (operands[2]) != REG
3454   || REGNO (operands[2]) != REGNO (operands[0]))
3455     output_asm_insn ("move%.w %2,%0", operands);
3456   return "swap %0\;mov%.w %1,%0";
3457 })
3458
3459 (define_insn "iorsi_zext"
3460   [(set (match_operand:SI 0 "nonimmediate_operand" "=o,d")
3461     (ior:SI (zero_extend:SI (match_operand 1 "general_operand" "dn,dmn"))
3462         (match_operand:SI 2 "general_operand" "0,0")))]
3463   "!TARGET_COLDFIRE"
3464 {
3465   int byte_mode;
3466
3467   CC_STATUS_INIT;
3468   byte_mode = (GET_MODE (operands[1]) == QImode);
3469   if (GET_CODE (operands[0]) == MEM)
3470     operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
3471                                   byte_mode ? 3 : 2);
3472   if (byte_mode)
3473     return "or%.b %1,%0";
3474   else
3475     return "or%.w %1,%0";
3476 })
3477 \f
3478 ;; xor instructions
3479
3480 ;; "xordi3" is mainly here to help combine().
3481 (define_insn "xordi3"
3482   [(set (match_operand:DI 0 "nonimmediate_operand" "=od")
3483         (xor:DI (match_operand:DI 1 "general_operand" "%0")
3484                 (match_operand:DI 2 "general_operand" "dn")))]
3485   "!TARGET_COLDFIRE"
3486 {
3487   CC_STATUS_INIT;
3488   /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3489
3490   if (CONSTANT_P (operands[2]))
3491     {
3492       rtx hi, lo;
3493
3494       split_double (operands[2], &hi, &lo);
3495
3496       switch (INTVAL (hi))
3497         {
3498           case 0 :
3499             break;
3500           case -1 :
3501             output_asm_insn ("not%.l %0", operands);
3502             break;
3503           default :
3504             /* FIXME : a scratch register would be welcome here if
3505                -128 <= INTVAL (hi) < -1 */
3506             {
3507             rtx xoperands[3];
3508
3509             xoperands[0] = operands[0];
3510             xoperands[2] = hi;
3511             output_asm_insn (output_xorsi3 (xoperands), xoperands);
3512             }
3513         }
3514       if (GET_CODE (operands[0]) == REG)
3515         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3516       else
3517         operands[0] = adjust_address (operands[0], SImode, 4);
3518       switch (INTVAL (lo))
3519         {
3520           case 0 :
3521             break;
3522           case -1 :
3523             output_asm_insn ("not%.l %0", operands);
3524             break;
3525           default :
3526             /* FIXME : a scratch register would be welcome here if
3527                -128 <= INTVAL (lo) < -1 */
3528             operands[2] = lo;
3529             /* FIXME : this should be merged with xorsi3 */
3530             {
3531             rtx xoperands[3];
3532
3533             xoperands[0] = operands[0];
3534             xoperands[2] = lo;
3535             output_asm_insn (output_xorsi3 (xoperands), xoperands);
3536             }
3537         }
3538       return "";
3539     }
3540   if (GET_CODE (operands[0]) != REG)
3541     {
3542       operands[1] = adjust_address (operands[0], SImode, 4);
3543       return "eor%.l %2,%0\;eor%.l %R2,%1";
3544     }
3545   if (GET_CODE (operands[2]) != REG)
3546     {
3547       operands[1] = adjust_address (operands[2], SImode, 4);
3548       return "eor%.l %2,%0\;eor%.l %1,%R0";
3549     }
3550   return "eor%.l %2,%0\;eor%.l %R2,%R0";
3551 })
3552
3553 (define_expand "xorsi3"
3554   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3555         (xor:SI (match_operand:SI 1 "general_operand" "")
3556                 (match_operand:SI 2 "general_operand" "")))]
3557   ""
3558   "")
3559
3560 (define_insn "xorsi3_internal"
3561   [(set (match_operand:SI 0 "nonimmediate_operand" "=do,m")
3562         (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
3563                 (match_operand:SI 2 "general_operand" "di,dKT")))]
3564
3565   "!TARGET_COLDFIRE"
3566 {
3567   return output_xorsi3 (operands);
3568 })
3569
3570 (define_insn "xorsi3_5200"
3571   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,d")
3572         (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
3573                 (match_operand:SI 2 "general_operand" "d,Ks")))]
3574   "TARGET_COLDFIRE"
3575 {
3576   return output_xorsi3 (operands);
3577 })
3578
3579 (define_insn "xorhi3"
3580   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
3581         (xor:HI (match_operand:HI 1 "general_operand" "%0")
3582                 (match_operand:HI 2 "general_operand" "dn")))]
3583   "!TARGET_COLDFIRE"
3584   "eor%.w %2,%0")
3585
3586 (define_insn ""
3587   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
3588         (xor:HI (match_dup 0)
3589                 (match_operand:HI 1 "general_operand" "dn")))]
3590   "!TARGET_COLDFIRE"
3591   "eor%.w %1,%0")
3592
3593 (define_insn ""
3594   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
3595         (xor:HI (match_operand:HI 1 "general_operand" "dn")
3596                 (match_dup 0)))]
3597   "!TARGET_COLDFIRE"
3598   "eor%.w %1,%0")
3599
3600 (define_insn "xorqi3"
3601   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
3602         (xor:QI (match_operand:QI 1 "general_operand" "%0")
3603                 (match_operand:QI 2 "general_operand" "dn")))]
3604   "!TARGET_COLDFIRE"
3605   "eor%.b %2,%0")
3606
3607 (define_insn ""
3608   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
3609         (xor:QI (match_dup 0)
3610                 (match_operand:QI 1 "general_operand" "dn")))]
3611   "!TARGET_COLDFIRE"
3612   "eor%.b %1,%0")
3613
3614 (define_insn ""
3615   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
3616         (xor:QI (match_operand:QI 1 "general_operand" "dn")
3617                 (match_dup 0)))]
3618   "!TARGET_COLDFIRE"
3619   "eor%.b %1,%0")
3620 \f
3621 ;; negation instructions
3622
3623 (define_expand "negdi2"
3624   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3625         (neg:DI (match_operand:DI 1 "general_operand" "")))]
3626   ""
3627 {
3628   if (TARGET_COLDFIRE)
3629     emit_insn (gen_negdi2_5200 (operands[0], operands[1]));
3630   else
3631     emit_insn (gen_negdi2_internal (operands[0], operands[1]));
3632   DONE;
3633 })
3634
3635 (define_insn "negdi2_internal"
3636   [(set (match_operand:DI 0 "nonimmediate_operand" "=<,do,!*a")
3637         (neg:DI (match_operand:DI 1 "general_operand" "0,0,0")))]
3638   "!TARGET_COLDFIRE"
3639 {
3640   if (which_alternative == 0)
3641     return "neg%.l %0\;negx%.l %0";
3642   if (GET_CODE (operands[0]) == REG)
3643     operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3644   else
3645     operands[1] = adjust_address (operands[0], SImode, 4);
3646   if (ADDRESS_REG_P (operands[0]))
3647     return "exg %/d0,%1\;neg%.l %/d0\;exg %/d0,%1\;exg %/d0,%0\;negx%.l %/d0\;exg %/d0,%0";
3648   else
3649     return "neg%.l %1\;negx%.l %0";
3650 })
3651
3652 (define_insn "negdi2_5200"
3653   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
3654         (neg:DI (match_operand:DI 1 "general_operand" "0")))]
3655   "TARGET_COLDFIRE"
3656 {
3657   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3658   return "neg%.l %1\;negx%.l %0";
3659 })
3660
3661 (define_expand "negsi2"
3662   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3663         (neg:SI (match_operand:SI 1 "general_operand" "")))]
3664   ""
3665 {
3666   if (TARGET_COLDFIRE)
3667     emit_insn (gen_negsi2_5200 (operands[0], operands[1]));
3668   else
3669     emit_insn (gen_negsi2_internal (operands[0], operands[1]));
3670   DONE;
3671 })
3672
3673 (define_insn "negsi2_internal"
3674   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
3675         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
3676   "!TARGET_COLDFIRE"
3677   "neg%.l %0")
3678
3679 (define_insn "negsi2_5200"
3680   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3681         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
3682   "TARGET_COLDFIRE"
3683   "neg%.l %0")
3684
3685 (define_insn "neghi2"
3686   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
3687         (neg:HI (match_operand:HI 1 "general_operand" "0")))]
3688   "!TARGET_COLDFIRE"
3689   "neg%.w %0")
3690
3691 (define_insn ""
3692   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
3693         (neg:HI (match_dup 0)))]
3694   "!TARGET_COLDFIRE"
3695   "neg%.w %0")
3696
3697 (define_insn "negqi2"
3698   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
3699         (neg:QI (match_operand:QI 1 "general_operand" "0")))]
3700   "!TARGET_COLDFIRE"
3701   "neg%.b %0")
3702
3703 (define_insn ""
3704   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
3705         (neg:QI (match_dup 0)))]
3706   "!TARGET_COLDFIRE"
3707   "neg%.b %0")
3708
3709 ;; If using software floating point, just flip the sign bit.
3710
3711 (define_expand "negsf2"
3712   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3713         (neg:SF (match_operand:SF 1 "general_operand" "")))]
3714   ""
3715 {
3716   if (!TARGET_HARD_FLOAT)
3717     {
3718       rtx result;
3719       rtx target;
3720
3721       target = operand_subword_force (operands[0], 0, SFmode);
3722       result = expand_binop (SImode, xor_optab,
3723                              operand_subword_force (operands[1], 0, SFmode),
3724                              GEN_INT (0x80000000), target, 0, OPTAB_WIDEN);
3725       gcc_assert (result);
3726
3727       if (result != target)
3728         emit_move_insn (result, target);
3729
3730       /* Make a place for REG_EQUAL.  */
3731       emit_move_insn (operands[0], operands[0]);
3732       DONE;
3733     }
3734 })
3735
3736 (define_expand "negdf2"
3737   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3738         (neg:DF (match_operand:DF 1 "general_operand" "")))]
3739   ""
3740 {
3741   if (!TARGET_HARD_FLOAT)
3742     {
3743       rtx result;
3744       rtx target;
3745       rtx insns;
3746
3747       start_sequence ();
3748       target = operand_subword (operands[0], 0, 1, DFmode);
3749       result = expand_binop (SImode, xor_optab,
3750                              operand_subword_force (operands[1], 0, DFmode),
3751                              GEN_INT (0x80000000), target, 0, OPTAB_WIDEN);
3752       gcc_assert (result);
3753
3754       if (result != target)
3755         emit_move_insn (result, target);
3756
3757       emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
3758                       operand_subword_force (operands[1], 1, DFmode));
3759
3760       insns = get_insns ();
3761       end_sequence ();
3762
3763       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
3764       DONE;
3765     }
3766 })
3767
3768 (define_expand "negxf2"
3769   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3770         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
3771   ""
3772 {
3773   if (!TARGET_68881)
3774     {
3775       rtx result;
3776       rtx target;
3777       rtx insns;
3778
3779       start_sequence ();
3780       target = operand_subword (operands[0], 0, 1, XFmode);
3781       result = expand_binop (SImode, xor_optab,
3782                              operand_subword_force (operands[1], 0, XFmode),
3783                              GEN_INT (0x80000000), target, 0, OPTAB_WIDEN);
3784       gcc_assert (result);
3785
3786       if (result != target)
3787         emit_move_insn (result, target);
3788
3789       emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
3790                       operand_subword_force (operands[1], 1, XFmode));
3791       emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
3792                       operand_subword_force (operands[1], 2, XFmode));
3793
3794       insns = get_insns ();
3795       end_sequence ();
3796
3797       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
3798       DONE;
3799     }
3800 })
3801
3802 (define_insn "neg<mode>2_68881"
3803   [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
3804         (neg:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m<FP:const>,0")))]
3805   "TARGET_68881"
3806 {
3807   if (DATA_REG_P (operands[0]))
3808     {
3809       operands[1] = GEN_INT (31);
3810       return "bchg %1,%0";
3811     }
3812   if (FP_REG_P (operands[1]))
3813     return "f<FP:round>neg%.x %1,%0";
3814   return "f<FP:round>neg%.<FP:prec> %f1,%0";
3815 })
3816
3817 (define_insn "neg<mode>2_cf"
3818   [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
3819         (neg:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,0")))]
3820   "TARGET_COLDFIRE_FPU"
3821 {
3822   if (DATA_REG_P (operands[0]))
3823     {
3824       operands[1] = GEN_INT (31);
3825       return "bchg %1,%0";
3826     }
3827   if (FP_REG_P (operands[1]))
3828     return "f<FP:prec>neg%.d %1,%0";
3829   return "f<FP:prec>neg%.<FP:prec> %1,%0";
3830 })
3831 \f
3832 ;; Sqrt instruction for the 68881
3833
3834 (define_expand "sqrt<mode>2"
3835   [(set (match_operand:FP 0 "nonimmediate_operand" "")
3836         (sqrt:FP (match_operand:FP 1 "general_operand" "")))]
3837   "TARGET_HARD_FLOAT"
3838   "")
3839
3840 (define_insn "sqrt<mode>2_68881"
3841   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3842         (sqrt:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m")))]
3843   "TARGET_68881"
3844 {
3845   if (FP_REG_P (operands[1]))
3846     return "f<FP:round>sqrt%.x %1,%0";
3847   return "f<FP:round>sqrt%.<FP:prec> %1,%0";
3848 })
3849
3850 (define_insn "sqrt<mode>2_cf"
3851   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3852         (sqrt:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U")))]
3853   "TARGET_COLDFIRE_FPU"
3854 {
3855   if (FP_REG_P (operands[1]))
3856     return "f<FP:prec>sqrt%.d %1,%0";
3857   return "f<FP:prec>sqrt%.<FP:prec> %1,%0";
3858 })
3859 ;; Absolute value instructions
3860 ;; If using software floating point, just zero the sign bit.
3861
3862 (define_expand "abssf2"
3863   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3864         (abs:SF (match_operand:SF 1 "general_operand" "")))]
3865   ""
3866 {
3867   if (!TARGET_HARD_FLOAT)
3868     {
3869       rtx result;
3870       rtx target;
3871
3872       target = operand_subword_force (operands[0], 0, SFmode);
3873       result = expand_binop (SImode, and_optab,
3874                              operand_subword_force (operands[1], 0, SFmode),
3875                              GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
3876       gcc_assert (result);
3877
3878       if (result != target)
3879         emit_move_insn (result, target);
3880
3881       /* Make a place for REG_EQUAL.  */
3882       emit_move_insn (operands[0], operands[0]);
3883       DONE;
3884     }
3885 })
3886
3887 (define_expand "absdf2"
3888   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3889         (abs:DF (match_operand:DF 1 "general_operand" "")))]
3890   ""
3891 {
3892   if (!TARGET_HARD_FLOAT)
3893     {
3894       rtx result;
3895       rtx target;
3896       rtx insns;
3897
3898       start_sequence ();
3899       target = operand_subword (operands[0], 0, 1, DFmode);
3900       result = expand_binop (SImode, and_optab,
3901                              operand_subword_force (operands[1], 0, DFmode),
3902                              GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
3903       gcc_assert (result);
3904
3905       if (result != target)
3906         emit_move_insn (result, target);
3907
3908       emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
3909                       operand_subword_force (operands[1], 1, DFmode));
3910
3911       insns = get_insns ();
3912       end_sequence ();
3913
3914       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
3915       DONE;
3916     }
3917 })
3918
3919 (define_expand "absxf2"
3920   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3921         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
3922   ""
3923 {
3924   if (!TARGET_68881)
3925     {
3926       rtx result;
3927       rtx target;
3928       rtx insns;
3929
3930       start_sequence ();
3931       target = operand_subword (operands[0], 0, 1, XFmode);
3932       result = expand_binop (SImode, and_optab,
3933                              operand_subword_force (operands[1], 0, XFmode),
3934                              GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
3935       gcc_assert (result);
3936
3937       if (result != target)
3938         emit_move_insn (result, target);
3939
3940       emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
3941                       operand_subword_force (operands[1], 1, XFmode));
3942       emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
3943                       operand_subword_force (operands[1], 2, XFmode));
3944
3945       insns = get_insns ();
3946       end_sequence ();
3947
3948       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
3949       DONE;
3950     }
3951 })
3952
3953 (define_insn "abs<mode>2_68881"
3954   [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
3955         (abs:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m<FP:const>,0")))]
3956   "TARGET_68881"
3957 {
3958   if (DATA_REG_P (operands[0]))
3959     {
3960       operands[1] = GEN_INT (31);
3961       return "bclr %1,%0";
3962     }
3963   if (FP_REG_P (operands[1]))
3964     return "f<FP:round>abs%.x %1,%0";
3965   return "f<FP:round>abs%.<FP:prec> %f1,%0";
3966 })
3967
3968 (define_insn "abs<mode>2_cf"
3969   [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
3970         (abs:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,0")))]
3971   "TARGET_COLDFIRE_FPU"
3972 {
3973   if (DATA_REG_P (operands[0]))
3974     {
3975       operands[1] = GEN_INT (31);
3976       return "bclr %1,%0";
3977     }
3978   if (FP_REG_P (operands[1]))
3979     return "f<FP:prec>abs%.d %1,%0";
3980   return "f<FP:prec>abs%.<FP:prec> %1,%0";
3981 })
3982 \f
3983 ;; one complement instructions
3984
3985 ;; "one_cmpldi2" is mainly here to help combine().
3986 (define_insn "one_cmpldi2"
3987   [(set (match_operand:DI 0 "nonimmediate_operand" "=dm")
3988         (not:DI (match_operand:DI 1 "general_operand" "0")))]
3989   "!TARGET_COLDFIRE"
3990 {
3991   CC_STATUS_INIT;
3992   if (GET_CODE (operands[0]) == REG)
3993     operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3994   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC
3995         || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3996     operands[1] = operands[0];
3997   else
3998     operands[1] = adjust_address (operands[0], SImode, 4);
3999   return "not%.l %1\;not%.l %0";
4000 })
4001
4002 (define_expand "one_cmplsi2"
4003   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4004         (not:SI (match_operand:SI 1 "general_operand" "")))]
4005   ""
4006 {
4007   if (TARGET_COLDFIRE)
4008     emit_insn (gen_one_cmplsi2_5200 (operands[0], operands[1]));
4009   else
4010     emit_insn (gen_one_cmplsi2_internal (operands[0], operands[1]));
4011   DONE;
4012 })
4013
4014 (define_insn "one_cmplsi2_internal"
4015   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
4016         (not:SI (match_operand:SI 1 "general_operand" "0")))]
4017   "!TARGET_COLDFIRE"
4018   "not%.l %0")
4019
4020 (define_insn "one_cmplsi2_5200"
4021   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4022         (not:SI (match_operand:SI 1 "general_operand" "0")))]
4023   "TARGET_COLDFIRE"
4024   "not%.l %0")
4025
4026 (define_insn "one_cmplhi2"
4027   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
4028         (not:HI (match_operand:HI 1 "general_operand" "0")))]
4029   "!TARGET_COLDFIRE"
4030   "not%.w %0")
4031
4032 (define_insn ""
4033   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
4034         (not:HI (match_dup 0)))]
4035   "!TARGET_COLDFIRE"
4036   "not%.w %0")
4037
4038 (define_insn "one_cmplqi2"
4039   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
4040         (not:QI (match_operand:QI 1 "general_operand" "0")))]
4041   "!TARGET_COLDFIRE"
4042   "not%.b %0")
4043
4044 (define_insn ""
4045   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
4046         (not:QI (match_dup 0)))]
4047   "!TARGET_COLDFIRE"
4048   "not%.b %0")
4049 \f
4050 ;; arithmetic shift instructions
4051 ;; We don't need the shift memory by 1 bit instruction
4052
4053 (define_insn "ashldi_extsi"
4054   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
4055     (ashift:DI
4056       (match_operator:DI 2 "extend_operator"
4057         [(match_operand:SI 1 "general_operand" "rm")])
4058       (const_int 32)))]
4059   ""
4060 {
4061   CC_STATUS_INIT;
4062   if (GET_CODE (operands[0]) == REG)
4063     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4064   else
4065     operands[2] = adjust_address (operands[0], SImode, 4);
4066   if (ADDRESS_REG_P (operands[0]))
4067     return "move%.l %1,%0\;sub%.l %2,%2";
4068   else
4069     return "move%.l %1,%0\;clr%.l %2";
4070 })
4071
4072 (define_insn "ashldi_sexthi"
4073   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,a*d")
4074     (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm,rm"))
4075         (const_int 32)))
4076     (clobber (match_scratch:SI 2 "=a,X"))]
4077   ""
4078 {
4079   CC_STATUS_INIT;
4080   if (GET_CODE (operands[0]) == MEM)
4081     {
4082     if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4083       return "clr%.l %0\;move%.w %1,%2\;move%.l %2,%0";
4084     else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
4085       return "move%.w %1,%2\;move%.l %2,%0\;clr%.l %0";
4086     else
4087       {
4088         operands[3] = adjust_address (operands[0], SImode, 4);
4089         return "move%.w %1,%2\;move%.l %2,%0\;clr%.l %3";
4090       }
4091     }
4092   else if (DATA_REG_P (operands[0]))
4093     return "move%.w %1,%0\;ext%.l %0\;clr%.l %R0";
4094   else
4095     return "move%.w %1,%0\;sub%.l %R0,%R0";
4096 })
4097
4098 (define_insn "ashldi_const32"
4099   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
4100         (ashift:DI (match_operand:DI 1 "general_operand" "ro")
4101                      (const_int 32)))]
4102   ""
4103 {
4104   CC_STATUS_INIT;
4105   if (GET_CODE (operands[1]) == REG)
4106     operands[3] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
4107   else
4108     operands[3] = adjust_address (operands[1], SImode, 4);
4109   if (GET_CODE (operands[0]) == REG)
4110     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4111   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4112     return "clr%.l %0\;move%.l %3,%0";
4113   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
4114     return "move%.l %3,%0\;clr%.l %0";
4115   else
4116     operands[2] = adjust_address (operands[0], SImode, 4);
4117   if (ADDRESS_REG_P (operands[2]))
4118     return "move%.l %3,%0\;sub%.l %2,%2";
4119   else
4120     return "move%.l %3,%0\;clr%.l %2";
4121 })
4122
4123 ;; The predicate below must be general_operand, because ashldi3 allows that
4124 (define_insn "ashldi_const"
4125   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4126         (ashift:DI (match_operand:DI 1 "general_operand" "0")
4127                      (match_operand 2 "const_int_operand" "n")))]
4128   "(!TARGET_COLDFIRE
4129     && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4130         || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4131         || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
4132 {
4133   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4134   if (INTVAL (operands[2]) == 1)
4135     return "add%.l %1,%1\;addx%.l %0,%0";
4136   else if (INTVAL (operands[2]) == 8)
4137     return "rol%.l #8,%1\;rol%.l #8,%0\;move%.b %1,%0\;clr%.b %1";
4138   else if (INTVAL (operands[2]) == 16)
4139     return "swap %1\;swap %0\;move%.w %1,%0\;clr%.w %1";
4140   else if (INTVAL (operands[2]) == 48)
4141     return "mov%.l %1,%0\;swap %0\;clr%.l %1\;clr%.w %0";
4142   else if (INTVAL (operands[2]) == 2)
4143     return "add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0";
4144   else if (INTVAL (operands[2]) == 3)
4145     return "add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0";
4146   else /* 32 < INTVAL (operands[2]) <= 63 */
4147     {
4148       operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
4149       output_asm_insn (INTVAL (operands[2]) <= 8 ? "asl%.l %2,%1" :
4150                         "moveq %2,%0\;asl%.l %0,%1", operands);
4151       return "mov%.l %1,%0\;moveq #0,%1";
4152     }
4153 })
4154
4155 (define_expand "ashldi3"
4156   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4157         (ashift:DI (match_operand:DI 1 "general_operand" "")
4158                      (match_operand 2 "const_int_operand" "")))]
4159   "!TARGET_COLDFIRE"
4160   "
4161 {
4162   /* ???  This is a named pattern like this is not allowed to FAIL based
4163      on its operands.  */
4164   if (GET_CODE (operands[2]) != CONST_INT
4165       || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
4166           && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
4167           && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
4168     FAIL;
4169 } ")
4170
4171 ;; On most 68k models, this makes faster code in a special case.
4172
4173 (define_insn "ashlsi_16"
4174   [(set (match_operand:SI 0 "register_operand" "=d")
4175         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4176                    (const_int 16)))]
4177   "!TARGET_68060"
4178 {
4179   CC_STATUS_INIT;
4180   return "swap %0\;clr%.w %0";
4181 })
4182
4183 ;; ashift patterns : use lsl instead of asl, because lsl always clears the
4184 ;; overflow bit, so we must not set CC_NO_OVERFLOW.
4185
4186 ;; On the 68000, this makes faster code in a special case.
4187
4188 (define_insn "ashlsi_17_24"
4189   [(set (match_operand:SI 0 "register_operand" "=d")
4190         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4191                    (match_operand:SI 2 "const_int_operand" "n")))]
4192   "(! TARGET_68020 && !TARGET_COLDFIRE
4193     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
4194 {
4195   CC_STATUS_INIT;
4196
4197   operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
4198   return "lsl%.w %2,%0\;swap %0\;clr%.w %0";
4199 })
4200
4201 (define_insn "ashlsi3"
4202   [(set (match_operand:SI 0 "register_operand" "=d")
4203         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4204                    (match_operand:SI 2 "general_operand" "dI")))]
4205   ""
4206 {
4207   if (operands[2] == const1_rtx)
4208     {
4209       cc_status.flags = CC_NO_OVERFLOW;
4210       return "add%.l %0,%0";
4211     }
4212   return "lsl%.l %2,%0";
4213 })
4214
4215 (define_insn "ashlhi3"
4216   [(set (match_operand:HI 0 "register_operand" "=d")
4217         (ashift:HI (match_operand:HI 1 "register_operand" "0")
4218                    (match_operand:HI 2 "general_operand" "dI")))]
4219   "!TARGET_COLDFIRE"
4220   "lsl%.w %2,%0")
4221
4222 (define_insn ""
4223   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4224         (ashift:HI (match_dup 0)
4225                    (match_operand:HI 1 "general_operand" "dI")))]
4226   "!TARGET_COLDFIRE"
4227   "lsl%.w %1,%0")
4228
4229 (define_insn "ashlqi3"
4230   [(set (match_operand:QI 0 "register_operand" "=d")
4231         (ashift:QI (match_operand:QI 1 "register_operand" "0")
4232                    (match_operand:QI 2 "general_operand" "dI")))]
4233   "!TARGET_COLDFIRE"
4234   "lsl%.b %2,%0")
4235
4236 (define_insn ""
4237   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4238         (ashift:QI (match_dup 0)
4239                    (match_operand:QI 1 "general_operand" "dI")))]
4240   "!TARGET_COLDFIRE"
4241   "lsl%.b %1,%0")
4242
4243 ;; On most 68k models, this makes faster code in a special case.
4244
4245 (define_insn "ashrsi_16"
4246   [(set (match_operand:SI 0 "register_operand" "=d")
4247         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4248                      (const_int 16)))]
4249   "!TARGET_68060"
4250   "swap %0\;ext%.l %0")
4251
4252 ;; On the 68000, this makes faster code in a special case.
4253
4254 (define_insn ""
4255   [(set (match_operand:SI 0 "register_operand" "=d")
4256         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4257                      (match_operand:SI 2 "const_int_operand" "n")))]
4258   "(! TARGET_68020 && !TARGET_COLDFIRE
4259     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
4260 {
4261   operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
4262   return "swap %0\;asr%.w %2,%0\;ext%.l %0";
4263 })
4264
4265 (define_insn "subreghi1ashrdi_const32"
4266   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4267     (subreg:HI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4268             (const_int 32)) 6))]
4269   ""
4270 {
4271   if (GET_CODE (operands[1]) != REG)
4272     operands[1] = adjust_address (operands[1], HImode, 2);
4273   return "move%.w %1,%0";
4274 })
4275
4276 (define_insn "subregsi1ashrdi_const32"
4277   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4278     (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4279             (const_int 32)) 4))]
4280   ""
4281 {
4282   return "move%.l %1,%0";
4283 })
4284
4285 (define_insn "ashrdi_const32"
4286   [(set (match_operand:DI 0 "register_operand" "=d")
4287         (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4288                      (const_int 32)))]
4289   ""
4290 {
4291   CC_STATUS_INIT;
4292   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4293   if (TARGET_68020)
4294     return "move%.l %1,%2\;smi %0\;extb%.l %0";
4295   else
4296     return "move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0";
4297 })
4298
4299 (define_insn "ashrdi_const32_mem"
4300   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,<")
4301         (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro,ro")
4302                      (const_int 32)))
4303    (clobber (match_scratch:SI 2 "=d,d"))]
4304   ""
4305 {
4306   CC_STATUS_INIT;
4307   if (which_alternative == 1)
4308     operands[3] = operands[0];
4309   else
4310     operands[3] = adjust_address (operands[0], SImode, 4);
4311   if (TARGET_68020)
4312     return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
4313   else
4314     return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
4315 })
4316
4317 ;; The predicate below must be general_operand, because ashrdi3 allows that
4318 (define_insn "ashrdi_const"
4319   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4320         (ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
4321                      (match_operand 2 "const_int_operand" "n")))]
4322   "(!TARGET_COLDFIRE 
4323     && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4324         || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4325         || INTVAL (operands[2]) == 31
4326         || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
4327 {
4328   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4329   if (INTVAL (operands[2]) == 63)
4330     return "add%.l %0,%0\;subx%.l %0,%0\;move%.l %0,%1";
4331   CC_STATUS_INIT;
4332   if (INTVAL (operands[2]) == 1)
4333     return "asr%.l #1,%0\;roxr%.l #1,%1";
4334   else if (INTVAL (operands[2]) == 8)
4335     return "move%.b %0,%1\;asr%.l #8,%0\;ror%.l #8,%1";
4336   else if (INTVAL (operands[2]) == 16)
4337     return "move%.w %0,%1\;swap %0\;ext%.l %0\;swap %1";
4338   else if (INTVAL (operands[2]) == 48)
4339     return "swap %0\;ext%.l %0\;move%.l %0,%1\;smi %0\;ext%.w %0";
4340   else if (INTVAL (operands[2]) == 31)
4341     return "add%.l %1,%1\;addx%.l %0,%0\;move%.l %0,%1\;subx%.l %0,%0";
4342   else if (INTVAL (operands[2]) == 2)
4343     return "asr%.l #1,%0\;roxr%.l #1,%1\;asr%.l #1,%0\;roxr%.l #1,%1";
4344   else if (INTVAL (operands[2]) == 3)
4345     return "asr%.l #1,%0\;roxr%.l #1,%1\;asr%.l #1,%0\;roxr%.l #1,%1\;asr%.l #1,%0\;roxr%.l #1,%1";
4346   else /* 32 < INTVAL (operands[2]) <= 63 */
4347     {
4348       operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
4349       output_asm_insn (INTVAL (operands[2]) <= 8 ? "asr%.l %2,%0" :
4350                         "moveq %2,%1\;asr%.l %1,%0", operands);
4351       output_asm_insn ("mov%.l %0,%1\;smi %0", operands);
4352       return INTVAL (operands[2]) >= 15 ? "ext%.w %d0" :
4353              TARGET_68020 ? "extb%.l %0" : "ext%.w %0\;ext%.l %0";
4354     }
4355 })
4356
4357 (define_expand "ashrdi3"
4358   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4359         (ashiftrt:DI (match_operand:DI 1 "general_operand" "")
4360                      (match_operand 2 "const_int_operand" "")))]
4361   "!TARGET_COLDFIRE"
4362   "
4363 {
4364   /* ???  This is a named pattern like this is not allowed to FAIL based
4365      on its operands.  */
4366   if (GET_CODE (operands[2]) != CONST_INT
4367       || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
4368           && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
4369           && (INTVAL (operands[2]) < 31 || INTVAL (operands[2]) > 63)))
4370     FAIL;
4371 } ")
4372
4373 ;; On all 68k models, this makes faster code in a special case.
4374
4375 (define_insn "ashrsi_31"
4376   [(set (match_operand:SI 0 "register_operand" "=d")
4377         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4378                      (const_int 31)))]
4379   ""
4380 {
4381   return "add%.l %0,%0\;subx%.l %0,%0";
4382 })
4383
4384 (define_insn "ashrsi3"
4385   [(set (match_operand:SI 0 "register_operand" "=d")
4386         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4387                      (match_operand:SI 2 "general_operand" "dI")))]
4388   ""
4389   "asr%.l %2,%0")
4390
4391 (define_insn "ashrhi3"
4392   [(set (match_operand:HI 0 "register_operand" "=d")
4393         (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
4394                      (match_operand:HI 2 "general_operand" "dI")))]
4395   "!TARGET_COLDFIRE"
4396   "asr%.w %2,%0")
4397
4398 (define_insn ""
4399   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4400         (ashiftrt:HI (match_dup 0)
4401                      (match_operand:HI 1 "general_operand" "dI")))]
4402   "!TARGET_COLDFIRE"
4403   "asr%.w %1,%0")
4404
4405 (define_insn "ashrqi3"
4406   [(set (match_operand:QI 0 "register_operand" "=d")
4407         (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
4408                      (match_operand:QI 2 "general_operand" "dI")))]
4409   "!TARGET_COLDFIRE"
4410   "asr%.b %2,%0")
4411
4412 (define_insn ""
4413   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4414         (ashiftrt:QI (match_dup 0)
4415                      (match_operand:QI 1 "general_operand" "dI")))]
4416   "!TARGET_COLDFIRE"
4417   "asr%.b %1,%0")
4418 \f
4419 ;; logical shift instructions
4420
4421 ;; commented out because of reload problems in 950612-1.c
4422 ;;(define_insn ""
4423 ;;        [(set (cc0)
4424 ;;            (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
4425 ;;                    (const_int 32)) 4))
4426 ;;        (set (match_operand:SI 1 "nonimmediate_operand" "=dm")
4427 ;;            (subreg:SI (lshiftrt:DI (match_dup 0)
4428 ;;                    (const_int 32)) 4))]
4429 ;;  ""
4430 ;;{
4431 ;;  return "move%.l %0,%1";
4432 ;;})
4433 ;;
4434 ;;(define_insn ""
4435 ;;        [(set (cc0)
4436 ;;            (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
4437 ;;                    (const_int 32)) 0))
4438 ;;        (set (match_operand:DI 1 "nonimmediate_operand" "=do")
4439 ;;            (lshiftrt:DI (match_dup 0)
4440 ;;                (const_int 32)))]
4441 ;;  ""
4442 ;;{
4443 ;;  if (GET_CODE (operands[1]) == REG)
4444 ;;    operands[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
4445 ;;  else
4446 ;;    operands[2] = adjust_address (operands[1], SImode, 4);
4447 ;;  return "move%.l %0,%2\;clr%.l %1";
4448 ;;})
4449
4450 (define_insn "subreg1lshrdi_const32"
4451   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4452     (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4453             (const_int 32)) 4))]
4454   ""
4455 {
4456   return "move%.l %1,%0";
4457 })
4458
4459 (define_insn "lshrdi_const32"
4460   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,<,>")
4461         (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,ro,ro")
4462                      (const_int 32)))]
4463   ""
4464 {
4465   CC_STATUS_INIT;
4466   if (which_alternative == 1)
4467     return "move%.l %1,%0\;clr%.l %0";
4468   if (which_alternative == 2)
4469     return "clr%.l %0\;move%.l %1,%0";
4470   if (GET_CODE (operands[0]) == REG)
4471     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4472   else
4473     operands[2] = adjust_address (operands[0], SImode, 4);
4474   if (GET_CODE (operands[1]) == REG)
4475     operands[3] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
4476   else
4477     operands[3] = adjust_address (operands[1], SImode, 4);
4478   if (ADDRESS_REG_P (operands[0]))
4479     return "move%.l %1,%2\;sub%.l %0,%0";
4480   else
4481     return "move%.l %1,%2\;clr%.l %0";
4482 })
4483
4484 ;; The predicate below must be general_operand, because lshrdi3 allows that
4485 (define_insn "lshrdi_const"
4486   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4487         (lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
4488                      (match_operand 2 "const_int_operand" "n")))]
4489   "(!TARGET_COLDFIRE
4490     && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4491          || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4492          || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
4493 {
4494   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4495   if (INTVAL (operands[2]) == 63)
4496     return "add%.l %0,%0\;clr%.l %0\;clr%.l %1\;addx%.l %1,%1";
4497   CC_STATUS_INIT;
4498   if (INTVAL (operands[2]) == 1)
4499     return "lsr%.l #1,%0\;roxr%.l #1,%1";
4500   else if (INTVAL (operands[2]) == 8)
4501     return "move%.b %0,%1\;lsr%.l #8,%0\;ror%.l #8,%1";
4502   else if (INTVAL (operands[2]) == 16)
4503     return "move%.w %0,%1\;clr%.w %0\;swap %1\;swap %0";
4504   else if (INTVAL (operands[2]) == 48)
4505     return "move%.l %0,%1\;clr%.w %1\;clr%.l %0\;swap %1";
4506   else if (INTVAL (operands[2]) == 2)
4507     return "lsr%.l #1,%0\;roxr%.l #1,%1\;lsr%.l #1,%0\;roxr%.l #1,%1";
4508   else if (INTVAL (operands[2]) == 3)
4509     return "lsr%.l #1,%0\;roxr%.l #1,%1\;lsr%.l #1,%0\;roxr%.l #1,%1\;lsr%.l #1,%0\;roxr%.l #1,%1";
4510   else /* 32 < INTVAL (operands[2]) <= 63 */
4511     {
4512       operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
4513       output_asm_insn (INTVAL (operands[2]) <= 8 ? "lsr%.l %2,%0" :
4514                         "moveq %2,%1\;lsr%.l %1,%0", operands);
4515       return "mov%.l %0,%1\;moveq #0,%0";
4516     }
4517 })
4518
4519 (define_expand "lshrdi3"
4520   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4521         (lshiftrt:DI (match_operand:DI 1 "general_operand" "")
4522                      (match_operand 2 "const_int_operand" "")))]
4523   "!TARGET_COLDFIRE"
4524 {
4525   /* ???  This is a named pattern like this is not allowed to FAIL based
4526      on its operands.  */
4527   if (GET_CODE (operands[2]) != CONST_INT
4528       || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
4529           && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
4530           && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
4531     FAIL;
4532 })
4533
4534 ;; On all 68k models, this makes faster code in a special case.
4535
4536 (define_insn "lshrsi_31"
4537   [(set (match_operand:SI 0 "register_operand" "=d")
4538         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
4539                      (const_int 31)))]
4540   ""
4541 {
4542   return "add%.l %0,%0\;subx%.l %0,%0\;neg%.l %0";
4543 })
4544
4545 ;; On most 68k models, this makes faster code in a special case.
4546
4547 (define_insn "lshrsi_16"
4548   [(set (match_operand:SI 0 "register_operand" "=d")
4549         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
4550                      (const_int 16)))]
4551   "!TARGET_68060"
4552 {
4553   CC_STATUS_INIT;
4554   return "clr%.w %0\;swap %0";
4555 })
4556
4557 ;; On the 68000, this makes faster code in a special case.
4558
4559 (define_insn "lshrsi_17_24"
4560   [(set (match_operand:SI 0 "register_operand" "=d")
4561         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
4562                      (match_operand:SI 2 "const_int_operand" "n")))]
4563   "(! TARGET_68020 && !TARGET_COLDFIRE
4564     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
4565 {
4566   /* I think lsr%.w sets the CC properly.  */
4567   operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
4568   return "clr%.w %0\;swap %0\;lsr%.w %2,%0";
4569 })
4570
4571 (define_insn "lshrsi3"
4572   [(set (match_operand:SI 0 "register_operand" "=d")
4573         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
4574                      (match_operand:SI 2 "general_operand" "dI")))]
4575   ""
4576   "lsr%.l %2,%0")
4577
4578 (define_insn "lshrhi3"
4579   [(set (match_operand:HI 0 "register_operand" "=d")
4580         (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
4581                      (match_operand:HI 2 "general_operand" "dI")))]
4582   "!TARGET_COLDFIRE"
4583   "lsr%.w %2,%0")
4584
4585 (define_insn ""
4586   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4587         (lshiftrt:HI (match_dup 0)
4588                      (match_operand:HI 1 "general_operand" "dI")))]
4589   "!TARGET_COLDFIRE"
4590   "lsr%.w %1,%0")
4591
4592 (define_insn "lshrqi3"
4593   [(set (match_operand:QI 0 "register_operand" "=d")
4594         (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
4595                      (match_operand:QI 2 "general_operand" "dI")))]
4596   "!TARGET_COLDFIRE"
4597   "lsr%.b %2,%0")
4598
4599 (define_insn ""
4600   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4601         (lshiftrt:QI (match_dup 0)
4602                      (match_operand:QI 1 "general_operand" "dI")))]
4603   "!TARGET_COLDFIRE"
4604   "lsr%.b %1,%0")
4605 \f
4606 ;; rotate instructions
4607
4608 (define_insn "rotlsi3"
4609   [(set (match_operand:SI 0 "register_operand" "=d")
4610         (rotate:SI (match_operand:SI 1 "register_operand" "0")
4611                    (match_operand:SI 2 "general_operand" "dINO")))]
4612   "!TARGET_COLDFIRE"
4613 {
4614   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)
4615     return "swap %0";
4616   else if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 16)
4617     {
4618       operands[2] = GEN_INT (32 - INTVAL (operands[2]));
4619       return "ror%.l %2,%0";
4620     }
4621   else
4622     return "rol%.l %2,%0";
4623 })
4624
4625 (define_insn "rotlhi3"
4626   [(set (match_operand:HI 0 "register_operand" "=d")
4627         (rotate:HI (match_operand:HI 1 "register_operand" "0")
4628                    (match_operand:HI 2 "general_operand" "dIP")))]
4629   "!TARGET_COLDFIRE"
4630 {
4631   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
4632     {
4633       operands[2] = GEN_INT (16 - INTVAL (operands[2]));
4634       return "ror%.w %2,%0";
4635     }
4636   else
4637     return "rol%.w %2,%0";
4638 })
4639
4640 (define_insn ""
4641   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4642         (rotate:HI (match_dup 0)
4643                    (match_operand:HI 1 "general_operand" "dIP")))]
4644   "!TARGET_COLDFIRE"
4645 {
4646   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
4647     {
4648       operands[2] = GEN_INT (16 - INTVAL (operands[2]));
4649       return "ror%.w %2,%0";
4650     }
4651   else
4652     return "rol%.w %2,%0";
4653 })
4654
4655 (define_insn "rotlqi3"
4656   [(set (match_operand:QI 0 "register_operand" "=d")
4657         (rotate:QI (match_operand:QI 1 "register_operand" "0")
4658                    (match_operand:QI 2 "general_operand" "dI")))]
4659   "!TARGET_COLDFIRE"
4660 {
4661   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
4662     {
4663       operands[2] = GEN_INT (8 - INTVAL (operands[2]));
4664       return "ror%.b %2,%0";
4665     }
4666   else
4667     return "rol%.b %2,%0";
4668 })
4669
4670 (define_insn ""
4671   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4672         (rotate:QI (match_dup 0)
4673                    (match_operand:QI 1 "general_operand" "dI")))]
4674   "!TARGET_COLDFIRE"
4675 {
4676   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
4677     {
4678       operands[2] = GEN_INT (8 - INTVAL (operands[2]));
4679       return "ror%.b %2,%0";
4680     }
4681   else
4682     return "rol%.b %2,%0";
4683 })
4684
4685 (define_insn "rotrsi3"
4686   [(set (match_operand:SI 0 "register_operand" "=d")
4687         (rotatert:SI (match_operand:SI 1 "register_operand" "0")
4688                      (match_operand:SI 2 "general_operand" "dI")))]
4689   "!TARGET_COLDFIRE"
4690   "ror%.l %2,%0")
4691
4692 (define_insn "rotrhi3"
4693   [(set (match_operand:HI 0 "register_operand" "=d")
4694         (rotatert:HI (match_operand:HI 1 "register_operand" "0")
4695                      (match_operand:HI 2 "general_operand" "dI")))]
4696   "!TARGET_COLDFIRE"
4697   "ror%.w %2,%0")
4698
4699 (define_insn ""
4700   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4701         (rotatert:HI (match_dup 0)
4702                      (match_operand:HI 1 "general_operand" "dI")))]
4703   "!TARGET_COLDFIRE"
4704   "ror%.w %1,%0")
4705
4706 (define_insn "rotrqi3"
4707   [(set (match_operand:QI 0 "register_operand" "=d")
4708         (rotatert:QI (match_operand:QI 1 "register_operand" "0")
4709                      (match_operand:QI 2 "general_operand" "dI")))]
4710   "!TARGET_COLDFIRE"
4711   "ror%.b %2,%0")
4712
4713 (define_insn ""
4714   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4715         (rotatert:QI (match_dup 0)
4716                      (match_operand:QI 1 "general_operand" "dI")))]
4717   "!TARGET_COLDFIRE"
4718   "ror%.b %1,%0")
4719 \f
4720
4721 ;; Bit set/clear in memory byte.
4722
4723 ;; set bit, bit number is int
4724 (define_insn "bsetmemqi"
4725   [(set (match_operand:QI 0 "memory_operand" "+m")
4726         (ior:QI (subreg:QI (ashift:SI (const_int 1)
4727                 (match_operand:SI 1 "general_operand" "d")) 3)
4728         (match_dup 0)))]
4729   ""
4730 {
4731   CC_STATUS_INIT;
4732   return "bset %1,%0";
4733 })
4734
4735 ;; set bit, bit number is (sign/zero)_extended from HImode/QImode
4736 (define_insn ""
4737   [(set (match_operand:QI 0 "memory_operand" "+m")
4738         (ior:QI (subreg:QI (ashift:SI (const_int 1)
4739             (match_operator:SI 2 "extend_operator"
4740                 [(match_operand 1 "general_operand" "d")])) 3)
4741         (match_dup 0)))]
4742   ""
4743 {
4744   CC_STATUS_INIT;
4745   return "bset %1,%0";
4746 })
4747
4748 ;; clear bit, bit number is int
4749 (define_insn "bclrmemqi"
4750   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
4751         (const_int 1)
4752         (minus:SI (const_int 7)
4753             (match_operand:SI 1 "general_operand" "d")))
4754     (const_int 0))]
4755   ""
4756 {
4757   CC_STATUS_INIT;
4758   return "bclr %1,%0";
4759 })
4760
4761 ;; clear bit, bit number is (sign/zero)_extended from HImode/QImode
4762 (define_insn ""
4763   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
4764         (const_int 1)
4765         (minus:SI (const_int 7)
4766             (match_operator:SI 2 "extend_operator"
4767                 [(match_operand 1 "general_operand" "d")])))
4768     (const_int 0))]
4769   ""
4770 {
4771   CC_STATUS_INIT;
4772   return "bclr %1,%0";
4773 })
4774
4775 ;; Special cases of bit-field insns which we should
4776 ;; recognize in preference to the general case.
4777 ;; These handle aligned 8-bit and 16-bit fields,
4778 ;; which can usually be done with move instructions.
4779
4780 ;
4781 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
4782 ; alignment of structure members is specified.
4783 ;
4784 ; The move is allowed to be odd byte aligned, because that's still faster
4785 ; than an odd byte aligned bit-field instruction.
4786 ;
4787 (define_insn ""
4788   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
4789                          (const_int 32)
4790                          (match_operand:SI 1 "const_int_operand" "n"))
4791         (match_operand:SI 2 "general_src_operand" "rmSi"))]
4792   "TARGET_68020 && TARGET_BITFIELD
4793    && (INTVAL (operands[1]) % 8) == 0
4794    && ! mode_dependent_address_p (XEXP (operands[0], 0))"
4795 {
4796   operands[0]
4797     = adjust_address (operands[0], SImode, INTVAL (operands[1]) / 8);
4798
4799   return "move%.l %2,%0";
4800 })
4801
4802 (define_insn ""
4803   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+do")
4804                          (match_operand:SI 1 "const_int_operand" "n")
4805                          (match_operand:SI 2 "const_int_operand" "n"))
4806         (match_operand:SI 3 "register_operand" "d"))]
4807   "TARGET_68020 && TARGET_BITFIELD
4808    && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
4809    && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
4810    && (GET_CODE (operands[0]) == REG
4811        || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
4812 {
4813   if (REG_P (operands[0]))
4814     {
4815       if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
4816         return "bfins %3,%0{%b2:%b1}";
4817     }
4818   else
4819     operands[0] = adjust_address (operands[0],
4820                                   INTVAL (operands[1]) == 8 ? QImode : HImode,
4821                                   INTVAL (operands[2]) / 8);
4822
4823   if (GET_CODE (operands[3]) == MEM)
4824     operands[3] = adjust_address (operands[3],
4825                                   INTVAL (operands[1]) == 8 ? QImode : HImode,
4826                                   (32 - INTVAL (operands[1])) / 8);
4827
4828   if (INTVAL (operands[1]) == 8)
4829     return "move%.b %3,%0";
4830   return "move%.w %3,%0";
4831 })
4832
4833
4834 ;
4835 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
4836 ; alignment of structure members is specified.
4837 ;
4838 ; The move is allowed to be odd byte aligned, because that's still faster
4839 ; than an odd byte aligned bit-field instruction.
4840 ;
4841 (define_insn ""
4842   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4843         (zero_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
4844                          (const_int 32)
4845                          (match_operand:SI 2 "const_int_operand" "n")))]
4846   "TARGET_68020 && TARGET_BITFIELD
4847    && (INTVAL (operands[2]) % 8) == 0
4848    && ! mode_dependent_address_p (XEXP (operands[1], 0))"
4849 {
4850   operands[1]
4851     = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8);
4852
4853   return "move%.l %1,%0";
4854 })
4855
4856 (define_insn ""
4857   [(set (match_operand:SI 0 "nonimmediate_operand" "=&d")
4858         (zero_extract:SI (match_operand:SI 1 "register_operand" "do")
4859                          (match_operand:SI 2 "const_int_operand" "n")
4860                          (match_operand:SI 3 "const_int_operand" "n")))]
4861   "TARGET_68020 && TARGET_BITFIELD
4862    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
4863    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
4864    && (GET_CODE (operands[1]) == REG
4865        || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
4866 {
4867   cc_status.flags |= CC_NOT_NEGATIVE;
4868   if (REG_P (operands[1]))
4869     {
4870       if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
4871         return "bfextu %1{%b3:%b2},%0";
4872     }
4873   else
4874     operands[1]
4875       = adjust_address (operands[1], SImode, INTVAL (operands[3]) / 8);
4876
4877   output_asm_insn ("clr%.l %0", operands);
4878   if (GET_CODE (operands[0]) == MEM)
4879     operands[0] = adjust_address (operands[0],
4880                                   INTVAL (operands[2]) == 8 ? QImode : HImode,
4881                                   (32 - INTVAL (operands[1])) / 8);
4882
4883   if (INTVAL (operands[2]) == 8)
4884     return "move%.b %1,%0";
4885   return "move%.w %1,%0";
4886 })
4887
4888 ;
4889 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
4890 ; alignment of structure members is specified.
4891 ;
4892 ; The move is allowed to be odd byte aligned, because that's still faster
4893 ; than an odd byte aligned bit-field instruction.
4894 ;
4895 (define_insn ""
4896   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4897         (sign_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
4898                          (const_int 32)
4899                          (match_operand:SI 2 "const_int_operand" "n")))]
4900   "TARGET_68020 && TARGET_BITFIELD
4901    && (INTVAL (operands[2]) % 8) == 0
4902    && ! mode_dependent_address_p (XEXP (operands[1], 0))"
4903 {
4904   operands[1]
4905     = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8);
4906
4907   return "move%.l %1,%0";
4908 })
4909
4910 (define_insn ""
4911   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4912         (sign_extract:SI (match_operand:SI 1 "register_operand" "do")
4913                          (match_operand:SI 2 "const_int_operand" "n")
4914                          (match_operand:SI 3 "const_int_operand" "n")))]
4915   "TARGET_68020 && TARGET_BITFIELD
4916    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
4917    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
4918    && (GET_CODE (operands[1]) == REG
4919        || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
4920 {
4921   if (REG_P (operands[1]))
4922     {
4923       if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
4924         return "bfexts %1{%b3:%b2},%0";
4925     }
4926   else
4927     operands[1]
4928       = adjust_address (operands[1],
4929                         INTVAL (operands[2]) == 8 ? QImode : HImode,
4930                         INTVAL (operands[3]) / 8);
4931
4932   if (INTVAL (operands[2]) == 8)
4933     return "move%.b %1,%0\;extb%.l %0";
4934   return "move%.w %1,%0\;ext%.l %0";
4935 })
4936 \f
4937 ;; Bit-field instructions, general cases.
4938 ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
4939 ;; so that its address is reloaded.
4940
4941 (define_expand "extv"
4942   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4943         (sign_extract:SI (match_operand:SI 1 "general_operand" "")
4944                          (match_operand:SI 2 "general_operand" "")
4945                          (match_operand:SI 3 "general_operand" "")))]
4946   "TARGET_68020 && TARGET_BITFIELD"
4947   "")
4948
4949 (define_insn ""
4950   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4951         (sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
4952                          (match_operand:SI 2 "general_operand" "dn")
4953                          (match_operand:SI 3 "general_operand" "dn")))]
4954   "TARGET_68020 && TARGET_BITFIELD"
4955   "bfexts %1{%b3:%b2},%0")
4956
4957 (define_expand "extzv"
4958   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4959         (zero_extract:SI (match_operand:SI 1 "general_operand" "")
4960                          (match_operand:SI 2 "general_operand" "")
4961                          (match_operand:SI 3 "general_operand" "")))]
4962   "TARGET_68020 && TARGET_BITFIELD"
4963   "")
4964
4965 (define_insn ""
4966   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d")
4967         (zero_extract:SI (match_operand:QI 1 "memory_operand" "o,d")
4968                          (match_operand:SI 2 "general_operand" "dn,dn")
4969                          (match_operand:SI 3 "general_operand" "dn,dn")))]
4970   "TARGET_68020 && TARGET_BITFIELD"
4971 {
4972   if (GET_CODE (operands[2]) == CONST_INT)
4973     {
4974       if (INTVAL (operands[2]) != 32)
4975         cc_status.flags |= CC_NOT_NEGATIVE;
4976     }
4977   else
4978     {
4979       CC_STATUS_INIT;
4980     }
4981   return "bfextu %1{%b3:%b2},%0";
4982 })
4983
4984 (define_insn ""
4985   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
4986                          (match_operand:SI 1 "general_operand" "dn")
4987                          (match_operand:SI 2 "general_operand" "dn"))
4988         (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
4989                 (match_operand 3 "const_int_operand" "n")))]
4990   "TARGET_68020 && TARGET_BITFIELD
4991    && (INTVAL (operands[3]) == -1
4992        || (GET_CODE (operands[1]) == CONST_INT
4993            && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
4994 {
4995   CC_STATUS_INIT;
4996   return "bfchg %0{%b2:%b1}";
4997 })
4998
4999 (define_insn ""
5000   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5001                          (match_operand:SI 1 "general_operand" "dn")
5002                          (match_operand:SI 2 "general_operand" "dn"))
5003         (const_int 0))]
5004   "TARGET_68020 && TARGET_BITFIELD"
5005 {
5006   CC_STATUS_INIT;
5007   return "bfclr %0{%b2:%b1}";
5008 })
5009
5010 (define_insn ""
5011   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5012                          (match_operand:SI 1 "general_operand" "dn")
5013                          (match_operand:SI 2 "general_operand" "dn"))
5014         (const_int -1))]
5015   "TARGET_68020 && TARGET_BITFIELD"
5016 {
5017   CC_STATUS_INIT;
5018   return "bfset %0{%b2:%b1}";
5019 })
5020
5021 (define_expand "insv"
5022   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "")
5023                          (match_operand:SI 1 "general_operand" "")
5024                          (match_operand:SI 2 "general_operand" ""))
5025         (match_operand:SI 3 "register_operand" ""))]
5026   "TARGET_68020 && TARGET_BITFIELD"
5027   "")
5028
5029 (define_insn ""
5030   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5031                          (match_operand:SI 1 "general_operand" "dn")
5032                          (match_operand:SI 2 "general_operand" "dn"))
5033         (match_operand:SI 3 "register_operand" "d"))]
5034   "TARGET_68020 && TARGET_BITFIELD"
5035   "bfins %3,%0{%b2:%b1}")
5036
5037 ;; Now recognize bit-field insns that operate on registers
5038 ;; (or at least were intended to do so).
5039
5040 (define_insn ""
5041   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
5042         (sign_extract:SI (match_operand:SI 1 "register_operand" "d")
5043                          (match_operand:SI 2 "general_operand" "dn")
5044                          (match_operand:SI 3 "general_operand" "dn")))]
5045   "TARGET_68020 && TARGET_BITFIELD"
5046   "bfexts %1{%b3:%b2},%0")
5047
5048 (define_insn ""
5049   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
5050         (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
5051                          (match_operand:SI 2 "general_operand" "dn")
5052                          (match_operand:SI 3 "general_operand" "dn")))]
5053   "TARGET_68020 && TARGET_BITFIELD"
5054 {
5055   if (GET_CODE (operands[2]) == CONST_INT)
5056     {
5057       if (INTVAL (operands[2]) != 32)
5058         cc_status.flags |= CC_NOT_NEGATIVE;
5059     }
5060   else
5061     {
5062       CC_STATUS_INIT;
5063     }
5064   return "bfextu %1{%b3:%b2},%0";
5065 })
5066
5067 (define_insn ""
5068   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5069                          (match_operand:SI 1 "general_operand" "dn")
5070                          (match_operand:SI 2 "general_operand" "dn"))
5071         (const_int 0))]
5072   "TARGET_68020 && TARGET_BITFIELD"
5073 {
5074   CC_STATUS_INIT;
5075   return "bfclr %0{%b2:%b1}";
5076 })
5077
5078 (define_insn ""
5079   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5080                          (match_operand:SI 1 "general_operand" "dn")
5081                          (match_operand:SI 2 "general_operand" "dn"))
5082         (const_int -1))]
5083   "TARGET_68020 && TARGET_BITFIELD"
5084 {
5085   CC_STATUS_INIT;
5086   return "bfset %0{%b2:%b1}";
5087 })
5088
5089 (define_insn ""
5090   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5091                          (match_operand:SI 1 "general_operand" "dn")
5092                          (match_operand:SI 2 "general_operand" "dn"))
5093         (match_operand:SI 3 "register_operand" "d"))]
5094   "TARGET_68020 && TARGET_BITFIELD"
5095 {
5096 #if 0
5097   /* These special cases are now recognized by a specific pattern.  */
5098   if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
5099       && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
5100     return "move%.w %3,%0";
5101   if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
5102       && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
5103     return "move%.b %3,%0";
5104 #endif
5105   return "bfins %3,%0{%b2:%b1}";
5106 })
5107 \f
5108 ;; Special patterns for optimizing bit-field instructions.
5109
5110 (define_insn ""
5111   [(set (cc0)
5112         (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
5113                          (match_operand:SI 1 "const_int_operand" "n")
5114                          (match_operand:SI 2 "general_operand" "dn")))]
5115   "TARGET_68020 && TARGET_BITFIELD"
5116 {
5117   if (operands[1] == const1_rtx
5118       && GET_CODE (operands[2]) == CONST_INT)
5119     {
5120       int width = GET_CODE (operands[0]) == REG ? 31 : 7;
5121       return output_btst (operands,
5122                           GEN_INT (width - INTVAL (operands[2])),
5123                           operands[0], insn, 1000);
5124       /* Pass 1000 as SIGNPOS argument so that btst will
5125          not think we are testing the sign bit for an `and'
5126          and assume that nonzero implies a negative result.  */
5127     }
5128   if (INTVAL (operands[1]) != 32)
5129     cc_status.flags = CC_NOT_NEGATIVE;
5130   return "bftst %0{%b2:%b1}";
5131 })
5132
5133
5134 ;;; now handle the register cases
5135 (define_insn ""
5136   [(set (cc0)
5137         (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
5138                          (match_operand:SI 1 "const_int_operand" "n")
5139                          (match_operand:SI 2 "general_operand" "dn")))]
5140   "TARGET_68020 && TARGET_BITFIELD"
5141 {
5142   if (operands[1] == const1_rtx
5143       && GET_CODE (operands[2]) == CONST_INT)
5144     {
5145       int width = GET_CODE (operands[0]) == REG ? 31 : 7;
5146       return output_btst (operands, GEN_INT (width - INTVAL (operands[2])),
5147                           operands[0], insn, 1000);
5148       /* Pass 1000 as SIGNPOS argument so that btst will
5149          not think we are testing the sign bit for an `and'
5150          and assume that nonzero implies a negative result.  */
5151     }
5152   if (INTVAL (operands[1]) != 32)
5153     cc_status.flags = CC_NOT_NEGATIVE;
5154   return "bftst %0{%b2:%b1}";
5155 })
5156 \f
5157 (define_insn "scc0_di"
5158   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
5159     (match_operator 1 "valid_dbcc_comparison_p"
5160       [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
5161   "! TARGET_COLDFIRE"
5162 {
5163   return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
5164 })
5165
5166 (define_insn "scc0_di_5200"
5167   [(set (match_operand:QI 0 "nonimmediate_operand" "=d")
5168     (match_operator 1 "valid_dbcc_comparison_p"
5169       [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
5170   "TARGET_COLDFIRE"
5171 {
5172   return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
5173 })
5174
5175 (define_insn "scc_di"
5176   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,dm")
5177     (match_operator 1 "valid_dbcc_comparison_p"
5178       [(match_operand:DI 2 "general_operand" "ro,r")
5179        (match_operand:DI 3 "general_operand" "r,ro")]))]
5180   "! TARGET_COLDFIRE"
5181 {
5182   return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
5183 })
5184
5185 (define_insn "scc_di_5200"
5186   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d")
5187     (match_operator 1 "valid_dbcc_comparison_p"
5188       [(match_operand:DI 2 "general_operand" "ro,r")
5189        (match_operand:DI 3 "general_operand" "r,ro")]))]
5190   "TARGET_COLDFIRE"
5191 {
5192   return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
5193 })
5194
5195 ;; Note that operand 0 of an SCC insn is supported in the hardware as
5196 ;; memory, but we cannot allow it to be in memory in case the address
5197 ;; needs to be reloaded.
5198
5199 (define_expand "seq"
5200   [(set (match_operand:QI 0 "register_operand" "")
5201         (eq:QI (cc0) (const_int 0)))]
5202   ""
5203 {
5204   if ((TARGET_68060 || TARGET_COLDFIRE_FPU)
5205       && m68k_last_compare_had_fp_operands)
5206     {
5207       m68k_last_compare_had_fp_operands = 0;
5208       FAIL;
5209     }
5210 })
5211
5212 (define_insn ""
5213   [(set (match_operand:QI 0 "register_operand" "=d")
5214         (eq:QI (cc0) (const_int 0)))]
5215   ""
5216 {
5217   cc_status = cc_prev_status;
5218   OUTPUT_JUMP ("seq %0", "fseq %0", "seq %0");
5219 })
5220
5221 (define_expand "sne"
5222   [(set (match_operand:QI 0 "register_operand" "")
5223         (ne:QI (cc0) (const_int 0)))]
5224   ""
5225 {
5226   if ((TARGET_68060 || TARGET_COLDFIRE_FPU)
5227       && m68k_last_compare_had_fp_operands)
5228     {
5229       m68k_last_compare_had_fp_operands = 0;
5230       FAIL;
5231     }
5232 })
5233
5234 (define_insn ""
5235   [(set (match_operand:QI 0 "register_operand" "=d")
5236         (ne:QI (cc0) (const_int 0)))]
5237   ""
5238 {
5239   cc_status = cc_prev_status;
5240   OUTPUT_JUMP ("sne %0", "fsne %0", "sne %0");
5241 })
5242
5243 (define_expand "sgt"
5244   [(set (match_operand:QI 0 "register_operand" "")
5245         (gt:QI (cc0) (const_int 0)))]
5246   ""
5247 {
5248   if ((TARGET_68060 || TARGET_COLDFIRE_FPU)
5249       && m68k_last_compare_had_fp_operands)
5250     {
5251       m68k_last_compare_had_fp_operands = 0;
5252       FAIL;
5253     }
5254 })
5255
5256 (define_insn ""
5257   [(set (match_operand:QI 0 "register_operand" "=d")
5258         (gt:QI (cc0) (const_int 0)))]
5259   ""
5260 {
5261   cc_status = cc_prev_status;
5262   OUTPUT_JUMP ("sgt %0", "fsgt %0", 0);
5263 })
5264
5265 (define_expand "sgtu"
5266   [(set (match_operand:QI 0 "register_operand" "")
5267         (gtu:QI (cc0) (const_int 0)))]
5268   ""
5269   "")
5270
5271 (define_insn ""
5272   [(set (match_operand:QI 0 "register_operand" "=d")
5273         (gtu:QI (cc0) (const_int 0)))]
5274   ""
5275 {
5276   cc_status = cc_prev_status;
5277   return "shi %0";
5278 })
5279
5280 (define_expand "slt"
5281   [(set (match_operand:QI 0 "register_operand" "")
5282         (lt:QI (cc0) (const_int 0)))]
5283   ""
5284 {
5285   if ((TARGET_68060 || TARGET_COLDFIRE_FPU)
5286       && m68k_last_compare_had_fp_operands)
5287     {
5288       m68k_last_compare_had_fp_operands = 0;
5289       FAIL;
5290     }
5291 })
5292
5293 (define_insn ""
5294   [(set (match_operand:QI 0 "register_operand" "=d")
5295         (lt:QI (cc0) (const_int 0)))]
5296   ""
5297 {
5298    cc_status = cc_prev_status;
5299    OUTPUT_JUMP ("slt %0", "fslt %0", "smi %0");
5300 })
5301
5302 (define_expand "sltu"
5303   [(set (match_operand:QI 0 "register_operand" "")
5304         (ltu:QI (cc0) (const_int 0)))]
5305   ""
5306   "")
5307
5308 (define_insn ""
5309   [(set (match_operand:QI 0 "register_operand" "=d")
5310         (ltu:QI (cc0) (const_int 0)))]
5311   ""
5312 {
5313    cc_status = cc_prev_status;
5314    return "scs %0";
5315 })
5316
5317 (define_expand "sge"
5318   [(set (match_operand:QI 0 "register_operand" "")
5319         (ge:QI (cc0) (const_int 0)))]
5320   ""
5321 {
5322   if ((TARGET_68060 || TARGET_COLDFIRE_FPU)
5323       && m68k_last_compare_had_fp_operands)
5324     {
5325       m68k_last_compare_had_fp_operands = 0;
5326       FAIL;
5327     }
5328 })
5329
5330 (define_insn ""
5331   [(set (match_operand:QI 0 "register_operand" "=d")
5332         (ge:QI (cc0) (const_int 0)))]
5333   ""
5334 {
5335    cc_status = cc_prev_status;
5336    OUTPUT_JUMP ("sge %0", "fsge %0", "spl %0");
5337 })
5338
5339 (define_expand "sgeu"
5340   [(set (match_operand:QI 0 "register_operand" "")
5341         (geu:QI (cc0) (const_int 0)))]
5342   ""
5343   "")
5344
5345 (define_insn ""
5346   [(set (match_operand:QI 0 "register_operand" "=d")
5347         (geu:QI (cc0) (const_int 0)))]
5348   ""
5349 {
5350    cc_status = cc_prev_status;
5351    return "scc %0";
5352 })
5353
5354 (define_expand "sle"
5355   [(set (match_operand:QI 0 "register_operand" "")
5356         (le:QI (cc0) (const_int 0)))]
5357   ""
5358 {
5359   if ((TARGET_68060 || TARGET_COLDFIRE_FPU)
5360       && m68k_last_compare_had_fp_operands)
5361     {
5362       m68k_last_compare_had_fp_operands = 0;
5363       FAIL;
5364     }
5365 })
5366
5367 (define_insn ""
5368   [(set (match_operand:QI 0 "register_operand" "=d")
5369         (le:QI (cc0) (const_int 0)))]
5370   ""
5371 {
5372   cc_status = cc_prev_status;
5373   OUTPUT_JUMP ("sle %0", "fsle %0", 0);
5374 })
5375
5376 (define_expand "sleu"
5377   [(set (match_operand:QI 0 "register_operand" "")
5378         (leu:QI (cc0) (const_int 0)))]
5379   ""
5380   "")
5381
5382 (define_insn ""
5383   [(set (match_operand:QI 0 "register_operand" "=d")
5384         (leu:QI (cc0) (const_int 0)))]
5385   ""
5386 {
5387    cc_status = cc_prev_status;
5388    return "sls %0";
5389 })
5390
5391 (define_expand "sordered"
5392   [(set (match_operand:QI 0 "register_operand" "")
5393         (ordered:QI (cc0) (const_int 0)))]
5394   "TARGET_68881 && !TARGET_68060"
5395 {
5396   gcc_assert (m68k_last_compare_had_fp_operands);
5397   m68k_last_compare_had_fp_operands = 0;
5398 })
5399
5400 (define_insn "*sordered_1"
5401   [(set (match_operand:QI 0 "register_operand" "=d")
5402         (ordered:QI (cc0) (const_int 0)))]
5403   "TARGET_68881 && !TARGET_68060"
5404 {
5405   cc_status = cc_prev_status;
5406   return "fsor %0";
5407 })
5408
5409 (define_expand "sunordered"
5410   [(set (match_operand:QI 0 "register_operand" "")
5411         (unordered:QI (cc0) (const_int 0)))]
5412   "TARGET_68881 && !TARGET_68060"
5413 {
5414   gcc_assert (m68k_last_compare_had_fp_operands);
5415   m68k_last_compare_had_fp_operands = 0;
5416 })
5417
5418 (define_insn "*sunordered_1"
5419   [(set (match_operand:QI 0 "register_operand" "=d")
5420         (unordered:QI (cc0) (const_int 0)))]
5421   "TARGET_68881 && !TARGET_68060"
5422 {
5423   cc_status = cc_prev_status;
5424   return "fsun %0";
5425 })
5426
5427 (define_expand "suneq"
5428   [(set (match_operand:QI 0 "register_operand" "")
5429         (uneq:QI (cc0) (const_int 0)))]
5430   "TARGET_68881 && !TARGET_68060"
5431 {
5432   gcc_assert (m68k_last_compare_had_fp_operands);
5433   m68k_last_compare_had_fp_operands = 0;
5434 })
5435
5436 (define_insn "*suneq_1"
5437   [(set (match_operand:QI 0 "register_operand" "=d")
5438         (uneq:QI (cc0) (const_int 0)))]
5439   "TARGET_68881 && !TARGET_68060"
5440 {
5441   cc_status = cc_prev_status;
5442   return "fsueq %0";
5443 })
5444
5445 (define_expand "sunge"
5446   [(set (match_operand:QI 0 "register_operand" "")
5447         (unge:QI (cc0) (const_int 0)))]
5448   "TARGET_68881 && !TARGET_68060"
5449 {
5450   gcc_assert (m68k_last_compare_had_fp_operands);
5451   m68k_last_compare_had_fp_operands = 0;
5452 })
5453
5454 (define_insn "*sunge_1"
5455   [(set (match_operand:QI 0 "register_operand" "=d")
5456         (unge:QI (cc0) (const_int 0)))]
5457   "TARGET_68881 && !TARGET_68060"
5458 {
5459   cc_status = cc_prev_status;
5460   return "fsuge %0";
5461 })
5462
5463 (define_expand "sungt"
5464   [(set (match_operand:QI 0 "register_operand" "")
5465         (ungt:QI (cc0) (const_int 0)))]
5466   "TARGET_68881 && !TARGET_68060"
5467 {
5468   gcc_assert (m68k_last_compare_had_fp_operands);
5469   m68k_last_compare_had_fp_operands = 0;
5470 })
5471
5472 (define_insn "*sungt_1"
5473   [(set (match_operand:QI 0 "register_operand" "=d")
5474         (ungt:QI (cc0) (const_int 0)))]
5475   "TARGET_68881 && !TARGET_68060"
5476 {
5477   cc_status = cc_prev_status;
5478   return "fsugt %0";
5479 })
5480
5481 (define_expand "sunle"
5482   [(set (match_operand:QI 0 "register_operand" "")
5483         (unle:QI (cc0) (const_int 0)))]
5484   "TARGET_68881 && !TARGET_68060"
5485 {
5486   gcc_assert (m68k_last_compare_had_fp_operands);
5487   m68k_last_compare_had_fp_operands = 0;
5488 })
5489
5490 (define_insn "*sunle_1"
5491   [(set (match_operand:QI 0 "register_operand" "=d")
5492         (unle:QI (cc0) (const_int 0)))]
5493   "TARGET_68881 && !TARGET_68060"
5494 {
5495   cc_status = cc_prev_status;
5496   return "fsule %0";
5497 })
5498
5499 (define_expand "sunlt"
5500   [(set (match_operand:QI 0 "register_operand" "")
5501         (unlt:QI (cc0) (const_int 0)))]
5502   "TARGET_68881 && !TARGET_68060"
5503 {
5504   gcc_assert (m68k_last_compare_had_fp_operands);
5505   m68k_last_compare_had_fp_operands = 0;
5506 })
5507
5508 (define_insn "*sunlt_1"
5509   [(set (match_operand:QI 0 "register_operand" "=d")
5510         (unlt:QI (cc0) (const_int 0)))]
5511   "TARGET_68881 && !TARGET_68060"
5512 {
5513   cc_status = cc_prev_status;
5514   return "fsult %0";
5515 })
5516
5517 (define_expand "sltgt"
5518   [(set (match_operand:QI 0 "register_operand" "")
5519         (ltgt:QI (cc0) (const_int 0)))]
5520   "TARGET_68881 && !TARGET_68060"
5521 {
5522   gcc_assert (m68k_last_compare_had_fp_operands);
5523   m68k_last_compare_had_fp_operands = 0;
5524 })
5525
5526 (define_insn "*sltgt_1"
5527   [(set (match_operand:QI 0 "register_operand" "=d")
5528         (ltgt:QI (cc0) (const_int 0)))]
5529   "TARGET_68881 && !TARGET_68060"
5530 {
5531   cc_status = cc_prev_status;
5532   return "fsogl %0";
5533 })
5534
5535 (define_insn "*fsogt_1"
5536   [(set (match_operand:QI 0 "register_operand" "=d")
5537         (not:QI (unle:QI (cc0) (const_int 0))))]
5538   "TARGET_68881 && !TARGET_68060"
5539 {
5540   cc_status = cc_prev_status;
5541   return "fsogt %0";
5542 })
5543
5544 (define_insn "*fsoge_1"
5545   [(set (match_operand:QI 0 "register_operand" "=d")
5546         (not:QI (unlt:QI (cc0) (const_int 0))))]
5547   "TARGET_68881 && !TARGET_68060"
5548 {
5549   cc_status = cc_prev_status;
5550   return "fsoge %0";
5551 })
5552
5553 (define_insn "*fsolt_1"
5554   [(set (match_operand:QI 0 "register_operand" "=d")
5555         (not:QI (unge:QI (cc0) (const_int 0))))]
5556   "TARGET_68881 && !TARGET_68060"
5557 {
5558   cc_status = cc_prev_status;
5559   return "fsolt %0";
5560 })
5561
5562 (define_insn "*fsole_1"
5563   [(set (match_operand:QI 0 "register_operand" "=d")
5564         (not:QI (ungt:QI (cc0) (const_int 0))))]
5565   "TARGET_68881 && !TARGET_68060"
5566 {
5567   cc_status = cc_prev_status;
5568   return "fsole %0";
5569 })
5570 \f
5571 ;; Basic conditional jump instructions.
5572
5573 (define_insn "beq0_di"
5574   [(set (pc)
5575     (if_then_else (eq (match_operand:DI 0 "general_operand" "d*ao,<>")
5576             (const_int 0))
5577         (label_ref (match_operand 1 "" ","))
5578         (pc)))
5579    (clobber (match_scratch:SI 2 "=d,d"))]
5580   ""
5581 {
5582   CC_STATUS_INIT;
5583   if (which_alternative == 1)
5584     {
5585       if (MOTOROLA)
5586         return "move%.l %0,%2\;or%.l %0,%2\;jbeq %l1";
5587       else
5588         return "move%.l %0,%2\;or%.l %0,%2\;jeq %l1";
5589     }
5590   if ((cc_prev_status.value1
5591       && rtx_equal_p (cc_prev_status.value1, operands[0]))
5592     || (cc_prev_status.value2
5593       && rtx_equal_p (cc_prev_status.value2, operands[0])))
5594     {
5595       cc_status = cc_prev_status;
5596       return MOTOROLA ? "jbeq %l1" : "jeq %l1";
5597     }
5598   if (GET_CODE (operands[0]) == REG)
5599     operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
5600   else
5601     operands[3] = adjust_address (operands[0], SImode, 4);
5602   if (! ADDRESS_REG_P (operands[0]))
5603     {
5604       if (reg_overlap_mentioned_p (operands[2], operands[0]))
5605         {
5606           if (reg_overlap_mentioned_p (operands[2], operands[3]))
5607             {
5608               if (MOTOROLA)
5609                 return "or%.l %0,%2\;jbeq %l1";
5610               else
5611                 return "or%.l %0,%2\;jeq %l1";
5612             }
5613           else
5614             {
5615               if (MOTOROLA)
5616                 return "or%.l %3,%2\;jbeq %l1";
5617               else
5618                 return "or%.l %3,%2\;jeq %l1";
5619             }
5620         }
5621       if (MOTOROLA)
5622         return "move%.l %0,%2\;or%.l %3,%2\;jbeq %l1";
5623       else
5624         return "move%.l %0,%2\;or%.l %3,%2\;jeq %l1";
5625     }
5626   operands[4] = gen_label_rtx();
5627   if (TARGET_68020 || TARGET_COLDFIRE)
5628     {
5629       if (MOTOROLA)
5630         output_asm_insn ("tst%.l %0\;jbne %l4\;tst%.l %3\;jbeq %l1", operands);
5631       else
5632         output_asm_insn ("tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1", operands);
5633     }
5634   else
5635     {
5636       if (MOTOROLA)
5637         output_asm_insn ("cmp%.w #0,%0\;jbne %l4\;cmp%.w #0,%3\;jbeq %l1", operands);
5638       else
5639         output_asm_insn ("cmp%.w #0,%0\;jne %l4\;cmp%.w #0,%3\;jeq %l1", operands);
5640     }
5641   (*targetm.asm_out.internal_label) (asm_out_file, "L",
5642                                 CODE_LABEL_NUMBER (operands[4]));
5643   return "";
5644 })
5645
5646 (define_insn "bne0_di"
5647   [(set (pc)
5648     (if_then_else (ne (match_operand:DI 0 "general_operand" "do,*a")
5649             (const_int 0))
5650         (label_ref (match_operand 1 "" ","))
5651         (pc)))
5652    (clobber (match_scratch:SI 2 "=d,X"))]
5653   ""
5654 {
5655   if ((cc_prev_status.value1
5656       && rtx_equal_p (cc_prev_status.value1, operands[0]))
5657     || (cc_prev_status.value2
5658       && rtx_equal_p (cc_prev_status.value2, operands[0])))
5659     {
5660       cc_status = cc_prev_status;
5661       return MOTOROLA ? "jbne %l1" : "jne %l1";
5662     }
5663   CC_STATUS_INIT;
5664   if (GET_CODE (operands[0]) == REG)
5665     operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
5666   else
5667     operands[3] = adjust_address (operands[0], SImode, 4);
5668   if (!ADDRESS_REG_P (operands[0]))
5669     {
5670       if (reg_overlap_mentioned_p (operands[2], operands[0]))
5671         {
5672           if (reg_overlap_mentioned_p (operands[2], operands[3]))
5673             {
5674               if (MOTOROLA)
5675                 return "or%.l %0,%2\;jbne %l1";
5676               else
5677                 return "or%.l %0,%2\;jne %l1";
5678             }
5679           else
5680             {
5681               if (MOTOROLA)
5682                 return "or%.l %3,%2\;jbne %l1";
5683               else
5684                 return "or%.l %3,%2\;jne %l1";
5685             }
5686         }
5687       if (MOTOROLA)
5688         return "move%.l %0,%2\;or%.l %3,%2\;jbne %l1";
5689       else
5690         return "move%.l %0,%2\;or%.l %3,%2\;jne %l1";
5691     }
5692   if (TARGET_68020 || TARGET_COLDFIRE)
5693     {
5694       if (MOTOROLA)
5695         return "tst%.l %0\;jbne %l1\;tst%.l %3\;jbne %l1";
5696       else
5697         return "tst%.l %0\;jne %l1\;tst%.l %3\;jne %l1";
5698     }
5699   else
5700     {
5701       if (MOTOROLA)
5702         return "cmp%.w #0,%0\;jbne %l1\;cmp%.w #0,%3\;jbne %l1";
5703       else
5704         return "cmp%.w #0,%0\;jne %l1\;cmp%.w #0,%3\;jne %l1";
5705     }
5706 })
5707
5708 (define_insn "bge0_di"
5709   [(set (pc)
5710     (if_then_else (ge (match_operand:DI 0 "general_operand" "ro")
5711             (const_int 0))
5712         (label_ref (match_operand 1 "" ""))
5713         (pc)))]
5714   ""
5715 {
5716   if ((cc_prev_status.value1
5717       && rtx_equal_p (cc_prev_status.value1, operands[0]))
5718     || (cc_prev_status.value2
5719       && rtx_equal_p (cc_prev_status.value2, operands[0])))
5720     {
5721       cc_status = cc_prev_status;
5722       if (cc_status.flags & CC_REVERSED)
5723         {
5724           return MOTOROLA ? "jble %l1" : "jle %l1";
5725         }
5726       else
5727         {
5728           return MOTOROLA ? "jbpl %l1" : "jpl %l1";
5729         }
5730     }
5731   CC_STATUS_INIT;
5732   if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0]))
5733     output_asm_insn("tst%.l %0", operands);
5734   else
5735     {
5736       /* On an address reg, cmpw may replace cmpl.  */
5737       output_asm_insn("cmp%.w #0,%0", operands);
5738     }
5739   return MOTOROLA ? "jbpl %l1" : "jpl %l1";
5740 })
5741
5742 (define_insn "blt0_di"
5743   [(set (pc)
5744     (if_then_else (lt (match_operand:DI 0 "general_operand" "ro")
5745             (const_int 0))
5746         (label_ref (match_operand 1 "" ""))
5747         (pc)))]
5748   ""
5749 {
5750   if ((cc_prev_status.value1
5751       && rtx_equal_p (cc_prev_status.value1, operands[0]))
5752     || (cc_prev_status.value2
5753       && rtx_equal_p (cc_prev_status.value2, operands[0])))
5754     {
5755       cc_status = cc_prev_status;
5756       if (cc_status.flags & CC_REVERSED)
5757         {
5758           return MOTOROLA ? "jbgt %l1" : "jgt %l1";
5759         }
5760       else
5761         {
5762           return MOTOROLA ? "jbmi %l1" : "jmi %l1";
5763         }
5764     }
5765   CC_STATUS_INIT;
5766   if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0]))
5767     output_asm_insn("tst%.l %0", operands);
5768   else
5769     {
5770       /* On an address reg, cmpw may replace cmpl.  */
5771       output_asm_insn("cmp%.w #0,%0", operands);
5772     }
5773
5774   return MOTOROLA ? "jbmi %l1" : "jmi %l1";
5775 })
5776
5777 (define_insn "beq"
5778   [(set (pc)
5779         (if_then_else (eq (cc0)
5780                           (const_int 0))
5781                       (label_ref (match_operand 0 "" ""))
5782                       (pc)))]
5783   ""
5784 {
5785   if (MOTOROLA)
5786     OUTPUT_JUMP ("jbeq %l0", "fbeq %l0", "jbeq %l0");
5787   else
5788     OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
5789 })
5790
5791 (define_insn "bne"
5792   [(set (pc)
5793         (if_then_else (ne (cc0)
5794                           (const_int 0))
5795                       (label_ref (match_operand 0 "" ""))
5796                       (pc)))]
5797   ""
5798 {
5799   if (MOTOROLA)
5800     OUTPUT_JUMP ("jbne %l0", "fbne %l0", "jbne %l0");
5801   else
5802     OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
5803 })
5804
5805 (define_insn "bgt"
5806   [(set (pc)
5807         (if_then_else (gt (cc0)
5808                           (const_int 0))
5809                       (label_ref (match_operand 0 "" ""))
5810                       (pc)))]
5811   ""
5812 {
5813   if (MOTOROLA)
5814     OUTPUT_JUMP ("jbgt %l0", "fbgt %l0", 0);
5815   else
5816     OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0);
5817 })
5818
5819 (define_insn "bgtu"
5820   [(set (pc)
5821         (if_then_else (gtu (cc0)
5822                            (const_int 0))
5823                       (label_ref (match_operand 0 "" ""))
5824                       (pc)))]
5825   ""
5826 {
5827   return MOTOROLA ? "jbhi %l0" : "jhi %l0";
5828 })
5829
5830 (define_insn "blt"
5831   [(set (pc)
5832         (if_then_else (lt (cc0)
5833                           (const_int 0))
5834                       (label_ref (match_operand 0 "" ""))
5835                       (pc)))]
5836   ""
5837 {
5838   if (MOTOROLA)
5839     OUTPUT_JUMP ("jblt %l0", "fblt %l0", "jbmi %l0");
5840   else
5841     OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0");
5842 })
5843
5844 (define_insn "bltu"
5845   [(set (pc)
5846         (if_then_else (ltu (cc0)
5847                            (const_int 0))
5848                       (label_ref (match_operand 0 "" ""))
5849                       (pc)))]
5850   ""
5851 {
5852   return MOTOROLA ? "jbcs %l0" : "jcs %l0";
5853 })
5854
5855 (define_insn "bge"
5856   [(set (pc)
5857         (if_then_else (ge (cc0)
5858                           (const_int 0))
5859                       (label_ref (match_operand 0 "" ""))
5860                       (pc)))]
5861   ""
5862 {
5863   if (MOTOROLA)
5864     OUTPUT_JUMP ("jbge %l0", "fbge %l0", "jbpl %l0");
5865   else
5866     OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0");
5867 })
5868
5869 (define_insn "bgeu"
5870   [(set (pc)
5871         (if_then_else (geu (cc0)
5872                            (const_int 0))
5873                       (label_ref (match_operand 0 "" ""))
5874                       (pc)))]
5875   ""
5876 {
5877   return MOTOROLA ? "jbcc %l0" : "jcc %l0";
5878 })
5879
5880 (define_insn "ble"
5881   [(set (pc)
5882         (if_then_else (le (cc0)
5883                           (const_int 0))
5884                       (label_ref (match_operand 0 "" ""))
5885                       (pc)))]
5886   ""
5887 {
5888   if (MOTOROLA)
5889     OUTPUT_JUMP ("jble %l0", "fble %l0", 0);
5890   else
5891     OUTPUT_JUMP ("jle %l0", "fjle %l0", 0);
5892 })
5893
5894 (define_insn "bleu"
5895   [(set (pc)
5896         (if_then_else (leu (cc0)
5897                            (const_int 0))
5898                       (label_ref (match_operand 0 "" ""))
5899                       (pc)))]
5900   ""
5901 {
5902   return MOTOROLA ? "jbls %l0" : "jls %l0";
5903 })
5904
5905 (define_insn "bordered"
5906   [(set (pc)
5907         (if_then_else (ordered (cc0) (const_int 0))
5908                       (label_ref (match_operand 0 "" ""))
5909                       (pc)))]
5910   "TARGET_68881"
5911 {
5912   gcc_assert (cc_prev_status.flags & CC_IN_68881);
5913   return MOTOROLA ? "fbor %l0" : "fjor %l0";
5914 })
5915
5916 (define_insn "bunordered"
5917   [(set (pc)
5918         (if_then_else (unordered (cc0) (const_int 0))
5919                       (label_ref (match_operand 0 "" ""))
5920                       (pc)))]
5921   "TARGET_68881"
5922 {
5923   gcc_assert (cc_prev_status.flags & CC_IN_68881);
5924   return MOTOROLA ? "fbun %l0" : "fjun %l0";
5925 })
5926
5927 (define_insn "buneq"
5928   [(set (pc)
5929         (if_then_else (uneq (cc0) (const_int 0))
5930                       (label_ref (match_operand 0 "" ""))
5931                       (pc)))]
5932   "TARGET_68881"
5933 {
5934   gcc_assert (cc_prev_status.flags & CC_IN_68881);
5935   return MOTOROLA ? "fbueq %l0" : "fjueq %l0";
5936 })
5937
5938 (define_insn "bunge"
5939   [(set (pc)
5940         (if_then_else (unge (cc0) (const_int 0))
5941                       (label_ref (match_operand 0 "" ""))
5942                       (pc)))]
5943   "TARGET_68881"
5944 {
5945   gcc_assert (cc_prev_status.flags & CC_IN_68881);
5946   return MOTOROLA ? "fbuge %l0" : "fjuge %l0";
5947 })
5948
5949 (define_insn "bungt"
5950   [(set (pc)
5951         (if_then_else (ungt (cc0) (const_int 0))
5952                       (label_ref (match_operand 0 "" ""))
5953                       (pc)))]
5954   "TARGET_68881"
5955 {
5956   gcc_assert (cc_prev_status.flags & CC_IN_68881);
5957   return MOTOROLA ? "fbugt %l0" : "fjugt %l0";
5958 })
5959
5960 (define_insn "bunle"
5961   [(set (pc)
5962         (if_then_else (unle (cc0) (const_int 0))
5963                       (label_ref (match_operand 0 "" ""))
5964                       (pc)))]
5965   "TARGET_68881"
5966 {
5967   gcc_assert (cc_prev_status.flags & CC_IN_68881);
5968   return MOTOROLA ? "fbule %l0" : "fjule %l0";
5969 })
5970
5971 (define_insn "bunlt"
5972   [(set (pc)
5973         (if_then_else (unlt (cc0) (const_int 0))
5974                       (label_ref (match_operand 0 "" ""))
5975                       (pc)))]
5976   "TARGET_68881"
5977 {
5978   gcc_assert (cc_prev_status.flags & CC_IN_68881);
5979   return MOTOROLA ? "fbult %l0" : "fjult %l0";
5980 })
5981
5982 (define_insn "bltgt"
5983   [(set (pc)
5984         (if_then_else (ltgt (cc0) (const_int 0))
5985                       (label_ref (match_operand 0 "" ""))
5986                       (pc)))]
5987   "TARGET_68881"
5988 {
5989   gcc_assert (cc_prev_status.flags & CC_IN_68881);
5990   return MOTOROLA ? "fbogl %l0" : "fjogl %l0";
5991 })
5992 \f
5993 ;; Negated conditional jump instructions.
5994
5995 (define_insn ""
5996   [(set (pc)
5997         (if_then_else (eq (cc0)
5998                           (const_int 0))
5999                       (pc)
6000                       (label_ref (match_operand 0 "" ""))))]
6001   ""
6002 {
6003   if (MOTOROLA)
6004     OUTPUT_JUMP ("jbne %l0", "fbne %l0", "jbne %l0");
6005   else
6006     OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
6007 })
6008
6009 (define_insn ""
6010   [(set (pc)
6011         (if_then_else (ne (cc0)
6012                           (const_int 0))
6013                       (pc)
6014                       (label_ref (match_operand 0 "" ""))))]
6015   ""
6016 {
6017   if (MOTOROLA)
6018     OUTPUT_JUMP ("jbeq %l0", "fbeq %l0", "jbeq %l0");
6019   else
6020     OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
6021 })
6022
6023 (define_insn ""
6024   [(set (pc)
6025         (if_then_else (gt (cc0)
6026                           (const_int 0))
6027                       (pc)
6028                       (label_ref (match_operand 0 "" ""))))]
6029   ""
6030 {
6031   if (MOTOROLA)
6032     OUTPUT_JUMP ("jble %l0", "fbngt %l0", 0);
6033   else
6034     OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0);
6035 })
6036
6037 (define_insn ""
6038   [(set (pc)
6039         (if_then_else (gtu (cc0)
6040                            (const_int 0))
6041                       (pc)
6042                       (label_ref (match_operand 0 "" ""))))]
6043   ""
6044 {
6045   return MOTOROLA ? "jbls %l0" : "jls %l0";
6046 })
6047
6048 (define_insn ""
6049   [(set (pc)
6050         (if_then_else (lt (cc0)
6051                           (const_int 0))
6052                       (pc)
6053                       (label_ref (match_operand 0 "" ""))))]
6054   ""
6055 {
6056   if (MOTOROLA)
6057     OUTPUT_JUMP ("jbge %l0", "fbnlt %l0", "jbpl %l0");
6058   else
6059     OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0");
6060 })
6061
6062 (define_insn ""
6063   [(set (pc)
6064         (if_then_else (ltu (cc0)
6065                            (const_int 0))
6066                       (pc)
6067                       (label_ref (match_operand 0 "" ""))))]
6068   ""
6069 {
6070   return MOTOROLA ? "jbcc %l0" : "jcc %l0";
6071 })
6072
6073 (define_insn ""
6074   [(set (pc)
6075         (if_then_else (ge (cc0)
6076                           (const_int 0))
6077                       (pc)
6078                       (label_ref (match_operand 0 "" ""))))]
6079   ""
6080 {
6081   if (MOTOROLA)
6082     OUTPUT_JUMP ("jblt %l0", "fbnge %l0", "jbmi %l0");
6083   else
6084     OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0");
6085 })
6086
6087 (define_insn ""
6088   [(set (pc)
6089         (if_then_else (geu (cc0)
6090                            (const_int 0))
6091                       (pc)
6092                       (label_ref (match_operand 0 "" ""))))]
6093   ""
6094 {
6095   return MOTOROLA ? "jbcs %l0" : "jcs %l0";
6096 })
6097
6098 (define_insn ""
6099   [(set (pc)
6100         (if_then_else (le (cc0)
6101                           (const_int 0))
6102                       (pc)
6103                       (label_ref (match_operand 0 "" ""))))]
6104   ""
6105 {
6106   if (MOTOROLA)
6107     OUTPUT_JUMP ("jbgt %l0", "fbnle %l0", 0);
6108   else
6109     OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0);
6110 })
6111
6112 (define_insn ""
6113   [(set (pc)
6114         (if_then_else (leu (cc0)
6115                            (const_int 0))
6116                       (pc)
6117                       (label_ref (match_operand 0 "" ""))))]
6118   ""
6119 {
6120   return MOTOROLA ? "jbhi %l0" : "jhi %l0";
6121 })
6122
6123 (define_insn "*bordered_rev"
6124   [(set (pc)
6125         (if_then_else (ordered (cc0) (const_int 0))
6126                       (pc)
6127                       (label_ref (match_operand 0 "" ""))))]
6128   "TARGET_68881"
6129 {
6130   gcc_assert (cc_prev_status.flags & CC_IN_68881);
6131   return MOTOROLA ? "fbun %l0" : "fjun %l0";
6132 })
6133
6134 (define_insn "*bunordered_rev"
6135   [(set (pc)
6136         (if_then_else (unordered (cc0) (const_int 0))
6137                       (pc)
6138                       (label_ref (match_operand 0 "" ""))))]
6139   "TARGET_68881"
6140 {
6141   gcc_assert (cc_prev_status.flags & CC_IN_68881);
6142   return MOTOROLA ? "fbor %l0" : "fjor %l0";
6143 })
6144
6145 (define_insn "*buneq_rev"
6146   [(set (pc)
6147         (if_then_else (uneq (cc0) (const_int 0))
6148                       (pc)
6149                       (label_ref (match_operand 0 "" ""))))]
6150   "TARGET_68881"
6151 {
6152   gcc_assert (cc_prev_status.flags & CC_IN_68881);
6153   return MOTOROLA ? "fbogl %l0" : "fjogl %l0";
6154 })
6155
6156 (define_insn "*bunge_rev"
6157   [(set (pc)
6158         (if_then_else (unge (cc0) (const_int 0))
6159                       (pc)
6160                       (label_ref (match_operand 0 "" ""))))]
6161   "TARGET_68881"
6162 {
6163   gcc_assert (cc_prev_status.flags & CC_IN_68881);
6164   return MOTOROLA ? "fbolt %l0" : "fjolt %l0";
6165 })
6166
6167 (define_insn "*bunle_rev"
6168   [(set (pc)
6169         (if_then_else (unle (cc0) (const_int 0))
6170                       (pc)
6171                       (label_ref (match_operand 0 "" ""))))]
6172   "TARGET_68881"
6173 {
6174   gcc_assert (cc_prev_status.flags & CC_IN_68881);
6175   return MOTOROLA ? "fbogt %l0" : "fjogt %l0";
6176 })
6177
6178 (define_insn "*bunlt_rev"
6179   [(set (pc)
6180         (if_then_else (unlt (cc0) (const_int 0))
6181                       (pc)
6182                       (label_ref (match_operand 0 "" ""))))]
6183   "TARGET_68881"
6184 {
6185   gcc_assert (cc_prev_status.flags & CC_IN_68881);
6186   return MOTOROLA ? "fboge %l0" : "fjoge %l0";
6187 })
6188
6189 (define_insn "*bltgt_rev"
6190   [(set (pc)
6191         (if_then_else (ltgt (cc0) (const_int 0))
6192                       (pc)
6193                       (label_ref (match_operand 0 "" ""))))]
6194   "TARGET_68881"
6195 {
6196   gcc_assert (cc_prev_status.flags & CC_IN_68881);
6197   return MOTOROLA ? "fbueq %l0" : "fjueq %l0";
6198 })
6199 \f
6200 ;; Unconditional and other jump instructions
6201 (define_insn "jump"
6202   [(set (pc)
6203         (label_ref (match_operand 0 "" "")))]
6204   ""
6205 {
6206   return MOTOROLA ? "jbra %l0" : "jra %l0";
6207 })
6208
6209 (define_expand "tablejump"
6210   [(parallel [(set (pc) (match_operand 0 "" ""))
6211               (use (label_ref (match_operand 1 "" "")))])]
6212   ""
6213 {
6214 #ifdef CASE_VECTOR_PC_RELATIVE
6215     operands[0] = gen_rtx_PLUS (SImode, pc_rtx,
6216                                 gen_rtx_SIGN_EXTEND (SImode, operands[0]));
6217 #endif
6218 })
6219
6220 ;; Jump to variable address from dispatch table of absolute addresses.
6221 (define_insn ""
6222   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
6223    (use (label_ref (match_operand 1 "" "")))]
6224   ""
6225 {
6226   return MOTOROLA ? "jmp (%0)" : "jmp %0@";
6227 })
6228
6229 ;; Jump to variable address from dispatch table of relative addresses.
6230 (define_insn ""
6231   [(set (pc)
6232         (plus:SI (pc)
6233                  (sign_extend:SI (match_operand:HI 0 "register_operand" "r"))))
6234    (use (label_ref (match_operand 1 "" "")))]
6235   ""
6236 {
6237 #ifdef ASM_RETURN_CASE_JUMP
6238   ASM_RETURN_CASE_JUMP;
6239 #else
6240   if (TARGET_COLDFIRE)
6241     {
6242       if (ADDRESS_REG_P (operands[0]))
6243         return MOTOROLA ? "jmp (2,pc,%0.l)" : "jmp pc@(2,%0:l)";
6244       else if (MOTOROLA)
6245         return "ext%.l %0\;jmp (2,pc,%0.l)";
6246       else
6247         return "extl %0\;jmp pc@(2,%0:l)";
6248     }
6249   else
6250     return MOTOROLA ? "jmp (2,pc,%0.w)" : "jmp pc@(2,%0:w)";
6251 #endif
6252 })
6253
6254 ;; Decrement-and-branch insns.
6255 (define_insn ""
6256   [(set (pc)
6257         (if_then_else
6258          (ne (match_operand:HI 0 "nonimmediate_operand" "+d*g")
6259              (const_int 0))
6260          (label_ref (match_operand 1 "" ""))
6261          (pc)))
6262    (set (match_dup 0)
6263         (plus:HI (match_dup 0)
6264                  (const_int -1)))]
6265   "!TARGET_COLDFIRE"
6266 {
6267   CC_STATUS_INIT;
6268   if (DATA_REG_P (operands[0]))
6269     return "dbra %0,%l1";
6270   if (GET_CODE (operands[0]) == MEM)
6271     return MOTOROLA ?
6272       "subq%.w #1,%0\;jbcc %l1" :
6273       "subqw #1,%0\;jcc %l1";
6274   return MOTOROLA ?
6275     "subq%.w #1,%0\;cmp%.w #-1,%0\;jbne %l1" :
6276     "subqw #1,%0\;cmpw #-1,%0\;jne %l1";
6277 })
6278
6279 (define_insn ""
6280   [(set (pc)
6281         (if_then_else
6282          (ne (match_operand:SI 0 "nonimmediate_operand" "+d*g")
6283              (const_int 0))
6284          (label_ref (match_operand 1 "" ""))
6285          (pc)))
6286    (set (match_dup 0)
6287         (plus:SI (match_dup 0)
6288                  (const_int -1)))]
6289   "!TARGET_COLDFIRE"
6290 {
6291   CC_STATUS_INIT;
6292   if (DATA_REG_P (operands[0]))
6293     return MOTOROLA ?
6294       "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jbcc %l1" :
6295       "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1";
6296   if (GET_CODE (operands[0]) == MEM)
6297     return MOTOROLA ?
6298       "subq%.l #1,%0\;jbcc %l1" :
6299       "subq%.l #1,%0\;jcc %l1";
6300   return MOTOROLA ?
6301     "subq.l #1,%0\;cmp.l #-1,%0\;jbne %l1" :
6302     "subql #1,%0\;cmpl #-1,%0\;jne %l1";
6303 })
6304
6305 ;; Two dbra patterns that use REG_NOTES info generated by strength_reduce.
6306
6307 (define_insn ""
6308   [(set (pc)
6309         (if_then_else
6310           (ge (plus:HI (match_operand:HI 0 "nonimmediate_operand" "+d*am")
6311                        (const_int -1))
6312               (const_int 0))
6313           (label_ref (match_operand 1 "" ""))
6314           (pc)))
6315    (set (match_dup 0)
6316         (plus:HI (match_dup 0)
6317                  (const_int -1)))]
6318   "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)"
6319 {
6320   CC_STATUS_INIT;
6321   if (DATA_REG_P (operands[0]))
6322     return "dbra %0,%l1";
6323   if (GET_CODE (operands[0]) == MEM)
6324     return MOTOROLA ?
6325       "subq%.w #1,%0\;jbcc %l1" :
6326       "subq%.w #1,%0\;jcc %l1";
6327   return MOTOROLA ?
6328     "subq.w #1,%0\;cmp.w #-1,%0\;jbne %l1" :
6329     "subqw #1,%0\;cmpw #-1,%0\;jne %l1";
6330 })
6331
6332 (define_expand "decrement_and_branch_until_zero"
6333   [(parallel [(set (pc)
6334                    (if_then_else
6335                     (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "")
6336                                  (const_int -1))
6337                         (const_int 0))
6338                     (label_ref (match_operand 1 "" ""))
6339                     (pc)))
6340               (set (match_dup 0)
6341                    (plus:SI (match_dup 0)
6342                             (const_int -1)))])]
6343   ""
6344   "")
6345
6346 (define_insn ""
6347   [(set (pc)
6348         (if_then_else
6349           (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+d*am")
6350                        (const_int -1))
6351               (const_int 0))
6352           (label_ref (match_operand 1 "" ""))
6353           (pc)))
6354    (set (match_dup 0)
6355         (plus:SI (match_dup 0)
6356                  (const_int -1)))]
6357   "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)"
6358 {
6359   CC_STATUS_INIT;
6360   if (DATA_REG_P (operands[0]))
6361     return MOTOROLA ?
6362       "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jbcc %l1" :
6363       "dbra %0,%l1\;clr%.w %0\;subql #1,%0\;jcc %l1";
6364   if (GET_CODE (operands[0]) == MEM)
6365     return MOTOROLA ?
6366       "subq%.l #1,%0\;jbcc %l1" :
6367       "subql #1,%0\;jcc %l1";
6368   return MOTOROLA ?
6369     "subq.l #1,%0\;cmp.l #-1,%0\;jbne %l1" :
6370     "subql #1,%0\;cmpl #-1,%0\;jne %l1";
6371 })
6372
6373
6374 ;; For PIC calls, in order to be able to support
6375 ;; dynamic linker LAZY BINDING, all the procedure calls need to go
6376 ;; through the PLT (Procedure Linkage Table) section in PIC mode.
6377 ;;
6378 ;; PIC calls are handled by loading the address of the function into a
6379 ;; register (via movsi), then emitting a register indirect call using
6380 ;; the "jsr" function call syntax.
6381 ;;
6382 ;; When outputting MIT syntax (e.g. on Suns), we add a bogus extra
6383 ;; operand to the jbsr statement to indicate that this call should
6384 ;; go through the PLT (why? because this is the way that Sun does it).
6385 ;;
6386 ;; We have different patterns for PIC calls and non-PIC calls.  The
6387 ;; different patterns are only used to choose the right syntax.
6388 ;;
6389 ;; The svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it
6390 ;; will create the correct relocation entry (R_68K_PLT32) for `FUNC',
6391 ;; that tells the linker editor to create an entry for `FUNC' in PLT
6392 ;; section at link time. However, all global objects reference are still
6393 ;; done by using `OBJ@GOT'. So, the goal here is to output the function
6394 ;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'.
6395 ;; We need to have a way to differentiate these two different operands.
6396 ;;
6397 ;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate
6398 ;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs
6399 ;; to be changed to recognize function calls symbol_ref operand as a valid
6400 ;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will
6401 ;; avoid the compiler to load this symbol_ref operand into a register.
6402 ;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly
6403 ;; since the value is a PC relative offset, not a real address.
6404 ;;
6405 ;; All global objects are treated in the similar way as in SUN3. The only
6406 ;; difference is: on m68k svr4, the reference of such global object needs
6407 ;; to end with a suffix "@GOT" so the assembler and linker know to create
6408 ;; an entry for it in GOT (Global Offset Table) section. This is done in
6409 ;; m68k.c.
6410
6411 ;; Call subroutine with no return value.
6412 (define_expand "call"
6413   [(call (match_operand:QI 0 "memory_operand" "")
6414          (match_operand:SI 1 "general_operand" ""))]
6415   ;; Operand 1 not really used on the m68000.
6416
6417   ""
6418 {
6419   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
6420     SYMBOL_REF_FLAG (XEXP (operands[0], 0)) = 1;
6421 })
6422
6423 ;; This is a normal call sequence.
6424 (define_insn ""
6425   [(call (match_operand:QI 0 "memory_operand" "o")
6426          (match_operand:SI 1 "general_operand" "g"))]
6427   ;; Operand 1 not really used on the m68000.
6428
6429   "! flag_pic"
6430 {
6431 #if MOTOROLA && !defined (USE_GAS)
6432   return "jsr %0";
6433 #else
6434   return "jbsr %0";
6435 #endif
6436 })
6437
6438 ;; This is a PIC call sequence.
6439 (define_insn ""
6440   [(call (match_operand:QI 0 "memory_operand" "o")
6441          (match_operand:SI 1 "general_operand" "g"))]
6442   ;; Operand 1 not really used on the m68000.
6443
6444   "flag_pic"
6445 {
6446   m68k_output_pic_call(operands[0]);
6447   return "";
6448 })
6449
6450 ;; Call subroutine, returning value in operand 0
6451 ;; (which must be a hard register).
6452 ;; See comments before "call" regarding PIC calls.
6453 (define_expand "call_value"
6454   [(set (match_operand 0 "" "")
6455         (call (match_operand:QI 1 "memory_operand" "")
6456      (match_operand:SI 2 "general_operand" "")))]
6457   ;; Operand 2 not really used on the m68000.
6458   ""
6459 {
6460   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6461     SYMBOL_REF_FLAG (XEXP (operands[1], 0)) = 1;
6462 })
6463
6464 ;; This is a normal call_value
6465 (define_insn ""
6466   [(set (match_operand 0 "" "=rf")
6467         (call (match_operand:QI 1 "memory_operand" "o")
6468               (match_operand:SI 2 "general_operand" "g")))]
6469   ;; Operand 2 not really used on the m68000.
6470   "! flag_pic"
6471 {
6472 #if MOTOROLA && !defined (USE_GAS)
6473   return "jsr %1";
6474 #else
6475   return "jbsr %1";
6476 #endif
6477 })
6478
6479 ;; This is a PIC call_value
6480 (define_insn ""
6481   [(set (match_operand 0 "" "=rf")
6482         (call (match_operand:QI 1 "memory_operand" "o")
6483               (match_operand:SI 2 "general_operand" "g")))]
6484   ;; Operand 2 not really used on the m68000.
6485   "flag_pic"
6486 {
6487   m68k_output_pic_call(operands[1]);
6488   return "";
6489 })
6490
6491 ;; Call subroutine returning any type.
6492
6493 (define_expand "untyped_call"
6494   [(parallel [(call (match_operand 0 "" "")
6495                     (const_int 0))
6496               (match_operand 1 "" "")
6497               (match_operand 2 "" "")])]
6498   "NEEDS_UNTYPED_CALL"
6499 {
6500   int i;
6501
6502   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6503
6504   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6505     {
6506       rtx set = XVECEXP (operands[2], 0, i);
6507       emit_move_insn (SET_DEST (set), SET_SRC (set));
6508     }
6509
6510   /* The optimizer does not know that the call sets the function value
6511      registers we stored in the result block.  We avoid problems by
6512      claiming that all hard registers are used and clobbered at this
6513      point.  */
6514   emit_insn (gen_blockage ());
6515
6516   DONE;
6517 })
6518
6519 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6520 ;; all of memory.  This blocks insns from being moved across this point.
6521
6522 (define_insn "blockage"
6523   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6524   ""
6525   "")
6526
6527 (define_insn "nop"
6528   [(const_int 0)]
6529   ""
6530   "nop")
6531
6532 ;; Used for frameless functions which save no regs and allocate no locals.
6533 (define_insn "return"
6534   [(return)]
6535   "USE_RETURN_INSN"
6536 {
6537   if (current_function_pops_args == 0)
6538     return "rts";
6539   operands[0] = GEN_INT (current_function_pops_args);
6540   return "rtd %0";
6541 })
6542
6543 (define_insn "indirect_jump"
6544   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6545   ""
6546   "jmp %a0")
6547 \f
6548 ;; This should not be used unless the add/sub insns can't be.
6549
6550 (define_insn ""
6551   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
6552         (match_operand:QI 1 "address_operand" "p"))]
6553   ""
6554 {
6555   /* Recognize an insn that refers to a table of offsets.  Such an insn will
6556      need to refer to a label on the insn.  So output one.  Use the
6557      label-number of the table of offsets to generate this label.  This code,
6558      and similar code above, assumes that there will be at most one reference
6559      to each table.  */
6560   if (GET_CODE (operands[1]) == PLUS
6561       && GET_CODE (XEXP (operands[1], 1)) == LABEL_REF
6562       && GET_CODE (XEXP (operands[1], 0)) != PLUS)
6563     {
6564       rtx labelref = XEXP (operands[1], 1);
6565       if (MOTOROLA)
6566         asm_fprintf (asm_out_file, "\\t.set %LLI%d,.+2\\n",
6567                      CODE_LABEL_NUMBER (XEXP (labelref, 0)));
6568       else
6569         (*targetm.asm_out.internal_label) (asm_out_file, "LI",
6570                      CODE_LABEL_NUMBER (XEXP (labelref, 0)));
6571     }
6572   return "lea %a1,%0";
6573 })
6574 \f
6575 ;; This is the first machine-dependent peephole optimization.
6576 ;; It is useful when a floating value is returned from a function call
6577 ;; and then is moved into an FP register.
6578 ;; But it is mainly intended to test the support for these optimizations.
6579
6580 (define_peephole
6581   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
6582    (set (match_operand:DF 0 "register_operand" "=f")
6583         (match_operand:DF 1 "register_operand" "ad"))]
6584   "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
6585 {
6586   rtx xoperands[2];
6587   xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
6588   output_asm_insn ("move%.l %1,%@", xoperands);
6589   output_asm_insn ("move%.l %1,%-", operands);
6590   return "fmove%.d %+,%0";
6591 })
6592
6593 ;; Optimize a stack-adjust followed by a push of an argument.
6594 ;; This is said to happen frequently with -msoft-float
6595 ;; when there are consecutive library calls.
6596
6597 (define_peephole
6598   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6599                                  (match_operand:SI 0 "const_int_operand" "n")))
6600    (set (match_operand:SF 1 "push_operand" "=m")
6601         (match_operand:SF 2 "general_operand" "rmfF"))]
6602   "INTVAL (operands[0]) >= 4
6603    && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
6604 {
6605   if (INTVAL (operands[0]) > 4)
6606     {
6607       rtx xoperands[2];
6608       xoperands[0] = stack_pointer_rtx;
6609       xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4);
6610       if (INTVAL (xoperands[1]) <= 8)
6611         {
6612           if (!TARGET_COLDFIRE)
6613             output_asm_insn ("addq%.w %1,%0", xoperands);
6614           else
6615             output_asm_insn ("addq%.l %1,%0", xoperands);
6616         }
6617       else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16) 
6618         {
6619           xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8);
6620           output_asm_insn ("addq%.w #8,%0\;addq%.w %1,%0", xoperands);
6621         }
6622       else if (INTVAL (xoperands[1]) <= 0x7FFF)
6623         {
6624           if (TARGET_68040)
6625             output_asm_insn ("add%.w %1,%0", xoperands);
6626           else if (MOTOROLA)
6627             output_asm_insn ("lea (%c1,%0),%0", xoperands);
6628           else
6629             output_asm_insn ("lea %0@(%c1),%0", xoperands);
6630         }
6631       else
6632         output_asm_insn ("add%.l %1,%0", xoperands);
6633     }
6634   if (FP_REG_P (operands[2]))
6635     return "fmove%.s %2,%@";
6636   return "move%.l %2,%@";
6637 })
6638
6639 ;; Speed up stack adjust followed by a fullword fixedpoint push.
6640
6641 (define_peephole
6642   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6643                                  (match_operand:SI 0 "const_int_operand" "n")))
6644    (set (match_operand:SI 1 "push_operand" "=m")
6645         (match_operand:SI 2 "general_operand" "g"))]
6646   "INTVAL (operands[0]) >= 4
6647    && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
6648 {
6649   if (INTVAL (operands[0]) > 4)
6650     {
6651       rtx xoperands[2];
6652       xoperands[0] = stack_pointer_rtx;
6653       xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4);
6654       if (INTVAL (xoperands[1]) <= 8)
6655         {
6656           if (!TARGET_COLDFIRE)
6657             output_asm_insn ("addq%.w %1,%0", xoperands);
6658           else
6659             output_asm_insn ("addq%.l %1,%0", xoperands);
6660         }
6661       else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16)
6662         {
6663           xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8);
6664           output_asm_insn ("addq%.w #8,%0\;addq%.w %1,%0", xoperands);
6665         }
6666       else if (INTVAL (xoperands[1]) <= 0x7FFF)
6667         {
6668           if (TARGET_68040)
6669             output_asm_insn ("add%.w %1,%0", xoperands);
6670           else if (MOTOROLA)
6671             output_asm_insn ("lea (%c1,%0),%0", xoperands);
6672           else
6673             output_asm_insn ("lea %0@(%c1),%0", xoperands);
6674         }
6675       else
6676         output_asm_insn ("add%.l %1,%0", xoperands);
6677     }
6678   if (operands[2] == const0_rtx)
6679     return "clr%.l %@";
6680   return "move%.l %2,%@";
6681 })
6682
6683 ;; Speed up pushing a single byte but leaving four bytes of space.
6684
6685 (define_peephole
6686   [(set (mem:QI (pre_dec:SI (reg:SI SP_REG)))
6687         (match_operand:QI 1 "general_operand" "dami"))
6688    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (const_int 2)))]
6689   "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
6690 {
6691   rtx xoperands[4];
6692
6693   if (GET_CODE (operands[1]) == REG)
6694     return "move%.l %1,%-";
6695
6696   xoperands[1] = operands[1];
6697   xoperands[2]
6698     = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, 3));
6699   xoperands[3] = stack_pointer_rtx;
6700   if (!TARGET_COLDFIRE)
6701     output_asm_insn ("subq%.w #4,%3\;move%.b %1,%2", xoperands);
6702   else
6703     output_asm_insn ("subq%.l #4,%3\;move%.b %1,%2", xoperands);
6704   return "";
6705 })
6706
6707 (define_peephole
6708   [(set (match_operand:SI 0 "register_operand" "=d")
6709         (const_int 0))
6710    (set (strict_low_part (subreg:HI (match_dup 0) 2))
6711         (match_operand:HI 1 "general_operand" "rmn"))]
6712   "strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0])"
6713 {
6714   if (GET_CODE (operands[1]) == CONST_INT)
6715     {
6716       if (operands[1] == const0_rtx
6717           && (DATA_REG_P (operands[0])
6718               || GET_CODE (operands[0]) == MEM)
6719           /* clr insns on 68000 read before writing.
6720              This isn't so on the 68010, but we have no TARGET_68010.  */
6721           && ((TARGET_68020 || TARGET_COLDFIRE)
6722               || !(GET_CODE (operands[0]) == MEM
6723                    && MEM_VOLATILE_P (operands[0]))))
6724         return "clr%.w %0";
6725     }
6726   return "move%.w %1,%0";
6727 })
6728
6729 ;; dbCC peepholes
6730 ;;
6731 ;; Turns
6732 ;;   loop:
6733 ;;           [ ... ]
6734 ;;           jCC label          ; abnormal loop termination
6735 ;;           dbra dN, loop      ; normal loop termination
6736 ;;
6737 ;; Into
6738 ;;   loop:
6739 ;;           [ ... ]
6740 ;;           dbCC dN, loop
6741 ;;           jCC label
6742 ;;
6743 ;; Which moves the jCC condition outside the inner loop for free.
6744 ;;
6745
6746 (define_peephole
6747   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
6748                              [(cc0) (const_int 0)])
6749                            (label_ref (match_operand 2 "" ""))
6750                            (pc)))
6751    (parallel
6752     [(set (pc)
6753           (if_then_else
6754             (ne (match_operand:HI 0 "register_operand" "")
6755                 (const_int 0))
6756             (label_ref (match_operand 1 "" ""))
6757             (pc)))
6758      (set (match_dup 0)
6759           (plus:HI (match_dup 0)
6760                    (const_int -1)))])]
6761   "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
6762 {
6763   CC_STATUS_INIT;
6764   output_dbcc_and_branch (operands);
6765   return "";
6766 })
6767
6768 (define_peephole
6769   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
6770                              [(cc0) (const_int 0)])
6771                            (label_ref (match_operand 2 "" ""))
6772                            (pc)))
6773    (parallel
6774     [(set (pc)
6775           (if_then_else
6776             (ne (match_operand:SI 0 "register_operand" "")
6777                 (const_int 0))
6778             (label_ref (match_operand 1 "" ""))
6779             (pc)))
6780      (set (match_dup 0)
6781           (plus:SI (match_dup 0)
6782                    (const_int -1)))])]
6783   "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
6784 {
6785   CC_STATUS_INIT;
6786   output_dbcc_and_branch (operands);
6787   return "";
6788 })
6789
6790 (define_peephole
6791   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
6792                              [(cc0) (const_int 0)])
6793                            (label_ref (match_operand 2 "" ""))
6794                            (pc)))
6795    (parallel
6796     [(set (pc)
6797           (if_then_else
6798             (ge (plus:HI (match_operand:HI 0 "register_operand" "")
6799                          (const_int -1))
6800                 (const_int 0))
6801             (label_ref (match_operand 1 "" ""))
6802             (pc)))
6803      (set (match_dup 0)
6804           (plus:HI (match_dup 0)
6805                    (const_int -1)))])]
6806   "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
6807 {
6808   CC_STATUS_INIT;
6809   output_dbcc_and_branch (operands);
6810   return "";
6811 })
6812
6813 (define_peephole
6814   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
6815                              [(cc0) (const_int 0)])
6816                            (label_ref (match_operand 2 "" ""))
6817                            (pc)))
6818    (parallel
6819     [(set (pc)
6820           (if_then_else
6821             (ge (plus:SI (match_operand:SI 0 "register_operand" "")
6822                          (const_int -1))
6823                 (const_int 0))
6824             (label_ref (match_operand 1 "" ""))
6825             (pc)))
6826      (set (match_dup 0)
6827           (plus:SI (match_dup 0)
6828                    (const_int -1)))])]
6829   "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
6830 {
6831   CC_STATUS_INIT;
6832   output_dbcc_and_branch (operands);
6833   return "";
6834 })
6835
6836 \f
6837 (define_insn "extendsfxf2"
6838   [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f")
6839         (float_extend:XF (match_operand:SF 1 "general_operand" "f,rmF")))]
6840   "TARGET_68881"
6841 {
6842   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
6843     {
6844       if (REGNO (operands[0]) == REGNO (operands[1]))
6845         {
6846           /* Extending float to double in an fp-reg is a no-op.
6847              NOTICE_UPDATE_CC has already assumed that the
6848              cc will be set.  So cancel what it did.  */
6849           cc_status = cc_prev_status;
6850           return "";
6851         }
6852       return "f%$move%.x %1,%0";
6853     }
6854   if (FP_REG_P (operands[0]))
6855     {
6856       if (FP_REG_P (operands[1]))
6857         return "f%$move%.x %1,%0";
6858       else if (ADDRESS_REG_P (operands[1]))
6859         return "move%.l %1,%-\;f%$move%.s %+,%0";
6860       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
6861         return output_move_const_single (operands);
6862       return "f%$move%.s %f1,%0";
6863     }
6864   return "fmove%.x %f1,%0";
6865 })
6866
6867
6868 (define_insn "extenddfxf2"
6869   [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f")
6870         (float_extend:XF
6871           (match_operand:DF 1 "general_operand" "f,rmE")))]
6872   "TARGET_68881"
6873 {
6874   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
6875     {
6876       if (REGNO (operands[0]) == REGNO (operands[1]))
6877         {
6878           /* Extending float to double in an fp-reg is a no-op.
6879              NOTICE_UPDATE_CC has already assumed that the
6880              cc will be set.  So cancel what it did.  */
6881           cc_status = cc_prev_status;
6882           return "";
6883         }
6884       return "fmove%.x %1,%0";
6885     }
6886   if (FP_REG_P (operands[0]))
6887     {
6888       if (REG_P (operands[1]))
6889         {
6890           rtx xoperands[2];
6891           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
6892           output_asm_insn ("move%.l %1,%-", xoperands);
6893           output_asm_insn ("move%.l %1,%-", operands);
6894           return "f%&move%.d %+,%0";
6895         }
6896       if (GET_CODE (operands[1]) == CONST_DOUBLE)
6897         return output_move_const_double (operands);
6898       return "f%&move%.d %f1,%0";
6899     }
6900   return "fmove%.x %f1,%0";
6901 })
6902
6903 (define_insn "truncxfdf2"
6904   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!r")
6905         (float_truncate:DF
6906           (match_operand:XF 1 "general_operand" "f,f")))]
6907   "TARGET_68881"
6908 {
6909   if (REG_P (operands[0]))
6910     {
6911       output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
6912       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
6913       return "move%.l %+,%0";
6914     }
6915   return "fmove%.d %f1,%0";
6916 })
6917
6918 (define_insn "sin<mode>2"
6919   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
6920         (unspec:FP
6921           [(match_operand:FP 1 "general_operand" "f<FP:dreg>m")] UNSPEC_SIN))]
6922   "TARGET_68881 && flag_unsafe_math_optimizations"
6923 {
6924   if (FP_REG_P (operands[1]))
6925     return "fsin%.x %1,%0";
6926   else
6927     return "fsin%.<FP:prec> %1,%0";
6928 })
6929
6930 (define_insn "cos<mode>2"
6931   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
6932         (unspec:FP
6933           [(match_operand:FP 1 "general_operand" "f<FP:dreg>m")] UNSPEC_COS))]
6934   "TARGET_68881 && flag_unsafe_math_optimizations"
6935 {
6936   if (FP_REG_P (operands[1]))
6937     return "fcos%.x %1,%0";
6938   else
6939     return "fcos%.<FP:prec> %1,%0";
6940 })
6941
6942 (define_insn "trap"
6943   [(trap_if (const_int -1) (const_int 7))]
6944   ""
6945   "trap #7")
6946
6947 (define_insn "conditional_trap"
6948   [(trap_if (match_operator 0 "valid_dbcc_comparison_p"
6949                             [(cc0) (const_int 0)])
6950             (match_operand:SI 1 "const_int_operand" "I"))]
6951   "TARGET_68020 && ! flags_in_68881 ()"
6952 {
6953   switch (GET_CODE (operands[0]))
6954   {
6955   case EQ:  return "trapeq";
6956   case NE:  return "trapne";
6957   case GT:  return "trapgt";
6958   case GTU: return "traphi";
6959   case LT:  return "traplt";
6960   case LTU: return "trapcs";
6961   case GE:  return "trapge";
6962   case GEU: return "trapcc";
6963   case LE:  return "traple";
6964   case LEU: return "trapls";
6965   default: gcc_unreachable ();
6966   }
6967 })