⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mach_dep.c

📁 A garbage collector for C and C
💻 C
📖 第 1 页 / 共 2 页
字号:
	  asm("pushl %ecx");  asm("call GC_push_one"); asm("addl $4,%esp");	  asm("pushl %edx");  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 %edi");  asm("call GC_push_one"); asm("addl $4,%esp");#	  define HAVE_PUSH_REGS#       endif#       ifdef NS32K	  asm ("movd r3, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");	  asm ("movd r4, 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 r7, tos"); asm ("bsr ?_GC_push_one"); asm ("adjspb $-4");#	  define HAVE_PUSH_REGS#       endif#       if defined(SPARC)	  GC_save_regs_ret_val = GC_save_regs_in_stack();#	  define HAVE_PUSH_REGS#       endif#	ifdef RT	    GC_push_one(TMP_SP);    /* GC_push_one from r11 */	    asm("cas r11, r6, r0"); GC_push_one(TMP_SP);	/* r6 */	    asm("cas r11, r7, r0"); GC_push_one(TMP_SP);	/* through */	    asm("cas r11, r8, r0"); GC_push_one(TMP_SP);	/* r10 */	    asm("cas r11, r9, r0"); GC_push_one(TMP_SP);	    asm("cas r11, r10, r0"); GC_push_one(TMP_SP);	    asm("cas r11, r12, r0"); GC_push_one(TMP_SP); /* r12 */	    asm("cas r11, r13, r0"); GC_push_one(TMP_SP); /* through */	    asm("cas r11, r14, r0"); GC_push_one(TMP_SP); /* r15 */	    asm("cas r11, r15, r0"); GC_push_one(TMP_SP);#	    define HAVE_PUSH_REGS#       endif#       if defined(M68K) && defined(SYSV)  	/*  Once again similar to SUN and HP, though setjmp appears to work.  		--Parag  	 */#        ifdef __GNUC__  	  asm("subqw #0x4,%sp");	/* allocate word on top of stack */    	  asm("movl %a2,%sp@");	asm("jbsr GC_push_one");  	  asm("movl %a3,%sp@");	asm("jbsr GC_push_one");  	  asm("movl %a4,%sp@");	asm("jbsr GC_push_one");  	  asm("movl %a5,%sp@");	asm("jbsr GC_push_one");  	  /* Skip frame pointer and stack pointer */  	  asm("movl %d1,%sp@");	asm("jbsr GC_push_one");  	  asm("movl %d2,%sp@");	asm("jbsr GC_push_one");  	  asm("movl %d3,%sp@");	asm("jbsr GC_push_one");  	  asm("movl %d4,%sp@");	asm("jbsr GC_push_one");  	  asm("movl %d5,%sp@");	asm("jbsr GC_push_one");  	  asm("movl %d6,%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	*/#	  define HAVE_PUSH_REGS#        else /* !__GNUC__*/  	  asm("subq.w &0x4,%sp");	/* allocate word on top of stack */    	  asm("mov.l %a2,(%sp)"); asm("jsr GC_push_one");  	  asm("mov.l %a3,(%sp)"); asm("jsr GC_push_one");  	  asm("mov.l %a4,(%sp)"); asm("jsr GC_push_one");  	  asm("mov.l %a5,(%sp)"); asm("jsr GC_push_one");  	  /* Skip frame pointer and stack pointer */  	  asm("mov.l %d1,(%sp)"); asm("jsr GC_push_one");  	  asm("mov.l %d2,(%sp)"); asm("jsr GC_push_one");  	  asm("mov.l %d3,(%sp)"); asm("jsr GC_push_one");  	  asm("mov.l %d4,(%sp)"); asm("jsr GC_push_one");  	  asm("mov.l %d5,(%sp)"); asm("jsr GC_push_one");   	  asm("mov.l %d6,(%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	*/#	  define HAVE_PUSH_REGS#        endif /* !__GNUC__ */#       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... */#       if !defined(HAVE_PUSH_REGS)	    --> We just generated an empty GC_push_regs, which	    --> is almost certainly broken.  Try defining	    --> USE_GENERIC_PUSH_REGS instead.#       endif}#endif /* !USE_GENERIC_PUSH_REGS && !USE_ASM_PUSH_REGS */#if defined(USE_GENERIC_PUSH_REGS)void GC_generic_push_regs(cold_gc_frame)ptr_t cold_gc_frame;{	{	    word dummy;#	    ifdef HAVE_BUILTIN_UNWIND_INIT	      /* This was suggested by Richard Henderson as the way to	*/	      /* force callee-save registers and register windows onto	*/	      /* the stack.						*/	      __builtin_unwind_init();#	    else /* !HAVE_BUILTIN_UNWIND_INIT */	      /* Generic code                          */	      /* The idea is due to Parag Patel at HP. */	      /* We're not sure whether he would like  */	      /* to be he acknowledged for it or not.  */	      jmp_buf regs;	      register word * i = (word *) regs;	      register ptr_t lim = (ptr_t)(regs) + (sizeof regs);	      /* Setjmp doesn't always clear all of the buffer.		*/	      /* That tends to preserve garbage.  Clear it.   		*/		for (; (char *)i < lim; i++) {		    *i = 0;		}#	      if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \                || defined(UTS4) || defined(LINUX) || defined(EWS4800)		  (void) setjmp(regs);#	      else	          (void) _setjmp(regs);		  /* We don't want to mess with signals. According to	*/		  /* SUSV3, setjmp() may or may not save signal mask.	*/		  /* _setjmp won't, but is less portable.		*/#	      endif#	    endif /* !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);	    /* Strongly discourage the compiler from treating the above	*/	    /* as a tail-call, since that would pop the register 	*/	    /* contents before we get a chance to look at them.		*/	    GC_noop1((word)(&dummy));	}}#endif /* USE_GENERIC_PUSH_REGS *//* On register window machines, we need a way to force registers into 	*//* the stack.	Return sp.						*/# ifdef SPARC    asm("	.seg 	\"text\"");#   if defined(SVR4) || defined(NETBSD) || defined(FREEBSD)      asm("	.globl	GC_save_regs_in_stack");      asm("GC_save_regs_in_stack:");      asm("	.type GC_save_regs_in_stack,#function");#   else      asm("	.globl	_GC_save_regs_in_stack");      asm("_GC_save_regs_in_stack:");#   endif#   if defined(__arch64__) || defined(__sparcv9)      asm("	save	%sp,-128,%sp");      asm("	flushw");      asm("	ret");      asm("	restore %sp,2047+128,%o0");#   else      asm("	ta	0x3   ! ST_FLUSH_WINDOWS");      asm("	retl");      asm("	mov	%sp,%o0");#   endif#   ifdef SVR4      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");#   endif#   ifdef LINT	word GC_save_regs_in_stack() { return(0 /* sp really */);}#   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	*//* returns arg.  Stack clearing is crucial on SPARC, so we supply	*//* an assembly version that's more careful.  Assumes limit is hotter	*//* than sp, and limit is 8 byte aligned.				*/#if defined(ASM_CLEAR_CODE)#ifndef SPARC	--> fix it#endif# ifdef SUNOS4    asm(".globl _GC_clear_stack_inner");    asm("_GC_clear_stack_inner:");# else    asm(".globl GC_clear_stack_inner");    asm("GC_clear_stack_inner:");    asm(".type GC_save_regs_in_stack,#function");# 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("add %sp,-8,%o3");	/* p = sp-8	*/  asm("clr %g1");		/* [g0,g1] = 0	*/  asm("add %o1,-0x60,%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("std %g0,[%o3]");		/* *(long long *)p = 0	*/  asm("cmp %o3,%o1");  asm("bgu 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	*/#endif /* old SPARC */  /* First argument = %o0 = return value */#   ifdef SVR4      asm("	.GC_clear_stack_inner_end:");      asm("	.size GC_clear_stack_inner,.GC_clear_stack_inner_end-GC_clear_stack_inner");#   endif  # ifdef LINT    /*ARGSUSED*/    ptr_t GC_clear_stack_inner(arg, limit)    ptr_t arg; word limit;    { return(arg); }# endif#endif  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -