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