|
|
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:
180: (define_expand "tsthi"
181: [(set (cc0)
182: (match_operand:HI 0 "general_operand" ""))]
183: ""
184: "
185: {
1.1.1.2 ! root 186: extern rtx test_op0; extern enum machine_mode test_mode;
1.1 root 187: test_op0 = copy_rtx (operands[0]);
1.1.1.2 ! root 188: test_mode = HImode;
1.1 root 189: DONE;
190: }")
191:
192: (define_insn ""
193: [(set (cc0)
194: (compare (match_operand:HI 0 "memory_operand" "m")
195: (match_operand:HI 1 "memory_operand" "m")))]
196: "weird_memory_memory (operands[0], operands[1])"
197: "*
198: {
199: rtx br_insn = NEXT_INSN (insn);
200:
201: if (GET_CODE (br_insn) != JUMP_INSN)
202: abort();
203:
204: weird_memory_memory (operands[0], operands[1]);
205:
1.1.1.2 ! root 206: if (swap_operands)
1.1 root 207: {
1.1.1.2 ! root 208: cc_status.flags = CC_REVERSED;
1.1 root 209: return \"cmph %0,%1\";
210: }
1.1.1.2 ! root 211:
! 212: return \"cmph %1,%0\";
1.1 root 213: }")
214:
215: (define_insn ""
216: [(set (cc0)
217: (compare (match_operand:HI 0 "nonimmediate_operand" "r,m")
218: (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
1.1.1.2 ! root 219: "(GET_CODE (operands[0]) != GET_CODE (operands[1]))"
1.1 root 220: "*
221: {
222: rtx br_insn = NEXT_INSN (insn);
223:
224: if (GET_CODE (br_insn) != JUMP_INSN)
225: abort();
226:
1.1.1.2 ! root 227: if (which_alternative != 0)
1.1 root 228: {
1.1.1.2 ! root 229: cc_status.flags = CC_REVERSED;
1.1 root 230: return \"cmph %0,%1\";
231: }
1.1.1.2 ! root 232:
! 233: return \"cmph %1,%0\";
1.1 root 234: }")
235:
236: (define_expand "cmpqi"
237: [(set (cc0)
238: (compare (match_operand:QI 0 "general_operand" "")
239: (match_operand:QI 1 "general_operand" "")))]
240: ""
241: "
242: {
1.1.1.2 ! root 243: extern rtx test_op0, test_op1; extern enum machine_mode test_mode;
1.1 root 244: test_op0 = copy_rtx (operands[0]);
245: test_op1 = copy_rtx (operands[1]);
1.1.1.2 ! root 246: test_mode = QImode;
1.1 root 247: DONE;
248: }")
249:
250: (define_expand "tstqi"
251: [(set (cc0)
252: (match_operand:QI 0 "general_operand" ""))]
253: ""
254: "
255: {
1.1.1.2 ! root 256: extern rtx test_op0; extern enum machine_mode test_mode;
1.1 root 257: test_op0 = copy_rtx (operands[0]);
1.1.1.2 ! root 258: test_mode = QImode;
1.1 root 259: DONE;
260: }")
261:
262: (define_insn ""
263: [(set (cc0)
264: (compare (match_operand:QI 0 "memory_operand" "m")
265: (match_operand:QI 1 "memory_operand" "m")))]
266: "weird_memory_memory (operands[0], operands[1])"
267: "*
268: {
269: rtx br_insn = NEXT_INSN (insn);
270: RTX_CODE br_code;
271:
272: if (GET_CODE (br_insn) != JUMP_INSN)
273: abort();
274: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
275:
276: weird_memory_memory (operands[0], operands[1]);
277:
1.1.1.2 ! root 278: if (swap_operands)
! 279: {
! 280: cc_status.flags = CC_REVERSED;
! 281: if (TRULY_UNSIGNED_COMPARE_P (br_code))
! 282: {
! 283: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
! 284: return \"ucmpb %0,%1\";
! 285: }
! 286: return \"cmpb %0,%1\";
! 287: }
! 288:
! 289: if (TRULY_UNSIGNED_COMPARE_P (br_code))
1.1 root 290: {
1.1.1.2 ! root 291: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
! 292: return \"ucmpb %1,%0\";
1.1 root 293: }
1.1.1.2 ! root 294: return \"cmpb %1,%0\";
1.1 root 295: }")
296:
297: (define_insn ""
298: [(set (cc0)
299: (compare (match_operand:QI 0 "nonimmediate_operand" "r,m")
300: (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
1.1.1.2 ! root 301: "(GET_CODE (operands[0]) != GET_CODE (operands[1]))"
1.1 root 302: "*
303: {
304: rtx br_insn = NEXT_INSN (insn);
305: RTX_CODE br_code;
306:
307: if (GET_CODE (br_insn) != JUMP_INSN)
308: abort();
309: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
310:
1.1.1.2 ! root 311: if (which_alternative != 0)
! 312: {
! 313: cc_status.flags = CC_REVERSED;
! 314: if (TRULY_UNSIGNED_COMPARE_P (br_code))
! 315: {
! 316: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
! 317: return \"ucmpb %0,%1\";
! 318: }
! 319: return \"cmpb %0,%1\";
! 320: }
! 321:
! 322: if (TRULY_UNSIGNED_COMPARE_P (br_code))
1.1 root 323: {
1.1.1.2 ! root 324: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
! 325: return \"ucmpb %1,%0\";
1.1 root 326: }
1.1.1.2 ! root 327: return \"cmpb %1,%0\";
1.1 root 328: }")
329:
330: (define_expand "bgt"
331: [(set (pc) (if_then_else (gt (cc0) (const_int 0))
332: (label_ref (match_operand 0 "" "")) (pc)))]
333: "" "extend_and_branch (SIGN_EXTEND);")
334:
335: (define_expand "blt"
336: [(set (pc) (if_then_else (lt (cc0) (const_int 0))
337: (label_ref (match_operand 0 "" "")) (pc)))]
338: "" "extend_and_branch (SIGN_EXTEND);")
339:
340: (define_expand "bge"
341: [(set (pc) (if_then_else (ge (cc0) (const_int 0))
342: (label_ref (match_operand 0 "" "")) (pc)))]
343: "" "extend_and_branch (SIGN_EXTEND);")
344:
345: (define_expand "ble"
346: [(set (pc) (if_then_else (le (cc0) (const_int 0))
347: (label_ref (match_operand 0 "" "")) (pc)))]
348: "" "extend_and_branch (SIGN_EXTEND);")
349:
350: (define_expand "beq"
351: [(set (pc) (if_then_else (eq (cc0) (const_int 0))
352: (label_ref (match_operand 0 "" "")) (pc)))]
353: "" "extend_and_branch (SIGN_EXTEND);")
354:
355: (define_expand "bne"
356: [(set (pc) (if_then_else (ne (cc0) (const_int 0))
357: (label_ref (match_operand 0 "" "")) (pc)))]
358: "" "extend_and_branch (SIGN_EXTEND);")
359:
360: (define_expand "bgtu"
361: [(set (pc) (if_then_else (gtu (cc0) (const_int 0))
362: (label_ref (match_operand 0 "" "")) (pc)))]
363: "" "extend_and_branch (ZERO_EXTEND);")
364:
365: (define_expand "bltu"
366: [(set (pc) (if_then_else (ltu (cc0) (const_int 0))
367: (label_ref (match_operand 0 "" "")) (pc)))]
368: "" "extend_and_branch (ZERO_EXTEND);")
369:
370: (define_expand "bgeu"
371: [(set (pc) (if_then_else (geu (cc0) (const_int 0))
372: (label_ref (match_operand 0 "" "")) (pc)))]
373: "" "extend_and_branch (ZERO_EXTEND);")
374:
375: (define_expand "bleu"
376: [(set (pc) (if_then_else (leu (cc0) (const_int 0))
377: (label_ref (match_operand 0 "" "")) (pc)))]
378: "" "extend_and_branch (ZERO_EXTEND);")
379:
380: (define_insn "cmpdf"
381: [(set (cc0)
382: (compare (match_operand:DF 0 "register_operand" "r")
383: (match_operand:DF 1 "register_operand" "r")))]
384: ""
385: "cmpd %1,%0")
386:
387: (define_insn "cmpsf"
388: [(set (cc0)
389: (compare (match_operand:SF 0 "register_operand" "r")
390: (match_operand:SF 1 "register_operand" "r")))]
391: ""
392: "cmpf %1,%0")
393:
394: (define_insn "tstdf"
395: [(set (cc0)
396: (match_operand:DF 0 "register_operand" "r"))]
397: ""
398: "mtstd %0,%0")
399:
400: (define_insn "tstsf"
401: [(set (cc0)
402: (match_operand:SF 0 "register_operand" "r"))]
403: ""
404: "mtstf %0,%0")
405:
406: ;______________________________________________________________________
407: ;
408: ; Fixed-point Arithmetic.
409: ;______________________________________________________________________
410:
411: (define_insn "addsi3"
412: [(set (match_operand:SI 0 "register_operand" "=r,!r")
413: (plus:SI (match_operand:SI 1 "register_operand" "%0,r")
414: (match_operand:SI 2 "general_operand" "g,rJ")))]
415: ""
416: "*
417: {
418: if (which_alternative == 0)
419: return \"addw %2,%0\";
420: else
421: {
1.1.1.2 ! root 422: forget_cc_if_dependent (operands[0]);
! 423: return REG_P (operands[2])
! 424: ? \"mova (%2)[%1*1],%0\" : \"mova %a2[%1*1],%0\";
1.1 root 425: }
426: }")
427:
428: (define_insn "subsi3"
429: [(set (match_operand:SI 0 "register_operand" "=r,r")
430: (minus:SI (match_operand:SI 1 "general_operand" "0,g")
431: (match_operand:SI 2 "general_operand" "g,0")))]
432: ""
1.1.1.2 ! root 433: "* return (which_alternative == 0) ? \"subw %2,%0\" : \"rsubw %1,%0\";")
1.1 root 434:
435: (define_insn "mulsi3"
436: [(set (match_operand:SI 0 "register_operand" "=r")
437: (mult:SI (match_operand:SI 1 "register_operand" "%0")
438: (match_operand:SI 2 "general_operand" "g")))]
439: ""
440: "mulw %2,%0")
441:
442: (define_insn "umulsi3"
443: [(set (match_operand:SI 0 "register_operand" "=r")
444: (umult:SI (match_operand:SI 1 "register_operand" "%0")
445: (match_operand:SI 2 "general_operand" "g")))]
446: ""
447: "umulw %2,%0")
448:
449: (define_insn "divsi3"
450: [(set (match_operand:SI 0 "register_operand" "=r,r")
451: (div:SI (match_operand:SI 1 "general_operand" "0,g")
452: (match_operand:SI 2 "general_operand" "g,0")))]
453: ""
1.1.1.2 ! root 454: "* return (which_alternative == 0) ? \"divw %2,%0\" : \"rdivw %1,%0\";")
1.1 root 455:
456: (define_insn "udivsi3"
457: [(set (match_operand:SI 0 "register_operand" "=r")
458: (udiv:SI (match_operand:SI 1 "register_operand" "0")
459: (match_operand:SI 2 "general_operand" "g")))]
460: ""
1.1.1.2 ! root 461: "udivw %2,%0")
1.1 root 462:
463: (define_insn "modsi3"
464: [(set (match_operand:SI 0 "register_operand" "=r")
465: (mod:SI (match_operand:SI 1 "register_operand" "0")
466: (match_operand:SI 2 "general_operand" "g")))]
467: ""
468: "modw %2,%0")
469:
470: (define_insn "umodsi3"
471: [(set (match_operand:SI 0 "register_operand" "=r")
472: (umod:SI (match_operand:SI 1 "register_operand" "0")
473: (match_operand:SI 2 "general_operand" "g")))]
474: ""
1.1.1.2 ! root 475: "umodw %2,%0")
1.1 root 476:
477: (define_insn "negsi2"
478: [(set (match_operand:SI 0 "register_operand" "=r")
479: (neg:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
480: ""
481: "mnegw %1,%0")
482:
483: (define_insn "one_cmplsi2"
484: [(set (match_operand:SI 0 "register_operand" "=r")
485: (not:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
486: ""
487: "mcomw %1,%0")
488:
489: (define_insn "abssi2"
490: [(set (match_operand:SI 0 "register_operand" "=r")
491: (abs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
492: ""
493: "mabsw %1,%0")
494:
495: ;______________________________________________________________________
496: ;
497: ; Floating-point Arithmetic.
498: ;______________________________________________________________________
499:
500: (define_insn "adddf3"
501: [(set (match_operand:DF 0 "register_operand" "=r")
502: (plus:DF (match_operand:DF 1 "register_operand" "%0")
503: (match_operand:DF 2 "register_operand" "r")))]
504: ""
505: "addd %2,%0")
506:
507: (define_insn "addsf3"
508: [(set (match_operand:SF 0 "register_operand" "=r")
509: (plus:SF (match_operand:SF 1 "register_operand" "%0")
510: (match_operand:SF 2 "register_operand" "r")))]
511: ""
512: "addf %2,%0")
513:
514: (define_insn "subdf3"
515: [(set (match_operand:DF 0 "register_operand" "=r")
516: (minus:DF (match_operand:DF 1 "register_operand" "0")
517: (match_operand:DF 2 "register_operand" "r")))]
518: ""
519: "subd %2,%0")
520:
521: (define_insn "subsf3"
522: [(set (match_operand:SF 0 "register_operand" "=r")
523: (minus:SF (match_operand:SF 1 "register_operand" "0")
524: (match_operand:SF 2 "register_operand" "r")))]
525: ""
526: "subf %2,%0")
527:
528: (define_insn "muldf3"
529: [(set (match_operand:DF 0 "register_operand" "=r")
530: (mult:DF (match_operand:DF 1 "register_operand" "%0")
531: (match_operand:DF 2 "register_operand" "r")))]
532: ""
533: "muld %2,%0")
534:
535: (define_insn "mulsf3"
536: [(set (match_operand:SF 0 "register_operand" "=r")
537: (mult:SF (match_operand:SF 1 "register_operand" "%0")
538: (match_operand:SF 2 "register_operand" "r")))]
539: ""
540: "mulf %2,%0")
541:
542: (define_insn "divdf3"
543: [(set (match_operand:DF 0 "register_operand" "=r")
544: (div:DF (match_operand:DF 1 "register_operand" "0")
545: (match_operand:DF 2 "register_operand" "r")))]
546: ""
547: "divd %2,%0")
548:
549: (define_insn "divsf3"
550: [(set (match_operand:SF 0 "register_operand" "=r")
551: (div:SF (match_operand:SF 1 "register_operand" "0")
552: (match_operand:SF 2 "register_operand" "r")))]
553: ""
554: "divf %2,%0")
555:
556: (define_insn "negdf2"
557: [(set (match_operand:DF 0 "register_operand" "=r")
558: (neg:DF (match_operand:DF 1 "register_operand" "r")))]
559: ""
560: "mnegd %1,%0")
561:
562: (define_insn "negsf2"
563: [(set (match_operand:SF 0 "register_operand" "=r")
564: (neg:SF (match_operand:SF 1 "register_operand" "r")))]
565: ""
566: "mnegf %1,%0")
567:
568: (define_insn "absdf2"
569: [(set (match_operand:DF 0 "register_operand" "=r")
570: (abs:DF (match_operand:DF 1 "register_operand" "r")))]
571: ""
572: "mabsd %1,%0")
573:
574: (define_insn "abssf2"
575: [(set (match_operand:SF 0 "register_operand" "=r")
576: (abs:SF (match_operand:SF 1 "register_operand" "r")))]
577: ""
578: "mabsf %1,%0")
579:
580: ;______________________________________________________________________
581: ;
582: ; Logical and Shift Instructions.
583: ;______________________________________________________________________
584:
585: (define_insn ""
586: [(set (cc0)
587: (and:SI (match_operand:SI 0 "register_operand" "%r")
588: (match_operand:SI 1 "general_operand" "g")))]
589: ""
590: "bitw %1,%0");
591:
592: (define_insn "andsi3"
593: [(set (match_operand:SI 0 "register_operand" "=r,r")
594: (and:SI (match_operand:SI 1 "register_operand" "%0,r")
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")
623: (ior:SI (match_operand:SI 1 "register_operand" "%0")
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")
630: (xor:SI (match_operand:SI 1 "register_operand" "%0")
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"
945: [(set (match_operand:DF 0 "general_operand" "=r,m")
946: (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "rm,r")))]
947: ""
948: "cvtfd %1,%0")
949:
950: (define_insn "truncdfsf2"
951: [(set (match_operand:SF 0 "general_operand" "=r,m")
952: (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "rm,r")))]
953: ""
954: "cvtdf %1,%0")
955:
956: (define_insn "floatsisf2"
957: [(set (match_operand:SF 0 "general_operand" "=r,m")
958: (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
959: ""
960: "cvtwf %1,%0")
961:
962: (define_insn "floatsidf2"
963: [(set (match_operand:DF 0 "general_operand" "=r,m")
964: (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
965: ""
966: "cvtwd %1,%0")
967:
968: (define_insn "fix_truncsfsi2"
969: [(set (match_operand:SI 0 "general_operand" "=r,m")
970: (fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "rm,r"))))]
971: ""
972: "cvtfw %1,%0")
973:
974: (define_insn "fix_truncdfsi2"
975: [(set (match_operand:SI 0 "general_operand" "=r,m")
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:
! 1200: ;; Combine two word moves with consequtive operands into one long move.
! 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")
1257: (plus:DI (match_operand:DI 1 "register_operand" "%0")
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")
1303: (ior:DI (match_operand:DI 1 "register_operand" "%0")
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")
1326: (and:DI (match_operand:DI 1 "register_operand" "%0")
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")
1349: (xor:DI (match_operand:DI 1 "register_operand" "%0")
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.