]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/gcc/config/i386/freebsd.h.fixed
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.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$ */
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},               \
144      { "no-profiler-epilogue",  -MASK_PROFILER_EPILOGUE},               \
145      { "aout",                   MASK_AOUT},                            \
146      { "no-aout",               -MASK_AOUT},                            \
147      { "underscores",            MASK_UNDERSCORES},                     \
148      { "no-underscores",        -MASK_UNDERSCORES},
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 /* FreeBSD ELF using our home-grown crtbegin.o/crtend.o does not support the
162    DWARF2 unwinding mechanisms.  Once `make world' bootstraping problems with
163    the EGCS crtstuff.c is overcome, we will switch to the non-sjlj-exceptions 
164    type exception machanism.  */
165 #define DWARF2_UNWIND_INFO 0
166
167 /* The a.out tools do not support "linkonce" sections. */
168 #undef  SUPPORTS_ONE_ONLY
169 #define SUPPORTS_ONE_ONLY       TARGET_ELF
170
171 /* Enable alias attribute support.  */
172 #undef  SET_ASM_OP
173 #define SET_ASM_OP              ".set"
174
175 /* The a.out tools do not support "Lscope" .stabs symbols. */
176 #undef  NO_DBX_FUNCTION_END
177 #define NO_DBX_FUNCTION_END     TARGET_AOUT
178
179 /* In ELF, the function stabs come first, before the relative offsets.  */
180 #undef  DBX_FUNCTION_FIRST
181 #define DBX_CHECK_FUNCTION_FIRST TARGET_ELF
182
183 /* supply our own hook for calling __main() from main() */
184 #undef  INVOKE__main
185 #define INVOKE__main
186 #undef  GEN_CALL__MAIN
187 #define GEN_CALL__MAIN                                                  \
188   do {                                                                  \
189     if (!(TARGET_ELF))                                                  \
190       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, NAME__MAIN), 0,    \
191                          VOIDmode, 0);                                  \
192   } while (0)
193
194 /* Indicate that jump tables go in the text section.  This is
195    necessary when compiling PIC code.  */
196 #undef  JUMP_TABLES_IN_TEXT_SECTION
197 #define JUMP_TABLES_IN_TEXT_SECTION     (flag_pic)
198
199 /* override the exception table positioning */
200 #undef  EXCEPTION_SECTION
201 #define EXCEPTION_SECTION() \
202   do {                                                                  \
203     if (TARGET_ELF)                                                     \
204       {                                                                 \
205         named_section (NULL_TREE, ".gcc_except_table", 0);              \
206       }                                                                 \
207     else                                                                \
208       {                                                                 \
209         if (flag_pic)                                                   \
210           data_section ();                                              \
211         else                                                            \
212           readonly_data_section ();                                     \
213       }                                                                 \
214   } while (0);
215
216 /* Tell final.c that we don't need a label passed to mcount.  */
217 #undef  NO_PROFILE_DATA
218 #define NO_PROFILE_DATA
219
220 /* Output assembler code to FILE to begin profiling of the current function.
221    LABELNO is an optional label.  */
222
223 #undef  FUNCTION_PROFILER
224 #define FUNCTION_PROFILER(FILE, LABELNO)  \
225   do {                                                                  \
226     char *_name = TARGET_AOUT ? "mcount" : ".mcount";                   \
227     if (flag_pic)                                                       \
228       fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", _name);               \
229     else                                                                \
230       fprintf ((FILE), "\tcall %s\n", _name);                           \
231   } while (0)
232
233 /* Output assembler code to FILE to end profiling of the current function.  */
234
235 #undef  FUNCTION_PROFILER_EPILOGUE
236 #define FUNCTION_PROFILER_EPILOGUE(FILE, DO_RTL)                        \
237   do {                                                                  \
238     if (TARGET_PROFILER_EPILOGUE)                                       \
239       {                                                                 \
240         if (DO_RTL)                                                     \
241           {                                                             \
242           /* ".mexitcount" is specially handled in                      \
243              ASM_HACK_SYMBOLREF () so that we don't need to handle      \
244              flag_pic or TARGET_AOUT here.  */                          \
245             rtx xop;                                                    \
246             xop = gen_rtx_MEM (FUNCTION_MODE,                           \
247                             gen_rtx_SYMBOL_REF (Pmode, ".mexitcount")); \
248             emit_call_insn (gen_rtx (CALL, VOIDmode, xop, const0_rtx)); \
249           }                                                             \
250         else                                                            \
251           {                                                             \
252           /* XXX this !DO_RTL case is broken but not actually used.  */ \
253             char *_name = TARGET_AOUT ? "mcount" : ".mcount";           \
254             if (flag_pic)                                               \
255               fprintf (FILE, "\tcall *%s@GOT(%%ebx)\n", _name);         \
256             else                                                        \
257               fprintf (FILE, "\tcall %s\n", _name);                     \
258           }                                                             \
259       }                                                                 \
260   } while (0)
261
262
263 /************************[  Assembler stuff  ]********************************/
264
265 #undef  ASM_APP_ON
266 #define ASM_APP_ON      "#APP\n"
267
268 #undef  ASM_APP_OFF
269 #define ASM_APP_OFF     "#NO_APP\n" 
270
271 /* This is how to begin an assembly language file.
272    The .file command should always begin the output.
273    ELF also needs a .version.  */
274
275 #undef  ASM_FILE_START
276 #define ASM_FILE_START(FILE)                                            \
277   do {                                                                  \
278     output_file_directive ((FILE), main_input_filename);                \
279     if (TARGET_ELF)                                                     \
280       fprintf ((FILE), "\t.version\t\"01.01\"\n");                      \
281   } while (0)
282
283 /* This is how to store into the string BUF
284    the symbol_ref name of an internal numbered label where      
285    PREFIX is the class of label and NUM is the number within the class.  
286    This is suitable for output with `assemble_name'.  */
287 #undef  ASM_GENERATE_INTERNAL_LABEL
288 #define ASM_GENERATE_INTERNAL_LABEL(BUF, PREFIX, NUMBER)                \
289   sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".",           \
290            (PREFIX), (NUMBER))
291
292 /* This is how to output an internal numbered label where
293    PREFIX is the class of label and NUM is the number within the class.
294    For most svr4/ELF systems, the convention is that any symbol which begins
295    with a period is not put into the linker symbol table by the assembler.  */
296 #undef  ASM_OUTPUT_INTERNAL_LABEL
297 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)                      \
298   fprintf ((FILE), "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".",        \
299            (PREFIX), (NUM))
300
301 /* This is how to output a reference to a user-level label named NAME.  */
302 #undef  ASM_OUTPUT_LABELREF
303 #define ASM_OUTPUT_LABELREF(FILE, NAME)                                 \
304   do {                                                                  \
305     char *_name = (NAME);                                               \
306     /* Hack to avoid writing lots of rtl in                             \
307        FUNCTION_PROFILER_EPILOGUE ().  */                               \
308     if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)          \
309       {                                                                 \
310         if (TARGET_AOUT)                                                \
311           _name++;                                                      \
312         if (flag_pic)                                                   \
313           fprintf ((FILE), "*%s@GOT(%%ebx)", _name);                    \
314         else                                                            \
315           fprintf ((FILE), "%s", _name);                                \
316       }                                                                 \
317     else                                                                \
318       fprintf (FILE, "%s%s", TARGET_UNDERSCORES ? "_" : "", _name);     \
319 } while (0)
320
321 /* This is how to hack on the symbol code of certain relcalcitrant
322    symbols to modify their output in output_pic_addr_const ().  */
323
324 #undef  ASM_HACK_SYMBOLREF_CODE
325 #define ASM_HACK_SYMBOLREF_CODE(NAME, CODE)                             \
326   do {                                                                  \
327     /* Part of hack to avoid writing lots of rtl in                     \
328        FUNCTION_PROFILER_EPILOGUE ().  */                               \
329     char *_name = (NAME);                                               \
330     if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)          \
331       (CODE) = 'X';                                                     \
332   } while (0)
333
334 /* This is how to output an element of a case-vector that is relative.
335    This is only used for PIC code.  See comments by the `casesi' insn in
336    i386.md for an explanation of the expression this outputs. */
337 #undef  ASM_OUTPUT_ADDR_DIFF_ELT
338 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)                \
339   fprintf ((FILE), "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, (VALUE))
340
341 #undef  ASM_OUTPUT_ALIGN
342 #define ASM_OUTPUT_ALIGN(FILE, LOG)                                     \
343   if ((LOG)!=0) {                                                       \
344     if (in_text_section())                                              \
345       fprintf ((FILE), "\t.p2align %d,0x90\n", (LOG));                  \
346     else                                                                \
347       fprintf ((FILE), "\t.p2align %d\n", (LOG));                       \
348   }
349
350 #undef  ASM_OUTPUT_SOURCE_LINE
351 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINE)                              \
352   do {                                                                  \
353     static int sym_lineno = 1;                                          \
354     if (TARGET_ELF)                                                     \
355       {                                                                 \
356         fprintf ((FILE), ".stabn 68,0,%d,.LM%d-", (LINE), sym_lineno);  \
357         assemble_name ((FILE),                                          \
358                 XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));  \
359         fprintf ((FILE), "\n.LM%d:\n", sym_lineno);                     \
360         sym_lineno += 1;                                                \
361       }                                                                 \
362     else                                                                \
363       {                                                                 \
364         fprintf ((FILE), "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE,       \
365                 lineno);                                                \
366       }                                                                 \
367   } while (0)
368
369 /* These macros generate the special .type and .size directives which
370    are used to set the corresponding fields of the linker symbol table
371    entries in an ELF object file under SVR4.  These macros also output
372    the starting labels for the relevant functions/objects.  */
373
374 /* Write the extra assembler code needed to declare a function properly.
375    Some svr4 assemblers need to also have something extra said about the
376    function's return value.  We allow for that here.  */
377
378 #undef  ASM_DECLARE_FUNCTION_NAME
379 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)                     \
380   do {                                                                  \
381     fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);                             \
382     assemble_name (FILE, NAME);                                         \
383     putc (',', FILE);                                                   \
384     fprintf (FILE, TYPE_OPERAND_FMT, "function");                       \
385     putc ('\n', FILE);                                                  \
386     ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));                      \
387     ASM_OUTPUT_LABEL(FILE, NAME);                                       \
388   } while (0)
389
390 /* Write the extra assembler code needed to declare an object properly.  */
391
392 #undef  ASM_DECLARE_OBJECT_NAME
393 #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)                       \
394   do {                                                                  \
395     fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);                             \
396     assemble_name (FILE, NAME);                                         \
397     putc (',', FILE);                                                   \
398     fprintf (FILE, TYPE_OPERAND_FMT, "object");                         \
399     putc ('\n', FILE);                                                  \
400     size_directive_output = 0;                                          \
401     if (!flag_inhibit_size_directive && DECL_SIZE (DECL))               \
402       {                                                                 \
403         size_directive_output = 1;                                      \
404         fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
405         assemble_name (FILE, NAME);                                     \
406         putc (',', FILE);                                               \
407         fprintf (FILE, HOST_WIDE_INT_PRINT_DEC,                         \
408                  int_size_in_bytes (TREE_TYPE (DECL)));                 \
409         fputc ('\n', FILE);                                             \
410       }                                                                 \
411     ASM_OUTPUT_LABEL(FILE, NAME);                                       \
412   } while (0)
413
414 /* Output the size directive for a decl in rest_of_decl_compilation
415    in the case where we did not do so before the initializer.
416    Once we find the error_mark_node, we know that the value of
417    size_directive_output was set
418    by ASM_DECLARE_OBJECT_NAME when it was run for the same decl.  */
419
420 #undef  ASM_FINISH_DECLARE_OBJECT
421 #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)        \
422   do {                                                                  \
423     char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0);                   \
424     if (!flag_inhibit_size_directive && DECL_SIZE (DECL)                \
425         && ! AT_END && TOP_LEVEL                                        \
426         && DECL_INITIAL (DECL) == error_mark_node                       \
427         && !size_directive_output)                                      \
428       {                                                                 \
429         size_directive_output = 1;                                      \
430         fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
431         assemble_name (FILE, name);                                     \
432         putc (',', FILE);                                               \
433         fprintf (FILE, HOST_WIDE_INT_PRINT_DEC,                         \
434                 int_size_in_bytes (TREE_TYPE (DECL)));                  \
435         fputc ('\n', FILE);                                             \
436       }                                                                 \
437   } while (0)
438
439 /* This is how to declare the size of a function.  */
440
441 #undef  ASM_DECLARE_FUNCTION_SIZE
442 #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
443   do {                                                                  \
444     if (!flag_inhibit_size_directive)                                   \
445       {                                                                 \
446         char label[256];                                                \
447         static int labelno;                                             \
448         labelno++;                                                      \
449         ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);            \
450         ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno);               \
451         fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
452         assemble_name (FILE, (FNAME));                                  \
453         fprintf (FILE, ",");                                            \
454         assemble_name (FILE, label);                                    \
455         fprintf (FILE, "-");                                            \
456         assemble_name (FILE, (FNAME));                                  \
457         putc ('\n', FILE);                                              \
458       }                                                                 \
459   } while (0)
460
461
462 /* The routine used to output NUL terminated strings.  We use a special
463    version of this for most svr4 targets because doing so makes the
464    generated assembly code more compact (and thus faster to assemble)
465    as well as more readable, especially for targets like the i386
466    (where the only alternative is to output character sequences as
467    comma separated lists of numbers).   */
468
469 #undef  ASM_OUTPUT_LIMITED_STRING
470 #define ASM_OUTPUT_LIMITED_STRING(FILE, STR)                            \
471   do {                                                                  \
472       register unsigned char *_limited_str = (unsigned char *) (STR);   \
473       register unsigned ch;                                             \
474       fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP);                      \
475       for (; (ch = *_limited_str); _limited_str++)                      \
476         {                                                               \
477           register int escape;                                          \
478           switch (escape = ESCAPES[ch])                                 \
479             {                                                           \
480             case 0:                                                     \
481               putc (ch, (FILE));                                        \
482               break;                                                    \
483             case 1:                                                     \
484               fprintf ((FILE), "\\%03o", ch);                           \
485               break;                                                    \
486             default:                                                    \
487               putc ('\\', (FILE));                                      \
488               putc (escape, (FILE));                                    \
489               break;                                                    \
490             }                                                           \
491         }                                                               \
492       fprintf ((FILE), "\"\n");                                         \
493   } while (0)
494
495 /* Switch into a generic section.
496  
497    We make the section read-only and executable for a function decl,
498    read-only for a const data decl, and writable for a non-const data decl.
499  
500    If the section has already been defined, we must not
501    emit the attributes here. The SVR4 assembler does not
502    recognize section redefinitions.
503    If DECL is NULL, no attributes are emitted.  */
504
505 #undef  ASM_OUTPUT_SECTION_NAME
506 #define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)                \
507   do {                                                                  \
508     static struct section_info                                          \
509       {                                                                 \
510         struct section_info *next;                                      \
511         char *name;                                                     \
512         enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type;              \
513       } *sections;                                                      \
514     struct section_info *s;                                             \
515     char *mode;                                                         \
516     enum sect_enum type;                                                \
517                                                                         \
518     for (s = sections; s; s = s->next)                                  \
519       if (!strcmp (NAME, s->name))                                      \
520         break;                                                          \
521                                                                         \
522     if (DECL && TREE_CODE (DECL) == FUNCTION_DECL)                      \
523       type = SECT_EXEC, mode = "ax";                                    \
524     else if (DECL && DECL_READONLY_SECTION (DECL, RELOC))               \
525       type = SECT_RO, mode = "a";                                       \
526     else                                                                \
527       type = SECT_RW, mode = "aw";                                      \
528                                                                         \
529     if (s == 0)                                                         \
530       {                                                                 \
531         s = (struct section_info *) xmalloc (sizeof (struct section_info));  \
532         s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME));       \
533         strcpy (s->name, NAME);                                         \
534         s->type = type;                                                 \
535         s->next = sections;                                             \
536         sections = s;                                                   \
537         fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, mode);  \
538       }                                                                 \
539     else                                                                \
540       {                                                                 \
541         if (DECL && s->type != type)                                    \
542           error_with_decl (DECL, "%s causes a section type conflict");  \
543                                                                         \
544         fprintf (FILE, ".section\t%s\n", NAME);                         \
545       }                                                                 \
546   } while (0)
547
548 #undef  MAKE_DECL_ONE_ONLY
549 #define MAKE_DECL_ONE_ONLY(DECL)        (DECL_WEAK (DECL) = 1)
550 #undef  UNIQUE_SECTION_P
551 #define UNIQUE_SECTION_P(DECL)          (DECL_ONE_ONLY (DECL))
552 #undef  UNIQUE_SECTION
553 #define UNIQUE_SECTION(DECL,RELOC)                                      \
554   do {                                                                  \
555     int len;                                                            \
556     char *name, *string, *prefix;                                       \
557                                                                         \
558     name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL));             \
559                                                                         \
560     if (! DECL_ONE_ONLY (DECL))                                         \
561       {                                                                 \
562         prefix = ".";                                                   \
563         if (TREE_CODE (DECL) == FUNCTION_DECL)                          \
564           prefix = ".text.";                                            \
565         else if (DECL_READONLY_SECTION (DECL, RELOC))                   \
566           prefix = ".rodata.";                                          \
567         else                                                            \
568           prefix = ".data.";                                            \
569       }                                                                 \
570     else if (TREE_CODE (DECL) == FUNCTION_DECL)                         \
571       prefix = ".gnu.linkonce.t.";                                      \
572     else if (DECL_READONLY_SECTION (DECL, RELOC))                       \
573       prefix = ".gnu.linkonce.r.";                                      \
574     else                                                                \
575       prefix = ".gnu.linkonce.d.";                                      \
576                                                                         \
577     len = strlen (name) + strlen (prefix);                              \
578     string = alloca (len + 1);                                          \
579     sprintf (string, "%s%s", prefix, name);                             \
580                                                                         \
581     DECL_SECTION_NAME (DECL) = build_string (len, string);              \
582   } while (0)
583
584 /* A C statement or statements to switch to the appropriate
585    section for output of DECL.  DECL is either a `VAR_DECL' node
586    or a constant of some sort.  RELOC indicates whether forming
587    the initial value of DECL requires link-time relocations.  */
588
589 #undef  SELECT_SECTION
590 #define SELECT_SECTION(DECL,RELOC)                                      \
591   {                                                                     \
592     if (flag_pic && RELOC)                                              \
593       data_section ();                                                  \
594     else if (TREE_CODE (DECL) == STRING_CST)                            \
595       {                                                                 \
596         if (! flag_writable_strings)                                    \
597           const_section ();                                             \
598         else                                                            \
599           data_section ();                                              \
600       }                                                                 \
601     else if (TREE_CODE (DECL) == VAR_DECL)                              \
602       {                                                                 \
603         if (! DECL_READONLY_SECTION (DECL, RELOC))                      \
604           data_section ();                                              \
605         else                                                            \
606           const_section ();                                             \
607       }                                                                 \
608     else                                                                \
609       const_section ();                                                 \
610   }
611
612 /* Define macro used to output shift-double opcodes when the shift
613    count is in %cl.  Some assemblers require %cl as an argument;
614    some don't.
615
616    *OLD* GAS requires the %cl argument, so override i386/unix.h. */
617       
618 #undef  AS3_SHIFT_DOUBLE
619 #define AS3_SHIFT_DOUBLE(a,b,c,d)       AS3 (a,b,c,d)
620
621
622 /************************[  Debugger stuff  ]*********************************/
623
624 /* Copy this from the svr4 specifications... */
625 /* Define the register numbers to be used in Dwarf debugging information.
626    The SVR4 reference port C compiler uses the following register numbers
627    in its Dwarf output code:
628         0 for %eax (gnu regno = 0)
629         1 for %ecx (gnu regno = 2)
630         2 for %edx (gnu regno = 1)
631         3 for %ebx (gnu regno = 3)
632         4 for %esp (gnu regno = 7)
633         5 for %ebp (gnu regno = 6)
634         6 for %esi (gnu regno = 4)
635         7 for %edi (gnu regno = 5)
636    The following three DWARF register numbers are never generated by
637    the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
638    believes these numbers have these meanings.
639         8  for %eip    (no gnu equivalent)
640         9  for %eflags (no gnu equivalent)
641         10 for %trapno (no gnu equivalent)
642    It is not at all clear how we should number the FP stack registers
643    for the x86 architecture.  If the version of SDB on x86/svr4 were
644    a bit less brain dead with respect to floating-point then we would
645    have a precedent to follow with respect to DWARF register numbers
646    for x86 FP registers, but the SDB on x86/svr4 is so completely
647    broken with respect to FP registers that it is hardly worth thinking
648    of it as something to strive for compatibility with.
649    The version of x86/svr4 SDB I have at the moment does (partially)
650    seem to believe that DWARF register number 11 is associated with
651    the x86 register %st(0), but that's about all.  Higher DWARF
652    register numbers don't seem to be associated with anything in
653    particular, and even for DWARF regno 11, SDB only seems to under-
654    stand that it should say that a variable lives in %st(0) (when
655    asked via an `=' command) if we said it was in DWARF regno 11,
656    but SDB still prints garbage when asked for the value of the
657    variable in question (via a `/' command).
658    (Also note that the labels SDB prints for various FP stack regs
659    when doing an `x' command are all wrong.)
660    Note that these problems generally don't affect the native SVR4
661    C compiler because it doesn't allow the use of -O with -g and
662    because when it is *not* optimizing, it allocates a memory
663    location for each floating-point variable, and the memory
664    location is what gets described in the DWARF AT_location
665    attribute for the variable in question.
666    Regardless of the severe mental illness of the x86/svr4 SDB, we
667    do something sensible here and we use the following DWARF
668    register numbers.  Note that these are all stack-top-relative
669    numbers.
670         11 for %st(0) (gnu regno = 8)
671         12 for %st(1) (gnu regno = 9)
672         13 for %st(2) (gnu regno = 10)
673         14 for %st(3) (gnu regno = 11)
674         15 for %st(4) (gnu regno = 12)
675         16 for %st(5) (gnu regno = 13)
676         17 for %st(6) (gnu regno = 14)
677         18 for %st(7) (gnu regno = 15)
678 */
679 #undef  DWARF_DBX_REGISTER_NUMBER
680 #define DWARF_DBX_REGISTER_NUMBER(n) \
681 ((n) == 0 ? 0 \
682  : (n) == 1 ? 2 \
683  : (n) == 2 ? 1 \
684  : (n) == 3 ? 3 \
685  : (n) == 4 ? 6 \
686  : (n) == 5 ? 7 \
687  : (n) == 6 ? 5 \
688  : (n) == 7 ? 4 \
689  : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
690  : (-1))
691
692 /* Now what stabs expects in the register.  */
693 #undef  STABS_DBX_REGISTER_NUMBER
694 #define STABS_DBX_REGISTER_NUMBER(n) \
695 ((n) == 0 ? 0 : \
696  (n) == 1 ? 2 : \
697  (n) == 2 ? 1 : \
698  (n) == 3 ? 3 : \
699  (n) == 4 ? 6 : \
700  (n) == 5 ? 7 : \
701  (n) == 6 ? 4 : \
702  (n) == 7 ? 5 : \
703  (n) + 4)
704
705 #undef  DBX_REGISTER_NUMBER
706 #define DBX_REGISTER_NUMBER(n)  ((write_symbols == DWARF_DEBUG)         \
707                                 ? DWARF_DBX_REGISTER_NUMBER(n)          \
708                                 : STABS_DBX_REGISTER_NUMBER(n))
709
710 /* tag end of file in elf mode */
711 #undef  DBX_OUTPUT_MAIN_SOURCE_FILE_END
712 #define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME)                 \
713   do {                                                                  \
714     if (TARGET_ELF) {                                                   \
715       fprintf ((FILE), "\t.text\n\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", \
716                 N_SO);                                                  \
717     }                                                                   \
718   } while (0)
719
720 /* stabs-in-elf has offsets relative to function beginning */
721 #undef  DBX_OUTPUT_LBRAC
722 #define DBX_OUTPUT_LBRAC(FILE, NAME)                                    \
723   do {                                                                  \
724     fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC);             \
725     assemble_name (asmfile, buf);                                       \
726     if (TARGET_ELF)                                                     \
727       {                                                                 \
728         fputc ('-', asmfile);                                           \
729         assemble_name (asmfile,                                         \
730                  XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
731       }                                                                 \
732     fprintf (asmfile, "\n");                                            \
733   } while (0)
734
735 #undef  DBX_OUTPUT_RBRAC
736 #define DBX_OUTPUT_RBRAC(FILE, NAME)                                    \
737   do {                                                                  \
738     fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC);             \
739     assemble_name (asmfile, buf);                                       \
740     if (TARGET_ELF)                                                     \
741       {                                                                 \
742         fputc ('-', asmfile);                                           \
743         assemble_name (asmfile,                                         \
744                  XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
745       }                                                                 \
746     fprintf (asmfile, "\n");                                            \
747   } while (0)