|
|
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: ;; Note that it is wrong to add similar patterns for QI or HImode
501: ;; because bte/btne always compare the whole register.
502:
503: (define_insn ""
504: [(set (pc)
505: (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
506: (match_operand:SI 1 "bte_operand" "rK"))
507: (label_ref (match_operand 2 "" ""))
508: (pc)))]
509: ""
510: "bte %1,%0,%2")
511:
512: (define_insn ""
513: [(set (pc)
514: (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
515: (match_operand:SI 1 "bte_operand" "rK"))
516: (label_ref (match_operand 2 "" ""))
517: (pc)))]
518: ""
519: "btne %1,%0,%2")
520:
521: (define_insn ""
522: [(set (pc)
523: (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
524: (match_operand:SI 1 "bte_operand" "rK"))
525: (pc)
526: (label_ref (match_operand 2 "" ""))))]
527: ""
528: "btne %1,%0,%2")
529:
530: (define_insn ""
531: [(set (pc)
532: (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
533: (match_operand:SI 1 "bte_operand" "rK"))
534: (pc)
535: (label_ref (match_operand 2 "" ""))))]
536: ""
537: "bte %1,%0,%2")
538:
539: ;; Load byte/halfword, zero-extend, & compare-and-branch insns.
540: ;; These are made by combining.
541:
542: (define_insn ""
543: [(set (pc)
544: (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
545: (match_operand:SI 1 "bte_operand" "K"))
546: (label_ref (match_operand 2 "" ""))
547: (pc)))
548: (match_scratch:SI 3 "=r")]
549: ""
550: "ld.b %0,%3;bte %1,%3,%2")
551:
552: (define_insn ""
553: [(set (pc)
554: (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
555: (match_operand:SI 1 "bte_operand" "K"))
556: (label_ref (match_operand 2 "" ""))
557: (pc)))
558: (match_scratch:SI 3 "=r")]
559: ""
560: "ld.b %0,%3;btne %1,%3,%2")
561:
562: (define_insn ""
563: [(set (pc)
564: (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
565: (match_operand:SI 1 "bte_operand" "K"))
566: (pc)
567: (label_ref (match_operand 2 "" ""))))
568: (match_scratch:SI 3 "=r")]
569: ""
570: "ld.b %0,%3;btne %1,%3,%2")
571:
572: (define_insn ""
573: [(set (pc)
574: (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
575: (match_operand:SI 1 "bte_operand" "K"))
576: (pc)
577: (label_ref (match_operand 2 "" ""))))
578: (match_scratch:SI 3 "=r")]
579: ""
580: "ld.b %0,%3;bte %1,%3,%2")
581:
582: (define_insn ""
583: [(set (pc)
584: (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
585: (match_operand:SI 1 "bte_operand" "K"))
586: (label_ref (match_operand 2 "" ""))
587: (pc)))
588: (match_scratch:SI 3 "=r")]
589: ""
590: "ld.s %0,%3;bte %1,%3,%2")
591:
592: (define_insn ""
593: [(set (pc)
594: (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
595: (match_operand:SI 1 "bte_operand" "K"))
596: (label_ref (match_operand 2 "" ""))
597: (pc)))
598: (match_scratch:SI 3 "=r")]
599: ""
600: "ld.s %0,%3;btne %1,%3,%2")
601:
602: (define_insn ""
603: [(set (pc)
604: (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
605: (match_operand:SI 1 "bte_operand" "K"))
606: (pc)
607: (label_ref (match_operand 2 "" ""))))
608: (match_scratch:SI 3 "=r")]
609: ""
610: "ld.s %0,%3;btne %1,%3,%2")
611:
612: (define_insn ""
613: [(set (pc)
614: (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
615: (match_operand:SI 1 "bte_operand" "K"))
616: (pc)
617: (label_ref (match_operand 2 "" ""))))
618: (match_scratch:SI 3 "=r")]
619: ""
620: "ld.s %0,%3;bte %1,%3,%2")
621:
622:
623: ;; Generation of conditionals.
624:
625: ;; We save the compare operands in the cmpxx patterns and use then when
626: ;; we generate the branch.
627:
628: (define_expand "cmpsi"
629: [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
630: (match_operand:SI 1 "compare_operand" "")))]
631: ""
632: "
633: { i860_compare_op0 = operands[0];
634: i860_compare_op1 = operands[1];
635: DONE;
636: }")
637:
638: (define_expand "cmpsf"
639: [(set (cc0) (compare (match_operand:SF 0 "register_operand" "")
640: (match_operand:SF 1 "register_operand" "")))]
641: ""
642: "
643: { i860_compare_op0 = operands[0];
644: i860_compare_op1 = operands[1];
645: DONE;
646: }")
647:
648: (define_expand "cmpdf"
649: [(set (cc0) (compare (match_operand:DF 0 "register_operand" "")
650: (match_operand:DF 1 "register_operand" "")))]
651: ""
652: "
653: { i860_compare_op0 = operands[0];
654: i860_compare_op1 = operands[1];
655: DONE;
656: }")
657:
658: ;; These are the standard-named conditional branch patterns.
659: ;; Detailed comments are found in the first one only.
660:
661: (define_expand "beq"
662: [(set (pc)
663: (if_then_else (eq (cc0)
664: (const_int 0))
665: (label_ref (match_operand 0 "" ""))
666: (pc)))]
667: ""
668: "
669: {
670: /* Emit a single-condition compare insn according to
671: the type of operands and the condition to be tested. */
672:
673: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
674: emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
675: else if (GET_MODE (i860_compare_op0) == SFmode)
676: emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
677: else if (GET_MODE (i860_compare_op0) == DFmode)
678: emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
679: else
680: abort ();
681:
682: /* Emit branch-if-true. */
683:
684: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
685: DONE;
686: }")
687:
688: (define_expand "bne"
689: [(set (pc)
690: (if_then_else (ne (cc0)
691: (const_int 0))
692: (label_ref (match_operand 0 "" ""))
693: (pc)))]
694: ""
695: "
696: {
697: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
698: emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
699: else if (GET_MODE (i860_compare_op0) == SFmode)
700: emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
701: else if (GET_MODE (i860_compare_op0) == DFmode)
702: emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
703: else
704: abort ();
705:
706: emit_jump_insn (gen_flipped_cbranch (operands[0]));
707:
708: DONE;
709: }")
710:
711: (define_expand "bgt"
712: [(set (pc)
713: (if_then_else (gt (cc0)
714: (const_int 0))
715: (label_ref (match_operand 0 "" ""))
716: (pc)))]
717: ""
718: "
719: {
720: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
721: emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
722: else if (GET_MODE (i860_compare_op0) == SFmode)
723: emit_insn (gen_cmpgtsf (i860_compare_op0, i860_compare_op1));
724: else if (GET_MODE (i860_compare_op0) == DFmode)
725: emit_insn (gen_cmpgtdf (i860_compare_op0, i860_compare_op1));
726: else
727: abort ();
728:
729: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
730: DONE;
731: }")
732:
733: (define_expand "blt"
734: [(set (pc)
735: (if_then_else (lt (cc0)
736: (const_int 0))
737: (label_ref (match_operand 0 "" ""))
738: (pc)))]
739: ""
740: "
741: {
742: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
743: emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
744: else if (GET_MODE (i860_compare_op0) == SFmode)
745: emit_insn (gen_cmpltsf (i860_compare_op0, i860_compare_op1));
746: else if (GET_MODE (i860_compare_op0) == DFmode)
747: emit_insn (gen_cmpltdf (i860_compare_op0, i860_compare_op1));
748: else
749: abort ();
750:
751: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
752: DONE;
753: }")
754:
755: (define_expand "ble"
756: [(set (pc)
757: (if_then_else (le (cc0)
758: (const_int 0))
759: (label_ref (match_operand 0 "" ""))
760: (pc)))]
761: ""
762: "
763: {
764: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
765: {
766: emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
767: emit_jump_insn (gen_flipped_cbranch (operands[0]));
768: }
769: else
770: {
771: if (GET_MODE (i860_compare_op0) == SFmode)
772: emit_insn (gen_cmplesf (i860_compare_op0, i860_compare_op1));
773: else if (GET_MODE (i860_compare_op0) == DFmode)
774: emit_insn (gen_cmpledf (i860_compare_op0, i860_compare_op1));
775: else
776: abort ();
777: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
778: }
779: DONE;
780: }")
781:
782: (define_expand "bge"
783: [(set (pc)
784: (if_then_else (ge (cc0)
785: (const_int 0))
786: (label_ref (match_operand 0 "" ""))
787: (pc)))]
788: ""
789: "
790: {
791: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
792: {
793: emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
794: emit_jump_insn (gen_flipped_cbranch (operands[0]));
795: }
796: else
797: {
798: if (GET_MODE (i860_compare_op0) == SFmode)
799: emit_insn (gen_cmpgesf (i860_compare_op0, i860_compare_op1));
800: else if (GET_MODE (i860_compare_op0) == DFmode)
801: emit_insn (gen_cmpgedf (i860_compare_op0, i860_compare_op1));
802: else
803: abort ();
804: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
805: }
806: DONE;
807: }")
808:
809: (define_expand "bgtu"
810: [(set (pc)
811: (if_then_else (gtu (cc0)
812: (const_int 0))
813: (label_ref (match_operand 0 "" ""))
814: (pc)))]
815: ""
816: "
817: {
818: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
819: abort ();
820:
821: emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
822: emit_jump_insn (gen_flipped_cbranch (operands[0]));
823: DONE;
824: }")
825:
826: (define_expand "bltu"
827: [(set (pc)
828: (if_then_else (ltu (cc0)
829: (const_int 0))
830: (label_ref (match_operand 0 "" ""))
831: (pc)))]
832: ""
833: "
834: {
835: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
836: abort ();
837:
838: emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
839: emit_jump_insn (gen_flipped_cbranch (operands[0]));
840: DONE;
841: }")
842:
843: (define_expand "bgeu"
844: [(set (pc)
845: (if_then_else (geu (cc0)
846: (const_int 0))
847: (label_ref (match_operand 0 "" ""))
848: (pc)))]
849: ""
850: "
851: {
852: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
853: abort ();
854:
855: emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
856: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
857: DONE;
858: }")
859:
860: (define_expand "bleu"
861: [(set (pc)
862: (if_then_else (leu (cc0)
863: (const_int 0))
864: (label_ref (match_operand 0 "" ""))
865: (pc)))]
866: ""
867: "
868: {
869: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
870: abort ();
871:
872: emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
873: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
874: DONE;
875: }")
876:
877: ;; Move instructions
878:
879: ;; Note that source operands for `mov' pseudo-instructions are no longer
880: ;; allowed (by the svr4 assembler) to be "big" things, i.e. constants that
881: ;; won't fit in 16-bits. (This includes any sort of a relocatable address
882: ;; also.) Thus, we must use an explicit orh/or pair of instructions if
883: ;; the source operand is something "big".
884:
885: (define_insn "movsi"
886: [(set (match_operand:SI 0 "general_operand" "=r,m,f")
887: (match_operand:SI 1 "general_operand" "rmif,rfJ,rmfJ"))]
888: ""
889: "*
890: {
891: if (GET_CODE (operands[0]) == MEM)
892: {
893: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
894: return output_store (operands);
895: if (FP_REG_P (operands[1]))
896: return \"fst.l %1,%0\";
897: return \"st.l %r1,%0\";
898: }
899: if (GET_CODE (operands[1]) == MEM)
900: {
901: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
902: return output_load (operands);
903: if (FP_REG_P (operands[0]))
904: return \"fld.l %1,%0\";
905: return \"ld.l %1,%0\";
906: }
907: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
908: return \"fmov.ss %1,%0\";
909: if (FP_REG_P (operands[1]))
910: return \"fxfr %1,%0\";
911: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
912: return \"fmov.ss %?f0,%0\";
913: if (FP_REG_P (operands[0]))
914: return \"ixfr %1,%0\";
915:
916: if (GET_CODE (operands[1]) == REG)
917: return \"shl %?r0,%1,%0\";
918:
919: CC_STATUS_PARTIAL_INIT;
920:
921: if (GET_CODE (operands[1]) == CONST_INT)
922: {
923: if((INTVAL (operands[1]) & 0xffff0000) == 0)
924: return \"or %L1,%?r0,%0\";
925: if((INTVAL (operands[1]) & 0x0000ffff) == 0)
926: return \"orh %H1,%?r0,%0\";
927: }
928: return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
929: }")
930:
931: (define_insn "movhi"
932: [(set (match_operand:HI 0 "general_operand" "=r,m,!*f,!r")
933: (match_operand:HI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
934: ""
935: "*
936: {
937: if (GET_CODE (operands[0]) == MEM)
938: {
939: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
940: return output_store (operands);
941: return \"st.s %r1,%0\";
942: }
943: if (GET_CODE (operands[1]) == MEM)
944: {
945: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
946: return output_load (operands);
947: return \"ld.s %1,%0\";
948: }
949: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
950: return \"fmov.ss %1,%0\";
951: if (FP_REG_P (operands[1]))
952: return \"fxfr %1,%0\";
953: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
954: return \"fmov.ss %?f0,%0\";
955: if (FP_REG_P (operands[0]))
956: return \"ixfr %1,%0\";
957:
958: if (GET_CODE (operands[1]) == REG)
959: return \"shl %?r0,%1,%0\";
960:
961: CC_STATUS_PARTIAL_INIT;
962:
963: return \"or %L1,%?r0,%0\";
964: }")
965:
966: (define_insn "movqi"
967: [(set (match_operand:QI 0 "general_operand" "=r,m,!*f,!r")
968: (match_operand:QI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
969: ""
970: "*
971: {
972: if (GET_CODE (operands[0]) == MEM)
973: {
974: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
975: return output_store (operands);
976: return \"st.b %r1,%0\";
977: }
978: if (GET_CODE (operands[1]) == MEM)
979: {
980: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
981: return output_load (operands);
982: return \"ld.b %1,%0\";
983: }
984: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
985: return \"fmov.ss %1,%0\";
986: if (FP_REG_P (operands[1]))
987: return \"fxfr %1,%0\";
988: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
989: return \"fmov.ss %?f0,%0\";
990: if (FP_REG_P (operands[0]))
991: return \"ixfr %1,%0\";
992:
993: if (GET_CODE (operands[1]) == REG)
994: return \"shl %?r0,%1,%0\";
995:
996: CC_STATUS_PARTIAL_INIT;
997:
998: return \"or %L1,%?r0,%0\";
999: }")
1000:
1001: ;; The definition of this insn does not really explain what it does,
1002: ;; but it should suffice
1003: ;; that anything generated as this insn will be recognized as one
1004: ;; and that it won't successfully combine with anything.
1005: (define_expand "movstrsi"
1006: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1007: (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1008: (use (match_operand:SI 2 "nonmemory_operand" ""))
1009: (use (match_operand:SI 3 "immediate_operand" ""))
1010: (clobber (match_dup 4))
1011: (clobber (match_dup 5))
1012: (clobber (match_dup 6))
1013: (clobber (match_dup 0))
1014: (clobber (match_dup 1))])]
1015: ""
1016: "
1017: {
1018: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1019: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1020: operands[4] = gen_reg_rtx (SImode);
1021: operands[5] = gen_reg_rtx (SImode);
1022: operands[6] = gen_reg_rtx (SImode);
1023: }")
1024:
1025: (define_insn ""
1026: [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1027: (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1028: (use (match_operand:SI 2 "general_operand" "rn"))
1029: (use (match_operand:SI 3 "immediate_operand" "i"))
1030: (clobber (match_operand:SI 4 "register_operand" "=r"))
1031: (clobber (match_operand:SI 5 "register_operand" "=r"))
1032: (clobber (match_operand:SI 6 "register_operand" "=r"))
1033: (clobber (match_dup 0))
1034: (clobber (match_dup 1))]
1035: ""
1036: "* return output_block_move (operands);")
1037:
1038: ;; Floating point move insns
1039:
1040: ;; This pattern forces (set (reg:DF ...) (const_double ...))
1041: ;; to be reloaded by putting the constant into memory.
1042: ;; It must come before the more general movdf pattern.
1043: (define_insn ""
1044: [(set (match_operand:DF 0 "general_operand" "=r,f,o")
1045: (match_operand:DF 1 "" "mG,m,G"))]
1046: "GET_CODE (operands[1]) == CONST_DOUBLE"
1047: "*
1048: {
1049: if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode))
1050: return output_fp_move_double (operands);
1051: return output_move_double (operands);
1052: }")
1053:
1054: (define_insn "movdf"
1055: [(set (match_operand:DF 0 "general_operand" "=*rm,*r,?f,?*rm")
1056: (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))]
1057: ""
1058: "*
1059: {
1060: if (GET_CODE (operands[0]) == MEM
1061: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1062: return output_store (operands);
1063: if (GET_CODE (operands[1]) == MEM
1064: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1065: return output_load (operands);
1066:
1067: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1068: return output_fp_move_double (operands);
1069: return output_move_double (operands);
1070: }")
1071:
1072: (define_insn "movdi"
1073: [(set (match_operand:DI 0 "general_operand" "=rm,r,?f,?rm")
1074: (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))]
1075: ""
1076: "*
1077: {
1078: if (GET_CODE (operands[0]) == MEM
1079: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1080: return output_store (operands);
1081: if (GET_CODE (operands[1]) == MEM
1082: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1083: return output_load (operands);
1084:
1085: /* ??? How can we have a DFmode arg here with DImode above? */
1086: if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode))
1087: return \"fmov.dd %?f0,%0\";
1088:
1089: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1090: return output_fp_move_double (operands);
1091: return output_move_double (operands);
1092: }")
1093:
1094: ;; The alternative m/r is separate from m/f
1095: ;; The first alternative is separate from the second for the same reason.
1096: (define_insn "movsf"
1097: [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m")
1098: (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))]
1099: ""
1100: "*
1101: {
1102: if (GET_CODE (operands[0]) == MEM
1103: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1104: return output_store (operands);
1105: if (GET_CODE (operands[1]) == MEM
1106: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1107: return output_load (operands);
1108: if (FP_REG_P (operands[0]))
1109: {
1110: if (FP_REG_P (operands[1]))
1111: return \"fmov.ss %1,%0\";
1112: if (GET_CODE (operands[1]) == REG)
1113: return \"ixfr %1,%0\";
1114: if (operands[1] == CONST0_RTX (SFmode))
1115: return \"fmov.ss %?f0,%0\";
1116: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1117: {
1118: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1119: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1120: && cc_prev_status.mdep == XEXP(operands[1],0)))
1121: {
1122: CC_STATUS_INIT;
1123: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1124: cc_status.mdep = XEXP (operands[1], 0);
1125: return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\";
1126: }
1127: return \"fld.l %L1(%?r31),%0\";
1128: }
1129: return \"fld.l %1,%0\";
1130: }
1131: if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
1132: {
1133: if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1]))
1134: return \"fxfr %1,%0\";
1135: if (GET_CODE (operands[0]) == REG)
1136: {
1137: CC_STATUS_PARTIAL_INIT;
1138: if (GET_CODE (operands[1]) == CONST_DOUBLE)
1139: {
1140: register unsigned long ul;
1141:
1142: ul = sfmode_constant_to_ulong (operands[1]);
1143: if ((ul & 0x0000ffff) == 0)
1144: return \"orh %H1,%?r0,%0\";
1145: if ((ul & 0xffff0000) == 0)
1146: return \"or %L1,%?r0,%0\";
1147: }
1148: return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
1149: }
1150: /* Now operand 0 must be memory.
1151: If operand 1 is CONST_DOUBLE, its value must be 0. */
1152: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1153: {
1154: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1155: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1156: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1157: {
1158: CC_STATUS_INIT;
1159: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1160: cc_status.mdep = XEXP (operands[0], 0);
1161: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1162: }
1163: return \"fst.l %r1,%L0(%?r31)\";
1164: }
1165: return \"fst.l %r1,%0\";
1166: }
1167: if (GET_CODE (operands[0]) == MEM)
1168: return \"st.l %r1,%0\";
1169: if (GET_CODE (operands[1]) == MEM)
1170: return \"ld.l %1,%0\";
1171: if (operands[1] == CONST0_RTX (SFmode))
1172: return \"shl %?r0,%?r0,%0\";
1173: return \"mov %1,%0\";
1174: }")
1175:
1176: ;; Special load insns for REG+REG addresses.
1177: ;; Such addresses are not "legitimate" because st rejects them.
1178:
1179: (define_insn ""
1180: [(set (match_operand:DF 0 "register_operand" "=rf")
1181: (match_operand:DF 1 "indexed_operand" "m"))]
1182: ""
1183: "*
1184: {
1185: if (FP_REG_P (operands[0]))
1186: return output_fp_move_double (operands);
1187: return output_move_double (operands);
1188: }")
1189:
1190: (define_insn ""
1191: [(set (match_operand:SF 0 "register_operand" "=rf")
1192: (match_operand:SF 1 "indexed_operand" "m"))]
1193: ""
1194: "*
1195: {
1196: if (FP_REG_P (operands[0]))
1197: return \"fld.l %1,%0\";
1198: return \"ld.l %1,%0\";
1199: }")
1200:
1201: (define_insn ""
1202: [(set (match_operand:SI 0 "register_operand" "=rf")
1203: (match_operand:SI 1 "indexed_operand" "m"))]
1204: ""
1205: "*
1206: {
1207: if (FP_REG_P (operands[0]))
1208: return \"fld.l %1,%0\";
1209: return \"ld.l %1,%0\";
1210: }")
1211:
1212: (define_insn ""
1213: [(set (match_operand:HI 0 "register_operand" "=r")
1214: (match_operand:HI 1 "indexed_operand" "m"))]
1215: ""
1216: "ld.s %1,%0")
1217:
1218: (define_insn ""
1219: [(set (match_operand:QI 0 "register_operand" "=r")
1220: (match_operand:QI 1 "indexed_operand" "m"))]
1221: ""
1222: "ld.b %1,%0")
1223:
1224: ;; Likewise for floating-point store insns.
1225:
1226: (define_insn ""
1227: [(set (match_operand:DF 0 "indexed_operand" "=m")
1228: (match_operand:DF 1 "register_operand" "f"))]
1229: ""
1230: "fst.d %1,%0")
1231:
1232: (define_insn ""
1233: [(set (match_operand:SF 0 "indexed_operand" "=m")
1234: (match_operand:SF 1 "register_operand" "f"))]
1235: ""
1236: "fst.l %1,%0")
1237:
1238: ;;- truncation instructions
1239: (define_insn "truncsiqi2"
1240: [(set (match_operand:QI 0 "general_operand" "=g")
1241: (truncate:QI
1242: (match_operand:SI 1 "register_operand" "r")))]
1243: ""
1244: "*
1245: {
1246: if (GET_CODE (operands[0]) == MEM)
1247: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1248: {
1249: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1250: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1251: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1252: {
1253: CC_STATUS_INIT;
1254: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1255: cc_status.mdep = XEXP (operands[0], 0);
1256: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1257: }
1258: return \"st.b %1,%L0(%?r31)\";
1259: }
1260: else
1261: return \"st.b %1,%0\";
1262: return \"shl %?r0,%1,%0\";
1263: }")
1264:
1265: (define_insn "trunchiqi2"
1266: [(set (match_operand:QI 0 "general_operand" "=g")
1267: (truncate:QI
1268: (match_operand:HI 1 "register_operand" "r")))]
1269: ""
1270: "*
1271: {
1272: if (GET_CODE (operands[0]) == MEM)
1273: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1274: {
1275: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1276: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1277: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1278: {
1279: CC_STATUS_INIT;
1280: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1281: cc_status.mdep = XEXP (operands[0], 0);
1282: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1283: }
1284: return \"st.b %1,%L0(%?r31)\";
1285: }
1286: else
1287: return \"st.b %1,%0\";
1288: return \"shl %?r0,%1,%0\";
1289: }")
1290:
1291: (define_insn "truncsihi2"
1292: [(set (match_operand:HI 0 "general_operand" "=g")
1293: (truncate:HI
1294: (match_operand:SI 1 "register_operand" "r")))]
1295: ""
1296: "*
1297: {
1298: if (GET_CODE (operands[0]) == MEM)
1299: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1300: {
1301: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1302: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1303: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1304: {
1305: CC_STATUS_INIT;
1306: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1307: cc_status.mdep = XEXP (operands[0], 0);
1308: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1309: }
1310: return \"st.s %1,%L0(%?r31)\";
1311: }
1312: else
1313: return \"st.s %1,%0\";
1314: return \"shl %?r0,%1,%0\";
1315: }")
1316:
1317: ;;- zero extension instructions
1318:
1319: (define_insn "zero_extendhisi2"
1320: [(set (match_operand:SI 0 "register_operand" "=r")
1321: (zero_extend:SI
1322: (match_operand:HI 1 "register_operand" "r")))]
1323: ""
1324: "*
1325: {
1326: CC_STATUS_PARTIAL_INIT;
1327: return \"and 0xffff,%1,%0\";
1328: }")
1329:
1330: (define_insn "zero_extendqihi2"
1331: [(set (match_operand:HI 0 "register_operand" "=r")
1332: (zero_extend:HI
1333: (match_operand:QI 1 "register_operand" "r")))]
1334: ""
1335: "*
1336: {
1337: CC_STATUS_PARTIAL_INIT;
1338: return \"and 0xff,%1,%0\";
1339: }")
1340:
1341: (define_insn "zero_extendqisi2"
1342: [(set (match_operand:SI 0 "register_operand" "=r")
1343: (zero_extend:SI
1344: (match_operand:QI 1 "register_operand" "r")))]
1345: ""
1346: "*
1347: {
1348: CC_STATUS_PARTIAL_INIT;
1349: return \"and 0xff,%1,%0\";
1350: }")
1351:
1352: ;; Sign extension instructions.
1353:
1354: (define_insn ""
1355: [(set (match_operand:SI 0 "register_operand" "=r")
1356: (sign_extend:SI
1357: (match_operand:HI 1 "indexed_operand" "m")))]
1358: ""
1359: "ld.s %1,%0")
1360:
1361: (define_insn ""
1362: [(set (match_operand:HI 0 "register_operand" "=r")
1363: (sign_extend:HI
1364: (match_operand:QI 1 "indexed_operand" "m")))]
1365: ""
1366: "ld.b %1,%0")
1367:
1368: (define_insn ""
1369: [(set (match_operand:SI 0 "register_operand" "=r")
1370: (sign_extend:SI
1371: (match_operand:QI 1 "indexed_operand" "m")))]
1372: ""
1373: "ld.b %1,%0")
1374:
1375: (define_insn "extendhisi2"
1376: [(set (match_operand:SI 0 "register_operand" "=r")
1377: (sign_extend:SI
1378: (match_operand:HI 1 "nonimmediate_operand" "mr")))]
1379: ""
1380: "*
1381: {
1382: if (REG_P (operands[1]))
1383: return \"shl 16,%1,%0\;shra 16,%0,%0\";
1384: if (GET_CODE (operands[1]) == CONST_INT)
1385: abort ();
1386: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1387: {
1388: CC_STATUS_INIT;
1389: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1390: cc_status.mdep = XEXP (operands[1], 0);
1391: return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\";
1392: }
1393: else
1394: return \"ld.s %1,%0\";
1395: }")
1396:
1397: (define_insn "extendqihi2"
1398: [(set (match_operand:HI 0 "register_operand" "=r")
1399: (sign_extend:HI
1400: (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1401: ""
1402: "*
1403: {
1404: if (REG_P (operands[1]))
1405: return \"shl 24,%1,%0\;shra 24,%0,%0\";
1406: if (GET_CODE (operands[1]) == CONST_INT)
1407: abort ();
1408: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1409: {
1410: CC_STATUS_INIT;
1411: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1412: cc_status.mdep = XEXP (operands[1], 0);
1413: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1414: }
1415: else
1416: return \"ld.b %1,%0\";
1417: }")
1418:
1419: (define_insn "extendqisi2"
1420: [(set (match_operand:SI 0 "register_operand" "=r")
1421: (sign_extend:SI
1422: (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1423: ""
1424: "*
1425: {
1426: if (REG_P (operands[1]))
1427: return \"shl 24,%1,%0\;shra 24,%0,%0\";
1428: if (GET_CODE (operands[1]) == CONST_INT)
1429: abort ();
1430: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1431: {
1432: CC_STATUS_INIT;
1433: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1434: cc_status.mdep = XEXP (operands[1], 0);
1435: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1436: }
1437: else
1438: return \"ld.b %1,%0\";
1439: }")
1440:
1441: ;; Signed bitfield extractions come out looking like
1442: ;; (shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
1443: ;; which we expand poorly as four shift insns.
1444: ;; These patters yeild two shifts:
1445: ;; (shiftrt (shift <Y> <C3>) <C4>)
1446: (define_insn ""
1447: [(set (match_operand:SI 0 "register_operand" "=r")
1448: (ashiftrt:SI
1449: (sign_extend:SI
1450: (match_operand:QI 1 "register_operand" "r"))
1451: (match_operand:SI 2 "logic_int" "n")))]
1452: "INTVAL (operands[2]) < 8"
1453: "*
1454: {
1455: return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
1456: }")
1457:
1458: (define_insn ""
1459: [(set (match_operand:SI 0 "register_operand" "=r")
1460: (ashiftrt:SI
1461: (sign_extend:SI
1462: (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1463: (match_operand:SI 2 "logic_int" "n")) 0))
1464: (match_operand:SI 3 "logic_int" "n")))]
1465: "INTVAL (operands[3]) < 8"
1466: "*
1467: {
1468: return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1469: }")
1470:
1471: (define_insn ""
1472: [(set (match_operand:SI 0 "register_operand" "=r")
1473: (ashiftrt:SI
1474: (sign_extend:SI
1475: (ashift:QI (match_operand:QI 1 "register_operand" "r")
1476: (match_operand:QI 2 "logic_int" "n")))
1477: (match_operand:SI 3 "logic_int" "n")))]
1478: "INTVAL (operands[3]) < 8"
1479: "*
1480: {
1481: return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1482: }")
1483:
1484: ;; Special patterns for optimizing bit-field instructions.
1485:
1486: ;; First two patterns are for bitfields that came from memory
1487: ;; testing only the high bit. They work with old combiner.
1488:
1489: (define_insn ""
1490: [(set (cc0)
1491: (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1492: (const_int 7)) 0))
1493: (const_int 0)))]
1494: ""
1495: "*
1496: {
1497: CC_STATUS_PARTIAL_INIT;
1498: return \"and 128,%0,%?r0\";
1499: }")
1500:
1501: (define_insn ""
1502: [(set (cc0)
1503: (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1504: (const_int 7)) 0))
1505: (const_int 0)))]
1506: ""
1507: "*
1508: {
1509: CC_STATUS_PARTIAL_INIT;
1510: return \"and 128,%0,%?r0\";
1511: }")
1512:
1513: ;; next two patterns are good for bitfields coming from memory
1514: ;; (via pseudo-register) or from a register, though this optimization
1515: ;; is only good for values contained wholly within the bottom 13 bits
1516: (define_insn ""
1517: [(set (cc0)
1518: (eq
1519: (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1520: (match_operand:SI 1 "logic_int" "n"))
1521: (match_operand:SI 2 "logic_int" "n"))
1522: (const_int 0)))]
1523: "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1524: "*
1525: {
1526: CC_STATUS_PARTIAL_INIT;
1527: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1528: (INTVAL (operands[2]) << INTVAL (operands[1])));
1529: return \"and %2,%0,%?r0\";
1530: }")
1531:
1532: (define_insn ""
1533: [(set (cc0)
1534: (eq
1535: (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1536: (match_operand:SI 1 "logic_int" "n"))
1537: (match_operand:SI 2 "logic_int" "n"))
1538: (const_int 0)))]
1539: "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1540: "*
1541: {
1542: CC_STATUS_PARTIAL_INIT;
1543: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1544: (INTVAL (operands[2]) << INTVAL (operands[1])));
1545: return \"and %2,%0,%?r0\";
1546: }")
1547:
1548: ;; Conversions between float and double.
1549:
1550: (define_insn "extendsfdf2"
1551: [(set (match_operand:DF 0 "register_operand" "=f")
1552: (float_extend:DF
1553: (match_operand:SF 1 "register_operand" "f")))]
1554: ""
1555: "fmov.sd %1,%0")
1556:
1557: (define_insn "truncdfsf2"
1558: [(set (match_operand:SF 0 "register_operand" "=f")
1559: (float_truncate:SF
1560: (match_operand:DF 1 "register_operand" "f")))]
1561: ""
1562: "fmov.ds %1,%0")
1563:
1564: ;; Conversion between fixed point and floating point.
1565: ;; Note that among the fix-to-float insns
1566: ;; the ones that start with SImode come first.
1567: ;; That is so that an operand that is a CONST_INT
1568: ;; (and therefore lacks a specific machine mode).
1569: ;; will be recognized as SImode (which is always valid)
1570: ;; rather than as QImode or HImode.
1571:
1572: ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1573: ;; to be reloaded by putting the constant into memory.
1574: ;; It must come before the more general floatsisf2 pattern.
1575: (define_expand "floatsidf2"
1576: [(set (match_dup 2) (match_dup 3))
1577: (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
1578: (const_int -2147483648)))
1579: (set (match_dup 5) (match_dup 3))
1580: (set (subreg:SI (match_dup 5) 0) (match_dup 4))
1581: (set (match_operand:DF 0 "register_operand" "")
1582: (minus:DF (match_dup 5) (match_dup 2)))]
1583: ""
1584: "
1585: {
1586: REAL_VALUE_TYPE d;
1587: /* 4503601774854144 is (1 << 30) * ((1 << 22) + (1 << 1)). */
1588: d = REAL_VALUE_ATOF (\"4503601774854144\", DFmode);
1589: operands[2] = gen_reg_rtx (DFmode);
1590: operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode);
1591: operands[4] = gen_reg_rtx (SImode);
1592: operands[5] = gen_reg_rtx (DFmode);
1593: }")
1594:
1595: ;; Floating to fixed conversion.
1596:
1597: (define_expand "fix_truncdfsi2"
1598: ;; This first insn produces a double-word value
1599: ;; in which only the low word is valid.
1600: [(set (match_dup 2)
1601: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1602: (set (match_operand:SI 0 "register_operand" "=f")
1603: (subreg:SI (match_dup 2) 0))]
1604: ""
1605: "
1606: {
1607: operands[2] = gen_reg_rtx (DImode);
1608: }")
1609:
1610: ;; Recognize the first insn generated above.
1611: ;; This RTL looks like a fix_truncdfdi2 insn,
1612: ;; but we dont call it that, because only 32 bits
1613: ;; of the result are valid.
1614: ;; This pattern will work for the intended purposes
1615: ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
1616: (define_insn ""
1617: [(set (match_operand:DI 0 "register_operand" "=f")
1618: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1619: ""
1620: "ftrunc.dd %1,%0")
1621:
1622: (define_expand "fix_truncsfsi2"
1623: ;; This first insn produces a double-word value
1624: ;; in which only the low word is valid.
1625: [(set (match_dup 2)
1626: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
1627: (set (match_operand:SI 0 "register_operand" "=f")
1628: (subreg:SI (match_dup 2) 0))]
1629: ""
1630: "
1631: {
1632: operands[2] = gen_reg_rtx (DImode);
1633: }")
1634:
1635: ;; Recognize the first insn generated above.
1636: ;; This RTL looks like a fix_truncsfdi2 insn,
1637: ;; but we dont call it that, because only 32 bits
1638: ;; of the result are valid.
1639: ;; This pattern will work for the intended purposes
1640: ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
1641: (define_insn ""
1642: [(set (match_operand:DI 0 "register_operand" "=f")
1643: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1644: ""
1645: "ftrunc.sd %1,%0")
1646:
1647: ;;- arithmetic instructions
1648:
1649: (define_insn "addsi3"
1650: [(set (match_operand:SI 0 "register_operand" "=r,*f")
1651: (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
1652: (match_operand:SI 2 "arith_operand" "rI,*f")))]
1653: ""
1654: "*
1655: {
1656: if (which_alternative == 1)
1657: return \"fiadd.ss %2,%1,%0\";
1658: CC_STATUS_PARTIAL_INIT;
1659: return \"addu %2,%1,%0\";
1660: }")
1661:
1662: (define_insn "adddi3"
1663: [(set (match_operand:DI 0 "register_operand" "=f")
1664: (plus:DI (match_operand:DI 1 "register_operand" "%f")
1665: (match_operand:DI 2 "register_operand" "f")))]
1666: ""
1667: "fiadd.dd %1,%2,%0")
1668:
1669: (define_insn "subsi3"
1670: [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
1671: (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
1672: (match_operand:SI 2 "arith_operand" "rI,r,*f")))]
1673: ""
1674: "*
1675: {
1676: if (which_alternative == 2)
1677: return \"fisub.ss %1,%2,%0\";
1678: CC_STATUS_PARTIAL_INIT;
1679: if (REG_P (operands[2]))
1680: return \"subu %1,%2,%0\";
1681: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1682: return \"addu %2,%1,%0\";
1683: }")
1684:
1685: (define_insn "subdi3"
1686: [(set (match_operand:DI 0 "register_operand" "=f")
1687: (minus:DI (match_operand:DI 1 "register_operand" "%f")
1688: (match_operand:DI 2 "register_operand" "f")))]
1689: ""
1690: "fisub.dd %1,%2,%0")
1691:
1692: (define_expand "mulsi3"
1693: [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1694: (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1695: (clobber (match_dup 3))
1696: (set (subreg:SI (match_dup 3) 0)
1697: (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1698: (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1699: ""
1700: "
1701: {
1702: if (WORDS_BIG_ENDIAN)
1703: emit_insn (gen_mulsi3_big (operands[0], operands[1], operands[2]));
1704: else
1705: emit_insn (gen_mulsi3_little (operands[0], operands[1], operands[2]));
1706: DONE;
1707: }")
1708:
1709: (define_expand "mulsi3_little"
1710: [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1711: (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1712: (clobber (match_dup 3))
1713: (set (subreg:SI (match_dup 3) 0)
1714: (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1715: (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1716: "! WORDS_BIG_ENDIAN"
1717: "
1718: {
1719: operands[3] = gen_reg_rtx (DImode);
1720: operands[4] = gen_reg_rtx (DImode);
1721: operands[5] = gen_reg_rtx (DImode);
1722: }")
1723:
1724: (define_expand "mulsi3_big"
1725: [(set (subreg:SI (match_dup 4) 1) (match_operand:SI 1 "general_operand" ""))
1726: (set (subreg:SI (match_dup 5) 1) (match_operand:SI 2 "general_operand" ""))
1727: (clobber (match_dup 3))
1728: (set (subreg:SI (match_dup 3) 1)
1729: (mult:SI (subreg:SI (match_dup 4) 1) (subreg:SI (match_dup 5) 1)))
1730: (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 1))]
1731: "WORDS_BIG_ENDIAN"
1732: "
1733: {
1734: operands[3] = gen_reg_rtx (DImode);
1735: operands[4] = gen_reg_rtx (DImode);
1736: operands[5] = gen_reg_rtx (DImode);
1737: }")
1738:
1739: (define_insn ""
1740: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1741: (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1742: (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1743: "! WORDS_BIG_ENDIAN"
1744: "fmlow.dd %2,%1,%0")
1745:
1746: (define_insn ""
1747: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 1)
1748: (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 1)
1749: (subreg:SI (match_operand:DI 2 "register_operand" "f") 1)))]
1750: "WORDS_BIG_ENDIAN"
1751: "fmlow.dd %2,%1,%0")
1752:
1753: ;;- and instructions (with compliment also)
1754: (define_insn "andsi3"
1755: [(set (match_operand:SI 0 "register_operand" "=r")
1756: (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1757: (match_operand:SI 2 "nonmemory_operand" "rL")))]
1758: ""
1759: "*
1760: {
1761: rtx xop[3];
1762:
1763: CC_STATUS_PARTIAL_INIT;
1764: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1765: return \"and %2,%1,%0\";
1766: if ((INTVAL (operands[2]) & 0xffff) == 0)
1767: {
1768: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1769: (unsigned) INTVAL (operands[2]) >> 16);
1770: return \"andh %2,%1,%0\";
1771: }
1772: xop[0] = operands[0];
1773: xop[1] = operands[1];
1774: xop[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]) & 0xffff);
1775: output_asm_insn (\"andnot %2,%1,%0\", xop);
1776: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1777: ~(unsigned) INTVAL (operands[2]) >> 16);
1778: return \"andnoth %2,%0,%0\";
1779: }")
1780:
1781: (define_insn ""
1782: [(set (match_operand:SI 0 "register_operand" "=r")
1783: (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn"))
1784: (match_operand:SI 2 "register_operand" "r")))]
1785: ""
1786: "*
1787: {
1788: rtx xop[3];
1789:
1790: CC_STATUS_PARTIAL_INIT;
1791: if (REG_P (operands[1]) || LOGIC_INT (operands[1]))
1792: return \"andnot %1,%2,%0\";
1793: if ((INTVAL (operands[1]) & 0xffff) == 0)
1794: {
1795: operands[1] = gen_rtx (CONST_INT, VOIDmode,
1796: (unsigned) INTVAL (operands[1]) >> 16);
1797: return \"andnoth %1,%2,%0\";
1798: }
1799: xop[0] = operands[0];
1800: xop[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) & 0xffff));
1801: xop[2] = operands[2];
1802: output_asm_insn (\"andnot %1,%2,%0\", xop);
1803: operands[1] = gen_rtx (CONST_INT, VOIDmode,
1804: (unsigned) INTVAL (operands[1]) >> 16);
1805: return \"andnoth %1,%0,%0\";
1806: }")
1807:
1808: (define_insn "iorsi3"
1809: [(set (match_operand:SI 0 "register_operand" "=r")
1810: (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1811: (match_operand:SI 2 "nonmemory_operand" "rL")))]
1812: ""
1813: "*
1814: {
1815: rtx xop[3];
1816:
1817: CC_STATUS_PARTIAL_INIT;
1818: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1819: return \"or %2,%1,%0\";
1820: if ((INTVAL (operands[2]) & 0xffff) == 0)
1821: {
1822: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1823: (unsigned) INTVAL (operands[2]) >> 16);
1824: return \"orh %2,%1,%0\";
1825: }
1826: xop[0] = operands[0];
1827: xop[1] = operands[1];
1828: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1829: output_asm_insn (\"or %2,%1,%0\", xop);
1830: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1831: (unsigned) INTVAL (operands[2]) >> 16);
1832: return \"orh %2,%0,%0\";
1833: }")
1834:
1835: (define_insn "xorsi3"
1836: [(set (match_operand:SI 0 "register_operand" "=r")
1837: (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1838: (match_operand:SI 2 "nonmemory_operand" "rL")))]
1839: ""
1840: "*
1841: {
1842: rtx xop[3];
1843:
1844: CC_STATUS_PARTIAL_INIT;
1845: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1846: return \"xor %2,%1,%0\";
1847: if ((INTVAL (operands[2]) & 0xffff) == 0)
1848: {
1849: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1850: (unsigned) INTVAL (operands[2]) >> 16);
1851: return \"xorh %2,%1,%0\";
1852: }
1853: xop[0] = operands[0];
1854: xop[1] = operands[1];
1855: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1856: output_asm_insn (\"xor %2,%1,%0\", xop);
1857: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1858: (unsigned) INTVAL (operands[2]) >> 16);
1859: return \"xorh %2,%0,%0\";
1860: }")
1861:
1862: ;(The i860 instruction set doesn't allow an immediate second operand in
1863: ; a subtraction.)
1864: (define_insn "negsi2"
1865: [(set (match_operand:SI 0 "general_operand" "=r")
1866: (neg:SI (match_operand:SI 1 "arith_operand" "r")))]
1867: ""
1868: "*
1869: {
1870: CC_STATUS_PARTIAL_INIT;
1871: return \"subu %?r0,%1,%0\";
1872: }")
1873:
1874: (define_insn "one_cmplsi2"
1875: [(set (match_operand:SI 0 "general_operand" "=r")
1876: (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1877: ""
1878: "*
1879: {
1880: CC_STATUS_PARTIAL_INIT;
1881: return \"subu -1,%1,%0\";
1882: }")
1883:
1884: ;; Floating point arithmetic instructions.
1885:
1886: (define_insn "adddf3"
1887: [(set (match_operand:DF 0 "register_operand" "=f")
1888: (plus:DF (match_operand:DF 1 "register_operand" "f")
1889: (match_operand:DF 2 "register_operand" "f")))]
1890: ""
1891: "fadd.dd %1,%2,%0")
1892:
1893: (define_insn "addsf3"
1894: [(set (match_operand:SF 0 "register_operand" "=f")
1895: (plus:SF (match_operand:SF 1 "register_operand" "f")
1896: (match_operand:SF 2 "register_operand" "f")))]
1897: ""
1898: "fadd.ss %1,%2,%0")
1899:
1900: (define_insn "subdf3"
1901: [(set (match_operand:DF 0 "register_operand" "=f")
1902: (minus:DF (match_operand:DF 1 "register_operand" "f")
1903: (match_operand:DF 2 "register_operand" "f")))]
1904: ""
1905: "fsub.dd %1,%2,%0")
1906:
1907: (define_insn "subsf3"
1908: [(set (match_operand:SF 0 "register_operand" "=f")
1909: (minus:SF (match_operand:SF 1 "register_operand" "f")
1910: (match_operand:SF 2 "register_operand" "f")))]
1911: ""
1912: "fsub.ss %1,%2,%0")
1913:
1914: (define_insn "muldf3"
1915: [(set (match_operand:DF 0 "register_operand" "=f")
1916: (mult:DF (match_operand:DF 1 "register_operand" "f")
1917: (match_operand:DF 2 "register_operand" "f")))]
1918: ""
1919: "fmul.dd %1,%2,%0")
1920:
1921: (define_insn "mulsf3"
1922: [(set (match_operand:SF 0 "register_operand" "=f")
1923: (mult:SF (match_operand:SF 1 "register_operand" "f")
1924: (match_operand:SF 2 "register_operand" "f")))]
1925: ""
1926: "fmul.ss %1,%2,%0")
1927:
1928: (define_insn "negdf2"
1929: [(set (match_operand:DF 0 "register_operand" "=f")
1930: (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1931: ""
1932: "fsub.dd %?f0,%1,%0")
1933:
1934: (define_insn "negsf2"
1935: [(set (match_operand:SF 0 "register_operand" "=f")
1936: (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1937: ""
1938: "fsub.ss %?f0,%1,%0")
1939:
1940: (define_insn "divdf3"
1941: [(set (match_operand:DF 0 "register_operand" "=&f")
1942: (div:DF (match_operand:DF 1 "register_operand" "f")
1943: (match_operand:DF 2 "register_operand" "f")))
1944: (clobber (match_scratch:DF 3 "=&f"))
1945: (clobber (match_scratch:DF 4 "=&f"))]
1946: ""
1947: "*
1948: {
1949: CC_STATUS_PARTIAL_INIT;
1950: if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1951: || (cc_prev_status.flags & CC_HI_R31_ADJ)
1952: || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1953: {
1954: cc_status.flags |= CC_KNOW_HI_R31;
1955: cc_status.flags &= ~CC_HI_R31_ADJ;
1956: cc_status.mdep = CONST2_RTX (SFmode);
1957: return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1958: orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1959: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1960: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1961: fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1962: }
1963: else
1964: return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1965: ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1966: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1967: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1968: fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1969: }")
1970:
1971: (define_insn "divsf3"
1972: [(set (match_operand:SF 0 "register_operand" "=&f")
1973: (div:SF (match_operand:SF 1 "register_operand" "f")
1974: (match_operand:SF 2 "register_operand" "f")))
1975: (clobber (match_scratch:SF 3 "=&f"))
1976: (clobber (match_scratch:SF 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: output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands);
1989: }
1990: return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\\
1991: fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\\
1992: fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\\
1993: fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\";
1994: }")
1995:
1996: ;; Shift instructions
1997:
1998: ;; Optimized special case of shifting.
1999: ;; Must precede the general case.
2000:
2001: (define_insn ""
2002: [(set (match_operand:SI 0 "register_operand" "=r")
2003: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2004: (const_int 24)))]
2005: ""
2006: "*
2007: {
2008: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
2009: {
2010: CC_STATUS_INIT;
2011: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
2012: cc_status.mdep = XEXP (operands[1], 0);
2013: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
2014: }
2015: return \"ld.b %1,%0\";
2016: }")
2017:
2018:
2019: ;;- arithmetic shift instructions
2020: (define_insn "ashlsi3"
2021: [(set (match_operand:SI 0 "register_operand" "=r")
2022: (ashift:SI (match_operand:SI 1 "register_operand" "r")
2023: (match_operand:SI 2 "shift_operand" "rn")))]
2024: ""
2025: "*
2026: {
2027: return \"shl %2,%1,%0\";
2028: }")
2029:
2030: (define_insn "ashlhi3"
2031: [(set (match_operand:HI 0 "register_operand" "=r")
2032: (ashift:HI (match_operand:HI 1 "register_operand" "r")
2033: (match_operand:HI 2 "shift_operand" "rn")))]
2034: ""
2035: "*
2036: {
2037: return \"shl %2,%1,%0\";
2038: }")
2039:
2040: (define_insn "ashlqi3"
2041: [(set (match_operand:QI 0 "register_operand" "=r")
2042: (ashift:QI (match_operand:QI 1 "register_operand" "r")
2043: (match_operand:QI 2 "shift_operand" "rn")))]
2044: ""
2045: "*
2046: {
2047: return \"shl %2,%1,%0\";
2048: }")
2049:
2050: (define_insn "ashrsi3"
2051: [(set (match_operand:SI 0 "register_operand" "=r")
2052: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2053: (match_operand:SI 2 "shift_operand" "rn")))]
2054: ""
2055: "*
2056: {
2057: return \"shra %2,%1,%0\";
2058: }")
2059:
2060: (define_insn "lshrsi3"
2061: [(set (match_operand:SI 0 "register_operand" "=r")
2062: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2063: (match_operand:SI 2 "shift_operand" "rn")))]
2064: ""
2065: "*
2066: {
2067: return \"shr %2,%1,%0\";
2068: }")
2069:
2070: ;; Unconditional and other jump instructions
2071:
2072: (define_insn "jump"
2073: [(set (pc) (label_ref (match_operand 0 "" "")))]
2074: ""
2075: "*
2076: {
2077: return \"br %l0\;nop\";
2078: }")
2079:
2080: ;; Here are two simple peepholes which fill the delay slot of
2081: ;; an unconditional branch.
2082:
2083: (define_peephole
2084: [(set (match_operand:SI 0 "register_operand" "=rf")
2085: (match_operand:SI 1 "single_insn_src_p" "gfG"))
2086: (set (pc) (label_ref (match_operand 2 "" "")))]
2087: ""
2088: "* return output_delayed_branch (\"br %l2\", operands, insn);")
2089:
2090: (define_peephole
2091: [(set (match_operand:SI 0 "memory_operand" "=m")
2092: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2093: (set (pc) (label_ref (match_operand 2 "" "")))]
2094: ""
2095: "* return output_delayed_branch (\"br %l2\", operands, insn);")
2096:
2097: (define_insn "tablejump"
2098: [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2099: (use (label_ref (match_operand 1 "" "")))]
2100: ""
2101: "bri %0\;nop")
2102:
2103: (define_peephole
2104: [(set (match_operand:SI 0 "memory_operand" "=m")
2105: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2106: (set (pc) (match_operand:SI 2 "register_operand" "r"))
2107: (use (label_ref (match_operand 3 "" "")))]
2108: ""
2109: "* return output_delayed_branch (\"bri %2\", operands, insn);")
2110:
2111: ;;- jump to subroutine
2112: (define_expand "call"
2113: [(call (match_operand:SI 0 "memory_operand" "m")
2114: (match_operand 1 "" "i"))]
2115: ;; operand[2] is next_arg_register
2116: ""
2117: "
2118: {
2119: /* Make sure the address is just one reg and will stay that way. */
2120: if (! call_insn_operand (operands[0], QImode))
2121: operands[0]
2122: = change_address (operands[0], VOIDmode,
2123: copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2124: if (INTVAL (operands[1]) > 0)
2125: {
2126: emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2127: emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2128: }
2129: }")
2130:
2131: ;;- jump to subroutine
2132: (define_insn ""
2133: [(call (match_operand:SI 0 "call_insn_operand" "m")
2134: (match_operand 1 "" "i"))]
2135: ;; operand[2] is next_arg_register
2136: ""
2137: "*
2138: {
2139: /* strip the MEM. */
2140: operands[0] = XEXP (operands[0], 0);
2141: CC_STATUS_INIT;
2142: if (GET_CODE (operands[0]) == REG)
2143: return \"calli %0\;nop\";
2144: return \"call %0\;nop\";
2145: }")
2146:
2147: (define_peephole
2148: [(set (match_operand:SI 0 "register_operand" "=rf")
2149: (match_operand:SI 1 "single_insn_src_p" "gfG"))
2150: (call (match_operand:SI 2 "memory_operand" "m")
2151: (match_operand 3 "" "i"))]
2152: ;;- Don't use operand 1 for most machines.
2153: "! reg_mentioned_p (operands[0], operands[2])"
2154: "*
2155: {
2156: /* strip the MEM. */
2157: operands[2] = XEXP (operands[2], 0);
2158: if (GET_CODE (operands[2]) == REG)
2159: return output_delayed_branch (\"calli %2\", operands, insn);
2160: return output_delayed_branch (\"call %2\", operands, insn);
2161: }")
2162:
2163: (define_peephole
2164: [(set (match_operand:SI 0 "memory_operand" "=m")
2165: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2166: (call (match_operand:SI 2 "call_insn_operand" "m")
2167: (match_operand 3 "" "i"))]
2168: ;;- Don't use operand 1 for most machines.
2169: ""
2170: "*
2171: {
2172: /* strip the MEM. */
2173: operands[2] = XEXP (operands[2], 0);
2174: if (GET_CODE (operands[2]) == REG)
2175: return output_delayed_branch (\"calli %2\", operands, insn);
2176: return output_delayed_branch (\"call %2\", operands, insn);
2177: }")
2178:
2179: (define_expand "call_value"
2180: [(set (match_operand 0 "register_operand" "=rf")
2181: (call (match_operand:SI 1 "memory_operand" "m")
2182: (match_operand 2 "" "i")))]
2183: ;; operand 3 is next_arg_register
2184: ""
2185: "
2186: {
2187: /* Make sure the address is just one reg and will stay that way. */
2188: if (! call_insn_operand (operands[1], QImode))
2189: operands[1]
2190: = change_address (operands[1], VOIDmode,
2191: copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2192: if (INTVAL (operands[2]) > 0)
2193: {
2194: emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2195: emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2196: }
2197: }")
2198:
2199: (define_insn ""
2200: [(set (match_operand 0 "register_operand" "=rf")
2201: (call (match_operand:SI 1 "call_insn_operand" "m")
2202: (match_operand 2 "" "i")))]
2203: ;; operand 3 is next_arg_register
2204: ""
2205: "*
2206: {
2207: /* strip the MEM. */
2208: operands[1] = XEXP (operands[1], 0);
2209: CC_STATUS_INIT;
2210: if (GET_CODE (operands[1]) == REG)
2211: return \"calli %1\;nop\";
2212: return \"call %1\;nop\";
2213: }")
2214:
2215: (define_peephole
2216: [(set (match_operand:SI 0 "register_operand" "=rf")
2217: (match_operand:SI 1 "single_insn_src_p" "gfG"))
2218: (set (match_operand 2 "" "=rf")
2219: (call (match_operand:SI 3 "call_insn_operand" "m")
2220: (match_operand 4 "" "i")))]
2221: ;;- Don't use operand 4 for most machines.
2222: "! reg_mentioned_p (operands[0], operands[3])"
2223: "*
2224: {
2225: /* strip the MEM. */
2226: operands[3] = XEXP (operands[3], 0);
2227: if (GET_CODE (operands[3]) == REG)
2228: return output_delayed_branch (\"calli %3\", operands, insn);
2229: return output_delayed_branch (\"call %3\", operands, insn);
2230: }")
2231:
2232: (define_peephole
2233: [(set (match_operand:SI 0 "memory_operand" "=m")
2234: (match_operand:SI 1 "reg_or_0_operand" "rJf"))
2235: (set (match_operand 2 "" "=rf")
2236: (call (match_operand:SI 3 "call_insn_operand" "m")
2237: (match_operand 4 "" "i")))]
2238: ;;- Don't use operand 4 for most machines.
2239: ""
2240: "*
2241: {
2242: /* strip the MEM. */
2243: operands[3] = XEXP (operands[3], 0);
2244: if (GET_CODE (operands[3]) == REG)
2245: return output_delayed_branch (\"calli %3\", operands, insn);
2246: return output_delayed_branch (\"call %3\", operands, insn);
2247: }")
2248:
2249: ;; Call subroutine returning any type.
2250:
2251: (define_expand "untyped_call"
2252: [(parallel [(call (match_operand 0 "" "")
2253: (const_int 0))
2254: (match_operand 1 "" "")
2255: (match_operand 2 "" "")])]
2256: ""
2257: "
2258: {
2259: int i;
2260:
2261: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2262:
2263: for (i = 0; i < XVECLEN (operands[2], 0); i++)
2264: {
2265: rtx set = XVECEXP (operands[2], 0, i);
2266: emit_move_insn (SET_DEST (set), SET_SRC (set));
2267: }
2268:
2269: /* The optimizer does not know that the call sets the function value
2270: registers we stored in the result block. We avoid problems by
2271: claiming that all hard registers are used and clobbered at this
2272: point. */
2273: emit_insn (gen_blockage ());
2274:
2275: DONE;
2276: }")
2277:
2278: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2279: ;; all of memory. This blocks insns from being moved across this point.
2280:
2281: (define_insn "blockage"
2282: [(unspec_volatile [(const_int 0)] 0)]
2283: ""
2284: "")
2285:
2286: (define_insn "nop"
2287: [(const_int 0)]
2288: ""
2289: "nop")
2290:
2291: (define_insn "indirect_jump"
2292: [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2293: ""
2294: "bri %0")
2295:
2296: ;;
2297: ;; A special insn that does the work to get setup just
2298: ;; before a table jump.
2299: ;;
2300: (define_insn ""
2301: [(set (match_operand:SI 0 "register_operand" "=r")
2302: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2303: (label_ref (match_operand 2 "" "")))))]
2304: ""
2305: "*
2306: {
2307: CC_STATUS_INIT;
2308: return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\";
2309: }")
2310:
2311: (define_peephole
2312: [(set (match_operand:SI 0 "register_operand" "=rf")
2313: (match_operand:SI 1 "single_insn_src_p" "gfG"))
2314: (set (pc) (match_operand:SI 2 "register_operand" "r"))
2315: (use (label_ref (match_operand 3 "" "")))]
2316: "REGNO (operands[0]) != REGNO (operands[2])"
2317: "* return output_delayed_branch (\"bri %2\", operands, insn);")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.