--- gcc/config/i386/osfrose.h 2018/04/24 18:10:27 1.1.1.1 +++ gcc/config/i386/osfrose.h 2018/04/24 18:16:39 1.1.1.2 @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler. Intel 386 (OSF/1 with OSF/rose) version. - Copyright (C) 1991 Free Software Foundation, Inc. + Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. @@ -18,9 +18,6 @@ You should have received a copy of the G along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* Put leading underscores in front of names. */ -#define YES_UNDERSCORES - #include "halfpic.h" #include "i386/gstabs.h" @@ -33,28 +30,58 @@ the Free Software Foundation, 675 Mass A #define WORD_SWITCH_TAKES_ARG(STR) \ (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) || !strcmp (STR, "pic-names")) +/* This defines which switch letters take arguments. On svr4, most of + the normal cases (defined in gcc.c) apply, and we also have -h* and + -z* options (for the linker). */ + +#define SWITCH_TAKES_ARG(CHAR) \ + ( (CHAR) == 'D' \ + || (CHAR) == 'U' \ + || (CHAR) == 'o' \ + || (CHAR) == 'e' \ + || (CHAR) == 'T' \ + || (CHAR) == 'u' \ + || (CHAR) == 'I' \ + || (CHAR) == 'm' \ + || (CHAR) == 'L' \ + || (CHAR) == 'A' \ + || (CHAR) == 'h' \ + || (CHAR) == 'z') + #define MASK_HALF_PIC 0x40000000 /* Mask for half-pic code */ #define MASK_HALF_PIC_DEBUG 0x20000000 /* Debug flag */ #define MASK_ELF 0x10000000 /* ELF not rose */ #define MASK_NO_IDENT 0x08000000 /* suppress .ident */ - -#define TARGET_HALF_PIC (target_flags & MASK_HALF_PIC) -#define TARGET_DEBUG (target_flags & MASK_HALF_PIC_DEBUG) -#define HALF_PIC_DEBUG TARGET_DEBUG -#define TARGET_ELF (target_flags & MASK_ELF) -#define TARGET_ROSE ((target_flags & MASK_ELF) == 0) -#define TARGET_IDENT ((target_flags & MASK_NO_IDENT) == 0) +#define MASK_NO_UNDERSCORES 0x04000000 /* suppress leading _ */ +#define MASK_LARGE_ALIGN 0x02000000 /* align to >word boundaries */ +#define MASK_NO_MCOUNT 0x01000000 /* profiling uses mcount_ptr */ + +#define TARGET_HALF_PIC (target_flags & MASK_HALF_PIC) +#define TARGET_DEBUG (target_flags & MASK_HALF_PIC_DEBUG) +#define HALF_PIC_DEBUG TARGET_DEBUG +#define TARGET_ELF (target_flags & MASK_ELF) +#define TARGET_ROSE ((target_flags & MASK_ELF) == 0) +#define TARGET_IDENT ((target_flags & MASK_NO_IDENT) == 0) +#define TARGET_UNDERSCORES ((target_flags & MASK_NO_UNDERSCORES) == 0) +#define TARGET_LARGE_ALIGN (target_flags & MASK_LARGE_ALIGN) +#define TARGET_MCOUNT ((target_flags & MASK_NO_MCOUNT) == 0) #undef SUBTARGET_SWITCHES #define SUBTARGET_SWITCHES \ { "half-pic", MASK_HALF_PIC}, \ { "no-half-pic", -MASK_HALF_PIC}, \ + { "debug-half-pic", MASK_HALF_PIC_DEBUG}, \ { "debugb", MASK_HALF_PIC_DEBUG}, \ { "elf", MASK_ELF}, \ - { "no-elf", -MASK_ELF}, \ { "rose", -MASK_ELF}, \ { "ident", -MASK_NO_IDENT}, \ - { "no-ident", MASK_NO_IDENT}, + { "no-ident", MASK_NO_IDENT}, \ + { "underscores", -MASK_NO_UNDERSCORES}, \ + { "no-underscores", MASK_NO_UNDERSCORES}, \ + { "large-align", MASK_LARGE_ALIGN}, \ + { "no-large-align",-MASK_LARGE_ALIGN}, \ + { "mcount", -MASK_NO_MCOUNT}, \ + { "no-mcount", MASK_NO_MCOUNT}, /* OSF/rose uses stabs, not dwarf. */ #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG @@ -69,11 +96,14 @@ the Free Software Foundation, 675 Mass A /* Change default predefines. */ #undef CPP_PREDEFINES -#define CPP_PREDEFINES "-DOSF -DOSF1 -Dunix -Di386 -Asystem(unix) -Acpu(i386) -Amachine(i386)" +#define CPP_PREDEFINES "-DOSF -DOSF1 -Dunix -Di386 -Asystem(unix) -Asystem(xpg4) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC #define CPP_SPEC "\ -%{!melf: -D__ROSE__} %{melf: -D__ELF__} \ +%{!melf: -D__ROSE__ %{!pic-none: -D__SHARED__}} \ +%{melf: -D__ELF__ %{fpic: -D__SHARED__}} \ +%{mno-underscores: -D__NO_UNDERSCORES__} \ +%{melf: %{!munderscores: -D__NO_UNDERSCORES__}} \ %{.S: %{!ansi:%{!traditional:%{!traditional-cpp:%{!ftraditional: -traditional}}}}} \ %{.S: -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ %{.cc: -D__LANGUAGE_C_PLUS_PLUS} \ @@ -82,27 +112,32 @@ the Free Software Foundation, 675 Mass A %{.m: -D__LANGUAGE_OBJECTIVE_C} \ %{!.S: -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" -/* Turn on -mpic-extern by default. */ +/* Turn on -pic-extern by default. */ #undef CC1_SPEC #define CC1_SPEC "\ -%{!melf: %{!mrose: %{!mno-elf: -mrose }}} \ +%{!melf: %{!mrose: -mrose }} \ +%{melf: %{!munderscores: %{!mno-underscores: -mno-underscores }}} \ %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ -%{pic-none: -mno-half-pic} \ -%{fpic: -mno-half-pic} \ -%{fPIC: -mno-half-pic} \ -%{pic-lib: -mhalf-pic} \ -%{pic-extern: -mhalf-pic} \ -%{pic-calls: -mhalf-pic} \ -%{pic-names*: -mhalf-pic} \ -%{!pic-*: %{!fpic: %{!fPIC: -mhalf-pic}}}" +%{!melf: %{pic-none: -mno-half-pic} \ + %{pic-extern: } %{pic-lib: } %{pic-calls: } %{pic-names*: } \ + %{!pic-none: -mhalf-pic }}" #undef ASM_SPEC #define ASM_SPEC "%{v*: -v}" #undef LINK_SPEC -#define LINK_SPEC "%{v*: -v} \ - %{!noshrlib: %{pic-none: -noshrlib} %{!pic-none: -warn_nopic}} \ - %{nostdlib} %{noshrlib} %{glue}" +#define LINK_SPEC "%{v*: -v} \ +%{!melf: %{!noshrlib: %{pic-none: -noshrlib} %{!pic-none: -warn_nopic}} \ + %{nostdlib} %{noshrlib} %{glue}} \ +%{melf: %{dy} %{dn} %{glue: } \ + %{h*} %{z*} \ + %{static:-dn -Bstatic} \ + %{shared:-G -dy} \ + %{symbolic:-Bsymbolic -G -dy} \ + %{G:-G} \ + %{!dy: %{!dn: %{!static: %{!shared: %{!symbolic: \ + %{noshrlib: -dn } %{pic-none: -dn } \ + %{!noshrlib: %{!pic-none: -dy}}}}}}}}" #undef LIB_SPEC #define LIB_SPEC "-lc" @@ -141,11 +176,313 @@ the Free Software Foundation, 675 Mass A /* Temporarily turn off long double being 96 bits. */ #undef LONG_DOUBLE_TYPE_SIZE -/* Tell final.c we don't need a label passed to mcount. */ -#define NO_PROFILE_DATA +/* This macro generates the assembly code for function entry. + FILE is a stdio stream to output the code to. + SIZE is an int: how many units of temporary storage to allocate. + Refer to the array `regs_ever_live' to determine which registers + to save; `regs_ever_live[I]' is nonzero if register number I + is ever used in the function. This macro is responsible for + knowing which registers should not be saved even if used. + + We override it here to allow for the new profiling code to go before + the prologue and the old mcount code to go after the prologue (and + after %ebx has been set up for ELF shared library support). */ + +#define OSF_PROFILE_BEFORE_PROLOGUE \ + (!TARGET_MCOUNT \ + && !current_function_needs_context \ + && (!flag_pic \ + || !frame_pointer_needed \ + || (!current_function_uses_pic_offset_table \ + && !current_function_uses_const_pool))) + +#undef FUNCTION_PROLOGUE +#define FUNCTION_PROLOGUE(FILE, SIZE) \ +do \ + { \ + char *prefix = (TARGET_UNDERSCORES) ? "_" : ""; \ + char *lprefix = LPREFIX; \ + int labelno = profile_label_no; \ + \ + if (profile_flag && OSF_PROFILE_BEFORE_PROLOGUE) \ + { \ + if (!flag_pic && !HALF_PIC_P ()) \ + { \ + fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ + fprintf (FILE, "\tcall *%s_mcount_ptr\n", prefix); \ + } \ + \ + else if (HALF_PIC_P ()) \ + { \ + rtx symref; \ + \ + HALF_PIC_EXTERNAL ("_mcount_ptr"); \ + symref = HALF_PIC_PTR (gen_rtx (SYMBOL_REF, Pmode, \ + "_mcount_ptr")); \ + \ + fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ + fprintf (FILE, "\tmovl %s%s,%%eax\n", prefix, \ + XSTR (symref, 0)); \ + fprintf (FILE, "\tcall *(%%eax)\n"); \ + } \ + \ + else \ + { \ + static int call_no = 0; \ + \ + fprintf (FILE, "\tcall %sPc%d\n", lprefix, call_no); \ + fprintf (FILE, "%sPc%d:\tpopl %%eax\n", lprefix, call_no); \ + fprintf (FILE, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-%sPc%d],%%eax\n", \ + lprefix, call_no++); \ + fprintf (FILE, "\tleal $%sP%d@GOTOFF(%%eax),%%edx\n", \ + lprefix, labelno); \ + fprintf (FILE, "\tmovl %s_mcount_ptr@GOT(%%eax),%%eax\n", \ + prefix); \ + fprintf (FILE, "\tcall *(%%eax)\n"); \ + } \ + } \ + \ + function_prologue (FILE, SIZE); \ + } \ +while (0) + +/* A C statement or compound statement to output to FILE some assembler code to + call the profiling subroutine `mcount'. Before calling, the assembler code + must load the address of a counter variable into a register where `mcount' + expects to find the address. The name of this variable is `LP' followed by + the number LABELNO, so you would generate the name using `LP%d' in a + `fprintf'. + + The details of how the address should be passed to `mcount' are determined + by your operating system environment, not by GNU CC. To figure them out, + compile a small program for profiling using the system's installed C + compiler and look at the assembler code that results. */ #undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) fprintf (FILE, "\tcall _mcount\n") +#define FUNCTION_PROFILER(FILE, LABELNO) \ +do \ + { \ + if (!OSF_PROFILE_BEFORE_PROLOGUE) \ + { \ + char *prefix = (TARGET_UNDERSCORES) ? "_" : ""; \ + char *lprefix = LPREFIX; \ + int labelno = LABELNO; \ + \ + /* Note that OSF/rose blew it in terms of calling mcount, \ + since OSF/rose prepends a leading underscore, but mcount's \ + doesn't. At present, we keep this kludge for ELF as well \ + to allow old kernels to build profiling. */ \ + \ + if (flag_pic \ + && !current_function_uses_pic_offset_table \ + && !current_function_uses_const_pool) \ + abort (); \ + \ + if (TARGET_MCOUNT && flag_pic) \ + { \ + fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ + lprefix, labelno); \ + fprintf (FILE, "\tcall *%smcount@GOT(%%ebx)\n", prefix); \ + } \ + \ + else if (TARGET_MCOUNT && HALF_PIC_P ()) \ + { \ + rtx symdef; \ + \ + HALF_PIC_EXTERNAL ("mcount"); \ + symdef = HALF_PIC_PTR (gen_rtx (SYMBOL_REF, Pmode, "mcount")); \ + fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ + fprintf (FILE, "\tcall *%s%s\n", prefix, XSTR (symdef, 0)); \ + } \ + \ + else if (TARGET_MCOUNT) \ + { \ + fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ + fprintf (FILE, "\tcall %smcount\n", prefix); \ + } \ + \ + else if (flag_pic && frame_pointer_needed) \ + { \ + fprintf (FILE, "\tmovl 4(%%ebp),%%ecx\n"); \ + fprintf (FILE, "\tpushl %%ecx\n"); \ + fprintf (FILE, "\tleal $%sP%d@GOTOFF(%%ebx),%%edx\n", \ + lprefix, labelno); \ + fprintf (FILE, "\tmovl _mcount_ptr@GOT(%%eax),%%eax\n"); \ + fprintf (FILE, "\tcall *(%%eax)\n"); \ + fprintf (FILE, "\tpopl %%eax\n"); \ + } \ + \ + else if (frame_pointer_needed) \ + { \ + fprintf (FILE, "\tmovl 4(%%ebp),%%ecx\n"); \ + fprintf (FILE, "\tpushl %%ecx\n"); \ + fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ + fprintf (FILE, "\tcall *_mcount_ptr\n"); \ + fprintf (FILE, "\tpopl %%eax\n"); \ + } \ + \ + else \ + abort (); \ + } \ + } \ +while (0) + +/* A C statement or compound statement to output to FILE some + assembler code to initialize basic-block profiling for the current + object module. This code should call the subroutine + `__bb_init_func' once per object module, passing it as its sole + argument the address of a block allocated in the object module. + + The name of the block is a local symbol made with this statement: + + ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0); + + Of course, since you are writing the definition of + `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you + can take a short cut in the definition of this macro and use the + name that you know will result. + + The first word of this block is a flag which will be nonzero if the + object module has already been initialized. So test this word + first, and do not call `__bb_init_func' if the flag is nonzero. */ + +#undef FUNCTION_BLOCK_PROFILER +#define FUNCTION_BLOCK_PROFILER(STREAM, LABELNO) \ +do \ + { \ + if (!flag_pic) \ + { \ + fprintf (STREAM, "\tcmpl $0,%sPBX0\n", LPREFIX); \ + fprintf (STREAM, "\tjne 0f\n"); \ + fprintf (STREAM, "\tpushl $%sPBX0\n", LPREFIX); \ + fprintf (STREAM, "\tcall %s__bb_init_func\n", \ + (TARGET_UNDERSCORES) ? "_" : ""); \ + fprintf (STREAM, "0:\n"); \ + } \ + else \ + { \ + fprintf (STREAM, "\tpushl %eax\n"); \ + fprintf (STREAM, "\tmovl %sPBX0@GOT(%ebx),%eax\n"); \ + fprintf (STREAM, "\tcmpl $0,(%eax)\n"); \ + fprintf (STREAM, "\tjne 0f\n"); \ + fprintf (STREAM, "\tpushl %eax\n"); \ + fprintf (STREAM, "\tcall %s__bb_init_func@PLT\n", \ + (TARGET_UNDERSCORES) ? "_" : ""); \ + fprintf (STREAM, "0:\n"); \ + fprintf (STREAM, "\tpopl %eax\n"); \ + } \ + } \ +while (0) + +/* A C statement or compound statement to increment the count + associated with the basic block number BLOCKNO. Basic blocks are + numbered separately from zero within each compilation. The count + associated with block number BLOCKNO is at index BLOCKNO in a + vector of words; the name of this array is a local symbol made + with this statement: + + ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2); + + Of course, since you are writing the definition of + `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you + can take a short cut in the definition of this macro and use the + name that you know will result. */ + +#undef BLOCK_PROFILER +#define BLOCK_PROFILER(STREAM, BLOCKNO) \ +do \ + { \ + if (!flag_pic) \ + fprintf (STREAM, "\tincl %sPBX2+%d\n", LPREFIX, (BLOCKNO)*4); \ + else \ + { \ + fprintf (STREAM, "\tpushl %eax\n"); \ + fprintf (STREAM, "\tmovl %sPBX2@GOT(%ebx),%eax\n", LPREFIX); \ + fprintf (STREAM, "\tincl %d(%eax)\n", (BLOCKNO)*4); \ + fprintf (STREAM, "\tpopl %eax\n"); \ + } \ + } \ +while (0) + +/* A C function or functions which are needed in the library to + support block profiling. When support goes into libc, undo + the #if 0. */ + +#if 0 +#undef BLOCK_PROFILING_CODE +#define BLOCK_PROFILING_CODE +#endif + +/* Prefix for internally generated assembler labels. If we aren't using + underscores, we are using prefix `.'s to identify labels that should + be ignored, as in `i386/gas.h' --karl@cs.umb.edu */ +#undef LPREFIX +#define LPREFIX ((TARGET_UNDERSCORES) ? "L" : ".L") + +/* This is how to store into the string BUF + the symbol_ref name of an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. + This is suitable for output with `assemble_name'. */ + +#undef ASM_GENERATE_INTERNAL_LABEL +#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ + sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".", \ + (PREFIX), (NUMBER)) + +/* This is how to output an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. */ + +#undef ASM_OUTPUT_INTERNAL_LABEL +#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ + fprintf (FILE, "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".", \ + PREFIX, NUM) + +/* This is how to output a reference to a user-level label named NAME. */ + +#undef ASM_OUTPUT_LABELREF +#define ASM_OUTPUT_LABELREF(FILE,NAME) \ + fprintf (FILE, "%s%s", (TARGET_UNDERSCORES) ? "_" : "", NAME) + +/* This is how to output an element of a case-vector that is relative. + This is only used for PIC code. See comments by the `casesi' insn in + i386.md for an explanation of the expression this outputs. */ + +#undef ASM_OUTPUT_ADDR_DIFF_ELT +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ + fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) + +/* A C expression to output text to align the location counter in the + way that is desirable at a point in the code that is reached only + by jumping. + + This macro need not be defined if you don't want any special + alignment to be done at such a time. Most machine descriptions do + not currently define the macro. */ + +#undef ASM_OUTPUT_ALIGN_CODE +#define ASM_OUTPUT_ALIGN_CODE(STREAM) \ + fprintf (STREAM, "\t.align\t%d\n", \ + (TARGET_486 && TARGET_LARGE_ALIGN) ? 4 : 2) + +/* A C expression to output text to align the location counter in the + way that is desirable at the beginning of a loop. + + This macro need not be defined if you don't want any special + alignment to be done at such a time. Most machine descriptions do + not currently define the macro. */ + +#undef ASM_OUTPUT_LOOP_ALIGN +#define ASM_OUTPUT_LOOP_ALIGN(STREAM) \ + fprintf (STREAM, "\t.align\t2\n") + +/* A C statement to output to the stdio stream STREAM an assembler + command to advance the location counter to a multiple of 2 to the + POWER bytes. POWER will be a C expression of type `int'. */ + +#undef ASM_OUTPUT_ALIGN +#define ASM_OUTPUT_ALIGN(STREAM, POWER) \ + fprintf (STREAM, "\t.align\t%d\n", \ + (!TARGET_LARGE_ALIGN && (POWER) > 2) ? 2 : (POWER)) /* A C expression that is 1 if the RTX X is a constant which is a valid address. On most machines, this can be defined as @@ -236,7 +573,8 @@ the Free Software Foundation, 675 Mass A defined, is executed once just after all the command options have been parsed. */ -#define OVERRIDE_OPTIONS \ +#undef SUBTARGET_OVERRIDE_OPTIONS +#define SUBTARGET_OVERRIDE_OPTIONS \ { \ /* \ if (TARGET_ELF && TARGET_HALF_PIC) \ @@ -284,11 +622,55 @@ the Free Software Foundation, 675 Mass A #define ENCODE_SECTION_INFO(DECL) \ do \ { \ - if (HALF_PIC_P ()) \ + if (HALF_PIC_P ()) \ HALF_PIC_ENCODE (DECL); \ + \ + else if (flag_pic) \ + { \ + rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ + = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + || ! TREE_PUBLIC (DECL)); \ + } \ + } \ +while (0) + + +/* On most machines, read-only variables, constants, and jump tables + are placed in the text section. If this is not the case on your + machine, this macro should be defined to be the name of a function + (either `data_section' or a function defined in `EXTRA_SECTIONS') + that switches to the section to be used for read-only items. + + If these items should be placed in the text section, this macro + should not be defined. */ + +#if 0 +#undef READONLY_DATA_SECTION +#define READONLY_DATA_SECTION() \ +do \ + { \ + if (TARGET_ELF) \ + { \ + if (in_section != in_rodata) \ + { \ + fprintf (asm_out_file, "\t.section \"rodata\"\n"); \ + in_section = in_rodata; \ + } \ + } \ + else \ + text_section (); \ } \ while (0) +#endif + +/* A list of names for sections other than the standard two, which are + `in_text' and `in_data'. You need not define this macro on a + system with no other sections (that GCC needs to use). */ +#undef EXTRA_SECTIONS +#define EXTRA_SECTIONS in_rodata, in_data1 /* Given a decl node or constant node, choose the section to output it in and select that section. */ @@ -338,6 +720,7 @@ while (0) #define TYPE_ASM_OP ".type" #define SIZE_ASM_OP ".size" #define WEAK_ASM_OP ".weak" +#define SET_ASM_OP ".set" /* The following macro defines the format used to output the second operand of the .type assembler directive. Different svr4 assemblers @@ -358,28 +741,51 @@ while (0) in the usual manner as a label (by means of `ASM_OUTPUT_LABEL'). */ #undef ASM_DECLARE_OBJECT_NAME -#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \ -do \ - { \ - ASM_OUTPUT_LABEL(STREAM,NAME); \ - HALF_PIC_DECLARE (NAME); \ - if (TARGET_ELF) \ - { \ - fprintf (STREAM, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (STREAM, NAME); \ - putc (',', STREAM); \ - fprintf (STREAM, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', STREAM); \ - if (!flag_inhibit_size_directive) \ - { \ - fprintf (STREAM, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (STREAM, NAME); \ - fprintf (STREAM, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \ - } \ - } \ - } \ +#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \ +do \ + { \ + ASM_OUTPUT_LABEL(STREAM,NAME); \ + HALF_PIC_DECLARE (NAME); \ + if (TARGET_ELF) \ + { \ + fprintf (STREAM, "\t%s\t ", TYPE_ASM_OP); \ + assemble_name (STREAM, NAME); \ + putc (',', STREAM); \ + fprintf (STREAM, TYPE_OPERAND_FMT, "object"); \ + putc ('\n', STREAM); \ + size_directive_output = 0; \ + if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ + { \ + size_directive_output = 1; \ + fprintf (STREAM, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (STREAM, NAME); \ + fprintf (STREAM, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + } \ + } \ while (0) +/* Output the size directive for a decl in rest_of_decl_compilation + in the case where we did not do so before the initializer. + Once we find the error_mark_node, we know that the value of + size_directive_output was set + by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ + +#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ +do { \ + char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ + if (TARGET_ELF \ + && !flag_inhibit_size_directive && DECL_SIZE (DECL) \ + && ! AT_END && TOP_LEVEL \ + && DECL_INITIAL (DECL) == error_mark_node \ + && !size_directive_output) \ + { \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, name); \ + fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + } while (0) + /* This is how to declare a function name. */ #undef ASM_DECLARE_FUNCTION_NAME @@ -420,7 +826,7 @@ do \ labelno++; \ ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ - fprintf (FILE, "/\t%s\t ", SIZE_ASM_OP); \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ assemble_name (FILE, (FNAME)); \ fprintf (FILE, ","); \ assemble_name (FILE, label); \ @@ -451,8 +857,21 @@ do \ \ if (TARGET_IDENT) \ { \ - fprintf ((STREAM), "\t%s\t\"GCC: (GNU) %s -O%d", \ - IDENT_ASM_OP, version_string, optimize); \ + char *fstart = main_input_filename; \ + char *fname; \ + \ + if (!fstart) \ + fstart = ""; \ + \ + fname = fstart + strlen (fstart) - 1; \ + while (fname > fstart && *fname != '/') \ + fname--; \ + \ + if (*fname == '/') \ + fname++; \ + \ + fprintf ((STREAM), "\t%s\t\"GCC: (GNU) %s %s -O%d", \ + IDENT_ASM_OP, version_string, fname, optimize); \ \ if (write_symbols == PREFERRED_DEBUGGING_TYPE) \ fprintf ((STREAM), " -g%d", (int)debug_info_level); \ @@ -550,47 +969,57 @@ while (0) Use "word" pseudos to avoid printing NaNs, infinity, etc. */ /* This is how to output an assembler line defining a `double' constant. */ - #undef ASM_OUTPUT_DOUBLE - -#ifndef CROSS_COMPILE #define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \ do \ { \ long value_long[2]; \ + char dstr[30]; \ REAL_VALUE_TO_TARGET_DOUBLE (VALUE, value_long); \ - \ - fprintf (STREAM, "\t.long\t0x%08lx\t\t# %.20g\n\t.long\t0x%08lx\n", \ - value_long[0], VALUE, value_long[1]); \ + REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ + if (sizeof (int) == sizeof (long)) \ + fprintf (STREAM, "\t.long\t0x%08x\t\t# %s\n\t.long\t0x%08x\n", \ + value_long[0], dstr, value_long[1]); \ + else \ + fprintf (STREAM, "\t.long\t0x%08lx\t\t# %s\n\t.long\t0x%08lx\n", \ + value_long[0], dstr, value_long[1]); \ } \ while (0) -#else -#define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \ - fprintf (STREAM, "\t.double\t%.20g\n", VALUE) -#endif - /* This is how to output an assembler line defining a `float' constant. */ - #undef ASM_OUTPUT_FLOAT - -#ifndef CROSS_COMPILE #define ASM_OUTPUT_FLOAT(STREAM, VALUE) \ do \ { \ long value_long; \ + char dstr[30]; \ REAL_VALUE_TO_TARGET_SINGLE (VALUE, value_long); \ - \ - fprintf (STREAM, "\t.long\t0x%08lx\t\t# %.12g (float)\n", \ - value_long, VALUE); \ + REAL_VALUE_TO_DECIMAL (VALUE, "%.12g", dstr); \ + if (sizeof (int) == sizeof (long)) \ + fprintf (STREAM, "\t.long\t0x%08x\t\t# %s (float)\n", \ + value_long, dstr); \ + else \ + fprintf (STREAM, "\t.long\t0x%08lx\t\t# %s (float)\n", \ + value_long, dstr); \ } \ while (0) -#else -#define ASM_OUTPUT_FLOAT(STREAM, VALUE) \ - fprintf (STREAM, "\t.float\t%.12g\n", VALUE) -#endif - +/* This is how to output an assembler line for a `long double' constant. */ +#undef ASM_OUTPUT_LONG_DOUBLE +#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ +do { long l[3]; \ + char dstr[30]; \ + REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ + REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ + if (sizeof (int) == sizeof (long)) \ + fprintf (FILE, \ + "\t.long\t0x%08x\t\t# %s\n\t.long\t0x%08x\n\t.long\t0x%08x\n", \ + l[0], dstr, l[1], l[2]); \ + else \ + fprintf (FILE, \ + "\t.long\t0x%08lx\t\t# %s\n\t.long\t0x%08lx\n\t.long\t0x%08lx\n", \ + l[0], dstr, l[1], l[2]); \ + } while (0) /* Generate calls to memcpy, etc., not bcopy, etc. */ #define TARGET_MEM_FUNCTIONS