freebsd.h revision 58478
198944Sobrien/* Definitions for Intel 386 running FreeBSD with either a.out or ELF format
298944Sobrien   Copyright (C) 1996-2000 Free Software Foundation, Inc.
398944Sobrien   Contributed by Eric Youngdale.
498944Sobrien   Modified for stabs-in-ELF by H.J. Lu.
598944Sobrien   Adapted from GNU/Linux version by John Polstra.
698944Sobrien   Added support for generating "old a.out gas" on the fly by Peter Wemm.
798944Sobrien   Continued development by David O'Brien <obrien@freebsd.org>
898944Sobrien
998944SobrienThis file is part of GNU CC.
1098944Sobrien
1198944SobrienGNU CC is free software; you can redistribute it and/or modify
1298944Sobrienit under the terms of the GNU General Public License as published by
1398944Sobrienthe Free Software Foundation; either version 2, or (at your option)
1498944Sobrienany later version.
1598944Sobrien
1698944SobrienGNU CC is distributed in the hope that it will be useful,
1798944Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1898944SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1998944SobrienGNU General Public License for more details.
2098944Sobrien
2198944SobrienYou should have received a copy of the GNU General Public License
2298944Sobrienalong with GNU CC; see the file COPYING.  If not, write to
2398944Sobrienthe Free Software Foundation, 59 Temple Place - Suite 330,
2498944SobrienBoston, MA 02111-1307, USA.  */
2598944Sobrien
26130803Smarcel/* $FreeBSD: head/contrib/gcc/config/i386/freebsd.h 58478 2000-03-23 10:18:26Z obrien $ */
27130803Smarcel
2898944Sobrien#undef  CPP_PREDEFINES
2998944Sobrien#define CPP_PREDEFINES 							\
3098944Sobrien  "-Di386 -Acpu(i386) -Amachine(i386)"					\
3198944Sobrien  FBSD_CPP_PREDEFINES
3298944Sobrien
3398944Sobrien#undef  CC1_SPEC
3498944Sobrien#define CC1_SPEC "\
3598944Sobrien  %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \
3698944Sobrien  %{maout: %{!mno-underscores: %{!munderscores: -munderscores }}}"
3798944Sobrien
3898944Sobrien#undef  ASM_SPEC
3998944Sobrien#define ASM_SPEC	"%{v*: -v} %{maout: %{fpic:-k} %{fPIC:-k}}"
4098944Sobrien
4198944Sobrien#undef  ASM_FINAL_SPEC
4298944Sobrien#define ASM_FINAL_SPEC	"%|"
4398944Sobrien
4498944Sobrien/* Provide a LINK_SPEC appropriate for FreeBSD.  Here we provide support
4598944Sobrien   for the special GCC options -static and -shared, which allow us to
4698944Sobrien   link things in one of these three modes by applying the appropriate
4798944Sobrien   combinations of options at link-time. We like to support here for
4898944Sobrien   as many of the other GNU linker options as possible. But I don't
4998944Sobrien   have the time to search for those flags. I am sure how to add
5098944Sobrien   support for -soname shared_object_name. H.J.
5198944Sobrien
5298944Sobrien   I took out %{v:%{!V:-V}}. It is too much :-(. They can use
5398944Sobrien   -Wl,-V.
5498944Sobrien
5598944Sobrien   When the -shared link option is used a final link is not being
5698944Sobrien   done.  */
5798944Sobrien
5898944Sobrien#undef	LINK_SPEC
5998944Sobrien#define LINK_SPEC "\
6098944Sobrien %{p:%e`-p' not supported; use `-pg' and gprof(1)} \
6198944Sobrien  %{maout: %{shared:-Bshareable} \
6298944Sobrien    %{!shared:%{!nostdlib:%{!r:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} \
6398944Sobrien      %{pg:-Bstatic} %{Z}} \
6498944Sobrien    %{assert*} %{R*}} \
6598944Sobrien  %{!maout: \
6698944Sobrien    -m elf_i386 \
6798944Sobrien    %{Wl,*:%*} \
6898944Sobrien    %{assert*} %{R*} %{rpath*} %{defsym*} \
6998944Sobrien    %{shared:-Bshareable %{h*} %{soname*}} \
7098944Sobrien    %{symbolic:-Bsymbolic} \
7198944Sobrien    %{!shared: \
7298944Sobrien      %{!static: \
7398944Sobrien	%{rdynamic: -export-dynamic} \
7498944Sobrien	%{!dynamic-linker: -dynamic-linker /usr/libexec/ld-elf.so.1}} \
7598944Sobrien      %{static:-Bstatic}}}"
7698944Sobrien
7798944Sobrien#undef STARTFILE_SPEC
7898944Sobrien#define STARTFILE_SPEC "\
7998944Sobrien  %{maout: %{shared:c++rt0.o%s} \
8098944Sobrien    %{!shared: \
8198944Sobrien      %{pg:gcrt0.o%s}%{!pg: \
8298944Sobrien	%{static:scrt0.o%s} \
8398944Sobrien	%{!static:crt0.o%s}}}} \
8498944Sobrien  %{!maout: \
8598944Sobrien    %{!shared: \
8698944Sobrien      %{pg:gcrt1.o%s} \
8798944Sobrien      %{!pg: \
8898944Sobrien	%{p:gcrt1.o%s} \
8998944Sobrien	%{!p:crt1.o%s}}} \
9098944Sobrien    crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
9198944Sobrien
9298944Sobrien/* Provide an ENDFILE_SPEC appropriate for FreeBSD/i386.  Here we tack on our
9398944Sobrien   own magical crtend.o file (compare w/crtstuff.c) which provides part of the
9498944Sobrien   support for getting C++ file-scope static object constructed before
9598944Sobrien   entering `main', followed by the normal "finalizer" file, `crtn.o'.  */
96218822Sdim
9798944Sobrien#undef  ENDFILE_SPEC
9898944Sobrien#define ENDFILE_SPEC "\
9998944Sobrien  %{!maout: \
10098944Sobrien    %{!shared:crtend.o%s} \
10198944Sobrien    %{shared:crtendS.o%s} crtn.o%s}"
10298944Sobrien
10398944Sobrien
10498944Sobrien/************************[  Target stuff  ]***********************************/
10598944Sobrien
10698944Sobrien/* Define the actual types of some ANSI-mandated types.
10798944Sobrien   Needs to agree with <machine/ansi.h>.  GCC defaults come from c-decl.c,
10898944Sobrien   c-common.c, and config/<arch>/<arch>.h.  */
10998944Sobrien
11098944Sobrien#undef SIZE_TYPE
11198944Sobrien#define SIZE_TYPE	"unsigned int"
11298944Sobrien
11398944Sobrien#undef PTRDIFF_TYPE
11498944Sobrien#define PTRDIFF_TYPE	"int"
11598944Sobrien
11698944Sobrien/* This is the pseudo-op used to generate a 32-bit word of data with a
11798944Sobrien   specific value in some section.  */
11898944Sobrien
11998944Sobrien#undef INT_ASM_OP
12098944Sobrien#define INT_ASM_OP	".long"
12198944Sobrien
12298944Sobrien/* Biggest alignment supported by the object file format of this
12398944Sobrien   machine.  Use this macro to limit the alignment which can be
12498944Sobrien   specified using the `__attribute__ ((aligned (N)))' construct.  If
12598944Sobrien   not defined, the default value is `BIGGEST_ALIGNMENT'.  */
12698944Sobrien
12798944Sobrien#define MAX_OFILE_ALIGNMENT (32768*8)
12898944Sobrien
12998944Sobrien#undef  TARGET_VERSION
13098944Sobrien#define TARGET_VERSION	fprintf (stderr, " (i386 FreeBSD/ELF)");
13198944Sobrien
13298944Sobrien#define MASK_PROFILER_EPILOGUE	010000000000
13398944Sobrien#define MASK_AOUT		004000000000	/* a.out not elf */
13498944Sobrien#define MASK_UNDERSCORES	002000000000	/* use leading _ */
13598944Sobrien
13698944Sobrien#define TARGET_PROFILER_EPILOGUE	(target_flags & MASK_PROFILER_EPILOGUE)
13798944Sobrien#define TARGET_AOUT			(target_flags & MASK_AOUT)
13898944Sobrien#define TARGET_ELF			((target_flags & MASK_AOUT) == 0)
13998944Sobrien#define TARGET_UNDERSCORES		((target_flags & MASK_UNDERSCORES) != 0)
14098944Sobrien
14198944Sobrien#undef	SUBTARGET_SWITCHES
14298944Sobrien#define SUBTARGET_SWITCHES						\
14398944Sobrien     { "profiler-epilogue",	 MASK_PROFILER_EPILOGUE},		\
14498944Sobrien     { "no-profiler-epilogue",	-MASK_PROFILER_EPILOGUE},		\
14598944Sobrien     { "aout",			 MASK_AOUT},				\
14698944Sobrien     { "no-aout",		-MASK_AOUT},				\
14798944Sobrien     { "underscores",		 MASK_UNDERSCORES},			\
14898944Sobrien     { "no-underscores",	-MASK_UNDERSCORES},
14998944Sobrien
15098944Sobrien/* This goes away when the math emulator is fixed.  */
15198944Sobrien#undef  TARGET_DEFAULT
15298944Sobrien#define TARGET_DEFAULT \
15398944Sobrien  (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
15498944Sobrien
15598944Sobrien/* Prefix for internally generated assembler labels.  If we aren't using
15698944Sobrien   underscores, we are using prefix `.'s to identify labels that should
15798944Sobrien   be ignored, as in `i386/gas.h' --karl@cs.umb.edu  */
15898944Sobrien#undef  LPREFIX
15998944Sobrien#define LPREFIX ((TARGET_UNDERSCORES) ? "L" : ".L")
16098944Sobrien
16198944Sobrien/* FreeBSD ELF using our home-grown crtbegin.o/crtend.o does not support the
16298944Sobrien   DWARF2 unwinding mechanisms.  Once `make world' bootstraping problems with
16398944Sobrien   the EGCS crtstuff.c is overcome, we will switch to the non-sjlj-exceptions
16498944Sobrien   type exception machanism.  */
16598944Sobrien#define DWARF2_UNWIND_INFO 0
16698944Sobrien
16798944Sobrien/* The a.out tools do not support "linkonce" sections. */
16898944Sobrien#undef  SUPPORTS_ONE_ONLY
16998944Sobrien#define SUPPORTS_ONE_ONLY	TARGET_ELF
17098944Sobrien
17198944Sobrien/* Enable alias attribute support.  */
17298944Sobrien#undef  SET_ASM_OP
17398944Sobrien#define SET_ASM_OP		".set"
17498944Sobrien
17598944Sobrien/* The a.out tools do not support "Lscope" .stabs symbols. */
17698944Sobrien#undef  NO_DBX_FUNCTION_END
17798944Sobrien#define NO_DBX_FUNCTION_END	TARGET_AOUT
17898944Sobrien
17998944Sobrien/* In ELF, the function stabs come first, before the relative offsets.  */
18098944Sobrien#undef  DBX_FUNCTION_FIRST
18198944Sobrien#define DBX_CHECK_FUNCTION_FIRST TARGET_ELF
18298944Sobrien
18398944Sobrien/* supply our own hook for calling __main() from main() */
18498944Sobrien#undef  INVOKE__main
18598944Sobrien#define INVOKE__main
18698944Sobrien#undef  GEN_CALL__MAIN
18798944Sobrien#define GEN_CALL__MAIN							\
18898944Sobrien  do {									\
18998944Sobrien    if (!(TARGET_ELF))							\
19098944Sobrien      emit_library_call (gen_rtx (SYMBOL_REF, Pmode, NAME__MAIN), 0,	\
19198944Sobrien			 VOIDmode, 0);					\
19298944Sobrien  } while (0)
19398944Sobrien
19498944Sobrien/* Indicate that jump tables go in the text section.  This is
19598944Sobrien   necessary when compiling PIC code.  */
19698944Sobrien#undef  JUMP_TABLES_IN_TEXT_SECTION
19798944Sobrien#define JUMP_TABLES_IN_TEXT_SECTION	(flag_pic)
19898944Sobrien
19998944Sobrien/* override the exception table positioning */
20098944Sobrien#undef  EXCEPTION_SECTION
20198944Sobrien#define EXCEPTION_SECTION() \
20298944Sobrien  do {									\
20398944Sobrien    if (TARGET_ELF)							\
20498944Sobrien      {									\
20598944Sobrien	named_section (NULL_TREE, ".gcc_except_table", 0);		\
20698944Sobrien      }									\
20798944Sobrien    else								\
20898944Sobrien      {									\
20998944Sobrien	if (flag_pic)							\
21098944Sobrien	  data_section ();						\
21198944Sobrien	else								\
21298944Sobrien	  readonly_data_section ();					\
21398944Sobrien      }									\
21498944Sobrien  } while (0);
21598944Sobrien
21698944Sobrien/* Tell final.c that we don't need a label passed to mcount.  */
21798944Sobrien#undef  NO_PROFILE_DATA
21898944Sobrien#define NO_PROFILE_DATA
21998944Sobrien
22098944Sobrien/* Output assembler code to FILE to begin profiling of the current function.
22198944Sobrien   LABELNO is an optional label.  */
22298944Sobrien
22398944Sobrien#undef  FUNCTION_PROFILER
22498944Sobrien#define FUNCTION_PROFILER(FILE, LABELNO)  \
22598944Sobrien  do {									\
22698944Sobrien    char *_name = TARGET_AOUT ? "mcount" : ".mcount";			\
22798944Sobrien    if (flag_pic)							\
22898944Sobrien      fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", _name);		\
22998944Sobrien    else								\
23098944Sobrien      fprintf ((FILE), "\tcall %s\n", _name);				\
23198944Sobrien  } while (0)
23298944Sobrien
23398944Sobrien/* Output assembler code to FILE to end profiling of the current function.  */
23498944Sobrien
23598944Sobrien#undef  FUNCTION_PROFILER_EPILOGUE
23698944Sobrien#define FUNCTION_PROFILER_EPILOGUE(FILE, DO_RTL)			\
23798944Sobrien  do {									\
23898944Sobrien    if (TARGET_PROFILER_EPILOGUE)					\
23998944Sobrien      {									\
24098944Sobrien	if (DO_RTL)							\
24198944Sobrien	  {								\
24298944Sobrien	  /* ".mexitcount" is specially handled in			\
24398944Sobrien	     ASM_HACK_SYMBOLREF () so that we don't need to handle	\
24498944Sobrien	     flag_pic or TARGET_AOUT here.  */				\
24598944Sobrien	    rtx xop;							\
24698944Sobrien	    xop = gen_rtx_MEM (FUNCTION_MODE,				\
24798944Sobrien			    gen_rtx_SYMBOL_REF (Pmode, ".mexitcount"));	\
24898944Sobrien	    emit_call_insn (gen_rtx (CALL, VOIDmode, xop, const0_rtx));	\
24998944Sobrien	  }								\
25098944Sobrien	else								\
25198944Sobrien	  {								\
25298944Sobrien	  /* XXX this !DO_RTL case is broken but not actually used.  */	\
25398944Sobrien	    char *_name = TARGET_AOUT ? "mcount" : ".mcount";		\
25498944Sobrien	    if (flag_pic)						\
25598944Sobrien	      fprintf (FILE, "\tcall *%s@GOT(%%ebx)\n", _name);		\
25698944Sobrien	    else							\
25798944Sobrien	      fprintf (FILE, "\tcall %s\n", _name);			\
25898944Sobrien	  }								\
25998944Sobrien      }									\
26098944Sobrien  } while (0)
26198944Sobrien
26298944Sobrien
26398944Sobrien/************************[  Assembler stuff  ]********************************/
26498944Sobrien
26598944Sobrien#undef  ASM_APP_ON
26698944Sobrien#define ASM_APP_ON	"#APP\n"
26798944Sobrien
26898944Sobrien#undef  ASM_APP_OFF
26998944Sobrien#define ASM_APP_OFF	"#NO_APP\n"
27098944Sobrien
27198944Sobrien/* This is how to begin an assembly language file.
272130803Smarcel   The .file command should always begin the output.
273130803Smarcel   ELF also needs a .version.  */
274130803Smarcel
275130803Smarcel#undef  ASM_FILE_START
27698944Sobrien#define ASM_FILE_START(FILE)						\
27798944Sobrien  do {									\
27898944Sobrien    output_file_directive ((FILE), main_input_filename);		\
27998944Sobrien    if (TARGET_ELF)							\
28098944Sobrien      fprintf ((FILE), "\t.version\t\"01.01\"\n");			\
28198944Sobrien  } while (0)
28298944Sobrien
28398944Sobrien/* This is how to store into the string BUF
28498944Sobrien   the symbol_ref name of an internal numbered label where
28598944Sobrien   PREFIX is the class of label and NUM is the number within the class.
28698944Sobrien   This is suitable for output with `assemble_name'.  */
28798944Sobrien#undef	ASM_GENERATE_INTERNAL_LABEL
28898944Sobrien#define ASM_GENERATE_INTERNAL_LABEL(BUF, PREFIX, NUMBER)		\
289130803Smarcel  sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".",		\
290130803Smarcel	   (PREFIX), (NUMBER))
291130803Smarcel
29298944Sobrien/* This is how to output an internal numbered label where
29398944Sobrien   PREFIX is the class of label and NUM is the number within the class.
29498944Sobrien   For most svr4/ELF systems, the convention is that any symbol which begins
29598944Sobrien   with a period is not put into the linker symbol table by the assembler.  */
29698944Sobrien#undef	ASM_OUTPUT_INTERNAL_LABEL
29798944Sobrien#define	ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)			\
29898944Sobrien  fprintf ((FILE), "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".",	\
29998944Sobrien	   (PREFIX), (NUM))
30098944Sobrien
30198944Sobrien/* This is how to output a reference to a user-level label named NAME.  */
30298944Sobrien#undef  ASM_OUTPUT_LABELREF
30398944Sobrien#define ASM_OUTPUT_LABELREF(FILE, NAME)					\
30498944Sobrien  do {									\
30598944Sobrien    char *_name = (NAME);						\
30698944Sobrien    /* Hack to avoid writing lots of rtl in				\
30798944Sobrien       FUNCTION_PROFILER_EPILOGUE ().  */				\
30898944Sobrien    if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)		\
30998944Sobrien      {									\
31098944Sobrien	if (TARGET_AOUT)						\
31198944Sobrien	  _name++;							\
31298944Sobrien	if (flag_pic)							\
31398944Sobrien	  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)
748