OSDN Git Service

* m68k.md (xordi3, anddi3): These patterns are not available on
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / m68k.md
1 ;;- Machine description for GNU compiler, Motorola 68000 Version
2 ;;  Copyright (C) 1987, 88, 93-98, 1999 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 && !TARGET_PCREL && 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" "rKT,rKs,mSr,mSa,>")
521                  (match_operand:SI 1 "general_src_operand" "mSr,mSa,KTr,Ksr,>")))]
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   if (ADDRESS_REG_P (operands[0])
541       && GET_CODE (operands[1]) == CONST_INT
542       && INTVAL (operands[1]) < 0x8000
543       && INTVAL (operands[1]) >= -0x8000)
544     {
545 #ifdef SGS_CMP_ORDER
546       return \"cmp%.w %0,%1\";
547 #else
548       return \"cmp%.w %1,%0\";
549 #endif
550     }
551 #ifdef SGS_CMP_ORDER
552   return \"cmp%.l %d0,%d1\";
553 #else
554   return \"cmp%.l %d1,%d0\";
555 #endif
556 }")
557
558 (define_insn ""
559   [(set (cc0)
560         (compare (match_operand:SI 0 "nonimmediate_operand" "mrKs,r")
561                  (match_operand:SI 1 "general_operand" "r,mrKs")))]
562   "TARGET_5200"
563   "*
564 {
565   if (REG_P (operands[1])
566       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
567     { cc_status.flags |= CC_REVERSED;
568 #ifdef SGS_CMP_ORDER
569       return \"cmp%.l %d1,%d0\";
570 #else
571       return \"cmp%.l %d0,%d1\";
572 #endif
573     }
574 #ifdef SGS_CMP_ORDER
575   return \"cmp%.l %d0,%d1\";
576 #else
577   return \"cmp%.l %d1,%d0\";
578 #endif
579 }")
580
581 (define_expand "cmphi"
582   [(set (cc0)
583         (compare (match_operand:HI 0 "nonimmediate_src_operand" "")
584                  (match_operand:HI 1 "general_src_operand" "")))]
585   "!TARGET_5200"
586   "m68k_last_compare_had_fp_operands = 0;")
587
588 (define_insn ""
589   [(set (cc0)
590         (compare (match_operand:HI 0 "nonimmediate_src_operand" "rnmS,d,n,mS,>")
591                  (match_operand:HI 1 "general_src_operand" "d,rnmS,mS,n,>")))]
592   "!TARGET_5200"
593   "*
594 {
595   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
596 #ifdef SGS_CMP_ORDER
597     return \"cmpm%.w %0,%1\";
598 #else
599     return \"cmpm%.w %1,%0\";
600 #endif
601   if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
602       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
603     { cc_status.flags |= CC_REVERSED;
604 #ifdef SGS_CMP_ORDER
605       return \"cmp%.w %d1,%d0\";
606 #else
607       return \"cmp%.w %d0,%d1\";
608 #endif
609     }
610 #ifdef SGS_CMP_ORDER
611   return \"cmp%.w %d0,%d1\";
612 #else
613   return \"cmp%.w %d1,%d0\";
614 #endif
615 }")
616
617 (define_expand "cmpqi"
618   [(set (cc0)
619         (compare (match_operand:QI 0 "nonimmediate_src_operand" "")
620                  (match_operand:QI 1 "general_src_operand" "")))]
621   "!TARGET_5200"
622   "m68k_last_compare_had_fp_operands = 0;")
623
624 (define_insn ""
625   [(set (cc0)
626         (compare (match_operand:QI 0 "nonimmediate_src_operand" "dn,dmS,>")
627                  (match_operand:QI 1 "general_src_operand" "dmS,nd,>")))]
628   "!TARGET_5200"
629   "*
630 {
631   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
632 #ifdef SGS_CMP_ORDER
633     return \"cmpm%.b %0,%1\";
634 #else
635     return \"cmpm%.b %1,%0\";
636 #endif
637   if (REG_P (operands[1])
638       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
639     { cc_status.flags |= CC_REVERSED;
640 #ifdef SGS_CMP_ORDER
641       return \"cmp%.b %d1,%d0\";
642 #else
643       return \"cmp%.b %d0,%d1\";
644 #endif
645     }
646 #ifdef SGS_CMP_ORDER
647   return \"cmp%.b %d0,%d1\";
648 #else
649   return \"cmp%.b %d1,%d0\";
650 #endif
651 }")
652
653 (define_expand "cmpdf"
654   [(set (cc0)
655         (compare (match_operand:DF 0 "general_operand" "")
656                  (match_operand:DF 1 "general_operand" "")))]
657   "TARGET_68881 || TARGET_FPA"
658   "
659 {
660   m68k_last_compare_had_fp_operands = 1;
661   if (TARGET_FPA)
662     {
663       emit_insn (gen_cmpdf_fpa (operands[0], operands[1]));
664       DONE;
665     }
666 }")
667
668 (define_insn "cmpdf_fpa"
669   [(set (cc0)
670         (compare (match_operand:DF 0 "general_operand" "x,y")
671                  (match_operand:DF 1 "general_operand" "xH,rmF")))
672    (clobber (match_scratch:SI 2 "=d,d"))]
673   "TARGET_FPA"
674   "fpcmp%.d %y1,%0\;fpmove fpastatus,%2\;movw %2,cc")
675
676 (define_insn ""
677   [(set (cc0)
678         (compare (match_operand:DF 0 "general_operand" "f,mG")
679                  (match_operand:DF 1 "general_operand" "fmG,f")))]
680   "TARGET_68881"
681   "*
682 {
683   cc_status.flags = CC_IN_68881;
684 #ifdef SGS_CMP_ORDER
685   if (REG_P (operands[0]))
686     {
687       if (REG_P (operands[1]))
688         return \"fcmp%.x %0,%1\";
689       else
690         return \"fcmp%.d %0,%f1\";
691     }
692   cc_status.flags |= CC_REVERSED;
693   return \"fcmp%.d %1,%f0\";
694 #else
695   if (REG_P (operands[0]))
696     {
697       if (REG_P (operands[1]))
698         return \"fcmp%.x %1,%0\";
699       else
700         return \"fcmp%.d %f1,%0\";
701     }
702   cc_status.flags |= CC_REVERSED;
703   return \"fcmp%.d %f0,%1\";
704 #endif
705 }")
706
707 (define_expand "cmpsf"
708  [(set (cc0)
709        (compare (match_operand:SF 0 "general_operand" "")
710                 (match_operand:SF 1 "general_operand" "")))]
711  "TARGET_68881 || TARGET_FPA"
712  "
713 {
714   m68k_last_compare_had_fp_operands = 1;
715   if (TARGET_FPA)
716     {
717       emit_insn (gen_cmpsf_fpa (operands[0], operands[1]));
718       DONE;
719     }
720 }")
721
722 (define_insn "cmpsf_fpa"
723   [(set (cc0)
724         (compare (match_operand:SF 0 "general_operand" "x,y")
725                  (match_operand:SF 1 "general_operand" "xH,rmF")))
726    (clobber (match_scratch:SI 2 "=d,d"))]
727   "TARGET_FPA"
728   "fpcmp%.s %w1,%x0\;fpmove fpastatus,%2\;movw %2,cc")
729
730 (define_insn ""
731   [(set (cc0)
732         (compare (match_operand:SF 0 "general_operand" "f,mdG")
733                  (match_operand:SF 1 "general_operand" "fmdG,f")))]
734   "TARGET_68881"
735   "*
736 {
737   cc_status.flags = CC_IN_68881;
738 #ifdef SGS_CMP_ORDER
739   if (FP_REG_P (operands[0]))
740     {
741       if (FP_REG_P (operands[1]))
742         return \"fcmp%.x %0,%1\";
743       else
744         return \"fcmp%.s %0,%f1\";
745     }
746   cc_status.flags |= CC_REVERSED;
747   return \"fcmp%.s %1,%f0\";
748 #else
749   if (FP_REG_P (operands[0]))
750     {
751       if (FP_REG_P (operands[1]))
752         return \"fcmp%.x %1,%0\";
753       else
754         return \"fcmp%.s %f1,%0\";
755     }
756   cc_status.flags |= CC_REVERSED;
757   return \"fcmp%.s %f0,%1\";
758 #endif
759 }")
760 \f
761 ;; Recognizers for btst instructions.
762
763 ;; Coldfire/5200 only allows "<Q>" type addresses when the bit position is
764 ;; specified as a constant, so we must disable all patterns that may extract
765 ;; from a MEM at a constant bit position if we can't use this as a constraint.
766
767 (define_insn ""
768   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_src_operand" "oS")
769                             (const_int 1)
770                             (minus:SI (const_int 7)
771                                       (match_operand:SI 1 "general_operand" "di"))))]
772   "!TARGET_5200"
773   "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
774
775 ;; This is the same as the above pattern except for the constraints.  The 'i'
776 ;; has been deleted.
777
778 (define_insn ""
779   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
780                             (const_int 1)
781                             (minus:SI (const_int 7)
782                                       (match_operand:SI 1 "general_operand" "d"))))]
783   "TARGET_5200"
784   "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
785
786 (define_insn ""
787   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
788                             (const_int 1)
789                             (minus:SI (const_int 31)
790                                       (match_operand:SI 1 "general_operand" "di"))))]
791   ""
792   "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
793
794 ;; The following two patterns are like the previous two
795 ;; except that they use the fact that bit-number operands
796 ;; are automatically masked to 3 or 5 bits.
797
798 (define_insn ""
799   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
800                             (const_int 1)
801                             (minus:SI (const_int 7)
802                                       (and:SI
803                                        (match_operand:SI 1 "register_operand" "d")
804                                        (const_int 7)))))]
805   ""
806   "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
807
808 (define_insn ""
809   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
810                             (const_int 1)
811                             (minus:SI (const_int 31)
812                                       (and:SI
813                                        (match_operand:SI 1 "register_operand" "d")
814                                        (const_int 31)))))]
815   ""
816   "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
817
818 ;; Nonoffsettable mem refs are ok in this one pattern
819 ;; since we don't try to adjust them.
820 (define_insn ""
821   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
822                             (const_int 1)
823                             (match_operand:SI 1 "const_int_operand" "n")))]
824   "(unsigned) INTVAL (operands[1]) < 8 && !TARGET_5200"
825   "*
826 {
827   operands[1] = GEN_INT (7 - INTVAL (operands[1]));
828   return output_btst (operands, operands[1], operands[0], insn, 7);
829 }")
830
831 (define_insn ""
832   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "do")
833                             (const_int 1)
834                             (match_operand:SI 1 "const_int_operand" "n")))]
835   "!TARGET_5200"
836   "*
837 {
838   if (GET_CODE (operands[0]) == MEM)
839     {
840       operands[0] = adj_offsettable_operand (operands[0],
841                                              INTVAL (operands[1]) / 8);
842       operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
843       return output_btst (operands, operands[1], operands[0], insn, 7);
844     }
845   operands[1] = GEN_INT (31 - INTVAL (operands[1]));
846   return output_btst (operands, operands[1], operands[0], insn, 31);
847 }")
848
849 ;; This is the same as the above pattern except for the constraints.
850 ;; The 'o' has been replaced with 'Q'.
851
852 (define_insn ""
853   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "dQ")
854                             (const_int 1)
855                             (match_operand:SI 1 "const_int_operand" "n")))]
856   "TARGET_5200"
857   "*
858 {
859   if (GET_CODE (operands[0]) == MEM)
860     {
861       operands[0] = adj_offsettable_operand (operands[0],
862                                              INTVAL (operands[1]) / 8);
863       operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
864       return output_btst (operands, operands[1], operands[0], insn, 7);
865     }
866   operands[1] = GEN_INT (31 - INTVAL (operands[1]));
867   return output_btst (operands, operands[1], operands[0], insn, 31);
868 }")
869
870 \f
871 ;; move instructions
872
873 ;; A special case in which it is not desirable
874 ;; to reload the constant into a data register.
875 (define_insn "pushexthisi_const"
876   [(set (match_operand:SI 0 "push_operand" "=m")
877         (match_operand:SI 1 "const_int_operand" "J"))]
878   "INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000"
879   "*
880 {
881   if (operands[1] == const0_rtx)
882     return \"clr%.l %0\";
883   return \"pea %a1\";
884 }")
885
886 ;This is never used.
887 ;(define_insn "swapsi"
888 ;  [(set (match_operand:SI 0 "general_operand" "+r")
889 ;       (match_operand:SI 1 "general_operand" "+r"))
890 ;   (set (match_dup 1) (match_dup 0))]
891 ;  ""
892 ;  "exg %1,%0")
893
894 ;; Special case of fullword move when source is zero.
895 ;; The reason this is special is to avoid loading a zero
896 ;; into a data reg with moveq in order to store it elsewhere.
897
898 (define_insn "movsi_const0"
899   [(set (match_operand:SI 0 "general_operand" "=g")
900         (const_int 0))]
901   ;; clr insns on 68000 read before writing.
902   ;; This isn't so on the 68010, but we have no TARGET_68010.
903   "((TARGET_68020 || TARGET_5200)
904     || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))"
905   "*
906 {
907   if (ADDRESS_REG_P (operands[0]))
908     {
909       /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
910       if (!TARGET_68040 && !TARGET_68060)
911         return \"sub%.l %0,%0\";
912       else
913         {
914 #ifdef MOTOROLA
915 #ifdef SGS
916           /* Many SGS assemblers croak on size specifiers for constants. */
917           return \"lea 0,%0\";
918 #else
919           return \"lea 0.w,%0\";
920 #endif
921 #else
922           return \"lea 0:w,%0\";
923 #endif
924         }
925     }
926   /* moveq is faster on the 68000.  */
927   if (DATA_REG_P (operands[0]) && (!TARGET_68020 && !TARGET_5200))
928 #if defined(MOTOROLA) && !defined(CRDS)
929     return \"moveq%.l %#0,%0\";
930 #else
931     return \"moveq %#0,%0\";
932 #endif
933   return \"clr%.l %0\";
934 }")
935
936 ;; General case of fullword move.
937 ;;
938 ;; This is the main "hook" for PIC code.  When generating
939 ;; PIC, movsi is responsible for determining when the source address
940 ;; needs PIC relocation and appropriately calling legitimize_pic_address
941 ;; to perform the actual relocation.
942 ;;
943 ;; In both the PIC and non-PIC cases the patterns generated will
944 ;; matched by the next define_insn.
945 (define_expand "movsi"
946   [(set (match_operand:SI 0 "general_operand" "")
947         (match_operand:SI 1 "general_operand" ""))]
948   ""
949   "
950 {
951   if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
952     {
953       /* The source is an address which requires PIC relocation.
954          Call legitimize_pic_address with the source, mode, and a relocation
955          register (a new pseudo, or the final destination if reload_in_progress
956          is set).   Then fall through normally */
957       extern rtx legitimize_pic_address();
958       rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
959       operands[1] = legitimize_pic_address (operands[1], SImode, temp);
960     }
961   else if (flag_pic && TARGET_PCREL && ! reload_in_progress)
962     {
963       /* Don't allow writes to memory except via a register;
964          the m68k doesn't consider PC-relative addresses to be writable.  */
965       if (symbolic_operand (operands[0], SImode))
966         operands[0] = force_reg (SImode, XEXP (operands[0], 0));
967       else if (GET_CODE (operands[0]) == MEM
968                && symbolic_operand (XEXP (operands[0], 0), SImode))
969         operands[0] = gen_rtx (MEM, SImode,
970                                force_reg (SImode, XEXP (operands[0], 0)));
971     }
972 }")
973
974 ;; General case of fullword move.  The register constraints
975 ;; force integer constants in range for a moveq to be reloaded
976 ;; if they are headed for memory.
977 (define_insn ""
978   ;; Notes: make sure no alternative allows g vs g.
979   ;; We don't allow f-regs since fixed point cannot go in them.
980   ;; We do allow y and x regs since fixed point is allowed in them.
981   [(set (match_operand:SI 0 "general_operand" "=g,d,a<,y,!*x*r*m")
982         (match_operand:SI 1 "general_src_operand" "daymSKT,n,i,g,*x*r*m"))]
983
984   "!TARGET_5200"
985   "*
986 {
987   if (which_alternative == 4)
988     return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\";
989   if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0]))
990     return \"fpmove%.l %x1,%x0\";
991   return output_move_simode (operands);
992 }")
993
994 (define_insn ""
995   [(set (match_operand:SI 0 "general_operand" "=r<Q>,g")
996         (match_operand:SI 1 "general_operand" "g,r<Q>"))]
997   "TARGET_5200"
998   "* return output_move_simode (operands);")
999
1000 ;; Special case of fullword move, where we need to get a non-GOT PIC
1001 ;; reference into an address register.
1002 (define_insn ""
1003   [(set (match_operand:SI 0 "general_operand" "=a<")
1004         (match_operand:SI 1 "pcrel_address" ""))]
1005   "TARGET_PCREL"
1006   "*
1007 {
1008   if (push_operand (operands[0], SImode))
1009     return \"pea %a1\";
1010   return \"lea %a1,%0\";
1011 }")
1012
1013 (define_expand "movhi"
1014   [(set (match_operand:HI 0 "general_operand" "")
1015         (match_operand:HI 1 "general_operand" ""))]
1016   ""
1017   "")
1018
1019 (define_insn ""
1020   [(set (match_operand:HI 0 "general_operand" "=g")
1021         (match_operand:HI 1 "general_src_operand" "gS"))]
1022   "!TARGET_5200"
1023   "* return output_move_himode (operands);")
1024
1025  (define_insn ""
1026   [(set (match_operand:HI 0 "general_operand" "=r<Q>,g")
1027         (match_operand:HI 1 "general_operand" "g,r<Q>"))]
1028   "TARGET_5200"
1029   "* return output_move_himode (operands);")
1030
1031 (define_expand "movstricthi"
1032   [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
1033         (match_operand:HI 1 "general_src_operand" ""))]
1034   ""
1035   "")
1036
1037 (define_insn ""
1038   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
1039         (match_operand:HI 1 "general_src_operand" "rmSn"))]
1040   "!TARGET_5200"
1041   "* return output_move_stricthi (operands);")
1042
1043 (define_insn ""
1044   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+d,m"))
1045         (match_operand:HI 1 "general_src_operand" "rmn,r"))]
1046   "TARGET_5200"
1047   "* return output_move_stricthi (operands);")
1048
1049 (define_expand "movqi"
1050   [(set (match_operand:QI 0 "general_operand" "")
1051         (match_operand:QI 1 "general_src_operand" ""))]
1052   ""
1053   "")
1054
1055 (define_insn ""
1056   [(set (match_operand:QI 0 "general_operand" "=d,*a,m")
1057         (match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))]
1058   "!TARGET_5200"
1059   "* return output_move_qimode (operands);")
1060
1061 (define_insn ""
1062   [(set (match_operand:QI 0 "general_operand" "=d<Q>,dm,d*a")
1063         (match_operand:QI 1 "general_src_operand" "dmi,d<Q>,di*a"))]
1064   "TARGET_5200"
1065   "* return output_move_qimode (operands);")
1066
1067 (define_expand "movstrictqi"
1068   [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1069         (match_operand:QI 1 "general_src_operand" ""))]
1070   ""
1071   "")
1072
1073 (define_insn ""
1074   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
1075         (match_operand:QI 1 "general_src_operand" "dmSn"))]
1076   "!TARGET_5200"
1077   "* return output_move_strictqi (operands);")
1078
1079 (define_insn ""
1080   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+d,m"))
1081         (match_operand:QI 1 "general_src_operand" "dmn,d"))]
1082   "TARGET_5200"
1083   "* return output_move_strictqi (operands);")
1084
1085 (define_expand "movsf"
1086   [(set (match_operand:SF 0 "general_operand" "")
1087         (match_operand:SF 1 "general_operand" ""))]
1088   ""
1089   "")
1090
1091 (define_insn ""
1092   [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm")
1093         (match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))]
1094 ;  [(set (match_operand:SF 0 "general_operand" "=rmf")
1095 ;       (match_operand:SF 1 "general_operand" "rmfF"))]
1096   "!TARGET_5200"
1097   "*
1098 {
1099   if (which_alternative >= 4)
1100     return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\";
1101   if (FPA_REG_P (operands[0]))
1102     {
1103       if (FPA_REG_P (operands[1]))
1104         return \"fpmove%.s %x1,%x0\";
1105       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
1106         return output_move_const_single (operands);
1107       else if (FP_REG_P (operands[1]))
1108         return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\";
1109       return \"fpmove%.s %x1,%x0\";
1110     }
1111   if (FPA_REG_P (operands[1]))
1112     {
1113       if (FP_REG_P (operands[0]))
1114         return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\";
1115       else
1116         return \"fpmove%.s %x1,%x0\";
1117     }
1118   if (FP_REG_P (operands[0]))
1119     {
1120       if (FP_REG_P (operands[1]))
1121         return \"f%$move%.x %1,%0\";
1122       else if (ADDRESS_REG_P (operands[1]))
1123         return \"move%.l %1,%-\;f%$move%.s %+,%0\";
1124       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
1125         return output_move_const_single (operands);
1126       return \"f%$move%.s %f1,%0\";
1127     }
1128   if (FP_REG_P (operands[1]))
1129     {
1130       if (ADDRESS_REG_P (operands[0]))
1131         return \"fmove%.s %1,%-\;move%.l %+,%0\";
1132       return \"fmove%.s %f1,%0\";
1133     }
1134   if (operands[1] == CONST0_RTX (SFmode)
1135       /* clr insns on 68000 read before writing.
1136          This isn't so on the 68010, but we have no TARGET_68010.  */
1137       && ((TARGET_68020 || TARGET_5200)
1138           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1139     {
1140       if (ADDRESS_REG_P (operands[0]))
1141         {
1142           /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
1143           if (!TARGET_68040 && !TARGET_68060)
1144             return \"sub%.l %0,%0\";
1145           else
1146             {
1147 #ifdef MOTOROLA
1148 #ifdef SGS
1149               /* Many SGS assemblers croak on size specifiers for constants. */
1150               return \"lea 0,%0\";
1151 #else
1152               return \"lea 0.w,%0\";
1153 #endif
1154 #else
1155               return \"lea 0:w,%0\";
1156 #endif
1157             }
1158         }
1159       /* moveq is faster on the 68000.  */
1160       if (DATA_REG_P (operands[0]) && !(TARGET_68020 || TARGET_5200))
1161         {
1162 #if defined(MOTOROLA) && !defined(CRDS)
1163           return \"moveq%.l %#0,%0\";
1164 #else
1165           return \"moveq %#0,%0\";
1166 #endif
1167         }
1168       return \"clr%.l %0\";
1169     }
1170   return \"move%.l %1,%0\";
1171 }")
1172
1173 (define_insn ""
1174   [(set (match_operand:SF 0 "general_operand" "=r,g")
1175         (match_operand:SF 1 "general_operand" "g,r"))]
1176   "TARGET_5200"
1177   "* return \"move%.l %1,%0\";")
1178
1179 (define_expand "movdf"
1180   [(set (match_operand:DF 0 "general_operand" "")
1181         (match_operand:DF 1 "general_operand" ""))]
1182   ""
1183   "")
1184
1185 (define_insn ""
1186   [(set (match_operand:DF 0 "general_operand"
1187                                 "=*rm,*rf,*rf,&*rof<>,y,*rm,x,!x,!*rm")
1188         (match_operand:DF 1 "general_operand"
1189                                 "*rf,m,0,*rofE<>,*rmE,y,xH,*rm,x"))]
1190 ;  [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>")
1191 ;       (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
1192   "!TARGET_5200"
1193   "*
1194 {
1195   if (which_alternative == 7)
1196     return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\";
1197   if (FPA_REG_P (operands[0]))
1198     {
1199       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1200         return output_move_const_double (operands);
1201       if (FP_REG_P (operands[1]))
1202         return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\";
1203       return \"fpmove%.d %x1,%x0\";
1204     }
1205   else if (FPA_REG_P (operands[1]))
1206     {
1207       if (FP_REG_P(operands[0]))
1208         return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\";
1209       else
1210         return \"fpmove%.d %x1,%x0\";
1211     }
1212   if (FP_REG_P (operands[0]))
1213     {
1214       if (FP_REG_P (operands[1]))
1215         return \"f%&move%.x %1,%0\";
1216       if (REG_P (operands[1]))
1217         {
1218           rtx xoperands[2];
1219           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1220           output_asm_insn (\"move%.l %1,%-\", xoperands);
1221           output_asm_insn (\"move%.l %1,%-\", operands);
1222           return \"f%&move%.d %+,%0\";
1223         }
1224       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1225         return output_move_const_double (operands);
1226       return \"f%&move%.d %f1,%0\";
1227     }
1228   else if (FP_REG_P (operands[1]))
1229     {
1230       if (REG_P (operands[0]))
1231         {
1232           output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1233           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1234           return \"move%.l %+,%0\";
1235         }
1236       else
1237         return \"fmove%.d %f1,%0\";
1238     }
1239   return output_move_double (operands);
1240 }")
1241
1242 (define_insn ""
1243   [(set (match_operand:DF 0 "general_operand" "=r,g")
1244         (match_operand:DF 1 "general_operand" "g,r"))]
1245   "TARGET_5200"
1246   "* return output_move_double (operands);")
1247
1248 (define_expand "movxf"
1249   [(set (match_operand:XF 0 "nonimmediate_operand" "")
1250         (match_operand:XF 1 "general_operand" ""))]
1251   ""
1252   "
1253 {
1254   if (CONSTANT_P (operands[1]))
1255     {
1256       operands[1] = force_const_mem (XFmode, operands[1]);
1257       if (! memory_address_p (XFmode, XEXP (operands[1], 0))
1258           && ! reload_in_progress)
1259         operands[1] = change_address (operands[1], XFmode,
1260                                       XEXP (operands[1], 0));
1261     }
1262   if (flag_pic && TARGET_PCREL && ! reload_in_progress)
1263     {
1264       /* Don't allow writes to memory except via a register;
1265          the m68k doesn't consider PC-relative addresses to be writable.  */
1266       if (GET_CODE (operands[0]) == MEM
1267           && symbolic_operand (XEXP (operands[0], 0), SImode))
1268         operands[0] = gen_rtx (MEM, XFmode,
1269                                force_reg (SImode, XEXP (operands[0], 0)));
1270     }
1271 }")
1272
1273 (define_insn ""
1274   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f,!r")
1275         (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r,!r"))]
1276   "TARGET_68881"
1277   "*
1278 {
1279   if (FP_REG_P (operands[0]))
1280     {
1281       if (FP_REG_P (operands[1]))
1282         return \"fmove%.x %1,%0\";
1283       if (REG_P (operands[1]))
1284         {
1285           rtx xoperands[2];
1286           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1287           output_asm_insn (\"move%.l %1,%-\", xoperands);
1288           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1289           output_asm_insn (\"move%.l %1,%-\", xoperands);
1290           output_asm_insn (\"move%.l %1,%-\", operands);
1291           return \"fmove%.x %+,%0\";
1292         }
1293       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1294         return \"fmove%.x %1,%0\";
1295       return \"fmove%.x %f1,%0\";
1296     }
1297   if (FP_REG_P (operands[1]))
1298     {
1299       if (REG_P (operands[0]))
1300         {
1301           output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
1302           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1303           output_asm_insn (\"move%.l %+,%0\", operands);
1304           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1305           return \"move%.l %+,%0\";
1306         }
1307       /* Must be memory destination.  */
1308       return \"fmove%.x %f1,%0\";
1309     }
1310   return output_move_double (operands);
1311 }
1312 ")
1313
1314 (define_insn ""
1315   [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
1316         (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))]
1317   "! TARGET_68881 && ! TARGET_5200"
1318   "*
1319 {
1320   if (FP_REG_P (operands[0]))
1321     {
1322       if (FP_REG_P (operands[1]))
1323         return \"fmove%.x %1,%0\";
1324       if (REG_P (operands[1]))
1325         {
1326           rtx xoperands[2];
1327           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1328           output_asm_insn (\"move%.l %1,%-\", xoperands);
1329           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1330           output_asm_insn (\"move%.l %1,%-\", xoperands);
1331           output_asm_insn (\"move%.l %1,%-\", operands);
1332           return \"fmove%.x %+,%0\";
1333         }
1334       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1335         return \"fmove%.x %1,%0\";
1336       return \"fmove%.x %f1,%0\";
1337     }
1338   if (FP_REG_P (operands[1]))
1339     {
1340       if (REG_P (operands[0]))
1341         {
1342           output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
1343           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1344           output_asm_insn (\"move%.l %+,%0\", operands);
1345           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1346           return \"move%.l %+,%0\";
1347         }
1348       else
1349         return \"fmove%.x %f1,%0\";
1350     }
1351   return output_move_double (operands);
1352 }
1353 ")
1354
1355 (define_insn ""
1356   [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g")
1357         (match_operand:XF 1 "nonimmediate_operand" "g,r"))]
1358   "! TARGET_68881 && TARGET_5200"
1359   "* return output_move_double (operands);")
1360
1361 (define_expand "movdi"
1362   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1363   [(set (match_operand:DI 0 "general_operand" "")
1364         (match_operand:DI 1 "general_operand" ""))]
1365   ""
1366   "")
1367
1368 ;; movdi can apply to fp regs in some cases
1369 (define_insn ""
1370   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1371   [(set (match_operand:DI 0 "general_operand" "=rm,r,&ro<>,y,rm,!*x,!rm")
1372         (match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))]
1373 ;  [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm")
1374 ;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))]
1375 ;  [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f")
1376 ;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
1377   "!TARGET_5200"
1378   "*
1379 {
1380   if (which_alternative == 8)
1381     return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\";
1382   if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
1383     return \"fpmove%.d %x1,%x0\";
1384   if (FP_REG_P (operands[0]))
1385     {
1386       if (FP_REG_P (operands[1]))
1387         return \"fmove%.x %1,%0\";
1388       if (REG_P (operands[1]))
1389         {
1390           rtx xoperands[2];
1391           xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1392           output_asm_insn (\"move%.l %1,%-\", xoperands);
1393           output_asm_insn (\"move%.l %1,%-\", operands);
1394           return \"fmove%.d %+,%0\";
1395         }
1396       if (GET_CODE (operands[1]) == CONST_DOUBLE)
1397         return output_move_const_double (operands);
1398       return \"fmove%.d %f1,%0\";
1399     }
1400   else if (FP_REG_P (operands[1]))
1401     {
1402       if (REG_P (operands[0]))
1403         {
1404           output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1405           operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1406           return \"move%.l %+,%0\";
1407         }
1408       else
1409         return \"fmove%.d %f1,%0\";
1410     }
1411   return output_move_double (operands);
1412 }")
1413
1414 (define_insn ""
1415   [(set (match_operand:DI 0 "general_operand" "=r,g")
1416         (match_operand:DI 1 "general_operand" "g,r"))]
1417   "TARGET_5200"
1418   "* return output_move_double (operands);")
1419
1420 ;; Thus goes after the move instructions
1421 ;; because the move instructions are better (require no spilling)
1422 ;; when they can apply.  It goes before the add/sub insns
1423 ;; so we will prefer it to them.
1424
1425 (define_insn "pushasi"
1426   [(set (match_operand:SI 0 "push_operand" "=m")
1427         (match_operand:SI 1 "address_operand" "p"))]
1428   ""
1429   "pea %a1")
1430 \f
1431 ;; truncation instructions
1432 (define_insn "truncsiqi2"
1433   [(set (match_operand:QI 0 "general_operand" "=dm,d")
1434         (truncate:QI
1435          (match_operand:SI 1 "general_src_operand" "doJS,i")))]
1436   ""
1437   "*
1438 {
1439   if (GET_CODE (operands[0]) == REG)
1440     {
1441       /* Must clear condition codes, since the move.l bases them on
1442          the entire 32 bits, not just the desired 8 bits.  */
1443       CC_STATUS_INIT;
1444       return \"move%.l %1,%0\";
1445     }
1446   if (GET_CODE (operands[1]) == MEM)
1447     operands[1] = adj_offsettable_operand (operands[1], 3);
1448   return \"move%.b %1,%0\";
1449 }")
1450
1451 (define_insn "trunchiqi2"
1452   [(set (match_operand:QI 0 "general_operand" "=dm,d")
1453         (truncate:QI
1454          (match_operand:HI 1 "general_src_operand" "doJS,i")))]
1455   ""
1456   "*
1457 {
1458   if (GET_CODE (operands[0]) == REG
1459       && (GET_CODE (operands[1]) == MEM
1460           || GET_CODE (operands[1]) == CONST_INT))
1461     {
1462       /* Must clear condition codes, since the move.w bases them on
1463          the entire 16 bits, not just the desired 8 bits.  */
1464       CC_STATUS_INIT;
1465       return \"move%.w %1,%0\";
1466     }
1467   if (GET_CODE (operands[0]) == REG)
1468     {
1469       /* Must clear condition codes, since the move.l bases them on
1470          the entire 32 bits, not just the desired 8 bits.  */
1471       CC_STATUS_INIT;
1472       return \"move%.l %1,%0\";
1473     }
1474   if (GET_CODE (operands[1]) == MEM)
1475     operands[1] = adj_offsettable_operand (operands[1], 1);
1476   return \"move%.b %1,%0\";
1477 }")
1478
1479 (define_insn "truncsihi2"
1480   [(set (match_operand:HI 0 "general_operand" "=dm,d")
1481         (truncate:HI
1482          (match_operand:SI 1 "general_src_operand" "roJS,i")))]
1483   ""
1484   "*
1485 {
1486   if (GET_CODE (operands[0]) == REG)
1487     {
1488       /* Must clear condition codes, since the move.l bases them on
1489          the entire 32 bits, not just the desired 8 bits.  */
1490       CC_STATUS_INIT;
1491       return \"move%.l %1,%0\";
1492     }
1493   if (GET_CODE (operands[1]) == MEM)
1494     operands[1] = adj_offsettable_operand (operands[1], 2);
1495   return \"move%.w %1,%0\";
1496 }")
1497 \f
1498 ;; zero extension instructions
1499
1500 (define_insn "zero_extendqidi2"
1501   [(set (match_operand:DI 0 "general_operand" "=&d")
1502         (zero_extend:DI (match_operand:QI 1 "general_operand" "dm")))]
1503   ""
1504   "*
1505 {
1506   CC_STATUS_INIT;
1507   operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1508   return \"moveq %#0,%0\;moveq %#0,%2\;move%.b %1,%2\";
1509 }")
1510
1511 (define_insn "zero_extendhidi2"
1512   [(set (match_operand:DI 0 "general_operand" "=&d")
1513         (zero_extend:DI (match_operand:HI 1 "general_operand" "rm")))]
1514   ""
1515   "*
1516 {
1517   CC_STATUS_INIT;
1518   operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1519   return \"moveq %#0,%0\;moveq %#0,%2\;move%.w %1,%2\";
1520 }")
1521
1522 ;; this is the canonical form for (lshiftrt:DI x 32)
1523 (define_insn "zero_extendsidi2"
1524   [(set (match_operand:DI 0 "general_operand" "rm")
1525     (zero_extend:DI (match_operand:SI 1 "general_operand" "rm")))]
1526   ""
1527   "*
1528 {
1529   CC_STATUS_INIT;
1530   if (GET_CODE (operands[0]) == REG)
1531     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1532   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1533     return \"move%.l %1,%0\;clr%.l %0\";
1534   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1535     return \"clr%.l %0\;move%.l %1,%0\";
1536   else
1537     operands[2] = adj_offsettable_operand (operands[0], 4);
1538   if (GET_CODE (operands[1]) != REG || GET_CODE (operands[2]) != REG
1539       || REGNO (operands[1]) != REGNO (operands[2]))
1540     output_asm_insn (\"move%.l %1,%2\", operands);
1541   if (ADDRESS_REG_P (operands[0]))
1542     return \"sub%.l %0,%0\";
1543   else
1544     return \"clr%.l %0\";
1545 }")
1546
1547 (define_expand "zero_extendhisi2"
1548   [(set (match_operand:SI 0 "register_operand" "")
1549         (const_int 0))
1550    (set (strict_low_part (match_dup 2))
1551         (match_operand:HI 1 "general_operand" ""))]
1552   ""
1553   "
1554 {
1555   operands[1] = make_safe_from (operands[1], operands[0]);
1556   if (GET_CODE (operands[0]) == SUBREG)
1557     operands[2] = gen_rtx_SUBREG (HImode, SUBREG_REG (operands[0]),
1558                                   SUBREG_WORD (operands[0]));
1559   else
1560     operands[2] = gen_rtx_SUBREG (HImode, operands[0], 0);
1561 }")
1562
1563 (define_expand "zero_extendqihi2"
1564   [(set (match_operand:HI 0 "register_operand" "")
1565         (const_int 0))
1566    (set (strict_low_part (match_dup 2))
1567         (match_operand:QI 1 "general_operand" ""))]
1568   ""
1569   "
1570 {
1571   operands[1] = make_safe_from (operands[1], operands[0]);
1572   if (GET_CODE (operands[0]) == SUBREG)
1573     operands[2] = gen_rtx_SUBREG (QImode, SUBREG_REG (operands[0]),
1574                                   SUBREG_WORD (operands[0]));
1575   else
1576     operands[2] = gen_rtx_SUBREG (QImode, operands[0], 0);
1577 }")
1578
1579 (define_expand "zero_extendqisi2"
1580   [(set (match_operand:SI 0 "register_operand" "")
1581         (const_int 0))
1582    (set (strict_low_part (match_dup 2))
1583         (match_operand:QI 1 "general_operand" ""))]
1584   ""
1585   "
1586 {
1587   operands[1] = make_safe_from (operands[1], operands[0]);
1588   if (GET_CODE (operands[0]) == SUBREG)
1589     operands[2] = gen_rtx_SUBREG (QImode, SUBREG_REG (operands[0]),
1590                                   SUBREG_WORD (operands[0]));
1591   else
1592     operands[2] = gen_rtx_SUBREG (QImode, operands[0], 0);
1593 }")
1594 \f
1595 ;; Patterns to recognize zero-extend insns produced by the combiner.
1596 ;; We don't allow both operands in memory, because of aliasing problems.
1597 ;; Explicitly disallow two memory operands via the condition since reloading
1598 ;; of this case will result in worse code than the uncombined patterns.
1599
1600 (define_insn ""
1601   [(set (match_operand:SI 0 "general_operand" "=do<>,d<")
1602         (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "r,mS")))]
1603   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1604   "*
1605 {
1606   if (DATA_REG_P (operands[0]))
1607     {
1608       if (GET_CODE (operands[1]) == REG
1609           && REGNO (operands[0]) == REGNO (operands[1]))
1610         return \"and%.l %#0xFFFF,%0\";
1611       if (reg_mentioned_p (operands[0], operands[1]))
1612         return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\";
1613       return \"clr%.l %0\;move%.w %1,%0\";
1614     }
1615   else if (GET_CODE (operands[0]) == MEM
1616            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1617     return \"move%.w %1,%0\;clr%.w %0\";
1618   else if (GET_CODE (operands[0]) == MEM
1619            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1620     return \"clr%.w %0\;move%.w %1,%0\";
1621   else
1622     {
1623       output_asm_insn (\"clr%.w %0\", operands);
1624       operands[0] = adj_offsettable_operand (operands[0], 2);
1625       return \"move%.w %1,%0\";
1626     }
1627 }")
1628
1629 (define_insn ""
1630   [(set (match_operand:HI 0 "general_operand" "=do<>,d")
1631         (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
1632   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1633   "*
1634 {
1635   if (DATA_REG_P (operands[0]))
1636     {
1637       if (GET_CODE (operands[1]) == REG
1638           && REGNO (operands[0]) == REGNO (operands[1]))
1639         return (!TARGET_5200 ? \"and%.w %#0xFF,%0\" : \"and%.l %#0xFF,%0\");
1640       if (reg_mentioned_p (operands[0], operands[1]))
1641         return (!TARGET_5200 ? \"move%.b %1,%0\;and%.w %#0xFF,%0\" 
1642                              : \"move%.b %1,%0\;and%.l %#0xFF,%0\");
1643       return \"clr%.w %0\;move%.b %1,%0\";
1644     }
1645   else if (GET_CODE (operands[0]) == MEM
1646            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1647     {
1648       if (REGNO (XEXP (XEXP (operands[0], 0), 0))
1649           == STACK_POINTER_REGNUM)
1650         {
1651           output_asm_insn (\"clr%.w %-\", operands);
1652           operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
1653                                      plus_constant (stack_pointer_rtx, 1));
1654           return \"move%.b %1,%0\";
1655         }
1656       else
1657         return \"move%.b %1,%0\;clr%.b %0\";
1658     }
1659   else if (GET_CODE (operands[0]) == MEM
1660            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1661     return \"clr%.b %0\;move%.b %1,%0\";
1662   else
1663     {
1664       output_asm_insn (\"clr%.b %0\", operands);
1665       operands[0] = adj_offsettable_operand (operands[0], 1);
1666       return \"move%.b %1,%0\";
1667     }
1668 }")
1669
1670 (define_insn ""
1671   [(set (match_operand:SI 0 "general_operand" "=do<>,d")
1672         (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
1673   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1674   "*
1675 {
1676   if (DATA_REG_P (operands[0]))
1677     {
1678       if (GET_CODE (operands[1]) == REG
1679           && REGNO (operands[0]) == REGNO (operands[1]))
1680         return \"and%.l %#0xFF,%0\";
1681       if (reg_mentioned_p (operands[0], operands[1]))
1682         return \"move%.b %1,%0\;and%.l %#0xFF,%0\";
1683       return \"clr%.l %0\;move%.b %1,%0\";
1684     }
1685   else if (GET_CODE (operands[0]) == MEM
1686            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1687     {
1688       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1689 #ifdef MOTOROLA
1690 #ifdef SGS
1691       return \"clr%.l -(%0)\;move%.b %1,3(%0)\";
1692 #else
1693       return \"clr%.l -(%0)\;move%.b %1,(3,%0)\";
1694 #endif
1695 #else
1696       return \"clrl %0@-\;moveb %1,%0@(3)\";
1697 #endif
1698     }
1699   else if (GET_CODE (operands[0]) == MEM
1700            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1701     {
1702       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1703 #ifdef MOTOROLA
1704 #ifdef SGS
1705       return \"clr%.l (%0)+\;move%.b %1,-1(%0)\";
1706 #else
1707       return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\";
1708 #endif
1709 #else
1710       return \"clrl %0@+\;moveb %1,%0@(-1)\";
1711 #endif
1712     }
1713   else
1714     {
1715       output_asm_insn (\"clr%.l %0\", operands);
1716       operands[0] = adj_offsettable_operand (operands[0], 3);
1717       return \"move%.b %1,%0\";
1718     }
1719 }")
1720 \f
1721 ;; sign extension instructions
1722
1723 (define_insn "extendqidi2"
1724   [(set (match_operand:DI 0 "general_operand" "=d")
1725         (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))]
1726   ""
1727   "*
1728 {
1729   CC_STATUS_INIT;
1730   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1731   if (TARGET_68020 || TARGET_5200)
1732     return \"move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0\";
1733   else
1734     return \"move%.b %1,%2\;ext%.w %0\;ext%.l %2\;move%.l %2,%0\;smi %0\";
1735 }")
1736
1737 (define_insn "extendhidi2"
1738   [(set (match_operand:DI 0 "general_operand" "=d")
1739         (sign_extend:DI
1740          (match_operand:HI 1 "general_src_operand" "rmS")))]
1741   ""
1742   "*
1743 {
1744   CC_STATUS_INIT;
1745   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1746   if (TARGET_68020 || TARGET_5200)
1747     return \"move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0\";
1748   else
1749     return \"move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0\";
1750 }")
1751
1752 (define_insn "extendsidi2"
1753   [(set (match_operand:DI 0 "general_operand" "=d")
1754         (sign_extend:DI
1755          (match_operand:SI 1 "general_operand" "rm")))]
1756   ""
1757   "*
1758 {
1759   CC_STATUS_INIT;
1760   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1761   if (TARGET_68020 || TARGET_5200)
1762     return \"move%.l %1,%2\;smi %0\;extb%.l %0\";
1763   else
1764     return \"move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0\";
1765 }")
1766
1767 ;; Special case when one can avoid register clobbering, copy and test
1768 ;; Maybe there is a way to make that the general case, by forcing the
1769 ;; result of the SI tree to be in the lower register of the DI target
1770
1771 (define_insn "extendplussidi"
1772   [(set (match_operand:DI 0 "register_operand" "=d")
1773     (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
1774             (match_operand:SI 2 "general_operand" "rmn"))))]
1775   ""
1776   "*
1777 {
1778   CC_STATUS_INIT;
1779   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1780   if (GET_CODE (operands[1]) == CONST_INT
1781   && (unsigned) INTVAL (operands[1]) > 8)
1782     {
1783       rtx tmp = operands[1];
1784
1785       operands[1] = operands[2];
1786       operands[2] = tmp;
1787     }
1788   if (GET_CODE (operands[1]) == REG
1789       && REGNO (operands[1]) == REGNO (operands[3]))
1790     output_asm_insn (\"add%.l %2,%3\", operands);
1791   else
1792     output_asm_insn (\"move%.l %2,%3\;add%.l %1,%3\", operands);
1793   if (TARGET_68020 || TARGET_5200)
1794     return \"smi %0\;extb%.l %0\";
1795   else
1796     return \"smi %0\;ext%.w %0\;ext%.l %0\";
1797 }")
1798
1799 (define_insn "extendhisi2"
1800   [(set (match_operand:SI 0 "general_operand" "=*d,a")
1801         (sign_extend:SI
1802          (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
1803   ""
1804   "*
1805 {
1806   if (ADDRESS_REG_P (operands[0]))
1807     return \"move%.w %1,%0\";
1808   return \"ext%.l %0\";
1809 }")
1810
1811 (define_insn "extendqihi2"
1812   [(set (match_operand:HI 0 "general_operand" "=d")
1813         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1814   ""
1815   "ext%.w %0")
1816
1817 (define_insn "extendqisi2"
1818   [(set (match_operand:SI 0 "general_operand" "=d")
1819         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1820   "TARGET_68020 || TARGET_5200"
1821   "extb%.l %0")
1822 \f
1823 ;; Conversions between float and double.
1824
1825 (define_expand "extendsfdf2"
1826   [(set (match_operand:DF 0 "general_operand" "")
1827         (float_extend:DF
1828          (match_operand:SF 1 "general_operand" "")))]
1829   "TARGET_68881 || TARGET_FPA"
1830   "")
1831
1832 (define_insn ""
1833   [(set (match_operand:DF 0 "general_operand" "=x,y")
1834         (float_extend:DF
1835          (match_operand:SF 1 "general_operand" "xH,rmF")))]
1836   "TARGET_FPA"
1837   "fpstod %w1,%0")
1838
1839 (define_insn ""
1840   [(set (match_operand:DF 0 "general_operand" "=*fdm,f")
1841         (float_extend:DF
1842           (match_operand:SF 1 "general_operand" "f,dmF")))]
1843   "TARGET_68881"
1844   "*
1845 {
1846   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1847     {
1848       if (REGNO (operands[0]) == REGNO (operands[1]))
1849         {
1850           /* Extending float to double in an fp-reg is a no-op.
1851              NOTICE_UPDATE_CC has already assumed that the
1852              cc will be set.  So cancel what it did.  */
1853           cc_status = cc_prev_status;
1854           return \"\";
1855         }
1856       return \"f%&move%.x %1,%0\";
1857     }
1858   if (FP_REG_P (operands[0]))
1859     return \"f%&move%.s %f1,%0\";
1860   if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
1861     {
1862       output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1863       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1864       return \"move%.l %+,%0\";
1865     }
1866   return \"fmove%.d %f1,%0\";
1867 }")
1868
1869 ;; This cannot output into an f-reg because there is no way to be
1870 ;; sure of truncating in that case.
1871 ;; But on the Sun FPA, we can be sure.
1872 (define_expand "truncdfsf2"
1873   [(set (match_operand:SF 0 "general_operand" "")
1874         (float_truncate:SF
1875           (match_operand:DF 1 "general_operand" "")))]
1876   "TARGET_68881 || TARGET_FPA"
1877   "")
1878
1879 (define_insn ""
1880   [(set (match_operand:SF 0 "general_operand" "=x,y")
1881         (float_truncate:SF
1882           (match_operand:DF 1 "general_operand" "xH,rmF")))]
1883   "TARGET_FPA"
1884   "fpdtos %y1,%0")
1885
1886 ;; On the '040 we can truncate in a register accurately and easily.
1887 (define_insn ""
1888   [(set (match_operand:SF 0 "general_operand" "=f")
1889         (float_truncate:SF
1890           (match_operand:DF 1 "general_operand" "fmG")))]
1891   "TARGET_68040_ONLY"
1892   "*
1893 {
1894   if (FP_REG_P (operands[1]))
1895     return \"f%$move%.x %1,%0\";
1896   return \"f%$move%.d %f1,%0\";
1897 }")
1898
1899 (define_insn ""
1900   [(set (match_operand:SF 0 "general_operand" "=dm")
1901         (float_truncate:SF
1902           (match_operand:DF 1 "general_operand" "f")))]
1903   "TARGET_68881"
1904   "fmove%.s %f1,%0")
1905 \f
1906 ;; Conversion between fixed point and floating point.
1907 ;; Note that among the fix-to-float insns
1908 ;; the ones that start with SImode come first.
1909 ;; That is so that an operand that is a CONST_INT
1910 ;; (and therefore lacks a specific machine mode).
1911 ;; will be recognized as SImode (which is always valid)
1912 ;; rather than as QImode or HImode.
1913
1914 (define_expand "floatsisf2"
1915   [(set (match_operand:SF 0 "general_operand" "")
1916         (float:SF (match_operand:SI 1 "general_operand" "")))]
1917   "TARGET_68881 || TARGET_FPA"
1918   "")
1919
1920 (define_insn ""
1921   [(set (match_operand:SF 0 "general_operand" "=y,x")
1922         (float:SF (match_operand:SI 1 "general_operand" "rmi,x")))]
1923   "TARGET_FPA"
1924   "fpltos %1,%0")
1925
1926 (define_insn ""
1927   [(set (match_operand:SF 0 "general_operand" "=f")
1928         (float:SF (match_operand:SI 1 "general_operand" "dmi")))]
1929   "TARGET_68881"
1930   "f%$move%.l %1,%0")
1931
1932 (define_expand "floatsidf2"
1933   [(set (match_operand:DF 0 "general_operand" "")
1934         (float:DF (match_operand:SI 1 "general_operand" "")))]
1935   "TARGET_68881 || TARGET_FPA"
1936   "")
1937
1938 (define_insn ""
1939   [(set (match_operand:DF 0 "general_operand" "=y,x")
1940         (float:DF (match_operand:SI 1 "general_operand" "rmi,x")))]
1941   "TARGET_FPA"
1942   "fpltod %1,%0")
1943
1944 (define_insn ""
1945   [(set (match_operand:DF 0 "general_operand" "=f")
1946         (float:DF (match_operand:SI 1 "general_operand" "dmi")))]
1947   "TARGET_68881"
1948   "f%&move%.l %1,%0")
1949
1950 (define_insn "floathisf2"
1951   [(set (match_operand:SF 0 "general_operand" "=f")
1952         (float:SF (match_operand:HI 1 "general_operand" "dmn")))]
1953   "TARGET_68881"
1954   "f%$move%.w %1,%0")
1955
1956 (define_insn "floathidf2"
1957   [(set (match_operand:DF 0 "general_operand" "=f")
1958         (float:DF (match_operand:HI 1 "general_operand" "dmn")))]
1959   "TARGET_68881"
1960   "fmove%.w %1,%0")
1961
1962 (define_insn "floatqisf2"
1963   [(set (match_operand:SF 0 "general_operand" "=f")
1964         (float:SF (match_operand:QI 1 "general_operand" "dmn")))]
1965   "TARGET_68881"
1966   "fmove%.b %1,%0")
1967
1968 (define_insn "floatqidf2"
1969   [(set (match_operand:DF 0 "general_operand" "=f")
1970         (float:DF (match_operand:QI 1 "general_operand" "dmn")))]
1971   "TARGET_68881"
1972   "f%&move%.b %1,%0")
1973
1974 ;; New routines to convert floating-point values to integers
1975 ;; to be used on the '040.  These should be faster than trapping
1976 ;; into the kernel to emulate fintrz.  They should also be faster
1977 ;; than calling the subroutines fixsfsi or fixdfsi.
1978
1979 (define_insn "fix_truncdfsi2"
1980   [(set (match_operand:SI 0 "general_operand" "=dm")
1981         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1982    (clobber (match_scratch:SI 2 "=d"))
1983    (clobber (match_scratch:SI 3 "=d"))]
1984   "TARGET_68881 && TARGET_68040"
1985   "*
1986 {
1987   CC_STATUS_INIT;
1988   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,%!\";
1989 }")
1990
1991 (define_insn "fix_truncdfhi2"
1992   [(set (match_operand:HI 0 "general_operand" "=dm")
1993         (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1994    (clobber (match_scratch:SI 2 "=d"))
1995    (clobber (match_scratch:SI 3 "=d"))]
1996   "TARGET_68881 && TARGET_68040"
1997   "*
1998 {
1999   CC_STATUS_INIT;
2000   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,%!\";
2001 }")
2002
2003 (define_insn "fix_truncdfqi2"
2004   [(set (match_operand:QI 0 "general_operand" "=dm")
2005         (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2006    (clobber (match_scratch:SI 2 "=d"))
2007    (clobber (match_scratch:SI 3 "=d"))]
2008   "TARGET_68881 && TARGET_68040"
2009   "*
2010 {
2011   CC_STATUS_INIT;
2012   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,%!\";
2013 }")
2014
2015 ;; Convert a float to a float whose value is an integer.
2016 ;; This is the first stage of converting it to an integer type.
2017
2018 (define_insn "ftruncdf2"
2019   [(set (match_operand:DF 0 "general_operand" "=f")
2020         (fix:DF (match_operand:DF 1 "general_operand" "fFm")))]
2021   "TARGET_68881 && !TARGET_68040"
2022   "*
2023 {
2024   if (FP_REG_P (operands[1]))
2025     return \"fintrz%.x %f1,%0\";
2026   return \"fintrz%.d %f1,%0\";
2027 }")
2028
2029 (define_insn "ftruncsf2"
2030   [(set (match_operand:SF 0 "general_operand" "=f")
2031         (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))]
2032   "TARGET_68881 && !TARGET_68040"
2033   "*
2034 {
2035   if (FP_REG_P (operands[1]))
2036     return \"fintrz%.x %f1,%0\";
2037   return \"fintrz%.s %f1,%0\";
2038 }")
2039
2040 ;; Convert a float whose value is an integer
2041 ;; to an actual integer.  Second stage of converting float to integer type.
2042 (define_insn "fixsfqi2"
2043   [(set (match_operand:QI 0 "general_operand" "=dm")
2044         (fix:QI (match_operand:SF 1 "general_operand" "f")))]
2045   "TARGET_68881"
2046   "fmove%.b %1,%0")
2047
2048 (define_insn "fixsfhi2"
2049   [(set (match_operand:HI 0 "general_operand" "=dm")
2050         (fix:HI (match_operand:SF 1 "general_operand" "f")))]
2051   "TARGET_68881"
2052   "fmove%.w %1,%0")
2053
2054 (define_insn "fixsfsi2"
2055   [(set (match_operand:SI 0 "general_operand" "=dm")
2056         (fix:SI (match_operand:SF 1 "general_operand" "f")))]
2057   "TARGET_68881"
2058   "fmove%.l %1,%0")
2059
2060 (define_insn "fixdfqi2"
2061   [(set (match_operand:QI 0 "general_operand" "=dm")
2062         (fix:QI (match_operand:DF 1 "general_operand" "f")))]
2063   "TARGET_68881"
2064   "fmove%.b %1,%0")
2065
2066 (define_insn "fixdfhi2"
2067   [(set (match_operand:HI 0 "general_operand" "=dm")
2068         (fix:HI (match_operand:DF 1 "general_operand" "f")))]
2069   "TARGET_68881"
2070   "fmove%.w %1,%0")
2071
2072 (define_insn "fixdfsi2"
2073   [(set (match_operand:SI 0 "general_operand" "=dm")
2074         (fix:SI (match_operand:DF 1 "general_operand" "f")))]
2075   "TARGET_68881"
2076   "fmove%.l %1,%0")
2077
2078 ;; Convert a float to an integer.
2079 ;; On the Sun FPA, this is done in one step.
2080
2081 (define_insn ""
2082   [(set (match_operand:SI 0 "general_operand" "=x,y")
2083         (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "xH,rmF"))))]
2084   "TARGET_FPA"
2085   "fpstol %w1,%0")
2086
2087 (define_insn ""
2088   [(set (match_operand:SI 0 "general_operand" "=x,y")
2089         (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "xH,rmF"))))]
2090   "TARGET_FPA"
2091   "fpdtol %y1,%0")
2092 \f
2093 ;; add instructions
2094
2095 (define_insn "adddi_lshrdi_63"
2096   [(set (match_operand:DI 0 "general_operand" "=d")
2097     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm")
2098             (const_int 63))
2099         (match_dup 1)))
2100    (clobber (match_scratch:SI 2 "=d"))]
2101   ""
2102   "*
2103 {
2104   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2105   if (REG_P (operands[1]) && REGNO (operands[1]) == REGNO (operands[0]))
2106     return
2107     \"move%.l %1,%2\;add%.l %2,%2\;subx%.l %2,%2\;sub%.l %2,%3\;subx%.l %2,%0\";
2108   if (GET_CODE (operands[1]) == REG)
2109     operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2110   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
2111         || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
2112     operands[4] = operands[1];
2113   else
2114     operands[4] = adj_offsettable_operand (operands[1], 4);
2115   if (GET_CODE (operands[1]) == MEM
2116    && GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
2117     output_asm_insn (\"move%.l %4,%3\", operands);
2118   output_asm_insn (\"move%.l %1,%0\;smi %2\", operands);
2119   if (TARGET_68020 || TARGET_5200)
2120     output_asm_insn (\"extb%.l %2\", operands);
2121   else
2122     output_asm_insn (\"ext%.w %2\;ext%.l %2\", operands);
2123   if (GET_CODE (operands[1]) != MEM
2124    || GET_CODE (XEXP (operands[1], 0)) != PRE_DEC)
2125     output_asm_insn (\"move%.l %4,%3\", operands);
2126   return \"sub%.l %2,%3\;subx%.l %2,%0\";
2127 }")
2128
2129 (define_insn "adddi_sexthishl32"
2130   [(set (match_operand:DI 0 "general_operand" "=o,a,*d,*d")
2131     (plus:DI (ashift:DI (sign_extend:DI
2132           (match_operand:HI 1 "general_operand" "rm,rm,rm,rm"))
2133             (const_int 32))
2134         (match_operand:DI 2 "general_operand" "0,0,0,0")))
2135    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
2136   "!TARGET_5200"
2137   "*
2138 {
2139   CC_STATUS_INIT;
2140   if (ADDRESS_REG_P (operands[0]))
2141     return \"add%.w %1,%0\";
2142   else if (ADDRESS_REG_P (operands[3]))
2143     return \"move%.w %1,%3\;add%.l %3,%0\";
2144   else
2145     return \"move%.w %1,%3\;ext%.l %3\;add%.l %3,%0\";
2146 } ")
2147
2148 (define_insn "adddi_dilshr32"
2149   [(set (match_operand:DI 0 "general_operand" "=d,o")
2150 ;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
2151 ;;      (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
2152 ;;            (const_int 32))))]
2153     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,r")
2154             (const_int 32))
2155         (match_operand:DI 2 "general_operand" "0,0")))]
2156   ""
2157   "*
2158 {
2159   CC_STATUS_INIT;
2160   if (GET_CODE (operands[0]) == REG)
2161     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2162   else
2163     operands[2] = adj_offsettable_operand (operands[0], 4);
2164   return \"add%.l %1,%2\;negx%.l %0\;neg%.l %0\";
2165 } ")
2166
2167 (define_insn "adddi_dishl32"
2168   [(set (match_operand:DI 0 "general_operand" "=r,o")
2169 ;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
2170 ;;      (ashift:DI (match_operand:DI 1 "general_operand" "ro")
2171 ;;            (const_int 32))))]
2172     (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro,r")
2173             (const_int 32))
2174         (match_operand:DI 2 "general_operand" "0,0")))]
2175   ""
2176   "*
2177 {
2178   CC_STATUS_INIT;
2179   if (GET_CODE (operands[1]) == REG)
2180     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2181   else
2182     operands[1] = adj_offsettable_operand (operands[1], 4);
2183   return \"add%.l %1,%0\";
2184 } ")
2185
2186 (define_insn "adddi3"
2187   [(set (match_operand:DI 0 "general_operand" "=<,o<>,d,d,d")
2188         (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0,0")
2189                  (match_operand:DI 2 "general_operand" "<,d,no>,d,a")))
2190    (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
2191   ""
2192   "*
2193 {
2194   if (DATA_REG_P (operands[0]))
2195     {
2196       if (DATA_REG_P (operands[2]))
2197         return \"add%.l %R2,%R0\;addx%.l %2,%0\";
2198       else if (GET_CODE (operands[2]) == MEM
2199           && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
2200         {
2201           return \"move%.l %2,%3\;add%.l %2,%R0\;addx%.l %3,%0\";
2202         }
2203       else
2204         {
2205           rtx xoperands[2];
2206           if (GET_CODE (operands[2]) == REG)
2207             operands[1] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2208           else if (GET_CODE (operands[2]) == CONST_DOUBLE)
2209             {
2210               operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
2211               operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[2]));
2212             }
2213           else if (GET_CODE (operands[2]) == CONST_INT)
2214             {
2215               operands[1] = operands[2];
2216               operands[2] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
2217             }
2218           else
2219             operands[1] = adj_offsettable_operand (operands[2], 4);
2220           xoperands[0] = operands[3];
2221           if (GET_CODE (operands[1]) == CONST_INT
2222               && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2223             xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
2224           else
2225             xoperands[1] = operands[2];
2226           output_asm_insn (output_move_simode (xoperands), xoperands);
2227           if (GET_CODE (operands[1]) == CONST_INT)
2228             {
2229               if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
2230                 {
2231 #ifdef NO_ADDSUB_Q
2232                   return \"add%.l %1,%R0\;addx%.l %3,%0\";
2233 #else
2234                   return \"addq%.l %1,%R0\;addx%.l %3,%0\";
2235 #endif
2236                 }
2237               else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2238                 {
2239                   operands[1] = GEN_INT (-INTVAL (operands[1]));
2240 #ifdef NO_ADDSUB_Q
2241                   return \"sub%.l %1,%R0\;subx%.l %3,%0\";
2242 #else
2243                   return \"subq%.l %1,%R0\;subx%.l %3,%0\";
2244 #endif
2245                 }
2246             }
2247           return \"add%.l %1,%R0\;addx%.l %3,%0\";
2248         }
2249     }
2250   else if (GET_CODE (operands[0]) == MEM)
2251     {
2252       if (GET_CODE (operands[2]) == MEM
2253           && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
2254         return \"add%.l %2,%0\;addx%.l %2,%0\";
2255       CC_STATUS_INIT;
2256       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2257         {
2258           operands[1]
2259             = gen_rtx_MEM (SImode,
2260                            gen_rtx_PLUS (VOIDmode, XEXP(operands[0], 0),
2261                                          GEN_INT (-8)));
2262           return \"move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1\";
2263         }
2264       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2265         {
2266           operands[1] = XEXP(operands[0], 0);
2267           return \"add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1\";
2268         }
2269       else
2270         {
2271           operands[1] = adj_offsettable_operand (operands[0], 4);
2272           return \"add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\";
2273         }
2274     }
2275   else
2276     abort ();
2277 } ")
2278
2279 (define_insn "addsi_lshrsi_31"
2280   [(set (match_operand:SI 0 "general_operand" "=dm")
2281     (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm")
2282             (const_int 31))
2283         (match_dup 1)))]
2284   ""
2285   "*
2286 {
2287   operands[2] = operands[0];
2288   operands[3] = gen_label_rtx();
2289   if (GET_CODE (operands[0]) == MEM)
2290     {
2291       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2292         operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2293       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2294         operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2295     }
2296   output_asm_insn (\"move%.l %1,%0\", operands);
2297 #ifdef MOTOROLA
2298   output_asm_insn (\"jbpl %l3\", operands);
2299 #else
2300   output_asm_insn (\"jpl %l3\", operands);
2301 #endif
2302 #ifndef NO_ADDSUB_Q
2303   output_asm_insn (\"addq%.l %#1,%2\", operands);
2304 #else
2305   output_asm_insn (\"add%.l %#1,%2\", operands);
2306 #endif
2307   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
2308                                 CODE_LABEL_NUMBER (operands[3]));
2309   return \"\";
2310 }")
2311
2312 (define_expand "addsi3"
2313   [(set (match_operand:SI 0 "general_operand" "")
2314         (plus:SI (match_operand:SI 1 "general_operand" "")
2315                  (match_operand:SI 2 "general_src_operand" "")))]
2316   ""
2317   "")
2318
2319 ;; Note that the middle two alternatives are near-duplicates
2320 ;; in order to handle insns generated by reload.
2321 ;; This is needed since they are not themselves reloaded,
2322 ;; so commutativity won't apply to them.
2323 (define_insn "*addsi3_internal"
2324   [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,d,a")
2325         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0")
2326                  (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))]
2327
2328
2329   "! TARGET_5200"
2330   "* return output_addsi3 (operands);")
2331
2332 (define_insn "*addsi3_5200"
2333   [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r")
2334         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
2335                  (match_operand:SI 2 "general_src_operand" "d,rJK,a,mrIKLs")))]
2336   "TARGET_5200"
2337   "* return output_addsi3 (operands);")
2338
2339 (define_insn ""
2340   [(set (match_operand:SI 0 "general_operand" "=a")
2341         (plus:SI (match_operand:SI 1 "general_operand" "0")
2342                  (sign_extend:SI
2343                   (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2344   "!TARGET_5200"
2345   "add%.w %2,%0")
2346
2347 (define_insn "addhi3"
2348   [(set (match_operand:HI 0 "general_operand" "=m,r")
2349         (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
2350                  (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2351   "!TARGET_5200"
2352   "*
2353 {
2354   if (GET_CODE (operands[2]) == CONST_INT)
2355     {
2356 #ifndef NO_ADDSUB_Q
2357       /* If the constant would be a negative number when interpreted as
2358          HImode, make it negative.  This is usually, but not always, done
2359          elsewhere in the compiler.  First check for constants out of range,
2360          which could confuse us.  */
2361
2362       if (INTVAL (operands[2]) >= 32768)
2363         operands[2] = GEN_INT (INTVAL (operands[2]) - 65536);
2364
2365       if (INTVAL (operands[2]) > 0
2366           && INTVAL (operands[2]) <= 8)
2367         return \"addq%.w %2,%0\";
2368       if (INTVAL (operands[2]) < 0
2369           && INTVAL (operands[2]) >= -8)
2370         {
2371           operands[2] = GEN_INT (-INTVAL (operands[2]));
2372           return \"subq%.w %2,%0\";
2373         }
2374       /* On the CPU32 it is faster to use two addqw instructions to
2375          add a small integer (8 < N <= 16) to a register.  
2376          Likewise for subqw. */
2377       if (TARGET_CPU32 && REG_P (operands[0]))
2378         {
2379           if (INTVAL (operands[2]) > 8
2380               && INTVAL (operands[2]) <= 16)
2381             {
2382               operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2383               return \"addq%.w %#8,%0\;addq%.w %2,%0\";
2384             }
2385           if (INTVAL (operands[2]) < -8
2386               && INTVAL (operands[2]) >= -16)
2387             {
2388               operands[2] = GEN_INT (-INTVAL (operands[2]) - 8);
2389               return \"subq%.w %#8,%0\;subq%.w %2,%0\";
2390             }
2391         }
2392 #endif
2393       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2394 #ifdef MOTOROLA  
2395             return \"lea (%c2,%0),%0\";
2396 #else
2397             return \"lea %0@(%c2),%0\";
2398 #endif
2399     }
2400   return \"add%.w %2,%0\";
2401 }")
2402
2403 ;; These insns must use MATCH_DUP instead of the more expected
2404 ;; use of a matching constraint because the "output" here is also
2405 ;; an input, so you can't use the matching constraint.  That also means
2406 ;; that you can't use the "%", so you need patterns with the matched
2407 ;; operand in both positions.
2408
2409 (define_insn ""
2410   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2411         (plus:HI (match_dup 0)
2412                  (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2413   "!TARGET_5200"
2414   "*
2415 {
2416   if (GET_CODE (operands[1]) == CONST_INT)
2417     {
2418 #ifndef NO_ADDSUB_Q
2419       /* If the constant would be a negative number when interpreted as
2420          HImode, make it negative.  This is usually, but not always, done
2421          elsewhere in the compiler.  First check for constants out of range,
2422          which could confuse us.  */
2423
2424       if (INTVAL (operands[1]) >= 32768)
2425         operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2426
2427       if (INTVAL (operands[1]) > 0
2428           && INTVAL (operands[1]) <= 8)
2429         return \"addq%.w %1,%0\";
2430       if (INTVAL (operands[1]) < 0
2431           && INTVAL (operands[1]) >= -8)
2432         {
2433           operands[1] = GEN_INT (-INTVAL (operands[1]));
2434           return \"subq%.w %1,%0\";
2435         }
2436       /* On the CPU32 it is faster to use two addqw instructions to
2437          add a small integer (8 < N <= 16) to a register. 
2438          Likewise for subqw. */
2439       if (TARGET_CPU32 && REG_P (operands[0]))
2440         {
2441           if (INTVAL (operands[1]) > 8
2442               && INTVAL (operands[1]) <= 16)
2443             {
2444               operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2445               return \"addq%.w %#8,%0\;addq%.w %1,%0\";
2446             }
2447           if (INTVAL (operands[1]) < -8
2448               && INTVAL (operands[1]) >= -16)
2449             {
2450               operands[1] = GEN_INT (-INTVAL (operands[1]) - 8);
2451               return \"subq%.w %#8,%0\;subq%.w %1,%0\";
2452             }
2453         }
2454 #endif
2455       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2456 #ifdef MOTOROLA  
2457             return \"lea (%c1,%0),%0\";
2458 #else
2459             return \"lea %0@(%c1),%0\";
2460 #endif
2461     }
2462   return \"add%.w %1,%0\";
2463 }")
2464
2465 (define_insn ""
2466   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2467         (plus:HI (match_operand:HI 1 "general_src_operand" "dn,rmSn")
2468                  (match_dup 0)))]
2469   "!TARGET_5200"
2470   "*
2471 {
2472   if (GET_CODE (operands[1]) == CONST_INT)
2473     {
2474 #ifndef NO_ADDSUB_Q
2475       /* If the constant would be a negative number when interpreted as
2476          HImode, make it negative.  This is usually, but not always, done
2477          elsewhere in the compiler.  First check for constants out of range,
2478          which could confuse us.  */
2479
2480       if (INTVAL (operands[1]) >= 32768)
2481         operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2482
2483       if (INTVAL (operands[1]) > 0
2484           && INTVAL (operands[1]) <= 8)
2485         return \"addq%.w %1,%0\";
2486       if (INTVAL (operands[1]) < 0
2487           && INTVAL (operands[1]) >= -8)
2488         {
2489           operands[1] = GEN_INT (-INTVAL (operands[1]));
2490           return \"subq%.w %1,%0\";
2491         }
2492       /* On the CPU32 it is faster to use two addqw instructions to
2493          add a small integer (8 < N <= 16) to a register.
2494          Likewise for subqw. */
2495       if (TARGET_CPU32 && REG_P (operands[0])) 
2496         {
2497           if (INTVAL (operands[1]) > 8
2498               && INTVAL (operands[1]) <= 16)
2499             {
2500               operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2501               return \"addq%.w %#8,%0\;addq%.w %1,%0\";
2502             }
2503           if (INTVAL (operands[1]) < -8
2504               && INTVAL (operands[1]) >= -16)
2505             {
2506               operands[1] = GEN_INT (-INTVAL (operands[1]) - 8);
2507               return \"subq%.w %#8,%0\;subq%.w %1,%0\";
2508             }
2509         }
2510 #endif
2511       if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
2512 #ifdef MOTOROLA  
2513             return \"lea (%c1,%0),%0\";
2514 #else
2515             return \"lea %0@(%c1),%0\";
2516 #endif
2517     }
2518   return \"add%.w %1,%0\";
2519 }")
2520
2521 (define_insn "addqi3"
2522   [(set (match_operand:QI 0 "general_operand" "=m,d")
2523         (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
2524                  (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2525   "!TARGET_5200"
2526   "*
2527 {
2528 #ifndef NO_ADDSUB_Q
2529   if (GET_CODE (operands[2]) == CONST_INT)
2530     {
2531       if (INTVAL (operands[2]) >= 128)
2532         operands[2] = GEN_INT (INTVAL (operands[2]) - 256);
2533
2534       if (INTVAL (operands[2]) > 0
2535           && INTVAL (operands[2]) <= 8)
2536         return \"addq%.b %2,%0\";
2537       if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
2538        {
2539          operands[2] = GEN_INT (-INTVAL (operands[2]));
2540          return \"subq%.b %2,%0\";
2541        }
2542     }
2543 #endif
2544   return \"add%.b %2,%0\";
2545 }")
2546
2547 (define_insn ""
2548   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2549         (plus:QI (match_dup 0)
2550                  (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2551   "!TARGET_5200"
2552   "*
2553 {
2554 #ifndef NO_ADDSUB_Q
2555   if (GET_CODE (operands[1]) == CONST_INT)
2556     {
2557       if (INTVAL (operands[1]) >= 128)
2558         operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2559
2560       if (INTVAL (operands[1]) > 0
2561           && INTVAL (operands[1]) <= 8)
2562         return \"addq%.b %1,%0\";
2563       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2564        {
2565          operands[1] = GEN_INT (-INTVAL (operands[1]));
2566          return \"subq%.b %1,%0\";
2567        }
2568     }
2569 #endif
2570   return \"add%.b %1,%0\";
2571 }")
2572
2573 (define_insn ""
2574   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2575         (plus:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
2576                  (match_dup 0)))]
2577   "!TARGET_5200"
2578   "*
2579 {
2580 #ifndef NO_ADDSUB_Q
2581   if (GET_CODE (operands[1]) == CONST_INT)
2582     {
2583       if (INTVAL (operands[1]) >= 128)
2584         operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2585
2586       if (INTVAL (operands[1]) > 0
2587           && INTVAL (operands[1]) <= 8)
2588         return \"addq%.b %1,%0\";
2589       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2590        {
2591          operands[1] = GEN_INT (-INTVAL (operands[1]));
2592          return \"subq%.b %1,%0\";
2593        }
2594     }
2595 #endif
2596   return \"add%.b %1,%0\";
2597 }")
2598
2599 (define_expand "adddf3"
2600   [(set (match_operand:DF 0 "general_operand" "")
2601         (plus:DF (match_operand:DF 1 "general_operand" "")
2602                  (match_operand:DF 2 "general_operand" "")))]
2603   "TARGET_68881 || TARGET_FPA"
2604   "")
2605
2606 (define_insn ""
2607   [(set (match_operand:DF 0 "general_operand" "=x,y")
2608         (plus:DF (match_operand:DF 1 "general_operand" "%xH,y")
2609                  (match_operand:DF 2 "general_operand" "xH,dmF")))]
2610   "TARGET_FPA"
2611   "*
2612 {
2613   if (rtx_equal_p (operands[0], operands[1]))
2614     return \"fpadd%.d %y2,%0\";
2615   if (rtx_equal_p (operands[0], operands[2]))
2616     return \"fpadd%.d %y1,%0\";
2617   if (which_alternative == 0)
2618     return \"fpadd3%.d %w2,%w1,%0\";
2619   return \"fpadd3%.d %x2,%x1,%0\";
2620 }")
2621
2622 (define_insn ""
2623   [(set (match_operand:DF 0 "general_operand" "=f")
2624         (plus:DF (float:DF (match_operand:SI 2 "general_operand" "dmi"))
2625                  (match_operand:DF 1 "general_operand" "0")))]
2626   "TARGET_68881"
2627   "f%&add%.l %2,%0")
2628
2629 (define_insn ""
2630   [(set (match_operand:DF 0 "general_operand" "=f")
2631         (plus:DF (float:DF (match_operand:HI 2 "general_operand" "dmn"))
2632                  (match_operand:DF 1 "general_operand" "0")))]
2633   "TARGET_68881"
2634   "f%&add%.w %2,%0")
2635
2636 (define_insn ""
2637   [(set (match_operand:DF 0 "general_operand" "=f")
2638         (plus:DF (float:DF (match_operand:QI 2 "general_operand" "dmn"))
2639                  (match_operand:DF 1 "general_operand" "0")))]
2640   "TARGET_68881"
2641   "f%&add%.b %2,%0")
2642
2643 (define_insn ""
2644   [(set (match_operand:DF 0 "general_operand" "=f")
2645         (plus:DF (match_operand:DF 1 "general_operand" "%0")
2646                  (match_operand:DF 2 "general_operand" "fmG")))]
2647   "TARGET_68881"
2648   "*
2649 {
2650   if (REG_P (operands[2]))
2651     return \"f%&add%.x %2,%0\";
2652   return \"f%&add%.d %f2,%0\";
2653 }")
2654
2655 (define_expand "addsf3"
2656   [(set (match_operand:SF 0 "general_operand" "")
2657         (plus:SF (match_operand:SF 1 "general_operand" "")
2658                  (match_operand:SF 2 "general_operand" "")))]
2659   "TARGET_68881 || TARGET_FPA"
2660   "")
2661
2662 (define_insn ""
2663   [(set (match_operand:SF 0 "general_operand" "=x,y")
2664         (plus:SF (match_operand:SF 1 "general_operand" "%xH,y")
2665                  (match_operand:SF 2 "general_operand" "xH,rmF")))]
2666   "TARGET_FPA"
2667   "*
2668 {
2669   if (rtx_equal_p (operands[0], operands[1]))
2670     return \"fpadd%.s %w2,%0\";
2671   if (rtx_equal_p (operands[0], operands[2]))
2672     return \"fpadd%.s %w1,%0\";
2673   if (which_alternative == 0)
2674     return \"fpadd3%.s %w2,%w1,%0\";
2675   return \"fpadd3%.s %2,%1,%0\";
2676 }")
2677
2678 (define_insn ""
2679   [(set (match_operand:SF 0 "general_operand" "=f")
2680         (plus:SF (float:SF (match_operand:SI 2 "general_operand" "dmi"))
2681                  (match_operand:SF 1 "general_operand" "0")))]
2682   "TARGET_68881"
2683   "f%$add%.l %2,%0")
2684
2685 (define_insn ""
2686   [(set (match_operand:SF 0 "general_operand" "=f")
2687         (plus:SF (float:SF (match_operand:HI 2 "general_operand" "dmn"))
2688                  (match_operand:SF 1 "general_operand" "0")))]
2689   "TARGET_68881"
2690   "f%$add%.w %2,%0")
2691
2692 (define_insn ""
2693   [(set (match_operand:SF 0 "general_operand" "=f")
2694         (plus:SF (float:SF (match_operand:QI 2 "general_operand" "dmn"))
2695                  (match_operand:SF 1 "general_operand" "0")))]
2696   "TARGET_68881"
2697   "f%$add%.b %2,%0")
2698
2699 (define_insn ""
2700   [(set (match_operand:SF 0 "general_operand" "=f")
2701         (plus:SF (match_operand:SF 1 "general_operand" "%0")
2702                  (match_operand:SF 2 "general_operand" "fdmF")))]
2703   "TARGET_68881"
2704   "*
2705 {
2706   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2707     return \"f%$add%.x %2,%0\";
2708   return \"f%$add%.s %f2,%0\";
2709 }")
2710 \f
2711 ;; subtract instructions
2712
2713 (define_insn "subdi_sexthishl32"
2714   [(set (match_operand:DI 0 "general_operand" "=o,a,*d,*d")
2715     (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
2716         (ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm"))
2717             (const_int 32))))
2718    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
2719   "!TARGET_5200"
2720   "*
2721 {
2722   CC_STATUS_INIT;
2723   if (ADDRESS_REG_P (operands[0]))
2724     return \"sub%.w %2,%0\";
2725   else if (ADDRESS_REG_P (operands[3]))
2726     return \"move%.w %2,%3\;sub%.l %3,%0\";
2727   else
2728     return \"move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0\";
2729 } ")
2730
2731 (define_insn "subdi_dishl32"
2732   [(set (match_operand:DI 0 "general_operand" "+ro")
2733     (minus:DI (match_dup 0)
2734         (ashift:DI (match_operand:DI 1 "general_operand" "ro")
2735             (const_int 32))))]
2736   ""
2737   "*
2738 {
2739   CC_STATUS_INIT;
2740   if (GET_CODE (operands[1]) == REG)
2741     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2742   else
2743     operands[1] = adj_offsettable_operand (operands[1], 4);
2744   return \"sub%.l %1,%0\";
2745 } ")
2746
2747 (define_insn "subdi3"
2748   [(set (match_operand:DI 0 "general_operand" "=<,o<>,d,d,d")
2749         (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0,0")
2750                  (match_operand:DI 2 "general_operand" "<,d,no>,d,a")))
2751    (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
2752   ""
2753   "*
2754 {
2755   if (DATA_REG_P (operands[0]))
2756     {
2757       if (DATA_REG_P (operands[2]))
2758         return \"sub%.l %R2,%R0\;subx%.l %2,%0\";
2759       else if (GET_CODE (operands[2]) == MEM
2760           && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
2761         {
2762           return \"move%.l %2,%3\;sub%.l %2,%R0\;subx%.l %3,%0\";
2763         }
2764       else
2765         {
2766           rtx xoperands[2];
2767           if (GET_CODE (operands[2]) == REG)
2768             operands[1] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2769           else if (GET_CODE (operands[2]) == CONST_DOUBLE)
2770             {
2771               operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
2772               operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[2]));
2773             }
2774           else if (GET_CODE (operands[2]) == CONST_INT)
2775             {
2776               operands[1] = operands[2];
2777               operands[2] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
2778             }
2779           else
2780             operands[1] = adj_offsettable_operand (operands[2], 4);
2781           xoperands[0] = operands[3];
2782           if (GET_CODE (operands[1]) == CONST_INT
2783               && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2784             xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
2785           else
2786             xoperands[1] = operands[2];
2787           output_asm_insn (output_move_simode (xoperands), xoperands);
2788           if (GET_CODE (operands[1]) == CONST_INT)
2789             {
2790               if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
2791                 {
2792 #ifdef NO_ADDSUB_Q
2793                   return \"sub%.l %1,%R0\;subx%.l %3,%0\";
2794 #else
2795                   return \"subq%.l %1,%R0\;subx%.l %3,%0\";
2796 #endif
2797                 }
2798               else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2799                 {
2800                   operands[1] = GEN_INT (-INTVAL (operands[1]));
2801 #ifdef NO_ADDSUB_Q
2802                   return \"add%.l %1,%R0\;addx%.l %3,%0\";
2803 #else
2804                   return \"addq%.l %1,%R0\;addx%.l %3,%0\";
2805 #endif
2806                 }
2807             }
2808           return \"sub%.l %1,%R0\;subx%.l %3,%0\";
2809         }
2810     }
2811   else if (GET_CODE (operands[0]) == MEM)
2812     {
2813       if (GET_CODE (operands[2]) == MEM
2814           && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
2815         return \"sub%.l %2,%0\;subx%.l %2,%0\";
2816       CC_STATUS_INIT;
2817       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2818         {
2819           operands[1]
2820             = gen_rtx_MEM (SImode,
2821                            gen_rtx_PLUS (VOIDmode, XEXP(operands[0], 0),
2822                                          GEN_INT (-8)));
2823           return \"move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1\";
2824         }
2825       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2826         {
2827           operands[1] = XEXP(operands[0], 0);
2828           return \"sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1\";
2829         }
2830       else
2831         {
2832           operands[1] = adj_offsettable_operand (operands[0], 4);
2833           return \"sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\";
2834         }
2835     }
2836   else
2837     abort ();
2838 } ")
2839
2840 (define_insn "subsi3"
2841   [(set (match_operand:SI 0 "general_operand" "=m,d,a")
2842         (minus:SI (match_operand:SI 1 "general_operand" "0,0,0")
2843                   (match_operand:SI 2 "general_src_operand" "dT,mSrT,mSrs")))]
2844   ""
2845   "sub%.l %2,%0")
2846
2847 (define_insn ""
2848   [(set (match_operand:SI 0 "general_operand" "=a")
2849         (minus:SI (match_operand:SI 1 "general_operand" "0")
2850                   (sign_extend:SI
2851                    (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2852   "!TARGET_5200"
2853   "sub%.w %2,%0")
2854
2855 (define_insn "subhi3"
2856   [(set (match_operand:HI 0 "general_operand" "=m,r")
2857         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2858                   (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2859   "!TARGET_5200"
2860   "sub%.w %2,%0")
2861
2862 (define_insn ""
2863   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2864         (minus:HI (match_dup 0)
2865                   (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2866   "!TARGET_5200"
2867   "sub%.w %1,%0")
2868
2869 (define_insn "subqi3"
2870   [(set (match_operand:QI 0 "general_operand" "=m,d")
2871         (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2872                   (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2873   "!TARGET_5200"
2874   "sub%.b %2,%0")
2875
2876 (define_insn ""
2877   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2878         (minus:QI (match_dup 0)
2879                   (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2880   "!TARGET_5200"
2881   "sub%.b %1,%0")
2882
2883 (define_expand "subdf3"
2884   [(set (match_operand:DF 0 "general_operand" "")
2885         (minus:DF (match_operand:DF 1 "general_operand" "")
2886                   (match_operand:DF 2 "general_operand" "")))]
2887   "TARGET_68881 || TARGET_FPA"
2888   "")
2889
2890 (define_insn ""
2891   [(set (match_operand:DF 0 "general_operand" "=x,y,y")
2892         (minus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF")
2893                   (match_operand:DF 2 "general_operand" "xH,dmF,0")))]
2894   "TARGET_FPA"
2895   "*
2896 {
2897   if (rtx_equal_p (operands[0], operands[2]))
2898     return \"fprsub%.d %y1,%0\";
2899   if (rtx_equal_p (operands[0], operands[1]))
2900     return \"fpsub%.d %y2,%0\";
2901   if (which_alternative == 0)
2902     return \"fpsub3%.d %w2,%w1,%0\";
2903   return \"fpsub3%.d %x2,%x1,%0\";
2904 }")
2905
2906 (define_insn ""
2907   [(set (match_operand:DF 0 "general_operand" "=f")
2908         (minus:DF (match_operand:DF 1 "general_operand" "0")
2909                   (float:DF (match_operand:SI 2 "general_operand" "dmi"))))]
2910   "TARGET_68881"
2911   "f%&sub%.l %2,%0")
2912
2913 (define_insn ""
2914   [(set (match_operand:DF 0 "general_operand" "=f")
2915         (minus:DF (match_operand:DF 1 "general_operand" "0")
2916                   (float:DF (match_operand:HI 2 "general_operand" "dmn"))))]
2917   "TARGET_68881"
2918   "f%&sub%.w %2,%0")
2919
2920 (define_insn ""
2921   [(set (match_operand:DF 0 "general_operand" "=f")
2922         (minus:DF (match_operand:DF 1 "general_operand" "0")
2923                   (float:DF (match_operand:QI 2 "general_operand" "dmn"))))]
2924   "TARGET_68881"
2925   "f%&sub%.b %2,%0")
2926
2927 (define_insn ""
2928   [(set (match_operand:DF 0 "general_operand" "=f")
2929         (minus:DF (match_operand:DF 1 "general_operand" "0")
2930                   (match_operand:DF 2 "general_operand" "fmG")))]
2931   "TARGET_68881"
2932   "*
2933 {
2934   if (REG_P (operands[2]))
2935     return \"f%&sub%.x %2,%0\";
2936   return \"f%&sub%.d %f2,%0\";
2937 }")
2938
2939 (define_expand "subsf3"
2940   [(set (match_operand:SF 0 "general_operand" "")
2941         (minus:SF (match_operand:SF 1 "general_operand" "")
2942                   (match_operand:SF 2 "general_operand" "")))]
2943   "TARGET_68881 || TARGET_FPA"
2944   "")
2945
2946 (define_insn ""
2947   [(set (match_operand:SF 0 "general_operand" "=x,y,y")
2948         (minus:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
2949                   (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
2950   "TARGET_FPA"
2951   "*
2952 {
2953   if (rtx_equal_p (operands[0], operands[2]))
2954     return \"fprsub%.s %w1,%0\";
2955   if (rtx_equal_p (operands[0], operands[1]))
2956     return \"fpsub%.s %w2,%0\";
2957   if (which_alternative == 0)
2958     return \"fpsub3%.s %w2,%w1,%0\";
2959   return \"fpsub3%.s %2,%1,%0\";
2960 }")
2961
2962 (define_insn ""
2963   [(set (match_operand:SF 0 "general_operand" "=f")
2964         (minus:SF (match_operand:SF 1 "general_operand" "0")
2965                   (float:SF (match_operand:SI 2 "general_operand" "dmi"))))]
2966   "TARGET_68881"
2967   "f%$sub%.l %2,%0")
2968
2969 (define_insn ""
2970   [(set (match_operand:SF 0 "general_operand" "=f")
2971         (minus:SF (match_operand:SF 1 "general_operand" "0")
2972                   (float:SF (match_operand:HI 2 "general_operand" "dmn"))))]
2973   "TARGET_68881"
2974   "f%$sub%.w %2,%0")
2975
2976 (define_insn ""
2977   [(set (match_operand:SF 0 "general_operand" "=f")
2978         (minus:SF (match_operand:SF 1 "general_operand" "0")
2979                   (float:SF (match_operand:QI 2 "general_operand" "dmn"))))]
2980   "TARGET_68881"
2981   "f%$sub%.b %2,%0")
2982
2983 (define_insn ""
2984   [(set (match_operand:SF 0 "general_operand" "=f")
2985         (minus:SF (match_operand:SF 1 "general_operand" "0")
2986                   (match_operand:SF 2 "general_operand" "fdmF")))]
2987   "TARGET_68881"
2988   "*
2989 {
2990   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2991     return \"f%$sub%.x %2,%0\";
2992   return \"f%$sub%.s %f2,%0\";
2993 }")
2994 \f
2995 ;; multiply instructions
2996
2997 (define_insn "mulhi3"
2998   [(set (match_operand:HI 0 "general_operand" "=d")
2999         (mult:HI (match_operand:HI 1 "general_operand" "%0")
3000                  (match_operand:HI 2 "general_src_operand" "dmSn")))]
3001   ""
3002   "*
3003 {
3004 #if defined(MOTOROLA) && !defined(CRDS)
3005   return \"muls%.w %2,%0\";
3006 #else
3007   return \"muls %2,%0\";
3008 #endif
3009 }")
3010
3011 (define_insn "mulhisi3"
3012   [(set (match_operand:SI 0 "general_operand" "=d")
3013         (mult:SI (sign_extend:SI
3014                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
3015                  (sign_extend:SI
3016                   (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
3017   ""
3018   "*
3019 {
3020 #if defined(MOTOROLA) && !defined(CRDS)
3021   return \"muls%.w %2,%0\";
3022 #else
3023   return \"muls %2,%0\";
3024 #endif
3025 }")
3026
3027 (define_insn ""
3028   [(set (match_operand:SI 0 "general_operand" "=d")
3029         (mult:SI (sign_extend:SI
3030                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
3031                  (match_operand:SI 2 "const_int_operand" "n")))]
3032   "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
3033   "*
3034 {
3035 #if defined(MOTOROLA) && !defined(CRDS)
3036   return \"muls%.w %2,%0\";
3037 #else
3038   return \"muls %2,%0\";
3039 #endif
3040 }")
3041
3042 (define_expand "mulsi3"
3043   [(set (match_operand:SI 0 "general_operand" "")
3044         (mult:SI (match_operand:SI 1 "general_operand" "")
3045                  (match_operand:SI 2 "general_operand" "")))]
3046   "TARGET_68020 || TARGET_5200"
3047   "")
3048
3049 (define_insn ""
3050   [(set (match_operand:SI 0 "general_operand" "=d")
3051         (mult:SI (match_operand:SI 1 "general_operand" "%0")
3052                  (match_operand:SI 2 "general_src_operand" "dmSTK")))]
3053
3054   "TARGET_68020"
3055   "muls%.l %2,%0")
3056
3057 (define_insn ""
3058   [(set (match_operand:SI 0 "general_operand" "=d")
3059         (mult:SI (match_operand:SI 1 "general_operand" "%0")
3060                  (match_operand:SI 2 "general_operand" "d<Q>")))]
3061   "TARGET_5200"
3062   "muls%.l %2,%0")
3063
3064 (define_insn "umulhisi3"
3065   [(set (match_operand:SI 0 "general_operand" "=d")
3066         (mult:SI (zero_extend:SI
3067                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
3068                  (zero_extend:SI
3069                   (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
3070   ""
3071   "*
3072 {
3073 #if defined(MOTOROLA) && !defined(CRDS)
3074   return \"mulu%.w %2,%0\";
3075 #else
3076   return \"mulu %2,%0\";
3077 #endif
3078 }")
3079
3080 (define_insn ""
3081   [(set (match_operand:SI 0 "general_operand" "=d")
3082         (mult:SI (zero_extend:SI
3083                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
3084                  (match_operand:SI 2 "const_int_operand" "n")))]
3085   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
3086   "*
3087 {
3088 #if defined(MOTOROLA) && !defined(CRDS)
3089   return \"mulu%.w %2,%0\";
3090 #else
3091   return \"mulu %2,%0\";
3092 #endif
3093 }")
3094
3095 ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
3096 ;; proper matching constraint.  This is because the matching is between
3097 ;; the high-numbered word of the DImode operand[0] and operand[1].
3098 (define_expand "umulsidi3"
3099   [(parallel
3100     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1)
3101           (mult:SI (match_operand:SI 1 "register_operand" "")
3102                    (match_operand:SI 2 "nonimmediate_operand" "")))
3103      (set (subreg:SI (match_dup 0) 0)
3104           (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3105                                              (zero_extend:DI (match_dup 2)))
3106                                     (const_int 32))))])]
3107   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3108   "")
3109
3110 (define_insn ""
3111   [(set (match_operand:SI 0 "register_operand" "=d")
3112         (mult:SI (match_operand:SI 1 "register_operand" "%0")
3113                   (match_operand:SI 2 "nonimmediate_operand" "dm")))
3114    (set (match_operand:SI 3 "register_operand" "=d")
3115         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3116                                            (zero_extend:DI (match_dup 2)))
3117                                   (const_int 32))))]
3118   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3119   "mulu%.l %2,%3:%0")
3120
3121 ; Match immediate case.  For 2.4 only match things < 2^31.
3122 ; It's tricky with larger values in these patterns since we need to match
3123 ; values between the two parallel multiplies, between a CONST_DOUBLE and
3124 ; a CONST_INT.
3125 (define_insn ""
3126   [(set (match_operand:SI 0 "register_operand" "=d")
3127         (mult:SI (match_operand:SI 1 "register_operand" "%0")
3128                  (match_operand:SI 2 "const_int_operand" "n")))
3129    (set (match_operand:SI 3 "register_operand" "=d")
3130         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3131                                            (match_dup 2))
3132                                   (const_int 32))))]
3133   "TARGET_68020 && !TARGET_68060 && !TARGET_5200
3134    && (unsigned) INTVAL (operands[2]) <= 0x7fffffff"
3135   "mulu%.l %2,%3:%0")
3136
3137 (define_expand "mulsidi3"
3138   [(parallel
3139     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1)
3140           (mult:SI (match_operand:SI 1 "register_operand" "")
3141                    (match_operand:SI 2 "nonimmediate_operand" "")))
3142      (set (subreg:SI (match_dup 0) 0)
3143           (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3144                                              (sign_extend:DI (match_dup 2)))
3145                                     (const_int 32))))])]
3146   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3147   "")
3148
3149 (define_insn ""
3150   [(set (match_operand:SI 0 "register_operand" "=d")
3151         (mult:SI (match_operand:SI 1 "register_operand" "%0")
3152                  (match_operand:SI 2 "nonimmediate_operand" "dm")))
3153    (set (match_operand:SI 3 "register_operand" "=d")
3154         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3155                                            (sign_extend:DI (match_dup 2)))
3156                                   (const_int 32))))]
3157   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3158   "muls%.l %2,%3:%0")
3159
3160 (define_insn ""
3161   [(set (match_operand:SI 0 "register_operand" "=d")
3162         (mult:SI (match_operand:SI 1 "register_operand" "%0")
3163                  (match_operand:SI 2 "const_sint32_operand" "")))
3164    (set (match_operand:SI 3 "register_operand" "=d")
3165         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3166                                            (match_dup 2))
3167                                   (const_int 32))))]
3168   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3169   "muls%.l %2,%3:%0")
3170
3171 (define_expand "umulsi3_highpart"
3172   [(parallel
3173     [(set (match_operand:SI 0 "register_operand" "")
3174           (truncate:SI
3175            (lshiftrt:DI
3176             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3177                      (zero_extend:DI (match_operand:SI 2 "general_operand" "")))
3178             (const_int 32))))
3179      (clobber (match_dup 3))])]
3180   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3181   "
3182 {
3183   operands[3] = gen_reg_rtx (SImode);
3184   if (GET_CODE (operands[2]) == CONST_INT
3185       || GET_CODE (operands[2]) == CONST_DOUBLE)
3186     {
3187       if (! const_uint32_operand (operands[2], VOIDmode))
3188         abort ();
3189       /* We have to adjust the operand order for the matching constraints.  */
3190       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[3],
3191                                              operands[1], operands[2]));
3192       DONE;
3193     }
3194 }")
3195
3196 (define_insn ""
3197   [(set (match_operand:SI 0 "register_operand" "=d")
3198         (truncate:SI
3199          (lshiftrt:DI
3200           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "%1"))
3201                    (zero_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
3202           (const_int 32))))
3203    (clobber (match_operand:SI 1 "register_operand" "=d"))]
3204   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3205   "mulu%.l %3,%0:%1")
3206
3207 (define_insn "const_umulsi3_highpart"
3208   [(set (match_operand:SI 0 "register_operand" "=d")
3209         (truncate:SI
3210          (lshiftrt:DI
3211           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "1"))
3212                    (match_operand 3 "const_uint32_operand" ""))
3213           (const_int 32))))
3214    (clobber (match_operand:SI 1 "register_operand" "=d"))]
3215   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3216   "mulu%.l %3,%0:%1")
3217
3218 (define_expand "smulsi3_highpart"
3219   [(parallel
3220     [(set (match_operand:SI 0 "register_operand" "")
3221           (truncate:SI
3222            (lshiftrt:DI
3223             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3224                      (sign_extend:DI (match_operand:SI 2 "general_operand" "")))
3225             (const_int 32))))
3226      (clobber (match_dup 3))])]
3227   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3228   "
3229 {
3230   operands[3] = gen_reg_rtx (SImode);
3231   if (GET_CODE (operands[2]) == CONST_INT
3232       || GET_CODE (operands[2]) == CONST_DOUBLE)
3233     {
3234       if (! const_sint32_operand (operands[2], VOIDmode))
3235         abort ();
3236       /* We have to adjust the operand order for the matching constraints.  */
3237       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[3],
3238                                              operands[1], operands[2]));
3239       DONE;
3240     }
3241 }")
3242
3243 (define_insn ""
3244   [(set (match_operand:SI 0 "register_operand" "=d")
3245         (truncate:SI
3246          (lshiftrt:DI
3247           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "%1"))
3248                    (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
3249           (const_int 32))))
3250    (clobber (match_operand:SI 1 "register_operand" "=d"))]
3251   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3252   "muls%.l %3,%0:%1")
3253
3254 (define_insn "const_smulsi3_highpart"
3255   [(set (match_operand:SI 0 "register_operand" "=d")
3256         (truncate:SI
3257          (lshiftrt:DI
3258           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1"))
3259                    (match_operand 3 "const_sint32_operand" ""))
3260           (const_int 32))))
3261    (clobber (match_operand:SI 1 "register_operand" "=d"))]
3262   "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
3263   "muls%.l %3,%0:%1")
3264
3265 (define_expand "muldf3"
3266   [(set (match_operand:DF 0 "general_operand" "")
3267         (mult:DF (match_operand:DF 1 "general_operand" "")
3268                  (match_operand:DF 2 "general_operand" "")))]
3269   "TARGET_68881 || TARGET_FPA"
3270   "")
3271
3272 (define_insn ""
3273   [(set (match_operand:DF 0 "general_operand" "=x,y")
3274         (mult:DF (match_operand:DF 1 "general_operand" "%xH,y")
3275                  (match_operand:DF 2 "general_operand" "xH,rmF")))]
3276   "TARGET_FPA"
3277   "*
3278 {
3279   if (rtx_equal_p (operands[1], operands[2]))
3280     return \"fpsqr%.d %y1,%0\";
3281   if (rtx_equal_p (operands[0], operands[1]))
3282     return \"fpmul%.d %y2,%0\";
3283   if (rtx_equal_p (operands[0], operands[2]))
3284     return \"fpmul%.d %y1,%0\";
3285   if (which_alternative == 0)
3286     return \"fpmul3%.d %w2,%w1,%0\";
3287   return \"fpmul3%.d %x2,%x1,%0\";
3288 }")
3289
3290 (define_insn ""
3291   [(set (match_operand:DF 0 "general_operand" "=f")
3292         (mult:DF (float:DF (match_operand:SI 2 "general_operand" "dmi"))
3293                  (match_operand:DF 1 "general_operand" "0")))]
3294   "TARGET_68881"
3295   "f%&mul%.l %2,%0")
3296
3297 (define_insn ""
3298   [(set (match_operand:DF 0 "general_operand" "=f")
3299         (mult:DF (float:DF (match_operand:HI 2 "general_operand" "dmn"))
3300                  (match_operand:DF 1 "general_operand" "0")))]
3301   "TARGET_68881"
3302   "f%&mul%.w %2,%0")
3303
3304 (define_insn ""
3305   [(set (match_operand:DF 0 "general_operand" "=f")
3306         (mult:DF (float:DF (match_operand:QI 2 "general_operand" "dmn"))
3307                  (match_operand:DF 1 "general_operand" "0")))]
3308   "TARGET_68881"
3309   "f%&mul%.b %2,%0")
3310
3311 (define_insn ""
3312   [(set (match_operand:DF 0 "general_operand" "=f")
3313         (mult:DF (match_operand:DF 1 "general_operand" "%0")
3314                  (match_operand:DF 2 "general_operand" "fmG")))]
3315   "TARGET_68881"
3316   "*
3317 {
3318   if (GET_CODE (operands[2]) == CONST_DOUBLE
3319       && floating_exact_log2 (operands[2]) && !TARGET_68040 && !TARGET_68060)
3320     {
3321       int i = floating_exact_log2 (operands[2]);
3322       operands[2] = GEN_INT (i);
3323       return \"fscale%.l %2,%0\";
3324     }
3325   if (REG_P (operands[2]))
3326     return \"f%&mul%.x %2,%0\";
3327   return \"f%&mul%.d %f2,%0\";
3328 }")
3329
3330 (define_expand "mulsf3"
3331   [(set (match_operand:SF 0 "general_operand" "")
3332         (mult:SF (match_operand:SF 1 "general_operand" "")
3333                  (match_operand:SF 2 "general_operand" "")))]
3334   "TARGET_68881 || TARGET_FPA"
3335   "")
3336
3337 (define_insn ""
3338   [(set (match_operand:SF 0 "general_operand" "=x,y")
3339         (mult:SF (match_operand:SF 1 "general_operand" "%xH,y")
3340                  (match_operand:SF 2 "general_operand" "xH,rmF")))]
3341   "TARGET_FPA"
3342   "*
3343 {
3344   if (rtx_equal_p (operands[1], operands[2]))
3345     return \"fpsqr%.s %w1,%0\";
3346   if (rtx_equal_p (operands[0], operands[1]))
3347     return \"fpmul%.s %w2,%0\";
3348   if (rtx_equal_p (operands[0], operands[2]))
3349     return \"fpmul%.s %w1,%0\";
3350   if (which_alternative == 0)
3351     return \"fpmul3%.s %w2,%w1,%0\";
3352   return \"fpmul3%.s %2,%1,%0\";
3353 }")
3354
3355 (define_insn ""
3356   [(set (match_operand:SF 0 "general_operand" "=f")
3357         (mult:SF (float:SF (match_operand:SI 2 "general_operand" "dmi"))
3358                  (match_operand:SF 1 "general_operand" "0")))]
3359   "TARGET_68881"
3360   "*
3361 {
3362   return (TARGET_68040_ONLY
3363           ? \"fsmul%.l %2,%0\"
3364           : \"fsglmul%.l %2,%0\");
3365 }")
3366
3367 (define_insn ""
3368   [(set (match_operand:SF 0 "general_operand" "=f")
3369         (mult:SF (float:SF (match_operand:HI 2 "general_operand" "dmn"))
3370                  (match_operand:SF 1 "general_operand" "0")))]
3371   "TARGET_68881"
3372   "*
3373 {
3374   return (TARGET_68040_ONLY
3375           ? \"fsmul%.w %2,%0\"
3376           : \"fsglmul%.w %2,%0\");
3377 }")
3378
3379 (define_insn ""
3380   [(set (match_operand:SF 0 "general_operand" "=f")
3381         (mult:SF (float:SF (match_operand:QI 2 "general_operand" "dmn"))
3382                  (match_operand:SF 1 "general_operand" "0")))]
3383   "TARGET_68881"
3384   "*
3385 {
3386   return (TARGET_68040_ONLY
3387           ? \"fsmul%.b %2,%0\"
3388           : \"fsglmul%.b %2,%0\");
3389 }")
3390
3391 (define_insn ""
3392   [(set (match_operand:SF 0 "general_operand" "=f")
3393         (mult:SF (match_operand:SF 1 "general_operand" "%0")
3394                  (match_operand:SF 2 "general_operand" "fdmF")))]
3395   "TARGET_68881"
3396   "*
3397 {
3398 #ifdef FSGLMUL_USE_S
3399   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3400     return (TARGET_68040_ONLY
3401             ? \"fsmul%.s %2,%0\"
3402             : \"fsglmul%.s %2,%0\");
3403 #else
3404   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3405     return (TARGET_68040_ONLY
3406             ? \"fsmul%.x %2,%0\"
3407             : \"fsglmul%.x %2,%0\");
3408 #endif
3409   return (TARGET_68040_ONLY
3410           ? \"fsmul%.s %f2,%0\"
3411           : \"fsglmul%.s %f2,%0\");
3412 }")
3413 \f
3414 ;; divide instructions
3415
3416 (define_expand "divdf3"
3417   [(set (match_operand:DF 0 "general_operand" "")
3418         (div:DF (match_operand:DF 1 "general_operand" "")
3419                 (match_operand:DF 2 "general_operand" "")))]
3420   "TARGET_68881 || TARGET_FPA"
3421   "")
3422
3423 (define_insn ""
3424   [(set (match_operand:DF 0 "general_operand" "=x,y,y")
3425         (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF")
3426                 (match_operand:DF 2 "general_operand" "xH,rmF,0")))]
3427   "TARGET_FPA"
3428   "*
3429 {
3430   if (rtx_equal_p (operands[0], operands[2]))
3431     return \"fprdiv%.d %y1,%0\";
3432   if (rtx_equal_p (operands[0], operands[1]))
3433     return \"fpdiv%.d %y2,%0\";
3434   if (which_alternative == 0)
3435     return \"fpdiv3%.d %w2,%w1,%0\";
3436   return \"fpdiv3%.d %x2,%x1,%x0\";
3437 }")
3438
3439 (define_insn ""
3440   [(set (match_operand:DF 0 "general_operand" "=f")
3441         (div:DF (match_operand:DF 1 "general_operand" "0")
3442                 (float:DF (match_operand:SI 2 "general_operand" "dmi"))))]
3443   "TARGET_68881"
3444   "f%&div%.l %2,%0")
3445
3446 (define_insn ""
3447   [(set (match_operand:DF 0 "general_operand" "=f")
3448         (div:DF (match_operand:DF 1 "general_operand" "0")
3449                 (float:DF (match_operand:HI 2 "general_operand" "dmn"))))]
3450   "TARGET_68881"
3451   "f%&div%.w %2,%0")
3452
3453 (define_insn ""
3454   [(set (match_operand:DF 0 "general_operand" "=f")
3455         (div:DF (match_operand:DF 1 "general_operand" "0")
3456                 (float:DF (match_operand:QI 2 "general_operand" "dmn"))))]
3457   "TARGET_68881"
3458   "f%&div%.b %2,%0")
3459
3460 (define_insn ""
3461   [(set (match_operand:DF 0 "general_operand" "=f")
3462         (div:DF (match_operand:DF 1 "general_operand" "0")
3463                 (match_operand:DF 2 "general_operand" "fmG")))]
3464   "TARGET_68881"
3465   "*
3466 {
3467   if (REG_P (operands[2]))
3468     return \"f%&div%.x %2,%0\";
3469   return \"f%&div%.d %f2,%0\";
3470 }")
3471
3472 (define_expand "divsf3"
3473   [(set (match_operand:SF 0 "general_operand" "")
3474         (div:SF (match_operand:SF 1 "general_operand" "")
3475                 (match_operand:SF 2 "general_operand" "")))]
3476   "TARGET_68881 || TARGET_FPA"
3477   "")
3478
3479 (define_insn ""
3480   [(set (match_operand:SF 0 "general_operand" "=x,y,y")
3481         (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
3482                 (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
3483   "TARGET_FPA"
3484   "*
3485 {
3486   if (rtx_equal_p (operands[0], operands[1]))
3487     return \"fpdiv%.s %w2,%0\";
3488   if (rtx_equal_p (operands[0], operands[2]))
3489     return \"fprdiv%.s %w1,%0\";
3490   if (which_alternative == 0)
3491     return \"fpdiv3%.s %w2,%w1,%0\";
3492   return \"fpdiv3%.s %2,%1,%0\";
3493 }")
3494
3495 (define_insn ""
3496   [(set (match_operand:SF 0 "general_operand" "=f")
3497         (div:SF (match_operand:SF 1 "general_operand" "0")
3498                 (float:SF (match_operand:SI 2 "general_operand" "dmi"))))]
3499   "TARGET_68881"
3500   "*
3501 {
3502   return (TARGET_68040_ONLY
3503           ? \"fsdiv%.l %2,%0\"
3504           : \"fsgldiv%.l %2,%0\");
3505 }")
3506
3507 (define_insn ""
3508   [(set (match_operand:SF 0 "general_operand" "=f")
3509         (div:SF (match_operand:SF 1 "general_operand" "0")
3510                 (float:SF (match_operand:HI 2 "general_operand" "dmn"))))]
3511   "TARGET_68881"
3512   "*
3513 {
3514   return (TARGET_68040_ONLY
3515           ? \"fsdiv%.w %2,%0\"
3516           : \"fsgldiv%.w %2,%0\");
3517 }")
3518
3519 (define_insn ""
3520   [(set (match_operand:SF 0 "general_operand" "=f")
3521         (div:SF (match_operand:SF 1 "general_operand" "0")
3522                 (float:SF (match_operand:QI 2 "general_operand" "dmn"))))]
3523   "TARGET_68881"
3524   "*
3525 {
3526   return (TARGET_68040_ONLY
3527           ? \"fsdiv%.b %2,%0\"
3528           : \"fsgldiv%.b %2,%0\");
3529 }")
3530
3531 (define_insn ""
3532   [(set (match_operand:SF 0 "general_operand" "=f")
3533         (div:SF (match_operand:SF 1 "general_operand" "0")
3534                 (match_operand:SF 2 "general_operand" "fdmF")))]
3535   "TARGET_68881"
3536   "*
3537 {
3538 #ifdef FSGLDIV_USE_S
3539   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3540     return (TARGET_68040_ONLY
3541             ? \"fsdiv%.s %2,%0\"
3542             : \"fsgldiv%.s %2,%0\");
3543 #else
3544   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3545     return (TARGET_68040_ONLY
3546             ? \"fsdiv%.x %2,%0\"
3547             : \"fsgldiv%.x %2,%0\");
3548 #endif
3549   return (TARGET_68040_ONLY
3550           ? \"fsdiv%.s %f2,%0\"
3551           : \"fsgldiv%.s %f2,%0\");
3552 }")
3553 \f
3554 ;; Remainder instructions.
3555
3556 (define_insn "divmodsi4"
3557   [(set (match_operand:SI 0 "general_operand" "=d")
3558         (div:SI (match_operand:SI 1 "general_operand" "0")
3559                 (match_operand:SI 2 "general_src_operand" "dmSTK")))
3560    (set (match_operand:SI 3 "general_operand" "=d")
3561         (mod:SI (match_dup 1) (match_dup 2)))]
3562   "TARGET_68020 && !TARGET_5200"
3563   "*
3564 {
3565   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3566     return \"divs%.l %2,%0\";
3567   else
3568     return \"divsl%.l %2,%3:%0\";
3569 }")
3570
3571 (define_insn "udivmodsi4"
3572   [(set (match_operand:SI 0 "general_operand" "=d")
3573         (udiv:SI (match_operand:SI 1 "general_operand" "0")
3574                  (match_operand:SI 2 "general_src_operand" "dmSTK")))
3575    (set (match_operand:SI 3 "general_operand" "=d")
3576         (umod:SI (match_dup 1) (match_dup 2)))]
3577   "TARGET_68020 && !TARGET_5200"
3578   "*
3579 {
3580   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3581     return \"divu%.l %2,%0\";
3582   else
3583     return \"divul%.l %2,%3:%0\";
3584 }")
3585
3586 (define_insn "divmodhi4"
3587   [(set (match_operand:HI 0 "general_operand" "=d")
3588         (div:HI (match_operand:HI 1 "general_operand" "0")
3589                 (match_operand:HI 2 "general_src_operand" "dmSKT")))
3590    (set (match_operand:HI 3 "general_operand" "=d")
3591         (mod:HI (match_dup 1) (match_dup 2)))]
3592   "!TARGET_5200"
3593   "*
3594 {
3595 #ifdef MOTOROLA
3596   output_asm_insn (\"ext%.l %0\;divs%.w %2,%0\", operands);
3597 #else
3598   output_asm_insn (\"extl %0\;divs %2,%0\", operands);
3599 #endif
3600   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3601     {
3602       CC_STATUS_INIT;
3603       return \"move%.l %0,%3\;swap %3\";
3604     }
3605   else
3606     return \"\";
3607 }")
3608
3609 (define_insn "udivmodhi4"
3610   [(set (match_operand:HI 0 "general_operand" "=d")
3611         (udiv:HI (match_operand:HI 1 "general_operand" "0")
3612                  (match_operand:HI 2 "general_src_operand" "dmSKT")))
3613    (set (match_operand:HI 3 "general_operand" "=d")
3614         (umod:HI (match_dup 1) (match_dup 2)))]
3615   "!TARGET_5200"
3616   "*
3617 {
3618 #ifdef MOTOROLA
3619   output_asm_insn (\"and%.l %#0xFFFF,%0\;divu%.w %2,%0\", operands);
3620 #else
3621   output_asm_insn (\"and%.l %#0xFFFF,%0\;divu %2,%0\", operands);
3622 #endif
3623   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3624     {
3625       CC_STATUS_INIT;
3626       return \"move%.l %0,%3\;swap %3\";
3627     }
3628   else
3629     return \"\";
3630 }")
3631 \f
3632 ;; logical-and instructions
3633
3634 ;; "anddi3" is mainly here to help combine().
3635 (define_insn "anddi3"
3636   [(set (match_operand:DI 0 "general_operand" "=o,d")
3637         (and:DI (match_operand:DI 1 "general_operand" "%0,0")
3638                 (match_operand:DI 2 "general_operand" "dn,don")))]
3639   "!TARGET_5200"
3640   "*
3641 {
3642   CC_STATUS_INIT;
3643   /* We can get CONST_DOUBLE, but also const1_rtx etc. */
3644   if (GET_CODE (operands[2]) == CONST_DOUBLE
3645      || GET_CODE (operands[2]) == CONST_INT)
3646     {
3647       rtx hi, lo;
3648
3649       if (GET_CODE (operands[2]) == CONST_DOUBLE)
3650         {
3651           hi = GEN_INT (CONST_DOUBLE_HIGH (operands[2]));
3652           lo = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
3653         }
3654       else
3655         {
3656           lo = operands[2];
3657           hi = INTVAL (lo) < 0 ? constm1_rtx : const0_rtx;
3658         }
3659       switch (INTVAL (hi))
3660         {
3661           case 0 :
3662             output_asm_insn (\"clr%.l %0\", operands);
3663             break;
3664           case -1 :
3665             break;
3666           default :
3667             {
3668             rtx xoperands[3];
3669
3670             xoperands[0] = operands[0];
3671             xoperands[2] = hi;
3672             output_asm_insn (output_andsi3 (xoperands), xoperands);
3673             }
3674         }
3675       if (GET_CODE (operands[0]) == REG)
3676         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3677       else
3678         operands[0] = adj_offsettable_operand (operands[0], 4);
3679       switch (INTVAL (lo))
3680         {
3681           case 0 :
3682             output_asm_insn (\"clr%.l %0\", operands);
3683             break;
3684           case -1 :
3685             break;
3686           default :
3687             {
3688             rtx xoperands[3];
3689
3690             xoperands[0] = operands[0];
3691             xoperands[2] = lo;
3692             output_asm_insn (output_andsi3 (xoperands), xoperands);
3693             }
3694         }
3695       return \"\";
3696     }
3697   if (GET_CODE (operands[0]) != REG)
3698     {
3699       operands[1] = adj_offsettable_operand (operands[0], 4);
3700       return \"and%.l %2,%0\;and%.l %R2,%1\";
3701     }
3702   if (GET_CODE (operands[2]) != REG)
3703     {
3704       operands[1] = adj_offsettable_operand (operands[2], 4);
3705       return \"and%.l %2,%0\;and%.l %1,%R0\";
3706     }
3707   return \"and%.l %2,%0\;and%.l %R2,%R0\";
3708 }")
3709
3710 ;; Prevent AND from being made with sp.  This doesn't exist in the machine
3711 ;; and reload will cause inefficient code.  Since sp is a FIXED_REG, we
3712 ;; can't allocate pseudos into it.
3713
3714 (define_expand "andsi3"
3715   [(set (match_operand:SI 0 "not_sp_operand" "")
3716         (and:SI (match_operand:SI 1 "general_operand" "")
3717                 (match_operand:SI 2 "general_src_operand" "")))]
3718   ""
3719   "")
3720
3721 (define_insn "andsi3_internal"
3722   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3723         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3724                 (match_operand:SI 2 "general_src_operand" "dKT,dmSM")))]
3725   "!TARGET_5200"
3726   "*
3727 {
3728   return output_andsi3 (operands);
3729 }")
3730
3731 (define_insn "andsi3_5200"
3732   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3733         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3734                 (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
3735   "TARGET_5200"
3736   "and%.l %2,%0")
3737
3738 (define_insn "andhi3"
3739   [(set (match_operand:HI 0 "general_operand" "=m,d")
3740         (and:HI (match_operand:HI 1 "general_operand" "%0,0")
3741                 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
3742   "!TARGET_5200"
3743   "and%.w %2,%0")
3744
3745 (define_insn ""
3746   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3747         (and:HI (match_dup 0)
3748                 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
3749   "!TARGET_5200"
3750   "and%.w %1,%0")
3751
3752 (define_insn ""
3753   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3754         (and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
3755                 (match_dup 0)))]
3756   "!TARGET_5200"
3757   "and%.w %1,%0")
3758
3759 (define_insn "andqi3"
3760   [(set (match_operand:QI 0 "general_operand" "=m,d")
3761         (and:QI (match_operand:QI 1 "general_operand" "%0,0")
3762                 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
3763   "!TARGET_5200"
3764   "and%.b %2,%0")
3765
3766 (define_insn ""
3767   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3768         (and:QI (match_dup 0)
3769                 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
3770   "!TARGET_5200"
3771   "and%.b %1,%0")
3772
3773 (define_insn ""
3774   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3775         (and:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
3776                 (match_dup 0)))]
3777   "!TARGET_5200"
3778   "and%.b %1,%0")
3779 \f
3780 ;; inclusive-or instructions
3781
3782 (define_insn "iordi_zext"
3783   [(set (match_operand:DI 0 "general_operand" "=o,d")
3784     (ior:DI (zero_extend:DI (match_operand 1 "general_operand" "dn,dmn"))
3785         (match_operand:DI 2 "general_operand" "0,0")))]
3786   "!TARGET_5200"
3787   "*
3788 {
3789   int byte_mode;
3790
3791   CC_STATUS_INIT;
3792   if (GET_CODE (operands[0]) == REG)
3793     operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
3794   else
3795     operands[0] = adj_offsettable_operand (operands[0], 4);
3796   if (GET_MODE (operands[1]) == SImode)
3797     return \"or%.l %1,%0\";
3798   byte_mode = (GET_MODE (operands[1]) == QImode);
3799   if (GET_CODE (operands[0]) == MEM)
3800     operands[0] = adj_offsettable_operand (operands[0], byte_mode ? 3 : 2);
3801   if (byte_mode)
3802     return \"or%.b %1,%0\";
3803   else
3804     return \"or%.w %1,%0\";
3805 }")
3806
3807 ;; "iordi3" is mainly here to help combine().
3808 (define_insn "iordi3"
3809   [(set (match_operand:DI 0 "general_operand" "=o,d")
3810         (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
3811                 (match_operand:DI 2 "general_operand" "dn,don")))]
3812   "!TARGET_5200"
3813   "*
3814 {
3815   CC_STATUS_INIT;
3816   /* We can get CONST_DOUBLE, but also const1_rtx etc. */
3817   if (GET_CODE (operands[2]) == CONST_DOUBLE
3818      || GET_CODE (operands[2]) == CONST_INT)
3819     {
3820       rtx hi, lo;
3821
3822       if (GET_CODE (operands[2]) == CONST_DOUBLE)
3823         {
3824           hi = GEN_INT (CONST_DOUBLE_HIGH (operands[2]));
3825           lo = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
3826         }
3827       else
3828         {
3829           lo = operands[2];
3830           hi = INTVAL (lo) < 0 ? constm1_rtx : const0_rtx;
3831         }
3832       switch (INTVAL (hi))
3833         {
3834           case 0 :
3835             break;
3836           case -1 :
3837             /* FIXME : a scratch register would be welcome here if operand[0]
3838                is not a register */
3839             output_asm_insn (\"move%.l %#-1,%0\", operands);
3840             break;
3841           default :
3842             {
3843             rtx xoperands[3];
3844
3845             xoperands[0] = operands[0];
3846             xoperands[2] = hi;
3847             output_asm_insn (output_iorsi3 (xoperands), xoperands);
3848             }
3849         }
3850       if (GET_CODE (operands[0]) == REG)
3851         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3852       else
3853         operands[0] = adj_offsettable_operand (operands[0], 4);
3854       switch (INTVAL (lo))
3855         {
3856           case 0 :
3857             break;
3858           case -1 :
3859             /* FIXME : a scratch register would be welcome here if operand[0]
3860                is not a register */
3861             output_asm_insn (\"move%.l %#-1,%R0\", operands);
3862             break;
3863           default :
3864             {
3865             rtx xoperands[3];
3866
3867             xoperands[0] = operands[0];
3868             xoperands[2] = lo;
3869             output_asm_insn (output_iorsi3 (xoperands), xoperands);
3870             }
3871         }
3872       return \"\";
3873     }
3874   if (GET_CODE (operands[0]) != REG)
3875     {
3876       operands[1] = adj_offsettable_operand (operands[0], 4);
3877       return \"or%.l %2,%0\;or%.l %R2,%1\";
3878     }
3879   if (GET_CODE (operands[2]) != REG)
3880     {
3881       operands[1] = adj_offsettable_operand (operands[2], 4);
3882       return \"or%.l %2,%0\;or%.l %1,%R0\";
3883     }
3884   return \"or%.l %2,%0\;or%.l %R2,%R0\";
3885 }")
3886
3887 (define_expand "iorsi3"
3888   [(set (match_operand:SI 0 "general_operand" "")
3889         (ior:SI (match_operand:SI 1 "general_operand" "")
3890                 (match_operand:SI 2 "general_src_operand" "")))]
3891   ""
3892   "")
3893
3894 (define_insn "iorsi3_internal"
3895   [(set (match_operand:SI 0 "general_operand" "=m,d")
3896         (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3897                 (match_operand:SI 2 "general_src_operand" "dKT,dmSMT")))]
3898   "! TARGET_5200"
3899   "*
3900 {
3901   return output_iorsi3 (operands);
3902 }")
3903
3904 (define_insn "iorsi3_5200"
3905   [(set (match_operand:SI 0 "general_operand" "=m,d")
3906         (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3907                 (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
3908   "TARGET_5200"
3909   "or%.l %2,%0")
3910
3911 (define_insn "iorhi3"
3912   [(set (match_operand:HI 0 "general_operand" "=m,d")
3913         (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
3914                 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
3915   "!TARGET_5200"
3916   "or%.w %2,%0")
3917
3918 (define_insn ""
3919   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3920         (ior:HI (match_dup 0)
3921                 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
3922   "!TARGET_5200"
3923   "or%.w %1,%0")
3924
3925 (define_insn ""
3926   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3927         (ior:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
3928                 (match_dup 0)))]
3929   "!TARGET_5200"
3930   "or%.w %1,%0")
3931
3932 (define_insn "iorqi3"
3933   [(set (match_operand:QI 0 "general_operand" "=m,d")
3934         (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
3935                 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
3936   "!TARGET_5200"
3937   "or%.b %2,%0")
3938
3939 (define_insn ""
3940   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3941         (ior:QI (match_dup 0)
3942                 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
3943   "!TARGET_5200"
3944   "or%.b %1,%0")
3945
3946 (define_insn ""
3947   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3948         (ior:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
3949                 (match_dup 0)))]
3950   "!TARGET_5200"
3951   "or%.b %1,%0")
3952
3953 ;; On all 68k models, this makes faster code in a special case.
3954 ;; See also ashlsi_16, ashrsi_16 and lshrsi_16.
3955
3956 (define_insn "iorsi_zexthi_ashl16"
3957   [(set (match_operand:SI 0 "general_operand" "=&d")
3958     (ior:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rmn"))
3959         (ashift:SI (match_operand:SI 2 "general_operand" "or")
3960             (const_int 16))))]
3961   ""
3962   "*
3963 {
3964   CC_STATUS_INIT;
3965   if (GET_CODE (operands[2]) != REG)
3966       operands[2] = adj_offsettable_operand (operands[2], 2);
3967   if (GET_CODE (operands[2]) != REG
3968   || REGNO (operands[2]) != REGNO (operands[0]))
3969     output_asm_insn (\"move%.w %2,%0\", operands);
3970   return \"swap %0\;mov%.w %1,%0\";
3971 }")
3972
3973 (define_insn "iorsi_zext"
3974   [(set (match_operand:SI 0 "general_operand" "=o,d")
3975     (ior:SI (zero_extend:SI (match_operand 1 "general_operand" "dn,dmn"))
3976         (match_operand:SI 2 "general_operand" "0,0")))]
3977   "!TARGET_5200"
3978   "*
3979 {
3980   int byte_mode;
3981
3982   CC_STATUS_INIT;
3983   byte_mode = (GET_MODE (operands[1]) == QImode);
3984   if (GET_CODE (operands[0]) == MEM)
3985     operands[0] = adj_offsettable_operand (operands[0], byte_mode ? 3 : 2);
3986   if (byte_mode)
3987     return \"or%.b %1,%0\";
3988   else
3989     return \"or%.w %1,%0\";
3990 }")
3991 \f
3992 ;; xor instructions
3993
3994 ;; "xordi3" is mainly here to help combine().
3995 (define_insn "xordi3"
3996   [(set (match_operand:DI 0 "general_operand" "=od")
3997         (xor:DI (match_operand:DI 1 "general_operand" "%0")
3998                 (match_operand:DI 2 "general_operand" "dn")))]
3999   "!TARGET_5200"
4000   "*
4001 {
4002   CC_STATUS_INIT;
4003   /* We can get CONST_DOUBLE, but also const1_rtx etc. */
4004   if (GET_CODE (operands[2]) == CONST_DOUBLE
4005      || GET_CODE (operands[2]) == CONST_INT)
4006     {
4007       rtx hi, lo;
4008
4009       if (GET_CODE (operands[2]) == CONST_DOUBLE)
4010         {
4011           hi = GEN_INT (CONST_DOUBLE_HIGH (operands[2]));
4012           lo = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4013         }
4014       else
4015         {
4016           lo = operands[2];
4017           hi = INTVAL (lo) < 0 ? constm1_rtx : const0_rtx;
4018         }
4019       switch (INTVAL (hi))
4020         {
4021           case 0 :
4022             break;
4023           case -1 :
4024             output_asm_insn (\"not%.l %0\", operands);
4025             break;
4026           default :
4027             /* FIXME : a scratch register would be welcome here if
4028                -128 <= INTVAL (hi) < -1 */
4029             {
4030             rtx xoperands[3];
4031
4032             xoperands[0] = operands[0];
4033             xoperands[2] = hi;
4034             output_asm_insn (output_xorsi3 (xoperands), xoperands);
4035             }
4036         }
4037       if (GET_CODE (operands[0]) == REG)
4038         operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4039       else
4040         operands[0] = adj_offsettable_operand (operands[0], 4);
4041       switch (INTVAL (lo))
4042         {
4043           case 0 :
4044             break;
4045           case -1 :
4046             output_asm_insn (\"not%.l %0\", operands);
4047             break;
4048           default :
4049             /* FIXME : a scratch register would be welcome here if
4050                -128 <= INTVAL (lo) < -1 */
4051             operands[2] = lo;
4052             /* FIXME : this should be merged with xorsi3 */
4053             {
4054             rtx xoperands[3];
4055
4056             xoperands[0] = operands[0];
4057             xoperands[2] = lo;
4058             output_asm_insn (output_xorsi3 (xoperands), xoperands);
4059             }
4060         }
4061       return \"\";
4062     }
4063   if (GET_CODE (operands[0]) != REG)
4064     {
4065       operands[1] = adj_offsettable_operand (operands[0], 4);
4066       return \"eor%.l %2,%0\;eor%.l %R2,%1\";
4067     }
4068   if (GET_CODE (operands[2]) != REG)
4069     {
4070       operands[1] = adj_offsettable_operand (operands[2], 4);
4071       return \"eor%.l %2,%0\;eor%.l %1,%R0\";
4072     }
4073   return \"eor%.l %2,%0\;eor%.l %R2,%R0\";
4074 }")
4075
4076 (define_expand "xorsi3"
4077   [(set (match_operand:SI 0 "general_operand" "")
4078         (xor:SI (match_operand:SI 1 "general_operand" "")
4079                 (match_operand:SI 2 "general_operand" "")))]
4080   ""
4081   "")
4082
4083 (define_insn "xorsi3_internal"
4084   [(set (match_operand:SI 0 "general_operand" "=do,m")
4085         (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
4086                 (match_operand:SI 2 "general_operand" "di,dKT")))]
4087
4088   "!TARGET_5200"
4089   "*
4090 {
4091   return output_xorsi3 (operands);
4092 }")
4093
4094 (define_insn "xorsi3_5200"
4095   [(set (match_operand:SI 0 "general_operand" "=dm,d")
4096         (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
4097                 (match_operand:SI 2 "general_operand" "d,Ks")))]
4098   "TARGET_5200"
4099   "eor%.l %2,%0")
4100
4101 (define_insn "xorhi3"
4102   [(set (match_operand:HI 0 "general_operand" "=dm")
4103         (xor:HI (match_operand:HI 1 "general_operand" "%0")
4104                 (match_operand:HI 2 "general_operand" "dn")))]
4105   "!TARGET_5200"
4106   "eor%.w %2,%0")
4107
4108 (define_insn ""
4109   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
4110         (xor:HI (match_dup 0)
4111                 (match_operand:HI 1 "general_operand" "dn")))]
4112   "!TARGET_5200"
4113   "eor%.w %1,%0")
4114
4115 (define_insn ""
4116   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
4117         (xor:HI (match_operand:HI 1 "general_operand" "dn")
4118                 (match_dup 0)))]
4119   "!TARGET_5200"
4120   "eor%.w %1,%0")
4121
4122 (define_insn "xorqi3"
4123   [(set (match_operand:QI 0 "general_operand" "=dm")
4124         (xor:QI (match_operand:QI 1 "general_operand" "%0")
4125                 (match_operand:QI 2 "general_operand" "dn")))]
4126   "!TARGET_5200"
4127   "eor%.b %2,%0")
4128
4129 (define_insn ""
4130   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
4131         (xor:QI (match_dup 0)
4132                 (match_operand:QI 1 "general_operand" "dn")))]
4133   "!TARGET_5200"
4134   "eor%.b %1,%0")
4135
4136 (define_insn ""
4137   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
4138         (xor:QI (match_operand:QI 1 "general_operand" "dn")
4139                 (match_dup 0)))]
4140   "!TARGET_5200"
4141   "eor%.b %1,%0")
4142 \f
4143 ;; negation instructions
4144
4145 (define_expand "negdi2"
4146   [(set (match_operand:DI 0 "general_operand" "")
4147         (neg:DI (match_operand:DI 1 "general_operand" "")))]
4148   ""
4149   "
4150 {
4151   if (TARGET_5200)
4152     emit_insn (gen_negdi2_5200 (operands[0], operands[1]));
4153   else
4154     emit_insn (gen_negdi2_internal (operands[0], operands[1]));
4155   DONE;
4156 }")
4157
4158 (define_insn "negdi2_internal"
4159   [(set (match_operand:DI 0 "general_operand" "=<,do,!*a")
4160         (neg:DI (match_operand:DI 1 "general_operand" "0,0,0")))]
4161   "!TARGET_5200"
4162   "*
4163 {
4164   if (which_alternative == 0)
4165     return \"neg%.l %0\;negx%.l %0\";
4166   if (GET_CODE (operands[0]) == REG)
4167     operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4168   else
4169     operands[1] = adj_offsettable_operand (operands[0], 4);
4170   if (ADDRESS_REG_P (operands[0]))
4171     return \"exg %/d0,%1\;neg%.l %/d0\;exg %/d0,%1\;exg %/d0,%0\;negx%.l %/d0\;exg %/d0,%0\";
4172   else
4173     return \"neg%.l %1\;negx%.l %0\";
4174 } ")
4175
4176 (define_insn "negdi2_5200"
4177   [(set (match_operand:DI 0 "general_operand" "=d")
4178         (neg:DI (match_operand:DI 1 "general_operand" "0")))]
4179   "TARGET_5200"
4180   "*
4181 {
4182   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4183   return \"neg%.l %1\;negx%.l %0\";
4184 } ")
4185
4186 (define_expand "negsi2"
4187   [(set (match_operand:SI 0 "general_operand" "")
4188         (neg:SI (match_operand:SI 1 "general_operand" "")))]
4189   ""
4190   "
4191 {
4192   if (TARGET_5200)
4193     emit_insn (gen_negsi2_5200 (operands[0], operands[1]));
4194   else
4195     emit_insn (gen_negsi2_internal (operands[0], operands[1]));
4196   DONE;
4197 }")
4198
4199 (define_insn "negsi2_internal"
4200   [(set (match_operand:SI 0 "general_operand" "=dm")
4201         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
4202   "!TARGET_5200"
4203   "neg%.l %0")
4204
4205 (define_insn "negsi2_5200"
4206   [(set (match_operand:SI 0 "general_operand" "=d")
4207         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
4208   "TARGET_5200"
4209   "neg%.l %0")
4210
4211 (define_insn "neghi2"
4212   [(set (match_operand:HI 0 "general_operand" "=dm")
4213         (neg:HI (match_operand:HI 1 "general_operand" "0")))]
4214   "!TARGET_5200"
4215   "neg%.w %0")
4216
4217 (define_insn ""
4218   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
4219         (neg:HI (match_dup 0)))]
4220   "!TARGET_5200"
4221   "neg%.w %0")
4222
4223 (define_insn "negqi2"
4224   [(set (match_operand:QI 0 "general_operand" "=dm")
4225         (neg:QI (match_operand:QI 1 "general_operand" "0")))]
4226   "!TARGET_5200"
4227   "neg%.b %0")
4228
4229 (define_insn ""
4230   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
4231         (neg:QI (match_dup 0)))]
4232   "!TARGET_5200"
4233   "neg%.b %0")
4234
4235 ;; If using software floating point, just flip the sign bit.
4236
4237 (define_expand "negsf2"
4238   [(set (match_operand:SF 0 "general_operand" "")
4239         (neg:SF (match_operand:SF 1 "general_operand" "")))]
4240   ""
4241   "
4242 {
4243   if (!TARGET_FPA && !TARGET_68881)
4244     {
4245       rtx result;
4246       rtx target;
4247
4248       target = operand_subword_force (operands[0], 0, SFmode);
4249       result = expand_binop (SImode, xor_optab,
4250                              operand_subword_force (operands[1], 0, SFmode),
4251                              GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
4252       if (result == 0)
4253         abort ();
4254
4255       if (result != target)
4256         emit_move_insn (result, target);
4257
4258       /* Make a place for REG_EQUAL.  */
4259       emit_move_insn (operands[0], operands[0]);
4260       DONE;
4261     }
4262 }")
4263
4264 (define_insn ""
4265   [(set (match_operand:SF 0 "general_operand" "=x,y")
4266         (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
4267   "TARGET_FPA"
4268   "fpneg%.s %w1,%0")
4269
4270 (define_insn ""
4271   [(set (match_operand:SF 0 "general_operand" "=f,d")
4272         (neg:SF (match_operand:SF 1 "general_operand" "fdmF,0")))]
4273   "TARGET_68881"
4274   "*
4275 {
4276   if (DATA_REG_P (operands[0]))
4277     {
4278       operands[1] = GEN_INT (31);
4279       return \"bchg %1,%0\";
4280     }
4281   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
4282     return \"f%$neg%.x %1,%0\";
4283   return \"f%$neg%.s %f1,%0\";
4284 }")
4285
4286 (define_expand "negdf2"
4287   [(set (match_operand:DF 0 "general_operand" "")
4288         (neg:DF (match_operand:DF 1 "general_operand" "")))]
4289   ""
4290   "
4291 {
4292   if (!TARGET_FPA && !TARGET_68881)
4293     {
4294       rtx result;
4295       rtx target;
4296       rtx insns;
4297
4298       start_sequence ();
4299       target = operand_subword (operands[0], 0, 1, DFmode);
4300       result = expand_binop (SImode, xor_optab,
4301                              operand_subword_force (operands[1], 0, DFmode),
4302                              GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
4303       if (result == 0)
4304         abort ();
4305
4306       if (result != target)
4307         emit_move_insn (result, target);
4308
4309       emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
4310                       operand_subword_force (operands[1], 1, DFmode));
4311
4312       insns = get_insns ();
4313       end_sequence ();
4314
4315       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
4316       DONE;
4317     }
4318 }")
4319
4320 (define_insn ""
4321   [(set (match_operand:DF 0 "general_operand" "=x,y")
4322         (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
4323   "TARGET_FPA"
4324   "fpneg%.d %y1, %0")
4325
4326 (define_insn ""
4327   [(set (match_operand:DF 0 "general_operand" "=f,d")
4328         (neg:DF (match_operand:DF 1 "general_operand" "fmF,0")))]
4329   "TARGET_68881"
4330   "*
4331 {
4332   if (DATA_REG_P (operands[0]))
4333     {
4334       operands[1] = GEN_INT (31);
4335       return \"bchg %1,%0\";
4336     }
4337   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
4338     return \"f%&neg%.x %1,%0\";
4339   return \"f%&neg%.d %f1,%0\";
4340 }")
4341 \f
4342 ;; Sqrt instruction for the 68881
4343
4344 (define_insn "sqrtsf2"
4345   [(set (match_operand:SF 0 "general_operand" "=f")
4346         (sqrt:SF (match_operand:SF 1 "general_operand" "fm")))]
4347   "TARGET_68881"
4348   "*
4349 {
4350   if (FP_REG_P (operands[1]))
4351     return \"f%$sqrt%.x %1,%0\";
4352   else
4353     return \"f%$sqrt%.s %1,%0\";
4354 }")
4355
4356 (define_insn "sqrtdf2"
4357   [(set (match_operand:DF 0 "general_operand" "=f")
4358         (sqrt:DF (match_operand:DF 1 "general_operand" "fm")))]
4359   "TARGET_68881"
4360   "*
4361 {
4362   if (FP_REG_P (operands[1]))
4363     return \"f%&sqrt%.x %1,%0\";
4364   else
4365     return \"f%&sqrt%.d %1,%0\";
4366 }")
4367
4368 ;; Absolute value instructions
4369 ;; If using software floating point, just zero the sign bit.
4370
4371 (define_expand "abssf2"
4372   [(set (match_operand:SF 0 "general_operand" "")
4373         (abs:SF (match_operand:SF 1 "general_operand" "")))]
4374   ""
4375   "
4376 {
4377   if (!TARGET_FPA && !TARGET_68881)
4378     {
4379       rtx result;
4380       rtx target;
4381
4382       target = operand_subword_force (operands[0], 0, SFmode);
4383       result = expand_binop (SImode, and_optab,
4384                              operand_subword_force (operands[1], 0, SFmode),
4385                              GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
4386       if (result == 0)
4387         abort ();
4388
4389       if (result != target)
4390         emit_move_insn (result, target);
4391
4392       /* Make a place for REG_EQUAL.  */
4393       emit_move_insn (operands[0], operands[0]);
4394       DONE;
4395     }
4396 }")
4397
4398 (define_insn ""
4399   [(set (match_operand:SF 0 "general_operand" "=x,y")
4400         (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
4401   "TARGET_FPA"
4402   "fpabs%.s %y1,%0")
4403
4404 (define_insn ""
4405   [(set (match_operand:SF 0 "general_operand" "=f")
4406         (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))]
4407   "TARGET_68881"
4408   "*
4409 {
4410   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
4411     return \"f%$abs%.x %1,%0\";
4412   return \"f%$abs%.s %f1,%0\";
4413 }")
4414
4415 (define_expand "absdf2"
4416   [(set (match_operand:DF 0 "general_operand" "")
4417         (abs:DF (match_operand:DF 1 "general_operand" "")))]
4418   ""
4419   "
4420 {
4421   if (!TARGET_FPA && !TARGET_68881)
4422     {
4423       rtx result;
4424       rtx target;
4425       rtx insns;
4426
4427       start_sequence ();
4428       target = operand_subword (operands[0], 0, 1, DFmode);
4429       result = expand_binop (SImode, and_optab,
4430                              operand_subword_force (operands[1], 0, DFmode),
4431                              GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
4432       if (result == 0)
4433         abort ();
4434
4435       if (result != target)
4436         emit_move_insn (result, target);
4437
4438       emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
4439                       operand_subword_force (operands[1], 1, DFmode));
4440
4441       insns = get_insns ();
4442       end_sequence ();
4443
4444       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
4445       DONE;
4446     }
4447 }")
4448
4449 (define_insn ""
4450   [(set (match_operand:DF 0 "general_operand" "=x,y")
4451         (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
4452   "TARGET_FPA"
4453   "fpabs%.d %y1,%0")
4454
4455 (define_insn ""
4456   [(set (match_operand:DF 0 "general_operand" "=f")
4457         (abs:DF (match_operand:DF 1 "general_operand" "fmF")))]
4458   "TARGET_68881"
4459   "*
4460 {
4461   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
4462     return \"f%&abs%.x %1,%0\";
4463   return \"f%&abs%.d %f1,%0\";
4464 }")
4465 \f
4466 ;; one complement instructions
4467
4468 ;; "one_cmpldi2" is mainly here to help combine().
4469 (define_insn "one_cmpldi2"
4470   [(set (match_operand:DI 0 "general_operand" "=dm")
4471         (not:DI (match_operand:DI 1 "general_operand" "0")))]
4472   "!TARGET_5200"
4473   "*
4474 {
4475   CC_STATUS_INIT;
4476   if (GET_CODE (operands[0]) == REG)
4477     operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4478   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC
4479         || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4480     operands[1] = operands[0];
4481   else
4482     operands[1] = adj_offsettable_operand (operands[0], 4);
4483   return \"not%.l %1\;not%.l %0\";
4484 }")
4485
4486 (define_expand "one_cmplsi2"
4487   [(set (match_operand:SI 0 "general_operand" "")
4488         (not:SI (match_operand:SI 1 "general_operand" "")))]
4489   ""
4490   "
4491 {
4492   if (TARGET_5200)
4493     emit_insn (gen_one_cmplsi2_5200 (operands[0], operands[1]));
4494   else
4495     emit_insn (gen_one_cmplsi2_internal (operands[0], operands[1]));
4496   DONE;
4497 }")
4498
4499 (define_insn "one_cmplsi2_internal"
4500   [(set (match_operand:SI 0 "general_operand" "=dm")
4501         (not:SI (match_operand:SI 1 "general_operand" "0")))]
4502   "!TARGET_5200"
4503   "not%.l %0")
4504
4505 (define_insn "one_cmplsi2_5200"
4506   [(set (match_operand:SI 0 "general_operand" "=d")
4507         (not:SI (match_operand:SI 1 "general_operand" "0")))]
4508   "TARGET_5200"
4509   "not%.l %0")
4510
4511 (define_insn "one_cmplhi2"
4512   [(set (match_operand:HI 0 "general_operand" "=dm")
4513         (not:HI (match_operand:HI 1 "general_operand" "0")))]
4514   "!TARGET_5200"
4515   "not%.w %0")
4516
4517 (define_insn ""
4518   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
4519         (not:HI (match_dup 0)))]
4520   "!TARGET_5200"
4521   "not%.w %0")
4522
4523 (define_insn "one_cmplqi2"
4524   [(set (match_operand:QI 0 "general_operand" "=dm")
4525         (not:QI (match_operand:QI 1 "general_operand" "0")))]
4526   "!TARGET_5200"
4527   "not%.b %0")
4528
4529 (define_insn ""
4530   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
4531         (not:QI (match_dup 0)))]
4532   "!TARGET_5200"
4533   "not%.b %0")
4534 \f
4535 ;; arithmetic shift instructions
4536 ;; We don't need the shift memory by 1 bit instruction
4537
4538 (define_insn "ashldi_extsi"
4539   [(set (match_operand:DI 0 "general_operand" "=ro")
4540     (ashift:DI
4541       (match_operator:DI 2 "extend_operator"
4542         [(match_operand:SI 1 "general_operand" "rm")])
4543       (const_int 32)))]
4544   ""
4545   "*
4546 {
4547   CC_STATUS_INIT;
4548   if (GET_CODE (operands[0]) == REG)
4549     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4550   else
4551     operands[2] = adj_offsettable_operand (operands[0], 4);
4552   if (ADDRESS_REG_P (operands[0]))
4553     return \"move%.l %1,%0\;sub%.l %2,%2\";
4554   else
4555     return \"move%.l %1,%0\;clr%.l %2\";
4556 } ")
4557
4558 (define_insn "ashldi_sexthi"
4559   [(set (match_operand:DI 0 "general_operand" "=m,a*d")
4560     (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm,rm"))
4561         (const_int 32)))
4562     (clobber (match_scratch:SI 2 "=a,X"))]
4563   ""
4564   "*
4565 {
4566   CC_STATUS_INIT;
4567   if (GET_CODE (operands[0]) == MEM)
4568     {
4569     if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4570       return \"clr%.l %0\;move%.w %1,%2\;move%.l %2,%0\";
4571     else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
4572       return \"move%.w %1,%2\;move%.l %2,%0\;clr%.l %0\";
4573     else
4574       {
4575         operands[3] = adj_offsettable_operand (operands[0], 4);
4576         return \"move%.w %1,%2\;move%.l %2,%0\;clr%.l %3\";
4577       }
4578     }
4579   else if (DATA_REG_P (operands[0]))
4580     return \"move%.w %1,%0\;ext%.l %0\;clr%.l %R0\";
4581   else
4582     return \"move%.w %1,%0\;sub%.l %R0,%R0\";
4583 } ")
4584
4585 (define_insn "ashldi_const32"
4586   [(set (match_operand:DI 0 "general_operand" "=rm")
4587         (ashift:DI (match_operand:DI 1 "general_operand" "ro")
4588                      (const_int 32)))]
4589   ""
4590   "*
4591 {
4592   CC_STATUS_INIT;
4593   if (GET_CODE (operands[1]) == REG)
4594     operands[3] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
4595   else
4596     operands[3] = adj_offsettable_operand (operands[1], 4);
4597   if (GET_CODE (operands[0]) == REG)
4598     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4599   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4600     return \"clr%.l %0\;move%.l %3,%0\";
4601   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
4602     return \"move%.l %3,%0\;clr%.l %0\";
4603   else
4604     operands[2] = adj_offsettable_operand (operands[0], 4);
4605   if (ADDRESS_REG_P (operands[2]))
4606     return \"move%.l %3,%0\;sub%.l %2,%2\";
4607   else
4608     return \"move%.l %3,%0\;clr%.l %2\";
4609 } ")
4610
4611 ;; The predicate below must be general_operand, because ashldi3 allows that
4612 (define_insn "ashldi_const"
4613   [(set (match_operand:DI 0 "general_operand" "=d")
4614         (ashift:DI (match_operand:DI 1 "general_operand" "0")
4615                      (match_operand 2 "const_int_operand" "n")))]
4616   "(!TARGET_5200
4617     && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4618         || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4619         || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
4620   "*
4621 {
4622   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4623   if (INTVAL (operands[2]) == 1)
4624     return \"add%.l %1,%1\;addx%.l %0,%0\";
4625   else if (INTVAL (operands[2]) == 8)
4626     return \"rol%.l %#8,%1\;rol%.l %#8,%0\;move%.b %1,%0\;clr%.b %1\";
4627   else if (INTVAL (operands[2]) == 16)
4628     return \"swap %1\;swap %0\;move%.w %1,%0\;clr%.w %1\";
4629   else if (INTVAL (operands[2]) == 48)
4630     return \"mov%.l %1,%0\;swap %0\;clr%.l %1\;clr%.w %0\";
4631   else if (INTVAL (operands[2]) == 2)
4632     return \"add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\";
4633   else if (INTVAL (operands[2]) == 3)
4634     return \"add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\";
4635   else /* 32 < INTVAL (operands[2]) <= 63 */
4636     {
4637       operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
4638       output_asm_insn (INTVAL (operands[2]) <= 8 ? \"asl%.l %2,%1\" :
4639                         \"moveq %2,%0\;asl%.l %0,%1\", operands);
4640       return \"mov%.l %1,%0\;moveq %#0,%1\";
4641     }
4642 } ")
4643
4644 (define_expand "ashldi3"
4645   [(set (match_operand:DI 0 "general_operand" "")
4646         (ashift:DI (match_operand:DI 1 "general_operand" "")
4647                      (match_operand 2 "const_int_operand" "")))]
4648   "!TARGET_5200"
4649   "
4650 {
4651   /* ???  This is a named pattern like this is not allowed to FAIL based
4652      on its operands.  */
4653   if (GET_CODE (operands[2]) != CONST_INT
4654       || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
4655           && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
4656           && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
4657     FAIL;
4658 } ")
4659
4660 ;; On most 68k models, this makes faster code in a special case.
4661
4662 (define_insn "ashlsi_16"
4663   [(set (match_operand:SI 0 "register_operand" "=d")
4664         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4665                    (const_int 16)))]
4666   "!TARGET_68060"
4667   "*
4668 {
4669   CC_STATUS_INIT;
4670   return \"swap %0\;clr%.w %0\";
4671 }")
4672
4673 ;; ashift patterns : use lsl instead of asl, because lsl always clears the
4674 ;; overflow bit, so we must not set CC_NO_OVERFLOW.
4675
4676 ;; On the 68000, this makes faster code in a special case.
4677
4678 (define_insn "ashlsi_17_24"
4679   [(set (match_operand:SI 0 "register_operand" "=d")
4680         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4681                    (match_operand:SI 2 "const_int_operand" "n")))]
4682   "(! TARGET_68020 && !TARGET_5200
4683     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
4684   "*
4685 {
4686   CC_STATUS_INIT;
4687
4688   operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
4689   return \"lsl%.w %2,%0\;swap %0\;clr%.w %0\";
4690 }")
4691
4692 (define_insn "ashlsi3"
4693   [(set (match_operand:SI 0 "register_operand" "=d")
4694         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4695                    (match_operand:SI 2 "general_operand" "dI")))]
4696   ""
4697   "*
4698 {
4699   if (operands[2] == const1_rtx)
4700     {
4701       cc_status.flags = CC_NO_OVERFLOW;
4702       return \"add%.l %0,%0\";
4703     }
4704   return \"lsl%.l %2,%0\";
4705 }")
4706
4707 (define_insn "ashlhi3"
4708   [(set (match_operand:HI 0 "register_operand" "=d")
4709         (ashift:HI (match_operand:HI 1 "register_operand" "0")
4710                    (match_operand:HI 2 "general_operand" "dI")))]
4711   "!TARGET_5200"
4712   "lsl%.w %2,%0")
4713
4714 (define_insn ""
4715   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4716         (ashift:HI (match_dup 0)
4717                    (match_operand:HI 1 "general_operand" "dI")))]
4718   "!TARGET_5200"
4719   "lsl%.w %1,%0")
4720
4721 (define_insn "ashlqi3"
4722   [(set (match_operand:QI 0 "register_operand" "=d")
4723         (ashift:QI (match_operand:QI 1 "register_operand" "0")
4724                    (match_operand:QI 2 "general_operand" "dI")))]
4725   "!TARGET_5200"
4726   "lsl%.b %2,%0")
4727
4728 (define_insn ""
4729   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4730         (ashift:QI (match_dup 0)
4731                    (match_operand:QI 1 "general_operand" "dI")))]
4732   "!TARGET_5200"
4733   "lsl%.b %1,%0")
4734
4735 ;; On most 68k models, this makes faster code in a special case.
4736
4737 (define_insn "ashrsi_16"
4738   [(set (match_operand:SI 0 "register_operand" "=d")
4739         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4740                      (const_int 16)))]
4741   "!TARGET_68060"
4742   "swap %0\;ext%.l %0")
4743
4744 ;; On the 68000, this makes faster code in a special case.
4745
4746 (define_insn ""
4747   [(set (match_operand:SI 0 "register_operand" "=d")
4748         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4749                      (match_operand:SI 2 "const_int_operand" "n")))]
4750   "(! TARGET_68020 && !TARGET_5200
4751     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
4752   "*
4753 {
4754   operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
4755   return \"swap %0\;asr%.w %2,%0\;ext%.l %0\";
4756 }")
4757
4758 (define_insn "subreghi1ashrdi_const32"
4759   [(set (match_operand:HI 0 "general_operand" "=rm")
4760     (subreg:HI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4761             (const_int 32)) 1))]
4762   ""
4763   "*
4764 {
4765   if (GET_CODE (operands[1]) != REG)
4766     operands[1] = adj_offsettable_operand (operands[1], 2);
4767   return \"move%.w %1,%0\";
4768 } ")
4769
4770 (define_insn "subregsi1ashrdi_const32"
4771   [(set (match_operand:SI 0 "general_operand" "=rm")
4772     (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4773             (const_int 32)) 1))]
4774   ""
4775   "*
4776 {
4777   return \"move%.l %1,%0\";
4778 } ")
4779
4780 (define_insn "ashrdi_const32"
4781   [(set (match_operand:DI 0 "register_operand" "=d")
4782         (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4783                      (const_int 32)))]
4784   ""
4785   "*
4786 {
4787   CC_STATUS_INIT;
4788   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4789   if (TARGET_68020)
4790     return \"move%.l %1,%2\;smi %0\;extb%.l %0\";
4791   else
4792     return \"move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0\";
4793 } ")
4794
4795 (define_insn "ashrdi_const32_mem"
4796   [(set (match_operand:DI 0 "general_operand" "=o,<")
4797         (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro,ro")
4798                      (const_int 32)))
4799    (clobber (match_scratch:SI 2 "=d,d"))]
4800   ""
4801   "*
4802 {
4803   CC_STATUS_INIT;
4804   if (which_alternative == 1)
4805     operands[3] = operands[0];
4806   else
4807     operands[3] = adj_offsettable_operand (operands[0], 4);
4808   if (TARGET_68020)
4809     return \"move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0\";
4810   else
4811     return \"move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\";
4812 } ")
4813
4814 ;; The predicate below must be general_operand, because ashrdi3 allows that
4815 (define_insn "ashrdi_const"
4816   [(set (match_operand:DI 0 "general_operand" "=d")
4817         (ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
4818                      (match_operand 2 "const_int_operand" "n")))]
4819   "(!TARGET_5200 
4820     && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4821         || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4822         || INTVAL (operands[2]) == 31
4823         || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
4824   "*
4825 {
4826   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4827   if (INTVAL (operands[2]) == 63)
4828     return \"add%.l %0,%0\;subx%.l %0,%0\;move%.l %0,%1\";
4829   CC_STATUS_INIT;
4830   if (INTVAL (operands[2]) == 1)
4831     return \"asr%.l %#1,%0\;roxr%.l %#1,%1\";
4832   else if (INTVAL (operands[2]) == 8)
4833     return \"move%.b %0,%1\;asr%.l %#8,%0\;ror%.l %#8,%1\";
4834   else if (INTVAL (operands[2]) == 16)
4835     return \"move%.w %0,%1\;clr%.w %0\;swap %1\;ext%.l %0\";
4836   else if (INTVAL (operands[2]) == 48)
4837     return \"swap %0\;ext%.l %0\;move%.l %0,%1\;smi %0\;ext%.w %0\";
4838   else if (INTVAL (operands[2]) == 31)
4839     return \"add%.l %1,%1\;addx%.l %0,%0\;move%.l %0,%1\;subx%.l %0,%0\";
4840   else if (INTVAL (operands[2]) == 2)
4841     return \"asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\";
4842   else if (INTVAL (operands[2]) == 3)
4843     return \"asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\";
4844   else /* 32 < INTVAL (operands[2]) <= 63 */
4845     {
4846       operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
4847       output_asm_insn (INTVAL (operands[2]) <= 8 ? \"asr%.l %2,%0\" :
4848                         \"moveq %2,%1\;asr%.l %1,%0\", operands);
4849       output_asm_insn (\"mov%.l %0,%1\;smi %0\", operands);
4850       return INTVAL (operands[2]) >= 15 ? \"ext%.w %d0\" :
4851              TARGET_68020 ? \"extb%.l %0\" : \"ext%.w %0\;ext%.l %0\";
4852     }
4853 } ")
4854
4855 (define_expand "ashrdi3"
4856   [(set (match_operand:DI 0 "general_operand" "")
4857         (ashiftrt:DI (match_operand:DI 1 "general_operand" "")
4858                      (match_operand 2 "const_int_operand" "")))]
4859   "!TARGET_5200"
4860   "
4861 {
4862   /* ???  This is a named pattern like this is not allowed to FAIL based
4863      on its operands.  */
4864   if (GET_CODE (operands[2]) != CONST_INT
4865       || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
4866           && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
4867           && (INTVAL (operands[2]) < 31 || INTVAL (operands[2]) > 63)))
4868     FAIL;
4869 } ")
4870
4871 ;; On all 68k models, this makes faster code in a special case.
4872
4873 (define_insn "ashrsi_31"
4874   [(set (match_operand:SI 0 "register_operand" "=d")
4875         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4876                      (const_int 31)))]
4877   ""
4878   "*
4879 {
4880   return \"add%.l %0,%0\;subx%.l %0,%0\";
4881 }")
4882
4883 (define_insn "ashrsi3"
4884   [(set (match_operand:SI 0 "register_operand" "=d")
4885         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4886                      (match_operand:SI 2 "general_operand" "dI")))]
4887   ""
4888   "asr%.l %2,%0")
4889
4890 (define_insn "ashrhi3"
4891   [(set (match_operand:HI 0 "register_operand" "=d")
4892         (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
4893                      (match_operand:HI 2 "general_operand" "dI")))]
4894   "!TARGET_5200"
4895   "asr%.w %2,%0")
4896
4897 (define_insn ""
4898   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4899         (ashiftrt:HI (match_dup 0)
4900                      (match_operand:HI 1 "general_operand" "dI")))]
4901   "!TARGET_5200"
4902   "asr%.w %1,%0")
4903
4904 (define_insn "ashrqi3"
4905   [(set (match_operand:QI 0 "register_operand" "=d")
4906         (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
4907                      (match_operand:QI 2 "general_operand" "dI")))]
4908   "!TARGET_5200"
4909   "asr%.b %2,%0")
4910
4911 (define_insn ""
4912   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4913         (ashiftrt:QI (match_dup 0)
4914                      (match_operand:QI 1 "general_operand" "dI")))]
4915   "!TARGET_5200"
4916   "asr%.b %1,%0")
4917 \f
4918 ;; logical shift instructions
4919
4920 ;; commented out because of reload problems in 950612-1.c
4921 ;;(define_insn ""
4922 ;;        [(set (cc0)
4923 ;;            (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
4924 ;;                    (const_int 32)) 1))
4925 ;;        (set (match_operand:SI 1 "general_operand" "=dm")
4926 ;;            (subreg:SI (lshiftrt:DI (match_dup 0)
4927 ;;                    (const_int 32)) 1))]
4928 ;;  ""
4929 ;;  "*
4930 ;;{
4931 ;;  return \"move%.l %0,%1\";
4932 ;;} ")
4933 ;;
4934 ;;(define_insn ""
4935 ;;        [(set (cc0)
4936 ;;            (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
4937 ;;                    (const_int 32)) 0))
4938 ;;        (set (match_operand:DI 1 "general_operand" "=do")
4939 ;;            (lshiftrt:DI (match_dup 0)
4940 ;;                (const_int 32)))]
4941 ;;  ""
4942 ;;  "*
4943 ;;{
4944 ;;  if (GET_CODE (operands[1]) == REG)
4945 ;;    operands[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
4946 ;;  else
4947 ;;    operands[2] = adj_offsettable_operand (operands[1], 4);
4948 ;;  return \"move%.l %0,%2\;clr%.l %1\";
4949 ;;} ")
4950
4951 (define_insn "subreg1lshrdi_const32"
4952   [(set (match_operand:SI 0 "general_operand" "=rm")
4953     (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4954             (const_int 32)) 1))]
4955   ""
4956   "*
4957 {
4958   return \"move%.l %1,%0\";
4959 } ")
4960
4961 (define_insn "lshrdi_const32"
4962   [(set (match_operand:DI 0 "general_operand" "=ro,<,>")
4963         (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,ro,ro")
4964                      (const_int 32)))]
4965   ""
4966   "*
4967 {
4968   CC_STATUS_INIT;
4969   if (which_alternative == 1)
4970     return \"move%.l %1,%0\;clr%.l %0\";
4971   if (which_alternative == 2)
4972     return \"clr%.l %0\;move%.l %1,%0\";
4973   if (GET_CODE (operands[0]) == REG)
4974     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4975   else
4976     operands[2] = adj_offsettable_operand (operands[0], 4);
4977   if (GET_CODE (operands[1]) == REG)
4978     operands[3] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
4979   else
4980     operands[3] = adj_offsettable_operand (operands[1], 4);
4981   if (ADDRESS_REG_P (operands[0]))
4982     return \"move%.l %1,%2\;sub%.l %0,%0\";
4983   else
4984     return \"move%.l %1,%2\;clr%.l %0\";
4985 } ")
4986
4987 ;; The predicate below must be general_operand, because lshrdi3 allows that
4988 (define_insn "lshrdi_const"
4989   [(set (match_operand:DI 0 "general_operand" "=d")
4990         (lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
4991                      (match_operand 2 "const_int_operand" "n")))]
4992   "(!TARGET_5200
4993     && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4994          || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4995          || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
4996   "*
4997 {
4998   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4999   if (INTVAL (operands[2]) == 63)
5000     return \"add%.l %0,%0\;clr%.l %0\;clr%.l %1\;addx%.l %1,%1\";
5001   CC_STATUS_INIT;
5002   if (INTVAL (operands[2]) == 1)
5003     return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\";
5004   else if (INTVAL (operands[2]) == 8)
5005     return \"move%.b %0,%1\;lsr%.l %#8,%0\;ror%.l %#8,%1\";
5006   else if (INTVAL (operands[2]) == 16)
5007     return \"move%.w %0,%1\;clr%.w %0\;swap %1\;swap %0\";
5008   else if (INTVAL (operands[2]) == 48)
5009     return \"move%.l %0,%1\;clr%.w %1\;clr%.l %0\;swap %1\";
5010   else if (INTVAL (operands[2]) == 2)
5011     return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\";
5012   else if (INTVAL (operands[2]) == 3)
5013     return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\";
5014   else /* 32 < INTVAL (operands[2]) <= 63 */
5015     {
5016       operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5017       output_asm_insn (INTVAL (operands[2]) <= 8 ? \"lsr%.l %2,%0\" :
5018                         \"moveq %2,%1\;lsr%.l %1,%0\", operands);
5019       return \"mov%.l %0,%1\;moveq %#0,%0\";
5020     }
5021 } ")
5022
5023 (define_expand "lshrdi3"
5024   [(set (match_operand:DI 0 "general_operand" "")
5025         (lshiftrt:DI (match_operand:DI 1 "general_operand" "")
5026                      (match_operand 2 "const_int_operand" "")))]
5027   "!TARGET_5200"
5028   "
5029 {
5030   /* ???  This is a named pattern like this is not allowed to FAIL based
5031      on its operands.  */
5032   if (GET_CODE (operands[2]) != CONST_INT
5033       || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
5034           && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
5035           && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
5036     FAIL;
5037 } ")
5038
5039 ;; On all 68k models, this makes faster code in a special case.
5040
5041 (define_insn "lshrsi_31"
5042   [(set (match_operand:SI 0 "register_operand" "=d")
5043         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
5044                      (const_int 31)))]
5045   ""
5046   "*
5047 {
5048   return \"add%.l %0,%0\;subx%.l %0,%0\;neg%.l %0\";
5049 }")
5050
5051 ;; On most 68k models, this makes faster code in a special case.
5052
5053 (define_insn "lshrsi_16"
5054   [(set (match_operand:SI 0 "register_operand" "=d")
5055         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
5056                      (const_int 16)))]
5057   "!TARGET_68060"
5058   "*
5059 {
5060   CC_STATUS_INIT;
5061   return \"clr%.w %0\;swap %0\";
5062 }")
5063
5064 ;; On the 68000, this makes faster code in a special case.
5065
5066 (define_insn "lshrsi_17_24"
5067   [(set (match_operand:SI 0 "register_operand" "=d")
5068         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
5069                      (match_operand:SI 2 "const_int_operand" "n")))]
5070   "(! TARGET_68020 && !TARGET_5200
5071     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
5072   "*
5073 {
5074   /* I think lsr%.w sets the CC properly.  */
5075   operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
5076   return \"clr%.w %0\;swap %0\;lsr%.w %2,%0\";
5077 }")
5078
5079 (define_insn "lshrsi3"
5080   [(set (match_operand:SI 0 "register_operand" "=d")
5081         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
5082                      (match_operand:SI 2 "general_operand" "dI")))]
5083   ""
5084   "lsr%.l %2,%0")
5085
5086 (define_insn "lshrhi3"
5087   [(set (match_operand:HI 0 "register_operand" "=d")
5088         (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
5089                      (match_operand:HI 2 "general_operand" "dI")))]
5090   "!TARGET_5200"
5091   "lsr%.w %2,%0")
5092
5093 (define_insn ""
5094   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
5095         (lshiftrt:HI (match_dup 0)
5096                      (match_operand:HI 1 "general_operand" "dI")))]
5097   "!TARGET_5200"
5098   "lsr%.w %1,%0")
5099
5100 (define_insn "lshrqi3"
5101   [(set (match_operand:QI 0 "register_operand" "=d")
5102         (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
5103                      (match_operand:QI 2 "general_operand" "dI")))]
5104   "!TARGET_5200"
5105   "lsr%.b %2,%0")
5106
5107 (define_insn ""
5108   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
5109         (lshiftrt:QI (match_dup 0)
5110                      (match_operand:QI 1 "general_operand" "dI")))]
5111   "!TARGET_5200"
5112   "lsr%.b %1,%0")
5113 \f
5114 ;; rotate instructions
5115
5116 (define_insn "rotlsi3"
5117   [(set (match_operand:SI 0 "register_operand" "=d")
5118         (rotate:SI (match_operand:SI 1 "register_operand" "0")
5119                    (match_operand:SI 2 "general_operand" "dINO")))]
5120   "!TARGET_5200"
5121   "*
5122 {
5123   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)
5124     return \"swap %0\";
5125   else if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 16)
5126     {
5127       operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5128       return \"ror%.l %2,%0\";
5129     }
5130   else
5131     return \"rol%.l %2,%0\";
5132 }")
5133
5134 (define_insn "rotlhi3"
5135   [(set (match_operand:HI 0 "register_operand" "=d")
5136         (rotate:HI (match_operand:HI 1 "register_operand" "0")
5137                    (match_operand:HI 2 "general_operand" "dIP")))]
5138   "!TARGET_5200"
5139   "*
5140 {
5141   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
5142     {
5143       operands[2] = GEN_INT (16 - INTVAL (operands[2]));
5144       return \"ror%.w %2,%0\";
5145     }
5146   else
5147     return \"rol%.w %2,%0\";
5148 }")
5149
5150 (define_insn ""
5151   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
5152         (rotate:HI (match_dup 0)
5153                    (match_operand:HI 1 "general_operand" "dIP")))]
5154   "!TARGET_5200"
5155   "*
5156 {
5157   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
5158     {
5159       operands[2] = GEN_INT (16 - INTVAL (operands[2]));
5160       return \"ror%.w %2,%0\";
5161     }
5162   else
5163     return \"rol%.w %2,%0\";
5164 }")
5165
5166 (define_insn "rotlqi3"
5167   [(set (match_operand:QI 0 "register_operand" "=d")
5168         (rotate:QI (match_operand:QI 1 "register_operand" "0")
5169                    (match_operand:QI 2 "general_operand" "dI")))]
5170   "!TARGET_5200"
5171   "*
5172 {
5173   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
5174     {
5175       operands[2] = GEN_INT (8 - INTVAL (operands[2]));
5176       return \"ror%.b %2,%0\";
5177     }
5178   else
5179     return \"rol%.b %2,%0\";
5180 }")
5181
5182 (define_insn ""
5183   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
5184         (rotate:QI (match_dup 0)
5185                    (match_operand:QI 1 "general_operand" "dI")))]
5186   "!TARGET_5200"
5187   "*
5188 {
5189   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
5190     {
5191       operands[2] = GEN_INT (8 - INTVAL (operands[2]));
5192       return \"ror%.b %2,%0\";
5193     }
5194   else
5195     return \"rol%.b %2,%0\";
5196 }")
5197
5198 (define_insn "rotrsi3"
5199   [(set (match_operand:SI 0 "register_operand" "=d")
5200         (rotatert:SI (match_operand:SI 1 "register_operand" "0")
5201                      (match_operand:SI 2 "general_operand" "dI")))]
5202   "!TARGET_5200"
5203   "ror%.l %2,%0")
5204
5205 (define_insn "rotrhi3"
5206   [(set (match_operand:HI 0 "register_operand" "=d")
5207         (rotatert:HI (match_operand:HI 1 "register_operand" "0")
5208                      (match_operand:HI 2 "general_operand" "dI")))]
5209   "!TARGET_5200"
5210   "ror%.w %2,%0")
5211
5212 (define_insn ""
5213   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
5214         (rotatert:HI (match_dup 0)
5215                      (match_operand:HI 1 "general_operand" "dI")))]
5216   "!TARGET_5200"
5217   "ror%.w %1,%0")
5218
5219 (define_insn "rotrqi3"
5220   [(set (match_operand:QI 0 "register_operand" "=d")
5221         (rotatert:QI (match_operand:QI 1 "register_operand" "0")
5222                      (match_operand:QI 2 "general_operand" "dI")))]
5223   "!TARGET_5200"
5224   "ror%.b %2,%0")
5225
5226 (define_insn ""
5227   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
5228         (rotatert:QI (match_dup 0)
5229                      (match_operand:QI 1 "general_operand" "dI")))]
5230   "!TARGET_5200"
5231   "ror%.b %1,%0")
5232 \f
5233
5234 ;; Bit set/clear in memory byte.
5235
5236 ;; set bit, bit number is int
5237 (define_insn "bsetmemqi"
5238   [(set (match_operand:QI 0 "memory_operand" "+m")
5239         (ior:QI (subreg:QI (ashift:SI (const_int 1)
5240                 (match_operand:SI 1 "general_operand" "d")) 0)
5241         (match_dup 0)))]
5242   ""
5243   "*
5244 {
5245   CC_STATUS_INIT;
5246   return \"bset %1,%0\";
5247 }")
5248
5249 ;; set bit, bit number is (sign/zero)_extended from HImode/QImode
5250 (define_insn ""
5251   [(set (match_operand:QI 0 "memory_operand" "+m")
5252         (ior:QI (subreg:QI (ashift:SI (const_int 1)
5253             (match_operator:SI 2 "extend_operator"
5254                 [(match_operand 1 "general_operand" "d")])) 0)
5255         (match_dup 0)))]
5256   ""
5257   "*
5258 {
5259   CC_STATUS_INIT;
5260   return \"bset %1,%0\";
5261 }")
5262
5263 ;; clear bit, bit number is int
5264 (define_insn "bclrmemqi"
5265   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
5266         (const_int 1)
5267         (minus:SI (const_int 7)
5268             (match_operand:SI 1 "general_operand" "d")))
5269     (const_int 0))]
5270   ""
5271   "*
5272 {
5273   CC_STATUS_INIT;
5274   return \"bclr %1,%0\";
5275 }")
5276
5277 ;; clear bit, bit number is (sign/zero)_extended from HImode/QImode
5278 (define_insn ""
5279   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
5280         (const_int 1)
5281         (minus:SI (const_int 7)
5282             (match_operator:SI 2 "extend_operator"
5283                 [(match_operand 1 "general_operand" "d")])))
5284     (const_int 0))]
5285   ""
5286   "*
5287 {
5288   CC_STATUS_INIT;
5289   return \"bclr %1,%0\";
5290 }")
5291
5292 ;; Special cases of bit-field insns which we should
5293 ;; recognize in preference to the general case.
5294 ;; These handle aligned 8-bit and 16-bit fields,
5295 ;; which can usually be done with move instructions.
5296
5297 ;
5298 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
5299 ; alignment of structure members is specified.
5300 ;
5301 ; The move is allowed to be odd byte aligned, because that's still faster
5302 ; than an odd byte aligned bit field instruction.
5303 ;
5304 (define_insn ""
5305   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5306                          (const_int 32)
5307                          (match_operand:SI 2 "const_int_operand" "n"))
5308         (match_operand:SI 3 "general_src_operand" "rmSi"))]
5309   "TARGET_68020 && TARGET_BITFIELD
5310    && (INTVAL (operands[2]) % 8) == 0
5311    && ! mode_dependent_address_p (XEXP (operands[0], 0))"
5312   "*
5313 {
5314   operands[0]
5315     = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
5316
5317   return \"move%.l %3,%0\";
5318 }")
5319
5320 (define_insn ""
5321   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+do")
5322                          (match_operand:SI 1 "const_int_operand" "n")
5323                          (match_operand:SI 2 "const_int_operand" "n"))
5324         (match_operand:SI 3 "register_operand" "d"))]
5325   "TARGET_68020 && TARGET_BITFIELD
5326    && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
5327    && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
5328    && (GET_CODE (operands[0]) == REG
5329        || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
5330   "*
5331 {
5332   if (REG_P (operands[0]))
5333     {
5334       if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
5335         return \"bfins %3,%0{%b2:%b1}\";
5336     }
5337   else
5338     operands[0]
5339       = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
5340
5341   if (GET_CODE (operands[3]) == MEM)
5342     operands[3] = adj_offsettable_operand (operands[3],
5343                                            (32 - INTVAL (operands[1])) / 8);
5344   if (INTVAL (operands[1]) == 8)
5345     return \"move%.b %3,%0\";
5346   return \"move%.w %3,%0\";
5347 }")
5348
5349
5350 ;
5351 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
5352 ; alignment of structure members is specified.
5353 ;
5354 ; The move is allowed to be odd byte aligned, because that's still faster
5355 ; than an odd byte aligned bit field instruction.
5356 ;
5357 (define_insn ""
5358   [(set (match_operand:SI 0 "general_operand" "=rm")
5359         (zero_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
5360                          (const_int 32)
5361                          (match_operand:SI 3 "const_int_operand" "n")))]
5362   "TARGET_68020 && TARGET_BITFIELD
5363    && (INTVAL (operands[3]) % 8) == 0
5364    && ! mode_dependent_address_p (XEXP (operands[1], 0))"
5365   "*
5366 {
5367   operands[1]
5368     = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
5369
5370   return \"move%.l %1,%0\";
5371 }")
5372
5373 (define_insn ""
5374   [(set (match_operand:SI 0 "general_operand" "=&d")
5375         (zero_extract:SI (match_operand:SI 1 "register_operand" "do")
5376                          (match_operand:SI 2 "const_int_operand" "n")
5377                          (match_operand:SI 3 "const_int_operand" "n")))]
5378   "TARGET_68020 && TARGET_BITFIELD
5379    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
5380    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
5381    && (GET_CODE (operands[1]) == REG
5382        || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
5383   "*
5384 {
5385   cc_status.flags |= CC_NOT_NEGATIVE;
5386   if (REG_P (operands[1]))
5387     {
5388       if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
5389         return \"bfextu %1{%b3:%b2},%0\";
5390     }
5391   else
5392     operands[1]
5393       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
5394
5395   output_asm_insn (\"clr%.l %0\", operands);
5396   if (GET_CODE (operands[0]) == MEM)
5397     operands[0] = adj_offsettable_operand (operands[0],
5398                                            (32 - INTVAL (operands[1])) / 8);
5399   if (INTVAL (operands[2]) == 8)
5400     return \"move%.b %1,%0\";
5401   return \"move%.w %1,%0\";
5402 }")
5403
5404 ;
5405 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
5406 ; alignment of structure members is specified.
5407 ;
5408 ; The move is allowed to be odd byte aligned, because that's still faster
5409 ; than an odd byte aligned bit field instruction.
5410 ;
5411 (define_insn ""
5412   [(set (match_operand:SI 0 "general_operand" "=rm")
5413         (sign_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
5414                          (const_int 32)
5415                          (match_operand:SI 3 "const_int_operand" "n")))]
5416   "TARGET_68020 && TARGET_BITFIELD
5417    && (INTVAL (operands[3]) % 8) == 0
5418    && ! mode_dependent_address_p (XEXP (operands[1], 0))"
5419   "*
5420 {
5421   operands[1]
5422     = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
5423
5424   return \"move%.l %1,%0\";
5425 }")
5426
5427 (define_insn ""
5428   [(set (match_operand:SI 0 "general_operand" "=d")
5429         (sign_extract:SI (match_operand:SI 1 "register_operand" "do")
5430                          (match_operand:SI 2 "const_int_operand" "n")
5431                          (match_operand:SI 3 "const_int_operand" "n")))]
5432   "TARGET_68020 && TARGET_BITFIELD
5433    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
5434    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
5435    && (GET_CODE (operands[1]) == REG
5436        || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
5437   "*
5438 {
5439   if (REG_P (operands[1]))
5440     {
5441       if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
5442         return \"bfexts %1{%b3:%b2},%0\";
5443     }
5444   else
5445     operands[1]
5446       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
5447
5448   if (INTVAL (operands[2]) == 8)
5449     return \"move%.b %1,%0\;extb%.l %0\";
5450   return \"move%.w %1,%0\;ext%.l %0\";
5451 }")
5452 \f
5453 ;; Bit field instructions, general cases.
5454 ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
5455 ;; so that its address is reloaded.
5456
5457 (define_expand "extv"
5458   [(set (match_operand:SI 0 "general_operand" "")
5459         (sign_extract:SI (match_operand:SI 1 "general_operand" "")
5460                          (match_operand:SI 2 "general_operand" "")
5461                          (match_operand:SI 3 "general_operand" "")))]
5462   "TARGET_68020 && TARGET_BITFIELD"
5463   "")
5464
5465 (define_insn ""
5466   [(set (match_operand:SI 0 "general_operand" "=d")
5467         (sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
5468                          (match_operand:SI 2 "general_operand" "di")
5469                          (match_operand:SI 3 "general_operand" "di")))]
5470   "TARGET_68020 && TARGET_BITFIELD"
5471   "bfexts %1{%b3:%b2},%0")
5472
5473 (define_expand "extzv"
5474   [(set (match_operand:SI 0 "general_operand" "")
5475         (zero_extract:SI (match_operand:SI 1 "general_operand" "")
5476                          (match_operand:SI 2 "general_operand" "")
5477                          (match_operand:SI 3 "general_operand" "")))]
5478   "TARGET_68020 && TARGET_BITFIELD"
5479   "")
5480
5481 (define_insn ""
5482   [(set (match_operand:SI 0 "general_operand" "=d,d")
5483         (zero_extract:SI (match_operand:QI 1 "memory_operand" "o,d")
5484                          (match_operand:SI 2 "general_operand" "di,di")
5485                          (match_operand:SI 3 "general_operand" "di,di")))]
5486   "TARGET_68020 && TARGET_BITFIELD"
5487   "*
5488 {
5489   if (GET_CODE (operands[2]) == CONST_INT)
5490     {
5491       if (INTVAL (operands[2]) != 32)
5492         cc_status.flags |= CC_NOT_NEGATIVE;
5493     }
5494   else
5495     {
5496       CC_STATUS_INIT;
5497     }
5498   return \"bfextu %1{%b3:%b2},%0\";
5499 }")
5500
5501 (define_insn ""
5502   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5503                          (match_operand:SI 1 "general_operand" "di")
5504                          (match_operand:SI 2 "general_operand" "di"))
5505         (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
5506                 (match_operand 3 "const_int_operand" "n")))]
5507   "TARGET_68020 && TARGET_BITFIELD
5508    && (INTVAL (operands[3]) == -1
5509        || (GET_CODE (operands[1]) == CONST_INT
5510            && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
5511   "*
5512 {
5513   CC_STATUS_INIT;
5514   return \"bfchg %0{%b2:%b1}\";
5515 }")
5516
5517 (define_insn ""
5518   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5519                          (match_operand:SI 1 "general_operand" "di")
5520                          (match_operand:SI 2 "general_operand" "di"))
5521         (const_int 0))]
5522   "TARGET_68020 && TARGET_BITFIELD"
5523   "*
5524 {
5525   CC_STATUS_INIT;
5526   return \"bfclr %0{%b2:%b1}\";
5527 }")
5528
5529 (define_insn ""
5530   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5531                          (match_operand:SI 1 "general_operand" "di")
5532                          (match_operand:SI 2 "general_operand" "di"))
5533         (const_int -1))]
5534   "TARGET_68020 && TARGET_BITFIELD"
5535   "*
5536 {
5537   CC_STATUS_INIT;
5538   return \"bfset %0{%b2:%b1}\";
5539 }")
5540
5541 (define_expand "insv"
5542   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5543                          (match_operand:SI 1 "general_operand" "")
5544                          (match_operand:SI 2 "general_operand" ""))
5545         (match_operand:SI 3 "register_operand" ""))]
5546   "TARGET_68020 && TARGET_BITFIELD"
5547   "")
5548
5549 (define_insn ""
5550   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5551                          (match_operand:SI 1 "general_operand" "di")
5552                          (match_operand:SI 2 "general_operand" "di"))
5553         (match_operand:SI 3 "register_operand" "d"))]
5554   "TARGET_68020 && TARGET_BITFIELD"
5555   "bfins %3,%0{%b2:%b1}")
5556
5557 ;; Now recognize bit field insns that operate on registers
5558 ;; (or at least were intended to do so).
5559
5560 (define_insn ""
5561   [(set (match_operand:SI 0 "general_operand" "=d")
5562         (sign_extract:SI (match_operand:SI 1 "register_operand" "d")
5563                          (match_operand:SI 2 "general_operand" "di")
5564                          (match_operand:SI 3 "general_operand" "di")))]
5565   "TARGET_68020 && TARGET_BITFIELD"
5566   "bfexts %1{%b3:%b2},%0")
5567
5568 (define_insn ""
5569   [(set (match_operand:SI 0 "general_operand" "=d")
5570         (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
5571                          (match_operand:SI 2 "general_operand" "di")
5572                          (match_operand:SI 3 "general_operand" "di")))]
5573   "TARGET_68020 && TARGET_BITFIELD"
5574   "*
5575 {
5576   if (GET_CODE (operands[2]) == CONST_INT)
5577     {
5578       if (INTVAL (operands[2]) != 32)
5579         cc_status.flags |= CC_NOT_NEGATIVE;
5580     }
5581   else
5582     {
5583       CC_STATUS_INIT;
5584     }
5585   return \"bfextu %1{%b3:%b2},%0\";
5586 }")
5587
5588 (define_insn ""
5589   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5590                          (match_operand:SI 1 "general_operand" "di")
5591                          (match_operand:SI 2 "general_operand" "di"))
5592         (const_int 0))]
5593   "TARGET_68020 && TARGET_BITFIELD"
5594   "*
5595 {
5596   CC_STATUS_INIT;
5597   return \"bfclr %0{%b2:%b1}\";
5598 }")
5599
5600 (define_insn ""
5601   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5602                          (match_operand:SI 1 "general_operand" "di")
5603                          (match_operand:SI 2 "general_operand" "di"))
5604         (const_int -1))]
5605   "TARGET_68020 && TARGET_BITFIELD"
5606   "*
5607 {
5608   CC_STATUS_INIT;
5609   return \"bfset %0{%b2:%b1}\";
5610 }")
5611
5612 (define_insn ""
5613   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5614                          (match_operand:SI 1 "general_operand" "di")
5615                          (match_operand:SI 2 "general_operand" "di"))
5616         (match_operand:SI 3 "register_operand" "d"))]
5617   "TARGET_68020 && TARGET_BITFIELD"
5618   "*
5619 {
5620 #if 0
5621   /* These special cases are now recognized by a specific pattern.  */
5622   if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
5623       && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
5624     return \"move%.w %3,%0\";
5625   if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
5626       && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
5627     return \"move%.b %3,%0\";
5628 #endif
5629   return \"bfins %3,%0{%b2:%b1}\";
5630 }")
5631 \f
5632 ;; Special patterns for optimizing bit-field instructions.
5633
5634 (define_insn ""
5635   [(set (cc0)
5636         (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
5637                          (match_operand:SI 1 "const_int_operand" "n")
5638                          (match_operand:SI 2 "general_operand" "di")))]
5639   "TARGET_68020 && TARGET_BITFIELD"
5640   "*
5641 {
5642   if (operands[1] == const1_rtx
5643       && GET_CODE (operands[2]) == CONST_INT)
5644     {
5645       int width = GET_CODE (operands[0]) == REG ? 31 : 7;
5646       return output_btst (operands,
5647                           GEN_INT (width - INTVAL (operands[2])),
5648                           operands[0],
5649                           insn, 1000);
5650       /* Pass 1000 as SIGNPOS argument so that btst will
5651          not think we are testing the sign bit for an `and'
5652          and assume that nonzero implies a negative result.  */
5653     }
5654   if (INTVAL (operands[1]) != 32)
5655     cc_status.flags = CC_NOT_NEGATIVE;
5656   return \"bftst %0{%b2:%b1}\";
5657 }")
5658
5659
5660 ;;; now handle the register cases
5661 (define_insn ""
5662   [(set (cc0)
5663         (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
5664                          (match_operand:SI 1 "const_int_operand" "n")
5665                          (match_operand:SI 2 "general_operand" "di")))]
5666   "TARGET_68020 && TARGET_BITFIELD"
5667   "*
5668 {
5669   if (operands[1] == const1_rtx
5670       && GET_CODE (operands[2]) == CONST_INT)
5671     {
5672       int width = GET_CODE (operands[0]) == REG ? 31 : 7;
5673       return output_btst (operands,
5674                           GEN_INT (width - INTVAL (operands[2])),
5675                           operands[0],
5676                           insn, 1000);
5677       /* Pass 1000 as SIGNPOS argument so that btst will
5678          not think we are testing the sign bit for an `and'
5679          and assume that nonzero implies a negative result.  */
5680     }
5681   if (INTVAL (operands[1]) != 32)
5682     cc_status.flags = CC_NOT_NEGATIVE;
5683   return \"bftst %0{%b2:%b1}\";
5684 }")
5685 \f
5686 (define_insn "scc0_di"
5687   [(set (match_operand:QI 0 "general_operand" "=dm")
5688     (match_operator 1 "valid_dbcc_comparison_p"
5689       [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
5690   "! TARGET_5200"
5691   "*
5692 {
5693   return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
5694 } ")
5695
5696 (define_insn "scc0_di_5200"
5697   [(set (match_operand:QI 0 "general_operand" "=d")
5698     (match_operator 1 "valid_dbcc_comparison_p"
5699       [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
5700   "TARGET_5200"
5701   "*
5702 {
5703   return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
5704 } ")
5705
5706 (define_insn "scc_di"
5707   [(set (match_operand:QI 0 "general_operand" "=dm,dm")
5708     (match_operator 1 "valid_dbcc_comparison_p"
5709       [(match_operand:DI 2 "general_operand" "ro,r")
5710        (match_operand:DI 3 "general_operand" "r,ro")]))]
5711   "! TARGET_5200"
5712   "*
5713 {
5714   return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
5715 } ")
5716
5717 (define_insn "scc_di_5200"
5718   [(set (match_operand:QI 0 "general_operand" "=d,d")
5719     (match_operator 1 "valid_dbcc_comparison_p"
5720       [(match_operand:DI 2 "general_operand" "ro,r")
5721        (match_operand:DI 3 "general_operand" "r,ro")]))]
5722   "TARGET_5200"
5723   "*
5724 {
5725   return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
5726 } ")
5727
5728 ;; Note that operand 0 of an SCC insn is supported in the hardware as
5729 ;; memory, but we cannot allow it to be in memory in case the address
5730 ;; needs to be reloaded.
5731
5732 (define_expand "seq"
5733   [(set (match_operand:QI 0 "register_operand" "")
5734         (eq:QI (cc0) (const_int 0)))]
5735   ""
5736   "
5737 {
5738   if (TARGET_68060 && m68k_last_compare_had_fp_operands)
5739     {
5740       m68k_last_compare_had_fp_operands = 0;
5741       FAIL;
5742     }
5743 }")
5744
5745 (define_insn ""
5746   [(set (match_operand:QI 0 "register_operand" "=d")
5747         (eq:QI (cc0) (const_int 0)))]
5748   ""
5749   "*
5750   cc_status = cc_prev_status;
5751   OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
5752 ")
5753
5754 (define_expand "sne"
5755   [(set (match_operand:QI 0 "register_operand" "")
5756         (ne:QI (cc0) (const_int 0)))]
5757   ""
5758   "
5759 {
5760   if (TARGET_68060 && m68k_last_compare_had_fp_operands)
5761     {
5762       m68k_last_compare_had_fp_operands = 0;
5763       FAIL;
5764     }
5765 }")
5766
5767 (define_insn ""
5768   [(set (match_operand:QI 0 "register_operand" "=d")
5769         (ne:QI (cc0) (const_int 0)))]
5770   ""
5771   "*
5772   cc_status = cc_prev_status;
5773   OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
5774 ")
5775
5776 (define_expand "sgt"
5777   [(set (match_operand:QI 0 "register_operand" "")
5778         (gt:QI (cc0) (const_int 0)))]
5779   ""
5780   "
5781 {
5782   if (TARGET_68060 && m68k_last_compare_had_fp_operands)
5783     {
5784       m68k_last_compare_had_fp_operands = 0;
5785       FAIL;
5786     }
5787 }")
5788
5789 (define_insn ""
5790   [(set (match_operand:QI 0 "register_operand" "=d")
5791         (gt:QI (cc0) (const_int 0)))]
5792   ""
5793   "*
5794   cc_status = cc_prev_status;
5795   OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0);
5796 ")
5797
5798 (define_expand "sgtu"
5799   [(set (match_operand:QI 0 "register_operand" "")
5800         (gtu:QI (cc0) (const_int 0)))]
5801   ""
5802   "")
5803
5804 (define_insn ""
5805   [(set (match_operand:QI 0 "register_operand" "=d")
5806         (gtu:QI (cc0) (const_int 0)))]
5807   ""
5808   "*
5809    cc_status = cc_prev_status;
5810    return \"shi %0\"; ")
5811
5812 (define_expand "slt"
5813   [(set (match_operand:QI 0 "register_operand" "")
5814         (lt:QI (cc0) (const_int 0)))]
5815   ""
5816   "
5817 {
5818   if (TARGET_68060 && m68k_last_compare_had_fp_operands)
5819     {
5820       m68k_last_compare_had_fp_operands = 0;
5821       FAIL;
5822     }
5823 }")
5824
5825 (define_insn ""
5826   [(set (match_operand:QI 0 "register_operand" "=d")
5827         (lt:QI (cc0) (const_int 0)))]
5828   ""
5829   "*
5830    cc_status = cc_prev_status;
5831    OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
5832
5833 (define_expand "sltu"
5834   [(set (match_operand:QI 0 "register_operand" "")
5835         (ltu:QI (cc0) (const_int 0)))]
5836   ""
5837   "")
5838
5839 (define_insn ""
5840   [(set (match_operand:QI 0 "register_operand" "=d")
5841         (ltu:QI (cc0) (const_int 0)))]
5842   ""
5843   "*
5844    cc_status = cc_prev_status;
5845    return \"scs %0\"; ")
5846
5847 (define_expand "sge"
5848   [(set (match_operand:QI 0 "register_operand" "")
5849         (ge:QI (cc0) (const_int 0)))]
5850   ""
5851   "
5852 {
5853   if (TARGET_68060 && m68k_last_compare_had_fp_operands)
5854     {
5855       m68k_last_compare_had_fp_operands = 0;
5856       FAIL;
5857     }
5858 }")
5859
5860 (define_insn ""
5861   [(set (match_operand:QI 0 "register_operand" "=d")
5862         (ge:QI (cc0) (const_int 0)))]
5863   ""
5864   "*
5865    cc_status = cc_prev_status;
5866    OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
5867
5868 (define_expand "sgeu"
5869   [(set (match_operand:QI 0 "register_operand" "")
5870         (geu:QI (cc0) (const_int 0)))]
5871   ""
5872   "")
5873
5874 (define_insn ""
5875   [(set (match_operand:QI 0 "register_operand" "=d")
5876         (geu:QI (cc0) (const_int 0)))]
5877   ""
5878   "*
5879    cc_status = cc_prev_status;
5880    return \"scc %0\"; ")
5881
5882 (define_expand "sle"
5883   [(set (match_operand:QI 0 "register_operand" "")
5884         (le:QI (cc0) (const_int 0)))]
5885   ""
5886   "
5887 {
5888   if (TARGET_68060 && m68k_last_compare_had_fp_operands)
5889     {
5890       m68k_last_compare_had_fp_operands = 0;
5891       FAIL;
5892     }
5893 }")
5894
5895 (define_insn ""
5896   [(set (match_operand:QI 0 "register_operand" "=d")
5897         (le:QI (cc0) (const_int 0)))]
5898   ""
5899   "*
5900   cc_status = cc_prev_status;
5901   OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0);
5902 ")
5903
5904 (define_expand "sleu"
5905   [(set (match_operand:QI 0 "register_operand" "")
5906         (leu:QI (cc0) (const_int 0)))]
5907   ""
5908   "")
5909
5910 (define_insn ""
5911   [(set (match_operand:QI 0 "register_operand" "=d")
5912         (leu:QI (cc0) (const_int 0)))]
5913   ""
5914   "*
5915    cc_status = cc_prev_status;
5916    return \"sls %0\"; ")
5917 \f
5918 ;; Basic conditional jump instructions.
5919
5920 (define_insn "beq0_di"
5921   [(set (pc)
5922     (if_then_else (eq (match_operand:DI 0 "general_operand" "d*ao,<>")
5923             (const_int 0))
5924         (label_ref (match_operand 1 "" ","))
5925         (pc)))
5926    (clobber (match_scratch:SI 2 "=d,d"))]
5927   ""
5928   "*
5929 {
5930   CC_STATUS_INIT;
5931   if (which_alternative == 1)
5932 #ifdef MOTOROLA
5933     return \"move%.l %0,%2\;or%.l %0,%2\;jbeq %l1\";
5934 #else
5935     return \"move%.l %0,%2\;or%.l %0,%2\;jeq %l1\";
5936 #endif
5937   if ((cc_prev_status.value1
5938       && rtx_equal_p (cc_prev_status.value1, operands[0]))
5939     || (cc_prev_status.value2
5940       && rtx_equal_p (cc_prev_status.value2, operands[0])))
5941     {
5942       cc_status = cc_prev_status;
5943 #ifdef MOTOROLA
5944       return \"jbeq %l1\";
5945 #else
5946       return \"jeq %l1\";
5947 #endif
5948     }
5949   if (GET_CODE (operands[0]) == REG)
5950     operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
5951   else
5952     operands[3] = adj_offsettable_operand (operands[0], 4);
5953   if (! ADDRESS_REG_P (operands[0]))
5954     {
5955       if (reg_overlap_mentioned_p (operands[2], operands[0]))
5956         {
5957           if (reg_overlap_mentioned_p (operands[2], operands[3]))
5958             {
5959 #ifdef MOTOROLA
5960               return \"or%.l %0,%2\;jbeq %l1\";
5961 #else
5962               return \"or%.l %0,%2\;jeq %l1\";
5963 #endif
5964             }
5965           else
5966             {
5967 #ifdef MOTOROLA
5968               return \"or%.l %3,%2\;jbeq %l1\";
5969 #else
5970               return \"or%.l %3,%2\;jeq %l1\";
5971 #endif
5972             }
5973         }
5974 #ifdef MOTOROLA
5975       return \"move%.l %0,%2\;or%.l %3,%2\;jbeq %l1\";
5976 #else
5977       return \"move%.l %0,%2\;or%.l %3,%2\;jeq %l1\";
5978 #endif
5979     }
5980   operands[4] = gen_label_rtx();
5981   if (TARGET_68020 || TARGET_5200)
5982     {
5983 #ifdef MOTOROLA
5984       output_asm_insn (\"tst%.l %0\;jbne %l4\;tst%.l %3\;jbeq %l1\", operands);
5985 #else
5986       output_asm_insn (\"tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1\", operands);
5987 #endif
5988     }
5989   else
5990     {
5991 #ifdef MOTOROLA
5992 #ifdef SGS_CMP_ORDER
5993       output_asm_insn (\"cmp%.w %0,%#0\;jbne %l4\;cmp%.w %3,%#0\;jbeq %l1\", operands);
5994 #else
5995       output_asm_insn (\"cmp%.w %#0,%0\;jbne %l4\;cmp%.w %#0,%3\;jbeq %l1\", operands);
5996 #endif
5997 #else
5998       output_asm_insn (\"cmp%.w %#0,%0\;jne %l4\;cmp%.w %#0,%3\;jeq %l1\", operands);
5999 #endif
6000     }
6001   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6002                                 CODE_LABEL_NUMBER (operands[4]));
6003   return \"\";
6004 } ")
6005
6006 (define_insn "bne0_di"
6007   [(set (pc)
6008     (if_then_else (ne (match_operand:DI 0 "general_operand" "do,*a")
6009             (const_int 0))
6010         (label_ref (match_operand 1 "" ","))
6011         (pc)))
6012    (clobber (match_scratch:SI 2 "=d,X"))]
6013   ""
6014   "*
6015 {
6016   if ((cc_prev_status.value1
6017       && rtx_equal_p (cc_prev_status.value1, operands[0]))
6018     || (cc_prev_status.value2
6019       && rtx_equal_p (cc_prev_status.value2, operands[0])))
6020     {
6021       cc_status = cc_prev_status;
6022 #ifdef MOTOROLA
6023       return \"jbne %l1\";
6024 #else
6025       return \"jne %l1\";
6026 #endif
6027     }
6028   CC_STATUS_INIT;
6029   if (GET_CODE (operands[0]) == REG)
6030     operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
6031   else
6032     operands[3] = adj_offsettable_operand (operands[0], 4);
6033   if (!ADDRESS_REG_P (operands[0]))
6034     {
6035       if (reg_overlap_mentioned_p (operands[2], operands[0]))
6036         {
6037           if (reg_overlap_mentioned_p (operands[2], operands[3]))
6038             {
6039 #ifdef MOTOROLA
6040               return \"or%.l %0,%2\;jbne %l1\";
6041 #else
6042               return \"or%.l %0,%2\;jne %l1\";
6043 #endif
6044             }
6045           else
6046             {
6047 #ifdef MOTOROLA
6048               return \"or%.l %3,%2\;jbne %l1\";
6049 #else
6050               return \"or%.l %3,%2\;jne %l1\";
6051 #endif
6052             }
6053         }
6054 #ifdef MOTOROLA
6055       return \"move%.l %0,%2\;or%.l %3,%2\;jbne %l1\";
6056 #else
6057       return \"move%.l %0,%2\;or%.l %3,%2\;jne %l1\";
6058 #endif
6059     }
6060   if (TARGET_68020 || TARGET_5200)
6061     {
6062 #ifdef MOTOROLA
6063       return \"tst%.l %0\;jbne %l1\;tst%.l %3\;jbne %l1\";
6064 #else
6065       return \"tst%.l %0\;jne %l1\;tst%.l %3\;jne %l1\";
6066 #endif
6067     }
6068   else
6069     {
6070 #ifdef MOTOROLA
6071 #ifdef SGS_CMP_ORDER
6072       return \"cmp%.w %0,%#0\;jbne %l1\;cmp%.w %3,%#0\;jbne %l1\";
6073 #else
6074       return \"cmp%.w %#0,%0\;jbne %l1\;cmp%.w %#0,%3\;jbne %l1\";
6075 #endif
6076 #else
6077       return \"cmp%.w %#0,%0\;jne %l1\;cmp%.w %#0,%3\;jne %l1\";
6078 #endif
6079     }
6080 } ")
6081
6082 (define_insn "bge0_di"
6083   [(set (pc)
6084     (if_then_else (ge (match_operand:DI 0 "general_operand" "ro")
6085             (const_int 0))
6086         (label_ref (match_operand 1 "" ""))
6087         (pc)))]
6088   ""
6089   "*
6090 {
6091   if ((cc_prev_status.value1
6092       && rtx_equal_p (cc_prev_status.value1, operands[0]))
6093     || (cc_prev_status.value2
6094       && rtx_equal_p (cc_prev_status.value2, operands[0])))
6095     {
6096       cc_status = cc_prev_status;
6097       if (cc_status.flags & CC_REVERSED)
6098         {
6099 #ifdef MOTOROLA
6100           return \"jble %l1\";
6101 #else
6102           return \"jle %l1\";
6103 #endif
6104         }
6105       else
6106         {
6107 #ifdef MOTOROLA
6108           return \"jbpl %l1\";
6109 #else
6110           return \"jpl %l1\";
6111 #endif
6112         }
6113     }
6114   CC_STATUS_INIT;
6115   if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (operands[0]))
6116     output_asm_insn(\"tst%.l %0\", operands);
6117   else
6118     {
6119       /* On an address reg, cmpw may replace cmpl.  */
6120 #ifdef SGS_CMP_ORDER
6121       output_asm_insn(\"cmp%.w %0,%#0\", operands);
6122 #else
6123       output_asm_insn(\"cmp%.w %#0,%0\", operands);
6124 #endif
6125     }
6126
6127 #ifdef MOTOROLA
6128   return \"jbpl %l1\";
6129 #else
6130   return \"jpl %l1\";
6131 #endif
6132 } ")
6133
6134 (define_insn "blt0_di"
6135   [(set (pc)
6136     (if_then_else (lt (match_operand:DI 0 "general_operand" "ro")
6137             (const_int 0))
6138         (label_ref (match_operand 1 "" ""))
6139         (pc)))]
6140   ""
6141   "*
6142 {
6143   if ((cc_prev_status.value1
6144       && rtx_equal_p (cc_prev_status.value1, operands[0]))
6145     || (cc_prev_status.value2
6146       && rtx_equal_p (cc_prev_status.value2, operands[0])))
6147     {
6148       cc_status = cc_prev_status;
6149       if (cc_status.flags & CC_REVERSED)
6150         {
6151 #ifdef MOTOROLA
6152           return \"jbgt %l1\";
6153 #else
6154           return \"jgt %l1\";
6155 #endif
6156         }
6157       else
6158         {
6159 #ifdef MOTOROLA
6160           return \"jbmi %l1\";
6161 #else
6162           return \"jmi %l1\";
6163 #endif
6164         }
6165     }
6166   CC_STATUS_INIT;
6167   if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (operands[0]))
6168     output_asm_insn(\"tst%.l %0\", operands);
6169   else
6170     {
6171       /* On an address reg, cmpw may replace cmpl.  */
6172 #ifdef SGS_CMP_ORDER
6173       output_asm_insn(\"cmp%.w %0,%#0\", operands);
6174 #else
6175       output_asm_insn(\"cmp%.w %#0,%0\", operands);
6176 #endif
6177     }
6178
6179 #ifdef MOTOROLA
6180   return \"jbmi %l1\";
6181 #else
6182   return \"jmi %l1\";
6183 #endif
6184 } ")
6185
6186 (define_insn "beq"
6187   [(set (pc)
6188         (if_then_else (eq (cc0)
6189                           (const_int 0))
6190                       (label_ref (match_operand 0 "" ""))
6191                       (pc)))]
6192   ""
6193   "*
6194 {
6195 #ifdef MOTOROLA
6196   OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
6197 #else
6198   OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
6199 #endif
6200 }")
6201
6202 (define_insn "bne"
6203   [(set (pc)
6204         (if_then_else (ne (cc0)
6205                           (const_int 0))
6206                       (label_ref (match_operand 0 "" ""))
6207                       (pc)))]
6208   ""
6209   "*
6210 {
6211 #ifdef MOTOROLA
6212   OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
6213 #else
6214   OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
6215 #endif
6216 }")
6217
6218 (define_insn "bgt"
6219   [(set (pc)
6220         (if_then_else (gt (cc0)
6221                           (const_int 0))
6222                       (label_ref (match_operand 0 "" ""))
6223                       (pc)))]
6224   ""
6225   "*
6226 #ifdef MOTOROLA
6227   OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0);
6228 #else
6229   OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0);
6230 #endif
6231 ")
6232
6233 (define_insn "bgtu"
6234   [(set (pc)
6235         (if_then_else (gtu (cc0)
6236                            (const_int 0))
6237                       (label_ref (match_operand 0 "" ""))
6238                       (pc)))]
6239   ""
6240   "*
6241 #ifdef MOTOROLA
6242   return \"jbhi %l0\";
6243 #else
6244   return \"jhi %l0\";
6245 #endif
6246 ")
6247
6248 (define_insn "blt"
6249   [(set (pc)
6250         (if_then_else (lt (cc0)
6251                           (const_int 0))
6252                       (label_ref (match_operand 0 "" ""))
6253                       (pc)))]
6254   ""
6255   "*
6256 #ifdef MOTOROLA
6257   OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\");
6258 #else
6259   OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\");
6260 #endif
6261 ")
6262
6263 (define_insn "bltu"
6264   [(set (pc)
6265         (if_then_else (ltu (cc0)
6266                            (const_int 0))
6267                       (label_ref (match_operand 0 "" ""))
6268                       (pc)))]
6269   ""
6270   "*
6271 #ifdef MOTOROLA
6272   return \"jbcs %l0\";
6273 #else
6274   return \"jcs %l0\";
6275 #endif
6276 ")
6277
6278 (define_insn "bge"
6279   [(set (pc)
6280         (if_then_else (ge (cc0)
6281                           (const_int 0))
6282                       (label_ref (match_operand 0 "" ""))
6283                       (pc)))]
6284   ""
6285   "*
6286 #ifdef MOTOROLA
6287   OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\");
6288 #else
6289   OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\");
6290 #endif
6291 ")
6292
6293 (define_insn "bgeu"
6294   [(set (pc)
6295         (if_then_else (geu (cc0)
6296                            (const_int 0))
6297                       (label_ref (match_operand 0 "" ""))
6298                       (pc)))]
6299   ""
6300   "*
6301 #ifdef MOTOROLA
6302   return \"jbcc %l0\";
6303 #else
6304   return \"jcc %l0\";
6305 #endif
6306 ")
6307
6308 (define_insn "ble"
6309   [(set (pc)
6310         (if_then_else (le (cc0)
6311                           (const_int 0))
6312                       (label_ref (match_operand 0 "" ""))
6313                       (pc)))]
6314   ""
6315   "*
6316 #ifdef MOTOROLA
6317   OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0);
6318 #else
6319   OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0);
6320 #endif
6321 ")
6322
6323 (define_insn "bleu"
6324   [(set (pc)
6325         (if_then_else (leu (cc0)
6326                            (const_int 0))
6327                       (label_ref (match_operand 0 "" ""))
6328                       (pc)))]
6329   ""
6330   "*
6331 #ifdef MOTOROLA
6332   return \"jbls %l0\";
6333 #else
6334   return \"jls %l0\";
6335 #endif
6336 ")
6337 \f
6338 ;; Negated conditional jump instructions.
6339
6340 (define_insn ""
6341   [(set (pc)
6342         (if_then_else (eq (cc0)
6343                           (const_int 0))
6344                       (pc)
6345                       (label_ref (match_operand 0 "" ""))))]
6346   ""
6347   "*
6348 {
6349 #ifdef MOTOROLA
6350   OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
6351 #else
6352   OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
6353 #endif
6354 }")
6355
6356 (define_insn ""
6357   [(set (pc)
6358         (if_then_else (ne (cc0)
6359                           (const_int 0))
6360                       (pc)
6361                       (label_ref (match_operand 0 "" ""))))]
6362   ""
6363   "*
6364 {
6365 #ifdef MOTOROLA
6366   OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
6367 #else
6368   OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
6369 #endif
6370 }")
6371
6372 (define_insn ""
6373   [(set (pc)
6374         (if_then_else (gt (cc0)
6375                           (const_int 0))
6376                       (pc)
6377                       (label_ref (match_operand 0 "" ""))))]
6378   ""
6379   "*
6380 #ifdef MOTOROLA
6381   OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0);
6382 #else
6383   OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0);
6384 #endif
6385 ")
6386
6387 (define_insn ""
6388   [(set (pc)
6389         (if_then_else (gtu (cc0)
6390                            (const_int 0))
6391                       (pc)
6392                       (label_ref (match_operand 0 "" ""))))]
6393   ""
6394   "*
6395 #ifdef MOTOROLA
6396   return \"jbls %l0\";
6397 #else
6398   return \"jls %l0\";
6399 #endif
6400 ")
6401
6402 (define_insn ""
6403   [(set (pc)
6404         (if_then_else (lt (cc0)
6405                           (const_int 0))
6406                       (pc)
6407                       (label_ref (match_operand 0 "" ""))))]
6408   ""
6409   "*
6410 #ifdef MOTOROLA
6411   OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\");
6412 #else
6413   OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\");
6414 #endif
6415 ")
6416
6417 (define_insn ""
6418   [(set (pc)
6419         (if_then_else (ltu (cc0)
6420                            (const_int 0))
6421                       (pc)
6422                       (label_ref (match_operand 0 "" ""))))]
6423   ""
6424   "*
6425 #ifdef MOTOROLA
6426   return \"jbcc %l0\";
6427 #else
6428   return \"jcc %l0\";
6429 #endif
6430 ")
6431
6432 (define_insn ""
6433   [(set (pc)
6434         (if_then_else (ge (cc0)
6435                           (const_int 0))
6436                       (pc)
6437                       (label_ref (match_operand 0 "" ""))))]
6438   ""
6439   "*
6440 #ifdef MOTOROLA
6441   OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\");
6442 #else
6443   OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\");
6444 #endif
6445 ")
6446
6447 (define_insn ""
6448   [(set (pc)
6449         (if_then_else (geu (cc0)
6450                            (const_int 0))
6451                       (pc)
6452                       (label_ref (match_operand 0 "" ""))))]
6453   ""
6454   "*
6455 #ifdef MOTOROLA
6456   return \"jbcs %l0\";
6457 #else
6458   return \"jcs %l0\";
6459 #endif
6460 ")
6461
6462 (define_insn ""
6463   [(set (pc)
6464         (if_then_else (le (cc0)
6465                           (const_int 0))
6466                       (pc)
6467                       (label_ref (match_operand 0 "" ""))))]
6468   ""
6469   "*
6470 #ifdef MOTOROLA
6471   OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0);
6472 #else
6473   OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0);
6474 #endif
6475 ")
6476
6477 (define_insn ""
6478   [(set (pc)
6479         (if_then_else (leu (cc0)
6480                            (const_int 0))
6481                       (pc)
6482                       (label_ref (match_operand 0 "" ""))))]
6483   ""
6484   "*
6485 #ifdef MOTOROLA
6486   return \"jbhi %l0\";
6487 #else
6488   return \"jhi %l0\";
6489 #endif
6490 ")
6491 \f
6492 ;; Unconditional and other jump instructions
6493 (define_insn "jump"
6494   [(set (pc)
6495         (label_ref (match_operand 0 "" "")))]
6496   ""
6497   "*
6498 #ifdef MOTOROLA
6499   return \"jbra %l0\";
6500 #else
6501   return \"jra %l0\";
6502 #endif
6503 ")
6504
6505 ;; We support two different ways of handling dispatch tables.
6506 ;; The NeXT uses absolute tables, and other machines use relative.
6507 ;; This define_expand can generate either kind.
6508 (define_expand "tablejump"
6509   [(parallel [(set (pc) (match_operand 0 "" ""))
6510               (use (label_ref (match_operand 1 "" "")))])]
6511   ""
6512   "
6513 {
6514 #ifdef CASE_VECTOR_PC_RELATIVE
6515     operands[0] = gen_rtx_PLUS (SImode, pc_rtx,
6516                                 gen_rtx_SIGN_EXTEND (SImode, operands[0]));
6517 #endif
6518 }")
6519
6520 ;; Jump to variable address from dispatch table of absolute addresses.
6521 (define_insn ""
6522   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
6523    (use (label_ref (match_operand 1 "" "")))]
6524   ""
6525   "*
6526 #ifdef MOTOROLA
6527   return \"jmp (%0)\";
6528 #else
6529   return \"jmp %0@\";
6530 #endif
6531 ")
6532
6533 ;; Jump to variable address from dispatch table of relative addresses.
6534 (define_insn ""
6535   [(set (pc)
6536         (plus:SI (pc)
6537                  (sign_extend:SI (match_operand:HI 0 "register_operand" "r"))))
6538    (use (label_ref (match_operand 1 "" "")))]
6539   ""
6540   "*
6541 #ifdef ASM_RETURN_CASE_JUMP
6542  ASM_RETURN_CASE_JUMP;
6543 #else
6544 #ifdef SGS
6545 #ifdef ASM_OUTPUT_CASE_LABEL
6546   if (TARGET_5200) 
6547     return \"ext%.l %0\;jmp 6(%%pc,%0.l)\";
6548   else
6549     return \"jmp 6(%%pc,%0.w)\";
6550 #else
6551   if (TARGET_5200)
6552     {
6553 #ifdef CRDS
6554       return \"ext%.l %0\;jmp 2(pc,%0.l)\";
6555 #else
6556       return \"extl %0\;jmp 2(%%pc,%0.l)\";
6557 #endif  /* end !CRDS */
6558     }
6559   else
6560     {
6561 #ifdef CRDS
6562       return \"jmp 2(pc,%0.w)\";
6563 #else
6564       return \"jmp 2(%%pc,%0.w)\";
6565 #endif  /* end !CRDS */
6566     }
6567 #endif
6568 #else /* not SGS */
6569   if (TARGET_5200)
6570     {
6571 #ifdef MOTOROLA
6572       return \"ext%.l %0\;jmp (2,pc,%0.l)\";
6573 #else
6574       return \"extl %0\;jmp pc@(2,%0:l)\";
6575 #endif
6576     }
6577   else
6578     {
6579 #ifdef MOTOROLA
6580       return \"jmp (2,pc,%0.w)\";
6581 #else
6582       return \"jmp pc@(2,%0:w)\";
6583 #endif
6584     }
6585 #endif
6586 #endif
6587 ")
6588
6589 ;; Decrement-and-branch insns.
6590 (define_insn ""
6591   [(set (pc)
6592         (if_then_else
6593          (ne (match_operand:HI 0 "general_operand" "+d*g")
6594              (const_int 0))
6595          (label_ref (match_operand 1 "" ""))
6596          (pc)))
6597    (set (match_dup 0)
6598         (plus:HI (match_dup 0)
6599                  (const_int -1)))]
6600   "!TARGET_5200"
6601   "*
6602 {
6603   CC_STATUS_INIT;
6604   if (DATA_REG_P (operands[0]))
6605     return \"dbra %0,%l1\";
6606   if (GET_CODE (operands[0]) == MEM)
6607     {
6608 #ifdef MOTOROLA
6609 #ifdef NO_ADDSUB_Q
6610       return \"sub%.w %#1,%0\;jbcc %l1\";
6611 #else
6612       return \"subq%.w %#1,%0\;jbcc %l1\";
6613 #endif
6614 #else /* not MOTOROLA */
6615       return \"subqw %#1,%0\;jcc %l1\";
6616 #endif
6617     }
6618 #ifdef MOTOROLA
6619 #ifdef SGS_CMP_ORDER
6620 #ifdef NO_ADDSUB_Q
6621   return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
6622 #else
6623   return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
6624 #endif
6625 #else /* not SGS_CMP_ORDER */
6626   return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\";
6627 #endif
6628 #else /* not MOTOROLA */
6629   return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
6630 #endif
6631 }")
6632
6633 (define_insn ""
6634   [(set (pc)
6635         (if_then_else
6636          (ne (match_operand:SI 0 "general_operand" "+d*g")
6637              (const_int 0))
6638          (label_ref (match_operand 1 "" ""))
6639          (pc)))
6640    (set (match_dup 0)
6641         (plus:SI (match_dup 0)
6642                  (const_int -1)))]
6643   "!TARGET_5200"
6644   "*
6645 {
6646   CC_STATUS_INIT;
6647 #ifdef MOTOROLA
6648 #ifdef NO_ADDSUB_Q
6649   if (DATA_REG_P (operands[0]))
6650     return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\";
6651   if (GET_CODE (operands[0]) == MEM)
6652     return \"sub%.l %#1,%0\;jbcc %l1\";
6653 #else
6654   if (DATA_REG_P (operands[0]))
6655     return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\";
6656   if (GET_CODE (operands[0]) == MEM)
6657     return \"subq%.l %#1,%0\;jbcc %l1\";
6658 #endif /* NO_ADDSUB_Q */
6659 #ifdef SGS_CMP_ORDER
6660 #ifdef NO_ADDSUB_Q
6661   return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
6662 #else
6663   return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
6664 #endif
6665 #else /* not SGS_CMP_ORDER */
6666   return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
6667 #endif /* not SGS_CMP_ORDER */
6668 #else /* not MOTOROLA */
6669   if (DATA_REG_P (operands[0]))
6670     return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\";
6671   if (GET_CODE (operands[0]) == MEM)
6672     return \"subql %#1,%0\;jcc %l1\";
6673   return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
6674 #endif /* not MOTOROLA */
6675 }")
6676
6677 ;; Two dbra patterns that use REG_NOTES info generated by strength_reduce.
6678
6679 (define_insn ""
6680   [(set (pc)
6681         (if_then_else
6682           (ge (plus:HI (match_operand:HI 0 "general_operand" "+d*am")
6683                        (const_int -1))
6684               (const_int 0))
6685           (label_ref (match_operand 1 "" ""))
6686           (pc)))
6687    (set (match_dup 0)
6688         (plus:HI (match_dup 0)
6689                  (const_int -1)))]
6690   "!TARGET_5200 && find_reg_note (insn, REG_NONNEG, 0)"
6691   "*
6692 {
6693   CC_STATUS_INIT;
6694 #ifdef MOTOROLA
6695 #ifdef NO_ADDSUB_Q
6696   if (DATA_REG_P (operands[0]))
6697     return \"dbra %0,%l1\";
6698   if (GET_CODE (operands[0]) == MEM)
6699     return \"sub%.w %#1,%0\;jbcc %l1\";
6700 #else
6701   if (DATA_REG_P (operands[0]))
6702     return \"dbra %0,%l1\";
6703   if (GET_CODE (operands[0]) == MEM)
6704     return \"subq%.w %#1,%0\;jbcc %l1\";
6705 #endif
6706 #ifdef SGS_CMP_ORDER
6707 #ifdef NO_ADDSUB_Q
6708   return \"sub.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\";
6709 #else
6710   return \"subq.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\";
6711 #endif
6712 #else /* not SGS_CMP_ORDER */
6713   return \"subq.w %#1,%0\;cmp.w %#-1,%0\;jbne %l1\";
6714 #endif /* not SGS_CMP_ORDER */
6715 #else /* not MOTOROLA */
6716   if (DATA_REG_P (operands[0]))
6717     return \"dbra %0,%l1\";
6718   if (GET_CODE (operands[0]) == MEM)
6719     return \"subqw %#1,%0\;jcc %l1\";
6720   return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
6721 #endif /* not MOTOROLA */
6722 }")
6723
6724 (define_expand "decrement_and_branch_until_zero"
6725   [(parallel [(set (pc)
6726                    (if_then_else
6727                     (ge (plus:SI (match_operand:SI 0 "general_operand" "")
6728                                  (const_int -1))
6729                         (const_int 0))
6730                     (label_ref (match_operand 1 "" ""))
6731                     (pc)))
6732               (set (match_dup 0)
6733                    (plus:SI (match_dup 0)
6734                             (const_int -1)))])]
6735   ""
6736   "")
6737
6738 (define_insn ""
6739   [(set (pc)
6740         (if_then_else
6741           (ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am")
6742                        (const_int -1))
6743               (const_int 0))
6744           (label_ref (match_operand 1 "" ""))
6745           (pc)))
6746    (set (match_dup 0)
6747         (plus:SI (match_dup 0)
6748                  (const_int -1)))]
6749   "!TARGET_5200 && find_reg_note (insn, REG_NONNEG, 0)"
6750   "*
6751 {
6752   CC_STATUS_INIT;
6753 #ifdef MOTOROLA
6754 #ifdef NO_ADDSUB_Q
6755   if (DATA_REG_P (operands[0]))
6756     return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\";
6757   if (GET_CODE (operands[0]) == MEM)
6758     return \"sub%.l %#1,%0\;jbcc %l1\";
6759 #else
6760   if (DATA_REG_P (operands[0]))
6761     return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\";
6762   if (GET_CODE (operands[0]) == MEM)
6763     return \"subq%.l %#1,%0\;jbcc %l1\";
6764 #endif
6765 #ifdef SGS_CMP_ORDER
6766 #ifdef NO_ADDSUB_Q
6767   return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
6768 #else
6769   return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
6770 #endif
6771 #else /* not SGS_CMP_ORDER */
6772   return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
6773 #endif /* not SGS_CMP_ORDER */
6774 #else /* not MOTOROLA */
6775   if (DATA_REG_P (operands[0]))
6776     return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\";
6777   if (GET_CODE (operands[0]) == MEM)
6778     return \"subql %#1,%0\;jcc %l1\";
6779   return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
6780 #endif /* not MOTOROLA */
6781 }")
6782
6783
6784 ;; For PIC calls, in order to be able to support
6785 ;; dynamic linker LAZY BINDING, all the procedure calls need to go
6786 ;; through the PLT (Procedure Linkage Table) section in PIC mode.
6787 ;;
6788 ;; PIC calls are handled by loading the address of the function into a
6789 ;; register (via movsi), then emitting a register indirect call using
6790 ;; the "jsr" function call syntax.
6791 ;;
6792 ;; When outputting MIT syntax (e.g. on Suns), we add a bogus extra
6793 ;; operand to the jbsr statement to indicate that this call should
6794 ;; go through the PLT (why? because this is the way that Sun does it).
6795 ;;
6796 ;; We have different patterns for PIC calls and non-PIC calls.  The
6797 ;; different patterns are only used to choose the right syntax.
6798 ;;
6799 ;; The svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it
6800 ;; will create the correct relocation entry (R_68K_PLT32) for `FUNC',
6801 ;; that tells the linker editor to create an entry for `FUNC' in PLT
6802 ;; section at link time. However, all global objects reference are still
6803 ;; done by using `OBJ@GOT'. So, the goal here is to output the function
6804 ;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'.
6805 ;; We need to have a way to differentiate these two different operands.
6806 ;;
6807 ;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate
6808 ;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs
6809 ;; to be changed to recognize function calls symbol_ref operand as a valid
6810 ;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will
6811 ;; avoid the compiler to load this symbol_ref operand into a register.
6812 ;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly
6813 ;; since the value is a PC relative offset, not a real address.
6814 ;;
6815 ;; All global objects are treated in the similar way as in SUN3. The only
6816 ;; difference is: on m68k svr4, the reference of such global object needs
6817 ;; to end with a suffix "@GOT" so the assembler and linker know to create
6818 ;; an entry for it in GOT (Global Offset Table) section. This is done in
6819 ;; m68k.c.
6820
6821 ;; Call subroutine with no return value.
6822 (define_expand "call"
6823   [(call (match_operand:QI 0 "memory_operand" "")
6824          (match_operand:SI 1 "general_operand" ""))]
6825   ;; Operand 1 not really used on the m68000.
6826
6827   ""
6828   "
6829 {
6830   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
6831     SYMBOL_REF_FLAG (XEXP (operands[0], 0)) = 1;
6832 }")
6833
6834 ;; This is a normal call sequence.
6835 (define_insn ""
6836   [(call (match_operand:QI 0 "memory_operand" "o")
6837          (match_operand:SI 1 "general_operand" "g"))]
6838   ;; Operand 1 not really used on the m68000.
6839
6840   "! flag_pic"
6841   "*
6842 #if defined (MOTOROLA) && !defined (USE_GAS)
6843 #ifdef MOTOROLA_BSR
6844   if (GET_CODE (operands[0]) == MEM
6845       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
6846     return \"bsr %0\";
6847 #endif
6848   return \"jsr %0\";
6849 #else
6850   return \"jbsr %0\";
6851 #endif
6852 ")
6853
6854 ;; This is a PIC call sequence.
6855 (define_insn ""
6856   [(call (match_operand:QI 0 "memory_operand" "o")
6857          (match_operand:SI 1 "general_operand" "g"))]
6858   ;; Operand 1 not really used on the m68000.
6859
6860   "flag_pic"
6861   "*
6862   if (GET_CODE (operands[0]) == MEM
6863       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
6864     {
6865       if (TARGET_PCREL) return \"bsr.l %o0\";
6866 #ifdef MOTOROLA
6867 #ifdef HPUX_ASM
6868       return \"bsr.l %0\";
6869 #else
6870 #ifdef USE_GAS
6871       return \"bsr.l %0@PLTPC\";
6872 #else
6873       return \"bsr %0@PLTPC\";
6874 #endif
6875 #endif
6876 #else
6877 #ifdef USE_GAS
6878       return \"bsr.l %0\";
6879 #else
6880       /* The ',a1' is a dummy argument telling the Sun assembler we want PIC,
6881          GAS just plain ignores it.  FIXME: not anymore, gas doesnt!  */
6882       return \"jbsr %0,a1\";
6883 #endif
6884 #endif
6885     }
6886   return \"jsr %0\";
6887 ")
6888
6889 ;; Call subroutine, returning value in operand 0
6890 ;; (which must be a hard register).
6891 ;; See comments before "call" regarding PIC calls.
6892 (define_expand "call_value"
6893   [(set (match_operand 0 "" "")
6894         (call (match_operand:QI 1 "memory_operand" "")
6895      (match_operand:SI 2 "general_operand" "")))]
6896   ;; Operand 2 not really used on the m68000.
6897   ""
6898   "
6899 {
6900   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6901     SYMBOL_REF_FLAG (XEXP (operands[1], 0)) = 1;
6902 }")
6903
6904 ;; This is a normal call_value
6905 (define_insn ""
6906   [(set (match_operand 0 "" "=rf")
6907         (call (match_operand:QI 1 "memory_operand" "o")
6908               (match_operand:SI 2 "general_operand" "g")))]
6909   ;; Operand 2 not really used on the m68000.
6910   "! flag_pic"
6911   "*
6912 #if defined (MOTOROLA) && !defined (USE_GAS)
6913 #ifdef MOTOROLA_BSR
6914   if (GET_CODE (operands[1]) == MEM
6915       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6916     return \"bsr %1\";
6917 #endif
6918   return \"jsr %1\";
6919 #else
6920   return \"jbsr %1\";
6921 #endif
6922 ")
6923
6924 ;; This is a PIC call_value
6925 (define_insn ""
6926   [(set (match_operand 0 "" "=rf")
6927         (call (match_operand:QI 1 "memory_operand" "o")
6928               (match_operand:SI 2 "general_operand" "g")))]
6929   ;; Operand 2 not really used on the m68000.
6930   "flag_pic"
6931   "*
6932   if (GET_CODE (operands[1]) == MEM
6933       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6934     {
6935       if (TARGET_PCREL) return \"bsr.l %o1\";
6936 #ifdef MOTOROLA
6937 #ifdef HPUX_ASM
6938       return \"bsr.l %1\";
6939 #else
6940 #ifdef USE_GAS
6941       return \"bsr.l %1@PLTPC\";
6942 #else
6943       return \"bsr %1@PLTPC\";
6944 #endif
6945 #endif
6946 #else
6947 #ifdef USE_GAS
6948       return \"bsr.l %1\";
6949 #else
6950       /* The ',a1' is a dummy argument telling the Sun assembler we want PIC
6951          GAS just plain ignores it.  FIXME: Not anymore, gas doesnt!  */
6952       return \"jbsr %1,a1\";
6953 #endif
6954 #endif
6955     }
6956   return \"jsr %1\";
6957 ")
6958
6959 ;; Call subroutine returning any type.
6960
6961 (define_expand "untyped_call"
6962   [(parallel [(call (match_operand 0 "" "")
6963                     (const_int 0))
6964               (match_operand 1 "" "")
6965               (match_operand 2 "" "")])]
6966   "NEEDS_UNTYPED_CALL"
6967   "
6968 {
6969   int i;
6970
6971   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
6972
6973   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6974     {
6975       rtx set = XVECEXP (operands[2], 0, i);
6976       emit_move_insn (SET_DEST (set), SET_SRC (set));
6977     }
6978
6979   /* The optimizer does not know that the call sets the function value
6980      registers we stored in the result block.  We avoid problems by
6981      claiming that all hard registers are used and clobbered at this
6982      point.  */
6983   emit_insn (gen_blockage ());
6984
6985   DONE;
6986 }")
6987
6988 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6989 ;; all of memory.  This blocks insns from being moved across this point.
6990
6991 (define_insn "blockage"
6992   [(unspec_volatile [(const_int 0)] 0)]
6993   ""
6994   "")
6995
6996 (define_insn "nop"
6997   [(const_int 0)]
6998   ""
6999   "nop")
7000
7001 (define_insn "probe"
7002  [(reg:SI 15)]
7003  "NEED_PROBE"
7004  "*
7005 {
7006   operands[0] = gen_rtx_PLUS (SImode, stack_pointer_rtx,
7007                               GEN_INT (NEED_PROBE));
7008   return \"tstl %a0\";
7009 }")
7010
7011 ;; Used for frameless functions which save no regs and allocate no locals.
7012 (define_insn "return"
7013   [(return)]
7014   "USE_RETURN_INSN"
7015   "*
7016 {
7017   if (current_function_pops_args == 0)
7018     return \"rts\";
7019   operands[0] = GEN_INT (current_function_pops_args);
7020   return \"rtd %0\";
7021 }")
7022
7023 (define_insn "indirect_jump"
7024   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7025   ""
7026   "jmp %a0")
7027 \f
7028 ;; This should not be used unless the add/sub insns can't be.
7029
7030 (define_insn ""
7031   [(set (match_operand:SI 0 "general_operand" "=a")
7032         (match_operand:QI 1 "address_operand" "p"))]
7033   ""
7034   "*
7035 {
7036 #ifndef SGS_NO_LI
7037   /* Recognize an insn that refers to a table of offsets.  Such an insn will
7038      need to refer to a label on the insn.  So output one.  Use the
7039      label-number of the table of offsets to generate this label.  This code,
7040      and similar code above, assumes that there will be at most one reference
7041      to each table.  */
7042   if (GET_CODE (operands[1]) == PLUS
7043       && GET_CODE (XEXP (operands[1], 1)) == LABEL_REF
7044       && GET_CODE (XEXP (operands[1], 0)) != PLUS)
7045     {
7046       rtx labelref = XEXP (operands[1], 1);
7047 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
7048 #ifdef SGS
7049       asm_fprintf (asm_out_file, \"\\tset %LLI%d,.+2\\n\",
7050                    CODE_LABEL_NUMBER (XEXP (labelref, 0)));
7051 #else /* not SGS */
7052       asm_fprintf (asm_out_file, \"\\t.set %LLI%d,.+2\\n\",
7053                    CODE_LABEL_NUMBER (XEXP (labelref, 0)));
7054 #endif /* not SGS */
7055 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
7056       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\",
7057                                  CODE_LABEL_NUMBER (XEXP (labelref, 0)));
7058 #ifdef SGS_SWITCH_TABLES
7059       /* Set flag saying we need to define the symbol
7060          LD%n (with value L%n-LI%n) at the end of the switch table.  */
7061       switch_table_difference_label_flag = 1;
7062 #endif /* SGS_SWITCH_TABLES */
7063 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
7064     }
7065 #endif /* SGS_NO_LI */
7066
7067   return \"lea %a1,%0\";
7068 }")
7069 \f
7070 ;; This is the first machine-dependent peephole optimization.
7071 ;; It is useful when a floating value is returned from a function call
7072 ;; and then is moved into an FP register.
7073 ;; But it is mainly intended to test the support for these optimizations.
7074
7075 (define_peephole
7076   [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
7077    (set (match_operand:DF 0 "register_operand" "=f")
7078         (match_operand:DF 1 "register_operand" "ad"))]
7079   "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
7080   "*
7081 {
7082   rtx xoperands[2];
7083   xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
7084   output_asm_insn (\"move%.l %1,%@\", xoperands);
7085   output_asm_insn (\"move%.l %1,%-\", operands);
7086   return \"fmove%.d %+,%0\";
7087 }
7088 ")
7089
7090 ;; Optimize a stack-adjust followed by a push of an argument.
7091 ;; This is said to happen frequently with -msoft-float
7092 ;; when there are consecutive library calls.
7093
7094 (define_peephole
7095   [(set (reg:SI 15) (plus:SI (reg:SI 15)
7096                              (match_operand:SI 0 "const_int_operand" "n")))
7097    (set (match_operand:SF 1 "push_operand" "=m")
7098         (match_operand:SF 2 "general_operand" "rmfF"))]
7099   "INTVAL (operands[0]) >= 4
7100    && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
7101   "*
7102 {
7103   if (INTVAL (operands[0]) > 4)
7104     {
7105       rtx xoperands[2];
7106       xoperands[0] = stack_pointer_rtx;
7107       xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4);
7108 #ifndef NO_ADDSUB_Q
7109       if (INTVAL (xoperands[1]) <= 8)
7110         {
7111           if (!TARGET_5200)
7112             output_asm_insn (\"addq%.w %1,%0\", xoperands);
7113           else
7114             output_asm_insn (\"addq%.l %1,%0\", xoperands);
7115         }
7116       else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16) 
7117         {
7118           xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8);
7119           output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
7120         }
7121       else
7122 #endif
7123         if (INTVAL (xoperands[1]) <= 0x7FFF)
7124         {
7125           if (TARGET_68040)
7126             output_asm_insn (\"add%.w %1,%0\", xoperands);
7127           else
7128 #ifdef MOTOROLA  
7129             output_asm_insn (\"lea (%c1,%0),%0\", xoperands);
7130 #else
7131             output_asm_insn (\"lea %0@(%c1),%0\", xoperands);
7132 #endif
7133         }
7134       else
7135         output_asm_insn (\"add%.l %1,%0\", xoperands);
7136     }
7137   if (FP_REG_P (operands[2]))
7138     return \"fmove%.s %2,%@\";
7139   return \"move%.l %2,%@\";
7140 }")
7141
7142 ;; Speed up stack adjust followed by a fullword fixedpoint push.
7143
7144 (define_peephole
7145   [(set (reg:SI 15) (plus:SI (reg:SI 15)
7146                              (match_operand:SI 0 "const_int_operand" "n")))
7147    (set (match_operand:SI 1 "push_operand" "=m")
7148         (match_operand:SI 2 "general_operand" "g"))]
7149   "INTVAL (operands[0]) >= 4
7150    && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
7151   "*
7152 {
7153   if (INTVAL (operands[0]) > 4)
7154     {
7155       rtx xoperands[2];
7156       xoperands[0] = stack_pointer_rtx;
7157       xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4);
7158 #ifndef NO_ADDSUB_Q
7159       if (INTVAL (xoperands[1]) <= 8)
7160         {
7161           if (!TARGET_5200)
7162             output_asm_insn (\"addq%.w %1,%0\", xoperands);
7163           else
7164             output_asm_insn (\"addq%.l %1,%0\", xoperands);
7165         }
7166       else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16)
7167         {
7168           xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8);
7169           output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
7170         }
7171       else
7172 #endif
7173         if (INTVAL (xoperands[1]) <= 0x7FFF)
7174         {
7175           if (TARGET_68040)
7176             output_asm_insn (\"add%.w %1,%0\", xoperands);
7177           else
7178             {
7179 #ifdef MOTOROLA  
7180               output_asm_insn (\"lea (%c1,%0),%0\", xoperands);
7181 #else
7182               output_asm_insn (\"lea %0@(%c1),%0\", xoperands);
7183 #endif
7184             }
7185         }
7186       else
7187         output_asm_insn (\"add%.l %1,%0\", xoperands);
7188     }
7189   if (operands[2] == const0_rtx)
7190     return \"clr%.l %@\";
7191   return \"move%.l %2,%@\";
7192 }")
7193
7194 ;; Speed up pushing a single byte but leaving four bytes of space.
7195
7196 (define_peephole
7197   [(set (mem:QI (pre_dec:SI (reg:SI 15)))
7198         (match_operand:QI 1 "general_operand" "dami"))
7199    (set (reg:SI 15) (minus:SI (reg:SI 15) (const_int 2)))]
7200   "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
7201   "*
7202 {
7203   rtx xoperands[4];
7204
7205   if (GET_CODE (operands[1]) == REG)
7206     return \"move%.l %1,%-\";
7207
7208   xoperands[1] = operands[1];
7209   xoperands[2]
7210     = gen_rtx_MEM (QImode,
7211                    gen_rtx_PLUS (VOIDmode, stack_pointer_rtx,
7212                                  GEN_INT (3)));
7213   xoperands[3] = stack_pointer_rtx;
7214   if (!TARGET_5200)
7215     output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands);
7216   else
7217     output_asm_insn (\"subq%.l %#4,%3\;move%.b %1,%2\", xoperands);
7218   return \"\";
7219 }")
7220
7221 (define_peephole
7222   [(set (match_operand:SI 0 "register_operand" "=d")
7223         (const_int 0))
7224    (set (strict_low_part (subreg:HI (match_dup 0) 0))
7225         (match_operand:HI 1 "general_operand" "rmn"))]
7226   "strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0])"
7227   "*
7228 {
7229   if (GET_CODE (operands[1]) == CONST_INT)
7230     {
7231       if (operands[1] == const0_rtx
7232           && (DATA_REG_P (operands[0])
7233               || GET_CODE (operands[0]) == MEM)
7234           /* clr insns on 68000 read before writing.
7235              This isn't so on the 68010, but we have no TARGET_68010.  */
7236           && ((TARGET_68020 || TARGET_5200)
7237               || !(GET_CODE (operands[0]) == MEM
7238                    && MEM_VOLATILE_P (operands[0]))))
7239         return \"clr%.w %0\";
7240     }
7241   return \"move%.w %1,%0\";
7242 }")
7243
7244 ;; dbCC peepholes
7245 ;;
7246 ;; Turns
7247 ;;   loop:
7248 ;;           [ ... ]
7249 ;;           jCC label          ; abnormal loop termination
7250 ;;           dbra dN, loop      ; normal loop termination
7251 ;;
7252 ;; Into
7253 ;;   loop:
7254 ;;           [ ... ]
7255 ;;           dbCC dN, loop
7256 ;;           jCC label
7257 ;;
7258 ;; Which moves the jCC condition outside the inner loop for free.
7259 ;;
7260 (define_peephole
7261   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
7262                              [(cc0) (const_int 0)])
7263                            (label_ref (match_operand 2 "" ""))
7264                            (pc)))
7265    (parallel
7266     [(set (pc)
7267           (if_then_else
7268             (ge (plus:HI (match_operand:HI 0 "register_operand" "+d")
7269                          (const_int -1))
7270                 (const_int 0))
7271             (label_ref (match_operand 1 "" ""))
7272             (pc)))
7273      (set (match_dup 0)
7274           (plus:HI (match_dup 0)
7275                    (const_int -1)))])]
7276   "!TARGET_5200 && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
7277   "*
7278 {
7279   CC_STATUS_INIT;
7280   output_dbcc_and_branch (operands);
7281   return \"\";
7282 }")
7283
7284 (define_peephole
7285   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
7286                              [(cc0) (const_int 0)])
7287                            (label_ref (match_operand 2 "" ""))
7288                            (pc)))
7289    (parallel
7290     [(set (pc)
7291           (if_then_else
7292             (ge (plus:SI (match_operand:SI 0 "register_operand" "+d")
7293                          (const_int -1))
7294                 (const_int 0))
7295             (label_ref (match_operand 1 "" ""))
7296             (pc)))
7297      (set (match_dup 0)
7298           (plus:SI (match_dup 0)
7299                    (const_int -1)))])]
7300   "!TARGET_5200 && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
7301   "*
7302 {
7303   CC_STATUS_INIT;
7304   output_dbcc_and_branch (operands);
7305   return \"\";
7306 }")
7307
7308 \f
7309 ;; FPA multiply and add.
7310 (define_insn ""
7311   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
7312         (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y")
7313                           (match_operand:DF 2 "general_operand" "xH,y,y"))
7314                  (match_operand:DF 3 "general_operand" "xH,y,dmF")))]
7315    "TARGET_FPA"
7316    "@
7317     fpma%.d %1,%w2,%w3,%0
7318     fpma%.d %x1,%x2,%x3,%0
7319     fpma%.d %x1,%x2,%x3,%0")
7320
7321 (define_insn ""
7322   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
7323         (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y")
7324                           (match_operand:SF 2 "general_operand" "xH,y,ydmF"))
7325                  (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))]
7326    "TARGET_FPA"
7327    "@
7328     fpma%.s %1,%w2,%w3,%0
7329     fpma%.s %1,%2,%3,%0
7330     fpma%.s %1,%2,%3,%0")
7331
7332 ;; FPA Multiply and subtract
7333 (define_insn ""
7334   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
7335         (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
7336                   (mult:DF (match_operand:DF 2 "general_operand" "%xH,y,y")
7337                            (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
7338   "TARGET_FPA"
7339   "@
7340    fpms%.d %3,%w2,%w1,%0
7341    fpms%.d %x3,%2,%x1,%0
7342    fpms%.d %x3,%2,%x1,%0")
7343
7344 (define_insn ""
7345   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
7346         (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
7347                   (mult:SF (match_operand:SF 2 "general_operand" "%xH,rmF,y")
7348                            (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
7349   "TARGET_FPA"
7350   "@
7351    fpms%.s %3,%w2,%w1,%0
7352    fpms%.s %3,%2,%1,%0
7353    fpms%.s %3,%2,%1,%0")
7354
7355 (define_insn ""
7356   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
7357         (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%xH,y,y")
7358                            (match_operand:DF 2 "general_operand" "x,y,rmF"))
7359                   (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
7360   "TARGET_FPA"
7361   "@
7362    fpmr%.d %2,%w1,%w3,%0
7363    fpmr%.d %x2,%1,%x3,%0
7364    fpmr%.d %x2,%1,%x3,%0")
7365
7366 (define_insn ""
7367   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
7368         (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y")
7369                            (match_operand:SF 2 "general_operand" "x,y,yrmF"))
7370                   (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
7371   "TARGET_FPA"
7372   "@
7373    fpmr%.s %2,%w1,%w3,%0
7374    fpmr%.s %x2,%1,%x3,%0
7375    fpmr%.s %x2,%1,%x3,%0")
7376
7377 ;; FPA Add and multiply
7378 (define_insn ""
7379   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
7380         (mult:DF (plus:DF (match_operand:DF 1 "general_operand" "%xH,y,y")
7381                           (match_operand:DF 2 "general_operand" "x,y,rmF"))
7382                  (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
7383   "TARGET_FPA"
7384   "@
7385    fpam%.d %2,%w1,%w3,%0
7386    fpam%.d %x2,%1,%x3,%0
7387    fpam%.d %x2,%1,%x3,%0")
7388
7389 (define_insn ""
7390   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
7391         (mult:SF (plus:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y")
7392                           (match_operand:SF 2 "general_operand" "x,y,yrmF"))
7393                  (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
7394   "TARGET_FPA"
7395   "@
7396    fpam%.s %2,%w1,%w3,%0
7397    fpam%.s %x2,%1,%x3,%0
7398    fpam%.s %x2,%1,%x3,%0")
7399
7400 ;;FPA Subtract and multiply
7401 (define_insn ""
7402   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
7403         (mult:DF (minus:DF (match_operand:DF 1 "general_operand" "xH,y,y")
7404                            (match_operand:DF 2 "general_operand" "x,y,rmF"))
7405                  (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
7406   "TARGET_FPA"
7407   "@
7408    fpsm%.d %2,%w1,%w3,%0
7409    fpsm%.d %x2,%1,%x3,%0
7410    fpsm%.d %x2,%1,%x3,%0")
7411
7412 (define_insn ""
7413   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
7414         (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
7415                  (minus:DF (match_operand:DF 2 "general_operand" "xH,y,y")
7416                            (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
7417   "TARGET_FPA"
7418   "@
7419    fpsm%.d %3,%w2,%w1,%0
7420    fpsm%.d %x3,%2,%x1,%0
7421    fpsm%.d %x3,%2,%x1,%0")
7422
7423 (define_insn ""
7424   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
7425         (mult:SF (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,y")
7426                            (match_operand:SF 2 "general_operand" "x,y,yrmF"))
7427                  (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
7428   "TARGET_FPA"
7429   "@
7430    fpsm%.s %2,%w1,%w3,%0
7431    fpsm%.s %x2,%1,%x3,%0
7432    fpsm%.s %x2,%1,%x3,%0")
7433
7434 (define_insn ""
7435   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
7436         (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
7437                  (minus:SF (match_operand:SF 2 "general_operand" "xH,rmF,y")
7438                            (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
7439   "TARGET_FPA"
7440   "@
7441    fpsm%.s %3,%w2,%w1,%0
7442    fpsm%.s %x3,%2,%x1,%0
7443    fpsm%.s %x3,%2,%x1,%0")
7444
7445 (define_expand "tstxf"
7446   [(set (cc0)
7447         (match_operand:XF 0 "nonimmediate_operand" ""))]
7448   "TARGET_68881"
7449   "m68k_last_compare_had_fp_operands = 1;")
7450
7451 (define_insn ""
7452   [(set (cc0)
7453         (match_operand:XF 0 "nonimmediate_operand" "fm"))]
7454   "TARGET_68881"
7455   "*
7456 {
7457   cc_status.flags = CC_IN_68881;
7458   return \"ftst%.x %0\";
7459 }")
7460
7461 (define_expand "cmpxf"
7462   [(set (cc0)
7463         (compare (match_operand:XF 0 "nonimmediate_operand" "")
7464                  (match_operand:XF 1 "nonimmediate_operand" "")))]
7465   "TARGET_68881"
7466   "m68k_last_compare_had_fp_operands = 1;")
7467
7468 (define_insn ""
7469   [(set (cc0)
7470         (compare (match_operand:XF 0 "nonimmediate_operand" "f,m")
7471                  (match_operand:XF 1 "nonimmediate_operand" "fm,f")))]
7472   "TARGET_68881"
7473   "*
7474 {
7475   cc_status.flags = CC_IN_68881;
7476 #ifdef SGS_CMP_ORDER
7477   if (REG_P (operands[0]))
7478     {
7479       if (REG_P (operands[1]))
7480         return \"fcmp%.x %0,%1\";
7481       else
7482         return \"fcmp%.x %0,%f1\";
7483     }
7484   cc_status.flags |= CC_REVERSED;
7485   return \"fcmp%.x %1,%f0\";
7486 #else
7487   if (REG_P (operands[0]))
7488     {
7489       if (REG_P (operands[1]))
7490         return \"fcmp%.x %1,%0\";
7491       else
7492         return \"fcmp%.x %f1,%0\";
7493     }
7494   cc_status.flags |= CC_REVERSED;
7495   return \"fcmp%.x %f0,%1\";
7496 #endif
7497 }")
7498
7499 (define_insn "extendsfxf2"
7500   [(set (match_operand:XF 0 "general_operand" "=fm,f")
7501         (float_extend:XF (match_operand:SF 1 "general_operand" "f,rmF")))]
7502   "TARGET_68881"
7503   "*
7504 {
7505   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
7506     {
7507       if (REGNO (operands[0]) == REGNO (operands[1]))
7508         {
7509           /* Extending float to double in an fp-reg is a no-op.
7510              NOTICE_UPDATE_CC has already assumed that the
7511              cc will be set.  So cancel what it did.  */
7512           cc_status = cc_prev_status;
7513           return \"\";
7514         }
7515       return \"f%$move%.x %1,%0\";
7516     }
7517   if (FP_REG_P (operands[0]))
7518     {
7519       if (FP_REG_P (operands[1]))
7520         return \"f%$move%.x %1,%0\";
7521       else if (ADDRESS_REG_P (operands[1]))
7522         return \"move%.l %1,%-\;f%$move%.s %+,%0\";
7523       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
7524         return output_move_const_single (operands);
7525       return \"f%$move%.s %f1,%0\";
7526     }
7527   return \"fmove%.x %f1,%0\";
7528 }")
7529
7530
7531 (define_insn "extenddfxf2"
7532   [(set (match_operand:XF 0 "general_operand" "=fm,f")
7533         (float_extend:XF
7534           (match_operand:DF 1 "general_operand" "f,rmE")))]
7535   "TARGET_68881"
7536   "*
7537 {
7538   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
7539     {
7540       if (REGNO (operands[0]) == REGNO (operands[1]))
7541         {
7542           /* Extending float to double in an fp-reg is a no-op.
7543              NOTICE_UPDATE_CC has already assumed that the
7544              cc will be set.  So cancel what it did.  */
7545           cc_status = cc_prev_status;
7546           return \"\";
7547         }
7548       return \"fmove%.x %1,%0\";
7549     }
7550   if (FP_REG_P (operands[0]))
7551     {
7552       if (REG_P (operands[1]))
7553         {
7554           rtx xoperands[2];
7555           xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
7556           output_asm_insn (\"move%.l %1,%-\", xoperands);
7557           output_asm_insn (\"move%.l %1,%-\", operands);
7558           return \"f%&move%.d %+,%0\";
7559         }
7560       if (GET_CODE (operands[1]) == CONST_DOUBLE)
7561         return output_move_const_double (operands);
7562       return \"f%&move%.d %f1,%0\";
7563     }
7564   return \"fmove%.x %f1,%0\";
7565 }")
7566
7567 (define_insn "truncxfdf2"
7568   [(set (match_operand:DF 0 "general_operand" "=m,!r")
7569         (float_truncate:DF
7570           (match_operand:XF 1 "general_operand" "f,f")))]
7571   "TARGET_68881"
7572   "*
7573 {
7574   if (REG_P (operands[0]))
7575     {
7576       output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
7577       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
7578       return \"move%.l %+,%0\";
7579     }
7580   return \"fmove%.d %f1,%0\";
7581 }")
7582
7583 (define_insn "truncxfsf2"
7584   [(set (match_operand:SF 0 "general_operand" "=dm")
7585         (float_truncate:SF
7586           (match_operand:XF 1 "general_operand" "f")))]
7587   "TARGET_68881"
7588   "fmove%.s %f1,%0")
7589
7590 (define_insn "floatsixf2"
7591   [(set (match_operand:XF 0 "general_operand" "=f")
7592         (float:XF (match_operand:SI 1 "general_operand" "dmi")))]
7593   "TARGET_68881"
7594   "fmove%.l %1,%0")
7595
7596 (define_insn "floathixf2"
7597   [(set (match_operand:XF 0 "general_operand" "=f")
7598         (float:XF (match_operand:HI 1 "general_operand" "dmn")))]
7599   "TARGET_68881"
7600   "fmove%.w %1,%0")
7601
7602 (define_insn "floatqixf2"
7603   [(set (match_operand:XF 0 "general_operand" "=f")
7604         (float:XF (match_operand:QI 1 "general_operand" "dmn")))]
7605   "TARGET_68881"
7606   "fmove%.b %1,%0")
7607
7608 (define_insn "ftruncxf2"
7609   [(set (match_operand:XF 0 "general_operand" "=f")
7610         (fix:XF (match_operand:XF 1 "general_operand" "fFm")))]
7611   "TARGET_68881"
7612   "*
7613 {
7614   if (FP_REG_P (operands[1]))
7615     return \"fintrz%.x %f1,%0\";
7616   return \"fintrz%.x %f1,%0\";
7617 }")
7618
7619 (define_insn "fixxfqi2"
7620   [(set (match_operand:QI 0 "general_operand" "=dm")
7621         (fix:QI (match_operand:XF 1 "general_operand" "f")))]
7622   "TARGET_68881"
7623   "fmove%.b %1,%0")
7624
7625 (define_insn "fixxfhi2"
7626   [(set (match_operand:HI 0 "general_operand" "=dm")
7627         (fix:HI (match_operand:XF 1 "general_operand" "f")))]
7628   "TARGET_68881"
7629   "fmove%.w %1,%0")
7630
7631 (define_insn "fixxfsi2"
7632   [(set (match_operand:SI 0 "general_operand" "=dm")
7633         (fix:SI (match_operand:XF 1 "general_operand" "f")))]
7634   "TARGET_68881"
7635   "fmove%.l %1,%0")
7636
7637 (define_insn ""
7638   [(set (match_operand:XF 0 "general_operand" "=f")
7639         (plus:XF (float:XF (match_operand:SI 2 "general_operand" "dmi"))
7640                  (match_operand:XF 1 "nonimmediate_operand" "0")))]
7641   "TARGET_68881"
7642   "fadd%.l %2,%0")
7643
7644 (define_insn ""
7645   [(set (match_operand:XF 0 "general_operand" "=f")
7646         (plus:XF (float:XF (match_operand:HI 2 "general_operand" "dmn"))
7647                  (match_operand:XF 1 "nonimmediate_operand" "0")))]
7648   "TARGET_68881"
7649   "fadd%.w %2,%0")
7650
7651 (define_insn ""
7652   [(set (match_operand:XF 0 "general_operand" "=f")
7653         (plus:XF (float:XF (match_operand:QI 2 "general_operand" "dmn"))
7654                  (match_operand:XF 1 "general_operand" "0")))]
7655   "TARGET_68881"
7656   "fadd%.b %2,%0")
7657
7658 (define_insn "addxf3"
7659   [(set (match_operand:XF 0 "general_operand" "=f")
7660         (plus:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
7661                  (match_operand:XF 2 "nonimmediate_operand" "fm")))]
7662   "TARGET_68881"
7663   "*
7664 {
7665   if (REG_P (operands[2]))
7666     return \"fadd%.x %2,%0\";
7667   return \"fadd%.x %f2,%0\";
7668 }")
7669
7670 (define_insn ""
7671   [(set (match_operand:XF 0 "general_operand" "=f")
7672         (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
7673                   (float:XF (match_operand:SI 2 "general_operand" "dmi"))))]
7674   "TARGET_68881"
7675   "fsub%.l %2,%0")
7676
7677 (define_insn ""
7678   [(set (match_operand:XF 0 "general_operand" "=f")
7679         (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
7680                   (float:XF (match_operand:HI 2 "general_operand" "dmn"))))]
7681   "TARGET_68881"
7682   "fsub%.w %2,%0")
7683
7684 (define_insn ""
7685   [(set (match_operand:XF 0 "general_operand" "=f")
7686         (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
7687                   (float:XF (match_operand:QI 2 "general_operand" "dmn"))))]
7688   "TARGET_68881"
7689   "fsub%.b %2,%0")
7690
7691 (define_insn "subxf3"
7692   [(set (match_operand:XF 0 "general_operand" "=f")
7693         (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
7694                   (match_operand:XF 2 "nonimmediate_operand" "fm")))]
7695   "TARGET_68881"
7696   "*
7697 {
7698   if (REG_P (operands[2]))
7699     return \"fsub%.x %2,%0\";
7700   return \"fsub%.x %f2,%0\";
7701 }")
7702
7703 (define_insn ""
7704   [(set (match_operand:XF 0 "general_operand" "=f")
7705         (mult:XF (float:XF (match_operand:SI 2 "general_operand" "dmi"))
7706                  (match_operand:XF 1 "nonimmediate_operand" "0")))]
7707   "TARGET_68881"
7708   "fmul%.l %2,%0")
7709
7710 (define_insn ""
7711   [(set (match_operand:XF 0 "general_operand" "=f")
7712         (mult:XF (float:XF (match_operand:HI 2 "general_operand" "dmn"))
7713                  (match_operand:XF 1 "nonimmediate_operand" "0")))]
7714   "TARGET_68881"
7715   "fmul%.w %2,%0")
7716
7717 (define_insn ""
7718   [(set (match_operand:XF 0 "general_operand" "=f")
7719         (mult:XF (float:XF (match_operand:QI 2 "general_operand" "dmn"))
7720                  (match_operand:XF 1 "nonimmediate_operand" "0")))]
7721   "TARGET_68881"
7722   "fmul%.b %2,%0")
7723
7724 (define_insn "mulxf3"
7725   [(set (match_operand:XF 0 "general_operand" "=f")
7726         (mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
7727                  (match_operand:XF 2 "nonimmediate_operand" "fm")))]
7728   "TARGET_68881"
7729   "*
7730 {
7731   if (REG_P (operands[2]))
7732     return \"fmul%.x %2,%0\";
7733   return \"fmul%.x %f2,%0\";
7734 }")
7735
7736 (define_insn ""
7737   [(set (match_operand:XF 0 "general_operand" "=f")
7738         (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
7739                 (float:XF (match_operand:SI 2 "general_operand" "dmi"))))]
7740   "TARGET_68881"
7741   "fdiv%.l %2,%0")
7742
7743 (define_insn ""
7744   [(set (match_operand:XF 0 "general_operand" "=f")
7745         (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
7746                 (float:XF (match_operand:HI 2 "general_operand" "dmn"))))]
7747   "TARGET_68881"
7748   "fdiv%.w %2,%0")
7749
7750 (define_insn ""
7751   [(set (match_operand:XF 0 "general_operand" "=f")
7752         (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
7753                 (float:XF (match_operand:QI 2 "general_operand" "dmn"))))]
7754   "TARGET_68881"
7755   "fdiv%.b %2,%0")
7756
7757 (define_insn "divxf3"
7758   [(set (match_operand:XF 0 "general_operand" "=f")
7759         (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
7760                 (match_operand:XF 2 "nonimmediate_operand" "fm")))]
7761   "TARGET_68881"
7762   "*
7763 {
7764   if (REG_P (operands[2]))
7765     return \"fdiv%.x %2,%0\";
7766   return \"fdiv%.x %f2,%0\";
7767 }")
7768
7769 (define_expand "negxf2"
7770   [(set (match_operand:XF 0 "general_operand" "")
7771         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
7772   ""
7773   "
7774 {
7775   /* ??? There isn't an FPA define_insn so we could handle it here too.
7776      For now we don't (paranoia).  */
7777   if (!TARGET_68881)
7778     {
7779       rtx result;
7780       rtx target;
7781       rtx insns;
7782
7783       start_sequence ();
7784       target = operand_subword (operands[0], 0, 1, XFmode);
7785       result = expand_binop (SImode, xor_optab,
7786                              operand_subword_force (operands[1], 0, XFmode),
7787                              GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
7788       if (result == 0)
7789         abort ();
7790
7791       if (result != target)
7792         emit_move_insn (result, target);
7793
7794       emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
7795                       operand_subword_force (operands[1], 1, XFmode));
7796       emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
7797                       operand_subword_force (operands[1], 2, XFmode));
7798
7799       insns = get_insns ();
7800       end_sequence ();
7801
7802       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
7803       DONE;
7804     }
7805 }")
7806
7807 (define_insn "negxf2_68881"
7808   [(set (match_operand:XF 0 "general_operand" "=f")
7809         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "fm")))]
7810   "TARGET_68881"
7811   "*
7812 {
7813   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
7814     return \"fneg%.x %1,%0\";
7815   return \"fneg%.x %f1,%0\";
7816 }")
7817
7818 (define_expand "absxf2"
7819   [(set (match_operand:XF 0 "general_operand" "")
7820         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
7821   ""
7822   "
7823 {
7824   /* ??? There isn't an FPA define_insn so we could handle it here too.
7825      For now we don't (paranoia).  */
7826   if (!TARGET_68881)
7827     {
7828       rtx result;
7829       rtx target;
7830       rtx insns;
7831
7832       start_sequence ();
7833       target = operand_subword (operands[0], 0, 1, XFmode);
7834       result = expand_binop (SImode, and_optab,
7835                              operand_subword_force (operands[1], 0, XFmode),
7836                              GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
7837       if (result == 0)
7838         abort ();
7839
7840       if (result != target)
7841         emit_move_insn (result, target);
7842
7843       emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
7844                       operand_subword_force (operands[1], 1, XFmode));
7845       emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
7846                       operand_subword_force (operands[1], 2, XFmode));
7847
7848       insns = get_insns ();
7849       end_sequence ();
7850
7851       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
7852       DONE;
7853     }
7854 }")
7855
7856 (define_insn "absxf2_68881"
7857   [(set (match_operand:XF 0 "general_operand" "=f")
7858         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "fm")))]
7859   "TARGET_68881"
7860   "*
7861 {
7862   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
7863     return \"fabs%.x %1,%0\";
7864   return \"fabs%.x %f1,%0\";
7865 }")
7866
7867 (define_insn "sqrtxf2"
7868   [(set (match_operand:XF 0 "general_operand" "=f")
7869         (sqrt:XF (match_operand:XF 1 "nonimmediate_operand" "fm")))]
7870   "TARGET_68881"
7871   "fsqrt%.x %1,%0")
7872
7873 (define_insn "sinsf2"
7874   [(set (match_operand:SF 0 "general_operand" "=f")
7875         (unspec:SF [(match_operand:SF 1 "general_operand" "fm")] 1))]
7876   "TARGET_68881 && flag_fast_math"
7877   "*
7878 {
7879   if (FP_REG_P (operands[1]))
7880     return \"fsin%.x %1,%0\";
7881   else
7882     return \"fsin%.s %1,%0\";
7883 }")
7884
7885 (define_insn "sindf2"
7886   [(set (match_operand:DF 0 "general_operand" "=f")
7887         (unspec:DF [(match_operand:DF 1 "general_operand" "fm")] 1))]
7888   "TARGET_68881 && flag_fast_math"
7889   "*
7890 {
7891   if (FP_REG_P (operands[1]))
7892     return \"fsin%.x %1,%0\";
7893   else
7894     return \"fsin%.d %1,%0\";
7895 }")
7896
7897 (define_insn "sinxf2"
7898   [(set (match_operand:XF 0 "general_operand" "=f")
7899         (unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 1))]
7900   "TARGET_68881 && flag_fast_math"
7901   "fsin%.x %1,%0")
7902
7903 (define_insn "cossf2"
7904   [(set (match_operand:SF 0 "general_operand" "=f")
7905         (unspec:SF [(match_operand:SF 1 "general_operand" "fm")] 2))]
7906   "TARGET_68881 && flag_fast_math"
7907   "*
7908 {
7909   if (FP_REG_P (operands[1]))
7910     return \"fcos%.x %1,%0\";
7911   else
7912     return \"fcos%.s %1,%0\";
7913 }")
7914
7915 (define_insn "cosdf2"
7916   [(set (match_operand:DF 0 "general_operand" "=f")
7917         (unspec:DF [(match_operand:DF 1 "general_operand" "fm")] 2))]
7918   "TARGET_68881 && flag_fast_math"
7919   "*
7920 {
7921   if (FP_REG_P (operands[1]))
7922     return \"fcos%.x %1,%0\";
7923   else
7924     return \"fcos%.d %1,%0\";
7925 }")
7926
7927 (define_insn "cosxf2"
7928   [(set (match_operand:XF 0 "general_operand" "=f")
7929         (unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 2))]
7930   "TARGET_68881 && flag_fast_math"
7931   "fcos%.x %1,%0")