[BACK]Return to mach_dep.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / gc

Diff for /OpenXM_contrib2/asir2000/gc/mach_dep.c between version 1.1 and 1.7

version 1.1, 1999/12/03 07:39:09 version 1.7, 2003/06/24 05:11:33
Line 12 
Line 12 
  * modified is included with the above copyright notice.   * modified is included with the above copyright notice.
  */   */
 /* Boehm, November 17, 1995 12:13 pm PST */  /* Boehm, November 17, 1995 12:13 pm PST */
 # include "gc_priv.h"  # include "private/gc_priv.h"
 # include <stdio.h>  # include <stdio.h>
 # include <setjmp.h>  # include <setjmp.h>
 # if defined(OS2) || defined(CX_UX)  # if defined(OS2) || defined(CX_UX)
Line 21 
Line 21 
 # endif  # endif
 # ifdef AMIGA  # ifdef AMIGA
 #   ifndef __GNUC__  #   ifndef __GNUC__
 #     include <dos/dos.h>  #     include <dos.h>
 #   else  #   else
 #     include <machine/reg.h>  #     include <machine/reg.h>
 #   endif  #   endif
Line 62  asm static void PushMacRegisters()
Line 62  asm static void PushMacRegisters()
   
 #endif /* __MWERKS__ */  #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. */  /* Routine to mark from registers that are preserved by the C compiler. */
 /* This must be ported to every new architecture.  There is a generic   */  /* This must be ported to every new architecture.  There is a generic   */
 /* version at the end, that is likely, but not guaranteed to work       */  /* version at the end, that is likely, but not guaranteed to work       */
 /* on your architecture.  Run the test_setjmp program to see whether    */  /* on your architecture.  Run the test_setjmp program to see whether    */
 /* there is any chance it will work.                                    */  /* 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()  void GC_push_regs()
 {  {
 #       ifdef RT  #       ifdef RT
           register long TMP_SP; /* must be bound to r11 */            register long TMP_SP; /* must be bound to r11 */
 #       endif  #       endif
   
 #       ifdef VAX  #       ifdef VAX
           /* VAX - generic code below does not work under 4.2 */            /* VAX - generic code below does not work under 4.2 */
           /* r1 through r5 are caller save, and therefore     */            /* r1 through r5 are caller save, and therefore     */
Line 84  void GC_push_regs()
Line 92  void GC_push_regs()
           asm("pushl r8");      asm("calls $1,_GC_push_one");            asm("pushl r8");      asm("calls $1,_GC_push_one");
           asm("pushl r7");      asm("calls $1,_GC_push_one");            asm("pushl r7");      asm("calls $1,_GC_push_one");
           asm("pushl r6");      asm("calls $1,_GC_push_one");            asm("pushl r6");      asm("calls $1,_GC_push_one");
   #         define HAVE_PUSH_REGS
 #       endif  #       endif
 #       if defined(M68K) && (defined(SUNOS4) || defined(NEXT))  #       if defined(M68K) && (defined(SUNOS4) || defined(NEXT))
         /*  M68K SUNOS - could be replaced by generic code */          /*  M68K SUNOS - could be replaced by generic code */
Line 106  void GC_push_regs()
Line 115  void GC_push_regs()
           asm("movl d7,sp@");   asm("jbsr _GC_push_one");            asm("movl d7,sp@");   asm("jbsr _GC_push_one");
   
           asm("addqw #0x4,sp");         /* put stack back where it was  */            asm("addqw #0x4,sp");         /* put stack back where it was  */
   #         define HAVE_PUSH_REGS
 #       endif  #       endif
   
 #       if defined(M68K) && defined(HP)  #       if defined(M68K) && defined(HP)
