]>
Commit | Line | Data |
---|---|---|
996a5f59 | 1 | ;;- Machine description for GNU compiler, Motorola 68000 Version |
7adcbafe | 2 | ;; Copyright (C) 1987-2022 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 MK |
195 | ;; Type of the Y operand. |
196 | ;; See m68k.c: enum attr_op_type. | |
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 MK |
206 | ;; Type of the X operand. |
207 | ;; See m68k.c: enum attr_op_type. | |
208 | (define_attr "opx_type" | |
209 | "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l" | |
210 | (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk, | |
211 | unknown") (const_string "none") | |
212 | (eq_attr "type" "pea") (const_string "mem1") | |
213 | (eq_attr "type" "jmp,jsr") | |
214 | (symbol_ref "m68k_sched_attr_opx_type (insn, 1)")] | |
215 | (symbol_ref "m68k_sched_attr_opx_type (insn, 0)"))) | |
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 | "") |