aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <meissner@gcc.gnu.org>1996-02-13 19:19:40 +0000
committerMichael Meissner <meissner@gcc.gnu.org>1996-02-13 19:19:40 +0000
commit979721f8815d928b6290e2190ababa409fe886ab (patch)
treee50b22d985c9826b2e7f690463524030216c1427 /gcc
parent126e5b0d250c6955ae27a0f8c65e1f0e254215df (diff)
downloadgcc-979721f8815d928b6290e2190ababa409fe886ab.zip
gcc-979721f8815d928b6290e2190ababa409fe886ab.tar.gz
gcc-979721f8815d928b6290e2190ababa409fe886ab.tar.bz2
Cygwin32 support; Make eabi update stack first before doing stores in prolog
From-SVN: r11259
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/rs6000/cygwin32.h10
-rw-r--r--gcc/config/rs6000/ntstack.asm42
-rw-r--r--gcc/config/rs6000/rs6000.c157
-rw-r--r--gcc/config/rs6000/rs6000.md12
-rw-r--r--gcc/config/rs6000/t-winnt11
-rw-r--r--gcc/config/rs6000/win-nt.h2
-rw-r--r--gcc/config/rs6000/x-cygwin321
-rw-r--r--gcc/config/rs6000/xm-cygwin32.h30
-rw-r--r--gcc/libgcc1-test.c3
9 files changed, 230 insertions, 38 deletions
diff --git a/gcc/config/rs6000/cygwin32.h b/gcc/config/rs6000/cygwin32.h
index cdec7af..2230848 100644
--- a/gcc/config/rs6000/cygwin32.h
+++ b/gcc/config/rs6000/cygwin32.h
@@ -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
index 0000000..71a251a
--- /dev/null
+++ b/gcc/config/rs6000/ntstack.asm
@@ -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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 40c9066..0c0eae6 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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))
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4969fc83..89b9cba 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -6327,6 +6327,18 @@
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)
diff --git a/gcc/config/rs6000/t-winnt b/gcc/config/rs6000/t-winnt
index 4659346..847e6ac 100644
--- a/gcc/config/rs6000/t-winnt
+++ b/gcc/config/rs6000/t-winnt
@@ -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
diff --git a/gcc/config/rs6000/win-nt.h b/gcc/config/rs6000/win-nt.h
index 0146eb6..b0c99f9 100644
--- a/gcc/config/rs6000/win-nt.h
+++ b/gcc/config/rs6000/win-nt.h
@@ -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
index 0000000..0a397eb
--- /dev/null
+++ b/gcc/config/rs6000/x-cygwin32
@@ -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
index 0000000..a917d07
--- /dev/null
+++ b/gcc/config/rs6000/xm-cygwin32.h
@@ -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
+
+
diff --git a/gcc/libgcc1-test.c b/gcc/libgcc1-test.c
index 392d4fc..977b9c7 100644
--- a/gcc/libgcc1-test.c
+++ b/gcc/libgcc1-test.c
@@ -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() {}