OSDN Git Service

Cygwin32 support; Make eabi update stack first before doing stores in prolog
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Feb 1996 19:19:40 +0000 (19:19 +0000)
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Feb 1996 19:19:40 +0000 (19:19 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11259 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/rs6000/cygwin32.h
gcc/config/rs6000/ntstack.asm [new file with mode: 0644]
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/t-winnt
gcc/config/rs6000/win-nt.h
gcc/config/rs6000/x-cygwin32 [new file with mode: 0644]
gcc/config/rs6000/xm-cygwin32.h [new file with mode: 0644]
gcc/libgcc1-test.c

index cdec7af..2230848 100644 (file)
@@ -35,7 +35,7 @@ Boston, MA 02111-1307, USA. */
 
 #define        CPP_PREDEFINES "-DWIN32 -D__WIN32__ -D__WINNT__ \
   -D__CYGWIN32__ -DPOSIX \
-  -D_POWER -DPPC -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
+  -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
 
 /* We have to dynamic link to get to the system dlls,
    and I've put all of libc and libm and the unix stuff into
@@ -49,10 +49,6 @@ Boston, MA 02111-1307, USA. */
 #define        LINK_SPEC "%{v:-V}"
 
 
-/* No need for libgcc, it's in the shared library. */
-#undef LIBGCC_SPEC
-#define LIBGCC_SPEC ""
-
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC "%{!:crt0%O%s}"
 
@@ -62,3 +58,7 @@ Boston, MA 02111-1307, USA. */
 #define WCHAR_TYPE "short unsigned int"
 
 /* XXX set up stack probing */
+
+#define DBX_DEBUGGING_INFO 
+#undef SDB_DEBUGGING_INFO 
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gcc/config/rs6000/ntstack.asm b/gcc/config/rs6000/ntstack.asm
new file mode 100644 (file)
index 0000000..71a251a
--- /dev/null
@@ -0,0 +1,42 @@
+# CYGNUS LOCAL -- NT/WRS development, meissner
+# Allocate stack for NT, inserting stack probes every 4k pages
+
+       .file   "ntstack.asm"
+
+#      Setup MS Structured-Exception-Handling
+       .pdata
+       .align 2
+       .ualong ..__allocate_stack,__allocate_stack.e,0,0,__allocate_stack.b
+
+#      Switch to the relocation section
+       .reldata
+       .globl __allocate_stack
+       .globl ..__allocate_stack
+__allocate_stack:
+       .ualong ..__allocate_stack,.toc
+
+       .text
+       .align 2
+..__allocate_stack:
+       .function       ..__allocate_stack
+__allocate_stack.b:
+       lwz     0,0(1)                  # old stack link
+       srawi.  4,3,12                  # get # of pages to check
+       neg     3,3                     # negate so we can use stwux
+       bgt-    0,.Lcheck
+       stwux   0,1,3                   # small request, just decrement and return
+       blr
+
+.Lcheck:
+       mtctr   4                       # number of pages to check
+       mr      5,1                     # tmp pointer
+.Lloop:
+       lwzu    6,-4096(5)              # touch the page
+       bdnz+   .Lloop                  # and loop back
+
+       stwux   0,1,3                   # update stack pointer
+       blr
+
+__allocate_stack.e:
+FE_MOT_RESVD..__allocate_stack:
+# END CYGNUS LOCAL -- NT/WRS development, meissner
index 40c9066..0c0eae6 100644 (file)
@@ -2899,6 +2899,8 @@ output_prolog (file, size)
   int reg_size = info->reg_size;
   char *store_reg;
   char *load_reg;
+  int sp_reg = 1;
+  int sp_offset = 0;
 
   if (TARGET_32BIT)
     {
@@ -2941,12 +2943,36 @@ output_prolog (file, size)
       common_mode_defined = 1;
     }
 
+  /* For V.4, update stack before we do any saving and set back pointer.  */
+  if (info->push_p && DEFAULT_ABI == ABI_V4)
+    {
+      if (info->total_size < 32767)
+       {
+         asm_fprintf (file,
+                      (TARGET_32BIT) ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n",
+                      reg_names[1], - info->total_size, reg_names[1]);
+         sp_offset = info->total_size;
+       }
+      else
+       {
+         int neg_size = - info->total_size;
+         sp_reg = 12;
+         asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
+         asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n",
+                      reg_names[0], (neg_size >> 16) & 0xffff,
+                      reg_names[0], reg_names[0], neg_size & 0xffff);
+         asm_fprintf (file,
+                      (TARGET_32BIT) ? "\t{stux|stwux} %s,%s,%s\n" : "\tstdux %s,%s,%s\n",
+                      reg_names[1], reg_names[1], reg_names[0]);
+       }
+    }
+
   /* If we use the link register, get it into r0.  */
   if (info->lr_save_p)
     asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
 
   /* If we need to save CR, put it into r12.  */
-  if (info->cr_save_p)
+  if (info->cr_save_p && sp_reg != 12)
     asm_fprintf (file, "\tmfcr %s\n", reg_names[12]);
 
   /* Do any required saving of fpr's.  If only one or two to save, do it
@@ -2955,10 +2981,10 @@ output_prolog (file, size)
   if (FP_SAVE_INLINE (info->first_fp_reg_save))
     {
       int regno = info->first_fp_reg_save;
-      int loc   = info->fp_save_offset;
+      int loc   = info->fp_save_offset + sp_offset;
 
       for ( ; regno < 64; regno++, loc += 8)
-       asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[1]);
+       asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]);
     }
   else if (info->first_fp_reg_save != 64)
     asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX,
@@ -2968,17 +2994,17 @@ output_prolog (file, size)
   if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT)
     {
       int regno    = info->first_gp_reg_save;
-      int loc      = info->gp_save_offset;
+      int loc      = info->gp_save_offset + sp_offset;
 
       for ( ; regno < 32; regno++, loc += reg_size)
-       asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[1]);
+       asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]);
     }
 
   else if (info->first_gp_reg_save != 32)
     asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n",
                 reg_names[info->first_gp_reg_save],
-                info->gp_save_offset,
-                reg_names[1]);
+                info->gp_save_offset + sp_offset,
+                reg_names[sp_reg]);
 
   /* Save main's arguments if we need to call a function */
 #ifdef NAME__MAIN
@@ -2989,23 +3015,75 @@ output_prolog (file, size)
       int size = info->main_size;
 
       for (regno = 3; size > 0; regno++, loc -= reg_size, size -= reg_size)
-       asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[1]);
+       asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]);
     }
 #endif
 
   /* Save lr if we used it.  */
   if (info->lr_save_p)
-    asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset, reg_names[1]);
+    asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset + sp_offset,
+                reg_names[sp_reg]);
 
   /* Save CR if we use any that must be preserved.  */
   if (info->cr_save_p)
-    asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset, reg_names[1]);
+    {
+      if (sp_reg == 12)        /* If r12 is used to hold the original sp, copy cr now */
+       {
+         asm_fprintf (file, "\tmfcr %s\n", reg_names[0]);
+         asm_fprintf (file, store_reg, reg_names[0],
+                      info->cr_save_offset + sp_offset,
+                      reg_names[sp_reg]);
+       }
+      else
+       asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset,
+                    reg_names[sp_reg]);
+    }
 
   if (info->toc_save_p)
-    asm_fprintf (file, store_reg, reg_names[2], info->toc_save_offset, reg_names[1]);
+    asm_fprintf (file, store_reg, reg_names[2], info->toc_save_offset + sp_offset,
+                reg_names[sp_reg]);
 
-  /* Update stack and set back pointer.  */
-  if (info->push_p)
+  /* NT needs us to probe the stack frame every 4k pages for large frames, so
+     do it here.  */
+  if (DEFAULT_ABI == ABI_NT && info->total_size > 4096)
+    {
+      if (info->total_size < 32768)
+       {
+         int probe_offset = 4096;
+         while (probe_offset < info->total_size)
+           {
+             asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", reg_names[0], -probe_offset, reg_names[1]);
+             probe_offset += 4096;
+           }
+       }
+      else
+       {
+         int probe_iterations = info->total_size / 4096;
+         static int probe_labelno = 0;
+         char buf[256];
+
+         if (probe_iterations < 32768)
+           asm_fprintf (file, "\tli %s,%d\n", reg_names[12], probe_iterations);
+         else
+           {
+             asm_fprintf (file, "\tlis %s,%d\n", reg_names[12], probe_iterations >> 16);
+             if (probe_iterations & 0xffff)
+               asm_fprintf (file, "\tori %s,%s,%d\n", reg_names[12], reg_names[12],
+                            probe_iterations & 0xffff);
+           }
+         asm_fprintf (file, "\tmtctr %s\n", reg_names[12]);
+         asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
+         ASM_OUTPUT_INTERNAL_LABEL (file, "LCprobe", probe_labelno);
+         asm_fprintf (file, "\t{lu|lwzu} %s,-4096(%s)\n", reg_names[0], reg_names[12]);
+         ASM_GENERATE_INTERNAL_LABEL (buf, "LCprobe", probe_labelno);
+         fputs ("\tbdnz ", file);
+         assemble_name (file, buf);
+         fputs ("\n", file);
+       }
+    }
+
+  /* Update stack and set back pointer and we have already done so for V.4.  */
+  if (info->push_p && DEFAULT_ABI != ABI_V4)
     {
       if (info->total_size < 32767)
        asm_fprintf (file,
@@ -3063,8 +3141,17 @@ output_prolog (file, size)
                asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[1]);
            }
          else
