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