freebsd.h revision 68601
134229Speter/* Definitions for Intel 386 running FreeBSD with either a.out or ELF format
258478Sobrien   Copyright (C) 1996-2000 Free Software Foundation, Inc.
334229Speter   Contributed by Eric Youngdale.
434229Speter   Modified for stabs-in-ELF by H.J. Lu.
551408Sobrien   Adapted from GNU/Linux version by John Polstra.
634229Speter   Added support for generating "old a.out gas" on the fly by Peter Wemm.
752112Sobrien   Continued development by David O'Brien <obrien@freebsd.org>
818334Speter
918334SpeterThis file is part of GNU CC.
1018334Speter
1118334SpeterGNU CC is free software; you can redistribute it and/or modify
1218334Speterit under the terms of the GNU General Public License as published by
1318334Speterthe Free Software Foundation; either version 2, or (at your option)
1418334Speterany later version.
1518334Speter
1618334SpeterGNU CC is distributed in the hope that it will be useful,
1718334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1818334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1918334SpeterGNU General Public License for more details.
2018334Speter
2118334SpeterYou should have received a copy of the GNU General Public License
2218334Speteralong with GNU CC; see the file COPYING.  If not, write to
2318334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
2418334SpeterBoston, MA 02111-1307, USA.  */
2518334Speter
2651408Sobrien/* $FreeBSD: head/contrib/gcc/config/i386/freebsd.h 68601 2000-11-11 04:50:51Z obrien $ */
2718334Speter
2858478Sobrien#undef  CPP_PREDEFINES
2958478Sobrien#define CPP_PREDEFINES 							\
3058478Sobrien  "-Di386 -Acpu(i386) -Amachine(i386)"					\
3158478Sobrien  FBSD_CPP_PREDEFINES
3251408Sobrien
3358478Sobrien#undef  CC1_SPEC
3458478Sobrien#define CC1_SPEC "\
3558478Sobrien  %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \
3658478Sobrien  %{maout: %{!mno-underscores: %{!munderscores: -munderscores }}}"
3751408Sobrien
3858478Sobrien#undef  ASM_SPEC
3958478Sobrien#define ASM_SPEC	"%{v*: -v} %{maout: %{fpic:-k} %{fPIC:-k}}"
4058478Sobrien
4158478Sobrien#undef  ASM_FINAL_SPEC
4258478Sobrien#define ASM_FINAL_SPEC	"%|"
4358478Sobrien
4458478Sobrien/* Provide a LINK_SPEC appropriate for FreeBSD.  Here we provide support
4558478Sobrien   for the special GCC options -static and -shared, which allow us to
4658478Sobrien   link things in one of these three modes by applying the appropriate
4758478Sobrien   combinations of options at link-time. We like to support here for
4858478Sobrien   as many of the other GNU linker options as possible. But I don't
4958478Sobrien   have the time to search for those flags. I am sure how to add
5058478Sobrien   support for -soname shared_object_name. H.J.
5158478Sobrien
5258478Sobrien   I took out %{v:%{!V:-V}}. It is too much :-(. They can use
5358478Sobrien   -Wl,-V.
5458478Sobrien
5558478Sobrien   When the -shared link option is used a final link is not being
5658478Sobrien   done.  */
5758478Sobrien
5858478Sobrien#undef	LINK_SPEC
5958478Sobrien#define LINK_SPEC "\
6058478Sobrien %{p:%e`-p' not supported; use `-pg' and gprof(1)} \
6158478Sobrien  %{maout: %{shared:-Bshareable} \
6258478Sobrien    %{!shared:%{!nostdlib:%{!r:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} \
6358478Sobrien      %{pg:-Bstatic} %{Z}} \
6458478Sobrien    %{assert*} %{R*}} \
6558478Sobrien  %{!maout: \
6658478Sobrien    -m elf_i386 \
6758478Sobrien    %{Wl,*:%*} \
6858478Sobrien    %{assert*} %{R*} %{rpath*} %{defsym*} \
6958478Sobrien    %{shared:-Bshareable %{h*} %{soname*}} \
7058478Sobrien    %{symbolic:-Bsymbolic} \
7158478Sobrien    %{!shared: \
7258478Sobrien      %{!static: \
7358478Sobrien	%{rdynamic: -export-dynamic} \
7458478Sobrien	%{!dynamic-linker: -dynamic-linker /usr/libexec/ld-elf.so.1}} \
7558478Sobrien      %{static:-Bstatic}}}"
7658478Sobrien
7758478Sobrien#undef STARTFILE_SPEC
7858478Sobrien#define STARTFILE_SPEC "\
7958478Sobrien  %{maout: %{shared:c++rt0.o%s} \
8058478Sobrien    %{!shared: \
8158478Sobrien      %{pg:gcrt0.o%s}%{!pg: \
8258478Sobrien	%{static:scrt0.o%s} \
8358478Sobrien	%{!static:crt0.o%s}}}} \
8458478Sobrien  %{!maout: \
8558478Sobrien    %{!shared: \
8658478Sobrien      %{pg:gcrt1.o%s} \
8758478Sobrien      %{!pg: \
8858478Sobrien	%{p:gcrt1.o%s} \
8958478Sobrien	%{!p:crt1.o%s}}} \
9058478Sobrien    crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
9158478Sobrien
9258478Sobrien/* Provide an ENDFILE_SPEC appropriate for FreeBSD/i386.  Here we tack on our
9358478Sobrien   own magical crtend.o file (compare w/crtstuff.c) which provides part of the
9458478Sobrien   support for getting C++ file-scope static object constructed before
9558478Sobrien   entering `main', followed by the normal "finalizer" file, `crtn.o'.  */
9658478Sobrien
9758478Sobrien#undef  ENDFILE_SPEC
9858478Sobrien#define ENDFILE_SPEC "\
9958478Sobrien  %{!maout: \
10058478Sobrien    %{!shared:crtend.o%s} \
10158478Sobrien    %{shared:crtendS.o%s} crtn.o%s}"
10258478Sobrien
10358478Sobrien
10458478Sobrien/************************[  Target stuff  ]***********************************/
10558478Sobrien
10658478Sobrien/* Define the actual types of some ANSI-mandated types.
10758478Sobrien   Needs to agree with <machine/ansi.h>.  GCC defaults come from c-decl.c,
10858478Sobrien   c-common.c, and config/<arch>/<arch>.h.  */
10958478Sobrien
11058478Sobrien#undef SIZE_TYPE
11158478Sobrien#define SIZE_TYPE	"unsigned int"
11258478Sobrien
11358478Sobrien#undef PTRDIFF_TYPE
11458478Sobrien#define PTRDIFF_TYPE	"int"
11558478Sobrien
11658478Sobrien/* This is the pseudo-op used to generate a 32-bit word of data with a
11758478Sobrien   specific value in some section.  */
11858478Sobrien
11958478Sobrien#undef INT_ASM_OP
12058478Sobrien#define INT_ASM_OP	".long"
12158478Sobrien
12258478Sobrien/* Biggest alignment supported by the object file format of this
12358478Sobrien   machine.  Use this macro to limit the alignment which can be
12458478Sobrien   specified using the `__attribute__ ((aligned (N)))' construct.  If
12558478Sobrien   not defined, the default value is `BIGGEST_ALIGNMENT'.  */
12658478Sobrien
12758478Sobrien#define MAX_OFILE_ALIGNMENT (32768*8)
12858478Sobrien
12958478Sobrien#undef  TARGET_VERSION
13058478Sobrien#define TARGET_VERSION	fprintf (stderr, " (i386 FreeBSD/ELF)");
13158478Sobrien
13234229Speter#define MASK_PROFILER_EPILOGUE	010000000000
13334229Speter#define MASK_AOUT		004000000000	/* a.out not elf */
13434229Speter#define MASK_UNDERSCORES	002000000000	/* use leading _ */
13518349Speter
13634229Speter#define TARGET_PROFILER_EPILOGUE	(target_flags & MASK_PROFILER_EPILOGUE)
13734229Speter#define TARGET_AOUT			(target_flags & MASK_AOUT)
13834229Speter#define TARGET_ELF			((target_flags & MASK_AOUT) == 0)
13934229Speter#define TARGET_UNDERSCORES		((target_flags & MASK_UNDERSCORES) != 0)
14018349Speter
14134229Speter#undef	SUBTARGET_SWITCHES
14252112Sobrien#define SUBTARGET_SWITCHES						\
14368601Sobrien  { "profiler-epilogue",	 MASK_PROFILER_EPILOGUE, "Function profiler epilogue"}, \
14468601Sobrien  { "no-profiler-epilogue",	-MASK_PROFILER_EPILOGUE, "No function profiler epilogue"}, \
14568601Sobrien  { "aout",			 MASK_AOUT, "Generate an a.out (vs. ELF) binary"}, \
14668601Sobrien  { "no-aout",			-MASK_AOUT, "Do not generate an a.out binary"}, \
14768601Sobrien  { "underscores",		 MASK_UNDERSCORES, "Add leading underscores to symbols"}, \
14868601Sobrien  { "no-underscores",		-MASK_UNDERSCORES, "Do not add leading underscores to symbols"},
14918349Speter
15058478Sobrien/* This goes away when the math emulator is fixed.  */
15158478Sobrien#undef  TARGET_DEFAULT
15258478Sobrien#define TARGET_DEFAULT \
15358478Sobrien  (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
15458478Sobrien
15534229Speter/* Prefix for internally generated assembler labels.  If we aren't using
15634229Speter   underscores, we are using prefix `.'s to identify labels that should
15734229Speter   be ignored, as in `i386/gas.h' --karl@cs.umb.edu  */
15834229Speter#undef  LPREFIX
15934229Speter#define LPREFIX ((TARGET_UNDERSCORES) ? "L" : ".L")
16018349Speter
16158478Sobrien/* The a.out tools do not support "linkonce" sections. */
16258478Sobrien#undef  SUPPORTS_ONE_ONLY
16358478Sobrien#define SUPPORTS_ONE_ONLY	TARGET_ELF
16418349Speter
16558478Sobrien/* Enable alias attribute support.  */
16658478Sobrien#undef  SET_ASM_OP
16758478Sobrien#define SET_ASM_OP		".set"
16818349Speter
16958478Sobrien/* The a.out tools do not support "Lscope" .stabs symbols. */
17058478Sobrien#undef  NO_DBX_FUNCTION_END
17158478Sobrien#define NO_DBX_FUNCTION_END	TARGET_AOUT
17251408Sobrien
17358478Sobrien/* In ELF, the function stabs come first, before the relative offsets.  */
17458478Sobrien#undef  DBX_FUNCTION_FIRST
17558478Sobrien#define DBX_CHECK_FUNCTION_FIRST TARGET_ELF
17618349Speter
17758478Sobrien/* supply our own hook for calling __main() from main() */
17858478Sobrien#undef  INVOKE__main
17958478Sobrien#define INVOKE__main
18058478Sobrien#undef  GEN_CALL__MAIN
18158478Sobrien#define GEN_CALL__MAIN							\
18258478Sobrien  do {									\
18358478Sobrien    if (!(TARGET_ELF))							\
18458478Sobrien      emit_library_call (gen_rtx (SYMBOL_REF, Pmode, NAME__MAIN), 0,	\
18558478Sobrien			 VOIDmode, 0);					\
18658478Sobrien  } while (0)
18758478Sobrien
18858478Sobrien/* Indicate that jump tables go in the text section.  This is
18958478Sobrien   necessary when compiling PIC code.  */
19058478Sobrien#undef  JUMP_TABLES_IN_TEXT_SECTION
19158478Sobrien#define JUMP_TABLES_IN_TEXT_SECTION	(flag_pic)
19258478Sobrien
19358478Sobrien/* override the exception table positioning */
19458478Sobrien#undef  EXCEPTION_SECTION
19558478Sobrien#define EXCEPTION_SECTION() \
19658478Sobrien  do {									\
19758478Sobrien    if (TARGET_ELF)							\
19858478Sobrien      {									\
19958478Sobrien	named_section (NULL_TREE, ".gcc_except_table", 0);		\
20058478Sobrien      }									\
20158478Sobrien    else								\
20258478Sobrien      {									\
20358478Sobrien	if (flag_pic)							\
20458478Sobrien	  data_section ();						\
20558478Sobrien	else								\
20658478Sobrien	  readonly_data_section ();					\
20758478Sobrien      }									\
20858478Sobrien  } while (0);
20958478Sobrien
21058478Sobrien/* Tell final.c that we don't need a label passed to mcount.  */
21158478Sobrien#undef  NO_PROFILE_DATA
21258478Sobrien#define NO_PROFILE_DATA
21358478Sobrien
21458478Sobrien/* Output assembler code to FILE to begin profiling of the current function.
21558478Sobrien   LABELNO is an optional label.  */
21658478Sobrien
21758478Sobrien#undef  FUNCTION_PROFILER
21858478Sobrien#define FUNCTION_PROFILER(FILE, LABELNO)  \
21958478Sobrien  do {									\
22058478Sobrien    char *_name = TARGET_AOUT ? "mcount" : ".mcount";			\
22158478Sobrien    if (flag_pic)							\
22258478Sobrien      fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", _name);		\
22358478Sobrien    else								\
22458478Sobrien      fprintf ((FILE), "\tcall %s\n", _name);				\
22558478Sobrien  } while (0)
22658478Sobrien
22758478Sobrien/* Output assembler code to FILE to end profiling of the current function.  */
22858478Sobrien
22958478Sobrien#undef  FUNCTION_PROFILER_EPILOGUE
23058478Sobrien#define FUNCTION_PROFILER_EPILOGUE(FILE, DO_RTL)			\
23158478Sobrien  do {									\
23258478Sobrien    if (TARGET_PROFILER_EPILOGUE)					\
23358478Sobrien      {									\
23458478Sobrien	if (DO_RTL)							\
23558478Sobrien	  {								\
23658478Sobrien	  /* ".mexitcount" is specially handled in			\
23758478Sobrien	     ASM_HACK_SYMBOLREF () so that we don't need to handle	\
23858478Sobrien	     flag_pic or TARGET_AOUT here.  */				\
23958478Sobrien	    rtx xop;							\
24058478Sobrien	    xop = gen_rtx_MEM (FUNCTION_MODE,				\
24158478Sobrien			    gen_rtx_SYMBOL_REF (Pmode, ".mexitcount"));	\
24258478Sobrien	    emit_call_insn (gen_rtx (CALL, VOIDmode, xop, const0_rtx));	\
24358478Sobrien	  }								\
24458478Sobrien	else								\
24558478Sobrien	  {								\
24658478Sobrien	  /* XXX this !DO_RTL case is broken but not actually used.  */	\
24758478Sobrien	    char *_name = TARGET_AOUT ? "mcount" : ".mcount";		\
24858478Sobrien	    if (flag_pic)						\
24958478Sobrien	      fprintf (FILE, "\tcall *%s@GOT(%%ebx)\n", _name);		\
25058478Sobrien	    else							\
25158478Sobrien	      fprintf (FILE, "\tcall %s\n", _name);			\
25258478Sobrien	  }								\
25358478Sobrien      }									\
25458478Sobrien  } while (0)
25558478Sobrien
25658478Sobrien
25758478Sobrien/************************[  Assembler stuff  ]********************************/
25858478Sobrien
25958478Sobrien#undef  ASM_APP_ON
26058478Sobrien#define ASM_APP_ON	"#APP\n"
26158478Sobrien
26258478Sobrien#undef  ASM_APP_OFF
26358478Sobrien#define ASM_APP_OFF	"#NO_APP\n"
26458478Sobrien
26558478Sobrien/* This is how to begin an assembly language file.
26658478Sobrien   The .file command should always begin the output.
26758478Sobrien   ELF also needs a .version.  */
26858478Sobrien
26958478Sobrien#undef  ASM_FILE_START
27034229Speter#define ASM_FILE_START(FILE)						\
27134229Speter  do {									\
27258478Sobrien    output_file_directive ((FILE), main_input_filename);		\
27358478Sobrien    if (TARGET_ELF)							\
27458478Sobrien      fprintf ((FILE), "\t.version\t\"01.01\"\n");			\
27534229Speter  } while (0)
27618349Speter
27734229Speter/* This is how to store into the string BUF
27834229Speter   the symbol_ref name of an internal numbered label where
27934229Speter   PREFIX is the class of label and NUM is the number within the class.
28034229Speter   This is suitable for output with `assemble_name'.  */
28134229Speter#undef	ASM_GENERATE_INTERNAL_LABEL
28258478Sobrien#define ASM_GENERATE_INTERNAL_LABEL(BUF, PREFIX, NUMBER)		\
28358478Sobrien  sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".",		\
28458478Sobrien	   (PREFIX), (NUMBER))
28518349Speter
28634229Speter/* This is how to output an internal numbered label where
28758478Sobrien   PREFIX is the class of label and NUM is the number within the class.
28858478Sobrien   For most svr4/ELF systems, the convention is that any symbol which begins
28958478Sobrien   with a period is not put into the linker symbol table by the assembler.  */
29034229Speter#undef	ASM_OUTPUT_INTERNAL_LABEL
29134229Speter#define	ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)			\
29252112Sobrien  fprintf ((FILE), "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".",	\
29352112Sobrien	   (PREFIX), (NUM))
29418334Speter
29558478Sobrien/* This is how to output a reference to a user-level label named NAME.  */
29658478Sobrien#undef  ASM_OUTPUT_LABELREF
29758478Sobrien#define ASM_OUTPUT_LABELREF(FILE, NAME)					\
29858478Sobrien  do {									\
29958478Sobrien    char *_name = (NAME);						\
30058478Sobrien    /* Hack to avoid writing lots of rtl in				\
30158478Sobrien       FUNCTION_PROFILER_EPILOGUE ().  */				\
30258478Sobrien    if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)		\
30358478Sobrien      {									\
30458478Sobrien	if (TARGET_AOUT)						\
30558478Sobrien	  _name++;							\
30658478Sobrien	if (flag_pic)							\
30758478Sobrien	  fprintf ((FILE), "*%s@GOT(%%ebx)", _name);			\
30858478Sobrien	else								\
30958478Sobrien	  fprintf ((FILE), "%s", _name);				\
31058478Sobrien      }									\
31158478Sobrien    else								\
31258478Sobrien      fprintf (FILE, "%s%s", TARGET_UNDERSCORES ? "_" : "", _name);	\
31358478Sobrien} while (0)
31458478Sobrien
31556810Sobrien/* This is how to hack on the symbol code of certain relcalcitrant
31656810Sobrien   symbols to modify their output in output_pic_addr_const ().  */
31756810Sobrien
31858478Sobrien#undef  ASM_HACK_SYMBOLREF_CODE
31956810Sobrien#define ASM_HACK_SYMBOLREF_CODE(NAME, CODE)				\
32058478Sobrien  do {									\
32158478Sobrien    /* Part of hack to avoid writing lots of rtl in			\
32258478Sobrien       FUNCTION_PROFILER_EPILOGUE ().  */				\
32358478Sobrien    char *_name = (NAME);						\
32458478Sobrien    if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)		\
32558478Sobrien      (CODE) = 'X';							\
32658478Sobrien  } while (0)
32756810Sobrien
32834229Speter/* This is how to output an element of a case-vector that is relative.
32934229Speter   This is only used for PIC code.  See comments by the `casesi' insn in
33034229Speter   i386.md for an explanation of the expression this outputs. */
33158478Sobrien#undef  ASM_OUTPUT_ADDR_DIFF_ELT
33258478Sobrien#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)		\
33352112Sobrien  fprintf ((FILE), "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, (VALUE))
33418349Speter
33558478Sobrien#undef  ASM_OUTPUT_ALIGN
33652112Sobrien#define ASM_OUTPUT_ALIGN(FILE, LOG)      				\
33751408Sobrien  if ((LOG)!=0) {							\
33851408Sobrien    if (in_text_section())						\
33951408Sobrien      fprintf ((FILE), "\t.p2align %d,0x90\n", (LOG));			\
34051408Sobrien    else								\
34151408Sobrien      fprintf ((FILE), "\t.p2align %d\n", (LOG));			\
34251408Sobrien  }
34318349Speter
34458478Sobrien#undef  ASM_OUTPUT_SOURCE_LINE
34558478Sobrien#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE)				\
34658478Sobrien  do {									\
34758478Sobrien    static int sym_lineno = 1;						\
34858478Sobrien    if (TARGET_ELF)							\
34958478Sobrien      {									\
35058478Sobrien	fprintf ((FILE), ".stabn 68,0,%d,.LM%d-", (LINE), sym_lineno);	\
35158478Sobrien	assemble_name ((FILE), 						\
35258478Sobrien		XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));	\
35358478Sobrien	fprintf ((FILE), "\n.LM%d:\n", sym_lineno);			\
35458478Sobrien	sym_lineno += 1;						\
35558478Sobrien      }									\
35658478Sobrien    else								\
35758478Sobrien      {									\
35858478Sobrien	fprintf ((FILE), "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE,	\
35958478Sobrien		lineno);						\
36058478Sobrien      }									\
36158478Sobrien  } while (0)
36218334Speter
36358478Sobrien/* These macros generate the special .type and .size directives which
36458478Sobrien   are used to set the corresponding fields of the linker symbol table
36558478Sobrien   entries in an ELF object file under SVR4.  These macros also output
36658478Sobrien   the starting labels for the relevant functions/objects.  */
36751408Sobrien
36858478Sobrien/* Write the extra assembler code needed to declare a function properly.
36958478Sobrien   Some svr4 assemblers need to also have something extra said about the
37058478Sobrien   function's return value.  We allow for that here.  */
37151408Sobrien
37258478Sobrien#undef  ASM_DECLARE_FUNCTION_NAME
37358478Sobrien#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
37434229Speter  do {									\
37558478Sobrien    fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);				\
37658478Sobrien    assemble_name (FILE, NAME);						\
37758478Sobrien    putc (',', FILE);							\
37858478Sobrien    fprintf (FILE, TYPE_OPERAND_FMT, "function");			\
37958478Sobrien    putc ('\n', FILE);							\
38058478Sobrien    ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));			\
38158478Sobrien    ASM_OUTPUT_LABEL(FILE, NAME);					\
38234229Speter  } while (0)
38318334Speter
38458478Sobrien/* This is how to declare the size of a function.  */
38518349Speter
38658478Sobrien#undef  ASM_DECLARE_FUNCTION_SIZE
38758478Sobrien#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)			\
38858478Sobrien  do {									\
38958478Sobrien    if (!flag_inhibit_size_directive)					\
39058478Sobrien      {									\
39158478Sobrien        char label[256];						\
39258478Sobrien	static int labelno;						\
39358478Sobrien	labelno++;							\
39458478Sobrien	ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);		\
39558478Sobrien	ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno);		\
39658478Sobrien	fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);				\
39758478Sobrien	assemble_name (FILE, (FNAME));					\
39858478Sobrien        fprintf (FILE, ",");						\
39958478Sobrien	assemble_name (FILE, label);					\
40058478Sobrien        fprintf (FILE, "-");						\
40158478Sobrien	assemble_name (FILE, (FNAME));					\
40258478Sobrien	putc ('\n', FILE);						\
40358478Sobrien      }									\
40458478Sobrien  } while (0)
40518334Speter
40618334Speter
40758478Sobrien/* The routine used to output NUL terminated strings.  We use a special
40858478Sobrien   version of this for most svr4 targets because doing so makes the
40958478Sobrien   generated assembly code more compact (and thus faster to assemble)
41058478Sobrien   as well as more readable, especially for targets like the i386
41158478Sobrien   (where the only alternative is to output character sequences as
41258478Sobrien   comma separated lists of numbers).   */
41318334Speter
41458478Sobrien#undef  ASM_OUTPUT_LIMITED_STRING
41558478Sobrien#define ASM_OUTPUT_LIMITED_STRING(FILE, STR)				\
41658478Sobrien  do {									\
41758478Sobrien      register unsigned char *_limited_str = (unsigned char *) (STR);	\
41858478Sobrien      register unsigned ch;						\
41958478Sobrien      fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP);			\
42058478Sobrien      for (; (ch = *_limited_str); _limited_str++)			\
42158478Sobrien        {								\
42258478Sobrien	  register int escape;						\
42358478Sobrien	  switch (escape = ESCAPES[ch])					\
42458478Sobrien	    {								\
42558478Sobrien	    case 0:							\
42658478Sobrien	      putc (ch, (FILE));					\
42758478Sobrien	      break;							\
42858478Sobrien	    case 1:							\
42958478Sobrien	      fprintf ((FILE), "\\%03o", ch);				\
43058478Sobrien	      break;							\
43158478Sobrien	    default:							\
43258478Sobrien	      putc ('\\', (FILE));					\
43358478Sobrien	      putc (escape, (FILE));					\
43458478Sobrien	      break;							\
43558478Sobrien	    }								\
43658478Sobrien        }								\
43758478Sobrien      fprintf ((FILE), "\"\n");						\
43858478Sobrien  } while (0)
43934269Speter
44058478Sobrien/* Switch into a generic section.
44158478Sobrien
44258478Sobrien   We make the section read-only and executable for a function decl,
44358478Sobrien   read-only for a const data decl, and writable for a non-const data decl.
44458478Sobrien
44558478Sobrien   If the section has already been defined, we must not
44658478Sobrien   emit the attributes here. The SVR4 assembler does not
44758478Sobrien   recognize section redefinitions.
44858478Sobrien   If DECL is NULL, no attributes are emitted.  */
44934284Speter
45058478Sobrien#undef  ASM_OUTPUT_SECTION_NAME
45158478Sobrien#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)		\
45258478Sobrien  do {									\
45358478Sobrien    static struct section_info						\
45458478Sobrien      {									\
45558478Sobrien	struct section_info *next;				        \
45658478Sobrien	char *name;						        \
45758478Sobrien	enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type;		\
45858478Sobrien      } *sections;							\
45958478Sobrien    struct section_info *s;						\
46058478Sobrien    char *mode;								\
46158478Sobrien    enum sect_enum type;						\
46258478Sobrien									\
46358478Sobrien    for (s = sections; s; s = s->next)					\
46458478Sobrien      if (!strcmp (NAME, s->name))					\
46558478Sobrien	break;								\
46658478Sobrien									\
46758478Sobrien    if (DECL && TREE_CODE (DECL) == FUNCTION_DECL)			\
46858478Sobrien      type = SECT_EXEC, mode = "ax";					\
46958478Sobrien    else if (DECL && DECL_READONLY_SECTION (DECL, RELOC))		\
47058478Sobrien      type = SECT_RO, mode = "a";					\
47158478Sobrien    else								\
47258478Sobrien      type = SECT_RW, mode = "aw";					\
47358478Sobrien									\
47458478Sobrien    if (s == 0)								\
47558478Sobrien      {									\
47658478Sobrien	s = (struct section_info *) xmalloc (sizeof (struct section_info));  \
47758478Sobrien	s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME));	\
47858478Sobrien	strcpy (s->name, NAME);						\
47958478Sobrien	s->type = type;							\
48058478Sobrien	s->next = sections;						\
48158478Sobrien	sections = s;							\
48258478Sobrien	fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, mode);	\
48358478Sobrien      }									\
48458478Sobrien    else								\
48558478Sobrien      {									\
48658478Sobrien	if (DECL && s->type != type)					\
48758478Sobrien	  error_with_decl (DECL, "%s causes a section type conflict");	\
48858478Sobrien									\
48958478Sobrien	fprintf (FILE, ".section\t%s\n", NAME);				\
49058478Sobrien      }									\
49158478Sobrien  } while (0)
49218334Speter
49358478Sobrien#undef  MAKE_DECL_ONE_ONLY
49458478Sobrien#define MAKE_DECL_ONE_ONLY(DECL)	(DECL_WEAK (DECL) = 1)
49558478Sobrien#undef  UNIQUE_SECTION_P
49658478Sobrien#define UNIQUE_SECTION_P(DECL)		(DECL_ONE_ONLY (DECL))
49758478Sobrien#undef  UNIQUE_SECTION
49858478Sobrien#define UNIQUE_SECTION(DECL,RELOC)					\
49958478Sobrien  do {									\
50058478Sobrien    int len;								\
50158478Sobrien    char *name, *string, *prefix;					\
50258478Sobrien									\
50358478Sobrien    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL));		\
50458478Sobrien									\
50558478Sobrien    if (! DECL_ONE_ONLY (DECL))						\
50658478Sobrien      {									\
50758478Sobrien	prefix = ".";                                             	\
50858478Sobrien	if (TREE_CODE (DECL) == FUNCTION_DECL)				\
50958478Sobrien	  prefix = ".text.";						\
51058478Sobrien	else if (DECL_READONLY_SECTION (DECL, RELOC))			\
51158478Sobrien	  prefix = ".rodata.";						\
51258478Sobrien	else								\
51358478Sobrien	  prefix = ".data.";						\
51458478Sobrien      }									\
51558478Sobrien    else if (TREE_CODE (DECL) == FUNCTION_DECL)				\
51658478Sobrien      prefix = ".gnu.linkonce.t.";					\
51758478Sobrien    else if (DECL_READONLY_SECTION (DECL, RELOC))			\
51858478Sobrien      prefix = ".gnu.linkonce.r.";					\
51958478Sobrien    else								\
52058478Sobrien      prefix = ".gnu.linkonce.d.";					\
52158478Sobrien									\
52258478Sobrien    len = strlen (name) + strlen (prefix);				\
52358478Sobrien    string = alloca (len + 1);						\
52458478Sobrien    sprintf (string, "%s%s", prefix, name);				\
52558478Sobrien									\
52658478Sobrien    DECL_SECTION_NAME (DECL) = build_string (len, string);		\
52758478Sobrien  } while (0)
52834229Speter
52958478Sobrien/* A C statement or statements to switch to the appropriate
53058478Sobrien   section for output of DECL.  DECL is either a `VAR_DECL' node
53158478Sobrien   or a constant of some sort.  RELOC indicates whether forming
53258478Sobrien   the initial value of DECL requires link-time relocations.  */
53334229Speter
53458478Sobrien#undef  SELECT_SECTION
53558478Sobrien#define SELECT_SECTION(DECL,RELOC)					\
53658478Sobrien  {									\
53758478Sobrien    if (flag_pic && RELOC)						\
53858478Sobrien      data_section ();							\
53958478Sobrien    else if (TREE_CODE (DECL) == STRING_CST)				\
54058478Sobrien      {									\
54158478Sobrien	if (! flag_writable_strings)					\
54258478Sobrien	  const_section ();						\
54358478Sobrien	else								\
54458478Sobrien	  data_section ();						\
54558478Sobrien      }									\
54658478Sobrien    else if (TREE_CODE (DECL) == VAR_DECL)				\
54758478Sobrien      {									\
54858478Sobrien	if (! DECL_READONLY_SECTION (DECL, RELOC))			\
54958478Sobrien	  data_section ();						\
55058478Sobrien	else								\
55158478Sobrien	  const_section ();						\
55258478Sobrien      }									\
55358478Sobrien    else								\
55458478Sobrien      const_section ();							\
55558478Sobrien  }
55658478Sobrien
55734229Speter/* Define macro used to output shift-double opcodes when the shift
55834229Speter   count is in %cl.  Some assemblers require %cl as an argument;
55934229Speter   some don't.
56034229Speter
56134229Speter   *OLD* GAS requires the %cl argument, so override i386/unix.h. */
56234229Speter
56358478Sobrien#undef  AS3_SHIFT_DOUBLE
56458478Sobrien#define AS3_SHIFT_DOUBLE(a,b,c,d)	AS3 (a,b,c,d)
56534229Speter
56618334Speter
56758478Sobrien/************************[  Debugger stuff  ]*********************************/
56818334Speter
56951408Sobrien/* Copy this from the svr4 specifications... */
57051408Sobrien/* Define the register numbers to be used in Dwarf debugging information.
57151408Sobrien   The SVR4 reference port C compiler uses the following register numbers
57251408Sobrien   in its Dwarf output code:
57351408Sobrien	0 for %eax (gnu regno = 0)
57451408Sobrien	1 for %ecx (gnu regno = 2)
57551408Sobrien	2 for %edx (gnu regno = 1)
57651408Sobrien	3 for %ebx (gnu regno = 3)
57751408Sobrien	4 for %esp (gnu regno = 7)
57851408Sobrien	5 for %ebp (gnu regno = 6)
57951408Sobrien	6 for %esi (gnu regno = 4)
58051408Sobrien	7 for %edi (gnu regno = 5)
58151408Sobrien   The following three DWARF register numbers are never generated by
58251408Sobrien   the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
58351408Sobrien   believes these numbers have these meanings.
58451408Sobrien	8  for %eip    (no gnu equivalent)
58551408Sobrien	9  for %eflags (no gnu equivalent)
58651408Sobrien	10 for %trapno (no gnu equivalent)
58751408Sobrien   It is not at all clear how we should number the FP stack registers
58851408Sobrien   for the x86 architecture.  If the version of SDB on x86/svr4 were
58951408Sobrien   a bit less brain dead with respect to floating-point then we would
59051408Sobrien   have a precedent to follow with respect to DWARF register numbers
59151408Sobrien   for x86 FP registers, but the SDB on x86/svr4 is so completely
59251408Sobrien   broken with respect to FP registers that it is hardly worth thinking
59351408Sobrien   of it as something to strive for compatibility with.
59451408Sobrien   The version of x86/svr4 SDB I have at the moment does (partially)
59551408Sobrien   seem to believe that DWARF register number 11 is associated with
59651408Sobrien   the x86 register %st(0), but that's about all.  Higher DWARF
59751408Sobrien   register numbers don't seem to be associated with anything in
59851408Sobrien   particular, and even for DWARF regno 11, SDB only seems to under-
59951408Sobrien   stand that it should say that a variable lives in %st(0) (when
60051408Sobrien   asked via an `=' command) if we said it was in DWARF regno 11,
60151408Sobrien   but SDB still prints garbage when asked for the value of the
60251408Sobrien   variable in question (via a `/' command).
60351408Sobrien   (Also note that the labels SDB prints for various FP stack regs
60451408Sobrien   when doing an `x' command are all wrong.)
60551408Sobrien   Note that these problems generally don't affect the native SVR4
60651408Sobrien   C compiler because it doesn't allow the use of -O with -g and
60751408Sobrien   because when it is *not* optimizing, it allocates a memory
60851408Sobrien   location for each floating-point variable, and the memory
60951408Sobrien   location is what gets described in the DWARF AT_location
61051408Sobrien   attribute for the variable in question.
61151408Sobrien   Regardless of the severe mental illness of the x86/svr4 SDB, we
61251408Sobrien   do something sensible here and we use the following DWARF
61351408Sobrien   register numbers.  Note that these are all stack-top-relative
61451408Sobrien   numbers.
61551408Sobrien	11 for %st(0) (gnu regno = 8)
61651408Sobrien	12 for %st(1) (gnu regno = 9)
61751408Sobrien	13 for %st(2) (gnu regno = 10)
61851408Sobrien	14 for %st(3) (gnu regno = 11)
61951408Sobrien	15 for %st(4) (gnu regno = 12)
62051408Sobrien	16 for %st(5) (gnu regno = 13)
62151408Sobrien	17 for %st(6) (gnu regno = 14)
62251408Sobrien	18 for %st(7) (gnu regno = 15)
62351408Sobrien*/
62458478Sobrien#undef  DWARF_DBX_REGISTER_NUMBER
62534229Speter#define DWARF_DBX_REGISTER_NUMBER(n) \
62634229Speter((n) == 0 ? 0 \
62734229Speter : (n) == 1 ? 2 \
62834229Speter : (n) == 2 ? 1 \
62934229Speter : (n) == 3 ? 3 \
63034229Speter : (n) == 4 ? 6 \
63134229Speter : (n) == 5 ? 7 \
63234229Speter : (n) == 6 ? 5 \
63334229Speter : (n) == 7 ? 4 \
63434229Speter : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
63534229Speter : (-1))
63634229Speter
63734229Speter/* Now what stabs expects in the register.  */
63858478Sobrien#undef  STABS_DBX_REGISTER_NUMBER
63934229Speter#define STABS_DBX_REGISTER_NUMBER(n) \
64034229Speter((n) == 0 ? 0 : \
64134229Speter (n) == 1 ? 2 : \
64234229Speter (n) == 2 ? 1 : \
64334229Speter (n) == 3 ? 3 : \
64434229Speter (n) == 4 ? 6 : \
64534229Speter (n) == 5 ? 7 : \
64634229Speter (n) == 6 ? 4 : \
64734229Speter (n) == 7 ? 5 : \
64834229Speter (n) + 4)
64934229Speter
65034229Speter#undef  DBX_REGISTER_NUMBER
65158478Sobrien#define DBX_REGISTER_NUMBER(n)	((write_symbols == DWARF_DEBUG)		\
65258478Sobrien				? DWARF_DBX_REGISTER_NUMBER(n)		\
65334229Speter				: STABS_DBX_REGISTER_NUMBER(n))
65434229Speter
65558478Sobrien/* tag end of file in elf mode */
65658478Sobrien#undef  DBX_OUTPUT_MAIN_SOURCE_FILE_END
65758478Sobrien#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME)			\
65858478Sobrien  do {									\
65958478Sobrien    if (TARGET_ELF) {							\
66058478Sobrien      fprintf ((FILE), "\t.text\n\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", \
66158478Sobrien		N_SO);							\
66218334Speter    }									\
66358478Sobrien  } while (0)
66418334Speter
66558478Sobrien/* stabs-in-elf has offsets relative to function beginning */
66658478Sobrien#undef  DBX_OUTPUT_LBRAC
66758478Sobrien#define DBX_OUTPUT_LBRAC(FILE, NAME)					\
66858478Sobrien  do {									\
66958478Sobrien    fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC);		\
67058478Sobrien    assemble_name (asmfile, buf);					\
67158478Sobrien    if (TARGET_ELF)							\
67258478Sobrien      {									\
67358478Sobrien        fputc ('-', asmfile);						\
67458478Sobrien        assemble_name (asmfile,						\
67558478Sobrien	      	 XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));	\
67658478Sobrien      }									\
67758478Sobrien    fprintf (asmfile, "\n");						\
67858478Sobrien  } while (0)
67952112Sobrien
68058478Sobrien#undef  DBX_OUTPUT_RBRAC
68158478Sobrien#define DBX_OUTPUT_RBRAC(FILE, NAME)					\
68258478Sobrien  do {									\
68358478Sobrien    fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC);		\
68458478Sobrien    assemble_name (asmfile, buf);					\
68558478Sobrien    if (TARGET_ELF)							\
68658478Sobrien      {									\
68758478Sobrien        fputc ('-', asmfile);						\
68858478Sobrien        assemble_name (asmfile,						\
68958478Sobrien		 XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));	\
69058478Sobrien      }									\
69158478Sobrien    fprintf (asmfile, "\n");						\
69258478Sobrien  } while (0)
693