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