OSDN Git Service

(zero_extendsidi2): New pattern.
[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 ;; this one is the canonical form for (lshiftrt:DI x 32)
1372 (define_insn "zero_extendsidi2"
1373   [(set (match_operand:DI 0 "general_operand" "ro,<,>")
1374     (zero_extend:DI (match_operand:SI 1 "general_operand" "rm,rm,rm")))]
1375   ""
1376   "*
1377 {
1378   CC_STATUS_INIT;
1379   if (which_alternative == 2)
1380     return \"clr%.l %0\;move%.l %1,%0\";
1381   if (which_alternative == 1)
1382     return \"move%.l %1,%0\;clr%.l %0\";
1383   if (GET_CODE (operands[0]) == REG)
1384     operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1385   else
1386     operands[2] = adj_offsettable_operand (operands[0], 4);
1387   if (ADDRESS_REG_P (operands[0]))
1388     return \"move%.l %1,%2\;sub%.l %0,%0\";
1389   else
1390     return \"move%.l %1,%2\;clr%.l %0\";
1391 }")
1392
1393 (define_expand "zero_extendhisi2"
1394   [(set (match_operand:SI 0 "register_operand" "")
1395         (const_int 0))
1396    (set (strict_low_part (match_dup 2))
1397         (match_operand:HI 1 "general_operand" ""))]
1398   ""
1399   "
1400 {
1401   operands[1] = make_safe_from (operands[1], operands[0]);
1402   if (GET_CODE (operands[0]) == SUBREG)
1403     operands[2] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[0]),
1404                            SUBREG_WORD (operands[0]));
1405   else
1406     operands[2] = gen_rtx (SUBREG, HImode, operands[0], 0);
1407 }")
1408
1409 (define_expand "zero_extendqihi2"
1410   [(set (match_operand:HI 0 "register_operand" "")
1411         (const_int 0))
1412    (set (strict_low_part (match_dup 2))
1413         (match_operand:QI 1 "general_operand" ""))]
1414   ""
1415   "
1416 {
1417   operands[1] = make_safe_from (operands[1], operands[0]);
1418   if (GET_CODE (operands[0]) == SUBREG)
1419     operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]),
1420                            SUBREG_WORD (operands[0]));
1421   else
1422     operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0);
1423 }")
1424
1425 (define_expand "zero_extendqisi2"
1426   [(set (match_operand:SI 0 "register_operand" "")
1427         (const_int 0))
1428    (set (strict_low_part (match_dup 2))
1429         (match_operand:QI 1 "general_operand" ""))]
1430   ""
1431   "
1432 {
1433   operands[1] = make_safe_from (operands[1], operands[0]);
1434   if (GET_CODE (operands[0]) == SUBREG)
1435     operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]),
1436                            SUBREG_WORD (operands[0]));
1437   else
1438     operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0);
1439 }")
1440 \f
1441 ;; Patterns to recognize zero-extend insns produced by the combiner.
1442 ;; We don't allow both operands in memory, because of aliasing problems.
1443 ;; Explicitly disallow two memory operands via the condition since reloading
1444 ;; of this case will result in worse code than the uncombined patterns.
1445
1446 (define_insn ""
1447   [(set (match_operand:SI 0 "general_operand" "=do<>,d<")
1448         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1449   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1450   "*
1451 {
1452   if (DATA_REG_P (operands[0]))
1453     {
1454       if (GET_CODE (operands[1]) == REG
1455           && REGNO (operands[0]) == REGNO (operands[1]))
1456         return \"and%.l %#0xFFFF,%0\";
1457       if (reg_mentioned_p (operands[0], operands[1]))
1458         return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\";
1459       return \"clr%.l %0\;move%.w %1,%0\";
1460     }
1461   else if (GET_CODE (operands[0]) == MEM
1462            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1463     return \"move%.w %1,%0\;clr%.w %0\";
1464   else if (GET_CODE (operands[0]) == MEM
1465            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1466     return \"clr%.w %0\;move%.w %1,%0\";
1467   else
1468     {
1469       output_asm_insn (\"clr%.w %0\", operands);
1470       operands[0] = adj_offsettable_operand (operands[0], 2);
1471       return \"move%.w %1,%0\";
1472     }
1473 }")
1474
1475 (define_insn ""
1476   [(set (match_operand:HI 0 "general_operand" "=do<>,d")
1477         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
1478   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1479   "*
1480 {
1481   if (DATA_REG_P (operands[0]))
1482     {
1483       if (GET_CODE (operands[1]) == REG
1484           && REGNO (operands[0]) == REGNO (operands[1]))
1485         return \"and%.w %#0xFF,%0\";
1486       if (reg_mentioned_p (operands[0], operands[1]))
1487         return \"move%.b %1,%0\;and%.w %#0xFF,%0\";
1488       return \"clr%.w %0\;move%.b %1,%0\";
1489     }
1490   else if (GET_CODE (operands[0]) == MEM
1491            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1492     {
1493       if (REGNO (XEXP (XEXP (operands[0], 0), 0))
1494           == STACK_POINTER_REGNUM)
1495         {
1496           output_asm_insn (\"clr%.w %-\", operands);
1497           operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
1498                                  plus_constant (stack_pointer_rtx, 1));
1499           return \"move%.b %1,%0\";
1500         }
1501       else
1502         return \"move%.b %1,%0\;clr%.b %0\";
1503     }
1504   else if (GET_CODE (operands[0]) == MEM
1505            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1506     return \"clr%.b %0\;move%.b %1,%0\";
1507   else
1508     {
1509       output_asm_insn (\"clr%.b %0\", operands);
1510       operands[0] = adj_offsettable_operand (operands[0], 1);
1511       return \"move%.b %1,%0\";
1512     }
1513 }")
1514
1515 (define_insn ""
1516   [(set (match_operand:SI 0 "general_operand" "=do<>,d")
1517         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
1518   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1519   "*
1520 {
1521   if (DATA_REG_P (operands[0]))
1522     {
1523       if (GET_CODE (operands[1]) == REG
1524           && REGNO (operands[0]) == REGNO (operands[1]))
1525         return \"and%.l %#0xFF,%0\";
1526       if (reg_mentioned_p (operands[0], operands[1]))
1527         return \"move%.b %1,%0\;and%.l %#0xFF,%0\";
1528       return \"clr%.l %0\;move%.b %1,%0\";
1529     }
1530   else if (GET_CODE (operands[0]) == MEM
1531            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1532     {
1533       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1534 #ifdef MOTOROLA
1535 #ifdef SGS
1536       return \"clr%.l -(%0)\;move%.b %1,3(%0)\";
1537 #else
1538       return \"clr%.l -(%0)\;move%.b %1,(3,%0)\";
1539 #endif
1540 #else
1541       return \"clrl %0@-\;moveb %1,%0@(3)\";
1542 #endif
1543     }
1544   else if (GET_CODE (operands[0]) == MEM
1545            && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1546     {
1547       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1548 #ifdef MOTOROLA
1549 #ifdef SGS
1550       return \"clr%.l (%0)+\;move%.b %1,-1(%0)\";
1551 #else
1552       return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\";
1553 #endif
1554 #else
1555       return \"clrl %0@+\;moveb %1,%0@(-1)\";
1556 #endif
1557     }
1558   else
1559     {
1560       output_asm_insn (\"clr%.l %0\", operands);
1561       operands[0] = adj_offsettable_operand (operands[0], 3);
1562       return \"move%.b %1,%0\";
1563     }
1564 }")
1565 \f
1566 ;; sign extension instructions
1567
1568 (define_insn "extendqidi2"
1569   [(set (match_operand:DI 0 "register_operand" "=d")
1570         (sign_extend:DI
1571          (match_operand:QI 1 "general_operand" "rm")))]
1572   ""
1573   "*
1574 {
1575   CC_STATUS_INIT;
1576   operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1577   if (TARGET_68020)
1578     return \"move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0\";
1579   else
1580     return \"move%.b %1,%2\;ext%.w %0\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0\";
1581 }")
1582
1583 (define_insn "extendhidi2"
1584   [(set (match_operand:DI 0 "register_operand" "=d")
1585         (sign_extend:DI
1586          (match_operand:HI 1 "general_operand" "rm")))]
1587   ""
1588   "*
1589 {
1590   CC_STATUS_INIT;
1591   operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1592   if (TARGET_68020)
1593     return \"move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0\";
1594   else
1595     return \"move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0\";
1596 }")
1597
1598 (define_insn "extendsidi2"
1599   [(set (match_operand:DI 0 "register_operand" "=d")
1600         (sign_extend:DI
1601          (match_operand:SI 1 "general_operand" "rm")))]
1602   ""
1603   "*
1604 {
1605   CC_STATUS_INIT;
1606   operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1607   if (TARGET_68020)
1608     return \"move%.l %1,%2\;smi %0\;extb%.l %0\";
1609   else
1610     return \"move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0\";
1611 }")
1612
1613 ;; Special case when one can avoid register clobbering, copy and test
1614 ;; Maybe there is a way to make that the general case, by forcing the
1615 ;; result of the SI tree to be in the lower register of the DI target
1616
1617 (define_insn "extendplussidi"
1618   [(set (match_operand:DI 0 "register_operand" "=d")
1619     (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
1620             (match_operand:SI 2 "general_operand" "rmn"))))]
1621   ""
1622   "*
1623 {
1624   CC_STATUS_INIT;
1625   operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1626   if (GET_CODE (operands[1]) == CONST_INT
1627   && (unsigned) INTVAL (operands[1]) > 8)
1628     {
1629       rtx tmp = operands[1];
1630
1631       operands[1] = operands[2];
1632       operands[2] = tmp;
1633     }
1634   if (TARGET_68020)
1635     return \"move%.l %2,%3\;add%.l %1,%3\;smi %0\;extb%.l %0\";
1636   else
1637     return \"move%.l %2,%3\;add%.l %1,%3\;smi %0\;ext%.w %0\;ext%.l %0\";
1638 }")
1639
1640 (define_insn "extendhisi2"
1641   [(set (match_operand:SI 0 "general_operand" "=*d,a")
1642         (sign_extend:SI
1643          (match_operand:HI 1 "nonimmediate_operand" "0,rm")))]
1644   ""
1645   "*
1646 {
1647   if (ADDRESS_REG_P (operands[0]))
1648     return \"move%.w %1,%0\";
1649   return \"ext%.l %0\";
1650 }")
1651
1652 (define_insn "extendqihi2"
1653   [(set (match_operand:HI 0 "general_operand" "=d")
1654         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1655   ""
1656   "ext%.w %0")
1657
1658 (define_insn "extendqisi2"
1659   [(set (match_operand:SI 0 "general_operand" "=d")
1660         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1661   "TARGET_68020"
1662   "extb%.l %0")
1663 \f
1664 ;; Conversions between float and double.
1665
1666 (define_expand "extendsfdf2"
1667   [(set (match_operand:DF 0 "general_operand" "")
1668         (float_extend:DF
1669          (match_operand:SF 1 "general_operand" "")))]
1670   "TARGET_68881 || TARGET_FPA"
1671   "")
1672
1673 (define_insn ""
1674   [(set (match_operand:DF 0 "general_operand" "=x,y")
1675         (float_extend:DF
1676          (match_operand:SF 1 "general_operand" "xH,rmF")))]
1677   "TARGET_FPA"
1678   "fpstod %w1,%0")
1679
1680 (define_insn ""
1681   [(set (match_operand:DF 0 "general_operand" "=*fdm,f")
1682         (float_extend:DF
1683           (match_operand:SF 1 "general_operand" "f,dmF")))]
1684   "TARGET_68881"
1685   "*
1686 {
1687   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1688     {
1689       if (REGNO (operands[0]) == REGNO (operands[1]))
1690         {
1691           /* Extending float to double in an fp-reg is a no-op.
1692              NOTICE_UPDATE_CC has already assumed that the
1693              cc will be set.  So cancel what it did.  */
1694           cc_status = cc_prev_status;
1695           return \"\";
1696         }
1697       return \"f%&move%.x %1,%0\";
1698     }
1699   if (FP_REG_P (operands[0]))
1700     return \"f%&move%.s %f1,%0\";
1701   if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
1702     {
1703       output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1704       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1705       return \"move%.l %+,%0\";
1706     }
1707   return \"fmove%.d %f1,%0\";
1708 }")
1709
1710 ;; This cannot output into an f-reg because there is no way to be
1711 ;; sure of truncating in that case.
1712 ;; But on the Sun FPA, we can be sure.
1713 (define_expand "truncdfsf2"
1714   [(set (match_operand:SF 0 "general_operand" "")
1715         (float_truncate:SF
1716           (match_operand:DF 1 "general_operand" "")))]
1717   "TARGET_68881 || TARGET_FPA"
1718   "")
1719
1720 (define_insn ""
1721   [(set (match_operand:SF 0 "general_operand" "=x,y")
1722         (float_truncate:SF
1723           (match_operand:DF 1 "general_operand" "xH,rmF")))]
1724   "TARGET_FPA"
1725   "fpdtos %y1,%0")
1726
1727 ;; On the '040 we can truncate in a register accurately and easily.
1728 (define_insn ""
1729   [(set (match_operand:SF 0 "general_operand" "=f")
1730         (float_truncate:SF
1731           (match_operand:DF 1 "general_operand" "fmG")))]
1732   "TARGET_68040_ONLY"
1733   "*
1734 {
1735   if (FP_REG_P (operands[1]))
1736     return \"f%$move%.x %1,%0\";
1737   return \"f%$move%.d %f1,%0\";
1738 }")
1739
1740 (define_insn ""
1741   [(set (match_operand:SF 0 "general_operand" "=dm")
1742         (float_truncate:SF
1743           (match_operand:DF 1 "general_operand" "f")))]
1744   "TARGET_68881"
1745   "fmove%.s %f1,%0")
1746 \f
1747 ;; Conversion between fixed point and floating point.
1748 ;; Note that among the fix-to-float insns
1749 ;; the ones that start with SImode come first.
1750 ;; That is so that an operand that is a CONST_INT
1751 ;; (and therefore lacks a specific machine mode).
1752 ;; will be recognized as SImode (which is always valid)
1753 ;; rather than as QImode or HImode.
1754
1755 (define_expand "floatsisf2"
1756   [(set (match_operand:SF 0 "general_operand" "")
1757         (float:SF (match_operand:SI 1 "general_operand" "")))]
1758   "TARGET_68881 || TARGET_FPA"
1759   "")
1760
1761 (define_insn ""
1762   [(set (match_operand:SF 0 "general_operand" "=y,x")
1763         (float:SF (match_operand:SI 1 "general_operand" "rmi,x")))]
1764   "TARGET_FPA"
1765   "fpltos %1,%0")
1766
1767 (define_insn ""
1768   [(set (match_operand:SF 0 "general_operand" "=f")
1769         (float:SF (match_operand:SI 1 "general_operand" "dmi")))]
1770   "TARGET_68881"
1771   "f%$move%.l %1,%0")
1772
1773 (define_expand "floatsidf2"
1774   [(set (match_operand:DF 0 "general_operand" "")
1775         (float:DF (match_operand:SI 1 "general_operand" "")))]
1776   "TARGET_68881 || TARGET_FPA"
1777   "")
1778
1779 (define_insn ""
1780   [(set (match_operand:DF 0 "general_operand" "=y,x")
1781         (float:DF (match_operand:SI 1 "general_operand" "rmi,x")))]
1782   "TARGET_FPA"
1783   "fpltod %1,%0")
1784
1785 (define_insn ""
1786   [(set (match_operand:DF 0 "general_operand" "=f")
1787         (float:DF (match_operand:SI 1 "general_operand" "dmi")))]
1788   "TARGET_68881"
1789   "f%&move%.l %1,%0")
1790
1791 (define_insn "floathisf2"
1792   [(set (match_operand:SF 0 "general_operand" "=f")
1793         (float:SF (match_operand:HI 1 "general_operand" "dmn")))]
1794   "TARGET_68881"
1795   "f%$move%.w %1,%0")
1796
1797 (define_insn "floathidf2"
1798   [(set (match_operand:DF 0 "general_operand" "=f")
1799         (float:DF (match_operand:HI 1 "general_operand" "dmn")))]
1800   "TARGET_68881"
1801   "fmove%.w %1,%0")
1802
1803 (define_insn "floatqisf2"
1804   [(set (match_operand:SF 0 "general_operand" "=f")
1805         (float:SF (match_operand:QI 1 "general_operand" "dmn")))]
1806   "TARGET_68881"
1807   "fmove%.b %1,%0")
1808
1809 (define_insn "floatqidf2"
1810   [(set (match_operand:DF 0 "general_operand" "=f")
1811         (float:DF (match_operand:QI 1 "general_operand" "dmn")))]
1812   "TARGET_68881"
1813   "f%&move%.b %1,%0")
1814
1815 ;; New routines to convert floating-point values to integers
1816 ;; to be used on the '040.  These should be faster than trapping
1817 ;; into the kernel to emulate fintrz.  They should also be faster
1818 ;; than calling the subroutines fixsfsi or fixdfsi.
1819
1820 (define_insn "fix_truncdfsi2"
1821   [(set (match_operand:SI 0 "general_operand" "=dm")
1822         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1823    (clobber (match_scratch:SI 2 "=d"))
1824    (clobber (match_scratch:SI 3 "=d"))]
1825   "TARGET_68881 && TARGET_68040"
1826   "*
1827 {
1828   CC_STATUS_INIT;
1829   return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.l %1,%0\;fmovem%.l %2,%!\";
1830 }")
1831
1832 (define_insn "fix_truncdfhi2"
1833   [(set (match_operand:HI 0 "general_operand" "=dm")
1834         (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1835    (clobber (match_scratch:SI 2 "=d"))
1836    (clobber (match_scratch:SI 3 "=d"))]
1837   "TARGET_68881 && TARGET_68040"
1838   "*
1839 {
1840   CC_STATUS_INIT;
1841   return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.w %1,%0\;fmovem%.l %2,%!\";
1842 }")
1843
1844 (define_insn "fix_truncdfqi2"
1845   [(set (match_operand:QI 0 "general_operand" "=dm")
1846         (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1847    (clobber (match_scratch:SI 2 "=d"))
1848    (clobber (match_scratch:SI 3 "=d"))]
1849   "TARGET_68881 && TARGET_68040"
1850   "*
1851 {
1852   CC_STATUS_INIT;
1853   return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.b %1,%0\;fmovem%.l %2,%!\";
1854 }")
1855
1856 ;; Convert a float to a float whose value is an integer.
1857 ;; This is the first stage of converting it to an integer type.
1858
1859 (define_insn "ftruncdf2"
1860   [(set (match_operand:DF 0 "general_operand" "=f")
1861         (fix:DF (match_operand:DF 1 "general_operand" "fFm")))]
1862   "TARGET_68881 && !TARGET_68040"
1863   "*
1864 {
1865   if (FP_REG_P (operands[1]))
1866     return \"fintrz%.x %f1,%0\";
1867   return \"fintrz%.d %f1,%0\";
1868 }")
1869
1870 (define_insn "ftruncsf2"
1871   [(set (match_operand:SF 0 "general_operand" "=f")
1872         (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))]
1873   "TARGET_68881 && !TARGET_68040"
1874   "*
1875 {
1876   if (FP_REG_P (operands[1]))
1877     return \"fintrz%.x %f1,%0\";
1878   return \"fintrz%.s %f1,%0\";
1879 }")
1880
1881 ;; Convert a float whose value is an integer
1882 ;; to an actual integer.  Second stage of converting float to integer type.
1883 (define_insn "fixsfqi2"
1884   [(set (match_operand:QI 0 "general_operand" "=dm")
1885         (fix:QI (match_operand:SF 1 "general_operand" "f")))]
1886   "TARGET_68881"
1887   "fmove%.b %1,%0")
1888
1889 (define_insn "fixsfhi2"
1890   [(set (match_operand:HI 0 "general_operand" "=dm")
1891         (fix:HI (match_operand:SF 1 "general_operand" "f")))]
1892   "TARGET_68881"
1893   "fmove%.w %1,%0")
1894
1895 (define_insn "fixsfsi2"
1896   [(set (match_operand:SI 0 "general_operand" "=dm")
1897         (fix:SI (match_operand:SF 1 "general_operand" "f")))]
1898   "TARGET_68881"
1899   "fmove%.l %1,%0")
1900
1901 (define_insn "fixdfqi2"
1902   [(set (match_operand:QI 0 "general_operand" "=dm")
1903         (fix:QI (match_operand:DF 1 "general_operand" "f")))]
1904   "TARGET_68881"
1905   "fmove%.b %1,%0")
1906
1907 (define_insn "fixdfhi2"
1908   [(set (match_operand:HI 0 "general_operand" "=dm")
1909         (fix:HI (match_operand:DF 1 "general_operand" "f")))]
1910   "TARGET_68881"
1911   "fmove%.w %1,%0")
1912
1913 (define_insn "fixdfsi2"
1914   [(set (match_operand:SI 0 "general_operand" "=dm")
1915         (fix:SI (match_operand:DF 1 "general_operand" "f")))]
1916   "TARGET_68881"
1917   "fmove%.l %1,%0")
1918
1919 ;; Convert a float to an integer.
1920 ;; On the Sun FPA, this is done in one step.
1921
1922 (define_insn ""
1923   [(set (match_operand:SI 0 "general_operand" "=x,y")
1924         (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "xH,rmF"))))]
1925   "TARGET_FPA"
1926   "fpstol %w1,%0")
1927
1928 (define_insn ""
1929   [(set (match_operand:SI 0 "general_operand" "=x,y")
1930         (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "xH,rmF"))))]
1931   "TARGET_FPA"
1932   "fpdtol %y1,%0")
1933 \f
1934 ;; add instructions
1935
1936 (define_insn "adddia_sexthishl32"
1937   [(set (match_operand:DI 0 "register_operand" "+a")
1938     (plus:DI (ashift:DI (sign_extend:DI
1939           (match_operand:HI 1 "general_operand" "rm"))
1940             (const_int 32))
1941         (match_dup 0)))]
1942   ""
1943   "*
1944 {
1945   CC_STATUS_INIT;
1946   return \"add%.w %1,%0\";
1947 } ")
1948
1949 (define_insn "adddid_sexthishl32"
1950   [(set (match_operand:DI 0 "register_operand" "+do")
1951     (plus:DI (ashift:DI (sign_extend:DI
1952           (match_operand:HI 1 "general_operand" "rm"))
1953             (const_int 32))
1954         (match_dup 0)))
1955    (clobber (match_scratch:SI 2 "=a"))]
1956   ""
1957   "*
1958 {
1959   CC_STATUS_INIT;
1960   return \"move%.w %1,%2\;add%.l %2,%0\";
1961 } ")
1962
1963 (define_insn "adddi_dilshr32"
1964   [(set (match_operand:DI 0 "general_operand" "=ro")
1965     (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
1966             (const_int 32))
1967         (match_operand:DI 2 "general_operand" "0")))]
1968   ""
1969   "*
1970 {
1971   CC_STATUS_INIT;
1972   if (GET_CODE (operands[0]) == REG)
1973     operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1974   else
1975     operands[0] = adj_offsettable_operand (operands[0], 4);
1976   return \"add%.l %1,%0\";
1977 } ")
1978
1979 (define_insn "adddi_dishl32"
1980   [(set (match_operand:DI 0 "general_operand" "=ro")
1981     (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro")
1982             (const_int 32))
1983         (match_operand:DI 2 "general_operand" "0")))]
1984   ""
1985   "*
1986 {
1987   CC_STATUS_INIT;
1988   if (GET_CODE (operands[1]) == REG)
1989     operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1990   else
1991     operands[1] = adj_offsettable_operand (operands[1], 4);
1992   return \"add%.l %1,%0\";
1993 } ")
1994
1995 (define_insn "adddi_mem"
1996   [(set (match_operand:DI 0 "general_operand" "=m")
1997         (plus:DI (match_operand:DI 1 "general_operand" "%0")
1998                  (match_operand:DI 2 "general_operand" "d")))
1999    (clobber (match_scratch:SI 3 "=d"))]
2000   ""
2001   "*
2002 {
2003   CC_STATUS_INIT;
2004   operands[1] = adj_offsettable_operand (operands[0], 4);
2005   operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
2006   return \"add%.l %4,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\";
2007 } ")
2008
2009 (define_insn "adddi3"
2010   [(set (match_operand:DI 0 "general_operand" "=d,d,d,<")
2011         (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0")
2012                  (match_operand:DI 2 "general_operand" "ao,>,d,<")))]
2013   ""
2014   "*
2015 {
2016   if (which_alternative == 3)
2017     return \"add%.l %2,%0\;addx%.l %2,%0\";
2018   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
2019   if (which_alternative == 1)
2020     {
2021       CC_STATUS_INIT;
2022       return \"add%.l %2,%0\;add%.l %2,%1\;negx%.l %0\;neg%.l %0\";
2023     }
2024   if (GET_CODE (operands[2]) == REG)
2025     operands[3] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
2026   else
2027     operands[3] = adj_offsettable_operand (operands[2], 4);
2028   if (which_alternative == 2)
2029     return \"add%.l %3,%1\;addx%.l %2,%0\";
2030   CC_STATUS_INIT;
2031   /* negx + neg simulates (non-existent) addx #0 */
2032   /* TODO : this should work also for CONST operands[2] */
2033   return \"add%.l %3,%1\;negx%.l %0\;neg%.l %0\;add%.l %2,%0\";
2034 } ")
2035
2036 ;; Note that the middle two alternatives are near-duplicates
2037 ;; in order to handle insns generated by reload.
2038 ;; This is needed since they are not themselves reloaded,
2039 ;; so commutativity won't apply to them.
2040 (define_insn "addsi3"
2041   [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r")
2042         (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
2043                  (match_operand:SI 2 "general_operand" "dIKLs,rJK,a,mrIKLs")))]
2044   ""
2045   "*
2046 {
2047   if (! operands_match_p (operands[0], operands[1]))
2048     {
2049       if (!ADDRESS_REG_P (operands[1]))
2050         {
2051           rtx tmp = operands[1];
2052
2053           operands[1] = operands[2];
2054           operands[2] = tmp;
2055         }
2056
2057       /* These insns can result from reloads to access
2058          stack slots over 64k from the frame pointer.  */
2059       if (GET_CODE (operands[2]) == CONST_INT
2060           && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
2061         return \"move%.l %2,%0\;add%.l %1,%0\";
2062 #ifdef SGS
2063       if (GET_CODE (operands[2]) == REG)
2064         return \"lea 0(%1,%2.l),%0\";
2065       else
2066         return \"lea %c2(%1),%0\";
2067 #else /* not SGS */
2068 #ifdef MOTOROLA
2069       if (GET_CODE (operands[2]) == REG)
2070         return \"lea (%1,%2.l),%0\";
2071       else
2072         return \"lea (%c2,%1),%0\";
2073 #else /* not MOTOROLA (MIT syntax) */
2074       if (GET_CODE (operands[2]) == REG)
2075         return \"lea %1@(0,%2:l),%0\";
2076       else
2077         return \"lea %1@(%c2),%0\";
2078 #endif /* not MOTOROLA */
2079 #endif /* not SGS */
2080     }
2081   if (GET_CODE (operands[2]) == CONST_INT)
2082     {
2083 #ifndef NO_ADDSUB_Q
2084       if (INTVAL (operands[2]) > 0
2085           && INTVAL (operands[2]) <= 8)
2086         return (ADDRESS_REG_P (operands[0])
2087                 ? \"addq%.w %2,%0\"
2088                 : \"addq%.l %2,%0\");
2089       if (INTVAL (operands[2]) < 0
2090           && INTVAL (operands[2]) >= -8)
2091         {
2092           operands[2] = gen_rtx (CONST_INT, VOIDmode,
2093                                  - INTVAL (operands[2]));
2094           return (ADDRESS_REG_P (operands[0])
2095                   ? \"subq%.w %2,%0\"
2096                   : \"subq%.l %2,%0\");
2097         }
2098       /* On everything except the 68000 it is faster to use two
2099          addqw instructions to add a small integer (8 < N <= 16)
2100          to an address register.  Likewise for subqw.*/
2101       if (INTVAL (operands[2]) > 8
2102           && INTVAL (operands[2]) <= 16
2103           && ADDRESS_REG_P (operands[0])
2104           && TARGET_68020) 
2105         {
2106           operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
2107           return \"addq%.w %#8,%0\;addq%.w %2,%0\";
2108         }
2109       if (INTVAL (operands[2]) < -8
2110           && INTVAL (operands[2]) >= -16
2111           && ADDRESS_REG_P (operands[0])
2112           && TARGET_68020) 
2113         {
2114           operands[2] = gen_rtx (CONST_INT, VOIDmode, 
2115                                   - INTVAL (operands[2]) - 8);
2116           return \"subq%.w %#8,%0\;subq%.w %2,%0\";
2117         }
2118 #endif
2119       if (ADDRESS_REG_P (operands[0])
2120           && INTVAL (operands[2]) >= -0x8000
2121           && INTVAL (operands[2]) < 0x8000)
2122         return \"add%.w %2,%0\";
2123     }
2124   return \"add%.l %2,%0\";
2125 }")
2126
2127 (define_insn ""
2128   [(set (match_operand:SI 0 "general_operand" "=a")
2129         (plus:SI (match_operand:SI 1 "general_operand" "0")
2130                  (sign_extend:SI
2131                   (match_operand:HI 2 "nonimmediate_operand" "rm"))))]
2132   ""
2133   "add%.w %2,%0")
2134
2135 (define_insn "addhi3"
2136   [(set (match_operand:HI 0 "general_operand" "=m,r")
2137         (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
2138                  (match_operand:HI 2 "general_operand" "dn,rmn")))]
2139   ""
2140   "*
2141 {
2142 #ifndef NO_ADDSUB_Q
2143   if (GET_CODE (operands[2]) == CONST_INT)
2144     {
2145       /* If the constant would be a negative number when interpreted as
2146          HImode, make it negative.  This is usually, but not always, done
2147          elsewhere in the compiler.  First check for constants out of range,
2148          which could confuse us.  */
2149
2150       if (INTVAL (operands[2]) >= 32768)
2151         operands[2] = gen_rtx (CONST_INT, VOIDmode,
2152                                INTVAL (operands[2]) - 65536);
2153
2154       if (INTVAL (operands[2]) > 0
2155           && INTVAL (operands[2]) <= 8)
2156         return \"addq%.w %2,%0\";
2157       if (INTVAL (operands[2]) < 0
2158           && INTVAL (operands[2]) >= -8)
2159         {
2160           operands[2] = gen_rtx (CONST_INT, VOIDmode,
2161                                  - INTVAL (operands[2]));
2162           return \"subq%.w %2,%0\";
2163         }
2164       /* On everything except the 68000 it is faster to use two
2165          addqw instructions to add a small integer (8 < N <= 16)
2166          to an address register.  Likewise for subqw. */
2167       if (INTVAL (operands[2]) > 8
2168           && INTVAL (operands[2]) <= 16
2169           && ADDRESS_REG_P (operands[0])
2170           && TARGET_68020) 
2171         {
2172           operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
2173           return \"addq%.w %#8,%0\;addq%.w %2,%0\";
2174         }
2175       if (INTVAL (operands[2]) < -8
2176           && INTVAL (operands[2]) >= -16
2177           && ADDRESS_REG_P (operands[0])
2178           && TARGET_68020) 
2179         {
2180           operands[2] = gen_rtx (CONST_INT, VOIDmode, 
2181                                  - INTVAL (operands[2]) - 8);
2182           return \"subq%.w %#8,%0\;subq%.w %2,%0\";
2183         }
2184     }
2185 #endif
2186   return \"add%.w %2,%0\";
2187 }")
2188
2189 ;; These insns must use MATCH_DUP instead of the more expected
2190 ;; use of a matching constraint because the "output" here is also
2191 ;; an input, so you can't use the matching constraint.  That also means
2192 ;; that you can't use the "%", so you need patterns with the matched
2193 ;; operand in both positions.
2194
2195 (define_insn ""
2196   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2197         (plus:HI (match_dup 0)
2198                  (match_operand:HI 1 "general_operand" "dn,rmn")))]
2199   ""
2200   "*
2201 {
2202 #ifndef NO_ADDSUB_Q
2203   if (GET_CODE (operands[1]) == CONST_INT)
2204     {
2205       /* If the constant would be a negative number when interpreted as
2206          HImode, make it negative.  This is usually, but not always, done
2207          elsewhere in the compiler.  First check for constants out of range,
2208          which could confuse us.  */
2209
2210       if (INTVAL (operands[1]) >= 32768)
2211         operands[1] = gen_rtx (CONST_INT, VOIDmode,
2212                                INTVAL (operands[1]) - 65536);
2213
2214       if (INTVAL (operands[1]) > 0
2215           && INTVAL (operands[1]) <= 8)
2216         return \"addq%.w %1,%0\";
2217       if (INTVAL (operands[1]) < 0
2218           && INTVAL (operands[1]) >= -8)
2219         {
2220           operands[1] = gen_rtx (CONST_INT, VOIDmode,
2221                                  - INTVAL (operands[1]));
2222           return \"subq%.w %1,%0\";
2223         }
2224       /* On everything except the 68000 it is faster to use two
2225          addqw instructions to add a small integer (8 < N <= 16)
2226          to an address register.  Likewise for subqw. */
2227       if (INTVAL (operands[1]) > 8
2228           && INTVAL (operands[1]) <= 16
2229           && ADDRESS_REG_P (operands[0])
2230           && TARGET_68020) 
2231         {
2232           operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8);
2233           return \"addq%.w %#8,%0\;addq%.w %1,%0\";
2234         }
2235       if (INTVAL (operands[1]) < -8
2236           && INTVAL (operands[1]) >= -16
2237           && ADDRESS_REG_P (operands[0])
2238           && TARGET_68020) 
2239         {
2240           operands[1] = gen_rtx (CONST_INT, VOIDmode, 
2241                                  - INTVAL (operands[1]) - 8);
2242           return \"subq%.w %#8,%0\;subq%.w %1,%0\";
2243         }
2244     }
2245 #endif
2246   return \"add%.w %1,%0\";
2247 }")
2248
2249 (define_insn ""
2250   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2251         (plus:HI (match_operand:HI 1 "general_operand" "dn,rmn")
2252                  (match_dup 0)))]
2253   ""
2254   "*
2255 {
2256 #ifndef NO_ADDSUB_Q
2257   if (GET_CODE (operands[1]) == CONST_INT)
2258     {
2259       /* If the constant would be a negative number when interpreted as
2260          HImode, make it negative.  This is usually, but not always, done
2261          elsewhere in the compiler.  First check for constants out of range,
2262          which could confuse us.  */
2263
2264       if (INTVAL (operands[1]) >= 32768)
2265         operands[1] = gen_rtx (CONST_INT, VOIDmode,
2266                                INTVAL (operands[1]) - 65536);
2267
2268       if (INTVAL (operands[1]) > 0
2269           && INTVAL (operands[1]) <= 8)
2270         return \"addq%.w %1,%0\";
2271       if (INTVAL (operands[1]) < 0
2272           && INTVAL (operands[1]) >= -8)
2273         {
2274           operands[1] = gen_rtx (CONST_INT, VOIDmode,
2275                                  - INTVAL (operands[1]));
2276           return \"subq%.w %1,%0\";
2277         }
2278       /* On everything except the 68000 it is faster to use two
2279          addqw instructions to add a small integer (8 < N <= 16)
2280          to an address register.  Likewise for subqw. */
2281       if (INTVAL (operands[1]) > 8
2282           && INTVAL (operands[1]) <= 16
2283           && ADDRESS_REG_P (operands[0])
2284           && TARGET_68020) 
2285         {
2286           operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8);
2287           return \"addq%.w %#8,%0\;addq%.w %1,%0\";
2288         }
2289       if (INTVAL (operands[1]) < -8
2290           && INTVAL (operands[1]) >= -16
2291           && ADDRESS_REG_P (operands[0])
2292           && TARGET_68020) 
2293         {
2294           operands[1] = gen_rtx (CONST_INT, VOIDmode, 
2295                                  - INTVAL (operands[1]) - 8);
2296           return \"subq%.w %#8,%0\;subq%.w %1,%0\";
2297         }
2298     }
2299 #endif
2300   return \"add%.w %1,%0\";
2301 }")
2302
2303 (define_insn "addqi3"
2304   [(set (match_operand:QI 0 "general_operand" "=m,d")
2305         (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
2306                  (match_operand:QI 2 "general_operand" "dn,dmn")))]
2307   ""
2308   "*
2309 {
2310 #ifndef NO_ADDSUB_Q
2311   if (GET_CODE (operands[2]) == CONST_INT)
2312     {
2313       if (INTVAL (operands[2]) >= 128)
2314         operands[2] = gen_rtx (CONST_INT, VOIDmode,
2315                                INTVAL (operands[2]) - 256);
2316
2317       if (INTVAL (operands[2]) > 0
2318           && INTVAL (operands[2]) <= 8)
2319         return \"addq%.b %2,%0\";
2320       if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
2321        {
2322          operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
2323          return \"subq%.b %2,%0\";
2324        }
2325     }
2326 #endif
2327   return \"add%.b %2,%0\";
2328 }")
2329
2330 (define_insn ""
2331   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2332         (plus:QI (match_dup 0)
2333                  (match_operand:QI 1 "general_operand" "dn,dmn")))]
2334   ""
2335   "*
2336 {
2337 #ifndef NO_ADDSUB_Q
2338   if (GET_CODE (operands[1]) == CONST_INT)
2339     {
2340       if (INTVAL (operands[1]) >= 128)
2341         operands[1] = gen_rtx (CONST_INT, VOIDmode,
2342                                INTVAL (operands[1]) - 256);
2343
2344       if (INTVAL (operands[1]) > 0
2345           && INTVAL (operands[1]) <= 8)
2346         return \"addq%.b %1,%0\";
2347       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2348        {
2349          operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]));
2350          return \"subq%.b %1,%0\";
2351        }
2352     }
2353 #endif
2354   return \"add%.b %1,%0\";
2355 }")
2356
2357 (define_insn ""
2358   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2359         (plus:QI (match_operand:QI 1 "general_operand" "dn,dmn")
2360                  (match_dup 0)))]
2361   ""
2362   "*
2363 {
2364 #ifndef NO_ADDSUB_Q
2365   if (GET_CODE (operands[1]) == CONST_INT)
2366     {
2367       if (INTVAL (operands[1]) >= 128)
2368         operands[1] = gen_rtx (CONST_INT, VOIDmode,
2369                                INTVAL (operands[1]) - 256);
2370
2371       if (INTVAL (operands[1]) > 0
2372           && INTVAL (operands[1]) <= 8)
2373         return \"addq%.b %1,%0\";
2374       if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2375        {
2376          operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]));
2377          return \"subq%.b %1,%0\";
2378        }
2379     }
2380 #endif
2381   return \"add%.b %1,%0\";
2382 }")
2383
2384 (define_expand "adddf3"
2385   [(set (match_operand:DF 0 "general_operand" "")
2386         (plus:DF (match_operand:DF 1 "general_operand" "")
2387                  (match_operand:DF 2 "general_operand" "")))]
2388   "TARGET_68881 || TARGET_FPA"
2389   "")
2390
2391 (define_insn ""
2392   [(set (match_operand:DF 0 "general_operand" "=x,y")
2393         (plus:DF (match_operand:DF 1 "general_operand" "%xH,y")
2394                  (match_operand:DF 2 "general_operand" "xH,dmF")))]
2395   "TARGET_FPA"
2396   "*
2397 {
2398   if (rtx_equal_p (operands[0], operands[1]))
2399     return \"fpadd%.d %y2,%0\";
2400   if (rtx_equal_p (operands[0], operands[2]))
2401     return \"fpadd%.d %y1,%0\";
2402   if (which_alternative == 0)
2403     return \"fpadd3%.d %w2,%w1,%0\";
2404   return \"fpadd3%.d %x2,%x1,%0\";
2405 }")
2406
2407 (define_insn ""
2408   [(set (match_operand:DF 0 "general_operand" "=f")
2409         (plus:DF (match_operand:DF 1 "general_operand" "%0")
2410                  (match_operand:DF 2 "general_operand" "fmG")))]
2411   "TARGET_68881"
2412   "*
2413 {
2414   if (REG_P (operands[2]))
2415     return \"f%&add%.x %2,%0\";
2416   return \"f%&add%.d %f2,%0\";
2417 }")
2418
2419 (define_expand "addsf3"
2420   [(set (match_operand:SF 0 "general_operand" "")
2421         (plus:SF (match_operand:SF 1 "general_operand" "")
2422                  (match_operand:SF 2 "general_operand" "")))]
2423   "TARGET_68881 || TARGET_FPA"
2424   "")
2425
2426 (define_insn ""
2427   [(set (match_operand:SF 0 "general_operand" "=x,y")
2428         (plus:SF (match_operand:SF 1 "general_operand" "%xH,y")
2429                  (match_operand:SF 2 "general_operand" "xH,rmF")))]
2430   "TARGET_FPA"
2431   "*
2432 {
2433   if (rtx_equal_p (operands[0], operands[1]))
2434     return \"fpadd%.s %w2,%0\";
2435   if (rtx_equal_p (operands[0], operands[2]))
2436     return \"fpadd%.s %w1,%0\";
2437   if (which_alternative == 0)
2438     return \"fpadd3%.s %w2,%w1,%0\";
2439   return \"fpadd3%.s %2,%1,%0\";
2440 }")
2441
2442 (define_insn ""
2443   [(set (match_operand:SF 0 "general_operand" "=f")
2444         (plus:SF (match_operand:SF 1 "general_operand" "%0")
2445                  (match_operand:SF 2 "general_operand" "fdmF")))]
2446   "TARGET_68881"
2447   "*
2448 {
2449   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2450     return \"f%$add%.x %2,%0\";
2451   return \"f%$add%.s %f2,%0\";
2452 }")
2453 \f
2454 ;; subtract instructions
2455
2456 (define_insn "subdia_sexthishl32"
2457   [(set (match_operand:DI 0 "register_operand" "+a")
2458     (minus:DI (match_dup 0)
2459         (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
2460             (const_int 32))))]
2461   ""
2462   "*
2463 {
2464   CC_STATUS_INIT;
2465   return \"sub%.w %1,%0\";
2466 } ")
2467
2468 (define_insn "subdid_sexthishl32"
2469   [(set (match_operand:DI 0 "register_operand" "+do")
2470     (minus:DI (match_dup 0)
2471         (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
2472             (const_int 32))))
2473    (clobber (match_scratch:SI 2 "=a"))]
2474   ""
2475   "*
2476 {
2477   CC_STATUS_INIT;
2478   return \"move%.w %1,%2\;sub%.l %2,%0\";
2479 } ")
2480
2481 (define_insn "subdi_dishl32"
2482   [(set (match_operand:DI 0 "register_operand" "+d")
2483     (minus:DI (match_dup 0)
2484         (ashift:DI (match_operand:DI 1 "register_operand" "d")
2485             (const_int 32))))]
2486   ""
2487   "*
2488 {
2489   CC_STATUS_INIT;
2490   operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
2491   return \"sub%.l %1,%0\";
2492 } ")
2493
2494 (define_insn "subdi_mem"
2495   [(set (match_operand:DI 0 "general_operand" "=m")
2496         (minus:DI (match_operand:DI 1 "general_operand" "0")
2497                  (match_operand:DI 2 "general_operand" "d")))
2498    (clobber (match_scratch:SI 3 "=d"))]
2499   ""
2500   "*
2501 {
2502   CC_STATUS_INIT;
2503   operands[1] = adj_offsettable_operand (operands[0], 4);
2504   operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
2505   return \"sub%.l %4,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\";
2506 } ")
2507
2508 (define_insn "subdi3"
2509   [(set (match_operand:DI 0 "general_operand" "=d,d,d,<")
2510         (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
2511                  (match_operand:DI 2 "general_operand" "ao,>,d,<")))]
2512   ""
2513   "*
2514 {
2515   if (which_alternative == 3)
2516     return \"sub%.l %2,%0\;subx%.l %2,%0\";
2517   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
2518   if (which_alternative == 1)
2519     {
2520       CC_STATUS_INIT;
2521       return \"neg%.l %0\;add%.l %2,%0\;sub%.l %2,%1\;negx%.l %0\";
2522     }
2523   if (GET_CODE (operands[2]) == REG)
2524     operands[3] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
2525   else
2526     operands[3] = adj_offsettable_operand (operands[2], 4);
2527   if (which_alternative == 2)
2528     return \"sub%.l %3,%1\;subx%.l %2,%0\";
2529   CC_STATUS_INIT;
2530   /* neg + negx simulates (non-existent) subx #0 */
2531   /* TODO : this should work also for CONST operands[2] */
2532   return \"neg%.l %0\;sub%.l %3,%1\;negx%.l %0\;sub%.l %2,%0\";
2533 } ")
2534
2535 (define_insn "subsi3"
2536   [(set (match_operand:SI 0 "general_operand" "=m,r")
2537         (minus:SI (match_operand:SI 1 "general_operand" "0,0")
2538                   (match_operand:SI 2 "general_operand" "ds,mrs")))]
2539   ""
2540   "sub%.l %2,%0")
2541
2542 (define_insn ""
2543   [(set (match_operand:SI 0 "general_operand" "=a")
2544         (minus:SI (match_operand:SI 1 "general_operand" "0")
2545                   (sign_extend:SI
2546                    (match_operand:HI 2 "nonimmediate_operand" "rm"))))]
2547   ""
2548   "sub%.w %2,%0")
2549
2550 (define_insn "subhi3"
2551   [(set (match_operand:HI 0 "general_operand" "=m,r")
2552         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2553                   (match_operand:HI 2 "general_operand" "dn,rmn")))]
2554   ""
2555   "sub%.w %2,%0")
2556
2557 (define_insn ""
2558   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2559         (minus:HI (match_dup 0)
2560                   (match_operand:HI 1 "general_operand" "dn,rmn")))]
2561   ""
2562   "sub%.w %1,%0")
2563
2564 (define_insn "subqi3"
2565   [(set (match_operand:QI 0 "general_operand" "=m,d")
2566         (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2567                   (match_operand:QI 2 "general_operand" "dn,dmn")))]
2568   ""
2569   "sub%.b %2,%0")
2570
2571 (define_insn ""
2572   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2573         (minus:QI (match_dup 0)
2574                   (match_operand:QI 1 "general_operand" "dn,dmn")))]
2575   ""
2576   "sub%.b %1,%0")
2577
2578 (define_expand "subdf3"
2579   [(set (match_operand:DF 0 "general_operand" "")
2580         (minus:DF (match_operand:DF 1 "general_operand" "")
2581                   (match_operand:DF 2 "general_operand" "")))]
2582   "TARGET_68881 || TARGET_FPA"
2583   "")
2584
2585 (define_insn ""
2586   [(set (match_operand:DF 0 "general_operand" "=x,y,y")
2587         (minus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF")
2588                   (match_operand:DF 2 "general_operand" "xH,dmF,0")))]
2589   "TARGET_FPA"
2590   "*
2591 {
2592   if (rtx_equal_p (operands[0], operands[2]))
2593     return \"fprsub%.d %y1,%0\";
2594   if (rtx_equal_p (operands[0], operands[1]))
2595     return \"fpsub%.d %y2,%0\";
2596   if (which_alternative == 0)
2597     return \"fpsub3%.d %w2,%w1,%0\";
2598   return \"fpsub3%.d %x2,%x1,%0\";
2599 }")
2600
2601 (define_insn ""
2602   [(set (match_operand:DF 0 "general_operand" "=f")
2603         (minus:DF (match_operand:DF 1 "general_operand" "0")
2604                   (match_operand:DF 2 "general_operand" "fmG")))]
2605   "TARGET_68881"
2606   "*
2607 {
2608   if (REG_P (operands[2]))
2609     return \"f%&sub%.x %2,%0\";
2610   return \"f%&sub%.d %f2,%0\";
2611 }")
2612
2613 (define_expand "subsf3"
2614   [(set (match_operand:SF 0 "general_operand" "")
2615         (minus:SF (match_operand:SF 1 "general_operand" "")
2616                   (match_operand:SF 2 "general_operand" "")))]
2617   "TARGET_68881 || TARGET_FPA"
2618   "")
2619
2620 (define_insn ""
2621   [(set (match_operand:SF 0 "general_operand" "=x,y,y")
2622         (minus:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
2623                   (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
2624   "TARGET_FPA"
2625   "*
2626 {
2627   if (rtx_equal_p (operands[0], operands[2]))
2628     return \"fprsub%.s %w1,%0\";
2629   if (rtx_equal_p (operands[0], operands[1]))
2630     return \"fpsub%.s %w2,%0\";
2631   if (which_alternative == 0)
2632     return \"fpsub3%.s %w2,%w1,%0\";
2633   return \"fpsub3%.s %2,%1,%0\";
2634 }")
2635
2636 (define_insn ""
2637   [(set (match_operand:SF 0 "general_operand" "=f")
2638         (minus:SF (match_operand:SF 1 "general_operand" "0")
2639                   (match_operand:SF 2 "general_operand" "fdmF")))]
2640   "TARGET_68881"
2641   "*
2642 {
2643   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2644     return \"f%$sub%.x %2,%0\";
2645   return \"f%$sub%.s %f2,%0\";
2646 }")
2647 \f
2648 ;; multiply instructions
2649
2650 (define_insn "mulhi3"
2651   [(set (match_operand:HI 0 "general_operand" "=d")
2652         (mult:HI (match_operand:HI 1 "general_operand" "%0")
2653                  (match_operand:HI 2 "general_operand" "dmn")))]
2654   ""
2655   "*
2656 {
2657 #if defined(MOTOROLA) && !defined(CRDS)
2658   return \"muls%.w %2,%0\";
2659 #else
2660   return \"muls %2,%0\";
2661 #endif
2662 }")
2663
2664 (define_insn "mulhisi3"
2665   [(set (match_operand:SI 0 "general_operand" "=d")
2666         (mult:SI (sign_extend:SI
2667                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2668                  (sign_extend:SI
2669                   (match_operand:HI 2 "nonimmediate_operand" "dm"))))]
2670   ""
2671   "*
2672 {
2673 #if defined(MOTOROLA) && !defined(CRDS)
2674   return \"muls%.w %2,%0\";
2675 #else
2676   return \"muls %2,%0\";
2677 #endif
2678 }")
2679
2680 (define_insn ""
2681   [(set (match_operand:SI 0 "general_operand" "=d")
2682         (mult:SI (sign_extend:SI
2683                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2684                  (match_operand:SI 2 "const_int_operand" "n")))]
2685   "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
2686   "*
2687 {
2688 #if defined(MOTOROLA) && !defined(CRDS)
2689   return \"muls%.w %2,%0\";
2690 #else
2691   return \"muls %2,%0\";
2692 #endif
2693 }")
2694
2695 (define_insn "mulsi3"
2696   [(set (match_operand:SI 0 "general_operand" "=d")
2697         (mult:SI (match_operand:SI 1 "general_operand" "%0")
2698                  (match_operand:SI 2 "general_operand" "dmsK")))]
2699   "TARGET_68020"
2700   "muls%.l %2,%0")
2701
2702 (define_insn "umulhisi3"
2703   [(set (match_operand:SI 0 "general_operand" "=d")
2704         (mult:SI (zero_extend:SI
2705                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2706                  (zero_extend:SI
2707                   (match_operand:HI 2 "nonimmediate_operand" "dm"))))]
2708   ""
2709   "*
2710 {
2711 #if defined(MOTOROLA) && !defined(CRDS)
2712   return \"mulu%.w %2,%0\";
2713 #else
2714   return \"mulu %2,%0\";
2715 #endif
2716 }")
2717
2718 (define_insn ""
2719   [(set (match_operand:SI 0 "general_operand" "=d")
2720         (mult:SI (zero_extend:SI
2721                   (match_operand:HI 1 "nonimmediate_operand" "%0"))
2722                  (match_operand:SI 2 "const_int_operand" "n")))]
2723   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
2724   "*
2725 {
2726 #if defined(MOTOROLA) && !defined(CRDS)
2727   return \"mulu%.w %2,%0\";
2728 #else
2729   return \"mulu %2,%0\";
2730 #endif
2731 }")
2732
2733 ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
2734 ;; proper matching constraint.  This is because the matching is between
2735 ;; the high-numbered word of the DImode operand[0] and operand[1].
2736 (define_expand "umulsidi3"
2737   [(parallel
2738     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1)
2739           (mult:SI (match_operand:SI 1 "register_operand" "")
2740                    (match_operand:SI 2 "nonimmediate_operand" "")))
2741      (set (subreg:SI (match_dup 0) 0)
2742           (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2743                                              (zero_extend:DI (match_dup 2)))
2744                                     (const_int 32))))])]
2745   "TARGET_68020"
2746   "")
2747
2748 (define_insn ""
2749   [(set (match_operand:SI 0 "register_operand" "=d")
2750         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2751                   (match_operand:SI 2 "nonimmediate_operand" "dm")))
2752    (set (match_operand:SI 3 "register_operand" "=d")
2753         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2754                                            (zero_extend:DI (match_dup 2)))
2755                                   (const_int 32))))]
2756   "TARGET_68020"
2757   "mulu%.l %2,%3:%0")
2758
2759 ; Match immediate case.  For 2.4 only match things < 2^31.
2760 ; It's tricky with larger values in these patterns since we need to match
2761 ; values between the two parallel multiplies, between a CONST_DOUBLE and
2762 ; a CONST_INT.
2763 (define_insn ""
2764   [(set (match_operand:SI 0 "register_operand" "=d")
2765         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2766                  (match_operand:SI 2 "const_int_operand" "n")))
2767    (set (match_operand:SI 3 "register_operand" "=d")
2768         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
2769                                            (match_dup 2))
2770                                   (const_int 32))))]
2771   "TARGET_68020
2772    && (unsigned) INTVAL (operands[2]) <= 0x7fffffff"
2773   "mulu%.l %2,%3:%0")
2774
2775 (define_expand "mulsidi3"
2776   [(parallel
2777     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1)
2778           (mult:SI (match_operand:SI 1 "register_operand" "")
2779                    (match_operand:SI 2 "nonimmediate_operand" "")))
2780      (set (subreg:SI (match_dup 0) 0)
2781           (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2782                                              (sign_extend:DI (match_dup 2)))
2783                                     (const_int 32))))])]
2784   "TARGET_68020"
2785   "")
2786
2787 (define_insn ""
2788   [(set (match_operand:SI 0 "register_operand" "=d")
2789         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2790                  (match_operand:SI 2 "nonimmediate_operand" "dm")))
2791    (set (match_operand:SI 3 "register_operand" "=d")
2792         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2793                                            (sign_extend:DI (match_dup 2)))
2794                                   (const_int 32))))]
2795   "TARGET_68020"
2796   "muls%.l %2,%3:%0")
2797
2798 (define_insn ""
2799   [(set (match_operand:SI 0 "register_operand" "=d")
2800         (mult:SI (match_operand:SI 1 "register_operand" "%0")
2801                  (match_operand:SI 2 "const_int_operand" "n")))
2802    (set (match_operand:SI 3 "register_operand" "=d")
2803         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
2804                                            (match_dup 2))
2805                                   (const_int 32))))]
2806   "TARGET_68020
2807    /* This test is a noop on 32 bit machines,
2808       but important for a cross-compiler hosted on 64-bit machines.  */
2809    && INTVAL (operands[2]) <= 0x7fffffff
2810    && INTVAL (operands[2]) >= -0x80000000"
2811   "muls%.l %2,%3:%0")
2812
2813 (define_expand "umulsi3_highpart"
2814   [(parallel
2815     [(set (match_operand:SI 0 "register_operand" "")
2816           (truncate:SI
2817            (lshiftrt:DI
2818             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2819                      (zero_extend:DI (match_operand:SI 2 "general_operand" "")))
2820             (const_int 32))))
2821      (clobber (match_dup 3))])]
2822   "TARGET_68020"
2823   "
2824 {
2825   operands[3] = gen_reg_rtx (SImode);
2826   if (CONSTANT_P (operands[2]))
2827     {
2828       /* We have to rearrange the operand order for the matching constraints.  */
2829       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[3],
2830                                              operands[1], operands[2]));
2831       DONE;
2832     }
2833 }")
2834
2835 (define_insn ""
2836   [(set (match_operand:SI 0 "register_operand" "=d")
2837         (truncate:SI
2838          (lshiftrt:DI
2839           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "%1"))
2840                    (zero_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
2841           (const_int 32))))
2842    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2843   "TARGET_68020"
2844   "mulu%.l %3,%0:%1")
2845
2846 (define_insn "const_umulsi3_highpart"
2847   [(set (match_operand:SI 0 "register_operand" "=d")
2848         (truncate:SI
2849          (lshiftrt:DI
2850           (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "1"))
2851                    (match_operand:DI 3 "immediate_operand" "i"))
2852           (const_int 32))))
2853    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2854   "TARGET_68020"
2855   "mulu%.l %3,%0:%1")
2856
2857 (define_expand "smulsi3_highpart"
2858   [(parallel
2859     [(set (match_operand:SI 0 "register_operand" "")
2860           (truncate:SI
2861            (lshiftrt:DI
2862             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2863                      (sign_extend:DI (match_operand:SI 2 "general_operand" "")))
2864             (const_int 32))))
2865      (clobber (match_dup 3))])]
2866   "TARGET_68020"
2867   "
2868 {
2869   operands[3] = gen_reg_rtx (SImode);
2870   if (CONSTANT_P (operands[2]))
2871     {
2872       /* We have to rearrange the operand order for the matching constraints.  */
2873       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[3],
2874                                              operands[1], operands[2]));
2875       DONE;
2876     }
2877 }")
2878
2879 (define_insn ""
2880   [(set (match_operand:SI 0 "register_operand" "=d")
2881         (truncate:SI
2882          (lshiftrt:DI
2883           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "%1"))
2884                    (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
2885           (const_int 32))))
2886    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2887   "TARGET_68020"
2888   "muls%.l %3,%0:%1")
2889
2890 (define_insn "const_smulsi3_highpart"
2891   [(set (match_operand:SI 0 "register_operand" "=d")
2892         (truncate:SI
2893          (lshiftrt:DI
2894           (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1"))
2895                    (match_operand:DI 3 "immediate_operand" "i"))
2896           (const_int 32))))
2897    (clobber (match_operand:SI 1 "register_operand" "=d"))]
2898   "TARGET_68020"
2899   "muls%.l %3,%0:%1")
2900
2901 (define_expand "muldf3"
2902   [(set (match_operand:DF 0 "general_operand" "")
2903         (mult:DF (match_operand:DF 1 "general_operand" "")
2904                  (match_operand:DF 2 "general_operand" "")))]
2905   "TARGET_68881 || TARGET_FPA"
2906   "")
2907
2908 (define_insn ""
2909   [(set (match_operand:DF 0 "general_operand" "=x,y")
2910         (mult:DF (match_operand:DF 1 "general_operand" "%xH,y")
2911                  (match_operand:DF 2 "general_operand" "xH,rmF")))]
2912   "TARGET_FPA"
2913   "*
2914 {
2915   if (rtx_equal_p (operands[1], operands[2]))
2916     return \"fpsqr%.d %y1,%0\";
2917   if (rtx_equal_p (operands[0], operands[1]))
2918     return \"fpmul%.d %y2,%0\";
2919   if (rtx_equal_p (operands[0], operands[2]))
2920     return \"fpmul%.d %y1,%0\";
2921   if (which_alternative == 0)
2922     return \"fpmul3%.d %w2,%w1,%0\";
2923   return \"fpmul3%.d %x2,%x1,%0\";
2924 }")
2925
2926 (define_insn ""
2927   [(set (match_operand:DF 0 "general_operand" "=f")
2928         (mult:DF (match_operand:DF 1 "general_operand" "%0")
2929                  (match_operand:DF 2 "general_operand" "fmG")))]
2930   "TARGET_68881"
2931   "*
2932 {
2933   if (GET_CODE (operands[2]) == CONST_DOUBLE
2934       && floating_exact_log2 (operands[2]) && !TARGET_68040)
2935     {
2936       int i = floating_exact_log2 (operands[2]);
2937       operands[2] = gen_rtx (CONST_INT, VOIDmode, i);
2938       return \"fscale%.l %2,%0\";
2939     }
2940   if (REG_P (operands[2]))
2941     return \"f%&mul%.x %2,%0\";
2942   return \"f%&mul%.d %f2,%0\";
2943 }")
2944
2945 (define_expand "mulsf3"
2946   [(set (match_operand:SF 0 "general_operand" "")
2947         (mult:SF (match_operand:SF 1 "general_operand" "")
2948                  (match_operand:SF 2 "general_operand" "")))]
2949   "TARGET_68881 || TARGET_FPA"
2950   "")
2951
2952 (define_insn ""
2953   [(set (match_operand:SF 0 "general_operand" "=x,y")
2954         (mult:SF (match_operand:SF 1 "general_operand" "%xH,y")
2955                  (match_operand:SF 2 "general_operand" "xH,rmF")))]
2956   "TARGET_FPA"
2957   "*
2958 {
2959   if (rtx_equal_p (operands[1], operands[2]))
2960     return \"fpsqr%.s %w1,%0\";
2961   if (rtx_equal_p (operands[0], operands[1]))
2962     return \"fpmul%.s %w2,%0\";
2963   if (rtx_equal_p (operands[0], operands[2]))
2964     return \"fpmul%.s %w1,%0\";
2965   if (which_alternative == 0)
2966     return \"fpmul3%.s %w2,%w1,%0\";
2967   return \"fpmul3%.s %2,%1,%0\";
2968 }")
2969
2970 (define_insn ""
2971   [(set (match_operand:SF 0 "general_operand" "=f")
2972         (mult:SF (match_operand:SF 1 "general_operand" "%0")
2973                  (match_operand:SF 2 "general_operand" "fdmF")))]
2974   "TARGET_68881"
2975   "*
2976 {
2977 #ifdef FSGLMUL_USE_S
2978   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2979     return (TARGET_68040_ONLY
2980             ? \"fsmul%.s %2,%0\"
2981             : \"fsglmul%.s %2,%0\");
2982 #else
2983   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2984     return (TARGET_68040_ONLY
2985             ? \"fsmul%.x %2,%0\"
2986             : \"fsglmul%.x %2,%0\");
2987 #endif
2988   return (TARGET_68040_ONLY
2989           ? \"fsmul%.s %f2,%0\"
2990           : \"fsglmul%.s %f2,%0\");
2991 }")
2992 \f
2993 ;; divide instructions
2994
2995 (define_insn "divhi3"
2996   [(set (match_operand:HI 0 "general_operand" "=d")
2997         (div:HI (match_operand:HI 1 "general_operand" "0")
2998                 (match_operand:HI 2 "general_operand" "dmn")))]
2999   ""
3000   "*
3001 {
3002 #ifdef MOTOROLA
3003   return \"ext%.l %0\;divs%.w %2,%0\";
3004 #else
3005   return \"extl %0\;divs %2,%0\";
3006 #endif
3007 }")
3008
3009 ;; These patterns don't work because the divs instruction is undefined if
3010 ;; the quotient is more than 16 bits.  This valid C would be miscompiled:
3011 ;; int n; short d; unsigned short q; ... q = (unsigned int) (n / d);
3012 ;; Imagine what happens when n = 100000 and d = 1.
3013 ;;(define_insn "divhisi3"
3014 ;;  [(set (match_operand:HI 0 "general_operand" "=d")
3015 ;;      (truncate:HI
3016 ;;       (div:SI
3017 ;;        (match_operand:SI 1 "general_operand" "0")
3018 ;;        (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
3019 ;;  ""
3020 ;;  "*
3021 ;;{
3022 ;;#ifdef MOTOROLA
3023 ;;  return \"divs%.w %2,%0\";
3024 ;;#else
3025 ;;  return \"divs %2,%0\";
3026 ;;#endif
3027 ;;}")
3028
3029 ;;(define_insn ""
3030 ;;  [(set (match_operand:HI 0 "general_operand" "=d")
3031 ;;      (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0")
3032 ;;                           (match_operand:SI 2 "const_int_operand" "n"))))]
3033 ;;  ""
3034 ;;  "*
3035 ;;{
3036 ;;#ifdef MOTOROLA
3037 ;;  return \"divs%.w %2,%0\";
3038 ;;#else
3039 ;;  return \"divs %2,%0\";
3040 ;;#endif
3041 ;;}")
3042
3043 (define_insn "udivhi3"
3044   [(set (match_operand:HI 0 "general_operand" "=d")
3045         (udiv:HI (match_operand:HI 1 "general_operand" "0")
3046                  (match_operand:HI 2 "general_operand" "dmn")))]
3047   ""
3048   "*
3049 {
3050 #ifdef MOTOROLA
3051   return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\";
3052 #else
3053   return \"andl %#0xFFFF,%0\;divu %2,%0\";
3054 #endif
3055 }")
3056
3057 ;; See comment before divhisi3 why these are commented out.
3058 ;;(define_insn "udivhisi3"
3059 ;;  [(set (match_operand:HI 0 "general_operand" "=d")
3060 ;;      (truncate:HI
3061 ;;       (udiv:SI
3062 ;;        (match_operand:SI 1 "general_operand" "0")
3063 ;;        (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
3064 ;;  ""
3065 ;;  "*
3066 ;;{
3067 ;;#ifdef MOTOROLA
3068 ;;  return \"divu%.w %2,%0\";
3069 ;;#else
3070 ;;  return \"divu %2,%0\";
3071 ;;#endif
3072 ;;}")
3073
3074 ;;(define_insn ""
3075 ;;  [(set (match_operand:HI 0 "general_operand" "=d")
3076 ;;      (truncate:HI (udiv:SI (match_operand:SI 1 "general_operand" "0")
3077 ;;                            (match_operand:SI 2 "const_int_operand" "n"))))]
3078 ;;  ""
3079 ;;  "*
3080 ;;{
3081 ;;#ifdef MOTOROLA
3082 ;;  return \"divu%.w %2,%0\";
3083 ;;#else
3084 ;;  return \"divu %2,%0\";
3085 ;;#endif
3086 ;;}")
3087
3088 (define_expand "divdf3"
3089   [(set (match_operand:DF 0 "general_operand" "")
3090         (div:DF (match_operand:DF 1 "general_operand" "")
3091                 (match_operand:DF 2 "general_operand" "")))]
3092   "TARGET_68881 || TARGET_FPA"
3093   "")
3094
3095 (define_insn ""
3096   [(set (match_operand:DF 0 "general_operand" "=x,y,y")
3097         (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF")
3098                 (match_operand:DF 2 "general_operand" "xH,rmF,0")))]
3099   "TARGET_FPA"
3100   "*
3101 {
3102   if (rtx_equal_p (operands[0], operands[2]))
3103     return \"fprdiv%.d %y1,%0\";
3104   if (rtx_equal_p (operands[0], operands[1]))
3105     return \"fpdiv%.d %y2,%0\";
3106   if (which_alternative == 0)
3107     return \"fpdiv3%.d %w2,%w1,%0\";
3108   return \"fpdiv3%.d %x2,%x1,%x0\";
3109 }")
3110
3111 (define_insn ""
3112   [(set (match_operand:DF 0 "general_operand" "=f")
3113         (div:DF (match_operand:DF 1 "general_operand" "0")
3114                 (match_operand:DF 2 "general_operand" "fmG")))]
3115   "TARGET_68881"
3116   "*
3117 {
3118   if (REG_P (operands[2]))
3119     return \"f%&div%.x %2,%0\";
3120   return \"f%&div%.d %f2,%0\";
3121 }")
3122
3123 (define_expand "divsf3"
3124   [(set (match_operand:SF 0 "general_operand" "")
3125         (div:SF (match_operand:SF 1 "general_operand" "")
3126                 (match_operand:SF 2 "general_operand" "")))]
3127   "TARGET_68881 || TARGET_FPA"
3128   "")
3129
3130 (define_insn ""
3131   [(set (match_operand:SF 0 "general_operand" "=x,y,y")
3132         (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
3133                 (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
3134   "TARGET_FPA"
3135   "*
3136 {
3137   if (rtx_equal_p (operands[0], operands[1]))
3138     return \"fpdiv%.s %w2,%0\";
3139   if (rtx_equal_p (operands[0], operands[2]))
3140     return \"fprdiv%.s %w1,%0\";
3141   if (which_alternative == 0)
3142     return \"fpdiv3%.s %w2,%w1,%0\";
3143   return \"fpdiv3%.s %2,%1,%0\";
3144 }")
3145
3146 (define_insn ""
3147   [(set (match_operand:SF 0 "general_operand" "=f")
3148         (div:SF (match_operand:SF 1 "general_operand" "0")
3149                 (match_operand:SF 2 "general_operand" "fdmF")))]
3150   "TARGET_68881"
3151   "*
3152 {
3153 #ifdef FSGLDIV_USE_S
3154   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3155     return (TARGET_68040_ONLY
3156             ? \"fsdiv%.s %2,%0\"
3157             : \"fsgldiv%.s %2,%0\");
3158 #else
3159   if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
3160     return (TARGET_68040_ONLY
3161             ? \"fsdiv%.x %2,%0\"
3162             : \"fsgldiv%.x %2,%0\");
3163 #endif
3164   return (TARGET_68040_ONLY
3165           ? \"fsdiv%.s %f2,%0\"
3166           : \"fsgldiv%.s %f2,%0\");
3167 }")
3168 \f
3169 ;; Remainder instructions.
3170
3171 (define_insn "modhi3"
3172   [(set (match_operand:HI 0 "general_operand" "=d")
3173         (mod:HI (match_operand:HI 1 "general_operand" "0")
3174                 (match_operand:HI 2 "general_operand" "dmn")))]
3175   ""
3176   "*
3177 {
3178   /* The swap insn produces cc's that don't correspond to the result.  */
3179   CC_STATUS_INIT;
3180 #ifdef MOTOROLA
3181   return \"ext%.l %0\;divs%.w %2,%0\;swap %0\";
3182 #else
3183   return \"extl %0\;divs %2,%0\;swap %0\";
3184 #endif
3185 }")
3186
3187 ;; See comment before divhisi3 why these are commented out.
3188 ;;(define_insn "modhisi3"
3189 ;;  [(set (match_operand:HI 0 "general_operand" "=d")
3190 ;;      (truncate:HI
3191 ;;       (mod:SI
3192 ;;        (match_operand:SI 1 "general_operand" "0")
3193 ;;        (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
3194 ;;  ""
3195 ;;  "*
3196 ;;{
3197 ;;  /* The swap insn produces cc's that don't correspond to the result.  */
3198 ;;  CC_STATUS_INIT;
3199 ;;#ifdef MOTOROLA
3200 ;;  return \"divs%.w %2,%0\;swap %0\";
3201 ;;#else
3202 ;;  return \"divs %2,%0\;swap %0\";
3203 ;;#endif
3204 ;;}")
3205
3206 ;;(define_insn ""
3207 ;;  [(set (match_operand:HI 0 "general_operand" "=d")
3208 ;;      (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0")
3209 ;;                           (match_operand:SI 2 "const_int_operand" "n"))))]
3210 ;;  ""
3211 ;;  "*
3212 ;;{
3213 ;;  /* The swap insn produces cc's that don't correspond to the result.  */
3214 ;;  CC_STATUS_INIT;
3215 ;;#ifdef MOTOROLA
3216 ;;  return \"divs%.w %2,%0\;swap %0\";
3217 ;;#else
3218 ;;  return \"divs %2,%0\;swap %0\";
3219 ;;#endif
3220 ;;}")
3221
3222 (define_insn "umodhi3"
3223   [(set (match_operand:HI 0 "general_operand" "=d")
3224         (umod:HI (match_operand:HI 1 "general_operand" "0")
3225                  (match_operand:HI 2 "general_operand" "dmn")))]
3226   ""
3227   "*
3228 {
3229   /* The swap insn produces cc's that don't correspond to the result.  */
3230   CC_STATUS_INIT;
3231 #ifdef MOTOROLA
3232   return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\";
3233 #else
3234   return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\";
3235 #endif
3236 }")
3237
3238 ;; See comment before divhisi3 why these are commented out.
3239 ;;(define_insn "umodhisi3"
3240 ;;  [(set (match_operand:HI 0 "general_operand" "=d")
3241 ;;      (truncate:HI
3242 ;;       (umod:SI
3243 ;;        (match_operand:SI 1 "general_operand" "0")
3244 ;;        (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
3245 ;;  ""
3246 ;;  "*
3247 ;;{
3248 ;;  /* The swap insn produces cc's that don't correspond to the result.  */
3249 ;;  CC_STATUS_INIT;
3250 ;;#ifdef MOTOROLA
3251 ;;  return \"divu%.w %2,%0\;swap %0\";
3252 ;;#else
3253 ;;  return \"divu %2,%0\;swap %0\";
3254 ;;#endif
3255 ;;}")
3256
3257 ;;(define_insn ""
3258 ;;  [(set (match_operand:HI 0 "general_operand" "=d")
3259 ;;      (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0")
3260 ;;                            (match_operand:SI 2 "const_int_operand" "n"))))]
3261 ;;  ""
3262 ;;  "*
3263 ;;{
3264 ;;  /* The swap insn produces cc's that don't correspond to the result.  */
3265 ;;  CC_STATUS_INIT;
3266 ;;#ifdef MOTOROLA
3267 ;;  return \"divu%.w %2,%0\;swap %0\";
3268 ;;#else
3269 ;;  return \"divu %2,%0\;swap %0\";
3270 ;;#endif
3271 ;;}")
3272
3273 (define_insn "divmodsi4"
3274   [(set (match_operand:SI 0 "general_operand" "=d")
3275         (div:SI (match_operand:SI 1 "general_operand" "0")
3276                 (match_operand:SI 2 "general_operand" "dmsK")))
3277    (set (match_operand:SI 3 "general_operand" "=d")
3278         (mod:SI (match_dup 1) (match_dup 2)))]
3279   "TARGET_68020"
3280   "*
3281 {
3282   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3283     return \"divs%.l %2,%0\";
3284   else
3285     return \"divsl%.l %2,%3:%0\";
3286 }")
3287
3288 (define_insn "udivmodsi4"
3289   [(set (match_operand:SI 0 "general_operand" "=d")
3290         (udiv:SI (match_operand:SI 1 "general_operand" "0")
3291                  (match_operand:SI 2 "general_operand" "dmsK")))
3292    (set (match_operand:SI 3 "general_operand" "=d")
3293         (umod:SI (match_dup 1) (match_dup 2)))]
3294   "TARGET_68020"
3295   "*
3296 {
3297   if (find_reg_note (insn, REG_UNUSED, operands[3]))
3298     return \"divu%.l %2,%0\";
3299   else
3300     return \"divul%.l %2,%3:%0\";
3301 }")
3302 \f
3303 ;; logical-and instructions
3304
3305 ;; Prevent AND from being made with sp.  This doesn't exist in the machine
3306 ;; and reload will cause inefficient code.  Since sp is a FIXED_REG, we
3307 ;; can't allocate pseudos into it.
3308 (define_insn "andsi3"
3309   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3310         (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3311                 (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
3312   ""
3313   "*
3314 {
3315   int logval;
3316   if (GET_CODE (operands[2]) == CONST_INT
3317       && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
3318       && (DATA_REG_P (operands[0])
3319           || offsettable_memref_p (operands[0])))
3320     { 
3321       if (GET_CODE (operands[0]) != REG)
3322         operands[0] = adj_offsettable_operand (operands[0], 2);
3323       operands[2] = gen_rtx (CONST_INT, VOIDmode,
3324                              INTVAL (operands[2]) & 0xffff);
3325       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3326       CC_STATUS_INIT;
3327       if (operands[2] == const0_rtx)
3328         return \"clr%.w %0\";
3329       return \"and%.w %2,%0\";
3330     }
3331   if (GET_CODE (operands[2]) == CONST_INT
3332       && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3333       && (DATA_REG_P (operands[0])
3334           || offsettable_memref_p (operands[0])))
3335     { 
3336       if (DATA_REG_P (operands[0]))
3337         {
3338           operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
3339         }
3340       else
3341         {
3342           operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3343           operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
3344         }
3345       /* This does not set condition codes in a standard way.  */
3346       CC_STATUS_INIT;
3347       return \"bclr %1,%0\";
3348     }
3349   return \"and%.l %2,%0\";
3350 }")
3351
3352 (define_insn "andhi3"
3353   [(set (match_operand:HI 0 "general_operand" "=m,d")
3354         (and:HI (match_operand:HI 1 "general_operand" "%0,0")
3355                 (match_operand:HI 2 "general_operand" "dn,dmn")))]
3356   ""
3357   "and%.w %2,%0")
3358
3359 (define_insn ""
3360   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3361         (and:HI (match_dup 0)
3362                 (match_operand:HI 1 "general_operand" "dn,dmn")))]
3363   ""
3364   "and%.w %1,%0")
3365
3366 (define_insn ""
3367   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3368         (and:HI (match_operand:HI 1 "general_operand" "dn,dmn")
3369                 (match_dup 0)))]
3370   ""
3371   "and%.w %1,%0")
3372
3373 (define_insn "andqi3"
3374   [(set (match_operand:QI 0 "general_operand" "=m,d")
3375         (and:QI (match_operand:QI 1 "general_operand" "%0,0")
3376                 (match_operand:QI 2 "general_operand" "dn,dmn")))]
3377   ""
3378   "and%.b %2,%0")
3379
3380 (define_insn ""
3381   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3382         (and:QI (match_dup 0)
3383                 (match_operand:QI 1 "general_operand" "dn,dmn")))]
3384   ""
3385   "and%.b %1,%0")
3386
3387 (define_insn ""
3388   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3389         (and:QI (match_operand:QI 1 "general_operand" "dn,dmn")
3390                 (match_dup 0)))]
3391   ""
3392   "and%.b %1,%0")
3393 \f
3394 ;; inclusive-or instructions
3395
3396 (define_insn "iorsi3"
3397   [(set (match_operand:SI 0 "general_operand" "=m,d")
3398         (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3399                 (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
3400   ""
3401   "*
3402 {
3403   register int logval;
3404   if (GET_CODE (operands[2]) == CONST_INT
3405       && INTVAL (operands[2]) >> 16 == 0
3406       && (DATA_REG_P (operands[0])
3407           || offsettable_memref_p (operands[0])))
3408     { 
3409       if (GET_CODE (operands[0]) != REG)
3410         operands[0] = adj_offsettable_operand (operands[0], 2);
3411       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3412       CC_STATUS_INIT;
3413       return \"or%.w %2,%0\";
3414     }
3415   if (GET_CODE (operands[2]) == CONST_INT
3416       && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3417       && (DATA_REG_P (operands[0])
3418           || offsettable_memref_p (operands[0])))
3419     { 
3420       if (DATA_REG_P (operands[0]))
3421         {
3422           operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
3423         }
3424       else
3425         {
3426           operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3427           operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
3428         }
3429       CC_STATUS_INIT;
3430       return \"bset %1,%0\";
3431     }
3432   return \"or%.l %2,%0\";
3433 }")
3434
3435 (define_insn "iorhi3"
3436   [(set (match_operand:HI 0 "general_operand" "=m,d")
3437         (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
3438                 (match_operand:HI 2 "general_operand" "dn,dmn")))]
3439   ""
3440   "or%.w %2,%0")
3441
3442 (define_insn ""
3443   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3444         (ior:HI (match_dup 0)
3445                 (match_operand:HI 1 "general_operand" "dn,dmn")))]
3446   ""
3447   "or%.w %1,%0")
3448
3449 (define_insn ""
3450   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3451         (ior:HI (match_operand:HI 1 "general_operand" "dn,dmn")
3452                 (match_dup 0)))]
3453   ""
3454   "or%.w %1,%0")
3455
3456 (define_insn "iorqi3"
3457   [(set (match_operand:QI 0 "general_operand" "=m,d")
3458         (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
3459                 (match_operand:QI 2 "general_operand" "dn,dmn")))]
3460   ""
3461   "or%.b %2,%0")
3462
3463 (define_insn ""
3464   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3465         (ior:QI (match_dup 0)
3466                 (match_operand:QI 1 "general_operand" "dn,dmn")))]
3467   ""
3468   "or%.b %1,%0")
3469
3470 (define_insn ""
3471   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3472         (ior:QI (match_operand:QI 1 "general_operand" "dn,dmn")
3473                 (match_dup 0)))]
3474   ""
3475   "or%.b %1,%0")
3476
3477 (define_insn ""
3478   [(set (match_operand:SI 0 "general_operand" "=o,d")
3479     (ior:SI (zero_extend:SI (match_operand 1 "general_operand" "dn,dmn"))
3480         (match_operand:SI 2 "general_operand" "0,0")))]
3481   ""
3482   "*
3483 {
3484   int byte_mode;
3485
3486   CC_STATUS_INIT;
3487   byte_mode = (GET_MODE(operands[1]) == QImode);
3488   if (GET_CODE (operands[0]) == MEM)
3489     operands[0] = adj_offsettable_operand (operands[0], byte_mode ? 3 : 2);
3490   if (byte_mode)
3491         return \"or%.b %1,%0\";
3492   else
3493         return \"or%.w %1,%0\";
3494 }")
3495 \f
3496 ;; xor instructions
3497
3498 (define_insn "xorsi3"
3499   [(set (match_operand:SI 0 "general_operand" "=do,m")
3500         (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
3501                 (match_operand:SI 2 "general_operand" "di,dKs")))]
3502   ""
3503   "*
3504 {
3505   if (GET_CODE (operands[2]) == CONST_INT
3506       && INTVAL (operands[2]) >> 16 == 0
3507       && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
3508     { 
3509       if (! DATA_REG_P (operands[0]))
3510         operands[0] = adj_offsettable_operand (operands[0], 2);
3511       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3512       CC_STATUS_INIT;
3513       return \"eor%.w %2,%0\";
3514     }
3515   return \"eor%.l %2,%0\";
3516 }")
3517
3518 (define_insn "xorhi3"
3519   [(set (match_operand:HI 0 "general_operand" "=dm")
3520         (xor:HI (match_operand:HI 1 "general_operand" "%0")
3521                 (match_operand:HI 2 "general_operand" "dn")))]
3522   ""
3523   "eor%.w %2,%0")
3524
3525 (define_insn ""
3526   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
3527         (xor:HI (match_dup 0)
3528                 (match_operand:HI 1 "general_operand" "dn")))]
3529   ""
3530   "eor%.w %1,%0")
3531
3532
3533 (define_insn ""
3534   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
3535         (xor:HI (match_operand:HI 1 "general_operand" "dn")
3536                 (match_dup 0)))]
3537   ""
3538   "eor%.w %1,%0")
3539
3540 (define_insn "xorqi3"
3541   [(set (match_operand:QI 0 "general_operand" "=dm")
3542         (xor:QI (match_operand:QI 1 "general_operand" "%0")
3543                 (match_operand:QI 2 "general_operand" "dn")))]
3544   ""
3545   "eor%.b %2,%0")
3546
3547 (define_insn ""
3548   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
3549         (xor:QI (match_dup 0)
3550                 (match_operand:QI 1 "general_operand" "dn")))]
3551   ""
3552   "eor%.b %1,%0")
3553
3554 (define_insn ""
3555   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
3556         (xor:QI (match_operand:QI 1 "general_operand" "dn")
3557                 (match_dup 0)))]
3558   ""
3559   "eor%.b %1,%0")
3560 \f
3561 ;; negation instructions
3562
3563 (define_insn "negdi2"
3564   [(set (match_operand:DI 0 "general_operand" "=d*ao,<")
3565         (neg:DI (match_operand:DI 1 "general_operand" "0,0")))]
3566   ""
3567   "*
3568 {
3569   if (which_alternative == 1)
3570     return \"neg%.l %0\;negx%.l %0\";
3571   if (GET_CODE (operands[0]) == REG)
3572     operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
3573   else
3574     operands[1] = adj_offsettable_operand (operands[0], 4);
3575   if (ADDRESS_REG_P (operands[0]))
3576     return \"exg %/d0,%1\;neg%.l %/d0\;exg %/d0,%1\;exg %/d0,%0\;negx%.l %/d0\;exg %/d0,%0\";
3577   else
3578     return \"neg%.l %1\;negx%.l %0\";
3579 } ")
3580
3581 (define_insn "negsi2"
3582   [(set (match_operand:SI 0 "general_operand" "=dm")
3583         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
3584   ""
3585   "neg%.l %0")
3586
3587 (define_insn "neghi2"
3588   [(set (match_operand:HI 0 "general_operand" "=dm")
3589         (neg:HI (match_operand:HI 1 "general_operand" "0")))]
3590   ""
3591   "neg%.w %0")
3592
3593 (define_insn ""
3594   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
3595         (neg:HI (match_dup 0)))]
3596   ""
3597   "neg%.w %0")
3598
3599 (define_insn "negqi2"
3600   [(set (match_operand:QI 0 "general_operand" "=dm")
3601         (neg:QI (match_operand:QI 1 "general_operand" "0")))]
3602   ""
3603   "neg%.b %0")
3604
3605 (define_insn ""
3606   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
3607         (neg:QI (match_dup 0)))]
3608   ""
3609   "neg%.b %0")
3610
3611 ;; If using software floating point, just flip the sign bit.
3612
3613 (define_expand "negsf2"
3614   [(set (match_operand:SF 0 "general_operand" "")
3615         (neg:SF (match_operand:SF 1 "general_operand" "")))]
3616   ""
3617   "
3618 {
3619   if (!TARGET_FPA && !TARGET_68881)
3620     {
3621       rtx result;
3622       rtx target;
3623
3624       target = operand_subword_force (operands[0], 0, SFmode);
3625       result = expand_binop (SImode, xor_optab,
3626                              operand_subword_force (operands[1], 0, SFmode),
3627                              GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
3628       if (result == 0)
3629         abort ();
3630
3631       if (result != target)
3632         emit_move_insn (result, target);
3633
3634       /* Make a place for REG_EQUAL.  */
3635       emit_move_insn (operands[0], operands[0]);
3636       DONE;
3637     }
3638 }")
3639
3640 (define_insn ""
3641   [(set (match_operand:SF 0 "general_operand" "=x,y")
3642         (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
3643   "TARGET_FPA"
3644   "fpneg%.s %w1,%0")
3645
3646 (define_insn ""
3647   [(set (match_operand:SF 0 "general_operand" "=f,d")
3648         (neg:SF (match_operand:SF 1 "general_operand" "fdmF,0")))]
3649   "TARGET_68881"
3650   "*
3651 {
3652   if (DATA_REG_P (operands[0]))
3653     {
3654       operands[1] = gen_rtx (CONST_INT, VOIDmode, 31);
3655       return \"bchg %1,%0\";
3656     }
3657   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
3658     return \"f%$neg%.x %1,%0\";
3659   return \"f%$neg%.s %f1,%0\";
3660 }")
3661
3662 (define_expand "negdf2"
3663   [(set (match_operand:DF 0 "general_operand" "")
3664         (neg:DF (match_operand:DF 1 "general_operand" "")))]
3665   ""
3666   "
3667 {
3668   if (!TARGET_FPA && !TARGET_68881)
3669     {
3670       rtx result;
3671       rtx target;
3672       rtx insns;
3673
3674       start_sequence ();
3675       target = operand_subword (operands[0], 0, 1, DFmode);
3676       result = expand_binop (SImode, xor_optab,
3677                              operand_subword_force (operands[1], 0, DFmode),
3678                              GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
3679       if (result == 0)
3680         abort ();
3681
3682       if (result != target)
3683         emit_move_insn (result, target);
3684   
3685       emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
3686                       operand_subword_force (operands[1], 1, DFmode));
3687
3688       insns = get_insns ();
3689       end_sequence ();
3690
3691       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
3692       DONE;
3693     }
3694 }")
3695
3696 (define_insn ""
3697   [(set (match_operand:DF 0 "general_operand" "=x,y")
3698         (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
3699   "TARGET_FPA"
3700   "fpneg%.d %y1, %0")
3701
3702 (define_insn ""
3703   [(set (match_operand:DF 0 "general_operand" "=f,d")
3704         (neg:DF (match_operand:DF 1 "general_operand" "fmF,0")))]
3705   "TARGET_68881"
3706   "*
3707 {
3708   if (DATA_REG_P (operands[0]))
3709     {
3710       operands[1] = gen_rtx (CONST_INT, VOIDmode, 31);
3711       return \"bchg %1,%0\";
3712     }
3713   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
3714     return \"f%&neg%.x %1,%0\";
3715   return \"f%&neg%.d %f1,%0\";
3716 }")
3717 \f
3718 ;; Sqrt instruction for the 68881
3719
3720 (define_insn "sqrtsf2"
3721   [(set (match_operand:SF 0 "general_operand" "=f")
3722         (sqrt:SF (match_operand:SF 1 "general_operand" "fm")))]
3723   "TARGET_68881"
3724   "*
3725 {
3726   if (FP_REG_P (operands[1]))
3727     return \"fsqrt%.x %1,%0\";
3728   else
3729     return \"fsqrt%.s %1,%0\";
3730 }")
3731
3732 (define_insn "sqrtdf2"
3733   [(set (match_operand:DF 0 "general_operand" "=f")
3734         (sqrt:DF (match_operand:DF 1 "general_operand" "fm")))]
3735   "TARGET_68881"
3736   "*
3737 {
3738   if (FP_REG_P (operands[1]))
3739     return \"fsqrt%.x %1,%0\";
3740   else
3741     return \"fsqrt%.d %1,%0\";
3742 }")
3743
3744 ;; Absolute value instructions
3745 ;; If using software floating point, just zero the sign bit.
3746
3747 (define_expand "abssf2"
3748   [(set (match_operand:SF 0 "general_operand" "")
3749         (abs:SF (match_operand:SF 1 "general_operand" "")))]
3750   ""
3751   "
3752 {
3753   if (!TARGET_FPA && !TARGET_68881)
3754     {
3755       rtx result;
3756       rtx target;
3757
3758       target = operand_subword_force (operands[0], 0, SFmode);
3759       result = expand_binop (SImode, and_optab,
3760                              operand_subword_force (operands[1], 0, SFmode),
3761                              GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
3762       if (result == 0)
3763         abort ();
3764
3765       if (result != target)
3766         emit_move_insn (result, target);
3767
3768       /* Make a place for REG_EQUAL.  */
3769       emit_move_insn (operands[0], operands[0]);
3770       DONE;
3771     }
3772 }")
3773
3774 (define_insn ""
3775   [(set (match_operand:SF 0 "general_operand" "=x,y")
3776         (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
3777   "TARGET_FPA"
3778   "fpabs%.s %y1,%0")
3779
3780 (define_insn ""
3781   [(set (match_operand:SF 0 "general_operand" "=f")
3782         (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))]
3783   "TARGET_68881"
3784   "*
3785 {
3786   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
3787     return \"f%$abs%.x %1,%0\";
3788   return \"f%$abs%.s %f1,%0\";
3789 }")
3790
3791 (define_expand "absdf2"
3792   [(set (match_operand:DF 0 "general_operand" "")
3793         (abs:DF (match_operand:DF 1 "general_operand" "")))]
3794   ""
3795   "
3796 {
3797   if (!TARGET_FPA && !TARGET_68881)
3798     {
3799       rtx result;
3800       rtx target;
3801       rtx insns;
3802
3803       start_sequence ();
3804       target = operand_subword (operands[0], 0, 1, DFmode);
3805       result = expand_binop (SImode, and_optab,
3806                              operand_subword_force (operands[1], 0, DFmode),
3807                              GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
3808       if (result == 0)
3809         abort ();
3810
3811       if (result != target)
3812         emit_move_insn (result, target);
3813   
3814       emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
3815                       operand_subword_force (operands[1], 1, DFmode));
3816
3817       insns = get_insns ();
3818       end_sequence ();
3819
3820       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
3821       DONE;
3822     }
3823 }")
3824
3825 (define_insn ""
3826   [(set (match_operand:DF 0 "general_operand" "=x,y")
3827         (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
3828   "TARGET_FPA"
3829   "fpabs%.d %y1,%0")
3830
3831 (define_insn ""
3832   [(set (match_operand:DF 0 "general_operand" "=f")
3833         (abs:DF (match_operand:DF 1 "general_operand" "fmF")))]
3834   "TARGET_68881"
3835   "*
3836 {
3837   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
3838     return \"f%&abs%.x %1,%0\";
3839   return \"f%&abs%.d %f1,%0\";
3840 }")
3841 \f
3842 ;; one complement instructions
3843
3844 (define_insn "one_cmplsi2"
3845   [(set (match_operand:SI 0 "general_operand" "=dm")
3846         (not:SI (match_operand:SI 1 "general_operand" "0")))]
3847   ""
3848   "not%.l %0")
3849
3850 (define_insn "one_cmplhi2"
3851   [(set (match_operand:HI 0 "general_operand" "=dm")
3852         (not:HI (match_operand:HI 1 "general_operand" "0")))]
3853   ""
3854   "not%.w %0")
3855
3856 (define_insn ""
3857   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
3858         (not:HI (match_dup 0)))]
3859   ""
3860   "not%.w %0")
3861
3862 (define_insn "one_cmplqi2"
3863   [(set (match_operand:QI 0 "general_operand" "=dm")
3864         (not:QI (match_operand:QI 1 "general_operand" "0")))]
3865   ""
3866   "not%.b %0")
3867
3868 (define_insn ""
3869   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
3870         (not:QI (match_dup 0)))]
3871   ""
3872   "not%.b %0")
3873 \f
3874 ;; arithmetic shift instructions
3875 ;; We don't need the shift memory by 1 bit instruction
3876
3877 (define_insn "ashldi_sexthi"
3878   [(set (match_operand:DI 0 "general_operand" "=*da")
3879     (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
3880         (const_int 32)))]
3881   ""
3882   "*
3883 {
3884   CC_STATUS_INIT;
3885   operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
3886   if (DATA_REG_P (operands[0]))
3887     return \"move%.w %1,%0\;ext%.l %0\;clr%.l %2\";
3888   else
3889     return \"move%.w %1,%0\;sub%.l %2,%2\";
3890 } ")
3891
3892 (define_insn "ashldi_const32"
3893   [(set (match_operand:DI 0 "general_operand" "=ro,<,>")
3894         (ashift:DI (match_operand:DI 1 "general_operand" "ro,ro,ro")
3895                      (const_int 32)))]
3896   ""
3897   "*
3898 {
3899   CC_STATUS_INIT;
3900   if (GET_CODE (operands[1]) == REG)
3901     operands[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
3902   else
3903     operands[3] = adj_offsettable_operand (operands[1], 4);
3904   if (which_alternative == 1)
3905     return \"clr%.l %0\;move%.l %3,%0\";
3906   if (which_alternative == 2)
3907     return \"move%.l %3,%0\;clr%.l %0\";
3908   if (GET_CODE (operands[0]) == REG)
3909     operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
3910   else
3911     operands[2] = adj_offsettable_operand (operands[0], 4);
3912   if (ADDRESS_REG_P (operands[2]))
3913     return \"move%.l %3,%0\;sub%.l %2,%2\";
3914   else
3915     return \"move%.l %3,%0\;clr%.l %2\";
3916 } ")
3917
3918 (define_insn "ashldi_const"
3919   [(set (match_operand:DI 0 "general_operand" "=d")
3920         (ashift:DI (match_operand:DI 1 "general_operand" "0")
3921                      (match_operand 2 "const_int_operand" "n")))]
3922   "(INTVAL (operands[2]) == 1
3923    || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
3924   "*
3925 {
3926   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
3927   if (INTVAL (operands[2]) == 1)
3928     return \"add%.l %1,%1\;addx%.l %0,%0\";
3929   else if (INTVAL (operands[2]) == 2)
3930     return \"add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\";
3931   else/* if (INTVAL (operands[2]) == 3)*/
3932     return \"add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\";
3933 } ")
3934
3935 (define_expand "ashldi3"
3936   [(set (match_operand:DI 0 "general_operand" "=rm")
3937         (ashift:DI (match_operand:DI 1 "general_operand" "rm")
3938                      (match_operand 2 "const_int_operand" "n")))]
3939   ""
3940   "
3941 {
3942   if (GET_CODE (operands[2]) != CONST_INT
3943   || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
3944      && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
3945     FAIL;
3946 } ")
3947
3948 ;; On all 68k models, this makes faster code in a special case.
3949
3950 (define_insn ""
3951   [(set (match_operand:SI 0 "register_operand" "=d")
3952         (ashift:SI (match_operand:SI 1 "register_operand" "0")
3953                    (const_int 16)))]
3954   ""
3955   "*
3956 {
3957   CC_STATUS_INIT;
3958   return \"swap %0\;clr%.w %0\";
3959 }")
3960
3961 ;; On the 68000, this makes faster code in a special case.
3962
3963 (define_insn ""
3964   [(set (match_operand:SI 0 "register_operand" "=d")
3965         (ashift:SI (match_operand:SI 1 "register_operand" "0")
3966                    (match_operand:SI 2 "const_int_operand" "n")))]
3967   "(! TARGET_68020
3968     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
3969   "*
3970 {
3971   CC_STATUS_INIT;
3972
3973   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
3974   return \"asl%.w %2,%0\;swap %0\;clr%.w %0\";
3975 }")
3976
3977 (define_insn "ashlsi3"
3978   [(set (match_operand:SI 0 "register_operand" "=d")
3979         (ashift:SI (match_operand:SI 1 "register_operand" "0")
3980                    (match_operand:SI 2 "general_operand" "dI")))]
3981   ""
3982   "*
3983 {
3984   if (operands[2] == const1_rtx)
3985     return \"add%.l %0,%0\";
3986   return \"asl%.l %2,%0\";
3987 }")
3988
3989 (define_insn "ashlhi3"
3990   [(set (match_operand:HI 0 "register_operand" "=d")
3991         (ashift:HI (match_operand:HI 1 "register_operand" "0")
3992                    (match_operand:HI 2 "general_operand" "dI")))]
3993   ""
3994   "asl%.w %2,%0")
3995
3996 (define_insn ""
3997   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
3998         (ashift:HI (match_dup 0)
3999                    (match_operand:HI 1 "general_operand" "dI")))]
4000   ""
4001   "asl%.w %1,%0")
4002
4003 (define_insn "ashlqi3"
4004   [(set (match_operand:QI 0 "register_operand" "=d")
4005         (ashift:QI (match_operand:QI 1 "register_operand" "0")
4006                    (match_operand:QI 2 "general_operand" "dI")))]
4007   ""
4008   "asl%.b %2,%0")
4009
4010 (define_insn ""
4011   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4012         (ashift:QI (match_dup 0)
4013                    (match_operand:QI 1 "general_operand" "dI")))]
4014   ""
4015   "asl%.b %1,%0")
4016
4017 ;; On all 68k models, this makes faster code in a special case.
4018
4019 (define_insn ""
4020   [(set (match_operand:SI 0 "register_operand" "=d")
4021         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4022                      (const_int 16)))]
4023   ""
4024   "swap %0\;ext%.l %0")
4025
4026 ;; On the 68000, this makes faster code in a special case.
4027
4028 (define_insn ""
4029   [(set (match_operand:SI 0 "register_operand" "=d")
4030         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4031                      (match_operand:SI 2 "const_int_operand" "n")))]
4032   "(! TARGET_68020
4033     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
4034   "*
4035 {
4036   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
4037   return \"swap %0\;asr%.w %2,%0\;ext%.l %0\";
4038 }")
4039
4040 (define_insn "subreg1ashrdi_const32"
4041   [(set (match_operand:SI 0 "general_operand" "=rm")
4042     (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4043             (const_int 32)) 1))]
4044   ""
4045   "*
4046 {
4047   return \"move%.l %1,%0\";
4048 } ")
4049
4050 (define_insn "ashrdi_const32"
4051   [(set (match_operand:DI 0 "general_operand" "=d")
4052         (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4053                      (const_int 32)))]
4054   ""
4055   "*
4056 {
4057   CC_STATUS_INIT;
4058   operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
4059   if (TARGET_68020)
4060     return \"move%.l %1,%2\;smi %0\;extb%.l %0\";
4061   else
4062     return \"move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0\";
4063 } ")
4064
4065 (define_insn "ashrdi_const32_mem"
4066   [(set (match_operand:DI 0 "general_operand" "=o,<")
4067         (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro,ro")
4068                      (const_int 32)))
4069    (clobber (match_scratch:SI 2 "=d,d"))]
4070   ""
4071   "*
4072 {
4073   CC_STATUS_INIT;
4074   if (which_alternative == 1)
4075     operands[3] = operands[0];
4076   else
4077     operands[3] = adj_offsettable_operand (operands[0], 4);
4078   if (TARGET_68020)
4079     return \"move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0\";
4080   else
4081     return \"move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\";
4082 } ")
4083
4084 (define_insn "ashrdi_const"
4085   [(set (match_operand:DI 0 "general_operand" "=d")
4086         (ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
4087                      (match_operand 2 "const_int_operand" "n")))]
4088   "(INTVAL (operands[2]) == 1
4089   || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
4090   "*
4091 {
4092   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
4093   CC_STATUS_INIT;
4094   if (INTVAL (operands[2]) == 1)
4095     return \"asr%.l %#1,%0\;roxr%.l %#1,%1\";
4096   else if (INTVAL (operands[2]) == 2)
4097     return \"asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\";
4098   else/* if (INTVAL (operands[2]) == 3)*/
4099     return \"asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\";
4100 } ")
4101
4102 (define_expand "ashrdi3"
4103   [(set (match_operand:DI 0 "general_operand" "=rm")
4104         (ashiftrt:DI (match_operand:DI 1 "general_operand" "rm")
4105                      (match_operand 2 "const_int_operand" "n")))]
4106   ""
4107   "
4108 {
4109   if (GET_CODE (operands[2]) != CONST_INT
4110   || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
4111      && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
4112     FAIL;
4113 } ")
4114
4115 (define_insn "ashrsi3"
4116   [(set (match_operand:SI 0 "register_operand" "=d")
4117         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4118                      (match_operand:SI 2 "general_operand" "dI")))]
4119   ""
4120   "asr%.l %2,%0")
4121
4122 (define_insn "ashrhi3"
4123   [(set (match_operand:HI 0 "register_operand" "=d")
4124         (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
4125                      (match_operand:HI 2 "general_operand" "dI")))]
4126   ""
4127   "asr%.w %2,%0")
4128
4129 (define_insn ""
4130   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4131         (ashiftrt:HI (match_dup 0)
4132                      (match_operand:HI 1 "general_operand" "dI")))]
4133   ""
4134   "asr%.w %1,%0")
4135
4136 (define_insn "ashrqi3"
4137   [(set (match_operand:QI 0 "register_operand" "=d")
4138         (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
4139                      (match_operand:QI 2 "general_operand" "dI")))]
4140   ""
4141   "asr%.b %2,%0")
4142
4143 (define_insn ""
4144   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4145         (ashiftrt:QI (match_dup 0)
4146                      (match_operand:QI 1 "general_operand" "dI")))]
4147   ""
4148   "asr%.b %1,%0")
4149 \f
4150 ;; logical shift instructions
4151
4152 (define_insn "subreg1lshrdi_const32"
4153   [(set (match_operand:SI 0 "general_operand" "=rm")
4154     (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4155             (const_int 32)) 1))]
4156   ""
4157   "*
4158 {
4159   return \"move%.l %1,%0\";
4160 } ")
4161
4162 (define_insn "lshrdi_const32"
4163   [(set (match_operand:DI 0 "general_operand" "=ro,<,>")
4164         (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,ro,ro")
4165                      (const_int 32)))]
4166   ""
4167   "*
4168 {
4169   CC_STATUS_INIT;
4170   if (which_alternative == 1)
4171     return \"move%.l %1,%0\;clr%.l %0\";
4172   if (which_alternative == 2)
4173     return \"clr%.l %0\;move%.l %1,%0\";
4174   if (GET_CODE (operands[0]) == REG)
4175     operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
4176   else
4177     operands[2] = adj_offsettable_operand (operands[0], 4);
4178   if (GET_CODE (operands[1]) == REG)
4179     operands[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
4180   else
4181     operands[3] = adj_offsettable_operand (operands[1], 4);
4182   if (ADDRESS_REG_P (operands[0]))
4183     return \"move%.l %1,%2\;sub%.l %0,%0\";
4184   else
4185     return \"move%.l %1,%2\;clr%.l %0\";
4186 } ")
4187
4188 (define_insn "lshrdi_const"
4189   [(set (match_operand:DI 0 "general_operand" "=d")
4190         (lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
4191                      (match_operand 2 "const_int_operand" "n")))]
4192   "(INTVAL (operands[2]) == 1 
4193     || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
4194   "*
4195 {
4196   CC_STATUS_INIT;
4197   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
4198   if (INTVAL (operands[2]) == 1)
4199     return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\";
4200   else if (INTVAL (operands[2]) == 2)
4201     return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\";
4202   else /*if (INTVAL (operands[2]) == 3)*/
4203     return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\";
4204 } ")
4205
4206 (define_expand "lshrdi3"
4207   [(set (match_operand:DI 0 "general_operand" "=rm")
4208         (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm")
4209                      (match_operand 2 "const_int_operand" "n")))]
4210   ""
4211   "
4212 {
4213   if (GET_CODE (operands[2]) != CONST_INT
4214   || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
4215       && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
4216     FAIL;
4217 } ")
4218
4219 ;; On all 68k models, this makes faster code in a special case.
4220
4221 (define_insn "lshrsi_31"
4222   [(set (match_operand:SI 0 "register_operand" "=d")
4223         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
4224                      (const_int 31)))]
4225   ""
4226   "*
4227 {
4228 #if defined(MOTOROLA) && !defined(CRDS)
4229   return \"roxl%.l %#1,%0\;moveq%.l %#0,%d0\;roxl%.l %#1,%0\";
4230 #else
4231   return \"roxl%.l %#1,%0\;moveq %#0,%d0\;roxl%.l %#1,%0\";
4232 #endif
4233 }")
4234
4235 ;; On all 68k models, this makes faster code in a special case.
4236
4237 (define_insn "lshrsi_16"
4238   [(set (match_operand:SI 0 "register_operand" "=d")
4239         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
4240                      (const_int 16)))]
4241   ""
4242   "*
4243 {
4244   CC_STATUS_INIT;
4245   return \"clr%.w %0\;swap %0\";
4246 }")
4247
4248 ;; On the 68000, this makes faster code in a special case.
4249
4250 (define_insn "lshrsi_17_24"
4251   [(set (match_operand:SI 0 "register_operand" "=d")
4252         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
4253                      (match_operand:SI 2 "const_int_operand" "n")))]
4254   "(! TARGET_68020
4255     && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
4256   "*
4257 {
4258   /* I think lsr%.w sets the CC properly.  */
4259   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
4260   return \"clr%.w %0\;swap %0\;lsr%.w %2,%0\";
4261 }")
4262
4263 (define_insn "lshrsi3"
4264   [(set (match_operand:SI 0 "register_operand" "=d")
4265         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
4266                      (match_operand:SI 2 "general_operand" "dI")))]
4267   ""
4268   "lsr%.l %2,%0")
4269
4270 (define_insn "lshrhi3"
4271   [(set (match_operand:HI 0 "register_operand" "=d")
4272         (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
4273                      (match_operand:HI 2 "general_operand" "dI")))]
4274   ""
4275   "lsr%.w %2,%0")
4276
4277 (define_insn ""
4278   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4279         (lshiftrt:HI (match_dup 0)
4280                      (match_operand:HI 1 "general_operand" "dI")))]
4281   ""
4282   "lsr%.w %1,%0")
4283
4284 (define_insn "lshrqi3"
4285   [(set (match_operand:QI 0 "register_operand" "=d")
4286         (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
4287                      (match_operand:QI 2 "general_operand" "dI")))]
4288   ""
4289   "lsr%.b %2,%0")
4290
4291 (define_insn ""
4292   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4293         (lshiftrt:QI (match_dup 0)
4294                      (match_operand:QI 1 "general_operand" "dI")))]
4295   ""
4296   "lsr%.b %1,%0")
4297 \f
4298 ;; rotate instructions
4299
4300 (define_insn "rotlsi3"
4301   [(set (match_operand:SI 0 "register_operand" "=d")
4302         (rotate:SI (match_operand:SI 1 "register_operand" "0")
4303                    (match_operand:SI 2 "general_operand" "dI")))]
4304   ""
4305   "rol%.l %2,%0")
4306
4307 (define_insn "rotlhi3"
4308   [(set (match_operand:HI 0 "register_operand" "=d")
4309         (rotate:HI (match_operand:HI 1 "register_operand" "0")
4310                    (match_operand:HI 2 "general_operand" "dI")))]
4311   ""
4312   "rol%.w %2,%0")
4313
4314
4315 (define_insn ""
4316   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4317         (rotate:HI (match_dup 0)
4318                    (match_operand:HI 1 "general_operand" "dI")))]
4319   ""
4320   "rol%.w %1,%0")
4321
4322 (define_insn "rotlqi3"
4323   [(set (match_operand:QI 0 "register_operand" "=d")
4324         (rotate:QI (match_operand:QI 1 "register_operand" "0")
4325                    (match_operand:QI 2 "general_operand" "dI")))]
4326   ""
4327   "rol%.b %2,%0")
4328
4329 (define_insn ""
4330   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4331         (rotate:QI (match_dup 0)
4332                    (match_operand:QI 1 "general_operand" "dI")))]
4333   ""
4334   "rol%.b %1,%0")
4335
4336 (define_insn "rotrsi3"
4337   [(set (match_operand:SI 0 "register_operand" "=d")
4338         (rotatert:SI (match_operand:SI 1 "register_operand" "0")
4339                      (match_operand:SI 2 "general_operand" "dI")))]
4340   ""
4341   "ror%.l %2,%0")
4342
4343 (define_insn "rotrhi3"
4344   [(set (match_operand:HI 0 "register_operand" "=d")
4345         (rotatert:HI (match_operand:HI 1 "register_operand" "0")
4346                      (match_operand:HI 2 "general_operand" "dI")))]
4347   ""
4348   "ror%.w %2,%0")
4349
4350 (define_insn ""
4351   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4352         (rotatert:HI (match_dup 0)
4353                      (match_operand:HI 1 "general_operand" "dI")))]
4354   ""
4355   "ror%.w %1,%0")
4356
4357 (define_insn "rotrqi3"
4358   [(set (match_operand:QI 0 "register_operand" "=d")
4359         (rotatert:QI (match_operand:QI 1 "register_operand" "0")
4360                      (match_operand:QI 2 "general_operand" "dI")))]
4361   ""
4362   "ror%.b %2,%0")
4363
4364 (define_insn ""
4365   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4366         (rotatert:QI (match_dup 0)
4367                      (match_operand:QI 1 "general_operand" "dI")))]
4368   ""
4369   "ror%.b %1,%0")
4370 \f
4371
4372 ;; Bit set/clear in memory byte.
4373
4374 ;; set bit, bit number is int
4375 (define_insn "bsetmemqi"
4376   [(set (match_operand:QI 0 "memory_operand" "+m")
4377         (ior:QI (subreg:QI (ashift:SI (const_int 1)
4378                 (match_operand:SI 1 "general_operand" "d")) 0)
4379         (match_dup 0)))]
4380   ""
4381   "*
4382 {
4383   CC_STATUS_INIT;
4384   return \"bset %1,%0\";
4385 }")
4386
4387 ;; set bit, bit number is (sign/zero)_extended from HImode/QImode
4388 (define_insn ""
4389   [(set (match_operand:QI 0 "memory_operand" "+m")
4390         (ior:QI (subreg:QI (ashift:SI (const_int 1)
4391             (match_operator:SI 2 "extend_operator"
4392                 [(match_operand 1 "general_operand" "d")])) 0)
4393         (match_dup 0)))]
4394   ""
4395   "*
4396 {
4397   CC_STATUS_INIT;
4398   return \"bset %1,%0\";
4399 }")
4400
4401 ;; clear bit, bit number is int
4402 (define_insn "bclrmemqi"
4403   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
4404         (const_int 1)
4405         (minus:SI (const_int 7)
4406             (match_operand:SI 1 "general_operand" "d")))
4407     (const_int 0))]
4408   ""
4409   "*
4410 {
4411   CC_STATUS_INIT;
4412   return \"bclr %1,%0\";
4413 }")
4414
4415 ;; clear bit, bit number is (sign/zero)_extended from HImode/QImode
4416 (define_insn ""
4417   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
4418         (const_int 1)
4419         (minus:SI (const_int 7)
4420             (match_operator:SI 2 "extend_operator"
4421                 [(match_operand 1 "general_operand" "d")])))
4422     (const_int 0))]
4423   ""
4424   "*
4425 {
4426   CC_STATUS_INIT;
4427   return \"bclr %1,%0\";
4428 }")
4429
4430 ;; Special cases of bit-field insns which we should
4431 ;; recognize in preference to the general case.
4432 ;; These handle aligned 8-bit and 16-bit fields,
4433 ;; which can usually be done with move instructions.
4434
4435 ;
4436 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
4437 ; alignment of structure members is specified.
4438 ;
4439 ; The move is allowed to be odd byte aligned, because that's still faster
4440 ; than an odd byte aligned bit field instruction.
4441 ;
4442 (define_insn ""
4443   [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o")
4444                          (const_int 32)
4445                          (match_operand:SI 2 "const_int_operand" "n"))
4446         (match_operand:SI 3 "general_operand" "rmi"))]
4447   "TARGET_68020 && TARGET_BITFIELD
4448    && (INTVAL (operands[2]) % 8) == 0
4449    && ! mode_dependent_address_p (XEXP (operands[0], 0))"
4450   "*
4451 {
4452   operands[0]
4453     = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
4454
4455   return \"move%.l %3,%0\";
4456 }")
4457
4458 (define_insn ""
4459   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do")
4460                          (match_operand:SI 1 "const_int_operand" "n")
4461                          (match_operand:SI 2 "const_int_operand" "n"))
4462         (match_operand:SI 3 "register_operand" "d"))]
4463   "TARGET_68020 && TARGET_BITFIELD
4464    && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
4465    && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
4466    && (GET_CODE (operands[0]) == REG
4467        || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
4468   "*
4469 {
4470   if (REG_P (operands[0]))
4471     {
4472       if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
4473         return \"bfins %3,%0{%b2:%b1}\";
4474     }
4475   else
4476     operands[0]
4477       = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
4478
4479   if (GET_CODE (operands[3]) == MEM)
4480     operands[3] = adj_offsettable_operand (operands[3],
4481                                            (32 - INTVAL (operands[1])) / 8);
4482   if (INTVAL (operands[1]) == 8)
4483     return \"move%.b %3,%0\";
4484   return \"move%.w %3,%0\";
4485 }")
4486
4487
4488 ;
4489 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
4490 ; alignment of structure members is specified.
4491 ;
4492 ; The move is allowed to be odd byte aligned, because that's still faster
4493 ; than an odd byte aligned bit field instruction.
4494 ;
4495 (define_insn ""
4496   [(set (match_operand:SI 0 "general_operand" "=rm")
4497         (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o")
4498                          (const_int 32)
4499                          (match_operand:SI 3 "const_int_operand" "n")))]
4500   "TARGET_68020 && TARGET_BITFIELD
4501    && (INTVAL (operands[3]) % 8) == 0
4502    && ! mode_dependent_address_p (XEXP (operands[1], 0))"
4503   "*
4504 {
4505   operands[1]
4506     = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
4507
4508   return \"move%.l %1,%0\";
4509 }")
4510
4511 (define_insn ""
4512   [(set (match_operand:SI 0 "general_operand" "=&d")
4513         (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
4514                          (match_operand:SI 2 "const_int_operand" "n")
4515                          (match_operand:SI 3 "const_int_operand" "n")))]
4516   "TARGET_68020 && TARGET_BITFIELD
4517    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
4518    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
4519    && (GET_CODE (operands[1]) == REG
4520        || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
4521   "*
4522 {
4523   cc_status.flags |= CC_NOT_NEGATIVE;
4524   if (REG_P (operands[1]))
4525     {
4526       if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
4527         return \"bfextu %1{%b3:%b2},%0\";
4528     }
4529   else
4530     operands[1]
4531       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
4532
4533   output_asm_insn (\"clr%.l %0\", operands);
4534   if (GET_CODE (operands[0]) == MEM)
4535     operands[0] = adj_offsettable_operand (operands[0],
4536                                            (32 - INTVAL (operands[1])) / 8);
4537   if (INTVAL (operands[2]) == 8)
4538     return \"move%.b %1,%0\";
4539   return \"move%.w %1,%0\";
4540 }")
4541
4542 ;
4543 ; Special case for 32-bit field in memory.  This only occurs when 32-bit
4544 ; alignment of structure members is specified.
4545 ;
4546 ; The move is allowed to be odd byte aligned, because that's still faster
4547 ; than an odd byte aligned bit field instruction.
4548 ;
4549 (define_insn ""
4550   [(set (match_operand:SI 0 "general_operand" "=rm")
4551         (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o")
4552                          (const_int 32)
4553                          (match_operand:SI 3 "const_int_operand" "n")))]
4554   "TARGET_68020 && TARGET_BITFIELD
4555    && (INTVAL (operands[3]) % 8) == 0
4556    && ! mode_dependent_address_p (XEXP (operands[1], 0))"
4557   "*
4558 {
4559   operands[1]
4560     = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
4561
4562   return \"move%.l %1,%0\";
4563 }")
4564
4565 (define_insn ""
4566   [(set (match_operand:SI 0 "general_operand" "=d")
4567         (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
4568                          (match_operand:SI 2 "const_int_operand" "n")
4569                          (match_operand:SI 3 "const_int_operand" "n")))]
4570   "TARGET_68020 && TARGET_BITFIELD
4571    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
4572    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
4573    && (GET_CODE (operands[1]) == REG
4574        || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
4575   "*
4576 {
4577   if (REG_P (operands[1]))
4578     {
4579       if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
4580         return \"bfexts %1{%b3:%b2},%0\";
4581     }
4582   else
4583     operands[1]
4584       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
4585
4586   if (INTVAL (operands[2]) == 8)
4587     return \"move%.b %1,%0\;extb%.l %0\";
4588   return \"move%.w %1,%0\;ext%.l %0\";
4589 }")
4590 \f
4591 ;; Bit field instructions, general cases.
4592 ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
4593 ;; so that its address is reloaded.
4594
4595 (define_insn "extv"
4596   [(set (match_operand:SI 0 "general_operand" "=d,d")
4597         (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
4598                          (match_operand:SI 2 "general_operand" "di,di")
4599                          (match_operand:SI 3 "general_operand" "di,di")))]
4600   "TARGET_68020 && TARGET_BITFIELD"
4601   "bfexts %1{%b3:%b2},%0")
4602
4603 (define_insn "extzv"
4604   [(set (match_operand:SI 0 "general_operand" "=d,d")
4605         (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
4606                          (match_operand:SI 2 "general_operand" "di,di")
4607                          (match_operand:SI 3 "general_operand" "di,di")))]
4608   "TARGET_68020 && TARGET_BITFIELD"
4609   "*
4610 {
4611   if (GET_CODE (operands[2]) == CONST_INT)
4612     {
4613       if (INTVAL (operands[2]) != 32)
4614         cc_status.flags |= CC_NOT_NEGATIVE;
4615     }
4616   else
4617     {
4618       CC_STATUS_INIT;
4619     }
4620   return \"bfextu %1{%b3:%b2},%0\";
4621 }")
4622
4623 (define_insn ""
4624   [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
4625                          (match_operand:SI 1 "general_operand" "di,di")
4626                          (match_operand:SI 2 "general_operand" "di,di"))
4627         (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
4628                 (match_operand 3 "const_int_operand" "n,n")))]
4629   "TARGET_68020 && TARGET_BITFIELD
4630    && (INTVAL (operands[3]) == -1
4631        || (GET_CODE (operands[1]) == CONST_INT
4632            && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
4633   "*
4634 {
4635   CC_STATUS_INIT;
4636   return \"bfchg %0{%b2:%b1}\";
4637 }")
4638
4639 (define_insn ""
4640   [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
4641                          (match_operand:SI 1 "general_operand" "di,di")
4642                          (match_operand:SI 2 "general_operand" "di,di"))
4643         (const_int 0))]
4644   "TARGET_68020 && TARGET_BITFIELD"
4645   "*
4646 {
4647   CC_STATUS_INIT;
4648   return \"bfclr %0{%b2:%b1}\";
4649 }")
4650
4651 (define_insn ""
4652   [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
4653                          (match_operand:SI 1 "general_operand" "di,di")
4654                          (match_operand:SI 2 "general_operand" "di,di"))
4655         (const_int -1))]
4656   "TARGET_68020 && TARGET_BITFIELD"
4657   "*
4658 {
4659   CC_STATUS_INIT;
4660   return \"bfset %0{%b2:%b1}\";
4661 }")
4662
4663 (define_insn "insv"
4664   [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
4665                          (match_operand:SI 1 "general_operand" "di,di")
4666                          (match_operand:SI 2 "general_operand" "di,di"))
4667         (match_operand:SI 3 "register_operand" "d,d"))]
4668   "TARGET_68020 && TARGET_BITFIELD"
4669   "bfins %3,%0{%b2:%b1}")
4670
4671 ;; Now recognize bit field insns that operate on registers
4672 ;; (or at least were intended to do so).
4673
4674 (define_insn ""
4675   [(set (match_operand:SI 0 "general_operand" "=d")
4676         (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
4677                          (match_operand:SI 2 "general_operand" "di")
4678                          (match_operand:SI 3 "general_operand" "di")))]
4679   "TARGET_68020 && TARGET_BITFIELD"
4680   "bfexts %1{%b3:%b2},%0")
4681
4682 (define_insn ""
4683   [(set (match_operand:SI 0 "general_operand" "=d")
4684         (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
4685                          (match_operand:SI 2 "general_operand" "di")
4686                          (match_operand:SI 3 "general_operand" "di")))]
4687   "TARGET_68020 && TARGET_BITFIELD"
4688   "*
4689 {
4690   if (GET_CODE (operands[2]) == CONST_INT)
4691     {
4692       if (INTVAL (operands[2]) != 32)
4693         cc_status.flags |= CC_NOT_NEGATIVE;
4694     }
4695   else
4696     {
4697       CC_STATUS_INIT;
4698     }
4699   return \"bfextu %1{%b3:%b2},%0\";
4700 }")
4701
4702 (define_insn ""
4703   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
4704                          (match_operand:SI 1 "general_operand" "di")
4705                          (match_operand:SI 2 "general_operand" "di"))
4706         (const_int 0))]
4707   "TARGET_68020 && TARGET_BITFIELD"
4708   "*
4709 {
4710   CC_STATUS_INIT;
4711   return \"bfclr %0{%b2:%b1}\";
4712 }")
4713
4714 (define_insn ""
4715   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
4716                          (match_operand:SI 1 "general_operand" "di")
4717                          (match_operand:SI 2 "general_operand" "di"))
4718         (const_int -1))]
4719   "TARGET_68020 && TARGET_BITFIELD"
4720   "*
4721 {
4722   CC_STATUS_INIT;
4723   return \"bfset %0{%b2:%b1}\";
4724 }")
4725
4726 (define_insn ""
4727   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
4728                          (match_operand:SI 1 "general_operand" "di")
4729                          (match_operand:SI 2 "general_operand" "di"))
4730         (match_operand:SI 3 "register_operand" "d"))]
4731   "TARGET_68020 && TARGET_BITFIELD"
4732   "*
4733 {
4734 #if 0
4735   /* These special cases are now recognized by a specific pattern.  */
4736   if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
4737       && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
4738     return \"move%.w %3,%0\";
4739   if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
4740       && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
4741     return \"move%.b %3,%0\";
4742 #endif
4743   return \"bfins %3,%0{%b2:%b1}\";
4744 }")
4745 \f
4746 ;; Special patterns for optimizing bit-field instructions.
4747
4748 (define_insn ""
4749   [(set (cc0)
4750         (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
4751                          (match_operand:SI 1 "const_int_operand" "n")
4752                          (match_operand:SI 2 "general_operand" "di")))]
4753   "TARGET_68020 && TARGET_BITFIELD"
4754   "*
4755 {
4756   if (operands[1] == const1_rtx
4757       && GET_CODE (operands[2]) == CONST_INT)
4758     {    
4759       int width = GET_CODE (operands[0]) == REG ? 31 : 7;
4760       return output_btst (operands,
4761                           gen_rtx (CONST_INT, VOIDmode,
4762                                    width - INTVAL (operands[2])),
4763                           operands[0],
4764                           insn, 1000);
4765       /* Pass 1000 as SIGNPOS argument so that btst will
4766          not think we are testing the sign bit for an `and'
4767          and assume that nonzero implies a negative result.  */
4768     }
4769   if (INTVAL (operands[1]) != 32)
4770     cc_status.flags = CC_NOT_NEGATIVE;
4771   return \"bftst %0{%b2:%b1}\";
4772 }")
4773
4774   
4775 ;;; now handle the register cases
4776 (define_insn ""
4777   [(set (cc0)
4778         (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
4779                          (match_operand:SI 1 "const_int_operand" "n")
4780                          (match_operand:SI 2 "general_operand" "di")))]
4781   "TARGET_68020 && TARGET_BITFIELD"
4782   "*
4783 {
4784   if (operands[1] == const1_rtx
4785       && GET_CODE (operands[2]) == CONST_INT)
4786     {    
4787       int width = GET_CODE (operands[0]) == REG ? 31 : 7;
4788       return output_btst (operands,
4789                           gen_rtx (CONST_INT, VOIDmode,
4790                                    width - INTVAL (operands[2])),
4791                           operands[0],
4792                           insn, 1000);
4793       /* Pass 1000 as SIGNPOS argument so that btst will
4794          not think we are testing the sign bit for an `and'
4795          and assume that nonzero implies a negative result.  */
4796     }
4797   if (INTVAL (operands[1]) != 32)
4798     cc_status.flags = CC_NOT_NEGATIVE;
4799   return \"bftst %0{%b2:%b1}\";
4800 }")
4801 \f
4802 (define_insn "seq"
4803   [(set (match_operand:QI 0 "general_operand" "=d")
4804         (eq:QI (cc0) (const_int 0)))]
4805   ""
4806   "*
4807   cc_status = cc_prev_status;
4808   OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
4809 ")
4810
4811 (define_insn "sne"
4812   [(set (match_operand:QI 0 "general_operand" "=d")
4813         (ne:QI (cc0) (const_int 0)))]
4814   ""
4815   "*
4816   cc_status = cc_prev_status;
4817   OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
4818 ")
4819
4820 (define_insn "sgt"
4821   [(set (match_operand:QI 0 "general_operand" "=d")
4822         (gt:QI (cc0) (const_int 0)))]
4823   ""
4824   "*
4825   cc_status = cc_prev_status;
4826   OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0);
4827 ")
4828
4829 (define_insn "sgtu"
4830   [(set (match_operand:QI 0 "general_operand" "=d")
4831         (gtu:QI (cc0) (const_int 0)))]
4832   ""
4833   "* cc_status = cc_prev_status;
4834      return \"shi %0\"; ")
4835
4836 (define_insn "slt"
4837   [(set (match_operand:QI 0 "general_operand" "=d")
4838         (lt:QI (cc0) (const_int 0)))]
4839   ""
4840   "* cc_status = cc_prev_status;
4841      OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
4842
4843 (define_insn "sltu"
4844   [(set (match_operand:QI 0 "general_operand" "=d")
4845         (ltu:QI (cc0) (const_int 0)))]
4846   ""
4847   "* cc_status = cc_prev_status;
4848      return \"scs %0\"; ")
4849
4850 (define_insn "sge"
4851   [(set (match_operand:QI 0 "general_operand" "=d")
4852         (ge:QI (cc0) (const_int 0)))]
4853   ""
4854   "* cc_status = cc_prev_status;
4855      OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
4856
4857 (define_insn "sgeu"
4858   [(set (match_operand:QI 0 "general_operand" "=d")
4859         (geu:QI (cc0) (const_int 0)))]
4860   ""
4861   "* cc_status = cc_prev_status;
4862      return \"scc %0\"; ")
4863
4864 (define_insn "sle"
4865   [(set (match_operand:QI 0 "general_operand" "=d")
4866         (le:QI (cc0) (const_int 0)))]
4867   ""
4868   "*
4869   cc_status = cc_prev_status;
4870   OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0);
4871 ")
4872
4873 (define_insn "sleu"
4874   [(set (match_operand:QI 0 "general_operand" "=d")
4875         (leu:QI (cc0) (const_int 0)))]
4876   ""
4877   "* cc_status = cc_prev_status;
4878      return \"sls %0\"; ")
4879 \f
4880 ;; Basic conditional jump instructions.
4881
4882 (define_insn "beq"
4883   [(set (pc)
4884         (if_then_else (eq (cc0)
4885                           (const_int 0))
4886                       (label_ref (match_operand 0 "" ""))
4887                       (pc)))]
4888   ""
4889   "*
4890 {
4891 #ifdef MOTOROLA
4892   OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
4893 #else
4894   OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
4895 #endif
4896 }")
4897
4898 (define_insn "bne"
4899   [(set (pc)
4900         (if_then_else (ne (cc0)
4901                           (const_int 0))
4902                       (label_ref (match_operand 0 "" ""))
4903                       (pc)))]
4904   ""
4905   "*
4906 {
4907 #ifdef MOTOROLA
4908   OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
4909 #else
4910   OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
4911 #endif
4912 }")
4913
4914 (define_insn "bgt"
4915   [(set (pc)
4916         (if_then_else (gt (cc0)
4917                           (const_int 0))
4918                       (label_ref (match_operand 0 "" ""))
4919                       (pc)))]
4920   ""
4921   "*
4922 #ifdef MOTOROLA
4923   OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0);
4924 #else
4925   OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0);
4926 #endif
4927 ")
4928
4929 (define_insn "bgtu"
4930   [(set (pc)
4931         (if_then_else (gtu (cc0)
4932                            (const_int 0))
4933                       (label_ref (match_operand 0 "" ""))
4934                       (pc)))]
4935   ""
4936   "*
4937 #ifdef MOTOROLA
4938   return \"jbhi %l0\";
4939 #else
4940   return \"jhi %l0\";
4941 #endif
4942 ")
4943
4944 (define_insn "blt"
4945   [(set (pc)
4946         (if_then_else (lt (cc0)
4947                           (const_int 0))
4948                       (label_ref (match_operand 0 "" ""))
4949                       (pc)))]
4950   ""
4951   "*
4952 #ifdef MOTOROLA
4953   OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\");
4954 #else
4955   OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\");
4956 #endif
4957 ")
4958
4959 (define_insn "bltu"
4960   [(set (pc)
4961         (if_then_else (ltu (cc0)
4962                            (const_int 0))
4963                       (label_ref (match_operand 0 "" ""))
4964                       (pc)))]
4965   ""
4966   "*
4967 #ifdef MOTOROLA
4968   return \"jbcs %l0\";
4969 #else
4970   return \"jcs %l0\";
4971 #endif
4972 ")
4973
4974 (define_insn "bge"
4975   [(set (pc)
4976         (if_then_else (ge (cc0)
4977                           (const_int 0))
4978                       (label_ref (match_operand 0 "" ""))
4979                       (pc)))]
4980   ""
4981   "*
4982 #ifdef MOTOROLA
4983   OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\");
4984 #else
4985   OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\");
4986 #endif
4987 ")
4988
4989 (define_insn "bgeu"
4990   [(set (pc)
4991         (if_then_else (geu (cc0)
4992                            (const_int 0))
4993                       (label_ref (match_operand 0 "" ""))
4994                       (pc)))]
4995   ""
4996   "*
4997 #ifdef MOTOROLA
4998   return \"jbcc %l0\";
4999 #else
5000   return \"jcc %l0\";
5001 #endif
5002 ")
5003
5004 (define_insn "ble"
5005   [(set (pc)
5006         (if_then_else (le (cc0)
5007                           (const_int 0))
5008                       (label_ref (match_operand 0 "" ""))
5009                       (pc)))]
5010   ""
5011   "*
5012 #ifdef MOTOROLA
5013   OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0);
5014 #else
5015   OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0);
5016 #endif
5017 ")
5018
5019 (define_insn "bleu"
5020   [(set (pc)
5021         (if_then_else (leu (cc0)
5022                            (const_int 0))
5023                       (label_ref (match_operand 0 "" ""))
5024                       (pc)))]
5025   ""
5026   "*
5027 #ifdef MOTOROLA
5028   return \"jbls %l0\";
5029 #else
5030   return \"jls %l0\";
5031 #endif
5032 ")
5033 \f
5034 ;; Negated conditional jump instructions.
5035
5036 (define_insn ""
5037   [(set (pc)
5038         (if_then_else (eq (cc0)
5039                           (const_int 0))
5040                       (pc)
5041                       (label_ref (match_operand 0 "" ""))))]
5042   ""
5043   "*
5044 {
5045 #ifdef MOTOROLA
5046   OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
5047 #else
5048   OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
5049 #endif
5050 }")
5051
5052 (define_insn ""
5053   [(set (pc)
5054         (if_then_else (ne (cc0)
5055                           (const_int 0))
5056                       (pc)
5057                       (label_ref (match_operand 0 "" ""))))]
5058   ""
5059   "*
5060 {
5061 #ifdef MOTOROLA
5062   OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
5063 #else
5064   OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
5065 #endif
5066 }")
5067
5068 (define_insn ""
5069   [(set (pc)
5070         (if_then_else (gt (cc0)
5071                           (const_int 0))
5072                       (pc)
5073                       (label_ref (match_operand 0 "" ""))))]
5074   ""
5075   "*
5076 #ifdef MOTOROLA
5077   OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0);
5078 #else
5079   OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0);
5080 #endif
5081 ")
5082
5083 (define_insn ""
5084   [(set (pc)
5085         (if_then_else (gtu (cc0)
5086                            (const_int 0))
5087                       (pc)
5088                       (label_ref (match_operand 0 "" ""))))]
5089   ""
5090   "*
5091 #ifdef MOTOROLA
5092   return \"jbls %l0\";
5093 #else
5094   return \"jls %l0\";
5095 #endif
5096 ")
5097
5098 (define_insn ""
5099   [(set (pc)
5100         (if_then_else (lt (cc0)
5101                           (const_int 0))
5102                       (pc)
5103                       (label_ref (match_operand 0 "" ""))))]
5104   ""
5105   "*
5106 #ifdef MOTOROLA
5107   OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\");
5108 #else
5109   OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\");
5110 #endif
5111 ")
5112
5113 (define_insn ""
5114   [(set (pc)
5115         (if_then_else (ltu (cc0)
5116                            (const_int 0))
5117                       (pc)
5118                       (label_ref (match_operand 0 "" ""))))]
5119   ""
5120   "*
5121 #ifdef MOTOROLA
5122   return \"jbcc %l0\";
5123 #else
5124   return \"jcc %l0\";
5125 #endif
5126 ")
5127
5128 (define_insn ""
5129   [(set (pc)
5130         (if_then_else (ge (cc0)
5131                           (const_int 0))
5132                       (pc)
5133                       (label_ref (match_operand 0 "" ""))))]
5134   ""
5135   "*
5136 #ifdef MOTOROLA
5137   OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\");
5138 #else
5139   OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\");
5140 #endif
5141 ")
5142
5143 (define_insn ""
5144   [(set (pc)
5145         (if_then_else (geu (cc0)
5146                            (const_int 0))
5147                       (pc)
5148                       (label_ref (match_operand 0 "" ""))))]
5149   ""
5150   "*
5151 #ifdef MOTOROLA
5152   return \"jbcs %l0\";
5153 #else
5154   return \"jcs %l0\";
5155 #endif
5156 ")
5157
5158 (define_insn ""
5159   [(set (pc)
5160         (if_then_else (le (cc0)
5161                           (const_int 0))
5162                       (pc)
5163                       (label_ref (match_operand 0 "" ""))))]
5164   ""
5165   "*
5166 #ifdef MOTOROLA
5167   OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0);
5168 #else
5169   OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0);
5170 #endif
5171 ")
5172
5173 (define_insn ""
5174   [(set (pc)
5175         (if_then_else (leu (cc0)
5176                            (const_int 0))
5177                       (pc)
5178                       (label_ref (match_operand 0 "" ""))))]
5179   ""
5180   "*
5181 #ifdef MOTOROLA
5182   return \"jbhi %l0\";
5183 #else
5184   return \"jhi %l0\";
5185 #endif
5186 ")
5187 \f
5188 ;; Unconditional and other jump instructions
5189 (define_insn "jump"
5190   [(set (pc)
5191         (label_ref (match_operand 0 "" "")))]
5192   ""
5193   "*
5194 #ifdef MOTOROLA
5195   return \"jbra %l0\";
5196 #else
5197   return \"jra %l0\";
5198 #endif
5199 ")
5200
5201 ;; We support two different ways of handling dispatch tables.
5202 ;; The NeXT uses absolute tables, and other machines use relative.
5203 ;; This define_expand can generate either kind.
5204 (define_expand "tablejump"
5205   [(parallel [(set (pc) (match_operand 0 "" ""))
5206               (use (label_ref (match_operand 1 "" "")))])]
5207   ""
5208   "
5209 {
5210 #ifdef CASE_VECTOR_PC_RELATIVE
5211     operands[0] = gen_rtx (PLUS, SImode, pc_rtx,
5212                            gen_rtx (SIGN_EXTEND, SImode, operands[0]));
5213 #endif
5214 }")
5215
5216 ;; Jump to variable address from dispatch table of absolute addresses.
5217 (define_insn ""
5218   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
5219    (use (label_ref (match_operand 1 "" "")))]
5220   ""
5221   "*
5222 #ifdef MOTOROLA
5223   return \"jmp (%0)\";
5224 #else
5225   return \"jmp %0@\";
5226 #endif
5227 ")
5228
5229 ;; Jump to variable address from dispatch table of relative addresses.
5230 (define_insn ""
5231   [(set (pc)
5232         (plus:SI (pc)
5233                  (sign_extend:SI (match_operand:HI 0 "register_operand" "r"))))
5234    (use (label_ref (match_operand 1 "" "")))]
5235   ""
5236   "*
5237 #ifdef ASM_RETURN_CASE_JUMP
5238  ASM_RETURN_CASE_JUMP;
5239 #else
5240 #ifdef SGS
5241 #ifdef ASM_OUTPUT_CASE_LABEL
5242   return \"jmp 6(%%pc,%0.w)\";
5243 #else
5244 #ifdef CRDS
5245   return \"jmp 2(pc,%0.w)\";
5246 #else
5247   return \"jmp 2(%%pc,%0.w)\";
5248 #endif  /* end !CRDS */
5249 #endif
5250 #else /* not SGS */
5251 #ifdef MOTOROLA
5252   return \"jmp (2,pc,%0.w)\";
5253 #else
5254   return \"jmp pc@(2,%0:w)\";
5255 #endif
5256 #endif
5257 #endif
5258 ")
5259
5260 ;; Decrement-and-branch insns.
5261 (define_insn ""
5262   [(set (pc)
5263         (if_then_else
5264          (ne (match_operand:HI 0 "general_operand" "+g")
5265              (const_int 0))
5266          (label_ref (match_operand 1 "" ""))
5267          (pc)))
5268    (set (match_dup 0)
5269         (plus:HI (match_dup 0)
5270                  (const_int -1)))]
5271   ""
5272   "*
5273 {
5274   CC_STATUS_INIT;
5275   if (DATA_REG_P (operands[0]))
5276     return \"dbra %0,%l1\";
5277   if (GET_CODE (operands[0]) == MEM)
5278     {
5279 #ifdef MOTOROLA
5280 #ifdef NO_ADDSUB_Q
5281       return \"sub%.w %#1,%0\;jbcc %l1\";
5282 #else
5283       return \"subq%.w %#1,%0\;jbcc %l1\";
5284 #endif
5285 #else /* not MOTOROLA */
5286       return \"subqw %#1,%0\;jcc %l1\";
5287 #endif
5288     }
5289 #ifdef MOTOROLA
5290 #ifdef SGS_CMP_ORDER
5291 #ifdef NO_ADDSUB_Q
5292   return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
5293 #else
5294   return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
5295 #endif
5296 #else /* not SGS_CMP_ORDER */
5297   return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\";
5298 #endif
5299 #else /* not MOTOROLA */
5300   return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
5301 #endif
5302 }")
5303
5304 (define_insn ""
5305   [(set (pc)
5306         (if_then_else
5307          (ne (match_operand:SI 0 "general_operand" "+g")
5308              (const_int 0))
5309          (label_ref (match_operand 1 "" ""))
5310          (pc)))
5311    (set (match_dup 0)
5312         (plus:SI (match_dup 0)
5313                  (const_int -1)))]
5314   ""
5315   "*
5316 {
5317   CC_STATUS_INIT;
5318 #ifdef MOTOROLA
5319 #ifdef NO_ADDSUB_Q
5320   if (DATA_REG_P (operands[0]))
5321     return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\";
5322   if (GET_CODE (operands[0]) == MEM)
5323     return \"sub%.l %#1,%0\;jbcc %l1\";
5324 #else
5325   if (DATA_REG_P (operands[0]))
5326     return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\";
5327   if (GET_CODE (operands[0]) == MEM)
5328     return \"subq%.l %#1,%0\;jbcc %l1\";
5329 #endif /* NO_ADDSUB_Q */
5330 #ifdef SGS_CMP_ORDER
5331 #ifdef NO_ADDSUB_Q
5332   return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
5333 #else
5334   return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
5335 #endif
5336 #else /* not SGS_CMP_ORDER */
5337   return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
5338 #endif /* not SGS_CMP_ORDER */
5339 #else /* not MOTOROLA */
5340   if (DATA_REG_P (operands[0]))
5341     return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\";
5342   if (GET_CODE (operands[0]) == MEM)
5343     return \"subql %#1,%0\;jcc %l1\";
5344   return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
5345 #endif /* not MOTOROLA */
5346 }")
5347
5348 ;; Two dbra patterns that use REG_NOTES info generated by strength_reduce.
5349
5350 (define_insn ""
5351   [(set (pc)
5352         (if_then_else
5353           (ge (plus:HI (match_operand:HI 0 "general_operand" "+g")
5354                        (const_int -1))
5355               (const_int 0))
5356           (label_ref (match_operand 1 "" ""))
5357           (pc)))
5358    (set (match_dup 0)
5359         (plus:HI (match_dup 0)
5360                  (const_int -1)))]
5361   "find_reg_note (insn, REG_NONNEG, 0)"
5362   "*
5363 {
5364   CC_STATUS_INIT;
5365 #ifdef MOTOROLA
5366 #ifdef NO_ADDSUB_Q
5367   if (DATA_REG_P (operands[0]))
5368     return \"dbra %0,%l1\";
5369   if (GET_CODE (operands[0]) == MEM)
5370     return \"sub%.w %#1,%0\;jbcc %l1\";
5371 #else
5372   if (DATA_REG_P (operands[0]))
5373     return \"dbra %0,%l1\";
5374   if (GET_CODE (operands[0]) == MEM)
5375     return \"subq%.w %#1,%0\;jbcc %l1\";
5376 #endif
5377 #ifdef SGS_CMP_ORDER
5378 #ifdef NO_ADDSUB_Q
5379   return \"sub.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\";
5380 #else
5381   return \"subq.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\";
5382 #endif
5383 #else /* not SGS_CMP_ORDER */
5384   return \"subq.w %#1,%0\;cmp.w %#-1,%0\;jbne %l1\";
5385 #endif /* not SGS_CMP_ORDER */
5386 #else /* not MOTOROLA */
5387   if (DATA_REG_P (operands[0]))
5388     return \"dbra %0,%l1\";
5389   if (GET_CODE (operands[0]) == MEM)
5390     return \"subqw %#1,%0\;jcc %l1\";
5391   return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
5392 #endif /* not MOTOROLA */
5393 }")
5394
5395 (define_insn "decrement_and_branch_until_zero"
5396   [(set (pc)
5397         (if_then_else
5398           (ge (plus:SI (match_operand:SI 0 "general_operand" "+g")
5399                        (const_int -1))
5400               (const_int 0))
5401           (label_ref (match_operand 1 "" ""))
5402           (pc)))
5403    (set (match_dup 0)
5404         (plus:SI (match_dup 0)
5405                  (const_int -1)))]
5406   "find_reg_note (insn, REG_NONNEG, 0)"
5407   "*
5408 {
5409   CC_STATUS_INIT;
5410 #ifdef MOTOROLA
5411 #ifdef NO_ADDSUB_Q
5412   if (DATA_REG_P (operands[0]))
5413     return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\";
5414   if (GET_CODE (operands[0]) == MEM)
5415     return \"sub%.l %#1,%0\;jbcc %l1\";
5416 #else
5417   if (DATA_REG_P (operands[0]))
5418     return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\";
5419   if (GET_CODE (operands[0]) == MEM)
5420     return \"subq%.l %#1,%0\;jbcc %l1\";
5421 #endif
5422 #ifdef SGS_CMP_ORDER
5423 #ifdef NO_ADDSUB_Q
5424   return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
5425 #else
5426   return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
5427 #endif
5428 #else /* not SGS_CMP_ORDER */
5429   return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
5430 #endif /* not SGS_CMP_ORDER */
5431 #else /* not MOTOROLA */
5432   if (DATA_REG_P (operands[0]))
5433     return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\";
5434   if (GET_CODE (operands[0]) == MEM)
5435     return \"subql %#1,%0\;jcc %l1\";
5436   return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
5437 #endif /* not MOTOROLA */
5438 }")
5439
5440
5441 ;; PIC calls are handled by loading the address of the function into a 
5442 ;; register (via movsi), then emitting a register indirect call using
5443 ;; the "jsr" function call syntax.
5444 ;;
5445 ;; It is important to note that the "jsr" syntax is always used for 
5446 ;; PIC calls, even on machines in which GCC normally uses the "jbsr"
5447 ;; syntax for non-PIC calls.  This keeps at least 1 assembler (Sun)
5448 ;; from emitting incorrect code for a PIC call.
5449 ;;
5450 ;; We have different patterns for PIC calls and non-PIC calls.  The
5451 ;; different patterns are only used to choose the right syntax
5452 ;; ("jsr" vs "jbsr").
5453 ;;
5454 ;; On svr4 m68k, PIC stuff is done differently. To be able to support
5455 ;; dynamic linker LAZY BINDING, all the procedure calls need to go 
5456 ;; through the PLT (Procedure Linkage Table) section in PIC mode. The 
5457 ;; svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it 
5458 ;; will create the correct relocation entry (R_68K_PLT32) for `FUNC', 
5459 ;; that tells the linker editor to create an entry for `FUNC' in PLT
5460 ;; section at link time. However, all global objects reference are still
5461 ;; done by using `OBJ@GOT'. So, the goal here is to output the function 
5462 ;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'. 
5463 ;; We need to have a way to differentiate these two different operands.
5464 ;;
5465 ;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate 
5466 ;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs
5467 ;; to be changed to recognize function calls symbol_ref operand as a legal 
5468 ;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will 
5469 ;; avoid the compiler to load this symbol_ref operand into a register. 
5470 ;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly 
5471 ;; since the value is a PC relative offset, not a real address.
5472 ;;
5473 ;; All global objects are treated in the similar way as in SUN3. The only 
5474 ;; difference is: on m68k svr4, the reference of such global object needs 
5475 ;; to end with a suffix "@GOT" so the assembler and linker know to create
5476 ;; an entry for it in GOT (Global Offset Table) section. This is done in 
5477 ;; m68k.c.
5478
5479 ;; Call subroutine with no return value.
5480 (define_expand "call"
5481   [(call (match_operand:QI 0 "memory_operand" "")
5482          (match_operand:SI 1 "general_operand" ""))]
5483   ;; Operand 1 not really used on the m68000.
5484
5485   ""
5486   "
5487 {
5488   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5489 #ifdef MOTOROLA
5490     SYMBOL_REF_FLAG (XEXP (operands[0], 0)) = 1;
5491 #else
5492     operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
5493                            force_reg (Pmode, XEXP (operands[0], 0)));
5494 #endif
5495 }")
5496
5497 ;; This is a normal call sequence.
5498 (define_insn ""
5499   [(call (match_operand:QI 0 "memory_operand" "o")
5500          (match_operand:SI 1 "general_operand" "g"))]
5501   ;; Operand 1 not really used on the m68000.
5502
5503   "! flag_pic"
5504   "*
5505 #ifdef MOTOROLA
5506 #ifdef MOTOROLA_BSR
5507   if (GET_CODE (operands[0]) == MEM 
5508       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5509     return \"bsr %0\";
5510 #endif
5511   return \"jsr %0\";
5512 #else
5513   return \"jbsr %0\";
5514 #endif
5515 ")
5516
5517 ;; This is a PIC call sequence.
5518 (define_insn ""
5519   [(call (match_operand:QI 0 "memory_operand" "o")
5520          (match_operand:SI 1 "general_operand" "g"))]
5521   ;; Operand 1 not really used on the m68000.
5522
5523   "flag_pic"
5524   "*
5525 #ifdef MOTOROLA
5526   if (GET_CODE (operands[0]) == MEM 
5527       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5528 #ifdef HPUX_ASM
5529     return \"bsr.l %0\";
5530 #else
5531     return \"bsr %0@PLTPC\";
5532 #endif
5533 #endif
5534   return \"jsr %0\";
5535 ")
5536
5537 ;; Call subroutine, returning value in operand 0
5538 ;; (which must be a hard register).
5539 ;; See comments before "call" regarding PIC calls.
5540 (define_expand "call_value"
5541   [(set (match_operand 0 "" "")
5542         (call (match_operand:QI 1 "memory_operand" "")
5543      (match_operand:SI 2 "general_operand" "")))]
5544   ;; Operand 2 not really used on the m68000.
5545   ""
5546   "
5547 {
5548   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
5549 #ifdef MOTOROLA
5550     SYMBOL_REF_FLAG (XEXP (operands[1], 0)) = 1;
5551 #else
5552     operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
5553                            force_reg (Pmode, XEXP (operands[1], 0)));
5554 #endif
5555 }")
5556
5557 ;; This is a normal call_value
5558 (define_insn ""
5559   [(set (match_operand 0 "" "=rf")
5560         (call (match_operand:QI 1 "memory_operand" "o")
5561               (match_operand:SI 2 "general_operand" "g")))]
5562   ;; Operand 2 not really used on the m68000.
5563   "! flag_pic"
5564   "*
5565 #ifdef MOTOROLA
5566 #ifdef MOTOROLA_BSR
5567   if (GET_CODE (operands[1]) == MEM 
5568       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
5569     return \"bsr %1\";
5570 #endif
5571   return \"jsr %1\";
5572 #else
5573   return \"jbsr %1\";
5574 #endif
5575 ")
5576
5577 ;; This is a PIC call_value
5578 (define_insn ""
5579   [(set (match_operand 0 "" "=rf")
5580         (call (match_operand:QI 1 "memory_operand" "o")
5581               (match_operand:SI 2 "general_operand" "g")))]
5582   ;; Operand 2 not really used on the m68000.
5583   "flag_pic"
5584   "*
5585 #ifdef MOTOROLA
5586   if (GET_CODE (operands[1]) == MEM 
5587       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
5588 #ifdef HPUX_ASM
5589     return \"bsr.l %1\";
5590 #else
5591     return \"bsr %1@PLTPC\";
5592 #endif
5593 #endif
5594   return \"jsr %1\";
5595 ")
5596
5597 ;; Call subroutine returning any type.
5598
5599 (define_expand "untyped_call"
5600   [(parallel [(call (match_operand 0 "" "")
5601                     (const_int 0))
5602               (match_operand 1 "" "")
5603               (match_operand 2 "" "")])]
5604   "NEEDS_UNTYPED_CALL"
5605   "
5606 {
5607   int i;
5608
5609   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
5610
5611   for (i = 0; i < XVECLEN (operands[2], 0); i++)
5612     {
5613       rtx set = XVECEXP (operands[2], 0, i);
5614       emit_move_insn (SET_DEST (set), SET_SRC (set));
5615     }
5616
5617   /* The optimizer does not know that the call sets the function value
5618      registers we stored in the result block.  We avoid problems by
5619      claiming that all hard registers are used and clobbered at this
5620      point.  */
5621   emit_insn (gen_blockage ());
5622
5623   DONE;
5624 }")
5625
5626 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
5627 ;; all of memory.  This blocks insns from being moved across this point.
5628
5629 (define_insn "blockage"
5630   [(unspec_volatile [(const_int 0)] 0)]
5631   ""
5632   "")
5633
5634 (define_insn "nop"
5635   [(const_int 0)]
5636   ""
5637   "nop")
5638
5639 (define_insn "probe"
5640  [(reg:SI 15)]
5641  "NEED_PROBE"
5642  "*
5643 {
5644   operands[0] = gen_rtx (PLUS, SImode, stack_pointer_rtx,
5645                          gen_rtx (CONST_INT, VOIDmode, NEED_PROBE));
5646   return \"tstl %a0\";
5647 }")
5648
5649 ;; Used for frameless functions which save no regs and allocate no locals.
5650 (define_insn "return"
5651   [(return)]
5652   "USE_RETURN_INSN"
5653   "*
5654 {
5655   if (current_function_pops_args == 0)
5656     return \"rts\";
5657   operands[0] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args);
5658   return \"rtd %0\";
5659 }")
5660
5661 (define_insn "indirect_jump"
5662   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
5663   ""
5664   "jmp %a0")
5665 \f
5666 ;; This should not be used unless the add/sub insns can't be.
5667
5668 (define_insn ""
5669   [(set (match_operand:SI 0 "general_operand" "=a")
5670         (match_operand:QI 1 "address_operand" "p"))]
5671   ""
5672   "*
5673 {
5674 #ifndef SGS_NO_LI
5675   /* Recognize an insn that refers to a table of offsets.  Such an insn will
5676      need to refer to a label on the insn.  So output one.  Use the
5677      label-number of the table of offsets to generate this label.  This code,
5678      and similar code above, assumes that there will be at most one reference
5679      to each table.  */
5680   if (GET_CODE (operands[1]) == PLUS
5681       && GET_CODE (XEXP (operands[1], 1)) == LABEL_REF
5682       && GET_CODE (XEXP (operands[1], 0)) != PLUS)
5683     {
5684       rtx labelref = XEXP (operands[1], 1);
5685 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
5686 #ifdef SGS
5687       asm_fprintf (asm_out_file, \"\\tset %LLI%d,.+2\\n\",
5688                    CODE_LABEL_NUMBER (XEXP (labelref, 0)));
5689 #else /* not SGS */
5690       asm_fprintf (asm_out_file, \"\\t.set %LLI%d,.+2\\n\",
5691                    CODE_LABEL_NUMBER (XEXP (labelref, 0)));
5692 #endif /* not SGS */
5693 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
5694       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\",
5695                                  CODE_LABEL_NUMBER (XEXP (labelref, 0)));
5696 #ifdef SGS_SWITCH_TABLES
5697       /* Set flag saying we need to define the symbol
5698          LD%n (with value L%n-LI%n) at the end of the switch table.  */
5699       switch_table_difference_label_flag = 1;
5700 #endif /* SGS_SWITCH_TABLES */
5701 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
5702     }
5703 #endif /* SGS_NO_LI */
5704
5705   return \"lea %a1,%0\";
5706 }")
5707 \f
5708 ;; This is the first machine-dependent peephole optimization.
5709 ;; It is useful when a floating value is returned from a function call
5710 ;; and then is moved into an FP register.
5711 ;; But it is mainly intended to test the support for these optimizations.
5712
5713 (define_peephole
5714   [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
5715    (set (match_operand:DF 0 "register_operand" "=f")
5716         (match_operand:DF 1 "register_operand" "ad"))]
5717   "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5718   "*
5719 {
5720   rtx xoperands[2];
5721   xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
5722   output_asm_insn (\"move%.l %1,%@\", xoperands);
5723   output_asm_insn (\"move%.l %1,%-\", operands);
5724   return \"fmove%.d %+,%0\";
5725 }
5726 ")
5727
5728 ;; Optimize a stack-adjust followed by a push of an argument.
5729 ;; This is said to happen frequently with -msoft-float
5730 ;; when there are consecutive library calls.
5731
5732 (define_peephole
5733   [(set (reg:SI 15) (plus:SI (reg:SI 15)
5734                              (match_operand:SI 0 "const_int_operand" "n")))
5735    (set (match_operand:SF 1 "push_operand" "=m")
5736         (match_operand:SF 2 "general_operand" "rmfF"))]
5737   "INTVAL (operands[0]) >= 4
5738    && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
5739   "*
5740 {
5741   if (INTVAL (operands[0]) > 4)
5742     {
5743       rtx xoperands[2];
5744       xoperands[0] = stack_pointer_rtx;
5745       xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4);
5746 #ifndef NO_ADDSUB_Q
5747       if (INTVAL (xoperands[1]) <= 8)
5748         output_asm_insn (\"addq%.w %1,%0\", xoperands);
5749       else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
5750         {
5751           xoperands[1] = gen_rtx (CONST_INT, VOIDmode, 
5752                                   INTVAL (xoperands[1]) - 8);
5753           output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
5754         }
5755       else
5756 #endif
5757         if (INTVAL (xoperands[1]) <= 0x7FFF)
5758           output_asm_insn (\"add%.w %1,%0\", xoperands);
5759       else
5760         output_asm_insn (\"add%.l %1,%0\", xoperands);
5761     }
5762   if (FP_REG_P (operands[2]))
5763     return \"fmove%.s %2,%@\";
5764   return \"move%.l %2,%@\";
5765 }")
5766
5767 ;; Speed up stack adjust followed by a fullword fixedpoint push.
5768
5769 (define_peephole
5770   [(set (reg:SI 15) (plus:SI (reg:SI 15)
5771                              (match_operand:SI 0 "const_int_operand" "n")))
5772    (set (match_operand:SI 1 "push_operand" "=m")
5773         (match_operand:SI 2 "general_operand" "g"))]
5774   "INTVAL (operands[0]) >= 4
5775    && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
5776   "*
5777 {
5778   if (INTVAL (operands[0]) > 4)
5779     {
5780       rtx xoperands[2];
5781       xoperands[0] = stack_pointer_rtx;
5782       xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4);
5783 #ifndef NO_ADDSUB_Q
5784       if (INTVAL (xoperands[1]) <= 8)
5785         output_asm_insn (\"addq%.w %1,%0\", xoperands);
5786       else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
5787         {
5788           xoperands[1] = gen_rtx (CONST_INT, VOIDmode, 
5789                                   INTVAL (xoperands[1]) - 8);
5790           output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
5791         }
5792       else
5793 #endif
5794         if (INTVAL (xoperands[1]) <= 0x7FFF)
5795           output_asm_insn (\"add%.w %1,%0\", xoperands);
5796       else
5797         output_asm_insn (\"add%.l %1,%0\", xoperands);
5798     }
5799   if (operands[2] == const0_rtx)
5800     return \"clr%.l %@\";
5801   return \"move%.l %2,%@\";
5802 }")
5803
5804 ;; Speed up pushing a single byte but leaving four bytes of space.
5805
5806 (define_peephole
5807   [(set (mem:QI (pre_dec:SI (reg:SI 15)))
5808         (match_operand:QI 1 "general_operand" "dami"))
5809    (set (reg:SI 15) (minus:SI (reg:SI 15) (const_int 2)))]
5810   "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
5811   "*
5812 {
5813   rtx xoperands[4];
5814
5815   if (GET_CODE (operands[1]) == REG)
5816     return \"move%.l %1,%-\";
5817
5818   xoperands[1] = operands[1];
5819   xoperands[2]
5820     = gen_rtx (MEM, QImode,
5821                gen_rtx (PLUS, VOIDmode, stack_pointer_rtx,
5822                         gen_rtx (CONST_INT, VOIDmode, 3)));
5823   xoperands[3] = stack_pointer_rtx;
5824   output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands);
5825   return \"\";
5826 }")
5827
5828 (define_peephole
5829   [(set (match_operand:SI 0 "register_operand" "=d")
5830         (const_int 0))
5831    (set (strict_low_part (subreg:HI (match_dup 0) 0))
5832         (match_operand:HI 1 "general_operand" "rmn"))]
5833   "strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0])"
5834   "*
5835 {
5836   if (GET_CODE (operands[1]) == CONST_INT)
5837     {
5838       if (operands[1] == const0_rtx
5839           && (DATA_REG_P (operands[0])
5840               || GET_CODE (operands[0]) == MEM)
5841           /* clr insns on 68000 read before writing.
5842              This isn't so on the 68010, but we have no alternative for it.  */
5843           && (TARGET_68020
5844               || !(GET_CODE (operands[0]) == MEM
5845                    && MEM_VOLATILE_P (operands[0]))))
5846         return \"clr%.w %0\";
5847     }
5848   return \"move%.w %1,%0\";
5849 }")
5850
5851 ;; dbCC peepholes
5852 ;;
5853 ;; Turns
5854 ;;   loop:
5855 ;;           [ ... ]
5856 ;;           jCC label          ; abnormal loop termination
5857 ;;           dbra dN, loop      ; normal loop termination
5858 ;;
5859 ;; Into
5860 ;;   loop:
5861 ;;           [ ... ]
5862 ;;           dbCC dN, loop
5863 ;;           jCC label
5864 ;;
5865 ;; Which moves the jCC condition outside the inner loop for free.
5866 ;;
5867 (define_peephole
5868   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
5869                              [(cc0) (const_int 0)])
5870                            (label_ref (match_operand 2 "" ""))
5871                            (pc)))
5872    (parallel
5873     [(set (pc)
5874           (if_then_else
5875             (ge (plus:HI (match_operand:HI 0 "register_operand" "+d")
5876                          (const_int -1))
5877                 (const_int 0))
5878             (label_ref (match_operand 1 "" ""))
5879             (pc)))
5880      (set (match_dup 0)
5881           (plus:HI (match_dup 0)
5882                    (const_int -1)))])]
5883   "DATA_REG_P (operands[0])"
5884   "*
5885 {
5886   CC_STATUS_INIT;
5887   output_dbcc_and_branch (operands);
5888   return \"\";
5889 }")
5890
5891 (define_peephole
5892   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
5893                              [(cc0) (const_int 0)])
5894                            (label_ref (match_operand 2 "" ""))
5895                            (pc)))
5896    (parallel
5897     [(set (pc)
5898           (if_then_else
5899             (ge (plus:SI (match_operand:SI 0 "register_operand" "+d")
5900                          (const_int -1))
5901                 (const_int 0))
5902             (label_ref (match_operand 1 "" ""))
5903             (pc)))
5904      (set (match_dup 0)
5905           (plus:SI (match_dup 0)
5906                    (const_int -1)))])]
5907   "DATA_REG_P (operands[0])"
5908   "*
5909 {
5910   CC_STATUS_INIT;
5911   output_dbcc_and_branch (operands);
5912   return \"\";
5913 }")
5914
5915 \f
5916 ;; FPA multiply and add.
5917 (define_insn ""
5918   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
5919         (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y")
5920                           (match_operand:DF 2 "general_operand" "xH,y,y"))
5921                  (match_operand:DF 3 "general_operand" "xH,y,dmF")))]
5922    "TARGET_FPA"
5923    "@
5924     fpma%.d %1,%w2,%w3,%0
5925     fpma%.d %x1,%x2,%x3,%0
5926     fpma%.d %x1,%x2,%x3,%0")
5927
5928 (define_insn ""
5929   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
5930         (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y")
5931                           (match_operand:SF 2 "general_operand" "xH,y,ydmF"))
5932                  (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))]
5933    "TARGET_FPA"
5934    "@
5935     fpma%.s %1,%w2,%w3,%0
5936     fpma%.s %1,%2,%3,%0
5937     fpma%.s %1,%2,%3,%0")
5938
5939 ;; FPA Multiply and subtract
5940 (define_insn ""
5941   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
5942         (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
5943                   (mult:DF (match_operand:DF 2 "general_operand" "%xH,y,y")
5944                            (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
5945   "TARGET_FPA"
5946   "@
5947    fpms%.d %3,%w2,%w1,%0
5948    fpms%.d %x3,%2,%x1,%0
5949    fpms%.d %x3,%2,%x1,%0")
5950
5951 (define_insn ""
5952   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
5953         (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
5954                   (mult:SF (match_operand:SF 2 "general_operand" "%xH,rmF,y")
5955                            (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
5956   "TARGET_FPA"
5957   "@
5958    fpms%.s %3,%w2,%w1,%0
5959    fpms%.s %3,%2,%1,%0
5960    fpms%.s %3,%2,%1,%0")
5961
5962 (define_insn ""
5963   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
5964         (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%xH,y,y")
5965                            (match_operand:DF 2 "general_operand" "x,y,rmF"))
5966                   (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
5967   "TARGET_FPA"
5968   "@
5969    fpmr%.d %2,%w1,%w3,%0
5970    fpmr%.d %x2,%1,%x3,%0
5971    fpmr%.d %x2,%1,%x3,%0")
5972
5973 (define_insn ""
5974   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
5975         (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y")
5976                            (match_operand:SF 2 "general_operand" "x,y,yrmF"))
5977                   (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
5978   "TARGET_FPA"
5979   "@
5980    fpmr%.s %2,%w1,%w3,%0
5981    fpmr%.s %x2,%1,%x3,%0
5982    fpmr%.s %x2,%1,%x3,%0")
5983
5984 ;; FPA Add and multiply
5985 (define_insn ""
5986   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
5987         (mult:DF (plus:DF (match_operand:DF 1 "general_operand" "%xH,y,y")
5988                           (match_operand:DF 2 "general_operand" "x,y,rmF"))
5989                  (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
5990   "TARGET_FPA"
5991   "@
5992    fpam%.d %2,%w1,%w3,%0
5993    fpam%.d %x2,%1,%x3,%0
5994    fpam%.d %x2,%1,%x3,%0")
5995
5996 (define_insn ""
5997   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
5998         (mult:SF (plus:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y")
5999                           (match_operand:SF 2 "general_operand" "x,y,yrmF"))
6000                  (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
6001   "TARGET_FPA"
6002   "@
6003    fpam%.s %2,%w1,%w3,%0
6004    fpam%.s %x2,%1,%x3,%0
6005    fpam%.s %x2,%1,%x3,%0")
6006
6007 ;;FPA Subtract and multiply
6008 (define_insn ""
6009   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
6010         (mult:DF (minus:DF (match_operand:DF 1 "general_operand" "xH,y,y")
6011                            (match_operand:DF 2 "general_operand" "x,y,rmF"))
6012                  (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
6013   "TARGET_FPA"
6014   "@
6015    fpsm%.d %2,%w1,%w3,%0
6016    fpsm%.d %x2,%1,%x3,%0
6017    fpsm%.d %x2,%1,%x3,%0")
6018
6019 (define_insn ""
6020   [(set (match_operand:DF 0 "register_operand" "=x,y,y")
6021         (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
6022                  (minus:DF (match_operand:DF 2 "general_operand" "xH,y,y")
6023                            (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
6024   "TARGET_FPA"
6025   "@
6026    fpsm%.d %3,%w2,%w1,%0
6027    fpsm%.d %x3,%2,%x1,%0
6028    fpsm%.d %x3,%2,%x1,%0")
6029
6030 (define_insn ""
6031   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
6032         (mult:SF (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,y")
6033                            (match_operand:SF 2 "general_operand" "x,y,yrmF"))
6034                  (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
6035   "TARGET_FPA"
6036   "@
6037    fpsm%.s %2,%w1,%w3,%0
6038    fpsm%.s %x2,%1,%x3,%0
6039    fpsm%.s %x2,%1,%x3,%0")
6040
6041 (define_insn ""
6042   [(set (match_operand:SF 0 "register_operand" "=x,y,y")
6043         (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
6044                  (minus:SF (match_operand:SF 2 "general_operand" "xH,rmF,y")
6045                            (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
6046   "TARGET_FPA"
6047   "@
6048    fpsm%.s %3,%w2,%w1,%0
6049    fpsm%.s %x3,%2,%x1,%0
6050    fpsm%.s %x3,%2,%x1,%0")
6051
6052 (define_insn "tstxf"
6053   [(set (cc0)
6054         (match_operand:XF 0 "nonimmediate_operand" "fm"))]
6055   "TARGET_68881"
6056   "*
6057 {
6058   cc_status.flags = CC_IN_68881;
6059   return \"ftst%.x %0\";
6060 }")
6061
6062
6063 (define_expand "cmpxf"
6064   [(set (cc0)
6065         (compare (match_operand:XF 0 "general_operand" "f,mG")
6066                  (match_operand:XF 1 "general_operand" "fmG,f")))]
6067   "TARGET_68881"
6068   "
6069 {
6070   if (CONSTANT_P (operands[0]))
6071       operands[0] = force_const_mem (XFmode, operands[0]);
6072   if (CONSTANT_P (operands[1]))
6073       operands[1] = force_const_mem (XFmode, operands[1]);
6074 }")
6075
6076 (define_insn ""
6077   [(set (cc0)
6078         (compare (match_operand:XF 0 "nonimmediate_operand" "f,mG")
6079                  (match_operand:XF 1 "nonimmediate_operand" "fmG,f")))]
6080   "TARGET_68881"
6081   "*
6082 {
6083   cc_status.flags = CC_IN_68881;
6084 #ifdef SGS_CMP_ORDER
6085   if (REG_P (operands[0]))
6086     {
6087       if (REG_P (operands[1]))
6088         return \"fcmp%.x %0,%1\";
6089       else
6090         return \"fcmp%.x %0,%f1\";
6091     }
6092   cc_status.flags |= CC_REVERSED;
6093   return \"fcmp%.x %1,%f0\";
6094 #else
6095   if (REG_P (operands[0]))
6096     {
6097       if (REG_P (operands[1]))
6098         return \"fcmp%.x %1,%0\";
6099       else
6100         return \"fcmp%.x %f1,%0\";
6101     }
6102   cc_status.flags |= CC_REVERSED;
6103   return \"fcmp%.x %f0,%1\";
6104 #endif
6105 }")
6106
6107 (define_insn "extendsfxf2"
6108   [(set (match_operand:XF 0 "general_operand" "=fm,f")
6109         (float_extend:XF (match_operand:SF 1 "general_operand" "f,m")))]
6110   "TARGET_68881"
6111   "*
6112 {
6113   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
6114     {
6115       if (REGNO (operands[0]) == REGNO (operands[1]))
6116         {
6117           /* Extending float to double in an fp-reg is a no-op.
6118              NOTICE_UPDATE_CC has already assumed that the
6119              cc will be set.  So cancel what it did.  */
6120           cc_status = cc_prev_status;
6121           return \"\";
6122         }
6123       return \"f%$move%.x %1,%0\";
6124     }
6125   if (FP_REG_P (operands[0]))
6126     return \"f%$move%.s %f1,%0\";
6127   return \"fmove%.x %f1,%0\";
6128 }")
6129
6130
6131 (define_insn "extenddfxf2"
6132   [(set (match_operand:XF 0 "general_operand" "=fm,f")
6133         (float_extend:XF
6134           (match_operand:DF 1 "general_operand" "f,m")))]
6135   "TARGET_68881"
6136   "*
6137 {
6138   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
6139     {
6140       if (REGNO (operands[0]) == REGNO (operands[1]))
6141         {
6142           /* Extending float to double in an fp-reg is a no-op.
6143              NOTICE_UPDATE_CC has already assumed that the
6144              cc will be set.  So cancel what it did.  */
6145           cc_status = cc_prev_status;
6146           return \"\";
6147         }
6148       return \"fmove%.x %1,%0\";
6149     }
6150   if (FP_REG_P (operands[0]))
6151     return \"f%&move%.d %f1,%0\";
6152   return \"fmove%.x %f1,%0\";
6153 }")
6154
6155 (define_insn "truncxfdf2"
6156   [(set (match_operand:DF 0 "general_operand" "=m,!r")
6157         (float_truncate:DF
6158           (match_operand:XF 1 "general_operand" "f,f")))]
6159   "TARGET_68881"
6160   "*
6161 {
6162   if (REG_P (operands[0]))
6163     {
6164       output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
6165       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
6166       return \"move%.l %+,%0\";
6167     }
6168   return \"fmove%.d %f1,%0\";
6169 }")
6170  
6171 (define_insn "truncxfsf2"
6172   [(set (match_operand:SF 0 "general_operand" "=dm")
6173         (float_truncate:SF
6174           (match_operand:XF 1 "general_operand" "f")))]
6175   "TARGET_68881"
6176   "fmove%.s %f1,%0")
6177
6178 (define_insn "floatsixf2"
6179   [(set (match_operand:XF 0 "general_operand" "=f")
6180         (float:XF (match_operand:SI 1 "general_operand" "dmi")))]
6181   "TARGET_68881"
6182   "fmove%.l %1,%0")
6183
6184 (define_insn "floathixf2"
6185   [(set (match_operand:XF 0 "general_operand" "=f")
6186         (float:XF (match_operand:HI 1 "general_operand" "dmn")))]
6187   "TARGET_68881"
6188   "fmove%.w %1,%0")
6189
6190 (define_insn "floatqixf2"
6191   [(set (match_operand:XF 0 "general_operand" "=f")
6192         (float:XF (match_operand:QI 1 "general_operand" "dmn")))]
6193   "TARGET_68881"
6194   "fmove%.b %1,%0")
6195
6196 (define_insn "ftruncxf2"
6197   [(set (match_operand:XF 0 "general_operand" "=f")
6198         (fix:XF (match_operand:XF 1 "general_operand" "fFm")))]
6199   "TARGET_68881"
6200   "*
6201 {
6202   if (FP_REG_P (operands[1]))
6203     return \"fintrz%.x %f1,%0\";
6204   return \"fintrz%.x %f1,%0\";
6205 }")
6206
6207 (define_insn "fixxfqi2"
6208   [(set (match_operand:QI 0 "general_operand" "=dm")
6209         (fix:QI (match_operand:XF 1 "general_operand" "f")))]
6210   "TARGET_68881"
6211   "fmove%.b %1,%0")
6212
6213 (define_insn "fixxfhi2"
6214   [(set (match_operand:HI 0 "general_operand" "=dm")
6215         (fix:HI (match_operand:XF 1 "general_operand" "f")))]
6216   "TARGET_68881"
6217   "fmove%.w %1,%0")
6218
6219 (define_insn "fixxfsi2"
6220   [(set (match_operand:SI 0 "general_operand" "=dm")
6221         (fix:SI (match_operand:XF 1 "general_operand" "f")))]
6222   "TARGET_68881"
6223   "fmove%.l %1,%0")
6224
6225 (define_expand "addxf3"
6226   [(set (match_operand:XF 0 "general_operand" "")
6227         (plus:XF (match_operand:XF 1 "general_operand" "")
6228                  (match_operand:XF 2 "general_operand" "")))]
6229   "TARGET_68881"
6230   "
6231 {
6232   if (CONSTANT_P (operands[1]))
6233     operands[1] = force_const_mem (XFmode, operands[1]);
6234   if (CONSTANT_P (operands[2]))
6235     operands[2] = force_const_mem (XFmode, operands[2]);
6236 }")
6237
6238 (define_insn ""
6239   [(set (match_operand:XF 0 "general_operand" "=f")
6240         (plus:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
6241                  (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
6242   "TARGET_68881"
6243   "*
6244 {
6245   if (REG_P (operands[2]))
6246     return \"fadd%.x %2,%0\";
6247   return \"fadd%.x %f2,%0\";
6248 }")
6249
6250 (define_expand "subxf3"
6251   [(set (match_operand:XF 0 "general_operand" "")
6252         (minus:XF (match_operand:XF 1 "general_operand" "")
6253                  (match_operand:XF 2 "general_operand" "")))]
6254   "TARGET_68881"
6255   "
6256 {
6257   if (CONSTANT_P (operands[1]))
6258     operands[1] = force_const_mem (XFmode, operands[1]);
6259   if (CONSTANT_P (operands[2]))
6260     operands[2] = force_const_mem (XFmode, operands[2]);
6261 }")
6262
6263 (define_insn ""
6264   [(set (match_operand:XF 0 "general_operand" "=f")
6265         (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
6266                  (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
6267   "TARGET_68881"
6268   "*
6269 {
6270   if (REG_P (operands[2]))
6271     return \"fsub%.x %2,%0\";
6272   return \"fsub%.x %f2,%0\";
6273 }")
6274
6275 (define_expand "mulxf3"
6276   [(set (match_operand:XF 0 "general_operand" "")
6277         (mult:XF (match_operand:XF 1 "general_operand" "")
6278                 (match_operand:XF 2 "general_operand" "")))]
6279   "TARGET_68881"
6280   "
6281 {
6282   if (CONSTANT_P (operands[1]))
6283     operands[1] = force_const_mem (XFmode, operands[1]);
6284   if (CONSTANT_P (operands[2]))
6285     operands[2] = force_const_mem (XFmode, operands[2]);
6286 }")
6287
6288 (define_insn ""
6289   [(set (match_operand:XF 0 "general_operand" "=f")
6290         (mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
6291                 (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
6292   "TARGET_68881"
6293   "*
6294 {
6295   if (REG_P (operands[2]))
6296     return \"fmul%.x %2,%0\";
6297   return \"fmul%.x %f2,%0\";
6298 }")
6299
6300 (define_expand "divxf3"
6301   [(set (match_operand:XF 0 "general_operand" "")
6302         (div:XF (match_operand:XF 1 "general_operand" "")
6303                 (match_operand:XF 2 "general_operand" "")))]
6304   "TARGET_68881"
6305   "
6306 {
6307   if (CONSTANT_P (operands[1]))
6308     operands[1] = force_const_mem (XFmode, operands[1]);
6309   if (CONSTANT_P (operands[2]))
6310     operands[2] = force_const_mem (XFmode, operands[2]);
6311 }")
6312
6313 (define_insn ""
6314   [(set (match_operand:XF 0 "general_operand" "=f")
6315         (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
6316                 (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
6317   "TARGET_68881"
6318   "*
6319 {
6320   if (REG_P (operands[2]))
6321     return \"fdiv%.x %2,%0\";
6322   return \"fdiv%.x %f2,%0\";
6323 }")
6324
6325 (define_expand "negxf2"
6326   [(set (match_operand:XF 0 "general_operand" "")
6327         (neg:XF (match_operand:XF 1 "general_operand" "")))]
6328   ""
6329   "
6330 {
6331   /* ??? There isn't an FPA define_insn so we could handle it here too.
6332      For now we don't (paranoia).  */
6333   if (!TARGET_FPA && !TARGET_68881)
6334     {
6335       rtx result;
6336       rtx target;
6337       rtx insns;
6338
6339       start_sequence ();
6340       target = operand_subword (operands[0], 0, 1, XFmode);
6341       result = expand_binop (SImode, xor_optab,
6342                              operand_subword_force (operands[1], 0, XFmode),
6343                              GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
6344       if (result == 0)
6345         abort ();
6346
6347       if (result != target)
6348         emit_move_insn (result, target);
6349   
6350       emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
6351                       operand_subword_force (operands[1], 1, XFmode));
6352       emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
6353                       operand_subword_force (operands[1], 2, XFmode));
6354
6355       insns = get_insns ();
6356       end_sequence ();
6357
6358       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
6359       DONE;
6360     }
6361 }")
6362
6363 (define_insn "negxf2_68881"
6364   [(set (match_operand:XF 0 "general_operand" "=f")
6365         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))]
6366   "TARGET_68881"
6367   "*
6368 {
6369   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
6370     return \"fneg%.x %1,%0\";
6371   return \"fneg%.x %f1,%0\";
6372 }")
6373
6374 (define_expand "absxf2"
6375   [(set (match_operand:XF 0 "general_operand" "")
6376         (abs:XF (match_operand:XF 1 "general_operand" "")))]
6377   ""
6378   "
6379 {
6380   /* ??? There isn't an FPA define_insn so we could handle it here too.
6381      For now we don't (paranoia).  */
6382   if (!TARGET_FPA && !TARGET_68881)
6383     {
6384       rtx result;
6385       rtx target;
6386       rtx insns;
6387
6388       start_sequence ();
6389       target = operand_subword (operands[0], 0, 1, XFmode);
6390       result = expand_binop (SImode, and_optab,
6391                              operand_subword_force (operands[1], 0, XFmode),
6392                              GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
6393       if (result == 0)
6394         abort ();
6395
6396       if (result != target)
6397         emit_move_insn (result, target);
6398   
6399       emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
6400                       operand_subword_force (operands[1], 1, XFmode));
6401       emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
6402                       operand_subword_force (operands[1], 2, XFmode));
6403
6404       insns = get_insns ();
6405       end_sequence ();
6406
6407       emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
6408       DONE;
6409     }
6410 }")
6411
6412 (define_insn "absxf2_68881"
6413   [(set (match_operand:XF 0 "general_operand" "=f")
6414         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))]
6415   "TARGET_68881"
6416   "*
6417 {
6418   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
6419     return \"fabs%.x %1,%0\";
6420   return \"fabs%.x %f1,%0\";
6421 }")
6422
6423 (define_insn "sqrtxf2"
6424   [(set (match_operand:XF 0 "general_operand" "=f")
6425         (sqrt:XF (match_operand:XF 1 "nonimmediate_operand" "fm")))]
6426   "TARGET_68881"
6427   "*
6428 {
6429     return \"fsqrt%.x %1,%0\";
6430 }")
6431
6432 (define_insn "sinsf2"
6433   [(set (match_operand:SF 0 "general_operand" "=f")
6434         (unspec:SF [(match_operand:SF 1 "general_operand" "fm")] 1))]
6435   "TARGET_68881 && flag_fast_math"
6436   "*
6437 {
6438   if (FP_REG_P (operands[1]))
6439     return \"fsin%.x %1,%0\";
6440   else
6441     return \"fsin%.s %1,%0\";
6442 }")
6443
6444 (define_insn "sindf2"
6445   [(set (match_operand:DF 0 "general_operand" "=f")
6446         (unspec:DF [(match_operand:DF 1 "general_operand" "fm")] 1))]
6447   "TARGET_68881 && flag_fast_math"
6448   "*
6449 {
6450   if (FP_REG_P (operands[1]))
6451     return \"fsin%.x %1,%0\";
6452   else
6453     return \"fsin%.d %1,%0\";
6454 }")
6455
6456 (define_insn "sinxf2"
6457   [(set (match_operand:XF 0 "general_operand" "=f")
6458         (unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 1))]
6459   "TARGET_68881 && flag_fast_math"
6460   "*
6461 {
6462     return \"fsin%.x %1,%0\";
6463 }")
6464
6465 (define_insn "cossf2"
6466   [(set (match_operand:SF 0 "general_operand" "=f")
6467         (unspec:SF [(match_operand:SF 1 "general_operand" "fm")] 2))]
6468   "TARGET_68881 && flag_fast_math"
6469   "*
6470 {
6471   if (FP_REG_P (operands[1]))
6472     return \"fcos%.x %1,%0\";
6473   else
6474     return \"fcos%.s %1,%0\";
6475 }")
6476
6477 (define_insn "cosdf2"
6478   [(set (match_operand:DF 0 "general_operand" "=f")
6479         (unspec:DF [(match_operand:DF 1 "general_operand" "fm")] 2))]
6480   "TARGET_68881 && flag_fast_math"
6481   "*
6482 {
6483   if (FP_REG_P (operands[1]))
6484     return \"fcos%.x %1,%0\";
6485   else
6486     return \"fcos%.d %1,%0\";
6487 }")
6488
6489 (define_insn "cosxf2"
6490   [(set (match_operand:XF 0 "general_operand" "=f")
6491         (unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 2))]
6492   "TARGET_68881 && flag_fast_math"
6493   "*
6494 {
6495     return \"fcos%.x %1,%0\";
6496 }")