OSDN Git Service

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