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