Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / gcc / config / i386 / freebsd.h.fixed
1 /* Definitions for Intel 386 running FreeBSD with either a.out or ELF format
2    Copyright (C) 1996-2000 Free Software Foundation, Inc.
3    Contributed by Eric Youngdale.
4    Modified for stabs-in-ELF by H.J. Lu.
5    Adapted from GNU/Linux version by John Polstra.
6    Added support for generating "old a.out gas" on the fly by Peter Wemm.
7    Continued development by David O'Brien <obrien@freebsd.org>
8
9 This file is part of GNU CC.
10
11 GNU CC is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15
16 GNU CC is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GNU CC; see the file COPYING.  If not, write to
23 the Free Software Foundation, 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA.  */
25
26 /* $FreeBSD: src/contrib/gcc/config/i386/freebsd.h.fixed,v 1.34.2.3 2001/03/02 09:27:49 obrien Exp $ */
27
28 #undef  CPP_PREDEFINES
29 #define CPP_PREDEFINES                                                  \
30   "-Di386 -Acpu(i386) -Amachine(i386)"                                  \
31   FBSD_CPP_PREDEFINES
32
33 #undef  CC1_SPEC
34 #define CC1_SPEC "\
35   %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \
36   %{maout: %{!mno-underscores: %{!munderscores: -munderscores }}}"
37
38 #undef  ASM_SPEC
39 #define ASM_SPEC        "%{v*: -v} %{maout: %{fpic:-k} %{fPIC:-k}}"
40
41 #undef  ASM_FINAL_SPEC 
42 #define ASM_FINAL_SPEC  "%|"
43
44 /* Provide a LINK_SPEC appropriate for FreeBSD.  Here we provide support
45    for the special GCC options -static and -shared, which allow us to
46    link things in one of these three modes by applying the appropriate
47    combinations of options at link-time. We like to support here for
48    as many of the other GNU linker options as possible. But I don't
49    have the time to search for those flags. I am sure how to add
50    support for -soname shared_object_name. H.J.
51
52    I took out %{v:%{!V:-V}}. It is too much :-(. They can use
53    -Wl,-V.
54
55    When the -shared link option is used a final link is not being
56    done.  */
57
58 #undef  LINK_SPEC
59 #define LINK_SPEC "\
60  %{p:%e`-p' not supported; use `-pg' and gprof(1)} \
61   %{maout: %{shared:-Bshareable} \
62     %{!shared:%{!nostdlib:%{!r:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} \
63       %{pg:-Bstatic} %{Z}} \
64     %{assert*} %{R*}} \
65   %{!maout: \
66     -m elf_i386 \
67     %{Wl,*:%*} \
68     %{assert*} %{R*} %{rpath*} %{defsym*} \
69     %{shared:-Bshareable %{h*} %{soname*}} \
70     %{symbolic:-Bsymbolic} \
71     %{!shared: \
72       %{!static: \
73         %{rdynamic: -export-dynamic} \
74         %{!dynamic-linker: -dynamic-linker /usr/libexec/ld-elf.so.1}} \
75       %{static:-Bstatic}}}"
76
77 #undef STARTFILE_SPEC
78 #define STARTFILE_SPEC "\
79   %{maout: %{shared:c++rt0.o%s} \
80     %{!shared: \
81       %{pg:gcrt0.o%s}%{!pg: \
82         %{static:scrt0.o%s} \
83         %{!static:crt0.o%s}}}} \
84   %{!maout: \
85     %{!shared: \
86       %{pg:gcrt1.o%s} \
87       %{!pg: \
88         %{p:gcrt1.o%s} \
89         %{!p:crt1.o%s}}} \
90     crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
91
92 /* Provide an ENDFILE_SPEC appropriate for FreeBSD/i386.  Here we tack on our
93    own magical crtend.o file (compare w/crtstuff.c) which provides part of the
94    support for getting C++ file-scope static object constructed before
95    entering `main', followed by the normal "finalizer" file, `crtn.o'.  */
96
97 #undef  ENDFILE_SPEC
98 #define ENDFILE_SPEC "\
99   %{!maout: \
100     %{!shared:crtend.o%s} \
101     %{shared:crtendS.o%s} crtn.o%s}"
102
103
104 /************************[  Target stuff  ]***********************************/
105
106 /* Define the actual types of some ANSI-mandated types.  
107    Needs to agree with <machine/ansi.h>.  GCC defaults come from c-decl.c,
108    c-common.c, and config/<arch>/<arch>.h.  */
109
110 #undef SIZE_TYPE
111 #define SIZE_TYPE       "unsigned int"
112  
113 #undef PTRDIFF_TYPE
114 #define PTRDIFF_TYPE    "int"
115
116 /* This is the pseudo-op used to generate a 32-bit word of data with a
117    specific value in some section.  */
118
119 #undef INT_ASM_OP
120 #define INT_ASM_OP      ".long"
121
122 /* Biggest alignment supported by the object file format of this
123    machine.  Use this macro to limit the alignment which can be
124    specified using the `__attribute__ ((aligned (N)))' construct.  If
125    not defined, the default value is `BIGGEST_ALIGNMENT'.  */
126
127 #define MAX_OFILE_ALIGNMENT (32768*8)
128
129 #undef  TARGET_VERSION
130 #define TARGET_VERSION  fprintf (stderr, " (i386 FreeBSD/ELF)");
131
132 #define MASK_PROFILER_EPILOGUE  010000000000
133 #define MASK_AOUT               004000000000    /* a.out not elf */
134 #define MASK_UNDERSCORES        002000000000    /* use leading _ */
135
136 #define TARGET_PROFILER_EPILOGUE        (target_flags & MASK_PROFILER_EPILOGUE)
137 #define TARGET_AOUT                     (target_flags & MASK_AOUT)
138 #define TARGET_ELF                      ((target_flags & MASK_AOUT) == 0)
139 #define TARGET_UNDERSCORES              ((target_flags & MASK_UNDERSCORES) != 0)
140
141 #undef  SUBTARGET_SWITCHES
142 #define SUBTARGET_SWITCHES                                              \
143   { "profiler-epilogue",         MASK_PROFILER_EPILOGUE, "Function profiler epilogue"}, \
144   { "no-profiler-epilogue",     -MASK_PROFILER_EPILOGUE, "No function profiler epilogue"}, \
145   { "aout",                      MASK_AOUT, "Generate an a.out (vs. ELF) binary"}, \
146   { "no-aout",                  -MASK_AOUT, "Do not generate an a.out binary"}, \
147   { "underscores",               MASK_UNDERSCORES, "Add leading underscores to symbols"}, \
148   { "no-underscores",           -MASK_UNDERSCORES, "Do not add leading underscores to symbols"},
149
150 /* This goes away when the math emulator is fixed.  */
151 #undef  TARGET_DEFAULT
152 #define TARGET_DEFAULT \
153   (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
154
155 /* Prefix for internally generated assembler labels.  If we aren't using 
156    underscores, we are using prefix `.'s to identify labels that should  
157    be ignored, as in `i386/gas.h' --karl@cs.umb.edu  */                 
158 #undef  LPREFIX
159 #define LPREFIX ((TARGET_UNDERSCORES) ? "L" : ".L")
160
161 /* The a.out tools do not support "linkonce" sections. */
162 #undef  SUPPORTS_ONE_ONLY
163 #define SUPPORTS_ONE_ONLY       TARGET_ELF
164
165 /* Enable alias attribute support.  */
166 #undef  SET_ASM_OP
167 #define SET_ASM_OP              ".set"
168
169 /* The a.out tools do not support "Lscope" .stabs symbols. */
170 #undef  NO_DBX_FUNCTION_END
171 #define NO_DBX_FUNCTION_END     TARGET_AOUT
172
173 /* In ELF, the function stabs come first, before the relative offsets.  */
174 #undef  DBX_FUNCTION_FIRST
175 #define DBX_CHECK_FUNCTION_FIRST TARGET_ELF
176
177 /* supply our own hook for calling __main() from main() */
178 #undef  INVOKE__main
179 #define INVOKE__main
180 #undef  GEN_CALL__MAIN
181 #define GEN_CALL__MAIN                                                  \
182   do {                                                                  \
183     if (!(TARGET_ELF))                                                  \
184       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, NAME__MAIN), 0,    \
185                          VOIDmode, 0);                                  \
186   } while (0)
187
188 /* Indicate that jump tables go in the text section.  This is
189    necessary when compiling PIC code.  */
190 #undef  JUMP_TABLES_IN_TEXT_SECTION
191 #define JUMP_TABLES_IN_TEXT_SECTION     (flag_pic)
192
193 /* override the exception table positioning */
194 #undef  EXCEPTION_SECTION
195 #define EXCEPTION_SECTION() \
196   do {                                                                  \
197     if (TARGET_ELF)                                                     \
198       {                                                                 \
199         named_section (NULL_TREE, ".gcc_except_table", 0);              \
200       }                                                                 \
201     else                                                                \
202       {                                                                 \
203         if (flag_pic)                                                   \
204           data_section ();                                              \
205         else                                                            \
206           readonly_data_section ();                                     \
207       }                                                                 \
208   } while (0);
209
210 /* Tell final.c that we don't need a label passed to mcount.  */
211 #undef  NO_PROFILE_COUNTERS
212 #define NO_PROFILE_COUNTERS
213
214 /* Output assembler code to FILE to begin profiling of the current function.
215    LABELNO is an optional label.  */
216
217 #undef  FUNCTION_PROFILER
218 #define FUNCTION_PROFILER(FILE, LABELNO)  \
219   do {                                                                  \
220     char *_name = TARGET_AOUT ? "mcount" : ".mcount";                   \
221     if (flag_pic)                                                       \
222       fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", _name);               \
223     else                                                                \
224       fprintf ((FILE), "\tcall %s\n", _name);                           \
225   } while (0)
226
227 /* Output assembler code to FILE to end profiling of the current function.  */
228
229 #undef  FUNCTION_PROFILER_EPILOGUE
230 #define FUNCTION_PROFILER_EPILOGUE(FILE, DO_RTL)                        \
231   do {                                                                  \
232     if (TARGET_PROFILER_EPILOGUE)                                       \
233       {                                                                 \
234         if (DO_RTL)                                                     \
235           {                                                             \
236           /* ".mexitcount" is specially handled in                      \
237              ASM_HACK_SYMBOLREF () so that we don't need to handle      \
238              flag_pic or TARGET_AOUT here.  */                          \
239             rtx xop;                                                    \
240             xop = gen_rtx_MEM (FUNCTION_MODE,                           \
241                             gen_rtx_SYMBOL_REF (Pmode, ".mexitcount")); \
242             emit_call_insn (gen_rtx (CALL, VOIDmode, xop, const0_rtx)); \
243           }                                                             \
244         else                                                            \
245           {                                                             \
246           /* XXX this !DO_RTL case is broken but not actually used.  */ \
247             char *_name = TARGET_AOUT ? "mcount" : ".mcount";           \
248             if (flag_pic)                                               \
249               fprintf (FILE, "\tcall *%s@GOT(%%ebx)\n", _name);         \
250             else                                                        \
251               fprintf (FILE, "\tcall %s\n", _name);                     \
252           }                                                             \
253       }                                                                 \
254   } while (0)
255
256
257 /************************[  Assembler stuff  ]********************************/
258
259 #undef  ASM_APP_ON
260 #define ASM_APP_ON      "#APP\n"
261
262 #undef  ASM_APP_OFF
263 #define ASM_APP_OFF     "#NO_APP\n" 
264
265 /* This is how to begin an assembly language file.
266    The .file command should always begin the output.
267    ELF also needs a .version.  */
268
269 #undef  ASM_FILE_START
270 #define ASM_FILE_START(FILE)                                            \
271   do {                                                                  \
272     output_file_directive ((FILE), main_input_filename);                \
273     if (TARGET_ELF)                                                     \
274       fprintf ((FILE), "\t.version\t\"01.01\"\n");                      \
275   } while (0)
276
277 /* This is how to store into the string BUF
278    the symbol_ref name of an internal numbered label where      
279    PREFIX is the class of label and NUM is the number within the class.  
280    This is suitable for output with `assemble_name'.  */
281 #undef  ASM_GENERATE_INTERNAL_LABEL
282 #define ASM_GENERATE_INTERNAL_LABEL(BUF, PREFIX, NUMBER)                \
283   sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".",           \
284            (PREFIX), (NUMBER))
285
286 /* This is how to output an internal numbered label where
287    PREFIX is the class of label and NUM is the number within the class.
288    For most svr4/ELF systems, the convention is that any symbol which begins
289    with a period is not put into the linker symbol table by the assembler.  */
290 #undef  ASM_OUTPUT_INTERNAL_LABEL
291 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)                      \
292   fprintf ((FILE), "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".",        \
293            (PREFIX), (NUM))
294
295 /* This is how to output a reference to a user-level label named NAME.  */
296 #undef  ASM_OUTPUT_LABELREF
297 #define ASM_OUTPUT_LABELREF(FILE, NAME)                                 \
298   do {                                                                  \
299     char *_name = (NAME);                                               \
300     /* Hack to avoid writing lots of rtl in                             \
301        FUNCTION_PROFILER_EPILOGUE ().  */                               \
302     if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)          \
303       {                                                                 \
304         if (TARGET_AOUT)                                                \
305           _name++;                                                      \
306         if (flag_pic)                                                   \
307           fprintf ((FILE), "*%s@GOT(%%ebx)", _name);                    \
308         else                                                            \
309           fprintf ((FILE), "%s", _name);                                \
310       }                                                                 \
311     else                                                                \
312       fprintf (FILE, "%s%s", TARGET_UNDERSCORES ? "_" : "", _name);     \
313 } while (0)
314
315 /* This is how to hack on the symbol code of certain relcalcitrant
316    symbols to modify their output in output_pic_addr_const ().  */
317
318 #undef  ASM_HACK_SYMBOLREF_CODE
319 #define ASM_HACK_SYMBOLREF_CODE(NAME, CODE)                             \
320   do {                                                                  \
321     /* Part of hack to avoid writing lots of rtl in                     \
322        FUNCTION_PROFILER_EPILOGUE ().  */                               \
323     char *_name = (NAME);                                               \
324     if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)          \
325       (CODE) = 'X';                                                     \
326   } while (0)
327
328 /* This is how to output an element of a case-vector that is relative.
329    This is only used for PIC code.  See comments by the `casesi' insn in
330    i386.md for an explanation of the expression this outputs. */
331 #undef  ASM_OUTPUT_ADDR_DIFF_ELT
332 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)                \
333   fprintf ((FILE), "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, (VALUE))
334
335 #undef  ASM_OUTPUT_ALIGN
336 #define ASM_OUTPUT_ALIGN(FILE, LOG)                                     \
337   if ((LOG)!=0) {                                                       \
338     if (in_text_section())                                              \
339       fprintf ((FILE), "\t.p2align %d,0x90\n", (LOG));                  \
340     else                                                                \
341       fprintf ((FILE), "\t.p2align %d\n", (LOG));                       \
342   }
343
344 #undef  ASM_OUTPUT_ALIGNED_COMMON
345 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)              \
346   do {                                                                  \
347     if (TARGET_ELF)                                                     \
348       {                                                                 \
349         fprintf ((FILE), "%s", COMMON_ASM_OP);                          \
350         assemble_name ((FILE), (NAME));                                 \
351         fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT);  \
352       }                                                                 \
353     else                                                                \
354       {                                                                 \
355         int rounded = (SIZE);                                           \
356         if (rounded == 0) rounded = 1;                                  \
357         rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;             \
358         rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)        \
359                    * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));              \
360         fprintf ((FILE), "%s ", COMMON_ASM_OP);                         \
361         assemble_name ((FILE), (NAME));                                 \
362         fprintf ((FILE), ",%u\n", (rounded));                           \
363       }                                                                 \
364   } while (0)
365
366 /* This says how to output assembler code to declare an
367    uninitialized internal linkage data object.  Under SVR4,
368    the linker seems to want the alignment of data objects
369    to depend on their types.  We do exactly that here.  */
370
371 #undef  ASM_OUTPUT_ALIGNED_LOCAL
372 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)               \
373   do {                                                                  \
374     if (TARGET_ELF)                                                     \
375       {                                                                 \
376         fprintf ((FILE), "%s", LOCAL_ASM_OP);                           \
377         assemble_name ((FILE), (NAME));                                 \
378         fprintf ((FILE), "\n");                                         \
379         ASM_OUTPUT_ALIGNED_COMMON ((FILE), (NAME), (SIZE), (ALIGN));    \
380       }                                                                 \
381     else                                                                \
382       {                                                                 \
383         int rounded = (SIZE);                                           \
384         if (rounded == 0) rounded = 1;                                  \
385         rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;             \
386         rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)        \
387                    * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));              \
388         fputs ("\t.lcomm\t", (FILE));                                   \
389         assemble_name ((FILE), (NAME));                                 \
390         fprintf ((FILE), ",%u\n", (rounded));                           \
391       }                                                                 \
392   } while (0)
393
394 /* How to output some space.  The rules are different depending on the
395    object format.  */
396 #undef  ASM_OUTPUT_SKIP
397 #define ASM_OUTPUT_SKIP(FILE, SIZE)                                     \
398   do {                                                                  \
399     if (TARGET_ELF)                                                     \
400       {                                                                 \
401         fprintf ((FILE), "%s%u\n", SKIP_ASM_OP, (SIZE));                \
402       }                                                                 \
403     else                                                                \
404       {                                                                 \
405         fprintf ((FILE), "\t.space\t%u\n", (SIZE));                     \
406       }                                                                 \
407   } while (0)
408
409
410 #undef  ASM_OUTPUT_SOURCE_LINE
411 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINE)                              \
412   do {                                                                  \
413     static int sym_lineno = 1;                                          \
414     if (TARGET_ELF)                                                     \
415       {                                                                 \
416         fprintf ((FILE), ".stabn 68,0,%d,.LM%d-", (LINE), sym_lineno);  \
417         assemble_name ((FILE),                                          \
418                 XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));  \
419         fprintf ((FILE), "\n.LM%d:\n", sym_lineno);                     \
420         sym_lineno += 1;                                                \
421       }                                                                 \
422     else                                                                \
423       {                                                                 \
424         fprintf ((FILE), "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE,       \
425                 lineno);                                                \
426       }                                                                 \
427   } while (0)
428
429 /* These macros generate the special .type and .size directives which
430    are used to set the corresponding fields of the linker symbol table
431    entries in an ELF object file under SVR4.  These macros also output
432    the starting labels for the relevant functions/objects.  */
433
434 /* Write the extra assembler code needed to declare a function properly.
435    Some svr4 assemblers need to also have something extra said about the
436    function's return value.  We allow for that here.  */
437
438 #undef  ASM_DECLARE_FUNCTION_NAME
439 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)                     \
440   do {                                                                  \
441     fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);                             \
442     assemble_name (FILE, NAME);                                         \
443     putc (',', FILE);                                                   \
444     fprintf (FILE, TYPE_OPERAND_FMT, "function");                       \
445     putc ('\n', FILE);                                                  \
446     ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));                      \
447     ASM_OUTPUT_LABEL(FILE, NAME);                                       \
448   } while (0)
449
450 /* This is how to declare the size of a function.  */
451
452 #undef  ASM_DECLARE_FUNCTION_SIZE
453 #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
454   do {                                                                  \
455     if (!flag_inhibit_size_directive)                                   \
456       {                                                                 \
457         char label[256];                                                \
458         static int labelno;                                             \
459         labelno++;                                                      \
460         ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);            \
461         ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno);               \
462         fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
463         assemble_name (FILE, (FNAME));                                  \
464         fprintf (FILE, ",");                                            \
465         assemble_name (FILE, label);                                    \
466         fprintf (FILE, "-");                                            \
467         assemble_name (FILE, (FNAME));                                  \
468         putc ('\n', FILE);                                              \
469       }                                                                 \
470   } while (0)
471
472
473 /* The routine used to output NUL terminated strings.  We use a special
474    version of this for most svr4 targets because doing so makes the
475    generated assembly code more compact (and thus faster to assemble)
476    as well as more readable, especially for targets like the i386
477    (where the only alternative is to output character sequences as
478    comma separated lists of numbers).   */
479
480 #undef  ASM_OUTPUT_LIMITED_STRING
481 #define ASM_OUTPUT_LIMITED_STRING(FILE, STR)                            \
482   do {                                                                  \
483       register unsigned char *_limited_str = (unsigned char *) (STR);   \
484       register unsigned ch;                                             \
485       fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP);                      \
486       for (; (ch = *_limited_str); _limited_str++)                      \
487         {                                                               \
488           register int escape;                                          \
489           switch (escape = ESCAPES[ch])                                 \
490             {                                                           \
491             case 0:                                                     \
492               putc (ch, (FILE));                                        \
493               break;                                                    \
494             case 1:                                                     \
495               fprintf ((FILE), "\\%03o", ch);                           \
496               break;                                                    \
497             default:                                                    \
498               putc ('\\', (FILE));                                      \
499               putc (escape, (FILE));                                    \
500               break;                                                    \
501             }                                                           \
502         }                                                               \
503       fprintf ((FILE), "\"\n");                                         \
504   } while (0)
505
506 /* Switch into a generic section.
507  
508    We make the section read-only and executable for a function decl,
509    read-only for a const data decl, and writable for a non-const data decl.
510  
511    If the section has already been defined, we must not
512    emit the attributes here. The SVR4 assembler does not
513    recognize section redefinitions.
514    If DECL is NULL, no attributes are emitted.  */
515
516 #undef  ASM_OUTPUT_SECTION_NAME
517 #define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)                \
518   do {                                                                  \
519     static struct section_info                                          \
520       {                                                                 \
521         struct section_info *next;                                      \
522         char *name;                                                     \
523         enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type;              \
524       } *sections;                                                      \
525     struct section_info *s;                                             \
526     char *mode;                                                         \
527     enum sect_enum type;                                                \
528                                                                         \
529     for (s = sections; s; s = s->next)                                  \
530       if (!strcmp (NAME, s->name))                                      \
531         break;                                                          \
532                                                                         \
533     if (DECL && TREE_CODE (DECL) == FUNCTION_DECL)                      \
534       type = SECT_EXEC, mode = "ax";                                    \
535     else if (DECL && DECL_READONLY_SECTION (DECL, RELOC))               \
536       type = SECT_RO, mode = "a";                                       \
537     else                                                                \
538       type = SECT_RW, mode = "aw";                                      \
539                                                                         \
540     if (s == 0)                                                         \
541       {                                                                 \
542         s = (struct section_info *) xmalloc (sizeof (struct section_info));  \
543         s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME));       \
544         strcpy (s->name, NAME);                                         \
545         s->type = type;                                                 \
546         s->next = sections;                                             \
547         sections = s;                                                   \
548         fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, mode);  \
549       }                                                                 \
550     else                                                                \
551       {                                                                 \
552         if (DECL && s->type != type)                                    \
553           error_with_decl (DECL, "%s causes a section type conflict");  \
554                                                                         \
555         fprintf (FILE, ".section\t%s\n", NAME);                         \
556       }                                                                 \
557   } while (0)
558
559 #undef  MAKE_DECL_ONE_ONLY
560 #define MAKE_DECL_ONE_ONLY(DECL)        (DECL_WEAK (DECL) = 1)
561 #undef  UNIQUE_SECTION_P
562 #define UNIQUE_SECTION_P(DECL)          (DECL_ONE_ONLY (DECL))
563 #undef  UNIQUE_SECTION
564 #define UNIQUE_SECTION(DECL,RELOC)                                      \
565   do {                                                                  \
566     int len;                                                            \
567     char *name, *string, *prefix;                                       \
568                                                                         \
569     name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL));             \
570                                                                         \
571     if (! DECL_ONE_ONLY (DECL))                                         \
572       {                                                                 \
573         prefix = ".";                                                   \
574         if (TREE_CODE (DECL) == FUNCTION_DECL)                          \
575           prefix = ".text.";                                            \
576         else if (DECL_READONLY_SECTION (DECL, RELOC))                   \
577           prefix = ".rodata.";                                          \
578         else                                                            \
579           prefix = ".data.";                                            \
580       }                                                                 \
581     else if (TREE_CODE (DECL) == FUNCTION_DECL)                         \
582       prefix = ".gnu.linkonce.t.";                                      \
583     else if (DECL_READONLY_SECTION (DECL, RELOC))                       \
584       prefix = ".gnu.linkonce.r.";                                      \
585     else                                                                \
586       prefix = ".gnu.linkonce.d.";                                      \
587                                                                         \
588     len = strlen (name) + strlen (prefix);                              \
589     string = alloca (len + 1);                                          \
590     sprintf (string, "%s%s", prefix, name);                             \
591                                                                         \
592     DECL_SECTION_NAME (DECL) = build_string (len, string);              \
593   } while (0)
594
595 /* A C statement or statements to switch to the appropriate
596    section for output of DECL.  DECL is either a `VAR_DECL' node
597    or a constant of some sort.  RELOC indicates whether forming
598    the initial value of DECL requires link-time relocations.  */
599
600 #undef  SELECT_SECTION
601 #define SELECT_SECTION(DECL,RELOC)                                      \
602   {                                                                     \
603     if (flag_pic && RELOC)                                              \
604       data_section ();                                                  \
605     else if (TREE_CODE (DECL) == STRING_CST)                            \
606       {                                                                 \
607         if (! flag_writable_strings)                                    \
608           const_section ();                                             \
609         else                                                            \
610           data_section ();                                              \
611       }                                                                 \
612     else if (TREE_CODE (DECL) == VAR_DECL)                              \
613       {                                                                 \
614         if (! DECL_READONLY_SECTION (DECL, RELOC))                      \
615           data_section ();                                              \
616         else                                                            \
617           const_section ();                                             \
618       }                                                                 \
619     else                                                                \
620       const_section ();                                                 \
621   }
622
623 /* A C statement (sans semicolon) to output an element in the table of
624    global constructors.  */
625 #undef  ASM_OUTPUT_CONSTRUCTOR
626 #define ASM_OUTPUT_CONSTRUCTOR(FILE, NAME)                              \
627   do {                                                                  \
628     if (TARGET_ELF)                                                     \
629       {                                                                 \
630         ctors_section ();                                               \
631         fprintf ((FILE), "%s ", INT_ASM_OP);                            \
632         assemble_name ((FILE), (NAME));                                 \
633         fprintf ((FILE), "\n");                                         \
634       }                                                                 \
635     else                                                                \
636       {                                                                 \
637         fprintf (asm_out_file, "%s \"%s__CTOR_LIST__\",22,0,0,",        \
638                  ASM_STABS_OP, (TARGET_UNDERSCORES) ? "_" : "");        \
639         assemble_name (asm_out_file, name);                             \
640         fputc ('\n', asm_out_file);                                     \
641       }                                                                 \
642   } while (0)
643
644 /* A C statement (sans semicolon) to output an element in the table of
645    global destructors.  */
646 #undef  ASM_OUTPUT_DESTRUCTOR
647 #define ASM_OUTPUT_DESTRUCTOR(FILE, NAME)                               \
648   do {                                                                  \
649     if (TARGET_ELF)                                                     \
650       {                                                                 \
651         dtors_section ();                                               \
652         fprintf ((FILE), "%s ", INT_ASM_OP);                            \
653         assemble_name ((FILE), (NAME));                                 \
654         fprintf ((FILE), "\n");                                         \
655       }                                                                 \
656     else                                                                \
657       {                                                                 \
658         fprintf (asm_out_file, "%s \"%s__DTOR_LIST__\",22,0,0,",        \
659                  ASM_STABS_OP, (TARGET_UNDERSCORES) ? "_" : "");        \
660         assemble_name (asm_out_file, name);                             \
661         fputc ('\n', asm_out_file);                                     \
662       }                                                                 \
663   } while (0)
664
665 /* Define macro used to output shift-double opcodes when the shift
666    count is in %cl.  Some assemblers require %cl as an argument;
667    some don't.
668
669    *OLD* GAS requires the %cl argument, so override i386/unix.h. */
670       
671 #undef  AS3_SHIFT_DOUBLE
672 #define AS3_SHIFT_DOUBLE(a,b,c,d)       AS3 (a,b,c,d)
673
674
675 /************************[  Debugger stuff  ]*********************************/
676
677 /* Copy this from the svr4 specifications... */
678 /* Define the register numbers to be used in Dwarf debugging information.
679    The SVR4 reference port C compiler uses the following register numbers
680    in its Dwarf output code:
681         0 for %eax (gnu regno = 0)
682         1 for %ecx (gnu regno = 2)
683         2 for %edx (gnu regno = 1)
684         3 for %ebx (gnu regno = 3)
685         4 for %esp (gnu regno = 7)
686         5 for %ebp (gnu regno = 6)
687         6 for %esi (gnu regno = 4)
688         7 for %edi (gnu regno = 5)
689    The following three DWARF register numbers are never generated by
690    the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
691    believes these numbers have these meanings.
692         8  for %eip    (no gnu equivalent)
693         9  for %eflags (no gnu equivalent)
694         10 for %trapno (no gnu equivalent)
695    It is not at all clear how we should number the FP stack registers
696    for the x86 architecture.  If the version of SDB on x86/svr4 were
697    a bit less brain dead with respect to floating-point then we would
698    have a precedent to follow with respect to DWARF register numbers
699    for x86 FP registers, but the SDB on x86/svr4 is so completely
700    broken with respect to FP registers that it is hardly worth thinking
701    of it as something to strive for compatibility with.
702    The version of x86/svr4 SDB I have at the moment does (partially)
703    seem to believe that DWARF register number 11 is associated with
704    the x86 register %st(0), but that's about all.  Higher DWARF
705    register numbers don't seem to be associated with anything in
706    particular, and even for DWARF regno 11, SDB only seems to under-
707    stand that it should say that a variable lives in %st(0) (when
708    asked via an `=' command) if we said it was in DWARF regno 11,
709    but SDB still prints garbage when asked for the value of the
710    variable in question (via a `/' command).
711    (Also note that the labels SDB prints for various FP stack regs
712    when doing an `x' command are all wrong.)
713    Note that these problems generally don't affect the native SVR4
714    C compiler because it doesn't allow the use of -O with -g and
715    because when it is *not* optimizing, it allocates a memory
716    location for each floating-point variable, and the memory
717    location is what gets described in the DWARF AT_location
718    attribute for the variable in question.
719    Regardless of the severe mental illness of the x86/svr4 SDB, we
720    do something sensible here and we use the following DWARF
721    register numbers.  Note that these are all stack-top-relative
722    numbers.
723         11 for %st(0) (gnu regno = 8)
724         12 for %st(1) (gnu regno = 9)
725         13 for %st(2) (gnu regno = 10)
726         14 for %st(3) (gnu regno = 11)
727         15 for %st(4) (gnu regno = 12)
728         16 for %st(5) (gnu regno = 13)
729         17 for %st(6) (gnu regno = 14)
730         18 for %st(7) (gnu regno = 15)
731 */
732 #undef  DWARF_DBX_REGISTER_NUMBER
733 #define DWARF_DBX_REGISTER_NUMBER(n) \
734 ((n) == 0 ? 0 \
735  : (n) == 1 ? 2 \
736  : (n) == 2 ? 1 \
737  : (n) == 3 ? 3 \
738  : (n) == 4 ? 6 \
739  : (n) == 5 ? 7 \
740  : (n) == 6 ? 5 \
741  : (n) == 7 ? 4 \
742  : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
743  : (-1))
744
745 /* Now what stabs expects in the register.  */
746 #undef  STABS_DBX_REGISTER_NUMBER
747 #define STABS_DBX_REGISTER_NUMBER(n) \
748 ((n) == 0 ? 0 : \
749  (n) == 1 ? 2 : \
750  (n) == 2 ? 1 : \
751  (n) == 3 ? 3 : \
752  (n) == 4 ? 6 : \
753  (n) == 5 ? 7 : \
754  (n) == 6 ? 4 : \
755  (n) == 7 ? 5 : \
756  (n) + 4)
757
758 #undef  DBX_REGISTER_NUMBER
759 #define DBX_REGISTER_NUMBER(n)  ((write_symbols == DWARF_DEBUG)         \
760                                 ? DWARF_DBX_REGISTER_NUMBER(n)          \
761                                 : STABS_DBX_REGISTER_NUMBER(n))
762
763 /* tag end of file in elf mode */
764 #undef  DBX_OUTPUT_MAIN_SOURCE_FILE_END
765 #define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME)                 \
766   do {                                                                  \
767     if (TARGET_ELF) {                                                   \
768       fprintf ((FILE), "\t.text\n\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", \
769                 N_SO);                                                  \
770     }                                                                   \
771   } while (0)
772
773 /* stabs-in-elf has offsets relative to function beginning */
774 #undef  DBX_OUTPUT_LBRAC
775 #define DBX_OUTPUT_LBRAC(FILE, NAME)                                    \
776   do {                                                                  \
777     fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC);             \
778     assemble_name (asmfile, buf);                                       \
779     if (TARGET_ELF)                                                     \
780       {                                                                 \
781         fputc ('-', asmfile);                                           \
782         assemble_name (asmfile,                                         \
783                  XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
784       }                                                                 \
785     fprintf (asmfile, "\n");                                            \
786   } while (0)
787
788 #undef  DBX_OUTPUT_RBRAC
789 #define DBX_OUTPUT_RBRAC(FILE, NAME)                                    \
790   do {                                                                  \
791     fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC);             \
792     assemble_name (asmfile, buf);                                       \
793     if (TARGET_ELF)                                                     \
794       {                                                                 \
795         fputc ('-', asmfile);                                           \
796         assemble_name (asmfile,                                         \
797                  XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
798       }                                                                 \
799     fprintf (asmfile, "\n");                                            \
800   } while (0)