📄 gexpr68.c
字号:
if (ap->offset->nodetype != en_icon)
return FALSE;
v = ap->offset->v.i;
return (v >=-128 && v < 128);
}
int isambyte2(AMODE *ap, AMODE *ap2)
{
long v;
if (ap->offset->nodetype != en_icon || ap2->offset->nodetype != en_icon)
return FALSE;
v = ap->offset->v.i + ap2->offset->v.i;
return (v >=-128 && v < 128);
}
AMODE *gen_index(int siz1,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, *ap3, *ap;
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 (prm_68020 && (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 | F_AREG,4);
if (ap1->mode == am_immed) {
while (--scale)
ap1->offset->v.i <<=1;
}
else {
if (ap1->mode == am_dreg)
ap1->mode = am_baseindxdata;
else
ap1->mode = am_baseindxaddr;
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_INDX | F_DREG | F_AREG,4,FALSE);
switch (ap1->mode) {
case am_ainc:
case am_adec:
ap2 = temp_addr();
gen_lea(siz1,ap1,ap2);
freeop(ap1);
ap1 = ap2;
default:
rsold[rsodepth-1] = rsdepth;
break;
case am_baseindxdata:
case am_baseindxaddr:
if (ap1->sreg >=0 && ap1->preg >= 0) {
int t = rsold[rsodepth-1];
freeop(ap1);
ap3 = temp_addr();
gen_lea(siz1,ap1,ap3);
ap3->mode = am_ind;
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 (prm_68020 && (scale = node->v.p[1]->v.p[1]->v.i) < 4 && scale) {
if (node->v.p[1]->v.p[0]->nodetype == en_tempref)
ap2 = gen_expr(node->v.p[1]->v.p[0],F_IMMED | F_DREG | F_AREG,4);
if (ap2->mode == am_immed) {
while (--scale)
ap2->offset->v.i <<=1;
}
else {
if (ap2->mode == am_dreg)
ap2->mode = am_baseindxdata;
else
ap2->mode = am_baseindxaddr;
ap2->sreg = ap1->preg;
ap2->preg = -1;
ap2->scale = scale;
ap2->offset = makenode(en_icon,0,0);
}
break;
}
default: {
int flag = ap1->mode == am_areg || ap1->mode == am_ind ||
ap1->mode == am_indx || ap1->mode == am_baseindxaddr;
node2.v.p[0] = node->v.p[1];
node2.nodetype = node->nodetype;
mark();
ap2 = gen_deref(&node2,F_INDX | F_DREG | F_AREG,4,flag);
switch (ap1->mode) {
case am_ainc:
case am_adec:
ap3 = temp_addr();
gen_lea(siz1,ap2,ap3);
freeop(ap2);
ap2 = ap3;
default:
rsold[rsodepth-1] = rsdepth;
break;
case am_baseindxdata:
case am_baseindxaddr:
if (ap2->sreg >=0 && ap2->preg >= 0) {
int t = rsold[rsodepth-1];
freeop(ap2);
ap3 = temp_addr();
gen_lea(siz1,ap2,ap3);
ap3->mode = am_ind;
if (t <rsdepth-1 && ap3->preg + 8 == regstack[t+1])
t+=2;
if (t <rsdepth && ap3->preg + 8 == regstack[t])
t+=1;
ap2 = ap3;
}
}
release();
}
break;
}
tryagain:
switch(ap1->mode) {
case am_areg:
switch (ap2->mode) {
case am_areg:
ap1->sreg = ap2->preg;
ap1->mode = am_baseindxaddr;
ap1->offset = makenode(en_icon,0,0);
ap1->scale = 0;
return ap1;
case am_dreg:
ap1->sreg = ap2->preg;
ap1->mode = am_baseindxdata;
ap1->offset = makenode(en_icon,0,0);
ap1->scale = 0;
return ap1;
case am_adirect:
if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
ap1->mode = am_indx;
ap1->offset = ap2->offset;
return ap1;
}
ap = temp_addr();
gen_lea(0,ap2,ap);
ap1->mode = am_baseindxaddr;
ap1->offset = makenode(en_icon,0,0);
ap1->scale = 0;
ap1->sreg = ap->preg;
return ap1;
case am_immed:
if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
ap1->mode = am_indx;
ap1->offset = ap2->offset;
return ap1;
}
ap = temp_data();
gen_code(op_move,4,ap2,ap);
ap1->mode = am_baseindxdata;
ap1->offset = makenode(en_icon,0,0);
ap1->scale = 0;
ap1->sreg = ap->preg;
return ap1;
case am_indx:
if (prm_68020 || isambyte(ap2)) {
ap1->mode = am_baseindxaddr;
ap1->offset = ap2->offset;
ap1->scale = 0;
ap1->sreg = ap2->preg;
return ap1;
}
freeop(ap2);
ap = temp_addr();
gen_lea(0,ap2,ap);
ap->mode = am_baseindxaddr;
ap->sreg = ap1->preg;
ap->scale = 0;
ap->offset = makenode(en_icon,0,0);
return ap;
case am_ind:
ap1->mode = am_baseindxaddr;
ap1->offset = makenode(en_icon,0,0);
ap1->scale = 0;
ap1->sreg = ap2->preg;
return ap1;
case am_baseindxaddr:
case am_baseindxdata:
if (ap2->preg == -1) {
ap2->preg = ap1->preg;
return ap2;
}
freeop(ap2);
ap = temp_addr();
gen_lea(0,ap2,ap);
ap1->mode = am_baseindxaddr;
ap1->scale = 0;
ap1->offset = makenode(en_icon,0,0);
ap1->sreg = ap->preg;
return ap1;
}
break;
case am_dreg:
switch (ap2->mode) {
case am_areg:
ap2->sreg = ap1->preg;
ap2->mode = am_baseindxdata;
ap2->offset = makenode(en_icon,0,0);
ap2->scale = 0;
return ap2;
case am_dreg:
freeop(ap2);
ap = temp_addr();
gen_lea(0,ap1,ap);
ap->sreg = ap1->preg;
ap->mode = am_baseindxdata;
ap->offset = makenode(en_icon,0,0);
ap->scale = 0;
return ap;
case am_adirect:
if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
freeop(ap1);
ap = temp_addr();
gen_code(op_move,4,ap1,ap);
ap->mode = am_indx;
ap->offset = ap2->offset;
return ap;
}
ap = temp_addr();
gen_lea(0,ap2,ap);
ap->mode = am_baseindxdata;
ap->offset = makenode(en_icon,0,0);
ap->scale = 0;
ap->sreg = ap1->preg;
return ap;
case am_immed:
if (prm_68020 || isamshort(ap2)) {
freeop(ap1);
ap = temp_addr();
gen_code(op_move,4,ap1,ap);
ap->mode = am_indx;
ap->offset = ap2->offset;
return ap;
}
ap = temp_addr();
gen_code(op_move,0,ap2,ap);
ap->mode = am_baseindxdata;
ap->offset = makenode(en_icon,0,0);
ap->scale = 0;
ap->sreg = ap1->preg;
return ap;
case am_indx:
if (prm_68020 || isambyte(ap2)) {
ap2->mode = am_baseindxdata;
ap2->scale = 0;
ap2->sreg = ap1->preg;
return ap2;
}
freeop(ap2);
ap = temp_addr();
gen_lea(0,ap2,ap);
ap->mode = am_baseindxdata;
ap->sreg = ap1->preg;
ap->scale = 0;
ap->offset = makenode(en_icon,0,0);
return ap;
case am_ind:
ap2->mode = am_baseindxdata;
ap2->offset = makenode(en_icon,0,0);
ap2->scale = 0;
ap2->sreg = ap1->preg;
return ap2;
case am_baseindxaddr:
case am_baseindxdata:
if (ap2->preg == -1) {
ap = temp_addr();
gen_code(op_move,4,ap1,ap);
ap2->preg = ap->preg;
return ap2;
}
freeop(ap2);
ap = temp_addr();
gen_lea(0,ap2,ap);
ap->mode = am_baseindxdata;
ap->scale = 0;
ap->offset = makenode(en_icon,0,0);
ap->sreg = ap1->preg;
return ap;
}
break;
case am_adirect:
switch (ap2->mode) {
case am_areg:
if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
ap2->mode = am_indx;
ap2->offset = ap1->offset;
return ap2;
}
ap = temp_addr();
gen_lea(0,ap1,ap);
ap2->mode = am_baseindxaddr;
ap2->offset = makenode(en_icon,0,0);
ap2->scale = 0;
ap2->sreg = ap->preg;
return ap2;
case am_dreg:
if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
freeop(ap1);
ap = temp_addr();
gen_code(op_move,4,ap2,ap);
ap->mode = am_indx;
ap->offset = ap1->offset;
return ap;
}
ap = temp_addr();
gen_lea(0,ap1,ap);
ap->mode = am_baseindxdata;
ap->offset = makenode(en_icon,0,0);
ap->scale = 0;
ap->sreg = ap2->preg;
return ap;
case am_adirect:
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap1;
case am_immed:
ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
return ap1;
case am_indx:
if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
ap2->offset = makenode(en_add,ap2->offset,ap1->offset);
return ap2;
}
ap = temp_addr();
gen_lea(0,ap1,ap);
ap2->mode = am_baseindxaddr;
ap2->sreg = ap->preg;
ap2->scale = 0;
return ap2;
case am_ind:
if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
ap2->offset = ap1->offset;
ap2->mode = am_indx;
return ap2;
}
ap = temp_addr();
gen_lea(0,ap1,ap);
ap2->mode = am_baseindxaddr;
ap2->sreg = ap->preg;
ap2->scale = 0;
ap2->offset = makenode(en_icon,0,0);
return ap2;
case am_baseindxaddr:
case am_baseindxdata:
if (prm_68020) {
ap2->offset = makenode(en_add,ap2->offset,ap1->offset);
return ap2;
}
if (ap2->preg == -1) {
ap = temp_addr();
ap2->preg = ap->preg;
gen_lea(0,ap1,ap);
return ap2;
}
ap = temp_addr();
gen_lea(0,ap1,ap);
ap2->mode = am_baseindxaddr;
ap2->sreg = ap->preg;
ap2->scale = 0;
ap2->offset = makenode(en_icon,0,0);
return ap2;
}
break;
case am_immed:
switch (ap2->mode) {
case am_areg:
if (prm_68020 || isamshort(ap1)) {
ap2->mode = am_indx;
ap2->offset = ap1->offset;
return ap2;
}
ap = temp_data();
gen_code(op_move,4,ap1,ap);
ap2->mode = am_baseindxdata;
ap2->offset = makenode(en_icon,0,0);
ap2->scale = 0;
ap2->sreg = ap->preg;
return ap2;
case am_dreg:
if (prm_68020 || isamshort(ap1)) {
freeop(ap2);
ap = temp_addr();
gen_code(op_move,4,ap2,ap);
ap->mode = am_indx;
ap->offset = ap1->offset;
return ap;
}
ap = temp_addr();
gen_code(op_move,0,ap1,ap);
ap->mode = am_baseindxdata;
ap->offset = makenode(en_icon,0,0);
ap->scale = 0;
ap->sreg = ap2->preg;
return ap;
case am_adirect:
ap2->offset = makenode(en_add,ap2->offset,ap1->offset);
return ap2;
case am_immed:
if (prm_68020 || isamshort2(ap1,ap2)) {
ap1->offset->v.i += ap2->offset->v.i;
return ap1;
}
if (isamshort(ap1)) {
ap = temp_addr();
gen_code(op_move,4,ap2,ap);
ap->mode = am_indx;
ap->offset = ap1->offset;
return ap;
}
if (isamshort(ap2)) {
ap = temp_addr();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -