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