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