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