|
|
1.1 root 1: ;;- Machine description for Intel 860 chip for GNU C compiler
2: ;; Copyright (C) 1989, 1990 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: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22:
23: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
24: ;;- updates for most instructions.
25:
26: ;;- Operand classes for the register allocator:
27:
28: /* Bit-test instructions. */
29:
30: (define_insn ""
31: [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
32: (match_operand:SI 1 "logic_operand" "rL"))
33: (const_int 0)))]
34: ""
35: "*
36: {
37: CC_STATUS_PARTIAL_INIT;
38: return \"and %1,%0,%?r0\";
39: }")
40:
41: (define_insn ""
42: [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
43: (match_operand:SI 1 "logic_operand" "rL"))
44: (const_int 0)))]
45: ""
46: "*
47: {
48: CC_STATUS_PARTIAL_INIT;
49: cc_status.flags |= CC_NEGATED;
50: return \"and %1,%0,%?r0\";
51: }")
52:
53: (define_insn ""
54: [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
55: (match_operand:SI 1 "immediate_operand" "i"))
56: (const_int 0)))]
57: "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
58: "*
59: {
60: CC_STATUS_PARTIAL_INIT;
61: return \"andh %H1,%0,%?r0\";
62: }")
63:
64: (define_insn ""
65: [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
66: (match_operand:SI 1 "immediate_operand" "i"))
67: (const_int 0)))]
68: "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
69: "*
70: {
71: CC_STATUS_PARTIAL_INIT;
72: cc_status.flags |= CC_NEGATED;
73: return \"andh %H1,%0,%?r0\";
74: }")
75:
76: (define_insn ""
77: [(set (cc0) (eq (ashiftrt:SI
78: (sign_extend:SI
79: (ashift:QI (match_operand:QI 0 "register_operand" "r")
80: (match_operand:QI 1 "logic_int" "n")))
81: (match_operand:SI 2 "logic_int" "n"))
82: (const_int 0)))]
83: ""
84: "*
85: {
86: int width = 8 - INTVAL (operands[2]);
87: int pos = 8 - width - INTVAL (operands[1]);
88:
89: CC_STATUS_PARTIAL_INIT;
90: operands[2] = gen_rtx (CONST_INT, VOIDmode,
91: ~((-1) << width) << pos);
92: return \"and %2,%0,%?r0\";
93: }")
94:
95: ;; -------------------------------------------------------------------------
96: ;; SImode signed integer comparisons
97: ;; -------------------------------------------------------------------------
98:
99: (define_insn "cmpeqsi"
100: [(set (cc0) (eq (match_operand:SI 0 "logic_operand" "r,rL")
101: (match_operand:SI 1 "logic_operand" "L,r")))]
102: ""
103: "*
104: {
105: CC_STATUS_PARTIAL_INIT;
106: if (REG_P (operands[0]))
107: return \"xor %1,%0,%?r0\";
108: else
109: return \"xor %0,%1,%?r0\";
110: }")
111:
112: (define_insn "cmpnesi"
113: [(set (cc0) (ne (match_operand:SI 0 "logic_operand" "r,rL")
114: (match_operand:SI 1 "logic_operand" "L,r")))]
115: ""
116: "*
117: {
118: CC_STATUS_PARTIAL_INIT;
119: cc_status.flags |= CC_NEGATED;
120: if (REG_P (operands[0]))
121: return \"xor %1,%0,%?r0\";
122: else
123: return \"xor %0,%1,%?r0\";
124: }")
125:
126: (define_insn "cmpltsi"
127: [(set (cc0) (lt (match_operand:SI 0 "arith_operand" "r,rI")
128: (match_operand:SI 1 "arith_operand" "I,r")))]
129: ""
130: "*
131: {
132: CC_STATUS_PARTIAL_INIT;
133: if (REG_P (operands[1]))
134: return \"subs %0,%1,%?r0\";
135: else
136: {
137: cc_status.flags |= CC_REVERSED;
138: operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]));
139: return \"adds %1,%0,%?r0\";
140: }
141: }")
142:
143: (define_insn "cmpgtsi"
144: [(set (cc0) (gt (match_operand:SI 0 "arith_operand" "r,rI")
145: (match_operand:SI 1 "arith_operand" "I,r")))]
146: ""
147: "*
148: {
149: CC_STATUS_PARTIAL_INIT;
150: if (REG_P (operands[0]))
151: return \"subs %1,%0,%?r0\";
152: else
153: {
154: cc_status.flags |= CC_REVERSED;
155: operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0]));
156: return \"adds %0,%1,%?r0\";
157: }
158: }")
159:
160: (define_insn "cmplesi"
161: [(set (cc0) (le (match_operand:SI 0 "arith_operand" "r,rI")
162: (match_operand:SI 1 "arith_operand" "I,r")))]
163: ""
164: "*
165: {
166: CC_STATUS_PARTIAL_INIT;
167: cc_status.flags |= CC_NEGATED;
168: if (REG_P (operands[0]))
169: return \"subs %1,%0,%?r0\";
170: else
171: {
172: cc_status.flags |= CC_REVERSED;
173: operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0]));
174: return \"adds %0,%1,%?r0\";
175: }
176: }")
177:
178: (define_insn "cmpgesi"
179: [(set (cc0) (ge (match_operand:SI 0 "arith_operand" "r,rI")
180: (match_operand:SI 1 "arith_operand" "I,r")))]
181: ""
182: "*
183: {
184: CC_STATUS_PARTIAL_INIT;
185: cc_status.flags |= CC_NEGATED;
186: if (REG_P (operands[1]))
187: return \"subs %0,%1,%?r0\";
188: else
189: {
190: cc_status.flags |= CC_REVERSED;
191: operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]));
192: return \"adds %1,%0,%?r0\";
193: }
194: }")
195:
196: ;; -------------------------------------------------------------------------
197: ;; SImode unsigned integer comparisons
198: ;; -------------------------------------------------------------------------
199:
200: ;; WARNING! There is a small i860 hardware limitation (bug?) which we
201: ;; may run up against (if we are not careful) when we are trying to do
202: ;; unsigned comparisons like (x >= 0), (x < 0), (0 <= x), and (0 > x).
203: ;; Specifically, we must avoid using an `addu' instruction to perform
204: ;; such comparisons because the result (in the CC bit register) will
205: ;; come out wrong. (This fact is documented in a footnote on page 7-10
206: ;; of the 1991 version of the i860 Microprocessor Family Programmer's
207: ;; Reference Manual). Note that unsigned comparisons of this sort are
208: ;; always redundant anyway, because an unsigned quantity can never be
209: ;; less than zero. When we see cases like this, we generate an
210: ;; `or K,%r0,%r0' instruction instead (where K is a constant 0 or -1)
211: ;; so as to get the CC bit register set properly for any subsequent
212: ;; conditional jump instruction.
213:
214: (define_insn "cmpgeusi"
215: [(set (cc0) (geu (match_operand:SI 0 "arith_operand" "r,rI")
216: (match_operand:SI 1 "arith_operand" "I,r")))]
217: ""
218: "*
219: {
220: CC_STATUS_PARTIAL_INIT;
221: if (REG_P (operands[1]))
222: return \"subu %0,%1,%?r0\";
223: else
224: {
225: if (INTVAL (operands[1]) == 0)
226: return \"or 0,%?r0,%?r0\";
227: else
228: {
229: cc_status.flags |= CC_REVERSED;
230: operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]));
231: return \"addu %1,%0,%?r0\";
232: }
233: }
234: }")
235:
236: (define_insn "cmpleusi"
237: [(set (cc0) (leu (match_operand:SI 0 "arith_operand" "r,rI")
238: (match_operand:SI 1 "arith_operand" "I,r")))]
239: ""
240: "*
241: {
242: CC_STATUS_PARTIAL_INIT;
243: if (REG_P (operands[0]))
244: return \"subu %1,%0,%?r0\";
245: else
246: {
247: if (INTVAL (operands[0]) == 0)
248: return \"or 0,%?r0,%?r0\";
249: else
250: {
251: cc_status.flags |= CC_REVERSED;
252: operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0]));
253: return \"addu %0,%1,%?r0\";
254: }
255: }
256: }")
257:
258: ;; -------------------------------------------------------------------------
259: ;; SFmode floating-point comparisons
260: ;; -------------------------------------------------------------------------
261:
262: (define_insn "cmpeqsf"
263: [(set (cc0) (eq (match_operand:SF 0 "reg_or_0_operand" "fG")
264: (match_operand:SF 1 "reg_or_0_operand" "fG")))]
265: ""
266: "*
267: {
268: CC_STATUS_PARTIAL_INIT;
269: return \"pfeq.ss %r0,%r1,%?f0\";
270: }")
271:
272: (define_insn "cmpnesf"
273: [(set (cc0) (ne (match_operand:SF 0 "reg_or_0_operand" "fG")
274: (match_operand:SF 1 "reg_or_0_operand" "fG")))]
275: ""
276: "*
277: {
278: CC_STATUS_PARTIAL_INIT;
279: cc_status.flags |= CC_NEGATED;
280: return \"pfeq.ss %r1,%r0,%?f0\";
281: }")
282:
283: ;; NOTE: The i860 Programmer's Reference Manual says that when we are
284: ;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these
285: ;; in order to be IEEE compliant (in case a trap occurs during these
286: ;; operations). Conversely, for (A <= B) or (A >= B) comparisons, we
287: ;; must use pfle to be IEEE compliant.
288:
289: (define_insn "cmpltsf"
290: [(set (cc0) (lt (match_operand:SF 0 "reg_or_0_operand" "fG")
291: (match_operand:SF 1 "reg_or_0_operand" "fG")))]
292: ""
293: "*
294: {
295: CC_STATUS_PARTIAL_INIT;
296: return \"pfgt.ss %r1,%r0,%?f0\";
297: }")
298:
299: (define_insn "cmpgtsf"
300: [(set (cc0) (gt (match_operand:SF 0 "reg_or_0_operand" "fG")
301: (match_operand:SF 1 "reg_or_0_operand" "fG")))]
302: ""
303: "*
304: {
305: CC_STATUS_PARTIAL_INIT;
306: return \"pfgt.ss %r0,%r1,%?f0\";
307: }")
308:
309: ;; NOTE: The pfle opcode doesn't do what you think it does. It is
310: ;; bass-ackwards. It *clears* the CC flag if the first operand is
311: ;; less than or equal to the second. Thus, we have to set CC_NEGATED
312: ;; for the following two patterns.
313:
314: (define_insn "cmplesf"
315: [(set (cc0) (le (match_operand:SF 0 "reg_or_0_operand" "fG")
316: (match_operand:SF 1 "reg_or_0_operand" "fG")))]
317: ""
318: "*
319: {
320: CC_STATUS_PARTIAL_INIT;
321: cc_status.flags |= CC_NEGATED;
322: return \"pfle.ss %r0,%r1,%?f0\";
323: }")
324:
325: (define_insn "cmpgesf"
326: [(set (cc0) (ge (match_operand:SF 0 "reg_or_0_operand" "fG")
327: (match_operand:SF 1 "reg_or_0_operand" "fG")))]
328: ""
329: "*
330: {
331: CC_STATUS_PARTIAL_INIT;
332: cc_status.flags |= CC_NEGATED;
333: return \"pfle.ss %r1,%r0,%?f0\";
334: }")
335:
336: ;; -------------------------------------------------------------------------
337: ;; DFmode floating-point comparisons
338: ;; -------------------------------------------------------------------------
339:
340: (define_insn "cmpeqdf"
341: [(set (cc0) (eq (match_operand:DF 0 "reg_or_0_operand" "fG")
342: (match_operand:DF 1 "reg_or_0_operand" "fG")))]
343: ""
344: "*
345: {
346: CC_STATUS_PARTIAL_INIT;
347: return \"pfeq.dd %r0,%r1,%?f0\";
348: }")
349:
350: (define_insn "cmpnedf"
351: [(set (cc0) (ne (match_operand:DF 0 "reg_or_0_operand" "fG")
352: (match_operand:DF 1 "reg_or_0_operand" "fG")))]
353: ""
354: "*
355: {
356: CC_STATUS_PARTIAL_INIT;
357: cc_status.flags |= CC_NEGATED;
358: return \"pfeq.dd %r1,%r0,%?f0\";
359: }")
360:
361: ;; NOTE: The i860 Programmer's Reference Manual says that when we are
362: ;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these
363: ;; in order to be IEEE compliant (in case a trap occurs during these
364: ;; operations). Conversely, for (A <= B) or (A >= B) comparisons, we
365: ;; must use pfle to be IEEE compliant.
366:
367: (define_insn "cmpltdf"
368: [(set (cc0) (lt (match_operand:DF 0 "reg_or_0_operand" "fG")
369: (match_operand:DF 1 "reg_or_0_operand" "fG")))]
370: ""
371: "*
372: {
373: CC_STATUS_PARTIAL_INIT;
374: return \"pfgt.dd %r1,%r0,%?f0\";
375: }")
376:
377: (define_insn "cmpgtdf"
378: [(set (cc0) (gt (match_operand:DF 0 "reg_or_0_operand" "fG")
379: (match_operand:DF 1 "reg_or_0_operand" "fG")))]
380: ""
381: "*
382: {
383: CC_STATUS_PARTIAL_INIT;
384: return \"pfgt.dd %r0,%r1,%?f0\";
385: }")
386:
387: ;; NOTE: The pfle opcode doesn't do what you think it does. It is
388: ;; bass-ackwards. It *clears* the CC flag if the first operand is
389: ;; less than or equal to the second. Thus, we have to set CC_NEGATED
390: ;; for the following two patterns.
391:
392: (define_insn "cmpledf"
393: [(set (cc0) (le (match_operand:DF 0 "reg_or_0_operand" "fG")
394: (match_operand:DF 1 "reg_or_0_operand" "fG")))]
395: ""
396: "*
397: {
398: CC_STATUS_PARTIAL_INIT;
399: cc_status.flags |= CC_NEGATED;
400: return \"pfle.dd %r0,%r1,%?f0\";
401: }")
402:
403: (define_insn "cmpgedf"
404: [(set (cc0) (ge (match_operand:DF 0 "reg_or_0_operand" "fG")
405: (match_operand:DF 1 "reg_or_0_operand" "fG")))]
406: ""
407: "*
408: {
409: CC_STATUS_PARTIAL_INIT;
410: cc_status.flags |= CC_NEGATED;
411: return \"pfle.dd %r1,%r0,%?f0\";
412: }")
413:
414: ;; ------------------------------------------------------------------------
415: ;; Integer EQ/NE comparisons against constant values which will fit in the
416: ;; 16-bit immediate field of an instruction. These are made by combining.
417: ;; ------------------------------------------------------------------------
418:
419: (define_insn ""
420: [(set (cc0) (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m"))
421: (match_operand:SI 1 "small_int" "I")))]
422: "INTVAL (operands[1]) >= 0"
423: "*
424: {
425: CC_STATUS_PARTIAL_INIT;
426: return \"ld.s %0,%?r31\;xor %1,%?r31,%?r0\";
427: }")
428:
429: (define_insn ""
430: [(set (cc0) (eq (match_operand:SI 0 "small_int" "I")
431: (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))))]
432: "INTVAL (operands[0]) >= 0"
433: "*
434: {
435: CC_STATUS_PARTIAL_INIT;
436: return \"ld.s %1,%?r31\;xor %0,%?r31,%?r0\";
437: }")
438:
439: ;; ------------------------------------------------------------------------
440: ;; Define the real conditional branch instructions.
441: ;; ------------------------------------------------------------------------
442:
443: (define_insn "cbranch"
444: [(set (pc) (if_then_else (eq (cc0) (const_int 0))
445: (label_ref (match_operand 0 "" ""))
446: (pc)))]
447: ""
448: "*
449: {
450: if ((cc_prev_status.flags & CC_NEGATED) == 0)
451: return \"bnc %l0\";
452: else
453: return \"bc %l0\";
454: }")
455:
456: (define_insn "flipped_cbranch"
457: [(set (pc) (if_then_else (ne (cc0)
458: (const_int 0))
459: (pc)
460: (label_ref (match_operand 0 "" ""))))]
461: ""
462: "*
463: {
464: if ((cc_prev_status.flags & CC_NEGATED) == 0)
465: return \"bnc %l0\";
466: else
467: return \"bc %l0\";
468: }")
469:
470: (define_insn "inverse_cbranch"
471: [(set (pc) (if_then_else (eq (cc0)
472: (const_int 0))
473: (pc)
474: (label_ref (match_operand 0 "" ""))))]
475: ""
476: "*
477: {
478: if ((cc_prev_status.flags & CC_NEGATED) == 0)
479: return \"bc %l0\";
480: else
481: return \"bnc %l0\";
482: }")
483:
484:
485: (define_insn "flipped_inverse_cbranch"
486: [(set (pc) (if_then_else (ne (cc0)
487: (const_int 0))
488: (label_ref (match_operand 0 "" ""))
489: (pc)))]
490: ""
491: "*
492: {
493: if ((cc_prev_status.flags & CC_NEGATED) == 0)
494: return \"bc %l0\";
495: else
496: return \"bnc %l0\";
497: }")
498:
499: ;; Simple BTE/BTNE compare-and-branch insns made by combining.
500:
501: (define_insn ""
502: [(set (pc)
503: (if_then_else (eq (match_operand:QI 0 "register_operand" "r")
504: (match_operand:QI 1 "bte_operand" "rK"))
505: (label_ref (match_operand 2 "" ""))
506: (pc)))]
507: ""
508: "bte %1,%0,%2")
509:
510: (define_insn ""
511: [(set (pc)
512: (if_then_else (ne (match_operand:QI 0 "register_operand" "r")
513: (match_operand:QI 1 "bte_operand" "rK"))
514: (label_ref (match_operand 2 "" ""))
515: (pc)))]
516: ""
517: "btne %1,%0,%2")
518:
519: (define_insn ""
520: [(set (pc)
521: (if_then_else (eq (match_operand:QI 0 "register_operand" "r")
522: (match_operand:QI 1 "bte_operand" "rK"))
523: (pc)
524: (label_ref (match_operand 2 "" ""))))]
525: ""
526: "btne %1,%0,%2")
527:
528: (define_insn ""
529: [(set (pc)
530: (if_then_else (ne (match_operand:QI 0 "register_operand" "r")
531: (match_operand:QI 1 "bte_operand" "rK"))
532: (pc)
533: (label_ref (match_operand 2 "" ""))))]
534: ""
535: "bte %1,%0,%2")
536:
537: (define_insn ""
538: [(set (pc)
539: (if_then_else (eq (match_operand:HI 0 "register_operand" "r")
540: (match_operand:HI 1 "bte_operand" "rK"))
541: (label_ref (match_operand 2 "" ""))
542: (pc)))]
543: ""
544: "bte %1,%0,%2")
545:
546: (define_insn ""
547: [(set (pc)
548: (if_then_else (ne (match_operand:HI 0 "register_operand" "r")
549: (match_operand:HI 1 "bte_operand" "rK"))
550: (label_ref (match_operand 2 "" ""))
551: (pc)))]
552: ""
553: "btne %1,%0,%2")
554:
555: (define_insn ""
556: [(set (pc)
557: (if_then_else (eq (match_operand:HI 0 "register_operand" "r")
558: (match_operand:HI 1 "bte_operand" "rK"))
559: (pc)
560: (label_ref (match_operand 2 "" ""))))]
561: ""
562: "btne %1,%0,%2")
563:
564: (define_insn ""
565: [(set (pc)
566: (if_then_else (ne (match_operand:HI 0 "register_operand" "r")
567: (match_operand:HI 1 "bte_operand" "rK"))
568: (pc)
569: (label_ref (match_operand 2 "" ""))))]
570: ""
571: "bte %1,%0,%2")
572:
573: (define_insn ""
574: [(set (pc)
575: (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
576: (match_operand:SI 1 "bte_operand" "rK"))
577: (label_ref (match_operand 2 "" ""))
578: (pc)))]
579: ""
580: "bte %1,%0,%2")
581:
582: (define_insn ""
583: [(set (pc)
584: (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
585: (match_operand:SI 1 "bte_operand" "rK"))
586: (label_ref (match_operand 2 "" ""))
587: (pc)))]
588: ""
589: "btne %1,%0,%2")
590:
591: (define_insn ""
592: [(set (pc)
593: (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
594: (match_operand:SI 1 "bte_operand" "rK"))
595: (pc)
596: (label_ref (match_operand 2 "" ""))))]
597: ""
598: "btne %1,%0,%2")
599:
600: (define_insn ""
601: [(set (pc)
602: (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
603: (match_operand:SI 1 "bte_operand" "rK"))
604: (pc)
605: (label_ref (match_operand 2 "" ""))))]
606: ""
607: "bte %1,%0,%2")
608:
609: ;; Load byte/halfword, zero-extend, & compare-and-branch insns.
610: ;; These are made by combining.
611:
612: (define_insn ""
613: [(set (pc)
614: (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
615: (match_operand:SI 1 "bte_operand" "K"))
616: (label_ref (match_operand 2 "" ""))
617: (pc)))
618: (match_scratch:SI 3 "=r")]
619: ""
620: "ld.b %0,%3;bte %1,%3,%2")
621:
622: (define_insn ""
623: [(set (pc)
624: (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
625: (match_operand:SI 1 "bte_operand" "K"))
626: (label_ref (match_operand 2 "" ""))
627: (pc)))
628: (match_scratch:SI 3 "=r")]
629: ""
630: "ld.b %0,%3;btne %1,%3,%2")
631:
632: (define_insn ""
633: [(set (pc)
634: (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
635: (match_operand:SI 1 "bte_operand" "K"))
636: (pc)
637: (label_ref (match_operand 2 "" ""))))
638: (match_scratch:SI 3 "=r")]
639: ""
640: "ld.b %0,%3;btne %1,%3,%2")
641:
642: (define_insn ""
643: [(set (pc)
644: (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
645: (match_operand:SI 1 "bte_operand" "K"))
646: (pc)
647: (label_ref (match_operand 2 "" ""))))
648: (match_scratch:SI 3 "=r")]
649: ""
650: "ld.b %0,%3;bte %1,%3,%2")
651:
652: (define_insn ""
653: [(set (pc)
654: (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
655: (match_operand:SI 1 "bte_operand" "K"))
656: (label_ref (match_operand 2 "" ""))
657: (pc)))
658: (match_scratch:SI 3 "=r")]
659: ""
660: "ld.s %0,%3;bte %1,%3,%2")
661:
662: (define_insn ""
663: [(set (pc)
664: (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
665: (match_operand:SI 1 "bte_operand" "K"))
666: (label_ref (match_operand 2 "" ""))
667: (pc)))
668: (match_scratch:SI 3 "=r")]
669: ""
670: "ld.s %0,%3;btne %1,%3,%2")
671:
672: (define_insn ""
673: [(set (pc)
674: (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
675: (match_operand:SI 1 "bte_operand" "K"))
676: (pc)
677: (label_ref (match_operand 2 "" ""))))
678: (match_scratch:SI 3 "=r")]
679: ""
680: "ld.s %0,%3;btne %1,%3,%2")
681:
682: (define_insn ""
683: [(set (pc)
684: (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
685: (match_operand:SI 1 "bte_operand" "K"))
686: (pc)
687: (label_ref (match_operand 2 "" ""))))
688: (match_scratch:SI 3 "=r")]
689: ""
690: "ld.s %0,%3;bte %1,%3,%2")
691:
692:
693: ;; Generation of conditionals.
694:
695: ;; We save the compare operands in the cmpxx patterns and use then when
696: ;; we generate the branch.
697:
698: (define_expand "cmpsi"
699: [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
700: (match_operand:SI 1 "compare_operand" "")))]
701: ""
702: "
703: { i860_compare_op0 = operands[0];
704: i860_compare_op1 = operands[1];
705: DONE;
706: }")
707:
708: (define_expand "cmpsf"
709: [(set (cc0) (compare (match_operand:SF 0 "register_operand" "")
710: (match_operand:SF 1 "register_operand" "")))]
711: ""
712: "
713: { i860_compare_op0 = operands[0];
714: i860_compare_op1 = operands[1];
715: DONE;
716: }")
717:
718: (define_expand "cmpdf"
719: [(set (cc0) (compare (match_operand:DF 0 "register_operand" "")
720: (match_operand:DF 1 "register_operand" "")))]
721: ""
722: "
723: { i860_compare_op0 = operands[0];
724: i860_compare_op1 = operands[1];
725: DONE;
726: }")
727:
728: ;; These are the standard-named conditional branch patterns.
729: ;; Detailed comments are found in the first one only.
730:
731: (define_expand "beq"
732: [(set (pc)
733: (if_then_else (eq (cc0)
734: (const_int 0))
735: (label_ref (match_operand 0 "" ""))
736: (pc)))]
737: ""
738: "
739: {
740: /* Emit a single-condition compare insn according to
741: the type of operands and the condition to be tested. */
742:
743: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
744: emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
745: else if (GET_MODE (i860_compare_op0) == SFmode)
746: emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
747: else if (GET_MODE (i860_compare_op0) == DFmode)
748: emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
749: else
750: abort ();
751:
752: /* Emit branch-if-true. */
753:
754: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
755: DONE;
756: }")
757:
758: (define_expand "bne"
759: [(set (pc)
760: (if_then_else (ne (cc0)
761: (const_int 0))
762: (label_ref (match_operand 0 "" ""))
763: (pc)))]
764: ""
765: "
766: {
767: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
768: emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
769: else if (GET_MODE (i860_compare_op0) == SFmode)
770: emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
771: else if (GET_MODE (i860_compare_op0) == DFmode)
772: emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
773: else
774: abort ();
775:
776: emit_jump_insn (gen_flipped_cbranch (operands[0]));
777:
778: DONE;
779: }")
780:
781: (define_expand "bgt"
782: [(set (pc)
783: (if_then_else (gt (cc0)
784: (const_int 0))
785: (label_ref (match_operand 0 "" ""))
786: (pc)))]
787: ""
788: "
789: {
790: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
791: emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
792: else if (GET_MODE (i860_compare_op0) == SFmode)
793: emit_insn (gen_cmpgtsf (i860_compare_op0, i860_compare_op1));
794: else if (GET_MODE (i860_compare_op0) == DFmode)
795: emit_insn (gen_cmpgtdf (i860_compare_op0, i860_compare_op1));
796: else
797: abort ();
798:
799: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
800: DONE;
801: }")
802:
803: (define_expand "blt"
804: [(set (pc)
805: (if_then_else (lt (cc0)
806: (const_int 0))
807: (label_ref (match_operand 0 "" ""))
808: (pc)))]
809: ""
810: "
811: {
812: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
813: emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
814: else if (GET_MODE (i860_compare_op0) == SFmode)
815: emit_insn (gen_cmpltsf (i860_compare_op0, i860_compare_op1));
816: else if (GET_MODE (i860_compare_op0) == DFmode)
817: emit_insn (gen_cmpltdf (i860_compare_op0, i860_compare_op1));
818: else
819: abort ();
820:
821: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
822: DONE;
823: }")
824:
825: (define_expand "ble"
826: [(set (pc)
827: (if_then_else (le (cc0)
828: (const_int 0))
829: (label_ref (match_operand 0 "" ""))
830: (pc)))]
831: ""
832: "
833: {
834: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
835: {
836: emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
837: emit_jump_insn (gen_flipped_cbranch (operands[0]));
838: }
839: else
840: {
841: if (GET_MODE (i860_compare_op0) == SFmode)
842: emit_insn (gen_cmplesf (i860_compare_op0, i860_compare_op1));
843: else if (GET_MODE (i860_compare_op0) == DFmode)
844: emit_insn (gen_cmpledf (i860_compare_op0, i860_compare_op1));
845: else
846: abort ();
847: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
848: }
849: DONE;
850: }")
851:
852: (define_expand "bge"
853: [(set (pc)
854: (if_then_else (ge (cc0)
855: (const_int 0))
856: (label_ref (match_operand 0 "" ""))
857: (pc)))]
858: ""
859: "
860: {
861: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
862: {
863: emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
864: emit_jump_insn (gen_flipped_cbranch (operands[0]));
865: }
866: else
867: {
868: if (GET_MODE (i860_compare_op0) == SFmode)
869: emit_insn (gen_cmpgesf (i860_compare_op0, i860_compare_op1));
870: else if (GET_MODE (i860_compare_op0) == DFmode)
871: emit_insn (gen_cmpgedf (i860_compare_op0, i860_compare_op1));
872: else
873: abort ();
874: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
875: }
876: DONE;
877: }")
878:
879: (define_expand "bgtu"
880: [(set (pc)
881: (if_then_else (gtu (cc0)
882: (const_int 0))
883: (label_ref (match_operand 0 "" ""))
884: (pc)))]
885: ""
886: "
887: {
888: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
889: abort ();
890:
891: emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
892: emit_jump_insn (gen_flipped_cbranch (operands[0]));
893: DONE;
894: }")
895:
896: (define_expand "bltu"
897: [(set (pc)
898: (if_then_else (ltu (cc0)
899: (const_int 0))
900: (label_ref (match_operand 0 "" ""))
901: (pc)))]
902: ""
903: "
904: {
905: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
906: abort ();
907:
908: emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
909: emit_jump_insn (gen_flipped_cbranch (operands[0]));
910: DONE;
911: }")
912:
913: (define_expand "bgeu"
914: [(set (pc)
915: (if_then_else (geu (cc0)
916: (const_int 0))
917: (label_ref (match_operand 0 "" ""))
918: (pc)))]
919: ""
920: "
921: {
922: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
923: abort ();
924:
925: emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
926: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
927: DONE;
928: }")
929:
930: (define_expand "bleu"
931: [(set (pc)
932: (if_then_else (leu (cc0)
933: (const_int 0))
934: (label_ref (match_operand 0 "" ""))
935: (pc)))]
936: ""
937: "
938: {
939: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
940: abort ();
941:
942: emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
943: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
944: DONE;
945: }")
946:
947: ;; Move instructions
948:
949: ;; Note that source operands for `mov' pseudo-instructions are no longer
950: ;; allowed (by the svr4 assembler) to be "big" things, i.e. constants that
951: ;; won't fit in 16-bits. (This includes any sort of a relocatable address
952: ;; also.) Thus, we must use an explicit orh/or pair of instructions if
953: ;; the source operand is something "big".
954:
955: (define_insn "movsi"
956: [(set (match_operand:SI 0 "general_operand" "=r,m,f")
957: (match_operand:SI 1 "general_operand" "rmif,rfJ,rmfJ"))]
958: ""
959: "*
960: {
961: if (GET_CODE (operands[0]) == MEM)
962: {
963: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
964: return output_store (operands);
965: if (FP_REG_P (operands[1]))
966: return \"fst.l %1,%0\";
967: return \"st.l %r1,%0\";
968: }
969: if (GET_CODE (operands[1]) == MEM)
970: {
971: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
972: return output_load (operands);
973: if (FP_REG_P (operands[0]))
974: return \"fld.l %1,%0\";
975: return \"ld.l %1,%0\";
976: }
977: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
978: return \"fmov.ss %1,%0\";
979: if (FP_REG_P (operands[1]))
980: return \"fxfr %1,%0\";
981: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
982: return \"fmov.ss %?f0,%0\";
983: if (FP_REG_P (operands[0]))
984: return \"ixfr %1,%0\";
985:
986: if (GET_CODE (operands[1]) == REG)
987: return \"shl %?r0,%1,%0\";
988:
989: CC_STATUS_PARTIAL_INIT;
990:
991: if (GET_CODE (operands[1]) == CONST_INT)
992: {
993: if((INTVAL (operands[1]) & 0xffff0000) == 0)
994: return \"or %L1,%?r0,%0\";
995: if((INTVAL (operands[1]) & 0x0000ffff) == 0)
996: return \"orh %H1,%?r0,%0\";
997: }
998: return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
999: }")
1000:
1001: (define_insn "movhi"
1002: [(set (match_operand:HI 0 "general_operand" "=r,m,!*f,!r")
1003: (match_operand:HI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
1004: ""
1005: "*
1006: {
1007: if (GET_CODE (operands[0]) == MEM)
1008: {
1009: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1010: return output_store (operands);
1011: return \"st.s %r1,%0\";
1012: }
1013: if (GET_CODE (operands[1]) == MEM)
1014: {
1015: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1016: return output_load (operands);
1017: return \"ld.s %1,%0\";
1018: }
1019: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
1020: return \"fmov.ss %1,%0\";
1021: if (FP_REG_P (operands[1]))
1022: return \"fxfr %1,%0\";
1023: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
1024: return \"fmov.ss %?f0,%0\";
1025: if (FP_REG_P (operands[0]))
1026: return \"ixfr %1,%0\";
1027:
1028: if (GET_CODE (operands[1]) == REG)
1029: return \"shl %?r0,%1,%0\";
1030:
1031: CC_STATUS_PARTIAL_INIT;
1032:
1033: return \"or %L1,%?r0,%0\";
1034: }")
1035:
1036: (define_insn "movqi"
1037: [(set (match_operand:QI 0 "general_operand" "=r,m,!*f,!r")
1038: (match_operand:QI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
1039: ""
1040: "*
1041: {
1042: if (GET_CODE (operands[0]) == MEM)
1043: {
1044: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1045: return output_store (operands);
1046: return \"st.b %r1,%0\";
1047: }
1048: if (GET_CODE (operands[1]) == MEM)
1049: {
1050: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1051: return output_load (operands);
1052: return \"ld.b %1,%0\";
1053: }
1054: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
1055: return \"fmov.ss %1,%0\";
1056: if (FP_REG_P (operands[1]))
1057: return \"fxfr %1,%0\";
1058: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
1059: return \"fmov.ss %?f0,%0\";
1060: if (FP_REG_P (operands[0]))
1061: return \"ixfr %1,%0\";
1062:
1063: if (GET_CODE (operands[1]) == REG)
1064: return \"shl %?r0,%1,%0\";
1065:
1066: CC_STATUS_PARTIAL_INIT;
1067:
1068: return \"or %L1,%?r0,%0\";
1069: }")
1070:
1071: ;; The definition of this insn does not really explain what it does,
1072: ;; but it should suffice
1073: ;; that anything generated as this insn will be recognized as one
1074: ;; and that it won't successfully combine with anything.
1075: (define_expand "movstrsi"
1076: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1077: (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1078: (use (match_operand:SI 2 "nonmemory_operand" ""))
1079: (use (match_operand:SI 3 "immediate_operand" ""))
1080: (clobber (match_dup 4))
1081: (clobber (match_dup 5))
1082: (clobber (match_dup 6))
1083: (clobber (match_dup 0))
1084: (clobber (match_dup 1))])]
1085: ""
1086: "
1087: {
1088: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1089: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1090: operands[4] = gen_reg_rtx (SImode);
1091: operands[5] = gen_reg_rtx (SImode);
1092: operands[6] = gen_reg_rtx (SImode);
1093: }")
1094:
1095: (define_insn ""
1096: [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1097: (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1098: (use (match_operand:SI 2 "general_operand" "rn"))
1099: (use (match_operand:SI 3 "immediate_operand" "i"))
1100: (clobber (match_operand:SI 4 "register_operand" "=r"))
1101: (clobber (match_operand:SI 5 "register_operand" "=r"))
1102: (clobber (match_operand:SI 6 "register_operand" "=r"))
1103: (clobber (match_dup 0))
1104: (clobber (match_dup 1))]
1105: ""
1106: "* return output_block_move (operands);")
1107:
1108: ;; Floating point move insns
1109:
1110: ;; This pattern forces (set (reg:DF ...) (const_double ...))
1111: ;; to be reloaded by putting the constant into memory.
1112: ;; It must come before the more general movdf pattern.
1113: (define_insn ""
1114: [(set (match_operand:DF 0 "general_operand" "=r,f,o")
1115: (match_operand:DF 1 "" "mG,m,G"))]
1116: "GET_CODE (operands[1]) == CONST_DOUBLE"
1117: "*
1118: {
1119: if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode))
1120: return output_fp_move_double (operands);
1121: return output_move_double (operands);
1122: }")
1123:
1124: (define_insn "movdf"
1125: [(set (match_operand:DF 0 "general_operand" "=*rm,&*r,?f,?*rm")
1126: (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))]
1127: ""
1128: "*
1129: {
1130: if (GET_CODE (operands[0]) == MEM
1131: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1132: return output_store (operands);
1133: if (GET_CODE (operands[1]) == MEM
1134: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1135: return output_load (operands);
1136:
1137: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1138: return output_fp_move_double (operands);
1139: return output_move_double (operands);
1140: }")
1141:
1142: (define_insn "movdi"
1143: [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm")
1144: (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))]
1145: ""
1146: "*
1147: {
1148: if (GET_CODE (operands[0]) == MEM
1149: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1150: return output_store (operands);
1151: if (GET_CODE (operands[1]) == MEM
1152: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1153: return output_load (operands);
1154:
1155: /* ??? How can we have a DFmode arg here with DImode above? */
1156: if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode))
1157: return \"fmov.dd %?f0,%0\";
1158:
1159: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1160: return output_fp_move_double (operands);
1161: return output_move_double (operands);
1162: }")
1163:
1164: ;; The alternative m/r is separate from m/f
1165: ;; The first alternative is separate from the second for the same reason.
1166: (define_insn "movsf"
1167: [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m")
1168: (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))]
1169: ""
1170: "*
1171: {
1172: if (GET_CODE (operands[0]) == MEM
1173: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1174: return output_store (operands);
1175: if (GET_CODE (operands[1]) == MEM
1176: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1177: return output_load (operands);
1178: if (FP_REG_P (operands[0]))
1179: {
1180: if (FP_REG_P (operands[1]))
1181: return \"fmov.ss %1,%0\";
1182: if (GET_CODE (operands[1]) == REG)
1183: return \"ixfr %1,%0\";
1184: if (operands[1] == CONST0_RTX (SFmode))
1185: return \"fmov.ss %?f0,%0\";
1186: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1187: {
1188: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1189: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1190: && cc_prev_status.mdep == XEXP(operands[1],0)))
1191: {
1192: CC_STATUS_INIT;
1193: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1194: cc_status.mdep = XEXP (operands[1], 0);
1195: return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\";
1196: }
1197: return \"fld.l %L1(%?r31),%0\";
1198: }
1199: return \"fld.l %1,%0\";
1200: }
1201: if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
1202: {
1203: if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1]))
1204: return \"fxfr %1,%0\";
1205: if (GET_CODE (operands[0]) == REG)
1206: {
1207: CC_STATUS_PARTIAL_INIT;
1208: if (GET_CODE (operands[1]) == CONST_DOUBLE)
1209: {
1210: register unsigned long ul;
1211:
1212: ul = sfmode_constant_to_ulong (operands[1]);
1213: if ((ul & 0x0000ffff) == 0)
1214: return \"orh %H1,%?r0,%0\";
1215: if ((ul & 0xffff0000) == 0)
1216: return \"or %L1,%?r0,%0\";
1217: }
1218: return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
1219: }
1220: /* Now operand 0 must be memory.
1221: If operand 1 is CONST_DOUBLE, its value must be 0. */
1222: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1223: {
1224: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1225: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1226: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1227: {
1228: CC_STATUS_INIT;
1229: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1230: cc_status.mdep = XEXP (operands[0], 0);
1231: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1232: }
1233: return \"fst.l %r1,%L0(%?r31)\";
1234: }
1235: return \"fst.l %r1,%0\";
1236: }
1237: if (GET_CODE (operands[0]) == MEM)
1238: return \"st.l %r1,%0\";
1239: if (GET_CODE (operands[1]) == MEM)
1240: return \"ld.l %1,%0\";
1241: if (operands[1] == CONST0_RTX (SFmode))
1242: return \"shl %?r0,%?r0,%0\";
1243: return \"mov %1,%0\";
1244: }")
1245:
1246: ;; Special load insns for REG+REG addresses.
1247: ;; Such addresses are not "legitimate" because st rejects them.
1248:
1249: (define_insn ""
1250: [(set (match_operand:DF 0 "register_operand" "=rf")
1251: (match_operand:DF 1 "indexed_operand" "m"))]
1252: ""
1253: "*
1254: {
1255: if (FP_REG_P (operands[0]))
1256: return output_fp_move_double (operands);
1257: return output_move_double (operands);
1258: }")
1259:
1260: (define_insn ""
1261: [(set (match_operand:SF 0 "register_operand" "=rf")
1262: (match_operand:SF 1 "indexed_operand" "m"))]
1263: ""
1264: "*
1265: {
1266: if (FP_REG_P (operands[0]))
1267: return \"fld.l %1,%0\";
1268: return \"ld.l %1,%0\";
1269: }")
1270:
1271: (define_insn ""
1272: [(set (match_operand:SI 0 "register_operand" "=rf")
1273: (match_operand:SI 1 "indexed_operand" "m"))]
1274: ""
1275: "*
1276: {
1277: if (FP_REG_P (operands[0]))
1278: return \"fld.l %1,%0\";
1279: return \"ld.l %1,%0\";
1280: }")
1281:
1282: (define_insn ""
1283: [(set (match_operand:HI 0 "register_operand" "=r")
1284: (match_operand:HI 1 "indexed_operand" "m"))]
1285: ""
1286: "ld.s %1,%0")
1287:
1288: (define_insn ""
1289: [(set (match_operand:QI 0 "register_operand" "=r")
1290: (match_operand:QI 1 "indexed_operand" "m"))]
1291: ""
1292: "ld.b %1,%0")
1293:
1294: ;; Likewise for floating-point store insns.
1295:
1296: (define_insn ""
1297: [(set (match_operand:DF 0 "indexed_operand" "=m")
1298: (match_operand:DF 1 "register_operand" "f"))]
1299: ""
1300: "fst.d %1,%0")
1301:
1302: (define_insn ""
1303: [(set (match_operand:SF 0 "indexed_operand" "=m")
1304: (match_operand:SF 1 "register_operand" "f"))]
1305: ""
1306: "fst.l %1,%0")
1307:
1308: ;;- truncation instructions
1309: (define_insn "truncsiqi2"
1310: [(set (match_operand:QI 0 "general_operand" "=g")
1311: (truncate:QI
1312: (match_operand:SI 1 "register_operand" "r")))]
1313: ""
1314: "*
1315: {
1316: if (GET_CODE (operands[0]) == MEM)
1317: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1318: {
1319: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1320: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1321: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1322: {
1323: CC_STATUS_INIT;
1324: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1325: cc_status.mdep = XEXP (operands[0], 0);
1326: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1327: }
1328: return \"st.b %1,%L0(%?r31)\";
1329: }
1330: else
1331: return \"st.b %1,%0\";
1332: return \"shl %?r0,%1,%0\";
1333: }")
1334:
1335: (define_insn "trunchiqi2"
1336: [(set (match_operand:QI 0 "general_operand" "=g")
1337: (truncate:QI
1338: (match_operand:HI 1 "register_operand" "r")))]
1339: ""
1340: "*
1341: {
1342: if (GET_CODE (operands[0]) == MEM)
1343: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1344: {
1345: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1346: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1347: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1348: {
1349: CC_STATUS_INIT;
1350: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1351: cc_status.mdep = XEXP (operands[0], 0);
1352: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1353: }
1354: return \"st.b %1,%L0(%?r31)\";
1355: }
1356: else
1357: return \"st.b %1,%0\";
1358: return \"shl %?r0,%1,%0\";
1359: }")
1360:
1361: (define_insn "truncsihi2"
1362: [(set (match_operand:HI 0 "general_operand" "=g")
1363: (truncate:HI
1364: (match_operand:SI 1 "register_operand" "r")))]
1365: ""
1366: "*
1367: {
1368: if (GET_CODE (operands[0]) == MEM)
1369: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1370: {
1371: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1372: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1373: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1374: {
1375: CC_STATUS_INIT;
1376: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1377: cc_status.mdep = XEXP (operands[0], 0);
1378: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1379: }
1380: return \"st.s %1,%L0(%?r31)\";
1381: }
1382: else
1383: return \"st.s %1,%0\";
1384: return \"shl %?r0,%1,%0\";
1385: }")
1386:
1387: ;;- zero extension instructions
1388:
1389: (define_insn "zero_extendhisi2"
1390: [(set (match_operand:SI 0 "register_operand" "=r")
1391: (zero_extend:SI
1392: (match_operand:HI 1 "register_operand" "r")))]
1393: ""
1394: "*
1395: {
1396: CC_STATUS_PARTIAL_INIT;
1397: return \"and 0xffff,%1,%0\";
1398: }")
1399:
1400: (define_insn "zero_extendqihi2"
1401: [(set (match_operand:HI 0 "register_operand" "=r")
1402: (zero_extend:HI
1403: (match_operand:QI 1 "register_operand" "r")))]
1404: ""
1405: "*
1406: {
1407: CC_STATUS_PARTIAL_INIT;
1408: return \"and 0xff,%1,%0\";
1409: }")
1410:
1411: (define_insn "zero_extendqisi2"
1412: [(set (match_operand:SI 0 "register_operand" "=r")
1413: (zero_extend:SI
1414: (match_operand:QI 1 "register_operand" "r")))]
1415: ""
1416: "*
1417: {
1418: CC_STATUS_PARTIAL_INIT;
1419: return \"and 0xff,%1,%0\";
1420: }")
1421:
1422: ;; Sign extension instructions.
1423:
1424: (define_insn ""
1425: [(set (match_operand:SI 0 "register_operand" "=r")
1426: (sign_extend:SI
1427: (match_operand:HI 1 "indexed_operand" "m")))]
1428: ""
1429: "ld.s %1,%0")
1430:
1431: (define_insn ""
1432: [(set (match_operand:HI 0 "register_operand" "=r")
1433: (sign_extend:HI
1434: (match_operand:QI 1 "indexed_operand" "m")))]
1435: ""
1436: "ld.b %1,%0")
1437:
1438: (define_insn ""
1439: [(set (match_operand:SI 0 "register_operand" "=r")
1440: (sign_extend:SI
1441: (match_operand:QI 1 "indexed_operand" "m")))]
1442: ""
1443: "ld.b %1,%0")
1444:
1445: (define_insn "extendhisi2"
1446: [(set (match_operand:SI 0 "register_operand" "=r")
1447: (sign_extend:SI
1448: (match_operand:HI 1 "nonimmediate_operand" "mr")))]
1449: ""
1450: "*
1451: {
1452: if (REG_P (operands[1]))
1453: return \"shl 16,%1,%0\;shra 16,%0,%0\";
1454: if (GET_CODE (operands[1]) == CONST_INT)
1455: abort ();
1456: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1457: {
1458: CC_STATUS_INIT;
1459: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1460: cc_status.mdep = XEXP (operands[1], 0);
1461: return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\";
1462: }
1463: else
1464: return \"ld.s %1,%0\";
1465: }")
1466:
1467: (define_insn "extendqihi2"
1468: [(set (match_operand:HI 0 "register_operand" "=r")
1469: (sign_extend:HI
1470: (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1471: ""
1472: "*
1473: {
1474: if (REG_P (operands[1]))
1475: return \"shl 24,%1,%0\;shra 24,%0,%0\";
1476: if (GET_CODE (operands[1]) == CONST_INT)
1477: abort ();
1478: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1479: {
1480: CC_STATUS_INIT;
1481: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1482: cc_status.mdep = XEXP (operands[1], 0);
1483: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1484: }
1485: else
1486: return \"ld.b %1,%0\";
1487: }")
1488:
1489: (define_insn "extendqisi2"
1490: [(set (match_operand:SI 0 "register_operand" "=r")
1491: (sign_extend:SI
1492: (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1493: ""
1494: "*
1495: {
1496: if (REG_P (operands[1]))
1497: return \"shl 24,%1,%0\;shra 24,%0,%0\";
1498: if (GET_CODE (operands[1]) == CONST_INT)
1499: abort ();
1500: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1501: {
1502: CC_STATUS_INIT;
1503: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1504: cc_status.mdep = XEXP (operands[1], 0);
1505: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1506: }
1507: else
1508: return \"ld.b %1,%0\";
1509: }")
1510:
1511: ;; Signed bitfield extractions come out looking like
1512: ;; (shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
1513: ;; which we expand poorly as four shift insns.
1514: ;; These patters yeild two shifts:
1515: ;; (shiftrt (shift <Y> <C3>) <C4>)
1516: (define_insn ""
1517: [(set (match_operand:SI 0 "register_operand" "=r")
1518: (ashiftrt:SI
1519: (sign_extend:SI
1520: (match_operand:QI 1 "register_operand" "r"))
1521: (match_operand:SI 2 "logic_int" "n")))]
1522: "INTVAL (operands[2]) < 8"
1523: "*
1524: {
1525: return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
1526: }")
1527:
1528: (define_insn ""
1529: [(set (match_operand:SI 0 "register_operand" "=r")
1530: (ashiftrt:SI
1531: (sign_extend:SI
1532: (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1533: (match_operand:SI 2 "logic_int" "n")) 0))
1534: (match_operand:SI 3 "logic_int" "n")))]
1535: "INTVAL (operands[3]) < 8"
1536: "*
1537: {
1538: return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1539: }")
1540:
1541: (define_insn ""
1542: [(set (match_operand:SI 0 "register_operand" "=r")
1543: (ashiftrt:SI
1544: (sign_extend:SI
1545: (ashift:QI (match_operand:QI 1 "register_operand" "r")
1546: (match_operand:QI 2 "logic_int" "n")))
1547: (match_operand:SI 3 "logic_int" "n")))]
1548: "INTVAL (operands[3]) < 8"
1549: "*
1550: {
1551: return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1552: }")
1553:
1554: ;; Special patterns for optimizing bit-field instructions.
1555:
1556: ;; First two patterns are for bitfields that came from memory
1557: ;; testing only the high bit. They work with old combiner.
1558:
1559: (define_insn ""
1560: [(set (cc0)
1561: (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1562: (const_int 7)) 0))
1563: (const_int 0)))]
1564: ""
1565: "*
1566: {
1567: CC_STATUS_PARTIAL_INIT;
1568: return \"and 128,%0,%?r0\";
1569: }")
1570:
1571: (define_insn ""
1572: [(set (cc0)
1573: (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1574: (const_int 7)) 0))
1575: (const_int 0)))]
1576: ""
1577: "*
1578: {
1579: CC_STATUS_PARTIAL_INIT;
1580: return \"and 128,%0,%?r0\";
1581: }")
1582:
1583: ;; next two patterns are good for bitfields coming from memory
1584: ;; (via pseudo-register) or from a register, though this optimization
1585: ;; is only good for values contained wholly within the bottom 13 bits
1586: (define_insn ""
1587: [(set (cc0)
1588: (eq
1589: (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1590: (match_operand:SI 1 "logic_int" "n"))
1591: (match_operand:SI 2 "logic_int" "n"))
1592: (const_int 0)))]
1593: "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1594: "*
1595: {
1596: CC_STATUS_PARTIAL_INIT;
1597: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1598: (INTVAL (operands[2]) << INTVAL (operands[1])));
1599: return \"and %2,%0,%?r0\";
1600: }")
1601:
1602: (define_insn ""
1603: [(set (cc0)
1604: (eq
1605: (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1606: (match_operand:SI 1 "logic_int" "n"))
1607: (match_operand:SI 2 "logic_int" "n"))
1608: (const_int 0)))]
1609: "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1610: "*
1611: {
1612: CC_STATUS_PARTIAL_INIT;
1613: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1614: (INTVAL (operands[2]) << INTVAL (operands[1])));
1615: return \"and %2,%0,%?r0\";
1616: }")
1617:
1618: ;; Conversions between float and double.
1619:
1620: (define_insn "extendsfdf2"
1621: [(set (match_operand:DF 0 "register_operand" "=f")
1622: (float_extend:DF
1623: (match_operand:SF 1 "register_operand" "f")))]
1624: ""
1625: "fmov.sd %1,%0")
1626:
1627: (define_insn "truncdfsf2"
1628: [(set (match_operand:SF 0 "register_operand" "=f")
1629: (float_truncate:SF
1630: (match_operand:DF 1 "register_operand" "f")))]
1631: ""
1632: "fmov.ds %1,%0")
1633:
1634: ;; Conversion between fixed point and floating point.
1635: ;; Note that among the fix-to-float insns
1636: ;; the ones that start with SImode come first.
1637: ;; That is so that an operand that is a CONST_INT
1638: ;; (and therefore lacks a specific machine mode).
1639: ;; will be recognized as SImode (which is always valid)
1640: ;; rather than as QImode or HImode.
1641:
1642: ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1643: ;; to be reloaded by putting the constant into memory.
1644: ;; It must come before the more general floatsisf2 pattern.
1645: (define_expand "floatsidf2"
1646: [(set (match_dup 2) (match_dup 3))
1647: (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
1648: (const_int -2147483648)))
1.1.1.2 ! root 1649: (set (match_dup 5) (match_dup 3))
1.1 root 1650: (set (subreg:SI (match_dup 5) 0) (match_dup 4))
1651: (set (match_operand:DF 0 "register_operand" "")
1652: (minus:DF (match_dup 5) (match_dup 2)))]
1653: ""
1654: "
1655: {
1656: REAL_VALUE_TYPE d;
1657: /* 4503601774854144 is (1 << 30) * ((1 << 22) + (1 << 1)). */
1658: d = REAL_VALUE_ATOF (\"4503601774854144\");
1659: operands[2] = gen_reg_rtx (DFmode);
1660: operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode);
1661: operands[4] = gen_reg_rtx (SImode);
1662: operands[5] = gen_reg_rtx (DFmode);
1663: }")
1664:
1665: ;; Floating to fixed conversion.
1666:
1667: (define_expand "fix_truncdfsi2"
1668: ;; This first insn produces a double-word value
1669: ;; in which only the low word is valid.
1670: [(set (match_dup 2)
1671: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1672: (set (match_operand:SI 0 "register_operand" "=f")
1673: (subreg:SI (match_dup 2) 0))]
1674: ""
1675: "
1676: {
1677: operands[2] = gen_reg_rtx (DImode);
1678: }")
1679:
1680: ;; Recognize the first insn generated above.
1681: ;; This RTL looks like a fix_truncdfdi2 insn,
1682: ;; but we dont call it that, because only 32 bits
1683: ;; of the result are valid.
1684: ;; This pattern will work for the intended purposes
1685: ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
1686: (define_insn ""
1687: [(set (match_operand:DI 0 "register_operand" "=f")
1688: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1689: ""
1690: "ftrunc.dd %1,%0")
1691:
1692: (define_expand "fix_truncsfsi2"
1693: ;; This first insn produces a double-word value
1694: ;; in which only the low word is valid.
1695: [(set (match_dup 2)
1696: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
1697: (set (match_operand:SI 0 "register_operand" "=f")
1698: (subreg:SI (match_dup 2) 0))]
1699: ""
1700: "
1701: {
1702: operands[2] = gen_reg_rtx (DImode);
1703: }")
1704:
1705: ;; Recognize the first insn generated above.
1706: ;; This RTL looks like a fix_truncsfdi2 insn,
1707: ;; but we dont call it that, because only 32 bits
1708: ;; of the result are valid.
1709: ;; This pattern will work for the intended purposes
1710: ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
1711: (define_insn ""
1712: [(set (match_operand:DI 0 "register_operand" "=f")
1713: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1714: ""
1715: "ftrunc.sd %1,%0")
1716:
1717: ;;- arithmetic instructions
1718:
1719: (define_insn "addsi3"
1720: [(set (match_operand:SI 0 "register_operand" "=r,*f")
1721: (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
1722: (match_operand:SI 2 "arith_operand" "rI,*f")))]
1723: ""
1724: "*
1725: {
1726: if (which_alternative == 1)
1727: return \"fiadd.ss %2,%1,%0\";
1728: CC_STATUS_PARTIAL_INIT;
1729: return \"addu %2,%1,%0\";
1730: }")
1731:
1732: (define_insn "adddi3"
1733: [(set (match_operand:DI 0 "register_operand" "=f")
1734: (plus:DI (match_operand:DI 1 "register_operand" "%f")
1735: (match_operand:DI 2 "register_operand" "f")))]
1736: ""
1737: "fiadd.dd %1,%2,%0")
1738:
1739: (define_insn "subsi3"
1740: [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
1741: (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
1742: (match_operand:SI 2 "arith_operand" "rI,r,*f")))]
1743: ""
1744: "*
1745: {
1746: if (which_alternative == 2)
1747: return \"fisub.ss %1,%2,%0\";
1748: CC_STATUS_PARTIAL_INIT;
1749: if (REG_P (operands[2]))
1750: return \"subu %1,%2,%0\";
1751: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1752: return \"addu %2,%1,%0\";
1753: }")
1754:
1755: (define_insn "subdi3"
1756: [(set (match_operand:DI 0 "register_operand" "=f")
1757: (minus:DI (match_operand:DI 1 "register_operand" "%f")
1758: (match_operand:DI 2 "register_operand" "f")))]
1759: ""
1760: "fisub.dd %1,%2,%0")
1761:
1762: (define_expand "mulsi3"
1763: [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1764: (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1765: (clobber (match_dup 3))
1766: (set (subreg:SI (match_dup 3) 0)
1767: (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1768: (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1769: ""
1770: "
1771: {
1772: operands[3] = gen_reg_rtx (DImode);
1773: operands[4] = gen_reg_rtx (DImode);
1774: operands[5] = gen_reg_rtx (DImode);
1775: }")
1776:
1777: (define_insn ""
1778: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1779: (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1780: (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1781: ""
1782: "fmlow.dd %2,%1,%0")
1783:
1784: ;;- and instructions (with compliment also)
1785: (define_insn "andsi3"
1786: [(set (match_operand:SI 0 "register_operand" "=r")
1787: (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1788: (match_operand:SI 2 "nonmemory_operand" "rL")))]
1789: ""
1790: "*
1791: {
1792: rtx xop[3];
1793:
1794: CC_STATUS_PARTIAL_INIT;
1795: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1796: return \"and %2,%1,%0\";
1797: if ((INTVAL (operands[2]) & 0xffff) == 0)
1798: {
1799: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1800: (unsigned) INTVAL (operands[2]) >> 16);
1801: return \"andh %2,%1,%0\";
1802: }
1803: xop[0] = operands[0];
1804: xop[1] = operands[1];
1805: xop[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]) & 0xffff);
1806: output_asm_insn (\"andnot %2,%1,%0\", xop);
1807: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1808: ~(unsigned) INTVAL (operands[2]) >> 16);
1809: return \"andnoth %2,%0,%0\";
1810: }")
1811:
1812: (define_insn ""
1813: [(set (match_operand:SI 0 "register_operand" "=r")
1814: (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn"))
1815: (match_operand:SI 2 "register_operand" "r")))]
1816: ""
1817: "*
1818: {
1819: rtx xop[3];
1820:
1821: CC_STATUS_PARTIAL_INIT;
1822: if (REG_P (operands[1]) || LOGIC_INT (operands[1]))
1823: return \"andnot %1,%2,%0\";
1824: if ((INTVAL (operands[1]) & 0xffff) == 0)
1825: {
1826: operands[1] = gen_rtx (CONST_INT, VOIDmode,
1827: (unsigned) INTVAL (operands[1]) >> 16);
1828: return \"andnoth %1,%2,%0\";
1829: }
1830: xop[0] = operands[0];
1831: xop[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) & 0xffff));
1832: xop[2] = operands[2];
1833: output_asm_insn (\"andnot %1,%2,%0\", xop);
1834: operands[1] = gen_rtx (CONST_INT, VOIDmode,
1835: (unsigned) INTVAL (operands[1]) >> 16);
1836: return \"andnoth %1,%0,%0\";
1837: }")
1838:
1839: (define_insn "iorsi3"
1840: [(set (match_operand:SI 0 "register_operand" "=r")
1841: (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1842: (match_operand:SI 2 "nonmemory_operand" "rL")))]
1843: ""
1844: "*
1845: {
1846: rtx xop[3];
1847:
1848: CC_STATUS_PARTIAL_INIT;
1849: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1850: return \"or %2,%1,%0\";
1851: if ((INTVAL (operands[2]) & 0xffff) == 0)
1852: {
1853: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1854: (unsigned) INTVAL (operands[2]) >> 16);
1855: return \"orh %2,%1,%0\";
1856: }
1857: xop[0] = operands[0];
1858: xop[1] = operands[1];
1859: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1860: output_asm_insn (\"or %2,%1,%0\", xop);
1861: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1862: (unsigned) INTVAL (operands[2]) >> 16);
1863: return \"orh %2,%0,%0\";
1864: }")
1865:
1866: (define_insn "xorsi3"
1867: [(set (match_operand:SI 0 "register_operand" "=r")
1868: (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1869: (match_operand:SI 2 "nonmemory_operand" "rL")))]
1870: ""
1871: "*
1872: {
1873: rtx xop[3];
1874:
1875: CC_STATUS_PARTIAL_INIT;
1876: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1877: return \"xor %2,%1,%0\";
1878: if ((INTVAL (operands[2]) & 0xffff) == 0)
1879: {
1880: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1881: (unsigned) INTVAL (operands[2]) >> 16);
1882: return \"xorh %2,%1,%0\";
1883: }
1884: xop[0] = operands[0];
1885: xop[1] = operands[1];
1886: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1887: output_asm_insn (\"xor %2,%1,%0\", xop);
1888: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1889: (unsigned) INTVAL (operands[2]) >> 16);
1890: return \"xorh %2,%0,%0\";
1891: }")
1892:
1893: ;(The i860 instruction set doesn't allow an immediate second operand in
1894: ; a subtraction.)
1895: (define_insn "negsi2"
1896: [(set (match_operand:SI 0 "general_operand" "=r")
1897: (neg:SI (match_operand:SI 1 "arith_operand" "r")))]
1898: ""
1899: "*
1900: {
1901: CC_STATUS_PARTIAL_INIT;
1902: return \"subu %?r0,%1,%0\";
1903: }")
1904:
1905: (define_insn "one_cmplsi2"
1906: [(set (match_operand:SI 0 "general_operand" "=r")
1907: (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1908: ""
1909: "*
1910: {
1911: CC_STATUS_PARTIAL_INIT;
1912: return \"subu -1,%1,%0\";
1913: }")
1914:
1915: ;; Floating point arithmetic instructions.
1916:
1917: (define_insn "adddf3"
1918: [(set (match_operand:DF 0 "register_operand" "=f")
1919: (plus:DF (match_operand:DF 1 "register_operand" "f")
1920: (match_operand:DF 2 "register_operand" "f")))]
1921: ""
1922: "fadd.dd %1,%2,%0")
1923:
1924: (define_insn "addsf3"
1925: [(set (match_operand:SF 0 "register_operand" "=f")
1926: (plus:SF (match_operand:SF 1 "register_operand" "f")
1927: (match_operand:SF 2 "register_operand" "f")))]
1928: ""
1929: "fadd.ss %1,%2,%0")
1930:
1931: (define_insn "subdf3"
1932: [(set (match_operand:DF 0 "register_operand" "=f")
1933: (minus:DF (match_operand:DF 1 "register_operand" "f")
1934: (match_operand:DF 2 "register_operand" "f")))]
1935: ""
1936: "fsub.dd %1,%2,%0")
1937:
1938: (define_insn "subsf3"
1939: [(set (match_operand:SF 0 "register_operand" "=f")
1940: (minus:SF (match_operand:SF 1 "register_operand" "f")
1941: (match_operand:SF 2 "register_operand" "f")))]
1942: ""
1943: "fsub.ss %1,%2,%0")
1944:
1945: (define_insn "muldf3"
1946: [(set (match_operand:DF 0 "register_operand" "=f")
1947: (mult:DF (match_operand:DF 1 "register_operand" "f")
1948: (match_operand:DF 2 "register_operand" "f")))]
1949: ""
1950: "fmul.dd %1,%2,%0")
1951:
1952: (define_insn "mulsf3"
1953: [(set (match_operand:SF 0 "register_operand" "=f")
1954: (mult:SF (match_operand:SF 1 "register_operand" "f")
1955: (match_operand:SF 2 "register_operand" "f")))]
1956: ""
1957: "fmul.ss %1,%2,%0")
1958:
1959: (define_insn "negdf2"
1960: [(set (match_operand:DF 0 "register_operand" "=f")
1961: (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1962: ""
1963: "fsub.dd %?f0,%1,%0")
1964:
1965: (define_insn "negsf2"
1966: [(set (match_operand:SF 0 "register_operand" "=f")
1967: (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1968: ""
1969: "fsub.ss %?f0,%1,%0")
1970:
1971: (define_insn "divdf3"
1972: [(set (match_operand:DF 0 "register_operand" "=&f")
1973: (div:DF (match_operand:DF 1 "register_operand" "f")
1974: (match_operand:DF 2 "register_operand" "f")))
1975: (clobber (match_scratch:DF 3 "=&f"))
1976: (clobber (match_scratch:DF 4 "=&f"))]
1977: ""
1978: "*
1979: {
1980: CC_STATUS_PARTIAL_INIT;
1981: if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1982: || (cc_prev_status.flags & CC_HI_R31_ADJ)
1983: || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1984: {
1985: cc_status.flags |= CC_KNOW_HI_R31;
1986: cc_status.flags &= ~CC_HI_R31_ADJ;
1987: cc_status.mdep = CONST2_RTX (SFmode);
1988: return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1989: orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1990: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1991: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1992: fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1993: }
1994: else
1995: return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1996: ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1997: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1998: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1999: fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
2000: }")
2001:
2002: (define_insn "divsf3"
2003: [(set (match_operand:SF 0 "register_operand" "=&f")
2004: (div:SF (match_operand:SF 1 "register_operand" "f")
2005: (match_operand:SF 2 "register_operand" "f")))
2006: (clobber (match_scratch:SF 3 "=&f"))
2007: (clobber (match_scratch:SF 4 "=&f"))]
2008: ""
2009: "*
2010: {
2011: CC_STATUS_PARTIAL_INIT;
2012: if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
2013: || (cc_prev_status.flags & CC_HI_R31_ADJ)
2014: || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
2015: {
2016: cc_status.flags |= CC_KNOW_HI_R31;
2017: cc_status.flags &= ~CC_HI_R31_ADJ;
2018: cc_status.mdep = CONST2_RTX (SFmode);
2019: output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands);
2020: }
2021: return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\\
2022: fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\\
2023: fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\\
2024: fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\";
2025: }")
2026:
2027: ;; Shift instructions
2028:
2029: ;; Optimized special case of shifting.
2030: ;; Must precede the general case.
2031:
2032: (define_insn ""
2033: [(set (match_operand:SI 0 "register_operand" "=r")
2034: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2035: (const_int 24)))]
2036: ""
2037: "*
2038: {
2039: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
2040: {
2041: CC_STATUS_INIT;
2042: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
2043: cc_status.mdep = XEXP (operands[1], 0);
2044: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
2045: }
2046: return \"ld.b %1,%0\";
2047: }")
2048:
2049:
2050: ;;- arithmetic shift instructions
2051: (define_insn "ashlsi3"
2052: [(set (match_operand:SI 0 "register_operand" "=r")
2053: (ashift:SI (match_operand:SI 1 "register_operand" "r")
2054: (match_operand:SI 2 "shift_operand" "rn")))]
2055: ""
2056: "*
2057: {
2058: return \"shl %2,%1,%0\";
2059: }")
2060:
2061: (define_insn "ashlhi3"
2062: [(set (match_operand:HI 0 "register_operand" "=r")
2063: (ashift:HI (match_operand:HI 1 "register_operand" "r")
2064: (match_operand:HI 2 "shift_operand" "rn")))]
2065: ""
2066: "*
2067: {
2068: return \"shl %2,%1,%0\";
2069: }")
2070:
2071: (define_insn "ashlqi3"
2072: [(set (match_operand:QI 0 "register_operand" "=r")
2073: (ashift:QI (match_operand:QI 1 "register_operand" "r")
2074: (match_operand:QI 2 "shift_operand" "rn")))]
2075: ""
2076: "*
2077: {
2078: return \"shl %2,%1,%0\";
2079: }")
2080:
2081: (define_insn "ashrsi3"
2082: [(set (match_operand:SI 0 "register_operand" "=r")
2083: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2084: (match_operand:SI 2 "shift_operand" "rn")))]
2085: ""
2086: "*
2087: {
2088: return \"shra %2,%1,%0\";
2089: }")
2090:
2091: (define_insn "lshrsi3"
2092: [(set (match_operand:SI 0 "register_operand" "=r")
2093: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2094: (match_operand:SI 2 "shift_operand" "rn")))]
2095: ""
2096: "*
2097: {
2098: return \"shr %2,%1,%0\";
2099: }")
2100:
2101: ;; Unconditional and other jump instructions
2102:
2103: (define_insn "jump"
2104: [(set (pc) (label_ref (match_operand 0 "" "")))]
2105: ""
2106: "*
2107: {
2108: return \"br %l0\;nop\";
2109: }")
2110:
2111: ;; Here are two simple peepholes which fill the delay slot of
2112: ;; an unconditional branch.
2113:
2114: (define_peephole
2115: [(set (match_operand:SI 0 "register_operand" "=rf")
2116: (match_operand:SI 1 "single_insn_src_p" "gfG"))
2117: (set (pc) (label_ref (match_operand 2 "" "")))]
2118: ""
2119: "* return output_delayed_branch (\"br %l2\", operands, insn);")
2120:
2121: (define_peephole
2122: [(set (match_operand:SI 0 "memory_operand" "=m")
2123: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2124: (set (pc) (label_ref (match_operand 2 "" "")))]
2125: ""
2126: "* return output_delayed_branch (\"br %l2\", operands, insn);")
2127:
2128: (define_insn "tablejump"
2129: [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2130: (use (label_ref (match_operand 1 "" "")))]
2131: ""
2132: "bri %0\;nop")
2133:
2134: (define_peephole
2135: [(set (match_operand:SI 0 "memory_operand" "=m")
2136: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2137: (set (pc) (match_operand:SI 2 "register_operand" "r"))
2138: (use (label_ref (match_operand 3 "" "")))]
2139: ""
2140: "* return output_delayed_branch (\"bri %2\", operands, insn);")
2141:
2142: ;;- jump to subroutine
2143: (define_expand "call"
2144: [(call (match_operand:SI 0 "memory_operand" "m")
2145: (match_operand 1 "" "i"))]
2146: ;; operand[2] is next_arg_register
2147: ""
2148: "
2149: {
2150: if (INTVAL (operands[1]) > 0)
2151: {
2152: emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2153: emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2154: }
2155: }")
2156:
2157: ;;- jump to subroutine
2158: (define_insn ""
2159: [(call (match_operand:SI 0 "memory_operand" "m")
2160: (match_operand 1 "" "i"))]
2161: ;; operand[2] is next_arg_register
2162: ""
2163: "*
2164: {
2165: /* strip the MEM. */
2166: operands[0] = XEXP (operands[0], 0);
2167: CC_STATUS_INIT;
2168: if (GET_CODE (operands[0]) == REG)
2169: return \"calli %0\;nop\";
2170: return \"call %0\;nop\";
2171: }")
2172:
2173: (define_peephole
2174: [(set (match_operand:SI 0 "register_operand" "=rf")
2175: (match_operand:SI 1 "single_insn_src_p" "gfG"))
2176: (call (match_operand:SI 2 "memory_operand" "m")
2177: (match_operand 3 "" "i"))]
2178: ;;- Don't use operand 1 for most machines.
2179: "! reg_mentioned_p (operands[0], operands[2])"
2180: "*
2181: {
2182: /* strip the MEM. */
2183: operands[2] = XEXP (operands[2], 0);
2184: if (GET_CODE (operands[2]) == REG)
2185: return output_delayed_branch (\"calli %2\", operands, insn);
2186: return output_delayed_branch (\"call %2\", operands, insn);
2187: }")
2188:
2189: (define_peephole
2190: [(set (match_operand:SI 0 "memory_operand" "=m")
2191: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2192: (call (match_operand:SI 2 "memory_operand" "m")
2193: (match_operand 3 "" "i"))]
2194: ;;- Don't use operand 1 for most machines.
2195: ""
2196: "*
2197: {
2198: /* strip the MEM. */
2199: operands[2] = XEXP (operands[2], 0);
2200: if (GET_CODE (operands[2]) == REG)
2201: return output_delayed_branch (\"calli %2\", operands, insn);
2202: return output_delayed_branch (\"call %2\", operands, insn);
2203: }")
2204:
2205: (define_expand "call_value"
2206: [(set (match_operand 0 "register_operand" "=rf")
2207: (call (match_operand:SI 1 "memory_operand" "m")
2208: (match_operand 2 "" "i")))]
2209: ;; operand 3 is next_arg_register
2210: ""
2211: "
2212: {
2213: if (INTVAL (operands[2]) > 0)
2214: {
2215: emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2216: emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2217: }
2218: }")
2219:
2220: (define_insn ""
2221: [(set (match_operand 0 "register_operand" "=rf")
2222: (call (match_operand:SI 1 "memory_operand" "m")
2223: (match_operand 2 "" "i")))]
2224: ;; operand 3 is next_arg_register
2225: ""
2226: "*
2227: {
2228: /* strip the MEM. */
2229: operands[1] = XEXP (operands[1], 0);
2230: CC_STATUS_INIT;
2231: if (GET_CODE (operands[1]) == REG)
2232: return \"calli %1\;nop\";
2233: return \"call %1\;nop\";
2234: }")
2235:
2236: (define_peephole
2237: [(set (match_operand:SI 0 "register_operand" "=rf")
2238: (match_operand:SI 1 "single_insn_src_p" "gfG"))
2239: (set (match_operand 2 "" "=rf")
2240: (call (match_operand:SI 3 "memory_operand" "m")
2241: (match_operand 4 "" "i")))]
2242: ;;- Don't use operand 4 for most machines.
2243: "! reg_mentioned_p (operands[0], operands[3])"
2244: "*
2245: {
2246: /* strip the MEM. */
2247: operands[3] = XEXP (operands[3], 0);
2248: if (GET_CODE (operands[3]) == REG)
2249: return output_delayed_branch (\"calli %3\", operands, insn);
2250: return output_delayed_branch (\"call %3\", operands, insn);
2251: }")
2252:
2253: (define_peephole
2254: [(set (match_operand:SI 0 "memory_operand" "=m")
2255: (match_operand:SI 1 "reg_or_0_operand" "rJf"))
2256: (set (match_operand 2 "" "=rf")
2257: (call (match_operand:SI 3 "memory_operand" "m")
2258: (match_operand 4 "" "i")))]
2259: ;;- Don't use operand 4 for most machines.
2260: ""
2261: "*
2262: {
2263: /* strip the MEM. */
2264: operands[3] = XEXP (operands[3], 0);
2265: if (GET_CODE (operands[3]) == REG)
2266: return output_delayed_branch (\"calli %3\", operands, insn);
2267: return output_delayed_branch (\"call %3\", operands, insn);
2268: }")
2269:
2270: (define_insn "nop"
2271: [(const_int 0)]
2272: ""
2273: "nop")
2274:
2275: (define_insn "indirect_jump"
2276: [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2277: ""
2278: "bri %0")
2279:
2280: ;;
2281: ;; A special insn that does the work to get setup just
2282: ;; before a table jump.
2283: ;;
2284: (define_insn ""
2285: [(set (match_operand:SI 0 "register_operand" "=r")
2286: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2287: (label_ref (match_operand 2 "" "")))))]
2288: ""
2289: "*
2290: {
2291: CC_STATUS_INIT;
2292: return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\";
2293: }")
2294:
2295: (define_peephole
2296: [(set (match_operand:SI 0 "register_operand" "=rf")
2297: (match_operand:SI 1 "single_insn_src_p" "gfG"))
2298: (set (pc) (match_operand:SI 2 "register_operand" "r"))
2299: (use (label_ref (match_operand 3 "" "")))]
2300: "REGNO (operands[0]) != REGNO (operands[2])"
2301: "* return output_delayed_branch (\"bri %2\", operands, insn);")
2302:
2303: ;;- Local variables:
2304: ;;- mode:emacs-lisp
2305: ;;- comment-start: ";;- "
2306: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2307: ;;- eval: (modify-syntax-entry ?[ "(]")
2308: ;;- eval: (modify-syntax-entry ?] ")[")
2309: ;;- eval: (modify-syntax-entry ?{ "(}")
2310: ;;- eval: (modify-syntax-entry ?} "){")
2311: ;;- End:
2312:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.