?? gexpr386.c
字號:
case en_cul:
case en_cp:
ssize = 4;
break;
case en_tempref:
case en_regref:
ssize = node->v.p[0]->v.i >> 8;
break;
case en_floatref:
case en_cf:
ssize = 6;
break;
case en_doubleref:
case en_cd:
ssize = 8;
break;
case en_longdoubleref:
case en_cld:
ssize = 10;
break;
default:
ssize = -4;
}
if (chksize( ssize , rsize ))
rsize = ssize;
ap2 = gen_expr(node->v.p[1],F_DREG | F_FREG,rsize);
mark();
ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
ap4 = xalloc(sizeof(AMODE));
ap4->preg = ap1->preg;
ap4->mode = am_indisp;
ap4->offset = makenode(en_icon,0,0);
if (!equal_address(ap1,ap2) )
if (rsize > 4) {
floatstore(ap4,ssize,flags);
gen_codef(op_fwait,0,0,0);
}
else
if (node->v.p[0]->nodetype == en_bits)
bit_move(ap4,ap2,node->v.p[0],flags,ssize,rsize);
else
if (ap2->mode != am_dreg && ap2->mode != am_immed
&& ap4->mode != am_dreg) {
ap3 = temp_data();
gen_code(op_mov,rsize,ap3,ap2);
gen_code(op_mov,ssize,ap4,ap3);
freeop(ap3);
}
else
gen_code(op_mov,ssize,ap4,ap2);
freeop(ap1);
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,size);
return ap2;
}
AMODE *gen_aincdec(ENODE *node, int flags, int size, int op)
/*
* generate an auto increment or decrement node. op should be
* either op_add (for increment) or op_sub (for decrement).
*/
{ AMODE *ap1,*ap2;
int ssize,rsize;
ssize = natural_size(node->v.p[0]);
if (!(flags & F_NOVALUE)) {
ap2 = temp_data();
}
mark();
ap1 = gen_expr(node->v.p[0],F_ALL,ssize);
if (!(flags &F_NOVALUE)) {
gen_code(op_mov,ssize,ap2,ap1);
}
gen_code(op,ssize,ap1,make_immed((int)node->v.p[1]));
freeop(ap1);
release();
if (!(flags & F_NOVALUE)) {
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,size);
}
return ap2;
}
int push_param(ENODE *ep, int size)
/*
* push the operand expression onto the stack.
*/
{ AMODE *ap, *ap2;
int rv,sz;
switch (ep->nodetype) {
case en_absacon:
ep->v.i = (( SYM *)ep->v.p[0])->value.i;
ap = xalloc(sizeof(AMODE));
ap->mode = am_immed;
ap->offset = ep; /* use as constant node */
gen_code(op_push,4,ap,0);
rv = 4;
break;
case en_napccon:
case en_nacon:
ep->v.p[0] = ((SYM *)ep->v.p[0])->name;
case en_labcon:
case en_nalabcon:
ap = xalloc(sizeof(AMODE));
ap->mode = am_immed;
ap->offset = ep; /* use as constant node */
gen_code(op_push,4,ap,0);
make_legal(ap,F_ALL,4);
rv = 4;
break;
case en_cf:
case en_floatref:
ap = gen_expr(ep,F_FREG | F_VOL,6);
gen_code(op_sub,4,makedreg(ESP),make_immed(4));
ap2 = make_immed(0);
ap2->preg = ESP;
ap2->mode = am_indisp;
gen_codef(op_fstp,6,ap2,0);
gen_codef(op_fwait,0,0,0);
rv = 4;
break;
case en_cd:
case en_doubleref:
ap = gen_expr(ep,F_FREG | F_VOL,8);
gen_code(op_sub,4,makedreg(ESP),make_immed(8));
ap2 = make_immed(0);
ap2->preg = ESP;
ap2->mode = am_indisp;
gen_codef(op_fstp,8,ap2,0);
gen_codef(op_fwait,0,0,0);
rv = 8;
break;
case en_cld:
case en_longdoubleref:
ap = gen_expr(ep,F_FREG | F_VOL,8);
gen_code(op_sub,4,makedreg(ESP),make_immed(10));
ap2 = make_immed(0);
ap2->preg = ESP;
ap2->mode = am_indisp;
gen_codef(op_fstp,10,ap2,0);
gen_codef(op_fwait,0,0,0);
rv = 8;
break;
case en_rcon:
case en_fcon:
case en_lrcon:
rv = size;
if (rv == 6) rv= 4;
if (rv == 10) rv= 12;
ap = gen_expr(ep,F_FREG | F_VOL,size);
make_floatconst(ap,size);
gen_code(op_sub,4,makedreg(ESP),make_immed(rv));
ap2 = make_immed(0);
ap2->preg = ESP;
ap2->mode = am_indisp;
gen_codef(op_fstp,rv,ap2,0);
gen_codef(op_fwait,0,0,0);
break;
default:
rv = 4;
ap = gen_expr(ep,F_ALL,4);
if (ap->mode != am_dreg &&ap->mode != am_immed&& ap->mode != am_freg) {
sz = natural_size(ep->v.p[0]);
if (sz < 4 && sz >-4)
do_extend(ap,sz,4,F_DREG);
}
if (ap->mode == am_freg) {
gen_code(op_push,4,makedreg(3),0);
ap2 = make_immed(0);
ap2->preg = ESP;
ap2->mode = am_indisp;
gen_codef(op_fistp,4,ap2,0);
gen_codef(op_fwait,0,0,0);
}
else
gen_code(op_push,4,ap,0);
break;
}
freeop(ap);
stackdepth += rv;
return(rv);
}
int push_stackblock(ENODE *ep)
{
AMODE *ap;
int sz = (ep->size + stackadd) &stackmod;
if (!sz)
return(0);
gen_code(op_sub,4,makedreg(ESP),make_immed(sz));
gen_code(op_push,4,makedreg(ESI),0);
gen_code(op_push,4,makedreg(EDI),0);
stackdepth+=sz+8;
gen_code(op_lea,4,makedreg(EDI),make_stack(-8));
switch (ep->nodetype) {
case en_napccon:
case en_nacon:
ep->v.p[0] = ((SYM *)ep->v.p[0])->name;
case en_nalabcon:
case en_labcon:
ap = xalloc(sizeof(AMODE));
ap->mode = am_direct;
ap->offset = ep; /* use as constant node */
gen_code(op_lea,4,makedreg(ESI),ap);
break;
case en_absacon:
ep->v.i = (( SYM *)ep->v.p[0])->value.i;
ap = xalloc(sizeof(AMODE));
ap->mode = am_direct;
ap->offset = ep; /* use as constant node */
gen_code(op_lea,4,makedreg(ESI),ap);
break;
default:
ap = gen_expr(ep,F_DREG | F_MEM | F_IMMED,4);
gen_code(op_mov,4,makedreg(ESI),ap);
break;
}
gen_code(op_mov,4,makedreg(ECX),make_immed(sz));
gen_code(op_cld,0,0,0);
gen_code(op_rep,0,0,0);
gen_code(op_movsb,0,0,0);
gen_code(op_pop,4,makedreg(EDI),0);
gen_code(op_pop,4,makedreg(ESI),0);
stackdepth-=8;
freeop(ap);
return(sz);
}
int gen_parms(ENODE *plist,int size)
/*
* push a list of parameters onto the stack and return the
* size of parameters pushed.
*/
{ int i;
i = 0;
while( plist != 0 )
{
if (plist->nodetype == en_stackblock)
i+=push_stackblock(plist->v.p[0]);
else
i+=push_param(plist->v.p[0],size);
plist = plist->v.p[1];
}
return i;
}
AMODE *gen_fcall(ENODE *node,int flags, int size)
/*
* generate a function call node and return the address mode
* of the result.
*/
{ AMODE *ap, *result;
ENODE *node2;
int i,ssize;
result = temp_data();
temp_data(); temp_data(); /* push any used data registers */
freeop(result); freeop(result); freeop(result);
if (node->nodetype == en_callblock) {
i = gen_parms(node->v.p[1]->v.p[1]->v.p[1]->v.p[0],size);
ap = gen_expr(node->v.p[0],F_ALL,4);
gen_code(op_push,4,ap,0);
i+=4;
stackdepth+=4;
node = node->v.p[1];
freeop(ap);
ssize = 4;
}
else {
i = gen_parms(node->v.p[1]->v.p[1]->v.p[0],size); /* generate parameters */
ssize = node->v.p[0]->v.i;
}
if (node->nodetype == en_intcall) {
AMODE *ap2 = xalloc(sizeof(AMODE));
ap2->mode = am_seg;
ap2->seg = e_cs;
gen_code(op_pushfd,0,0,0);
gen_code(op_push,0,ap2,0);
}
if( node->v.p[1]->v.p[0]->nodetype == en_nacon || node->v.p[1]->v.p[0]->nodetype == en_napccon ) {
SYM *sp= node->v.p[1]->v.p[0]->v.p[0];
if (sp->inreg) {
ap = makedreg(sp->value.i);
}
else {
node->v.p[1]->v.p[0]->v.p[0] = sp->name;
ap = make_offset(node->v.p[1]->v.p[0]);
ap->mode = am_immed;
}
gen_code(op_call,0,ap,0);
}
else
{
if (node->v.p[1]->v.p[0]->nodetype == en_l_ref) {
node2=node->v.p[1]->v.p[0]->v.p[0];
}
else {
if (node->v.p[1]->v.p[0]->nodetype != en_tempref)
DIAG("gen_fcall - questionable indirection");
node2=node->v.p[1]->v.p[0];
}
ap = gen_expr(node2,F_ALL,4);
freeop(ap);
gen_code(op_call,4,ap,0);
}
if( i != 0 ) {
if (i == 4)
gen_code(op_pop,4,makedreg(ECX),0);
else
gen_code(op_add,4,makedreg(4),make_immed(i));
stackdepth -= i;
}
if (ssize > 4) {
result = fstack();
}
else {
result = temp_data();
if( result->preg != EAX)
gen_code(op_mov,4,result,makedreg(EAX));
}
result->tempflag = 1;
do_extend(result,ssize,size,flags);
make_legal(result,flags,size);
return result;
}
AMODE *gen_pfcall(ENODE *node,int flags, int size)
/*
* generate a function call node to a pascal function
* and return the address mode of the result.
*/
{ AMODE *ap, *result;
int i,ssize;
ENODE * invnode = 0,*anode,*node2;
/* invert the parameter list */
if (node->nodetype == en_pcallblock)
anode = node->v.p[1]->v.p[1]->v.p[1]->v.p[0];
else
anode = node->v.p[1]->v.p[1]->v.p[0];
while (anode) {
invnode = makenode(anode->nodetype,anode->v.p[0],invnode);
anode = anode->v.p[1];
}
result = temp_data();
temp_data(); temp_data(); /* push any used data registers */
freeop(result); freeop(result); freeop(result);
if (node->nodetype == en_pcallblock) {
ap = gen_expr(node->v.p[0],F_ALL,4);
gen_code(op_push,4,ap,0);
freeop(ap);
i=4;
stackdepth+=4;
i += gen_parms(invnode,size);
node = node->v.p[1];
ssize = 4;
}
else {
i = gen_parms(invnode,size); /* generate parameters */
ssize = node->v.p[0]->v.i;
}
if( node->v.p[1]->v.p[0]->nodetype == en_nacon || node->v.p[1]->v.p[0]->nodetype == en_napccon ) {
SYM *sp= node->v.p[1]->v.p[0]->v.p[0];
if (sp->inreg) {
ap = makedreg(sp->value.i);
}
else {
node->v.p[0]->v.p[0]->v.p[0] = sp->name;
ap = make_offset(node->v.p[1]->v.p[0]);
ap->mode = am_immed;
}
gen_code(op_call,0,ap,0);
}
else
{
if (node->v.p[1]->v.p[0]->nodetype == en_l_ref) {
node2=node->v.p[1]->v.p[0]->v.p[0];
}
else {
if (node->v.p[1]->v.p[0]->nodetype != en_tempref)
DIAG("gen_fcall - questionable indirection");
node2=node->v.p[1]->v.p[0];
}
ap = gen_expr(node2,F_ALL,4);
freeop(ap);
gen_code(op_call,4,ap,0);
}
stackdepth -= i;
if (ssize > 4) {
result = fstack();
}
else {
result = temp_data();
if( result->preg != EAX)
gen_code(op_mov,4,result,makedreg(EAX));
}
result->tempflag = 1;
do_extend(result,ssize,size,flags);
make_legal(result,flags,size);
return result;
}
AMODE *gen_expr(ENODE *node, int flags, int size)
/*
* general expression evaluation. returns the addressing mode
* of the result.
*/
{
AMODE *ap1, *ap2;
int lab0, lab1;
int natsize;
if( node == 0 )
{
DIAG("null node in gen_expr.");
return 0;
}
switch( node->nodetype )
{
case en_bits:
size = natural_size(node->v.p[0]);
ap1 = gen_expr(node->v.p[0],F_ALL,size);
if (!(flags & F_NOBIT))
bit_legal(ap1,node,size);
return ap1;
case en_cb:
case en_cub:
case en_cw:
case en_cuw:
case en_cl:
case en_cul:
case en_cf:
case en_cd:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -