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