Cygwin32 support; Make eabi update stack first before doing stores in prolog

From-SVN: r11259
This commit is contained in:
Michael Meissner 1996-02-13 19:19:40 +00:00
parent 126e5b0d25
commit 979721f881
9 changed files with 230 additions and 38 deletions

View 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

View File

@ -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

View 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))

View File

@ -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)

View 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

View 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"

View File

@ -0,0 +1 @@
USE_COLLECT2 =

View File

@ -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

View 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() {}