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