|
|
1.1 ! root 1: ;;- Machine description for SPUR chip for GNU C compiler ! 2: ;; Copyright (C) 1988 Free Software Foundation, Inc. ! 3: ! 4: ;; This file is part of GNU CC. ! 5: ! 6: ;; GNU CC is distributed in the hope that it will be useful, ! 7: ;; but WITHOUT ANY WARRANTY. No author or distributor ! 8: ;; accepts responsibility to anyone for the consequences of using it ! 9: ;; or for whether it serves any particular purpose or works at all, ! 10: ;; unless he says so in writing. Refer to the GNU CC General Public ! 11: ;; License for full details. ! 12: ! 13: ;; Everyone is granted permission to copy, modify and redistribute ! 14: ;; GNU CC, but only under the conditions described in the ! 15: ;; GNU CC General Public License. A copy of this license is ! 16: ;; supposed to have been given to you along with GNU CC so you ! 17: ;; can know your rights and responsibilities. It should be in a ! 18: ;; file named COPYING. Among other things, the copyright notice ! 19: ;; and this notice must be preserved on all copies. ! 20: ! 21: ! 22: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 23: ! 24: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ! 25: ;;- updates for most instructions. ! 26: ! 27: ;;- Operand classes for the register allocator: ! 28: ! 29: ;; Compare instructions. ! 30: ;; This pattern is used for generating an "insn" ! 31: ;; which does just a compare and sets a (fictitious) condition code. ! 32: ! 33: ;; The actual SPUR insns are compare-and-conditional-jump. ! 34: ;; The define_peephole's below recognize the combinations of ! 35: ;; compares and jumps, and output each pair as a single assembler insn. ! 36: ! 37: ;; This controls RTL generation and register allocation. ! 38: (define_insn "cmpsi" ! 39: [(set (cc0) ! 40: (minus (match_operand:SI 0 "nonmemory_operand" "rK") ! 41: (match_operand:SI 1 "nonmemory_operand" "rK")))] ! 42: "" ! 43: "* ! 44: { ! 45: cc_status.value1 = operands[0], cc_status.value2 = operands[1]; ! 46: return \"\"; ! 47: }") ! 48: ! 49: ;; We have to have this because cse can optimize the previous pattern ! 50: ;; into this one. ! 51: ! 52: (define_insn "tstsi" ! 53: [(set (cc0) ! 54: (match_operand:SI 0 "register_operand" "r"))] ! 55: "" ! 56: "* ! 57: { ! 58: cc_status.value1 = operands[0], cc_status.value2 = const0_rtx; ! 59: return \"\"; ! 60: }") ! 61: ! 62: ! 63: ;; These control RTL generation for conditional jump insns ! 64: ;; and match them for register allocation. ! 65: ! 66: (define_insn "beq" ! 67: [(set (pc) ! 68: (if_then_else (eq (cc0) ! 69: (const_int 0)) ! 70: (label_ref (match_operand 0 "" "")) ! 71: (pc)))] ! 72: "" ! 73: "* return output_compare (operands, \"eq\", \"eq\"); ") ! 74: ! 75: (define_insn "bne" ! 76: [(set (pc) ! 77: (if_then_else (ne (cc0) ! 78: (const_int 0)) ! 79: (label_ref (match_operand 0 "" "")) ! 80: (pc)))] ! 81: "" ! 82: "* return output_compare (operands, \"ne\", \"ne\"); ") ! 83: ! 84: (define_insn "bgt" ! 85: [(set (pc) ! 86: (if_then_else (gt (cc0) ! 87: (const_int 0)) ! 88: (label_ref (match_operand 0 "" "")) ! 89: (pc)))] ! 90: "" ! 91: "* return output_compare (operands, \"gt\", \"lt\"); ") ! 92: ! 93: (define_insn "bgtu" ! 94: [(set (pc) ! 95: (if_then_else (gtu (cc0) ! 96: (const_int 0)) ! 97: (label_ref (match_operand 0 "" "")) ! 98: (pc)))] ! 99: "" ! 100: "* return output_compare (operands, \"ugt\", \"ult\"); ") ! 101: ! 102: (define_insn "blt" ! 103: [(set (pc) ! 104: (if_then_else (lt (cc0) ! 105: (const_int 0)) ! 106: (label_ref (match_operand 0 "" "")) ! 107: (pc)))] ! 108: "" ! 109: "* return output_compare (operands, \"lt\", \"gt\"); ") ! 110: ! 111: (define_insn "bltu" ! 112: [(set (pc) ! 113: (if_then_else (ltu (cc0) ! 114: (const_int 0)) ! 115: (label_ref (match_operand 0 "" "")) ! 116: (pc)))] ! 117: "" ! 118: "* return output_compare (operands, \"ult\", \"ugt\"); ") ! 119: ! 120: (define_insn "bge" ! 121: [(set (pc) ! 122: (if_then_else (ge (cc0) ! 123: (const_int 0)) ! 124: (label_ref (match_operand 0 "" "")) ! 125: (pc)))] ! 126: "" ! 127: "* return output_compare (operands, \"ge\", \"le\"); ") ! 128: ! 129: (define_insn "bgeu" ! 130: [(set (pc) ! 131: (if_then_else (geu (cc0) ! 132: (const_int 0)) ! 133: (label_ref (match_operand 0 "" "")) ! 134: (pc)))] ! 135: "" ! 136: "* return output_compare (operands, \"uge\", \"ule\"); ") ! 137: ! 138: (define_insn "ble" ! 139: [(set (pc) ! 140: (if_then_else (le (cc0) ! 141: (const_int 0)) ! 142: (label_ref (match_operand 0 "" "")) ! 143: (pc)))] ! 144: "" ! 145: "* return output_compare (operands, \"le\", \"ge\"); ") ! 146: ! 147: (define_insn "bleu" ! 148: [(set (pc) ! 149: (if_then_else (leu (cc0) ! 150: (const_int 0)) ! 151: (label_ref (match_operand 0 "" "")) ! 152: (pc)))] ! 153: "" ! 154: "* return output_compare (operands, \"ule\", \"uge\"); ") ! 155: ! 156: ;; These match inverted jump insns for register allocation. ! 157: ! 158: (define_insn "" ! 159: [(set (pc) ! 160: (if_then_else (eq (cc0) ! 161: (const_int 0)) ! 162: (pc) ! 163: (label_ref (match_operand 0 "" ""))))] ! 164: "" ! 165: "* return output_compare (operands, \"ne\", \"ne\"); ") ! 166: ! 167: (define_insn "" ! 168: [(set (pc) ! 169: (if_then_else (ne (cc0) ! 170: (const_int 0)) ! 171: (pc) ! 172: (label_ref (match_operand 0 "" ""))))] ! 173: "" ! 174: "* return output_compare (operands, \"eq\", \"eq\"); ") ! 175: ! 176: (define_insn "" ! 177: [(set (pc) ! 178: (if_then_else (gt (cc0) ! 179: (const_int 0)) ! 180: (pc) ! 181: (label_ref (match_operand 0 "" ""))))] ! 182: "" ! 183: "* return output_compare (operands, \"le\", \"ge\"); ") ! 184: ! 185: (define_insn "" ! 186: [(set (pc) ! 187: (if_then_else (gtu (cc0) ! 188: (const_int 0)) ! 189: (pc) ! 190: (label_ref (match_operand 0 "" ""))))] ! 191: "" ! 192: "* return output_compare (operands, \"ule\", \"uge\"); ") ! 193: ! 194: (define_insn "" ! 195: [(set (pc) ! 196: (if_then_else (lt (cc0) ! 197: (const_int 0)) ! 198: (pc) ! 199: (label_ref (match_operand 0 "" ""))))] ! 200: "" ! 201: "* return output_compare (operands, \"ge\", \"le\"); ") ! 202: ! 203: (define_insn "" ! 204: [(set (pc) ! 205: (if_then_else (ltu (cc0) ! 206: (const_int 0)) ! 207: (pc) ! 208: (label_ref (match_operand 0 "" ""))))] ! 209: "" ! 210: "* return output_compare (operands, \"uge\", \"ule\"); ") ! 211: ! 212: (define_insn "" ! 213: [(set (pc) ! 214: (if_then_else (ge (cc0) ! 215: (const_int 0)) ! 216: (pc) ! 217: (label_ref (match_operand 0 "" ""))))] ! 218: "" ! 219: "* return output_compare (operands, \"lt\", \"gt\"); ") ! 220: ! 221: (define_insn "" ! 222: [(set (pc) ! 223: (if_then_else (geu (cc0) ! 224: (const_int 0)) ! 225: (pc) ! 226: (label_ref (match_operand 0 "" ""))))] ! 227: "" ! 228: "* return output_compare (operands, \"ult\", \"ugt\"); ") ! 229: ! 230: (define_insn "" ! 231: [(set (pc) ! 232: (if_then_else (le (cc0) ! 233: (const_int 0)) ! 234: (pc) ! 235: (label_ref (match_operand 0 "" ""))))] ! 236: "" ! 237: "* return output_compare (operands, \"gt\", \"lt\"); ") ! 238: ! 239: (define_insn "" ! 240: [(set (pc) ! 241: (if_then_else (leu (cc0) ! 242: (const_int 0)) ! 243: (pc) ! 244: (label_ref (match_operand 0 "" ""))))] ! 245: "" ! 246: "* return output_compare (operands, \"ugt\", \"ult\"); ") ! 247: ! 248: ;; Move instructions ! 249: ! 250: (define_insn "movsi" ! 251: [(set (match_operand:SI 0 "general_operand" "=r,m") ! 252: (match_operand:SI 1 "general_operand" "rmi,rJ"))] ! 253: "" ! 254: "* ! 255: { ! 256: if (GET_CODE (operands[0]) == MEM) ! 257: return \"st_32 %r1,%0\"; ! 258: if (GET_CODE (operands[1]) == MEM) ! 259: return \"ld_32 %0,%1\;nop\"; ! 260: if (GET_CODE (operands[1]) == REG) ! 261: return \"add_nt %0,%1,$0\"; ! 262: if (GET_CODE (operands[1]) == SYMBOL_REF && operands[1]->unchanging) ! 263: return \"add_nt %0,r24,$(%1-0b)\"; ! 264: return \"add_nt %0,r0,%1\"; ! 265: }") ! 266: ! 267: (define_insn "" ! 268: [(set (match_operand:SI 0 "register_operand" "=r") ! 269: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") ! 270: (match_operand:SI 2 "register_operand" "r"))))] ! 271: "" ! 272: "ld_32 %0,%1,%2\;nop") ! 273: ! 274: ;; Generate insns for moving single bytes. ! 275: ! 276: (define_expand "movqi" ! 277: [(set (match_operand:QI 0 "general_operand" "") ! 278: (match_operand:QI 1 "general_operand" ""))] ! 279: "" ! 280: " ! 281: { ! 282: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) ! 283: operands[1] = copy_to_reg (operands[1]); ! 284: ! 285: if (GET_CODE (operands[1]) == MEM) ! 286: { ! 287: rtx tem = gen_reg_rtx (SImode); ! 288: rtx addr = force_reg (SImode, XEXP (operands[1], 0)); ! 289: emit_move_insn (tem, gen_rtx (MEM, SImode, addr)); ! 290: emit_insn (gen_rtx (SET, VOIDmode, ! 291: gen_rtx (SUBREG, SImode, operands[0], 0), ! 292: gen_rtx (ZERO_EXTRACT, SImode, tem, ! 293: gen_rtx (CONST_INT, VOIDmode, 8), ! 294: addr))); ! 295: } ! 296: else if (GET_CODE (operands[0]) == MEM) ! 297: { ! 298: rtx tem = gen_reg_rtx (SImode); ! 299: rtx addr = force_reg (SImode, XEXP (operands[0], 0)); ! 300: emit_move_insn (tem, gen_rtx (MEM, SImode, addr)); ! 301: if (! CONSTANT_ADDRESS_P (operands[1])) ! 302: operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0); ! 303: emit_insn (gen_rtx (SET, VOIDmode, ! 304: gen_rtx (ZERO_EXTRACT, SImode, tem, ! 305: gen_rtx (CONST_INT, VOIDmode, 8), ! 306: addr), ! 307: operands[1])); ! 308: emit_move_insn (gen_rtx (MEM, SImode, addr), tem); ! 309: } ! 310: else ! 311: { ! 312: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); ! 313: } ! 314: DONE; ! 315: }") ! 316: ! 317: ;; Recognize insns generated for moving single bytes. ! 318: ! 319: (define_insn "" ! 320: [(set (match_operand:QI 0 "general_operand" "=r,m") ! 321: (match_operand:QI 1 "general_operand" "rmi,r"))] ! 322: "" ! 323: "* ! 324: { ! 325: if (GET_CODE (operands[0]) == MEM) ! 326: return \"st_32 %1,%0\"; ! 327: if (GET_CODE (operands[1]) == MEM) ! 328: return \"ld_32 %0,%1\;nop\"; ! 329: if (GET_CODE (operands[1]) == REG) ! 330: return \"add_nt %0,%1,$0\"; ! 331: return \"add_nt %0,r0,%1\"; ! 332: }") ! 333: ! 334: (define_insn "" ! 335: [(set (match_operand:SI 0 "register_operand" "=r") ! 336: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") ! 337: (const_int 8) ! 338: (match_operand:SI 2 "nonmemory_operand" "rI")))] ! 339: "" ! 340: "extract %0,%1,%2") ! 341: ! 342: (define_insn "" ! 343: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") ! 344: (const_int 8) ! 345: (match_operand:SI 1 "nonmemory_operand" "rI")) ! 346: (match_operand:SI 2 "nonmemory_operand" "ri"))] ! 347: "" ! 348: "wr_insert %1\;insert %0,%0,%2") ! 349: ! 350: ;; Constant propagation can optimize the previous pattern into this pattern. ! 351: ;[Not any more. It could when the position-operand contains a MULT.] ! 352: ! 353: ;(define_insn "" ! 354: ; [(set (zero_extract:QI (match_operand:SI 0 "register_operand" "+r") ! 355: ; (const_int 8) ! 356: ; (match_operand:SI 1 "immediate_operand" "I")) ! 357: ; (match_operand:QI 2 "register_operand" "r"))] ! 358: ; "GET_CODE (operands[1]) == CONST_INT ! 359: ; && INTVAL (operands[1]) % 8 == 0 ! 360: ; && (unsigned) INTVAL (operands[1]) < 32" ! 361: ; "* ! 362: ;{ ! 363: ; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8); ! 364: ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\"; ! 365: ;}") ! 366: ! 367: ;; The three define_expand patterns on this page ! 368: ;; serve as subroutines of "movhi". ! 369: ! 370: ;; Generate code to fetch an aligned halfword from memory. ! 371: ;; Operand 0 is the destination register (HImode). ! 372: ;; Operand 1 is the memory address (SImode). ! 373: ;; Operand 2 is a temporary (SImode). ! 374: ;; Operand 3 is a temporary (SImode). ! 375: ;; Operand 4 is a temporary (QImode). ! 376: ! 377: (define_expand "loadhi" ! 378: [(set (match_operand:SI 2 "register_operand" "") ! 379: (mem:SI (match_operand:SI 1 "register_operand" ""))) ! 380: ;; Extract the low byte. ! 381: (set (subreg:SI (match_dup 5) 0) ! 382: (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 1))) ! 383: ;; Form address of high byte. ! 384: (set (match_operand:SI 3 "register_operand" "") ! 385: (plus:SI (match_dup 1) (const_int 1))) ! 386: ;; Extract the high byte. ! 387: (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0) ! 388: (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))) ! 389: ;; Put the high byte in with the low one. ! 390: (set (zero_extract:SI (match_dup 5) (const_int 8) (const_int 1)) ! 391: (subreg:SI (match_dup 4) 0)) ! 392: (set (match_operand:HI 0 "register_operand" "") (match_dup 5))] ! 393: "" ! 394: "operands[5] = gen_reg_rtx (HImode);") ! 395: ! 396: ;; Generate code to store an aligned halfword into memory. ! 397: ;; Operand 0 is the destination address (SImode). ! 398: ;; Operand 1 is the source register (HImode, not constant). ! 399: ;; Operand 2 is a temporary (SImode). ! 400: ;; Operand 3 is a temporary (SImode). ! 401: ;; Operand 4 is a temporary (QImode). ! 402: ! 403: (define_expand "storehi" ! 404: [(set (match_operand:SI 2 "register_operand" "") ! 405: (mem:SI (match_operand:SI 0 "register_operand" ""))) ! 406: ;; Insert the low byte. ! 407: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0)) ! 408: (subreg:SI (match_operand:HI 1 "register_operand" "") 0)) ! 409: ;; Form address of high byte. ! 410: (set (match_operand:SI 3 "register_operand" "") ! 411: (plus:SI (match_dup 0) (const_int 1))) ! 412: ;; Extract the high byte from the source. ! 413: (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0) ! 414: (zero_extract:SI (match_dup 1) (const_int 8) (const_int 1))) ! 415: ;; Store high byte into the memory word ! 416: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3)) ! 417: (subreg:SI (match_dup 4) 0)) ! 418: ;; Put memory word back into memory. ! 419: (set (mem:SI (match_dup 0)) ! 420: (match_dup 2))] ! 421: "" ! 422: "") ! 423: ! 424: ;; Like storehi but operands[1] is a CONST_INT. ! 425: ! 426: (define_expand "storeinthi" ! 427: [(set (match_operand:SI 2 "register_operand" "") ! 428: (mem:SI (match_operand:SI 0 "register_operand" ""))) ! 429: ;; Insert the low byte. ! 430: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0)) ! 431: (match_dup 5)) ! 432: ;; Form address of high byte. ! 433: (set (match_operand:SI 3 "register_operand" "") ! 434: (plus:SI (match_dup 0) (const_int 1))) ! 435: ;; Store high byte into the memory word ! 436: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3)) ! 437: (match_dup 6)) ! 438: ;; Put memory word back into memory. ! 439: (set (mem:SI (match_dup 0)) ! 440: (match_dup 2))] ! 441: "" ! 442: " operands[5] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 255); ! 443: operands[6] = gen_rtx (CONST_INT, VOIDmode, ! 444: (INTVAL (operands[1]) >> 8) & 255); ! 445: ") ! 446: ! 447: ;; Main entry for generating insns to move halfwords. ! 448: ! 449: (define_expand "movhi" ! 450: [(set (match_operand:HI 0 "general_operand" "") ! 451: (match_operand:HI 1 "general_operand" ""))] ! 452: "" ! 453: " ! 454: { ! 455: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) ! 456: operands[1] = copy_to_reg (operands[1]); ! 457: ! 458: if (GET_CODE (operands[1]) == MEM) ! 459: { ! 460: rtx insn = ! 461: emit_insn (gen_loadhi (operands[0], ! 462: force_reg (SImode, XEXP (operands[1], 0)), ! 463: gen_reg_rtx (SImode), gen_reg_rtx (SImode), ! 464: gen_reg_rtx (QImode))); ! 465: /* Tell cse what value the loadhi produces, so it detect duplicates. */ ! 466: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1], 0); ! 467: } ! 468: else if (GET_CODE (operands[0]) == MEM) ! 469: { ! 470: if (GET_CODE (operands[1]) == CONST_INT) ! 471: emit_insn (gen_storeinthi (force_reg (SImode, XEXP (operands[0], 0)), ! 472: operands[1], ! 473: gen_reg_rtx (SImode), gen_reg_rtx (SImode), ! 474: gen_reg_rtx (QImode))); ! 475: else ! 476: { ! 477: if (CONSTANT_P (operands[1])) ! 478: operands[1] = force_reg (HImode, operands[1]); ! 479: emit_insn (gen_storehi (force_reg (SImode, XEXP (operands[0], 0)), ! 480: operands[1], ! 481: gen_reg_rtx (SImode), gen_reg_rtx (SImode), ! 482: gen_reg_rtx (QImode))); ! 483: } ! 484: } ! 485: else ! 486: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); ! 487: DONE; ! 488: }") ! 489: ! 490: ;; Recognize insns generated for moving halfwords. ! 491: ;; (Note that the extract and insert patterns for single-byte moves ! 492: ;; are also involved in recognizing some of the insns used for this purpose.) ! 493: ! 494: (define_insn "" ! 495: [(set (match_operand:HI 0 "general_operand" "=r,m") ! 496: (match_operand:HI 1 "general_operand" "rmi,r"))] ! 497: "" ! 498: "* ! 499: { ! 500: if (GET_CODE (operands[0]) == MEM) ! 501: return \"st_32 %1,%0\"; ! 502: if (GET_CODE (operands[1]) == MEM) ! 503: return \"ld_32 %0,%1\;nop\"; ! 504: if (GET_CODE (operands[1]) == REG) ! 505: return \"add_nt %0,%1,$0\"; ! 506: return \"add_nt %0,r0,%1\"; ! 507: }") ! 508: ! 509: (define_insn "" ! 510: [(set (match_operand:SI 0 "register_operand" "=r") ! 511: (zero_extract:SI (match_operand:HI 1 "register_operand" "r") ! 512: (const_int 8) ! 513: (match_operand:SI 2 "nonmemory_operand" "rI")))] ! 514: "" ! 515: "extract %0,%1,%2") ! 516: ! 517: (define_insn "" ! 518: [(set (zero_extract:SI (match_operand:HI 0 "register_operand" "+r") ! 519: (const_int 8) ! 520: (match_operand:SI 1 "nonmemory_operand" "rI")) ! 521: (match_operand:SI 2 "nonmemory_operand" "ri"))] ! 522: "" ! 523: "wr_insert %1\;insert %0,%0,%2") ! 524: ! 525: ;; Constant propagation can optimize the previous pattern into this pattern. ! 526: ! 527: ;(define_insn "" ! 528: ; [(set (zero_extract:QI (match_operand:HI 0 "register_operand" "+r") ! 529: ; (const_int 8) ! 530: ; (match_operand:SI 1 "immediate_operand" "I")) ! 531: ; (match_operand:QI 2 "register_operand" "r"))] ! 532: ; "GET_CODE (operands[1]) == CONST_INT ! 533: ; && INTVAL (operands[1]) % 8 == 0 ! 534: ; && (unsigned) INTVAL (operands[1]) < 32" ! 535: ; "* ! 536: ;{ ! 537: ; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8); ! 538: ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\"; ! 539: ;}") ! 540: ! 541: ;; This pattern forces (set (reg:DF ...) (const_double ...)) ! 542: ;; to be reloaded by putting the constant into memory. ! 543: ;; It must come before the more general movdf pattern. ! 544: (define_insn "" ! 545: [(set (match_operand:DF 0 "general_operand" "=r,f,o") ! 546: (match_operand:DF 1 "" "mG,m,G"))] ! 547: "GET_CODE (operands[1]) == CONST_DOUBLE" ! 548: "* ! 549: { ! 550: if (FP_REG_P (operands[0])) ! 551: return output_fp_move_double (operands); ! 552: if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == REG) ! 553: { ! 554: operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 555: return \"add_nt %0,r0,$0\;add_nt %1,r0,$0\"; ! 556: } ! 557: if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM) ! 558: { ! 559: operands[1] = adj_offsetable_operand (operands[0], 4); ! 560: return \"st_32 r0,%0\;st_32 r0,%1\"; ! 561: } ! 562: return output_move_double (operands); ! 563: } ! 564: ") ! 565: ! 566: (define_insn "movdf" ! 567: [(set (match_operand:DF 0 "general_operand" "=r,m,?f,?rm") ! 568: (match_operand:DF 1 "general_operand" "rm,r,rfm,f"))] ! 569: "" ! 570: "* ! 571: { ! 572: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! 573: return output_fp_move_double (operands); ! 574: return output_move_double (operands); ! 575: } ! 576: ") ! 577: ! 578: (define_insn "movdi" ! 579: [(set (match_operand:DI 0 "general_operand" "=r,m,?f,?rm") ! 580: (match_operand:DI 1 "general_operand" "rm,r,rfm,f"))] ! 581: "" ! 582: "* ! 583: { ! 584: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! 585: return output_fp_move_double (operands); ! 586: return output_move_double (operands); ! 587: } ! 588: ") ! 589: ! 590: (define_insn "movsf" ! 591: [(set (match_operand:SF 0 "general_operand" "=rf,m") ! 592: (match_operand:SF 1 "general_operand" "rfm,rf"))] ! 593: "" ! 594: "* ! 595: { ! 596: if (FP_REG_P (operands[0])) ! 597: { ! 598: if (FP_REG_P (operands[1])) ! 599: return \"fmov %0,%1\"; ! 600: if (GET_CODE (operands[1]) == REG) ! 601: { ! 602: rtx xoperands[2]; ! 603: int offset = - get_frame_size () - 8; ! 604: xoperands[1] = operands[1]; ! 605: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset); ! 606: output_asm_insn (\"st_32 %1,r25,%0\", xoperands); ! 607: xoperands[1] = operands[0]; ! 608: output_asm_insn (\"ld_sgl %1,r25,%0\;nop\", xoperands); ! 609: return \"\"; ! 610: } ! 611: return \"ld_sgl %0,%1\;nop\"; ! 612: } ! 613: if (FP_REG_P (operands[1])) ! 614: { ! 615: if (GET_CODE (operands[0]) == REG) ! 616: { ! 617: rtx xoperands[2]; ! 618: int offset = - get_frame_size () - 8; ! 619: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset); ! 620: xoperands[1] = operands[1]; ! 621: output_asm_insn (\"st_sgl %1,r25,%0\", xoperands); ! 622: xoperands[1] = operands[0]; ! 623: output_asm_insn (\"ld_32 %1,r25,%0\;nop\", xoperands); ! 624: return \"\"; ! 625: } ! 626: return \"st_sgl %1,%0\"; ! 627: } ! 628: if (GET_CODE (operands[0]) == MEM) ! 629: return \"st_32 %r1,%0\"; ! 630: if (GET_CODE (operands[1]) == MEM) ! 631: return \"ld_32 %0,%1\;nop\"; ! 632: if (GET_CODE (operands[1]) == REG) ! 633: return \"add_nt %0,%1,$0\"; ! 634: return \"add_nt %0,r0,%1\"; ! 635: }") ! 636: ! 637: ;;- truncation instructions ! 638: ;; I think these are unnecessary, since subreg will be used instead. ! 639: ;(define_insn "truncsiqi2" ! 640: ; [(set (match_operand:QI 0 "register_operand" "=r") ! 641: ; (truncate:QI ! 642: ; (match_operand:SI 1 "register_operand" "r")))] ! 643: ; "" ! 644: ; "add_nt, %0,%1,$0") ! 645: ; ! 646: ;(define_insn "trunchiqi2" ! 647: ; [(set (match_operand:QI 0 "register_operand" "=r") ! 648: ; (truncate:QI ! 649: ; (match_operand:HI 1 "register_operand" "r")))] ! 650: ; "" ! 651: ; "add_nt, %0,%1,$0") ! 652: ; ! 653: ;(define_insn "truncsihi2" ! 654: ; [(set (match_operand:HI 0 "register_operand" "=r") ! 655: ; (truncate:HI ! 656: ; (match_operand:SI 1 "register_operand" "r")))] ! 657: ; "" ! 658: ; "add_nt, %0,%1,$0") ! 659: ! 660: ;;- zero extension instructions ! 661: ! 662: ;; Note that the one starting from HImode comes before those for QImode ! 663: ;; so that a constant operand will match HImode, not QImode. ! 664: (define_expand "zero_extendhisi2" ! 665: [(set (match_operand:SI 0 "register_operand" "") ! 666: (and:SI (subreg:SI (match_operand:HI 1 "register_operand" "") 0) ! 667: ;; This constant is invalid, but reloading will handle it. ! 668: ;; It's useless to generate here the insns to construct it ! 669: ;; because constant propagation would simplify them anyway. ! 670: (match_dup 2)))] ! 671: "" ! 672: " operands[2] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535)); ") ! 673: ! 674: (define_insn "zero_extendqihi2" ! 675: [(set (match_operand:HI 0 "register_operand" "=r") ! 676: (zero_extend:HI ! 677: (match_operand:QI 1 "register_operand" "r")))] ! 678: "" ! 679: "extract %0,%1,$0") ! 680: ! 681: (define_insn "zero_extendqisi2" ! 682: [(set (match_operand:SI 0 "register_operand" "=r") ! 683: (zero_extend:SI ! 684: (match_operand:QI 1 "register_operand" "r")))] ! 685: "" ! 686: "extract %0,%1,$0") ! 687: ! 688: ;;- sign extension instructions ! 689: ;; Note that the one starting from HImode comes before those for QImode ! 690: ;; so that a constant operand will match HImode, not QImode. ! 691: ! 692: (define_expand "extendhisi2" ! 693: [(set (match_dup 2) ! 694: (and:SI (subreg:SI (match_operand:HI 1 "register_operand" "") 0) ! 695: (match_dup 4))) ! 696: (set (match_dup 3) (plus:SI (match_dup 2) (match_dup 5))) ! 697: (set (match_operand:SI 0 "register_operand" "") ! 698: (xor:SI (match_dup 3) (match_dup 5)))] ! 699: "" ! 700: " ! 701: { ! 702: operands[2] = gen_reg_rtx (SImode); ! 703: operands[3] = gen_reg_rtx (SImode); ! 704: operands[4] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535)); ! 705: operands[5] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, -32768)); ! 706: }") ! 707: ! 708: (define_expand "extendqihi2" ! 709: [(set (match_dup 2) ! 710: (and:HI (subreg:HI (match_operand:QI 1 "register_operand" "") 0) ! 711: (const_int 255))) ! 712: (set (match_dup 3) ! 713: (plus:SI (match_dup 2) (const_int -128))) ! 714: (set (match_operand:HI 0 "register_operand" "") ! 715: (xor:SI (match_dup 3) (const_int -128)))] ! 716: "" ! 717: " ! 718: { ! 719: operands[2] = gen_reg_rtx (HImode); ! 720: operands[3] = gen_reg_rtx (HImode); ! 721: }") ! 722: ! 723: (define_expand "extendqisi2" ! 724: [(set (match_dup 2) ! 725: (and:SI (subreg:SI (match_operand:QI 1 "register_operand" "") 0) ! 726: (const_int 255))) ! 727: (set (match_dup 3) (plus:SI (match_dup 2) (const_int -128))) ! 728: (set (match_operand:SI 0 "register_operand" "") ! 729: (xor:SI (match_dup 3) (const_int -128)))] ! 730: "" ! 731: " ! 732: { ! 733: operands[2] = gen_reg_rtx (SImode); ! 734: operands[3] = gen_reg_rtx (SImode); ! 735: }") ! 736: ! 737: ;;- arithmetic instructions ! 738: ! 739: (define_insn "addsi3" ! 740: [(set (match_operand:SI 0 "register_operand" "=r") ! 741: (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r") ! 742: (match_operand:SI 2 "nonmemory_operand" "rI")))] ! 743: "" ! 744: "add %0,%1,%2") ! 745: ! 746: (define_insn "subsi3" ! 747: [(set (match_operand:SI 0 "register_operand" "=r") ! 748: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 749: (match_operand:SI 2 "nonmemory_operand" "rI")))] ! 750: "" ! 751: "sub %0,%1,%2") ! 752: ! 753: (define_insn "andsi3" ! 754: [(set (match_operand:SI 0 "register_operand" "=r") ! 755: (and:SI (match_operand:SI 1 "nonmemory_operand" "%r") ! 756: (match_operand:SI 2 "nonmemory_operand" "rI")))] ! 757: "" ! 758: "and %0,%1,%2") ! 759: ! 760: (define_insn "iorsi3" ! 761: [(set (match_operand:SI 0 "register_operand" "=r") ! 762: (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r") ! 763: (match_operand:SI 2 "nonmemory_operand" "rI")))] ! 764: "" ! 765: "or %0,%1,%2") ! 766: ! 767: (define_insn "xorsi3" ! 768: [(set (match_operand:SI 0 "register_operand" "=r") ! 769: (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r") ! 770: (match_operand:SI 2 "nonmemory_operand" "rI")))] ! 771: "" ! 772: "xor %0,%1,%2") ! 773: ! 774: (define_insn "negsi2" ! 775: [(set (match_operand:SI 0 "register_operand" "=r") ! 776: (neg:SI (match_operand:SI 1 "nonmemory_operand" "rI")))] ! 777: "" ! 778: "sub %0,r0,%1") ! 779: ! 780: (define_insn "one_cmplsi2" ! 781: [(set (match_operand:SI 0 "register_operand" "=r") ! 782: (not:SI (match_operand:SI 1 "register_operand" "r")))] ! 783: "" ! 784: "xor %0,%1,$-1") ! 785: ! 786: ;; Floating point arithmetic instructions. ! 787: ! 788: (define_insn "adddf3" ! 789: [(set (match_operand:DF 0 "register_operand" "=f") ! 790: (plus:DF (match_operand:DF 1 "register_operand" "f") ! 791: (match_operand:DF 2 "register_operand" "f")))] ! 792: "TARGET_FPU" ! 793: "fadd %0,%1,%2") ! 794: ! 795: (define_insn "addsf3" ! 796: [(set (match_operand:SF 0 "register_operand" "=f") ! 797: (plus:SF (match_operand:SF 1 "register_operand" "f") ! 798: (match_operand:SF 2 "register_operand" "f")))] ! 799: "TARGET_FPU" ! 800: "fadd %0,%1,%2") ! 801: ! 802: (define_insn "subdf3" ! 803: [(set (match_operand:DF 0 "register_operand" "=f") ! 804: (minus:DF (match_operand:DF 1 "register_operand" "f") ! 805: (match_operand:DF 2 "register_operand" "f")))] ! 806: "TARGET_FPU" ! 807: "fsub %0,%1,%2") ! 808: ! 809: (define_insn "subsf3" ! 810: [(set (match_operand:SF 0 "register_operand" "=f") ! 811: (minus:SF (match_operand:SF 1 "register_operand" "f") ! 812: (match_operand:SF 2 "register_operand" "f")))] ! 813: "TARGET_FPU" ! 814: "fsub %0,%1,%2") ! 815: ! 816: (define_insn "muldf3" ! 817: [(set (match_operand:DF 0 "register_operand" "=f") ! 818: (mult:DF (match_operand:DF 1 "register_operand" "f") ! 819: (match_operand:DF 2 "register_operand" "f")))] ! 820: "TARGET_FPU" ! 821: "fmul %0,%1,%2") ! 822: ! 823: (define_insn "mulsf3" ! 824: [(set (match_operand:SF 0 "register_operand" "=f") ! 825: (mult:SF (match_operand:SF 1 "register_operand" "f") ! 826: (match_operand:SF 2 "register_operand" "f")))] ! 827: "TARGET_FPU" ! 828: "fmul %0,%1,%2") ! 829: ! 830: (define_insn "divdf3" ! 831: [(set (match_operand:DF 0 "register_operand" "=f") ! 832: (div:DF (match_operand:DF 1 "register_operand" "f") ! 833: (match_operand:DF 2 "register_operand" "f")))] ! 834: "TARGET_FPU" ! 835: "fdiv %0,%1,%2") ! 836: ! 837: (define_insn "divsf3" ! 838: [(set (match_operand:SF 0 "register_operand" "=f") ! 839: (div:SF (match_operand:SF 1 "register_operand" "f") ! 840: (match_operand:SF 2 "register_operand" "f")))] ! 841: "TARGET_FPU" ! 842: "fdiv %0,%1,%2") ! 843: ! 844: (define_insn "negdf2" ! 845: [(set (match_operand:DF 0 "register_operand" "=f") ! 846: (neg:DF (match_operand:DF 1 "nonmemory_operand" "f")))] ! 847: "TARGET_FPU" ! 848: "fneg %0,%1") ! 849: ! 850: (define_insn "negsf2" ! 851: [(set (match_operand:SF 0 "register_operand" "=f") ! 852: (neg:SF (match_operand:SF 1 "nonmemory_operand" "f")))] ! 853: "TARGET_FPU" ! 854: "fneg %0,%1") ! 855: ! 856: (define_insn "absdf2" ! 857: [(set (match_operand:DF 0 "register_operand" "=f") ! 858: (abs:DF (match_operand:DF 1 "nonmemory_operand" "f")))] ! 859: "TARGET_FPU" ! 860: "fabs %0,%1") ! 861: ! 862: (define_insn "abssf2" ! 863: [(set (match_operand:SF 0 "register_operand" "=f") ! 864: (abs:SF (match_operand:SF 1 "nonmemory_operand" "f")))] ! 865: "TARGET_FPU" ! 866: "fabs %0,%1") ! 867: ! 868: ;; Shift instructions ! 869: ! 870: (define_insn "" ! 871: [(set (match_operand:SI 0 "register_operand" "=r") ! 872: (ashift:SI (match_operand:SI 1 "register_operand" "r") ! 873: (match_operand:SI 2 "immediate_operand" "I")))] ! 874: "GET_CODE (operands[2]) == CONST_INT ! 875: && (unsigned) INTVAL (operands[2]) <= 3" ! 876: "sll %0,%1,%2") ! 877: ! 878: (define_insn "" ! 879: [(set (match_operand:SI 0 "register_operand" "=r") ! 880: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") ! 881: (const_int 1)))] ! 882: "" ! 883: "sra %0,%1,$1") ! 884: ! 885: (define_insn "" ! 886: [(set (match_operand:SI 0 "register_operand" "=r") ! 887: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") ! 888: (const_int 1)))] ! 889: "" ! 890: "srl %0,%1,$1") ! 891: ! 892: (define_expand "ashlsi3" ! 893: [(set (match_operand:SI 0 "register_operand" "") ! 894: (ashift:SI (match_operand:SI 1 "register_operand" "") ! 895: (match_operand:SI 2 "nonmemory_operand" "")))] ! 896: "" ! 897: " ! 898: { ! 899: if (GET_CODE (operands[2]) != CONST_INT ! 900: || (unsigned) INTVAL (operands[2]) > 3) ! 901: FAIL; ! 902: }") ! 903: ! 904: (define_expand "lshlsi3" ! 905: [(set (match_operand:SI 0 "register_operand" "") ! 906: (ashift:SI (match_operand:SI 1 "register_operand" "") ! 907: (match_operand:SI 2 "nonmemory_operand" "")))] ! 908: "" ! 909: " ! 910: { ! 911: if (GET_CODE (operands[2]) != CONST_INT ! 912: || (unsigned) INTVAL (operands[2]) > 3) ! 913: FAIL; ! 914: }") ! 915: ! 916: (define_expand "ashrsi3" ! 917: [(set (match_operand:SI 0 "register_operand" "") ! 918: (ashiftrt:SI (match_operand:SI 1 "register_operand" "") ! 919: (match_operand:SI 2 "nonmemory_operand" "")))] ! 920: "" ! 921: " ! 922: { ! 923: if (GET_CODE (operands[2]) != CONST_INT ! 924: || (unsigned) INTVAL (operands[2]) > 1) ! 925: FAIL; ! 926: }") ! 927: ! 928: (define_expand "lshrsi3" ! 929: [(set (match_operand:SI 0 "register_operand" "") ! 930: (lshiftrt:SI (match_operand:SI 1 "register_operand" "") ! 931: (match_operand:SI 2 "nonmemory_operand" "")))] ! 932: "" ! 933: " ! 934: { ! 935: if (GET_CODE (operands[2]) != CONST_INT ! 936: || (unsigned) INTVAL (operands[2]) > 1) ! 937: FAIL; ! 938: }") ! 939: ! 940: ;; Unconditional and other jump instructions ! 941: (define_insn "jump" ! 942: [(set (pc) ! 943: (label_ref (match_operand 0 "" "")))] ! 944: "" ! 945: "jump %l0\;nop") ! 946: ! 947: (define_insn "tablejump" ! 948: [(set (pc) (match_operand:SI 0 "register_operand" "r")) ! 949: (use (label_ref (match_operand 1 "" "")))] ! 950: "" ! 951: "jump_reg r0,%0\;nop") ! 952: ! 953: ;;- jump to subroutine ! 954: (define_insn "call" ! 955: [(call (match_operand:SI 0 "memory_operand" "m") ! 956: (match_operand:SI 1 "general_operand" "g"))] ! 957: ;;- Don't use operand 1 for most machines. ! 958: "" ! 959: "add_nt r9,%0\;call .+8\;jump_reg r0,r9\;nop") ! 960: ! 961: (define_insn "call_value" ! 962: [(set (match_operand 0 "" "g") ! 963: (call (match_operand:SI 1 "memory_operand" "m") ! 964: (match_operand:SI 2 "general_operand" "g")))] ! 965: ;;- Don't use operand 1 for most machines. ! 966: "" ! 967: "add_nt r9,%1\;call .+8\;jump_reg r0,r9\;nop") ! 968: ! 969: ;; A memory ref with constant address is not normally valid. ! 970: ;; But it is valid in a call insns. This pattern allows the ! 971: ;; loading of the address to combine with the call. ! 972: (define_insn "" ! 973: [(call (mem:SI (match_operand:SI 0 "" "i")) ! 974: (match_operand:SI 1 "general_operand" "g"))] ! 975: ;;- Don't use operand 1 for most machines. ! 976: "GET_CODE (operands[0]) == SYMBOL_REF" ! 977: "call %0\;nop") ! 978: ! 979: (define_insn "" ! 980: [(set (match_operand 0 "" "g") ! 981: (call (mem:SI (match_operand:SI 1 "" "i")) ! 982: (match_operand:SI 2 "general_operand" "g")))] ! 983: ;;- Don't use operand 1 for most machines. ! 984: "GET_CODE (operands[1]) == SYMBOL_REF" ! 985: "call %1\;nop") ! 986: ! 987: ;;- Local variables: ! 988: ;;- mode:emacs-lisp ! 989: ;;- comment-start: ";;- " ! 990: ;;- eval: (set-syntax-table (copy-sequence (syntax-table))) ! 991: ;;- eval: (modify-syntax-entry ?[ "(]") ! 992: ;;- eval: (modify-syntax-entry ?] ")[") ! 993: ;;- eval: (modify-syntax-entry ?{ "(}") ! 994: ;;- eval: (modify-syntax-entry ?} "){") ! 995: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.