OSDN Git Service

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