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