|
|
1.1.1.3 ! root 1: /* Definitions of target machine for GNU compiler. SONY NEWS-OS 4 version. 1.1 root 2: Copyright (C) 1987, 1989 Free Software Foundation, Inc. 3: 4: This file is part of GNU CC. 5: 6: GNU CC is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU CC is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14: GNU General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU CC; see the file COPYING. If not, write to 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19: 20: #ifndef USE_GAS 21: /* This controls conditionals in m68k.h. */ 22: #define MOTOROLA /* Use Motorola syntax rather than "MIT" */ 23: #define SGS_NO_LI /* Suppress jump table label usage */ 24: #endif 25: 26: #include "m68k.h" 27: 28: /* See m68k.h. 7 means 68020 with 68881. */ 29: 30: #define TARGET_DEFAULT 7 31: 32: /* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified. 33: This will control the use of inline 68881 insns in certain macros. */ 34: 35: #define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__}" 36: 37: /* Names to predefine in the preprocessor for this target machine. */ 38: /* These are the ones defined by Sony, plus mc68000 for uniformity with 39: GCC on other 68000 systems. */ 40: 41: #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews700" 42: 43: /* These conditionals tested for different submodels, 44: but they were incorrect since they tested the host rather than the target. 45: The choice of model shouldn't actually matter. */ 46: 47: #if 0 48: #ifdef news800 49: #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews800" 50: #endif 51: #ifdef news900 52: #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews900" 53: #endif 54: #ifdef news1500 55: #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1500" 56: #endif 57: #ifdef news1700 58: #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1700" 59: #endif 60: #ifdef news1800 61: #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1800" 62: #endif 63: #ifdef news1900 64: #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1900" 65: #endif 66: #endif 67: 68: /* Link with libg.a when debugging, for dbx's sake. */ 69: 70: #define LIB_SPEC "%{g:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} " 71: 72: /* This is BSD, so it wants DBX format. */ 73: 74: #define DBX_DEBUGGING_INFO 75: 76: #if 0 77: /* This is to be compatible with types.h. 78: It was found to be necessary with Newsos 3. */ 79: 80: #define SIZE_TYPE "long int" 81: #endif 82: 83: /* Override parts of m68k.h to fit Sony's assembler syntax. */ 84: 85: #undef BIGGEST_ALIGNMENT 86: #undef CALL_USED_REGISTERS 87: #undef FUNCTION_VALUE 88: #undef LIBCALL_VALUE 89: #undef FUNCTION_PROFILER 90: 91: #ifdef MOTOROLA 92: #undef FUNCTION_PROLOGUE 93: #undef FUNCTION_EPILOGUE 94: #undef REGISTER_NAMES 95: #undef ASM_OUTPUT_REG_PUSH 96: #undef ASM_OUTPUT_REG_POP 97: #undef ASM_OUTPUT_DOUBLE 98: #undef ASM_OUTPUT_SKIP 99: #undef ASM_FORMAT_PRIVATE_NAME 100: #undef PRINT_OPERAND 101: #undef PRINT_OPERAND_ADDRESS 102: #endif 103: 104: #undef ASM_OUTPUT_ALIGN 105: 106: /* There is no point aligning anything to a rounder boundary than this. */ 107: #define BIGGEST_ALIGNMENT 32 108: 109: /* A bitfield declared as `int' forces `int' alignment for the struct. */ 110: #define PCC_BITFIELD_TYPE_MATTERS 1 111: 112: /* NEWS makes d2, d3, fp2 and fp3 unsaved registers, unlike the Sun system. */ 113: 114: #define CALL_USED_REGISTERS \ 115: {1, 1, 1, 1, 0, 0, 0, 0, \ 116: 1, 1, 0, 0, 0, 0, 0, 1, \ 117: 1, 1, 1, 1, 0, 0, 0, 0} 118: 119: /* NEWS returns floats and doubles in fp0, not d0/d1. */ 120: 121: #define FUNCTION_VALUE(VALTYPE,FUNC) LIBCALL_VALUE (TYPE_MODE (VALTYPE)) 122: 123: #define LIBCALL_VALUE(MODE) \ 124: gen_rtx (REG, (MODE), ((TARGET_68881 && ((MODE) == SFmode || (MODE) == DFmode)) ? 16 : 0)) 125: 126: #define ASM_OUTPUT_ALIGN(FILE,LOG) \ 127: fprintf (FILE, "\t.align %d\n", (LOG)) 128: 129: #ifdef MOTOROLA 130: 131: /* Don't try to define `gcc_compiled.' since the assembler does not 132: accept symbols with periods. This is no real loss since GDB only 133: really needs it for parms passed in registers. */ 134: #define ASM_IDENTIFY_GCC(FILE) 135: 136: #define FUNCTION_PROLOGUE(FILE, SIZE) \ 137: { register int regno; \ 138: register int mask = 0; \ 139: extern char call_used_regs[]; \ 140: int fsize = ((SIZE) + 3) & -4; \ 141: if (frame_pointer_needed) \ 142: { if (fsize < 0x8000) \ 143: fprintf (FILE, "\tlink fp,#%d\n", -fsize); \ 144: else if (TARGET_68020) \ 145: fprintf (FILE, "\tlink.l fp,#%d\n", -fsize); \ 146: else \ 1.1.1.3 ! root 147: fprintf (FILE, "\tlink fp,#0\n\tsub.l #%d,sp\n", fsize);\ ! 148: } \ ! 149: else if (fsize) \ ! 150: { \ ! 151: int amt = fsize + 4; \ ! 152: /* Adding negative number is faster on the 68040. */ \ ! 153: if (fsize + 4 < 0x8000) \ ! 154: asm_fprintf (FILE, "\tadd.w %0I%d,%Rsp\n", - amt); \ ! 155: else \ ! 156: asm_fprintf (FILE, "\tadd.l %0I%d,%Rsp\n", - amt); \ ! 157: } \ 1.1 root 158: for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++) \ 159: if (regs_ever_live[regno] && ! call_used_regs[regno]) \ 160: mask |= 1 << (regno - 16); \ 161: if (mask != 0) \ 162: fprintf (FILE, "\tfmovem.x #0x%x,-(sp)\n", mask & 0xff); \ 163: mask = 0; \ 164: for (regno = 0; regno < 16; regno++) \ 165: if (regs_ever_live[regno] && ! call_used_regs[regno]) \ 166: mask |= 1 << (15 - regno); \ 167: if (frame_pointer_needed) \ 168: mask &= ~ (1 << (15-FRAME_POINTER_REGNUM)); \ 169: if (exact_log2 (mask) >= 0) \ 170: fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]); \ 171: else if (mask) fprintf (FILE, "\tmovem.l #0x%x,-(sp)\n", mask); } 172: 173: #define FUNCTION_PROFILER(FILE, LABEL_NO) \ 174: fprintf (FILE, "\tmove.l #LP%d,d0\n\tjsr mcount\n", (LABEL_NO)); 175: 176: #define FUNCTION_EPILOGUE(FILE, SIZE) \ 177: { register int regno; \ 178: register int mask, fmask; \ 179: register int nregs; \ 180: int offset, foffset; \ 181: extern char call_used_regs[]; \ 182: int fsize = ((SIZE) + 3) & -4; \ 183: int big = 0; \ 184: nregs = 0; fmask = 0; \ 185: for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++) \ 186: if (regs_ever_live[regno] && ! call_used_regs[regno]) \ 187: { nregs++; fmask |= 1 << (23 - regno); } \ 188: foffset = nregs * 12; \ 189: nregs = 0; mask = 0; \ 190: if (frame_pointer_needed) regs_ever_live[FRAME_POINTER_REGNUM] = 0; \ 191: for (regno = 0; regno < 16; regno++) \ 192: if (regs_ever_live[regno] && ! call_used_regs[regno]) \ 193: { nregs++; mask |= 1 << regno; } \ 194: offset = foffset + nregs * 4; \ 195: if (offset + fsize >= 0x8000 \ 196: && frame_pointer_needed \ 197: && (mask || fmask)) \ 198: { fprintf (FILE, "\tmove.l #%d,a0\n", -fsize); \ 199: fsize = 0, big = 1; } \ 200: if (exact_log2 (mask) >= 0) { \ 201: if (big) \ 202: fprintf (FILE, "\tmove.l (-%d,fp,a0.l),%s\n", \ 203: offset + fsize, reg_names[exact_log2 (mask)]); \ 204: else if (! frame_pointer_needed) \ 205: fprintf (FILE, "\tmove.l (sp)+,%s\n", \ 206: reg_names[exact_log2 (mask)]); \ 207: else \ 208: fprintf (FILE, "\tmove.l (-%d,fp),%s\n", \ 209: offset + fsize, reg_names[exact_log2 (mask)]); } \ 210: else if (mask) { \ 211: if (big) \ 212: fprintf (FILE, "\tmovem.l (-%d,fp,a0.l),#0x%x\n", \ 213: offset + fsize, mask); \ 214: else if (! frame_pointer_needed) \ 215: fprintf (FILE, "\tmovem.l (sp)+,#0x%x\n", mask); \ 216: else \ 217: fprintf (FILE, "\tmovem.l (-%d,fp),#0x%x\n", \ 218: offset + fsize, mask); } \ 219: if (fmask) { \ 220: if (big) \ 221: fprintf (FILE, "\tfmovem.x (-%d,fp,a0.l),#0x%x\n", \ 222: foffset + fsize, fmask); \ 223: else if (! frame_pointer_needed) \ 224: fprintf (FILE, "\tfmovem.x (sp)+,#0x%x\n", fmask); \ 225: else \ 226: fprintf (FILE, "\tfmovem.x (-%d,fp),#0x%x\n", \ 227: foffset + fsize, fmask); } \ 228: if (frame_pointer_needed) \ 229: fprintf (FILE, "\tunlk fp\n"); \ 1.1.1.3 ! root 230: else if (fsize) \ ! 231: { \ ! 232: if (fsize + 4 < 0x8000) \ ! 233: fprintf (FILE, "\tadd.w #%d,sp\n", fsize + 4); \ ! 234: else \ ! 235: fprintf (FILE, "\tadd.l #%d,sp\n", fsize + 4); \ ! 236: } \ 1.1 root 237: if (current_function_pops_args) \ 238: fprintf (FILE, "\trtd #%d\n", current_function_pops_args); \ 239: else fprintf (FILE, "\trts\n"); } 240: 241: /* Difference from m68k.h is in `fp' instead of `a6'. */ 242: 243: #define REGISTER_NAMES \ 244: {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \ 245: "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \ 246: "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7"} 247: 248: /* This is how to output an insn to push a register on the stack. 249: It need not be very fast code. */ 250: 251: #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ 252: fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO]) 253: 254: /* This is how to output an insn to pop a register from the stack. 255: It need not be very fast code. */ 256: 257: #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ 258: fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO]) 259: 260: #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ 261: fprintf (FILE, "\t.double 0d%.20e\n", (VALUE)) 262: 263: #define ASM_OUTPUT_SKIP(FILE,SIZE) \ 264: fprintf (FILE, "\t.space %u\n", (SIZE)) 265: 1.1.1.3 ! root 266: #if 0 ! 267: /* The NEWS assembler in version 3.4 complains about fmove.d, but this ! 268: macro proved not to work right. 3.4 is old, so forget about it. */ ! 269: #define ASM_OUTPUT_OPCODE(FILE, STRING) \ ! 270: { \ ! 271: if (!strncmp (STRING, "fmove.d", 7) \ ! 272: && CONSTANT_P (operands[1])) \ ! 273: { \ ! 274: fprintf (FILE, "fmove.x"); \ ! 275: STRING += 7; \ ! 276: } \ ! 277: } ! 278: #endif ! 279: 1.1 root 280: /* Store in OUTPUT a string (made with alloca) containing 281: an assembler-name for a local static variable named NAME. 282: LABELNO is an integer which is different for each call. */ 283: 284: #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ 285: ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 13), \ 286: sprintf ((OUTPUT), "%s$$$%d", (NAME), (LABELNO))) 287: 288: #define PRINT_OPERAND(FILE, X, CODE) \ 289: { if (CODE == '.') fprintf (FILE, "."); \ 290: else if (CODE == '#') fprintf (FILE, "#"); \ 291: else if (CODE == '-') fprintf (FILE, "-(sp)"); \ 292: else if (CODE == '+') fprintf (FILE, "(sp)+"); \ 293: else if (CODE == '@') fprintf (FILE, "(sp)"); \ 1.1.1.2 root 294: else if (CODE == '!') fprintf (FILE, "fpcr"); \ 1.1 root 295: else if (CODE == '$') {if (TARGET_68040_ONLY) fprintf (FILE, "s");} \ 296: else if (CODE == '&') {if (TARGET_68040_ONLY) fprintf (FILE, "d");} \ 297: else if (GET_CODE (X) == REG) \ 298: fprintf (FILE, "%s", reg_names[REGNO (X)]); \ 299: else if (GET_CODE (X) == MEM) \ 300: output_address (XEXP (X, 0)); \ 301: else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \ 302: { union { double d; int i[2]; } u; \ 303: union { float f; int i; } u1; \ 304: u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ 305: u1.f = u.d; \ 306: if (CODE == 'f') \ 307: fprintf (FILE, "#0f%.9e", u1.f); \ 308: else \ 309: fprintf (FILE, "#0x%x", u1.i); } \ 310: else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode) \ 311: { union { double d; int i[2]; } u; \ 312: u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ 313: fprintf (FILE, "#0d%.20e", u.d); } \ 314: else if (CODE == 'b') output_addr_const (FILE, X); \ 315: else { putc ('#', FILE); output_addr_const (FILE, X); }} 316: 317: #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ 318: { register rtx reg1, reg2, breg, ireg; \ 319: register rtx addr = ADDR; \ 320: rtx offset; \ 321: switch (GET_CODE (addr)) \ 322: { \ 323: case REG: \ 324: fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \ 325: break; \ 326: case PRE_DEC: \ 327: fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \ 328: break; \ 329: case POST_INC: \ 330: fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \ 331: break; \ 332: case PLUS: \ 333: reg1 = 0; reg2 = 0; \ 334: ireg = 0; breg = 0; \ 335: offset = 0; \ 336: if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \ 337: { \ 338: offset = XEXP (addr, 0); \ 339: addr = XEXP (addr, 1); \ 340: } \ 341: else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \ 342: { \ 343: offset = XEXP (addr, 1); \ 344: addr = XEXP (addr, 0); \ 345: } \ 346: if (GET_CODE (addr) != PLUS) ; \ 347: else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \ 348: { \ 349: reg1 = XEXP (addr, 0); \ 350: addr = XEXP (addr, 1); \ 351: } \ 352: else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \ 353: { \ 354: reg1 = XEXP (addr, 1); \ 355: addr = XEXP (addr, 0); \ 356: } \ 357: else if (GET_CODE (XEXP (addr, 0)) == MULT) \ 358: { \ 359: reg1 = XEXP (addr, 0); \ 360: addr = XEXP (addr, 1); \ 361: } \ 362: else if (GET_CODE (XEXP (addr, 1)) == MULT) \ 363: { \ 364: reg1 = XEXP (addr, 1); \ 365: addr = XEXP (addr, 0); \ 366: } \ 367: else if (GET_CODE (XEXP (addr, 0)) == REG) \ 368: { \ 369: reg1 = XEXP (addr, 0); \ 370: addr = XEXP (addr, 1); \ 371: } \ 372: else if (GET_CODE (XEXP (addr, 1)) == REG) \ 373: { \ 374: reg1 = XEXP (addr, 1); \ 375: addr = XEXP (addr, 0); \ 376: } \ 377: if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \ 378: || GET_CODE (addr) == SIGN_EXTEND) \ 379: { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \ 380: if (offset != 0) { if (addr != 0) abort (); addr = offset; } \ 381: if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \ 382: || GET_CODE (reg1) == MULT)) \ 383: || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \ 384: { breg = reg2; ireg = reg1; } \ 385: else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \ 386: { breg = reg1; ireg = reg2; } \ 387: if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \ 388: { int scale = 1; \ 389: if (GET_CODE (ireg) == MULT) \ 390: { scale = INTVAL (XEXP (ireg, 1)); \ 391: ireg = XEXP (ireg, 0); } \ 392: if (GET_CODE (ireg) == SIGN_EXTEND) \ 393: fprintf (FILE, "(L%d.b,pc,%s.w", \ 394: CODE_LABEL_NUMBER (XEXP (addr, 0)), \ 395: reg_names[REGNO (XEXP (ireg, 0))]); \ 396: else \ 397: fprintf (FILE, "(L%d.b,pc,%s.l", \ 398: CODE_LABEL_NUMBER (XEXP (addr, 0)), \ 399: reg_names[REGNO (ireg)]); \ 400: if (scale != 1) fprintf (FILE, "*%d", scale); \ 401: putc (')', FILE); \ 402: break; } \ 403: if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF) \ 404: { fprintf (FILE, "(L%d.b,pc,%s.l", \ 405: CODE_LABEL_NUMBER (XEXP (addr, 0)), \ 406: reg_names[REGNO (breg)]); \ 407: putc (')', FILE); \ 408: break; } \ 409: if (ireg != 0 || breg != 0) \ 410: { int scale = 1; \ 411: if (breg == 0) \ 412: abort (); \ 413: if (addr && GET_CODE (addr) == LABEL_REF) abort (); \ 414: fprintf (FILE, "("); \ 415: if (addr != 0) { \ 416: output_addr_const (FILE, addr); \ 417: putc (',', FILE); } \ 418: fprintf (FILE, "%s", reg_names[REGNO (breg)]); \ 419: if (ireg != 0) \ 420: putc (',', FILE); \ 421: if (ireg != 0 && GET_CODE (ireg) == MULT) \ 422: { scale = INTVAL (XEXP (ireg, 1)); \ 423: ireg = XEXP (ireg, 0); } \ 424: if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \ 425: fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \ 426: else if (ireg != 0) \ 427: fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \ 428: if (scale != 1) fprintf (FILE, "*%d", scale); \ 429: putc (')', FILE); \ 430: break; \ 431: } \ 432: else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \ 433: { fprintf (FILE, "(L%d.b,pc,%s.l)", \ 434: CODE_LABEL_NUMBER (XEXP (addr, 0)), \ 435: reg_names[REGNO (reg1)]); \ 436: break; } \ 437: default: \ 438: if (GET_CODE (addr) == CONST_INT \ 439: && INTVAL (addr) < 0x8000 \ 440: && INTVAL (addr) >= -0x8000) \ 441: fprintf (FILE, "%d.w", INTVAL (addr)); \ 442: else \ 443: output_addr_const (FILE, addr); \ 444: }} 445: 446: #else /* Using GAS, which uses the MIT assembler syntax, like a Sun. */ 447: 448: #define FUNCTION_PROFILER(FILE, LABEL_NO) \ 449: fprintf (FILE, "\tmovl #LP%d,d0\n\tjsr mcount\n", (LABEL_NO)); 450: 451: #endif /* MOTOROLA */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.