-           {                   /* for large frames, reg 0 above contains -frame size */
+           {                   /* for large AIX/NT frames, reg 0 above contains -frame size */
+                               /* for V.4, we need to reload -frame size */
              loc = info->main_save_offset;
+             if (DEFAULT_ABI == ABI_V4 && info->total_size > 32767)
+               {
+                 int neg_size = - info->total_size;
+                 asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n",
+                              reg_names[0], (neg_size >> 16) & 0xffff,
+                              reg_names[0], reg_names[0], neg_size & 0xffff);
+               }
+
              asm_fprintf (file, "\t{sf|subf} %s,%s,%s\n", reg_names[0], reg_names[0],
                           reg_names[1]);
 
@@ -3163,6 +3250,8 @@ output_epilog (file, size)
   rs6000_stack_t *info = rs6000_stack_info ();
   char *load_reg = (TARGET_32BIT) ? "\t{l|lwz} %s,%d(%s)\n" : "\tld %s,%d(%s)\n";
   rtx insn = get_last_insn ();
+  int sp_reg = 1;
+  int sp_offset = 0;
   int i;
 
   /* Forget about any temporaries created */
@@ -3180,10 +3269,19 @@ output_epilog (file, size)
         we know what size to update it with.  */
       if (frame_pointer_needed || current_function_calls_alloca
          || info->total_size > 32767)
-       asm_fprintf (file, load_reg, reg_names[1], 0, reg_names[1]);
+       {
+         /* Under V.4, don't reset the stack pointer until after we're done
+            loading the saved registers.  */
+         if (DEFAULT_ABI == ABI_V4)
+           sp_reg = 11;
+
+         asm_fprintf (file, load_reg, reg_names[sp_reg], 0, reg_names[1]);
+       }
       else if (info->push_p)
        {
-         if (TARGET_NEW_MNEMONICS)
+         if (DEFAULT_ABI == ABI_V4)
+           sp_offset = info->total_size;
+         else if (TARGET_NEW_MNEMONICS)
            asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], info->total_size);
          else
            asm_fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], info->total_size, reg_names[1]);
@@ -3191,11 +3289,11 @@ output_epilog (file, size)
 
       /* Get the old lr if we saved it.  */
       if (info->lr_save_p)
-       asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset, reg_names[1]);
+       asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset + sp_offset, reg_names[sp_reg]);
 
       /* Get the old cr if we saved it.  */
       if (info->cr_save_p)
-       asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset, reg_names[1]);
+       asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset + sp_offset, reg_names[sp_reg]);
 
       /* Set LR here to try to overlap restores below.  */
       if (info->lr_save_p)
@@ -3205,27 +3303,27 @@ output_epilog (file, size)
       if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT)
        {
          int regno    = info->first_gp_reg_save;
-         int loc      = info->gp_save_offset;
+         int loc      = info->gp_save_offset + sp_offset;
          int reg_size = (TARGET_32BIT) ? 4 : 8;
 
          for ( ; regno < 32; regno++, loc += reg_size)
-           asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[1]);
+           asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[sp_reg]);
        }
 
       else if (info->first_gp_reg_save != 32)
        asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n",
                     reg_names[info->first_gp_reg_save],
