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