?? gexpr386.c
字號:
*/
{ AMODE *ap1, *ap2, *ap3;
int ssize,rsize;
ssize = natural_size(node->v.p[0]);
rsize = natural_size(node->v.p[1]);
if (rsize == 0)
rsize = ssize;
if (rsize > 4) {
ap2 = gen_expr(node->v.p[0],F_FREG,rsize);
ap3 = gen_expr(node->v.p[0],F_MEM,ssize);
ap1 = gen_expr(node->v.p[1],F_FREG | F_MEM,rsize);
if (ap1->mode == am_freg)
gen_code(fop,0,0,0);
else {
if (rsize <= 4)
if (fop == op_fadd)
fop = op_fiadd;
else
fop = op_fisub;
gen_f10code(fop,rsize,ap1,0);
}
floatstore(ap3,ssize,flags);
gen_codef(op_fwait,0,0,0);
if (!(flags & F_NOVALUE)) {
ap2 = fstack();
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,size);
}
return ap2;
}
if (chksize( ssize ,rsize ))
rsize = ssize;
ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
mark();
ap1 = gen_expr(node->v.p[1],F_DREG | F_IMMED,rsize);
if (node->v.p[0]->nodetype == en_bits)
ap3= get_bitval(ap2,node->v.p[0],ssize);
if (node->v.p[0]->nodetype == en_bits) {
gen_code(op,ssize,ap3,ap1);
bit_move(ap2,ap3,node->v.p[0],flags, ssize,rsize);
freeop(ap3);
}
else
gen_code(op,ssize,ap2,ap1);
freeop(ap1);
release();
if (flags & F_NOVALUE)
freeop(ap2);
else {
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,4);
}
return ap2;
}
AMODE *gen_aslogic(ENODE *node, int flags, int size, int op)
/*
* generate a and equal or a or equal node.
*/
{ AMODE *ap1, *ap2;
int ssize,rsize;
ssize = natural_size(node->v.p[0]);
rsize = natural_size(node->v.p[1]);
if (chksize( ssize , rsize ))
rsize = ssize;
ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
mark();
ap1 = gen_expr(node->v.p[1],F_DREG | F_IMMED,rsize);
if (node->v.p[0]->nodetype == en_bits) {
if (ap1->mode == am_immed) {
ap1->offset->v.i &= bittab[node->v.p[0]->bits-1];
ap1->offset->v.i <<= node->v.p[0]->startbit;
gen_code(op,ssize,ap2,ap1);
}
else {
gen_code(op_and,ssize,ap1,make_immed(bittab[node->v.p[0]->bits-1]));
if (node->v.p[0]->startbit)
gen_code(op_shl,ssize,ap1,make_immed(node->v.p[0]->startbit));
gen_code(op,ssize,ap2,ap1);
if (!(flags & F_NOVALUE)) {
freeop(ap1);
release();
if (node->v.p[0]->startbit)
gen_code(op_shr,ssize,ap2,make_immed(node->v.p[0]->startbit));
do_extend(ap2,ssize,size,0);
make_legal(ap2,F_DREG,size);
return(ap2);
}
}
}
else
gen_code(op,ssize,ap2,ap1);
freeop(ap1);
release();
if (flags & F_NOVALUE)
freeop(ap2);
else {
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,4);
}
return ap2;
}
AMODE *gen_asshift(ENODE *node, int flags, int size, int op)
/*
* generate shift equals operators.
*/
{
AMODE *ap1, *ap2, *ap3;
int ssize = natural_size(node->v.p[0]);
int rsize = natural_size(node->v.p[1]);
if (chksize( ssize , rsize ))
rsize = rsize;
ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
mark();
ap1 = gen_expr(node->v.p[1],F_DREG | F_IMMED,rsize);
if (node->v.p[0]->nodetype == en_bits)
ap3 = get_bitval(ap2,node->v.p[0],ssize);
else
ap3 = ap2;
doshift(ap3,ap1,ssize,op);
if (node->v.p[0]->nodetype == en_bits)
bit_move(ap2,ap3,node->v.p[0],flags,ssize,rsize);
freeop(ap1);
release();
if (ap3 != ap1)
freeop(ap3);
if (flags & F_NOVALUE)
freeop(ap2);
else {
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,4);
}
return ap2;
}
AMODE *gen_asmul(ENODE *node, int flags, int size,int op)
/*
* generate a *= node.
*/
{ AMODE *ap1, *ap2,*ap3;
int ssize, lsize,rsize;
ssize = natural_size(node->v.p[0]);
rsize = natural_size(node->v.p[1]);
if (rsize == 0)
rsize = ssize;
if (rsize > 4) {
int fop = op_fmul;
ap2 = gen_expr(node->v.p[0],F_FREG,rsize);
ap3 = gen_expr(node->v.p[0],F_MEM,ssize);
ap1 = gen_expr(node->v.p[1],F_FREG | F_MEM,rsize);
if (ap1->mode == am_freg)
gen_code(fop,0,0,0);
else {
if (rsize <= 4)
fop = op_fimul;
gen_f10code(fop,ssize,ap1,0);
}
floatstore(ap3,ssize,flags);
gen_codef(op_fwait,0,0,0);
if (!(flags & F_NOVALUE)) {
ap2 = fstack();
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,size);
}
return ap2;
}
if (op == op_imul)
lsize= -4;
else
lsize = 4;
ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
mark();
ap1 = gen_expr(node->v.p[1],F_ALL,lsize);
ap3 = xalloc(sizeof(AMODE));
ap3->mode = ap2->mode;
ap3->preg = ap2->preg;
ap3->sreg = ap2->sreg;
ap3->scale = ap2->scale;
ap3->offset = ap2->offset;
if (node->v.p[0]->nodetype == en_bits)
ap2 = get_bitval(ap2,node->v.p[0],ssize);
else {
make_legal(ap2,F_DREG | F_VOL,4);
do_extend(ap2,ssize,lsize,F_DREG);
}
domul(ap2,ap1,lsize,op);
freeop(ap1);
release();
if (!equal_address(ap2,ap3))
if (node->v.p[0]->nodetype == en_bits)
bit_move(ap3,ap2,node->v.p[0],flags,ssize,rsize);
else
gen_code(op_mov,ssize,ap3,ap2);
if (flags & F_NOVALUE)
freeop(ap2);
else {
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,4);
}
return ap2;
}
AMODE *gen_asmodiv(ENODE *node, int flags, int size, int op, int modflag)
/*
* generate /= and %= nodes.
*/
{ AMODE *ap1, *ap2,*ap3;
int ssize,lsize,rsize;
ssize = natural_size(node->v.p[0]);
rsize = natural_size(node->v.p[1]);
if (rsize == 0)
rsize = ssize;
if (rsize > 4) {
int fop = op_fdiv;
ap2 = gen_expr(node->v.p[0],F_FREG,rsize);
ap3 = gen_expr(node->v.p[0],F_MEM,ssize);
ap1 = gen_expr(node->v.p[1],F_FREG | F_MEM,rsize);
if (ap1->mode == am_freg)
gen_code(fop,0,0,0);
else {
if (rsize <= 4)
fop = op_fidiv;
gen_f10code(fop,ssize,ap1,0);
}
floatstore(ap3,ssize,flags);
gen_codef(op_fwait,0,0,0);
if (!(flags & F_NOVALUE)) {
ap2 = fstack();
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,size);
}
return ap2;
}
if (op == op_idiv)
lsize= -4;
else
lsize = 4;
ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST, ssize);
mark();
ap1 = gen_expr(node->v.p[1],F_ALL,lsize);
ap3 = xalloc(sizeof(AMODE));
ap3->mode = ap2->mode;
ap3->preg = ap2->preg;
ap3->sreg = ap2->sreg;
ap3->scale = ap2->scale;
ap3->offset = ap2->offset;
if (node->v.p[0]->nodetype == en_bits)
ap2 = get_bitval(ap2,node->v.p[0],ssize);
else {
make_legal(ap2,F_DREG | F_VOL,4);
do_extend(ap2,ssize,lsize,F_DREG);
}
dodiv(ap2,ap1,ssize,op,modflag);
freeop(ap1);
release();
if (!equal_address(ap2,ap3))
if (node->v.p[0]->nodetype == en_bits)
bit_move(ap3,ap2,node->v.p[0],flags,ssize,rsize);
else
gen_code(op_mov,ssize,ap3,ap2);
if (flags & F_NOVALUE)
freeop(ap2);
else {
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,4);
}
return ap2;
}
AMODE *gen_moveblock(ENODE *node, int flags, int size)
{
AMODE *ap1, *ap2;
if (!node->size)
return(0);
ap2 = gen_expr(node->v.p[1],F_DREG | F_VOL,4);
mark();
ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,4);
gen_push(ESI,am_dreg,0);
gen_push(EDI,am_dreg,0);
if (regs[1])
gen_push(ECX,am_dreg,0);
gen_code(op_mov,4,makedreg(ESI),ap2);
gen_code(op_mov,4,makedreg(EDI),ap1);
gen_code(op_mov,4,makedreg(ECX),make_immed(node->size));
gen_code(op_cld,0,0,0);
gen_code(op_rep,1,0,0);
gen_code(op_movsb,1,0,0);
if (regs[1])
gen_pop(ECX,am_dreg,0);
gen_pop(EDI,am_dreg,0);
gen_pop(ESI,am_dreg,0);
freeop(ap2);
freeop(ap1);
release();
return(ap2);
}
AMODE *gen_assign(ENODE *node, int flags, int size)
/*
* generate code for an assignment node. if the size of the
* assignment destination is larger than the size passed then
* everything below this node will be evaluated with the
* assignment size.
*/
{ AMODE *ap1, *ap2, *ap3,*ap4 = 0;
int ssize,rsize;
rsize = natural_size(node->v.p[1]);
switch( node->v.p[0]->nodetype )
{
case en_bits:
ssize = natural_size(node->v.p[0]);
break;
case en_ub_ref:
case en_cub:
ssize = 1;
break;
case en_b_ref:
case en_cb:
ssize = -1;
break;
case en_uw_ref:
case en_cuw:
ssize = 2;
break;
case en_w_ref:
case en_cw:
ssize = -2;
break;
case en_l_ref:
case en_cl:
ssize = -4;
break;
case en_ul_ref:
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 | F_IMMED,rsize);
mark();
ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
if (!equal_address(ap1,ap2) ) {
if (rsize > 4) {
floatstore(ap1,ssize,flags);
gen_codef(op_fwait,0,0,0);
}
else {
if (node->v.p[0]->nodetype == en_bits) {
bit_move(ap1,ap2,node->v.p[0],flags,ssize,rsize);
}
else {
if (ap2->mode != am_dreg && ap2->mode != am_immed
&& ap1->mode != am_dreg) {
freeop(ap2);
ap3 = temp_data();
gen_code(op_mov,ssize,ap3,ap2);
gen_code(op_mov,ssize,ap1,ap3);
}
else {
gen_code(op_mov,ssize,ap1,ap2);
}
}
}
}
release();
if (flags & F_NOVALUE)
freeop(ap2);
else {
do_extend(ap2,ssize,size,flags);
make_legal(ap2,flags,size);
}
return ap2;
}
AMODE *gen_refassign(ENODE *node, int flags, int size)
/*
* generate code for an assignment node. if the size of the
* assignment destination is larger than the size passed then
* everything below this node will be evaluated with the
* assignment size.
*/
{ AMODE *ap1, *ap2, *ap3,*ap4;
int ssize,rsize;
rsize = natural_size(node->v.p[1]);
switch( node->v.p[0]->nodetype )
{
case en_bits:
ssize = natural_size(node->v.p[0]);
break;
case en_ub_ref:
case en_cub:
ssize = 1;
break;
case en_b_ref:
case en_cb:
ssize = -1;
break;
case en_uw_ref:
case en_cuw:
ssize = 2;
break;
case en_w_ref:
case en_cw:
ssize = -2;
break;
case en_l_ref:
case en_cl:
ssize = -4;
break;
case en_ul_ref:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -