|
|
1.1 ! root 1: /* Subroutines for insn-output.c for the Gmicro. ! 2: Ported by Masanobu Yuhara, Fujitsu Laboratories LTD. ! 3: ([email protected]) ! 4: ! 5: Copyright (C) 1990, 1991 Free Software Foundation, Inc. ! 6: ! 7: This file is part of GNU CC. ! 8: ! 9: GNU CC is free software; you can redistribute it and/or modify ! 10: it under the terms of the GNU General Public License as published by ! 11: the Free Software Foundation; either version 2, or (at your option) ! 12: any later version. ! 13: ! 14: GNU CC is distributed in the hope that it will be useful, ! 15: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 17: GNU General Public License for more details. ! 18: ! 19: Among other things, the copyright ! 20: notice and this notice must be preserved on all copies. ! 21: ! 22: You should have received a copy of the GNU General Public License ! 23: along with GNU CC; see the file COPYING. If not, write to ! 24: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 25: ! 26: ! 27: #include <stdio.h> ! 28: #include "config.h" ! 29: #include "rtl.h" ! 30: #include "regs.h" ! 31: #include "hard-reg-set.h" ! 32: #include "real.h" ! 33: #include "insn-config.h" ! 34: #include "conditions.h" ! 35: #include "insn-flags.h" ! 36: #include "output.h" ! 37: #include "insn-attr.h" ! 38: ! 39: extern char *rtx_name[]; ! 40: ! 41: mypr (s, a1, a2, a3, a4, a5) ! 42: char *s; ! 43: int a1, a2, a3, a4, a5; ! 44: { ! 45: fprintf (stderr, s, a1, a2, a3, a4, a5); ! 46: } ! 47: ! 48: myprcode (i) ! 49: int i; ! 50: { ! 51: if (i < 0 || i > 90) ! 52: fprintf (stderr, "code = %d\n", i); ! 53: else ! 54: fprintf (stderr, "code = %s\n", rtx_name[i]); ! 55: } ! 56: ! 57: myabort (i) ! 58: int i; ! 59: { ! 60: fprintf (stderr, "myabort"); ! 61: myprcode (i); ! 62: } ! 63: ! 64: ! 65: /* This is how to output an ascii string. */ ! 66: /* See ASM_OUTPUT_ASCII in gmicro.h. */ ! 67: output_ascii (file, p, size) ! 68: FILE *file; ! 69: char *p; ! 70: int size; ! 71: { ! 72: int i; ! 73: int in_quote = 0; ! 74: register int c; ! 75: ! 76: fprintf (file, "\t.sdata "); ! 77: ! 78: for (i = 0; i < size; i++) ! 79: { ! 80: c = p[i]; ! 81: if (c >= ' ' && c < 0x7f) ! 82: { ! 83: if (!in_quote) ! 84: { ! 85: putc ('"', file); ! 86: in_quote = 1; ! 87: } ! 88: putc (c, file); ! 89: } ! 90: else ! 91: { ! 92: if (in_quote) ! 93: { ! 94: putc ('"', file); ! 95: in_quote = 0; ! 96: } ! 97: fprintf (file, "<%d>", c); ! 98: } ! 99: } ! 100: if (in_quote) ! 101: putc ('"', file); ! 102: putc ('\n', file); ! 103: } ! 104: ! 105: ! 106: /* call this when GET_CODE (index) is MULT. */ ! 107: print_scaled_index (file, index) ! 108: FILE *file; ! 109: register rtx index; ! 110: { ! 111: register rtx ireg; ! 112: int scale; ! 113: ! 114: if (GET_CODE (XEXP (index, 0)) == REG) ! 115: { ! 116: ireg = XEXP (index, 0); ! 117: scale = INTVAL (XEXP (index, 1)); ! 118: } ! 119: else ! 120: { ! 121: ireg = XEXP (index, 1); ! 122: scale = INTVAL (XEXP (index, 0)); ! 123: } ! 124: if (scale == 1) ! 125: fprintf (file, "%s", reg_names[REGNO (ireg)]); ! 126: else ! 127: fprintf (file, "%s*%d", reg_names[REGNO (ireg)], scale); ! 128: } ! 129: ! 130: ! 131: print_operand_address (file, addr) ! 132: FILE *file; ! 133: register rtx addr; ! 134: { ! 135: register rtx xtmp0, xtmp1, breg, ixreg; ! 136: int scale; ! 137: int needcomma = 0; ! 138: rtx offset; ! 139: ! 140: fprintf (file, "@"); ! 141: retry: ! 142: switch (GET_CODE (addr)) ! 143: { ! 144: case MEM: ! 145: fprintf (file, "@"); ! 146: addr = XEXP (addr, 0); ! 147: goto retry; ! 148: ! 149: case REG: ! 150: fprintf (file, "%s", reg_names[REGNO (addr)]); ! 151: break; ! 152: ! 153: case MULT: ! 154: print_scaled_index (file, addr); ! 155: break; ! 156: ! 157: case PRE_DEC: ! 158: fprintf (file, "-%s", reg_names[REGNO (XEXP (addr, 0))]); ! 159: break; ! 160: ! 161: case POST_INC: ! 162: fprintf (file, "%s+", reg_names[REGNO (XEXP (addr, 0))]); ! 163: break; ! 164: ! 165: case PLUS: ! 166: xtmp0 = XEXP (addr, 0); ! 167: xtmp1 = XEXP (addr, 1); ! 168: ixreg = 0; breg = 0; ! 169: offset = 0; ! 170: if (CONSTANT_ADDRESS_P (xtmp0)) ! 171: { ! 172: offset = xtmp0; ! 173: breg = xtmp1; ! 174: } ! 175: else if (CONSTANT_ADDRESS_P (xtmp1)) ! 176: { ! 177: offset = xtmp1; ! 178: breg = xtmp0; ! 179: } ! 180: else ! 181: { ! 182: goto NOT_DISP; ! 183: } ! 184: ! 185: if (REG_CODE_BASE_P (breg)) ! 186: goto PRINT_MEM; ! 187: ! 188: if (GET_CODE (breg) == MULT) ! 189: { ! 190: if (REG_CODE_INDEX_P (XEXP (breg, 0))) ! 191: { ! 192: ixreg = XEXP (breg, 0); ! 193: scale = INTVAL (XEXP (breg, 1)); ! 194: breg = 0; ! 195: } ! 196: else ! 197: { ! 198: ixreg = XEXP (breg, 1); ! 199: scale = INTVAL (XEXP (breg, 0)); ! 200: breg = 0; ! 201: } ! 202: goto PRINT_MEM; ! 203: } ! 204: ! 205: /* GET_CODE (breg) must be PLUS here. */ ! 206: xtmp0 = XEXP (breg, 0); ! 207: xtmp1 = XEXP (breg, 1); ! 208: if (REG_CODE_BASE_P (xtmp0)) ! 209: { ! 210: breg = xtmp0; ! 211: xtmp0 = xtmp1; ! 212: } ! 213: else ! 214: { ! 215: breg = xtmp1; ! 216: /* xtmp0 = xtmp0; */ ! 217: } ! 218: ! 219: if (GET_CODE (xtmp0) == MULT) ! 220: { ! 221: if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) ! 222: { ! 223: ixreg = XEXP (xtmp0, 0); ! 224: scale = INTVAL (XEXP (xtmp0, 1)); ! 225: } ! 226: else ! 227: { ! 228: ixreg = XEXP (xtmp0, 1); ! 229: scale = INTVAL (XEXP (xtmp0, 0)); ! 230: } ! 231: } ! 232: else ! 233: { ! 234: ixreg = xtmp0; ! 235: scale = 1; ! 236: } ! 237: goto PRINT_MEM; ! 238: ! 239: NOT_DISP: ! 240: if (REG_CODE_BASE_P (xtmp0)) ! 241: { ! 242: breg = xtmp0; ! 243: xtmp0 = xtmp1; ! 244: } ! 245: else if (REG_CODE_BASE_P (xtmp1)) ! 246: { ! 247: breg = xtmp1; ! 248: /* xtmp0 = xtmp0; */ ! 249: } ! 250: else ! 251: goto NOT_BASE; ! 252: ! 253: if (REG_CODE_INDEX_P (xtmp0)) ! 254: { ! 255: ixreg = xtmp0; ! 256: scale = 1; ! 257: goto PRINT_MEM; ! 258: } ! 259: else if (CONSTANT_ADDRESS_P (xtmp0)) ! 260: { ! 261: offset = xtmp0; ! 262: goto PRINT_MEM; ! 263: } ! 264: else if (GET_CODE (xtmp0) == MULT) ! 265: { ! 266: if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) ! 267: { ! 268: ixreg = XEXP (xtmp0, 0); ! 269: scale = INTVAL (XEXP (xtmp0, 1)); ! 270: } ! 271: else ! 272: { ! 273: ixreg = XEXP (xtmp0, 1); ! 274: scale = INTVAL (XEXP (xtmp0, 0)); ! 275: } ! 276: goto PRINT_MEM; ! 277: } ! 278: ! 279: /* GET_CODE (xtmp0) must be PLUS. */ ! 280: xtmp1 = XEXP (xtmp0, 1); ! 281: xtmp0 = XEXP (xtmp0, 0); ! 282: ! 283: if (CONSTANT_ADDRESS_P (xtmp0)) ! 284: { ! 285: offset = xtmp0; ! 286: xtmp0 = xtmp1; ! 287: } ! 288: else ! 289: { ! 290: offset = xtmp1; ! 291: /* xtmp0 = xtmp0; */ ! 292: } ! 293: ! 294: if (REG_CODE_INDEX_P (xtmp0)) ! 295: { ! 296: ixreg = xtmp0; ! 297: } ! 298: else ! 299: { /* GET_CODE (xtmp0) must be MULT. */ ! 300: if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) ! 301: { ! 302: ixreg = XEXP (xtmp0, 0); ! 303: scale = INTVAL (XEXP (xtmp0, 1)); ! 304: } ! 305: else ! 306: { ! 307: ixreg = XEXP (xtmp0, 1); ! 308: scale = INTVAL (XEXP (xtmp0, 0)); ! 309: } ! 310: } ! 311: goto PRINT_MEM; ! 312: ! 313: NOT_BASE: ! 314: if (GET_CODE (xtmp0) == PLUS) ! 315: { ! 316: ixreg = xtmp1; ! 317: /* xtmp0 = xtmp0; */ ! 318: } ! 319: else ! 320: { ! 321: ixreg = xtmp0; ! 322: xtmp0 = xtmp1; ! 323: } ! 324: ! 325: if (REG_CODE_INDEX_P (ixreg)) ! 326: { ! 327: scale = 1; ! 328: } ! 329: else if (REG_CODE_INDEX_P (XEXP (ixreg, 0))) ! 330: { ! 331: scale = INTVAL (XEXP (ixreg, 1)); ! 332: ixreg = XEXP (ixreg, 0); ! 333: } ! 334: else ! 335: { /* was else if with no condition. OK ??? */ ! 336: scale = INTVAL (XEXP (ixreg, 0)); ! 337: ixreg = XEXP (ixreg, 1); ! 338: } ! 339: ! 340: if (REG_CODE_BASE_P (XEXP (xtmp0, 0))) ! 341: { ! 342: breg = XEXP (xtmp0, 0); ! 343: offset = XEXP (xtmp0, 1); ! 344: } ! 345: else ! 346: { ! 347: breg = XEXP (xtmp0, 1); ! 348: offset = XEXP (xtmp0, 0); ! 349: } ! 350: ! 351: PRINT_MEM: ! 352: if (breg == 0 && ixreg == 0) ! 353: { ! 354: output_address (offset); ! 355: break; ! 356: } ! 357: else if (ixreg == 0 && offset == 0) ! 358: { ! 359: fprintf (file, "%s", reg_names[REGNO (breg)]); ! 360: break; ! 361: } ! 362: else ! 363: { ! 364: fprintf (file, "("); ! 365: if (offset != 0) ! 366: { ! 367: output_addr_const (file, offset); ! 368: needcomma = 1; ! 369: } ! 370: if (breg != 0) ! 371: { ! 372: if (needcomma) ! 373: fprintf (file, ","); ! 374: fprintf (file, "%s", reg_names[REGNO (breg)]); ! 375: needcomma = 1; ! 376: } ! 377: if (ixreg != 0) ! 378: { ! 379: if (needcomma) ! 380: fprintf (file, ","); ! 381: fprintf (file, "%s", reg_names[REGNO (ixreg)]); ! 382: if (scale != 1) ! 383: fprintf (file,"*%d", scale); ! 384: } ! 385: fprintf (file, ")"); ! 386: ! 387: break; ! 388: } ! 389: ! 390: default: ! 391: output_addr_const (file, addr); ! 392: } ! 393: } ! 394: ! 395: ! 396: ! 397: /* Return a REG that occurs in ADDR with coefficient 1. ! 398: ADDR can be effectively incremented by incrementing REG. */ ! 399: ! 400: static rtx ! 401: find_addr_reg (addr) ! 402: rtx addr; ! 403: { ! 404: while (GET_CODE (addr) == PLUS) ! 405: { ! 406: if (GET_CODE (XEXP (addr, 0)) == REG) ! 407: addr = XEXP (addr, 0); ! 408: else if (GET_CODE (XEXP (addr, 1)) == REG) ! 409: addr = XEXP (addr, 1); ! 410: else if (GET_CODE (XEXP (addr, 0)) == PLUS) ! 411: addr = XEXP (addr, 0); ! 412: else if (GET_CODE (XEXP (addr, 1)) == PLUS) ! 413: addr = XEXP (addr, 1); ! 414: } ! 415: if (GET_CODE (addr) == REG) ! 416: return addr; ! 417: return 0; ! 418: } ! 419: ! 420: ! 421: /* Return the best assembler insn template ! 422: for moving operands[1] into operands[0] as a fullword. */ ! 423: ! 424: static char * ! 425: singlemove_string (operands) ! 426: rtx *operands; ! 427: { ! 428: if (FPU_REG_P (operands[0]) || FPU_REG_P (operands[1])) ! 429: { ! 430: if (GREG_P (operands[0]) || GREG_P (operands[1])) ! 431: { ! 432: myabort (101); /* Not Supported yet !! */ ! 433: } ! 434: else ! 435: { ! 436: return "fmov.s %1,%0"; ! 437: } ! 438: } ! 439: return "mov.w %1,%0"; ! 440: } ! 441: ! 442: ! 443: /* Output assembler code to perform a doubleword move insn ! 444: with operands OPERANDS. */ ! 445: ! 446: char * ! 447: output_move_double (operands) ! 448: rtx *operands; ! 449: { ! 450: enum ! 451: { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } ! 452: optype0, optype1; ! 453: rtx latehalf[2]; ! 454: rtx addreg0 = 0, addreg1 = 0; ! 455: ! 456: /* First classify both operands. */ ! 457: ! 458: if (REG_P (operands[0])) ! 459: optype0 = REGOP; ! 460: else if (offsettable_memref_p (operands[0])) ! 461: optype0 = OFFSOP; ! 462: else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) ! 463: optype0 = POPOP; ! 464: else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! 465: optype0 = PUSHOP; ! 466: else if (GET_CODE (operands[0]) == MEM) ! 467: optype0 = MEMOP; ! 468: else ! 469: optype0 = RNDOP; ! 470: ! 471: if (REG_P (operands[1])) ! 472: optype1 = REGOP; ! 473: else if (CONSTANT_P (operands[1])) ! 474: optype1 = CNSTOP; ! 475: else if (offsettable_memref_p (operands[1])) ! 476: optype1 = OFFSOP; ! 477: else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC) ! 478: optype1 = POPOP; ! 479: else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ! 480: optype1 = PUSHOP; ! 481: else if (GET_CODE (operands[1]) == MEM) ! 482: optype1 = MEMOP; ! 483: else ! 484: optype1 = RNDOP; ! 485: ! 486: /* Check for the cases that the operand constraints are not ! 487: supposed to allow to happen. Abort if we get one, ! 488: because generating code for these cases is painful. */ ! 489: ! 490: if (optype0 == RNDOP || optype1 == RNDOP) ! 491: myabort (102); ! 492: ! 493: /* If one operand is decrementing and one is incrementing ! 494: decrement the former register explicitly ! 495: and change that operand into ordinary indexing. */ ! 496: ! 497: if (optype0 == PUSHOP && optype1 == POPOP) ! 498: { ! 499: operands[0] = XEXP (XEXP (operands[0], 0), 0); ! 500: output_asm_insn ("sub.w %#8,%0", operands); ! 501: operands[0] = gen_rtx (MEM, DImode, operands[0]); ! 502: optype0 = OFFSOP; ! 503: } ! 504: if (optype0 == POPOP && optype1 == PUSHOP) ! 505: { ! 506: operands[1] = XEXP (XEXP (operands[1], 0), 0); ! 507: output_asm_insn ("sub.w %#8,%1", operands); ! 508: operands[1] = gen_rtx (MEM, DImode, operands[1]); ! 509: optype1 = OFFSOP; ! 510: } ! 511: ! 512: /* If an operand is an unoffsettable memory ref, find a register ! 513: we can increment temporarily to make it refer to the second word. */ ! 514: ! 515: if (optype0 == MEMOP) ! 516: addreg0 = find_addr_reg (operands[0]); ! 517: ! 518: if (optype1 == MEMOP) ! 519: addreg1 = find_addr_reg (operands[1]); ! 520: ! 521: /* Ok, we can do one word at a time. ! 522: Normally we do the low-numbered word first, ! 523: but if either operand is autodecrementing then we ! 524: do the high-numbered word first. ! 525: ! 526: In either case, set up in LATEHALF the operands to use ! 527: for the high-numbered word and in some cases alter the ! 528: operands in OPERANDS to be suitable for the low-numbered word. */ ! 529: ! 530: if (optype0 == REGOP) ! 531: latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 532: else if (optype0 == OFFSOP) ! 533: latehalf[0] = adj_offsettable_operand (operands[0], 4); ! 534: else ! 535: latehalf[0] = operands[0]; ! 536: ! 537: if (optype1 == REGOP) ! 538: latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 539: else if (optype1 == OFFSOP) ! 540: latehalf[1] = adj_offsettable_operand (operands[1], 4); ! 541: else if (optype1 == CNSTOP) ! 542: { ! 543: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 544: split_double (operands[1], &operands[1], &latehalf[1]); ! 545: else if (CONSTANT_P (operands[1])) ! 546: latehalf[1] = const0_rtx; ! 547: } ! 548: else ! 549: latehalf[1] = operands[1]; ! 550: ! 551: /* If insn is effectively movd N(sp),-(sp) then we will do the ! 552: high word first. We should use the adjusted operand 1 (which is N+4(sp)) ! 553: for the low word as well, to compensate for the first decrement of sp. */ ! 554: if (optype0 == PUSHOP ! 555: && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM ! 556: && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1])) ! 557: operands[1] = latehalf[1]; ! 558: ! 559: /* If one or both operands autodecrementing, ! 560: do the two words, high-numbered first. */ ! 561: ! 562: /* Likewise, the first move would clobber the source of the second one, ! 563: do them in the other order. This happens only for registers; ! 564: such overlap can't happen in memory unless the user explicitly ! 565: sets it up, and that is an undefined circumstance. */ ! 566: ! 567: if (optype0 == PUSHOP || optype1 == PUSHOP ! 568: || (optype0 == REGOP && optype1 == REGOP ! 569: && REGNO (operands[0]) == REGNO (latehalf[1]))) ! 570: { ! 571: /* Make any unoffsettable addresses point at high-numbered word. */ ! 572: if (addreg0) ! 573: output_asm_insn ("add.w %#4,%0", &addreg0); ! 574: if (addreg1) ! 575: output_asm_insn ("add.w %#4,%0", &addreg1); ! 576: ! 577: /* Do that word. */ ! 578: output_asm_insn (singlemove_string (latehalf), latehalf); ! 579: ! 580: /* Undo the adds we just did. */ ! 581: if (addreg0) ! 582: output_asm_insn ("sub.w %#4,%0", &addreg0); ! 583: if (addreg1) ! 584: output_asm_insn ("sub.w %#4,%0", &addreg1); ! 585: ! 586: /* Do low-numbered word. */ ! 587: return singlemove_string (operands); ! 588: } ! 589: ! 590: /* Normal case: do the two words, low-numbered first. */ ! 591: ! 592: output_asm_insn (singlemove_string (operands), operands); ! 593: ! 594: /* Make any unoffsettable addresses point at high-numbered word. */ ! 595: if (addreg0) ! 596: output_asm_insn ("add.w %#4,%0", &addreg0); ! 597: if (addreg1) ! 598: output_asm_insn ("add.w %#4,%0", &addreg1); ! 599: ! 600: /* Do that word. */ ! 601: output_asm_insn (singlemove_string (latehalf), latehalf); ! 602: ! 603: /* Undo the adds we just did. */ ! 604: if (addreg0) ! 605: output_asm_insn ("sub.w %#4,%0", &addreg0); ! 606: if (addreg1) ! 607: output_asm_insn ("sub.w %#4,%0", &addreg1); ! 608: ! 609: return ""; ! 610: } ! 611: ! 612: /* Move const_double to floating point register (DF) */ ! 613: char * ! 614: output_move_const_double (operands) ! 615: rtx *operands; ! 616: { ! 617: int code = standard_fpu_constant_p (operands[1]); ! 618: ! 619: if (FPU_REG_P (operands[0])) ! 620: { ! 621: if (code != 0) ! 622: { ! 623: static char buf[40]; ! 624: ! 625: sprintf (buf, "fmvr from%d,%%0.d", code); ! 626: return buf; ! 627: } ! 628: else ! 629: { ! 630: return "fmov %1,%0.d"; ! 631: } ! 632: } ! 633: else if (GREG_P (operands[0])) ! 634: { ! 635: rtx xoperands[2]; ! 636: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 637: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, ! 638: CONST_DOUBLE_HIGH (operands[1])); ! 639: output_asm_insn ("mov.w %1,%0", xoperands); ! 640: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 641: CONST_DOUBLE_LOW (operands[1])); ! 642: return "mov.w %1,%0"; ! 643: } ! 644: else ! 645: { ! 646: return output_move_double (operands); /* ?????? */ ! 647: } ! 648: } ! 649: ! 650: char * ! 651: output_move_const_single (operands) ! 652: rtx *operands; ! 653: { ! 654: int code = standard_fpu_constant_p (operands[1]); ! 655: static char buf[40]; ! 656: ! 657: if (FPU_REG_P (operands[0])) ! 658: { ! 659: if (code != 0) ! 660: { ! 661: sprintf (buf, "fmvr from%d,%%0.s", code); ! 662: return buf; ! 663: } ! 664: return "fmov.s %f1,%0"; ! 665: } ! 666: else ! 667: return "mov.w %f1,%0"; ! 668: } ! 669: ! 670: ! 671: /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get ! 672: from the "fmvr" instruction of the Gmicro FPU. ! 673: The value, anded with 0xff, gives the code to use in fmovecr ! 674: to get the desired constant. */ ! 675: ! 676: u.i[0] = CONST_DOUBLE_LOW (x); ! 677: u.i[1] = CONST_DOUBLE_HIGH (x); ! 678: d = u.d; ! 679: ! 680: if (d == 0.0) /* +0.0 */ ! 681: return 0x0; ! 682: /* Note: there are various other constants available ! 683: but it is a nuisance to put in their values here. */ ! 684: if (d == 1.0) /* +1.0 */ ! 685: return 0x1; ! 686: ! 687: /* ! 688: * Stuff that looks different if it's single or double ! 689: */ ! 690: if (GET_MODE (x) == SFmode) ! 691: { ! 692: if (d == S_PI) ! 693: return 0x2; ! 694: if (d == (S_PI / 2.0)) ! 695: return 0x3; ! 696: if (d == S_E) ! 697: return 0x4; ! 698: if (d == S_LOGEof2) ! 699: return 0x5; ! 700: if (d == S_LOGEof10) ! 701: return 0x6; ! 702: if (d == S_LOG10of2) ! 703: return 0x7; ! 704: if (d == S_LOG10ofE) ! 705: return 0x8; ! 706: if (d == S_LOG2ofE) ! 707: return 0x9; ! 708: } ! 709: else ! 710: { ! 711: if (d == D_PI) ! 712: return 0x2; ! 713: if (d == (D_PI / 2.0)) ! 714: return 0x3; ! 715: if (d == D_E) ! 716: return 0x4; ! 717: if (d == D_LOGEof2) ! 718: return 0x5; ! 719: if (d == D_LOGEof10) ! 720: return 0x6; ! 721: if (d == D_LOG10of2) ! 722: return 0x7; ! 723: if (d == D_LOG10ofE) ! 724: return 0x8; ! 725: if (d == D_LOG2ofE) ! 726: return 0x9; ! 727: } ! 728: ! 729: return 0; ! 730: } ! 731: ! 732: #undef S_PI ! 733: #undef D_PI ! 734: #undef S_E ! 735: #undef D_E ! 736: #undef S_LOGEof2 ! 737: #undef D_LOGEof2 ! 738: #undef S_LOGEof10 ! 739: #undef D_LOGEof10 ! 740: #undef S_LOG10of2 ! 741: #undef D_LOG10of2 ! 742: #undef S_LOG10ofE ! 743: #undef D_LOG10ofE ! 744: #undef S_LOG2ofE ! 745: #undef D_LOG2ofE ! 746: ! 747: /* dest should be operand 0 */ ! 748: /* imm should be operand 1 */ ! 749: ! 750: extern char *sub_imm_word (); ! 751: ! 752: char * ! 753: add_imm_word (imm, dest, immp) ! 754: int imm; ! 755: rtx dest, *immp; ! 756: { ! 757: int is_reg, short_ok; ! 758: ! 759: ! 760: if (imm < 0) ! 761: { ! 762: *immp = gen_rtx (CONST_INT, VOIDmode, -imm); ! 763: return sub_imm_word (-imm, dest); ! 764: } ! 765: ! 766: if (imm == 0) ! 767: return "mov:l.w #0,%0"; ! 768: ! 769: short_ok = short_format_ok (dest); ! 770: ! 771: if (short_ok && imm <= 8) ! 772: return "add:q %1,%0.w"; ! 773: ! 774: if (imm < 128) ! 775: return "add:e %1,%0.w"; ! 776: ! 777: is_reg = (GET_CODE (dest) == REG); ! 778: ! 779: if (is_reg) ! 780: return "add:l %1,%0.w"; ! 781: ! 782: if (short_ok) ! 783: return "add:i %1,%0.w"; ! 784: ! 785: return "add %1,%0.w"; ! 786: } ! 787: ! 788: char * ! 789: sub_imm_word (imm, dest, immp) ! 790: int imm; ! 791: rtx dest, *immp; ! 792: { ! 793: int is_reg, short_ok; ! 794: ! 795: if (imm < 0 && imm != 0x80000000) ! 796: { ! 797: *immp = gen_rtx (CONST_INT, VOIDmode, -imm); ! 798: return add_imm_word (-imm, dest); ! 799: } ! 800: ! 801: if (imm == 0) ! 802: return "mov:z.w #0,%0"; ! 803: ! 804: short_ok = short_format_ok (dest); ! 805: ! 806: if (short_ok && imm <= 8) ! 807: return "sub:q %1,%0.w"; ! 808: ! 809: if (imm < 128) ! 810: return "sub:e %1,%0.w"; ! 811: ! 812: is_reg = (GET_CODE (dest) == REG); ! 813: ! 814: if (is_reg) ! 815: return "sub:l %1,%0.w"; ! 816: ! 817: if (short_ok) ! 818: return "sub:i %1,%0.w"; ! 819: ! 820: return "sub %1,%0.w"; ! 821: } ! 822: ! 823: int ! 824: short_format_ok (x) ! 825: rtx x; ! 826: { ! 827: rtx x0, x1; ! 828: ! 829: if (GET_CODE (x) == REG) ! 830: return 1; ! 831: ! 832: if (GET_CODE (x) == MEM ! 833: && GET_CODE (XEXP (x, 0)) == PLUS) ! 834: { ! 835: x0 = XEXP (XEXP (x, 0), 0); ! 836: x1 = XEXP (XEXP (x, 0), 1); ! 837: return ((GET_CODE (x0) == REG ! 838: && CONSTANT_P (x1) ! 839: && ((unsigned) (INTVAL (x1) + 0x8000) < 0x10000)) ! 840: || ! 841: (GET_CODE (x1) == REG ! 842: && CONSTANT_P (x0) ! 843: && ((unsigned) (INTVAL (x0) + 0x8000) < 0x10000))); ! 844: } ! 845: ! 846: return 0; ! 847: } ! 848: ! 849: myoutput_sp_adjust (file, op, fsize) ! 850: FILE *file; ! 851: char *op; ! 852: int fsize; ! 853: { ! 854: if (fsize == 0) ! 855: ; ! 856: else if (fsize < 8) ! 857: fprintf (file, "\t%s:q #%d,sp.w\n", op, fsize); ! 858: else if (fsize < 128) ! 859: fprintf (file, "\t%s:e #%d,sp.w\n", op, fsize); ! 860: else ! 861: fprintf (file, "\t%s:l #%d,sp.w\n", op, fsize); ! 862: } ! 863: ! 864: ! 865: char * ! 866: mov_imm_word (imm, dest) ! 867: int imm; ! 868: rtx dest; ! 869: { ! 870: int is_reg, short_ok; ! 871: ! 872: if (imm == 0) ! 873: return "mov:z.w #0,%0"; ! 874: ! 875: short_ok = short_format_ok (dest); ! 876: ! 877: if (short_ok && imm > 0 && imm <= 8) ! 878: return "mov:q %1,%0.w"; ! 879: ! 880: if (-128 <= imm && imm < 128) ! 881: return "mov:e %1,%0.w"; ! 882: ! 883: is_reg = (GET_CODE (dest) == REG); ! 884: ! 885: if (is_reg) ! 886: return "mov:l %1,%0.w"; ! 887: ! 888: if (short_ok) ! 889: return "mov:i %1,%0.w"; ! 890: ! 891: return "mov %1,%0.w"; ! 892: } ! 893: ! 894: char * ! 895: cmp_imm_word (imm, dest) ! 896: int imm; ! 897: rtx dest; ! 898: { ! 899: int is_reg, short_ok; ! 900: ! 901: if (imm == 0) ! 902: return "cmp:z.w #0,%0"; ! 903: ! 904: short_ok = short_format_ok (dest); ! 905: ! 906: if (short_ok && imm >0 && imm <= 8) ! 907: return "cmp:q %1,%0.w"; ! 908: ! 909: if (-128 <= imm && imm < 128) ! 910: return "cmp:e %1,%0.w"; ! 911: ! 912: is_reg = (GET_CODE (dest) == REG); ! 913: ! 914: if (is_reg) ! 915: return "cmp:l %1,%0.w"; ! 916: ! 917: if (short_ok) ! 918: return "cmp:i %1,%0.w"; ! 919: ! 920: return "cmp %1,%0.w"; ! 921: } ! 922: ! 923: char * ! 924: push_imm_word (imm) ! 925: int imm; ! 926: { ! 927: if (imm == 0) ! 928: return "mov:z.w #0,%-"; ! 929: ! 930: if (imm > 0 && imm <= 8) ! 931: return "mov:q %1,%-.w"; ! 932: ! 933: if (-128 <= imm && imm < 128) ! 934: return "mov:e %1,%-.w"; ! 935: ! 936: return "mov:g %1,%-.w"; ! 937: ! 938: /* In some cases, g-format may be better than I format.?? ! 939: return "mov %1,%0.w"; ! 940: */ ! 941: } ! 942: ! 943: my_signed_comp (insn) ! 944: rtx insn; ! 945: { ! 946: rtx my_insn; ! 947: ! 948: my_insn = NEXT_INSN (insn); ! 949: if (GET_CODE (my_insn) != JUMP_INSN) ! 950: { ! 951: fprintf (stderr, "my_signed_comp: Not Jump_insn "); ! 952: myabort (GET_CODE (my_insn)); ! 953: } ! 954: my_insn = PATTERN (my_insn); ! 955: if (GET_CODE (my_insn) != SET) ! 956: { ! 957: fprintf (stderr, "my_signed_comp: Not Set "); ! 958: myabort (GET_CODE (my_insn)); ! 959: } ! 960: my_insn = SET_SRC (my_insn); ! 961: if (GET_CODE (my_insn) != IF_THEN_ELSE) ! 962: { ! 963: fprintf (stderr, "my_signed_comp: Not if_then_else "); ! 964: myabort (GET_CODE (my_insn)); ! 965: } ! 966: switch (GET_CODE (XEXP (my_insn, 0))) ! 967: { ! 968: case NE: ! 969: case EQ: ! 970: case GE: ! 971: case GT: ! 972: case LE: ! 973: case LT: ! 974: return 1; ! 975: case GEU: ! 976: case GTU: ! 977: case LEU: ! 978: case LTU: ! 979: return 0; ! 980: } ! 981: fprintf (stderr, "my_signed_comp: Not cccc "); ! 982: myabort (GET_CODE (XEXP (my_insn, 0))); ! 983: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.