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

Annotation of OpenXM_contrib/gc/mach_dep.c, Revision 1.1

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

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