📄 gstmt68.c
字号:
}
if (flag &1)
{
if (retlab != - 1)
gen_label(retlab);
if (flag &2)
return ap;
if (currentfunc->value.classdata.eofdest)
{
if (returndreg)
{
if (currentfunc->tp->btp->type == bt_longlong || currentfunc
->tp->btp->type == bt_unsignedlonglong)
gen_codes(op_move, BESZ_DWORD, makedreg(1), push);
gen_codes(op_move, BESZ_DWORD, makedreg(0), push);
}
gen_expr(currentfunc->value.classdata.eofdest, TRUE, FALSE, 0);
if (returndreg)
{
gen_codes(op_move, BESZ_DWORD, pop, makedreg(0));
if (currentfunc->tp->btp->type == bt_longlong || currentfunc
->tp->btp->type == bt_unsignedlonglong)
gen_codes(op_move, BESZ_DWORD, pop, makedreg(1));
}
}
if ((conscount || try_block_list || currentfunc
->value.classdata.throwlist && currentfunc
->value.classdata.throwlist->data) && prm_xcept)
call_library2("__RundownExceptBlock", 0);
if ((!prm_linkreg || currentfunc->intflag) && (lc_maxauto))
if (lc_maxauto > 8)
{
AMODE *ap = xalloc(sizeof(AMODE));
ap->mode = am_indx;
ap->offset = makeintnode(en_icon, lc_maxauto);
ap->preg = 7;
gen_codes(op_lea, 0, ap, makeareg(7));
}
else
gen_codes(op_add, BESZ_DWORD, make_immed(lc_maxauto), makeareg(7));
if (fsave_mask != 0)
gen_codes(op_fmovem, BESZ_LDOUBLE, pop, make_mask(fsave_mask, 1));
if (save_mask != 0)
if (prm_coldfire)
if (rmaskcnt > 1)
{
gen_codes(op_movem, BESZ_DWORD, mvma7, make_mask(save_mask, 0));
mvn1 = xalloc(sizeof(struct enode));
mvn1->nodetype = en_icon;
mvn1->v.i = (rmaskcnt << 2);
ap3 = xalloc(sizeof(struct amode));
ap3->mode = am_indx;
ap3->preg = 7;
ap3->offset = mvn1;
gen_codes(op_lea, BESZ_DWORD, ap3, mvma7i);
freeop(ap3);
}
else
gen_codes(op_move, BESZ_DWORD, pop, make_mask(save_mask, 0));
else
gen_codes(op_movem, BESZ_DWORD, pop, make_mask(save_mask, 0));
if (prm_cplusplus && prm_xcept || prm_linkreg && !currentfunc->intflag
&& (currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM*)
- 1 || lc_maxauto) || !prm_smartframes || (currentfunc
->value.classdata.cppflags &PF_MEMBER) && !(currentfunc
->value.classdata.cppflags &PF_STATIC))
{
gen_codes(op_unlk, 0, makeareg(linkreg), 0);
} if (currentfunc->intflag)
gen_codes(op_rte, 0, 0, 0);
else
if (currentfunc->pascaldefn || currentfunc->isstdcall)
{
long retsize = 0;
if (currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM*)
- 1)
{
retsize = currentfunc->paramsize;
if (prm_linkreg)
retsize -= 8;
}
if (currentfunc->tp->btp && isstructured(currentfunc->tp->btp))
retsize += 4;
if (retsize)
{
if (prm_68020 || prm_68010)
gen_codes(op_rtd, 0, make_immed(retsize), 0);
else
{
ap = temp_addr();
freeop(ap);
gen_codes(op_move, BESZ_DWORD, pop, ap);
if (retsize > 8)
{
ap1 = xalloc(sizeof(AMODE));
ap1->mode = am_indx;
ap1->offset = makeintnode(en_icon, retsize);
ap1->preg = 7;
gen_codes(op_lea, 0, ap1, makeareg(7));
}
else
gen_codes(op_add, BESZ_DWORD, make_immed(retsize), makeareg(7));
ap->mode = am_ind;
gen_codes(op_jmp, 0, ap, 0);
}
return ;
}
}
gen_codes(op_rts, 0, 0, 0);
}
else
{
if (retlab == - 1)
retlab = nextlabel++;
gen_codes(op_bra, 0, make_label(retlab), 0);
}
}
//-------------------------------------------------------------------------
void gen_tryblock(void *val)
{
AMODE *ap1 = xalloc(sizeof(AMODE));
ap1->mode = am_indx;
ap1->preg = linkreg;
ap1->offset = makeintnode(en_icon, - xceptoffs + 12); // ESP in XCEPTDATA
// this is a little buggy, it doesn't push FP regs
switch ((int)val)
{
case 0:
// start of try block
gen_move(BESZ_DWORD, makedreg(3), push);
gen_move(BESZ_DWORD, makedreg(4), push);
gen_move(BESZ_DWORD, makedreg(5), push);
gen_move(BESZ_DWORD, makedreg(6), push);
gen_move(BESZ_DWORD, makedreg(7), push);
gen_move(BESZ_DWORD, ap1, push);
gen_move(BESZ_DWORD, makeareg(7), ap1);
break;
case 1:
//start of catch block
gen_move(BESZ_DWORD, ap1, makeareg(7));
gen_move(BESZ_DWORD, pop, ap1);
gen_move(BESZ_DWORD, pop, makedreg(7));
gen_move(BESZ_DWORD, pop, makedreg(6));
gen_move(BESZ_DWORD, pop, makedreg(5));
gen_move(BESZ_DWORD, pop, makedreg(4));
gen_move(BESZ_DWORD, pop, makedreg(3));
break;
case 2:
//end of try block
gen_move(BESZ_DWORD, ap1, makeareg(7));
gen_move(BESZ_DWORD, pop, ap1);
gen_codes(op_add, BESZ_DWORD, make_immed(4 *5), makedreg(7));
break;
}
}
//-------------------------------------------------------------------------
void genstmt(SNODE *stmt)
/*
* genstmt will generate a statement and follow the next pointer
* until the block is generated.
*/
{
while (stmt != 0)
{
switch (stmt->stype)
{
case st_case:
if ((int)stmt->label >= 0)
gen_label((int)stmt->label);
break;
case st_block:
genstmt(stmt->exp);
break;
case st_label:
gen_label((int)stmt->label);
break;
case st_goto:
gen_codes(op_bra, 0, make_label((int)stmt->label), 0);
break;
case st_tryblock:
initstack(); // important!!!
gen_tryblock(stmt->label);
break;
case st_expr:
gen_void(stmt->exp);
initstack();
break;
case st_return:
genreturn(stmt, 0);
break;
case st_if:
genif(stmt);
break;
case st_while:
genwhile(stmt);
break;
case st_do:
gendo(stmt);
break;
case st_for:
gen_for(stmt);
break;
case st_line:
gen_line(stmt);
break;
case st_continue:
gen_codes(op_bra, 0, make_label(contlab), 0);
break;
case st_break:
gen_codes(op_bra, 0, make_label(breaklab), 0);
break;
case st_switch:
genxswitch(stmt);
break;
case st__genword:
gen_genword(stmt);
break;
case st_asm:
if (stmt->exp)
add_peep(stmt->exp);
break;
default:
DIAG("unknown statement.");
break;
}
stmt = stmt->next;
}
}
//-------------------------------------------------------------------------
void scppinit(void)
/*
* Call C++ reference variable and class initializers
*/
{
#ifdef XXXXX
if (!strcmp(currentfunc->name, "_main"))
{
AMODE *ap1, *ap2, *ap3, *ap4;
int lbl = nextlabel++;
initstack();
ap1 = temp_addr();
ap4 = xalloc(sizeof(AMODE));
ap4->preg = ap1->preg;
ap4->mode = am_ind;
ap2 = set_symbol("CPPSTART", 0);
ap3 = set_symbol("CPPEND", 0);
gen_codes(op_lea, BESZ_DWORD, ap2, ap1);
gen_label(lbl);
gen_codes(op_move, BESZ_DWORD, ap1, push);
gen_codes(op_jsr, BESZ_DWORD, ap4, 0);
gen_codes(op_move, BESZ_DWORD, pop, ap1);
gen_codes(op_add, BESZ_DWORD, make_immed(4), ap1);
gen_codes(op_cmp, BESZ_DWORD, ap3, ap1);
gen_codes(op_bhi, 0, make_label(lbl), 0);
freeop(ap1);
}
#endif
}
SYM *gen_mp_virtual_thunk(SYM *vsp)
{
LIST *v = mpthunklist;
SYM *sp;
AMODE *ap1, *ap2;
char buf[256];
while (v)
{
sp = (SYM*)v->data;
if (sp->value.i == vsp->value.classdata.vtabindex)
if (isstructured(vsp->tp->btp) == isstructured(sp->tp->btp))
return sp;
v = v->link;
}
global_flag++;
sp = makesym(sc_static);
sp->tp = vsp->tp;
sp->value.i = vsp->value.classdata.vtabindex;
sprintf(buf, "@$mpt$%d$%d", sp->value.i, isstructured(sp->tp->btp));
sp->name = litlate(buf);
sp->staticlabel = FALSE;
v = xalloc(sizeof(LIST));
v->data = sp;
v->link = mpthunklist;
mpthunklist = v;
global_flag--;
// gen_codelab(sp) ;
gen_virtual(sp, FALSE);
ap1 = makedreg(7);
ap1->mode = am_indx;
ap1->offset = makeintnode(en_icon, isstructured(sp->tp->btp) ? 8 : 4);
gen_codes(op_move, BESZ_DWORD, ap1, makedreg(0));
ap1->preg = 0;
ap1->mode = am_indx;
if (sp->value.classdata.vtaboffs)
ap1->offset = makeintnode(en_icon, sp->value.classdata.vtaboffs);
else
ap1->offset = makeintnode(en_icon, 0);
gen_codes(op_move, BESZ_DWORD, ap1, makedreg(0));
ap1->mode = am_ind;
gen_codes(op_move, BESZ_DWORD, ap1, makedreg(0));
ap1->offset = makeintnode(en_icon, sp->value.i);
ap1->mode = am_indx;
gen_codes(op_jmp, BESZ_DWORD, ap1, 0);
flush_peep();
gen_endvirtual(sp);
return sp;
}
SYM *gen_vsn_virtual_thunk(SYM *func, int ofs)
{
SYM *sp;
AMODE *ap1, *ap2;
char buf[256];
global_flag++;
sp = makesym(sc_static);
sp->value.i = ofs;
sprintf(buf, "@$vsn%s$%d", func->name, sp->value.i);
sp->name = litlate(buf);
sp->staticlabel = FALSE;
sp->tp = func->mainsym; // strange use of the TP field here
global_flag--;
gen_virtual(sp, FALSE);
ap1 = makedreg(7);
ap1->mode = am_indx;
ap1->offset = makeintnode(en_icon, 4);
gen_codes(op_add, BESZ_DWORD, make_immed( - ofs), ap1);
ap2 = xalloc(sizeof(AMODE));
ap2->offset = makenode(en_napccon, (void*)func, 0);
ap2->mode = am_immed;
gen_codes(op_bra, BESZ_DWORD, ap2, 0);
flush_peep();
gen_endvirtual(sp);
return sp;
}
void genfunc(SNODE *stmt)
/*
* generate a function body.
*/
{
//int isconst = FALSE;
cseg();
currentfunc->gennedvirtfunc = (virtualfuncs || (currentfunc
->value.classdata.cppflags &(PF_HEADERFUNC | PF_INSTANTIATED)));
if (currentfunc->storage_class == sc_global && !(currentfunc
->value.classdata.cppflags &PF_INLINE))
if (!currentfunc->gennedvirtfunc)
globaldef(currentfunc);
returndreg = FALSE;
retsize = 0;
stackdepth = 0;
contlab = breaklab = - 1;
retlab = nextlabel++;
funcfloat = 0;
if (funcstmt)
gen_line(funcstmt);
funcstmt = 0;
#ifdef XXXXX
if (stmt->stype == st_line)
{
gen_line(stmt);
stmt = stmt->next;
}
if (!stmt)
{
if (currentfunc->gennedvirtfunc)
gen_virtual(currentfunc, FALSE);
else
gen_codelab(currentfunc);
gen_codes(op_rts, 0, 0, 0);
flush_peep();
if (currentfunc->gennedvirtfunc)
gen_endvirtual(currentfunc);
return ;
}
#endif
#ifdef XXXXX
if (currentfunc->value.classdata.cppflags &PF_CONSTRUCTOR)
{
isconst = TRUE;
}
#endif
if (currentfunc->gennedvirtfunc)
gen_virtual(currentfunc, FALSE);
else
gen_codelab(currentfunc);
/* name of function */
opt1(stmt); /* push args & also subtracts SP */
#ifdef XXXXX
if (isconst)
{
SYM *psp = currentfunc->parentclass;
if (currentfunc->value.classdata.basecons)
gen_void(currentfunc->value.classdata.basecons);
if (psp->value.classdata.baseclass->vtabsp)
{
CLASSLIST *l = psp->value.classdata.baseclass;
ENODE *thisn = copynode(thisenode);
ENODE *ts = makenode(en_nacon, psp
->value.classdata.baseclass->vtabsp, 0);
ENODE *exp1, *exp2;
thisn = makenode(en_a_ref, thisn, 0);
while (l)
{
if (l->flags &CL_VTAB)
{
exp1 = makenode(en_addstruc, ts, makeintnode
(en_icon, l->vtaboffs));
exp2 = makenode(en_addstruc, thisn, makeintnode
(en_icon, l->offset));
exp2 = makenode(en_a_ref, exp2, 0);
exp2 = makenode(en_assign, exp2, exp1);
initstack();
gen_expr(exp2, FALSE, TRUE, BESZ_DWORD);
}
l = l->link;
}
}
}
#endif
if (prm_cplusplus)
scppinit();
initstack();
genstmt(stmt);
if (block_rundown)
if (retsize)
if (retsize > BESZ_DWORD)
{
if (retsize == BESZ_QWORD) {
gen_codes(op_move, BESZ_DWORD, makedreg(0), push);
gen_codes(op_move, BESZ_DWORD, makedreg(1), push);
gen_void(block_rundown);
gen_codes(op_move, BESZ_DWORD, pop, makedreg(1));
gen_codes(op_move, BESZ_DWORD, pop, makedreg(0));
} else {
gen_codes(op_fmove, BESZ_LDOUBLE, makefreg(0), push);
gen_void(block_rundown);
gen_codes(op_fmove, BESZ_LDOUBLE, pop, makefreg(0));
}
}
else
{
gen_codes(op_move, BESZ_DWORD, makedreg(0), push);
gen_void(block_rundown);
gen_codes(op_move, BESZ_DWORD, pop, makedreg(0));
}
else
gen_void(block_rundown);
if (funcendstmt)
gen_line(funcendstmt);
funcendstmt = 0;
genreturn(0, 1);
thissp->inreg = FALSE;
thissp->value.i = 8;
flush_peep();
if (currentfunc->gennedvirtfunc)
gen_endvirtual(currentfunc);
if ((conscount || try_block_list || currentfunc
->value.classdata.throwlist && currentfunc
->value.classdata.throwlist->data) && prm_xcept)
dumpXceptBlock(currentfunc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -