OSDN Git Service

* config/m68k/m68k.c (m68k_output_mi_thunk): delete obsolete code
[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, 2002, 2003
3 ;;  Free Software Foundation, Inc.
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;;- Information about MCF5200 port.
23
24 ;;- The MCF5200 "ColdFire" architecture is a reduced version of the
25 ;;- 68k ISA.  Differences include reduced support for byte and word
26 ;;- operands and the removal of BCD, bitfield, rotate, and integer
27 ;;- divide instructions.  The TARGET_5200 flag turns the use of the
28 ;;- removed opcodes and addressing modes off.
29 ;;- 
30
31
32 ;;- instruction definitions
33
34 ;;- @@The original PO technology requires these to be ordered by speed,
35 ;;- @@    so that assigner will pick the fastest.
36
37 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
38
39 ;;- When naming insn's (operand 0 of define_insn) be careful about using
40 ;;- names from other targets machine descriptions.
41
42 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
43 ;;- updates for most instructions.
44
45 ;;- Operand classes for the register allocator:
46 ;;- 'a' one of the address registers can be used.
47 ;;- 'd' one of the data registers can be used.
48 ;;- 'f' one of the m68881 registers can be used
49 ;;- 'r' either a data or an address register can be used.
50
51 ;;- Immediate Floating point operator constraints
52 ;;- 'G' a floating point constant that is *NOT* one of the standard
53 ;;   68881 constant values (to force calling output_move_const_double
54 ;;   to get it from rom if it is a 68881 constant).
55 ;;
56 ;;   See the functions standard_XXX_constant_p in output-m68k.c for more
57 ;; info.
58
59 ;;- Immediate integer operand constraints:
60 ;;- 'I'  1 .. 8
61 ;;- 'J'  -32768 .. 32767
62 ;;- 'K'  all integers EXCEPT -128 .. 127
63 ;;- 'L'  -8 .. -1
64 ;;- 'M'  all integers EXCEPT -256 .. 255
65 ;;- 'N'  24 .. 31
66 ;;- 'O'  16
67 ;;- 'P'  8 .. 15
68
69 ;;- Assembler specs:
70 ;;- "%."    size separator ("." or "")                  move%.l d0,d1
71 ;;- "%#"    immediate separator ("#" or "")             move%.l %#0,d0
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 \f
126 (define_insn ""
127   [(set (match_operand:DF 0 "push_operand" "=m")
128         (match_operand:DF 1 "general_operand" "ro<>fyE"))]
129   ""
130   "*
131 {
132   if (FP_REG_P (operands[1]))
133     return \"fmove%.d %f1,%0\";
134   return output_move_double (operands);
135 }")
136
137 (define_insn "pushdi"
138   [(set (match_operand:DI 0 "push_operand" "=m")
139         (match_operand:DI 1 "general_operand" "ro<>Fyi"))]
140   ""
141   "*
142 {
143   return output_move_double (operands);
144 }")
145 \f
146 ;; We don't want to allow a constant operand for test insns because
147 ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
148 ;; be folded while optimizing anyway.
149
150 (define_expand "tstdi"
151   [(parallel [(set (cc0)
152                    (match_operand:DI 0 "nonimmediate_operand" ""))
153               (clobber (match_scratch:SI 1 ""))
154               (clobber (match_scratch:DI 2 ""))])]
155   ""
156   "m68k_last_compare_had_fp_operands = 0;")
157
158 (define_insn ""
159   [(set (cc0)
160         (match_operand:DI 0 "nonimmediate_operand" "am,d"))
161    (clobber (match_scratch:SI 1 "=X,d"))
162    (clobber (match_scratch:DI 2 "=d,X"))]
163   ""
164   "*
165 {
166   if (which_alternative == 0)
167     {
168       rtx xoperands[2];
169
170       xoperands[0] = operands[2];
171       xoperands[1] = operands[0];
172       output_move_double (xoperands);
173       cc_status.flags |= CC_REVERSED;
174       return \"neg%.l %R2\;negx%.l %2\";
175     }
176   if (find_reg_note (insn, REG_DEAD, operands[0]))
177     {
178       cc_status.flags |= CC_REVERSED;
179       return \"neg%.l %R0\;negx%.l %0\";
180     }
181   else
182     /*
183     ** 'sub' clears %1, and also clears the X cc bit
184     ** 'tst' sets the Z cc bit according to the low part of the DImode operand
185     ** 'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part
186     */
187     return \"sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0\";
188 }")
189
190 (define_expand "tstsi"
191   [(set (cc0)
192         (match_operand:SI 0 "nonimmediate_operand" ""))]
193   ""
194   "m68k_last_compare_had_fp_operands = 0;")
195
196 (define_insn ""
197   [(set (cc0)
198         (match_operand:SI 0 "nonimmediate_operand" "rm"))]
199   ""
200   "*
201 {
202 #ifdef ISI_OV
203   /* ISI's assembler fails to handle tstl a0.  */
204   if (! ADDRESS_REG_P (operands[0]))
205 #else
206   if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (operands[0]))
207 #endif
208     return \"tst%.l %0\";
209   /* If you think that the 68020 does not support tstl a0,
210      reread page B-167 of the 68020 manual more carefully.  */
211   /* On an address reg, cmpw may replace cmpl.  */
212 #ifdef SGS_CMP_ORDER
213   return \"cmp%.w %0,%#0\";
214 #else
215   return \"cmp%.w %#0,%0\";
216 #endif
217 }")
218
219 ;; This can't use an address register, because comparisons
220 ;; with address registers as second operand always test the whole word.
221 (define_expand "tsthi"
222   [(set (cc0)
223         (match_operand:HI 0 "nonimmediate_operand" ""))]
224   ""
225   "m68k_last_compare_had_fp_operands = 0;")
226
227 (define_insn ""
228   [(set (cc0)
229         (match_operand:HI 0 "nonimmediate_operand" "dm"))]
230   ""
231   "tst%.w %0")
232
233 (define_expand "tstqi"
234   [(set (cc0)
235         (match_operand:QI 0 "nonimmediate_operand" ""))]
236   ""
237   "m68k_last_compare_had_fp_operands = 0;")
238
239 (define_insn ""
240   [(set (cc0)
241         (match_operand:QI 0 "nonimmediate_operand" "dm"))]
242   ""
243   "tst%.b %0")
244
245 (define_expand "tstsf"
246   [(set (cc0)
247         (match_operand:SF 0 "general_operand" ""))]
248   "TARGET_68881"
249   "
250 {
251   m68k_last_compare_had_fp_operands = 1;
252 }")
253
254 (define_insn ""
255   [(set (cc0)
256         (match_operand:SF 0 "general_operand" "fdm"))]
257   "TARGET_68881"
258   "*
259 {
260   cc_status.flags = CC_IN_68881;
261   if (FP_REG_P (operands[0]))
262     return \"ftst%.x %0\";
263   return \"ftst%.s %0\";
264 }")
265
266 (define_expand "tstdf"
267   [(set (cc0)
268         (match_operand:DF 0 "general_operand" ""))]
269   "TARGET_68881"
270   "
271 {
272   m68k_last_compare_had_fp_operands = 1;
273 }")
274
275 (define_insn ""
276   [(set (cc0)
277         (match_operand:DF 0 "general_operand" "fm"))]
278   "TARGET_68881"
279   "*
280 {
281   cc_status.flags = CC_IN_68881;
282   if (FP_REG_P (operands[0]))
283     return \"ftst%.x %0\";
284   return \"ftst%.d %0\";
285 }")
286 \f
287 ;; compare instructions.
288
289 (define_expand "cmpdi"
290   [(parallel
291     [(set (cc0)
292           (compare (match_operand:DI 0 "nonimmediate_operand" "")
293                    (match_operand:DI 1 "general_operand" "")))
294      (clobber (match_dup 2))])]
295   ""
296   "m68k_last_compare_had_fp_operands = 0; operands[2] = gen_reg_rtx (DImode);")
297
298 (define_insn ""
299   [(set (cc0)
300         (compare (match_operand:DI 1 "nonimmediate_operand" "0,d")
301                  (match_operand:DI 2 "general_operand" "d,0")))
302    (clobber (match_operand:DI 0 "register_operand" "=d,d"))]
303   ""
304   "*
305 {
306   if (rtx_equal_p (operands[0], operands[1]))
307     return \"sub%.l %R2,%R0\;subx%.l %2,%0\";
308   else
309     {
310       cc_status.flags |= CC_REVERSED;
311       return \"sub%.l %R1,%R0\;subx%.l %1,%0\";
312     }
313 }")
314
315 ;; This is the second "hook" for PIC code (in addition to movsi). See
316 ;; comment of movsi for a description of PIC handling.
317 (define_expand "cmpsi"
318   [(set (cc0)
319         (compare (match_operand:SI 0 "nonimmediate_operand" "")
320                  (match_operand:SI 1 "general_operand" "")))]
321   ""
322   "
323 {
324   m68k_last_compare_had_fp_operands = 0;
325   if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
326     {
327       /* The source is an address which requires PIC relocation.
328          Call legitimize_pic_address with the source, mode, and a relocation
329          register (a new pseudo, or the final destination if reload_in_progress
330          is set).   Then fall through normally */
331       rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
332       operands[1] = legitimize_pic_address (operands[1], SImode, temp);
333     }
334 }")
335
336 ;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
337 (define_insn ""
338   [(set (cc0)
339         (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mSr,mSa,>")
340                  (match_operand:SI 1 "general_src_operand" "mSr,mSa,KTr,Ksr,>")))]
341   "!TARGET_5200"
342   "*
343 {
344   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
345 #ifdef SGS_CMP_ORDER
346     return \"cmpm%.l %0,%1\";
347 #else
348     return \"cmpm%.l %1,%0\";
349 #endif
350   if (REG_P (operands[1])
351       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
352     { cc_status.flags |= CC_REVERSED;
353 #ifdef SGS_CMP_ORDER
354       return \"cmp%.l %d1,%d0\";
355 #else
356       return \"cmp%.l %d0,%d1\";
357 #endif
358     }
359   if (ADDRESS_REG_P (operands[0])
360       && GET_CODE (operands[1]) == CONST_INT
361       && INTVAL (operands[1]) < 0x8000
362       && INTVAL (operands[1]) >= -0x8000)
363     {
364 #ifdef SGS_CMP_ORDER
365       return \"cmp%.w %0,%1\";
366 #else
367       return \"cmp%.w %1,%0\";
368 #endif
369     }
370 #ifdef SGS_CMP_ORDER
371   return \"cmp%.l %d0,%d1\";
372 #else
373   return \"cmp%.l %d1,%d0\";
374 #endif
375 }")
376
377 (define_insn ""
378   [(set (cc0)
379         (compare (match_operand:SI 0 "nonimmediate_operand" "mrKs,r")
380                  (match_operand:SI 1 "general_operand" "r,mrKs")))]
381   "TARGET_5200"
382   "*
383 {
384   if (REG_P (operands[1])
385       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
386     { cc_status.flags |= CC_REVERSED;
387 #ifdef SGS_CMP_ORDER
388       return \"cmp%.l %d1,%d0\";
389 #else
390       return \"cmp%.l %d0,%d1\";
391 #endif
392     }
393 #ifdef SGS_CMP_ORDER
394   return \"cmp%.l %d0,%d1\";
395 #else
396   return \"cmp%.l %d1,%d0\";
397 #endif
398 }")
399
400 (define_expand "cmphi"
401   [(set (cc0)
402         (compare (match_operand:HI 0 "nonimmediate_src_operand" "")
403                  (match_operand:HI 1 "general_src_operand" "")))]
404   "!TARGET_5200"
405   "m68k_last_compare_had_fp_operands = 0;")
406
407 (define_insn ""
408   [(set (cc0)
409         (compare (match_operand:HI 0 "nonimmediate_src_operand" "rnmS,d,n,mS,>")
410                  (match_operand:HI 1 "general_src_operand" "d,rnmS,mS,n,>")))]
411   "!TARGET_5200"
412   "*
413 {
414   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
415 #ifdef SGS_CMP_ORDER
416     return \"cmpm%.w %0,%1\";
417 #else
418     return \"cmpm%.w %1,%0\";
419 #endif
420   if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
421       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
422     { cc_status.flags |= CC_REVERSED;
423 #ifdef SGS_CMP_ORDER
424       return \"cmp%.w %d1,%d0\";
425 #else
426       return \"cmp%.w %d0,%d1\";
427 #endif
428     }
429 #ifdef SGS_CMP_ORDER
430   return \"cmp%.w %d0,%d1\";
431 #else
432   return \"cmp%.w %d1,%d0\";
433 #endif
434 }")
435
436 (define_expand "cmpqi"
437   [(set (cc0)
438         (compare (match_operand:QI 0 "nonimmediate_src_operand" "")
439                  (match_operand:QI 1 "general_src_operand" "")))]
440   "!TARGET_5200"
441   "m68k_last_compare_had_fp_operands = 0;")
442
443 (define_insn ""
444   [(set (cc0)
445         (compare (match_operand:QI 0 "nonimmediate_src_operand" "dn,dmS,>")
446                  (match_operand:QI 1 "general_src_operand" "dmS,nd,>")))]
447   "!TARGET_5200"
448   "*
449 {
450   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
451 #ifdef SGS_CMP_ORDER
452     return \"cmpm%.b %0,%1\";
453 #else
454     return \"cmpm%.b %1,%0\";
455 #endif
456   if (REG_P (operands[1])
457       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
458     { cc_status.flags |= CC_REVERSED;
459 #ifdef SGS_CMP_ORDER
460       return \"cmp%.b %d1,%d0\";
461 #else
462       return \"cmp%.b %d0,%d1\";
463 #endif
464     }
465 #ifdef SGS_CMP_ORDER
466   return \"cmp%.b %d0,%d1\";
467 #else
468   return \"cmp%.b %d1,%d0\";
469 #endif
470 }")
471
472 (define_expand "cmpdf"
473   [(set (cc0)
474         (compare (match_operand:DF 0 "general_operand" "")
475                  (match_operand:DF 1 "general_operand" "")))]
476   "TARGET_68881"
477   "
478 {
479   m68k_last_compare_had_fp_operands = 1;
480 }")
481
482 (define_insn ""
483   [(set (cc0)
484         (compare (match_operand:DF 0 "general_operand" "f,mG")
485                  (match_operand:DF 1 "general_operand" "fmG,f")))]
486   "TARGET_68881"
487   "*
488 {
489   cc_status.flags = CC_IN_68881;
490 #ifdef SGS_CMP_ORDER
491   if (REG_P (operands[0]))
492     {
493       if (REG_P (operands[1]))
494         return \"fcmp%.x %0,%1\";
495       else
496         return \"fcmp%.d %0,%f1\";
497     }
498   cc_status.flags |= CC_REVERSED;
499   return \"fcmp%.d %1,%f0\";
500 #else
501   if (REG_P (operands[0]))
502     {
503       if (REG_P (operands[1]))
504         return \"fcmp%.x %1,%0\";
505       else
506         return \"fcmp%.d %f1,%0\";
507     }
508   cc_status.flags |= CC_REVERSED;
509   return \"fcmp%.d %f0,%1\";
510 #endif
511 }")
512
513 (define_expand "cmpsf"
514  [(set (cc0)
515        (compare (match_operand:SF 0 "general_operand" "")
516                 (match_operand:SF 1 "general_operand" "")))]
517  "TARGET_68881"
518  "
519 {
520   m68k_last_compare_had_fp_operands = 1;
521 }")
522
523 (define_insn ""
524   [(set (cc0)
525         (compare (match_operand:SF 0 "general_operand" "f,mdG")
526                  (match_operand:SF 1 "general_operand" "fmdG,f")))]
527   "TARGET_68881"
528   "*
529 {
530   cc_status.flags = CC_IN_68881;
531 #ifdef SGS_CMP_ORDER
532   if (FP_REG_P (operands[0]))
533     {
534       if (FP_REG_P (operands[1]))
535         return \"fcmp%.x %0,%1\";
536       else
537         return \"fcmp%.s %0,%f1\";
538     }
539   cc_status.flags |= CC_REVERSED;
540   return \"fcmp%.s %1,%f0\";
541 #else
542   if (FP_REG_P (operands[0]))
543     {
544       if (FP_REG_P (operands[1]))
545         return \"fcmp%.x %1,%0\";
546       else
547         return \"fcmp%.s %f1,%0\";
548     }
549   cc_status.flags |= CC_REVERSED;
550   return \"fcmp%.s %f0,%1\";
551 #endif
552 }")
553 \f
554 ;; Recognizers for btst instructions.
555
556 ;; Coldfire/5200 only allows "<Q>" type addresses when the bit position is
557 ;; specified as a constant, so we must disable all patterns that may extract
558 ;; from a MEM at a constant bit position if we can't use this as a constraint.
559
560 (define_insn ""
561   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_src_operand" "oS")
562                             (const_int 1)
563                             (minus:SI (const_int 7)
564                                       (match_operand:SI 1 "general_operand" "di"))))]
565   "!TARGET_5200"
566   "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
567
568 ;; This is the same as the above pattern except for the constraints.  The 'i'
569 ;; has been deleted.
570
571 (define_insn ""
572   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
573                             (const_int 1)
574                             (minus:SI (const_int 7)
575                                       (match_operand:SI 1 "general_operand" "d"))))]
576   "TARGET_5200"
577   "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
578
579 (define_insn ""
580   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
581                             (const_int 1)
582                             (minus:SI (const_int 31)
583                                       (match_operand:SI 1 "general_operand" "di"))))]
584   ""
585   "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
586
587 ;; The following two patterns are like the previous two
588 ;; except that they use the fact that bit-number operands
589 ;; are automatically masked to 3 or 5 bits.
590
591 (define_insn ""
592   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
593                             (const_int 1)
594                             (minus:SI (const_int 7)
595                                       (and:SI
596                                        (match_operand:SI 1 "register_operand" "d")
597                                        (const_int 7)))))]
598   ""
599   "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
600
601 (define_insn ""
602   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
603                             (const_int 1)
604                             (minus:SI (const_int 31)
605                                       (and:SI
606                                        (match_operand:SI 1 "register_operand" "d")
607                                        (const_int 31)))))]
608   ""
609   "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
610
611 ;; Nonoffsettable mem refs are ok in this one pattern
612 ;; since we don't try to adjust them.
613 (define_insn ""
614   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
615                             (const_int 1)
616                             (match_operand:SI 1 "const_int_operand" "n")))]
617   "(unsigned) INTVAL (operands[1]) < 8 && !TARGET_5200"
618   "*
619 {
620   operands[1] = GEN_INT (7 - INTVAL (operands[1]));
621   return output_btst (operands, operands[1], operands[0], insn, 7);
622 }")
623
624 (define_insn ""
625   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "do")
626                             (const_int 1)
627                             (match_operand:SI 1 "const_int_operand" "n")))]
628   "!TARGET_5200"
629   "*
630 {
631   if (GET_CODE (operands[0]) == MEM)
632     {
633       operands[0] = adjust_address (operands[0], QImode,
634                                     INTVAL (operands[1]) / 8);
635       operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
636       return output_btst (operands, operands[1], operands[0], insn, 7);
637     }
638   operands[1] = GEN_INT (31 - INTVAL (operands[1]));
639   return output_btst (operands, operands[1], operands[0], insn, 31);
640 }")
641
642 ;; This is the same as the above pattern except for the constraints.
643 ;; The 'o' has been replaced with 'Q'.
644
645 (define_insn ""
646   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "dQ")
647                             (const_int 1)
648                             (match_operand:SI 1 "const_int_operand" "n")))]
649   "TARGET_5200"
650   "*
651 {
652   if (GET_CODE (operands[0]) == MEM)
653     {
654       operands[0] = adjust_address (operands[0], QImode,
655                                     INTVAL (operands[1]) / 8);
656       operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
657       return output_btst (operands, operands[1], operands[0], insn, 7);
658     }
659   operands[1] = GEN_INT (31 - INTVAL (operands[1]));
660   return output_btst (operands, operands[1], operands[0], insn, 31);
661 }")
662
663 \f
664 ;; move instructions
665
666 ;; A special case in which it is not desirable
667 ;; to reload the constant into a data register.
668 (define_insn "pushexthisi_const"
669   [(set (match_operand:SI 0 "push_operand" "=m")
670         (match_operand:SI 1 "const_int_operand" "J"))]
671   "INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000"
672   "*
673 {
674   if (operands[1] == const0_rtx)
675     return \"clr%.l %0\";
676   return \"pea %a1\";
677 }")
678
679 ;This is never used.
680 ;(define_insn "swapsi"
681 ;  [(set (match_operand:SI 0 "nonimmediate_operand" "+r")
682 ;       (match_operand:SI 1 "general_operand" "+r"))
683 ;   (set (match_dup 1) (match_dup 0))]
684 ;  ""
685 ;  "exg %1,%0")
686
687 ;; Special case of fullword move when source is zero.
688 ;; The reason this is special is to avoid loading a zero
689 ;; into a data reg with moveq in order to store it elsewhere.
690
691 (define_insn "movsi_const0"
692   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
693         (const_int 0))]
694   ;; clr insns on 68000 read before writing.
695   ;; This isn't so on the 68010, but we have no TARGET_68010.
696   "((TARGET_68020 || TARGET_5200)
697     || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))"
698   "*
699 {
700   if (ADDRESS_REG_P (operands[0]))
701     {
702       /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
703       if (!TARGET_68040 && !TARGET_68060)
704         return \"sub%.l %0,%0\";
705       else
706         {
707 #ifdef MOTOROLA
708 #ifdef SGS
709           /* Many SGS assemblers croak on size specifiers for constants.  */
710           return \"lea 0,%0\";
711 #else
712           return \"lea 0.w,%0\";
713 #endif
714 #else
715           return \"lea 0:w,%0\";
716 #endif
717         }
718     }
719   /* moveq is faster on the 68000.  */
720   if (DATA_REG_P (operands[0]) && (!TARGET_68020 && !TARGET_5200))
721 #if defined(MOTOROLA)
722     return \"moveq%.l %#0,%0\";
723 #else
724     return \"moveq %#0,%0\";
725 #endif
726   return \"clr%.l %0\";
727 }")
728
729 ;; General case of fullword move.
730 ;;
731 ;; This is the main "hook" for PIC code.  When generating
732 ;; PIC, movsi is responsible for determining when the source address
733 ;; needs PIC relocation and appropriately calling legitimize_pic_address
734 ;; to perform the actual relocation.
735 ;;
736 ;; In both the PIC and non-PIC cases the patterns generated will
737 ;; matched by the next define_insn.
738 (define_expand "movsi"
739   [(set (match_operand:SI 0 "nonimmediate_operand" "")
740         (match_operand:SI 1 "general_operand" ""))]
741   ""
742   "
743 {
744   if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
745     {
746       /* The source is an address which requires PIC relocation.
747          Call legitimize_pic_address with the source, mode, and a relocation
748          register (a new pseudo, or the final destination if reload_in_progress
749          is set).   Then fall through normally */
750       rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
751       operands[1] = legitimize_pic_address (operands[1], SImode, temp);
752     }
753   else if (flag_pic && TARGET_PCREL && ! reload_in_progress)
754     {
755       /* Don't allow writes to memory except via a register;
756          the m68k doesn't consider PC-relative addresses to be writable.  */
757       if (symbolic_operand (operands[0], SImode))
758         operands[0] = force_reg (SImode, XEXP (operands[0], 0));
759       else if (GET_CODE (operands[0]) == MEM
760                && symbolic_operand (XEXP (operands[0], 0), SImode))
761         operands[0] = gen_rtx (MEM, SImode,
762                                force_reg (SImode, XEXP (operands[0], 0)));
763     }
764 }")
765
766 ;; General case of fullword move.  The register constraints
767 ;; force integer constants in range for a moveq to be reloaded
768 ;; if they are headed for memory.
769 (define_insn ""
770   ;; Notes: make sure no alternative allows g vs g.
771   ;; We don't allow f-regs since fixed point cannot go in them.
772   [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
773         (match_operand:SI 1 "general_src_operand" "daymSKT,n,i"))]
774
775   "!TARGET_5200"
776   "*
777 {
778   return output_move_simode (operands);
779 }")
780
781 (define_insn ""
782   [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g")
783         (match_operand:SI 1 "general_operand" "g,r<Q>"))]
784   "TARGET_5200"
785   "* return output_move_simode (operands);")
786
787 ;; Special case of fullword move, where we need to get a non-GOT PIC
788 ;; reference into an address register.
789 (define_insn ""
790   [(set (match_operand:SI 0 "nonimmediate_operand" "=a<")
791         (match_operand:SI 1 "pcrel_address" ""))]
792   "TARGET_PCREL"
793   "*
794 {
795   if (push_operand (operands[0], SImode))
796     return \"pea %a1\";
797   return \"lea %a1,%0\";
798 }")
799
800 (define_expand "movhi"
801   [(set (match_operand:HI 0 "nonimmediate_operand" "")
802         (match_operand:HI 1 "general_operand" ""))]
803   ""
804   "")
805
806 (define_insn ""
807   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
808         (match_operand:HI 1 "general_src_operand" "gS"))]
809   "!TARGET_5200"
810   "* return output_move_himode (operands);")
811
812  (define_insn ""
813   [(set (match_operand:HI 0 "nonimmediate_operand" "=r<Q>,g")
814         (match_operand:HI 1 "general_operand" "g,r<Q>"))]
815   "TARGET_5200"
816   "* return output_move_himode (operands);")
817
818 (define_expand "movstricthi"
819   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
820         (match_operand:HI 1 "general_src_operand" ""))]
821   ""
822   "")
823
824 (define_insn ""
825   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
826         (match_operand:HI 1 "general_src_operand" "rmSn"))]
827   "!TARGET_5200"
828   "* return output_move_stricthi (operands);")
829
830 (define_insn ""
831   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+d,m"))
832         (match_operand:HI 1 "general_src_operand" "rmn,r"))]
833   "TARGET_5200"
834   "* return output_move_stricthi (operands);")
835
836 (define_expand "movqi"
837   [(set (match_operand:QI 0 "nonimmediate_operand" "")
838         (match_operand:QI 1 "general_src_operand" ""))]
839   ""
840   "")
841
842 (define_insn ""
843   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,*a,m")
844         (match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))]
845   "!TARGET_5200"
846   "* return output_move_qimode (operands);")
847
848 (define_insn ""
849   [(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>,dm,d*a")
850         (match_operand:QI 1 "general_src_operand" "dmi,d<Q>,di*a"))]
851   "TARGET_5200"
852   "* return output_move_qimode (operands);")
853
854 (define_expand "movstrictqi"
855   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
856         (match_operand:QI 1 "general_src_operand" ""))]
857   ""
858   "")
859
860 (define_insn ""
861   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
862         (match_operand:QI 1 "general_src_operand" "dmSn"))]
863   "!TARGET_5200"
864   "* return output_move_strictqi (operands);")
865
866 (define_insn ""
867   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d,m"))
868         (match_operand:QI 1 "general_src_operand" "dmn,d"))]
869   "TARGET_5200"
870   "* return output_move_strictqi (operands);")
871
872 (define_expand "pushqi1"
873   [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int -2)))
874    (set (mem:QI (plus:SI (reg:SI 15) (const_int 1)))
875         (match_operand:QI 0 "general_operand" ""))]
876   "!TARGET_5200"
877   "")
878
879 (define_expand "movsf"
880   [(set (match_operand:SF 0 "nonimmediate_operand" "")
881         (match_operand:SF 1 "general_operand" ""))]
882   ""
883   "")
884
885 (define_insn ""
886   [(set (match_operand:SF 0 "nonimmediate_operand" "=rmf")
887         (match_operand:SF 1 "general_operand" "rmfF"))]
888   "!TARGET_5200"
889   "*
890 {
891   if (FP_REG_P (operands[0]))
892     {
893       if (FP_REG_P (operands[1]))
894         return \"f%$move%.x %1,%0\";
895       else if (ADDRESS_REG_P (operands[1]))
896         return \"move%.l %1,%-\;f%$move%.s %+,%0\";
897       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
898         return output_move_const_single (operands);
899       return \"f%$move%.s %f1,%0\";
900     }
901   if (FP_REG_P (operands[1]))
902     {
903       if (ADDRESS_REG_P (operands[0]))
904         return \"fmove%.s %1,%-\;move%.l %+,%0\";
905       return \"fmove%.s %f1,%0\";
906     }
907   if (operands[1] == CONST0_RTX (SFmode)
908       /* clr insns on 68000 read before writing.
909          This isn't so on the 68010, but we have no TARGET_68010.  */
910       && ((TARGET_68020 || TARGET_5200)
911           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
912     {
913       if (ADDRESS_REG_P (operands[0]))
914         {
915           /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
916           if (!TARGET_68040 && !TARGET_68060)
917             return \"sub%.l %0,%0\";
918           else
919             {
920 #ifdef MOTOROLA
921 #ifdef SGS
922               /* Many SGS assemblers croak on size specifiers for constants.  */
923               return \"lea 0,%0\";
924 #else
925               return \"lea 0.w,%0\";
926 #endif
927 #else
928               return \"lea 0:w,%0\";
929 #endif
930             }
931         }
932       /* moveq is faster on the 68000.  */
933       if (DATA_REG_P (operands[0]) && !(TARGET_68020 || TARGET_5200))
934         {
935 #if defined(MOTOROLA)
936           return \"moveq%.l %#0,%0\";
937 #else
938           return \"moveq %#0,%0\";
939 #endif
940         }
941       return \"clr%.l %0\";
942     }
943   return \"move%.l %1,%0\";
944 }")
945
946 (define_insn ""
947   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,g")
948         (match_operand:SF 1 "general_operand" "g,r"))]
949   "TARGET_5200"
950   "* return \"move%.l %1,%0\";")
951
952 (define_expand "movdf"
953   [(set (match_operand:DF 0 "nonimmediate_operand" "")
954         (match_operand:DF 1 "general_operand" ""))]
955   ""
956   "")
957
958 (define_insn ""
959   [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,rf,rf,&rof<>")
960         (match_operand:DF 1 "general_operand" "*rf,m,0,*rofE<>"))]
961 ;  [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,&rf,&rof<>")
962 ;       (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
963   "!TARGET_5200"
964   "*
965 {
966   if (FP_REG_P (operands[0]))
967     {
968       if (FP_REG_P (operands[1]))
969         return \"f%&move%.x %1,%0\";
970       if (REG_P (operands[1]))
971         {
972           rtx xoperands[2];
973           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
974           output_asm_insn (\"move%.l %1,%-\", xoperands);
975           output_asm_insn (\"move%.l %1,%-\", operands);
976           return \"f%&move%.d %+,%0\";
977         }
978       if (GET_CODE (operands[1]) == CONST_DOUBLE)
979         return output_move_const_double (operands);
980       return \"f%&move%.d %f1,%0\";
981     }
982   else if (FP_REG_P (operands[1]))
983     {
984       if (REG_P (operands[0]))
985         {
986           output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
987           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
988           return \"move%.l %+,%0\";
989         }
990       else
991         return \"fmove%.d %f1,%0\";
992     }
993   return output_move_double (operands);
994 }")
995
996 (define_insn ""
997   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,g")
998         (match_operand:DF 1 "general_operand" "g,r"))]
999   "TARGET_5200"
1000   "* return output_move_double (operands);")
1001
1002 ;; ??? The XFmode patterns are schizophrenic about whether constants are
1003 ;; allowed.  Most but not all have predicates and constraint that disallow
1004 ;; constants.  Most but not all have output templates that handle constants.
1005 ;; See also LEGITIMATE_CONSTANT_P.
1006
1007 (define_expand "movxf"
1008   [(set (match_operand:XF 0 "nonimmediate_operand" "")
1009         (match_operand:XF 1 "general_operand" ""))]
1010   ""
1011   "
1012 {
1013   /* We can't rewrite operands during reload.  */
1014   if (! reload_in_progress)
1015     {
1016       if (CONSTANT_P (operands[1]))
1017         {
1018           operands[1] = force_const_mem (XFmode, operands[1]);
1019           if (! memory_address_p (XFmode, XEXP (operands[1], 0)))
1020             operands[1] = adjust_address (operands[1], XFmode, 0);
1021         }
1022       if (flag_pic && TARGET_PCREL)
1023         {
1024           /* Don't allow writes to memory except via a register; the
1025              m68k doesn't consider PC-relative addresses to be writable.  */
1026           if (GET_CODE (operands[0]) == MEM
1027               && symbolic_operand (XEXP (operands[0], 0), SImode))
1028             operands[0] = gen_rtx (MEM, XFmode,
1029                                    force_reg (SImode, XEXP (operands[0], 0)));
1030         }
1031     }
1032 }")
1033
1034 (define_insn ""
1035   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f,!r")
1036         (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r,!r"))]
1037   "TARGET_68881"
1038   "*
1039 {
1040   if (FP_REG_P (operands[0]))
1041     {
1042       if (FP_REG_P (operands[1]))
1043         return \"fmove%.x %1,%0\";
1044       if (REG_P (operands[1]))
1045         {
1046           rtx xoperands[2];
1047           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1048           output_asm_insn (\"move%.l %1,%-\", xoperands);
1049           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1050           output_asm_insn (\"move%.l %1,%-\", xoperands);
1051           output_asm_insn (\"move%.l %1,%-\", operands);
1052           return \"fmove%.x %+,%0\";
1053         }
1054       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1055         return \"fmove%.x %1,%0\";
1056       return \"fmove%.x %f1,%0\";
1057     }
1058   if (FP_REG_P (operands[1]))
1059     {
1060       if (REG_P (operands[0]))
1061         {
1062           output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
1063           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1064           output_asm_insn (\"move%.l %+,%0\", operands);
1065           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1066           return \"move%.l %+,%0\";
1067         }
1068       /* Must be memory destination.  */
1069       return \"fmove%.x %f1,%0\";
1070     }
1071   return output_move_double (operands);
1072 }
1073 ")
1074
1075 (define_insn ""
1076   [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
1077         (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))]
1078   "! TARGET_68881 && ! TARGET_5200"
1079   "*
1080 {
1081   if (FP_REG_P (operands[0]))
1082     {
1083       if (FP_REG_P (operands[1]))
1084         return \"fmove%.x %1,%0\";
1085       if (REG_P (operands[1]))
1086         {
1087           rtx xoperands[2];
1088           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1089           output_asm_insn (\"move%.l %1,%-\", xoperands);
1090           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1091           output_asm_insn (\"move%.l %1,%-\", xoperands);
1092           output_asm_insn (\"move%.l %1,%-\", operands);
1093           return \"fmove%.x %+,%0\";
1094         }
1095       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1096         return \"fmove%.x %1,%0\";
1097       return \"fmove%.x %f1,%0\";
1098     }
1099   if (FP_REG_P (operands[1]))
1100     {
1101       if (REG_P (operands[0]))
1102         {
1103           output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
1104           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1105           output_asm_insn (\"move%.l %+,%0\", operands);
1106           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1107           return \"move%.l %+,%0\";
1108         }
1109       else
1110         return \"fmove%.x %f1,%0\";
1111     }
1112   return output_move_double (operands);
1113 }
1114 ")
1115
1116 (define_insn ""
1117   [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g")
1118         (match_operand:XF 1 "nonimmediate_operand" "g,r"))]
1119   "! TARGET_68881 && TARGET_5200"
1120   "* return output_move_double (operands);")
1121
1122 (define_expand "movdi"
1123   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1124   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1125         (match_operand:DI 1 "general_operand" ""))]
1126   ""
1127   "")
1128
1129 ;; movdi can apply to fp regs in some cases
1130 (define_insn ""
1131   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1132   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r,&ro<>")
1133         (match_operand:DI 1 "general_operand" "rF,m,roi<>F"))]
1134 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&r,&ro<>,!&rm,!&f")
1135 ;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF"))]
1136 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&rf,&ro<>,!&rm,!&f")
1137 ;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
1138   "!TARGET_5200"
1139   "*
1140 {
1141   if (FP_REG_P (operands[0]))
1142     {
1143       if (FP_REG_P (operands[1]))
1144         return \"fmove%.x %1,%0\";
1145       if (REG_P (operands[1]))
1146         {
1147           rtx xoperands[2];
1148           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1149           output_asm_insn (\"move%.l %1,%-\", xoperands);
1150           output_asm_insn (\"move%.l %1,%-\", operands);
1151           return \"fmove%.d %+,%0\";
1152         }
1153       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1154         return output_move_const_double (operands);
1155       return \"fmove%.d %f1,%0\";
1156     }
1157   else if (FP_REG_P (operands[1]))
1158     {
1159       if (REG_P (operands[0]))
1160         {
1161           output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1162           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1163           return \"move%.l %+,%0\";
1164         }
1165       else
1166         return \"fmove%.d %f1,%0\";
1167     }
1168   return output_move_double (operands);
1169 }")
1170
1171 (define_insn ""
1172   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,g")
1173         (match_operand:DI 1 "general_operand" "g,r"))]
1174   "TARGET_5200"
1175   "* return output_move_double (operands);")
1176
1177 ;; Thus goes after the move instructions
1178 ;; because the move instructions are better (require no spilling)
1179 ;; when they can apply.  It goes before the add/sub insns
1180 ;; so we will prefer it to them.
1181
1182 (define_insn "pushasi"
1183   [(set (match_operand:SI 0 "push_operand" "=m")
1184         (match_operand:SI 1 "address_operand" "p"))]
1185   ""
1186   "pea %a1")
1187 \f
1188 ;; truncation instructions
1189 (define_insn "truncsiqi2"
1190   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
1191         (truncate:QI
1192          (match_operand:SI 1 "general_src_operand" "doJS,i")))]
1193   ""
1194   "*
1195 {
1196   if (GET_CODE (operands[0]) == REG)
1197     {
1198       /* Must clear condition codes, since the move.l bases them on
1199          the entire 32 bits, not just the desired 8 bits.  */
1200       CC_STATUS_INIT;
1201       return \"move%.l %1,%0\";
1202     }
1203   if (GET_CODE (operands[1]) == MEM)
1204     operands[1] = adjust_address (operands[1], QImode, 3);
1205   return \"move%.b %1,%0\";
1206 }")
1207
1208 (define_insn "trunchiqi2"
1209   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
1210         (truncate:QI
1211          (match_operand:HI 1 "general_src_operand" "doJS,i")))]
1212   ""
1213   "*
1214 {
1215   if (GET_CODE (operands[0]) == REG
1216       && (GET_CODE (operands[1]) == MEM
1217           || GET_CODE (operands[1]) == CONST_INT))
1218     {
1219       /* Must clear condition codes, since the move.w bases them on
1220          the entire 16 bits, not just the desired 8 bits.  */
1221       CC_STATUS_INIT;
1222       return \"move%.w %1,%0\";
1223     }
1224   if (GET_CODE (operands[0]) == REG)
1225     {
1226       /* Must clear condition codes, since the move.l bases them on
1227          the entire 32 bits, not just the desired 8 bits.  */
1228       CC_STATUS_INIT;
1229       return \"move%.l %1,%0\";
1230     }
1231   if (GET_CODE (operands[1]) == MEM)
1232     operands[1] = adjust_address (operands[1], QImode, 1);
1233   return \"move%.b %1,%0\";
1234 }")
1235
1236 (define_insn "truncsihi2"
1237   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm,d")
1238         (truncate:HI
1239          (match_operand:SI 1 "general_src_operand" "roJS,i")))]
1240   ""
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, 2);
1252   return \"move%.w %1,%0\";
1253 }")
1254 \f
1255 ;; zero extension instructions
1256
1257 (define_insn "zero_extendqidi2"
1258   [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
1259         (zero_extend:DI (match_operand:QI 1 "general_operand" "dm")))]
1260   ""
1261   "*
1262 {
1263   CC_STATUS_INIT;
1264   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1265   return \"moveq %#0,%0\;moveq %#0,%2\;move%.b %1,%2\";
1266 }")
1267
1268 (define_insn "zero_extendhidi2"
1269   [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
1270         (zero_extend:DI (match_operand:HI 1 "general_operand" "rm")))]
1271   ""
1272   "*
1273 {
1274   CC_STATUS_INIT;
1275   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1276   return \"moveq %#0,%0\;moveq %#0,%2\;move%.w %1,%2\";
1277 }")
1278
1279 ;; this is the canonical form for (lshiftrt:DI x 32)
1280 (define_expand "zero_extendsidi2"
1281   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1282     (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
1283   ""
1284   "")
1285
1286 (define_insn "*zero_extendsidi2_cf"
1287   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
1288     (zero_extend:DI (match_operand:SI 1 "general_operand" "rm,r")))]
1289   "TARGET_5200"
1290   "*
1291 {
1292   CC_STATUS_INIT;
1293   if (GET_CODE (operands[0]) == REG)
1294     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1295   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1296     return \"move%.l %1,%0\;clr%.l %0\";
1297   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1298     return \"clr%.l %0\;move%.l %1,%0\";
1299   else
1300     operands[2] = adjust_address (operands[0], SImode, 4);
1301   if (GET_CODE (operands[1]) != REG || GET_CODE (operands[2]) != REG
1302       || REGNO (operands[1]) != REGNO (operands[2]))
1303     output_asm_insn (\"move%.l %1,%2\", operands);
1304   if (ADDRESS_REG_P (operands[0]))
1305     return \"sub%.l %0,%0\";
1306   else
1307     return \"clr%.l %0\";
1308 }")
1309
1310 (define_insn "*zero_extendsidi2"
1311   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1312     (zero_extend:DI (match_operand:SI 1 "general_operand" "rm")))]
1313   "!TARGET_5200"
1314   "*
1315 {
1316   CC_STATUS_INIT;
1317   if (GET_CODE (operands[0]) == REG)
1318     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1319   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1320     return \"move%.l %1,%0\;clr%.l %0\";
1321   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1322     return \"clr%.l %0\;move%.l %1,%0\";
1323   else
1324     operands[2] = adjust_address (operands[0], SImode, 4);
1325   if (GET_CODE (operands[1]) != REG || GET_CODE (operands[2]) != REG
1326       || REGNO (operands[1]) != REGNO (operands[2]))
1327     output_asm_insn (\"move%.l %1,%2\", operands);
1328   if (ADDRESS_REG_P (operands[0]))
1329     return \"sub%.l %0,%0\";
1330   else
1331     return \"clr%.l %0\";
1332 }")
1333
1334 (define_expand "zero_extendhisi2"
1335   [(set (match_operand:SI 0 "register_operand" "")
1336         (const_int 0))
1337    (set (strict_low_part (match_dup 2))
1338         (match_operand:HI 1 "general_operand" ""))]
1339   ""
1340   "
1341 {
1342   operands[1] = make_safe_from (operands[1], operands[0]);
1343   operands[2] = gen_lowpart_SUBREG (HImode, operands[0]);
1344 }")
1345
1346 (define_expand "zero_extendqihi2"
1347   [(set (match_operand:HI 0 "register_operand" "")
1348         (const_int 0))
1349    (set (strict_low_part (match_dup 2))
1350         (match_operand:QI 1 "general_operand" ""))]
1351   ""
1352   "
1353 {
1354   operands[1] = make_safe_from (operands[1], operands[0]);
1355   operands[2] = gen_lowpart_SUBREG (QImode, operands[0]);
1356 }")
1357
1358 (define_expand "zero_extendqisi2"
1359   [(set (match_operand:SI 0 "register_operand" "")
1360         (const_int 0))
1361    (set (strict_low_part (match_dup 2))
1362         (match_operand:QI 1 "general_operand" ""))]
1363   ""
1364   "
1365 {
1366   operands[1] = make_safe_from (operands[1], operands[0]);
1367   operands[2] = gen_lowpart_SUBREG (QImode, operands[0]);
1368 }")
1369 \f
1370 ;; Patterns to recognize zero-extend insns produced by the combiner.
1371 ;; We don't allow both operands in memory, because of aliasing problems.
1372 ;; Explicitly disallow two memory operands via the condition since reloading
1373 ;; of this case will result in worse code than the uncombined patterns.
1374
1375 (define_insn ""
1376   [(set (match_operand:SI 0 "nonimmediate_operand" "=do<>,d<")
1377         (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "r,mS")))]
1378   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1379   "*
1380 {
1381   if (DATA_REG_P (operands[0]))
1382     {
1383       if (GET_CODE (operands[1]) == REG
1384           && REGNO (operands[0]) == REGNO (operands[1]))
1385         return \"and%.l %#0xFFFF,%0\";
1386       if (reg_mentioned_p (operands[0], operands[1]))
1387         return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\";
1388       return \"clr%.l %0\;move%.w %1,%0\";
1389     }
1390   else if (GET_CODE (operands[0]) == MEM
1391            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1392     return \"move%.w %1,%0\;clr%.w %0\";
1393   else if (GET_CODE (operands[0]) == MEM
1394            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1395     return \"clr%.w %0\;move%.w %1,%0\";
1396   else
1397     {
1398       output_asm_insn (\"clr%.w %0\", operands);
1399       operands[0] = adjust_address (operands[0], HImode, 2);
1400       return \"move%.w %1,%0\";
1401     }
1402 }")
1403
1404 (define_insn ""
1405   [(set (match_operand:HI 0 "nonimmediate_operand" "=do<>,d")
1406         (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
1407   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1408   "*
1409 {
1410   if (DATA_REG_P (operands[0]))
1411     {
1412       if (GET_CODE (operands[1]) == REG
1413           && REGNO (operands[0]) == REGNO (operands[1]))
1414         return (!TARGET_5200 ? \"and%.w %#0xFF,%0\" : \"and%.l %#0xFF,%0\");
1415       if (reg_mentioned_p (operands[0], operands[1]))
1416         return (!TARGET_5200 ? \"move%.b %1,%0\;and%.w %#0xFF,%0\" 
1417                              : \"move%.b %1,%0\;and%.l %#0xFF,%0\");
1418       return \"clr%.w %0\;move%.b %1,%0\";
1419     }
1420   else if (GET_CODE (operands[0]) == MEM
1421            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1422     {
1423       if (REGNO (XEXP (XEXP (operands[0], 0), 0))
1424           == STACK_POINTER_REGNUM)
1425         {
1426           output_asm_insn (\"clr%.w %-\", operands);
1427           operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
1428                                      plus_constant (stack_pointer_rtx, 1));
1429           return \"move%.b %1,%0\";
1430         }
1431       else
1432         return \"move%.b %1,%0\;clr%.b %0\";
1433     }
1434   else if (GET_CODE (operands[0]) == MEM
1435            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1436     return \"clr%.b %0\;move%.b %1,%0\";
1437   else
1438     {
1439       output_asm_insn (\"clr%.b %0\", operands);
1440       operands[0] = adjust_address (operands[0], QImode, 1);
1441       return \"move%.b %1,%0\";
1442     }
1443 }")
1444
1445 (define_insn ""
1446   [(set (match_operand:SI 0 "nonimmediate_operand" "=do<>,d")
1447         (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
1448   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1449   "*
1450 {
1451   if (DATA_REG_P (operands[0]))
1452     {
1453       if (GET_CODE (operands[1]) == REG
1454           && REGNO (operands[0]) == REGNO (operands[1]))
1455         return \"and%.l %#0xFF,%0\";
1456       if (reg_mentioned_p (operands[0], operands[1]))
1457         return \"move%.b %1,%0\;and%.l %#0xFF,%0\";
1458       return \"clr%.l %0\;move%.b %1,%0\";
1459     }
1460   else if (GET_CODE (operands[0]) == MEM
1461            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1462     {
1463       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1464 #ifdef MOTOROLA
1465 #ifdef SGS
1466       return \"clr%.l -(%0)\;move%.b %1,3(%0)\";
1467 #else
1468       return \"clr%.l -(%0)\;move%.b %1,(3,%0)\";
1469 #endif
1470 #else
1471       return \"clrl %0@-\;moveb %1,%0@(3)\";
1472 #endif
1473     }
1474   else if (GET_CODE (operands[0]) == MEM
1475            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1476     {
1477       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1478 #ifdef MOTOROLA
1479 #ifdef SGS
1480       return \"clr%.l (%0)+\;move%.b %1,-1(%0)\";
1481 #else
1482       return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\";
1483 #endif
1484 #else
1485       return \"clrl %0@+\;moveb %1,%0@(-1)\";
1486 #endif
1487     }
1488   else
1489     {
1490       output_asm_insn (\"clr%.l %0\", operands);
1491       operands[0] = adjust_address (operands[0], QImode, 3);
1492       return \"move%.b %1,%0\";
1493     }
1494 }")
1495 \f
1496 ;; sign extension instructions
1497
1498 (define_insn "extendqidi2"
1499   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1500         (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))]
1501   ""
1502   "*
1503 {
1504   CC_STATUS_INIT;
1505   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1506   if (TARGET_68020 || TARGET_5200)
1507     return \"move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0\";
1508   else
1509     return \"move%.b %1,%2\;ext%.w %0\;ext%.l %2\;move%.l %2,%0\;smi %0\";
1510 }")
1511
1512 (define_insn "extendhidi2"
1513   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1514         (sign_extend:DI
1515          (match_operand:HI 1 "general_src_operand" "rmS")))]
1516   ""
1517   "*
1518 {
1519   CC_STATUS_INIT;
1520   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1521   if (TARGET_68020 || TARGET_5200)
1522     return \"move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0\";
1523   else
1524     return \"move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0\";
1525 }")
1526
1527 (define_insn "extendsidi2"
1528   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1529         (sign_extend:DI
1530          (match_operand:SI 1 "general_operand" "rm")))]
1531   ""
1532   "*
1533 {
1534   CC_STATUS_INIT;
1535   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1536   if (TARGET_68020 || TARGET_5200)
1537     return \"move%.l %1,%2\;smi %0\;extb%.l %0\";
1538   else
1539     return \"move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0\";
1540 }")
1541
1542 ;; Special case when one can avoid register clobbering, copy and test
1543 ;; Maybe there is a way to make that the general case, by forcing the
1544 ;; result of the SI tree to be in the lower register of the DI target
1545
1546 (define_insn "extendplussidi"
1547   [(set (match_operand:DI 0 "register_operand" "=d")
1548     (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
1549             (match_operand:SI 2 "general_operand" "rmn"))))]
1550   ""
1551   "*
1552 {
1553   CC_STATUS_INIT;
1554   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1555   if (GET_CODE (operands[1]) == CONST_INT
1556   && (unsigned) INTVAL (operands[1]) > 8)
1557     {
1558       rtx tmp = operands[1];
1559
1560       operands[1] = operands[2];
1561       operands[2] = tmp;
1562     }
1563   if (GET_CODE (operands[1]) == REG
1564       && REGNO (operands[1]) == REGNO (operands[3]))
1565     output_asm_insn (\"add%.l %2,%3\", operands);
1566   else
1567     output_asm_insn (\"move%.l %2,%3\;add%.l %1,%3\", operands);
1568   if (TARGET_68020 || TARGET_5200)
1569     return \"smi %0\;extb%.l %0\";
1570   else
1571     return \"smi %0\;ext%.w %0\;ext%.l %0\";
1572 }")
1573
1574 (define_insn "extendhisi2"
1575   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
1576         (sign_extend:SI
1577          (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
1578   ""
1579   "*
1580 {
1581   if (ADDRESS_REG_P (operands[0]))
1582     return \"move%.w %1,%0\";
1583   return \"ext%.l %0\";
1584 }")
1585
1586 (define_insn "extendqihi2"
1587   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
1588         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1589   ""
1590   "ext%.w %0")
1591
1592 (define_insn "extendqisi2"
1593   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
1594         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1595   "TARGET_68020 || TARGET_5200"
1596   "extb%.l %0")
1597 \f
1598 ;; Conversions between float and double.
1599
1600 (define_expand "extendsfdf2"
1601   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1602         (float_extend:DF
1603          (match_operand:SF 1 "general_operand" "")))]
1604   "TARGET_68881"
1605   "")
1606
1607 (define_insn ""
1608   [(set (match_operand:DF 0 "nonimmediate_operand" "=*fdm,f")
1609         (float_extend:DF
1610           (match_operand:SF 1 "general_operand" "f,dmF")))]
1611   "TARGET_68881"
1612   "*
1613 {
1614   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1615     {
1616       if (REGNO (operands[0]) == REGNO (operands[1]))
1617         {
1618           /* Extending float to double in an fp-reg is a no-op.
1619              NOTICE_UPDATE_CC has already assumed that the
1620              cc will be set.  So cancel what it did.  */
1621           cc_status = cc_prev_status;
1622           return \"\";
1623         }
1624       return \"f%&move%.x %1,%0\";
1625     }
1626   if (FP_REG_P (operands[0]))
1627     return \"f%&move%.s %f1,%0\";
1628   if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
1629     {
1630       output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1631       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1632       return \"move%.l %+,%0\";
1633     }
1634   return \"fmove%.d %f1,%0\";
1635 }")
1636
1637 ;; This cannot output into an f-reg because there is no way to be
1638 ;; sure of truncating in that case.
1639 (define_expand "truncdfsf2"
1640   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1641         (float_truncate:SF
1642           (match_operand:DF 1 "general_operand" "")))]
1643   "TARGET_68881"
1644   "")
1645
1646 ;; On the '040 we can truncate in a register accurately and easily.
1647 (define_insn ""
1648   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1649         (float_truncate:SF
1650           (match_operand:DF 1 "general_operand" "fmG")))]
1651   "TARGET_68040_ONLY"
1652   "*
1653 {
1654   if (FP_REG_P (operands[1]))
1655     return \"f%$move%.x %1,%0\";
1656   return \"f%$move%.d %f1,%0\";
1657 }")
1658
1659 (define_insn ""
1660   [(set (match_operand:SF 0 "nonimmediate_operand" "=dm")
1661         (float_truncate:SF
1662           (match_operand:DF 1 "general_operand" "f")))]
1663   "TARGET_68881"
1664   "fmove%.s %f1,%0")
1665 \f
1666 ;; Conversion between fixed point and floating point.
1667 ;; Note that among the fix-to-float insns
1668 ;; the ones that start with SImode come first.
1669 ;; That is so that an operand that is a CONST_INT
1670 ;; (and therefore lacks a specific machine mode).
1671 ;; will be recognized as SImode (which is always valid)
1672 ;; rather than as QImode or HImode.
1673
1674 (define_expand "floatsisf2"
1675   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1676         (float:SF (match_operand:SI 1 "general_operand" "")))]
1677   "TARGET_68881"
1678   "")
1679
1680 (define_insn ""
1681   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1682         (float:SF (match_operand:SI 1 "general_operand" "dmi")))]
1683   "TARGET_68881"
1684   "f%$move%.l %1,%0")
1685
1686 (define_expand "floatsidf2"
1687   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1688         (float:DF (match_operand:SI 1 "general_operand" "")))]
1689   "TARGET_68881"
1690   "")
1691
1692 (define_insn ""
1693   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1694         (float:DF (match_operand:SI 1 "general_operand" "dmi")))]
1695   "TARGET_68881"
1696   "f%&move%.l %1,%0")
1697
1698 (define_insn "floathisf2"
1699   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1700         (float:SF (match_operand:HI 1 "general_operand" "dmn")))]
1701   "TARGET_68881"
1702   "f%$move%.w %1,%0")
1703
1704 (define_insn "floathidf2"
1705   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1706         (float:DF (match_operand:HI 1 "general_operand" "dmn")))]
1707   "TARGET_68881"
1708   "fmove%.w %1,%0")
1709
1710 (define_insn "floatqisf2"
1711   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1712         (float:SF (match_operand:QI 1 "general_operand" "dmn")))]
1713   "TARGET_68881"
1714   "fmove%.b %1,%0")
1715
1716 (define_insn "floatqidf2"
1717   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1718         (float:DF (match_operand:QI 1 "general_operand" "dmn")))]
1719   "TARGET_68881"
1720   "f%&move%.b %1,%0")
1721
1722 ;; New routines to convert floating-point values to integers
1723 ;; to be used on the '040.  These should be faster than trapping
1724 ;; into the kernel to emulate fintrz.  They should also be faster
1725 ;; than calling the subroutines fixsfsi or fixdfsi.
1726
1727 (define_insn "fix_truncdfsi2"
1728   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
1729         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1730    (clobber (match_scratch:SI 2 "=d"))
1731    (clobber (match_scratch:SI 3 "=d"))]
1732   "TARGET_68881 && TARGET_68040"
1733   "*
1734 {
1735   CC_STATUS_INIT;
1736   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,%!\";
1737 }")
1738
1739 (define_insn "fix_truncdfhi2"
1740   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
1741         (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1742    (clobber (match_scratch:SI 2 "=d"))
1743    (clobber (match_scratch:SI 3 "=d"))]
1744   "TARGET_68881 && TARGET_68040"
1745   "*
1746 {
1747   CC_STATUS_INIT;
1748   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,%!\";
1749 }")
1750
1751 (define_insn "fix_truncdfqi2"
1752   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
1753         (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1754    (clobber (match_scratch:SI 2 "=d"))
1755    (clobber (match_scratch:SI 3 "=d"))]
1756   "TARGET_68881 && TARGET_68040"
1757   "*
1758 {
1759   CC_STATUS_INIT;
1760   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,%!\";
1761 }")
1762
1763 ;; Convert a float to a float whose value is an integer.
1764 ;; This is the first stage of converting it to an integer type.
1765
1766 (define_insn "ftruncdf2"
1767   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1768         (fix:DF (match_operand:DF 1 "general_operand" "fFm")))]
1769   "TARGET_68881 && !TARGET_68040"
1770   "*
1771 {
1772   if (FP_REG_P (operands[1]))
1773     return \"fintrz%.x %f1,%0\";
1774   return \"fintrz%.d %f1,%0\";
1775 }")
1776
1777 (define_insn "ftruncsf2"
1778   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1779         (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))]
1780   "TARGET_68881 && !TARGET_68040"
1781   "*
1782 {
1783   if (FP_REG_P (operands[1]))
1784     return \"fintrz%.x %f1,%0\";
1785   return \"fintrz%.s %f1,%0\";
1786 }")
1787
1788 ;; Convert a float whose value is an integer
1789 ;; to an actual integer.  Second stage of converting float to integer type.
1790 (define_insn "fixsfqi2"
1791   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
1792         (fix:QI (match_operand:SF 1 "general_operand" "f")))]
1793   "TARGET_68881"
1794   "fmove%.b %1,%0")
1795
1796 (define_insn "fixsfhi2"
1797   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
1798         (fix:HI (match_operand:SF 1 "general_operand" "f")))]
1799   "TARGET_68881"
1800   "fmove%.w %1,%0")
1801
1802 (define_insn "fixsfsi2"
1803   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
1804         (fix:SI (match_operand:SF 1 "general_operand" "f")))]
1805   "TARGET_68881"
1806   "fmove%.l %1,%0")
1807
1808 (define_insn "fixdfqi2"
1809   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
1810         (fix:QI (match_operand:DF 1 "general_operand" "f")))]
1811   "TARGET_68881"
1812   "fmove%.b %1,%0")
1813
1814 (define_insn "fixdfhi2"
1815   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
1816         (fix:HI (match_operand:DF 1 "general_operand" "f")))]
1817   "TARGET_68881"
1818   "fmove%.w %1,%0")
1819
1820 (define_insn "fixdfsi2"
1821   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
1822         (fix:SI (match_operand:DF 1 "general_operand" "f")))]
1823   "TARGET_68881"
1824   "fmove%.l %1,%0")
1825 \f
1826 ;; add instructions
1827
1828 (define_insn "adddi_lshrdi_63"
1829   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1830     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm")
1831             (const_int 63))
1832         (match_dup 1)))
1833    (clobber (match_scratch:SI 2 "=d"))]
1834   ""
1835   "*
1836 {
1837   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1838   if (REG_P (operands[1]) && REGNO (operands[1]) == REGNO (operands[0]))
1839     return
1840     \"move%.l %1,%2\;add%.l %2,%2\;subx%.l %2,%2\;sub%.l %2,%3\;subx%.l %2,%0\";
1841   if (GET_CODE (operands[1]) == REG)
1842     operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1843   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
1844         || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1845     operands[4] = operands[1];
1846   else
1847     operands[4] = adjust_address (operands[1], SImode, 4);
1848   if (GET_CODE (operands[1]) == MEM
1849    && GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1850     output_asm_insn (\"move%.l %4,%3\", operands);
1851   output_asm_insn (\"move%.l %1,%0\;smi %2\", operands);
1852   if (TARGET_68020 || TARGET_5200)
1853     output_asm_insn (\"extb%.l %2\", operands);
1854   else
1855     output_asm_insn (\"ext%.w %2\;ext%.l %2\", operands);
1856   if (GET_CODE (operands[1]) != MEM
1857    || GET_CODE (XEXP (operands[1], 0)) != PRE_DEC)
1858     output_asm_insn (\"move%.l %4,%3\", operands);
1859   return \"sub%.l %2,%3\;subx%.l %2,%0\";
1860 }")
1861
1862 (define_insn "adddi_sexthishl32"
1863   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
1864     (plus:DI (ashift:DI (sign_extend:DI
1865           (match_operand:HI 1 "general_operand" "rm,rm,rm,rm"))
1866             (const_int 32))
1867         (match_operand:DI 2 "general_operand" "0,0,0,0")))
1868    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
1869   "!TARGET_5200"
1870   "*
1871 {
1872   CC_STATUS_INIT;
1873   if (ADDRESS_REG_P (operands[0]))
1874     return \"add%.w %1,%0\";
1875   else if (ADDRESS_REG_P (operands[3]))
1876     return \"move%.w %1,%3\;add%.l %3,%0\";
1877   else
1878     return \"move%.w %1,%3\;ext%.l %3\;add%.l %3,%0\";
1879 } ")
1880
1881 (define_insn "adddi_dilshr32"
1882   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o")
1883 ;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
1884 ;;      (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
1885 ;;            (const_int 32))))]
1886     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,d")
1887             (const_int 32))
1888         (match_operand:DI 2 "general_operand" "0,0")))]
1889   ""
1890   "*
1891 {
1892   CC_STATUS_INIT;
1893   if (GET_CODE (operands[0]) == REG)
1894     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1895   else
1896     operands[2] = adjust_address (operands[0], SImode, 4);
1897   return \"add%.l %1,%2\;negx%.l %0\;neg%.l %0\";
1898 } ")
1899
1900 (define_insn "adddi_dishl32"
1901   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
1902 ;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
1903 ;;      (ashift:DI (match_operand:DI 1 "general_operand" "ro")
1904 ;;            (const_int 32))))]
1905     (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro,d")
1906             (const_int 32))
1907         (match_operand:DI 2 "general_operand" "0,0")))]
1908   ""
1909   "*
1910 {
1911   CC_STATUS_INIT;
1912   if (GET_CODE (operands[1]) == REG)
1913     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1914   else
1915     operands[1] = adjust_address (operands[1], SImode, 4);
1916   return \"add%.l %1,%0\";
1917 } ")
1918
1919 (define_insn "adddi3"
1920   [(set (match_operand:DI 0 "nonimmediate_operand" "=<,o<>,d,d,d")
1921         (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0,0")
1922                  (match_operand:DI 2 "general_operand" "<,d,no>,d,a")))
1923    (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
1924   ""
1925   "*
1926 {
1927   if (DATA_REG_P (operands[0]))
1928     {
1929       if (DATA_REG_P (operands[2]))
1930         return \"add%.l %R2,%R0\;addx%.l %2,%0\";
1931       else if (GET_CODE (operands[2]) == MEM
1932           && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
1933         return \"move%.l %2,%3\;add%.l %2,%R0\;addx%.l %3,%0\";
1934       else
1935         {
1936           rtx high, low;
1937           rtx xoperands[2];
1938
1939           if (GET_CODE (operands[2]) == REG)
1940             {
1941               low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
1942               high = operands[2];
1943             }
1944           else if (CONSTANT_P (operands[2]))
1945             split_double (operands[2], &high, &low);
1946           else
1947             {
1948               low = adjust_address (operands[2], SImode, 4);
1949               high = operands[2];
1950             }
1951
1952           operands[1] = low, operands[2] = high;
1953           xoperands[0] = operands[3];
1954           if (GET_CODE (operands[1]) == CONST_INT
1955               && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
1956             xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
1957           else
1958             xoperands[1] = operands[2];
1959
1960           output_asm_insn (output_move_simode (xoperands), xoperands);
1961           if (GET_CODE (operands[1]) == CONST_INT)
1962             {
1963               if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
1964                 {
1965 #ifdef NO_ADDSUB_Q
1966                   return \"add%.l %1,%R0\;addx%.l %3,%0\";
1967 #else
1968                   return \"addq%.l %1,%R0\;addx%.l %3,%0\";
1969 #endif
1970                 }
1971               else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
1972                 {
1973                   operands[1] = GEN_INT (-INTVAL (operands[1]));
1974 #ifdef NO_ADDSUB_Q
1975                   return \"sub%.l %1,%R0\;subx%.l %3,%0\";
1976 #else
1977                   return \"subq%.l %1,%R0\;subx%.l %3,%0\";
1978 #endif
1979                 }
1980             }
1981           return \"add%.l %1,%R0\;addx%.l %3,%0\";
1982         }
1983     }
1984   else if (GET_CODE (operands[0]) == MEM)
1985     {
1986       if (GET_CODE (operands[2]) == MEM
1987           && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
1988         return \"add%.l %2,%0\;addx%.l %2,%0\";
1989       CC_STATUS_INIT;
1990       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1991         {
1992           operands[1] = gen_rtx_MEM (SImode,
1993                                      plus_constant (XEXP(operands[0], 0), -8));
1994           return \"move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1\";
1995         }
1996       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1997         {
1998           operands[1] = XEXP(operands[0], 0);
1999           return \"add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1\";
2000         }
2001       else
2002         {
2003           operands[1] = adjust_address (operands[0], SImode, 4);
2004           return \"add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\";
2005         }
2006     }
2007   else
2008     abort ();
2009 } ")
2010
2011 (define_insn "addsi_lshrsi_31"
2012   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
2013     (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm")
2014             (const_int 31))
2015         (match_dup 1)))]
2016   ""
2017   "*
2018 {
2019   operands[2] = operands[0];
2020   operands[3] = gen_label_rtx();
2021   if (GET_CODE (operands[0]) == MEM)
2022     {
2023       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2024         operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2025       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2026         operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2027     }
2028   output_asm_insn (\"move%.l %1,%0\", operands);
2029 #ifdef MOTOROLA
2030   output_asm_insn (\"jbpl %l3\", operands);
2031 #else
2032   output_asm_insn (\"jpl %l3\", operands);
2033 #endif
2034 #ifndef NO_ADDSUB_Q
2035   output_asm_insn (\"addq%.l %#1,%2\", operands);
2036 #else
2037   output_asm_insn (\"add%.l %#1,%2\", operands);
2038 #endif
2039   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2040                                 CODE_LABEL_NUMBER (operands[3]));
2041   return \"\";
2042 }")
2043
2044 (define_expand "addsi3"
2045   [(set (match_operand:SI 0 "nonimmediate_operand" "")
2046         (plus:SI (match_operand:SI 1 "general_operand" "")
2047                  (match_operand:SI 2 "general_src_operand" "")))]
2048   ""
2049   "")
2050
2051 ;; Note that the middle two alternatives are near-duplicates
2052 ;; in order to handle insns generated by reload.
2053 ;; This is needed since they are not themselves reloaded,
2054 ;; so commutativity won't apply to them.
2055 (define_insn "*addsi3_internal"
2056   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,d,a")
2057         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0")
2058                  (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))]
2059
2060
2061   "! TARGET_5200"
2062   "* return output_addsi3 (operands);")
2063
2064 (define_insn "*addsi3_5200"
2065   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,r")
2066         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
2067                  (match_operand:SI 2 "general_src_operand" "d,rJK,a,mrIKLs")))]
2068   "TARGET_5200"
2069   "* return output_addsi3 (operands);")
2070
2071 (define_insn ""
2072   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
2073         (plus:SI (match_operand:SI 1 "general_operand" "0")
2074                  (sign_extend:SI
2075                   (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2076   "!TARGET_5200"
2077   "add%.w %2,%0")
2078
2079 (define_insn "addhi3"
2080   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
2081         (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
2082                  (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2083   "!TARGET_5200"
2084   "*
2085 {
2086   if (GET_CODE (operands[2]) == CONST_INT)
2087     {
2088 #ifndef NO_ADDSUB_Q
2089       /* If the constant would be a negative number when interpreted as
2090          HImode, make it negative.  This is usually, but not always, done
2091          elsewhere in the compiler.  First check for constants out of range,
2092          which could confuse us.  */
2093
2094       if (INTVAL (operands[2]) >= 32768)
2095         operands[2] = GEN_INT (INTVAL (operands[2]) - 65536);
2096
2097       if (INTVAL (operands[2]) > 0
2098           && INTVAL (operands[2]) <= 8)
2099         return \"addq%.w %2,%0\";
2100       if (INTVAL (operands[2]) < 0
2101           && INTVAL (operands[2]) >= -8)
2102         {
2103           operands[2] = GEN_INT (- INTVAL (operands[2]));
2104           return \"subq%.w %2,%0\";
2105         }
2106       /* On the CPU32 it is faster to use two addqw instructions to
2107          add a small integer (8 < N <= 16) to a register.  
2108          Likewise for subqw.  */
2109       if (TARGET_CPU32 && REG_P (operands[0]))
2110         {
2111           if (INTVAL (operands[2]) > 8
2112               && INTVAL (operands[2]) <= 16)
2113             {
2114               operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2115               return \"addq%.w %#8,%0\;addq%.w %2,%0\";
2116             }
2117           if (INTVAL (operands[2]) < -8
2118               && INTVAL (operands[2]) >= -16)
2119             {
2120               operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2121               return \"subq%.w %#8,%0\;subq%.w %2,%0\";
2122             }
2123         }
2124 #endif
2125       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2126 #ifdef MOTOROLA  
2127             return \"lea (%c2,%0),%0\";
2128 #else
2129             return \"lea %0@(%c2),%0\";
2130 #endif
2131     }
2132   return \"add%.w %2,%0\";
2133 }")
2134
2135 ;; These insns must use MATCH_DUP instead of the more expected
2136 ;; use of a matching constraint because the "output" here is also
2137 ;; an input, so you can't use the matching constraint.  That also means
2138 ;; that you can't use the "%", so you need patterns with the matched
2139 ;; operand in both positions.
2140
2141 (define_insn ""
2142   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2143         (plus:HI (match_dup 0)
2144                  (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2145   "!TARGET_5200"
2146   "*
2147 {
2148   if (GET_CODE (operands[1]) == CONST_INT)
2149     {
2150 #ifndef NO_ADDSUB_Q
2151       /* If the constant would be a negative number when interpreted as
2152          HImode, make it negative.  This is usually, but not always, done
2153          elsewhere in the compiler.  First check for constants out of range,
2154          which could confuse us.  */
2155
2156       if (INTVAL (operands[1]) >= 32768)
2157         operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2158
2159       if (INTVAL (operands[1]) > 0
2160           && INTVAL (operands[1]) <= 8)
2161         return \"addq%.w %1,%0\";
2162       if (INTVAL (operands[1]) < 0
2163           && INTVAL (operands[1]) >= -8)
2164         {
2165           operands[1] = GEN_INT (- INTVAL (operands[1]));
2166           return \"subq%.w %1,%0\";
2167         }
2168       /* On the CPU32 it is faster to use two addqw instructions to
2169          add a small integer (8 < N <= 16) to a register. 
2170          Likewise for subqw.  */
2171       if (TARGET_CPU32 && REG_P (operands[0]))
2172         {
2173           if (INTVAL (operands[1]) > 8
2174               && INTVAL (operands[1]) <= 16)
2175             {
2176               operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2177               return \"addq%.w %#8,%0\;addq%.w %1,%0\";
2178             }
2179           if (INTVAL (operands[1]) < -8
2180               && INTVAL (operands[1]) >= -16)
2181             {
2182               operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
2183               return \"subq%.w %#8,%0\;subq%.w %1,%0\";
2184             }
2185         }
2186 #endif
2187       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2188 #ifdef MOTOROLA  
2189             return \"lea (%c1,%0),%0\";
2190 #else
2191             return \"lea %0@(%c1),%0\";
2192 #endif
2193     }
2194   return \"add%.w %1,%0\";
2195 }")
2196
2197 (define_insn ""
2198   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2199         (plus:HI (match_operand:HI 1 "general_src_operand" "dn,rmSn")
2200                  (match_dup 0)))]
2201   "!TARGET_5200"
2202   "*
2203 {
2204   if (GET_CODE (operands[1]) == CONST_INT)
2205     {
2206 #ifndef NO_ADDSUB_Q
2207       /* If the constant would be a negative number when interpreted as
2208          HImode, make it negative.  This is usually, but not always, done
2209          elsewhere in the compiler.  First check for constants out of range,
2210          which could confuse us.  */
2211
2212       if (INTVAL (operands[1]) >= 32768)
2213         operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2214
2215       if (INTVAL (operands[1]) > 0
2216           && INTVAL (operands[1]) <= 8)
2217         return \"addq%.w %1,%0\";
2218       if (INTVAL (operands[1]) < 0
2219           && INTVAL (operands[1]) >= -8)
2220         {
2221           operands[1] = GEN_INT (- INTVAL (operands[1]));
2222           return \"subq%.w %1,%0\";
2223         }
2224       /* On the CPU32 it is faster to use two addqw instructions to
2225          add a small integer (8 < N <= 16) to a register.
2226          Likewise for subqw.  */
2227       if (TARGET_CPU32 && REG_P (operands[0])) 
2228         {
2229           if (INTVAL (operands[1]) > 8
2230               && INTVAL (operands[1]) <= 16)
2231             {
2232               operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2233               return \"addq%.w %#8,%0\;addq%.w %1,%0\";
2234             }
2235           if (INTVAL (operands[1]) < -8
2236               && INTVAL (operands[1]) >= -16)
2237             {
2238               operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
2239               return \"subq%.w %#8,%0\;subq%.w %1,%0\";
2240             }
2241         }
2242 #endif
2243       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2244 #ifdef MOTOROLA  
2245             return \"lea (%c1,%0),%0\";
2246 #else
2247             return \"lea %0@(%c1),%0\";
2248 #endif
2249     }
2250   return \"add%.w %1,%0\";
2251 }")
2252
2253 (define_insn "addqi3"
2254   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
2255         (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
2256                  (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2257   "!TARGET_5200"
2258   "*
2259 {
2260 #ifndef NO_ADDSUB_Q
2261   if (GET_CODE (operands[2]) == CONST_INT)
2262     {
2263       if (INTVAL (operands[2]) >= 128)
2264         operands[2] = GEN_INT (INTVAL (operands[2]) - 256);
2265
2266       if (INTVAL (operands[2]) > 0
2267           && INTVAL (operands[2]) <= 8)
2268         return \"addq%.b %2,%0\";
2269       if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
2270        {
2271          operands[2] = GEN_INT (- INTVAL (operands[2]));
2272          return \"subq%.b %2,%0\";
2273        }
2274     }
2275 #endif
2276   return \"add%.b %2,%0\";
2277 }")
2278
2279 (define_insn ""
2280   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2281         (plus:QI (match_dup 0)
2282                  (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2283   "!TARGET_5200"
2284   "*
2285 {
2286 #ifndef NO_ADDSUB_Q
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 #endif
2302   return \"add%.b %1,%0\";
2303 }")
2304
2305 (define_insn ""
2306   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2307         (plus:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
2308                  (match_dup 0)))]
2309   "!TARGET_5200"
2310   "*
2311 {
2312 #ifndef NO_ADDSUB_Q
2313   if (GET_CODE (operands[1]) == CONST_INT)
2314     {
2315       if (INTVAL (operands[1]) >= 128)
2316         operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2317
2318       if (INTVAL (operands[1]) > 0
2319           && INTVAL (operands[1]) <= 8)
2320         return \"addq%.b %1,%0\";
2321       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2322        {
2323          operands[1] = GEN_INT (- INTVAL (operands[1]));
2324          return \"subq%.b %1,%0\";
2325        }
2326     }
2327 #endif
2328   return \"add%.b %1,%0\";
2329 }")
2330
2331 (define_expand "adddf3"
2332   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2333         (plus:DF (match_operand:DF 1 "general_operand" "")
2334                  (match_operand:DF 2 "general_operand" "")))]
2335   "TARGET_68881"
2336   "")
2337
2338 (define_insn ""
2339   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2340         (plus:DF (float:DF (match_operand:SI 2 "general_operand" "dmi"))
2341                  (match_operand:DF 1 "general_operand" "0")))]
2342   "TARGET_68881"
2343   "f%&add%.l %2,%0")
2344
2345 (define_insn ""
2346   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2347         (plus:DF (float:DF (match_operand:HI 2 "general_operand" "dmn"))
2348                  (match_operand:DF 1 "general_operand" "0")))]
2349   "TARGET_68881"
2350   "f%&add%.w %2,%0")
2351
2352 (define_insn ""
2353   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2354         (plus:DF (float:DF (match_operand:QI 2 "general_operand" "dmn"))
2355                  (match_operand:DF 1 "general_operand" "0")))]
2356   "TARGET_68881"
2357   "f%&add%.b %2,%0")
2358
2359 (define_insn ""
2360   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2361         (plus:DF (match_operand:DF 1 "general_operand" "%0")
2362                  (match_operand:DF 2 "general_operand" "fmG")))]
2363   "TARGET_68881"
2364   "*
2365 {
2366   if (REG_P (operands[2]))
2367     return \"f%&add%.x %2,%0\";
2368   return \"f%&add%.d %f2,%0\";
2369 }")
2370
2371 (define_expand "addsf3"
2372   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2373         (plus:SF (match_operand:SF 1 "general_operand" "")
2374                  (match_operand:SF 2 "general_operand" "")))]
2375   "TARGET_68881"
2376   "")
2377
2378 (define_insn ""
2379   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2380         (plus:SF (float:SF (match_operand:SI 2 "general_operand" "dmi"))
2381                  (match_operand:SF 1 "general_operand" "0")))]
2382   "TARGET_68881"
2383   "f%$add%.l %2,%0")
2384
2385 (define_insn ""
2386   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2387         (plus:SF (float:SF (match_operand:HI 2 "general_operand" "dmn"))
2388                  (match_operand:SF 1 "general_operand" "0")))]
2389   "TARGET_68881"
2390   "f%$add%.w %2,%0")
2391
2392 (define_insn ""
2393   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2394         (plus:SF (float:SF (match_operand:QI 2 "general_operand" "dmn"))
2395                  (match_operand:SF 1 "general_operand" "0")))]
2396   "TARGET_68881"
2397   "f%$add%.b %2,%0")
2398
2399 (define_insn ""
2400   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2401         (plus:SF (match_operand:SF 1 "general_operand" "%0")
2402                  (match_operand:SF 2 "general_operand" "fdmF")))]
2403   "TARGET_68881"
2404   "*
2405 {
2406   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2407     return \"f%$add%.x %2,%0\";
2408   return \"f%$add%.s %f2,%0\";
2409 }")
2410 \f
2411 ;; subtract instructions
2412
2413 (define_insn "subdi_sexthishl32"
2414   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
2415     (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
2416         (ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm"))
2417             (const_int 32))))
2418    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
2419   "!TARGET_5200"
2420   "*
2421 {
2422   CC_STATUS_INIT;
2423   if (ADDRESS_REG_P (operands[0]))
2424     return \"sub%.w %2,%0\";
2425   else if (ADDRESS_REG_P (operands[3]))
2426     return \"move%.w %2,%3\;sub%.l %3,%0\";
2427   else
2428     return \"move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0\";
2429 } ")
2430
2431 (define_insn "subdi_dishl32"
2432   [(set (match_operand:DI 0 "nonimmediate_operand" "+ro")
2433     (minus:DI (match_dup 0)
2434         (ashift:DI (match_operand:DI 1 "general_operand" "ro")
2435             (const_int 32))))]
2436   ""
2437   "*
2438 {
2439   CC_STATUS_INIT;
2440   if (GET_CODE (operands[1]) == REG)
2441     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2442   else
2443     operands[1] = adjust_address (operands[1], SImode, 4);
2444   return \"sub%.l %1,%0\";
2445 } ")
2446
2447 (define_insn "subdi3"
2448   [(set (match_operand:DI 0 "nonimmediate_operand" "=<,o<>,d,d,d")
2449         (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0,0")
2450                  (match_operand:DI 2 "general_operand" "<,d,no>,d,a")))
2451    (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
2452   ""
2453   "*
2454 {
2455   if (DATA_REG_P (operands[0]))
2456     {
2457       if (DATA_REG_P (operands[2]))
2458         return \"sub%.l %R2,%R0\;subx%.l %2,%0\";
2459       else if (GET_CODE (operands[2]) == MEM
2460           && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
2461         {
2462           return \"move%.l %2,%3\;sub%.l %2,%R0\;subx%.l %3,%0\";
2463         }
2464       else
2465         {
2466           rtx high, low;
2467           rtx xoperands[2];
2468
2469           if (GET_CODE (operands[2]) == REG)
2470             {
2471               low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2472               high = operands[2];
2473             }
2474           else if (CONSTANT_P (operands[2]))
2475             split_double (operands[2], &high, &low);
2476           else
2477             {
2478               low = adjust_address (operands[2], SImode, 4);
2479               high = operands[2];
2480             }
2481
2482           operands[1] = low, operands[2] = high;
2483           xoperands[0] = operands[3];
2484           if (GET_CODE (operands[1]) == CONST_INT
2485               && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2486             xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
2487           else
2488             xoperands[1] = operands[2];
2489
2490           output_asm_insn (output_move_simode (xoperands), xoperands);
2491           if (GET_CODE (operands[1]) == CONST_INT)
2492             {
2493               if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
2494                 {
2495 #ifdef NO_ADDSUB_Q
2496                   return \"sub%.l %1,%R0\;subx%.l %3,%0\";
2497 #else
2498                   return \"subq%.l %1,%R0\;subx%.l %3,%0\";
2499 #endif
2500                 }
2501               else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2502                 {
2503                   operands[1] = GEN_INT (-INTVAL (operands[1]));
2504 #ifdef NO_ADDSUB_Q
2505                   return \"add%.l %1,%R0\;addx%.l %3,%0\";
2506 #else
2507                   return \"addq%.l %1,%R0\;addx%.l %3,%0\";
2508 #endif
2509                 }
2510             }
2511           return \"sub%.l %1,%R0\;subx%.l %3,%0\";
2512         }
2513     }
2514   else if (GET_CODE (operands[0]) == MEM)
2515     {
2516       if (GET_CODE (operands[2]) == MEM
2517           && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
2518         return \"sub%.l %2,%0\;subx%.l %2,%0\";
2519       CC_STATUS_INIT;
2520       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2521         {
2522           operands[1]
2523             = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[0], 0), -8));
2524           return \"move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1\";
2525         }
2526       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2527         {
2528           operands[1] = XEXP(operands[0], 0);
2529           return \"sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1\";
2530         }
2531       else
2532         {
2533           operands[1] = adjust_address (operands[0], SImode, 4);
2534           return \"sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\";
2535         }
2536     }
2537   else
2538     abort ();
2539 } ")
2540
2541 (define_insn "subsi3"
2542   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d,a")
2543         (minus:SI (match_operand:SI 1 "general_operand" "0,0,0")
2544                   (match_operand:SI 2 "general_src_operand" "dT,mSrT,mSrs")))]
2545   ""
2546   "sub%.l %2,%0")
2547
2548 (define_insn ""
2549   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
2550         (minus:SI (match_operand:SI 1 "general_operand" "0")
2551                   (sign_extend:SI
2552                    (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2553   "!TARGET_5200"
2554   "sub%.w %2,%0")
2555
2556 (define_insn "subhi3"
2557   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
2558         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2559                   (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2560   "!TARGET_5200"
2561   "sub%.w %2,%0")
2562
2563 (define_insn ""
2564   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2565         (minus:HI (match_dup 0)
2566                   (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2567   "!TARGET_5200"
2568   "sub%.w %1,%0")
2569
2570 (define_insn "subqi3"
2571   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
2572         (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2573                   (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2574   "!TARGET_5200"
2575   "sub%.b %2,%0")
2576
2577 (define_insn ""
2578   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2579         (minus:QI (match_dup 0)
2580                   (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2581   "!TARGET_5200"
2582   "sub%.b %1,%0")
2583
2584 (define_expand "subdf3"
2585   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2586         (minus:DF (match_operand:DF 1 "general_operand" "")
2587                   (match_operand:DF 2 "general_operand" "")))]
2588   "TARGET_68881"
2589   "")
2590
2591 (define_insn ""
2592   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2593         (minus:DF (match_operand:DF 1 "general_operand" "0")
2594                   (float:DF (match_operand:SI 2 "general_operand" "dmi"))))]
2595   "TARGET_68881"
2596   "f%&sub%.l %2,%0")
2597
2598 (define_insn ""
2599   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2600         (minus:DF (match_operand:DF 1 "general_operand" "0")
2601                   (float:DF (match_operand:HI 2 "general_operand" "dmn"))))]
2602   "TARGET_68881"
2603   "f%&sub%.w %2,%0")
2604
2605 (define_insn ""
2606   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2607         (minus:DF (match_operand:DF 1 "general_operand" "0")
2608                   (float:DF (match_operand:QI 2 "general_operand" "dmn"))))]
2609   "TARGET_68881"
2610   "f%&sub%.b %2,%0")
2611
2612 (define_insn ""
2613   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2614         (minus:DF (match_operand:DF 1 "general_operand" "0")
2615                   (match_operand:DF 2 "general_operand" "fmG")))]
2616   "TARGET_68881"
2617   "*
2618 {
2619   if (REG_P (operands[2]))
2620     return \"f%&sub%.x %2,%0\";
2621   return \"f%&sub%.d %f2,%0\";
2622 }")
2623
2624 (define_expand "subsf3"
2625   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2626         (minus:SF (match_operand:SF 1 "general_operand" "")
2627                   (match_operand:SF 2 "general_operand" "")))]
2628   "TARGET_68881"
2629   "")
2630
2631 (define_insn ""
2632   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2633         (minus:SF (match_operand:SF 1 "general_operand" "0")
2634                   (float:SF (match_operand:SI 2 "general_operand" "dmi"))))]
2635   "TARGET_68881"
2636   "f%$sub%.l %2,%0")
2637
2638 (define_insn ""
2639   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2640         (minus:SF (match_operand:SF 1 "general_operand" "0")
2641                   (float:SF (match_operand:HI 2 "general_operand" "dmn"))))]
2642   "TARGET_68881"
2643   "f%$sub%.w %2,%0")
2644
2645 (define_insn ""
2646   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2647         (minus:SF (match_operand:SF 1 "general_operand" "0")
2648                   (float:SF (match_operand:QI 2 "general_operand" "dmn"))))]
2649   "TARGET_68881"
2650   "f%$sub%.b %2,%0")
2651
2652 (define_insn ""
2653   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2654         (minus:SF (match_operand:SF 1 "general_operand" "0")
2655                   (match_operand:SF 2 "general_operand" "fdmF")))]
2656   "TARGET_68881"
2657   "*
2658 {
2659   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2660     return \"f%$sub%.x %2,%0\";
2661   return \"f%$sub%.s %f2,%0\";
2662 }")
2663 \f
2664 ;; multiply instructions
2665
2666 (define_insn "mulhi3"
2667   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
2668         (mult:HI (match_operand:HI 1 "general_operand" "%0")
2669                  (match_operand:HI 2 "general_src_operand" "dmSn")))]
2670   ""
2671   "*
2672 {
2673 #if defined(MOTOROLA)
2674   return \"muls%.w %2,%0\";
2675 #else
2676   return \"muls %2,%0\";
2677 #endif
2678 }")
2679
2680 (define_insn "mulhisi3"
2681   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2682         (mult:SI (sign_extend:SI
2683                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2684                  (sign_extend:SI
2685                   (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
2686   ""
2687   "*
2688 {
2689 #if defined(MOTOROLA)
2690   return \"muls%.w %2,%0\";
2691 #else
2692   return \"muls %2,%0\";
2693 #endif
2694 }")
2695
2696 (define_insn ""
2697   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2698         (mult:SI (sign_extend:SI
2699                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2700                  (match_operand:SI 2 "const_int_operand" "n")))]
2701   "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
2702   "*
2703 {
2704 #if defined(MOTOROLA)
2705   return \"muls%.w %2,%0\";
2706 #else
2707   return \"muls %2,%0\";
2708 #endif
2709 }")
2710
2711 (define_expand "mulsi3"
2712   [(set (match_operand:SI 0 "nonimmediate_operand" "")
2713         (mult:SI (match_operand:SI 1 "general_operand" "")
2714                  (match_operand:SI 2 "general_operand" "")))]
2715   "TARGET_68020 || TARGET_5200"
2716   "")
2717
2718 (define_insn ""
2719   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2720         (mult:SI (match_operand:SI 1 "general_operand" "%0")
2721                  (match_operand:SI 2 "general_src_operand" "dmSTK")))]
2722
2723   "TARGET_68020"
2724   "muls%.l %2,%0")
2725
2726 (define_insn ""
2727   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2728         (mult:SI (match_operand:SI 1 "general_operand" "%0")
2729                  (match_operand:SI 2 "general_operand" "d<Q>")))]
2730   "TARGET_5200"
2731   "muls%.l %2,%0")
2732
2733 (define_insn "umulhisi3"
2734   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2735         (mult:SI (zero_extend:SI
2736                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2737                  (zero_extend:SI
2738                   (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
2739   ""
2740   "*
2741 {
2742 #if defined(MOTOROLA)
2743   return \"mulu%.w %2,%0\";
2744 #else
2745   return \"mulu %2,%0\";
2746 #endif
2747 }")
2748
2749 (define_insn ""
2750   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2751         (mult:SI (zero_extend:SI
2752                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2753                  (match_operand:SI 2 "const_int_operand" "n")))]
2754   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
2755   "*
2756 {
2757 #if defined(MOTOROLA)
2758   return \"mulu%.w %2,%0\";
2759 #else
2760   return \"mulu %2,%0\";
2761 #endif
2762 }")
2763
2764 ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
2765 ;; proper matching constraint.  This is because the matching is between
2766 ;; the high-numbered word of the DImode operand[0] and operand[1].
2767 (define_expand "umulsidi3"
2768   [(parallel
2769     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
2770           (mult:SI (match_operand:SI 1 "register_operand" "")
2771                    (match_operand:SI 2 "register_operand" "")))
2772      (set (subreg:SI (match_dup 0) 0)
2773           (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2774                                              (zero_extend:DI (match_dup 2)))
2775                                     (const_int 32))))])]
2776   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2777   "")
2778
2779 (define_insn ""
2780   [(set (match_operand:SI 0 "register_operand" "=d")
2781         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2782                   (match_operand:SI 2 "nonimmediate_operand" "dm")))
2783    (set (match_operand:SI 3 "register_operand" "=d")
2784         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2785                                            (zero_extend:DI (match_dup 2)))
2786                                   (const_int 32))))]
2787   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2788   "mulu%.l %2,%3:%0")
2789
2790 ; Match immediate case.  For 2.4 only match things < 2^31.
2791 ; It's tricky with larger values in these patterns since we need to match
2792 ; values between the two parallel multiplies, between a CONST_DOUBLE and
2793 ; a CONST_INT.
2794 (define_insn ""
2795   [(set (match_operand:SI 0 "register_operand" "=d")
2796         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2797                  (match_operand:SI 2 "const_int_operand" "n")))
2798    (set (match_operand:SI 3 "register_operand" "=d")
2799         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2800                                            (match_dup 2))
2801                                   (const_int 32))))]
2802   "TARGET_68020 && !TARGET_68060 && !TARGET_5200
2803    && (unsigned) INTVAL (operands[2]) <= 0x7fffffff"
2804   "mulu%.l %2,%3:%0")
2805
2806 (define_expand "mulsidi3"
2807   [(parallel
2808     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
2809           (mult:SI (match_operand:SI 1 "register_operand" "")
2810                    (match_operand:SI 2 "register_operand" "")))
2811      (set (subreg:SI (match_dup 0) 0)
2812           (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2813                                              (sign_extend:DI (match_dup 2)))
2814                                     (const_int 32))))])]
2815   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2816   "")
2817
2818 (define_insn ""
2819   [(set (match_operand:SI 0 "register_operand" "=d")
2820         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2821                  (match_operand:SI 2 "nonimmediate_operand" "dm")))
2822    (set (match_operand:SI 3 "register_operand" "=d")
2823         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2824                                            (sign_extend:DI (match_dup 2)))
2825                                   (const_int 32))))]
2826   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2827   "muls%.l %2,%3:%0")
2828
2829 (define_insn ""
2830   [(set (match_operand:SI 0 "register_operand" "=d")
2831         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2832                  (match_operand:SI 2 "const_int_operand" "n")))
2833    (set (match_operand:SI 3 "register_operand" "=d")
2834         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2835                                            (match_dup 2))
2836                                   (const_int 32))))]
2837   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2838   "muls%.l %2,%3:%0")
2839
2840 (define_expand "umulsi3_highpart"
2841   [(parallel
2842     [(set (match_operand:SI 0 "register_operand" "")
2843           (truncate:SI
2844            (lshiftrt:DI
2845             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2846                      (zero_extend:DI (match_operand:SI 2 "general_operand" "")))
2847             (const_int 32))))
2848      (clobber (match_dup 3))])]
2849   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2850   "
2851 {
2852   operands[3] = gen_reg_rtx (SImode);
2853
2854   if (GET_CODE (operands[2]) == CONST_INT)
2855     {
2856       operands[2] = immed_double_const (INTVAL (operands[2]) & 0xffffffff,
2857                                         0, DImode);
2858
2859       /* We have to adjust the operand order for the matching constraints.  */
2860       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[3],
2861                                              operands[1], operands[2]));
2862       DONE;
2863     }
2864 }")
2865
2866 (define_insn ""
2867   [(set (match_operand:SI 0 "register_operand" "=d")
2868         (truncate:SI
2869          (lshiftrt:DI
2870           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "%1"))
2871                    (zero_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
2872           (const_int 32))))
2873    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2874   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2875   "mulu%.l %3,%0:%1")
2876
2877 (define_insn "const_umulsi3_highpart"
2878   [(set (match_operand:SI 0 "register_operand" "=d")
2879         (truncate:SI
2880          (lshiftrt:DI
2881           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "1"))
2882                    (match_operand:DI 3 "const_uint32_operand" "n"))
2883           (const_int 32))))
2884    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2885   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2886   "mulu%.l %3,%0:%1")
2887
2888 (define_expand "smulsi3_highpart"
2889   [(parallel
2890     [(set (match_operand:SI 0 "register_operand" "")
2891           (truncate:SI
2892            (lshiftrt:DI
2893             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2894                      (sign_extend:DI (match_operand:SI 2 "general_operand" "")))
2895             (const_int 32))))
2896      (clobber (match_dup 3))])]
2897   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2898   "
2899 {
2900   operands[3] = gen_reg_rtx (SImode);
2901   if (GET_CODE (operands[2]) == CONST_INT)
2902     {
2903       /* We have to adjust the operand order for the matching constraints.  */
2904       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[3],
2905                                              operands[1], operands[2]));
2906       DONE;
2907     }
2908 }")
2909
2910 (define_insn ""
2911   [(set (match_operand:SI 0 "register_operand" "=d")
2912         (truncate:SI
2913          (lshiftrt:DI
2914           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "%1"))
2915                    (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
2916           (const_int 32))))
2917    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2918   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2919   "muls%.l %3,%0:%1")
2920
2921 (define_insn "const_smulsi3_highpart"
2922   [(set (match_operand:SI 0 "register_operand" "=d")
2923         (truncate:SI
2924          (lshiftrt:DI
2925           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1"))
2926                    (match_operand:DI 3 "const_sint32_operand" "n"))
2927           (const_int 32))))
2928    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2929   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2930   "muls%.l %3,%0:%1")
2931
2932 (define_expand "muldf3"
2933   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2934         (mult:DF (match_operand:DF 1 "general_operand" "")
2935                  (match_operand:DF 2 "general_operand" "")))]
2936   "TARGET_68881"
2937   "")
2938
2939 (define_insn ""
2940   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2941         (mult:DF (float:DF (match_operand:SI 2 "general_operand" "dmi"))
2942                  (match_operand:DF 1 "general_operand" "0")))]
2943   "TARGET_68881"
2944   "f%&mul%.l %2,%0")
2945
2946 (define_insn ""
2947   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2948         (mult:DF (float:DF (match_operand:HI 2 "general_operand" "dmn"))
2949                  (match_operand:DF 1 "general_operand" "0")))]
2950   "TARGET_68881"
2951   "f%&mul%.w %2,%0")
2952
2953 (define_insn ""
2954   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2955         (mult:DF (float:DF (match_operand:QI 2 "general_operand" "dmn"))
2956                  (match_operand:DF 1 "general_operand" "0")))]
2957   "TARGET_68881"
2958   "f%&mul%.b %2,%0")
2959
2960 (define_insn ""
2961   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2962         (mult:DF (match_operand:DF 1 "general_operand" "%0")
2963                  (match_operand:DF 2 "general_operand" "fmG")))]
2964   "TARGET_68881"
2965   "*
2966 {
2967   if (GET_CODE (operands[2]) == CONST_DOUBLE
2968       && floating_exact_log2 (operands[2]) && !TARGET_68040 && !TARGET_68060)
2969     {
2970       int i = floating_exact_log2 (operands[2]);
2971       operands[2] = GEN_INT (i);
2972       return \"fscale%.l %2,%0\";
2973     }
2974   if (REG_P (operands[2]))
2975     return \"f%&mul%.x %2,%0\";
2976   return \"f%&mul%.d %f2,%0\";
2977 }")
2978
2979 (define_expand "mulsf3"
2980   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2981         (mult:SF (match_operand:SF 1 "general_operand" "")
2982                  (match_operand:SF 2 "general_operand" "")))]
2983   "TARGET_68881"
2984   "")
2985
2986 (define_insn ""
2987   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2988         (mult:SF (float:SF (match_operand:SI 2 "general_operand" "dmi"))
2989                  (match_operand:SF 1 "general_operand" "0")))]
2990   "TARGET_68881"
2991   "*
2992 {
2993   return (TARGET_68040_ONLY
2994           ? \"fsmul%.l %2,%0\"
2995           : \"fsglmul%.l %2,%0\");
2996 }")
2997
2998 (define_insn ""
2999   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3000         (mult:SF (float:SF (match_operand:HI 2 "general_operand" "dmn"))
3001                  (match_operand:SF 1 "general_operand" "0")))]
3002   "TARGET_68881"
3003   "*
3004 {
3005   return (TARGET_68040_ONLY
3006           ? \"fsmul%.w %2,%0\"
3007           : \"fsglmul%.w %2,%0\");
3008 }")
3009
3010 (define_insn ""
3011   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3012         (mult:SF (float:SF (match_operand:QI 2 "general_operand" "dmn"))
3013                  (match_operand:SF 1 "general_operand" "0")))]
3014   "TARGET_68881"
3015   "*
3016 {
3017   return (TARGET_68040_ONLY
3018           ? \"fsmul%.b %2,%0\"
3019           : \"fsglmul%.b %2,%0\");
3020 }")
3021
3022 (define_insn ""
3023   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3024         (mult:SF (match_operand:SF 1 "general_operand" "%0")
3025                  (match_operand:SF 2 "general_operand" "fdmF")))]
3026   "TARGET_68881"
3027   "*
3028 {
3029 #ifdef FSGLMUL_USE_S
3030   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3031     return (TARGET_68040_ONLY
3032             ? \"fsmul%.s %2,%0\"
3033             : \"fsglmul%.s %2,%0\");
3034 #else
3035   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3036     return (TARGET_68040_ONLY
3037             ? \"fsmul%.x %2,%0\"
3038             : \"fsglmul%.x %2,%0\");
3039 #endif
3040   return (TARGET_68040_ONLY
3041           ? \"fsmul%.s %f2,%0\"
3042           : \"fsglmul%.s %f2,%0\");
3043 }")
3044 \f
3045 ;; divide instructions
3046
3047 (define_expand "divdf3"
3048   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3049         (div:DF (match_operand:DF 1 "general_operand" "")
3050                 (match_operand:DF 2 "general_operand" "")))]
3051   "TARGET_68881"
3052   "")
3053
3054 (define_insn ""
3055   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3056         (div:DF (match_operand:DF 1 "general_operand" "0")
3057                 (float:DF (match_operand:SI 2 "general_operand" "dmi"))))]
3058   "TARGET_68881"
3059   "f%&div%.l %2,%0")
3060
3061 (define_insn ""
3062   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3063         (div:DF (match_operand:DF 1 "general_operand" "0")
3064                 (float:DF (match_operand:HI 2 "general_operand" "dmn"))))]
3065   "TARGET_68881"
3066   "f%&div%.w %2,%0")
3067
3068 (define_insn ""
3069   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3070         (div:DF (match_operand:DF 1 "general_operand" "0")
3071                 (float:DF (match_operand:QI 2 "general_operand" "dmn"))))]
3072   "TARGET_68881"
3073   "f%&div%.b %2,%0")
3074
3075 (define_insn ""
3076   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3077         (div:DF (match_operand:DF 1 "general_operand" "0")
3078                 (match_operand:DF 2 "general_operand" "fmG")))]
3079   "TARGET_68881"
3080   "*
3081 {
3082   if (REG_P (operands[2]))
3083     return \"f%&div%.x %2,%0\";
3084   return \"f%&div%.d %f2,%0\";
3085 }")
3086
3087 (define_expand "divsf3"
3088   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3089         (div:SF (match_operand:SF 1 "general_operand" "")
3090                 (match_operand:SF 2 "general_operand" "")))]
3091   "TARGET_68881"
3092   "")
3093
3094 (define_insn ""
3095   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3096         (div:SF (match_operand:SF 1 "general_operand" "0")
3097                 (float:SF (match_operand:SI 2 "general_operand" "dmi"))))]
3098   "TARGET_68881"
3099   "*
3100 {
3101   return (TARGET_68040_ONLY
3102           ? \"fsdiv%.l %2,%0\"
3103           : \"fsgldiv%.l %2,%0\");
3104 }")
3105
3106 (define_insn ""
3107   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3108         (div:SF (match_operand:SF 1 "general_operand" "0")
3109                 (float:SF (match_operand:HI 2 "general_operand" "dmn"))))]
3110   "TARGET_68881"
3111   "*
3112 {
3113   return (TARGET_68040_ONLY
3114           ? \"fsdiv%.w %2,%0\"
3115           : \"fsgldiv%.w %2,%0\");
3116 }")
3117
3118 (define_insn ""
3119   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3120         (div:SF (match_operand:SF 1 "general_operand" "0")
3121                 (float:SF (match_operand:QI 2 "general_operand" "dmn"))))]
3122   "TARGET_68881"
3123   "*
3124 {
3125   return (TARGET_68040_ONLY
3126           ? \"fsdiv%.b %2,%0\"
3127           : \"fsgldiv%.b %2,%0\");
3128 }")
3129
3130 (define_insn ""
3131   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3132         (div:SF (match_operand:SF 1 "general_operand" "0")
3133                 (match_operand:SF 2 "general_operand" "fdmF")))]
3134   "TARGET_68881"
3135   "*
3136 {
3137 #ifdef FSGLDIV_USE_S
3138   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3139     return (TARGET_68040_ONLY
3140             ? \"fsdiv%.s %2,%0\"
3141             : \"fsgldiv%.s %2,%0\");
3142 #else
3143   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3144     return (TARGET_68040_ONLY
3145             ? \"fsdiv%.x %2,%0\"
3146             : \"fsgldiv%.x %2,%0\");
3147 #endif
3148   return (TARGET_68040_ONLY
3149           ? \"fsdiv%.s %f2,%0\"
3150           : \"fsgldiv%.s %f2,%0\");
3151 }")
3152 \f
3153 ;; Remainder instructions.
3154
3155 (define_insn "divmodsi4"
3156   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3157         (div:SI (match_operand:SI 1 "general_operand" "0")
3158                 (match_operand:SI 2 "general_src_operand" "dmSTK")))
3159    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3160         (mod:SI (match_dup 1) (match_dup 2)))]
3161   "TARGET_68020 && !TARGET_5200"
3162   "*
3163 {
3164   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3165     return \"divs%.l %2,%0\";
3166   else
3167     return \"divsl%.l %2,%3:%0\";
3168 }")
3169
3170 (define_insn "udivmodsi4"
3171   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3172         (udiv:SI (match_operand:SI 1 "general_operand" "0")
3173                  (match_operand:SI 2 "general_src_operand" "dmSTK")))
3174    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3175         (umod:SI (match_dup 1) (match_dup 2)))]
3176   "TARGET_68020 && !TARGET_5200"
3177   "*
3178 {
3179   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3180     return \"divu%.l %2,%0\";
3181   else
3182     return \"divul%.l %2,%3:%0\";
3183 }")
3184
3185 (define_insn "divmodhi4"
3186   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3187         (div:HI (match_operand:HI 1 "general_operand" "0")
3188                 (match_operand:HI 2 "general_src_operand" "dmSKT")))
3189    (set (match_operand:HI 3 "nonimmediate_operand" "=d")
3190         (mod:HI (match_dup 1) (match_dup 2)))]
3191   "!TARGET_5200"
3192   "*
3193 {
3194 #ifdef MOTOROLA
3195   output_asm_insn (\"ext%.l %0\;divs%.w %2,%0\", operands);
3196 #else
3197   output_asm_insn (\"extl %0\;divs %2,%0\", operands);
3198 #endif
3199   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3200     {
3201       CC_STATUS_INIT;
3202       return \"move%.l %0,%3\;swap %3\";
3203     }
3204   else
3205     return \"\";
3206 }")
3207
3208 (define_insn "udivmodhi4"
3209   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3210         (udiv:HI (match_operand:HI 1 "general_operand" "0")
3211                  (match_operand:HI 2 "general_src_operand" "dmSKT")))
3212    (set (match_operand:HI 3 "nonimmediate_operand" "=d")
3213         (umod:HI (match_dup 1) (match_dup 2)))]
3214   "!TARGET_5200"
3215   "*
3216 {
3217 #ifdef MOTOROLA
3218   output_asm_insn (\"and%.l %#0xFFFF,%0\;divu%.w %2,%0\", operands);
3219 #else
3220   output_asm_insn (\"and%.l %#0xFFFF,%0\;divu %2,%0\", operands);
3221 #endif
3222   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3223     {
3224       CC_STATUS_INIT;
3225       return \"move%.l %0,%3\;swap %3\";
3226     }
3227   else
3228     return \"\";
3229 }")
3230 \f
3231 ;; logical-and instructions
3232
3233 ;; "anddi3" is mainly here to help combine().
3234 (define_insn "anddi3"
3235   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3236         (and:DI (match_operand:DI 1 "general_operand" "%0,0")
3237                 (match_operand:DI 2 "general_operand" "dn,don")))]
3238   "!TARGET_5200"
3239   "*
3240 {
3241   CC_STATUS_INIT;
3242   /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3243   if (CONSTANT_P (operands[2]))
3244     {
3245       rtx hi, lo;
3246
3247       split_double (operands[2], &hi, &lo);
3248
3249       switch (INTVAL (hi))
3250         {
3251           case 0 :
3252             output_asm_insn (\"clr%.l %0\", operands);
3253             break;
3254           case -1 :
3255             break;
3256           default :
3257             {
3258             rtx xoperands[3];
3259
3260             xoperands[0] = operands[0];
3261             xoperands[2] = hi;
3262             output_asm_insn (output_andsi3 (xoperands), xoperands);
3263             }
3264         }
3265       if (GET_CODE (operands[0]) == REG)
3266         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3267       else
3268         operands[0] = adjust_address (operands[0], SImode, 4);
3269       switch (INTVAL (lo))
3270         {
3271           case 0 :
3272             output_asm_insn (\"clr%.l %0\", operands);
3273             break;
3274           case -1 :
3275             break;
3276           default :
3277             {
3278             rtx xoperands[3];
3279
3280             xoperands[0] = operands[0];
3281             xoperands[2] = lo;
3282             output_asm_insn (output_andsi3 (xoperands), xoperands);
3283             }
3284         }
3285       return \"\";
3286     }
3287   if (GET_CODE (operands[0]) != REG)
3288     {
3289       operands[1] = adjust_address (operands[0], SImode, 4);
3290       return \"and%.l %2,%0\;and%.l %R2,%1\";
3291     }
3292   if (GET_CODE (operands[2]) != REG)
3293     {
3294       operands[1] = adjust_address (operands[2], SImode, 4);
3295       return \"and%.l %2,%0\;and%.l %1,%R0\";
3296     }
3297   return \"and%.l %2,%0\;and%.l %R2,%R0\";
3298 }")
3299
3300 ;; Prevent AND from being made with sp.  This doesn't exist in the machine
3301 ;; and reload will cause inefficient code.  Since sp is a FIXED_REG, we
3302 ;; can't allocate pseudos into it.
3303
3304 (define_expand "andsi3"
3305   [(set (match_operand:SI 0 "not_sp_operand" "")
3306         (and:SI (match_operand:SI 1 "general_operand" "")
3307                 (match_operand:SI 2 "general_src_operand" "")))]
3308   ""
3309   "")
3310
3311 (define_insn "andsi3_internal"
3312   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3313         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3314                 (match_operand:SI 2 "general_src_operand" "dKT,dmSM")))]
3315   "!TARGET_5200"
3316   "*
3317 {
3318   return output_andsi3 (operands);
3319 }")
3320
3321 (define_insn "andsi3_5200"
3322   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3323         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3324                 (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
3325   "TARGET_5200"
3326   "and%.l %2,%0")
3327
3328 (define_insn "andhi3"
3329   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
3330         (and:HI (match_operand:HI 1 "general_operand" "%0,0")
3331                 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
3332   "!TARGET_5200"
3333   "and%.w %2,%0")
3334
3335 (define_insn ""
3336   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3337         (and:HI (match_dup 0)
3338                 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
3339   "!TARGET_5200"
3340   "and%.w %1,%0")
3341
3342 (define_insn ""
3343   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3344         (and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
3345                 (match_dup 0)))]
3346   "!TARGET_5200"
3347   "and%.w %1,%0")
3348
3349 (define_insn "andqi3"
3350   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
3351         (and:QI (match_operand:QI 1 "general_operand" "%0,0")
3352                 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
3353   "!TARGET_5200"
3354   "and%.b %2,%0")
3355
3356 (define_insn ""
3357   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3358         (and:QI (match_dup 0)
3359                 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
3360   "!TARGET_5200"
3361   "and%.b %1,%0")
3362
3363 (define_insn ""
3364   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3365         (and:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
3366                 (match_dup 0)))]
3367   "!TARGET_5200"
3368   "and%.b %1,%0")
3369 \f
3370 ;; inclusive-or instructions
3371
3372 (define_insn "iordi_zext"
3373   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3374     (ior:DI (zero_extend:DI (match_operand 1 "general_operand" "dn,dmn"))
3375         (match_operand:DI 2 "general_operand" "0,0")))]
3376   "!TARGET_5200"
3377   "*
3378 {
3379   int byte_mode;
3380
3381   CC_STATUS_INIT;
3382   if (GET_CODE (operands[0]) == REG)
3383     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3384   else
3385     operands[0] = adjust_address (operands[0], SImode, 4);
3386   if (GET_MODE (operands[1]) == SImode)
3387     return \"or%.l %1,%0\";
3388   byte_mode = (GET_MODE (operands[1]) == QImode);
3389   if (GET_CODE (operands[0]) == MEM)
3390     operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
3391                                   byte_mode ? 3 : 2);
3392   if (byte_mode)
3393     return \"or%.b %1,%0\";
3394   else
3395     return \"or%.w %1,%0\";
3396 }")
3397
3398 ;; "iordi3" is mainly here to help combine().
3399 (define_insn "iordi3"
3400   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3401         (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
3402                 (match_operand:DI 2 "general_operand" "dn,don")))]
3403   "!TARGET_5200"
3404   "*
3405 {
3406   CC_STATUS_INIT;
3407   /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3408   if (CONSTANT_P (operands[2]))
3409     {
3410       rtx hi, lo;
3411
3412       split_double (operands[2], &hi, &lo);
3413
3414       switch (INTVAL (hi))
3415         {
3416           case 0 :
3417             break;
3418           case -1 :
3419             /* FIXME : a scratch register would be welcome here if operand[0]
3420                is not a register */
3421             output_asm_insn (\"move%.l %#-1,%0\", operands);
3422             break;
3423           default :
3424             {
3425             rtx xoperands[3];
3426
3427             xoperands[0] = operands[0];
3428             xoperands[2] = hi;
3429             output_asm_insn (output_iorsi3 (xoperands), xoperands);
3430             }
3431         }
3432       if (GET_CODE (operands[0]) == REG)
3433         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3434       else
3435         operands[0] = adjust_address (operands[0], SImode, 4);
3436       switch (INTVAL (lo))
3437         {
3438           case 0 :
3439             break;
3440           case -1 :
3441             /* FIXME : a scratch register would be welcome here if operand[0]
3442                is not a register */
3443             output_asm_insn (\"move%.l %#-1,%0\", operands);
3444             break;
3445           default :
3446             {
3447             rtx xoperands[3];
3448
3449             xoperands[0] = operands[0];
3450             xoperands[2] = lo;
3451             output_asm_insn (output_iorsi3 (xoperands), xoperands);
3452             }
3453         }
3454       return \"\";
3455     }
3456   if (GET_CODE (operands[0]) != REG)
3457     {
3458       operands[1] = adjust_address (operands[0], SImode, 4);
3459       return \"or%.l %2,%0\;or%.l %R2,%1\";
3460     }
3461   if (GET_CODE (operands[2]) != REG)
3462     {
3463       operands[1] = adjust_address (operands[2], SImode, 4);
3464       return \"or%.l %2,%0\;or%.l %1,%R0\";
3465     }
3466   return \"or%.l %2,%0\;or%.l %R2,%R0\";
3467 }")
3468
3469 (define_expand "iorsi3"
3470   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3471         (ior:SI (match_operand:SI 1 "general_operand" "")
3472                 (match_operand:SI 2 "general_src_operand" "")))]
3473   ""
3474   "")
3475
3476 (define_insn "iorsi3_internal"