?? gexpr386.c
字號:
if (ap->mode != am_freg) {
freeop(ap);
gen_codef(op_fld,isize,ap,0);
ap->mode = am_freg;
ap->preg = 0;
ap->tempflag = TRUE;
}
switch(osize) {
case 1:
case -1:
case 2:
case -2:
case 4:
case -4:
freeop(ap);
ap2 = temp_data();
ap->mode = ap2->mode;
ap->preg = ap2->preg;
gen_code(op_push,4,makedreg(3),0);
gen_codef(op_fistp,4,ap2 = make_stack(0),0);
gen_codef(op_fwait,0,0,0);
gen_code(op_mov,osize,ap,ap2);
gen_code(op_add,4,sreg,make_immed(4));
goto doextend;
case 6:
case 8:
break;
}
}
}
int isshort(ENODE *node)
/*
* return true if the node passed can be generated as a short
* offset.
*/
{ return (isintconst(node->nodetype) &&
(node->v.i >= -32768L && node->v.i <= 32767L));
}
int isbyte(ENODE *node)
/*
* return true if the node passed can be evaluated as a byte
* offset.
*/
{ return isintconst(node->nodetype) &&
(-128 <= node->v.i && node->v.i <= 127);
}
AMODE *gen_index(ENODE *node)
/*
* generate code to evaluate an index node (^+) and return
* the addressing mode of the result. This routine takes no
* flags since it always returns either am_ind or am_indx.
*/
{ AMODE *ap1,*ap2, *ap, *ap3;
ENODE node2;
int scale;
switch (node->v.p[0]->nodetype) {
case en_icon:
ap1 = gen_expr(node->v.p[0],F_IMMED,4);
break;
case en_lsh:
if ((scale = node->v.p[0]->v.p[1]->v.i) < 4 && scale) {
ap1 = gen_expr(node->v.p[0]->v.p[0],F_IMMED | F_DREG,4);
if (ap1->mode == am_immed) {
while (--scale)
ap1->offset->v.i <<=1;
}
else {
ap1->mode = am_indispscale;
ap1->sreg = ap1->preg;
ap1->preg = -1;
ap1->scale = scale;
ap1->offset = makenode(en_icon,0,0);
}
break;
}
default:
mark();
ap1 = gen_deref(node,F_MEM | F_DREG,4);
switch (ap1->mode) {
default:
rsold[rsodepth-1] = rsdepth;
break;
case am_indispscale:
if (ap1->sreg >=0 && ap1->preg >= 0) {
int t = rsold[rsodepth-1];
freeop(ap1);
ap3 = temp_data();
gen_code(op_lea,4,ap3,ap1);
ap3->mode = am_indisp;
ap3->offset = makenode(en_icon,0,0);
if (t <rsdepth-1 && ap3->preg + 8 == regstack[t+1])
t+=2;
if (t <rsdepth && ap3->preg + 8 == regstack[t])
t+=1;
ap1 = ap3;
}
}
release();
break;
}
switch (node->v.p[1]->nodetype) {
case en_icon:
ap2 = gen_expr(node->v.p[1],F_IMMED,4);
break;
case en_lsh:
if ((scale = node->v.p[1]->v.p[1]->v.i) < 4 && scale) {
ap2 = gen_expr(node->v.p[1]->v.p[0],F_IMMED | F_DREG,4);
if (ap2->mode == am_immed) {
while (--scale)
ap2->offset->v.i <<=1;
}
else {
ap2->mode = am_indispscale;
ap2->sreg = ap2->preg;
ap2->preg = -1;
ap2->scale = scale;
ap2->offset = makenode(en_icon,0,0);
}
break;
}
default:
node2.v.p[0] = node->v.p[1];
node2.nodetype = node->nodetype;
mark();
ap2 = gen_deref(&node2,F_MEM | F_DREG,4);
switch (ap1->mode) {
default:
rsold[rsodepth-1] = rsdepth;
break;
case am_indispscale:
if (ap1->sreg >=0 && ap1->preg >= 0) {
int t = rsold[rsodepth-1];
freeop(ap1);
ap3 = temp_data();
gen_code(op_lea,4,ap3,ap1);
ap3->mode = am_indisp;
ap3->offset = makenode(en_icon,0,0);
if (t <rsdepth-1 && ap3->preg + 8 == regstack[t+1])
t+=2;
if (t <rsdepth && ap3->preg + 8 == regstack[t])
t+=1;
ap1 = ap3;
}
}
release();
break;
}
switch(ap1->mode) {
case am_dreg:
switch (ap2->mode) {
case am_dreg:
ap1->sreg = ap2->preg;
ap1->scale = 0;
ap1->mode = am_indispscale;
ap1->offset = makenode(en_icon,(char *)0,0);
return ap1;
case am_immed:
case am_direct:
ap2->preg = ap1->preg;
ap2->mode = am_indisp;
return ap2;
case am_indisp:
ap2->sreg = ap2->preg;
ap2->preg = ap1->preg;
ap2->mode = am_indispscale;
ap2->offset = ap1->offset;
ap2->scale = 0;
return ap2;
case am_indispscale:
if (ap2->preg == -1) {
ap2->preg = ap1->preg;
return ap2;
}
freeop(ap2);
ap = temp_data();
gen_code(op_lea,4,ap,ap2);
ap->sreg = ap1->preg;
ap->mode = am_indispscale;
ap->scale = 0;
ap->offset = makenode(en_icon,0,0);
return ap;
}
break;
case am_direct:
case am_immed:
switch (ap2->mode) {
case am_dreg:
ap2->mode = am_indisp;
ap2->offset = ap1->offset;
return ap2;
case am_immed:
case am_direct:
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap1->offset->v.i += ap2->offset->v.i;
else
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
ap1->mode = am_direct;
return ap1;
case am_indisp:
case am_indispscale:
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap2->offset->v.i += ap1->offset->v.i;
else
ap2->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap2;
}
break;
case am_indisp:
switch (ap2->mode) {
case am_dreg:
ap1->mode = am_indispscale;
ap1->sreg = ap2->preg;
ap1->scale = 0;
return ap1;
case am_immed:
case am_direct:
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap1->offset->v.i += ap2->offset->v.i;
else
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap1;
case am_indisp:
ap1->mode = am_indispscale;
ap1->sreg = ap2->preg;
ap1->scale = 0;
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap1->offset->v.i += ap2->offset->v.i;
else
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap1;
case am_indispscale:
if (ap2->preg == -1) {
ap2->preg = ap1->preg;
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap2->offset->v.i += ap1->offset->v.i;
else
ap2->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap2;
}
freeop(ap2);
ap = temp_data();
gen_code(op_lea,4,ap,ap2);
ap1->sreg = ap->preg;
ap1->scale = 0;
ap1->mode = am_indispscale;
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap1->offset->v.i += ap2->offset->v.i;
else
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap1;
}
break;
case am_indispscale:
switch (ap2->mode) {
case am_dreg:
if (ap1->preg == -1) {
ap1->preg = ap2->preg;
return ap1;
}
freeop(ap1);
ap = temp_data();
gen_code(op_lea,4,ap,ap1);
ap->sreg = ap2->preg;
ap->scale = 0;
ap->offset = ap1->offset;
return ap;
case am_immed:
case am_direct:
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap1->offset->v.i += ap2->offset->v.i;
else
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap1;
case am_indisp:
if (ap1->preg == -1) {
ap1->preg = ap2->preg;
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap1->offset->v.i += ap2->offset->v.i;
else
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap1;
}
freeop(ap1);
ap = temp_data();
gen_code(op_lea,4,ap,ap1);
ap->sreg = ap2->preg;
ap->scale = 0;
ap->mode = am_indispscale;
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap->offset->v.i = ap2->offset->v.i +ap1->offset->v.i;
else
ap->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap;
case am_indispscale:
if (ap1->preg == -1 && ap2->preg == -1) {
if (ap1->scale == 0) {
ap2->preg = ap1->sreg;
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap2->offset->v.i += ap1->offset->v.i;
else
ap2->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap2;
} else if (ap2->scale == 0) {
ap1->preg = ap2->sreg;
if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype == en_icon)
ap1->offset->v.i += ap2->offset->v.i;
else
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap1;
}
}
if (ap1->preg == -1) {
freeop(ap2);
ap = temp_data();
gen_code(op_lea,4,ap,ap2);
ap1->preg = ap->preg;
return ap1;
}
else if (ap2->preg == -1) {
freeop(ap1);
ap = temp_data();
gen_code(op_lea,4,ap,ap1);
ap2->preg = ap->preg;
return ap2;
}
freeop(ap1);
ap = temp_data();
gen_code(op_lea,4,ap,ap1);
freeop(ap2);
ap1 = temp_data();
gen_code(op_lea,4,ap1,ap2);
ap->mode = am_indispscale;
ap->sreg = ap1->preg;
ap->scale = 0;
ap->offset = makenode(en_icon,0,0);
return ap;
}
break;
}
DIAG("invalid index conversion");
}
AMODE *gen_deref(ENODE *node, int flags,int size)
/*
* return the addressing mode of a dereferenced node.
*/
{ AMODE *ap1;
int ssize,psize;
psize = size;
if (psize < 0)
psize = - psize;
switch( node->nodetype ) /* get load size */
{
case en_ub_ref:
ssize = 1;
break;
case en_b_ref:
ssize = -1;
break;
case en_uw_ref:
ssize = 2;
break;
case en_w_ref:
ssize = -2;
break;
case en_l_ref:
ssize = -4;
break;
case en_ul_ref:
ssize = 4;
break;
case en_floatref:
ssize = 6;
break;
case en_doubleref:
ssize = 8;
break;
case en_longdoubleref:
ssize = 10;
break;
default:
ssize = 4;
}
if( node->v.p[0]->nodetype == en_add )
{
ap1 = gen_index(node->v.p[0]);
do_extend(ap1,ssize,psize,flags);
make_legal(ap1,flags,psize);
return ap1;
}
else if( node->v.p[0]->nodetype == en_autocon || node->v.p[0]->nodetype == en_autoreg)
{
ap1 = xalloc(sizeof(AMODE));
ap1->mode = am_indisp;
ap1->preg = ESP;
if (prm_linkreg) {
ap1->preg = EBP;
ap1->offset = makenode(en_icon,(char *)((SYM *)node->v.p[0]->v.p[0])->value.i,0);
}
else if (((SYM *)node->v.p[0]->v.p[0])->funcparm)
ap1->offset = makenode(en_icon,(char *)(((SYM *)node->v.p[0]->v.p[0])->value.i+framedepth+stackdepth),0);
else
ap1->offset = makenode(en_icon,(char *)(((SYM *)node->v.p[0]->v.p[0])->value.i+stackdepth+lc_maxauto),0);
do_extend(ap1,ssize,size,flags);
make_legal(ap1,flags,psize);
return ap1;
}
else if( node->v.p[0]->nodetype == en_nacon || node->v.p[0]->nodetype == en_napccon)
{
ap1 = xalloc(sizeof(AMODE));
ap1->offset = makenode(node->v.p[0]->nodetype,(char *)((SYM *)node->v.p[0]->v.p[0])->name,0);
ap1->mode = am_direct;
do_extend(ap1,ssize,size,flags);
make_legal(ap1,flags,psize);
return ap1;
}
else if( node->v.p[0]->nodetype == en_nalabcon)
{
ap1 = xalloc(sizeof(AMODE));
ap1->offset = makenode(node->v.p[0]->nodetype,(char *)node->v.p[0]->v.i,0);
ap1->mode = am_direct;
do_extend(ap1,ssize,size,flags);
make_legal(ap1,flags,psize);
return ap1;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -