OSDN Git Service

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