Small data support; Windows NT attributes; windows NT call indrect fix
authorMichael Meissner <meissner@gcc.gnu.org>
Wed, 24 Jan 1996 20:56:01 +0000 (20:56 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Wed, 24 Jan 1996 20:56:01 +0000 (20:56 +0000)
From-SVN: r11093

12 files changed:
gcc/config/rs6000/aix41.h
gcc/config/rs6000/eabi.h
gcc/config/rs6000/eabiaix.h
gcc/config/rs6000/eabile.h
gcc/config/rs6000/eabisim.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/sysv4.h
gcc/config/rs6000/sysv4le.h
gcc/config/rs6000/t-ppcgas
gcc/config/rs6000/win-nt.h

index 3807d0b29cd3507628dc8525bc07a15dc193cabb..98aaaf1b4b522aed40c7e8b4f171b4d9fecaa87e 100644 (file)
@@ -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
 
index ea32add7d07099e378022258d09dcd6147b0a1ec..25bc1efa5a5ba2a294826b31f31bad2bf0a0bd43 100644 (file)
@@ -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 \
index 82b059c942ad84d20e73f3274087a3cd72993a6a..4ac15453ba3eb34f99d1780fcc5bbc899d360f46 100644 (file)
@@ -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" }
index aaa3ecd426c0443cf9a14654f777a40b9b3cdac0..cf1a6afbecdcf4e0c43bc94ef643e45e4dcca661 100644 (file)
@@ -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" }
index fcd094eefd799bf29cdc28d23e98672484cb1cbb..30371eba57867794e5085b9d9eea28c6dbb9a9d0 100644 (file)
@@ -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 \
index a942923bcaadec163dfcd8974f90df7ee31f8bb4..47e1f35af8fda2485bd7d32f0253e7439f077d7e 100644 (file)
@@ -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;
+}
+
 \f
 /* 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
 }
 \f
 /* 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;
 }
+
+\f
+/* 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_<name> pointer.  */
+      if (is_attribute_p ("dllimport", identifier))
+       return (args == NULL_TREE);
+
+      /* Dllexport attribute says says the callee is to create a __imp_<name>
+        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;
+}
+
+\f
+/* 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 */
index 4830957e4c01c502887715f9bf64d65b5eb9e426..0ecc03c2b95be6043d69133d405753601c6123e8 100644 (file)
@@ -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)
 \f
+/* 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))
+
+\f
 /* 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 ();
index bd8c0d2c6a3bac8cb8e6013dfc23419809fe3930..8131d84c6277eace6fe105ecc40bf8a4bd8bbd8f 100644 (file)
     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)
          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));
     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)
          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],
   ""
   "*
 {
-  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\";
 }"
   "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")])
   "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")])
   ""
   "*
 {
-  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\";
 }"
   "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")])
   "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")])
index eacd292f01998d428c2fb3d24684415843866beb..183be95a485fe5d8ed5e093f15b740a85f362ed9 100644 (file)
@@ -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,<path> 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" }
index 14663a6b6c75d90e535f00c7b68415ab8049d7ff..3eeb803e167b67ab5fef2edcb2cea873a673ae26 100644 (file)
@@ -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" }
index 4aba30647e3eaba28c9bb02e71a14cf85f3d0c65..8cca77ba95051db760c6ab96d5f8e847c52457c4 100644 (file)
@@ -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
index fa71bf8dd38c51dd50fdc5d446c7622d5dcf9827..9789131a6326478fa2769cdc5c1e6ed35dd015ae 100644 (file)
@@ -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");                                       \