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