summaryrefslogtreecommitdiff
path: root/mach_dep.c
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>1999-11-01 23:15:51 +0000
committerguest <ivmai@mail.ru>2011-07-29 10:54:17 +0400
commit5eb4f4df8eae239cdba43e6794329aac5fefe484 (patch)
tree4d290f113747d19c1da5d51975f03e8d56e8de53 /mach_dep.c
parent756e3e7b1d5e6e307c6b33c3c4bfbdd4e4940419 (diff)
downloadbdwgc-5eb4f4df8eae239cdba43e6794329aac5fefe484.tar.gz
Merged GC 5.0alpha4 with local changes, plus:
* Makefile.in: Rebuilt. * Makefile.am (gctest_LDADD): Added THREADLIB. (TESTS): New macro. * configure: Rebuilt. * configure.in (INCLUDES): New subst. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30332 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'mach_dep.c')
-rw-r--r--mach_dep.c127
1 files changed, 95 insertions, 32 deletions
diff --git a/mach_dep.c b/mach_dep.c
index e39880b4..52f86346 100644
--- a/mach_dep.c
+++ b/mach_dep.c
@@ -20,7 +20,11 @@
# define _longjmp(b,v) longjmp(b,v)
# endif
# ifdef AMIGA
-# include <dos.h>
+# ifndef __GNUC__
+# include <dos/dos.h>
+# else
+# include <machine/reg.h>
+# endif
# endif
#if defined(__MWERKS__) && !defined(POWERPC)
@@ -58,12 +62,19 @@ asm static void PushMacRegisters()
#endif /* __MWERKS__ */
+# if defined(SPARC) || defined(IA64)
+ /* Value returned from register flushing routine; either sp (SPARC) */
+ /* or ar.bsp (IA64) */
+ word GC_save_regs_ret_val;
+# endif
+
/* Routine to mark from registers that are preserved by the C compiler. */
/* This must be ported to every new architecture. There is a generic */
/* version at the end, that is likely, but not guaranteed to work */
/* on your architecture. Run the test_setjmp program to see whether */
/* there is any chance it will work. */
+#ifndef USE_GENERIC_PUSH_REGS
void GC_push_regs()
{
# ifdef RT
@@ -125,9 +136,28 @@ void GC_push_regs()
asm("addq.w &0x4,%sp"); /* put stack back where it was */
# endif /* M68K HP */
-# ifdef AMIGA
- /* AMIGA - could be replaced by generic code */
- /* a0, a1, d0 and d1 are caller save */
+# if defined(M68K) && defined(AMIGA)
+ /* AMIGA - could be replaced by generic code */
+ /* a0, a1, d0 and d1 are caller save */
+
+# ifdef __GNUC__
+ asm("subq.w &0x4,%sp"); /* allocate word on top of stack */
+
+ asm("mov.l %a2,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %a3,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %a4,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %a5,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %a6,(%sp)"); asm("jsr _GC_push_one");
+ /* Skip frame pointer and stack pointer */
+ asm("mov.l %d2,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %d3,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %d4,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %d5,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %d6,(%sp)"); asm("jsr _GC_push_one");
+ asm("mov.l %d7,(%sp)"); asm("jsr _GC_push_one");
+
+ asm("addq.w &0x4,%sp"); /* put stack back where it was */
+# else /* !__GNUC__ */
GC_push_one(getreg(REG_A2));
GC_push_one(getreg(REG_A3));
GC_push_one(getreg(REG_A4));
@@ -140,7 +170,8 @@ void GC_push_regs()
GC_push_one(getreg(REG_D5));
GC_push_one(getreg(REG_D6));
GC_push_one(getreg(REG_D7));
-# endif
+# endif /* !__GNUC__ */
+# endif /* AMIGA */
# if defined(M68K) && defined(MACOS)
# if defined(THINK_C)
@@ -169,8 +200,10 @@ void GC_push_regs()
# endif /* MACOS */
# if defined(I386) &&!defined(OS2) &&!defined(SVR4) &&!defined(MSWIN32) \
- && !defined(SCO) && !defined(SCO_ELF) && !(defined(LINUX) \
- && defined(__ELF__)) && !defined(DOS4GW) && !defined(FREEBSD)
+ && !defined(SCO) && !defined(SCO_ELF) \
+ && !(defined(LINUX) && defined(__ELF__)) \
+ && !(defined(__FreeBSD__) && defined(__ELF__)) \
+ && !defined(DOS4GW)
/* I386 code, generic code does not appear to work */
/* It does appear to work under OS2, and asms dont */
/* This is used for some 38g UNIX variants and for CYGWIN32 */
@@ -183,8 +216,11 @@ void GC_push_regs()
asm("pushl %ebx"); asm("call _GC_push_one"); asm("addl $4,%esp");
# endif
-# if defined(I386) && (defined(LINUX) || defined(FREEBSD)) && defined(__ELF__)
- /* This is modified for Linux/FreeBSD with ELF (Note: _ELF_ only) */
+# if ( defined(I386) && defined(LINUX) && defined(__ELF__) ) \
+ || ( defined(I386) && defined(__FreeBSD__) && defined(__ELF__) )
+
+ /* This is modified for Linux with ELF (Note: _ELF_ only) */
+ /* This section handles FreeBSD with ELF. */
asm("pushl %eax"); asm("call GC_push_one"); asm("addl $4,%esp");
asm("pushl %ecx"); asm("call GC_push_one"); asm("addl $4,%esp");
asm("pushl %edx"); asm("call GC_push_one"); asm("addl $4,%esp");
@@ -238,12 +274,12 @@ void GC_push_regs()
asm ("movd r7, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
# endif
-# ifdef SPARC
+# if defined(SPARC) || defined(IA64)
{
word GC_save_regs_in_stack();
/* generic code will not work */
- (void)GC_save_regs_in_stack();
+ GC_save_regs_ret_val = GC_save_regs_in_stack();
}
# endif
@@ -303,8 +339,32 @@ void GC_push_regs()
# endif /* !__GNUC__ */
# endif /* M68K/SYSV */
+# if defined(PJ)
+ {
+ register int * sp asm ("optop");
+ extern int *__libc_stack_end;
-# if defined(HP_PA) || defined(M88K) || defined(POWERPC) || (defined(I386) && (defined(OS2) || defined(USE_GENERIC))) || defined(UTS4)
+ GC_push_all_stack (sp, __libc_stack_end);
+ }
+# endif
+
+ /* other machines... */
+# if !(defined M68K) && !(defined VAX) && !(defined RT)
+# if !(defined SPARC) && !(defined I386) && !(defined NS32K)
+# if !defined(POWERPC) && !defined(UTS4) && !defined(IA64)
+# if !defined(PJ)
+ --> bad news <--
+# endif
+# endif
+# endif
+# endif
+}
+#endif /* !USE_GENERIC_PUSH_REGS */
+
+#if defined(USE_GENERIC_PUSH_REGS)
+void GC_generic_push_regs(cold_gc_frame)
+ptr_t cold_gc_frame;
+{
/* Generic code */
/* The idea is due to Parag Patel at HP. */
/* We're not sure whether he would like */
@@ -324,28 +384,10 @@ void GC_push_regs()
# else
(void) _setjmp(regs);
# endif
- GC_push_all_stack((ptr_t)regs, lim);
+ GC_push_current_stack(cold_gc_frame);
}
-# endif
-# if defined(PJ)
- {
- register int * sp asm ("optop");
- extern int *__libc_stack_end;
-
- GC_push_all_stack (sp, __libc_stack_end);
- }
-# endif
- /* other machines... */
-# if !(defined M68K) && !(defined VAX) && !(defined RT)
-# if !(defined SPARC) && !(defined I386) && !(defined NS32K)
-# if !defined(HP_PA) && !defined(M88K) && !defined(POWERPC)
-# if !defined(UTS4) && !defined(PJ)
- --> bad news <--
-# endif
-# endif
-# endif
-# endif
}
+#endif /* USE_GENERIC_PUSH_REGS */
/* On register window machines, we need a way to force registers into */
/* the stack. Return sp. */
@@ -372,6 +414,27 @@ void GC_push_regs()
# endif
# endif
+/* On IA64, we also need to flush register windows. But they end */
+/* up on the other side of the stack segment. */
+/* Returns the backing store pointer for the register stack. */
+# ifdef IA64
+ asm(" .text");
+ asm(" .psr abi64");
+ asm(" .psr lsb");
+ asm(" .lsb");
+ asm("");
+ asm(" .text");
+ asm(" .align 16");
+ asm(" .global GC_save_regs_in_stack");
+ asm(" .proc GC_save_regs_in_stack");
+ asm("GC_save_regs_in_stack:");
+ asm(" .body");
+ asm(" flushrs");
+ asm(" ;;");
+ asm(" mov r8=ar.bsp");
+ asm(" br.ret.sptk.few rp");
+ asm(" .endp GC_save_regs_in_stack");
+# endif
/* GC_clear_stack_inner(arg, limit) clears stack area up to limit and */
/* returns arg. Stack clearing is crucial on SPARC, so we supply */