|
|
1.1 root 1: ;;- Machine description for GNU C compiler for Alliant FX systems
2: ;; Copyright (C) 1989 Free Software Foundation, Inc.
3: ;; Adapted from m68k.md by Paul Petersen ([email protected])
4: ;; and Joe Weening ([email protected]).
5:
6: ;; This file is part of GNU CC.
7:
8: ;; GNU CC is free software; you can redistribute it and/or modify
9: ;; it under the terms of the GNU General Public License as published by
10: ;; the Free Software Foundation; either version 1, or (at your option)
11: ;; any later version.
12:
13: ;; GNU CC is distributed in the hope that it will be useful,
14: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: ;; GNU General Public License for more details.
17:
18: ;; You should have received a copy of the GNU General Public License
19: ;; along with GNU CC; see the file COPYING. If not, write to
20: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22:
23: ;;- instruction definitions
24:
25: ;;- @@The original PO technology requires these to be ordered by speed,
26: ;;- @@ so that assigner will pick the fastest.
27:
28: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29:
30: ;;- When naming insn's (operand 0 of define_insn) be careful about using
31: ;;- names from other targets machine descriptions.
32:
33: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
34: ;;- updates for most instructions.
35:
36: ;;- Operand classes for the register allocator:
37: ;;- 'a' one of the address registers can be used.
38: ;;- 'd' one of the data registers can be used.
39: ;;- 'f' one of the CE floating point registers can be used
40: ;;- 'r' either a data or an address register can be used.
41:
42: ;;- Immediate integer operand constraints:
43: ;;- 'I' 1 .. 8
44: ;;- 'J' -32768 .. 32767
45: ;;- 'K' -128 .. 127
46: ;;- 'L' -8 .. -1
47:
48: ;;- Some remnants of constraint codes for the m68k ('x','y','G','H')
49: ;;- may remain in the insn definitions.
50:
51: ;;- Some of these insn's are composites of several Alliant op codes.
52: ;;- The assembler (or final @@??) insures that the appropriate one is
53: ;;- selected.
54:
55: ;; Put tstsi first among test insns so it matches a CONST_INT operand.
56:
57: (define_insn "tstsi"
58: [(set (cc0)
59: (match_operand:SI 0 "general_operand" "rm"))]
60: ""
61: "*
62: {
63: if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
64: return \"tst%.l %0\";
65: /* If you think that the 68020 does not support tstl a0,
66: reread page B-167 of the 68020 manual more carefully. */
67: /* On an address reg, cmpw may replace cmpl. */
68: return \"cmp%.w %#0,%0\";
69: }")
70:
71: (define_insn "tsthi"
72: [(set (cc0)
73: (match_operand:HI 0 "general_operand" "rm"))]
74: ""
75: "*
76: {
77: if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
78: return \"tst%.w %0\";
79: return \"cmp%.w %#0,%0\";
80: }")
81:
82: (define_insn "tstqi"
83: [(set (cc0)
84: (match_operand:QI 0 "general_operand" "dm"))]
85: ""
86: "tst%.b %0")
87:
88: (define_insn "tstsf"
89: [(set (cc0)
90: (match_operand:SF 0 "nonimmediate_operand" "fm"))]
91: "TARGET_CE"
92: "*
93: {
94: cc_status.flags = CC_IN_FP;
95: return \"ftest%.s %0\";
96: }")
97:
98: (define_insn "tstdf"
99: [(set (cc0)
100: (match_operand:DF 0 "nonimmediate_operand" "fm"))]
101: "TARGET_CE"
102: "*
103: {
104: cc_status.flags = CC_IN_FP;
105: return \"ftest%.d %0\";
106: }")
107:
108: ;; compare instructions.
109:
110: ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
111:
112: ;; A composite of the cmp, cmpa, & cmpi m68000 op codes.
113: (define_insn "cmpsi"
114: [(set (cc0)
115: (compare (match_operand:SI 0 "general_operand" "rKs,mr,>")
116: (match_operand:SI 1 "general_operand" "mr,Ksr,>")))]
117: ""
118: "*
119: {
120: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
121: return \"cmpm%.l %1,%0\";
122: if (REG_P (operands[1])
123: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
124: {
125: cc_status.flags |= CC_REVERSED;
126: return \"cmp%.l %d0,%d1\";
127: }
128: return \"cmp%.l %d1,%d0\";
129: }")
130:
131: (define_insn "cmphi"
132: [(set (cc0)
133: (compare (match_operand:HI 0 "general_operand" "rnm,d,n,m")
134: (match_operand:HI 1 "general_operand" "d,rnm,m,n")))]
135: ""
136: "*
137: {
138: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
139: return \"cmpm%.w %1,%0\";
140: if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
141: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
142: { cc_status.flags |= CC_REVERSED;
143: return \"cmp%.w %d0,%d1\";
144: }
145: return \"cmp%.w %d1,%d0\";
146: }")
147:
148: (define_insn "cmpqi"
149: [(set (cc0)
150: (compare (match_operand:QI 0 "general_operand" "dn,md,>")
151: (match_operand:QI 1 "general_operand" "dm,nd,>")))]
152: ""
153: "*
154: {
155: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
156: return \"cmpm%.b %1,%0\";
157: if (REG_P (operands[1])
158: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
159: {
160: cc_status.flags |= CC_REVERSED;
161: return \"cmp%.b %d0,%d1\";
162: }
163: return \"cmp%.b %d1,%d0\";
164: }")
165:
166: (define_insn "cmpdf"
167: [(set (cc0)
168: (compare (match_operand:DF 0 "nonimmediate_operand" "f,m")
169: (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
170: "TARGET_CE"
171: "*
172: {
173: cc_status.flags = CC_IN_FP;
174: if (FP_REG_P (operands[0]))
175: return \"fcmp%.d %1,%0\";
176: cc_status.flags |= CC_REVERSED;
177: return \"fcmp%.d %0,%1\";
178: }")
179:
180: (define_insn "cmpsf"
181: [(set (cc0)
182: (compare (match_operand:SF 0 "nonimmediate_operand" "f,m")
183: (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
184: "TARGET_CE"
185: "*
186: {
187: cc_status.flags = CC_IN_FP;
188: if (FP_REG_P (operands[0]))
189: return \"fcmp%.s %1,%0\";
190: cc_status.flags |= CC_REVERSED;
191: return \"fcmp%.s %0,%1\";
192: }")
193:
194: ;; Recognizers for btst instructions.
195:
196: (define_insn ""
197: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do")
198: (const_int 1)
199: (minus:SI (const_int 7)
200: (match_operand:SI 1 "general_operand" "di"))))]
201: ""
202: "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
203:
204: (define_insn ""
205: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d")
206: (const_int 1)
207: (minus:SI (const_int 31)
208: (match_operand:SI 1 "general_operand" "di"))))]
209: ""
210: "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
211:
212: ;; The following two patterns are like the previous two
213: ;; except that they use the fact that bit-number operands
214: ;; are automatically masked to 3 or 5 bits.
215:
216: (define_insn ""
217: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do")
218: (const_int 1)
219: (minus:SI (const_int 7)
220: (and:SI
221: (match_operand:SI 1 "general_operand" "d")
222: (const_int 7)))))]
223: ""
224: "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
225:
226: (define_insn ""
227: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d")
228: (const_int 1)
229: (minus:SI (const_int 31)
230: (and:SI
231: (match_operand:SI 1 "general_operand" "d")
232: (const_int 31)))))]
233: ""
234: "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
235:
236: ;; Nonoffsettable mem refs are ok in this one pattern
237: ;; since we don't try to adjust them.
238: (define_insn ""
239: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "md")
240: (const_int 1)
241: (match_operand:SI 1 "general_operand" "i")))]
242: "GET_CODE (operands[1]) == CONST_INT
243: && (unsigned) INTVAL (operands[1]) < 8"
244: "*
245: {
246: operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1]));
247: return output_btst (operands, operands[1], operands[0], insn, 7);
248: }")
249:
250: (define_insn ""
251: ;; The constraint "o,d" here means that a nonoffsettable memref
252: ;; will match the first alternative, and its address will be reloaded.
253: ;; Copying the memory contents into a reg would be incorrect if the
254: ;; bit position is over 7.
255: [(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "o,d")
256: (const_int 1)
257: (match_operand:SI 1 "general_operand" "i,i")))]
258: "GET_CODE (operands[1]) == CONST_INT"
259: "*
260: {
261: if (GET_CODE (operands[0]) == MEM)
262: {
263: operands[0] = adj_offsettable_operand (operands[0],
264: INTVAL (operands[1]) / 8);
265: operands[1] = gen_rtx (CONST_INT, VOIDmode,
266: 7 - INTVAL (operands[1]) % 8);
267: return output_btst (operands, operands[1], operands[0], insn, 7);
268: }
269: operands[1] = gen_rtx (CONST_INT, VOIDmode,
270: 15 - INTVAL (operands[1]));
271: return output_btst (operands, operands[1], operands[0], insn, 15);
272: }")
273:
274: (define_insn ""
275: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "do")
276: (const_int 1)
277: (match_operand:SI 1 "general_operand" "i")))]
278: "GET_CODE (operands[1]) == CONST_INT"
279: "*
280: {
281: if (GET_CODE (operands[0]) == MEM)
282: {
283: operands[0] = adj_offsettable_operand (operands[0],
284: INTVAL (operands[1]) / 8);
285: operands[1] = gen_rtx (CONST_INT, VOIDmode,
286: 7 - INTVAL (operands[1]) % 8);
287: return output_btst (operands, operands[1], operands[0], insn, 7);
288: }
289: operands[1] = gen_rtx (CONST_INT, VOIDmode,
290: 31 - INTVAL (operands[1]));
291: return output_btst (operands, operands[1], operands[0], insn, 31);
292: }")
293:
294: (define_insn ""
295: [(set (cc0) (subreg:SI (lshiftrt:QI (match_operand:QI 0 "nonimmediate_operand" "dm")
296: (const_int 7))
297: 0))]
298: ""
299: "*
300: {
301: cc_status.flags = CC_Z_IN_NOT_N | CC_NOT_NEGATIVE;
302: return \"tst%.b %0\";
303: }")
304:
305: (define_insn ""
306: [(set (cc0) (and:SI (sign_extend:SI (sign_extend:HI (match_operand:QI 0 "nonimmediate_operand" "dm")))
307: (match_operand:SI 1 "general_operand" "i")))]
308: "(GET_CODE (operands[1]) == CONST_INT
309: && (unsigned) INTVAL (operands[1]) < 0x100
310: && exact_log2 (INTVAL (operands[1])) >= 0)"
311: "*
312: { register int log = exact_log2 (INTVAL (operands[1]));
313: operands[1] = gen_rtx (CONST_INT, VOIDmode, log);
314: return output_btst (operands, operands[1], operands[0], insn, 7);
315: }")
316:
317: ;; move instructions
318:
319: ;; A special case in which it is not desirable
320: ;; to reload the constant into a data register.
321: (define_insn ""
322: [(set (match_operand:SI 0 "push_operand" "=m")
323: (match_operand:SI 1 "general_operand" "J"))]
324: "GET_CODE (operands[1]) == CONST_INT
325: && INTVAL (operands[1]) >= -0x8000
326: && INTVAL (operands[1]) < 0x8000"
327: "*
328: {
329: if (operands[1] == const0_rtx)
330: return \"clr%.l %0\";
331: return \"pea %a1\";
332: }")
333:
334: ;This is never used.
335: ;(define_insn "swapsi"
336: ; [(set (match_operand:SI 0 "general_operand" "r")
337: ; (match_operand:SI 1 "general_operand" "r"))
338: ; (set (match_dup 1) (match_dup 0))]
339: ; ""
340: ; "exg %1,%0")
341:
342: ;; Special case of fullword move when source is zero.
343: ;; The reason this is special is to avoid loading a zero
344: ;; into a data reg with moveq in order to store it elsewhere.
345:
346: (define_insn ""
347: [(set (match_operand:SI 0 "general_operand" "=g")
348: (const_int 0))]
349: ""
350: "*
351: {
352: if (ADDRESS_REG_P (operands[0]))
353: return \"sub%.l %0,%0\";
354: return \"clr%.l %0\";
355: }")
356:
357: ;; General case of fullword move. The register constraints
358: ;; force integer constants in range for a moveq to be reloaded
359: ;; if they are headed for memory.
360: (define_insn "movsi"
361: ;; Notes: make sure no alternative allows g vs g.
362: ;; We don't allow f-regs since fixed point cannot go in them.
363: ;; We do allow y and x regs since fixed point is allowed in them.
364: [(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m")
365: (match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))]
366: ""
367: "*
368: {
369: if (GET_CODE (operands[1]) == CONST_INT)
370: {
371: if (operands[1] == const0_rtx
372: && (DATA_REG_P (operands[0])
373: || GET_CODE (operands[0]) == MEM))
374: return \"clr%.l %0\";
375: else if (DATA_REG_P (operands[0])
376: && INTVAL (operands[1]) < 128
377: && INTVAL (operands[1]) >= -128)
378: return \"moveq %1,%0\";
379: else if (ADDRESS_REG_P (operands[0])
380: && INTVAL (operands[1]) < 0x8000
381: && INTVAL (operands[1]) >= -0x8000)
382: return \"mov%.w %1,%0\";
383: else if (push_operand (operands[0], SImode)
384: && INTVAL (operands[1]) < 0x8000
385: && INTVAL (operands[1]) >= -0x8000)
386: return \"pea %a1\";
387: }
388: else if ((GET_CODE (operands[1]) == SYMBOL_REF
389: || GET_CODE (operands[1]) == CONST)
390: && push_operand (operands[0], SImode))
391: return \"pea %a1\";
392: else if ((GET_CODE (operands[1]) == SYMBOL_REF
393: || GET_CODE (operands[1]) == CONST)
394: && ADDRESS_REG_P (operands[0]))
395: return \"lea %a1,%0\";
396: return \"mov%.l %1,%0\";
397: }")
398:
399: (define_insn "movhi"
400: [(set (match_operand:HI 0 "general_operand" "=g")
401: (match_operand:HI 1 "general_operand" "g"))]
402: ""
403: "*
404: {
405: if (GET_CODE (operands[1]) == CONST_INT)
406: {
407: if (operands[1] == const0_rtx
408: && (DATA_REG_P (operands[0])
409: || GET_CODE (operands[0]) == MEM))
410: return \"clr%.w %0\";
411: else if (DATA_REG_P (operands[0])
412: && INTVAL (operands[1]) < 128
413: && INTVAL (operands[1]) >= -128)
414: {
415: return \"moveq %1,%0\";
416: }
417: else if (INTVAL (operands[1]) < 0x8000
418: && INTVAL (operands[1]) >= -0x8000)
419: return \"mov%.w %1,%0\";
420: }
421: else if (CONSTANT_P (operands[1]))
422: return \"mov%.l %1,%0\";
423: /* Recognize the insn before a tablejump, one that refers
424: to a table of offsets. Such an insn will need to refer
425: to a label on the insn. So output one. Use the label-number
426: of the table of offsets to generate this label. */
427: if (GET_CODE (operands[1]) == MEM
428: && GET_CODE (XEXP (operands[1], 0)) == PLUS
429: && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
430: || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF)
431: && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS
432: && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS)
433: {
434: rtx labelref;
435: if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF)
436: labelref = XEXP (XEXP (operands[1], 0), 0);
437: else
438: labelref = XEXP (XEXP (operands[1], 0), 1);
439: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\",
440: CODE_LABEL_NUMBER (XEXP (labelref, 0)));
441: }
442: return \"mov%.w %1,%0\";
443: }")
444:
445: (define_insn "movstricthi"
446: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
447: (match_operand:HI 1 "general_operand" "rmn"))]
448: ""
449: "*
450: {
451: if (GET_CODE (operands[1]) == CONST_INT)
452: {
453: if (operands[1] == const0_rtx
454: && (DATA_REG_P (operands[0])
455: || GET_CODE (operands[0]) == MEM))
456: return \"clr%.w %0\";
457: }
458: return \"mov%.w %1,%0\";
459: }")
460:
461: (define_insn "movqi"
462: [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")
463: (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]
464: ""
465: "*
466: {
467: rtx xoperands[4];
468: if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
469: {
470: xoperands[1] = operands[1];
471: xoperands[2]
472: = gen_rtx (MEM, QImode,
473: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
474: xoperands[3] = stack_pointer_rtx;
475: /* Just pushing a byte puts it in the high byte of the halfword. */
476: /* We must put it in the low half, the second byte. */
477: output_asm_insn (\"subq%.w %#2,%3\;mov%.b %1,%2\", xoperands);
478: return \"mov%.w %+,%0\";
479: }
480: if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
481: {
482: xoperands[0] = operands[0];
483: xoperands[1] = operands[1];
484: xoperands[2]
485: = gen_rtx (MEM, QImode,
486: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
487: xoperands[3] = stack_pointer_rtx;
488: output_asm_insn (\"mov%.w %1,%-\;mov%.b %2,%0\;addq%.w %#2,%3\", xoperands);
489: return \"\";
490: }
491: if (operands[1] == const0_rtx)
492: return \"clr%.b %0\";
493: if (GET_CODE (operands[1]) == CONST_INT
494: && INTVAL (operands[1]) == -1)
495: return \"st %0\";
496: if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
497: return \"mov%.l %1,%0\";
498: if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
499: return \"mov%.w %1,%0\";
500: return \"mov%.b %1,%0\";
501: }")
502:
503: (define_insn "movstrictqi"
504: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
505: (match_operand:QI 1 "general_operand" "dmn"))]
506: ""
507: "*
508: {
509: if (operands[1] == const0_rtx)
510: return \"clr%.b %0\";
511: return \"mov%.b %1,%0\";
512: }")
513:
514: ;; Floating-point moves on a CE are faster using an FP register than
515: ;; with movl instructions. (Especially for double floats, but also
516: ;; for single floats, even though it takes an extra instruction.) But
517: ;; on an IP, the FP registers are simulated and so should be avoided.
518: ;; We do this by using define_expand for movsf and movdf, and using
519: ;; different constraints for each target type. The constraints for
520: ;; TARGET_CE allow general registers because they sometimes need to
521: ;; hold floats, but they are not preferable.
522:
523: (define_expand "movsf"
524: [(set (match_operand:SF 0 "general_operand" "")
525: (match_operand:SF 1 "nonimmediate_operand" ""))]
526: ""
527: "")
528:
529: (define_insn ""
530: [(set (match_operand:SF 0 "general_operand" "=f,m,!*r,!f*m")
531: (match_operand:SF 1 "nonimmediate_operand" "fm,f,f*r*m,*r"))]
532: "TARGET_CE"
533: "*
534: {
535: if (FP_REG_P (operands[0]))
536: {
537: if (FP_REG_P (operands[1]))
538: return \"fmove%.s %1,%0\";
539: if (REG_P (operands[1]))
540: return \"mov%.l %1,%-\;fmove%.s %+,%0\";
541: return \"fmove%.s %1,%0\";
542: }
543: if (FP_REG_P (operands[1]))
544: {
545: if (REG_P (operands[0]))
546: return \"fmove%.s %1,%-\;mov%.l %+,%0\";
547: return \"fmove%.s %1,%0\";
548: }
549: return \"mov%.l %1,%0\";
550: }")
551:
552: (define_insn ""
553: [(set (match_operand:SF 0 "general_operand" "=frm")
554: (match_operand:SF 1 "nonimmediate_operand" "frm"))]
555: "!TARGET_CE"
556: "*
557: {
558: if (FP_REG_P (operands[0]))
559: {
560: if (FP_REG_P (operands[1]))
561: return \"fmove%.s %1,%0\";
562: if (REG_P (operands[1]))
563: return \"mov%.l %1,%-\;fmove%.s %+,%0\";
564: return \"fmove%.s %1,%0\";
565: }
566: if (FP_REG_P (operands[1]))
567: {
568: if (REG_P (operands[0]))
569: return \"fmove%.s %1,%-\;mov%.l %+,%0\";
570: return \"fmove%.s %1,%0\";
571: }
572: return \"mov%.l %1,%0\";
573: }")
574:
575: (define_expand "movdf"
576: [(set (match_operand:DF 0 "general_operand" "")
577: (match_operand:DF 1 "nonimmediate_operand" ""))]
578: ""
579: "")
580:
581: (define_insn ""
582: [(set (match_operand:DF 0 "general_operand" "=f,m,!*r,!f*m")
583: (match_operand:DF 1 "nonimmediate_operand" "fm,f,f*r*m,*r"))]
584: "TARGET_CE"
585: "*
586: {
587: if (FP_REG_P (operands[0]))
588: {
589: if (FP_REG_P (operands[1]))
590: return \"fmove%.d %1,%0\";
591: if (REG_P (operands[1]))
592: {
593: rtx xoperands[2];
594: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
595: output_asm_insn (\"mov%.l %1,%-\", xoperands);
596: output_asm_insn (\"mov%.l %1,%-\", operands);
597: return \"fmove%.d %+,%0\";
598: }
599: return \"fmove%.d %1,%0\";
600: }
601: else if (FP_REG_P (operands[1]))
602: {
603: if (REG_P (operands[0]))
604: {
605: output_asm_insn (\"fmove%.d %1,%-\;mov%.l %+,%0\", operands);
606: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
607: return \"mov%.l %+,%0\";
608: }
609: return \"fmove%.d %1,%0\";
610: }
611: return output_move_double (operands);
612: }")
613:
614: (define_insn ""
615: [(set (match_operand:DF 0 "general_operand" "=frm")
616: (match_operand:DF 1 "nonimmediate_operand" "frm"))]
617: "!TARGET_CE"
618: "*
619: {
620: if (FP_REG_P (operands[0]))
621: {
622: if (FP_REG_P (operands[1]))
623: return \"fmove%.d %1,%0\";
624: if (REG_P (operands[1]))
625: {
626: rtx xoperands[2];
627: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
628: output_asm_insn (\"mov%.l %1,%-\", xoperands);
629: output_asm_insn (\"mov%.l %1,%-\", operands);
630: return \"fmove%.d %+,%0\";
631: }
632: return \"fmove%.d %1,%0\";
633: }
634: else if (FP_REG_P (operands[1]))
635: {
636: if (REG_P (operands[0]))
637: {
638: output_asm_insn (\"fmove%.d %1,%-\;mov%.l %+,%0\", operands);
639: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
640: return \"mov%.l %+,%0\";
641: }
642: return \"fmove%.d %1,%0\";
643: }
644: return output_move_double (operands);
645: }")
646:
647: (define_insn "movdi"
648: [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>")
649: (match_operand:DI 1 "general_operand" "r,m,roi<>"))]
650: ""
651: "*
652: {
653: return output_move_double (operands);
654: }
655: ")
656:
657: ;; This goes after the move instructions
658: ;; because the move instructions are better (require no spilling)
659: ;; when they can apply. It goes before the add/sub insns
660: ;; so we will prefer it to them.
661:
662: (define_insn "pushasi"
663: [(set (match_operand:SI 0 "push_operand" "=m")
664: (match_operand:SI 1 "address_operand" "p"))]
665: ""
666: "pea %a1")
667:
668: ;; truncation instructions
669: (define_insn "truncsiqi2"
670: [(set (match_operand:QI 0 "general_operand" "=dm,d")
671: (truncate:QI
672: (match_operand:SI 1 "general_operand" "doJ,i")))]
673: ""
674: "*
675: {
676: if (GET_CODE (operands[0]) == REG)
677: return \"mov%.l %1,%0\";
678: if (GET_CODE (operands[1]) == MEM)
679: operands[1] = adj_offsettable_operand (operands[1], 3);
680: return \"mov%.b %1,%0\";
681: }")
682:
683: (define_insn "trunchiqi2"
684: [(set (match_operand:QI 0 "general_operand" "=dm,d")
685: (truncate:QI
686: (match_operand:HI 1 "general_operand" "doJ,i")))]
687: ""
688: "*
689: {
690: if (GET_CODE (operands[0]) == REG
691: && (GET_CODE (operands[1]) == MEM
692: || GET_CODE (operands[1]) == CONST_INT))
693: return \"mov%.w %1,%0\";
694: if (GET_CODE (operands[0]) == REG)
695: return \"mov%.l %1,%0\";
696: if (GET_CODE (operands[1]) == MEM)
697: operands[1] = adj_offsettable_operand (operands[1], 1);
698: return \"mov%.b %1,%0\";
699: }")
700:
701: (define_insn "truncsihi2"
702: [(set (match_operand:HI 0 "general_operand" "=dm,d")
703: (truncate:HI
704: (match_operand:SI 1 "general_operand" "roJ,i")))]
705: ""
706: "*
707: {
708: if (GET_CODE (operands[0]) == REG)
709: return \"mov%.l %1,%0\";
710: if (GET_CODE (operands[1]) == MEM)
711: operands[1] = adj_offsettable_operand (operands[1], 2);
712: return \"mov%.w %1,%0\";
713: }")
714:
715: ;; zero extension instructions
716:
717: (define_expand "zero_extendhisi2"
718: [(set (match_operand:SI 0 "register_operand" "")
719: (const_int 0))
720: (set (strict_low_part (subreg:HI (match_dup 0) 0))
721: (match_operand:HI 1 "general_operand" ""))]
722: ""
723: "operands[1] = make_safe_from (operands[1], operands[0]);")
724:
725: (define_expand "zero_extendqihi2"
726: [(set (match_operand:HI 0 "register_operand" "")
727: (const_int 0))
728: (set (strict_low_part (subreg:QI (match_dup 0) 0))
729: (match_operand:QI 1 "general_operand" ""))]
730: ""
731: "operands[1] = make_safe_from (operands[1], operands[0]);")
732:
733: (define_expand "zero_extendqisi2"
734: [(set (match_operand:SI 0 "register_operand" "")
735: (const_int 0))
736: (set (strict_low_part (subreg:QI (match_dup 0) 0))
737: (match_operand:QI 1 "general_operand" ""))]
738: ""
739: " operands[1] = make_safe_from (operands[1], operands[0]); ")
740:
741: ;; Patterns to recognize zero-extend insns produced by the combiner.
742:
743: ;; Note that the one starting from HImode comes before those for QImode
744: ;; so that a constant operand will match HImode, not QImode.
745: (define_insn ""
746: [(set (match_operand:SI 0 "general_operand" "=do<>")
747: (zero_extend:SI
748: (match_operand:HI 1 "general_operand" "rmn")))]
749: ""
750: "*
751: {
752: if (DATA_REG_P (operands[0]))
753: {
754: if (GET_CODE (operands[1]) == REG
755: && REGNO (operands[0]) == REGNO (operands[1]))
756: return \"and%.l %#0xFFFF,%0\";
757: if (reg_mentioned_p (operands[0], operands[1]))
758: return \"mov%.w %1,%0\;and%.l %#0xFFFF,%0\";
759: return \"clr%.l %0\;mov%.w %1,%0\";
760: }
761: else if (GET_CODE (operands[0]) == MEM
762: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
763: return \"mov%.w %1,%0\;clr%.w %0\";
764: else if (GET_CODE (operands[0]) == MEM
765: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
766: return \"clr%.w %0\;mov%.w %1,%0\";
767: else
768: {
769: output_asm_insn (\"clr%.w %0\", operands);
770: operands[0] = adj_offsettable_operand (operands[0], 2);
771: return \"mov%.w %1,%0\";
772: }
773: }")
774:
775: (define_insn ""
776: [(set (match_operand:HI 0 "general_operand" "=do<>")
777: (zero_extend:HI
778: (match_operand:QI 1 "general_operand" "dmn")))]
779: ""
780: "*
781: {
782: if (DATA_REG_P (operands[0]))
783: {
784: if (GET_CODE (operands[1]) == REG
785: && REGNO (operands[0]) == REGNO (operands[1]))
786: return \"and%.w %#0xFF,%0\";
787: if (reg_mentioned_p (operands[0], operands[1]))
788: return \"mov%.b %1,%0\;and%.w %#0xFF,%0\";
789: return \"clr%.w %0\;mov%.b %1,%0\";
790: }
791: else if (GET_CODE (operands[0]) == MEM
792: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
793: {
794: if (REGNO (XEXP (XEXP (operands[0], 0), 0))
795: == STACK_POINTER_REGNUM)
796: return \"clr%.w %-\;mov%.b %1,%0\";
797: else
798: return \"mov%.b %1,%0\;clr%.b %0\";
799: }
800: else if (GET_CODE (operands[0]) == MEM
801: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
802: return \"clr%.b %0\;mov%.b %1,%0\";
803: else
804: {
805: output_asm_insn (\"clr%.b %0\", operands);
806: operands[0] = adj_offsettable_operand (operands[0], 1);
807: return \"mov%.b %1,%0\";
808: }
809: }")
810:
811: (define_insn ""
812: [(set (match_operand:SI 0 "general_operand" "=do<>")
813: (zero_extend:SI
814: (match_operand:QI 1 "general_operand" "dmn")))]
815: ""
816: "*
817: {
818: if (DATA_REG_P (operands[0]))
819: {
820: if (GET_CODE (operands[1]) == REG
821: && REGNO (operands[0]) == REGNO (operands[1]))
822: return \"and%.l %#0xFF,%0\";
823: if (reg_mentioned_p (operands[0], operands[1]))
824: return \"mov%.b %1,%0\;and%.l %#0xFF,%0\";
825: return \"clr%.l %0\;mov%.b %1,%0\";
826: }
827: else if (GET_CODE (operands[0]) == MEM
828: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
829: {
830: operands[0] = XEXP (XEXP (operands[0], 0), 0);
831: return \"clr%.l %0@-\;mov%.b %1,%0@(3)\";
832: }
833: else if (GET_CODE (operands[0]) == MEM
834: && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
835: {
836: operands[0] = XEXP (XEXP (operands[0], 0), 0);
837: return \"clr%.l %0@+\;mov%.b %1,%0@(-1)\";
838: }
839: else
840: {
841: output_asm_insn (\"clr%.l %0\", operands);
842: operands[0] = adj_offsettable_operand (operands[0], 3);
843: return \"mov%.b %1,%0\";
844: }
845: }")
846:
847: ;; sign extension instructions
848: ;; Note that the one starting from HImode comes before those for QImode
849: ;; so that a constant operand will match HImode, not QImode.
850:
851: (define_insn "extendhisi2"
852: [(set (match_operand:SI 0 "general_operand" "=*d,a")
853: (sign_extend:SI
854: (match_operand:HI 1 "general_operand" "0,rmn")))]
855: ""
856: "*
857: {
858: if (ADDRESS_REG_P (operands[0]))
859: return \"mov%.w %1,%0\";
860: return \"ext%.l %0\";
861: }")
862:
863: (define_insn "extendqihi2"
864: [(set (match_operand:HI 0 "general_operand" "=d")
865: (sign_extend:HI
866: (match_operand:QI 1 "general_operand" "0")))]
867: ""
868: "ext%.w %0")
869:
870: (define_insn "extendqisi2"
871: [(set (match_operand:SI 0 "general_operand" "=d")
872: (sign_extend:SI
873: (match_operand:QI 1 "general_operand" "0")))]
874: "TARGET_68020"
875: "extb%.l %0")
876:
877: ;; Conversions between float and double.
878:
879: (define_insn "extendsfdf2"
880: [(set (match_operand:DF 0 "general_operand" "=f,m")
881: (float_extend:DF
882: (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
883: "TARGET_CE"
884: "fmovesd %1,%0")
885:
886: (define_insn "truncdfsf2"
887: [(set (match_operand:SF 0 "general_operand" "=f,m")
888: (float_truncate:SF
889: (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
890: "TARGET_CE"
891: "fmoveds %1,%0")
892:
893: ;; Conversion between fixed point and floating point.
894: ;; Note that among the fix-to-float insns
895: ;; the ones that start with SImode come first.
896: ;; That is so that an operand that is a CONST_INT
897: ;; (and therefore lacks a specific machine mode).
898: ;; will be recognized as SImode (which is always valid)
899: ;; rather than as QImode or HImode.
900:
901: (define_insn "floatsisf2"
902: [(set (match_operand:SF 0 "register_operand" "=f")
903: (float:SF (match_operand:SI 1 "nonimmediate_operand" "dm")))]
904: "TARGET_CE"
905: "fmovels %1,%0")
906:
907: (define_insn "floatsidf2"
908: [(set (match_operand:DF 0 "register_operand" "=f")
909: (float:DF (match_operand:SI 1 "nonimmediate_operand" "dm")))]
910: "TARGET_CE"
911: "fmoveld %1,%0")
912:
913: (define_insn "floathisf2"
914: [(set (match_operand:SF 0 "register_operand" "=f")
915: (float:SF (match_operand:HI 1 "nonimmediate_operand" "dm")))]
916: "TARGET_CE"
917: "fmovews %1,%0")
918:
919: (define_insn "floathidf2"
920: [(set (match_operand:DF 0 "register_operand" "=f")
921: (float:DF (match_operand:HI 1 "nonimmediate_operand" "dm")))]
922: "TARGET_CE"
923: "fmovewd %1,%0")
924:
925: (define_insn "floatqisf2"
926: [(set (match_operand:SF 0 "register_operand" "=f")
927: (float:SF (match_operand:QI 1 "nonimmediate_operand" "dm")))]
928: "TARGET_CE"
929: "fmovebs %1,%0")
930:
931: (define_insn "floatqidf2"
932: [(set (match_operand:DF 0 "register_operand" "=f")
933: (float:DF (match_operand:QI 1 "nonimmediate_operand" "dm")))]
934: "TARGET_CE"
935: "fmovebd %1,%0")
936:
937: ;; Float-to-fix conversion insns.
938:
939: (define_insn "fix_truncsfqi2"
940: [(set (match_operand:QI 0 "general_operand" "=dm")
941: (fix:QI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
942: "TARGET_CE"
943: "fmovesb %1,%0")
944:
945: (define_insn "fix_truncsfhi2"
946: [(set (match_operand:HI 0 "general_operand" "=dm")
947: (fix:HI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
948: "TARGET_CE"
949: "fmovesw %1,%0")
950:
951: (define_insn "fix_truncsfsi2"
952: [(set (match_operand:SI 0 "general_operand" "=dm")
953: (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
954: "TARGET_CE"
955: "fmovesl %1,%0")
956:
957: (define_insn "fix_truncdfqi2"
958: [(set (match_operand:QI 0 "general_operand" "=dm")
959: (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
960: "TARGET_CE"
961: "fmovedb %1,%0")
962:
963: (define_insn "fix_truncdfhi2"
964: [(set (match_operand:HI 0 "general_operand" "=dm")
965: (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
966: "TARGET_CE"
967: "fmovedw %1,%0")
968:
969: (define_insn "fix_truncdfsi2"
970: [(set (match_operand:SI 0 "general_operand" "=dm")
971: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
972: "TARGET_CE"
973: "fmovedl %1,%0")
974:
975: ;; add instructions
976:
977: (define_insn "addsi3"
978: [(set (match_operand:SI 0 "general_operand" "=m,r,!a,!a")
979: (plus:SI (match_operand:SI 1 "general_operand" "%0,0,a,rJK")
980: (match_operand:SI 2 "general_operand" "dIKLs,mrIKLs,rJK,a")))]
981: ""
982: "*
983: {
984: if (! operands_match_p (operands[0], operands[1]))
985: {
986: if (!ADDRESS_REG_P (operands[1]))
987: {
988: rtx tmp = operands[1];
989:
990: operands[1] = operands[2];
991: operands[2] = tmp;
992: }
993:
994: /* These insns can result from reloads to access
995: stack slots over 64k from the frame pointer. */
996: if (GET_CODE (operands[2]) == CONST_INT
997: && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
998: return \"mov%.l %2,%0\;add%.l %1,%0\";
999: if (GET_CODE (operands[2]) == REG)
1000: return \"lea %1@[%2:L:B],%0\";
1001: else
1002: return \"lea %1@(%c2),%0\";
1003: }
1004: if (GET_CODE (operands[2]) == CONST_INT)
1005: {
1006: if (INTVAL (operands[2]) > 0
1007: && INTVAL (operands[2]) <= 8)
1008: return (ADDRESS_REG_P (operands[0])
1009: ? \"addq%.w %2,%0\"
1010: : \"addq%.l %2,%0\");
1011: if (INTVAL (operands[2]) < 0
1012: && INTVAL (operands[2]) >= -8)
1013: {
1014: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1015: - INTVAL (operands[2]));
1016: return (ADDRESS_REG_P (operands[0])
1017: ? \"subq%.w %2,%0\"
1018: : \"subq%.l %2,%0\");
1019: }
1020: if (ADDRESS_REG_P (operands[0])
1021: && INTVAL (operands[2]) >= -0x8000
1022: && INTVAL (operands[2]) < 0x8000)
1023: return \"add%.w %2,%0\";
1024: }
1025: return \"add%.l %2,%0\";
1026: }")
1027:
1028: (define_insn ""
1029: [(set (match_operand:SI 0 "general_operand" "=a")
1030: (plus:SI (match_operand:SI 1 "general_operand" "0")
1031: (sign_extend:SI (match_operand:HI 2 "general_operand" "rmn"))))]
1032: ""
1033: "add%.w %2,%0")
1034:
1035: (define_insn "addhi3"
1036: [(set (match_operand:HI 0 "general_operand" "=m,r")
1037: (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
1038: (match_operand:HI 2 "general_operand" "dn,rmn")))]
1039: ""
1040: "*
1041: {
1042: if (GET_CODE (operands[2]) == CONST_INT)
1043: {
1044: if (INTVAL (operands[2]) > 0
1045: && INTVAL (operands[2]) <= 8)
1046: return \"addq%.w %2,%0\";
1047: }
1048: if (GET_CODE (operands[2]) == CONST_INT)
1049: {
1050: if (INTVAL (operands[2]) < 0
1051: && INTVAL (operands[2]) >= -8)
1052: {
1053: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1054: - INTVAL (operands[2]));
1055: return \"subq%.w %2,%0\";
1056: }
1057: }
1058: return \"add%.w %2,%0\";
1059: }")
1060:
1061: (define_insn ""
1062: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
1063: (plus:HI (match_dup 0)
1064: (match_operand:HI 1 "general_operand" "dn,rmn")))]
1065: ""
1066: "add%.w %1,%0")
1067:
1068: (define_insn "addqi3"
1069: [(set (match_operand:QI 0 "general_operand" "=m,d")
1070: (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
1071: (match_operand:QI 2 "general_operand" "dn,dmn")))]
1072: ""
1073: "*
1074: {
1075: if (GET_CODE (operands[2]) == CONST_INT)
1076: {
1077: if (INTVAL (operands[2]) > 0
1078: && INTVAL (operands[2]) <= 8)
1079: return \"addq%.b %2,%0\";
1080: }
1081: if (GET_CODE (operands[2]) == CONST_INT)
1082: {
1083: if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
1084: {
1085: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1086: return \"subq%.b %2,%0\";
1087: }
1088: }
1089: return \"add%.b %2,%0\";
1090: }")
1091:
1092: (define_insn ""
1093: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
1094: (plus:QI (match_dup 0)
1095: (match_operand:QI 1 "general_operand" "dn,dmn")))]
1096: ""
1097: "add%.b %1,%0")
1098:
1099: (define_insn "adddf3"
1100: [(set (match_operand:DF 0 "register_operand" "=f")
1101: (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%f")
1102: (match_operand:DF 2 "nonimmediate_operand" "fm")))]
1103: "TARGET_CE"
1104: "fadd%.d %2,%1,%0")
1105:
1106: (define_insn "addsf3"
1107: [(set (match_operand:SF 0 "register_operand" "=f")
1108: (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%f")
1109: (match_operand:SF 2 "nonimmediate_operand" "fm")))]
1110: "TARGET_CE"
1111: "fadd%.s %2,%1,%0")
1112:
1113: ;; subtract instructions
1114:
1115: (define_insn "subsi3"
1116: [(set (match_operand:SI 0 "general_operand" "=m,r,!a,?d")
1117: (minus:SI (match_operand:SI 1 "general_operand" "0,0,a,mrIKs")
1118: (match_operand:SI 2 "general_operand" "dIKs,mrIKs,J,0")))]
1119: ""
1120: "*
1121: {
1122: if (! operands_match_p (operands[0], operands[1]))
1123: {
1124: if (operands_match_p (operands[0], operands[2]))
1125: {
1126: if (GET_CODE (operands[1]) == CONST_INT)
1127: {
1128: if (INTVAL (operands[1]) > 0
1129: && INTVAL (operands[1]) <= 8)
1130: return \"subq%.l %1,%0\;neg%.l %0\";
1131: }
1132: return \"sub%.l %1,%0\;neg%.l %0\";
1133: }
1134: /* This case is matched by J, but negating -0x8000
1135: in an lea would give an invalid displacement.
1136: So do this specially. */
1137: if (INTVAL (operands[2]) == -0x8000)
1138: return \"mov%.l %1,%0\;sub%.l %2,%0\";
1139: return \"lea %1@(%n2),%0\";
1140: }
1141: if (GET_CODE (operands[2]) == CONST_INT)
1142: {
1143: if (INTVAL (operands[2]) > 0
1144: && INTVAL (operands[2]) <= 8)
1145: return \"subq%.l %2,%0\";
1146: if (ADDRESS_REG_P (operands[0])
1147: && INTVAL (operands[2]) >= -0x8000
1148: && INTVAL (operands[2]) < 0x8000)
1149: return \"sub%.w %2,%0\";
1150: }
1151: return \"sub%.l %2,%0\";
1152: }")
1153:
1154: (define_insn ""
1155: [(set (match_operand:SI 0 "general_operand" "=a")
1156: (minus:SI (match_operand:SI 1 "general_operand" "0")
1157: (sign_extend:SI (match_operand:HI 2 "general_operand" "rmn"))))]
1158: ""
1159: "sub%.w %2,%0")
1160:
1161: (define_insn "subhi3"
1162: [(set (match_operand:HI 0 "general_operand" "=m,r")
1163: (minus:HI (match_operand:HI 1 "general_operand" "0,0")
1164: (match_operand:HI 2 "general_operand" "dn,rmn")))]
1165: ""
1166: "sub%.w %2,%0")
1167:
1168: (define_insn ""
1169: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
1170: (minus:HI (match_dup 0)
1171: (match_operand:HI 1 "general_operand" "dn,rmn")))]
1172: ""
1173: "sub%.w %1,%0")
1174:
1175: (define_insn "subqi3"
1176: [(set (match_operand:QI 0 "general_operand" "=m,d")
1177: (minus:QI (match_operand:QI 1 "general_operand" "0,0")
1178: (match_operand:QI 2 "general_operand" "dn,dmn")))]
1179: ""
1180: "sub%.b %2,%0")
1181:
1182: (define_insn ""
1183: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
1184: (minus:QI (match_dup 0)
1185: (match_operand:QI 1 "general_operand" "dn,dmn")))]
1186: ""
1187: "sub%.b %1,%0")
1188:
1189: (define_insn "subdf3"
1190: [(set (match_operand:DF 0 "register_operand" "=f,f")
1191: (minus:DF (match_operand:DF 1 "nonimmediate_operand" "f,fm")
1192: (match_operand:DF 2 "nonimmediate_operand" "fm,f")))]
1193: "TARGET_CE"
1194: "*
1195: {
1196: if (FP_REG_P (operands[1]))
1197: return \"fsub%.d %2,%1,%0\";
1198: return \"frsub%.d %1,%2,%0\";
1199: }")
1200:
1201: (define_insn "subsf3"
1202: [(set (match_operand:SF 0 "register_operand" "=f,f")
1203: (minus:SF (match_operand:SF 1 "nonimmediate_operand" "f,fm")
1204: (match_operand:SF 2 "nonimmediate_operand" "fm,f")))]
1205: "TARGET_CE"
1206: "*
1207: {
1208: if (FP_REG_P (operands[1]))
1209: return \"fsub%.s %2,%1,%0\";
1210: return \"frsub%.s %1,%2,%0\";
1211: }")
1212:
1213: ;; multiply instructions
1214:
1215: (define_insn "mulhi3"
1216: [(set (match_operand:HI 0 "general_operand" "=d")
1217: (mult:HI (match_operand:HI 1 "general_operand" "%0")
1218: (match_operand:HI 2 "general_operand" "dmn")))]
1219: ""
1220: "muls %2,%0")
1221:
1222: (define_insn "mulhisi3"
1223: [(set (match_operand:SI 0 "general_operand" "=d")
1224: (mult:SI (match_operand:HI 1 "general_operand" "%0")
1225: (match_operand:HI 2 "general_operand" "dmn")))]
1226: ""
1227: "muls %2,%0")
1228:
1229: (define_insn "mulsi3"
1230: [(set (match_operand:SI 0 "general_operand" "=d")
1231: (mult:SI (match_operand:SI 1 "general_operand" "%0")
1232: (match_operand:SI 2 "general_operand" "dmsK")))]
1233: "TARGET_68020"
1234: "muls%.l %2,%0")
1235:
1236: (define_insn "umulhi3"
1237: [(set (match_operand:HI 0 "general_operand" "=d")
1238: (umult:HI (match_operand:HI 1 "general_operand" "%0")
1239: (match_operand:HI 2 "general_operand" "dmn")))]
1240: ""
1241: "mulu %2,%0")
1242:
1243: (define_insn "umulhisi3"
1244: [(set (match_operand:SI 0 "general_operand" "=d")
1245: (umult:SI (match_operand:HI 1 "general_operand" "%0")
1246: (match_operand:HI 2 "general_operand" "dmn")))]
1247: ""
1248: "mulu %2,%0")
1249:
1250: (define_insn "umulsi3"
1251: [(set (match_operand:SI 0 "general_operand" "=d")
1252: (umult:SI (match_operand:SI 1 "general_operand" "%0")
1253: (match_operand:SI 2 "general_operand" "dmsK")))]
1254: "TARGET_68020"
1255: "mulu%.l %2,%0")
1256:
1257: (define_insn "muldf3"
1258: [(set (match_operand:DF 0 "register_operand" "=f")
1259: (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%f")
1260: (match_operand:DF 2 "nonimmediate_operand" "fm")))]
1261: "TARGET_CE"
1262: "fmul%.d %2,%1,%0")
1263:
1264: (define_insn "mulsf3"
1265: [(set (match_operand:SF 0 "register_operand" "=f")
1266: (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%f")
1267: (match_operand:SF 2 "nonimmediate_operand" "fm")))]
1268: "TARGET_CE"
1269: "fmul%.s %2,%1,%0")
1270:
1271: ;; divide instructions
1272:
1273: (define_insn "divhi3"
1274: [(set (match_operand:HI 0 "general_operand" "=d")
1275: (div:HI (match_operand:HI 1 "general_operand" "0")
1276: (match_operand:HI 2 "general_operand" "dmn")))]
1277: ""
1278: "extl %0\;divs %2,%0")
1279:
1280: (define_insn "divhisi3"
1281: [(set (match_operand:HI 0 "general_operand" "=d")
1282: (div:HI (match_operand:SI 1 "general_operand" "0")
1283: (match_operand:HI 2 "general_operand" "dmn")))]
1284: ""
1285: "divs %2,%0")
1286:
1287: (define_insn "divsi3"
1288: [(set (match_operand:SI 0 "general_operand" "=d")
1289: (div:SI (match_operand:SI 1 "general_operand" "0")
1290: (match_operand:SI 2 "general_operand" "dmsK")))]
1291: "TARGET_68020"
1292: "divs%.l %2,%0,%0")
1293:
1294: (define_insn "udivhi3"
1295: [(set (match_operand:HI 0 "general_operand" "=d")
1296: (udiv:HI (match_operand:HI 1 "general_operand" "0")
1297: (match_operand:HI 2 "general_operand" "dmn")))]
1298: ""
1299: "and%.l %#0xFFFF,%0\;divu %2,%0")
1300:
1301: (define_insn "udivhisi3"
1302: [(set (match_operand:HI 0 "general_operand" "=d")
1303: (udiv:HI (match_operand:SI 1 "general_operand" "0")
1304: (match_operand:HI 2 "general_operand" "dmn")))]
1305: ""
1306: "divu %2,%0")
1307:
1308: (define_insn "udivsi3"
1309: [(set (match_operand:SI 0 "general_operand" "=d")
1310: (udiv:SI (match_operand:SI 1 "general_operand" "0")
1311: (match_operand:SI 2 "general_operand" "dmsK")))]
1312: "TARGET_68020"
1313: "divu%.l %2,%0,%0")
1314:
1315: (define_insn "divdf3"
1316: [(set (match_operand:DF 0 "register_operand" "=f,f")
1317: (div:DF (match_operand:DF 1 "nonimmediate_operand" "f,fm")
1318: (match_operand:DF 2 "nonimmediate_operand" "fm,f")))]
1319: "TARGET_CE"
1320: "*
1321: {
1322: if (FP_REG_P (operands[1]))
1323: return \"fdiv%.d %2,%1,%0\";
1324: return \"frdiv%.d %1,%2,%0\";
1325: }")
1326:
1327: (define_insn "divsf3"
1328: [(set (match_operand:SF 0 "register_operand" "=f,f")
1329: (div:SF (match_operand:SF 1 "nonimmediate_operand" "f,fm")
1330: (match_operand:SF 2 "nonimmediate_operand" "fm,f")))]
1331: "TARGET_CE"
1332: "*
1333: {
1334: if (FP_REG_P (operands[1]))
1335: return \"fdiv%.s %2,%1,%0\";
1336: return \"frdiv%.s %1,%2,%0\";
1337: }")
1338:
1339: ;; Remainder instructions.
1340:
1341: (define_insn "modhi3"
1342: [(set (match_operand:HI 0 "general_operand" "=d")
1343: (mod:HI (match_operand:HI 1 "general_operand" "0")
1344: (match_operand:HI 2 "general_operand" "dmn")))]
1345: ""
1346: "*
1347: {
1348: /* The swap insn produces cc's that don't correspond to the result. */
1349: CC_STATUS_INIT;
1350: return \"extl %0\;divs %2,%0\;swap %0\";
1351: }")
1352:
1353: (define_insn "modhisi3"
1354: [(set (match_operand:HI 0 "general_operand" "=d")
1355: (mod:HI (match_operand:SI 1 "general_operand" "0")
1356: (match_operand:HI 2 "general_operand" "dmn")))]
1357: ""
1358: "*
1359: {
1360: /* The swap insn produces cc's that don't correspond to the result. */
1361: CC_STATUS_INIT;
1362: return \"divs %2,%0\;swap %0\";
1363: }")
1364:
1365: (define_insn "umodhi3"
1366: [(set (match_operand:HI 0 "general_operand" "=d")
1367: (umod:HI (match_operand:HI 1 "general_operand" "0")
1368: (match_operand:HI 2 "general_operand" "dmn")))]
1369: ""
1370: "*
1371: {
1372: /* The swap insn produces cc's that don't correspond to the result. */
1373: CC_STATUS_INIT;
1374: return \"and%.l %#0xFFFF,%0\;divu %2,%0\;swap %0\";
1375: }")
1376:
1377: (define_insn "umodhisi3"
1378: [(set (match_operand:HI 0 "general_operand" "=d")
1379: (umod:HI (match_operand:SI 1 "general_operand" "0")
1380: (match_operand:HI 2 "general_operand" "dmn")))]
1381: ""
1382: "*
1383: {
1384: /* The swap insn produces cc's that don't correspond to the result. */
1385: CC_STATUS_INIT;
1386: return \"divu %2,%0\;swap %0\";
1387: }")
1388:
1389: (define_insn "divmodsi4"
1390: [(set (match_operand:SI 0 "general_operand" "=d")
1391: (div:SI (match_operand:SI 1 "general_operand" "0")
1392: (match_operand:SI 2 "general_operand" "dmsK")))
1393: (set (match_operand:SI 3 "general_operand" "=d")
1394: (mod:SI (match_dup 1) (match_dup 2)))]
1395: "TARGET_68020"
1396: "divs%.l %2,%0,%3")
1397:
1398: (define_insn "udivmodsi4"
1399: [(set (match_operand:SI 0 "general_operand" "=d")
1400: (udiv:SI (match_operand:SI 1 "general_operand" "0")
1401: (match_operand:SI 2 "general_operand" "dmsK")))
1402: (set (match_operand:SI 3 "general_operand" "=d")
1403: (umod:SI (match_dup 1) (match_dup 2)))]
1404: "TARGET_68020"
1405: "divu%.l %2,%0,%3")
1406:
1407: ;; logical-and instructions
1408:
1409: (define_insn "andsi3"
1410: [(set (match_operand:SI 0 "general_operand" "=m,d")
1411: (and:SI (match_operand:SI 1 "general_operand" "%0,0")
1412: (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
1413: ""
1414: "*
1415: {
1416: if (GET_CODE (operands[2]) == CONST_INT
1417: && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
1418: && (DATA_REG_P (operands[0])
1419: || offsettable_memref_p (operands[0])))
1420: {
1421: if (GET_CODE (operands[0]) != REG)
1422: operands[0] = adj_offsettable_operand (operands[0], 2);
1423: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1424: INTVAL (operands[2]) & 0xffff);
1425: /* Do not delete a following tstl %0 insn; that would be incorrect. */
1426: CC_STATUS_INIT;
1427: if (operands[2] == const0_rtx)
1428: return \"clr%.w %0\";
1429: return \"and%.w %2,%0\";
1430: }
1431: return \"and%.l %2,%0\";
1432: }")
1433:
1434: (define_insn "andhi3"
1435: [(set (match_operand:HI 0 "general_operand" "=m,d")
1436: (and:HI (match_operand:HI 1 "general_operand" "%0,0")
1437: (match_operand:HI 2 "general_operand" "dn,dmn")))]
1438: ""
1439: "and%.w %2,%0")
1440:
1441: (define_insn "andqi3"
1442: [(set (match_operand:QI 0 "general_operand" "=m,d")
1443: (and:QI (match_operand:QI 1 "general_operand" "%0,0")
1444: (match_operand:QI 2 "general_operand" "dn,dmn")))]
1445: ""
1446: "and%.b %2,%0")
1447:
1448: (define_insn ""
1449: [(set (match_operand:SI 0 "general_operand" "=d")
1450: (and:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "dm"))
1451: (match_operand:SI 2 "general_operand" "0")))]
1452: "GET_CODE (operands[2]) == CONST_INT
1453: && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
1454: "and%.w %1,%0")
1455:
1456: (define_insn ""
1457: [(set (match_operand:SI 0 "general_operand" "=d")
1458: (and:SI (zero_extend:SI (match_operand:QI 1 "general_operand" "dm"))
1459: (match_operand:SI 2 "general_operand" "0")))]
1460: "GET_CODE (operands[2]) == CONST_INT
1461: && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
1462: "and%.b %1,%0")
1463:
1464: ;; inclusive-or instructions
1465:
1466: (define_insn "iorsi3"
1467: [(set (match_operand:SI 0 "general_operand" "=m,d")
1468: (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
1469: (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
1470: ""
1471: "*
1472: {
1473: register int logval;
1474: if (GET_CODE (operands[2]) == CONST_INT
1475: && INTVAL (operands[2]) >> 16 == 0
1476: && (DATA_REG_P (operands[0])
1477: || offsettable_memref_p (operands[0])))
1478: {
1479: if (GET_CODE (operands[0]) != REG)
1480: operands[0] = adj_offsettable_operand (operands[0], 2);
1481: /* Do not delete a following tstl %0 insn; that would be incorrect. */
1482: CC_STATUS_INIT;
1483: return \"or%.w %2,%0\";
1484: }
1485: if (GET_CODE (operands[2]) == CONST_INT
1486: && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
1487: && (DATA_REG_P (operands[0])
1488: || offsettable_memref_p (operands[0])))
1489: {
1490: if (DATA_REG_P (operands[0]))
1491: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
1492: else
1493: {
1494: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
1495: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
1496: }
1497: return \"bset %1,%0\";
1498: }
1499: return \"or%.l %2,%0\";
1500: }")
1501:
1502: (define_insn "iorhi3"
1503: [(set (match_operand:HI 0 "general_operand" "=m,d")
1504: (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
1505: (match_operand:HI 2 "general_operand" "dn,dmn")))]
1506: ""
1507: "or%.w %2,%0")
1508:
1509: (define_insn "iorqi3"
1510: [(set (match_operand:QI 0 "general_operand" "=m,d")
1511: (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
1512: (match_operand:QI 2 "general_operand" "dn,dmn")))]
1513: ""
1514: "or%.b %2,%0")
1515:
1516: ;; xor instructions
1517:
1518: (define_insn "xorsi3"
1519: [(set (match_operand:SI 0 "general_operand" "=do,m")
1520: (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
1521: (match_operand:SI 2 "general_operand" "di,dKs")))]
1522: ""
1523: "*
1524: {
1525: if (GET_CODE (operands[2]) == CONST_INT
1526: && INTVAL (operands[2]) >> 16 == 0
1527: && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
1528: {
1529: if (! DATA_REG_P (operands[0]))
1530: operands[0] = adj_offsettable_operand (operands[0], 2);
1531: /* Do not delete a following tstl %0 insn; that would be incorrect. */
1532: CC_STATUS_INIT;
1533: return \"eor%.w %2,%0\";
1534: }
1535: return \"eor%.l %2,%0\";
1536: }")
1537:
1538: (define_insn "xorhi3"
1539: [(set (match_operand:HI 0 "general_operand" "=dm")
1540: (xor:HI (match_operand:HI 1 "general_operand" "%0")
1541: (match_operand:HI 2 "general_operand" "dn")))]
1542: ""
1543: "eor%.w %2,%0")
1544:
1545: (define_insn "xorqi3"
1546: [(set (match_operand:QI 0 "general_operand" "=dm")
1547: (xor:QI (match_operand:QI 1 "general_operand" "%0")
1548: (match_operand:QI 2 "general_operand" "dn")))]
1549: ""
1550: "eor%.b %2,%0")
1551:
1552: ;; negation instructions
1553:
1554: (define_insn "negsi2"
1555: [(set (match_operand:SI 0 "general_operand" "=dm")
1556: (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1557: ""
1558: "neg%.l %0")
1559:
1560: (define_insn "neghi2"
1561: [(set (match_operand:HI 0 "general_operand" "=dm")
1562: (neg:HI (match_operand:HI 1 "general_operand" "0")))]
1563: ""
1564: "neg%.w %0")
1565:
1566: (define_insn "negqi2"
1567: [(set (match_operand:QI 0 "general_operand" "=dm")
1568: (neg:QI (match_operand:QI 1 "general_operand" "0")))]
1569: ""
1570: "neg%.b %0")
1571:
1572: (define_insn "negsf2"
1573: [(set (match_operand:SF 0 "register_operand" "=f")
1574: (neg:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1575: "TARGET_CE"
1576: "fneg%.s %1,%0")
1577:
1578: (define_insn "negdf2"
1579: [(set (match_operand:DF 0 "register_operand" "=f")
1580: (neg:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1581: "TARGET_CE"
1582: "fneg%.d %1,%0")
1583:
1584: ;; Absolute value instructions
1585:
1586: (define_insn "abssf2"
1587: [(set (match_operand:SF 0 "register_operand" "=f")
1588: (abs:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1589: "TARGET_CE"
1590: "fabs%.s %1,%0")
1591:
1592: (define_insn "absdf2"
1593: [(set (match_operand:DF 0 "register_operand" "=f")
1594: (abs:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1595: "TARGET_CE"
1596: "fabs%.d %1,%0")
1597:
1598: ;; Square root instructions
1599:
1600: (define_insn "sqrtsf2"
1601: [(set (match_operand:SF 0 "register_operand" "=f")
1602: (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1603: "TARGET_CE"
1604: "fsqrt%.s %1,%0")
1605:
1606: (define_insn "sqrtdf2"
1607: [(set (match_operand:DF 0 "register_operand" "=f")
1608: (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1609: "TARGET_CE"
1610: "fsqrt%.d %1,%0")
1611:
1612: ;; one complement instructions
1613:
1614: (define_insn "one_cmplsi2"
1615: [(set (match_operand:SI 0 "general_operand" "=dm")
1616: (not:SI (match_operand:SI 1 "general_operand" "0")))]
1617: ""
1618: "not%.l %0")
1619:
1620: (define_insn "one_cmplhi2"
1621: [(set (match_operand:HI 0 "general_operand" "=dm")
1622: (not:HI (match_operand:HI 1 "general_operand" "0")))]
1623: ""
1624: "not%.w %0")
1625:
1626: (define_insn "one_cmplqi2"
1627: [(set (match_operand:QI 0 "general_operand" "=dm")
1628: (not:QI (match_operand:QI 1 "general_operand" "0")))]
1629: ""
1630: "not%.b %0")
1631:
1632: ;; Optimized special case of shifting.
1633: ;; Must precede the general case.
1634:
1635: (define_insn ""
1636: [(set (match_operand:SI 0 "general_operand" "=d")
1637: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1638: (const_int 24)))]
1639: "GET_CODE (XEXP (operands[1], 0)) != POST_INC
1640: && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC"
1641: "*
1642: {
1643: if (TARGET_68020)
1644: return \"mov%.b %1,%0\;extb%.l %0\";
1645: return \"mov%.b %1,%0\;ext%.w %0\;ext%.l %0\";
1646: }")
1647:
1648: (define_insn ""
1649: [(set (match_operand:SI 0 "general_operand" "=d")
1650: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1651: (const_int 24)))]
1652: "GET_CODE (XEXP (operands[1], 0)) != POST_INC
1653: && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC"
1654: "*
1655: {
1656: if (reg_mentioned_p (operands[0], operands[1]))
1657: return \"mov%.b %1,%0\;and%.l %#0xFF,%0\";
1658: return \"clr%.l %0\;mov%.b %1,%0\";
1659: }")
1660:
1661: (define_insn ""
1662: [(set (cc0) (compare (match_operand:QI 0 "general_operand" "i")
1663: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1664: (const_int 24))))]
1665: "(GET_CODE (operands[0]) == CONST_INT
1666: && (INTVAL (operands[0]) & ~0xff) == 0)"
1667: "* cc_status.flags |= CC_REVERSED;
1668: return \"cmp%.b %0,%1\";
1669: ")
1670:
1671: (define_insn ""
1672: [(set (cc0) (compare (lshiftrt:SI (match_operand:SI 0 "memory_operand" "m")
1673: (const_int 24))
1674: (match_operand:QI 1 "general_operand" "i")))]
1675: "(GET_CODE (operands[1]) == CONST_INT
1676: && (INTVAL (operands[1]) & ~0xff) == 0)"
1677: "*
1678: return \"cmp%.b %1,%0\";
1679: ")
1680:
1681: (define_insn ""
1682: [(set (cc0) (compare (match_operand:QI 0 "general_operand" "i")
1683: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1684: (const_int 24))))]
1685: "(GET_CODE (operands[0]) == CONST_INT
1686: && ((INTVAL (operands[0]) + 0x80) & ~0xff) == 0)"
1687: "* cc_status.flags |= CC_REVERSED;
1688: return \"cmp%.b %0,%1\";
1689: ")
1690:
1691: (define_insn ""
1692: [(set (cc0) (compare (ashiftrt:SI (match_operand:SI 0 "memory_operand" "m")
1693: (const_int 24))
1694: (match_operand:QI 1 "general_operand" "i")))]
1695: "(GET_CODE (operands[1]) == CONST_INT
1696: && ((INTVAL (operands[1]) + 0x80) & ~0xff) == 0)"
1697: "*
1698: return \"cmp%.b %1,%0\";
1699: ")
1700:
1701: ;; arithmetic shift instructions
1702: ;; We don't need the shift memory by 1 bit instruction
1703:
1704: (define_insn "ashlsi3"
1705: [(set (match_operand:SI 0 "general_operand" "=d")
1706: (ashift:SI (match_operand:SI 1 "general_operand" "0")
1707: (match_operand:SI 2 "general_operand" "dI")))]
1708: ""
1709: "asl%.l %2,%0")
1710:
1711: (define_insn "ashlhi3"
1712: [(set (match_operand:HI 0 "general_operand" "=d")
1713: (ashift:HI (match_operand:HI 1 "general_operand" "0")
1714: (match_operand:HI 2 "general_operand" "dI")))]
1715: ""
1716: "asl%.w %2,%0")
1717:
1718: (define_insn "ashlqi3"
1719: [(set (match_operand:QI 0 "general_operand" "=d")
1720: (ashift:QI (match_operand:QI 1 "general_operand" "0")
1721: (match_operand:QI 2 "general_operand" "dI")))]
1722: ""
1723: "asl%.b %2,%0")
1724:
1725: (define_insn "ashrsi3"
1726: [(set (match_operand:SI 0 "general_operand" "=d")
1727: (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1728: (match_operand:SI 2 "general_operand" "dI")))]
1729: ""
1730: "asr%.l %2,%0")
1731:
1732: (define_insn "ashrhi3"
1733: [(set (match_operand:HI 0 "general_operand" "=d")
1734: (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1735: (match_operand:HI 2 "general_operand" "dI")))]
1736: ""
1737: "asr%.w %2,%0")
1738:
1739: (define_insn "ashrqi3"
1740: [(set (match_operand:QI 0 "general_operand" "=d")
1741: (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
1742: (match_operand:QI 2 "general_operand" "dI")))]
1743: ""
1744: "asr%.b %2,%0")
1745:
1746: ;; logical shift instructions
1747:
1748: (define_insn "lshlsi3"
1749: [(set (match_operand:SI 0 "general_operand" "=d")
1750: (lshift:SI (match_operand:SI 1 "general_operand" "0")
1751: (match_operand:SI 2 "general_operand" "dI")))]
1752: ""
1753: "lsl%.l %2,%0")
1754:
1755: (define_insn "lshlhi3"
1756: [(set (match_operand:HI 0 "general_operand" "=d")
1757: (lshift:HI (match_operand:HI 1 "general_operand" "0")
1758: (match_operand:HI 2 "general_operand" "dI")))]
1759: ""
1760: "lsl%.w %2,%0")
1761:
1762: (define_insn "lshlqi3"
1763: [(set (match_operand:QI 0 "general_operand" "=d")
1764: (lshift:QI (match_operand:QI 1 "general_operand" "0")
1765: (match_operand:QI 2 "general_operand" "dI")))]
1766: ""
1767: "lsl%.b %2,%0")
1768:
1769: (define_insn "lshrsi3"
1770: [(set (match_operand:SI 0 "general_operand" "=d")
1771: (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1772: (match_operand:SI 2 "general_operand" "dI")))]
1773: ""
1774: "lsr%.l %2,%0")
1775:
1776: (define_insn "lshrhi3"
1777: [(set (match_operand:HI 0 "general_operand" "=d")
1778: (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1779: (match_operand:HI 2 "general_operand" "dI")))]
1780: ""
1781: "lsr%.w %2,%0")
1782:
1783: (define_insn "lshrqi3"
1784: [(set (match_operand:QI 0 "general_operand" "=d")
1785: (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1786: (match_operand:QI 2 "general_operand" "dI")))]
1787: ""
1788: "lsr%.b %2,%0")
1789:
1790: ;; rotate instructions
1791:
1792: (define_insn "rotlsi3"
1793: [(set (match_operand:SI 0 "general_operand" "=d")
1794: (rotate:SI (match_operand:SI 1 "general_operand" "0")
1795: (match_operand:SI 2 "general_operand" "dI")))]
1796: ""
1797: "rol%.l %2,%0")
1798:
1799: (define_insn "rotlhi3"
1800: [(set (match_operand:HI 0 "general_operand" "=d")
1801: (rotate:HI (match_operand:HI 1 "general_operand" "0")
1802: (match_operand:HI 2 "general_operand" "dI")))]
1803: ""
1804: "rol%.w %2,%0")
1805:
1806: (define_insn "rotlqi3"
1807: [(set (match_operand:QI 0 "general_operand" "=d")
1808: (rotate:QI (match_operand:QI 1 "general_operand" "0")
1809: (match_operand:QI 2 "general_operand" "dI")))]
1810: ""
1811: "rol%.b %2,%0")
1812:
1813: (define_insn "rotrsi3"
1814: [(set (match_operand:SI 0 "general_operand" "=d")
1815: (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1816: (match_operand:SI 2 "general_operand" "dI")))]
1817: ""
1818: "ror%.l %2,%0")
1819:
1820: (define_insn "rotrhi3"
1821: [(set (match_operand:HI 0 "general_operand" "=d")
1822: (rotatert:HI (match_operand:HI 1 "general_operand" "0")
1823: (match_operand:HI 2 "general_operand" "dI")))]
1824: ""
1825: "ror%.w %2,%0")
1826:
1827: (define_insn "rotrqi3"
1828: [(set (match_operand:QI 0 "general_operand" "=d")
1829: (rotatert:QI (match_operand:QI 1 "general_operand" "0")
1830: (match_operand:QI 2 "general_operand" "dI")))]
1831: ""
1832: "ror%.b %2,%0")
1833:
1834: ;; Special cases of bit-field insns which we should
1835: ;; recognize in preference to the general case.
1836: ;; These handle aligned 8-bit and 16-bit fields,
1837: ;; which can usually be done with move instructions.
1838:
1839: (define_insn ""
1840: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do")
1841: (match_operand:SI 1 "immediate_operand" "i")
1842: (match_operand:SI 2 "immediate_operand" "i"))
1843: (match_operand:SI 3 "general_operand" "d"))]
1844: "TARGET_68020 && TARGET_BITFIELD
1845: && GET_CODE (operands[1]) == CONST_INT
1846: && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
1847: && GET_CODE (operands[2]) == CONST_INT
1848: && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
1849: && (GET_CODE (operands[0]) == REG
1850: || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
1851: "*
1852: {
1853: if (REG_P (operands[0]))
1854: {
1855: if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
1856: return \"bfins %3,[%c2,%c1]%0\";
1857: }
1858: else
1859: operands[0]
1860: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
1861:
1862: if (GET_CODE (operands[3]) == MEM)
1863: operands[3] = adj_offsettable_operand (operands[3],
1864: (32 - INTVAL (operands[1])) / 8);
1865: if (INTVAL (operands[1]) == 8)
1866: return \"mov%.b %3,%0\";
1867: return \"mov%.w %3,%0\";
1868: }")
1869:
1870: (define_insn ""
1871: [(set (match_operand:SI 0 "general_operand" "=&d")
1872: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
1873: (match_operand:SI 2 "immediate_operand" "i")
1874: (match_operand:SI 3 "immediate_operand" "i")))]
1875: "TARGET_68020 && TARGET_BITFIELD
1876: && GET_CODE (operands[2]) == CONST_INT
1877: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
1878: && GET_CODE (operands[3]) == CONST_INT
1879: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
1880: && (GET_CODE (operands[1]) == REG
1881: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
1882: "*
1883: {
1884: if (REG_P (operands[1]))
1885: {
1886: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
1887: return \"bfextu [%c3,%c2]%1,%0\";
1888: }
1889: else
1890: operands[1]
1891: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
1892:
1893: output_asm_insn (\"clrl %0\", operands);
1894: if (GET_CODE (operands[0]) == MEM)
1895: operands[0] = adj_offsettable_operand (operands[0],
1896: (32 - INTVAL (operands[1])) / 8);
1897: if (INTVAL (operands[2]) == 8)
1898: return \"mov%.b %1,%0\";
1899: return \"mov%.w %1,%0\";
1900: }")
1901:
1902: (define_insn ""
1903: [(set (match_operand:SI 0 "general_operand" "=d")
1904: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
1905: (match_operand:SI 2 "immediate_operand" "i")
1906: (match_operand:SI 3 "immediate_operand" "i")))]
1907: "TARGET_68020 && TARGET_BITFIELD
1908: && GET_CODE (operands[2]) == CONST_INT
1909: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
1910: && GET_CODE (operands[3]) == CONST_INT
1911: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
1912: && (GET_CODE (operands[1]) == REG
1913: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
1914: "*
1915: {
1916: if (REG_P (operands[1]))
1917: {
1918: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
1919: return \"bfexts [%c3,%c2]%1,%0\";
1920: }
1921: else
1922: operands[1]
1923: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
1924:
1925: if (INTVAL (operands[2]) == 8)
1926: return \"mov%.b %1,%0\;extb%.l %0\";
1927: return \"mov%.w %1,%0\;ext%.l %0\";
1928: }")
1929:
1930: ;; Bit field instructions, general cases.
1931: ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
1932: ;; so that its address is reloaded.
1933:
1934: (define_insn "extv"
1935: [(set (match_operand:SI 0 "general_operand" "=d,d")
1936: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
1937: (match_operand:SI 2 "general_operand" "di,di")
1938: (match_operand:SI 3 "general_operand" "di,di")))]
1939: "TARGET_68020 && TARGET_BITFIELD"
1940: "bfexts [%c3,%c2]%1,%0")
1941:
1942: (define_insn "extzv"
1943: [(set (match_operand:SI 0 "general_operand" "=d,d")
1944: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
1945: (match_operand:SI 2 "general_operand" "di,di")
1946: (match_operand:SI 3 "general_operand" "di,di")))]
1947: "TARGET_68020 && TARGET_BITFIELD"
1948: "bfextu [%c3,%c2]%1,%0")
1949:
1950: (define_insn ""
1951: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
1952: (match_operand:SI 1 "general_operand" "di,di")
1953: (match_operand:SI 2 "general_operand" "di,di"))
1954: (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
1955: (match_operand 3 "immediate_operand" "i,i")))]
1956: "TARGET_68020 && TARGET_BITFIELD
1957: && GET_CODE (operands[3]) == CONST_INT
1958: && (INTVAL (operands[3]) == -1
1959: || (GET_CODE (operands[1]) == CONST_INT
1960: && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
1961: "*
1962: {
1963: CC_STATUS_INIT;
1964: return \"bfchg [%c2,%c1]%0\";
1965: }")
1966:
1967: (define_insn ""
1968: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
1969: (match_operand:SI 1 "general_operand" "di,di")
1970: (match_operand:SI 2 "general_operand" "di,di"))
1971: (const_int 0))]
1972: "TARGET_68020 && TARGET_BITFIELD"
1973: "*
1974: {
1975: CC_STATUS_INIT;
1976: return \"bfclr [%c2,%c1]%0\";
1977: }")
1978:
1979: (define_insn ""
1980: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
1981: (match_operand:SI 1 "general_operand" "di,di")
1982: (match_operand:SI 2 "general_operand" "di,di"))
1983: (const_int -1))]
1984: "TARGET_68020 && TARGET_BITFIELD"
1985: "*
1986: {
1987: CC_STATUS_INIT;
1988: return \"bfset [%c2,%c1]%0\";
1989: }")
1990:
1991: (define_insn "insv"
1992: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
1993: (match_operand:SI 1 "general_operand" "di,di")
1994: (match_operand:SI 2 "general_operand" "di,di"))
1995: (match_operand:SI 3 "general_operand" "d,d"))]
1996: "TARGET_68020 && TARGET_BITFIELD"
1997: "bfins %3,[%c2,%c1]%0")
1998:
1999: ;; Now recognize bit field insns that operate on registers
2000: ;; (or at least were intended to do so).
2001:
2002: (define_insn ""
2003: [(set (match_operand:SI 0 "general_operand" "=d")
2004: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
2005: (match_operand:SI 2 "general_operand" "di")
2006: (match_operand:SI 3 "general_operand" "di")))]
2007: "TARGET_68020 && TARGET_BITFIELD"
2008: "bfexts [%c3,%c2]%1,%0")
2009:
2010: (define_insn ""
2011: [(set (match_operand:SI 0 "general_operand" "=d")
2012: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
2013: (match_operand:SI 2 "general_operand" "di")
2014: (match_operand:SI 3 "general_operand" "di")))]
2015: "TARGET_68020 && TARGET_BITFIELD"
2016: "bfextu [%c3,%c2]%1,%0")
2017:
2018: (define_insn ""
2019: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
2020: (match_operand:SI 1 "general_operand" "di")
2021: (match_operand:SI 2 "general_operand" "di"))
2022: (const_int 0))]
2023: "TARGET_68020 && TARGET_BITFIELD"
2024: "*
2025: {
2026: CC_STATUS_INIT;
2027: return \"bfclr [%c2,%c1]%0\";
2028: }")
2029:
2030: (define_insn ""
2031: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
2032: (match_operand:SI 1 "general_operand" "di")
2033: (match_operand:SI 2 "general_operand" "di"))
2034: (const_int -1))]
2035: "TARGET_68020 && TARGET_BITFIELD"
2036: "*
2037: {
2038: CC_STATUS_INIT;
2039: return \"bfset [%c2,%c1]%0\";
2040: }")
2041:
2042: (define_insn ""
2043: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
2044: (match_operand:SI 1 "general_operand" "di")
2045: (match_operand:SI 2 "general_operand" "di"))
2046: (match_operand:SI 3 "general_operand" "d"))]
2047: "TARGET_68020 && TARGET_BITFIELD"
2048: "*
2049: {
2050: return \"bfins %3,[%c2,%c1]%0\";
2051: }")
2052:
2053: ;; Special patterns for optimizing bit-field instructions.
2054:
2055: (define_insn ""
2056: [(set (cc0)
2057: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
2058: (match_operand:SI 1 "general_operand" "di")
2059: (match_operand:SI 2 "general_operand" "di")))]
2060: "TARGET_68020 && TARGET_BITFIELD
2061: && GET_CODE (operands[1]) == CONST_INT"
2062: "*
2063: {
2064: if (operands[1] == const1_rtx
2065: && GET_CODE (operands[2]) == CONST_INT)
2066: {
2067: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
2068: return output_btst (operands,
2069: gen_rtx (CONST_INT, VOIDmode,
2070: width - INTVAL (operands[2])),
2071: operands[0],
2072: insn, 1000);
2073: /* Pass 1000 as SIGNPOS argument so that btst will
2074: not think we are testing the sign bit for an `and'
2075: and assume that nonzero implies a negative result. */
2076: }
2077: if (INTVAL (operands[1]) != 32)
2078: cc_status.flags = CC_NOT_NEGATIVE;
2079: return \"bftst [%c2,%c1]%0\";
2080: }")
2081:
2082: (define_insn ""
2083: [(set (cc0)
2084: (subreg:QI
2085: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
2086: (match_operand:SI 1 "general_operand" "di")
2087: (match_operand:SI 2 "general_operand" "di"))
2088: 0))]
2089: "TARGET_68020 && TARGET_BITFIELD
2090: && GET_CODE (operands[1]) == CONST_INT"
2091: "*
2092: {
2093: if (operands[1] == const1_rtx
2094: && GET_CODE (operands[2]) == CONST_INT)
2095: {
2096: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
2097: return output_btst (operands,
2098: gen_rtx (CONST_INT, VOIDmode,
2099: width - INTVAL (operands[2])),
2100: operands[0],
2101: insn, 1000);
2102: /* Pass 1000 as SIGNPOS argument so that btst will
2103: not think we are testing the sign bit for an `and'
2104: and assume that nonzero implies a negative result. */
2105: }
2106: if (INTVAL (operands[1]) != 32)
2107: cc_status.flags = CC_NOT_NEGATIVE;
2108: return \"bftst [%c2,%c1]%0\";
2109: }")
2110:
2111: (define_insn ""
2112: [(set (cc0)
2113: (subreg:HI
2114: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
2115: (match_operand:SI 1 "general_operand" "di")
2116: (match_operand:SI 2 "general_operand" "di"))
2117: 0))]
2118: "TARGET_68020 && TARGET_BITFIELD
2119: && GET_CODE (operands[1]) == CONST_INT"
2120: "*
2121: {
2122: if (operands[1] == const1_rtx
2123: && GET_CODE (operands[2]) == CONST_INT)
2124: {
2125: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
2126: return output_btst (operands,
2127: gen_rtx (CONST_INT, VOIDmode,
2128: width - INTVAL (operands[2])),
2129: operands[0],
2130: insn, 1000);
2131: /* Pass 1000 as SIGNPOS argument so that btst will
2132: not think we are testing the sign bit for an `and'
2133: and assume that nonzero implies a negative result. */
2134: }
2135: if (INTVAL (operands[1]) != 32)
2136: cc_status.flags = CC_NOT_NEGATIVE;
2137: return \"bftst [%c2,%c1]%0\";
2138: }")
2139:
2140: ;;; now handle the register cases
2141: (define_insn ""
2142: [(set (cc0)
2143: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
2144: (match_operand:SI 1 "general_operand" "di")
2145: (match_operand:SI 2 "general_operand" "di")))]
2146: "TARGET_68020 && TARGET_BITFIELD
2147: && GET_CODE (operands[1]) == CONST_INT"
2148: "*
2149: {
2150: if (operands[1] == const1_rtx
2151: && GET_CODE (operands[2]) == CONST_INT)
2152: {
2153: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
2154: return output_btst (operands,
2155: gen_rtx (CONST_INT, VOIDmode,
2156: width - INTVAL (operands[2])),
2157: operands[0],
2158: insn, 1000);
2159: /* Pass 1000 as SIGNPOS argument so that btst will
2160: not think we are testing the sign bit for an `and'
2161: and assume that nonzero implies a negative result. */
2162: }
2163: if (INTVAL (operands[1]) != 32)
2164: cc_status.flags = CC_NOT_NEGATIVE;
2165: return \"bftst [%c2,%c1]%0\";
2166: }")
2167:
2168: (define_insn ""
2169: [(set (cc0)
2170: (subreg:QI
2171: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
2172: (match_operand:SI 1 "general_operand" "di")
2173: (match_operand:SI 2 "general_operand" "di"))
2174: 0))]
2175: "TARGET_68020 && TARGET_BITFIELD
2176: && GET_CODE (operands[1]) == CONST_INT"
2177: "*
2178: {
2179: if (operands[1] == const1_rtx
2180: && GET_CODE (operands[2]) == CONST_INT)
2181: {
2182: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
2183: return output_btst (operands,
2184: gen_rtx (CONST_INT, VOIDmode,
2185: width - INTVAL (operands[2])),
2186: operands[0],
2187: insn, 1000);
2188: /* Pass 1000 as SIGNPOS argument so that btst will
2189: not think we are testing the sign bit for an `and'
2190: and assume that nonzero implies a negative result. */
2191: }
2192: if (INTVAL (operands[1]) != 32)
2193: cc_status.flags = CC_NOT_NEGATIVE;
2194: return \"bftst [%c2,%c1]%0\";
2195: }")
2196:
2197: (define_insn ""
2198: [(set (cc0)
2199: (subreg:HI
2200: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
2201: (match_operand:SI 1 "general_operand" "di")
2202: (match_operand:SI 2 "general_operand" "di"))
2203: 0))]
2204: "TARGET_68020 && TARGET_BITFIELD
2205: && GET_CODE (operands[1]) == CONST_INT"
2206: "*
2207: {
2208: if (operands[1] == const1_rtx
2209: && GET_CODE (operands[2]) == CONST_INT)
2210: {
2211: int width = GET_CODE (operands[0]) == REG ? 31 : 7;
2212: return output_btst (operands,
2213: gen_rtx (CONST_INT, VOIDmode,
2214: width - INTVAL (operands[2])),
2215: operands[0],
2216: insn, 1000);
2217: /* Pass 1000 as SIGNPOS argument so that btst will
2218: not think we are testing the sign bit for an `and'
2219: and assume that nonzero implies a negative result. */
2220: }
2221: if (INTVAL (operands[1]) != 32)
2222: cc_status.flags = CC_NOT_NEGATIVE;
2223: return \"bftst [%c2,%c1]%0\";
2224: }")
2225:
2226: (define_insn "seq"
2227: [(set (match_operand:QI 0 "general_operand" "=d")
2228: (eq (cc0) (const_int 0)))]
2229: ""
2230: "*
2231: cc_status = cc_prev_status;
2232: OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
2233: ")
2234:
2235: (define_insn "sne"
2236: [(set (match_operand:QI 0 "general_operand" "=d")
2237: (ne (cc0) (const_int 0)))]
2238: ""
2239: "*
2240: cc_status = cc_prev_status;
2241: OUTPUT_JUMP (\"sne %0\", \"fsneq %0\", \"sne %0\");
2242: ")
2243:
2244: (define_insn "sgt"
2245: [(set (match_operand:QI 0 "general_operand" "=d")
2246: (gt (cc0) (const_int 0)))]
2247: ""
2248: "*
2249: cc_status = cc_prev_status;
2250: OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", \"and%.b %#0xc,%!\;sgt %0\");
2251: ")
2252:
2253: (define_insn "sgtu"
2254: [(set (match_operand:QI 0 "general_operand" "=d")
2255: (gtu (cc0) (const_int 0)))]
2256: ""
2257: "* cc_status = cc_prev_status;
2258: return \"shi %0\"; ")
2259:
2260: (define_insn "slt"
2261: [(set (match_operand:QI 0 "general_operand" "=d")
2262: (lt (cc0) (const_int 0)))]
2263: ""
2264: "* cc_status = cc_prev_status;
2265: OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
2266:
2267: (define_insn "sltu"
2268: [(set (match_operand:QI 0 "general_operand" "=d")
2269: (ltu (cc0) (const_int 0)))]
2270: ""
2271: "* cc_status = cc_prev_status;
2272: return \"scs %0\"; ")
2273:
2274: (define_insn "sge"
2275: [(set (match_operand:QI 0 "general_operand" "=d")
2276: (ge (cc0) (const_int 0)))]
2277: ""
2278: "* cc_status = cc_prev_status;
2279: OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
2280:
2281: (define_insn "sgeu"
2282: [(set (match_operand:QI 0 "general_operand" "=d")
2283: (geu (cc0) (const_int 0)))]
2284: ""
2285: "* cc_status = cc_prev_status;
2286: return \"scc %0\"; ")
2287:
2288: (define_insn "sle"
2289: [(set (match_operand:QI 0 "general_operand" "=d")
2290: (le (cc0) (const_int 0)))]
2291: ""
2292: "*
2293: cc_status = cc_prev_status;
2294: OUTPUT_JUMP (\"sle %0\", \"fsle %0\", \"and%.b %#0xc,%!\;sle %0\");
2295: ")
2296:
2297: (define_insn "sleu"
2298: [(set (match_operand:QI 0 "general_operand" "=d")
2299: (leu (cc0) (const_int 0)))]
2300: ""
2301: "* cc_status = cc_prev_status;
2302: return \"sls %0\"; ")
2303:
2304: ;; Basic conditional jump instructions.
2305:
2306: (define_insn "beq"
2307: [(set (pc)
2308: (if_then_else (eq (cc0)
2309: (const_int 0))
2310: (label_ref (match_operand 0 "" ""))
2311: (pc)))]
2312: ""
2313: "*
2314: {
2315: OUTPUT_JUMP (\"jeq %l0\", \"fbeq %l0\", \"jeq %l0\");
2316: }")
2317:
2318: (define_insn "bne"
2319: [(set (pc)
2320: (if_then_else (ne (cc0)
2321: (const_int 0))
2322: (label_ref (match_operand 0 "" ""))
2323: (pc)))]
2324: ""
2325: "*
2326: {
2327: OUTPUT_JUMP (\"jne %l0\", \"fbneq %l0\", \"jne %l0\");
2328: }")
2329:
2330: (define_insn "bgt"
2331: [(set (pc)
2332: (if_then_else (gt (cc0)
2333: (const_int 0))
2334: (label_ref (match_operand 0 "" ""))
2335: (pc)))]
2336: ""
2337: "*
2338: OUTPUT_JUMP (\"jgt %l0\", \"fbgt %l0\", \"and%.b %#0xc,%!\;jgt %l0\");
2339: ")
2340:
2341: (define_insn "bgtu"
2342: [(set (pc)
2343: (if_then_else (gtu (cc0)
2344: (const_int 0))
2345: (label_ref (match_operand 0 "" ""))
2346: (pc)))]
2347: ""
2348: "*
2349: return \"jhi %l0\";
2350: ")
2351:
2352: (define_insn "blt"
2353: [(set (pc)
2354: (if_then_else (lt (cc0)
2355: (const_int 0))
2356: (label_ref (match_operand 0 "" ""))
2357: (pc)))]
2358: ""
2359: "*
2360: OUTPUT_JUMP (\"jlt %l0\", \"fblt %l0\", \"jmi %l0\");
2361: ")
2362:
2363: (define_insn "bltu"
2364: [(set (pc)
2365: (if_then_else (ltu (cc0)
2366: (const_int 0))
2367: (label_ref (match_operand 0 "" ""))
2368: (pc)))]
2369: ""
2370: "*
2371: return \"jcs %l0\";
2372: ")
2373:
2374: (define_insn "bge"
2375: [(set (pc)
2376: (if_then_else (ge (cc0)
2377: (const_int 0))
2378: (label_ref (match_operand 0 "" ""))
2379: (pc)))]
2380: ""
2381: "*
2382: OUTPUT_JUMP (\"jge %l0\", \"fbge %l0\", \"jpl %l0\");
2383: ")
2384:
2385: (define_insn "bgeu"
2386: [(set (pc)
2387: (if_then_else (geu (cc0)
2388: (const_int 0))
2389: (label_ref (match_operand 0 "" ""))
2390: (pc)))]
2391: ""
2392: "*
2393: return \"jcc %l0\";
2394: ")
2395:
2396: (define_insn "ble"
2397: [(set (pc)
2398: (if_then_else (le (cc0)
2399: (const_int 0))
2400: (label_ref (match_operand 0 "" ""))
2401: (pc)))]
2402: ""
2403: "*
2404: OUTPUT_JUMP (\"jle %l0\", \"fble %l0\", \"and%.b %#0xc,%!\;jle %l0\");
2405: ")
2406:
2407: (define_insn "bleu"
2408: [(set (pc)
2409: (if_then_else (leu (cc0)
2410: (const_int 0))
2411: (label_ref (match_operand 0 "" ""))
2412: (pc)))]
2413: ""
2414: "*
2415: return \"jls %l0\";
2416: ")
2417:
2418: ;; Negated conditional jump instructions.
2419:
2420: (define_insn ""
2421: [(set (pc)
2422: (if_then_else (eq (cc0)
2423: (const_int 0))
2424: (pc)
2425: (label_ref (match_operand 0 "" ""))))]
2426: ""
2427: "*
2428: {
2429: OUTPUT_JUMP (\"jne %l0\", \"fbneq %l0\", \"jne %l0\");
2430: }")
2431:
2432: (define_insn ""
2433: [(set (pc)
2434: (if_then_else (ne (cc0)
2435: (const_int 0))
2436: (pc)
2437: (label_ref (match_operand 0 "" ""))))]
2438: ""
2439: "*
2440: {
2441: OUTPUT_JUMP (\"jeq %l0\", \"fbeq %l0\", \"jeq %l0\");
2442: }")
2443:
2444: (define_insn ""
2445: [(set (pc)
2446: (if_then_else (gt (cc0)
2447: (const_int 0))
2448: (pc)
2449: (label_ref (match_operand 0 "" ""))))]
2450: ""
2451: "*
2452: OUTPUT_JUMP (\"jle %l0\", \"fbngt %l0\", \"and%.b %#0xc,%!\;jle %l0\");
2453: ")
2454:
2455: (define_insn ""
2456: [(set (pc)
2457: (if_then_else (gtu (cc0)
2458: (const_int 0))
2459: (pc)
2460: (label_ref (match_operand 0 "" ""))))]
2461: ""
2462: "*
2463: return \"jls %l0\";
2464: ")
2465:
2466: (define_insn ""
2467: [(set (pc)
2468: (if_then_else (lt (cc0)
2469: (const_int 0))
2470: (pc)
2471: (label_ref (match_operand 0 "" ""))))]
2472: ""
2473: "*
2474: OUTPUT_JUMP (\"jge %l0\", \"fbnlt %l0\", \"jpl %l0\");
2475: ")
2476:
2477: (define_insn ""
2478: [(set (pc)
2479: (if_then_else (ltu (cc0)
2480: (const_int 0))
2481: (pc)
2482: (label_ref (match_operand 0 "" ""))))]
2483: ""
2484: "*
2485: return \"jcc %l0\";
2486: ")
2487:
2488: (define_insn ""
2489: [(set (pc)
2490: (if_then_else (ge (cc0)
2491: (const_int 0))
2492: (pc)
2493: (label_ref (match_operand 0 "" ""))))]
2494: ""
2495: "*
2496: OUTPUT_JUMP (\"jlt %l0\", \"fbnge %l0\", \"jmi %l0\");
2497: ")
2498:
2499: (define_insn ""
2500: [(set (pc)
2501: (if_then_else (geu (cc0)
2502: (const_int 0))
2503: (pc)
2504: (label_ref (match_operand 0 "" ""))))]
2505: ""
2506: "*
2507: return \"jcs %l0\";
2508: ")
2509:
2510: (define_insn ""
2511: [(set (pc)
2512: (if_then_else (le (cc0)
2513: (const_int 0))
2514: (pc)
2515: (label_ref (match_operand 0 "" ""))))]
2516: ""
2517: "*
2518: OUTPUT_JUMP (\"jgt %l0\", \"fbnle %l0\", \"and%.b %#0xc,%!\;jgt %l0\");
2519: ")
2520:
2521: (define_insn ""
2522: [(set (pc)
2523: (if_then_else (leu (cc0)
2524: (const_int 0))
2525: (pc)
2526: (label_ref (match_operand 0 "" ""))))]
2527: ""
2528: "*
2529: return \"jhi %l0\";
2530: ")
2531:
2532: ;; Subroutines of "casesi".
2533:
2534: (define_expand "casesi_1"
2535: [(set (match_operand:SI 3 "general_operand" "")
2536: (plus:SI (match_operand:SI 0 "general_operand" "")
2537: ;; Note operand 1 has been negated!
2538: (match_operand:SI 1 "immediate_operand" "")))
2539: (set (cc0) (compare (match_operand:SI 2 "general_operand" "")
2540: (match_dup 3)))
2541: (set (pc) (if_then_else (ltu (cc0) (const_int 0))
2542: (label_ref (match_operand 4 "" "")) (pc)))]
2543: ""
2544: "")
2545:
2546: (define_expand "casesi_2"
2547: [(set (match_operand:SI 0 "" "") (mem:HI (match_operand:SI 1 "" "")))
2548: ;; The USE here is so that at least one jump-insn will refer to the label,
2549: ;; to keep it alive in jump_optimize.
2550: (parallel [(set (pc)
2551: (plus:SI (pc) (match_dup 0)))
2552: (use (label_ref (match_operand 2 "" "")))])]
2553: ""
2554: "")
2555:
2556: ;; Operand 0 is index (in bytes); operand 1 is minimum, operand 2 the maximum;
2557: ;; operand 3 is CODE_LABEL for the table;
2558: ;; operand 4 is the CODE_LABEL to go to if index out of range.
2559: (define_expand "casesi"
2560: ;; We don't use these for generating the RTL, but we must describe
2561: ;; the operands here.
2562: [(match_operand:SI 0 "general_operand" "")
2563: (match_operand:SI 1 "immediate_operand" "")
2564: (match_operand:SI 2 "general_operand" "")
2565: (match_operand 3 "" "")
2566: (match_operand 4 "" "")]
2567: ""
2568: "
2569: {
2570: rtx table_elt_addr;
2571: rtx index_diff;
2572:
2573: operands[1] = negate_rtx (SImode, operands[1]);
2574: index_diff = gen_reg_rtx (SImode);
2575: /* Emit the first few insns. */
2576: emit_insn (gen_casesi_1 (operands[0], operands[1], operands[2],
2577: index_diff, operands[4]));
2578: /* Construct a memory address. This may emit some insns. */
2579: table_elt_addr
2580: = memory_address_noforce
2581: (HImode,
2582: gen_rtx (PLUS, Pmode,
2583: gen_rtx (MULT, Pmode, index_diff,
2584: gen_rtx (CONST_INT, VOIDmode, 2)),
2585: gen_rtx (LABEL_REF, VOIDmode, operands[3])));
2586: /* Emit the last few insns. */
2587: emit_insn (gen_casesi_2 (gen_reg_rtx (HImode), table_elt_addr, operands[3]));
2588: DONE;
2589: }")
2590:
2591: ;; Recognize one of the insns resulting from casesi_2.
2592: (define_insn ""
2593: [(set (pc)
2594: (plus:SI (pc) (match_operand:HI 0 "general_operand" "r")))
2595: (use (label_ref (match_operand 1 "" "")))]
2596: ""
2597: "*
2598: return \"jmp pc@(2:B)[%0:W:B]\";
2599: ")
2600:
2601: ;; Unconditional and other jump instructions
2602: (define_insn "jump"
2603: [(set (pc)
2604: (label_ref (match_operand 0 "" "")))]
2605: ""
2606: "*
2607: return \"jra %l0\";
2608: ")
2609:
2610: (define_insn ""
2611: [(set (pc)
2612: (if_then_else
2613: (ne (compare (plus:HI (match_operand:HI 0 "general_operand" "g")
2614: (const_int -1))
2615: (const_int -1))
2616: (const_int 0))
2617: (label_ref (match_operand 1 "" ""))
2618: (pc)))
2619: (set (match_dup 0)
2620: (plus:HI (match_dup 0)
2621: (const_int -1)))]
2622: ""
2623: "*
2624: {
2625: if (DATA_REG_P (operands[0]))
2626: return \"dbra %0,%l1\";
2627: if (GET_CODE (operands[0]) == MEM)
2628: {
2629: return \"subq%.w %#1,%0\;jcc %l1\";
2630: }
2631: return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jne %l1\";
2632: }")
2633:
2634: (define_insn ""
2635: [(set (pc)
2636: (if_then_else
2637: (ne (compare (plus:SI (match_operand:SI 0 "general_operand" "g")
2638: (const_int -1))
2639: (const_int -1))
2640: (const_int 0))
2641: (label_ref (match_operand 1 "" ""))
2642: (pc)))
2643: (set (match_dup 0)
2644: (plus:SI (match_dup 0)
2645: (const_int -1)))]
2646: ""
2647: "*
2648: {
2649: if (DATA_REG_P (operands[0]))
2650: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jcc %l1\";
2651: if (GET_CODE (operands[0]) == MEM)
2652: return \"subq%.l %#1,%0\;jcc %l1\";
2653: return \"subq%.l %#1,%0\;cmp%.l %#-1,%0\;jne %l1\";
2654: }")
2655:
2656: ;; dbra patterns that use REG_NOTES info generated by strength_reduce.
2657:
2658: (define_insn ""
2659: [(set (pc)
2660: (if_then_else
2661: (ge (plus:SI (match_operand:SI 0 "general_operand" "g")
2662: (const_int -1))
2663: (const_int 0))
2664: (label_ref (match_operand 1 "" ""))
2665: (pc)))
2666: (set (match_dup 0)
2667: (plus:SI (match_dup 0)
2668: (const_int -1)))]
2669: "find_reg_note (insn, REG_NONNEG, 0)"
2670: "*
2671: {
2672: if (DATA_REG_P (operands[0]))
2673: return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\";
2674: if (GET_CODE (operands[0]) == MEM)
2675: return \"subq%.l %#1,%0\;jcc %l1\";
2676: return \"subq%.l %#1,%0\;cmp%.l %#-1,%0\;jne %l1\";
2677: }")
2678:
2679: ;; Call subroutine with no return value.
2680: (define_insn "call"
2681: [(call (match_operand:QI 0 "general_operand" "o")
2682: (match_operand:SI 1 "general_operand" "g"))]
2683: ""
2684: "*
2685: {
2686: rtx xoperands[2];
2687: int size = XINT(operands[1],0);
2688:
2689: if (size == 0)
2690: output_asm_insn (\"sub%.l a0,a0\;jbsr %0\", operands);
2691: else
2692: {
2693: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, size/4);
2694: output_asm_insn (\"mov%.l sp,a0\;pea %a1\", xoperands);
2695: output_asm_insn (\"jbsr %0\", operands);
2696: size = size + 4;
2697: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, size);
2698: if (size <= 8)
2699: output_asm_insn (\"addq%.l %1,sp\", xoperands);
2700: else if (size < 0x8000)
2701: output_asm_insn (\"add%.w %1,sp\", xoperands);
2702: else
2703: output_asm_insn (\"add%.l %1,sp\", xoperands);
2704: }
2705: return \"mov%.l a6@(-4),a0\";
2706: }")
2707:
2708: ;; Call subroutine, returning value in operand 0
2709: ;; (which must be a hard register).
2710: (define_insn "call_value"
2711: [(set (match_operand 0 "" "=rf")
2712: (call (match_operand:QI 1 "general_operand" "o")
2713: (match_operand:SI 2 "general_operand" "g")))]
2714: ""
2715: "*
2716: {
2717: rtx xoperands[3];
2718: int size = XINT(operands[2],0);
2719:
2720: if (size == 0)
2721: output_asm_insn(\"sub%.l a0,a0\;jbsr %1\", operands);
2722: else
2723: {
2724: xoperands[2] = gen_rtx (CONST_INT, VOIDmode, size/4);
2725: output_asm_insn (\"mov%.l sp,a0\;pea %a2\", xoperands);
2726: output_asm_insn (\"jbsr %1\", operands);
2727: size = size + 4;
2728: xoperands[2] = gen_rtx (CONST_INT, VOIDmode, size);
2729: if (size <= 8)
2730: output_asm_insn (\"addq%.l %2,sp\", xoperands);
2731: else if (size < 0x8000)
2732: output_asm_insn (\"add%.w %2,sp\", xoperands);
2733: else
2734: output_asm_insn (\"add%.l %2,sp\", xoperands);
2735: }
2736: return \"mov%.l a6@(-4),a0\";
2737: }")
2738:
2739: (define_insn "nop"
2740: [(const_int 0)]
2741: ""
2742: "nop")
2743:
2744: ;; This should not be used unless the add/sub insns can't be.
2745:
2746: (define_insn ""
2747: [(set (match_operand:SI 0 "general_operand" "=a")
2748: (match_operand:QI 1 "address_operand" "p"))]
2749: ""
2750: "lea %a1,%0")
2751:
2752: ;; This is the first machine-dependent peephole optimization.
2753: ;; It is useful when a floating value is returned from a function call
2754: ;; and then is moved into an FP register.
2755: ;; But it is mainly intended to test the support for these optimizations.
2756:
2757: ;Not applicable to Alliant -- floating results are returned in fp0
2758: ;(define_peephole
2759: ; [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
2760: ; (set (match_operand:DF 0 "register_operand" "f")
2761: ; (match_operand:DF 1 "register_operand" "ad"))]
2762: ; "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
2763: ; "*
2764: ;{
2765: ; rtx xoperands[2];
2766: ; xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
2767: ; output_asm_insn (\"mov%.l %1,%@\", xoperands);
2768: ; output_asm_insn (\"mov%.l %1,%-\", operands);
2769: ; return \"fmove%.d %+,%0\";
2770: ;}
2771: ;")
2772:
2773:
2774: ;;- Local variables:
2775: ;;- mode:emacs-lisp
2776: ;;- comment-start: ";;- "
2777: ;;- comment-start-skip: ";+- *"
2778: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2779: ;;- eval: (modify-syntax-entry ?[ "(]")
2780: ;;- eval: (modify-syntax-entry ?] ")[")
2781: ;;- eval: (modify-syntax-entry ?{ "(}")
2782: ;;- eval: (modify-syntax-entry ?} "){")
2783: ;;- End:
2784:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.