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