|
|
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);
1.1.1.2 ! root 393: if (top_dead_p (insn))
! 394: output_asm_insn (\"fstp%S0 %0\", xops);
! 395: else
! 396: output_asm_insn (\"fst%S0\", xops);
1.1 root 397: RET;
398: }
399: return \"push%L0 %1\";
400: }")
401:
402: (define_insn "movsf"
403: [(set (match_operand:SF 0 "general_operand" "=rf,rmf,!rm")
404: (match_operand:SF 1 "general_operand" "m,rf,F"))]
405: ""
406: "*
407: {
408: if (FP_REG_P (operands[1])
409: && !FP_REG_P (operands[0])
410: && !top_dead_p (insn))
411: fp_store_sf (operands[0]);
412: else
413: output_movsf (operands[0], operands[1]);
414: RETCOM (movsf);
415: }")
416:
417: ;;should change to handle the memory operands[1] without doing df push..
418: (define_insn ""
419: [(set (match_operand:DF 0 "push_operand" "=<,<")
420: (match_operand:DF 1 "general_operand" "gF,f"))]
421: ""
422: "*
423: {
424: if (FP_REG_P (operands[1]))
425: {
426: rtx xops[3];
427: xops[0] = AT_SP (DFmode);
428: xops[1] = gen_rtx (CONST_INT, VOIDmode, 8);
429: xops[2] = stack_pointer_rtx;
430: /* fp_pop_level--; */
431: output_asm_insn (AS2 (sub%L0,%1,%2), xops);
1.1.1.2 ! root 432: if (top_dead_p(insn))
! 433: output_asm_insn (\"fstp%Q0 %0\", xops);
! 434: else
! 435: output_asm_insn (\"fst%Q0 %0\", xops);
1.1 root 436: RETCOM (pushdf);
437: }
438: else
439: return output_move_double (operands);
440: }")
441:
442: (define_insn "movdf"
443: [(set (match_operand:DF 0 "general_operand" "=&rf,rmf,!rm")
444: (match_operand:DF 1 "general_operand" "m,fr,F"))]
445: ""
446: "*
447: {
448: if (FP_REG_P (operands[1])
449: && ! FP_REG_P (operands[0])
450: && ! top_dead_p (insn))
451: fp_store_df (operands[0]);
452: else
453: output_movdf (operands[0], operands[1]);
454: RETCOM (movdf);
455: }")
456:
457: (define_insn ""
458: [(set (match_operand:DI 0 "push_operand" "=<")
459: (match_operand:DI 1 "general_operand" "roiF"))]
460: ""
461: "*
462: {
463: return output_move_double (operands);
464: }")
465:
466: (define_insn "movdi"
467: [(set (match_operand:DI 0 "general_operand" "=&r,rm")
468: (match_operand:DI 1 "general_operand" "m,riF"))]
469: ""
470: "*
471: {
472: return output_move_double (operands);
473: }")
474:
475: ;; These go after the move instructions
476: ;; because the move instructions are better (require no spilling)
477: ;; when they can apply. But these go before the add and subtract insns
478: ;; because it is often shorter to use these when both apply.
479:
480: ;Lennart Augustsson <[email protected]>
481: ;says this pattern just makes slower code:
482: ; pushl %ebp
483: ; addl $-80,(%esp)
484: ;instead of
485: ; leal -80(%ebp),%eax
486: ; pushl %eax
487: ;
488: ;(define_insn ""
489: ; [(set (match_operand:SI 0 "push_operand" "=<")
490: ; (plus:SI (match_operand:SI 1 "general_operand" "%r")
491: ; (match_operand:SI 2 "general_operand" "ri")))]
492: ; ""
493: ; "*
494: ;{
495: ; rtx xops[4];
496: ; xops[0] = operands[0];
497: ; xops[1] = operands[1];
498: ; xops[2] = operands[2];
499: ; xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
500: ; output_asm_insn (\"push%z1 %1\", xops);
501: ; output_asm_insn (AS2 (add%z3,%2,%3), xops);
502: ; RET;
503: ;}")
504:
505: (define_insn ""
506: [(set (match_operand:SI 0 "general_operand" "=g")
507: (plus:SI (match_operand:SI 1 "general_operand" "0")
508: (const_int 1)))]
509: ""
510: "inc%L0 %0")
511:
512: (define_insn ""
513: [(set (match_operand:SI 0 "general_operand" "=g")
514: (plus:SI (match_operand:SI 1 "general_operand" "0")
515: (const_int -1)))]
516: ""
517: "dec%L0 %0")
518:
519: (define_insn ""
520: [(set (match_operand:SI 0 "general_operand" "=g")
521: (minus:SI (match_operand:SI 1 "general_operand" "0")
522: (const_int 1)))]
523: ""
524: "dec%L0 %0")
525:
526: (define_insn ""
527: [(set (match_operand:SI 0 "register_operand" "=r")
528: (match_operand:QI 1 "address_operand" "p"))]
529: ""
530: "*
531: {
532: CC_STATUS_INIT;
533: /* Adding a constant to a register is faster with an add. */
534: if (GET_CODE (operands[1]) == PLUS
535: && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
536: && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
537: {
538: operands[1] = XEXP (operands[1], 1);
539: return AS2 (add%L0,%1,%0);
540: }
541: return \"lea%L0 %a1,%0\";
542: }")
543:
544: ;;- conversion instructions
545: ;;- NONE
546:
547: ;;- truncation instructions
548: (define_insn "truncsiqi2"
549: [(set (match_operand:QI 0 "general_operand" "=qm,q")
550: (truncate:QI
551: (match_operand:SI 1 "general_operand" "qi,m")))]
552: ""
1.1.1.2 ! root 553: "mov%B0 %b1,%0")
1.1 root 554:
555: (define_insn "trunchiqi2"
556: [(set (match_operand:QI 0 "general_operand" "=qm,q")
557: (truncate:QI
558: (match_operand:HI 1 "general_operand" "qi,m")))]
559: ""
1.1.1.2 ! root 560: "mov%B0 %b1,%0")
1.1 root 561:
562: (define_insn "truncsihi2"
563: [(set (match_operand:HI 0 "general_operand" "=rm,r")
564: (truncate:HI
565: (match_operand:SI 1 "general_operand" "ri,m")))]
566: ""
1.1.1.2 ! root 567: "mov%W0 %w1,%0")
1.1 root 568:
569: ;;- zero extension instructions
570: ;; Note that the one starting from HImode comes before those for QImode
571: ;; so that a constant operand will match HImode, not QImode.
572:
573: (define_insn "zero_extendhisi2"
574: [(set (match_operand:SI 0 "general_operand" "=r")
575: (zero_extend:SI
576: (match_operand:HI 1 "general_operand" "rm")))]
577: ""
578: "movz%W0%L0 %1,%0")
579:
580: (define_insn "zero_extendqihi2"
581: [(set (match_operand:HI 0 "general_operand" "=r")
582: (zero_extend:HI
583: (match_operand:QI 1 "general_operand" "qm")))]
584: ""
585: "movz%B0%W0 %1,%0")
586:
587: (define_insn "zero_extendqisi2"
588: [(set (match_operand:SI 0 "general_operand" "=r")
589: (zero_extend:SI
590: (match_operand:QI 1 "general_operand" "qm")))]
591: ""
592: "movz%B0%L0 %1,%0")
593:
594: ;;- sign extension instructions
595: ;; Note that the one starting from HImode comes before those for QImode
596: ;; so that a constant operand will match HImode, not QImode.
597:
598: /*
599: (define_insn "extendsidi2"
600: [(set (match_operand:DI 0 "general_operand" "=a")
601: (sign_extend:DI
602: (match_operand:SI 1 "general_operand" "a")))]
603: ""
604: "clq")
605: */
606:
607: (define_insn "extendhisi2"
608: [(set (match_operand:SI 0 "general_operand" "=r")
609: (sign_extend:SI
610: (match_operand:HI 1 "general_operand" "rm")))]
611: ""
612: "movs%W0%L0 %1,%0")
613:
614: (define_insn "extendqihi2"
615: [(set (match_operand:HI 0 "general_operand" "=r")
616: (sign_extend:HI
617: (match_operand:QI 1 "general_operand" "qm")))]
618: ""
619: "movs%B0%W0 %1,%0")
620:
621: (define_insn "extendqisi2"
622: [(set (match_operand:SI 0 "general_operand" "=r")
623: (sign_extend:SI
624: (match_operand:QI 1 "general_operand" "qm")))]
625: ""
626: "movs%B0%L0 %1,%0"
627: )
628:
629: ;; Conversions between float and double.
630:
631: (define_insn "extendsfdf2"
632: [(set (match_operand:DF 0 "general_operand" "=fm,f,fm,fm")
633: (float_extend:DF
634: (match_operand:SF 1 "general_operand" "m,0,f,!*r")))]
635: "TARGET_80387"
636: "*
637: {
638: if (FP_REG_P (operands[0]))
639: {
640: output_movsf (operands[0], operands[1]);
641: RET;
642: }
643: if (FP_REG_P (operands[1]))
644: {
645: if (top_dead_p (insn))
646: fp_pop_df (operands[0]);
647: else
648: fp_store_df (operands[0]);
649: RET;
650: }
651: output_movsf (FP_TOP, operands[1]);
652: fp_pop_df (operands[0]);
653: RETCOM (extendsfdf2);
654: }")
655:
656: ;; This cannot output into an f-reg because there is no way to be
657: ;; sure of truncating in that case.
658: (define_insn "truncdfsf2"
659: [(set (match_operand:SF 0 "general_operand" "=m,!*r")
660: (float_truncate:SF
661: (match_operand:DF 1 "general_operand" "f,f")))]
662: "TARGET_80387"
663: "*
664: {
665: if (top_dead_p (insn))
666: fp_pop_sf (operands[0]);
667: else
668: fp_store_sf (operands[0]);
669: RETCOM (truncdfsf2);
670: }")
671:
672: ;; Conversion between fixed point and floating point.
673: ;; Note that among the fix-to-float insns
674: ;; the ones that start with SImode come first.
675: ;; That is so that an operand that is a CONST_INT
676: ;; (and therefore lacks a specific machine mode).
677: ;; will be recognized as SImode (which is always valid)
678: ;; rather than as QImode or HImode. The 80387 would not know
679: ;; what to do with the smaller sizes anyway. (I think).
680:
681: (define_insn "floatsisf2"
682: [(set (match_operand:SF 0 "general_operand" "=fm,fm")
683: (float:SF (match_operand:SI 1 "general_operand" "m,!*r")))]
684: "TARGET_80387"
685: "*
686: {
687: /* fp_pop_level++; */
688:
689: if (GET_CODE (operands[1]) != MEM)
690: {
691: rtx xops[2];
692: output_asm_insn (\"push%L0 %1\", operands);
693: operands[1] = AT_SP (SImode);
694: output_asm_insn (\"fild%L0 %1\", operands);
695: xops[0] = stack_pointer_rtx;
696: xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
697: output_asm_insn (AS2 (add%L0,%1,%0), xops);
698: }
699: else
700: output_asm_insn (\"fild%L0 %1\", operands);
701:
702: if (! FP_REG_P (operands[0]))
703: {
704: /* fp_pop_level--; */
705: return \"fstp%S0 %0\";
706: }
707: RET;
708: }")
709:
710: (define_insn "floatsidf2"
711: [(set (match_operand:DF 0 "general_operand" "=fm,fm")
712: (float:DF (match_operand:SI 1 "general_operand" "m,!*r")))]
713: "TARGET_80387"
714: "*
715: {
716: /* fp_pop_level++; */
717: if (GET_CODE (operands[1]) != MEM)
718: {
719: rtx xops[2];
720: output_asm_insn (\"push%L0 %1\", operands);
721: operands[1] = AT_SP (SImode);
722: output_asm_insn (\"fild%L0 %1\", operands);
723: xops[0] = stack_pointer_rtx;
724: xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
725: output_asm_insn (AS2 (add%L0,%1,%0), xops);
726: }
727: else
728: output_asm_insn (\"fild%L0 %1\", operands);
729: if (! FP_REG_P (operands[0]))
730: {
731: /* fp_pop_level--; */
732: return \"fstp%Q0 %0\";
733: }
734: RET;
735: }")
736:
737: ;; Convert a float to a float whose value is an integer.
738: ;; This is the first stage of converting it to an integer type.
739:
740: ;; On the 387 truncating doub to an short integer shor can be performed:
741:
742: ; fstcw -4(%esp) ;save cw
743: ; movw -4(%esp),%ax
744: ; orw $0x0c00,%ax ;set rounding to chop towards zero
745: ; movw %ax,-2(%esp) ;
746: ; fldcw -2(%esp) ;
747: ; fldl doubl
748: ; fistpl -12(%esp) ;store the round value
749: ; fldcw -4(%esp) ;restore cw
750: ; movl -12(%esp),%eax
751: ; movw %ax,shor ; move the result into shor.
752:
753: ;; but it is probably better to have a call, rather than waste this
754: ;; space. The last instruction would have been a movl if were
755: ;; going to an int instead of a short.
756: ;; For the moment we will go with the soft float for these.
757:
758: /* These are incorrect since they don't set the rounding bits of CW flag.
759: The proper way to do that is to make the function prologue save the CW
760: and also construct the alternate CW value needed for these insns.
761: Then these insns can output two fldcw's, referring to fixed places in
762: the stack frame.
763:
764: ;; Convert a float whose value is an integer
765: ;; to an actual integer. Second stage of converting float to integer type.
766:
767: (define_insn "fix_truncsfqi2"
768: [(set (match_operand:QI 0 "general_operand" "=m,?*q")
769: (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
770: "TARGET_80387"
771: "*
772: {
773: fp_pop_int (operands[0]);
774: RET;
775: }")
776:
777: (define_insn "fix_truncsfhi2"
778: [(set (match_operand:HI 0 "general_operand" "=m,?*r")
779: (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
780: "TARGET_80387"
781: "*
782: {
783: fp_pop_int (operands[0]);
784: RET;
785: }")
786:
787: (define_insn "fix_truncsfsi2"
788: [(set (match_operand:SI 0 "general_operand" "=m,?*r")
789: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
790: "TARGET_80387"
791: "*
792: {
793: fp_pop_int (operands[0]);
794: RET;
795: }")
796:
797: (define_insn "fix_truncdfqi2"
798: [(set (match_operand:QI 0 "general_operand" "=m,?*q")
799: (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
800:
801: "TARGET_80387"
802: "*
803: {
804: fp_pop_int (operands[0]);
805: RET;
806: }")
807:
808:
809: (define_insn "fix_truncdfhi2"
810: [(set (match_operand:HI 0 "general_operand" "=m,?*r")
811: (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
812: "TARGET_80387"
813: "*
814: {
815: fp_pop_int (operands[0]);
816: RET;
817: }")
818:
819:
820: (define_insn "fix_truncdfsi2"
821: [(set (match_operand:SI 0 "general_operand" "=m,?*r")
822: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
823: "TARGET_80387"
824: "*
825: {
826: fp_pop_int (operands[0]);
827: RET;
828: }")
829: */
830:
831:
832: ;;- add instructions
833: ;;moved incl to above leal
834:
835: (define_insn "addsi3"
836: [(set (match_operand:SI 0 "general_operand" "=rm,r")
837: (plus:SI (match_operand:SI 1 "general_operand" "%0,0")
838: (match_operand:SI 2 "general_operand" "ri,rm")))]
839: ""
840: "add%L0 %2,%0")
841:
842: (define_insn ""
843: [(set (match_operand:HI 0 "general_operand" "=g")
844: (plus:HI (match_operand:HI 1 "general_operand" "0")
845: (const_int 1)))]
846: ""
847: "inc%W0 %0")
848:
849: (define_insn "addhi3"
850: [(set (match_operand:HI 0 "general_operand" "=rm,r")
851: (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
852: (match_operand:HI 2 "general_operand" "ri,rm")))]
853: ""
854: "add%W0 %2,%0")
855:
856: (define_insn ""
857: [(set (match_operand:QI 0 "general_operand" "=qm")
858: (plus:QI (match_operand:QI 1 "general_operand" "0")
859: (const_int 1)))]
860: ""
861: "inc%B0 %0")
862:
863: (define_insn "addqi3"
864: [(set (match_operand:QI 0 "general_operand" "=m,q")
865: (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
866: (match_operand:QI 2 "general_operand" "qn,qmn")))]
867: ""
868: "add%B0 %2,%0")
869:
870: ;;had "fmF,m"
871:
872: (define_insn "adddf3"
873: [(set (match_operand:DF 0 "general_operand" "=f,m,f")
874: (plus:DF (match_operand:DF 1 "general_operand" "%0,0,0")
875: (match_operand:DF 2 "general_operand" "m,!f,!*r")))]
876: "TARGET_80387"
877: "*FP_CALL (\"fadd%z0 %0\", \"fadd%z0 %0\", 2)")
878:
879: (define_insn "addsf3"
880: [(set (match_operand:SF 0 "general_operand" "=f,m,f")
881: (plus:SF (match_operand:SF 1 "general_operand" "%0,0,0")
882: (match_operand:SF 2 "general_operand" "m,!f,!*r")))]
883: "TARGET_80387"
884: "*FP_CALL (\"fadd%z0 %0\", \"fadd%z0 %0\", 2)")
885:
886: ;;- subtract instructions
887:
888: ;;moved decl above leal
889:
890: (define_insn "subsi3"
891: [(set (match_operand:SI 0 "general_operand" "=rm,r")
892: (minus:SI (match_operand:SI 1 "general_operand" "0,0")
893: (match_operand:SI 2 "general_operand" "ri,rm")))]
894: ""
895: "sub%L0 %2,%0")
896:
897: (define_insn ""
898: [(set (match_operand:HI 0 "general_operand" "=g")
899: (minus:HI (match_operand:HI 1 "general_operand" "0")
900: (const_int 1)))]
901: ""
902: "dec%W0 %0")
903:
904: (define_insn "subhi3"
905: [(set (match_operand:HI 0 "general_operand" "=rm,r")
906: (minus:HI (match_operand:HI 1 "general_operand" "0,0")
907: (match_operand:HI 2 "general_operand" "ri,rm")))]
908: ""
909: "sub%W0 %2,%0")
910:
911: (define_insn ""
912: [(set (match_operand:QI 0 "general_operand" "=qm")
913: (minus:QI (match_operand:QI 1 "general_operand" "0")
914: (const_int 1)))]
915: ""
916: "dec%B0 %0")
917:
918: (define_insn "subqi3"
919: [(set (match_operand:QI 0 "general_operand" "=m,q")
920: (minus:QI (match_operand:QI 1 "general_operand" "0,0")
921: (match_operand:QI 2 "general_operand" "qn,qmn")))]
922: ""
923: "sub%B0 %2,%0")
924:
925: (define_insn "subdf3"
926: [(set (match_operand:DF 0 "general_operand" "=f,m,f,f")
927: (minus:DF (match_operand:DF 1 "general_operand" "0,0,0,m")
928: (match_operand:DF 2 "general_operand" "m,!f,!*r,*0")))]
929: "TARGET_80387"
930: "*FP_CALL (\"fsub%z0 %0\", \"fsubr%z0 %0\", 2)")
931:
932:
933: (define_insn "subsf3"
934: [(set (match_operand:SF 0 "general_operand" "=f,m,f,f")
935: (minus:SF (match_operand:SF 1 "general_operand" "0,0,0,m")
936: (match_operand:SF 2 "general_operand" "m,!f,!*r,*0")))]
937: "TARGET_80387"
938: "*FP_CALL (\"fsub%z0 %0\", \"fsubr%z0 %0\", 2)")
939:
940: ;;- multiply instructions
941:
942: ;(define_insn "mulqi3"
943: ; [(set (match_operand:QI 0 "general_operand" "=a")
944: ; (mult:QI (match_operand:QI 1 "general_operand" "%0")
945: ; (match_operand:QI 2 "general_operand" "qm")))]
946: ; ""
947: ; "mul%B0 %2,%0")
948:
949: (define_insn "mulhi3"
950: [(set (match_operand:HI 0 "general_operand" "=r,r")
951: (mult:SI (match_operand:HI 1 "general_operand" "%0,rm")
952: (match_operand:HI 2 "general_operand" "g,i")))]
953: ""
954: "*
955: {
956: if (GET_CODE (operands[1]) == REG
957: && REGNO (operands[1]) == REGNO (operands[0])
958: && (GET_CODE (operands[2]) == MEM
959: || GET_CODE (operands[2]) == REG))
960: /* Assembler has weird restrictions. */
961: return AS2 (imul%W0,%2,%0);
962: return AS3 (imul%W0,%2,%1,%0);
963: }")
964:
965: (define_insn "mulsi3"
966: [(set (match_operand:SI 0 "general_operand" "=r,r")
967: (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
968: (match_operand:SI 2 "general_operand" "g,i")))]
969: ""
970: "*
971: {
972: if (GET_CODE (operands[1]) == REG
973: && REGNO (operands[1]) == REGNO (operands[0])
974: && (GET_CODE (operands[2]) == MEM
975: || GET_CODE (operands[2]) == REG))
976: /* Assembler has weird restrictions. */
977: return AS2 (imul%L0,%2,%0);
978: return AS3 (imul%L0,%2,%1,%0);
979: }")
980:
981: ;; Turned off due to possible assembler bug.
982: ;(define_insn "umulqi3"
983: ; [(set (match_operand:QI 0 "general_operand" "=a")
984: ; (umult:QI (match_operand:QI 1 "general_operand" "%0")
985: ; (match_operand:QI 2 "general_operand" "qm")))]
986: ; ""
987: ; "mul%B0 %2,%0")
988:
989: ;(define_insn "umulqihi3"
990: ; [(set (match_operand:HI 0 "general_operand" "=a")
991: ; (umult:HI (match_operand:QI 1 "general_operand" "%0")
992: ; (match_operand:QI 2 "general_operand" "qm")))]
993: ; ""
994: ; "mul%B0 %2,%0")
995:
996: (define_insn "umulhi3"
997: [(set (match_operand:HI 0 "general_operand" "=a")
998: (umult:SI (match_operand:HI 1 "general_operand" "%0")
999: (match_operand:HI 2 "general_operand" "rm")))
1000: (clobber (reg:HI 1))]
1001: ""
1002: "mul%W0 %2,%0")
1003:
1004: (define_insn "umulsi3"
1005: [(set (match_operand:SI 0 "general_operand" "=a")
1006: (umult:SI (match_operand:SI 1 "general_operand" "%0")
1007: (match_operand:SI 2 "general_operand" "rm")))
1008: (clobber (reg:SI 1))]
1009: ""
1010: "mul%L0 %2,%0")
1011:
1012: (define_insn "muldf3"
1013: [(set (match_operand:DF 0 "general_operand" "=f,m,f")
1014: (mult:DF (match_operand:DF 1 "general_operand" "%0,0,0")
1015: (match_operand:DF 2 "general_operand" "m,!f,!*r")))]
1016: "TARGET_80387"
1017: "*FP_CALL (\"fmul%z0 %0\", \"fmul%z0 %0\", 2)
1018: ")
1019:
1020: (define_insn "mulsf3"
1021: [(set (match_operand:SF 0 "general_operand" "=f,m,f")
1022: (mult:SF (match_operand:SF 1 "general_operand" "%0,0,0")
1023: (match_operand:SF 2 "general_operand" "m,!f,!*r")))]
1024: "TARGET_80387"
1025: "*FP_CALL (\"fmul%z0 %0\", \"fmul%z0 %0\", 2)
1026: ")
1027:
1028: ;;- divide instructions
1029: (define_insn "divdf3"
1030: [(set (match_operand:DF 0 "general_operand" "=f,m,f,f")
1031: (div:DF (match_operand:DF 1 "general_operand" "0,0,0,m")
1032: (match_operand:DF 2 "general_operand" "m,!f,!*r,*0")))]
1033: "TARGET_80387"
1034: "*FP_CALL (\"fdiv%z0 %0\", \"fdivr%z0 %0\", 2)
1035: ")
1036:
1037: (define_insn "divsf3"
1038: [(set (match_operand:SF 0 "general_operand" "=f,m,f,f")
1039: (div:SF (match_operand:SF 1 "general_operand" "0,0,0,m")
1040: (match_operand:SF 2 "general_operand" "m,!f,!*r,*0")))]
1041: "TARGET_80387"
1042: "*FP_CALL (\"fdiv%z0 %0\", \"fdivr%z0 %0\", 2)
1043: ")
1044:
1045: ;; Remainder instructions.
1046:
1047: (define_insn "divmodsi4"
1048: [(set (match_operand:SI 0 "general_operand" "=a")
1049: (div:SI (match_operand:SI 1 "general_operand" "0")
1050: (match_operand:SI 2 "general_operand" "rm")))
1051: (set (match_operand:SI 3 "general_operand" "=&d")
1052: (mod:SI (match_dup 1) (match_dup 2)))]
1053: ""
1054: "cltd\;idiv%L0 %2")
1055:
1056: (define_insn "udivmodsi4"
1057: [(set (match_operand:SI 0 "general_operand" "=a")
1058: (udiv:SI (match_operand:SI 1 "general_operand" "0")
1059: (match_operand:SI 2 "general_operand" "rm")))
1060: (set (match_operand:SI 3 "general_operand" "=&d")
1061: (umod:SI (match_dup 1) (match_dup 2)))]
1062: ""
1063: "xor%L0 %3,%3\;div%L0 %2")
1064:
1065: /*
1066: ;;this should be a valid double division which we may want to add
1067:
1068: (define_insn ""
1069: [(set (match_operand:SI 0 "general_operand" "=a")
1070: (udiv:DI (match_operand:DI 1 "general_operand" "a")
1071: (match_operand:SI 2 "general_operand" "rm")))
1072: (set (match_operand:SI 3 "general_operand" "=d")
1073: (umod:SI (match_dup 1) (match_dup 2)))]
1074: ""
1075: "div%L0 %2,%0")
1076: */
1077:
1078: ;;- and instructions
1079:
1080: ;; The `r' in `rm' for operand 3 looks redundant, but it causes
1081: ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
1082:
1083: (define_insn "andsi3"
1084: [(set (match_operand:SI 0 "general_operand" "=rm,r")
1085: (and:SI (match_operand:SI 1 "general_operand" "%0,0")
1086: (match_operand:SI 2 "general_operand" "ri,rm")))]
1087: ""
1088: "and%L0 %2,%0")
1089:
1090: (define_insn "andhi3"
1091: [(set (match_operand:HI 0 "general_operand" "=rm,r")
1092: (and:HI (match_operand:HI 1 "general_operand" "%0,0")
1093: (match_operand:HI 2 "general_operand" "ri,rm")))]
1094: ""
1095: "and%W0 %2,%0")
1096:
1097: (define_insn "andqi3"
1098: [(set (match_operand:QI 0 "general_operand" "=m,q")
1099: (and:QI (match_operand:QI 1 "general_operand" "%0,0")
1100: (match_operand:QI 2 "general_operand" "qn,qmn")))]
1101: ""
1102: "and%B0 %2,%0")
1103:
1104: /* I am nervous about these two.. add them later..
1105: ;I presume this means that we have something in say op0= eax which is small
1106: ;and we want to and it with memory so we can do this by just an
1107: ;andb m,%al and have success.
1108: (define_insn ""
1109: [(set (match_operand:SI 0 "general_operand" "=r")
1110: (and:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rm"))
1111: (match_operand:SI 2 "general_operand" "0")))]
1112: "GET_CODE (operands[2]) == CONST_INT
1113: && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
1114: "and%W0 %1,%0")
1115:
1116: (define_insn ""
1117: [(set (match_operand:SI 0 "general_operand" "=q")
1118: (and:SI (zero_extend:SI (match_operand:QI 1 "general_operand" "qm"))
1119: (match_operand:SI 2 "general_operand" "0")))]
1120: "GET_CODE (operands[2]) == CONST_INT
1121: && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
1122: "and%L0 %1,%0")
1123:
1124: */
1125:
1126:
1127:
1128: ;;- Bit set (inclusive or) instructions
1129:
1130: (define_insn "iorsi3"
1131: [(set (match_operand:SI 0 "general_operand" "=rm,r")
1132: (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
1133: (match_operand:SI 2 "general_operand" "ri,rm")))]
1134: ""
1135: "or%L0 %2,%0")
1136:
1137: (define_insn "iorhi3"
1138: [(set (match_operand:HI 0 "general_operand" "=rm,r")
1139: (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
1140: (match_operand:HI 2 "general_operand" "ri,rm")))]
1141: ""
1142: "or%W0 %2,%0")
1143:
1144: (define_insn "iorqi3"
1145: [(set (match_operand:QI 0 "general_operand" "=m,q")
1146: (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
1147: (match_operand:QI 2 "general_operand" "qn,qmn")))]
1148: ""
1149: "or%B0 %2,%0")
1150:
1151: ;;- xor instructions
1152:
1153: (define_insn "xorsi3"
1154: [(set (match_operand:SI 0 "general_operand" "=rm,r")
1155: (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
1156: (match_operand:SI 2 "general_operand" "ri,rm")))]
1157: ""
1158: "xor%L0 %2,%0")
1159:
1160: (define_insn "xorhi3"
1161: [(set (match_operand:HI 0 "general_operand" "=rm,r")
1162: (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
1163: (match_operand:HI 2 "general_operand" "ri,rm")))]
1164: ""
1165: "xor%W0 %2,%0")
1166:
1167: (define_insn "xorqi3"
1168: [(set (match_operand:QI 0 "general_operand" "=qm")
1169: (xor:QI (match_operand:QI 1 "general_operand" "%0")
1170: (match_operand:QI 2 "general_operand" "qn")))]
1171: ""
1172: "xor%B0 %2,%0")
1173:
1174: ;;- negation instructions
1175: (define_insn "negsi2"
1176: [(set (match_operand:SI 0 "general_operand" "=rm")
1177: (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1178: ""
1179: "neg%L0 %0")
1180:
1181: (define_insn "neghi2"
1182: [(set (match_operand:HI 0 "general_operand" "=rm")
1183: (neg:HI (match_operand:HI 1 "general_operand" "0")))]
1184: ""
1185: "neg%W0 %0")
1186:
1187: (define_insn "negqi2"
1188: [(set (match_operand:QI 0 "general_operand" "=qm")
1189: (neg:QI (match_operand:QI 1 "general_operand" "0")))]
1190: ""
1191: "neg%B0 %0")
1192:
1193: (define_insn "negsf2"
1194: [(set (match_operand:SF 0 "general_operand" "=f,!m")
1195: (neg:SF (match_operand:SF 1 "general_operand" "0,0")))]
1196: "TARGET_80387"
1197: "*FP_CALL1 (\"fchs\")")
1198:
1199: (define_insn "negdf2"
1200: [(set (match_operand:DF 0 "general_operand" "=f,!m")
1201: (neg:DF (match_operand:DF 1 "general_operand" "0,0")))]
1202: "TARGET_80387"
1203: "*FP_CALL1 (\"fchs\")")
1204:
1205: ;; Absolute value instructions
1206:
1207: (define_insn "abssf2"
1208: [(set (match_operand:SF 0 "general_operand" "=f,!m")
1209: (abs:SF (match_operand:SF 1 "general_operand" "0,0")))]
1210: "TARGET_80387"
1211: "*FP_CALL1 (\"fabs\")")
1212:
1213: (define_insn "absdf2"
1214: [(set (match_operand:DF 0 "general_operand" "=f,!m")
1215: (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1216: "TARGET_80387"
1217: "*FP_CALL1 (\"fabs\")")
1218:
1219: ;;- one complement instructions
1220: (define_insn "one_cmplsi2"
1221: [(set (match_operand:SI 0 "general_operand" "=rm")
1222: (not:SI (match_operand:SI 1 "general_operand" "0")))]
1223: ""
1224: "not%L0 %0")
1225:
1226: (define_insn "one_cmplhi2"
1227: [(set (match_operand:HI 0 "general_operand" "=rm")
1228: (not:HI (match_operand:HI 1 "general_operand" "0")))]
1229: ""
1230: "not%W0 %0")
1231:
1232: (define_insn "one_cmplqi2"
1233: [(set (match_operand:QI 0 "general_operand" "=qm")
1234: (not:QI (match_operand:QI 1 "general_operand" "0")))]
1235: ""
1236: "not%B0 %0")
1237:
1238: ;;- arithmetic shift instructions
1239:
1240: (define_insn "ashlsi3"
1241: [(set (match_operand:SI 0 "general_operand" "=rm")
1242: (ashift:SI (match_operand:SI 1 "general_operand" "0")
1243: (match_operand:SI 2 "general_operand" "cI")))]
1244: ""
1245: "*
1246: {
1247: if (REG_P (operands[2]))
1248: return AS2 (sal%L0,%R0cl,%0);
1249: else if (REG_P (operands[1]) && GET_CODE (operands[2]) == CONST_INT
1250: && INTVAL (operands[2]) == 1)
1251: return AS2 (add%L0,%1,%1);
1252: return AS2 (sal%L0,%2,%1);
1253: }")
1254:
1255: (define_insn "ashlhi3"
1256: [(set (match_operand:HI 0 "general_operand" "=rm")
1257: (ashift:HI (match_operand:HI 1 "general_operand" "0")
1258: (match_operand:HI 2 "general_operand" "cI")))]
1259: ""
1260: "*
1261: {
1262: if (REG_P (operands[2]))
1263: return AS2 (sal%W0,%R0cl,%0);
1264: else
1265: return AS2 (sal%W0,%2,%1);
1266: }")
1267:
1268: (define_insn "ashlqi3"
1269: [(set (match_operand:QI 0 "general_operand" "=qm")
1270: (ashift:QI (match_operand:QI 1 "general_operand" "0")
1271: (match_operand:QI 2 "general_operand" "cI")))]
1272: ""
1273: "*
1274: {
1275: if (REG_P (operands[2]))
1276: return AS2 (sal%B0,%R0cl,%0);
1277: else
1278: return AS2 (sal%B0,%2,%1);
1279: }")
1280:
1281: (define_insn "ashrsi3"
1282: [(set (match_operand:SI 0 "general_operand" "=rm")
1283: (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1284: (match_operand:SI 2 "general_operand" "cI")))]
1285: ""
1286: "*
1287: {
1288: if (REG_P (operands[2]))
1289: return AS2 (sar%L0,%R0cl,%0);
1290: else
1291: return AS2 (sar%L0,%2,%0);
1292: }")
1293:
1294: (define_insn "ashrhi3"
1295: [(set (match_operand:HI 0 "general_operand" "=rm")
1296: (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1297: (match_operand:HI 2 "general_operand" "cI")))]
1298: ""
1299: "*
1300: {
1301: if (REG_P (operands[2]))
1302: return AS2 (sar%W0,%R0cl,%0);
1303: else
1304: return AS2 (sar%W0,%2,%0);
1305: }")
1306:
1307: (define_insn "ashrqi3"
1308: [(set (match_operand:QI 0 "general_operand" "=qm")
1309: (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
1310: (match_operand:QI 2 "general_operand" "cI")))]
1311: ""
1312: "*
1313: {
1314: if (REG_P (operands[2]))
1315: return AS2 (sar%B0,%R0cl,%0);
1316: return
1317: AS2 (sar%B0,%2,%1);
1318: }")
1319:
1320: ;;- logical shift instructions
1321:
1322: (define_insn "lshlsi3"
1323: [(set (match_operand:SI 0 "general_operand" "=rm")
1324: (lshift:SI (match_operand:SI 1 "general_operand" "0")
1325: (match_operand:SI 2 "general_operand" "cI")))]
1326: ""
1327: "*
1328: {
1329: if (REG_P (operands[2]))
1330: return AS2 (shl%L0,%R0cl,%0);
1331: else
1332: return AS2 (shl%L0,%2,%1);
1333: }")
1334:
1335: (define_insn "lshlhi3"
1336: [(set (match_operand:HI 0 "general_operand" "=rm")
1337: (lshift:HI (match_operand:HI 1 "general_operand" "0")
1338: (match_operand:HI 2 "general_operand" "cI")))]
1339: ""
1340: "*
1341: {
1342: if (REG_P (operands[2]))
1343: return AS2 (shl%W0,%R0cl,%0);
1344: else
1345: return AS2 (shl%W0,%2,%1);
1346: }")
1347:
1348: (define_insn "lshlqi3"
1349: [(set (match_operand:QI 0 "general_operand" "=qm")
1350: (lshift:QI (match_operand:QI 1 "general_operand" "0")
1351: (match_operand:QI 2 "general_operand" "cI")))]
1352: ""
1353: "*
1354: {
1355: if (REG_P (operands[2]))
1356: return AS2 (shl%B0,%R0cl,%0);
1357: else
1358: return AS2 (shl%B0,%2,%1);
1359: }")
1360:
1361: (define_insn "lshrsi3"
1362: [(set (match_operand:SI 0 "general_operand" "=rm")
1363: (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1364: (match_operand:SI 2 "general_operand" "cI")))]
1365: ""
1366: "*
1367: {
1368: if (REG_P (operands[2]))
1369: return AS2 (shr%L0,%R0cl,%0);
1370: else
1371: return AS2 (shr%L0,%2,%1);
1372: }")
1373:
1374: (define_insn "lshrhi3"
1375: [(set (match_operand:HI 0 "general_operand" "=rm")
1376: (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1377: (match_operand:HI 2 "general_operand" "cI")))]
1378: ""
1379: "*
1380: {
1381: if (REG_P (operands[2]))
1382: return AS2 (shr%W0,%%cl,%0);
1383: else
1384: return AS2 (shr%W0,%2,%1);
1385: }")
1386:
1387: (define_insn "lshrqi3"
1388: [(set (match_operand:QI 0 "general_operand" "=qm")
1389: (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1390: (match_operand:QI 2 "general_operand" "cI")))]
1391: ""
1392: "*
1393: {
1394: if (REG_P (operands[2]))
1395: return AS2 (shr%B0,%%cl,%0);
1396: else
1397: return AS2 (shr%B0,%2,%1);
1398: }")
1399:
1400: ;;- rotate instructions
1401:
1402: (define_insn "rotlsi3"
1403: [(set (match_operand:SI 0 "general_operand" "=rm")
1404: (rotate:SI (match_operand:SI 1 "general_operand" "0")
1405: (match_operand:SI 2 "general_operand" "cI")))]
1406: ""
1407: "*
1408: {
1409: if (REG_P (operands[2]))
1410: return AS2 (rol%L0,%%cl,%0);
1411: else
1412: return AS2 (rol%L0,%2,%1);
1413: }")
1414:
1415: (define_insn "rotlhi3"
1416: [(set (match_operand:HI 0 "general_operand" "=rm")
1417: (rotate:HI (match_operand:HI 1 "general_operand" "0")
1418: (match_operand:HI 2 "general_operand" "cI")))]
1419: ""
1420: "*
1421: {
1422: if (REG_P (operands[2]))
1423: return AS2 (rol%W0,%%cl,%0);
1424: else
1425: return AS2 (rol%W0,%2,%1);
1426: }")
1427:
1428: (define_insn "rotlqi3"
1429: [(set (match_operand:QI 0 "general_operand" "=qm")
1430: (rotate:QI (match_operand:QI 1 "general_operand" "0")
1431: (match_operand:QI 2 "general_operand" "cI")))]
1432: ""
1433: "*
1434: {
1435: if (REG_P (operands[2]))
1436: return AS2 (rol%B0,%%cl,%0);
1437: else
1438: return AS2 (rol%B0,%2,%1);
1439: }")
1440:
1441: (define_insn "rotrsi3"
1442: [(set (match_operand:SI 0 "general_operand" "=rm")
1443: (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1444: (match_operand:SI 2 "general_operand" "cI")))]
1445: ""
1446: "*
1447: {
1448: if (REG_P (operands[2]))
1449: return AS2 (ror%L0,%%cl,%0);
1450: else
1451: return AS2 (ror%L0,%2,%1);
1452: }")
1453:
1454: (define_insn "rotrhi3"
1455: [(set (match_operand:HI 0 "general_operand" "=rm")
1456: (rotatert:HI (match_operand:HI 1 "general_operand" "0")
1457: (match_operand:HI 2 "general_operand" "cI")))]
1458: ""
1459: "*
1460: {
1461: if (REG_P (operands[2]))
1462: return AS2 (ror%W0,%%cl,%0);
1463: else
1464: return AS2 (ror%W0,%2,%1);
1465: }")
1466:
1467: (define_insn "rotrqi3"
1468: [(set (match_operand:QI 0 "general_operand" "=qm")
1469: (rotatert:QI (match_operand:QI 1 "general_operand" "0")
1470: (match_operand:QI 2 "general_operand" "cI")))]
1471: ""
1472: "*
1473: {
1474: if (REG_P (operands[2]))
1475: return AS2 (ror%B0,%%cl,%0);
1476: else
1477: return AS2 (ror%B0,%2,%1);
1478: }")
1479:
1480: ;; Store-flag instructions.
1481:
1482: (define_insn "seq"
1483: [(set (match_operand:QI 0 "general_operand" "=q")
1484: (eq (cc0) (const_int 0)))]
1485: ""
1486: "*
1487: cc_status = cc_prev_status;
1488: return \"sete %0\";
1489: ")
1490:
1491: (define_insn "sne"
1492: [(set (match_operand:QI 0 "general_operand" "=q")
1493: (ne (cc0) (const_int 0)))]
1494: ""
1495: "*
1496: cc_status = cc_prev_status;
1497: return \"setne %0\";
1498: ")
1499:
1500: (define_insn "sgt"
1501: [(set (match_operand:QI 0 "general_operand" "=q")
1502: (gt (cc0) (const_int 0)))]
1503: ""
1504: "*
1505: cc_status = cc_prev_status;
1506: OUTPUT_JUMP (\"setg %0\", \"seta %0\", 0);
1507: ")
1508:
1509: (define_insn "sgtu"
1510: [(set (match_operand:QI 0 "general_operand" "=q")
1511: (gtu (cc0) (const_int 0)))]
1512: ""
1513: "* cc_status = cc_prev_status;
1514: return \"seta %0\"; ")
1515:
1516: (define_insn "slt"
1517: [(set (match_operand:QI 0 "general_operand" "=q")
1518: (lt (cc0) (const_int 0)))]
1519: ""
1520: "* cc_status = cc_prev_status;
1521: OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\"); ")
1522:
1523: (define_insn "sltu"
1524: [(set (match_operand:QI 0 "general_operand" "=q")
1525: (ltu (cc0) (const_int 0)))]
1526: ""
1527: "* cc_status = cc_prev_status;
1528: return \"setb %0\"; ")
1529:
1530: (define_insn "sge"
1531: [(set (match_operand:QI 0 "general_operand" "=q")
1532: (ge (cc0) (const_int 0)))]
1533: ""
1534: "* cc_status = cc_prev_status;
1535: OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\"); ")
1536:
1537: (define_insn "sgeu"
1538: [(set (match_operand:QI 0 "general_operand" "=q")
1539: (geu (cc0) (const_int 0)))]
1540: ""
1541: "* cc_status = cc_prev_status;
1542: return \"setae %0\"; ")
1543:
1544: (define_insn "sle"
1545: [(set (match_operand:QI 0 "general_operand" "=q")
1546: (le (cc0) (const_int 0)))]
1547: ""
1548: "*
1549: cc_status = cc_prev_status;
1550: OUTPUT_JUMP (\"setle %0\", \"setbe %0\", 0);
1551: ")
1552:
1553: (define_insn "sleu"
1554: [(set (match_operand:QI 0 "general_operand" "=q")
1555: (leu (cc0) (const_int 0)))]
1556: ""
1557: "* cc_status = cc_prev_status;
1558: return \"setbe %0\"; ")
1559:
1560: ;; Basic conditional jump instructions.
1561: ;; We ignore the overflow flag for signed branch instructions.
1562:
1563: (define_insn "beq"
1564: [(set (pc)
1565: (if_then_else (eq (cc0)
1566: (const_int 0))
1567: (label_ref (match_operand 0 "" ""))
1568: (pc)))]
1569: ""
1570: "je %l0")
1571:
1572: (define_insn "bne"
1573: [(set (pc)
1574: (if_then_else (ne (cc0)
1575: (const_int 0))
1576: (label_ref (match_operand 0 "" ""))
1577: (pc)))]
1578: ""
1579: "jne %l0")
1580:
1581: (define_insn "bgt"
1582: [(set (pc)
1583: (if_then_else (gt (cc0)
1584: (const_int 0))
1585: (label_ref (match_operand 0 "" ""))
1586: (pc)))]
1587: ""
1588: "*OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0)")
1589:
1590: (define_insn "bgtu"
1591: [(set (pc)
1592: (if_then_else (gtu (cc0)
1593: (const_int 0))
1594: (label_ref (match_operand 0 "" ""))
1595: (pc)))]
1596: ""
1597: "ja %l0")
1598:
1599: (define_insn "blt"
1600: [(set (pc)
1601: (if_then_else (lt (cc0)
1602: (const_int 0))
1603: (label_ref (match_operand 0 "" ""))
1604: (pc)))]
1605: ""
1606: "*OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\")")
1607:
1608: (define_insn "bltu"
1609: [(set (pc)
1610: (if_then_else (ltu (cc0)
1611: (const_int 0))
1612: (label_ref (match_operand 0 "" ""))
1613: (pc)))]
1614: ""
1615: "jb %l0")
1616:
1617: (define_insn "bge"
1618: [(set (pc)
1619: (if_then_else (ge (cc0)
1620: (const_int 0))
1621: (label_ref (match_operand 0 "" ""))
1622: (pc)))]
1623: ""
1624: "*OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\")")
1625:
1626: (define_insn "bgeu"
1627: [(set (pc)
1628: (if_then_else (geu (cc0)
1629: (const_int 0))
1630: (label_ref (match_operand 0 "" ""))
1631: (pc)))]
1632: ""
1633: "jae %l0")
1634:
1635: (define_insn "ble"
1636: [(set (pc)
1637: (if_then_else (le (cc0)
1638: (const_int 0))
1639: (label_ref (match_operand 0 "" ""))
1640: (pc)))]
1641: ""
1642: "*OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0) ")
1643:
1644: (define_insn "bleu"
1645: [(set (pc)
1646: (if_then_else (leu (cc0)
1647: (const_int 0))
1648: (label_ref (match_operand 0 "" ""))
1649: (pc)))]
1650: ""
1651: "jbe %l0")
1652:
1653: ;; Negated conditional jump instructions.
1654:
1655: (define_insn ""
1656: [(set (pc)
1657: (if_then_else (eq (cc0)
1658: (const_int 0))
1659: (pc)
1660: (label_ref (match_operand 0 "" ""))))]
1661: ""
1662: "jne %l0")
1663:
1664: (define_insn ""
1665: [(set (pc)
1666: (if_then_else (ne (cc0)
1667: (const_int 0))
1668: (pc)
1669: (label_ref (match_operand 0 "" ""))))]
1670: ""
1671: "je %l0")
1672:
1673: (define_insn ""
1674: [(set (pc)
1675: (if_then_else (gt (cc0)
1676: (const_int 0))
1677: (pc)
1678: (label_ref (match_operand 0 "" ""))))]
1679: ""
1680: "*OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0) ")
1681:
1682: (define_insn ""
1683: [(set (pc)
1684: (if_then_else (gtu (cc0)
1685: (const_int 0))
1686: (pc)
1687: (label_ref (match_operand 0 "" ""))))]
1688: ""
1689: "jbe %l0")
1690:
1691: (define_insn ""
1692: [(set (pc)
1693: (if_then_else (lt (cc0)
1694: (const_int 0))
1695: (pc)
1696: (label_ref (match_operand 0 "" ""))))]
1697: ""
1698: "*OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\")
1699: ")
1700:
1701: (define_insn ""
1702: [(set (pc)
1703: (if_then_else (ltu (cc0)
1704: (const_int 0))
1705: (pc)
1706: (label_ref (match_operand 0 "" ""))))]
1707: ""
1708: "jae %l0")
1709:
1710: (define_insn ""
1711: [(set (pc)
1712: (if_then_else (ge (cc0)
1713: (const_int 0))
1714: (pc)
1715: (label_ref (match_operand 0 "" ""))))]
1716: ""
1717: "*OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\")")
1718:
1719: (define_insn ""
1720: [(set (pc)
1721: (if_then_else (geu (cc0)
1722: (const_int 0))
1723: (pc)
1724: (label_ref (match_operand 0 "" ""))))]
1725: ""
1726: "jb %l0")
1727:
1728: (define_insn ""
1729: [(set (pc)
1730: (if_then_else (le (cc0)
1731: (const_int 0))
1732: (pc)
1733: (label_ref (match_operand 0 "" ""))))]
1734: ""
1735: "*OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0)")
1736:
1737: (define_insn ""
1738: [(set (pc)
1739: (if_then_else (leu (cc0)
1740: (const_int 0))
1741: (pc)
1742: (label_ref (match_operand 0 "" ""))))]
1743: ""
1744: "ja %l0")
1745:
1746: ;; Unconditional and other jump instructions
1747: (define_insn "jump"
1748: [(set (pc)
1749: (label_ref (match_operand 0 "" "")))]
1750: ""
1751: "jmp %l0")
1752:
1753: (define_insn "tablejump"
1754: [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
1755: (use (label_ref (match_operand 1 "" "")))]
1756: ""
1757: "*
1758: {
1759: CC_STATUS_INIT;
1760:
1761: return \"jmp %*%0\";
1762: }")
1763:
1764: /*
1765: (define_insn ""
1766: [(set (pc)
1767: (if_then_else
1768: (ne (compare (minus:HI (match_operand:HI 0 "general_operand" "c")
1769: (const_int 1))
1770: (const_int -1))
1771: (const_int 0))
1772: (label_ref (match_operand 1 "" "g"))
1773: (pc)))
1774: (set (match_dup 0)
1775: (minus:HI (match_dup 0)
1776: (const_int 1)))]
1777: ""
1778: "loop %l1")
1779:
1780: (define_insn ""
1781: [(set (pc)
1782: (if_then_else
1783: (ne (compare (const_int -1)
1784: (minus:SI (match_operand:SI 0 "general_operand" "c")
1785: (const_int 1)))
1786: (const_int 0))
1787: (label_ref (match_operand 1 "" "g"))
1788: (pc)))
1789: (set (match_dup 0)
1790: (minus:SI (match_dup 0)
1791: (const_int 1)))]
1792: ""
1793: "loop %l1")
1794: */
1795:
1796: ;; Call subroutine returning no value.
1797: (define_insn "call"
1798: [(call (match_operand:QI 0 "indirect_operand" "m")
1799: (match_operand:SI 1 "general_operand" "g"))]
1800: ;; Operand 1 not really used on the m68000.
1801: ""
1802: "*
1803: {
1804: if (GET_CODE (operands[0]) == MEM
1805: && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1806: {
1807: operands[0] = XEXP (operands[0], 0);
1808: return \"call %*%0\";
1809: }
1810: else
1811: return \"call %0\";
1812: }")
1813:
1814: ;; Call subroutine, returning value in operand 0
1815: ;; (which must be a hard register).
1816: (define_insn "call_value"
1817: [(set (match_operand 0 "" "=rf")
1818: (call (match_operand:QI 1 "indirect_operand" "m")
1819: (match_operand:SI 2 "general_operand" "g")))]
1820: ;; Operand 2 not really used on the m68000.
1821: ""
1822: "*
1823: {
1824: if (GET_CODE (operands[1]) == MEM
1825: && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1826: {
1827: operands[1] = XEXP (operands[1], 0);
1828: output_asm_insn (\"call %*%1\", operands);
1829: }
1830: else
1831: output_asm_insn (\"call %1\", operands);
1832:
1833: if (GET_MODE (operands[0]) == DFmode
1834: || GET_MODE (operands[0]) == SFmode)
1835: {
1836: /* fp_pop_level++; */
1837: /* pop if reg dead */
1838: if (!FP_REG_P (operands[0]))
1839: abort ();
1840: if (top_dead_p (insn))
1841: {
1842: POP_ONE_FP;
1843: }
1844: }
1845: RET;
1846: }")
1847:
1848: (define_insn "nop"
1849: [(const_int 0)]
1850: ""
1851: "nop")
1852:
1853: ;;- Local variables:
1854: ;;- mode:emacs-lisp
1855: ;;- comment-start: ";;- "
1856: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
1857: ;;- eval: (modify-syntax-entry ?[ "(]")
1858: ;;- eval: (modify-syntax-entry ?] ")[")
1859: ;;- eval: (modify-syntax-entry ?{ "(}")
1860: ;;- eval: (modify-syntax-entry ?} "){")
1861: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.