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