|
|
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"
1.1.1.4 ! root 659: ; [(set (match_operand:SI 0 "general_operand" "+r")
! 660: ; (match_operand:SI 1 "general_operand" "+r"))
1.1 root 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: {
1.1.1.4 ! root 2540: #ifdef FSGLMUL_USE_S
! 2541: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
! 2542: return (TARGET_68040_ONLY
! 2543: ? \"fsmul%.s %2,%0\"
! 2544: : \"fsglmul%.s %2,%0\");
! 2545: #else
1.1 root 2546: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2547: return (TARGET_68040_ONLY
2548: ? \"fsmul%.x %2,%0\"
2549: : \"fsglmul%.x %2,%0\");
1.1.1.4 ! root 2550: #endif
1.1 root 2551: return (TARGET_68040_ONLY
2552: ? \"fsmul%.s %f2,%0\"
2553: : \"fsglmul%.s %f2,%0\");
2554: }")
2555:
2556: ;; divide instructions
2557:
2558: (define_insn "divhi3"
2559: [(set (match_operand:HI 0 "general_operand" "=d")
2560: (div:HI (match_operand:HI 1 "general_operand" "0")
2561: (match_operand:HI 2 "general_operand" "dmn")))]
2562: ""
2563: "*
2564: {
2565: #ifdef MOTOROLA
2566: return \"ext%.l %0\;divs%.w %2,%0\";
2567: #else
2568: return \"extl %0\;divs %2,%0\";
2569: #endif
2570: }")
2571:
2572: (define_insn "divhisi3"
2573: [(set (match_operand:HI 0 "general_operand" "=d")
2574: (truncate:HI
2575: (div:SI
2576: (match_operand:SI 1 "general_operand" "0")
2577: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
2578: ""
2579: "*
2580: {
2581: #ifdef MOTOROLA
2582: return \"divs%.w %2,%0\";
2583: #else
2584: return \"divs %2,%0\";
2585: #endif
2586: }")
2587:
2588: (define_insn ""
2589: [(set (match_operand:HI 0 "general_operand" "=d")
2590: (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0")
2591: (match_operand:SI 2 "const_int_operand" "n"))))]
2592: ""
2593: "*
2594: {
2595: #ifdef MOTOROLA
2596: return \"divs%.w %2,%0\";
2597: #else
2598: return \"divs %2,%0\";
2599: #endif
2600: }")
2601:
2602: (define_insn "udivhi3"
2603: [(set (match_operand:HI 0 "general_operand" "=d")
2604: (udiv:HI (match_operand:HI 1 "general_operand" "0")
2605: (match_operand:HI 2 "general_operand" "dmn")))]
2606: ""
2607: "*
2608: {
2609: #ifdef MOTOROLA
2610: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\";
2611: #else
2612: return \"andl %#0xFFFF,%0\;divu %2,%0\";
2613: #endif
2614: }")
2615:
2616: (define_insn "udivhisi3"
2617: [(set (match_operand:HI 0 "general_operand" "=d")
2618: (truncate:HI
2619: (udiv:SI
2620: (match_operand:SI 1 "general_operand" "0")
2621: (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
2622: ""
2623: "*
2624: {
2625: #ifdef MOTOROLA
2626: return \"divu%.w %2,%0\";
2627: #else
2628: return \"divu %2,%0\";
2629: #endif
2630: }")
2631:
2632: (define_insn ""
2633: [(set (match_operand:HI 0 "general_operand" "=d")
2634: (truncate:HI (udiv:SI (match_operand:SI 1 "general_operand" "0")
2635: (match_operand:SI 2 "const_int_operand" "n"))))]
2636: ""
2637: "*
2638: {
2639: #ifdef MOTOROLA
2640: return \"divu%.w %2,%0\";
2641: #else
2642: return \"divu %2,%0\";
2643: #endif
2644: }")
2645:
2646: (define_expand "divdf3"
2647: [(set (match_operand:DF 0 "general_operand" "")
2648: (div:DF (match_operand:DF 1 "general_operand" "")
2649: (match_operand:DF 2 "general_operand" "")))]
2650: "TARGET_68881 || TARGET_FPA"
2651: "")
2652:
2653: (define_insn ""
2654: [(set (match_operand:DF 0 "general_operand" "=x,y,y")
2655: (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF")
2656: (match_operand:DF 2 "general_operand" "xH,rmF,0")))]
2657: "TARGET_FPA"
2658: "*
2659: {
2660: if (rtx_equal_p (operands[0], operands[2]))
2661: return \"fprdiv%.d %y1,%0\";
2662: if (rtx_equal_p (operands[0], operands[1]))
2663: return \"fpdiv%.d %y2,%0\";
2664: if (which_alternative == 0)
2665: return \"fpdiv3%.d %w2,%w1,%0\";
2666: return \"fpdiv3%.d %x2,%x1,%x0\";
2667: }")
2668:
2669: (define_insn ""
2670: [(set (match_operand:DF 0 "general_operand" "=f")
2671: (div:DF (match_operand:DF 1 "general_operand" "0")
2672: (match_operand:DF 2 "general_operand" "fmG")))]
2673: "TARGET_68881"
2674: "*
2675: {
2676: if (REG_P (operands[2]))
2677: return \"f%&div%.x %2,%0\";
2678: return \"f%&div%.d %f2,%0\";
2679: }")
2680:
2681: (define_expand "divsf3"
2682: [(set (match_operand:SF 0 "general_operand" "")
2683: (div:SF (match_operand:SF 1 "general_operand" "")
2684: (match_operand:SF 2 "general_operand" "")))]
2685: "TARGET_68881 || TARGET_FPA"
2686: "")
2687:
2688: (define_insn ""
2689: [(set (match_operand:SF 0 "general_operand" "=x,y,y")
2690: (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
2691: (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
2692: "TARGET_FPA"
2693: "*
2694: {
2695: if (rtx_equal_p (operands[0], operands[1]))
2696: return \"fpdiv%.s %w2,%0\";
2697: if (rtx_equal_p (operands[0], operands[2]))
2698: return \"fprdiv%.s %w1,%0\";
2699: if (which_alternative == 0)
2700: return \"fpdiv3%.s %w2,%w1,%0\";
2701: return \"fpdiv3%.s %2,%1,%0\";
2702: }")
2703:
2704: (define_insn ""
2705: [(set (match_operand:SF 0 "general_operand" "=f")
2706: (div:SF (match_operand:SF 1 "general_operand" "0")
2707: (match_operand:SF 2 "general_operand" "fdmF")))]
2708: "TARGET_68881"
2709: "*
2710: {
1.1.1.3 root 2711: #ifdef FSGLDIV_USE_S
2712: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2713: return (TARGET_68040_ONLY
2714: ? \"fsdiv%.s %2,%0\"
2715: : \"fsgldiv%.s %2,%0\");
2716: #else
1.1 root 2717: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2718: return (TARGET_68040_ONLY
2719: ? \"fsdiv%.x %2,%0\"
2720: : \"fsgldiv%.x %2,%0\");
1.1.1.3 root 2721: #endif
1.1 root 2722: return (TARGET_68040_ONLY
2723: ? \"fsdiv%.s %f2,%0\"
2724: : \"fsgldiv%.s %f2,%0\");
2725: }")
2726:
2727: ;; Remainder instructions.
2728:
2729: (define_insn "modhi3"
2730: [(set (match_operand:HI 0 "general_operand" "=d")
2731: (mod:HI (match_operand:HI 1 "general_operand" "0")
2732: (match_operand:HI 2 "general_operand" "dmn")))]
2733: ""
2734: "*
2735: {
2736: /* The swap insn produces cc's that don't correspond to the result. */
2737: CC_STATUS_INIT;
2738: #ifdef MOTOROLA
2739: return \"ext%.l %0\;divs%.w %2,%0\;swap %0\";
2740: #else
2741: return \"extl %0\;divs %2,%0\;swap %0\";
2742: #endif
2743: }")
2744:
2745: (define_insn "modhisi3"
2746: [(set (match_operand:HI 0 "general_operand" "=d")
2747: (truncate:HI
2748: (mod:SI
2749: (match_operand:SI 1 "general_operand" "0")
2750: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
2751: ""
2752: "*
2753: {
2754: /* The swap insn produces cc's that don't correspond to the result. */
2755: CC_STATUS_INIT;
2756: #ifdef MOTOROLA
2757: return \"divs%.w %2,%0\;swap %0\";
2758: #else
2759: return \"divs %2,%0\;swap %0\";
2760: #endif
2761: }")
2762:
2763: (define_insn ""
2764: [(set (match_operand:HI 0 "general_operand" "=d")
2765: (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0")
2766: (match_operand:SI 2 "const_int_operand" "n"))))]
2767: ""
2768: "*
2769: {
2770: /* The swap insn produces cc's that don't correspond to the result. */
2771: CC_STATUS_INIT;
2772: #ifdef MOTOROLA
2773: return \"divs%.w %2,%0\;swap %0\";
2774: #else
2775: return \"divs %2,%0\;swap %0\";
2776: #endif
2777: }")
2778:
2779: (define_insn "umodhi3"
2780: [(set (match_operand:HI 0 "general_operand" "=d")
2781: (umod:HI (match_operand:HI 1 "general_operand" "0")
2782: (match_operand:HI 2 "general_operand" "dmn")))]
2783: ""
2784: "*
2785: {
2786: /* The swap insn produces cc's that don't correspond to the result. */
2787: CC_STATUS_INIT;
2788: #ifdef MOTOROLA
2789: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\";
2790: #else
2791: return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\";
2792: #endif
2793: }")
2794:
2795: (define_insn "umodhisi3"
2796: [(set (match_operand:HI 0 "general_operand" "=d")
2797: (truncate:HI
2798: (umod:SI
2799: (match_operand:SI 1 "general_operand" "0")
2800: (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
2801: ""
2802: "*
2803: {
2804: /* The swap insn produces cc's that don't correspond to the result. */
2805: CC_STATUS_INIT;
2806: #ifdef MOTOROLA
2807: return \"divu%.w %2,%0\;swap %0\";
2808: #else
2809: return \"divu %2,%0\;swap %0\";
2810: #endif
2811: }")
2812:
2813: (define_insn ""
2814: [(set (match_operand:HI 0 "general_operand" "=d")
2815: (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0")
2816: (match_operand:SI 2 "const_int_operand" "n"))))]
2817: ""
2818: "*
2819: {
2820: /* The swap insn produces cc's that don't correspond to the result. */
2821: CC_STATUS_INIT;
2822: #ifdef MOTOROLA
2823: return \"divu%.w %2,%0\;swap %0\";
2824: #else
2825: return \"divu %2,%0\;swap %0\";
2826: #endif
2827: }")
2828:
2829: (define_insn "divmodsi4"
2830: [(set (match_operand:SI 0 "general_operand" "=d")
2831: (div:SI (match_operand:SI 1 "general_operand" "0")
2832: (match_operand:SI 2 "general_operand" "dmsK")))
2833: (set (match_operand:SI 3 "general_operand" "=d")
2834: (mod:SI (match_dup 1) (match_dup 2)))]
2835: "TARGET_68020"
2836: "*
2837: {
2838: if (find_reg_note (insn, REG_UNUSED, operands[3]))
2839: return \"divs%.l %2,%0\";
2840: else
2841: return \"divsl%.l %2,%3:%0\";
2842: }")
2843:
2844: (define_insn "udivmodsi4"
2845: [(set (match_operand:SI 0 "general_operand" "=d")
2846: (udiv:SI (match_operand:SI 1 "general_operand" "0")
2847: (match_operand:SI 2 "general_operand" "dmsK")))
2848: (set (match_operand:SI 3 "general_operand" "=d")
2849: (umod:SI (match_dup 1) (match_dup 2)))]
2850: "TARGET_68020"
2851: "*
2852: {
2853: if (find_reg_note (insn, REG_UNUSED, operands[3]))
2854: return \"divu%.l %2,%0\";
2855: else
2856: return \"divul%.l %2,%3:%0\";
2857: }")
2858:
2859: ;; logical-and instructions
2860:
2861: ;; Prevent AND from being made with sp. This doesn't exist in the machine
2862: ;; and reload will cause inefficient code. Since sp is a FIXED_REG, we
1.1.1.2 root 2863: ;; can't allocate pseudos into it.
1.1 root 2864: (define_insn "andsi3"
2865: [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
2866: (and:SI (match_operand:SI 1 "general_operand" "%0,0")
2867: (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
2868: ""
2869: "*
2870: {
2871: int logval;
2872: if (GET_CODE (operands[2]) == CONST_INT
2873: && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
2874: && (DATA_REG_P (operands[0])
2875: || offsettable_memref_p (operands[0])))
2876: {
2877: if (GET_CODE (operands[0]) != REG)
2878: operands[0] = adj_offsettable_operand (operands[0], 2);
2879: operands[2] = gen_rtx (CONST_INT, VOIDmode,
2880: INTVAL (operands[2]) & 0xffff);
2881: /* Do not delete a following tstl %0 insn; that would be incorrect. */
2882: CC_STATUS_INIT;
2883: if (operands[2] == const0_rtx)
2884: return \"clr%.w %0\";
2885: return \"and%.w %2,%0\";
2886: }
2887: if (GET_CODE (operands[2]) == CONST_INT
2888: && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
2889: && (DATA_REG_P (operands[0])
2890: || offsettable_memref_p (operands[0])))
2891: {
2892: if (DATA_REG_P (operands[0]))
2893: {
2894: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
2895: }
2896: else
2897: {
2898: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
2899: }
2900: /* This does not set condition codes in a standard way. */
2901: CC_STATUS_INIT;
2902: return \"bclr %1,%0\";
2903: }
2904: return \"and%.l %2,%0\";
2905: }")
2906:
2907: (define_insn "andhi3"
2908: [(set (match_operand:HI 0 "general_operand" "=m,d")
2909: (and:HI (match_operand:HI 1 "general_operand" "%0,0")
2910: (match_operand:HI 2 "general_operand" "dn,dmn")))]
2911: ""
2912: "and%.w %2,%0")
2913:
1.1.1.2 root 2914: (define_insn ""
2915: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2916: (and:HI (match_dup 0)
2917: (match_operand:HI 1 "general_operand" "dn,dmn")))]
2918: ""
2919: "and%.w %1,%0")
2920:
2921: (define_insn ""
2922: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2923: (and:HI (match_operand:HI 1 "general_operand" "dn,dmn")
2924: (match_dup 0)))]
2925: ""
2926: "and%.w %1,%0")
2927:
1.1 root 2928: (define_insn "andqi3"
2929: [(set (match_operand:QI 0 "general_operand" "=m,d")
2930: (and:QI (match_operand:QI 1 "general_operand" "%0,0")
2931: (match_operand:QI 2 "general_operand" "dn,dmn")))]
2932: ""
2933: "and%.b %2,%0")
2934:
1.1.1.2 root 2935: (define_insn ""
2936: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2937: (and:QI (match_dup 0)
2938: (match_operand:QI 1 "general_operand" "dn,dmn")))]
2939: ""
2940: "and%.b %1,%0")
2941:
2942: (define_insn ""
2943: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
2944: (and:QI (match_operand:QI 1 "general_operand" "dn,dmn")
2945: (match_dup 0)))]
2946: ""
2947: "and%.b %1,%0")
1.1 root 2948:
2949: ;; inclusive-or instructions
2950:
2951: (define_insn "iorsi3"
2952: [(set (match_operand:SI 0 "general_operand" "=m,d")
2953: (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
2954: (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
2955: ""
2956: "*
2957: {
2958: register int logval;
2959: if (GET_CODE (operands[2]) == CONST_INT
2960: && INTVAL (operands[2]) >> 16 == 0
2961: && (DATA_REG_P (operands[0])
2962: || offsettable_memref_p (operands[0])))
2963: {
2964: if (GET_CODE (operands[0]) != REG)
2965: operands[0] = adj_offsettable_operand (operands[0], 2);
2966: /* Do not delete a following tstl %0 insn; that would be incorrect. */
2967: CC_STATUS_INIT;
2968: return \"or%.w %2,%0\";
2969: }
2970: if (GET_CODE (operands[2]) == CONST_INT
2971: && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
2972: && (DATA_REG_P (operands[0])
2973: || offsettable_memref_p (operands[0])))
2974: {
2975: if (DATA_REG_P (operands[0]))
2976: {
2977: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
2978: }
2979: else
2980: {
2981: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
2982: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
2983: }
2984: return \"bset %1,%0\";
2985: }
2986: return \"or%.l %2,%0\";
2987: }")
2988:
2989: (define_insn "iorhi3"
2990: [(set (match_operand:HI 0 "general_operand" "=m,d")
2991: (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
2992: (match_operand:HI 2 "general_operand" "dn,dmn")))]
2993: ""
2994: "or%.w %2,%0")
2995:
1.1.1.2 root 2996: (define_insn ""
2997: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
2998: (ior:HI (match_dup 0)
2999: (match_operand:HI 1 "general_operand" "dn,dmn")))]
3000: ""
3001: "or%.w %1,%0")
3002:
3003: (define_insn ""
3004: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
3005: (ior:HI (match_operand:HI 1 "general_operand" "dn,dmn")
3006: (match_dup 0)))]
3007: ""
3008: "or%.w %1,%0")
3009:
1.1 root 3010: (define_insn "iorqi3"
3011: [(set (match_operand:QI 0 "general_operand" "=m,d")
3012: (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
3013: (match_operand:QI 2 "general_operand" "dn,dmn")))]
3014: ""
3015: "or%.b %2,%0")
1.1.1.2 root 3016:
3017: (define_insn ""
3018: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3019: (ior:QI (match_dup 0)
3020: (match_operand:QI 1 "general_operand" "dn,dmn")))]
3021: ""
3022: "or%.b %1,%0")
3023:
3024: (define_insn ""
3025: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
3026: (ior:QI (match_operand:QI 1 "general_operand" "dn,dmn")
3027: (match_dup 0)))]
3028: ""
3029: "or%.b %1,%0")
1.1 root 3030:
3031: ;; xor instructions
3032:
3033: (define_insn "xorsi3"
3034: [(set (match_operand:SI 0 "general_operand" "=do,m")
3035: (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
3036: (match_operand:SI 2 "general_operand" "di,dKs")))]
3037: ""
3038: "*
3039: {
3040: if (GET_CODE (operands[2]) == CONST_INT
3041: && INTVAL (operands[2]) >> 16 == 0
3042: && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
3043: {
3044: if (! DATA_REG_P (operands[0]))
3045: operands[0] = adj_offsettable_operand (operands[0], 2);
3046: /* Do not delete a following tstl %0 insn; that would be incorrect. */
3047: CC_STATUS_INIT;
3048: return \"eor%.w %2,%0\";
3049: }
3050: return \"eor%.l %2,%0\";
3051: }")
3052:
3053: (define_insn "xorhi3"
3054: [(set (match_operand:HI 0 "general_operand" "=dm")
3055: (xor:HI (match_operand:HI 1 "general_operand" "%0")
3056: (match_operand:HI 2 "general_operand" "dn")))]
3057: ""
3058: "eor%.w %2,%0")
3059:
1.1.1.2 root 3060: (define_insn ""
3061: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
3062: (xor:HI (match_dup 0)
3063: (match_operand:HI 1 "general_operand" "dn")))]
3064: ""
3065: "eor%.w %1,%0")
3066:
3067:
3068: (define_insn ""
3069: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
3070: (xor:HI (match_operand:HI 1 "general_operand" "dn")
3071: (match_dup 0)))]
3072: ""
3073: "eor%.w %1,%0")
3074:
1.1 root 3075: (define_insn "xorqi3"
3076: [(set (match_operand:QI 0 "general_operand" "=dm")
3077: (xor:QI (match_operand:QI 1 "general_operand" "%0")
3078: (match_operand:QI 2 "general_operand" "dn")))]
3079: ""
3080: "eor%.b %2,%0")
1.1.1.2 root 3081:
3082: (define_insn ""
3083: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
3084: (xor:QI (match_dup 0)
3085: (match_operand:QI 1 "general_operand" "dn")))]
3086: ""
3087: "eor%.b %1,%0")
3088:
3089: (define_insn ""
3090: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
3091: (xor:QI (match_operand:QI 1 "general_operand" "dn")
3092: (match_dup 0)))]
3093: ""
3094: "eor%.b %1,%0")
1.1 root 3095:
3096: ;; negation instructions
3097:
3098: (define_insn "negsi2"
3099: [(set (match_operand:SI 0 "general_operand" "=dm")
3100: (neg:SI (match_operand:SI 1 "general_operand" "0")))]
3101: ""
3102: "neg%.l %0")
3103:
3104: (define_insn "neghi2"
3105: [(set (match_operand:HI 0 "general_operand" "=dm")
3106: (neg:HI (match_operand:HI 1 "general_operand" "0")))]
3107: ""
3108: "neg%.w %0")
3109:
1.1.1.2 root 3110: (define_insn ""
3111: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
3112: (neg:HI (match_dup 0)))]
3113: ""
3114: "neg%.w %0")
3115:
1.1 root 3116: (define_insn "negqi2"
3117: [(set (match_operand:QI 0 "general_operand" "=dm")
3118: (neg:QI (match_operand:QI 1 "general_operand" "0")))]
3119: ""
3120: "neg%.b %0")
3121:
1.1.1.2 root 3122: (define_insn ""
3123: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
3124: (neg:QI (match_dup 0)))]
3125: ""
3126: "neg%.b %0")
3127:
1.1 root 3128: (define_expand "negsf2"
3129: [(set (match_operand:SF 0 "general_operand" "")
3130: (neg:SF (match_operand:SF 1 "general_operand" "")))]
3131: "TARGET_68881 || TARGET_FPA"
3132: "")
3133:
3134: (define_insn ""
3135: [(set (match_operand:SF 0 "general_operand" "=x,y")
3136: (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
3137: "TARGET_FPA"
3138: "fpneg%.s %w1,%0")
3139:
3140: (define_insn ""
3141: [(set (match_operand:SF 0 "general_operand" "=f,d")
3142: (neg:SF (match_operand:SF 1 "general_operand" "fdmF,0")))]
3143: "TARGET_68881"
3144: "*
3145: {
3146: if (DATA_REG_P (operands[0]))
3147: {
3148: operands[1] = gen_rtx (CONST_INT, VOIDmode, 31);
3149: return \"bchg %1,%0\";
3150: }
3151: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
3152: return \"f%$neg%.x %1,%0\";
3153: return \"f%$neg%.s %f1,%0\";
3154: }")
3155:
3156: (define_expand "negdf2"
3157: [(set (match_operand:DF 0 "general_operand" "")
3158: (neg:DF (match_operand:DF 1 "general_operand" "")))]
3159: "TARGET_68881 || TARGET_FPA"
3160: "")
3161:
3162: (define_insn ""
3163: [(set (match_operand:DF 0 "general_operand" "=x,y")
3164: (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
3165: "TARGET_FPA"
3166: "fpneg%.d %y1, %0")
3167:
3168: (define_insn ""
3169: [(set (match_operand:DF 0 "general_operand" "=f,d")
3170: (neg:DF (match_operand:DF 1 "general_operand" "fmF,0")))]
3171: "TARGET_68881"
3172: "*
3173: {
3174: if (DATA_REG_P (operands[0]))
3175: {
3176: operands[1] = gen_rtx (CONST_INT, VOIDmode, 31);
3177: return \"bchg %1,%0\";
3178: }
3179: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
3180: return \"f%&neg%.x %1,%0\";
3181: return \"f%&neg%.d %f1,%0\";
3182: }")
3183:
1.1.1.3 root 3184: ;; Sqrt instruction for the 68881
3185:
3186: (define_insn "sqrtdf2"
3187: [(set (match_operand:DF 0 "general_operand" "=f")
3188: (sqrt:DF (match_operand:DF 1 "general_operand" "fm")))]
3189: "TARGET_68881"
3190: "*
3191: {
3192: if (FP_REG_P (operands[1]))
3193: return \"fsqrt%.x %1,%0\";
3194: else
3195: return \"fsqrt%.d %1,%0\";
3196: }")
3197:
1.1 root 3198: ;; Absolute value instructions
3199:
3200: (define_expand "abssf2"
3201: [(set (match_operand:SF 0 "general_operand" "")
3202: (abs:SF (match_operand:SF 1 "general_operand" "")))]
3203: "TARGET_68881 || TARGET_FPA"
3204: "")
3205:
3206: (define_insn ""
3207: [(set (match_operand:SF 0 "general_operand" "=x,y")
3208: (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
3209: "TARGET_FPA"
3210: "fpabs%.s %y1,%0")
3211:
3212: (define_insn ""
3213: [(set (match_operand:SF 0 "general_operand" "=f")
3214: (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))]
3215: "TARGET_68881"
3216: "*
3217: {
3218: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
3219: return \"f%$abs%.x %1,%0\";
3220: return \"f%$abs%.s %f1,%0\";
3221: }")
3222:
3223: (define_expand "absdf2"
3224: [(set (match_operand:DF 0 "general_operand" "")
3225: (abs:DF (match_operand:DF 1 "general_operand" "")))]
3226: "TARGET_68881 || TARGET_FPA"
3227: "")
3228:
3229: (define_insn ""
3230: [(set (match_operand:DF 0 "general_operand" "=x,y")
3231: (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
3232: "TARGET_FPA"
3233: "fpabs%.d %y1,%0")
3234:
3235: (define_insn ""
3236: [(set (match_operand:DF 0 "general_operand" "=f")
3237: (abs:DF (match_operand:DF 1 "general_operand" "fmF")))]
3238: "TARGET_68881"
3239: "*
3240: {
3241: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
3242: return \"f%&abs%.x %1,%0\";
3243: return \"f%&abs%.d %f1,%0\";
3244: }")
3245:
3246: ;; one complement instructions
3247:
3248: (define_insn "one_cmplsi2"
3249: [(set (match_operand:SI 0 "general_operand" "=dm")
3250: (not:SI (match_operand:SI 1 "general_operand" "0")))]
3251: ""
3252: "not%.l %0")
3253:
3254: (define_insn "one_cmplhi2"
3255: [(set (match_operand:HI 0 "general_operand" "=dm")
3256: (not:HI (match_operand:HI 1 "general_operand" "0")))]
3257: ""
3258: "not%.w %0")
3259:
1.1.1.2 root 3260: (define_insn ""
3261: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
3262: (not:HI (match_dup 0)))]
3263: ""
3264: "not%.w %0")
3265:
1.1 root 3266: (define_insn "one_cmplqi2"
3267: [(set (match_operand:QI 0 "general_operand" "=dm")
3268: (not:QI (match_operand:QI 1 "general_operand" "0")))]
3269: ""
3270: "not%.b %0")
1.1.1.2 root 3271:
3272: (define_insn ""
3273: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
3274: (not:QI (match_dup 0)))]
3275: ""
3276: "not%.b %0")
1.1 root 3277:
3278: ;; arithmetic shift instructions
3279: ;; We don't need the shift memory by 1 bit instruction
3280:
1.1.1.2 root 3281: ;; On all 68k models, this makes faster code in a special case.
3282:
3283: (define_insn ""
3284: [(set (match_operand:SI 0 "register_operand" "=d")
3285: (ashift:SI (match_operand:SI 1 "register_operand" "0")
3286: (match_operand:SI 2 "immediate_operand" "i")))]
3287: "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)"
3288: "*
3289: {
3290: CC_STATUS_INIT;
3291: return \"swap %0\;clr%.w %0\";
3292: }")
3293:
1.1 root 3294: ;; On the 68000, this makes faster code in a special case.
3295:
3296: (define_insn ""
3297: [(set (match_operand:SI 0 "register_operand" "=d")
3298: (ashift:SI (match_operand:SI 1 "register_operand" "0")
3299: (match_operand:SI 2 "immediate_operand" "i")))]
3300: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT
1.1.1.2 root 3301: && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
1.1 root 3302: "*
3303: {
3304: CC_STATUS_INIT;
3305:
3306: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
1.1.1.2 root 3307: return \"asl%.w %2,%0\;swap %0\;clr%.w %0\";
1.1 root 3308: }")
3309:
3310: (define_insn "ashlsi3"
3311: [(set (match_operand:SI 0 "register_operand" "=d")
3312: (ashift:SI (match_operand:SI 1 "register_operand" "0")
3313: (match_operand:SI 2 "general_operand" "dI")))]
3314: ""
3315: "*
3316: {
3317: if (operands[2] == const1_rtx)
3318: return \"add%.l %0,%0\";
3319: return \"asl%.l %2,%0\";
3320: }")
3321:
3322: (define_insn "ashlhi3"
3323: [(set (match_operand:HI 0 "register_operand" "=d")
3324: (ashift:HI (match_operand:HI 1 "register_operand" "0")
3325: (match_operand:HI 2 "general_operand" "dI")))]
3326: ""
3327: "asl%.w %2,%0")
3328:
1.1.1.2 root 3329: (define_insn ""
3330: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
3331: (ashift:HI (match_dup 0)
3332: (match_operand:HI 1 "general_operand" "dI")))]
3333: ""
3334: "asl%.w %1,%0")
3335:
1.1 root 3336: (define_insn "ashlqi3"
3337: [(set (match_operand:QI 0 "register_operand" "=d")
3338: (ashift:QI (match_operand:QI 1 "register_operand" "0")
3339: (match_operand:QI 2 "general_operand" "dI")))]
3340: ""
3341: "asl%.b %2,%0")
3342:
1.1.1.2 root 3343: (define_insn ""
3344: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
3345: (ashift:QI (match_dup 0)
3346: (match_operand:QI 1 "general_operand" "dI")))]
3347: ""
3348: "asl%.b %1,%0")
3349:
3350: ;; On all 68k models, this makes faster code in a special case.
3351:
3352: (define_insn ""
3353: [(set (match_operand:SI 0 "register_operand" "=d")
3354: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
3355: (match_operand:SI 2 "immediate_operand" "i")))]
3356: "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)"
3357: "swap %0\;ext%.l %0")
3358:
1.1 root 3359: ;; On the 68000, this makes faster code in a special case.
3360:
3361: (define_insn ""
3362: [(set (match_operand:SI 0 "register_operand" "=d")
3363: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
3364: (match_operand:SI 2 "immediate_operand" "i")))]
3365: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT
1.1.1.2 root 3366: && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
1.1 root 3367: "*
3368: {
3369: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
3370: return \"swap %0\;asr%.w %2,%0\;ext%.l %0\";
3371: }")
3372:
3373: (define_insn "ashrsi3"
3374: [(set (match_operand:SI 0 "register_operand" "=d")
3375: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
3376: (match_operand:SI 2 "general_operand" "dI")))]
3377: ""
3378: "*
3379: {
3380: return \"asr%.l %2,%0\";
3381: }")
3382:
3383: (define_insn "ashrhi3"
3384: [(set (match_operand:HI 0 "register_operand" "=d")
3385: (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
3386: (match_operand:HI 2 "general_operand" "dI")))]
3387: ""
3388: "asr%.w %2,%0")
3389:
1.1.1.2 root 3390: (define_insn ""
3391: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
3392: (ashiftrt:HI (match_dup 0)
3393: (match_operand:HI 1 "general_operand" "dI")))]
3394: ""
3395: "asr%.w %1,%0")
3396:
1.1 root 3397: (define_insn "ashrqi3"
3398: [(set (match_operand:QI 0 "register_operand" "=d")
3399: (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
3400: (match_operand:QI 2 "general_operand" "dI")))]
3401: ""
3402: "asr%.b %2,%0")
1.1.1.2 root 3403:
3404: (define_insn ""
3405: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
3406: (ashiftrt:QI (match_dup 0)
3407: (match_operand:QI 1 "general_operand" "dI")))]
3408: ""
3409: "asr%.b %1,%0")
1.1 root 3410:
3411: ;; logical shift instructions
3412:
1.1.1.2 root 3413: ;; On all 68k models, this makes faster code in a special case.
3414:
3415: (define_insn ""
3416: [(set (match_operand:SI 0 "register_operand" "=d")
3417: (lshift:SI (match_operand:SI 1 "register_operand" "0")
3418: (match_operand:SI 2 "immediate_operand" "i")))]
3419: "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)"
3420: "*
3421: {
3422: CC_STATUS_INIT;
3423: return \"swap %0\;clr%.w %0\";
3424: }")
3425:
1.1 root 3426: ;; On the 68000, this makes faster code in a special case.
3427:
3428: (define_insn ""
3429: [(set (match_operand:SI 0 "register_operand" "=d")
3430: (lshift:SI (match_operand:SI 1 "register_operand" "0")
3431: (match_operand:SI 2 "immediate_operand" "i")))]
3432: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT
1.1.1.2 root 3433: && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
1.1 root 3434: "*
3435: {
3436: CC_STATUS_INIT;
3437:
3438: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
1.1.1.2 root 3439: return \"lsl%.w %2,%0\;swap %0\;clr%.w %0\";
1.1 root 3440: }")
3441:
3442: (define_insn "lshlsi3"
3443: [(set (match_operand:SI 0 "register_operand" "=d")
3444: (lshift:SI (match_operand:SI 1 "register_operand" "0")
3445: (match_operand:SI 2 "general_operand" "dI")))]
3446: ""
3447: "*
3448: {
3449: if (operands[2] == const1_rtx)
3450: return \"add%.l %0,%0\";
3451: return \"lsl%.l %2,%0\";
3452: }")
3453:
3454: (define_insn "lshlhi3"
3455: [(set (match_operand:HI 0 "register_operand" "=d")
3456: (lshift:HI (match_operand:HI 1 "register_operand" "0")
3457: (match_operand:HI 2 "general_operand" "dI")))]
3458: ""
3459: "lsl%.w %2,%0")
3460:
1.1.1.2 root 3461: (define_insn ""
3462: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
3463: (lshift:HI (match_dup 0)
3464: (match_operand:HI 1 "general_operand" "dI")))]
3465: ""
3466: "lsl%.w %1,%0")
3467:
1.1 root 3468: (define_insn "lshlqi3"
3469: [(set (match_operand:QI 0 "register_operand" "=d")
3470: (lshift:QI (match_operand:QI 1 "register_operand" "0")
3471: (match_operand:QI 2 "general_operand" "dI")))]
3472: ""
3473: "lsl%.b %2,%0")
3474:
1.1.1.2 root 3475: (define_insn ""
3476: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
3477: (lshift:QI (match_dup 0)
3478: (match_operand:QI 1 "general_operand" "dI")))]
3479: ""
3480: "lsl%.b %1,%0")
3481:
3482: ;; On all 68k models, this makes faster code in a special case.
3483:
3484: (define_insn ""
3485: [(set (match_operand:SI 0 "register_operand" "=d")
3486: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3487: (match_operand:SI 2 "immediate_operand" "i")))]
3488: "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)"
3489: "*
3490: {
3491: CC_STATUS_INIT;
3492: return \"clr%.w %0\;swap %0\";
3493: }")
3494:
1.1 root 3495: ;; On the 68000, this makes faster code in a special case.
3496:
3497: (define_insn ""
3498: [(set (match_operand:SI 0 "register_operand" "=d")
3499: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3500: (match_operand:SI 2 "immediate_operand" "i")))]
3501: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT
1.1.1.2 root 3502: && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
1.1 root 3503: "*
3504: {
3505: /* I think lsr%.w sets the CC properly. */
3506: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
1.1.1.2 root 3507: return \"clr%.w %0\;swap %0\;lsr%.w %2,%0\";
1.1 root 3508: }")
3509:
3510: (define_insn "lshrsi3"
3511: [(set (match_operand:SI 0 "register_operand" "=d")
3512: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3513: (match_operand:SI 2 "general_operand" "dI")))]
3514: ""
3515: "*
3516: {
3517: return \"lsr%.l %2,%0\";
3518: }")
3519:
3520: (define_insn "lshrhi3"
3521: [(set (match_operand:HI 0 "register_operand" "=d")
3522: (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
3523: (match_operand:HI 2 "general_operand" "dI")))]
3524: ""
3525: "lsr%.w %2,%0")
3526:
1.1.1.2 root 3527: (define_insn ""
3528: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
3529: (lshiftrt:HI (match_dup 0)
3530: (match_operand:HI 1 "general_operand" "dI")))]
3531: ""
3532: "lsr%.w %1,%0")
3533:
1.1 root 3534: (define_insn "lshrqi3"
3535: [(set (match_operand:QI 0 "register_operand" "=d")
3536: (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
3537: (match_operand:QI 2 "general_operand" "dI")))]
3538: ""
3539: "lsr%.b %2,%0")
1.1.1.2 root 3540:
3541: (define_insn ""
3542: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
3543: (lshiftrt:QI (match_dup 0)
3544: (match_operand:QI 1 "general_operand" "dI")))]
3545: ""
3546: "lsr%.b %1,%0")
1.1 root 3547:
3548: ;; rotate instructions
3549:
3550: (define_insn "rotlsi3"
3551: [(set (match_operand:SI 0 "register_operand" "=d")
3552: (rotate:SI (match_operand:SI 1 "register_operand" "0")
3553: (match_operand:SI 2 "general_operand" "dI")))]
3554: ""
3555: "rol%.l %2,%0")
3556:
3557: (define_insn "rotlhi3"
3558: [(set (match_operand:HI 0 "register_operand" "=d")
3559: (rotate:HI (match_operand:HI 1 "register_operand" "0")
3560: (match_operand:HI 2 "general_operand" "dI")))]
3561: ""
3562: "rol%.w %2,%0")
3563:
1.1.1.2 root 3564:
3565: (define_insn ""
3566: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
3567: (rotate:HI (match_dup 0)
3568: (match_operand:HI 1 "general_operand" "dI")))]
3569: ""
3570: "rol%.w %1,%0")
3571:
1.1 root 3572: (define_insn "rotlqi3"
3573: [(set (match_operand:QI 0 "register_operand" "=d")
3574: (rotate:QI (match_operand:QI 1 "register_operand" "0")
3575: (match_operand:QI 2 "general_operand" "dI")))]
3576: ""
3577: "rol%.b %2,%0")
3578:
1.1.1.2 root 3579: (define_insn ""
3580: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
3581: (rotate:QI (match_dup 0)
3582: (match_operand:QI 1 "general_operand" "dI")))]
3583: ""
3584: "rol%.b %1,%0")
3585:
1.1 root 3586: (define_insn "rotrsi3"
3587: [(set (match_operand:SI 0 "register_operand" "=d")
3588: (rotatert:SI (match_operand:SI 1 "register_operand" "0")
3589: (match_operand:SI 2 "general_operand" "dI")))]
3590: ""
3591: "ror%.l %2,%0")
3592:
3593: (define_insn "rotrhi3"
3594: [(set (match_operand:HI 0 "register_operand" "=d")
3595: (rotatert:HI (match_operand:HI 1 "register_operand" "0")
3596: (match_operand:HI 2 "general_operand" "dI")))]
3597: ""
3598: "ror%.w %2,%0")
3599:
1.1.1.2 root 3600: (define_insn ""
3601: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
3602: (rotatert:HI (match_dup 0)
3603: (match_operand:HI 1 "general_operand" "dI")))]
3604: ""
3605: "ror%.w %1,%0")
3606:
1.1 root 3607: (define_insn "rotrqi3"
3608: [(set (match_operand:QI 0 "register_operand" "=d")
3609: (rotatert:QI (match_operand:QI 1 "register_operand" "0")
3610: (match_operand:QI 2 "general_operand" "dI")))]
3611: ""
3612: "ror%.b %2,%0")
1.1.1.2 root 3613:
3614: (define_insn ""
3615: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
3616: (rotatert:QI (match_dup 0)
3617: (match_operand:QI 1 "general_operand" "dI")))]
3618: ""
3619: "ror%.b %1,%0")
1.1 root 3620:
3621: ;; Special cases of bit-field insns which we should
3622: ;; recognize in preference to the general case.
3623: ;; These handle aligned 8-bit and 16-bit fields,
3624: ;; which can usually be done with move instructions.
3625:
3626: ;
3627: ; Special case for 32-bit field in memory. This only occurs when 32-bit
3628: ; alignment of structure members is specified.
3629: ;
3630: ; The move is allowed to be odd byte aligned, because that's still faster
3631: ; than an odd byte aligned bit field instruction.
3632: ;
3633: (define_insn ""
1.1.1.4 ! root 3634: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o")
1.1 root 3635: (match_operand:SI 1 "immediate_operand" "i")
3636: (match_operand:SI 2 "immediate_operand" "i"))
3637: (match_operand:SI 3 "general_operand" "rmi"))]
3638: "TARGET_68020 && TARGET_BITFIELD
3639: && GET_CODE (operands[1]) == CONST_INT
3640: && (INTVAL (operands[1]) == 32)
3641: && GET_CODE (operands[2]) == CONST_INT
3642: && (INTVAL (operands[2]) % 8) == 0
3643: && ! mode_dependent_address_p (XEXP (operands[0], 0))"
3644: "*
3645: {
3646: operands[0]
3647: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
3648:
3649: return \"move%.l %3,%0\";
3650: }")
3651:
3652: (define_insn ""
3653: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do")
3654: (match_operand:SI 1 "immediate_operand" "i")
3655: (match_operand:SI 2 "immediate_operand" "i"))
3656: (match_operand:SI 3 "general_operand" "d"))]
3657: "TARGET_68020 && TARGET_BITFIELD
3658: && GET_CODE (operands[1]) == CONST_INT
3659: && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
3660: && GET_CODE (operands[2]) == CONST_INT
3661: && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
3662: && (GET_CODE (operands[0]) == REG
3663: || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
3664: "*
3665: {
3666: if (REG_P (operands[0]))
3667: {
3668: if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
3669: return \"bfins %3,%0{%b2:%b1}\";
3670: }
3671: else
3672: operands[0]
3673: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
3674:
3675: if (GET_CODE (operands[3]) == MEM)
3676: operands[3] = adj_offsettable_operand (operands[3],
3677: (32 - INTVAL (operands[1])) / 8);
3678: if (INTVAL (operands[1]) == 8)
3679: return \"move%.b %3,%0\";
3680: return \"move%.w %3,%0\";
3681: }")
3682:
3683:
3684: ;
3685: ; Special case for 32-bit field in memory. This only occurs when 32-bit
3686: ; alignment of structure members is specified.
3687: ;
3688: ; The move is allowed to be odd byte aligned, because that's still faster
3689: ; than an odd byte aligned bit field instruction.
3690: ;
3691: (define_insn ""
3692: [(set (match_operand:SI 0 "general_operand" "=rm")
3693: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o")
3694: (match_operand:SI 2 "immediate_operand" "i")
3695: (match_operand:SI 3 "immediate_operand" "i")))]
3696: "TARGET_68020 && TARGET_BITFIELD
3697: && GET_CODE (operands[2]) == CONST_INT
3698: && (INTVAL (operands[2]) == 32)
3699: && GET_CODE (operands[3]) == CONST_INT
3700: && (INTVAL (operands[3]) % 8) == 0
3701: && ! mode_dependent_address_p (XEXP (operands[1], 0))"
3702: "*
3703: {
3704: operands[1]
3705: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
3706:
3707: return \"move%.l %1,%0\";
3708: }")
3709:
3710: (define_insn ""
3711: [(set (match_operand:SI 0 "general_operand" "=&d")
3712: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
3713: (match_operand:SI 2 "immediate_operand" "i")
3714: (match_operand:SI 3 "immediate_operand" "i")))]
3715: "TARGET_68020 && TARGET_BITFIELD
3716: && GET_CODE (operands[2]) == CONST_INT
3717: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3718: && GET_CODE (operands[3]) == CONST_INT
3719: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
3720: && (GET_CODE (operands[1]) == REG
3721: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
3722: "*
3723: {
3724: cc_status.flags |= CC_NOT_NEGATIVE;
3725: if (REG_P (operands[1]))
3726: {
3727: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
3728: return \"bfextu %1{%b3:%b2},%0\";
3729: }
3730: else
3731: operands[1]
3732: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
3733:
3734: output_asm_insn (\"clr%.l %0\", operands);
3735: if (GET_CODE (operands[0]) == MEM)
3736: operands[0] = adj_offsettable_operand (operands[0],
3737: (32 - INTVAL (operands[1])) / 8);
3738: if (INTVAL (operands[2]) == 8)
3739: return \"move%.b %1,%0\";
3740: return \"move%.w %1,%0\";
3741: }")
3742:
3743: ;
3744: ; Special case for 32-bit field in memory. This only occurs when 32-bit
3745: ; alignment of structure members is specified.
3746: ;
3747: ; The move is allowed to be odd byte aligned, because that's still faster
3748: ; than an odd byte aligned bit field instruction.
3749: ;
3750: (define_insn ""
3751: [(set (match_operand:SI 0 "general_operand" "=rm")
3752: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o")
3753: (match_operand:SI 2 "immediate_operand" "i")
3754: (match_operand:SI 3 "immediate_operand" "i")))]
3755: "TARGET_68020 && TARGET_BITFIELD
3756: && GET_CODE (operands[2]) == CONST_INT
3757: && (INTVAL (operands[2]) == 32)
3758: && GET_CODE (operands[3]) == CONST_INT
3759: && (INTVAL (operands[3]) % 8) == 0
3760: && ! mode_dependent_address_p (XEXP (operands[1], 0))"
3761: "*
3762: {
3763: operands[1]
3764: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
3765:
3766: return \"move%.l %1,%0\";
3767: }")
3768:
3769: (define_insn ""
3770: [(set (match_operand:SI 0 "general_operand" "=d")
3771: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
3772: (match_operand:SI 2 "immediate_operand" "i")
3773: (match_operand:SI 3 "immediate_operand" "i")))]
3774: "TARGET_68020 && TARGET_BITFIELD
3775: && GET_CODE (operands[2]) == CONST_INT
3776: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3777: && GET_CODE (operands[3]) == CONST_INT
3778: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
3779: && (GET_CODE (operands[1]) == REG
3780: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
3781: "*
3782: {
3783: if (REG_P (operands[1]))
3784: {
3785: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
3786: return \"bfexts %1{%b3:%b2},%0\";
3787: }
3788: else
3789: operands[1]
3790: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
3791:
3792: if (INTVAL (operands[2]) == 8)
3793: return \"move%.b %1,%0\;extb%.l %0\";
3794: return \"move%.w %1,%0\;ext%.l %0\";
3795: }")
3796:
3797: ;; Bit field instructions, general cases.
3798: ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
3799: ;; so that its address is reloaded.
3800:
3801: (define_insn "extv"
3802: [(set (match_operand:SI 0 "general_operand" "=d,d")
3803: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
3804: (match_operand:SI 2 "general_operand" "di,di")
3805: (match_operand:SI 3 "general_operand" "di,di")))]
3806: "TARGET_68020 && TARGET_BITFIELD"
3807: "bfexts %1{%b3:%b2},%0")
3808:
3809: (define_insn "extzv"
3810: [(set (match_operand:SI 0 "general_operand" "=d,d")
3811: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
3812: (match_operand:SI 2 "general_operand" "di,di")
3813: (match_operand:SI 3 "general_operand" "di,di")))]
3814: "TARGET_68020 && TARGET_BITFIELD"
3815: "*
3816: {
3817: cc_status.flags |= CC_NOT_NEGATIVE;
3818: return \"bfextu %1{%b3:%b2},%0\";
3819: }")
3820:
3821: (define_insn ""
3822: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
3823: (match_operand:SI 1 "general_operand" "di,di")
3824: (match_operand:SI 2 "general_operand" "di,di"))
3825: (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
3826: (match_operand 3 "immediate_operand" "i,i")))]
3827: "TARGET_68020 && TARGET_BITFIELD
3828: && GET_CODE (operands[3]) == CONST_INT
3829: && (INTVAL (operands[3]) == -1
3830: || (GET_CODE (operands[1]) == CONST_INT
3831: && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
3832: "*
3833: {
3834: CC_STATUS_INIT;
3835: return \"bfchg %0{%b2:%b1}\";
3836: }")
3837:
3838: (define_insn ""
3839: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
3840: (match_operand:SI 1 "general_operand" "di,di")
3841: (match_operand:SI 2 "general_operand" "di,di"))
3842: (const_int 0))]
3843: "TARGET_68020 && TARGET_BITFIELD"
3844: "*
3845: {
3846: CC_STATUS_INIT;
3847: return \"bfclr %0{%b2:%b1}\";
3848: }")
3849:
3850: (define_insn ""
3851: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
3852: (match_operand:SI 1 "general_operand" "di,di")
3853: (match_operand:SI 2 "general_operand" "di,di"))
3854: (const_int -1))]
3855: "TARGET_68020 && TARGET_BITFIELD"
3856: "*
3857: {
3858: CC_STATUS_INIT;
3859: return \"bfset %0{%b2:%b1}\";
3860: }")
3861:
3862: (define_insn "insv"
3863: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
3864: (match_operand:SI 1 "general_operand" "di,di")
3865: (match_operand:SI 2 "general_operand" "di,di"))
3866: (match_operand:SI 3 "general_operand" "d,d"))]
3867: "TARGET_68020 && TARGET_BITFIELD"
3868: "bfins %3,%0{%b2:%b1}")
3869:
3870: ;; Now recognize bit field insns that operate on registers
3871: ;; (or at least were intended to do so).
3872:
3873: (define_insn ""
3874: [(set (match_operand:SI 0 "general_operand" "=d")
3875: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
3876: (match_operand:SI 2 "general_operand" "di")
3877: (match_operand:SI 3 "general_operand" "di")))]
3878: "TARGET_68020 && TARGET_BITFIELD"
3879: "bfexts %1{%b3:%b2},%0")
3880:
3881: (define_insn ""
3882: [(set (match_operand:SI 0 "general_operand" "=d")
3883: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
3884: (match_operand:SI 2 "general_operand" "di")
3885: (match_operand:SI 3 "general_operand" "di")))]
3886: "TARGET_68020 && TARGET_BITFIELD"
3887: "*
3888: {
3889: cc_status.flags |= CC_NOT_NEGATIVE;
3890: return \"bfextu %1{%b3:%b2},%0\";
3891: }")
3892:
3893: (define_insn ""
3894: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
3895: (match_operand:SI 1 "general_operand" "di")
3896: (match_operand:SI 2 "general_operand" "di"))
3897: (const_int 0))]
3898: "TARGET_68020 && TARGET_BITFIELD"
3899: "*
3900: {
3901: CC_STATUS_INIT;
3902: return \"bfclr %0{%b2:%b1}\";
3903: }")
3904:
3905: (define_insn ""
3906: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
3907: (match_operand:SI 1 "general_operand" "di")
3908: (match_operand:SI 2 "general_operand" "di"))
3909: (const_int -1))]
3910: "TARGET_68020 && TARGET_BITFIELD"
3911: "*
3912: {
3913: CC_STATUS_INIT;
3914: return \"bfset %0{%b2:%b1}\";
3915: }")
3916:
3917: (define_insn ""
3918: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
3919: (match_operand:SI 1 "general_operand" "di")
3920: (match_operand:SI 2 "general_operand" "di"))
3921: (match_operand:SI 3 "general_operand" "d"))]
3922: "TARGET_68020 && TARGET_BITFIELD"
3923: "*
3924: {
3925: #if 0
3926: /* These special cases are now recognized by a specific pattern. */
3927: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
3928: && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
3929: return \"move%.w %3,%0\";
3930: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
3931: && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
3932: return \"move%.b %3,%0\";
3933: #endif
3934: return \"bfins %3,%0{%b2:%b1}\";
3935: }")
3936:
3937: ;; Special patterns for optimizing bit-field instructions.
3938:
3939: (define_insn ""
3940: [(set (cc0)
3941: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
3942: (match_operand:SI 1 "general_operand" "di")
3943: (match_operand:SI 2 "general_operand" "di")))]
3944: "TARGET_68020 && TARGET_BITFIELD
3945: && GET_CODE (operands[1]) == CONST_INT"
3946: "*
3947: {
3948: if (operands[1] == const1_rtx
3949: && GET_CODE (operands[2]) == CONST_INT)
3950: {
3951: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3952: return output_btst (operands,
3953: gen_rtx (CONST_INT, VOIDmode,
3954: width - INTVAL (operands[2])),
3955: operands[0],
3956: insn, 1000);
3957: /* Pass 1000 as SIGNPOS argument so that btst will
3958: not think we are testing the sign bit for an `and'
3959: and assume that nonzero implies a negative result. */
3960: }
3961: if (INTVAL (operands[1]) != 32)
3962: cc_status.flags = CC_NOT_NEGATIVE;
3963: return \"bftst %0{%b2:%b1}\";
3964: }")
3965:
3966:
3967: ;;; now handle the register cases
3968: (define_insn ""
3969: [(set (cc0)
3970: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
3971: (match_operand:SI 1 "general_operand" "di")
3972: (match_operand:SI 2 "general_operand" "di")))]
3973: "TARGET_68020 && TARGET_BITFIELD
3974: && GET_CODE (operands[1]) == CONST_INT"
3975: "*
3976: {
3977: if (operands[1] == const1_rtx
3978: && GET_CODE (operands[2]) == CONST_INT)
3979: {
3980: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3981: return output_btst (operands,
3982: gen_rtx (CONST_INT, VOIDmode,
3983: width - INTVAL (operands[2])),
3984: operands[0],
3985: insn, 1000);
3986: /* Pass 1000 as SIGNPOS argument so that btst will
3987: not think we are testing the sign bit for an `and'
3988: and assume that nonzero implies a negative result. */
3989: }
3990: if (INTVAL (operands[1]) != 32)
3991: cc_status.flags = CC_NOT_NEGATIVE;
3992: return \"bftst %0{%b2:%b1}\";
3993: }")
3994:
3995: (define_insn "seq"
3996: [(set (match_operand:QI 0 "general_operand" "=d")
3997: (eq:QI (cc0) (const_int 0)))]
3998: ""
3999: "*
4000: cc_status = cc_prev_status;
4001: OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
4002: ")
4003:
4004: (define_insn "sne"
4005: [(set (match_operand:QI 0 "general_operand" "=d")
4006: (ne:QI (cc0) (const_int 0)))]
4007: ""
4008: "*
4009: cc_status = cc_prev_status;
4010: OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
4011: ")
4012:
4013: (define_insn "sgt"
4014: [(set (match_operand:QI 0 "general_operand" "=d")
4015: (gt:QI (cc0) (const_int 0)))]
4016: ""
4017: "*
4018: cc_status = cc_prev_status;
4019: OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0);
4020: ")
4021:
4022: (define_insn "sgtu"
4023: [(set (match_operand:QI 0 "general_operand" "=d")
4024: (gtu:QI (cc0) (const_int 0)))]
4025: ""
4026: "* cc_status = cc_prev_status;
4027: return \"shi %0\"; ")
4028:
4029: (define_insn "slt"
4030: [(set (match_operand:QI 0 "general_operand" "=d")
4031: (lt:QI (cc0) (const_int 0)))]
4032: ""
4033: "* cc_status = cc_prev_status;
4034: OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
4035:
4036: (define_insn "sltu"
4037: [(set (match_operand:QI 0 "general_operand" "=d")
4038: (ltu:QI (cc0) (const_int 0)))]
4039: ""
4040: "* cc_status = cc_prev_status;
4041: return \"scs %0\"; ")
4042:
4043: (define_insn "sge"
4044: [(set (match_operand:QI 0 "general_operand" "=d")
4045: (ge:QI (cc0) (const_int 0)))]
4046: ""
4047: "* cc_status = cc_prev_status;
4048: OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
4049:
4050: (define_insn "sgeu"
4051: [(set (match_operand:QI 0 "general_operand" "=d")
4052: (geu:QI (cc0) (const_int 0)))]
4053: ""
4054: "* cc_status = cc_prev_status;
4055: return \"scc %0\"; ")
4056:
4057: (define_insn "sle"
4058: [(set (match_operand:QI 0 "general_operand" "=d")
4059: (le:QI (cc0) (const_int 0)))]
4060: ""
4061: "*
4062: cc_status = cc_prev_status;
4063: OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0);
4064: ")
4065:
4066: (define_insn "sleu"
4067: [(set (match_operand:QI 0 "general_operand" "=d")
4068: (leu:QI (cc0) (const_int 0)))]
4069: ""
4070: "* cc_status = cc_prev_status;
4071: return \"sls %0\"; ")
4072:
4073: ;; Basic conditional jump instructions.
4074:
4075: (define_insn "beq"
4076: [(set (pc)
4077: (if_then_else (eq (cc0)
4078: (const_int 0))
4079: (label_ref (match_operand 0 "" ""))
4080: (pc)))]
4081: ""
4082: "*
4083: {
4084: #ifdef MOTOROLA
4085: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
4086: #else
4087: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
4088: #endif
4089: }")
4090:
4091: (define_insn "bne"
4092: [(set (pc)
4093: (if_then_else (ne (cc0)
4094: (const_int 0))
4095: (label_ref (match_operand 0 "" ""))
4096: (pc)))]
4097: ""
4098: "*
4099: {
4100: #ifdef MOTOROLA
4101: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
4102: #else
4103: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
4104: #endif
4105: }")
4106:
4107: (define_insn "bgt"
4108: [(set (pc)
4109: (if_then_else (gt (cc0)
4110: (const_int 0))
4111: (label_ref (match_operand 0 "" ""))
4112: (pc)))]
4113: ""
4114: "*
4115: #ifdef MOTOROLA
4116: OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0);
4117: #else
4118: OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0);
4119: #endif
4120: ")
4121:
4122: (define_insn "bgtu"
4123: [(set (pc)
4124: (if_then_else (gtu (cc0)
4125: (const_int 0))
4126: (label_ref (match_operand 0 "" ""))
4127: (pc)))]
4128: ""
4129: "*
4130: #ifdef MOTOROLA
4131: return \"jbhi %l0\";
4132: #else
4133: return \"jhi %l0\";
4134: #endif
4135: ")
4136:
4137: (define_insn "blt"
4138: [(set (pc)
4139: (if_then_else (lt (cc0)
4140: (const_int 0))
4141: (label_ref (match_operand 0 "" ""))
4142: (pc)))]
4143: ""
4144: "*
4145: #ifdef MOTOROLA
4146: OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\");
4147: #else
4148: OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\");
4149: #endif
4150: ")
4151:
4152: (define_insn "bltu"
4153: [(set (pc)
4154: (if_then_else (ltu (cc0)
4155: (const_int 0))
4156: (label_ref (match_operand 0 "" ""))
4157: (pc)))]
4158: ""
4159: "*
4160: #ifdef MOTOROLA
4161: return \"jbcs %l0\";
4162: #else
4163: return \"jcs %l0\";
4164: #endif
4165: ")
4166:
4167: (define_insn "bge"
4168: [(set (pc)
4169: (if_then_else (ge (cc0)
4170: (const_int 0))
4171: (label_ref (match_operand 0 "" ""))
4172: (pc)))]
4173: ""
4174: "*
4175: #ifdef MOTOROLA
4176: OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\");
4177: #else
4178: OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\");
4179: #endif
4180: ")
4181:
4182: (define_insn "bgeu"
4183: [(set (pc)
4184: (if_then_else (geu (cc0)
4185: (const_int 0))
4186: (label_ref (match_operand 0 "" ""))
4187: (pc)))]
4188: ""
4189: "*
4190: #ifdef MOTOROLA
4191: return \"jbcc %l0\";
4192: #else
4193: return \"jcc %l0\";
4194: #endif
4195: ")
4196:
4197: (define_insn "ble"
4198: [(set (pc)
4199: (if_then_else (le (cc0)
4200: (const_int 0))
4201: (label_ref (match_operand 0 "" ""))
4202: (pc)))]
4203: ""
4204: "*
4205: #ifdef MOTOROLA
4206: OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0);
4207: #else
4208: OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0);
4209: #endif
4210: ")
4211:
4212: (define_insn "bleu"
4213: [(set (pc)
4214: (if_then_else (leu (cc0)
4215: (const_int 0))
4216: (label_ref (match_operand 0 "" ""))
4217: (pc)))]
4218: ""
4219: "*
4220: #ifdef MOTOROLA
4221: return \"jbls %l0\";
4222: #else
4223: return \"jls %l0\";
4224: #endif
4225: ")
4226:
4227: ;; Negated conditional jump instructions.
4228:
4229: (define_insn ""
4230: [(set (pc)
4231: (if_then_else (eq (cc0)
4232: (const_int 0))
4233: (pc)
4234: (label_ref (match_operand 0 "" ""))))]
4235: ""
4236: "*
4237: {
4238: #ifdef MOTOROLA
4239: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
4240: #else
4241: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
4242: #endif
4243: }")
4244:
4245: (define_insn ""
4246: [(set (pc)
4247: (if_then_else (ne (cc0)
4248: (const_int 0))
4249: (pc)
4250: (label_ref (match_operand 0 "" ""))))]
4251: ""
4252: "*
4253: {
4254: #ifdef MOTOROLA
4255: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
4256: #else
4257: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
4258: #endif
4259: }")
4260:
4261: (define_insn ""
4262: [(set (pc)
4263: (if_then_else (gt (cc0)
4264: (const_int 0))
4265: (pc)
4266: (label_ref (match_operand 0 "" ""))))]
4267: ""
4268: "*
4269: #ifdef MOTOROLA
4270: OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0);
4271: #else
4272: OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0);
4273: #endif
4274: ")
4275:
4276: (define_insn ""
4277: [(set (pc)
4278: (if_then_else (gtu (cc0)
4279: (const_int 0))
4280: (pc)
4281: (label_ref (match_operand 0 "" ""))))]
4282: ""
4283: "*
4284: #ifdef MOTOROLA
4285: return \"jbls %l0\";
4286: #else
4287: return \"jls %l0\";
4288: #endif
4289: ")
4290:
4291: (define_insn ""
4292: [(set (pc)
4293: (if_then_else (lt (cc0)
4294: (const_int 0))
4295: (pc)
4296: (label_ref (match_operand 0 "" ""))))]
4297: ""
4298: "*
4299: #ifdef MOTOROLA
4300: OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\");
4301: #else
4302: OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\");
4303: #endif
4304: ")
4305:
4306: (define_insn ""
4307: [(set (pc)
4308: (if_then_else (ltu (cc0)
4309: (const_int 0))
4310: (pc)
4311: (label_ref (match_operand 0 "" ""))))]
4312: ""
4313: "*
4314: #ifdef MOTOROLA
4315: return \"jbcc %l0\";
4316: #else
4317: return \"jcc %l0\";
4318: #endif
4319: ")
4320:
4321: (define_insn ""
4322: [(set (pc)
4323: (if_then_else (ge (cc0)
4324: (const_int 0))
4325: (pc)
4326: (label_ref (match_operand 0 "" ""))))]
4327: ""
4328: "*
4329: #ifdef MOTOROLA
4330: OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\");
4331: #else
4332: OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\");
4333: #endif
4334: ")
4335:
4336: (define_insn ""
4337: [(set (pc)
4338: (if_then_else (geu (cc0)
4339: (const_int 0))
4340: (pc)
4341: (label_ref (match_operand 0 "" ""))))]
4342: ""
4343: "*
4344: #ifdef MOTOROLA
4345: return \"jbcs %l0\";
4346: #else
4347: return \"jcs %l0\";
4348: #endif
4349: ")
4350:
4351: (define_insn ""
4352: [(set (pc)
4353: (if_then_else (le (cc0)
4354: (const_int 0))
4355: (pc)
4356: (label_ref (match_operand 0 "" ""))))]
4357: ""
4358: "*
4359: #ifdef MOTOROLA
4360: OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0);
4361: #else
4362: OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0);
4363: #endif
4364: ")
4365:
4366: (define_insn ""
4367: [(set (pc)
4368: (if_then_else (leu (cc0)
4369: (const_int 0))
4370: (pc)
4371: (label_ref (match_operand 0 "" ""))))]
4372: ""
4373: "*
4374: #ifdef MOTOROLA
4375: return \"jbhi %l0\";
4376: #else
4377: return \"jhi %l0\";
4378: #endif
4379: ")
4380:
4381: ;; Unconditional and other jump instructions
4382: (define_insn "jump"
4383: [(set (pc)
4384: (label_ref (match_operand 0 "" "")))]
4385: ""
4386: "*
4387: #ifdef MOTOROLA
4388: return \"jbra %l0\";
4389: #else
4390: return \"jra %l0\";
4391: #endif
4392: ")
4393:
4394: ;; We support two different ways of handling dispatch tables.
4395: ;; The NeXT uses absolute tables, and other machines use relative.
4396: ;; This define_expand can generate either kind.
4397: (define_expand "tablejump"
4398: [(parallel [(set (pc) (match_operand 0 "" ""))
4399: (use (label_ref (match_operand 1 "" "")))])]
4400: ""
4401: "
4402: {
4403: #ifdef CASE_VECTOR_PC_RELATIVE
4404: operands[0] = gen_rtx (PLUS, SImode, pc_rtx, operands[0]);
4405: #endif
4406: }")
4407:
4408: ;; Jump to variable address from dispatch table of absolute addresses.
4409: (define_insn ""
4410: [(set (pc) (match_operand:SI 0 "register_operand" "a"))
4411: (use (label_ref (match_operand 1 "" "")))]
4412: ""
4413: "*
4414: #ifdef MOTOROLA
4415: return \"jmp (%0)\";
4416: #else
4417: return \"jmp %0@\";
4418: #endif
4419: ")
4420:
4421: ;; Jump to variable address from dispatch table of relative addresses.
4422: (define_insn ""
4423: [(set (pc)
4424: (plus:SI (pc) (match_operand:HI 0 "register_operand" "r")))
4425: (use (label_ref (match_operand 1 "" "")))]
4426: ""
4427: "*
4428: #ifdef ASM_RETURN_CASE_JUMP
4429: ASM_RETURN_CASE_JUMP;
4430: #else
4431: #ifdef SGS
4432: #ifdef ASM_OUTPUT_CASE_LABEL
4433: return \"jmp 6(%%pc,%0.w)\";
4434: #else
4435: #ifdef CRDS
4436: return \"jmp 2(pc,%0.w)\";
4437: #else
4438: return \"jmp 2(%%pc,%0.w)\";
4439: #endif /* end !CRDS */
4440: #endif
4441: #else /* not SGS */
4442: #ifdef MOTOROLA
4443: return \"jmp (2,pc,%0.w)\";
4444: #else
4445: return \"jmp pc@(2,%0:w)\";
4446: #endif
4447: #endif
4448: #endif
4449: ")
4450:
4451: ;; Decrement-and-branch insns.
4452: (define_insn ""
4453: [(set (pc)
4454: (if_then_else
4455: (ne (match_operand:HI 0 "general_operand" "+g")
4456: (const_int 0))
4457: (label_ref (match_operand 1 "" ""))
4458: (pc)))
4459: (set (match_dup 0)
4460: (plus:HI (match_dup 0)
4461: (const_int -1)))]
4462: ""
4463: "*
4464: {
4465: CC_STATUS_INIT;
4466: if (DATA_REG_P (operands[0]))
4467: return \"dbra %0,%l1\";
4468: if (GET_CODE (operands[0]) == MEM)
4469: {
4470: #ifdef MOTOROLA
4471: #ifdef NO_ADDSUB_Q
4472: return \"sub%.w %#1,%0\;jbcc %l1\";
4473: #else
4474: return \"subq%.w %#1,%0\;jbcc %l1\";
4475: #endif
4476: #else /* not MOTOROLA */
4477: return \"subqw %#1,%0\;jcc %l1\";
4478: #endif
4479: }
4480: #ifdef MOTOROLA
4481: #ifdef SGS_CMP_ORDER
1.1.1.2 root 4482: #ifdef NO_ADDSUB_Q
1.1 root 4483: return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
4484: #else
4485: return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
4486: #endif
4487: #else /* not SGS_CMP_ORDER */
4488: return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\";
4489: #endif
4490: #else /* not MOTOROLA */
4491: return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
4492: #endif
4493: }")
4494:
4495: (define_insn ""
4496: [(set (pc)
4497: (if_then_else
4498: (ne (match_operand:SI 0 "general_operand" "+g")
4499: (const_int 0))
4500: (label_ref (match_operand 1 "" ""))
4501: (pc)))
4502: (set (match_dup 0)
4503: (plus:SI (match_dup 0)
4504: (const_int -1)))]
4505: ""
4506: "*
4507: {
4508: CC_STATUS_INIT;
4509: #ifdef MOTOROLA
1.1.1.2 root 4510: #ifdef NO_ADDSUB_Q
1.1 root 4511: if (DATA_REG_P (operands[0]))
4512: return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\";
4513: if (GET_CODE (operands[0]) == MEM)
4514: return \"sub%.l %#1,%0\;jbcc %l1\";
4515: #else
4516: if (DATA_REG_P (operands[0]))
4517: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\";
4518: if (GET_CODE (operands[0]) == MEM)
4519: return \"subq%.l %#1,%0\;jbcc %l1\";
1.1.1.2 root 4520: #endif /* NO_ADDSUB_Q */
1.1 root 4521: #ifdef SGS_CMP_ORDER
1.1.1.2 root 4522: #ifdef NO_ADDSUB_Q
1.1 root 4523: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
4524: #else
4525: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
4526: #endif
4527: #else /* not SGS_CMP_ORDER */
4528: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
4529: #endif /* not SGS_CMP_ORDER */
4530: #else /* not MOTOROLA */
4531: if (DATA_REG_P (operands[0]))
1.1.1.2 root 4532: return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\";
1.1 root 4533: if (GET_CODE (operands[0]) == MEM)
4534: return \"subql %#1,%0\;jcc %l1\";
4535: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
4536: #endif /* not MOTOROLA */
4537: }")
4538:
1.1.1.2 root 4539: ;; Two dbra patterns that use REG_NOTES info generated by strength_reduce.
4540:
4541: (define_insn ""
4542: [(set (pc)
4543: (if_then_else
4544: (ge (plus:HI (match_operand:HI 0 "general_operand" "+g")
4545: (const_int -1))
4546: (const_int 0))
4547: (label_ref (match_operand 1 "" ""))
4548: (pc)))
4549: (set (match_dup 0)
4550: (plus:HI (match_dup 0)
4551: (const_int -1)))]
4552: "find_reg_note (insn, REG_NONNEG, 0)"
4553: "*
4554: {
4555: CC_STATUS_INIT;
4556: #ifdef MOTOROLA
4557: #ifdef NO_ADDSUB_Q
4558: if (DATA_REG_P (operands[0]))
4559: return \"dbra %0,%l1\";
4560: if (GET_CODE (operands[0]) == MEM)
4561: return \"sub%.w %#1,%0\;jbcc %l1\";
4562: #else
4563: if (DATA_REG_P (operands[0]))
4564: return \"dbra %0,%l1\";
4565: if (GET_CODE (operands[0]) == MEM)
4566: return \"subq%.w %#1,%0\;jbcc %l1\";
4567: #endif
4568: #ifdef SGS_CMP_ORDER
4569: #ifdef NO_ADDSUB_Q
4570: return \"sub.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\";
4571: #else
4572: return \"subq.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\";
4573: #endif
4574: #else /* not SGS_CMP_ORDER */
4575: return \"subq.w %#1,%0\;cmp.w %#-1,%0\;jbne %l1\";
4576: #endif /* not SGS_CMP_ORDER */
4577: #else /* not MOTOROLA */
4578: if (DATA_REG_P (operands[0]))
4579: return \"dbra %0,%l1\";
4580: if (GET_CODE (operands[0]) == MEM)
4581: return \"subqw %#1,%0\;jcc %l1\";
4582: return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
4583: #endif /* not MOTOROLA */
4584: }")
1.1 root 4585:
4586: (define_insn "decrement_and_branch_until_zero"
4587: [(set (pc)
4588: (if_then_else
1.1.1.2 root 4589: (ge (plus:SI (match_operand:SI 0 "general_operand" "+g")
4590: (const_int -1))
1.1 root 4591: (const_int 0))
4592: (label_ref (match_operand 1 "" ""))
4593: (pc)))
4594: (set (match_dup 0)
4595: (plus:SI (match_dup 0)
4596: (const_int -1)))]
4597: "find_reg_note (insn, REG_NONNEG, 0)"
4598: "*
4599: {
4600: CC_STATUS_INIT;
4601: #ifdef MOTOROLA
1.1.1.2 root 4602: #ifdef NO_ADDSUB_Q
1.1 root 4603: if (DATA_REG_P (operands[0]))
4604: return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\";
4605: if (GET_CODE (operands[0]) == MEM)
4606: return \"sub%.l %#1,%0\;jbcc %l1\";
4607: #else
4608: if (DATA_REG_P (operands[0]))
4609: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\";
4610: if (GET_CODE (operands[0]) == MEM)
4611: return \"subq%.l %#1,%0\;jbcc %l1\";
4612: #endif
4613: #ifdef SGS_CMP_ORDER
1.1.1.2 root 4614: #ifdef NO_ADDSUB_Q
1.1 root 4615: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
4616: #else
4617: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
4618: #endif
4619: #else /* not SGS_CMP_ORDER */
4620: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
4621: #endif /* not SGS_CMP_ORDER */
4622: #else /* not MOTOROLA */
4623: if (DATA_REG_P (operands[0]))
1.1.1.2 root 4624: return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\";
1.1 root 4625: if (GET_CODE (operands[0]) == MEM)
4626: return \"subql %#1,%0\;jcc %l1\";
4627: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
4628: #endif /* not MOTOROLA */
4629: }")
4630:
4631:
4632: ;; PIC calls are handled by loading the address of the function into a
4633: ;; register (via movsi), then emitting a register indirect call using
4634: ;; the "jsr" function call syntax.
4635: ;;
4636: ;; It is important to note that the "jsr" syntax is always used for
4637: ;; PIC calls, even on machines in which GCC normally uses the "jbsr"
4638: ;; syntax for non-PIC calls. This keeps at least 1 assembler (Sun)
4639: ;; from emitting incorrect code for a PIC call.
4640: ;;
4641: ;; We have different patterns for PIC calls and non-PIC calls. The
4642: ;; different patterns are only used to choose the right syntax
4643: ;; ("jsr" vs "jbsr").
4644:
4645: ;; Call subroutine with no return value.
4646: (define_expand "call"
4647: [(call (match_operand:QI 0 "memory_operand" "")
4648: (match_operand:SI 1 "general_operand" ""))]
4649: ;; Operand 1 not really used on the m68000.
4650:
4651: ""
4652: "
4653: {
4654: if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
4655: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
4656: force_reg (Pmode, XEXP (operands[0], 0)));
4657: }")
4658:
4659: ;; This is a normal call sequence.
4660: (define_insn ""
4661: [(call (match_operand:QI 0 "memory_operand" "o")
4662: (match_operand:SI 1 "general_operand" "g"))]
4663: ;; Operand 1 not really used on the m68000.
4664:
4665: "! flag_pic"
4666: "*
4667: #ifdef MOTOROLA
4668: return \"jsr %0\";
4669: #else
4670: return \"jbsr %0\";
4671: #endif
4672: ")
4673:
4674: ;; This is a PIC call sequence.
4675: (define_insn ""
4676: [(call (match_operand:QI 0 "memory_operand" "o")
4677: (match_operand:SI 1 "general_operand" "g"))]
4678: ;; Operand 1 not really used on the m68000.
4679:
4680: "flag_pic"
4681: "*
4682: return \"jsr %0\";
4683: ")
4684:
4685: ;; Call subroutine, returning value in operand 0
4686: ;; (which must be a hard register).
4687: ;; See comments before "call" regarding PIC calls.
4688: (define_expand "call_value"
4689: [(set (match_operand 0 "" "")
4690: (call (match_operand:QI 1 "memory_operand" "")
4691: (match_operand:SI 2 "general_operand" "")))]
4692: ;; Operand 2 not really used on the m68000.
4693: ""
4694: "
4695: {
4696: if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
4697: operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
4698: force_reg (Pmode, XEXP (operands[1], 0)));
4699: }")
4700:
4701: ;; This is a normal call_value
4702: (define_insn ""
4703: [(set (match_operand 0 "" "=rf")
4704: (call (match_operand:QI 1 "memory_operand" "o")
4705: (match_operand:SI 2 "general_operand" "g")))]
4706: ;; Operand 2 not really used on the m68000.
4707: "! flag_pic"
4708: "*
4709: #ifdef MOTOROLA
4710: return \"jsr %1\";
4711: #else
4712: return \"jbsr %1\";
4713: #endif
4714: ")
4715:
4716: ;; This is a PIC call_value
4717: (define_insn ""
4718: [(set (match_operand 0 "" "=rf")
4719: (call (match_operand:QI 1 "memory_operand" "o")
4720: (match_operand:SI 2 "general_operand" "g")))]
4721: ;; Operand 2 not really used on the m68000.
4722: "flag_pic"
4723: "*
4724: return \"jsr %1\";
4725: ")
4726:
4727: (define_insn "nop"
4728: [(const_int 0)]
4729: ""
4730: "nop")
4731:
4732: (define_insn "probe"
4733: [(reg:SI 15)]
4734: "NEED_PROBE"
4735: "*
4736: {
4737: operands[0] = gen_rtx (PLUS, SImode, stack_pointer_rtx,
4738: gen_rtx (CONST_INT, VOIDmode, NEED_PROBE));
1.1.1.4 ! root 4739: return \"tstl %a0\";
1.1 root 4740: }")
4741:
1.1.1.2 root 4742: ;; Used for frameless functions which save no regs and allocate no locals.
1.1 root 4743: (define_insn "return"
4744: [(return)]
4745: "USE_RETURN_INSN"
4746: "*
4747: {
4748: if (current_function_pops_args == 0)
4749: return \"rts\";
4750: operands[0] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args);
4751: return \"rtd %0\";
4752: }")
4753:
4754: (define_insn "indirect_jump"
1.1.1.4 ! root 4755: [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1.1 root 4756: ""
1.1.1.4 ! root 4757: "jmp %a0")
1.1 root 4758:
4759: ;; This should not be used unless the add/sub insns can't be.
4760:
4761: (define_insn ""
4762: [(set (match_operand:SI 0 "general_operand" "=a")
4763: (match_operand:QI 1 "address_operand" "p"))]
4764: ""
4765: "lea %a1,%0")
4766:
4767: ;; This is the first machine-dependent peephole optimization.
4768: ;; It is useful when a floating value is returned from a function call
4769: ;; and then is moved into an FP register.
4770: ;; But it is mainly intended to test the support for these optimizations.
4771:
4772: (define_peephole
4773: [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
1.1.1.4 ! root 4774: (set (match_operand:DF 0 "register_operand" "=f")
1.1 root 4775: (match_operand:DF 1 "register_operand" "ad"))]
4776: "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
4777: "*
4778: {
4779: rtx xoperands[2];
4780: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
4781: output_asm_insn (\"move%.l %1,%@\", xoperands);
4782: output_asm_insn (\"move%.l %1,%-\", operands);
4783: return \"fmove%.d %+,%0\";
4784: }
4785: ")
4786:
4787: ;; Optimize a stack-adjust followed by a push of an argument.
4788: ;; This is said to happen frequently with -msoft-float
4789: ;; when there are consecutive library calls.
4790:
4791: (define_peephole
4792: [(set (reg:SI 15) (plus:SI (reg:SI 15)
4793: (match_operand:SI 0 "immediate_operand" "n")))
4794: (set (match_operand:SF 1 "push_operand" "=m")
4795: (match_operand:SF 2 "general_operand" "rmfF"))]
4796: "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4
4797: && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
4798: "*
4799: {
4800: if (INTVAL (operands[0]) > 4)
4801: {
4802: rtx xoperands[2];
4803: xoperands[0] = stack_pointer_rtx;
4804: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4);
4805: #ifndef NO_ADDSUB_Q
4806: if (INTVAL (xoperands[1]) <= 8)
4807: output_asm_insn (\"addq%.w %1,%0\", xoperands);
4808: else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
4809: {
4810: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
4811: INTVAL (xoperands[1]) - 8);
1.1.1.3 root 4812: output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
1.1 root 4813: }
4814: else
4815: #endif
4816: if (INTVAL (xoperands[1]) <= 0x7FFF)
4817: output_asm_insn (\"add%.w %1,%0\", xoperands);
4818: else
4819: output_asm_insn (\"add%.l %1,%0\", xoperands);
4820: }
4821: if (FP_REG_P (operands[2]))
4822: return \"fmove%.s %2,%@\";
4823: return \"move%.l %2,%@\";
4824: }")
4825:
4826: ;; Speed up stack adjust followed by a fullword fixedpoint push.
4827:
4828: (define_peephole
4829: [(set (reg:SI 15) (plus:SI (reg:SI 15)
4830: (match_operand:SI 0 "immediate_operand" "n")))
4831: (set (match_operand:SI 1 "push_operand" "=m")
4832: (match_operand:SI 2 "general_operand" "g"))]
4833: "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4
4834: && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
4835: "*
4836: {
4837: if (INTVAL (operands[0]) > 4)
4838: {
4839: rtx xoperands[2];
4840: xoperands[0] = stack_pointer_rtx;
4841: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4);
4842: #ifndef NO_ADDSUB_Q
4843: if (INTVAL (xoperands[1]) <= 8)
4844: output_asm_insn (\"addq%.w %1,%0\", xoperands);
4845: else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
4846: {
4847: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
4848: INTVAL (xoperands[1]) - 8);
1.1.1.3 root 4849: output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
1.1 root 4850: }
4851: else
4852: #endif
4853: if (INTVAL (xoperands[1]) <= 0x7FFF)
4854: output_asm_insn (\"add%.w %1,%0\", xoperands);
4855: else
4856: output_asm_insn (\"add%.l %1,%0\", xoperands);
4857: }
4858: if (operands[2] == const0_rtx)
4859: return \"clr%.l %@\";
4860: return \"move%.l %2,%@\";
4861: }")
4862:
4863: ;; Speed up pushing a single byte but leaving four bytes of space.
4864:
4865: (define_peephole
4866: [(set (mem:QI (pre_dec:SI (reg:SI 15)))
4867: (match_operand:QI 1 "general_operand" "dami"))
4868: (set (reg:SI 15) (minus:SI (reg:SI 15) (const_int 2)))]
4869: "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
4870: "*
4871: {
4872: rtx xoperands[4];
4873:
4874: if (GET_CODE (operands[1]) == REG)
4875: return \"move%.l %1,%-\";
4876:
4877: xoperands[1] = operands[1];
4878: xoperands[2]
4879: = gen_rtx (MEM, QImode,
4880: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx,
4881: gen_rtx (CONST_INT, VOIDmode, 3)));
4882: xoperands[3] = stack_pointer_rtx;
4883: output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands);
4884: return \"\";
4885: }")
1.1.1.2 root 4886:
4887: ;; dbCC peepholes
4888: ;;
4889: ;; Turns
4890: ;; loop:
4891: ;; [ ... ]
4892: ;; jCC label ; abnormal loop termination
4893: ;; dbra dN, loop ; normal loop termination
4894: ;;
4895: ;; Into
4896: ;; loop:
4897: ;; [ ... ]
4898: ;; dbCC dN, loop
4899: ;; jCC label
4900: ;;
4901: ;; Which moves the jCC condition outside the inner loop for free.
1.1.1.3 root 4902: ;;
1.1.1.2 root 4903: (define_peephole
4904: [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
4905: [(cc0) (const_int 0)])
4906: (label_ref (match_operand 2 "" ""))
4907: (pc)))
4908: (parallel
4909: [(set (pc)
4910: (if_then_else
4911: (ge (plus:HI (match_operand:HI 0 "register_operand" "+d")
4912: (const_int -1))
4913: (const_int 0))
4914: (label_ref (match_operand 1 "" ""))
4915: (pc)))
4916: (set (match_dup 0)
4917: (plus:HI (match_dup 0)
4918: (const_int -1)))])]
4919: "DATA_REG_P (operands[0])"
4920: "*
4921: {
4922: CC_STATUS_INIT;
4923: output_dbcc_and_branch (operands);
4924: return \"\";
4925: }")
4926:
4927: (define_peephole
4928: [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
4929: [(cc0) (const_int 0)])
4930: (label_ref (match_operand 2 "" ""))
4931: (pc)))
4932: (parallel
4933: [(set (pc)
4934: (if_then_else
4935: (ge (plus:SI (match_operand:SI 0 "register_operand" "+d")
4936: (const_int -1))
4937: (const_int 0))
4938: (label_ref (match_operand 1 "" ""))
4939: (pc)))
4940: (set (match_dup 0)
4941: (plus:SI (match_dup 0)
4942: (const_int -1)))])]
4943: "DATA_REG_P (operands[0])"
4944: "*
4945: {
4946: CC_STATUS_INIT;
4947: output_dbcc_and_branch (operands);
4948: return \"\";
4949: }")
4950:
1.1 root 4951:
4952: ;; FPA multiply and add.
4953: (define_insn ""
4954: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4955: (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y")
4956: (match_operand:DF 2 "general_operand" "xH,y,y"))
4957: (match_operand:DF 3 "general_operand" "xH,y,dmF")))]
4958: "TARGET_FPA"
4959: "@
4960: fpma%.d %1,%w2,%w3,%0
4961: fpma%.d %x1,%x2,%x3,%0
4962: fpma%.d %x1,%x2,%x3,%0")
4963:
4964: (define_insn ""
4965: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4966: (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y")
4967: (match_operand:SF 2 "general_operand" "xH,y,ydmF"))
4968: (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))]
4969: "TARGET_FPA"
4970: "@
4971: fpma%.s %1,%w2,%w3,%0
4972: fpma%.s %1,%2,%3,%0
4973: fpma%.s %1,%2,%3,%0")
4974:
4975: ;; FPA Multiply and subtract
4976: (define_insn ""
4977: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4978: (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
4979: (mult:DF (match_operand:DF 2 "general_operand" "%xH,y,y")
4980: (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
4981: "TARGET_FPA"
4982: "@
4983: fpms%.d %3,%w2,%w1,%0
4984: fpms%.d %x3,%2,%x1,%0
4985: fpms%.d %x3,%2,%x1,%0")
4986:
4987: (define_insn ""
4988: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4989: (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
4990: (mult:SF (match_operand:SF 2 "general_operand" "%xH,rmF,y")
4991: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
4992: "TARGET_FPA"
4993: "@
4994: fpms%.s %3,%w2,%w1,%0
4995: fpms%.s %3,%2,%1,%0
4996: fpms%.s %3,%2,%1,%0")
4997:
4998: (define_insn ""
4999: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
5000: (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%xH,y,y")
5001: (match_operand:DF 2 "general_operand" "x,y,rmF"))
5002: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
5003: "TARGET_FPA"
5004: "@
5005: fpmr%.d %2,%w1,%w3,%0
5006: fpmr%.d %x2,%1,%x3,%0
5007: fpmr%.d %x2,%1,%x3,%0")
5008:
5009: (define_insn ""
5010: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
5011: (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y")
5012: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
5013: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
5014: "TARGET_FPA"
5015: "@
5016: fpmr%.s %2,%w1,%w3,%0
5017: fpmr%.s %x2,%1,%x3,%0
5018: fpmr%.s %x2,%1,%x3,%0")
5019:
5020: ;; FPA Add and multiply
5021: (define_insn ""
5022: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
5023: (mult:DF (plus:DF (match_operand:DF 1 "general_operand" "%xH,y,y")
5024: (match_operand:DF 2 "general_operand" "x,y,rmF"))
5025: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
5026: "TARGET_FPA"
5027: "@
5028: fpam%.d %2,%w1,%w3,%0
5029: fpam%.d %x2,%1,%x3,%0
5030: fpam%.d %x2,%1,%x3,%0")
5031:
5032: (define_insn ""
5033: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
5034: (mult:SF (plus:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y")
5035: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
5036: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
5037: "TARGET_FPA"
5038: "@
5039: fpam%.s %2,%w1,%w3,%0
5040: fpam%.s %x2,%1,%x3,%0
5041: fpam%.s %x2,%1,%x3,%0")
5042:
5043: ;;FPA Subtract and multiply
5044: (define_insn ""
5045: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
5046: (mult:DF (minus:DF (match_operand:DF 1 "general_operand" "xH,y,y")
5047: (match_operand:DF 2 "general_operand" "x,y,rmF"))
5048: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
5049: "TARGET_FPA"
5050: "@
5051: fpsm%.d %2,%w1,%w3,%0
5052: fpsm%.d %x2,%1,%x3,%0
5053: fpsm%.d %x2,%1,%x3,%0")
5054:
5055: (define_insn ""
5056: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
5057: (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
5058: (minus:DF (match_operand:DF 2 "general_operand" "xH,y,y")
5059: (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
5060: "TARGET_FPA"
5061: "@
5062: fpsm%.d %3,%w2,%w1,%0
5063: fpsm%.d %x3,%2,%x1,%0
5064: fpsm%.d %x3,%2,%x1,%0")
5065:
5066: (define_insn ""
5067: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
5068: (mult:SF (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,y")
5069: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
5070: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
5071: "TARGET_FPA"
5072: "@
5073: fpsm%.s %2,%w1,%w3,%0
5074: fpsm%.s %x2,%1,%x3,%0
5075: fpsm%.s %x2,%1,%x3,%0")
5076:
5077: (define_insn ""
5078: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
5079: (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
5080: (minus:SF (match_operand:SF 2 "general_operand" "xH,rmF,y")
5081: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
5082: "TARGET_FPA"
5083: "@
5084: fpsm%.s %3,%w2,%w1,%0
5085: fpsm%.s %x3,%2,%x1,%0
5086: fpsm%.s %x3,%2,%x1,%0")
5087:
5088: ;;- Local variables:
5089: ;;- mode:emacs-lisp
5090: ;;- comment-start: ";;- "
5091: ;;- comment-start-skip: ";+- *"
5092: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
5093: ;;- eval: (modify-syntax-entry ?[ "(]")
5094: ;;- eval: (modify-syntax-entry ?] ")[")
5095: ;;- eval: (modify-syntax-entry ?{ "(}")
5096: ;;- eval: (modify-syntax-entry ?} "){")
5097: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.