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