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