OSDN Git Service

2000-03-03 Jonathan Larmour <jlarmour@cygnus.co.uk>
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / elf.h
1 /* Definitions of target machine for GNU compiler.  MIPS R3000 version with
2    GOFAST floating point library.
3    Copyright (C) 1994, 1997, 1999 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Use ELF.  */
23 #define OBJECT_FORMAT_ELF
24
25 /* Until we figure out what MIPS ELF targets normally use, just do
26    stabs in ELF.  */
27 #ifndef PREFERRED_DEBUGGING_TYPE
28 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
29 #endif
30
31 /* Mostly like ECOFF.  */
32 #include "gofast.h"
33 #include "mips/ecoff.h"
34
35 /* We need to use .esize and .etype instead of .size and .type to
36    avoid conflicting with ELF directives.  */
37 #undef PUT_SDB_SIZE
38 #define PUT_SDB_SIZE(a)                                 \
39 do {                                                    \
40   extern FILE *asm_out_text_file;                       \
41   fprintf (asm_out_text_file, "\t.esize\t%d;", (a));    \
42 } while (0)
43
44 #undef PUT_SDB_TYPE
45 #define PUT_SDB_TYPE(a)                                 \
46 do {                                                    \
47   extern FILE *asm_out_text_file;                       \
48   fprintf (asm_out_text_file, "\t.etype\t0x%x;", (a));  \
49 } while (0)
50
51 /* Biggest alignment supported by the object file format of this
52    machine.  Use this macro to limit the alignment which can be
53    specified using the `__attribute__ ((aligned (N)))' construct.  If
54    not defined, the default value is `BIGGEST_ALIGNMENT'.  */
55
56 #define MAX_OFILE_ALIGNMENT (32768*8)
57
58 /* A C statement to output something to the assembler file to switch to section
59    NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
60    NULL_TREE.  Some target formats do not support arbitrary sections.  Do not
61    define this macro in such cases.  */
62
63 #define ASM_OUTPUT_SECTION_NAME(F, DECL, NAME, RELOC) \
64 do {                                                            \
65   extern FILE *asm_out_text_file;                               \
66   if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL)              \
67     fprintf (asm_out_text_file, "\t.section %s,\"ax\",@progbits\n", (NAME)); \
68   else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC))       \
69     fprintf (F, "\t.section %s,\"a\",@progbits\n", (NAME));     \
70   else                                                          \
71     fprintf (F, "\t.section %s,\"aw\",@progbits\n", (NAME));    \
72 } while (0)
73
74 /* The following macro defines the format used to output the second
75    operand of the .type assembler directive.  Different svr4 assemblers
76    expect various different forms for this operand.  The one given here
77    is just a default.  You may need to override it in your machine-
78    specific tm.h file (depending upon the particulars of your assembler).  */
79
80 #define TYPE_OPERAND_FMT        "@%s"
81
82 /* Define the strings used for the special svr4 .type and .size directives.
83    These strings generally do not vary from one system running svr4 to
84    another, but if a given system (e.g. m88k running svr) needs to use
85    different pseudo-op names for these, they may be overridden in the
86    file which includes this one.  */
87
88 #undef TYPE_ASM_OP
89 #undef SIZE_ASM_OP
90 #define TYPE_ASM_OP     ".type"
91 #define SIZE_ASM_OP     ".size"
92
93 /* If defined, a C expression whose value is a string containing the
94    assembler operation to identify the following data as
95    uninitialized global data.  If not defined, and neither
96    `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
97    uninitialized global data will be output in the data section if
98    `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
99    used.  */
100 #ifndef BSS_SECTION_ASM_OP
101 #define BSS_SECTION_ASM_OP      ".section\t.bss"
102 #endif
103
104 #define SBSS_SECTION_ASM_OP     "\t.section .sbss"
105
106 /* Like `ASM_OUTPUT_BSS' except takes the required alignment as a
107    separate, explicit argument.  If you define this macro, it is used
108    in place of `ASM_OUTPUT_BSS', and gives you more flexibility in
109    handling the required alignment of the variable.  The alignment is
110    specified as the number of bits.
111
112    Try to use function `asm_output_aligned_bss' defined in file
113    `varasm.c' when defining this macro. */
114 #ifndef ASM_OUTPUT_ALIGNED_BSS
115 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
116 do {                                                                    \
117   ASM_GLOBALIZE_LABEL (FILE, NAME);                                     \
118   if (SIZE > 0 && SIZE <= mips_section_threshold)                       \
119     sbss_section ();                                                    \
120   else                                                                  \
121     bss_section ();                                                     \
122   ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));          \
123   last_assemble_variable_decl = DECL;                                   \
124   ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);                           \
125   ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);                              \
126 } while (0)
127 #endif
128
129 /* These macros generate the special .type and .size directives which
130    are used to set the corresponding fields of the linker symbol table
131    entries in an ELF object file under SVR4.  These macros also output
132    the starting labels for the relevant functions/objects.  */
133
134 /* Write the extra assembler code needed to declare an object properly.  */
135
136 #undef ASM_DECLARE_OBJECT_NAME
137 #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)                       \
138   do {                                                                  \
139     fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);                             \
140     assemble_name (FILE, NAME);                                         \
141     putc (',', FILE);                                                   \
142     fprintf (FILE, TYPE_OPERAND_FMT, "object");                         \
143     putc ('\n', FILE);                                                  \
144     size_directive_output = 0;                                          \
145     if (!flag_inhibit_size_directive && DECL_SIZE (DECL))               \
146       {                                                                 \
147         size_directive_output = 1;                                      \
148         fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
149         assemble_name (FILE, NAME);                                     \
150         fprintf (FILE, ",%d\n",  int_size_in_bytes (TREE_TYPE (DECL))); \
151       }                                                                 \
152     mips_declare_object (FILE, NAME, "", ":\n", 0);                     \
153   } while (0)
154
155 /* Output the size directive for a decl in rest_of_decl_compilation
156    in the case where we did not do so before the initializer.
157    Once we find the error_mark_node, we know that the value of
158    size_directive_output was set
159    by ASM_DECLARE_OBJECT_NAME when it was run for the same decl.  */
160
161 #undef ASM_FINISH_DECLARE_OBJECT
162 #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)         \
163 do {                                                                     \
164      char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0);                   \
165      if (!flag_inhibit_size_directive && DECL_SIZE (DECL)                \
166          && ! AT_END && TOP_LEVEL                                        \
167          && DECL_INITIAL (DECL) == error_mark_node                       \
168          && !size_directive_output)                                      \
169        {                                                                 \
170          size_directive_output = 1;                                      \
171          fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
172          assemble_name (FILE, name);                                     \
173          fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL)));  \
174        }                                                                 \
175    } while (0)
176
177 #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)                            \
178  do { fputc ( '\t', FILE);                                            \
179       assemble_name (FILE, LABEL1);                                   \
180       fputs ( " = ", FILE);                                           \
181       assemble_name (FILE, LABEL2);                                   \
182       fputc ( '\n', FILE);                                            \
183  } while (0)
184
185 /* Note about .weak vs. .weakext
186    The mips native assemblers support .weakext, but not .weak.
187    mips-elf gas supports .weak, but not .weakext.
188    mips-elf gas has been changed to support both .weak and .weakext,
189    but until that support is generally available, the 'if' below
190    should serve. */
191
192 #define ASM_WEAKEN_LABEL(FILE,NAME) ASM_OUTPUT_WEAK_ALIAS(FILE,NAME,0)
193 #define ASM_OUTPUT_WEAK_ALIAS(FILE,NAME,VALUE)  \
194  do {                                           \
195   if (TARGET_GAS)                               \
196       fputs ("\t.weak\t", FILE);                \
197   else                                          \
198       fputs ("\t.weakext\t", FILE);             \
199   assemble_name (FILE, NAME);                   \
200   if (VALUE)                                    \
201     {                                           \
202       fputc (' ', FILE);                        \
203       assemble_name (FILE, VALUE);              \
204     }                                           \
205   fputc ('\n', FILE);                           \
206  } while (0)
207
208 #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
209 #undef UNIQUE_SECTION_P
210 #define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL))
211 #define UNIQUE_SECTION(DECL,RELOC)                                         \
212 do {                                                                       \
213   int len, size, sec;                                                      \
214   char *name, *string, *prefix;                                            \
215   static char *prefixes[4][2] = {                                          \
216     { ".text.", ".gnu.linkonce.t." },                                      \
217     { ".rodata.", ".gnu.linkonce.r." },                                    \
218     { ".data.", ".gnu.linkonce.d." },                                      \
219     { ".sdata.", ".gnu.linkonce.s." }                                      \
220   };                                                                       \
221                                                                            \
222   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL));                  \
223   size = int_size_in_bytes (TREE_TYPE (decl));                             \
224                                                                            \
225   /* Determine the base section we are interested in:                      \
226      0=text, 1=rodata, 2=data, 3=sdata, [4=bss].  */                       \
227   if (TREE_CODE (DECL) == FUNCTION_DECL)                                   \
228     sec = 0;                                                               \
229   else if (DECL_INITIAL (DECL) == 0                                        \
230            || DECL_INITIAL (DECL) == error_mark_node)                      \
231     sec = 2;                                                               \
232   else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16)                          \
233       && TREE_CODE (decl) == STRING_CST                                    \
234       && !flag_writable_strings)                                           \
235     {                                                                      \
236       /* For embedded position independent code, put constant strings      \
237          in the text section, because the data section is limited to       \
238          64K in size.  For mips16 code, put strings in the text            \
239          section so that a PC relative load instruction can be used to     \
240          get their address.  */                                            \
241       sec = 0;                                                             \
242     }                                                                      \
243   else if (TARGET_EMBEDDED_DATA)                                           \
244     {                                                                      \
245       /* For embedded applications, always put an object in read-only data \
246          if possible, in order to reduce RAM usage.  */                    \
247                                                                            \
248       if (DECL_READONLY_SECTION (DECL, RELOC))                             \
249         sec = 1;                                                           \
250       else if (size > 0 && size <= mips_section_threshold)                 \
251         sec = 3;                                                           \
252       else                                                                 \
253         sec = 2;                                                           \
254     }                                                                      \
255   else                                                                     \
256     {                                                                      \
257       /* For hosted applications, always put an object in small data if    \
258          possible, as this gives the best performance.  */                 \
259                                                                            \
260       if (size > 0 && size <= mips_section_threshold)                      \
261         sec = 3;                                                           \
262       else if (DECL_READONLY_SECTION (DECL, RELOC))                        \
263         sec = 1;                                                           \
264       else                                                                 \
265         sec = 2;                                                           \
266     }                                                                      \
267                                                                            \
268   prefix = prefixes[sec][DECL_ONE_ONLY (DECL)];                            \
269   len = strlen (name) + strlen (prefix);                                   \
270   string = alloca (len + 1);                                               \
271   sprintf (string, "%s%s", prefix, name);                                  \
272                                                                            \
273   DECL_SECTION_NAME (DECL) = build_string (len, string);                   \
274 } while (0)
275
276 /* Support the ctors/dtors and other sections.  */
277  
278 /* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
279  
280    Note that we want to give these sections the SHF_WRITE attribute
281    because these sections will actually contain data (i.e. tables of
282    addresses of functions in the current root executable or shared library
283    file) and, in the case of a shared library, the relocatable addresses
284    will have to be properly resolved/relocated (and then written into) by
285    the dynamic linker when it actually attaches the given shared library
286    to the executing process.  (Note that on SVR4, you may wish to use the
287    `-z text' option to the ELF linker, when building a shared library, as
288    an additional check that you are doing everything right.  But if you do
289    use the `-z text' option when building a shared library, you will get
290    errors unless the .ctors and .dtors sections are marked as writable
291    via the SHF_WRITE attribute.)  */
292
293 #define CTORS_SECTION_ASM_OP    "\t.section\t.ctors,\"aw\""
294 #define DTORS_SECTION_ASM_OP    "\t.section\t.dtors,\"aw\""
295  
296 /* There's no point providing a default definition of __CTOR_LIST__
297    since people are expected either to use crtbegin.o, or an equivalent,
298    or provide their own definition.  */
299 #define CTOR_LISTS_DEFINED_EXTERNALLY
300
301 /* A list of other sections which the compiler might be "in" at any
302    given time.  */
303 #undef EXTRA_SECTIONS
304 #define EXTRA_SECTIONS in_sdata, in_sbss, in_rdata, in_ctors, in_dtors
305  
306 #define INVOKE__main
307
308 #undef EXTRA_SECTION_FUNCTIONS
309 #define EXTRA_SECTION_FUNCTIONS                                         \
310   SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP) \
311   SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP) \
312   SECTION_FUNCTION_TEMPLATE(rdata_section, in_rdata, RDATA_SECTION_ASM_OP) \
313   SECTION_FUNCTION_TEMPLATE(ctors_section, in_ctors, CTORS_SECTION_ASM_OP) \
314   SECTION_FUNCTION_TEMPLATE(dtors_section, in_dtors, DTORS_SECTION_ASM_OP)
315
316 #define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP)                               \
317 void FN ()                                                            \
318 {                                                                     \
319   if (in_section != ENUM)                                             \
320     {                                                                 \
321       fprintf (asm_out_file, "%s\n", OP);                             \
322       in_section = ENUM;                                              \
323     }                                                                 \
324 }
325
326
327 /* A C statement (sans semicolon) to output an element in the table of
328    global constructors.  */
329 #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME)                             \
330   do {                                                                \
331     ctors_section ();                                                 \
332     fprintf (FILE, "\t%s\t", TARGET_LONG64 ? ".dword" : ".word");     \
333     assemble_name (FILE, NAME);                                       \
334     fprintf (FILE, "\n");                                             \
335   } while (0)
336
337
338 /* A C statement (sans semicolon) to output an element in the table of
339    global destructors.  */
340 #define ASM_OUTPUT_DESTRUCTOR(FILE,NAME)                              \
341   do {                                                                \
342     dtors_section ();                                                 \
343     fprintf (FILE, "\t%s\t", TARGET_LONG64 ? ".dword" : ".word");     \
344     assemble_name (FILE, NAME);                                       \
345     fprintf (FILE, "\n");                                             \
346   } while (0)
347
348 #define CTOR_LIST_BEGIN                                 \
349 asm (CTORS_SECTION_ASM_OP);                             \
350 func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) }
351  
352 #define CTOR_LIST_END                                   \
353 asm (CTORS_SECTION_ASM_OP);                             \
354 func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
355  
356 #define DTOR_LIST_BEGIN                                 \
357 asm (DTORS_SECTION_ASM_OP);                             \
358 func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) }
359
360 #define DTOR_LIST_END                                   \
361 asm (DTORS_SECTION_ASM_OP);                             \
362 func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
363
364 /* Don't set the target flags, this is done by the linker script */
365 #undef LIB_SPEC
366 #define LIB_SPEC ""
367
368 #undef  STARTFILE_SPEC
369 #define STARTFILE_SPEC "crtbegin%O%s %{!mno-crt0:crt0%O%s}"
370
371 #undef  ENDFILE_SPEC
372 #define ENDFILE_SPEC "crtend%O%s"