X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=boehm-gc%2Fmach_dep.c;h=ba1e0b6fe506d35692c0de98f1bfaa2eff9917fc;hb=72aaef024c3b41d6b99a86d710a79b99df7bc526;hp=776bf6909bc187c5af4716d30792210c56f2c2f5;hpb=8fee6c5ba203062646a84ef04770c79ba2be0a6a;p=pf3gnuchains%2Fgcc-fork.git diff --git a/boehm-gc/mach_dep.c b/boehm-gc/mach_dep.c index 776bf6909bc..ba1e0b6fe50 100644 --- a/boehm-gc/mach_dep.c +++ b/boehm-gc/mach_dep.c @@ -27,6 +27,10 @@ # endif # endif +#if defined(RS6000) || defined(POWERPC) +# include +#endif + #if defined(__MWERKS__) && !defined(POWERPC) asm static void PushMacRegisters() @@ -74,30 +78,14 @@ asm static void PushMacRegisters() /* on your architecture. Run the test_setjmp program to see whether */ /* there is any chance it will work. */ -#ifndef USE_GENERIC_PUSH_REGS +#if !defined(USE_GENERIC_PUSH_REGS) && !defined(USE_ASM_PUSH_REGS) +#undef HAVE_PUSH_REGS void GC_push_regs() { # ifdef RT register long TMP_SP; /* must be bound to r11 */ # endif -# if defined(MIPS) && defined(LINUX) - /* I'm not sure whether this has actually been tested. */ -# define call_push(x) asm("move $4," x ";"); asm("jal GC_push_one") - call_push("$2"); - call_push("$3"); - call_push("$16"); - call_push("$17"); - call_push("$18"); - call_push("$19"); - call_push("$20"); - call_push("$21"); - call_push("$22"); - call_push("$23"); - call_push("$30"); -# undef call_push -# endif /* MIPS && LINUX */ - # ifdef VAX /* VAX - generic code below does not work under 4.2 */ /* r1 through r5 are caller save, and therefore */ @@ -108,6 +96,7 @@ void GC_push_regs() asm("pushl r8"); asm("calls $1,_GC_push_one"); asm("pushl r7"); asm("calls $1,_GC_push_one"); asm("pushl r6"); asm("calls $1,_GC_push_one"); +# define HAVE_PUSH_REGS # endif # if defined(M68K) && (defined(SUNOS4) || defined(NEXT)) /* M68K SUNOS - could be replaced by generic code */ @@ -130,6 +119,7 @@ void GC_push_regs() asm("movl d7,sp@"); asm("jbsr _GC_push_one"); asm("addqw #0x4,sp"); /* put stack back where it was */ +# define HAVE_PUSH_REGS # endif # if defined(M68K) && defined(HP) @@ -152,6 +142,7 @@ void GC_push_regs() asm("mov.l %d7,(%sp)"); asm("jsr _GC_push_one"); asm("addq.w &0x4,%sp"); /* put stack back where it was */ +# define HAVE_PUSH_REGS # endif /* M68K HP */ # if defined(M68K) && defined(AMIGA) @@ -175,6 +166,7 @@ void GC_push_regs() asm("mov.l %d7,(%sp)"); asm("jsr _GC_push_one"); asm("addq.w &0x4,%sp"); /* put stack back where it was */ +# define HAVE_PUSH_REGS # else /* !__GNUC__ */ GC_push_one(getreg(REG_A2)); GC_push_one(getreg(REG_A3)); @@ -191,6 +183,7 @@ void GC_push_regs() GC_push_one(getreg(REG_D5)); GC_push_one(getreg(REG_D6)); GC_push_one(getreg(REG_D7)); +# define HAVE_PUSH_REGS # endif /* !__GNUC__ */ # endif /* AMIGA */ @@ -213,10 +206,12 @@ void GC_push_regs() PushMacReg(d7); add.w #4,sp ; fix stack. } +# define HAVE_PUSH_REGS # undef PushMacReg # endif /* THINK_C */ # if defined(__MWERKS__) PushMacRegisters(); +# define HAVE_PUSH_REGS # endif /* __MWERKS__ */ # endif /* MACOS */ @@ -239,13 +234,15 @@ void GC_push_regs() asm("pushl %esi"); asm("call _GC_push_one"); asm("addl $4,%esp"); asm("pushl %edi"); asm("call _GC_push_one"); asm("addl $4,%esp"); asm("pushl %ebx"); asm("call _GC_push_one"); asm("addl $4,%esp"); +# define HAVE_PUSH_REGS # endif # if ( defined(I386) && defined(LINUX) && defined(__ELF__) ) \ || ( defined(I386) && defined(FREEBSD) && defined(__ELF__) ) \ || ( defined(I386) && defined(NETBSD) && defined(__ELF__) ) \ || ( defined(I386) && defined(OPENBSD) && defined(__ELF__) ) \ - || ( defined(I386) && defined(HURD) && defined(__ELF__) ) + || ( defined(I386) && defined(HURD) && defined(__ELF__) ) \ + || ( defined(I386) && defined(DGUX) ) /* This is modified for Linux with ELF (Note: _ELF_ only) */ /* This section handles FreeBSD with ELF. */ @@ -260,6 +257,7 @@ void GC_push_regs() asm("pushl %esi; call GC_push_one; addl $4,%esp"); asm("pushl %edi; call GC_push_one; addl $4,%esp"); asm("pushl %ebx; call GC_push_one; addl $4,%esp"); +# define HAVE_PUSH_REGS # endif # if ( defined(I386) && defined(BEOS) && defined(__ELF__) ) @@ -271,6 +269,7 @@ void GC_push_regs() asm("pushl %esi; call GC_push_one; addl $4,%esp"); asm("pushl %edi; call GC_push_one; addl $4,%esp"); asm("pushl %ebx; call GC_push_one; addl $4,%esp"); +# define HAVE_PUSH_REGS # endif # if defined(I386) && defined(MSWIN32) && !defined(__MINGW32__) \ @@ -297,6 +296,7 @@ void GC_push_regs() __asm push edi __asm call GC_push_one __asm add esp,4 +# define HAVE_PUSH_REGS # endif # if defined(I386) && (defined(SVR4) || defined(SCO) || defined(SCO_ELF)) @@ -308,6 +308,7 @@ void GC_push_regs() asm("pushl %ebp"); asm("call GC_push_one"); asm("addl $4,%esp"); asm("pushl %esi"); asm("call GC_push_one"); asm("addl $4,%esp"); asm("pushl %edi"); asm("call GC_push_one"); asm("addl $4,%esp"); +# define HAVE_PUSH_REGS # endif # ifdef NS32K @@ -316,14 +317,12 @@ void GC_push_regs() asm ("movd r5, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4"); asm ("movd r6, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4"); asm ("movd r7, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4"); +# define HAVE_PUSH_REGS # endif # if defined(SPARC) - { - word GC_save_regs_in_stack(); - - GC_save_regs_ret_val = GC_save_regs_in_stack(); - } + GC_save_regs_ret_val = GC_save_regs_in_stack(); +# define HAVE_PUSH_REGS # endif # ifdef RT @@ -339,6 +338,7 @@ void GC_push_regs() asm("cas r11, r13, r0"); GC_push_one(TMP_SP); /* through */ asm("cas r11, r14, r0"); GC_push_one(TMP_SP); /* r15 */ asm("cas r11, r15, r0"); GC_push_one(TMP_SP); +# define HAVE_PUSH_REGS # endif # if defined(M68K) && defined(SYSV) @@ -362,6 +362,7 @@ void GC_push_regs() asm("movl %d7,%sp@"); asm("jbsr GC_push_one"); asm("addqw #0x4,%sp"); /* put stack back where it was */ +# define HAVE_PUSH_REGS # else /* !__GNUC__*/ asm("subq.w &0x4,%sp"); /* allocate word on top of stack */ @@ -379,6 +380,7 @@ void GC_push_regs() asm("mov.l %d7,(%sp)"); asm("jsr GC_push_one"); asm("addq.w &0x4,%sp"); /* put stack back where it was */ +# define HAVE_PUSH_REGS # endif /* !__GNUC__ */ # endif /* M68K/SYSV */ @@ -388,73 +390,101 @@ void GC_push_regs() extern int *__libc_stack_end; GC_push_all_stack (sp, __libc_stack_end); +# define HAVE_PUSH_REGS + /* Isn't this redundant with the code to push the stack? */ } # endif /* other machines... */ -# if !defined(M68K) && !defined(VAX) && !defined(RT) -# if !defined(SPARC) && !defined(I386) && !defined(NS32K) -# if !defined(POWERPC) && !defined(UTS4) -# if !defined(PJ) && !(defined(MIPS) && defined(LINUX)) - --> bad news <-- -# endif -# endif +# if !defined(HAVE_PUSH_REGS) + --> We just generated an empty GC_push_regs, which + --> is almost certainly broken. Try defining + --> USE_GENERIC_PUSH_REGS instead. # endif +} +#endif /* !USE_GENERIC_PUSH_REGS && !USE_ASM_PUSH_REGS */ + +void GC_with_callee_saves_pushed(fn, arg) +void (*fn)(); +ptr_t arg; +{ + word dummy; + +# if defined(USE_GENERIC_PUSH_REGS) +# ifdef HAVE_BUILTIN_UNWIND_INIT + /* This was suggested by Richard Henderson as the way to */ + /* force callee-save registers and register windows onto */ + /* the stack. */ + __builtin_unwind_init(); +# else /* !HAVE_BUILTIN_UNWIND_INIT */ +# if defined(RS6000) || defined(POWERPC) + /* FIXME: RS6000 means AIX. */ + /* This should probably be used in all Posix/non-gcc */ + /* settings. We defer that change to minimize risk. */ + ucontext_t ctxt; + getcontext(&ctxt); +# else + /* Generic code */ + /* The idea is due to Parag Patel at HP. */ + /* We're not sure whether he would like */ + /* to be he acknowledged for it or not. */ + jmp_buf regs; + register word * i = (word *) regs; + register ptr_t lim = (ptr_t)(regs) + (sizeof regs); + + /* Setjmp doesn't always clear all of the buffer. */ + /* That tends to preserve garbage. Clear it. */ + for (; (char *)i < lim; i++) { + *i = 0; + } +# if defined(MSWIN32) || defined(MSWINCE) \ + || defined(UTS4) || defined(LINUX) || defined(EWS4800) + (void) setjmp(regs); +# else + (void) _setjmp(regs); + /* We don't want to mess with signals. According to */ + /* SUSV3, setjmp() may or may not save signal mask. */ + /* _setjmp won't, but is less portable. */ # endif +# endif /* !AIX ... */ +# endif /* !HAVE_BUILTIN_UNWIND_INIT */ +# else +# if defined(PTHREADS) && !defined(MSWIN32) /* !USE_GENERIC_PUSH_REGS */ + /* We may still need this to save thread contexts. */ + ucontext_t ctxt; + getcontext(&ctxt); +# else /* Shouldn't be needed */ + ABORT("Unexpected call to GC_with_callee_saves_pushed"); +# endif +# endif +# if (defined(SPARC) && !defined(HAVE_BUILTIN_UNWIND_INIT)) \ + || defined(IA64) + /* On a register window machine, we need to save register */ + /* contents on the stack for this to work. The setjmp */ + /* is probably not needed on SPARC, since pointers are */ + /* only stored in windowed or scratch registers. It is */ + /* needed on IA64, since some non-windowed registers are */ + /* preserved. */ + { + GC_save_regs_ret_val = GC_save_regs_in_stack(); + /* On IA64 gcc, could use __builtin_ia64_flushrs() and */ + /* __builtin_ia64_flushrs(). The latter will be done */ + /* implicitly by __builtin_unwind_init() for gcc3.0.1 */ + /* and later. */ + } +# endif + fn(arg); + /* Strongly discourage the compiler from treating the above */ + /* as a tail-call, since that would pop the register */ + /* contents before we get a chance to look at them. */ + GC_noop1((word)(&dummy)); } -#endif /* !USE_GENERIC_PUSH_REGS */ #if defined(USE_GENERIC_PUSH_REGS) void GC_generic_push_regs(cold_gc_frame) ptr_t cold_gc_frame; { - { -# ifdef HAVE_BUILTIN_UNWIND_INIT - /* This was suggested by Richard Henderson as the way to */ - /* force callee-save registers and register windows onto */ - /* the stack. */ - __builtin_unwind_init(); -# else /* !HAVE_BUILTIN_UNWIND_INIT */ - /* Generic code */ - /* The idea is due to Parag Patel at HP. */ - /* We're not sure whether he would like */ - /* to be he acknowledged for it or not. */ - jmp_buf regs; - register word * i = (word *) regs; - register ptr_t lim = (ptr_t)(regs) + (sizeof regs); - - /* Setjmp doesn't always clear all of the buffer. */ - /* That tends to preserve garbage. Clear it. */ - for (; (char *)i < lim; i++) { - *i = 0; - } -# if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \ - || defined(UTS4) || defined(LINUX) - (void) setjmp(regs); -# else - (void) _setjmp(regs); -# endif -# endif /* !HAVE_BUILTIN_UNWIND_INIT */ -# if (defined(SPARC) && !defined(HAVE_BUILTIN_UNWIND_INIT)) \ - || defined(IA64) - /* On a register window machine, we need to save register */ - /* contents on the stack for this to work. The setjmp */ - /* is probably not needed on SPARC, since pointers are */ - /* only stored in windowed or scratch registers. It is */ - /* needed on IA64, since some non-windowed registers are */ - /* preserved. */ - { - word GC_save_regs_in_stack(); - - GC_save_regs_ret_val = GC_save_regs_in_stack(); - /* On IA64 gcc, could use __builtin_ia64_flushrs() and */ - /* __builtin_ia64_flushrs(). The latter will be done */ - /* implicitly by __builtin_unwind_init() for gcc3.0.1 */ - /* and later. */ - } -# endif - GC_push_current_stack(cold_gc_frame); - } + GC_with_callee_saves_pushed(GC_push_current_stack, cold_gc_frame); } #endif /* USE_GENERIC_PUSH_REGS */ @@ -462,7 +492,7 @@ ptr_t cold_gc_frame; /* the stack. Return sp. */ # ifdef SPARC asm(" .seg \"text\""); -# ifdef SVR4 +# if defined(SVR4) || defined(NETBSD) || defined(FREEBSD) asm(" .globl GC_save_regs_in_stack"); asm("GC_save_regs_in_stack:"); asm(" .type GC_save_regs_in_stack,#function"); @@ -492,8 +522,11 @@ ptr_t cold_gc_frame; /* 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 -# ifdef __GNUC__ +/* We now implement this as a separate assembly file, since inline */ +/* assembly code here doesn't work with either the Intel or HP */ +/* compilers. */ +# if 0 +# ifdef LINUX asm(" .text"); asm(" .psr abi64"); asm(" .psr lsb"); @@ -510,12 +543,25 @@ ptr_t cold_gc_frame; asm(" mov r8=ar.bsp"); asm(" br.ret.sptk.few rp"); asm(" .endp GC_save_regs_in_stack"); -# else - void GC_save_regs_in_stack() { - asm(" flushrs"); - asm(" ;;"); - asm(" mov r8=ar.bsp"); - asm(" br.ret.sptk.few rp"); +# endif /* LINUX */ +# if 0 /* Other alternatives that don't work on HP/UX */ + word GC_save_regs_in_stack() { +# if USE_BUILTINS + __builtin_ia64_flushrs(); + return __builtin_ia64_bsp(); +# else +# ifdef HPUX + _asm(" flushrs"); + _asm(" ;;"); + _asm(" mov r8=ar.bsp"); + _asm(" br.ret.sptk.few rp"); +# else + asm(" flushrs"); + asm(" ;;"); + asm(" mov r8=ar.bsp"); + asm(" br.ret.sptk.few rp"); +# endif +# endif } # endif # endif