Line 128  void GC_push_regs()
Line 138  void GC_push_regs()
           asm("mov.l %d7,(%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  */            asm("addq.w &0x4,%sp");       /* put stack back where it was  */
   #         define HAVE_PUSH_REGS
 #       endif /* M68K HP */  #       endif /* M68K HP */
   
 #       if defined(M68K) && defined(AMIGA)  #       if defined(M68K) && defined(AMIGA)
Line 151  void GC_push_regs()
Line 162  void GC_push_regs()
           asm("mov.l %d7,(%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  */            asm("addq.w &0x4,%sp");       /* put stack back where it was  */
   #         define HAVE_PUSH_REGS
 #        else /* !__GNUC__ */  #        else /* !__GNUC__ */
           GC_push_one(getreg(REG_A2));            GC_push_one(getreg(REG_A2));
           GC_push_one(getreg(REG_A3));            GC_push_one(getreg(REG_A3));
           GC_push_one(getreg(REG_A4));  #         ifndef __SASC
                 /* Can probably be changed to #if 0 -Kjetil M. (a4=globals)*/
               GC_push_one(getreg(REG_A4));
   #         endif
           GC_push_one(getreg(REG_A5));            GC_push_one(getreg(REG_A5));
           GC_push_one(getreg(REG_A6));            GC_push_one(getreg(REG_A6));
           /* Skip stack pointer */            /* Skip stack pointer */
Line 164  void GC_push_regs()
Line 179  void GC_push_regs()
           GC_push_one(getreg(REG_D5));            GC_push_one(getreg(REG_D5));
           GC_push_one(getreg(REG_D6));            GC_push_one(getreg(REG_D6));
           GC_push_one(getreg(REG_D7));            GC_push_one(getreg(REG_D7));
   #         define HAVE_PUSH_REGS
 #        endif /* !__GNUC__ */  #        endif /* !__GNUC__ */
 #       endif /* AMIGA */  #       endif /* AMIGA */
   
Line 186  void GC_push_regs()
Line 202  void GC_push_regs()
               PushMacReg(d7);                PushMacReg(d7);
               add.w   #4,sp                   ; fix stack.                add.w   #4,sp                   ; fix stack.
           }            }
   #         define HAVE_PUSH_REGS
 #         undef PushMacReg  #         undef PushMacReg
 #       endif /* THINK_C */  #       endif /* THINK_C */
 #       if defined(__MWERKS__)  #       if defined(__MWERKS__)
           PushMacRegisters();            PushMacRegisters();
   #         define HAVE_PUSH_REGS
 #       endif   /* __MWERKS__ */  #       endif   /* __MWERKS__ */
 #   endif       /* MACOS */  #   endif       /* MACOS */
   
 #       if defined(I386) &&!defined(OS2) &&!defined(SVR4) &&!defined(MSWIN32) \  #       if defined(I386) &&!defined(OS2) &&!defined(SVR4) \
           && (defined(__MINGW32__) || !defined(MSWIN32)) \
         && !defined(SCO) && !defined(SCO_ELF) \          && !defined(SCO) && !defined(SCO_ELF) \
         && !(defined(LINUX)       && defined(__ELF__)) \          && !(defined(LINUX) && defined(__ELF__)) \
         && !(defined(__FreeBSD__) && defined(__ELF__)) \          && !(defined(FREEBSD) && defined(__ELF__)) \
         && !defined(DOS4GW)          && !(defined(NETBSD) && defined(__ELF__)) \
           && !(defined(OPENBSD) && defined(__ELF__)) \
           && !(defined(BEOS) && defined(__ELF__)) \
           && !defined(DOS4GW) && !defined(HURD)
         /* I386 code, generic code does not appear to work */          /* I386 code, generic code does not appear to work */
         /* It does appear to work under OS2, and asms dont */          /* It does appear to work under OS2, and asms dont */
         /* This is used for some 38g UNIX variants and for CYGWIN32 */          /* This is used for some 38g UNIX variants and for CYGWIN32 */
