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