From: Michael Meissner Date: Tue, 13 Feb 1996 19:19:40 +0000 (+0000) Subject: Cygwin32 support; Make eabi update stack first before doing stores in prolog X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=979721f8815d928b6290e2190ababa409fe886ab;p=gcc.git Cygwin32 support; Make eabi update stack first before doing stores in prolog From-SVN: r11259 --- diff --git a/gcc/config/rs6000/cygwin32.h b/gcc/config/rs6000/cygwin32.h index cdec7af79a7..2230848a333 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 00000000000..71a251a5999 --- /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 40c90661fad..0c0eae6c16f 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 4969fc83806..89b9cba6201 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 46593464ca1..847e6ac376a 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 0146eb6a250..b0c99f9c07f 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 00000000000..0a397ebd5bd --- /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 00000000000..a917d07d876 --- /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 392d4fc7e9c..977b9c76188 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() {}