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