OSDN Git Service

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