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 ) ); }
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 ) ); } }
/* * 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(;;) ; }
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; } }