|
|
1.1 ! root 1: /* ! 2: dpx2.h - Bull DPX/2 200 and 300 systems (m68k, SysVr3). ! 3: ! 4: Contributed by Frederic Pierresteguy. ! 5: Bug reports to [email protected]. ! 6: */ ! 7: ! 8: #ifndef USE_GAS ! 9: #define MOTOROLA /* Use Motorola syntax rather than "MIT" */ ! 10: #define SGS_NO_LI /* Suppress jump table label usage */ ! 11: #define VERSADOS /* This is the name of the assembler we have */ ! 12: #define USG ! 13: #endif ! 14: ! 15: #include "m68k/m68k.h" ! 16: #undef SELECT_RTX_SECTION ! 17: #include "svr3.h" ! 18: ! 19: /* See m68k.h. 7 means 68020 with 68881. ! 20: * We really have 68030 and 68882, ! 21: * but this will get us going. ! 22: */ ! 23: #ifndef TARGET_DEFAULT ! 24: #define TARGET_DEFAULT 7 ! 25: #endif ! 26: ! 27: #define OBJECT_FORMAT_COFF ! 28: #define NO_SYS_SIGLIST ! 29: ! 30: #ifdef CPP_PREDEFINES ! 31: #undef CPP_PREDEFINES ! 32: #endif ! 33: /* ! 34: * define all the things the compiler should ! 35: */ ! 36: #ifdef ncl_mr ! 37: # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_mr=1 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" ! 38: #else ! 39: # ifdef ncl_el ! 40: # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_el-D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" ! 41: # else ! 42: # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" ! 43: # endif ! 44: #endif ! 45: ! 46: #undef CPP_SPEC ! 47: /* ! 48: * you can't get a DPX/2 without a 68882 but allow it ! 49: * to be ignored... ! 50: */ ! 51: # define __HAVE_68881__ 1 ! 52: # define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__ }" ! 53: ! 54: #define HAVE_ATEXIT ! 55: #undef DO_GLOBAL_CTORS_BODY /* don't use svr3.h version */ ! 56: #undef DO_GLOBAL_DTORS_BODY ! 57: ! 58: #ifndef USE_GAS ! 59: /* ! 60: * handle the native MOTOROLA VERSAdos assembler. ! 61: */ ! 62: ! 63: /* See m68k.h. 3 means 68020 with 68881 and no bitfiled ! 64: * bitfield instructions do not seem to work a clean way. ! 65: */ ! 66: #undef TARGET_DEFAULT ! 67: #define TARGET_DEFAULT 3 ! 68: ! 69: #undef EXTRA_SECTIONS ! 70: #undef EXTRA_SECTION_FUNCTIONS ! 71: #undef READONLY_DATA_SECTION ! 72: #define READONLY_DATA_SECTION data_section ! 73: #undef SELECT_SECTION ! 74: #undef SELECT_RTX_SECTION ! 75: #define fini_section() while (0) ! 76: ! 77: #undef CTORS_SECTION_ASM_OP ! 78: #define CTORS_SECTION_ASM_OP "\tsection 15" ! 79: #undef DTORS_SECTION_ASM_OP ! 80: #define DTORS_SECTION_ASM_OP "\tsection 15" ! 81: #undef INIT_SECTION_ASM_OP ! 82: #define BSS_SECTION_ASM_OP "\tsection 14" ! 83: #undef TEXT_SECTION_ASM_OP ! 84: #define TEXT_SECTION_ASM_OP "\tsection 10" ! 85: #undef DATA_SECTION_ASM_OP ! 86: #define DATA_SECTION_ASM_OP "\tsection 15" ! 87: ! 88: ! 89: /* Don't try using XFmode. */ ! 90: #undef LONG_DOUBLE_TYPE_SIZE ! 91: #define LONG_DOUBLE_TYPE_SIZE 64 ! 92: ! 93: /* Define if you don't want extended real, but do want to use the ! 94: software floating point emulator for REAL_ARITHMETIC and ! 95: decimal <-> binary conversion. */ ! 96: #define REAL_ARITHMETIC ! 97: ! 98: #undef ASM_OUTPUT_SOURCE_FILENAME ! 99: #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NA) \ ! 100: do { fprintf ((FILE), "\t.file\t'%s'\n", (NA)); } while (0) ! 101: ! 102: /* Assembler pseudos to introduce constants of various size. */ ! 103: ! 104: #undef ASM_BYTE_OP ! 105: #define ASM_BYTE_OP "\tdc.b" ! 106: #undef ASM_LONG ! 107: #define ASM_LONG "\tdc.l" ! 108: ! 109: /* ! 110: * we don't seem to support any of: ! 111: * .globl ! 112: * .even ! 113: * .align ! 114: * .ascii ! 115: */ ! 116: #undef ASM_OUTPUT_SKIP ! 117: #define ASM_OUTPUT_SKIP(FILE,SIZE) \ ! 118: fprintf (FILE, "\tdcb.b %u,0\n", (SIZE)) ! 119: ! 120: #undef GLOBAL_ASM_OP ! 121: #define GLOBAL_ASM_OP "\txdef" ! 122: ! 123: #undef ASM_OUTPUT_ALIGN ! 124: #define ASM_OUTPUT_ALIGN(FILE,LOG) \ ! 125: if ((LOG) >= 1) \ ! 126: fprintf (FILE, "\tds.w 0\n"); ! 127: ! 128: ! 129: #define STRING_LIMIT (0) ! 130: #undef ASM_APP_ON ! 131: #define ASM_APP_ON "" ! 132: #undef ASM_APP_OFF ! 133: #define ASM_APP_OFF "" ! 134: /* ! 135: * dc.b 'hello, world!' ! 136: * dc.b 10,0 ! 137: * is how we have to output "hello, world!\n" ! 138: */ ! 139: #undef ASM_OUTPUT_ASCII ! 140: #define ASM_OUTPUT_ASCII(asm_out_file, p, thissize) \ ! 141: do { register int i, c, f=0, len=0; \ ! 142: for (i = 0; i < thissize; i++) { \ ! 143: c = p[i]; \ ! 144: if (c == '\'' || c < ' ' || c > 127) { \ ! 145: switch(f) { \ ! 146: case 0: /* need to output dc.b etc */ \ ! 147: fprintf(asm_out_file, "\tdc.b %d", c); \ ! 148: f=1; \ ! 149: break; \ ! 150: case 1: \ ! 151: fprintf(asm_out_file, ",%d", c); \ ! 152: break; \ ! 153: default: \ ! 154: /* close a string */ \ ! 155: fprintf(asm_out_file, "'\n\tdc.b %d", c); \ ! 156: f=1; \ ! 157: break; \ ! 158: } \ ! 159: } else { \ ! 160: switch(f) { \ ! 161: case 0: \ ! 162: fprintf(asm_out_file, "\tdc.b '%c", c); \ ! 163: f=2; \ ! 164: break; \ ! 165: case 2: \ ! 166: if (len >= 79) { \ ! 167: fprintf(asm_out_file, "'\n\tdc.b '%c", c); \ ! 168: len = 0; } \ ! 169: else \ ! 170: fprintf(asm_out_file, "%c", c); \ ! 171: break; \ ! 172: default: \ ! 173: len = 0; \ ! 174: fprintf(asm_out_file, "\n\tdc.b '%c", c); \ ! 175: f=2; \ ! 176: break; \ ! 177: } \ ! 178: } \ ! 179: len++; \ ! 180: } \ ! 181: if (f==2) \ ! 182: putc('\'', asm_out_file); \ ! 183: putc('\n', asm_out_file); } while (0) ! 184: ! 185: /* This is how to output an insn to push a register on the stack. ! 186: It need not be very fast code. */ ! 187: ! 188: #undef ASM_OUTPUT_REG_PUSH ! 189: #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ ! 190: fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO]) ! 191: ! 192: /* This is how to output an insn to pop a register from the stack. ! 193: It need not be very fast code. */ ! 194: ! 195: #undef ASM_OUTPUT_REG_POP ! 196: #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ ! 197: fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO]) ! 198: ! 199: ! 200: #define PUT_SDB_FUNCTION_START(LINE) \ ! 201: fprintf (asm_out_file, \ ! 202: "\t.def\t.bf%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ ! 203: SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! 204: ! 205: #define PUT_SDB_FUNCTION_END(LINE) \ ! 206: fprintf (asm_out_file, \ ! 207: "\t.def\t.ef%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ ! 208: SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! 209: ! 210: #define PUT_SDB_BLOCK_START(LINE) \ ! 211: fprintf (asm_out_file, \ ! 212: "\t.def\t.bb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ ! 213: SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! 214: ! 215: #define PUT_SDB_BLOCK_END(LINE) \ ! 216: fprintf (asm_out_file, \ ! 217: "\t.def\t.eb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ ! 218: SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! 219: ! 220: #define PUT_SDB_EPILOGUE_END(NAME) ! 221: ! 222: /* Output type in decimal not in octal as done in sdbout.c */ ! 223: #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%d%s", a, SDB_DELIM) ! 224: ! 225: #undef FUNCTION_PROLOGUE ! 226: #define FUNCTION_PROLOGUE(FILE, SIZE) \ ! 227: { \ ! 228: register int regno; \ ! 229: register int mask = 0; \ ! 230: int num_saved_regs = 0, first = 1; \ ! 231: extern char call_used_regs[]; \ ! 232: int fsize = ((SIZE) + 3) & -4; \ ! 233: \ ! 234: \ ! 235: if (frame_pointer_needed) \ ! 236: { \ ! 237: /* Adding negative number is faster on the 68040. */ \ ! 238: if (fsize < 0x8000 && !TARGET_68040) \ ! 239: { \ ! 240: fprintf (FILE, "\tlink %s,#%d\n", \ ! 241: reg_names[FRAME_POINTER_REGNUM], -fsize); \ ! 242: } \ ! 243: else if (TARGET_68020) \ ! 244: { \ ! 245: fprintf (FILE, "\tlink %s,#%d\n", \ ! 246: reg_names[FRAME_POINTER_REGNUM], -fsize); \ ! 247: } \ ! 248: else \ ! 249: { \ ! 250: fprintf (FILE, "\tlink %s,#0\n\tadd.l #%d,sp\n", \ ! 251: reg_names[FRAME_POINTER_REGNUM], -fsize); \ ! 252: } \ ! 253: } \ ! 254: else if (fsize) \ ! 255: { \ ! 256: /* Adding negative number is faster on the 68040. */ \ ! 257: if (fsize + 4 < 0x8000) \ ! 258: { \ ! 259: fprintf (FILE, "\tadd.w #%d,sp\n", - (fsize + 4)); \ ! 260: } \ ! 261: else \ ! 262: { \ ! 263: fprintf (FILE, "\tadd.l #%d,sp\n", - (fsize + 4)); \ ! 264: } \ ! 265: } \ ! 266: for (regno = 23; regno >= 16; regno--) \ ! 267: if (regs_ever_live[regno] && ! call_used_regs[regno]) \ ! 268: if (first) { \ ! 269: fprintf (FILE, "\tfmovem.x %s", reg_names[regno]); \ ! 270: first = 0; \ ! 271: } \ ! 272: else fprintf (FILE, "/%s", reg_names[regno]); \ ! 273: if (!first) fprintf (FILE, ",-(sp)\n"); \ ! 274: \ ! 275: mask = 0; \ ! 276: for (regno = 0; regno < 16; regno++) \ ! 277: if (regs_ever_live[regno] && ! call_used_regs[regno]) \ ! 278: { \ ! 279: mask |= 1 << (15 - regno); \ ! 280: num_saved_regs++; \ ! 281: } \ ! 282: if (frame_pointer_needed) \ ! 283: { \ ! 284: mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM)); \ ! 285: num_saved_regs--; \ ! 286: } \ ! 287: \ ! 288: \ ! 289: if (num_saved_regs <= 2) \ ! 290: { \ ! 291: /* Store each separately in the same order moveml uses. \ ! 292: Using two movel instructions instead of a single moveml \ ! 293: is about 15% faster for the 68020 and 68030 at no expense \ ! 294: in code size */ \ ! 295: \ ! 296: int i; \ ! 297: \ ! 298: /* Undo the work from above. */ \ ! 299: for (i = 0; i< 16; i++) \ ! 300: if (mask & (1 << i)) \ ! 301: fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[15 - i]); \ ! 302: } \ ! 303: else if (mask) \ ! 304: { \ ! 305: first = 1; \ ! 306: for (regno = 0; regno < 16; regno++) \ ! 307: if (mask & (1 << regno)) \ ! 308: if (first) { \ ! 309: fprintf (FILE, "\tmovem.l %s", reg_names[15 - regno]); \ ! 310: first = 0; \ ! 311: } \ ! 312: else fprintf (FILE, "/%s", reg_names[15 - regno]); \ ! 313: fprintf (FILE, ",-(sp)\n"); \ ! 314: } \ ! 315: if (flag_pic && current_function_uses_pic_offset_table) \ ! 316: { \ ! 317: fprintf (FILE, "\tmove.l #__GLOBAL_OFFSET_TABLE_, %s\n", \ ! 318: reg_names[PIC_OFFSET_TABLE_REGNUM]); \ ! 319: fprintf (FILE, "\tlea.l (pc,%s.l),%s\n", \ ! 320: reg_names[PIC_OFFSET_TABLE_REGNUM], \ ! 321: reg_names[PIC_OFFSET_TABLE_REGNUM]); \ ! 322: } \ ! 323: } ! 324: ! 325: ! 326: #undef FUNCTION_EPILOGUE ! 327: #define FUNCTION_EPILOGUE(FILE, SIZE) \ ! 328: { \ ! 329: register int regno; \ ! 330: register int mask, fmask; \ ! 331: register int nregs; \ ! 332: int offset, foffset, fpoffset, first = 1; \ ! 333: extern char call_used_regs[]; \ ! 334: int fsize = ((SIZE) + 3) & -4; \ ! 335: int big = 0; \ ! 336: rtx insn = get_last_insn (); \ ! 337: \ ! 338: /* If the last insn was a BARRIER, we don't have to write any code. */ \ ! 339: if (GET_CODE (insn) == NOTE) \ ! 340: insn = prev_nonnote_insn (insn); \ ! 341: if (insn && GET_CODE (insn) == BARRIER) \ ! 342: { \ ! 343: /* Output just a no-op so that debuggers don't get confused \ ! 344: about which function the pc is in at this address. */ \ ! 345: fprintf (FILE, "\tnop\n"); \ ! 346: return; \ ! 347: } \ ! 348: \ ! 349: nregs = 0; fmask = 0; fpoffset = 0; \ ! 350: for (regno = 16; regno < 24; regno++) \ ! 351: if (regs_ever_live[regno] && ! call_used_regs[regno]) \ ! 352: { \ ! 353: nregs++; \ ! 354: fmask |= 1 << (23 - regno); \ ! 355: } \ ! 356: foffset = fpoffset + nregs * 12; \ ! 357: nregs = 0; mask = 0; \ ! 358: if (frame_pointer_needed) \ ! 359: regs_ever_live[FRAME_POINTER_REGNUM] = 0; \ ! 360: for (regno = 0; regno < 16; regno++) \ ! 361: if (regs_ever_live[regno] && ! call_used_regs[regno]) \ ! 362: { \ ! 363: nregs++; \ ! 364: mask |= 1 << regno; \ ! 365: } \ ! 366: offset = foffset + nregs * 4; \ ! 367: if (offset + fsize >= 0x8000 \ ! 368: && frame_pointer_needed \ ! 369: && (mask || fmask || fpoffset)) \ ! 370: { \ ! 371: fprintf (FILE, "\tmove.l #%d,a0\n", -fsize); \ ! 372: fsize = 0, big = 1; \ ! 373: } \ ! 374: if (nregs <= 2) \ ! 375: { \ ! 376: /* Restore each separately in the same order moveml does. \ ! 377: Using two movel instructions instead of a single moveml \ ! 378: is about 15% faster for the 68020 and 68030 at no expense \ ! 379: in code size. */ \ ! 380: \ ! 381: int i; \ ! 382: \ ! 383: /* Undo the work from above. */ \ ! 384: for (i = 0; i< 16; i++) \ ! 385: if (mask & (1 << i)) \ ! 386: { \ ! 387: if (big) \ ! 388: { \ ! 389: fprintf (FILE, "\tmove.l -%d(%s,a0.l),%s\n", \ ! 390: offset + fsize, \ ! 391: reg_names[FRAME_POINTER_REGNUM], \ ! 392: reg_names[i]); \ ! 393: } \ ! 394: else if (! frame_pointer_needed) \ ! 395: { \ ! 396: fprintf (FILE, "\tmove.l (sp)+,%s\n", \ ! 397: reg_names[i]); \ ! 398: } \ ! 399: else \ ! 400: { \ ! 401: fprintf (FILE, "\tmove.l -%d(%s),%s\n", \ ! 402: offset + fsize, \ ! 403: reg_names[FRAME_POINTER_REGNUM], \ ! 404: reg_names[i]); \ ! 405: } \ ! 406: offset = offset - 4; \ ! 407: } \ ! 408: } \ ! 409: else if (mask) \ ! 410: { \ ! 411: first = 1; \ ! 412: for (regno = 0; regno < 16; regno++) \ ! 413: if (mask & (1 << regno)) \ ! 414: if (first && big) { \ ! 415: fprintf (FILE, "\tmovem.l -%d(%s,a0.l),%s", \ ! 416: offset + fsize, \ ! 417: reg_names[FRAME_POINTER_REGNUM], \ ! 418: reg_names[regno]); \ ! 419: first = 0; \ ! 420: } \ ! 421: else if (first && ! frame_pointer_needed) { \ ! 422: fprintf (FILE, "\tmovem.l (sp)+,%s", \ ! 423: offset + fsize, \ ! 424: reg_names[FRAME_POINTER_REGNUM], \ ! 425: reg_names[regno]); \ ! 426: first = 0; \ ! 427: } \ ! 428: else if (first) { \ ! 429: fprintf (FILE, "\tmovem.l -%d(%s),%s", \ ! 430: offset + fsize, \ ! 431: reg_names[FRAME_POINTER_REGNUM], \ ! 432: reg_names[regno]); \ ! 433: first = 0; \ ! 434: } \ ! 435: else \ ! 436: fprintf (FILE, "/%s", reg_names[regno]); \ ! 437: fprintf (FILE, "\n"); \ ! 438: } \ ! 439: if (fmask) \ ! 440: { \ ! 441: first = 1; \ ! 442: for (regno = 16; regno < 24; regno++) \ ! 443: if (fmask & (1 << (23 - regno))) \ ! 444: if (first && big) { \ ! 445: fprintf (FILE, "\tfmovem.x -%d(%s,a0.l),%s", \ ! 446: foffset + fsize, \ ! 447: reg_names[FRAME_POINTER_REGNUM], \ ! 448: reg_names[regno]); \ ! 449: first = 0; \ ! 450: } \ ! 451: else if (first && ! frame_pointer_needed) { \ ! 452: fprintf (FILE, "\tfmovem.x (sp)+,%s", \ ! 453: foffset + fsize, \ ! 454: reg_names[FRAME_POINTER_REGNUM], \ ! 455: reg_names[regno]); \ ! 456: first = 0; \ ! 457: } \ ! 458: else if (first) { \ ! 459: fprintf (FILE, "\tfmovem.x -%d(%s),%s", \ ! 460: foffset + fsize, \ ! 461: reg_names[FRAME_POINTER_REGNUM], \ ! 462: reg_names[regno]); \ ! 463: first = 0; \ ! 464: } \ ! 465: else fprintf (FILE, "/%s", reg_names[regno]); \ ! 466: fprintf (FILE, "\n"); \ ! 467: } \ ! 468: if (frame_pointer_needed) \ ! 469: fprintf (FILE, "\tunlk %s\n", \ ! 470: reg_names[FRAME_POINTER_REGNUM]); \ ! 471: else if (fsize) \ ! 472: { \ ! 473: if (fsize + 4 < 0x8000) \ ! 474: { \ ! 475: fprintf (FILE, "\tadd.w #%d,sp\n", fsize + 4); \ ! 476: } \ ! 477: else \ ! 478: { \ ! 479: fprintf (FILE, "\tadd.l #%d,sp\n", fsize + 4); \ ! 480: } \ ! 481: } \ ! 482: if (current_function_pops_args) \ ! 483: fprintf (FILE, "\trtd #%d\n", current_function_pops_args); \ ! 484: else \ ! 485: fprintf (FILE, "\trts\n"); \ ! 486: } ! 487: ! 488: /* Translate Motorola opcodes such as `jbeq' ! 489: into VERSAdos opcodes such as `beq'. ! 490: Change `fbeq' to `fbseq', `fbne' to `fbsneq'. ! 491: */ ! 492: ! 493: #undef ASM_OUTPUT_OPCODE ! 494: #define ASM_OUTPUT_OPCODE(FILE, PTR) \ ! 495: { if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \ ! 496: { ++(PTR); \ ! 497: while (*(PTR) != ' ') \ ! 498: { putc (*(PTR), (FILE)); ++(PTR); } \ ! 499: } \ ! 500: else if ((PTR)[0] == 'f') \ ! 501: { \ ! 502: if (!strncmp ((PTR), "fbeq", 4)) \ ! 503: { fprintf ((FILE), "fbseq"); (PTR) += 4; } \ ! 504: else if (!strncmp ((PTR), "fbne", 4)) \ ! 505: { fprintf ((FILE), "fbsneq"); (PTR) += 4; } \ ! 506: } \ ! 507: else if ((PTR)[0] == 'b' && (PTR)[1] == 'f') \ ! 508: { \ ! 509: char *s; \ ! 510: if ((s = (char*)strchr ((PTR), '{'))) \ ! 511: while (*s != '}') { \ ! 512: if (*s == 'b') \ ! 513: /* hack, I replace it with R ie nothing */ \ ! 514: *s = '0'; \ ! 515: s++; } \ ! 516: } \ ! 517: } ! 518: ! 519: /* This is how to output a `long double' extended real constant. */ ! 520: #undef ASM_OUTPUT_LONG_DOUBLE ! 521: #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ ! 522: do { long l[3]; \ ! 523: REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ ! 524: if (sizeof (int) == sizeof (long)) \ ! 525: fprintf (FILE, "\tdc.l $%x,$%x,$%x\n", l[0], l[1], l[2]); \ ! 526: else \ ! 527: fprintf (FILE, "\tdc.l $%lx,$%lx,$%lx\n", l[0], l[1], l[2]); \ ! 528: } while (0) ! 529: ! 530: #undef ASM_OUTPUT_DOUBLE ! 531: #if 0 ! 532: #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! 533: do { char dstr[30]; \ ! 534: REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! 535: fprintf (FILE, "\tdc.d %s\n", dstr); \ ! 536: } while (0) ! 537: #endif ! 538: #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! 539: do { long l[2]; \ ! 540: REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ ! 541: fprintf (FILE, "\tdc.l $%x,$%x\n", l[0], l[1]); \ ! 542: } while (0) ! 543: ! 544: ! 545: /* This is how to output an assembler line defining a `float' constant. */ ! 546: #undef ASM_OUTPUT_FLOAT ! 547: #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ ! 548: do { long l; \ ! 549: REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ ! 550: if (sizeof (int) == sizeof (long)) \ ! 551: fprintf (FILE, "\tdc.l $%x\n", l); \ ! 552: else \ ! 553: fprintf (FILE, "\tdc.l $%lx\n", l); \ ! 554: } while (0) ! 555: ! 556: /* This is how to output an assembler line defining an `int' constant. */ ! 557: #undef ASM_OUTPUT_INT ! 558: #define ASM_OUTPUT_INT(FILE,VALUE) \ ! 559: ( fprintf (FILE, "\tdc.l "), \ ! 560: output_addr_const (FILE, (VALUE)), \ ! 561: fprintf (FILE, "\n")) ! 562: ! 563: /* Likewise for `char' and `short' constants. */ ! 564: #undef ASM_OUTPUT_SHORT ! 565: #define ASM_OUTPUT_SHORT(FILE,VALUE) \ ! 566: ( fprintf (FILE, "\tdc.w "), \ ! 567: output_addr_const (FILE, (VALUE)), \ ! 568: fprintf (FILE, "\n")) ! 569: ! 570: #undef ASM_OUTPUT_CHAR ! 571: #define ASM_OUTPUT_CHAR(FILE,VALUE) \ ! 572: ( fprintf (FILE, "\tdc.b "), \ ! 573: output_addr_const (FILE, (VALUE)), \ ! 574: fprintf (FILE, "\n")) ! 575: ! 576: /* This is how to output an assembler line for a numeric constant byte. */ ! 577: #undef ASM_OUTPUT_BYTE ! 578: #define ASM_OUTPUT_BYTE(FILE,VALUE) \ ! 579: fprintf (FILE, "\tdc.b $%x\n", (VALUE)) ! 580: ! 581: /* This is how to output an element of a case-vector that is absolute. ! 582: (The 68000 does not use such vectors, ! 583: but we must define this macro anyway.) */ ! 584: #undef ASM_OUTPUT_ADDR_VEC_ELT ! 585: #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ ! 586: asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE) ! 587: ! 588: /* This is how to output an element of a case-vector that is relative. */ ! 589: #undef ASM_OUTPUT_ADDR_DIFF_ELT ! 590: #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ ! 591: asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL) ! 592: ! 593: /* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to ! 594: keep switch tables in the text section. */ ! 595: #define JUMP_TABLES_IN_TEXT_SECTION 1 ! 596: ! 597: /* Output a float value (represented as a C double) as an immediate operand. ! 598: This macro is a 68k-specific macro. */ ! 599: #undef ASM_OUTPUT_FLOAT_OPERAND ! 600: #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \ ! 601: do { \ ! 602: if (CODE == 'f') \ ! 603: { \ ! 604: char dstr[30]; \ ! 605: REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr); \ ! 606: asm_fprintf ((FILE), "%I%s", dstr); \ ! 607: } \ ! 608: else \ ! 609: { \ ! 610: long l; \ ! 611: REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ ! 612: if (sizeof (int) == sizeof (long)) \ ! 613: asm_fprintf ((FILE), "%I$%x", l); \ ! 614: else \ ! 615: asm_fprintf ((FILE), "%I$%lx", l); \ ! 616: } \ ! 617: } while (0) ! 618: ! 619: /* Output a double value (represented as a C double) as an immediate operand. ! 620: This macro is a 68k-specific macro. */ ! 621: #undef ASM_OUTPUT_DOUBLE_OPERAND ! 622: #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \ ! 623: do { char dstr[30]; \ ! 624: REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! 625: asm_fprintf (FILE, "%I%s", dstr); \ ! 626: } while (0) ! 627: ! 628: /* Note, long double immediate operands are not actually ! 629: generated by m68k.md. */ ! 630: #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND ! 631: #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE) \ ! 632: do { char dstr[30]; \ ! 633: REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! 634: asm_fprintf (FILE, "%I%s", dstr); \ ! 635: } while (0) ! 636: ! 637: #undef ASM_OUTPUT_COMMON ! 638: #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ ! 639: ( fputs ("\t.comm ", (FILE)), \ ! 640: assemble_name ((FILE), (NAME)), \ ! 641: fprintf ((FILE), ",%u\n", (ROUNDED))) ! 642: ! 643: #undef ASM_OUTPUT_LOCAL ! 644: #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ ! 645: do { \ ! 646: int align = exact_log2 (ROUNDED); \ ! 647: /*fprintf ((FILE), "\tsection 14\n"); */ \ ! 648: data_section (); \ ! 649: ASM_OUTPUT_ALIGN ((FILE), align) \ ! 650: ASM_OUTPUT_LABEL ((FILE), (NAME)); \ ! 651: fprintf ((FILE), "\tdcb.b %u,0\n", (ROUNDED)); \ ! 652: /* fprintf ((FILE), "\tsection 10\n"); */ \ ! 653: } while (0) ! 654: ! 655: #undef PRINT_OPERAND_ADDRESS ! 656: #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ ! 657: { register rtx reg1, reg2, breg, ireg; \ ! 658: register rtx addr = ADDR; \ ! 659: rtx offset; \ ! 660: switch (GET_CODE (addr)) \ ! 661: { \ ! 662: case REG: \ ! 663: fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \ ! 664: break; \ ! 665: case PRE_DEC: \ ! 666: fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \ ! 667: break; \ ! 668: case POST_INC: \ ! 669: fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \ ! 670: break; \ ! 671: case PLUS: \ ! 672: reg1 = 0; reg2 = 0; \ ! 673: ireg = 0; breg = 0; \ ! 674: offset = 0; \ ! 675: if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \ ! 676: { \ ! 677: offset = XEXP (addr, 0); \ ! 678: addr = XEXP (addr, 1); \ ! 679: } \ ! 680: else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \ ! 681: { \ ! 682: offset = XEXP (addr, 1); \ ! 683: addr = XEXP (addr, 0); \ ! 684: } \ ! 685: if (GET_CODE (addr) != PLUS) ; \ ! 686: else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \ ! 687: { \ ! 688: reg1 = XEXP (addr, 0); \ ! 689: addr = XEXP (addr, 1); \ ! 690: } \ ! 691: else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \ ! 692: { \ ! 693: reg1 = XEXP (addr, 1); \ ! 694: addr = XEXP (addr, 0); \ ! 695: } \ ! 696: else if (GET_CODE (XEXP (addr, 0)) == MULT) \ ! 697: { \ ! 698: reg1 = XEXP (addr, 0); \ ! 699: addr = XEXP (addr, 1); \ ! 700: } \ ! 701: else if (GET_CODE (XEXP (addr, 1)) == MULT) \ ! 702: { \ ! 703: reg1 = XEXP (addr, 1); \ ! 704: addr = XEXP (addr, 0); \ ! 705: } \ ! 706: else if (GET_CODE (XEXP (addr, 0)) == REG) \ ! 707: { \ ! 708: reg1 = XEXP (addr, 0); \ ! 709: addr = XEXP (addr, 1); \ ! 710: } \ ! 711: else if (GET_CODE (XEXP (addr, 1)) == REG) \ ! 712: { \ ! 713: reg1 = XEXP (addr, 1); \ ! 714: addr = XEXP (addr, 0); \ ! 715: } \ ! 716: if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \ ! 717: || GET_CODE (addr) == SIGN_EXTEND) \ ! 718: { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \ ! 719: /* for OLD_INDEXING \ ! 720: else if (GET_CODE (addr) == PLUS) \ ! 721: { \ ! 722: if (GET_CODE (XEXP (addr, 0)) == REG) \ ! 723: { \ ! 724: reg2 = XEXP (addr, 0); \ ! 725: addr = XEXP (addr, 1); \ ! 726: } \ ! 727: else if (GET_CODE (XEXP (addr, 1)) == REG) \ ! 728: { \ ! 729: reg2 = XEXP (addr, 1); \ ! 730: addr = XEXP (addr, 0); \ ! 731: } \ ! 732: } \ ! 733: */ \ ! 734: if (offset != 0) { if (addr != 0) abort (); addr = offset; } \ ! 735: if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \ ! 736: || GET_CODE (reg1) == MULT)) \ ! 737: || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \ ! 738: { breg = reg2; ireg = reg1; } \ ! 739: else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \ ! 740: { breg = reg1; ireg = reg2; } \ ! 741: if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \ ! 742: { int scale = 1; \ ! 743: if (GET_CODE (ireg) == MULT) \ ! 744: { scale = INTVAL (XEXP (ireg, 1)); \ ! 745: ireg = XEXP (ireg, 0); } \ ! 746: if (GET_CODE (ireg) == SIGN_EXTEND) \ ! 747: fprintf (FILE, "(.L%d,pc,%s.w", \ ! 748: CODE_LABEL_NUMBER (XEXP (addr, 0)), \ ! 749: reg_names[REGNO (XEXP (ireg, 0))]); \ ! 750: else \ ! 751: fprintf (FILE, "(.L%d,pc,%s.l", \ ! 752: CODE_LABEL_NUMBER (XEXP (addr, 0)), \ ! 753: reg_names[REGNO (ireg)]); \ ! 754: if (scale != 1) fprintf (FILE, "*%d", scale); \ ! 755: putc (')', FILE); \ ! 756: break; } \ ! 757: if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF \ ! 758: && ! (flag_pic && breg == pic_offset_table_rtx)) \ ! 759: { \ ! 760: fprintf (FILE, "(.L%d,pc,%s.l", \ ! 761: CODE_LABEL_NUMBER (XEXP (addr, 0)), \ ! 762: reg_names[REGNO (breg)]); \ ! 763: putc (')', FILE); \ ! 764: break; } \ ! 765: if (ireg != 0 || breg != 0) \ ! 766: { int scale = 1; \ ! 767: if (breg == 0) \ ! 768: abort (); \ ! 769: putc ('(', FILE); \ ! 770: if (addr != 0) \ ! 771: { \ ! 772: output_addr_const (FILE, addr); \ ! 773: putc (',', FILE); \ ! 774: } \ ! 775: fprintf (FILE, "%s", reg_names[REGNO (breg)]); \ ! 776: if (ireg != 0) \ ! 777: putc (',', FILE); \ ! 778: if (ireg != 0 && GET_CODE (ireg) == MULT) \ ! 779: { scale = INTVAL (XEXP (ireg, 1)); \ ! 780: ireg = XEXP (ireg, 0); } \ ! 781: if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \ ! 782: fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \ ! 783: else if (ireg != 0) \ ! 784: fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \ ! 785: if (scale != 1) fprintf (FILE, "*%d", scale); \ ! 786: putc (')', FILE); \ ! 787: break; \ ! 788: } \ ! 789: else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \ ! 790: { fprintf (FILE, "(.L%d,pc,%s.w)", \ ! 791: CODE_LABEL_NUMBER (XEXP (addr, 0)), \ ! 792: reg_names[REGNO (reg1)]); \ ! 793: break; } \ ! 794: default: \ ! 795: if (GET_CODE (addr) == CONST_INT \ ! 796: && INTVAL (addr) < 0x8000 \ ! 797: && INTVAL (addr) >= -0x8000) \ ! 798: fprintf (FILE, "%d.w", INTVAL (addr)); \ ! 799: else \ ! 800: output_addr_const (FILE, addr); \ ! 801: }} ! 802: ! 803: ! 804: #endif /* ! use gas */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.