|
|
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 1, 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' -128 .. 127
56: ;;- 'L' -8 .. -1
57:
58: ;;- FPA port explanation:
59:
60: ;;- Usage of the Sun FPA and the 68881 together
61:
62: ;;- The current port of gcc to the sun fpa disallows use of the m68881
63: ;;- instructions completely if code is targetted for the fpa. This is
64: ;;- for the following reasons:
65:
66: ;;- 1) Expressing the preference hierarchy (ie. use the fpa if you
67: ;;- can, the 68881 otherwise, and data registers only if you are
68: ;;- forced to it) is a bitch with the current constraint scheme,
69: ;;- especially since it would have to work for any combination of
70: ;;- -mfpa, -m68881.
71:
72: ;;- 2) There are no instructions to move between the two types of
73: ;;- registers; the stack must be used as an intermediary.
74:
75: ;;- It could indeed be done; I think the best way would be to have
76: ;;- seperate patterns for TARGET_FPA (which implies a 68881),
77: ;;- TARGET_68881, and no floating point co-processor. Use
78: ;;- define_expands for all of the named instruction patterns, and
79: ;;- include code in the FPA instruction to deal with the 68881 with
80: ;;- preferences specifically set to favor the fpa. Some of this has
81: ;;- already been done:
82: ;;-
83: ;;- 1) Separation of most of the patterns out into a TARGET_FPA
84: ;;- case and a TARGET_68881 case (the exceptions are the patterns
85: ;;- which would need one define_expand and three define_insn's under
86: ;;- it (with alot of duplicate code between them) to replace the
87: ;;- current single define_insn. These are mov{[ds]f,[ds]i} and the
88: ;;- first two patterns in the md.
89: ;;-
90: ;;- Some would still have to be done:
91: ;;-
92: ;;- 1) Add code to the fpa patterns which correspond to 68881
93: ;;- patterns to deal with the 68881 case (including preferences!).
94: ;;- What you might actually do here is combine the fpa and 68881 code
95: ;;- back together into one pattern for those instructions where it's
96: ;;- absolutely necessary and save yourself some duplicate code. I'm
97: ;;- not completely sure as to whether you could get away with doing
98: ;;- this only for the mov* insns, or if you'd have to do it for all
99: ;;- named insns.
100: ;;- 2) Add code to the mov{[ds]f,[ds]i} instructions to handle
101: ;;- moving between fpa regs and 68881 regs.
102:
103: ;;- Since the fpa is more powerful than the 68881 and also has more
104: ;;- registers, and since I think the reultant md would be medium ugly
105: ;;- (lot's of duplicate code, ugly constraint strings), I elected not
106: ;;- to do this change.
107:
108: ;;- Another reason why someone *might* want to do the change is to
109: ;;- control which register classes are accessed in a slightly cleaner
110: ;;- way than I have. See the blurb on CONDITIONAL_REGISTER_USAGE in
111: ;;- the internals manual.
112:
113: ;;- Yet another reason why someone might want to do this change is to
114: ;;- allow use of some of the 68881 insns which have no equivalent on
115: ;;- the fpa. The sqrt instruction comes fairly quickly to mind.
116:
117: ;;- If this is ever done, don't forget to change tm-sun3.h so that
118: ;;- it *will* define __HAVE_68881__ when the FPA is in use.
119:
120: ;;- Condition code hack
121:
122: ;;- When a floating point compare is done in the fpa, the resulting
123: ;;- condition codes are left in the fpastatus register. The values in
124: ;;- this register must be moved into the 68000 cc register before any
125: ;;- jump is executed. Once this has been done, regular jump
126: ;;- instructions are fine (ie. floating point jumps are not necessary.
127: ;;- They are only done if the cc is in the 68881).
128:
129: ;;- The instructions that move the fpastatus register to the 68000
130: ;;- register clobber a data register (the move cannot be done direct).
131: ;;- These instructions might be bundled either with the compare
132: ;;- instruction, or the branch instruction. If we were using both the
133: ;;- fpa and the 68881 together, we would wish to only mark the
134: ;;- register clobbered if we were doing the compare in the fpa, but I
135: ;;- think that that decision (whether to clobber the register or not)
136: ;;- must be done before register allocation (makes sense) and hence we
137: ;;- can't know if the floating point compare will be done in the fpa
138: ;;- or the fp. So whenever we are asked for code that uses the fpa,
139: ;;- we will mark a data register as clobbered. This is reasonable, as
140: ;;- almost all floating point compare operations done with fpa code
141: ;;- enabled will be done in the fpa. It's even more reasonable since
142: ;;- we decided to make the 68881 and the fpa mutually exclusive.
143:
144: ;;- We place to code to move the fpastatus register inside of a
145: ;;- define_expand so that we can do it conditionally based on whether
146: ;;- we are tagetting an fpa or not.
147:
148: ;;- This still leaves us with the question of where we wish to put the
149: ;;- code to move the fpastatus reg. If we put it in the compare
150: ;;- instruction, we can restrict the clobbering of the register to
151: ;;- floating point compares, but we can't take advantage of floating
152: ;;- point subtracts & etc. that alter the fpastatus register. If we
153: ;;- put it in the branch instruction, all branches compiled with fpa
154: ;;- code enabled will clobber a data register, but we will be able to
155: ;;- take advantage of fpa subtracts. This balance favors putting the
156: ;;- code in with the compare instruction.
157:
158: ;;- Note that if some enterprising hacker should decide to switch
159: ;;- this, he'll need to modify the code in NOTICE_UPDATE_CC.
160:
161: ;;- Usage of the top 16 fpa registers
162:
163: ;;- The only locations which we may transfer fpa registers 16-31 from
164: ;;- or to are the fpa registers 0-15. (68000 registers and memory
165: ;;- locations are impossible). This causes problems in gcc, which
166: ;;- assumes that mov?? instructions require no additional registers
167: ;;- (see section 11.7) and since floating point moves *must* be
168: ;;- supported into general registers (see section 12.3 under
169: ;;- HARD_REGNO_OK_FOR_MODE_P) from anywhere.
170:
171: ;;- My solution was to reserve fpa0 for moves into or out of these top
172: ;;- 16 registers and to disparage the choice to reload into or out of
173: ;;- these registers as much as I could. That alternative is always
174: ;;- last in the list, so it will not be used unless all else fails. I
175: ;;- will note that according to my current information, sun's compiler
176: ;;- doesn't use these top 16 registers at all.
177:
178: ;;- There is another possible way to do it. I *believe* that if you
179: ;;- make absolutely sure that the code will not be exectued in the
180: ;;- reload pass, you can support the mov?? names with define_expands
181: ;;- which require new registers. This may be possible by the
182: ;;- appropriate juggling of constraints. I may come back to this later.
183:
184: ;;- Usage of constant RAM
185:
186: ;;- This has been handled correctly (I believe) but the way I've done
187: ;;- it could use a little explanation. The constant RAM can only be
188: ;;- accessed when the instruction is in "command register" mode.
189: ;;- "command register" mode means that no accessing of memory or the
190: ;;- 68000 registers is being done. This can be expressed easily in
191: ;;- constraints, so generally the mode of the instruction is
192: ;;- determined by a branch off of which_alternative. In outputing
193: ;;- instructions, a 'w' means to output an access to the constant ram
194: ;;- (if the arg is CONST_DOUBLE and is one of the available
195: ;;- constants), and 'x' means to output a register pair (if the arg is
196: ;;- a 68000 register) and a 'y' is the combination of the above two
197: ;;- processies. You use a 'y' in two operand DF instructions where you
198: ;;- *know* the other operand is an fpa register, you use an 'x' in DF
199: ;;- instructions where the arg might be a 68000 register and the
200: ;;- instruction is *not* in "command register" mode, and you use a 'w'
201: ;;- in two situations: 1) The instruction *is* in command register
202: ;;- mode (and hence won't be accessing 68000 registers), or 2) The
203: ;;- instruction is a two operand SF instruction where you know the
204: ;;- other operand is an fpa register.
205:
206: ;;- Optimization issues
207:
208: ;;- I actually think that I've included all of the fpa instructions
209: ;;- that should be included. Note that if someone is interested in
210: ;;- doing serious floating point work on the sun fpa, I would advise
211: ;;- the use of the "asm" instruction in gcc to allow you to use the
212: ;;- sin, cos, and exponential functions on the fpa board.
213:
214: ;;- END FPA Explanation Section.
215:
216:
217: ;;- Some of these insn's are composites of several m68000 op codes.
218: ;;- The assembler (or final @@??) insures that the appropriate one is
219: ;;- selected.
220:
221: (define_insn ""
222: [(set (match_operand:DF 0 "push_operand" "=m")
223: (match_operand:DF 1 "general_operand" "ro<>fyF"))]
224: ""
225: "*
226: {
227: if (FP_REG_P (operands[1]))
228: return \"fmove%.d %f1,%0\";
229: if (FPA_REG_P (operands[1]))
230: return \"fpmove%.d %1, %x0\";
231: return output_move_double (operands);
232: }")
233:
234: (define_insn ""
235: [(set (match_operand:DI 0 "push_operand" "=m")
236: (match_operand:DI 1 "general_operand" "ro<>Fy"))]
237: ""
238: "*
239: {
240: return output_move_double (operands);
241: }")
242:
243: ;; Put tstsi first among test insns so it matches a CONST_INT operand.
244:
245: (define_insn "tstsi"
246: [(set (cc0)
247: (match_operand:SI 0 "general_operand" "rm"))]
248: ""
249: "*
250: {
251: #ifdef ISI_OV
252: /* ISI's assembler fails to handle tstl a0. */
253: if (! ADDRESS_REG_P (operands[0]))
254: #else
255: if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
256: #endif
257: return \"tst%.l %0\";
258: /* If you think that the 68020 does not support tstl a0,
259: reread page B-167 of the 68020 manual more carefully. */
260: /* On an address reg, cmpw may replace cmpl. */
261: #ifdef HPUX_ASM
262: return \"cmp%.w %0,%#0\";
263: #else
264: return \"cmp%.w %#0,%0\";
265: #endif
266: }")
267:
268: (define_insn "tsthi"
269: [(set (cc0)
270: (match_operand:HI 0 "general_operand" "rm"))]
271: ""
272: "*
273: {
274: #ifdef ISI_OV
275: if (! ADDRESS_REG_P (operands[0]))
276: #else
277: if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
278: #endif
279: return \"tst%.w %0\";
280: #ifdef HPUX_ASM
281: return \"cmp%.w %0,%#0\";
282: #else
283: return \"cmp%.w %#0,%0\";
284: #endif
285: }")
286:
287: (define_insn "tstqi"
288: [(set (cc0)
289: (match_operand:QI 0 "general_operand" "dm"))]
290: ""
291: "tst%.b %0")
292:
293: (define_expand "tstsf"
294: [(set (cc0)
295: (match_operand:SF 0 "general_operand" ""))]
296: "TARGET_68881 || TARGET_FPA"
297: "
298: {
299: if (TARGET_FPA)
300: {
301: emit_insn (gen_rtx (PARALLEL, VOIDmode,
302: gen_rtvec (2,
303: gen_rtx (SET, VOIDmode,
304: cc0_rtx, operands[0]),
305: gen_rtx (CLOBBER, VOIDmode,
306: gen_reg_rtx (SImode)))));
307: DONE;
308: }
309: }")
310:
311: (define_insn ""
312: [(set (cc0)
313: (match_operand:SF 0 "general_operand" "xmdF"))
314: (clobber (match_operand:SI 1 "general_operand" "d"))]
315: "TARGET_FPA"
316: "fptst%.s %x0\;fpmove fpastatus,%1\;movw %1,cc")
317:
318: (define_insn ""
319: [(set (cc0)
320: (match_operand:SF 0 "general_operand" "fdm"))]
321: "TARGET_68881"
322: "*
323: {
324: cc_status.flags = CC_IN_68881;
325: if (FP_REG_P (operands[0]))
326: return \"ftst%.x %0\";
327: return \"ftst%.s %0\";
328: }")
329:
330: (define_expand "tstdf"
331: [(set (cc0)
332: (match_operand:DF 0 "general_operand" ""))]
333: "TARGET_68881 || TARGET_FPA"
334: "
335: {
336: if (TARGET_FPA)
337: {
338: emit_insn (gen_rtx (PARALLEL, VOIDmode,
339: gen_rtvec (2, gen_rtx (SET, VOIDmode,
340: cc0_rtx, operands[0]),
341: gen_rtx (CLOBBER, VOIDmode,
342: gen_reg_rtx (SImode)))));
343: DONE;
344: }
345: }")
346:
347: (define_insn ""
348: [(set (cc0)
349: (match_operand:DF 0 "general_operand" "xrmF"))
350: (clobber (match_operand:SI 1 "general_operand" "d"))]
351: "TARGET_FPA"
352: "fptst%.d %x0\;fpmove fpastatus,%1\;movw %1,cc")
353:
354: (define_insn ""
355: [(set (cc0)
356: (match_operand:DF 0 "general_operand" "fm"))]
357: "TARGET_68881"
358: "*
359: {
360: cc_status.flags = CC_IN_68881;
361: if (FP_REG_P (operands[0]))
362: return \"ftst%.x %0\";
363: return \"ftst%.d %0\";
364: }")
365:
366: ;; compare instructions.
367:
368: ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
369:
370: ;; A composite of the cmp, cmpa, & cmpi m68000 op codes.
371: (define_insn "cmpsi"
372: [(set (cc0)
373: (compare (match_operand:SI 0 "general_operand" "rKs,mr,>")
374: (match_operand:SI 1 "general_operand" "mr,Ksr,>")))]
375: ""
376: "*
377: {
378: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
379: return \"cmpm%.l %1,%0\";
380: if (REG_P (operands[1])
381: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
382: { cc_status.flags |= CC_REVERSED;
383: #ifdef HPUX_ASM
384: return \"cmp%.l %d1,%d0\";
385: #else
386: return \"cmp%.l %d0,%d1\";
387: #endif
388: }
389: #ifdef HPUX_ASM
390: return \"cmp%.l %d0,%d1\";
391: #else
392: return \"cmp%.l %d1,%d0\";
393: #endif
394: }")
395:
396: (define_insn "cmphi"
397: [(set (cc0)
398: (compare (match_operand:HI 0 "general_operand" "rnm,d,n,m")
399: (match_operand:HI 1 "general_operand" "d,rnm,m,n")))]
400: ""
401: "*
402: {
403: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
404: return \"cmpm%.w %1,%0\";
405: if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
406: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
407: { cc_status.flags |= CC_REVERSED;
408: #ifdef HPUX_ASM
409: return \"cmp%.w %d1,%d0\";
410: #else
411: return \"cmp%.w %d0,%d1\";
412: #endif
413: }
414: #ifdef HPUX_ASM
415: return \"cmp%.w %d0,%d1\";
416: #else
417: return \"cmp%.w %d1,%d0\";
418: #endif
419: }")
420:
421: (define_insn "cmpqi"
422: [(set (cc0)
423: (compare (match_operand:QI 0 "general_operand" "dn,md,>")
424: (match_operand:QI 1 "general_operand" "dm,nd,>")))]
425: ""
426: "*
427: {
428: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
429: return \"cmpm%.b %1,%0\";
430: if (REG_P (operands[1])
431: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
432: { cc_status.flags |= CC_REVERSED;
433: #ifdef HPUX_ASM
434: return \"cmp%.b %d1,%d0\";
435: #else
436: return \"cmp%.b %d0,%d1\";
437: #endif
438: }
439: #ifdef HPUX_ASM
440: return \"cmp%.b %d0,%d1\";
441: #else
442: return \"cmp%.b %d1,%d0\";
443: #endif
444: }")
445:
446: (define_expand "cmpdf"
447: [(set (cc0)
448: (compare (match_operand:DF 0 "general_operand" "")
449: (match_operand:DF 1 "general_operand" "")))]
450: "TARGET_68881 || TARGET_FPA"
451: "
452: {
453: if (TARGET_FPA)
454: {
455: rtx set = gen_rtx (SET, VOIDmode, cc0_rtx,
456: gen_rtx (COMPARE, VOIDmode, operands[0], operands[1]));
457: emit_insn (gen_rtx (PARALLEL, VOIDmode,
458: gen_rtvec (2, set,
459: gen_rtx (CLOBBER, VOIDmode,
460: gen_reg_rtx (SImode)))));
461: DONE;
462: }
463: }")
464:
465: (define_insn ""
466: [(set (cc0)
467: (compare (match_operand:DF 0 "general_operand" "x,y")
468: (match_operand:DF 1 "general_operand" "xH,rmF")))
469: (clobber (match_operand:SI 2 "general_operand" "d,d"))]
470: "TARGET_FPA"
471: "fpcmp%.d %y1,%0\;fpmove fpastatus,%2\;movw %2,cc")
472:
473: (define_insn ""
474: [(set (cc0)
475: (compare (match_operand:DF 0 "general_operand" "f,mG")
476: (match_operand:DF 1 "general_operand" "fmG,f")))]
477: "TARGET_68881"
478: "*
479: {
480: cc_status.flags = CC_IN_68881;
481: #ifdef HPUX_ASM
482: if (REG_P (operands[0]))
483: {
484: if (REG_P (operands[1]))
485: return \"fcmp%.x %0,%1\";
486: else
487: return \"fcmp%.d %0,%f1\";
488: }
489: cc_status.flags |= CC_REVERSED;
490: return \"fcmp%.d %1,%f0\";
491: #else
492: if (REG_P (operands[0]))
493: {
494: if (REG_P (operands[1]))
495: return \"fcmp%.x %1,%0\";
496: else
497: return \"fcmp%.d %f1,%0\";
498: }
499: cc_status.flags |= CC_REVERSED;
500: return \"fcmp%.d %f0,%1\";
501: #endif
502: }")
503:
504: (define_expand "cmpsf"
505: [(set (cc0)
506: (compare (match_operand:SF 0 "general_operand" "")
507: (match_operand:SF 1 "general_operand" "")))]
508: "TARGET_68881 || TARGET_FPA"
509: "
510: {
511: if (TARGET_FPA)
512: {
513: rtx set = gen_rtx (SET, VOIDmode, cc0_rtx,
514: gen_rtx (COMPARE, VOIDmode, operands[0], operands[1]));
515: emit_insn (gen_rtx (PARALLEL, VOIDmode,
516: gen_rtvec (2, set,
517: gen_rtx (CLOBBER, VOIDmode,
518: gen_reg_rtx(SImode)))));
519: DONE;
520: }
521: }")
522:
523: (define_insn ""
524: [(set (cc0)
525: (compare (match_operand:SF 0 "general_operand" "x,y")
526: (match_operand:SF 1 "general_operand" "xH,rmF")))
527: (clobber (match_operand:SI 2 "general_operand" "d,d"))]
528: "TARGET_FPA"
529: "fpcmp%.s %w1,%x0\;fpmove fpastatus,%2\;movw %2,cc")
530:
531: (define_insn ""
532: [(set (cc0)
533: (compare (match_operand:SF 0 "general_operand" "f,mdG")
534: (match_operand:SF 1 "general_operand" "fmdG,f")))]
535: "TARGET_68881"
536: "*
537: {
538: cc_status.flags = CC_IN_68881;
539: #ifdef HPUX_ASM
540: if (FP_REG_P (operands[0]))
541: {
542: if (FP_REG_P (operands[1]))
543: return \"fcmp%.x %0,%1\";
544: else
545: return \"fcmp%.s %0,%f1\";
546: }
547: cc_status.flags |= CC_REVERSED;
548: return \"fcmp%.s %1,%f0\";
549: #else
550: if (FP_REG_P (operands[0]))
551: {
552: if (FP_REG_P (operands[1]))
553: return \"fcmp%.x %1,%0\";
554: else
555: return \"fcmp%.s %f1,%0\";
556: }
557: cc_status.flags |= CC_REVERSED;
558: return \"fcmp%.s %f0,%1\";
559: #endif
560: }")
561:
562: ;; Recognizers for btst instructions.
563:
564: (define_insn ""
565: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do")
566: (const_int 1)
567: (minus:SI (const_int 7)
568: (match_operand:SI 1 "general_operand" "di"))))]
569: ""
570: "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
571:
572: (define_insn ""
573: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d")
574: (const_int 1)
575: (minus:SI (const_int 31)
576: (match_operand:SI 1 "general_operand" "di"))))]
577: ""
578: "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
579:
580: ;; The following two patterns are like the previous two
581: ;; except that they use the fact that bit-number operands
582: ;; are automatically masked to 3 or 5 bits.
583:
584: (define_insn ""
585: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do")
586: (const_int 1)
587: (minus:SI (const_int 7)
588: (and:SI
589: (match_operand:SI 1 "general_operand" "d")
590: (const_int 7)))))]
591: ""
592: "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
593:
594: (define_insn ""
595: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d")
596: (const_int 1)
597: (minus:SI (const_int 31)
598: (and:SI
599: (match_operand:SI 1 "general_operand" "d")
600: (const_int 31)))))]
601: ""
602: "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
603:
604: ;; Nonoffsettable mem refs are ok in this one pattern
605: ;; since we don't try to adjust them.
606: (define_insn ""
607: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "md")
608: (const_int 1)
609: (match_operand:SI 1 "general_operand" "i")))]
610: "GET_CODE (operands[1]) == CONST_INT
611: && (unsigned) INTVAL (operands[1]) < 8"
612: "*
613: {
614: operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1]));
615: return output_btst (operands, operands[1], operands[0], insn, 7);
616: }")
617:
618: (define_insn ""
619: ;; The constraint "o,d" here means that a nonoffsettable memref
620: ;; will match the first alternative, and its address will be reloaded.
621: ;; Copying the memory contents into a reg would be incorrect if the
622: ;; bit position is over 7.
623: [(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "o,d")
624: (const_int 1)
625: (match_operand:SI 1 "general_operand" "i,i")))]
626: "GET_CODE (operands[1]) == CONST_INT"
627: "*
628: {
629: if (GET_CODE (operands[0]) == MEM)
630: {
631: operands[0] = adj_offsettable_operand (operands[0],
632: INTVAL (operands[1]) / 8);
633: operands[1] = gen_rtx (CONST_INT, VOIDmode,
634: 7 - INTVAL (operands[1]) % 8);
635: return output_btst (operands, operands[1], operands[0], insn, 7);
636: }
637: operands[1] = gen_rtx (CONST_INT, VOIDmode,
638: 15 - INTVAL (operands[1]));
639: return output_btst (operands, operands[1], operands[0], insn, 15);
640: }")
641:
642: (define_insn ""
643: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "do")
644: (const_int 1)
645: (match_operand:SI 1 "general_operand" "i")))]
646: "GET_CODE (operands[1]) == CONST_INT"
647: "*
648: {
649: if (GET_CODE (operands[0]) == MEM)
650: {
651: operands[0] = adj_offsettable_operand (operands[0],
652: INTVAL (operands[1]) / 8);
653: operands[1] = gen_rtx (CONST_INT, VOIDmode,
654: 7 - INTVAL (operands[1]) % 8);
655: return output_btst (operands, operands[1], operands[0], insn, 7);
656: }
657: operands[1] = gen_rtx (CONST_INT, VOIDmode,
658: 31 - INTVAL (operands[1]));
659: return output_btst (operands, operands[1], operands[0], insn, 31);
660: }")
661:
662: (define_insn ""
663: [(set (cc0) (subreg:SI (lshiftrt:QI (match_operand:QI 0 "nonimmediate_operand" "dm")
664: (const_int 7))
665: 0))]
666: ""
667: "*
668: {
669: cc_status.flags = CC_Z_IN_NOT_N | CC_NOT_NEGATIVE;
670: return \"tst%.b %0\";
671: }")
672:
673: (define_insn ""
674: [(set (cc0) (and:SI (sign_extend:SI (sign_extend:HI (match_operand:QI 0 "nonimmediate_operand" "dm")))
675: (match_operand:SI 1 "general_operand" "i")))]
676: "(GET_CODE (operands[1]) == CONST_INT
677: && (unsigned) INTVAL (operands[1]) < 0x100
678: && exact_log2 (INTVAL (operands[1])) >= 0)"
679: "*
680: { register int log = exact_log2 (INTVAL (operands[1]));
681: operands[1] = gen_rtx (CONST_INT, VOIDmode, log);
682: return output_btst (operands, operands[1], operands[0], insn, 7);
683: }")
684:
685: ;; move instructions
686:
687: ;; A special case in which it is not desirable
688: ;; to reload the constant into a data register.
689: (define_insn ""
690: [(set (match_operand:SI 0 "push_operand" "=m")
691: (match_operand:SI 1 "general_operand" "J"))]
692: "GET_CODE (operands[1]) == CONST_INT
693: && INTVAL (operands[1]) >= -0x8000
694: && INTVAL (operands[1]) < 0x8000"
695: "*
696: {
697: if (operands[1] == const0_rtx)
698: return \"clr%.l %0\";
699: return \"pea %a1\";
700: }")
701:
702: ;This is never used.
703: ;(define_insn "swapsi"
704: ; [(set (match_operand:SI 0 "general_operand" "r")
705: ; (match_operand:SI 1 "general_operand" "r"))
706: ; (set (match_dup 1) (match_dup 0))]
707: ; ""
708: ; "exg %1,%0")
709:
710: ;; Special case of fullword move when source is zero.
711: ;; The reason this is special is to avoid loading a zero
712: ;; into a data reg with moveq in order to store it elsewhere.
713:
714: (define_insn ""
715: [(set (match_operand:SI 0 "general_operand" "=g")
716: (const_int 0))]
717: ""
718: "*
719: {
720: if (ADDRESS_REG_P (operands[0]))
721: return \"sub%.l %0,%0\";
722: /* moveq is faster on the 68000. */
723: if (DATA_REG_P (operands[0]) && !TARGET_68020)
724: #ifdef MOTOROLA
725: return \"moveq%.l %#0,%0\";
726: #else
727: return \"moveq %#0,%0\";
728: #endif
729: return \"clr%.l %0\";
730: }")
731:
732: ;; General case of fullword move. The register constraints
733: ;; force integer constants in range for a moveq to be reloaded
734: ;; if they are headed for memory.
735: (define_insn "movsi"
736: ;; Notes: make sure no alternative allows g vs g.
737: ;; We don't allow f-regs since fixed point cannot go in them.
738: ;; We do allow y and x regs since fixed point is allowed in them.
739: [(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m")
740: (match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))]
741: ""
742: "*
743: {
744: if (which_alternative == 3)
745: return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\";
746: if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0]))
747: return \"fpmove%.l %x1,%x0\";
748: if (GET_CODE (operands[1]) == CONST_INT)
749: {
750: if (operands[1] == const0_rtx
751: && (DATA_REG_P (operands[0])
752: || GET_CODE (operands[0]) == MEM))
753: return \"clr%.l %0\";
754: else if (DATA_REG_P (operands[0])
755: && INTVAL (operands[1]) < 128
756: && INTVAL (operands[1]) >= -128)
757: {
758: #ifdef MOTOROLA
759: return \"moveq%.l %1,%0\";
760: #else
761: return \"moveq %1,%0\";
762: #endif
763: }
764: else if (ADDRESS_REG_P (operands[0])
765: && INTVAL (operands[1]) < 0x8000
766: && INTVAL (operands[1]) >= -0x8000)
767: return \"move%.w %1,%0\";
768: else if (push_operand (operands[0], SImode)
769: && INTVAL (operands[1]) < 0x8000
770: && INTVAL (operands[1]) >= -0x8000)
771: return \"pea %a1\";
772: }
773: else if ((GET_CODE (operands[1]) == SYMBOL_REF
774: || GET_CODE (operands[1]) == CONST)
775: && push_operand (operands[0], SImode))
776: return \"pea %a1\";
777: else if ((GET_CODE (operands[1]) == SYMBOL_REF
778: || GET_CODE (operands[1]) == CONST)
779: && ADDRESS_REG_P (operands[0]))
780: return \"lea %a1,%0\";
781: return \"move%.l %1,%0\";
782: }")
783:
784: (define_insn "movhi"
785: [(set (match_operand:HI 0 "general_operand" "=g")
786: (match_operand:HI 1 "general_operand" "g"))]
787: ""
788: "*
789: {
790: if (GET_CODE (operands[1]) == CONST_INT)
791: {
792: if (operands[1] == const0_rtx
793: && (DATA_REG_P (operands[0])
794: || GET_CODE (operands[0]) == MEM))
795: return \"clr%.w %0\";
796: else if (DATA_REG_P (operands[0])
797: && INTVAL (operands[1]) < 128
798: && INTVAL (operands[1]) >= -128)
799: {
800: #ifdef MOTOROLA
801: return \"moveq%.l %1,%0\";
802: #else
803: return \"moveq %1,%0\";
804: #endif
805: }
806: else if (INTVAL (operands[1]) < 0x8000
807: && INTVAL (operands[1]) >= -0x8000)
808: return \"move%.w %1,%0\";
809: }
810: else if (CONSTANT_P (operands[1]))
811: return \"move%.l %1,%0\";
812: #ifndef SONY_ASM
813: /* Recognize the insn before a tablejump, one that refers
814: to a table of offsets. Such an insn will need to refer
815: to a label on the insn. So output one. Use the label-number
816: of the table of offsets to generate this label. */
817: if (GET_CODE (operands[1]) == MEM
818: && GET_CODE (XEXP (operands[1], 0)) == PLUS
819: && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
820: || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF)
821: && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS
822: && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS)
823: {
824: rtx labelref;
825: if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF)
826: labelref = XEXP (XEXP (operands[1], 0), 0);
827: else
828: labelref = XEXP (XEXP (operands[1], 0), 1);
829: #if defined (MOTOROLA) && ! defined (SGS_3B1)
830: #ifdef SGS
831: fprintf (asm_out_file, \"\\tset %s%d,.+2\\n\", \"LI\",
832: CODE_LABEL_NUMBER (XEXP (labelref, 0)));
833: #else /* not SGS */
834: fprintf (asm_out_file, \"\\t.set %s%d,.+2\\n\", \"LI\",
835: CODE_LABEL_NUMBER (XEXP (labelref, 0)));
836: #endif /* not SGS */
837: #else /* SGS_3B1 or not MOTOROLA */
838: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\",
839: CODE_LABEL_NUMBER (XEXP (labelref, 0)));
840: /* For sake of 3b1, set flag saying we need to define the symbol
841: LD%n (with value L%n-LI%n) at the end of the switch table. */
842: RTX_INTEGRATED_P (next_real_insn (XEXP (labelref, 0))) = 1;
843: #endif /* SGS_3B1 or not MOTOROLA */
844: }
845: #endif /* SONY_ASM */
846: return \"move%.w %1,%0\";
847: }")
848:
849: (define_insn "movstricthi"
850: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
851: (match_operand:HI 1 "general_operand" "rmn"))]
852: ""
853: "*
854: {
855: if (GET_CODE (operands[1]) == CONST_INT)
856: {
857: if (operands[1] == const0_rtx
858: && (DATA_REG_P (operands[0])
859: || GET_CODE (operands[0]) == MEM))
860: return \"clr%.w %0\";
861: }
862: return \"move%.w %1,%0\";
863: }")
864:
865: (define_insn "movqi"
866: [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")
867: (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]
868: ""
869: "*
870: {
871: rtx xoperands[4];
872: if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
873: {
874: xoperands[1] = operands[1];
875: xoperands[2]
876: = gen_rtx (MEM, QImode,
877: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
878: xoperands[3] = stack_pointer_rtx;
879: /* Just pushing a byte puts it in the high byte of the halfword. */
880: /* We must put it in the low half, the second byte. */
881: output_asm_insn (\"subq%.w %#2,%3\;move%.b %1,%2\", xoperands);
882: return \"move%.w %+,%0\";
883: }
884: if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
885: {
886: xoperands[0] = operands[0];
887: xoperands[1] = operands[1];
888: xoperands[2]
889: = gen_rtx (MEM, QImode,
890: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
891: xoperands[3] = stack_pointer_rtx;
892: output_asm_insn (\"move%.w %1,%-\;move%.b %2,%0\;addq%.w %#2,%3\", xoperands);
893: return \"\";
894: }
895: if (operands[1] == const0_rtx)
896: return \"clr%.b %0\";
897: if (GET_CODE (operands[1]) == CONST_INT
898: && INTVAL (operands[1]) == -1)
899: return \"st %0\";
900: if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
901: return \"move%.l %1,%0\";
902: if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
903: return \"move%.w %1,%0\";
904: return \"move%.b %1,%0\";
905: }")
906:
907: (define_insn "movstrictqi"
908: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
909: (match_operand:QI 1 "general_operand" "dmn"))]
910: ""
911: "*
912: {
913: if (operands[1] == const0_rtx)
914: return \"clr%.b %0\";
915: return \"move%.b %1,%0\";
916: }")
917:
918: (define_insn "movsf"
919: [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm")
920: (match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))]
921: ; [(set (match_operand:SF 0 "general_operand" "=rmf")
922: ; (match_operand:SF 1 "general_operand" "rmfF"))]
923: ""
924: "*
925: {
926: if (which_alternative >= 4)
927: return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\";
928: if (FPA_REG_P (operands[0]))
929: {
930: if (FPA_REG_P (operands[1]))
931: return \"fpmove%.s %x1,%x0\";
932: else if (GET_CODE (operands[1]) == CONST_DOUBLE)
933: return output_move_const_single (operands);
934: else if (FP_REG_P (operands[1]))
935: return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\";
936: return \"fpmove%.s %x1,%x0\";
937: }
938: if (FPA_REG_P (operands[1]))
939: {
940: if (FP_REG_P (operands[0]))
941: return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\";
942: else
943: return \"fpmove%.s %x1,%x0\";
944: }
945: if (FP_REG_P (operands[0]))
946: {
947: if (FP_REG_P (operands[1]))
948: return \"fmove%.x %1,%0\";
949: else if (ADDRESS_REG_P (operands[1]))
950: return \"move%.l %1,%-\;fmove%.s %+,%0\";
951: else if (GET_CODE (operands[1]) == CONST_DOUBLE)
952: return output_move_const_single (operands);
953: return \"fmove%.s %f1,%0\";
954: }
955: if (FP_REG_P (operands[1]))
956: {
957: if (ADDRESS_REG_P (operands[0]))
958: return \"fmove%.s %1,%-\;move%.l %+,%0\";
959: return \"fmove%.s %f1,%0\";
960: }
961: return \"move%.l %1,%0\";
962: }")
963:
964: (define_insn "movdf"
965: [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>,y,rm,x,!x,!rm")
966: (match_operand:DF 1 "general_operand" "rf,m,rofF<>,rmF,y,xH,rm,x"))]
967: ; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>")
968: ; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
969: ""
970: "*
971: {
972: if (which_alternative == 6)
973: return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\";
974: if (FPA_REG_P (operands[0]))
975: {
976: if (GET_CODE (operands[1]) == CONST_DOUBLE)
977: return output_move_const_double (operands);
978: if (FP_REG_P (operands[1]))
979: return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\";
980: return \"fpmove%.d %x1,%x0\";
981: }
982: else if (FPA_REG_P (operands[1]))
983: {
984: if (FP_REG_P(operands[0]))
985: return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\";
986: else
987: return \"fpmove%.d %x1,%x0\";
988: }
989: if (FP_REG_P (operands[0]))
990: {
991: if (FP_REG_P (operands[1]))
992: return \"fmove%.x %1,%0\";
993: if (REG_P (operands[1]))
994: {
995: rtx xoperands[2];
996: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
997: output_asm_insn (\"move%.l %1,%-\", xoperands);
998: output_asm_insn (\"move%.l %1,%-\", operands);
999: return \"fmove%.d %+,%0\";
1000: }
1001: if (GET_CODE (operands[1]) == CONST_DOUBLE)
1002: return output_move_const_double (operands);
1003: return \"fmove%.d %f1,%0\";
1004: }
1005: else if (FP_REG_P (operands[1]))
1006: {
1007: if (REG_P (operands[0]))
1008: {
1009: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1010: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1011: return \"move%.l %+,%0\";
1012: }
1013: else
1014: return \"fmove%.d %f1,%0\";
1015: }
1016: return output_move_double (operands);
1017: }
1018: ")
1019:
1020: ;; movdi can apply to fp regs in some cases
1021: (define_insn "movdi"
1022: ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1023: [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,y,rm,!*x,!rm")
1024: (match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))]
1025: ; [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm")
1026: ; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))]
1027: ; [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f")
1028: ; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
1029: ""
1030: "*
1031: {
1032: if (which_alternative == 8)
1033: return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\";
1034: if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
1035: return \"fpmove%.d %x1,%x0\";
1036: if (FP_REG_P (operands[0]))
1037: {
1038: if (FP_REG_P (operands[1]))
1039: return \"fmove%.x %1,%0\";
1040: if (REG_P (operands[1]))
1041: {
1042: rtx xoperands[2];
1043: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1044: output_asm_insn (\"move%.l %1,%-\", xoperands);
1045: output_asm_insn (\"move%.l %1,%-\", operands);
1046: return \"fmove%.d %+,%0\";
1047: }
1048: if (GET_CODE (operands[1]) == CONST_DOUBLE)
1049: return output_move_const_double (operands);
1050: return \"fmove%.d %f1,%0\";
1051: }
1052: else if (FP_REG_P (operands[1]))
1053: {
1054: if (REG_P (operands[0]))
1055: {
1056: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1057: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1058: return \"move%.l %+,%0\";
1059: }
1060: else
1061: return \"fmove%.d %f1,%0\";
1062: }
1063: return output_move_double (operands);
1064: }
1065: ")
1066:
1067: ;; Thus goes after the move instructions
1068: ;; because the move instructions are better (require no spilling)
1069: ;; when they can apply. It goes before the add/sub insns
1070: ;; so we will prefer it to them.
1071:
1072: (define_insn "pushasi"
1073: [(set (match_operand:SI 0 "push_operand" "=m")
1074: (match_operand:SI 1 "address_operand" "p"))]
1075: ""
1076: "pea %a1")
1077:
1078: ;; truncation instructions
1079: (define_insn "truncsiqi2"
1080: [(set (match_operand:QI 0 "general_operand" "=dm,d")
1081: (truncate:QI
1082: (match_operand:SI 1 "general_operand" "doJ,i")))]
1083: ""
1084: "*
1085: {
1086: if (GET_CODE (operands[0]) == REG)
1087: return \"move%.l %1,%0\";
1088: if (GET_CODE (operands[1]) == MEM)
1089: operands[1] = adj_offsettable_operand (operands[1], 3);
1090: return \"move%.b %1,%0\";
1091: }")
1092:
1093: (define_insn "trunchiqi2"
1094: [(set (match_operand:QI 0 "general_operand" "=dm,d")
1095: (truncate:QI
1096: (match_operand:HI 1 "general_operand" "doJ,i")))]
1097: ""
1098: "*
1099: {
1100: if (GET_CODE (operands[0]) == REG
1101: && (GET_CODE (operands[1]) == MEM
1102: || GET_CODE (operands[1]) == CONST_INT))
1103: return \"move%.w %1,%0\";
1104: if (GET_CODE (operands[0]) == REG)
1105: return \"move%.l %1,%0\";
1106: if (GET_CODE (operands[1]) == MEM)
1107: operands[1] = adj_offsettable_operand (operands[1], 1);
1108: return \"move%.b %1,%0\";
1109: }")
1110:
1111: (define_insn "truncsihi2"
1112: [(set (match_operand:HI 0 "general_operand" "=dm,d")
1113: (truncate:HI
1114: (match_operand:SI 1 "general_operand" "roJ,i")))]
1115: ""
1116: "*
1117: {
1118: if (GET_CODE (operands[0]) == REG)
1119: return \"move%.l %1,%0\";
1120: if (GET_CODE (operands[1]) == MEM)
1121: operands[1] = adj_offsettable_operand (operands[1], 2);
1122: return \"move%.w %1,%0\";
1123: }")
1124:
1125: ;; zero extension instructions
1126:
1127: (define_expand "zero_extendhisi2"
1128: [(set (match_operand:SI 0 "register_operand" "")
1129: (const_int 0))
1130: (set (strict_low_part (subreg:HI (match_dup 0) 0))
1131: (match_operand:HI 1 "general_operand" ""))]
1132: ""
1133: "operands[1] = make_safe_from (operands[1], operands[0]);")
1134:
1135: (define_expand "zero_extendqihi2"
1136: [(set (match_operand:HI 0 "register_operand" "")
1137: (const_int 0))
1138: (set (strict_low_part (subreg:QI (match_dup 0) 0))
1139: (match_operand:QI 1 "general_operand" ""))]
1140: ""
1141: "operands[1] = make_safe_from (operands[1], operands[0]);")
1142:
1143: (define_expand "zero_extendqisi2"
1144: [(set (match_operand:SI 0 "register_operand" "")
1145: (const_int 0))
1146: (set (strict_low_part (subreg:QI (match_dup 0) 0))
1147: (match_operand:QI 1 "general_operand" ""))]
1148: ""
1149: " operands[1] = make_safe_from (operands[1], operands[0]); ")
1150:
1151: ;; Patterns to recognize zero-extend insns produced by the combiner.
1152:
1153: ;; Note that the one starting from HImode comes before those for QImode
1154: ;; so that a constant operand will match HImode, not QImode.
1155: (define_insn ""
1156: [(set (match_operand:SI 0 "general_operand" "=do<>")
1157: (zero_extend:SI
1158: (match_operand:HI 1 "general_operand" "rmn")))]
1159: ""
1160: "*
1161: {
1162: if (DATA_REG_P (operands[0]))
1163: {
1164: if (GET_CODE (operands[1]) == REG
1165: && REGNO (operands[0]) == REGNO (operands[1]))
1166: return \"and%.l %#0xFFFF,%0\";
1167: if (reg_mentioned_p (operands[0], operands[1]))
1168: return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\";
1169: return \"clr%.l %0\;move%.w %1,%0\";
1170: }
1171: else if (GET_CODE (operands[0]) == MEM
1172: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1173: return \"move%.w %1,%0\;clr%.w %0\";
1174: else if (GET_CODE (operands[0]) == MEM
1175: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1176: return \"clr%.w %0\;move%.w %1,%0\";
1177: else
1178: {
1179: output_asm_insn (\"clr%.w %0\", operands);
1180: operands[0] = adj_offsettable_operand (operands[0], 2);
1181: return \"move%.w %1,%0\";
1182: }
1183: }")
1184:
1185: (define_insn ""
1186: [(set (match_operand:HI 0 "general_operand" "=do<>")
1187: (zero_extend:HI
1188: (match_operand:QI 1 "general_operand" "dmn")))]
1189: ""
1190: "*
1191: {
1192: if (DATA_REG_P (operands[0]))
1193: {
1194: if (GET_CODE (operands[1]) == REG
1195: && REGNO (operands[0]) == REGNO (operands[1]))
1196: return \"and%.w %#0xFF,%0\";
1197: if (reg_mentioned_p (operands[0], operands[1]))
1198: return \"move%.b %1,%0\;and%.w %#0xFF,%0\";
1199: return \"clr%.w %0\;move%.b %1,%0\";
1200: }
1201: else if (GET_CODE (operands[0]) == MEM
1202: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1203: {
1204: if (REGNO (XEXP (XEXP (operands[0], 0), 0))
1205: == STACK_POINTER_REGNUM)
1206: return \"clr%.w %-\;move%.b %1,%0\";
1207: else
1208: return \"move%.b %1,%0\;clr%.b %0\";
1209: }
1210: else if (GET_CODE (operands[0]) == MEM
1211: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1212: return \"clr%.b %0\;move%.b %1,%0\";
1213: else
1214: {
1215: output_asm_insn (\"clr%.b %0\", operands);
1216: operands[0] = adj_offsettable_operand (operands[0], 1);
1217: return \"move%.b %1,%0\";
1218: }
1219: }")
1220:
1221: (define_insn ""
1222: [(set (match_operand:SI 0 "general_operand" "=do<>")
1223: (zero_extend:SI
1224: (match_operand:QI 1 "general_operand" "dmn")))]
1225: ""
1226: "*
1227: {
1228: if (DATA_REG_P (operands[0]))
1229: {
1230: if (GET_CODE (operands[1]) == REG
1231: && REGNO (operands[0]) == REGNO (operands[1]))
1232: return \"and%.l %#0xFF,%0\";
1233: if (reg_mentioned_p (operands[0], operands[1]))
1234: return \"move%.b %1,%0\;and%.l %#0xFF,%0\";
1235: return \"clr%.l %0\;move%.b %1,%0\";
1236: }
1237: else if (GET_CODE (operands[0]) == MEM
1238: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1239: {
1240: operands[0] = XEXP (XEXP (operands[0], 0), 0);
1241: #ifdef MOTOROLA
1242: #ifdef SGS
1243: return \"clr.l -(%0)\;move%.b %1,3(%0)\";
1244: #else
1245: return \"clr.l -(%0)\;move%.b %1,(3,%0)\";
1246: #endif
1247: #else
1248: return \"clrl %0@-\;moveb %1,%0@(3)\";
1249: #endif
1250: }
1251: else if (GET_CODE (operands[0]) == MEM
1252: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1253: {
1254: operands[0] = XEXP (XEXP (operands[0], 0), 0);
1255: #ifdef MOTOROLA
1256: #ifdef SGS
1257: return \"clr.l (%0)+\;move%.b %1,-1(%0)\";
1258: #else
1259: return \"clr.l (%0)+\;move%.b %1,(-1,%0)\";
1260: #endif
1261: #else
1262: return \"clrl %0@+\;moveb %1,%0@(-1)\";
1263: #endif
1264: }
1265: else
1266: {
1267: output_asm_insn (\"clr%.l %0\", operands);
1268: operands[0] = adj_offsettable_operand (operands[0], 3);
1269: return \"move%.b %1,%0\";
1270: }
1271: }")
1272:
1273: ;; sign extension instructions
1274: ;; Note that the one starting from HImode comes before those for QImode
1275: ;; so that a constant operand will match HImode, not QImode.
1276:
1277: (define_insn "extendhisi2"
1278: [(set (match_operand:SI 0 "general_operand" "=*d,a")
1279: (sign_extend:SI
1280: (match_operand:HI 1 "general_operand" "0,rmn")))]
1281: ""
1282: "*
1283: {
1284: if (ADDRESS_REG_P (operands[0]))
1285: return \"move%.w %1,%0\";
1286: return \"ext%.l %0\";
1287: }")
1288:
1289: (define_insn "extendqihi2"
1290: [(set (match_operand:HI 0 "general_operand" "=d")
1291: (sign_extend:HI
1292: (match_operand:QI 1 "general_operand" "0")))]
1293: ""
1294: "ext%.w %0")
1295:
1296: (define_insn "extendqisi2"
1297: [(set (match_operand:SI 0 "general_operand" "=d")
1298: (sign_extend:SI
1299: (match_operand:QI 1 "general_operand" "0")))]
1300: "TARGET_68020"
1301: "extb%.l %0")
1302:
1303: ;; Conversions between float and double.
1304:
1305: (define_expand "extendsfdf2"
1306: [(set (match_operand:DF 0 "general_operand" "")
1307: (float_extend:DF
1308: (match_operand:SF 1 "general_operand" "")))]
1309: "TARGET_68881 || TARGET_FPA"
1310: "")
1311:
1312: (define_insn ""
1313: [(set (match_operand:DF 0 "general_operand" "=x,y")
1314: (float_extend:DF
1315: (match_operand:SF 1 "general_operand" "xH,rmF")))]
1316: "TARGET_FPA"
1317: "fpstod %w1,%0")
1318:
1319: (define_insn ""
1320: [(set (match_operand:DF 0 "general_operand" "=*fdm,f")
1321: (float_extend:DF
1322: (match_operand:SF 1 "general_operand" "f,dmF")))]
1323: "TARGET_68881"
1324: "*
1325: {
1326: if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1327: {
1328: if (REGNO (operands[0]) == REGNO (operands[1]))
1329: {
1330: /* Extending float to double in an fp-reg is a no-op.
1331: NOTICE_UPDATE_CC has already assumed that the
1332: cc will be set. So cancel what it did. */
1333: cc_status = cc_prev_status;
1334: return \"\";
1335: }
1336: return \"fmove%.x %1,%0\";
1337: }
1338: if (FP_REG_P (operands[0]))
1339: return \"fmove%.s %f1,%0\";
1340: if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
1341: {
1342: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
1343: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1344: return \"move%.l %+,%0\";
1345: }
1346: return \"fmove%.d %f1,%0\";
1347: }")
1348:
1349: ;; This cannot output into an f-reg because there is no way to be
1350: ;; sure of truncating in that case.
1351: ;; But on the Sun FPA, we can be sure.
1352: (define_expand "truncdfsf2"
1353: [(set (match_operand:SF 0 "general_operand" "")
1354: (float_truncate:SF
1355: (match_operand:DF 1 "general_operand" "")))]
1356: "TARGET_68881 || TARGET_FPA"
1357: "")
1358:
1359: (define_insn ""
1.1.1.2 ! root 1360: [(set (match_operand:SF 0 "general_operand" "=x,y")
1.1 root 1361: (float_truncate:SF
1362: (match_operand:DF 1 "general_operand" "xH,rmF")))]
1363: "TARGET_FPA"
1364: "fpdtos %y1,%0")
1365:
1366: (define_insn ""
1367: [(set (match_operand:SF 0 "general_operand" "=dm")
1368: (float_truncate:SF
1369: (match_operand:DF 1 "general_operand" "f")))]
1370: "TARGET_68881"
1371: "fmove%.s %f1,%0")
1372:
1373: ;; Conversion between fixed point and floating point.
1374: ;; Note that among the fix-to-float insns
1375: ;; the ones that start with SImode come first.
1376: ;; That is so that an operand that is a CONST_INT
1377: ;; (and therefore lacks a specific machine mode).
1378: ;; will be recognized as SImode (which is always valid)
1379: ;; rather than as QImode or HImode.
1380:
1381: (define_expand "floatsisf2"
1382: [(set (match_operand:SF 0 "general_operand" "")
1383: (float:SF (match_operand:SI 1 "general_operand" "")))]
1384: "TARGET_68881 || TARGET_FPA"
1385: "")
1386:
1387: (define_insn ""
1388: [(set (match_operand:SF 0 "general_operand" "=y,x")
1389: (float:SF (match_operand:SI 1 "general_operand" "rmi,x")))]
1390: "TARGET_FPA"
1391: "fpltos %1,%0")
1392:
1393: (define_insn ""
1394: [(set (match_operand:SF 0 "general_operand" "=f")
1395: (float:SF (match_operand:SI 1 "general_operand" "dmi")))]
1396: "TARGET_68881"
1397: "fmove%.l %1,%0")
1398:
1399: (define_expand "floatsidf2"
1400: [(set (match_operand:DF 0 "general_operand" "")
1401: (float:DF (match_operand:SI 1 "general_operand" "")))]
1402: "TARGET_68881 || TARGET_FPA"
1403: "")
1404:
1405: (define_insn ""
1.1.1.2 ! root 1406: [(set (match_operand:DF 0 "general_operand" "=y,x")
1.1 root 1407: (float:DF (match_operand:SI 1 "general_operand" "rmi,x")))]
1408: "TARGET_FPA"
1409: "fpltod %1,%0")
1410:
1411: (define_insn ""
1412: [(set (match_operand:DF 0 "general_operand" "=f")
1413: (float:DF (match_operand:SI 1 "general_operand" "dmi")))]
1414: "TARGET_68881"
1415: "fmove%.l %1,%0")
1416:
1417: (define_insn "floathisf2"
1418: [(set (match_operand:SF 0 "general_operand" "=f")
1419: (float:SF (match_operand:HI 1 "general_operand" "dmn")))]
1420: "TARGET_68881"
1421: "fmove%.w %1,%0")
1422:
1423: (define_insn "floathidf2"
1424: [(set (match_operand:DF 0 "general_operand" "=f")
1425: (float:DF (match_operand:HI 1 "general_operand" "dmn")))]
1426: "TARGET_68881"
1427: "fmove%.w %1,%0")
1428:
1429: (define_insn "floatqisf2"
1430: [(set (match_operand:SF 0 "general_operand" "=f")
1431: (float:SF (match_operand:QI 1 "general_operand" "dmn")))]
1432: "TARGET_68881"
1433: "fmove%.b %1,%0")
1434:
1435: (define_insn "floatqidf2"
1436: [(set (match_operand:DF 0 "general_operand" "=f")
1437: (float:DF (match_operand:QI 1 "general_operand" "dmn")))]
1438: "TARGET_68881"
1439: "fmove%.b %1,%0")
1440:
1441: ;; Convert a float to a float whose value is an integer.
1442: ;; This is the first stage of converting it to an integer type.
1443:
1444: (define_insn "ftruncdf2"
1445: [(set (match_operand:DF 0 "general_operand" "=f")
1446: (fix:DF (match_operand:DF 1 "general_operand" "fFm")))]
1447: "TARGET_68881"
1448: "*
1449: {
1450: if (FP_REG_P (operands[1]))
1451: return \"fintrz%.x %f1,%0\";
1452: return \"fintrz%.d %f1,%0\";
1453: }")
1454:
1455: (define_insn "ftruncsf2"
1456: [(set (match_operand:SF 0 "general_operand" "=f")
1457: (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))]
1458: "TARGET_68881"
1459: "*
1460: {
1461: if (FP_REG_P (operands[1]))
1462: return \"fintrz%.x %f1,%0\";
1463: return \"fintrz%.s %f1,%0\";
1464: }")
1465:
1466: ;; Convert a float whose value is an integer
1467: ;; to an actual integer. Second stage of converting float to integer type.
1468: (define_insn "fixsfqi2"
1469: [(set (match_operand:QI 0 "general_operand" "=dm")
1470: (fix:QI (match_operand:SF 1 "general_operand" "f")))]
1471: "TARGET_68881"
1472: "fmove%.b %1,%0")
1473:
1474: (define_insn "fixsfhi2"
1475: [(set (match_operand:HI 0 "general_operand" "=dm")
1476: (fix:HI (match_operand:SF 1 "general_operand" "f")))]
1477: "TARGET_68881"
1478: "fmove%.w %1,%0")
1479:
1480: (define_insn "fixsfsi2"
1481: [(set (match_operand:SI 0 "general_operand" "=dm")
1482: (fix:SI (match_operand:SF 1 "general_operand" "f")))]
1483: "TARGET_68881"
1484: "fmove%.l %1,%0")
1485:
1486: (define_insn "fixdfqi2"
1487: [(set (match_operand:QI 0 "general_operand" "=dm")
1488: (fix:QI (match_operand:DF 1 "general_operand" "f")))]
1489: "TARGET_68881"
1490: "fmove%.b %1,%0")
1491:
1492: (define_insn "fixdfhi2"
1493: [(set (match_operand:HI 0 "general_operand" "=dm")
1494: (fix:HI (match_operand:DF 1 "general_operand" "f")))]
1495: "TARGET_68881"
1496: "fmove%.w %1,%0")
1497:
1498: (define_insn "fixdfsi2"
1499: [(set (match_operand:SI 0 "general_operand" "=dm")
1500: (fix:SI (match_operand:DF 1 "general_operand" "f")))]
1501: "TARGET_68881"
1502: "fmove%.l %1,%0")
1503:
1504: ;; Convert a float to an integer.
1505: ;; On the Sun FPA, this is done in one step.
1506:
1507: (define_insn "fix_truncsfsi2"
1508: [(set (match_operand:SI 0 "general_operand" "=x,y")
1509: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "xH,rmF"))))]
1510: "TARGET_FPA"
1511: "fpstol %w1,%0")
1512:
1513: (define_insn "fix_truncdfsi2"
1514: [(set (match_operand:SI 0 "general_operand" "=x,y")
1515: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "xH,rmF"))))]
1516: "TARGET_FPA"
1517: "fpdtol %y1,%0")
1518:
1519: ;; add instructions
1520:
1521: ;; Note that the last two alternatives are near-duplicates
1522: ;; in order to handle insns generated by reload.
1523: ;; This is needed since they are not themselves reloaded,
1524: ;; so commutativity won't apply to them.
1525: (define_insn "addsi3"
1526: [(set (match_operand:SI 0 "general_operand" "=m,r,!a,!a")
1527: (plus:SI (match_operand:SI 1 "general_operand" "%0,0,a,rJK")
1528: (match_operand:SI 2 "general_operand" "dIKLs,mrIKLs,rJK,a")))]
1529: ""
1530: "*
1531: {
1532: if (! operands_match_p (operands[0], operands[1]))
1533: {
1534: if (!ADDRESS_REG_P (operands[1]))
1535: {
1536: rtx tmp = operands[1];
1537:
1538: operands[1] = operands[2];
1539: operands[2] = tmp;
1540: }
1541:
1542: /* These insns can result from reloads to access
1543: stack slots over 64k from the frame pointer. */
1544: if (GET_CODE (operands[2]) == CONST_INT
1545: && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
1546: return \"move%.l %2,%0\;add%.l %1,%0\";
1547: #ifdef SGS
1548: if (GET_CODE (operands[2]) == REG)
1549: return \"lea 0(%1,%2.l),%0\";
1550: else
1551: return \"lea %c2(%1),%0\";
1552: #else /* not SGS */
1553: #ifdef MOTOROLA
1554: if (GET_CODE (operands[2]) == REG)
1555: return \"lea (%1,%2.l),%0\";
1556: else
1557: return \"lea (%c2,%1),%0\";
1558: #else /* not MOTOROLA (MIT syntax) */
1559: if (GET_CODE (operands[2]) == REG)
1560: return \"lea %1@(0,%2:l),%0\";
1561: else
1562: return \"lea %1@(%c2),%0\";
1563: #endif /* not MOTOROLA */
1564: #endif /* not SGS */
1565: }
1566: if (GET_CODE (operands[2]) == CONST_INT)
1567: {
1568: #ifndef NO_ADDSUB_Q
1569: if (INTVAL (operands[2]) > 0
1570: && INTVAL (operands[2]) <= 8)
1571: return (ADDRESS_REG_P (operands[0])
1572: ? \"addq%.w %2,%0\"
1573: : \"addq%.l %2,%0\");
1574: if (INTVAL (operands[2]) < 0
1575: && INTVAL (operands[2]) >= -8)
1576: {
1577: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1578: - INTVAL (operands[2]));
1579: return (ADDRESS_REG_P (operands[0])
1580: ? \"subq%.w %2,%0\"
1581: : \"subq%.l %2,%0\");
1582: }
1583: #endif
1584: if (ADDRESS_REG_P (operands[0])
1585: && INTVAL (operands[2]) >= -0x8000
1586: && INTVAL (operands[2]) < 0x8000)
1587: return \"add%.w %2,%0\";
1588: }
1589: return \"add%.l %2,%0\";
1590: }")
1591:
1592: (define_insn ""
1593: [(set (match_operand:SI 0 "general_operand" "=a")
1594: (plus:SI (match_operand:SI 1 "general_operand" "0")
1595: (sign_extend:SI (match_operand:HI 2 "general_operand" "rmn"))))]
1596: ""
1597: "add%.w %2,%0")
1598:
1599: (define_insn "addhi3"
1600: [(set (match_operand:HI 0 "general_operand" "=m,r")
1601: (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
1602: (match_operand:HI 2 "general_operand" "dn,rmn")))]
1603: ""
1604: "*
1605: {
1606: #ifndef NO_ADDSUB_Q
1607: if (GET_CODE (operands[2]) == CONST_INT)
1608: {
1609: if (INTVAL (operands[2]) > 0
1610: && INTVAL (operands[2]) <= 8)
1611: return \"addq%.w %2,%0\";
1612: }
1613: if (GET_CODE (operands[2]) == CONST_INT)
1614: {
1615: if (INTVAL (operands[2]) < 0
1616: && INTVAL (operands[2]) >= -8)
1617: {
1618: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1619: - INTVAL (operands[2]));
1620: return \"subq%.w %2,%0\";
1621: }
1622: }
1623: #endif
1624: return \"add%.w %2,%0\";
1625: }")
1626:
1627: (define_insn ""
1628: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
1629: (plus:HI (match_dup 0)
1630: (match_operand:HI 1 "general_operand" "dn,rmn")))]
1631: ""
1632: "add%.w %1,%0")
1633:
1634: (define_insn "addqi3"
1635: [(set (match_operand:QI 0 "general_operand" "=m,d")
1636: (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
1637: (match_operand:QI 2 "general_operand" "dn,dmn")))]
1638: ""
1639: "*
1640: {
1641: #ifndef NO_ADDSUB_Q
1642: if (GET_CODE (operands[2]) == CONST_INT)
1643: {
1644: if (INTVAL (operands[2]) > 0
1645: && INTVAL (operands[2]) <= 8)
1646: return \"addq%.b %2,%0\";
1647: }
1648: if (GET_CODE (operands[2]) == CONST_INT)
1649: {
1650: if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
1651: {
1652: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1653: return \"subq%.b %2,%0\";
1654: }
1655: }
1656: #endif
1657: return \"add%.b %2,%0\";
1658: }")
1659:
1660: (define_insn ""
1661: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
1662: (plus:QI (match_dup 0)
1663: (match_operand:QI 1 "general_operand" "dn,dmn")))]
1664: ""
1665: "add%.b %1,%0")
1666:
1667: (define_expand "adddf3"
1668: [(set (match_operand:DF 0 "general_operand" "")
1669: (plus:DF (match_operand:DF 1 "general_operand" "")
1670: (match_operand:DF 2 "general_operand" "")))]
1671: "TARGET_68881 || TARGET_FPA"
1672: "")
1673:
1674: (define_insn ""
1675: [(set (match_operand:DF 0 "general_operand" "=x,y")
1676: (plus:DF (match_operand:DF 1 "general_operand" "%xH,y")
1677: (match_operand:DF 2 "general_operand" "xH,dmF")))]
1678: "TARGET_FPA"
1679: "*
1680: {
1681: if (rtx_equal_p (operands[0], operands[1]))
1682: return \"fpadd%.d %y2,%0\";
1683: if (rtx_equal_p (operands[0], operands[2]))
1684: return \"fpadd%.d %y1,%0\";
1685: if (which_alternative == 0)
1686: return \"fpadd3%.d %w2,%w1,%0\";
1687: return \"fpadd3%.d %x2,%x1,%0\";
1688: }")
1689:
1690: (define_insn ""
1691: [(set (match_operand:DF 0 "general_operand" "=f")
1692: (plus:DF (match_operand:DF 1 "general_operand" "%0")
1693: (match_operand:DF 2 "general_operand" "fmG")))]
1694: "TARGET_68881"
1695: "*
1696: {
1697: if (REG_P (operands[2]))
1698: return \"fadd%.x %2,%0\";
1699: return \"fadd%.d %f2,%0\";
1700: }")
1701:
1702: (define_expand "addsf3"
1703: [(set (match_operand:SF 0 "general_operand" "")
1704: (plus:SF (match_operand:SF 1 "general_operand" "")
1705: (match_operand:SF 2 "general_operand" "")))]
1706: "TARGET_68881 || TARGET_FPA"
1707: "")
1708:
1709: (define_insn ""
1710: [(set (match_operand:SF 0 "general_operand" "=x,y")
1711: (plus:SF (match_operand:SF 1 "general_operand" "%xH,y")
1712: (match_operand:SF 2 "general_operand" "xH,rmF")))]
1713: "TARGET_FPA"
1714: "*
1715: {
1716: if (rtx_equal_p (operands[0], operands[1]))
1717: return \"fpadd%.s %w2,%0\";
1718: if (rtx_equal_p (operands[0], operands[2]))
1719: return \"fpadd%.s %w1,%0\";
1720: if (which_alternative == 0)
1721: return \"fpadd3%.s %w2,%w1,%0\";
1722: return \"fpadd3%.s %2,%1,%0\";
1723: }")
1724:
1725: (define_insn ""
1726: [(set (match_operand:SF 0 "general_operand" "=f")
1727: (plus:SF (match_operand:SF 1 "general_operand" "%0")
1728: (match_operand:SF 2 "general_operand" "fdmF")))]
1729: "TARGET_68881"
1730: "*
1731: {
1732: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
1733: return \"fadd%.x %2,%0\";
1734: return \"fadd%.s %f2,%0\";
1735: }")
1736:
1737: ;; subtract instructions
1738:
1739: (define_insn "subsi3"
1740: [(set (match_operand:SI 0 "general_operand" "=m,r,!a,?d")
1741: (minus:SI (match_operand:SI 1 "general_operand" "0,0,a,mrIKs")
1742: (match_operand:SI 2 "general_operand" "dIKs,mrIKs,J,0")))]
1743: ""
1744: "*
1745: {
1746: if (! operands_match_p (operands[0], operands[1]))
1747: {
1748: if (operands_match_p (operands[0], operands[2]))
1749: {
1750: #ifndef NO_ADDSUB_Q
1751: if (GET_CODE (operands[1]) == CONST_INT)
1752: {
1753: if (INTVAL (operands[1]) > 0
1754: && INTVAL (operands[1]) <= 8)
1755: return \"subq%.l %1,%0\;neg%.l %0\";
1756: }
1757: #endif
1758: return \"sub%.l %1,%0\;neg%.l %0\";
1759: }
1760: /* This case is matched by J, but negating -0x8000
1761: in an lea would give an invalid displacement.
1762: So do this specially. */
1763: if (INTVAL (operands[2]) == -0x8000)
1764: return \"move%.l %1,%0\;sub%.l %2,%0\";
1765: #ifdef SGS
1766: return \"lea %n2(%1),%0\";
1767: #else
1768: #ifdef MOTOROLA
1769: return \"lea (%n2,%1),%0\";
1770: #else /* not MOTOROLA (MIT syntax) */
1771: return \"lea %1@(%n2),%0\";
1772: #endif /* not MOTOROLA */
1773: #endif /* not SGS */
1774: }
1775: if (GET_CODE (operands[2]) == CONST_INT)
1776: {
1777: #ifndef NO_ADDSUB_Q
1778: if (INTVAL (operands[2]) > 0
1779: && INTVAL (operands[2]) <= 8)
1780: return \"subq%.l %2,%0\";
1781: #endif
1782: if (ADDRESS_REG_P (operands[0])
1783: && INTVAL (operands[2]) >= -0x8000
1784: && INTVAL (operands[2]) < 0x8000)
1785: return \"sub%.w %2,%0\";
1786: }
1787: return \"sub%.l %2,%0\";
1788: }")
1789:
1790: (define_insn ""
1791: [(set (match_operand:SI 0 "general_operand" "=a")
1792: (minus:SI (match_operand:SI 1 "general_operand" "0")
1793: (sign_extend:SI (match_operand:HI 2 "general_operand" "rmn"))))]
1794: ""
1795: "sub%.w %2,%0")
1796:
1797: (define_insn "subhi3"
1798: [(set (match_operand:HI 0 "general_operand" "=m,r")
1799: (minus:HI (match_operand:HI 1 "general_operand" "0,0")
1800: (match_operand:HI 2 "general_operand" "dn,rmn")))]
1801: ""
1802: "sub%.w %2,%0")
1803:
1804: (define_insn ""
1805: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
1806: (minus:HI (match_dup 0)
1807: (match_operand:HI 1 "general_operand" "dn,rmn")))]
1808: ""
1809: "sub%.w %1,%0")
1810:
1811: (define_insn "subqi3"
1812: [(set (match_operand:QI 0 "general_operand" "=m,d")
1813: (minus:QI (match_operand:QI 1 "general_operand" "0,0")
1814: (match_operand:QI 2 "general_operand" "dn,dmn")))]
1815: ""
1816: "sub%.b %2,%0")
1817:
1818: (define_insn ""
1819: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
1820: (minus:QI (match_dup 0)
1821: (match_operand:QI 1 "general_operand" "dn,dmn")))]
1822: ""
1823: "sub%.b %1,%0")
1824:
1825: (define_expand "subdf3"
1826: [(set (match_operand:DF 0 "general_operand" "")
1827: (minus:DF (match_operand:DF 1 "general_operand" "")
1828: (match_operand:DF 2 "general_operand" "")))]
1829: "TARGET_68881 || TARGET_FPA"
1830: "")
1831:
1832: (define_insn ""
1833: [(set (match_operand:DF 0 "general_operand" "=x,y,y")
1834: (minus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF")
1835: (match_operand:DF 2 "general_operand" "xH,dmF,0")))]
1836: "TARGET_FPA"
1837: "*
1838: {
1839: if (rtx_equal_p (operands[0], operands[2]))
1840: return \"fprsub%.d %y1,%0\";
1841: if (rtx_equal_p (operands[0], operands[1]))
1842: return \"fpsub%.d %y2,%0\";
1843: if (which_alternative == 0)
1844: return \"fpsub3%.d %w2,%w1,%0\";
1845: return \"fpsub3%.d %x2,%x1,%0\";
1846: }")
1847:
1848: (define_insn ""
1849: [(set (match_operand:DF 0 "general_operand" "=f")
1850: (minus:DF (match_operand:DF 1 "general_operand" "0")
1851: (match_operand:DF 2 "general_operand" "fmG")))]
1852: "TARGET_68881"
1853: "*
1854: {
1855: if (REG_P (operands[2]))
1856: return \"fsub%.x %2,%0\";
1857: return \"fsub%.d %f2,%0\";
1858: }")
1859:
1860: (define_expand "subsf3"
1861: [(set (match_operand:SF 0 "general_operand" "")
1862: (minus:SF (match_operand:SF 1 "general_operand" "")
1863: (match_operand:SF 2 "general_operand" "")))]
1864: "TARGET_68881 || TARGET_FPA"
1865: "")
1866:
1867: (define_insn ""
1868: [(set (match_operand:SF 0 "general_operand" "=x,y,y")
1869: (minus:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
1870: (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
1871: "TARGET_FPA"
1872: "*
1873: {
1874: if (rtx_equal_p (operands[0], operands[2]))
1875: return \"fprsub%.s %w1,%0\";
1876: if (rtx_equal_p (operands[0], operands[1]))
1877: return \"fpsub%.s %w2,%0\";
1878: if (which_alternative == 0)
1879: return \"fpsub3%.s %w2,%w1,%0\";
1880: return \"fpsub3%.s %2,%1,%0\";
1881: }")
1882:
1883: (define_insn ""
1884: [(set (match_operand:SF 0 "general_operand" "=f")
1885: (minus:SF (match_operand:SF 1 "general_operand" "0")
1886: (match_operand:SF 2 "general_operand" "fdmF")))]
1887: "TARGET_68881"
1888: "*
1889: {
1890: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
1891: return \"fsub%.x %2,%0\";
1892: return \"fsub%.s %f2,%0\";
1893: }")
1894:
1895: ;; multiply instructions
1896:
1897: (define_insn "mulhi3"
1898: [(set (match_operand:HI 0 "general_operand" "=d")
1899: (mult:HI (match_operand:HI 1 "general_operand" "%0")
1900: (match_operand:HI 2 "general_operand" "dmn")))]
1901: ""
1902: "*
1903: {
1904: #ifdef MOTOROLA
1905: return \"muls.w %2,%0\";
1906: #else
1907: return \"muls %2,%0\";
1908: #endif
1909: }")
1910:
1911: (define_insn "mulhisi3"
1912: [(set (match_operand:SI 0 "general_operand" "=d")
1913: (mult:SI (match_operand:HI 1 "general_operand" "%0")
1914: (match_operand:HI 2 "general_operand" "dmn")))]
1915: ""
1916: "*
1917: {
1918: #ifdef MOTOROLA
1919: return \"muls.w %2,%0\";
1920: #else
1921: return \"muls %2,%0\";
1922: #endif
1923: }")
1924:
1925: (define_insn "mulsi3"
1926: [(set (match_operand:SI 0 "general_operand" "=d")
1927: (mult:SI (match_operand:SI 1 "general_operand" "%0")
1928: (match_operand:SI 2 "general_operand" "dmsK")))]
1929: "TARGET_68020"
1930: "muls%.l %2,%0")
1931:
1932: (define_insn "umulhi3"
1933: [(set (match_operand:HI 0 "general_operand" "=d")
1934: (umult:HI (match_operand:HI 1 "general_operand" "%0")
1935: (match_operand:HI 2 "general_operand" "dmn")))]
1936: ""
1937: "*
1938: {
1939: #ifdef MOTOROLA
1940: return \"mulu.w %2,%0\";
1941: #else
1942: return \"mulu %2,%0\";
1943: #endif
1944: }")
1945:
1946: (define_insn "umulhisi3"
1947: [(set (match_operand:SI 0 "general_operand" "=d")
1948: (umult:SI (match_operand:HI 1 "general_operand" "%0")
1949: (match_operand:HI 2 "general_operand" "dmn")))]
1950: ""
1951: "*
1952: {
1953: #ifdef MOTOROLA
1954: return \"mulu.w %2,%0\";
1955: #else
1956: return \"mulu %2,%0\";
1957: #endif
1958: }")
1959:
1960: (define_insn "umulsi3"
1961: [(set (match_operand:SI 0 "general_operand" "=d")
1962: (umult:SI (match_operand:SI 1 "general_operand" "%0")
1963: (match_operand:SI 2 "general_operand" "dmsK")))]
1964: "TARGET_68020"
1965: "mulu%.l %2,%0")
1966:
1967: (define_expand "muldf3"
1968: [(set (match_operand:DF 0 "general_operand" "")
1969: (mult:DF (match_operand:DF 1 "general_operand" "")
1970: (match_operand:DF 2 "general_operand" "")))]
1971: "TARGET_68881 || TARGET_FPA"
1972: "")
1973:
1974: (define_insn ""
1975: [(set (match_operand:DF 0 "general_operand" "=x,y")
1976: (mult:DF (match_operand:DF 1 "general_operand" "%xH,y")
1977: (match_operand:DF 2 "general_operand" "xH,rmF")))]
1978: "TARGET_FPA"
1979: "*
1980: {
1981: if (rtx_equal_p (operands[1], operands[2]))
1982: return \"fpsqr%.d %y1,%0\";
1983: if (rtx_equal_p (operands[0], operands[1]))
1984: return \"fpmul%.d %y2,%0\";
1985: if (rtx_equal_p (operands[0], operands[2]))
1986: return \"fpmul%.d %y1,%0\";
1987: if (which_alternative == 0)
1988: return \"fpmul3%.d %w2,%w1,%0\";
1989: return \"fpmul3%.d %x2,%x1,%0\";
1990: }")
1991:
1992: (define_insn ""
1993: [(set (match_operand:DF 0 "general_operand" "=f")
1994: (mult:DF (match_operand:DF 1 "general_operand" "%0")
1995: (match_operand:DF 2 "general_operand" "fmG")))]
1996: "TARGET_68881"
1997: "*
1998: {
1999: if (REG_P (operands[2]))
2000: return \"fmul%.x %2,%0\";
2001: return \"fmul%.d %f2,%0\";
2002: }")
2003:
2004: (define_expand "mulsf3"
2005: [(set (match_operand:SF 0 "general_operand" "")
2006: (mult:SF (match_operand:SF 1 "general_operand" "")
2007: (match_operand:SF 2 "general_operand" "")))]
2008: "TARGET_68881 || TARGET_FPA"
2009: "")
2010:
2011: (define_insn ""
2012: [(set (match_operand:SF 0 "general_operand" "=x,y")
2013: (mult:SF (match_operand:SF 1 "general_operand" "%xH,y")
2014: (match_operand:SF 2 "general_operand" "xH,rmF")))]
2015: "TARGET_FPA"
2016: "*
2017: {
2018: if (rtx_equal_p (operands[1], operands[2]))
2019: return \"fpsqr%.s %w1,%0\";
2020: if (rtx_equal_p (operands[0], operands[1]))
2021: return \"fpmul%.s %w2,%0\";
2022: if (rtx_equal_p (operands[0], operands[2]))
2023: return \"fpmul%.s %w1,%0\";
2024: if (which_alternative == 0)
2025: return \"fpmul3%.s %w2,%w1,%0\";
2026: return \"fpmul3%.s %2,%1,%0\";
2027: }")
2028:
2029: (define_insn ""
2030: [(set (match_operand:SF 0 "general_operand" "=f")
2031: (mult:SF (match_operand:SF 1 "general_operand" "%0")
2032: (match_operand:SF 2 "general_operand" "fdmF")))]
2033: "TARGET_68881"
2034: "*
2035: {
2036: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2037: return \"fsglmul%.x %2,%0\";
2038: return \"fsglmul%.s %f2,%0\";
2039: }")
2040:
2041: ;; divide instructions
2042:
2043: (define_insn "divhi3"
2044: [(set (match_operand:HI 0 "general_operand" "=d")
2045: (div:HI (match_operand:HI 1 "general_operand" "0")
2046: (match_operand:HI 2 "general_operand" "dmn")))]
2047: ""
2048: "*
2049: {
2050: #ifdef MOTOROLA
2051: return \"ext.l %0\;divs.w %2,%0\";
2052: #else
2053: return \"extl %0\;divs %2,%0\";
2054: #endif
2055: }")
2056:
2057: (define_insn "divhisi3"
2058: [(set (match_operand:HI 0 "general_operand" "=d")
2059: (div:HI (match_operand:SI 1 "general_operand" "0")
2060: (match_operand:HI 2 "general_operand" "dmn")))]
2061: ""
2062: "*
2063: {
2064: #ifdef MOTOROLA
2065: return \"divs.w %2,%0\";
2066: #else
2067: return \"divs %2,%0\";
2068: #endif
2069: }")
2070:
2071: (define_insn "divsi3"
2072: [(set (match_operand:SI 0 "general_operand" "=d")
2073: (div:SI (match_operand:SI 1 "general_operand" "0")
2074: (match_operand:SI 2 "general_operand" "dmsK")))]
2075: "TARGET_68020"
2076: "divs%.l %2,%0")
2077:
2078: (define_insn "udivhi3"
2079: [(set (match_operand:HI 0 "general_operand" "=d")
2080: (udiv:HI (match_operand:HI 1 "general_operand" "0")
2081: (match_operand:HI 2 "general_operand" "dmn")))]
2082: ""
2083: "*
2084: {
2085: #ifdef MOTOROLA
2086: return \"and.l %#0xFFFF,%0\;divu.w %2,%0\";
2087: #else
2088: return \"andl %#0xFFFF,%0\;divu %2,%0\";
2089: #endif
2090: }")
2091:
2092: (define_insn "udivhisi3"
2093: [(set (match_operand:HI 0 "general_operand" "=d")
2094: (udiv:HI (match_operand:SI 1 "general_operand" "0")
2095: (match_operand:HI 2 "general_operand" "dmn")))]
2096: ""
2097: "*
2098: {
2099: #ifdef MOTOROLA
2100: return \"divu.w %2,%0\";
2101: #else
2102: return \"divu %2,%0\";
2103: #endif
2104: }")
2105:
2106: (define_insn "udivsi3"
2107: [(set (match_operand:SI 0 "general_operand" "=d")
2108: (udiv:SI (match_operand:SI 1 "general_operand" "0")
2109: (match_operand:SI 2 "general_operand" "dmsK")))]
2110: "TARGET_68020"
2111: "divu%.l %2,%0")
2112:
2113: (define_expand "divdf3"
2114: [(set (match_operand:DF 0 "general_operand" "")
2115: (div:DF (match_operand:DF 1 "general_operand" "")
2116: (match_operand:DF 2 "general_operand" "")))]
2117: "TARGET_68881 || TARGET_FPA"
2118: "")
2119:
2120: (define_insn ""
2121: [(set (match_operand:DF 0 "general_operand" "=x,y,y")
2122: (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF")
2123: (match_operand:DF 2 "general_operand" "xH,rmF,0")))]
2124: "TARGET_FPA"
2125: "*
2126: {
2127: if (rtx_equal_p (operands[0], operands[2]))
2128: return \"fprdiv%.d %y1,%0\";
2129: if (rtx_equal_p (operands[0], operands[1]))
2130: return \"fpdiv%.d %y2,%0\";
2131: if (which_alternative == 0)
2132: return \"fpdiv3%.d %w2,%w1,%0\";
2133: return \"fpdiv3%.d %x2,%x1,%x0\";
2134: }")
2135:
2136: (define_insn ""
2137: [(set (match_operand:DF 0 "general_operand" "=f")
2138: (div:DF (match_operand:DF 1 "general_operand" "0")
2139: (match_operand:DF 2 "general_operand" "fmG")))]
2140: "TARGET_68881"
2141: "*
2142: {
2143: if (REG_P (operands[2]))
2144: return \"fdiv%.x %2,%0\";
2145: return \"fdiv%.d %f2,%0\";
2146: }")
2147:
2148: (define_expand "divsf3"
2149: [(set (match_operand:SF 0 "general_operand" "")
2150: (div:SF (match_operand:SF 1 "general_operand" "")
2151: (match_operand:SF 2 "general_operand" "")))]
2152: "TARGET_68881 || TARGET_FPA"
2153: "")
2154:
2155: (define_insn ""
2156: [(set (match_operand:SF 0 "general_operand" "=x,y,y")
2157: (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF")
2158: (match_operand:SF 2 "general_operand" "xH,rmF,0")))]
2159: "TARGET_FPA"
2160: "*
2161: {
2162: if (rtx_equal_p (operands[0], operands[1]))
2163: return \"fpdiv%.s %w2,%0\";
2164: if (rtx_equal_p (operands[0], operands[2]))
2165: return \"fprdiv%.s %w1,%0\";
2166: if (which_alternative == 0)
2167: return \"fpdiv3%.s %w2,%w1,%0\";
2168: return \"fpdiv3%.s %2,%1,%0\";
2169: }")
2170:
2171: (define_insn ""
2172: [(set (match_operand:SF 0 "general_operand" "=f")
2173: (div:SF (match_operand:SF 1 "general_operand" "0")
2174: (match_operand:SF 2 "general_operand" "fdmF")))]
2175: "TARGET_68881"
2176: "*
2177: {
2178: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2]))
2179: return \"fsgldiv%.x %2,%0\";
2180: return \"fsgldiv%.s %f2,%0\";
2181: }")
2182:
2183: ;; Remainder instructions.
2184:
2185: (define_insn "modhi3"
2186: [(set (match_operand:HI 0 "general_operand" "=d")
2187: (mod:HI (match_operand:HI 1 "general_operand" "0")
2188: (match_operand:HI 2 "general_operand" "dmn")))]
2189: ""
2190: "*
2191: {
2192: /* The swap insn produces cc's that don't correspond to the result. */
2193: CC_STATUS_INIT;
2194: #ifdef MOTOROLA
2195: #ifdef SGS_3B1
2196: return \"ext.l %0\;divs.w %2,%0\;swap.w %0\";
2197: #else
2198: return \"ext.l %0\;divs.w %2,%0\;swap %0\";
2199: #endif
2200: #else
2201: return \"extl %0\;divs %2,%0\;swap %0\";
2202: #endif
2203: }")
2204:
2205: (define_insn "modhisi3"
2206: [(set (match_operand:HI 0 "general_operand" "=d")
2207: (mod:HI (match_operand:SI 1 "general_operand" "0")
2208: (match_operand:HI 2 "general_operand" "dmn")))]
2209: ""
2210: "*
2211: {
2212: /* The swap insn produces cc's that don't correspond to the result. */
2213: CC_STATUS_INIT;
2214: #ifdef MOTOROLA
2215: #ifdef SGS_3B1
2216: return \"divs.w %2,%0\;swap.w %0\";
2217: #else
2218: return \"divs.w %2,%0\;swap %0\";
2219: #endif
2220: #else
2221: return \"divs %2,%0\;swap %0\";
2222: #endif
2223: }")
2224:
2225: (define_insn "umodhi3"
2226: [(set (match_operand:HI 0 "general_operand" "=d")
2227: (umod:HI (match_operand:HI 1 "general_operand" "0")
2228: (match_operand:HI 2 "general_operand" "dmn")))]
2229: ""
2230: "*
2231: {
2232: /* The swap insn produces cc's that don't correspond to the result. */
2233: CC_STATUS_INIT;
2234: #ifdef MOTOROLA
2235: #ifdef SGS_3B1
2236: return \"and.l %#0xFFFF,%0\;divu.w %2,%0\;swap.w %0\";
2237: #else
2238: return \"and.l %#0xFFFF,%0\;divu.w %2,%0\;swap %0\";
2239: #endif
2240: #else
2241: return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\";
2242: #endif
2243: }")
2244:
2245: (define_insn "umodhisi3"
2246: [(set (match_operand:HI 0 "general_operand" "=d")
2247: (umod:HI (match_operand:SI 1 "general_operand" "0")
2248: (match_operand:HI 2 "general_operand" "dmn")))]
2249: ""
2250: "*
2251: {
2252: /* The swap insn produces cc's that don't correspond to the result. */
2253: CC_STATUS_INIT;
2254: #ifdef MOTOROLA
2255: #ifdef SGS_3B1
2256: return \"divu.w %2,%0\;swap.w %0\";
2257: #else
2258: return \"divu.w %2,%0\;swap %0\";
2259: #endif
2260: #else
2261: return \"divu %2,%0\;swap %0\";
2262: #endif
2263: }")
2264:
2265: (define_insn "divmodsi4"
2266: [(set (match_operand:SI 0 "general_operand" "=d")
2267: (div:SI (match_operand:SI 1 "general_operand" "0")
2268: (match_operand:SI 2 "general_operand" "dmsK")))
2269: (set (match_operand:SI 3 "general_operand" "=d")
2270: (mod:SI (match_dup 1) (match_dup 2)))]
2271: "TARGET_68020"
2272: "divsl%.l %2,%3:%0")
2273:
2274: (define_insn "udivmodsi4"
2275: [(set (match_operand:SI 0 "general_operand" "=d")
2276: (udiv:SI (match_operand:SI 1 "general_operand" "0")
2277: (match_operand:SI 2 "general_operand" "dmsK")))
2278: (set (match_operand:SI 3 "general_operand" "=d")
2279: (umod:SI (match_dup 1) (match_dup 2)))]
2280: "TARGET_68020"
2281: "divul%.l %2,%3:%0")
2282:
2283: ;; logical-and instructions
2284:
2285: (define_insn "andsi3"
2286: [(set (match_operand:SI 0 "general_operand" "=m,d")
2287: (and:SI (match_operand:SI 1 "general_operand" "%0,0")
2288: (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
2289: ""
2290: "*
2291: {
2292: if (GET_CODE (operands[2]) == CONST_INT
2293: && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
2294: && (DATA_REG_P (operands[0])
2295: || offsettable_memref_p (operands[0])))
2296: {
2297: if (GET_CODE (operands[0]) != REG)
2298: operands[0] = adj_offsettable_operand (operands[0], 2);
2299: operands[2] = gen_rtx (CONST_INT, VOIDmode,
2300: INTVAL (operands[2]) & 0xffff);
2301: /* Do not delete a following tstl %0 insn; that would be incorrect. */
2302: CC_STATUS_INIT;
2303: if (operands[2] == const0_rtx)
2304: return \"clr%.w %0\";
2305: return \"and%.w %2,%0\";
2306: }
2307: return \"and%.l %2,%0\";
2308: }")
2309:
2310: (define_insn "andhi3"
2311: [(set (match_operand:HI 0 "general_operand" "=m,d")
2312: (and:HI (match_operand:HI 1 "general_operand" "%0,0")
2313: (match_operand:HI 2 "general_operand" "dn,dmn")))]
2314: ""
2315: "and%.w %2,%0")
2316:
2317: (define_insn "andqi3"
2318: [(set (match_operand:QI 0 "general_operand" "=m,d")
2319: (and:QI (match_operand:QI 1 "general_operand" "%0,0")
2320: (match_operand:QI 2 "general_operand" "dn,dmn")))]
2321: ""
2322: "and%.b %2,%0")
2323:
2324: (define_insn ""
2325: [(set (match_operand:SI 0 "general_operand" "=d")
2326: (and:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "dm"))
2327: (match_operand:SI 2 "general_operand" "0")))]
2328: "GET_CODE (operands[2]) == CONST_INT
2329: && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
2330: "and%.w %1,%0")
2331:
2332: (define_insn ""
2333: [(set (match_operand:SI 0 "general_operand" "=d")
2334: (and:SI (zero_extend:SI (match_operand:QI 1 "general_operand" "dm"))
2335: (match_operand:SI 2 "general_operand" "0")))]
2336: "GET_CODE (operands[2]) == CONST_INT
2337: && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
2338: "and%.b %1,%0")
2339:
2340: ;; inclusive-or instructions
2341:
2342: (define_insn "iorsi3"
2343: [(set (match_operand:SI 0 "general_operand" "=m,d")
2344: (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
2345: (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
2346: ""
2347: "*
2348: {
2349: register int logval;
2350: if (GET_CODE (operands[2]) == CONST_INT
2351: && INTVAL (operands[2]) >> 16 == 0
2352: && (DATA_REG_P (operands[0])
2353: || offsettable_memref_p (operands[0])))
2354: {
2355: if (GET_CODE (operands[0]) != REG)
2356: operands[0] = adj_offsettable_operand (operands[0], 2);
2357: /* Do not delete a following tstl %0 insn; that would be incorrect. */
2358: CC_STATUS_INIT;
2359: return \"or%.w %2,%0\";
2360: }
2361: if (GET_CODE (operands[2]) == CONST_INT
2362: && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
2363: && (DATA_REG_P (operands[0])
2364: || offsettable_memref_p (operands[0])))
2365: {
2366: if (DATA_REG_P (operands[0]))
2367: {
2368: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
2369: }
2370: else
2371: {
2372: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
2373: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
2374: }
2375: return \"bset %1,%0\";
2376: }
2377: return \"or%.l %2,%0\";
2378: }")
2379:
2380: (define_insn "iorhi3"
2381: [(set (match_operand:HI 0 "general_operand" "=m,d")
2382: (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
2383: (match_operand:HI 2 "general_operand" "dn,dmn")))]
2384: ""
2385: "or%.w %2,%0")
2386:
2387: (define_insn "iorqi3"
2388: [(set (match_operand:QI 0 "general_operand" "=m,d")
2389: (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
2390: (match_operand:QI 2 "general_operand" "dn,dmn")))]
2391: ""
2392: "or%.b %2,%0")
2393:
2394: ;; xor instructions
2395:
2396: (define_insn "xorsi3"
2397: [(set (match_operand:SI 0 "general_operand" "=do,m")
2398: (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
2399: (match_operand:SI 2 "general_operand" "di,dKs")))]
2400: ""
2401: "*
2402: {
2403: if (GET_CODE (operands[2]) == CONST_INT
2404: && INTVAL (operands[2]) >> 16 == 0
2405: && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
2406: {
2407: if (! DATA_REG_P (operands[0]))
2408: operands[0] = adj_offsettable_operand (operands[0], 2);
2409: /* Do not delete a following tstl %0 insn; that would be incorrect. */
2410: CC_STATUS_INIT;
2411: return \"eor%.w %2,%0\";
2412: }
2413: return \"eor%.l %2,%0\";
2414: }")
2415:
2416: (define_insn "xorhi3"
2417: [(set (match_operand:HI 0 "general_operand" "=dm")
2418: (xor:HI (match_operand:HI 1 "general_operand" "%0")
2419: (match_operand:HI 2 "general_operand" "dn")))]
2420: ""
2421: "eor%.w %2,%0")
2422:
2423: (define_insn "xorqi3"
2424: [(set (match_operand:QI 0 "general_operand" "=dm")
2425: (xor:QI (match_operand:QI 1 "general_operand" "%0")
2426: (match_operand:QI 2 "general_operand" "dn")))]
2427: ""
2428: "eor%.b %2,%0")
2429:
2430: ;; negation instructions
2431:
2432: (define_insn "negsi2"
2433: [(set (match_operand:SI 0 "general_operand" "=dm")
2434: (neg:SI (match_operand:SI 1 "general_operand" "0")))]
2435: ""
2436: "neg%.l %0")
2437:
2438: (define_insn "neghi2"
2439: [(set (match_operand:HI 0 "general_operand" "=dm")
2440: (neg:HI (match_operand:HI 1 "general_operand" "0")))]
2441: ""
2442: "neg%.w %0")
2443:
2444: (define_insn "negqi2"
2445: [(set (match_operand:QI 0 "general_operand" "=dm")
2446: (neg:QI (match_operand:QI 1 "general_operand" "0")))]
2447: ""
2448: "neg%.b %0")
2449:
2450: (define_expand "negsf2"
2451: [(set (match_operand:SF 0 "general_operand" "")
2452: (neg:SF (match_operand:SF 1 "general_operand" "")))]
2453: "TARGET_68881 || TARGET_FPA"
2454: "")
2455:
2456: (define_insn ""
2457: [(set (match_operand:SF 0 "general_operand" "=x,y")
2458: (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
2459: "TARGET_FPA"
2460: "fpneg%.s %w1,%0")
2461:
2462: (define_insn ""
2463: [(set (match_operand:SF 0 "general_operand" "=f")
2464: (neg:SF (match_operand:SF 1 "general_operand" "fdmF")))]
2465: "TARGET_68881"
2466: "*
2467: {
2468: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
2469: return \"fneg%.x %1,%0\";
2470: return \"fneg%.s %f1,%0\";
2471: }")
2472:
2473: (define_expand "negdf2"
2474: [(set (match_operand:DF 0 "general_operand" "")
2475: (neg:DF (match_operand:DF 1 "general_operand" "")))]
2476: "TARGET_68881 || TARGET_FPA"
2477: "")
2478:
2479: (define_insn ""
2480: [(set (match_operand:DF 0 "general_operand" "=x,y")
2481: (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
2482: "TARGET_FPA"
2483: "fpneg%.d %y1, %0")
2484:
2485: (define_insn ""
2486: [(set (match_operand:DF 0 "general_operand" "=f")
2487: (neg:DF (match_operand:DF 1 "general_operand" "fmF")))]
2488: "TARGET_68881"
2489: "*
2490: {
2491: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
2492: return \"fneg%.x %1,%0\";
2493: return \"fneg%.d %f1,%0\";
2494: }")
2495:
2496: ;; Absolute value instructions
2497:
2498: (define_expand "abssf2"
2499: [(set (match_operand:SF 0 "general_operand" "")
2500: (abs:SF (match_operand:SF 1 "general_operand" "")))]
2501: "TARGET_68881 || TARGET_FPA"
2502: "")
2503:
2504: (define_insn ""
2505: [(set (match_operand:SF 0 "general_operand" "=x,y")
2506: (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))]
2507: "TARGET_FPA"
2508: "fpabs%.s %y1,%0")
2509:
2510: (define_insn ""
2511: [(set (match_operand:SF 0 "general_operand" "=f")
2512: (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))]
2513: "TARGET_68881"
2514: "*
2515: {
2516: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
2517: return \"fabs%.x %1,%0\";
2518: return \"fabs%.s %f1,%0\";
2519: }")
2520:
2521: (define_expand "absdf2"
2522: [(set (match_operand:DF 0 "general_operand" "")
2523: (abs:DF (match_operand:DF 1 "general_operand" "")))]
2524: "TARGET_68881 || TARGET_FPA"
2525: "")
2526:
2527: (define_insn ""
2528: [(set (match_operand:DF 0 "general_operand" "=x,y")
2529: (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))]
2530: "TARGET_FPA"
2531: "fpabs%.d %y1,%0")
2532:
2533: (define_insn ""
2534: [(set (match_operand:DF 0 "general_operand" "=f")
2535: (abs:DF (match_operand:DF 1 "general_operand" "fmF")))]
2536: "TARGET_68881"
2537: "*
2538: {
2539: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
2540: return \"fabs%.x %1,%0\";
2541: return \"fabs%.d %f1,%0\";
2542: }")
2543:
2544: ;; one complement instructions
2545:
2546: (define_insn "one_cmplsi2"
2547: [(set (match_operand:SI 0 "general_operand" "=dm")
2548: (not:SI (match_operand:SI 1 "general_operand" "0")))]
2549: ""
2550: "not%.l %0")
2551:
2552: (define_insn "one_cmplhi2"
2553: [(set (match_operand:HI 0 "general_operand" "=dm")
2554: (not:HI (match_operand:HI 1 "general_operand" "0")))]
2555: ""
2556: "not%.w %0")
2557:
2558: (define_insn "one_cmplqi2"
2559: [(set (match_operand:QI 0 "general_operand" "=dm")
2560: (not:QI (match_operand:QI 1 "general_operand" "0")))]
2561: ""
2562: "not%.b %0")
2563:
2564: ;; Optimized special case of shifting.
2565: ;; Must precede the general case.
2566:
2567: (define_insn ""
2568: [(set (match_operand:SI 0 "general_operand" "=d")
2569: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2570: (const_int 24)))]
2571: "GET_CODE (XEXP (operands[1], 0)) != POST_INC
2572: && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC"
2573: "*
2574: {
2575: if (TARGET_68020)
2576: return \"move%.b %1,%0\;extb%.l %0\";
2577: return \"move%.b %1,%0\;ext%.w %0\;ext%.l %0\";
2578: }")
2579:
2580: (define_insn ""
2581: [(set (match_operand:SI 0 "general_operand" "=d")
2582: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2583: (const_int 24)))]
2584: "GET_CODE (XEXP (operands[1], 0)) != POST_INC
2585: && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC"
2586: "*
2587: {
2588: if (reg_mentioned_p (operands[0], operands[1]))
2589: return \"move%.b %1,%0\;and%.l %#0xFF,%0\";
2590: return \"clr%.l %0\;move%.b %1,%0\";
2591: }")
2592:
2593: (define_insn ""
2594: [(set (cc0) (compare (match_operand:QI 0 "general_operand" "i")
2595: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2596: (const_int 24))))]
2597: "(GET_CODE (operands[0]) == CONST_INT
2598: && (INTVAL (operands[0]) & ~0xff) == 0)"
2599: "* cc_status.flags |= CC_REVERSED;
2600: #ifdef HPUX_ASM
2601: return \"cmp%.b %1,%0\";
2602: #else
2603: return \"cmp%.b %0,%1\";
2604: #endif
2605: ")
2606:
2607: (define_insn ""
2608: [(set (cc0) (compare (lshiftrt:SI (match_operand:SI 0 "memory_operand" "m")
2609: (const_int 24))
2610: (match_operand:QI 1 "general_operand" "i")))]
2611: "(GET_CODE (operands[1]) == CONST_INT
2612: && (INTVAL (operands[1]) & ~0xff) == 0)"
2613: "*
2614: #ifdef HPUX_ASM
2615: return \"cmp%.b %0,%1\";
2616: #else
2617: return \"cmp%.b %1,%0\";
2618: #endif
2619: ")
2620:
2621: (define_insn ""
2622: [(set (cc0) (compare (match_operand:QI 0 "general_operand" "i")
2623: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2624: (const_int 24))))]
2625: "(GET_CODE (operands[0]) == CONST_INT
2626: && ((INTVAL (operands[0]) + 0x80) & ~0xff) == 0)"
2627: "* cc_status.flags |= CC_REVERSED;
2628: #ifdef HPUX_ASM
2629: return \"cmp%.b %1,%0\";
2630: #else
2631: return \"cmp%.b %0,%1\";
2632: #endif
2633: ")
2634:
2635: (define_insn ""
2636: [(set (cc0) (compare (ashiftrt:SI (match_operand:SI 0 "memory_operand" "m")
2637: (const_int 24))
2638: (match_operand:QI 1 "general_operand" "i")))]
2639: "(GET_CODE (operands[1]) == CONST_INT
2640: && ((INTVAL (operands[1]) + 0x80) & ~0xff) == 0)"
2641: "*
2642: #ifdef HPUX_ASM
2643: return \"cmp%.b %0,%1\";
2644: #else
2645: return \"cmp%.b %1,%0\";
2646: #endif
2647: ")
2648:
2649: ;; arithmetic shift instructions
2650: ;; We don't need the shift memory by 1 bit instruction
2651:
2652: (define_insn "ashlsi3"
2653: [(set (match_operand:SI 0 "general_operand" "=d")
2654: (ashift:SI (match_operand:SI 1 "general_operand" "0")
2655: (match_operand:SI 2 "general_operand" "dI")))]
2656: ""
2657: "asl%.l %2,%0")
2658:
2659: (define_insn "ashlhi3"
2660: [(set (match_operand:HI 0 "general_operand" "=d")
2661: (ashift:HI (match_operand:HI 1 "general_operand" "0")
2662: (match_operand:HI 2 "general_operand" "dI")))]
2663: ""
2664: "asl%.w %2,%0")
2665:
2666: (define_insn "ashlqi3"
2667: [(set (match_operand:QI 0 "general_operand" "=d")
2668: (ashift:QI (match_operand:QI 1 "general_operand" "0")
2669: (match_operand:QI 2 "general_operand" "dI")))]
2670: ""
2671: "asl%.b %2,%0")
2672:
2673: (define_insn "ashrsi3"
2674: [(set (match_operand:SI 0 "general_operand" "=d")
2675: (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
2676: (match_operand:SI 2 "general_operand" "dI")))]
2677: ""
2678: "asr%.l %2,%0")
2679:
2680: (define_insn "ashrhi3"
2681: [(set (match_operand:HI 0 "general_operand" "=d")
2682: (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
2683: (match_operand:HI 2 "general_operand" "dI")))]
2684: ""
2685: "asr%.w %2,%0")
2686:
2687: (define_insn "ashrqi3"
2688: [(set (match_operand:QI 0 "general_operand" "=d")
2689: (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
2690: (match_operand:QI 2 "general_operand" "dI")))]
2691: ""
2692: "asr%.b %2,%0")
2693:
2694: ;; logical shift instructions
2695:
2696: (define_insn "lshlsi3"
2697: [(set (match_operand:SI 0 "general_operand" "=d")
2698: (lshift:SI (match_operand:SI 1 "general_operand" "0")
2699: (match_operand:SI 2 "general_operand" "dI")))]
2700: ""
2701: "lsl%.l %2,%0")
2702:
2703: (define_insn "lshlhi3"
2704: [(set (match_operand:HI 0 "general_operand" "=d")
2705: (lshift:HI (match_operand:HI 1 "general_operand" "0")
2706: (match_operand:HI 2 "general_operand" "dI")))]
2707: ""
2708: "lsl%.w %2,%0")
2709:
2710: (define_insn "lshlqi3"
2711: [(set (match_operand:QI 0 "general_operand" "=d")
2712: (lshift:QI (match_operand:QI 1 "general_operand" "0")
2713: (match_operand:QI 2 "general_operand" "dI")))]
2714: ""
2715: "lsl%.b %2,%0")
2716:
2717: (define_insn "lshrsi3"
2718: [(set (match_operand:SI 0 "general_operand" "=d")
2719: (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
2720: (match_operand:SI 2 "general_operand" "dI")))]
2721: ""
2722: "lsr%.l %2,%0")
2723:
2724: (define_insn "lshrhi3"
2725: [(set (match_operand:HI 0 "general_operand" "=d")
2726: (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
2727: (match_operand:HI 2 "general_operand" "dI")))]
2728: ""
2729: "lsr%.w %2,%0")
2730:
2731: (define_insn "lshrqi3"
2732: [(set (match_operand:QI 0 "general_operand" "=d")
2733: (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
2734: (match_operand:QI 2 "general_operand" "dI")))]
2735: ""
2736: "lsr%.b %2,%0")
2737:
2738: ;; rotate instructions
2739:
2740: (define_insn "rotlsi3"
2741: [(set (match_operand:SI 0 "general_operand" "=d")
2742: (rotate:SI (match_operand:SI 1 "general_operand" "0")
2743: (match_operand:SI 2 "general_operand" "dI")))]
2744: ""
2745: "rol%.l %2,%0")
2746:
2747: (define_insn "rotlhi3"
2748: [(set (match_operand:HI 0 "general_operand" "=d")
2749: (rotate:HI (match_operand:HI 1 "general_operand" "0")
2750: (match_operand:HI 2 "general_operand" "dI")))]
2751: ""
2752: "rol%.w %2,%0")
2753:
2754: (define_insn "rotlqi3"
2755: [(set (match_operand:QI 0 "general_operand" "=d")
2756: (rotate:QI (match_operand:QI 1 "general_operand" "0")
2757: (match_operand:QI 2 "general_operand" "dI")))]
2758: ""
2759: "rol%.b %2,%0")
2760:
2761: (define_insn "rotrsi3"
2762: [(set (match_operand:SI 0 "general_operand" "=d")
2763: (rotatert:SI (match_operand:SI 1 "general_operand" "0")
2764: (match_operand:SI 2 "general_operand" "dI")))]
2765: ""
2766: "ror%.l %2,%0")
2767:
2768: (define_insn "rotrhi3"
2769: [(set (match_operand:HI 0 "general_operand" "=d")
2770: (rotatert:HI (match_operand:HI 1 "general_operand" "0")
2771: (match_operand:HI 2 "general_operand" "dI")))]
2772: ""
2773: "ror%.w %2,%0")
2774:
2775: (define_insn "rotrqi3"
2776: [(set (match_operand:QI 0 "general_operand" "=d")
2777: (rotatert:QI (match_operand:QI 1 "general_operand" "0")
2778: (match_operand:QI 2 "general_operand" "dI")))]
2779: ""
2780: "ror%.b %2,%0")
2781:
2782: ;; Special cases of bit-field insns which we should
2783: ;; recognize in preference to the general case.
2784: ;; These handle aligned 8-bit and 16-bit fields,
2785: ;; which can usually be done with move instructions.
2786:
2787: (define_insn ""
2788: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do")
2789: (match_operand:SI 1 "immediate_operand" "i")
2790: (match_operand:SI 2 "immediate_operand" "i"))
2791: (match_operand:SI 3 "general_operand" "d"))]
2792: "TARGET_68020 && TARGET_BITFIELD
2793: && GET_CODE (operands[1]) == CONST_INT
2794: && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
2795: && GET_CODE (operands[2]) == CONST_INT
2796: && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
2797: && (GET_CODE (operands[0]) == REG
2798: || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
2799: "*
2800: {
2801: if (REG_P (operands[0]))
2802: {
2803: if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
2804: return \"bfins %3,%0{%b2:%b1}\";
2805: }
2806: else
2807: operands[0]
2808: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
2809:
2810: if (GET_CODE (operands[3]) == MEM)
2811: operands[3] = adj_offsettable_operand (operands[3],
2812: (32 - INTVAL (operands[1])) / 8);
2813: if (INTVAL (operands[1]) == 8)
2814: return \"move%.b %3,%0\";
2815: return \"move%.w %3,%0\";
2816: }")
2817:
2818: (define_insn ""
2819: [(set (match_operand:SI 0 "general_operand" "=&d")
2820: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
2821: (match_operand:SI 2 "immediate_operand" "i")
2822: (match_operand:SI 3 "immediate_operand" "i")))]
2823: "TARGET_68020 && TARGET_BITFIELD
2824: && GET_CODE (operands[2]) == CONST_INT
2825: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
2826: && GET_CODE (operands[3]) == CONST_INT
2827: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
2828: && (GET_CODE (operands[1]) == REG
2829: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
2830: "*
2831: {
2832: if (REG_P (operands[1]))
2833: {
2834: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
2835: return \"bfextu %1{%b3:%b2},%0\";
2836: }
2837: else
2838: operands[1]
2839: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
2840:
2841: output_asm_insn (\"clr%.l %0\", operands);
2842: if (GET_CODE (operands[0]) == MEM)
2843: operands[0] = adj_offsettable_operand (operands[0],
2844: (32 - INTVAL (operands[1])) / 8);
2845: if (INTVAL (operands[2]) == 8)
2846: return \"move%.b %1,%0\";
2847: return \"move%.w %1,%0\";
2848: }")
2849:
2850: (define_insn ""
2851: [(set (match_operand:SI 0 "general_operand" "=d")
2852: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
2853: (match_operand:SI 2 "immediate_operand" "i")
2854: (match_operand:SI 3 "immediate_operand" "i")))]
2855: "TARGET_68020 && TARGET_BITFIELD
2856: && GET_CODE (operands[2]) == CONST_INT
2857: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
2858: && GET_CODE (operands[3]) == CONST_INT
2859: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
2860: && (GET_CODE (operands[1]) == REG
2861: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
2862: "*
2863: {
2864: if (REG_P (operands[1]))
2865: {
2866: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
2867: return \"bfexts %1{%b3:%b2},%0\";
2868: }
2869: else
2870: operands[1]
2871: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
2872:
2873: if (INTVAL (operands[2]) == 8)
2874: return \"move%.b %1,%0\;extb%.l %0\";
2875: return \"move%.w %1,%0\;ext%.l %0\";
2876: }")
2877:
2878: ;; Bit field instructions, general cases.
2879: ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
2880: ;; so that its address is reloaded.
2881:
2882: (define_insn "extv"
2883: [(set (match_operand:SI 0 "general_operand" "=d,d")
2884: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
2885: (match_operand:SI 2 "general_operand" "di,di")
2886: (match_operand:SI 3 "general_operand" "di,di")))]
2887: "TARGET_68020 && TARGET_BITFIELD"
2888: "bfexts %1{%b3:%b2},%0")
2889:
2890: (define_insn "extzv"
2891: [(set (match_operand:SI 0 "general_operand" "=d,d")
2892: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
2893: (match_operand:SI 2 "general_operand" "di,di")
2894: (match_operand:SI 3 "general_operand" "di,di")))]
2895: "TARGET_68020 && TARGET_BITFIELD"
2896: "bfextu %1{%b3:%b2},%0")
2897:
2898: (define_insn ""
2899: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
2900: (match_operand:SI 1 "general_operand" "di,di")
2901: (match_operand:SI 2 "general_operand" "di,di"))
2902: (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
2903: (match_operand 3 "immediate_operand" "i,i")))]
2904: "TARGET_68020 && TARGET_BITFIELD
2905: && GET_CODE (operands[3]) == CONST_INT
2906: && (INTVAL (operands[3]) == -1
2907: || (GET_CODE (operands[1]) == CONST_INT
2908: && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
2909: "*
2910: {
2911: CC_STATUS_INIT;
2912: return \"bfchg %0{%b2:%b1}\";
2913: }")
2914:
2915: (define_insn ""
2916: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
2917: (match_operand:SI 1 "general_operand" "di,di")
2918: (match_operand:SI 2 "general_operand" "di,di"))
2919: (const_int 0))]
2920: "TARGET_68020 && TARGET_BITFIELD"
2921: "*
2922: {
2923: CC_STATUS_INIT;
2924: return \"bfclr %0{%b2:%b1}\";
2925: }")
2926:
2927: (define_insn ""
2928: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
2929: (match_operand:SI 1 "general_operand" "di,di")
2930: (match_operand:SI 2 "general_operand" "di,di"))
2931: (const_int -1))]
2932: "TARGET_68020 && TARGET_BITFIELD"
2933: "*
2934: {
2935: CC_STATUS_INIT;
2936: return \"bfset %0{%b2:%b1}\";
2937: }")
2938:
2939: (define_insn "insv"
2940: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
2941: (match_operand:SI 1 "general_operand" "di,di")
2942: (match_operand:SI 2 "general_operand" "di,di"))
2943: (match_operand:SI 3 "general_operand" "d,d"))]
2944: "TARGET_68020 && TARGET_BITFIELD"
2945: "bfins %3,%0{%b2:%b1}")
2946:
2947: ;; Now recognize bit field insns that operate on registers
2948: ;; (or at least were intended to do so).
2949:
2950: (define_insn ""
2951: [(set (match_operand:SI 0 "general_operand" "=d")
2952: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
2953: (match_operand:SI 2 "general_operand" "di")
2954: (match_operand:SI 3 "general_operand" "di")))]
2955: "TARGET_68020 && TARGET_BITFIELD"
2956: "bfexts %1{%b3:%b2},%0")
2957:
2958: (define_insn ""
2959: [(set (match_operand:SI 0 "general_operand" "=d")
2960: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
2961: (match_operand:SI 2 "general_operand" "di")
2962: (match_operand:SI 3 "general_operand" "di")))]
2963: "TARGET_68020 && TARGET_BITFIELD"
2964: "bfextu %1{%b3:%b2},%0")
2965:
2966: (define_insn ""
2967: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
2968: (match_operand:SI 1 "general_operand" "di")
2969: (match_operand:SI 2 "general_operand" "di"))
2970: (const_int 0))]
2971: "TARGET_68020 && TARGET_BITFIELD"
2972: "*
2973: {
2974: CC_STATUS_INIT;
2975: return \"bfclr %0{%b2:%b1}\";
2976: }")
2977:
2978: (define_insn ""
2979: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
2980: (match_operand:SI 1 "general_operand" "di")
2981: (match_operand:SI 2 "general_operand" "di"))
2982: (const_int -1))]
2983: "TARGET_68020 && TARGET_BITFIELD"
2984: "*
2985: {
2986: CC_STATUS_INIT;
2987: return \"bfset %0{%b2:%b1}\";
2988: }")
2989:
2990: (define_insn ""
2991: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
2992: (match_operand:SI 1 "general_operand" "di")
2993: (match_operand:SI 2 "general_operand" "di"))
2994: (match_operand:SI 3 "general_operand" "d"))]
2995: "TARGET_68020 && TARGET_BITFIELD"
2996: "*
2997: {
2998: #if 0
2999: /* These special cases are now recognized by a specific pattern. */
3000: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
3001: && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
3002: return \"move%.w %3,%0\";
3003: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
3004: && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
3005: return \"move%.b %3,%0\";
3006: #endif
3007: return \"bfins %3,%0{%b2:%b1}\";
3008: }")
3009:
3010: ;; Special patterns for optimizing bit-field instructions.
3011:
3012: (define_insn ""
3013: [(set (cc0)
3014: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
3015: (match_operand:SI 1 "general_operand" "di")
3016: (match_operand:SI 2 "general_operand" "di")))]
3017: "TARGET_68020 && TARGET_BITFIELD
3018: && GET_CODE (operands[1]) == CONST_INT"
3019: "*
3020: {
3021: if (operands[1] == const1_rtx
3022: && GET_CODE (operands[2]) == CONST_INT)
3023: {
3024: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3025: return output_btst (operands,
3026: gen_rtx (CONST_INT, VOIDmode,
3027: width - INTVAL (operands[2])),
3028: operands[0],
3029: insn, 1000);
3030: /* Pass 1000 as SIGNPOS argument so that btst will
3031: not think we are testing the sign bit for an `and'
3032: and assume that nonzero implies a negative result. */
3033: }
3034: if (INTVAL (operands[1]) != 32)
3035: cc_status.flags = CC_NOT_NEGATIVE;
3036: return \"bftst %0{%b2:%b1}\";
3037: }")
3038:
3039: (define_insn ""
3040: [(set (cc0)
3041: (subreg:QI
3042: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
3043: (match_operand:SI 1 "general_operand" "di")
3044: (match_operand:SI 2 "general_operand" "di"))
3045: 0))]
3046: "TARGET_68020 && TARGET_BITFIELD
3047: && GET_CODE (operands[1]) == CONST_INT"
3048: "*
3049: {
3050: if (operands[1] == const1_rtx
3051: && GET_CODE (operands[2]) == CONST_INT)
3052: {
3053: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3054: return output_btst (operands,
3055: gen_rtx (CONST_INT, VOIDmode,
3056: width - INTVAL (operands[2])),
3057: operands[0],
3058: insn, 1000);
3059: /* Pass 1000 as SIGNPOS argument so that btst will
3060: not think we are testing the sign bit for an `and'
3061: and assume that nonzero implies a negative result. */
3062: }
3063: if (INTVAL (operands[1]) != 32)
3064: cc_status.flags = CC_NOT_NEGATIVE;
3065: return \"bftst %0{%b2:%b1}\";
3066: }")
3067:
3068: (define_insn ""
3069: [(set (cc0)
3070: (subreg:HI
3071: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
3072: (match_operand:SI 1 "general_operand" "di")
3073: (match_operand:SI 2 "general_operand" "di"))
3074: 0))]
3075: "TARGET_68020 && TARGET_BITFIELD
3076: && GET_CODE (operands[1]) == CONST_INT"
3077: "*
3078: {
3079: if (operands[1] == const1_rtx
3080: && GET_CODE (operands[2]) == CONST_INT)
3081: {
3082: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3083: return output_btst (operands,
3084: gen_rtx (CONST_INT, VOIDmode,
3085: width - INTVAL (operands[2])),
3086: operands[0],
3087: insn, 1000);
3088: /* Pass 1000 as SIGNPOS argument so that btst will
3089: not think we are testing the sign bit for an `and'
3090: and assume that nonzero implies a negative result. */
3091: }
3092: if (INTVAL (operands[1]) != 32)
3093: cc_status.flags = CC_NOT_NEGATIVE;
3094: return \"bftst %0{%b2:%b1}\";
3095: }")
3096:
3097: ;;; now handle the register cases
3098: (define_insn ""
3099: [(set (cc0)
3100: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
3101: (match_operand:SI 1 "general_operand" "di")
3102: (match_operand:SI 2 "general_operand" "di")))]
3103: "TARGET_68020 && TARGET_BITFIELD
3104: && GET_CODE (operands[1]) == CONST_INT"
3105: "*
3106: {
3107: if (operands[1] == const1_rtx
3108: && GET_CODE (operands[2]) == CONST_INT)
3109: {
3110: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3111: return output_btst (operands,
3112: gen_rtx (CONST_INT, VOIDmode,
3113: width - INTVAL (operands[2])),
3114: operands[0],
3115: insn, 1000);
3116: /* Pass 1000 as SIGNPOS argument so that btst will
3117: not think we are testing the sign bit for an `and'
3118: and assume that nonzero implies a negative result. */
3119: }
3120: if (INTVAL (operands[1]) != 32)
3121: cc_status.flags = CC_NOT_NEGATIVE;
3122: return \"bftst %0{%b2:%b1}\";
3123: }")
3124:
3125: (define_insn ""
3126: [(set (cc0)
3127: (subreg:QI
3128: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
3129: (match_operand:SI 1 "general_operand" "di")
3130: (match_operand:SI 2 "general_operand" "di"))
3131: 0))]
3132: "TARGET_68020 && TARGET_BITFIELD
3133: && GET_CODE (operands[1]) == CONST_INT"
3134: "*
3135: {
3136: if (operands[1] == const1_rtx
3137: && GET_CODE (operands[2]) == CONST_INT)
3138: {
3139: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3140: return output_btst (operands,
3141: gen_rtx (CONST_INT, VOIDmode,
3142: width - INTVAL (operands[2])),
3143: operands[0],
3144: insn, 1000);
3145: /* Pass 1000 as SIGNPOS argument so that btst will
3146: not think we are testing the sign bit for an `and'
3147: and assume that nonzero implies a negative result. */
3148: }
3149: if (INTVAL (operands[1]) != 32)
3150: cc_status.flags = CC_NOT_NEGATIVE;
3151: return \"bftst %0{%b2:%b1}\";
3152: }")
3153:
3154: (define_insn ""
3155: [(set (cc0)
3156: (subreg:HI
3157: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
3158: (match_operand:SI 1 "general_operand" "di")
3159: (match_operand:SI 2 "general_operand" "di"))
3160: 0))]
3161: "TARGET_68020 && TARGET_BITFIELD
3162: && GET_CODE (operands[1]) == CONST_INT"
3163: "*
3164: {
3165: if (operands[1] == const1_rtx
3166: && GET_CODE (operands[2]) == CONST_INT)
3167: {
3168: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
3169: return output_btst (operands,
3170: gen_rtx (CONST_INT, VOIDmode,
3171: width - INTVAL (operands[2])),
3172: operands[0],
3173: insn, 1000);
3174: /* Pass 1000 as SIGNPOS argument so that btst will
3175: not think we are testing the sign bit for an `and'
3176: and assume that nonzero implies a negative result. */
3177: }
3178: if (INTVAL (operands[1]) != 32)
3179: cc_status.flags = CC_NOT_NEGATIVE;
3180: return \"bftst %0{%b2:%b1}\";
3181: }")
3182:
3183: (define_insn "seq"
3184: [(set (match_operand:QI 0 "general_operand" "=d")
3185: (eq (cc0) (const_int 0)))]
3186: ""
3187: "*
3188: cc_status = cc_prev_status;
3189: OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
3190: ")
3191:
3192: (define_insn "sne"
3193: [(set (match_operand:QI 0 "general_operand" "=d")
3194: (ne (cc0) (const_int 0)))]
3195: ""
3196: "*
3197: cc_status = cc_prev_status;
3198: OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
3199: ")
3200:
3201: (define_insn "sgt"
3202: [(set (match_operand:QI 0 "general_operand" "=d")
3203: (gt (cc0) (const_int 0)))]
3204: ""
3205: "*
3206: cc_status = cc_prev_status;
3207: OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0);
3208: ")
3209:
3210: (define_insn "sgtu"
3211: [(set (match_operand:QI 0 "general_operand" "=d")
3212: (gtu (cc0) (const_int 0)))]
3213: ""
3214: "* cc_status = cc_prev_status;
3215: return \"shi %0\"; ")
3216:
3217: (define_insn "slt"
3218: [(set (match_operand:QI 0 "general_operand" "=d")
3219: (lt (cc0) (const_int 0)))]
3220: ""
3221: "* cc_status = cc_prev_status;
3222: OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
3223:
3224: (define_insn "sltu"
3225: [(set (match_operand:QI 0 "general_operand" "=d")
3226: (ltu (cc0) (const_int 0)))]
3227: ""
3228: "* cc_status = cc_prev_status;
3229: return \"scs %0\"; ")
3230:
3231: (define_insn "sge"
3232: [(set (match_operand:QI 0 "general_operand" "=d")
3233: (ge (cc0) (const_int 0)))]
3234: ""
3235: "* cc_status = cc_prev_status;
3236: OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
3237:
3238: (define_insn "sgeu"
3239: [(set (match_operand:QI 0 "general_operand" "=d")
3240: (geu (cc0) (const_int 0)))]
3241: ""
3242: "* cc_status = cc_prev_status;
3243: return \"scc %0\"; ")
3244:
3245: (define_insn "sle"
3246: [(set (match_operand:QI 0 "general_operand" "=d")
3247: (le (cc0) (const_int 0)))]
3248: ""
3249: "*
3250: cc_status = cc_prev_status;
3251: OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0);
3252: ")
3253:
3254: (define_insn "sleu"
3255: [(set (match_operand:QI 0 "general_operand" "=d")
3256: (leu (cc0) (const_int 0)))]
3257: ""
3258: "* cc_status = cc_prev_status;
3259: return \"sls %0\"; ")
3260:
3261: ;; Basic conditional jump instructions.
3262:
3263: (define_insn "beq"
3264: [(set (pc)
3265: (if_then_else (eq (cc0)
3266: (const_int 0))
3267: (label_ref (match_operand 0 "" ""))
3268: (pc)))]
3269: ""
3270: "*
3271: {
3272: #ifdef MOTOROLA
3273: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
3274: #else
3275: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
3276: #endif
3277: }")
3278:
3279: (define_insn "bne"
3280: [(set (pc)
3281: (if_then_else (ne (cc0)
3282: (const_int 0))
3283: (label_ref (match_operand 0 "" ""))
3284: (pc)))]
3285: ""
3286: "*
3287: {
3288: #ifdef MOTOROLA
3289: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
3290: #else
3291: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
3292: #endif
3293: }")
3294:
3295: (define_insn "bgt"
3296: [(set (pc)
3297: (if_then_else (gt (cc0)
3298: (const_int 0))
3299: (label_ref (match_operand 0 "" ""))
3300: (pc)))]
3301: ""
3302: "*
3303: #ifdef MOTOROLA
3304: OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0);
3305: #else
3306: OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0);
3307: #endif
3308: ")
3309:
3310: (define_insn "bgtu"
3311: [(set (pc)
3312: (if_then_else (gtu (cc0)
3313: (const_int 0))
3314: (label_ref (match_operand 0 "" ""))
3315: (pc)))]
3316: ""
3317: "*
3318: #ifdef MOTOROLA
3319: return \"jbhi %l0\";
3320: #else
3321: return \"jhi %l0\";
3322: #endif
3323: ")
3324:
3325: (define_insn "blt"
3326: [(set (pc)
3327: (if_then_else (lt (cc0)
3328: (const_int 0))
3329: (label_ref (match_operand 0 "" ""))
3330: (pc)))]
3331: ""
3332: "*
3333: #ifdef MOTOROLA
3334: OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\");
3335: #else
3336: OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\");
3337: #endif
3338: ")
3339:
3340: (define_insn "bltu"
3341: [(set (pc)
3342: (if_then_else (ltu (cc0)
3343: (const_int 0))
3344: (label_ref (match_operand 0 "" ""))
3345: (pc)))]
3346: ""
3347: "*
3348: #ifdef MOTOROLA
3349: return \"jbcs %l0\";
3350: #else
3351: return \"jcs %l0\";
3352: #endif
3353: ")
3354:
3355: (define_insn "bge"
3356: [(set (pc)
3357: (if_then_else (ge (cc0)
3358: (const_int 0))
3359: (label_ref (match_operand 0 "" ""))
3360: (pc)))]
3361: ""
3362: "*
3363: #ifdef MOTOROLA
3364: OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\");
3365: #else
3366: OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\");
3367: #endif
3368: ")
3369:
3370: (define_insn "bgeu"
3371: [(set (pc)
3372: (if_then_else (geu (cc0)
3373: (const_int 0))
3374: (label_ref (match_operand 0 "" ""))
3375: (pc)))]
3376: ""
3377: "*
3378: #ifdef MOTOROLA
3379: return \"jbcc %l0\";
3380: #else
3381: return \"jcc %l0\";
3382: #endif
3383: ")
3384:
3385: (define_insn "ble"
3386: [(set (pc)
3387: (if_then_else (le (cc0)
3388: (const_int 0))
3389: (label_ref (match_operand 0 "" ""))
3390: (pc)))]
3391: ""
3392: "*
3393: #ifdef MOTOROLA
3394: OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0);
3395: #else
3396: OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0);
3397: #endif
3398: ")
3399:
3400: (define_insn "bleu"
3401: [(set (pc)
3402: (if_then_else (leu (cc0)
3403: (const_int 0))
3404: (label_ref (match_operand 0 "" ""))
3405: (pc)))]
3406: ""
3407: "*
3408: #ifdef MOTOROLA
3409: return \"jbls %l0\";
3410: #else
3411: return \"jls %l0\";
3412: #endif
3413: ")
3414:
3415: ;; Negated conditional jump instructions.
3416:
3417: (define_insn ""
3418: [(set (pc)
3419: (if_then_else (eq (cc0)
3420: (const_int 0))
3421: (pc)
3422: (label_ref (match_operand 0 "" ""))))]
3423: ""
3424: "*
3425: {
3426: #ifdef MOTOROLA
3427: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\");
3428: #else
3429: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\");
3430: #endif
3431: }")
3432:
3433: (define_insn ""
3434: [(set (pc)
3435: (if_then_else (ne (cc0)
3436: (const_int 0))
3437: (pc)
3438: (label_ref (match_operand 0 "" ""))))]
3439: ""
3440: "*
3441: {
3442: #ifdef MOTOROLA
3443: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\");
3444: #else
3445: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\");
3446: #endif
3447: }")
3448:
3449: (define_insn ""
3450: [(set (pc)
3451: (if_then_else (gt (cc0)
3452: (const_int 0))
3453: (pc)
3454: (label_ref (match_operand 0 "" ""))))]
3455: ""
3456: "*
3457: #ifdef MOTOROLA
3458: OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0);
3459: #else
3460: OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0);
3461: #endif
3462: ")
3463:
3464: (define_insn ""
3465: [(set (pc)
3466: (if_then_else (gtu (cc0)
3467: (const_int 0))
3468: (pc)
3469: (label_ref (match_operand 0 "" ""))))]
3470: ""
3471: "*
3472: #ifdef MOTOROLA
3473: return \"jbls %l0\";
3474: #else
3475: return \"jls %l0\";
3476: #endif
3477: ")
3478:
3479: (define_insn ""
3480: [(set (pc)
3481: (if_then_else (lt (cc0)
3482: (const_int 0))
3483: (pc)
3484: (label_ref (match_operand 0 "" ""))))]
3485: ""
3486: "*
3487: #ifdef MOTOROLA
3488: OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\");
3489: #else
3490: OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\");
3491: #endif
3492: ")
3493:
3494: (define_insn ""
3495: [(set (pc)
3496: (if_then_else (ltu (cc0)
3497: (const_int 0))
3498: (pc)
3499: (label_ref (match_operand 0 "" ""))))]
3500: ""
3501: "*
3502: #ifdef MOTOROLA
3503: return \"jbcc %l0\";
3504: #else
3505: return \"jcc %l0\";
3506: #endif
3507: ")
3508:
3509: (define_insn ""
3510: [(set (pc)
3511: (if_then_else (ge (cc0)
3512: (const_int 0))
3513: (pc)
3514: (label_ref (match_operand 0 "" ""))))]
3515: ""
3516: "*
3517: #ifdef MOTOROLA
3518: OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\");
3519: #else
3520: OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\");
3521: #endif
3522: ")
3523:
3524: (define_insn ""
3525: [(set (pc)
3526: (if_then_else (geu (cc0)
3527: (const_int 0))
3528: (pc)
3529: (label_ref (match_operand 0 "" ""))))]
3530: ""
3531: "*
3532: #ifdef MOTOROLA
3533: return \"jbcs %l0\";
3534: #else
3535: return \"jcs %l0\";
3536: #endif
3537: ")
3538:
3539: (define_insn ""
3540: [(set (pc)
3541: (if_then_else (le (cc0)
3542: (const_int 0))
3543: (pc)
3544: (label_ref (match_operand 0 "" ""))))]
3545: ""
3546: "*
3547: #ifdef MOTOROLA
3548: OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0);
3549: #else
3550: OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0);
3551: #endif
3552: ")
3553:
3554: (define_insn ""
3555: [(set (pc)
3556: (if_then_else (leu (cc0)
3557: (const_int 0))
3558: (pc)
3559: (label_ref (match_operand 0 "" ""))))]
3560: ""
3561: "*
3562: #ifdef MOTOROLA
3563: return \"jbhi %l0\";
3564: #else
3565: return \"jhi %l0\";
3566: #endif
3567: ")
3568:
3569: ;; Subroutines of "casesi".
3570:
3571: (define_expand "casesi_1"
3572: [(set (match_operand:SI 3 "general_operand" "")
3573: (plus:SI (match_operand:SI 0 "general_operand" "")
3574: ;; Note operand 1 has been negated!
3575: (match_operand:SI 1 "immediate_operand" "")))
3576: (set (cc0) (compare (match_operand:SI 2 "general_operand" "")
3577: (match_dup 3)))
3578: (set (pc) (if_then_else (ltu (cc0) (const_int 0))
3579: (label_ref (match_operand 4 "" "")) (pc)))]
3580: ""
3581: "")
3582:
3583: (define_expand "casesi_2"
3584: [(set (match_operand:SI 0 "" "") (mem:HI (match_operand:SI 1 "" "")))
3585: ;; The USE here is so that at least one jump-insn will refer to the label,
3586: ;; to keep it alive in jump_optimize.
3587: (parallel [(set (pc)
3588: (plus:SI (pc) (match_dup 0)))
3589: (use (label_ref (match_operand 2 "" "")))])]
3590: ""
3591: "")
3592:
3593: ;; Operand 0 is index (in bytes); operand 1 is minimum, operand 2 themaximum;
3594: ;; operand 3 is CODE_LABEL for the table;
3595: ;; operand 4 is the CODE_LABEL to go to if index out of range.
3596: (define_expand "casesi"
3597: ;; We don't use these for generating the RTL, but we must describe
3598: ;; the operands here.
3599: [(match_operand:SI 0 "general_operand" "")
3600: (match_operand:SI 1 "immediate_operand" "")
3601: (match_operand:SI 2 "general_operand" "")
3602: (match_operand 3 "" "")
3603: (match_operand 4 "" "")]
3604: ""
3605: "
3606: {
3607: rtx table_elt_addr;
3608: rtx index_diff;
3609:
3610: operands[1] = negate_rtx (SImode, operands[1]);
3611: index_diff = gen_reg_rtx (SImode);
3612: /* Emit the first few insns. */
3613: emit_insn (gen_casesi_1 (operands[0], operands[1], operands[2],
3614: index_diff, operands[4]));
3615: /* Construct a memory address. This may emit some insns. */
3616: table_elt_addr
3617: = memory_address_noforce
3618: (HImode,
3619: gen_rtx (PLUS, Pmode,
3620: gen_rtx (MULT, Pmode, index_diff,
3621: gen_rtx (CONST_INT, VOIDmode, 2)),
3622: gen_rtx (LABEL_REF, VOIDmode, operands[3])));
3623: /* Emit the last few insns. */
3624: emit_insn (gen_casesi_2 (gen_reg_rtx (HImode), table_elt_addr, operands[3]));
3625: DONE;
3626: }")
3627:
3628: ;; Recognize one of the insns resulting from casesi_2.
3629: (define_insn ""
3630: [(set (pc)
3631: (plus:SI (pc) (match_operand:HI 0 "general_operand" "r")))
3632: (use (label_ref (match_operand 1 "" "")))]
3633: ""
3634: "*
3635: #ifdef SGS
3636: #ifdef ASM_OUTPUT_CASE_LABEL
3637: return \"jmp 6(%%pc,%0.w)\";
3638: #else
3639: return \"jmp 2(%%pc,%0.w)\";
3640: #endif
3641: #else /* not SGS */
3642: #ifdef MOTOROLA
3643: return \"jmp (2,pc,%0.w)\";
3644: #else
3645: return \"jmp pc@(2,%0:w)\";
3646: #endif
3647: #endif
3648: ")
3649:
3650: ;; Unconditional and other jump instructions
3651: (define_insn "jump"
3652: [(set (pc)
3653: (label_ref (match_operand 0 "" "")))]
3654: ""
3655: "*
3656: #ifdef MOTOROLA
3657: return \"jbra %l0\";
3658: #else
3659: return \"jra %l0\";
3660: #endif
3661: ")
3662:
3663: (define_insn ""
3664: [(set (pc)
3665: (if_then_else
3666: (ne (compare (plus:HI (match_operand:HI 0 "general_operand" "g")
3667: (const_int -1))
3668: (const_int -1))
3669: (const_int 0))
3670: (label_ref (match_operand 1 "" ""))
3671: (pc)))
3672: (set (match_dup 0)
3673: (plus:HI (match_dup 0)
3674: (const_int -1)))]
3675: ""
3676: "*
3677: {
3678: CC_STATUS_INIT;
3679: if (DATA_REG_P (operands[0]))
3680: return \"dbra %0,%l1\";
3681: if (GET_CODE (operands[0]) == MEM)
3682: {
3683: #ifdef MOTOROLA
3684: #ifdef NO_ADDSUB_Q
3685: return \"sub%.w %#1,%0\;jbcc %l1\";
3686: #else
3687: return \"subq%.w %#1,%0\;jbcc %l1\";
3688: #endif
3689: #else /* not MOTOROLA */
3690: return \"subqw %#1,%0\;jcc %l1\";
3691: #endif
3692: }
3693: #ifdef MOTOROLA
3694: #ifdef HPUX_ASM
3695: #ifndef NO_ADDSUB_Q
3696: return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
3697: #else
3698: return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
3699: #endif
3700: #else /* not HPUX_ASM */
3701: return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\";
3702: #endif
3703: #else /* not MOTOROLA */
3704: return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
3705: #endif
3706: }")
3707:
3708: (define_insn ""
3709: [(set (pc)
3710: (if_then_else
3711: (ne (compare (plus:SI (match_operand:SI 0 "general_operand" "g")
3712: (const_int -1))
3713: (const_int -1))
3714: (const_int 0))
3715: (label_ref (match_operand 1 "" ""))
3716: (pc)))
3717: (set (match_dup 0)
3718: (plus:SI (match_dup 0)
3719: (const_int -1)))]
3720: ""
3721: "*
3722: {
3723: CC_STATUS_INIT;
3724: #ifdef MOTOROLA
3725: #ifndef NO_ADDSUB_Q
3726: if (DATA_REG_P (operands[0]))
3727: return \"dbra %0,%l1\;clr.w %0\;sub.l %#1,%0\;jbcc %l1\";
3728: if (GET_CODE (operands[0]) == MEM)
3729: return \"sub.l %#1,%0\;jbcc %l1\";
3730: #else
3731: if (DATA_REG_P (operands[0]))
3732: return \"dbra %0,%l1\;clr.w %0\;subq.l %#1,%0\;jbcc %l1\";
3733: if (GET_CODE (operands[0]) == MEM)
3734: return \"subq.l %#1,%0\;jbcc %l1\";
3735: #endif /* not NO_ADDSUB_Q */
3736: #ifdef HPUX_ASM
3737: #ifndef NO_ADDSUB_Q
3738: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
3739: #else
3740: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
3741: #endif
3742: #else
3743: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
3744: #endif
3745: #else
3746: if (DATA_REG_P (operands[0]))
3747: return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\";
3748: if (GET_CODE (operands[0]) == MEM)
3749: return \"subql %#1,%0\;jcc %l1\";
3750: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
3751: #endif
3752: }")
3753:
3754: ;; dbra patterns that use REG_NOTES info generated by strength_reduce.
3755:
3756: (define_insn ""
3757: [(set (pc)
3758: (if_then_else
3759: (ge (plus:SI (match_operand:SI 0 "general_operand" "g")
3760: (const_int -1))
3761: (const_int 0))
3762: (label_ref (match_operand 1 "" ""))
3763: (pc)))
3764: (set (match_dup 0)
3765: (plus:SI (match_dup 0)
3766: (const_int -1)))]
3767: "find_reg_note (insn, REG_NONNEG, 0)"
3768: "*
3769: {
3770: CC_STATUS_INIT;
3771: #ifdef MOTOROLA
3772: #ifndef NO_ADDSUB_Q
3773: if (DATA_REG_P (operands[0]))
3774: return \"dbra %0,%l1\;clr.w %0\;sub.l %#1,%0\;jbcc %l1\";
3775: if (GET_CODE (operands[0]) == MEM)
3776: return \"sub.l %#1,%0\;jbcc %l1\";
3777: #else
3778: if (DATA_REG_P (operands[0]))
3779: return \"dbra %0,%l1\;clr.w %0\;subq.l %#1,%0\;jbcc %l1\";
3780: if (GET_CODE (operands[0]) == MEM)
3781: return \"subq.l %#1,%0\;jbcc %l1\";
3782: #endif
3783: #ifdef HPUX_ASM
3784: #ifndef NO_ADDSUB_Q
3785: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
3786: #else
3787: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
3788: #endif
3789: #else
3790: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
3791: #endif
3792: #else
3793: if (DATA_REG_P (operands[0]))
3794: return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\";
3795: if (GET_CODE (operands[0]) == MEM)
3796: return \"subql %#1,%0\;jcc %l1\";
3797: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
3798: #endif
3799: }")
3800:
3801: ;; Call subroutine with no return value.
3802: (define_insn "call"
3803: [(call (match_operand:QI 0 "general_operand" "o")
3804: (match_operand:SI 1 "general_operand" "g"))]
3805: ;; Operand 1 not really used on the m68000.
3806:
3807: ""
3808: "*
3809: #ifdef MOTOROLA
3810: return \"jsr %0\";
3811: #else
3812: return \"jbsr %0\";
3813: #endif
3814: ")
3815:
3816: ;; Call subroutine, returning value in operand 0
3817: ;; (which must be a hard register).
3818: (define_insn "call_value"
3819: [(set (match_operand 0 "" "=rf")
3820: (call (match_operand:QI 1 "general_operand" "o")
3821: (match_operand:SI 2 "general_operand" "g")))]
3822: ;; Operand 2 not really used on the m68000.
3823: ""
3824: "*
3825: #ifdef MOTOROLA
3826: return \"jsr %1\";
3827: #else
3828: return \"jbsr %1\";
3829: #endif
3830: ")
3831:
3832: (define_insn "nop"
3833: [(const_int 0)]
3834: ""
3835: "nop")
3836:
3837: ;; This should not be used unless the add/sub insns can't be.
3838:
3839: (define_insn ""
3840: [(set (match_operand:SI 0 "general_operand" "=a")
3841: (match_operand:QI 1 "address_operand" "p"))]
3842: ""
3843: "lea %a1,%0")
3844:
3845: ;; This is the first machine-dependent peephole optimization.
3846: ;; It is useful when a floating value is returned from a function call
3847: ;; and then is moved into an FP register.
3848: ;; But it is mainly intended to test the support for these optimizations.
3849:
3850: (define_peephole
3851: [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
3852: (set (match_operand:DF 0 "register_operand" "f")
3853: (match_operand:DF 1 "register_operand" "ad"))]
3854: "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3855: "*
3856: {
3857: rtx xoperands[2];
3858: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
3859: output_asm_insn (\"move%.l %1,%@\", xoperands);
3860: output_asm_insn (\"move%.l %1,%-\", operands);
3861: return \"fmove%.d %+,%0\";
3862: }
3863: ")
3864:
3865: ;; FPA multiply and add.
3866: (define_insn ""
3867: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
3868: (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y")
3869: (match_operand:DF 2 "general_operand" "xH,y,y"))
3870: (match_operand:DF 3 "general_operand" "xH,y,dmF")))]
3871: "TARGET_FPA"
3872: "*
3873: {
3874: if (which_alternative == 0)
3875: return \"fpma%.d %1,%w2,%w3,%0\";
3876: return \"fpma%.d %x1,%x2,%x3,%0\";
3877: }")
3878:
3879: (define_insn ""
3880: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
3881: (plus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF")
3882: (mult:DF (match_operand:DF 2 "general_operand" "%x,dmF,y")
3883: (match_operand:DF 3 "general_operand" "xH,y,y"))))]
3884: "TARGET_FPA"
3885: "*
3886: {
3887: if (which_alternative == 0)
3888: return \"fpma%.d %2,%w3,%w1,%0\";
3889: return \"fpma%.d %x2,%x3,%x1,%0\";
3890: }")
3891:
3892: (define_insn ""
3893: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
3894: (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y")
3895: (match_operand:SF 2 "general_operand" "xH,y,ydmF"))
3896: (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))]
3897: "TARGET_FPA"
3898: "*
3899: {
3900: if (which_alternative == 0)
3901: return \"fpma%.s %1,%w2,%w3,%0\";
3902: return \"fpma%.s %1,%2,%3,%0\";
3903: }")
3904:
3905: (define_insn ""
3906: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
3907: (plus:SF (match_operand:SF 1 "general_operand" "xH,ydmF,ydmF")
3908: (mult:SF (match_operand:SF 2 "general_operand" "%x,ydmF,y")
3909: (match_operand:SF 3 "general_operand" "xH,y,ydmF"))))]
3910: "TARGET_FPA"
3911: "*
3912: {
3913: if (which_alternative == 0)
3914: return \"fpma%.s %2,%w3,%w1,%0\";
3915: return \"fpma%.s %2,%3,%1,%0\";
3916: }")
3917:
3918: ;; FPA Multiply and subtract
3919: (define_insn ""
3920: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
3921: (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
3922: (mult:DF (match_operand:DF 2 "register_operand" "%xH,y,y")
3923: (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
3924: "TARGET_FPA"
3925: "*
3926: {
3927: if (which_alternative == 0)
3928: return \"fpms%.d %3,%w2,%w1,%0\";
3929: return \"fpms%.d %x3,%2,%x1,%0\";
3930: }")
3931:
3932: (define_insn ""
3933: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
3934: (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
3935: (mult:SF (match_operand:SF 2 "register_operand" "%xH,rmF,y")
3936: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
3937: "TARGET_FPA"
3938: "*
3939: {
3940: if (which_alternative == 0)
3941: return \"fpms%.s %3,%w2,%w1,%0\";
3942: return \"fpms%.s %3,%2,%1,%0\";
3943: }")
3944:
3945: (define_insn ""
3946: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
3947: (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "%xH,y,y")
3948: (match_operand:DF 2 "general_operand" "x,y,rmF"))
3949: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
3950: "TARGET_FPA"
3951: "*
3952: {
3953: if (which_alternative == 0)
3954: return \"fpmr%.d %2,%w1,%w3,%0\";
3955: return \"fpmr%.d %x2,%1,%x3,%0\";
3956: }")
3957:
3958: (define_insn ""
3959: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
3960: (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%xH,rmF,y")
3961: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
3962: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
3963: "TARGET_FPA"
3964: "*
3965: {
3966: if (which_alternative == 0)
3967: return \"fpmr%.s %2,%w1,%w3,%0\";
3968: return \"fpmr%.s %x2,%1,%x3,%0\";
3969: }")
3970:
3971: ;; FPA Add and multiply
3972: (define_insn ""
3973: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
3974: (mult:DF (plus:DF (match_operand:DF 1 "register_operand" "%xH,y,y")
3975: (match_operand:DF 2 "general_operand" "x,y,rmF"))
3976: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
3977: "TARGET_FPA"
3978: "*
3979: {
3980: if (which_alternative == 0)
3981: return \"fpam%.d %2,%w1,%w3,%0\";
3982: return \"fpam%.d %x2,%1,%x3,%0\";
3983: }")
3984:
3985: (define_insn ""
3986: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
3987: (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
3988: (plus:DF (match_operand:DF 2 "register_operand" "%xH,y,y")
3989: (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
3990: "TARGET_FPA"
3991: "*
3992: {
3993: if (which_alternative == 0)
3994: return \"fpam%.d %3,%w2,%w1,%0\";
3995: return \"fpam%.d %x3,%2,%x1,%0\";
3996: }")
3997:
3998: (define_insn ""
3999: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4000: (mult:SF (plus:SF (match_operand:SF 1 "register_operand" "%xH,rmF,y")
4001: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
4002: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
4003: "TARGET_FPA"
4004: "*
4005: {
4006: if (which_alternative == 0)
4007: return \"fpam%.s %2,%w1,%w3,%0\";
4008: return \"fpam%.s %x2,%1,%x3,%0\";
4009: }")
4010:
4011: (define_insn ""
4012: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4013: (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
4014: (plus:SF (match_operand:SF 2 "register_operand" "%xH,rmF,y")
4015: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
4016: "TARGET_FPA"
4017: "*
4018: {
4019: if (which_alternative == 0)
4020: return \"fpam%.s %3,%w2,%w1,%0\";
4021: return \"fpam%.s %x3,%2,%x1,%0\";
4022: }")
4023:
4024: ;;FPA Subtract and multiply
4025: (define_insn ""
4026: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4027: (mult:DF (minus:DF (match_operand:DF 1 "register_operand" "xH,y,y")
4028: (match_operand:DF 2 "general_operand" "x,y,rmF"))
4029: (match_operand:DF 3 "general_operand" "xH,rmF,y")))]
4030: "TARGET_FPA"
4031: "*
4032: {
4033: if (which_alternative == 0)
4034: return \"fpsm%.d %2,%w1,%w3,%0\";
4035: return \"fpsm%.d %x2,%1,%x3,%0\";
4036: }")
4037:
4038: (define_insn ""
4039: [(set (match_operand:DF 0 "register_operand" "=x,y,y")
4040: (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y")
4041: (minus:DF (match_operand:DF 2 "register_operand" "xH,y,y")
4042: (match_operand:DF 3 "general_operand" "x,y,rmF"))))]
4043: "TARGET_FPA"
4044: "*
4045: {
4046: if (which_alternative == 0)
4047: return \"fpsm%.d %3,%w2,%w1,%0\";
4048: return \"fpsm%.d %x3,%2,%x1,%0\";
4049: }")
4050:
4051: (define_insn ""
4052: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4053: (mult:SF (minus:SF (match_operand:SF 1 "register_operand" "xH,rmF,y")
4054: (match_operand:SF 2 "general_operand" "x,y,yrmF"))
4055: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))]
4056: "TARGET_FPA"
4057: "*
4058: {
4059: if (which_alternative == 0)
4060: return \"fpsm%.s %2,%w1,%w3,%0\";
4061: return \"fpsm%.s %x2,%1,%x3,%0\";
4062: }")
4063:
4064: (define_insn ""
4065: [(set (match_operand:SF 0 "register_operand" "=x,y,y")
4066: (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF")
4067: (minus:SF (match_operand:SF 2 "register_operand" "xH,rmF,y")
4068: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))]
4069: "TARGET_FPA"
4070: "*
4071: {
4072: if (which_alternative == 0)
4073: return \"fpsm%.s %3,%w2,%w1,%0\";
4074: return \"fpsm%.s %x3,%2,%x1,%0\";
4075: }")
4076:
4077:
4078: ;;- Local variables:
4079: ;;- mode:emacs-lisp
4080: ;;- comment-start: ";;- "
4081: ;;- comment-start-skip: ";+- *"
4082: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
4083: ;;- eval: (modify-syntax-entry ?[ "(]")
4084: ;;- eval: (modify-syntax-entry ?] ")[")
4085: ;;- eval: (modify-syntax-entry ?{ "(}")
4086: ;;- eval: (modify-syntax-entry ?} "){")
4087: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.