freebsd.h revision 95348
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 95348 2002-04-24 04:48:00Z 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    %{Wl,*:%*} \
6758478Sobrien    %{assert*} %{R*} %{rpath*} %{defsym*} \
6858478Sobrien    %{shared:-Bshareable %{h*} %{soname*}} \
6958478Sobrien    %{symbolic:-Bsymbolic} \
7058478Sobrien    %{!shared: \
7158478Sobrien      %{!static: \
7258478Sobrien	%{rdynamic: -export-dynamic} \
7358478Sobrien	%{!dynamic-linker: -dynamic-linker /usr/libexec/ld-elf.so.1}} \
7458478Sobrien      %{static:-Bstatic}}}"
7558478Sobrien
7658478Sobrien#undef STARTFILE_SPEC
7758478Sobrien#define STARTFILE_SPEC "\
7858478Sobrien  %{maout: %{shared:c++rt0.o%s} \
7958478Sobrien    %{!shared: \
8058478Sobrien      %{pg:gcrt0.o%s}%{!pg: \
8158478Sobrien	%{static:scrt0.o%s} \
8258478Sobrien	%{!static:crt0.o%s}}}} \
8358478Sobrien  %{!maout: \
8458478Sobrien    %{!shared: \
8558478Sobrien      %{pg:gcrt1.o%s} \
8658478Sobrien      %{!pg: \
8758478Sobrien	%{p:gcrt1.o%s} \
8858478Sobrien	%{!p:crt1.o%s}}} \
8958478Sobrien    crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
9058478Sobrien
9158478Sobrien/* Provide an ENDFILE_SPEC appropriate for FreeBSD/i386.  Here we tack on our
9258478Sobrien   own magical crtend.o file (compare w/crtstuff.c) which provides part of the
9358478Sobrien   support for getting C++ file-scope static object constructed before
9458478Sobrien   entering `main', followed by the normal "finalizer" file, `crtn.o'.  */
9558478Sobrien
9658478Sobrien#undef  ENDFILE_SPEC
9758478Sobrien#define ENDFILE_SPEC "\
9858478Sobrien  %{!maout: \
9958478Sobrien    %{!shared:crtend.o%s} \
10058478Sobrien    %{shared:crtendS.o%s} crtn.o%s}"
10158478Sobrien
10258478Sobrien
10358478Sobrien/************************[  Target stuff  ]***********************************/
10458478Sobrien
10558478Sobrien/* Define the actual types of some ANSI-mandated types.
10658478Sobrien   Needs to agree with <machine/ansi.h>.  GCC defaults come from c-decl.c,
10758478Sobrien   c-common.c, and config/<arch>/<arch>.h.  */
10858478Sobrien
10958478Sobrien#undef SIZE_TYPE
11058478Sobrien#define SIZE_TYPE	"unsigned int"
11158478Sobrien
11258478Sobrien#undef PTRDIFF_TYPE
11358478Sobrien#define PTRDIFF_TYPE	"int"
11458478Sobrien
11558478Sobrien/* This is the pseudo-op used to generate a 32-bit word of data with a
11658478Sobrien   specific value in some section.  */
11758478Sobrien
11858478Sobrien#undef INT_ASM_OP
11958478Sobrien#define INT_ASM_OP	".long"
12058478Sobrien
12158478Sobrien/* Biggest alignment supported by the object file format of this
12258478Sobrien   machine.  Use this macro to limit the alignment which can be
12358478Sobrien   specified using the `__attribute__ ((aligned (N)))' construct.  If
12458478Sobrien   not defined, the default value is `BIGGEST_ALIGNMENT'.  */
12558478Sobrien
12658478Sobrien#define MAX_OFILE_ALIGNMENT (32768*8)
12758478Sobrien
12858478Sobrien#undef  TARGET_VERSION
12958478Sobrien#define TARGET_VERSION	fprintf (stderr, " (i386 FreeBSD/ELF)");
13058478Sobrien
13134229Speter#define MASK_PROFILER_EPILOGUE	010000000000
13234229Speter#define MASK_AOUT		004000000000	/* a.out not elf */
13334229Speter#define MASK_UNDERSCORES	002000000000	/* use leading _ */
13418349Speter
13534229Speter#define TARGET_PROFILER_EPILOGUE	(target_flags & MASK_PROFILER_EPILOGUE)
13634229Speter#define TARGET_AOUT			(target_flags & MASK_AOUT)
13734229Speter#define TARGET_ELF			((target_flags & MASK_AOUT) == 0)
13834229Speter#define TARGET_UNDERSCORES		((target_flags & MASK_UNDERSCORES) != 0)
13918349Speter
14034229Speter#undef	SUBTARGET_SWITCHES
14152112Sobrien#define SUBTARGET_SWITCHES						\
14268601Sobrien  { "profiler-epilogue",	 MASK_PROFILER_EPILOGUE, "Function profiler epilogue"}, \
14368601Sobrien  { "no-profiler-epilogue",	-MASK_PROFILER_EPILOGUE, "No function profiler epilogue"}, \
14468601Sobrien  { "aout",			 MASK_AOUT, "Generate an a.out (vs. ELF) binary"}, \
14568601Sobrien  { "no-aout",			-MASK_AOUT, "Do not generate an a.out binary"}, \
14668601Sobrien  { "underscores",		 MASK_UNDERSCORES, "Add leading underscores to symbols"}, \
14768601Sobrien  { "no-underscores",		-MASK_UNDERSCORES, "Do not add leading underscores to symbols"},
14818349Speter
14958478Sobrien/* This goes away when the math emulator is fixed.  */
15058478Sobrien#undef  TARGET_DEFAULT
15158478Sobrien#define TARGET_DEFAULT \
15258478Sobrien  (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
15358478Sobrien
15434229Speter/* Prefix for internally generated assembler labels.  If we aren't using
15534229Speter   underscores, we are using prefix `.'s to identify labels that should
15634229Speter   be ignored, as in `i386/gas.h' --karl@cs.umb.edu  */
15734229Speter#undef  LPREFIX
15834229Speter#define LPREFIX ((TARGET_UNDERSCORES) ? "L" : ".L")
15918349Speter
16058478Sobrien/* The a.out tools do not support "linkonce" sections. */
16158478Sobrien#undef  SUPPORTS_ONE_ONLY
16258478Sobrien#define SUPPORTS_ONE_ONLY	TARGET_ELF
16318349Speter
16458478Sobrien/* Enable alias attribute support.  */
16558478Sobrien#undef  SET_ASM_OP
16658478Sobrien#define SET_ASM_OP		".set"
16718349Speter
16858478Sobrien/* The a.out tools do not support "Lscope" .stabs symbols. */
16958478Sobrien#undef  NO_DBX_FUNCTION_END
17058478Sobrien#define NO_DBX_FUNCTION_END	TARGET_AOUT
17151408Sobrien
17258478Sobrien/* In ELF, the function stabs come first, before the relative offsets.  */
17358478Sobrien#undef  DBX_FUNCTION_FIRST
17458478Sobrien#define DBX_CHECK_FUNCTION_FIRST TARGET_ELF
17518349Speter
17658478Sobrien/* supply our own hook for calling __main() from main() */
17758478Sobrien#undef  INVOKE__main
17858478Sobrien#define INVOKE__main
17958478Sobrien#undef  GEN_CALL__MAIN
18058478Sobrien#define GEN_CALL__MAIN							\
18158478Sobrien  do {									\
18258478Sobrien    if (!(TARGET_ELF))							\
18358478Sobrien      emit_library_call (gen_rtx (SYMBOL_REF, Pmode, NAME__MAIN), 0,	\
18458478Sobrien			 VOIDmode, 0);					\
18558478Sobrien  } while (0)
18658478Sobrien
18758478Sobrien/* Indicate that jump tables go in the text section.  This is
18858478Sobrien   necessary when compiling PIC code.  */
18958478Sobrien#undef  JUMP_TABLES_IN_TEXT_SECTION
19058478Sobrien#define JUMP_TABLES_IN_TEXT_SECTION	(flag_pic)
19158478Sobrien
19258478Sobrien/* override the exception table positioning */
19358478Sobrien#undef  EXCEPTION_SECTION
19458478Sobrien#define EXCEPTION_SECTION() \
19558478Sobrien  do {									\
19658478Sobrien    if (TARGET_ELF)							\
19758478Sobrien      {									\
19858478Sobrien	named_section (NULL_TREE, ".gcc_except_table", 0);		\
19958478Sobrien      }									\
20058478Sobrien    else								\
20158478Sobrien      {									\
20258478Sobrien	if (flag_pic)							\
20358478Sobrien	  data_section ();						\
20458478Sobrien	else								\
20558478Sobrien	  readonly_data_section ();					\
20658478Sobrien      }									\
20758478Sobrien  } while (0);
20858478Sobrien
20958478Sobrien/* Tell final.c that we don't need a label passed to mcount.  */
21073325Sobrien#undef  NO_PROFILE_COUNTERS
21173325Sobrien#define NO_PROFILE_COUNTERS
21258478Sobrien
21358478Sobrien/* Output assembler code to FILE to begin profiling of the current function.
21458478Sobrien   LABELNO is an optional label.  */
21558478Sobrien
21658478Sobrien#undef  FUNCTION_PROFILER
21758478Sobrien#define FUNCTION_PROFILER(FILE, LABELNO)  \
21858478Sobrien  do {									\
21958478Sobrien    char *_name = TARGET_AOUT ? "mcount" : ".mcount";			\
22058478Sobrien    if (flag_pic)							\
22158478Sobrien      fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", _name);		\
22258478Sobrien    else								\
22358478Sobrien      fprintf ((FILE), "\tcall %s\n", _name);				\
22458478Sobrien  } while (0)
22558478Sobrien
22658478Sobrien/* Output assembler code to FILE to end profiling of the current function.  */
22758478Sobrien
22858478Sobrien#undef  FUNCTION_PROFILER_EPILOGUE
22958478Sobrien#define FUNCTION_PROFILER_EPILOGUE(FILE, DO_RTL)			\
23058478Sobrien  do {									\
23158478Sobrien    if (TARGET_PROFILER_EPILOGUE)					\
23258478Sobrien      {									\
23358478Sobrien	if (DO_RTL)							\
23458478Sobrien	  {								\
23558478Sobrien	  /* ".mexitcount" is specially handled in			\
23658478Sobrien	     ASM_HACK_SYMBOLREF () so that we don't need to handle	\
23758478Sobrien	     flag_pic or TARGET_AOUT here.  */				\
23858478Sobrien	    rtx xop;							\
23958478Sobrien	    xop = gen_rtx_MEM (FUNCTION_MODE,				\
24058478Sobrien			    gen_rtx_SYMBOL_REF (Pmode, ".mexitcount"));	\
24158478Sobrien	    emit_call_insn (gen_rtx (CALL, VOIDmode, xop, const0_rtx));	\
24258478Sobrien	  }								\
24358478Sobrien	else								\
24458478Sobrien	  {								\
24558478Sobrien	  /* XXX this !DO_RTL case is broken but not actually used.  */	\
24658478Sobrien	    char *_name = TARGET_AOUT ? "mcount" : ".mcount";		\
24758478Sobrien	    if (flag_pic)						\
24858478Sobrien	      fprintf (FILE, "\tcall *%s@GOT(%%ebx)\n", _name);		\
24958478Sobrien	    else							\
25058478Sobrien	      fprintf (FILE, "\tcall %s\n", _name);			\
25158478Sobrien	  }								\
25258478Sobrien      }									\
25358478Sobrien  } while (0)
25458478Sobrien
25558478Sobrien
25658478Sobrien/************************[  Assembler stuff  ]********************************/
25758478Sobrien
25895348Sobrien/* Override the default comment-starter of "/" from unix.h.  */
25995348Sobrien#undef  ASM_COMMENT_START
26095348Sobrien#define ASM_COMMENT_START "#"
26195348Sobrien
26258478Sobrien#undef  ASM_APP_ON
26358478Sobrien#define ASM_APP_ON	"#APP\n"
26458478Sobrien
26558478Sobrien#undef  ASM_APP_OFF
26658478Sobrien#define ASM_APP_OFF	"#NO_APP\n"
26758478Sobrien
26858478Sobrien/* This is how to begin an assembly language file.
26958478Sobrien   The .file command should always begin the output.
27058478Sobrien   ELF also needs a .version.  */
27158478Sobrien
27258478Sobrien#undef  ASM_FILE_START
27334229Speter#define ASM_FILE_START(FILE)						\
27434229Speter  do {									\
27558478Sobrien    output_file_directive ((FILE), main_input_filename);		\
27658478Sobrien    if (TARGET_ELF)							\
27758478Sobrien      fprintf ((FILE), "\t.version\t\"01.01\"\n");			\
27834229Speter  } while (0)
27918349Speter
28034229Speter/* This is how to store into the string BUF
28134229Speter   the symbol_ref name of an internal numbered label where
28234229Speter   PREFIX is the class of label and NUM is the number within the class.
28334229Speter   This is suitable for output with `assemble_name'.  */
28434229Speter#undef	ASM_GENERATE_INTERNAL_LABEL
28558478Sobrien#define ASM_GENERATE_INTERNAL_LABEL(BUF, PREFIX, NUMBER)		\
28658478Sobrien  sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".",		\
28758478Sobrien	   (PREFIX), (NUMBER))
28818349Speter
28934229Speter/* This is how to output an internal numbered label where
29058478Sobrien   PREFIX is the class of label and NUM is the number within the class.
29158478Sobrien   For most svr4/ELF systems, the convention is that any symbol which begins
29258478Sobrien   with a period is not put into the linker symbol table by the assembler.  */
29334229Speter#undef	ASM_OUTPUT_INTERNAL_LABEL
29434229Speter#define	ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)			\
29552112Sobrien  fprintf ((FILE), "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".",	\
29652112Sobrien	   (PREFIX), (NUM))
29718334Speter
29858478Sobrien/* This is how to output a reference to a user-level label named NAME.  */
29958478Sobrien#undef  ASM_OUTPUT_LABELREF
30058478Sobrien#define ASM_OUTPUT_LABELREF(FILE, NAME)					\
30158478Sobrien  do {									\
30258478Sobrien    char *_name = (NAME);						\
30358478Sobrien    /* Hack to avoid writing lots of rtl in				\
30458478Sobrien       FUNCTION_PROFILER_EPILOGUE ().  */				\
30558478Sobrien    if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)		\
30658478Sobrien      {									\
30758478Sobrien	if (TARGET_AOUT)						\
30858478Sobrien	  _name++;							\
30958478Sobrien	if (flag_pic)							\
31058478Sobrien	  fprintf ((FILE), "*%s@GOT(%%ebx)", _name);			\
31158478Sobrien	else								\
31258478Sobrien	  fprintf ((FILE), "%s", _name);				\
31358478Sobrien      }									\
31458478Sobrien    else								\
31558478Sobrien      fprintf (FILE, "%s%s", TARGET_UNDERSCORES ? "_" : "", _name);	\
31658478Sobrien} while (0)
31758478Sobrien
31856810Sobrien/* This is how to hack on the symbol code of certain relcalcitrant
31956810Sobrien   symbols to modify their output in output_pic_addr_const ().  */
32056810Sobrien
32158478Sobrien#undef  ASM_HACK_SYMBOLREF_CODE
32256810Sobrien#define ASM_HACK_SYMBOLREF_CODE(NAME, CODE)				\
32358478Sobrien  do {									\
32458478Sobrien    /* Part of hack to avoid writing lots of rtl in			\
32558478Sobrien       FUNCTION_PROFILER_EPILOGUE ().  */				\
32658478Sobrien    char *_name = (NAME);						\
32758478Sobrien    if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0)		\
32858478Sobrien      (CODE) = 'X';							\
32958478Sobrien  } while (0)
33056810Sobrien
33134229Speter/* This is how to output an element of a case-vector that is relative.
33234229Speter   This is only used for PIC code.  See comments by the `casesi' insn in
33334229Speter   i386.md for an explanation of the expression this outputs. */
33458478Sobrien#undef  ASM_OUTPUT_ADDR_DIFF_ELT
33558478Sobrien#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)		\
33652112Sobrien  fprintf ((FILE), "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, (VALUE))
33718349Speter
33858478Sobrien#undef  ASM_OUTPUT_ALIGN
33952112Sobrien#define ASM_OUTPUT_ALIGN(FILE, LOG)      				\
34051408Sobrien  if ((LOG)!=0) {							\
34151408Sobrien    if (in_text_section())						\
34251408Sobrien      fprintf ((FILE), "\t.p2align %d,0x90\n", (LOG));			\
34351408Sobrien    else								\
34451408Sobrien      fprintf ((FILE), "\t.p2align %d\n", (LOG));			\
34551408Sobrien  }
34618349Speter
34773305Sobrien#undef  ASM_OUTPUT_ALIGNED_COMMON
34873305Sobrien#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
34973305Sobrien  do {									\
35073305Sobrien    if (TARGET_ELF)							\
35173305Sobrien      {									\
35273305Sobrien	fprintf ((FILE), "%s", COMMON_ASM_OP);				\
35373305Sobrien	assemble_name ((FILE), (NAME));					\
35473305Sobrien	fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT);	\
35573305Sobrien      }									\
35673305Sobrien    else								\
35773305Sobrien      {									\
35873305Sobrien	int rounded = (SIZE);						\
35973305Sobrien	if (rounded == 0) rounded = 1;					\
36073305Sobrien	rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;		\
36173305Sobrien	rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)	\
36273305Sobrien		   * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));		\
36373305Sobrien	fprintf ((FILE), "%s ", COMMON_ASM_OP);				\
36473305Sobrien	assemble_name ((FILE), (NAME));					\
36573305Sobrien	fprintf ((FILE), ",%u\n", (rounded));				\
36673305Sobrien      }									\
36773305Sobrien  } while (0)
36873305Sobrien
36973305Sobrien/* This says how to output assembler code to declare an
37073305Sobrien   uninitialized internal linkage data object.  Under SVR4,
37173305Sobrien   the linker seems to want the alignment of data objects
37273305Sobrien   to depend on their types.  We do exactly that here.  */
37373305Sobrien
37473305Sobrien#undef  ASM_OUTPUT_ALIGNED_LOCAL
37573305Sobrien#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
37673305Sobrien  do {									\
37773305Sobrien    if (TARGET_ELF)							\
37873305Sobrien      {									\
37973305Sobrien	fprintf ((FILE), "%s", LOCAL_ASM_OP);				\
38073305Sobrien	assemble_name ((FILE), (NAME));					\
38173305Sobrien	fprintf ((FILE), "\n");						\
38273305Sobrien	ASM_OUTPUT_ALIGNED_COMMON ((FILE), (NAME), (SIZE), (ALIGN));	\
38373305Sobrien      }									\
38473305Sobrien    else								\
38573305Sobrien      {									\
38673305Sobrien	int rounded = (SIZE);						\
38773305Sobrien	if (rounded == 0) rounded = 1;					\
38873305Sobrien	rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;		\
38973305Sobrien	rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)	\
39073305Sobrien		   * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));		\
39173305Sobrien	fputs ("\t.lcomm\t", (FILE));					\
39273305Sobrien	assemble_name ((FILE), (NAME));					\
39373305Sobrien	fprintf ((FILE), ",%u\n", (rounded));				\
39473305Sobrien      }									\
39573305Sobrien  } while (0)
39673305Sobrien
39773305Sobrien/* How to output some space.  The rules are different depending on the
39873305Sobrien   object format.  */
39973305Sobrien#undef  ASM_OUTPUT_SKIP
40073305Sobrien#define ASM_OUTPUT_SKIP(FILE, SIZE) 					\
40173305Sobrien  do {									\
40273305Sobrien    if (TARGET_ELF)							\
40373305Sobrien      {									\
40473305Sobrien        fprintf ((FILE), "%s%u\n", SKIP_ASM_OP, (SIZE));		\
40573305Sobrien      }									\
40673305Sobrien    else								\
40773305Sobrien      {									\
40873305Sobrien        fprintf ((FILE), "\t.space\t%u\n", (SIZE));			\
40973305Sobrien      }									\
41073305Sobrien  } while (0)
41173305Sobrien
41273305Sobrien
41358478Sobrien#undef  ASM_OUTPUT_SOURCE_LINE
41458478Sobrien#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE)				\
41558478Sobrien  do {									\
41658478Sobrien    static int sym_lineno = 1;						\
41758478Sobrien    if (TARGET_ELF)							\
41858478Sobrien      {									\
41958478Sobrien	fprintf ((FILE), ".stabn 68,0,%d,.LM%d-", (LINE), sym_lineno);	\
42058478Sobrien	assemble_name ((FILE), 						\
42158478Sobrien		XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));	\
42258478Sobrien	fprintf ((FILE), "\n.LM%d:\n", sym_lineno);			\
42358478Sobrien	sym_lineno += 1;						\
42458478Sobrien      }									\
42558478Sobrien    else								\
42658478Sobrien      {									\
42758478Sobrien	fprintf ((FILE), "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE,	\
42858478Sobrien		lineno);						\
42958478Sobrien      }									\
43058478Sobrien  } while (0)
43118334Speter
43258478Sobrien/* These macros generate the special .type and .size directives which
43358478Sobrien   are used to set the corresponding fields of the linker symbol table
43458478Sobrien   entries in an ELF object file under SVR4.  These macros also output
43558478Sobrien   the starting labels for the relevant functions/objects.  */
43651408Sobrien
43758478Sobrien/* Write the extra assembler code needed to declare a function properly.
43858478Sobrien   Some svr4 assemblers need to also have something extra said about the
43958478Sobrien   function's return value.  We allow for that here.  */
44051408Sobrien
44158478Sobrien#undef  ASM_DECLARE_FUNCTION_NAME
44258478Sobrien#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
44334229Speter  do {									\
44458478Sobrien    fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);				\
44558478Sobrien    assemble_name (FILE, NAME);						\
44658478Sobrien    putc (',', FILE);							\
44758478Sobrien    fprintf (FILE, TYPE_OPERAND_FMT, "function");			\
44858478Sobrien    putc ('\n', FILE);							\
44958478Sobrien    ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));			\
45058478Sobrien    ASM_OUTPUT_LABEL(FILE, NAME);					\
45134229Speter  } while (0)
45218334Speter
45358478Sobrien/* This is how to declare the size of a function.  */
45418349Speter
45558478Sobrien#undef  ASM_DECLARE_FUNCTION_SIZE
45658478Sobrien#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)			\
45758478Sobrien  do {									\
45858478Sobrien    if (!flag_inhibit_size_directive)					\
45958478Sobrien      {									\
46058478Sobrien        char label[256];						\
46158478Sobrien	static int labelno;						\
46258478Sobrien	labelno++;							\
46358478Sobrien	ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);		\
46458478Sobrien	ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno);		\
46558478Sobrien	fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);				\
46658478Sobrien	assemble_name (FILE, (FNAME));					\
46758478Sobrien        fprintf (FILE, ",");						\
46858478Sobrien	assemble_name (FILE, label);					\
46958478Sobrien        fprintf (FILE, "-");						\
47058478Sobrien	assemble_name (FILE, (FNAME));					\
47158478Sobrien	putc ('\n', FILE);						\
47258478Sobrien      }									\
47358478Sobrien  } while (0)
47418334Speter
47518334Speter
47658478Sobrien/* The routine used to output NUL terminated strings.  We use a special
47758478Sobrien   version of this for most svr4 targets because doing so makes the
47858478Sobrien   generated assembly code more compact (and thus faster to assemble)
47958478Sobrien   as well as more readable, especially for targets like the i386
48058478Sobrien   (where the only alternative is to output character sequences as
48158478Sobrien   comma separated lists of numbers).   */
48218334Speter
48358478Sobrien#undef  ASM_OUTPUT_LIMITED_STRING
48458478Sobrien#define ASM_OUTPUT_LIMITED_STRING(FILE, STR)				\
48558478Sobrien  do {									\
48658478Sobrien      register unsigned char *_limited_str = (unsigned char *) (STR);	\
48758478Sobrien      register unsigned ch;						\
48858478Sobrien      fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP);			\
48958478Sobrien      for (; (ch = *_limited_str); _limited_str++)			\
49058478Sobrien        {								\
49158478Sobrien	  register int escape;						\
49258478Sobrien	  switch (escape = ESCAPES[ch])					\
49358478Sobrien	    {								\
49458478Sobrien	    case 0:							\
49558478Sobrien	      putc (ch, (FILE));					\
49658478Sobrien	      break;							\
49758478Sobrien	    case 1:							\
49858478Sobrien	      fprintf ((FILE), "\\%03o", ch);				\
49958478Sobrien	      break;							\
50058478Sobrien	    default:							\
50158478Sobrien	      putc ('\\', (FILE));					\
50258478Sobrien	      putc (escape, (FILE));					\
50358478Sobrien	      break;							\
50458478Sobrien	    }								\
50558478Sobrien        }								\
50658478Sobrien      fprintf ((FILE), "\"\n");						\
50758478Sobrien  } while (0)
50834269Speter
50958478Sobrien/* Switch into a generic section.
51058478Sobrien
51158478Sobrien   We make the section read-only and executable for a function decl,
51258478Sobrien   read-only for a const data decl, and writable for a non-const data decl.
51358478Sobrien
51458478Sobrien   If the section has already been defined, we must not
51558478Sobrien   emit the attributes here. The SVR4 assembler does not
51658478Sobrien   recognize section redefinitions.
51758478Sobrien   If DECL is NULL, no attributes are emitted.  */
51834284Speter
51958478Sobrien#undef  ASM_OUTPUT_SECTION_NAME
52058478Sobrien#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)		\
52158478Sobrien  do {									\
52258478Sobrien    static struct section_info						\
52358478Sobrien      {									\
52458478Sobrien	struct section_info *next;				        \
52558478Sobrien	char *name;						        \
52658478Sobrien	enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type;		\
52758478Sobrien      } *sections;							\
52858478Sobrien    struct section_info *s;						\
52958478Sobrien    char *mode;								\
53058478Sobrien    enum sect_enum type;						\
53158478Sobrien									\
53258478Sobrien    for (s = sections; s; s = s->next)					\
53358478Sobrien      if (!strcmp (NAME, s->name))					\
53458478Sobrien	break;								\
53558478Sobrien									\
53658478Sobrien    if (DECL && TREE_CODE (DECL) == FUNCTION_DECL)			\
53758478Sobrien      type = SECT_EXEC, mode = "ax";					\
53858478Sobrien    else if (DECL && DECL_READONLY_SECTION (DECL, RELOC))		\
53958478Sobrien      type = SECT_RO, mode = "a";					\
54058478Sobrien    else								\
54158478Sobrien      type = SECT_RW, mode = "aw";					\
54258478Sobrien									\
54358478Sobrien    if (s == 0)								\
54458478Sobrien      {									\
54558478Sobrien	s = (struct section_info *) xmalloc (sizeof (struct section_info));  \
54658478Sobrien	s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME));	\
54758478Sobrien	strcpy (s->name, NAME);						\
54858478Sobrien	s->type = type;							\
54958478Sobrien	s->next = sections;						\
55058478Sobrien	sections = s;							\
55158478Sobrien	fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, mode);	\
55258478Sobrien      }									\
55358478Sobrien    else								\
55458478Sobrien      {									\
55558478Sobrien	if (DECL && s->type != type)					\
55658478Sobrien	  error_with_decl (DECL, "%s causes a section type conflict");	\
55758478Sobrien									\
55858478Sobrien	fprintf (FILE, ".section\t%s\n", NAME);				\
55958478Sobrien      }									\
56058478Sobrien  } while (0)
56118334Speter
56258478Sobrien#undef  MAKE_DECL_ONE_ONLY
56358478Sobrien#define MAKE_DECL_ONE_ONLY(DECL)	(DECL_WEAK (DECL) = 1)
56458478Sobrien#undef  UNIQUE_SECTION_P
56558478Sobrien#define UNIQUE_SECTION_P(DECL)		(DECL_ONE_ONLY (DECL))
56658478Sobrien#undef  UNIQUE_SECTION
56758478Sobrien#define UNIQUE_SECTION(DECL,RELOC)					\
56858478Sobrien  do {									\
56958478Sobrien    int len;								\
57058478Sobrien    char *name, *string, *prefix;					\
57158478Sobrien									\
57258478Sobrien    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL));		\
57358478Sobrien									\
57458478Sobrien    if (! DECL_ONE_ONLY (DECL))						\
57558478Sobrien      {									\
57658478Sobrien	prefix = ".";                                             	\
57758478Sobrien	if (TREE_CODE (DECL) == FUNCTION_DECL)				\
57858478Sobrien	  prefix = ".text.";						\
57958478Sobrien	else if (DECL_READONLY_SECTION (DECL, RELOC))			\
58058478Sobrien	  prefix = ".rodata.";						\
58158478Sobrien	else								\
58258478Sobrien	  prefix = ".data.";						\
58358478Sobrien      }									\
58458478Sobrien    else if (TREE_CODE (DECL) == FUNCTION_DECL)				\
58558478Sobrien      prefix = ".gnu.linkonce.t.";					\
58658478Sobrien    else if (DECL_READONLY_SECTION (DECL, RELOC))			\
58758478Sobrien      prefix = ".gnu.linkonce.r.";					\
58858478Sobrien    else								\
58958478Sobrien      prefix = ".gnu.linkonce.d.";					\
59058478Sobrien									\
59158478Sobrien    len = strlen (name) + strlen (prefix);				\
59258478Sobrien    string = alloca (len + 1);						\
59358478Sobrien    sprintf (string, "%s%s", prefix, name);				\
59458478Sobrien									\
59558478Sobrien    DECL_SECTION_NAME (DECL) = build_string (len, string);		\
59658478Sobrien  } while (0)
59734229Speter
59858478Sobrien/* A C statement or statements to switch to the appropriate
59958478Sobrien   section for output of DECL.  DECL is either a `VAR_DECL' node
60058478Sobrien   or a constant of some sort.  RELOC indicates whether forming
60158478Sobrien   the initial value of DECL requires link-time relocations.  */
60234229Speter
60358478Sobrien#undef  SELECT_SECTION
60458478Sobrien#define SELECT_SECTION(DECL,RELOC)					\
60558478Sobrien  {									\
60658478Sobrien    if (flag_pic && RELOC)						\
60758478Sobrien      data_section ();							\
60858478Sobrien    else if (TREE_CODE (DECL) == STRING_CST)				\
60958478Sobrien      {									\
61058478Sobrien	if (! flag_writable_strings)					\
61158478Sobrien	  const_section ();						\
61258478Sobrien	else								\
61358478Sobrien	  data_section ();						\
61458478Sobrien      }									\
61558478Sobrien    else if (TREE_CODE (DECL) == VAR_DECL)				\
61658478Sobrien      {									\
61758478Sobrien	if (! DECL_READONLY_SECTION (DECL, RELOC))			\
61858478Sobrien	  data_section ();						\
61958478Sobrien	else								\
62058478Sobrien	  const_section ();						\
62158478Sobrien      }									\
62258478Sobrien    else								\
62358478Sobrien      const_section ();							\
62458478Sobrien  }
62558478Sobrien
62673305Sobrien/* A C statement (sans semicolon) to output an element in the table of
62773305Sobrien   global constructors.  */
62873305Sobrien#undef  ASM_OUTPUT_CONSTRUCTOR
62973305Sobrien#define ASM_OUTPUT_CONSTRUCTOR(FILE, NAME)				\
63073305Sobrien  do {									\
63173305Sobrien    if (TARGET_ELF)							\
63273305Sobrien      {									\
63373305Sobrien	ctors_section ();						\
63473305Sobrien	fprintf ((FILE), "%s ", INT_ASM_OP);				\
63573305Sobrien	assemble_name ((FILE), (NAME));					\
63673305Sobrien	fprintf ((FILE), "\n");						\
63773305Sobrien      }									\
63873305Sobrien    else								\
63973305Sobrien      {									\
64073305Sobrien	fprintf (asm_out_file, "%s \"%s__CTOR_LIST__\",22,0,0,",	\
64173305Sobrien		 ASM_STABS_OP, (TARGET_UNDERSCORES) ? "_" : "");	\
64273305Sobrien	assemble_name (asm_out_file, name);				\
64373305Sobrien	fputc ('\n', asm_out_file);					\
64473305Sobrien      }									\
64573305Sobrien  } while (0)
64673305Sobrien
64773305Sobrien/* A C statement (sans semicolon) to output an element in the table of
64873305Sobrien   global destructors.  */
64973305Sobrien#undef  ASM_OUTPUT_DESTRUCTOR
65073305Sobrien#define ASM_OUTPUT_DESTRUCTOR(FILE, NAME)				\
65173305Sobrien  do {									\
65273305Sobrien    if (TARGET_ELF)							\
65373305Sobrien      {									\
65473305Sobrien	dtors_section ();						\
65573305Sobrien	fprintf ((FILE), "%s ", INT_ASM_OP);				\
65673305Sobrien	assemble_name ((FILE), (NAME));					\
65773305Sobrien	fprintf ((FILE), "\n");						\
65873305Sobrien      }									\
65973305Sobrien    else								\
66073305Sobrien      {									\
66173305Sobrien	fprintf (asm_out_file, "%s \"%s__DTOR_LIST__\",22,0,0,",	\
66273305Sobrien		 ASM_STABS_OP, (TARGET_UNDERSCORES) ? "_" : "");	\
66373305Sobrien	assemble_name (asm_out_file, name);				\
66473305Sobrien	fputc ('\n', asm_out_file);					\
66573305Sobrien      }									\
66673305Sobrien  } while (0)
66773305Sobrien
66834229Speter/* Define macro used to output shift-double opcodes when the shift
66934229Speter   count is in %cl.  Some assemblers require %cl as an argument;
67034229Speter   some don't.
67134229Speter
67234229Speter   *OLD* GAS requires the %cl argument, so override i386/unix.h. */
67334229Speter
67458478Sobrien#undef  AS3_SHIFT_DOUBLE
67558478Sobrien#define AS3_SHIFT_DOUBLE(a,b,c,d)	AS3 (a,b,c,d)
67634229Speter
67718334Speter
67858478Sobrien/************************[  Debugger stuff  ]*********************************/
67918334Speter
68051408Sobrien/* Copy this from the svr4 specifications... */
68151408Sobrien/* Define the register numbers to be used in Dwarf debugging information.
68251408Sobrien   The SVR4 reference port C compiler uses the following register numbers
68351408Sobrien   in its Dwarf output code:
68451408Sobrien	0 for %eax (gnu regno = 0)
68551408Sobrien	1 for %ecx (gnu regno = 2)
68651408Sobrien	2 for %edx (gnu regno = 1)
68751408Sobrien	3 for %ebx (gnu regno = 3)
68851408Sobrien	4 for %esp (gnu regno = 7)
68951408Sobrien	5 for %ebp (gnu regno = 6)
69051408Sobrien	6 for %esi (gnu regno = 4)
69151408Sobrien	7 for %edi (gnu regno = 5)
69251408Sobrien   The following three DWARF register numbers are never generated by
69351408Sobrien   the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
69451408Sobrien   believes these numbers have these meanings.
69551408Sobrien	8  for %eip    (no gnu equivalent)
69651408Sobrien	9  for %eflags (no gnu equivalent)
69751408Sobrien	10 for %trapno (no gnu equivalent)
69851408Sobrien   It is not at all clear how we should number the FP stack registers
69951408Sobrien   for the x86 architecture.  If the version of SDB on x86/svr4 were
70051408Sobrien   a bit less brain dead with respect to floating-point then we would
70151408Sobrien   have a precedent to follow with respect to DWARF register numbers
70251408Sobrien   for x86 FP registers, but the SDB on x86/svr4 is so completely
70351408Sobrien   broken with respect to FP registers that it is hardly worth thinking
70451408Sobrien   of it as something to strive for compatibility with.
70551408Sobrien   The version of x86/svr4 SDB I have at the moment does (partially)
70651408Sobrien   seem to believe that DWARF register number 11 is associated with
70751408Sobrien   the x86 register %st(0), but that's about all.  Higher DWARF
70851408Sobrien   register numbers don't seem to be associated with anything in
70951408Sobrien   particular, and even for DWARF regno 11, SDB only seems to under-
71051408Sobrien   stand that it should say that a variable lives in %st(0) (when
71151408Sobrien   asked via an `=' command) if we said it was in DWARF regno 11,
71251408Sobrien   but SDB still prints garbage when asked for the value of the
71351408Sobrien   variable in question (via a `/' command).
71451408Sobrien   (Also note that the labels SDB prints for various FP stack regs
71551408Sobrien   when doing an `x' command are all wrong.)
71651408Sobrien   Note that these problems generally don't affect the native SVR4
71751408Sobrien   C compiler because it doesn't allow the use of -O with -g and
71851408Sobrien   because when it is *not* optimizing, it allocates a memory
71951408Sobrien   location for each floating-point variable, and the memory
72051408Sobrien   location is what gets described in the DWARF AT_location
72151408Sobrien   attribute for the variable in question.
72251408Sobrien   Regardless of the severe mental illness of the x86/svr4 SDB, we
72351408Sobrien   do something sensible here and we use the following DWARF
72451408Sobrien   register numbers.  Note that these are all stack-top-relative
72551408Sobrien   numbers.
72651408Sobrien	11 for %st(0) (gnu regno = 8)
72751408Sobrien	12 for %st(1) (gnu regno = 9)
72851408Sobrien	13 for %st(2) (gnu regno = 10)
72951408Sobrien	14 for %st(3) (gnu regno = 11)
73051408Sobrien	15 for %st(4) (gnu regno = 12)
73151408Sobrien	16 for %st(5) (gnu regno = 13)
73251408Sobrien	17 for %st(6) (gnu regno = 14)
73351408Sobrien	18 for %st(7) (gnu regno = 15)
73451408Sobrien*/
73558478Sobrien#undef  DWARF_DBX_REGISTER_NUMBER
73634229Speter#define DWARF_DBX_REGISTER_NUMBER(n) \
73734229Speter((n) == 0 ? 0 \
73834229Speter : (n) == 1 ? 2 \
73934229Speter : (n) == 2 ? 1 \
74034229Speter : (n) == 3 ? 3 \
74134229Speter : (n) == 4 ? 6 \
74234229Speter : (n) == 5 ? 7 \
74334229Speter : (n) == 6 ? 5 \
74434229Speter : (n) == 7 ? 4 \
74534229Speter : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
74634229Speter : (-1))
74734229Speter
74834229Speter/* Now what stabs expects in the register.  */
74958478Sobrien#undef  STABS_DBX_REGISTER_NUMBER
75034229Speter#define STABS_DBX_REGISTER_NUMBER(n) \
75134229Speter((n) == 0 ? 0 : \
75234229Speter (n) == 1 ? 2 : \
75334229Speter (n) == 2 ? 1 : \
75434229Speter (n) == 3 ? 3 : \
75534229Speter (n) == 4 ? 6 : \
75634229Speter (n) == 5 ? 7 : \
75734229Speter (n) == 6 ? 4 : \
75834229Speter (n) == 7 ? 5 : \
75934229Speter (n) + 4)
76034229Speter
76134229Speter#undef  DBX_REGISTER_NUMBER
76293263Sobrien#define DBX_REGISTER_NUMBER(n)	((write_symbols == DWARF2_DEBUG		\
76393263Sobrien	    			  || write_symbols == DWARF_DEBUG)	\
76458478Sobrien				? DWARF_DBX_REGISTER_NUMBER(n)		\
76534229Speter				: STABS_DBX_REGISTER_NUMBER(n))
76634229Speter
76758478Sobrien/* tag end of file in elf mode */
76858478Sobrien#undef  DBX_OUTPUT_MAIN_SOURCE_FILE_END
76958478Sobrien#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME)			\
77058478Sobrien  do {									\
77158478Sobrien    if (TARGET_ELF) {							\
77258478Sobrien      fprintf ((FILE), "\t.text\n\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", \
77358478Sobrien		N_SO);							\
77418334Speter    }									\
77558478Sobrien  } while (0)
77618334Speter
77758478Sobrien/* stabs-in-elf has offsets relative to function beginning */
77858478Sobrien#undef  DBX_OUTPUT_LBRAC
77958478Sobrien#define DBX_OUTPUT_LBRAC(FILE, NAME)					\
78058478Sobrien  do {									\
78158478Sobrien    fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC);		\
78258478Sobrien    assemble_name (asmfile, buf);					\
78358478Sobrien    if (TARGET_ELF)							\
78458478Sobrien      {									\
78558478Sobrien        fputc ('-', asmfile);						\
78658478Sobrien        assemble_name (asmfile,						\
78758478Sobrien	      	 XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));	\
78858478Sobrien      }									\
78958478Sobrien    fprintf (asmfile, "\n");						\
79058478Sobrien  } while (0)
79152112Sobrien
79258478Sobrien#undef  DBX_OUTPUT_RBRAC
79358478Sobrien#define DBX_OUTPUT_RBRAC(FILE, NAME)					\
79458478Sobrien  do {									\
79558478Sobrien    fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC);		\
79658478Sobrien    assemble_name (asmfile, buf);					\
79758478Sobrien    if (TARGET_ELF)							\
79858478Sobrien      {									\
79958478Sobrien        fputc ('-', asmfile);						\
80058478Sobrien        assemble_name (asmfile,						\
80158478Sobrien		 XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));	\
80258478Sobrien      }									\
80358478Sobrien    fprintf (asmfile, "\n");						\
80458478Sobrien  } while (0)
805