|
|
1.1 root 1: ;; Machine description for Pyramid 90 Series 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: ;; Instruction patterns. When multiple patterns apply,
21: ;; the first one in the file is chosen.
22: ;;
23: ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
24: ;;
25: ;; cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
26: ;; updates for most instructions.
27:
1.1.1.2 root 28: ;; * Try using define_insn instead of some peepholes in more places.
29: ;; * Set REG_NOTES:REG_EQUIV for cvt[bh]w loads. This would make the
30: ;; backward scan in sign_extend needless.
31: ;; * Match (pc) (label_ref) case in peephole patterns.
32: ;; * Should optimize
33: ;; "cmpX op1,op2; b{eq,ne} LY; ucmpX op1.op2; b{lt,le,gt,ge} LZ"
34: ;; to
35: ;; "ucmpX op1,op2; b{eq,ne} LY; b{lt,le,gt,ge} LZ"
36: ;; by pre-scanning insn and running notice_update_cc for them.
37: ;; * Is it necessary to do copy_rtx in the test and compare patterns?
38: ;; * Fix true frame pointer omission.
1.1 root 39: ;; * Make the jump tables contain branches, not addresses! This would
40: ;; save us one instruction.
41: ;; * Could the compilcated scheme for compares be simplyfied, if we had
42: ;; no named cmpqi or cmphi patterns, and instead anonymous patterns for
43: ;; the less-than-word compare cases pyr can handle???
44: ;; * The jump insn seems to accept more than just IR addressing. Would
1.1.1.2 root 45: ;; we win by telling GCC? Or can we use movw into the global reg which
46: ;; is a synonym for pc?
1.1 root 47: ;; * More DImode patterns.
48: ;; * Scan backwards in "zero_extendhisi2", "zero_extendqisi2" to find out
1.1.1.2 root 49: ;; if the extension can be omitted.
1.1 root 50: ;; * "divmodsi" with Pyramid "ediv" insn. Is it possible in rtl??
51: ;; * Would "rcsp tmpreg; u?cmp[bh] op1_regdispl(tmpreg),op2" win in
52: ;; comparison with the two extensions and single test generated now?
53: ;; The rcsp insn could be expanded, and moved out of loops by the
54: ;; optimizer, making 1 (64 bit) insn of 3 (32 bit) insns in loops.
55: ;; The rcsp insn could be followed by an add insn, making non-displacement
56: ;; IR addressing sufficient.
57:
58: ;______________________________________________________________________
59: ;
60: ; Test and Compare Patterns.
61: ;______________________________________________________________________
62:
1.1.1.2 root 63: ; The argument for the rather complicated test and compare expansion
64: ; scheme, is the irregular pyramid instructions for these operations.
65: ; 1) Pyramid has different signed and unsigned compares. 2) HImode
66: ; and QImode integers are memory-memory and immediate-memory only. 3)
67: ; Unsigned HImode compares doesn't exist. 4) Only certain
68: ; combinations of addresses are allowed for memory-memory compares.
69: ; Whenever necessary, in order to fulfill these addressing
70: ; constraints, the compare operands are swapped.
1.1 root 71:
72: (define_expand "tstsi"
73: [(set (cc0)
74: (match_operand:SI 0 "general_operand" ""))]
1.1.1.2 root 75: "" "operands[0] = force_reg (SImode, operands[0]);")
1.1 root 76:
77: (define_insn ""
78: [(set (cc0)
79: (compare (match_operand:SI 0 "memory_operand" "m")
80: (match_operand:SI 1 "memory_operand" "m")))]
81: "weird_memory_memory (operands[0], operands[1])"
82: "*
83: {
84: rtx br_insn = NEXT_INSN (insn);
85: RTX_CODE br_code;
86:
87: if (GET_CODE (br_insn) != JUMP_INSN)
88: abort();
89: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
90:
91: weird_memory_memory (operands[0], operands[1]);
92:
1.1.1.2 root 93: if (swap_operands)
94: {
95: cc_status.flags = CC_REVERSED;
96: if (TRULY_UNSIGNED_COMPARE_P (br_code))
97: {
98: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
99: return \"ucmpw %0,%1\";
100: }
101: return \"cmpw %0,%1\";
102: }
103:
104: if (TRULY_UNSIGNED_COMPARE_P (br_code))
1.1 root 105: {
1.1.1.2 root 106: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
107: return \"ucmpw %1,%0\";
1.1 root 108: }
1.1.1.2 root 109: return \"cmpw %1,%0\";
1.1 root 110: }")
111:
1.1.1.2 root 112: (define_insn "cmpsi"
1.1 root 113: [(set (cc0)
114: (compare (match_operand:SI 0 "general_operand" "r,g")
115: (match_operand:SI 1 "general_operand" "g,r")))]
116: ""
117: "*
118: {
119: rtx br_insn = NEXT_INSN (insn);
120: RTX_CODE br_code;
121:
122: if (GET_CODE (br_insn) != JUMP_INSN)
123: abort();
124: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
125:
1.1.1.2 root 126: if (which_alternative != 0)
127: {
128: cc_status.flags = CC_REVERSED;
129: if (TRULY_UNSIGNED_COMPARE_P (br_code))
130: {
131: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
132: return \"ucmpw %0,%1\";
133: }
134: return \"cmpw %0,%1\";
135: }
136:
137: if (TRULY_UNSIGNED_COMPARE_P (br_code))
1.1 root 138: {
1.1.1.2 root 139: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
140: return \"ucmpw %1,%0\";
1.1 root 141: }
1.1.1.2 root 142: return \"cmpw %1,%0\";
1.1 root 143: }")
144:
145: (define_insn ""
146: [(set (cc0)
1.1.1.2 root 147: (match_operand:SI 0 "general_operand" "r"))]
1.1 root 148: ""
1.1.1.2 root 149: "*
150: {
151: rtx br_insn = NEXT_INSN (insn);
152: RTX_CODE br_code;
153:
154: if (GET_CODE (br_insn) != JUMP_INSN)
155: abort();
156: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
157:
158: if (TRULY_UNSIGNED_COMPARE_P (br_code))
159: {
160: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
161: return \"ucmpw $0,%0\";
162: }
163: return \"mtstw %0,%0\";
164: }")
1.1 root 165:
166: (define_expand "cmphi"
167: [(set (cc0)
168: (compare (match_operand:HI 0 "general_operand" "")
169: (match_operand:HI 1 "general_operand" "")))]
170: ""
171: "
172: {
1.1.1.2 root 173: extern rtx test_op0, test_op1; extern enum machine_mode test_mode;
1.1 root 174: test_op0 = copy_rtx (operands[0]);
175: test_op1 = copy_rtx (operands[1]);
1.1.1.2 root 176: test_mode = HImode;
1.1 root 177: DONE;
178: }")
179:
1.1.1.3 ! root 180: (define_insn "tsthi"
1.1 root 181: [(set (cc0)
1.1.1.3 ! root 182: (match_operand:HI 0 "nonimmediate_operand" "rm"))]
1.1 root 183: ""
1.1.1.3 ! root 184: "*
1.1 root 185: {
1.1.1.3 ! root 186: cc_status.flags = CC_NO_OVERFLOW;
! 187: return \"cvthw %0,lr15\";
1.1 root 188: }")
189:
190: (define_insn ""
191: [(set (cc0)
192: (compare (match_operand:HI 0 "memory_operand" "m")
193: (match_operand:HI 1 "memory_operand" "m")))]
194: "weird_memory_memory (operands[0], operands[1])"
195: "*
196: {
197: rtx br_insn = NEXT_INSN (insn);
198:
199: if (GET_CODE (br_insn) != JUMP_INSN)
200: abort();
201:
202: weird_memory_memory (operands[0], operands[1]);
203:
1.1.1.2 root 204: if (swap_operands)
1.1 root 205: {
1.1.1.2 root 206: cc_status.flags = CC_REVERSED;
1.1 root 207: return \"cmph %0,%1\";
208: }
1.1.1.2 root 209:
210: return \"cmph %1,%0\";
1.1 root 211: }")
212:
213: (define_insn ""
214: [(set (cc0)
215: (compare (match_operand:HI 0 "nonimmediate_operand" "r,m")
216: (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
1.1.1.2 root 217: "(GET_CODE (operands[0]) != GET_CODE (operands[1]))"
1.1 root 218: "*
219: {
220: rtx br_insn = NEXT_INSN (insn);
221:
222: if (GET_CODE (br_insn) != JUMP_INSN)
223: abort();
224:
1.1.1.2 root 225: if (which_alternative != 0)
1.1 root 226: {
1.1.1.2 root 227: cc_status.flags = CC_REVERSED;
1.1 root 228: return \"cmph %0,%1\";
229: }
1.1.1.2 root 230:
231: return \"cmph %1,%0\";
1.1 root 232: }")
233:
234: (define_expand "cmpqi"
235: [(set (cc0)
236: (compare (match_operand:QI 0 "general_operand" "")
237: (match_operand:QI 1 "general_operand" "")))]
238: ""
239: "
240: {
1.1.1.2 root 241: extern rtx test_op0, test_op1; extern enum machine_mode test_mode;
1.1 root 242: test_op0 = copy_rtx (operands[0]);
243: test_op1 = copy_rtx (operands[1]);
1.1.1.2 root 244: test_mode = QImode;
1.1 root 245: DONE;
246: }")
247:
1.1.1.3 ! root 248: (define_insn "tstqi"
1.1 root 249: [(set (cc0)
1.1.1.3 ! root 250: (match_operand:QI 0 "nonimmediate_operand" "rm"))]
1.1 root 251: ""
1.1.1.3 ! root 252: "*
1.1 root 253: {
1.1.1.3 ! root 254: cc_status.flags = CC_NO_OVERFLOW;
! 255: return \"cvtbw %0,lr15\";
1.1 root 256: }")
257:
258: (define_insn ""
259: [(set (cc0)
260: (compare (match_operand:QI 0 "memory_operand" "m")
261: (match_operand:QI 1 "memory_operand" "m")))]
262: "weird_memory_memory (operands[0], operands[1])"
263: "*
264: {
265: rtx br_insn = NEXT_INSN (insn);
266: RTX_CODE br_code;
267:
268: if (GET_CODE (br_insn) != JUMP_INSN)
269: abort();
270: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
271:
272: weird_memory_memory (operands[0], operands[1]);
273:
1.1.1.2 root 274: if (swap_operands)
275: {
276: cc_status.flags = CC_REVERSED;
277: if (TRULY_UNSIGNED_COMPARE_P (br_code))
278: {
279: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
280: return \"ucmpb %0,%1\";
281: }
282: return \"cmpb %0,%1\";
283: }
284:
285: if (TRULY_UNSIGNED_COMPARE_P (br_code))
1.1 root 286: {
1.1.1.2 root 287: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
288: return \"ucmpb %1,%0\";
1.1 root 289: }
1.1.1.2 root 290: return \"cmpb %1,%0\";
1.1 root 291: }")
292:
293: (define_insn ""
294: [(set (cc0)
295: (compare (match_operand:QI 0 "nonimmediate_operand" "r,m")
296: (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
1.1.1.2 root 297: "(GET_CODE (operands[0]) != GET_CODE (operands[1]))"
1.1 root 298: "*
299: {
300: rtx br_insn = NEXT_INSN (insn);
301: RTX_CODE br_code;
302:
303: if (GET_CODE (br_insn) != JUMP_INSN)
304: abort();
305: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
306:
1.1.1.2 root 307: if (which_alternative != 0)
308: {
309: cc_status.flags = CC_REVERSED;
310: if (TRULY_UNSIGNED_COMPARE_P (br_code))
311: {
312: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
313: return \"ucmpb %0,%1\";
314: }
315: return \"cmpb %0,%1\";
316: }
317:
318: if (TRULY_UNSIGNED_COMPARE_P (br_code))
1.1 root 319: {
1.1.1.2 root 320: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
321: return \"ucmpb %1,%0\";
1.1 root 322: }
1.1.1.2 root 323: return \"cmpb %1,%0\";
1.1 root 324: }")
325:
326: (define_expand "bgt"
327: [(set (pc) (if_then_else (gt (cc0) (const_int 0))
328: (label_ref (match_operand 0 "" "")) (pc)))]
329: "" "extend_and_branch (SIGN_EXTEND);")
330:
331: (define_expand "blt"
332: [(set (pc) (if_then_else (lt (cc0) (const_int 0))
333: (label_ref (match_operand 0 "" "")) (pc)))]
334: "" "extend_and_branch (SIGN_EXTEND);")
335:
336: (define_expand "bge"
337: [(set (pc) (if_then_else (ge (cc0) (const_int 0))
338: (label_ref (match_operand 0 "" "")) (pc)))]
339: "" "extend_and_branch (SIGN_EXTEND);")
340:
341: (define_expand "ble"
342: [(set (pc) (if_then_else (le (cc0) (const_int 0))
343: (label_ref (match_operand 0 "" "")) (pc)))]
344: "" "extend_and_branch (SIGN_EXTEND);")
345:
346: (define_expand "beq"
347: [(set (pc) (if_then_else (eq (cc0) (const_int 0))
348: (label_ref (match_operand 0 "" "")) (pc)))]
349: "" "extend_and_branch (SIGN_EXTEND);")
350:
351: (define_expand "bne"
352: [(set (pc) (if_then_else (ne (cc0) (const_int 0))
353: (label_ref (match_operand 0 "" "")) (pc)))]
354: "" "extend_and_branch (SIGN_EXTEND);")
355:
356: (define_expand "bgtu"
357: [(set (pc) (if_then_else (gtu (cc0) (const_int 0))
358: (label_ref (match_operand 0 "" "")) (pc)))]
359: "" "extend_and_branch (ZERO_EXTEND);")
360:
361: (define_expand "bltu"
362: [(set (pc) (if_then_else (ltu (cc0) (const_int 0))
363: (label_ref (match_operand 0 "" "")) (pc)))]
364: "" "extend_and_branch (ZERO_EXTEND);")
365:
366: (define_expand "bgeu"
367: [(set (pc) (if_then_else (geu (cc0) (const_int 0))
368: (label_ref (match_operand 0 "" "")) (pc)))]
369: "" "extend_and_branch (ZERO_EXTEND);")
370:
371: (define_expand "bleu"
372: [(set (pc) (if_then_else (leu (cc0) (const_int 0))
373: (label_ref (match_operand 0 "" "")) (pc)))]
374: "" "extend_and_branch (ZERO_EXTEND);")
375:
376: (define_insn "cmpdf"
377: [(set (cc0)
378: (compare (match_operand:DF 0 "register_operand" "r")
379: (match_operand:DF 1 "register_operand" "r")))]
380: ""
381: "cmpd %1,%0")
382:
383: (define_insn "cmpsf"
384: [(set (cc0)
385: (compare (match_operand:SF 0 "register_operand" "r")
386: (match_operand:SF 1 "register_operand" "r")))]
387: ""
388: "cmpf %1,%0")
389:
390: (define_insn "tstdf"
391: [(set (cc0)
392: (match_operand:DF 0 "register_operand" "r"))]
393: ""
394: "mtstd %0,%0")
395:
396: (define_insn "tstsf"
397: [(set (cc0)
398: (match_operand:SF 0 "register_operand" "r"))]
399: ""
400: "mtstf %0,%0")
401:
402: ;______________________________________________________________________
403: ;
404: ; Fixed-point Arithmetic.
405: ;______________________________________________________________________
406:
407: (define_insn "addsi3"
408: [(set (match_operand:SI 0 "register_operand" "=r,!r")
1.1.1.3 ! root 409: (plus:SI (match_operand:SI 1 "general_operand" "%0,r")
1.1 root 410: (match_operand:SI 2 "general_operand" "g,rJ")))]
411: ""
412: "*
413: {
414: if (which_alternative == 0)
415: return \"addw %2,%0\";
416: else
417: {
1.1.1.2 root 418: forget_cc_if_dependent (operands[0]);
419: return REG_P (operands[2])
420: ? \"mova (%2)[%1*1],%0\" : \"mova %a2[%1*1],%0\";
1.1 root 421: }
422: }")
423:
424: (define_insn "subsi3"
425: [(set (match_operand:SI 0 "register_operand" "=r,r")
426: (minus:SI (match_operand:SI 1 "general_operand" "0,g")
427: (match_operand:SI 2 "general_operand" "g,0")))]
428: ""
1.1.1.2 root 429: "* return (which_alternative == 0) ? \"subw %2,%0\" : \"rsubw %1,%0\";")
1.1 root 430:
431: (define_insn "mulsi3"
432: [(set (match_operand:SI 0 "register_operand" "=r")
1.1.1.3 ! root 433: (mult:SI (match_operand:SI 1 "general_operand" "%0")
1.1 root 434: (match_operand:SI 2 "general_operand" "g")))]
435: ""
436: "mulw %2,%0")
437:
438: (define_insn "umulsi3"
439: [(set (match_operand:SI 0 "register_operand" "=r")
1.1.1.3 ! root 440: (umult:SI (match_operand:SI 1 "general_operand" "%0")
1.1 root 441: (match_operand:SI 2 "general_operand" "g")))]
442: ""
443: "umulw %2,%0")
444:
445: (define_insn "divsi3"
446: [(set (match_operand:SI 0 "register_operand" "=r,r")
447: (div:SI (match_operand:SI 1 "general_operand" "0,g")
448: (match_operand:SI 2 "general_operand" "g,0")))]
449: ""
1.1.1.2 root 450: "* return (which_alternative == 0) ? \"divw %2,%0\" : \"rdivw %1,%0\";")
1.1 root 451:
452: (define_insn "udivsi3"
453: [(set (match_operand:SI 0 "register_operand" "=r")
454: (udiv:SI (match_operand:SI 1 "register_operand" "0")
455: (match_operand:SI 2 "general_operand" "g")))]
456: ""
1.1.1.2 root 457: "udivw %2,%0")
1.1 root 458:
459: (define_insn "modsi3"
460: [(set (match_operand:SI 0 "register_operand" "=r")
461: (mod:SI (match_operand:SI 1 "register_operand" "0")
462: (match_operand:SI 2 "general_operand" "g")))]
463: ""
464: "modw %2,%0")
465:
466: (define_insn "umodsi3"
467: [(set (match_operand:SI 0 "register_operand" "=r")
468: (umod:SI (match_operand:SI 1 "register_operand" "0")
469: (match_operand:SI 2 "general_operand" "g")))]
470: ""
1.1.1.2 root 471: "umodw %2,%0")
1.1 root 472:
473: (define_insn "negsi2"
474: [(set (match_operand:SI 0 "register_operand" "=r")
475: (neg:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
476: ""
477: "mnegw %1,%0")
478:
479: (define_insn "one_cmplsi2"
480: [(set (match_operand:SI 0 "register_operand" "=r")
481: (not:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
482: ""
483: "mcomw %1,%0")
484:
485: (define_insn "abssi2"
486: [(set (match_operand:SI 0 "register_operand" "=r")
487: (abs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
488: ""
489: "mabsw %1,%0")
490:
491: ;______________________________________________________________________
492: ;
493: ; Floating-point Arithmetic.
494: ;______________________________________________________________________
495:
496: (define_insn "adddf3"
497: [(set (match_operand:DF 0 "register_operand" "=r")
498: (plus:DF (match_operand:DF 1 "register_operand" "%0")
499: (match_operand:DF 2 "register_operand" "r")))]
500: ""
501: "addd %2,%0")
502:
503: (define_insn "addsf3"
504: [(set (match_operand:SF 0 "register_operand" "=r")
505: (plus:SF (match_operand:SF 1 "register_operand" "%0")
506: (match_operand:SF 2 "register_operand" "r")))]
507: ""
508: "addf %2,%0")
509:
510: (define_insn "subdf3"
511: [(set (match_operand:DF 0 "register_operand" "=r")
512: (minus:DF (match_operand:DF 1 "register_operand" "0")
513: (match_operand:DF 2 "register_operand" "r")))]
514: ""
515: "subd %2,%0")
516:
517: (define_insn "subsf3"
518: [(set (match_operand:SF 0 "register_operand" "=r")
519: (minus:SF (match_operand:SF 1 "register_operand" "0")
520: (match_operand:SF 2 "register_operand" "r")))]
521: ""
522: "subf %2,%0")
523:
524: (define_insn "muldf3"
525: [(set (match_operand:DF 0 "register_operand" "=r")
526: (mult:DF (match_operand:DF 1 "register_operand" "%0")
527: (match_operand:DF 2 "register_operand" "r")))]
528: ""
529: "muld %2,%0")
530:
531: (define_insn "mulsf3"
532: [(set (match_operand:SF 0 "register_operand" "=r")
533: (mult:SF (match_operand:SF 1 "register_operand" "%0")
534: (match_operand:SF 2 "register_operand" "r")))]
535: ""
536: "mulf %2,%0")
537:
538: (define_insn "divdf3"
539: [(set (match_operand:DF 0 "register_operand" "=r")
540: (div:DF (match_operand:DF 1 "register_operand" "0")
541: (match_operand:DF 2 "register_operand" "r")))]
542: ""
543: "divd %2,%0")
544:
545: (define_insn "divsf3"
546: [(set (match_operand:SF 0 "register_operand" "=r")
547: (div:SF (match_operand:SF 1 "register_operand" "0")
548: (match_operand:SF 2 "register_operand" "r")))]
549: ""
550: "divf %2,%0")
551:
552: (define_insn "negdf2"
553: [(set (match_operand:DF 0 "register_operand" "=r")
554: (neg:DF (match_operand:DF 1 "register_operand" "r")))]
555: ""
556: "mnegd %1,%0")
557:
558: (define_insn "negsf2"
559: [(set (match_operand:SF 0 "register_operand" "=r")
560: (neg:SF (match_operand:SF 1 "register_operand" "r")))]
561: ""
562: "mnegf %1,%0")
563:
564: (define_insn "absdf2"
565: [(set (match_operand:DF 0 "register_operand" "=r")
566: (abs:DF (match_operand:DF 1 "register_operand" "r")))]
567: ""
568: "mabsd %1,%0")
569:
570: (define_insn "abssf2"
571: [(set (match_operand:SF 0 "register_operand" "=r")
572: (abs:SF (match_operand:SF 1 "register_operand" "r")))]
573: ""
574: "mabsf %1,%0")
575:
576: ;______________________________________________________________________
577: ;
578: ; Logical and Shift Instructions.
579: ;______________________________________________________________________
580:
581: (define_insn ""
582: [(set (cc0)
1.1.1.3 ! root 583: (and:SI (match_operand:SI 0 "general_operand" "%r")
1.1 root 584: (match_operand:SI 1 "general_operand" "g")))]
585: ""
1.1.1.3 ! root 586: "*
! 587: {
! 588: cc_status.flags |= CC_NO_OVERFLOW;
! 589: return \"bitw %1,%0\";
! 590: }")
1.1 root 591:
592: (define_insn "andsi3"
593: [(set (match_operand:SI 0 "register_operand" "=r,r")
1.1.1.3 ! root 594: (and:SI (match_operand:SI 1 "general_operand" "%0,r")
1.1 root 595: (match_operand:SI 2 "general_operand" "g,K")))]
596: ""
597: "*
598: {
599: if (which_alternative == 0)
600: return \"andw %2,%0\";
1.1.1.2 root 601:
602: cc_status.flags = CC_NOT_NEGATIVE;
603: return (INTVAL (operands[2]) == 255
604: ? \"movzbw %1,%0\" : \"movzhw %1,%0\");
1.1 root 605: }")
606:
607: (define_insn "andcbsi3"
608: [(set (match_operand:SI 0 "register_operand" "=r")
609: (and:SI (match_operand:SI 1 "register_operand" "0")
610: (not:SI (match_operand:SI 2 "general_operand" "g"))))]
611: ""
612: "bicw %2,%0")
613:
614: (define_insn ""
615: [(set (match_operand:SI 0 "register_operand" "=r")
616: (and:SI (not:SI (match_operand:SI 1 "general_operand" "g"))
617: (match_operand:SI 2 "register_operand" "0")))]
618: ""
619: "bicw %1,%0")
620:
621: (define_insn "iorsi3"
622: [(set (match_operand:SI 0 "register_operand" "=r")
1.1.1.3 ! root 623: (ior:SI (match_operand:SI 1 "general_operand" "%0")
1.1 root 624: (match_operand:SI 2 "general_operand" "g")))]
625: ""
626: "orw %2,%0")
627:
628: (define_insn "xorsi3"
629: [(set (match_operand:SI 0 "register_operand" "=r")
1.1.1.3 ! root 630: (xor:SI (match_operand:SI 1 "general_operand" "%0")
1.1 root 631: (match_operand:SI 2 "general_operand" "g")))]
632: ""
633: "xorw %2,%0")
634:
1.1.1.2 root 635: ; The arithmetic left shift instructions work strangely on pyramids.
636: ; They fail to modify the sign bit. Therefore, use logic shifts.
1.1 root 637:
638: (define_insn "ashlsi3"
639: [(set (match_operand:SI 0 "register_operand" "=r")
640: (ashift:SI (match_operand:SI 1 "register_operand" "0")
641: (match_operand:SI 2 "general_operand" "rnm")))]
642: ""
1.1.1.2 root 643: "* return output_shift (\"lshlw %2,%0\", operands[2], 32); ")
1.1 root 644:
645: (define_insn "ashrsi3"
646: [(set (match_operand:SI 0 "register_operand" "=r")
647: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
648: (match_operand:SI 2 "general_operand" "rnm")))]
649: ""
1.1.1.2 root 650: "* return output_shift (\"ashrw %2,%0\", operands[2], 32); ")
1.1 root 651:
652: (define_insn "ashrdi3"
653: [(set (match_operand:DI 0 "register_operand" "=r")
654: (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
655: (match_operand:SI 2 "general_operand" "rnm")))]
656: ""
1.1.1.2 root 657: "* return output_shift (\"ashrl %2,%0\", operands[2], 64); ")
1.1 root 658:
659: (define_insn "lshrsi3"
660: [(set (match_operand:SI 0 "register_operand" "=r")
661: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
662: (match_operand:SI 2 "general_operand" "rnm")))]
663: ""
1.1.1.2 root 664: "* return output_shift (\"lshrw %2,%0\", operands[2], 32); ")
1.1 root 665:
666: (define_insn "rotlsi3"
667: [(set (match_operand:SI 0 "register_operand" "=r")
668: (rotate:SI (match_operand:SI 1 "register_operand" "0")
669: (match_operand:SI 2 "general_operand" "rnm")))]
670: ""
1.1.1.2 root 671: "* return output_shift (\"rotlw %2,%0\", operands[2], 32); ")
1.1 root 672:
673: (define_insn "rotrsi3"
674: [(set (match_operand:SI 0 "register_operand" "=r")
675: (rotatert:SI (match_operand:SI 1 "register_operand" "0")
676: (match_operand:SI 2 "general_operand" "rnm")))]
677: ""
1.1.1.2 root 678: "* return output_shift (\"rotrw %2,%0\", operands[2], 32); ")
1.1 root 679:
680: ;______________________________________________________________________
681: ;
682: ; Fixed and Floating Moves.
683: ;______________________________________________________________________
684:
1.1.1.2 root 685: ;; If the destination is a memory operand, indexed source operands are
1.1 root 686: ;; disallowed. Big DImode constants are always loaded into a reg pair,
687: ;; although offsetable memory addresses really could be dealt with.
688:
689: (define_insn ""
690: [(set (match_operand:DI 0 "memory_operand" "=m")
691: (match_operand:DI 1 "nonindexed_operand" "gF"))]
692: "(GET_CODE (operands[1]) == CONST_DOUBLE
1.1.1.2 root 693: ? ((CONST_DOUBLE_HIGH (operands[1]) == 0
694: && CONST_DOUBLE_LOW (operands[1]) >= 0)
695: || (CONST_DOUBLE_HIGH (operands[1]) == -1
696: && CONST_DOUBLE_LOW (operands[1]) < 0))
697: : 1)"
1.1 root 698: "*
699: {
700: if (GET_CODE (operands[1]) == CONST_DOUBLE)
701: operands[1] = gen_rtx (CONST_INT, VOIDmode,
702: CONST_DOUBLE_LOW (operands[1]));
703: return \"movl %1,%0\";
704: }")
705:
706: ;; Force the destination to a register, so all source operands are allowed.
707:
708: (define_insn "movdi"
709: [(set (match_operand:DI 0 "general_operand" "=r")
710: (match_operand:DI 1 "general_operand" "gF"))]
711: ""
712: "* return output_move_double (operands); ")
713:
1.1.1.2 root 714: ;; If the destination is a memory address, indexed source operands are
715: ;; disallowed.
1.1 root 716:
717: (define_insn ""
718: [(set (match_operand:SI 0 "memory_operand" "=m")
719: (match_operand:SI 1 "nonindexed_operand" "g"))]
720: ""
1.1.1.2 root 721: "movw %1,%0")
1.1 root 722:
723: ;; Force the destination to a register, so all source operands are allowed.
724:
725: (define_insn "movsi"
726: [(set (match_operand:SI 0 "general_operand" "=r")
727: (match_operand:SI 1 "general_operand" "g"))]
728: ""
1.1.1.2 root 729: "movw %1,%0")
1.1 root 730:
1.1.1.2 root 731: ;; If the destination is a memory address, indexed source operands are
732: ;; disallowed.
1.1 root 733:
734: (define_insn ""
735: [(set (match_operand:HI 0 "memory_operand" "=m")
736: (match_operand:HI 1 "nonindexed_operand" "g"))]
737: ""
738: "*
739: {
740: if (REG_P (operands[1]))
741: return \"cvtwh %1,%0\"; /* reg -> mem */
742: else
1.1.1.2 root 743: return \"movh %1,%0\"; /* mem imm -> mem */
1.1 root 744: }")
745:
746: ;; Force the destination to a register, so all source operands are allowed.
747:
748: (define_insn "movhi"
749: [(set (match_operand:HI 0 "general_operand" "=r")
750: (match_operand:HI 1 "general_operand" "g"))]
751: ""
752: "*
753: {
754: if (GET_CODE (operands[1]) != MEM)
1.1.1.2 root 755: return \"movw %1,%0\"; /* reg imm -> reg */
756: return \"cvthw %1,%0\"; /* mem -> reg */
1.1 root 757: }")
758:
1.1.1.2 root 759: ;; If the destination is a memory address, indexed source operands are
760: ;; disallowed.
1.1 root 761:
762: (define_insn ""
763: [(set (match_operand:QI 0 "memory_operand" "=m")
764: (match_operand:QI 1 "nonindexed_operand" "g"))]
765: ""
766: "*
767: {
768: if (REG_P (operands[1]))
769: return \"cvtwb %1,%0\"; /* reg -> mem */
770: else
1.1.1.2 root 771: return \"movb %1,%0\"; /* mem imm -> mem */
1.1 root 772: }")
773:
774: ;; Force the destination to a register, so all source operands are allowed.
775:
776: (define_insn "movqi"
777: [(set (match_operand:QI 0 "general_operand" "=r")
778: (match_operand:QI 1 "general_operand" "g"))]
779: ""
780: "*
781: {
782: if (GET_CODE (operands[1]) != MEM)
1.1.1.2 root 783: return \"movw %1,%0\"; /* reg imm -> reg */
784: return \"cvtbw %1,%0\"; /* mem -> reg */
1.1 root 785: }")
786:
1.1.1.2 root 787: ;; If the destination is a memory address, indexed source operands are
788: ;; disallowed.
1.1 root 789:
790: (define_insn ""
791: [(set (match_operand:DF 0 "memory_operand" "=m")
792: (match_operand:DF 1 "nonindexed_operand" "g"))]
793: "GET_CODE (operands[1]) != CONST_DOUBLE"
1.1.1.2 root 794: "movl %1,%0")
1.1 root 795:
796: ;; Force the destination to a register, so all source operands are allowed.
797:
798: (define_insn "movdf"
799: [(set (match_operand:DF 0 "general_operand" "=r")
800: (match_operand:DF 1 "general_operand" "gF"))]
801: ""
802: "* return output_move_double (operands); ")
803:
1.1.1.2 root 804: ;; If the destination is a memory address, indexed source operands are
805: ;; disallowed.
1.1 root 806:
807: (define_insn ""
808: [(set (match_operand:SF 0 "memory_operand" "=m")
809: (match_operand:SF 1 "nonindexed_operand" "g"))]
810: ""
1.1.1.2 root 811: "movw %1,%0")
1.1 root 812:
813: ;; Force the destination to a register, so all source operands are allowed.
814:
815: (define_insn "movsf"
816: [(set (match_operand:SF 0 "general_operand" "=r")
817: (match_operand:SF 1 "general_operand" "g"))]
818: ""
1.1.1.2 root 819: "movw %1,%0")
1.1 root 820:
821: (define_insn ""
822: [(set (match_operand:SI 0 "register_operand" "=r")
823: (match_operand:QI 1 "address_operand" "p"))]
824: ""
825: "*
1.1.1.2 root 826: {
827: forget_cc_if_dependent (operands[0]);
1.1 root 828: return \"mova %a1,%0\";
1.1.1.2 root 829: }")
1.1 root 830:
831: ;______________________________________________________________________
832: ;
833: ; Conversion patterns.
834: ;______________________________________________________________________
835:
836: ;; The trunc patterns are used only when non compile-time constants are used.
837:
838: (define_insn "truncsiqi2"
1.1.1.2 root 839: [(set (match_operand:QI 0 "register_operand" "=r")
840: (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
1.1 root 841: ""
842: "*
843: {
1.1.1.2 root 844: if (REG_P (operands[0]) && REG_P (operands[1])
845: && REGNO (operands[0]) == REGNO (operands[1]))
846: {
847: cc_status = cc_prev_status;
848: return \"\";
849: }
850: forget_cc_if_dependent (operands[0]);
851: return \"movw %1,%0\";
1.1 root 852: }")
853:
854: (define_insn "truncsihi2"
1.1.1.2 root 855: [(set (match_operand:HI 0 "register_operand" "=r")
856: (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
1.1 root 857: ""
858: "*
859: {
1.1.1.2 root 860: if (REG_P (operands[0]) && REG_P (operands[1])
861: && REGNO (operands[0]) == REGNO (operands[1]))
862: {
863: cc_status = cc_prev_status;
864: return \"\";
865: }
866: forget_cc_if_dependent (operands[0]);
867: return \"movw %1,%0\";
1.1 root 868: }")
869:
870: (define_insn "extendhisi2"
871: [(set (match_operand:SI 0 "general_operand" "=r,m")
872: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm,r")))]
873: ""
874: "*
875: {
876: extern int optimize;
877: if (optimize && REG_P (operands[0]) && REG_P (operands[1])
878: && REGNO (operands[0]) == REGNO (operands[1])
879: && already_sign_extended (insn, HImode, operands[0]))
880: {
1.1.1.2 root 881: cc_status = cc_prev_status;
1.1 root 882: return \"\";
883: }
884: return \"cvthw %1,%0\";
885: }")
886:
887: (define_insn "extendqisi2"
888: [(set (match_operand:SI 0 "general_operand" "=r,m")
889: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm,r")))]
890: ""
891: "*
892: {
893: extern int optimize;
894: if (optimize && REG_P (operands[0]) && REG_P (operands[1])
895: && REGNO (operands[0]) == REGNO (operands[1])
896: && already_sign_extended (insn, QImode, operands[0]))
897: {
1.1.1.2 root 898: cc_status = cc_prev_status;
1.1 root 899: return \"\";
900: }
901: return \"cvtbw %1,%0\";
902: }")
903:
904: ; Pyramid doesn't have insns *called* "cvtbh" or "movzbh".
905: ; But we can cvtbw/movzbw into a register, where there is no distinction
906: ; between words and halfwords.
1.1.1.2 root 907:
1.1 root 908: (define_insn "extendqihi2"
909: [(set (match_operand:HI 0 "register_operand" "=r")
910: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
911: ""
912: "cvtbw %1,%0")
913:
914: (define_insn "zero_extendhisi2"
915: [(set (match_operand:SI 0 "register_operand" "=r")
916: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
917: ""
918: "*
919: {
1.1.1.2 root 920: cc_status.flags = CC_NOT_NEGATIVE;
1.1 root 921: return \"movzhw %1,%0\";
922: }")
923:
924: (define_insn "zero_extendqisi2"
925: [(set (match_operand:SI 0 "register_operand" "=r")
926: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
927: ""
928: "*
929: {
1.1.1.2 root 930: cc_status.flags = CC_NOT_NEGATIVE;
1.1 root 931: return \"movzbw %1,%0\";
932: }")
933:
934: (define_insn "zero_extendqihi2"
935: [(set (match_operand:HI 0 "register_operand" "=r")
936: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
937: ""
938: "*
939: {
1.1.1.2 root 940: cc_status.flags = CC_NOT_NEGATIVE;
1.1 root 941: return \"movzbw %1,%0\";
942: }")
943:
944: (define_insn "extendsfdf2"
1.1.1.3 ! root 945: [(set (match_operand:DF 0 "general_operand" "=&r,m")
1.1 root 946: (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "rm,r")))]
947: ""
948: "cvtfd %1,%0")
949:
950: (define_insn "truncdfsf2"
1.1.1.3 ! root 951: [(set (match_operand:SF 0 "general_operand" "=&r,m")
1.1 root 952: (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "rm,r")))]
953: ""
954: "cvtdf %1,%0")
955:
956: (define_insn "floatsisf2"
1.1.1.3 ! root 957: [(set (match_operand:SF 0 "general_operand" "=&r,m")
1.1 root 958: (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
959: ""
960: "cvtwf %1,%0")
961:
962: (define_insn "floatsidf2"
1.1.1.3 ! root 963: [(set (match_operand:DF 0 "general_operand" "=&r,m")
1.1 root 964: (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
965: ""
966: "cvtwd %1,%0")
967:
968: (define_insn "fix_truncsfsi2"
1.1.1.3 ! root 969: [(set (match_operand:SI 0 "general_operand" "=&r,m")
1.1 root 970: (fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "rm,r"))))]
971: ""
972: "cvtfw %1,%0")
973:
974: (define_insn "fix_truncdfsi2"
1.1.1.3 ! root 975: [(set (match_operand:SI 0 "general_operand" "=&r,m")
1.1 root 976: (fix:SI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "rm,r"))))]
977: ""
978: "cvtdw %1,%0")
979:
980: ;______________________________________________________________________
981: ;
982: ; Flow Control Patterns.
983: ;______________________________________________________________________
984:
985: ;; Prefer "br" to "jump" for unconditional jumps, since it's faster.
986: ;; (The assembler can manage with out-of-range branches.)
987:
988: (define_insn "jump"
989: [(set (pc)
990: (label_ref (match_operand 0 "" "")))]
991: ""
992: "br %l0")
993:
994: (define_insn ""
995: [(set (pc)
996: (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
997: (label_ref (match_operand 1 "" ""))
998: (pc)))]
999: ""
1.1.1.2 root 1000: "*
1001: {
1002: extern int optimize;
1003: if (optimize)
1004: switch (GET_CODE (operands[0]))
1005: {
1006: case EQ: case NE:
1007: break;
1008: case LT: case LE: case GE: case GT:
1009: if (cc_prev_status.mdep == CC_VALID_FOR_UNSIGNED)
1010: return 0;
1011: break;
1012: case LTU: case LEU: case GEU: case GTU:
1013: if (cc_prev_status.mdep != CC_VALID_FOR_UNSIGNED)
1014: return 0;
1015: break;
1016: }
1017:
1018: return \"b%N0 %l1\";
1019: }")
1.1 root 1020:
1021: (define_insn ""
1022: [(set (pc)
1023: (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
1024: (pc)
1025: (label_ref (match_operand 1 "" ""))))]
1026: ""
1.1.1.2 root 1027: "*
1028: {
1029: extern int optimize;
1030: if (optimize)
1031: switch (GET_CODE (operands[0]))
1032: {
1033: case EQ: case NE:
1034: break;
1035: case LT: case LE: case GE: case GT:
1036: if (cc_prev_status.mdep == CC_VALID_FOR_UNSIGNED)
1037: return 0;
1038: break;
1039: case LTU: case LEU: case GEU: case GTU:
1040: if (cc_prev_status.mdep != CC_VALID_FOR_UNSIGNED)
1041: return 0;
1042: break;
1043: }
1044:
1045: return \"b%C0 %l1\";
1046: }")
1.1 root 1047:
1048: (define_insn "call"
1049: [(call (match_operand:QI 0 "memory_operand" "m")
1.1.1.2 root 1050: (match_operand:SI 1 "immediate_operand" "n"))]
1.1 root 1051: ""
1052: "call %0")
1053:
1054: (define_insn "call_value"
1055: [(set (match_operand 0 "" "=r")
1056: (call (match_operand:QI 1 "memory_operand" "m")
1057: (match_operand:SI 2 "immediate_operand" "n")))]
1058: ;; Operand 2 not really used on Pyramid architecture.
1059: ""
1060: "call %1")
1061:
1.1.1.2 root 1062: (define_insn "return"
1.1 root 1063: [(return)]
1064: ""
1.1.1.2 root 1065: "*
1066: {
1067: if (get_frame_size () + current_function_pretend_args_size
1068: + current_function_args_size != 0
1069: || current_function_calls_alloca)
1070: {
1071: int dealloc_size = current_function_pretend_args_size;
1072: if (current_function_pops_args)
1073: dealloc_size += current_function_args_size;
1074: operands[0] = gen_rtx (CONST_INT, VOIDmode, dealloc_size);
1075: return \"retd %0\";
1076: }
1077: else
1078: return \"ret\";
1079: }")
1.1 root 1080:
1081: (define_insn "tablejump"
1082: [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1083: (use (label_ref (match_operand 1 "" "")))]
1084: ""
1085: "jump (%0)")
1.1.1.2 root 1086:
1087: (define_insn "nop"
1088: [(const_int 0)]
1089: ""
1090: "movw gr0,gr0 # nop")
1.1 root 1091:
1092: ;______________________________________________________________________
1093: ;
1094: ; Peep-hole Optimization Patterns.
1095: ;______________________________________________________________________
1096:
1097: ;; Optimize fullword move followed by a test of the moved value.
1098:
1.1.1.2 root 1099: (define_peephole
1100: [(set (match_operand:SI 0 "register_operand" "=r")
1101: (match_operand:SI 1 "nonimmediate_operand" "rm"))
1102: (set (cc0) (match_operand:SI 2 "nonimmediate_operand" "rm"))]
1103: "rtx_equal_p (operands[2], operands[0])
1104: || rtx_equal_p (operands[2], operands[1])"
1105: "*
1106: cc_status.flags |= CC_NO_OVERFLOW;
1107: return \"mtstw %1,%0\";
1108: ")
1109:
1110: ;; Same for HI and QI mode move-test as well.
1111:
1112: (define_peephole
1113: [(set (match_operand:HI 0 "register_operand" "=r")
1114: (match_operand:HI 1 "nonimmediate_operand" "rm"))
1115: (set (match_operand:SI 2 "register_operand" "=r")
1116: (sign_extend:SI (match_operand:HI 3 "nonimmediate_operand" "rm")))
1117: (set (cc0) (match_dup 2))]
1118: "dead_or_set_p (insn, operands[2])
1119: && (rtx_equal_p (operands[3], operands[0])
1120: || rtx_equal_p (operands[3], operands[1]))"
1121: "*
1122: cc_status.flags |= CC_NO_OVERFLOW;
1123: return \"cvthw %1,%0\";
1124: ")
1125:
1126: (define_peephole
1127: [(set (match_operand:QI 0 "register_operand" "=r")
1128: (match_operand:QI 1 "nonimmediate_operand" "rm"))
1129: (set (match_operand:SI 2 "register_operand" "=r")
1130: (sign_extend:SI (match_operand:QI 3 "nonimmediate_operand" "rm")))
1131: (set (cc0) (match_dup 2))]
1132: "dead_or_set_p (insn, operands[2])
1133: && (rtx_equal_p (operands[3], operands[0])
1134: || rtx_equal_p (operands[3], operands[1]))"
1135: "*
1136: cc_status.flags |= CC_NO_OVERFLOW;
1137: return \"cvtbw %1,%0\";
1138: ")
1139:
1140: ;; Optimize loops with an incremented/decremented variable.
1141:
1142: (define_peephole
1143: [(set (match_operand:SI 0 "register_operand" "=r")
1144: (plus:SI (match_dup 0)
1145: (const_int -1)))
1146: (set (cc0)
1147: (compare (match_operand:SI 1 "register_operand" "r")
1148: (match_operand:SI 2 "nonmemory_operand" "ri")))
1149: (set (pc)
1150: (if_then_else (match_operator:SI 3 "signed_comparison"
1151: [(cc0) (const_int 0)])
1152: (label_ref (match_operand 4 "" ""))
1153: (pc)))]
1154: "(GET_CODE (operands[2]) == CONST_INT
1155: ? (unsigned)INTVAL (operands[2]) + 32 >= 64
1156: : 1) && (rtx_equal_p (operands[0], operands[1])
1157: || rtx_equal_p (operands[0], operands[2]))"
1158: "*
1159: if (rtx_equal_p (operands[0], operands[1]))
1160: {
1161: output_asm_insn (\"dcmpw %2,%0\", operands);
1162: return \"b%N3 %l4\";
1163: }
1164: else
1165: {
1166: output_asm_insn (\"dcmpw %1,%0\", operands);
1167: return \"b%R3 %l4\";
1168: }
1169: ")
1170:
1171: (define_peephole
1172: [(set (match_operand:SI 0 "register_operand" "=r")
1173: (plus:SI (match_dup 0)
1174: (const_int 1)))
1175: (set (cc0)
1176: (compare (match_operand:SI 1 "register_operand" "r")
1177: (match_operand:SI 2 "nonmemory_operand" "ri")))
1178: (set (pc)
1179: (if_then_else (match_operator:SI 3 "signed_comparison"
1180: [(cc0) (const_int 0)])
1181: (label_ref (match_operand 4 "" ""))
1182: (pc)))]
1183: "(GET_CODE (operands[2]) == CONST_INT
1184: ? (unsigned)INTVAL (operands[2]) + 32 >= 64
1185: : 1) && (rtx_equal_p (operands[0], operands[1])
1186: || rtx_equal_p (operands[0], operands[2]))"
1187: "*
1188: if (rtx_equal_p (operands[0], operands[1]))
1189: {
1190: output_asm_insn (\"icmpw %2,%0\", operands);
1191: return \"b%N3 %l4\";
1192: }
1193: else
1194: {
1195: output_asm_insn (\"icmpw %1,%0\", operands);
1196: return \"b%R3 %l4\";
1197: }
1198: ")
1199:
1.1.1.3 ! root 1200: ;; Combine two word moves with consecutive operands into one long move.
1.1.1.2 root 1201: ;; Also combines immediate moves, if the high-order destination operand
1202: ;; is loaded with 0 or -1 and the low-order destination operand is loaded
1203: ;; with a constant with the same sign.
1204:
1205: (define_peephole
1206: [(set (match_operand:SI 0 "general_operand" "=g")
1207: (match_operand:SI 1 "general_operand" "g"))
1208: (set (match_operand:SI 2 "general_operand" "=g")
1209: (match_operand:SI 3 "general_operand" "g"))]
1210: "movdi_possible (operands)"
1211: "*
1212: output_asm_insn (\"# COMBINE movw %1,%0\", operands);
1213: output_asm_insn (\"# COMBINE movw %3,%2\", operands);
1214: movdi_possible (operands);
1215: if (CONSTANT_P (operands[1]))
1216: return (swap_operands) ? \"movl %3,%0\" : \"movl %1,%2\";
1217:
1218: return (swap_operands) ? \"movl %1,%0\" : \"movl %3,%2\";
1219: ")
1220:
1221: ;; Optimize certain tests after memory stores.
1222:
1223: (define_peephole
1224: [(set (match_operand 0 "memory_operand" "=m")
1225: (match_operand 1 "register_operand" "r"))
1226: (set (match_operand:SI 2 "register_operand" "=r")
1227: (sign_extend:SI (match_dup 1)))
1228: (set (cc0)
1229: (match_dup 2))]
1230: "dead_or_set_p (insn, operands[2])"
1231: "*
1232: cc_status.flags |= CC_NO_OVERFLOW;
1233: if (GET_MODE (operands[0]) == QImode)
1234: return \"cvtwb %1,%0\";
1235: else
1236: return \"cvtwh %1,%0\";
1237: ")
1.1 root 1238:
1239: ;______________________________________________________________________
1240: ;
1241: ; DImode Patterns.
1242: ;______________________________________________________________________
1243:
1244: (define_expand "extendsidi2"
1245: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
1.1.1.2 root 1246: (match_operand:SI 1 "general_operand" "g"))
1.1 root 1247: (set (subreg:SI (match_dup 0) 0)
1248: (subreg:SI (match_dup 0) 1))
1249: (set (subreg:SI (match_dup 0) 0)
1250: (ashiftrt:SI (subreg:SI (match_dup 0) 0)
1251: (const_int 31)))]
1252: ""
1253: "")
1254:
1255: (define_insn "adddi3"
1256: [(set (match_operand:DI 0 "register_operand" "=r")
1.1.1.3 ! root 1257: (plus:DI (match_operand:DI 1 "nonmemory_operand" "%0")
1.1 root 1258: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1259: ""
1260: "*
1261: {
1262: rtx xoperands[2];
1263: CC_STATUS_INIT;
1264: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1265: if (REG_P (operands[2]))
1266: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1267: else
1268: {
1269: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1270: CONST_DOUBLE_LOW (operands[2]));
1271: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1272: CONST_DOUBLE_HIGH (operands[2]));
1273: }
1274: output_asm_insn (\"addw %1,%0\", xoperands);
1275: return \"addwc %2,%0\";
1276: }")
1277:
1278: (define_insn "subdi3"
1279: [(set (match_operand:DI 0 "register_operand" "=r")
1280: (minus:DI (match_operand:DI 1 "register_operand" "0")
1281: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1282: ""
1283: "*
1284: {
1285: rtx xoperands[2];
1286: CC_STATUS_INIT;
1287: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1288: if (REG_P (operands[2]))
1289: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1290: else
1291: {
1292: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1293: CONST_DOUBLE_LOW (operands[2]));
1294: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1295: CONST_DOUBLE_HIGH (operands[2]));
1296: }
1297: output_asm_insn (\"subw %1,%0\", xoperands);
1298: return \"subwb %2,%0\";
1299: }")
1300:
1301: (define_insn "iordi3"
1302: [(set (match_operand:DI 0 "register_operand" "=r")
1.1.1.3 ! root 1303: (ior:DI (match_operand:DI 1 "nonmemory_operand" "%0")
1.1 root 1304: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1305: ""
1306: "*
1307: {
1308: rtx xoperands[2];
1309: CC_STATUS_INIT;
1310: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1311: if (REG_P (operands[2]))
1312: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1313: else
1314: {
1315: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1316: CONST_DOUBLE_LOW (operands[2]));
1317: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1318: CONST_DOUBLE_HIGH (operands[2]));
1319: }
1320: output_asm_insn (\"orw %1,%0\", xoperands);
1321: return \"orw %2,%0\";
1322: }")
1323:
1324: (define_insn "anddi3"
1325: [(set (match_operand:DI 0 "register_operand" "=r")
1.1.1.3 ! root 1326: (and:DI (match_operand:DI 1 "nonmemory_operand" "%0")
1.1 root 1327: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1328: ""
1329: "*
1330: {
1331: rtx xoperands[2];
1332: CC_STATUS_INIT;
1333: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1334: if (REG_P (operands[2]))
1335: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1336: else
1337: {
1338: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1339: CONST_DOUBLE_LOW (operands[2]));
1340: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1341: CONST_DOUBLE_HIGH (operands[2]));
1342: }
1343: output_asm_insn (\"andw %1,%0\", xoperands);
1344: return \"andw %2,%0\";
1345: }")
1346:
1347: (define_insn "xordi3"
1348: [(set (match_operand:DI 0 "register_operand" "=r")
1.1.1.3 ! root 1349: (xor:DI (match_operand:DI 1 "nonmemory_operand" "%0")
1.1 root 1350: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1351: ""
1352: "*
1353: {
1354: rtx xoperands[2];
1355: CC_STATUS_INIT;
1356: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1357: if (REG_P (operands[2]))
1358: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1359: else
1360: {
1361: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1362: CONST_DOUBLE_LOW (operands[2]));
1363: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1364: CONST_DOUBLE_HIGH (operands[2]));
1365: }
1366: output_asm_insn (\"xorw %1,%0\", xoperands);
1367: return \"xorw %2,%0\";
1368: }")
1369:
1370: ;;- Local variables:
1371: ;;- mode:emacs-lisp
1372: ;;- comment-start: ";;- "
1373: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
1374: ;;- eval: (modify-syntax-entry ?] ")[")
1375: ;;- eval: (modify-syntax-entry ?{ "(}")
1376: ;;- eval: (modify-syntax-entry ?} "){")
1377: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.