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

Annotation of OpenXM_contrib2/asir2000/gc/mach_dep.c, Revision 1.1

1.1     ! noro        1: /*
        !             2:  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
        !             3:  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
        !             4:  *
        !             5:  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
        !             6:  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
        !             7:  *
        !             8:  * Permission is hereby granted to use or copy this program
        !             9:  * for any purpose,  provided the above notices are retained on all copies.
        !            10:  * Permission to modify the code and to distribute modified code is granted,
        !            11:  * provided the above notices are retained, and a notice that the code was
        !            12:  * modified is included with the above copyright notice.
        !            13:  */
        !            14: /* Boehm, November 17, 1995 12:13 pm PST */
        !            15: # include "gc_priv.h"
        !            16: # include <stdio.h>
        !            17: # include <setjmp.h>
        !            18: # if defined(OS2) || defined(CX_UX)
        !            19: #   define _setjmp(b) setjmp(b)
        !            20: #   define _longjmp(b,v) longjmp(b,v)
        !            21: # endif
        !            22: # ifdef AMIGA
        !            23: #   ifndef __GNUC__
        !            24: #     include <dos/dos.h>
        !            25: #   else
        !            26: #     include <machine/reg.h>
        !            27: #   endif
        !            28: # endif
        !            29:
        !            30: #if defined(__MWERKS__) && !defined(POWERPC)
        !            31:
        !            32: asm static void PushMacRegisters()
        !            33: {
        !            34:     sub.w   #4,sp                   // reserve space for one parameter.
        !            35:     move.l  a2,(sp)
        !            36:     jsr                GC_push_one
        !            37:     move.l  a3,(sp)
        !            38:     jsr                GC_push_one
        !            39:     move.l  a4,(sp)
        !            40:     jsr                GC_push_one
        !            41: #   if !__option(a6frames)
        !            42:        // <pcb> perhaps a6 should be pushed if stack frames are not being used.
        !            43:        move.l  a6,(sp)
        !            44:        jsr             GC_push_one
        !            45: #   endif
        !            46:        // skip a5 (globals), a6 (frame pointer), and a7 (stack pointer)
        !            47:     move.l  d2,(sp)
        !            48:     jsr                GC_push_one
        !            49:     move.l  d3,(sp)
        !            50:     jsr                GC_push_one
        !            51:     move.l  d4,(sp)
        !            52:     jsr                GC_push_one
        !            53:     move.l  d5,(sp)
        !            54:     jsr                GC_push_one
        !            55:     move.l  d6,(sp)
        !            56:     jsr                GC_push_one
        !            57:     move.l  d7,(sp)
        !            58:     jsr                GC_push_one
        !            59:     add.w   #4,sp                   // fix stack.
        !            60:     rts
        !            61: }
        !            62:
        !            63: #endif /* __MWERKS__ */
        !            64:
        !            65: /* Routine to mark from registers that are preserved by the C compiler. */
        !            66: /* This must be ported to every new architecture.  There is a generic   */
        !            67: /* version at the end, that is likely, but not guaranteed to work       */
        !            68: /* on your architecture.  Run the test_setjmp program to see whether    */
        !            69: /* there is any chance it will work.                                    */
        !            70:
        !            71: #ifndef USE_GENERIC_PUSH_REGS
        !            72: void GC_push_regs()
        !            73: {
        !            74: #       ifdef RT
        !            75:          register long TMP_SP; /* must be bound to r11 */
        !            76: #       endif
        !            77: #       ifdef VAX
        !            78:          /* VAX - generic code below does not work under 4.2 */
        !            79:          /* r1 through r5 are caller save, and therefore     */
        !            80:          /* on the stack or dead.                            */
        !            81:          asm("pushl r11");     asm("calls $1,_GC_push_one");
        !            82:          asm("pushl r10");     asm("calls $1,_GC_push_one");
        !            83:          asm("pushl r9");      asm("calls $1,_GC_push_one");
        !            84:          asm("pushl r8");      asm("calls $1,_GC_push_one");
        !            85:          asm("pushl r7");      asm("calls $1,_GC_push_one");
        !            86:          asm("pushl r6");      asm("calls $1,_GC_push_one");
        !            87: #       endif
        !            88: #       if defined(M68K) && (defined(SUNOS4) || defined(NEXT))
        !            89:        /*  M68K SUNOS - could be replaced by generic code */
        !            90:          /* a0, a1 and d1 are caller save          */
        !            91:          /*  and therefore are on stack or dead.   */
        !            92:
        !            93:          asm("subqw #0x4,sp");         /* allocate word on top of stack */
        !            94:
        !            95:          asm("movl a2,sp@");   asm("jbsr _GC_push_one");
        !            96:          asm("movl a3,sp@");   asm("jbsr _GC_push_one");
        !            97:          asm("movl a4,sp@");   asm("jbsr _GC_push_one");
        !            98:          asm("movl a5,sp@");   asm("jbsr _GC_push_one");
        !            99:          /* Skip frame pointer and stack pointer */
        !           100:          asm("movl d1,sp@");   asm("jbsr _GC_push_one");
        !           101:          asm("movl d2,sp@");   asm("jbsr _GC_push_one");
        !           102:          asm("movl d3,sp@");   asm("jbsr _GC_push_one");
        !           103:          asm("movl d4,sp@");   asm("jbsr _GC_push_one");
        !           104:          asm("movl d5,sp@");   asm("jbsr _GC_push_one");
        !           105:          asm("movl d6,sp@");   asm("jbsr _GC_push_one");
        !           106:          asm("movl d7,sp@");   asm("jbsr _GC_push_one");
        !           107:
        !           108:          asm("addqw #0x4,sp");         /* put stack back where it was  */
        !           109: #       endif
        !           110:
        !           111: #       if defined(M68K) && defined(HP)
        !           112:        /*  M68K HP - could be replaced by generic code */
        !           113:          /* a0, a1 and d1 are caller save.  */
        !           114:
        !           115:          asm("subq.w &0x4,%sp");       /* allocate word on top of stack */
        !           116:
        !           117:          asm("mov.l %a2,(%sp)"); asm("jsr _GC_push_one");
        !           118:          asm("mov.l %a3,(%sp)"); asm("jsr _GC_push_one");
        !           119:          asm("mov.l %a4,(%sp)"); asm("jsr _GC_push_one");
        !           120:          asm("mov.l %a5,(%sp)"); asm("jsr _GC_push_one");
        !           121:          /* Skip frame pointer and stack pointer */
        !           122:          asm("mov.l %d1,(%sp)"); asm("jsr _GC_push_one");
        !           123:          asm("mov.l %d2,(%sp)"); asm("jsr _GC_push_one");
        !           124:          asm("mov.l %d3,(%sp)"); asm("jsr _GC_push_one");
        !           125:          asm("mov.l %d4,(%sp)"); asm("jsr _GC_push_one");
        !           126:          asm("mov.l %d5,(%sp)"); asm("jsr _GC_push_one");
        !           127:          asm("mov.l %d6,(%sp)"); asm("jsr _GC_push_one");
        !           128:          asm("mov.l %d7,(%sp)"); asm("jsr _GC_push_one");
        !           129:
        !           130:          asm("addq.w &0x4,%sp");       /* put stack back where it was  */
        !           131: #       endif /* M68K HP */
        !           132:
        !           133: #      if defined(M68K) && defined(AMIGA)
        !           134:         /*  AMIGA - could be replaced by generic code                  */
        !           135:         /* a0, a1, d0 and d1 are caller save */
        !           136:
        !           137: #        ifdef __GNUC__
        !           138:          asm("subq.w &0x4,%sp");       /* allocate word on top of stack */
        !           139:
        !           140:          asm("mov.l %a2,(%sp)"); asm("jsr _GC_push_one");
        !           141:          asm("mov.l %a3,(%sp)"); asm("jsr _GC_push_one");
        !           142:          asm("mov.l %a4,(%sp)"); asm("jsr _GC_push_one");
        !           143:          asm("mov.l %a5,(%sp)"); asm("jsr _GC_push_one");
        !           144:          asm("mov.l %a6,(%sp)"); asm("jsr _GC_push_one");
        !           145:          /* Skip frame pointer and stack pointer */
        !           146:          asm("mov.l %d2,(%sp)"); asm("jsr _GC_push_one");
        !           147:          asm("mov.l %d3,(%sp)"); asm("jsr _GC_push_one");
        !           148:          asm("mov.l %d4,(%sp)"); asm("jsr _GC_push_one");
        !           149:          asm("mov.l %d5,(%sp)"); asm("jsr _GC_push_one");
        !           150:          asm("mov.l %d6,(%sp)"); asm("jsr _GC_push_one");
        !           151:          asm("mov.l %d7,(%sp)"); asm("jsr _GC_push_one");
        !           152:
        !           153:          asm("addq.w &0x4,%sp");       /* put stack back where it was  */
        !           154: #        else /* !__GNUC__ */
        !           155:          GC_push_one(getreg(REG_A2));
        !           156:          GC_push_one(getreg(REG_A3));
        !           157:          GC_push_one(getreg(REG_A4));
        !           158:          GC_push_one(getreg(REG_A5));
        !           159:          GC_push_one(getreg(REG_A6));
        !           160:          /* Skip stack pointer */
        !           161:          GC_push_one(getreg(REG_D2));
        !           162:          GC_push_one(getreg(REG_D3));
        !           163:          GC_push_one(getreg(REG_D4));
        !           164:          GC_push_one(getreg(REG_D5));
        !           165:          GC_push_one(getreg(REG_D6));
        !           166:          GC_push_one(getreg(REG_D7));
        !           167: #       endif /* !__GNUC__ */
        !           168: #       endif /* AMIGA */
        !           169:
        !           170: #      if defined(M68K) && defined(MACOS)
        !           171: #      if defined(THINK_C)
        !           172: #         define PushMacReg(reg) \
        !           173:               move.l  reg,(sp) \
        !           174:               jsr             GC_push_one
        !           175:          asm {
        !           176:               sub.w   #4,sp                   ; reserve space for one parameter.
        !           177:               PushMacReg(a2);
        !           178:               PushMacReg(a3);
        !           179:               PushMacReg(a4);
        !           180:               ; skip a5 (globals), a6 (frame pointer), and a7 (stack pointer)
        !           181:               PushMacReg(d2);
        !           182:               PushMacReg(d3);
        !           183:               PushMacReg(d4);
        !           184:               PushMacReg(d5);
        !           185:               PushMacReg(d6);
        !           186:               PushMacReg(d7);
        !           187:               add.w   #4,sp                   ; fix stack.
        !           188:          }
        !           189: #        undef PushMacReg
        !           190: #      endif /* THINK_C */
        !           191: #      if defined(__MWERKS__)
        !           192:          PushMacRegisters();
        !           193: #      endif   /* __MWERKS__ */
        !           194: #   endif      /* MACOS */
        !           195:
        !           196: #       if defined(I386) &&!defined(OS2) &&!defined(SVR4) &&!defined(MSWIN32) \
        !           197:        && !defined(SCO) && !defined(SCO_ELF) \
        !           198:        && !(defined(LINUX)       && defined(__ELF__)) \
        !           199:        && !(defined(__FreeBSD__) && defined(__ELF__)) \
        !           200:        && !defined(DOS4GW)
        !           201:        /* I386 code, generic code does not appear to work */
        !           202:        /* It does appear to work under OS2, and asms dont */
        !           203:        /* This is used for some 38g UNIX variants and for CYGWIN32 */
        !           204:          asm("pushl %eax");  asm("call _GC_push_one"); asm("addl $4,%esp");
        !           205:          asm("pushl %ecx");  asm("call _GC_push_one"); asm("addl $4,%esp");
        !           206:          asm("pushl %edx");  asm("call _GC_push_one"); asm("addl $4,%esp");
        !           207:          asm("pushl %ebp");  asm("call _GC_push_one"); asm("addl $4,%esp");
        !           208:          asm("pushl %esi");  asm("call _GC_push_one"); asm("addl $4,%esp");
        !           209:          asm("pushl %edi");  asm("call _GC_push_one"); asm("addl $4,%esp");
        !           210:          asm("pushl %ebx");  asm("call _GC_push_one"); asm("addl $4,%esp");
        !           211: #       endif
        !           212:
        !           213: #      if ( defined(I386) && defined(LINUX) && defined(__ELF__) ) \
        !           214:        || ( defined(I386) && defined(__FreeBSD__) && defined(__ELF__) )
        !           215:
        !           216:        /* This is modified for Linux with ELF (Note: _ELF_ only) */
        !           217:        /* This section handles FreeBSD with ELF. */
        !           218:          asm("pushl %eax");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           219:          asm("pushl %ecx");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           220:          asm("pushl %edx");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           221:          asm("pushl %ebp");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           222:          asm("pushl %esi");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           223:          asm("pushl %edi");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           224:          asm("pushl %ebx");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           225: #      endif
        !           226:
        !           227: #       if defined(I386) && defined(MSWIN32) && !defined(USE_GENERIC)
        !           228:        /* I386 code, Microsoft variant         */
        !           229:          __asm  push eax
        !           230:          __asm  call GC_push_one
        !           231:          __asm  add esp,4
        !           232:          __asm  push ebx
        !           233:          __asm  call GC_push_one
        !           234:          __asm  add esp,4
        !           235:          __asm  push ecx
        !           236:          __asm  call GC_push_one
        !           237:          __asm  add esp,4
        !           238:          __asm  push edx
        !           239:          __asm  call GC_push_one
        !           240:          __asm  add esp,4
        !           241:          __asm  push ebp
        !           242:          __asm  call GC_push_one
        !           243:          __asm  add esp,4
        !           244:          __asm  push esi
        !           245:          __asm  call GC_push_one
        !           246:          __asm  add esp,4
        !           247:          __asm  push edi
        !           248:          __asm  call GC_push_one
        !           249:          __asm  add esp,4
        !           250: #       endif
        !           251:
        !           252: #       if defined(I386) && (defined(SVR4) || defined(SCO) || defined(SCO_ELF))
        !           253:        /* I386 code, SVR4 variant, generic code does not appear to work */
        !           254:          asm("pushl %eax");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           255:          asm("pushl %ebx");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           256:          asm("pushl %ecx");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           257:          asm("pushl %edx");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           258:          asm("pushl %ebp");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           259:          asm("pushl %esi");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           260:          asm("pushl %edi");  asm("call GC_push_one"); asm("addl $4,%esp");
        !           261: #       endif
        !           262:
        !           263: #       ifdef NS32K
        !           264:          asm ("movd r3, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
        !           265:          asm ("movd r4, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
        !           266:          asm ("movd r5, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
        !           267:          asm ("movd r6, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
        !           268:          asm ("movd r7, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");
        !           269: #       endif
        !           270:
        !           271: #       ifdef SPARC
        !           272:          {
        !           273:              word GC_save_regs_in_stack();
        !           274:
        !           275:              /* generic code will not work */
        !           276:              (void)GC_save_regs_in_stack();
        !           277:          }
        !           278: #       endif
        !           279:
        !           280: #      ifdef RT
        !           281:            GC_push_one(TMP_SP);    /* GC_push_one from r11 */
        !           282:
        !           283:            asm("cas r11, r6, r0"); GC_push_one(TMP_SP);        /* r6 */
        !           284:            asm("cas r11, r7, r0"); GC_push_one(TMP_SP);        /* through */
        !           285:            asm("cas r11, r8, r0"); GC_push_one(TMP_SP);        /* r10 */
        !           286:            asm("cas r11, r9, r0"); GC_push_one(TMP_SP);
        !           287:            asm("cas r11, r10, r0"); GC_push_one(TMP_SP);
        !           288:
        !           289:            asm("cas r11, r12, r0"); GC_push_one(TMP_SP); /* r12 */
        !           290:            asm("cas r11, r13, r0"); GC_push_one(TMP_SP); /* through */
        !           291:            asm("cas r11, r14, r0"); GC_push_one(TMP_SP); /* r15 */
        !           292:            asm("cas r11, r15, r0"); GC_push_one(TMP_SP);
        !           293: #       endif
        !           294:
        !           295: #       if defined(M68K) && defined(SYSV)
        !           296:        /*  Once again similar to SUN and HP, though setjmp appears to work.
        !           297:                --Parag
        !           298:         */
        !           299: #        ifdef __GNUC__
        !           300:          asm("subqw #0x4,%sp");        /* allocate word on top of stack */
        !           301:
        !           302:          asm("movl %a2,%sp@"); asm("jbsr GC_push_one");
        !           303:          asm("movl %a3,%sp@"); asm("jbsr GC_push_one");
        !           304:          asm("movl %a4,%sp@"); asm("jbsr GC_push_one");
        !           305:          asm("movl %a5,%sp@"); asm("jbsr GC_push_one");
        !           306:          /* Skip frame pointer and stack pointer */
        !           307:          asm("movl %d1,%sp@"); asm("jbsr GC_push_one");
        !           308:          asm("movl %d2,%sp@"); asm("jbsr GC_push_one");
        !           309:          asm("movl %d3,%sp@"); asm("jbsr GC_push_one");
        !           310:          asm("movl %d4,%sp@"); asm("jbsr GC_push_one");
        !           311:          asm("movl %d5,%sp@"); asm("jbsr GC_push_one");
        !           312:          asm("movl %d6,%sp@"); asm("jbsr GC_push_one");
        !           313:          asm("movl %d7,%sp@"); asm("jbsr GC_push_one");
        !           314:
        !           315:          asm("addqw #0x4,%sp");        /* put stack back where it was  */
        !           316: #        else /* !__GNUC__*/
        !           317:          asm("subq.w &0x4,%sp");       /* allocate word on top of stack */
        !           318:
        !           319:          asm("mov.l %a2,(%sp)"); asm("jsr GC_push_one");
        !           320:          asm("mov.l %a3,(%sp)"); asm("jsr GC_push_one");
        !           321:          asm("mov.l %a4,(%sp)"); asm("jsr GC_push_one");
        !           322:          asm("mov.l %a5,(%sp)"); asm("jsr GC_push_one");
        !           323:          /* Skip frame pointer and stack pointer */
        !           324:          asm("mov.l %d1,(%sp)"); asm("jsr GC_push_one");
        !           325:          asm("mov.l %d2,(%sp)"); asm("jsr GC_push_one");
        !           326:          asm("mov.l %d3,(%sp)"); asm("jsr GC_push_one");
        !           327:          asm("mov.l %d4,(%sp)"); asm("jsr GC_push_one");
        !           328:          asm("mov.l %d5,(%sp)"); asm("jsr GC_push_one");
        !           329:          asm("mov.l %d6,(%sp)"); asm("jsr GC_push_one");
        !           330:          asm("mov.l %d7,(%sp)"); asm("jsr GC_push_one");
        !           331:
        !           332:          asm("addq.w &0x4,%sp");       /* put stack back where it was  */
        !           333: #        endif /* !__GNUC__ */
        !           334: #       endif /* M68K/SYSV */
        !           335:
        !           336:
        !           337:       /* other machines... */
        !           338: #       if !(defined M68K) && !(defined VAX) && !(defined RT)
        !           339: #      if !(defined SPARC) && !(defined I386) && !(defined NS32K)
        !           340: #      if !defined(POWERPC) && !defined(UTS4)
        !           341:            --> bad news <--
        !           342: #       endif
        !           343: #       endif
        !           344: #       endif
        !           345: }
        !           346: #endif /* !USE_GENERIC_PUSH_REGS */
        !           347:
        !           348: #if defined(USE_GENERIC_PUSH_REGS)
        !           349: void GC_generic_push_regs(cold_gc_frame)
        !           350: ptr_t cold_gc_frame;
        !           351: {
        !           352:        /* Generic code                          */
        !           353:        /* The idea is due to Parag Patel at HP. */
        !           354:        /* We're not sure whether he would like  */
        !           355:        /* to be he acknowledged for it or not.  */
        !           356:        {
        !           357:            static jmp_buf regs;
        !           358:            register word * i = (word *) regs;
        !           359:            register ptr_t lim = (ptr_t)(regs) + (sizeof regs);
        !           360:
        !           361:            /* Setjmp on Sun 3s doesn't clear all of the buffer.  */
        !           362:            /* That tends to preserve garbage.  Clear it.         */
        !           363:                for (; (char *)i < lim; i++) {
        !           364:                    *i = 0;
        !           365:                }
        !           366: #          if defined(POWERPC) || defined(MSWIN32) || defined(UTS4)
        !           367:                (void) setjmp(regs);
        !           368: #          else
        !           369:                (void) _setjmp(regs);
        !           370: #          endif
        !           371:            GC_push_current_stack(cold_gc_frame);
        !           372:        }
        !           373: }
        !           374: #endif /* USE_GENERIC_PUSH_REGS */
        !           375:
        !           376: /* On register window machines, we need a way to force registers into  */
        !           377: /* the stack.  Return sp.                                              */
        !           378: # ifdef SPARC
        !           379:     asm("      .seg    \"text\"");
        !           380: #   ifdef SVR4
        !           381:       asm("    .globl  GC_save_regs_in_stack");
        !           382:       asm("GC_save_regs_in_stack:");
        !           383:       asm("    .type GC_save_regs_in_stack,#function");
        !           384: #   else
        !           385:       asm("    .globl  _GC_save_regs_in_stack");
        !           386:       asm("_GC_save_regs_in_stack:");
        !           387: #   endif
        !           388:     asm("      ta      0x3   ! ST_FLUSH_WINDOWS");
        !           389:     asm("      mov     %sp,%o0");
        !           390:     asm("      retl");
        !           391:     asm("      nop");
        !           392: #   ifdef SVR4
        !           393:       asm("    .GC_save_regs_in_stack_end:");
        !           394:       asm("    .size GC_save_regs_in_stack,.GC_save_regs_in_stack_end-GC_save_regs_in_stack");
        !           395: #   endif
        !           396: #   ifdef LINT
        !           397:        word GC_save_regs_in_stack() { return(0 /* sp really */);}
        !           398: #   endif
        !           399: # endif
        !           400:
        !           401:
        !           402: /* GC_clear_stack_inner(arg, limit) clears stack area up to limit and  */
        !           403: /* returns arg.  Stack clearing is crucial on SPARC, so we supply      */
        !           404: /* an assembly version that's more careful.  Assumes limit is hotter   */
        !           405: /* than sp, and limit is 8 byte aligned.                               */
        !           406: #if defined(ASM_CLEAR_CODE) && !defined(THREADS)
        !           407: #ifndef SPARC
        !           408:        --> fix it
        !           409: #endif
        !           410: # ifdef SUNOS4
        !           411:     asm(".globl _GC_clear_stack_inner");
        !           412:     asm("_GC_clear_stack_inner:");
        !           413: # else
        !           414:     asm(".globl GC_clear_stack_inner");
        !           415:     asm("GC_clear_stack_inner:");
        !           416:     asm(".type GC_save_regs_in_stack,#function");
        !           417: # endif
        !           418:   asm("mov %sp,%o2");          /* Save sp      */
        !           419:   asm("add %sp,-8,%o3");       /* p = sp-8     */
        !           420:   asm("clr %g1");              /* [g0,g1] = 0  */
        !           421:   asm("add %o1,-0x60,%sp");    /* Move sp out of the way,      */
        !           422:                                /* so that traps still work.    */
        !           423:                                /* Includes some extra words    */
        !           424:                                /* so we can be sloppy below.   */
        !           425:   asm("loop:");
        !           426:   asm("std %g0,[%o3]");                /* *(long long *)p = 0  */
        !           427:   asm("cmp %o3,%o1");
        !           428:   asm("bgu loop        ");             /* if (p > limit) goto loop     */
        !           429:     asm("add %o3,-8,%o3");     /* p -= 8 (delay slot) */
        !           430:   asm("retl");
        !           431:     asm("mov %o2,%sp");                /* Restore sp., delay slot      */
        !           432:   /* First argument = %o0 = return value */
        !           433: #   ifdef SVR4
        !           434:       asm("    .GC_clear_stack_inner_end:");
        !           435:       asm("    .size GC_clear_stack_inner,.GC_clear_stack_inner_end-GC_clear_stack_inner");
        !           436: #   endif
        !           437:
        !           438: # ifdef LINT
        !           439:     /*ARGSUSED*/
        !           440:     ptr_t GC_clear_stack_inner(arg, limit)
        !           441:     ptr_t arg; word limit;
        !           442:     { return(arg); }
        !           443: # endif
        !           444: #endif

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