OSDN Git Service

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