OSDN Git Service

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