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