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