]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/m68k/m68k.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / m68k / m68k.md
CommitLineData
996a5f59 1;;- Machine description for GNU compiler, Motorola 68000 Version
a945c346 2;; Copyright (C) 1987-2024 Free Software Foundation, Inc.
e0c17b2d 3
7ec022b2 4;; This file is part of GCC.
e0c17b2d 5
7ec022b2 6;; GCC is free software; you can redistribute it and/or modify
e0c17b2d 7;; it under the terms of the GNU General Public License as published by
2f83c7d6 8;; the Free Software Foundation; either version 3, or (at your option)
e0c17b2d
RS
9;; any later version.
10
7ec022b2 11;; GCC is distributed in the hope that it will be useful,
e0c17b2d
RS
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
2f83c7d6
NC
17;; along with GCC; see the file COPYING3. If not see
18;; <http://www.gnu.org/licenses/>.
e0c17b2d 19
15338c41
RK
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
9425fb04 25;;- divide instructions. The TARGET_COLDFIRE flag turns the use of the
15338c41
RK
26;;- removed opcodes and addressing modes off.
27;;-
28
e0c17b2d
RS
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.
dcc21c4c 46;;- 'f' one of the m68881/fpu registers can be used
e0c17b2d 47;;- 'r' either a data or an address register can be used.
e0c17b2d
RS
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).
e0c17b2d
RS
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
7b7e5637 62;;- 'M' all integers EXCEPT -256 .. 255
e62db39c
RK
63;;- 'N' 24 .. 31
64;;- 'O' 16
65;;- 'P' 8 .. 15
e0c17b2d
RS
66
67;;- Assembler specs:
68;;- "%." size separator ("." or "") move%.l d0,d1
e0c17b2d
RS
69;;- "%-" push operand "sp@-" move%.l d0,%-
70;;- "%+" pop operand "sp@+" move%.l d0,%+
71;;- "%@" top of stack "sp@" move%.l d0,%@
7c129456 72;;- "%!" fpcr register
e0c17b2d
RS
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
fe95f2f7 82;;- TUNE_68040 flag turns the use of the opcodes off.
e0c17b2d
RS
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
59fbf3cb 90;;- switch.
e0c17b2d
RS
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
dc086e21
RK
96;;- Information about 68060 port.
97
98;;- The 68060 executes all 68030 and 68881/2 instructions, but some must
935fb288
RK
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
dc086e21 101;;- the kernel. The affected instructions are: divs.l <ea>,Dr:Dq;
4ea62d1a 102;;- divu.l <ea>,Dr:Dq; muls.l <ea>,Dr:Dq; mulu.l <ea>,Dr:Dq; and
fe95f2f7 103;;- fscale. The TUNE_68060 flag turns the use of the opcodes off.
dc086e21 104
e0c17b2d
RS
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.
d1b3178b
AS
108
109;; UNSPEC usage:
110
111(define_constants
a40ed0f3
KH
112 [(UNSPEC_SIN 1)
113 (UNSPEC_COS 2)
114 (UNSPEC_GOT 3)
c47b0cb4 115 (UNSPEC_IB 4)
96fcacb7 116 (UNSPEC_TIE 5)
75df395f
MK
117 (UNSPEC_RELOC16 6)
118 (UNSPEC_RELOC32 7)
d1b3178b
AS
119 ])
120
121;; UNSPEC_VOLATILE usage:
122
123(define_constants
124 [(UNSPECV_BLOCKAGE 0)
7b45b59b
RH
125 (UNSPECV_CAS_1 1)
126 (UNSPECV_CAS_2 2)
127 (UNSPECV_TAS_1 3)
128 (UNSPECV_TAS_2 4)
d1b3178b 129 ])
428511bb
RZ
130
131;; Registers by name.
132(define_constants
576c9028
KH
133 [(D0_REG 0)
134 (A0_REG 8)
a40ed0f3
KH
135 (A1_REG 9)
136 (PIC_REG 13)
de41203b 137 (A6_REG 14)
428511bb 138 (SP_REG 15)
a40ed0f3 139 (FP0_REG 16)
428511bb 140 ])
41b6a5e2
KH
141
142(include "predicates.md")
b38bab94 143(include "constraints.md")
e0c17b2d 144\f
c47b0cb4
MK
145;; ::::::::::::::::::::
146;; ::
147;; :: Attributes
148;; ::
149;; ::::::::::::::::::::
150
151;; Processor type.
96fcacb7 152(define_attr "cpu" "cfv1, cfv2, cfv3, cfv4, unknown"
826fadba
MK
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")))
c47b0cb4 158
c47b0cb4
MK
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.
c47b0cb4
MK
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.
96fcacb7
MK
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,
c47b0cb4 187 unknown"
96fcacb7 188 (const_string "unknown"))
c47b0cb4
MK
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
c47b0cb4 195;; Type of the Y operand.
e53b6e56 196;; See m68k.cc: enum attr_op_type.
c47b0cb4 197(define_attr "opy_type"
96fcacb7
MK
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")
c47b0cb4
MK
203 (symbol_ref "m68k_sched_attr_opy_type (insn, 1)")]
204 (symbol_ref "m68k_sched_attr_opy_type (insn, 0)")))
205
96fcacb7 206;; Type of the X operand.
e53b6e56 207;; See m68k.cc: enum attr_op_type.
96fcacb7
MK
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)")))
c47b0cb4
MK
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.
96fcacb7
MK
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)")))
c47b0cb4
MK
233
234;; Memory accesses of the insn.
235;; 00 - no memory references
236;; 10 - memory is read
96fcacb7 237;; i0 - indexed memory is read
c47b0cb4 238;; 01 - memory is written
96fcacb7 239;; 0i - indexed memory is written
c47b0cb4 240;; 11 - memory is read, memory is written
96fcacb7
MK
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"
c47b0cb4
MK
244 (symbol_ref "m68k_sched_attr_op_mem (insn)"))
245
96fcacb7
MK
246;; Instruction size in words.
247(define_attr "size" "1,2,3"
248 (symbol_ref "m68k_sched_attr_size (insn)"))
249
5ad2f1a5
MK
250;; Alternative is OK for ColdFire.
251(define_attr "ok_for_coldfire" "yes,no" (const_string "yes"))
252
6cebc6cb
BS
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
5ad2f1a5
MK
265;; Define 'enabled' attribute.
266(define_attr "enabled" ""
c5c68094 267 (cond [(and (match_test "TARGET_COLDFIRE")
5ad2f1a5
MK
268 (eq_attr "ok_for_coldfire" "no"))
269 (const_int 0)]
270 (const_int 1)))
c47b0cb4 271\f
7b45b59b
RH
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
dcc21c4c
PB
276;; Mode macros for floating point operations.
277;; Valid floating point modes
3abcb3a7 278(define_mode_iterator FP [SF DF (XF "TARGET_68881")])
dcc21c4c
PB
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 "")])
c0220ea4 283;; Suffix specifying source operand format
dcc21c4c
PB
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
c47b0cb4
MK
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"))]
e0c17b2d 294 ""
c47b0cb4
MK
295 "@
296 fmove%.d %f1,%0
297 #"
298 "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 1)"
299 [(const_int 0)]
e0c17b2d 300{
c47b0cb4
MK
301 m68k_emit_move_double (operands);
302 DONE;
303}
96fcacb7 304 [(set_attr "type" "fmove,*")])
e0c17b2d 305
c47b0cb4 306(define_insn_and_split "pushdi"
e0c17b2d 307 [(set (match_operand:DI 0 "push_operand" "=m")
d6fb69e7 308 (match_operand:DI 1 "general_operand" "ro<>Fi"))]
e0c17b2d 309 ""
c47b0cb4
MK
310 "#"
311 "&& reload_completed"
312 [(const_int 0)]
e0c17b2d 313{
c47b0cb4
MK
314 m68k_emit_move_double (operands);
315 DONE;
c223cf45 316})
e0c17b2d 317\f
6cebc6cb
BS
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"))]
31e033e9 327 ""
31e033e9 328{
6cebc6cb
BS
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]))
935fb288 339 {
6cebc6cb
BS
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";
935fb288 348 }
6cebc6cb
BS
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);
935fb288 352 else
6cebc6cb
BS
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})
e0c17b2d 358
6cebc6cb
BS
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"))]
31e033e9 366 ""
31e033e9 367{
6cebc6cb
BS
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);
31e033e9 373 else
6cebc6cb
BS
374 operands[3] = adjust_address (operands[0], SImode, 4);
375 if (!ADDRESS_REG_P (operands[0]))
a1efcf3c 376 {
6cebc6cb
BS
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";
a1efcf3c 385 }
6cebc6cb
BS
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";
c223cf45 390})
31e033e9 391
6cebc6cb
BS
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"))]
f90b7a5a 401 ""
6cebc6cb
BS
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})
f90b7a5a
PB
408
409(define_expand "cbranchdi4"
6cebc6cb
BS
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 ""))])]
f723f6ef 419 ""
f723f6ef 420{
6cebc6cb
BS
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 }
f90b7a5a
PB
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{
6cebc6cb
BS
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 }
428511bb 460})
f723f6ef 461
6cebc6cb 462(define_mode_iterator CMPMODE [QI HI SI])
f90b7a5a 463
6cebc6cb
BS
464(define_expand "cbranch<mode>4"
465 [(set (pc)
f90b7a5a 466 (if_then_else (match_operator 0 "ordered_comparison_operator"
6cebc6cb
BS
467 [(match_operand:CMPMODE 1 "nonimmediate_operand" "")
468 (match_operand:CMPMODE 2 "m68k_comparison_operand" "")])
f90b7a5a
PB
469 (label_ref (match_operand 3 ""))
470 (pc)))]
471 ""
472 "")
473
6cebc6cb
BS
474(define_expand "cstore<mode>4"
475 [(set (match_operand:QI 0 "register_operand")
f90b7a5a 476 (match_operator:QI 1 "ordered_comparison_operator"
6cebc6cb
BS
477 [(match_operand:CMPMODE 2 "nonimmediate_operand" "")
478 (match_operand:CMPMODE 3 "m68k_comparison_operand" "")]))]
f90b7a5a
PB
479 ""
480 "")
481
1f36fbf4
JL
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
6cebc6cb
BS
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")])
45a45488 499(define_mode_attr cmp1_cf_constraints [(QI "dm") (HI "dm") (SI "mr,r,rm")])
6cebc6cb
BS
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)))]
9425fb04 510 "!TARGET_COLDFIRE"
e0c17b2d 511{
6cebc6cb
BS
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"
6ac62473 526{
6cebc6cb
BS
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);
c47b0cb4 530}
6cebc6cb 531 [(set_attr "flags_valid" "set")])
e0c17b2d 532
6cebc6cb
BS
533(define_insn "cbranch<mode>4_insn_cf"
534 [(set (pc)
f90b7a5a 535 (if_then_else (match_operator 0 "ordered_comparison_operator"
6cebc6cb
BS
536 [(match_operand:CMPMODE 1 "nonimmediate_operand" "<cmp1_cf_constraints>")
537 (match_operand:CMPMODE 2 "<cmp2_cf_predicate>" "<cmp2_cf_constraints>")])
f90b7a5a
PB
538 (label_ref (match_operand 3 ""))
539 (pc)))]
6cebc6cb
BS
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")])
f90b7a5a 547
6cebc6cb
BS
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")])
2b3600ac 562
6cebc6cb
BS
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>")]))]
9425fb04 568 "!TARGET_COLDFIRE"
e0c17b2d 569{
6cebc6cb
BS
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")])
e0c17b2d 575
6cebc6cb
BS
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)])
f90b7a5a
PB
601 (label_ref (match_operand 3 ""))
602 (pc)))]
603 ""
6cebc6cb
BS
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")])
f90b7a5a 610
6cebc6cb
BS
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})
2b3600ac 627
6cebc6cb
BS
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))"
e0c17b2d 657{
6cebc6cb
BS
658 rtx_code code = GET_CODE (operands[0]);
659 if (GET_CODE (operands[1]) == MEM)
3b4b85c9 660 {
6cebc6cb
BS
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);
e0c17b2d 665 }
6cebc6cb
BS
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);
c223cf45 698})
e0c17b2d 699
6cebc6cb
BS
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
f90b7a5a 717(define_expand "cbranch<mode>4"
6cebc6cb 718 [(set (pc)
f90b7a5a 719 (if_then_else (match_operator 0 "comparison_operator"
6cebc6cb
BS
720 [(match_operand:FP 1 "register_operand" "")
721 (match_operand:FP 2 "fp_src_operand" "")])
f90b7a5a
PB
722 (label_ref (match_operand 3 ""))
723 (pc)))]
dcc21c4c 724 "TARGET_HARD_FLOAT"
f90b7a5a
PB
725 "")
726
6cebc6cb
BS
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).
f90b7a5a 729(define_expand "cstore<mode>4"
6cebc6cb 730 [(set (match_operand:QI 0 "register_operand")
f90b7a5a 731 (match_operator:QI 1 "m68k_cstore_comparison_operator"
6cebc6cb
BS
732 [(match_operand:FP 2 "register_operand" "")
733 (match_operand:FP 3 "fp_src_operand" "")]))]
f90b7a5a
PB
734 "TARGET_HARD_FLOAT && !(TUNE_68060 || TARGET_COLDFIRE_FPU)"
735 "if (TARGET_COLDFIRE && operands[2] != const0_rtx)
736 FAIL;")
e0c17b2d 737
6cebc6cb
BS
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)))]
67595cbb 745 "TARGET_68881
6cebc6cb
BS
746 && (register_operand (operands[1], <MODE>mode)
747 || register_operand (operands[2], <MODE>mode)
748 || const0_operand (operands[2], <MODE>mode))"
c223cf45 749{
6cebc6cb
BS
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")])
08417478 755
6cebc6cb
BS
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")])
08417478 773
6cebc6cb
BS
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))"
c223cf45 785{
6cebc6cb
BS
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")])
e0c17b2d 791
6cebc6cb
BS
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))"
c223cf45 803{
6cebc6cb
BS
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")])
e0c17b2d 809
6cebc6cb
BS
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")])
e0c17b2d 825
6cebc6cb
BS
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"
c223cf45 833{
6cebc6cb
BS
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")])
e0c17b2d 839
e0c17b2d
RS
840;; move instructions
841
842;; A special case in which it is not desirable
843;; to reload the constant into a data register.
7b7e5637 844(define_insn "pushexthisi_const"
c47b0cb4
MK
845 [(set (match_operand:SI 0 "push_operand" "=m,m,m")
846 (match_operand:SI 1 "const_int_operand" "C0,R,J"))]
1ecba59d 847 "INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000"
c47b0cb4
MK
848 "@
849 clr%.l %0
850 mov3q%.l %1,%-
851 pea %a1"
96fcacb7 852 [(set_attr "type" "clr_l,mov3q_l,pea")])
e0c17b2d
RS
853
854;This is never used.
855;(define_insn "swapsi"
8406d023 856; [(set (match_operand:SI 0 "nonimmediate_operand" "+r")
17d71a73 857; (match_operand:SI 1 "general_operand" "+r"))
e0c17b2d
RS
858; (set (match_dup 1) (match_dup 0))]
859; ""
860; "exg %1,%0")
861
c47b0cb4
MK
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"
96fcacb7
MK
872 [(set_attr "type" "moveq_l,alu_l,clr_l")
873 (set_attr "opy" "*,0,*")])
c47b0cb4
MK
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")
e0c17b2d 879 (const_int 0))]
c47b0cb4 880 "TUNE_68040_60"
e0c17b2d 881{
c47b0cb4 882 if (which_alternative == 0)
4b3d1177 883 return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
c47b0cb4
MK
884 else if (which_alternative == 1)
885 return "clr%.l %0";
886 else
b8aa7986 887 {
c47b0cb4
MK
888 gcc_unreachable ();
889 return "";
b8aa7986 890 }
c47b0cb4 891}
96fcacb7 892 [(set_attr "type" "lea,clr_l")])
c47b0cb4
MK
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"
96fcacb7
MK
902 [(set_attr "type" "alu_l,clr_l")
903 (set_attr "opy" "0,*")])
e0c17b2d 904
935fb288 905;; General case of fullword move.
e0c17b2d
RS
906;;
907;; This is the main "hook" for PIC code. When generating
908;; PIC, movsi is responsible for determining when the source address
b4ac57ab 909;; needs PIC relocation and appropriately calling legitimize_pic_address
e0c17b2d
RS
910;; to perform the actual relocation.
911;;
912;; In both the PIC and non-PIC cases the patterns generated will
935fb288 913;; matched by the next define_insn.
e0c17b2d 914(define_expand "movsi"
7ffb5e78
RS
915 [(set (match_operand:SI 0 "" "")
916 (match_operand:SI 1 "" ""))]
e0c17b2d 917 ""
e0c17b2d 918{
7ffb5e78
RS
919 rtx tmp, base, offset;
920
75df395f
MK
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))
e0c17b2d 956 {
935fb288 957 /* The source is an address which requires PIC relocation.
e0c17b2d
RS
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 */
e0c17b2d
RS
961 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
962 operands[1] = legitimize_pic_address (operands[1], SImode, temp);
963 }
2c8ec431
DL
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))
f1c25d3b 972 operands[0] = gen_rtx_MEM (SImode,
2c8ec431
DL
973 force_reg (SImode, XEXP (operands[0], 0)));
974 }
7ffb5e78
RS
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 {
b3a13419 981 tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
7ffb5e78
RS
982 emit_move_insn (tmp, base);
983 emit_insn (gen_addsi3 (operands[0], tmp, offset));
984 DONE;
985 }
986 }
428511bb 987})
e0c17b2d 988
39250081
RZ
989;; General case of fullword move.
990(define_insn "*movsi_m68k"
e0c17b2d
RS
991 ;; Notes: make sure no alternative allows g vs g.
992 ;; We don't allow f-regs since fixed point cannot go in them.
39250081
RZ
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);
6cebc6cb
BS
998}
999 [(set_attr "flags_valid" "set")])
39250081
RZ
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"
1a8965c4 1005 [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
d6fb69e7 1006 (match_operand:SI 1 "general_src_operand" "damSKT,n,i"))]
2c8ec431 1007
9425fb04 1008 "!TARGET_COLDFIRE"
e0c17b2d 1009{
12ce9562 1010 return output_move_simode (operands);
6cebc6cb
BS
1011}
1012 [(set_attr "flags_valid" "set")])
e0c17b2d 1013
f233b84c 1014;; ColdFire move instructions can have at most one operand of mode >= 6.
5e04daf3 1015(define_insn "*movsi_cf"
c47b0cb4
MK
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"))]
f233b84c 1018 "TARGET_COLDFIRE"
c47b0cb4
MK
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}
96fcacb7 1064 [(set_attr "type" "mov3q_l,moveq_l,*,mvsz,mvsz,move_l,move,pea,lea,move_l,move_l,move_l")])
12ce9562 1065
2c8ec431
DL
1066;; Special case of fullword move, where we need to get a non-GOT PIC
1067;; reference into an address register.
1068(define_insn ""
8406d023 1069 [(set (match_operand:SI 0 "nonimmediate_operand" "=a<")
2c8ec431
DL
1070 (match_operand:SI 1 "pcrel_address" ""))]
1071 "TARGET_PCREL"
2c8ec431
DL
1072{
1073 if (push_operand (operands[0], SImode))
c223cf45
BI
1074 return "pea %a1";
1075 return "lea %a1,%0";
1076})
2c8ec431 1077
12ce9562 1078(define_expand "movhi"
8406d023 1079 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12ce9562
RK
1080 (match_operand:HI 1 "general_operand" ""))]
1081 ""
1082 "")
1083
1084(define_insn ""
8406d023 1085 [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
2c8ec431 1086 (match_operand:HI 1 "general_src_operand" "gS"))]
9425fb04 1087 "!TARGET_COLDFIRE"
6cebc6cb
BS
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")))])
12ce9562 1093
4761e388 1094(define_insn ""
d1fe6168
PB
1095 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<Q>,g,U")
1096 (match_operand:HI 1 "general_operand" "g,r<Q>,U"))]
9425fb04 1097 "TARGET_COLDFIRE"
6cebc6cb
BS
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")))])
e0c17b2d 1103
95912206 1104(define_expand "movstricthi"
8406d023 1105 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2c8ec431 1106 (match_operand:HI 1 "general_src_operand" ""))]
95912206
RK
1107 ""
1108 "")
1109
1110(define_insn ""
8406d023 1111 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
2c8ec431 1112 (match_operand:HI 1 "general_src_operand" "rmSn"))]
9425fb04 1113 "!TARGET_COLDFIRE"
6cebc6cb
BS
1114 "* return output_move_stricthi (operands);"
1115 [(set_attr "flags_valid" "move")])
95912206
RK
1116
1117(define_insn ""
8406d023 1118 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+d,m"))
2c8ec431 1119 (match_operand:HI 1 "general_src_operand" "rmn,r"))]
9425fb04 1120 "TARGET_COLDFIRE"
6cebc6cb
BS
1121 "* return output_move_stricthi (operands);"
1122 [(set_attr "flags_valid" "move")])
e0c17b2d 1123
12ce9562 1124(define_expand "movqi"
8406d023 1125 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2c8ec431 1126 (match_operand:QI 1 "general_src_operand" ""))]
12ce9562
RK
1127 ""
1128 "")
1129
1130(define_insn ""
8406d023 1131 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,*a,m")
2c8ec431 1132 (match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))]
9425fb04 1133 "!TARGET_COLDFIRE"
6cebc6cb
BS
1134 "* return output_move_qimode (operands);"
1135 [(set_attr "flags_valid" "set")])
e0c17b2d 1136
12ce9562 1137(define_insn ""
d1fe6168
PB
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"))]
9425fb04 1140 "TARGET_COLDFIRE"
6cebc6cb
BS
1141 "* return output_move_qimode (operands);"
1142 [(set_attr "flags_valid" "set")])
e0c17b2d 1143
95912206 1144(define_expand "movstrictqi"
8406d023 1145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2c8ec431 1146 (match_operand:QI 1 "general_src_operand" ""))]
95912206
RK
1147 ""
1148 "")
1149
1150(define_insn ""
8406d023 1151 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
2c8ec431 1152 (match_operand:QI 1 "general_src_operand" "dmSn"))]
9425fb04 1153 "!TARGET_COLDFIRE"
6cebc6cb
BS
1154 "* return output_move_strictqi (operands);"
1155 [(set_attr "flags_valid" "move")])
95912206 1156
c47b0cb4
MK
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"))]
9425fb04 1160 "TARGET_COLDFIRE"
c47b0cb4
MK
1161 "@
1162 clr%.b %0
1163 clr%.b %0
1164 move%.b %1,%0
1165 move%.b %1,%0"
96fcacb7 1166 [(set_attr "type" "clr,clr,move,move")])
e0c17b2d 1167
b7b59ff4 1168(define_expand "pushqi1"
428511bb
RZ
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)))
b7b59ff4 1171 (match_operand:QI 0 "general_operand" ""))]
9425fb04 1172 "!TARGET_COLDFIRE"
b7b59ff4
RZ
1173 "")
1174
dcc21c4c
PB
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. */
f7df4a84 1185 emit_insn (gen_rtx_SET (operands[0], operands[1]));
dcc21c4c
PB
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. */
f7df4a84 1199 emit_insn (gen_rtx_SET (operands[0], operands[1]));
dcc21c4c
PB
1200 DONE;
1201})
1202
12ce9562 1203(define_expand "movsf"
8406d023 1204 [(set (match_operand:SF 0 "nonimmediate_operand" "")
12ce9562
RK
1205 (match_operand:SF 1 "general_operand" ""))]
1206 ""
1207 "")
1208
1209(define_insn ""
1a8965c4
AS
1210 [(set (match_operand:SF 0 "nonimmediate_operand" "=rmf")
1211 (match_operand:SF 1 "general_operand" "rmfF"))]
9425fb04 1212 "!TARGET_COLDFIRE"
e0c17b2d 1213{
e0c17b2d
RS
1214 if (FP_REG_P (operands[0]))
1215 {
1216 if (FP_REG_P (operands[1]))
c223cf45 1217 return "f%$move%.x %1,%0";
e0c17b2d 1218 else if (ADDRESS_REG_P (operands[1]))
c223cf45 1219 return "move%.l %1,%-\;f%$move%.s %+,%0";
e0c17b2d
RS
1220 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
1221 return output_move_const_single (operands);
c223cf45 1222 return "f%$move%.s %f1,%0";
e0c17b2d
RS
1223 }
1224 if (FP_REG_P (operands[1]))
1225 {
1226 if (ADDRESS_REG_P (operands[0]))
c223cf45
BI
1227 return "fmove%.s %1,%-\;move%.l %+,%0";
1228 return "fmove%.s %f1,%0";
e0c17b2d 1229 }
0fd12b04 1230 if (operands[1] == CONST0_RTX (SFmode)
3197c489
RS
1231 /* clr insns on 68000 read before writing. */
1232 && ((TARGET_68010 || TARGET_COLDFIRE)
0fd12b04
AS
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 */
9cf106c8 1238 if (TUNE_68040_60)
4b3d1177 1239 return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
9cf106c8
JB
1240 else
1241 return "sub%.l %0,%0";
0fd12b04
AS
1242 }
1243 /* moveq is faster on the 68000. */
fe95f2f7
JB
1244 if (DATA_REG_P (operands[0]) && TUNE_68000_10)
1245 return "moveq #0,%0";
c223cf45 1246 return "clr%.l %0";
0fd12b04 1247 }
c223cf45 1248 return "move%.l %1,%0";
6cebc6cb
BS
1249}
1250 [(set_attr "flags_valid" "move")])
e0c17b2d 1251
dcc21c4c 1252(define_insn "movsf_cf_soft"
31c5b444
RS
1253 [(set (match_operand:SF 0 "nonimmediate_operand" "=r<Q>,g,U")
1254 (match_operand:SF 1 "general_operand" "g,r<Q>,U"))]
dcc21c4c 1255 "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
c47b0cb4
MK
1256 "move%.l %1,%0"
1257 [(set_attr "type" "move_l")])
12ce9562 1258
31c5b444
RS
1259;; SFmode MEMs are restricted to modes 2-4 if TARGET_COLDFIRE_FPU.
1260;; The move instructions can handle all combinations.
dcc21c4c
PB
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];
dcc21c4c 1270 long l;
34a72c33 1271 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
dcc21c4c
PB
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]))
17e143a1 1297 return "move%.l %1,%-;fsmove%.s %+,%0";
dcc21c4c 1298 if (FP_REG_P (operands[1]))
17e143a1
RS
1299 return "fsmove%.d %1,%0";
1300 return "fsmove%.s %f1,%0";
dcc21c4c
PB
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. */
f7df4a84 1327 emit_insn (gen_rtx_SET (operands[0], operands[1]));
dcc21c4c
PB
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. */
f7df4a84 1341 emit_insn (gen_rtx_SET (operands[0], operands[1]));
dcc21c4c
PB
1342 DONE;
1343})
1344
12ce9562 1345(define_expand "movdf"
8406d023 1346 [(set (match_operand:DF 0 "nonimmediate_operand" "")
12ce9562
RK
1347 (match_operand:DF 1 "general_operand" ""))]
1348 ""
dcc21c4c
PB
1349{
1350 if (TARGET_COLDFIRE_FPU)
1351 if (emit_move_sequence (operands, DFmode, 0))
1352 DONE;
1353})
12ce9562
RK
1354
1355(define_insn ""
1a8965c4
AS
1356 [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,rf,rf,&rof<>")
1357 (match_operand:DF 1 "general_operand" "*rf,m,0,*rofE<>"))]
8406d023 1358; [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,&rf,&rof<>")
e0c17b2d 1359; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
9425fb04 1360 "!TARGET_COLDFIRE"
e0c17b2d 1361{
e0c17b2d
RS
1362 if (FP_REG_P (operands[0]))
1363 {
1364 if (FP_REG_P (operands[1]))
c223cf45 1365 return "f%&move%.x %1,%0";
e0c17b2d
RS
1366 if (REG_P (operands[1]))
1367 {
1368 rtx xoperands[2];
1d8eaa6b 1369 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
c223cf45
BI
1370 output_asm_insn ("move%.l %1,%-", xoperands);
1371 output_asm_insn ("move%.l %1,%-", operands);
1372 return "f%&move%.d %+,%0";
e0c17b2d
RS
1373 }
1374 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1375 return output_move_const_double (operands);
c223cf45 1376 return "f%&move%.d %f1,%0";
e0c17b2d
RS
1377 }
1378 else if (FP_REG_P (operands[1]))
1379 {
1380 if (REG_P (operands[0]))
1381 {
c223cf45 1382 output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1d8eaa6b 1383 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45 1384 return "move%.l %+,%0";
e0c17b2d
RS
1385 }
1386 else
c223cf45 1387 return "fmove%.d %f1,%0";
e0c17b2d
RS
1388 }
1389 return output_move_double (operands);
6cebc6cb
BS
1390}
1391 [(set_attr "flags_valid" "move")])
12ce9562 1392
c47b0cb4 1393(define_insn_and_split "movdf_cf_soft"
8406d023 1394 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,g")
12ce9562 1395 (match_operand:DF 1 "general_operand" "g,r"))]
dcc21c4c 1396 "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
c47b0cb4
MK
1397 "#"
1398 "&& reload_completed"
1399 [(const_int 0)]
c223cf45 1400{
c47b0cb4
MK
1401 m68k_emit_move_double (operands);
1402 DONE;
c223cf45 1403})
e0c17b2d 1404
dcc21c4c
PB
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];
dcc21c4c
PB
1411 long l[2];
1412
1413 switch (which_alternative)
1414 {
1415 default:
17e143a1
RS
1416 return "fdmove%.d %1,%0";
1417 case 1:
dcc21c4c
PB
1418 return "fmove%.d %1,%0";
1419 case 2:
1420 return "fmove%.d %1,%-;move%.l %+,%0;move%.l %+,%R0";
1421 case 3:
17e143a1 1422 return "move%.l %R1,%-;move%.l %1,%-;fdmove%.d %+,%0";
bb017fc1 1423 case 4: case 5: case 6:
dcc21c4c
PB
1424 return output_move_double (operands);
1425 case 7:
34a72c33 1426 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
dcc21c4c
PB
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
8338d44d
JW
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.
1a627b35 1447;; See also TARGET_LEGITIMATE_CONSTANT_P.
8338d44d 1448
2743360a
RS
1449(define_expand "movxf"
1450 [(set (match_operand:XF 0 "nonimmediate_operand" "")
1451 (match_operand:XF 1 "general_operand" ""))]
503e4b87 1452 ""
2743360a 1453{
8338d44d
JW
1454 /* We can't rewrite operands during reload. */
1455 if (! reload_in_progress)
2c8ec431 1456 {
8338d44d
JW
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))
f1c25d3b 1469 operands[0] = gen_rtx_MEM (XFmode,
8338d44d
JW
1470 force_reg (SImode, XEXP (operands[0], 0)));
1471 }
2c8ec431 1472 }
428511bb 1473})
2743360a
RS
1474
1475(define_insn ""
1b13a490
PB
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"))]
2743360a 1478 "TARGET_68881"
2743360a
RS
1479{
1480 if (FP_REG_P (operands[0]))
1481 {
1482 if (FP_REG_P (operands[1]))
c223cf45 1483 return "fmove%.x %1,%0";
2743360a
RS
1484 if (REG_P (operands[1]))
1485 {
1486 rtx xoperands[2];
1d8eaa6b 1487 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
c223cf45 1488 output_asm_insn ("move%.l %1,%-", xoperands);
1d8eaa6b 1489 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
c223cf45
BI
1490 output_asm_insn ("move%.l %1,%-", xoperands);
1491 output_asm_insn ("move%.l %1,%-", operands);
1492 return "fmove%.x %+,%0";
2743360a
RS
1493 }
1494 if (GET_CODE (operands[1]) == CONST_DOUBLE)
c223cf45
BI
1495 return "fmove%.x %1,%0";
1496 return "fmove%.x %f1,%0";
2743360a 1497 }
619aeb96 1498 if (FP_REG_P (operands[1]))
2743360a 1499 {
619aeb96
JW
1500 if (REG_P (operands[0]))
1501 {
c223cf45 1502 output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands);
619aeb96 1503 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45 1504 output_asm_insn ("move%.l %+,%0", operands);
619aeb96 1505 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45 1506 return "move%.l %+,%0";
619aeb96
JW
1507 }
1508 /* Must be memory destination. */
c223cf45 1509 return "fmove%.x %f1,%0";
2743360a 1510 }
619aeb96 1511 return output_move_double (operands);
6cebc6cb
BS
1512}
1513 [(set_attr "flags_valid" "move")])
2743360a 1514
503e4b87 1515(define_insn ""
b07b4e49 1516 [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
503e4b87 1517 (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))]
9425fb04 1518 "! TARGET_68881 && ! TARGET_COLDFIRE"
503e4b87
RS
1519{
1520 if (FP_REG_P (operands[0]))
1521 {
1522 if (FP_REG_P (operands[1]))
c223cf45 1523 return "fmove%.x %1,%0";
503e4b87
RS
1524 if (REG_P (operands[1]))
1525 {
1526 rtx xoperands[2];
1d8eaa6b 1527 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
c223cf45 1528 output_asm_insn ("move%.l %1,%-", xoperands);
1d8eaa6b 1529 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
c223cf45
BI
1530 output_asm_insn ("move%.l %1,%-", xoperands);
1531 output_asm_insn ("move%.l %1,%-", operands);
1532 return "fmove%.x %+,%0";
503e4b87
RS
1533 }
1534 if (GET_CODE (operands[1]) == CONST_DOUBLE)
c223cf45
BI
1535 return "fmove%.x %1,%0";
1536 return "fmove%.x %f1,%0";
503e4b87
RS
1537 }
1538 if (FP_REG_P (operands[1]))
1539 {
1540 if (REG_P (operands[0]))
1541 {
c223cf45 1542 output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands);
1d8eaa6b 1543 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45 1544 output_asm_insn ("move%.l %+,%0", operands);
1d8eaa6b 1545 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45 1546 return "move%.l %+,%0";
503e4b87
RS
1547 }
1548 else
c223cf45 1549 return "fmove%.x %f1,%0";
503e4b87
RS
1550 }
1551 return output_move_double (operands);
c223cf45 1552})
503e4b87 1553
079e639f
JW
1554(define_insn ""
1555 [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g")
1556 (match_operand:XF 1 "nonimmediate_operand" "g,r"))]
9425fb04 1557 "! TARGET_68881 && TARGET_COLDFIRE"
079e639f
JW
1558 "* return output_move_double (operands);")
1559
12ce9562
RK
1560(define_expand "movdi"
1561 ;; Let's see if it really still needs to handle fp regs, and, if so, why.
8406d023 1562 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12ce9562
RK
1563 (match_operand:DI 1 "general_operand" ""))]
1564 ""
1565 "")
1566
e0c17b2d 1567;; movdi can apply to fp regs in some cases
12ce9562 1568(define_insn ""
e0c17b2d 1569 ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1a8965c4
AS
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"))]
8406d023 1574; [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&rf,&ro<>,!&rm,!&f")
e0c17b2d 1575; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
9425fb04 1576 "!TARGET_COLDFIRE"
e0c17b2d 1577{
e0c17b2d
RS
1578 if (FP_REG_P (operands[0]))
1579 {
1580 if (FP_REG_P (operands[1]))
c223cf45 1581 return "fmove%.x %1,%0";
e0c17b2d
RS
1582 if (REG_P (operands[1]))
1583 {
1584 rtx xoperands[2];
1d8eaa6b 1585 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
c223cf45
BI
1586 output_asm_insn ("move%.l %1,%-", xoperands);
1587 output_asm_insn ("move%.l %1,%-", operands);
1588 return "fmove%.d %+,%0";
e0c17b2d
RS
1589 }
1590 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1591 return output_move_const_double (operands);
c223cf45 1592 return "fmove%.d %f1,%0";
e0c17b2d
RS
1593 }
1594 else if (FP_REG_P (operands[1]))
1595 {
1596 if (REG_P (operands[0]))
1597 {
c223cf45 1598 output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1d8eaa6b 1599 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45 1600 return "move%.l %+,%0";
e0c17b2d
RS
1601 }
1602 else
c223cf45 1603 return "fmove%.d %f1,%0";
e0c17b2d
RS
1604 }
1605 return output_move_double (operands);
c223cf45 1606})
12ce9562
RK
1607
1608(define_insn ""
8406d023 1609 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,g")
12ce9562 1610 (match_operand:DI 1 "general_operand" "g,r"))]
9425fb04 1611 "TARGET_COLDFIRE"
12ce9562 1612 "* return output_move_double (operands);")
e0c17b2d
RS
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 ""
c47b0cb4
MK
1623 "pea %a1"
1624 [(set_attr "type" "pea")])
e0c17b2d
RS
1625\f
1626;; truncation instructions
1627(define_insn "truncsiqi2"
8406d023 1628 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
e0c17b2d 1629 (truncate:QI
2c8ec431 1630 (match_operand:SI 1 "general_src_operand" "doJS,i")))]
1481bdb1 1631 "!TARGET_COLDFIRE"
e0c17b2d
RS
1632{
1633 if (GET_CODE (operands[0]) == REG)
6cebc6cb
BS
1634 return "move%.l %1,%0";
1635
e0c17b2d 1636 if (GET_CODE (operands[1]) == MEM)
b72f00af 1637 operands[1] = adjust_address (operands[1], QImode, 3);
c223cf45 1638 return "move%.b %1,%0";
6cebc6cb
BS
1639}
1640 [(set (attr "flags_valid")
1641 (if_then_else (match_operand 0 "register_operand")
1642 (const_string "no")
1643 (const_string "yes")))])
e0c17b2d
RS
1644
1645(define_insn "trunchiqi2"
8406d023 1646 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
e0c17b2d 1647 (truncate:QI
2c8ec431 1648 (match_operand:HI 1 "general_src_operand" "doJS,i")))]
1481bdb1 1649 "!TARGET_COLDFIRE"
e0c17b2d
RS
1650{
1651 if (GET_CODE (operands[0]) == REG
1652 && (GET_CODE (operands[1]) == MEM
1653 || GET_CODE (operands[1]) == CONST_INT))
6cebc6cb
BS
1654 return "move%.w %1,%0";
1655
e0c17b2d 1656 if (GET_CODE (operands[0]) == REG)
6cebc6cb
BS
1657 return "move%.l %1,%0";
1658
e0c17b2d 1659 if (GET_CODE (operands[1]) == MEM)
b72f00af 1660 operands[1] = adjust_address (operands[1], QImode, 1);
c223cf45 1661 return "move%.b %1,%0";
6cebc6cb
BS
1662}
1663 [(set (attr "flags_valid")
1664 (if_then_else (match_operand 0 "register_operand")
1665 (const_string "no")
1666 (const_string "yes")))])
e0c17b2d
RS
1667
1668(define_insn "truncsihi2"
8406d023 1669 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm,d")
e0c17b2d 1670 (truncate:HI
2c8ec431 1671 (match_operand:SI 1 "general_src_operand" "roJS,i")))]
1481bdb1 1672 "!TARGET_COLDFIRE"
e0c17b2d
RS
1673{
1674 if (GET_CODE (operands[0]) == REG)
6cebc6cb
BS
1675 return "move%.l %1,%0";
1676
e0c17b2d 1677 if (GET_CODE (operands[1]) == MEM)
b72f00af 1678 operands[1] = adjust_address (operands[1], QImode, 2);
c223cf45 1679 return "move%.w %1,%0";
6cebc6cb
BS
1680}
1681 [(set (attr "flags_valid")
1682 (if_then_else (match_operand 0 "register_operand")
1683 (const_string "no")
1684 (const_string "yes")))])
e0c17b2d
RS
1685\f
1686;; zero extension instructions
1687
9652c531
RZ
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 "#"
9147affc 1696 "&& 1"
9652c531
RZ
1697 [(set (match_dup 0)
1698 (const_int 0))
1699 (set (match_dup 0)
1700 (match_dup 1))]
4b8bef1d 1701{
9652c531 1702 operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0);
c223cf45 1703})
4b8bef1d 1704
9652c531
RZ
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 "#"
9147affc 1713 "&& 1"
9652c531
RZ
1714 [(set (match_dup 0)
1715 (match_dup 1))
1716 (set (match_dup 0)
1717 (const_int 0))]
4b8bef1d 1718{
9652c531 1719 operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0);
c223cf45 1720})
4b8bef1d 1721
9652c531
RZ
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" "")))]
801aee46 1725 ""
9652c531
RZ
1726 "#"
1727 ""
1728 [(set (match_dup 2)
1729 (zero_extend:SI (match_dup 1)))
1730 (set (match_dup 3)
1731 (const_int 0))]
0655301f 1732{
9652c531
RZ
1733 operands[2] = gen_lowpart (SImode, operands[0]);
1734 operands[3] = gen_highpart (SImode, operands[0]);
c223cf45 1735})
0655301f 1736
9652c531
RZ
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))]
801aee46 1747{
9652c531
RZ
1748 operands[2] = gen_lowpart (SImode, operands[0]);
1749 operands[3] = gen_highpart (SImode, operands[0]);
c223cf45 1750})
801aee46 1751
9652c531
RZ
1752(define_expand "zero_extendsidi2"
1753 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1754 (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))]
e0c17b2d 1755 ""
04760127
KH
1756{
1757 if (GET_CODE (operands[0]) == MEM
1758 && GET_CODE (operands[1]) == MEM)
1759 operands[1] = force_reg (SImode, operands[1]);
1760})
e0c17b2d 1761
9652c531
RZ
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 "#"
9147affc 1767 "&& 1"
9652c531
RZ
1768 [(set (match_dup 2)
1769 (match_dup 1))
1770 (set (match_dup 3)
1771 (const_int 0))]
e0c17b2d 1772{
9652c531
RZ
1773 operands[2] = gen_lowpart (SImode, operands[0]);
1774 operands[3] = gen_highpart (SImode, operands[0]);
1775})
e0c17b2d 1776
9652c531
RZ
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")))]
59c92f76 1780 "ISA_HAS_MVS_MVZ"
c47b0cb4 1781 "mvz%.w %1,%0"
96fcacb7 1782 [(set_attr "type" "mvsz")])
9652c531
RZ
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")))]
e0c17b2d 1787 ""
9652c531 1788 "#")
e0c17b2d 1789
9652c531
RZ
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 "")
e0c17b2d 1795
9652c531
RZ
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 "#")
e0c17b2d 1801
9652c531
RZ
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")))]
59c92f76 1805 "ISA_HAS_MVS_MVZ"
c47b0cb4 1806 "mvz%.b %1,%0"
96fcacb7 1807 [(set_attr "type" "mvsz")])
9652c531
RZ
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" "")))]
59c92f76 1820 "!ISA_HAS_MVS_MVZ
986e74d5
JB
1821 && reload_completed
1822 && reg_mentioned_p (operands[0], operands[1])"
9652c531
RZ
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" "")))]
59c92f76 1836 "!ISA_HAS_MVS_MVZ && reload_completed"
9652c531
RZ
1837 [(set (match_dup 0)
1838 (const_int 0))
1839 (set (strict_low_part (match_dup 2))
1840 (match_dup 1))]
e0c17b2d 1841{
9652c531 1842 operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]);
c223cf45 1843})
e0c17b2d
RS
1844\f
1845;; sign extension instructions
1846
801aee46 1847(define_insn "extendqidi2"
8406d023 1848 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
2c8ec431 1849 (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))]
801aee46 1850 ""
801aee46 1851{
1d8eaa6b 1852 operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
59c92f76 1853 if (ISA_HAS_MVS_MVZ)
5e04daf3 1854 return "mvs%.b %1,%2\;smi %0\;extb%.l %0";
9425fb04 1855 if (TARGET_68020 || TARGET_COLDFIRE)
1b8452d0
AS
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 }
801aee46 1862 else
1b8452d0
AS
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 }
c223cf45 1869})
801aee46
RK
1870
1871(define_insn "extendhidi2"
8406d023 1872 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
801aee46 1873 (sign_extend:DI
2c8ec431 1874 (match_operand:HI 1 "general_src_operand" "rmS")))]
801aee46 1875 ""
801aee46 1876{
1d8eaa6b 1877 operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
59c92f76 1878 if (ISA_HAS_MVS_MVZ)
5e04daf3 1879 return "mvs%.w %1,%2\;smi %0\;extb%.l %0";
9425fb04 1880 if (TARGET_68020 || TARGET_COLDFIRE)
c223cf45 1881 return "move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0";
801aee46 1882 else
c223cf45
BI
1883 return "move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0";
1884})
801aee46
RK
1885
1886(define_insn "extendsidi2"
5a1c3c10
MK
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"))]
801aee46 1891 ""
801aee46 1892{
5a1c3c10
MK
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. */
01e304f8 1904 operands[3] = adjust_address (operands[0], SImode,
5a1c3c10 1905 which_alternative == 3 ? 0 : 4);
01e304f8 1906 operands[0] = adjust_address (operands[0], SImode, 0);
5a1c3c10 1907
01e304f8
RZ
1908 if (TARGET_68020 || TARGET_COLDFIRE)
1909 return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
801aee46 1910 else
01e304f8 1911 return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
5a1c3c10
MK
1912}
1913 [(set_attr "ok_for_coldfire" "yes,no,yes,yes")])
801aee46
RK
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
2f7ac5ce
JL
1919;; Don't allow memory for operand 1 as that would require an earlyclobber
1920;; which results in worse code
801aee46
RK
1921(define_insn "extendplussidi"
1922 [(set (match_operand:DI 0 "register_operand" "=d")
2f7ac5ce 1923 (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rn")
801aee46
RK
1924 (match_operand:SI 2 "general_operand" "rmn"))))]
1925 ""
801aee46 1926{
1d8eaa6b 1927 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
801aee46
RK
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 }
935fb288
RK
1936 if (GET_CODE (operands[1]) == REG
1937 && REGNO (operands[1]) == REGNO (operands[3]))
c223cf45 1938 output_asm_insn ("add%.l %2,%3", operands);
935fb288 1939 else
c223cf45 1940 output_asm_insn ("move%.l %2,%3\;add%.l %1,%3", operands);
9425fb04 1941 if (TARGET_68020 || TARGET_COLDFIRE)
c223cf45 1942 return "smi %0\;extb%.l %0";
801aee46 1943 else
c223cf45
BI
1944 return "smi %0\;ext%.w %0\;ext%.l %0";
1945})
801aee46 1946
5e04daf3
PB
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")))]
59c92f76 1958 "ISA_HAS_MVS_MVZ"
c47b0cb4 1959 "mvs%.w %1,%0"
96fcacb7 1960 [(set_attr "type" "mvsz")])
5e04daf3
PB
1961
1962(define_insn "*68k_extendhisi2"
8406d023 1963 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
e0c17b2d 1964 (sign_extend:SI
2c8ec431 1965 (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
59c92f76 1966 "!ISA_HAS_MVS_MVZ"
c47b0cb4
MK
1967 "@
1968 ext%.l %0
1969 move%.w %1,%0"
96fcacb7 1970 [(set_attr "type" "ext,move")])
e0c17b2d
RS
1971
1972(define_insn "extendqihi2"
8406d023 1973 [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
e0c17b2d
RS
1974 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1975 ""
c47b0cb4 1976 "ext%.w %0"
96fcacb7 1977 [(set_attr "type" "ext")])
e0c17b2d 1978
5e04daf3
PB
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"
428511bb 1986 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
5e04daf3 1987 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))]
59c92f76 1988 "ISA_HAS_MVS_MVZ"
c47b0cb4 1989 "mvs%.b %1,%0"
96fcacb7 1990 [(set_attr "type" "mvsz")])
5e04daf3
PB
1991
1992(define_insn "*68k_extendqisi2"
8406d023 1993 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
e0c17b2d 1994 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
59c92f76 1995 "TARGET_68020 || (TARGET_COLDFIRE && !ISA_HAS_MVS_MVZ)"
c47b0cb4 1996 "extb%.l %0"
96fcacb7 1997 [(set_attr "type" "ext")])
e0c17b2d
RS
1998\f
1999;; Conversions between float and double.
2000
2001(define_expand "extendsfdf2"
8406d023 2002 [(set (match_operand:DF 0 "nonimmediate_operand" "")
e0c17b2d
RS
2003 (float_extend:DF
2004 (match_operand:SF 1 "general_operand" "")))]
dcc21c4c 2005 "TARGET_HARD_FLOAT"
e0c17b2d
RS
2006 "")
2007
e0c17b2d 2008(define_insn ""
8406d023 2009 [(set (match_operand:DF 0 "nonimmediate_operand" "=*fdm,f")
e0c17b2d
RS
2010 (float_extend:DF
2011 (match_operand:SF 1 "general_operand" "f,dmF")))]
2012 "TARGET_68881"
e0c17b2d
RS
2013{
2014 if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
2015 {
2016 if (REGNO (operands[0]) == REGNO (operands[1]))
2017 {
6cebc6cb 2018 /* Extending float to double in an fp-reg is a no-op. */
c223cf45 2019 return "";
e0c17b2d 2020 }
c223cf45 2021 return "f%&move%.x %1,%0";
e0c17b2d
RS
2022 }
2023 if (FP_REG_P (operands[0]))
c223cf45 2024 return "f%&move%.s %f1,%0";
e0c17b2d
RS
2025 if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
2026 {
c223cf45 2027 output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1d8eaa6b 2028 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45 2029 return "move%.l %+,%0";
e0c17b2d 2030 }
c223cf45
BI
2031 return "fmove%.d %f1,%0";
2032})
e0c17b2d 2033
dcc21c4c
PB
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 {
6cebc6cb 2044 /* Extending float to double in an fp-reg is a no-op. */
dcc21c4c
PB
2045 return "";
2046 }
17e143a1 2047 return "fdmove%.d %1,%0";
dcc21c4c 2048 }
17e143a1 2049 return "fdmove%.s %f1,%0";
dcc21c4c
PB
2050})
2051
e0c17b2d
RS
2052;; This cannot output into an f-reg because there is no way to be
2053;; sure of truncating in that case.
e0c17b2d 2054(define_expand "truncdfsf2"
8406d023 2055 [(set (match_operand:SF 0 "nonimmediate_operand" "")
e0c17b2d
RS
2056 (float_truncate:SF
2057 (match_operand:DF 1 "general_operand" "")))]
dcc21c4c 2058 "TARGET_HARD_FLOAT"
e0c17b2d
RS
2059 "")
2060
e0c17b2d
RS
2061;; On the '040 we can truncate in a register accurately and easily.
2062(define_insn ""
8406d023 2063 [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
e0c17b2d
RS
2064 (float_truncate:SF
2065 (match_operand:DF 1 "general_operand" "fmG")))]
b101567e 2066 "TARGET_68881 && TARGET_68040"
e0c17b2d
RS
2067{
2068 if (FP_REG_P (operands[1]))
c223cf45
BI
2069 return "f%$move%.x %1,%0";
2070 return "f%$move%.d %f1,%0";
2071})
e0c17b2d 2072
dcc21c4c
PB
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 "@
17e143a1 2079 fsmove%.d %1,%0
c47b0cb4
MK
2080 fmove%.s %1,%0"
2081 [(set_attr "type" "fmove")])
dcc21c4c 2082
c47b0cb4 2083(define_insn "*truncdfsf2_68881"
8406d023 2084 [(set (match_operand:SF 0 "nonimmediate_operand" "=dm")
e0c17b2d
RS
2085 (float_truncate:SF
2086 (match_operand:DF 1 "general_operand" "f")))]
2087 "TARGET_68881"
c47b0cb4
MK
2088 "fmove%.s %f1,%0"
2089 [(set_attr "type" "fmove")])
e0c17b2d
RS
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
dcc21c4c
PB
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"
e0c17b2d
RS
2103 "")
2104
dcc21c4c
PB
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")))]
e0c17b2d 2108 "TARGET_68881"
96fcacb7
MK
2109 "f<FP:round>move%.l %1,%0"
2110 [(set_attr "type" "fmove")])
e0c17b2d 2111
dcc21c4c
PB
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"
c47b0cb4
MK
2116 "f<FP:prec>move%.l %1,%0"
2117 [(set_attr "type" "fmove")])
e0c17b2d 2118
e0c17b2d 2119
dcc21c4c
PB
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 "")
e0c17b2d 2125
dcc21c4c
PB
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")))]
e0c17b2d 2129 "TARGET_68881"
c47b0cb4
MK
2130 "fmove%.w %1,%0"
2131 [(set_attr "type" "fmove")])
e0c17b2d 2132
dcc21c4c
PB
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"
c47b0cb4
MK
2137 "fmove%.w %1,%0"
2138 [(set_attr "type" "fmove")])
dcc21c4c
PB
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")))]
e0c17b2d 2150 "TARGET_68881"
c47b0cb4
MK
2151 "fmove%.b %1,%0"
2152 [(set_attr "type" "fmove")])
e0c17b2d 2153
dcc21c4c
PB
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"
c47b0cb4
MK
2158 "fmove%.b %1,%0"
2159 [(set_attr "type" "fmove")])
dcc21c4c 2160
e0c17b2d
RS
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
2743360a 2165;; than calling the subroutines fixsfsi or fixdfsi.
e0c17b2d
RS
2166
2167(define_insn "fix_truncdfsi2"
8406d023 2168 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
e0c17b2d
RS
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"))]
fe95f2f7 2172 "TARGET_68881 && TUNE_68040"
e0c17b2d 2173{
3b4b85c9 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,%!";
c223cf45 2175})
e0c17b2d
RS
2176
2177(define_insn "fix_truncdfhi2"
8406d023 2178 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
e0c17b2d
RS
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"))]
fe95f2f7 2182 "TARGET_68881 && TUNE_68040"
e0c17b2d 2183{
3b4b85c9 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,%!";
c223cf45 2185})
e0c17b2d
RS
2186
2187(define_insn "fix_truncdfqi2"
8406d023 2188 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
e0c17b2d
RS
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"))]
fe95f2f7 2192 "TARGET_68881 && TUNE_68040"
e0c17b2d 2193{
3b4b85c9 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,%!";
c223cf45 2195})
e0c17b2d
RS
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
dcc21c4c
PB
2200(define_expand "ftrunc<mode>2"
2201 [(set (match_operand:FP 0 "nonimmediate_operand" "")
2202 (fix:FP (match_operand:FP 1 "general_operand" "")))]
fe95f2f7 2203 "TARGET_HARD_FLOAT && !TUNE_68040"
dcc21c4c
PB
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")))]
fe95f2f7 2209 "TARGET_68881 && !TUNE_68040"
e0c17b2d
RS
2210{
2211 if (FP_REG_P (operands[1]))
c223cf45 2212 return "fintrz%.x %f1,%0";
dcc21c4c 2213 return "fintrz%.<FP:prec> %f1,%0";
96fcacb7
MK
2214}
2215 [(set_attr "type" "falu")])
e0c17b2d 2216
dcc21c4c
PB
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"
e0c17b2d
RS
2221{
2222 if (FP_REG_P (operands[1]))
dcc21c4c
PB
2223 return "fintrz%.d %f1,%0";
2224 return "fintrz%.<FP:prec> %f1,%0";
c47b0cb4 2225}
96fcacb7 2226 [(set_attr "type" "falu")])
e0c17b2d
RS
2227
2228;; Convert a float whose value is an integer
2229;; to an actual integer. Second stage of converting float to integer type.
dcc21c4c
PB
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"
8406d023 2237 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
dcc21c4c 2238 (fix:QI (match_operand:FP 1 "general_operand" "f")))]
e0c17b2d 2239 "TARGET_68881"
96fcacb7
MK
2240 "fmove%.b %1,%0"
2241 [(set_attr "type" "fmove")])
e0c17b2d 2242
dcc21c4c
PB
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"
c47b0cb4
MK
2247 "fmove%.b %1,%0"
2248 [(set_attr "type" "fmove")])
e0c17b2d 2249
dcc21c4c
PB
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"
8406d023 2257 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
dcc21c4c 2258 (fix:HI (match_operand:FP 1 "general_operand" "f")))]
e0c17b2d 2259 "TARGET_68881"
96fcacb7
MK
2260 "fmove%.w %1,%0"
2261 [(set_attr "type" "fmove")])
e0c17b2d 2262
dcc21c4c
PB
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"
c47b0cb4
MK
2267 "fmove%.w %1,%0"
2268 [(set_attr "type" "fmove")])
dcc21c4c
PB
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"
8406d023 2277 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
dcc21c4c 2278 (fix:SI (match_operand:FP 1 "general_operand" "f")))]
e0c17b2d 2279 "TARGET_68881"
96fcacb7
MK
2280 "fmove%.l %1,%0"
2281 [(set_attr "type" "fmove")])
dcc21c4c
PB
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"
c47b0cb4
MK
2287 "fmove%.l %1,%0"
2288 [(set_attr "type" "fmove")])
dcc21c4c 2289
e0c17b2d
RS
2290\f
2291;; add instructions
2292
acc3b6d9 2293(define_insn "adddi_lshrdi_63"
8406d023 2294 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
acc3b6d9
RK
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 ""
acc3b6d9 2300{
1d8eaa6b 2301 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
acc3b6d9
RK
2302 if (REG_P (operands[1]) && REGNO (operands[1]) == REGNO (operands[0]))
2303 return
c223cf45 2304 "move%.l %1,%2\;add%.l %2,%2\;subx%.l %2,%2\;sub%.l %2,%3\;subx%.l %2,%0";
acc3b6d9 2305 if (GET_CODE (operands[1]) == REG)
1d8eaa6b 2306 operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
acc3b6d9
RK
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
b72f00af 2311 operands[4] = adjust_address (operands[1], SImode, 4);
acc3b6d9
RK
2312 if (GET_CODE (operands[1]) == MEM
2313 && GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
c223cf45
BI
2314 output_asm_insn ("move%.l %4,%3", operands);
2315 output_asm_insn ("move%.l %1,%0\;smi %2", operands);
9425fb04 2316 if (TARGET_68020 || TARGET_COLDFIRE)
c223cf45 2317 output_asm_insn ("extb%.l %2", operands);
acc3b6d9 2318 else
c223cf45 2319 output_asm_insn ("ext%.w %2\;ext%.l %2", operands);
acc3b6d9
RK
2320 if (GET_CODE (operands[1]) != MEM
2321 || GET_CODE (XEXP (operands[1], 0)) != PRE_DEC)
c223cf45
BI
2322 output_asm_insn ("move%.l %4,%3", operands);
2323 return "sub%.l %2,%3\;subx%.l %2,%0";
2324})
acc3b6d9 2325
f8e0b2ea 2326(define_insn "adddi_sexthishl32"
8406d023 2327 [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
801aee46 2328 (plus:DI (ashift:DI (sign_extend:DI
935fb288 2329 (match_operand:HI 1 "general_operand" "rm,rm,rm,rm"))
801aee46 2330 (const_int 32))
935fb288
RK
2331 (match_operand:DI 2 "general_operand" "0,0,0,0")))
2332 (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
9425fb04 2333 "!TARGET_COLDFIRE"
801aee46 2334{
f8e0b2ea 2335 if (ADDRESS_REG_P (operands[0]))
c223cf45 2336 return "add%.w %1,%0";
935fb288 2337 else if (ADDRESS_REG_P (operands[3]))
c223cf45 2338 return "move%.w %1,%3\;add%.l %3,%0";
f8e0b2ea 2339 else
c223cf45
BI
2340 return "move%.w %1,%3\;ext%.l %3\;add%.l %3,%0";
2341})
801aee46 2342
b6d2f42e 2343(define_insn "*adddi_dilshr32"
8406d023 2344 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o")
b6d2f42e
RS
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"
801aee46 2349{
801aee46 2350 if (GET_CODE (operands[0]) == REG)
1d8eaa6b 2351 operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
801aee46 2352 else
b72f00af 2353 operands[2] = adjust_address (operands[0], SImode, 4);
c223cf45
BI
2354 return "add%.l %1,%2\;negx%.l %0\;neg%.l %0";
2355})
801aee46 2356
b6d2f42e
RS
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{
b6d2f42e
RS
2364 return "add%.l %1,%R0\;negx%.l %0\;neg%.l %0";
2365})
2366
801aee46 2367(define_insn "adddi_dishl32"
8406d023 2368 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
31e033e9
RK
2369;; (plus:DI (match_operand:DI 2 "general_operand" "%0")
2370;; (ashift:DI (match_operand:DI 1 "general_operand" "ro")
2371;; (const_int 32))))]
b7b59ff4 2372 (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro,d")
801aee46 2373 (const_int 32))
af55143f 2374 (match_operand:DI 2 "general_operand" "0,0")))]
801aee46 2375 ""
801aee46 2376{
801aee46 2377 if (GET_CODE (operands[1]) == REG)
1d8eaa6b 2378 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
801aee46 2379 else
b72f00af 2380 operands[1] = adjust_address (operands[1], SImode, 4);
c223cf45 2381 return "add%.l %1,%0";
c47b0cb4 2382}
96fcacb7 2383 [(set_attr "type" "alu_l")])
801aee46 2384
54dad0c2 2385(define_insn "adddi3"
b6d2f42e
RS
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"))]
54dad0c2 2390 ""
54dad0c2 2391{
055c1584
RK
2392 if (DATA_REG_P (operands[0]))
2393 {
2394 if (DATA_REG_P (operands[2]))
c223cf45 2395 return "add%.l %R2,%R0\;addx%.l %2,%0";
055c1584
RK
2396 else if (GET_CODE (operands[2]) == MEM
2397 && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
c223cf45 2398 return "move%.l %2,%3\;add%.l %2,%R0\;addx%.l %3,%0";
055c1584
RK
2399 else
2400 {
c5c76735 2401 rtx high, low;
7878eae7 2402 rtx xoperands[2];
c5c76735 2403
055c1584 2404 if (GET_CODE (operands[2]) == REG)
5f24901c 2405 {
c5c76735
JL
2406 low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2407 high = operands[2];
5f24901c 2408 }
c5c76735
JL
2409 else if (CONSTANT_P (operands[2]))
2410 split_double (operands[2], &high, &low);
2411 else
5f24901c 2412 {
b72f00af 2413 low = adjust_address (operands[2], SImode, 4);
c5c76735 2414 high = operands[2];
5f24901c 2415 }
c5c76735
JL
2416
2417 operands[1] = low, operands[2] = high;
7878eae7 2418 xoperands[0] = operands[3];
436bf9fb
AS
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];
c5c76735 2424
7878eae7
AS
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)
c223cf45 2429 return "addq%.l %1,%R0\;addx%.l %3,%0";
7878eae7
AS
2430 else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2431 {
2432 operands[1] = GEN_INT (-INTVAL (operands[1]));
c223cf45 2433 return "subq%.l %1,%R0\;subx%.l %3,%0";
7878eae7
AS
2434 }
2435 }
c223cf45 2436 return "add%.l %1,%R0\;addx%.l %3,%0";
055c1584
RK
2437 }
2438 }
4761e388 2439 else
801aee46 2440 {
4761e388 2441 gcc_assert (GET_CODE (operands[0]) == MEM);
055c1584
RK
2442 if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2443 {
c5c76735 2444 operands[1] = gen_rtx_MEM (SImode,
0a81f074
RS
2445 plus_constant (Pmode,
2446 XEXP(operands[0], 0), -8));
c223cf45 2447 return "move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1";
055c1584
RK
2448 }
2449 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2450 {
2451 operands[1] = XEXP(operands[0], 0);
c223cf45 2452 return "add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1";
055c1584
RK
2453 }
2454 else
2455 {
b72f00af 2456 operands[1] = adjust_address (operands[0], SImode, 4);
c223cf45 2457 return "add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0";
055c1584 2458 }
801aee46 2459 }
6cebc6cb
BS
2460}
2461 [(set (attr "flags_valid")
2462 (if_then_else (match_operand 0 "register_operand")
2463 (const_string "noov")
2464 (const_string "no")))])
54dad0c2 2465
31e033e9 2466(define_insn "addsi_lshrsi_31"
5ad2f1a5
MK
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")
31e033e9 2469 (const_int 31))
28ee27fd 2470 (match_dup 1)))]
31e033e9 2471 ""
31e033e9
RK
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)
1d8eaa6b 2478 operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
31e033e9 2479 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1d8eaa6b 2480 operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
31e033e9 2481 }
c223cf45 2482 output_asm_insn ("move%.l %1,%0", operands);
da398bb5 2483 output_asm_insn ("jpl %l3", operands);
3b4b85c9 2484 output_asm_insn ("addq%.l #1,%2", operands);
c223cf45 2485 (*targetm.asm_out.internal_label) (asm_out_file, "L",
31e033e9 2486 CODE_LABEL_NUMBER (operands[3]));
c223cf45 2487 return "";
5ad2f1a5
MK
2488}
2489 [(set_attr "ok_for_coldfire" "no,yes,yes")])
31e033e9 2490
079e639f 2491(define_expand "addsi3"
8406d023 2492 [(set (match_operand:SI 0 "nonimmediate_operand" "")
079e639f 2493 (plus:SI (match_operand:SI 1 "general_operand" "")
2c8ec431 2494 (match_operand:SI 2 "general_src_operand" "")))]
079e639f
JW
2495 ""
2496 "")
2497
e0c17b2d
RS
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.
079e639f 2502(define_insn "*addsi3_internal"
8406d023 2503 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,d,a")
2c8ec431
DL
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
9425fb04 2508 "! TARGET_COLDFIRE"
6cebc6cb
BS
2509 "* return output_addsi3 (operands);"
2510 [(set_attr "flags_valid" "noov,unchanged,unchanged,noov,unchanged")])
e0c17b2d 2511
c47b0cb4 2512(define_insn_and_split "*addsi3_5200"
75df395f
MK
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")))]
9425fb04 2516 "TARGET_COLDFIRE"
c47b0cb4
MK
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
c47b0cb4 2527 case 3:
7279bb22 2528 case 4:
c47b0cb4
MK
2529 return "add%.l %2,%0";
2530
7279bb22 2531 case 5:
c47b0cb4
MK
2532 /* move%.l %2,%0\n\tadd%.l %1,%0 */
2533 return "#";
2534
7279bb22 2535 case 6:
4b3d1177 2536 return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
c47b0cb4 2537
7279bb22 2538 case 7:
4b3d1177 2539 return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0";
c47b0cb4 2540
7279bb22
MK
2541 case 2:
2542 case 8:
4b3d1177 2543 return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
c47b0cb4
MK
2544
2545 default:
2546 gcc_unreachable ();
2547 return "";
2548 }
2549}
7279bb22 2550 "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 5) && !operands_match_p (operands[0], operands[1])"
c47b0cb4
MK
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 ""
75df395f
MK
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")])
e0c17b2d
RS
2560
2561(define_insn ""
8406d023 2562 [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
e0c17b2d
RS
2563 (plus:SI (match_operand:SI 1 "general_operand" "0")
2564 (sign_extend:SI
2c8ec431 2565 (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
9425fb04 2566 "!TARGET_COLDFIRE"
e0c17b2d
RS
2567 "add%.w %2,%0")
2568
2569(define_insn "addhi3"
8406d023 2570 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
e0c17b2d 2571 (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
2c8ec431 2572 (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
9425fb04 2573 "!TARGET_COLDFIRE"
e0c17b2d 2574{
e0c17b2d
RS
2575 if (GET_CODE (operands[2]) == CONST_INT)
2576 {
b4ac57ab
RS
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)
1d8eaa6b 2583 operands[2] = GEN_INT (INTVAL (operands[2]) - 65536);
b4ac57ab 2584
e0c17b2d
RS
2585 if (INTVAL (operands[2]) > 0
2586 && INTVAL (operands[2]) <= 8)
c223cf45 2587 return "addq%.w %2,%0";
e0c17b2d
RS
2588 if (INTVAL (operands[2]) < 0
2589 && INTVAL (operands[2]) >= -8)
2590 {
c5c76735 2591 operands[2] = GEN_INT (- INTVAL (operands[2]));
c223cf45 2592 return "subq%.w %2,%0";
e0c17b2d 2593 }
b8aa7986 2594 /* On the CPU32 it is faster to use two addqw instructions to
6cebc6cb 2595 add a small integer (8 < N <= 16) to a register.
7a1929e1 2596 Likewise for subqw. */
fe95f2f7 2597 if (TUNE_CPU32 && REG_P (operands[0]))
e0c17b2d 2598 {
6db59ad5
RK
2599 if (INTVAL (operands[2]) > 8
2600 && INTVAL (operands[2]) <= 16)
2601 {
1d8eaa6b 2602 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
3b4b85c9 2603 return "addq%.w #8,%0\;addq%.w %2,%0";
6db59ad5
RK
2604 }
2605 if (INTVAL (operands[2]) < -8
2606 && INTVAL (operands[2]) >= -16)
2607 {
c5c76735 2608 operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
3b4b85c9 2609 return "subq%.w #8,%0\;subq%.w %2,%0";
6db59ad5 2610 }
e0c17b2d 2611 }
fe95f2f7 2612 if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
4b3d1177 2613 return MOTOROLA ? "lea (%c2,%0),%0" : "lea %0@(%c2),%0";
b8aa7986 2614 }
c223cf45 2615 return "add%.w %2,%0";
6cebc6cb
BS
2616}
2617 [(set (attr "flags_valid")
2618 (if_then_else (match_operand 0 "address_reg_operand")
2619 (const_string "unchanged")
2620 (const_string "noov")))])
e0c17b2d 2621
988a9e3a
RK
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
e0c17b2d 2628(define_insn ""
8406d023 2629 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
e0c17b2d 2630 (plus:HI (match_dup 0)
2c8ec431 2631 (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
9425fb04 2632 "!TARGET_COLDFIRE"
b4ac57ab 2633{
6cebc6cb 2634 gcc_assert (!ADDRESS_REG_P (operands[0]));
b4ac57ab
RS
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)
1d8eaa6b 2643 operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
b4ac57ab
RS
2644
2645 if (INTVAL (operands[1]) > 0
2646 && INTVAL (operands[1]) <= 8)
c223cf45 2647 return "addq%.w %1,%0";
b4ac57ab
RS
2648 if (INTVAL (operands[1]) < 0
2649 && INTVAL (operands[1]) >= -8)
2650 {
c5c76735 2651 operands[1] = GEN_INT (- INTVAL (operands[1]));
c223cf45 2652 return "subq%.w %1,%0";
b4ac57ab 2653 }
b8aa7986 2654 /* On the CPU32 it is faster to use two addqw instructions to
bc8c44a6 2655 add a small integer (8 < N <= 16) to a register.
7a1929e1 2656 Likewise for subqw. */
fe95f2f7 2657 if (TUNE_CPU32 && REG_P (operands[0]))
b4ac57ab 2658 {
6db59ad5
RK
2659 if (INTVAL (operands[1]) > 8
2660 && INTVAL (operands[1]) <= 16)
2661 {
1d8eaa6b 2662 operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
3b4b85c9 2663 return "addq%.w #8,%0\;addq%.w %1,%0";
6db59ad5
RK
2664 }
2665 if (INTVAL (operands[1]) < -8
2666 && INTVAL (operands[1]) >= -16)
2667 {
c5c76735 2668 operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
3b4b85c9 2669 return "subq%.w #8,%0\;subq%.w %1,%0";
6db59ad5 2670 }
b4ac57ab 2671 }
b8aa7986 2672 }
c223cf45 2673 return "add%.w %1,%0";
6cebc6cb
BS
2674}
2675 [(set_attr "flags_valid" "noov")])
e0c17b2d 2676
988a9e3a 2677(define_insn ""
8406d023 2678 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2c8ec431 2679 (plus:HI (match_operand:HI 1 "general_src_operand" "dn,rmSn")
988a9e3a 2680 (match_dup 0)))]
9425fb04 2681 "!TARGET_COLDFIRE"
b4ac57ab 2682{
6cebc6cb 2683 gcc_assert (!ADDRESS_REG_P (operands[0]));
b4ac57ab
RS
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)
1d8eaa6b 2692 operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
b4ac57ab
RS
2693
2694 if (INTVAL (operands[1]) > 0
2695 && INTVAL (operands[1]) <= 8)
c223cf45 2696 return "addq%.w %1,%0";
b4ac57ab
RS
2697 if (INTVAL (operands[1]) < 0
2698 && INTVAL (operands[1]) >= -8)
2699 {
c5c76735 2700 operands[1] = GEN_INT (- INTVAL (operands[1]));
c223cf45 2701 return "subq%.w %1,%0";
b4ac57ab 2702 }
b8aa7986 2703 /* On the CPU32 it is faster to use two addqw instructions to
bc8c44a6 2704 add a small integer (8 < N <= 16) to a register.
7a1929e1 2705 Likewise for subqw. */
fe95f2f7 2706 if (TUNE_CPU32 && REG_P (operands[0]))
b4ac57ab 2707 {
6db59ad5
RK
2708 if (INTVAL (operands[1]) > 8
2709 && INTVAL (operands[1]) <= 16)
2710 {
1d8eaa6b 2711 operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
3b4b85c9 2712 return "addq%.w #8,%0\;addq%.w %1,%0";
6db59ad5
RK
2713 }
2714 if (INTVAL (operands[1]) < -8
2715 && INTVAL (operands[1]) >= -16)
2716 {
c5c76735 2717 operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
3b4b85c9 2718 return "subq%.w #8,%0\;subq%.w %1,%0";
6db59ad5 2719 }
b4ac57ab 2720 }
b8aa7986 2721 }
c223cf45 2722 return "add%.w %1,%0";
6cebc6cb
BS
2723}
2724 [(set_attr "flags_valid" "noov")])
988a9e3a 2725
e0c17b2d 2726(define_insn "addqi3"
8406d023 2727 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
e0c17b2d 2728 (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
2c8ec431 2729 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
9425fb04 2730 "!TARGET_COLDFIRE"
e0c17b2d 2731{
e0c17b2d
RS
2732 if (GET_CODE (operands[2]) == CONST_INT)
2733 {
b4ac57ab 2734 if (INTVAL (operands[2]) >= 128)
1d8eaa6b 2735 operands[2] = GEN_INT (INTVAL (operands[2]) - 256);
b4ac57ab 2736
e0c17b2d
RS
2737 if (INTVAL (operands[2]) > 0
2738 && INTVAL (operands[2]) <= 8)
c223cf45 2739 return "addq%.b %2,%0";
e0c17b2d
RS
2740 if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
2741 {
c5c76735 2742 operands[2] = GEN_INT (- INTVAL (operands[2]));
c223cf45 2743 return "subq%.b %2,%0";
e0c17b2d
RS
2744 }
2745 }
c223cf45 2746 return "add%.b %2,%0";
6cebc6cb
BS
2747}
2748 [(set_attr "flags_valid" "noov")])
e0c17b2d
RS
2749
2750(define_insn ""
8406d023 2751 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
e0c17b2d 2752 (plus:QI (match_dup 0)
2c8ec431 2753 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
9425fb04 2754 "!TARGET_COLDFIRE"
b4ac57ab 2755{
b4ac57ab
RS
2756 if (GET_CODE (operands[1]) == CONST_INT)
2757 {
2758 if (INTVAL (operands[1]) >= 128)
1d8eaa6b 2759 operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
b4ac57ab
RS
2760
2761 if (INTVAL (operands[1]) > 0
2762 && INTVAL (operands[1]) <= 8)
c223cf45 2763 return "addq%.b %1,%0";
b4ac57ab
RS
2764 if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2765 {
c5c76735 2766 operands[1] = GEN_INT (- INTVAL (operands[1]));
c223cf45 2767 return "subq%.b %1,%0";
b4ac57ab
RS
2768 }
2769 }
c223cf45
BI
2770 return "add%.b %1,%0";
2771})
e0c17b2d 2772
988a9e3a 2773(define_insn ""
8406d023 2774 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2c8ec431 2775 (plus:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
988a9e3a 2776 (match_dup 0)))]
9425fb04 2777 "!TARGET_COLDFIRE"
b4ac57ab 2778{
b4ac57ab
RS
2779 if (GET_CODE (operands[1]) == CONST_INT)
2780 {
2781 if (INTVAL (operands[1]) >= 128)
1d8eaa6b 2782 operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
b4ac57ab
RS
2783
2784 if (INTVAL (operands[1]) > 0
2785 && INTVAL (operands[1]) <= 8)
c223cf45 2786 return "addq%.b %1,%0";
b4ac57ab
RS
2787 if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2788 {
c5c76735 2789 operands[1] = GEN_INT (- INTVAL (operands[1]));
c223cf45 2790 return "subq%.b %1,%0";
b4ac57ab
RS
2791 }
2792 }
c223cf45
BI
2793 return "add%.b %1,%0";
2794})
988a9e3a 2795
dcc21c4c
PB
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"
e0c17b2d
RS
2801 "")
2802
dcc21c4c
PB
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")))]
22859ae8 2807 "TARGET_68881"
96fcacb7
MK
2808 "f<FP:round>add%.l %2,%0"
2809 [(set_attr "type" "falu")
2810 (set_attr "opy" "2")])
22859ae8 2811
dcc21c4c
PB
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")))]
22859ae8 2816 "TARGET_68881"
96fcacb7
MK
2817 "f<FP:round>add%.w %2,%0"
2818 [(set_attr "type" "falu")
2819 (set_attr "opy" "2")])
22859ae8 2820
dcc21c4c
PB
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")))]
22859ae8 2825 "TARGET_68881"
96fcacb7
MK
2826 "f<FP:round>add%.b %2,%0"
2827 [(set_attr "type" "falu")
2828 (set_attr "opy" "2")])
22859ae8 2829
dcc21c4c
PB
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>")))]
e0c17b2d 2834 "TARGET_68881"
e0c17b2d 2835{
dcc21c4c
PB
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";
96fcacb7
MK
2839}
2840 [(set_attr "type" "falu")
2841 (set_attr "opy" "2")])
e0c17b2d 2842
dcc21c4c
PB
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"
e0c17b2d 2848{
dcc21c4c 2849 if (FP_REG_P (operands[2]))
17e143a1
RS
2850 return "f<FP:prec>add%.d %2,%0";
2851 return "f<FP:prec>add%.<FP:prec> %2,%0";
c47b0cb4 2852}
96fcacb7
MK
2853 [(set_attr "type" "falu")
2854 (set_attr "opy" "2")])
e0c17b2d
RS
2855\f
2856;; subtract instructions
2857
f8e0b2ea 2858(define_insn "subdi_sexthishl32"
8406d023 2859 [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
935fb288
RK
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"))
801aee46 2862 (const_int 32))))
935fb288 2863 (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
9425fb04 2864 "!TARGET_COLDFIRE"
801aee46 2865{
f8e0b2ea 2866 if (ADDRESS_REG_P (operands[0]))
c223cf45 2867 return "sub%.w %2,%0";
935fb288 2868 else if (ADDRESS_REG_P (operands[3]))
c223cf45 2869 return "move%.w %2,%3\;sub%.l %3,%0";
f8e0b2ea 2870 else
c223cf45
BI
2871 return "move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0";
2872})
801aee46
RK
2873
2874(define_insn "subdi_dishl32"
8406d023 2875 [(set (match_operand:DI 0 "nonimmediate_operand" "+ro")
801aee46 2876 (minus:DI (match_dup 0)
31e033e9 2877 (ashift:DI (match_operand:DI 1 "general_operand" "ro")
801aee46
RK
2878 (const_int 32))))]
2879 ""
801aee46 2880{
31e033e9 2881 if (GET_CODE (operands[1]) == REG)
1d8eaa6b 2882 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
31e033e9 2883 else
b72f00af 2884 operands[1] = adjust_address (operands[1], SImode, 4);
c223cf45 2885 return "sub%.l %1,%0";
c47b0cb4 2886}
96fcacb7 2887 [(set_attr "type" "alu_l")])
801aee46 2888
055c1584 2889(define_insn "subdi3"
b6d2f42e
RS
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"))]
801aee46 2894 ""
801aee46 2895{
055c1584 2896 if (DATA_REG_P (operands[0]))
31e033e9 2897 {
055c1584 2898 if (DATA_REG_P (operands[2]))
c223cf45 2899 return "sub%.l %R2,%R0\;subx%.l %2,%0";
055c1584
RK
2900 else if (GET_CODE (operands[2]) == MEM
2901 && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
2902 {
c223cf45 2903 return "move%.l %2,%3\;sub%.l %2,%R0\;subx%.l %3,%0";
055c1584
RK
2904 }
2905 else
2906 {
c5c76735 2907 rtx high, low;
7878eae7 2908 rtx xoperands[2];
c5c76735 2909
055c1584 2910 if (GET_CODE (operands[2]) == REG)
5f24901c 2911 {
c5c76735
JL
2912 low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2913 high = operands[2];
5f24901c 2914 }
c5c76735
JL
2915 else if (CONSTANT_P (operands[2]))
2916 split_double (operands[2], &high, &low);
2917 else
5f24901c 2918 {
b72f00af 2919 low = adjust_address (operands[2], SImode, 4);
c5c76735 2920 high = operands[2];
5f24901c 2921 }
c5c76735
JL
2922
2923 operands[1] = low, operands[2] = high;
7878eae7 2924 xoperands[0] = operands[3];
436bf9fb
AS
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];
c5c76735 2930
7878eae7
AS
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)
c223cf45 2935 return "subq%.l %1,%R0\;subx%.l %3,%0";
7878eae7
AS
2936 else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2937 {
2938 operands[1] = GEN_INT (-INTVAL (operands[1]));
c223cf45 2939 return "addq%.l %1,%R0\;addx%.l %3,%0";
7878eae7
AS
2940 }
2941 }
c223cf45 2942 return "sub%.l %1,%R0\;subx%.l %3,%0";
055c1584 2943 }
31e033e9 2944 }
4761e388 2945 else
801aee46 2946 {
4761e388 2947 gcc_assert (GET_CODE (operands[0]) == MEM);
055c1584
RK
2948 if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2949 {
1d8eaa6b 2950 operands[1]
0a81f074
RS
2951 = gen_rtx_MEM (SImode, plus_constant (Pmode,
2952 XEXP (operands[0], 0), -8));
c223cf45 2953 return "move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1";
055c1584
RK
2954 }
2955 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2956 {
2957 operands[1] = XEXP(operands[0], 0);
c223cf45 2958 return "sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1";
055c1584
RK
2959 }
2960 else
2961 {
b72f00af 2962 operands[1] = adjust_address (operands[0], SImode, 4);
c223cf45 2963 return "sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0";
055c1584 2964 }
801aee46 2965 }
6cebc6cb
BS
2966}
2967 [(set (attr "flags_valid")
2968 (if_then_else (match_operand 0 "register_operand")
2969 (const_string "noov")
2970 (const_string "no")))])
54dad0c2 2971
e0c17b2d 2972(define_insn "subsi3"
6cebc6cb
BS
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")))]
e0c17b2d 2976 ""
c47b0cb4 2977 "@
6cebc6cb 2978 subq%.l %2, %0
c47b0cb4
MK
2979 subq%.l %2, %0
2980 sub%.l %2,%0
2981 sub%.l %2,%0
2982 sub%.l %2,%0"
6cebc6cb
BS
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")])
e0c17b2d
RS
2986
2987(define_insn ""
8406d023 2988 [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
e0c17b2d
RS
2989 (minus:SI (match_operand:SI 1 "general_operand" "0")
2990 (sign_extend:SI
2c8ec431 2991 (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
9425fb04 2992 "!TARGET_COLDFIRE"
e0c17b2d
RS
2993 "sub%.w %2,%0")
2994
2995(define_insn "subhi3"
8406d023 2996 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
e0c17b2d 2997 (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2c8ec431 2998 (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
9425fb04 2999 "!TARGET_COLDFIRE"
6cebc6cb
BS
3000 "sub%.w %2,%0"
3001 [(set_attr "flags_valid" "noov")])
e0c17b2d
RS
3002
3003(define_insn ""
8406d023 3004 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
e0c17b2d 3005 (minus:HI (match_dup 0)
2c8ec431 3006 (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
9425fb04 3007 "!TARGET_COLDFIRE"
6cebc6cb
BS
3008 "sub%.w %1,%0"
3009 [(set_attr "flags_valid" "noov")])
e0c17b2d
RS
3010
3011(define_insn "subqi3"
8406d023 3012 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
e0c17b2d 3013 (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2c8ec431 3014 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
9425fb04 3015 "!TARGET_COLDFIRE"
6cebc6cb
BS
3016 "sub%.b %2,%0"
3017 [(set_attr "flags_valid" "noov")])
e0c17b2d
RS
3018
3019(define_insn ""
8406d023 3020 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
e0c17b2d 3021 (minus:QI (match_dup 0)
2c8ec431 3022 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
9425fb04 3023 "!TARGET_COLDFIRE"
6cebc6cb
BS
3024 "sub%.b %1,%0"
3025 [(set_attr "flags_valid" "noov")])
e0c17b2d 3026
dcc21c4c
PB
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"
e0c17b2d
RS
3032 "")
3033
dcc21c4c
PB
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"))))]
22859ae8 3038 "TARGET_68881"
96fcacb7
MK
3039 "f<FP:round>sub%.l %2,%0"
3040 [(set_attr "type" "falu")
3041 (set_attr "opy" "2")])
22859ae8 3042
dcc21c4c
PB
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"))))]
22859ae8 3047 "TARGET_68881"
96fcacb7
MK
3048 "f<FP:round>sub%.w %2,%0"
3049 [(set_attr "type" "falu")
3050 (set_attr "opy" "2")])
22859ae8 3051
dcc21c4c
PB
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"))))]
22859ae8 3056 "TARGET_68881"
96fcacb7
MK
3057 "f<FP:round>sub%.b %2,%0"
3058 [(set_attr "type" "falu")
3059 (set_attr "opy" "2")])
22859ae8 3060
dcc21c4c
PB
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>")))]
e0c17b2d 3065 "TARGET_68881"
e0c17b2d 3066{
dcc21c4c
PB
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";
96fcacb7
MK
3070}
3071 [(set_attr "type" "falu")
3072 (set_attr "opy" "2")])
e0c17b2d 3073
dcc21c4c
PB
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"
e0c17b2d 3079{
dcc21c4c 3080 if (FP_REG_P (operands[2]))
17e143a1
RS
3081 return "f<FP:prec>sub%.d %2,%0";
3082 return "f<FP:prec>sub%.<FP:prec> %2,%0";
c47b0cb4 3083}
96fcacb7
MK
3084 [(set_attr "type" "falu")
3085 (set_attr "opy" "2")])
e0c17b2d
RS
3086\f
3087;; multiply instructions
3088
3089(define_insn "mulhi3"
8406d023 3090 [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
e0c17b2d 3091 (mult:HI (match_operand:HI 1 "general_operand" "%0")
2c8ec431 3092 (match_operand:HI 2 "general_src_operand" "dmSn")))]
e0c17b2d 3093 ""
4b3d1177
KH
3094{
3095 return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
3096}
96fcacb7 3097 [(set_attr "type" "mul_w")
c47b0cb4 3098 (set_attr "opy" "2")])
e0c17b2d
RS
3099
3100(define_insn "mulhisi3"
8406d023 3101 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
e0c17b2d
RS
3102 (mult:SI (sign_extend:SI
3103 (match_operand:HI 1 "nonimmediate_operand" "%0"))
3104 (sign_extend:SI
2c8ec431 3105 (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
e0c17b2d 3106 ""
4b3d1177
KH
3107{
3108 return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
3109}
96fcacb7 3110 [(set_attr "type" "mul_w")
c47b0cb4 3111 (set_attr "opy" "2")])
e0c17b2d 3112
c47b0cb4 3113(define_insn "*mulhisisi3_s"
8406d023 3114 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
e0c17b2d
RS
3115 (mult:SI (sign_extend:SI
3116 (match_operand:HI 1 "nonimmediate_operand" "%0"))
3117 (match_operand:SI 2 "const_int_operand" "n")))]
008660af 3118 "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
4b3d1177
KH
3119{
3120 return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
3121}
96fcacb7 3122 [(set_attr "type" "mul_w")
c47b0cb4 3123 (set_attr "opy" "2")])
e0c17b2d 3124
a139ec25 3125(define_expand "mulsi3"
8406d023 3126 [(set (match_operand:SI 0 "nonimmediate_operand" "")
a139ec25
RK
3127 (mult:SI (match_operand:SI 1 "general_operand" "")
3128 (match_operand:SI 2 "general_operand" "")))]
9425fb04 3129 "TARGET_68020 || TARGET_COLDFIRE"
a139ec25
RK
3130 "")
3131
c47b0cb4 3132(define_insn "*mulsi3_68020"
8406d023 3133 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
e0c17b2d 3134 (mult:SI (match_operand:SI 1 "general_operand" "%0")
2c8ec431
DL
3135 (match_operand:SI 2 "general_src_operand" "dmSTK")))]
3136
a139ec25 3137 "TARGET_68020"
c47b0cb4 3138 "muls%.l %2,%0"
96fcacb7 3139 [(set_attr "type" "mul_l")
c47b0cb4 3140 (set_attr "opy" "2")])
a139ec25 3141
c47b0cb4 3142(define_insn "*mulsi3_cf"
8406d023 3143 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
a139ec25 3144 (mult:SI (match_operand:SI 1 "general_operand" "%0")
b1016f1c 3145 (match_operand:SI 2 "general_operand" "d<Q>")))]
9425fb04 3146 "TARGET_COLDFIRE"
c47b0cb4 3147 "muls%.l %2,%0"
96fcacb7 3148 [(set_attr "type" "mul_l")
c47b0cb4 3149 (set_attr "opy" "2")])
e0c17b2d
RS
3150
3151(define_insn "umulhisi3"
8406d023 3152 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
e0c17b2d
RS
3153 (mult:SI (zero_extend:SI
3154 (match_operand:HI 1 "nonimmediate_operand" "%0"))
3155 (zero_extend:SI
2c8ec431 3156 (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
e0c17b2d 3157 ""
4b3d1177
KH
3158{
3159 return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
3160}
96fcacb7 3161 [(set_attr "type" "mul_w")
c47b0cb4 3162 (set_attr "opy" "2")])
e0c17b2d 3163
c47b0cb4 3164(define_insn "*mulhisisi3_z"
8406d023 3165 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
e0c17b2d
RS
3166 (mult:SI (zero_extend:SI
3167 (match_operand:HI 1 "nonimmediate_operand" "%0"))
3168 (match_operand:SI 2 "const_int_operand" "n")))]
5e636986 3169 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
4b3d1177
KH
3170{
3171 return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
3172}
96fcacb7 3173 [(set_attr "type" "mul_w")
c47b0cb4 3174 (set_attr "opy" "2")])
e0c17b2d
RS
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
ddef6bc7 3181 [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
5e636986 3182 (mult:SI (match_operand:SI 1 "register_operand" "")
f56e86bd 3183 (match_operand:SI 2 "register_operand" "")))
e0c17b2d 3184 (set (subreg:SI (match_dup 0) 0)
5e636986
RS
3185 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3186 (zero_extend:DI (match_dup 2)))
3187 (const_int 32))))])]
fe95f2f7 3188 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
e0c17b2d
RS
3189 "")
3190
3191(define_insn ""
3192 [(set (match_operand:SI 0 "register_operand" "=d")
5e636986
RS
3193 (mult:SI (match_operand:SI 1 "register_operand" "%0")
3194 (match_operand:SI 2 "nonimmediate_operand" "dm")))
e0c17b2d 3195 (set (match_operand:SI 3 "register_operand" "=d")
5e636986
RS
3196 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3197 (zero_extend:DI (match_dup 2)))
3198 (const_int 32))))]
fe95f2f7 3199 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
e0c17b2d
RS
3200 "mulu%.l %2,%3:%0")
3201
aef1522b
RS
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.
58ff42b3
TG
3206(define_insn ""
3207 [(set (match_operand:SI 0 "register_operand" "=d")
5e636986 3208 (mult:SI (match_operand:SI 1 "register_operand" "%0")
aef1522b 3209 (match_operand:SI 2 "const_int_operand" "n")))
58ff42b3 3210 (set (match_operand:SI 3 "register_operand" "=d")
5e636986
RS
3211 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3212 (match_dup 2))
3213 (const_int 32))))]
fe95f2f7 3214 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE
aef1522b 3215 && (unsigned) INTVAL (operands[2]) <= 0x7fffffff"
58ff42b3
TG
3216 "mulu%.l %2,%3:%0")
3217
e0c17b2d
RS
3218(define_expand "mulsidi3"
3219 [(parallel
ddef6bc7 3220 [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
5e636986 3221 (mult:SI (match_operand:SI 1 "register_operand" "")
f56e86bd 3222 (match_operand:SI 2 "register_operand" "")))
e0c17b2d 3223 (set (subreg:SI (match_dup 0) 0)
f06533b5
RS
3224 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3225 (sign_extend:DI (match_dup 2)))
3226 (const_int 32))))])]
fe95f2f7 3227 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
e0c17b2d
RS
3228 "")
3229
3230(define_insn ""
3231 [(set (match_operand:SI 0 "register_operand" "=d")
5e636986
RS
3232 (mult:SI (match_operand:SI 1 "register_operand" "%0")
3233 (match_operand:SI 2 "nonimmediate_operand" "dm")))
e0c17b2d 3234 (set (match_operand:SI 3 "register_operand" "=d")
f06533b5
RS
3235 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3236 (sign_extend:DI (match_dup 2)))
3237 (const_int 32))))]
fe95f2f7 3238 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
e0c17b2d
RS
3239 "muls%.l %2,%3:%0")
3240
58ff42b3
TG
3241(define_insn ""
3242 [(set (match_operand:SI 0 "register_operand" "=d")
5e636986 3243 (mult:SI (match_operand:SI 1 "register_operand" "%0")
97660e20 3244 (match_operand:SI 2 "const_int_operand" "n")))
58ff42b3 3245 (set (match_operand:SI 3 "register_operand" "=d")
f06533b5
RS
3246 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3247 (match_dup 2))
3248 (const_int 32))))]
fe95f2f7 3249 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
58ff42b3
TG
3250 "muls%.l %2,%3:%0")
3251
ca300626
TG
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))])]
fe95f2f7 3261 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
ca300626
TG
3262{
3263 operands[3] = gen_reg_rtx (SImode);
97660e20
RH
3264
3265 if (GET_CODE (operands[2]) == CONST_INT)
ca300626 3266 {
97660e20
RH
3267 operands[2] = immed_double_const (INTVAL (operands[2]) & 0xffffffff,
3268 0, DImode);
3269
28d29b39 3270 /* We have to adjust the operand order for the matching constraints. */
ca300626
TG
3271 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[3],
3272 operands[1], operands[2]));
3273 DONE;
3274 }
428511bb 3275})
ca300626
TG
3276
3277(define_insn ""
b812f401 3278 [(set (match_operand:SI 0 "register_operand" "=d")
ca300626
TG
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"))]
fe95f2f7 3285 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
6cebc6cb 3286 "mulu%.l %3,%0:%1")
ca300626
TG
3287
3288(define_insn "const_umulsi3_highpart"
b812f401 3289 [(set (match_operand:SI 0 "register_operand" "=d")
ca300626
TG
3290 (truncate:SI
3291 (lshiftrt:DI
3292 (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "1"))
97660e20 3293 (match_operand:DI 3 "const_uint32_operand" "n"))
ca300626
TG
3294 (const_int 32))))
3295 (clobber (match_operand:SI 1 "register_operand" "=d"))]
fe95f2f7 3296 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
6cebc6cb 3297 "mulu%.l %3,%0:%1")
ca300626
TG
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))])]
fe95f2f7 3308 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
ca300626
TG
3309{
3310 operands[3] = gen_reg_rtx (SImode);
97660e20 3311 if (GET_CODE (operands[2]) == CONST_INT)
ca300626 3312 {
28d29b39 3313 /* We have to adjust the operand order for the matching constraints. */
ca300626
TG
3314 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[3],
3315 operands[1], operands[2]));
3316 DONE;
3317 }
428511bb 3318})
ca300626
TG
3319
3320(define_insn ""
b812f401 3321 [(set (match_operand:SI 0 "register_operand" "=d")
ca300626
TG
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"))]
fe95f2f7 3328 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
6cebc6cb 3329 "muls%.l %3,%0:%1")
ca300626
TG
3330
3331(define_insn "const_smulsi3_highpart"
b812f401 3332 [(set (match_operand:SI 0 "register_operand" "=d")
ca300626
TG
3333 (truncate:SI
3334 (lshiftrt:DI
3335 (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1"))
97660e20 3336 (match_operand:DI 3 "const_sint32_operand" "n"))
ca300626
TG
3337 (const_int 32))))
3338 (clobber (match_operand:SI 1 "register_operand" "=d"))]
fe95f2f7 3339 "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
6cebc6cb 3340 "muls%.l %3,%0:%1")
ca300626 3341
dcc21c4c
PB
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"
e0c17b2d
RS
3347 "")
3348
dcc21c4c
PB
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")))]
22859ae8 3353 "TARGET_68881"
dcc21c4c 3354{
b101567e 3355 return TARGET_68040
dcc21c4c
PB
3356 ? "f<FP:round>mul%.l %2,%0"
3357 : "f<FP:round_mul>mul%.l %2,%0";
96fcacb7
MK
3358}
3359 [(set_attr "type" "fmul")
3360 (set_attr "opy" "2")])
22859ae8 3361
dcc21c4c
PB
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")))]
22859ae8 3366 "TARGET_68881"
dcc21c4c 3367{
b101567e 3368 return TARGET_68040
dcc21c4c
PB
3369 ? "f<FP:round>mul%.w %2,%0"
3370 : "f<FP:round_mul>mul%.w %2,%0";
96fcacb7
MK
3371}
3372 [(set_attr "type" "fmul")
3373 (set_attr "opy" "2")])
22859ae8 3374
dcc21c4c
PB
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")))]
22859ae8 3379 "TARGET_68881"
dcc21c4c 3380{
b101567e 3381 return TARGET_68040
dcc21c4c
PB
3382 ? "f<FP:round>mul%.b %2,%0"
3383 : "f<FP:round_mul>mul%.b %2,%0";
96fcacb7
MK
3384}
3385 [(set_attr "type" "fmul")
3386 (set_attr "opy" "2")])
22859ae8 3387
dcc21c4c 3388(define_insn "muldf_68881"
8406d023 3389 [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
e0c17b2d
RS
3390 (mult:DF (match_operand:DF 1 "general_operand" "%0")
3391 (match_operand:DF 2 "general_operand" "fmG")))]
3392 "TARGET_68881"
e0c17b2d
RS
3393{
3394 if (GET_CODE (operands[2]) == CONST_DOUBLE
9cf106c8 3395 && floating_exact_log2 (operands[2]) && !TUNE_68040_60)
e0c17b2d
RS
3396 {
3397 int i = floating_exact_log2 (operands[2]);
1d8eaa6b 3398 operands[2] = GEN_INT (i);
c223cf45 3399 return "fscale%.l %2,%0";
e0c17b2d
RS
3400 }
3401 if (REG_P (operands[2]))
c223cf45
BI
3402 return "f%&mul%.x %2,%0";
3403 return "f%&mul%.d %f2,%0";
3404})
e0c17b2d 3405
dcc21c4c 3406(define_insn "mulsf_68881"
8406d023 3407 [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
e0c17b2d
RS
3408 (mult:SF (match_operand:SF 1 "general_operand" "%0")
3409 (match_operand:SF 2 "general_operand" "fdmF")))]
3410 "TARGET_68881"
e0c17b2d 3411{
dcc21c4c 3412 if (FP_REG_P (operands[2]))
b101567e 3413 return (TARGET_68040
c223cf45
BI
3414 ? "fsmul%.x %2,%0"
3415 : "fsglmul%.x %2,%0");
b101567e 3416 return (TARGET_68040
c223cf45
BI
3417 ? "fsmul%.s %f2,%0"
3418 : "fsglmul%.s %f2,%0");
3419})
e0c17b2d 3420
dcc21c4c
PB
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")))]
22859ae8 3425 "TARGET_68881"
dcc21c4c
PB
3426{
3427 return "fmul%.x %f2,%0";
3428})
22859ae8 3429
dcc21c4c
PB
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"
e0c17b2d 3435{
dcc21c4c
PB
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";
c47b0cb4 3439}
96fcacb7
MK
3440 [(set_attr "type" "fmul")
3441 (set_attr "opy" "2")])
dcc21c4c
PB
3442\f
3443;; divide instructions
e0c17b2d 3444
dcc21c4c
PB
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"
e0c17b2d
RS
3450 "")
3451
dcc21c4c
PB
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"))))]
22859ae8 3456 "TARGET_68881"
22859ae8 3457{
b101567e 3458 return TARGET_68040
dcc21c4c
PB
3459 ? "f<FP:round>div%.l %2,%0"
3460 : "f<FP:round_mul>div%.l %2,%0";
c223cf45 3461})
22859ae8 3462
dcc21c4c
PB
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"))))]
22859ae8 3467 "TARGET_68881"
22859ae8 3468{
b101567e 3469 return TARGET_68040
dcc21c4c
PB
3470 ? "f<FP:round>div%.w %2,%0"
3471 : "f<FP:round_mul>div%.w %2,%0";
c223cf45 3472})
22859ae8 3473
dcc21c4c
PB
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"))))]
22859ae8 3478 "TARGET_68881"
22859ae8 3479{
b101567e 3480 return TARGET_68040
dcc21c4c
PB
3481 ? "f<FP:round>div%.b %2,%0"
3482 : "f<FP:round_mul>div%.b %2,%0";
c223cf45 3483})
22859ae8 3484
dcc21c4c
PB
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>")))]
e0c17b2d 3489 "TARGET_68881"
e0c17b2d 3490{
dcc21c4c 3491 if (FP_REG_P (operands[2]))
b101567e 3492 return (TARGET_68040
dcc21c4c
PB
3493 ? "f<FP:round>div%.x %2,%0"
3494 : "f<FP:round_mul>div%.x %2,%0");
b101567e 3495 return (TARGET_68040
dcc21c4c
PB
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";
c47b0cb4 3509}
96fcacb7
MK
3510 [(set_attr "type" "fdiv")
3511 (set_attr "opy" "2")])
e0c17b2d
RS
3512\f
3513;; Remainder instructions.
3514
9425fb04
PB
3515(define_expand "divmodsi4"
3516 [(parallel
6cebc6cb 3517 [(set (match_operand:SI 0 "register_operand" "")
9425fb04
PB
3518 (div:SI (match_operand:SI 1 "general_operand" "")
3519 (match_operand:SI 2 "general_src_operand" "")))
6cebc6cb 3520 (set (match_operand:SI 3 "register_operand" "")
9425fb04
PB
3521 (mod:SI (match_dup 1) (match_dup 2)))])]
3522 "TARGET_68020 || TARGET_CF_HWDIV"
3523 "")
3524
3525(define_insn ""
6cebc6cb 3526 [(set (match_operand:SI 0 "register_operand" "=d")
9425fb04
PB
3527 (div:SI (match_operand:SI 1 "general_operand" "0")
3528 (match_operand:SI 2 "general_src_operand" "d<Q>U")))
6cebc6cb 3529 (set (match_operand:SI 3 "register_operand" "=&d")
9425fb04
PB
3530 (mod:SI (match_dup 1) (match_dup 2)))]
3531 "TARGET_CF_HWDIV"
9425fb04
PB
3532{
3533 if (find_reg_note (insn, REG_UNUSED, operands[3]))
c223cf45 3534 return "divs%.l %2,%0";
9425fb04 3535 else if (find_reg_note (insn, REG_UNUSED, operands[0]))
c223cf45 3536 return "rems%.l %2,%3:%0";
9425fb04 3537 else
c223cf45 3538 return "rems%.l %2,%3:%0\;divs%.l %2,%0";
96fcacb7
MK
3539}
3540 [(set_attr "type" "div_l")
3541 (set_attr "opy" "2")])
9425fb04
PB
3542
3543(define_insn ""
6cebc6cb 3544 [(set (match_operand:SI 0 "register_operand" "=d")
e0c17b2d 3545 (div:SI (match_operand:SI 1 "general_operand" "0")
2c8ec431 3546 (match_operand:SI 2 "general_src_operand" "dmSTK")))
6cebc6cb 3547 (set (match_operand:SI 3 "register_operand" "=d")
e0c17b2d 3548 (mod:SI (match_dup 1) (match_dup 2)))]
9425fb04 3549 "TARGET_68020"
e0c17b2d
RS
3550{
3551 if (find_reg_note (insn, REG_UNUSED, operands[3]))
c223cf45 3552 return "divs%.l %2,%0";
e0c17b2d 3553 else
c223cf45
BI
3554 return "divsl%.l %2,%3:%0";
3555})
e0c17b2d 3556
9425fb04
PB
3557(define_expand "udivmodsi4"
3558 [(parallel
6cebc6cb 3559 [(set (match_operand:SI 0 "register_operand" "=d")
9425fb04
PB
3560 (udiv:SI (match_operand:SI 1 "general_operand" "0")
3561 (match_operand:SI 2 "general_src_operand" "dmSTK")))
6cebc6cb 3562 (set (match_operand:SI 3 "register_operand" "=d")
9425fb04
PB
3563 (umod:SI (match_dup 1) (match_dup 2)))])]
3564 "TARGET_68020 || TARGET_CF_HWDIV"
3565 "")
3566
3567(define_insn ""
6cebc6cb 3568 [(set (match_operand:SI 0 "register_operand" "=d")
9425fb04
PB
3569 (udiv:SI (match_operand:SI 1 "general_operand" "0")
3570 (match_operand:SI 2 "general_src_operand" "d<Q>U")))
6cebc6cb 3571 (set (match_operand:SI 3 "register_operand" "=&d")
9425fb04
PB
3572 (umod:SI (match_dup 1) (match_dup 2)))]
3573 "TARGET_CF_HWDIV"
9425fb04
PB
3574{
3575 if (find_reg_note (insn, REG_UNUSED, operands[3]))
c223cf45 3576 return "divu%.l %2,%0";
9425fb04 3577 else if (find_reg_note (insn, REG_UNUSED, operands[0]))
c223cf45 3578 return "remu%.l %2,%3:%0";
9425fb04 3579 else
c223cf45 3580 return "remu%.l %2,%3:%0\;divu%.l %2,%0";
96fcacb7
MK
3581}
3582 [(set_attr "type" "div_l")
3583 (set_attr "opy" "2")])
9425fb04
PB
3584
3585(define_insn ""
6cebc6cb 3586 [(set (match_operand:SI 0 "register_operand" "=d")
e0c17b2d 3587 (udiv:SI (match_operand:SI 1 "general_operand" "0")
2c8ec431 3588 (match_operand:SI 2 "general_src_operand" "dmSTK")))
6cebc6cb 3589 (set (match_operand:SI 3 "register_operand" "=d")
e0c17b2d 3590 (umod:SI (match_dup 1) (match_dup 2)))]
9425fb04 3591 "TARGET_68020 && !TARGET_COLDFIRE"
e0c17b2d
RS
3592{
3593 if (find_reg_note (insn, REG_UNUSED, operands[3]))
c223cf45 3594 return "divu%.l %2,%0";
e0c17b2d 3595 else
c223cf45
BI
3596 return "divul%.l %2,%3:%0";
3597})
2ac53349
RK
3598
3599(define_insn "divmodhi4"
6cebc6cb 3600 [(set (match_operand:HI 0 "register_operand" "=d")
2ac53349 3601 (div:HI (match_operand:HI 1 "general_operand" "0")
2c8ec431 3602 (match_operand:HI 2 "general_src_operand" "dmSKT")))
6cebc6cb 3603 (set (match_operand:HI 3 "register_operand" "=d")
2ac53349 3604 (mod:HI (match_dup 1) (match_dup 2)))]
9425fb04 3605 "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
2ac53349 3606{
4b3d1177
KH
3607 output_asm_insn (MOTOROLA ?
3608 "ext%.l %0\;divs%.w %2,%0" :
3609 "extl %0\;divs %2,%0",
3610 operands);
2ac53349 3611 if (!find_reg_note(insn, REG_UNUSED, operands[3]))
6cebc6cb 3612 return "move%.l %0,%3\;swap %3";
2ac53349 3613 else
c223cf45
BI
3614 return "";
3615})
2ac53349
RK
3616
3617(define_insn "udivmodhi4"
6cebc6cb 3618 [(set (match_operand:HI 0 "register_operand" "=d")
2ac53349 3619 (udiv:HI (match_operand:HI 1 "general_operand" "0")
2c8ec431 3620 (match_operand:HI 2 "general_src_operand" "dmSKT")))
6cebc6cb 3621 (set (match_operand:HI 3 "register_operand" "=d")
2ac53349 3622 (umod:HI (match_dup 1) (match_dup 2)))]
9425fb04 3623 "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
2ac53349 3624{
59c92f76 3625 if (ISA_HAS_MVS_MVZ)
4b3d1177
KH
3626 output_asm_insn (MOTOROLA ?
3627 "mvz%.w %0,%0\;divu%.w %2,%0" :
3628 "mvz%.w %0,%0\;divu %2,%0",
3629 operands);
5e04daf3 3630 else
4b3d1177
KH
3631 output_asm_insn (MOTOROLA ?
3632 "and%.l #0xFFFF,%0\;divu%.w %2,%0" :
3633 "and%.l #0xFFFF,%0\;divu %2,%0",
3634 operands);
5e04daf3 3635
2ac53349 3636 if (!find_reg_note(insn, REG_UNUSED, operands[3]))
6cebc6cb 3637 return "move%.l %0,%3\;swap %3";
2ac53349 3638 else
c223cf45
BI
3639 return "";
3640})
e0c17b2d
RS
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
b4ac57ab 3646;; can't allocate pseudos into it.
00523ef2
RK
3647
3648(define_expand "andsi3"
2c8ec431
DL
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" "")))]
e0c17b2d 3652 ""
00523ef2
RK
3653 "")
3654
9652c531
RZ
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
00523ef2
RK
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")
2c8ec431 3668 (match_operand:SI 2 "general_src_operand" "dKT,dmSM")))]
9425fb04 3669 "!TARGET_COLDFIRE"
e0c17b2d 3670{
5f24901c 3671 return output_andsi3 (operands);
6cebc6cb
BS
3672}
3673 [(set_attr "flags_valid" "set")])
e0c17b2d 3674
00523ef2
RK
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")
2c8ec431 3678 (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
9425fb04 3679 "TARGET_COLDFIRE"
5e04daf3 3680{
59c92f76 3681 if (ISA_HAS_MVS_MVZ
986e74d5 3682 && DATA_REG_P (operands[0])
5e04daf3
PB
3683 && GET_CODE (operands[2]) == CONST_INT)
3684 {
3685 if (INTVAL (operands[2]) == 0x000000ff)
428511bb 3686 return "mvz%.b %0,%0";
5e04daf3 3687 else if (INTVAL (operands[2]) == 0x0000ffff)
428511bb 3688 return "mvz%.w %0,%0";
5e04daf3
PB
3689 }
3690 return output_andsi3 (operands);
3691})
00523ef2 3692
e0c17b2d 3693(define_insn "andhi3"
8406d023 3694 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
e0c17b2d 3695 (and:HI (match_operand:HI 1 "general_operand" "%0,0")
2c8ec431 3696 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
9425fb04 3697 "!TARGET_COLDFIRE"
6cebc6cb
BS
3698 "and%.w %2,%0"
3699 [(set_attr "flags_valid" "yes")])
e0c17b2d 3700
988a9e3a 3701(define_insn ""
8406d023 3702 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
988a9e3a 3703 (and:HI (match_dup 0)
2c8ec431 3704 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
9425fb04 3705 "!TARGET_COLDFIRE"
6cebc6cb
BS
3706 "and%.w %1,%0"
3707 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
3708
3709(define_insn ""
8406d023 3710 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2c8ec431 3711 (and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
988a9e3a 3712 (match_dup 0)))]
9425fb04 3713 "!TARGET_COLDFIRE"
6cebc6cb
BS
3714 "and%.w %1,%0"
3715 [(set_attr "flags_valid" "yes")])
988a9e3a 3716
e0c17b2d 3717(define_insn "andqi3"
8406d023 3718 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
e0c17b2d 3719 (and:QI (match_operand:QI 1 "general_operand" "%0,0")
2c8ec431 3720 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
9425fb04 3721 "!TARGET_COLDFIRE"
6cebc6cb
BS
3722 "and%.b %2,%0"
3723 [(set_attr "flags_valid" "yes")])
e0c17b2d 3724
988a9e3a 3725(define_insn ""
8406d023 3726 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
988a9e3a 3727 (and:QI (match_dup 0)
2c8ec431 3728 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
9425fb04 3729 "!TARGET_COLDFIRE"
6cebc6cb
BS
3730 "and%.b %1,%0"
3731 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
3732
3733(define_insn ""
8406d023 3734 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2c8ec431 3735 (and:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
988a9e3a 3736 (match_dup 0)))]
9425fb04 3737 "!TARGET_COLDFIRE"
988a9e3a 3738 "and%.b %1,%0")
e0c17b2d
RS
3739\f
3740;; inclusive-or instructions
3741
4b8bef1d 3742(define_insn "iordi_zext"
8406d023 3743 [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
4b8bef1d
PDM
3744 (ior:DI (zero_extend:DI (match_operand 1 "general_operand" "dn,dmn"))
3745 (match_operand:DI 2 "general_operand" "0,0")))]
9425fb04 3746 "!TARGET_COLDFIRE"
4b8bef1d
PDM
3747{
3748 int byte_mode;
3749
4b8bef1d 3750 if (GET_CODE (operands[0]) == REG)
c5c76735 3751 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4b8bef1d 3752 else
b72f00af 3753 operands[0] = adjust_address (operands[0], SImode, 4);
4b8bef1d 3754 if (GET_MODE (operands[1]) == SImode)
c223cf45 3755 return "or%.l %1,%0";
4b8bef1d
PDM
3756 byte_mode = (GET_MODE (operands[1]) == QImode);
3757 if (GET_CODE (operands[0]) == MEM)
b72f00af
RK
3758 operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
3759 byte_mode ? 3 : 2);
4b8bef1d 3760 if (byte_mode)
c223cf45 3761 return "or%.b %1,%0";
4b8bef1d 3762 else
c223cf45
BI
3763 return "or%.w %1,%0";
3764})
4b8bef1d 3765
00523ef2 3766(define_expand "iorsi3"
8406d023 3767 [(set (match_operand:SI 0 "nonimmediate_operand" "")
00523ef2 3768 (ior:SI (match_operand:SI 1 "general_operand" "")
2c8ec431 3769 (match_operand:SI 2 "general_src_operand" "")))]
00523ef2
RK
3770 ""
3771 "")
3772
3773(define_insn "iorsi3_internal"
8406d023 3774 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d")
e0c17b2d 3775 (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
2c8ec431 3776 (match_operand:SI 2 "general_src_operand" "dKT,dmSMT")))]
9425fb04 3777 "! TARGET_COLDFIRE"
e0c17b2d 3778{
5f24901c 3779 return output_iorsi3 (operands);
6cebc6cb
BS
3780}
3781 [(set_attr "flags_valid" "set")])
e0c17b2d 3782
00523ef2 3783(define_insn "iorsi3_5200"
8406d023 3784 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d")
00523ef2 3785 (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
2c8ec431 3786 (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
9425fb04 3787 "TARGET_COLDFIRE"
5e04daf3
PB
3788{
3789 return output_iorsi3 (operands);
6cebc6cb
BS
3790}
3791 [(set_attr "flags_valid" "set")])
00523ef2 3792
e0c17b2d 3793(define_insn "iorhi3"
8406d023 3794 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
e0c17b2d 3795 (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
2c8ec431 3796 (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
9425fb04 3797 "!TARGET_COLDFIRE"
e0c17b2d
RS
3798 "or%.w %2,%0")
3799
988a9e3a 3800(define_insn ""
8406d023 3801 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
988a9e3a 3802 (ior:HI (match_dup 0)
2c8ec431 3803 (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
9425fb04 3804 "!TARGET_COLDFIRE"
988a9e3a
RK
3805 "or%.w %1,%0")
3806
3807(define_insn ""
8406d023 3808 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2c8ec431 3809 (ior:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
988a9e3a 3810 (match_dup 0)))]
9425fb04 3811 "!TARGET_COLDFIRE"
6cebc6cb
BS
3812 "or%.w %1,%0"
3813 [(set_attr "flags_valid" "yes")])
988a9e3a 3814
e0c17b2d 3815(define_insn "iorqi3"
8406d023 3816 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
e0c17b2d 3817 (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
2c8ec431 3818 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
9425fb04 3819 "!TARGET_COLDFIRE"
6cebc6cb
BS
3820 "or%.b %2,%0"
3821 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
3822
3823(define_insn ""
8406d023 3824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
988a9e3a 3825 (ior:QI (match_dup 0)
2c8ec431 3826 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
9425fb04 3827 "!TARGET_COLDFIRE"
6cebc6cb
BS
3828 "or%.b %1,%0"
3829 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
3830
3831(define_insn ""
8406d023 3832 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2c8ec431 3833 (ior:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
988a9e3a 3834 (match_dup 0)))]
9425fb04 3835 "!TARGET_COLDFIRE"
6cebc6cb
BS
3836 "or%.b %1,%0"
3837 [(set_attr "flags_valid" "yes")])
61314cb4 3838
4f23aac0
RK
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"
8406d023 3843 [(set (match_operand:SI 0 "nonimmediate_operand" "=&d")
4b8bef1d
PDM
3844 (ior:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rmn"))
3845 (ashift:SI (match_operand:SI 2 "general_operand" "or")
4f23aac0 3846 (const_int 16))))]
4b8bef1d 3847 ""
4f23aac0 3848{
4f23aac0 3849 if (GET_CODE (operands[2]) != REG)
b72f00af 3850 operands[2] = adjust_address (operands[2], HImode, 2);
4b8bef1d
PDM
3851 if (GET_CODE (operands[2]) != REG
3852 || REGNO (operands[2]) != REGNO (operands[0]))
c223cf45
BI
3853 output_asm_insn ("move%.w %2,%0", operands);
3854 return "swap %0\;mov%.w %1,%0";
3855})
4f23aac0 3856
4b8bef1d 3857(define_insn "iorsi_zext"
8406d023 3858 [(set (match_operand:SI 0 "nonimmediate_operand" "=o,d")
61314cb4
RK
3859 (ior:SI (zero_extend:SI (match_operand 1 "general_operand" "dn,dmn"))
3860 (match_operand:SI 2 "general_operand" "0,0")))]
9425fb04 3861 "!TARGET_COLDFIRE"
61314cb4
RK
3862{
3863 int byte_mode;
3864
4b8bef1d 3865 byte_mode = (GET_MODE (operands[1]) == QImode);
61314cb4 3866 if (GET_CODE (operands[0]) == MEM)
b72f00af
RK
3867 operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
3868 byte_mode ? 3 : 2);
61314cb4 3869 if (byte_mode)
c223cf45 3870 return "or%.b %1,%0";
61314cb4 3871 else
c223cf45
BI
3872 return "or%.w %1,%0";
3873})
e0c17b2d
RS
3874\f
3875;; xor instructions
3876
00523ef2 3877(define_expand "xorsi3"
8406d023 3878 [(set (match_operand:SI 0 "nonimmediate_operand" "")
00523ef2
RK
3879 (xor:SI (match_operand:SI 1 "general_operand" "")
3880 (match_operand:SI 2 "general_operand" "")))]
3881 ""
3882 "")
3883
3884(define_insn "xorsi3_internal"
5e7821eb
JL
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")))]
2c8ec431 3888
9425fb04 3889 "!TARGET_COLDFIRE"
e0c17b2d 3890{
5f24901c 3891 return output_xorsi3 (operands);
6cebc6cb
BS
3892}
3893 [(set_attr "flags_valid" "set")])
e0c17b2d 3894
00523ef2 3895(define_insn "xorsi3_5200"
8406d023 3896 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,d")
43ecaf28
RK
3897 (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
3898 (match_operand:SI 2 "general_operand" "d,Ks")))]
9425fb04 3899 "TARGET_COLDFIRE"
5e04daf3
PB
3900{
3901 return output_xorsi3 (operands);
6cebc6cb
BS
3902}
3903 [(set_attr "flags_valid" "set")])
00523ef2 3904
e0c17b2d 3905(define_insn "xorhi3"
8406d023 3906 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
e0c17b2d
RS
3907 (xor:HI (match_operand:HI 1 "general_operand" "%0")
3908 (match_operand:HI 2 "general_operand" "dn")))]
9425fb04 3909 "!TARGET_COLDFIRE"
6cebc6cb
BS
3910 "eor%.w %2,%0"
3911 [(set_attr "flags_valid" "yes")])
e0c17b2d 3912
988a9e3a 3913(define_insn ""
8406d023 3914 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
988a9e3a
RK
3915 (xor:HI (match_dup 0)
3916 (match_operand:HI 1 "general_operand" "dn")))]
9425fb04 3917 "!TARGET_COLDFIRE"
6cebc6cb
BS
3918 "eor%.w %1,%0"
3919 [(set_attr "flags_valid" "yes")])
988a9e3a 3920
988a9e3a 3921(define_insn ""
8406d023 3922 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
988a9e3a
RK
3923 (xor:HI (match_operand:HI 1 "general_operand" "dn")
3924 (match_dup 0)))]
9425fb04 3925 "!TARGET_COLDFIRE"
6cebc6cb
BS
3926 "eor%.w %1,%0"
3927 [(set_attr "flags_valid" "yes")])
988a9e3a 3928
e0c17b2d 3929(define_insn "xorqi3"
8406d023 3930 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
e0c17b2d
RS
3931 (xor:QI (match_operand:QI 1 "general_operand" "%0")
3932 (match_operand:QI 2 "general_operand" "dn")))]
9425fb04 3933 "!TARGET_COLDFIRE"
6cebc6cb
BS
3934 "eor%.b %2,%0"
3935 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
3936
3937(define_insn ""
8406d023 3938 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
988a9e3a
RK
3939 (xor:QI (match_dup 0)
3940 (match_operand:QI 1 "general_operand" "dn")))]
9425fb04 3941 "!TARGET_COLDFIRE"
6cebc6cb
BS
3942 "eor%.b %1,%0"
3943 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
3944
3945(define_insn ""
8406d023 3946 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
988a9e3a
RK
3947 (xor:QI (match_operand:QI 1 "general_operand" "dn")
3948 (match_dup 0)))]
9425fb04 3949 "!TARGET_COLDFIRE"
6cebc6cb
BS
3950 "eor%.b %1,%0"
3951 [(set_attr "flags_valid" "yes")])
e0c17b2d
RS
3952\f
3953;; negation instructions
3954
a418b6c5 3955(define_expand "negdi2"
8406d023 3956 [(set (match_operand:DI 0 "nonimmediate_operand" "")
a418b6c5
ILT
3957 (neg:DI (match_operand:DI 1 "general_operand" "")))]
3958 ""
a418b6c5 3959{
9425fb04 3960 if (TARGET_COLDFIRE)
a418b6c5
ILT
3961 emit_insn (gen_negdi2_5200 (operands[0], operands[1]));
3962 else
3963 emit_insn (gen_negdi2_internal (operands[0], operands[1]));
3964 DONE;
428511bb 3965})
a418b6c5
ILT
3966
3967(define_insn "negdi2_internal"
8406d023 3968 [(set (match_operand:DI 0 "nonimmediate_operand" "=<,do,!*a")
935fb288 3969 (neg:DI (match_operand:DI 1 "general_operand" "0,0,0")))]
9425fb04 3970 "!TARGET_COLDFIRE"
801aee46 3971{
935fb288 3972 if (which_alternative == 0)
c223cf45 3973 return "neg%.l %0\;negx%.l %0";
801aee46 3974 if (GET_CODE (operands[0]) == REG)
1d8eaa6b 3975 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
801aee46 3976 else
b72f00af 3977 operands[1] = adjust_address (operands[0], SImode, 4);
6231ef82 3978 if (ADDRESS_REG_P (operands[0]))
c223cf45 3979 return "exg %/d0,%1\;neg%.l %/d0\;exg %/d0,%1\;exg %/d0,%0\;negx%.l %/d0\;exg %/d0,%0";
6231ef82 3980 else
c223cf45
BI
3981 return "neg%.l %1\;negx%.l %0";
3982})
801aee46 3983
a418b6c5 3984(define_insn "negdi2_5200"
8406d023 3985 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
dfb331d6 3986 (neg:DI (match_operand:DI 1 "general_operand" "0")))]
9425fb04 3987 "TARGET_COLDFIRE"
a418b6c5 3988{
1d8eaa6b 3989 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45
BI
3990 return "neg%.l %1\;negx%.l %0";
3991})
a418b6c5 3992
dfb331d6 3993(define_expand "negsi2"
8406d023 3994 [(set (match_operand:SI 0 "nonimmediate_operand" "")
dfb331d6
RK
3995 (neg:SI (match_operand:SI 1 "general_operand" "")))]
3996 ""
dfb331d6 3997{
9425fb04 3998 if (TARGET_COLDFIRE)
dfb331d6
RK
3999 emit_insn (gen_negsi2_5200 (operands[0], operands[1]));
4000 else
4001 emit_insn (gen_negsi2_internal (operands[0], operands[1]));
4002 DONE;
428511bb 4003})
dfb331d6
RK
4004
4005(define_insn "negsi2_internal"
8406d023 4006 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
e0c17b2d 4007 (neg:SI (match_operand:SI 1 "general_operand" "0")))]
9425fb04 4008 "!TARGET_COLDFIRE"
c47b0cb4 4009 "neg%.l %0"
6cebc6cb
BS
4010 [(set_attr "type" "neg_l")
4011 (set_attr "flags_valid" "noov")])
dfb331d6
RK
4012
4013(define_insn "negsi2_5200"
8406d023 4014 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
dfb331d6 4015 (neg:SI (match_operand:SI 1 "general_operand" "0")))]
9425fb04 4016 "TARGET_COLDFIRE"
c47b0cb4 4017 "neg%.l %0"
6cebc6cb
BS
4018 [(set_attr "type" "neg_l")
4019 (set_attr "flags_valid" "noov")])
e0c17b2d
RS
4020
4021(define_insn "neghi2"
8406d023 4022 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
e0c17b2d 4023 (neg:HI (match_operand:HI 1 "general_operand" "0")))]
9425fb04 4024 "!TARGET_COLDFIRE"
6cebc6cb
BS
4025 "neg%.w %0"
4026 [(set_attr "flags_valid" "noov")])
e0c17b2d 4027
988a9e3a 4028(define_insn ""
8406d023 4029 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
988a9e3a 4030 (neg:HI (match_dup 0)))]
9425fb04 4031 "!TARGET_COLDFIRE"
6cebc6cb
BS
4032 "neg%.w %0"
4033 [(set_attr "flags_valid" "noov")])
988a9e3a 4034
e0c17b2d 4035(define_insn "negqi2"
8406d023 4036 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
e0c17b2d 4037 (neg:QI (match_operand:QI 1 "general_operand" "0")))]
9425fb04 4038 "!TARGET_COLDFIRE"
6cebc6cb
BS
4039 "neg%.b %0"
4040 [(set_attr "flags_valid" "noov")])
e0c17b2d 4041
988a9e3a 4042(define_insn ""
8406d023 4043 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
988a9e3a 4044 (neg:QI (match_dup 0)))]
9425fb04 4045 "!TARGET_COLDFIRE"
6cebc6cb
BS
4046 "neg%.b %0"
4047 [(set_attr "flags_valid" "noov")])
988a9e3a 4048
51200988
DE
4049;; If using software floating point, just flip the sign bit.
4050
e0c17b2d 4051(define_expand "negsf2"
8406d023 4052 [(set (match_operand:SF 0 "nonimmediate_operand" "")
e0c17b2d 4053 (neg:SF (match_operand:SF 1 "general_operand" "")))]
51200988 4054 ""
51200988 4055{
dcc21c4c 4056 if (!TARGET_HARD_FLOAT)
51200988
DE
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),
ab1e659c 4064 GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
4761e388 4065 gcc_assert (result);
51200988
DE
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 }
428511bb 4074})
e0c17b2d 4075
e0c17b2d 4076(define_expand "negdf2"
8406d023 4077 [(set (match_operand:DF 0 "nonimmediate_operand" "")
e0c17b2d 4078 (neg:DF (match_operand:DF 1 "general_operand" "")))]
51200988 4079 ""
51200988 4080{
dcc21c4c 4081 if (!TARGET_HARD_FLOAT)
51200988
DE
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),
ab1e659c 4091 GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
4761e388 4092 gcc_assert (result);
51200988
DE
4093
4094 if (result != target)
4095 emit_move_insn (result, target);
935fb288 4096
51200988
DE
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
d70dcf29 4103 emit_insn (insns);
51200988
DE
4104 DONE;
4105 }
428511bb 4106})
e0c17b2d 4107
dcc21c4c
PB
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),
ab1e659c 4123 GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
dcc21c4c
PB
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
d70dcf29 4137 emit_insn (insns);
dcc21c4c
PB
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")))]
e0c17b2d 4145 "TARGET_68881"
e0c17b2d
RS
4146{
4147 if (DATA_REG_P (operands[0]))
4148 {
1d8eaa6b 4149 operands[1] = GEN_INT (31);
c223cf45 4150 return "bchg %1,%0";
e0c17b2d 4151 }
dcc21c4c
PB
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";
c223cf45 4170})
e0c17b2d 4171\f
d7902217
JL
4172;; Sqrt instruction for the 68881
4173
dcc21c4c
PB
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")))]
0e73100c 4183 "TARGET_68881"
0e73100c
RK
4184{
4185 if (FP_REG_P (operands[1]))
dcc21c4c
PB
4186 return "f<FP:round>sqrt%.x %1,%0";
4187 return "f<FP:round>sqrt%.<FP:prec> %1,%0";
c47b0cb4
MK
4188}
4189 [(set_attr "type" "fsqrt")])
0e73100c 4190
dcc21c4c
PB
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"
d7902217
JL
4195{
4196 if (FP_REG_P (operands[1]))
dcc21c4c
PB
4197 return "f<FP:prec>sqrt%.d %1,%0";
4198 return "f<FP:prec>sqrt%.<FP:prec> %1,%0";
96fcacb7
MK
4199}
4200 [(set_attr "type" "fsqrt")])
e0c17b2d 4201;; Absolute value instructions
51200988 4202;; If using software floating point, just zero the sign bit.
e0c17b2d
RS
4203
4204(define_expand "abssf2"
8406d023 4205 [(set (match_operand:SF 0 "nonimmediate_operand" "")
e0c17b2d 4206 (abs:SF (match_operand:SF 1 "general_operand" "")))]
51200988 4207 ""
51200988 4208{
dcc21c4c 4209 if (!TARGET_HARD_FLOAT)
51200988
DE
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),
c5c76735 4217 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
4761e388 4218 gcc_assert (result);
51200988
DE
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 }
428511bb 4227})
e0c17b2d 4228
e0c17b2d 4229(define_expand "absdf2"
8406d023 4230 [(set (match_operand:DF 0 "nonimmediate_operand" "")
e0c17b2d 4231 (abs:DF (match_operand:DF 1 "general_operand" "")))]
51200988 4232 ""
51200988 4233{
dcc21c4c 4234 if (!TARGET_HARD_FLOAT)
51200988
DE
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),
c5c76735 4244 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
4761e388 4245 gcc_assert (result);
51200988
DE
4246
4247 if (result != target)
4248 emit_move_insn (result, target);
935fb288 4249
51200988
DE
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
d70dcf29 4256 emit_insn (insns);
51200988
DE
4257 DONE;
4258 }
428511bb 4259})
e0c17b2d 4260
dcc21c4c
PB
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
d70dcf29 4290 emit_insn (insns);
dcc21c4c
PB
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"
e0c17b2d 4314{
dcc21c4c
PB
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";
96fcacb7
MK
4323}
4324 [(set_attr "type" "bitrw,fneg")])
e0c17b2d 4325\f
7a6525d6
SL
4326;; bit indexing instructions
4327
577e0395
AS
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"
6cebc6cb 4341 "bfffo %1{#0:#0},%0")
577e0395 4342
7a6525d6 4343;; ColdFire ff1 instruction implements clz.
577e0395 4344(define_insn "*clzsi2_cf"
7a6525d6
SL
4345 [(set (match_operand:SI 0 "register_operand" "=d")
4346 (clz:SI (match_operand:SI 1 "register_operand" "0")))]
59c92f76 4347 "ISA_HAS_FF1"
6cebc6cb 4348 "ff1 %0"
96fcacb7 4349 [(set_attr "type" "ext")])
7a6525d6 4350\f
e0c17b2d
RS
4351;; one complement instructions
4352
dfb331d6 4353(define_expand "one_cmplsi2"
8406d023 4354 [(set (match_operand:SI 0 "nonimmediate_operand" "")
dfb331d6
RK
4355 (not:SI (match_operand:SI 1 "general_operand" "")))]
4356 ""
dfb331d6 4357{
9425fb04 4358 if (TARGET_COLDFIRE)
dfb331d6
RK
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;
428511bb 4363})
dfb331d6
RK
4364
4365(define_insn "one_cmplsi2_internal"
8406d023 4366 [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
e0c17b2d 4367 (not:SI (match_operand:SI 1 "general_operand" "0")))]
9425fb04 4368 "!TARGET_COLDFIRE"
6cebc6cb
BS
4369 "not%.l %0"
4370 [(set_attr "flags_valid" "yes")])
dfb331d6
RK
4371
4372(define_insn "one_cmplsi2_5200"
8406d023 4373 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
dfb331d6 4374 (not:SI (match_operand:SI 1 "general_operand" "0")))]
9425fb04 4375 "TARGET_COLDFIRE"
c47b0cb4 4376 "not%.l %0"
96fcacb7 4377 [(set_attr "type" "neg_l")])
e0c17b2d
RS
4378
4379(define_insn "one_cmplhi2"
8406d023 4380 [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
e0c17b2d 4381 (not:HI (match_operand:HI 1 "general_operand" "0")))]
9425fb04 4382 "!TARGET_COLDFIRE"
6cebc6cb
BS
4383 "not%.w %0"
4384 [(set_attr "flags_valid" "yes")])
e0c17b2d 4385
988a9e3a 4386(define_insn ""
8406d023 4387 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
988a9e3a 4388 (not:HI (match_dup 0)))]
9425fb04 4389 "!TARGET_COLDFIRE"
6cebc6cb
BS
4390 "not%.w %0"
4391 [(set_attr "flags_valid" "yes")])
988a9e3a 4392
e0c17b2d 4393(define_insn "one_cmplqi2"
8406d023 4394 [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
e0c17b2d 4395 (not:QI (match_operand:QI 1 "general_operand" "0")))]
9425fb04 4396 "!TARGET_COLDFIRE"
6cebc6cb
BS
4397 "not%.b %0"
4398 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
4399
4400(define_insn ""
8406d023 4401 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
988a9e3a 4402 (not:QI (match_dup 0)))]
9425fb04 4403 "!TARGET_COLDFIRE"
6cebc6cb
BS
4404 "not%.b %0"
4405 [(set_attr "flags_valid" "yes")])
e0c17b2d
RS
4406\f
4407;; arithmetic shift instructions
4408;; We don't need the shift memory by 1 bit instruction
63e6247d 4409(define_insn_and_split "ashldi_extsi"
8406d023 4410 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
31e033e9
RK
4411 (ashift:DI
4412 (match_operator:DI 2 "extend_operator"
4413 [(match_operand:SI 1 "general_operand" "rm")])
4414 (const_int 32)))]
4415 ""
63e6247d
JL
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);")
31e033e9 4421
801aee46 4422(define_insn "ashldi_sexthi"
8406d023 4423 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,a*d")
935fb288
RK
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"))]
801aee46 4427 ""
801aee46 4428{
935fb288
RK
4429 if (GET_CODE (operands[0]) == MEM)
4430 {
4431 if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
c223cf45 4432 return "clr%.l %0\;move%.w %1,%2\;move%.l %2,%0";
935fb288 4433 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
c223cf45 4434 return "move%.w %1,%2\;move%.l %2,%0\;clr%.l %0";
935fb288
RK
4435 else
4436 {
b72f00af 4437 operands[3] = adjust_address (operands[0], SImode, 4);
c223cf45 4438 return "move%.w %1,%2\;move%.l %2,%0\;clr%.l %3";
935fb288
RK
4439 }
4440 }
4441 else if (DATA_REG_P (operands[0]))
c223cf45 4442 return "move%.w %1,%0\;ext%.l %0\;clr%.l %R0";
801aee46 4443 else
c223cf45
BI
4444 return "move%.w %1,%0\;sub%.l %R0,%R0";
4445})
801aee46 4446
01e304f8
RZ
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)))]
801aee46 4540 ""
01e304f8
RZ
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))]
801aee46 4573{
01e304f8
RZ
4574 operands[2] = gen_highpart (SImode, operands[0]);
4575 operands[3] = gen_lowpart (SImode, operands[0]);
c223cf45 4576})
801aee46 4577
01e304f8
RZ
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
c2ad275a
JL
4599 && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4600 || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
01e304f8
RZ
4601 || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))"
4602 "#")
801aee46
RK
4603
4604(define_expand "ashldi3"
01e304f8
RZ
4605 [(set (match_operand:DI 0 "register_operand" "")
4606 (ashift:DI (match_operand:DI 1 "register_operand" "")
09c92f1c 4607 (match_operand:SI 2 "const_int_operand" "")))]
9425fb04 4608 "!TARGET_COLDFIRE"
801aee46 4609{
c2ad275a
JL
4610 /* ??? This is a named pattern like this is not allowed to FAIL based
4611 on its operands. */
801aee46 4612 if (GET_CODE (operands[2]) != CONST_INT
c2ad275a
JL
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)))
801aee46 4616 FAIL;
01e304f8 4617})
801aee46 4618
dbe68272 4619;; On most 68k models, this makes faster code in a special case.
b4ac57ab 4620
dbe68272 4621(define_insn "ashlsi_16"
b4ac57ab
RS
4622 [(set (match_operand:SI 0 "register_operand" "=d")
4623 (ashift:SI (match_operand:SI 1 "register_operand" "0")
1ecba59d 4624 (const_int 16)))]
fe95f2f7 4625 "!TUNE_68060"
6cebc6cb 4626 "swap %0\;clr%.w %0")
b4ac57ab 4627
935fb288 4628;; ashift patterns : use lsl instead of asl, because lsl always clears the
6cebc6cb 4629;; overflow bit, allowing more comparisons.
935fb288 4630
e0c17b2d
RS
4631;; On the 68000, this makes faster code in a special case.
4632
dbe68272 4633(define_insn "ashlsi_17_24"
e0c17b2d
RS
4634 [(set (match_operand:SI 0 "register_operand" "=d")
4635 (ashift:SI (match_operand:SI 1 "register_operand" "0")
1ecba59d 4636 (match_operand:SI 2 "const_int_operand" "n")))]
fe95f2f7
JB
4637 "TUNE_68000_10
4638 && INTVAL (operands[2]) > 16
4639 && INTVAL (operands[2]) <= 24"
e0c17b2d 4640{
1d8eaa6b 4641 operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
c223cf45
BI
4642 return "lsl%.w %2,%0\;swap %0\;clr%.w %0";
4643})
e0c17b2d
RS
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 ""
e0c17b2d
RS
4650{
4651 if (operands[2] == const1_rtx)
6cebc6cb 4652 return "add%.l %0,%0";
c223cf45 4653 return "lsl%.l %2,%0";
6cebc6cb
BS
4654}
4655 [(set (attr "flags_valid")
4656 (if_then_else (match_operand 2 "const1_operand")
4657 (const_string "noov")
4658 (const_string "yes")))])
e0c17b2d
RS
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")))]
9425fb04 4664 "!TARGET_COLDFIRE"
6cebc6cb
BS
4665 "lsl%.w %2,%0"
4666 [(set_attr "flags_valid" "yes")])
e0c17b2d 4667
988a9e3a
RK
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")))]
9425fb04 4672 "!TARGET_COLDFIRE"
6cebc6cb
BS
4673 "lsl%.w %1,%0"
4674 [(set_attr "flags_valid" "yes")])
988a9e3a 4675
e0c17b2d
RS
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")))]
9425fb04 4680 "!TARGET_COLDFIRE"
6cebc6cb
BS
4681 "lsl%.b %2,%0"
4682 [(set_attr "flags_valid" "yes")])
e0c17b2d 4683
988a9e3a
RK
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")))]
9425fb04 4688 "!TARGET_COLDFIRE"
6cebc6cb
BS
4689 "lsl%.b %1,%0"
4690 [(set_attr "flags_valid" "yes")])
988a9e3a 4691
2c5447d9 4692;; On most 68k models, this makes faster code in a special case.
b4ac57ab 4693
4f23aac0 4694(define_insn "ashrsi_16"
b4ac57ab
RS
4695 [(set (match_operand:SI 0 "register_operand" "=d")
4696 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1ecba59d 4697 (const_int 16)))]
fe95f2f7 4698 "!TUNE_68060"
b4ac57ab
RS
4699 "swap %0\;ext%.l %0")
4700
e0c17b2d
RS
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")
1ecba59d 4706 (match_operand:SI 2 "const_int_operand" "n")))]
fe95f2f7
JB
4707 "TUNE_68000_10
4708 && INTVAL (operands[2]) > 16
4709 && INTVAL (operands[2]) <= 24"
e0c17b2d 4710{
1d8eaa6b 4711 operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
c223cf45
BI
4712 return "swap %0\;asr%.w %2,%0\;ext%.l %0";
4713})
e0c17b2d 4714
31e033e9 4715(define_insn "subreghi1ashrdi_const32"
8406d023 4716 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
31e033e9 4717 (subreg:HI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
b7b59ff4 4718 (const_int 32)) 6))]
31e033e9 4719 ""
31e033e9
RK
4720{
4721 if (GET_CODE (operands[1]) != REG)
b72f00af 4722 operands[1] = adjust_address (operands[1], HImode, 2);
c223cf45 4723 return "move%.w %1,%0";
c47b0cb4 4724}
96fcacb7 4725 [(set_attr "type" "move")])
31e033e9
RK
4726
4727(define_insn "subregsi1ashrdi_const32"
8406d023 4728 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
801aee46 4729 (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
ddef6bc7 4730 (const_int 32)) 4))]
801aee46 4731 ""
801aee46 4732{
c223cf45 4733 return "move%.l %1,%0";
c47b0cb4
MK
4734}
4735 [(set_attr "type" "move_l")])
801aee46 4736
01e304f8
RZ
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{
01e304f8
RZ
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")
801aee46 4818 (const_int 32)))
01e304f8 4819 (clobber (match_scratch:SI 2 "=d,d"))]
801aee46 4820 ""
801aee46 4821{
01e304f8
RZ
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";
801aee46 4827 else
01e304f8 4828 return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
c223cf45 4829})
801aee46 4830
01e304f8
RZ
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
31e033e9 4842;; The predicate below must be general_operand, because ashrdi3 allows that
801aee46 4843(define_insn "ashrdi_const"
01e304f8
RZ
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
3cac0a21 4848 && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
c2ad275a
JL
4849 || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4850 || INTVAL (operands[2]) == 31
01e304f8 4851 || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))"
801aee46 4852{
1d8eaa6b 4853 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
01e304f8 4854 if (INTVAL (operands[2]) == 48)
c223cf45 4855 return "swap %0\;ext%.l %0\;move%.l %0,%1\;smi %0\;ext%.w %0";
01e304f8 4856 if (INTVAL (operands[2]) == 31)
c223cf45 4857 return "add%.l %1,%1\;addx%.l %0,%0\;move%.l %0,%1\;subx%.l %0,%0";
01e304f8 4858 if (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)
3cac0a21 4859 {
3a598fbe 4860 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
c223cf45
BI
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";
3cac0a21 4866 }
01e304f8 4867 return "#";
c223cf45 4868})
801aee46
RK
4869
4870(define_expand "ashrdi3"
01e304f8
RZ
4871 [(set (match_operand:DI 0 "register_operand" "")
4872 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
09c92f1c 4873 (match_operand:SI 2 "const_int_operand" "")))]
9425fb04 4874 "!TARGET_COLDFIRE"
801aee46 4875{
c2ad275a
JL
4876 /* ??? This is a named pattern like this is not allowed to FAIL based
4877 on its operands. */
801aee46 4878 if (GET_CODE (operands[2]) != CONST_INT
c2ad275a
JL
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)))
801aee46 4882 FAIL;
01e304f8 4883})
801aee46 4884
3f6ddf54
TG
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 ""
3f6ddf54 4892{
c223cf45
BI
4893 return "add%.l %0,%0\;subx%.l %0,%0";
4894})
3f6ddf54 4895
e0c17b2d
RS
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 ""
c47b0cb4 4901 "asr%.l %2,%0"
96fcacb7 4902 [(set_attr "type" "shift")
6cebc6cb
BS
4903 (set_attr "opy" "2")
4904 (set_attr "flags_valid" "noov")])
e0c17b2d
RS
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")))]
9425fb04 4910 "!TARGET_COLDFIRE"
6cebc6cb
BS
4911 "asr%.w %2,%0"
4912 [(set_attr "flags_valid" "noov")])
e0c17b2d 4913
988a9e3a
RK
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")))]
9425fb04 4918 "!TARGET_COLDFIRE"
6cebc6cb
BS
4919 "asr%.w %1,%0"
4920 [(set_attr "flags_valid" "noov")])
988a9e3a 4921
e0c17b2d
RS
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")))]
9425fb04 4926 "!TARGET_COLDFIRE"
6cebc6cb
BS
4927 "asr%.b %2,%0"
4928 [(set_attr "flags_valid" "noov")])
988a9e3a
RK
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")))]
9425fb04 4934 "!TARGET_COLDFIRE"
6cebc6cb
BS
4935 "asr%.b %1,%0"
4936 [(set_attr "flags_valid" "noov")])
e0c17b2d
RS
4937\f
4938;; logical shift instructions
4939
75fbfd0c
RK
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")
ddef6bc7 4944;; (const_int 32)) 4))
8406d023 4945;; (set (match_operand:SI 1 "nonimmediate_operand" "=dm")
75fbfd0c 4946;; (subreg:SI (lshiftrt:DI (match_dup 0)
ddef6bc7 4947;; (const_int 32)) 4))]
75fbfd0c 4948;; ""
75fbfd0c 4949;;{
c223cf45
BI
4950;; return "move%.l %0,%1";
4951;;})
75fbfd0c
RK
4952;;
4953;;(define_insn ""
4954;; [(set (cc0)
4955;; (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
4956;; (const_int 32)) 0))
8406d023 4957;; (set (match_operand:DI 1 "nonimmediate_operand" "=do")
75fbfd0c
RK
4958;; (lshiftrt:DI (match_dup 0)
4959;; (const_int 32)))]
4960;; ""
75fbfd0c
RK
4961;;{
4962;; if (GET_CODE (operands[1]) == REG)
1d8eaa6b 4963;; operands[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
75fbfd0c 4964;; else
b72f00af 4965;; operands[2] = adjust_address (operands[1], SImode, 4);
c223cf45
BI
4966;; return "move%.l %0,%2\;clr%.l %1";
4967;;})
31e033e9 4968
801aee46 4969(define_insn "subreg1lshrdi_const32"
8406d023 4970 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
801aee46 4971 (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
ddef6bc7 4972 (const_int 32)) 4))]
801aee46 4973 ""
c47b0cb4
MK
4974 "move%.l %1,%0"
4975 [(set_attr "type" "move_l")])
801aee46 4976
01e304f8
RZ
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"
9fd8313a 4982{
9fd8313a
AS
4983 return "lsr%.l #1,%0\;roxr%.l #1,%R0";
4984})
01e304f8
RZ
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")
801aee46
RK
5078 (const_int 32)))]
5079 ""
01e304f8
RZ
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))]
801aee46 5091{
01e304f8
RZ
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]);
c223cf45 5095})
801aee46 5096
01e304f8
RZ
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")
801aee46 5139 (match_operand 2 "const_int_operand" "n")))]
9425fb04 5140 "(!TARGET_COLDFIRE
01e304f8 5141 && ((INTVAL (operands[2]) >= 2 && INTVAL (operands[2]) <= 3)
c2ad275a
JL
5142 || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
5143 || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
01e304f8 5144 "#")
801aee46
RK
5145
5146(define_expand "lshrdi3"
01e304f8
RZ
5147 [(set (match_operand:DI 0 "register_operand" "")
5148 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
09c92f1c 5149 (match_operand:SI 2 "const_int_operand" "")))]
9425fb04 5150 "!TARGET_COLDFIRE"
801aee46 5151{
c2ad275a
JL
5152 /* ??? This is a named pattern like this is not allowed to FAIL based
5153 on its operands. */
801aee46 5154 if (GET_CODE (operands[2]) != CONST_INT
c2ad275a
JL
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)))
801aee46 5158 FAIL;
c223cf45 5159})
1ecba59d 5160
b4ac57ab
RS
5161;; On all 68k models, this makes faster code in a special case.
5162
801aee46
RK
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 ""
801aee46 5168{
c223cf45
BI
5169 return "add%.l %0,%0\;subx%.l %0,%0\;neg%.l %0";
5170})
801aee46 5171
dbe68272 5172;; On most 68k models, this makes faster code in a special case.
801aee46
RK
5173
5174(define_insn "lshrsi_16"
b4ac57ab
RS
5175 [(set (match_operand:SI 0 "register_operand" "=d")
5176 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1ecba59d 5177 (const_int 16)))]
fe95f2f7 5178 "!TUNE_68060"
b4ac57ab 5179{
c223cf45
BI
5180 return "clr%.w %0\;swap %0";
5181})
b4ac57ab 5182
e0c17b2d
RS
5183;; On the 68000, this makes faster code in a special case.
5184
801aee46 5185(define_insn "lshrsi_17_24"
e0c17b2d
RS
5186 [(set (match_operand:SI 0 "register_operand" "=d")
5187 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1ecba59d 5188 (match_operand:SI 2 "const_int_operand" "n")))]
fe95f2f7
JB
5189 "TUNE_68000_10
5190 && INTVAL (operands[2]) > 16
5191 && INTVAL (operands[2]) <= 24"
e0c17b2d 5192{
e0c17b2d 5193 /* I think lsr%.w sets the CC properly. */
1d8eaa6b 5194 operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
c223cf45
BI
5195 return "clr%.w %0\;swap %0\;lsr%.w %2,%0";
5196})
e0c17b2d
RS
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 ""
c47b0cb4 5203 "lsr%.l %2,%0"
96fcacb7 5204 [(set_attr "type" "shift")
6cebc6cb
BS
5205 (set_attr "opy" "2")
5206 (set_attr "flags_valid" "yes")])
e0c17b2d
RS
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")))]
9425fb04 5212 "!TARGET_COLDFIRE"
6cebc6cb
BS
5213 "lsr%.w %2,%0"
5214 [(set_attr "flags_valid" "yes")])
e0c17b2d 5215
988a9e3a
RK
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")))]
9425fb04 5220 "!TARGET_COLDFIRE"
6cebc6cb
BS
5221 "lsr%.w %1,%0"
5222 [(set_attr "flags_valid" "yes")])
988a9e3a 5223
e0c17b2d
RS
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")))]
9425fb04 5228 "!TARGET_COLDFIRE"
6cebc6cb
BS
5229 "lsr%.b %2,%0"
5230 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
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")))]
9425fb04 5236 "!TARGET_COLDFIRE"
6cebc6cb
BS
5237 "lsr%.b %1,%0"
5238 [(set_attr "flags_valid" "yes")])
e0c17b2d
RS
5239\f
5240;; rotate instructions
5241
331fc6d8
AS
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"
6cebc6cb
BS
5248 [(set_attr "type" "shift")
5249 (set_attr "flags_valid" "yes")])
331fc6d8 5250
e0c17b2d
RS
5251(define_insn "rotlsi3"
5252 [(set (match_operand:SI 0 "register_operand" "=d")
5253 (rotate:SI (match_operand:SI 1 "register_operand" "0")
e62db39c 5254 (match_operand:SI 2 "general_operand" "dINO")))]
9425fb04 5255 "!TARGET_COLDFIRE"
e62db39c
RK
5256{
5257 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)
c223cf45 5258 return "swap %0";
e62db39c
RK
5259 else if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 16)
5260 {
1d8eaa6b 5261 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
c223cf45 5262 return "ror%.l %2,%0";
e62db39c
RK
5263 }
5264 else
c223cf45 5265 return "rol%.l %2,%0";
6cebc6cb
BS
5266}
5267 [(set_attr "flags_valid" "yes")])
e0c17b2d
RS
5268
5269(define_insn "rotlhi3"
5270 [(set (match_operand:HI 0 "register_operand" "=d")
5271 (rotate:HI (match_operand:HI 1 "register_operand" "0")
e62db39c 5272 (match_operand:HI 2 "general_operand" "dIP")))]
9425fb04 5273 "!TARGET_COLDFIRE"
e62db39c
RK
5274{
5275 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
5276 {
1d8eaa6b 5277 operands[2] = GEN_INT (16 - INTVAL (operands[2]));
c223cf45 5278 return "ror%.w %2,%0";
e62db39c
RK
5279 }
5280 else
c223cf45 5281 return "rol%.w %2,%0";
6cebc6cb
BS
5282}
5283 [(set_attr "flags_valid" "yes")])
988a9e3a 5284
e7413f3d 5285(define_insn "*rotlhi3_lowpart"
988a9e3a
RK
5286 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
5287 (rotate:HI (match_dup 0)
e62db39c 5288 (match_operand:HI 1 "general_operand" "dIP")))]
9425fb04 5289 "!TARGET_COLDFIRE"
e62db39c 5290{
e7413f3d 5291 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >= 8)
e62db39c 5292 {
e7413f3d
AS
5293 operands[1] = GEN_INT (16 - INTVAL (operands[1]));
5294 return "ror%.w %1,%0";
e62db39c
RK
5295 }
5296 else
e7413f3d 5297 return "rol%.w %1,%0";
6cebc6cb
BS
5298}
5299 [(set_attr "flags_valid" "yes")])
988a9e3a 5300
e0c17b2d
RS
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")))]
9425fb04 5305 "!TARGET_COLDFIRE"
e62db39c
RK
5306{
5307 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
5308 {
1d8eaa6b 5309 operands[2] = GEN_INT (8 - INTVAL (operands[2]));
c223cf45 5310 return "ror%.b %2,%0";
e62db39c
RK
5311 }
5312 else
c223cf45 5313 return "rol%.b %2,%0";
6cebc6cb
BS
5314}
5315 [(set_attr "flags_valid" "yes")])
e0c17b2d 5316
e7413f3d 5317(define_insn "*rotlqi3_lowpart"
988a9e3a
RK
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")))]
9425fb04 5321 "!TARGET_COLDFIRE"
e62db39c 5322{
e7413f3d 5323 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >= 4)
e62db39c 5324 {
e7413f3d
AS
5325 operands[1] = GEN_INT (8 - INTVAL (operands[1]));
5326 return "ror%.b %1,%0";
e62db39c
RK
5327 }
5328 else
e7413f3d 5329 return "rol%.b %1,%0";
6cebc6cb
BS
5330}
5331 [(set_attr "flags_valid" "yes")])
988a9e3a 5332
e0c17b2d
RS
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")))]
9425fb04 5337 "!TARGET_COLDFIRE"
6cebc6cb
BS
5338 "ror%.l %2,%0"
5339 [(set_attr "flags_valid" "yes")])
e0c17b2d
RS
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")))]
9425fb04 5345 "!TARGET_COLDFIRE"
e0c17b2d
RS
5346 "ror%.w %2,%0")
5347
dee16055 5348(define_insn "rotrhi_lowpart"
988a9e3a
RK
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")))]
9425fb04 5352 "!TARGET_COLDFIRE"
988a9e3a
RK
5353 "ror%.w %1,%0")
5354
e0c17b2d
RS
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")))]
9425fb04 5359 "!TARGET_COLDFIRE"
6cebc6cb
BS
5360 "ror%.b %2,%0"
5361 [(set_attr "flags_valid" "yes")])
988a9e3a
RK
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")))]
9425fb04 5367 "!TARGET_COLDFIRE"
6cebc6cb
BS
5368 "ror%.b %1,%0"
5369 [(set_attr "flags_valid" "yes")])
dee16055
AS
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})
e0c17b2d 5383\f
7bc89c29
RK
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)
b7b59ff4 5391 (match_operand:SI 1 "general_operand" "d")) 3)
7bc89c29
RK
5392 (match_dup 0)))]
5393 ""
6cebc6cb 5394 "bset %1,%0"
96fcacb7 5395 [(set_attr "type" "bitrw")])
7bc89c29
RK
5396
5397;; set bit, bit number is (sign/zero)_extended from HImode/QImode
c47b0cb4 5398(define_insn "*bsetmemqi_ext"
7bc89c29
RK
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"
b7b59ff4 5402 [(match_operand 1 "general_operand" "d")])) 3)
7bc89c29
RK
5403 (match_dup 0)))]
5404 ""
6cebc6cb 5405 "bset %1,%0"
96fcacb7 5406 [(set_attr "type" "bitrw")])
7bc89c29 5407
636a9a89 5408(define_insn "*bsetdreg"
ad2f2a35 5409 [(set (match_operand:SI 0 "register_operand" "=d")
636a9a89
JL
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 ""
6cebc6cb 5415 "bset %1,%0"
636a9a89
JL
5416 [(set_attr "type" "bitrw")])
5417
5418(define_insn "*bchgdreg"
ad2f2a35 5419 [(set (match_operand:SI 0 "register_operand" "=d")
636a9a89
JL
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 ""
6cebc6cb 5425 "bchg %1,%0"
636a9a89
JL
5426 [(set_attr "type" "bitrw")])
5427
5428(define_insn "*bclrdreg"
ad2f2a35 5429 [(set (match_operand:SI 0 "register_operand" "=d")
636a9a89
JL
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 ""
6cebc6cb 5435 "bclr %1,%0"
636a9a89
JL
5436 [(set_attr "type" "bitrw")])
5437
7bc89c29
RK
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 ""
6cebc6cb 5446 "bclr %1,%0"
96fcacb7 5447 [(set_attr "type" "bitrw")])
7bc89c29
RK
5448
5449;; clear bit, bit number is (sign/zero)_extended from HImode/QImode
c47b0cb4 5450(define_insn "*bclrmemqi_ext"
7bc89c29
RK
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 ""
6cebc6cb 5458 "bclr %1,%0"
96fcacb7 5459 [(set_attr "type" "bitrw")])
7bc89c29 5460
e0c17b2d
RS
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
c16eadc7 5471; than an odd byte aligned bit-field instruction.
e0c17b2d 5472;
481f83c7 5473(define_insn "*insv_32_mem"
83199882 5474 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
1ecba59d 5475 (const_int 32)
c77e04ae
RH
5476 (match_operand:SI 1 "const_int_operand" "n"))
5477 (match_operand:SI 2 "general_src_operand" "rmSi"))]
e0c17b2d 5478 "TARGET_68020 && TARGET_BITFIELD
c77e04ae 5479 && (INTVAL (operands[1]) % 8) == 0
5bfed9a9
GJL
5480 && ! mode_dependent_address_p (XEXP (operands[0], 0),
5481 MEM_ADDR_SPACE (operands[0]))"
e0c17b2d
RS
5482{
5483 operands[0]
b72f00af 5484 = adjust_address (operands[0], SImode, INTVAL (operands[1]) / 8);
e0c17b2d 5485
c223cf45
BI
5486 return "move%.l %2,%0";
5487})
e0c17b2d 5488
481f83c7
AS
5489(define_insn "*insv_8_16_reg"
5490 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
1ecba59d
TG
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"))]
e0c17b2d 5494 "TARGET_68020 && TARGET_BITFIELD
0ff27231 5495 && IN_RANGE (INTVAL (operands[2]), 0, 31)
e0c17b2d 5496 && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
481f83c7 5497 && INTVAL (operands[2]) % INTVAL (operands[1]) == 0"
e0c17b2d 5498{
481f83c7
AS
5499 if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
5500 return "bfins %3,%0{%b2:%b1}";
b72f00af 5501
e0c17b2d 5502 if (INTVAL (operands[1]) == 8)
c223cf45
BI
5503 return "move%.b %3,%0";
5504 return "move%.w %3,%0";
5505})
e0c17b2d
RS
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
c16eadc7 5513; than an odd byte aligned bit-field instruction.
e0c17b2d 5514;
481f83c7 5515(define_insn "*extzv_32_mem"
8406d023 5516 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2c8ec431 5517 (zero_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
1ecba59d 5518 (const_int 32)
c77e04ae 5519 (match_operand:SI 2 "const_int_operand" "n")))]
e0c17b2d 5520 "TARGET_68020 && TARGET_BITFIELD
c77e04ae 5521 && (INTVAL (operands[2]) % 8) == 0
5bfed9a9
GJL
5522 && ! mode_dependent_address_p (XEXP (operands[1], 0),
5523 MEM_ADDR_SPACE (operands[1]))"
e0c17b2d
RS
5524{
5525 operands[1]
b72f00af 5526 = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8);
e0c17b2d 5527
c223cf45
BI
5528 return "move%.l %1,%0";
5529})
e0c17b2d 5530
481f83c7 5531(define_insn "*extzv_8_16_reg"
8406d023 5532 [(set (match_operand:SI 0 "nonimmediate_operand" "=&d")
481f83c7 5533 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1ecba59d
TG
5534 (match_operand:SI 2 "const_int_operand" "n")
5535 (match_operand:SI 3 "const_int_operand" "n")))]
e0c17b2d 5536 "TARGET_68020 && TARGET_BITFIELD
0ff27231 5537 && IN_RANGE (INTVAL (operands[3]), 0, 31)
bb14e228 5538 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
481f83c7 5539 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0"
e0c17b2d 5540{
481f83c7
AS
5541 if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
5542 return "bfextu %1{%b3:%b2},%0";
e0c17b2d 5543
c223cf45 5544 output_asm_insn ("clr%.l %0", operands);
e0c17b2d 5545 if (INTVAL (operands[2]) == 8)
c223cf45
BI
5546 return "move%.b %1,%0";
5547 return "move%.w %1,%0";
5548})
e0c17b2d
RS
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
c16eadc7 5555; than an odd byte aligned bit-field instruction.
e0c17b2d 5556;
481f83c7 5557(define_insn "*extv_32_mem"
8406d023 5558 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2c8ec431 5559 (sign_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
1ecba59d 5560 (const_int 32)
c77e04ae 5561 (match_operand:SI 2 "const_int_operand" "n")))]
e0c17b2d 5562 "TARGET_68020 && TARGET_BITFIELD
c77e04ae 5563 && (INTVAL (operands[2]) % 8) == 0
5bfed9a9
GJL
5564 && ! mode_dependent_address_p (XEXP (operands[1], 0),
5565 MEM_ADDR_SPACE (operands[1]))"
e0c17b2d
RS
5566{
5567 operands[1]
b72f00af 5568 = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8);
e0c17b2d 5569
c223cf45
BI
5570 return "move%.l %1,%0";
5571})
e0c17b2d 5572
481f83c7 5573(define_insn "*extv_8_16_reg"
8406d023 5574 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
481f83c7 5575 (sign_extract:SI (match_operand:SI 1 "register_operand" "d")
1ecba59d
TG
5576 (match_operand:SI 2 "const_int_operand" "n")
5577 (match_operand:SI 3 "const_int_operand" "n")))]
e0c17b2d 5578 "TARGET_68020 && TARGET_BITFIELD
0ff27231 5579 && IN_RANGE (INTVAL (operands[3]), 0, 31)
bb14e228 5580 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
481f83c7 5581 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0"
e0c17b2d 5582{
481f83c7
AS
5583 if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
5584 return "bfexts %1{%b3:%b2},%0";
e0c17b2d
RS
5585
5586 if (INTVAL (operands[2]) == 8)
c223cf45
BI
5587 return "move%.b %1,%0\;extb%.l %0";
5588 return "move%.w %1,%0\;ext%.l %0";
5589})
e0c17b2d 5590\f
c16eadc7 5591;; Bit-field instructions, general cases.
e0c17b2d
RS
5592;; "o,d" constraint causes a nonoffsettable memref to match the "o"
5593;; so that its address is reloaded.
5594
83199882 5595(define_expand "extv"
3670ec28 5596 [(set (match_operand:SI 0 "register_operand" "")
83199882 5597 (sign_extract:SI (match_operand:SI 1 "general_operand" "")
3670ec28
RZ
5598 (match_operand:SI 2 "const_int_operand" "")
5599 (match_operand:SI 3 "const_int_operand" "")))]
83199882
RK
5600 "TARGET_68020 && TARGET_BITFIELD"
5601 "")
5602
481f83c7 5603(define_insn "*extv_bfexts_mem"
3670ec28 5604 [(set (match_operand:SI 0 "register_operand" "=d")
83199882 5605 (sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
3670ec28
RZ
5606 (match_operand:SI 2 "nonmemory_operand" "dn")
5607 (match_operand:SI 3 "nonmemory_operand" "dn")))]
e0c17b2d 5608 "TARGET_68020 && TARGET_BITFIELD"
4b3d1177 5609 "bfexts %1{%b3:%b2},%0")
e0c17b2d 5610
83199882 5611(define_expand "extzv"
3670ec28 5612 [(set (match_operand:SI 0 "register_operand" "")
83199882 5613 (zero_extract:SI (match_operand:SI 1 "general_operand" "")
3670ec28
RZ
5614 (match_operand:SI 2 "const_int_operand" "")
5615 (match_operand:SI 3 "const_int_operand" "")))]
6cebc6cb
BS
5616 "TARGET_68020 && TARGET_BITFIELD"
5617 "")
e0c17b2d 5618
6cebc6cb
BS
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"
c223cf45 5625{
6cebc6cb
BS
5626 return "bfextu %1{%b3:%b2},%0";
5627})
1afac9a6 5628
6cebc6cb
BS
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})
e0c17b2d 5642
6cebc6cb
BS
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"
1afac9a6 5649{
6cebc6cb
BS
5650 return "bfclr %0{%b2:%b1}";
5651})
1afac9a6 5652
6cebc6cb
BS
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})
e0c17b2d 5662
6cebc6cb
BS
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 "
c223cf45 5670{
6cebc6cb
BS
5671 /* Special case initializing a field to all ones. */
5672 if (GET_CODE (operands[3]) == CONST_INT)
1afac9a6 5673 {
6cebc6cb
BS
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
1afac9a6 5679 }
6cebc6cb 5680}")
1afac9a6 5681
6cebc6cb
BS
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}")
e0c17b2d 5689
6cebc6cb
BS
5690;; Now recognize bit-field insns that operate on registers
5691;; (or at least were intended to do so).
1afac9a6 5692
6cebc6cb
BS
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")
c05148e8 5700
6cebc6cb
BS
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)"
c05148e8 5707{
6cebc6cb
BS
5708 return "bfextu %1{%b3:%b2},%0";
5709})
c05148e8 5710
6cebc6cb
BS
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)"
c05148e8 5717{
6cebc6cb
BS
5718 return "bfclr %0{%b2:%b1}";
5719})
c05148e8 5720
6cebc6cb
BS
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)"
c05148e8 5727{
6cebc6cb
BS
5728 return "bfset %0{%b2:%b1}";
5729})
c05148e8 5730
6cebc6cb
BS
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)"
c05148e8 5737{
6cebc6cb
BS
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"
7a34bba9 5755{
6cebc6cb
BS
5756 return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
5757})
7a34bba9 5758
6cebc6cb
BS
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"
c05148e8 5764{
6cebc6cb
BS
5765 return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
5766})
c05148e8 5767
6cebc6cb
BS
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"
c05148e8 5774{
6cebc6cb
BS
5775 return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
5776})
c05148e8 5777
6cebc6cb
BS
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"
c05148e8 5784{
6cebc6cb
BS
5785 return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
5786})
e0c17b2d
RS
5787\f
5788;; Unconditional and other jump instructions
5789(define_insn "jump"
5790 [(set (pc)
5791 (label_ref (match_operand 0 "" "")))]
5792 ""
da398bb5 5793 "jra %l0"
c47b0cb4 5794 [(set_attr "type" "bra")])
e0c17b2d 5795
e0c17b2d
RS
5796(define_expand "tablejump"
5797 [(parallel [(set (pc) (match_operand 0 "" ""))
5798 (use (label_ref (match_operand 1 "" "")))])]
5799 ""
e0c17b2d 5800{
143015c4 5801#if CASE_VECTOR_PC_RELATIVE
1d8eaa6b 5802 operands[0] = gen_rtx_PLUS (SImode, pc_rtx,
c24900be
MP
5803 TARGET_LONG_JUMP_TABLE_OFFSETS
5804 ? operands[0]
5805 : gen_rtx_SIGN_EXTEND (SImode, operands[0]));
e0c17b2d 5806#endif
428511bb 5807})
e0c17b2d
RS
5808
5809;; Jump to variable address from dispatch table of absolute addresses.
c47b0cb4 5810(define_insn "*tablejump_internal"
e0c17b2d
RS
5811 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
5812 (use (label_ref (match_operand 1 "" "")))]
5813 ""
4b3d1177
KH
5814{
5815 return MOTOROLA ? "jmp (%0)" : "jmp %0@";
5816}
96fcacb7 5817 [(set_attr "type" "jmp")])
e0c17b2d
RS
5818
5819;; Jump to variable address from dispatch table of relative addresses.
c24900be
MP
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"
e0c17b2d 5835 [(set (pc)
9fb8a974
RK
5836 (plus:SI (pc)
5837 (sign_extend:SI (match_operand:HI 0 "register_operand" "r"))))
e0c17b2d 5838 (use (label_ref (match_operand 1 "" "")))]
c24900be 5839 "!TARGET_LONG_JUMP_TABLE_OFFSETS"
c223cf45 5840{
e0c17b2d 5841#ifdef ASM_RETURN_CASE_JUMP
c223cf45 5842 ASM_RETURN_CASE_JUMP;
e0c17b2d 5843#else
9425fb04 5844 if (TARGET_COLDFIRE)
641241db 5845 {
c1c1d123 5846 if (ADDRESS_REG_P (operands[0]))
4b3d1177
KH
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)";
c1c1d123 5850 else
4b3d1177 5851 return "extl %0\;jmp pc@(2,%0:l)";
641241db
RK
5852 }
5853 else
4b3d1177 5854 return MOTOROLA ? "jmp (2,pc,%0.w)" : "jmp pc@(2,%0:w)";
e0c17b2d 5855#endif
c223cf45 5856})
e0c17b2d
RS
5857
5858;; Decrement-and-branch insns.
da398bb5 5859(define_insn "*dbne_hi"
e0c17b2d
RS
5860 [(set (pc)
5861 (if_then_else
8406d023 5862 (ne (match_operand:HI 0 "nonimmediate_operand" "+d*g")
e0c17b2d
RS
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)))]
9425fb04 5869 "!TARGET_COLDFIRE"
e0c17b2d 5870{
e0c17b2d 5871 if (DATA_REG_P (operands[0]))
c223cf45 5872 return "dbra %0,%l1";
e0c17b2d 5873 if (GET_CODE (operands[0]) == MEM)
da398bb5
RZ
5874 return "subq%.w #1,%0\;jcc %l1";
5875 return "subq%.w #1,%0\;cmp%.w #-1,%0\;jne %l1";
c223cf45 5876})
e0c17b2d 5877
da398bb5 5878(define_insn "*dbne_si"
e0c17b2d
RS
5879 [(set (pc)
5880 (if_then_else
8406d023 5881 (ne (match_operand:SI 0 "nonimmediate_operand" "+d*g")
e0c17b2d
RS
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)))]
9425fb04 5888 "!TARGET_COLDFIRE"
e0c17b2d 5889{
3b4b85c9 5890 if (DATA_REG_P (operands[0]))
da398bb5 5891 return "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1";
3b4b85c9 5892 if (GET_CODE (operands[0]) == MEM)
da398bb5
RZ
5893 return "subq%.l #1,%0\;jcc %l1";
5894 return "subq%.l #1,%0\;cmp%.l #-1,%0\;jne %l1";
c223cf45 5895})
e0c17b2d 5896
b4ac57ab
RS
5897;; Two dbra patterns that use REG_NOTES info generated by strength_reduce.
5898
da398bb5 5899(define_insn "*dbge_hi"
b4ac57ab
RS
5900 [(set (pc)
5901 (if_then_else
8406d023 5902 (ge (plus:HI (match_operand:HI 0 "nonimmediate_operand" "+d*am")
b4ac57ab
RS
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)))]
9425fb04 5910 "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)"
b4ac57ab 5911{
3b4b85c9
BI
5912 if (DATA_REG_P (operands[0]))
5913 return "dbra %0,%l1";
5914 if (GET_CODE (operands[0]) == MEM)
da398bb5
RZ
5915 return "subq%.w #1,%0\;jcc %l1";
5916 return "subq%.w #1,%0\;cmp%.w #-1,%0\;jne %l1";
c223cf45 5917})
e0c17b2d 5918
8f61c2cc
MM
5919(define_expand "decrement_and_branch_until_zero"
5920 [(parallel [(set (pc)
5921 (if_then_else
8406d023 5922 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "")
8f61c2cc
MM
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
da398bb5 5933(define_insn "*dbge_si"
e0c17b2d
RS
5934 [(set (pc)
5935 (if_then_else
8406d023 5936 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+d*am")
b4ac57ab 5937 (const_int -1))
e0c17b2d
RS
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)))]
9425fb04 5944 "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)"
e0c17b2d 5945{
3b4b85c9 5946 if (DATA_REG_P (operands[0]))
da398bb5 5947 return "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1";
3b4b85c9 5948 if (GET_CODE (operands[0]) == MEM)
da398bb5
RZ
5949 return "subq%.l #1,%0\;jcc %l1";
5950 return "subq%.l #1,%0\;cmp%.l #-1,%0\;jne %l1";
c223cf45 5951})
e0c17b2d 5952
f7e70894
RS
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
e0c17b2d
RS
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.
e0c17b2d 5993 ""
e0c17b2d 5994{
29ca003a 5995 operands[0] = m68k_legitimize_call_address (operands[0]);
428511bb 5996})
e0c17b2d 5997
29ca003a
RS
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"))]
e0c17b2d 6001 ;; Operand 1 not really used on the m68000.
f7e70894 6002 "!SIBLING_CALL_P (insn)"
c223cf45 6003{
29ca003a 6004 return output_call (operands[0]);
96fcacb7
MK
6005}
6006 [(set_attr "type" "jsr")])
e0c17b2d
RS
6007
6008;; Call subroutine, returning value in operand 0
6009;; (which must be a hard register).
e0c17b2d
RS
6010(define_expand "call_value"
6011 [(set (match_operand 0 "" "")
6012 (call (match_operand:QI 1 "memory_operand" "")
29ca003a 6013 (match_operand:SI 2 "general_operand" "")))]
e0c17b2d
RS
6014 ;; Operand 2 not really used on the m68000.
6015 ""
e0c17b2d 6016{
29ca003a 6017 operands[1] = m68k_legitimize_call_address (operands[1]);
428511bb 6018})
e0c17b2d 6019
c47b0cb4 6020(define_insn "*non_symbolic_call_value"
29ca003a 6021 [(set (match_operand 0 "" "=rf,rf")
c47b0cb4 6022 (call (mem:QI (match_operand:SI 1 "non_symbolic_call_operand" "a,W"))
29ca003a 6023 (match_operand:SI 2 "general_operand" "g,g")))]
e0c17b2d 6024 ;; Operand 2 not really used on the m68000.
f7e70894 6025 "!SIBLING_CALL_P (insn)"
c47b0cb4
MK
6026 "jsr %a1"
6027 [(set_attr "type" "jsr")
c47b0cb4
MK
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"
c223cf45 6036{
29ca003a 6037 operands[0] = operands[1];
c47b0cb4
MK
6038 return m68k_symbolic_call;
6039}
6040 [(set_attr "type" "jsr")
c47b0cb4
MK
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")
c47b0cb4 6056 (set_attr "opx" "1")])
e0c17b2d 6057
e165d9e5
TW
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"
e165d9e5
TW
6066{
6067 int i;
6068
58d745ec 6069 emit_call_insn (gen_call (operands[0], const0_rtx));
e165d9e5
TW
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;
428511bb 6084})
e165d9e5
TW
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"
d1b3178b 6090 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
e165d9e5 6091 ""
6cebc6cb
BS
6092 ""
6093 [(set_attr "flags_valid" "unchanged")])
e165d9e5 6094
e0c17b2d
RS
6095(define_insn "nop"
6096 [(const_int 0)]
6097 ""
c47b0cb4 6098 "nop"
6cebc6cb
BS
6099 [(set_attr "type" "nop")
6100 (set_attr "flags_valid" "unchanged")])
e0c17b2d 6101
a40ed0f3
KH
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{
f7e70894
RS
6114 m68k_expand_epilogue (false);
6115 DONE;
6116})
6117
6118(define_expand "sibcall_epilogue"
6119 [(return)]
6120 ""
6121{
6122 m68k_expand_epilogue (true);
a40ed0f3
KH
6123 DONE;
6124})
6125
b4ac57ab 6126;; Used for frameless functions which save no regs and allocate no locals.
a40ed0f3 6127(define_expand "return"
e0c17b2d 6128 [(return)]
a2bda628 6129 "m68k_use_return_insn ()"
a40ed0f3
KH
6130 "")
6131
6132(define_insn "*return"
6133 [(return)]
6134 ""
e0c17b2d 6135{
a4242737 6136 switch (m68k_get_function_kind (current_function_decl))
a40ed0f3 6137 {
a4242737
KH
6138 case m68k_fk_interrupt_handler:
6139 return "rte";
6140
6141 case m68k_fk_interrupt_thread:
6142 return "sleep";
6143
6144 default:
38173d38 6145 if (crtl->args.pops_args)
a4242737 6146 {
38173d38 6147 operands[0] = GEN_INT (crtl->args.pops_args);
a4242737
KH
6148 return "rtd %0";
6149 }
6150 else
6151 return "rts";
a40ed0f3 6152 }
c47b0cb4
MK
6153}
6154 [(set_attr "type" "rts")])
a40ed0f3
KH
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{
0a81f074
RS
6203 operands[2] = gen_frame_mem (SImode,
6204 plus_constant (Pmode, stack_pointer_rtx, -4));
a40ed0f3
KH
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);
4b3d1177
KH
6218 if (!MOTOROLA)
6219 return "link %0,%1";
6220 else if (INTVAL (operands[1]) >= -0x8000)
6221 return "link.w %0,%1";
a40ed0f3 6222 else
4b3d1177 6223 return "link.l %0,%1";
96fcacb7
MK
6224}
6225 [(set_attr "type" "link")])
a40ed0f3
KH
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 ""
c47b0cb4
MK
6246 "unlk %0"
6247 [(set_attr "type" "unlk")])
a40ed0f3
KH
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);
4b3d1177 6257 return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0";
a40ed0f3
KH
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");
c223cf45 6274})
e0c17b2d
RS
6275
6276(define_insn "indirect_jump"
560df144 6277 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
e0c17b2d 6278 ""
c47b0cb4
MK
6279 "jmp %a0"
6280 [(set_attr "type" "jmp")])
e0c17b2d
RS
6281\f
6282;; This should not be used unless the add/sub insns can't be.
6283
e59d83aa 6284(define_insn "*lea"
8406d023 6285 [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
e0c17b2d
RS
6286 (match_operand:QI 1 "address_operand" "p"))]
6287 ""
e59d83aa 6288 "lea %a1,%0")
e0c17b2d
RS
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
39250081 6295(define_peephole2
428511bb 6296 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
39250081
RZ
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);")
e0c17b2d
RS
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
39250081
RZ
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
428511bb 6318 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
39250081
RZ
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))]
e0c17b2d 6326{
39250081
RZ
6327 operands[0] = GEN_INT (INTVAL (operands[0]) - 4);
6328 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
c223cf45 6329})
e0c17b2d
RS
6330
6331;; Speed up stack adjust followed by a fullword fixedpoint push.
39250081
RZ
6332;; Constant operands need special care, as replacing a "pea X.w" with
6333;; "move.l #X,(%sp)" is often not a win.
e0c17b2d 6334
39250081
RZ
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
428511bb 6372 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
39250081
RZ
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 "")
b4ac57ab 6442
39250081
RZ
6443(define_peephole2
6444 [(set (match_operand:SI 0 "register_operand" "")
ed359ebc 6445 (const_int 0))
39250081
RZ
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 "")
ed359ebc 6452
b4ac57ab
RS
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.
9cebe490 6468;;
6cebc6cb 6469(define_mode_iterator DBCC [HI SI])
161eb4fc
RH
6470
6471(define_peephole
6cebc6cb
BS
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" "")])
b4ac57ab
RS
6475 (label_ref (match_operand 2 "" ""))
6476 (pc)))
6477 (parallel
6478 [(set (pc)
6479 (if_then_else
6cebc6cb 6480 (ne (match_operand:DBCC 0 "register_operand" "")
b4ac57ab
RS
6481 (const_int 0))
6482 (label_ref (match_operand 1 "" ""))
6483 (pc)))
6484 (set (match_dup 0)
6cebc6cb
BS
6485 (plus:DBCC (match_dup 0)
6486 (const_int -1)))])]
6487 "!TARGET_COLDFIRE && DATA_REG_P (operands[0])"
b4ac57ab 6488{
6cebc6cb
BS
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);
c223cf45
BI
6492 return "";
6493})
b4ac57ab
RS
6494
6495(define_peephole
6cebc6cb
BS
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" "")])
b4ac57ab
RS
6499 (label_ref (match_operand 2 "" ""))
6500 (pc)))
6501 (parallel
6502 [(set (pc)
6503 (if_then_else
6cebc6cb
BS
6504 (ge (plus:DBCC (match_operand:DBCC 0 "register_operand" "")
6505 (const_int -1))
b4ac57ab
RS
6506 (const_int 0))
6507 (label_ref (match_operand 1 "" ""))
6508 (pc)))
6509 (set (match_dup 0)
6cebc6cb
BS
6510 (plus:DBCC (match_dup 0)
6511 (const_int -1)))])]
6512 "!TARGET_COLDFIRE && DATA_REG_P (operands[0])"
b4ac57ab 6513{
6cebc6cb
BS
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);
c223cf45
BI
6517 return "";
6518})
e0c17b2d 6519\f
2743360a 6520(define_insn "extendsfxf2"
8406d023 6521 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f")
ab87f8c8 6522 (float_extend:XF (match_operand:SF 1 "general_operand" "f,rmF")))]
2743360a 6523 "TARGET_68881"
2743360a
RS
6524{
6525 if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
6526 {
6527 if (REGNO (operands[0]) == REGNO (operands[1]))
6528 {
6cebc6cb 6529 /* Extending float to double in an fp-reg is a no-op. */
c223cf45 6530 return "";
2743360a 6531 }
c223cf45 6532 return "f%$move%.x %1,%0";
2743360a
RS
6533 }
6534 if (FP_REG_P (operands[0]))
ab87f8c8
JL
6535 {
6536 if (FP_REG_P (operands[1]))
c223cf45 6537 return "f%$move%.x %1,%0";
ab87f8c8 6538 else if (ADDRESS_REG_P (operands[1]))
c223cf45 6539 return "move%.l %1,%-\;f%$move%.s %+,%0";
ab87f8c8
JL
6540 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
6541 return output_move_const_single (operands);
c223cf45 6542 return "f%$move%.s %f1,%0";
ab87f8c8 6543 }
c223cf45
BI
6544 return "fmove%.x %f1,%0";
6545})
2743360a
RS
6546
6547
6548(define_insn "extenddfxf2"
8406d023 6549 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f")
2743360a 6550 (float_extend:XF
ab87f8c8 6551 (match_operand:DF 1 "general_operand" "f,rmE")))]
2743360a 6552 "TARGET_68881"
2743360a
RS
6553{
6554 if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
6555 {
6556 if (REGNO (operands[0]) == REGNO (operands[1]))
6557 {
6cebc6cb 6558 /* Extending float to double in an fp-reg is a no-op. */
c223cf45 6559 return "";
2743360a 6560 }
c223cf45 6561 return "fmove%.x %1,%0";
2743360a
RS
6562 }
6563 if (FP_REG_P (operands[0]))
ab87f8c8
JL
6564 {
6565 if (REG_P (operands[1]))
6566 {
6567 rtx xoperands[2];
c5c76735 6568 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
c223cf45
BI
6569 output_asm_insn ("move%.l %1,%-", xoperands);
6570 output_asm_insn ("move%.l %1,%-", operands);
6571 return "f%&move%.d %+,%0";
ab87f8c8
JL
6572 }
6573 if (GET_CODE (operands[1]) == CONST_DOUBLE)
6574 return output_move_const_double (operands);
c223cf45 6575 return "f%&move%.d %f1,%0";
ab87f8c8 6576 }
c223cf45
BI
6577 return "fmove%.x %f1,%0";
6578})
2743360a
RS
6579
6580(define_insn "truncxfdf2"
8406d023 6581 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!r")
2743360a
RS
6582 (float_truncate:DF
6583 (match_operand:XF 1 "general_operand" "f,f")))]
6584 "TARGET_68881"
2743360a
RS
6585{
6586 if (REG_P (operands[0]))
6587 {
c223cf45 6588 output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1d8eaa6b 6589 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
c223cf45 6590 return "move%.l %+,%0";
2743360a 6591 }
c223cf45
BI
6592 return "fmove%.d %f1,%0";
6593})
935fb288 6594
2f6fc0b6
AS
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
dcc21c4c
PB
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))]
de6c5979 6606 "TARGET_68881 && flag_unsafe_math_optimizations"
0e73100c
RK
6607{
6608 if (FP_REG_P (operands[1]))
c223cf45 6609 return "fsin%.x %1,%0";
0e73100c 6610 else
dcc21c4c 6611 return "fsin%.<FP:prec> %1,%0";
c223cf45 6612})
0e73100c 6613
dcc21c4c
PB
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))]
de6c5979 6618 "TARGET_68881 && flag_unsafe_math_optimizations"
0e73100c
RK
6619{
6620 if (FP_REG_P (operands[1]))
c223cf45 6621 return "fcos%.x %1,%0";
0e73100c 6622 else
dcc21c4c 6623 return "fcos%.<FP:prec> %1,%0";
c223cf45 6624})
0e73100c 6625
6cebc6cb 6626;; Unconditional traps are assumed to have const_true_rtx for the condition.
a157febd 6627(define_insn "trap"
6cebc6cb 6628 [(trap_if (const_int -1) (const_int 7))]
a157febd 6629 ""
c47b0cb4
MK
6630 "trap #7"
6631 [(set_attr "type" "trap")])
a157febd 6632
6cebc6cb
BS
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"
f90b7a5a 6638 [(trap_if (match_operator 0 "ordered_comparison_operator"
6cebc6cb
BS
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"
67595cbb 6643{
6cebc6cb
BS
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})
f90b7a5a 6661
6cebc6cb 6662(define_insn "ctrap<mode>4_cf"
f90b7a5a 6663 [(trap_if (match_operator 0 "ordered_comparison_operator"
6cebc6cb
BS
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)
a157febd 6672 {
c223cf45
BI
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";
4761e388 6683 default: gcc_unreachable ();
a157febd 6684 }
c223cf45 6685})
c47b0cb4 6686
96fcacb7
MK
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
c47b0cb4
MK
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")])
b8c96320
MK
6706
6707(include "cf.md")
7b45b59b 6708(include "sync.md")
dcca1b05
KK
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];")
bcff0913 6742
57d7fe86
JL
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" ""))
57d7fe86 6766 (set (pc) (if_then_else (match_operator 5 "equality_comparison_operator"
6cebc6cb 6767 [(match_operand:SI 2 "register_operand" "") (match_dup 0)])
57d7fe86
JL
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)
05d41b0c
AS
6773 && DATA_REG_P (operands[2])
6774 && !rtx_equal_p (operands[0], operands[2])"
57d7fe86 6775 [(set (match_dup 2) (plus:SI (match_dup 2) (match_dup 6)))
6cebc6cb 6776 (set (pc) (if_then_else (match_op_dup 5 [(match_dup 2) (const_int 0)])
57d7fe86
JL
6777 (match_dup 3)
6778 (match_dup 4)))]
6779 "operands[6] = GEN_INT (-INTVAL (operands[1]));")
6780
bcff0913
JL
6781(define_peephole2
6782 [(set (match_operand:SI 0 "register_operand" "")
6783 (match_operand:SI 1 "pow2_m1_operand" ""))
6cebc6cb
BS
6784 (set (pc) (if_then_else (gtu (match_operand:SI 2 "register_operand" "")
6785 (match_operand:SI 3 "register_operand" ""))
bcff0913
JL
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)))
6cebc6cb 6796 (set (pc) (if_then_else (ne (match_dup 7) (const_int 0))
bcff0913
JL
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
6cebc6cb
BS
6805 [(set (pc) (if_then_else (gtu (match_operand:SI 0 "register_operand" "")
6806 (match_operand:SI 1 "pow2_m1_operand" ""))
bcff0913
JL
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)))
6cebc6cb 6815 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
bcff0913
JL
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" ""))
6cebc6cb
BS
6822 (set (pc) (if_then_else (leu (match_operand:SI 2 "register_operand" "")
6823 (match_operand:SI 3 "register_operand" ""))
bcff0913
JL
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)))
6cebc6cb 6834 (set (pc) (if_then_else (eq (match_dup 7) (const_int 0))
bcff0913
JL
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}")
bcff0913 6841(define_peephole2
6cebc6cb
BS
6842 [(set (pc) (if_then_else (leu (match_operand:SI 0 "register_operand" "")
6843 (match_operand:SI 1 "pow2_m1_operand" ""))
bcff0913
JL
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)))
6cebc6cb 6852 (set (pc) (if_then_else (eq (match_dup 0) (const_int 0))
bcff0913
JL
6853 (match_dup 2) (match_dup 3)))]
6854 "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }")
6855
83ad4fac
JL
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
6cebc6cb
BS
6861 [(set (pc) (if_then_else (match_operator 1 "swap_peephole_relational_operator"
6862 [(match_operand:SI 0 "register_operand" "")
6863 (const_int 65535)])
83ad4fac
JL
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)))
6cebc6cb 6871 (set (pc) (if_then_else (match_op_dup 1 [(subreg:HI (match_dup 0) 2) (const_int 0)])
83ad4fac
JL
6872 (match_dup 2) (match_dup 3)))]
6873 "")