comparison gcc/config/m68k/m68k.md @ 0:a06113de4d67

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