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