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