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