|
|
1.1 root 1: ;;- Machine description for GNU compiler
2: ;;- Motorola 68000 Version
3: ;; Copyright (C) 1987, 1988 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: ;;- "%!" ??? "cc" (not used)
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 outputing
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 appropriatly 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: /* For sake of 3b1, set flag saying we need to define the symbol
876: LD%n (with value L%n-LI%n) at the end of the switch table. */
877: RTX_INTEGRATED_P (next_real_insn (XEXP (labelref, 0))) = 1;
878: #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
879: }
880: #endif /* SGS_NO_LI */
881: return \"move%.w %1,%0\";
882: }")
883:
884: (define_insn "movstricthi"
885: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
886: (match_operand:HI 1 "general_operand" "rmn"))]
887: ""
888: "*
889: {
890: if (GET_CODE (operands[1]) == CONST_INT)
891: {
892: if (operands[1] == const0_rtx
893: && (DATA_REG_P (operands[0])
894: || GET_CODE (operands[0]) == MEM)
895: /* clr insns on 68000 read before writing.
896: This isn't so on the 68010, but we have no alternative for it. */
897: && (TARGET_68020
898: || !(GET_CODE (operands[0]) == MEM
899: && MEM_VOLATILE_P (operands[0]))))
900: return \"clr%.w %0\";
901: }
902: return \"move%.w %1,%0\";
903: }")
904:
905: (define_insn "movqi"
906: [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")
907: (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]
908: ""
909: "*
910: {
911: rtx xoperands[4];
912:
913: /* This is probably useless, since it loses for pushing a struct
914: of several bytes a byte at a time. */
915: if (GET_CODE (operands[0]) == MEM
916: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
917: && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
918: {
919: xoperands[1] = operands[1];
920: xoperands[2]
921: = gen_rtx (MEM, QImode,
922: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
923: xoperands[3] = stack_pointer_rtx;
924: /* Just pushing a byte puts it in the high byte of the halfword. */
925: /* We must put it in the low-order, high-numbered byte. */
926: output_asm_insn (\"subq%.w %#2,%3\;move%.b %1,%2\", xoperands);
927: return \"\";
928: }
929:
930: if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
931: {
932: xoperands[1] = operands[1];
933: xoperands[2]
934: = gen_rtx (MEM, QImode,
935: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
936: xoperands[3] = stack_pointer_rtx;
937: /* Just pushing a byte puts it in the high byte of the halfword. */
938: /* We must put it in the low half, the second byte. */
939: output_asm_insn (\"subq%.w %#2,%3\;move%.b %1,%2\", xoperands);
940: return \"move%.w %+,%0\";
941: }
942: if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
943: {
944: xoperands[0] = operands[0];
945: xoperands[1] = operands[1];
946: xoperands[2]
947: = gen_rtx (MEM, QImode,
948: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
949: xoperands[3] = stack_pointer_rtx;
950: output_asm_insn (\"move%.w %1,%-\;move%.b %2,%0\;addq%.w %#2,%3\", xoperands);
951: return \"\";
952: }
953: /* clr and st insns on 68000 read before writing.
954: This isn't so on the 68010, but we have no alternative for it. */
955: if (TARGET_68020
956: || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
957: {
958: if (operands[1] == const0_rtx)
959: return \"clr%.b %0\";
960: if (GET_CODE (operands[1]) == CONST_INT
961: && INTVAL (operands[1]) == -1)
962: {
963: CC_STATUS_INIT;
964: return \"st %0\";
965: }
966: }
967: if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
968: return \"move%.l %1,%0\";
969: if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
970: return \"move%.w %1,%0\";
971: return \"move%.b %1,%0\";
972: }")
973:
974: (define_insn "movstrictqi"
975: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
976: (match_operand:QI 1 "general_operand" "dmn"))]
977: ""
978: "*
979: {
980: if (operands[1] == const0_rtx
981: /* clr insns on 68000 read before writing.
982: This isn't so on the 68010, but we have no alternative for it. */
983: && (TARGET_68020
984: || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
985: return \"clr%.b %0\";
986: return \"move%.b %1,%0\";
987: }")
988:
989: (define_insn "movsf"
990: [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm")
991: (match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))]
992: ; [(set (match_operand:SF 0 "general_operand" "=rmf")
993: ; (match_operand:SF 1 "general_operand" "rmfF"))]
994: ""
995: "*
996: {
997: if (which_alternative >= 4)
998: return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\";
999: if (FPA_REG_P (operands[0]))
1000: {
1001: if (FPA_REG_P (operands[1]))
1002: return \"fpmove%.s %x1,%x0\";
1003: else if (GET_CODE (operands[1]) == CONST_DOUBLE)
1004: return output_move_const_single (operands);
1005: else if (FP_REG_P (operands[1]))
1006: return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\";
1007: return \"fpmove%.s %x1,%x0\";
1008: }
1009: if (FPA_REG_P (operands[1]))
1010: {
1011: if (FP_REG_P (operands[0]))
1012: return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\";
1013: else
1014: return \"fpmove%.s %x1,%x0\";
1015: }
1016: if (FP_REG_P (operands[0]))
1017: {
1018: if (FP_REG_P (operands[1]))
1019: return \"f%$move%.x %1,%0\";
1020: else if (ADDRESS_REG_P (operands[1]))
1021: return \"move%.l %1,%-\;f%$move%.s %+,%0\";
1022: else if (GET_CODE (operands[1]) == CONST_DOUBLE)
1023: return output_move_const_single (operands);
1024: return \"f%$move%.s %f1,%0\";
1025: }
1026: if (FP_REG_P (operands[1]))
1027: {
1028: if (ADDRESS_REG_P (operands[0]))
1029: return \"fmove%.s %1,%-\;move%.l %+,%0\";
1030: return \"fmove%.s %f1,%0\";
1031: }
1032: return \"move%.l %1,%0\";
1033: }")
1034:
1035: (define_insn "movdf"
1036: [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>,y,rm,x,!x,!rm")
1037: (match_operand:DF 1 "general_operand" "rf,m,rofE<>,rmE,y,xH,rm,x"))]
1038: ; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>")
1039: ; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
1040: ""
1041: "*
1042: {
1043: if (which_alternative == 6)
1044: return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\";
1045: if (FPA_REG_P (operands[0]))
1046: {
1047: if (GET_CODE (operands[1]) == CONST_DOUBLE)
1048: return output_move_const_double (operands);
1049: if (FP_REG_P (operands[1]))
1050: return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\";
1051: return \"fpmove%.d %x1,%x0\";
1052: }
1053: else if (FPA_REG_P (operands[1]))
1054: {
1055: if (FP_REG_P(operands[0]))
1056: return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\";
1057: else
1058: return \"fpmove%.d %x1,%x0\";
1059: }
1060: if (FP_REG_P (operands[0]))
1061: {
1062: if (FP_REG_P (operands[1]))
1063: return \"f%&move%.x %1,%0\";
1064: if (REG_P (operands[1]))
1065: {
1066: rtx xoperands[2];
1067: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1068: output_asm_insn (\"move%.l %1,%-\", xoperands);
1069: output_asm_insn (\"move%.l %1,%-\", operands);
1070: return \"f%&move%.d %+,%0\";
1071: }
1072: if (GET_CODE (operands[1]) == CONST_DOUBLE)
1073: return output_move_const_double (operands);
1074: return \"f%&move%.d %f1,%0\";
1075: }
1076: else if (FP_REG_P (operands[1]))
1077: {
1078: if (REG_P (operands[0]))
1079: {
1080: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1081: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1082: return \"move%.l %+,%0\";
1083: }
1084: else
1085: return \"fmove%.d %f1,%0\";
1086: }
1087: return output_move_double (operands);
1088: }
1089: ")
1090:
1091: ;; movdi can apply to fp regs in some cases
1092: (define_insn "movdi"
1093: ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1094: [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,y,rm,!*x,!rm")
1095: (match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))]
1096: ; [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm")
1097: ; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))]
1098: ; [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f")
1099: ; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
1100: ""
1101: "*
1102: {
1103: if (which_alternative == 8)
1104: return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\";
1105: if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
1106: return \"fpmove%.d %x1,%x0\";
1107: if (FP_REG_P (operands[0]))
1108: {
1109: if (FP_REG_P (operands[1]))
1110: return \"fmove%.x %1,%0\";
1111: if (REG_P (operands[1]))
1112: {
1113: rtx xoperands[2];
1114: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1115: output_asm_insn (\"move%.l %1,%-\", xoperands);
1116: output_asm_insn (\"move%.l %1,%-\", operands);
1117: return \"fmove%.d %+,%0\";
1118: }
1119: if (GET_CODE (operands[1]) == CONST_DOUBLE)
1120: return output_move_const_double (operands);
1121: return \"fmove%.d %f1,%0\";
1122: }
1123: else if (FP_REG_P (operands[1]))
1124: {
1125: if (REG_P (operands[0]))
1126: {
1127: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1128: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1129: return \"move%.l %+,%0\";
1130: }
1131: else
1132: return \"fmove%.d %f1,%0\";
1133: }
1134: return output_move_double (operands);
1135: }
1136: ")
1137:
1138: ;; Thus goes after the move instructions
1139: ;; because the move instructions are better (require no spilling)
1140: ;; when they can apply. It goes before the add/sub insns
1141: ;; so we will prefer it to them.
1142:
1143: (define_insn "pushasi"
1144: [(set (match_operand:SI 0 "push_operand" "=m")
1145: (match_operand:SI 1 "address_operand" "p"))]
1146: ""
1147: "pea %a1")
1148:
1149: ;; truncation instructions
1150: (define_insn "truncsiqi2"
1151: [(set (match_operand:QI 0 "general_operand" "=dm,d")
1152: (truncate:QI
1153: (match_operand:SI 1 "general_operand" "doJ,i")))]
1154: ""
1155: "*
1156: {
1157: if (GET_CODE (operands[0]) == REG)
1158: {
1159: /* Must clear condition codes, since the mov.l bases them on
1160: the entire 32 bits, not just the desired 8 bits. */
1161: CC_STATUS_INIT;
1162: return \"move%.l %1,%0\";
1163: }
1164: if (GET_CODE (operands[1]) == MEM)
1165: operands[1] = adj_offsettable_operand (operands[1], 3);
1166: return \"move%.b %1,%0\";
1167: }")
1168:
1169: (define_insn "trunchiqi2"
1170: [(set (match_operand:QI 0 "general_operand" "=dm,d")
1171: (truncate:QI
1172: (match_operand:HI 1 "general_operand" "doJ,i")))]
1173: ""
1174: "*
1175: {
1176: if (GET_CODE (operands[0]) == REG
1177: && (GET_CODE (operands[1]) == MEM
1178: || GET_CODE (operands[1]) == CONST_INT))
1179: {
1180: /* Must clear condition codes, since the mov.w bases them on
1181: the entire 16 bits, not just the desired 8 bits. */
1182: CC_STATUS_INIT;
1183: return \"move%.w %1,%0\";
1184: }
1185: if (GET_CODE (operands[0]) == REG)
1186: {
1187: /* Must clear condition codes, since the mov.l bases them on
1188: the entire 32 bits, not just the desired 8 bits. */
1189: CC_STATUS_INIT;
1190: return \"move%.l %1,%0\";
1191: }
1192: if (GET_CODE (operands[1]) == MEM)
1193: operands[1] = adj_offsettable_operand (operands[1], 1);
1194: return \"move%.b %1,%0\";
1195: }")
1196:
1197: (define_insn "truncsihi2"
1198: [(set (match_operand:HI 0 "general_operand" "=dm,d")
1199: (truncate:HI
1200: (match_operand:SI 1 "general_operand" "roJ,i")))]
1201: ""
1202: "*
1203: {
1204: if (GET_CODE (operands[0]) == REG)
1205: {
1206: /* Must clear condition codes, since the mov.l bases them on
1207: the entire 32 bits, not just the desired 8 bits. */
1208: CC_STATUS_INIT;
1209: return \"move%.l %1,%0\";
1210: }
1211: if (GET_CODE (operands[1]) == MEM)
1212: operands[1] = adj_offsettable_operand (operands[1], 2);
1213: return \"move%.w %1,%0\";
1214: }")
1215:
1216: ;; zero extension instructions
1217:
1218: (define_expand "zero_extendhisi2"
1219: [(set (match_operand:SI 0 "register_operand" "")
1220: (const_int 0))
1221: (set (strict_low_part (match_dup 2))
1222: (match_operand:HI 1 "general_operand" ""))]
1223: ""
1224: "
1225: {
1226: operands[1] = make_safe_from (operands[1], operands[0]);
1227: if (GET_CODE (operands[0]) == SUBREG)
1228: operands[2] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[0]),
1229: SUBREG_WORD (operands[0]));
1230: else
1231: operands[2] = gen_rtx (SUBREG, HImode, operands[0], 0);
1232: }")
1233:
1234: (define_expand "zero_extendqihi2"
1235: [(set (match_operand:HI 0 "register_operand" "")
1236: (const_int 0))
1237: (set (strict_low_part (match_dup 2))
1238: (match_operand:QI 1 "general_operand" ""))]
1239: ""
1240: "
1241: {
1242: operands[1] = make_safe_from (operands[1], operands[0]);
1243: if (GET_CODE (operands[0]) == SUBREG)
1244: operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]),
1245: SUBREG_WORD (operands[0]));
1246: else
1247: operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0);
1248: }")
1249:
1250: (define_expand "zero_extendqisi2"
1251: [(set (match_operand:SI 0 "register_operand" "")
1252: (const_int 0))
1253: (set (strict_low_part (match_dup 2))
1254: (match_operand:QI 1 "general_operand" ""))]
1255: ""
1256: "
1257: {
1258: operands[1] = make_safe_from (operands[1], operands[0]);
1259: if (GET_CODE (operands[0]) == SUBREG)
1260: operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]),
1261: SUBREG_WORD (operands[0]));
1262: else
1263: operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0);
1264: }")
1265:
1266: ;; Patterns to recognize zero-extend insns produced by the combiner.
1267: ;; We don't allow both operands in memory, because of aliasing problems.
1268:
1269: (define_insn ""
1270: [(set (match_operand:SI 0 "general_operand" "=do<>,d<")
1271: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rn,m")))]
1272: ""
1273: "*
1274: {
1275: if (DATA_REG_P (operands[0]))
1276: {
1277: if (GET_CODE (operands[1]) == REG
1278: && REGNO (operands[0]) == REGNO (operands[1]))
1279: return \"and%.l %#0xFFFF,%0\";
1280: if (reg_mentioned_p (operands[0], operands[1]))
1281: return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\";
1282: return \"clr%.l %0\;move%.w %1,%0\";
1283: }
1284: else if (GET_CODE (operands[0]) == MEM
1285: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1286: return \"move%.w %1,%0\;clr%.w %0\";
1287: else if (GET_CODE (operands[0]) == MEM
1288: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1289: return \"clr%.w %0\;move%.w %1,%0\";
1290: else
1291: {
1292: output_asm_insn (\"clr%.w %0\", operands);
1293: operands[0] = adj_offsettable_operand (operands[0], 2);
1294: return \"move%.w %1,%0\";
1295: }
1296: }")
1297:
1298: (define_insn ""
1299: [(set (match_operand:HI 0 "general_operand" "=do<>,d")
1300: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "dn,m")))]
1301: ""
1302: "*
1303: {
1304: if (DATA_REG_P (operands[0]))
1305: {
1306: if (GET_CODE (operands[1]) == REG
1307: && REGNO (operands[0]) == REGNO (operands[1]))
1308: return \"and%.w %#0xFF,%0\";
1309: if (reg_mentioned_p (operands[0], operands[1]))
1310: return \"move%.b %1,%0\;and%.w %#0xFF,%0\";
1311: return \"clr%.w %0\;move%.b %1,%0\";
1312: }
1313: else if (GET_CODE (operands[0]) == MEM
1314: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1315: {
1316: if (REGNO (XEXP (XEXP (operands[0], 0), 0))
1317: == STACK_POINTER_REGNUM)
1318: {
1319: output_asm_insn (\"clr%.w %-\", operands);
1320: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
1321: plus_constant (stack_pointer_rtx, 1));
1322: return \"move%.b %1,%0\";
1323: }
1324: else
1325: return \"move%.b %1,%0\;clr%.b %0\";
1326: }
1327: else if (GET_CODE (operands[0]) == MEM
1328: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1329: return \"clr%.b %0\;move%.b %1,%0\";
1330: else
1331: {
1332: output_asm_insn (\"clr%.b %0\", operands);
1333: operands[0] = adj_offsettable_operand (operands[0], 1);
1334: return \"move%.b %1,%0\";
1335: }
1336: }")
1337:
1338: (define_insn ""
1339: [(set (match_operand:SI 0 "general_operand" "=do<>,d")
1340: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "dn,m")))]
1341: ""
1342: "*
1343: {
1344: if (DATA_REG_P (operands[0]))
1345: {
1346: if (GET_CODE (operands[1]) == REG
1347: && REGNO (operands[0]) == REGNO (operands[1]))
1348: return \"and%.l %#0xFF,%0\";
1349: if (reg_mentioned_p (operands[0], operands[1]))
1350: return \"move%.b %1,%0\;and%.l %#0xFF,%0\";
1351: return \"clr%.l %0\;move%.b %1,%0\";
1352: }
1353: else if (GET_CODE (operands[0]) == MEM
1354: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1355: {
1356: operands[0] = XEXP (XEXP (operands[0], 0), 0);
1357: #ifdef MOTOROLA
1358: #ifdef SGS
1359: return \"clr%.l -(%0)\;move%.b %1,3(%0)\";
1360: #else
1361: return \"clr%.l -(%0)\;move%.b %1,(3,%0)\";
1362: #endif
1363: #else
1364: return \"clrl %0@-\;moveb %1,%0@(3)\";
1365: #endif
1366: }
1367: else if (GET_CODE (operands[0]) == MEM
1368: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1369: {
1370: operands[0] = XEXP (XEXP (operands[0], 0), 0);
1371: #ifdef MOTOROLA
1372: #ifdef SGS
1373: return \"clr%.l (%0)+\;move%.b %1,-1(%0)\";
1374: #else
1375: return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\";
1376: #endif
1377: #else
1378: return \"clrl %0@+\;moveb %1,%0@(-1)\";
1379: #endif
1380: }
1381: else
1382: {
1383: output_asm_insn (\"clr%.l %0\", operands);
1384: operands[0] = adj_offsettable_operand (operands[0], 3);
1385: return \"move%.b %1,%0\";
1386: }
1387: }")
1388:
1389: ;; sign extension instructions
1390:
1391: (define_insn "extendhisi2"
1392: [(set (match_operand:SI 0 "general_operand" "=*d,a")
1393: (sign_extend:SI
1394: (match_operand:HI 1 "nonimmediate_operand" "0,rmn")))]
1395: ""
1396: "*
1397: {
1398: if (ADDRESS_REG_P (operands[0]))
1399: return \"move%.w %1,%0\";
1400: return \"ext%.l %0\";
1401: }")
1402:
1403: (define_insn "extendqihi2"
1404: [(set (match_operand:HI 0 "general_operand" "=d")
1405: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1406: ""
1407: "ext%.w %0")
1408:
1409: (define_insn "extendqisi2"
1410: [(set (match_operand:SI 0 "general_operand" "=d")
1411: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1412: "TARGET_68020"
1413: "extb%.l %0")
1414:
1415: ;; Conversions between float and double.
1416:
1417: (define_expand "extendsfdf2"
1418: [(set (match_operand:DF 0 "general_operand" "")
1419: (float_extend:DF
1420: (match_operand:SF 1 "general_operand" "")))]
1421: "TARGET_68881 || TARGET_FPA"
1422: "")
1423:
1424: (define_insn ""
1425: [(set (match_operand:DF 0 "general_operand" "=x,y")
1426: (float_extend:DF
1427: (match_operand:SF 1 "general_operand" "xH,rmF")))]
1428: "TARGET_FPA"
1429: "fpstod %w1,%0")
1430:
1431: (define_insn ""
1432: [(set (match_operand:DF 0 "general_operand" "=*fdm,f")
1433: (float_extend:DF
1434: (match_operand:SF 1 "general_operand" "f,dmF")))]
1435: "TARGET_68881"
1436: "*
1437: {
1438: if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1439: {
1440: if (REGNO (operands[0]) == REGNO (operands[1]))
1441: {
1442: /* Extending float to double in an fp-reg is a no-op.
1443: NOTICE_UPDATE_CC has already assumed that the
1444: cc will be set. So cancel what it did. */
1445: cc_status = cc_prev_status;
1446: return \"\";
1447: }
1448: return \"f%&move%.x %1,%0\";
1449: }
1450: if (FP_REG_P (operands[0]))
1451: return \"f%&move%.s %f1,%0\";
1452: if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
1453: {
1454: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1455: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1456: return \"move%.l %+,%0\";
1457: }
1458: return \"fmove%.d %f1,%0\";
1459: }")
1460:
1461: ;; This cannot output into an f-reg because there is no way to be
1462: ;; sure of truncating in that case.
1463: ;; But on the Sun FPA, we can be sure.
1464: (define_expand "truncdfsf2"
1465: [(set (match_operand:SF 0 "general_operand" "")
1466: (float_truncate:SF
1467: (match_operand:DF 1 "general_operand" "")))]
1468: "TARGET_68881 || TARGET_FPA"
1469: "")
1470:
1471: (define_insn ""
1472: [(set (match_operand:SF 0 "general_operand" "=x,y")
1473: (float_truncate:SF
1474: (match_operand:DF 1 "general_operand" "xH,rmF")))]
1475: "TARGET_FPA"
1476: "fpdtos %y1,%0")
1477:
1478: ;; On the '040 we can truncate in a register accurately and easily.
1479: (define_insn ""
1480: [(set (match_operand:SF 0 "general_operand" "=f")
1481: (float_truncate:SF
1482: (match_operand:DF 1 "general_operand" "fmG")))]
1483: "TARGET_68040_ONLY"
1484: "*
1485: {
1486: if (FP_REG_P (operands[1]))
1487: return \"fsmove%.x %1,%0\";
1488: return \"fsmove%.d %f1,%0\";
1489: }")
1490:
1491: (define_insn ""
1492: [(set (match_operand:SF 0 "general_operand" "=dm")
1493: (float_truncate:SF
1494: (match_operand:DF 1 "general_operand" "f")))]
1495: "TARGET_68881"
1496: "fmove%.s %f1,%0")
1497:
1498: ;; Conversion between fixed point and floating point.
1499: ;; Note that among the fix-to-float insns
1500: ;; the ones that start with SImode come first.
1501: ;; That is so that an operand that is a CONST_INT
1502: ;; (and therefore lacks a specific machine mode).
1503: ;; will be recognized as SImode (which is always valid)
1504: ;; rather than as QImode or HImode.
1505:
1506: (define_expand "floatsisf2"
1507: [(set (match_operand:SF 0 "general_operand" "")
1508: (float:SF (match_operand:SI 1 "general_operand" "")))]
1509: "TARGET_68881 || TARGET_FPA"
1510: "")
1511:
1512: (define_insn ""
1513: [(set (match_operand:SF 0 "general_operand" "=y,x")
1514: (float:SF (match_operand:SI 1 "general_operand" "rmi,x")))]
1515: "TARGET_FPA"
1516: "fpltos %1,%0")
1517:
1518: (define_insn ""
1519: [(set (match_operand:SF 0 "general_operand" "=f")
1520: (float:SF (match_operand:SI 1 "general_operand" "dmi")))]
1521: "TARGET_68881"
1522: "f%$move%.l %1,%0")
1523:
1524: (define_expand "floatsidf2"
1525: [(set (match_operand:DF 0 "general_operand" "")
1526: (float:DF (match_operand:SI 1 "general_operand" "")))]
1527: "TARGET_68881 || TARGET_FPA"
1528: "")
1529:
1530: (define_insn ""
1531: [(set (match_operand:DF 0 "general_operand" "=y,x")
1532: (float:DF (match_operand:SI 1 "general_operand" "rmi,x")))]
1533: "TARGET_FPA"
1534: "fpltod %1,%0")
1535:
1536: (define_insn ""
1537: [(set (match_operand:DF 0 "general_operand" "=f")
1538: (float:DF (match_operand:SI 1 "general_operand" "dmi")))]
1539: "TARGET_68881"
1540: "f%&move%.l %1,%0")
1541:
1542: (define_insn "floathisf2"
1543: [(set (match_operand:SF 0 "general_operand" "=f")
1544: (float:SF (match_operand:HI 1 "general_operand" "dmn")))]
1545: "TARGET_68881"
1546: "f%$move%.w %1,%0")
1547:
1548: (define_insn "floathidf2"
1549: [(set (match_operand:DF 0 "general_operand" "=f")
1550: (float:DF (match_operand:HI 1 "general_operand" "dmn")))]
1551: "TARGET_68881"
1552: "fmove%.w %1,%0")
1553:
1554: (define_insn "floatqisf2"
1555: [(set (match_operand:SF 0 "general_operand" "=f")
1556: (float:SF (match_operand:QI 1 "general_operand" "dmn")))]
1557: "TARGET_68881"
1558: "fmove%.b %1,%0")
1559:
1560: (define_insn "floatqidf2"
1561: [(set (match_operand:DF 0 "general_operand" "=f")
1562: (float:DF (match_operand:QI 1 "general_operand" "dmn")))]
1563: "TARGET_68881"
1564: "f%&move%.b %1,%0")
1565:
1566: ;; New routines to convert floating-point values to integers
1567: ;; to be used on the '040. These should be faster than trapping
1568: ;; into the kernel to emulate fintrz. They should also be faster
1569: ;; than calling the subroutines fixsfsi() or fixdfsi().
1570:
1571: (define_insn "fix_truncdfsi2"
1572: [(set (match_operand:SI 0 "general_operand" "=dm")
1573: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1574: (clobber (match_scratch:SI 2 "=d"))
1575: (clobber (match_scratch:SI 3 "=d"))]
1576: "TARGET_68040"
1577: "*
1578: {
1579: CC_STATUS_INIT;
1580: return \"fmovem%.l fpcr,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,fpcr\;fmove%.l %1,%0\;fmovem%.l %2,fpcr\";
1581: }")
1582:
1583: (define_insn "fix_truncdfhi2"
1584: [(set (match_operand:HI 0 "general_operand" "=dm")
1585: (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1586: (clobber (match_scratch:SI 2 "=d"))
1587: (clobber (match_scratch:SI 3 "=d"))]
1588: "TARGET_68040"
1589: "*
1590: {
1591: CC_STATUS_INIT;
1592: return \"fmovem%.l fpcr,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,fpcr\;fmove%.w %1,%0\;fmovem%.l %2,fpcr\";
1593: }")
1594:
1595: (define_insn "fix_truncdfqi2"
1596: [(set (match_operand:QI 0 "general_operand" "=dm")
1597: (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1598: (clobber (match_scratch:SI 2 "=d"))
1599: (clobber (match_scratch:SI 3 "=d"))]
1600: "TARGET_68040"
1601: "*
1602: {
1603: CC_STATUS_INIT;
1604: return \"fmovem%.l fpcr,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,fpcr\;fmove%.b %1,%0\;fmovem%.l %2,fpcr\";
1605: }")
1606:
1607: ;; Convert a float to a float whose value is an integer.
1608: ;; This is the first stage of converting it to an integer type.
1609:
1610: (define_insn "ftruncdf2"
1611: [(set (match_operand:DF 0 "general_operand" "=f")
1612: (fix:DF (match_operand:DF 1 "general_operand" "fFm")))]
1613: "TARGET_68881 && !TARGET_68040"
1614: "*
1615: {
1616: if (FP_REG_P (operands[1]))
1617: return \"fintrz%.x %f1,%0\";
1618: return \"fintrz%.d %f1,%0\";
1619: }")
1620:
1621: (define_insn "ftruncsf2"
1622: [(set (match_operand:SF 0 "general_operand" "=f")
1623: (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))]
1624: "TARGET_68881 && !TARGET_68040"
1625: "*
1626: {
1627: if (FP_REG_P (operands[1]))
1628: return \"fintrz%.x %f1,%0\";
1629: return \"fintrz%.s %f1,%0\";
1630: }")
1631:
1632: ;; Convert a float whose value is an integer
1633: ;; to an actual integer. Second stage of converting float to integer type.
1634: (define_insn "fixsfqi2"
1635: [(set (match_operand:QI 0 "general_operand" "=dm")
1636: (fix:QI (match_operand:SF 1 "general_operand" "f")))]
1637: "TARGET_68881"
1638: "fmove%.b %1,%0")
1639:
1640: (define_insn "fixsfhi2"
1641: [(set (match_operand:HI 0 "general_operand" "=dm")
1642: (fix:HI (match_operand:SF 1 "general_operand" "f")))]
1643: "TARGET_68881"
1644: "fmove%.w %1,%0")
1645:
1646: (define_insn "fixsfsi2"
1647: [(set (match_operand:SI 0 "general_operand" "=dm")
1648: (fix:SI (match_operand:SF 1 "general_operand" "f")))]
1649: "TARGET_68881"
1650: "fmove%.l %1,%0")
1651:
1652: (define_insn "fixdfqi2"
1653: [(set (match_operand:QI 0 "general_operand" "=dm")
1654: (fix:QI (match_operand:DF 1 "general_operand" "f")))]
1655: "TARGET_68881"
1656: "fmove%.b %1,%0")
1657:
1658: (define_insn "fixdfhi2"
1659: [(set (match_operand:HI 0 "general_operand" "=dm")
1660: (fix:HI (match_operand:DF 1 "general_operand" "f")))]
1661: "TARGET_68881"
1662: "fmove%.w %1,%0")
1663:
1664: (define_insn "fixdfsi2"
1665: [(set (match_operand:SI 0 "general_operand" "=dm")
1666: (fix:SI (match_operand:DF 1 "general_operand" "f")))]
1667: "TARGET_68881"
1668: "fmove%.l %1,%0")
1669:
1670: ;; Convert a float to an integer.
1671: ;; On the Sun FPA, this is done in one step.
1672:
1673: (define_insn ""
1674: [(set (match_operand:SI 0 "general_operand" "=x,y")
1675: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "xH,rmF"))))]
1676: "TARGET_FPA"
1677: "fpstol %w1,%0")
1678:
1679: (define_insn ""
1680: [(set (match_operand:SI 0 "general_operand" "=x,y")
1681: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "xH,rmF"))))]
1682: "TARGET_FPA"
1683: "fpdtol %y1,%0")
1684:
1685: ;; add instructions
1686:
1687: ;; Note that the middle two alternatives are near-duplicates
1688: ;; in order to handle insns generated by reload.
1689: ;; This is needed since they are not themselves reloaded,
1690: ;; so commutativity won't apply to them.
1691: (define_insn "addsi3"
1692: [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r")
1693: (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
1694: (match_operand:SI 2 "general_operand" "dIKLs,rJK,a,mrIKLs")))]
1695: ""
1696: "*
1697: {
1698: if (! operands_match_p (operands[0], operands[1]))
1699: {
1700: if (!ADDRESS_REG_P (operands[1]))
1701: {
1702: rtx tmp = operands[1];
1703:
1704: operands[1] = operands[2];
1705: operands[2] = tmp;
1706: }
1707:
1708: /* These insns can result from reloads to access
1709: stack slots over 64k from the frame pointer. */
1710: if (GET_CODE (operands[2]) == CONST_INT
1711: && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
1712: return \"move%.l %2,%0\;add%.l %1,%0\";
1713: #ifdef SGS
1714: if (GET_CODE (operands[2]) == REG)
1715: return \"lea 0(%1,%2.l),%0\";
1716: else
1717: return \"lea %c2(%1),%0\";
1718: #else /* not SGS */
1719: #ifdef MOTOROLA
1720: if (GET_CODE (operands[2]) == REG)
1721: return \"lea (%1,%2.l),%0\";
1722: else
1723: return \"lea (%c2,%1),%0\";
1724: #else /* not MOTOROLA (MIT syntax) */
1725: if (GET_CODE (operands[2]) == REG)
1726: return \"lea %1@(0,%2:l),%0\";
1727: else
1728: return \"lea %1@(%c2),%0\";
1729: #endif /* not MOTOROLA */
1730: #endif /* not SGS */
1731: }
1732: if (GET_CODE (operands[2]) == CONST_INT)
1733: {
1734: #ifndef NO_ADDSUB_Q
1735: if (INTVAL (operands[2]) > 0
1736: && INTVAL (operands[2]) <= 8)
1737: return (ADDRESS_REG_P (operands[0])
1738: ? \"addq%.w %2,%0\"
1739: : \"addq%.l %2,%0\");
1740: if (INTVAL (operands[2]) < 0
1741: && INTVAL (operands[2]) >= -8)
1742: {
1743: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1744: - INTVAL (operands[2]));
1745: return (ADDRESS_REG_P (operands[0])
1746: ? \"subq%.w %2,%0\"
1747: : \"subq%.l %2,%0\");
1748: }
1749: /* On everything except the 68000 it is faster to use two
1750: addqw instuctions to add a small integer (8 < N <= 16)
1751: to an address register. Likewise for subqw.*/
1752: if (INTVAL (operands[2]) > 8
1753: && INTVAL (operands[2]) <= 16
1754: && ADDRESS_REG_P (operands[0])
1755: && TARGET_68020)
1756: {
1757: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
1758: return \"addq%.w %#8,%0; addq%.w %2,%0\";
1759: }
1760: if (INTVAL (operands[2]) < -8
1761: && INTVAL (operands[2]) >= -16
1762: && ADDRESS_REG_P (operands[0])
1763: && TARGET_68020)
1764: {
1765: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1766: - INTVAL (operands[2]) - 8);
1767: return \"subq%.w %#8,%0; subq%.w %2,%0\";
1768: }
1769: #endif
1770: if (ADDRESS_REG_P (operands[0])
1771: && INTVAL (operands[2]) >= -0x8000
1772: && INTVAL (operands[2]) < 0x8000)
1773: return \"add%.w %2,%0\";
1774: }
1775: return \"add%.l %2,%0\";
1776: }")
1777:
1778: (define_insn ""
1779: [(set (match_operand:SI 0 "general_operand" "=a")
1780: (plus:SI (match_operand:SI 1 "general_operand" "0")
1781: (sign_extend:SI
1782: (match_operand:HI 2 "nonimmediate_operand" "rm"))))]
1783: ""
1784: "add%.w %2,%0")
1785:
1786: (define_insn "addhi3"
1787: [(set (match_operand:HI 0 "general_operand" "=m,r")
1788: (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
1789: (match_operand:HI 2 "general_operand" "dn,rmn")))]
1790: ""
1791: "*
1792: {
1793: #ifndef NO_ADDSUB_Q
1794: if (GET_CODE (operands[2]) == CONST_INT)
1795: {
1796: if (INTVAL (operands[2]) > 0
1797: && INTVAL (operands[2]) <= 8)
1798: return \"addq%.w %2,%0\";
1799: if (INTVAL (operands[2]) < 0
1800: && INTVAL (operands[2]) >= -8)
1801: {
1802: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1803: - INTVAL (operands[2]));
1804: return \"subq%.w %2,%0\";
1805: }
1806: /* On everything except the 68000 it is faster to use two
1807: addqw instuctions to add a small integer (8 < N <= 16)
1808: to an address register. Likewise for subqw. */
1809: if (INTVAL (operands[2]) > 8
1810: && INTVAL (operands[2]) <= 16
1811: && ADDRESS_REG_P (operands[0])
1812: && TARGET_68020)
1813: {
1814: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
1815: return \"addq%.w %#8,%0; addq%.w %2,%0\";
1816: }
1817: if (INTVAL (operands[2]) < -8
1818: && INTVAL (operands[2]) >= -16
1819: && ADDRESS_REG_P (operands[0])
1820: && TARGET_68020)
1821: {
1822: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1823: - INTVAL (operands[2]) - 8);
1824: return \"subq%.w %#8,%0; subq%.w %2,%0\";
1825: }
1826: }
1827: #endif
1828: return \"add%.w %2,%0\";
1829: }")
1830:
1831: (define_insn ""
1832: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
1833: (plus:HI (match_dup 0)
1834: (match_operand:HI 1 "general_operand" "dn,rmn")))]
1835: ""
1836: "add%.w %1,%0")
1837:
1838: (define_insn "addqi3"
1839: [(set (match_operand:QI 0 "general_operand" "=m,d")
1840: (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
1841: (match_operand:QI 2 "general_operand" "dn,dmn")))]
1842: ""
1843: "*
1844: {
1845: #ifndef NO_ADDSUB_Q
1846: if (GET_CODE (operands[2]) == CONST_INT)
1847: {
1848: if (INTVAL (operands[2]) > 0
1849: && INTVAL (operands[2]) <= 8)
1850: return \"addq%.b %2,%0\";
1851: }
1852: if (GET_CODE (operands[2]) == CONST_INT)
1853: {
1854: if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
1855: {
1856: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1857: return \"subq%.b %2,%0\";
1858: }
1859: }
1860: #endif
1861: return \"add%.b %2,%0\";
1862: }")
1863:
1864: (define_insn ""
1865: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
1866: (plus:QI (match_dup 0)
1867: (match_operand:QI 1 "general_operand" "dn,dmn")))]
1868: ""
1869: "add%.b %1,%0")
1870:
1871: (define_expand "adddf3"
1872: [(set (match_operand:DF 0 "general_operand" "")
1873: (plus:DF (match_operand:DF 1 "general_operand" "")
1874: (match_operand:DF 2 "general_operand" "")))]
1875: "TARGET_68881 || TARGET_FPA"
1876: "")
1877:
1878: (define_insn ""
1879: [(set (match_operand:DF 0 "general_operand" "=x,y")
1880: (plus:DF (match_operand:DF 1 "general_operand" "%xH,y")
1881: (match_operand:DF 2 "general_operand" "xH,dmF")))]
1882: "TARGET_FPA"
1883: "*
1884: {
1885: if (rtx_equal_p (operands[0], operands[1]))
1886: return \"fpadd%.d %y2,%0\";
1887: if (rtx_equal_p (operands[0], operands[2]))
1888: return \"fpadd%.d %y1,%0\";
1889: if (which_alternative == 0)
1890: return \"fpadd3%.d %w2,%w1,%0\";
1891: return \"fpadd3%.d %x2,%x1,%0\";
1892: }")
1893:
1894: (define_insn ""
1895: [(set (match_operand:DF 0 "general_operand" "=f")
1896: (plus:DF (match_operand:DF 1 "general_operand" "%0")
1897: (match_operand:DF 2 "general_operand" "fmG")))]
1898: "TARGET_68881"
1899: "*
1900: {
1901: if (REG_P (operands[2]))
1902: return \"f%&add%.x %2,%0\";
1903: return \"f%&add%.d %f2,%0\";
1904: }")
1905:
1906: (define_expand "addsf3"
1907: [(set (match_operand:SF 0 "general_operand" "")
1908: (plus:SF (match_operand:SF 1 "general_operand" "")
1909: (match_operand:SF 2 "general_operand" "")))]
1910: "TARGET_68881 || TARGET_FPA"
1911: "")
1912:
1913: (define_insn ""
1914: [(set (match_operand:SF 0 "general_operand" "=x,y")
1915: (plus:SF (match_operand:SF 1 "general_operand" "%xH,y")
1916: (match_operand:SF 2 "general_operand" "xH,rmF")))]
1917: "TARGET_FPA"
1918: "*
1919: {
1920: if (rtx_equal_p (operands[0], operands[1]))
1921: return \"fpadd%.s %w2,%0\";
1922: if (rtx_equal_p (operands[0], operands[2]))
1923: return \"fpadd%.s %w1,%0\";
1924: if (which_alternative == 0)
1925: return \"fpadd3%.s %w2,%w1,%0\";
1926: return \"fpadd3%.s %2,%1,%0\";
1927: }")
1928:
1929: (define_insn ""
1930: [(set (match_operand:SF 0 "general_operand" "=f")
1931: (plus:SF (match_operand:SF 1 "general_operand" "%0")
1932: (match_operand:SF 2 "general_operand" "fdmF")))]
1933: "TARGET_68881"
1934: "*
1935: {
1936: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
1937: return \"f%$add%.x %2,%0\";
1938: return \"f%$add%.s %f2,%0\";
1939: }")
1940:
1941: ;; subtract instructions
1942:
1943: (define_insn "subsi3"
1944: [(set (match_operand:SI 0 "general_operand" "=m,r,!a,?d")
1945: (minus:SI (match_operand:SI 1 "general_operand" "0,0,a,mrIKs")
1946: (match_operand:SI 2 "general_operand" "dIKs,mrIKs,J,0")))]
1947: ""
1948: "*
1949: {
1950: if (! operands_match_p (operands[0], operands[1]))
1951: {
1952: if (operands_match_p (operands[0], operands[2]))
1953: {
1954: #ifndef NO_ADDSUB_Q
1955: if (GET_CODE (operands[1]) == CONST_INT)
1956: {
1957: if (INTVAL (operands[1]) > 0
1958: && INTVAL (operands[1]) <= 8)
1959: return \"subq%.l %1,%0\;neg%.l %0\";
1960: }
1961: #endif
1962: return \"sub%.l %1,%0\;neg%.l %0\";
1963: }
1964: /* This case is matched by J, but negating -0x8000
1965: in an lea would give an invalid displacement.
1966: So do this specially. */
1967: if (INTVAL (operands[2]) == -0x8000)
1968: return \"move%.l %1,%0\;sub%.l %2,%0\";
1969: #ifdef SGS
1970: return \"lea %n2(%1),%0\";
1971: #else
1972: #ifdef MOTOROLA
1973: return \"lea (%n2,%1),%0\";
1974: #else /* not MOTOROLA (MIT syntax) */
1975: return \"lea %1@(%n2),%0\";
1976: #endif /* not MOTOROLA */
1977: #endif /* not SGS */
1978: }
1979: if (GET_CODE (operands[2]) == CONST_INT)
1980: {
1981: #ifndef NO_ADDSUB_Q
1982: if (INTVAL (operands[2]) > 0
1983: && INTVAL (operands[2]) <= 8)
1984: return \"subq%.l %2,%0\";
1985: /* Using two subqw for 8 < N <= 16 being subtracted from an
1986: address register is faster on all but 68000 */
1987: if (INTVAL (operands[2]) > 8
1988: && INTVAL (operands[2]) <= 16
1989: && ADDRESS_REG_P (operands[0])
1990: && TARGET_68020)
1991: {
1992: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
1993: return \"subq%.w %#8,%0; subq%.w %2,%0\";
1994: }
1995: #endif
1996: if (ADDRESS_REG_P (operands[0])
1997: && INTVAL (operands[2]) >= -0x8000
1998: && INTVAL (operands[2]) < 0x8000)
1999: return \"sub%.w %2,%0\";
2000: }
2001: return \"sub%.l %2,%0\";
2002: }")
2003:
2004: (define_insn ""
2005: [(set (match_operand:SI 0 "general_operand" "=a")
2006: (minus:SI (match_operand:SI 1 "general_operand" "0")
2007: (sign_extend:SI
2008: (match_operand:HI 2 "nonimmediate_operand" "rmn"))))]
2009: ""
2010: "sub%.w %2,%0")
2011:
2012: (define_insn "subhi3"
2013: [(set (match_operand:HI 0 "general_operand" "=m,r")
2014: (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2015: (match_operand:HI 2 "general_operand" "dn,rmn")))]
2016: ""
2017: "sub%.w %2,%0")
2018:
2019: (define_insn ""
2020: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2021: (minus:HI (match_dup 0)
2022: (match_operand:HI 1 "general_operand" "dn,rmn")))]
2023: ""
2024: "sub%.w %1,%0")
2025:
2026: (define_insn "subqi3"
2027: [(set (match_operand:QI 0 "general_operand" "=m,d")
2028: (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2029: (match_operand:QI 2 "general_operand" "dn,dmn")))]
2030: ""
2031: "sub%.b %2,%0")
2032:
2033: (define_insn ""
2034: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2035: (minus:QI (match_dup 0)
2036: (match_operand:QI 1 "general_operand" "dn,dmn")))]
2037: ""
2038: "sub%.b %1,%0")
2039:
2040: (define_expand "subdf3"
2041: [(set (match_operand:DF 0 "general_operand" "")
2042: (minus:DF (match_operand:DF 1 "general_operand" "")
2043: (match_operand:DF 2 "general_operand" "")))]
2044: "TARGET_68881 || TARGET_FPA"
2045: "")
2046:
2047: (define_insn ""
2048: [(set (match_operand:DF 0 "general_operand" "=x,y,y")
2049: (minus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF")
2050: (match_operand:DF 2 "general_operand" "xH,dmF,0")))]
2051: "TARGET_FPA"
2052: "*
2053: {
2054: if (rtx_equal_p (operands[0], operands[2]))
2055: return \"fprsub%.d %y1,%0\";
2056: if (rtx_equal_p (operands[0], operands[1]))
2057: return \"fpsub%.d %y2,%0\";
2058: if (which_alternative == 0)
2059: return \"fpsub3%.d %w2,%w1,%0\";
2060: return \"fpsub3%.d %x2,%x1,%0\";
2061: }")
2062:
2063: (define_insn ""
2064: [(set (match_operand:DF 0 "general_operand" "=f")
2065: (minus:DF (match_operand:DF 1 "general_operand" "0")
2066: (match_operand:DF 2 "general_operand" "fmG")))]
2067: "TARGET_68881"
2068: "*
2069: {
2070: if (REG_P (operands[2]))
2071: return \"f%&sub%.x %2,%0\";
2072: return \"f%&sub%.d %f2,%0\";
2073: }")
2074:
2075: (define_expand "subsf3"
2076: [(set (match_operand:SF 0 "general_operand" "")
2077: (minus:SF (match_operand:SF 1 "general_operand" "")
2078: (match_operand:SF 2 "general_operand" "")))]
2079: "TARGET_68881 || TARGET_FPA"
2080: "")
2081:
2082: (define_insn ""
2083: [(set (match_operand:SF 0 "general_operand" "=x,y,y")
2084: (minus:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
2085: (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
2086: "TARGET_FPA"
2087: "*
2088: {
2089: if (rtx_equal_p (operands[0], operands[2]))
2090: return \"fprsub%.s %w1,%0\";
2091: if (rtx_equal_p (operands[0], operands[1]))
2092: return \"fpsub%.s %w2,%0\";
2093: if (which_alternative == 0)
2094: return \"fpsub3%.s %w2,%w1,%0\";
2095: return \"fpsub3%.s %2,%1,%0\";
2096: }")
2097:
2098: (define_insn ""
2099: [(set (match_operand:SF 0 "general_operand" "=f")
2100: (minus:SF (match_operand:SF 1 "general_operand" "0")
2101: (match_operand:SF 2 "general_operand" "fdmF")))]
2102: "TARGET_68881"
2103: "*
2104: {
2105: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2106: return \"f%$sub%.x %2,%0\";
2107: return \"f%$sub%.s %f2,%0\";
2108: }")
2109:
2110: ;; multiply instructions
2111:
2112: (define_insn "mulhi3"
2113: [(set (match_operand:HI 0 "general_operand" "=d")
2114: (mult:HI (match_operand:HI 1 "general_operand" "%0")
2115: (match_operand:HI 2 "general_operand" "dmn")))]
2116: ""
2117: "*
2118: {
2119: #if defined(MOTOROLA) && !defined(CRDS)
2120: return \"muls%.w %2,%0\";
2121: #else
2122: return \"muls %2,%0\";
2123: #endif
2124: }")
2125:
2126: (define_insn "mulhisi3"
2127: [(set (match_operand:SI 0 "general_operand" "=d")
2128: (mult:SI (sign_extend:SI
2129: (match_operand:HI 1 "nonimmediate_operand" "%0"))
2130: (sign_extend:SI
2131: (match_operand:HI 2 "nonimmediate_operand" "dmn"))))]
2132: ""
2133: "*
2134: {
2135: #if defined(MOTOROLA) && !defined(CRDS)
2136: return \"muls%.w %2,%0\";
2137: #else
2138: return \"muls %2,%0\";
2139: #endif
2140: }")
2141:
2142: (define_insn ""
2143: [(set (match_operand:SI 0 "general_operand" "=d")
2144: (mult:SI (sign_extend:SI
2145: (match_operand:HI 1 "nonimmediate_operand" "%0"))
2146: (match_operand:SI 2 "const_int_operand" "n")))]
2147: ""
2148: "*
2149: {
2150: #if defined(MOTOROLA) && !defined(CRDS)
2151: return \"muls%.w %2,%0\";
2152: #else
2153: return \"muls %2,%0\";
2154: #endif
2155: }")
2156:
2157: (define_insn "mulsi3"
2158: [(set (match_operand:SI 0 "general_operand" "=d")
2159: (mult:SI (match_operand:SI 1 "general_operand" "%0")
2160: (match_operand:SI 2 "general_operand" "dmsK")))]
2161: "TARGET_68020"
2162: "muls%.l %2,%0")
2163:
2164: (define_insn "umulhisi3"
2165: [(set (match_operand:SI 0 "general_operand" "=d")
2166: (mult:SI (zero_extend:SI
2167: (match_operand:HI 1 "nonimmediate_operand" "%0"))
2168: (zero_extend:SI
2169: (match_operand:HI 2 "nonimmediate_operand" "dmn"))))]
2170: ""
2171: "*
2172: {
2173: #if defined(MOTOROLA) && !defined(CRDS)
2174: return \"mulu%.w %2,%0\";
2175: #else
2176: return \"mulu %2,%0\";
2177: #endif
2178: }")
2179:
2180: (define_insn ""
2181: [(set (match_operand:SI 0 "general_operand" "=d")
2182: (mult:SI (zero_extend:SI
2183: (match_operand:HI 1 "nonimmediate_operand" "%0"))
2184: (match_operand:SI 2 "const_int_operand" "n")))]
2185: ""
2186: "*
2187: {
2188: #if defined(MOTOROLA) && !defined(CRDS)
2189: return \"mulu%.w %2,%0\";
2190: #else
2191: return \"mulu %2,%0\";
2192: #endif
2193: }")
2194:
2195: ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
2196: ;; proper matching constraint. This is because the matching is between
2197: ;; the high-numbered word of the DImode operand[0] and operand[1].
2198: (define_expand "umulsidi3"
2199: [(parallel
2200: [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1)
2201: (subreg:SI
2202: (mult:DI (zero_extend:DI
2203: (match_operand:SI 1 "register_operand" ""))
2204: (zero_extend:DI
2205: (match_operand:SI 2 "general_operand" ""))) 1))
2206: (set (subreg:SI (match_dup 0) 0)
2207: (subreg:SI
2208: (mult:DI (zero_extend:DI
2209: (match_dup 1))
2210: (zero_extend:DI
2211: (match_dup 2))) 0))])]
2212: "TARGET_68020"
2213: "")
2214:
2215: (define_insn ""
2216: [(set (match_operand:SI 0 "register_operand" "=d")
2217: (subreg:SI
2218: (mult:DI (zero_extend:DI
2219: (match_operand:SI 1 "register_operand" "%0"))
2220: (zero_extend:DI
2221: (match_operand:SI 2 "general_operand" "dmsK"))) 1))
2222: (set (match_operand:SI 3 "register_operand" "=d")
2223: (subreg:SI
2224: (mult:DI (zero_extend:DI
2225: (match_dup 1))
2226: (zero_extend:DI
2227: (match_dup 2))) 0))]
2228: "TARGET_68020"
2229: "mulu%.l %2,%3:%0")
2230:
2231: (define_expand "mulsidi3"
2232: [(parallel
2233: [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1)
2234: (subreg:SI
2235: (mult:DI (sign_extend:DI
2236: (match_operand:SI 1 "register_operand" ""))
2237: (sign_extend:DI
2238: (match_operand:SI 2 "general_operand" ""))) 1))
2239: (set (subreg:SI (match_dup 0) 0)
2240: (subreg:SI
2241: (mult:DI (sign_extend:DI
2242: (match_dup 1))
2243: (sign_extend:DI
2244: (match_dup 2))) 0))])]
2245: "TARGET_68020"
2246: "")
2247:
2248: (define_insn ""
2249: [(set (match_operand:SI 0 "register_operand" "=d")
2250: (subreg:SI
2251: (mult:DI (sign_extend:DI
2252: (match_operand:SI 1 "register_operand" "%0"))
2253: (sign_extend:DI
2254: (match_operand:SI 2 "general_operand" "dmKs"))) 1))
2255: (set (match_operand:SI 3 "register_operand" "=d")
2256: (subreg:SI
2257: (mult:DI (sign_extend:DI
2258: (match_dup 1))
2259: (sign_extend:DI
2260: (match_dup 2))) 0))]
2261: "TARGET_68020"
2262: "muls%.l %2,%3:%0")
2263:
2264: (define_expand "muldf3"
2265: [(set (match_operand:DF 0 "general_operand" "")
2266: (mult:DF (match_operand:DF 1 "general_operand" "")
2267: (match_operand:DF 2 "general_operand" "")))]
2268: "TARGET_68881 || TARGET_FPA"
2269: "")
2270:
2271: (define_insn ""
2272: [(set (match_operand:DF 0 "general_operand" "=x,y")
2273: (mult:DF (match_operand:DF 1 "general_operand" "%xH,y")
2274: (match_operand:DF 2 "general_operand" "xH,rmF")))]
2275: "TARGET_FPA"
2276: "*
2277: {
2278: if (rtx_equal_p (operands[1], operands[2]))
2279: return \"fpsqr%.d %y1,%0\";
2280: if (rtx_equal_p (operands[0], operands[1]))
2281: return \"fpmul%.d %y2,%0\";
2282: if (rtx_equal_p (operands[0], operands[2]))
2283: return \"fpmul%.d %y1,%0\";
2284: if (which_alternative == 0)
2285: return \"fpmul3%.d %w2,%w1,%0\";
2286: return \"fpmul3%.d %x2,%x1,%0\";
2287: }")
2288:
2289: (define_insn ""
2290: [(set (match_operand:DF 0 "general_operand" "=f")
2291: (mult:DF (match_operand:DF 1 "general_operand" "%0")
2292: (match_operand:DF 2 "general_operand" "fmG")))]
2293: "TARGET_68881"
2294: "*
2295: {
2296: if (GET_CODE (operands[2]) == CONST_DOUBLE
2297: && floating_exact_log2 (operands[2]) && !TARGET_68040)
2298: {
2299: int i = floating_exact_log2 (operands[2]);
2300: operands[2] = gen_rtx (CONST_INT, VOIDmode, i);
2301: return \"fscale%.l %2,%0\";
2302: }
2303: if (REG_P (operands[2]))
2304: return \"f%&mul%.x %2,%0\";
2305: return \"f%&mul%.d %f2,%0\";
2306: }")
2307:
2308: (define_expand "mulsf3"
2309: [(set (match_operand:SF 0 "general_operand" "")
2310: (mult:SF (match_operand:SF 1 "general_operand" "")
2311: (match_operand:SF 2 "general_operand" "")))]
2312: "TARGET_68881 || TARGET_FPA"
2313: "")
2314:
2315: (define_insn ""
2316: [(set (match_operand:SF 0 "general_operand" "=x,y")
2317: (mult:SF (match_operand:SF 1 "general_operand" "%xH,y")
2318: (match_operand:SF 2 "general_operand" "xH,rmF")))]
2319: "TARGET_FPA"
2320: "*
2321: {
2322: if (rtx_equal_p (operands[1], operands[2]))
2323: return \"fpsqr%.s %w1,%0\";
2324: if (rtx_equal_p (operands[0], operands[1]))
2325: return \"fpmul%.s %w2,%0\";
2326: if (rtx_equal_p (operands[0], operands[2]))
2327: return \"fpmul%.s %w1,%0\";
2328: if (which_alternative == 0)
2329: return \"fpmul3%.s %w2,%w1,%0\";
2330: return \"fpmul3%.s %2,%1,%0\";
2331: }")
2332:
2333: (define_insn ""
2334: [(set (match_operand:SF 0 "general_operand" "=f")
2335: (mult:SF (match_operand:SF 1 "general_operand" "%0")
2336: (match_operand:SF 2 "general_operand" "fdmF")))]
2337: "TARGET_68881"
2338: "*
2339: {
2340: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2341: return (TARGET_68040_ONLY
2342: ? \"fsmul%.x %2,%0\"
2343: : \"fsglmul%.x %2,%0\");
2344: return (TARGET_68040_ONLY
2345: ? \"fsmul%.s %f2,%0\"
2346: : \"fsglmul%.s %f2,%0\");
2347: }")
2348:
2349: ;; divide instructions
2350:
2351: (define_insn "divhi3"
2352: [(set (match_operand:HI 0 "general_operand" "=d")
2353: (div:HI (match_operand:HI 1 "general_operand" "0")
2354: (match_operand:HI 2 "general_operand" "dmn")))]
2355: ""
2356: "*
2357: {
2358: #ifdef MOTOROLA
2359: return \"ext%.l %0\;divs%.w %2,%0\";
2360: #else
2361: return \"extl %0\;divs %2,%0\";
2362: #endif
2363: }")
2364:
2365: (define_insn "divhisi3"
2366: [(set (match_operand:HI 0 "general_operand" "=d")
2367: (truncate:HI
2368: (div:SI
2369: (match_operand:SI 1 "general_operand" "0")
2370: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
2371: ""
2372: "*
2373: {
2374: #ifdef MOTOROLA
2375: return \"divs%.w %2,%0\";
2376: #else
2377: return \"divs %2,%0\";
2378: #endif
2379: }")
2380:
2381: (define_insn ""
2382: [(set (match_operand:HI 0 "general_operand" "=d")
2383: (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0")
2384: (match_operand:SI 2 "const_int_operand" "n"))))]
2385: ""
2386: "*
2387: {
2388: #ifdef MOTOROLA
2389: return \"divs%.w %2,%0\";
2390: #else
2391: return \"divs %2,%0\";
2392: #endif
2393: }")
2394:
2395: (define_insn "udivhi3"
2396: [(set (match_operand:HI 0 "general_operand" "=d")
2397: (udiv:HI (match_operand:HI 1 "general_operand" "0")
2398: (match_operand:HI 2 "general_operand" "dmn")))]
2399: ""
2400: "*
2401: {
2402: #ifdef MOTOROLA
2403: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\";
2404: #else
2405: return \"andl %#0xFFFF,%0\;divu %2,%0\";
2406: #endif
2407: }")
2408:
2409: (define_insn "udivhisi3"
2410: [(set (match_operand:HI 0 "general_operand" "=d")
2411: (truncate:HI
2412: (udiv:SI
2413: (match_operand:SI 1 "general_operand" "0")
2414: (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
2415: ""
2416: "*
2417: {
2418: #ifdef MOTOROLA
2419: return \"divu%.w %2,%0\";
2420: #else
2421: return \"divu %2,%0\";
2422: #endif
2423: }")
2424:
2425: (define_insn ""
2426: [(set (match_operand:HI 0 "general_operand" "=d")
2427: (truncate:HI (udiv:SI (match_operand:SI 1 "general_operand" "0")
2428: (match_operand:SI 2 "const_int_operand" "n"))))]
2429: ""
2430: "*
2431: {
2432: #ifdef MOTOROLA
2433: return \"divu%.w %2,%0\";
2434: #else
2435: return \"divu %2,%0\";
2436: #endif
2437: }")
2438:
2439: (define_expand "divdf3"
2440: [(set (match_operand:DF 0 "general_operand" "")
2441: (div:DF (match_operand:DF 1 "general_operand" "")
2442: (match_operand:DF 2 "general_operand" "")))]
2443: "TARGET_68881 || TARGET_FPA"
2444: "")
2445:
2446: (define_insn ""
2447: [(set (match_operand:DF 0 "general_operand" "=x,y,y")
2448: (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF")
2449: (match_operand:DF 2 "general_operand" "xH,rmF,0")))]
2450: "TARGET_FPA"
2451: "*
2452: {
2453: if (rtx_equal_p (operands[0], operands[2]))
2454: return \"fprdiv%.d %y1,%0\";
2455: if (rtx_equal_p (operands[0], operands[1]))
2456: return \"fpdiv%.d %y2,%0\";
2457: if (which_alternative == 0)
2458: return \"fpdiv3%.d %w2,%w1,%0\";
2459: return \"fpdiv3%.d %x2,%x1,%x0\";
2460: }")
2461:
2462: (define_insn ""
2463: [(set (match_operand:DF 0 "general_operand" "=f")
2464: (div:DF (match_operand:DF 1 "general_operand" "0")
2465: (match_operand:DF 2 "general_operand" "fmG")))]
2466: "TARGET_68881"
2467: "*
2468: {
2469: if (REG_P (operands[2]))
2470: return \"f%&div%.x %2,%0\";
2471: return \"f%&div%.d %f2,%0\";
2472: }")
2473:
2474: (define_expand "divsf3"
2475: [(set (match_operand:SF 0 "general_operand" "")
2476: (div:SF (match_operand:SF 1 "general_operand" "")
2477: (match_operand:SF 2 "general_operand" "")))]
2478: "TARGET_68881 || TARGET_FPA"
2479: "")
2480:
2481: (define_insn ""
2482: [(set (match_operand:SF 0 "general_operand" "=x,y,y")
2483: (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
2484: (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
2485: "TARGET_FPA"
2486: "*
2487: {
2488: if (rtx_equal_p (operands[0], operands[1]))
2489: return \"fpdiv%.s %w2,%0\";
2490: if (rtx_equal_p (operands[0], operands[2]))
2491: return \"fprdiv%.s %w1,%0\";
2492: if (which_alternative == 0)
2493: return \"fpdiv3%.s %w2,%w1,%0\";
2494: return \"fpdiv3%.s %2,%1,%0\";
2495: }")
2496:
2497: (define_insn ""
2498: [(set (match_operand:SF 0 "general_operand" "=f")
2499: (div:SF (match_operand:SF 1 "general_operand" "0")
2500: (match_operand:SF 2 "general_operand" "fdmF")))]
2501: "TARGET_68881"
2502: "*
2503: {
2504: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2505: return (TARGET_68040_ONLY
2506: ? \"fsdiv%.x %2,%0\"
2507: : \"fsgldiv%.x %2,%0\");
2508: return (TARGET_68040_ONLY
2509: ? \"fsdiv%.s %f2,%0\"
2510: : \"fsgldiv%.s %f2,%0\");
2511: }")
2512:
2513: ;; Remainder instructions.
2514:
2515: (define_insn "modhi3"
2516: [(set (match_operand:HI 0 "general_operand" "=d")
2517: (mod:HI (match_operand:HI 1 "general_operand" "0")
2518: (match_operand:HI 2 "general_operand" "dmn")))]
2519: ""
2520: "*
2521: {
2522: /* The swap insn produces cc's that don't correspond to the result. */
2523: CC_STATUS_INIT;
2524: #ifdef MOTOROLA
2525: #ifdef SGS_SWAP_W
2526: return \"ext%.l %0\;divs%.w %2,%0\;swap%.w %0\";
2527: #else
2528: return \"ext%.l %0\;divs%.w %2,%0\;swap %0\";
2529: #endif
2530: #else
2531: return \"extl %0\;divs %2,%0\;swap %0\";
2532: #endif
2533: }")
2534:
2535: (define_insn "modhisi3"
2536: [(set (match_operand:HI 0 "general_operand" "=d")
2537: (truncate:HI
2538: (mod:SI
2539: (match_operand:SI 1 "general_operand" "0")
2540: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
2541: ""
2542: "*
2543: {
2544: /* The swap insn produces cc's that don't correspond to the result. */
2545: CC_STATUS_INIT;
2546: #ifdef MOTOROLA
2547: #ifdef SGS_SWAP_W
2548: return \"divs%.w %2,%0\;swap%.w %0\";
2549: #else
2550: return \"divs%.w %2,%0\;swap %0\";
2551: #endif
2552: #else
2553: return \"divs %2,%0\;swap %0\";
2554: #endif
2555: }")
2556:
2557: (define_insn ""
2558: [(set (match_operand:HI 0 "general_operand" "=d")
2559: (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0")
2560: (match_operand:SI 2 "const_int_operand" "n"))))]
2561: ""
2562: "*
2563: {
2564: /* The swap insn produces cc's that don't correspond to the result. */
2565: CC_STATUS_INIT;
2566: #ifdef MOTOROLA
2567: #ifdef SGS_SWAP_W
2568: return \"divs%.w %2,%0\;swap%.w %0\";
2569: #else
2570: return \"divs%.w %2,%0\;swap %0\";
2571: #endif
2572: #else
2573: return \"divs %2,%0\;swap %0\";
2574: #endif
2575: }")
2576:
2577: (define_insn "umodhi3"
2578: [(set (match_operand:HI 0 "general_operand" "=d")
2579: (umod:HI (match_operand:HI 1 "general_operand" "0")
2580: (match_operand:HI 2 "general_operand" "dmn")))]
2581: ""
2582: "*
2583: {
2584: /* The swap insn produces cc's that don't correspond to the result. */
2585: CC_STATUS_INIT;
2586: #ifdef MOTOROLA
2587: #ifdef SGS_SWAP_W
2588: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap%.w %0\";
2589: #else
2590: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\";
2591: #endif
2592: #else
2593: return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\";
2594: #endif
2595: }")
2596:
2597: (define_insn "umodhisi3"
2598: [(set (match_operand:HI 0 "general_operand" "=d")
2599: (truncate:HI
2600: (umod:SI
2601: (match_operand:SI 1 "general_operand" "0")
2602: (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
2603: ""
2604: "*
2605: {
2606: /* The swap insn produces cc's that don't correspond to the result. */
2607: CC_STATUS_INIT;
2608: #ifdef MOTOROLA
2609: #ifdef SGS_SWAP_W
2610: return \"divu%.w %2,%0\;swap%.w %0\";
2611: #else
2612: return \"divu%.w %2,%0\;swap %0\";
2613: #endif
2614: #else
2615: return \"divu %2,%0\;swap %0\";
2616: #endif
2617: }")
2618:
2619: (define_insn ""
2620: [(set (match_operand:HI 0 "general_operand" "=d")
2621: (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0")
2622: (match_operand:SI 2 "const_int_operand" "n"))))]
2623: ""
2624: "*
2625: {
2626: /* The swap insn produces cc's that don't correspond to the result. */
2627: CC_STATUS_INIT;
2628: #ifdef MOTOROLA
2629: #ifdef SGS_SWAP_W
2630: return \"divu%.w %2,%0\;swap%.w %0\";
2631: #else
2632: return \"divu%.w %2,%0\;swap %0\";
2633: #endif
2634: #else
2635: return \"divu %2,%0\;swap %0\";
2636: #endif
2637: }")
2638:
2639: (define_insn "divmodsi4"
2640: [(set (match_operand:SI 0 "general_operand" "=d")
2641: (div:SI (match_operand:SI 1 "general_operand" "0")
2642: (match_operand:SI 2 "general_operand" "dmsK")))
2643: (set (match_operand:SI 3 "general_operand" "=d")
2644: (mod:SI (match_dup 1) (match_dup 2)))]
2645: "TARGET_68020"
2646: "*
2647: {
2648: if (find_reg_note (insn, REG_UNUSED, operands[3]))
2649: return \"divs%.l %2,%0\";
2650: else
2651: return \"divsl%.l %2,%3:%0\";
2652: }")
2653:
2654: (define_insn "udivmodsi4"
2655: [(set (match_operand:SI 0 "general_operand" "=d")
2656: (udiv:SI (match_operand:SI 1 "general_operand" "0")
2657: (match_operand:SI 2 "general_operand" "dmsK")))
2658: (set (match_operand:SI 3 "general_operand" "=d")
2659: (umod:SI (match_dup 1) (match_dup 2)))]
2660: "TARGET_68020"
2661: "*
2662: {
2663: if (find_reg_note (insn, REG_UNUSED, operands[3]))
2664: return \"divu%.l %2,%0\";
2665: else
2666: return \"divul%.l %2,%3:%0\";
2667: }")
2668:
2669: ;; logical-and instructions
2670:
2671: ;; Prevent AND from being made with sp. This doesn't exist in the machine
2672: ;; and reload will cause inefficient code. Since sp is a FIXED_REG, we
2673: ;; can't allocate psuedos into it.
2674: (define_insn "andsi3"
2675: [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
2676: (and:SI (match_operand:SI 1 "general_operand" "%0,0")
2677: (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
2678: ""
2679: "*
2680: {
2681: int logval;
2682: if (GET_CODE (operands[2]) == CONST_INT
2683: && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
2684: && (DATA_REG_P (operands[0])
2685: || offsettable_memref_p (operands[0])))
2686: {
2687: if (GET_CODE (operands[0]) != REG)
2688: operands[0] = adj_offsettable_operand (operands[0], 2);
2689: operands[2] = gen_rtx (CONST_INT, VOIDmode,
2690: INTVAL (operands[2]) & 0xffff);
2691: /* Do not delete a following tstl %0 insn; that would be incorrect. */
2692: CC_STATUS_INIT;
2693: if (operands[2] == const0_rtx)
2694: return \"clr%.w %0\";
2695: return \"and%.w %2,%0\";
2696: }
2697: if (GET_CODE (operands[2]) == CONST_INT
2698: && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
2699: && (DATA_REG_P (operands[0])
2700: || offsettable_memref_p (operands[0])))
2701: {
2702: if (DATA_REG_P (operands[0]))
2703: {
2704: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
2705: }
2706: else
2707: {
2708: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
2709: }
2710: /* This does not set condition codes in a standard way. */
2711: CC_STATUS_INIT;
2712: return \"bclr %1,%0\";
2713: }
2714: return \"and%.l %2,%0\";
2715: }")
2716:
2717: (define_insn "andhi3"
2718: [(set (match_operand:HI 0 "general_operand" "=m,d")
2719: (and:HI (match_operand:HI 1 "general_operand" "%0,0")
2720: (match_operand:HI 2 "general_operand" "dn,dmn")))]
2721: ""
2722: "and%.w %2,%0")
2723:
2724: (define_insn "andqi3"
2725: [(set (match_operand:QI 0 "general_operand" "=m,d")
2726: (and:QI (match_operand:QI 1 "general_operand" "%0,0")
2727: (match_operand:QI 2 "general_operand" "dn,dmn")))]
2728: ""
2729: "and%.b %2,%0")
2730:
2731:
2732: ;; inclusive-or instructions
2733:
2734: (define_insn "iorsi3"
2735: [(set (match_operand:SI 0 "general_operand" "=m,d")
2736: (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
2737: (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
2738: ""
2739: "*
2740: {
2741: register int logval;
2742: if (GET_CODE (operands[2]) == CONST_INT
2743: && INTVAL (operands[2]) >> 16 == 0
2744: && (DATA_REG_P (operands[0])
2745: || offsettable_memref_p (operands[0])))
2746: {
2747: if (GET_CODE (operands[0]) != REG)
2748: operands[0] = adj_offsettable_operand (operands[0], 2);
2749: /* Do not delete a following tstl %0 insn; that would be incorrect. */
2750: CC_STATUS_INIT;
2751: return \"or%.w %2,%0\";
2752: }
2753: if (GET_CODE (operands[2]) == CONST_INT
2754: && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
2755: && (DATA_REG_P (operands[0])
2756: || offsettable_memref_p (operands[0])))
2757: {
2758: if (DATA_REG_P (operands[0]))
2759: {
2760: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
2761: }
2762: else
2763: {
2764: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
2765: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
2766: }
2767: return \"bset %1,%0\";
2768: }
2769: return \"or%.l %2,%0\";
2770: }")
2771:
2772: (define_insn "iorhi3"
2773: [(set (match_operand:HI 0 "general_operand" "=m,d")
2774: (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
2775: (match_operand:HI 2 "general_operand" "dn,dmn")))]
2776: ""
2777: "or%.w %2,%0")
2778:
2779: (define_insn "iorqi3"
2780: [(set (match_operand:QI 0 "general_operand" "=m,d")
2781: (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
2782: (match_operand:QI 2 "general_operand" "dn,dmn")))]
2783: ""
2784: "or%.b %2,%0")
2785:
2786: ;; xor instructions
2787:
2788: (define_insn "xorsi3"
2789: [(set (match_operand:SI 0 "general_operand" "=do,m")
2790: (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
2791: (match_operand:SI 2 "general_operand" "di,dKs")))]
2792: ""
2793: "*
2794: {
2795: if (GET_CODE (operands[2]) == CONST_INT
2796: && INTVAL (operands[2]) >> 16 == 0
2797: && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
2798: {
2799: if (! DATA_REG_P (operands[0]))
2800: operands[0] = adj_offsettable_operand (operands[0], 2);
2801: /* Do not delete a following tstl %0 insn; that would be incorrect. */
2802: CC_STATUS_INIT;
2803: return \"eor%.w %2,%0\";
2804: }
2805: return \"eor%.l %2,%0\";
2806: }")
2807:
2808: (define_insn "xorhi3"
2809: [(set (match_operand:HI 0 "general_operand" "=dm")
2810: (xor:HI (match_operand:HI 1 "general_operand" "%0")
2811: (match_operand:HI 2 "general_operand" "dn")))]
2812: ""
2813: "eor%.w %2,%0")
2814:
2815: (define_insn "xorqi3"
2816: [(set (match_operand:QI 0 "general_operand" "=dm")
2817: (xor:QI (match_operand:QI 1 "general_operand" "%0")
2818: (match_operand:QI 2 "general_operand" "dn")))]
2819: ""
2820: "eor%.b %2,%0")
2821:
2822: ;; negation instructions
2823:
2824: (define_insn "negsi2"
2825: [(set (match_operand:SI 0 "general_operand" "=dm")
2826: (neg:SI (match_operand:SI 1 "general_operand" "0")))]
2827: ""
2828: "neg%.l %0")
2829:
2830: (define_insn "neghi2"
2831: [(set (match_operand:HI 0 "general_operand" "=dm")
2832: (neg:HI (match_operand:HI 1 "general_operand" "0")))]
2833: ""
2834: "neg%.w %0")
2835:
2836: (define_insn "negqi2"
2837: [(set (match_operand:QI 0 "general_operand" "=dm")
2838: (neg:QI (match_operand:QI 1 "general_operand" "0")))]
2839: ""
2840: "neg%.b %0")
2841:
2842: (define_expand "negsf2"
2843: [(set (match_operand:SF 0 "general_operand" "")
2844: (neg:SF (match_operand:SF 1 "general_operand" "")))]
2845: "TARGET_68881 || TARGET_FPA"
2846: "")
2847:
2848: (define_insn ""
2849: [(set (match_operand:SF 0 "general_operand" "=x,y")
2850: (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
2851: "TARGET_FPA"
2852: "fpneg%.s %w1,%0")
2853:
2854: (define_insn ""
2855: [(set (match_operand:SF 0 "general_operand" "=f,d")
2856: (neg:SF (match_operand:SF 1 "general_operand" "fdmF,0")))]
2857: "TARGET_68881"
2858: "*
2859: {
2860: if (DATA_REG_P (operands[0]))
2861: {
2862: operands[1] = gen_rtx (CONST_INT, VOIDmode, 31);
2863: return \"bchg %1,%0\";
2864: }
2865: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
2866: return \"f%$neg%.x %1,%0\";
2867: return \"f%$neg%.s %f1,%0\";
2868: }")
2869:
2870: (define_expand "negdf2"
2871: [(set (match_operand:DF 0 "general_operand" "")
2872: (neg:DF (match_operand:DF 1 "general_operand" "")))]
2873: "TARGET_68881 || TARGET_FPA"
2874: "")
2875:
2876: (define_insn ""
2877: [(set (match_operand:DF 0 "general_operand" "=x,y")
2878: (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
2879: "TARGET_FPA"
2880: "fpneg%.d %y1, %0")
2881:
2882: (define_insn ""
2883: [(set (match_operand:DF 0 "general_operand" "=f,d")
2884: (neg:DF (match_operand:DF 1 "general_operand" "fmF,0")))]
2885: "TARGET_68881"
2886: "*
2887: {
2888: if (DATA_REG_P (operands[0]))
2889: {
2890: operands[1] = gen_rtx (CONST_INT, VOIDmode, 31);
2891: return \"bchg %1,%0\";
2892: }
2893: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
2894: return \"f%&neg%.x %1,%0\";
2895: return \"f%&neg%.d %f1,%0\";
2896: }")
2897:
2898: ;; Absolute value instructions
2899:
2900: (define_expand "abssf2"
2901: [(set (match_operand:SF 0 "general_operand" "")
2902: (abs:SF (match_operand:SF 1 "general_operand" "")))]
2903: "TARGET_68881 || TARGET_FPA"
2904: "")
2905:
2906: (define_insn ""
2907: [(set (match_operand:SF 0 "general_operand" "=x,y")
2908: (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
2909: "TARGET_FPA"
2910: "fpabs%.s %y1,%0")
2911:
2912: (define_insn ""
2913: [(set (match_operand:SF 0 "general_operand" "=f")
2914: (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))]
2915: "TARGET_68881"
2916: "*
2917: {
2918: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
2919: return \"f%$abs%.x %1,%0\";
2920: return \"f%$abs%.s %f1,%0\";
2921: }")
2922:
2923: (define_expand "absdf2"
2924: [(set (match_operand:DF 0 "general_operand" "")
2925: (abs:DF (match_operand:DF 1 "general_operand" "")))]
2926: "TARGET_68881 || TARGET_FPA"
2927: "")
2928:
2929: (define_insn ""
2930: [(set (match_operand:DF 0 "general_operand" "=x,y")
2931: (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
2932: "TARGET_FPA"
2933: "fpabs%.d %y1,%0")
2934:
2935: (define_insn ""
2936: [(set (match_operand:DF 0 "general_operand" "=f")
2937: (abs:DF (match_operand:DF 1 "general_operand" "fmF")))]
2938: "TARGET_68881"
2939: "*
2940: {
2941: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
2942: return \"f%&abs%.x %1,%0\";
2943: return \"f%&abs%.d %f1,%0\";
2944: }")
2945:
2946: ;; one complement instructions
2947:
2948: (define_insn "one_cmplsi2"
2949: [(set (match_operand:SI 0 "general_operand" "=dm")
2950: (not:SI (match_operand:SI 1 "general_operand" "0")))]
2951: ""
2952: "not%.l %0")
2953:
2954: (define_insn "one_cmplhi2"
2955: [(set (match_operand:HI 0 "general_operand" "=dm")
2956: (not:HI (match_operand:HI 1 "general_operand" "0")))]
2957: ""
2958: "not%.w %0")
2959:
2960: (define_insn "one_cmplqi2"
2961: [(set (match_operand:QI 0 "general_operand" "=dm")
2962: (not:QI (match_operand:QI 1 "general_operand" "0")))]
2963: ""
2964: "not%.b %0")
2965:
2966: ;; arithmetic shift instructions
2967: ;; We don't need the shift memory by 1 bit instruction
2968:
2969: ;; On the 68000, this makes faster code in a special case.
2970:
2971: (define_insn ""
2972: [(set (match_operand:SI 0 "register_operand" "=d")
2973: (ashift:SI (match_operand:SI 1 "register_operand" "0")
2974: (match_operand:SI 2 "immediate_operand" "i")))]
2975: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT
2976: && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)"
2977: "*
2978: {
2979: CC_STATUS_INIT;
2980:
2981: if (INTVAL (operands[2]) == 16)
2982: return \"swap %0\;clrw %0\";
2983:
2984: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
2985: return \"asl%.w %2,%0\;swap %0\;clrw %0\";
2986: }")
2987:
2988: (define_insn "ashlsi3"
2989: [(set (match_operand:SI 0 "register_operand" "=d")
2990: (ashift:SI (match_operand:SI 1 "register_operand" "0")
2991: (match_operand:SI 2 "general_operand" "dI")))]
2992: ""
2993: "*
2994: {
2995: if (operands[2] == const1_rtx)
2996: return \"add%.l %0,%0\";
2997: return \"asl%.l %2,%0\";
2998: }")
2999:
3000: (define_insn "ashlhi3"
3001: [(set (match_operand:HI 0 "register_operand" "=d")
3002: (ashift:HI (match_operand:HI 1 "register_operand" "0")
3003: (match_operand:HI 2 "general_operand" "dI")))]
3004: ""
3005: "asl%.w %2,%0")
3006:
3007: (define_insn "ashlqi3"
3008: [(set (match_operand:QI 0 "register_operand" "=d")
3009: (ashift:QI (match_operand:QI 1 "register_operand" "0")
3010: (match_operand:QI 2 "general_operand" "dI")))]
3011: ""
3012: "asl%.b %2,%0")
3013:
3014: ;; On the 68000, this makes faster code in a special case.
3015:
3016: (define_insn ""
3017: [(set (match_operand:SI 0 "register_operand" "=d")
3018: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
3019: (match_operand:SI 2 "immediate_operand" "i")))]
3020: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT
3021: && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)"
3022: "*
3023: {
3024: if (INTVAL (operands[2]) == 16)
3025: return \"swap %0\;ext%.l %0\";
3026:
3027: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
3028: return \"swap %0\;asr%.w %2,%0\;ext%.l %0\";
3029: }")
3030:
3031: (define_insn "ashrsi3"
3032: [(set (match_operand:SI 0 "register_operand" "=d")
3033: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
3034: (match_operand:SI 2 "general_operand" "dI")))]
3035: ""
3036: "*
3037: {
3038: return \"asr%.l %2,%0\";
3039: }")
3040:
3041: (define_insn "ashrhi3"
3042: [(set (match_operand:HI 0 "register_operand" "=d")
3043: (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
3044: (match_operand:HI 2 "general_operand" "dI")))]
3045: ""
3046: "asr%.w %2,%0")
3047:
3048: (define_insn "ashrqi3"
3049: [(set (match_operand:QI 0 "register_operand" "=d")
3050: (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
3051: (match_operand:QI 2 "general_operand" "dI")))]
3052: ""
3053: "asr%.b %2,%0")
3054:
3055: ;; logical shift instructions
3056:
3057: ;; On the 68000, this makes faster code in a special case.
3058:
3059: (define_insn ""
3060: [(set (match_operand:SI 0 "register_operand" "=d")
3061: (lshift:SI (match_operand:SI 1 "register_operand" "0")
3062: (match_operand:SI 2 "immediate_operand" "i")))]
3063: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT
3064: && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)"
3065: "*
3066: {
3067: CC_STATUS_INIT;
3068:
3069: if (INTVAL (operands[2]) == 16)
3070: return \"swap %0\;clrw %0\";
3071:
3072: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
3073: return \"lsl%.w %2,%0\;swap %0\;clrw %0\";
3074: }")
3075:
3076: (define_insn "lshlsi3"
3077: [(set (match_operand:SI 0 "register_operand" "=d")
3078: (lshift:SI (match_operand:SI 1 "register_operand" "0")
3079: (match_operand:SI 2 "general_operand" "dI")))]
3080: ""
3081: "*
3082: {
3083: if (operands[2] == const1_rtx)
3084: return \"add%.l %0,%0\";
3085: return \"lsl%.l %2,%0\";
3086: }")
3087:
3088: (define_insn "lshlhi3"
3089: [(set (match_operand:HI 0 "register_operand" "=d")
3090: (lshift:HI (match_operand:HI 1 "register_operand" "0")
3091: (match_operand:HI 2 "general_operand" "dI")))]
3092: ""
3093: "lsl%.w %2,%0")
3094:
3095: (define_insn "lshlqi3"
3096: [(set (match_operand:QI 0 "register_operand" "=d")
3097: (lshift:QI (match_operand:QI 1 "register_operand" "0")
3098: (match_operand:QI 2 "general_operand" "dI")))]
3099: ""
3100: "lsl%.b %2,%0")
3101:
3102: ;; On the 68000, this makes faster code in a special case.
3103:
3104: (define_insn ""
3105: [(set (match_operand:SI 0 "register_operand" "=d")
3106: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3107: (match_operand:SI 2 "immediate_operand" "i")))]
3108: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT
3109: && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)"
3110: "*
3111: {
3112: if (INTVAL (operands[2]) == 16)
3113: {
3114: CC_STATUS_INIT;
3115: return \"clrw %0\;swap %0\";
3116: }
3117:
3118: /* I think lsr%.w sets the CC properly. */
3119: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
3120: return \"clrw %0\;swap %0\;lsr%.w %2,%0\";
3121: }")
3122:
3123: (define_insn "lshrsi3"
3124: [(set (match_operand:SI 0 "register_operand" "=d")
3125: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3126: (match_operand:SI 2 "general_operand" "dI")))]
3127: ""
3128: "*
3129: {
3130: return \"lsr%.l %2,%0\";
3131: }")
3132:
3133: (define_insn "lshrhi3"
3134: [(set (match_operand:HI 0 "register_operand" "=d")
3135: (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
3136: (match_operand:HI 2 "general_operand" "dI")))]
3137: ""
3138: "lsr%.w %2,%0")
3139:
3140: (define_insn "lshrqi3"
3141: [(set (match_operand:QI 0 "register_operand" "=d")
3142: (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
3143: (match_operand:QI 2 "general_operand" "dI")))]
3144: ""
3145: "lsr%.b %2,%0")
3146:
3147: ;; rotate instructions
3148:
3149: (define_insn "rotlsi3"
3150: [(set (match_operand:SI 0 "register_operand" "=d")
3151: (rotate:SI (match_operand:SI 1 "register_operand" "0")
3152: (match_operand:SI 2 "general_operand" "dI")))]
3153: ""
3154: "rol%.l %2,%0")
3155:
3156: (define_insn "rotlhi3"
3157: [(set (match_operand:HI 0 "register_operand" "=d")
3158: (rotate:HI (match_operand:HI 1 "register_operand" "0")
3159: (match_operand:HI 2 "general_operand" "dI")))]
3160: ""
3161: "rol%.w %2,%0")
3162:
3163: (define_insn "rotlqi3"
3164: [(set (match_operand:QI 0 "register_operand" "=d")
3165: (rotate:QI (match_operand:QI 1 "register_operand" "0")
3166: (match_operand:QI 2 "general_operand" "dI")))]
3167: ""
3168: "rol%.b %2,%0")
3169:
3170: (define_insn "rotrsi3"
3171: [(set (match_operand:SI 0 "register_operand" "=d")
3172: (rotatert:SI (match_operand:SI 1 "register_operand" "0")
3173: (match_operand:SI 2 "general_operand" "dI")))]
3174: ""
3175: "ror%.l %2,%0")
3176:
3177: (define_insn "rotrhi3"
3178: [(set (match_operand:HI 0 "register_operand" "=d")
3179: (rotatert:HI (match_operand:HI 1 "register_operand" "0")
3180: (match_operand:HI 2 "general_operand" "dI")))]
3181: ""
3182: "ror%.w %2,%0")
3183:
3184: (define_insn "rotrqi3"
3185: [(set (match_operand:QI 0 "register_operand" "=d")
3186: (rotatert:QI (match_operand:QI 1 "register_operand" "0")
3187: (match_operand:QI 2 "general_operand" "dI")))]
3188: ""
3189: "ror%.b %2,%0")
3190:
3191: ;; Special cases of bit-field insns which we should
3192: ;; recognize in preference to the general case.
3193: ;; These handle aligned 8-bit and 16-bit fields,
3194: ;; which can usually be done with move instructions.
3195:
3196: ;
3197: ; Special case for 32-bit field in memory. This only occurs when 32-bit
3198: ; alignment of structure members is specified.
3199: ;
3200: ; The move is allowed to be odd byte aligned, because that's still faster
3201: ; than an odd byte aligned bit field instruction.
3202: ;
3203: (define_insn ""
3204: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "o")
3205: (match_operand:SI 1 "immediate_operand" "i")
3206: (match_operand:SI 2 "immediate_operand" "i"))
3207: (match_operand:SI 3 "general_operand" "rmi"))]
3208: "TARGET_68020 && TARGET_BITFIELD
3209: && GET_CODE (operands[1]) == CONST_INT
3210: && (INTVAL (operands[1]) == 32)
3211: && GET_CODE (operands[2]) == CONST_INT
3212: && (INTVAL (operands[2]) % 8) == 0
3213: && ! mode_dependent_address_p (XEXP (operands[0], 0))"
3214: "*
3215: {
3216: operands[0]
3217: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
3218:
3219: return \"move%.l %3,%0\";
3220: }")
3221:
3222: (define_insn ""
3223: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do")
3224: (match_operand:SI 1 "immediate_operand" "i")
3225: (match_operand:SI 2 "immediate_operand" "i"))
3226: (match_operand:SI 3 "general_operand" "d"))]
3227: "TARGET_68020 && TARGET_BITFIELD
3228: && GET_CODE (operands[1]) == CONST_INT
3229: && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
3230: && GET_CODE (operands[2]) == CONST_INT
3231: && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
3232: && (GET_CODE (operands[0]) == REG
3233: || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
3234: "*
3235: {
3236: if (REG_P (operands[0]))
3237: {
3238: if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
3239: return \"bfins %3,%0{%b2:%b1}\";
3240: }
3241: else
3242: operands[0]
3243: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
3244:
3245: if (GET_CODE (operands[3]) == MEM)
3246: operands[3] = adj_offsettable_operand (operands[3],
3247: (32 - INTVAL (operands[1])) / 8);
3248: if (INTVAL (operands[1]) == 8)
3249: return \"move%.b %3,%0\";
3250: return \"move%.w %3,%0\";
3251: }")
3252:
3253:
3254: ;
3255: ; Special case for 32-bit field in memory. This only occurs when 32-bit
3256: ; alignment of structure members is specified.
3257: ;
3258: ; The move is allowed to be odd byte aligned, because that's still faster
3259: ; than an odd byte aligned bit field instruction.
3260: ;
3261: (define_insn ""
3262: [(set (match_operand:SI 0 "general_operand" "=rm")
3263: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o")
3264: (match_operand:SI 2 "immediate_operand" "i")
3265: (match_operand:SI 3 "immediate_operand" "i")))]
3266: "TARGET_68020 && TARGET_BITFIELD
3267: && GET_CODE (operands[2]) == CONST_INT
3268: && (INTVAL (operands[2]) == 32)
3269: && GET_CODE (operands[3]) == CONST_INT
3270: && (INTVAL (operands[3]) % 8) == 0
3271: && ! mode_dependent_address_p (XEXP (operands[1], 0))"
3272: "*
3273: {
3274: operands[1]
3275: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
3276:
3277: return \"move%.l %1,%0\";
3278: }")
3279:
3280: (define_insn ""
3281: [(set (match_operand:SI 0 "general_operand" "=&d")
3282: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
3283: (match_operand:SI 2 "immediate_operand" "i")
3284: (match_operand:SI 3 "immediate_operand" "i")))]
3285: "TARGET_68020 && TARGET_BITFIELD
3286: && GET_CODE (operands[2]) == CONST_INT
3287: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3288: && GET_CODE (operands[3]) == CONST_INT
3289: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
3290: && (GET_CODE (operands[1]) == REG
3291: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
3292: "*
3293: {
3294: cc_status.flags |= CC_NOT_NEGATIVE;
3295: if (REG_P (operands[1]))
3296: {
3297: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
3298: return \"bfextu %1{%b3:%b2},%0\";
3299: }
3300: else
3301: operands[1]
3302: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
3303:
3304: output_asm_insn (\"clr%.l %0\", operands);
3305: if (GET_CODE (operands[0]) == MEM)
3306: operands[0] = adj_offsettable_operand (operands[0],
3307: (32 - INTVAL (operands[1])) / 8);
3308: if (INTVAL (operands[2]) == 8)
3309: return \"move%.b %1,%0\";
3310: return \"move%.w %1,%0\";
3311: }")
3312:
3313: ;
3314: ; Special case for 32-bit field in memory. This only occurs when 32-bit
3315: ; alignment of structure members is specified.
3316: ;
3317: ; The move is allowed to be odd byte aligned, because that's still faster
3318: ; than an odd byte aligned bit field instruction.
3319: ;
3320: (define_insn ""
3321: [(set (match_operand:SI 0 "general_operand" "=rm")
3322: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o")
3323: (match_operand:SI 2 "immediate_operand" "i")
3324: (match_operand:SI 3 "immediate_operand" "i")))]
3325: "TARGET_68020 && TARGET_BITFIELD
3326: && GET_CODE (operands[2]) == CONST_INT
3327: && (INTVAL (operands[2]) == 32)
3328: && GET_CODE (operands[3]) == CONST_INT
3329: && (INTVAL (operands[3]) % 8) == 0
3330: && ! mode_dependent_address_p (XEXP (operands[1], 0))"
3331: "*
3332: {
3333: operands[1]
3334: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
3335:
3336: return \"move%.l %1,%0\";
3337: }")
3338:
3339: (define_insn ""
3340: [(set (match_operand:SI 0 "general_operand" "=d")
3341: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
3342: (match_operand:SI 2 "immediate_operand" "i")
3343: (match_operand:SI 3 "immediate_operand" "i")))]
3344: "TARGET_68020 && TARGET_BITFIELD
3345: && GET_CODE (operands[2]) == CONST_INT
3346: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3347: && GET_CODE (operands[3]) == CONST_INT
3348: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
3349: && (GET_CODE (operands[1]) == REG
3350: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
3351: "*
3352: {
3353: if (REG_P (operands[1]))
3354: {
3355: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
3356: return \"bfexts %1{%b3:%b2},%0\";
3357: }
3358: else
3359: operands[1]
3360: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
3361:
3362: if (INTVAL (operands[2]) == 8)
3363: return \"move%.b %1,%0\;extb%.l %0\";
3364: return \"move%.w %1,%0\;ext%.l %0\";
3365: }")
3366:
3367: ;; Bit field instructions, general cases.
3368: ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
3369: ;; so that its address is reloaded.
3370:
3371: (define_insn "extv"
3372: [(set (match_operand:SI 0 "general_operand" "=d,d")
3373: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
3374: (match_operand:SI 2 "general_operand" "di,di")
3375: (match_operand:SI 3 "general_operand" "di,di")))]
3376: "TARGET_68020 && TARGET_BITFIELD"
3377: "bfexts %1{%b3:%b2},%0")
3378:
3379: (define_insn "extzv"
3380: [(set (match_operand:SI 0 "general_operand" "=d,d")
3381: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
3382: (match_operand:SI 2 "general_operand" "di,di")
3383: (match_operand:SI 3 "general_operand" "di,di")))]
3384: "TARGET_68020 && TARGET_BITFIELD"
3385: "*
3386: {
3387: cc_status.flags |= CC_NOT_NEGATIVE;
3388: return \"bfextu %1{%b3:%b2},%0\";
3389: }")
3390:
3391: (define_insn ""
3392: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
3393: (match_operand:SI 1 "general_operand" "di,di")
3394: (match_operand:SI 2 "general_operand" "di,di"))
3395: (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
3396: (match_operand 3 "immediate_operand" "i,i")))]
3397: "TARGET_68020 && TARGET_BITFIELD
3398: && GET_CODE (operands[3]) == CONST_INT
3399: && (INTVAL (operands[3]) == -1
3400: || (GET_CODE (operands[1]) == CONST_INT
3401: && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
3402: "*
3403: {
3404: CC_STATUS_INIT;
3405: return \"bfchg %0{%b2:%b1}\";
3406: }")
3407:
3408: (define_insn ""
3409: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
3410: (match_operand:SI 1 "general_operand" "di,di")
3411: (match_operand:SI 2 "general_operand" "di,di"))
3412: (const_int 0))]
3413: "TARGET_68020 && TARGET_BITFIELD"
3414: "*
3415: {
3416: CC_STATUS_INIT;
3417: return \"bfclr %0{%b2:%b1}\";
3418: }")
3419:
3420: (define_insn ""
3421: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
3422: (match_operand:SI 1 "general_operand" "di,di")
3423: (match_operand:SI 2 "general_operand" "di,di"))
3424: (const_int -1))]
3425: "TARGET_68020 && TARGET_BITFIELD"
3426: "*
3427: {
3428: CC_STATUS_INIT;
3429: return \"bfset %0{%b2:%b1}\";
3430: }")
3431:
3432: (define_insn "insv"
3433: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
3434: (match_operand:SI 1 "general_operand" "di,di")
3435: (match_operand:SI 2 "general_operand" "di,di"))
3436: (match_operand:SI 3 "general_operand" "d,d"))]
3437: "TARGET_68020 && TARGET_BITFIELD"
3438: "bfins %3,%0{%b2:%b1}")
3439:
3440: ;; Now recognize bit field insns that operate on registers
3441: ;; (or at least were intended to do so).
3442:
3443: (define_insn ""
3444: [(set (match_operand:SI 0 "general_operand" "=d")
3445: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
3446: (match_operand:SI 2 "general_operand" "di")
3447: (match_operand:SI 3 "general_operand" "di")))]
3448: "TARGET_68020 && TARGET_BITFIELD"
3449: "bfexts %1{%b3:%b2},%0")
3450:
3451: (define_insn ""
3452: [(set (match_operand:SI 0 "general_operand" "=d")
3453: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
3454: (match_operand:SI 2 "general_operand" "di")
3455: (match_operand:SI 3 "general_operand" "di")))]
3456: "TARGET_68020 && TARGET_BITFIELD"
3457: "*
3458: {
3459: cc_status.flags |= CC_NOT_NEGATIVE;
3460: return \"bfextu %1{%b3:%b2},%0\";
3461: }")
3462:
3463: (define_insn ""
3464: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
3465: (match_operand:SI 1 "general_operand" "di")
3466: (match_operand:SI 2 "general_operand" "di"))
3467: (const_int 0))]
3468: "TARGET_68020 && TARGET_BITFIELD"
3469: "*
3470: {
3471: CC_STATUS_INIT;
3472: return \"bfclr %0{%b2:%b1}\";
3473: }")
3474:
3475: (define_insn ""
3476: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
3477: (match_operand:SI 1 "general_operand" "di")
3478: (match_operand:SI 2 "general_operand" "di"))
3479: (const_int -1))]
3480: "TARGET_68020 && TARGET_BITFIELD"
3481: "*
3482: {
3483: CC_STATUS_INIT;
3484: return \"bfset %0{%b2:%b1}\";
3485: }")
3486:
3487: (define_insn ""
3488: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
3489: (match_operand:SI 1 "general_operand" "di")
3490: (match_operand:SI 2 "general_operand" "di"))
3491: (match_operand:SI 3 "general_operand" "d"))]
3492: "TARGET_68020 && TARGET_BITFIELD"
3493: "*
3494: {
3495: #if 0
3496: /* These special cases are now recognized by a specific pattern. */
3497: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
3498: && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
3499: return \"move%.w %3,%0\";
3500: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
3501: && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
3502: return \"move%.b %3,%0\";
3503: #endif
3504: return \"bfins %3,%0{%b2:%b1}\";
3505: }")
3506:
3507: ;; Special patterns for optimizing bit-field instructions.
3508:
3509: (define_insn ""
3510: [(set (cc0)
3511: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
3512: (match_operand:SI 1 "general_operand" "di")
3513: (match_operand:SI 2 "general_operand" "di")))]
3514: "TARGET_68020 && TARGET_BITFIELD
3515: && GET_CODE (operands[1]) == CONST_INT"
3516: "*
3517: {
3518: if (operands[1] == const1_rtx
3519: && GET_CODE (operands[2]) == CONST_INT)
3520: {
3521: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3522: return output_btst (operands,
3523: gen_rtx (CONST_INT, VOIDmode,
3524: width - INTVAL (operands[2])),
3525: operands[0],
3526: insn, 1000);
3527: /* Pass 1000 as SIGNPOS argument so that btst will
3528: not think we are testing the sign bit for an `and'
3529: and assume that nonzero implies a negative result. */
3530: }
3531: if (INTVAL (operands[1]) != 32)
3532: cc_status.flags = CC_NOT_NEGATIVE;
3533: return \"bftst %0{%b2:%b1}\";
3534: }")
3535:
3536:
3537: ;;; now handle the register cases
3538: (define_insn ""
3539: [(set (cc0)
3540: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
3541: (match_operand:SI 1 "general_operand" "di")
3542: (match_operand:SI 2 "general_operand" "di")))]
3543: "TARGET_68020 && TARGET_BITFIELD
3544: && GET_CODE (operands[1]) == CONST_INT"
3545: "*
3546: {
3547: if (operands[1] == const1_rtx
3548: && GET_CODE (operands[2]) == CONST_INT)
3549: {
3550: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3551: return output_btst (operands,
3552: gen_rtx (CONST_INT, VOIDmode,
3553: width - INTVAL (operands[2])),
3554: operands[0],
3555: insn, 1000);
3556: /* Pass 1000 as SIGNPOS argument so that btst will
3557: not think we are testing the sign bit for an `and'
3558: and assume that nonzero implies a negative result. */
3559: }
3560: if (INTVAL (operands[1]) != 32)
3561: cc_status.flags = CC_NOT_NEGATIVE;
3562: return \"bftst %0{%b2:%b1}\";
3563: }")
3564:
3565: (define_insn "seq"
3566: [(set (match_operand:QI 0 "general_operand" "=d")
3567: (eq:QI (cc0) (const_int 0)))]
3568: ""
3569: "*
3570: cc_status = cc_prev_status;
3571: OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
3572: ")
3573:
3574: (define_insn "sne"
3575: [(set (match_operand:QI 0 "general_operand" "=d")
3576: (ne:QI (cc0) (const_int 0)))]
3577: ""
3578: "*
3579: cc_status = cc_prev_status;
3580: OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
3581: ")
3582:
3583: (define_insn "sgt"
3584: [(set (match_operand:QI 0 "general_operand" "=d")
3585: (gt:QI (cc0) (const_int 0)))]
3586: ""
3587: "*
3588: cc_status = cc_prev_status;
3589: OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0);
3590: ")
3591:
3592: (define_insn "sgtu"
3593: [(set (match_operand:QI 0 "general_operand" "=d")
3594: (gtu:QI (cc0) (const_int 0)))]
3595: ""
3596: "* cc_status = cc_prev_status;
3597: return \"shi %0\"; ")
3598:
3599: (define_insn "slt"
3600: [(set (match_operand:QI 0 "general_operand" "=d")
3601: (lt:QI (cc0) (const_int 0)))]
3602: ""
3603: "* cc_status = cc_prev_status;
3604: OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
3605:
3606: (define_insn "sltu"
3607: [(set (match_operand:QI 0 "general_operand" "=d")
3608: (ltu:QI (cc0) (const_int 0)))]
3609: ""
3610: "* cc_status = cc_prev_status;
3611: return \"scs %0\"; ")
3612:
3613: (define_insn "sge"
3614: [(set (match_operand:QI 0 "general_operand" "=d")
3615: (ge:QI (cc0) (const_int 0)))]
3616: ""
3617: "* cc_status = cc_prev_status;
3618: OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
3619:
3620: (define_insn "sgeu"
3621: [(set (match_operand:QI 0 "general_operand" "=d")
3622: (geu:QI (cc0) (const_int 0)))]
3623: ""
3624: "* cc_status = cc_prev_status;
3625: return \"scc %0\"; ")
3626:
3627: (define_insn "sle"
3628: [(set (match_operand:QI 0 "general_operand" "=d")
3629: (le:QI (cc0) (const_int 0)))]
3630: ""
3631: "*
3632: cc_status = cc_prev_status;
3633: OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0);
3634: ")
3635:
3636: (define_insn "sleu"
3637: [(set (match_operand:QI 0 "general_operand" "=d")
3638: (leu:QI (cc0) (const_int 0)))]
3639: ""
3640: "* cc_status = cc_prev_status;
3641: return \"sls %0\"; ")
3642:
3643: ;; Basic conditional jump instructions.
3644:
3645: (define_insn "beq"
3646: [(set (pc)
3647: (if_then_else (eq (cc0)
3648: (const_int 0))
3649: (label_ref (match_operand 0 "" ""))
3650: (pc)))]
3651: ""
3652: "*
3653: {
3654: #ifdef MOTOROLA
3655: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
3656: #else
3657: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
3658: #endif
3659: }")
3660:
3661: (define_insn "bne"
3662: [(set (pc)
3663: (if_then_else (ne (cc0)
3664: (const_int 0))
3665: (label_ref (match_operand 0 "" ""))
3666: (pc)))]
3667: ""
3668: "*
3669: {
3670: #ifdef MOTOROLA
3671: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
3672: #else
3673: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
3674: #endif
3675: }")
3676:
3677: (define_insn "bgt"
3678: [(set (pc)
3679: (if_then_else (gt (cc0)
3680: (const_int 0))
3681: (label_ref (match_operand 0 "" ""))
3682: (pc)))]
3683: ""
3684: "*
3685: #ifdef MOTOROLA
3686: OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0);
3687: #else
3688: OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0);
3689: #endif
3690: ")
3691:
3692: (define_insn "bgtu"
3693: [(set (pc)
3694: (if_then_else (gtu (cc0)
3695: (const_int 0))
3696: (label_ref (match_operand 0 "" ""))
3697: (pc)))]
3698: ""
3699: "*
3700: #ifdef MOTOROLA
3701: return \"jbhi %l0\";
3702: #else
3703: return \"jhi %l0\";
3704: #endif
3705: ")
3706:
3707: (define_insn "blt"
3708: [(set (pc)
3709: (if_then_else (lt (cc0)
3710: (const_int 0))
3711: (label_ref (match_operand 0 "" ""))
3712: (pc)))]
3713: ""
3714: "*
3715: #ifdef MOTOROLA
3716: OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\");
3717: #else
3718: OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\");
3719: #endif
3720: ")
3721:
3722: (define_insn "bltu"
3723: [(set (pc)
3724: (if_then_else (ltu (cc0)
3725: (const_int 0))
3726: (label_ref (match_operand 0 "" ""))
3727: (pc)))]
3728: ""
3729: "*
3730: #ifdef MOTOROLA
3731: return \"jbcs %l0\";
3732: #else
3733: return \"jcs %l0\";
3734: #endif
3735: ")
3736:
3737: (define_insn "bge"
3738: [(set (pc)
3739: (if_then_else (ge (cc0)
3740: (const_int 0))
3741: (label_ref (match_operand 0 "" ""))
3742: (pc)))]
3743: ""
3744: "*
3745: #ifdef MOTOROLA
3746: OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\");
3747: #else
3748: OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\");
3749: #endif
3750: ")
3751:
3752: (define_insn "bgeu"
3753: [(set (pc)
3754: (if_then_else (geu (cc0)
3755: (const_int 0))
3756: (label_ref (match_operand 0 "" ""))
3757: (pc)))]
3758: ""
3759: "*
3760: #ifdef MOTOROLA
3761: return \"jbcc %l0\";
3762: #else
3763: return \"jcc %l0\";
3764: #endif
3765: ")
3766:
3767: (define_insn "ble"
3768: [(set (pc)
3769: (if_then_else (le (cc0)
3770: (const_int 0))
3771: (label_ref (match_operand 0 "" ""))
3772: (pc)))]
3773: ""
3774: "*
3775: #ifdef MOTOROLA
3776: OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0);
3777: #else
3778: OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0);
3779: #endif
3780: ")
3781:
3782: (define_insn "bleu"
3783: [(set (pc)
3784: (if_then_else (leu (cc0)
3785: (const_int 0))
3786: (label_ref (match_operand 0 "" ""))
3787: (pc)))]
3788: ""
3789: "*
3790: #ifdef MOTOROLA
3791: return \"jbls %l0\";
3792: #else
3793: return \"jls %l0\";
3794: #endif
3795: ")
3796:
3797: ;; Negated conditional jump instructions.
3798:
3799: (define_insn ""
3800: [(set (pc)
3801: (if_then_else (eq (cc0)
3802: (const_int 0))
3803: (pc)
3804: (label_ref (match_operand 0 "" ""))))]
3805: ""
3806: "*
3807: {
3808: #ifdef MOTOROLA
3809: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
3810: #else
3811: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
3812: #endif
3813: }")
3814:
3815: (define_insn ""
3816: [(set (pc)
3817: (if_then_else (ne (cc0)
3818: (const_int 0))
3819: (pc)
3820: (label_ref (match_operand 0 "" ""))))]
3821: ""
3822: "*
3823: {
3824: #ifdef MOTOROLA
3825: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
3826: #else
3827: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
3828: #endif
3829: }")
3830:
3831: (define_insn ""
3832: [(set (pc)
3833: (if_then_else (gt (cc0)
3834: (const_int 0))
3835: (pc)
3836: (label_ref (match_operand 0 "" ""))))]
3837: ""
3838: "*
3839: #ifdef MOTOROLA
3840: OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0);
3841: #else
3842: OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0);
3843: #endif
3844: ")
3845:
3846: (define_insn ""
3847: [(set (pc)
3848: (if_then_else (gtu (cc0)
3849: (const_int 0))
3850: (pc)
3851: (label_ref (match_operand 0 "" ""))))]
3852: ""
3853: "*
3854: #ifdef MOTOROLA
3855: return \"jbls %l0\";
3856: #else
3857: return \"jls %l0\";
3858: #endif
3859: ")
3860:
3861: (define_insn ""
3862: [(set (pc)
3863: (if_then_else (lt (cc0)
3864: (const_int 0))
3865: (pc)
3866: (label_ref (match_operand 0 "" ""))))]
3867: ""
3868: "*
3869: #ifdef MOTOROLA
3870: OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\");
3871: #else
3872: OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\");
3873: #endif
3874: ")
3875:
3876: (define_insn ""
3877: [(set (pc)
3878: (if_then_else (ltu (cc0)
3879: (const_int 0))
3880: (pc)
3881: (label_ref (match_operand 0 "" ""))))]
3882: ""
3883: "*
3884: #ifdef MOTOROLA
3885: return \"jbcc %l0\";
3886: #else
3887: return \"jcc %l0\";
3888: #endif
3889: ")
3890:
3891: (define_insn ""
3892: [(set (pc)
3893: (if_then_else (ge (cc0)
3894: (const_int 0))
3895: (pc)
3896: (label_ref (match_operand 0 "" ""))))]
3897: ""
3898: "*
3899: #ifdef MOTOROLA
3900: OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\");
3901: #else
3902: OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\");
3903: #endif
3904: ")
3905:
3906: (define_insn ""
3907: [(set (pc)
3908: (if_then_else (geu (cc0)
3909: (const_int 0))
3910: (pc)
3911: (label_ref (match_operand 0 "" ""))))]
3912: ""
3913: "*
3914: #ifdef MOTOROLA
3915: return \"jbcs %l0\";
3916: #else
3917: return \"jcs %l0\";
3918: #endif
3919: ")
3920:
3921: (define_insn ""
3922: [(set (pc)
3923: (if_then_else (le (cc0)
3924: (const_int 0))
3925: (pc)
3926: (label_ref (match_operand 0 "" ""))))]
3927: ""
3928: "*
3929: #ifdef MOTOROLA
3930: OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0);
3931: #else
3932: OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0);
3933: #endif
3934: ")
3935:
3936: (define_insn ""
3937: [(set (pc)
3938: (if_then_else (leu (cc0)
3939: (const_int 0))
3940: (pc)
3941: (label_ref (match_operand 0 "" ""))))]
3942: ""
3943: "*
3944: #ifdef MOTOROLA
3945: return \"jbhi %l0\";
3946: #else
3947: return \"jhi %l0\";
3948: #endif
3949: ")
3950:
3951: ;; Unconditional and other jump instructions
3952: (define_insn "jump"
3953: [(set (pc)
3954: (label_ref (match_operand 0 "" "")))]
3955: ""
3956: "*
3957: #ifdef MOTOROLA
3958: return \"jbra %l0\";
3959: #else
3960: return \"jra %l0\";
3961: #endif
3962: ")
3963:
3964: ;; We support two different ways of handling dispatch tables.
3965: ;; The NeXT uses absolute tables, and other machines use relative.
3966: ;; This define_expand can generate either kind.
3967: (define_expand "tablejump"
3968: [(parallel [(set (pc) (match_operand 0 "" ""))
3969: (use (label_ref (match_operand 1 "" "")))])]
3970: ""
3971: "
3972: {
3973: #ifdef CASE_VECTOR_PC_RELATIVE
3974: operands[0] = gen_rtx (PLUS, SImode, pc_rtx, operands[0]);
3975: #endif
3976: }")
3977:
3978: ;; Jump to variable address from dispatch table of absolute addresses.
3979: (define_insn ""
3980: [(set (pc) (match_operand:SI 0 "register_operand" "a"))
3981: (use (label_ref (match_operand 1 "" "")))]
3982: ""
3983: "*
3984: #ifdef MOTOROLA
3985: return \"jmp (%0)\";
3986: #else
3987: return \"jmp %0@\";
3988: #endif
3989: ")
3990:
3991: ;; Jump to variable address from dispatch table of relative addresses.
3992: (define_insn ""
3993: [(set (pc)
3994: (plus:SI (pc) (match_operand:HI 0 "register_operand" "r")))
3995: (use (label_ref (match_operand 1 "" "")))]
3996: ""
3997: "*
3998: #ifdef ASM_RETURN_CASE_JUMP
3999: ASM_RETURN_CASE_JUMP;
4000: #else
4001: #ifdef SGS
4002: #ifdef ASM_OUTPUT_CASE_LABEL
4003: return \"jmp 6(%%pc,%0.w)\";
4004: #else
4005: #ifdef CRDS
4006: return \"jmp 2(pc,%0.w)\";
4007: #else
4008: return \"jmp 2(%%pc,%0.w)\";
4009: #endif /* end !CRDS */
4010: #endif
4011: #else /* not SGS */
4012: #ifdef MOTOROLA
4013: return \"jmp (2,pc,%0.w)\";
4014: #else
4015: return \"jmp pc@(2,%0:w)\";
4016: #endif
4017: #endif
4018: #endif
4019: ")
4020:
4021: ;; Decrement-and-branch insns.
4022: (define_insn ""
4023: [(set (pc)
4024: (if_then_else
4025: (ne (match_operand:HI 0 "general_operand" "+g")
4026: (const_int 0))
4027: (label_ref (match_operand 1 "" ""))
4028: (pc)))
4029: (set (match_dup 0)
4030: (plus:HI (match_dup 0)
4031: (const_int -1)))]
4032: ""
4033: "*
4034: {
4035: CC_STATUS_INIT;
4036: if (DATA_REG_P (operands[0]))
4037: return \"dbra %0,%l1\";
4038: if (GET_CODE (operands[0]) == MEM)
4039: {
4040: #ifdef MOTOROLA
4041: #ifdef NO_ADDSUB_Q
4042: return \"sub%.w %#1,%0\;jbcc %l1\";
4043: #else
4044: return \"subq%.w %#1,%0\;jbcc %l1\";
4045: #endif
4046: #else /* not MOTOROLA */
4047: return \"subqw %#1,%0\;jcc %l1\";
4048: #endif
4049: }
4050: #ifdef MOTOROLA
4051: #ifdef SGS_CMP_ORDER
4052: #ifndef NO_ADDSUB_Q
4053: return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
4054: #else
4055: return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
4056: #endif
4057: #else /* not SGS_CMP_ORDER */
4058: return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\";
4059: #endif
4060: #else /* not MOTOROLA */
4061: return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
4062: #endif
4063: }")
4064:
4065: (define_insn ""
4066: [(set (pc)
4067: (if_then_else
4068: (ne (match_operand:SI 0 "general_operand" "+g")
4069: (const_int 0))
4070: (label_ref (match_operand 1 "" ""))
4071: (pc)))
4072: (set (match_dup 0)
4073: (plus:SI (match_dup 0)
4074: (const_int -1)))]
4075: ""
4076: "*
4077: {
4078: CC_STATUS_INIT;
4079: #ifdef MOTOROLA
4080: #ifndef NO_ADDSUB_Q
4081: if (DATA_REG_P (operands[0]))
4082: return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\";
4083: if (GET_CODE (operands[0]) == MEM)
4084: return \"sub%.l %#1,%0\;jbcc %l1\";
4085: #else
4086: if (DATA_REG_P (operands[0]))
4087: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\";
4088: if (GET_CODE (operands[0]) == MEM)
4089: return \"subq%.l %#1,%0\;jbcc %l1\";
4090: #endif /* not NO_ADDSUB_Q */
4091: #ifdef SGS_CMP_ORDER
4092: #ifndef NO_ADDSUB_Q
4093: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
4094: #else
4095: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
4096: #endif
4097: #else /* not SGS_CMP_ORDER */
4098: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
4099: #endif /* not SGS_CMP_ORDER */
4100: #else /* not MOTOROLA */
4101: if (DATA_REG_P (operands[0]))
4102: return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\";
4103: if (GET_CODE (operands[0]) == MEM)
4104: return \"subql %#1,%0\;jcc %l1\";
4105: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
4106: #endif /* not MOTOROLA */
4107: }")
4108:
4109: ;; dbra patterns that use REG_NOTES info generated by strength_reduce.
4110:
4111: (define_insn "decrement_and_branch_until_zero"
4112: [(set (pc)
4113: (if_then_else
4114: (gt (match_operand:SI 0 "general_operand" "+g")
4115: (const_int 0))
4116: (label_ref (match_operand 1 "" ""))
4117: (pc)))
4118: (set (match_dup 0)
4119: (plus:SI (match_dup 0)
4120: (const_int -1)))]
4121: "find_reg_note (insn, REG_NONNEG, 0)"
4122: "*
4123: {
4124: CC_STATUS_INIT;
4125: #ifdef MOTOROLA
4126: #ifndef NO_ADDSUB_Q
4127: if (DATA_REG_P (operands[0]))
4128: return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\";
4129: if (GET_CODE (operands[0]) == MEM)
4130: return \"sub%.l %#1,%0\;jbcc %l1\";
4131: #else
4132: if (DATA_REG_P (operands[0]))
4133: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\";
4134: if (GET_CODE (operands[0]) == MEM)
4135: return \"subq%.l %#1,%0\;jbcc %l1\";
4136: #endif
4137: #ifdef SGS_CMP_ORDER
4138: #ifndef NO_ADDSUB_Q
4139: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
4140: #else
4141: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
4142: #endif
4143: #else /* not SGS_CMP_ORDER */
4144: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
4145: #endif /* not SGS_CMP_ORDER */
4146: #else /* not MOTOROLA */
4147: if (DATA_REG_P (operands[0]))
4148: return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\";
4149: if (GET_CODE (operands[0]) == MEM)
4150: return \"subql %#1,%0\;jcc %l1\";
4151: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
4152: #endif /* not MOTOROLA */
4153: }")
4154:
4155:
4156: ;; PIC calls are handled by loading the address of the function into a
4157: ;; register (via movsi), then emitting a register indirect call using
4158: ;; the "jsr" function call syntax.
4159: ;;
4160: ;; It is important to note that the "jsr" syntax is always used for
4161: ;; PIC calls, even on machines in which GCC normally uses the "jbsr"
4162: ;; syntax for non-PIC calls. This keeps at least 1 assembler (Sun)
4163: ;; from emitting incorrect code for a PIC call.
4164: ;;
4165: ;; We have different patterns for PIC calls and non-PIC calls. The
4166: ;; different patterns are only used to choose the right syntax
4167: ;; ("jsr" vs "jbsr").
4168:
4169: ;; Call subroutine with no return value.
4170: (define_expand "call"
4171: [(call (match_operand:QI 0 "memory_operand" "")
4172: (match_operand:SI 1 "general_operand" ""))]
4173: ;; Operand 1 not really used on the m68000.
4174:
4175: ""
4176: "
4177: {
4178: if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
4179: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
4180: force_reg (Pmode, XEXP (operands[0], 0)));
4181: }")
4182:
4183: ;; This is a normal call sequence.
4184: (define_insn ""
4185: [(call (match_operand:QI 0 "memory_operand" "o")
4186: (match_operand:SI 1 "general_operand" "g"))]
4187: ;; Operand 1 not really used on the m68000.
4188:
4189: "! flag_pic"
4190: "*
4191: #ifdef MOTOROLA
4192: return \"jsr %0\";
4193: #else
4194: return \"jbsr %0\";
4195: #endif
4196: ")
4197:
4198: ;; This is a PIC call sequence.
4199: (define_insn ""
4200: [(call (match_operand:QI 0 "memory_operand" "o")
4201: (match_operand:SI 1 "general_operand" "g"))]
4202: ;; Operand 1 not really used on the m68000.
4203:
4204: "flag_pic"
4205: "*
4206: return \"jsr %0\";
4207: ")
4208:
4209: ;; Call subroutine, returning value in operand 0
4210: ;; (which must be a hard register).
4211: ;; See comments before "call" regarding PIC calls.
4212: (define_expand "call_value"
4213: [(set (match_operand 0 "" "")
4214: (call (match_operand:QI 1 "memory_operand" "")
4215: (match_operand:SI 2 "general_operand" "")))]
4216: ;; Operand 2 not really used on the m68000.
4217: ""
4218: "
4219: {
4220: if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
4221: operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
4222: force_reg (Pmode, XEXP (operands[1], 0)));
4223: }")
4224:
4225: ;; This is a normal call_value
4226: (define_insn ""
4227: [(set (match_operand 0 "" "=rf")
4228: (call (match_operand:QI 1 "memory_operand" "o")
4229: (match_operand:SI 2 "general_operand" "g")))]
4230: ;; Operand 2 not really used on the m68000.
4231: "! flag_pic"
4232: "*
4233: #ifdef MOTOROLA
4234: return \"jsr %1\";
4235: #else
4236: return \"jbsr %1\";
4237: #endif
4238: ")
4239:
4240: ;; This is a PIC call_value
4241: (define_insn ""
4242: [(set (match_operand 0 "" "=rf")
4243: (call (match_operand:QI 1 "memory_operand" "o")
4244: (match_operand:SI 2 "general_operand" "g")))]
4245: ;; Operand 2 not really used on the m68000.
4246: "flag_pic"
4247: "*
4248: return \"jsr %1\";
4249: ")
4250:
4251: (define_insn "nop"
4252: [(const_int 0)]
4253: ""
4254: "nop")
4255:
4256: (define_insn "probe"
4257: [(reg:SI 15)]
4258: "NEED_PROBE"
4259: "*
4260: {
4261: operands[0] = gen_rtx (PLUS, SImode, stack_pointer_rtx,
4262: gen_rtx (CONST_INT, VOIDmode, NEED_PROBE));
4263: return \"tstl %0\";
4264: }")
4265:
4266: ;; Used for framless functions which save no regs and allocate no locals.
4267: (define_insn "return"
4268: [(return)]
4269: "USE_RETURN_INSN"
4270: "*
4271: {
4272: if (current_function_pops_args == 0)
4273: return \"rts\";
4274: operands[0] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args);
4275: return \"rtd %0\";
4276: }")
4277:
4278: (define_insn "indirect_jump"
4279: [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
4280: ""
4281: "*
4282: #ifdef MOTOROLA
4283: return \"jmp (%0)\";
4284: #else
4285: return \"jmp %0@\";
4286: #endif
4287: ")
4288:
4289: ;; This should not be used unless the add/sub insns can't be.
4290:
4291: (define_insn ""
4292: [(set (match_operand:SI 0 "general_operand" "=a")
4293: (match_operand:QI 1 "address_operand" "p"))]
4294: ""
4295: "lea %a1,%0")
4296:
4297: ;; This is the first machine-dependent peephole optimization.
4298: ;; It is useful when a floating value is returned from a function call
4299: ;; and then is moved into an FP register.
4300: ;; But it is mainly intended to test the support for these optimizations.
4301:
4302: (define_peephole
4303: [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
4304: (set (match_operand:DF 0 "register_operand" "f")
4305: (match_operand:DF 1 "register_operand" "ad"))]
4306: "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
4307: "*
4308: {
4309: rtx xoperands[2];
4310: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
4311: output_asm_insn (\"move%.l %1,%@\", xoperands);
4312: output_asm_insn (\"move%.l %1,%-\", operands);
4313: return \"fmove%.d %+,%0\";
4314: }
4315: ")
4316:
4317: ;; Optimize a stack-adjust followed by a push of an argument.
4318: ;; This is said to happen frequently with -msoft-float
4319: ;; when there are consecutive library calls.
4320:
4321: (define_peephole
4322: [(set (reg:SI 15) (plus:SI (reg:SI 15)
4323: (match_operand:SI 0 "immediate_operand" "n")))
4324: (set (match_operand:SF 1 "push_operand" "=m")
4325: (match_operand:SF 2 "general_operand" "rmfF"))]
4326: "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4
4327: && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
4328: "*
4329: {
4330: if (INTVAL (operands[0]) > 4)
4331: {
4332: rtx xoperands[2];
4333: xoperands[0] = stack_pointer_rtx;
4334: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4);
4335: #ifndef NO_ADDSUB_Q
4336: if (INTVAL (xoperands[1]) <= 8)
4337: output_asm_insn (\"addq%.w %1,%0\", xoperands);
4338: else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
4339: {
4340: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
4341: INTVAL (xoperands[1]) - 8);
4342: output_asm_insn (\"addq%.w %#8,%0; addq%.w %1,%0\", xoperands);
4343: }
4344: else
4345: #endif
4346: if (INTVAL (xoperands[1]) <= 0x7FFF)
4347: output_asm_insn (\"add%.w %1,%0\", xoperands);
4348: else
4349: output_asm_insn (\"add%.l %1,%0\", xoperands);
4350: }
4351: if (FP_REG_P (operands[2]))
4352: return \"fmove%.s %2,%@\";
4353: return \"move%.l %2,%@\";
4354: }")
4355:
4356: ;; Speed up stack adjust followed by a fullword fixedpoint push.
4357:
4358: (define_peephole
4359: [(set (reg:SI 15) (plus:SI (reg:SI 15)
4360: (match_operand:SI 0 "immediate_operand" "n")))
4361: (set (match_operand:SI 1 "push_operand" "=m")
4362: (match_operand:SI 2 "general_operand" "g"))]
4363: "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4
4364: && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
4365: "*
4366: {
4367: if (INTVAL (operands[0]) > 4)
4368: {
4369: rtx xoperands[2];
4370: xoperands[0] = stack_pointer_rtx;
4371: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4);
4372: #ifndef NO_ADDSUB_Q
4373: if (INTVAL (xoperands[1]) <= 8)
4374: output_asm_insn (\"addq%.w %1,%0\", xoperands);
4375: else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
4376: {
4377: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
4378: INTVAL (xoperands[1]) - 8);
4379: output_asm_insn (\"addq%.w %#8,%0; addq%.w %1,%0\", xoperands);
4380: }
4381: else
4382: #endif
4383: if (INTVAL (xoperands[1]) <= 0x7FFF)
4384: output_asm_insn (\"add%.w %1,%0\", xoperands);
4385: else
4386: output_asm_insn (\"add%.l %1,%0\", xoperands);
4387: }
4388: if (operands[2] == const0_rtx)
4389: return \"clr%.l %@\";
4390: return \"move%.l %2,%@\";
4391: }")
4392:
4393: ;; Speed up pushing a single byte but leaving four bytes of space.
4394:
4395: (define_peephole
4396: [(set (mem:QI (pre_dec:SI (reg:SI 15)))
4397: (match_operand:QI 1 "general_operand" "dami"))
4398: (set (reg:SI 15) (minus:SI (reg:SI 15) (const_int 2)))]
4399: "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
4400: "*
4401: {
4402: rtx xoperands[4];
4403:
4404: if (GET_CODE (operands[1]) == REG)
4405: return \"move%.l %1,%-\";
4406:
4407: xoperands[1] = operands[1];
4408: xoperands[2]
4409: = gen_rtx (MEM, QImode,
4410: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx,
4411: gen_rtx (CONST_INT, VOIDmode, 3)));
4412: xoperands[3] = stack_pointer_rtx;
4413: output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands);
4414: return \"\";
4415: }")
4416:
4417: ;; FPA multiply and add.
4418: (define_insn ""
4419: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4420: (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y")
4421: (match_operand:DF 2 "general_operand" "xH,y,y"))
4422: (match_operand:DF 3 "general_operand" "xH,y,dmF")))]
4423: "TARGET_FPA"
4424: "@
4425: fpma%.d %1,%w2,%w3,%0
4426: fpma%.d %x1,%x2,%x3,%0
4427: fpma%.d %x1,%x2,%x3,%0")
4428:
4429: (define_insn ""
4430: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4431: (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y")
4432: (match_operand:SF 2 "general_operand" "xH,y,ydmF"))
4433: (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))]
4434: "TARGET_FPA"
4435: "@
4436: fpma%.s %1,%w2,%w3,%0
4437: fpma%.s %1,%2,%3,%0
4438: fpma%.s %1,%2,%3,%0")
4439:
4440: ;; FPA Multiply and subtract
4441: (define_insn ""
4442: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4443: (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
4444: (mult:DF (match_operand:DF 2 "general_operand" "%xH,y,y")
4445: (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
4446: "TARGET_FPA"
4447: "@
4448: fpms%.d %3,%w2,%w1,%0
4449: fpms%.d %x3,%2,%x1,%0
4450: fpms%.d %x3,%2,%x1,%0")
4451:
4452: (define_insn ""
4453: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4454: (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
4455: (mult:SF (match_operand:SF 2 "general_operand" "%xH,rmF,y")
4456: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
4457: "TARGET_FPA"
4458: "@
4459: fpms%.s %3,%w2,%w1,%0
4460: fpms%.s %3,%2,%1,%0
4461: fpms%.s %3,%2,%1,%0")
4462:
4463: (define_insn ""
4464: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4465: (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%xH,y,y")
4466: (match_operand:DF 2 "general_operand" "x,y,rmF"))
4467: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
4468: "TARGET_FPA"
4469: "@
4470: fpmr%.d %2,%w1,%w3,%0
4471: fpmr%.d %x2,%1,%x3,%0
4472: fpmr%.d %x2,%1,%x3,%0")
4473:
4474: (define_insn ""
4475: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4476: (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y")
4477: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
4478: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
4479: "TARGET_FPA"
4480: "@
4481: fpmr%.s %2,%w1,%w3,%0
4482: fpmr%.s %x2,%1,%x3,%0
4483: fpmr%.s %x2,%1,%x3,%0")
4484:
4485: ;; FPA Add and multiply
4486: (define_insn ""
4487: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4488: (mult:DF (plus:DF (match_operand:DF 1 "general_operand" "%xH,y,y")
4489: (match_operand:DF 2 "general_operand" "x,y,rmF"))
4490: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
4491: "TARGET_FPA"
4492: "@
4493: fpam%.d %2,%w1,%w3,%0
4494: fpam%.d %x2,%1,%x3,%0
4495: fpam%.d %x2,%1,%x3,%0")
4496:
4497: (define_insn ""
4498: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4499: (mult:SF (plus:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y")
4500: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
4501: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
4502: "TARGET_FPA"
4503: "@
4504: fpam%.s %2,%w1,%w3,%0
4505: fpam%.s %x2,%1,%x3,%0
4506: fpam%.s %x2,%1,%x3,%0")
4507:
4508: ;;FPA Subtract and multiply
4509: (define_insn ""
4510: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4511: (mult:DF (minus:DF (match_operand:DF 1 "general_operand" "xH,y,y")
4512: (match_operand:DF 2 "general_operand" "x,y,rmF"))
4513: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
4514: "TARGET_FPA"
4515: "@
4516: fpsm%.d %2,%w1,%w3,%0
4517: fpsm%.d %x2,%1,%x3,%0
4518: fpsm%.d %x2,%1,%x3,%0")
4519:
4520: (define_insn ""
4521: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4522: (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
4523: (minus:DF (match_operand:DF 2 "general_operand" "xH,y,y")
4524: (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
4525: "TARGET_FPA"
4526: "@
4527: fpsm%.d %3,%w2,%w1,%0
4528: fpsm%.d %x3,%2,%x1,%0
4529: fpsm%.d %x3,%2,%x1,%0")
4530:
4531: (define_insn ""
4532: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4533: (mult:SF (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,y")
4534: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
4535: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
4536: "TARGET_FPA"
4537: "@
4538: fpsm%.s %2,%w1,%w3,%0
4539: fpsm%.s %x2,%1,%x3,%0
4540: fpsm%.s %x2,%1,%x3,%0")
4541:
4542: (define_insn ""
4543: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4544: (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
4545: (minus:SF (match_operand:SF 2 "general_operand" "xH,rmF,y")
4546: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
4547: "TARGET_FPA"
4548: "@
4549: fpsm%.s %3,%w2,%w1,%0
4550: fpsm%.s %x3,%2,%x1,%0
4551: fpsm%.s %x3,%2,%x1,%0")
4552:
4553: ;;- Local variables:
4554: ;;- mode:emacs-lisp
4555: ;;- comment-start: ";;- "
4556: ;;- comment-start-skip: ";+- *"
4557: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
4558: ;;- eval: (modify-syntax-entry ?[ "(]")
4559: ;;- eval: (modify-syntax-entry ?] ")[")
4560: ;;- eval: (modify-syntax-entry ?{ "(}")
4561: ;;- eval: (modify-syntax-entry ?} "){")
4562: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.