OSDN Git Service

* config/m68k/m68k.c (output_move_const_into_data_reg,
[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     return \"moveq %#0,%0\";
722   return \"clr%.l %0\";
723 }")
724
725 ;; General case of fullword move.
726 ;;
727 ;; This is the main "hook" for PIC code.  When generating
728 ;; PIC, movsi is responsible for determining when the source address
729 ;; needs PIC relocation and appropriately calling legitimize_pic_address
730 ;; to perform the actual relocation.
731 ;;
732 ;; In both the PIC and non-PIC cases the patterns generated will
733 ;; matched by the next define_insn.
734 (define_expand "movsi"
735   [(set (match_operand:SI 0 "nonimmediate_operand" "")
736         (match_operand:SI 1 "general_operand" ""))]
737   ""
738   "
739 {
740   if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
741     {
742       /* The source is an address which requires PIC relocation.
743          Call legitimize_pic_address with the source, mode, and a relocation
744          register (a new pseudo, or the final destination if reload_in_progress
745          is set).   Then fall through normally */
746       rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
747       operands[1] = legitimize_pic_address (operands[1], SImode, temp);
748     }
749   else if (flag_pic && TARGET_PCREL && ! reload_in_progress)
750     {
751       /* Don't allow writes to memory except via a register;
752          the m68k doesn't consider PC-relative addresses to be writable.  */
753       if (symbolic_operand (operands[0], SImode))
754         operands[0] = force_reg (SImode, XEXP (operands[0], 0));
755       else if (GET_CODE (operands[0]) == MEM
756                && symbolic_operand (XEXP (operands[0], 0), SImode))
757         operands[0] = gen_rtx (MEM, SImode,
758                                force_reg (SImode, XEXP (operands[0], 0)));
759     }
760 }")
761
762 ;; General case of fullword move.  The register constraints
763 ;; force integer constants in range for a moveq to be reloaded
764 ;; if they are headed for memory.
765 (define_insn ""
766   ;; Notes: make sure no alternative allows g vs g.
767   ;; We don't allow f-regs since fixed point cannot go in them.
768   [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
769         (match_operand:SI 1 "general_src_operand" "daymSKT,n,i"))]
770
771   "!TARGET_5200"
772   "*
773 {
774   return output_move_simode (operands);
775 }")
776
777 (define_insn ""
778   [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g")
779         (match_operand:SI 1 "general_operand" "g,r<Q>"))]
780   "TARGET_5200"
781   "* return output_move_simode (operands);")
782
783 ;; Special case of fullword move, where we need to get a non-GOT PIC
784 ;; reference into an address register.
785 (define_insn ""
786   [(set (match_operand:SI 0 "nonimmediate_operand" "=a<")
787         (match_operand:SI 1 "pcrel_address" ""))]
788   "TARGET_PCREL"
789   "*
790 {
791   if (push_operand (operands[0], SImode))
792     return \"pea %a1\";
793   return \"lea %a1,%0\";
794 }")
795
796 (define_expand "movhi"
797   [(set (match_operand:HI 0 "nonimmediate_operand" "")
798         (match_operand:HI 1 "general_operand" ""))]
799   ""
800   "")
801
802 (define_insn ""
803   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
804         (match_operand:HI 1 "general_src_operand" "gS"))]
805   "!TARGET_5200"
806   "* return output_move_himode (operands);")
807
808  (define_insn ""
809   [(set (match_operand:HI 0 "nonimmediate_operand" "=r<Q>,g")
810         (match_operand:HI 1 "general_operand" "g,r<Q>"))]
811   "TARGET_5200"
812   "* return output_move_himode (operands);")
813
814 (define_expand "movstricthi"
815   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
816         (match_operand:HI 1 "general_src_operand" ""))]
817   ""
818   "")
819
820 (define_insn ""
821   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
822         (match_operand:HI 1 "general_src_operand" "rmSn"))]
823   "!TARGET_5200"
824   "* return output_move_stricthi (operands);")
825
826 (define_insn ""
827   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+d,m"))
828         (match_operand:HI 1 "general_src_operand" "rmn,r"))]
829   "TARGET_5200"
830   "* return output_move_stricthi (operands);")
831
832 (define_expand "movqi"
833   [(set (match_operand:QI 0 "nonimmediate_operand" "")
834         (match_operand:QI 1 "general_src_operand" ""))]
835   ""
836   "")
837
838 (define_insn ""
839   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,*a,m")
840         (match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))]
841   "!TARGET_5200"
842   "* return output_move_qimode (operands);")
843
844 (define_insn ""
845   [(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>,dm,d*a")
846         (match_operand:QI 1 "general_src_operand" "dmi,d<Q>,di*a"))]
847   "TARGET_5200"
848   "* return output_move_qimode (operands);")
849
850 (define_expand "movstrictqi"
851   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
852         (match_operand:QI 1 "general_src_operand" ""))]
853   ""
854   "")
855
856 (define_insn ""
857   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
858         (match_operand:QI 1 "general_src_operand" "dmSn"))]
859   "!TARGET_5200"
860   "* return output_move_strictqi (operands);")
861
862 (define_insn ""
863   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d,m"))
864         (match_operand:QI 1 "general_src_operand" "dmn,d"))]
865   "TARGET_5200"
866   "* return output_move_strictqi (operands);")
867
868 (define_expand "pushqi1"
869   [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int -2)))
870    (set (mem:QI (plus:SI (reg:SI 15) (const_int 1)))
871         (match_operand:QI 0 "general_operand" ""))]
872   "!TARGET_5200"
873   "")
874
875 (define_expand "movsf"
876   [(set (match_operand:SF 0 "nonimmediate_operand" "")
877         (match_operand:SF 1 "general_operand" ""))]
878   ""
879   "")
880
881 (define_insn ""
882   [(set (match_operand:SF 0 "nonimmediate_operand" "=rmf")
883         (match_operand:SF 1 "general_operand" "rmfF"))]
884   "!TARGET_5200"
885   "*
886 {
887   if (FP_REG_P (operands[0]))
888     {
889       if (FP_REG_P (operands[1]))
890         return \"f%$move%.x %1,%0\";
891       else if (ADDRESS_REG_P (operands[1]))
892         return \"move%.l %1,%-\;f%$move%.s %+,%0\";
893       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
894         return output_move_const_single (operands);
895       return \"f%$move%.s %f1,%0\";
896     }
897   if (FP_REG_P (operands[1]))
898     {
899       if (ADDRESS_REG_P (operands[0]))
900         return \"fmove%.s %1,%-\;move%.l %+,%0\";
901       return \"fmove%.s %f1,%0\";
902     }
903   if (operands[1] == CONST0_RTX (SFmode)
904       /* clr insns on 68000 read before writing.
905          This isn't so on the 68010, but we have no TARGET_68010.  */
906       && ((TARGET_68020 || TARGET_5200)
907           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
908     {
909       if (ADDRESS_REG_P (operands[0]))
910         {
911           /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
912           if (!TARGET_68040 && !TARGET_68060)
913             return \"sub%.l %0,%0\";
914           else
915             {
916 #ifdef MOTOROLA
917 #ifdef SGS
918               /* Many SGS assemblers croak on size specifiers for constants.  */
919               return \"lea 0,%0\";
920 #else
921               return \"lea 0.w,%0\";
922 #endif
923 #else
924               return \"lea 0:w,%0\";
925 #endif
926             }
927         }
928       /* moveq is faster on the 68000.  */
929       if (DATA_REG_P (operands[0]) && !(TARGET_68020 || TARGET_5200))
930         {
931           return \"moveq %#0,%0\";
932         }
933       return \"clr%.l %0\";
934     }
935   return \"move%.l %1,%0\";
936 }")
937
938 (define_insn ""
939   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,g")
940         (match_operand:SF 1 "general_operand" "g,r"))]
941   "TARGET_5200"
942   "* return \"move%.l %1,%0\";")
943
944 (define_expand "movdf"
945   [(set (match_operand:DF 0 "nonimmediate_operand" "")
946         (match_operand:DF 1 "general_operand" ""))]
947   ""
948   "")
949
950 (define_insn ""
951   [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,rf,rf,&rof<>")
952         (match_operand:DF 1 "general_operand" "*rf,m,0,*rofE<>"))]
953 ;  [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,&rf,&rof<>")
954 ;       (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
955   "!TARGET_5200"
956   "*
957 {
958   if (FP_REG_P (operands[0]))
959     {
960       if (FP_REG_P (operands[1]))
961         return \"f%&move%.x %1,%0\";
962       if (REG_P (operands[1]))
963         {
964           rtx xoperands[2];
965           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
966           output_asm_insn (\"move%.l %1,%-\", xoperands);
967           output_asm_insn (\"move%.l %1,%-\", operands);
968           return \"f%&move%.d %+,%0\";
969         }
970       if (GET_CODE (operands[1]) == CONST_DOUBLE)
971         return output_move_const_double (operands);
972       return \"f%&move%.d %f1,%0\";
973     }
974   else if (FP_REG_P (operands[1]))
975     {
976       if (REG_P (operands[0]))
977         {
978           output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
979           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
980           return \"move%.l %+,%0\";
981         }
982       else
983         return \"fmove%.d %f1,%0\";
984     }
985   return output_move_double (operands);
986 }")
987
988 (define_insn ""
989   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,g")
990         (match_operand:DF 1 "general_operand" "g,r"))]
991   "TARGET_5200"
992   "* return output_move_double (operands);")
993
994 ;; ??? The XFmode patterns are schizophrenic about whether constants are
995 ;; allowed.  Most but not all have predicates and constraint that disallow
996 ;; constants.  Most but not all have output templates that handle constants.
997 ;; See also LEGITIMATE_CONSTANT_P.
998
999 (define_expand "movxf"
1000   [(set (match_operand:XF 0 "nonimmediate_operand" "")
1001         (match_operand:XF 1 "general_operand" ""))]
1002   ""
1003   "
1004 {
1005   /* We can't rewrite operands during reload.  */
1006   if (! reload_in_progress)
1007     {
1008       if (CONSTANT_P (operands[1]))
1009         {
1010           operands[1] = force_const_mem (XFmode, operands[1]);
1011           if (! memory_address_p (XFmode, XEXP (operands[1], 0)))
1012             operands[1] = adjust_address (operands[1], XFmode, 0);
1013         }
1014       if (flag_pic && TARGET_PCREL)
1015         {
1016           /* Don't allow writes to memory except via a register; the
1017              m68k doesn't consider PC-relative addresses to be writable.  */
1018           if (GET_CODE (operands[0]) == MEM
1019               && symbolic_operand (XEXP (operands[0], 0), SImode))
1020             operands[0] = gen_rtx (MEM, XFmode,
1021                                    force_reg (SImode, XEXP (operands[0], 0)));
1022         }
1023     }
1024 }")
1025
1026 (define_insn ""
1027   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f,!r")
1028         (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r,!r"))]
1029   "TARGET_68881"
1030   "*
1031 {
1032   if (FP_REG_P (operands[0]))
1033     {
1034       if (FP_REG_P (operands[1]))
1035         return \"fmove%.x %1,%0\";
1036       if (REG_P (operands[1]))
1037         {
1038           rtx xoperands[2];
1039           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1040           output_asm_insn (\"move%.l %1,%-\", xoperands);
1041           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1042           output_asm_insn (\"move%.l %1,%-\", xoperands);
1043           output_asm_insn (\"move%.l %1,%-\", operands);
1044           return \"fmove%.x %+,%0\";
1045         }
1046       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1047         return \"fmove%.x %1,%0\";
1048       return \"fmove%.x %f1,%0\";
1049     }
1050   if (FP_REG_P (operands[1]))
1051     {
1052       if (REG_P (operands[0]))
1053         {
1054           output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
1055           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1056           output_asm_insn (\"move%.l %+,%0\", operands);
1057           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1058           return \"move%.l %+,%0\";
1059         }
1060       /* Must be memory destination.  */
1061       return \"fmove%.x %f1,%0\";
1062     }
1063   return output_move_double (operands);
1064 }
1065 ")
1066
1067 (define_insn ""
1068   [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
1069         (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))]
1070   "! TARGET_68881 && ! TARGET_5200"
1071   "*
1072 {
1073   if (FP_REG_P (operands[0]))
1074     {
1075       if (FP_REG_P (operands[1]))
1076         return \"fmove%.x %1,%0\";
1077       if (REG_P (operands[1]))
1078         {
1079           rtx xoperands[2];
1080           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1081           output_asm_insn (\"move%.l %1,%-\", xoperands);
1082           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1083           output_asm_insn (\"move%.l %1,%-\", xoperands);
1084           output_asm_insn (\"move%.l %1,%-\", operands);
1085           return \"fmove%.x %+,%0\";
1086         }
1087       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1088         return \"fmove%.x %1,%0\";
1089       return \"fmove%.x %f1,%0\";
1090     }
1091   if (FP_REG_P (operands[1]))
1092     {
1093       if (REG_P (operands[0]))
1094         {
1095           output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
1096           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1097           output_asm_insn (\"move%.l %+,%0\", operands);
1098           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1099           return \"move%.l %+,%0\";
1100         }
1101       else
1102         return \"fmove%.x %f1,%0\";
1103     }
1104   return output_move_double (operands);
1105 }
1106 ")
1107
1108 (define_insn ""
1109   [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g")
1110         (match_operand:XF 1 "nonimmediate_operand" "g,r"))]
1111   "! TARGET_68881 && TARGET_5200"
1112   "* return output_move_double (operands);")
1113
1114 (define_expand "movdi"
1115   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1116   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1117         (match_operand:DI 1 "general_operand" ""))]
1118   ""
1119   "")
1120
1121 ;; movdi can apply to fp regs in some cases
1122 (define_insn ""
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" "=rm,r,&ro<>")
1125         (match_operand:DI 1 "general_operand" "rF,m,roi<>F"))]
1126 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&r,&ro<>,!&rm,!&f")
1127 ;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF"))]
1128 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&rf,&ro<>,!&rm,!&f")
1129 ;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
1130   "!TARGET_5200"
1131   "*
1132 {
1133   if (FP_REG_P (operands[0]))
1134     {
1135       if (FP_REG_P (operands[1]))
1136         return \"fmove%.x %1,%0\";
1137       if (REG_P (operands[1]))
1138         {
1139           rtx xoperands[2];
1140           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1141           output_asm_insn (\"move%.l %1,%-\", xoperands);
1142           output_asm_insn (\"move%.l %1,%-\", operands);
1143           return \"fmove%.d %+,%0\";
1144         }
1145       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1146         return output_move_const_double (operands);
1147       return \"fmove%.d %f1,%0\";
1148     }
1149   else if (FP_REG_P (operands[1]))
1150     {
1151       if (REG_P (operands[0]))
1152         {
1153           output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1154           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1155           return \"move%.l %+,%0\";
1156         }
1157       else
1158         return \"fmove%.d %f1,%0\";
1159     }
1160   return output_move_double (operands);
1161 }")
1162
1163 (define_insn ""
1164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,g")
1165         (match_operand:DI 1 "general_operand" "g,r"))]
1166   "TARGET_5200"
1167   "* return output_move_double (operands);")
1168
1169 ;; Thus goes after the move instructions
1170 ;; because the move instructions are better (require no spilling)
1171 ;; when they can apply.  It goes before the add/sub insns
1172 ;; so we will prefer it to them.
1173
1174 (define_insn "pushasi"
1175   [(set (match_operand:SI 0 "push_operand" "=m")
1176         (match_operand:SI 1 "address_operand" "p"))]
1177   ""
1178   "pea %a1")
1179 \f
1180 ;; truncation instructions
1181 (define_insn "truncsiqi2"
1182   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
1183         (truncate:QI
1184          (match_operand:SI 1 "general_src_operand" "doJS,i")))]
1185   ""
1186   "*
1187 {
1188   if (GET_CODE (operands[0]) == REG)
1189     {
1190       /* Must clear condition codes, since the move.l bases them on
1191          the entire 32 bits, not just the desired 8 bits.  */
1192       CC_STATUS_INIT;
1193       return \"move%.l %1,%0\";
1194     }
1195   if (GET_CODE (operands[1]) == MEM)
1196     operands[1] = adjust_address (operands[1], QImode, 3);
1197   return \"move%.b %1,%0\";
1198 }")
1199
1200 (define_insn "trunchiqi2"
1201   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
1202         (truncate:QI
1203          (match_operand:HI 1 "general_src_operand" "doJS,i")))]
1204   ""
1205   "*
1206 {
1207   if (GET_CODE (operands[0]) == REG
1208       && (GET_CODE (operands[1]) == MEM
1209           || GET_CODE (operands[1]) == CONST_INT))
1210     {
1211       /* Must clear condition codes, since the move.w bases them on
1212          the entire 16 bits, not just the desired 8 bits.  */
1213       CC_STATUS_INIT;
1214       return \"move%.w %1,%0\";
1215     }
1216   if (GET_CODE (operands[0]) == REG)
1217     {
1218       /* Must clear condition codes, since the move.l bases them on
1219          the entire 32 bits, not just the desired 8 bits.  */
1220       CC_STATUS_INIT;
1221       return \"move%.l %1,%0\";
1222     }
1223   if (GET_CODE (operands[1]) == MEM)
1224     operands[1] = adjust_address (operands[1], QImode, 1);
1225   return \"move%.b %1,%0\";
1226 }")
1227
1228 (define_insn "truncsihi2"
1229   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm,d")
1230         (truncate:HI
1231          (match_operand:SI 1 "general_src_operand" "roJS,i")))]
1232   ""
1233   "*
1234 {
1235   if (GET_CODE (operands[0]) == REG)
1236     {
1237       /* Must clear condition codes, since the move.l bases them on
1238          the entire 32 bits, not just the desired 8 bits.  */
1239       CC_STATUS_INIT;
1240       return \"move%.l %1,%0\";
1241     }
1242   if (GET_CODE (operands[1]) == MEM)
1243     operands[1] = adjust_address (operands[1], QImode, 2);
1244   return \"move%.w %1,%0\";
1245 }")
1246 \f
1247 ;; zero extension instructions
1248
1249 (define_insn "zero_extendqidi2"
1250   [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
1251         (zero_extend:DI (match_operand:QI 1 "general_operand" "dm")))]
1252   ""
1253   "*
1254 {
1255   CC_STATUS_INIT;
1256   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1257   return \"moveq %#0,%0\;moveq %#0,%2\;move%.b %1,%2\";
1258 }")
1259
1260 (define_insn "zero_extendhidi2"
1261   [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
1262         (zero_extend:DI (match_operand:HI 1 "general_operand" "rm")))]
1263   ""
1264   "*
1265 {
1266   CC_STATUS_INIT;
1267   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1268   return \"moveq %#0,%0\;moveq %#0,%2\;move%.w %1,%2\";
1269 }")
1270
1271 ;; this is the canonical form for (lshiftrt:DI x 32)
1272 (define_expand "zero_extendsidi2"
1273   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1274     (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
1275   ""
1276   "")
1277
1278 (define_insn "*zero_extendsidi2_cf"
1279   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
1280     (zero_extend:DI (match_operand:SI 1 "general_operand" "rm,r")))]
1281   "TARGET_5200"
1282   "*
1283 {
1284   CC_STATUS_INIT;
1285   if (GET_CODE (operands[0]) == REG)
1286     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1287   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1288     return \"move%.l %1,%0\;clr%.l %0\";
1289   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1290     return \"clr%.l %0\;move%.l %1,%0\";
1291   else
1292     operands[2] = adjust_address (operands[0], SImode, 4);
1293   if (GET_CODE (operands[1]) != REG || GET_CODE (operands[2]) != REG
1294       || REGNO (operands[1]) != REGNO (operands[2]))
1295     output_asm_insn (\"move%.l %1,%2\", operands);
1296   if (ADDRESS_REG_P (operands[0]))
1297     return \"sub%.l %0,%0\";
1298   else
1299     return \"clr%.l %0\";
1300 }")
1301
1302 (define_insn "*zero_extendsidi2"
1303   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1304     (zero_extend:DI (match_operand:SI 1 "general_operand" "rm")))]
1305   "!TARGET_5200"
1306   "*
1307 {
1308   CC_STATUS_INIT;
1309   if (GET_CODE (operands[0]) == REG)
1310     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1311   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1312     return \"move%.l %1,%0\;clr%.l %0\";
1313   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1314     return \"clr%.l %0\;move%.l %1,%0\";
1315   else
1316     operands[2] = adjust_address (operands[0], SImode, 4);
1317   if (GET_CODE (operands[1]) != REG || GET_CODE (operands[2]) != REG
1318       || REGNO (operands[1]) != REGNO (operands[2]))
1319     output_asm_insn (\"move%.l %1,%2\", operands);
1320   if (ADDRESS_REG_P (operands[0]))
1321     return \"sub%.l %0,%0\";
1322   else
1323     return \"clr%.l %0\";
1324 }")
1325
1326 (define_expand "zero_extendhisi2"
1327   [(set (match_operand:SI 0 "register_operand" "")
1328         (const_int 0))
1329    (set (strict_low_part (match_dup 2))
1330         (match_operand:HI 1 "general_operand" ""))]
1331   ""
1332   "
1333 {
1334   operands[1] = make_safe_from (operands[1], operands[0]);
1335   operands[2] = gen_lowpart_SUBREG (HImode, operands[0]);
1336 }")
1337
1338 (define_expand "zero_extendqihi2"
1339   [(set (match_operand:HI 0 "register_operand" "")
1340         (const_int 0))
1341    (set (strict_low_part (match_dup 2))
1342         (match_operand:QI 1 "general_operand" ""))]
1343   ""
1344   "
1345 {
1346   operands[1] = make_safe_from (operands[1], operands[0]);
1347   operands[2] = gen_lowpart_SUBREG (QImode, operands[0]);
1348 }")
1349
1350 (define_expand "zero_extendqisi2"
1351   [(set (match_operand:SI 0 "register_operand" "")
1352         (const_int 0))
1353    (set (strict_low_part (match_dup 2))
1354         (match_operand:QI 1 "general_operand" ""))]
1355   ""
1356   "
1357 {
1358   operands[1] = make_safe_from (operands[1], operands[0]);
1359   operands[2] = gen_lowpart_SUBREG (QImode, operands[0]);
1360 }")
1361 \f
1362 ;; Patterns to recognize zero-extend insns produced by the combiner.
1363 ;; We don't allow both operands in memory, because of aliasing problems.
1364 ;; Explicitly disallow two memory operands via the condition since reloading
1365 ;; of this case will result in worse code than the uncombined patterns.
1366
1367 (define_insn ""
1368   [(set (match_operand:SI 0 "nonimmediate_operand" "=do<>,d<")
1369         (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "r,mS")))]
1370   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1371   "*
1372 {
1373   if (DATA_REG_P (operands[0]))
1374     {
1375       if (GET_CODE (operands[1]) == REG
1376           && REGNO (operands[0]) == REGNO (operands[1]))
1377         return \"and%.l %#0xFFFF,%0\";
1378       if (reg_mentioned_p (operands[0], operands[1]))
1379         return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\";
1380       return \"clr%.l %0\;move%.w %1,%0\";
1381     }
1382   else if (GET_CODE (operands[0]) == MEM
1383            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1384     return \"move%.w %1,%0\;clr%.w %0\";
1385   else if (GET_CODE (operands[0]) == MEM
1386            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1387     return \"clr%.w %0\;move%.w %1,%0\";
1388   else
1389     {
1390       output_asm_insn (\"clr%.w %0\", operands);
1391       operands[0] = adjust_address (operands[0], HImode, 2);
1392       return \"move%.w %1,%0\";
1393     }
1394 }")
1395
1396 (define_insn ""
1397   [(set (match_operand:HI 0 "nonimmediate_operand" "=do<>,d")
1398         (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
1399   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1400   "*
1401 {
1402   if (DATA_REG_P (operands[0]))
1403     {
1404       if (GET_CODE (operands[1]) == REG
1405           && REGNO (operands[0]) == REGNO (operands[1]))
1406         return (!TARGET_5200 ? \"and%.w %#0xFF,%0\" : \"and%.l %#0xFF,%0\");
1407       if (reg_mentioned_p (operands[0], operands[1]))
1408         return (!TARGET_5200 ? \"move%.b %1,%0\;and%.w %#0xFF,%0\" 
1409                              : \"move%.b %1,%0\;and%.l %#0xFF,%0\");
1410       return \"clr%.w %0\;move%.b %1,%0\";
1411     }
1412   else if (GET_CODE (operands[0]) == MEM
1413            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1414     {
1415       if (REGNO (XEXP (XEXP (operands[0], 0), 0))
1416           == STACK_POINTER_REGNUM)
1417         {
1418           output_asm_insn (\"clr%.w %-\", operands);
1419           operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
1420                                      plus_constant (stack_pointer_rtx, 1));
1421           return \"move%.b %1,%0\";
1422         }
1423       else
1424         return \"move%.b %1,%0\;clr%.b %0\";
1425     }
1426   else if (GET_CODE (operands[0]) == MEM
1427            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1428     return \"clr%.b %0\;move%.b %1,%0\";
1429   else
1430     {
1431       output_asm_insn (\"clr%.b %0\", operands);
1432       operands[0] = adjust_address (operands[0], QImode, 1);
1433       return \"move%.b %1,%0\";
1434     }
1435 }")
1436
1437 (define_insn ""
1438   [(set (match_operand:SI 0 "nonimmediate_operand" "=do<>,d")
1439         (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
1440   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1441   "*
1442 {
1443   if (DATA_REG_P (operands[0]))
1444     {
1445       if (GET_CODE (operands[1]) == REG
1446           && REGNO (operands[0]) == REGNO (operands[1]))
1447         return \"and%.l %#0xFF,%0\";
1448       if (reg_mentioned_p (operands[0], operands[1]))
1449         return \"move%.b %1,%0\;and%.l %#0xFF,%0\";
1450       return \"clr%.l %0\;move%.b %1,%0\";
1451     }
1452   else if (GET_CODE (operands[0]) == MEM
1453            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1454     {
1455       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1456 #ifdef MOTOROLA
1457 #ifdef SGS
1458       return \"clr%.l -(%0)\;move%.b %1,3(%0)\";
1459 #else
1460       return \"clr%.l -(%0)\;move%.b %1,(3,%0)\";
1461 #endif
1462 #else
1463       return \"clrl %0@-\;moveb %1,%0@(3)\";
1464 #endif
1465     }
1466   else if (GET_CODE (operands[0]) == MEM
1467            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1468     {
1469       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1470 #ifdef MOTOROLA
1471 #ifdef SGS
1472       return \"clr%.l (%0)+\;move%.b %1,-1(%0)\";
1473 #else
1474       return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\";
1475 #endif
1476 #else
1477       return \"clrl %0@+\;moveb %1,%0@(-1)\";
1478 #endif
1479     }
1480   else
1481     {
1482       output_asm_insn (\"clr%.l %0\", operands);
1483       operands[0] = adjust_address (operands[0], QImode, 3);
1484       return \"move%.b %1,%0\";
1485     }
1486 }")
1487 \f
1488 ;; sign extension instructions
1489
1490 (define_insn "extendqidi2"
1491   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1492         (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))]
1493   ""
1494   "*
1495 {
1496   CC_STATUS_INIT;
1497   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1498   if (TARGET_68020 || TARGET_5200)
1499     return \"move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0\";
1500   else
1501     return \"move%.b %1,%2\;ext%.w %0\;ext%.l %2\;move%.l %2,%0\;smi %0\";
1502 }")
1503
1504 (define_insn "extendhidi2"
1505   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1506         (sign_extend:DI
1507          (match_operand:HI 1 "general_src_operand" "rmS")))]
1508   ""
1509   "*
1510 {
1511   CC_STATUS_INIT;
1512   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1513   if (TARGET_68020 || TARGET_5200)
1514     return \"move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0\";
1515   else
1516     return \"move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0\";
1517 }")
1518
1519 (define_insn "extendsidi2"
1520   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1521         (sign_extend:DI
1522          (match_operand:SI 1 "general_operand" "rm")))]
1523   ""
1524   "*
1525 {
1526   CC_STATUS_INIT;
1527   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1528   if (TARGET_68020 || TARGET_5200)
1529     return \"move%.l %1,%2\;smi %0\;extb%.l %0\";
1530   else
1531     return \"move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0\";
1532 }")
1533
1534 ;; Special case when one can avoid register clobbering, copy and test
1535 ;; Maybe there is a way to make that the general case, by forcing the
1536 ;; result of the SI tree to be in the lower register of the DI target
1537
1538 (define_insn "extendplussidi"
1539   [(set (match_operand:DI 0 "register_operand" "=d")
1540     (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
1541             (match_operand:SI 2 "general_operand" "rmn"))))]
1542   ""
1543   "*
1544 {
1545   CC_STATUS_INIT;
1546   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1547   if (GET_CODE (operands[1]) == CONST_INT
1548   && (unsigned) INTVAL (operands[1]) > 8)
1549     {
1550       rtx tmp = operands[1];
1551
1552       operands[1] = operands[2];
1553       operands[2] = tmp;
1554     }
1555   if (GET_CODE (operands[1]) == REG
1556       && REGNO (operands[1]) == REGNO (operands[3]))
1557     output_asm_insn (\"add%.l %2,%3\", operands);
1558   else
1559     output_asm_insn (\"move%.l %2,%3\;add%.l %1,%3\", operands);
1560   if (TARGET_68020 || TARGET_5200)
1561     return \"smi %0\;extb%.l %0\";
1562   else
1563     return \"smi %0\;ext%.w %0\;ext%.l %0\";
1564 }")
1565
1566 (define_insn "extendhisi2"
1567   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
1568         (sign_extend:SI
1569          (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
1570   ""
1571   "*
1572 {
1573   if (ADDRESS_REG_P (operands[0]))
1574     return \"move%.w %1,%0\";
1575   return \"ext%.l %0\";
1576 }")
1577
1578 (define_insn "extendqihi2"
1579   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
1580         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1581   ""
1582   "ext%.w %0")
1583
1584 (define_insn "extendqisi2"
1585   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
1586         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1587   "TARGET_68020 || TARGET_5200"
1588   "extb%.l %0")
1589 \f
1590 ;; Conversions between float and double.
1591
1592 (define_expand "extendsfdf2"
1593   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1594         (float_extend:DF
1595          (match_operand:SF 1 "general_operand" "")))]
1596   "TARGET_68881"
1597   "")
1598
1599 (define_insn ""
1600   [(set (match_operand:DF 0 "nonimmediate_operand" "=*fdm,f")
1601         (float_extend:DF
1602           (match_operand:SF 1 "general_operand" "f,dmF")))]
1603   "TARGET_68881"
1604   "*
1605 {
1606   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1607     {
1608       if (REGNO (operands[0]) == REGNO (operands[1]))
1609         {
1610           /* Extending float to double in an fp-reg is a no-op.
1611              NOTICE_UPDATE_CC has already assumed that the
1612              cc will be set.  So cancel what it did.  */
1613           cc_status = cc_prev_status;
1614           return \"\";
1615         }
1616       return \"f%&move%.x %1,%0\";
1617     }
1618   if (FP_REG_P (operands[0]))
1619     return \"f%&move%.s %f1,%0\";
1620   if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
1621     {
1622       output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1623       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1624       return \"move%.l %+,%0\";
1625     }
1626   return \"fmove%.d %f1,%0\";
1627 }")
1628
1629 ;; This cannot output into an f-reg because there is no way to be
1630 ;; sure of truncating in that case.
1631 (define_expand "truncdfsf2"
1632   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1633         (float_truncate:SF
1634           (match_operand:DF 1 "general_operand" "")))]
1635   "TARGET_68881"
1636   "")
1637
1638 ;; On the '040 we can truncate in a register accurately and easily.
1639 (define_insn ""
1640   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1641         (float_truncate:SF
1642           (match_operand:DF 1 "general_operand" "fmG")))]
1643   "TARGET_68040_ONLY"
1644   "*
1645 {
1646   if (FP_REG_P (operands[1]))
1647     return \"f%$move%.x %1,%0\";
1648   return \"f%$move%.d %f1,%0\";
1649 }")
1650
1651 (define_insn ""
1652   [(set (match_operand:SF 0 "nonimmediate_operand" "=dm")
1653         (float_truncate:SF
1654           (match_operand:DF 1 "general_operand" "f")))]
1655   "TARGET_68881"
1656   "fmove%.s %f1,%0")
1657 \f
1658 ;; Conversion between fixed point and floating point.
1659 ;; Note that among the fix-to-float insns
1660 ;; the ones that start with SImode come first.
1661 ;; That is so that an operand that is a CONST_INT
1662 ;; (and therefore lacks a specific machine mode).
1663 ;; will be recognized as SImode (which is always valid)
1664 ;; rather than as QImode or HImode.
1665
1666 (define_expand "floatsisf2"
1667   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1668         (float:SF (match_operand:SI 1 "general_operand" "")))]
1669   "TARGET_68881"
1670   "")
1671
1672 (define_insn ""
1673   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1674         (float:SF (match_operand:SI 1 "general_operand" "dmi")))]
1675   "TARGET_68881"
1676   "f%$move%.l %1,%0")
1677
1678 (define_expand "floatsidf2"
1679   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1680         (float:DF (match_operand:SI 1 "general_operand" "")))]
1681   "TARGET_68881"
1682   "")
1683
1684 (define_insn ""
1685   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1686         (float:DF (match_operand:SI 1 "general_operand" "dmi")))]
1687   "TARGET_68881"
1688   "f%&move%.l %1,%0")
1689
1690 (define_insn "floathisf2"
1691   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1692         (float:SF (match_operand:HI 1 "general_operand" "dmn")))]
1693   "TARGET_68881"
1694   "f%$move%.w %1,%0")
1695
1696 (define_insn "floathidf2"
1697   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1698         (float:DF (match_operand:HI 1 "general_operand" "dmn")))]
1699   "TARGET_68881"
1700   "fmove%.w %1,%0")
1701
1702 (define_insn "floatqisf2"
1703   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1704         (float:SF (match_operand:QI 1 "general_operand" "dmn")))]
1705   "TARGET_68881"
1706   "fmove%.b %1,%0")
1707
1708 (define_insn "floatqidf2"
1709   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1710         (float:DF (match_operand:QI 1 "general_operand" "dmn")))]
1711   "TARGET_68881"
1712   "f%&move%.b %1,%0")
1713
1714 ;; New routines to convert floating-point values to integers
1715 ;; to be used on the '040.  These should be faster than trapping
1716 ;; into the kernel to emulate fintrz.  They should also be faster
1717 ;; than calling the subroutines fixsfsi or fixdfsi.
1718
1719 (define_insn "fix_truncdfsi2"
1720   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
1721         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1722    (clobber (match_scratch:SI 2 "=d"))
1723    (clobber (match_scratch:SI 3 "=d"))]
1724   "TARGET_68881 && TARGET_68040"
1725   "*
1726 {
1727   CC_STATUS_INIT;
1728   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,%!\";
1729 }")
1730
1731 (define_insn "fix_truncdfhi2"
1732   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
1733         (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1734    (clobber (match_scratch:SI 2 "=d"))
1735    (clobber (match_scratch:SI 3 "=d"))]
1736   "TARGET_68881 && TARGET_68040"
1737   "*
1738 {
1739   CC_STATUS_INIT;
1740   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,%!\";
1741 }")
1742
1743 (define_insn "fix_truncdfqi2"
1744   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
1745         (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1746    (clobber (match_scratch:SI 2 "=d"))
1747    (clobber (match_scratch:SI 3 "=d"))]
1748   "TARGET_68881 && TARGET_68040"
1749   "*
1750 {
1751   CC_STATUS_INIT;
1752   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,%!\";
1753 }")
1754
1755 ;; Convert a float to a float whose value is an integer.
1756 ;; This is the first stage of converting it to an integer type.
1757
1758 (define_insn "ftruncdf2"
1759   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1760         (fix:DF (match_operand:DF 1 "general_operand" "fFm")))]
1761   "TARGET_68881 && !TARGET_68040"
1762   "*
1763 {
1764   if (FP_REG_P (operands[1]))
1765     return \"fintrz%.x %f1,%0\";
1766   return \"fintrz%.d %f1,%0\";
1767 }")
1768
1769 (define_insn "ftruncsf2"
1770   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1771         (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))]
1772   "TARGET_68881 && !TARGET_68040"
1773   "*
1774 {
1775   if (FP_REG_P (operands[1]))
1776     return \"fintrz%.x %f1,%0\";
1777   return \"fintrz%.s %f1,%0\";
1778 }")
1779
1780 ;; Convert a float whose value is an integer
1781 ;; to an actual integer.  Second stage of converting float to integer type.
1782 (define_insn "fixsfqi2"
1783   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
1784         (fix:QI (match_operand:SF 1 "general_operand" "f")))]
1785   "TARGET_68881"
1786   "fmove%.b %1,%0")
1787
1788 (define_insn "fixsfhi2"
1789   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
1790         (fix:HI (match_operand:SF 1 "general_operand" "f")))]
1791   "TARGET_68881"
1792   "fmove%.w %1,%0")
1793
1794 (define_insn "fixsfsi2"
1795   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
1796         (fix:SI (match_operand:SF 1 "general_operand" "f")))]
1797   "TARGET_68881"
1798   "fmove%.l %1,%0")
1799
1800 (define_insn "fixdfqi2"
1801   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
1802         (fix:QI (match_operand:DF 1 "general_operand" "f")))]
1803   "TARGET_68881"
1804   "fmove%.b %1,%0")
1805
1806 (define_insn "fixdfhi2"
1807   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
1808         (fix:HI (match_operand:DF 1 "general_operand" "f")))]
1809   "TARGET_68881"
1810   "fmove%.w %1,%0")
1811
1812 (define_insn "fixdfsi2"
1813   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
1814         (fix:SI (match_operand:DF 1 "general_operand" "f")))]
1815   "TARGET_68881"
1816   "fmove%.l %1,%0")
1817 \f
1818 ;; add instructions
1819
1820 (define_insn "adddi_lshrdi_63"
1821   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1822     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm")
1823             (const_int 63))
1824         (match_dup 1)))
1825    (clobber (match_scratch:SI 2 "=d"))]
1826   ""
1827   "*
1828 {
1829   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1830   if (REG_P (operands[1]) && REGNO (operands[1]) == REGNO (operands[0]))
1831     return
1832     \"move%.l %1,%2\;add%.l %2,%2\;subx%.l %2,%2\;sub%.l %2,%3\;subx%.l %2,%0\";
1833   if (GET_CODE (operands[1]) == REG)
1834     operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1835   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
1836         || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1837     operands[4] = operands[1];
1838   else
1839     operands[4] = adjust_address (operands[1], SImode, 4);
1840   if (GET_CODE (operands[1]) == MEM
1841    && GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1842     output_asm_insn (\"move%.l %4,%3\", operands);
1843   output_asm_insn (\"move%.l %1,%0\;smi %2\", operands);
1844   if (TARGET_68020 || TARGET_5200)
1845     output_asm_insn (\"extb%.l %2\", operands);
1846   else
1847     output_asm_insn (\"ext%.w %2\;ext%.l %2\", operands);
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   return \"sub%.l %2,%3\;subx%.l %2,%0\";
1852 }")
1853
1854 (define_insn "adddi_sexthishl32"
1855   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
1856     (plus:DI (ashift:DI (sign_extend:DI
1857           (match_operand:HI 1 "general_operand" "rm,rm,rm,rm"))
1858             (const_int 32))
1859         (match_operand:DI 2 "general_operand" "0,0,0,0")))
1860    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
1861   "!TARGET_5200"
1862   "*
1863 {
1864   CC_STATUS_INIT;
1865   if (ADDRESS_REG_P (operands[0]))
1866     return \"add%.w %1,%0\";
1867   else if (ADDRESS_REG_P (operands[3]))
1868     return \"move%.w %1,%3\;add%.l %3,%0\";
1869   else
1870     return \"move%.w %1,%3\;ext%.l %3\;add%.l %3,%0\";
1871 } ")
1872
1873 (define_insn "adddi_dilshr32"
1874   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o")
1875 ;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
1876 ;;      (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
1877 ;;            (const_int 32))))]
1878     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,d")
1879             (const_int 32))
1880         (match_operand:DI 2 "general_operand" "0,0")))]
1881   ""
1882   "*
1883 {
1884   CC_STATUS_INIT;
1885   if (GET_CODE (operands[0]) == REG)
1886     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1887   else
1888     operands[2] = adjust_address (operands[0], SImode, 4);
1889   return \"add%.l %1,%2\;negx%.l %0\;neg%.l %0\";
1890 } ")
1891
1892 (define_insn "adddi_dishl32"
1893   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
1894 ;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
1895 ;;      (ashift:DI (match_operand:DI 1 "general_operand" "ro")
1896 ;;            (const_int 32))))]
1897     (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro,d")
1898             (const_int 32))
1899         (match_operand:DI 2 "general_operand" "0,0")))]
1900   ""
1901   "*
1902 {
1903   CC_STATUS_INIT;
1904   if (GET_CODE (operands[1]) == REG)
1905     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1906   else
1907     operands[1] = adjust_address (operands[1], SImode, 4);
1908   return \"add%.l %1,%0\";
1909 } ")
1910
1911 (define_insn "adddi3"
1912   [(set (match_operand:DI 0 "nonimmediate_operand" "=<,o<>,d,d,d")
1913         (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0,0")
1914                  (match_operand:DI 2 "general_operand" "<,d,no>,d,a")))
1915    (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
1916   ""
1917   "*
1918 {
1919   if (DATA_REG_P (operands[0]))
1920     {
1921       if (DATA_REG_P (operands[2]))
1922         return \"add%.l %R2,%R0\;addx%.l %2,%0\";
1923       else if (GET_CODE (operands[2]) == MEM
1924           && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
1925         return \"move%.l %2,%3\;add%.l %2,%R0\;addx%.l %3,%0\";
1926       else
1927         {
1928           rtx high, low;
1929           rtx xoperands[2];
1930
1931           if (GET_CODE (operands[2]) == REG)
1932             {
1933               low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
1934               high = operands[2];
1935             }
1936           else if (CONSTANT_P (operands[2]))
1937             split_double (operands[2], &high, &low);
1938           else
1939             {
1940               low = adjust_address (operands[2], SImode, 4);
1941               high = operands[2];
1942             }
1943
1944           operands[1] = low, operands[2] = high;
1945           xoperands[0] = operands[3];
1946           if (GET_CODE (operands[1]) == CONST_INT
1947               && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
1948             xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
1949           else
1950             xoperands[1] = operands[2];
1951
1952           output_asm_insn (output_move_simode (xoperands), xoperands);
1953           if (GET_CODE (operands[1]) == CONST_INT)
1954             {
1955               if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
1956                 {
1957 #ifdef NO_ADDSUB_Q
1958                   return \"add%.l %1,%R0\;addx%.l %3,%0\";
1959 #else
1960                   return \"addq%.l %1,%R0\;addx%.l %3,%0\";
1961 #endif
1962                 }
1963               else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
1964                 {
1965                   operands[1] = GEN_INT (-INTVAL (operands[1]));
1966 #ifdef NO_ADDSUB_Q
1967                   return \"sub%.l %1,%R0\;subx%.l %3,%0\";
1968 #else
1969                   return \"subq%.l %1,%R0\;subx%.l %3,%0\";
1970 #endif
1971                 }
1972             }
1973           return \"add%.l %1,%R0\;addx%.l %3,%0\";
1974         }
1975     }
1976   else if (GET_CODE (operands[0]) == MEM)
1977     {
1978       if (GET_CODE (operands[2]) == MEM
1979           && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
1980         return \"add%.l %2,%0\;addx%.l %2,%0\";
1981       CC_STATUS_INIT;
1982       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1983         {
1984           operands[1] = gen_rtx_MEM (SImode,
1985                                      plus_constant (XEXP(operands[0], 0), -8));
1986           return \"move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1\";
1987         }
1988       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1989         {
1990           operands[1] = XEXP(operands[0], 0);
1991           return \"add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1\";
1992         }
1993       else
1994         {
1995           operands[1] = adjust_address (operands[0], SImode, 4);
1996           return \"add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\";
1997         }
1998     }
1999   else
2000     abort ();
2001 } ")
2002
2003 (define_insn "addsi_lshrsi_31"
2004   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
2005     (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm")
2006             (const_int 31))
2007         (match_dup 1)))]
2008   ""
2009   "*
2010 {
2011   operands[2] = operands[0];
2012   operands[3] = gen_label_rtx();
2013   if (GET_CODE (operands[0]) == MEM)
2014     {
2015       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2016         operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2017       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2018         operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2019     }
2020   output_asm_insn (\"move%.l %1,%0\", operands);
2021 #ifdef MOTOROLA
2022   output_asm_insn (\"jbpl %l3\", operands);
2023 #else
2024   output_asm_insn (\"jpl %l3\", operands);
2025 #endif
2026 #ifndef NO_ADDSUB_Q
2027   output_asm_insn (\"addq%.l %#1,%2\", operands);
2028 #else
2029   output_asm_insn (\"add%.l %#1,%2\", operands);
2030 #endif
2031   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2032                                 CODE_LABEL_NUMBER (operands[3]));
2033   return \"\";
2034 }")
2035
2036 (define_expand "addsi3"
2037   [(set (match_operand:SI 0 "nonimmediate_operand" "")
2038         (plus:SI (match_operand:SI 1 "general_operand" "")
2039                  (match_operand:SI 2 "general_src_operand" "")))]
2040   ""
2041   "")
2042
2043 ;; Note that the middle two alternatives are near-duplicates
2044 ;; in order to handle insns generated by reload.
2045 ;; This is needed since they are not themselves reloaded,
2046 ;; so commutativity won't apply to them.
2047 (define_insn "*addsi3_internal"
2048   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,d,a")
2049         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0")
2050                  (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))]
2051
2052
2053   "! TARGET_5200"
2054   "* return output_addsi3 (operands);")
2055
2056 (define_insn "*addsi3_5200"
2057   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,r")
2058         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
2059                  (match_operand:SI 2 "general_src_operand" "d,rJK,a,mrIKLs")))]
2060   "TARGET_5200"
2061   "* return output_addsi3 (operands);")
2062
2063 (define_insn ""
2064   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
2065         (plus:SI (match_operand:SI 1 "general_operand" "0")
2066                  (sign_extend:SI
2067                   (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2068   "!TARGET_5200"
2069   "add%.w %2,%0")
2070
2071 (define_insn "addhi3"
2072   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
2073         (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
2074                  (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2075   "!TARGET_5200"
2076   "*
2077 {
2078   if (GET_CODE (operands[2]) == CONST_INT)
2079     {
2080 #ifndef NO_ADDSUB_Q
2081       /* If the constant would be a negative number when interpreted as
2082          HImode, make it negative.  This is usually, but not always, done
2083          elsewhere in the compiler.  First check for constants out of range,
2084          which could confuse us.  */
2085
2086       if (INTVAL (operands[2]) >= 32768)
2087         operands[2] = GEN_INT (INTVAL (operands[2]) - 65536);
2088
2089       if (INTVAL (operands[2]) > 0
2090           && INTVAL (operands[2]) <= 8)
2091         return \"addq%.w %2,%0\";
2092       if (INTVAL (operands[2]) < 0
2093           && INTVAL (operands[2]) >= -8)
2094         {
2095           operands[2] = GEN_INT (- INTVAL (operands[2]));
2096           return \"subq%.w %2,%0\";
2097         }
2098       /* On the CPU32 it is faster to use two addqw instructions to
2099          add a small integer (8 < N <= 16) to a register.  
2100          Likewise for subqw.  */
2101       if (TARGET_CPU32 && REG_P (operands[0]))
2102         {
2103           if (INTVAL (operands[2]) > 8
2104               && INTVAL (operands[2]) <= 16)
2105             {
2106               operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2107               return \"addq%.w %#8,%0\;addq%.w %2,%0\";
2108             }
2109           if (INTVAL (operands[2]) < -8
2110               && INTVAL (operands[2]) >= -16)
2111             {
2112               operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2113               return \"subq%.w %#8,%0\;subq%.w %2,%0\";
2114             }
2115         }
2116 #endif
2117       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2118 #ifdef MOTOROLA  
2119             return \"lea (%c2,%0),%0\";
2120 #else
2121             return \"lea %0@(%c2),%0\";
2122 #endif
2123     }
2124   return \"add%.w %2,%0\";
2125 }")
2126
2127 ;; These insns must use MATCH_DUP instead of the more expected
2128 ;; use of a matching constraint because the "output" here is also
2129 ;; an input, so you can't use the matching constraint.  That also means
2130 ;; that you can't use the "%", so you need patterns with the matched
2131 ;; operand in both positions.
2132
2133 (define_insn ""
2134   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2135         (plus:HI (match_dup 0)
2136                  (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2137   "!TARGET_5200"
2138   "*
2139 {
2140   if (GET_CODE (operands[1]) == CONST_INT)
2141     {
2142 #ifndef NO_ADDSUB_Q
2143       /* If the constant would be a negative number when interpreted as
2144          HImode, make it negative.  This is usually, but not always, done
2145          elsewhere in the compiler.  First check for constants out of range,
2146          which could confuse us.  */
2147
2148       if (INTVAL (operands[1]) >= 32768)
2149         operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2150
2151       if (INTVAL (operands[1]) > 0
2152           && INTVAL (operands[1]) <= 8)
2153         return \"addq%.w %1,%0\";
2154       if (INTVAL (operands[1]) < 0
2155           && INTVAL (operands[1]) >= -8)
2156         {
2157           operands[1] = GEN_INT (- INTVAL (operands[1]));
2158           return \"subq%.w %1,%0\";
2159         }
2160       /* On the CPU32 it is faster to use two addqw instructions to
2161          add a small integer (8 < N <= 16) to a register. 
2162          Likewise for subqw.  */
2163       if (TARGET_CPU32 && REG_P (operands[0]))
2164         {
2165           if (INTVAL (operands[1]) > 8
2166               && INTVAL (operands[1]) <= 16)
2167             {
2168               operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2169               return \"addq%.w %#8,%0\;addq%.w %1,%0\";
2170             }
2171           if (INTVAL (operands[1]) < -8
2172               && INTVAL (operands[1]) >= -16)
2173             {
2174               operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
2175               return \"subq%.w %#8,%0\;subq%.w %1,%0\";
2176             }
2177         }
2178 #endif
2179       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2180 #ifdef MOTOROLA  
2181             return \"lea (%c1,%0),%0\";
2182 #else
2183             return \"lea %0@(%c1),%0\";
2184 #endif
2185     }
2186   return \"add%.w %1,%0\";
2187 }")
2188
2189 (define_insn ""
2190   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2191         (plus:HI (match_operand:HI 1 "general_src_operand" "dn,rmSn")
2192                  (match_dup 0)))]
2193   "!TARGET_5200"
2194   "*
2195 {
2196   if (GET_CODE (operands[1]) == CONST_INT)
2197     {
2198 #ifndef NO_ADDSUB_Q
2199       /* If the constant would be a negative number when interpreted as
2200          HImode, make it negative.  This is usually, but not always, done
2201          elsewhere in the compiler.  First check for constants out of range,
2202          which could confuse us.  */
2203
2204       if (INTVAL (operands[1]) >= 32768)
2205         operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2206
2207       if (INTVAL (operands[1]) > 0
2208           && INTVAL (operands[1]) <= 8)
2209         return \"addq%.w %1,%0\";
2210       if (INTVAL (operands[1]) < 0
2211           && INTVAL (operands[1]) >= -8)
2212         {
2213           operands[1] = GEN_INT (- INTVAL (operands[1]));
2214           return \"subq%.w %1,%0\";
2215         }
2216       /* On the CPU32 it is faster to use two addqw instructions to
2217          add a small integer (8 < N <= 16) to a register.
2218          Likewise for subqw.  */
2219       if (TARGET_CPU32 && REG_P (operands[0])) 
2220         {
2221           if (INTVAL (operands[1]) > 8
2222               && INTVAL (operands[1]) <= 16)
2223             {
2224               operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2225               return \"addq%.w %#8,%0\;addq%.w %1,%0\";
2226             }
2227           if (INTVAL (operands[1]) < -8
2228               && INTVAL (operands[1]) >= -16)
2229             {
2230               operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
2231               return \"subq%.w %#8,%0\;subq%.w %1,%0\";
2232             }
2233         }
2234 #endif
2235       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2236 #ifdef MOTOROLA  
2237             return \"lea (%c1,%0),%0\";
2238 #else
2239             return \"lea %0@(%c1),%0\";
2240 #endif
2241     }
2242   return \"add%.w %1,%0\";
2243 }")
2244
2245 (define_insn "addqi3"
2246   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
2247         (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
2248                  (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2249   "!TARGET_5200"
2250   "*
2251 {
2252 #ifndef NO_ADDSUB_Q
2253   if (GET_CODE (operands[2]) == CONST_INT)
2254     {
2255       if (INTVAL (operands[2]) >= 128)
2256         operands[2] = GEN_INT (INTVAL (operands[2]) - 256);
2257
2258       if (INTVAL (operands[2]) > 0
2259           && INTVAL (operands[2]) <= 8)
2260         return \"addq%.b %2,%0\";
2261       if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
2262        {
2263          operands[2] = GEN_INT (- INTVAL (operands[2]));
2264          return \"subq%.b %2,%0\";
2265        }
2266     }
2267 #endif
2268   return \"add%.b %2,%0\";
2269 }")
2270
2271 (define_insn ""
2272   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2273         (plus:QI (match_dup 0)
2274                  (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2275   "!TARGET_5200"
2276   "*
2277 {
2278 #ifndef NO_ADDSUB_Q
2279   if (GET_CODE (operands[1]) == CONST_INT)
2280     {
2281       if (INTVAL (operands[1]) >= 128)
2282         operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2283
2284       if (INTVAL (operands[1]) > 0
2285           && INTVAL (operands[1]) <= 8)
2286         return \"addq%.b %1,%0\";
2287       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2288        {
2289          operands[1] = GEN_INT (- INTVAL (operands[1]));
2290          return \"subq%.b %1,%0\";
2291        }
2292     }
2293 #endif
2294   return \"add%.b %1,%0\";
2295 }")
2296
2297 (define_insn ""
2298   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2299         (plus:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
2300                  (match_dup 0)))]
2301   "!TARGET_5200"
2302   "*
2303 {
2304 #ifndef NO_ADDSUB_Q
2305   if (GET_CODE (operands[1]) == CONST_INT)
2306     {
2307       if (INTVAL (operands[1]) >= 128)
2308         operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2309
2310       if (INTVAL (operands[1]) > 0
2311           && INTVAL (operands[1]) <= 8)
2312         return \"addq%.b %1,%0\";
2313       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2314        {
2315          operands[1] = GEN_INT (- INTVAL (operands[1]));
2316          return \"subq%.b %1,%0\";
2317        }
2318     }
2319 #endif
2320   return \"add%.b %1,%0\";
2321 }")
2322
2323 (define_expand "adddf3"
2324   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2325         (plus:DF (match_operand:DF 1 "general_operand" "")
2326                  (match_operand:DF 2 "general_operand" "")))]
2327   "TARGET_68881"
2328   "")
2329
2330 (define_insn ""
2331   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2332         (plus:DF (float:DF (match_operand:SI 2 "general_operand" "dmi"))
2333                  (match_operand:DF 1 "general_operand" "0")))]
2334   "TARGET_68881"
2335   "f%&add%.l %2,%0")
2336
2337 (define_insn ""
2338   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2339         (plus:DF (float:DF (match_operand:HI 2 "general_operand" "dmn"))
2340                  (match_operand:DF 1 "general_operand" "0")))]
2341   "TARGET_68881"
2342   "f%&add%.w %2,%0")
2343
2344 (define_insn ""
2345   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2346         (plus:DF (float:DF (match_operand:QI 2 "general_operand" "dmn"))
2347                  (match_operand:DF 1 "general_operand" "0")))]
2348   "TARGET_68881"
2349   "f%&add%.b %2,%0")
2350
2351 (define_insn ""
2352   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2353         (plus:DF (match_operand:DF 1 "general_operand" "%0")
2354                  (match_operand:DF 2 "general_operand" "fmG")))]
2355   "TARGET_68881"
2356   "*
2357 {
2358   if (REG_P (operands[2]))
2359     return \"f%&add%.x %2,%0\";
2360   return \"f%&add%.d %f2,%0\";
2361 }")
2362
2363 (define_expand "addsf3"
2364   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2365         (plus:SF (match_operand:SF 1 "general_operand" "")
2366                  (match_operand:SF 2 "general_operand" "")))]
2367   "TARGET_68881"
2368   "")
2369
2370 (define_insn ""
2371   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2372         (plus:SF (float:SF (match_operand:SI 2 "general_operand" "dmi"))
2373                  (match_operand:SF 1 "general_operand" "0")))]
2374   "TARGET_68881"
2375   "f%$add%.l %2,%0")
2376
2377 (define_insn ""
2378   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2379         (plus:SF (float:SF (match_operand:HI 2 "general_operand" "dmn"))
2380                  (match_operand:SF 1 "general_operand" "0")))]
2381   "TARGET_68881"
2382   "f%$add%.w %2,%0")
2383
2384 (define_insn ""
2385   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2386         (plus:SF (float:SF (match_operand:QI 2 "general_operand" "dmn"))
2387                  (match_operand:SF 1 "general_operand" "0")))]
2388   "TARGET_68881"
2389   "f%$add%.b %2,%0")
2390
2391 (define_insn ""
2392   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2393         (plus:SF (match_operand:SF 1 "general_operand" "%0")
2394                  (match_operand:SF 2 "general_operand" "fdmF")))]
2395   "TARGET_68881"
2396   "*
2397 {
2398   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2399     return \"f%$add%.x %2,%0\";
2400   return \"f%$add%.s %f2,%0\";
2401 }")
2402 \f
2403 ;; subtract instructions
2404
2405 (define_insn "subdi_sexthishl32"
2406   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
2407     (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
2408         (ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm"))
2409             (const_int 32))))
2410    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
2411   "!TARGET_5200"
2412   "*
2413 {
2414   CC_STATUS_INIT;
2415   if (ADDRESS_REG_P (operands[0]))
2416     return \"sub%.w %2,%0\";
2417   else if (ADDRESS_REG_P (operands[3]))
2418     return \"move%.w %2,%3\;sub%.l %3,%0\";
2419   else
2420     return \"move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0\";
2421 } ")
2422
2423 (define_insn "subdi_dishl32"
2424   [(set (match_operand:DI 0 "nonimmediate_operand" "+ro")
2425     (minus:DI (match_dup 0)
2426         (ashift:DI (match_operand:DI 1 "general_operand" "ro")
2427             (const_int 32))))]
2428   ""
2429   "*
2430 {
2431   CC_STATUS_INIT;
2432   if (GET_CODE (operands[1]) == REG)
2433     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2434   else
2435     operands[1] = adjust_address (operands[1], SImode, 4);
2436   return \"sub%.l %1,%0\";
2437 } ")
2438
2439 (define_insn "subdi3"
2440   [(set (match_operand:DI 0 "nonimmediate_operand" "=<,o<>,d,d,d")
2441         (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0,0")
2442                  (match_operand:DI 2 "general_operand" "<,d,no>,d,a")))
2443    (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
2444   ""
2445   "*
2446 {
2447   if (DATA_REG_P (operands[0]))
2448     {
2449       if (DATA_REG_P (operands[2]))
2450         return \"sub%.l %R2,%R0\;subx%.l %2,%0\";
2451       else if (GET_CODE (operands[2]) == MEM
2452           && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
2453         {
2454           return \"move%.l %2,%3\;sub%.l %2,%R0\;subx%.l %3,%0\";
2455         }
2456       else
2457         {
2458           rtx high, low;
2459           rtx xoperands[2];
2460
2461           if (GET_CODE (operands[2]) == REG)
2462             {
2463               low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2464               high = operands[2];
2465             }
2466           else if (CONSTANT_P (operands[2]))
2467             split_double (operands[2], &high, &low);
2468           else
2469             {
2470               low = adjust_address (operands[2], SImode, 4);
2471               high = operands[2];
2472             }
2473
2474           operands[1] = low, operands[2] = high;
2475           xoperands[0] = operands[3];
2476           if (GET_CODE (operands[1]) == CONST_INT
2477               && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2478             xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
2479           else
2480             xoperands[1] = operands[2];
2481
2482           output_asm_insn (output_move_simode (xoperands), xoperands);
2483           if (GET_CODE (operands[1]) == CONST_INT)
2484             {
2485               if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
2486                 {
2487 #ifdef NO_ADDSUB_Q
2488                   return \"sub%.l %1,%R0\;subx%.l %3,%0\";
2489 #else
2490                   return \"subq%.l %1,%R0\;subx%.l %3,%0\";
2491 #endif
2492                 }
2493               else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2494                 {
2495                   operands[1] = GEN_INT (-INTVAL (operands[1]));
2496 #ifdef NO_ADDSUB_Q
2497                   return \"add%.l %1,%R0\;addx%.l %3,%0\";
2498 #else
2499                   return \"addq%.l %1,%R0\;addx%.l %3,%0\";
2500 #endif
2501                 }
2502             }
2503           return \"sub%.l %1,%R0\;subx%.l %3,%0\";
2504         }
2505     }
2506   else if (GET_CODE (operands[0]) == MEM)
2507     {
2508       if (GET_CODE (operands[2]) == MEM
2509           && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
2510         return \"sub%.l %2,%0\;subx%.l %2,%0\";
2511       CC_STATUS_INIT;
2512       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2513         {
2514           operands[1]
2515             = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[0], 0), -8));
2516           return \"move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1\";
2517         }
2518       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2519         {
2520           operands[1] = XEXP(operands[0], 0);
2521           return \"sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1\";
2522         }
2523       else
2524         {
2525           operands[1] = adjust_address (operands[0], SImode, 4);
2526           return \"sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\";
2527         }
2528     }
2529   else
2530     abort ();
2531 } ")
2532
2533 (define_insn "subsi3"
2534   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d,a")
2535         (minus:SI (match_operand:SI 1 "general_operand" "0,0,0")
2536                   (match_operand:SI 2 "general_src_operand" "dT,mSrT,mSrs")))]
2537   ""
2538   "sub%.l %2,%0")
2539
2540 (define_insn ""
2541   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
2542         (minus:SI (match_operand:SI 1 "general_operand" "0")
2543                   (sign_extend:SI
2544                    (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2545   "!TARGET_5200"
2546   "sub%.w %2,%0")
2547
2548 (define_insn "subhi3"
2549   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
2550         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2551                   (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2552   "!TARGET_5200"
2553   "sub%.w %2,%0")
2554
2555 (define_insn ""
2556   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2557         (minus:HI (match_dup 0)
2558                   (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2559   "!TARGET_5200"
2560   "sub%.w %1,%0")
2561
2562 (define_insn "subqi3"
2563   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
2564         (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2565                   (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2566   "!TARGET_5200"
2567   "sub%.b %2,%0")
2568
2569 (define_insn ""
2570   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2571         (minus:QI (match_dup 0)
2572                   (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2573   "!TARGET_5200"
2574   "sub%.b %1,%0")
2575
2576 (define_expand "subdf3"
2577   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2578         (minus:DF (match_operand:DF 1 "general_operand" "")
2579                   (match_operand:DF 2 "general_operand" "")))]
2580   "TARGET_68881"
2581   "")
2582
2583 (define_insn ""
2584   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2585         (minus:DF (match_operand:DF 1 "general_operand" "0")
2586                   (float:DF (match_operand:SI 2 "general_operand" "dmi"))))]
2587   "TARGET_68881"
2588   "f%&sub%.l %2,%0")
2589
2590 (define_insn ""
2591   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2592         (minus:DF (match_operand:DF 1 "general_operand" "0")
2593                   (float:DF (match_operand:HI 2 "general_operand" "dmn"))))]
2594   "TARGET_68881"
2595   "f%&sub%.w %2,%0")
2596
2597 (define_insn ""
2598   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2599         (minus:DF (match_operand:DF 1 "general_operand" "0")
2600                   (float:DF (match_operand:QI 2 "general_operand" "dmn"))))]
2601   "TARGET_68881"
2602   "f%&sub%.b %2,%0")
2603
2604 (define_insn ""
2605   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2606         (minus:DF (match_operand:DF 1 "general_operand" "0")
2607                   (match_operand:DF 2 "general_operand" "fmG")))]
2608   "TARGET_68881"
2609   "*
2610 {
2611   if (REG_P (operands[2]))
2612     return \"f%&sub%.x %2,%0\";
2613   return \"f%&sub%.d %f2,%0\";
2614 }")
2615
2616 (define_expand "subsf3"
2617   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2618         (minus:SF (match_operand:SF 1 "general_operand" "")
2619                   (match_operand:SF 2 "general_operand" "")))]
2620   "TARGET_68881"
2621   "")
2622
2623 (define_insn ""
2624   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2625         (minus:SF (match_operand:SF 1 "general_operand" "0")
2626                   (float:SF (match_operand:SI 2 "general_operand" "dmi"))))]
2627   "TARGET_68881"
2628   "f%$sub%.l %2,%0")
2629
2630 (define_insn ""
2631   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2632         (minus:SF (match_operand:SF 1 "general_operand" "0")
2633                   (float:SF (match_operand:HI 2 "general_operand" "dmn"))))]
2634   "TARGET_68881"
2635   "f%$sub%.w %2,%0")
2636
2637 (define_insn ""
2638   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2639         (minus:SF (match_operand:SF 1 "general_operand" "0")
2640                   (float:SF (match_operand:QI 2 "general_operand" "dmn"))))]
2641   "TARGET_68881"
2642   "f%$sub%.b %2,%0")
2643
2644 (define_insn ""
2645   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2646         (minus:SF (match_operand:SF 1 "general_operand" "0")
2647                   (match_operand:SF 2 "general_operand" "fdmF")))]
2648   "TARGET_68881"
2649   "*
2650 {
2651   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2652     return \"f%$sub%.x %2,%0\";
2653   return \"f%$sub%.s %f2,%0\";
2654 }")
2655 \f
2656 ;; multiply instructions
2657
2658 (define_insn "mulhi3"
2659   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
2660         (mult:HI (match_operand:HI 1 "general_operand" "%0")
2661                  (match_operand:HI 2 "general_src_operand" "dmSn")))]
2662   ""
2663   "*
2664 {
2665 #if defined(MOTOROLA)
2666   return \"muls%.w %2,%0\";
2667 #else
2668   return \"muls %2,%0\";
2669 #endif
2670 }")
2671
2672 (define_insn "mulhisi3"
2673   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2674         (mult:SI (sign_extend:SI
2675                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2676                  (sign_extend:SI
2677                   (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
2678   ""
2679   "*
2680 {
2681 #if defined(MOTOROLA)
2682   return \"muls%.w %2,%0\";
2683 #else
2684   return \"muls %2,%0\";
2685 #endif
2686 }")
2687
2688 (define_insn ""
2689   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2690         (mult:SI (sign_extend:SI
2691                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2692                  (match_operand:SI 2 "const_int_operand" "n")))]
2693   "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
2694   "*
2695 {
2696 #if defined(MOTOROLA)
2697   return \"muls%.w %2,%0\";
2698 #else
2699   return \"muls %2,%0\";
2700 #endif
2701 }")
2702
2703 (define_expand "mulsi3"
2704   [(set (match_operand:SI 0 "nonimmediate_operand" "")
2705         (mult:SI (match_operand:SI 1 "general_operand" "")
2706                  (match_operand:SI 2 "general_operand" "")))]
2707   "TARGET_68020 || TARGET_5200"
2708   "")
2709
2710 (define_insn ""
2711   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2712         (mult:SI (match_operand:SI 1 "general_operand" "%0")
2713                  (match_operand:SI 2 "general_src_operand" "dmSTK")))]
2714
2715   "TARGET_68020"
2716   "muls%.l %2,%0")
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_operand" "d<Q>")))]
2722   "TARGET_5200"
2723   "muls%.l %2,%0")
2724
2725 (define_insn "umulhisi3"
2726   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2727         (mult:SI (zero_extend:SI
2728                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2729                  (zero_extend:SI
2730                   (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
2731   ""
2732   "*
2733 {
2734 #if defined(MOTOROLA)
2735   return \"mulu%.w %2,%0\";
2736 #else
2737   return \"mulu %2,%0\";
2738 #endif
2739 }")
2740
2741 (define_insn ""
2742   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
2743         (mult:SI (zero_extend:SI
2744                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2745                  (match_operand:SI 2 "const_int_operand" "n")))]
2746   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
2747   "*
2748 {
2749 #if defined(MOTOROLA)
2750   return \"mulu%.w %2,%0\";
2751 #else
2752   return \"mulu %2,%0\";
2753 #endif
2754 }")
2755
2756 ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
2757 ;; proper matching constraint.  This is because the matching is between
2758 ;; the high-numbered word of the DImode operand[0] and operand[1].
2759 (define_expand "umulsidi3"
2760   [(parallel
2761     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
2762           (mult:SI (match_operand:SI 1 "register_operand" "")
2763                    (match_operand:SI 2 "register_operand" "")))
2764      (set (subreg:SI (match_dup 0) 0)
2765           (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2766                                              (zero_extend:DI (match_dup 2)))
2767                                     (const_int 32))))])]
2768   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2769   "")
2770
2771 (define_insn ""
2772   [(set (match_operand:SI 0 "register_operand" "=d")
2773         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2774                   (match_operand:SI 2 "nonimmediate_operand" "dm")))
2775    (set (match_operand:SI 3 "register_operand" "=d")
2776         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2777                                            (zero_extend:DI (match_dup 2)))
2778                                   (const_int 32))))]
2779   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2780   "mulu%.l %2,%3:%0")
2781
2782 ; Match immediate case.  For 2.4 only match things < 2^31.
2783 ; It's tricky with larger values in these patterns since we need to match
2784 ; values between the two parallel multiplies, between a CONST_DOUBLE and
2785 ; a CONST_INT.
2786 (define_insn ""
2787   [(set (match_operand:SI 0 "register_operand" "=d")
2788         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2789                  (match_operand:SI 2 "const_int_operand" "n")))
2790    (set (match_operand:SI 3 "register_operand" "=d")
2791         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2792                                            (match_dup 2))
2793                                   (const_int 32))))]
2794   "TARGET_68020 && !TARGET_68060 && !TARGET_5200
2795    && (unsigned) INTVAL (operands[2]) <= 0x7fffffff"
2796   "mulu%.l %2,%3:%0")
2797
2798 (define_expand "mulsidi3"
2799   [(parallel
2800     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
2801           (mult:SI (match_operand:SI 1 "register_operand" "")
2802                    (match_operand:SI 2 "register_operand" "")))
2803      (set (subreg:SI (match_dup 0) 0)
2804           (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2805                                              (sign_extend:DI (match_dup 2)))
2806                                     (const_int 32))))])]
2807   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2808   "")
2809
2810 (define_insn ""
2811   [(set (match_operand:SI 0 "register_operand" "=d")
2812         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2813                  (match_operand:SI 2 "nonimmediate_operand" "dm")))
2814    (set (match_operand:SI 3 "register_operand" "=d")
2815         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2816                                            (sign_extend:DI (match_dup 2)))
2817                                   (const_int 32))))]
2818   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2819   "muls%.l %2,%3:%0")
2820
2821 (define_insn ""
2822   [(set (match_operand:SI 0 "register_operand" "=d")
2823         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2824                  (match_operand:SI 2 "const_int_operand" "n")))
2825    (set (match_operand:SI 3 "register_operand" "=d")
2826         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2827                                            (match_dup 2))
2828                                   (const_int 32))))]
2829   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2830   "muls%.l %2,%3:%0")
2831
2832 (define_expand "umulsi3_highpart"
2833   [(parallel
2834     [(set (match_operand:SI 0 "register_operand" "")
2835           (truncate:SI
2836            (lshiftrt:DI
2837             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2838                      (zero_extend:DI (match_operand:SI 2 "general_operand" "")))
2839             (const_int 32))))
2840      (clobber (match_dup 3))])]
2841   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2842   "
2843 {
2844   operands[3] = gen_reg_rtx (SImode);
2845
2846   if (GET_CODE (operands[2]) == CONST_INT)
2847     {
2848       operands[2] = immed_double_const (INTVAL (operands[2]) & 0xffffffff,
2849                                         0, DImode);
2850
2851       /* We have to adjust the operand order for the matching constraints.  */
2852       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[3],
2853                                              operands[1], operands[2]));
2854       DONE;
2855     }
2856 }")
2857
2858 (define_insn ""
2859   [(set (match_operand:SI 0 "register_operand" "=d")
2860         (truncate:SI
2861          (lshiftrt:DI
2862           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "%1"))
2863                    (zero_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
2864           (const_int 32))))
2865    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2866   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2867   "mulu%.l %3,%0:%1")
2868
2869 (define_insn "const_umulsi3_highpart"
2870   [(set (match_operand:SI 0 "register_operand" "=d")
2871         (truncate:SI
2872          (lshiftrt:DI
2873           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "1"))
2874                    (match_operand:DI 3 "const_uint32_operand" "n"))
2875           (const_int 32))))
2876    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2877   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2878   "mulu%.l %3,%0:%1")
2879
2880 (define_expand "smulsi3_highpart"
2881   [(parallel
2882     [(set (match_operand:SI 0 "register_operand" "")
2883           (truncate:SI
2884            (lshiftrt:DI
2885             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2886                      (sign_extend:DI (match_operand:SI 2 "general_operand" "")))
2887             (const_int 32))))
2888      (clobber (match_dup 3))])]
2889   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2890   "
2891 {
2892   operands[3] = gen_reg_rtx (SImode);
2893   if (GET_CODE (operands[2]) == CONST_INT)
2894     {
2895       /* We have to adjust the operand order for the matching constraints.  */
2896       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[3],
2897                                              operands[1], operands[2]));
2898       DONE;
2899     }
2900 }")
2901
2902 (define_insn ""
2903   [(set (match_operand:SI 0 "register_operand" "=d")
2904         (truncate:SI
2905          (lshiftrt:DI
2906           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "%1"))
2907                    (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
2908           (const_int 32))))
2909    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2910   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2911   "muls%.l %3,%0:%1")
2912
2913 (define_insn "const_smulsi3_highpart"
2914   [(set (match_operand:SI 0 "register_operand" "=d")
2915         (truncate:SI
2916          (lshiftrt:DI
2917           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1"))
2918                    (match_operand:DI 3 "const_sint32_operand" "n"))
2919           (const_int 32))))
2920    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2921   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
2922   "muls%.l %3,%0:%1")
2923
2924 (define_expand "muldf3"
2925   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2926         (mult:DF (match_operand:DF 1 "general_operand" "")
2927                  (match_operand:DF 2 "general_operand" "")))]
2928   "TARGET_68881"
2929   "")
2930
2931 (define_insn ""
2932   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2933         (mult:DF (float:DF (match_operand:SI 2 "general_operand" "dmi"))
2934                  (match_operand:DF 1 "general_operand" "0")))]
2935   "TARGET_68881"
2936   "f%&mul%.l %2,%0")
2937
2938 (define_insn ""
2939   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2940         (mult:DF (float:DF (match_operand:HI 2 "general_operand" "dmn"))
2941                  (match_operand:DF 1 "general_operand" "0")))]
2942   "TARGET_68881"
2943   "f%&mul%.w %2,%0")
2944
2945 (define_insn ""
2946   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2947         (mult:DF (float:DF (match_operand:QI 2 "general_operand" "dmn"))
2948                  (match_operand:DF 1 "general_operand" "0")))]
2949   "TARGET_68881"
2950   "f%&mul%.b %2,%0")
2951
2952 (define_insn ""
2953   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
2954         (mult:DF (match_operand:DF 1 "general_operand" "%0")
2955                  (match_operand:DF 2 "general_operand" "fmG")))]
2956   "TARGET_68881"
2957   "*
2958 {
2959   if (GET_CODE (operands[2]) == CONST_DOUBLE
2960       && floating_exact_log2 (operands[2]) && !TARGET_68040 && !TARGET_68060)
2961     {
2962       int i = floating_exact_log2 (operands[2]);
2963       operands[2] = GEN_INT (i);
2964       return \"fscale%.l %2,%0\";
2965     }
2966   if (REG_P (operands[2]))
2967     return \"f%&mul%.x %2,%0\";
2968   return \"f%&mul%.d %f2,%0\";
2969 }")
2970
2971 (define_expand "mulsf3"
2972   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2973         (mult:SF (match_operand:SF 1 "general_operand" "")
2974                  (match_operand:SF 2 "general_operand" "")))]
2975   "TARGET_68881"
2976   "")
2977
2978 (define_insn ""
2979   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2980         (mult:SF (float:SF (match_operand:SI 2 "general_operand" "dmi"))
2981                  (match_operand:SF 1 "general_operand" "0")))]
2982   "TARGET_68881"
2983   "*
2984 {
2985   return (TARGET_68040_ONLY
2986           ? \"fsmul%.l %2,%0\"
2987           : \"fsglmul%.l %2,%0\");
2988 }")
2989
2990 (define_insn ""
2991   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2992         (mult:SF (float:SF (match_operand:HI 2 "general_operand" "dmn"))
2993                  (match_operand:SF 1 "general_operand" "0")))]
2994   "TARGET_68881"
2995   "*
2996 {
2997   return (TARGET_68040_ONLY
2998           ? \"fsmul%.w %2,%0\"
2999           : \"fsglmul%.w %2,%0\");
3000 }")
3001
3002 (define_insn ""
3003   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3004         (mult:SF (float:SF (match_operand:QI 2 "general_operand" "dmn"))
3005                  (match_operand:SF 1 "general_operand" "0")))]
3006   "TARGET_68881"
3007   "*
3008 {
3009   return (TARGET_68040_ONLY
3010           ? \"fsmul%.b %2,%0\"
3011           : \"fsglmul%.b %2,%0\");
3012 }")
3013
3014 (define_insn ""
3015   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3016         (mult:SF (match_operand:SF 1 "general_operand" "%0")
3017                  (match_operand:SF 2 "general_operand" "fdmF")))]
3018   "TARGET_68881"
3019   "*
3020 {
3021 #ifdef FSGLMUL_USE_S
3022   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3023     return (TARGET_68040_ONLY
3024             ? \"fsmul%.s %2,%0\"
3025             : \"fsglmul%.s %2,%0\");
3026 #else
3027   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3028     return (TARGET_68040_ONLY
3029             ? \"fsmul%.x %2,%0\"
3030             : \"fsglmul%.x %2,%0\");
3031 #endif
3032   return (TARGET_68040_ONLY
3033           ? \"fsmul%.s %f2,%0\"
3034           : \"fsglmul%.s %f2,%0\");
3035 }")
3036 \f
3037 ;; divide instructions
3038
3039 (define_expand "divdf3"
3040   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3041         (div:DF (match_operand:DF 1 "general_operand" "")
3042                 (match_operand:DF 2 "general_operand" "")))]
3043   "TARGET_68881"
3044   "")
3045
3046 (define_insn ""
3047   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3048         (div:DF (match_operand:DF 1 "general_operand" "0")
3049                 (float:DF (match_operand:SI 2 "general_operand" "dmi"))))]
3050   "TARGET_68881"
3051   "f%&div%.l %2,%0")
3052
3053 (define_insn ""
3054   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3055         (div:DF (match_operand:DF 1 "general_operand" "0")
3056                 (float:DF (match_operand:HI 2 "general_operand" "dmn"))))]
3057   "TARGET_68881"
3058   "f%&div%.w %2,%0")
3059
3060 (define_insn ""
3061   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3062         (div:DF (match_operand:DF 1 "general_operand" "0")
3063                 (float:DF (match_operand:QI 2 "general_operand" "dmn"))))]
3064   "TARGET_68881"
3065   "f%&div%.b %2,%0")
3066
3067 (define_insn ""
3068   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3069         (div:DF (match_operand:DF 1 "general_operand" "0")
3070                 (match_operand:DF 2 "general_operand" "fmG")))]
3071   "TARGET_68881"
3072   "*
3073 {
3074   if (REG_P (operands[2]))
3075     return \"f%&div%.x %2,%0\";
3076   return \"f%&div%.d %f2,%0\";
3077 }")
3078
3079 (define_expand "divsf3"
3080   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3081         (div:SF (match_operand:SF 1 "general_operand" "")
3082                 (match_operand:SF 2 "general_operand" "")))]
3083   "TARGET_68881"
3084   "")
3085
3086 (define_insn ""
3087   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3088         (div:SF (match_operand:SF 1 "general_operand" "0")
3089                 (float:SF (match_operand:SI 2 "general_operand" "dmi"))))]
3090   "TARGET_68881"
3091   "*
3092 {
3093   return (TARGET_68040_ONLY
3094           ? \"fsdiv%.l %2,%0\"
3095           : \"fsgldiv%.l %2,%0\");
3096 }")
3097
3098 (define_insn ""
3099   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3100         (div:SF (match_operand:SF 1 "general_operand" "0")
3101                 (float:SF (match_operand:HI 2 "general_operand" "dmn"))))]
3102   "TARGET_68881"
3103   "*
3104 {
3105   return (TARGET_68040_ONLY
3106           ? \"fsdiv%.w %2,%0\"
3107           : \"fsgldiv%.w %2,%0\");
3108 }")
3109
3110 (define_insn ""
3111   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3112         (div:SF (match_operand:SF 1 "general_operand" "0")
3113                 (float:SF (match_operand:QI 2 "general_operand" "dmn"))))]
3114   "TARGET_68881"
3115   "*
3116 {
3117   return (TARGET_68040_ONLY
3118           ? \"fsdiv%.b %2,%0\"
3119           : \"fsgldiv%.b %2,%0\");
3120 }")
3121
3122 (define_insn ""
3123   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3124         (div:SF (match_operand:SF 1 "general_operand" "0")
3125                 (match_operand:SF 2 "general_operand" "fdmF")))]
3126   "TARGET_68881"
3127   "*
3128 {
3129 #ifdef FSGLDIV_USE_S
3130   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3131     return (TARGET_68040_ONLY
3132             ? \"fsdiv%.s %2,%0\"
3133             : \"fsgldiv%.s %2,%0\");
3134 #else
3135   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3136     return (TARGET_68040_ONLY
3137             ? \"fsdiv%.x %2,%0\"
3138             : \"fsgldiv%.x %2,%0\");
3139 #endif
3140   return (TARGET_68040_ONLY
3141           ? \"fsdiv%.s %f2,%0\"
3142           : \"fsgldiv%.s %f2,%0\");
3143 }")
3144 \f
3145 ;; Remainder instructions.
3146
3147 (define_insn "divmodsi4"
3148   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3149         (div:SI (match_operand:SI 1 "general_operand" "0")
3150                 (match_operand:SI 2 "general_src_operand" "dmSTK")))
3151    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3152         (mod:SI (match_dup 1) (match_dup 2)))]
3153   "TARGET_68020 && !TARGET_5200"
3154   "*
3155 {
3156   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3157     return \"divs%.l %2,%0\";
3158   else
3159     return \"divsl%.l %2,%3:%0\";
3160 }")
3161
3162 (define_insn "udivmodsi4"
3163   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3164         (udiv:SI (match_operand:SI 1 "general_operand" "0")
3165                  (match_operand:SI 2 "general_src_operand" "dmSTK")))
3166    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3167         (umod:SI (match_dup 1) (match_dup 2)))]
3168   "TARGET_68020 && !TARGET_5200"
3169   "*
3170 {
3171   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3172     return \"divu%.l %2,%0\";
3173   else
3174     return \"divul%.l %2,%3:%0\";
3175 }")
3176
3177 (define_insn "divmodhi4"
3178   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3179         (div:HI (match_operand:HI 1 "general_operand" "0")
3180                 (match_operand:HI 2 "general_src_operand" "dmSKT")))
3181    (set (match_operand:HI 3 "nonimmediate_operand" "=d")
3182         (mod:HI (match_dup 1) (match_dup 2)))]
3183   "!TARGET_5200"
3184   "*
3185 {
3186 #ifdef MOTOROLA
3187   output_asm_insn (\"ext%.l %0\;divs%.w %2,%0\", operands);
3188 #else
3189   output_asm_insn (\"extl %0\;divs %2,%0\", operands);
3190 #endif
3191   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3192     {
3193       CC_STATUS_INIT;
3194       return \"move%.l %0,%3\;swap %3\";
3195     }
3196   else
3197     return \"\";
3198 }")
3199
3200 (define_insn "udivmodhi4"
3201   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3202         (udiv:HI (match_operand:HI 1 "general_operand" "0")
3203                  (match_operand:HI 2 "general_src_operand" "dmSKT")))
3204    (set (match_operand:HI 3 "nonimmediate_operand" "=d")
3205         (umod:HI (match_dup 1) (match_dup 2)))]
3206   "!TARGET_5200"
3207   "*
3208 {
3209 #ifdef MOTOROLA
3210   output_asm_insn (\"and%.l %#0xFFFF,%0\;divu%.w %2,%0\", operands);
3211 #else
3212   output_asm_insn (\"and%.l %#0xFFFF,%0\;divu %2,%0\", operands);
3213 #endif
3214   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3215     {
3216       CC_STATUS_INIT;
3217       return \"move%.l %0,%3\;swap %3\";
3218     }
3219   else
3220     return \"\";
3221 }")
3222 \f
3223 ;; logical-and instructions
3224
3225 ;; "anddi3" is mainly here to help combine().
3226 (define_insn "anddi3"
3227   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3228         (and:DI (match_operand:DI 1 "general_operand" "%0,0")
3229                 (match_operand:DI 2 "general_operand" "dn,don")))]
3230   "!TARGET_5200"
3231   "*
3232 {
3233   CC_STATUS_INIT;
3234   /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3235   if (CONSTANT_P (operands[2]))
3236     {
3237       rtx hi, lo;
3238
3239       split_double (operands[2], &hi, &lo);
3240
3241       switch (INTVAL (hi))
3242         {
3243           case 0 :
3244             output_asm_insn (\"clr%.l %0\", operands);
3245             break;
3246           case -1 :
3247             break;
3248           default :
3249             {
3250             rtx xoperands[3];
3251
3252             xoperands[0] = operands[0];
3253             xoperands[2] = hi;
3254             output_asm_insn (output_andsi3 (xoperands), xoperands);
3255             }
3256         }
3257       if (GET_CODE (operands[0]) == REG)
3258         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3259       else
3260         operands[0] = adjust_address (operands[0], SImode, 4);
3261       switch (INTVAL (lo))
3262         {
3263           case 0 :
3264             output_asm_insn (\"clr%.l %0\", operands);
3265             break;
3266           case -1 :
3267             break;
3268           default :
3269             {
3270             rtx xoperands[3];
3271
3272             xoperands[0] = operands[0];
3273             xoperands[2] = lo;
3274             output_asm_insn (output_andsi3 (xoperands), xoperands);
3275             }
3276         }
3277       return \"\";
3278     }
3279   if (GET_CODE (operands[0]) != REG)
3280     {
3281       operands[1] = adjust_address (operands[0], SImode, 4);
3282       return \"and%.l %2,%0\;and%.l %R2,%1\";
3283     }
3284   if (GET_CODE (operands[2]) != REG)
3285     {
3286       operands[1] = adjust_address (operands[2], SImode, 4);
3287       return \"and%.l %2,%0\;and%.l %1,%R0\";
3288     }
3289   return \"and%.l %2,%0\;and%.l %R2,%R0\";
3290 }")
3291
3292 ;; Prevent AND from being made with sp.  This doesn't exist in the machine
3293 ;; and reload will cause inefficient code.  Since sp is a FIXED_REG, we
3294 ;; can't allocate pseudos into it.
3295
3296 (define_expand "andsi3"
3297   [(set (match_operand:SI 0 "not_sp_operand" "")
3298         (and:SI (match_operand:SI 1 "general_operand" "")
3299                 (match_operand:SI 2 "general_src_operand" "")))]
3300   ""
3301   "")
3302
3303 (define_insn "andsi3_internal"
3304   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3305         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3306                 (match_operand:SI 2 "general_src_operand" "dKT,dmSM")))]
3307   "!TARGET_5200"
3308   "*
3309 {
3310   return output_andsi3 (operands);
3311 }")
3312
3313 (define_insn "andsi3_5200"
3314   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3315         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3316                 (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
3317   "TARGET_5200"
3318   "and%.l %2,%0")
3319
3320 (define_insn "andhi3"
3321   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
3322         (and:HI (match_operand:HI 1 "general_operand" "%0,0")
3323                 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
3324   "!TARGET_5200"
3325   "and%.w %2,%0")
3326
3327 (define_insn ""
3328   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3329         (and:HI (match_dup 0)
3330                 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
3331   "!TARGET_5200"
3332   "and%.w %1,%0")
3333
3334 (define_insn ""
3335   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3336         (and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
3337                 (match_dup 0)))]
3338   "!TARGET_5200"
3339   "and%.w %1,%0")
3340
3341 (define_insn "andqi3"
3342   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
3343         (and:QI (match_operand:QI 1 "general_operand" "%0,0")
3344                 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
3345   "!TARGET_5200"
3346   "and%.b %2,%0")
3347
3348 (define_insn ""
3349   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3350         (and:QI (match_dup 0)
3351                 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
3352   "!TARGET_5200"
3353   "and%.b %1,%0")
3354
3355 (define_insn ""
3356   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3357         (and:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
3358                 (match_dup 0)))]
3359   "!TARGET_5200"
3360   "and%.b %1,%0")
3361 \f
3362 ;; inclusive-or instructions
3363
3364 (define_insn "iordi_zext"
3365   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3366     (ior:DI (zero_extend:DI (match_operand 1 "general_operand" "dn,dmn"))
3367         (match_operand:DI 2 "general_operand" "0,0")))]
3368   "!TARGET_5200"
3369   "*
3370 {
3371   int byte_mode;
3372
3373   CC_STATUS_INIT;
3374   if (GET_CODE (operands[0]) == REG)
3375     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3376   else
3377     operands[0] = adjust_address (operands[0], SImode, 4);
3378   if (GET_MODE (operands[1]) == SImode)
3379     return \"or%.l %1,%0\";
3380   byte_mode = (GET_MODE (operands[1]) == QImode);
3381   if (GET_CODE (operands[0]) == MEM)
3382     operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
3383                                   byte_mode ? 3 : 2);
3384   if (byte_mode)
3385     return \"or%.b %1,%0\";
3386   else
3387     return \"or%.w %1,%0\";
3388 }")
3389
3390 ;; "iordi3" is mainly here to help combine().
3391 (define_insn "iordi3"
3392   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3393         (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
3394                 (match_operand:DI 2 "general_operand" "dn,don")))]
3395   "!TARGET_5200"
3396   "*
3397 {
3398   CC_STATUS_INIT;
3399   /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3400   if (CONSTANT_P (operands[2]))
3401     {
3402       rtx hi, lo;
3403
3404       split_double (operands[2], &hi, &lo);
3405
3406       switch (INTVAL (hi))
3407         {
3408           case 0 :
3409             break;
3410           case -1 :
3411             /* FIXME : a scratch register would be welcome here if operand[0]
3412                is not a register */
3413             output_asm_insn (\"move%.l %#-1,%0\", operands);
3414             break;
3415           default :
3416             {
3417             rtx xoperands[3];
3418
3419             xoperands[0] = operands[0];
3420             xoperands[2] = hi;
3421             output_asm_insn (output_iorsi3 (xoperands), xoperands);
3422             }
3423         }
3424       if (GET_CODE (operands[0]) == REG)
3425         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3426       else
3427         operands[0] = adjust_address (operands[0], SImode, 4);
3428       switch (INTVAL (lo))
3429         {
3430           case 0 :
3431             break;
3432           case -1 :
3433             /* FIXME : a scratch register would be welcome here if operand[0]
3434                is not a register */
3435             output_asm_insn (\"move%.l %#-1,%0\", operands);
3436             break;
3437           default :
3438             {
3439             rtx xoperands[3];
3440
3441             xoperands[0] = operands[0];
3442             xoperands[2] = lo;
3443             output_asm_insn (output_iorsi3 (xoperands), xoperands);
3444             }
3445         }
3446       return \"\";
3447     }
3448   if (GET_CODE (operands[0]) != REG)
3449     {
3450       operands[1] = adjust_address (operands[0], SImode, 4);
3451       return \"or%.l %2,%0\;or%.l %R2,%1\";
3452     }
3453   if (GET_CODE (operands[2]) != REG)
3454     {
3455       operands[1] = adjust_address (operands[2], SImode, 4);
3456       return \"or%.l %2,%0\;or%.l %1,%R0\";
3457     }
3458   return \"or%.l %2,%0\;or%.l %R2,%R0\";
3459 }")
3460
3461 (define_expand "iorsi3"
3462   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3463         (ior:SI (match_operand:SI 1 "general_operand" "")
3464                 (match_operand:SI 2 "general_src_operand" "")))]
3465   ""
3466   "")
3467
3468 (define_insn "iorsi3_internal"
3469   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d")
3470         (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3471                 (match_operand:SI 2 "general_src_operand" "dKT,dmSMT")))]
3472   "! TARGET_5200"
3473   "*
3474 {
3475   return output_iorsi3 (operands);