|
|
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.2 ! root 179: return \"pfeq.s %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.2 ! root 190: return \"pfgt.s %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.2 ! root 201: return \"pfgt.s %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.2 ! root 212: return \"pfle.s %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.2 ! root 223: return \"pfle.s %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.2 ! root 234: return \"pfeq.d %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.2 ! root 245: return \"pfgt.d %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.2 ! root 256: return \"pfgt.d %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.2 ! root 267: return \"pfle.d %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.2 ! root 278: return \"pfle.d %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:
974: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
975: return output_fp_move_double (operands);
976: return output_move_double (operands);
977: }")
978:
979: (define_insn "movdi"
980: [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm")
1.1.1.2 ! root 981: (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))]
1.1 root 982: ""
983: "*
984: {
985: if (GET_CODE (operands[0]) == MEM
986: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
987: return output_store (operands);
988: if (GET_CODE (operands[1]) == MEM
989: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
990: return output_load (operands);
991:
1.1.1.2 ! root 992: if (FP_REG_P (operands[0]) && operands[1] == dconst0_rtx)
! 993: return \"fmov.dd f0,%0\";
! 994:
1.1 root 995: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
996: return output_fp_move_double (operands);
997: return output_move_double (operands);
998: }")
999:
1.1.1.2 ! root 1000: ;; The alternative m/r is separate from m/f
! 1001: ;; so that an f-reg won't be used as a reload reg between m and F.
! 1002: ;; The first alternative is separate from the second for the same reason.
1.1 root 1003: (define_insn "movsf"
1.1.1.2 ! root 1004: [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m")
! 1005: (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))]
1.1 root 1006: ""
1007: "*
1008: {
1009: if (GET_CODE (operands[0]) == MEM
1010: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1011: return output_store (operands);
1012: if (GET_CODE (operands[1]) == MEM
1013: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1014: return output_load (operands);
1015: if (FP_REG_P (operands[0]))
1016: {
1017: if (FP_REG_P (operands[1]))
1018: return \"fmov.ss %1,%0\";
1019: if (GET_CODE (operands[1]) == REG)
1020: return \"ixfr %1,%0\";
1021: if (operands[1] == fconst0_rtx)
1022: return \"fmov.ss f0,%0\";
1023: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1024: {
1025: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1026: cc_status.mdep = XEXP (operands[1], 0);
1027: return \"orh ha%%%m1,r0,r31\;fld.l l%%%m1(r31),%0\";
1028: }
1029: return \"fld.l %1,%0\";
1030: }
1031: if (FP_REG_P (operands[1]))
1032: {
1033: if (GET_CODE (operands[0]) == REG)
1034: return \"fxfr %1,%0\";
1035: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1036: {
1037: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1038: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1039: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1040: {
1041: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1042: cc_status.mdep = XEXP (operands[0], 0);
1043: output_asm_insn (\"orh ha%%%m0,r0,r31\", operands);
1044: }
1045: return \"fst.l %r1,l%%%m0(r31)\";
1046: }
1047: return \"fst.l %r1,%0\";
1048: }
1049: if (GET_CODE (operands[0]) == MEM)
1050: return \"st.l %r1,%0\";
1051: if (GET_CODE (operands[1]) == MEM)
1052: return \"ld.l %1,%0\";
1053: if (operands[1] == fconst0_rtx)
1054: return \"mov r0,%0\";
1055: return \"mov %1,%0\";
1056: }")
1057:
1058: ;; Special load insns for REG+REG addresses.
1059: ;; Such addresses are not "legitimate" because st rejects them.
1060:
1061: (define_insn ""
1062: [(set (match_operand:DF 0 "register_operand" "rf")
1063: (match_operand:DF 1 "indexed_operand" "m"))]
1064: ""
1065: "*
1066: {
1067: if (FP_REG_P (operands[0]))
1068: return output_fp_move_double (operands);
1069: return output_move_double (operands);
1070: }")
1071:
1072: (define_insn ""
1073: [(set (match_operand:SF 0 "register_operand" "rf")
1074: (match_operand:SF 1 "indexed_operand" "m"))]
1075: ""
1076: "*
1077: {
1078: if (FP_REG_P (operands[0]))
1079: return \"fld.l %1,%0\";
1080: return \"ld.l %1,%0\";
1081: }")
1082:
1083: (define_insn ""
1084: [(set (match_operand:SI 0 "register_operand" "rf")
1085: (match_operand:SI 1 "indexed_operand" "m"))]
1086: ""
1087: "*
1088: {
1089: if (FP_REG_P (operands[0]))
1090: return \"fld.l %1,%0\";
1091: return \"ld.l %1,%0\";
1092: }")
1093:
1094: (define_insn ""
1095: [(set (match_operand:HI 0 "register_operand" "r")
1096: (match_operand:HI 1 "indexed_operand" "m"))]
1097: ""
1098: "ld.s %1,%0")
1099:
1100: (define_insn ""
1101: [(set (match_operand:QI 0 "register_operand" "r")
1102: (match_operand:QI 1 "indexed_operand" "m"))]
1103: ""
1104: "ld.b %1,%0")
1105:
1106: ;; Likewise for floating-point store insns.
1107:
1108: (define_insn ""
1109: [(set (match_operand:DF 0 "indexed_operand" "m")
1110: (match_operand:DF 1 "register_operand" "f"))]
1111: ""
1112: "fst.d %1,%0")
1113:
1114: (define_insn ""
1115: [(set (match_operand:SF 0 "indexed_operand" "m")
1116: (match_operand:SF 1 "register_operand" "f"))]
1117: ""
1118: "fst.l %1,%0")
1119:
1120: ;;- truncation instructions
1121: (define_insn "truncsiqi2"
1122: [(set (match_operand:QI 0 "general_operand" "=g")
1123: (truncate:QI
1124: (match_operand:SI 1 "register_operand" "r")))]
1125: ""
1126: "*
1127: {
1128: if (GET_CODE (operands[0]) == MEM)
1129: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1130: {
1131: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1132: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1133: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1134: {
1135: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1136: cc_status.mdep = XEXP (operands[0], 0);
1137: output_asm_insn (\"orh ha%%%m0,r0,r31\", operands);
1138: }
1139: return \"st.b %1,l%%%m0(r31)\";
1140: }
1141: else
1142: return \"st.b %1,%0\";
1143: return \"mov %1,%0\";
1144: }")
1145:
1146: (define_insn "trunchiqi2"
1147: [(set (match_operand:QI 0 "general_operand" "=g")
1148: (truncate:QI
1149: (match_operand:HI 1 "register_operand" "r")))]
1150: ""
1151: "*
1152: {
1153: if (GET_CODE (operands[0]) == MEM)
1154: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1155: {
1156: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1157: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1158: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1159: {
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 ha%%%m0,r0,r31\", operands);
1163: }
1164: return \"st.b %1,l%%%m0(r31)\";
1165: }
1166: else
1167: return \"st.b %1,%0\";
1168: return \"mov %1,%0\";
1169: }")
1170:
1171: (define_insn "truncsihi2"
1172: [(set (match_operand:HI 0 "general_operand" "=g")
1173: (truncate:HI
1174: (match_operand:SI 1 "register_operand" "r")))]
1175: ""
1176: "*
1177: {
1178: if (GET_CODE (operands[0]) == MEM)
1179: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1180: {
1181: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1182: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1183: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1184: {
1185: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1186: cc_status.mdep = XEXP (operands[0], 0);
1187: output_asm_insn (\"orh ha%%%m0,r0,r31\", operands);
1188: }
1189: return \"st.s %1,l%%%m0(r31)\";
1190: }
1191: else
1192: return \"st.s %1,%0\";
1193: return \"mov %1,%0\";
1194: }")
1195:
1196: ;;- zero extension instructions
1197:
1198: ;; Note that the one starting from HImode comes before those for QImode
1199: ;; so that a constant operand will match HImode, not QImode.
1200:
1201: (define_insn "zero_extendhisi2"
1202: [(set (match_operand:SI 0 "register_operand" "=r")
1203: (zero_extend:SI
1204: (match_operand:HI 1 "register_operand" "r")))]
1205: ""
1206: "and 0xffff,%1,%0")
1207:
1208: (define_insn "zero_extendqihi2"
1209: [(set (match_operand:HI 0 "register_operand" "=r")
1210: (zero_extend:HI
1211: (match_operand:QI 1 "register_operand" "r")))]
1212: ""
1213: "and 0xff,%1,%0")
1214:
1215: (define_insn "zero_extendqisi2"
1216: [(set (match_operand:SI 0 "register_operand" "=r")
1217: (zero_extend:SI
1218: (match_operand:QI 1 "register_operand" "r")))]
1219: ""
1220: "and 0xff,%1,%0")
1221:
1222: ;;- sign extension instructions
1223: ;; Note that the one starting from HImode comes before those for QImode
1224: ;; so that a constant operand will match HImode, not QImode.
1225:
1226: (define_insn "extendhisi2"
1227: [(set (match_operand:SI 0 "register_operand" "=r")
1228: (sign_extend:SI
1229: (match_operand:HI 1 "general_operand" "mr")))]
1230: ""
1231: "*
1232: {
1233: if (REG_P (operands[1]))
1234: return \"shl 16,%1,%0\;shra 16,%0,%0\";
1235: if (GET_CODE (operands[1]) == CONST_INT)
1236: abort ();
1237: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1238: {
1239: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1240: cc_status.mdep = XEXP (operands[1], 0);
1241: return \"orh ha%%%m1,r0,r31\;ld.s l%%%m1(r31),%0\";
1242: }
1243: else
1244: return \"ld.s %1,%0\";
1245: }")
1246:
1247: (define_insn "extendqihi2"
1248: [(set (match_operand:HI 0 "register_operand" "=r")
1249: (sign_extend:HI
1250: (match_operand:QI 1 "general_operand" "mr")))]
1251: ""
1252: "*
1253: {
1254: if (REG_P (operands[1]))
1255: return \"shl 24,%1,%0\;shra 24,%0,%0\";
1256: if (GET_CODE (operands[1]) == CONST_INT)
1257: abort ();
1258: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1259: {
1260: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1261: cc_status.mdep = XEXP (operands[1], 0);
1262: return \"orh ha%%%m1,r0,r31\;ld.b l%%%m1(r31),%0\";
1263: }
1264: else
1265: return \"ld.b %1,%0\";
1266: }")
1267:
1268: (define_insn "extendqisi2"
1269: [(set (match_operand:SI 0 "register_operand" "=r")
1270: (sign_extend:SI
1271: (match_operand:QI 1 "general_operand" "mr")))]
1272: ""
1273: "*
1274: {
1275: if (REG_P (operands[1]))
1276: return \"shl 24,%1,%0\;shra 24,%0,%0\";
1277: if (GET_CODE (operands[1]) == CONST_INT)
1278: abort ();
1279: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1280: {
1281: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1282: cc_status.mdep = XEXP (operands[1], 0);
1283: return \"orh ha%%%m1,r0,r31\;ld.b l%%%m1(r31),%0\";
1284: }
1285: else
1286: return \"ld.b %1,%0\";
1287: }")
1288:
1289: (define_insn ""
1290: [(set (match_operand:SI 0 "register_operand" "=r")
1291: (sign_extend:SI
1292: (match_operand:HI 1 "indexed_operand" "m")))]
1293: ""
1294: "ld.s %1,%0")
1295:
1296: (define_insn ""
1297: [(set (match_operand:HI 0 "register_operand" "=r")
1298: (sign_extend:HI
1299: (match_operand:QI 1 "indexed_operand" "m")))]
1300: ""
1301: "ld.b %1,%0")
1302:
1303: (define_insn ""
1304: [(set (match_operand:SI 0 "register_operand" "=r")
1305: (sign_extend:SI
1306: (match_operand:QI 1 "indexed_operand" "m")))]
1307: ""
1308: "ld.b %1,%0")
1309:
1310: ;; Signed bitfield extractions come out looking like
1311: ;; (shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
1312: ;; which we expand poorly as four shift insns.
1313: ;; These patters yeild two shifts:
1314: ;; (shiftrt (shift <Y> <C3>) <C4>)
1315: (define_insn ""
1316: [(set (match_operand:SI 0 "register_operand" "=r")
1317: (ashiftrt:SI
1318: (sign_extend:SI
1319: (match_operand:QI 1 "register_operand" "r"))
1320: (match_operand:SI 2 "logic_int" "n")))]
1321: ""
1322: "*
1323: {
1324: return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
1325: }")
1326:
1327: (define_insn ""
1328: [(set (match_operand:SI 0 "register_operand" "=r")
1329: (ashiftrt:SI
1330: (sign_extend:SI
1331: (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1332: (match_operand:SI 2 "logic_int" "n")) 0))
1333: (match_operand:SI 3 "logic_int" "n")))]
1334: ""
1335: "*
1336: {
1337: return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1338: }")
1339:
1340: (define_insn ""
1341: [(set (match_operand:SI 0 "register_operand" "=r")
1342: (ashiftrt:SI
1343: (sign_extend:SI
1344: (ashift:QI (match_operand:QI 1 "register_operand" "r")
1345: (match_operand:QI 2 "logic_int" "n")))
1346: (match_operand:SI 3 "logic_int" "n")))]
1347: ""
1348: "*
1349: {
1350: return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1351: }")
1352:
1353: ;; Special patterns for optimizing bit-field instructions.
1354:
1355: ;; First two patterns are for bitfields that came from memory
1356: ;; testing only the high bit. They work with old combiner.
1357:
1358: (define_insn ""
1359: [(set (cc0)
1360: (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1361: (const_int 7)) 0))
1362: (const_int 0)))]
1363: ""
1364: "and 128,%0,r0")
1365:
1366: (define_insn ""
1367: [(set (cc0)
1368: (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1369: (const_int 7)) 0))
1370: (const_int 0)))]
1371: ""
1372: "and 128,%0,r0")
1373:
1374: ;; next two patterns are good for bitfields coming from memory
1375: ;; (via pseudo-register) or from a register, though this optimization
1376: ;; is only good for values contained wholly within the bottom 13 bits
1377: (define_insn ""
1378: [(set (cc0)
1379: (eq
1380: (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1381: (match_operand:SI 1 "logic_int" "n"))
1382: (match_operand:SI 2 "logic_int" "n"))
1383: (const_int 0)))]
1384: "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1385: "*
1386: {
1387: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1388: (INTVAL (operands[2]) << INTVAL (operands[1])));
1389: return \"and %2,%0,r0\";
1390: }")
1391:
1392: (define_insn ""
1393: [(set (cc0)
1394: (eq
1395: (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1396: (match_operand:SI 1 "logic_int" "n"))
1397: (match_operand:SI 2 "logic_int" "n"))
1398: (const_int 0)))]
1399: "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1400: "*
1401: {
1402: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1403: (INTVAL (operands[2]) << INTVAL (operands[1])));
1404: return \"and %2,%0,r0\";
1405: }")
1406:
1407: ;; Conversions between float and double.
1408:
1409: (define_insn "extendsfdf2"
1410: [(set (match_operand:DF 0 "register_operand" "=f")
1411: (float_extend:DF
1412: (match_operand:SF 1 "register_operand" "f")))]
1413: ""
1414: "fmov.sd %1,%0")
1415:
1416: (define_insn "truncdfsf2"
1417: [(set (match_operand:SF 0 "register_operand" "=f")
1418: (float_truncate:SF
1419: (match_operand:DF 1 "register_operand" "f")))]
1420: ""
1421: "fmov.ds %1,%0")
1422:
1423: ;; Conversion between fixed point and floating point.
1424: ;; Note that among the fix-to-float insns
1425: ;; the ones that start with SImode come first.
1426: ;; That is so that an operand that is a CONST_INT
1427: ;; (and therefore lacks a specific machine mode).
1428: ;; will be recognized as SImode (which is always valid)
1429: ;; rather than as QImode or HImode.
1430:
1431: (define_expand "floatsidf2"
1432: [(set (match_dup 2) (match_dup 3))
1433: (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
1434: (const_int -2147483648)))
1.1.1.2 ! root 1435: (set (subreg:SI (match_dup 5) 0) (match_dup 4))
! 1436: (set (subreg:SI (match_dup 5) 1) (subreg:SI (match_dup 2) 1))
1.1 root 1437: (set (match_operand:DF 0 "register_operand" "")
1438: (minus:DF (match_dup 5) (match_dup 2)))]
1439: ""
1440: "
1441: {
1442: /* Generate desired value, in float format of host machine. */
1443: double d = (double) (1 << 30) * ((double) (1 << 22) + (double) (1 << 1));
1444: operands[2] = gen_reg_rtx (DFmode);
1445: operands[3] = immed_double_const (d, DFmode);
1446: operands[4] = gen_reg_rtx (SImode);
1447: operands[5] = gen_reg_rtx (DFmode);
1448: }")
1449:
1450: ;; Floating to fixed conversion.
1451:
1452: (define_expand "fix_truncdfsi2"
1453: ;; This first insn produces a double-word value
1454: ;; in which only the low word is valid.
1455: [(set (match_dup 2)
1456: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1457: (set (match_operand:SI 0 "register_operand" "=f")
1458: (subreg:SI (match_dup 2) 0))]
1459: ""
1460: "
1461: {
1462: operands[2] = gen_reg_rtx (DImode);
1463: }")
1464:
1465: ;; Recognize the first insn generated above.
1466: ;; This RTL looks like a fix_truncdfdi2 insn,
1467: ;; but we dont call it that, because only 32 bits
1468: ;; of the result are valid.
1469: ;; This pattern will work for the intended purposes
1470: ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
1471: (define_insn ""
1472: [(set (match_operand:DI 0 "register_operand" "=f")
1473: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1474: ""
1475: "ftrunc.dd %1,%0")
1476:
1477: (define_expand "fix_truncsfsi2"
1478: ;; This first insn produces a double-word value
1479: ;; in which only the low word is valid.
1480: [(set (match_dup 2)
1481: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
1482: (set (match_operand:SI 0 "register_operand" "=f")
1483: (subreg:SI (match_dup 2) 0))]
1484: ""
1485: "
1486: {
1487: operands[2] = gen_reg_rtx (DImode);
1488: }")
1489:
1490: ;; Recognize the first insn generated above.
1491: ;; This RTL looks like a fix_truncsfdi2 insn,
1492: ;; but we dont call it that, because only 32 bits
1493: ;; of the result are valid.
1494: ;; This pattern will work for the intended purposes
1495: ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
1496: (define_insn ""
1497: [(set (match_operand:DI 0 "register_operand" "=f")
1498: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1499: ""
1500: "ftrunc.sd %1,%0")
1501:
1502: ;;- arithmetic instructions
1503:
1504: (define_insn "addsi3"
1505: [(set (match_operand:SI 0 "register_operand" "=r,*f")
1506: (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
1507: (match_operand:SI 2 "nonmemory_operand" "rn,*f")))]
1508: ""
1509: "*
1510: {
1511: if (which_alternative == 1)
1512: return \"fiadd.ss %2,%1,%0\";
1513: if (REG_P (operands[2]))
1514: return \"addu %2,%1,%0\";
1515: if (SMALL_INT (operands[2]))
1516: return \"addu %2,%1,%0\";
1517: cc_status.flags &= ~CC_KNOW_HI_R31;
1518: return \"orh h%%%2,r0,r31\;or l%%%2,r31,r31\;addu %1,r31,%0\";
1519: }")
1520:
1521: (define_insn "adddi3"
1522: [(set (match_operand:DI 0 "register_operand" "=f")
1523: (plus:DI (match_operand:DI 1 "register_operand" "%f")
1524: (match_operand:DI 2 "register_operand" "f")))]
1525: ""
1.1.1.2 ! root 1526: "fiadd.dd %1,%2,%0")
1.1 root 1527:
1528: (define_insn "subsi3"
1529: [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
1530: (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
1531: (match_operand:SI 2 "nonmemory_operand" "rn,r,*f")))]
1532: ""
1533: "*
1534: {
1535: if (which_alternative == 2)
1536: return \"fisub.ss %1,%2,%0\";
1537: if (REG_P (operands[2]))
1538: return \"subu %1,%2,%0\";
1539: if (SMALL_INT (operands[2]) && INTVAL (operands[2]) != -0x10000)
1540: {
1541: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1542: return \"addu %2,%1,%0\";
1543: }
1544: cc_status.flags &= ~CC_KNOW_HI_R31;
1545: return \"orh h%%%2,r0,r31\;or l%%%2,r31,r31\;sub %1,r31,%0\";
1546: }")
1547:
1548: (define_insn "subdi3"
1549: [(set (match_operand:DI 0 "register_operand" "=f")
1550: (minus:DI (match_operand:DI 1 "register_operand" "%f")
1551: (match_operand:DI 2 "register_operand" "f")))]
1552: ""
1.1.1.2 ! root 1553: "fisub.dd %1,%2,%0")
1.1 root 1554:
1555: (define_expand "mulsi3"
1556: [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1557: (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1558: (clobber (match_dup 3))
1559: (set (subreg:SI (match_dup 3) 0)
1560: (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1561: (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1562: ""
1563: "
1564: {
1565: operands[3] = gen_reg_rtx (DImode);
1566: operands[4] = gen_reg_rtx (DImode);
1567: operands[5] = gen_reg_rtx (DImode);
1568: }")
1569:
1570: (define_insn ""
1571: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1572: (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1573: (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1574: ""
1575: "fmlow.dd %2,%1,%0")
1576:
1577: ;;- and instructions (with compliment also)
1578: (define_insn "andsi3"
1579: [(set (match_operand:SI 0 "register_operand" "=r")
1580: (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1581: (match_operand:SI 2 "nonmemory_operand" "rn")))]
1582: ""
1583: "*
1584: {
1585: rtx xop[3];
1586:
1587: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1588: return \"and %2,%1,%0\";
1589: if ((INTVAL (operands[2]) & 0xffff) == 0)
1590: {
1591: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1592: (unsigned) INTVAL (operands[2]) >> 16);
1593: return \"andh %2,%1,%0\";
1594: }
1595: xop[0] = operands[0];
1596: xop[1] = operands[1];
1.1.1.2 ! root 1597: xop[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]) & 0xffff);
1.1 root 1598: output_asm_insn (\"andnot %2,%1,%0\", xop);
1599: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1600: ~(unsigned) INTVAL (operands[2]) >> 16);
1601: return \"andnoth %2,%0,%0\";
1602: }")
1603:
1604: (define_insn "andcbsi3"
1605: [(set (match_operand:SI 0 "register_operand" "=r")
1606: (and:SI (match_operand:SI 1 "register_operand" "r")
1607: (not:SI (match_operand:SI 2 "register_operand" "rn"))))]
1608: ""
1609: "*
1610: {
1611: rtx xop[3];
1612:
1613: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1614: return \"andnot %2,%1,%0\";
1615: if ((INTVAL (operands[2]) & 0xffff) == 0)
1616: {
1617: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1618: (unsigned) INTVAL (operands[2]) >> 16);
1619: return \"andnoth %2,%1,%0\";
1620: }
1621: xop[0] = operands[0];
1622: xop[1] = operands[1];
1623: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1624: output_asm_insn (\"andnot %2,%1,%0\", xop);
1625: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1626: (unsigned) INTVAL (operands[2]) >> 16);
1627: return \"andnoth %2,%0,%0\";
1628: }")
1629:
1630: (define_insn "iorsi3"
1631: [(set (match_operand:SI 0 "register_operand" "=r")
1632: (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1633: (match_operand:SI 2 "nonmemory_operand" "rn")))]
1634: ""
1635: "*
1636: {
1637: rtx xop[3];
1638:
1639: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1640: return \"or %2,%1,%0\";
1641: if ((INTVAL (operands[2]) & 0xffff) == 0)
1642: {
1643: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1644: (unsigned) INTVAL (operands[2]) >> 16);
1645: return \"orh %2,%1,%0\";
1646: }
1647: xop[0] = operands[0];
1648: xop[1] = operands[1];
1649: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1650: output_asm_insn (\"or %2,%1,%0\", xop);
1651: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1652: (unsigned) INTVAL (operands[2]) >> 16);
1653: return \"orh %2,%0,%0\";
1654: }")
1655:
1656: (define_insn "xorsi3"
1657: [(set (match_operand:SI 0 "register_operand" "=r")
1658: (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1659: (match_operand:SI 2 "nonmemory_operand" "rn")))]
1660: ""
1661: "*
1662: {
1663: rtx xop[3];
1664:
1665: if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1666: return \"xor %2,%1,%0\";
1667: if ((INTVAL (operands[2]) & 0xffff) == 0)
1668: {
1669: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1670: (unsigned) INTVAL (operands[2]) >> 16);
1671: return \"xorh %2,%1,%0\";
1672: }
1673: xop[0] = operands[0];
1674: xop[1] = operands[1];
1675: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1676: output_asm_insn (\"xor %2,%1,%0\", xop);
1677: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1678: (unsigned) INTVAL (operands[2]) >> 16);
1679: return \"xorh %2,%0,%0\";
1680: }")
1681:
1682: (define_insn "negsi2"
1683: [(set (match_operand:SI 0 "general_operand" "=r")
1684: (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
1685: ""
1686: "subu r0,%1,%0")
1687:
1688: (define_insn "one_cmplsi2"
1689: [(set (match_operand:SI 0 "general_operand" "=r")
1690: (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1691: ""
1692: "subu -1,%1,%0")
1693:
1694: ;; Floating point arithmetic instructions.
1695:
1696: (define_insn "adddf3"
1697: [(set (match_operand:DF 0 "register_operand" "=f")
1698: (plus:DF (match_operand:DF 1 "register_operand" "f")
1699: (match_operand:DF 2 "register_operand" "f")))]
1700: ""
1701: "fadd.dd %1,%2,%0")
1702:
1703: (define_insn "addsf3"
1704: [(set (match_operand:SF 0 "register_operand" "=f")
1705: (plus:SF (match_operand:SF 1 "register_operand" "f")
1706: (match_operand:SF 2 "register_operand" "f")))]
1707: ""
1708: "fadd.ss %1,%2,%0")
1709:
1710: (define_insn "subdf3"
1711: [(set (match_operand:DF 0 "register_operand" "=f")
1712: (minus:DF (match_operand:DF 1 "register_operand" "f")
1713: (match_operand:DF 2 "register_operand" "f")))]
1714: ""
1715: "fsub.dd %1,%2,%0")
1716:
1717: (define_insn "subsf3"
1718: [(set (match_operand:SF 0 "register_operand" "=f")
1719: (minus:SF (match_operand:SF 1 "register_operand" "f")
1720: (match_operand:SF 2 "register_operand" "f")))]
1721: ""
1722: "fsub.ss %1,%2,%0")
1723:
1724: (define_insn "muldf3"
1725: [(set (match_operand:DF 0 "register_operand" "=f")
1726: (mult:DF (match_operand:DF 1 "register_operand" "f")
1727: (match_operand:DF 2 "register_operand" "f")))]
1728: ""
1729: "fmul.dd %1,%2,%0")
1730:
1731: (define_insn "mulsf3"
1732: [(set (match_operand:SF 0 "register_operand" "=f")
1733: (mult:SF (match_operand:SF 1 "register_operand" "f")
1734: (match_operand:SF 2 "register_operand" "f")))]
1735: ""
1736: "fmul.ss %1,%2,%0")
1737:
1738: (define_insn "negdf2"
1739: [(set (match_operand:DF 0 "register_operand" "=f")
1740: (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1741: ""
1742: "fsub.dd f0,%1,%0")
1743:
1744: (define_insn "negsf2"
1745: [(set (match_operand:SF 0 "register_operand" "=f")
1746: (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1747: ""
1748: "fsub.ss f0,%1,%0")
1749:
1750: ;; Shift instructions
1751:
1752: ;; Optimized special case of shifting.
1753: ;; Must precede the general case.
1754:
1755: (define_insn ""
1756: [(set (match_operand:SI 0 "register_operand" "=r")
1757: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1758: (const_int 24)))]
1759: ""
1760: "*
1761: {
1762: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1763: {
1764: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1765: cc_status.mdep = XEXP (operands[1], 0);
1766: return \"orh ha%%%m1,r0,r31\;ld.b l%%%m1(r31),%0\";
1767: }
1768: return \"ld.b %1,%0\";
1769: }")
1770:
1771:
1772: ;;- arithmetic shift instructions
1773: (define_insn "ashlsi3"
1774: [(set (match_operand:SI 0 "register_operand" "=r")
1775: (ashift:SI (match_operand:SI 1 "register_operand" "r")
1776: (match_operand:SI 2 "nonmemory_operand" "rn")))]
1777: ""
1778: "*
1779: {
1780: if (GET_CODE (operands[2]) == CONST_INT
1781: && INTVAL (operands[2]) >= 32)
1782: return \"mov r0,%0\";
1783: return \"shl %2,%1,%0\";
1784: }")
1785:
1786: (define_insn "ashlhi3"
1787: [(set (match_operand:HI 0 "register_operand" "=r")
1788: (ashift:HI (match_operand:HI 1 "register_operand" "r")
1789: (match_operand:HI 2 "nonmemory_operand" "rn")))]
1790: ""
1791: "*
1792: {
1793: if (GET_CODE (operands[2]) == CONST_INT
1794: && INTVAL (operands[2]) >= 16)
1795: return \"mov r0,%0\";
1796: return \"shl %2,%1,%0\";
1797: }")
1798:
1799: (define_insn "ashlqi3"
1800: [(set (match_operand:QI 0 "register_operand" "=r")
1801: (ashift:QI (match_operand:QI 1 "register_operand" "r")
1802: (match_operand:QI 2 "nonmemory_operand" "rn")))]
1803: ""
1804: "*
1805: {
1806: if (GET_CODE (operands[2]) == CONST_INT
1807: && INTVAL (operands[2]) >= 8)
1808: return \"mov r0,%0\";
1809: return \"shl %2,%1,%0\";
1810: }")
1811:
1812: (define_insn "ashrsi3"
1813: [(set (match_operand:SI 0 "register_operand" "=r")
1814: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
1815: (match_operand:SI 2 "nonmemory_operand" "rn")))]
1816: ""
1817: "*
1818: {
1819: if (GET_CODE (operands[2]) == CONST_INT
1820: && INTVAL (operands[2]) >= 32)
1821: return \"shra 31,%1,%0\";
1822: return \"shra %2,%1,%0\";
1823: }")
1824:
1825: (define_insn "lshrsi3"
1826: [(set (match_operand:SI 0 "register_operand" "=r")
1827: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1828: (match_operand:SI 2 "nonmemory_operand" "rn")))]
1829: ""
1830: "*
1831: {
1832: if (GET_CODE (operands[2]) == CONST_INT
1833: && INTVAL (operands[2]) >= 32)
1834: return \"mov r0,%0\";
1835: return \"shr %2,%1,%0\";
1836: }")
1837:
1838: ;; Unconditional and other jump instructions
1839:
1840: (define_insn "jump"
1841: [(set (pc) (label_ref (match_operand 0 "" "")))]
1842: ""
1843: "*
1844: {
1845: return \"br %l0\;nop\";
1846: }")
1847:
1848: ;; Here are two simple peepholes which fill the delay slot of
1849: ;; an unconditional branch.
1850:
1851: (define_peephole
1852: [(set (match_operand:SI 0 "register_operand" "=rf")
1853: (match_operand:SI 1 "single_insn_src_p" "p"))
1854: (set (pc) (label_ref (match_operand 2 "" "")))]
1855: ""
1856: "* return output_delayed_branch (\"br %l2\", operands, insn);")
1857:
1858: (define_peephole
1859: [(set (match_operand:SI 0 "memory_operand" "=m")
1860: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
1861: (set (pc) (label_ref (match_operand 2 "" "")))]
1862: ""
1863: "* return output_delayed_branch (\"br %l2\", operands, insn);")
1864:
1865: (define_insn "tablejump"
1866: [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1867: (use (label_ref (match_operand 1 "" "")))]
1868: ""
1869: "bri %0\;nop")
1870:
1871: (define_peephole
1872: [(set (match_operand:SI 0 "memory_operand" "=m")
1873: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
1874: (set (pc) (match_operand:SI 2 "register_operand" "r"))
1875: (use (label_ref (match_operand 3 "" "")))]
1876: ""
1877: "* return output_delayed_branch (\"bri %2\", operands, insn);")
1878:
1879: ;;- jump to subroutine
1880: (define_expand "call"
1881: [(call (match_operand:SI 0 "memory_operand" "m")
1882: (match_operand 1 "" "i"))]
1883: ;; operand[2] is next_arg_register
1884: ""
1885: "
1886: {
1887: if (INTVAL (operands[1]) > 0)
1888: {
1889: emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
1890: emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
1891: }
1892: }")
1893:
1894: ;;- jump to subroutine
1895: (define_insn ""
1896: [(call (match_operand:SI 0 "memory_operand" "m")
1897: (match_operand 1 "" "i"))]
1898: ;; operand[2] is next_arg_register
1899: ""
1900: "*
1901: {
1902: /* strip the MEM. */
1903: operands[0] = XEXP (operands[0], 0);
1904: CC_STATUS_INIT;
1905: if (GET_CODE (operands[0]) == REG)
1906: return \"calli %0\;nop\";
1907: return \"call %0\;nop\";
1908: }")
1909:
1910: (define_peephole
1911: [(set (match_operand:SI 0 "register_operand" "=rf")
1912: (match_operand:SI 1 "single_insn_src_p" "p"))
1913: (call (match_operand:SI 2 "memory_operand" "m")
1914: (match_operand 3 "" "i"))]
1915: ;;- Don't use operand 1 for most machines.
1916: "! reg_mentioned_p (operands[0], operands[2])"
1917: "*
1918: {
1919: /* strip the MEM. */
1920: operands[2] = XEXP (operands[2], 0);
1921: if (GET_CODE (operands[2]) == REG)
1922: return output_delayed_branch (\"calli %2\", operands, insn);
1923: return output_delayed_branch (\"call %2\", operands, insn);
1924: }")
1925:
1926: (define_peephole
1927: [(set (match_operand:SI 0 "memory_operand" "=m")
1928: (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
1929: (call (match_operand:SI 2 "memory_operand" "m")
1930: (match_operand 3 "" "i"))]
1931: ;;- Don't use operand 1 for most machines.
1932: ""
1933: "*
1934: {
1935: /* strip the MEM. */
1936: operands[2] = XEXP (operands[2], 0);
1937: if (GET_CODE (operands[2]) == REG)
1938: return output_delayed_branch (\"calli %2\", operands, insn);
1939: return output_delayed_branch (\"call %2\", operands, insn);
1940: }")
1941:
1942: (define_expand "call_value"
1943: [(set (match_operand 0 "register_operand" "rf")
1944: (call (match_operand:SI 1 "memory_operand" "m")
1945: (match_operand 2 "" "i")))]
1946: ;; operand 3 is next_arg_register
1947: ""
1948: "
1949: {
1950: if (INTVAL (operands[2]) > 0)
1951: {
1952: emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
1953: emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
1954: }
1955: }")
1956:
1957: (define_insn ""
1958: [(set (match_operand 0 "register_operand" "=rf")
1959: (call (match_operand:SI 1 "memory_operand" "m")
1960: (match_operand 2 "" "i")))]
1961: ;; operand 3 is next_arg_register
1962: ""
1963: "*
1964: {
1965: /* strip the MEM. */
1966: operands[1] = XEXP (operands[1], 0);
1967: CC_STATUS_INIT;
1968: if (GET_CODE (operands[1]) == REG)
1969: return \"calli %1\;nop\";
1970: return \"call %1\;nop\";
1971: }")
1972:
1973: (define_peephole
1974: [(set (match_operand:SI 0 "register_operand" "=rf")
1975: (match_operand:SI 1 "single_insn_src_p" "p"))
1976: (set (match_operand 2 "" "=rf")
1977: (call (match_operand:SI 3 "memory_operand" "m")
1978: (match_operand 4 "" "i")))]
1979: ;;- Don't use operand 4 for most machines.
1980: "! reg_mentioned_p (operands[0], operands[3])"
1981: "*
1982: {
1983: /* strip the MEM. */
1984: operands[3] = XEXP (operands[3], 0);
1985: if (GET_CODE (operands[3]) == REG)
1986: return output_delayed_branch (\"calli %3\", operands, insn);
1987: return output_delayed_branch (\"call %3\", operands, insn);
1988: }")
1989:
1990: (define_peephole
1991: [(set (match_operand:SI 0 "memory_operand" "=m")
1992: (match_operand:SI 1 "reg_or_0_operand" "rJf"))
1993: (set (match_operand 2 "" "=rf")
1994: (call (match_operand:SI 3 "memory_operand" "m")
1995: (match_operand 4 "" "i")))]
1996: ;;- Don't use operand 4 for most machines.
1997: ""
1998: "*
1999: {
2000: /* strip the MEM. */
2001: operands[3] = XEXP (operands[3], 0);
2002: if (GET_CODE (operands[3]) == REG)
2003: return output_delayed_branch (\"calli %3\", operands, insn);
2004: return output_delayed_branch (\"call %3\", operands, insn);
2005: }")
2006:
2007: (define_insn "nop"
2008: [(const_int 0)]
2009: ""
2010: "nop")
2011:
2012: (define_insn ""
2013: [(set (match_operand:SI 0 "register_operand" "r")
2014: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2015: (label_ref (match_operand 2 "" "")))))]
2016: ""
2017: "*
2018: {
2019: cc_status.flags = 0;
2020: return \"mov %l2,r31\;ld.l r31(%1),%0\";
2021: }")
2022:
2023: (define_peephole
2024: [(set (match_operand:SI 0 "register_operand" "=rf")
2025: (match_operand:SI 1 "single_insn_src_p" "p"))
2026: (set (pc) (match_operand:SI 2 "register_operand" "r"))
2027: (use (label_ref (match_operand 3 "" "")))]
2028: "REGNO (operands[0]) != REGNO (operands[2])"
2029: "* return output_delayed_branch (\"bri %2\", operands, insn);")
2030:
2031: ;;- Local variables:
2032: ;;- mode:emacs-lisp
2033: ;;- comment-start: ";;- "
2034: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2035: ;;- eval: (modify-syntax-entry ?[ "(]")
2036: ;;- eval: (modify-syntax-entry ?] ")[")
2037: ;;- eval: (modify-syntax-entry ?{ "(}")
2038: ;;- eval: (modify-syntax-entry ?} "){")
2039: ;;- End:
2040:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.