|
|
1.1 ! root 1: ;;- Machine description for SPARC chip for GNU C compiler ! 2: ;; Copyright (C) 1988, 1989 Free Software Foundation, Inc. ! 3: ;; Contributed by Michael Tiemann ([email protected]) ! 4: ! 5: ;; This file is part of GNU CC. ! 6: ! 7: ;; GNU CC is free software; you can redistribute it and/or modify ! 8: ;; it under the terms of the GNU General Public License as published by ! 9: ;; the Free Software Foundation; either version 1, or (at your option) ! 10: ;; any later version. ! 11: ! 12: ;; GNU CC is distributed in the hope that it will be useful, ! 13: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: ;; GNU General Public License for more details. ! 16: ! 17: ;; You should have received a copy of the GNU General Public License ! 18: ;; along with GNU CC; see the file COPYING. If not, write to ! 19: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 20: ! 21: ! 22: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 23: ! 24: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ! 25: ;;- updates for most instructions. ! 26: ! 27: ;;- Operand classes for the register allocator: ! 28: ! 29: ;; Compare instructions. ! 30: ;; This controls RTL generation and register allocation. ! 31: ! 32: ;; Put cmpsi first among compare insns so it matches two CONST_INT operands. ! 33: ! 34: (define_insn "cmpsi" ! 35: [(set (cc0) ! 36: (compare (match_operand:SI 0 "arith_operand" "r,rI") ! 37: (match_operand:SI 1 "arith_operand" "I,r")))] ! 38: "" ! 39: "* ! 40: { ! 41: if (! REG_P (operands[0])) ! 42: { ! 43: cc_status.flags |= CC_REVERSED; ! 44: return \"cmp %1,%0\"; ! 45: } ! 46: return \"cmp %0,%1\"; ! 47: }") ! 48: ! 49: (define_expand "cmpdf" ! 50: [(set (cc0) ! 51: (compare (match_operand:DF 0 "nonmemory_operand" "f,fG") ! 52: (match_operand:DF 1 "nonmemory_operand" "G,f")))] ! 53: "" ! 54: "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, DFmode, 32)));") ! 55: ! 56: (define_insn "" ! 57: [(set (cc0) ! 58: (compare (match_operand:DF 0 "nonmemory_operand" "f,fG") ! 59: (match_operand:DF 1 "nonmemory_operand" "G,f")))] ! 60: "" ! 61: "* ! 62: { ! 63: if (GET_CODE (operands[0]) == CONST_DOUBLE ! 64: || GET_CODE (operands[1]) == CONST_DOUBLE) ! 65: make_f0_contain_0 (2); ! 66: ! 67: cc_status.flags |= CC_IN_FCCR; ! 68: if (GET_CODE (operands[0]) == CONST_DOUBLE) ! 69: return \"fcmped %%f0,%1\;nop\"; ! 70: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 71: return \"fcmped %0,%%f0\;nop\"; ! 72: return \"fcmped %0,%1\;nop\"; ! 73: }") ! 74: ! 75: (define_expand "cmpsf" ! 76: [(set (cc0) ! 77: (compare (match_operand:SF 0 "nonmemory_operand" "f,fG") ! 78: (match_operand:SF 1 "nonmemory_operand" "G,f")))] ! 79: "" ! 80: "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SFmode, 32)));") ! 81: ! 82: (define_insn "" ! 83: [(set (cc0) ! 84: (compare (match_operand:SF 0 "nonmemory_operand" "f,fG") ! 85: (match_operand:SF 1 "nonmemory_operand" "G,f")))] ! 86: "" ! 87: "* ! 88: { ! 89: if (GET_CODE (operands[0]) == CONST_DOUBLE ! 90: || GET_CODE (operands[1]) == CONST_DOUBLE) ! 91: make_f0_contain_0 (1); ! 92: ! 93: cc_status.flags |= CC_IN_FCCR; ! 94: if (GET_CODE (operands[0]) == CONST_DOUBLE) ! 95: return \"fcmpes %%f0,%1\;nop\"; ! 96: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 97: return \"fcmpes %0,%%f0\;nop\"; ! 98: return \"fcmpes %0,%1\;nop\"; ! 99: }") ! 100: ! 101: ;; Put tstsi first among test insns so it matches a CONST_INT operand. ! 102: ! 103: (define_insn "tstsi" ! 104: [(set (cc0) ! 105: (match_operand:SI 0 "register_operand" "r"))] ! 106: "" ! 107: "tst %0") ! 108: ! 109: ;; Need this to take a general operand because cse can make ! 110: ;; a CONST which won't be in a register. ! 111: (define_insn "" ! 112: [(set (cc0) ! 113: (match_operand:SI 0 "immediate_operand" "i"))] ! 114: "" ! 115: "set %0,%%g1\;tst %%g1") ! 116: ! 117: ;; Optimize the case of following a reg-reg move with a test ! 118: ;; of reg just moved. ! 119: ! 120: (define_peephole ! 121: [(set (match_operand:SI 0 "register_operand" "=r") ! 122: (match_operand:SI 1 "register_operand" "r")) ! 123: (set (cc0) (match_operand:SI 2 "register_operand" "r"))] ! 124: "operands[2] == operands[0] ! 125: || operands[2] == operands[1]" ! 126: "orcc %1,%%g0,%0 ! 2-insn combine") ! 127: ! 128: ;; Optimize 5(6) insn sequence to 3(4) insns. ! 129: ;; These patterns could also optimize more complicated sets ! 130: ;; before conditional branches. ! 131: ! 132: ;; Turned off because (1) this case is rarely encounted ! 133: ;; (2) to be correct, more conditions must be checked ! 134: ;; (3) the conditions must be checked with rtx_equal_p, not == ! 135: ;; (4) when branch scheduling is added to the compiler, ! 136: ;; this optimization will be performed by the branch scheduler ! 137: ;; Bottom line: it is not worth the trouble of fixing or ! 138: ;; maintaining it. ! 139: ! 140: ;(define_peephole ! 141: ; [(set (match_operand:SI 0 "register_operand" "=r") ! 142: ; (match_operand:SI 1 "general_operand" "g")) ! 143: ; (set (match_operand:SI 2 "register_operand" "=r") ! 144: ; (match_operand:SI 3 "reg_or_0_operand" "rJ")) ! 145: ; (set (cc0) (match_operand:SI 4 "register_operand" "r")) ! 146: ; (set (pc) (match_operand 5 "" ""))] ! 147: ; "GET_CODE (operands[5]) == IF_THEN_ELSE ! 148: ; && operands[0] != operands[3] ! 149: ; && ! reg_mentioned_p (operands[2], operands[1]) ! 150: ; && (operands[4] == operands[0] ! 151: ; || operands[4] == operands[2] ! 152: ; || operands[4] == operands[3])" ! 153: ; "* ! 154: ;{ ! 155: ; rtx xoperands[2]; ! 156: ; int parity; ! 157: ; xoperands[0] = XEXP (operands[5], 0); ! 158: ; if (GET_CODE (XEXP (operands[5], 1)) == PC) ! 159: ; { ! 160: ; parity = 1; ! 161: ; xoperands[1] = XEXP (XEXP (operands[5], 2), 0); ! 162: ; } ! 163: ; else ! 164: ; { ! 165: ; parity = 0; ! 166: ; xoperands[1] = XEXP (XEXP (operands[5], 1), 0); ! 167: ; } ! 168: ; ! 169: ; if (operands[4] == operands[0]) ! 170: ; { ! 171: ; /* Although the constraints for operands[1] permit a general ! 172: ; operand (and hence possibly a const_int), we know that ! 173: ; in this branch it cannot be a CONST_INT, since that would give ! 174: ; us a fixed condition, and those should have been optimized away. */ ! 175: ; if (REG_P (operands[1])) ! 176: ; output_asm_insn (\"orcc %1,%%g0,%0 ! 3-insn reorder\", operands); ! 177: ; else if (GET_CODE (operands[1]) != MEM) ! 178: ; abort (); ! 179: ; else ! 180: ; { ! 181: ; if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 182: ; output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;tst %0 ! 4-insn reorder\", operands); ! 183: ; else ! 184: ; output_asm_insn (\"ld %1,%0\;tst %0 ! 3.5-insn reorder\", operands); ! 185: ; } ! 186: ; XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 2); ! 187: ; XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 3); ! 188: ; } ! 189: ; else ! 190: ; { ! 191: ; output_asm_insn (\"orcc %3,%%g0,%2 ! 3-insn reorder\", operands); ! 192: ; } ! 193: ; if (parity) ! 194: ; return output_delayed_branch (\"b%N0 %l1\", xoperands, insn); ! 195: ; else ! 196: ; return output_delayed_branch (\"b%C0 %l1\", xoperands, insn); ! 197: ;}") ! 198: ! 199: ;; By default, operations don't set the condition codes. ! 200: ;; These patterns allow cc's to be set, while doing some work ! 201: ! 202: (define_insn "" ! 203: [(set (cc0) ! 204: (zero_extend:SI (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)))] ! 205: "" ! 206: "andcc %0,0xff,%%g0") ! 207: ! 208: (define_insn "" ! 209: [(set (cc0) ! 210: (plus:SI (match_operand:SI 0 "register_operand" "r%") ! 211: (match_operand:SI 1 "arith_operand" "rI")))] ! 212: "" ! 213: "addcc %0,%1,%%g0") ! 214: ! 215: (define_insn "" ! 216: [(set (cc0) ! 217: (plus:SI (match_operand:SI 0 "register_operand" "r%") ! 218: (match_operand:SI 1 "arith_operand" "rI"))) ! 219: (set (match_operand:SI 2 "register_operand" "=r") ! 220: (plus:SI (match_dup 0) (match_dup 1)))] ! 221: "" ! 222: "addcc %0,%1,%2") ! 223: ! 224: (define_insn "" ! 225: [(set (cc0) ! 226: (minus:SI (match_operand:SI 0 "register_operand" "r") ! 227: (match_operand:SI 1 "arith_operand" "rI"))) ! 228: (set (match_operand:SI 2 "register_operand" "=r") ! 229: (minus:SI (match_dup 0) (match_dup 1)))] ! 230: "" ! 231: "subcc %0,%1,%2") ! 232: ! 233: (define_insn "" ! 234: [(set (cc0) ! 235: (and:SI (match_operand:SI 0 "register_operand" "r%") ! 236: (match_operand:SI 1 "arith_operand" "rI")))] ! 237: "" ! 238: "andcc %0,%1,%%g0") ! 239: ! 240: (define_insn "" ! 241: [(set (cc0) ! 242: (and:SI (match_operand:SI 0 "register_operand" "r%") ! 243: (match_operand:SI 1 "arith_operand" "rI"))) ! 244: (set (match_operand:SI 2 "register_operand" "=r") ! 245: (and:SI (match_dup 0) (match_dup 1)))] ! 246: "" ! 247: "andcc %0,%1,%2") ! 248: ! 249: (define_insn "" ! 250: [(set (cc0) ! 251: (and:SI (match_operand:SI 0 "register_operand" "r%") ! 252: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))] ! 253: "" ! 254: "andncc %0,%1,%%g0") ! 255: ! 256: (define_insn "" ! 257: [(set (cc0) ! 258: (and:SI (match_operand:SI 0 "register_operand" "r%") ! 259: (not:SI (match_operand:SI 1 "arith_operand" "rI")))) ! 260: (set (match_operand:SI 2 "register_operand" "=r") ! 261: (and:SI (match_dup 0) (not:SI (match_dup 1))))] ! 262: "" ! 263: "andncc %0,%1,%2") ! 264: ! 265: (define_insn "" ! 266: [(set (cc0) ! 267: (ior:SI (match_operand:SI 0 "register_operand" "r%") ! 268: (match_operand:SI 1 "arith_operand" "rI")))] ! 269: "" ! 270: "orcc %0,%1,%%g0") ! 271: ! 272: (define_insn "" ! 273: [(set (cc0) ! 274: (ior:SI (match_operand:SI 0 "register_operand" "r%") ! 275: (match_operand:SI 1 "arith_operand" "rI"))) ! 276: (set (match_operand:SI 2 "register_operand" "=r") ! 277: (ior:SI (match_dup 0) (match_dup 1)))] ! 278: "" ! 279: "orcc %0,%1,%2") ! 280: ! 281: (define_insn "" ! 282: [(set (cc0) ! 283: (ior:SI (match_operand:SI 0 "register_operand" "r%") ! 284: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))] ! 285: "" ! 286: "orncc %0,%1,%%g0") ! 287: ! 288: (define_insn "" ! 289: [(set (cc0) ! 290: (ior:SI (match_operand:SI 0 "register_operand" "r%") ! 291: (not:SI (match_operand:SI 1 "arith_operand" "rI")))) ! 292: (set (match_operand:SI 2 "register_operand" "=r") ! 293: (ior:SI (match_dup 0) (not:SI (match_dup 1))))] ! 294: "" ! 295: "orncc %0,%1,%2") ! 296: ! 297: (define_insn "" ! 298: [(set (cc0) ! 299: (xor:SI (match_operand:SI 0 "register_operand" "r%") ! 300: (match_operand:SI 1 "arith_operand" "rI")))] ! 301: "" ! 302: "xorcc %0,%1,%%g0") ! 303: ! 304: (define_insn "" ! 305: [(set (cc0) ! 306: (xor:SI (match_operand:SI 0 "register_operand" "r%") ! 307: (match_operand:SI 1 "arith_operand" "rI"))) ! 308: (set (match_operand:SI 2 "register_operand" "=r") ! 309: (xor:SI (match_dup 0) (match_dup 1)))] ! 310: "" ! 311: "xorcc %0,%1,%2") ! 312: ! 313: (define_insn "" ! 314: [(set (cc0) ! 315: (xor:SI (match_operand:SI 0 "register_operand" "r%") ! 316: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))] ! 317: "" ! 318: "xnorcc %0,%1,%%g0") ! 319: ! 320: (define_insn "" ! 321: [(set (cc0) ! 322: (xor:SI (match_operand:SI 0 "register_operand" "r%") ! 323: (not:SI (match_operand:SI 1 "arith_operand" "rI")))) ! 324: (set (match_operand:SI 2 "register_operand" "=r") ! 325: (xor:SI (match_dup 0) (not:SI (match_dup 1))))] ! 326: "" ! 327: "xnorcc %0,%1,%2") ! 328: ! 329: (define_expand "tstdf" ! 330: [(set (cc0) ! 331: (match_operand:DF 0 "register_operand" "f"))] ! 332: "" ! 333: "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, DFmode, 32)));") ! 334: ! 335: (define_insn "" ! 336: [(set (cc0) ! 337: (match_operand:DF 0 "register_operand" "f"))] ! 338: "" ! 339: "* ! 340: { ! 341: make_f0_contain_0 (2); ! 342: cc_status.flags |= CC_IN_FCCR; ! 343: return \"fcmped %0,%%f0\;nop\"; ! 344: }") ! 345: ! 346: (define_expand "tstsf" ! 347: [(set (cc0) ! 348: (match_operand:SF 0 "register_operand" "f"))] ! 349: "" ! 350: "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SFmode, 32)));") ! 351: ! 352: (define_insn "" ! 353: [(set (cc0) ! 354: (match_operand:SF 0 "register_operand" "f"))] ! 355: "" ! 356: "* ! 357: { ! 358: make_f0_contain_0 (1); ! 359: cc_status.flags |= CC_IN_FCCR; ! 360: return \"fcmpes %0,%%f0\;nop\"; ! 361: }") ! 362: ! 363: ;; There are no logical links for the condition codes. This ! 364: ;; would not normally be a problem, but on the SPARC (and possibly ! 365: ;; other RISC machines), when argument passing, the insn which sets ! 366: ;; the condition code and the insn which uses the set condition code ! 367: ;; may not be performed adjacently (due to optimizations performed ! 368: ;; in combine.c). To make up for this, we emit insn patterns which ! 369: ;; cannot possibly be rearranged on us. ! 370: (define_expand "seq" ! 371: [(set (match_operand:SI 0 "general_operand" "=r") ! 372: (eq (cc0) (const_int 0)))] ! 373: "" ! 374: "gen_scc_insn (EQ, VOIDmode, operands); DONE;") ! 375: ! 376: (define_expand "sne" ! 377: [(set (match_operand:SI 0 "general_operand" "=r") ! 378: (ne (cc0) (const_int 0)))] ! 379: "" ! 380: "gen_scc_insn (NE, VOIDmode, operands); DONE;") ! 381: ! 382: (define_insn "" ! 383: [(set (match_operand:SI 0 "general_operand" "=r,r") ! 384: (match_operator 1 "eq_or_neq" ! 385: [(compare (match_operand:SI 2 "general_operand" "r,rI") ! 386: (match_operand:SI 3 "general_operand" "I,r")) ! 387: (const_int 0)]))] ! 388: "" ! 389: "* ! 390: { ! 391: CC_STATUS_INIT; ! 392: cc_status.value1 = operands[0]; ! 393: if (! REG_P (operands[2])) ! 394: { ! 395: output_asm_insn (\"cmp %3,%2\", operands); ! 396: cc_status.flags |= CC_REVERSED; ! 397: } ! 398: else ! 399: output_asm_insn (\"cmp %2,%3\", operands); ! 400: return output_scc_insn (GET_CODE (operands[1]), operands[0]); ! 401: }") ! 402: ! 403: (define_insn "" ! 404: [(set (match_operand:SI 0 "general_operand" "=r") ! 405: (match_operator 1 "eq_or_neq" ! 406: [(match_operand:SI 2 "general_operand" "r") ! 407: (const_int 0)]))] ! 408: "" ! 409: "* ! 410: { ! 411: CC_STATUS_INIT; ! 412: cc_status.value1 = operands[0]; ! 413: output_asm_insn (\"tst %2\", operands); ! 414: return output_scc_insn (GET_CODE (operands[1]), operands[0]); ! 415: }") ! 416: ! 417: (define_insn "" ! 418: [(set (match_operand:SI 0 "general_operand" "=r,r") ! 419: (match_operator 1 "eq_or_neq" ! 420: [(compare (match_operand:DF 2 "general_operand" "f,fG") ! 421: (match_operand:DF 3 "general_operand" "G,f")) ! 422: (const_int 0)]))] ! 423: "" ! 424: "* ! 425: { ! 426: CC_STATUS_INIT; ! 427: cc_status.value1 = operands[0]; ! 428: cc_status.flags |= CC_IN_FCCR; ! 429: ! 430: if (GET_CODE (operands[2]) == CONST_DOUBLE ! 431: || GET_CODE (operands[3]) == CONST_DOUBLE) ! 432: make_f0_contain_0 (2); ! 433: ! 434: if (GET_CODE (operands[2]) == CONST_DOUBLE) ! 435: output_asm_insn (\"fcmped %%f0,%3\;nop\", operands); ! 436: else if (GET_CODE (operands[3]) == CONST_DOUBLE) ! 437: output_asm_insn (\"fcmped %2,%%f0\;nop\", operands); ! 438: else output_asm_insn (\"fcmped %2,%3\;nop\", operands); ! 439: return output_scc_insn (GET_CODE (operands[1]), operands[0]); ! 440: }") ! 441: ! 442: (define_insn "" ! 443: [(set (match_operand:SI 0 "general_operand" "=r") ! 444: (match_operator 1 "eq_or_neq" ! 445: [(match_operand:DF 2 "general_operand" "f") ! 446: (const_int 0)]))] ! 447: "" ! 448: "* ! 449: { ! 450: CC_STATUS_INIT; ! 451: cc_status.value1 = operands[0]; ! 452: cc_status.flags |= CC_IN_FCCR; ! 453: ! 454: make_f0_contain_0 (2); ! 455: output_asm_insn (\"fcmped %2,%%f0\;nop\", operands); ! 456: return output_scc_insn (GET_CODE (operands[1]), operands[0]); ! 457: }") ! 458: ! 459: (define_insn "" ! 460: [(set (match_operand:SI 0 "general_operand" "=r,r") ! 461: (match_operator 1 "eq_or_neq" ! 462: [(compare (match_operand:SF 2 "general_operand" "f,fG") ! 463: (match_operand:SF 3 "general_operand" "G,f")) ! 464: (const_int 0)]))] ! 465: "" ! 466: "* ! 467: { ! 468: CC_STATUS_INIT; ! 469: cc_status.value1 = operands[0]; ! 470: cc_status.flags |= CC_IN_FCCR; ! 471: ! 472: if (GET_CODE (operands[2]) == CONST_DOUBLE ! 473: || GET_CODE (operands[3]) == CONST_DOUBLE) ! 474: make_f0_contain_0 (1); ! 475: ! 476: if (GET_CODE (operands[2]) == CONST_DOUBLE) ! 477: output_asm_insn (\"fcmpes %%f0,%3\;nop\", operands); ! 478: else if (GET_CODE (operands[3]) == CONST_DOUBLE) ! 479: output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands); ! 480: else output_asm_insn (\"fcmpes %2,%3\;nop\", operands); ! 481: return output_scc_insn (GET_CODE (operands[1]), operands[0]); ! 482: }") ! 483: ! 484: (define_insn "" ! 485: [(set (match_operand:SI 0 "general_operand" "=r") ! 486: (match_operator 1 "eq_or_neq" ! 487: [(match_operand:SF 2 "general_operand" "f") ! 488: (const_int 0)]))] ! 489: "" ! 490: "* ! 491: { ! 492: CC_STATUS_INIT; ! 493: cc_status.value1 = operands[0]; ! 494: cc_status.flags |= CC_IN_FCCR; ! 495: ! 496: make_f0_contain_0 (1); ! 497: output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands); ! 498: return output_scc_insn (GET_CODE (operands[1]), operands[0]); ! 499: }") ! 500: ! 501: ;; These control RTL generation for conditional jump insns ! 502: ;; and match them for register allocation. ! 503: ! 504: (define_insn "beq" ! 505: [(set (pc) ! 506: (if_then_else (eq (cc0) ! 507: (const_int 0)) ! 508: (label_ref (match_operand 0 "" "")) ! 509: (pc)))] ! 510: "" ! 511: "* ! 512: { ! 513: if (cc_prev_status.flags & CC_IN_FCCR) ! 514: return \"fbe %l0\;nop\"; ! 515: return \"be %l0\;nop\"; ! 516: }") ! 517: ! 518: (define_insn "bne" ! 519: [(set (pc) ! 520: (if_then_else (ne (cc0) ! 521: (const_int 0)) ! 522: (label_ref (match_operand 0 "" "")) ! 523: (pc)))] ! 524: "" ! 525: "* ! 526: { ! 527: if (cc_prev_status.flags & CC_IN_FCCR) ! 528: return \"fbne %l0\;nop\"; ! 529: return \"bne %l0\;nop\"; ! 530: }") ! 531: ! 532: (define_insn "bgt" ! 533: [(set (pc) ! 534: (if_then_else (gt (cc0) ! 535: (const_int 0)) ! 536: (label_ref (match_operand 0 "" "")) ! 537: (pc)))] ! 538: "" ! 539: "* ! 540: { ! 541: if (cc_prev_status.flags & CC_IN_FCCR) ! 542: return \"fbg %l0\;nop\"; ! 543: return \"bg %l0\;nop\"; ! 544: }") ! 545: ! 546: (define_insn "bgtu" ! 547: [(set (pc) ! 548: (if_then_else (gtu (cc0) ! 549: (const_int 0)) ! 550: (label_ref (match_operand 0 "" "")) ! 551: (pc)))] ! 552: "" ! 553: "* ! 554: { ! 555: if (cc_prev_status.flags & CC_IN_FCCR) ! 556: abort (); ! 557: return \"bgu %l0\;nop\"; ! 558: }") ! 559: ! 560: (define_insn "blt" ! 561: [(set (pc) ! 562: (if_then_else (lt (cc0) ! 563: (const_int 0)) ! 564: (label_ref (match_operand 0 "" "")) ! 565: (pc)))] ! 566: "" ! 567: "* ! 568: { ! 569: if (cc_prev_status.flags & CC_IN_FCCR) ! 570: return \"fbl %l0\;nop\"; ! 571: return \"bl %l0\;nop\"; ! 572: }") ! 573: ! 574: (define_insn "bltu" ! 575: [(set (pc) ! 576: (if_then_else (ltu (cc0) ! 577: (const_int 0)) ! 578: (label_ref (match_operand 0 "" "")) ! 579: (pc)))] ! 580: "" ! 581: "* ! 582: { ! 583: if (cc_prev_status.flags & CC_IN_FCCR) ! 584: abort (); ! 585: return \"blu %l0\;nop\"; ! 586: }") ! 587: ! 588: (define_insn "bge" ! 589: [(set (pc) ! 590: (if_then_else (ge (cc0) ! 591: (const_int 0)) ! 592: (label_ref (match_operand 0 "" "")) ! 593: (pc)))] ! 594: "" ! 595: "* ! 596: { ! 597: if (cc_prev_status.flags & CC_IN_FCCR) ! 598: return \"fbge %l0\;nop\"; ! 599: return \"bge %l0\;nop\"; ! 600: }") ! 601: ! 602: (define_insn "bgeu" ! 603: [(set (pc) ! 604: (if_then_else (geu (cc0) ! 605: (const_int 0)) ! 606: (label_ref (match_operand 0 "" "")) ! 607: (pc)))] ! 608: "" ! 609: "* ! 610: { ! 611: if (cc_prev_status.flags & CC_IN_FCCR) ! 612: abort (); ! 613: return \"bgeu %l0\;nop\"; ! 614: }") ! 615: ! 616: (define_insn "ble" ! 617: [(set (pc) ! 618: (if_then_else (le (cc0) ! 619: (const_int 0)) ! 620: (label_ref (match_operand 0 "" "")) ! 621: (pc)))] ! 622: "" ! 623: "* ! 624: { ! 625: if (cc_prev_status.flags & CC_IN_FCCR) ! 626: return \"fble %l0\;nop\"; ! 627: return \"ble %l0\;nop\"; ! 628: }") ! 629: ! 630: (define_insn "bleu" ! 631: [(set (pc) ! 632: (if_then_else (leu (cc0) ! 633: (const_int 0)) ! 634: (label_ref (match_operand 0 "" "")) ! 635: (pc)))] ! 636: "" ! 637: "* ! 638: { ! 639: if (cc_prev_status.flags & CC_IN_FCCR) ! 640: abort (); ! 641: return \"bleu %l0\;nop\"; ! 642: }") ! 643: ! 644: ;; This matches inverted jump insns for register allocation. ! 645: ! 646: (define_insn "" ! 647: [(set (pc) ! 648: (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)]) ! 649: (pc) ! 650: (label_ref (match_operand 1 "" ""))))] ! 651: "" ! 652: "* ! 653: { ! 654: if (cc_prev_status.flags & CC_IN_FCCR) ! 655: return \"fb%F0 %l1\;nop\"; ! 656: return \"b%N0 %l1\;nop\"; ! 657: }") ! 658: ! 659: ;; Move instructions ! 660: ! 661: (define_insn "swapsi" ! 662: [(set (match_operand:SI 0 "general_operand" "r,rm") ! 663: (match_operand:SI 1 "general_operand" "m,r")) ! 664: (set (match_dup 1) (match_dup 0))] ! 665: "" ! 666: "* ! 667: { ! 668: if (GET_CODE (operands[1]) == MEM) ! 669: { ! 670: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 671: output_asm_insn (\"set %a1,%%g1\", operands), ! 672: operands[1] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 1)), ! 673: cc_status.flags &= ~CC_KNOW_HI_G1; ! 674: output_asm_insn (\"swap %1,%0\", operands); ! 675: } ! 676: if (REG_P (operands[0])) ! 677: { ! 678: if (REGNO (operands[0]) == REGNO (operands[1])) ! 679: return \"\"; ! 680: return \"xor %0,%1,%0\;xor %1,%0,%1\;xor %0,%1,%0\"; ! 681: } ! 682: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 683: { ! 684: output_asm_insn (\"set %a0,%%g1\", operands); ! 685: operands[0] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 1)); ! 686: cc_status.flags &= ~CC_KNOW_HI_G1; ! 687: } ! 688: return \"swap %0,%1\"; ! 689: }") ! 690: ! 691: (define_insn "movsi" ! 692: [(set (match_operand:SI 0 "general_operand" "=r,m") ! 693: (match_operand:SI 1 "general_operand" "rmif,rJ"))] ! 694: "" ! 695: "* ! 696: { ! 697: if (GET_CODE (operands[0]) == MEM) ! 698: { ! 699: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 700: return output_store (operands); ! 701: return \"st %r1,%0\"; ! 702: } ! 703: if (GET_CODE (operands[1]) == MEM) ! 704: { ! 705: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 706: return output_load_fixed (operands); ! 707: return \"ld %1,%0\"; ! 708: } ! 709: if (FP_REG_P (operands[1])) ! 710: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\"; ! 711: if (REG_P (operands[1]) ! 712: || (GET_CODE (operands[1]) == CONST_INT ! 713: && SMALL_INT (operands[1]))) ! 714: return \"mov %1,%0\"; ! 715: if (GET_CODE (operands[1]) == CONST_INT ! 716: && (INTVAL (operands[1]) & 0x3ff) == 0) ! 717: return \"sethi %%hi(%1),%0\"; ! 718: return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\"; ! 719: }") ! 720: ! 721: (define_insn "movhi" ! 722: [(set (match_operand:HI 0 "general_operand" "=r,m") ! 723: (match_operand:HI 1 "general_operand" "rmi,rJ"))] ! 724: "" ! 725: "* ! 726: { ! 727: if (GET_CODE (operands[0]) == MEM) ! 728: { ! 729: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 730: return output_store (operands); ! 731: return \"sth %r1,%0\"; ! 732: } ! 733: if (GET_CODE (operands[1]) == MEM) ! 734: { ! 735: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 736: return output_load_fixed (operands); ! 737: return \"ldsh %1,%0\"; ! 738: } ! 739: if (REG_P (operands[1]) ! 740: || (GET_CODE (operands[1]) == CONST_INT ! 741: && SMALL_INT (operands[1]))) ! 742: return \"mov %1,%0\"; ! 743: return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\"; ! 744: }") ! 745: ! 746: (define_insn "movqi" ! 747: [(set (match_operand:QI 0 "general_operand" "=r,m") ! 748: (match_operand:QI 1 "general_operand" "rmi,rJ"))] ! 749: "" ! 750: "* ! 751: { ! 752: if (GET_CODE (operands[0]) == MEM) ! 753: { ! 754: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 755: return output_store (operands); ! 756: return \"stb %r1,%0\"; ! 757: } ! 758: if (GET_CODE (operands[1]) == MEM) ! 759: { ! 760: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 761: return output_load_fixed (operands); ! 762: return \"ldsb %1,%0\"; ! 763: } ! 764: if (REG_P (operands[1]) ! 765: || (GET_CODE (operands[1]) == CONST_INT ! 766: && SMALL_INT (operands[1]))) ! 767: return \"mov %1,%0\"; ! 768: return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\"; ! 769: }") ! 770: ! 771: ;; The definition of this insn does not really explain what it does, ! 772: ;; but it should suffice ! 773: ;; that anything generated as this insn will be recognized as one ! 774: ;; and that it won't successfully combine with anything. ! 775: (define_expand "movstrsi" ! 776: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) ! 777: (mem:BLK (match_operand:BLK 1 "general_operand" ""))) ! 778: (use (match_operand:SI 2 "arith32_operand" "")) ! 779: (use (match_operand:SI 3 "immediate_operand" "")) ! 780: (clobber (match_dup 4)) ! 781: (clobber (match_dup 0)) ! 782: (clobber (match_dup 1))])] ! 783: "" ! 784: " ! 785: { ! 786: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); ! 787: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); ! 788: operands[4] = gen_reg_rtx (SImode); ! 789: }") ! 790: ! 791: (define_insn "" ! 792: [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ! 793: (mem:BLK (match_operand:SI 1 "register_operand" "r"))) ! 794: (use (match_operand:SI 2 "arith32_operand" "rn")) ! 795: (use (match_operand:SI 3 "immediate_operand" "i")) ! 796: (clobber (match_operand:SI 4 "register_operand" "=r")) ! 797: (clobber (match_operand:SI 5 "register_operand" "=0")) ! 798: (clobber (match_operand:SI 6 "register_operand" "=1"))] ! 799: "" ! 800: "* return output_block_move (operands);") ! 801: ! 802: ;; Floating point move insns ! 803: ! 804: ;; This pattern forces (set (reg:DF ...) (const_double ...)) ! 805: ;; to be reloaded by putting the constant into memory. ! 806: ;; It must come before the more general movdf pattern. ! 807: (define_insn "" ! 808: [(set (match_operand:DF 0 "general_operand" "=r,f,o") ! 809: (match_operand:DF 1 "" "mG,m,G"))] ! 810: "GET_CODE (operands[1]) == CONST_DOUBLE" ! 811: "* ! 812: { ! 813: if (FP_REG_P (operands[0])) ! 814: return output_fp_move_double (operands); ! 815: if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == REG) ! 816: { ! 817: operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 818: return \"mov %%g0,%0\;mov %%g0,%1\"; ! 819: } ! 820: if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM) ! 821: { ! 822: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 823: { ! 824: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1) ! 825: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 826: { ! 827: cc_status.flags |= CC_KNOW_HI_G1; ! 828: cc_status.mdep = XEXP (operands[0], 0); ! 829: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands); ! 830: } ! 831: return \"st %%g0,[%%g1+%%lo(%%m0)]\;st %%g0,[%%g1+%%lo(%%m0)+4]\"; ! 832: } ! 833: operands[1] = adj_offsettable_operand (operands[0], 4); ! 834: return \"st %%g0,%0\;st %%g0,%1\"; ! 835: } ! 836: return output_move_double (operands); ! 837: }") ! 838: ! 839: (define_insn "movdf" ! 840: [(set (match_operand:DF 0 "general_operand" "=rm,&r,?f,?rm") ! 841: (match_operand:DF 1 "general_operand" "r,m,rfm,f"))] ! 842: "" ! 843: "* ! 844: { ! 845: if (GET_CODE (operands[0]) == MEM ! 846: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 847: return output_store (operands); ! 848: if (GET_CODE (operands[1]) == MEM ! 849: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 850: return output_load_floating (operands); ! 851: ! 852: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! 853: return output_fp_move_double (operands); ! 854: return output_move_double (operands); ! 855: }") ! 856: ! 857: (define_insn "movdi" ! 858: [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm") ! 859: (match_operand:DI 1 "general_operand" "r,mi,rfm,f"))] ! 860: "" ! 861: "* ! 862: { ! 863: if (GET_CODE (operands[0]) == MEM ! 864: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 865: return output_store (operands); ! 866: if (GET_CODE (operands[1]) == MEM ! 867: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 868: return output_load_fixed (operands); ! 869: ! 870: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! 871: return output_fp_move_double (operands); ! 872: return output_move_double (operands); ! 873: }") ! 874: ! 875: (define_insn "movsf" ! 876: [(set (match_operand:SF 0 "general_operand" "=rf,m") ! 877: (match_operand:SF 1 "general_operand" "rfm,rf"))] ! 878: "" ! 879: "* ! 880: { ! 881: if (GET_CODE (operands[0]) == MEM ! 882: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 883: return output_store (operands); ! 884: if (GET_CODE (operands[1]) == MEM ! 885: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 886: return output_load_floating (operands); ! 887: if (FP_REG_P (operands[0])) ! 888: { ! 889: if (FP_REG_P (operands[1])) ! 890: return \"fmovs %1,%0\"; ! 891: if (GET_CODE (operands[1]) == REG) ! 892: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\"; ! 893: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 894: { ! 895: cc_status.flags |= CC_KNOW_HI_G1; ! 896: cc_status.mdep = XEXP (operands[1], 0); ! 897: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\"; ! 898: } ! 899: return \"ld %1,%0\"; ! 900: } ! 901: if (FP_REG_P (operands[1])) ! 902: { ! 903: if (GET_CODE (operands[0]) == REG) ! 904: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\"; ! 905: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 906: { ! 907: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1) ! 908: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 909: { ! 910: cc_status.flags |= CC_KNOW_HI_G1; ! 911: cc_status.mdep = XEXP (operands[0], 0); ! 912: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands); ! 913: } ! 914: return \"st %r1,[%%g1+%%lo(%m0)]\"; ! 915: } ! 916: return \"st %r1,%0\"; ! 917: } ! 918: if (GET_CODE (operands[0]) == MEM) ! 919: return \"st %r1,%0\"; ! 920: if (GET_CODE (operands[1]) == MEM) ! 921: return \"ld %1,%0\"; ! 922: return \"mov %1,%0\"; ! 923: }") ! 924: ! 925: ;;- truncation instructions ! 926: (define_insn "truncsiqi2" ! 927: [(set (match_operand:QI 0 "general_operand" "=g") ! 928: (truncate:QI ! 929: (match_operand:SI 1 "register_operand" "r")))] ! 930: "" ! 931: "* ! 932: { ! 933: if (GET_CODE (operands[0]) == MEM) ! 934: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 935: { ! 936: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1) ! 937: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 938: { ! 939: cc_status.flags |= CC_KNOW_HI_G1; ! 940: cc_status.mdep = XEXP (operands[0], 0); ! 941: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands); ! 942: } ! 943: return \"stb %1,[%%g1+%%lo(%m0)]\"; ! 944: } ! 945: else ! 946: return \"stb %1,%0\"; ! 947: return \"mov %1,%0\"; ! 948: }") ! 949: ! 950: (define_insn "trunchiqi2" ! 951: [(set (match_operand:QI 0 "general_operand" "=g") ! 952: (truncate:QI ! 953: (match_operand:HI 1 "register_operand" "r")))] ! 954: "" ! 955: "* ! 956: { ! 957: if (GET_CODE (operands[0]) == MEM) ! 958: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 959: { ! 960: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1) ! 961: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 962: { ! 963: cc_status.flags |= CC_KNOW_HI_G1; ! 964: cc_status.mdep = XEXP (operands[0], 0); ! 965: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands); ! 966: } ! 967: return \"stb %1,[%%g1+%%lo(%m0)]\"; ! 968: } ! 969: else ! 970: return \"stb %1,%0\"; ! 971: return \"mov %1,%0\"; ! 972: }") ! 973: ! 974: (define_insn "truncsihi2" ! 975: [(set (match_operand:HI 0 "general_operand" "=g") ! 976: (truncate:HI ! 977: (match_operand:SI 1 "register_operand" "r")))] ! 978: "" ! 979: "* ! 980: { ! 981: if (GET_CODE (operands[0]) == MEM) ! 982: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 983: { ! 984: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1) ! 985: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 986: { ! 987: cc_status.flags |= CC_KNOW_HI_G1; ! 988: cc_status.mdep = XEXP (operands[0], 0); ! 989: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands); ! 990: } ! 991: return \"sth %1,[%%g1+%%lo(%m0)]\"; ! 992: } ! 993: else ! 994: return \"sth %1,%0\"; ! 995: return \"mov %1,%0\"; ! 996: }") ! 997: ! 998: ;;- zero extension instructions ! 999: ! 1000: ;; Note that the one starting from HImode comes before those for QImode ! 1001: ;; so that a constant operand will match HImode, not QImode. ! 1002: ! 1003: (define_insn "zero_extendhisi2" ! 1004: [(set (match_operand:SI 0 "register_operand" "=r") ! 1005: (zero_extend:SI ! 1006: (match_operand:HI 1 "general_operand" "g")))] ! 1007: "" ! 1008: "* ! 1009: { ! 1010: if (REG_P (operands[1])) ! 1011: return \"sll %1,0x10,%0\;srl %0,0x10,%0\"; ! 1012: if (GET_CODE (operands[1]) == CONST_INT) ! 1013: abort (); ! 1014: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1015: { ! 1016: cc_status.flags |= CC_KNOW_HI_G1; ! 1017: cc_status.mdep = XEXP (operands[1], 0); ! 1018: return \"sethi %%hi(%m1),%%g1\;lduh [%%g1+%%lo(%m1)],%0\"; ! 1019: } ! 1020: else ! 1021: return \"lduh %1,%0\"; ! 1022: }") ! 1023: ! 1024: (define_insn "zero_extendqihi2" ! 1025: [(set (match_operand:HI 0 "register_operand" "=r") ! 1026: (zero_extend:HI ! 1027: (match_operand:QI 1 "general_operand" "g")))] ! 1028: "" ! 1029: "* ! 1030: { ! 1031: if (REG_P (operands[1])) ! 1032: return \"and %1,0xff,%0\"; ! 1033: if (GET_CODE (operands[1]) == CONST_INT) ! 1034: abort (); ! 1035: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1036: { ! 1037: cc_status.flags |= CC_KNOW_HI_G1; ! 1038: cc_status.mdep = XEXP (operands[1], 0); ! 1039: return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\"; ! 1040: } ! 1041: else ! 1042: return \"ldub %1,%0\"; ! 1043: }") ! 1044: ! 1045: (define_insn "zero_extendqisi2" ! 1046: [(set (match_operand:SI 0 "register_operand" "=r") ! 1047: (zero_extend:SI ! 1048: (match_operand:QI 1 "general_operand" "g")))] ! 1049: "" ! 1050: "* ! 1051: { ! 1052: if (REG_P (operands[1])) ! 1053: return \"and %1,0xff,%0\"; ! 1054: if (GET_CODE (operands[1]) == CONST_INT) ! 1055: abort (); ! 1056: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1057: { ! 1058: cc_status.flags |= CC_KNOW_HI_G1; ! 1059: cc_status.mdep = XEXP (operands[1], 0); ! 1060: return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\"; ! 1061: } ! 1062: else ! 1063: return \"ldub %1,%0\"; ! 1064: }") ! 1065: ! 1066: ;;- sign extension instructions ! 1067: ;; Note that the one starting from HImode comes before those for QImode ! 1068: ;; so that a constant operand will match HImode, not QImode. ! 1069: ! 1070: (define_insn "extendhisi2" ! 1071: [(set (match_operand:SI 0 "register_operand" "=r") ! 1072: (sign_extend:SI ! 1073: (match_operand:HI 1 "general_operand" "g")))] ! 1074: "" ! 1075: "* ! 1076: { ! 1077: if (REG_P (operands[1])) ! 1078: return \"sll %1,0x10,%0\;sra %0,0x10,%0\"; ! 1079: if (GET_CODE (operands[1]) == CONST_INT) ! 1080: abort (); ! 1081: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1082: { ! 1083: cc_status.flags |= CC_KNOW_HI_G1; ! 1084: cc_status.mdep = XEXP (operands[1], 0); ! 1085: return \"sethi %%hi(%m1),%%g1\;ldsh [%%g1+%%lo(%m1)],%0\"; ! 1086: } ! 1087: else ! 1088: return \"ldsh %1,%0\"; ! 1089: }") ! 1090: ! 1091: (define_insn "extendqihi2" ! 1092: [(set (match_operand:HI 0 "register_operand" "=r") ! 1093: (sign_extend:HI ! 1094: (match_operand:QI 1 "general_operand" "g")))] ! 1095: "" ! 1096: "* ! 1097: { ! 1098: if (REG_P (operands[1])) ! 1099: return \"sll %1,0x18,%0\;sra %0,0x18,%0\"; ! 1100: if (GET_CODE (operands[1]) == CONST_INT) ! 1101: abort (); ! 1102: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1103: { ! 1104: cc_status.flags |= CC_KNOW_HI_G1; ! 1105: cc_status.mdep = XEXP (operands[1], 0); ! 1106: return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\"; ! 1107: } ! 1108: else ! 1109: return \"ldsb %1,%0\"; ! 1110: }") ! 1111: ! 1112: (define_insn "extendqisi2" ! 1113: [(set (match_operand:SI 0 "register_operand" "=r") ! 1114: (sign_extend:SI ! 1115: (match_operand:QI 1 "general_operand" "g")))] ! 1116: "" ! 1117: "* ! 1118: { ! 1119: if (REG_P (operands[1])) ! 1120: return \"sll %1,0x18,%0\;sra %0,0x18,%0\"; ! 1121: if (GET_CODE (operands[1]) == CONST_INT) ! 1122: abort (); ! 1123: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1124: { ! 1125: cc_status.flags |= CC_KNOW_HI_G1; ! 1126: cc_status.mdep = XEXP (operands[1], 0); ! 1127: return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\"; ! 1128: } ! 1129: else ! 1130: return \"ldsb %1,%0\"; ! 1131: }") ! 1132: ! 1133: ;; Signed bitfield extractions come out looking like ! 1134: ;; (shiftrt (shift (sign_extend <Y>) <C1>) <C2>) ! 1135: ;; which we expand poorly as four shift insns. ! 1136: ;; These patters yeild two shifts: ! 1137: ;; (shiftrt (shift <Y> <C3>) <C4>) ! 1138: (define_insn "" ! 1139: [(set (match_operand:SI 0 "register_operand" "=r") ! 1140: (ashiftrt:SI ! 1141: (sign_extend:SI ! 1142: (match_operand:QI 1 "register_operand" "r")) ! 1143: (match_operand:SI 2 "small_int" "n")))] ! 1144: "" ! 1145: "sll %1,0x18,%0\;sra %0,0x18+%2,%0") ! 1146: ! 1147: (define_insn "" ! 1148: [(set (match_operand:SI 0 "register_operand" "=r") ! 1149: (ashiftrt:SI ! 1150: (sign_extend:SI ! 1151: (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r") ! 1152: (match_operand:SI 2 "small_int" "n")) 0)) ! 1153: (match_operand:SI 3 "small_int" "n")))] ! 1154: "" ! 1155: "sll %1,0x18+%2,%0\;sra %0,0x18+%3,%0") ! 1156: ! 1157: ;; Special patterns for optimizing bit-field instructions. ! 1158: ! 1159: ;; First two patterns are for bitfields that came from memory ! 1160: ;; testing only the high bit. They work with old combiner. ! 1161: ;; @@ Actually, the second pattern does not work if we ! 1162: ;; @@ need to set the N bit. ! 1163: (define_insn "" ! 1164: [(set (cc0) ! 1165: (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r") ! 1166: (const_int 7)) 0)))] ! 1167: "0" ! 1168: "andcc %0,128,%%g0") ! 1169: ! 1170: (define_insn "" ! 1171: [(set (cc0) ! 1172: (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r") ! 1173: (const_int 7)) 0)))] ! 1174: "0" ! 1175: "andcc %0,128,%%g0") ! 1176: ! 1177: ;; next two patterns are good for bitfields coming from memory ! 1178: ;; (via pseudo-register) or from a register, though this optimization ! 1179: ;; is only good for values contained wholly within the bottom 13 bits ! 1180: (define_insn "" ! 1181: [(set (cc0) ! 1182: (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r") ! 1183: (match_operand:SI 1 "small_int" "n")) ! 1184: (match_operand:SI 2 "small_int" "n")))] ! 1185: "(unsigned)((INTVAL (operands[2]) << INTVAL (operands[1])) + 0x1000) < 0x2000" ! 1186: "andcc %0,%2<<%1,%%g0") ! 1187: ! 1188: (define_insn "" ! 1189: [(set (cc0) ! 1190: (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r") ! 1191: (match_operand:SI 1 "small_int" "n")) ! 1192: (match_operand:SI 2 "small_int" "n")))] ! 1193: "(unsigned)((INTVAL (operands[2]) << INTVAL (operands[1])) + 0x1000) < 0x2000" ! 1194: "andcc %0,%2<<%1,%%g0") ! 1195: ! 1196: ;; Conversions between float and double. ! 1197: ! 1198: (define_insn "extendsfdf2" ! 1199: [(set (match_operand:DF 0 "register_operand" "=f") ! 1200: (float_extend:DF ! 1201: (match_operand:SF 1 "register_operand" "f")))] ! 1202: "" ! 1203: "fstod %1,%0") ! 1204: ! 1205: (define_insn "truncdfsf2" ! 1206: [(set (match_operand:SF 0 "register_operand" "=f") ! 1207: (float_truncate:SF ! 1208: (match_operand:DF 1 "register_operand" "f")))] ! 1209: "" ! 1210: "fdtos %1,%0") ! 1211: ! 1212: ;; Conversion between fixed point and floating point. ! 1213: ;; Note that among the fix-to-float insns ! 1214: ;; the ones that start with SImode come first. ! 1215: ;; That is so that an operand that is a CONST_INT ! 1216: ;; (and therefore lacks a specific machine mode). ! 1217: ;; will be recognized as SImode (which is always valid) ! 1218: ;; rather than as QImode or HImode. ! 1219: ! 1220: ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...))) ! 1221: ;; to be reloaded by putting the constant into memory. ! 1222: ;; It must come before the more general floatsisf2 pattern. ! 1223: (define_insn "" ! 1224: [(set (match_operand:SF 0 "general_operand" "=f") ! 1225: (float:SF (match_operand 1 "" "m")))] ! 1226: "GET_CODE (operands[1]) == CONST_INT" ! 1227: "* ! 1228: { ! 1229: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1230: { ! 1231: cc_status.flags |= CC_KNOW_HI_G1; ! 1232: cc_status.mdep = XEXP (operands[1], 0); ! 1233: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitos %0,%0\"; ! 1234: } ! 1235: return \"ld %1,%0\;fitos %0,%0\"; ! 1236: }") ! 1237: ! 1238: (define_insn "floatsisf2" ! 1239: [(set (match_operand:SF 0 "general_operand" "=f") ! 1240: (float:SF (match_operand:SI 1 "general_operand" "rfm")))] ! 1241: "" ! 1242: "* ! 1243: { ! 1244: if (GET_CODE (operands[1]) == MEM) ! 1245: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1246: { ! 1247: cc_status.flags |= CC_KNOW_HI_G1; ! 1248: cc_status.mdep = XEXP (operands[1], 0); ! 1249: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitos %0,%0\"; ! 1250: } ! 1251: else ! 1252: return \"ld %1,%0\;fitos %0,%0\"; ! 1253: else if (FP_REG_P (operands[1])) ! 1254: return \"fitos %1,%0\"; ! 1255: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\;fitos %0,%0\"; ! 1256: }") ! 1257: ! 1258: ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...))) ! 1259: ;; to be reloaded by putting the constant into memory. ! 1260: ;; It must come before the more general floatsidf2 pattern. ! 1261: (define_insn "" ! 1262: [(set (match_operand:DF 0 "general_operand" "=f") ! 1263: (float:DF (match_operand 1 "" "m")))] ! 1264: "GET_CODE (operands[1]) == CONST_INT" ! 1265: "* ! 1266: { ! 1267: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1268: { ! 1269: cc_status.flags |= CC_KNOW_HI_G1; ! 1270: cc_status.mdep = XEXP (operands[1], 0); ! 1271: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitod %0,%0\"; ! 1272: } ! 1273: return \"ld %1,%0\;fitod %0,%0\"; ! 1274: }") ! 1275: ! 1276: (define_insn "floatsidf2" ! 1277: [(set (match_operand:DF 0 "general_operand" "=f") ! 1278: (float:DF (match_operand:SI 1 "general_operand" "rfm")))] ! 1279: "" ! 1280: "* ! 1281: { ! 1282: if (GET_CODE (operands[1]) == MEM) ! 1283: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1284: { ! 1285: cc_status.flags |= CC_KNOW_HI_G1; ! 1286: cc_status.mdep = XEXP (operands[1], 0); ! 1287: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitod %0,%0\"; ! 1288: } ! 1289: else ! 1290: return \"ld %1,%0\;fitod %0,%0\"; ! 1291: else if (FP_REG_P (operands[1])) ! 1292: return \"fitod %1,%0\"; ! 1293: else ! 1294: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\;fitod %0,%0\"; ! 1295: }") ! 1296: ! 1297: ;; Convert a float to an actual integer. ! 1298: ;; Truncation is performed as part of the conversion. ! 1299: (define_insn "fix_truncsfsi2" ! 1300: [(set (match_operand:SI 0 "general_operand" "=rm") ! 1301: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] ! 1302: "" ! 1303: "* ! 1304: { ! 1305: cc_status.flags &= ~(CC_F1_IS_0); ! 1306: if (FP_REG_P (operands[1])) ! 1307: output_asm_insn (\"fstoi %1,%%f1\", operands); ! 1308: else if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1309: { ! 1310: cc_status.flags |= CC_KNOW_HI_G1; ! 1311: cc_status.mdep = XEXP (operands[1], 0); ! 1312: output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%%f1\;fstoi %%f1,%%f1\", operands); ! 1313: } ! 1314: else ! 1315: output_asm_insn (\"ld %1,%%f1\;fstoi %%f1,%%f1\", operands); ! 1316: if (GET_CODE (operands[0]) == MEM) ! 1317: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1318: { ! 1319: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1) ! 1320: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 1321: { ! 1322: cc_status.flags |= CC_KNOW_HI_G1; ! 1323: cc_status.mdep = XEXP (operands[0], 0); ! 1324: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands); ! 1325: } ! 1326: return \"st %%f1,[%%g1+%%lo(%m0)]\"; ! 1327: } ! 1328: else ! 1329: return \"st %%f1,%0\"; ! 1330: else ! 1331: return \"st %%f1,[%%fp-4]\;ld [%%fp-4],%0\"; ! 1332: }") ! 1333: ! 1334: (define_insn "fix_truncdfsi2" ! 1335: [(set (match_operand:SI 0 "general_operand" "=rm") ! 1336: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] ! 1337: "" ! 1338: "* ! 1339: { ! 1340: cc_status.flags &= ~CC_F0_IS_0; ! 1341: if (FP_REG_P (operands[1])) ! 1342: output_asm_insn (\"fdtoi %1,%%f0\", operands); ! 1343: else ! 1344: { ! 1345: rtx xoperands[2]; ! 1346: xoperands[0] = gen_rtx (REG, DFmode, 32); ! 1347: xoperands[1] = operands[1]; ! 1348: output_asm_insn (output_fp_move_double (xoperands), xoperands); ! 1349: output_asm_insn (\"fdtoi %%f0,%%f0\", 0); ! 1350: } ! 1351: if (GET_CODE (operands[0]) == MEM) ! 1352: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) ! 1353: { ! 1354: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1) ! 1355: && XEXP (operands[0], 0) == cc_prev_status.mdep)) ! 1356: { ! 1357: cc_status.flags |= CC_KNOW_HI_G1; ! 1358: cc_status.mdep = XEXP (operands[0], 0); ! 1359: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands); ! 1360: } ! 1361: return \"st %%f0,[%%g1+%%lo(%m0)]\"; ! 1362: } ! 1363: else ! 1364: return \"st %%f0,%0\"; ! 1365: else ! 1366: return \"st %%f0,[%%fp-4]\;ld [%%fp-4],%0\"; ! 1367: }") ! 1368: ! 1369: ;;- arithmetic instructions ! 1370: ! 1371: (define_insn "addsi3" ! 1372: [(set (match_operand:SI 0 "register_operand" "=r") ! 1373: (plus:SI (match_operand:SI 1 "arith32_operand" "%r") ! 1374: (match_operand:SI 2 "arith32_operand" "rn")))] ! 1375: "" ! 1376: "* ! 1377: { ! 1378: if (REG_P (operands[2])) ! 1379: return \"add %1,%2,%0\"; ! 1380: if (SMALL_INT (operands[2])) ! 1381: return \"add %1,%2,%0\"; ! 1382: cc_status.flags &= ~CC_KNOW_HI_G1; ! 1383: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;add %1,%%g1,%0\"; ! 1384: }") ! 1385: ! 1386: (define_insn "subsi3" ! 1387: [(set (match_operand:SI 0 "register_operand" "=r") ! 1388: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 1389: (match_operand:SI 2 "arith32_operand" "rn")))] ! 1390: "" ! 1391: "* ! 1392: { ! 1393: if (REG_P (operands[2])) ! 1394: return \"sub %1,%2,%0\"; ! 1395: if (SMALL_INT (operands[2])) ! 1396: return \"sub %1,%2,%0\"; ! 1397: cc_status.flags &= ~CC_KNOW_HI_G1; ! 1398: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;sub %1,%%g1,%0\"; ! 1399: }") ! 1400: ! 1401: (define_expand "mulsi3" ! 1402: [(set (match_operand:SI 0 "register_operand" "r") ! 1403: (mult:SI (match_operand:SI 1 "general_operand" "") ! 1404: (match_operand:SI 2 "general_operand" "")))] ! 1405: "" ! 1406: " ! 1407: { ! 1408: rtx src; ! 1409: ! 1410: if (GET_CODE (operands[1]) == CONST_INT) ! 1411: if (GET_CODE (operands[2]) == CONST_INT) ! 1412: { ! 1413: emit_move_insn (operands[0], ! 1414: gen_rtx (CONST_INT, VOIDmode, ! 1415: INTVAL (operands[1]) * INTVAL (operands[2]))); ! 1416: DONE; ! 1417: } ! 1418: else ! 1419: src = gen_rtx (MULT, SImode, ! 1420: copy_to_mode_reg (SImode, operands[2]), ! 1421: operands[1]); ! 1422: else if (GET_CODE (operands[2]) == CONST_INT) ! 1423: src = gen_rtx (MULT, SImode, ! 1424: copy_to_mode_reg (SImode, operands[1]), ! 1425: operands[2]); ! 1426: else src = 0; ! 1427: ! 1428: if (src) ! 1429: emit_insn (gen_rtx (SET, VOIDmode, operands[0], src)); ! 1430: else ! 1431: emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5, ! 1432: gen_rtx (SET, VOIDmode, operands[0], ! 1433: gen_rtx (MULT, SImode, operands[1], operands[2])), ! 1434: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 8)), ! 1435: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 9)), ! 1436: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 12)), ! 1437: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 13))))); ! 1438: DONE; ! 1439: }") ! 1440: ! 1441: (define_expand "umulsi3" ! 1442: [(set (match_operand:SI 0 "register_operand" "r") ! 1443: (umult:SI (match_operand:SI 1 "general_operand" "") ! 1444: (match_operand:SI 2 "general_operand" "")))] ! 1445: "" ! 1446: " ! 1447: { ! 1448: rtx src; ! 1449: ! 1450: if (GET_CODE (operands[1]) == CONST_INT) ! 1451: if (GET_CODE (operands[2]) == CONST_INT) ! 1452: { ! 1453: emit_move_insn (operands[0], ! 1454: gen_rtx (CONST_INT, VOIDmode, ! 1455: (unsigned)INTVAL (operands[1]) * (unsigned)INTVAL (operands[2]))); ! 1456: DONE; ! 1457: } ! 1458: else ! 1459: src = gen_rtx (UMULT, SImode, ! 1460: copy_to_mode_reg (SImode, operands[2]), ! 1461: operands[1]); ! 1462: else if (GET_CODE (operands[2]) == CONST_INT) ! 1463: src = gen_rtx (UMULT, SImode, ! 1464: copy_to_mode_reg (SImode, operands[1]), ! 1465: operands[2]); ! 1466: else src = 0; ! 1467: ! 1468: if (src) ! 1469: emit_insn (gen_rtx (SET, VOIDmode, operands[0], src)); ! 1470: else ! 1471: emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5, ! 1472: gen_rtx (SET, VOIDmode, operands[0], ! 1473: gen_rtx (UMULT, SImode, operands[1], operands[2])), ! 1474: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 8)), ! 1475: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 9)), ! 1476: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 12)), ! 1477: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 13))))); ! 1478: DONE; ! 1479: }") ! 1480: ! 1481: (define_insn "" ! 1482: [(set (match_operand:SI 0 "register_operand" "=r") ! 1483: (mult:SI (match_operand:SI 1 "register_operand" "r") ! 1484: (match_operand:SI 2 "immediate_operand" "n")))] ! 1485: "" ! 1486: "* return output_mul_by_constant (insn, operands, 0);") ! 1487: ! 1488: (define_insn "" ! 1489: [(set (match_operand:SI 0 "register_operand" "=r") ! 1490: (umult:SI (match_operand:SI 1 "register_operand" "r") ! 1491: (match_operand:SI 2 "immediate_operand" "n")))] ! 1492: "" ! 1493: "* return output_mul_by_constant (insn, operands, 1);") ! 1494: ! 1495: (define_insn "" ! 1496: [(set (match_operand:SI 0 "register_operand" "=r") ! 1497: (mult:SI (match_operand:SI 1 "general_operand" "%r") ! 1498: (match_operand:SI 2 "general_operand" "r"))) ! 1499: (clobber (reg:SI 8)) ! 1500: (clobber (reg:SI 9)) ! 1501: (clobber (reg:SI 12)) ! 1502: (clobber (reg:SI 13))] ! 1503: "" ! 1504: "* return output_mul_insn (operands, 0);") ! 1505: ! 1506: (define_insn "" ! 1507: [(set (match_operand:SI 0 "register_operand" "=r") ! 1508: (umult:SI (match_operand:SI 1 "general_operand" "%r") ! 1509: (match_operand:SI 2 "general_operand" "r"))) ! 1510: (clobber (reg:SI 8)) ! 1511: (clobber (reg:SI 9)) ! 1512: (clobber (reg:SI 12)) ! 1513: (clobber (reg:SI 13))] ! 1514: "" ! 1515: "* return output_mul_insn (operands, 1);") ! 1516: ! 1517: ;; this pattern is needed because cse may eliminate the multiplication, ! 1518: ;; but leave the clobbers behind. ! 1519: ! 1520: (define_insn "" ! 1521: [(set (match_operand:SI 0 "register_operand" "=r") ! 1522: (match_operand:SI 1 "general_operand" "g")) ! 1523: (clobber (reg:SI 8)) ! 1524: (clobber (reg:SI 9)) ! 1525: (clobber (reg:SI 12)) ! 1526: (clobber (reg:SI 13))] ! 1527: "" ! 1528: "* ! 1529: { ! 1530: if (GET_CODE (operands[1]) == CONST_INT) ! 1531: { ! 1532: if (SMALL_INT (operands[1])) ! 1533: return \"mov %1,%0\"; ! 1534: return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\"; ! 1535: } ! 1536: if (GET_CODE (operands[1]) == MEM) ! 1537: return \"ld %1,%0\"; ! 1538: return \"mov %1,%0\"; ! 1539: }") ! 1540: ! 1541: ;;- and instructions (with compliment also) ! 1542: (define_insn "andsi3" ! 1543: [(set (match_operand:SI 0 "register_operand" "=r") ! 1544: (and:SI (match_operand:SI 1 "arith32_operand" "%r") ! 1545: (match_operand:SI 2 "arith32_operand" "rn")))] ! 1546: "" ! 1547: "* ! 1548: { ! 1549: if (REG_P (operands[2]) || SMALL_INT (operands[2])) ! 1550: return \"and %1,%2,%0\"; ! 1551: cc_status.flags &= ~CC_KNOW_HI_G1; ! 1552: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;and %1,%%g1,%0\"; ! 1553: }") ! 1554: ! 1555: (define_insn "andcbsi3" ! 1556: [(set (match_operand:SI 0 "register_operand" "=r") ! 1557: (and:SI (match_operand:SI 1 "register_operand" "r") ! 1558: (not:SI (match_operand:SI 2 "register_operand" "r"))))] ! 1559: "" ! 1560: "andn %1,%2,%0") ! 1561: ! 1562: (define_insn "iorsi3" ! 1563: [(set (match_operand:SI 0 "register_operand" "=r") ! 1564: (ior:SI (match_operand:SI 1 "arith32_operand" "%r") ! 1565: (match_operand:SI 2 "arith32_operand" "rn")))] ! 1566: "" ! 1567: "* ! 1568: { ! 1569: if (REG_P (operands[2]) || SMALL_INT (operands[2])) ! 1570: return \"or %1,%2,%0\"; ! 1571: cc_status.flags &= ~CC_KNOW_HI_G1; ! 1572: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;or %1,%%g1,%0\"; ! 1573: }") ! 1574: ! 1575: (define_insn "iorcbsi3" ! 1576: [(set (match_operand:SI 0 "register_operand" "=r") ! 1577: (ior:SI (match_operand:SI 1 "register_operand" "r") ! 1578: (not:SI (match_operand:SI 2 "register_operand" "r"))))] ! 1579: "" ! 1580: "orn %1,%2,%0") ! 1581: ! 1582: (define_insn "xorsi3" ! 1583: [(set (match_operand:SI 0 "register_operand" "=r") ! 1584: (xor:SI (match_operand:SI 1 "arith32_operand" "%r") ! 1585: (match_operand:SI 2 "arith32_operand" "rn")))] ! 1586: "" ! 1587: "* ! 1588: { ! 1589: if (REG_P (operands[2]) || SMALL_INT (operands[2])) ! 1590: return \"xor %1,%2,%0\"; ! 1591: cc_status.flags &= ~CC_KNOW_HI_G1; ! 1592: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;xor %1,%%g1,%0\"; ! 1593: }") ! 1594: ! 1595: (define_insn "xorcbsi3" ! 1596: [(set (match_operand:SI 0 "register_operand" "=r") ! 1597: (xor:SI (match_operand:SI 1 "register_operand" "r") ! 1598: (not:SI (match_operand:SI 2 "register_operand" "r"))))] ! 1599: "" ! 1600: "xnor %1,%2,%0") ! 1601: ! 1602: ;; We cannot use the "neg" pseudo insn because the Sun assembler ! 1603: ;; does not know how to make it work for constants. ! 1604: (define_insn "negsi2" ! 1605: [(set (match_operand:SI 0 "general_operand" "=r") ! 1606: (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] ! 1607: "" ! 1608: "sub %%g0,%1,%0") ! 1609: ! 1610: ;; We cannot use the "not" pseudo insn because the Sun assembler ! 1611: ;; does not know how to make it work for constants. ! 1612: (define_insn "one_cmplsi2" ! 1613: [(set (match_operand:SI 0 "general_operand" "=r") ! 1614: (not:SI (match_operand:SI 1 "arith_operand" "rI")))] ! 1615: "" ! 1616: "xnor %%g0,%1,%0") ! 1617: ! 1618: ;; Floating point arithmetic instructions. ! 1619: ! 1620: (define_insn "adddf3" ! 1621: [(set (match_operand:DF 0 "register_operand" "=f") ! 1622: (plus:DF (match_operand:DF 1 "register_operand" "f") ! 1623: (match_operand:DF 2 "register_operand" "f")))] ! 1624: "" ! 1625: "faddd %1,%2,%0") ! 1626: ! 1627: (define_insn "addsf3" ! 1628: [(set (match_operand:SF 0 "register_operand" "=f") ! 1629: (plus:SF (match_operand:SF 1 "register_operand" "f") ! 1630: (match_operand:SF 2 "register_operand" "f")))] ! 1631: "" ! 1632: "fadds %1,%2,%0") ! 1633: ! 1634: (define_insn "subdf3" ! 1635: [(set (match_operand:DF 0 "register_operand" "=f") ! 1636: (minus:DF (match_operand:DF 1 "register_operand" "f") ! 1637: (match_operand:DF 2 "register_operand" "f")))] ! 1638: "" ! 1639: "fsubd %1,%2,%0") ! 1640: ! 1641: (define_insn "subsf3" ! 1642: [(set (match_operand:SF 0 "register_operand" "=f") ! 1643: (minus:SF (match_operand:SF 1 "register_operand" "f") ! 1644: (match_operand:SF 2 "register_operand" "f")))] ! 1645: "" ! 1646: "fsubs %1,%2,%0") ! 1647: ! 1648: (define_insn "muldf3" ! 1649: [(set (match_operand:DF 0 "register_operand" "=f") ! 1650: (mult:DF (match_operand:DF 1 "register_operand" "f") ! 1651: (match_operand:DF 2 "register_operand" "f")))] ! 1652: "" ! 1653: "fmuld %1,%2,%0") ! 1654: ! 1655: (define_insn "mulsf3" ! 1656: [(set (match_operand:SF 0 "register_operand" "=f") ! 1657: (mult:SF (match_operand:SF 1 "register_operand" "f") ! 1658: (match_operand:SF 2 "register_operand" "f")))] ! 1659: "" ! 1660: "fmuls %1,%2,%0") ! 1661: ! 1662: (define_insn "divdf3" ! 1663: [(set (match_operand:DF 0 "register_operand" "=f") ! 1664: (div:DF (match_operand:DF 1 "register_operand" "f") ! 1665: (match_operand:DF 2 "register_operand" "f")))] ! 1666: "" ! 1667: "fdivd %1,%2,%0") ! 1668: ! 1669: (define_insn "divsf3" ! 1670: [(set (match_operand:SF 0 "register_operand" "=f") ! 1671: (div:SF (match_operand:SF 1 "register_operand" "f") ! 1672: (match_operand:SF 2 "register_operand" "f")))] ! 1673: "" ! 1674: "fdivs %1,%2,%0") ! 1675: ! 1676: (define_insn "negdf2" ! 1677: [(set (match_operand:DF 0 "register_operand" "=f") ! 1678: (neg:DF (match_operand:DF 1 "register_operand" "f")))] ! 1679: "" ! 1680: "* ! 1681: { ! 1682: output_asm_insn (\"fnegs %1,%0\", operands); ! 1683: if (REGNO (operands[0]) != REGNO (operands[1])) ! 1684: { ! 1685: operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1); ! 1686: operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1); ! 1687: output_asm_insn (\"fmovs %1,%0\", operands); ! 1688: } ! 1689: return \"\"; ! 1690: }") ! 1691: ! 1692: (define_insn "negsf2" ! 1693: [(set (match_operand:SF 0 "register_operand" "=f") ! 1694: (neg:SF (match_operand:SF 1 "register_operand" "f")))] ! 1695: "" ! 1696: "fnegs %1,%0") ! 1697: ! 1698: (define_insn "absdf2" ! 1699: [(set (match_operand:DF 0 "register_operand" "=f") ! 1700: (abs:DF (match_operand:DF 1 "register_operand" "f")))] ! 1701: "" ! 1702: "* ! 1703: { ! 1704: output_asm_insn (\"fabss %1,%0\", operands); ! 1705: if (REGNO (operands[0]) != REGNO (operands[1])) ! 1706: { ! 1707: operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1); ! 1708: operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1); ! 1709: output_asm_insn (\"fmovs %1,%0\", operands); ! 1710: } ! 1711: return \"\"; ! 1712: }") ! 1713: ! 1714: (define_insn "abssf2" ! 1715: [(set (match_operand:SF 0 "register_operand" "=f") ! 1716: (abs:SF (match_operand:SF 1 "register_operand" "f")))] ! 1717: "" ! 1718: "fabss %1,%0") ! 1719: ! 1720: ;; Shift instructions ! 1721: ! 1722: ;; Optimized special case of shifting. ! 1723: ;; Must precede the general case. ! 1724: ! 1725: (define_insn "" ! 1726: [(set (match_operand:SI 0 "register_operand" "=r") ! 1727: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") ! 1728: (const_int 24)))] ! 1729: "" ! 1730: "* ! 1731: { ! 1732: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1733: { ! 1734: cc_status.flags |= CC_KNOW_HI_G1; ! 1735: cc_status.mdep = XEXP (operands[1], 0); ! 1736: return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\"; ! 1737: } ! 1738: return \"ldsb %1,%0\"; ! 1739: }") ! 1740: ! 1741: (define_insn "" ! 1742: [(set (match_operand:SI 0 "register_operand" "=r") ! 1743: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") ! 1744: (const_int 24)))] ! 1745: "" ! 1746: "* ! 1747: { ! 1748: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) ! 1749: { ! 1750: cc_status.flags |= CC_KNOW_HI_G1; ! 1751: cc_status.mdep = XEXP (operands[1], 0); ! 1752: return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\"; ! 1753: } ! 1754: return \"ldub %1,%0\"; ! 1755: }") ! 1756: ! 1757: ;;- arithmetic shift instructions ! 1758: (define_insn "ashlsi3" ! 1759: [(set (match_operand:SI 0 "register_operand" "=r") ! 1760: (ashift:SI (match_operand:SI 1 "register_operand" "r") ! 1761: (match_operand:SI 2 "arith32_operand" "rn")))] ! 1762: "" ! 1763: "* ! 1764: { ! 1765: if (GET_CODE (operands[2]) == CONST_INT ! 1766: && INTVAL (operands[2]) >= 32) ! 1767: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31); ! 1768: return \"sll %1,%2,%0\"; ! 1769: }") ! 1770: ! 1771: (define_insn "ashrsi3" ! 1772: [(set (match_operand:SI 0 "register_operand" "=r") ! 1773: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") ! 1774: (match_operand:SI 2 "arith32_operand" "rn")))] ! 1775: "" ! 1776: "* ! 1777: { ! 1778: if (GET_CODE (operands[2]) == CONST_INT ! 1779: && INTVAL (operands[2]) >= 32) ! 1780: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31); ! 1781: return \"sra %1,%2,%0\"; ! 1782: }") ! 1783: ! 1784: (define_insn "lshrsi3" ! 1785: [(set (match_operand:SI 0 "register_operand" "=r") ! 1786: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") ! 1787: (match_operand:SI 2 "arith32_operand" "rn")))] ! 1788: "" ! 1789: "* ! 1790: { ! 1791: if (GET_CODE (operands[2]) == CONST_INT ! 1792: && INTVAL (operands[2]) >= 32) ! 1793: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31); ! 1794: return \"srl %1,%2,%0\"; ! 1795: }") ! 1796: ! 1797: ;; Unconditional and other jump instructions ! 1798: ;; Note that for the Sparc, by setting the annul bit on an unconditional ! 1799: ;; branch, the following insn is never executed. This saves us a nop, ! 1800: ;; but requires a debugger which can handle annuled branches. ! 1801: (define_insn "jump" ! 1802: [(set (pc) (label_ref (match_operand 0 "" "")))] ! 1803: "" ! 1804: "* ! 1805: { ! 1806: extern int optimize; ! 1807: extern int flag_no_peephole; ! 1808: ! 1809: if (optimize && !flag_no_peephole) ! 1810: return \"b,a %l0\"; ! 1811: return \"b %l0\;nop\"; ! 1812: }") ! 1813: ! 1814: ;; Peephole optimizers recognize a few simple cases when delay insns are safe. ! 1815: ;; Complex ones are up front. Simple ones after. ! 1816: ! 1817: ;; This pattern is just like the following one, but matches when there ! 1818: ;; is a jump insn after the "delay" insn. Without this pattern, we ! 1819: ;; de-optimize that case. ! 1820: ! 1821: (define_peephole ! 1822: [(set (pc) (match_operand 0 "" "")) ! 1823: (set (match_operand:SI 1 "" "") ! 1824: (match_operand:SI 2 "" "")) ! 1825: (set (pc) (label_ref (match_operand 3 "" "")))] ! 1826: "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 2)" ! 1827: "* ! 1828: { ! 1829: rtx xoperands[2]; ! 1830: rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]); ! 1831: rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0); ! 1832: rtx label, head; ! 1833: int parity; ! 1834: ! 1835: if (GET_CODE (XEXP (operands[0], 1)) == PC) ! 1836: { ! 1837: parity = 1; ! 1838: label = XEXP (XEXP (operands[0], 2), 0); ! 1839: } ! 1840: else ! 1841: { ! 1842: parity = 0; ! 1843: label = XEXP (XEXP (operands[0], 1), 0); ! 1844: } ! 1845: xoperands[0] = XEXP (operands[0], 0); ! 1846: xoperands[1] = label; ! 1847: ! 1848: head = next_real_insn_no_labels (label); ! 1849: ! 1850: /* If at the target of this label we set the condition codes, ! 1851: and the condition codes are already set for that value, ! 1852: advance, if we can, to the following insn. */ ! 1853: if (GET_CODE (PATTERN (head)) == SET ! 1854: && GET_CODE (SET_DEST (PATTERN (head))) == CC0 ! 1855: && cc_status.value2 == SET_SRC (PATTERN (head))) ! 1856: { ! 1857: rtx nhead = next_real_insn_no_labels (head); ! 1858: if (nhead ! 1859: && GET_CODE (nhead) == INSN ! 1860: && GET_CODE (PATTERN (nhead)) == SET ! 1861: && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)), ! 1862: GET_MODE (SET_DEST (PATTERN (nhead)))) ! 1863: && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)) ! 1864: { ! 1865: head = nhead; ! 1866: } ! 1867: } ! 1868: ! 1869: /* Output the branch instruction first. */ ! 1870: if (cc_prev_status.flags & CC_IN_FCCR) ! 1871: { ! 1872: if (parity) ! 1873: output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands); ! 1874: else ! 1875: output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands); ! 1876: } ! 1877: else ! 1878: { ! 1879: if (parity) ! 1880: output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands); ! 1881: else ! 1882: output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands); ! 1883: } ! 1884: ! 1885: /* Now steal the first insn of the target. */ ! 1886: output_eager_then_insn (head, operands); ! 1887: ! 1888: XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 1); ! 1889: XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 2); ! 1890: ! 1891: return output_delayed_branch (\"b %l3 ! eager2\", operands, insn); ! 1892: }") ! 1893: ! 1894: ;; Here is a peephole which recognizes where delay insns can be made safe: ! 1895: ;; (1) following a conditional branch, if the target of the conditional branch ! 1896: ;; has only one user (this insn), move the first insn into our delay slot ! 1897: ;; and emit an annulled branch. ! 1898: ;; (2) following a conditional branch, if we can execute the fall-through ! 1899: ;; insn without risking any evil effects, then do that instead of a nop. ! 1900: ! 1901: (define_peephole ! 1902: [(set (pc) (match_operand 0 "" "")) ! 1903: (set (match_operand:SI 1 "" "") ! 1904: (match_operand:SI 2 "" ""))] ! 1905: "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 1)" ! 1906: "* ! 1907: { ! 1908: rtx xoperands[2]; ! 1909: rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]); ! 1910: rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0); ! 1911: rtx label, head, prev = (rtx)1; ! 1912: int parity; ! 1913: ! 1914: if (GET_CODE (XEXP (operands[0], 1)) == PC) ! 1915: { ! 1916: parity = 1; ! 1917: label = XEXP (XEXP (operands[0], 2), 0); ! 1918: } ! 1919: else ! 1920: { ! 1921: parity = 0; ! 1922: label = XEXP (XEXP (operands[0], 1), 0); ! 1923: } ! 1924: xoperands[0] = XEXP (operands[0], 0); ! 1925: xoperands[1] = label; ! 1926: ! 1927: if (LABEL_NUSES (label) == 1) ! 1928: { ! 1929: prev = PREV_INSN (label); ! 1930: while (prev ! 1931: && (GET_CODE (prev) == NOTE ! 1932: || (GET_CODE (prev) == INSN ! 1933: && (GET_CODE (PATTERN (prev)) == CLOBBER ! 1934: || GET_CODE (PATTERN (prev)) == USE)))) ! 1935: prev = PREV_INSN (prev); ! 1936: if (prev == 0 ! 1937: || GET_CODE (prev) == BARRIER) ! 1938: { ! 1939: prev = 0; ! 1940: head = next_real_insn_no_labels (label); ! 1941: } ! 1942: } ! 1943: if (prev == 0 ! 1944: && head != 0 ! 1945: && ! INSN_DELETED_P (head) ! 1946: && GET_CODE (head) == INSN ! 1947: && GET_CODE (PATTERN (head)) == SET ! 1948: && strict_single_insn_op_p (SET_SRC (PATTERN (head)), ! 1949: GET_MODE (SET_DEST (PATTERN (head)))) ! 1950: && strict_single_insn_op_p (SET_DEST (PATTERN (head)), VOIDmode)) ! 1951: { ! 1952: /* If at the target of this label we set the condition codes, ! 1953: and the condition codes are already set for that value, ! 1954: advance, if we can, to the following insn. */ ! 1955: if (GET_CODE (PATTERN (head)) == SET ! 1956: && GET_CODE (SET_DEST (PATTERN (head))) == CC0 ! 1957: && cc_status.value2 == SET_SRC (PATTERN (head))) ! 1958: { ! 1959: rtx nhead = next_real_insn_no_labels (head); ! 1960: if (nhead ! 1961: && GET_CODE (nhead) == INSN ! 1962: && GET_CODE (PATTERN (nhead)) == SET ! 1963: && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)), ! 1964: GET_MODE (SET_DEST (nhead))) ! 1965: && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)) ! 1966: head = nhead; ! 1967: } ! 1968: ! 1969: /* Output the branch instruction first. */ ! 1970: if (cc_prev_status.flags & CC_IN_FCCR) ! 1971: { ! 1972: if (parity) ! 1973: output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands); ! 1974: else ! 1975: output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands); ! 1976: } ! 1977: else ! 1978: { ! 1979: if (parity) ! 1980: output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands); ! 1981: else ! 1982: output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands); ! 1983: } ! 1984: ! 1985: /* Now steal the first insn of the target. */ ! 1986: output_eager_then_insn (head, operands); ! 1987: } ! 1988: else ! 1989: { ! 1990: /* Output the branch instruction first. */ ! 1991: if (cc_prev_status.flags & CC_IN_FCCR) ! 1992: { ! 1993: if (parity) ! 1994: output_asm_insn (\"fb%F0 %l1 ! eager\", xoperands); ! 1995: else ! 1996: output_asm_insn (\"fb%C0 %l1 ! eager\", xoperands); ! 1997: } ! 1998: else ! 1999: { ! 2000: if (parity) ! 2001: output_asm_insn (\"b%N0 %l1 ! eager\", xoperands); ! 2002: else ! 2003: output_asm_insn (\"b%C0 %l1 ! eager\", xoperands); ! 2004: } ! 2005: } ! 2006: return output_delay_insn (delay_insn); ! 2007: }") ! 2008: ! 2009: ;; Here are two simple peepholes which fill the delay slot of ! 2010: ;; an unconditional branch. ! 2011: ! 2012: (define_peephole ! 2013: [(set (match_operand:SI 0 "register_operand" "=r") ! 2014: (match_operand:SI 1 "single_insn_src_p" "p")) ! 2015: (set (pc) (label_ref (match_operand 2 "" "")))] ! 2016: "" ! 2017: "* return output_delayed_branch (\"b %l2\", operands, insn);") ! 2018: ! 2019: (define_peephole ! 2020: [(set (match_operand:SI 0 "memory_operand" "=m") ! 2021: (match_operand:SI 1 "reg_or_0_operand" "rJ")) ! 2022: (set (pc) (label_ref (match_operand 2 "" "")))] ! 2023: "" ! 2024: "* return output_delayed_branch (\"b %l2\", operands, insn);") ! 2025: ! 2026: (define_insn "tablejump" ! 2027: [(set (pc) (match_operand:SI 0 "register_operand" "r")) ! 2028: (use (label_ref (match_operand 1 "" "")))] ! 2029: "" ! 2030: "jmp %0\;nop") ! 2031: ! 2032: (define_peephole ! 2033: [(set (match_operand:SI 0 "register_operand" "=r") ! 2034: (match_operand:SI 1 "single_insn_src_p" "p")) ! 2035: (set (pc) (match_operand:SI 2 "register_operand" "r")) ! 2036: (use (label_ref (match_operand 3 "" "")))] ! 2037: "REGNO (operands[0]) != REGNO (operands[2])" ! 2038: "* return output_delayed_branch (\"jmp %2\", operands, insn);") ! 2039: ! 2040: (define_peephole ! 2041: [(set (match_operand:SI 0 "memory_operand" "=m") ! 2042: (match_operand:SI 1 "reg_or_0_operand" "rJ")) ! 2043: (set (pc) (match_operand:SI 2 "register_operand" "r")) ! 2044: (use (label_ref (match_operand 3 "" "")))] ! 2045: "" ! 2046: "* return output_delayed_branch (\"jmp %2\", operands, insn);") ! 2047: ! 2048: ;;- jump to subroutine ! 2049: (define_expand "call" ! 2050: [(call (match_operand:SI 0 "memory_operand" "m") ! 2051: (match_operand 1 "" "i"))] ! 2052: ;; operand[2] is next_arg_register ! 2053: "" ! 2054: " ! 2055: { ! 2056: rtx fn_rtx, nregs_rtx; ! 2057: ! 2058: if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[0], 0)) == REG) ! 2059: { ! 2060: rtx g1_rtx = gen_rtx (REG, SImode, 1); ! 2061: emit_move_insn (g1_rtx, XEXP (operands[0], 0)); ! 2062: fn_rtx = gen_rtx (MEM, SImode, g1_rtx); ! 2063: } ! 2064: else ! 2065: fn_rtx = operands[0]; ! 2066: ! 2067: /* Count the number of parameter registers being used by this call. ! 2068: if that argument is NULL, it means we are using them all, which ! 2069: means 6 on the sparc. */ ! 2070: #if 0 ! 2071: if (operands[2]) ! 2072: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8); ! 2073: else ! 2074: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); ! 2075: #else ! 2076: nregs_rtx = const0_rtx; ! 2077: #endif ! 2078: ! 2079: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, ! 2080: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), ! 2081: gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31))))); ! 2082: DONE; ! 2083: }") ! 2084: ! 2085: (define_insn "" ! 2086: [(call (match_operand:SI 0 "memory_operand" "m") ! 2087: (match_operand 1 "" "i")) ! 2088: (use (reg:SI 31))] ! 2089: ;;- Don't use operand 1 for most machines. ! 2090: "" ! 2091: "* ! 2092: { ! 2093: /* strip the MEM. */ ! 2094: operands[0] = XEXP (operands[0], 0); ! 2095: CC_STATUS_INIT; ! 2096: if (TARGET_SUN_ASM && GET_CODE (operands[0]) == REG) ! 2097: return \"jmpl %a0,%%o7\;nop\"; ! 2098: return \"call %a0,%1\;nop\"; ! 2099: }") ! 2100: ! 2101: (define_peephole ! 2102: [(set (match_operand:SI 0 "register_operand" "=r") ! 2103: (match_operand:SI 1 "single_insn_src_p" "p")) ! 2104: (parallel [(call (match_operand:SI 2 "memory_operand" "m") ! 2105: (match_operand 3 "" "i")) ! 2106: (use (reg:SI 31))])] ! 2107: ;;- Don't use operand 1 for most machines. ! 2108: "! reg_mentioned_p (operands[0], operands[2])" ! 2109: "* ! 2110: { ! 2111: /* strip the MEM. */ ! 2112: operands[2] = XEXP (operands[2], 0); ! 2113: if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG) ! 2114: return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn); ! 2115: return output_delayed_branch (\"call %a2,%3\", operands, insn); ! 2116: }") ! 2117: ! 2118: (define_peephole ! 2119: [(set (match_operand:SI 0 "memory_operand" "=m") ! 2120: (match_operand:SI 1 "reg_or_0_operand" "rJ")) ! 2121: (parallel [(call (match_operand:SI 2 "memory_operand" "m") ! 2122: (match_operand 3 "" "i")) ! 2123: (use (reg:SI 31))])] ! 2124: ;;- Don't use operand 1 for most machines. ! 2125: "" ! 2126: "* ! 2127: { ! 2128: /* strip the MEM. */ ! 2129: operands[2] = XEXP (operands[2], 0); ! 2130: if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG) ! 2131: return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn); ! 2132: return output_delayed_branch (\"call %a2,%3\", operands, insn); ! 2133: }") ! 2134: ! 2135: (define_expand "call_value" ! 2136: [(set (match_operand 0 "register_operand" "=rf") ! 2137: (call (match_operand:SI 1 "memory_operand" "m") ! 2138: (match_operand 2 "" "i")))] ! 2139: ;; operand 3 is next_arg_register ! 2140: "" ! 2141: " ! 2142: { ! 2143: rtx fn_rtx, nregs_rtx; ! 2144: rtvec vec; ! 2145: ! 2146: if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[1], 0)) == REG) ! 2147: { ! 2148: rtx g1_rtx = gen_rtx (REG, SImode, 1); ! 2149: emit_move_insn (g1_rtx, XEXP (operands[1], 0)); ! 2150: fn_rtx = gen_rtx (MEM, SImode, g1_rtx); ! 2151: } ! 2152: else ! 2153: fn_rtx = operands[1]; ! 2154: ! 2155: #if 0 ! 2156: if (operands[3]) ! 2157: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8); ! 2158: else ! 2159: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); ! 2160: #else ! 2161: nregs_rtx = const0_rtx; ! 2162: #endif ! 2163: ! 2164: vec = gen_rtvec (2, ! 2165: gen_rtx (SET, VOIDmode, operands[0], ! 2166: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)), ! 2167: gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31))); ! 2168: ! 2169: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec)); ! 2170: DONE; ! 2171: }") ! 2172: ! 2173: (define_insn "" ! 2174: [(set (match_operand 0 "" "=rf") ! 2175: (call (match_operand:SI 1 "memory_operand" "m") ! 2176: (match_operand 2 "" "i"))) ! 2177: (use (reg:SI 31))] ! 2178: ;;- Don't use operand 2 for most machines. ! 2179: "" ! 2180: "* ! 2181: { ! 2182: /* strip the MEM. */ ! 2183: operands[1] = XEXP (operands[1], 0); ! 2184: CC_STATUS_INIT; ! 2185: if (TARGET_SUN_ASM && GET_CODE (operands[1]) == REG) ! 2186: return \"jmpl %a1,%%o7\;nop\"; ! 2187: return \"call %a1,%2\;nop\"; ! 2188: }") ! 2189: ! 2190: (define_peephole ! 2191: [(set (match_operand:SI 0 "register_operand" "=r") ! 2192: (match_operand:SI 1 "single_insn_src_p" "p")) ! 2193: (parallel [(set (match_operand 2 "" "=rf") ! 2194: (call (match_operand:SI 3 "memory_operand" "m") ! 2195: (match_operand 4 "" "i"))) ! 2196: (use (reg:SI 31))])] ! 2197: ;;- Don't use operand 4 for most machines. ! 2198: "! reg_mentioned_p (operands[0], operands[3])" ! 2199: "* ! 2200: { ! 2201: /* strip the MEM. */ ! 2202: operands[3] = XEXP (operands[3], 0); ! 2203: if (TARGET_SUN_ASM && GET_CODE (operands[3]) == REG) ! 2204: return output_delayed_branch (\"jmpl %a3,%%o7\", operands, insn); ! 2205: return output_delayed_branch (\"call %a3,%4\", operands, insn); ! 2206: }") ! 2207: ! 2208: (define_peephole ! 2209: [(set (match_operand:SI 0 "memory_operand" "=m") ! 2210: (match_operand:SI 1 "reg_or_0_operand" "rJ")) ! 2211: (parallel [(set (match_operand 2 "" "=rf") ! 2212: (call (match_operand:SI 3 "memory_operand" "m") ! 2213: (match_operand 4 "" "i"))) ! 2214: (use (reg:SI 31))])] ! 2215: ;;- Don't use operand 4 for most machines. ! 2216: "" ! 2217: "* ! 2218: { ! 2219: /* strip the MEM. */ ! 2220: operands[3] = XEXP (operands[3], 0); ! 2221: if (TARGET_SUN_ASM && GET_CODE (operands[3]) == REG) ! 2222: return output_delayed_branch (\"jmpl %a3,%%o7\", operands, insn); ! 2223: return output_delayed_branch (\"call %a3,%4\", operands, insn); ! 2224: }") ! 2225: ! 2226: (define_insn "return" ! 2227: [(return)] ! 2228: "! TARGET_EPILOGUE" ! 2229: "ret\;restore") ! 2230: ! 2231: (define_peephole ! 2232: [(set (reg:SI 24) ! 2233: (match_operand:SI 0 "reg_or_0_operand" "rJ")) ! 2234: (return)] ! 2235: "! TARGET_EPILOGUE" ! 2236: "ret\;restore %r0,0x0,%%o0") ! 2237: ! 2238: (define_peephole ! 2239: [(set (reg:SI 24) ! 2240: (plus:SI (match_operand:SI 0 "register_operand" "r%") ! 2241: (match_operand:SI 1 "arith_operand" "rI"))) ! 2242: (return)] ! 2243: "! TARGET_EPILOGUE" ! 2244: "ret\;restore %r0,%1,%%o0") ! 2245: ! 2246: (define_peephole ! 2247: [(set (reg:SI 24) ! 2248: (minus:SI (match_operand:SI 0 "register_operand" "r") ! 2249: (match_operand:SI 1 "small_int" "I"))) ! 2250: (return)] ! 2251: "! TARGET_EPILOGUE" ! 2252: "ret\;restore %0,-(%1),%%o0") ! 2253: ! 2254: (define_insn "nop" ! 2255: [(const_int 0)] ! 2256: "" ! 2257: "nop") ! 2258: ! 2259: ;;- Local variables: ! 2260: ;;- mode:emacs-lisp ! 2261: ;;- comment-start: ";;- " ! 2262: ;;- eval: (set-syntax-table (copy-sequence (syntax-table))) ! 2263: ;;- eval: (modify-syntax-entry ?[ "(]") ! 2264: ;;- eval: (modify-syntax-entry ?] ")[") ! 2265: ;;- eval: (modify-syntax-entry ?{ "(}") ! 2266: ;;- eval: (modify-syntax-entry ?} "){") ! 2267: ;;- End: ! 2268:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.