-                    info->gp_save_offset,
-                    reg_names[1]);
+                    info->gp_save_offset + sp_offset,
+                    reg_names[sp_reg]);
 
       /* Restore fpr's if we can do it without calling a function.  */
       if (FP_SAVE_INLINE (info->first_fp_reg_save))
        {
          int regno = info->first_fp_reg_save;
-         int loc   = info->fp_save_offset;
+         int loc   = info->fp_save_offset + sp_offset;
 
          for ( ; regno < 64; regno++, loc += 8)
-           asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[1]);
+           asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]);
        }
 
       /* If we saved cr, restore it here.  Just those of cr2, cr3, and cr4
@@ -3236,6 +3334,17 @@ output_epilog (file, size)
                     + (regs_ever_live[71] != 0) * 0x10
                     + (regs_ever_live[72] != 0) * 0x8, reg_names[12]);
 
+      /* If this is V.4, unwind the stack pointer after all of the loads have been done */
+      if (sp_offset)
+       {
+         if (TARGET_NEW_MNEMONICS)
+           asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], sp_offset);
+         else
+           asm_fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], sp_offset, reg_names[1]);
+       }
+      else if (sp_reg != 1)
+       asm_fprintf (file, "\tmr %s,%s\n", reg_names[1], reg_names[sp_reg]);
+
       /* If we have to restore more than two FP registers, branch to the
         restore function.  It will return to our caller.  */
       if (info->first_fp_reg_save != 64 && !FP_SAVE_INLINE (info->first_fp_reg_save))
index 4969fc8..89b9cba 100644 (file)
 
   emit_move_insn (chain, stack_bot);
 
+  /* Under Windows NT, we need to add stack probes for large/variable allocations,
+     so do it via a call to the external function alloca, instead of doing it
+     inline.  */
+  if (DEFAULT_ABI == ABI_NT
+      && (GET_CODE (operands[0]) != CONST_INT || INTVAL (operands[0]) > 4096))
+    {
+      emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"__allocate_stack\"), 0,
+                        VOIDmode, 1,
+                        operands[0], Pmode);
+      DONE;
+    }
+
   if (GET_CODE (operands[0]) != CONST_INT
       || INTVAL (operands[0]) < -32767
       || INTVAL (operands[0]) > 32768)
index 4659346..847e6ac 100644 (file)
@@ -9,7 +9,7 @@ LIBGCC1_TEST =
 
 # These are really part of libgcc1, but this will cause them to be
 # built correctly, so... [taken from t-sparclite]
-LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c ntstack.s
 
 dp-bit.c: $(srcdir)/config/fp-bit.c
        cat $(srcdir)/config/fp-bit.c > dp-bit.c
@@ -18,10 +18,5 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
        echo '#define FLOAT' > fp-bit.c
        cat $(srcdir)/config/fp-bit.c >> fp-bit.c
 
-# Build the libraries for both hard and soft floating point
-
-MULTILIB_OPTIONS = msoft-float
-MULTILIB_DIRNAMES = soft-float
-
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
+ntstack.s: $(srcdir)/config/rs6000/ntstack.asm
+       cat $(srcdir)/config/rs6000/ntstack.asm > ntstack.s
index 0146eb6..b0c99f9 100644 (file)
@@ -36,7 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #undef CPP_PREDEFINES
 #define        CPP_PREDEFINES "-DWIN32 -D_WIN32 \
   -DWINNT -D__STDC__=0 -DALMOST_STDC \
-  -D_POWER -DPPC -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
+  -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
 
 #if 0
 #include "winnt/win-nt.h"
diff --git a/gcc/config/rs6000/x-cygwin32 b/gcc/config/rs6000/x-cygwin32
new file mode 100644 (file)
index 0000000..0a397eb
--- /dev/null
@@ -0,0 +1 @@
+USE_COLLECT2 =
diff --git a/gcc/config/rs6000/xm-cygwin32.h b/gcc/config/rs6000/xm-cygwin32.h
new file mode 100644 (file)
index 0000000..a917d07
--- /dev/null
@@ -0,0 +1,30 @@
+/* Configuration for GNU C-compiler for hosting on Windows NT.
+   using a unix style C library.
+   Copyright (C) 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+#define NO_STAB_H
+
+#include "rs6000/xm-rs6000.h"
+
+#define HAVE_STRERROR
+#define HAVE_RUSAGE
+#define HAVE_FILE_H
+
+
index 392d4fc..977b9c7 100644 (file)
@@ -95,6 +95,9 @@ dfoo ()
    message saying the start address is defaulted.  */
 extern void start() __asm__("start");
 extern void _start() __asm__("_start");
+extern void __start() __asm__("__start");
 
 void start() {}
 void _start() {}
+void __start() {}
+void mainCRTStartup() {}