|
|
1.1 root 1: ;;- Machine description for GNU compiler, Vax Version
2: ;; Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc.
3:
4: ;; This file is part of GNU CC.
5:
6: ;; GNU CC is free software; you can redistribute it and/or modify
7: ;; it under the terms of the GNU General Public License as published by
8: ;; the Free Software Foundation; either version 2, or (at your option)
9: ;; any later version.
10:
11: ;; GNU CC is distributed in the hope that it will be useful,
12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: ;; GNU General Public License for more details.
15:
16: ;; You should have received a copy of the GNU General Public License
17: ;; along with GNU CC; see the file COPYING. If not, write to
18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19:
20:
21: ;;- Instruction patterns. When multiple patterns apply,
22: ;;- the first one in the file is chosen.
23: ;;-
24: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25: ;;-
26: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
27: ;;- updates for most instructions.
28:
29: ;; We don't want to allow a constant operand for test insns because
30: ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
31: ;; be folded while optimizing anyway.
32:
33: (define_insn "tstsi"
34: [(set (cc0)
35: (match_operand:SI 0 "nonimmediate_operand" "g"))]
36: ""
37: "tstl %0")
38:
39: (define_insn "tsthi"
40: [(set (cc0)
41: (match_operand:HI 0 "nonimmediate_operand" "g"))]
42: ""
43: "tstw %0")
44:
45: (define_insn "tstqi"
46: [(set (cc0)
47: (match_operand:QI 0 "nonimmediate_operand" "g"))]
48: ""
49: "tstb %0")
50:
51: (define_insn "tstdf"
52: [(set (cc0)
53: (match_operand:DF 0 "general_operand" "gF"))]
54: ""
55: "tst%# %0")
56:
57: (define_insn "tstsf"
58: [(set (cc0)
59: (match_operand:SF 0 "general_operand" "gF"))]
60: ""
61: "tstf %0")
62:
63: (define_insn "cmpsi"
64: [(set (cc0)
65: (compare (match_operand:SI 0 "nonimmediate_operand" "g")
66: (match_operand:SI 1 "general_operand" "g")))]
67: ""
68: "cmpl %0,%1")
69:
70: (define_insn "cmphi"
71: [(set (cc0)
72: (compare (match_operand:HI 0 "nonimmediate_operand" "g")
73: (match_operand:HI 1 "general_operand" "g")))]
74: ""
75: "cmpw %0,%1")
76:
77: (define_insn "cmpqi"
78: [(set (cc0)
79: (compare (match_operand:QI 0 "nonimmediate_operand" "g")
80: (match_operand:QI 1 "general_operand" "g")))]
81: ""
82: "cmpb %0,%1")
83:
84: (define_insn "cmpdf"
85: [(set (cc0)
86: (compare (match_operand:DF 0 "general_operand" "gF,gF")
87: (match_operand:DF 1 "general_operand" "G,gF")))]
88: ""
89: "@
90: tst%# %0
91: cmp%# %0,%1")
92:
93: (define_insn "cmpsf"
94: [(set (cc0)
95: (compare (match_operand:SF 0 "general_operand" "gF,gF")
96: (match_operand:SF 1 "general_operand" "G,gF")))]
97: ""
98: "@
99: tstf %0
100: cmpf %0,%1")
101:
102: (define_insn ""
103: [(set (cc0)
104: (and:SI (match_operand:SI 0 "general_operand" "g")
105: (match_operand:SI 1 "general_operand" "g")))]
106: ""
107: "bitl %0,%1")
108:
109: (define_insn ""
110: [(set (cc0)
111: (and:HI (match_operand:HI 0 "general_operand" "g")
112: (match_operand:HI 1 "general_operand" "g")))]
113: ""
114: "bitw %0,%1")
115:
116: (define_insn ""
117: [(set (cc0)
118: (and:QI (match_operand:QI 0 "general_operand" "g")
119: (match_operand:QI 1 "general_operand" "g")))]
120: ""
121: "bitb %0,%1")
122:
123: ;; The vax has no sltu or sgeu patterns, but does have two-operand
124: ;; add/subtract with carry. This is still better than the alternative.
125: ;; Since the cc0-using insn cannot be separated from the cc0-setting insn,
126: ;; and the two are created independently, we can't just use a define_expand
127: ;; to try to optimize this. (The "movl" and "clrl" insns alter the cc0
128: ;; flags, but leave the carry flag alone, but that can't easily be expressed.)
129: ;;
130: ;; Several two-operator combinations could be added to make slightly more
131: ;; optimal code, but they'd have to cover all combinations of plus and minus
132: ;; using match_dup. If you want to do this, I'd suggest changing the "sgeu"
133: ;; pattern to something like (minus (const_int 1) (ltu ...)), so fewer
134: ;; patterns need to be recognized.
135: ;; -- Ken Raeburn ([email protected]) 24 August 1991.
136:
137: (define_insn "sltu"
138: [(set (match_operand:SI 0 "general_operand" "=ro")
139: (ltu (cc0) (const_int 0)))]
140: ""
141: "clrl %0\;adwc $0,%0")
142:
143: (define_insn "sgeu"
144: [(set (match_operand:SI 0 "general_operand" "=ro")
145: (geu (cc0) (const_int 0)))]
146: ""
147: "movl $1,%0\;sbwc $0,%0")
148:
149: (define_insn "movdf"
150: [(set (match_operand:DF 0 "general_operand" "=g,g")
151: (match_operand:DF 1 "general_operand" "G,gF"))]
152: ""
153: "@
154: clr%# %0
155: mov%# %1,%0")
156:
157: (define_insn "movsf"
158: [(set (match_operand:SF 0 "general_operand" "=g,g")
159: (match_operand:SF 1 "general_operand" "G,gF"))]
160: ""
161: "@
162: clrf %0
163: movf %1,%0")
164:
165: ;; Some vaxes don't support this instruction.
166: ;;(define_insn "movti"
167: ;; [(set (match_operand:TI 0 "general_operand" "=g")
168: ;; (match_operand:TI 1 "general_operand" "g"))]
169: ;; ""
170: ;; "movh %1,%0")
171:
172: (define_insn "movdi"
173: [(set (match_operand:DI 0 "general_operand" "=g,g")
174: (match_operand:DI 1 "general_operand" "I,g"))]
175: ""
176: "@
177: clrq %0
178: movq %D1,%0")
179:
180: ;; The VAX move instructions have space-time tradeoffs. On a microVAX
181: ;; register-register mov instructions take 3 bytes and 2 CPU cycles. clrl
182: ;; takes 2 bytes and 3 cycles. mov from constant to register takes 2 cycles
183: ;; if the constant is smaller than 4 bytes, 3 cycles for a longword
184: ;; constant. movz, mneg, and mcom are as fast as mov, so movzwl is faster
185: ;; than movl for positive constants that fit in 16 bits but not 6 bits. cvt
186: ;; instructions take 4 cycles. inc takes 3 cycles. The machine description
187: ;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl
188: ;; instead of movl).
189:
190: ;; Cycle counts for other models may vary (on a VAX 750 they are similar,
191: ;; but on a VAX 9000 most move and add instructions with one constant
192: ;; operand take 1 cycle).
193:
194: ;; Loads of constants between 64 and 128 used to be done with
195: ;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space.
196:
197: (define_insn "movsi"
198: [(set (match_operand:SI 0 "general_operand" "=g")
199: (match_operand:SI 1 "general_operand" "g"))]
200: ""
201: "*
202: {
203: rtx link;
204: if (operands[1] == const1_rtx
205: && (link = find_reg_note (insn, REG_WAS_0, 0))
206: /* Make sure the insn that stored the 0 is still present. */
207: && ! INSN_DELETED_P (XEXP (link, 0))
208: && GET_CODE (XEXP (link, 0)) != NOTE
209: /* Make sure cross jumping didn't happen here. */
210: && no_labels_between_p (XEXP (link, 0), insn)
211: /* Make sure the reg hasn't been clobbered. */
212: && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
213: return \"incl %0\";
214: if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
215: {
216: if (push_operand (operands[0], SImode))
217: return \"pushab %a1\";
218: return \"movab %a1,%0\";
219: }
220: if (operands[1] == const0_rtx)
221: return \"clrl %0\";
222: if (GET_CODE (operands[1]) == CONST_INT
223: && (unsigned) INTVAL (operands[1]) >= 64)
224: {
225: int i = INTVAL (operands[1]);
226: if ((unsigned)(~i) < 64)
227: return \"mcoml %N1,%0\";
228: if ((unsigned)i < 0x100)
229: return \"movzbl %1,%0\";
230: if (i >= -0x80 && i < 0)
231: return \"cvtbl %1,%0\";
232: if ((unsigned)i < 0x10000)
233: return \"movzwl %1,%0\";
234: if (i >= -0x8000 && i < 0)
235: return \"cvtwl %1,%0\";
236: }
237: if (push_operand (operands[0], SImode))
238: return \"pushl %1\";
239: return \"movl %1,%0\";
240: }")
241:
242: (define_insn "movhi"
243: [(set (match_operand:HI 0 "general_operand" "=g")
244: (match_operand:HI 1 "general_operand" "g"))]
245: ""
246: "*
247: {
248: rtx link;
249: if (operands[1] == const1_rtx
250: && (link = find_reg_note (insn, REG_WAS_0, 0))
251: /* Make sure the insn that stored the 0 is still present. */
252: && ! INSN_DELETED_P (XEXP (link, 0))
253: && GET_CODE (XEXP (link, 0)) != NOTE
254: /* Make sure cross jumping didn't happen here. */
255: && no_labels_between_p (XEXP (link, 0), insn)
256: /* Make sure the reg hasn't been clobbered. */
257: && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
258: return \"incw %0\";
259:
260: if (GET_CODE (operands[1]) == CONST_INT)
261: {
262: int i = INTVAL (operands[1]);
263: if (i == 0)
264: return \"clrw %0\";
265: else if ((unsigned int)i < 64)
266: return \"movw %1,%0\";
267: else if ((unsigned int)~i < 64)
268: return \"mcomw %H1,%0\";
269: else if ((unsigned int)i < 256)
270: return \"movzbw %1,%0\";
271: }
272: return \"movw %1,%0\";
273: }")
274:
275: (define_insn "movstricthi"
276: [(set (strict_low_part (match_operand:HI 0 "register_operand" "=g"))
277: (match_operand:HI 1 "general_operand" "g"))]
278: ""
279: "*
280: {
281: if (GET_CODE (operands[1]) == CONST_INT)
282: {
283: int i = INTVAL (operands[1]);
284: if (i == 0)
285: return \"clrw %0\";
286: else if ((unsigned int)i < 64)
287: return \"movw %1,%0\";
288: else if ((unsigned int)~i < 64)
289: return \"mcomw %H1,%0\";
290: else if ((unsigned int)i < 256)
291: return \"movzbw %1,%0\";
292: }
293: return \"movw %1,%0\";
294: }")
295:
296: (define_insn "movqi"
297: [(set (match_operand:QI 0 "general_operand" "=g")
298: (match_operand:QI 1 "general_operand" "g"))]
299: ""
300: "*
301: {
302: rtx link;
303: if (operands[1] == const1_rtx
304: && (link = find_reg_note (insn, REG_WAS_0, 0))
305: /* Make sure the insn that stored the 0 is still present. */
306: && ! INSN_DELETED_P (XEXP (link, 0))
307: && GET_CODE (XEXP (link, 0)) != NOTE
308: /* Make sure cross jumping didn't happen here. */
309: && no_labels_between_p (XEXP (link, 0), insn)
310: /* Make sure the reg hasn't been clobbered. */
311: && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
312: return \"incb %0\";
313:
314: if (GET_CODE (operands[1]) == CONST_INT)
315: {
316: int i = INTVAL (operands[1]);
317: if (i == 0)
318: return \"clrb %0\";
319: else if ((unsigned int)~i < 64)
320: return \"mcomb %B1,%0\";
321: }
322: return \"movb %1,%0\";
323: }")
324:
325: (define_insn "movstrictqi"
326: [(set (strict_low_part (match_operand:QI 0 "register_operand" "=g"))
327: (match_operand:QI 1 "general_operand" "g"))]
328: ""
329: "*
330: {
331: if (GET_CODE (operands[1]) == CONST_INT)
332: {
333: int i = INTVAL (operands[1]);
334: if (i == 0)
335: return \"clrb %0\";
336: else if ((unsigned int)~i < 64)
337: return \"mcomb %B1,%0\";
338: }
339: return \"movb %1,%0\";
340: }")
341:
342: ;; This is here to accept 4 arguments and pass the first 3 along
343: ;; to the movstrhi1 pattern that really does the work.
344: (define_expand "movstrhi"
345: [(set (match_operand:BLK 0 "general_operand" "=g")
346: (match_operand:BLK 1 "general_operand" "g"))
347: (use (match_operand:HI 2 "general_operand" "g"))
348: (match_operand 3 "" "")]
349: ""
350: "
351: emit_insn (gen_movstrhi1 (operands[0], operands[1], operands[2]));
352: DONE;
353: ")
354:
355: ;; The definition of this insn does not really explain what it does,
356: ;; but it should suffice
357: ;; that anything generated as this insn will be recognized as one
358: ;; and that it won't successfully combine with anything.
359: (define_insn "movstrhi1"
360: [(set (match_operand:BLK 0 "general_operand" "=g")
361: (match_operand:BLK 1 "general_operand" "g"))
362: (use (match_operand:HI 2 "general_operand" "g"))
363: (clobber (reg:SI 0))
364: (clobber (reg:SI 1))
365: (clobber (reg:SI 2))
366: (clobber (reg:SI 3))
367: (clobber (reg:SI 4))
368: (clobber (reg:SI 5))]
369: ""
370: "movc3 %2,%1,%0")
371:
372: ;; Extension and truncation insns.
373:
374: (define_insn "truncsiqi2"
375: [(set (match_operand:QI 0 "general_operand" "=g")
376: (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "g")))]
377: ""
378: "cvtlb %1,%0")
379:
380: (define_insn "truncsihi2"
381: [(set (match_operand:HI 0 "general_operand" "=g")
382: (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "g")))]
383: ""
384: "cvtlw %1,%0")
385:
386: (define_insn "trunchiqi2"
387: [(set (match_operand:QI 0 "general_operand" "=g")
388: (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))]
389: ""
390: "cvtwb %1,%0")
391:
392: (define_insn "extendhisi2"
393: [(set (match_operand:SI 0 "general_operand" "=g")
394: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
395: ""
396: "cvtwl %1,%0")
397:
398: (define_insn "extendqihi2"
399: [(set (match_operand:HI 0 "general_operand" "=g")
400: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
401: ""
402: "cvtbw %1,%0")
403:
404: (define_insn "extendqisi2"
405: [(set (match_operand:SI 0 "general_operand" "=g")
406: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
407: ""
408: "cvtbl %1,%0")
409:
410: (define_insn "extendsfdf2"
411: [(set (match_operand:DF 0 "general_operand" "=g")
412: (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))]
413: ""
414: "cvtf%# %1,%0")
415:
416: (define_insn "truncdfsf2"
417: [(set (match_operand:SF 0 "general_operand" "=g")
418: (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))]
419: ""
420: "cvt%#f %1,%0")
421:
422: (define_insn "zero_extendhisi2"
423: [(set (match_operand:SI 0 "general_operand" "=g")
424: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
425: ""
426: "movzwl %1,%0")
427:
428: (define_insn "zero_extendqihi2"
429: [(set (match_operand:HI 0 "general_operand" "=g")
430: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
431: ""
432: "movzbw %1,%0")
433:
434: (define_insn "zero_extendqisi2"
435: [(set (match_operand:SI 0 "general_operand" "=g")
436: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
437: ""
438: "movzbl %1,%0")
439:
440: ;; Fix-to-float conversion insns.
441:
442: (define_insn "floatsisf2"
443: [(set (match_operand:SF 0 "general_operand" "=g")
444: (float:SF (match_operand:SI 1 "nonimmediate_operand" "g")))]
445: ""
446: "cvtlf %1,%0")
447:
448: (define_insn "floatsidf2"
449: [(set (match_operand:DF 0 "general_operand" "=g")
450: (float:DF (match_operand:SI 1 "nonimmediate_operand" "g")))]
451: ""
452: "cvtl%# %1,%0")
453:
454: (define_insn "floathisf2"
455: [(set (match_operand:SF 0 "general_operand" "=g")
456: (float:SF (match_operand:HI 1 "nonimmediate_operand" "g")))]
457: ""
458: "cvtwf %1,%0")
459:
460: (define_insn "floathidf2"
461: [(set (match_operand:DF 0 "general_operand" "=g")
462: (float:DF (match_operand:HI 1 "nonimmediate_operand" "g")))]
463: ""
464: "cvtw%# %1,%0")
465:
466: (define_insn "floatqisf2"
467: [(set (match_operand:SF 0 "general_operand" "=g")
468: (float:SF (match_operand:QI 1 "nonimmediate_operand" "g")))]
469: ""
470: "cvtbf %1,%0")
471:
472: (define_insn "floatqidf2"
473: [(set (match_operand:DF 0 "general_operand" "=g")
474: (float:DF (match_operand:QI 1 "nonimmediate_operand" "g")))]
475: ""
476: "cvtb%# %1,%0")
477:
478: ;; Float-to-fix conversion insns.
479:
480: (define_insn "fix_truncsfqi2"
481: [(set (match_operand:QI 0 "general_operand" "=g")
482: (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))]
483: ""
484: "cvtfb %1,%0")
485:
486: (define_insn "fix_truncsfhi2"
487: [(set (match_operand:HI 0 "general_operand" "=g")
488: (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))]
489: ""
490: "cvtfw %1,%0")
491:
492: (define_insn "fix_truncsfsi2"
493: [(set (match_operand:SI 0 "general_operand" "=g")
494: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))]
495: ""
496: "cvtfl %1,%0")
497:
498: (define_insn "fix_truncdfqi2"
499: [(set (match_operand:QI 0 "general_operand" "=g")
500: (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))]
501: ""
502: "cvt%#b %1,%0")
503:
504: (define_insn "fix_truncdfhi2"
505: [(set (match_operand:HI 0 "general_operand" "=g")
506: (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))]
507: ""
508: "cvt%#w %1,%0")
509:
510: (define_insn "fix_truncdfsi2"
511: [(set (match_operand:SI 0 "general_operand" "=g")
512: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))]
513: ""
514: "cvt%#l %1,%0")
515:
516: ;;- All kinds of add instructions.
517:
518: (define_insn "adddf3"
519: [(set (match_operand:DF 0 "general_operand" "=g,g,g")
520: (plus:DF (match_operand:DF 1 "general_operand" "0,gF,gF")
521: (match_operand:DF 2 "general_operand" "gF,0,gF")))]
522: ""
523: "@
524: add%#2 %2,%0
525: add%#2 %1,%0
526: add%#3 %1,%2,%0")
527:
528: (define_insn "addsf3"
529: [(set (match_operand:SF 0 "general_operand" "=g,g,g")
530: (plus:SF (match_operand:SF 1 "general_operand" "0,gF,gF")
531: (match_operand:SF 2 "general_operand" "gF,0,gF")))]
532: ""
533: "@
534: addf2 %2,%0
535: addf2 %1,%0
536: addf3 %1,%2,%0")
537:
538: /* The space-time-opcode tradeoffs for addition vary by model of VAX.
539:
540: On a VAX 3 "movab (r1)[r2],r3" is faster than "addl3 r1,r2,r3",
541: but it not faster on other models.
542:
543: "movab #(r1),r2" is usually shorter than "addl3 #,r1,r2", and is
544: faster on a VAX 3, but some VAXes (e.g. VAX 9000) will stall if
545: a register is used in an address too soon after it is set.
546: Compromise by using movab only when it is shorter than the add
547: or the base register in the address is one of sp, ap, and fp,
548: which are not modified very often. */
549:
550:
551: (define_insn "addsi3"
552: [(set (match_operand:SI 0 "general_operand" "=g")
553: (plus:SI (match_operand:SI 1 "general_operand" "g")
554: (match_operand:SI 2 "general_operand" "g")))]
555: ""
556: "*
557: {
558: if (rtx_equal_p (operands[0], operands[1]))
559: {
560: if (operands[2] == const1_rtx)
561: return \"incl %0\";
562: if (operands[2] == constm1_rtx)
563: return \"decl %0\";
564: if (GET_CODE (operands[2]) == CONST_INT
565: && (unsigned) (- INTVAL (operands[2])) < 64)
566: return \"subl2 $%n2,%0\";
567: if (GET_CODE (operands[2]) == CONST_INT
568: && (unsigned) INTVAL (operands[2]) >= 64
569: && GET_CODE (operands[1]) == REG
570: && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768)
571: || REGNO (operands[1]) > 11))
572: return \"movab %c2(%1),%0\";
573: return \"addl2 %2,%0\";
574: }
575: if (rtx_equal_p (operands[0], operands[2]))
576: return \"addl2 %1,%0\";
577:
578: if (GET_CODE (operands[2]) == CONST_INT
579: && INTVAL (operands[2]) < 32767
580: && INTVAL (operands[2]) > -32768
581: && GET_CODE (operands[1]) == REG
582: && push_operand (operands[0], SImode))
583: return \"pushab %c2(%1)\";
584:
585: if (GET_CODE (operands[2]) == CONST_INT
586: && (unsigned) (- INTVAL (operands[2])) < 64)
587: return \"subl3 $%n2,%1,%0\";
588:
589: if (GET_CODE (operands[2]) == CONST_INT
590: && (unsigned) INTVAL (operands[2]) >= 64
591: && GET_CODE (operands[1]) == REG
592: && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768)
593: || REGNO (operands[1]) > 11))
594: return \"movab %c2(%1),%0\";
595:
596: /* Add this if using gcc on a VAX 3xxx:
597: if (REG_P (operands[1]) && REG_P (operands[2]))
598: return \"movab (%1)[%2],%0\";
599: */
600: return \"addl3 %1,%2,%0\";
601: }")
602:
603: (define_insn "addhi3"
604: [(set (match_operand:HI 0 "general_operand" "=g")
605: (plus:HI (match_operand:HI 1 "general_operand" "g")
606: (match_operand:HI 2 "general_operand" "g")))]
607: ""
608: "*
609: {
610: if (rtx_equal_p (operands[0], operands[1]))
611: {
612: if (operands[2] == const1_rtx)
613: return \"incw %0\";
614: if (operands[2] == constm1_rtx)
615: return \"decw %0\";
616: if (GET_CODE (operands[2]) == CONST_INT
617: && (unsigned) (- INTVAL (operands[2])) < 64)
618: return \"subw2 $%n2,%0\";
619: return \"addw2 %2,%0\";
620: }
621: if (rtx_equal_p (operands[0], operands[2]))
622: return \"addw2 %1,%0\";
623: if (GET_CODE (operands[2]) == CONST_INT
624: && (unsigned) (- INTVAL (operands[2])) < 64)
625: return \"subw3 $%n2,%1,%0\";
626: return \"addw3 %1,%2,%0\";
627: }")
628:
629: (define_insn "addqi3"
630: [(set (match_operand:QI 0 "general_operand" "=g")
631: (plus:QI (match_operand:QI 1 "general_operand" "g")
632: (match_operand:QI 2 "general_operand" "g")))]
633: ""
634: "*
635: {
636: if (rtx_equal_p (operands[0], operands[1]))
637: {
638: if (operands[2] == const1_rtx)
639: return \"incb %0\";
640: if (operands[2] == constm1_rtx)
641: return \"decb %0\";
642: if (GET_CODE (operands[2]) == CONST_INT
643: && (unsigned) (- INTVAL (operands[2])) < 64)
644: return \"subb2 $%n2,%0\";
645: return \"addb2 %2,%0\";
646: }
647: if (rtx_equal_p (operands[0], operands[2]))
648: return \"addb2 %1,%0\";
649: if (GET_CODE (operands[2]) == CONST_INT
650: && (unsigned) (- INTVAL (operands[2])) < 64)
651: return \"subb3 $%n2,%1,%0\";
652: return \"addb3 %1,%2,%0\";
653: }")
654:
655: ;; The add-with-carry (adwc) instruction only accepts two operands.
656: (define_insn "adddi3"
657: [(set (match_operand:DI 0 "general_operand" "=ro>,ro>")
658: (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
659: (match_operand:DI 2 "general_operand" "Fro,F")))]
660: ""
661: "*
662: {
663: rtx low[3];
664: char *pattern;
665: int carry = 1;
666:
667: split_quadword_operands (operands, low, 3);
668: /* Add low parts. */
669: if (rtx_equal_p (operands[0], operands[1]))
670: {
671: if (low[2] == const0_rtx)
672: /* Should examine operand, punt if not POST_INC. */
673: pattern = \"tstl %0\", carry = 0;
674: else if (low[2] == const1_rtx)
675: pattern = \"incl %0\";
676: else
677: pattern = \"addl2 %2,%0\";
678: }
679: else
680: {
681: if (low[2] == const0_rtx)
682: pattern = \"movl %1,%0\", carry = 0;
683: else
684: pattern = \"addl3 %2,%1,%0\";
685: }
686: if (pattern)
687: output_asm_insn (pattern, low);
688: if (!carry)
689: /* If CARRY is 0, we don't have any carry value to worry about. */
690: return OUT_FCN (CODE_FOR_addsi3) (operands, insn);
691: /* %0 = C + %1 + %2 */
692: if (!rtx_equal_p (operands[0], operands[1]))
693: output_asm_insn ((operands[1] == const0_rtx
694: ? \"clrl %0\"
695: : \"movl %1,%0\"), operands);
696: return \"adwc %2,%0\";
697: }")
698:
699: ;;- All kinds of subtract instructions.
700:
701: (define_insn "subdf3"
702: [(set (match_operand:DF 0 "general_operand" "=g,g")
703: (minus:DF (match_operand:DF 1 "general_operand" "0,gF")
704: (match_operand:DF 2 "general_operand" "gF,gF")))]
705: ""
706: "@
707: sub%#2 %2,%0
708: sub%#3 %2,%1,%0")
709:
710: (define_insn "subsf3"
711: [(set (match_operand:SF 0 "general_operand" "=g,g")
712: (minus:SF (match_operand:SF 1 "general_operand" "0,gF")
713: (match_operand:SF 2 "general_operand" "gF,gF")))]
714: ""
715: "@
716: subf2 %2,%0
717: subf3 %2,%1,%0")
718:
719: (define_insn "subsi3"
720: [(set (match_operand:SI 0 "general_operand" "=g,g")
721: (minus:SI (match_operand:SI 1 "general_operand" "0,g")
722: (match_operand:SI 2 "general_operand" "g,g")))]
723: ""
724: "@
725: subl2 %2,%0
726: subl3 %2,%1,%0")
727:
728: (define_insn "subhi3"
729: [(set (match_operand:HI 0 "general_operand" "=g,g")
730: (minus:HI (match_operand:HI 1 "general_operand" "0,g")
731: (match_operand:HI 2 "general_operand" "g,g")))]
732: ""
733: "@
734: subw2 %2,%0
735: subw3 %2,%1,%0")
736:
737: (define_insn "subqi3"
738: [(set (match_operand:QI 0 "general_operand" "=g,g")
739: (minus:QI (match_operand:QI 1 "general_operand" "0,g")
740: (match_operand:QI 2 "general_operand" "g,g")))]
741: ""
742: "@
743: subb2 %2,%0
744: subb3 %2,%1,%0")
745:
746: ;; The subtract-with-carry (sbwc) instruction only takes two operands.
747: (define_insn "subdi3"
748: [(set (match_operand:DI 0 "general_operand" "=or>,or>")
749: (minus:DI (match_operand:DI 1 "general_operand" "0,or>")
750: (match_operand:DI 2 "general_operand" "For,F")))]
751: ""
752: "*
753: {
754: rtx low[3];
755: char *pattern;
756: int carry = 1;
757:
758: split_quadword_operands (operands, low, 3);
759: /* Subtract low parts. */
760: if (rtx_equal_p (operands[0], operands[1]))
761: {
762: if (low[2] == const0_rtx)
763: pattern = 0, carry = 0;
764: else if (low[2] == constm1_rtx)
765: pattern = \"decl %0\";
766: else
767: pattern = \"subl2 %2,%0\";
768: }
769: else
770: {
771: if (low[2] == constm1_rtx)
772: pattern = \"decl %0\";
773: else if (low[2] == const0_rtx)
774: pattern = OUT_FCN (CODE_FOR_movsi) (low, insn), carry = 0;
775: else
776: pattern = \"subl3 %2,%1,%0\";
777: }
778: if (pattern)
779: output_asm_insn (pattern, low);
780: if (carry)
781: {
782: if (!rtx_equal_p (operands[0], operands[1]))
783: return \"movl %1,%0\;sbwc %2,%0\";
784: return \"sbwc %2,%0\";
785: /* %0 = %2 - %1 - C */
786: }
787: return OUT_FCN (CODE_FOR_subsi3) (operands, insn);
788: }")
789:
790: ;;- Multiply instructions.
791:
792: (define_insn "muldf3"
793: [(set (match_operand:DF 0 "general_operand" "=g,g,g")
794: (mult:DF (match_operand:DF 1 "general_operand" "0,gF,gF")
795: (match_operand:DF 2 "general_operand" "gF,0,gF")))]
796: ""
797: "@
798: mul%#2 %2,%0
799: mul%#2 %1,%0
800: mul%#3 %1,%2,%0")
801:
802: (define_insn "mulsf3"
803: [(set (match_operand:SF 0 "general_operand" "=g,g,g")
804: (mult:SF (match_operand:SF 1 "general_operand" "0,gF,gF")
805: (match_operand:SF 2 "general_operand" "gF,0,gF")))]
806: ""
807: "@
808: mulf2 %2,%0
809: mulf2 %1,%0
810: mulf3 %1,%2,%0")
811:
812: (define_insn "mulsi3"
813: [(set (match_operand:SI 0 "general_operand" "=g,g,g")
814: (mult:SI (match_operand:SI 1 "general_operand" "0,g,g")
815: (match_operand:SI 2 "general_operand" "g,0,g")))]
816: ""
817: "@
818: mull2 %2,%0
819: mull2 %1,%0
820: mull3 %1,%2,%0")
821:
822: (define_insn "mulhi3"
823: [(set (match_operand:HI 0 "general_operand" "=g,g,")
824: (mult:HI (match_operand:HI 1 "general_operand" "0,g,g")
825: (match_operand:HI 2 "general_operand" "g,0,g")))]
826: ""
827: "@
828: mulw2 %2,%0
829: mulw2 %1,%0
830: mulw3 %1,%2,%0")
831:
832: (define_insn "mulqi3"
833: [(set (match_operand:QI 0 "general_operand" "=g,g,g")
834: (mult:QI (match_operand:QI 1 "general_operand" "0,g,g")
835: (match_operand:QI 2 "general_operand" "g,0,g")))]
836: ""
837: "@
838: mulb2 %2,%0
839: mulb2 %1,%0
840: mulb3 %1,%2,%0")
841:
842: (define_insn "mulsidi3"
843: [(set (match_operand:DI 0 "general_operand" "=g")
844: (mult:DI (sign_extend:DI
845: (match_operand:SI 1 "nonimmediate_operand" "g"))
846: (sign_extend:DI
847: (match_operand:SI 2 "nonimmediate_operand" "g"))))]
848: ""
849: "emul %1,%2,$0,%0")
850:
851: (define_insn ""
852: [(set (match_operand:DI 0 "general_operand" "=g")
853: (plus:DI
854: (mult:DI (sign_extend:DI
855: (match_operand:SI 1 "nonimmediate_operand" "g"))
856: (sign_extend:DI
857: (match_operand:SI 2 "nonimmediate_operand" "g")))
858: (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))]
859: ""
860: "emul %1,%2,%3,%0")
861:
862: ;; 'F' constraint means type CONST_DOUBLE
863: (define_insn ""
864: [(set (match_operand:DI 0 "general_operand" "=g")
865: (plus:DI
866: (mult:DI (sign_extend:DI
867: (match_operand:SI 1 "nonimmediate_operand" "g"))
868: (sign_extend:DI
869: (match_operand:SI 2 "nonimmediate_operand" "g")))
870: (match_operand:DI 3 "immediate_operand" "F")))]
871: "GET_CODE (operands[3]) == CONST_DOUBLE
872: && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
873: "*
874: {
875: if (CONST_DOUBLE_HIGH (operands[3]))
876: operands[3] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[3]));
877: return \"emul %1,%2,%3,%0\";
878: }")
879:
880: ;;- Divide instructions.
881:
882: (define_insn "divdf3"
883: [(set (match_operand:DF 0 "general_operand" "=g,g")
884: (div:DF (match_operand:DF 1 "general_operand" "0,gF")
885: (match_operand:DF 2 "general_operand" "gF,gF")))]
886: ""
887: "@
888: div%#2 %2,%0
889: div%#3 %2,%1,%0")
890:
891: (define_insn "divsf3"
892: [(set (match_operand:SF 0 "general_operand" "=g,g")
893: (div:SF (match_operand:SF 1 "general_operand" "0,gF")
894: (match_operand:SF 2 "general_operand" "gF,gF")))]
895: ""
896: "@
897: divf2 %2,%0
898: divf3 %2,%1,%0")
899:
900: (define_insn "divsi3"
901: [(set (match_operand:SI 0 "general_operand" "=g,g")
902: (div:SI (match_operand:SI 1 "general_operand" "0,g")
903: (match_operand:SI 2 "general_operand" "g,g")))]
904: ""
905: "@
906: divl2 %2,%0
907: divl3 %2,%1,%0")
908:
909: (define_insn "divhi3"
910: [(set (match_operand:HI 0 "general_operand" "=g,g")
911: (div:HI (match_operand:HI 1 "general_operand" "0,g")
912: (match_operand:HI 2 "general_operand" "g,g")))]
913: ""
914: "@
915: divw2 %2,%0
916: divw3 %2,%1,%0")
917:
918: (define_insn "divqi3"
919: [(set (match_operand:QI 0 "general_operand" "=g,g")
920: (div:QI (match_operand:QI 1 "general_operand" "0,g")
921: (match_operand:QI 2 "general_operand" "g,g")))]
922: ""
923: "@
924: divb2 %2,%0
925: divb3 %2,%1,%0")
926:
927: ;This is left out because it is very slow;
928: ;we are better off programming around the "lack" of this insn.
929: ;(define_insn "divmoddisi4"
930: ; [(set (match_operand:SI 0 "general_operand" "=g")
931: ; (div:SI (match_operand:DI 1 "general_operand" "g")
932: ; (match_operand:SI 2 "general_operand" "g")))
933: ; (set (match_operand:SI 3 "general_operand" "=g")
934: ; (mod:SI (match_operand:DI 1 "general_operand" "g")
935: ; (match_operand:SI 2 "general_operand" "g")))]
936: ; ""
937: ; "ediv %2,%1,%0,%3")
938:
939: ;; Bit-and on the vax is done with a clear-bits insn.
940: (define_expand "andsi3"
941: [(set (match_operand:SI 0 "general_operand" "=g")
942: (and:SI (not:SI (match_operand:SI 1 "general_operand" "g"))
943: (match_operand:SI 2 "general_operand" "g")))]
944: ""
945: "
946: {
947: rtx op1 = operands[1];
948:
949: /* If there is a constant argument, complement that one. */
950: if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT)
951: {
952: operands[1] = operands[2];
953: operands[2] = op1;
954: op1 = operands[1];
955: }
956:
957: if (GET_CODE (op1) == CONST_INT)
958: operands[1] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (op1));
959: else
960: operands[1] = expand_unop (SImode, one_cmpl_optab, op1, 0, 1);
961: }")
962:
963: (define_expand "andhi3"
964: [(set (match_operand:HI 0 "general_operand" "=g")
965: (and:HI (not:HI (match_operand:HI 1 "general_operand" "g"))
966: (match_operand:HI 2 "general_operand" "g")))]
967: ""
968: "
969: {
970: rtx op1 = operands[1];
971:
972: if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT)
973: {
974: operands[1] = operands[2];
975: operands[2] = op1;
976: op1 = operands[1];
977: }
978:
979: if (GET_CODE (op1) == CONST_INT)
980: operands[1] = gen_rtx (CONST_INT, VOIDmode, 65535 & ~INTVAL (op1));
981: else
982: operands[1] = expand_unop (HImode, one_cmpl_optab, op1, 0, 1);
983: }")
984:
985: (define_expand "andqi3"
986: [(set (match_operand:QI 0 "general_operand" "=g")
987: (and:QI (not:QI (match_operand:QI 1 "general_operand" "g"))
988: (match_operand:QI 2 "general_operand" "g")))]
989: ""
990: "
991: {
992: rtx op1 = operands[1];
993:
994: if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT)
995: {
996: operands[1] = operands[2];
997: operands[2] = op1;
998: op1 = operands[1];
999: }
1000:
1001: if (GET_CODE (op1) == CONST_INT)
1002: operands[1] = gen_rtx (CONST_INT, VOIDmode, 255 & ~INTVAL (op1));
1003: else
1004: operands[1] = expand_unop (QImode, one_cmpl_optab, op1, 0, 1);
1005: }")
1006:
1007: (define_insn ""
1008: [(set (match_operand:SI 0 "general_operand" "=g,g")
1009: (and:SI (not:SI (match_operand:SI 1 "general_operand" "g,g"))
1010: (match_operand:SI 2 "general_operand" "0,g")))]
1011: ""
1012: "@
1013: bicl2 %1,%0
1014: bicl3 %1,%2,%0")
1015:
1016: (define_insn ""
1017: [(set (match_operand:HI 0 "general_operand" "=g,g")
1018: (and:HI (not:HI (match_operand:HI 1 "general_operand" "g,g"))
1019: (match_operand:HI 2 "general_operand" "0,g")))]
1020: ""
1021: "@
1022: bicw2 %1,%0
1023: bicw3 %1,%2,%0")
1024:
1025: (define_insn ""
1026: [(set (match_operand:QI 0 "general_operand" "=g,g")
1027: (and:QI (not:QI (match_operand:QI 1 "general_operand" "g,g"))
1028: (match_operand:QI 2 "general_operand" "0,g")))]
1029: ""
1030: "@
1031: bicb2 %1,%0
1032: bicb3 %1,%2,%0")
1033:
1034: ;; The following used to be needed because constant propagation can
1035: ;; create them starting from the bic insn patterns above. This is no
1036: ;; longer a problem. However, having these patterns allows optimization
1037: ;; opportunities in combine.c.
1038:
1039: (define_insn ""
1040: [(set (match_operand:SI 0 "general_operand" "=g,g")
1041: (and:SI (match_operand:SI 1 "general_operand" "0,g")
1042: (match_operand:SI 2 "const_int_operand" "n,n")))]
1043: ""
1044: "@
1045: bicl2 %N2,%0
1046: bicl3 %N2,%1,%0")
1047:
1048: (define_insn ""
1049: [(set (match_operand:HI 0 "general_operand" "=g,g")
1050: (and:HI (match_operand:HI 1 "general_operand" "0,g")
1051: (match_operand:HI 2 "const_int_operand" "n,n")))]
1052: ""
1053: "@
1054: bicw2 %H2,%0
1055: bicw3 %H2,%1,%0")
1056:
1057: (define_insn ""
1058: [(set (match_operand:QI 0 "general_operand" "=g,g")
1059: (and:QI (match_operand:QI 1 "general_operand" "0,g")
1060: (match_operand:QI 2 "const_int_operand" "n,n")))]
1061: ""
1062: "@
1063: bicb2 %B2,%0
1064: bicb3 %B2,%1,%0")
1065:
1066: ;;- Bit set instructions.
1067:
1068: (define_insn "iorsi3"
1069: [(set (match_operand:SI 0 "general_operand" "=g,g,g")
1070: (ior:SI (match_operand:SI 1 "general_operand" "0,g,g")
1071: (match_operand:SI 2 "general_operand" "g,0,g")))]
1072: ""
1073: "@
1074: bisl2 %2,%0
1075: bisl2 %1,%0
1076: bisl3 %2,%1,%0")
1077:
1078: (define_insn "iorhi3"
1079: [(set (match_operand:HI 0 "general_operand" "=g,g,g")
1080: (ior:HI (match_operand:HI 1 "general_operand" "0,g,g")
1081: (match_operand:HI 2 "general_operand" "g,0,g")))]
1082: ""
1083: "@
1084: bisw2 %2,%0
1085: bisw2 %1,%0
1086: bisw3 %2,%1,%0")
1087:
1088: (define_insn "iorqi3"
1089: [(set (match_operand:QI 0 "general_operand" "=g,g,g")
1090: (ior:QI (match_operand:QI 1 "general_operand" "0,g,g")
1091: (match_operand:QI 2 "general_operand" "g,0,g")))]
1092: ""
1093: "@
1094: bisb2 %2,%0
1095: bisb2 %1,%0
1096: bisb3 %2,%1,%0")
1097:
1098: ;;- xor instructions.
1099:
1100: (define_insn "xorsi3"
1101: [(set (match_operand:SI 0 "general_operand" "=g,g,g")
1102: (xor:SI (match_operand:SI 1 "general_operand" "0,g,g")
1103: (match_operand:SI 2 "general_operand" "g,0,g")))]
1104: ""
1105: "@
1106: xorl2 %2,%0
1107: xorl2 %1,%0
1108: xorl3 %2,%1,%0")
1109:
1110: (define_insn "xorhi3"
1111: [(set (match_operand:HI 0 "general_operand" "=g,g,g")
1112: (xor:HI (match_operand:HI 1 "general_operand" "0,g,g")
1113: (match_operand:HI 2 "general_operand" "g,0,g")))]
1114: ""
1115: "@
1116: xorw2 %2,%0
1117: xorw2 %1,%0
1118: xorw3 %2,%1,%0")
1119:
1120: (define_insn "xorqi3"
1121: [(set (match_operand:QI 0 "general_operand" "=g,g,g")
1122: (xor:QI (match_operand:QI 1 "general_operand" "0,g,g")
1123: (match_operand:QI 2 "general_operand" "g,0,g")))]
1124: ""
1125: "@
1126: xorb2 %2,%0
1127: xorb2 %1,%0
1128: xorb3 %2,%1,%0")
1129:
1130: (define_insn "negdf2"
1131: [(set (match_operand:DF 0 "general_operand" "=g")
1132: (neg:DF (match_operand:DF 1 "general_operand" "gF")))]
1133: ""
1134: "mneg%# %1,%0")
1135:
1136: (define_insn "negsf2"
1137: [(set (match_operand:SF 0 "general_operand" "=g")
1138: (neg:SF (match_operand:SF 1 "general_operand" "gF")))]
1139: ""
1140: "mnegf %1,%0")
1141:
1142: (define_insn "negsi2"
1143: [(set (match_operand:SI 0 "general_operand" "=g")
1144: (neg:SI (match_operand:SI 1 "general_operand" "g")))]
1145: ""
1146: "mnegl %1,%0")
1147:
1148: (define_insn "neghi2"
1149: [(set (match_operand:HI 0 "general_operand" "=g")
1150: (neg:HI (match_operand:HI 1 "general_operand" "g")))]
1151: ""
1152: "mnegw %1,%0")
1153:
1154: (define_insn "negqi2"
1155: [(set (match_operand:QI 0 "general_operand" "=g")
1156: (neg:QI (match_operand:QI 1 "general_operand" "g")))]
1157: ""
1158: "mnegb %1,%0")
1159:
1160: (define_insn "one_cmplsi2"
1161: [(set (match_operand:SI 0 "general_operand" "=g")
1162: (not:SI (match_operand:SI 1 "general_operand" "g")))]
1163: ""
1164: "mcoml %1,%0")
1165:
1166: (define_insn "one_cmplhi2"
1167: [(set (match_operand:HI 0 "general_operand" "=g")
1168: (not:HI (match_operand:HI 1 "general_operand" "g")))]
1169: ""
1170: "mcomw %1,%0")
1171:
1172: (define_insn "one_cmplqi2"
1173: [(set (match_operand:QI 0 "general_operand" "=g")
1174: (not:QI (match_operand:QI 1 "general_operand" "g")))]
1175: ""
1176: "mcomb %1,%0")
1177:
1178: ;; Arithmetic right shift on the vax works by negating the shift count,
1179: ;; then emitting a right shift with the shift count negated. This means
1180: ;; that all actual shift counts in the RTL will be positive. This
1181: ;; prevents converting shifts to ZERO_EXTRACTs with negative positions,
1182: ;; which isn't valid.
1183: (define_expand "ashrsi3"
1184: [(set (match_operand:SI 0 "general_operand" "=g")
1185: (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
1186: (match_operand:QI 2 "general_operand" "g")))]
1187: ""
1188: "
1189: {
1190: if (GET_CODE (operands[2]) != CONST_INT)
1191: operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2]));
1192: }")
1193:
1194: (define_insn ""
1195: [(set (match_operand:SI 0 "general_operand" "=g")
1196: (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
1197: (match_operand:QI 2 "const_int_operand" "n")))]
1198: ""
1199: "ashl $%n2,%1,%0")
1200:
1201: (define_insn ""
1202: [(set (match_operand:SI 0 "general_operand" "=g")
1203: (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
1204: (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
1205: ""
1206: "ashl %2,%1,%0")
1207:
1208: (define_insn "ashlsi3"
1209: [(set (match_operand:SI 0 "general_operand" "=g")
1210: (ashift:SI (match_operand:SI 1 "general_operand" "g")
1211: (match_operand:QI 2 "general_operand" "g")))]
1212: ""
1213: "*
1214: {
1215: if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
1216: return \"addl2 %0,%0\";
1217: if (GET_CODE (operands[1]) == REG
1218: && GET_CODE (operands[2]) == CONST_INT)
1219: {
1220: int i = INTVAL (operands[2]);
1221: if (i == 1)
1222: return \"addl3 %1,%1,%0\";
1223: if (i == 2)
1224: return \"moval 0[%1],%0\";
1225: if (i == 3)
1226: return \"movad 0[%1],%0\";
1227: }
1228: return \"ashl %2,%1,%0\";
1229: }")
1230:
1231: ;; Arithmetic right shift on the vax works by negating the shift count.
1232: (define_expand "ashrdi3"
1233: [(set (match_operand:DI 0 "general_operand" "=g")
1234: (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
1235: (match_operand:QI 2 "general_operand" "g")))]
1236: ""
1237: "
1238: {
1239: operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2]));
1240: }")
1241:
1242: (define_insn "ashldi3"
1243: [(set (match_operand:DI 0 "general_operand" "=g")
1244: (ashift:DI (match_operand:DI 1 "general_operand" "g")
1245: (match_operand:QI 2 "general_operand" "g")))]
1246: ""
1247: "ashq %2,%1,%0")
1248:
1249: (define_insn ""
1250: [(set (match_operand:DI 0 "general_operand" "=g")
1251: (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
1252: (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
1253: ""
1254: "ashq %2,%1,%0")
1255:
1256: ;; Rotate right on the vax works by negating the shift count.
1257: (define_expand "rotrsi3"
1258: [(set (match_operand:SI 0 "general_operand" "=g")
1259: (rotatert:SI (match_operand:SI 1 "general_operand" "g")
1260: (match_operand:QI 2 "general_operand" "g")))]
1261: ""
1262: "
1263: {
1264: if (GET_CODE (operands[2]) != CONST_INT)
1265: operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2]));
1266: }")
1267:
1268: (define_insn "rotlsi3"
1269: [(set (match_operand:SI 0 "general_operand" "=g")
1270: (rotate:SI (match_operand:SI 1 "general_operand" "g")
1271: (match_operand:QI 2 "general_operand" "g")))]
1272: ""
1273: "rotl %2,%1,%0")
1274:
1275: (define_insn ""
1276: [(set (match_operand:SI 0 "general_operand" "=g")
1277: (rotatert:SI (match_operand:SI 1 "general_operand" "g")
1278: (match_operand:QI 2 "const_int_operand" "n")))]
1279: ""
1280: "rotl $%R2,%1,%0")
1281:
1282: (define_insn ""
1283: [(set (match_operand:SI 0 "general_operand" "=g")
1284: (rotatert:SI (match_operand:SI 1 "general_operand" "g")
1285: (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
1286: ""
1287: "rotl %2,%1,%0")
1288:
1289: ;This insn is probably slower than a multiply and an add.
1290: ;(define_insn ""
1291: ; [(set (match_operand:SI 0 "general_operand" "=g")
1292: ; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
1293: ; (match_operand:SI 2 "general_operand" "g"))
1294: ; (match_operand:SI 3 "general_operand" "g")))]
1295: ; ""
1296: ; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
1297:
1298: ;; Special cases of bit-field insns which we should
1299: ;; recognize in preference to the general case.
1300: ;; These handle aligned 8-bit and 16-bit fields,
1301: ;; which can usually be done with move instructions.
1302:
1303: (define_insn ""
1304: [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+ro")
1305: (match_operand:QI 1 "const_int_operand" "n")
1306: (match_operand:SI 2 "const_int_operand" "n"))
1307: (match_operand:SI 3 "general_operand" "g"))]
1308: "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
1309: && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
1310: && (GET_CODE (operands[0]) == REG
1311: || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
1312: "*
1313: {
1314: if (REG_P (operands[0]))
1315: {
1316: if (INTVAL (operands[2]) != 0)
1317: return \"insv %3,%2,%1,%0\";
1318: }
1319: else
1320: operands[0]
1321: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
1322:
1323: if (INTVAL (operands[1]) == 8)
1324: return \"movb %3,%0\";
1325: return \"movw %3,%0\";
1326: }")
1327:
1328: (define_insn ""
1329: [(set (match_operand:SI 0 "general_operand" "=&g")
1330: (zero_extract:SI (match_operand:SI 1 "general_operand" "ro")
1331: (match_operand:QI 2 "const_int_operand" "n")
1332: (match_operand:SI 3 "const_int_operand" "n")))]
1333: "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
1334: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
1335: && (GET_CODE (operands[1]) == REG
1336: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
1337: "*
1338: {
1339: if (REG_P (operands[1]))
1340: {
1341: if (INTVAL (operands[3]) != 0)
1342: return \"extzv %3,%2,%1,%0\";
1343: }
1344: else
1345: operands[1]
1346: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
1347:
1348: if (INTVAL (operands[2]) == 8)
1349: return \"movzbl %1,%0\";
1350: return \"movzwl %1,%0\";
1351: }")
1352:
1353: (define_insn ""
1354: [(set (match_operand:SI 0 "general_operand" "=g")
1355: (sign_extract:SI (match_operand:SI 1 "general_operand" "ro")
1356: (match_operand:QI 2 "const_int_operand" "n")
1357: (match_operand:SI 3 "const_int_operand" "n")))]
1358: "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
1359: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
1360: && (GET_CODE (operands[1]) == REG
1361: || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
1362: "*
1363: {
1364: if (REG_P (operands[1]))
1365: {
1366: if (INTVAL (operands[3]) != 0)
1367: return \"extv %3,%2,%1,%0\";
1368: }
1369: else
1370: operands[1]
1371: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
1372:
1373: if (INTVAL (operands[2]) == 8)
1374: return \"cvtbl %1,%0\";
1375: return \"cvtwl %1,%0\";
1376: }")
1377:
1378: ;; Register-only SImode cases of bit-field insns.
1379:
1380: (define_insn ""
1381: [(set (cc0)
1382: (compare
1383: (sign_extract:SI (match_operand:SI 0 "nonmemory_operand" "r")
1384: (match_operand:QI 1 "general_operand" "g")
1385: (match_operand:SI 2 "general_operand" "g"))
1386: (match_operand:SI 3 "general_operand" "g")))]
1387: ""
1388: "cmpv %2,%1,%0,%3")
1389:
1390: (define_insn ""
1391: [(set (cc0)
1392: (compare
1393: (zero_extract:SI (match_operand:SI 0 "nonmemory_operand" "r")
1394: (match_operand:QI 1 "general_operand" "g")
1395: (match_operand:SI 2 "general_operand" "g"))
1396: (match_operand:SI 3 "general_operand" "g")))]
1397: ""
1398: "cmpzv %2,%1,%0,%3")
1399:
1400: ;; When the field position and size are constant and the destination
1401: ;; is a register, extv and extzv are much slower than a rotate followed
1402: ;; by a bicl or sign extension.
1403:
1404: (define_insn ""
1405: [(set (match_operand:SI 0 "general_operand" "=g")
1406: (sign_extract:SI (match_operand:SI 1 "nonmemory_operand" "r")
1407: (match_operand:QI 2 "general_operand" "g")
1408: (match_operand:SI 3 "general_operand" "g")))]
1409: ""
1410: "*
1411: {
1412: if (GET_CODE (operands[3]) != CONST_INT || GET_CODE (operands[2]) != CONST_INT
1413: || GET_CODE (operands[0]) != REG
1414: || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16))
1415: return \"extv %3,%2,%1,%0\";
1416: if (INTVAL (operands[2]) == 8)
1417: return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
1418: return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
1419: }")
1420:
1421: (define_insn ""
1422: [(set (match_operand:SI 0 "general_operand" "=g")
1423: (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "r")
1424: (match_operand:QI 2 "general_operand" "g")
1425: (match_operand:SI 3 "general_operand" "g")))]
1426: ""
1427: "*
1428: {
1429: if (GET_CODE (operands[3]) != CONST_INT || GET_CODE (operands[2]) != CONST_INT
1430: || GET_CODE (operands[0]) != REG)
1431: return \"extzv %3,%2,%1,%0\";
1432: if (INTVAL (operands[2]) == 8)
1433: return \"rotl %R3,%1,%0\;movzbl %0,%0\";
1434: if (INTVAL (operands[2]) == 16)
1435: return \"rotl %R3,%1,%0\;movzwl %0,%0\";
1436: if (INTVAL (operands[3]) & 31)
1437: return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
1438: if (rtx_equal_p (operands[0], operands[1]))
1439: return \"bicl2 %M2,%0\";
1440: return \"bicl3 %M2,%1,%0\";
1441: }")
1442:
1443: ;; Non-register cases.
1444: ;; nonimmediate_operand is used to make sure that mode-ambiguous cases
1445: ;; don't match these (and therefore match the cases above instead).
1446:
1447: (define_insn ""
1448: [(set (cc0)
1449: (compare
1450: (sign_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
1451: (match_operand:QI 1 "general_operand" "g")
1452: (match_operand:SI 2 "general_operand" "g"))
1453: (match_operand:SI 3 "general_operand" "g")))]
1454: ""
1455: "cmpv %2,%1,%0,%3")
1456:
1457: (define_insn ""
1458: [(set (cc0)
1459: (compare
1460: (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
1461: (match_operand:QI 1 "general_operand" "g")
1462: (match_operand:SI 2 "general_operand" "g"))
1463: (match_operand:SI 3 "general_operand" "g")))]
1464: ""
1465: "cmpzv %2,%1,%0,%3")
1466:
1467: (define_insn "extv"
1468: [(set (match_operand:SI 0 "general_operand" "=g")
1469: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "rm")
1470: (match_operand:QI 2 "general_operand" "g")
1471: (match_operand:SI 3 "general_operand" "g")))]
1472: ""
1473: "*
1474: {
1475: if (GET_CODE (operands[0]) != REG || GET_CODE (operands[2]) != CONST_INT
1476: || GET_CODE (operands[3]) != CONST_INT
1477: || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
1478: || side_effects_p (operands[1])
1479: || (GET_CODE (operands[1]) == MEM
1480: && mode_dependent_address_p (XEXP (operands[1], 0))))
1481: return \"extv %3,%2,%1,%0\";
1482: if (INTVAL (operands[2]) == 8)
1483: return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
1484: return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
1485: }")
1486:
1487: (define_insn "extzv"
1488: [(set (match_operand:SI 0 "general_operand" "=g")
1489: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "rm")
1490: (match_operand:QI 2 "general_operand" "g")
1491: (match_operand:SI 3 "general_operand" "g")))]
1492: ""
1493: "*
1494: {
1495: if (GET_CODE (operands[0]) != REG || GET_CODE (operands[2]) != CONST_INT
1496: || GET_CODE (operands[3]) != CONST_INT
1497: || side_effects_p (operands[1])
1498: || (GET_CODE (operands[1]) == MEM
1499: && mode_dependent_address_p (XEXP (operands[1], 0))))
1500: return \"extzv %3,%2,%1,%0\";
1501: if (INTVAL (operands[2]) == 8)
1502: return \"rotl %R3,%1,%0\;movzbl %0,%0\";
1503: if (INTVAL (operands[2]) == 16)
1504: return \"rotl %R3,%1,%0\;movzwl %0,%0\";
1505: return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
1506: }")
1507:
1508: (define_insn "insv"
1509: [(set (zero_extract:SI (match_operand:QI 0 "general_operand" "+g")
1510: (match_operand:QI 1 "general_operand" "g")
1511: (match_operand:SI 2 "general_operand" "g"))
1512: (match_operand:SI 3 "general_operand" "g"))]
1513: ""
1514: "insv %3,%2,%1,%0")
1515:
1516: (define_insn ""
1517: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1518: (match_operand:QI 1 "general_operand" "g")
1519: (match_operand:SI 2 "general_operand" "g"))
1520: (match_operand:SI 3 "general_operand" "g"))]
1521: ""
1522: "insv %3,%2,%1,%0")
1523:
1524: (define_insn "jump"
1525: [(set (pc)
1526: (label_ref (match_operand 0 "" "")))]
1527: ""
1528: "jbr %l0")
1529:
1530: (define_insn "beq"
1531: [(set (pc)
1532: (if_then_else (eq (cc0)
1533: (const_int 0))
1534: (label_ref (match_operand 0 "" ""))
1535: (pc)))]
1536: ""
1537: "jeql %l0")
1538:
1539: (define_insn "bne"
1540: [(set (pc)
1541: (if_then_else (ne (cc0)
1542: (const_int 0))
1543: (label_ref (match_operand 0 "" ""))
1544: (pc)))]
1545: ""
1546: "jneq %l0")
1547:
1548: (define_insn "bgt"
1549: [(set (pc)
1550: (if_then_else (gt (cc0)
1551: (const_int 0))
1552: (label_ref (match_operand 0 "" ""))
1553: (pc)))]
1554: ""
1555: "jgtr %l0")
1556:
1557: (define_insn "bgtu"
1558: [(set (pc)
1559: (if_then_else (gtu (cc0)
1560: (const_int 0))
1561: (label_ref (match_operand 0 "" ""))
1562: (pc)))]
1563: ""
1564: "jgtru %l0")
1565:
1566: (define_insn "blt"
1567: [(set (pc)
1568: (if_then_else (lt (cc0)
1569: (const_int 0))
1570: (label_ref (match_operand 0 "" ""))
1571: (pc)))]
1572: ""
1573: "jlss %l0")
1574:
1575: (define_insn "bltu"
1576: [(set (pc)
1577: (if_then_else (ltu (cc0)
1578: (const_int 0))
1579: (label_ref (match_operand 0 "" ""))
1580: (pc)))]
1581: ""
1582: "jlssu %l0")
1583:
1584: (define_insn "bge"
1585: [(set (pc)
1586: (if_then_else (ge (cc0)
1587: (const_int 0))
1588: (label_ref (match_operand 0 "" ""))
1589: (pc)))]
1590: ""
1591: "jgeq %l0")
1592:
1593: (define_insn "bgeu"
1594: [(set (pc)
1595: (if_then_else (geu (cc0)
1596: (const_int 0))
1597: (label_ref (match_operand 0 "" ""))
1598: (pc)))]
1599: ""
1600: "jgequ %l0")
1601:
1602: (define_insn "ble"
1603: [(set (pc)
1604: (if_then_else (le (cc0)
1605: (const_int 0))
1606: (label_ref (match_operand 0 "" ""))
1607: (pc)))]
1608: ""
1609: "jleq %l0")
1610:
1611: (define_insn "bleu"
1612: [(set (pc)
1613: (if_then_else (leu (cc0)
1614: (const_int 0))
1615: (label_ref (match_operand 0 "" ""))
1616: (pc)))]
1617: ""
1618: "jlequ %l0")
1619:
1620: ;; Recognize reversed jumps.
1621: (define_insn ""
1622: [(set (pc)
1623: (if_then_else (match_operator 0 "comparison_operator"
1624: [(cc0)
1625: (const_int 0)])
1626: (pc)
1627: (label_ref (match_operand 1 "" ""))))]
1628: ""
1629: "j%C0 %l1") ; %C0 negates condition
1630:
1631: ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand
1632: ;; of jlbs and jlbc insns are SImode in the hardware. However, if it is
1633: ;; memory, we use QImode in the insn. So we can't use those instructions
1634: ;; for mode-dependent addresses.
1635:
1636: (define_insn ""
1637: [(set (pc)
1638: (if_then_else
1639: (ne (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rQ,g")
1640: (const_int 1)
1641: (match_operand:SI 1 "general_operand" "I,g"))
1642: (const_int 0))
1643: (label_ref (match_operand 2 "" ""))
1644: (pc)))]
1645: ""
1646: "@
1647: jlbs %0,%l2
1648: jbs %1,%0,%l2")
1649:
1650: (define_insn ""
1651: [(set (pc)
1652: (if_then_else
1653: (eq (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rQ,g")
1654: (const_int 1)
1655: (match_operand:SI 1 "general_operand" "I,g"))
1656: (const_int 0))
1657: (label_ref (match_operand 2 "" ""))
1658: (pc)))]
1659: ""
1660: "@
1661: jlbc %0,%l2
1662: jbc %1,%0,%l2")
1663:
1664: (define_insn ""
1665: [(set (pc)
1666: (if_then_else
1667: (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1668: (const_int 1)
1669: (match_operand:SI 1 "general_operand" "I,g"))
1670: (const_int 0))
1671: (label_ref (match_operand 2 "" ""))
1672: (pc)))]
1673: ""
1674: "@
1675: jlbs %0,%l2
1676: jbs %1,%0,%l2")
1677:
1678: (define_insn ""
1679: [(set (pc)
1680: (if_then_else
1681: (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1682: (const_int 1)
1683: (match_operand:SI 1 "general_operand" "I,g"))
1684: (const_int 0))
1685: (label_ref (match_operand 2 "" ""))
1686: (pc)))]
1687: ""
1688: "@
1689: jlbc %0,%l2
1690: jbc %1,%0,%l2")
1691:
1692: ;; Subtract-and-jump and Add-and-jump insns.
1693: ;; These are not used when output is for the Unix assembler
1694: ;; because it does not know how to modify them to reach far.
1695:
1696: ;; Normal sob insns.
1697:
1698: (define_insn ""
1699: [(set (pc)
1700: (if_then_else
1701: (gt (plus:SI (match_operand:SI 0 "general_operand" "+g")
1702: (const_int -1))
1703: (const_int 0))
1704: (label_ref (match_operand 1 "" ""))
1705: (pc)))
1706: (set (match_dup 0)
1707: (plus:SI (match_dup 0)
1708: (const_int -1)))]
1709: "!TARGET_UNIX_ASM"
1710: "jsobgtr %0,%l1")
1711:
1712: (define_insn ""
1713: [(set (pc)
1714: (if_then_else
1715: (ge (plus:SI (match_operand:SI 0 "general_operand" "+g")
1716: (const_int -1))
1717: (const_int 0))
1718: (label_ref (match_operand 1 "" ""))
1719: (pc)))
1720: (set (match_dup 0)
1721: (plus:SI (match_dup 0)
1722: (const_int -1)))]
1723: "!TARGET_UNIX_ASM"
1724: "jsobgeq %0,%l1")
1725:
1726: ;; Normal aob insns. Define a version for when operands[1] is a constant.
1727: (define_insn ""
1728: [(set (pc)
1729: (if_then_else
1730: (lt (plus:SI (match_operand:SI 0 "general_operand" "+g")
1731: (const_int 1))
1732: (match_operand:SI 1 "general_operand" "g"))
1733: (label_ref (match_operand 2 "" ""))
1734: (pc)))
1735: (set (match_dup 0)
1736: (plus:SI (match_dup 0)
1737: (const_int 1)))]
1738: "!TARGET_UNIX_ASM"
1739: "jaoblss %1,%0,%l2")
1740:
1741: (define_insn ""
1742: [(set (pc)
1743: (if_then_else
1744: (lt (match_operand:SI 0 "general_operand" "+g")
1745: (match_operand:SI 1 "general_operand" "g"))
1746: (label_ref (match_operand 2 "" ""))
1747: (pc)))
1748: (set (match_dup 0)
1749: (plus:SI (match_dup 0)
1750: (const_int 1)))]
1751: "!TARGET_UNIX_ASM && GET_CODE (operands[1]) == CONST_INT"
1752: "jaoblss %P1,%0,%l2")
1753:
1754: (define_insn ""
1755: [(set (pc)
1756: (if_then_else
1757: (le (plus:SI (match_operand:SI 0 "general_operand" "+g")
1758: (const_int 1))
1759: (match_operand:SI 1 "general_operand" "g"))
1760: (label_ref (match_operand 2 "" ""))
1761: (pc)))
1762: (set (match_dup 0)
1763: (plus:SI (match_dup 0)
1764: (const_int 1)))]
1765: "!TARGET_UNIX_ASM"
1766: "jaobleq %1,%0,%l2")
1767:
1768: (define_insn ""
1769: [(set (pc)
1770: (if_then_else
1771: (le (match_operand:SI 0 "general_operand" "+g")
1772: (match_operand:SI 1 "general_operand" "g"))
1773: (label_ref (match_operand 2 "" ""))
1774: (pc)))
1775: (set (match_dup 0)
1776: (plus:SI (match_dup 0)
1777: (const_int 1)))]
1778: "!TARGET_UNIX_ASM && GET_CODE (operands[1]) == CONST_INT"
1779: "jaobleq %P1,%0,%l2")
1780:
1781: ;; Something like a sob insn, but compares against -1.
1782: ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
1783:
1784: (define_insn ""
1785: [(set (pc)
1786: (if_then_else
1787: (ne (match_operand:SI 0 "general_operand" "g")
1788: (const_int 0))
1789: (label_ref (match_operand 1 "" ""))
1790: (pc)))
1791: (set (match_dup 0)
1792: (plus:SI (match_dup 0)
1793: (const_int -1)))]
1794: ""
1795: "decl %0\;jgequ %l1")
1796:
1797: ;; Note that operand 1 is total size of args, in bytes,
1798: ;; and what the call insn wants is the number of words.
1799: (define_insn "call_pop"
1800: [(call (match_operand:QI 0 "memory_operand" "m")
1801: (match_operand:QI 1 "general_operand" "g"))
1802: (set (reg:SI 14) (plus:SI (reg:SI 14)
1803: (match_operand:SI 3 "immediate_operand" "i")))]
1804: ""
1805: "*
1806: if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 255 * 4)
1807: /* Vax `calls' really uses only one byte of #args, so pop explicitly. */
1808: return \"calls $0,%0\;addl2 %1,sp\";
1809: operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4);
1810: return \"calls %1,%0\";
1811: ")
1812:
1813: (define_insn "call_value_pop"
1814: [(set (match_operand 0 "" "=g")
1815: (call (match_operand:QI 1 "memory_operand" "m")
1816: (match_operand:QI 2 "general_operand" "g")))
1817: (set (reg:SI 14) (plus:SI (reg:SI 14)
1818: (match_operand:SI 4 "immediate_operand" "i")))]
1819: ""
1820: "*
1821: if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 255 * 4)
1822: /* Vax `calls' really uses only one byte of #args, so pop explicitly. */
1823: return \"calls $0,%1\;addl2 %2,sp\";
1824: operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4);
1825: return \"calls %2,%1\";
1826: ")
1827:
1828: ;; Define another set of these for the case of functions with no
1829: ;; operands. In that case, combine may simplify the adjustment of sp.
1830: (define_insn ""
1831: [(call (match_operand:QI 0 "memory_operand" "m")
1832: (match_operand:QI 1 "general_operand" "g"))
1833: (set (reg:SI 14) (reg:SI 14))]
1834: ""
1835: "*
1836: if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 255 * 4)
1837: /* Vax `calls' really uses only one byte of #args, so pop explicitly. */
1838: return \"calls $0,%0\;addl2 %1,sp\";
1839: operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4);
1840: return \"calls %1,%0\";
1841: ")
1842:
1843: (define_insn ""
1844: [(set (match_operand 0 "" "=g")
1845: (call (match_operand:QI 1 "memory_operand" "m")
1846: (match_operand:QI 2 "general_operand" "g")))
1847: (set (reg:SI 14) (reg:SI 14))]
1848: ""
1849: "*
1850: if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 255 * 4)
1851: /* Vax `calls' really uses only one byte of #args, so pop explicitly. */
1852: return \"calls $0,%1\;addl2 %2,sp\";
1853: operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4);
1854: return \"calls %2,%1\";
1855: ")
1856:
1857: ;; Call subroutine returning any type.
1858:
1859: (define_expand "untyped_call"
1860: [(parallel [(call (match_operand 0 "" "")
1861: (const_int 0))
1862: (match_operand 1 "" "")
1863: (match_operand 2 "" "")])]
1864: ""
1865: "
1866: {
1867: int i;
1868:
1869: emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx));
1870:
1871: for (i = 0; i < XVECLEN (operands[2], 0); i++)
1872: {
1873: rtx set = XVECEXP (operands[2], 0, i);
1874: emit_move_insn (SET_DEST (set), SET_SRC (set));
1875: }
1876:
1877: /* The optimizer does not know that the call sets the function value
1878: registers we stored in the result block. We avoid problems by
1879: claiming that all hard registers are used and clobbered at this
1880: point. */
1881: emit_insn (gen_blockage ());
1882:
1883: DONE;
1884: }")
1885:
1886: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1887: ;; all of memory. This blocks insns from being moved across this point.
1888:
1889: (define_insn "blockage"
1890: [(unspec_volatile [(const_int 0)] 0)]
1891: ""
1892: "")
1893:
1894: (define_insn "return"
1895: [(return)]
1896: ""
1897: "ret")
1898:
1899: (define_insn "nop"
1900: [(const_int 0)]
1901: ""
1902: "nop")
1903:
1904: ;; This had a wider constraint once, and it had trouble.
1905: ;; If you are tempted to try `g', please don't--it's not worth
1906: ;; the risk we will reopen the same bug.
1907: (define_insn "indirect_jump"
1908: [(set (pc) (match_operand:SI 0 "general_operand" "r"))]
1909: ""
1910: "jmp (%0)")
1911:
1912: ;; This is here to accept 5 arguments (as passed by expand_end_case)
1913: ;; and pass the first 4 along to the casesi1 pattern that really does the work.
1914: (define_expand "casesi"
1915: [(set (pc)
1916: (if_then_else (leu (minus:SI (match_operand:SI 0 "general_operand" "g")
1917: (match_operand:SI 1 "general_operand" "g"))
1918: (match_operand:SI 2 "general_operand" "g"))
1919: (plus:SI (sign_extend:SI
1920: (mem:HI
1921: (plus:SI (pc)
1922: (mult:SI (minus:SI (match_dup 0)
1923: (match_dup 1))
1924: (const_int 2)))))
1925: (label_ref:SI (match_operand 3 "" "")))
1926: (pc)))
1927: (match_operand 4 "" "")]
1928: ""
1929: "
1930: emit_insn (gen_casesi1 (operands[0], operands[1], operands[2], operands[3]));
1931: DONE;
1932: ")
1933:
1934: (define_insn "casesi1"
1935: [(set (pc)
1936: (if_then_else (leu (minus:SI (match_operand:SI 0 "general_operand" "g")
1937: (match_operand:SI 1 "general_operand" "g"))
1938: (match_operand:SI 2 "general_operand" "g"))
1939: (plus:SI (sign_extend:SI
1940: (mem:HI
1941: (plus:SI (pc)
1942: (mult:SI (minus:SI (match_dup 0)
1943: (match_dup 1))
1944: (const_int 2)))))
1945: (label_ref:SI (match_operand 3 "" "")))
1946: (pc)))]
1947: ""
1948: "casel %0,%1,%2")
1949:
1950: ;; This used to arise from the preceding by simplification
1951: ;; if operand 1 is zero. Perhaps it is no longer necessary.
1952: (define_insn ""
1953: [(set (pc)
1954: (if_then_else (leu (match_operand:SI 0 "general_operand" "g")
1955: (match_operand:SI 1 "general_operand" "g"))
1956: (plus:SI (sign_extend:SI
1957: (mem:HI
1958: (plus:SI (pc)
1959: (mult:SI (minus:SI (match_dup 0)
1960: (const_int 0))
1961: (const_int 2)))))
1962: (label_ref:SI (match_operand 3 "" "")))
1963: (pc)))]
1964: ""
1965: "casel %0,$0,%1")
1966:
1967: ;;- load or push effective address
1968: ;; These come after the move and add/sub patterns
1969: ;; because we don't want pushl $1 turned into pushad 1.
1970: ;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3.
1971:
1972: ;; It does not work to use constraints to distinguish pushes from moves,
1973: ;; because < matches any autodecrement, not just a push.
1974:
1975: (define_insn ""
1976: [(set (match_operand:SI 0 "general_operand" "=g")
1977: (match_operand:QI 1 "address_operand" "p"))]
1978: ""
1979: "*
1980: {
1981: if (push_operand (operands[0], SImode))
1982: return \"pushab %a1\";
1983: else
1984: return \"movab %a1,%0\";
1985: }")
1986:
1987: (define_insn ""
1988: [(set (match_operand:SI 0 "general_operand" "=g")
1989: (match_operand:HI 1 "address_operand" "p"))]
1990: ""
1991: "*
1992: {
1993: if (push_operand (operands[0], SImode))
1994: return \"pushaw %a1\";
1995: else
1996: return \"movaw %a1,%0\";
1997: }")
1998:
1999: (define_insn ""
2000: [(set (match_operand:SI 0 "general_operand" "=g")
2001: (match_operand:SI 1 "address_operand" "p"))]
2002: ""
2003: "*
2004: {
2005: if (push_operand (operands[0], SImode))
2006: return \"pushal %a1\";
2007: else
2008: return \"moval %a1,%0\";
2009: }")
2010:
2011: (define_insn ""
2012: [(set (match_operand:SI 0 "general_operand" "=g")
2013: (match_operand:DI 1 "address_operand" "p"))]
2014: ""
2015: "*
2016: {
2017: if (push_operand (operands[0], SImode))
2018: return \"pushaq %a1\";
2019: else
2020: return \"movaq %a1,%0\";
2021: }")
2022:
2023: (define_insn ""
2024: [(set (match_operand:SI 0 "general_operand" "=g")
2025: (match_operand:SF 1 "address_operand" "p"))]
2026: ""
2027: "*
2028: {
2029: if (push_operand (operands[0], SImode))
2030: return \"pushaf %a1\";
2031: else
2032: return \"movaf %a1,%0\";
2033: }")
2034:
2035: (define_insn ""
2036: [(set (match_operand:SI 0 "general_operand" "=g")
2037: (match_operand:DF 1 "address_operand" "p"))]
2038: ""
2039: "*
2040: {
2041: if (push_operand (operands[0], SImode))
2042: return \"pushad %a1\";
2043: else
2044: return \"movad %a1,%0\";
2045: }")
2046:
2047: ;; These used to be peepholes, but it is more straightforward to do them
2048: ;; as single insns. However, we must force the output to be a register
2049: ;; if it is not an offsettable address so that we know that we can assign
2050: ;; to it twice.
2051:
2052: ;; If we had a good way of evaluating the relative costs, these could be
2053: ;; machine-independent.
2054:
2055: ;; Optimize extzv ...,z; andl2 ...,z
2056: ;; or ashl ...,z; andl2 ...,z
2057: ;; with other operands constant. This is what the combiner converts the
2058: ;; above sequences to before attempting to recognize the new insn.
2059:
2060: (define_insn ""
2061: [(set (match_operand:SI 0 "general_operand" "=ro")
2062: (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
2063: (match_operand:QI 2 "const_int_operand" "n"))
2064: (match_operand:SI 3 "const_int_operand" "n")))]
2065: "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
2066: "*
2067: {
2068: unsigned long mask1 = INTVAL (operands[3]);
2069: unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1;
2070:
2071: if ((mask1 & mask2) != mask1)
2072: operands[3] = gen_rtx (CONST_INT, VOIDmode, mask1 & mask2);
2073:
2074: return \"rotl %R2,%1,%0\;bicl2 %N3,%0\";
2075: }")
2076:
2077: ;; left-shift and mask
2078: ;; The only case where `ashl' is better is if the mask only turns off
2079: ;; bits that the ashl would anyways, in which case it should have been
2080: ;; optimized away.
2081:
2082: (define_insn ""
2083: [(set (match_operand:SI 0 "general_operand" "=ro")
2084: (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "g")
2085: (match_operand:QI 2 "const_int_operand" "n"))
2086: (match_operand:SI 3 "const_int_operand" "n")))]
2087: ""
2088: "*
2089: {
2090: operands[3] = gen_rtx (CONST_INT, VOIDmode,
2091: INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1));
2092: return \"rotl %2,%1,%0\;bicl2 %N3,%0\";
2093: }")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.