Line 208  void GC_push_regs()
Line 230  void GC_push_regs()
           asm("pushl %esi");  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");            asm("pushl %edi");  asm("call _GC_push_one"); asm("addl $4,%esp");
           asm("pushl %ebx");  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  #       endif
   
 #       if ( defined(I386) && defined(LINUX) && defined(__ELF__) ) \  #       if ( defined(I386) && defined(LINUX) && defined(__ELF__) ) \
         || ( defined(I386) && defined(__FreeBSD__) && 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(DGUX) )
   
         /* This is modified for Linux with ELF (Note: _ELF_ only) */          /* This is modified for Linux with ELF (Note: _ELF_ only) */
         /* This section handles FreeBSD with ELF. */          /* This section handles FreeBSD with ELF. */
           asm("pushl %eax");  asm("call GC_push_one"); asm("addl $4,%esp");          /* Eax is caller-save and dead here.  Other caller-save         */
           asm("pushl %ecx");  asm("call GC_push_one"); asm("addl $4,%esp");          /* registers could also be skipped.  We assume there are no     */
           asm("pushl %edx");  asm("call GC_push_one"); asm("addl $4,%esp");          /* pointers in MMX registers, etc.                              */
           asm("pushl %ebp");  asm("call GC_push_one"); asm("addl $4,%esp");          /* We combine instructions in a single asm to prevent gcc from  */
           asm("pushl %esi");  asm("call GC_push_one"); asm("addl $4,%esp");          /* inserting code in the middle.                                */
           asm("pushl %edi");  asm("call GC_push_one"); asm("addl $4,%esp");            asm("pushl %ecx; call GC_push_one; addl $4,%esp");
           asm("pushl %ebx");  asm("call GC_push_one"); asm("addl $4,%esp");            asm("pushl %edx; call GC_push_one; addl $4,%esp");
             asm("pushl %ebp; call GC_push_one; addl $4,%esp");
             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  #       endif
   
 #       if defined(I386) && defined(MSWIN32) && !defined(USE_GENERIC)  #       if ( defined(I386) && defined(BEOS) && defined(__ELF__) )
           /* As far as I can understand from                              */
           /* http://www.beunited.org/articles/jbq/nasm.shtml,             */
           /* only ebp, esi, edi and ebx are not scratch. How MMX          */
           /* etc. registers should be treated, I have no idea.            */
             asm("pushl %ebp; call GC_push_one; addl $4,%esp");
             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__) \
              && !defined(USE_GENERIC)
         /* I386 code, Microsoft variant         */          /* I386 code, Microsoft variant         */
           __asm  push eax            __asm  push eax
           __asm  call GC_push_one            __asm  call GC_push_one
Line 247  void GC_push_regs()
Line 292  void GC_push_regs()
           __asm  push edi            __asm  push edi
           __asm  call GC_push_one            __asm  call GC_push_one
           __asm  add esp,4            __asm  add esp,4
   #         define HAVE_PUSH_REGS
 #       endif  #       endif
   
 #       if defined(I386) && (defined(SVR4) || defined(SCO) || defined(SCO_ELF))  #       if defined(I386) && (defined(SVR4) || defined(SCO) || defined(SCO_ELF))
Line 258  void GC_push_regs()
Line 304  void GC_push_regs()
           asm("pushl %ebp");  asm("call GC_push_one"); asm("addl $4,%esp");            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 %esi");  asm("call GC_push_one"); asm("addl $4,%esp");
           asm("pushl %edi");  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  #       endif
   
 #       ifdef NS32K  #       ifdef NS32K
