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