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