|
|
1.1 ! root 1: ;;- Machine description for Intel 860 chip for GNU C compiler ! 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: ! 21: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 22: ! 23: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ! 24: ;;- updates for most instructions. ! 25: ! 26: ;;- Operand classes for the register allocator: ! 27: ! 28: /* Bit-test instructions. */ ! 29: ! 30: (define_insn "" ! 31: [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r") ! 32: (match_operand:SI 1 "logic_operand" "rL")) ! 33: (const_int 0)))] ! 34: "" ! 35: "* ! 36: { ! 37: CC_STATUS_PARTIAL_INIT; ! 38: return \"and %1,%0,%?r0\"; ! 39: }") ! 40: ! 41: (define_insn "" ! 42: [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r") ! 43: (match_operand:SI 1 "logic_operand" "rL")) ! 44: (const_int 0)))] ! 45: "" ! 46: "* ! 47: { ! 48: CC_STATUS_PARTIAL_INIT; ! 49: cc_status.flags |= CC_NEGATED; ! 50: return \"and %1,%0,%?r0\"; ! 51: }") ! 52: ! 53: (define_insn "" ! 54: [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r") ! 55: (match_operand:SI 1 "immediate_operand" "i")) ! 56: (const_int 0)))] ! 57: "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0" ! 58: "* ! 59: { ! 60: CC_STATUS_PARTIAL_INIT; ! 61: return \"andh %H1,%0,%?r0\"; ! 62: }") ! 63: ! 64: (define_insn "" ! 65: [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r") ! 66: (match_operand:SI 1 "immediate_operand" "i")) ! 67: (const_int 0)))] ! 68: "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0" ! 69: "* ! 70: { ! 71: CC_STATUS_PARTIAL_INIT; ! 72: cc_status.flags |= CC_NEGATED; ! 73: return \"andh %H1,%0,%?r0\"; ! 74: }") ! 75: ! 76: (define_insn "" ! 77: [(set (cc0) (eq (ashiftrt:SI ! 78: (sign_extend:SI ! 79: (ashift:QI (match_operand:QI 0 "register_operand" "r") ! 80: (match_operand:QI 1 "logic_int" "n"))) ! 81: (match_operand:SI 2 "logic_int" "n")) ! 82: (const_int 0)))] ! 83: "" ! 84: "* ! 85: { ! 86: int width = 8 - INTVAL (operands[2]); ! 87: int pos = 8 - width - INTVAL (operands[1]); ! 88: ! 89: CC_STATUS_PARTIAL_INIT; ! 90: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 91: ~((-1) << width) << pos); ! 92: return \"and %2,%0,%?r0\"; ! 93: }") ! 94: ! 95: ;; ------------------------------------------------------------------------- ! 96: ;; SImode signed integer comparisons ! 97: ;; ------------------------------------------------------------------------- ! 98: ! 99: (define_insn "cmpeqsi" ! 100: [(set (cc0) (eq (match_operand:SI 0 "logic_operand" "r,rL") ! 101: (match_operand:SI 1 "logic_operand" "L,r")))] ! 102: "" ! 103: "* ! 104: { ! 105: CC_STATUS_PARTIAL_INIT; ! 106: if (REG_P (operands[0])) ! 107: return \"xor %1,%0,%?r0\"; ! 108: else ! 109: return \"xor %0,%1,%?r0\"; ! 110: }") ! 111: ! 112: (define_insn "cmpnesi" ! 113: [(set (cc0) (ne (match_operand:SI 0 "logic_operand" "r,rL") ! 114: (match_operand:SI 1 "logic_operand" "L,r")))] ! 115: "" ! 116: "* ! 117: { ! 118: CC_STATUS_PARTIAL_INIT; ! 119: cc_status.flags |= CC_NEGATED; ! 120: if (REG_P (operands[0])) ! 121: return \"xor %1,%0,%?r0\"; ! 122: else ! 123: return \"xor %0,%1,%?r0\"; ! 124: }") ! 125: ! 126: (define_insn "cmpltsi" ! 127: [(set (cc0) (lt (match_operand:SI 0 "arith_operand" "r,rI") ! 128: (match_operand:SI 1 "arith_operand" "I,r")))] ! 129: "" ! 130: "* ! 131: { ! 132: CC_STATUS_PARTIAL_INIT; ! 133: if (REG_P (operands[1])) ! 134: return \"subs %0,%1,%?r0\"; ! 135: else ! 136: { ! 137: cc_status.flags |= CC_REVERSED; ! 138: operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); ! 139: return \"adds %1,%0,%?r0\"; ! 140: } ! 141: }") ! 142: ! 143: (define_insn "cmpgtsi" ! 144: [(set (cc0) (gt (match_operand:SI 0 "arith_operand" "r,rI") ! 145: (match_operand:SI 1 "arith_operand" "I,r")))] ! 146: "" ! 147: "* ! 148: { ! 149: CC_STATUS_PARTIAL_INIT; ! 150: if (REG_P (operands[0])) ! 151: return \"subs %1,%0,%?r0\"; ! 152: else ! 153: { ! 154: cc_status.flags |= CC_REVERSED; ! 155: operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0])); ! 156: return \"adds %0,%1,%?r0\"; ! 157: } ! 158: }") ! 159: ! 160: (define_insn "cmplesi" ! 161: [(set (cc0) (le (match_operand:SI 0 "arith_operand" "r,rI") ! 162: (match_operand:SI 1 "arith_operand" "I,r")))] ! 163: "" ! 164: "* ! 165: { ! 166: CC_STATUS_PARTIAL_INIT; ! 167: cc_status.flags |= CC_NEGATED; ! 168: if (REG_P (operands[0])) ! 169: return \"subs %1,%0,%?r0\"; ! 170: else ! 171: { ! 172: cc_status.flags |= CC_REVERSED; ! 173: operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0])); ! 174: return \"adds %0,%1,%?r0\"; ! 175: } ! 176: }") ! 177: ! 178: (define_insn "cmpgesi" ! 179: [(set (cc0) (ge (match_operand:SI 0 "arith_operand" "r,rI") ! 180: (match_operand:SI 1 "arith_operand" "I,r")))] ! 181: "" ! 182: "* ! 183: { ! 184: CC_STATUS_PARTIAL_INIT; ! 185: cc_status.flags |= CC_NEGATED; ! 186: if (REG_P (operands[1])) ! 187: return \"subs %0,%1,%?r0\"; ! 188: else ! 189: { ! 190: cc_status.flags |= CC_REVERSED; ! 191: operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); ! 192: return \"adds %1,%0,%?r0\"; ! 193: } ! 194: }") ! 195: ! 196: ;; ------------------------------------------------------------------------- ! 197: ;; SImode unsigned integer comparisons ! 198: ;; ------------------------------------------------------------------------- ! 199: ! 200: ;; WARNING! There is a small i860 hardware limitation (bug?) which we ! 201: ;; may run up against (if we are not careful) when we are trying to do ! 202: ;; unsigned comparisons like (x >= 0), (x < 0), (0 <= x), and (0 > x). ! 203: ;; Specifically, we must avoid using an `addu' instruction to perform ! 204: ;; such comparisons because the result (in the CC bit register) will ! 205: ;; come out wrong. (This fact is documented in a footnote on page 7-10 ! 206: ;; of the 1991 version of the i860 Microprocessor Family Programmer's ! 207: ;; Reference Manual). Note that unsigned comparisons of this sort are ! 208: ;; always redundant anyway, because an unsigned quantity can never be ! 209: ;; less than zero. When we see cases like this, we generate an ! 210: ;; `or K,%r0,%r0' instruction instead (where K is a constant 0 or -1) ! 211: ;; so as to get the CC bit register set properly for any subsequent ! 212: ;; conditional jump instruction. ! 213: ! 214: (define_insn "cmpgeusi" ! 215: [(set (cc0) (geu (match_operand:SI 0 "arith_operand" "r,rI") ! 216: (match_operand:SI 1 "arith_operand" "I,r")))] ! 217: "" ! 218: "* ! 219: { ! 220: CC_STATUS_PARTIAL_INIT; ! 221: if (REG_P (operands[1])) ! 222: return \"subu %0,%1,%?r0\"; ! 223: else ! 224: { ! 225: if (INTVAL (operands[1]) == 0) ! 226: return \"or 0,%?r0,%?r0\"; ! 227: else ! 228: { ! 229: cc_status.flags |= CC_REVERSED; ! 230: operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); ! 231: return \"addu %1,%0,%?r0\"; ! 232: } ! 233: } ! 234: }") ! 235: ! 236: (define_insn "cmpleusi" ! 237: [(set (cc0) (leu (match_operand:SI 0 "arith_operand" "r,rI") ! 238: (match_operand:SI 1 "arith_operand" "I,r")))] ! 239: "" ! 240: "* ! 241: { ! 242: CC_STATUS_PARTIAL_INIT; ! 243: if (REG_P (operands[0])) ! 244: return \"subu %1,%0,%?r0\"; ! 245: else ! 246: { ! 247: if (INTVAL (operands[0]) == 0) ! 248: return \"or 0,%?r0,%?r0\"; ! 249: else ! 250: { ! 251: cc_status.flags |= CC_REVERSED; ! 252: operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0])); ! 253: return \"addu %0,%1,%?r0\"; ! 254: } ! 255: } ! 256: }") ! 257: ! 258: ;; ------------------------------------------------------------------------- ! 259: ;; SFmode floating-point comparisons ! 260: ;; ------------------------------------------------------------------------- ! 261: ! 262: (define_insn "cmpeqsf" ! 263: [(set (cc0) (eq (match_operand:SF 0 "reg_or_0_operand" "fG") ! 264: (match_operand:SF 1 "reg_or_0_operand" "fG")))] ! 265: "" ! 266: "* ! 267: { ! 268: CC_STATUS_PARTIAL_INIT; ! 269: return \"pfeq.ss %r0,%r1,%?f0\"; ! 270: }") ! 271: ! 272: (define_insn "cmpnesf" ! 273: [(set (cc0) (ne (match_operand:SF 0 "reg_or_0_operand" "fG") ! 274: (match_operand:SF 1 "reg_or_0_operand" "fG")))] ! 275: "" ! 276: "* ! 277: { ! 278: CC_STATUS_PARTIAL_INIT; ! 279: cc_status.flags |= CC_NEGATED; ! 280: return \"pfeq.ss %r1,%r0,%?f0\"; ! 281: }") ! 282: ! 283: ;; NOTE: The i860 Programmer's Reference Manual says that when we are ! 284: ;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these ! 285: ;; in order to be IEEE compliant (in case a trap occurs during these ! 286: ;; operations). Conversely, for (A <= B) or (A >= B) comparisons, we ! 287: ;; must use pfle to be IEEE compliant. ! 288: ! 289: (define_insn "cmpltsf" ! 290: [(set (cc0) (lt (match_operand:SF 0 "reg_or_0_operand" "fG") ! 291: (match_operand:SF 1 "reg_or_0_operand" "fG")))] ! 292: "" ! 293: "* ! 294: { ! 295: CC_STATUS_PARTIAL_INIT; ! 296: return \"pfgt.ss %r1,%r0,%?f0\"; ! 297: }") ! 298: ! 299: (define_insn "cmpgtsf" ! 300: [(set (cc0) (gt (match_operand:SF 0 "reg_or_0_operand" "fG") ! 301: (match_operand:SF 1 "reg_or_0_operand" "fG")))] ! 302: "" ! 303: "* ! 304: { ! 305: CC_STATUS_PARTIAL_INIT; ! 306: return \"pfgt.ss %r0,%r1,%?f0\"; ! 307: }") ! 308: ! 309: ;; NOTE: The pfle opcode doesn't do what you think it does. It is ! 310: ;; bass-ackwards. It *clears* the CC flag if the first operand is ! 311: ;; less than or equal to the second. Thus, we have to set CC_NEGATED ! 312: ;; for the following two patterns. ! 313: ! 314: (define_insn "cmplesf" ! 315: [(set (cc0) (le (match_operand:SF 0 "reg_or_0_operand" "fG") ! 316: (match_operand:SF 1 "reg_or_0_operand" "fG")))] ! 317: "" ! 318: "* ! 319: { ! 320: CC_STATUS_PARTIAL_INIT; ! 321: cc_status.flags |= CC_NEGATED; ! 322: return \"pfle.ss %r0,%r1,%?f0\"; ! 323: }") ! 324: ! 325: (define_insn "cmpgesf" ! 326: [(set (cc0) (ge (match_operand:SF 0 "reg_or_0_operand" "fG") ! 327: (match_operand:SF 1 "reg_or_0_operand" "fG")))] ! 328: "" ! 329: "* ! 330: { ! 331: CC_STATUS_PARTIAL_INIT; ! 332: cc_status.flags |= CC_NEGATED; ! 333: return \"pfle.ss %r1,%r0,%?f0\"; ! 334: }") ! 335: ! 336: ;; ------------------------------------------------------------------------- ! 337: ;; DFmode floating-point comparisons ! 338: ;; ------------------------------------------------------------------------- ! 339: ! 340: (define_insn "cmpeqdf" ! 341: [(set (cc0) (eq (match_operand:DF 0 "reg_or_0_operand" "fG") ! 342: (match_operand:DF 1 "reg_or_0_operand" "fG")))] ! 343: "" ! 344: "* ! 345: { ! 346: CC_STATUS_PARTIAL_INIT; ! 347: return \"pfeq.dd %r0,%r1,%?f0\"; ! 348: }") ! 349: ! 350: (define_insn "cmpnedf" ! 351: [(set (cc0) (ne (match_operand:DF 0 "reg_or_0_operand" "fG") ! 352: (match_operand:DF 1 "reg_or_0_operand" "fG")))] ! 353: "" ! 354: "* ! 355: { ! 356: CC_STATUS_PARTIAL_INIT; ! 357: cc_status.flags |= CC_NEGATED; ! 358: return \"pfeq.dd %r1,%r0,%?f0\"; ! 359: }") ! 360: ! 361: ;; NOTE: The i860 Programmer's Reference Manual says that when we are ! 362: ;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these ! 363: ;; in order to be IEEE compliant (in case a trap occurs during these ! 364: ;; operations). Conversely, for (A <= B) or (A >= B) comparisons, we ! 365: ;; must use pfle to be IEEE compliant. ! 366: ! 367: (define_insn "cmpltdf" ! 368: [(set (cc0) (lt (match_operand:DF 0 "reg_or_0_operand" "fG") ! 369: (match_operand:DF 1 "reg_or_0_operand" "fG")))] ! 370: "" ! 371: "* ! 372: { ! 373: CC_STATUS_PARTIAL_INIT; ! 374: return \"pfgt.dd %r1,%r0,%?f0\"; ! 375: }") ! 376: ! 377: (define_insn "cmpgtdf" ! 378: [(set (cc0) (gt (match_operand:DF 0 "reg_or_0_operand" "fG") ! 379: (match_operand:DF 1 "reg_or_0_operand" "fG")))] ! 380: "" ! 381: "* ! 382: { ! 383: CC_STATUS_PARTIAL_INIT; ! 384: return \"pfgt.dd %r0,%r1,%?f0\"; ! 385: }") ! 386: ! 387: ;; NOTE: The pfle opcode doesn't do what you think it does. It is ! 388: ;; bass-ackwards. It *clears* the CC flag if the first operand is ! 389: ;; less than or equal to the second. Thus, we have to set CC_NEGATED ! 390: ;; for the following two patterns. ! 391: ! 392: (define_insn "cmpledf" ! 393: [(set (cc0) (le (match_operand:DF 0 "reg_or_0_operand" "fG") ! 394: (match_operand:DF 1 "reg_or_0_operand" "fG")))] ! 395: "" ! 396: "* ! 397: { ! 398: CC_STATUS_PARTIAL_INIT; ! 399: cc_status.flags |= CC_NEGATED; ! 400: return \"pfle.dd %r0,%r1,%?f0\"; ! 401: }") ! 402: ! 403: (define_insn "cmpgedf" ! 404: [(set (cc0) (ge (match_operand:DF 0 "reg_or_0_operand" "fG") ! 405: (match_operand:DF 1 "reg_or_0_operand" "fG")))] ! 406: "" ! 407: "* ! 408: { ! 409: CC_STATUS_PARTIAL_INIT; ! 410: cc_status.flags |= CC_NEGATED; ! 411: return \"pfle.dd %r1,%r0,%?f0\"; ! 412: }") ! 413: ! 414: ;; ------------------------------------------------------------------------ ! 415: ;; Integer EQ/NE comparisons against constant values which will fit in the ! 416: ;; 16-bit immediate field of an instruction. These are made by combining. ! 417: ;; ------------------------------------------------------------------------ ! 418: ! 419: (define_insn "" ! 420: [(set (cc0) (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m")) ! 421: (match_operand:SI 1 "small_int" "I")))] ! 422: "INTVAL (operands[1]) >= 0" ! 423: "* ! 424: { ! 425: CC_STATUS_PARTIAL_INIT; ! 426: return \"ld.s %0,%?r31\;xor %1,%?r31,%?r0\"; ! 427: }") ! 428: ! 429: (define_insn "" ! 430: [(set (cc0) (eq (match_operand:SI 0 "small_int" "I") ! 431: (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))))] ! 432: "INTVAL (operands[0]) >= 0" ! 433: "* ! 434: { ! 435: CC_STATUS_PARTIAL_INIT; ! 436: return \"ld.s %1,%?r31\;xor %0,%?r31,%?r0\"; ! 437: }") ! 438: ! 439: ;; ------------------------------------------------------------------------ ! 440: ;; Define the real conditional branch instructions. ! 441: ;; ------------------------------------------------------------------------ ! 442: ! 443: (define_insn "cbranch" ! 444: [(set (pc) (if_then_else (eq (cc0) (const_int 0)) ! 445: (label_ref (match_operand 0 "" "")) ! 446: (pc)))] ! 447: "" ! 448: "* ! 449: { ! 450: if ((cc_prev_status.flags & CC_NEGATED) == 0) ! 451: return \"bnc %l0\"; ! 452: else ! 453: return \"bc %l0\"; ! 454: }") ! 455: ! 456: (define_insn "flipped_cbranch" ! 457: [(set (pc) (if_then_else (ne (cc0) ! 458: (const_int 0)) ! 459: (pc) ! 460: (label_ref (match_operand 0 "" ""))))] ! 461: "" ! 462: "* ! 463: { ! 464: if ((cc_prev_status.flags & CC_NEGATED) == 0) ! 465: return \"bnc %l0\"; ! 466: else ! 467: return \"bc %l0\"; ! 468: }") ! 469: ! 470: (define_insn "inverse_cbranch" ! 471: [(set (pc) (if_then_else (eq (cc0) ! 472: (const_int 0)) ! 473: (pc) ! 474: (label_ref (match_operand 0 "" ""))))] ! 475: "" ! 476: "* ! 477: { ! 478: if ((cc_prev_status.flags & CC_NEGATED) == 0) ! 479: return \"bc %l0\"; ! 480: else ! 481: return \"bnc %l0\"; ! 482: }") ! 483: ! 484: ! 485: (define_insn "flipped_inverse_cbranch" ! 486: [(set (pc) (if_then_else (ne (cc0) ! 487: (const_int 0)) ! 488: (label_ref (match_operand 0 "" "")) ! 489: (pc)))] ! 490: "" ! 491: "* ! 492: { ! 493: if ((cc_prev_status.flags & CC_NEGATED) == 0) ! 494: return \"bc %l0\"; ! 495: else ! 496: return \"bnc %l0\"; ! 497: }") ! 498: ! 499: ;; Simple BTE/BTNE compare-and-branch insns made by combining. ! 500: ;; Note that it is wrong to add similar patterns for QI or HImode ! 501: ;; because bte/btne always compare the whole register. ! 502: ! 503: (define_insn "" ! 504: [(set (pc) ! 505: (if_then_else (eq (match_operand:SI 0 "register_operand" "r") ! 506: (match_operand:SI 1 "bte_operand" "rK")) ! 507: (label_ref (match_operand 2 "" "")) ! 508: (pc)))] ! 509: "" ! 510: "bte %1,%0,%2") ! 511: ! 512: (define_insn "" ! 513: [(set (pc) ! 514: (if_then_else (ne (match_operand:SI 0 "register_operand" "r") ! 515: (match_operand:SI 1 "bte_operand" "rK")) ! 516: (label_ref (match_operand 2 "" "")) ! 517: (pc)))] ! 518: "" ! 519: "btne %1,%0,%2") ! 520: ! 521: (define_insn "" ! 522: [(set (pc) ! 523: (if_then_else (eq (match_operand:SI 0 "register_operand" "r") ! 524: (match_operand:SI 1 "bte_operand" "rK")) ! 525: (pc) ! 526: (label_ref (match_operand 2 "" ""))))] ! 527: "" ! 528: "btne %1,%0,%2") ! 529: ! 530: (define_insn "" ! 531: [(set (pc) ! 532: (if_then_else (ne (match_operand:SI 0 "register_operand" "r") ! 533: (match_operand:SI 1 "bte_operand" "rK")) ! 534: (pc) ! 535: (label_ref (match_operand 2 "" ""))))] ! 536: "" ! 537: "bte %1,%0,%2") ! 538: ! 539: ;; Load byte/halfword, zero-extend, & compare-and-branch insns. ! 540: ;; These are made by combining. ! 541: ! 542: (define_insn "" ! 543: [(set (pc) ! 544: (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) ! 545: (match_operand:SI 1 "bte_operand" "K")) ! 546: (label_ref (match_operand 2 "" "")) ! 547: (pc))) ! 548: (match_scratch:SI 3 "=r")] ! 549: "" ! 550: "ld.b %0,%3;bte %1,%3,%2") ! 551: ! 552: (define_insn "" ! 553: [(set (pc) ! 554: (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) ! 555: (match_operand:SI 1 "bte_operand" "K")) ! 556: (label_ref (match_operand 2 "" "")) ! 557: (pc))) ! 558: (match_scratch:SI 3 "=r")] ! 559: "" ! 560: "ld.b %0,%3;btne %1,%3,%2") ! 561: ! 562: (define_insn "" ! 563: [(set (pc) ! 564: (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) ! 565: (match_operand:SI 1 "bte_operand" "K")) ! 566: (pc) ! 567: (label_ref (match_operand 2 "" "")))) ! 568: (match_scratch:SI 3 "=r")] ! 569: "" ! 570: "ld.b %0,%3;btne %1,%3,%2") ! 571: ! 572: (define_insn "" ! 573: [(set (pc) ! 574: (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) ! 575: (match_operand:SI 1 "bte_operand" "K")) ! 576: (pc) ! 577: (label_ref (match_operand 2 "" "")))) ! 578: (match_scratch:SI 3 "=r")] ! 579: "" ! 580: "ld.b %0,%3;bte %1,%3,%2") ! 581: ! 582: (define_insn "" ! 583: [(set (pc) ! 584: (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")) ! 585: (match_operand:SI 1 "bte_operand" "K")) ! 586: (label_ref (match_operand 2 "" "")) ! 587: (pc))) ! 588: (match_scratch:SI 3 "=r")] ! 589: "" ! 590: "ld.s %0,%3;bte %1,%3,%2") ! 591: ! 592: (define_insn "" ! 593: [(set (pc) ! 594: (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")) ! 595: (match_operand:SI 1 "bte_operand" "K")) ! 596: (label_ref (match_operand 2 "" "")) ! 597: (pc))) ! 598: (match_scratch:SI 3 "=r")] ! 599: "" ! 600: "ld.s %0,%3;btne %1,%3,%2") ! 601: ! 602: (define_insn "" ! 603: [(set (pc) ! 604: (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")) ! 605: (match_operand:SI 1 "bte_operand" "K")) ! 606: (pc) ! 607: (label_ref (match_operand 2 "" "")))) ! 608: (match_scratch:SI 3 "=r")] ! 609: "" ! 610: "ld.s %0,%3;btne %1,%3,%2") ! 611: ! 612: (define_insn "" ! 613: [(set (pc) ! 614: (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")) ! 615: (match_operand:SI 1 "bte_operand" "K")) ! 616: (pc) ! 617: (label_ref (match_operand 2 "" "")))) ! 618: (match_scratch:SI 3 "=r")] ! 619: "" ! 620: "ld.s %0,%3;bte %1,%3,%2") ! 621: ! 622: ! 623: ;; Generation of conditionals. ! 624: ! 625: ;; We save the compare operands in the cmpxx patterns and use then when ! 626: ;; we generate the branch. ! 627: ! 628: (define_expand "cmpsi" ! 629: [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") ! 630: (match_operand:SI 1 "compare_operand" "")))] ! 631: "" ! 632: " ! 633: { i860_compare_op0 = operands[0]; ! 634: i860_compare_op1 = operands[1]; ! 635: DONE; ! 636: }") ! 637: ! 638: (define_expand "cmpsf" ! 639: [(set (cc0) (compare (match_operand:SF 0 "register_operand" "") ! 640: (match_operand:SF 1 "register_operand" "")))] ! 641: "" ! 642: " ! 643: { i860_compare_op0 = operands[0]; ! 644: i860_compare_op1 = operands[1]; ! 645: DONE; ! 646: }") ! 647: ! 648: (define_expand "cmpdf" ! 649: [(set (cc0) (compare (match_operand:DF 0 "register_operand" "") ! 650: (match_operand:DF 1 "register_operand" "")))] ! 651: "" ! 652: " ! 653: { i860_compare_op0 = operands[0]; ! 654: i860_compare_op1 = operands[1]; ! 655: DONE; ! 656: }") ! 657: ! 658: ;; These are the standard-named conditional branch patterns. ! 659: ;; Detailed comments are found in the first one only. ! 660: ! 661: (define_expand "beq" ! 662: [(set (pc) ! 663: (if_then_else (eq (cc0) ! 664: (const_int 0)) ! 665: (label_ref (match_operand 0 "" "")) ! 666: (pc)))] ! 667: "" ! 668: " ! 669: { ! 670: /* Emit a single-condition compare insn according to ! 671: the type of operands and the condition to be tested. */ ! 672: ! 673: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) ! 674: emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1)); ! 675: else if (GET_MODE (i860_compare_op0) == SFmode) ! 676: emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1)); ! 677: else if (GET_MODE (i860_compare_op0) == DFmode) ! 678: emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1)); ! 679: else ! 680: abort (); ! 681: ! 682: /* Emit branch-if-true. */ ! 683: ! 684: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); ! 685: DONE; ! 686: }") ! 687: ! 688: (define_expand "bne" ! 689: [(set (pc) ! 690: (if_then_else (ne (cc0) ! 691: (const_int 0)) ! 692: (label_ref (match_operand 0 "" "")) ! 693: (pc)))] ! 694: "" ! 695: " ! 696: { ! 697: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) ! 698: emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1)); ! 699: else if (GET_MODE (i860_compare_op0) == SFmode) ! 700: emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1)); ! 701: else if (GET_MODE (i860_compare_op0) == DFmode) ! 702: emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1)); ! 703: else ! 704: abort (); ! 705: ! 706: emit_jump_insn (gen_flipped_cbranch (operands[0])); ! 707: ! 708: DONE; ! 709: }") ! 710: ! 711: (define_expand "bgt" ! 712: [(set (pc) ! 713: (if_then_else (gt (cc0) ! 714: (const_int 0)) ! 715: (label_ref (match_operand 0 "" "")) ! 716: (pc)))] ! 717: "" ! 718: " ! 719: { ! 720: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) ! 721: emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1)); ! 722: else if (GET_MODE (i860_compare_op0) == SFmode) ! 723: emit_insn (gen_cmpgtsf (i860_compare_op0, i860_compare_op1)); ! 724: else if (GET_MODE (i860_compare_op0) == DFmode) ! 725: emit_insn (gen_cmpgtdf (i860_compare_op0, i860_compare_op1)); ! 726: else ! 727: abort (); ! 728: ! 729: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); ! 730: DONE; ! 731: }") ! 732: ! 733: (define_expand "blt" ! 734: [(set (pc) ! 735: (if_then_else (lt (cc0) ! 736: (const_int 0)) ! 737: (label_ref (match_operand 0 "" "")) ! 738: (pc)))] ! 739: "" ! 740: " ! 741: { ! 742: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) ! 743: emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1)); ! 744: else if (GET_MODE (i860_compare_op0) == SFmode) ! 745: emit_insn (gen_cmpltsf (i860_compare_op0, i860_compare_op1)); ! 746: else if (GET_MODE (i860_compare_op0) == DFmode) ! 747: emit_insn (gen_cmpltdf (i860_compare_op0, i860_compare_op1)); ! 748: else ! 749: abort (); ! 750: ! 751: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); ! 752: DONE; ! 753: }") ! 754: ! 755: (define_expand "ble" ! 756: [(set (pc) ! 757: (if_then_else (le (cc0) ! 758: (const_int 0)) ! 759: (label_ref (match_operand 0 "" "")) ! 760: (pc)))] ! 761: "" ! 762: " ! 763: { ! 764: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) ! 765: { ! 766: emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1)); ! 767: emit_jump_insn (gen_flipped_cbranch (operands[0])); ! 768: } ! 769: else ! 770: { ! 771: if (GET_MODE (i860_compare_op0) == SFmode) ! 772: emit_insn (gen_cmplesf (i860_compare_op0, i860_compare_op1)); ! 773: else if (GET_MODE (i860_compare_op0) == DFmode) ! 774: emit_insn (gen_cmpledf (i860_compare_op0, i860_compare_op1)); ! 775: else ! 776: abort (); ! 777: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); ! 778: } ! 779: DONE; ! 780: }") ! 781: ! 782: (define_expand "bge" ! 783: [(set (pc) ! 784: (if_then_else (ge (cc0) ! 785: (const_int 0)) ! 786: (label_ref (match_operand 0 "" "")) ! 787: (pc)))] ! 788: "" ! 789: " ! 790: { ! 791: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) ! 792: { ! 793: emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1)); ! 794: emit_jump_insn (gen_flipped_cbranch (operands[0])); ! 795: } ! 796: else ! 797: { ! 798: if (GET_MODE (i860_compare_op0) == SFmode) ! 799: emit_insn (gen_cmpgesf (i860_compare_op0, i860_compare_op1)); ! 800: else if (GET_MODE (i860_compare_op0) == DFmode) ! 801: emit_insn (gen_cmpgedf (i860_compare_op0, i860_compare_op1)); ! 802: else ! 803: abort (); ! 804: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); ! 805: } ! 806: DONE; ! 807: }") ! 808: ! 809: (define_expand "bgtu" ! 810: [(set (pc) ! 811: (if_then_else (gtu (cc0) ! 812: (const_int 0)) ! 813: (label_ref (match_operand 0 "" "")) ! 814: (pc)))] ! 815: "" ! 816: " ! 817: { ! 818: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT) ! 819: abort (); ! 820: ! 821: emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1)); ! 822: emit_jump_insn (gen_flipped_cbranch (operands[0])); ! 823: DONE; ! 824: }") ! 825: ! 826: (define_expand "bltu" ! 827: [(set (pc) ! 828: (if_then_else (ltu (cc0) ! 829: (const_int 0)) ! 830: (label_ref (match_operand 0 "" "")) ! 831: (pc)))] ! 832: "" ! 833: " ! 834: { ! 835: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT) ! 836: abort (); ! 837: ! 838: emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1)); ! 839: emit_jump_insn (gen_flipped_cbranch (operands[0])); ! 840: DONE; ! 841: }") ! 842: ! 843: (define_expand "bgeu" ! 844: [(set (pc) ! 845: (if_then_else (geu (cc0) ! 846: (const_int 0)) ! 847: (label_ref (match_operand 0 "" "")) ! 848: (pc)))] ! 849: "" ! 850: " ! 851: { ! 852: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT) ! 853: abort (); ! 854: ! 855: emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1)); ! 856: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); ! 857: DONE; ! 858: }") ! 859: ! 860: (define_expand "bleu" ! 861: [(set (pc) ! 862: (if_then_else (leu (cc0) ! 863: (const_int 0)) ! 864: (label_ref (match_operand 0 "" "")) ! 865: (pc)))] ! 866: "" ! 867: " ! 868: { ! 869: if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT) ! 870: abort (); ! 871: ! 872: emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1)); ! 873: emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); ! 874: DONE; ! 875: }") ! 876: ! 877: ;; Move instructions ! 878: ! 879: ;; Note that source operands for `mov' pseudo-instructions are no longer ! 880: ;; allowed (by the svr4 assembler) to be "big" things, i.e. constants that ! 881: ;; won't fit in 16-bits. (This includes any sort of a relocatable address ! 882: ;; also.) Thus, we must use an explicit orh/or pair of instructions if ! 883: ;; the source operand is something "big". ! 884: ! 885: (define_insn "movsi" ! 886: [(set (match_operand:SI 0 "general_operand" "=r,m,f") ! 887: (match_operand:SI 1 "general_operand" "rmif,rfJ,rmfJ"))] ! 888: "" ! 889: "* ! 890: { ! 891: if (GET_CODE (operands[0]) == MEM) ! 892: { ! 893: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 894: return output_store (operands); ! 895: if (FP_REG_P (operands[1])) ! 896: return \"fst.l %1,%0\"; ! 897: return \"st.l %r1,%0\"; ! 898: } ! 899: if (GET_CODE (operands[1]) == MEM) ! 900: { ! 901: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 902: return output_load (operands); ! 903: if (FP_REG_P (operands[0])) ! 904: return \"fld.l %1,%0\"; ! 905: return \"ld.l %1,%0\"; ! 906: } ! 907: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0])) ! 908: return \"fmov.ss %1,%0\"; ! 909: if (FP_REG_P (operands[1])) ! 910: return \"fxfr %1,%0\"; ! 911: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx) ! 912: return \"fmov.ss %?f0,%0\"; ! 913: if (FP_REG_P (operands[0])) ! 914: return \"ixfr %1,%0\"; ! 915: ! 916: if (GET_CODE (operands[1]) == REG) ! 917: return \"shl %?r0,%1,%0\"; ! 918: ! 919: CC_STATUS_PARTIAL_INIT; ! 920: ! 921: if (GET_CODE (operands[1]) == CONST_INT) ! 922: { ! 923: if((INTVAL (operands[1]) & 0xffff0000) == 0) ! 924: return \"or %L1,%?r0,%0\"; ! 925: if((INTVAL (operands[1]) & 0x0000ffff) == 0) ! 926: return \"orh %H1,%?r0,%0\"; ! 927: } ! 928: return \"orh %H1,%?r0,%0\;or %L1,%0,%0\"; ! 929: }") ! 930: ! 931: (define_insn "movhi" ! 932: [(set (match_operand:HI 0 "general_operand" "=r,m,!*f,!r") ! 933: (match_operand:HI 1 "general_operand" "rmi,rJ,rJ*f,*f"))] ! 934: "" ! 935: "* ! 936: { ! 937: if (GET_CODE (operands[0]) == MEM) ! 938: { ! 939: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 940: return output_store (operands); ! 941: return \"st.s %r1,%0\"; ! 942: } ! 943: if (GET_CODE (operands[1]) == MEM) ! 944: { ! 945: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 946: return output_load (operands); ! 947: return \"ld.s %1,%0\"; ! 948: } ! 949: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0])) ! 950: return \"fmov.ss %1,%0\"; ! 951: if (FP_REG_P (operands[1])) ! 952: return \"fxfr %1,%0\"; ! 953: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx) ! 954: return \"fmov.ss %?f0,%0\"; ! 955: if (FP_REG_P (operands[0])) ! 956: return \"ixfr %1,%0\"; ! 957: ! 958: if (GET_CODE (operands[1]) == REG) ! 959: return \"shl %?r0,%1,%0\"; ! 960: ! 961: CC_STATUS_PARTIAL_INIT; ! 962: ! 963: return \"or %L1,%?r0,%0\"; ! 964: }") ! 965: ! 966: (define_insn "movqi" ! 967: [(set (match_operand:QI 0 "general_operand" "=r,m,!*f,!r") ! 968: (match_operand:QI 1 "general_operand" "rmi,rJ,rJ*f,*f"))] ! 969: "" ! 970: "* ! 971: { ! 972: if (GET_CODE (operands[0]) == MEM) ! 973: { ! 974: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 975: return output_store (operands); ! 976: return \"st.b %r1,%0\"; ! 977: } ! 978: if (GET_CODE (operands[1]) == MEM) ! 979: { ! 980: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 981: return output_load (operands); ! 982: return \"ld.b %1,%0\"; ! 983: } ! 984: if (FP_REG_P (operands[1]) && FP_REG_P (operands[0])) ! 985: return \"fmov.ss %1,%0\"; ! 986: if (FP_REG_P (operands[1])) ! 987: return \"fxfr %1,%0\"; ! 988: if (FP_REG_P (operands[0]) && operands[1] == const0_rtx) ! 989: return \"fmov.ss %?f0,%0\"; ! 990: if (FP_REG_P (operands[0])) ! 991: return \"ixfr %1,%0\"; ! 992: ! 993: if (GET_CODE (operands[1]) == REG) ! 994: return \"shl %?r0,%1,%0\"; ! 995: ! 996: CC_STATUS_PARTIAL_INIT; ! 997: ! 998: return \"or %L1,%?r0,%0\"; ! 999: }") ! 1000: ! 1001: ;; The definition of this insn does not really explain what it does, ! 1002: ;; but it should suffice ! 1003: ;; that anything generated as this insn will be recognized as one ! 1004: ;; and that it won't successfully combine with anything. ! 1005: (define_expand "movstrsi" ! 1006: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) ! 1007: (mem:BLK (match_operand:BLK 1 "general_operand" ""))) ! 1008: (use (match_operand:SI 2 "nonmemory_operand" "")) ! 1009: (use (match_operand:SI 3 "immediate_operand" "")) ! 1010: (clobber (match_dup 4)) ! 1011: (clobber (match_dup 5)) ! 1012: (clobber (match_dup 6)) ! 1013: (clobber (match_dup 0)) ! 1014: (clobber (match_dup 1))])] ! 1015: "" ! 1016: " ! 1017: { ! 1018: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); ! 1019: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); ! 1020: operands[4] = gen_reg_rtx (SImode); ! 1021: operands[5] = gen_reg_rtx (SImode); ! 1022: operands[6] = gen_reg_rtx (SImode); ! 1023: }") ! 1024: ! 1025: (define_insn "" ! 1026: [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ! 1027: (mem:BLK (match_operand:SI 1 "register_operand" "r"))) ! 1028: (use (match_operand:SI 2 "general_operand" "rn")) ! 1029: (use (match_operand:SI 3 "immediate_operand" "i")) ! 1030: (clobber (match_operand:SI 4 "register_operand" "=r")) ! 1031: (clobber (match_operand:SI 5 "register_operand" "=r")) ! 1032: (clobber (match_operand:SI 6 "register_operand" "=r")) ! 1033: (clobber (match_dup 0)) ! 1034: (clobber (match_dup 1))] ! 1035: "" ! 1036: "* return output_block_move (operands);") ! 1037: ! 1038: ;; Floating point move insns ! 1039: ! 1040: ;; This pattern forces (set (reg:DF ...) (const_double ...)) ! 1041: ;; to be reloaded by putting the constant into memory. ! 1042: ;; It must come before the more general movdf pattern. ! 1043: (define_insn "" ! 1044: [(set (match_operand:DF 0 "general_operand" "=r,f,o") ! 1045: (match_operand:DF 1 "" "mG,m,G"))] ! 1046: "GET_CODE (operands[1]) == CONST_DOUBLE" ! 1047: "* ! 1048: { ! 1049: if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode)) ! 1050: return output_fp_move_double (operands); ! 1051: return output_move_double (operands); ! 1052: }") ! 1053: ! 1054: (define_insn "movdf" ! 1055: [(set (match_operand:DF 0 "general_operand" "=*rm,*r,?f,?*rm") ! 1056: (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))] ! 1057: "" ! 1058: "* ! 1059: { ! 1060: if (GET_CODE (operands[0]) == MEM ! 1061: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1062: return output_store (operands); ! 1063: if (GET_CODE (operands[1]) == MEM ! 1064: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1065: return output_load (operands); ! 1066: ! 1067: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! 1068: return output_fp_move_double (operands); ! 1069: return output_move_double (operands); ! 1070: }") ! 1071: ! 1072: (define_insn "movdi" ! 1073: [(set (match_operand:DI 0 "general_operand" "=rm,r,?f,?rm") ! 1074: (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))] ! 1075: "" ! 1076: "* ! 1077: { ! 1078: if (GET_CODE (operands[0]) == MEM ! 1079: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1080: return output_store (operands); ! 1081: if (GET_CODE (operands[1]) == MEM ! 1082: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1083: return output_load (operands); ! 1084: ! 1085: /* ??? How can we have a DFmode arg here with DImode above? */ ! 1086: if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode)) ! 1087: return \"fmov.dd %?f0,%0\"; ! 1088: ! 1089: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! 1090: return output_fp_move_double (operands); ! 1091: return output_move_double (operands); ! 1092: }") ! 1093: ! 1094: ;; The alternative m/r is separate from m/f ! 1095: ;; The first alternative is separate from the second for the same reason. ! 1096: (define_insn "movsf" ! 1097: [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m") ! 1098: (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))] ! 1099: "" ! 1100: "* ! 1101: { ! 1102: if (GET_CODE (operands[0]) == MEM ! 1103: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1104: return output_store (operands); ! 1105: if (GET_CODE (operands[1]) == MEM ! 1106: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1107: return output_load (operands); ! 1108: if (FP_REG_P (operands[0])) ! 1109: { ! 1110: if (FP_REG_P (operands[1])) ! 1111: return \"fmov.ss %1,%0\"; ! 1112: if (GET_CODE (operands[1]) == REG) ! 1113: return \"ixfr %1,%0\"; ! 1114: if (operands[1] == CONST0_RTX (SFmode)) ! 1115: return \"fmov.ss %?f0,%0\"; ! 1116: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1117: { ! 1118: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) ! 1119: && (cc_prev_status.flags & CC_HI_R31_ADJ) ! 1120: && cc_prev_status.mdep == XEXP(operands[1],0))) ! 1121: { ! 1122: CC_STATUS_INIT; ! 1123: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 1124: cc_status.mdep = XEXP (operands[1], 0); ! 1125: return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\"; ! 1126: } ! 1127: return \"fld.l %L1(%?r31),%0\"; ! 1128: } ! 1129: return \"fld.l %1,%0\"; ! 1130: } ! 1131: if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) ! 1132: { ! 1133: if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1])) ! 1134: return \"fxfr %1,%0\"; ! 1135: if (GET_CODE (operands[0]) == REG) ! 1136: { ! 1137: CC_STATUS_PARTIAL_INIT; ! 1138: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1139: { ! 1140: register unsigned long ul; ! 1141: ! 1142: ul = sfmode_constant_to_ulong (operands[1]); ! 1143: if ((ul & 0x0000ffff) == 0) ! 1144: return \"orh %H1,%?r0,%0\"; ! 1145: if ((ul & 0xffff0000) == 0) ! 1146: return \"or %L1,%?r0,%0\"; ! 1147: } ! 1148: return \"orh %H1,%?r0,%0\;or %L1,%0,%0\"; ! 1149: } ! 1150: /* Now operand 0 must be memory. ! 1151: If operand 1 is CONST_DOUBLE, its value must be 0. */ ! 1152: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1153: { ! 1154: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) ! 1155: && (cc_prev_status.flags & CC_HI_R31_ADJ) ! 1156: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 1157: { ! 1158: CC_STATUS_INIT; ! 1159: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 1160: cc_status.mdep = XEXP (operands[0], 0); ! 1161: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands); ! 1162: } ! 1163: return \"fst.l %r1,%L0(%?r31)\"; ! 1164: } ! 1165: return \"fst.l %r1,%0\"; ! 1166: } ! 1167: if (GET_CODE (operands[0]) == MEM) ! 1168: return \"st.l %r1,%0\"; ! 1169: if (GET_CODE (operands[1]) == MEM) ! 1170: return \"ld.l %1,%0\"; ! 1171: if (operands[1] == CONST0_RTX (SFmode)) ! 1172: return \"shl %?r0,%?r0,%0\"; ! 1173: return \"mov %1,%0\"; ! 1174: }") ! 1175: ! 1176: ;; Special load insns for REG+REG addresses. ! 1177: ;; Such addresses are not "legitimate" because st rejects them. ! 1178: ! 1179: (define_insn "" ! 1180: [(set (match_operand:DF 0 "register_operand" "=rf") ! 1181: (match_operand:DF 1 "indexed_operand" "m"))] ! 1182: "" ! 1183: "* ! 1184: { ! 1185: if (FP_REG_P (operands[0])) ! 1186: return output_fp_move_double (operands); ! 1187: return output_move_double (operands); ! 1188: }") ! 1189: ! 1190: (define_insn "" ! 1191: [(set (match_operand:SF 0 "register_operand" "=rf") ! 1192: (match_operand:SF 1 "indexed_operand" "m"))] ! 1193: "" ! 1194: "* ! 1195: { ! 1196: if (FP_REG_P (operands[0])) ! 1197: return \"fld.l %1,%0\"; ! 1198: return \"ld.l %1,%0\"; ! 1199: }") ! 1200: ! 1201: (define_insn "" ! 1202: [(set (match_operand:SI 0 "register_operand" "=rf") ! 1203: (match_operand:SI 1 "indexed_operand" "m"))] ! 1204: "" ! 1205: "* ! 1206: { ! 1207: if (FP_REG_P (operands[0])) ! 1208: return \"fld.l %1,%0\"; ! 1209: return \"ld.l %1,%0\"; ! 1210: }") ! 1211: ! 1212: (define_insn "" ! 1213: [(set (match_operand:HI 0 "register_operand" "=r") ! 1214: (match_operand:HI 1 "indexed_operand" "m"))] ! 1215: "" ! 1216: "ld.s %1,%0") ! 1217: ! 1218: (define_insn "" ! 1219: [(set (match_operand:QI 0 "register_operand" "=r") ! 1220: (match_operand:QI 1 "indexed_operand" "m"))] ! 1221: "" ! 1222: "ld.b %1,%0") ! 1223: ! 1224: ;; Likewise for floating-point store insns. ! 1225: ! 1226: (define_insn "" ! 1227: [(set (match_operand:DF 0 "indexed_operand" "=m") ! 1228: (match_operand:DF 1 "register_operand" "f"))] ! 1229: "" ! 1230: "fst.d %1,%0") ! 1231: ! 1232: (define_insn "" ! 1233: [(set (match_operand:SF 0 "indexed_operand" "=m") ! 1234: (match_operand:SF 1 "register_operand" "f"))] ! 1235: "" ! 1236: "fst.l %1,%0") ! 1237: ! 1238: ;;- truncation instructions ! 1239: (define_insn "truncsiqi2" ! 1240: [(set (match_operand:QI 0 "general_operand" "=g") ! 1241: (truncate:QI ! 1242: (match_operand:SI 1 "register_operand" "r")))] ! 1243: "" ! 1244: "* ! 1245: { ! 1246: if (GET_CODE (operands[0]) == MEM) ! 1247: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1248: { ! 1249: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) ! 1250: && (cc_prev_status.flags & CC_HI_R31_ADJ) ! 1251: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 1252: { ! 1253: CC_STATUS_INIT; ! 1254: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 1255: cc_status.mdep = XEXP (operands[0], 0); ! 1256: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands); ! 1257: } ! 1258: return \"st.b %1,%L0(%?r31)\"; ! 1259: } ! 1260: else ! 1261: return \"st.b %1,%0\"; ! 1262: return \"shl %?r0,%1,%0\"; ! 1263: }") ! 1264: ! 1265: (define_insn "trunchiqi2" ! 1266: [(set (match_operand:QI 0 "general_operand" "=g") ! 1267: (truncate:QI ! 1268: (match_operand:HI 1 "register_operand" "r")))] ! 1269: "" ! 1270: "* ! 1271: { ! 1272: if (GET_CODE (operands[0]) == MEM) ! 1273: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1274: { ! 1275: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) ! 1276: && (cc_prev_status.flags & CC_HI_R31_ADJ) ! 1277: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 1278: { ! 1279: CC_STATUS_INIT; ! 1280: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 1281: cc_status.mdep = XEXP (operands[0], 0); ! 1282: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands); ! 1283: } ! 1284: return \"st.b %1,%L0(%?r31)\"; ! 1285: } ! 1286: else ! 1287: return \"st.b %1,%0\"; ! 1288: return \"shl %?r0,%1,%0\"; ! 1289: }") ! 1290: ! 1291: (define_insn "truncsihi2" ! 1292: [(set (match_operand:HI 0 "general_operand" "=g") ! 1293: (truncate:HI ! 1294: (match_operand:SI 1 "register_operand" "r")))] ! 1295: "" ! 1296: "* ! 1297: { ! 1298: if (GET_CODE (operands[0]) == MEM) ! 1299: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1300: { ! 1301: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) ! 1302: && (cc_prev_status.flags & CC_HI_R31_ADJ) ! 1303: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 1304: { ! 1305: CC_STATUS_INIT; ! 1306: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 1307: cc_status.mdep = XEXP (operands[0], 0); ! 1308: output_asm_insn (\"orh %h0,%?r0,%?r31\", operands); ! 1309: } ! 1310: return \"st.s %1,%L0(%?r31)\"; ! 1311: } ! 1312: else ! 1313: return \"st.s %1,%0\"; ! 1314: return \"shl %?r0,%1,%0\"; ! 1315: }") ! 1316: ! 1317: ;;- zero extension instructions ! 1318: ! 1319: (define_insn "zero_extendhisi2" ! 1320: [(set (match_operand:SI 0 "register_operand" "=r") ! 1321: (zero_extend:SI ! 1322: (match_operand:HI 1 "register_operand" "r")))] ! 1323: "" ! 1324: "* ! 1325: { ! 1326: CC_STATUS_PARTIAL_INIT; ! 1327: return \"and 0xffff,%1,%0\"; ! 1328: }") ! 1329: ! 1330: (define_insn "zero_extendqihi2" ! 1331: [(set (match_operand:HI 0 "register_operand" "=r") ! 1332: (zero_extend:HI ! 1333: (match_operand:QI 1 "register_operand" "r")))] ! 1334: "" ! 1335: "* ! 1336: { ! 1337: CC_STATUS_PARTIAL_INIT; ! 1338: return \"and 0xff,%1,%0\"; ! 1339: }") ! 1340: ! 1341: (define_insn "zero_extendqisi2" ! 1342: [(set (match_operand:SI 0 "register_operand" "=r") ! 1343: (zero_extend:SI ! 1344: (match_operand:QI 1 "register_operand" "r")))] ! 1345: "" ! 1346: "* ! 1347: { ! 1348: CC_STATUS_PARTIAL_INIT; ! 1349: return \"and 0xff,%1,%0\"; ! 1350: }") ! 1351: ! 1352: ;; Sign extension instructions. ! 1353: ! 1354: (define_insn "" ! 1355: [(set (match_operand:SI 0 "register_operand" "=r") ! 1356: (sign_extend:SI ! 1357: (match_operand:HI 1 "indexed_operand" "m")))] ! 1358: "" ! 1359: "ld.s %1,%0") ! 1360: ! 1361: (define_insn "" ! 1362: [(set (match_operand:HI 0 "register_operand" "=r") ! 1363: (sign_extend:HI ! 1364: (match_operand:QI 1 "indexed_operand" "m")))] ! 1365: "" ! 1366: "ld.b %1,%0") ! 1367: ! 1368: (define_insn "" ! 1369: [(set (match_operand:SI 0 "register_operand" "=r") ! 1370: (sign_extend:SI ! 1371: (match_operand:QI 1 "indexed_operand" "m")))] ! 1372: "" ! 1373: "ld.b %1,%0") ! 1374: ! 1375: (define_insn "extendhisi2" ! 1376: [(set (match_operand:SI 0 "register_operand" "=r") ! 1377: (sign_extend:SI ! 1378: (match_operand:HI 1 "nonimmediate_operand" "mr")))] ! 1379: "" ! 1380: "* ! 1381: { ! 1382: if (REG_P (operands[1])) ! 1383: return \"shl 16,%1,%0\;shra 16,%0,%0\"; ! 1384: if (GET_CODE (operands[1]) == CONST_INT) ! 1385: abort (); ! 1386: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1387: { ! 1388: CC_STATUS_INIT; ! 1389: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 1390: cc_status.mdep = XEXP (operands[1], 0); ! 1391: return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\"; ! 1392: } ! 1393: else ! 1394: return \"ld.s %1,%0\"; ! 1395: }") ! 1396: ! 1397: (define_insn "extendqihi2" ! 1398: [(set (match_operand:HI 0 "register_operand" "=r") ! 1399: (sign_extend:HI ! 1400: (match_operand:QI 1 "nonimmediate_operand" "mr")))] ! 1401: "" ! 1402: "* ! 1403: { ! 1404: if (REG_P (operands[1])) ! 1405: return \"shl 24,%1,%0\;shra 24,%0,%0\"; ! 1406: if (GET_CODE (operands[1]) == CONST_INT) ! 1407: abort (); ! 1408: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1409: { ! 1410: CC_STATUS_INIT; ! 1411: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 1412: cc_status.mdep = XEXP (operands[1], 0); ! 1413: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\"; ! 1414: } ! 1415: else ! 1416: return \"ld.b %1,%0\"; ! 1417: }") ! 1418: ! 1419: (define_insn "extendqisi2" ! 1420: [(set (match_operand:SI 0 "register_operand" "=r") ! 1421: (sign_extend:SI ! 1422: (match_operand:QI 1 "nonimmediate_operand" "mr")))] ! 1423: "" ! 1424: "* ! 1425: { ! 1426: if (REG_P (operands[1])) ! 1427: return \"shl 24,%1,%0\;shra 24,%0,%0\"; ! 1428: if (GET_CODE (operands[1]) == CONST_INT) ! 1429: abort (); ! 1430: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1431: { ! 1432: CC_STATUS_INIT; ! 1433: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 1434: cc_status.mdep = XEXP (operands[1], 0); ! 1435: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\"; ! 1436: } ! 1437: else ! 1438: return \"ld.b %1,%0\"; ! 1439: }") ! 1440: ! 1441: ;; Signed bitfield extractions come out looking like ! 1442: ;; (shiftrt (sign_extend (shift <Y> <C1>)) <C2>) ! 1443: ;; which we expand poorly as four shift insns. ! 1444: ;; These patters yeild two shifts: ! 1445: ;; (shiftrt (shift <Y> <C3>) <C4>) ! 1446: (define_insn "" ! 1447: [(set (match_operand:SI 0 "register_operand" "=r") ! 1448: (ashiftrt:SI ! 1449: (sign_extend:SI ! 1450: (match_operand:QI 1 "register_operand" "r")) ! 1451: (match_operand:SI 2 "logic_int" "n")))] ! 1452: "INTVAL (operands[2]) < 8" ! 1453: "* ! 1454: { ! 1455: return \"shl 24,%1,%0\;shra 24+%2,%0,%0\"; ! 1456: }") ! 1457: ! 1458: (define_insn "" ! 1459: [(set (match_operand:SI 0 "register_operand" "=r") ! 1460: (ashiftrt:SI ! 1461: (sign_extend:SI ! 1462: (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r") ! 1463: (match_operand:SI 2 "logic_int" "n")) 0)) ! 1464: (match_operand:SI 3 "logic_int" "n")))] ! 1465: "INTVAL (operands[3]) < 8" ! 1466: "* ! 1467: { ! 1468: return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\"; ! 1469: }") ! 1470: ! 1471: (define_insn "" ! 1472: [(set (match_operand:SI 0 "register_operand" "=r") ! 1473: (ashiftrt:SI ! 1474: (sign_extend:SI ! 1475: (ashift:QI (match_operand:QI 1 "register_operand" "r") ! 1476: (match_operand:QI 2 "logic_int" "n"))) ! 1477: (match_operand:SI 3 "logic_int" "n")))] ! 1478: "INTVAL (operands[3]) < 8" ! 1479: "* ! 1480: { ! 1481: return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\"; ! 1482: }") ! 1483: ! 1484: ;; Special patterns for optimizing bit-field instructions. ! 1485: ! 1486: ;; First two patterns are for bitfields that came from memory ! 1487: ;; testing only the high bit. They work with old combiner. ! 1488: ! 1489: (define_insn "" ! 1490: [(set (cc0) ! 1491: (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r") ! 1492: (const_int 7)) 0)) ! 1493: (const_int 0)))] ! 1494: "" ! 1495: "* ! 1496: { ! 1497: CC_STATUS_PARTIAL_INIT; ! 1498: return \"and 128,%0,%?r0\"; ! 1499: }") ! 1500: ! 1501: (define_insn "" ! 1502: [(set (cc0) ! 1503: (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r") ! 1504: (const_int 7)) 0)) ! 1505: (const_int 0)))] ! 1506: "" ! 1507: "* ! 1508: { ! 1509: CC_STATUS_PARTIAL_INIT; ! 1510: return \"and 128,%0,%?r0\"; ! 1511: }") ! 1512: ! 1513: ;; next two patterns are good for bitfields coming from memory ! 1514: ;; (via pseudo-register) or from a register, though this optimization ! 1515: ;; is only good for values contained wholly within the bottom 13 bits ! 1516: (define_insn "" ! 1517: [(set (cc0) ! 1518: (eq ! 1519: (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r") ! 1520: (match_operand:SI 1 "logic_int" "n")) ! 1521: (match_operand:SI 2 "logic_int" "n")) ! 1522: (const_int 0)))] ! 1523: "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))" ! 1524: "* ! 1525: { ! 1526: CC_STATUS_PARTIAL_INIT; ! 1527: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1528: (INTVAL (operands[2]) << INTVAL (operands[1]))); ! 1529: return \"and %2,%0,%?r0\"; ! 1530: }") ! 1531: ! 1532: (define_insn "" ! 1533: [(set (cc0) ! 1534: (eq ! 1535: (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r") ! 1536: (match_operand:SI 1 "logic_int" "n")) ! 1537: (match_operand:SI 2 "logic_int" "n")) ! 1538: (const_int 0)))] ! 1539: "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))" ! 1540: "* ! 1541: { ! 1542: CC_STATUS_PARTIAL_INIT; ! 1543: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1544: (INTVAL (operands[2]) << INTVAL (operands[1]))); ! 1545: return \"and %2,%0,%?r0\"; ! 1546: }") ! 1547: ! 1548: ;; Conversions between float and double. ! 1549: ! 1550: (define_insn "extendsfdf2" ! 1551: [(set (match_operand:DF 0 "register_operand" "=f") ! 1552: (float_extend:DF ! 1553: (match_operand:SF 1 "register_operand" "f")))] ! 1554: "" ! 1555: "fmov.sd %1,%0") ! 1556: ! 1557: (define_insn "truncdfsf2" ! 1558: [(set (match_operand:SF 0 "register_operand" "=f") ! 1559: (float_truncate:SF ! 1560: (match_operand:DF 1 "register_operand" "f")))] ! 1561: "" ! 1562: "fmov.ds %1,%0") ! 1563: ! 1564: ;; Conversion between fixed point and floating point. ! 1565: ;; Note that among the fix-to-float insns ! 1566: ;; the ones that start with SImode come first. ! 1567: ;; That is so that an operand that is a CONST_INT ! 1568: ;; (and therefore lacks a specific machine mode). ! 1569: ;; will be recognized as SImode (which is always valid) ! 1570: ;; rather than as QImode or HImode. ! 1571: ! 1572: ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...))) ! 1573: ;; to be reloaded by putting the constant into memory. ! 1574: ;; It must come before the more general floatsisf2 pattern. ! 1575: (define_expand "floatsidf2" ! 1576: [(set (match_dup 2) (match_dup 3)) ! 1577: (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "") ! 1578: (const_int -2147483648))) ! 1579: (set (match_dup 5) (match_dup 3)) ! 1580: (set (subreg:SI (match_dup 5) 0) (match_dup 4)) ! 1581: (set (match_operand:DF 0 "register_operand" "") ! 1582: (minus:DF (match_dup 5) (match_dup 2)))] ! 1583: "" ! 1584: " ! 1585: { ! 1586: REAL_VALUE_TYPE d; ! 1587: /* 4503601774854144 is (1 << 30) * ((1 << 22) + (1 << 1)). */ ! 1588: d = REAL_VALUE_ATOF (\"4503601774854144\", DFmode); ! 1589: operands[2] = gen_reg_rtx (DFmode); ! 1590: operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode); ! 1591: operands[4] = gen_reg_rtx (SImode); ! 1592: operands[5] = gen_reg_rtx (DFmode); ! 1593: }") ! 1594: ! 1595: ;; Floating to fixed conversion. ! 1596: ! 1597: (define_expand "fix_truncdfsi2" ! 1598: ;; This first insn produces a double-word value ! 1599: ;; in which only the low word is valid. ! 1600: [(set (match_dup 2) ! 1601: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f")))) ! 1602: (set (match_operand:SI 0 "register_operand" "=f") ! 1603: (subreg:SI (match_dup 2) 0))] ! 1604: "" ! 1605: " ! 1606: { ! 1607: operands[2] = gen_reg_rtx (DImode); ! 1608: }") ! 1609: ! 1610: ;; Recognize the first insn generated above. ! 1611: ;; This RTL looks like a fix_truncdfdi2 insn, ! 1612: ;; but we dont call it that, because only 32 bits ! 1613: ;; of the result are valid. ! 1614: ;; This pattern will work for the intended purposes ! 1615: ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2. ! 1616: (define_insn "" ! 1617: [(set (match_operand:DI 0 "register_operand" "=f") ! 1618: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] ! 1619: "" ! 1620: "ftrunc.dd %1,%0") ! 1621: ! 1622: (define_expand "fix_truncsfsi2" ! 1623: ;; This first insn produces a double-word value ! 1624: ;; in which only the low word is valid. ! 1625: [(set (match_dup 2) ! 1626: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f")))) ! 1627: (set (match_operand:SI 0 "register_operand" "=f") ! 1628: (subreg:SI (match_dup 2) 0))] ! 1629: "" ! 1630: " ! 1631: { ! 1632: operands[2] = gen_reg_rtx (DImode); ! 1633: }") ! 1634: ! 1635: ;; Recognize the first insn generated above. ! 1636: ;; This RTL looks like a fix_truncsfdi2 insn, ! 1637: ;; but we dont call it that, because only 32 bits ! 1638: ;; of the result are valid. ! 1639: ;; This pattern will work for the intended purposes ! 1640: ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2. ! 1641: (define_insn "" ! 1642: [(set (match_operand:DI 0 "register_operand" "=f") ! 1643: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] ! 1644: "" ! 1645: "ftrunc.sd %1,%0") ! 1646: ! 1647: ;;- arithmetic instructions ! 1648: ! 1649: (define_insn "addsi3" ! 1650: [(set (match_operand:SI 0 "register_operand" "=r,*f") ! 1651: (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f") ! 1652: (match_operand:SI 2 "arith_operand" "rI,*f")))] ! 1653: "" ! 1654: "* ! 1655: { ! 1656: if (which_alternative == 1) ! 1657: return \"fiadd.ss %2,%1,%0\"; ! 1658: CC_STATUS_PARTIAL_INIT; ! 1659: return \"addu %2,%1,%0\"; ! 1660: }") ! 1661: ! 1662: (define_insn "adddi3" ! 1663: [(set (match_operand:DI 0 "register_operand" "=f") ! 1664: (plus:DI (match_operand:DI 1 "register_operand" "%f") ! 1665: (match_operand:DI 2 "register_operand" "f")))] ! 1666: "" ! 1667: "fiadd.dd %1,%2,%0") ! 1668: ! 1669: (define_insn "subsi3" ! 1670: [(set (match_operand:SI 0 "register_operand" "=r,r,*f") ! 1671: (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f") ! 1672: (match_operand:SI 2 "arith_operand" "rI,r,*f")))] ! 1673: "" ! 1674: "* ! 1675: { ! 1676: if (which_alternative == 2) ! 1677: return \"fisub.ss %1,%2,%0\"; ! 1678: CC_STATUS_PARTIAL_INIT; ! 1679: if (REG_P (operands[2])) ! 1680: return \"subu %1,%2,%0\"; ! 1681: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2])); ! 1682: return \"addu %2,%1,%0\"; ! 1683: }") ! 1684: ! 1685: (define_insn "subdi3" ! 1686: [(set (match_operand:DI 0 "register_operand" "=f") ! 1687: (minus:DI (match_operand:DI 1 "register_operand" "%f") ! 1688: (match_operand:DI 2 "register_operand" "f")))] ! 1689: "" ! 1690: "fisub.dd %1,%2,%0") ! 1691: ! 1692: (define_expand "mulsi3" ! 1693: [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" "")) ! 1694: (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" "")) ! 1695: (clobber (match_dup 3)) ! 1696: (set (subreg:SI (match_dup 3) 0) ! 1697: (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0))) ! 1698: (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))] ! 1699: "" ! 1700: " ! 1701: { ! 1702: if (WORDS_BIG_ENDIAN) ! 1703: emit_insn (gen_mulsi3_big (operands[0], operands[1], operands[2])); ! 1704: else ! 1705: emit_insn (gen_mulsi3_little (operands[0], operands[1], operands[2])); ! 1706: DONE; ! 1707: }") ! 1708: ! 1709: (define_expand "mulsi3_little" ! 1710: [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" "")) ! 1711: (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" "")) ! 1712: (clobber (match_dup 3)) ! 1713: (set (subreg:SI (match_dup 3) 0) ! 1714: (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0))) ! 1715: (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))] ! 1716: "! WORDS_BIG_ENDIAN" ! 1717: " ! 1718: { ! 1719: operands[3] = gen_reg_rtx (DImode); ! 1720: operands[4] = gen_reg_rtx (DImode); ! 1721: operands[5] = gen_reg_rtx (DImode); ! 1722: }") ! 1723: ! 1724: (define_expand "mulsi3_big" ! 1725: [(set (subreg:SI (match_dup 4) 1) (match_operand:SI 1 "general_operand" "")) ! 1726: (set (subreg:SI (match_dup 5) 1) (match_operand:SI 2 "general_operand" "")) ! 1727: (clobber (match_dup 3)) ! 1728: (set (subreg:SI (match_dup 3) 1) ! 1729: (mult:SI (subreg:SI (match_dup 4) 1) (subreg:SI (match_dup 5) 1))) ! 1730: (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 1))] ! 1731: "WORDS_BIG_ENDIAN" ! 1732: " ! 1733: { ! 1734: operands[3] = gen_reg_rtx (DImode); ! 1735: operands[4] = gen_reg_rtx (DImode); ! 1736: operands[5] = gen_reg_rtx (DImode); ! 1737: }") ! 1738: ! 1739: (define_insn "" ! 1740: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0) ! 1741: (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0) ! 1742: (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))] ! 1743: "! WORDS_BIG_ENDIAN" ! 1744: "fmlow.dd %2,%1,%0") ! 1745: ! 1746: (define_insn "" ! 1747: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 1) ! 1748: (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 1) ! 1749: (subreg:SI (match_operand:DI 2 "register_operand" "f") 1)))] ! 1750: "WORDS_BIG_ENDIAN" ! 1751: "fmlow.dd %2,%1,%0") ! 1752: ! 1753: ;;- and instructions (with compliment also) ! 1754: (define_insn "andsi3" ! 1755: [(set (match_operand:SI 0 "register_operand" "=r") ! 1756: (and:SI (match_operand:SI 1 "nonmemory_operand" "%r") ! 1757: (match_operand:SI 2 "nonmemory_operand" "rL")))] ! 1758: "" ! 1759: "* ! 1760: { ! 1761: rtx xop[3]; ! 1762: ! 1763: CC_STATUS_PARTIAL_INIT; ! 1764: if (REG_P (operands[2]) || LOGIC_INT (operands[2])) ! 1765: return \"and %2,%1,%0\"; ! 1766: if ((INTVAL (operands[2]) & 0xffff) == 0) ! 1767: { ! 1768: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1769: (unsigned) INTVAL (operands[2]) >> 16); ! 1770: return \"andh %2,%1,%0\"; ! 1771: } ! 1772: xop[0] = operands[0]; ! 1773: xop[1] = operands[1]; ! 1774: xop[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]) & 0xffff); ! 1775: output_asm_insn (\"andnot %2,%1,%0\", xop); ! 1776: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1777: ~(unsigned) INTVAL (operands[2]) >> 16); ! 1778: return \"andnoth %2,%0,%0\"; ! 1779: }") ! 1780: ! 1781: (define_insn "" ! 1782: [(set (match_operand:SI 0 "register_operand" "=r") ! 1783: (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn")) ! 1784: (match_operand:SI 2 "register_operand" "r")))] ! 1785: "" ! 1786: "* ! 1787: { ! 1788: rtx xop[3]; ! 1789: ! 1790: CC_STATUS_PARTIAL_INIT; ! 1791: if (REG_P (operands[1]) || LOGIC_INT (operands[1])) ! 1792: return \"andnot %1,%2,%0\"; ! 1793: if ((INTVAL (operands[1]) & 0xffff) == 0) ! 1794: { ! 1795: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 1796: (unsigned) INTVAL (operands[1]) >> 16); ! 1797: return \"andnoth %1,%2,%0\"; ! 1798: } ! 1799: xop[0] = operands[0]; ! 1800: xop[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) & 0xffff)); ! 1801: xop[2] = operands[2]; ! 1802: output_asm_insn (\"andnot %1,%2,%0\", xop); ! 1803: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 1804: (unsigned) INTVAL (operands[1]) >> 16); ! 1805: return \"andnoth %1,%0,%0\"; ! 1806: }") ! 1807: ! 1808: (define_insn "iorsi3" ! 1809: [(set (match_operand:SI 0 "register_operand" "=r") ! 1810: (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r") ! 1811: (match_operand:SI 2 "nonmemory_operand" "rL")))] ! 1812: "" ! 1813: "* ! 1814: { ! 1815: rtx xop[3]; ! 1816: ! 1817: CC_STATUS_PARTIAL_INIT; ! 1818: if (REG_P (operands[2]) || LOGIC_INT (operands[2])) ! 1819: return \"or %2,%1,%0\"; ! 1820: if ((INTVAL (operands[2]) & 0xffff) == 0) ! 1821: { ! 1822: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1823: (unsigned) INTVAL (operands[2]) >> 16); ! 1824: return \"orh %2,%1,%0\"; ! 1825: } ! 1826: xop[0] = operands[0]; ! 1827: xop[1] = operands[1]; ! 1828: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff)); ! 1829: output_asm_insn (\"or %2,%1,%0\", xop); ! 1830: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1831: (unsigned) INTVAL (operands[2]) >> 16); ! 1832: return \"orh %2,%0,%0\"; ! 1833: }") ! 1834: ! 1835: (define_insn "xorsi3" ! 1836: [(set (match_operand:SI 0 "register_operand" "=r") ! 1837: (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r") ! 1838: (match_operand:SI 2 "nonmemory_operand" "rL")))] ! 1839: "" ! 1840: "* ! 1841: { ! 1842: rtx xop[3]; ! 1843: ! 1844: CC_STATUS_PARTIAL_INIT; ! 1845: if (REG_P (operands[2]) || LOGIC_INT (operands[2])) ! 1846: return \"xor %2,%1,%0\"; ! 1847: if ((INTVAL (operands[2]) & 0xffff) == 0) ! 1848: { ! 1849: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1850: (unsigned) INTVAL (operands[2]) >> 16); ! 1851: return \"xorh %2,%1,%0\"; ! 1852: } ! 1853: xop[0] = operands[0]; ! 1854: xop[1] = operands[1]; ! 1855: xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff)); ! 1856: output_asm_insn (\"xor %2,%1,%0\", xop); ! 1857: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1858: (unsigned) INTVAL (operands[2]) >> 16); ! 1859: return \"xorh %2,%0,%0\"; ! 1860: }") ! 1861: ! 1862: ;(The i860 instruction set doesn't allow an immediate second operand in ! 1863: ; a subtraction.) ! 1864: (define_insn "negsi2" ! 1865: [(set (match_operand:SI 0 "general_operand" "=r") ! 1866: (neg:SI (match_operand:SI 1 "arith_operand" "r")))] ! 1867: "" ! 1868: "* ! 1869: { ! 1870: CC_STATUS_PARTIAL_INIT; ! 1871: return \"subu %?r0,%1,%0\"; ! 1872: }") ! 1873: ! 1874: (define_insn "one_cmplsi2" ! 1875: [(set (match_operand:SI 0 "general_operand" "=r") ! 1876: (not:SI (match_operand:SI 1 "arith_operand" "r")))] ! 1877: "" ! 1878: "* ! 1879: { ! 1880: CC_STATUS_PARTIAL_INIT; ! 1881: return \"subu -1,%1,%0\"; ! 1882: }") ! 1883: ! 1884: ;; Floating point arithmetic instructions. ! 1885: ! 1886: (define_insn "adddf3" ! 1887: [(set (match_operand:DF 0 "register_operand" "=f") ! 1888: (plus:DF (match_operand:DF 1 "register_operand" "f") ! 1889: (match_operand:DF 2 "register_operand" "f")))] ! 1890: "" ! 1891: "fadd.dd %1,%2,%0") ! 1892: ! 1893: (define_insn "addsf3" ! 1894: [(set (match_operand:SF 0 "register_operand" "=f") ! 1895: (plus:SF (match_operand:SF 1 "register_operand" "f") ! 1896: (match_operand:SF 2 "register_operand" "f")))] ! 1897: "" ! 1898: "fadd.ss %1,%2,%0") ! 1899: ! 1900: (define_insn "subdf3" ! 1901: [(set (match_operand:DF 0 "register_operand" "=f") ! 1902: (minus:DF (match_operand:DF 1 "register_operand" "f") ! 1903: (match_operand:DF 2 "register_operand" "f")))] ! 1904: "" ! 1905: "fsub.dd %1,%2,%0") ! 1906: ! 1907: (define_insn "subsf3" ! 1908: [(set (match_operand:SF 0 "register_operand" "=f") ! 1909: (minus:SF (match_operand:SF 1 "register_operand" "f") ! 1910: (match_operand:SF 2 "register_operand" "f")))] ! 1911: "" ! 1912: "fsub.ss %1,%2,%0") ! 1913: ! 1914: (define_insn "muldf3" ! 1915: [(set (match_operand:DF 0 "register_operand" "=f") ! 1916: (mult:DF (match_operand:DF 1 "register_operand" "f") ! 1917: (match_operand:DF 2 "register_operand" "f")))] ! 1918: "" ! 1919: "fmul.dd %1,%2,%0") ! 1920: ! 1921: (define_insn "mulsf3" ! 1922: [(set (match_operand:SF 0 "register_operand" "=f") ! 1923: (mult:SF (match_operand:SF 1 "register_operand" "f") ! 1924: (match_operand:SF 2 "register_operand" "f")))] ! 1925: "" ! 1926: "fmul.ss %1,%2,%0") ! 1927: ! 1928: (define_insn "negdf2" ! 1929: [(set (match_operand:DF 0 "register_operand" "=f") ! 1930: (neg:DF (match_operand:DF 1 "register_operand" "f")))] ! 1931: "" ! 1932: "fsub.dd %?f0,%1,%0") ! 1933: ! 1934: (define_insn "negsf2" ! 1935: [(set (match_operand:SF 0 "register_operand" "=f") ! 1936: (neg:SF (match_operand:SF 1 "register_operand" "f")))] ! 1937: "" ! 1938: "fsub.ss %?f0,%1,%0") ! 1939: ! 1940: (define_insn "divdf3" ! 1941: [(set (match_operand:DF 0 "register_operand" "=&f") ! 1942: (div:DF (match_operand:DF 1 "register_operand" "f") ! 1943: (match_operand:DF 2 "register_operand" "f"))) ! 1944: (clobber (match_scratch:DF 3 "=&f")) ! 1945: (clobber (match_scratch:DF 4 "=&f"))] ! 1946: "" ! 1947: "* ! 1948: { ! 1949: CC_STATUS_PARTIAL_INIT; ! 1950: if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0) ! 1951: || (cc_prev_status.flags & CC_HI_R31_ADJ) ! 1952: || (cc_prev_status.mdep != CONST2_RTX (SFmode))) ! 1953: { ! 1954: cc_status.flags |= CC_KNOW_HI_R31; ! 1955: cc_status.flags &= ~CC_HI_R31_ADJ; ! 1956: cc_status.mdep = CONST2_RTX (SFmode); ! 1957: return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\ ! 1958: orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\ ! 1959: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\ ! 1960: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\ ! 1961: fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\"; ! 1962: } ! 1963: else ! 1964: return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\ ! 1965: ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\ ! 1966: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\ ! 1967: fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\ ! 1968: fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\"; ! 1969: }") ! 1970: ! 1971: (define_insn "divsf3" ! 1972: [(set (match_operand:SF 0 "register_operand" "=&f") ! 1973: (div:SF (match_operand:SF 1 "register_operand" "f") ! 1974: (match_operand:SF 2 "register_operand" "f"))) ! 1975: (clobber (match_scratch:SF 3 "=&f")) ! 1976: (clobber (match_scratch:SF 4 "=&f"))] ! 1977: "" ! 1978: "* ! 1979: { ! 1980: CC_STATUS_PARTIAL_INIT; ! 1981: if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0) ! 1982: || (cc_prev_status.flags & CC_HI_R31_ADJ) ! 1983: || (cc_prev_status.mdep != CONST2_RTX (SFmode))) ! 1984: { ! 1985: cc_status.flags |= CC_KNOW_HI_R31; ! 1986: cc_status.flags &= ~CC_HI_R31_ADJ; ! 1987: cc_status.mdep = CONST2_RTX (SFmode); ! 1988: output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands); ! 1989: } ! 1990: return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\\ ! 1991: fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\\ ! 1992: fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\\ ! 1993: fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\"; ! 1994: }") ! 1995: ! 1996: ;; Shift instructions ! 1997: ! 1998: ;; Optimized special case of shifting. ! 1999: ;; Must precede the general case. ! 2000: ! 2001: (define_insn "" ! 2002: [(set (match_operand:SI 0 "register_operand" "=r") ! 2003: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") ! 2004: (const_int 24)))] ! 2005: "" ! 2006: "* ! 2007: { ! 2008: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 2009: { ! 2010: CC_STATUS_INIT; ! 2011: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; ! 2012: cc_status.mdep = XEXP (operands[1], 0); ! 2013: return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\"; ! 2014: } ! 2015: return \"ld.b %1,%0\"; ! 2016: }") ! 2017: ! 2018: ! 2019: ;;- arithmetic shift instructions ! 2020: (define_insn "ashlsi3" ! 2021: [(set (match_operand:SI 0 "register_operand" "=r") ! 2022: (ashift:SI (match_operand:SI 1 "register_operand" "r") ! 2023: (match_operand:SI 2 "shift_operand" "rn")))] ! 2024: "" ! 2025: "* ! 2026: { ! 2027: return \"shl %2,%1,%0\"; ! 2028: }") ! 2029: ! 2030: (define_insn "ashlhi3" ! 2031: [(set (match_operand:HI 0 "register_operand" "=r") ! 2032: (ashift:HI (match_operand:HI 1 "register_operand" "r") ! 2033: (match_operand:HI 2 "shift_operand" "rn")))] ! 2034: "" ! 2035: "* ! 2036: { ! 2037: return \"shl %2,%1,%0\"; ! 2038: }") ! 2039: ! 2040: (define_insn "ashlqi3" ! 2041: [(set (match_operand:QI 0 "register_operand" "=r") ! 2042: (ashift:QI (match_operand:QI 1 "register_operand" "r") ! 2043: (match_operand:QI 2 "shift_operand" "rn")))] ! 2044: "" ! 2045: "* ! 2046: { ! 2047: return \"shl %2,%1,%0\"; ! 2048: }") ! 2049: ! 2050: (define_insn "ashrsi3" ! 2051: [(set (match_operand:SI 0 "register_operand" "=r") ! 2052: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") ! 2053: (match_operand:SI 2 "shift_operand" "rn")))] ! 2054: "" ! 2055: "* ! 2056: { ! 2057: return \"shra %2,%1,%0\"; ! 2058: }") ! 2059: ! 2060: (define_insn "lshrsi3" ! 2061: [(set (match_operand:SI 0 "register_operand" "=r") ! 2062: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") ! 2063: (match_operand:SI 2 "shift_operand" "rn")))] ! 2064: "" ! 2065: "* ! 2066: { ! 2067: return \"shr %2,%1,%0\"; ! 2068: }") ! 2069: ! 2070: ;; Unconditional and other jump instructions ! 2071: ! 2072: (define_insn "jump" ! 2073: [(set (pc) (label_ref (match_operand 0 "" "")))] ! 2074: "" ! 2075: "* ! 2076: { ! 2077: return \"br %l0\;nop\"; ! 2078: }") ! 2079: ! 2080: ;; Here are two simple peepholes which fill the delay slot of ! 2081: ;; an unconditional branch. ! 2082: ! 2083: (define_peephole ! 2084: [(set (match_operand:SI 0 "register_operand" "=rf") ! 2085: (match_operand:SI 1 "single_insn_src_p" "gfG")) ! 2086: (set (pc) (label_ref (match_operand 2 "" "")))] ! 2087: "" ! 2088: "* return output_delayed_branch (\"br %l2\", operands, insn);") ! 2089: ! 2090: (define_peephole ! 2091: [(set (match_operand:SI 0 "memory_operand" "=m") ! 2092: (match_operand:SI 1 "reg_or_0_operand" "rfJ")) ! 2093: (set (pc) (label_ref (match_operand 2 "" "")))] ! 2094: "" ! 2095: "* return output_delayed_branch (\"br %l2\", operands, insn);") ! 2096: ! 2097: (define_insn "tablejump" ! 2098: [(set (pc) (match_operand:SI 0 "register_operand" "r")) ! 2099: (use (label_ref (match_operand 1 "" "")))] ! 2100: "" ! 2101: "bri %0\;nop") ! 2102: ! 2103: (define_peephole ! 2104: [(set (match_operand:SI 0 "memory_operand" "=m") ! 2105: (match_operand:SI 1 "reg_or_0_operand" "rfJ")) ! 2106: (set (pc) (match_operand:SI 2 "register_operand" "r")) ! 2107: (use (label_ref (match_operand 3 "" "")))] ! 2108: "" ! 2109: "* return output_delayed_branch (\"bri %2\", operands, insn);") ! 2110: ! 2111: ;;- jump to subroutine ! 2112: (define_expand "call" ! 2113: [(call (match_operand:SI 0 "memory_operand" "m") ! 2114: (match_operand 1 "" "i"))] ! 2115: ;; operand[2] is next_arg_register ! 2116: "" ! 2117: " ! 2118: { ! 2119: /* Make sure the address is just one reg and will stay that way. */ ! 2120: if (! call_insn_operand (operands[0], QImode)) ! 2121: operands[0] ! 2122: = change_address (operands[0], VOIDmode, ! 2123: copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); ! 2124: if (INTVAL (operands[1]) > 0) ! 2125: { ! 2126: emit_move_insn (arg_pointer_rtx, stack_pointer_rtx); ! 2127: emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx)); ! 2128: } ! 2129: }") ! 2130: ! 2131: ;;- jump to subroutine ! 2132: (define_insn "" ! 2133: [(call (match_operand:SI 0 "call_insn_operand" "m") ! 2134: (match_operand 1 "" "i"))] ! 2135: ;; operand[2] is next_arg_register ! 2136: "" ! 2137: "* ! 2138: { ! 2139: /* strip the MEM. */ ! 2140: operands[0] = XEXP (operands[0], 0); ! 2141: CC_STATUS_INIT; ! 2142: if (GET_CODE (operands[0]) == REG) ! 2143: return \"calli %0\;nop\"; ! 2144: return \"call %0\;nop\"; ! 2145: }") ! 2146: ! 2147: (define_peephole ! 2148: [(set (match_operand:SI 0 "register_operand" "=rf") ! 2149: (match_operand:SI 1 "single_insn_src_p" "gfG")) ! 2150: (call (match_operand:SI 2 "memory_operand" "m") ! 2151: (match_operand 3 "" "i"))] ! 2152: ;;- Don't use operand 1 for most machines. ! 2153: "! reg_mentioned_p (operands[0], operands[2])" ! 2154: "* ! 2155: { ! 2156: /* strip the MEM. */ ! 2157: operands[2] = XEXP (operands[2], 0); ! 2158: if (GET_CODE (operands[2]) == REG) ! 2159: return output_delayed_branch (\"calli %2\", operands, insn); ! 2160: return output_delayed_branch (\"call %2\", operands, insn); ! 2161: }") ! 2162: ! 2163: (define_peephole ! 2164: [(set (match_operand:SI 0 "memory_operand" "=m") ! 2165: (match_operand:SI 1 "reg_or_0_operand" "rfJ")) ! 2166: (call (match_operand:SI 2 "call_insn_operand" "m") ! 2167: (match_operand 3 "" "i"))] ! 2168: ;;- Don't use operand 1 for most machines. ! 2169: "" ! 2170: "* ! 2171: { ! 2172: /* strip the MEM. */ ! 2173: operands[2] = XEXP (operands[2], 0); ! 2174: if (GET_CODE (operands[2]) == REG) ! 2175: return output_delayed_branch (\"calli %2\", operands, insn); ! 2176: return output_delayed_branch (\"call %2\", operands, insn); ! 2177: }") ! 2178: ! 2179: (define_expand "call_value" ! 2180: [(set (match_operand 0 "register_operand" "=rf") ! 2181: (call (match_operand:SI 1 "memory_operand" "m") ! 2182: (match_operand 2 "" "i")))] ! 2183: ;; operand 3 is next_arg_register ! 2184: "" ! 2185: " ! 2186: { ! 2187: /* Make sure the address is just one reg and will stay that way. */ ! 2188: if (! call_insn_operand (operands[1], QImode)) ! 2189: operands[1] ! 2190: = change_address (operands[1], VOIDmode, ! 2191: copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); ! 2192: if (INTVAL (operands[2]) > 0) ! 2193: { ! 2194: emit_move_insn (arg_pointer_rtx, stack_pointer_rtx); ! 2195: emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx)); ! 2196: } ! 2197: }") ! 2198: ! 2199: (define_insn "" ! 2200: [(set (match_operand 0 "register_operand" "=rf") ! 2201: (call (match_operand:SI 1 "call_insn_operand" "m") ! 2202: (match_operand 2 "" "i")))] ! 2203: ;; operand 3 is next_arg_register ! 2204: "" ! 2205: "* ! 2206: { ! 2207: /* strip the MEM. */ ! 2208: operands[1] = XEXP (operands[1], 0); ! 2209: CC_STATUS_INIT; ! 2210: if (GET_CODE (operands[1]) == REG) ! 2211: return \"calli %1\;nop\"; ! 2212: return \"call %1\;nop\"; ! 2213: }") ! 2214: ! 2215: (define_peephole ! 2216: [(set (match_operand:SI 0 "register_operand" "=rf") ! 2217: (match_operand:SI 1 "single_insn_src_p" "gfG")) ! 2218: (set (match_operand 2 "" "=rf") ! 2219: (call (match_operand:SI 3 "call_insn_operand" "m") ! 2220: (match_operand 4 "" "i")))] ! 2221: ;;- Don't use operand 4 for most machines. ! 2222: "! reg_mentioned_p (operands[0], operands[3])" ! 2223: "* ! 2224: { ! 2225: /* strip the MEM. */ ! 2226: operands[3] = XEXP (operands[3], 0); ! 2227: if (GET_CODE (operands[3]) == REG) ! 2228: return output_delayed_branch (\"calli %3\", operands, insn); ! 2229: return output_delayed_branch (\"call %3\", operands, insn); ! 2230: }") ! 2231: ! 2232: (define_peephole ! 2233: [(set (match_operand:SI 0 "memory_operand" "=m") ! 2234: (match_operand:SI 1 "reg_or_0_operand" "rJf")) ! 2235: (set (match_operand 2 "" "=rf") ! 2236: (call (match_operand:SI 3 "call_insn_operand" "m") ! 2237: (match_operand 4 "" "i")))] ! 2238: ;;- Don't use operand 4 for most machines. ! 2239: "" ! 2240: "* ! 2241: { ! 2242: /* strip the MEM. */ ! 2243: operands[3] = XEXP (operands[3], 0); ! 2244: if (GET_CODE (operands[3]) == REG) ! 2245: return output_delayed_branch (\"calli %3\", operands, insn); ! 2246: return output_delayed_branch (\"call %3\", operands, insn); ! 2247: }") ! 2248: ! 2249: ;; Call subroutine returning any type. ! 2250: ! 2251: (define_expand "untyped_call" ! 2252: [(parallel [(call (match_operand 0 "" "") ! 2253: (const_int 0)) ! 2254: (match_operand 1 "" "") ! 2255: (match_operand 2 "" "")])] ! 2256: "" ! 2257: " ! 2258: { ! 2259: int i; ! 2260: ! 2261: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); ! 2262: ! 2263: for (i = 0; i < XVECLEN (operands[2], 0); i++) ! 2264: { ! 2265: rtx set = XVECEXP (operands[2], 0, i); ! 2266: emit_move_insn (SET_DEST (set), SET_SRC (set)); ! 2267: } ! 2268: ! 2269: /* The optimizer does not know that the call sets the function value ! 2270: registers we stored in the result block. We avoid problems by ! 2271: claiming that all hard registers are used and clobbered at this ! 2272: point. */ ! 2273: emit_insn (gen_blockage ()); ! 2274: ! 2275: DONE; ! 2276: }") ! 2277: ! 2278: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ! 2279: ;; all of memory. This blocks insns from being moved across this point. ! 2280: ! 2281: (define_insn "blockage" ! 2282: [(unspec_volatile [(const_int 0)] 0)] ! 2283: "" ! 2284: "") ! 2285: ! 2286: (define_insn "nop" ! 2287: [(const_int 0)] ! 2288: "" ! 2289: "nop") ! 2290: ! 2291: (define_insn "indirect_jump" ! 2292: [(set (pc) (match_operand:SI 0 "register_operand" "r"))] ! 2293: "" ! 2294: "bri %0") ! 2295: ! 2296: ;; ! 2297: ;; A special insn that does the work to get setup just ! 2298: ;; before a table jump. ! 2299: ;; ! 2300: (define_insn "" ! 2301: [(set (match_operand:SI 0 "register_operand" "=r") ! 2302: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") ! 2303: (label_ref (match_operand 2 "" "")))))] ! 2304: "" ! 2305: "* ! 2306: { ! 2307: CC_STATUS_INIT; ! 2308: return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\"; ! 2309: }") ! 2310: ! 2311: (define_peephole ! 2312: [(set (match_operand:SI 0 "register_operand" "=rf") ! 2313: (match_operand:SI 1 "single_insn_src_p" "gfG")) ! 2314: (set (pc) (match_operand:SI 2 "register_operand" "r")) ! 2315: (use (label_ref (match_operand 3 "" "")))] ! 2316: "REGNO (operands[0]) != REGNO (operands[2])" ! 2317: "* return output_delayed_branch (\"bri %2\", operands, insn);")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.