📄 gexpr68.c
字号:
{
ap1 = xalloc(sizeof(AMODE));
if (prm_rel)
ap1->mode = am_pcindx;
else {
ap1->mode = am_adirect;
if (prm_smallcode)
ap1->preg = 2;
else
ap1->preg = 4;
}
if (node->v.p[0]->nodetype == en_labcon)
ap1->offset = makenode(node->v.p[0]->nodetype,(char *)node->v.p[0]->v.i,0);
else
ap1->offset = makenode(node->v.p[0]->nodetype,((SYM *)node->v.p[0]->v.p[0])->name,0);
do_extend(ap1,siz1,size,flags);
make_legal(ap1,flags,psize);
return ap1;
}
else if (node->v.p[0]->nodetype == en_absacon) {
ap1 = xalloc(sizeof(AMODE));
ap1->mode = am_adirect;
ap1->preg = isshort(node->v.p[0]) ? 2 : 4;
ap1->offset = makenode(en_absacon,(char *)((SYM *)node->v.p[0]->v.p[0])->value.i,0);
do_extend(ap1,siz1,size,flags);
make_legal(ap1,flags,psize);
return ap1;
}
else if (node->v.p[0]->nodetype == en_regref) {
ap1 = gen_expr(node->v.p[0],F_ALL,4);
do_extend(ap1,siz1,size,flags);
make_legal(ap1,flags,psize);
return ap1;
}
if (flag) {
ap1 = gen_expr(node->v.p[0],F_AREG | F_DREG | F_IMMED,4); /* generate address */
if (ap1->mode == am_dreg)
return ap1;
}
else {
ap1 = gen_expr(node->v.p[0],F_AREG | F_IMMED,4); /* generate address */
}
/* AINCDEC for example may return an indirect mode already */
if (ap1->mode == am_areg || ap1->mode == am_immed) {
if( ap1->mode == am_areg )
{
ap1->mode = am_ind;
do_extend(ap1,siz1,size,flags);
make_legal(ap1,flags,psize);
return ap1;
}
ap1->mode = am_direct;
}
do_extend(ap1,siz1,size,flags);
make_legal(ap1,flags,psize);
return ap1;
}
AMODE *gen_unary(ENODE *node,int flags,int size,int op, int fop)
/*
* generate code to evaluate a unary minus or complement.
*/
{ AMODE *ap;
ap = gen_expr(node->v.p[0],F_FREG | F_DREG | F_VOL,size);
if (ap->mode == am_freg) {
gen_codef(fop,size,ap,0);
}
else {
gen_code(op,size,ap,0);
}
make_legal(ap,flags,size);
return ap;
}
AMODE *gen_binary(ENODE *node,int flags,int size,int op, int fop)
/*
* generate code to evaluate a binary node and return
* the addressing mode of the result.
*/
{ AMODE *ap1, *ap2;
ap1 = gen_expr(node->v.p[0],F_VOL | F_DREG | F_AREG | F_FREG,size);
mark();
ap2 = gen_expr(node->v.p[1],F_ALL,size);
if (size > 4)
gen_codef(fop,size,ap2,ap1);
else
gen_code(op,size,ap2,ap1);
freeop(ap2);
release();
make_legal(ap1,flags,size);
return ap1;
}
AMODE *gen_xbin(ENODE *node,int flags,int size,int op, int fop)
/*
* generate code to evaluate a restricted binary node and return
* the addressing mode of the result.
*/
{ AMODE *ap1, *ap2;
ap1 = gen_expr(node->v.p[0],F_VOL | F_DREG | F_FREG,size);
mark();
ap2 = gen_expr(node->v.p[1],F_DREG| F_FREG, size);
if (size > 4)
gen_codef(fop,size,ap2,ap1);
else
gen_code(op,size,ap2,ap1);
freeop(ap2);
release();
make_legal(ap1,flags,size);
return ap1;
}
AMODE *gen_shift(ENODE *node, int flags, int size, int op)
/*
* generate code to evaluate a shift node and return the
* address mode of the result.
*/
{ AMODE *ap1, *ap2;
ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,size);
mark();
ap2 = gen_expr(node->v.p[1],F_DREG | F_IMMED,size);
doshift(op,ap2,ap1,size);
freeop(ap2);
release();
make_legal(ap1,flags,size);
return ap1;
}
AMODE *gen_modiv(ENODE *node, int flags, int size, int op, int modflag)
/*
* generate code to evaluate a mod operator or a divide
* operator. these operations are done on only long
* divisors and word dividends so that the 68000 div
* instruction can be used.
*/
{ AMODE *ap1, *ap2,*ap3;
int temp;
int sz1 = natural_size(node->v.p[0]);
int sz2 = natural_size(node->v.p[0]);
int psize;
if (sz1 < 0) sz1 = - sz1;
if (sz2 < 0) sz2 = - sz2;
psize = sz2 > sz1 ? sz2 : sz1;
if (psize < 2) psize = 2;
if (op == op_divs) psize = -psize;
if (size > 4) {
ap1 = gen_expr(node->v.p[0],F_FREG | F_VOL,size);
mark();
ap2 = gen_expr(node->v.p[1],F_ALL&~F_AREG,size);
gen_codef(op_fdiv,size,ap2,ap1);
freeop(ap2);
release();
make_legal(ap1,flags,size);
return(ap1);
}
if (prm_68020 || psize ==2 || psize == -2) {
if (psize != 2 && psize != -2)
if (op == op_divs)
op = op_divsl;
else
op = op_divul;
ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,psize == 2 ? 4 : -4);
mark();
ap2 = gen_expr(node->v.p[1],F_ALL & ~F_AREG,psize);
if (psize !=2 && psize != -2) {
ap3 = temp_data();
temp = ap3->preg;
ap3->mode = am_divsl;
if( modflag ) {
ap3->sreg = ap1->sreg;
}
else {
ap3->sreg = ap3->preg = ap1->sreg;
}
gen_code(op,psize,ap2,ap3);
ap3->mode = am_dreg;
ap3->preg = temp;
if (modflag)
gen_code(op_exg,0,ap1,ap3);
freeop(ap3);
}
else {
gen_code(op,2,ap2,ap1);
if (modflag) {
gen_code(op_swap,2,ap1,0);
}
}
do_extend(ap1,psize,size,flags);
make_legal(ap1,flags,size);
freeop(ap2);
release();
return ap1;
}
flush_for_libcall();
if (op == op_divs) {
ap1 = gen_expr(node->v.p[0],F_ALL,-4);
}
else {
ap1 = gen_expr(node->v.p[0],F_ALL,4);
}
mark();
if (op == op_divs) {
ap2 = gen_expr(node->v.p[1],F_ALL,-4);
}
else {
ap2 = gen_expr(node->v.p[1],F_ALL,4);
}
gen_code(op_move,4,ap1,push);
freeop(ap2);
gen_code(op_move,4,ap2,push);
freeop(ap1);
if (op == op_divs)
if (modflag) {
ap1 = call_library("__mods",8);
}
else {
ap1 = call_library("__divs",8);
}
else
if (modflag) {
ap1 = call_library("__modu",8);
}
else {
ap1 = call_library("__divu",8);
}
release();
make_legal(ap1,flags,size);
return ap1;
}
void swap_nodes(ENODE *node)
/*
* exchange the two operands in a node.
*/
{ ENODE *temp;
temp = node->v.p[0];
node->v.p[0] = node->v.p[1];
node->v.p[1] = temp;
}
AMODE * gen_pdiv(ENODE *node, int flags, int size)
{
AMODE *ap1, *ap2;
ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,4);
mark();
ap2 = gen_expr(node->v.p[1],F_ALL,2);
gen_code(op_divs,2,ap2,ap1);
freeop(ap2);
release();
make_legal(ap1,flags,size);
return ap1;
}
AMODE * gen_pmul(ENODE *node, int flags, int size)
{
AMODE *ap1, *ap2;
if (isintconst(node->v.p[0]->nodetype))
swap_nodes(node);
ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,4);
mark();
ap2 = gen_expr(node->v.p[1],F_ALL,4);
gen_code(op_muls,0,ap2,ap1);
freeop(ap2);
release();
make_legal(ap1,flags,size);
return ap1;
}
AMODE *gen_mul(ENODE *node, int flags, int size, int op)
/*
* generate code to evaluate a multiply node. both operands
* are treated as words and the result is long and is always
* in a register so that the 68000 mul instruction can be used.
*/
{ AMODE *ap1, *ap2;
int sz1 = natural_size(node->v.p[0]);
int sz2 = natural_size(node->v.p[0]);
int psize;
if (sz1 < 0) sz1 = - sz1;
if (sz2 < 0) sz2 = - sz2;
psize = sz2 > sz1 ? sz2 : sz1;
if (psize < 2) psize = 2;
if (op == op_muls) psize = -psize;
if (size > 4) {
ap1 = gen_expr(node->v.p[0],F_FREG | F_VOL,size);
mark();
ap2 = gen_expr(node->v.p[1],F_ALL&~F_AREG,size);
gen_codef(op_fmul,size,ap2,ap1);
freeop(ap2);
release();
make_legal(ap1,flags,size);
return(ap1);
}
if (prm_68020 || psize == -2 || psize == 2) {
if (isintconst(node->v.p[0]->nodetype))
swap_nodes(node);
ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,psize);
mark();
ap2 = gen_expr(node->v.p[1],F_ALL&~F_AREG,psize);
gen_code(op,psize,ap2,ap1);
freeop(ap2);
release();
do_extend(ap1,psize,size,flags);
make_legal(ap1,flags,size);
return ap1;
}
flush_for_libcall();
if (isintconst(node->v.p[0]->nodetype))
swap_nodes(node);
if (op == op_muls) {
ap1 = gen_expr(node->v.p[0],F_ALL,-4);
}
else {
ap1 = gen_expr(node->v.p[0],F_ALL,4);
}
mark();
if (op == op_muls) {
ap2 = gen_expr(node->v.p[1],F_ALL,-4);
}
else {
ap2 = gen_expr(node->v.p[1],F_ALL,4);
}
gen_code(op_move,4,ap1,push);
freeop(ap2);
gen_code(op_move,4,ap2,push);
freeop(ap1);
if (op == op_muls) {
ap1 = call_library("__muls",8);
}
else {
ap1 = call_library("__mulu",8);
}
release();
make_legal(ap1,flags,size);
return ap1;
}
AMODE *gen_hook(ENODE *node, int flags, int size)
/*
* generate code to evaluate a condition operator node (?:)
*/
{ AMODE *ap1, *ap2;
int false_label, end_label;
false_label = nextlabel++;
end_label = nextlabel++;
flags = (flags & (F_AREG | F_DREG)) | F_VOL;
falsejp(node->v.p[0],false_label);
node = node->v.p[1];
ap1 = gen_expr(node->v.p[0],flags,size);
freeop(ap1);
gen_code(op_bra,0,make_label(end_label),0);
gen_label(false_label);
ap2 = gen_expr(node->v.p[1],flags,size);
if( !equal_address(ap1,ap2) )
{
freeop(ap2);
if( ap1->mode == am_dreg )
temp_data();
else
temp_addr();
gen_code(op_move,size,ap2,ap1);
}
gen_label(end_label);
return ap1;
}
AMODE *gen_asadd(ENODE *node, int flags, int size, int op, int fop)
/*
* generate a plus equal or a minus equal node.
*/
{ AMODE *ap1, *ap2, *ap3;
int ssize,rsize;
ssize = natural_size(node->v.p[0]);
rsize = natural_size(node->v.p[1]);
if (ssize > 4) {
ap1 = gen_expr(node->v.p[0],F_ALL,ssize);
ap3 = xalloc(sizeof(AMODE));
ap3->mode = ap1->mode;
ap3->preg = ap1->preg;
ap3->sreg = ap1->sreg;
ap3->offset = ap1->offset;
make_legal(ap1,F_FREG,ssize);
mark();
ap2 = gen_expr(node->v.p[1],F_ALL,size);
gen_codef(fop,ssize,ap2,ap1);
make_legal(ap1,flags,size);
if (ap3->mode != am_freg)
gen_codef(op_fmove,ssize,ap1,ap3);
freeop(ap2);
release();
return(ap1);
}
if (chksize( size , rsize ))
rsize = size;
ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,ssize);
mark();
if (node->v.p[0]->nodetype == en_bits) {
ap3= get_bitval(ap1,node->v.p[0],ssize);
}
ap2 = gen_expr(node->v.p[1],F_DREG | F_AREG | F_FREG | F_IMMED,rsize);
if (ssize > 4)
gen_codef(fop,ssize,ap2,ap1);
else
if (node->v.p[0]->nodetype == en_bits) {
gen_code(op,ssize,ap2,ap3);
bit_move(ap3,ap1,node->v.p[0],flags, ssize,rsize);
freeop(ap3);
}
else
gen_code(op,ssize,ap2,ap1);
freeop(ap2);
release();
if (flags & F_NOVALUE)
freeop(ap1);
else {
if (node->v.p[0]->nodetype == en_bits) {
do_extend(ap3,ssize,size,0);
make_legal(ap3,flags,size);
return ap3;
}
do_extend(ap1,ssize,size,0);
make_legal(ap1,flags,size);
}
return ap1;
}
AMODE *gen_aslogic(ENODE *node, int flags, int size, int op)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -