|
|
1.1 root 1: ;; GCC machine description for Intel 80386.
2: ;; Copyright (C) 1988 Free Software Foundation, Inc.
3: ;; Mostly by William Schelter.
4:
5: ;; This file is part of GNU CC.
6:
7: ;; GNU CC is free software; you can redistribute it and/or modify
8: ;; it under the terms of the GNU General Public License as published by
9: ;; the Free Software Foundation; either version 1, or (at your option)
10: ;; any later version.
11:
12: ;; GNU CC is distributed in the hope that it will be useful,
13: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: ;; GNU General Public License for more details.
16:
17: ;; You should have received a copy of the GNU General Public License
18: ;; along with GNU CC; see the file COPYING. If not, write to
19: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20:
21:
22: ;;- instruction definitions
23:
24: ;;- @@The original PO technology requires these to be ordered by speed,
25: ;;- @@ so that assigner will pick the fastest.
26:
27: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28:
29: ;;- When naming insn's (operand 0 of define_insn) be careful about using
30: ;;- names from other targets machine descriptions.
31:
32: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
33: ;;- updates for most instructions.
34:
35: ;;- Operand classes for the register allocator:
36: ;;- 'a' for eax
37: ;;- 'd' for edx
38: ;;- 'c' for ecx
39: ;;- 'b' for ebx
40: ;;- 'f' for anything in FLOAT_REGS
41: ;;- 'r' any (non-floating-point) register
42: ;;- 'q' regs that allow byte operations (A, B, C and D)
43: ;;- 'A' A and D registers
44:
45: ;; the special asm out single letter directives following a '%' are:
46: ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of operands[1]
47: ;; 's' output a '*'
48: ;; 'w' If the operand is a REG, it uses the mode size to determine the
49: ;; printing of the reg
50:
51:
52: ;; Put tstsi first among test insns so it matches a CONST_INT operand.
53:
54: (define_insn "tstsi"
55: [(set (cc0)
56: (match_operand:SI 0 "general_operand" "rm"))]
57: ""
58: "*
59: {
60: operands[1] = const0_rtx;
61: if (REG_P (operands[0]))
62: return AS2 (test%L0,%0,%0);
63: return AS2 (cmp%L0,%1,%0);
64: }")
65:
66: (define_insn "tsthi"
67: [(set (cc0)
68: (match_operand:HI 0 "general_operand" "rm"))]
69: ""
70: "*
71: {
72: operands[1] = const0_rtx;
73: if (REG_P (operands[0]))
74: return AS2 (test%W0,%0,%0);
75: return AS2 (cmp%W0,%1,%0);
76: }")
77:
78: (define_insn "tstqi"
79: [(set (cc0)
80: (match_operand:QI 0 "general_operand" "qm"))]
81: ""
82: "*
83: {
84: operands[1] = const0_rtx;
85: if (REG_P (operands[0]))
86: return AS2 (test%B0,%0,%0);
87: return AS2 (cmp%B0,%1,%0);
88: }")
89:
90: (define_insn "tstsf"
91: [(set (cc0)
92: (match_operand:SF 0 "general_operand" "rm,f"))
93: (clobber (reg:HI 0))]
94: "TARGET_80387"
95: "*
96: {
97: rtx xops[1];
98: if (!FP_REG_P (operands[0]))
99: fp_push_sf (operands[0]);
100: /* fp_pop_level--; */
101: xops[0] = FP_TOP;
102: cc_status.flags |= CC_IN_80387;
103: if (FP_REG_P (operands[0]) && ! top_dead_p (insn))
104: output_asm_insn (\"ftst\;fnstsw %R0ax\;sahf\", xops);
105: else
106: output_asm_insn (\"ftst\;fstp %0(0)\;fnstsw %R0ax\;sahf\", xops);
107: RETCOM (testsf);
108: }")
109:
110: (define_insn "tstdf"
111: [(set (cc0)
112: (match_operand:DF 0 "general_operand" "rm,f"))
113: (clobber (reg:HI 0))
114: ]
115: "TARGET_80387"
116: "*
117: {
118: rtx xops[1];
119: if (!FP_REG_P (operands[0]))
120: fp_push_df (operands[0]);
121: /* fp_pop_level--; */
122: xops[0] = FP_TOP;
123: cc_status.flags |= CC_IN_80387;
124: if (FP_REG_P (operands[0]) && ! top_dead_p (insn))
125: output_asm_insn (\"ftst\;fnstsw %R0ax\;sahf\", xops);
126: else
127: output_asm_insn (\"ftst\;fstp %0(0)\;fnstsw %R0ax\;sahf\", xops);
128: RETCOM (testdf);
129: }")
130:
131: ;;- compare instructions
132:
133: ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
134:
135: (define_insn "cmpsi"
136: [(set (cc0)
137: (compare (match_operand:SI 0 "general_operand" "mr,ri")
138: (match_operand:SI 1 "general_operand" "ri,mr")))]
139: ""
140: "*
141: {
142: if (REG_P (operands[1])
143: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
144: {
145: cc_status.flags |= CC_REVERSED;
146: return AS2 (cmp%L0,%0,%1);
147: }
148: return AS2 (cmp%L0,%1,%0);
149: }")
150:
151: (define_insn "cmphi"
152: [(set (cc0)
153: (compare (match_operand:HI 0 "general_operand" "mr,ri")
154: (match_operand:HI 1 "general_operand" "ri,mr")))]
155: ""
156: "*
157: {
158: if (REG_P (operands[1])
159: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
160: {
161: cc_status.flags |= CC_REVERSED;
162: return AS2 (cmp%W0,%0,%1);
163: }
164: return AS2 (cmp%W0,%1,%0);
165: }")
166:
167: (define_insn "cmpqi"
168: [(set (cc0)
169: (compare (match_operand:QI 0 "general_operand" "qn,mq")
170: (match_operand:QI 1 "general_operand" "qm,nq")))]
171: ""
172: "*
173: {
174: if (REG_P (operands[1])
175: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
176: {
177: cc_status.flags |= CC_REVERSED;
178: return AS2 (cmp%B0,%0,%1);
179: }
180: return AS2 (cmp%B0,%1,%0);
181: }")
182:
183: (define_insn "cmpdf"
184: [(set (cc0)
185: (compare (match_operand:DF 0 "general_operand" "m,f*r,m,f,r,!*r")
186: (match_operand:DF 1 "general_operand" "m,m,f*r,r,f,*r")))
187: (clobber (reg:SI 0))]
188: "TARGET_80387"
189: "*
190: {
191: if (FP_REG_P (operands[0]))
192: {
193: rtx tem = operands[1];
194: operands[1] = operands[0];
195: operands[0] = tem;
196: cc_status.flags |= CC_REVERSED;
197: }
198: if (! FP_REG_P (operands[1]))
199: output_movdf (FP_TOP, operands[1]);
200: output_movdf (FP_TOP, operands[0]);
201: /* fp_pop_level--;
202: fp_pop_level--; */
203: cc_status.flags |= CC_IN_80387;
204: return \"fcompp\;fnstsw %R0ax\;sahf\";
205: }")
206:
207: (define_insn "cmpsf"
208: [(set (cc0)
209: (compare (match_operand:SF 0 "general_operand" "m,f*r,m,f,r,!*r")
210: (match_operand:SF 1 "general_operand" "m,m,f*r,r,f,*r")))
211: (clobber (reg:SI 0))]
212: "TARGET_80387"
213: "*
214: {
215: if (FP_REG_P (operands[0]))
216: {
217: rtx tem = operands[1];
218: operands[1] = operands[0];
219: operands[0] = tem;
220: cc_status.flags |= CC_REVERSED;
221: }
222: if (! FP_REG_P (operands[1]))
223: output_movsf (FP_TOP, operands[1]);
224: output_movsf (FP_TOP, operands[0]);
225: /* fp_pop_level--;
226: fp_pop_level--; */
227: cc_status.flags |= CC_IN_80387;
228: return \"fcompp\;fnstsw %R0ax\;sahf\";
229: }")
230:
231: ;; logical compare
232: (define_insn ""
233: [(set (cc0)
234: (and:SI (match_operand:SI 0 "general_operand" "rm,ri")
235: (match_operand:SI 1 "general_operand" "ri,rm")))]
236: ""
237: "*
238: {
239: if (GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[0]) == MEM)
240: return AS2 (test%L0,%1,%0);
241: return AS2 (test%L0,%0,%1);
242: }")
243:
244: (define_insn ""
245: [(set (cc0)
246: (and:HI (match_operand:HI 0 "general_operand" "rm,ri")
247: (match_operand:HI 1 "general_operand" "ri,rm")))]
248: ""
249: "*
250: {
251: if (GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[0]) == MEM)
252: return AS2 (test%W0,%1,%0);
253: return AS2 (test%W0,%0,%1);
254: }")
255:
256: (define_insn ""
257: [(set (cc0)
258: (and:QI (match_operand:QI 0 "general_operand" "qm,qi")
259: (match_operand:QI 1 "general_operand" "qi,qm")))]
260: ""
261: "*
262: {
263: if (GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[0]) == MEM)
264: return AS2 (test%B0,%1,%0);
265: return AS2 (test%B0,%0,%1);
266: }")
267:
268: ;; move instructions.
269: ;; There is one for each machine mode,
270: ;; and each is preceded by a corresponding push-insn pattern
271: ;; (since pushes are not general_operands on the 386).
272:
273: (define_insn ""
274: [(set (match_operand:SI 0 "push_operand" "=<")
275: (match_operand:SI 1 "general_operand" "g"))]
276: ""
277: "push%L0 %1")
278:
279: ;; General case of fullword move.
280: (define_insn "movsi"
281: [(set (match_operand:SI 0 "general_operand" "=g,r")
282: (match_operand:SI 1 "general_operand" "ri,m"))]
283: ""
284: "*
285: {
286: rtx link;
287: if (operands[1] == const0_rtx && REG_P (operands[0]))
288: return \"xor%L0 %0,%0\";
289: if (operands[1] == const1_rtx
290: && (link = find_reg_note (insn, REG_WAS_0, 0))
291: /* Make sure the insn that stored the 0 is still present. */
292: && ! XEXP (link, 0)->volatil
293: && GET_CODE (XEXP (link, 0)) != NOTE
294: /* Make sure cross jumping didn't happen here. */
295: && no_labels_between_p (XEXP (link, 0), insn))
296: /* Fastest way to change a 0 to a 1. */
297: return \"inc%L0 %0\";
298: return \"mov%L0 %1,%0\";
299: }")
300:
301: (define_insn ""
302: [(set (match_operand:HI 0 "push_operand" "=<")
303: (match_operand:HI 1 "general_operand" "g"))]
304: ""
305: "push%W0 %1")
306:
307: (define_insn "movhi"
308: [(set (match_operand:HI 0 "general_operand" "=g,r")
309: (match_operand:HI 1 "general_operand" "ri,m"))]
310: ""
311: "*
312: {
313: rtx link;
314: if (operands[1] == const0_rtx && REG_P (operands[0]))
315: return \"xor%W0 %0,%0\";
316: if (operands[1] == const1_rtx
317: && (link = find_reg_note (insn, REG_WAS_0, 0))
318: /* Make sure the insn that stored the 0 is still present. */
319: && ! XEXP (link, 0)->volatil
320: && GET_CODE (XEXP (link, 0)) != NOTE
321: /* Make sure cross jumping didn't happen here. */
322: && no_labels_between_p (XEXP (link, 0), insn))
323: /* Fastest way to change a 0 to a 1. */
324: return \"inc%W0 %0\";
325: return \"mov%W0 %1,%0\";
326: }")
327:
328: ;; emit_push_insn when it calls move_by_pieces
329: ;; requires an insn to "push a byte".
330: ;; But actually we use pushw, which has the effect of rounding
331: ;; the amount pushed up to a halfword.
332: (define_insn ""
333: [(set (match_operand:QI 0 "push_operand" "=<")
334: (match_operand:QI 1 "general_operand" "q"))]
335: ""
336: "*
337: {
338: operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
339: return \"push%W0 %1\";
340: }")
341:
342: (define_insn "movqi"
343: [(set (match_operand:QI 0 "general_operand" "=q,*r,m")
344: (match_operand:QI 1 "general_operand" "*g,q,qi"))]
345: ""
346: "*
347: {
348: rtx link;
349: if (operands[1] == const0_rtx && REG_P (operands[0]))
350: return \"xor%B0 %0,%0\";
351: if (operands[1] == const1_rtx
352: && (link = find_reg_note (insn, REG_WAS_0, 0))
353: /* Make sure the insn that stored the 0 is still present. */
354: && ! XEXP (link, 0)->volatil
355: && GET_CODE (XEXP (link, 0)) != NOTE
356: /* Make sure cross jumping didn't happen here. */
357: && no_labels_between_p (XEXP (link, 0), insn))
358: /* Fastest way to change a 0 to a 1. */
359: return \"inc%B0 %0\";
360: /* If mov%B0 isn't allowed for one of these regs, use mov%W0. */
361: if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
362: return (AS2 (mov%W0,%w1,%w0));
363: return (AS2 (mov%B0,%1,%0));
364: }")
365:
366: ; I suspect nothing can ever match this ???
367: ;(define_insn ""
368: ; [(set (match_operand:SF 0 "general_operand" "rm")
369: ; (match_operand:SF 1 "general_operand" "f"))
370: ; (clobber (reg:SF 8))]
371: ; ""
372: ; "*
373: ;{
374: ; output_asm_insn ("???", operands);
375: ; fpop_sf (operands[0]);
376: ; RETCOM (movsf_clobber);
377: ;}")
378:
379: (define_insn ""
380: [(set (match_operand:SF 0 "push_operand" "=<,<")
381: (match_operand:SF 1 "general_operand" "gF,f"))]
382: ""
383: "*
384: {
385: if (FP_REG_P (operands[1]))
386: {
387: rtx xops[3];
388: xops[0] = AT_SP (SFmode);
389: xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
390: xops[2] = stack_pointer_rtx;
391: /* fp_pop_level--; */
392: output_asm_insn (AS2 (sub%L0,%1,%2), xops);
393: output_asm_insn (\"fstp%S0 %0\", xops);
394: RET;
395: }
396: return \"push%L0 %1\";
397: }")
398:
399: (define_insn "movsf"
400: [(set (match_operand:SF 0 "general_operand" "=rf,rmf,!rm")
401: (match_operand:SF 1 "general_operand" "m,rf,F"))]
402: ""
403: "*
404: {
405: if (FP_REG_P (operands[1])
406: && !FP_REG_P (operands[0])
407: && !top_dead_p (insn))
408: fp_store_sf (operands[0]);
409: else
410: output_movsf (operands[0], operands[1]);
411: RETCOM (movsf);
412: }")
413:
414: ;;should change to handle the memory operands[1] without doing df push..
415: (define_insn ""
416: [(set (match_operand:DF 0 "push_operand" "=<,<")
417: (match_operand:DF 1 "general_operand" "gF,f"))]
418: ""
419: "*
420: {
421: if (FP_REG_P (operands[1]))
422: {
423: rtx xops[3];
424: xops[0] = AT_SP (DFmode);
425: xops[1] = gen_rtx (CONST_INT, VOIDmode, 8);
426: xops[2] = stack_pointer_rtx;
427: /* fp_pop_level--; */
428: output_asm_insn (AS2 (sub%L0,%1,%2), xops);
429: output_asm_insn (\"fstp%Q0 %0\", xops);
430: RETCOM (pushdf);
431: }
432: else
433: return output_move_double (operands);
434: }")
435:
436: (define_insn "movdf"
437: [(set (match_operand:DF 0 "general_operand" "=&rf,rmf,!rm")
438: (match_operand:DF 1 "general_operand" "m,fr,F"))]
439: ""
440: "*
441: {
442: if (FP_REG_P (operands[1])
443: && ! FP_REG_P (operands[0])
444: && ! top_dead_p (insn))
445: fp_store_df (operands[0]);
446: else
447: output_movdf (operands[0], operands[1]);
448: RETCOM (movdf);
449: }")
450:
451: (define_insn ""
452: [(set (match_operand:DI 0 "push_operand" "=<")
453: (match_operand:DI 1 "general_operand" "roiF"))]
454: ""
455: "*
456: {
457: return output_move_double (operands);
458: }")
459:
460: (define_insn "movdi"
461: [(set (match_operand:DI 0 "general_operand" "=&r,rm")
462: (match_operand:DI 1 "general_operand" "m,riF"))]
463: ""
464: "*
465: {
466: return output_move_double (operands);
467: }")
468:
469: ;; These go after the move instructions
470: ;; because the move instructions are better (require no spilling)
471: ;; when they can apply. But these go before the add and subtract insns
472: ;; because it is often shorter to use these when both apply.
473:
474: ;Lennart Augustsson <[email protected]>
475: ;says this pattern just makes slower code:
476: ; pushl %ebp
477: ; addl $-80,(%esp)
478: ;instead of
479: ; leal -80(%ebp),%eax
480: ; pushl %eax
481: ;
482: ;(define_insn ""
483: ; [(set (match_operand:SI 0 "push_operand" "=<")
484: ; (plus:SI (match_operand:SI 1 "general_operand" "%r")
485: ; (match_operand:SI 2 "general_operand" "ri")))]
486: ; ""
487: ; "*
488: ;{
489: ; rtx xops[4];
490: ; xops[0] = operands[0];
491: ; xops[1] = operands[1];
492: ; xops[2] = operands[2];
493: ; xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
494: ; output_asm_insn (\"push%z1 %1\", xops);
495: ; output_asm_insn (AS2 (add%z3,%2,%3), xops);
496: ; RET;
497: ;}")
498:
499: (define_insn ""
500: [(set (match_operand:SI 0 "general_operand" "=g")
501: (plus:SI (match_operand:SI 1 "general_operand" "0")
502: (const_int 1)))]
503: ""
504: "inc%L0 %0")
505:
506: (define_insn ""
507: [(set (match_operand:SI 0 "general_operand" "=g")
508: (plus:SI (match_operand:SI 1 "general_operand" "0")
509: (const_int -1)))]
510: ""
511: "dec%L0 %0")
512:
513: (define_insn ""
514: [(set (match_operand:SI 0 "general_operand" "=g")
515: (minus:SI (match_operand:SI 1 "general_operand" "0")
516: (const_int 1)))]
517: ""
518: "dec%L0 %0")
519:
520: (define_insn ""
521: [(set (match_operand:SI 0 "register_operand" "=r")
522: (match_operand:QI 1 "address_operand" "p"))]
523: ""
524: "*
525: {
526: CC_STATUS_INIT;
527: /* Adding a constant to a register is faster with an add. */
528: if (GET_CODE (operands[1]) == PLUS
529: && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
530: && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
531: {
532: operands[1] = XEXP (operands[1], 1);
533: return AS2 (add%L0,%1,%0);
534: }
535: return \"lea%L0 %a1,%0\";
536: }")
537:
538: ;;- conversion instructions
539: ;;- NONE
540:
541: ;;- truncation instructions
542: (define_insn "truncsiqi2"
543: [(set (match_operand:QI 0 "general_operand" "=qm,q")
544: (truncate:QI
545: (match_operand:SI 1 "general_operand" "qi,m")))]
546: ""
547: "mov%B0 %1,%0")
548:
549: (define_insn "trunchiqi2"
550: [(set (match_operand:QI 0 "general_operand" "=qm,q")
551: (truncate:QI
552: (match_operand:HI 1 "general_operand" "qi,m")))]
553: ""
554: "mov%B0 %1,%0")
555:
556: (define_insn "truncsihi2"
557: [(set (match_operand:HI 0 "general_operand" "=rm,r")
558: (truncate:HI
559: (match_operand:SI 1 "general_operand" "ri,m")))]
560: ""
561: "mov%W0 %1,%0")
562:
563: ;;- zero extension instructions
564: ;; Note that the one starting from HImode comes before those for QImode
565: ;; so that a constant operand will match HImode, not QImode.
566:
567: (define_insn "zero_extendhisi2"
568: [(set (match_operand:SI 0 "general_operand" "=r")
569: (zero_extend:SI
570: (match_operand:HI 1 "general_operand" "rm")))]
571: ""
572: "movz%W0%L0 %1,%0")
573:
574: (define_insn "zero_extendqihi2"
575: [(set (match_operand:HI 0 "general_operand" "=r")
576: (zero_extend:HI
577: (match_operand:QI 1 "general_operand" "qm")))]
578: ""
579: "movz%B0%W0 %1,%0")
580:
581: (define_insn "zero_extendqisi2"
582: [(set (match_operand:SI 0 "general_operand" "=r")
583: (zero_extend:SI
584: (match_operand:QI 1 "general_operand" "qm")))]
585: ""
586: "movz%B0%L0 %1,%0")
587:
588: ;;- sign extension instructions
589: ;; Note that the one starting from HImode comes before those for QImode
590: ;; so that a constant operand will match HImode, not QImode.
591:
592: /*
593: (define_insn "extendsidi2"
594: [(set (match_operand:DI 0 "general_operand" "=a")
595: (sign_extend:DI
596: (match_operand:SI 1 "general_operand" "a")))]
597: ""
598: "clq")
599: */
600:
601: (define_insn "extendhisi2"
602: [(set (match_operand:SI 0 "general_operand" "=r")
603: (sign_extend:SI
604: (match_operand:HI 1 "general_operand" "rm")))]
605: ""
606: "movs%W0%L0 %1,%0")
607:
608: (define_insn "extendqihi2"
609: [(set (match_operand:HI 0 "general_operand" "=r")
610: (sign_extend:HI
611: (match_operand:QI 1 "general_operand" "qm")))]
612: ""
613: "movs%B0%W0 %1,%0")
614:
615: (define_insn "extendqisi2"
616: [(set (match_operand:SI 0 "general_operand" "=r")
617: (sign_extend:SI
618: (match_operand:QI 1 "general_operand" "qm")))]
619: ""
620: "movs%B0%L0 %1,%0"
621: )
622:
623: ;; Conversions between float and double.
624:
625: (define_insn "extendsfdf2"
626: [(set (match_operand:DF 0 "general_operand" "=fm,f,fm,fm")
627: (float_extend:DF
628: (match_operand:SF 1 "general_operand" "m,0,f,!*r")))]
629: "TARGET_80387"
630: "*
631: {
632: if (FP_REG_P (operands[0]))
633: {
634: output_movsf (operands[0], operands[1]);
635: RET;
636: }
637: if (FP_REG_P (operands[1]))
638: {
639: if (top_dead_p (insn))
640: fp_pop_df (operands[0]);
641: else
642: fp_store_df (operands[0]);
643: RET;
644: }
645: output_movsf (FP_TOP, operands[1]);
646: fp_pop_df (operands[0]);
647: RETCOM (extendsfdf2);
648: }")
649:
650: ;; This cannot output into an f-reg because there is no way to be
651: ;; sure of truncating in that case.
652: (define_insn "truncdfsf2"
653: [(set (match_operand:SF 0 "general_operand" "=m,!*r")
654: (float_truncate:SF
655: (match_operand:DF 1 "general_operand" "f,f")))]
656: "TARGET_80387"
657: "*
658: {
659: if (top_dead_p (insn))
660: fp_pop_sf (operands[0]);
661: else
662: fp_store_sf (operands[0]);
663: RETCOM (truncdfsf2);
664: }")
665:
666: ;; Conversion between fixed point and floating point.
667: ;; Note that among the fix-to-float insns
668: ;; the ones that start with SImode come first.
669: ;; That is so that an operand that is a CONST_INT
670: ;; (and therefore lacks a specific machine mode).
671: ;; will be recognized as SImode (which is always valid)
672: ;; rather than as QImode or HImode. The 80387 would not know
673: ;; what to do with the smaller sizes anyway. (I think).
674:
675: (define_insn "floatsisf2"
676: [(set (match_operand:SF 0 "general_operand" "=fm,fm")
677: (float:SF (match_operand:SI 1 "general_operand" "m,!*r")))]
678: "TARGET_80387"
679: "*
680: {
681: /* fp_pop_level++; */
682:
683: if (GET_CODE (operands[1]) != MEM)
684: {
685: rtx xops[2];
686: output_asm_insn (\"push%L0 %1\", operands);
687: operands[1] = AT_SP (SImode);
688: output_asm_insn (\"fild%L0 %1\", operands);
689: xops[0] = stack_pointer_rtx;
690: xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
691: output_asm_insn (AS2 (add%L0,%1,%0), xops);
692: }
693: else
694: output_asm_insn (\"fild%L0 %1\", operands);
695:
696: if (! FP_REG_P (operands[0]))
697: {
698: /* fp_pop_level--; */
699: return \"fstp%S0 %0\";
700: }
701: RET;
702: }")
703:
704: (define_insn "floatsidf2"
705: [(set (match_operand:DF 0 "general_operand" "=fm,fm")
706: (float:DF (match_operand:SI 1 "general_operand" "m,!*r")))]
707: "TARGET_80387"
708: "*
709: {
710: /* fp_pop_level++; */
711: if (GET_CODE (operands[1]) != MEM)
712: {
713: rtx xops[2];
714: output_asm_insn (\"push%L0 %1\", operands);
715: operands[1] = AT_SP (SImode);
716: output_asm_insn (\"fild%L0 %1\", operands);
717: xops[0] = stack_pointer_rtx;
718: xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
719: output_asm_insn (AS2 (add%L0,%1,%0), xops);
720: }
721: else
722: output_asm_insn (\"fild%L0 %1\", operands);
723: if (! FP_REG_P (operands[0]))
724: {
725: /* fp_pop_level--; */
726: return \"fstp%Q0 %0\";
727: }
728: RET;
729: }")
730:
731: ;; Convert a float to a float whose value is an integer.
732: ;; This is the first stage of converting it to an integer type.
733:
734: ;; On the 387 truncating doub to an short integer shor can be performed:
735:
736: ; fstcw -4(%esp) ;save cw
737: ; movw -4(%esp),%ax
738: ; orw $0x0c00,%ax ;set rounding to chop towards zero
739: ; movw %ax,-2(%esp) ;
740: ; fldcw -2(%esp) ;
741: ; fldl doubl
742: ; fistpl -12(%esp) ;store the round value
743: ; fldcw -4(%esp) ;restore cw
744: ; movl -12(%esp),%eax
745: ; movw %ax,shor ; move the result into shor.
746:
747: ;; but it is probably better to have a call, rather than waste this
748: ;; space. The last instruction would have been a movl if were
749: ;; going to an int instead of a short.
750: ;; For the moment we will go with the soft float for these.
751:
752: /* These are incorrect since they don't set the rounding bits of CW flag.
753: The proper way to do that is to make the function prologue save the CW
754: and also construct the alternate CW value needed for these insns.
755: Then these insns can output two fldcw's, referring to fixed places in
756: the stack frame.
757:
758: ;; Convert a float whose value is an integer
759: ;; to an actual integer. Second stage of converting float to integer type.
760:
761: (define_insn "fix_truncsfqi2"
762: [(set (match_operand:QI 0 "general_operand" "=m,?*q")
763: (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
764: "TARGET_80387"
765: "*
766: {
767: fp_pop_int (operands[0]);
768: RET;
769: }")
770:
771: (define_insn "fix_truncsfhi2"
772: [(set (match_operand:HI 0 "general_operand" "=m,?*r")
773: (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
774: "TARGET_80387"
775: "*
776: {
777: fp_pop_int (operands[0]);
778: RET;
779: }")
780:
781: (define_insn "fix_truncsfsi2"
782: [(set (match_operand:SI 0 "general_operand" "=m,?*r")
783: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
784: "TARGET_80387"
785: "*
786: {
787: fp_pop_int (operands[0]);
788: RET;
789: }")
790:
791: (define_insn "fix_truncdfqi2"
792: [(set (match_operand:QI 0 "general_operand" "=m,?*q")
793: (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
794:
795: "TARGET_80387"
796: "*
797: {
798: fp_pop_int (operands[0]);
799: RET;
800: }")
801:
802:
803: (define_insn "fix_truncdfhi2"
804: [(set (match_operand:HI 0 "general_operand" "=m,?*r")
805: (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
806: "TARGET_80387"
807: "*
808: {
809: fp_pop_int (operands[0]);
810: RET;
811: }")
812:
813:
814: (define_insn "fix_truncdfsi2"
815: [(set (match_operand:SI 0 "general_operand" "=m,?*r")
816: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
817: "TARGET_80387"
818: "*
819: {
820: fp_pop_int (operands[0]);
821: RET;
822: }")
823: */
824:
825:
826: ;;- add instructions
827: ;;moved incl to above leal
828:
829: (define_insn "addsi3"
830: [(set (match_operand:SI 0 "general_operand" "=rm,r")
831: (plus:SI (match_operand:SI 1 "general_operand" "%0,0")
832: (match_operand:SI 2 "general_operand" "ri,rm")))]
833: ""
834: "add%L0 %2,%0")
835:
836: (define_insn ""
837: [(set (match_operand:HI 0 "general_operand" "=g")
838: (plus:HI (match_operand:HI 1 "general_operand" "0")
839: (const_int 1)))]
840: ""
841: "inc%W0 %0")
842:
843: (define_insn "addhi3"
844: [(set (match_operand:HI 0 "general_operand" "=rm,r")
845: (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
846: (match_operand:HI 2 "general_operand" "ri,rm")))]
847: ""
848: "add%W0 %2,%0")
849:
850: (define_insn ""
851: [(set (match_operand:QI 0 "general_operand" "=qm")
852: (plus:QI (match_operand:QI 1 "general_operand" "0")
853: (const_int 1)))]
854: ""
855: "inc%B0 %0")
856:
857: (define_insn "addqi3"
858: [(set (match_operand:QI 0 "general_operand" "=m,q")
859: (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
860: (match_operand:QI 2 "general_operand" "qn,qmn")))]
861: ""
862: "add%B0 %2,%0")
863:
864: ;;had "fmF,m"
865:
866: (define_insn "adddf3"
867: [(set (match_operand:DF 0 "general_operand" "=f,m,f")
868: (plus:DF (match_operand:DF 1 "general_operand" "%0,0,0")
869: (match_operand:DF 2 "general_operand" "m,!f,!*r")))]
870: "TARGET_80387"
871: "*FP_CALL (\"fadd%z0 %0\", \"fadd%z0 %0\", 2)")
872:
873: (define_insn "addsf3"
874: [(set (match_operand:SF 0 "general_operand" "=f,m,f")
875: (plus:SF (match_operand:SF 1 "general_operand" "%0,0,0")
876: (match_operand:SF 2 "general_operand" "m,!f,!*r")))]
877: "TARGET_80387"
878: "*FP_CALL (\"fadd%z0 %0\", \"fadd%z0 %0\", 2)")
879:
880: ;;- subtract instructions
881:
882: ;;moved decl above leal
883:
884: (define_insn "subsi3"
885: [(set (match_operand:SI 0 "general_operand" "=rm,r")
886: (minus:SI (match_operand:SI 1 "general_operand" "0,0")
887: (match_operand:SI 2 "general_operand" "ri,rm")))]
888: ""
889: "sub%L0 %2,%0")
890:
891: (define_insn ""
892: [(set (match_operand:HI 0 "general_operand" "=g")
893: (minus:HI (match_operand:HI 1 "general_operand" "0")
894: (const_int 1)))]
895: ""
896: "dec%W0 %0")
897:
898: (define_insn "subhi3"
899: [(set (match_operand:HI 0 "general_operand" "=rm,r")
900: (minus:HI (match_operand:HI 1 "general_operand" "0,0")
901: (match_operand:HI 2 "general_operand" "ri,rm")))]
902: ""
903: "sub%W0 %2,%0")
904:
905: (define_insn ""
906: [(set (match_operand:QI 0 "general_operand" "=qm")
907: (minus:QI (match_operand:QI 1 "general_operand" "0")
908: (const_int 1)))]
909: ""
910: "dec%B0 %0")
911:
912: (define_insn "subqi3"
913: [(set (match_operand:QI 0 "general_operand" "=m,q")
914: (minus:QI (match_operand:QI 1 "general_operand" "0,0")
915: (match_operand:QI 2 "general_operand" "qn,qmn")))]
916: ""
917: "sub%B0 %2,%0")
918:
919: (define_insn "subdf3"
920: [(set (match_operand:DF 0 "general_operand" "=f,m,f,f")
921: (minus:DF (match_operand:DF 1 "general_operand" "0,0,0,m")
922: (match_operand:DF 2 "general_operand" "m,!f,!*r,*0")))]
923: "TARGET_80387"
924: "*FP_CALL (\"fsub%z0 %0\", \"fsubr%z0 %0\", 2)")
925:
926:
927: (define_insn "subsf3"
928: [(set (match_operand:SF 0 "general_operand" "=f,m,f,f")
929: (minus:SF (match_operand:SF 1 "general_operand" "0,0,0,m")
930: (match_operand:SF 2 "general_operand" "m,!f,!*r,*0")))]
931: "TARGET_80387"
932: "*FP_CALL (\"fsub%z0 %0\", \"fsubr%z0 %0\", 2)")
933:
934: ;;- multiply instructions
935:
936: ;(define_insn "mulqi3"
937: ; [(set (match_operand:QI 0 "general_operand" "=a")
938: ; (mult:QI (match_operand:QI 1 "general_operand" "%0")
939: ; (match_operand:QI 2 "general_operand" "qm")))]
940: ; ""
941: ; "mul%B0 %2,%0")
942:
943: (define_insn "mulhi3"
944: [(set (match_operand:HI 0 "general_operand" "=r,r")
945: (mult:SI (match_operand:HI 1 "general_operand" "%0,rm")
946: (match_operand:HI 2 "general_operand" "g,i")))]
947: ""
948: "*
949: {
950: if (GET_CODE (operands[1]) == REG
951: && REGNO (operands[1]) == REGNO (operands[0])
952: && (GET_CODE (operands[2]) == MEM
953: || GET_CODE (operands[2]) == REG))
954: /* Assembler has weird restrictions. */
955: return AS2 (imul%W0,%2,%0);
956: return AS3 (imul%W0,%2,%1,%0);
957: }")
958:
959: (define_insn "mulsi3"
960: [(set (match_operand:SI 0 "general_operand" "=r,r")
961: (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
962: (match_operand:SI 2 "general_operand" "g,i")))]
963: ""
964: "*
965: {
966: if (GET_CODE (operands[1]) == REG
967: && REGNO (operands[1]) == REGNO (operands[0])
968: && (GET_CODE (operands[2]) == MEM
969: || GET_CODE (operands[2]) == REG))
970: /* Assembler has weird restrictions. */
971: return AS2 (imul%L0,%2,%0);
972: return AS3 (imul%L0,%2,%1,%0);
973: }")
974:
975: ;; Turned off due to possible assembler bug.
976: ;(define_insn "umulqi3"
977: ; [(set (match_operand:QI 0 "general_operand" "=a")
978: ; (umult:QI (match_operand:QI 1 "general_operand" "%0")
979: ; (match_operand:QI 2 "general_operand" "qm")))]
980: ; ""
981: ; "mul%B0 %2,%0")
982:
983: ;(define_insn "umulqihi3"
984: ; [(set (match_operand:HI 0 "general_operand" "=a")
985: ; (umult:HI (match_operand:QI 1 "general_operand" "%0")
986: ; (match_operand:QI 2 "general_operand" "qm")))]
987: ; ""
988: ; "mul%B0 %2,%0")
989:
990: (define_insn "umulhi3"
991: [(set (match_operand:HI 0 "general_operand" "=a")
992: (umult:SI (match_operand:HI 1 "general_operand" "%0")
993: (match_operand:HI 2 "general_operand" "rm")))
994: (clobber (reg:HI 1))]
995: ""
996: "mul%W0 %2,%0")
997:
998: (define_insn "umulsi3"
999: [(set (match_operand:SI 0 "general_operand" "=a")
1000: (umult:SI (match_operand:SI 1 "general_operand" "%0")
1001: (match_operand:SI 2 "general_operand" "rm")))
1002: (clobber (reg:SI 1))]
1003: ""
1004: "mul%L0 %2,%0")
1005:
1006: (define_insn "muldf3"
1007: [(set (match_operand:DF 0 "general_operand" "=f,m,f")
1008: (mult:DF (match_operand:DF 1 "general_operand" "%0,0,0")
1009: (match_operand:DF 2 "general_operand" "m,!f,!*r")))]
1010: "TARGET_80387"
1011: "*FP_CALL (\"fmul%z0 %0\", \"fmul%z0 %0\", 2)
1012: ")
1013:
1014: (define_insn "mulsf3"
1015: [(set (match_operand:SF 0 "general_operand" "=f,m,f")
1016: (mult:SF (match_operand:SF 1 "general_operand" "%0,0,0")
1017: (match_operand:SF 2 "general_operand" "m,!f,!*r")))]
1018: "TARGET_80387"
1019: "*FP_CALL (\"fmul%z0 %0\", \"fmul%z0 %0\", 2)
1020: ")
1021:
1022: ;;- divide instructions
1023: (define_insn "divdf3"
1024: [(set (match_operand:DF 0 "general_operand" "=f,m,f,f")
1025: (div:DF (match_operand:DF 1 "general_operand" "0,0,0,m")
1026: (match_operand:DF 2 "general_operand" "m,!f,!*r,*0")))]
1027: "TARGET_80387"
1028: "*FP_CALL (\"fdiv%z0 %0\", \"fdivr%z0 %0\", 2)
1029: ")
1030:
1031: (define_insn "divsf3"
1032: [(set (match_operand:SF 0 "general_operand" "=f,m,f,f")
1033: (div:SF (match_operand:SF 1 "general_operand" "0,0,0,m")
1034: (match_operand:SF 2 "general_operand" "m,!f,!*r,*0")))]
1035: "TARGET_80387"
1036: "*FP_CALL (\"fdiv%z0 %0\", \"fdivr%z0 %0\", 2)
1037: ")
1038:
1039: ;; Remainder instructions.
1040:
1041: (define_insn "divmodsi4"
1042: [(set (match_operand:SI 0 "general_operand" "=a")
1043: (div:SI (match_operand:SI 1 "general_operand" "0")
1044: (match_operand:SI 2 "general_operand" "rm")))
1045: (set (match_operand:SI 3 "general_operand" "=&d")
1046: (mod:SI (match_dup 1) (match_dup 2)))]
1047: ""
1048: "cltd\;idiv%L0 %2")
1049:
1050: (define_insn "udivmodsi4"
1051: [(set (match_operand:SI 0 "general_operand" "=a")
1052: (udiv:SI (match_operand:SI 1 "general_operand" "0")
1053: (match_operand:SI 2 "general_operand" "rm")))
1054: (set (match_operand:SI 3 "general_operand" "=&d")
1055: (umod:SI (match_dup 1) (match_dup 2)))]
1056: ""
1057: "xor%L0 %3,%3\;div%L0 %2")
1058:
1059: /*
1060: ;;this should be a valid double division which we may want to add
1061:
1062: (define_insn ""
1063: [(set (match_operand:SI 0 "general_operand" "=a")
1064: (udiv:DI (match_operand:DI 1 "general_operand" "a")
1065: (match_operand:SI 2 "general_operand" "rm")))
1066: (set (match_operand:SI 3 "general_operand" "=d")
1067: (umod:SI (match_dup 1) (match_dup 2)))]
1068: ""
1069: "div%L0 %2,%0")
1070: */
1071:
1072: ;;- and instructions
1073:
1074: ;; The `r' in `rm' for operand 3 looks redundant, but it causes
1075: ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
1076:
1077: (define_insn "andsi3"
1078: [(set (match_operand:SI 0 "general_operand" "=rm,r")
1079: (and:SI (match_operand:SI 1 "general_operand" "%0,0")
1080: (match_operand:SI 2 "general_operand" "ri,rm")))]
1081: ""
1082: "and%L0 %2,%0")
1083:
1084: (define_insn "andhi3"
1085: [(set (match_operand:HI 0 "general_operand" "=rm,r")
1086: (and:HI (match_operand:HI 1 "general_operand" "%0,0")
1087: (match_operand:HI 2 "general_operand" "ri,rm")))]
1088: ""
1089: "and%W0 %2,%0")
1090:
1091: (define_insn "andqi3"
1092: [(set (match_operand:QI 0 "general_operand" "=m,q")
1093: (and:QI (match_operand:QI 1 "general_operand" "%0,0")
1094: (match_operand:QI 2 "general_operand" "qn,qmn")))]
1095: ""
1096: "and%B0 %2,%0")
1097:
1098: /* I am nervous about these two.. add them later..
1099: ;I presume this means that we have something in say op0= eax which is small
1100: ;and we want to and it with memory so we can do this by just an
1101: ;andb m,%al and have success.
1102: (define_insn ""
1103: [(set (match_operand:SI 0 "general_operand" "=r")
1104: (and:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rm"))
1105: (match_operand:SI 2 "general_operand" "0")))]
1106: "GET_CODE (operands[2]) == CONST_INT
1107: && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
1108: "and%W0 %1,%0")
1109:
1110: (define_insn ""
1111: [(set (match_operand:SI 0 "general_operand" "=q")
1112: (and:SI (zero_extend:SI (match_operand:QI 1 "general_operand" "qm"))
1113: (match_operand:SI 2 "general_operand" "0")))]
1114: "GET_CODE (operands[2]) == CONST_INT
1115: && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
1116: "and%L0 %1,%0")
1117:
1118: */
1119:
1120:
1121:
1122: ;;- Bit set (inclusive or) instructions
1123:
1124: (define_insn "iorsi3"
1125: [(set (match_operand:SI 0 "general_operand" "=rm,r")
1126: (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
1127: (match_operand:SI 2 "general_operand" "ri,rm")))]
1128: ""
1129: "or%L0 %2,%0")
1130:
1131: (define_insn "iorhi3"
1132: [(set (match_operand:HI 0 "general_operand" "=rm,r")
1133: (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
1134: (match_operand:HI 2 "general_operand" "ri,rm")))]
1135: ""
1136: "or%W0 %2,%0")
1137:
1138: (define_insn "iorqi3"
1139: [(set (match_operand:QI 0 "general_operand" "=m,q")
1140: (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
1141: (match_operand:QI 2 "general_operand" "qn,qmn")))]
1142: ""
1143: "or%B0 %2,%0")
1144:
1145: ;;- xor instructions
1146:
1147: (define_insn "xorsi3"
1148: [(set (match_operand:SI 0 "general_operand" "=rm,r")
1149: (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
1150: (match_operand:SI 2 "general_operand" "ri,rm")))]
1151: ""
1152: "xor%L0 %2,%0")
1153:
1154: (define_insn "xorhi3"
1155: [(set (match_operand:HI 0 "general_operand" "=rm,r")
1156: (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
1157: (match_operand:HI 2 "general_operand" "ri,rm")))]
1158: ""
1159: "xor%W0 %2,%0")
1160:
1161: (define_insn "xorqi3"
1162: [(set (match_operand:QI 0 "general_operand" "=qm")
1163: (xor:QI (match_operand:QI 1 "general_operand" "%0")
1164: (match_operand:QI 2 "general_operand" "qn")))]
1165: ""
1166: "xor%B0 %2,%0")
1167:
1168: ;;- negation instructions
1169: (define_insn "negsi2"
1170: [(set (match_operand:SI 0 "general_operand" "=rm")
1171: (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1172: ""
1173: "neg%L0 %0")
1174:
1175: (define_insn "neghi2"
1176: [(set (match_operand:HI 0 "general_operand" "=rm")
1177: (neg:HI (match_operand:HI 1 "general_operand" "0")))]
1178: ""
1179: "neg%W0 %0")
1180:
1181: (define_insn "negqi2"
1182: [(set (match_operand:QI 0 "general_operand" "=qm")
1183: (neg:QI (match_operand:QI 1 "general_operand" "0")))]
1184: ""
1185: "neg%B0 %0")
1186:
1187: (define_insn "negsf2"
1188: [(set (match_operand:SF 0 "general_operand" "=f,!m")
1189: (neg:SF (match_operand:SF 1 "general_operand" "0,0")))]
1190: "TARGET_80387"
1191: "*FP_CALL1 (\"fchs\")")
1192:
1193: (define_insn "negdf2"
1194: [(set (match_operand:DF 0 "general_operand" "=f,!m")
1195: (neg:DF (match_operand:DF 1 "general_operand" "0,0")))]
1196: "TARGET_80387"
1197: "*FP_CALL1 (\"fchs\")")
1198:
1199: ;; Absolute value instructions
1200:
1201: (define_insn "abssf2"
1202: [(set (match_operand:SF 0 "general_operand" "=f,!m")
1203: (abs:SF (match_operand:SF 1 "general_operand" "0,0")))]
1204: "TARGET_80387"
1205: "*FP_CALL1 (\"fabs\")")
1206:
1207: (define_insn "absdf2"
1208: [(set (match_operand:DF 0 "general_operand" "=f,!m")
1209: (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1210: "TARGET_80387"
1211: "*FP_CALL1 (\"fabs\")")
1212:
1213: ;;- one complement instructions
1214: (define_insn "one_cmplsi2"
1215: [(set (match_operand:SI 0 "general_operand" "=rm")
1216: (not:SI (match_operand:SI 1 "general_operand" "0")))]
1217: ""
1218: "not%L0 %0")
1219:
1220: (define_insn "one_cmplhi2"
1221: [(set (match_operand:HI 0 "general_operand" "=rm")
1222: (not:HI (match_operand:HI 1 "general_operand" "0")))]
1223: ""
1224: "not%W0 %0")
1225:
1226: (define_insn "one_cmplqi2"
1227: [(set (match_operand:QI 0 "general_operand" "=qm")
1228: (not:QI (match_operand:QI 1 "general_operand" "0")))]
1229: ""
1230: "not%B0 %0")
1231:
1232: ;;- arithmetic shift instructions
1233:
1234: (define_insn "ashlsi3"
1235: [(set (match_operand:SI 0 "general_operand" "=rm")
1236: (ashift:SI (match_operand:SI 1 "general_operand" "0")
1237: (match_operand:SI 2 "general_operand" "cI")))]
1238: ""
1239: "*
1240: {
1241: if (REG_P (operands[2]))
1242: return AS2 (sal%L0,%R0cl,%0);
1243: else if (REG_P (operands[1]) && GET_CODE (operands[2]) == CONST_INT
1244: && INTVAL (operands[2]) == 1)
1245: return AS2 (add%L0,%1,%1);
1246: return AS2 (sal%L0,%2,%1);
1247: }")
1248:
1249: (define_insn "ashlhi3"
1250: [(set (match_operand:HI 0 "general_operand" "=rm")
1251: (ashift:HI (match_operand:HI 1 "general_operand" "0")
1252: (match_operand:HI 2 "general_operand" "cI")))]
1253: ""
1254: "*
1255: {
1256: if (REG_P (operands[2]))
1257: return AS2 (sal%W0,%R0cl,%0);
1258: else
1259: return AS2 (sal%W0,%2,%1);
1260: }")
1261:
1262: (define_insn "ashlqi3"
1263: [(set (match_operand:QI 0 "general_operand" "=qm")
1264: (ashift:QI (match_operand:QI 1 "general_operand" "0")
1265: (match_operand:QI 2 "general_operand" "cI")))]
1266: ""
1267: "*
1268: {
1269: if (REG_P (operands[2]))
1270: return AS2 (sal%B0,%R0cl,%0);
1271: else
1272: return AS2 (sal%B0,%2,%1);
1273: }")
1274:
1275: (define_insn "ashrsi3"
1276: [(set (match_operand:SI 0 "general_operand" "=rm")
1277: (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1278: (match_operand:SI 2 "general_operand" "cI")))]
1279: ""
1280: "*
1281: {
1282: if (REG_P (operands[2]))
1283: return AS2 (sar%L0,%R0cl,%0);
1284: else
1285: return AS2 (sar%L0,%2,%0);
1286: }")
1287:
1288: (define_insn "ashrhi3"
1289: [(set (match_operand:HI 0 "general_operand" "=rm")
1290: (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1291: (match_operand:HI 2 "general_operand" "cI")))]
1292: ""
1293: "*
1294: {
1295: if (REG_P (operands[2]))
1296: return AS2 (sar%W0,%R0cl,%0);
1297: else
1298: return AS2 (sar%W0,%2,%0);
1299: }")
1300:
1301: (define_insn "ashrqi3"
1302: [(set (match_operand:QI 0 "general_operand" "=qm")
1303: (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
1304: (match_operand:QI 2 "general_operand" "cI")))]
1305: ""
1306: "*
1307: {
1308: if (REG_P (operands[2]))
1309: return AS2 (sar%B0,%R0cl,%0);
1310: return
1311: AS2 (sar%B0,%2,%1);
1312: }")
1313:
1314: ;;- logical shift instructions
1315:
1316: (define_insn "lshlsi3"
1317: [(set (match_operand:SI 0 "general_operand" "=rm")
1318: (lshift:SI (match_operand:SI 1 "general_operand" "0")
1319: (match_operand:SI 2 "general_operand" "cI")))]
1320: ""
1321: "*
1322: {
1323: if (REG_P (operands[2]))
1324: return AS2 (shl%L0,%R0cl,%0);
1325: else
1326: return AS2 (shl%L0,%2,%1);
1327: }")
1328:
1329: (define_insn "lshlhi3"
1330: [(set (match_operand:HI 0 "general_operand" "=rm")
1331: (lshift:HI (match_operand:HI 1 "general_operand" "0")
1332: (match_operand:HI 2 "general_operand" "cI")))]
1333: ""
1334: "*
1335: {
1336: if (REG_P (operands[2]))
1337: return AS2 (shl%W0,%R0cl,%0);
1338: else
1339: return AS2 (shl%W0,%2,%1);
1340: }")
1341:
1342: (define_insn "lshlqi3"
1343: [(set (match_operand:QI 0 "general_operand" "=qm")
1344: (lshift:QI (match_operand:QI 1 "general_operand" "0")
1345: (match_operand:QI 2 "general_operand" "cI")))]
1346: ""
1347: "*
1348: {
1349: if (REG_P (operands[2]))
1350: return AS2 (shl%B0,%R0cl,%0);
1351: else
1352: return AS2 (shl%B0,%2,%1);
1353: }")
1354:
1355: (define_insn "lshrsi3"
1356: [(set (match_operand:SI 0 "general_operand" "=rm")
1357: (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1358: (match_operand:SI 2 "general_operand" "cI")))]
1359: ""
1360: "*
1361: {
1362: if (REG_P (operands[2]))
1363: return AS2 (shr%L0,%R0cl,%0);
1364: else
1365: return AS2 (shr%L0,%2,%1);
1366: }")
1367:
1368: (define_insn "lshrhi3"
1369: [(set (match_operand:HI 0 "general_operand" "=rm")
1370: (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1371: (match_operand:HI 2 "general_operand" "cI")))]
1372: ""
1373: "*
1374: {
1375: if (REG_P (operands[2]))
1376: return AS2 (shr%W0,%%cl,%0);
1377: else
1378: return AS2 (shr%W0,%2,%1);
1379: }")
1380:
1381: (define_insn "lshrqi3"
1382: [(set (match_operand:QI 0 "general_operand" "=qm")
1383: (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1384: (match_operand:QI 2 "general_operand" "cI")))]
1385: ""
1386: "*
1387: {
1388: if (REG_P (operands[2]))
1389: return AS2 (shr%B0,%%cl,%0);
1390: else
1391: return AS2 (shr%B0,%2,%1);
1392: }")
1393:
1394: ;;- rotate instructions
1395:
1396: (define_insn "rotlsi3"
1397: [(set (match_operand:SI 0 "general_operand" "=rm")
1398: (rotate:SI (match_operand:SI 1 "general_operand" "0")
1399: (match_operand:SI 2 "general_operand" "cI")))]
1400: ""
1401: "*
1402: {
1403: if (REG_P (operands[2]))
1404: return AS2 (rol%L0,%%cl,%0);
1405: else
1406: return AS2 (rol%L0,%2,%1);
1407: }")
1408:
1409: (define_insn "rotlhi3"
1410: [(set (match_operand:HI 0 "general_operand" "=rm")
1411: (rotate:HI (match_operand:HI 1 "general_operand" "0")
1412: (match_operand:HI 2 "general_operand" "cI")))]
1413: ""
1414: "*
1415: {
1416: if (REG_P (operands[2]))
1417: return AS2 (rol%W0,%%cl,%0);
1418: else
1419: return AS2 (rol%W0,%2,%1);
1420: }")
1421:
1422: (define_insn "rotlqi3"
1423: [(set (match_operand:QI 0 "general_operand" "=qm")
1424: (rotate:QI (match_operand:QI 1 "general_operand" "0")
1425: (match_operand:QI 2 "general_operand" "cI")))]
1426: ""
1427: "*
1428: {
1429: if (REG_P (operands[2]))
1430: return AS2 (rol%B0,%%cl,%0);
1431: else
1432: return AS2 (rol%B0,%2,%1);
1433: }")
1434:
1435: (define_insn "rotrsi3"
1436: [(set (match_operand:SI 0 "general_operand" "=rm")
1437: (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1438: (match_operand:SI 2 "general_operand" "cI")))]
1439: ""
1440: "*
1441: {
1442: if (REG_P (operands[2]))
1443: return AS2 (ror%L0,%%cl,%0);
1444: else
1445: return AS2 (ror%L0,%2,%1);
1446: }")
1447:
1448: (define_insn "rotrhi3"
1449: [(set (match_operand:HI 0 "general_operand" "=rm")
1450: (rotatert:HI (match_operand:HI 1 "general_operand" "0")
1451: (match_operand:HI 2 "general_operand" "cI")))]
1452: ""
1453: "*
1454: {
1455: if (REG_P (operands[2]))
1456: return AS2 (ror%W0,%%cl,%0);
1457: else
1458: return AS2 (ror%W0,%2,%1);
1459: }")
1460:
1461: (define_insn "rotrqi3"
1462: [(set (match_operand:QI 0 "general_operand" "=qm")
1463: (rotatert:QI (match_operand:QI 1 "general_operand" "0")
1464: (match_operand:QI 2 "general_operand" "cI")))]
1465: ""
1466: "*
1467: {
1468: if (REG_P (operands[2]))
1469: return AS2 (ror%B0,%%cl,%0);
1470: else
1471: return AS2 (ror%B0,%2,%1);
1472: }")
1473:
1474: ;; Store-flag instructions.
1475:
1476: (define_insn "seq"
1477: [(set (match_operand:QI 0 "general_operand" "=q")
1478: (eq (cc0) (const_int 0)))]
1479: ""
1480: "*
1481: cc_status = cc_prev_status;
1482: return \"sete %0\";
1483: ")
1484:
1485: (define_insn "sne"
1486: [(set (match_operand:QI 0 "general_operand" "=q")
1487: (ne (cc0) (const_int 0)))]
1488: ""
1489: "*
1490: cc_status = cc_prev_status;
1491: return \"setne %0\";
1492: ")
1493:
1494: (define_insn "sgt"
1495: [(set (match_operand:QI 0 "general_operand" "=q")
1496: (gt (cc0) (const_int 0)))]
1497: ""
1498: "*
1499: cc_status = cc_prev_status;
1500: OUTPUT_JUMP (\"setg %0\", \"seta %0\", 0);
1501: ")
1502:
1503: (define_insn "sgtu"
1504: [(set (match_operand:QI 0 "general_operand" "=q")
1505: (gtu (cc0) (const_int 0)))]
1506: ""
1507: "* cc_status = cc_prev_status;
1508: return \"seta %0\"; ")
1509:
1510: (define_insn "slt"
1511: [(set (match_operand:QI 0 "general_operand" "=q")
1512: (lt (cc0) (const_int 0)))]
1513: ""
1514: "* cc_status = cc_prev_status;
1515: OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\"); ")
1516:
1517: (define_insn "sltu"
1518: [(set (match_operand:QI 0 "general_operand" "=q")
1519: (ltu (cc0) (const_int 0)))]
1520: ""
1521: "* cc_status = cc_prev_status;
1522: return \"setb %0\"; ")
1523:
1524: (define_insn "sge"
1525: [(set (match_operand:QI 0 "general_operand" "=q")
1526: (ge (cc0) (const_int 0)))]
1527: ""
1528: "* cc_status = cc_prev_status;
1529: OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\"); ")
1530:
1531: (define_insn "sgeu"
1532: [(set (match_operand:QI 0 "general_operand" "=q")
1533: (geu (cc0) (const_int 0)))]
1534: ""
1535: "* cc_status = cc_prev_status;
1536: return \"setae %0\"; ")
1537:
1538: (define_insn "sle"
1539: [(set (match_operand:QI 0 "general_operand" "=q")
1540: (le (cc0) (const_int 0)))]
1541: ""
1542: "*
1543: cc_status = cc_prev_status;
1544: OUTPUT_JUMP (\"setle %0\", \"setbe %0\", 0);
1545: ")
1546:
1547: (define_insn "sleu"
1548: [(set (match_operand:QI 0 "general_operand" "=q")
1549: (leu (cc0) (const_int 0)))]
1550: ""
1551: "* cc_status = cc_prev_status;
1552: return \"setbe %0\"; ")
1553:
1554: ;; Basic conditional jump instructions.
1555: ;; We ignore the overflow flag for signed branch instructions.
1556:
1557: (define_insn "beq"
1558: [(set (pc)
1559: (if_then_else (eq (cc0)
1560: (const_int 0))
1561: (label_ref (match_operand 0 "" ""))
1562: (pc)))]
1563: ""
1564: "je %l0")
1565:
1566: (define_insn "bne"
1567: [(set (pc)
1568: (if_then_else (ne (cc0)
1569: (const_int 0))
1570: (label_ref (match_operand 0 "" ""))
1571: (pc)))]
1572: ""
1573: "jne %l0")
1574:
1575: (define_insn "bgt"
1576: [(set (pc)
1577: (if_then_else (gt (cc0)
1578: (const_int 0))
1579: (label_ref (match_operand 0 "" ""))
1580: (pc)))]
1581: ""
1582: "*OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0)")
1583:
1584: (define_insn "bgtu"
1585: [(set (pc)
1586: (if_then_else (gtu (cc0)
1587: (const_int 0))
1588: (label_ref (match_operand 0 "" ""))
1589: (pc)))]
1590: ""
1591: "ja %l0")
1592:
1593: (define_insn "blt"
1594: [(set (pc)
1595: (if_then_else (lt (cc0)
1596: (const_int 0))
1597: (label_ref (match_operand 0 "" ""))
1598: (pc)))]
1599: ""
1600: "*OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\")")
1601:
1602: (define_insn "bltu"
1603: [(set (pc)
1604: (if_then_else (ltu (cc0)
1605: (const_int 0))
1606: (label_ref (match_operand 0 "" ""))
1607: (pc)))]
1608: ""
1609: "jb %l0")
1610:
1611: (define_insn "bge"
1612: [(set (pc)
1613: (if_then_else (ge (cc0)
1614: (const_int 0))
1615: (label_ref (match_operand 0 "" ""))
1616: (pc)))]
1617: ""
1618: "*OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\")")
1619:
1620: (define_insn "bgeu"
1621: [(set (pc)
1622: (if_then_else (geu (cc0)
1623: (const_int 0))
1624: (label_ref (match_operand 0 "" ""))
1625: (pc)))]
1626: ""
1627: "jae %l0")
1628:
1629: (define_insn "ble"
1630: [(set (pc)
1631: (if_then_else (le (cc0)
1632: (const_int 0))
1633: (label_ref (match_operand 0 "" ""))
1634: (pc)))]
1635: ""
1636: "*OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0) ")
1637:
1638: (define_insn "bleu"
1639: [(set (pc)
1640: (if_then_else (leu (cc0)
1641: (const_int 0))
1642: (label_ref (match_operand 0 "" ""))
1643: (pc)))]
1644: ""
1645: "jbe %l0")
1646:
1647: ;; Negated conditional jump instructions.
1648:
1649: (define_insn ""
1650: [(set (pc)
1651: (if_then_else (eq (cc0)
1652: (const_int 0))
1653: (pc)
1654: (label_ref (match_operand 0 "" ""))))]
1655: ""
1656: "jne %l0")
1657:
1658: (define_insn ""
1659: [(set (pc)
1660: (if_then_else (ne (cc0)
1661: (const_int 0))
1662: (pc)
1663: (label_ref (match_operand 0 "" ""))))]
1664: ""
1665: "je %l0")
1666:
1667: (define_insn ""
1668: [(set (pc)
1669: (if_then_else (gt (cc0)
1670: (const_int 0))
1671: (pc)
1672: (label_ref (match_operand 0 "" ""))))]
1673: ""
1674: "*OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0) ")
1675:
1676: (define_insn ""
1677: [(set (pc)
1678: (if_then_else (gtu (cc0)
1679: (const_int 0))
1680: (pc)
1681: (label_ref (match_operand 0 "" ""))))]
1682: ""
1683: "jbe %l0")
1684:
1685: (define_insn ""
1686: [(set (pc)
1687: (if_then_else (lt (cc0)
1688: (const_int 0))
1689: (pc)
1690: (label_ref (match_operand 0 "" ""))))]
1691: ""
1692: "*OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\")
1693: ")
1694:
1695: (define_insn ""
1696: [(set (pc)
1697: (if_then_else (ltu (cc0)
1698: (const_int 0))
1699: (pc)
1700: (label_ref (match_operand 0 "" ""))))]
1701: ""
1702: "jae %l0")
1703:
1704: (define_insn ""
1705: [(set (pc)
1706: (if_then_else (ge (cc0)
1707: (const_int 0))
1708: (pc)
1709: (label_ref (match_operand 0 "" ""))))]
1710: ""
1711: "*OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\")")
1712:
1713: (define_insn ""
1714: [(set (pc)
1715: (if_then_else (geu (cc0)
1716: (const_int 0))
1717: (pc)
1718: (label_ref (match_operand 0 "" ""))))]
1719: ""
1720: "jb %l0")
1721:
1722: (define_insn ""
1723: [(set (pc)
1724: (if_then_else (le (cc0)
1725: (const_int 0))
1726: (pc)
1727: (label_ref (match_operand 0 "" ""))))]
1728: ""
1729: "*OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0)")
1730:
1731: (define_insn ""
1732: [(set (pc)
1733: (if_then_else (leu (cc0)
1734: (const_int 0))
1735: (pc)
1736: (label_ref (match_operand 0 "" ""))))]
1737: ""
1738: "ja %l0")
1739:
1740: ;; Unconditional and other jump instructions
1741: (define_insn "jump"
1742: [(set (pc)
1743: (label_ref (match_operand 0 "" "")))]
1744: ""
1745: "jmp %l0")
1746:
1747: (define_insn "tablejump"
1748: [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
1749: (use (label_ref (match_operand 1 "" "")))]
1750: ""
1751: "*
1752: {
1753: CC_STATUS_INIT;
1754:
1755: return \"jmp %*%0\";
1756: }")
1757:
1758: /*
1759: (define_insn ""
1760: [(set (pc)
1761: (if_then_else
1762: (ne (compare (minus:HI (match_operand:HI 0 "general_operand" "c")
1763: (const_int 1))
1764: (const_int -1))
1765: (const_int 0))
1766: (label_ref (match_operand 1 "" "g"))
1767: (pc)))
1768: (set (match_dup 0)
1769: (minus:HI (match_dup 0)
1770: (const_int 1)))]
1771: ""
1772: "loop %l1")
1773:
1774: (define_insn ""
1775: [(set (pc)
1776: (if_then_else
1777: (ne (compare (const_int -1)
1778: (minus:SI (match_operand:SI 0 "general_operand" "c")
1779: (const_int 1)))
1780: (const_int 0))
1781: (label_ref (match_operand 1 "" "g"))
1782: (pc)))
1783: (set (match_dup 0)
1784: (minus:SI (match_dup 0)
1785: (const_int 1)))]
1786: ""
1787: "loop %l1")
1788: */
1789:
1790: ;; Call subroutine returning no value.
1791: (define_insn "call"
1792: [(call (match_operand:QI 0 "indirect_operand" "m")
1793: (match_operand:SI 1 "general_operand" "g"))]
1794: ;; Operand 1 not really used on the m68000.
1795: ""
1796: "*
1797: {
1798: if (GET_CODE (operands[0]) == MEM
1799: && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1800: {
1801: operands[0] = XEXP (operands[0], 0);
1802: return \"call %*%0\";
1803: }
1804: else
1805: return \"call %0\";
1806: }")
1807:
1808: ;; Call subroutine, returning value in operand 0
1809: ;; (which must be a hard register).
1810: (define_insn "call_value"
1811: [(set (match_operand 0 "" "=rf")
1812: (call (match_operand:QI 1 "indirect_operand" "m")
1813: (match_operand:SI 2 "general_operand" "g")))]
1814: ;; Operand 2 not really used on the m68000.
1815: ""
1816: "*
1817: {
1818: if (GET_CODE (operands[1]) == MEM
1819: && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1820: {
1821: operands[1] = XEXP (operands[1], 0);
1822: output_asm_insn (\"call %*%1\", operands);
1823: }
1824: else
1825: output_asm_insn (\"call %1\", operands);
1826:
1827: if (GET_MODE (operands[0]) == DFmode
1828: || GET_MODE (operands[0]) == SFmode)
1829: {
1830: /* fp_pop_level++; */
1831: /* pop if reg dead */
1832: if (!FP_REG_P (operands[0]))
1833: abort ();
1834: if (top_dead_p (insn))
1835: {
1836: POP_ONE_FP;
1837: }
1838: }
1839: RET;
1840: }")
1841:
1842: (define_insn "nop"
1843: [(const_int 0)]
1844: ""
1845: "nop")
1846:
1847: ;;- Local variables:
1848: ;;- mode:emacs-lisp
1849: ;;- comment-start: ";;- "
1850: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
1851: ;;- eval: (modify-syntax-entry ?[ "(]")
1852: ;;- eval: (modify-syntax-entry ?] ")[")
1853: ;;- eval: (modify-syntax-entry ?{ "(}")
1854: ;;- eval: (modify-syntax-entry ?} "){")
1855: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.