]>
Commit | Line | Data |
---|---|---|
9fdecdb7 | 1 | /* Target definitions for GNU compiler for Intel x86 CPU running NeXTSTEP |
8b109b37 | 2 | Copyright (C) 1993, 1995 Free Software Foundation, Inc. |
9fdecdb7 TW |
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 | ||
440954b5 | 20 | #include "i386/gas.h" |
9fdecdb7 TW |
21 | #include "nextstep.h" |
22 | ||
23 | /* By default, target has a 80387, with IEEE FP. */ | |
24 | ||
25 | #undef TARGET_DEFAULT | |
26 | #define TARGET_DEFAULT (1|0100) | |
27 | ||
28 | /* Implicit library calls should use memcpy, not bcopy, etc. */ | |
29 | ||
30 | #define TARGET_MEM_FUNCTIONS | |
31 | ||
32 | /* Machines that use the AT&T assembler syntax | |
33 | also return floating point values in an FP register. | |
34 | Define how to find the value returned by a function. | |
35 | VALTYPE is the data type of the value (as a tree). | |
36 | If the precise function being called is known, FUNC is its FUNCTION_DECL; | |
37 | otherwise, FUNC is 0. */ | |
38 | ||
39 | #undef VALUE_REGNO | |
40 | #define VALUE_REGNO(MODE) \ | |
4a37b939 JVA |
41 | ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \ |
42 | ? FIRST_FLOAT_REG : 0) | |
9fdecdb7 TW |
43 | |
44 | /* 1 if N is a possible register number for a function value. */ | |
45 | ||
46 | #undef FUNCTION_VALUE_REGNO_P | |
47 | #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0 || (N)== FIRST_FLOAT_REG) | |
48 | ||
4a37b939 JVA |
49 | #ifdef REAL_VALUE_TO_TARGET_LONG_DOUBLE |
50 | #undef ASM_OUTPUT_LONG_DOUBLE | |
51 | #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ | |
52 | do { \ | |
53 | long hex[3]; \ | |
54 | REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, hex); \ | |
55 | if (sizeof (int) == sizeof (long)) \ | |
56 | fprintf (FILE, "\t.long 0x%x\n\t.long 0x%x\n\t.long 0x%x\n", \ | |
57 | hex[0], hex[1], hex[2]); \ | |
58 | else \ | |
59 | fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n\t.long 0x%lx\n", \ | |
60 | hex[0], hex[1], hex[2]); \ | |
61 | } while (0) | |
62 | #endif | |
63 | ||
9fdecdb7 TW |
64 | #ifdef REAL_VALUE_TO_TARGET_DOUBLE |
65 | #undef ASM_OUTPUT_DOUBLE | |
66 | #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ | |
67 | do { \ | |
68 | long hex[2]; \ | |
69 | REAL_VALUE_TO_TARGET_DOUBLE (VALUE, hex); \ | |
4a37b939 JVA |
70 | if (sizeof (int) == sizeof (long)) \ |
71 | fprintf (FILE, "\t.long 0x%x\n\t.long 0x%x\n", hex[0], hex[1]); \ | |
72 | else \ | |
73 | fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", hex[0], hex[1]); \ | |
9fdecdb7 TW |
74 | } while (0) |
75 | #endif | |
76 | ||
77 | /* This is how to output an assembler line defining a `float' constant. */ | |
78 | ||
79 | #ifdef REAL_VALUE_TO_TARGET_SINGLE | |
80 | #undef ASM_OUTPUT_FLOAT | |
81 | #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ | |
82 | do { \ | |
83 | long hex; \ | |
84 | REAL_VALUE_TO_TARGET_SINGLE (VALUE, hex); \ | |
4a37b939 JVA |
85 | if (sizeof (int) == sizeof (long)) \ |
86 | fprintf (FILE, "\t.long 0x%x\n", hex); \ | |
87 | else \ | |
88 | fprintf (FILE, "\t.long 0x%lx\n", hex); \ | |
9fdecdb7 TW |
89 | } while (0) |
90 | #endif | |
91 | ||
92 | /* A C statement or statements which output an assembler instruction | |
93 | opcode to the stdio stream STREAM. The macro-operand PTR is a | |
94 | variable of type `char *' which points to the opcode name in its | |
95 | "internal" form--the form that is written in the machine description. | |
96 | ||
97 | GAS version 1.38.1 doesn't understand the `repz' opcode mnemonic. | |
98 | So use `repe' instead. */ | |
99 | ||
100 | #undef ASM_OUTPUT_OPCODE | |
101 | #define ASM_OUTPUT_OPCODE(STREAM, PTR) \ | |
102 | { \ | |
103 | if ((PTR)[0] == 'r' \ | |
104 | && (PTR)[1] == 'e' \ | |
105 | && (PTR)[2] == 'p') \ | |
106 | { \ | |
107 | if ((PTR)[3] == 'z') \ | |
108 | { \ | |
109 | fprintf (STREAM, "repe"); \ | |
110 | (PTR) += 4; \ | |
111 | } \ | |
112 | else if ((PTR)[3] == 'n' && (PTR)[4] == 'z') \ | |
113 | { \ | |
114 | fprintf (STREAM, "repne"); \ | |
115 | (PTR) += 5; \ | |
116 | } \ | |
117 | } \ | |
118 | } | |
119 | ||
120 | /* Define macro used to output shift-double opcodes when the shift | |
121 | count is in %cl. Some assemblers require %cl as an argument; | |
122 | some don't. | |
123 | ||
124 | GAS requires the %cl argument, so override unx386.h. */ | |
125 | ||
126 | #undef AS3_SHIFT_DOUBLE | |
127 | #define AS3_SHIFT_DOUBLE(a,b,c,d) AS3 (a,b,c,d) | |
128 | ||
129 | /* Print opcodes the way that GAS expects them. */ | |
130 | #define GAS_MNEMONICS 1 | |
131 | ||
132 | /* Names to predefine in the preprocessor for this target machine. */ | |
133 | ||
134 | #undef CPP_PREDEFINES | |
65c42379 | 135 | #define CPP_PREDEFINES "-Di386 -DNeXT -Dunix -D__MACH__ -D__LITTLE_ENDIAN__ -D__ARCHITECTURE__=\"i386\" -Asystem(unix) -Asystem(mach) -Acpu(i386) -Amachine(i386)" |
9fdecdb7 TW |
136 | |
137 | /* This accounts for the return pc and saved fp on the i386. */ | |
138 | ||
139 | #define OBJC_FORWARDING_STACK_OFFSET 8 | |
140 | #define OBJC_FORWARDING_MIN_OFFSET 8 | |
141 | ||
5a9771f1 | 142 | /* We do not want a dot in internal labels. */ |
440954b5 | 143 | |
344ba054 RS |
144 | #undef LPREFIX |
145 | #define LPREFIX "L" | |
146 | ||
440954b5 TW |
147 | #undef ASM_GENERATE_INTERNAL_LABEL |
148 | #define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ | |
5a9771f1 RS |
149 | sprintf ((BUF), "*%s%d", (PREFIX), (NUMBER)) |
150 | ||
151 | #undef ASM_OUTPUT_INTERNAL_LABEL | |
152 | #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ | |
153 | fprintf (FILE, "%s%d:\n", PREFIX, NUM) | |
440954b5 | 154 | |
9fdecdb7 TW |
155 | /* Output to assembler file text saying following lines |
156 | may contain character constants, extra white space, comments, etc. */ | |
157 | ||
158 | #undef ASM_APP_ON | |
159 | #define ASM_APP_ON "#APP\n" | |
160 | ||
161 | /* Output to assembler file text saying following lines | |
162 | no longer contain unusual constructs. */ | |
163 | ||
164 | #undef ASM_APP_OFF | |
165 | #define ASM_APP_OFF "#NO_APP\n" | |
166 | ||
167 | #undef ASM_OUTPUT_REG_PUSH | |
168 | #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ | |
169 | fprintf (FILE, "\tpushl %se%s\n", "%", reg_names[REGNO]) | |
170 | ||
171 | #undef ASM_OUTPUT_REG_POP | |
172 | #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ | |
173 | fprintf (FILE, "\tpopl %se%s\n", "%", reg_names[REGNO]) | |
174 | ||
175 | /* This is being overridden because the default i386 configuration | |
176 | generates calls to "_mcount". NeXT system libraries all use | |
177 | "mcount". */ | |
178 | ||
179 | #undef FUNCTION_PROFILER | |
180 | #define FUNCTION_PROFILER(FILE, LABELNO) \ | |
181 | { \ | |
182 | if (flag_pic) \ | |
183 | { \ | |
184 | fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ | |
185 | LPREFIX, (LABELNO)); \ | |
186 | fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \ | |
187 | } \ | |
188 | else \ | |
189 | { \ | |
190 | fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \ | |
191 | fprintf (FILE, "\tcall mcount\n"); \ | |
192 | } \ | |
193 | } | |
194 | ||
195 | /* BEGIN Calling Convention CHANGES */ | |
196 | ||
197 | /* These changes violate the Intel/Unix ABI. Specifically, they | |
198 | change the way that space for a block return value is passed to a | |
199 | function. The ABI says that the pointer is passed on the stack. | |
200 | We change to pass the pointer in %ebx. This makes the NeXT | |
201 | Objective-C forwarding mechanism possible to implement on an i386. */ | |
202 | ||
203 | /* Do NOT pass address of structure values on the stack. */ | |
204 | ||
205 | #undef STRUCT_VALUE_INCOMING | |
206 | #undef STRUCT_VALUE | |
207 | ||
208 | /* Pass them in %ebx. */ | |
209 | ||
210 | #undef STRUCT_VALUE_REGNUM | |
211 | #define STRUCT_VALUE_REGNUM 3 | |
212 | ||
213 | /* Because we are passing the pointer in a register, we don't need to | |
214 | rely on the callee to pop it. */ | |
215 | ||
216 | #undef RETURN_POPS_ARGS | |
8b109b37 | 217 | #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ |
9fdecdb7 TW |
218 | (TREE_CODE (FUNTYPE) == IDENTIFIER_NODE \ |
219 | ? 0 \ | |
220 | : (TARGET_RTD \ | |
221 | && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ | |
222 | || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ | |
223 | == void_type_node))) ? (SIZE) : 0) | |
224 | ||
225 | /* END Calling Convention CHANGES */ |