OSDN Git Service

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