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