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