Line 266  void GC_push_regs()
Line 313  void GC_push_regs()
           asm ("movd r5, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");            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 r6, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
           asm ("movd r7, 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  #       endif
   
 #       ifdef SPARC  #       if defined(SPARC)
           {            GC_save_regs_ret_val = GC_save_regs_in_stack();
               word GC_save_regs_in_stack();  #         define HAVE_PUSH_REGS
   
               /* generic code will not work */  
               (void)GC_save_regs_in_stack();  
           }  
 #       endif  #       endif
   
 #       ifdef RT  #       ifdef RT
Line 290  void GC_push_regs()
Line 334  void GC_push_regs()
             asm("cas r11, r13, r0"); GC_push_one(TMP_SP); /* through */              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, r14, r0"); GC_push_one(TMP_SP); /* r15 */
             asm("cas r11, r15, r0"); GC_push_one(TMP_SP);              asm("cas r11, r15, r0"); GC_push_one(TMP_SP);
   #           define HAVE_PUSH_REGS
 #       endif  #       endif
   
 #       if defined(M68K) && defined(SYSV)  #       if defined(M68K) && defined(SYSV)
Line 313  void GC_push_regs()
Line 358  void GC_push_regs()
           asm("movl %d7,%sp@"); asm("jbsr GC_push_one");            asm("movl %d7,%sp@"); asm("jbsr GC_push_one");
   
           asm("addqw #0x4,%sp");        /* put stack back where it was  */            asm("addqw #0x4,%sp");        /* put stack back where it was  */
   #         define HAVE_PUSH_REGS
 #        else /* !__GNUC__*/  #        else /* !__GNUC__*/
           asm("subq.w &0x4,%sp");       /* allocate word on top of stack */            asm("subq.w &0x4,%sp");       /* allocate word on top of stack */
   
Line 330  void GC_push_regs()
Line 376  void GC_push_regs()
           asm("mov.l %d7,(%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  */            asm("addq.w &0x4,%sp");       /* put stack back where it was  */
   #         define HAVE_PUSH_REGS
 #        endif /* !__GNUC__ */  #        endif /* !__GNUC__ */
 #       endif /* M68K/SYSV */  #       endif /* M68K/SYSV */
   
   #     if defined(PJ)
           {
               register int * sp asm ("optop");
               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... */        /* other machines... */
 #       if !(defined M68K) && !(defined VAX) && !(defined RT)  #       if !defined(HAVE_PUSH_REGS)
 #       if !(defined SPARC) && !(defined I386) && !(defined NS32K)              --> We just generated an empty GC_push_regs, which
 #       if !defined(POWERPC) && !defined(UTS4)              --> is almost certainly broken.  Try defining
             --> bad news <--              --> USE_GENERIC_PUSH_REGS instead.
 #       endif  #       endif
 #       endif  
 #       endif  
 }  }
 #endif /* !USE_GENERIC_PUSH_REGS */  #endif /* !USE_GENERIC_PUSH_REGS && !USE_ASM_PUSH_REGS */
   
 #if defined(USE_GENERIC_PUSH_REGS)  #if defined(USE_GENERIC_PUSH_REGS)
 void GC_generic_push_regs(cold_gc_frame)  void GC_generic_push_regs(cold_gc_frame)
 ptr_t 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  */  
         /* to be he acknowledged for it or not.  */  
         {          {
             static jmp_buf regs;  #           ifdef HAVE_BUILTIN_UNWIND_INIT
             register word * i = (word *) regs;                /* This was suggested by Richard Henderson as the way to  */
             register ptr_t lim = (ptr_t)(regs) + (sizeof regs);                /* 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 on Sun 3s doesn't clear all of the buffer.  */                /* Setjmp doesn't always clear all of the buffer.         */
             /* That tends to preserve garbage.  Clear it.         */                /* That tends to preserve garbage.  Clear it.             */
                 for (; (char *)i < lim; i++) {                  for (; (char *)i < lim; i++) {
                     *i = 0;                      *i = 0;
                 }                  }
 #           if defined(POWERPC) || defined(MSWIN32) || defined(UTS4)  #             if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \
                 (void) setjmp(regs);                  || defined(UTS4) || defined(LINUX) || defined(EWS4800)
 #           else                    (void) setjmp(regs);
                 (void) _setjmp(regs);  #             else
 #           endif                    (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.                                             */
                 {
                   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_push_current_stack(cold_gc_frame);
         }          }
 }  }
Line 377  ptr_t cold_gc_frame;
Line 456  ptr_t cold_gc_frame;
 /* the stack.   Return sp.                                              */  /* the stack.   Return sp.                                              */
 # ifdef SPARC  # ifdef SPARC
     asm("       .seg    \"text\"");      asm("       .seg    \"text\"");
 #   ifdef SVR4  #   if defined(SVR4) || defined(NETBSD)
       asm("     .globl  GC_save_regs_in_stack");        asm("     .globl  GC_save_regs_in_stack");
       asm("GC_save_regs_in_stack:");        asm("GC_save_regs_in_stack:");
       asm("     .type GC_save_regs_in_stack,#function");        asm("     .type GC_save_regs_in_stack,#function");
