home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / SYSTEM / GC / MACH_DEP.C < prev    next >
C/C++ Source or Header  |  1994-12-12  |  14KB  |  391 lines

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