📄 inasm68.c
字号:
//-------------------------------------------------------------------------
static AMODE *asm_movemarg(AMODE *rv)
{
AMODE old = *rv;
int start, val = 0, i;
if (rv->mode == am_freg)
{
rv->mode = am_fmask;
while (TRUE)
{
if (lastst != minus)
{
val |= 1 << old.preg;
if (lastst != divide)
break;
getsym();
if (lastst != kw_asmreg)
{
asm_err(ERR_ANEEDFP);
return 0;
}
regimage = keyimage;
old.preg = regimage->regnum;
old.mode = regimage->regtype;
getsym();
}
else
{
getsym();
start = old.preg;
if (lastst != kw_asmreg)
{
asm_err(ERR_ANEEDFP);
return 0;
}
regimage = keyimage;
old.preg = regimage->regnum;
old.mode = regimage->regtype;
getsym();
if (old.mode != am_freg)
{
asm_err(ERR_ANEEDFP);
return 0;
}
if (start <= old.preg)
for (i = start; i <= old.preg; i++)
val |= 1 << i;
}
}
}
else
{
rv->mode = am_mask;
rv->offset = 0;
while (TRUE)
{
if (lastst != minus)
{
if (old.mode == am_areg)
val |= 0x100 << old.preg;
else
val |= 1 << old.preg;
if (lastst != divide)
break;
getsym();
if (lastst != kw_asmreg)
{
asm_err(ERR_ANEEDAD);
return 0;
}
regimage = keyimage;
old.preg = regimage->regnum;
old.mode = regimage->regtype;
getsym();
if (old.mode != am_dreg && old.mode != am_areg)
{
asm_err(ERR_ANEEDAD);
return 0;
}
}
else
{
int modetype = old.mode;
getsym();
start = old.preg;
if (lastst != kw_asmreg)
{
asm_err(ERR_ANEEDAD);
return 0;
}
regimage = keyimage;
old.preg = regimage->regnum;
old.mode = regimage->regtype;
getsym();
if (old.mode != am_dreg && old.mode != am_areg)
{
asm_err(ERR_ANEEDAD);
return 0;
}
if (modetype != old.mode)
{
asm_err(ERR_AREGMISMATCH);
return 0;
}
if (start <= old.preg)
for (i = start; i <= old.preg; i++)
if (old.mode == am_areg)
val |= 0x100 << i;
else
val |= 1 << i;
}
}
}
rv->offset = (void*)val;
return rv;
}
//-------------------------------------------------------------------------
static AMODE *asm_amode(void)
{
AMODE *rv = xalloc(sizeof(AMODE));
int sz = 0, seg = 0;
lastsym = 0;
switch (lastst)
{
case kw_asmreg:
regimage = keyimage;
rv->preg = regimage->regnum;
rv->mode = regimage->regtype;
sz = regimage->size;
getsym();
if (lastst == divide || lastst == minus)
{
if (!asm_movemarg(rv))
{
asm_err(ERR_AILLADDRESS);
return 0;
}
}
else if (lastst == colon)
{
AMODE *temp;
getsym();
if (rv->mode != am_dreg)
{
asm_err(ERR_AILLADDRESS);
return 0;
}
if (!need_dreg(&temp))
return 0;
rv->mode = am_divsl;
rv->sreg = temp->preg;
}
break;
case openpa:
case minus:
rv = asm_mem();
break;
case id:
doid: rv->mode = am_immed;
rv->offset = asm_ident();
if (rv->offset->nodetype == en_autocon || rv->offset->nodetype ==
en_autoreg)
{
asm_err(ERR_AUSELEA);
return 0;
}
break;
case hash:
getsym();
if (lastst == id)
goto doid;
if (lastst != minus && lastst != iconst && lastst != lconst &&
lastst != luconst && lastst != cconst)
{
asm_err(ERR_AMODEEXPECT);
return 0;
}
// FALL THROUGH
case iconst:
case iuconst:
case lconst:
case luconst:
case cconst:
rv->mode = am_immed;
rv->offset = makeintnode(en_icon, intexpr(0));
;
break;
default:
asm_err(ERR_AMODEEXPECT);
return 0;
}
if (rv)
rv->length = theSize;
return rv;
}
//-------------------------------------------------------------------------
static AMODE *getbf(void)
{
AMODE *rv = xalloc(sizeof(AMODE));
if (lastst != begin)
return 0;
getsym();
if (lastst == kw_asmreg)
{
rv->mode = am_bfreg;
if (keyimage->regtype != am_dreg)
return 0;
rv->preg = keyimage->regnum;
getsym();
if (lastst != colon)
return 0;
getsym();
if (lastst != kw_asmreg)
return 0;
if (keyimage->regtype != am_dreg)
return 0;
rv->sreg = keyimage->regnum;
getsym();
if (lastst != end)
return 0;
getsym();
}
else
{
rv->mode = am_bf;
rv->preg = intexpr(0);
if (lastst != colon)
return 0;
getsym();
rv->sreg = intexpr(0);
if (lastst != end)
return 0;
getsym();
}
return rv;
}
//-------------------------------------------------------------------------
enum e_op asm_op(void)
{
int op;
if (lastst != kw_asminst)
{
asm_err(ERR_AINVOP);
return - 1;
} op = keyimage->regtype;
getsym();
return op;
}
//-------------------------------------------------------------------------
static OCODE *make_ocode(AMODE *ap1, AMODE *ap2, AMODE *ap3)
{
OCODE *o = xalloc(sizeof(OCODE));
o->oper1 = ap1;
o->oper2 = ap2;
o->oper3 = ap3;
return o;
}
//-------------------------------------------------------------------------
static int noincdec(AMODE *ap)
{
if (ap->mode == am_ainc || ap->mode == am_adec)
{
asm_err(ERR_AILLADDRESS);
return 0;
}
return 1;
}
//-------------------------------------------------------------------------
static int dreg(AMODE *ap)
{
if (ap->mode != am_dreg)
{
asm_err(ERR_AILLADDRESS);
return 0;
}
return 1;
}
//-------------------------------------------------------------------------
static int vermode(AMODE *ap, int dok, int aok, int pcok, int immok)
{
switch (ap->mode)
{
case am_dreg:
if (dok)
return 1;
break;
case am_areg:
if (aok)
return 1;
break;
case am_pcindx:
case am_pcindxaddr:
case am_pcindxdata:
case am_iiprepca:
case am_iiprepcd:
case am_iipostpca:
case am_iipostpcd:
if (pcok)
return 1;
break;
case am_immed:
if (immok)
return 1;
break;
case am_baseindxaddr:
case am_baseindxdata:
case am_iimem:
case am_iiprea:
case am_iipred:
case am_iiposta:
case am_iipostd:
case am_indx:
case am_ainc:
case am_adec:
case am_direct:
case am_adirect:
case am_ind:
return 1;
default:
break;
}
asm_err(ERR_AILLADDRESS);
return 0;
}
//-------------------------------------------------------------------------
static OCODE *ope_negbcd(void)
{
AMODE *ap1, *ap2;
if (theSize && theSize != 1)
{
asm_err(ERR_AINVSIZE);
return 0;
}
ap1 = asm_amode();
if (!ap1)
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode();
if (!ap2)
return (OCODE*) - 1;
if (ap1->mode != ap2->mode || (ap1->mode != am_dreg && ap1->mode != am_adec)
)
return (OCODE*) - 1;
return make_ocode(ap1, ap2, 0);
}
//-------------------------------------------------------------------------
static OCODE *ope_addx(void)
{
AMODE *ap1, *ap2;
if (!intsize())
{
return 0;
}
if (!theSize)
theSize = 2;
ap1 = asm_amode();
if (!ap1)
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode();
if (!ap2)
return (OCODE*) - 1;
if (ap1->mode != ap2->mode || (ap1->mode != am_dreg && ap1->mode != am_adec)
)
return (OCODE*) - 1;
return make_ocode(ap1, ap2, 0);
}
//-------------------------------------------------------------------------
static OCODE *ope_math(void)
{
AMODE *ap1, *ap2;
if (!intsize())
return 0;
if (!theSize)
theSize = 2;
ap1 = asm_amode();
if (!ap1)
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode();
if (!ap2)
return (OCODE*) - 1;
if (ap2->mode == am_areg)
if (!wordsize())
return ;
if (ap2->mode == am_dreg || ap2->mode == am_areg)
{
if (!vermode(ap1, TRUE, TRUE, TRUE, TRUE))
return 0;
}
else if (ap1->mode == am_dreg || ap1->mode == am_immed)
{
if (!vermode(ap2, TRUE, TRUE, FALSE, FALSE))
return 0;
}
else
{
return (OCODE*) - 1;
}
return make_ocode(ap1, ap2, 0);
}
//-------------------------------------------------------------------------
static OCODE *ope_amath(void)
{
AMODE *ap1, *ap2;
if (!wordsize())
return 0;
ap1 = asm_amode();
if (!ap1)
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode();
if (!ap2)
return (OCODE*) - 1;
if (ap2->mode != am_areg)
{
asm_err(ERR_AAREGEXPECT);
return 0;
}
if (!vermode(ap1, TRUE, TRUE, TRUE, TRUE))
return 0;
return make_ocode(ap1, ap2, 0);
}
//-------------------------------------------------------------------------
static OCODE *ope_imath(void)
{
AMODE *ap1, *ap2;
if (!intsize())
return 0;
if (!theSize)
theSize = 2;
ap1 = asm_amode();
if (!ap1)
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode();
if (!ap2)
return (OCODE*) - 1;
if (ap1->mode != am_immed)
{
return (OCODE*) - 1;
}
if (!vermode(ap2, TRUE, FALSE, FALSE, FALSE))
return 0;
return make_ocode(ap1, ap2, 0);
}
//-------------------------------------------------------------------------
static OCODE *ope_qmath(void)
{
OCODE *oc = ope_imath();
if (!oc)
return (OCODE*) - 1;
if (!intsize())
return 0;
if (oc->oper1->offset->v.i < 1 || oc->oper1->offset->v.i > 8)
{
return (OCODE*) - 1;
}
return oc;
}
//-------------------------------------------------------------------------
static OCODE *ope_log(void)
{
AMODE *ap1, *ap2;
if (!intsize())
return 0;
if (!theSize)
theSize = 2;
ap1 = asm_amode();
if (!ap1)
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode();
if (!ap2)
return (OCODE*) - 1;
if (ap2->mode == am_dreg)
{
if (!vermode(ap1, TRUE, FALSE, TRUE, TRUE))
return 0;
}
else if (ap1->mode == am_dreg || ap1->mode == am_immed)
{
if (!vermode(ap2, FALSE, FALSE, FALSE, FALSE))
return 0;
}
else
{
return (OCODE*) - 1;
}
return make_ocode(ap1, ap2, 0);
}
//-------------------------------------------------------------------------
static OCODE *ope_ilog(void)
{
AMODE *ap1, *ap2;
if (!intsize())
return 0;
if (!theSize)
theSize = 2;
ap1 = asm_amode();
if (!ap1)
return (OCODE*) - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -