|
|
1.1 ! root 1: ;;- Machine description for the pdp11 for GNU C compiler ! 2: ;; Copyright (C) 1994 Free Software Foundation, Inc. ! 3: ;; Contributed by Michael K. Gschwind ([email protected]). ! 4: ! 5: ;; This file is part of GNU CC. ! 6: ! 7: ;; GNU CC is free software; you can redistribute it and/or modify ! 8: ;; it under the terms of the GNU General Public License as published by ! 9: ;; the Free Software Foundation; either version 1, or (at your option) ! 10: ;; any later version. ! 11: ! 12: ;; GNU CC is distributed in the hope that it will be useful, ! 13: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: ;; GNU General Public License for more details. ! 16: ! 17: ;; You should have received a copy of the GNU General Public License ! 18: ;; along with GNU CC; see the file COPYING. If not, write to ! 19: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 20: ! 21: ! 22: ;; HI is 16 bit ! 23: ;; QI is 8 bit ! 24: ! 25: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 26: ! 27: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ! 28: ;;- updates for most instructions. ! 29: ! 30: ;;- Operand classes for the register allocator: ! 31: ! 32: ;; Compare instructions. ! 33: ! 34: ;; currently we only support df floats, which saves us quite some ! 35: ;; hassle switching the FP mode! ! 36: ;; we assume that CPU is always in long float mode, and ! 37: ;; 16 bit integer mode - currently, the prologue for main does this, ! 38: ;; but maybe we should just set up a NEW crt0 properly, ! 39: ;; -- and what about signal handling code? ! 40: ;; (we don't even let sf floats in the register file, so ! 41: ;; we only should have to worry about truncating and widening ! 42: ;; when going to memory) ! 43: ! 44: ;; abort() call by g++ - must define libfunc for cmp_optab ! 45: ;; and ucmp_optab for mode SImode, because we don't have that!!! ! 46: ;; - yet since no libfunc is there, we abort () ! 47: ! 48: ;; The only thing that remains to be done then is output ! 49: ;; the floats in a way the assembler can handle it (and ! 50: ;; if you're really into it, use a PDP11 float emulation ! 51: ;; libary to do floating point constant folding - but ! 52: ;; I guess you'll get reasonable results even when not ! 53: ;; doing this) ! 54: ;; the last thing to do is fix the UPDATE_CC macro to check ! 55: ;; for floating point condition codes, and set cc_status ! 56: ;; properly, also setting the CC_IN_FCCR flag. ! 57: ! 58: ;; define attributes ! 59: ;; currently type is only fpu or arith or unknown, maybe branch later ? ! 60: ;; default is arith ! 61: (define_attr "type" "unknown,arith,fp" (const_string "arith")) ! 62: ! 63: ;; length default is 1 word each ! 64: (define_attr "length" "" (const_int 1)) ! 65: ! 66: ;; a users asm staement ! 67: (define_asm_attributes ! 68: [(set_attr "type" "unknown") ! 69: ; all bets are off how long it is - make it 256, forces long jumps ! 70: ; whenever jumping around it !!! ! 71: (set_attr "length" "256")]) ! 72: ! 73: ;; define function units ! 74: ! 75: ;; arithmetic - values here immediately when next insn issued ! 76: ;; or does it mean the number of cycles after this insn was issued? ! 77: ;; how do I say that fpu insns use cpu also? (pre-interaction phase) ! 78: ! 79: ;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0) ! 80: ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0) ! 81: ! 82: ;; compare ! 83: (define_insn "cmpdf" ! 84: [(set (cc0) ! 85: (compare (match_operand:DF 0 "general_operand" "fR,Q,F") ! 86: (match_operand:DF 1 "register_operand" "a,a,a")))] ! 87: "TARGET_FPU" ! 88: "* ! 89: { ! 90: cc_status.flags = CC_IN_FPU; ! 91: return \"cmpd %0, %1\;cfcc\"; ! 92: }" ! 93: [(set_attr "length" "2,3,6")]) ! 94: ! 95: ;; a bit of brain damage, maybe inline later - ! 96: ;; problem is - gcc seems to NEED SImode because ! 97: ;; of the cmp weirdness - maybe change gcc to handle this? ! 98: ! 99: (define_expand "cmpsi" ! 100: [(set (reg:SI 0) ! 101: (match_operand:SI 0 "general_operand" "g")) ! 102: (set (reg:SI 2) ! 103: (match_operand:SI 1 "general_operand" "g")) ! 104: (parallel [(set (cc0) ! 105: (compare (reg:SI 0) ! 106: (reg:SI 2))) ! 107: (clobber (reg:SI 0))])] ! 108: "0" ;; disable for test ! 109: "") ! 110: ! 111: ;; check for next insn for branch code - does this still ! 112: ;; work in gcc 2.* ? ! 113: ! 114: (define_insn "" ! 115: [(set (cc0) ! 116: (compare (reg:SI 0) ! 117: (reg:SI 2))) ! 118: (clobber (reg:SI 0))] ! 119: "" ! 120: "* ! 121: { ! 122: rtx br_insn = NEXT_INSN (insn); ! 123: RTX_CODE br_code; ! 124: ! 125: if (GET_CODE (br_insn) != JUMP_INSN) ! 126: abort(); ! 127: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0)); ! 128: ! 129: switch(br_code) ! 130: { ! 131: case GEU: ! 132: case LTU: ! 133: case GTU: ! 134: case LEU: ! 135: ! 136: return \"jsr pc, ___ucmpsi\;cmp $1,r0\"; ! 137: ! 138: case GE: ! 139: case LT: ! 140: case GT: ! 141: case LE: ! 142: case EQ: ! 143: case NE: ! 144: ! 145: return \"jsr pc, ___cmpsi\;tst r0\"; ! 146: ! 147: default: ! 148: ! 149: abort(); ! 150: } ! 151: }" ! 152: [(set_attr "length" "4")]) ! 153: ! 154: ! 155: (define_insn "cmphi" ! 156: [(set (cc0) ! 157: (compare (match_operand:HI 0 "general_operand" "rR,rR,Qi,Qi") ! 158: (match_operand:HI 1 "general_operand" "rR,Qi,rR,Qi")))] ! 159: "" ! 160: "cmp %0,%1" ! 161: [(set_attr "length" "1,2,2,3")]) ! 162: ! 163: (define_insn "cmpqi" ! 164: [(set (cc0) ! 165: (compare (match_operand:QI 0 "general_operand" "rR,rR,Qi,Qi") ! 166: (match_operand:QI 1 "general_operand" "rR,Qi,rR,Qi")))] ! 167: "" ! 168: "cmpb %0,%1" ! 169: [(set_attr "length" "1,2,2,3")]) ! 170: ! 171: ! 172: ;; We have to have this because cse can optimize the previous pattern ! 173: ;; into this one. ! 174: ! 175: (define_insn "tstdf" ! 176: [(set (cc0) ! 177: (match_operand:DF 0 "general_operand" "fR,Q"))] ! 178: "TARGET_FPU" ! 179: "* ! 180: { ! 181: cc_status.flags = CC_IN_FPU; ! 182: return \"tstd %0\;cfcc\"; ! 183: }" ! 184: [(set_attr "length" "2,3")]) ! 185: ! 186: ! 187: (define_expand "tstsi" ! 188: [(set (reg:SI 0) ! 189: (match_operand:SI 0 "general_operand" "g")) ! 190: (parallel [(set (cc0) ! 191: (reg:SI 0)) ! 192: (clobber (reg:SI 0))])] ! 193: "0" ;; disable for test ! 194: "") ! 195: ! 196: (define_insn "" ! 197: [(set (cc0) ! 198: (reg:SI 0)) ! 199: (clobber (reg:SI 0))] ! 200: "" ! 201: "jsr pc, ___tstsi\;tst r0" ! 202: [(set_attr "length" "3")]) ! 203: ! 204: ! 205: (define_insn "tsthi" ! 206: [(set (cc0) ! 207: (match_operand:HI 0 "general_operand" "rR,Q"))] ! 208: "" ! 209: "tst %0" ! 210: [(set_attr "length" "1,2")]) ! 211: ! 212: (define_insn "tstqi" ! 213: [(set (cc0) ! 214: (match_operand:QI 0 "general_operand" "rR,Q"))] ! 215: "" ! 216: "tstb %0" ! 217: [(set_attr "length" "1,2")]) ! 218: ! 219: ;; sob instruction - we need an assembler which can make this instruction ! 220: ;; valid under _all_ circumstances! ! 221: ! 222: (define_insn "" ! 223: [(set (pc) ! 224: (if_then_else ! 225: (ne (plus:HI (match_operand:HI 0 "register_operand" "r") ! 226: (const_int -1)) ! 227: (const_int 0)) ! 228: (label_ref (match_operand 1 "" "")) ! 229: (pc))) ! 230: (set (match_dup 0) ! 231: (plus:HI (match_dup 0) ! 232: (const_int -1)))] ! 233: "TARGET_40_PLUS" ! 234: "* ! 235: { ! 236: static int labelcount = 0; ! 237: static char buf[1000]; ! 238: ! 239: if (get_attr_length (insn) == 1) ! 240: return \"sob %0, %l1\"; ! 241: ! 242: /* emulate sob */ ! 243: output_asm_insn (\"dec %0\", operands); ! 244: ! 245: sprintf (buf, \"bge LONG_SOB%d\", labelcount); ! 246: output_asm_insn (buf, NULL); ! 247: ! 248: output_asm_insn (\"jmp %l1\", operands); ! 249: ! 250: sprintf (buf, \"LONG_SOB%d:\", labelcount++); ! 251: output_asm_insn (buf, NULL); ! 252: ! 253: return \"\"; ! 254: }" ! 255: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 256: (pc)) ! 257: (const_int -256)) ! 258: (ge (minus (match_dup 0) ! 259: (pc)) ! 260: (const_int 0))) ! 261: (const_int 4) ! 262: (const_int 1)))]) ! 263: ! 264: ;; These control RTL generation for conditional jump insns ! 265: ;; and match them for register allocation. ! 266: ! 267: ;; problem with too short jump distance! we need an assembler which can ! 268: ;; make this legal for all jump distances! ! 269: ;; e.g. gas! ! 270: ! 271: ;; these must be changed to check for CC_IN_FCCR if float is to be ! 272: ;; enabled ! 273: ! 274: (define_insn "beq" ! 275: [(set (pc) ! 276: (if_then_else (eq (cc0) ! 277: (const_int 0)) ! 278: (label_ref (match_operand 0 "" "")) ! 279: (pc)))] ! 280: "" ! 281: "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));" ! 282: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 283: (pc)) ! 284: (const_int -128)) ! 285: (ge (minus (match_dup 0) ! 286: (pc)) ! 287: (const_int 128))) ! 288: (const_int 3) ! 289: (const_int 1)))]) ! 290: ! 291: ! 292: (define_insn "bne" ! 293: [(set (pc) ! 294: (if_then_else (ne (cc0) ! 295: (const_int 0)) ! 296: (label_ref (match_operand 0 "" "")) ! 297: (pc)))] ! 298: "" ! 299: "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));" ! 300: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 301: (pc)) ! 302: (const_int -128)) ! 303: (ge (minus (match_dup 0) ! 304: (pc)) ! 305: (const_int 128))) ! 306: (const_int 3) ! 307: (const_int 1)))]) ! 308: ! 309: (define_insn "bgt" ! 310: [(set (pc) ! 311: (if_then_else (gt (cc0) ! 312: (const_int 0)) ! 313: (label_ref (match_operand 0 "" "")) ! 314: (pc)))] ! 315: "" ! 316: "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));" ! 317: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 318: (pc)) ! 319: (const_int -128)) ! 320: (ge (minus (match_dup 0) ! 321: (pc)) ! 322: (const_int 128))) ! 323: (const_int 3) ! 324: (const_int 1)))]) ! 325: ! 326: (define_insn "bgtu" ! 327: [(set (pc) ! 328: (if_then_else (gtu (cc0) ! 329: (const_int 0)) ! 330: (label_ref (match_operand 0 "" "")) ! 331: (pc)))] ! 332: "" ! 333: "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));" ! 334: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 335: (pc)) ! 336: (const_int -128)) ! 337: (ge (minus (match_dup 0) ! 338: (pc)) ! 339: (const_int 128))) ! 340: (const_int 3) ! 341: (const_int 1)))]) ! 342: ! 343: (define_insn "blt" ! 344: [(set (pc) ! 345: (if_then_else (lt (cc0) ! 346: (const_int 0)) ! 347: (label_ref (match_operand 0 "" "")) ! 348: (pc)))] ! 349: "" ! 350: "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));" ! 351: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 352: (pc)) ! 353: (const_int -128)) ! 354: (ge (minus (match_dup 0) ! 355: (pc)) ! 356: (const_int 128))) ! 357: (const_int 3) ! 358: (const_int 1)))]) ! 359: ! 360: ! 361: (define_insn "bltu" ! 362: [(set (pc) ! 363: (if_then_else (ltu (cc0) ! 364: (const_int 0)) ! 365: (label_ref (match_operand 0 "" "")) ! 366: (pc)))] ! 367: "" ! 368: "* return output_jump(\"blo\", \"bhos\", get_attr_length(insn));" ! 369: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 370: (pc)) ! 371: (const_int -128)) ! 372: (ge (minus (match_dup 0) ! 373: (pc)) ! 374: (const_int 128))) ! 375: (const_int 3) ! 376: (const_int 1)))]) ! 377: ! 378: (define_insn "bge" ! 379: [(set (pc) ! 380: (if_then_else (ge (cc0) ! 381: (const_int 0)) ! 382: (label_ref (match_operand 0 "" "")) ! 383: (pc)))] ! 384: "" ! 385: "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));" ! 386: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 387: (pc)) ! 388: (const_int -128)) ! 389: (ge (minus (match_dup 0) ! 390: (pc)) ! 391: (const_int 128))) ! 392: (const_int 3) ! 393: (const_int 1)))]) ! 394: ! 395: (define_insn "bgeu" ! 396: [(set (pc) ! 397: (if_then_else (geu (cc0) ! 398: (const_int 0)) ! 399: (label_ref (match_operand 0 "" "")) ! 400: (pc)))] ! 401: "" ! 402: "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));" ! 403: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 404: (pc)) ! 405: (const_int -128)) ! 406: (ge (minus (match_dup 0) ! 407: (pc)) ! 408: (const_int 128))) ! 409: (const_int 3) ! 410: (const_int 1)))]) ! 411: ! 412: (define_insn "ble" ! 413: [(set (pc) ! 414: (if_then_else (le (cc0) ! 415: (const_int 0)) ! 416: (label_ref (match_operand 0 "" "")) ! 417: (pc)))] ! 418: "" ! 419: "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));" ! 420: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 421: (pc)) ! 422: (const_int -128)) ! 423: (ge (minus (match_dup 0) ! 424: (pc)) ! 425: (const_int 128))) ! 426: (const_int 3) ! 427: (const_int 1)))]) ! 428: ! 429: (define_insn "bleu" ! 430: [(set (pc) ! 431: (if_then_else (leu (cc0) ! 432: (const_int 0)) ! 433: (label_ref (match_operand 0 "" "")) ! 434: (pc)))] ! 435: "" ! 436: "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));" ! 437: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 438: (pc)) ! 439: (const_int -128)) ! 440: (ge (minus (match_dup 0) ! 441: (pc)) ! 442: (const_int 128))) ! 443: (const_int 3) ! 444: (const_int 1)))]) ! 445: ! 446: ! 447: ;; These match inverted jump insns for register allocation. ! 448: ! 449: (define_insn "" ! 450: [(set (pc) ! 451: (if_then_else (eq (cc0) ! 452: (const_int 0)) ! 453: (pc) ! 454: (label_ref (match_operand 0 "" ""))))] ! 455: "" ! 456: "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));" ! 457: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 458: (pc)) ! 459: (const_int -128)) ! 460: (ge (minus (match_dup 0) ! 461: (pc)) ! 462: (const_int 128))) ! 463: (const_int 3) ! 464: (const_int 1)))]) ! 465: ! 466: (define_insn "" ! 467: [(set (pc) ! 468: (if_then_else (ne (cc0) ! 469: (const_int 0)) ! 470: (pc) ! 471: (label_ref (match_operand 0 "" ""))))] ! 472: "" ! 473: "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));" ! 474: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 475: (pc)) ! 476: (const_int -128)) ! 477: (ge (minus (match_dup 0) ! 478: (pc)) ! 479: (const_int 128))) ! 480: (const_int 3) ! 481: (const_int 1)))]) ! 482: ! 483: (define_insn "" ! 484: [(set (pc) ! 485: (if_then_else (gt (cc0) ! 486: (const_int 0)) ! 487: (pc) ! 488: (label_ref (match_operand 0 "" ""))))] ! 489: "" ! 490: "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));" ! 491: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 492: (pc)) ! 493: (const_int -128)) ! 494: (ge (minus (match_dup 0) ! 495: (pc)) ! 496: (const_int 128))) ! 497: (const_int 3) ! 498: (const_int 1)))]) ! 499: ! 500: (define_insn "" ! 501: [(set (pc) ! 502: (if_then_else (gtu (cc0) ! 503: (const_int 0)) ! 504: (pc) ! 505: (label_ref (match_operand 0 "" ""))))] ! 506: "" ! 507: "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));" ! 508: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 509: (pc)) ! 510: (const_int -128)) ! 511: (ge (minus (match_dup 0) ! 512: (pc)) ! 513: (const_int 128))) ! 514: (const_int 3) ! 515: (const_int 1)))]) ! 516: ! 517: (define_insn "" ! 518: [(set (pc) ! 519: (if_then_else (lt (cc0) ! 520: (const_int 0)) ! 521: (pc) ! 522: (label_ref (match_operand 0 "" ""))))] ! 523: "" ! 524: "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));" ! 525: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 526: (pc)) ! 527: (const_int -128)) ! 528: (ge (minus (match_dup 0) ! 529: (pc)) ! 530: (const_int 128))) ! 531: (const_int 3) ! 532: (const_int 1)))]) ! 533: ! 534: (define_insn "" ! 535: [(set (pc) ! 536: (if_then_else (ltu (cc0) ! 537: (const_int 0)) ! 538: (pc) ! 539: (label_ref (match_operand 0 "" ""))))] ! 540: "" ! 541: "* return output_jump(\"bhos\", \"blo\", get_attr_length(insn));" ! 542: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 543: (pc)) ! 544: (const_int -128)) ! 545: (ge (minus (match_dup 0) ! 546: (pc)) ! 547: (const_int 128))) ! 548: (const_int 3) ! 549: (const_int 1)))]) ! 550: ! 551: (define_insn "" ! 552: [(set (pc) ! 553: (if_then_else (ge (cc0) ! 554: (const_int 0)) ! 555: (pc) ! 556: (label_ref (match_operand 0 "" ""))))] ! 557: "" ! 558: "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));" ! 559: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 560: (pc)) ! 561: (const_int -128)) ! 562: (ge (minus (match_dup 0) ! 563: (pc)) ! 564: (const_int 128))) ! 565: (const_int 3) ! 566: (const_int 1)))]) ! 567: ! 568: (define_insn "" ! 569: [(set (pc) ! 570: (if_then_else (geu (cc0) ! 571: (const_int 0)) ! 572: (pc) ! 573: (label_ref (match_operand 0 "" ""))))] ! 574: "" ! 575: "* return output_jump(\"blo\", \"bhos\", get_attr_length(insn));" ! 576: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 577: (pc)) ! 578: (const_int -128)) ! 579: (ge (minus (match_dup 0) ! 580: (pc)) ! 581: (const_int 128))) ! 582: (const_int 3) ! 583: (const_int 1)))]) ! 584: ! 585: (define_insn "" ! 586: [(set (pc) ! 587: (if_then_else (le (cc0) ! 588: (const_int 0)) ! 589: (pc) ! 590: (label_ref (match_operand 0 "" ""))))] ! 591: "" ! 592: "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));" ! 593: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 594: (pc)) ! 595: (const_int -128)) ! 596: (ge (minus (match_dup 0) ! 597: (pc)) ! 598: (const_int 128))) ! 599: (const_int 3) ! 600: (const_int 1)))]) ! 601: ! 602: (define_insn "" ! 603: [(set (pc) ! 604: (if_then_else (leu (cc0) ! 605: (const_int 0)) ! 606: (pc) ! 607: (label_ref (match_operand 0 "" ""))))] ! 608: "" ! 609: "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));" ! 610: [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) ! 611: (pc)) ! 612: (const_int -128)) ! 613: (ge (minus (match_dup 0) ! 614: (pc)) ! 615: (const_int 128))) ! 616: (const_int 3) ! 617: (const_int 1)))]) ! 618: ! 619: ;; Move instructions ! 620: ! 621: (define_insn "movdi" ! 622: [(set (match_operand:DI 0 "general_operand" "=g") ! 623: (match_operand:DI 1 "general_operand" "g"))] ! 624: "" ! 625: "* return output_move_quad (operands);" ! 626: ;; what's the mose expensive code - say twice movsi = 16 ! 627: [(set_attr "length" "16")]) ! 628: ! 629: (define_insn "movsi" ! 630: [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m") ! 631: (match_operand:SI 1 "general_operand" "rN,IJ,K,m,r"))] ! 632: "" ! 633: "* return output_move_double (operands);" ! 634: ;; what's the most expensive code ? - I think 8! ! 635: ;; we could split it up and make several sub-cases... ! 636: [(set_attr "length" "2,3,4,8,8")]) ! 637: ! 638: (define_insn "movhi" ! 639: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") ! 640: (match_operand:HI 1 "general_operand" "rRN,Qi,rRN,Qi"))] ! 641: "" ! 642: "* ! 643: { ! 644: if (operands[1] == const0_rtx) ! 645: return \"clr %0\"; ! 646: ! 647: return \"mov %1, %0\"; ! 648: }" ! 649: [(set_attr "length" "1,2,2,3")]) ! 650: ! 651: (define_insn "movqi" ! 652: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") ! 653: (match_operand:QI 1 "general_operand" "rRN,Qi,rRN,Qi"))] ! 654: "" ! 655: "* ! 656: { ! 657: if (operands[1] == const0_rtx) ! 658: return \"clrb %0\"; ! 659: ! 660: return \"movb %1, %0\"; ! 661: }" ! 662: [(set_attr "length" "1,2,2,3")]) ! 663: ! 664: ;; do we have to supply all these moves? e.g. to ! 665: ;; NO_LOAD_FPU_REGs ? ! 666: (define_insn "movdf" ! 667: [(set (match_operand:DF 0 "general_operand" "=f,R,f,Q,f,m") ! 668: (match_operand:DF 1 "general_operand" "fR,f,Q,f,F,m"))] ! 669: "" ! 670: "* return output_move_quad (operands);" ! 671: ;; just a guess.. ! 672: [(set_attr "length" "1,1,2,2,5,16")]) ! 673: ! 674: (define_insn "movsf" ! 675: [(set (match_operand:SF 0 "general_operand" "=g,r,g") ! 676: (match_operand:SF 1 "general_operand" "r,rmF,g"))] ! 677: "TARGET_FPU" ! 678: "* return output_move_double (operands);" ! 679: [(set_attr "length" "8,8,8")]) ! 680: ! 681: ;; maybe fiddle a bit with move_ratio, then ! 682: ;; let contraints only accept a register ... ! 683: ! 684: (define_expand "movstrhi" ! 685: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "=g,g")) ! 686: (mem:BLK (match_operand:BLK 1 "general_operand" "g,g"))) ! 687: (use (match_operand:HI 2 "arith_operand" "n,&mr")) ! 688: (use (match_operand:HI 3 "immediate_operand" "i,i")) ! 689: (clobber (match_scratch:HI 4 "=&r,X")) ! 690: (clobber (match_dup 0)) ! 691: (clobber (match_dup 1)) ! 692: (clobber (match_dup 2))])] ! 693: "(TARGET_BCOPY_BUILTIN)" ! 694: " ! 695: { ! 696: operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); ! 697: operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); ! 698: operands[2] = force_not_mem (operands[2]); ! 699: }") ! 700: ! 701: ! 702: (define_insn "" ; "movstrhi" ! 703: [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r")) ! 704: (mem:BLK (match_operand:HI 1 "general_operand" "r,r"))) ! 705: (use (match_operand:HI 2 "arith_operand" "n,&r")) ! 706: (use (match_operand:HI 3 "immediate_operand" "i,i")) ! 707: (clobber (match_scratch:HI 4 "=&r,X")) ! 708: (clobber (match_dup 0)) ! 709: (clobber (match_dup 1)) ! 710: (clobber (match_dup 2))] ! 711: "(TARGET_BCOPY_BUILTIN)" ! 712: "* return output_block_move (operands);" ! 713: ;;; just a guess ! 714: [(set_attr "length" "40")]) ! 715: ! 716: ! 717: ! 718: ;;- truncation instructions ! 719: ! 720: (define_insn "truncdfsf2" ! 721: [(set (match_operand:SF 0 "memory_operand" "=R,Q") ! 722: (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a")))] ! 723: "TARGET_FPU" ! 724: "stcdf %1, %0" ! 725: [(set_attr "length" "1,2")]) ! 726: ! 727: (define_expand "truncsihi2" ! 728: [(set (match_operand:HI 0 "general_operand" "=g") ! 729: (subreg:HI ! 730: (match_operand:SI 1 "general_operand" "or") ! 731: 0))] ! 732: "" ! 733: "") ! 734: ! 735: ! 736: ;;- zero extension instructions ! 737: ! 738: (define_insn "zero_extendqihi2" ! 739: [(set (match_operand:HI 0 "general_operand" "=r") ! 740: (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))] ! 741: "" ! 742: "bic $(256*255), %0" ! 743: [(set_attr "length" "2")]) ! 744: ! 745: (define_expand "zero_extendhisi2" ! 746: [(set (subreg:HI ! 747: (match_dup 0) ! 748: 1) ! 749: (match_operand:HI 1 "register_operand" "r")) ! 750: (set (subreg:HI ! 751: (match_operand:SI 0 "register_operand" "=r") ! 752: 0) ! 753: (const_int 0))] ! 754: "" ! 755: "/* operands[1] = make_safe_from (operands[1], operands[0]); */") ! 756: ! 757: ! 758: ;;- sign extension instructions ! 759: ! 760: (define_insn "extendsfdf2" ! 761: [(set (match_operand:DF 0 "register_operand" "=a,a") ! 762: (float_extend:SF (match_operand:SF 1 "memory_operand" "R,Q")))] ! 763: "TARGET_FPU" ! 764: "ldcfd %1, %0" ! 765: [(set_attr "length" "1,2")]) ! 766: ! 767: ;; does movb sign extend in register-to-register move? ! 768: (define_insn "extendqihi2" ! 769: [(set (match_operand:HI 0 "register_operand" "=r,r") ! 770: (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))] ! 771: "" ! 772: "movb %1, %0" ! 773: [(set_attr "length" "1,2")]) ! 774: ! 775: (define_insn "extendqisi2" ! 776: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 777: (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))] ! 778: "TARGET_40_PLUS" ! 779: "* ! 780: { ! 781: rtx latehalf[2]; ! 782: ! 783: /* make register pair available */ ! 784: latehalf[0] = operands[0]; ! 785: operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1); ! 786: ! 787: output_asm_insn(\"movb %1, %0\", operands); ! 788: output_asm_insn(\"sxt %0\", latehalf); ! 789: ! 790: return \"\"; ! 791: }" ! 792: [(set_attr "length" "2,3")]) ! 793: ! 794: ;; maybe we have to use define_expand to say that we have the instruction, ! 795: ;; unconditionally, and then match dependent on CPU type: ! 796: ! 797: (define_expand "extendhisi2" ! 798: [(set (match_operand:SI 0 "general_operand" "=g") ! 799: (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))] ! 800: "" ! 801: "") ! 802: ! 803: (define_insn "" ; "extendhisi2" ! 804: [(set (match_operand:SI 0 "general_operand" "=o,<,r") ! 805: (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))] ! 806: "TARGET_40_PLUS" ! 807: "* ! 808: { ! 809: rtx latehalf[2]; ! 810: ! 811: /* we don't want to mess with auto increment */ ! 812: ! 813: switch(which_alternative) ! 814: { ! 815: case 0: ! 816: ! 817: latehalf[0] = operands[0]; ! 818: operands[0] = adj_offsettable_operand(operands[0], 2); ! 819: ! 820: output_asm_insn(\"mov %1, %0\", operands); ! 821: output_asm_insn(\"sxt %0\", latehalf); ! 822: ! 823: return \"\"; ! 824: ! 825: case 1: ! 826: ! 827: /* - auto-decrement - right direction ;-) */ ! 828: output_asm_insn(\"mov %1, %0\", operands); ! 829: output_asm_insn(\"sxt %0\", operands); ! 830: ! 831: return \"\"; ! 832: ! 833: case 2: ! 834: ! 835: /* make register pair available */ ! 836: latehalf[0] = operands[0]; ! 837: operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1); ! 838: ! 839: output_asm_insn(\"mov %1, %0\", operands); ! 840: output_asm_insn(\"sxt %0\", latehalf); ! 841: ! 842: return \"\"; ! 843: ! 844: default: ! 845: ! 846: abort(); ! 847: } ! 848: }" ! 849: [(set_attr "length" "5,3,3")]) ! 850: ! 851: ! 852: (define_insn "" ! 853: [(set (match_operand:SI 0 "register_operand" "=r") ! 854: (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))] ! 855: "(! TARGET_40_PLUS)" ! 856: "* ! 857: { ! 858: static count = 0; ! 859: char buf[100]; ! 860: rtx lateoperands[2]; ! 861: ! 862: lateoperands[0] = operands[0]; ! 863: operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1); ! 864: ! 865: output_asm_insn(\"tst %0\", operands); ! 866: sprintf(buf, \"bge extendhisi%d\", count); ! 867: output_asm_insn(buf, NULL); ! 868: output_asm_insn(\"mov -1, %0\", lateoperands); ! 869: sprintf(buf, \"bne extendhisi%d\", count+1); ! 870: output_asm_insn(buf, NULL); ! 871: sprintf(buf, \"\\nextendhisi%d:\", count); ! 872: output_asm_insn(buf, NULL); ! 873: output_asm_insn(\"clr %0\", lateoperands); ! 874: sprintf(buf, \"\\nextendhisi%d:\", count+1); ! 875: output_asm_insn(buf, NULL); ! 876: ! 877: count += 2; ! 878: ! 879: return \"\"; ! 880: }" ! 881: [(set_attr "length" "6")]) ! 882: ! 883: ;; make float to int and vice versa ! 884: ;; using the cc_status.flag field we coulf probably cut down ! 885: ;; on seti and setl ! 886: ;; assume that we are normally in double and integer mode - ! 887: ;; what do pdp library routines do to fpu mode ? ! 888: ! 889: (define_insn "floatsidf2" ! 890: [(set (match_operand:DF 0 "register_operand" "=a,a") ! 891: (float:DF (match_operand:SI 1 "memory_operand" "R,Q")))] ! 892: "TARGET_FPU" ! 893: "setl\;ldcld %1, %0\;seti" ! 894: [(set_attr "length" "3,4")]) ! 895: ! 896: (define_insn "floathidf2" ! 897: [(set (match_operand:DF 0 "register_operand" "=a,a") ! 898: (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))] ! 899: "TARGET_FPU" ! 900: "ldcid %1, %0" ! 901: [(set_attr "length" "1,2")]) ! 902: ! 903: ;; cut float to int ! 904: (define_insn "fix_truncdfsi2" ! 905: [(set (match_operand:SI 0 "memory_operand" "=R,Q") ! 906: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))] ! 907: "TARGET_FPU" ! 908: "setl\;stcdl %1, %0\;seti" ! 909: [(set_attr "length" "3,4")]) ! 910: ! 911: (define_insn "fix_truncdfhi2" ! 912: [(set (match_operand:HI 0 "general_operand" "=rR,Q") ! 913: (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))] ! 914: "TARGET_FPU" ! 915: "stcdi %1, %0" ! 916: [(set_attr "length" "1,2")]) ! 917: ! 918: ! 919: ;;- arithmetic instructions ! 920: ;;- add instructions ! 921: ! 922: (define_insn "adddf3" ! 923: [(set (match_operand:DF 0 "register_operand" "=a,a,a") ! 924: (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0") ! 925: (match_operand:DF 2 "general_operand" "fR,Q,F")))] ! 926: "TARGET_FPU" ! 927: "addd %2, %0" ! 928: [(set_attr "length" "1,2,5")]) ! 929: ! 930: (define_insn "addsi3" ! 931: [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") ! 932: (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") ! 933: (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] ! 934: "" ! 935: "* ! 936: { /* Here we trust that operands don't overlap ! 937: ! 938: or is lateoperands the low word?? - looks like it! */ ! 939: ! 940: unsigned int i; ! 941: rtx lateoperands[3]; ! 942: ! 943: lateoperands[0] = operands[0]; ! 944: ! 945: if (REG_P (operands[0])) ! 946: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); ! 947: else ! 948: operands[0] = adj_offsettable_operand (operands[0], 2); ! 949: ! 950: if (! CONSTANT_P(operands[2])) ! 951: { ! 952: lateoperands[2] = operands[2]; ! 953: ! 954: if (REG_P (operands[2])) ! 955: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); ! 956: else ! 957: operands[2] = adj_offsettable_operand(operands[2], 2); ! 958: ! 959: output_asm_insn (\"add %2, %0\", operands); ! 960: output_asm_insn (\"adc %0\", lateoperands); ! 961: output_asm_insn (\"add %2, %0\", lateoperands); ! 962: return \"\"; ! 963: } ! 964: ! 965: lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff); ! 966: operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff); ! 967: ! 968: if (INTVAL(operands[2])) ! 969: { ! 970: output_asm_insn (\"add %2, %0\", operands); ! 971: output_asm_insn (\"adc %0\", lateoperands); ! 972: } ! 973: ! 974: if (INTVAL(lateoperands[2])) ! 975: output_asm_insn (\"add %2, %0\", lateoperands); ! 976: ! 977: return \"\"; ! 978: }" ! 979: [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")]) ! 980: ! 981: (define_insn "addhi3" ! 982: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") ! 983: (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") ! 984: (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] ! 985: "" ! 986: "* ! 987: { ! 988: if (GET_CODE (operands[2]) == CONST_INT) ! 989: if (INTVAL(operands[2]) == 1) ! 990: return \"inc %0\"; ! 991: else if (INTVAL(operands[2]) == -1) ! 992: return \"dec %0\"; ! 993: ! 994: return \"add %2, %0\"; ! 995: }" ! 996: [(set_attr "length" "1,2,2,3")]) ! 997: ! 998: (define_insn "addqi3" ! 999: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") ! 1000: (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") ! 1001: (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] ! 1002: "" ! 1003: "* ! 1004: { ! 1005: if (GET_CODE (operands[2]) == CONST_INT) ! 1006: if (INTVAL(operands[2]) == 1) ! 1007: return \"incb %0\"; ! 1008: else if (INTVAL(operands[2]) == -1) ! 1009: return \"decb %0\"; ! 1010: ! 1011: return \"addb %2, %0\"; ! 1012: }" ! 1013: [(set_attr "length" "1,2,2,3")]) ! 1014: ! 1015: ! 1016: ;;- subtract instructions ! 1017: ;; we don't have to care for constant second ! 1018: ;; args, since they are cononical plus:xx now! ! 1019: ;; also for minus:DF ?? ! 1020: ! 1021: (define_insn "subdf3" ! 1022: [(set (match_operand:DF 0 "register_operand" "=a,a") ! 1023: (minus:DF (match_operand:DF 1 "register_operand" "0,0") ! 1024: (match_operand:DF 2 "general_operand" "fR,Q")))] ! 1025: "TARGET_FPU" ! 1026: "subd %2, %0" ! 1027: [(set_attr "length" "1,2")]) ! 1028: ! 1029: (define_insn "subsi3" ! 1030: [(set (match_operand:SI 0 "general_operand" "=r,r,o,o") ! 1031: (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") ! 1032: (match_operand:SI 2 "general_operand" "r,o,r,o")))] ! 1033: "" ! 1034: "* ! 1035: { /* Here we trust that operands don't overlap ! 1036: ! 1037: or is lateoperands the low word?? - looks like it! */ ! 1038: ! 1039: unsigned int i; ! 1040: rtx lateoperands[3]; ! 1041: ! 1042: lateoperands[0] = operands[0]; ! 1043: ! 1044: if (REG_P (operands[0])) ! 1045: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); ! 1046: else ! 1047: operands[0] = adj_offsettable_operand (operands[0], 2); ! 1048: ! 1049: lateoperands[2] = operands[2]; ! 1050: ! 1051: if (REG_P (operands[2])) ! 1052: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); ! 1053: else ! 1054: operands[2] = adj_offsettable_operand(operands[2], 2); ! 1055: ! 1056: output_asm_insn (\"sub %2, %0\", operands); ! 1057: output_asm_insn (\"sbc %0\", lateoperands); ! 1058: output_asm_insn (\"sub %2, %0\", lateoperands); ! 1059: return \"\"; ! 1060: }" ! 1061: ;; offsetable memory addresses always are expensive!!! ! 1062: [(set_attr "length" "3,5,6,8")]) ! 1063: ! 1064: (define_insn "subhi3" ! 1065: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") ! 1066: (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") ! 1067: (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] ! 1068: "" ! 1069: "* ! 1070: { ! 1071: if (GET_CODE (operands[2]) == CONST_INT) ! 1072: abort(); ! 1073: ! 1074: return \"sub %2, %0\"; ! 1075: }" ! 1076: [(set_attr "length" "1,2,2,3")]) ! 1077: ! 1078: (define_insn "subqi3" ! 1079: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") ! 1080: (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0") ! 1081: (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))] ! 1082: "" ! 1083: "* ! 1084: { ! 1085: if (GET_CODE (operands[2]) == CONST_INT) ! 1086: abort(); ! 1087: ! 1088: return \"subb %2, %0\"; ! 1089: }" ! 1090: [(set_attr "length" "1,2,2,3")]) ! 1091: ! 1092: ;;;;- and instructions ! 1093: ;; Bit-and on the pdp (like on the vax) is done with a clear-bits insn. ! 1094: (define_expand "andsi3" ! 1095: [(set (match_operand:SI 0 "general_operand" "=g") ! 1096: (and:SI (match_operand:SI 1 "general_operand" "0") ! 1097: (not:SI (match_operand:SI 2 "general_operand" "g"))))] ! 1098: "" ! 1099: " ! 1100: { ! 1101: extern rtx expand_unop (); ! 1102: if (GET_CODE (operands[2]) == CONST_INT) ! 1103: operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); ! 1104: else ! 1105: operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1); ! 1106: }") ! 1107: ! 1108: (define_expand "andhi3" ! 1109: [(set (match_operand:HI 0 "general_operand" "=g") ! 1110: (and:HI (match_operand:HI 1 "general_operand" "0") ! 1111: (not:HI (match_operand:HI 2 "general_operand" "g"))))] ! 1112: "" ! 1113: " ! 1114: { ! 1115: extern rtx expand_unop (); ! 1116: if (GET_CODE (operands[2]) == CONST_INT) ! 1117: operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); ! 1118: else ! 1119: operands[2] = expand_unop (HImode, one_cmpl_optab, operands[2], 0, 1); ! 1120: }") ! 1121: ! 1122: (define_expand "andqi3" ! 1123: [(set (match_operand:QI 0 "general_operand" "=g") ! 1124: (and:QI (match_operand:QI 1 "general_operand" "0") ! 1125: (not:QI (match_operand:QI 2 "general_operand" "g"))))] ! 1126: "" ! 1127: " ! 1128: { ! 1129: extern rtx expand_unop (); ! 1130: rtx op = operands[2]; ! 1131: if (GET_CODE (op) == CONST_INT) ! 1132: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1133: ((1 << 8) - 1) & ~INTVAL (op)); ! 1134: else ! 1135: operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1); ! 1136: }") ! 1137: ! 1138: (define_insn "andcbsi3" ! 1139: [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") ! 1140: (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") ! 1141: (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))] ! 1142: "" ! 1143: "* ! 1144: { /* Here we trust that operands don't overlap ! 1145: ! 1146: or is lateoperands the low word?? - looks like it! */ ! 1147: ! 1148: unsigned int i; ! 1149: rtx lateoperands[3]; ! 1150: ! 1151: lateoperands[0] = operands[0]; ! 1152: ! 1153: if (REG_P (operands[0])) ! 1154: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); ! 1155: else ! 1156: operands[0] = adj_offsettable_operand (operands[0], 2); ! 1157: ! 1158: if (! CONSTANT_P(operands[2])) ! 1159: { ! 1160: lateoperands[2] = operands[2]; ! 1161: ! 1162: if (REG_P (operands[2])) ! 1163: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); ! 1164: else ! 1165: operands[2] = adj_offsettable_operand(operands[2], 2); ! 1166: ! 1167: output_asm_insn (\"bic %2, %0\", operands); ! 1168: output_asm_insn (\"bic %2, %0\", lateoperands); ! 1169: return \"\"; ! 1170: } ! 1171: ! 1172: lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff); ! 1173: operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff); ! 1174: ! 1175: /* these have different lengths, so we should have ! 1176: different constraints! */ ! 1177: if (INTVAL(operands[2])) ! 1178: output_asm_insn (\"bic %2, %0\", operands); ! 1179: ! 1180: if (INTVAL(lateoperands[2])) ! 1181: output_asm_insn (\"bic %2, %0\", lateoperands); ! 1182: ! 1183: return \"\"; ! 1184: }" ! 1185: [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) ! 1186: ! 1187: (define_insn "andcbhi3" ! 1188: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") ! 1189: (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0") ! 1190: (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))] ! 1191: "" ! 1192: "bic %2, %0" ! 1193: [(set_attr "length" "1,2,2,3")]) ! 1194: ! 1195: (define_insn "andcbqi3" ! 1196: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") ! 1197: (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0") ! 1198: (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))] ! 1199: "" ! 1200: "bicb %2, %0" ! 1201: [(set_attr "length" "1,2,2,3")]) ! 1202: ! 1203: ;;- Bit set (inclusive or) instructions ! 1204: (define_insn "iorsi3" ! 1205: [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") ! 1206: (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") ! 1207: (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] ! 1208: "" ! 1209: "* ! 1210: { /* Here we trust that operands don't overlap ! 1211: ! 1212: or is lateoperands the low word?? - looks like it! */ ! 1213: ! 1214: unsigned int i; ! 1215: rtx lateoperands[3]; ! 1216: ! 1217: lateoperands[0] = operands[0]; ! 1218: ! 1219: if (REG_P (operands[0])) ! 1220: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); ! 1221: else ! 1222: operands[0] = adj_offsettable_operand (operands[0], 2); ! 1223: ! 1224: if (! CONSTANT_P(operands[2])) ! 1225: { ! 1226: lateoperands[2] = operands[2]; ! 1227: ! 1228: if (REG_P (operands[2])) ! 1229: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); ! 1230: else ! 1231: operands[2] = adj_offsettable_operand(operands[2], 2); ! 1232: ! 1233: output_asm_insn (\"bis %2, %0\", operands); ! 1234: output_asm_insn (\"bis %2, %0\", lateoperands); ! 1235: return \"\"; ! 1236: } ! 1237: ! 1238: lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff); ! 1239: operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff); ! 1240: ! 1241: /* these have different lengths, so we should have ! 1242: different constraints! */ ! 1243: if (INTVAL(operands[2])) ! 1244: output_asm_insn (\"bis %2, %0\", operands); ! 1245: ! 1246: if (INTVAL(lateoperands[2])) ! 1247: output_asm_insn (\"bis %2, %0\", lateoperands); ! 1248: ! 1249: return \"\"; ! 1250: }" ! 1251: [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) ! 1252: ! 1253: (define_insn "iorhi3" ! 1254: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") ! 1255: (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") ! 1256: (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] ! 1257: "" ! 1258: "bis %2, %0" ! 1259: [(set_attr "length" "1,2,2,3")]) ! 1260: ! 1261: (define_insn "iorqi3" ! 1262: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") ! 1263: (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") ! 1264: (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))] ! 1265: "" ! 1266: "bisb %2, %0") ! 1267: ! 1268: ;;- xor instructions ! 1269: (define_insn "xorsi3" ! 1270: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") ! 1271: (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0") ! 1272: (match_operand:SI 2 "arith_operand" "r,I,J,K")))] ! 1273: "TARGET_40_PLUS" ! 1274: "* ! 1275: { /* Here we trust that operands don't overlap */ ! 1276: ! 1277: unsigned int i; ! 1278: rtx lateoperands[3]; ! 1279: ! 1280: lateoperands[0] = operands[0]; ! 1281: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); ! 1282: ! 1283: if (REG_P(operands[2])) ! 1284: { ! 1285: lateoperands[2] = operands[2]; ! 1286: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); ! 1287: ! 1288: output_asm_insn (\"xor %2, %0\", operands); ! 1289: output_asm_insn (\"xor %2, %0\", lateoperands); ! 1290: ! 1291: return \"\"; ! 1292: } ! 1293: ! 1294: lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff); ! 1295: operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff); ! 1296: ! 1297: if (INTVAL(operands[2])) ! 1298: output_asm_insn (\"xor %2, %0\", operands); ! 1299: ! 1300: if (INTVAL(lateoperands[2])) ! 1301: output_asm_insn (\"xor %2, %0\", lateoperands); ! 1302: ! 1303: return \"\"; ! 1304: }" ! 1305: [(set_attr "length" "2,1,1,2")]) ! 1306: ! 1307: (define_insn "xorhi3" ! 1308: [(set (match_operand:HI 0 "general_operand" "=rR,Q") ! 1309: (xor:HI (match_operand:HI 1 "general_operand" "%0,0") ! 1310: (match_operand:HI 2 "register_operand" "r,r")))] ! 1311: "TARGET_40_PLUS" ! 1312: "xor %2, %0" ! 1313: [(set_attr "length" "1,2")]) ! 1314: ! 1315: ;;- one complement instructions ! 1316: ! 1317: (define_insn "one_cmplhi2" ! 1318: [(set (match_operand:HI 0 "general_operand" "=rR,Q") ! 1319: (not:HI (match_operand:HI 1 "general_operand" "0,0")))] ! 1320: "" ! 1321: "com %0" ! 1322: [(set_attr "length" "1,2")]) ! 1323: ! 1324: (define_insn "one_cmplqi2" ! 1325: [(set (match_operand:QI 0 "general_operand" "=rR,Q") ! 1326: (not:QI (match_operand:QI 1 "general_operand" "0,0")))] ! 1327: "" ! 1328: "comb %0" ! 1329: [(set_attr "length" "1,2")]) ! 1330: ! 1331: ;;- arithmetic shift instructions ! 1332: (define_insn "ashlsi3" ! 1333: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 1334: (ashift:SI (match_operand:SI 1 "register_operand" "0,0") ! 1335: (match_operand:HI 2 "general_operand" "rR,Qi")))] ! 1336: "TARGET_45" ! 1337: "ashc %2,%0" ! 1338: [(set_attr "length" "1,2")]) ! 1339: ! 1340: ;; Arithmetic right shift on the pdp works by negating the shift count. ! 1341: (define_expand "ashrsi3" ! 1342: [(set (match_operand:SI 0 "register_operand" "=r") ! 1343: (ashift:SI (match_operand:SI 1 "register_operand" "0") ! 1344: (match_operand:HI 2 "general_operand" "g")))] ! 1345: "" ! 1346: " ! 1347: { ! 1348: operands[2] = negate_rtx (HImode, operands[2]); ! 1349: }") ! 1350: ! 1351: ;; define asl aslb asr asrb - ashc missing! ! 1352: ! 1353: ;; asl ! 1354: (define_insn "" ! 1355: [(set (match_operand:HI 0 "general_operand" "=rR,Q") ! 1356: (ashift:HI (match_operand:HI 1 "general_operand" "0,0") ! 1357: (const_int 1)))] ! 1358: "" ! 1359: "asl %0" ! 1360: [(set_attr "length" "1,2")]) ! 1361: ! 1362: ;; and another possibility for asr is << -1 ! 1363: ;; might cause problems since -1 can also be encoded as 65535! ! 1364: ;; not in gcc2 ??? ! 1365: ! 1366: ;; asr ! 1367: (define_insn "" ! 1368: [(set (match_operand:HI 0 "general_operand" "=rR,Q") ! 1369: (ashift:HI (match_operand:HI 1 "general_operand" "0,0") ! 1370: (const_int -1)))] ! 1371: "" ! 1372: "asr %0" ! 1373: [(set_attr "length" "1,2")]) ! 1374: ! 1375: ;; shift is by arbitrary count is expensive, ! 1376: ;; shift by one cheap - so let's do that, if ! 1377: ;; space doesn't matter ! 1378: (define_insn "" ! 1379: [(set (match_operand:HI 0 "general_operand" "=r") ! 1380: (ashift:HI (match_operand:HI 1 "general_operand" "0") ! 1381: (match_operand:HI 2 "expand_shift_operand" "O")))] ! 1382: "TARGET_TIME" ! 1383: "* ! 1384: { ! 1385: register int i; ! 1386: ! 1387: for (i = 1; i <= abs(INTVAL(operands[2])); i++) ! 1388: if (INTVAL(operands[2]) < 0) ! 1389: output_asm_insn(\"asr %0\", operands); ! 1390: else ! 1391: output_asm_insn(\"asl %0\", operands); ! 1392: ! 1393: return \"\"; ! 1394: }" ! 1395: ;; longest is 4 ! 1396: [(set (attr "length") (const_int 4))]) ! 1397: ! 1398: ;; aslb ! 1399: (define_insn "" ! 1400: [(set (match_operand:QI 0 "general_operand" "=r,o") ! 1401: (ashift:QI (match_operand:QI 1 "general_operand" "0,0") ! 1402: (match_operand:HI 2 "const_immediate_operand" "n,n")))] ! 1403: "" ! 1404: "* ! 1405: { /* allowing predec or post_inc is possible, but hairy! */ ! 1406: int i, cnt; ! 1407: ! 1408: cnt = INTVAL(operands[2]) & 0x0007; ! 1409: ! 1410: for (i=0 ; i < cnt ; i++) ! 1411: output_asm_insn(\"aslb %0\", operands); ! 1412: ! 1413: return \"\"; ! 1414: }" ! 1415: ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!! ! 1416: [(set_attr_alternative "length" ! 1417: [(const_int 7) ! 1418: (const_int 14)])]) ! 1419: ! 1420: ;;; asr ! 1421: ;(define_insn "" ! 1422: ; [(set (match_operand:HI 0 "general_operand" "=rR,Q") ! 1423: ; (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0") ! 1424: ; (const_int 1)))] ! 1425: ; "" ! 1426: ; "asr %0" ! 1427: ; [(set_attr "length" "1,2")]) ! 1428: ! 1429: ;; asrb ! 1430: (define_insn "" ! 1431: [(set (match_operand:QI 0 "general_operand" "=r,o") ! 1432: (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") ! 1433: (match_operand:HI 2 "const_immediate_operand" "n,n")))] ! 1434: "" ! 1435: "* ! 1436: { /* allowing predec or post_inc is possible, but hairy! */ ! 1437: int i, cnt; ! 1438: ! 1439: cnt = INTVAL(operands[2]) & 0x0007; ! 1440: ! 1441: for (i=0 ; i < cnt ; i++) ! 1442: output_asm_insn(\"asrb %0\", operands); ! 1443: ! 1444: return \"\"; ! 1445: }" ! 1446: [(set_attr_alternative "length" ! 1447: [(const_int 7) ! 1448: (const_int 14)])]) ! 1449: ! 1450: ;; the following is illegal - too complex!!! - just say 14 !!! ! 1451: ; [(set (attr "length") (plus (and (match_dup 2) ! 1452: ; (const_int 7)) ! 1453: ; (and (match_dup 2) ! 1454: ; (const_int 7))))]) ! 1455: ! 1456: ! 1457: ! 1458: ;; can we get +-1 in the next pattern? should ! 1459: ;; have been caught by previous patterns! ! 1460: ! 1461: (define_insn "ashlhi3" ! 1462: [(set (match_operand:HI 0 "register_operand" "=r,r") ! 1463: (ashift:HI (match_operand:HI 1 "register_operand" "0,0") ! 1464: (match_operand:HI 2 "general_operand" "rR,Qi")))] ! 1465: "" ! 1466: "* ! 1467: { ! 1468: if (GET_CODE(operands[2]) == CONST_INT) ! 1469: if (INTVAL(operands[2]) == 1) ! 1470: return \"asl %0\"; ! 1471: else if (INTVAL(operands[2]) == -1) ! 1472: return \"asr %0\"; ! 1473: ! 1474: return \"ash %2,%0\"; ! 1475: }" ! 1476: [(set_attr "length" "1,2")]) ! 1477: ! 1478: ;; Arithmetic right shift on the pdp works by negating the shift count. ! 1479: (define_expand "ashrhi3" ! 1480: [(set (match_operand:HI 0 "register_operand" "=r") ! 1481: (ashift:HI (match_operand:HI 1 "register_operand" "0") ! 1482: (match_operand:HI 2 "general_operand" "g")))] ! 1483: "" ! 1484: " ! 1485: { ! 1486: operands[2] = negate_rtx (HImode, operands[2]); ! 1487: }") ! 1488: ! 1489: ;;;;- logical shift instructions ! 1490: ;;(define_insn "lshrsi3" ! 1491: ;; [(set (match_operand:HI 0 "register_operand" "=r") ! 1492: ;; (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") ! 1493: ;; (match_operand:HI 2 "arith_operand" "rI")))] ! 1494: ;; "" ! 1495: ;; "srl %0,%2") ! 1496: ! 1497: ;; absolute ! 1498: ! 1499: (define_insn "absdf2" ! 1500: [(set (match_operand:DF 0 "general_operand" "=fR,Q") ! 1501: (abs:DF (match_operand:DF 1 "general_operand" "0,0")))] ! 1502: "TARGET_FPU" ! 1503: "absd %0" ! 1504: [(set_attr "length" "1,2")]) ! 1505: ! 1506: (define_insn "abshi2" ! 1507: [(set (match_operand:HI 0 "general_operand" "=r,o") ! 1508: (abs:HI (match_operand:HI 1 "general_operand" "0,0")))] ! 1509: "TARGET_ABSHI_BUILTIN" ! 1510: "* ! 1511: { ! 1512: static count = 0; ! 1513: char buf[200]; ! 1514: ! 1515: output_asm_insn(\"tst %0\", operands); ! 1516: sprintf(buf, \"bge abshi%d\", count); ! 1517: output_asm_insn(buf, NULL); ! 1518: output_asm_insn(\"neg %0\", operands); ! 1519: sprintf(buf, \"\\nabshi%d:\", count++); ! 1520: output_asm_insn(buf, NULL); ! 1521: ! 1522: return \"\"; ! 1523: }" ! 1524: [(set_attr "length" "3,5")]) ! 1525: ! 1526: ! 1527: ;; define expand abshi - is much better !!! - but ! 1528: ;; will it be optimized into an abshi2 ? ! 1529: ;; it will leave better code, because the tsthi might be ! 1530: ;; optimized away!! ! 1531: ; -- just a thought - don't have time to check ! 1532: ; ! 1533: ;(define_expand "abshi2" ! 1534: ; [(match_operand:HI 0 "general_operand" "") ! 1535: ; (match_operand:HI 1 "general_operand" "")] ! 1536: ; "" ! 1537: ; " ! 1538: ;{ ! 1539: ; rtx label = gen_label_rtx (); ! 1540: ; ! 1541: ; /* do I need this? */ ! 1542: ; do_pending_stack_adjust (); ! 1543: ; ! 1544: ; emit_move_insn (operands[0], operands[1]); ! 1545: ; ! 1546: ; emit_insn (gen_tsthi (operands[0])); ! 1547: ; emit_insn (gen_bge (label1)); ! 1548: ; ! 1549: ; emit_insn (gen_neghi(operands[0], operands[0]) ! 1550: ; ! 1551: ; emit_barrier (); ! 1552: ; ! 1553: ; emit_label (label); ! 1554: ; ! 1555: ; /* allow REG_NOTES to be set on last insn (labels don't have enough ! 1556: ; fields, and can't be used for REG_NOTES anyway). */ ! 1557: ; emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); ! 1558: ; DONE; ! 1559: ;}") ! 1560: ! 1561: ;; negate insns ! 1562: ! 1563: (define_insn "negdf2" ! 1564: [(set (match_operand:DF 0 "general_operand" "=fR,Q") ! 1565: (neg:DF (match_operand:DF 1 "register_operand" "0,0")))] ! 1566: "TARGET_FPU" ! 1567: "negd %0" ! 1568: [(set_attr "length" "1,2")]) ! 1569: ! 1570: (define_insn "neghi2" ! 1571: [(set (match_operand:HI 0 "general_operand" "=rR,Q") ! 1572: (neg:HI (match_operand:HI 1 "general_operand" "0,0")))] ! 1573: "" ! 1574: "neg %0" ! 1575: [(set_attr "length" "1,2")]) ! 1576: ! 1577: (define_insn "negqi2" ! 1578: [(set (match_operand:QI 0 "general_operand" "=rR,Q") ! 1579: (neg:QI (match_operand:QI 1 "general_operand" "0,0")))] ! 1580: "" ! 1581: "negb %0" ! 1582: [(set_attr "length" "1,2")]) ! 1583: ! 1584: ! 1585: ;; Unconditional and other jump instructions ! 1586: (define_insn "jump" ! 1587: [(set (pc) ! 1588: (label_ref (match_operand 0 "" "")))] ! 1589: "" ! 1590: "jmp %l0" ! 1591: [(set_attr "length" "2")]) ! 1592: ! 1593: (define_insn "" ! 1594: [(set (pc) ! 1595: (label_ref (match_operand 0 "" ""))) ! 1596: (clobber (const_int 1))] ! 1597: "" ! 1598: "jmp %l0" ! 1599: [(set_attr "length" "2")]) ! 1600: ! 1601: (define_insn "tablejump" ! 1602: [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q")) ! 1603: (use (label_ref (match_operand 1 "" "")))] ! 1604: "" ! 1605: "jmp %0" ! 1606: [(set_attr "length" "1,2")]) ! 1607: ! 1608: ;; indirect jump - let's be conservative! ! 1609: ;; allow only register_operand, even though we could also ! 1610: ;; allow labels etc. ! 1611: ! 1612: (define_insn "indirect_jump" ! 1613: [(set (pc) (match_operand:HI 0 "register_operand" "r"))] ! 1614: "" ! 1615: "jmp (%0)") ! 1616: ! 1617: ;;- jump to subroutine ! 1618: ! 1619: (define_insn "call" ! 1620: [(call (match_operand:HI 0 "general_operand" "R,Q") ! 1621: (match_operand:HI 1 "general_operand" "g,g")) ! 1622: ;; (use (reg:HI 0)) what was that ??? ! 1623: ] ! 1624: ;;- Don't use operand 1 for most machines. ! 1625: "" ! 1626: "jsr pc, %0" ! 1627: [(set_attr "length" "1,2")]) ! 1628: ! 1629: ;;- jump to subroutine ! 1630: (define_insn "call_value" ! 1631: [(set (match_operand 0 "" "") ! 1632: (call (match_operand:HI 1 "general_operand" "R,Q") ! 1633: (match_operand:HI 2 "general_operand" "g,g"))) ! 1634: ;; (use (reg:HI 0)) - what was that ???? ! 1635: ] ! 1636: ;;- Don't use operand 2 for most machines. ! 1637: "" ! 1638: "jsr pc, %1" ! 1639: [(set_attr "length" "1,2")]) ! 1640: ! 1641: ;;- nop instruction ! 1642: (define_insn "nop" ! 1643: [(const_int 0)] ! 1644: "" ! 1645: "nop") ! 1646: ! 1647: ! 1648: ;;- multiply ! 1649: ! 1650: (define_insn "muldf3" ! 1651: [(set (match_operand:DF 0 "register_operand" "=a,a,a") ! 1652: (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0") ! 1653: (match_operand:DF 2 "general_operand" "fR,Q,F")))] ! 1654: "TARGET_FPU" ! 1655: "muld %2, %0" ! 1656: [(set_attr "length" "1,2,5")]) ! 1657: ! 1658: ;; 16 bit result multiply: ! 1659: ;; currently we multiply only into odd registers, so we don't use two ! 1660: ;; registers - but this is a bit inefficient at times. If we define ! 1661: ;; a register class for each register, then we can specify properly ! 1662: ;; which register need which scratch register .... ! 1663: ! 1664: (define_insn "mulhi3" ! 1665: [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs ! 1666: (mult:HI (match_operand:HI 1 "register_operand" "%0,0") ! 1667: (match_operand:HI 2 "general_operand" "rR,Qi")))] ! 1668: "TARGET_45" ! 1669: "mul %2, %0" ! 1670: [(set_attr "length" "1,2")]) ! 1671: ! 1672: ;; 32 bit result ! 1673: (define_insn "mulhisi3" ! 1674: [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! ! 1675: (mult:SI (match_operand:HI 1 "register_operand" "%0,0") ! 1676: (match_operand:HI 2 "general_operand" "rR,Qi")))] ! 1677: "TARGET_45" ! 1678: "mul %2, %0" ! 1679: [(set_attr "length" "1,2")]) ! 1680: ! 1681: ;;- divide ! 1682: ;; how can I use the remainder ? - ! 1683: ;; modsidi and move upper register to lower ???? ! 1684: ! 1685: (define_insn "divdf3" ! 1686: [(set (match_operand:DF 0 "register_operand" "=a,a,a") ! 1687: (div:DF (match_operand:DF 1 "register_operand" "0,0,0") ! 1688: (match_operand:DF 2 "general_operand" "fR,Q,F")))] ! 1689: "TARGET_FPU" ! 1690: "divd %2, %0" ! 1691: [(set_attr "length" "1,2,5")]) ! 1692: ! 1693: (define_insn "" ! 1694: [(set (match_operand:HI 0 "general_operand" "=r,r") ! 1695: (truncate:HI ! 1696: (div:SI ! 1697: (match_operand:SI 1 "general_operand" "0,0") ! 1698: (sign_extend:SI (match_operand:HI 2 "general_operand" "rR,Q")))))] ! 1699: "TARGET_45" ! 1700: "div %2,%0" ! 1701: [(set_attr "length" "1,2")]) ! 1702: ! 1703: ;; - problem matching the (sign_extend:SI (const_int ...)) ! 1704: ; used without -O ! 1705: (define_insn "" ! 1706: [(set (match_operand:HI 0 "general_operand" "=r") ! 1707: (truncate:HI ! 1708: (div:SI ! 1709: (match_operand:SI 1 "general_operand" "0") ! 1710: (sign_extend:SI (match_operand 2 "immediate_operand" "n")))))] ! 1711: "TARGET_45" ! 1712: "div %2,%0" ! 1713: [(set_attr "length" "2")]) ! 1714: ! 1715: ; used with -O ! 1716: (define_insn "" ! 1717: [(set (match_operand:HI 0 "general_operand" "=r") ! 1718: (truncate:HI ! 1719: (div:SI ! 1720: (match_operand:SI 1 "general_operand" "0") ! 1721: (match_operand:SI 2 "immediate_operand" "i"))))] ! 1722: "TARGET_45" ! 1723: "div %2,%0" ! 1724: [(set_attr "length" "2")]) ! 1725: ! 1726: (define_expand "divhi3" ! 1727: [(set (match_dup 3) ! 1728: (sign_extend:SI (match_operand:HI 1 "general_operand" "g"))) ! 1729: (set (match_operand:HI 0 "general_operand" "g") ! 1730: (truncate:HI ! 1731: (div:SI ! 1732: (match_dup 3) ! 1733: (sign_extend:SI (match_operand:HI 2 "general_operand" "g")))))] ! 1734: "TARGET_45" ! 1735: "operands[3] = gen_reg_rtx (SImode);") ! 1736: ! 1737: (define_expand "udivqi" ! 1738: [(set (subreg:HI (match_dup 3) 1) ! 1739: (zero_extend:HI (match_operand:QI 1 "general_operand" "g"))) ! 1740: (set (subreg:HI (match_dup 3) 0) ! 1741: (const_int 0)) ! 1742: (set (match_dup 4) ! 1743: (sign_extend:HI (match_operand:QI 2 "general_operand" "g"))) ! 1744: (set (match_dup 5) ! 1745: (and:HI (match_dup 4) ! 1746: (const_int 255))) ! 1747: (set (match_dup 6) ! 1748: (truncate:HI ! 1749: (div:SI ! 1750: (match_dup 3) ! 1751: (sign_extend:SI (match_dup 5))))) ! 1752: (set (match_operand:QI 0 "general_operand" "g") ! 1753: (truncate:QI (match_dup 6)))] ! 1754: "TARGET_45" ! 1755: " ! 1756: { ! 1757: operands[3] = gen_reg_rtx (SImode); ! 1758: operands[4] = gen_reg_rtx (HImode); ! 1759: operands[5] = gen_reg_rtx (HImode); ! 1760: operands[6] = gen_reg_rtx (HImode); ! 1761: }") ! 1762: ! 1763: ;; we must restrict it to divide by 15-bit constant... ! 1764: (define_expand "udivhi3" ! 1765: [(set (subreg:HI (match_dup 3) 1) ! 1766: (match_operand:HI 1 "general_operand" "g")) ! 1767: (set (subreg:HI (match_dup 3) 0) ! 1768: (const_int 0)) ! 1769: (set (match_operand:HI 0 "general_operand" "g") ! 1770: (truncate:HI ! 1771: (div:SI ! 1772: (match_dup 3) ! 1773: (sign_extend:SI (match_operand:HI 2 "immediate15_operand" "n")))))] ! 1774: "TARGET_45" ! 1775: " ! 1776: { ! 1777: operands[3] = gen_reg_rtx (SImode); ! 1778: ! 1779: if (GET_CODE (operands[2]) != CONST_INT ! 1780: || ((INTVAL (operands[2]) & 0x8000) != 0x0000)) ! 1781: FAIL; ! 1782: }") ! 1783: ! 1784: (define_insn "" ! 1785: [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r,r") 1) ! 1786: (truncate:HI ! 1787: (mod:SI ! 1788: (match_operand:SI 1 "general_operand" "0,0") ! 1789: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rR,Q")))))] ! 1790: "TARGET_45" ! 1791: "div %2,%0" ! 1792: [(set_attr "length" "1,2")]) ! 1793: ! 1794: ;; (sign_extend:SI (const_int )) ! 1795: ; w/o -O ! 1796: (define_insn "" ! 1797: [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1) ! 1798: (truncate:HI ! 1799: (mod:SI ! 1800: (match_operand:SI 1 "general_operand" "0") ! 1801: (sign_extend:SI (match_operand 2 "immediate_operand" "i")))))] ! 1802: "TARGET_45" ! 1803: "div %2,%0" ! 1804: [(set_attr "length" "2")]) ! 1805: ; w/ -O ! 1806: (define_insn "" ! 1807: [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1) ! 1808: (truncate:HI ! 1809: (mod:SI ! 1810: (match_operand:SI 1 "general_operand" "0") ! 1811: (match_operand:SI 2 "immediate_operand" "i"))))] ! 1812: "TARGET_45" ! 1813: "div %2,%0" ! 1814: [(set_attr "length" "2")]) ! 1815: ! 1816: (define_expand "modhi3" ! 1817: [(set (match_dup 3) ! 1818: (sign_extend:SI (match_operand:HI 1 "general_operand" "g"))) ! 1819: (set (subreg:HI (match_dup 3) 1) ! 1820: (truncate:HI ! 1821: (mod:SI ! 1822: (match_dup 3) ! 1823: (sign_extend:SI (match_operand:HI 2 "general_operand" "g"))))) ! 1824: (set (match_operand:HI 0 "general_operand" "g") ! 1825: (subreg:HI (match_dup 3) 1))] ! 1826: "TARGET_45" ! 1827: "operands[3] = gen_reg_rtx (SImode);") ! 1828: ! 1829: ;; we must restrict it to mod by 15 bit constant ! 1830: (define_expand "umodhi3" ! 1831: [(set (subreg:HI (match_dup 3) 0) ! 1832: (match_operand:HI 1 "general_operand" "g")) ! 1833: (set (subreg:HI (match_dup 3) 1) ! 1834: (const_int 0)) ! 1835: (set (subreg:HI (match_dup 3) 1) ! 1836: (truncate:HI ! 1837: (mod:SI ! 1838: (match_dup 3) ! 1839: (sign_extend:SI (match_operand:HI 2 "immediate15_operand" "n"))))) ! 1840: (set (match_operand:HI 0 "general_operand" "g") ! 1841: (subreg:HI (match_dup 3) 1))] ! 1842: "TARGET_45" ! 1843: " ! 1844: { ! 1845: operands[3] = gen_reg_rtx (SImode); ! 1846: ! 1847: if (GET_CODE (operands[2]) != CONST_INT ! 1848: || ((INTVAL (operands[2]) & 0x8000) != 0x0000)) ! 1849: FAIL; ! 1850: }") ! 1851: ! 1852: (define_insn "" ! 1853: [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r,r") 0) ! 1854: (truncate:HI ! 1855: (div:SI ! 1856: (match_operand:SI 1 "general_operand" "0,0") ! 1857: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rR,Q"))))) ! 1858: (set (subreg:HI (match_dup 0) 1) ! 1859: (truncate:HI ! 1860: (mod:SI ! 1861: (match_dup 1) ! 1862: (sign_extend:SI (match_dup 2)))))] ! 1863: "TARGET_45" ! 1864: "div %2, %0" ! 1865: [(set_attr "length" "1,2")]) ! 1866: ! 1867: ;; (sign_extend:SI (const_int)) ! 1868: ; w/o -O ! 1869: (define_insn "" ! 1870: [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) ! 1871: (truncate:HI ! 1872: (div:SI ! 1873: (match_operand:SI 1 "general_operand" "0") ! 1874: (sign_extend:SI (match_operand 2 "immediate_operand" "i"))))) ! 1875: (set (subreg:HI (match_dup 0) 1) ! 1876: (truncate:HI ! 1877: (mod:SI ! 1878: (match_dup 1) ! 1879: (sign_extend:SI (match_dup 2)))))] ! 1880: "TARGET_45" ! 1881: "div %2, %0" ! 1882: [(set_attr "length" "2")]) ! 1883: ; w/ -O ! 1884: (define_insn "" ! 1885: [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) ! 1886: (truncate:HI ! 1887: (div:SI ! 1888: (match_operand:SI 1 "general_operand" "0") ! 1889: (match_operand:SI 2 "immediate_operand" "i")))) ! 1890: (set (subreg:HI (match_dup 0) 1) ! 1891: (truncate:HI ! 1892: (mod:SI ! 1893: (match_dup 1) ! 1894: (match_dup 2))))] ! 1895: "TARGET_45" ! 1896: "div %2, %0" ! 1897: [(set_attr "length" "2")]) ! 1898: ! 1899: (define_expand "divmodhi4" ! 1900: [(set (match_dup 4) ! 1901: (sign_extend:SI (match_operand:HI 1 "general_operand" "g"))) ! 1902: (set (subreg:HI (match_dup 4) 0) ! 1903: (truncate:HI ! 1904: (div:SI ! 1905: (match_dup 4) ! 1906: (sign_extend:SI (match_operand:HI 2 "general_operand" "g"))))) ! 1907: (set (subreg:HI (match_dup 4) 1) ! 1908: (truncate:HI ! 1909: (mod:SI ! 1910: (match_dup 4) ! 1911: (sign_extend:SI (match_dup 2))))) ! 1912: (set (match_operand:HI 0 "general_operand" "g") ! 1913: (subreg:HI (match_dup 4) 0)) ! 1914: (set (match_operand:HI 3 "general_operand" "g") ! 1915: (subreg:HI (match_dup 4) 1))] ! 1916: "TARGET_45" ! 1917: "operands[4] = gen_reg_rtx(SImode);") ! 1918: ! 1919: (define_expand "udivmodhi4" ! 1920: [(set (subreg:HI (match_dup 3) 1) ! 1921: (match_operand:HI 1 "general_operand" "g")) ! 1922: (set (subreg:HI (match_dup 3) 0) ! 1923: (const_int 0)) ! 1924: (set (subreg:HI (match_dup 4) 0) ! 1925: (truncate:HI ! 1926: (div:SI ! 1927: (match_dup 4) ! 1928: (sign_extend:SI (match_operand:HI 2 "immediate15_operand" "n"))))) ! 1929: (set (subreg:HI (match_dup 4) 1) ! 1930: (truncate:HI ! 1931: (mod:SI ! 1932: (match_dup 4) ! 1933: (sign_extend:SI (match_dup 2))))) ! 1934: (set (match_operand:HI 0 "general_operand" "g") ! 1935: (subreg:HI (match_dup 4) 0)) ! 1936: (set (match_operand:HI 3 "general_operand" "g") ! 1937: (subreg:HI (match_dup 4) 1))] ! 1938: "TARGET_45" ! 1939: " ! 1940: { ! 1941: operands[3] = gen_reg_rtx (SImode); ! 1942: ! 1943: if (GET_CODE (operands[2]) != CONST_INT ! 1944: || ((INTVAL (operands[2]) & 0x8000) != 0x0000)) ! 1945: FAIL; ! 1946: }") ! 1947: ! 1948: ;; truncate used in div/mod patterns ! 1949: (define_insn "" ! 1950: [(set (match_operand:QI 0 "general_operand" "=r,r") ! 1951: (truncate:QI (match_operand:HI 1 "general_operand" "0,r")))] ! 1952: "TARGET_45" ! 1953: "@ ! 1954: ; nop ! 1955: movb %1, %0" ! 1956: [(set_attr "length" "0,1")]) ! 1957: ! 1958: ;; is rotate doing the right thing to be included here ????
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.