OSDN Git Service

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