|
|
1.1 ! root 1: ;;- Machine description for SPARC chip for GNU C compiler ! 2: ;; Copyright (C) 1987, 1988, 1989, 1992 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 2, 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: ;; Insn type. Used to default other attribute values. ! 25: ! 26: ;; type "unary" insns have one input operand (1) and one output operand (0) ! 27: ;; type "binary" insns have two input operands (1,2) and one output (0) ! 28: ;; type "compare" insns have one or two input operands (0,1) and no output ! 29: ;; type "call_no_delay_slot" is a call followed by an unimp instruction. ! 30: ! 31: (define_attr "type" ! 32: "move,unary,binary,compare,load,store,branch,call,call_no_delay_slot,address,fpload,fpstore,fp,fpcmp,fpmul,fpdiv,fpsqrt,multi,misc" ! 33: (const_string "binary")) ! 34: ! 35: ;; Set true if insn uses call-clobbered intermediate register. ! 36: (define_attr "use_clobbered" "false,true" ! 37: (if_then_else (and (eq_attr "type" "address") ! 38: (match_operand 0 "clobbered_register" "")) ! 39: (const_string "true") ! 40: (const_string "false"))) ! 41: ! 42: ;; Length (in # of insns). ! 43: (define_attr "length" "" ! 44: (cond [(eq_attr "type" "load,fpload") ! 45: (if_then_else (match_operand 1 "symbolic_memory_operand" "") ! 46: (const_int 2) (const_int 1)) ! 47: ! 48: (eq_attr "type" "store,fpstore") ! 49: (if_then_else (match_operand 0 "symbolic_memory_operand" "") ! 50: (const_int 2) (const_int 1)) ! 51: ! 52: (eq_attr "type" "address") (const_int 2) ! 53: ! 54: (eq_attr "type" "binary") ! 55: (if_then_else (ior (match_operand 2 "arith_operand" "") ! 56: (match_operand 2 "arith_double_operand" "")) ! 57: (const_int 1) (const_int 3)) ! 58: ! 59: (eq_attr "type" "move,unary") ! 60: (if_then_else (ior (match_operand 1 "arith_operand" "") ! 61: (match_operand 1 "arith_double_operand" "")) ! 62: (const_int 1) (const_int 2))] ! 63: ! 64: (const_int 1))) ! 65: ! 66: (define_asm_attributes ! 67: [(set_attr "length" "1") ! 68: (set_attr "type" "multi")]) ! 69: ! 70: ;; Attributes for instruction and branch scheduling ! 71: ! 72: (define_attr "in_call_delay" "false,true" ! 73: (cond [(eq_attr "type" "branch,call,call_no_delay_slot,multi") ! 74: (const_string "false") ! 75: (eq_attr "type" "load,fpload,store,fpstore") ! 76: (if_then_else (eq_attr "length" "1") ! 77: (const_string "true") ! 78: (const_string "false")) ! 79: (eq_attr "type" "address") ! 80: (if_then_else (eq_attr "use_clobbered" "false") ! 81: (const_string "true") ! 82: (const_string "false"))] ! 83: (if_then_else (eq_attr "length" "1") ! 84: (const_string "true") ! 85: (const_string "false")))) ! 86: ! 87: (define_delay (eq_attr "type" "call") ! 88: [(eq_attr "in_call_delay" "true") (nil) (nil)]) ! 89: ! 90: ;; ??? Should implement the notion of predelay slots for floating point ! 91: ;; branches. This would allow us to remove the nop always inserted before ! 92: ;; a floating point branch. ! 93: ! 94: (define_attr "in_branch_delay" "false,true" ! 95: (if_then_else (and (eq_attr "type" "!branch,call,call_no_delay_slot,multi") ! 96: (eq_attr "length" "1")) ! 97: (const_string "true") ! 98: (const_string "false"))) ! 99: ! 100: (define_delay (eq_attr "type" "branch") ! 101: [(eq_attr "in_branch_delay" "true") ! 102: (nil) (eq_attr "in_branch_delay" "true")]) ! 103: ! 104: ;; Function units of the SPARC ! 105: ! 106: ;; (define_function_unit {name} {num-units} {n-users} {test} ! 107: ;; {ready-delay} {busy-delay} [{conflict-list}]) ! 108: ! 109: ;; The integer ALU. ! 110: ;; (Noted only for documentation; units that take one cycle do not need to ! 111: ;; be specified.) ! 112: ! 113: ;; (define_function_unit "alu" 1 0 ! 114: ;; (eq_attr "type" "unary,binary,move,address") 1 0) ! 115: ! 116: ;; Memory with load-delay of 1 (i.e., 2 cycle load). ! 117: (define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0) ! 118: ! 119: ;; SPARC has two floating-point units: the FP ALU, ! 120: ;; and the FP MUL/DIV/SQRT unit. ! 121: ;; Instruction timings on the CY7C602 are as follows ! 122: ;; FABSs 4 ! 123: ;; FADDs/d 5/5 ! 124: ;; FCMPs/d 4/4 ! 125: ;; FDIVs/d 23/37 ! 126: ;; FMOVs 4 ! 127: ;; FMULs/d 5/7 ! 128: ;; FNEGs 4 ! 129: ;; FSQRTs/d 34/63 ! 130: ;; FSUBs/d 5/5 ! 131: ;; FdTOi/s 5/5 ! 132: ;; FsTOi/d 5/5 ! 133: ;; FiTOs/d 9/5 ! 134: ! 135: ;; The CY7C602 can only support 2 fp isnsn simultaneously. ! 136: ;; More insns cause the chip to stall. Until we handle this ! 137: ;; better in the scheduler, we use excess cycle times to ! 138: ;; more evenly spread out fp insns. ! 139: ! 140: (define_function_unit "fp_alu" 1 2 (eq_attr "type" "fp") 8 0) ! 141: (define_function_unit "fp_mul" 1 2 (eq_attr "type" "fpmul") 10 0) ! 142: (define_function_unit "fp_div" 1 2 (eq_attr "type" "fpdiv") 23 0) ! 143: (define_function_unit "fp_sqrt" 1 2 (eq_attr "type" "fpsqrt") 34 0) ! 144: ! 145: ;; Compare instructions. ! 146: ;; This controls RTL generation and register allocation. ! 147: ! 148: ;; We generate RTL for comparisons and branches by having the cmpxx ! 149: ;; patterns store away the operands. Then, the scc and bcc patterns ! 150: ;; emit RTL for both the compare and the branch. ! 151: ;; ! 152: ;; We do this because we want to generate different code for an sne and ! 153: ;; seq insn. In those cases, if the second operand of the compare is not ! 154: ;; const0_rtx, we want to compute the xor of the two operands and test ! 155: ;; it against zero. ! 156: ;; ! 157: ;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match ! 158: ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc ! 159: ;; insns that actually require more than one machine instruction. ! 160: ! 161: ;; Put cmpsi first among compare insns so it matches two CONST_INT operands. ! 162: ! 163: (define_expand "cmpsi" ! 164: [(set (reg:CC 0) ! 165: (compare:CC (match_operand:SI 0 "register_operand" "") ! 166: (match_operand:SI 1 "arith_operand" "")))] ! 167: "" ! 168: " ! 169: { ! 170: sparc_compare_op0 = operands[0]; ! 171: sparc_compare_op1 = operands[1]; ! 172: DONE; ! 173: }") ! 174: ! 175: (define_expand "cmpsf" ! 176: [(set (reg:CCFP 0) ! 177: (compare:CCFP (match_operand:SF 0 "register_operand" "") ! 178: (match_operand:SF 1 "register_operand" "")))] ! 179: "" ! 180: " ! 181: { ! 182: sparc_compare_op0 = operands[0]; ! 183: sparc_compare_op1 = operands[1]; ! 184: DONE; ! 185: }") ! 186: ! 187: (define_expand "cmpdf" ! 188: [(set (reg:CCFP 0) ! 189: (compare:CCFP (match_operand:DF 0 "register_operand" "") ! 190: (match_operand:DF 1 "register_operand" "")))] ! 191: "" ! 192: " ! 193: { ! 194: sparc_compare_op0 = operands[0]; ! 195: sparc_compare_op1 = operands[1]; ! 196: DONE; ! 197: }") ! 198: ! 199: ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this ! 200: ;; without jumps using the addx/subx instructions. For the rest, we do ! 201: ;; branches. Seq_special and sne_special clobber the CC reg, because they ! 202: ;; generate addcc/subcc instructions. ! 203: ! 204: (define_expand "seq_special" ! 205: [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "") ! 206: (match_operand:SI 2 "register_operand" ""))) ! 207: (parallel [(set (match_operand:SI 0 "register_operand" "") ! 208: (eq:SI (match_dup 3) (const_int 0))) ! 209: (clobber (reg:CC 0))])] ! 210: ! 211: "" ! 212: "{ operands[3] = gen_reg_rtx (SImode); }") ! 213: ! 214: (define_expand "sne_special" ! 215: [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "") ! 216: (match_operand:SI 2 "register_operand" ""))) ! 217: (parallel [(set (match_operand:SI 0 "register_operand" "") ! 218: (ne:SI (match_dup 3) (const_int 0))) ! 219: (clobber (reg:CC 0))])] ! 220: "" ! 221: "{ operands[3] = gen_reg_rtx (SImode); }") ! 222: ! 223: (define_expand "seq" ! 224: [(set (match_operand:SI 0 "register_operand" "") ! 225: (eq:SI (match_dup 1) (const_int 0)))] ! 226: "" ! 227: " ! 228: { if (GET_MODE (sparc_compare_op0) == SImode) ! 229: { ! 230: emit_insn (gen_seq_special (operands[0], sparc_compare_op0, ! 231: sparc_compare_op1)); ! 232: DONE; ! 233: } ! 234: else ! 235: operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); ! 236: }") ! 237: ! 238: (define_expand "sne" ! 239: [(set (match_operand:SI 0 "register_operand" "") ! 240: (ne:SI (match_dup 1) (const_int 0)))] ! 241: "" ! 242: " ! 243: { if (GET_MODE (sparc_compare_op0) == SImode) ! 244: { ! 245: emit_insn (gen_sne_special (operands[0], sparc_compare_op0, ! 246: sparc_compare_op1)); ! 247: DONE; ! 248: } ! 249: else ! 250: operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); ! 251: }") ! 252: ! 253: (define_expand "sgt" ! 254: [(set (match_operand:SI 0 "register_operand" "") ! 255: (gt:SI (match_dup 1) (const_int 0)))] ! 256: "" ! 257: " ! 258: { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }") ! 259: ! 260: (define_expand "slt" ! 261: [(set (match_operand:SI 0 "register_operand" "") ! 262: (lt:SI (match_dup 1) (const_int 0)))] ! 263: "" ! 264: " ! 265: { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }") ! 266: ! 267: (define_expand "sge" ! 268: [(set (match_operand:SI 0 "register_operand" "") ! 269: (ge:SI (match_dup 1) (const_int 0)))] ! 270: "" ! 271: " ! 272: { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }") ! 273: ! 274: (define_expand "sle" ! 275: [(set (match_operand:SI 0 "register_operand" "") ! 276: (le:SI (match_dup 1) (const_int 0)))] ! 277: "" ! 278: " ! 279: { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }") ! 280: ! 281: (define_expand "sgtu" ! 282: [(set (match_operand:SI 0 "register_operand" "") ! 283: (gtu:SI (match_dup 1) (const_int 0)))] ! 284: "" ! 285: " ! 286: { ! 287: rtx tem; ! 288: ! 289: /* We can do ltu easily, so if both operands are registers, swap them and ! 290: do a LTU. */ ! 291: if ((GET_CODE (sparc_compare_op0) == REG ! 292: || GET_CODE (sparc_compare_op0) == SUBREG) ! 293: && (GET_CODE (sparc_compare_op1) == REG ! 294: || GET_CODE (sparc_compare_op1) == SUBREG)) ! 295: { ! 296: tem = sparc_compare_op0; ! 297: sparc_compare_op0 = sparc_compare_op1; ! 298: sparc_compare_op1 = tem; ! 299: emit_insn (gen_sltu (operands[0])); ! 300: DONE; ! 301: } ! 302: ! 303: operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); ! 304: }") ! 305: ! 306: (define_expand "sltu" ! 307: [(set (match_operand:SI 0 "register_operand" "") ! 308: (ltu:SI (match_dup 1) (const_int 0)))] ! 309: "" ! 310: " ! 311: { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); ! 312: }") ! 313: ! 314: (define_expand "sgeu" ! 315: [(set (match_operand:SI 0 "register_operand" "") ! 316: (geu:SI (match_dup 1) (const_int 0)))] ! 317: "" ! 318: " ! 319: { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); ! 320: }") ! 321: ! 322: (define_expand "sleu" ! 323: [(set (match_operand:SI 0 "register_operand" "") ! 324: (leu:SI (match_dup 1) (const_int 0)))] ! 325: "" ! 326: " ! 327: { ! 328: rtx tem; ! 329: ! 330: /* We can do geu easily, so if both operands are registers, swap them and ! 331: do a GEU. */ ! 332: if ((GET_CODE (sparc_compare_op0) == REG ! 333: || GET_CODE (sparc_compare_op0) == SUBREG) ! 334: && (GET_CODE (sparc_compare_op1) == REG ! 335: || GET_CODE (sparc_compare_op1) == SUBREG)) ! 336: { ! 337: tem = sparc_compare_op0; ! 338: sparc_compare_op0 = sparc_compare_op1; ! 339: sparc_compare_op1 = tem; ! 340: emit_insn (gen_sgeu (operands[0])); ! 341: DONE; ! 342: } ! 343: ! 344: operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); ! 345: }") ! 346: ! 347: ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares. ! 348: ! 349: (define_insn "" ! 350: [(set (reg:CC 0) ! 351: (compare:CC (match_operand:SI 0 "register_operand" "rJ") ! 352: (match_operand:SI 1 "arith_operand" "rI")))] ! 353: "" ! 354: "cmp %r0,%1" ! 355: [(set_attr "type" "compare")]) ! 356: ! 357: (define_insn "" ! 358: [(set (reg:CCFP 0) ! 359: (compare:CCFP (match_operand:DF 0 "register_operand" "f") ! 360: (match_operand:DF 1 "register_operand" "f")))] ! 361: "" ! 362: "fcmped %0,%1" ! 363: [(set_attr "type" "fpcmp")]) ! 364: ! 365: (define_insn "" ! 366: [(set (reg:CCFP 0) ! 367: (compare:CCFP (match_operand:SF 0 "register_operand" "f") ! 368: (match_operand:SF 1 "register_operand" "f")))] ! 369: "" ! 370: "fcmpes %0,%1" ! 371: [(set_attr "type" "fpcmp")]) ! 372: ! 373: ;; The SEQ and SNE patterns are special because they can be done ! 374: ;; without any branching and do not involve a COMPARE. ! 375: ! 376: (define_insn "" ! 377: [(set (match_operand:SI 0 "register_operand" "=r") ! 378: (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) ! 379: (clobber (reg:CC 0))] ! 380: "" ! 381: "subcc %%g0,%1,%%g0\;addx %%g0,0,%0" ! 382: [(set_attr "type" "unary") ! 383: (set_attr "length" "2")]) ! 384: ! 385: (define_insn "" ! 386: [(set (match_operand:SI 0 "register_operand" "=r") ! 387: (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") ! 388: (const_int 0)))) ! 389: (clobber (reg:CC 0))] ! 390: "" ! 391: "subcc %%g0,%1,%%g0\;subx %%g0,0,%0" ! 392: [(set_attr "type" "unary") ! 393: (set_attr "length" "2")]) ! 394: ! 395: (define_insn "" ! 396: [(set (match_operand:SI 0 "register_operand" "=r") ! 397: (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) ! 398: (clobber (reg:CC 0))] ! 399: "" ! 400: "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0" ! 401: [(set_attr "type" "unary") ! 402: (set_attr "length" "2")]) ! 403: ! 404: (define_insn "" ! 405: [(set (match_operand:SI 0 "register_operand" "=r") ! 406: (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") ! 407: (const_int 0)))) ! 408: (clobber (reg:CC 0))] ! 409: "" ! 410: "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0" ! 411: [(set_attr "type" "unary") ! 412: (set_attr "length" "2")]) ! 413: ! 414: ;; We can also do (x + (i == 0)) and related, so put them in. ! 415: ! 416: (define_insn "" ! 417: [(set (match_operand:SI 0 "register_operand" "=r") ! 418: (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r") ! 419: (const_int 0)) ! 420: (match_operand:SI 2 "register_operand" "r"))) ! 421: (clobber (reg:CC 0))] ! 422: "" ! 423: "subcc %%g0,%1,%%g0\;addx %2,0,%0" ! 424: [(set_attr "length" "2")]) ! 425: ! 426: (define_insn "" ! 427: [(set (match_operand:SI 0 "register_operand" "=r") ! 428: (minus:SI (match_operand:SI 2 "register_operand" "r") ! 429: (ne:SI (match_operand:SI 1 "register_operand" "r") ! 430: (const_int 0)))) ! 431: (clobber (reg:CC 0))] ! 432: "" ! 433: "subcc %%g0,%1,%%g0\;subx %2,0,%0" ! 434: [(set_attr "length" "2")]) ! 435: ! 436: (define_insn "" ! 437: [(set (match_operand:SI 0 "register_operand" "=r") ! 438: (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") ! 439: (const_int 0)) ! 440: (match_operand:SI 2 "register_operand" "r"))) ! 441: (clobber (reg:CC 0))] ! 442: "" ! 443: "subcc %%g0,%1,%%g0\;subx %2,-1,%0" ! 444: [(set_attr "length" "2")]) ! 445: ! 446: (define_insn "" ! 447: [(set (match_operand:SI 0 "register_operand" "=r") ! 448: (minus:SI (match_operand:SI 2 "register_operand" "r") ! 449: (eq:SI (match_operand:SI 1 "register_operand" "r") ! 450: (const_int 0)))) ! 451: (clobber (reg:CC 0))] ! 452: "" ! 453: "subcc %%g0,%1,%%g0\;addx %2,-1,%0" ! 454: [(set_attr "type" "unary") ! 455: (set_attr "length" "2")]) ! 456: ! 457: ;; We can also do GEU and LTU directly, but these operate after a ! 458: ;; compare. ! 459: ! 460: (define_insn "" ! 461: [(set (match_operand:SI 0 "register_operand" "=r") ! 462: (ltu:SI (reg:CC 0) (const_int 0)))] ! 463: "" ! 464: "addx %%g0,0,%0" ! 465: [(set_attr "type" "misc")]) ! 466: ! 467: (define_insn "" ! 468: [(set (match_operand:SI 0 "register_operand" "=r") ! 469: (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))] ! 470: "" ! 471: "subx %%g0,0,%0" ! 472: [(set_attr "type" "misc")]) ! 473: ! 474: ;; ??? Combine should canonicalize these next two to the same pattern. ! 475: (define_insn "" ! 476: [(set (match_operand:SI 0 "register_operand" "=r") ! 477: (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0))) ! 478: (match_operand:SI 1 "arith_operand" "rI")))] ! 479: "" ! 480: "subx %%g0,%1,%0" ! 481: [(set_attr "type" "unary")]) ! 482: ! 483: (define_insn "" ! 484: [(set (match_operand:SI 0 "register_operand" "=r") ! 485: (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) ! 486: (match_operand:SI 1 "arith_operand" "rI"))))] ! 487: "" ! 488: "subx %%g0,%1,%0" ! 489: [(set_attr "type" "unary")]) ! 490: ! 491: (define_insn "" ! 492: [(set (match_operand:SI 0 "register_operand" "=r") ! 493: (geu:SI (reg:CC 0) (const_int 0)))] ! 494: "" ! 495: "subx %%g0,-1,%0" ! 496: [(set_attr "type" "misc")]) ! 497: ! 498: (define_insn "" ! 499: [(set (match_operand:SI 0 "register_operand" "=r") ! 500: (neg:SI (geu:SI (reg:CC 0) (const_int 0))))] ! 501: "" ! 502: "addx %%g0,-1,%0" ! 503: [(set_attr "type" "misc")]) ! 504: ! 505: ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. ! 506: ! 507: (define_insn "" ! 508: [(set (match_operand:SI 0 "register_operand" "=r") ! 509: (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) ! 510: (match_operand:SI 1 "arith_operand" "rI")))] ! 511: "" ! 512: "addx %%g0,%1,%0" ! 513: [(set_attr "type" "unary")]) ! 514: ! 515: (define_insn "" ! 516: [(set (match_operand:SI 0 "register_operand" "=r") ! 517: (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) ! 518: (plus:SI (match_operand:SI 1 "arith_operand" "%r") ! 519: (match_operand:SI 2 "arith_operand" "rI"))))] ! 520: "" ! 521: "addx %1,%2,%0" ! 522: [(set_attr "type" "binary")]) ! 523: ! 524: (define_insn "" ! 525: [(set (match_operand:SI 0 "register_operand" "=r") ! 526: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 527: (ltu:SI (reg:CC 0) (const_int 0))))] ! 528: "" ! 529: "subx %1,0,%0" ! 530: [(set_attr "type" "unary")]) ! 531: ! 532: ;; ??? Combine should canonicalize these next two to the same pattern. ! 533: (define_insn "" ! 534: [(set (match_operand:SI 0 "register_operand" "=r") ! 535: (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") ! 536: (match_operand:SI 2 "arith_operand" "rI")) ! 537: (ltu:SI (reg:CC 0) (const_int 0))))] ! 538: "" ! 539: "subx %1,%2,%0" ! 540: [(set_attr "type" "binary")]) ! 541: ! 542: (define_insn "" ! 543: [(set (match_operand:SI 0 "register_operand" "=r") ! 544: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 545: (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) ! 546: (match_operand:SI 2 "arith_operand" "rI"))))] ! 547: "" ! 548: "subx %1,%2,%0" ! 549: [(set_attr "type" "binary")]) ! 550: ! 551: (define_insn "" ! 552: [(set (match_operand:SI 0 "register_operand" "=r") ! 553: (plus:SI (geu:SI (reg:CC 0) (const_int 0)) ! 554: (match_operand:SI 1 "register_operand" "r")))] ! 555: "" ! 556: "subx %1,-1,%0" ! 557: [(set_attr "type" "unary")]) ! 558: ! 559: (define_insn "" ! 560: [(set (match_operand:SI 0 "register_operand" "=r") ! 561: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 562: (geu:SI (reg:CC 0) (const_int 0))))] ! 563: "" ! 564: "addx %1,-1,%0" ! 565: [(set_attr "type" "unary")]) ! 566: ! 567: ;; Now we have the generic scc insns. These will be done using a jump. ! 568: ;; We have to exclude the cases above, since we will not want combine to ! 569: ;; turn something that does not require a jump into something that does. ! 570: (define_insn "" ! 571: [(set (match_operand:SI 0 "register_operand" "=r") ! 572: (match_operator:SI 1 "normal_comp_operator" [(reg 0) (const_int 0)]))] ! 573: "" ! 574: "* return output_scc_insn (operands, insn); " ! 575: [(set_attr "type" "multi")]) ! 576: ! 577: ;; These control RTL generation for conditional jump insns ! 578: ! 579: (define_expand "beq" ! 580: [(set (pc) ! 581: (if_then_else (eq (match_dup 1) (const_int 0)) ! 582: (label_ref (match_operand 0 "" "")) ! 583: (pc)))] ! 584: "" ! 585: " ! 586: { operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }") ! 587: ! 588: (define_expand "bne" ! 589: [(set (pc) ! 590: (if_then_else (ne (match_dup 1) (const_int 0)) ! 591: (label_ref (match_operand 0 "" "")) ! 592: (pc)))] ! 593: "" ! 594: " ! 595: { operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }") ! 596: ! 597: (define_expand "bgt" ! 598: [(set (pc) ! 599: (if_then_else (gt (match_dup 1) (const_int 0)) ! 600: (label_ref (match_operand 0 "" "")) ! 601: (pc)))] ! 602: "" ! 603: " ! 604: { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }") ! 605: ! 606: (define_expand "bgtu" ! 607: [(set (pc) ! 608: (if_then_else (gtu (match_dup 1) (const_int 0)) ! 609: (label_ref (match_operand 0 "" "")) ! 610: (pc)))] ! 611: "" ! 612: " ! 613: { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1); ! 614: }") ! 615: ! 616: (define_expand "blt" ! 617: [(set (pc) ! 618: (if_then_else (lt (match_dup 1) (const_int 0)) ! 619: (label_ref (match_operand 0 "" "")) ! 620: (pc)))] ! 621: "" ! 622: " ! 623: { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }") ! 624: ! 625: (define_expand "bltu" ! 626: [(set (pc) ! 627: (if_then_else (ltu (match_dup 1) (const_int 0)) ! 628: (label_ref (match_operand 0 "" "")) ! 629: (pc)))] ! 630: "" ! 631: " ! 632: { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); ! 633: }") ! 634: ! 635: (define_expand "bge" ! 636: [(set (pc) ! 637: (if_then_else (ge (match_dup 1) (const_int 0)) ! 638: (label_ref (match_operand 0 "" "")) ! 639: (pc)))] ! 640: "" ! 641: " ! 642: { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }") ! 643: ! 644: (define_expand "bgeu" ! 645: [(set (pc) ! 646: (if_then_else (geu (match_dup 1) (const_int 0)) ! 647: (label_ref (match_operand 0 "" "")) ! 648: (pc)))] ! 649: "" ! 650: " ! 651: { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); ! 652: }") ! 653: ! 654: (define_expand "ble" ! 655: [(set (pc) ! 656: (if_then_else (le (match_dup 1) (const_int 0)) ! 657: (label_ref (match_operand 0 "" "")) ! 658: (pc)))] ! 659: "" ! 660: " ! 661: { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }") ! 662: ! 663: (define_expand "bleu" ! 664: [(set (pc) ! 665: (if_then_else (leu (match_dup 1) (const_int 0)) ! 666: (label_ref (match_operand 0 "" "")) ! 667: (pc)))] ! 668: "" ! 669: " ! 670: { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); ! 671: }") ! 672: ! 673: ;; Now match both normal and inverted jump. ! 674: ! 675: (define_insn "" ! 676: [(set (pc) ! 677: (if_then_else (match_operator 0 "noov_compare_op" ! 678: [(reg 0) (const_int 0)]) ! 679: (label_ref (match_operand 1 "" "")) ! 680: (pc)))] ! 681: "" ! 682: "* ! 683: { ! 684: return output_cbranch (operands[0], 1, 0, ! 685: final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! 686: ! final_sequence); ! 687: }" ! 688: [(set_attr "type" "branch")]) ! 689: ! 690: (define_insn "" ! 691: [(set (pc) ! 692: (if_then_else (match_operator 0 "noov_compare_op" ! 693: [(reg 0) (const_int 0)]) ! 694: (pc) ! 695: (label_ref (match_operand 1 "" ""))))] ! 696: "" ! 697: "* ! 698: { ! 699: return output_cbranch (operands[0], 1, 1, ! 700: final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! 701: ! final_sequence); ! 702: }" ! 703: [(set_attr "type" "branch")]) ! 704: ! 705: ;; Move instructions ! 706: ! 707: (define_expand "movsi" ! 708: [(set (match_operand:SI 0 "general_operand" "") ! 709: (match_operand:SI 1 "general_operand" ""))] ! 710: "" ! 711: " ! 712: { ! 713: if (emit_move_sequence (operands, SImode, 0)) ! 714: DONE; ! 715: }") ! 716: ! 717: (define_expand "reload_insi" ! 718: [(set (match_operand:SI 0 "register_operand" "=r") ! 719: (match_operand:SI 1 "general_operand" "")) ! 720: (clobber (match_operand:SI 2 "register_operand" "=&r"))] ! 721: "" ! 722: " ! 723: { ! 724: if (emit_move_sequence (operands, SImode, operands[2])) ! 725: DONE; ! 726: ! 727: /* We don't want the clobber emitted, so handle this ourselves. */ ! 728: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); ! 729: DONE; ! 730: }") ! 731: ! 732: ;; We must support both 'r' and 'f' registers here, because combine may ! 733: ;; convert SFmode hard registers to SImode hard registers when simplifying ! 734: ;; subreg sets. ! 735: ! 736: ;; We cannot combine the similar 'r' and 'f' constraints, because it causes ! 737: ;; problems with register allocation. Reload might try to put an interger ! 738: ;; in an fp register, or an fp number is an integer register. ! 739: ! 740: (define_insn "" ! 741: [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,Q,Q,rf") ! 742: (match_operand:SI 1 "move_operand" "rI,K,Q,!Q,rJ,!f,!fr"))] ! 743: "register_operand (operands[0], SImode) ! 744: || register_operand (operands[1], SImode) ! 745: || operands[1] == const0_rtx" ! 746: "@ ! 747: mov %1,%0 ! 748: sethi %%hi(%a1),%0 ! 749: ld %1,%0 ! 750: ld %1,%0 ! 751: st %r1,%0 ! 752: st %r1,%0 ! 753: st %r1,[%%fp-4]\;ld [%%fp-4],%0" ! 754: [(set_attr "type" "move,move,load,load,store,store,misc") ! 755: (set_attr "length" "*,1,*,*,*,*,2")]) ! 756: ! 757: ;; Special pic pattern, for loading the address of a label into a register. ! 758: ;; It clobbers o7 because the call puts the return address (i.e. pc value) ! 759: ;; there. ! 760: ! 761: (define_insn "" ! 762: [(set (match_operand:SI 0 "register_operand" "=r") ! 763: (match_operand:SI 1 "move_pic_label" "i")) ! 764: (set (reg:SI 15) (pc))] ! 765: "" ! 766: "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0" ! 767: [(set_attr "type" "multi") ! 768: (set_attr "length" "4")]) ! 769: ! 770: (define_insn "" ! 771: [(set (match_operand:DI 0 "register_operand" "=r") ! 772: (high:DI (match_operand 1 "" "")))] ! 773: "check_pic (1)" ! 774: "* ! 775: { ! 776: rtx op0 = operands[0]; ! 777: rtx op1 = operands[1]; ! 778: ! 779: if (GET_CODE (op1) == CONST_INT) ! 780: { ! 781: operands[0] = operand_subword (op0, 1, 0, DImode); ! 782: output_asm_insn (\"sethi %%hi(%a1),%0\", operands); ! 783: ! 784: operands[0] = operand_subword (op0, 0, 0, DImode); ! 785: if (INTVAL (op1) < 0) ! 786: output_asm_insn (\"mov -1,%0\", operands); ! 787: else ! 788: output_asm_insn (\"mov 0,%0\", operands); ! 789: } ! 790: else if (GET_CODE (op1) == CONST_DOUBLE) ! 791: { ! 792: operands[0] = operand_subword (op0, 1, 0, DImode); ! 793: operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1)); ! 794: output_asm_insn (\"sethi %%hi(%a1),%0\", operands); ! 795: ! 796: operands[0] = operand_subword (op0, 0, 0, DImode); ! 797: operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1)); ! 798: output_asm_insn (singlemove_string (operands), operands); ! 799: } ! 800: else ! 801: abort (); ! 802: }" ! 803: [(set_attr "type" "move") ! 804: (set_attr "length" "2")]) ! 805: ! 806: (define_insn "" ! 807: [(set (match_operand:SI 0 "register_operand" "=r") ! 808: (high:SI (match_operand 1 "" "")))] ! 809: "check_pic (1)" ! 810: "sethi %%hi(%a1),%0" ! 811: [(set_attr "type" "move") ! 812: (set_attr "length" "1")]) ! 813: ! 814: (define_insn "" ! 815: [(set (match_operand:HI 0 "register_operand" "=r") ! 816: (high:HI (match_operand 1 "" "")))] ! 817: "check_pic (1)" ! 818: "sethi %%hi(%a1),%0" ! 819: [(set_attr "type" "move") ! 820: (set_attr "length" "1")]) ! 821: ! 822: (define_insn "" ! 823: [(set (match_operand:DI 0 "register_operand" "=r") ! 824: (lo_sum:DI (match_operand:DI 1 "register_operand" "r") ! 825: (match_operand:DI 2 "immediate_operand" "in")))] ! 826: "" ! 827: "or %R1,%%lo(%a2),%R0" ! 828: ;; Need to set length for this arith insn because operand2 ! 829: ;; is not an "arith_operand". ! 830: [(set_attr "length" "1")]) ! 831: ! 832: (define_insn "" ! 833: [(set (match_operand:SI 0 "register_operand" "=r") ! 834: (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 835: (match_operand:SI 2 "immediate_operand" "in")))] ! 836: "" ! 837: "or %1,%%lo(%a2),%0" ! 838: ;; Need to set length for this arith insn because operand2 ! 839: ;; is not an "arith_operand". ! 840: [(set_attr "length" "1")]) ! 841: ! 842: (define_insn "" ! 843: [(set (mem:SI (match_operand:SI 0 "symbolic_operand" "")) ! 844: (match_operand:SI 1 "reg_or_0_operand" "rJ")) ! 845: (clobber (match_scratch:SI 2 "=&r"))] ! 846: "" ! 847: "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" ! 848: [(set_attr "type" "store") ! 849: (set_attr "length" "2")]) ! 850: ! 851: (define_expand "movhi" ! 852: [(set (match_operand:HI 0 "general_operand" "") ! 853: (match_operand:HI 1 "general_operand" ""))] ! 854: "" ! 855: " ! 856: { ! 857: if (emit_move_sequence (operands, HImode, 0)) ! 858: DONE; ! 859: }") ! 860: ! 861: (define_insn "" ! 862: [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") ! 863: (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))] ! 864: "register_operand (operands[0], HImode) ! 865: || register_operand (operands[1], HImode) ! 866: || operands[1] == const0_rtx" ! 867: "@ ! 868: mov %1,%0 ! 869: sethi %%hi(%a1),%0 ! 870: lduh %1,%0 ! 871: sth %r1,%0" ! 872: [(set_attr "type" "move,move,load,store") ! 873: (set_attr "length" "*,1,*,1")]) ! 874: ! 875: (define_insn "" ! 876: [(set (match_operand:HI 0 "register_operand" "=r") ! 877: (lo_sum:HI (match_operand:HI 1 "register_operand" "r") ! 878: (match_operand 2 "immediate_operand" "in")))] ! 879: "" ! 880: "or %1,%%lo(%a2),%0" ! 881: [(set_attr "length" "1")]) ! 882: ! 883: (define_insn "" ! 884: [(set (mem:HI (match_operand:SI 0 "symbolic_operand" "")) ! 885: (match_operand:HI 1 "reg_or_0_operand" "rJ")) ! 886: (clobber (match_scratch:SI 2 "=&r"))] ! 887: "" ! 888: "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]" ! 889: [(set_attr "type" "store") ! 890: (set_attr "length" "2")]) ! 891: ! 892: (define_expand "movqi" ! 893: [(set (match_operand:QI 0 "general_operand" "") ! 894: (match_operand:QI 1 "general_operand" ""))] ! 895: "" ! 896: " ! 897: { ! 898: if (emit_move_sequence (operands, QImode, 0)) ! 899: DONE; ! 900: }") ! 901: ! 902: (define_insn "" ! 903: [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") ! 904: (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))] ! 905: "register_operand (operands[0], QImode) ! 906: || register_operand (operands[1], QImode) ! 907: || operands[1] == const0_rtx" ! 908: "@ ! 909: mov %1,%0 ! 910: sethi %%hi(%a1),%0 ! 911: ldub %1,%0 ! 912: stb %r1,%0" ! 913: [(set_attr "type" "move,move,load,store") ! 914: (set_attr "length" "*,1,*,1")]) ! 915: ! 916: (define_insn "" ! 917: [(set (match_operand:QI 0 "register_operand" "=r") ! 918: (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") ! 919: (match_operand 2 "immediate_operand" "in")) 0))] ! 920: "" ! 921: "or %1,%%lo(%a2),%0" ! 922: [(set_attr "length" "1")]) ! 923: ! 924: (define_insn "" ! 925: [(set (mem:QI (match_operand:SI 0 "symbolic_operand" "")) ! 926: (match_operand:QI 1 "reg_or_0_operand" "rJ")) ! 927: (clobber (match_scratch:SI 2 "=&r"))] ! 928: "" ! 929: "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]" ! 930: [(set_attr "type" "store") ! 931: (set_attr "length" "2")]) ! 932: ! 933: ;; The definition of this insn does not really explain what it does, ! 934: ;; but it should suffice ! 935: ;; that anything generated as this insn will be recognized as one ! 936: ;; and that it will not successfully combine with anything. ! 937: (define_expand "movstrsi" ! 938: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) ! 939: (mem:BLK (match_operand:BLK 1 "general_operand" ""))) ! 940: (use (match_operand:SI 2 "arith32_operand" "")) ! 941: (use (match_operand:SI 3 "immediate_operand" "")) ! 942: (clobber (match_dup 0)) ! 943: (clobber (match_dup 1)) ! 944: (clobber (match_scratch:SI 4 "")) ! 945: (clobber (reg:SI 0)) ! 946: (clobber (reg:SI 1))])] ! 947: "" ! 948: " ! 949: { ! 950: if (GET_CODE (operands[2]) == CONST_INT ! 951: && GET_CODE (operands[3]) == CONST_INT ! 952: && INTVAL (operands[2]) / INTVAL (operands[3]) > 32) ! 953: FAIL; ! 954: ! 955: operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); ! 956: operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); ! 957: operands[2] = force_not_mem (operands[2]); ! 958: }") ! 959: ! 960: (define_insn "" ! 961: [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ! 962: (mem:BLK (match_operand:SI 1 "register_operand" "r"))) ! 963: (use (match_operand:SI 2 "arith32_operand" "rn")) ! 964: (use (match_operand:SI 3 "immediate_operand" "i")) ! 965: (clobber (match_dup 0)) ! 966: (clobber (match_dup 1)) ! 967: (clobber (match_scratch:SI 4 "=&r")) ! 968: (clobber (reg:SI 0)) ! 969: (clobber (reg:SI 1))] ! 970: "" ! 971: "* return output_block_move (operands);" ! 972: [(set_attr "type" "multi")]) ! 973: ! 974: ;; Floating point move insns ! 975: ! 976: ;; This pattern forces (set (reg:DF ...) (const_double ...)) ! 977: ;; to be reloaded by putting the constant into memory. ! 978: ;; It must come before the more general movdf pattern. ! 979: ;; ??? A similar pattern for SF mode values would also be useful, but it ! 980: ;; is not as easy to write. ! 981: (define_insn "" ! 982: [(set (match_operand:DF 0 "general_operand" "=?r,r,f,o") ! 983: (match_operand:DF 1 "" "?E,G,m,G"))] ! 984: "GET_CODE (operands[1]) == CONST_DOUBLE" ! 985: "* ! 986: { ! 987: switch (which_alternative) ! 988: { ! 989: case 0: ! 990: return output_move_double (operands); ! 991: case 1: ! 992: return \"mov %%g0,%0\;mov %%g0,%R0\"; ! 993: case 2: ! 994: return output_fp_move_double (operands); ! 995: case 3: ! 996: operands[1] = adj_offsettable_operand (operands[0], 4); ! 997: return \"st %%g0,%0\;st %%g0,%1\"; ! 998: } ! 999: }" ! 1000: [(set_attr "type" "load,move,fpload,store") ! 1001: (set_attr "length" "3,2,3,3")]) ! 1002: ! 1003: (define_expand "movdf" ! 1004: [(set (match_operand:DF 0 "general_operand" "") ! 1005: (match_operand:DF 1 "general_operand" ""))] ! 1006: "" ! 1007: " ! 1008: { ! 1009: if (emit_move_sequence (operands, DFmode, 0)) ! 1010: DONE; ! 1011: }") ! 1012: ! 1013: (define_insn "" ! 1014: [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r") ! 1015: (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))] ! 1016: "register_operand (operands[0], DFmode) ! 1017: || register_operand (operands[1], DFmode)" ! 1018: "* ! 1019: { ! 1020: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! 1021: return output_fp_move_double (operands); ! 1022: return output_move_double (operands); ! 1023: }" ! 1024: [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi") ! 1025: (set_attr "length" "2,2,3,3,3,3,3,3")]) ! 1026: ! 1027: (define_insn "" ! 1028: [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i")) ! 1029: (match_operand:DF 1 "reg_or_0_operand" "rf,G")) ! 1030: (clobber (match_scratch:SI 2 "=&r,&r"))] ! 1031: "" ! 1032: "* ! 1033: { ! 1034: output_asm_insn (\"sethi %%hi(%a0),%2\", operands); ! 1035: if (which_alternative == 0) ! 1036: return \"std %1,[%2+%%lo(%a0)]\"; ! 1037: else ! 1038: return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\"; ! 1039: }" ! 1040: [(set_attr "type" "store") ! 1041: (set_attr "length" "3")]) ! 1042: ! 1043: ;; Double-word move insns. ! 1044: ! 1045: (define_expand "movdi" ! 1046: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") ! 1047: (match_operand:DI 1 "general_operand" ""))] ! 1048: "" ! 1049: " ! 1050: { ! 1051: if (emit_move_sequence (operands, DImode, 0)) ! 1052: DONE; ! 1053: }") ! 1054: ! 1055: (define_insn "" ! 1056: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?f,?r,?Q") ! 1057: (match_operand:DI 1 "general_operand" "r,r,Q,i,r,f,Q,f,f"))] ! 1058: "register_operand (operands[0], DImode) ! 1059: || register_operand (operands[1], DImode) ! 1060: || operands[1] == const0_rtx" ! 1061: "* ! 1062: { ! 1063: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! 1064: return output_fp_move_double (operands); ! 1065: return output_move_double (operands); ! 1066: }" ! 1067: [(set_attr "type" "move,store,load,misc,multi,fp,fpload,multi,fpstore") ! 1068: (set_attr "length" "2,3,3,3,3,2,3,3,3")]) ! 1069: ! 1070: ;; Floating-point move insns. ! 1071: ! 1072: (define_expand "movsf" ! 1073: [(set (match_operand:SF 0 "general_operand" "") ! 1074: (match_operand:SF 1 "general_operand" ""))] ! 1075: "" ! 1076: " ! 1077: { ! 1078: if (emit_move_sequence (operands, SFmode, 0)) ! 1079: DONE; ! 1080: }") ! 1081: ! 1082: (define_insn "" ! 1083: [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,rf,f,r,Q,Q") ! 1084: (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,!rf,Q,Q,f,r"))] ! 1085: "register_operand (operands[0], SFmode) ! 1086: || register_operand (operands[1], SFmode)" ! 1087: "@ ! 1088: fmovs %1,%0 ! 1089: mov %1,%0 ! 1090: st %r1,[%%fp-4]\;ld [%%fp-4],%0 ! 1091: ld %1,%0 ! 1092: ld %1,%0 ! 1093: st %r1,%0 ! 1094: st %r1,%0" ! 1095: [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store") ! 1096: (set_attr "length" "*,*,2,*,*,*,*")]) ! 1097: ! 1098: (define_insn "" ! 1099: [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i")) ! 1100: (match_operand:SF 1 "reg_or_0_operand" "rfG")) ! 1101: (clobber (match_scratch:SI 2 "=&r"))] ! 1102: "" ! 1103: "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" ! 1104: [(set_attr "type" "store") ! 1105: (set_attr "length" "2")]) ! 1106: ! 1107: ;;- zero extension instructions ! 1108: ! 1109: ;; These patterns originally accepted general_operands, however, slightly ! 1110: ;; better code is generated by only accepting register_operands, and then ! 1111: ;; letting combine generate the ldu[hb] insns. ! 1112: ! 1113: (define_expand "zero_extendhisi2" ! 1114: [(set (match_operand:SI 0 "register_operand" "") ! 1115: (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] ! 1116: "" ! 1117: " ! 1118: { ! 1119: rtx temp = gen_reg_rtx (SImode); ! 1120: rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); ! 1121: ! 1122: if (GET_CODE (operand1) == SUBREG) ! 1123: operand1 = XEXP (operand1, 0); ! 1124: ! 1125: emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), ! 1126: shift_16)); ! 1127: emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); ! 1128: DONE; ! 1129: }") ! 1130: ! 1131: (define_insn "" ! 1132: [(set (match_operand:SI 0 "register_operand" "=r") ! 1133: (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] ! 1134: "" ! 1135: "lduh %1,%0" ! 1136: [(set_attr "type" "load")]) ! 1137: ! 1138: (define_expand "zero_extendqihi2" ! 1139: [(set (match_operand:HI 0 "register_operand" "") ! 1140: (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] ! 1141: "" ! 1142: "") ! 1143: ! 1144: (define_insn "" ! 1145: [(set (match_operand:HI 0 "register_operand" "=r,r,r") ! 1146: (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,I,Q")))] ! 1147: "GET_CODE (operands[1]) != CONST_INT" ! 1148: "@ ! 1149: and %1,0xff,%0; ! 1150: mov (%1 & 0xff),%0 ! 1151: ldub %1,%0" ! 1152: [(set_attr "type" "unary,move,load") ! 1153: (set_attr "length" "1")]) ! 1154: ! 1155: (define_expand "zero_extendqisi2" ! 1156: [(set (match_operand:SI 0 "register_operand" "") ! 1157: (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] ! 1158: "" ! 1159: "") ! 1160: ! 1161: (define_insn "" ! 1162: [(set (match_operand:SI 0 "register_operand" "=r,r,r") ! 1163: (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,I,Q")))] ! 1164: "GET_CODE (operands[1]) != CONST_INT" ! 1165: "@ ! 1166: and %1,0xff,%0 ! 1167: mov (%1 & 0xff),%0 ! 1168: ldub %1,%0" ! 1169: [(set_attr "type" "unary,move,load") ! 1170: (set_attr "length" "1")]) ! 1171: ! 1172: (define_insn "" ! 1173: [(set (reg:CC 0) ! 1174: (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) ! 1175: (const_int 0)))] ! 1176: "" ! 1177: "andcc %0,0xff,%%g0" ! 1178: [(set_attr "type" "compare")]) ! 1179: ! 1180: (define_insn "" ! 1181: [(set (reg:CC 0) ! 1182: (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) ! 1183: (const_int 0))) ! 1184: (set (match_operand:SI 0 "register_operand" "=r") ! 1185: (zero_extend:SI (match_dup 1)))] ! 1186: "" ! 1187: "andcc %1,0xff,%0" ! 1188: [(set_attr "type" "unary")]) ! 1189: ! 1190: ;;- sign extension instructions ! 1191: ! 1192: ;; These patterns originally accepted general_operands, however, slightly ! 1193: ;; better code is generated by only accepting register_operands, and then ! 1194: ;; letting combine generate the lds[hb] insns. ! 1195: ! 1196: (define_expand "extendhisi2" ! 1197: [(set (match_operand:SI 0 "register_operand" "") ! 1198: (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] ! 1199: "" ! 1200: " ! 1201: { ! 1202: rtx temp = gen_reg_rtx (SImode); ! 1203: rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); ! 1204: ! 1205: if (GET_CODE (operand1) == SUBREG) ! 1206: operand1 = XEXP (operand1, 0); ! 1207: ! 1208: emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), ! 1209: shift_16)); ! 1210: emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); ! 1211: DONE; ! 1212: }") ! 1213: ! 1214: (define_insn "" ! 1215: [(set (match_operand:SI 0 "register_operand" "=r") ! 1216: (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] ! 1217: "" ! 1218: "ldsh %1,%0" ! 1219: [(set_attr "type" "load")]) ! 1220: ! 1221: (define_expand "extendqihi2" ! 1222: [(set (match_operand:HI 0 "register_operand" "") ! 1223: (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] ! 1224: "" ! 1225: " ! 1226: { ! 1227: rtx temp = gen_reg_rtx (SImode); ! 1228: rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); ! 1229: ! 1230: if (GET_CODE (operand1) == SUBREG) ! 1231: operand1 = XEXP (operand1, 0); ! 1232: if (GET_CODE (operand0) == SUBREG) ! 1233: operand0 = XEXP (operand0, 0); ! 1234: emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), ! 1235: shift_24)); ! 1236: if (GET_MODE (operand0) != SImode) ! 1237: operand0 = gen_rtx (SUBREG, SImode, operand0, 0); ! 1238: emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); ! 1239: DONE; ! 1240: }") ! 1241: ! 1242: (define_insn "" ! 1243: [(set (match_operand:HI 0 "register_operand" "=r") ! 1244: (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] ! 1245: "" ! 1246: "ldsb %1,%0" ! 1247: [(set_attr "type" "load")]) ! 1248: ! 1249: (define_expand "extendqisi2" ! 1250: [(set (match_operand:SI 0 "register_operand" "") ! 1251: (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] ! 1252: "" ! 1253: " ! 1254: { ! 1255: rtx temp = gen_reg_rtx (SImode); ! 1256: rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); ! 1257: ! 1258: if (GET_CODE (operand1) == SUBREG) ! 1259: operand1 = XEXP (operand1, 0); ! 1260: emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), ! 1261: shift_24)); ! 1262: emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); ! 1263: DONE; ! 1264: }") ! 1265: ! 1266: (define_insn "" ! 1267: [(set (match_operand:SI 0 "register_operand" "=r") ! 1268: (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] ! 1269: "" ! 1270: "ldsb %1,%0" ! 1271: [(set_attr "type" "load")]) ! 1272: ! 1273: ;; Conversions between float and double. ! 1274: ! 1275: (define_insn "extendsfdf2" ! 1276: [(set (match_operand:DF 0 "register_operand" "=f") ! 1277: (float_extend:DF ! 1278: (match_operand:SF 1 "register_operand" "f")))] ! 1279: "" ! 1280: "fstod %1,%0" ! 1281: [(set_attr "type" "fp")]) ! 1282: ! 1283: (define_insn "truncdfsf2" ! 1284: [(set (match_operand:SF 0 "register_operand" "=f") ! 1285: (float_truncate:SF ! 1286: (match_operand:DF 1 "register_operand" "f")))] ! 1287: "" ! 1288: "fdtos %1,%0" ! 1289: [(set_attr "type" "fp")]) ! 1290: ! 1291: ;; Conversion between fixed point and floating point. ! 1292: ! 1293: (define_insn "floatsisf2" ! 1294: [(set (match_operand:SF 0 "general_operand" "=f") ! 1295: (float:SF (match_operand:SI 1 "nonimmediate_operand" "rfm")))] ! 1296: "" ! 1297: "* return output_floatsisf2 (operands);" ! 1298: [(set_attr "type" "fp") ! 1299: (set_attr "length" "3")]) ! 1300: ! 1301: (define_insn "floatsidf2" ! 1302: [(set (match_operand:DF 0 "general_operand" "=f") ! 1303: (float:DF (match_operand:SI 1 "nonimmediate_operand" "rfm")))] ! 1304: "" ! 1305: "* return output_floatsidf2 (operands);" ! 1306: [(set_attr "type" "fp") ! 1307: (set_attr "length" "3")]) ! 1308: ! 1309: ;; Convert a float to an actual integer. ! 1310: ;; Truncation is performed as part of the conversion. ! 1311: ! 1312: (define_insn "fix_truncsfsi2" ! 1313: [(set (match_operand:SI 0 "general_operand" "=rm") ! 1314: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))) ! 1315: (clobber (match_scratch:SF 2 "=&f"))] ! 1316: "" ! 1317: "* ! 1318: { ! 1319: if (FP_REG_P (operands[1])) ! 1320: output_asm_insn (\"fstoi %1,%2\", operands); ! 1321: else ! 1322: output_asm_insn (\"ld %1,%2\;fstoi %2,%2\", operands); ! 1323: if (GET_CODE (operands[0]) == MEM) ! 1324: return \"st %2,%0\"; ! 1325: else ! 1326: return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\"; ! 1327: }" ! 1328: [(set_attr "type" "fp") ! 1329: (set_attr "length" "3")]) ! 1330: ! 1331: (define_insn "fix_truncdfsi2" ! 1332: [(set (match_operand:SI 0 "general_operand" "=rm") ! 1333: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))) ! 1334: (clobber (match_scratch:DF 2 "=&f"))] ! 1335: "" ! 1336: "* ! 1337: { ! 1338: if (FP_REG_P (operands[1])) ! 1339: output_asm_insn (\"fdtoi %1,%2\", operands); ! 1340: else ! 1341: { ! 1342: rtx xoperands[3]; ! 1343: xoperands[0] = operands[2]; ! 1344: xoperands[1] = operands[1]; ! 1345: output_asm_insn (output_fp_move_double (xoperands), xoperands); ! 1346: output_asm_insn (\"fdtoi %2,%2\", operands); ! 1347: } ! 1348: if (GET_CODE (operands[0]) == MEM) ! 1349: return \"st %2,%0\"; ! 1350: else ! 1351: return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\"; ! 1352: }" ! 1353: [(set_attr "type" "fp") ! 1354: (set_attr "length" "3")]) ! 1355: ! 1356: ;;- arithmetic instructions ! 1357: ! 1358: (define_insn "adddi3" ! 1359: [(set (match_operand:DI 0 "register_operand" "=r") ! 1360: (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") ! 1361: (match_operand:DI 2 "arith_double_operand" "rHI"))) ! 1362: (clobber (reg:SI 0))] ! 1363: "" ! 1364: "* ! 1365: { ! 1366: rtx op2 = operands[2]; ! 1367: ! 1368: /* If constant is postive, upper bits zeroed, otherwise unchanged ! 1369: * give the assembler a chance to pick the move instruction. */ ! 1370: if (GET_CODE (op2) == CONST_INT) ! 1371: { ! 1372: int sign = INTVAL (op2); ! 1373: if (sign < 0) ! 1374: return \"addcc %R1,%2,%R0\;addx %1,-1,%0\"; ! 1375: return \"addcc %R1,%2,%R0\;addx %1,0,%0\"; ! 1376: } ! 1377: else if (GET_CODE (op2) == CONST_DOUBLE) ! 1378: { ! 1379: int sign = CONST_DOUBLE_HIGH (op2); ! 1380: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1381: CONST_DOUBLE_LOW (operands[1])); ! 1382: if (sign < 0) ! 1383: return \"addcc %R1,%2,%R0\;addx %1,-1,%0\"; ! 1384: return \"addcc %R1,%2,%R0\;addx %1,0,%0\"; ! 1385: } ! 1386: return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\"; ! 1387: }" ! 1388: [(set_attr "length" "2")]) ! 1389: ! 1390: (define_insn "addsi3" ! 1391: [(set (match_operand:SI 0 "register_operand" "=r") ! 1392: (plus:SI (match_operand:SI 1 "arith_operand" "%r") ! 1393: (match_operand:SI 2 "arith_operand" "rI")))] ! 1394: "" ! 1395: "add %1,%2,%0") ! 1396: ! 1397: (define_insn "" ! 1398: [(set (reg:CC_NOOV 0) ! 1399: (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") ! 1400: (match_operand:SI 1 "arith_operand" "rI")) ! 1401: (const_int 0)))] ! 1402: "" ! 1403: "addcc %0,%1,%%g0" ! 1404: [(set_attr "type" "compare")]) ! 1405: ! 1406: (define_insn "" ! 1407: [(set (reg:CC_NOOV 0) ! 1408: (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r") ! 1409: (match_operand:SI 2 "arith_operand" "rI")) ! 1410: (const_int 0))) ! 1411: (set (match_operand:SI 0 "register_operand" "=r") ! 1412: (plus:SI (match_dup 1) (match_dup 2)))] ! 1413: "" ! 1414: "addcc %1,%2,%0") ! 1415: ! 1416: (define_insn "subdi3" ! 1417: [(set (match_operand:DI 0 "register_operand" "=r") ! 1418: (minus:DI (match_operand:DI 1 "register_operand" "r") ! 1419: (match_operand:DI 2 "arith_double_operand" "rHI"))) ! 1420: (clobber (reg:SI 0))] ! 1421: "" ! 1422: "* ! 1423: { ! 1424: rtx op2 = operands[2]; ! 1425: ! 1426: /* If constant is postive, upper bits zeroed, otherwise unchanged ! 1427: * give the assembler a chance to pick the move instruction. */ ! 1428: if (GET_CODE (op2) == CONST_INT) ! 1429: { ! 1430: int sign = INTVAL (op2); ! 1431: if (sign < 0) ! 1432: return \"subcc %R1,%2,%R0\;subx %1,-1,%0\"; ! 1433: return \"subcc %R1,%2,%R0\;subx %1,0,%0\"; ! 1434: } ! 1435: else if (GET_CODE (op2) == CONST_DOUBLE) ! 1436: { ! 1437: int sign = CONST_DOUBLE_HIGH (op2); ! 1438: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1439: CONST_DOUBLE_LOW (operands[1])); ! 1440: if (sign < 0) ! 1441: return \"subcc %R1,%2,%R0\;subx %1,-1,%0\"; ! 1442: return \"subcc %R1,%2,%R0\;subx %1,0,%0\"; ! 1443: } ! 1444: return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\"; ! 1445: }" ! 1446: [(set_attr "length" "2")]) ! 1447: ! 1448: (define_insn "subsi3" ! 1449: [(set (match_operand:SI 0 "register_operand" "=r") ! 1450: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 1451: (match_operand:SI 2 "arith_operand" "rI")))] ! 1452: "" ! 1453: "sub %1,%2,%0") ! 1454: ! 1455: (define_insn "" ! 1456: [(set (reg:CC_NOOV 0) ! 1457: (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r") ! 1458: (match_operand:SI 1 "arith_operand" "rI")) ! 1459: (const_int 0)))] ! 1460: "" ! 1461: "subcc %0,%1,%%g0" ! 1462: [(set_attr "type" "compare")]) ! 1463: ! 1464: (define_insn "" ! 1465: [(set (reg:CC_NOOV 0) ! 1466: (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r") ! 1467: (match_operand:SI 2 "arith_operand" "rI")) ! 1468: (const_int 0))) ! 1469: (set (match_operand:SI 0 "register_operand" "=r") ! 1470: (minus:SI (match_dup 1) (match_dup 2)))] ! 1471: "" ! 1472: "subcc %1,%2,%0") ! 1473: ! 1474: ;;- and instructions ! 1475: ;; We define DImode `and` so with DImode `not` we can get ! 1476: ;; DImode `andn`. Other combinations are possible. ! 1477: ! 1478: (define_expand "anddi3" ! 1479: [(set (match_operand:DI 0 "register_operand" "") ! 1480: (and:DI (match_operand:DI 1 "arith_double_operand" "") ! 1481: (match_operand:DI 2 "arith_double_operand" "")))] ! 1482: "" ! 1483: "") ! 1484: ! 1485: (define_insn "" ! 1486: [(set (match_operand:DI 0 "register_operand" "=r") ! 1487: (and:DI (match_operand:DI 1 "arith_double_operand" "%r") ! 1488: (match_operand:DI 2 "arith_double_operand" "rHI")))] ! 1489: "" ! 1490: "* ! 1491: { ! 1492: rtx op2 = operands[2]; ! 1493: ! 1494: /* If constant is postive, upper bits zeroed, otherwise unchanged ! 1495: * give the assembler a chance to pick the move instruction. */ ! 1496: if (GET_CODE (op2) == CONST_INT) ! 1497: { ! 1498: int sign = INTVAL (op2); ! 1499: if (sign < 0) ! 1500: return \"mov %1,%0\;and %R1,%2,%R0\"; ! 1501: return \"mov 0,%0\;and %R1,%2,%R0\"; ! 1502: } ! 1503: else if (GET_CODE (op2) == CONST_DOUBLE) ! 1504: { ! 1505: int sign = CONST_DOUBLE_HIGH (op2); ! 1506: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1507: CONST_DOUBLE_LOW (operands[1])); ! 1508: if (sign < 0) ! 1509: return \"mov %1,%0\;and %R1,%2,%R0\"; ! 1510: return \"mov 0,%0\;and %R1,%2,%R0\"; ! 1511: } ! 1512: return \"and %1,%2,%0\;and %R1,%R2,%R0\"; ! 1513: }" ! 1514: [(set_attr "length" "2")]) ! 1515: ! 1516: (define_insn "andsi3" ! 1517: [(set (match_operand:SI 0 "register_operand" "=r") ! 1518: (and:SI (match_operand:SI 1 "arith_operand" "%r") ! 1519: (match_operand:SI 2 "arith_operand" "rI")))] ! 1520: "" ! 1521: "and %1,%2,%0") ! 1522: ! 1523: (define_insn "" ! 1524: [(set (match_operand:DI 0 "register_operand" "=r") ! 1525: (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) ! 1526: (match_operand:DI 2 "register_operand" "r")))] ! 1527: "" ! 1528: "andn %2,%1,%0\;andn %R2,%R1,%R0" ! 1529: [(set_attr "length" "2")]) ! 1530: ! 1531: (define_insn "" ! 1532: [(set (match_operand:SI 0 "register_operand" "=r") ! 1533: (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) ! 1534: (match_operand:SI 2 "register_operand" "r")))] ! 1535: "" ! 1536: "andn %2,%1,%0") ! 1537: ! 1538: (define_expand "iordi3" ! 1539: [(set (match_operand:DI 0 "register_operand" "") ! 1540: (ior:DI (match_operand:DI 1 "arith_double_operand" "") ! 1541: (match_operand:DI 2 "arith_double_operand" "")))] ! 1542: "" ! 1543: "") ! 1544: ! 1545: (define_insn "" ! 1546: [(set (match_operand:DI 0 "register_operand" "=r") ! 1547: (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") ! 1548: (match_operand:DI 2 "arith_double_operand" "rHI")))] ! 1549: "" ! 1550: "* ! 1551: { ! 1552: rtx op2 = operands[2]; ! 1553: ! 1554: /* If constant is postive, upper bits zeroed, otherwise unchanged ! 1555: * give the assembler a chance to pick the move instruction. */ ! 1556: if (GET_CODE (op2) == CONST_INT) ! 1557: { ! 1558: int sign = INTVAL (op2); ! 1559: if (sign < 0) ! 1560: return \"mov -1,%0\;or %R1,%2,%R0\"; ! 1561: return \"mov %1,%0\;or %R1,%2,%R0\"; ! 1562: } ! 1563: else if (GET_CODE (op2) == CONST_DOUBLE) ! 1564: { ! 1565: int sign = CONST_DOUBLE_HIGH (op2); ! 1566: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1567: CONST_DOUBLE_LOW (operands[1])); ! 1568: if (sign < 0) ! 1569: return \"mov -1,%0\;or %R1,%2,%R0\"; ! 1570: return \"mov %1,%0\;or %R1,%2,%R0\"; ! 1571: } ! 1572: return \"or %1,%2,%0\;or %R1,%R2,%R0\"; ! 1573: }" ! 1574: [(set_attr "length" "2")]) ! 1575: ! 1576: (define_insn "iorsi3" ! 1577: [(set (match_operand:SI 0 "register_operand" "=r") ! 1578: (ior:SI (match_operand:SI 1 "arith_operand" "%r") ! 1579: (match_operand:SI 2 "arith_operand" "rI")))] ! 1580: "" ! 1581: "or %1,%2,%0") ! 1582: ! 1583: (define_insn "" ! 1584: [(set (match_operand:DI 0 "register_operand" "=r") ! 1585: (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) ! 1586: (match_operand:DI 2 "register_operand" "r")))] ! 1587: "" ! 1588: "orn %2,%1,%0\;orn %R2,%R1,%R0" ! 1589: [(set_attr "length" "2")]) ! 1590: ! 1591: (define_insn "" ! 1592: [(set (match_operand:SI 0 "register_operand" "=r") ! 1593: (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) ! 1594: (match_operand:SI 2 "register_operand" "r")))] ! 1595: "" ! 1596: "orn %2,%1,%0") ! 1597: ! 1598: (define_expand "xordi3" ! 1599: [(set (match_operand:DI 0 "register_operand" "") ! 1600: (xor:DI (match_operand:DI 1 "arith_double_operand" "") ! 1601: (match_operand:DI 2 "arith_double_operand" "")))] ! 1602: "" ! 1603: "") ! 1604: ! 1605: (define_insn "" ! 1606: [(set (match_operand:DI 0 "register_operand" "=r") ! 1607: (xor:DI (match_operand:DI 1 "arith_double_operand" "%r") ! 1608: (match_operand:DI 2 "arith_double_operand" "rHI")))] ! 1609: "" ! 1610: "* ! 1611: { ! 1612: rtx op2 = operands[2]; ! 1613: ! 1614: /* If constant is postive, upper bits zeroed, otherwise unchanged ! 1615: * give the assembler a chance to pick the move instruction. */ ! 1616: if (GET_CODE (op2) == CONST_INT) ! 1617: { ! 1618: int sign = INTVAL (op2); ! 1619: if (sign < 0) ! 1620: return \"xor %1,-1,%0\;xor %R1,%2,%R0\"; ! 1621: return \"mov %1,%0\;xor %R1,%2,%R0\"; ! 1622: } ! 1623: else if (GET_CODE (op2) == CONST_DOUBLE) ! 1624: { ! 1625: int sign = CONST_DOUBLE_HIGH (op2); ! 1626: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1627: CONST_DOUBLE_LOW (operands[1])); ! 1628: if (sign < 0) ! 1629: return \"xor %1,-1,%0\;xor %R1,%2,%R0\"; ! 1630: return \"mov %1,%0\;xor %R1,%2,%R0\"; ! 1631: } ! 1632: return \"xor %1,%2,%0\;xor %R1,%R2,%R0\"; ! 1633: }" ! 1634: [(set_attr "length" "2")]) ! 1635: ! 1636: (define_insn "xorsi3" ! 1637: [(set (match_operand:SI 0 "register_operand" "=r") ! 1638: (xor:SI (match_operand:SI 1 "arith_operand" "%rJ") ! 1639: (match_operand:SI 2 "arith_operand" "rI")))] ! 1640: "" ! 1641: "xor %r1,%2,%0") ! 1642: ! 1643: ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b). ! 1644: ;; Combine now canonicalizes to the rightmost expression. ! 1645: (define_insn "" ! 1646: [(set (match_operand:DI 0 "register_operand" "=r") ! 1647: (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") ! 1648: (match_operand:DI 2 "register_operand" "r"))))] ! 1649: "" ! 1650: "xnor %1,%2,%0\;xnor %R1,%R2,%R0" ! 1651: [(set_attr "length" "2")]) ! 1652: ! 1653: (define_insn "" ! 1654: [(set (match_operand:SI 0 "register_operand" "=r") ! 1655: (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ! 1656: (match_operand:SI 2 "arith_operand" "rI"))))] ! 1657: "" ! 1658: "xnor %r1,%2,%0") ! 1659: ! 1660: ;; These correspond to the above in the case where we also (or only) ! 1661: ;; want to set the condition code. ! 1662: ! 1663: (define_insn "" ! 1664: [(set (reg:CC 0) ! 1665: (compare:CC ! 1666: (match_operator:SI 2 "cc_arithop" ! 1667: [(match_operand:SI 0 "arith_operand" "%r") ! 1668: (match_operand:SI 1 "arith_operand" "rI")]) ! 1669: (const_int 0)))] ! 1670: "" ! 1671: "%A2cc %0,%1,%%g0" ! 1672: [(set_attr "type" "compare")]) ! 1673: ! 1674: (define_insn "" ! 1675: [(set (reg:CC 0) ! 1676: (compare:CC ! 1677: (match_operator:SI 3 "cc_arithop" ! 1678: [(match_operand:SI 1 "arith_operand" "%r") ! 1679: (match_operand:SI 2 "arith_operand" "rI")]) ! 1680: (const_int 0))) ! 1681: (set (match_operand:SI 0 "register_operand" "=r") ! 1682: (match_dup 3))] ! 1683: "" ! 1684: "%A3cc %1,%2,%0") ! 1685: ! 1686: (define_insn "" ! 1687: [(set (reg:CC 0) ! 1688: (compare:CC ! 1689: (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ") ! 1690: (match_operand:SI 1 "arith_operand" "rI"))) ! 1691: (const_int 0)))] ! 1692: "" ! 1693: "xnorcc %r0,%1,%%g0" ! 1694: [(set_attr "type" "compare")]) ! 1695: ! 1696: (define_insn "" ! 1697: [(set (reg:CC 0) ! 1698: (compare:CC ! 1699: (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") ! 1700: (match_operand:SI 2 "arith_operand" "rI"))) ! 1701: (const_int 0))) ! 1702: (set (match_operand:SI 0 "register_operand" "=r") ! 1703: (not:SI (xor:SI (match_dup 1) (match_dup 2))))] ! 1704: "" ! 1705: "xnorcc %r1,%2,%0") ! 1706: ! 1707: (define_insn "" ! 1708: [(set (reg:CC 0) ! 1709: (compare:CC ! 1710: (match_operator:SI 2 "cc_arithopn" ! 1711: [(not:SI (match_operand:SI 0 "arith_operand" "rI")) ! 1712: (match_operand:SI 1 "reg_or_0_operand" "rJ")]) ! 1713: (const_int 0)))] ! 1714: "" ! 1715: "%B2cc %r1,%0,%%g0" ! 1716: [(set_attr "type" "compare")]) ! 1717: ! 1718: (define_insn "" ! 1719: [(set (reg:CC 0) ! 1720: (compare:CC ! 1721: (match_operator:SI 3 "cc_arithopn" ! 1722: [(not:SI (match_operand:SI 1 "arith_operand" "rI")) ! 1723: (match_operand:SI 2 "reg_or_0_operand" "rJ")]) ! 1724: (const_int 0))) ! 1725: (set (match_operand:SI 0 "register_operand" "=r") ! 1726: (match_dup 3))] ! 1727: "" ! 1728: "%B3cc %r2,%1,%0") ! 1729: ! 1730: ;; We cannot use the "neg" pseudo insn because the Sun assembler ! 1731: ;; does not know how to make it work for constants. ! 1732: ! 1733: (define_insn "negdi2" ! 1734: [(set (match_operand:DI 0 "register_operand" "=r") ! 1735: (neg:DI (match_operand:DI 1 "register_operand" "r"))) ! 1736: (clobber (reg:SI 0))] ! 1737: "" ! 1738: "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0" ! 1739: [(set_attr "type" "unary") ! 1740: (set_attr "length" "2")]) ! 1741: ! 1742: (define_insn "negsi2" ! 1743: [(set (match_operand:SI 0 "general_operand" "=r") ! 1744: (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] ! 1745: "" ! 1746: "sub %%g0,%1,%0" ! 1747: [(set_attr "type" "unary")]) ! 1748: ! 1749: (define_insn "" ! 1750: [(set (reg:CC_NOOV 0) ! 1751: (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) ! 1752: (const_int 0)))] ! 1753: "" ! 1754: "subcc %%g0,%0,%%g0" ! 1755: [(set_attr "type" "compare")]) ! 1756: ! 1757: (define_insn "" ! 1758: [(set (reg:CC_NOOV 0) ! 1759: (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) ! 1760: (const_int 0))) ! 1761: (set (match_operand:SI 0 "register_operand" "=r") ! 1762: (neg:SI (match_dup 1)))] ! 1763: "" ! 1764: "subcc %%g0,%1,%0" ! 1765: [(set_attr "type" "unary")]) ! 1766: ! 1767: ;; We cannot use the "not" pseudo insn because the Sun assembler ! 1768: ;; does not know how to make it work for constants. ! 1769: (define_expand "one_cmpldi2" ! 1770: [(set (match_operand:DI 0 "register_operand" "=r") ! 1771: (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))] ! 1772: "" ! 1773: "") ! 1774: ! 1775: (define_insn "" ! 1776: [(set (match_operand:DI 0 "register_operand" "=r") ! 1777: (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))] ! 1778: "" ! 1779: "* ! 1780: { ! 1781: rtx op1 = operands[1]; ! 1782: ! 1783: if (GET_CODE (op1) == CONST_INT) ! 1784: { ! 1785: int sign = INTVAL (op1); ! 1786: if (sign < 0) ! 1787: return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\"; ! 1788: return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\"; ! 1789: } ! 1790: else if (GET_CODE (op1) == CONST_DOUBLE) ! 1791: { ! 1792: int sign = CONST_DOUBLE_HIGH (op1); ! 1793: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 1794: CONST_DOUBLE_LOW (operands[1])); ! 1795: if (sign < 0) ! 1796: return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\"; ! 1797: return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\"; ! 1798: } ! 1799: return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\"; ! 1800: }" ! 1801: [(set_attr "type" "unary") ! 1802: (set_attr "length" "2")]) ! 1803: ! 1804: (define_insn "one_cmplsi2" ! 1805: [(set (match_operand:SI 0 "register_operand" "=r") ! 1806: (not:SI (match_operand:SI 1 "arith_operand" "rI")))] ! 1807: "" ! 1808: "xnor %%g0,%1,%0" ! 1809: [(set_attr "type" "unary")]) ! 1810: ! 1811: (define_insn "" ! 1812: [(set (reg:CC 0) ! 1813: (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) ! 1814: (const_int 0)))] ! 1815: "" ! 1816: "xnorcc %%g0,%0,%%g0" ! 1817: [(set_attr "type" "compare")]) ! 1818: ! 1819: (define_insn "" ! 1820: [(set (reg:CC 0) ! 1821: (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) ! 1822: (const_int 0))) ! 1823: (set (match_operand:SI 0 "register_operand" "=r") ! 1824: (not:SI (match_dup 1)))] ! 1825: "" ! 1826: "xnorcc %%g0,%1,%0" ! 1827: [(set_attr "type" "unary")]) ! 1828: ! 1829: ;; Floating point arithmetic instructions. ! 1830: ! 1831: (define_insn "adddf3" ! 1832: [(set (match_operand:DF 0 "register_operand" "=f") ! 1833: (plus:DF (match_operand:DF 1 "register_operand" "f") ! 1834: (match_operand:DF 2 "register_operand" "f")))] ! 1835: "" ! 1836: "faddd %1,%2,%0" ! 1837: [(set_attr "type" "fp")]) ! 1838: ! 1839: (define_insn "addsf3" ! 1840: [(set (match_operand:SF 0 "register_operand" "=f") ! 1841: (plus:SF (match_operand:SF 1 "register_operand" "f") ! 1842: (match_operand:SF 2 "register_operand" "f")))] ! 1843: "" ! 1844: "fadds %1,%2,%0" ! 1845: [(set_attr "type" "fp")]) ! 1846: ! 1847: (define_insn "subdf3" ! 1848: [(set (match_operand:DF 0 "register_operand" "=f") ! 1849: (minus:DF (match_operand:DF 1 "register_operand" "f") ! 1850: (match_operand:DF 2 "register_operand" "f")))] ! 1851: "" ! 1852: "fsubd %1,%2,%0" ! 1853: [(set_attr "type" "fp")]) ! 1854: ! 1855: (define_insn "subsf3" ! 1856: [(set (match_operand:SF 0 "register_operand" "=f") ! 1857: (minus:SF (match_operand:SF 1 "register_operand" "f") ! 1858: (match_operand:SF 2 "register_operand" "f")))] ! 1859: "" ! 1860: "fsubs %1,%2,%0" ! 1861: [(set_attr "type" "fp")]) ! 1862: ! 1863: (define_insn "muldf3" ! 1864: [(set (match_operand:DF 0 "register_operand" "=f") ! 1865: (mult:DF (match_operand:DF 1 "register_operand" "f") ! 1866: (match_operand:DF 2 "register_operand" "f")))] ! 1867: "" ! 1868: "fmuld %1,%2,%0" ! 1869: [(set_attr "type" "fpmul")]) ! 1870: ! 1871: (define_insn "mulsf3" ! 1872: [(set (match_operand:SF 0 "register_operand" "=f") ! 1873: (mult:SF (match_operand:SF 1 "register_operand" "f") ! 1874: (match_operand:SF 2 "register_operand" "f")))] ! 1875: "" ! 1876: "fmuls %1,%2,%0" ! 1877: [(set_attr "type" "fpmul")]) ! 1878: ! 1879: (define_insn "divdf3" ! 1880: [(set (match_operand:DF 0 "register_operand" "=f") ! 1881: (div:DF (match_operand:DF 1 "register_operand" "f") ! 1882: (match_operand:DF 2 "register_operand" "f")))] ! 1883: "" ! 1884: "fdivd %1,%2,%0" ! 1885: [(set_attr "type" "fpdiv")]) ! 1886: ! 1887: (define_insn "divsf3" ! 1888: [(set (match_operand:SF 0 "register_operand" "=f") ! 1889: (div:SF (match_operand:SF 1 "register_operand" "f") ! 1890: (match_operand:SF 2 "register_operand" "f")))] ! 1891: "" ! 1892: "fdivs %1,%2,%0" ! 1893: [(set_attr "type" "fpdiv")]) ! 1894: ! 1895: (define_insn "negdf2" ! 1896: [(set (match_operand:DF 0 "register_operand" "=f,f") ! 1897: (neg:DF (match_operand:DF 1 "register_operand" "0,f")))] ! 1898: "" ! 1899: "@ ! 1900: fnegs %0,%0 ! 1901: fnegs %1,%0\;fmovs %R1,%R0" ! 1902: [(set_attr "type" "fp") ! 1903: (set_attr "length" "1,2")]) ! 1904: ! 1905: ! 1906: (define_insn "negsf2" ! 1907: [(set (match_operand:SF 0 "register_operand" "=f") ! 1908: (neg:SF (match_operand:SF 1 "register_operand" "f")))] ! 1909: "" ! 1910: "fnegs %1,%0" ! 1911: [(set_attr "type" "fp")]) ! 1912: ! 1913: (define_insn "absdf2" ! 1914: [(set (match_operand:DF 0 "register_operand" "=f,f") ! 1915: (abs:DF (match_operand:DF 1 "register_operand" "0,f")))] ! 1916: "" ! 1917: "@ ! 1918: fabss %0,%0 ! 1919: fabss %1,%0\;fmovs %R1,%R0" ! 1920: [(set_attr "type" "fp") ! 1921: (set_attr "length" "1,2")]) ! 1922: ! 1923: (define_insn "abssf2" ! 1924: [(set (match_operand:SF 0 "register_operand" "=f") ! 1925: (abs:SF (match_operand:SF 1 "register_operand" "f")))] ! 1926: "" ! 1927: "fabss %1,%0" ! 1928: [(set_attr "type" "fp")]) ! 1929: ! 1930: (define_insn "sqrtdf2" ! 1931: [(set (match_operand:DF 0 "register_operand" "=f") ! 1932: (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] ! 1933: "" ! 1934: "fsqrtd %1,%0" ! 1935: [(set_attr "type" "fpsqrt")]) ! 1936: ! 1937: (define_insn "sqrtsf2" ! 1938: [(set (match_operand:SF 0 "register_operand" "=f") ! 1939: (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] ! 1940: "" ! 1941: "fsqrts %1,%0" ! 1942: [(set_attr "type" "fpsqrt")]) ! 1943: ! 1944: ;;- arithmetic shift instructions ! 1945: ! 1946: ;; We can trivially handle shifting the constant 1 by 64 bits. ! 1947: ;; For other shifts we use the library routine. ! 1948: ;; ??? Questionable, we can do better than this can't we? ! 1949: (define_expand "ashldi3" ! 1950: [(parallel [(set (match_operand:DI 0 "register_operand" "") ! 1951: (ashift:DI (match_operand:DI 1 "const_double_operand" "") ! 1952: (match_operand:SI 2 "register_operand" ""))) ! 1953: (clobber (reg:SI 0))])] ! 1954: "" ! 1955: " ! 1956: { ! 1957: if (GET_CODE (operands[1]) == CONST_DOUBLE ! 1958: && CONST_DOUBLE_HIGH (operands[1]) == 0 ! 1959: && CONST_DOUBLE_LOW (operands[1]) == 1) ! 1960: operands[1] = const1_rtx; ! 1961: else if (operands[1] != const1_rtx) ! 1962: FAIL; ! 1963: }") ! 1964: ! 1965: ;; ??? Questionable, we can do better than this can't we? ! 1966: (define_insn "" ! 1967: [(set (match_operand:DI 0 "register_operand" "=&r") ! 1968: (ashift:DI (const_int 1) ! 1969: (match_operand:SI 2 "register_operand" "r"))) ! 1970: (clobber (reg:SI 0))] ! 1971: "" ! 1972: "subcc %2,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%2,%R0\;sll %0,%2,%0" ! 1973: [(set_attr "type" "multi") ! 1974: (set_attr "length" "5")]) ! 1975: ! 1976: (define_insn "ashlsi3" ! 1977: [(set (match_operand:SI 0 "register_operand" "=r") ! 1978: (ashift:SI (match_operand:SI 1 "register_operand" "r") ! 1979: (match_operand:SI 2 "arith_operand" "rI")))] ! 1980: "" ! 1981: "sll %1,%2,%0") ! 1982: ! 1983: (define_insn "ashrsi3" ! 1984: [(set (match_operand:SI 0 "register_operand" "=r") ! 1985: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") ! 1986: (match_operand:SI 2 "arith_operand" "rI")))] ! 1987: "" ! 1988: "sra %1,%2,%0") ! 1989: ! 1990: (define_insn "lshrsi3" ! 1991: [(set (match_operand:SI 0 "register_operand" "=r") ! 1992: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") ! 1993: (match_operand:SI 2 "arith_operand" "rI")))] ! 1994: "" ! 1995: "srl %1,%2,%0") ! 1996: ! 1997: ;; Unconditional and other jump instructions ! 1998: ;; Note that for the Sparc, by setting the annul bit on an unconditional ! 1999: ;; branch, the following insn is never executed. This saves us a nop, ! 2000: ;; but requires a debugger which can handle annuled branches. ! 2001: (define_insn "jump" ! 2002: [(set (pc) (label_ref (match_operand 0 "" "")))] ! 2003: "" ! 2004: "b%* %l0" ! 2005: [(set_attr "type" "branch")]) ! 2006: ! 2007: (define_expand "tablejump" ! 2008: [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r")) ! 2009: (use (label_ref (match_operand 1 "" "")))])] ! 2010: "" ! 2011: " ! 2012: { ! 2013: /* We need to use the PC value in %o7 that was set up when the address ! 2014: of the label was loaded into a register, so we need different RTL. */ ! 2015: if (flag_pic) ! 2016: { ! 2017: emit_insn (gen_pic_tablejump (operands[0], operands[1])); ! 2018: DONE; ! 2019: } ! 2020: }") ! 2021: ! 2022: (define_insn "pic_tablejump" ! 2023: [(set (pc) (match_operand:SI 0 "register_operand" "r")) ! 2024: (use (label_ref (match_operand 1 "" ""))) ! 2025: (use (reg:SI 15))] ! 2026: "" ! 2027: "jmp %%o7+%0%#" ! 2028: [(set_attr "type" "branch")]) ! 2029: ! 2030: (define_insn "" ! 2031: [(set (pc) (match_operand:SI 0 "address_operand" "p")) ! 2032: (use (label_ref (match_operand 1 "" "")))] ! 2033: "" ! 2034: "jmp %a0%#" ! 2035: [(set_attr "type" "branch")]) ! 2036: ! 2037: (define_insn "" ! 2038: [(set (pc) (label_ref (match_operand 0 "" ""))) ! 2039: (set (reg:SI 15) (label_ref (match_dup 0)))] ! 2040: "" ! 2041: "call %l0%#" ! 2042: [(set_attr "type" "branch")]) ! 2043: ! 2044: ;; This pattern recognizes the "instruction" that appears in ! 2045: ;; a function call that wants a structure value, ! 2046: ;; to inform the called function if compiled with Sun CC. ! 2047: ;(define_insn "" ! 2048: ; [(match_operand:SI 0 "immediate_operand" "")] ! 2049: ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0" ! 2050: ; "unimp %0" ! 2051: ; [(set_attr "type" "marker")]) ! 2052: ! 2053: ;;- jump to subroutine ! 2054: (define_expand "call" ! 2055: ;; Note that this expression is not used for generating RTL. ! 2056: ;; All the RTL is generated explicitly below. ! 2057: [(call (match_operand:SI 0 "call_operand" "") ! 2058: (match_operand 3 "" "i"))] ! 2059: ;; operands[2] is next_arg_register ! 2060: ;; operands[3] is struct_value_size_rtx. ! 2061: "" ! 2062: " ! 2063: { ! 2064: rtx fn_rtx, nregs_rtx; ! 2065: ! 2066: if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) ! 2067: { ! 2068: /* This is really a PIC sequence. We want to represent ! 2069: it as a funny jump so it's delay slots can be filled. ! 2070: ! 2071: ??? But if this really *is* a CALL, will not it clobber the ! 2072: call-clobbered registers? We lose this if it is a JUMP_INSN. ! 2073: Why cannot we have delay slots filled if it were a CALL? */ ! 2074: ! 2075: if (INTVAL (operands[3]) > 0) ! 2076: emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, ! 2077: gen_rtx (SET, VOIDmode, pc_rtx, ! 2078: XEXP (operands[0], 0)), ! 2079: operands[3], ! 2080: gen_rtx (CLOBBER, VOIDmode, ! 2081: gen_rtx (REG, SImode, 15))))); ! 2082: else ! 2083: emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, ! 2084: gen_rtx (SET, VOIDmode, pc_rtx, ! 2085: XEXP (operands[0], 0)), ! 2086: gen_rtx (CLOBBER, VOIDmode, ! 2087: gen_rtx (REG, SImode, 15))))); ! 2088: goto finish_call; ! 2089: } ! 2090: ! 2091: fn_rtx = operands[0]; ! 2092: ! 2093: /* Count the number of parameter registers being used by this call. ! 2094: if that argument is NULL, it means we are using them all, which ! 2095: means 6 on the sparc. */ ! 2096: #if 0 ! 2097: if (operands[2]) ! 2098: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8); ! 2099: else ! 2100: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); ! 2101: #else ! 2102: nregs_rtx = const0_rtx; ! 2103: #endif ! 2104: ! 2105: if (INTVAL (operands[3]) > 0) ! 2106: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, ! 2107: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), ! 2108: operands[3], ! 2109: gen_rtx (CLOBBER, VOIDmode, ! 2110: gen_rtx (REG, SImode, 15))))); ! 2111: else ! 2112: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, ! 2113: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), ! 2114: gen_rtx (CLOBBER, VOIDmode, ! 2115: gen_rtx (REG, SImode, 15))))); ! 2116: ! 2117: finish_call: ! 2118: #if 0 ! 2119: /* If this call wants a structure value, ! 2120: emit an unimp insn to let the called function know about this. */ ! 2121: if (INTVAL (operands[3]) > 0) ! 2122: { ! 2123: rtx insn = emit_insn (operands[3]); ! 2124: SCHED_GROUP_P (insn) = 1; ! 2125: } ! 2126: #endif ! 2127: ! 2128: DONE; ! 2129: }") ! 2130: ! 2131: (define_insn "" ! 2132: [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) ! 2133: (match_operand 1 "" "")) ! 2134: (clobber (reg:SI 15))] ! 2135: ;;- Do not use operand 1 for most machines. ! 2136: "" ! 2137: "* ! 2138: { ! 2139: return \"call %a0,%1%#\"; ! 2140: }" ! 2141: [(set_attr "type" "call")]) ! 2142: ! 2143: ;; This is a call that wants a structure value. ! 2144: (define_insn "" ! 2145: [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) ! 2146: (match_operand 1 "" "")) ! 2147: (match_operand 2 "immediate_operand" "") ! 2148: (clobber (reg:SI 15))] ! 2149: ;;- Do not use operand 1 for most machines. ! 2150: "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" ! 2151: "* ! 2152: { ! 2153: return \"call %a0,%1\;nop\;unimp %2\"; ! 2154: }" ! 2155: [(set_attr "type" "call_no_delay_slot")]) ! 2156: ! 2157: (define_expand "call_value" ! 2158: [(set (match_operand 0 "register_operand" "=rf") ! 2159: (call (match_operand:SI 1 "" "") ! 2160: (match_operand 4 "" "")))] ! 2161: ;; operand 3 is next_arg_register ! 2162: "" ! 2163: " ! 2164: { ! 2165: rtx fn_rtx, nregs_rtx; ! 2166: rtvec vec; ! 2167: ! 2168: fn_rtx = operands[1]; ! 2169: ! 2170: #if 0 ! 2171: if (operands[3]) ! 2172: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8); ! 2173: else ! 2174: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); ! 2175: #else ! 2176: nregs_rtx = const0_rtx; ! 2177: #endif ! 2178: ! 2179: vec = gen_rtvec (2, ! 2180: gen_rtx (SET, VOIDmode, operands[0], ! 2181: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)), ! 2182: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15))); ! 2183: ! 2184: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec)); ! 2185: ! 2186: DONE; ! 2187: }") ! 2188: ! 2189: (define_insn "" ! 2190: [(set (match_operand 0 "" "=rf") ! 2191: (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS")) ! 2192: (match_operand 2 "" ""))) ! 2193: (clobber (reg:SI 15))] ! 2194: ;;- Do not use operand 2 for most machines. ! 2195: "" ! 2196: "* ! 2197: { ! 2198: return \"call %a1,%2%#\"; ! 2199: }" ! 2200: [(set_attr "type" "call")]) ! 2201: ! 2202: (define_insn "return" ! 2203: [(return)] ! 2204: "! TARGET_EPILOGUE" ! 2205: "* return output_return (operands);" ! 2206: [(set_attr "type" "multi")]) ! 2207: ! 2208: (define_insn "nop" ! 2209: [(const_int 0)] ! 2210: "" ! 2211: "nop") ! 2212: ! 2213: (define_insn "indirect_jump" ! 2214: [(set (pc) (match_operand:SI 0 "address_operand" "p"))] ! 2215: "" ! 2216: "jmp %a0%#" ! 2217: [(set_attr "type" "branch")]) ! 2218: ! 2219: (define_expand "nonlocal_goto" ! 2220: [(match_operand:SI 0 "general_operand" "") ! 2221: (match_operand:SI 1 "general_operand" "") ! 2222: (match_operand:SI 2 "general_operand" "") ! 2223: (match_operand:SI 3 "" "")] ! 2224: "" ! 2225: " ! 2226: { ! 2227: rtx temp; ! 2228: /* Trap instruction to flush all the registers window. */ ! 2229: emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, ! 2230: gen_rtvec (1, const0_rtx), 0)); ! 2231: /* Load the fp value for the containing fn into %fp. ! 2232: This is needed because operands[2] refers to %fp. */ ! 2233: emit_move_insn (virtual_stack_vars_rtx, operands[0]); ! 2234: /* Find the containing function's current nonlocal goto handler, ! 2235: which will do any cleanups and then jump to the label. */ ! 2236: emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]); ! 2237: /* Restore %fp from stack pointer value for containing function. ! 2238: The restore insn that follows will move this to %sp, ! 2239: and reload the appropriate value into %fp. */ ! 2240: emit_move_insn (frame_pointer_rtx, operands[2]); ! 2241: /* Put in the static chain register the nonlocal label address. */ ! 2242: emit_move_insn (static_chain_rtx, operands[3]); ! 2243: /* USE of frame_pointer_rtx added for consistency; not clear if ! 2244: really needed. */ ! 2245: emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx)); ! 2246: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); ! 2247: emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx)); ! 2248: emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8))); ! 2249: /* Return, restoring reg window and jumping to goto handler. */ ! 2250: emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, ! 2251: gen_rtvec (1, const0_rtx), 1)); ! 2252: DONE; ! 2253: }") ! 2254: ! 2255: ;; Special trap insn to flush register windows. ! 2256: (define_insn "" ! 2257: [(unspec_volatile [(const_int 0)] 0)] ! 2258: "" ! 2259: "ta 3") ! 2260: ! 2261: (define_insn "" ! 2262: [(unspec_volatile [(const_int 0)] 1)] ! 2263: "" ! 2264: "jmp %%o0+0\;restore") ! 2265: ! 2266: ;(define_insn "tail_call" ;; tail call ! 2267: ; [(set (pc) (match_operand 0 "memory_operand" "m"))] ! 2268: ; "tail_call_valid_p ()" ! 2269: ; "* return output_tail_call (operands, insn);" ! 2270: ; [(set_attr "type" "branch")]) ! 2271: ! 2272: ;; Split up troublesome insns for better scheduling. */ ! 2273: ! 2274: ;; The following patterns are straightforward. They can be applied ! 2275: ;; either before or after register allocation. ! 2276: ! 2277: (define_split ! 2278: [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")]) ! 2279: (match_operand 2 "reg_or_0_operand" "")) ! 2280: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2281: "! flag_pic" ! 2282: [(set (match_dup 3) (high:SI (match_dup 1))) ! 2283: (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))]) ! 2284: (match_dup 2))] ! 2285: "") ! 2286: ! 2287: (define_split ! 2288: [(set (match_operator 0 "memop" ! 2289: [(match_operand:SI 1 "immediate_operand" "")]) ! 2290: (match_operand 2 "general_operand" "")) ! 2291: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2292: "flag_pic" ! 2293: [(set (match_op_dup 0 [(match_dup 1)]) ! 2294: (match_dup 2))] ! 2295: " ! 2296: { ! 2297: operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]), ! 2298: operands[3], 0); ! 2299: }") ! 2300: ! 2301: (define_split ! 2302: [(set (match_operand 0 "register_operand" "") ! 2303: (match_operator 1 "memop" ! 2304: [(match_operand:SI 2 "immediate_operand" "")]))] ! 2305: "flag_pic" ! 2306: [(set (match_dup 0) ! 2307: (match_op_dup 1 [(match_dup 2)]))] ! 2308: " ! 2309: { ! 2310: operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]), ! 2311: operands[0], 0); ! 2312: }") ! 2313: ! 2314: ;; Sign- and Zero-extend operations can have symbolic memory operands. ! 2315: ! 2316: (define_split ! 2317: [(set (match_operand 0 "register_operand" "") ! 2318: (match_operator 1 "extend_op" ! 2319: [(match_operator 2 "memop" ! 2320: [(match_operand:SI 3 "immediate_operand" "")])]))] ! 2321: "flag_pic" ! 2322: [(set (match_dup 0) ! 2323: (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))] ! 2324: " ! 2325: { ! 2326: operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]), ! 2327: operands[0], 0); ! 2328: }") ! 2329: ! 2330: (define_split ! 2331: [(set (match_operand:SI 0 "register_operand" "") ! 2332: (match_operand:SI 1 "immediate_operand" ""))] ! 2333: "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF ! 2334: || GET_CODE (operands[1]) == CONST ! 2335: || GET_CODE (operands[1]) == LABEL_REF)" ! 2336: [(set (match_dup 0) (high:SI (match_dup 1))) ! 2337: (set (match_dup 0) ! 2338: (lo_sum:SI (match_dup 0) (match_dup 1)))] ! 2339: "") ! 2340: ! 2341: ;; LABEL_REFs are not modified by `legitimize_pic_address` ! 2342: ;; so do not recurse infinitely in the PIC case. ! 2343: (define_split ! 2344: [(set (match_operand:SI 0 "register_operand" "") ! 2345: (match_operand:SI 1 "immediate_operand" ""))] ! 2346: "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF ! 2347: || GET_CODE (operands[1]) == CONST)" ! 2348: [(set (match_dup 0) (match_dup 1))] ! 2349: " ! 2350: { ! 2351: operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0); ! 2352: }") ! 2353: ! 2354: ;; These split sne/seq insns. The forms of the resulting insns are ! 2355: ;; somewhat bogus, but they avoid extra patterns and show data dependency. ! 2356: ;; Nothing will look at these in detail after splitting has occurred. ! 2357: ! 2358: (define_split ! 2359: [(set (match_operand:SI 0 "register_operand" "") ! 2360: (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0))) ! 2361: (clobber (reg:CC 0))] ! 2362: "" ! 2363: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) ! 2364: (const_int 0))) ! 2365: (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))] ! 2366: "") ! 2367: ! 2368: (define_split ! 2369: [(set (match_operand:SI 0 "register_operand" "") ! 2370: (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "") ! 2371: (const_int 0)))) ! 2372: (clobber (reg:CC 0))] ! 2373: "" ! 2374: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) ! 2375: (const_int 0))) ! 2376: (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))] ! 2377: "") ! 2378: ! 2379: (define_split ! 2380: [(set (match_operand:SI 0 "register_operand" "") ! 2381: (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0))) ! 2382: (clobber (reg:CC 0))] ! 2383: "" ! 2384: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) ! 2385: (const_int 0))) ! 2386: (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))] ! 2387: "") ! 2388: ! 2389: (define_split ! 2390: [(set (match_operand:SI 0 "register_operand" "") ! 2391: (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "") ! 2392: (const_int 0)))) ! 2393: (clobber (reg:CC 0))] ! 2394: "" ! 2395: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) ! 2396: (const_int 0))) ! 2397: (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))] ! 2398: "") ! 2399: ! 2400: (define_split ! 2401: [(set (match_operand:SI 0 "register_operand" "") ! 2402: (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "") ! 2403: (const_int 0)) ! 2404: (match_operand:SI 2 "register_operand" ""))) ! 2405: (clobber (reg:CC 0))] ! 2406: "" ! 2407: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) ! 2408: (const_int 0))) ! 2409: (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) ! 2410: (match_dup 2)))] ! 2411: "") ! 2412: ! 2413: (define_split ! 2414: [(set (match_operand:SI 0 "register_operand" "") ! 2415: (minus:SI (match_operand:SI 2 "register_operand" "") ! 2416: (ne:SI (match_operand:SI 1 "register_operand" "") ! 2417: (const_int 0)))) ! 2418: (clobber (reg:CC 0))] ! 2419: "" ! 2420: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) ! 2421: (const_int 0))) ! 2422: (set (match_dup 0) (minus:SI (match_dup 2) ! 2423: (ltu:SI (reg:CC 0) (const_int 0))))] ! 2424: "") ! 2425: ! 2426: (define_split ! 2427: [(set (match_operand:SI 0 "register_operand" "") ! 2428: (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "") ! 2429: (const_int 0)) ! 2430: (match_operand:SI 2 "register_operand" ""))) ! 2431: (clobber (reg:CC 0))] ! 2432: "" ! 2433: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) ! 2434: (const_int 0))) ! 2435: (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0)) ! 2436: (match_dup 2)))] ! 2437: "") ! 2438: ! 2439: (define_split ! 2440: [(set (match_operand:SI 0 "register_operand" "") ! 2441: (minus:SI (match_operand:SI 2 "register_operand" "") ! 2442: (eq:SI (match_operand:SI 1 "register_operand" "") ! 2443: (const_int 0)))) ! 2444: (clobber (reg:CC 0))] ! 2445: "" ! 2446: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) ! 2447: (const_int 0))) ! 2448: (set (match_dup 0) (minus:SI (match_dup 2) ! 2449: (geu:SI (reg:CC 0) (const_int 0))))] ! 2450: "") ! 2451: ! 2452: ;; Peepholes go at the end. ! 2453: ! 2454: ;; Optimize the case of following a reg-reg move with a test ! 2455: ;; of reg just moved. ! 2456: ! 2457: (define_peephole ! 2458: [(set (match_operand:SI 0 "register_operand" "=r") ! 2459: (match_operand:SI 1 "register_operand" "r")) ! 2460: (set (reg:CC 0) ! 2461: (compare:CC (match_operand:SI 2 "register_operand" "r") ! 2462: (const_int 0)))] ! 2463: "rtx_equal_p (operands[2], operands[0]) ! 2464: || rtx_equal_p (operands[2], operands[1])" ! 2465: "orcc %1,%%g0,%0" ! 2466: [(set_attr "type" "move")]) ! 2467: ! 2468: ;; Do {sign,zero}-extended compares somewhat more efficiently. ! 2469: ;; ??? Is this now the Right Way to do this? Or will SCRATCH ! 2470: ;; eventually have some impact here? ! 2471: ! 2472: (define_peephole ! 2473: [(set (match_operand:HI 0 "register_operand" "") ! 2474: (match_operand:HI 1 "memory_operand" "")) ! 2475: (set (match_operand:SI 2 "register_operand" "") ! 2476: (sign_extend:SI (match_dup 0))) ! 2477: (set (reg:CC 0) ! 2478: (compare:CC (match_dup 2) ! 2479: (const_int 0)))] ! 2480: "" ! 2481: "ldsh %1,%0\;orcc %0,%%g0,%2") ! 2482: ! 2483: (define_peephole ! 2484: [(set (match_operand:QI 0 "register_operand" "") ! 2485: (match_operand:QI 1 "memory_operand" "")) ! 2486: (set (match_operand:SI 2 "register_operand" "") ! 2487: (sign_extend:SI (match_dup 0))) ! 2488: (set (reg:CC 0) ! 2489: (compare:CC (match_dup 2) ! 2490: (const_int 0)))] ! 2491: "" ! 2492: "ldsb %1,%0\;orcc %0,%%g0,%2") ! 2493: ! 2494: (define_peephole ! 2495: [(set (match_operand:HI 0 "register_operand" "") ! 2496: (match_operand:HI 1 "memory_operand" "")) ! 2497: (set (match_operand:SI 2 "register_operand" "") ! 2498: (sign_extend:SI (match_dup 0)))] ! 2499: "dead_or_set_p (insn, operands[0])" ! 2500: "* ! 2501: { ! 2502: warning (\"bad peephole\"); ! 2503: if (! MEM_VOLATILE_P (operands[1])) ! 2504: abort (); ! 2505: return \"ldsh %1,%2\"; ! 2506: }") ! 2507: ! 2508: (define_peephole ! 2509: [(set (match_operand:QI 0 "register_operand" "") ! 2510: (match_operand:QI 1 "memory_operand" "")) ! 2511: (set (match_operand:SI 2 "register_operand" "") ! 2512: (sign_extend:SI (match_dup 0)))] ! 2513: "dead_or_set_p (insn, operands[0])" ! 2514: "* ! 2515: { ! 2516: warning (\"bad peephole\"); ! 2517: if (! MEM_VOLATILE_P (operands[1])) ! 2518: abort (); ! 2519: return \"ldsb %1,%2\"; ! 2520: }") ! 2521: ! 2522: ;; Floating-point move peepholes ! 2523: ! 2524: (define_peephole ! 2525: [(set (match_operand:SI 0 "register_operand" "=r") ! 2526: (lo_sum:SI (match_dup 0) ! 2527: (match_operand:SI 1 "immediate_operand" "i"))) ! 2528: (set (match_operand:DF 2 "register_operand" "=fr") ! 2529: (mem:DF (match_dup 0)))] ! 2530: "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" ! 2531: "* ! 2532: { ! 2533: /* Go by way of output_move_double in case the register in operand 2 ! 2534: is not properly aligned for ldd. */ ! 2535: operands[1] = gen_rtx (MEM, DFmode, ! 2536: gen_rtx (LO_SUM, SImode, operands[0], operands[1])); ! 2537: operands[0] = operands[2]; ! 2538: return output_move_double (operands); ! 2539: }") ! 2540: ! 2541: (define_peephole ! 2542: [(set (match_operand:SI 0 "register_operand" "=r") ! 2543: (lo_sum:SI (match_dup 0) ! 2544: (match_operand:SI 1 "immediate_operand" "i"))) ! 2545: (set (match_operand:SF 2 "register_operand" "=fr") ! 2546: (mem:SF (match_dup 0)))] ! 2547: "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" ! 2548: "ld [%0+%%lo(%a1)],%2") ! 2549: ! 2550: ;; Return peepholes. First the "normal" ones ! 2551: ! 2552: (define_insn "" ! 2553: [(set (match_operand:SI 0 "restore_operand" "") ! 2554: (match_operand:SI 1 "arith_operand" "rI")) ! 2555: (return)] ! 2556: "! TARGET_EPILOGUE" ! 2557: "* ! 2558: { ! 2559: if (current_function_returns_struct) ! 2560: return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; ! 2561: else ! 2562: return \"ret\;restore %%g0,%1,%Y0\"; ! 2563: }" ! 2564: [(set_attr "type" "multi")]) ! 2565: ! 2566: (define_insn "" ! 2567: [(set (match_operand:SI 0 "restore_operand" "") ! 2568: (plus:SI (match_operand:SI 1 "arith_operand" "%r") ! 2569: (match_operand:SI 2 "arith_operand" "rI"))) ! 2570: (return)] ! 2571: "! TARGET_EPILOGUE" ! 2572: "* ! 2573: { ! 2574: if (current_function_returns_struct) ! 2575: return \"jmp %%i7+12\;restore %r1,%2,%Y0\"; ! 2576: else ! 2577: return \"ret\;restore %r1,%2,%Y0\"; ! 2578: }" ! 2579: [(set_attr "type" "multi")]) ! 2580: ! 2581: ;; Turned off because it should never match (subtracting a constant ! 2582: ;; is turned into addition) and because it would do the wrong thing ! 2583: ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate). ! 2584: ;;(define_insn "" ! 2585: ;; [(set (match_operand:SI 0 "restore_operand" "") ! 2586: ;; (minus:SI (match_operand:SI 1 "register_operand" "r") ! 2587: ;; (match_operand:SI 2 "small_int" "I"))) ! 2588: ;; (return)] ! 2589: ;; "! TARGET_EPILOGUE" ! 2590: ;; "ret\;restore %1,-(%2),%Y0" ! 2591: ;; [(set_attr "type" "multi")]) ! 2592: ! 2593: ;; The following pattern is only generated by delayed-branch scheduling, ! 2594: ;; when the insn winds up in the epilogue. ! 2595: (define_insn "" ! 2596: [(set (reg:SF 32) ! 2597: (match_operand:SF 0 "register_operand" "f")) ! 2598: (return)] ! 2599: "! TARGET_EPILOGUE" ! 2600: "ret\;fmovs %0,%%f0") ! 2601: ! 2602: ;; Now peepholes to go a call followed by a jump. ! 2603: ! 2604: (define_peephole ! 2605: [(parallel [(set (match_operand 0 "" "") ! 2606: (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r")) ! 2607: (match_operand 2 "" ""))) ! 2608: (clobber (reg:SI 15))]) ! 2609: (set (pc) (label_ref (match_operand 3 "" "")))] ! 2610: "short_branch (INSN_UID (insn), INSN_UID (operands[3]))" ! 2611: "* ! 2612: { ! 2613: return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\"; ! 2614: }") ! 2615: ! 2616: (define_peephole ! 2617: [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) ! 2618: (match_operand 1 "" "")) ! 2619: (clobber (reg:SI 15))]) ! 2620: (set (pc) (label_ref (match_operand 2 "" "")))] ! 2621: "short_branch (INSN_UID (insn), INSN_UID (operands[2]))" ! 2622: "* ! 2623: { ! 2624: return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\"; ! 2625: }") ! 2626: ! 2627: (define_peephole ! 2628: [(parallel [(set (match_operand:SI 0 "register_operand" "=r") ! 2629: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ! 2630: (reg:SI 0))) ! 2631: (clobber (reg:CC 0))]) ! 2632: (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))] ! 2633: "" ! 2634: "subxcc %r1,0,%0" ! 2635: [(set_attr "type" "compare")]) ! 2636: ! 2637: ;;- Local variables: ! 2638: ;;- mode:emacs-lisp ! 2639: ;;- comment-start: ";;- " ! 2640: ;;- eval: (set-syntax-table (copy-sequence (syntax-table))) ! 2641: ;;- eval: (modify-syntax-entry ?[ "(]") ! 2642: ;;- eval: (modify-syntax-entry ?] ")[") ! 2643: ;;- eval: (modify-syntax-entry ?{ "(}") ! 2644: ;;- eval: (modify-syntax-entry ?} "){") ! 2645: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.