|
|
1.1 ! root 1: ;;- Machine description for GNU compiler, Vax Version ! 2: ;; Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc. ! 3: ! 4: ;; This file is part of GNU CC. ! 5: ! 6: ;; GNU CC is free software; you can redistribute it and/or modify ! 7: ;; it under the terms of the GNU General Public License as published by ! 8: ;; the Free Software Foundation; either version 2, or (at your option) ! 9: ;; any later version. ! 10: ! 11: ;; GNU CC is distributed in the hope that it will be useful, ! 12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: ;; GNU General Public License for more details. ! 15: ! 16: ;; You should have received a copy of the GNU General Public License ! 17: ;; along with GNU CC; see the file COPYING. If not, write to ! 18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 19: ! 20: ! 21: ;;- Instruction patterns. When multiple patterns apply, ! 22: ;;- the first one in the file is chosen. ! 23: ;;- ! 24: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 25: ;;- ! 26: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ! 27: ;;- updates for most instructions. ! 28: ! 29: ;; We don't want to allow a constant operand for test insns because ! 30: ;; (set (cc0) (const_int foo)) has no mode information. Such insns will ! 31: ;; be folded while optimizing anyway. ! 32: ! 33: (define_insn "tstsi" ! 34: [(set (cc0) ! 35: (match_operand:SI 0 "nonimmediate_operand" "g"))] ! 36: "" ! 37: "tstl %0") ! 38: ! 39: (define_insn "tsthi" ! 40: [(set (cc0) ! 41: (match_operand:HI 0 "nonimmediate_operand" "g"))] ! 42: "" ! 43: "tstw %0") ! 44: ! 45: (define_insn "tstqi" ! 46: [(set (cc0) ! 47: (match_operand:QI 0 "nonimmediate_operand" "g"))] ! 48: "" ! 49: "tstb %0") ! 50: ! 51: (define_insn "tstdf" ! 52: [(set (cc0) ! 53: (match_operand:DF 0 "general_operand" "gF"))] ! 54: "" ! 55: "tst%# %0") ! 56: ! 57: (define_insn "tstsf" ! 58: [(set (cc0) ! 59: (match_operand:SF 0 "general_operand" "gF"))] ! 60: "" ! 61: "tstf %0") ! 62: ! 63: (define_insn "cmpsi" ! 64: [(set (cc0) ! 65: (compare (match_operand:SI 0 "nonimmediate_operand" "g") ! 66: (match_operand:SI 1 "general_operand" "g")))] ! 67: "" ! 68: "cmpl %0,%1") ! 69: ! 70: (define_insn "cmphi" ! 71: [(set (cc0) ! 72: (compare (match_operand:HI 0 "nonimmediate_operand" "g") ! 73: (match_operand:HI 1 "general_operand" "g")))] ! 74: "" ! 75: "cmpw %0,%1") ! 76: ! 77: (define_insn "cmpqi" ! 78: [(set (cc0) ! 79: (compare (match_operand:QI 0 "nonimmediate_operand" "g") ! 80: (match_operand:QI 1 "general_operand" "g")))] ! 81: "" ! 82: "cmpb %0,%1") ! 83: ! 84: (define_insn "cmpdf" ! 85: [(set (cc0) ! 86: (compare (match_operand:DF 0 "general_operand" "gF,gF") ! 87: (match_operand:DF 1 "general_operand" "G,gF")))] ! 88: "" ! 89: "@ ! 90: tst%# %0 ! 91: cmp%# %0,%1") ! 92: ! 93: (define_insn "cmpsf" ! 94: [(set (cc0) ! 95: (compare (match_operand:SF 0 "general_operand" "gF,gF") ! 96: (match_operand:SF 1 "general_operand" "G,gF")))] ! 97: "" ! 98: "@ ! 99: tstf %0 ! 100: cmpf %0,%1") ! 101: ! 102: (define_insn "" ! 103: [(set (cc0) ! 104: (and:SI (match_operand:SI 0 "general_operand" "g") ! 105: (match_operand:SI 1 "general_operand" "g")))] ! 106: "" ! 107: "bitl %0,%1") ! 108: ! 109: (define_insn "" ! 110: [(set (cc0) ! 111: (and:HI (match_operand:HI 0 "general_operand" "g") ! 112: (match_operand:HI 1 "general_operand" "g")))] ! 113: "" ! 114: "bitw %0,%1") ! 115: ! 116: (define_insn "" ! 117: [(set (cc0) ! 118: (and:QI (match_operand:QI 0 "general_operand" "g") ! 119: (match_operand:QI 1 "general_operand" "g")))] ! 120: "" ! 121: "bitb %0,%1") ! 122: ! 123: ;; The vax has no sltu or sgeu patterns, but does have two-operand ! 124: ;; add/subtract with carry. This is still better than the alternative. ! 125: ;; Since the cc0-using insn cannot be separated from the cc0-setting insn, ! 126: ;; and the two are created independently, we can't just use a define_expand ! 127: ;; to try to optimize this. (The "movl" and "clrl" insns alter the cc0 ! 128: ;; flags, but leave the carry flag alone, but that can't easily be expressed.) ! 129: ;; ! 130: ;; Several two-operator combinations could be added to make slightly more ! 131: ;; optimal code, but they'd have to cover all combinations of plus and minus ! 132: ;; using match_dup. If you want to do this, I'd suggest changing the "sgeu" ! 133: ;; pattern to something like (minus (const_int 1) (ltu ...)), so fewer ! 134: ;; patterns need to be recognized. ! 135: ;; -- Ken Raeburn ([email protected]) 24 August 1991. ! 136: ! 137: (define_insn "sltu" ! 138: [(set (match_operand:SI 0 "general_operand" "=ro") ! 139: (ltu (cc0) (const_int 0)))] ! 140: "" ! 141: "clrl %0\;adwc $0,%0") ! 142: ! 143: (define_insn "sgeu" ! 144: [(set (match_operand:SI 0 "general_operand" "=ro") ! 145: (geu (cc0) (const_int 0)))] ! 146: "" ! 147: "movl $1,%0\;sbwc $0,%0") ! 148: ! 149: (define_insn "movdf" ! 150: [(set (match_operand:DF 0 "general_operand" "=g,g") ! 151: (match_operand:DF 1 "general_operand" "G,gF"))] ! 152: "" ! 153: "@ ! 154: clr%# %0 ! 155: mov%# %1,%0") ! 156: ! 157: (define_insn "movsf" ! 158: [(set (match_operand:SF 0 "general_operand" "=g,g") ! 159: (match_operand:SF 1 "general_operand" "G,gF"))] ! 160: "" ! 161: "@ ! 162: clrf %0 ! 163: movf %1,%0") ! 164: ! 165: ;; Some vaxes don't support this instruction. ! 166: ;;(define_insn "movti" ! 167: ;; [(set (match_operand:TI 0 "general_operand" "=g") ! 168: ;; (match_operand:TI 1 "general_operand" "g"))] ! 169: ;; "" ! 170: ;; "movh %1,%0") ! 171: ! 172: (define_insn "movdi" ! 173: [(set (match_operand:DI 0 "general_operand" "=g,g") ! 174: (match_operand:DI 1 "general_operand" "I,g"))] ! 175: "" ! 176: "@ ! 177: clrq %0 ! 178: movq %D1,%0") ! 179: ! 180: ;; The VAX move instructions have space-time tradeoffs. On a microVAX ! 181: ;; register-register mov instructions take 3 bytes and 2 CPU cycles. clrl ! 182: ;; takes 2 bytes and 3 cycles. mov from constant to register takes 2 cycles ! 183: ;; if the constant is smaller than 4 bytes, 3 cycles for a longword ! 184: ;; constant. movz, mneg, and mcom are as fast as mov, so movzwl is faster ! 185: ;; than movl for positive constants that fit in 16 bits but not 6 bits. cvt ! 186: ;; instructions take 4 cycles. inc takes 3 cycles. The machine description ! 187: ;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl ! 188: ;; instead of movl). ! 189: ! 190: ;; Cycle counts for other models may vary (on a VAX 750 they are similar, ! 191: ;; but on a VAX 9000 most move and add instructions with one constant ! 192: ;; operand take 1 cycle). ! 193: ! 194: ;; Loads of constants between 64 and 128 used to be done with ! 195: ;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space. ! 196: ! 197: (define_insn "movsi" ! 198: [(set (match_operand:SI 0 "general_operand" "=g") ! 199: (match_operand:SI 1 "general_operand" "g"))] ! 200: "" ! 201: "* ! 202: { ! 203: rtx link; ! 204: if (operands[1] == const1_rtx ! 205: && (link = find_reg_note (insn, REG_WAS_0, 0)) ! 206: /* Make sure the insn that stored the 0 is still present. */ ! 207: && ! INSN_DELETED_P (XEXP (link, 0)) ! 208: && GET_CODE (XEXP (link, 0)) != NOTE ! 209: /* Make sure cross jumping didn't happen here. */ ! 210: && no_labels_between_p (XEXP (link, 0), insn) ! 211: /* Make sure the reg hasn't been clobbered. */ ! 212: && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) ! 213: return \"incl %0\"; ! 214: if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) ! 215: { ! 216: if (push_operand (operands[0], SImode)) ! 217: return \"pushab %a1\"; ! 218: return \"movab %a1,%0\"; ! 219: } ! 220: if (operands[1] == const0_rtx) ! 221: return \"clrl %0\"; ! 222: if (GET_CODE (operands[1]) == CONST_INT ! 223: && (unsigned) INTVAL (operands[1]) >= 64) ! 224: { ! 225: int i = INTVAL (operands[1]); ! 226: if ((unsigned)(~i) < 64) ! 227: return \"mcoml %N1,%0\"; ! 228: if ((unsigned)i < 0x100) ! 229: return \"movzbl %1,%0\"; ! 230: if (i >= -0x80 && i < 0) ! 231: return \"cvtbl %1,%0\"; ! 232: if ((unsigned)i < 0x10000) ! 233: return \"movzwl %1,%0\"; ! 234: if (i >= -0x8000 && i < 0) ! 235: return \"cvtwl %1,%0\"; ! 236: } ! 237: if (push_operand (operands[0], SImode)) ! 238: return \"pushl %1\"; ! 239: return \"movl %1,%0\"; ! 240: }") ! 241: ! 242: (define_insn "movhi" ! 243: [(set (match_operand:HI 0 "general_operand" "=g") ! 244: (match_operand:HI 1 "general_operand" "g"))] ! 245: "" ! 246: "* ! 247: { ! 248: rtx link; ! 249: if (operands[1] == const1_rtx ! 250: && (link = find_reg_note (insn, REG_WAS_0, 0)) ! 251: /* Make sure the insn that stored the 0 is still present. */ ! 252: && ! INSN_DELETED_P (XEXP (link, 0)) ! 253: && GET_CODE (XEXP (link, 0)) != NOTE ! 254: /* Make sure cross jumping didn't happen here. */ ! 255: && no_labels_between_p (XEXP (link, 0), insn) ! 256: /* Make sure the reg hasn't been clobbered. */ ! 257: && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) ! 258: return \"incw %0\"; ! 259: ! 260: if (GET_CODE (operands[1]) == CONST_INT) ! 261: { ! 262: int i = INTVAL (operands[1]); ! 263: if (i == 0) ! 264: return \"clrw %0\"; ! 265: else if ((unsigned int)i < 64) ! 266: return \"movw %1,%0\"; ! 267: else if ((unsigned int)~i < 64) ! 268: return \"mcomw %H1,%0\"; ! 269: else if ((unsigned int)i < 256) ! 270: return \"movzbw %1,%0\"; ! 271: } ! 272: return \"movw %1,%0\"; ! 273: }") ! 274: ! 275: (define_insn "movstricthi" ! 276: [(set (strict_low_part (match_operand:HI 0 "register_operand" "=g")) ! 277: (match_operand:HI 1 "general_operand" "g"))] ! 278: "" ! 279: "* ! 280: { ! 281: if (GET_CODE (operands[1]) == CONST_INT) ! 282: { ! 283: int i = INTVAL (operands[1]); ! 284: if (i == 0) ! 285: return \"clrw %0\"; ! 286: else if ((unsigned int)i < 64) ! 287: return \"movw %1,%0\"; ! 288: else if ((unsigned int)~i < 64) ! 289: return \"mcomw %H1,%0\"; ! 290: else if ((unsigned int)i < 256) ! 291: return \"movzbw %1,%0\"; ! 292: } ! 293: return \"movw %1,%0\"; ! 294: }") ! 295: ! 296: (define_insn "movqi" ! 297: [(set (match_operand:QI 0 "general_operand" "=g") ! 298: (match_operand:QI 1 "general_operand" "g"))] ! 299: "" ! 300: "* ! 301: { ! 302: rtx link; ! 303: if (operands[1] == const1_rtx ! 304: && (link = find_reg_note (insn, REG_WAS_0, 0)) ! 305: /* Make sure the insn that stored the 0 is still present. */ ! 306: && ! INSN_DELETED_P (XEXP (link, 0)) ! 307: && GET_CODE (XEXP (link, 0)) != NOTE ! 308: /* Make sure cross jumping didn't happen here. */ ! 309: && no_labels_between_p (XEXP (link, 0), insn) ! 310: /* Make sure the reg hasn't been clobbered. */ ! 311: && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) ! 312: return \"incb %0\"; ! 313: ! 314: if (GET_CODE (operands[1]) == CONST_INT) ! 315: { ! 316: int i = INTVAL (operands[1]); ! 317: if (i == 0) ! 318: return \"clrb %0\"; ! 319: else if ((unsigned int)~i < 64) ! 320: return \"mcomb %B1,%0\"; ! 321: } ! 322: return \"movb %1,%0\"; ! 323: }") ! 324: ! 325: (define_insn "movstrictqi" ! 326: [(set (strict_low_part (match_operand:QI 0 "register_operand" "=g")) ! 327: (match_operand:QI 1 "general_operand" "g"))] ! 328: "" ! 329: "* ! 330: { ! 331: if (GET_CODE (operands[1]) == CONST_INT) ! 332: { ! 333: int i = INTVAL (operands[1]); ! 334: if (i == 0) ! 335: return \"clrb %0\"; ! 336: else if ((unsigned int)~i < 64) ! 337: return \"mcomb %B1,%0\"; ! 338: } ! 339: return \"movb %1,%0\"; ! 340: }") ! 341: ! 342: ;; This is here to accept 4 arguments and pass the first 3 along ! 343: ;; to the movstrhi1 pattern that really does the work. ! 344: (define_expand "movstrhi" ! 345: [(set (match_operand:BLK 0 "general_operand" "=g") ! 346: (match_operand:BLK 1 "general_operand" "g")) ! 347: (use (match_operand:HI 2 "general_operand" "g")) ! 348: (match_operand 3 "" "")] ! 349: "" ! 350: " ! 351: emit_insn (gen_movstrhi1 (operands[0], operands[1], operands[2])); ! 352: DONE; ! 353: ") ! 354: ! 355: ;; The definition of this insn does not really explain what it does, ! 356: ;; but it should suffice ! 357: ;; that anything generated as this insn will be recognized as one ! 358: ;; and that it won't successfully combine with anything. ! 359: (define_insn "movstrhi1" ! 360: [(set (match_operand:BLK 0 "general_operand" "=g") ! 361: (match_operand:BLK 1 "general_operand" "g")) ! 362: (use (match_operand:HI 2 "general_operand" "g")) ! 363: (clobber (reg:SI 0)) ! 364: (clobber (reg:SI 1)) ! 365: (clobber (reg:SI 2)) ! 366: (clobber (reg:SI 3)) ! 367: (clobber (reg:SI 4)) ! 368: (clobber (reg:SI 5))] ! 369: "" ! 370: "movc3 %2,%1,%0") ! 371: ! 372: ;; Extension and truncation insns. ! 373: ! 374: (define_insn "truncsiqi2" ! 375: [(set (match_operand:QI 0 "general_operand" "=g") ! 376: (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "g")))] ! 377: "" ! 378: "cvtlb %1,%0") ! 379: ! 380: (define_insn "truncsihi2" ! 381: [(set (match_operand:HI 0 "general_operand" "=g") ! 382: (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "g")))] ! 383: "" ! 384: "cvtlw %1,%0") ! 385: ! 386: (define_insn "trunchiqi2" ! 387: [(set (match_operand:QI 0 "general_operand" "=g") ! 388: (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] ! 389: "" ! 390: "cvtwb %1,%0") ! 391: ! 392: (define_insn "extendhisi2" ! 393: [(set (match_operand:SI 0 "general_operand" "=g") ! 394: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] ! 395: "" ! 396: "cvtwl %1,%0") ! 397: ! 398: (define_insn "extendqihi2" ! 399: [(set (match_operand:HI 0 "general_operand" "=g") ! 400: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] ! 401: "" ! 402: "cvtbw %1,%0") ! 403: ! 404: (define_insn "extendqisi2" ! 405: [(set (match_operand:SI 0 "general_operand" "=g") ! 406: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] ! 407: "" ! 408: "cvtbl %1,%0") ! 409: ! 410: (define_insn "extendsfdf2" ! 411: [(set (match_operand:DF 0 "general_operand" "=g") ! 412: (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))] ! 413: "" ! 414: "cvtf%# %1,%0") ! 415: ! 416: (define_insn "truncdfsf2" ! 417: [(set (match_operand:SF 0 "general_operand" "=g") ! 418: (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))] ! 419: "" ! 420: "cvt%#f %1,%0") ! 421: ! 422: (define_insn "zero_extendhisi2" ! 423: [(set (match_operand:SI 0 "general_operand" "=g") ! 424: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] ! 425: "" ! 426: "movzwl %1,%0") ! 427: ! 428: (define_insn "zero_extendqihi2" ! 429: [(set (match_operand:HI 0 "general_operand" "=g") ! 430: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] ! 431: "" ! 432: "movzbw %1,%0") ! 433: ! 434: (define_insn "zero_extendqisi2" ! 435: [(set (match_operand:SI 0 "general_operand" "=g") ! 436: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] ! 437: "" ! 438: "movzbl %1,%0") ! 439: ! 440: ;; Fix-to-float conversion insns. ! 441: ! 442: (define_insn "floatsisf2" ! 443: [(set (match_operand:SF 0 "general_operand" "=g") ! 444: (float:SF (match_operand:SI 1 "nonimmediate_operand" "g")))] ! 445: "" ! 446: "cvtlf %1,%0") ! 447: ! 448: (define_insn "floatsidf2" ! 449: [(set (match_operand:DF 0 "general_operand" "=g") ! 450: (float:DF (match_operand:SI 1 "nonimmediate_operand" "g")))] ! 451: "" ! 452: "cvtl%# %1,%0") ! 453: ! 454: (define_insn "floathisf2" ! 455: [(set (match_operand:SF 0 "general_operand" "=g") ! 456: (float:SF (match_operand:HI 1 "nonimmediate_operand" "g")))] ! 457: "" ! 458: "cvtwf %1,%0") ! 459: ! 460: (define_insn "floathidf2" ! 461: [(set (match_operand:DF 0 "general_operand" "=g") ! 462: (float:DF (match_operand:HI 1 "nonimmediate_operand" "g")))] ! 463: "" ! 464: "cvtw%# %1,%0") ! 465: ! 466: (define_insn "floatqisf2" ! 467: [(set (match_operand:SF 0 "general_operand" "=g") ! 468: (float:SF (match_operand:QI 1 "nonimmediate_operand" "g")))] ! 469: "" ! 470: "cvtbf %1,%0") ! 471: ! 472: (define_insn "floatqidf2" ! 473: [(set (match_operand:DF 0 "general_operand" "=g") ! 474: (float:DF (match_operand:QI 1 "nonimmediate_operand" "g")))] ! 475: "" ! 476: "cvtb%# %1,%0") ! 477: ! 478: ;; Float-to-fix conversion insns. ! 479: ! 480: (define_insn "fix_truncsfqi2" ! 481: [(set (match_operand:QI 0 "general_operand" "=g") ! 482: (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] ! 483: "" ! 484: "cvtfb %1,%0") ! 485: ! 486: (define_insn "fix_truncsfhi2" ! 487: [(set (match_operand:HI 0 "general_operand" "=g") ! 488: (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] ! 489: "" ! 490: "cvtfw %1,%0") ! 491: ! 492: (define_insn "fix_truncsfsi2" ! 493: [(set (match_operand:SI 0 "general_operand" "=g") ! 494: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] ! 495: "" ! 496: "cvtfl %1,%0") ! 497: ! 498: (define_insn "fix_truncdfqi2" ! 499: [(set (match_operand:QI 0 "general_operand" "=g") ! 500: (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] ! 501: "" ! 502: "cvt%#b %1,%0") ! 503: ! 504: (define_insn "fix_truncdfhi2" ! 505: [(set (match_operand:HI 0 "general_operand" "=g") ! 506: (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] ! 507: "" ! 508: "cvt%#w %1,%0") ! 509: ! 510: (define_insn "fix_truncdfsi2" ! 511: [(set (match_operand:SI 0 "general_operand" "=g") ! 512: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] ! 513: "" ! 514: "cvt%#l %1,%0") ! 515: ! 516: ;;- All kinds of add instructions. ! 517: ! 518: (define_insn "adddf3" ! 519: [(set (match_operand:DF 0 "general_operand" "=g,g,g") ! 520: (plus:DF (match_operand:DF 1 "general_operand" "0,gF,gF") ! 521: (match_operand:DF 2 "general_operand" "gF,0,gF")))] ! 522: "" ! 523: "@ ! 524: add%#2 %2,%0 ! 525: add%#2 %1,%0 ! 526: add%#3 %1,%2,%0") ! 527: ! 528: (define_insn "addsf3" ! 529: [(set (match_operand:SF 0 "general_operand" "=g,g,g") ! 530: (plus:SF (match_operand:SF 1 "general_operand" "0,gF,gF") ! 531: (match_operand:SF 2 "general_operand" "gF,0,gF")))] ! 532: "" ! 533: "@ ! 534: addf2 %2,%0 ! 535: addf2 %1,%0 ! 536: addf3 %1,%2,%0") ! 537: ! 538: /* The space-time-opcode tradeoffs for addition vary by model of VAX. ! 539: ! 540: On a VAX 3 "movab (r1)[r2],r3" is faster than "addl3 r1,r2,r3", ! 541: but it not faster on other models. ! 542: ! 543: "movab #(r1),r2" is usually shorter than "addl3 #,r1,r2", and is ! 544: faster on a VAX 3, but some VAXes (e.g. VAX 9000) will stall if ! 545: a register is used in an address too soon after it is set. ! 546: Compromise by using movab only when it is shorter than the add ! 547: or the base register in the address is one of sp, ap, and fp, ! 548: which are not modified very often. */ ! 549: ! 550: ! 551: (define_insn "addsi3" ! 552: [(set (match_operand:SI 0 "general_operand" "=g") ! 553: (plus:SI (match_operand:SI 1 "general_operand" "g") ! 554: (match_operand:SI 2 "general_operand" "g")))] ! 555: "" ! 556: "* ! 557: { ! 558: if (rtx_equal_p (operands[0], operands[1])) ! 559: { ! 560: if (operands[2] == const1_rtx) ! 561: return \"incl %0\"; ! 562: if (operands[2] == constm1_rtx) ! 563: return \"decl %0\"; ! 564: if (GET_CODE (operands[2]) == CONST_INT ! 565: && (unsigned) (- INTVAL (operands[2])) < 64) ! 566: return \"subl2 $%n2,%0\"; ! 567: if (GET_CODE (operands[2]) == CONST_INT ! 568: && (unsigned) INTVAL (operands[2]) >= 64 ! 569: && GET_CODE (operands[1]) == REG ! 570: && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768) ! 571: || REGNO (operands[1]) > 11)) ! 572: return \"movab %c2(%1),%0\"; ! 573: return \"addl2 %2,%0\"; ! 574: } ! 575: if (rtx_equal_p (operands[0], operands[2])) ! 576: return \"addl2 %1,%0\"; ! 577: ! 578: if (GET_CODE (operands[2]) == CONST_INT ! 579: && INTVAL (operands[2]) < 32767 ! 580: && INTVAL (operands[2]) > -32768 ! 581: && GET_CODE (operands[1]) == REG ! 582: && push_operand (operands[0], SImode)) ! 583: return \"pushab %c2(%1)\"; ! 584: ! 585: if (GET_CODE (operands[2]) == CONST_INT ! 586: && (unsigned) (- INTVAL (operands[2])) < 64) ! 587: return \"subl3 $%n2,%1,%0\"; ! 588: ! 589: if (GET_CODE (operands[2]) == CONST_INT ! 590: && (unsigned) INTVAL (operands[2]) >= 64 ! 591: && GET_CODE (operands[1]) == REG ! 592: && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768) ! 593: || REGNO (operands[1]) > 11)) ! 594: return \"movab %c2(%1),%0\"; ! 595: ! 596: /* Add this if using gcc on a VAX 3xxx: ! 597: if (REG_P (operands[1]) && REG_P (operands[2])) ! 598: return \"movab (%1)[%2],%0\"; ! 599: */ ! 600: return \"addl3 %1,%2,%0\"; ! 601: }") ! 602: ! 603: (define_insn "addhi3" ! 604: [(set (match_operand:HI 0 "general_operand" "=g") ! 605: (plus:HI (match_operand:HI 1 "general_operand" "g") ! 606: (match_operand:HI 2 "general_operand" "g")))] ! 607: "" ! 608: "* ! 609: { ! 610: if (rtx_equal_p (operands[0], operands[1])) ! 611: { ! 612: if (operands[2] == const1_rtx) ! 613: return \"incw %0\"; ! 614: if (operands[2] == constm1_rtx) ! 615: return \"decw %0\"; ! 616: if (GET_CODE (operands[2]) == CONST_INT ! 617: && (unsigned) (- INTVAL (operands[2])) < 64) ! 618: return \"subw2 $%n2,%0\"; ! 619: return \"addw2 %2,%0\"; ! 620: } ! 621: if (rtx_equal_p (operands[0], operands[2])) ! 622: return \"addw2 %1,%0\"; ! 623: if (GET_CODE (operands[2]) == CONST_INT ! 624: && (unsigned) (- INTVAL (operands[2])) < 64) ! 625: return \"subw3 $%n2,%1,%0\"; ! 626: return \"addw3 %1,%2,%0\"; ! 627: }") ! 628: ! 629: (define_insn "addqi3" ! 630: [(set (match_operand:QI 0 "general_operand" "=g") ! 631: (plus:QI (match_operand:QI 1 "general_operand" "g") ! 632: (match_operand:QI 2 "general_operand" "g")))] ! 633: "" ! 634: "* ! 635: { ! 636: if (rtx_equal_p (operands[0], operands[1])) ! 637: { ! 638: if (operands[2] == const1_rtx) ! 639: return \"incb %0\"; ! 640: if (operands[2] == constm1_rtx) ! 641: return \"decb %0\"; ! 642: if (GET_CODE (operands[2]) == CONST_INT ! 643: && (unsigned) (- INTVAL (operands[2])) < 64) ! 644: return \"subb2 $%n2,%0\"; ! 645: return \"addb2 %2,%0\"; ! 646: } ! 647: if (rtx_equal_p (operands[0], operands[2])) ! 648: return \"addb2 %1,%0\"; ! 649: if (GET_CODE (operands[2]) == CONST_INT ! 650: && (unsigned) (- INTVAL (operands[2])) < 64) ! 651: return \"subb3 $%n2,%1,%0\"; ! 652: return \"addb3 %1,%2,%0\"; ! 653: }") ! 654: ! 655: ;; The add-with-carry (adwc) instruction only accepts two operands. ! 656: (define_insn "adddi3" ! 657: [(set (match_operand:DI 0 "general_operand" "=ro>,ro>") ! 658: (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") ! 659: (match_operand:DI 2 "general_operand" "Fro,F")))] ! 660: "" ! 661: "* ! 662: { ! 663: rtx low[3]; ! 664: char *pattern; ! 665: int carry = 1; ! 666: ! 667: split_quadword_operands (operands, low, 3); ! 668: /* Add low parts. */ ! 669: if (rtx_equal_p (operands[0], operands[1])) ! 670: { ! 671: if (low[2] == const0_rtx) ! 672: /* Should examine operand, punt if not POST_INC. */ ! 673: pattern = \"tstl %0\", carry = 0; ! 674: else if (low[2] == const1_rtx) ! 675: pattern = \"incl %0\"; ! 676: else ! 677: pattern = \"addl2 %2,%0\"; ! 678: } ! 679: else ! 680: { ! 681: if (low[2] == const0_rtx) ! 682: pattern = \"movl %1,%0\", carry = 0; ! 683: else ! 684: pattern = \"addl3 %2,%1,%0\"; ! 685: } ! 686: if (pattern) ! 687: output_asm_insn (pattern, low); ! 688: if (!carry) ! 689: /* If CARRY is 0, we don't have any carry value to worry about. */ ! 690: return OUT_FCN (CODE_FOR_addsi3) (operands, insn); ! 691: /* %0 = C + %1 + %2 */ ! 692: if (!rtx_equal_p (operands[0], operands[1])) ! 693: output_asm_insn ((operands[1] == const0_rtx ! 694: ? \"clrl %0\" ! 695: : \"movl %1,%0\"), operands); ! 696: return \"adwc %2,%0\"; ! 697: }") ! 698: ! 699: ;;- All kinds of subtract instructions. ! 700: ! 701: (define_insn "subdf3" ! 702: [(set (match_operand:DF 0 "general_operand" "=g,g") ! 703: (minus:DF (match_operand:DF 1 "general_operand" "0,gF") ! 704: (match_operand:DF 2 "general_operand" "gF,gF")))] ! 705: "" ! 706: "@ ! 707: sub%#2 %2,%0 ! 708: sub%#3 %2,%1,%0") ! 709: ! 710: (define_insn "subsf3" ! 711: [(set (match_operand:SF 0 "general_operand" "=g,g") ! 712: (minus:SF (match_operand:SF 1 "general_operand" "0,gF") ! 713: (match_operand:SF 2 "general_operand" "gF,gF")))] ! 714: "" ! 715: "@ ! 716: subf2 %2,%0 ! 717: subf3 %2,%1,%0") ! 718: ! 719: (define_insn "subsi3" ! 720: [(set (match_operand:SI 0 "general_operand" "=g,g") ! 721: (minus:SI (match_operand:SI 1 "general_operand" "0,g") ! 722: (match_operand:SI 2 "general_operand" "g,g")))] ! 723: "" ! 724: "@ ! 725: subl2 %2,%0 ! 726: subl3 %2,%1,%0") ! 727: ! 728: (define_insn "subhi3" ! 729: [(set (match_operand:HI 0 "general_operand" "=g,g") ! 730: (minus:HI (match_operand:HI 1 "general_operand" "0,g") ! 731: (match_operand:HI 2 "general_operand" "g,g")))] ! 732: "" ! 733: "@ ! 734: subw2 %2,%0 ! 735: subw3 %2,%1,%0") ! 736: ! 737: (define_insn "subqi3" ! 738: [(set (match_operand:QI 0 "general_operand" "=g,g") ! 739: (minus:QI (match_operand:QI 1 "general_operand" "0,g") ! 740: (match_operand:QI 2 "general_operand" "g,g")))] ! 741: "" ! 742: "@ ! 743: subb2 %2,%0 ! 744: subb3 %2,%1,%0") ! 745: ! 746: ;; The subtract-with-carry (sbwc) instruction only takes two operands. ! 747: (define_insn "subdi3" ! 748: [(set (match_operand:DI 0 "general_operand" "=or>,or>") ! 749: (minus:DI (match_operand:DI 1 "general_operand" "0,or>") ! 750: (match_operand:DI 2 "general_operand" "For,F")))] ! 751: "" ! 752: "* ! 753: { ! 754: rtx low[3]; ! 755: char *pattern; ! 756: int carry = 1; ! 757: ! 758: split_quadword_operands (operands, low, 3); ! 759: /* Subtract low parts. */ ! 760: if (rtx_equal_p (operands[0], operands[1])) ! 761: { ! 762: if (low[2] == const0_rtx) ! 763: pattern = 0, carry = 0; ! 764: else if (low[2] == constm1_rtx) ! 765: pattern = \"decl %0\"; ! 766: else ! 767: pattern = \"subl2 %2,%0\"; ! 768: } ! 769: else ! 770: { ! 771: if (low[2] == constm1_rtx) ! 772: pattern = \"decl %0\"; ! 773: else if (low[2] == const0_rtx) ! 774: pattern = OUT_FCN (CODE_FOR_movsi) (low, insn), carry = 0; ! 775: else ! 776: pattern = \"subl3 %2,%1,%0\"; ! 777: } ! 778: if (pattern) ! 779: output_asm_insn (pattern, low); ! 780: if (carry) ! 781: { ! 782: if (!rtx_equal_p (operands[0], operands[1])) ! 783: return \"movl %1,%0\;sbwc %2,%0\"; ! 784: return \"sbwc %2,%0\"; ! 785: /* %0 = %2 - %1 - C */ ! 786: } ! 787: return OUT_FCN (CODE_FOR_subsi3) (operands, insn); ! 788: }") ! 789: ! 790: ;;- Multiply instructions. ! 791: ! 792: (define_insn "muldf3" ! 793: [(set (match_operand:DF 0 "general_operand" "=g,g,g") ! 794: (mult:DF (match_operand:DF 1 "general_operand" "0,gF,gF") ! 795: (match_operand:DF 2 "general_operand" "gF,0,gF")))] ! 796: "" ! 797: "@ ! 798: mul%#2 %2,%0 ! 799: mul%#2 %1,%0 ! 800: mul%#3 %1,%2,%0") ! 801: ! 802: (define_insn "mulsf3" ! 803: [(set (match_operand:SF 0 "general_operand" "=g,g,g") ! 804: (mult:SF (match_operand:SF 1 "general_operand" "0,gF,gF") ! 805: (match_operand:SF 2 "general_operand" "gF,0,gF")))] ! 806: "" ! 807: "@ ! 808: mulf2 %2,%0 ! 809: mulf2 %1,%0 ! 810: mulf3 %1,%2,%0") ! 811: ! 812: (define_insn "mulsi3" ! 813: [(set (match_operand:SI 0 "general_operand" "=g,g,g") ! 814: (mult:SI (match_operand:SI 1 "general_operand" "0,g,g") ! 815: (match_operand:SI 2 "general_operand" "g,0,g")))] ! 816: "" ! 817: "@ ! 818: mull2 %2,%0 ! 819: mull2 %1,%0 ! 820: mull3 %1,%2,%0") ! 821: ! 822: (define_insn "mulhi3" ! 823: [(set (match_operand:HI 0 "general_operand" "=g,g,") ! 824: (mult:HI (match_operand:HI 1 "general_operand" "0,g,g") ! 825: (match_operand:HI 2 "general_operand" "g,0,g")))] ! 826: "" ! 827: "@ ! 828: mulw2 %2,%0 ! 829: mulw2 %1,%0 ! 830: mulw3 %1,%2,%0") ! 831: ! 832: (define_insn "mulqi3" ! 833: [(set (match_operand:QI 0 "general_operand" "=g,g,g") ! 834: (mult:QI (match_operand:QI 1 "general_operand" "0,g,g") ! 835: (match_operand:QI 2 "general_operand" "g,0,g")))] ! 836: "" ! 837: "@ ! 838: mulb2 %2,%0 ! 839: mulb2 %1,%0 ! 840: mulb3 %1,%2,%0") ! 841: ! 842: (define_insn "mulsidi3" ! 843: [(set (match_operand:DI 0 "general_operand" "=g") ! 844: (mult:DI (sign_extend:DI ! 845: (match_operand:SI 1 "nonimmediate_operand" "g")) ! 846: (sign_extend:DI ! 847: (match_operand:SI 2 "nonimmediate_operand" "g"))))] ! 848: "" ! 849: "emul %1,%2,$0,%0") ! 850: ! 851: (define_insn "" ! 852: [(set (match_operand:DI 0 "general_operand" "=g") ! 853: (plus:DI ! 854: (mult:DI (sign_extend:DI ! 855: (match_operand:SI 1 "nonimmediate_operand" "g")) ! 856: (sign_extend:DI ! 857: (match_operand:SI 2 "nonimmediate_operand" "g"))) ! 858: (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))] ! 859: "" ! 860: "emul %1,%2,%3,%0") ! 861: ! 862: ;; 'F' constraint means type CONST_DOUBLE ! 863: (define_insn "" ! 864: [(set (match_operand:DI 0 "general_operand" "=g") ! 865: (plus:DI ! 866: (mult:DI (sign_extend:DI ! 867: (match_operand:SI 1 "nonimmediate_operand" "g")) ! 868: (sign_extend:DI ! 869: (match_operand:SI 2 "nonimmediate_operand" "g"))) ! 870: (match_operand:DI 3 "immediate_operand" "F")))] ! 871: "GET_CODE (operands[3]) == CONST_DOUBLE ! 872: && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" ! 873: "* ! 874: { ! 875: if (CONST_DOUBLE_HIGH (operands[3])) ! 876: operands[3] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[3])); ! 877: return \"emul %1,%2,%3,%0\"; ! 878: }") ! 879: ! 880: ;;- Divide instructions. ! 881: ! 882: (define_insn "divdf3" ! 883: [(set (match_operand:DF 0 "general_operand" "=g,g") ! 884: (div:DF (match_operand:DF 1 "general_operand" "0,gF") ! 885: (match_operand:DF 2 "general_operand" "gF,gF")))] ! 886: "" ! 887: "@ ! 888: div%#2 %2,%0 ! 889: div%#3 %2,%1,%0") ! 890: ! 891: (define_insn "divsf3" ! 892: [(set (match_operand:SF 0 "general_operand" "=g,g") ! 893: (div:SF (match_operand:SF 1 "general_operand" "0,gF") ! 894: (match_operand:SF 2 "general_operand" "gF,gF")))] ! 895: "" ! 896: "@ ! 897: divf2 %2,%0 ! 898: divf3 %2,%1,%0") ! 899: ! 900: (define_insn "divsi3" ! 901: [(set (match_operand:SI 0 "general_operand" "=g,g") ! 902: (div:SI (match_operand:SI 1 "general_operand" "0,g") ! 903: (match_operand:SI 2 "general_operand" "g,g")))] ! 904: "" ! 905: "@ ! 906: divl2 %2,%0 ! 907: divl3 %2,%1,%0") ! 908: ! 909: (define_insn "divhi3" ! 910: [(set (match_operand:HI 0 "general_operand" "=g,g") ! 911: (div:HI (match_operand:HI 1 "general_operand" "0,g") ! 912: (match_operand:HI 2 "general_operand" "g,g")))] ! 913: "" ! 914: "@ ! 915: divw2 %2,%0 ! 916: divw3 %2,%1,%0") ! 917: ! 918: (define_insn "divqi3" ! 919: [(set (match_operand:QI 0 "general_operand" "=g,g") ! 920: (div:QI (match_operand:QI 1 "general_operand" "0,g") ! 921: (match_operand:QI 2 "general_operand" "g,g")))] ! 922: "" ! 923: "@ ! 924: divb2 %2,%0 ! 925: divb3 %2,%1,%0") ! 926: ! 927: ;This is left out because it is very slow; ! 928: ;we are better off programming around the "lack" of this insn. ! 929: ;(define_insn "divmoddisi4" ! 930: ; [(set (match_operand:SI 0 "general_operand" "=g") ! 931: ; (div:SI (match_operand:DI 1 "general_operand" "g") ! 932: ; (match_operand:SI 2 "general_operand" "g"))) ! 933: ; (set (match_operand:SI 3 "general_operand" "=g") ! 934: ; (mod:SI (match_operand:DI 1 "general_operand" "g") ! 935: ; (match_operand:SI 2 "general_operand" "g")))] ! 936: ; "" ! 937: ; "ediv %2,%1,%0,%3") ! 938: ! 939: ;; Bit-and on the vax is done with a clear-bits insn. ! 940: (define_expand "andsi3" ! 941: [(set (match_operand:SI 0 "general_operand" "=g") ! 942: (and:SI (not:SI (match_operand:SI 1 "general_operand" "g")) ! 943: (match_operand:SI 2 "general_operand" "g")))] ! 944: "" ! 945: " ! 946: { ! 947: rtx op1 = operands[1]; ! 948: ! 949: /* If there is a constant argument, complement that one. */ ! 950: if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT) ! 951: { ! 952: operands[1] = operands[2]; ! 953: operands[2] = op1; ! 954: op1 = operands[1]; ! 955: } ! 956: ! 957: if (GET_CODE (op1) == CONST_INT) ! 958: operands[1] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (op1)); ! 959: else ! 960: operands[1] = expand_unop (SImode, one_cmpl_optab, op1, 0, 1); ! 961: }") ! 962: ! 963: (define_expand "andhi3" ! 964: [(set (match_operand:HI 0 "general_operand" "=g") ! 965: (and:HI (not:HI (match_operand:HI 1 "general_operand" "g")) ! 966: (match_operand:HI 2 "general_operand" "g")))] ! 967: "" ! 968: " ! 969: { ! 970: rtx op1 = operands[1]; ! 971: ! 972: if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT) ! 973: { ! 974: operands[1] = operands[2]; ! 975: operands[2] = op1; ! 976: op1 = operands[1]; ! 977: } ! 978: ! 979: if (GET_CODE (op1) == CONST_INT) ! 980: operands[1] = gen_rtx (CONST_INT, VOIDmode, 65535 & ~INTVAL (op1)); ! 981: else ! 982: operands[1] = expand_unop (HImode, one_cmpl_optab, op1, 0, 1); ! 983: }") ! 984: ! 985: (define_expand "andqi3" ! 986: [(set (match_operand:QI 0 "general_operand" "=g") ! 987: (and:QI (not:QI (match_operand:QI 1 "general_operand" "g")) ! 988: (match_operand:QI 2 "general_operand" "g")))] ! 989: "" ! 990: " ! 991: { ! 992: rtx op1 = operands[1]; ! 993: ! 994: if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT) ! 995: { ! 996: operands[1] = operands[2]; ! 997: operands[2] = op1; ! 998: op1 = operands[1]; ! 999: } ! 1000: ! 1001: if (GET_CODE (op1) == CONST_INT) ! 1002: operands[1] = gen_rtx (CONST_INT, VOIDmode, 255 & ~INTVAL (op1)); ! 1003: else ! 1004: operands[1] = expand_unop (QImode, one_cmpl_optab, op1, 0, 1); ! 1005: }") ! 1006: ! 1007: (define_insn "" ! 1008: [(set (match_operand:SI 0 "general_operand" "=g,g") ! 1009: (and:SI (not:SI (match_operand:SI 1 "general_operand" "g,g")) ! 1010: (match_operand:SI 2 "general_operand" "0,g")))] ! 1011: "" ! 1012: "@ ! 1013: bicl2 %1,%0 ! 1014: bicl3 %1,%2,%0") ! 1015: ! 1016: (define_insn "" ! 1017: [(set (match_operand:HI 0 "general_operand" "=g,g") ! 1018: (and:HI (not:HI (match_operand:HI 1 "general_operand" "g,g")) ! 1019: (match_operand:HI 2 "general_operand" "0,g")))] ! 1020: "" ! 1021: "@ ! 1022: bicw2 %1,%0 ! 1023: bicw3 %1,%2,%0") ! 1024: ! 1025: (define_insn "" ! 1026: [(set (match_operand:QI 0 "general_operand" "=g,g") ! 1027: (and:QI (not:QI (match_operand:QI 1 "general_operand" "g,g")) ! 1028: (match_operand:QI 2 "general_operand" "0,g")))] ! 1029: "" ! 1030: "@ ! 1031: bicb2 %1,%0 ! 1032: bicb3 %1,%2,%0") ! 1033: ! 1034: ;; The following used to be needed because constant propagation can ! 1035: ;; create them starting from the bic insn patterns above. This is no ! 1036: ;; longer a problem. However, having these patterns allows optimization ! 1037: ;; opportunities in combine.c. ! 1038: ! 1039: (define_insn "" ! 1040: [(set (match_operand:SI 0 "general_operand" "=g,g") ! 1041: (and:SI (match_operand:SI 1 "general_operand" "0,g") ! 1042: (match_operand:SI 2 "const_int_operand" "n,n")))] ! 1043: "" ! 1044: "@ ! 1045: bicl2 %N2,%0 ! 1046: bicl3 %N2,%1,%0") ! 1047: ! 1048: (define_insn "" ! 1049: [(set (match_operand:HI 0 "general_operand" "=g,g") ! 1050: (and:HI (match_operand:HI 1 "general_operand" "0,g") ! 1051: (match_operand:HI 2 "const_int_operand" "n,n")))] ! 1052: "" ! 1053: "@ ! 1054: bicw2 %H2,%0 ! 1055: bicw3 %H2,%1,%0") ! 1056: ! 1057: (define_insn "" ! 1058: [(set (match_operand:QI 0 "general_operand" "=g,g") ! 1059: (and:QI (match_operand:QI 1 "general_operand" "0,g") ! 1060: (match_operand:QI 2 "const_int_operand" "n,n")))] ! 1061: "" ! 1062: "@ ! 1063: bicb2 %B2,%0 ! 1064: bicb3 %B2,%1,%0") ! 1065: ! 1066: ;;- Bit set instructions. ! 1067: ! 1068: (define_insn "iorsi3" ! 1069: [(set (match_operand:SI 0 "general_operand" "=g,g,g") ! 1070: (ior:SI (match_operand:SI 1 "general_operand" "0,g,g") ! 1071: (match_operand:SI 2 "general_operand" "g,0,g")))] ! 1072: "" ! 1073: "@ ! 1074: bisl2 %2,%0 ! 1075: bisl2 %1,%0 ! 1076: bisl3 %2,%1,%0") ! 1077: ! 1078: (define_insn "iorhi3" ! 1079: [(set (match_operand:HI 0 "general_operand" "=g,g,g") ! 1080: (ior:HI (match_operand:HI 1 "general_operand" "0,g,g") ! 1081: (match_operand:HI 2 "general_operand" "g,0,g")))] ! 1082: "" ! 1083: "@ ! 1084: bisw2 %2,%0 ! 1085: bisw2 %1,%0 ! 1086: bisw3 %2,%1,%0") ! 1087: ! 1088: (define_insn "iorqi3" ! 1089: [(set (match_operand:QI 0 "general_operand" "=g,g,g") ! 1090: (ior:QI (match_operand:QI 1 "general_operand" "0,g,g") ! 1091: (match_operand:QI 2 "general_operand" "g,0,g")))] ! 1092: "" ! 1093: "@ ! 1094: bisb2 %2,%0 ! 1095: bisb2 %1,%0 ! 1096: bisb3 %2,%1,%0") ! 1097: ! 1098: ;;- xor instructions. ! 1099: ! 1100: (define_insn "xorsi3" ! 1101: [(set (match_operand:SI 0 "general_operand" "=g,g,g") ! 1102: (xor:SI (match_operand:SI 1 "general_operand" "0,g,g") ! 1103: (match_operand:SI 2 "general_operand" "g,0,g")))] ! 1104: "" ! 1105: "@ ! 1106: xorl2 %2,%0 ! 1107: xorl2 %1,%0 ! 1108: xorl3 %2,%1,%0") ! 1109: ! 1110: (define_insn "xorhi3" ! 1111: [(set (match_operand:HI 0 "general_operand" "=g,g,g") ! 1112: (xor:HI (match_operand:HI 1 "general_operand" "0,g,g") ! 1113: (match_operand:HI 2 "general_operand" "g,0,g")))] ! 1114: "" ! 1115: "@ ! 1116: xorw2 %2,%0 ! 1117: xorw2 %1,%0 ! 1118: xorw3 %2,%1,%0") ! 1119: ! 1120: (define_insn "xorqi3" ! 1121: [(set (match_operand:QI 0 "general_operand" "=g,g,g") ! 1122: (xor:QI (match_operand:QI 1 "general_operand" "0,g,g") ! 1123: (match_operand:QI 2 "general_operand" "g,0,g")))] ! 1124: "" ! 1125: "@ ! 1126: xorb2 %2,%0 ! 1127: xorb2 %1,%0 ! 1128: xorb3 %2,%1,%0") ! 1129: ! 1130: (define_insn "negdf2" ! 1131: [(set (match_operand:DF 0 "general_operand" "=g") ! 1132: (neg:DF (match_operand:DF 1 "general_operand" "gF")))] ! 1133: "" ! 1134: "mneg%# %1,%0") ! 1135: ! 1136: (define_insn "negsf2" ! 1137: [(set (match_operand:SF 0 "general_operand" "=g") ! 1138: (neg:SF (match_operand:SF 1 "general_operand" "gF")))] ! 1139: "" ! 1140: "mnegf %1,%0") ! 1141: ! 1142: (define_insn "negsi2" ! 1143: [(set (match_operand:SI 0 "general_operand" "=g") ! 1144: (neg:SI (match_operand:SI 1 "general_operand" "g")))] ! 1145: "" ! 1146: "mnegl %1,%0") ! 1147: ! 1148: (define_insn "neghi2" ! 1149: [(set (match_operand:HI 0 "general_operand" "=g") ! 1150: (neg:HI (match_operand:HI 1 "general_operand" "g")))] ! 1151: "" ! 1152: "mnegw %1,%0") ! 1153: ! 1154: (define_insn "negqi2" ! 1155: [(set (match_operand:QI 0 "general_operand" "=g") ! 1156: (neg:QI (match_operand:QI 1 "general_operand" "g")))] ! 1157: "" ! 1158: "mnegb %1,%0") ! 1159: ! 1160: (define_insn "one_cmplsi2" ! 1161: [(set (match_operand:SI 0 "general_operand" "=g") ! 1162: (not:SI (match_operand:SI 1 "general_operand" "g")))] ! 1163: "" ! 1164: "mcoml %1,%0") ! 1165: ! 1166: (define_insn "one_cmplhi2" ! 1167: [(set (match_operand:HI 0 "general_operand" "=g") ! 1168: (not:HI (match_operand:HI 1 "general_operand" "g")))] ! 1169: "" ! 1170: "mcomw %1,%0") ! 1171: ! 1172: (define_insn "one_cmplqi2" ! 1173: [(set (match_operand:QI 0 "general_operand" "=g") ! 1174: (not:QI (match_operand:QI 1 "general_operand" "g")))] ! 1175: "" ! 1176: "mcomb %1,%0") ! 1177: ! 1178: ;; Arithmetic right shift on the vax works by negating the shift count, ! 1179: ;; then emitting a right shift with the shift count negated. This means ! 1180: ;; that all actual shift counts in the RTL will be positive. This ! 1181: ;; prevents converting shifts to ZERO_EXTRACTs with negative positions, ! 1182: ;; which isn't valid. ! 1183: (define_expand "ashrsi3" ! 1184: [(set (match_operand:SI 0 "general_operand" "=g") ! 1185: (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") ! 1186: (match_operand:QI 2 "general_operand" "g")))] ! 1187: "" ! 1188: " ! 1189: { ! 1190: if (GET_CODE (operands[2]) != CONST_INT) ! 1191: operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2])); ! 1192: }") ! 1193: ! 1194: (define_insn "" ! 1195: [(set (match_operand:SI 0 "general_operand" "=g") ! 1196: (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") ! 1197: (match_operand:QI 2 "const_int_operand" "n")))] ! 1198: "" ! 1199: "ashl $%n2,%1,%0") ! 1200: ! 1201: (define_insn "" ! 1202: [(set (match_operand:SI 0 "general_operand" "=g") ! 1203: (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") ! 1204: (neg:QI (match_operand:QI 2 "general_operand" "g"))))] ! 1205: "" ! 1206: "ashl %2,%1,%0") ! 1207: ! 1208: (define_insn "ashlsi3" ! 1209: [(set (match_operand:SI 0 "general_operand" "=g") ! 1210: (ashift:SI (match_operand:SI 1 "general_operand" "g") ! 1211: (match_operand:QI 2 "general_operand" "g")))] ! 1212: "" ! 1213: "* ! 1214: { ! 1215: if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1])) ! 1216: return \"addl2 %0,%0\"; ! 1217: if (GET_CODE (operands[1]) == REG ! 1218: && GET_CODE (operands[2]) == CONST_INT) ! 1219: { ! 1220: int i = INTVAL (operands[2]); ! 1221: if (i == 1) ! 1222: return \"addl3 %1,%1,%0\"; ! 1223: if (i == 2) ! 1224: return \"moval 0[%1],%0\"; ! 1225: if (i == 3) ! 1226: return \"movad 0[%1],%0\"; ! 1227: } ! 1228: return \"ashl %2,%1,%0\"; ! 1229: }") ! 1230: ! 1231: ;; Arithmetic right shift on the vax works by negating the shift count. ! 1232: (define_expand "ashrdi3" ! 1233: [(set (match_operand:DI 0 "general_operand" "=g") ! 1234: (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") ! 1235: (match_operand:QI 2 "general_operand" "g")))] ! 1236: "" ! 1237: " ! 1238: { ! 1239: operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2])); ! 1240: }") ! 1241: ! 1242: (define_insn "ashldi3" ! 1243: [(set (match_operand:DI 0 "general_operand" "=g") ! 1244: (ashift:DI (match_operand:DI 1 "general_operand" "g") ! 1245: (match_operand:QI 2 "general_operand" "g")))] ! 1246: "" ! 1247: "ashq %2,%1,%0") ! 1248: ! 1249: (define_insn "" ! 1250: [(set (match_operand:DI 0 "general_operand" "=g") ! 1251: (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") ! 1252: (neg:QI (match_operand:QI 2 "general_operand" "g"))))] ! 1253: "" ! 1254: "ashq %2,%1,%0") ! 1255: ! 1256: ;; Rotate right on the vax works by negating the shift count. ! 1257: (define_expand "rotrsi3" ! 1258: [(set (match_operand:SI 0 "general_operand" "=g") ! 1259: (rotatert:SI (match_operand:SI 1 "general_operand" "g") ! 1260: (match_operand:QI 2 "general_operand" "g")))] ! 1261: "" ! 1262: " ! 1263: { ! 1264: if (GET_CODE (operands[2]) != CONST_INT) ! 1265: operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2])); ! 1266: }") ! 1267: ! 1268: (define_insn "rotlsi3" ! 1269: [(set (match_operand:SI 0 "general_operand" "=g") ! 1270: (rotate:SI (match_operand:SI 1 "general_operand" "g") ! 1271: (match_operand:QI 2 "general_operand" "g")))] ! 1272: "" ! 1273: "rotl %2,%1,%0") ! 1274: ! 1275: (define_insn "" ! 1276: [(set (match_operand:SI 0 "general_operand" "=g") ! 1277: (rotatert:SI (match_operand:SI 1 "general_operand" "g") ! 1278: (match_operand:QI 2 "const_int_operand" "n")))] ! 1279: "" ! 1280: "rotl $%R2,%1,%0") ! 1281: ! 1282: (define_insn "" ! 1283: [(set (match_operand:SI 0 "general_operand" "=g") ! 1284: (rotatert:SI (match_operand:SI 1 "general_operand" "g") ! 1285: (neg:QI (match_operand:QI 2 "general_operand" "g"))))] ! 1286: "" ! 1287: "rotl %2,%1,%0") ! 1288: ! 1289: ;This insn is probably slower than a multiply and an add. ! 1290: ;(define_insn "" ! 1291: ; [(set (match_operand:SI 0 "general_operand" "=g") ! 1292: ; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") ! 1293: ; (match_operand:SI 2 "general_operand" "g")) ! 1294: ; (match_operand:SI 3 "general_operand" "g")))] ! 1295: ; "" ! 1296: ; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0") ! 1297: ! 1298: ;; Special cases of bit-field insns which we should ! 1299: ;; recognize in preference to the general case. ! 1300: ;; These handle aligned 8-bit and 16-bit fields, ! 1301: ;; which can usually be done with move instructions. ! 1302: ! 1303: (define_insn "" ! 1304: [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+ro") ! 1305: (match_operand:QI 1 "const_int_operand" "n") ! 1306: (match_operand:SI 2 "const_int_operand" "n")) ! 1307: (match_operand:SI 3 "general_operand" "g"))] ! 1308: "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) ! 1309: && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 ! 1310: && (GET_CODE (operands[0]) == REG ! 1311: || ! mode_dependent_address_p (XEXP (operands[0], 0)))" ! 1312: "* ! 1313: { ! 1314: if (REG_P (operands[0])) ! 1315: { ! 1316: if (INTVAL (operands[2]) != 0) ! 1317: return \"insv %3,%2,%1,%0\"; ! 1318: } ! 1319: else ! 1320: operands[0] ! 1321: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); ! 1322: ! 1323: if (INTVAL (operands[1]) == 8) ! 1324: return \"movb %3,%0\"; ! 1325: return \"movw %3,%0\"; ! 1326: }") ! 1327: ! 1328: (define_insn "" ! 1329: [(set (match_operand:SI 0 "general_operand" "=&g") ! 1330: (zero_extract:SI (match_operand:SI 1 "general_operand" "ro") ! 1331: (match_operand:QI 2 "const_int_operand" "n") ! 1332: (match_operand:SI 3 "const_int_operand" "n")))] ! 1333: "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) ! 1334: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 ! 1335: && (GET_CODE (operands[1]) == REG ! 1336: || ! mode_dependent_address_p (XEXP (operands[1], 0)))" ! 1337: "* ! 1338: { ! 1339: if (REG_P (operands[1])) ! 1340: { ! 1341: if (INTVAL (operands[3]) != 0) ! 1342: return \"extzv %3,%2,%1,%0\"; ! 1343: } ! 1344: else ! 1345: operands[1] ! 1346: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 1347: ! 1348: if (INTVAL (operands[2]) == 8) ! 1349: return \"movzbl %1,%0\"; ! 1350: return \"movzwl %1,%0\"; ! 1351: }") ! 1352: ! 1353: (define_insn "" ! 1354: [(set (match_operand:SI 0 "general_operand" "=g") ! 1355: (sign_extract:SI (match_operand:SI 1 "general_operand" "ro") ! 1356: (match_operand:QI 2 "const_int_operand" "n") ! 1357: (match_operand:SI 3 "const_int_operand" "n")))] ! 1358: "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) ! 1359: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 ! 1360: && (GET_CODE (operands[1]) == REG ! 1361: || ! mode_dependent_address_p (XEXP (operands[1], 0)))" ! 1362: "* ! 1363: { ! 1364: if (REG_P (operands[1])) ! 1365: { ! 1366: if (INTVAL (operands[3]) != 0) ! 1367: return \"extv %3,%2,%1,%0\"; ! 1368: } ! 1369: else ! 1370: operands[1] ! 1371: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 1372: ! 1373: if (INTVAL (operands[2]) == 8) ! 1374: return \"cvtbl %1,%0\"; ! 1375: return \"cvtwl %1,%0\"; ! 1376: }") ! 1377: ! 1378: ;; Register-only SImode cases of bit-field insns. ! 1379: ! 1380: (define_insn "" ! 1381: [(set (cc0) ! 1382: (compare ! 1383: (sign_extract:SI (match_operand:SI 0 "nonmemory_operand" "r") ! 1384: (match_operand:QI 1 "general_operand" "g") ! 1385: (match_operand:SI 2 "general_operand" "g")) ! 1386: (match_operand:SI 3 "general_operand" "g")))] ! 1387: "" ! 1388: "cmpv %2,%1,%0,%3") ! 1389: ! 1390: (define_insn "" ! 1391: [(set (cc0) ! 1392: (compare ! 1393: (zero_extract:SI (match_operand:SI 0 "nonmemory_operand" "r") ! 1394: (match_operand:QI 1 "general_operand" "g") ! 1395: (match_operand:SI 2 "general_operand" "g")) ! 1396: (match_operand:SI 3 "general_operand" "g")))] ! 1397: "" ! 1398: "cmpzv %2,%1,%0,%3") ! 1399: ! 1400: ;; When the field position and size are constant and the destination ! 1401: ;; is a register, extv and extzv are much slower than a rotate followed ! 1402: ;; by a bicl or sign extension. ! 1403: ! 1404: (define_insn "" ! 1405: [(set (match_operand:SI 0 "general_operand" "=g") ! 1406: (sign_extract:SI (match_operand:SI 1 "nonmemory_operand" "r") ! 1407: (match_operand:QI 2 "general_operand" "g") ! 1408: (match_operand:SI 3 "general_operand" "g")))] ! 1409: "" ! 1410: "* ! 1411: { ! 1412: if (GET_CODE (operands[3]) != CONST_INT || GET_CODE (operands[2]) != CONST_INT ! 1413: || GET_CODE (operands[0]) != REG ! 1414: || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)) ! 1415: return \"extv %3,%2,%1,%0\"; ! 1416: if (INTVAL (operands[2]) == 8) ! 1417: return \"rotl %R3,%1,%0\;cvtbl %0,%0\"; ! 1418: return \"rotl %R3,%1,%0\;cvtwl %0,%0\"; ! 1419: }") ! 1420: ! 1421: (define_insn "" ! 1422: [(set (match_operand:SI 0 "general_operand" "=g") ! 1423: (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "r") ! 1424: (match_operand:QI 2 "general_operand" "g") ! 1425: (match_operand:SI 3 "general_operand" "g")))] ! 1426: "" ! 1427: "* ! 1428: { ! 1429: if (GET_CODE (operands[3]) != CONST_INT || GET_CODE (operands[2]) != CONST_INT ! 1430: || GET_CODE (operands[0]) != REG) ! 1431: return \"extzv %3,%2,%1,%0\"; ! 1432: if (INTVAL (operands[2]) == 8) ! 1433: return \"rotl %R3,%1,%0\;movzbl %0,%0\"; ! 1434: if (INTVAL (operands[2]) == 16) ! 1435: return \"rotl %R3,%1,%0\;movzwl %0,%0\"; ! 1436: if (INTVAL (operands[3]) & 31) ! 1437: return \"rotl %R3,%1,%0\;bicl2 %M2,%0\"; ! 1438: if (rtx_equal_p (operands[0], operands[1])) ! 1439: return \"bicl2 %M2,%0\"; ! 1440: return \"bicl3 %M2,%1,%0\"; ! 1441: }") ! 1442: ! 1443: ;; Non-register cases. ! 1444: ;; nonimmediate_operand is used to make sure that mode-ambiguous cases ! 1445: ;; don't match these (and therefore match the cases above instead). ! 1446: ! 1447: (define_insn "" ! 1448: [(set (cc0) ! 1449: (compare ! 1450: (sign_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm") ! 1451: (match_operand:QI 1 "general_operand" "g") ! 1452: (match_operand:SI 2 "general_operand" "g")) ! 1453: (match_operand:SI 3 "general_operand" "g")))] ! 1454: "" ! 1455: "cmpv %2,%1,%0,%3") ! 1456: ! 1457: (define_insn "" ! 1458: [(set (cc0) ! 1459: (compare ! 1460: (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm") ! 1461: (match_operand:QI 1 "general_operand" "g") ! 1462: (match_operand:SI 2 "general_operand" "g")) ! 1463: (match_operand:SI 3 "general_operand" "g")))] ! 1464: "" ! 1465: "cmpzv %2,%1,%0,%3") ! 1466: ! 1467: (define_insn "extv" ! 1468: [(set (match_operand:SI 0 "general_operand" "=g") ! 1469: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "rm") ! 1470: (match_operand:QI 2 "general_operand" "g") ! 1471: (match_operand:SI 3 "general_operand" "g")))] ! 1472: "" ! 1473: "* ! 1474: { ! 1475: if (GET_CODE (operands[0]) != REG || GET_CODE (operands[2]) != CONST_INT ! 1476: || GET_CODE (operands[3]) != CONST_INT ! 1477: || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16) ! 1478: || side_effects_p (operands[1]) ! 1479: || (GET_CODE (operands[1]) == MEM ! 1480: && mode_dependent_address_p (XEXP (operands[1], 0)))) ! 1481: return \"extv %3,%2,%1,%0\"; ! 1482: if (INTVAL (operands[2]) == 8) ! 1483: return \"rotl %R3,%1,%0\;cvtbl %0,%0\"; ! 1484: return \"rotl %R3,%1,%0\;cvtwl %0,%0\"; ! 1485: }") ! 1486: ! 1487: (define_insn "extzv" ! 1488: [(set (match_operand:SI 0 "general_operand" "=g") ! 1489: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "rm") ! 1490: (match_operand:QI 2 "general_operand" "g") ! 1491: (match_operand:SI 3 "general_operand" "g")))] ! 1492: "" ! 1493: "* ! 1494: { ! 1495: if (GET_CODE (operands[0]) != REG || GET_CODE (operands[2]) != CONST_INT ! 1496: || GET_CODE (operands[3]) != CONST_INT ! 1497: || side_effects_p (operands[1]) ! 1498: || (GET_CODE (operands[1]) == MEM ! 1499: && mode_dependent_address_p (XEXP (operands[1], 0)))) ! 1500: return \"extzv %3,%2,%1,%0\"; ! 1501: if (INTVAL (operands[2]) == 8) ! 1502: return \"rotl %R3,%1,%0\;movzbl %0,%0\"; ! 1503: if (INTVAL (operands[2]) == 16) ! 1504: return \"rotl %R3,%1,%0\;movzwl %0,%0\"; ! 1505: return \"rotl %R3,%1,%0\;bicl2 %M2,%0\"; ! 1506: }") ! 1507: ! 1508: (define_insn "insv" ! 1509: [(set (zero_extract:SI (match_operand:QI 0 "general_operand" "+g") ! 1510: (match_operand:QI 1 "general_operand" "g") ! 1511: (match_operand:SI 2 "general_operand" "g")) ! 1512: (match_operand:SI 3 "general_operand" "g"))] ! 1513: "" ! 1514: "insv %3,%2,%1,%0") ! 1515: ! 1516: (define_insn "" ! 1517: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") ! 1518: (match_operand:QI 1 "general_operand" "g") ! 1519: (match_operand:SI 2 "general_operand" "g")) ! 1520: (match_operand:SI 3 "general_operand" "g"))] ! 1521: "" ! 1522: "insv %3,%2,%1,%0") ! 1523: ! 1524: (define_insn "jump" ! 1525: [(set (pc) ! 1526: (label_ref (match_operand 0 "" "")))] ! 1527: "" ! 1528: "jbr %l0") ! 1529: ! 1530: (define_insn "beq" ! 1531: [(set (pc) ! 1532: (if_then_else (eq (cc0) ! 1533: (const_int 0)) ! 1534: (label_ref (match_operand 0 "" "")) ! 1535: (pc)))] ! 1536: "" ! 1537: "jeql %l0") ! 1538: ! 1539: (define_insn "bne" ! 1540: [(set (pc) ! 1541: (if_then_else (ne (cc0) ! 1542: (const_int 0)) ! 1543: (label_ref (match_operand 0 "" "")) ! 1544: (pc)))] ! 1545: "" ! 1546: "jneq %l0") ! 1547: ! 1548: (define_insn "bgt" ! 1549: [(set (pc) ! 1550: (if_then_else (gt (cc0) ! 1551: (const_int 0)) ! 1552: (label_ref (match_operand 0 "" "")) ! 1553: (pc)))] ! 1554: "" ! 1555: "jgtr %l0") ! 1556: ! 1557: (define_insn "bgtu" ! 1558: [(set (pc) ! 1559: (if_then_else (gtu (cc0) ! 1560: (const_int 0)) ! 1561: (label_ref (match_operand 0 "" "")) ! 1562: (pc)))] ! 1563: "" ! 1564: "jgtru %l0") ! 1565: ! 1566: (define_insn "blt" ! 1567: [(set (pc) ! 1568: (if_then_else (lt (cc0) ! 1569: (const_int 0)) ! 1570: (label_ref (match_operand 0 "" "")) ! 1571: (pc)))] ! 1572: "" ! 1573: "jlss %l0") ! 1574: ! 1575: (define_insn "bltu" ! 1576: [(set (pc) ! 1577: (if_then_else (ltu (cc0) ! 1578: (const_int 0)) ! 1579: (label_ref (match_operand 0 "" "")) ! 1580: (pc)))] ! 1581: "" ! 1582: "jlssu %l0") ! 1583: ! 1584: (define_insn "bge" ! 1585: [(set (pc) ! 1586: (if_then_else (ge (cc0) ! 1587: (const_int 0)) ! 1588: (label_ref (match_operand 0 "" "")) ! 1589: (pc)))] ! 1590: "" ! 1591: "jgeq %l0") ! 1592: ! 1593: (define_insn "bgeu" ! 1594: [(set (pc) ! 1595: (if_then_else (geu (cc0) ! 1596: (const_int 0)) ! 1597: (label_ref (match_operand 0 "" "")) ! 1598: (pc)))] ! 1599: "" ! 1600: "jgequ %l0") ! 1601: ! 1602: (define_insn "ble" ! 1603: [(set (pc) ! 1604: (if_then_else (le (cc0) ! 1605: (const_int 0)) ! 1606: (label_ref (match_operand 0 "" "")) ! 1607: (pc)))] ! 1608: "" ! 1609: "jleq %l0") ! 1610: ! 1611: (define_insn "bleu" ! 1612: [(set (pc) ! 1613: (if_then_else (leu (cc0) ! 1614: (const_int 0)) ! 1615: (label_ref (match_operand 0 "" "")) ! 1616: (pc)))] ! 1617: "" ! 1618: "jlequ %l0") ! 1619: ! 1620: ;; Recognize reversed jumps. ! 1621: (define_insn "" ! 1622: [(set (pc) ! 1623: (if_then_else (match_operator 0 "comparison_operator" ! 1624: [(cc0) ! 1625: (const_int 0)]) ! 1626: (pc) ! 1627: (label_ref (match_operand 1 "" ""))))] ! 1628: "" ! 1629: "j%C0 %l1") ; %C0 negates condition ! 1630: ! 1631: ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand ! 1632: ;; of jlbs and jlbc insns are SImode in the hardware. However, if it is ! 1633: ;; memory, we use QImode in the insn. So we can't use those instructions ! 1634: ;; for mode-dependent addresses. ! 1635: ! 1636: (define_insn "" ! 1637: [(set (pc) ! 1638: (if_then_else ! 1639: (ne (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rQ,g") ! 1640: (const_int 1) ! 1641: (match_operand:SI 1 "general_operand" "I,g")) ! 1642: (const_int 0)) ! 1643: (label_ref (match_operand 2 "" "")) ! 1644: (pc)))] ! 1645: "" ! 1646: "@ ! 1647: jlbs %0,%l2 ! 1648: jbs %1,%0,%l2") ! 1649: ! 1650: (define_insn "" ! 1651: [(set (pc) ! 1652: (if_then_else ! 1653: (eq (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rQ,g") ! 1654: (const_int 1) ! 1655: (match_operand:SI 1 "general_operand" "I,g")) ! 1656: (const_int 0)) ! 1657: (label_ref (match_operand 2 "" "")) ! 1658: (pc)))] ! 1659: "" ! 1660: "@ ! 1661: jlbc %0,%l2 ! 1662: jbc %1,%0,%l2") ! 1663: ! 1664: (define_insn "" ! 1665: [(set (pc) ! 1666: (if_then_else ! 1667: (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r") ! 1668: (const_int 1) ! 1669: (match_operand:SI 1 "general_operand" "I,g")) ! 1670: (const_int 0)) ! 1671: (label_ref (match_operand 2 "" "")) ! 1672: (pc)))] ! 1673: "" ! 1674: "@ ! 1675: jlbs %0,%l2 ! 1676: jbs %1,%0,%l2") ! 1677: ! 1678: (define_insn "" ! 1679: [(set (pc) ! 1680: (if_then_else ! 1681: (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r") ! 1682: (const_int 1) ! 1683: (match_operand:SI 1 "general_operand" "I,g")) ! 1684: (const_int 0)) ! 1685: (label_ref (match_operand 2 "" "")) ! 1686: (pc)))] ! 1687: "" ! 1688: "@ ! 1689: jlbc %0,%l2 ! 1690: jbc %1,%0,%l2") ! 1691: ! 1692: ;; Subtract-and-jump and Add-and-jump insns. ! 1693: ;; These are not used when output is for the Unix assembler ! 1694: ;; because it does not know how to modify them to reach far. ! 1695: ! 1696: ;; Normal sob insns. ! 1697: ! 1698: (define_insn "" ! 1699: [(set (pc) ! 1700: (if_then_else ! 1701: (gt (plus:SI (match_operand:SI 0 "general_operand" "+g") ! 1702: (const_int -1)) ! 1703: (const_int 0)) ! 1704: (label_ref (match_operand 1 "" "")) ! 1705: (pc))) ! 1706: (set (match_dup 0) ! 1707: (plus:SI (match_dup 0) ! 1708: (const_int -1)))] ! 1709: "!TARGET_UNIX_ASM" ! 1710: "jsobgtr %0,%l1") ! 1711: ! 1712: (define_insn "" ! 1713: [(set (pc) ! 1714: (if_then_else ! 1715: (ge (plus:SI (match_operand:SI 0 "general_operand" "+g") ! 1716: (const_int -1)) ! 1717: (const_int 0)) ! 1718: (label_ref (match_operand 1 "" "")) ! 1719: (pc))) ! 1720: (set (match_dup 0) ! 1721: (plus:SI (match_dup 0) ! 1722: (const_int -1)))] ! 1723: "!TARGET_UNIX_ASM" ! 1724: "jsobgeq %0,%l1") ! 1725: ! 1726: ;; Normal aob insns. Define a version for when operands[1] is a constant. ! 1727: (define_insn "" ! 1728: [(set (pc) ! 1729: (if_then_else ! 1730: (lt (plus:SI (match_operand:SI 0 "general_operand" "+g") ! 1731: (const_int 1)) ! 1732: (match_operand:SI 1 "general_operand" "g")) ! 1733: (label_ref (match_operand 2 "" "")) ! 1734: (pc))) ! 1735: (set (match_dup 0) ! 1736: (plus:SI (match_dup 0) ! 1737: (const_int 1)))] ! 1738: "!TARGET_UNIX_ASM" ! 1739: "jaoblss %1,%0,%l2") ! 1740: ! 1741: (define_insn "" ! 1742: [(set (pc) ! 1743: (if_then_else ! 1744: (lt (match_operand:SI 0 "general_operand" "+g") ! 1745: (match_operand:SI 1 "general_operand" "g")) ! 1746: (label_ref (match_operand 2 "" "")) ! 1747: (pc))) ! 1748: (set (match_dup 0) ! 1749: (plus:SI (match_dup 0) ! 1750: (const_int 1)))] ! 1751: "!TARGET_UNIX_ASM && GET_CODE (operands[1]) == CONST_INT" ! 1752: "jaoblss %P1,%0,%l2") ! 1753: ! 1754: (define_insn "" ! 1755: [(set (pc) ! 1756: (if_then_else ! 1757: (le (plus:SI (match_operand:SI 0 "general_operand" "+g") ! 1758: (const_int 1)) ! 1759: (match_operand:SI 1 "general_operand" "g")) ! 1760: (label_ref (match_operand 2 "" "")) ! 1761: (pc))) ! 1762: (set (match_dup 0) ! 1763: (plus:SI (match_dup 0) ! 1764: (const_int 1)))] ! 1765: "!TARGET_UNIX_ASM" ! 1766: "jaobleq %1,%0,%l2") ! 1767: ! 1768: (define_insn "" ! 1769: [(set (pc) ! 1770: (if_then_else ! 1771: (le (match_operand:SI 0 "general_operand" "+g") ! 1772: (match_operand:SI 1 "general_operand" "g")) ! 1773: (label_ref (match_operand 2 "" "")) ! 1774: (pc))) ! 1775: (set (match_dup 0) ! 1776: (plus:SI (match_dup 0) ! 1777: (const_int 1)))] ! 1778: "!TARGET_UNIX_ASM && GET_CODE (operands[1]) == CONST_INT" ! 1779: "jaobleq %P1,%0,%l2") ! 1780: ! 1781: ;; Something like a sob insn, but compares against -1. ! 1782: ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'. ! 1783: ! 1784: (define_insn "" ! 1785: [(set (pc) ! 1786: (if_then_else ! 1787: (ne (match_operand:SI 0 "general_operand" "g") ! 1788: (const_int 0)) ! 1789: (label_ref (match_operand 1 "" "")) ! 1790: (pc))) ! 1791: (set (match_dup 0) ! 1792: (plus:SI (match_dup 0) ! 1793: (const_int -1)))] ! 1794: "" ! 1795: "decl %0\;jgequ %l1") ! 1796: ! 1797: ;; Note that operand 1 is total size of args, in bytes, ! 1798: ;; and what the call insn wants is the number of words. ! 1799: (define_insn "call_pop" ! 1800: [(call (match_operand:QI 0 "memory_operand" "m") ! 1801: (match_operand:QI 1 "general_operand" "g")) ! 1802: (set (reg:SI 14) (plus:SI (reg:SI 14) ! 1803: (match_operand:SI 3 "immediate_operand" "i")))] ! 1804: "" ! 1805: "* ! 1806: if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 255 * 4) ! 1807: /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ ! 1808: return \"calls $0,%0\;addl2 %1,sp\"; ! 1809: operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4); ! 1810: return \"calls %1,%0\"; ! 1811: ") ! 1812: ! 1813: (define_insn "call_value_pop" ! 1814: [(set (match_operand 0 "" "=g") ! 1815: (call (match_operand:QI 1 "memory_operand" "m") ! 1816: (match_operand:QI 2 "general_operand" "g"))) ! 1817: (set (reg:SI 14) (plus:SI (reg:SI 14) ! 1818: (match_operand:SI 4 "immediate_operand" "i")))] ! 1819: "" ! 1820: "* ! 1821: if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 255 * 4) ! 1822: /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ ! 1823: return \"calls $0,%1\;addl2 %2,sp\"; ! 1824: operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4); ! 1825: return \"calls %2,%1\"; ! 1826: ") ! 1827: ! 1828: ;; Define another set of these for the case of functions with no ! 1829: ;; operands. In that case, combine may simplify the adjustment of sp. ! 1830: (define_insn "" ! 1831: [(call (match_operand:QI 0 "memory_operand" "m") ! 1832: (match_operand:QI 1 "general_operand" "g")) ! 1833: (set (reg:SI 14) (reg:SI 14))] ! 1834: "" ! 1835: "* ! 1836: if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 255 * 4) ! 1837: /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ ! 1838: return \"calls $0,%0\;addl2 %1,sp\"; ! 1839: operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4); ! 1840: return \"calls %1,%0\"; ! 1841: ") ! 1842: ! 1843: (define_insn "" ! 1844: [(set (match_operand 0 "" "=g") ! 1845: (call (match_operand:QI 1 "memory_operand" "m") ! 1846: (match_operand:QI 2 "general_operand" "g"))) ! 1847: (set (reg:SI 14) (reg:SI 14))] ! 1848: "" ! 1849: "* ! 1850: if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 255 * 4) ! 1851: /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ ! 1852: return \"calls $0,%1\;addl2 %2,sp\"; ! 1853: operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4); ! 1854: return \"calls %2,%1\"; ! 1855: ") ! 1856: ! 1857: ;; Call subroutine returning any type. ! 1858: ! 1859: (define_expand "untyped_call" ! 1860: [(parallel [(call (match_operand 0 "" "") ! 1861: (const_int 0)) ! 1862: (match_operand 1 "" "") ! 1863: (match_operand 2 "" "")])] ! 1864: "" ! 1865: " ! 1866: { ! 1867: int i; ! 1868: ! 1869: emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx)); ! 1870: ! 1871: for (i = 0; i < XVECLEN (operands[2], 0); i++) ! 1872: { ! 1873: rtx set = XVECEXP (operands[2], 0, i); ! 1874: emit_move_insn (SET_DEST (set), SET_SRC (set)); ! 1875: } ! 1876: ! 1877: /* The optimizer does not know that the call sets the function value ! 1878: registers we stored in the result block. We avoid problems by ! 1879: claiming that all hard registers are used and clobbered at this ! 1880: point. */ ! 1881: emit_insn (gen_blockage ()); ! 1882: ! 1883: DONE; ! 1884: }") ! 1885: ! 1886: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ! 1887: ;; all of memory. This blocks insns from being moved across this point. ! 1888: ! 1889: (define_insn "blockage" ! 1890: [(unspec_volatile [(const_int 0)] 0)] ! 1891: "" ! 1892: "") ! 1893: ! 1894: (define_insn "return" ! 1895: [(return)] ! 1896: "" ! 1897: "ret") ! 1898: ! 1899: (define_insn "nop" ! 1900: [(const_int 0)] ! 1901: "" ! 1902: "nop") ! 1903: ! 1904: ;; This had a wider constraint once, and it had trouble. ! 1905: ;; If you are tempted to try `g', please don't--it's not worth ! 1906: ;; the risk we will reopen the same bug. ! 1907: (define_insn "indirect_jump" ! 1908: [(set (pc) (match_operand:SI 0 "general_operand" "r"))] ! 1909: "" ! 1910: "jmp (%0)") ! 1911: ! 1912: ;; This is here to accept 5 arguments (as passed by expand_end_case) ! 1913: ;; and pass the first 4 along to the casesi1 pattern that really does the work. ! 1914: (define_expand "casesi" ! 1915: [(set (pc) ! 1916: (if_then_else (leu (minus:SI (match_operand:SI 0 "general_operand" "g") ! 1917: (match_operand:SI 1 "general_operand" "g")) ! 1918: (match_operand:SI 2 "general_operand" "g")) ! 1919: (plus:SI (sign_extend:SI ! 1920: (mem:HI ! 1921: (plus:SI (pc) ! 1922: (mult:SI (minus:SI (match_dup 0) ! 1923: (match_dup 1)) ! 1924: (const_int 2))))) ! 1925: (label_ref:SI (match_operand 3 "" ""))) ! 1926: (pc))) ! 1927: (match_operand 4 "" "")] ! 1928: "" ! 1929: " ! 1930: emit_insn (gen_casesi1 (operands[0], operands[1], operands[2], operands[3])); ! 1931: DONE; ! 1932: ") ! 1933: ! 1934: (define_insn "casesi1" ! 1935: [(set (pc) ! 1936: (if_then_else (leu (minus:SI (match_operand:SI 0 "general_operand" "g") ! 1937: (match_operand:SI 1 "general_operand" "g")) ! 1938: (match_operand:SI 2 "general_operand" "g")) ! 1939: (plus:SI (sign_extend:SI ! 1940: (mem:HI ! 1941: (plus:SI (pc) ! 1942: (mult:SI (minus:SI (match_dup 0) ! 1943: (match_dup 1)) ! 1944: (const_int 2))))) ! 1945: (label_ref:SI (match_operand 3 "" ""))) ! 1946: (pc)))] ! 1947: "" ! 1948: "casel %0,%1,%2") ! 1949: ! 1950: ;; This used to arise from the preceding by simplification ! 1951: ;; if operand 1 is zero. Perhaps it is no longer necessary. ! 1952: (define_insn "" ! 1953: [(set (pc) ! 1954: (if_then_else (leu (match_operand:SI 0 "general_operand" "g") ! 1955: (match_operand:SI 1 "general_operand" "g")) ! 1956: (plus:SI (sign_extend:SI ! 1957: (mem:HI ! 1958: (plus:SI (pc) ! 1959: (mult:SI (minus:SI (match_dup 0) ! 1960: (const_int 0)) ! 1961: (const_int 2))))) ! 1962: (label_ref:SI (match_operand 3 "" ""))) ! 1963: (pc)))] ! 1964: "" ! 1965: "casel %0,$0,%1") ! 1966: ! 1967: ;;- load or push effective address ! 1968: ;; These come after the move and add/sub patterns ! 1969: ;; because we don't want pushl $1 turned into pushad 1. ! 1970: ;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3. ! 1971: ! 1972: ;; It does not work to use constraints to distinguish pushes from moves, ! 1973: ;; because < matches any autodecrement, not just a push. ! 1974: ! 1975: (define_insn "" ! 1976: [(set (match_operand:SI 0 "general_operand" "=g") ! 1977: (match_operand:QI 1 "address_operand" "p"))] ! 1978: "" ! 1979: "* ! 1980: { ! 1981: if (push_operand (operands[0], SImode)) ! 1982: return \"pushab %a1\"; ! 1983: else ! 1984: return \"movab %a1,%0\"; ! 1985: }") ! 1986: ! 1987: (define_insn "" ! 1988: [(set (match_operand:SI 0 "general_operand" "=g") ! 1989: (match_operand:HI 1 "address_operand" "p"))] ! 1990: "" ! 1991: "* ! 1992: { ! 1993: if (push_operand (operands[0], SImode)) ! 1994: return \"pushaw %a1\"; ! 1995: else ! 1996: return \"movaw %a1,%0\"; ! 1997: }") ! 1998: ! 1999: (define_insn "" ! 2000: [(set (match_operand:SI 0 "general_operand" "=g") ! 2001: (match_operand:SI 1 "address_operand" "p"))] ! 2002: "" ! 2003: "* ! 2004: { ! 2005: if (push_operand (operands[0], SImode)) ! 2006: return \"pushal %a1\"; ! 2007: else ! 2008: return \"moval %a1,%0\"; ! 2009: }") ! 2010: ! 2011: (define_insn "" ! 2012: [(set (match_operand:SI 0 "general_operand" "=g") ! 2013: (match_operand:DI 1 "address_operand" "p"))] ! 2014: "" ! 2015: "* ! 2016: { ! 2017: if (push_operand (operands[0], SImode)) ! 2018: return \"pushaq %a1\"; ! 2019: else ! 2020: return \"movaq %a1,%0\"; ! 2021: }") ! 2022: ! 2023: (define_insn "" ! 2024: [(set (match_operand:SI 0 "general_operand" "=g") ! 2025: (match_operand:SF 1 "address_operand" "p"))] ! 2026: "" ! 2027: "* ! 2028: { ! 2029: if (push_operand (operands[0], SImode)) ! 2030: return \"pushaf %a1\"; ! 2031: else ! 2032: return \"movaf %a1,%0\"; ! 2033: }") ! 2034: ! 2035: (define_insn "" ! 2036: [(set (match_operand:SI 0 "general_operand" "=g") ! 2037: (match_operand:DF 1 "address_operand" "p"))] ! 2038: "" ! 2039: "* ! 2040: { ! 2041: if (push_operand (operands[0], SImode)) ! 2042: return \"pushad %a1\"; ! 2043: else ! 2044: return \"movad %a1,%0\"; ! 2045: }") ! 2046: ! 2047: ;; These used to be peepholes, but it is more straightforward to do them ! 2048: ;; as single insns. However, we must force the output to be a register ! 2049: ;; if it is not an offsettable address so that we know that we can assign ! 2050: ;; to it twice. ! 2051: ! 2052: ;; If we had a good way of evaluating the relative costs, these could be ! 2053: ;; machine-independent. ! 2054: ! 2055: ;; Optimize extzv ...,z; andl2 ...,z ! 2056: ;; or ashl ...,z; andl2 ...,z ! 2057: ;; with other operands constant. This is what the combiner converts the ! 2058: ;; above sequences to before attempting to recognize the new insn. ! 2059: ! 2060: (define_insn "" ! 2061: [(set (match_operand:SI 0 "general_operand" "=ro") ! 2062: (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") ! 2063: (match_operand:QI 2 "const_int_operand" "n")) ! 2064: (match_operand:SI 3 "const_int_operand" "n")))] ! 2065: "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0" ! 2066: "* ! 2067: { ! 2068: unsigned long mask1 = INTVAL (operands[3]); ! 2069: unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1; ! 2070: ! 2071: if ((mask1 & mask2) != mask1) ! 2072: operands[3] = gen_rtx (CONST_INT, VOIDmode, mask1 & mask2); ! 2073: ! 2074: return \"rotl %R2,%1,%0\;bicl2 %N3,%0\"; ! 2075: }") ! 2076: ! 2077: ;; left-shift and mask ! 2078: ;; The only case where `ashl' is better is if the mask only turns off ! 2079: ;; bits that the ashl would anyways, in which case it should have been ! 2080: ;; optimized away. ! 2081: ! 2082: (define_insn "" ! 2083: [(set (match_operand:SI 0 "general_operand" "=ro") ! 2084: (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "g") ! 2085: (match_operand:QI 2 "const_int_operand" "n")) ! 2086: (match_operand:SI 3 "const_int_operand" "n")))] ! 2087: "" ! 2088: "* ! 2089: { ! 2090: operands[3] = gen_rtx (CONST_INT, VOIDmode, ! 2091: INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1)); ! 2092: return \"rotl %2,%1,%0\;bicl2 %N3,%0\"; ! 2093: }")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.