|
|
1.1 root 1: ;;- Machine description for the pdp11 for GNU C compiler 1.1.1.2 ! root 2: ;; Copyright (C) 1994, 1995 Free Software Foundation, Inc. 1.1 root 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: 1.1.1.2 ! root 66: ;; a user's asm statement 1.1 root 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 1.1.1.2 ! root 268: ;; make this valid for all jump distances! 1.1 root 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: "" 1.1.1.2 ! root 368: "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));" 1.1 root 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: "" 1.1.1.2 ! root 541: "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));" 1.1 root 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: "" 1.1.1.2 ! root 575: "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));" 1.1 root 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 1.1.1.2 ! root 682: ;; let constraints only accept a register ... 1.1 root 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" 1.1.1.2 ! root 721: [(set (match_operand:SF 0 "general_operand" "=r,R,Q") ! 722: (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))] 1.1 root 723: "TARGET_FPU" 1.1.1.2 ! root 724: "* if (which_alternative ==0) ! 725: { ! 726: output_asm_insn(\"stcdf %1, -(sp)\", operands); ! 727: output_asm_insn(\"mov (sp)+, %0\", operands); ! 728: operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1); ! 729: output_asm_insn(\"mov (sp)+, %0\", operands); ! 730: return \"\"; ! 731: } ! 732: else if (which_alternative == 1) ! 733: return \"stcdf %1, %0\"; ! 734: else ! 735: return \"stcdf %1, %0\"; ! 736: " ! 737: [(set_attr "length" "3,1,2")]) ! 738: 1.1 root 739: 740: (define_expand "truncsihi2" 741: [(set (match_operand:HI 0 "general_operand" "=g") 742: (subreg:HI 743: (match_operand:SI 1 "general_operand" "or") 744: 0))] 745: "" 746: "") 747: 748: 749: ;;- zero extension instructions 750: 751: (define_insn "zero_extendqihi2" 752: [(set (match_operand:HI 0 "general_operand" "=r") 753: (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))] 754: "" 755: "bic $(256*255), %0" 756: [(set_attr "length" "2")]) 757: 758: (define_expand "zero_extendhisi2" 759: [(set (subreg:HI 760: (match_dup 0) 761: 1) 762: (match_operand:HI 1 "register_operand" "r")) 763: (set (subreg:HI 764: (match_operand:SI 0 "register_operand" "=r") 765: 0) 766: (const_int 0))] 767: "" 768: "/* operands[1] = make_safe_from (operands[1], operands[0]); */") 769: 770: 771: ;;- sign extension instructions 772: 773: (define_insn "extendsfdf2" 1.1.1.2 ! root 774: [(set (match_operand:DF 0 "register_operand" "=a,a,a") ! 775: (float_extend:SF (match_operand:SF 1 "general_operand" "r,R,Q")))] 1.1 root 776: "TARGET_FPU" 1.1.1.2 ! root 777: "@ ! 778: mov %1, -(sp)\;ldcfd (sp)+,%0 ! 779: ldcfd %1, %0 ! 780: ldcfd %1, %0" ! 781: [(set_attr "length" "2,1,2")]) 1.1 root 782: 783: ;; does movb sign extend in register-to-register move? 784: (define_insn "extendqihi2" 785: [(set (match_operand:HI 0 "register_operand" "=r,r") 786: (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))] 787: "" 788: "movb %1, %0" 789: [(set_attr "length" "1,2")]) 790: 791: (define_insn "extendqisi2" 792: [(set (match_operand:SI 0 "register_operand" "=r,r") 793: (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))] 794: "TARGET_40_PLUS" 795: "* 796: { 797: rtx latehalf[2]; 798: 799: /* make register pair available */ 800: latehalf[0] = operands[0]; 801: operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1); 802: 803: output_asm_insn(\"movb %1, %0\", operands); 804: output_asm_insn(\"sxt %0\", latehalf); 805: 806: return \"\"; 807: }" 808: [(set_attr "length" "2,3")]) 809: 810: ;; maybe we have to use define_expand to say that we have the instruction, 811: ;; unconditionally, and then match dependent on CPU type: 812: 813: (define_expand "extendhisi2" 814: [(set (match_operand:SI 0 "general_operand" "=g") 815: (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))] 816: "" 817: "") 818: 819: (define_insn "" ; "extendhisi2" 820: [(set (match_operand:SI 0 "general_operand" "=o,<,r") 821: (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))] 822: "TARGET_40_PLUS" 823: "* 824: { 825: rtx latehalf[2]; 826: 827: /* we don't want to mess with auto increment */ 828: 829: switch(which_alternative) 830: { 831: case 0: 832: 833: latehalf[0] = operands[0]; 834: operands[0] = adj_offsettable_operand(operands[0], 2); 835: 836: output_asm_insn(\"mov %1, %0\", operands); 837: output_asm_insn(\"sxt %0\", latehalf); 838: 839: return \"\"; 840: 841: case 1: 842: 843: /* - auto-decrement - right direction ;-) */ 844: output_asm_insn(\"mov %1, %0\", operands); 845: output_asm_insn(\"sxt %0\", operands); 846: 847: return \"\"; 848: 849: case 2: 850: 851: /* make register pair available */ 852: latehalf[0] = operands[0]; 853: operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1); 854: 855: output_asm_insn(\"mov %1, %0\", operands); 856: output_asm_insn(\"sxt %0\", latehalf); 857: 858: return \"\"; 859: 860: default: 861: 862: abort(); 863: } 864: }" 865: [(set_attr "length" "5,3,3")]) 866: 867: 868: (define_insn "" 869: [(set (match_operand:SI 0 "register_operand" "=r") 870: (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))] 871: "(! TARGET_40_PLUS)" 872: "* 873: { 874: static count = 0; 875: char buf[100]; 876: rtx lateoperands[2]; 877: 878: lateoperands[0] = operands[0]; 879: operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1); 880: 881: output_asm_insn(\"tst %0\", operands); 882: sprintf(buf, \"bge extendhisi%d\", count); 883: output_asm_insn(buf, NULL); 884: output_asm_insn(\"mov -1, %0\", lateoperands); 885: sprintf(buf, \"bne extendhisi%d\", count+1); 886: output_asm_insn(buf, NULL); 887: sprintf(buf, \"\\nextendhisi%d:\", count); 888: output_asm_insn(buf, NULL); 889: output_asm_insn(\"clr %0\", lateoperands); 890: sprintf(buf, \"\\nextendhisi%d:\", count+1); 891: output_asm_insn(buf, NULL); 892: 893: count += 2; 894: 895: return \"\"; 896: }" 897: [(set_attr "length" "6")]) 898: 899: ;; make float to int and vice versa 1.1.1.2 ! root 900: ;; using the cc_status.flag field we could probably cut down 1.1 root 901: ;; on seti and setl 902: ;; assume that we are normally in double and integer mode - 903: ;; what do pdp library routines do to fpu mode ? 904: 905: (define_insn "floatsidf2" 1.1.1.2 ! root 906: [(set (match_operand:DF 0 "register_operand" "=a,a,a") ! 907: (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))] 1.1 root 908: "TARGET_FPU" 1.1.1.2 ! root 909: "* if (which_alternative ==0) ! 910: { ! 911: rtx latehalf[2]; ! 912: ! 913: latehalf[0] = NULL; ! 914: latehalf[1] = gen_rtx(REG, HImode, REGNO (operands[0])+1); ! 915: output_asm_insn(\"mov %1, -(sp)\", latehalf); ! 916: output_asm_insn(\"mov %1, -(sp)\", operands); ! 917: ! 918: output_asm_insn(\"setl\", operands); ! 919: output_asm_insn(\"ldcld (sp)+, %0\", operands); ! 920: output_asm_insn(\"seti\", operands); ! 921: return \"\"; ! 922: } ! 923: else if (which_alternative == 1) ! 924: return \"setl\;ldcld %1, %0\;seti\"; ! 925: else ! 926: return \"setl\;ldcld %1, %0\;seti\"; ! 927: " ! 928: [(set_attr "length" "5,3,4")]) 1.1 root 929: 930: (define_insn "floathidf2" 931: [(set (match_operand:DF 0 "register_operand" "=a,a") 932: (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))] 933: "TARGET_FPU" 934: "ldcid %1, %0" 935: [(set_attr "length" "1,2")]) 936: 937: ;; cut float to int 938: (define_insn "fix_truncdfsi2" 1.1.1.2 ! root 939: [(set (match_operand:SI 0 "general_operand" "=r,R,Q") ! 940: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))] 1.1 root 941: "TARGET_FPU" 1.1.1.2 ! root 942: "* if (which_alternative ==0) ! 943: { ! 944: output_asm_insn(\"setl\", operands); ! 945: output_asm_insn(\"stcdl %1, -(sp)\", operands); ! 946: output_asm_insn(\"seti\", operands); ! 947: output_asm_insn(\"mov (sp)+, %0\", operands); ! 948: operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1); ! 949: output_asm_insn(\"mov (sp)+, %0\", operands); ! 950: return \"\"; ! 951: } ! 952: else if (which_alternative == 1) ! 953: return \"setl\;stcdl %1, %0\;seti\"; ! 954: else ! 955: return \"setl\;stcdl %1, %0\;seti\"; ! 956: " ! 957: [(set_attr "length" "5,3,4")]) 1.1 root 958: 959: (define_insn "fix_truncdfhi2" 960: [(set (match_operand:HI 0 "general_operand" "=rR,Q") 961: (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))] 962: "TARGET_FPU" 963: "stcdi %1, %0" 964: [(set_attr "length" "1,2")]) 965: 966: 967: ;;- arithmetic instructions 968: ;;- add instructions 969: 970: (define_insn "adddf3" 971: [(set (match_operand:DF 0 "register_operand" "=a,a,a") 972: (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0") 973: (match_operand:DF 2 "general_operand" "fR,Q,F")))] 974: "TARGET_FPU" 975: "addd %2, %0" 976: [(set_attr "length" "1,2,5")]) 977: 978: (define_insn "addsi3" 979: [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") 980: (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") 981: (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] 982: "" 983: "* 984: { /* Here we trust that operands don't overlap 985: 986: or is lateoperands the low word?? - looks like it! */ 987: 988: unsigned int i; 989: rtx lateoperands[3]; 990: 991: lateoperands[0] = operands[0]; 992: 993: if (REG_P (operands[0])) 994: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); 995: else 996: operands[0] = adj_offsettable_operand (operands[0], 2); 997: 998: if (! CONSTANT_P(operands[2])) 999: { 1000: lateoperands[2] = operands[2]; 1001: 1002: if (REG_P (operands[2])) 1003: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); 1004: else 1005: operands[2] = adj_offsettable_operand(operands[2], 2); 1006: 1007: output_asm_insn (\"add %2, %0\", operands); 1008: output_asm_insn (\"adc %0\", lateoperands); 1009: output_asm_insn (\"add %2, %0\", lateoperands); 1010: return \"\"; 1011: } 1012: 1013: lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff); 1014: operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff); 1015: 1016: if (INTVAL(operands[2])) 1017: { 1018: output_asm_insn (\"add %2, %0\", operands); 1019: output_asm_insn (\"adc %0\", lateoperands); 1020: } 1021: 1022: if (INTVAL(lateoperands[2])) 1023: output_asm_insn (\"add %2, %0\", lateoperands); 1024: 1025: return \"\"; 1026: }" 1027: [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")]) 1028: 1029: (define_insn "addhi3" 1030: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") 1031: (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") 1032: (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] 1033: "" 1034: "* 1035: { 1036: if (GET_CODE (operands[2]) == CONST_INT) 1037: if (INTVAL(operands[2]) == 1) 1038: return \"inc %0\"; 1039: else if (INTVAL(operands[2]) == -1) 1040: return \"dec %0\"; 1041: 1042: return \"add %2, %0\"; 1043: }" 1044: [(set_attr "length" "1,2,2,3")]) 1045: 1046: (define_insn "addqi3" 1047: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") 1048: (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") 1049: (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] 1050: "" 1051: "* 1052: { 1053: if (GET_CODE (operands[2]) == CONST_INT) 1054: if (INTVAL(operands[2]) == 1) 1055: return \"incb %0\"; 1056: else if (INTVAL(operands[2]) == -1) 1057: return \"decb %0\"; 1058: 1059: return \"addb %2, %0\"; 1060: }" 1061: [(set_attr "length" "1,2,2,3")]) 1062: 1063: 1064: ;;- subtract instructions 1065: ;; we don't have to care for constant second 1.1.1.2 ! root 1066: ;; args, since they are canonical plus:xx now! 1.1 root 1067: ;; also for minus:DF ?? 1068: 1069: (define_insn "subdf3" 1070: [(set (match_operand:DF 0 "register_operand" "=a,a") 1071: (minus:DF (match_operand:DF 1 "register_operand" "0,0") 1072: (match_operand:DF 2 "general_operand" "fR,Q")))] 1073: "TARGET_FPU" 1074: "subd %2, %0" 1075: [(set_attr "length" "1,2")]) 1076: 1077: (define_insn "subsi3" 1078: [(set (match_operand:SI 0 "general_operand" "=r,r,o,o") 1079: (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") 1080: (match_operand:SI 2 "general_operand" "r,o,r,o")))] 1081: "" 1082: "* 1083: { /* Here we trust that operands don't overlap 1084: 1085: or is lateoperands the low word?? - looks like it! */ 1086: 1087: unsigned int i; 1088: rtx lateoperands[3]; 1089: 1090: lateoperands[0] = operands[0]; 1091: 1092: if (REG_P (operands[0])) 1093: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); 1094: else 1095: operands[0] = adj_offsettable_operand (operands[0], 2); 1096: 1097: lateoperands[2] = operands[2]; 1098: 1099: if (REG_P (operands[2])) 1100: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); 1101: else 1102: operands[2] = adj_offsettable_operand(operands[2], 2); 1103: 1104: output_asm_insn (\"sub %2, %0\", operands); 1105: output_asm_insn (\"sbc %0\", lateoperands); 1106: output_asm_insn (\"sub %2, %0\", lateoperands); 1107: return \"\"; 1108: }" 1.1.1.2 ! root 1109: ;; offsettable memory addresses always are expensive!!! 1.1 root 1110: [(set_attr "length" "3,5,6,8")]) 1111: 1112: (define_insn "subhi3" 1113: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") 1114: (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") 1115: (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] 1116: "" 1117: "* 1118: { 1119: if (GET_CODE (operands[2]) == CONST_INT) 1120: abort(); 1121: 1122: return \"sub %2, %0\"; 1123: }" 1124: [(set_attr "length" "1,2,2,3")]) 1125: 1126: (define_insn "subqi3" 1127: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") 1128: (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0") 1129: (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))] 1130: "" 1131: "* 1132: { 1133: if (GET_CODE (operands[2]) == CONST_INT) 1134: abort(); 1135: 1136: return \"subb %2, %0\"; 1137: }" 1138: [(set_attr "length" "1,2,2,3")]) 1139: 1140: ;;;;- and instructions 1141: ;; Bit-and on the pdp (like on the vax) is done with a clear-bits insn. 1142: (define_expand "andsi3" 1143: [(set (match_operand:SI 0 "general_operand" "=g") 1144: (and:SI (match_operand:SI 1 "general_operand" "0") 1145: (not:SI (match_operand:SI 2 "general_operand" "g"))))] 1146: "" 1147: " 1148: { 1149: extern rtx expand_unop (); 1150: if (GET_CODE (operands[2]) == CONST_INT) 1151: operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); 1152: else 1153: operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1); 1154: }") 1155: 1156: (define_expand "andhi3" 1157: [(set (match_operand:HI 0 "general_operand" "=g") 1158: (and:HI (match_operand:HI 1 "general_operand" "0") 1159: (not:HI (match_operand:HI 2 "general_operand" "g"))))] 1160: "" 1161: " 1162: { 1163: extern rtx expand_unop (); 1164: if (GET_CODE (operands[2]) == CONST_INT) 1165: operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); 1166: else 1167: operands[2] = expand_unop (HImode, one_cmpl_optab, operands[2], 0, 1); 1168: }") 1169: 1170: (define_expand "andqi3" 1171: [(set (match_operand:QI 0 "general_operand" "=g") 1172: (and:QI (match_operand:QI 1 "general_operand" "0") 1173: (not:QI (match_operand:QI 2 "general_operand" "g"))))] 1174: "" 1175: " 1176: { 1177: extern rtx expand_unop (); 1178: rtx op = operands[2]; 1179: if (GET_CODE (op) == CONST_INT) 1180: operands[2] = gen_rtx (CONST_INT, VOIDmode, 1181: ((1 << 8) - 1) & ~INTVAL (op)); 1182: else 1183: operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1); 1184: }") 1185: 1186: (define_insn "andcbsi3" 1187: [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") 1188: (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") 1189: (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))] 1190: "" 1191: "* 1192: { /* Here we trust that operands don't overlap 1193: 1194: or is lateoperands the low word?? - looks like it! */ 1195: 1196: unsigned int i; 1197: rtx lateoperands[3]; 1198: 1199: lateoperands[0] = operands[0]; 1200: 1201: if (REG_P (operands[0])) 1202: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); 1203: else 1204: operands[0] = adj_offsettable_operand (operands[0], 2); 1205: 1206: if (! CONSTANT_P(operands[2])) 1207: { 1208: lateoperands[2] = operands[2]; 1209: 1210: if (REG_P (operands[2])) 1211: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); 1212: else 1213: operands[2] = adj_offsettable_operand(operands[2], 2); 1214: 1215: output_asm_insn (\"bic %2, %0\", operands); 1216: output_asm_insn (\"bic %2, %0\", lateoperands); 1217: return \"\"; 1218: } 1219: 1220: lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff); 1221: operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff); 1222: 1223: /* these have different lengths, so we should have 1224: different constraints! */ 1225: if (INTVAL(operands[2])) 1226: output_asm_insn (\"bic %2, %0\", operands); 1227: 1228: if (INTVAL(lateoperands[2])) 1229: output_asm_insn (\"bic %2, %0\", lateoperands); 1230: 1231: return \"\"; 1232: }" 1233: [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) 1234: 1235: (define_insn "andcbhi3" 1236: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") 1237: (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0") 1238: (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))] 1239: "" 1240: "bic %2, %0" 1241: [(set_attr "length" "1,2,2,3")]) 1242: 1243: (define_insn "andcbqi3" 1244: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") 1245: (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0") 1246: (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))] 1247: "" 1248: "bicb %2, %0" 1249: [(set_attr "length" "1,2,2,3")]) 1250: 1251: ;;- Bit set (inclusive or) instructions 1252: (define_insn "iorsi3" 1253: [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") 1254: (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") 1255: (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] 1256: "" 1257: "* 1258: { /* Here we trust that operands don't overlap 1259: 1260: or is lateoperands the low word?? - looks like it! */ 1261: 1262: unsigned int i; 1263: rtx lateoperands[3]; 1264: 1265: lateoperands[0] = operands[0]; 1266: 1267: if (REG_P (operands[0])) 1268: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); 1269: else 1270: operands[0] = adj_offsettable_operand (operands[0], 2); 1271: 1272: if (! CONSTANT_P(operands[2])) 1273: { 1274: lateoperands[2] = operands[2]; 1275: 1276: if (REG_P (operands[2])) 1277: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); 1278: else 1279: operands[2] = adj_offsettable_operand(operands[2], 2); 1280: 1281: output_asm_insn (\"bis %2, %0\", operands); 1282: output_asm_insn (\"bis %2, %0\", lateoperands); 1283: return \"\"; 1284: } 1285: 1286: lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff); 1287: operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff); 1288: 1289: /* these have different lengths, so we should have 1290: different constraints! */ 1291: if (INTVAL(operands[2])) 1292: output_asm_insn (\"bis %2, %0\", operands); 1293: 1294: if (INTVAL(lateoperands[2])) 1295: output_asm_insn (\"bis %2, %0\", lateoperands); 1296: 1297: return \"\"; 1298: }" 1299: [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) 1300: 1301: (define_insn "iorhi3" 1302: [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") 1303: (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") 1304: (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] 1305: "" 1306: "bis %2, %0" 1307: [(set_attr "length" "1,2,2,3")]) 1308: 1309: (define_insn "iorqi3" 1310: [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") 1311: (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") 1312: (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))] 1313: "" 1314: "bisb %2, %0") 1315: 1316: ;;- xor instructions 1317: (define_insn "xorsi3" 1318: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 1319: (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0") 1320: (match_operand:SI 2 "arith_operand" "r,I,J,K")))] 1321: "TARGET_40_PLUS" 1322: "* 1323: { /* Here we trust that operands don't overlap */ 1324: 1325: unsigned int i; 1326: rtx lateoperands[3]; 1327: 1328: lateoperands[0] = operands[0]; 1329: operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1); 1330: 1331: if (REG_P(operands[2])) 1332: { 1333: lateoperands[2] = operands[2]; 1334: operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1); 1335: 1336: output_asm_insn (\"xor %2, %0\", operands); 1337: output_asm_insn (\"xor %2, %0\", lateoperands); 1338: 1339: return \"\"; 1340: } 1341: 1342: lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff); 1343: operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff); 1344: 1345: if (INTVAL(operands[2])) 1346: output_asm_insn (\"xor %2, %0\", operands); 1347: 1348: if (INTVAL(lateoperands[2])) 1349: output_asm_insn (\"xor %2, %0\", lateoperands); 1350: 1351: return \"\"; 1352: }" 1353: [(set_attr "length" "2,1,1,2")]) 1354: 1355: (define_insn "xorhi3" 1356: [(set (match_operand:HI 0 "general_operand" "=rR,Q") 1357: (xor:HI (match_operand:HI 1 "general_operand" "%0,0") 1358: (match_operand:HI 2 "register_operand" "r,r")))] 1359: "TARGET_40_PLUS" 1360: "xor %2, %0" 1361: [(set_attr "length" "1,2")]) 1362: 1363: ;;- one complement instructions 1364: 1365: (define_insn "one_cmplhi2" 1366: [(set (match_operand:HI 0 "general_operand" "=rR,Q") 1367: (not:HI (match_operand:HI 1 "general_operand" "0,0")))] 1368: "" 1369: "com %0" 1370: [(set_attr "length" "1,2")]) 1371: 1372: (define_insn "one_cmplqi2" 1373: [(set (match_operand:QI 0 "general_operand" "=rR,Q") 1374: (not:QI (match_operand:QI 1 "general_operand" "0,0")))] 1375: "" 1376: "comb %0" 1377: [(set_attr "length" "1,2")]) 1378: 1379: ;;- arithmetic shift instructions 1380: (define_insn "ashlsi3" 1381: [(set (match_operand:SI 0 "register_operand" "=r,r") 1382: (ashift:SI (match_operand:SI 1 "register_operand" "0,0") 1383: (match_operand:HI 2 "general_operand" "rR,Qi")))] 1384: "TARGET_45" 1385: "ashc %2,%0" 1386: [(set_attr "length" "1,2")]) 1387: 1388: ;; Arithmetic right shift on the pdp works by negating the shift count. 1389: (define_expand "ashrsi3" 1390: [(set (match_operand:SI 0 "register_operand" "=r") 1391: (ashift:SI (match_operand:SI 1 "register_operand" "0") 1392: (match_operand:HI 2 "general_operand" "g")))] 1393: "" 1394: " 1395: { 1396: operands[2] = negate_rtx (HImode, operands[2]); 1397: }") 1398: 1399: ;; define asl aslb asr asrb - ashc missing! 1400: 1401: ;; asl 1402: (define_insn "" 1403: [(set (match_operand:HI 0 "general_operand" "=rR,Q") 1404: (ashift:HI (match_operand:HI 1 "general_operand" "0,0") 1405: (const_int 1)))] 1406: "" 1407: "asl %0" 1408: [(set_attr "length" "1,2")]) 1409: 1410: ;; and another possibility for asr is << -1 1411: ;; might cause problems since -1 can also be encoded as 65535! 1412: ;; not in gcc2 ??? 1413: 1414: ;; asr 1415: (define_insn "" 1416: [(set (match_operand:HI 0 "general_operand" "=rR,Q") 1417: (ashift:HI (match_operand:HI 1 "general_operand" "0,0") 1418: (const_int -1)))] 1419: "" 1420: "asr %0" 1421: [(set_attr "length" "1,2")]) 1422: 1423: ;; shift is by arbitrary count is expensive, 1424: ;; shift by one cheap - so let's do that, if 1425: ;; space doesn't matter 1426: (define_insn "" 1427: [(set (match_operand:HI 0 "general_operand" "=r") 1428: (ashift:HI (match_operand:HI 1 "general_operand" "0") 1429: (match_operand:HI 2 "expand_shift_operand" "O")))] 1430: "TARGET_TIME" 1431: "* 1432: { 1433: register int i; 1434: 1435: for (i = 1; i <= abs(INTVAL(operands[2])); i++) 1436: if (INTVAL(operands[2]) < 0) 1437: output_asm_insn(\"asr %0\", operands); 1438: else 1439: output_asm_insn(\"asl %0\", operands); 1440: 1441: return \"\"; 1442: }" 1443: ;; longest is 4 1444: [(set (attr "length") (const_int 4))]) 1445: 1446: ;; aslb 1447: (define_insn "" 1448: [(set (match_operand:QI 0 "general_operand" "=r,o") 1449: (ashift:QI (match_operand:QI 1 "general_operand" "0,0") 1450: (match_operand:HI 2 "const_immediate_operand" "n,n")))] 1451: "" 1452: "* 1453: { /* allowing predec or post_inc is possible, but hairy! */ 1454: int i, cnt; 1455: 1456: cnt = INTVAL(operands[2]) & 0x0007; 1457: 1458: for (i=0 ; i < cnt ; i++) 1459: output_asm_insn(\"aslb %0\", operands); 1460: 1461: return \"\"; 1462: }" 1463: ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!! 1464: [(set_attr_alternative "length" 1465: [(const_int 7) 1466: (const_int 14)])]) 1467: 1468: ;;; asr 1469: ;(define_insn "" 1470: ; [(set (match_operand:HI 0 "general_operand" "=rR,Q") 1471: ; (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0") 1472: ; (const_int 1)))] 1473: ; "" 1474: ; "asr %0" 1475: ; [(set_attr "length" "1,2")]) 1476: 1477: ;; asrb 1478: (define_insn "" 1479: [(set (match_operand:QI 0 "general_operand" "=r,o") 1480: (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") 1481: (match_operand:HI 2 "const_immediate_operand" "n,n")))] 1482: "" 1483: "* 1484: { /* allowing predec or post_inc is possible, but hairy! */ 1485: int i, cnt; 1486: 1487: cnt = INTVAL(operands[2]) & 0x0007; 1488: 1489: for (i=0 ; i < cnt ; i++) 1490: output_asm_insn(\"asrb %0\", operands); 1491: 1492: return \"\"; 1493: }" 1494: [(set_attr_alternative "length" 1495: [(const_int 7) 1496: (const_int 14)])]) 1497: 1.1.1.2 ! root 1498: ;; the following is invalid - too complex!!! - just say 14 !!! 1.1 root 1499: ; [(set (attr "length") (plus (and (match_dup 2) 1500: ; (const_int 7)) 1501: ; (and (match_dup 2) 1502: ; (const_int 7))))]) 1503: 1504: 1505: 1506: ;; can we get +-1 in the next pattern? should 1507: ;; have been caught by previous patterns! 1508: 1509: (define_insn "ashlhi3" 1510: [(set (match_operand:HI 0 "register_operand" "=r,r") 1511: (ashift:HI (match_operand:HI 1 "register_operand" "0,0") 1512: (match_operand:HI 2 "general_operand" "rR,Qi")))] 1513: "" 1514: "* 1515: { 1516: if (GET_CODE(operands[2]) == CONST_INT) 1517: if (INTVAL(operands[2]) == 1) 1518: return \"asl %0\"; 1519: else if (INTVAL(operands[2]) == -1) 1520: return \"asr %0\"; 1521: 1522: return \"ash %2,%0\"; 1523: }" 1524: [(set_attr "length" "1,2")]) 1525: 1526: ;; Arithmetic right shift on the pdp works by negating the shift count. 1527: (define_expand "ashrhi3" 1528: [(set (match_operand:HI 0 "register_operand" "=r") 1529: (ashift:HI (match_operand:HI 1 "register_operand" "0") 1530: (match_operand:HI 2 "general_operand" "g")))] 1531: "" 1532: " 1533: { 1534: operands[2] = negate_rtx (HImode, operands[2]); 1535: }") 1536: 1537: ;;;;- logical shift instructions 1538: ;;(define_insn "lshrsi3" 1539: ;; [(set (match_operand:HI 0 "register_operand" "=r") 1540: ;; (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") 1541: ;; (match_operand:HI 2 "arith_operand" "rI")))] 1542: ;; "" 1543: ;; "srl %0,%2") 1544: 1545: ;; absolute 1546: 1547: (define_insn "absdf2" 1548: [(set (match_operand:DF 0 "general_operand" "=fR,Q") 1549: (abs:DF (match_operand:DF 1 "general_operand" "0,0")))] 1550: "TARGET_FPU" 1551: "absd %0" 1552: [(set_attr "length" "1,2")]) 1553: 1554: (define_insn "abshi2" 1555: [(set (match_operand:HI 0 "general_operand" "=r,o") 1556: (abs:HI (match_operand:HI 1 "general_operand" "0,0")))] 1557: "TARGET_ABSHI_BUILTIN" 1558: "* 1559: { 1560: static count = 0; 1561: char buf[200]; 1562: 1563: output_asm_insn(\"tst %0\", operands); 1564: sprintf(buf, \"bge abshi%d\", count); 1565: output_asm_insn(buf, NULL); 1566: output_asm_insn(\"neg %0\", operands); 1567: sprintf(buf, \"\\nabshi%d:\", count++); 1568: output_asm_insn(buf, NULL); 1569: 1570: return \"\"; 1571: }" 1572: [(set_attr "length" "3,5")]) 1573: 1574: 1575: ;; define expand abshi - is much better !!! - but 1576: ;; will it be optimized into an abshi2 ? 1577: ;; it will leave better code, because the tsthi might be 1578: ;; optimized away!! 1579: ; -- just a thought - don't have time to check 1580: ; 1581: ;(define_expand "abshi2" 1582: ; [(match_operand:HI 0 "general_operand" "") 1583: ; (match_operand:HI 1 "general_operand" "")] 1584: ; "" 1585: ; " 1586: ;{ 1587: ; rtx label = gen_label_rtx (); 1588: ; 1589: ; /* do I need this? */ 1590: ; do_pending_stack_adjust (); 1591: ; 1592: ; emit_move_insn (operands[0], operands[1]); 1593: ; 1594: ; emit_insn (gen_tsthi (operands[0])); 1595: ; emit_insn (gen_bge (label1)); 1596: ; 1597: ; emit_insn (gen_neghi(operands[0], operands[0]) 1598: ; 1599: ; emit_barrier (); 1600: ; 1601: ; emit_label (label); 1602: ; 1603: ; /* allow REG_NOTES to be set on last insn (labels don't have enough 1604: ; fields, and can't be used for REG_NOTES anyway). */ 1605: ; emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); 1606: ; DONE; 1607: ;}") 1608: 1609: ;; negate insns 1610: 1611: (define_insn "negdf2" 1612: [(set (match_operand:DF 0 "general_operand" "=fR,Q") 1613: (neg:DF (match_operand:DF 1 "register_operand" "0,0")))] 1614: "TARGET_FPU" 1615: "negd %0" 1616: [(set_attr "length" "1,2")]) 1617: 1618: (define_insn "neghi2" 1619: [(set (match_operand:HI 0 "general_operand" "=rR,Q") 1620: (neg:HI (match_operand:HI 1 "general_operand" "0,0")))] 1621: "" 1622: "neg %0" 1623: [(set_attr "length" "1,2")]) 1624: 1625: (define_insn "negqi2" 1626: [(set (match_operand:QI 0 "general_operand" "=rR,Q") 1627: (neg:QI (match_operand:QI 1 "general_operand" "0,0")))] 1628: "" 1629: "negb %0" 1630: [(set_attr "length" "1,2")]) 1631: 1632: 1633: ;; Unconditional and other jump instructions 1634: (define_insn "jump" 1635: [(set (pc) 1636: (label_ref (match_operand 0 "" "")))] 1637: "" 1638: "jmp %l0" 1639: [(set_attr "length" "2")]) 1640: 1641: (define_insn "" 1642: [(set (pc) 1643: (label_ref (match_operand 0 "" ""))) 1644: (clobber (const_int 1))] 1645: "" 1646: "jmp %l0" 1647: [(set_attr "length" "2")]) 1648: 1649: (define_insn "tablejump" 1650: [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q")) 1651: (use (label_ref (match_operand 1 "" "")))] 1652: "" 1653: "jmp %0" 1654: [(set_attr "length" "1,2")]) 1655: 1656: ;; indirect jump - let's be conservative! 1657: ;; allow only register_operand, even though we could also 1658: ;; allow labels etc. 1659: 1660: (define_insn "indirect_jump" 1661: [(set (pc) (match_operand:HI 0 "register_operand" "r"))] 1662: "" 1663: "jmp (%0)") 1664: 1665: ;;- jump to subroutine 1666: 1667: (define_insn "call" 1668: [(call (match_operand:HI 0 "general_operand" "R,Q") 1669: (match_operand:HI 1 "general_operand" "g,g")) 1670: ;; (use (reg:HI 0)) what was that ??? 1671: ] 1672: ;;- Don't use operand 1 for most machines. 1673: "" 1674: "jsr pc, %0" 1675: [(set_attr "length" "1,2")]) 1676: 1677: ;;- jump to subroutine 1678: (define_insn "call_value" 1679: [(set (match_operand 0 "" "") 1680: (call (match_operand:HI 1 "general_operand" "R,Q") 1681: (match_operand:HI 2 "general_operand" "g,g"))) 1682: ;; (use (reg:HI 0)) - what was that ???? 1683: ] 1684: ;;- Don't use operand 2 for most machines. 1685: "" 1686: "jsr pc, %1" 1687: [(set_attr "length" "1,2")]) 1688: 1689: ;;- nop instruction 1690: (define_insn "nop" 1691: [(const_int 0)] 1692: "" 1693: "nop") 1694: 1695: 1696: ;;- multiply 1697: 1698: (define_insn "muldf3" 1699: [(set (match_operand:DF 0 "register_operand" "=a,a,a") 1700: (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0") 1701: (match_operand:DF 2 "general_operand" "fR,Q,F")))] 1702: "TARGET_FPU" 1703: "muld %2, %0" 1704: [(set_attr "length" "1,2,5")]) 1705: 1706: ;; 16 bit result multiply: 1707: ;; currently we multiply only into odd registers, so we don't use two 1708: ;; registers - but this is a bit inefficient at times. If we define 1709: ;; a register class for each register, then we can specify properly 1710: ;; which register need which scratch register .... 1711: 1712: (define_insn "mulhi3" 1713: [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs 1714: (mult:HI (match_operand:HI 1 "register_operand" "%0,0") 1715: (match_operand:HI 2 "general_operand" "rR,Qi")))] 1716: "TARGET_45" 1717: "mul %2, %0" 1718: [(set_attr "length" "1,2")]) 1719: 1720: ;; 32 bit result 1.1.1.2 ! root 1721: (define_expand "mulhisi3" ! 1722: [(set (match_dup 3) ! 1723: (match_operand:HI 1 "general_operand" "g,g")) ! 1724: (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! ! 1725: (mult:SI (truncate:HI ! 1726: (match_dup 0)) ! 1727: (match_operand:HI 2 "general_operand" "rR,Qi")))] ! 1728: "TARGET_45" ! 1729: "operands[3] = gen_lowpart(HImode, operands[1]);") ! 1730: ! 1731: (define_insn "" 1.1 root 1732: [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! 1.1.1.2 ! root 1733: (mult:SI (truncate:HI ! 1734: (match_operand:SI 1 "register_operand" "%0,0")) 1.1 root 1735: (match_operand:HI 2 "general_operand" "rR,Qi")))] 1736: "TARGET_45" 1737: "mul %2, %0" 1738: [(set_attr "length" "1,2")]) 1739: 1.1.1.2 ! root 1740: ;(define_insn "mulhisi3" ! 1741: ; [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! ! 1742: ; (mult:SI (truncate:HI ! 1743: ; (match_operand:SI 1 "register_operand" "%0,0")) ! 1744: ; (match_operand:HI 2 "general_operand" "rR,Qi")))] ! 1745: ; "TARGET_45" ! 1746: ; "mul %2, %0" ! 1747: ; [(set_attr "length" "1,2")]) 1.1 root 1748: 1.1.1.2 ! root 1749: ;;- divide 1.1 root 1750: (define_insn "divdf3" 1751: [(set (match_operand:DF 0 "register_operand" "=a,a,a") 1752: (div:DF (match_operand:DF 1 "register_operand" "0,0,0") 1753: (match_operand:DF 2 "general_operand" "fR,Q,F")))] 1754: "TARGET_FPU" 1755: "divd %2, %0" 1756: [(set_attr "length" "1,2,5")]) 1757: 1.1.1.2 ! root 1758: 1.1 root 1759: (define_expand "divhi3" 1.1.1.2 ! root 1760: [(set (subreg:HI (match_dup 1) 0) ! 1761: (div:HI (match_operand:SI 1 "general_operand" "0") ! 1762: (match_operand:HI 2 "general_operand" "g"))) ! 1763: (set (match_operand:HI 0 "general_operand" "=r") ! 1764: (subreg:HI (match_dup 1) 0))] 1.1 root 1765: "TARGET_45" 1.1.1.2 ! root 1766: "") 1.1 root 1767: 1768: (define_insn "" 1.1.1.2 ! root 1769: [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) ! 1770: (div:HI (match_operand:SI 1 "general_operand" "0") ! 1771: (match_operand:HI 2 "general_operand" "g")))] 1.1 root 1772: "TARGET_45" 1773: "div %2,%0" 1774: [(set_attr "length" "2")]) 1775: 1776: (define_expand "modhi3" 1.1.1.2 ! root 1777: [(set (subreg:HI (match_dup 1) 1) ! 1778: (mod:HI (match_operand:SI 1 "general_operand" "0") ! 1779: (match_operand:HI 2 "general_operand" "g"))) ! 1780: (set (match_operand:HI 0 "general_operand" "=r") ! 1781: (subreg:HI (match_dup 1) 1))] 1.1 root 1782: "TARGET_45" 1.1.1.2 ! root 1783: "") 1.1 root 1784: 1785: (define_insn "" 1.1.1.2 ! root 1786: [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1) ! 1787: (mod:HI (match_operand:SI 1 "general_operand" "0") ! 1788: (match_operand:HI 2 "general_operand" "g")))] 1.1 root 1789: "TARGET_45" 1.1.1.2 ! root 1790: "div %2,%0" 1.1 root 1791: [(set_attr "length" "2")]) 1792: 1.1.1.2 ! root 1793: ;(define_expand "divmodhi4" ! 1794: ; [(parallel [(set (subreg:HI (match_dup 1) 0) ! 1795: ; (div:HI (match_operand:SI 1 "general_operand" "0") ! 1796: ; (match_operand:HI 2 "general_operand" "g"))) ! 1797: ; (set (subreg:HI (match_dup 1) 1) ! 1798: ; (mod:HI (match_dup 1) ! 1799: ; (match_dup 2)))]) ! 1800: ; (set (match_operand:HI 3 "general_operand" "=r") ! 1801: ; (subreg:HI (match_dup 1) 1)) ! 1802: ; (set (match_operand:HI 0 "general_operand" "=r") ! 1803: ; (subreg:HI (match_dup 1) 0))] ! 1804: ; "TARGET_45" ! 1805: ; "") ! 1806: ; ! 1807: ;(define_insn "" ! 1808: ; [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) ! 1809: ; (div:HI (match_operand:SI 1 "general_operand" "0") ! 1810: ; (match_operand:HI 2 "general_operand" "g"))) ! 1811: ; (set (subreg:HI (match_dup 0) 1) ! 1812: ; (mod:HI (match_dup 1) ! 1813: ; (match_dup 2)))] ! 1814: ; "TARGET_45" ! 1815: ; "div %2, %0") ! 1816: ; 1.1 root 1817: 1818: ;; 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.