From 7509c7593690d86c4c754551d541f50c5aa3550a Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Wed, 24 Jan 1996 20:56:01 +0000 Subject: Small data support; Windows NT attributes; windows NT call indrect fix From-SVN: r11093 --- gcc/config/rs6000/aix41.h | 8 +- gcc/config/rs6000/eabi.h | 4 + gcc/config/rs6000/eabiaix.h | 2 +- gcc/config/rs6000/eabile.h | 2 +- gcc/config/rs6000/eabisim.h | 4 + gcc/config/rs6000/rs6000.c | 289 ++++++++++++++++++++++++++++++++++++++------ gcc/config/rs6000/rs6000.h | 113 ++++++++++++++--- gcc/config/rs6000/rs6000.md | 88 ++++++++------ gcc/config/rs6000/sysv4.h | 172 ++++++++++++++++++++------ gcc/config/rs6000/sysv4le.h | 2 +- gcc/config/rs6000/t-ppcgas | 6 +- gcc/config/rs6000/win-nt.h | 17 ++- 12 files changed, 563 insertions(+), 144 deletions(-) (limited to 'gcc') diff --git a/gcc/config/rs6000/aix41.h b/gcc/config/rs6000/aix41.h index 3807d0b..98aaaf1 100644 --- a/gcc/config/rs6000/aix41.h +++ b/gcc/config/rs6000/aix41.h @@ -77,13 +77,7 @@ Boston, MA 02111-1307, USA. */ } #undef LINK_SPEC -#ifndef CROSS_COMPILE #define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso -bI:/lib/syscalls.exp} %{!shared: %{g*:-bexport:/usr/lib/libg.exp}}\ + %{static:-bnso %(link_syscalls) } %{!shared: %{g*: %(link_libg) }}\ %{shared:-bM:SRE}" -#else -#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso} \ - %{shared:-bM:SRE}" -#endif diff --git a/gcc/config/rs6000/eabi.h b/gcc/config/rs6000/eabi.h index ea32add..25bc1ef 100644 --- a/gcc/config/rs6000/eabi.h +++ b/gcc/config/rs6000/eabi.h @@ -68,6 +68,10 @@ Boston, MA 02111-1307, USA. */ #define CPP_PREDEFINES \ "-DPPC -D__embedded__ -Asystem(embedded) -Acpu(powerpc) -Amachine(powerpc)" +/* Clue the simulator in to use netbsd */ +#undef LINK_START_SPEC +#define LINK_START_SPEC "%{msim: %{!Ttext*: -Ttext 0x10000000}}" + /* Use the simulator crt0 or mvme and libgloss/newlib libraries if desired */ #undef STARTFILE_SPEC #define STARTFILE_SPEC "crti.o%s \ diff --git a/gcc/config/rs6000/eabiaix.h b/gcc/config/rs6000/eabiaix.h index 82b059c..4ac1545 100644 --- a/gcc/config/rs6000/eabiaix.h +++ b/gcc/config/rs6000/eabiaix.h @@ -37,4 +37,4 @@ Boston, MA 02111-1307, USA. */ `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ #undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-aix" } +#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-aix", "mno-sdata" } diff --git a/gcc/config/rs6000/eabile.h b/gcc/config/rs6000/eabile.h index aaa3ecd..cf1a6af 100644 --- a/gcc/config/rs6000/eabile.h +++ b/gcc/config/rs6000/eabile.h @@ -41,4 +41,4 @@ Boston, MA 02111-1307, USA. */ `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ #undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv" } +#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv", "mno-sdata" } diff --git a/gcc/config/rs6000/eabisim.h b/gcc/config/rs6000/eabisim.h index fcd094e..30371eb 100644 --- a/gcc/config/rs6000/eabisim.h +++ b/gcc/config/rs6000/eabisim.h @@ -29,6 +29,10 @@ Boston, MA 02111-1307, USA. */ #define CPP_PREDEFINES \ "-DPPC -D__embedded__ -D__simulator__ -Asystem(embedded) -Asystem(simulator) -Acpu(powerpc) -Amachine(powerpc)" +/* Clue the simulator in to use netbsd */ +#undef LINK_START_SPEC +#define LINK_START_SPEC "%{!mmvme: %{!Ttext*: -Ttext 0x10000000}}" + /* Use the simulator crt0 or mvme and libgloss/newlib libraries if desired */ #undef STARTFILE_SPEC #define STARTFILE_SPEC "crti.o%s \ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a942923..47e1f35 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -37,6 +37,10 @@ Boston, MA 02111-1307, USA. */ #include "obstack.h" #include "tree.h" +#ifndef TARGET_NO_PROTOTYPE +#define TARGET_NO_PROTOTYPE 0 +#endif + extern char *language_string; extern int profile_block_flag; @@ -836,6 +840,29 @@ input_operand (op, mode) for an add will be valid. */ return add_operand (op, mode); } + +/* Return 1 for an operand in small memory on V.4/eabi */ + +int +small_data_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + rtx sym_ref, const_part; + + if (DEFAULT_ABI != ABI_V4) + return 0; + + if (GET_CODE (op) != SYMBOL_REF && GET_CODE (op) != CONST) + return 0; + + sym_ref = eliminate_constant_term (op, &const_part); + if (!sym_ref || GET_CODE (sym_ref) != SYMBOL_REF || *XSTR (sym_ref, 0) != '@') + return 0; + + return 1; +} + /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. @@ -852,19 +879,19 @@ init_cumulative_args (cum, fntype, libname, incoming) int incoming; { static CUMULATIVE_ARGS zero_cumulative; + enum rs6000_abi abi = DEFAULT_ABI; *cum = zero_cumulative; cum->words = 0; cum->fregno = FP_ARG_MIN_REG; cum->prototype = (fntype && TYPE_ARG_TYPES (fntype)); + cum->call_cookie = CALL_NORMAL; if (incoming) { cum->nargs_prototype = 1000; /* don't return an EXPR_LIST */ -#ifdef TARGET_V4_CALLS - if (TARGET_V4_CALLS) + if (abi == ABI_V4) cum->varargs_offset = RS6000_VARARGS_OFFSET; -#endif } else if (cum->prototype) @@ -876,6 +903,13 @@ init_cumulative_args (cum, fntype, libname, incoming) cum->nargs_prototype = 0; cum->orig_nargs = cum->nargs_prototype; + + /* Check for DLL import functions */ + if (abi == ABI_NT + && fntype + && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (fntype))) + cum->call_cookie = CALL_NT_DLLIMPORT; + if (TARGET_DEBUG_ARG) { fprintf (stderr, "\ninit_cumulative_args:"); @@ -886,10 +920,11 @@ init_cumulative_args (cum, fntype, libname, incoming) tree_code_name[ (int)TREE_CODE (ret_type) ]); } -#ifdef TARGET_V4_CALLS - if (TARGET_V4_CALLS && incoming) + if (abi == ABI_V4 && incoming) fprintf (stderr, " varargs = %d, ", cum->varargs_offset); -#endif + + if (cum->call_cookie == CALL_NT_DLLIMPORT) + fprintf (stderr, " dllimport,"); fprintf (stderr, " proto = %d, nargs = %d\n", cum->prototype, cum->nargs_prototype); @@ -936,8 +971,7 @@ function_arg_advance (cum, mode, type, named) cum->words += align; cum->nargs_prototype--; -#ifdef TARGET_V4_CALLS - if (TARGET_V4_CALLS) + if (DEFAULT_ABI == ABI_V4) { /* Long longs must not be split between registers and stack */ if ((GET_MODE_CLASS (mode) != MODE_FLOAT || TARGET_SOFT_FLOAT) @@ -963,7 +997,6 @@ function_arg_advance (cum, mode, type, named) cum->words += RS6000_ARG_SIZE (mode, type, 1); } else -#endif if (named) { cum->words += RS6000_ARG_SIZE (mode, type, named); @@ -1020,20 +1053,27 @@ function_arg (cum, mode, type, named) marker for software floating point, or compiler generated library calls. */ if (mode == VOIDmode) { -#ifdef TARGET_V4_CALLS - if (TARGET_V4_CALLS && TARGET_HARD_FLOAT && cum->nargs_prototype < 0 + enum rs6000_abi abi = DEFAULT_ABI; + + if (abi == ABI_V4 + && TARGET_HARD_FLOAT + && cum->nargs_prototype < 0 && type && (cum->prototype || TARGET_NO_PROTOTYPE)) - return GEN_INT ((cum->fregno == FP_ARG_MIN_REG) ? -1 : 1); -#endif + { + if (cum->call_cookie != CALL_NORMAL) + abort (); + + return GEN_INT ((cum->fregno == FP_ARG_MIN_REG) + ? CALL_V4_SET_FP_ARGS + : CALL_V4_CLEAR_FP_ARGS); + } - return GEN_INT (0); + return GEN_INT (cum->call_cookie); } if (!named) { -#ifdef TARGET_V4_CALLS - if (!TARGET_V4_CALLS) -#endif + if (DEFAULT_ABI != ABI_V4) return NULL_RTX; } @@ -1043,9 +1083,7 @@ function_arg (cum, mode, type, named) if (USE_FP_FOR_ARG_P (*cum, mode, type)) { if ((cum->nargs_prototype > 0) -#ifdef TARGET_V4_CALLS - || TARGET_V4_CALLS /* V.4 never passes FP values in GP registers */ -#endif + || (DEFAULT_ABI == ABI_V4) /* V.4 never passes FP values in GP registers */ || !type) return gen_rtx (REG, mode, cum->fregno); @@ -1056,14 +1094,12 @@ function_arg (cum, mode, type, named) gen_rtx (REG, mode, cum->fregno)); } -#ifdef TARGET_V4_CALLS /* Long longs won't be split between register and stack */ - else if (TARGET_V4_CALLS && + else if (DEFAULT_ABI == ABI_V4 && align_words + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG) { return NULL_RTX; } -#endif else if (align_words < GP_ARG_NUM_REG) return gen_rtx (REG, mode, GP_ARG_MIN_REG + align_words); @@ -1085,10 +1121,8 @@ function_arg_partial_nregs (cum, mode, type, named) if (! named) return 0; -#ifdef TARGET_V4_CALLS - if (TARGET_V4_CALLS) + if (DEFAULT_ABI == ABI_V4) return 0; -#endif if (USE_FP_FOR_ARG_P (*cum, mode, type)) { @@ -1124,15 +1158,13 @@ function_arg_pass_by_reference (cum, mode, type, named) tree type; int named; { -#ifdef TARGET_V4_CALLS - if (TARGET_V4_CALLS && type && AGGREGATE_TYPE_P (type)) + if (DEFAULT_ABI == ABI_V4 && type && AGGREGATE_TYPE_P (type)) { if (TARGET_DEBUG_ARG) fprintf (stderr, "function_arg_pass_by_reference: aggregate\n"); return 1; } -#endif return 0; } @@ -1169,13 +1201,11 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) "setup_vararg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, no_rtl= %d\n", cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), no_rtl); -#ifdef TARGET_V4_CALLS - if (TARGET_V4_CALLS && !no_rtl) + if (DEFAULT_ABI == ABI_V4 && !no_rtl) { rs6000_sysv_varargs_p = 1; save_area = plus_constant (frame_pointer_rtx, RS6000_VARARGS_OFFSET); } -#endif if (cum->words < 8) { @@ -1198,9 +1228,8 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD; } -#ifdef TARGET_V4_CALLS /* Save FP registers if needed. */ - if (TARGET_V4_CALLS && TARGET_HARD_FLOAT && !no_rtl) + if (DEFAULT_ABI == ABI_V4 && TARGET_HARD_FLOAT && !no_rtl) { int fregno = cum->fregno; int num_fp_reg = FP_ARG_V4_MAX_REG + 1 - fregno; @@ -1228,7 +1257,6 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) emit_label (lab); } } -#endif } /* If defined, is a C expression that produces the machine-specific @@ -2342,13 +2370,14 @@ print_operand_address (file, x) else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST) { output_addr_const (file, x); - /* When TARGET_MINIMAL_TOC, use the indirected toc table pointer instead - of the toc pointer. */ + if (DEFAULT_ABI == ABI_V4 && small_data_operand (x, GET_MODE (x))) + fprintf (file, "@sda21(%s)", reg_names[0]); + #ifdef TARGET_NO_TOC - if (TARGET_NO_TOC) + else if (TARGET_NO_TOC) ; - else #endif + else fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 ]); } else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG) @@ -3996,3 +4025,185 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt) return; } + + +/* If defined, a C expression whose value is nonzero if IDENTIFIER + with arguments ARGS is a valid machine specific attribute for DECL. + The attributes in ATTRIBUTES have previously been assigned to DECL. */ + +int +rs6000_valid_decl_attribute_p (decl, attributes, identifier, args) + tree decl; + tree attributes; + tree identifier; + tree args; +{ + return 0; +} + +/* If defined, a C expression whose value is nonzero if IDENTIFIER + with arguments ARGS is a valid machine specific attribute for TYPE. + The attributes in ATTRIBUTES have previously been assigned to TYPE. */ + +int +rs6000_valid_type_attribute_p (type, attributes, identifier, args) + tree type; + tree attributes; + tree identifier; + tree args; +{ + if (TREE_CODE (type) != FUNCTION_TYPE + && TREE_CODE (type) != FIELD_DECL + && TREE_CODE (type) != TYPE_DECL) + return 0; + + if (DEFAULT_ABI == ABI_NT) + { + /* Stdcall attribute says callee is responsible for popping arguments + if they are not variable. */ + if (is_attribute_p ("stdcall", identifier)) + return (args == NULL_TREE); + + /* Cdecl attribute says the callee is a normal C declaration */ + if (is_attribute_p ("cdecl", identifier)) + return (args == NULL_TREE); + + /* Dllimport attribute says says the caller is to call the function + indirectly through a __imp_ pointer. */ + if (is_attribute_p ("dllimport", identifier)) + return (args == NULL_TREE); + + /* Dllexport attribute says says the callee is to create a __imp_ + pointer. */ + if (is_attribute_p ("dllexport", identifier)) + return (args == NULL_TREE); + } + + return 0; +} + +/* If defined, a C expression whose value is zero if the attributes on + TYPE1 and TYPE2 are incompatible, one if they are compatible, and + two if they are nearly compatible (which causes a warning to be + generated). */ + +int +rs6000_comp_type_attributes (type1, type2) + tree type1; + tree type2; +{ + return 1; +} + +/* If defined, a C statement that assigns default attributes to newly + defined TYPE. */ + +void +rs6000_set_default_type_attributes (type) + tree type; +{ +} + +/* Return a dll import reference corresponding to to a call's SYMBOL_REF */ +struct rtx_def * +rs6000_dll_import_ref (call_ref) + rtx call_ref; +{ + char *call_name; + int len; + char *p; + rtx reg1, reg2; + tree node; + + if (GET_CODE (call_ref) != SYMBOL_REF) + abort (); + + call_name = XSTR (call_ref, 0); + len = sizeof ("__imp_") + strlen (call_name); + p = alloca (len); + reg2 = gen_reg_rtx (Pmode); + + strcpy (p, "__imp_"); + strcat (p, call_name); + node = get_identifier (p); + + reg1 = force_reg (Pmode, gen_rtx (SYMBOL_REF, VOIDmode, IDENTIFIER_POINTER (node))); + emit_move_insn (reg2, gen_rtx (MEM, Pmode, reg1)); + + return reg2; +} + + +/* A C statement or statements to switch to the appropriate section + for output of RTX in mode MODE. You can assume that RTX is some + kind of constant in RTL. The argument MODE is redundant except in + the case of a `const_int' rtx. Select the section by calling + `text_section' or one of the alternatives for other sections. + + Do not define this macro if you put all constants in the read-only + data section. */ + +#ifdef USING_SVR4_H + +void +rs6000_select_rtx_section (mode, x) + enum machine_mode mode; + rtx x; +{ + if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x)) + toc_section (); + else if (TARGET_SDATA && GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) <= 8) + sdata2_section (); + else + const_section (); +} + +/* A C statement or statements to switch to the appropriate + section for output of DECL. DECL is either a `VAR_DECL' node + or a constant of some sort. RELOC indicates whether forming + the initial value of DECL requires link-time relocations. */ + +void +rs6000_select_section (decl, reloc) + tree decl; + int reloc; +{ + int size = int_size_in_bytes (TREE_TYPE (decl)); + + if (TREE_CODE (decl) == STRING_CST) + { + if ((! flag_writable_strings) && TARGET_SDATA && (size <= 8)) + sdata2_section (); + else if (! flag_writable_strings) + const_section (); + else if (TARGET_SDATA && (size <= 8)) + sdata_section (); + else + data_section (); + } + else if (TREE_CODE (decl) == VAR_DECL) + { + if ((flag_pic && reloc) + || !TREE_READONLY (decl) + || TREE_SIDE_EFFECTS (decl) + || !DECL_INITIAL (decl) + || (DECL_INITIAL (decl) != error_mark_node + && !TREE_CONSTANT (DECL_INITIAL (decl)))) + { + if (TARGET_SDATA && (size <= 8) && (size > 0)) + sdata_section (); + else + data_section (); + } + else + { + if (TARGET_SDATA && (size <= 8) && (size > 0)) + sdata2_section (); + else + const_section (); + } + } + else + const_section (); +} +#endif /* USING_SVR4_H */ diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 4830957..0ecc03c 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -140,6 +140,10 @@ Boston, MA 02111-1307, USA. */ Do not define this macro if it does not need to do anything. */ +#ifndef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS +#endif + #define EXTRA_SPECS \ { "cpp_cpu", CPP_CPU_SPEC }, \ { "cpp_default", CPP_DEFAULT_SPEC }, \ @@ -147,7 +151,36 @@ Boston, MA 02111-1307, USA. */ { "cpp_sysv_default", CPP_SYSV_DEFAULT_SPEC }, \ { "cpp_endian", CPP_ENDIAN_SPEC }, \ { "asm_cpu", ASM_CPU_SPEC }, \ - { "asm_default", ASM_DEFAULT_SPEC } + { "asm_default", ASM_DEFAULT_SPEC }, \ + { "link_syscalls", LINK_SYSCALLS_SPEC }, \ + { "link_libg", LINK_LIBG_SPEC }, \ + { "link_path", LINK_PATH_SPEC }, \ + { "link_start", LINK_START_SPEC }, \ + SUBTARGET_EXTRA_SPECS + +/* Default paths to give linker under V.4 */ +#ifndef LINK_PATH_SPEC +#define LINK_PATH_SPEC "" +#endif + +/* Default location of syscalls.exp under AIX */ +#ifndef CROSS_COMPILE +#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp" +#else +#define LINK_SYSCALLS_SPEC "" +#endif + +/* Default location of libg.exp under AIX */ +#ifndef CROSS_COMPILE +#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp" +#else +#define LINK_LIBG_SPEC "" +#endif + +/* Default starting address if specified */ +#ifndef LINK_START_SPEC +#define LINK_START_SPEC "" +#endif /* Define the options for the binder: Start text at 512, align all segments to 512 bytes, and warn if there is text relocation. @@ -163,15 +196,9 @@ Boston, MA 02111-1307, USA. */ that to actually build a shared library you will also need to specify an export list with the -Wl,-bE option. */ -#ifndef CROSS_COMPILE -#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ - %{static:-bnso} \ - %{shared:-bM:SRE}" -#else #define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ - %{static:-bnso -bI:/lib/syscalls.exp} \ - %{!shared:%{g*:-bexport:/usr/lib/libg.exp}} %{shared:-bM:SRE}" -#endif + %{static:-bnso %(link_syscalls) } \ + %{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}" /* Profiled library versions are used by linking with special directories. */ #define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\ @@ -1206,13 +1233,24 @@ extern int rs6000_sysv_varargs_p; /* Minimum and maximum floating point registers used to hold arguments. */ #define FP_ARG_MIN_REG 33 -#define FP_ARG_MAX_REG 45 +#define FP_ARG_AIX_MAX_REG 45 +#define FP_ARG_V4_MAX_REG 40 +#define FP_ARG_MAX_REG FP_ARG_AIX_MAX_REG #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1) /* Return registers */ #define GP_ARG_RETURN GP_ARG_MIN_REG #define FP_ARG_RETURN FP_ARG_MIN_REG +/* Flags for the call/call_value rtl operations set up by function_arg */ +enum rs6000_call_cookie +{ + CALL_V4_SET_FP_ARGS = -1, /* V4, FP args passed */ + CALL_NORMAL = 0, /* no special processing */ + CALL_V4_CLEAR_FP_ARGS = 1, /* V4, no FP args passed */ + CALL_NT_DLLIMPORT = 2 /* NT, this is a DLL import call */ +}; + /* Define cutoff for using external functions to save floating point */ #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63) @@ -1246,12 +1284,13 @@ extern int rs6000_sysv_varargs_p; typedef struct rs6000_args { - int words; /* # words uses for passing GP registers */ - int fregno; /* next available FP register */ - int nargs_prototype; /* # args left in the current prototype */ - int orig_nargs; /* Original value of nargs_prototype */ - int varargs_offset; /* offset of the varargs save area */ - int prototype; /* Whether a prototype was defined */ + int words; /* # words uses for passing GP registers */ + int fregno; /* next available FP register */ + int nargs_prototype; /* # args left in the current prototype */ + int orig_nargs; /* Original value of nargs_prototype */ + int varargs_offset; /* offset of the varargs save area */ + int prototype; /* Whether a prototype was defined */ + enum rs6000_call_cookie call_cookie; /* Do special things for this call */ } CUMULATIVE_ARGS; /* Define intermediate macro to compute the size (in registers) of an argument @@ -1423,6 +1462,35 @@ typedef struct rs6000_args #define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT) \ rs6000_initialize_trampoline (ADDR, FNADDR, CXT) +/* If defined, a C expression whose value is nonzero if IDENTIFIER + with arguments ARGS is a valid machine specific attribute for DECL. + The attributes in ATTRIBUTES have previously been assigned to DECL. */ + +#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \ + (rs6000_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS)) + +/* If defined, a C expression whose value is nonzero if IDENTIFIER + with arguments ARGS is a valid machine specific attribute for TYPE. + The attributes in ATTRIBUTES have previously been assigned to TYPE. */ + +#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \ + (rs6000_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS)) + +/* If defined, a C expression whose value is zero if the attributes on + TYPE1 and TYPE2 are incompatible, one if they are compatible, and + two if they are nearly compatible (which causes a warning to be + generated). */ + +#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \ + (rs6000_comp_type_attributes (TYPE1, TYPE2)) + +/* If defined, a C statement that assigns default attributes to newly + defined TYPE. */ + +#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \ + (rs6000_set_default_type_attributes (TYPE)) + + /* Definitions for __builtin_return_address and __builtin_frame_address. __builtin_return_address (0) should give link register (65), enable this. */ @@ -1618,6 +1686,9 @@ typedef struct rs6000_args && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ && LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0)))) +#define LEGITIMATE_SMALL_DATA_P(MODE, X) \ + (DEFAULT_ABI == ABI_V4 && small_data_operand (X, MODE)) + #define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET) \ (GET_CODE (X) == CONST_INT \ && (unsigned) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000) @@ -1658,6 +1729,8 @@ typedef struct rs6000_args if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \ && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0))) \ goto ADDR; \ + if (LEGITIMATE_SMALL_DATA_P (MODE, X)) \ + goto ADDR; \ if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (X)) \ goto ADDR; \ if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X)) \ @@ -2434,7 +2507,7 @@ toc_section () \ `assemble_name' uses this. */ #define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fprintf (FILE, NAME) + fputs (NAME, FILE) /* This is how to output an internal numbered label where PREFIX is the class of label and NUM is the number within the class. */ @@ -2729,6 +2802,7 @@ extern int lwa_operand (); extern int call_operand (); extern int current_file_function_operand (); extern int input_operand (); +extern int small_data_operand (); extern void init_cumulative_args (); extern void function_arg_advance (); extern int function_arg_boundary (); @@ -2766,3 +2840,8 @@ extern int rs6000_adjust_cost (); extern void rs6000_trampoline_template (); extern int rs6000_trampoline_size (); extern void rs6000_initialize_trampoline (); +extern int rs6000_comp_type_attributes (); +extern int rs6000_valid_decl_attribute_p (); +extern int rs6000_valid_type_attribute_p (); +extern void rs6000_set_default_type_attributes (); +extern struct rtx_def *rs6000_dll_import_ref (); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index bd8c0d2..8131d84 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6405,6 +6405,15 @@ abort (); operands[0] = XEXP (operands[0], 0); + + /* Convert NT DLL imports into an indirect call. */ + if (GET_CODE (operands[0]) == SYMBOL_REF + && INTVAL (operands[2]) == (int)CALL_NT_DLLIMPORT) + { + operands[0] = rs6000_dll_import_ref (operands[0]); + operands[2] = GEN_INT ((int)CALL_NORMAL); + } + if (GET_CODE (operands[0]) != SYMBOL_REF) { if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC) @@ -6426,6 +6435,7 @@ else if (DEFAULT_ABI == ABI_NT) { /* NT function pointers are really pointers to a two word area */ + rs6000_save_toc_p = 1; emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]), operands[1], operands[2], toc_addr, toc_reg)); @@ -6450,6 +6460,15 @@ abort (); operands[1] = XEXP (operands[1], 0); + + /* Convert NT DLL imports into an indirect call. */ + if (GET_CODE (operands[1]) == SYMBOL_REF + && INTVAL (operands[3]) == (int)CALL_NT_DLLIMPORT) + { + operands[1] = rs6000_dll_import_ref (operands[1]); + operands[3] = GEN_INT ((int)CALL_NORMAL); + } + if (GET_CODE (operands[1]) != SYMBOL_REF) { if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC) @@ -6472,6 +6491,7 @@ else if (DEFAULT_ABI == ABI_NT) { /* NT function pointers are really pointers to a two word area */ + rs6000_save_toc_p = 1; emit_call_insn (gen_call_value_indirect_nt (operands[0], force_reg (Pmode, operands[1]), operands[2], operands[3], @@ -6498,11 +6518,11 @@ "" "* { - if (INTVAL (operands[2]) > 0) - return \"creqv 6,6,6\;bl %z0\"; - - else if (INTVAL (operands[2]) < 0) - return \"crxor 6,6,6\;bl %z0\"; + switch ((enum rs6000_call_cookie)INTVAL (operands[2])) + { + case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break; + case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break; + } return \"bl %z0\"; }" @@ -6523,16 +6543,16 @@ "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT" "* { - if (INTVAL (operands[2]) > 0) - output_asm_insn (\"creqv 6,6,6\", operands); - - else if (INTVAL (operands[2]) < 0) - output_asm_insn (\"crxor 6,6,6\", operands); - /* Indirect calls should go through call_indirect */ if (GET_CODE (operands[0]) == REG) abort (); + switch ((enum rs6000_call_cookie)INTVAL (operands[2])) + { + case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break; + case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break; + } + return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\"; }" [(set_attr "length" "8,12")]) @@ -6545,16 +6565,16 @@ "DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4" "* { - if (INTVAL (operands[2]) > 0) - output_asm_insn (\"creqv 6,6,6\", operands); - - else if (INTVAL (operands[2]) < 0) - output_asm_insn (\"crxor 6,6,6\", operands); - /* Indirect calls should go through call_indirect */ if (GET_CODE (operands[0]) == REG) abort (); + switch ((enum rs6000_call_cookie)INTVAL (operands[2])) + { + case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break; + case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break; + } + return \"bl %z0\"; }" [(set_attr "length" "4,8")]) @@ -6568,11 +6588,11 @@ "" "* { - if (INTVAL (operands[3]) > 0) - return \"creqv 6,6,6\;bl %z1\"; - - else if (INTVAL (operands[3]) < 0) - return \"crxor 6,6,6\;bl %z1\"; + switch ((enum rs6000_call_cookie)INTVAL (operands[3])) + { + case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break; + case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break; + } return \"bl %z1\"; }" @@ -6587,16 +6607,16 @@ "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT" "* { - if (INTVAL (operands[3]) > 0) - output_asm_insn (\"creqv 6,6,6\", operands); - - else if (INTVAL (operands[3]) < 0) - output_asm_insn (\"crxor 6,6,6\", operands); - /* This should be handled by call_value_indirect */ if (GET_CODE (operands[1]) == REG) abort (); + switch ((enum rs6000_call_cookie)INTVAL (operands[3])) + { + case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break; + case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break; + } + return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\"; }" [(set_attr "length" "8,12")]) @@ -6610,16 +6630,16 @@ "DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4" "* { - if (INTVAL (operands[3]) > 0) - output_asm_insn (\"creqv 6,6,6\", operands); - - else if (INTVAL (operands[3]) < 0) - output_asm_insn (\"crxor 6,6,6\", operands); - /* This should be handled by call_value_indirect */ if (GET_CODE (operands[1]) == REG) abort (); + switch ((enum rs6000_call_cookie)INTVAL (operands[3])) + { + case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break; + case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break; + } + return \"bl %z1\"; }" [(set_attr "length" "4,8")]) diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index eacd292..183be95 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */ #define MASK_NO_BITFIELD_TYPE 0x40000000 /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */ #define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */ #define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative */ -#define MASK_UNUSED 0x08000000 /* UNUSED, was no-traceback */ +#define MASK_SDATA 0x08000000 /* use eabi .sdata/.sdata2/.sbss relocations */ #define MASK_LITTLE_ENDIAN 0x04000000 /* target is little endian */ #define MASK_CALLS_1 0x02000000 /* First ABI bit (AIX, AIXDESC) */ #define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args */ @@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */ #define TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE) #define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN) #define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE) +#define TARGET_SDATA (target_flags & MASK_SDATA) #define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN) #define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE) #define TARGET_TOC ((target_flags & (MASK_64BIT \ @@ -71,9 +72,12 @@ Boston, MA 02111-1307, USA. */ { "strict-align", MASK_STRICT_ALIGN }, \ { "no-strict-align", -MASK_STRICT_ALIGN }, \ { "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \ + { "relocatable", -MASK_SDATA }, \ { "no-relocatable", -MASK_RELOCATABLE }, \ { "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \ { "no-relocatable-lib", -MASK_RELOCATABLE }, \ + { "sdata", MASK_SDATA }, \ + { "no-sdata", -MASK_SDATA }, \ { "little-endian", MASK_LITTLE_ENDIAN }, \ { "little", MASK_LITTLE_ENDIAN }, \ { "big-endian", -MASK_LITTLE_ENDIAN }, \ @@ -106,6 +110,23 @@ Boston, MA 02111-1307, USA. */ #define SUBTARGET_OVERRIDE_OPTIONS \ do { \ + rs6000_current_abi = ((TARGET_AIXDESC_CALLS) ? ABI_AIX : \ + (TARGET_NT_CALLS) ? ABI_NT : \ + (TARGET_AIX_CALLS) ? ABI_AIX_NODESC : \ + ABI_V4); \ + \ + if (TARGET_RELOCATABLE && TARGET_SDATA) \ + { \ + target_flags &= ~MASK_SDATA; \ + error ("-mrelocatable and -msdata are incompatible."); \ + } \ + \ + if (TARGET_SDATA && DEFAULT_ABI != ABI_V4) \ + { \ + target_flags &= ~MASK_SDATA; \ + error ("-msdata and -mcall-aix are incompatible."); \ + } \ + \ if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \ { \ target_flags |= MASK_MINIMAL_TOC; \ @@ -135,11 +156,6 @@ do { \ target_flags |= MASK_LITTLE_ENDIAN; \ error ("-mcall-nt must be little endian"); \ } \ - \ - rs6000_current_abi = ((TARGET_AIXDESC_CALLS) ? ABI_AIX : \ - (TARGET_NT_CALLS) ? ABI_NT : \ - (TARGET_AIX_CALLS) ? ABI_AIX_NODESC : \ - ABI_V4); \ } while (0) /* Default ABI to compile code for */ @@ -156,8 +172,6 @@ do { \ /* System V.4 passes the first 8 floating arguments in registers, instead of the first 13 like AIX does. */ #undef FP_ARG_MAX_REG -#define FP_ARG_AIX_MAX_REG 45 -#define FP_ARG_V4_MAX_REG 40 #define FP_ARG_MAX_REG ((TARGET_AIX_CALLS) ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG) /* Size of the V.4 varargs area if needed */ @@ -263,14 +277,20 @@ do { \ /* Besides the usual ELF sections, we need a toc section. */ #undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc +#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc, in_sdata, in_sdata2, in_sbss #undef EXTRA_SECTION_FUNCTIONS #define EXTRA_SECTION_FUNCTIONS \ CONST_SECTION_FUNCTION \ CTORS_SECTION_FUNCTION \ DTORS_SECTION_FUNCTION \ - TOC_SECTION_FUNCTION + TOC_SECTION_FUNCTION \ + SDATA_SECTION_FUNCTION \ + SDATA2_SECTION_FUNCTION \ + SBSS_SECTION_FUNCTION + +extern void toc_section (), sdata_section (), sdata2_section (); +extern void sbss_section (); #define TOC_SECTION_FUNCTION \ void \ @@ -321,16 +341,65 @@ toc_section () \ #define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\"" #define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t\".got1\",\"aw\"" -/* Use the TOC section for TOC entries. */ +#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\"" +#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\"" +#define SBSS_SECTION_ASM_OP "\t.section\t\".sbss\",\"aw\",@nobits" -#undef SELECT_RTX_SECTION -#define SELECT_RTX_SECTION(MODE, X) \ -{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X)) \ - toc_section (); \ - else \ - const_section (); \ +#define SDATA_SECTION_FUNCTION \ +void \ +sdata_section () \ +{ \ + if (in_section != in_sdata) \ + { \ + in_section = in_sdata; \ + fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \ + } \ +} + +#define SDATA2_SECTION_FUNCTION \ +void \ +sdata2_section () \ +{ \ + if (in_section != in_sdata2) \ + { \ + in_section = in_sdata2; \ + fprintf (asm_out_file, "%s\n", SDATA2_SECTION_ASM_OP); \ + } \ +} + +#define SBSS_SECTION_FUNCTION \ +void \ +sbss_section () \ +{ \ + if (in_section != in_sbss) \ + { \ + in_section = in_sbss; \ + fprintf (asm_out_file, "%s\n", SBSS_SECTION_ASM_OP); \ + } \ } +/* A C statement or statements to switch to the appropriate section + for output of RTX in mode MODE. You can assume that RTX is some + kind of constant in RTL. The argument MODE is redundant except in + the case of a `const_int' rtx. Select the section by calling + `text_section' or one of the alternatives for other sections. + + Do not define this macro if you put all constants in the read-only + data section. */ + +extern void rs6000_select_rtx_section (), rs6000_select_section (); + +#undef SELECT_RTX_SECTION +#define SELECT_RTX_SECTION(MODE, X) rs6000_select_rtx_section (MODE, X) + +/* A C statement or statements to switch to the appropriate + section for output of DECL. DECL is either a `VAR_DECL' node + or a constant of some sort. RELOC indicates whether forming + the initial value of DECL requires link-time relocations. */ + +#undef SELECT_SECTION +#define SELECT_SECTION(DECL,RELOC) rs6000_select_section (DECL, RELOC) + /* Return non-zero if this entry is to be written into the constant pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST containing one of them. If -mfp-in-toc (the default), we also do @@ -423,12 +492,11 @@ extern int rs6000_pic_labelno; #define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ fprintf (FILE, ".%s", PREFIX) -/* Pass -mppc to the assembler, since that is what powerpc.h currently - implies. */ +/* Pass various options to the assembler */ #undef ASM_SPEC #define ASM_SPEC "-u %(asm_cpu) \ %{V} %{v:%{!V:-V}} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \ -%{mrelocatable} %{mrelocatable-lib} %{memb} \ +%{mrelocatable} %{mrelocatable-lib} %{memb} %{msdata: -memb} \ %{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}" /* Output .file and comments listing what options there are */ @@ -528,14 +596,46 @@ do { \ XSTR (sym_ref, 0) = str; \ } \ } \ + else if (TARGET_SDATA && DEFAULT_ABI == ABI_V4 \ + && TREE_CODE (DECL) == VAR_DECL) \ + { \ + int size = int_size_in_bytes (TREE_TYPE (DECL)); \ + tree section_name = DECL_SECTION_NAME (DECL); \ + char *name = ((section_name) \ + ? IDENTIFIER_POINTER (section_name) \ + : (char *)0); \ + \ + if ((size > 0 && size <= 8) \ + || (name \ + && (strcmp (name, ".sdata") == 0 \ + || strcmp (name, ".sdata2") == 0 \ + || strcmp (name, ".sbss") == 0 \ + || strcmp (name, ".sbss2") == 0 \ + || strcmp (name, ".PPC.EMB.sdata0") == 0 \ + || strcmp (name, ".PPC.EMB.sbss0") == 0))) \ + { \ + rtx sym_ref = XEXP (DECL_RTL (DECL), 0); \ + char *str = permalloc (2 + strlen (XSTR (sym_ref, 0))); \ + strcpy (str, "@"); \ + strcat (str, XSTR (sym_ref, 0)); \ + XSTR (sym_ref, 0) = str; \ + } \ + } \ } while (0) /* This macro gets just the user-specified name out of the string in a SYMBOL_REF. Discard - a leading * */ + a leading * or @. */ #undef STRIP_NAME_ENCODING #define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \ - (VAR) = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*')) + (VAR) = ((SYMBOL_NAME) + (((SYMBOL_NAME)[0] == '*') || ((SYMBOL_NAME)[0] == '@'))) + +/* This is how to output a reference to a user-level label named NAME. + `assemble_name' uses this. */ + +#undef ASM_OUTPUT_LABELREF +#define ASM_OUTPUT_LABELREF(FILE,NAME) \ + fputs ((NAME) + (NAME[0] == '@'), FILE) /* But, to make this work, we have to output the stabs for the function name *first*... */ @@ -552,21 +652,17 @@ do { \ "-DPPC -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(powerpc) -Amachine(powerpc)" /* Don't put -Y P, for cross compilers */ -#undef LINK_SPEC -#ifdef CROSS_COMPILE -#define LINK_SPEC "\ -%{h*} %{V} %{v:%{!V:-V}} \ -%{b} %{Wl,*:%*} \ -%{static:-dn -Bstatic} \ -%{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \ -%{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \ -%{G:-G} \ -%{YP,*} \ -%{Qy:} %{!Qn:-Qy} \ -%{mlittle: -oformat elf32-powerpcle } %{mlittle-endian: -oformat elf32-powerpcle } \ -%{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc }" +#undef LINK_PATH_SPEC +#ifndef CROSS_COMPILE +#define LINK_PATH_SPEC "\ +%{!nostdlib: %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ +%{!p:-Y P,/usr/ccs/lib:/usr/lib}}}" + #else +#define LINK_PATH_SPEC "" +#endif +#undef LINK_SPEC #define LINK_SPEC "\ %{h*} %{V} %{v:%{!V:-V}} \ %{b} %{Wl,*:%*} \ @@ -575,12 +671,10 @@ do { \ %{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \ %{G:-G} \ %{YP,*} \ -%{!nostdlib: %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ - %{!p:-Y P,/usr/ccs/lib:/usr/lib}}} \ +%(link_path) %(link_start) \ %{Qy:} %{!Qn:-Qy} \ %{mlittle: -oformat elf32-powerpcle } %{mlittle-endian: -oformat elf32-powerpcle } \ %{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc }" -#endif /* CROSS_COMPILE */ #undef CPP_SYSV_SPEC #define CPP_SYSV_SPEC \ @@ -612,4 +706,4 @@ do { \ `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ #undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-sysv" } +#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-sysv", "mno-sdata" } diff --git a/gcc/config/rs6000/sysv4le.h b/gcc/config/rs6000/sysv4le.h index 14663a6..3eeb803 100644 --- a/gcc/config/rs6000/sysv4le.h +++ b/gcc/config/rs6000/sysv4le.h @@ -42,4 +42,4 @@ Boston, MA 02111-1307, USA. */ `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ #undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv" } +#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv", "mno-sdata" } diff --git a/gcc/config/rs6000/t-ppcgas b/gcc/config/rs6000/t-ppcgas index 4aba306..8cca77b 100644 --- a/gcc/config/rs6000/t-ppcgas +++ b/gcc/config/rs6000/t-ppcgas @@ -19,11 +19,11 @@ fp-bit.c: $(srcdir)/config/fp-bit.c MULTILIB_OPTIONS = msoft-float \ mlittle/mbig \ - mcall-sysv/mcall-aix/mcall-aixdesc + mcall-sysv/mcall-aix # /mcall-aixdesc MULTILIB_DIRNAMES = soft-float \ little big \ - sysv aix aixdesc + sysv aix # aixdesc MULTILIB_MATCHES = mlittle=mlittle-endian \ mbig=mbig-endian \ @@ -31,7 +31,7 @@ MULTILIB_MATCHES = mlittle=mlittle-endian \ msoft-float=mcpu?821 \ msoft-float=mcpu?860 -MULTILIB_EXCEPTIONS = *mlittle/*mcall-aixdesc* +#MULTILIB_EXCEPTIONS = *mlittle/*mcall-aixdesc* LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib diff --git a/gcc/config/rs6000/win-nt.h b/gcc/config/rs6000/win-nt.h index fa71bf8..9789131 100644 --- a/gcc/config/rs6000/win-nt.h +++ b/gcc/config/rs6000/win-nt.h @@ -45,8 +45,8 @@ Boston, MA 02111-1307, USA. */ #undef LIB_SPEC #define LIB_SPEC "%{mwindows:-subsystem:windows -entry:WinMainCRTStartup \ USER32.LIB GDI32.LIB COMDLG32.LIB WINSPOOL.LIB} \ - %{!mwindows:-subsystem:console -entry:mainCRTStartup} \ - %{mcrtmt:LIBCMT.LIB KERNEL32.LIB} %{!mcrtmt:LIBC.LIB KERNEL32.LIB} \ + %{!mwindows:-subsystem console -e mainCRTStartup} \ + %{mcrtmt:LIBCMT.LIB KERNEL32.LIB} %{!mcrtmt:-lkernel32 -lcygwin} \ %{v}" #undef LINK_SPEC @@ -249,6 +249,19 @@ toc_section () \ fprintf (FILE, "\t.ualong .."); \ assemble_name (FILE, NAME); \ fprintf (FILE, ",.toc\n"); \ + \ + if (lookup_attribute ("dllexport", \ + TYPE_ATTRIBUTES (TREE_TYPE (DECL)))) \ + { \ + fprintf (FILE, "\t.globl __imp_"); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n__imp_"); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, ":\n\t.ulong "); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } \ + \ fprintf (FILE, "\t.section .text\n\t.align 2\n.."); \ assemble_name (FILE, NAME); \ fprintf (FILE, ":\n"); \ -- cgit v1.1