|
|
1.1 ! root 1: /* Target definitions for GNU compiler for Intel 80386 running System V.4 ! 2: Copyright (C) 1991 Free Software Foundation, Inc. ! 3: ! 4: Written by Ron Guilmette ([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. */ ! 21: ! 22: #include "i386/i386.h" /* Base i386 target machine definitions */ ! 23: #include "i386/att.h" /* Use the i386 AT&T assembler syntax */ ! 24: #include "svr4.h" /* Definitions common to all SVR4 targets */ ! 25: ! 26: #undef TARGET_VERSION ! 27: #define TARGET_VERSION fprintf (stderr, " (i386 System V Release 4)"); ! 28: ! 29: /* The svr4 ABI for the i386 says that records and unions are returned ! 30: in memory. */ ! 31: ! 32: #undef RETURN_IN_MEMORY ! 33: #define RETURN_IN_MEMORY(TYPE) \ ! 34: (TYPE_MODE (TYPE) == BLKmode) ! 35: ! 36: /* Define which macros to predefine. __svr4__ is our extension. */ ! 37: /* This used to define X86, but [email protected] says that ! 38: is supposed to be defined optionally by user programs--not by default. */ ! 39: #define CPP_PREDEFINES \ ! 40: "-Di386 -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(i386) -Amachine(i386)" ! 41: ! 42: /* This is how to output assembly code to define a `float' constant. ! 43: We always have to use a .long pseudo-op to do this because the native ! 44: SVR4 ELF assembler is buggy and it generates incorrect values when we ! 45: try to use the .float pseudo-op instead. */ ! 46: ! 47: #undef ASM_OUTPUT_FLOAT ! 48: #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ ! 49: do { long value; \ ! 50: REAL_VALUE_TO_TARGET_SINGLE ((VALUE), value); \ ! 51: if (sizeof (int) == sizeof (long)) \ ! 52: fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value); \ ! 53: else \ ! 54: fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value); \ ! 55: } while (0) ! 56: ! 57: /* This is how to output assembly code to define a `double' constant. ! 58: We always have to use a pair of .long pseudo-ops to do this because ! 59: the native SVR4 ELF assembler is buggy and it generates incorrect ! 60: values when we try to use the the .double pseudo-op instead. */ ! 61: ! 62: #undef ASM_OUTPUT_DOUBLE ! 63: #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! 64: do { long value[2]; \ ! 65: REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), value); \ ! 66: if (sizeof (int) == sizeof (long)) \ ! 67: { \ ! 68: fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \ ! 69: fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \ ! 70: } \ ! 71: else \ ! 72: { \ ! 73: fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]); \ ! 74: fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]); \ ! 75: } \ ! 76: } while (0) ! 77: ! 78: ! 79: #undef ASM_OUTPUT_LONG_DOUBLE ! 80: #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ ! 81: do { long value[3]; \ ! 82: REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), value); \ ! 83: if (sizeof (int) == sizeof (long)) \ ! 84: { \ ! 85: fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \ ! 86: fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \ ! 87: fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[2]); \ ! 88: } \ ! 89: else \ ! 90: { \ ! 91: fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]); \ ! 92: fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]); \ ! 93: fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[2]); \ ! 94: } \ ! 95: } while (0) ! 96: ! 97: /* Output at beginning of assembler file. */ ! 98: /* The .file command should always begin the output. */ ! 99: ! 100: #undef ASM_FILE_START ! 101: #define ASM_FILE_START(FILE) \ ! 102: do { \ ! 103: output_file_directive (FILE, main_input_filename); \ ! 104: fprintf (FILE, "\t.version\t\"01.01\"\n"); \ ! 105: } while (0) ! 106: ! 107: /* Define the register numbers to be used in Dwarf debugging information. ! 108: The SVR4 reference port C compiler uses the following register numbers ! 109: in its Dwarf output code: ! 110: ! 111: 0 for %eax (gnu regno = 0) ! 112: 1 for %ecx (gnu regno = 2) ! 113: 2 for %edx (gnu regno = 1) ! 114: 3 for %ebx (gnu regno = 3) ! 115: 4 for %esp (gnu regno = 7) ! 116: 5 for %ebp (gnu regno = 6) ! 117: 6 for %esi (gnu regno = 4) ! 118: 7 for %edi (gnu regno = 5) ! 119: ! 120: The following three DWARF register numbers are never generated by ! 121: the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4 ! 122: believes these numbers have these meanings. ! 123: ! 124: 8 for %eip (no gnu equivalent) ! 125: 9 for %eflags (no gnu equivalent) ! 126: 10 for %trapno (no gnu equivalent) ! 127: ! 128: It is not at all clear how we should number the FP stack registers ! 129: for the x86 architecture. If the version of SDB on x86/svr4 were ! 130: a bit less brain dead with respect to floating-point then we would ! 131: have a precedent to follow with respect to DWARF register numbers ! 132: for x86 FP registers, but the SDB on x86/svr4 is so completely ! 133: broken with respect to FP registers that it is hardly worth thinking ! 134: of it as something to strive for compatibility with. ! 135: ! 136: The verison of x86/svr4 SDB I have at the moment does (partially) ! 137: seem to believe that DWARF register number 11 is associated with ! 138: the x86 register %st(0), but that's about all. Higher DWARF ! 139: register numbers don't seem to be associated with anything in ! 140: particular, and even for DWARF regno 11, SDB only seems to under- ! 141: stand that it should say that a variable lives in %st(0) (when ! 142: asked via an `=' command) if we said it was in DWARF regno 11, ! 143: but SDB still prints garbage when asked for the value of the ! 144: variable in question (via a `/' command). ! 145: ! 146: (Also note that the labels SDB prints for various FP stack regs ! 147: when doing an `x' command are all wrong.) ! 148: ! 149: Note that these problems generally don't affect the native SVR4 ! 150: C compiler because it doesn't allow the use of -O with -g and ! 151: because when it is *not* optimizing, it allocates a memory ! 152: location for each floating-point variable, and the memory ! 153: location is what gets described in the DWARF AT_location ! 154: attribute for the variable in question. ! 155: ! 156: Regardless of the severe mental illness of the x86/svr4 SDB, we ! 157: do something sensible here and we use the following DWARF ! 158: register numbers. Note that these are all stack-top-relative ! 159: numbers. ! 160: ! 161: 11 for %st(0) (gnu regno = 8) ! 162: 12 for %st(1) (gnu regno = 9) ! 163: 13 for %st(2) (gnu regno = 10) ! 164: 14 for %st(3) (gnu regno = 11) ! 165: 15 for %st(4) (gnu regno = 12) ! 166: 16 for %st(5) (gnu regno = 13) ! 167: 17 for %st(6) (gnu regno = 14) ! 168: 18 for %st(7) (gnu regno = 15) ! 169: */ ! 170: ! 171: #undef DBX_REGISTER_NUMBER ! 172: #define DBX_REGISTER_NUMBER(n) \ ! 173: ((n) == 0 ? 0 \ ! 174: : (n) == 1 ? 2 \ ! 175: : (n) == 2 ? 1 \ ! 176: : (n) == 3 ? 3 \ ! 177: : (n) == 4 ? 6 \ ! 178: : (n) == 5 ? 7 \ ! 179: : (n) == 6 ? 5 \ ! 180: : (n) == 7 ? 4 \ ! 181: : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \ ! 182: : (-1)) ! 183: ! 184: /* The routine used to output sequences of byte values. We use a special ! 185: version of this for most svr4 targets because doing so makes the ! 186: generated assembly code more compact (and thus faster to assemble) ! 187: as well as more readable. Note that if we find subparts of the ! 188: character sequence which end with NUL (and which are shorter than ! 189: STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */ ! 190: ! 191: #undef ASM_OUTPUT_ASCII ! 192: #define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \ ! 193: do \ ! 194: { \ ! 195: register unsigned char *_ascii_bytes = (unsigned char *) (STR); \ ! 196: register unsigned char *limit = _ascii_bytes + (LENGTH); \ ! 197: register unsigned bytes_in_chunk = 0; \ ! 198: for (; _ascii_bytes < limit; _ascii_bytes++) \ ! 199: { \ ! 200: register unsigned char *p; \ ! 201: if (bytes_in_chunk >= 64) \ ! 202: { \ ! 203: fputc ('\n', (FILE)); \ ! 204: bytes_in_chunk = 0; \ ! 205: } \ ! 206: for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \ ! 207: continue; \ ! 208: if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \ ! 209: { \ ! 210: if (bytes_in_chunk > 0) \ ! 211: { \ ! 212: fputc ('\n', (FILE)); \ ! 213: bytes_in_chunk = 0; \ ! 214: } \ ! 215: ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \ ! 216: _ascii_bytes = p; \ ! 217: } \ ! 218: else \ ! 219: { \ ! 220: if (bytes_in_chunk == 0) \ ! 221: fprintf ((FILE), "\t.byte\t"); \ ! 222: else \ ! 223: fputc (',', (FILE)); \ ! 224: fprintf ((FILE), "0x%02x", *_ascii_bytes); \ ! 225: bytes_in_chunk += 5; \ ! 226: } \ ! 227: } \ ! 228: if (bytes_in_chunk > 0) \ ! 229: fprintf ((FILE), "\n"); \ ! 230: } \ ! 231: while (0) ! 232: ! 233: /* This is how to output an element of a case-vector that is relative. ! 234: This is only used for PIC code. See comments by the `casesi' insn in ! 235: i386.md for an explanation of the expression this outputs. */ ! 236: ! 237: #undef ASM_OUTPUT_ADDR_DIFF_ELT ! 238: #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ ! 239: fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) ! 240: ! 241: /* Indicate that jump tables go in the text section. This is ! 242: necessary when compiling PIC code. */ ! 243: ! 244: #define JUMP_TABLES_IN_TEXT_SECTION
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.