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