]>
Commit | Line | Data |
---|---|---|
17fd0700 | 1 | /* Target definitions for GNU compiler for mc680x0 running System V.4 |
8636be86 | 2 | Copyright (C) 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003, 2004 |
2398fb2a | 3 | Free Software Foundation, Inc. |
4b27ecd5 RK |
4 | Contributed by Ron Guilmette (rfg@monkeys.com) and |
5 | Fred Fish (fnf@cygnus.com). | |
17fd0700 | 6 | |
7ec022b2 | 7 | This file is part of GCC. |
17fd0700 | 8 | |
7ec022b2 | 9 | GCC is free software; you can redistribute it and/or modify |
17fd0700 RS |
10 | it under the terms of the GNU General Public License as published by |
11 | the Free Software Foundation; either version 2, or (at your option) | |
12 | any later version. | |
13 | ||
7ec022b2 | 14 | GCC is distributed in the hope that it will be useful, |
17fd0700 RS |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | GNU General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
7ec022b2 | 20 | along with GCC; see the file COPYING. If not, write to |
0e29e3c9 RK |
21 | the Free Software Foundation, 59 Temple Place - Suite 330, |
22 | Boston, MA 02111-1307, USA. */ | |
17fd0700 | 23 | |
a7fbe404 NB |
24 | /* Target OS builtins. */ |
25 | #define TARGET_OS_CPP_BUILTINS() \ | |
26 | do \ | |
27 | { \ | |
28 | builtin_define_std ("unix"); \ | |
29 | builtin_define_std ("m68k"); \ | |
30 | builtin_define ("__svr4__"); \ | |
31 | builtin_define ("__motorola__"); \ | |
32 | builtin_assert ("system=unix"); \ | |
33 | builtin_assert ("system=svr4"); \ | |
34 | } \ | |
35 | while (0) | |
36 | ||
17fd0700 | 37 | #ifndef TARGET_DEFAULT |
9811059c | 38 | #define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020) |
17fd0700 RS |
39 | #endif |
40 | ||
41 | /* Override the definition of NO_DOLLAR_IN_LABEL in svr4.h, for special | |
42 | g++ assembler names. When this is defined, g++ uses embedded '.' | |
43 | characters and some m68k assemblers have problems with this. The | |
44 | chances are much greater that any particular assembler will permit | |
7a1929e1 | 45 | embedded '$' characters. */ |
17fd0700 RS |
46 | |
47 | #undef NO_DOLLAR_IN_LABEL | |
48 | ||
49 | /* Define PCC_STATIC_STRUCT_RETURN if the convention on the target machine | |
50 | is to use the nonreentrant technique for returning structure and union | |
51 | values, as commonly implemented by the AT&T Portable C Compiler (PCC). | |
52 | When defined, the gcc option -fpcc-struct-return can be used to cause | |
53 | this form to be generated. When undefined, the option does nothing. | |
54 | For m68k SVR4, the convention is to use a reentrant technique compatible | |
55 | with the gcc default, so override the definition of this macro in m68k.h */ | |
56 | ||
57 | #undef PCC_STATIC_STRUCT_RETURN | |
58 | ||
17fd0700 RS |
59 | /* Test to see if the target includes a 68881 by default, and use CPP_SPEC |
60 | to control whether or not __HAVE_68881__ is defined by default or not. | |
61 | If a 68881 is the default, gcc will use inline 68881 instructions, by | |
62 | predefining __HAVE_68881__, unless -msoft-float is specified. | |
63 | If a 68881 is not the default, gcc will only define __HAVE_68881__ if | |
7a1929e1 | 64 | -m68881 is specified. */ |
17fd0700 | 65 | |
9811059c | 66 | #if TARGET_DEFAULT & MASK_68881 |
17fd0700 RS |
67 | #define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__}" |
68 | #else | |
69 | #define CPP_SPEC "%{m68881:-D__HAVE_68881__}" | |
70 | #endif | |
71 | ||
72 | /* Output assembler code to FILE to increment profiler label # LABELNO | |
73 | for profiling a function entry. We override the definition in m68k.h | |
74 | and match the way the native m68k/SVR4 compiler does profiling, with the | |
75 | address of the profile counter in a1, not a0, and using bsr rather | |
7a1929e1 | 76 | than jsr. */ |
17fd0700 RS |
77 | |
78 | #undef FUNCTION_PROFILER | |
79 | #define FUNCTION_PROFILER(FILE, LABELNO) \ | |
80 | asm_fprintf ((FILE), "\tlea.l\t(%LLP%d,%Rpc),%Ra1\n\tbsr\t_mcount\n", \ | |
81 | (LABELNO)) | |
82 | ||
83 | /* Local common symbols are declared to the assembler with ".lcomm" rather | |
84 | than ".bss", so override the definition in svr4.h */ | |
24f34136 | 85 | /* ??? svr4.h no longer defines this, and this is only used by m68k/amix.h. */ |
17fd0700 RS |
86 | |
87 | #undef BSS_ASM_OP | |
6e7b07a7 | 88 | #define BSS_ASM_OP "\t.lcomm\t" |
17fd0700 RS |
89 | |
90 | /* Register in which address to store a structure value is passed to a | |
7a1929e1 | 91 | function. The default in m68k.h is a1. For m68k/SVR4 it is a0. */ |
17fd0700 | 92 | |
8636be86 KH |
93 | #undef M68K_STRUCT_VALUE_REGNUM |
94 | #define M68K_STRUCT_VALUE_REGNUM 8 | |
17fd0700 | 95 | |
9049a716 RK |
96 | /* Register in which static-chain is passed to a function. The |
97 | default in m68k.h is a0, but that is already the struct value | |
98 | regnum. Make it a1 instead. */ | |
99 | ||
100 | #undef STATIC_CHAIN_REGNUM | |
101 | #define STATIC_CHAIN_REGNUM 9 | |
102 | ||
17fd0700 RS |
103 | #define ASM_COMMENT_START "#" |
104 | ||
17fd0700 RS |
105 | /* Define how the m68k registers should be numbered for Dwarf output. |
106 | The numbering provided here should be compatible with the native | |
107 | SVR4 SDB debugger in the m68k/SVR4 reference port, where d0-d7 | |
7a1929e1 | 108 | are 0-7, a0-a8 are 8-15, and fp0-fp7 are 16-23. */ |
17fd0700 RS |
109 | |
110 | #define DBX_REGISTER_NUMBER(REGNO) (REGNO) | |
111 | ||
112 | /* The ASM_OUTPUT_SKIP macro is first defined in m68k.h, using ".skip". | |
6f1c3a33 | 113 | It is then overridden by m68k/sgs.h to use ".space", and again by svr4.h |
17fd0700 | 114 | to use ".zero". The m68k/SVR4 assembler uses ".space", so repeat the |
6f1c3a33 | 115 | definition from m68k/sgs.h here. Note that ASM_NO_SKIP_IN_TEXT is |
7a1929e1 | 116 | defined in m68k/sgs.h, so we don't have to repeat it here. */ |
17fd0700 RS |
117 | |
118 | #undef ASM_OUTPUT_SKIP | |
119 | #define ASM_OUTPUT_SKIP(FILE,SIZE) \ | |
58e15542 | 120 | fprintf (FILE, "%s%u\n", SPACE_ASM_OP, (int)(SIZE)) |
17fd0700 RS |
121 | |
122 | /* 1 if N is a possible register number for a function value. | |
123 | For m68k/SVR4 allow d0, a0, or fp0 as return registers, for integral, | |
124 | pointer, or floating types, respectively. Reject fp0 if not using a | |
7a1929e1 | 125 | 68881 coprocessor. */ |
17fd0700 RS |
126 | |
127 | #undef FUNCTION_VALUE_REGNO_P | |
128 | #define FUNCTION_VALUE_REGNO_P(N) \ | |
129 | ((N) == 0 || (N) == 8 || (TARGET_68881 && (N) == 16)) | |
130 | ||
7972af82 TW |
131 | /* Define this to be true when FUNCTION_VALUE_REGNO_P is true for |
132 | more than one register. */ | |
133 | ||
134 | #undef NEEDS_UNTYPED_CALL | |
135 | #define NEEDS_UNTYPED_CALL 1 | |
136 | ||
17fd0700 RS |
137 | /* Define how to generate (in the callee) the output value of a function |
138 | and how to find (in the caller) the value returned by a function. VALTYPE | |
139 | is the data type of the value (as a tree). If the precise function being | |
140 | called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0. | |
7a1929e1 | 141 | For m68k/SVR4 generate the result in d0, a0, or fp0 as appropriate. */ |
17fd0700 RS |
142 | |
143 | #undef FUNCTION_VALUE | |
144 | #define FUNCTION_VALUE(VALTYPE, FUNC) \ | |
145 | (TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_68881 \ | |
c5c76735 | 146 | ? gen_rtx_REG (TYPE_MODE (VALTYPE), 16) \ |
9a2073d8 | 147 | : (POINTER_TYPE_P (VALTYPE) \ |
c5c76735 JL |
148 | ? gen_rtx_REG (TYPE_MODE (VALTYPE), 8) \ |
149 | : gen_rtx_REG (TYPE_MODE (VALTYPE), 0))) | |
17fd0700 RS |
150 | |
151 | /* For compatibility with the large body of existing code which does not | |
152 | always properly declare external functions returning pointer types, the | |
153 | m68k/SVR4 convention is to copy the value returned for pointer functions | |
154 | from a0 to d0 in the function epilogue, so that callers that have | |
155 | neglected to properly declare the callee can still find the correct return | |
7a1929e1 | 156 | value. */ |
17fd0700 | 157 | |
17fd0700 RS |
158 | #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \ |
159 | do { \ | |
49ad7cfa BS |
160 | if (current_function_returns_pointer \ |
161 | && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \ | |
17fd0700 RS |
162 | asm_fprintf (FILE, "\tmov.l %Ra0,%Rd0\n"); \ |
163 | } while (0); | |
164 | ||
165 | /* Define how to find the value returned by a library function assuming the | |
166 | value has mode MODE. | |
167 | For m68k/SVR4 look for integer values in d0, pointer values in d0 | |
7a1929e1 | 168 | (returned in both d0 and a0), and floating values in fp0. */ |
17fd0700 RS |
169 | |
170 | #undef LIBCALL_VALUE | |
171 | #define LIBCALL_VALUE(MODE) \ | |
9049a716 RK |
172 | ((((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode) \ |
173 | && TARGET_68881) \ | |
c5c76735 JL |
174 | ? gen_rtx_REG ((MODE), 16) \ |
175 | : gen_rtx_REG ((MODE), 0)) | |
17fd0700 RS |
176 | |
177 | /* Boundary (in *bits*) on which stack pointer should be aligned. | |
7a1929e1 | 178 | The m68k/SVR4 convention is to keep the stack pointer longword aligned. */ |
17fd0700 RS |
179 | |
180 | #undef STACK_BOUNDARY | |
181 | #define STACK_BOUNDARY 32 | |
182 | ||
183 | /* Alignment of field after `int : 0' in a structure. | |
7a1929e1 | 184 | For m68k/SVR4, this is the next longword boundary. */ |
17fd0700 RS |
185 | |
186 | #undef EMPTY_FIELD_BOUNDARY | |
187 | #define EMPTY_FIELD_BOUNDARY 32 | |
188 | ||
189 | /* No data type wants to be aligned rounder than this. | |
190 | For m68k/SVR4, some types (doubles for example) are aligned on 8 byte | |
191 | boundaries */ | |
192 | ||
193 | #undef BIGGEST_ALIGNMENT | |
194 | #define BIGGEST_ALIGNMENT 64 | |
978d7af3 | 195 | |
abc95ed3 | 196 | /* SVR4 m68k assembler is bitching on the `comm i,1,1' which asks for |
978d7af3 | 197 | 1 byte alignment. Don't generate alignment for COMMON seems to be |
7a1929e1 | 198 | safer until we the assembler is fixed. */ |
978d7af3 | 199 | #undef ASM_OUTPUT_ALIGNED_COMMON |
da968ff3 | 200 | /* Same problem with this one. */ |
978d7af3 RS |
201 | #undef ASM_OUTPUT_ALIGNED_LOCAL |
202 | ||
203 | /* The `string' directive on m68k svr4 does not handle string with | |
204 | escape char (ie., `\') right. Use normal way to output ASCII bytes | |
7a1929e1 | 205 | seems to be safer. */ |
978d7af3 RS |
206 | #undef ASM_OUTPUT_ASCII |
207 | #define ASM_OUTPUT_ASCII(FILE,PTR,LEN) \ | |
9e269f72 | 208 | do { \ |
9d955c3a | 209 | register size_t sp = 0, limit = (LEN); \ |
301d03af | 210 | fputs (integer_asm_op (1, TRUE), (FILE)); \ |
978d7af3 | 211 | do { \ |
9d955c3a | 212 | int ch = (PTR)[sp]; \ |
978d7af3 RS |
213 | if (ch > ' ' && ! (ch & 0x80) && ch != '\\') \ |
214 | { \ | |
215 | fprintf ((FILE), "'%c", ch); \ | |
216 | } \ | |
217 | else \ | |
218 | { \ | |
219 | fprintf ((FILE), "0x%x", ch); \ | |
220 | } \ | |
9d955c3a | 221 | if (++sp < limit) \ |
978d7af3 RS |
222 | { \ |
223 | if ((sp % 10) == 0) \ | |
224 | { \ | |
301d03af | 225 | fprintf ((FILE), "\n%s", integer_asm_op (1, TRUE)); \ |
978d7af3 RS |
226 | } \ |
227 | else \ | |
228 | { \ | |
229 | putc (',', (FILE)); \ | |
230 | } \ | |
231 | } \ | |
9d955c3a | 232 | } while (sp < limit); \ |
978d7af3 | 233 | putc ('\n', (FILE)); \ |
9e269f72 | 234 | } while (0) |
978d7af3 | 235 | |
20e52bf1 RS |
236 | /* SVR4 m68k assembler is bitching on the syntax `2.b'. |
237 | So use the "LLDnnn-LLnnn" format. Define LLDnnn after the table. */ | |
978d7af3 RS |
238 | |
239 | #undef ASM_OUTPUT_CASE_END | |
20e52bf1 RS |
240 | #define ASM_OUTPUT_CASE_END(FILE,NUM,TABLE) \ |
241 | do { \ | |
242 | if (switch_table_difference_label_flag) \ | |
016c8440 | 243 | asm_fprintf ((FILE), "%s%LLD%d,%LL%d\n", SET_ASM_OP, (NUM), (NUM)); \ |
20e52bf1 RS |
244 | switch_table_difference_label_flag = 0; \ |
245 | } while (0) | |
978d7af3 | 246 | |
ca11c37c | 247 | extern int switch_table_difference_label_flag; |
24e3324a RS |
248 | |
249 | #undef ASM_OUTPUT_COMMON | |
250 | #undef ASM_OUTPUT_LOCAL | |
251 | #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ | |
252 | ( fputs (".comm ", (FILE)), \ | |
253 | assemble_name ((FILE), (NAME)), \ | |
58e15542 | 254 | fprintf ((FILE), ",%u\n", (int)(SIZE))) |
24e3324a RS |
255 | |
256 | #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ | |
257 | ( fputs (".lcomm ", (FILE)), \ | |
258 | assemble_name ((FILE), (NAME)), \ | |
58e15542 | 259 | fprintf ((FILE), ",%u\n", (int)(SIZE))) |
24e3324a RS |
260 | |
261 | /* Override the definition in svr4.h. In m68k svr4, using swbeg is the | |
7a1929e1 | 262 | standard way to do switch table. */ |
24e3324a RS |
263 | #undef ASM_OUTPUT_BEFORE_CASE_LABEL |
264 | #define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \ | |
016c8440 | 265 | fprintf ((FILE), "%s&%d\n", SWBEG_ASM_OP, XVECLEN (PATTERN (TABLE), 1)); |
24e3324a | 266 | |
9049a716 RK |
267 | /* Output assembler code for a block containing the constant parts |
268 | of a trampoline, leaving space for the variable parts. */ | |
269 | ||
270 | /* On m68k svr4, the trampoline is different from the generic version | |
271 | in that we use a1 as the static call chain. */ | |
272 | ||
273 | #undef TRAMPOLINE_TEMPLATE | |
274 | #define TRAMPOLINE_TEMPLATE(FILE) \ | |
275 | { \ | |
301d03af RS |
276 | assemble_aligned_integer (2, GEN_INT (0x227a)); \ |
277 | assemble_aligned_integer (2, GEN_INT (8)); \ | |
278 | assemble_aligned_integer (2, GEN_INT (0x2f3a)); \ | |
279 | assemble_aligned_integer (2, GEN_INT (8)); \ | |
280 | assemble_aligned_integer (2, GEN_INT (0x4e75)); \ | |
281 | assemble_aligned_integer (4, const0_rtx); \ | |
282 | assemble_aligned_integer (4, const0_rtx); \ | |
9049a716 | 283 | } |
f12d26af RK |
284 | |
285 | /* Redefine since we are using a different trampoline */ | |
286 | #undef TRAMPOLINE_SIZE | |
287 | #define TRAMPOLINE_SIZE 18 | |
288 | ||
289 | /* Emit RTL insns to initialize the variable parts of a trampoline. | |
290 | FNADDR is an RTX for the address of the function's pure code. | |
291 | CXT is an RTX for the static chain value for the function. */ | |
292 | ||
293 | #undef INITIALIZE_TRAMPOLINE | |
294 | #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ | |
295 | { \ | |
c5c76735 JL |
296 | emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 10)), CXT); \ |
297 | emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 14)), FNADDR); \ | |
f12d26af | 298 | } |