Line 385  ptr_t cold_gc_frame;
Line 464  ptr_t cold_gc_frame;
       asm("     .globl  _GC_save_regs_in_stack");        asm("     .globl  _GC_save_regs_in_stack");
       asm("_GC_save_regs_in_stack:");        asm("_GC_save_regs_in_stack:");
 #   endif  #   endif
     asm("       ta      0x3   ! ST_FLUSH_WINDOWS");  #   if defined(__arch64__) || defined(__sparcv9)
     asm("       mov     %sp,%o0");        asm("     save    %sp,-128,%sp");
     asm("       retl");        asm("     flushw");
     asm("       nop");        asm("     ret");
         asm("     restore %sp,2047+128,%o0");
   #   else
         asm("     ta      0x3   ! ST_FLUSH_WINDOWS");
         asm("     retl");
         asm("     mov     %sp,%o0");
   #   endif
 #   ifdef SVR4  #   ifdef SVR4
       asm("     .GC_save_regs_in_stack_end:");        asm("     .GC_save_regs_in_stack_end:");
       asm("     .size GC_save_regs_in_stack,.GC_save_regs_in_stack_end-GC_save_regs_in_stack");        asm("     .size GC_save_regs_in_stack,.GC_save_regs_in_stack_end-GC_save_regs_in_stack");
Line 398  ptr_t cold_gc_frame;
Line 483  ptr_t cold_gc_frame;
 #   endif  #   endif
 # 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.            */
   /* 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");
           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 /* 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
   
 /* GC_clear_stack_inner(arg, limit) clears stack area up to limit and   */  /* GC_clear_stack_inner(arg, limit) clears stack area up to limit and   */
 /* returns arg.  Stack clearing is crucial on SPARC, so we supply       */  /* returns arg.  Stack clearing is crucial on SPARC, so we supply       */
 /* an assembly version that's more careful.  Assumes limit is hotter    */  /* an assembly version that's more careful.  Assumes limit is hotter    */
 /* than sp, and limit is 8 byte aligned.                                */  /* than sp, and limit is 8 byte aligned.                                */
 #if defined(ASM_CLEAR_CODE) && !defined(THREADS)  #if defined(ASM_CLEAR_CODE)
 #ifndef SPARC  #ifndef SPARC
         --> fix it          --> fix it
 #endif  #endif
Line 415  ptr_t cold_gc_frame;
Line 546  ptr_t cold_gc_frame;
     asm("GC_clear_stack_inner:");      asm("GC_clear_stack_inner:");
     asm(".type GC_save_regs_in_stack,#function");      asm(".type GC_save_regs_in_stack,#function");
 # endif  # endif
   #if defined(__arch64__) || defined(__sparcv9)
     asm("mov %sp,%o2");           /* Save sp                      */
     asm("add %sp,2047-8,%o3");    /* p = sp+bias-8                */
     asm("add %o1,-2047-192,%sp"); /* Move sp out of the way,      */
                                   /* so that traps still work.    */
                                   /* Includes some extra words    */
                                   /* so we can be sloppy below.   */
     asm("loop:");
     asm("stx %g0,[%o3]");         /* *(long *)p = 0               */
     asm("cmp %o3,%o1");
     asm("bgu,pt %xcc, loop");     /* if (p > limit) goto loop     */
       asm("add %o3,-8,%o3");      /* p -= 8 (delay slot) */
     asm("retl");
       asm("mov %o2,%sp");         /* Restore sp., delay slot      */
   #else
   asm("mov %sp,%o2");           /* Save sp      */    asm("mov %sp,%o2");           /* Save sp      */
   asm("add %sp,-8,%o3");        /* p = sp-8     */    asm("add %sp,-8,%o3");        /* p = sp-8     */
   asm("clr %g1");               /* [g0,g1] = 0  */    asm("clr %g1");               /* [g0,g1] = 0  */
Line 429  ptr_t cold_gc_frame;
Line 575  ptr_t cold_gc_frame;
     asm("add %o3,-8,%o3");      /* p -= 8 (delay slot) */      asm("add %o3,-8,%o3");      /* p -= 8 (delay slot) */
   asm("retl");    asm("retl");
     asm("mov %o2,%sp");         /* Restore sp., delay slot      */      asm("mov %o2,%sp");         /* Restore sp., delay slot      */
   #endif /* old SPARC */
   /* First argument = %o0 = return value */    /* First argument = %o0 = return value */
 #   ifdef SVR4  #   ifdef SVR4
       asm("     .GC_clear_stack_inner_end:");        asm("     .GC_clear_stack_inner_end:");

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.7

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>