Esempio n. 1
0
void *SafeRecurseCpp( func_sr rtn, void *arg )
/********************************************/
/* This code assumes NO parameters on the stack! */
{
    #define SAVE_SIZE   512     /* this must be smaller than the stack */

    void    *savearea;
    void    *retval;

    if( stackavail() < 0x2000 ) { /* stack getting low! */
        savearea = CMemAlloc( SAVE_SIZE );
        if( savearea != NULL ) {
            memcpy( bp(), savearea, SAVE_SIZE );
            memcpy( sp(), sp() + SAVE_SIZE, bp() - sp() );
            setbp( bp() + SAVE_SIZE );
            setsp( sp() + SAVE_SIZE );
            retval = rtn( arg );
            setsp( sp() - SAVE_SIZE );
            memcpy( sp() + SAVE_SIZE, sp(), bp() - sp() - SAVE_SIZE );
            setbp( bp() - SAVE_SIZE );
            memcpy( savearea, bp(), SAVE_SIZE );
            CMemFree( savearea );
            return( retval );
        }
    }
    return( rtn( arg ) );
}
Esempio n. 2
0
void    *SafeRecurseCG( func_sr rtn, void *arg )
/**********************************************/
/* This code assumes NO parameters on the stack! */
{
    #define SAVE_SIZE   512     /* this must be smaller than the stack */

    void                *savearea;
    void                *retval;
    mem_out_action      old_action;

    if( stackavail() < 0x2000 ) { /* stack getting low! */
        old_action = SetMemOut( MO_OK );
        savearea = CGAlloc( SAVE_SIZE );
        if( savearea == NULL ) {
            FatalError( "No memory to save stack" );
        }
        SetMemOut( old_action );
        CypCopy( bp(), savearea, SAVE_SIZE );
        CypCopy( sp(), sp() + SAVE_SIZE, bp() - sp() );
        setbp( bp() + SAVE_SIZE );
        setsp( sp() + SAVE_SIZE );
        retval = rtn( arg );
        setsp( sp() - SAVE_SIZE );
        CypCopy( sp() + SAVE_SIZE, sp(), bp() - sp() - SAVE_SIZE );
        setbp( bp() - SAVE_SIZE );
        CypCopy( savearea, bp(), SAVE_SIZE );
        CGFree( savearea );
        return( retval );
    } else {
        return( rtn( arg ) );
    }
}
Esempio n. 3
0
/*
 * Copy the new kernel to its correct location in physical memory,
 * flush caches, ignore TLBs (we're in KSEG0 space), and jump to
 * the start of the kernel.
 */
void
main(ulong aentry, ulong acode, ulong asize, ulong argc)
{
	void *kernel;
	static ulong entry, code, size;

	putc('B'); putc('o'); putc('o'); putc('t');
	/* copy args to heap before moving stack to before a.out header */
	entry = aentry;
	code = acode;
	size = asize;
	_argc = argc;		/* argc passed to kernel */
	_env = (ulong)&((char**)CONFARGV)[argc];
	setsp(entry-0x20-4);

	memmove((void *)entry, (void *)code, size);

	cleancache();
	coherence();

	/*
	 * jump to kernel entry point.
	 */
	putc(' ');
	kernel = (void*)entry;
	go(kernel);			/* off we go - never to return */

	putc('?');
	putc('!');
	for(;;)
		;
}
Esempio n. 4
0
void
gen(Node *n)
{
	Node *l;
	Prog *sp, *spc, *spb;
	Case *cn;
	long sbc, scc;
	int snbreak;
	int g, o;

loop:
	if(n == Z)
		return;
	nearln = n->lineno;
	o = n->op;
	if(debug['G'])
		if(o != OLIST)
			print("%L %O\n", nearln, o);

	retok = 0;
	switch(o) {

	default:
		complex(n);
		doinc(n, PRE);
		cgen(n, D_NONE, n);
		doinc(n, POST);
		break;

	case OLIST:
		gen(n->left);

	rloop:
		n = n->right;
		goto loop;

	case ORETURN:
		retok = 1;
		complex(n);
		if(n->type == T)
			break;
		l = n->left;
		if(l == Z) {
			noretval(3);
			gbranch(ORETURN);
			break;
		}
		doinc(l, PRE);
		if(typesuv[n->type->etype]) {
			sugen(l, D_TREE, nodret, n->type->width);
			doinc(l, POST);
			noretval(3);
			gbranch(ORETURN);
			break;
		}
		g = regalloc(n->type, regret(n->type));
		cgen(l, g, n);
		doinc(l, POST);
		if(typefd[n->type->etype])
			noretval(1);
		else
			noretval(2);
		gbranch(ORETURN);
		regfree(g);
		break;

	case OLABEL:
		l = n->left;
		if(l) {
			l->xoffset = pc;
			if(l->label)
				patch(l->label, pc);
		}
		gbranch(OGOTO);	/* prevent self reference in reg */
		patch(p, pc);
		goto rloop;

	case OGOTO:
		retok = 1;
		n = n->left;
		if(n == Z)
			return;
		if(n->complex == 0) {
			diag(Z, "label undefined: %s", n->sym->name);
			return;
		}
		gbranch(OGOTO);
		if(n->xoffset) {
			patch(p, n->xoffset);
			return;
		}
		if(n->label)
			patch(n->label, pc-1);
		n->label = p;
		return;

	case OCASE:
		l = n->left;
		if(cases == C)
			diag(n, "case/default outside a switch");
		if(l == Z) {
			casf();
			cases->val = 0;
			cases->def = 1;
			cases->label = pc;
			setsp();;
			goto rloop;
		}
		complex(l);
		if(l->type == T)
			goto rloop;
		if(l->op == OCONST)
		if(typechl[l->type->etype]) {
			casf();
			cases->val = l->vconst;
			cases->def = 0;
			cases->label = pc;
			setsp();
			goto rloop;
		}
		diag(n, "case expression must be integer constant");
		goto rloop;

	case OSWITCH:
		l = n->left;
		complex(l);
		doinc(l, PRE);
		if(l->type == T)
			break;
		if(!typechl[l->type->etype]) {
			diag(n, "switch expression must be integer");
			break;
		}
		g = regalloc(types[TLONG], D_NONE);
		n->type = types[TLONG];
		cgen(l, g, n);
		regfree(g);
		doinc(l, POST);
		setsp();
		gbranch(OGOTO);		/* entry */
		sp = p;

		cn = cases;
		cases = C;
		casf();

		sbc = breakpc;
		breakpc = pc;
		snbreak = nbreak;
		nbreak = 0;
		gbranch(OGOTO);
		spb = p;

		gen(n->right);
		gbranch(OGOTO);
		patch(p, breakpc);
		nbreak++;

		patch(sp, pc);
		doswit(g, l);

		patch(spb, pc);
		cases = cn;
		breakpc = sbc;
		nbreak = snbreak;
		setsp();
		break;

	case OWHILE:
	case ODWHILE:
		l = n->left;
		gbranch(OGOTO);		/* entry */
		sp = p;

		scc = continpc;
		continpc = pc;
		gbranch(OGOTO);
		spc = p;

		sbc = breakpc;
		breakpc = pc;
		snbreak = nbreak;
		nbreak = 0;
		gbranch(OGOTO);
		spb = p;

		patch(spc, pc);
		if(n->op == OWHILE)
			patch(sp, pc);
		bcomplex(l);	/* test */
		patch(p, breakpc);
		if(l->op != OCONST || vconst(l) == 0)
			nbreak++;

		if(n->op == ODWHILE)
			patch(sp, pc);
		gen(n->right);		/* body */
		gbranch(OGOTO);
		patch(p, continpc);

		patch(spb, pc);
		continpc = scc;
		breakpc = sbc;
		if(nbreak == 0)
			retok = 1;
		nbreak = snbreak;
		break;

	case OFOR:
		l = n->left;
		gen(l->right->left);	/* init */
		gbranch(OGOTO);			/* entry */
		sp = p;

		scc = continpc;
		continpc = pc;
		gbranch(OGOTO);
		spc = p;

		sbc = breakpc;
		breakpc = pc;
		snbreak = nbreak;
		nbreak = 0;
		gbranch(OGOTO);
		spb = p;

		patch(spc, pc);
		gen(l->right->right);	/* inc */
		patch(sp, pc);	
		if(l->left != Z) {	/* test */
			bcomplex(l->left);
			patch(p, breakpc);
			if(l->left->op != OCONST || vconst(l->left) == 0)
				nbreak++;
		}
		gen(n->right);		/* body */
		gbranch(OGOTO);
		patch(p, continpc);

		patch(spb, pc);
		continpc = scc;
		breakpc = sbc;
		if(nbreak == 0)
			retok = 1;
		nbreak = snbreak;
		break;

	case OCONTINUE:
		if(continpc < 0) {
			diag(n, "continue not in a loop");
			break;
		}
		gbranch(OGOTO);
		patch(p, continpc);
		break;

	case OBREAK:
		if(breakpc < 0) {
			diag(n, "break not in a loop");
			break;
		}
		gbranch(OGOTO);
		patch(p, breakpc);
		nbreak++;
		break;

	case OIF:
		l = n->left;
		bcomplex(l);
		sp = p;
		if(n->right->left != Z)
			gen(n->right->left);
		if(n->right->right != Z) {
			gbranch(OGOTO);
			patch(sp, pc);
			sp = p;
			gen(n->right->right);
		}
		patch(sp, pc);
		break;

	case OSET:
	case OUSED:
		usedset(n->left, o);
		break;
	}
}