⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inasm68.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    return 1;
}

//-------------------------------------------------------------------------

int asm_enterauto(ENODE *node, int inbr, int *rinbr, int *reg1, int *reg2, int
    *rt1, int *rt2)
{
    if (node && ((node)->nodetype == en_autocon || (node)->nodetype ==
        en_autoreg))
    {
        if (*reg1 >= 0 &&  *reg2 >= 0)
        {
            asm_err(ERR_AINVINDXMODE);
            return 0;
        }
        if (reg1 < 0)
        {
            *reg1 = 7;
            if (prm_linkreg)
                *reg1 = linkreg;
            *rt1 = am_areg;
        }
        else
        {
            if (inbr)
                *rinbr = 1;
            *reg2 = 7;
            if (prm_linkreg)
                *reg2 = linkreg;
            *rt2 = am_areg;
        }
        return 1;
    }
    return 2;
}

//-------------------------------------------------------------------------

static AMODE *asm_mem(void)
{
    int reg1 =  - 1, reg2 =  - 1, scale = 1, temp, inbr = 0, usebr = 0;
    int rinbr = 0, rg1t = 0, rg2t = 0, thisscale = 0;
    int scalesize = 0;
    ENODE *node = 0,  *node0 = 0,  *node1 = 0;
    AMODE *rv;
    int gotident = FALSE, autonode = FALSE;
    if (lastst == minus)
    {
        getsym();
        if (lastst != openpa)
        {
            asm_err(ERR_AMODEEXPECT);
            return 0;
        }
        getsym();
        if (lastst != kw_asmreg || keyimage->regtype != am_areg)
        {
            asm_err(ERR_AAREGEXPECT);
            return 0;
        }
        regimage = keyimage;
        getsym();
        if (lastst != closepa)
        {
            asm_err(ERR_AMODEEXPECT);
            return 0;
        }
        rv = xalloc(sizeof(AMODE));
        rv->mode = am_adec;
        rv->preg = regimage->regnum;
        getsym();
        return rv;
    }
    getsym();
    if (lastst == openbr)
    {
        if (!prm_68020)
        {
            asm_err(ERR_AINVSELPROC);
            return 0;
        }
        inbr = 1;
        usebr = 1;
        getsym();
    }
    while (TRUE)
    {
        int rg;
        regimage = keyimage;
        if (regimage)
            rg = regimage->regnum;
        switch (lastst)
        {
            case closebr:
                if (!inbr)
                {
                    asm_err(ERR_AINVINDXMODE);
                    return 0;
                }
                inbr = 0;
                getsym();
                break;

            case kw_asmreg:
                getsym();
                scalesize = asm_getsize();
                if (scalesize != 0 && scalesize != 2 && scalesize != 4)
                {
                    asm_err(ERR_AINVINDXMODE);
                    return 0;
                }

                if (lastst == star)
                {
                    getsym();
                    scale = intexpr(0);

                    thisscale = 1;
                }
                if (inbr)
                {
                    if (reg1 ==  - 1 && thisscale)
                    {
                        asm_err(ERR_AMODEEXPECT);
                        return 0;
                    }
                    if (reg2 !=  - 1)
                    {
                        asm_err(ERR_ATOOMANYREGS);
                        return 0;
                    }
                    if (reg1 ==  - 1)
                    {
                        if (regimage->regtype != am_areg && regimage->regtype 
                            != am_pc)
                        {
                            asm_err(ERR_AAREGEXPECT);
                            return 0;
                        }
                        reg1 = rg;
                        rg1t = regimage->regtype;
                    }
                    else
                    {
                        rinbr = 1;
                        reg2 = rg;
                        rg2t = regimage->regtype;
                    }
                }
                else
                {
                    if (reg1 ==  - 1 && !usebr)
                    {
                        if (thisscale)
                        {
                            if (reg2 !=  - 1)
                            {
                                asm_err(ERR_ATOOMANYREGS);
                                return 0;
                            }
                            reg2 = rg;
                            rg2t = regimage->regtype;

                        }
                        else
                        {
                            reg1 = rg;
                            rg1t = regimage->regtype;
                        }
                    }
                    else
                    {
                        if (reg2 !=  - 1)
                        {
                            asm_err(ERR_ATOOMANYREGS);
                            return 0;
                        }
                        rg2t = regimage->regtype;
                        reg2 = rg;
                    }
                }
                break;
            case plus:
            case minus:
            case iconst:
                if (usebr)
                {
                    if (inbr)
                    {
                        if (node0)
                        {
                            asm_err(ERR_AINVINDXMODE);
                            return 0;
                        }
                        node0 = makeintnode(en_icon, intexpr(0));
                    }
                    else
                    {
                        if (node1)
                        {
                            asm_err(ERR_AINVINDXMODE);
                            return 0;
                        }
                        node1 = makeintnode(en_icon, intexpr(0));
                    }
                }
                else
                    if (!node0)
                        node0 = makeintnode(en_icon, intexpr(0));
                    else
                        if (!node1)
                            node1 = makeintnode(en_icon, intexpr(0));
                        else
                {
                    asm_err(ERR_AINVINDXMODE);
                    return 0;
                }
                break;
            case id:
                if (gotident)
                {
                    asm_err(ERR_AINVINDXMODE);
                    return 0;
                }
                node = asm_ident();
                if (lastst == plus)
                {
                    getsym();
                    node = makenode(en_add, node, makeintnode(en_icon, intexpr
                        (0)));
                }
                gotident = TRUE;
                switch (asm_enterauto(node, inbr, &rinbr, &reg1, &reg2, &rg1t,
                    &rg2t))
                {
                case 0:
                    return 0;
                case 1:
                    autonode = TRUE;
                    break;
                case 2:
                    autonode = FALSE;
                    break;
                }
                if (usebr)
                {
                    if (inbr)
                    {
                        if (node0)
                        {
                            asm_err(ERR_AINVINDXMODE);
                            return 0;
                        }
                        node0 = node;
                    }
                            else
                    {
                        if (node1)
                        {
                            asm_err(ERR_AINVINDXMODE);
                            return 0;
                        }
                        node1 = node;
                    }
                }
                        else
                            if (!node0)
                                node0 = node;
                            else
                                if (!node1)
                                    node1 = node;
                                else
                {
                    asm_err(ERR_AINVINDXMODE);
                    return 0;
                }
                break;
            default:
                asm_err(ERR_AILLADDRESS);
                return 0;
        }
        if (lastst == begin)
            break;
        if (lastst == closepa)
        {
            getsym();
            break;
        }
        if (lastst == closebr)
            continue;
        if (lastst != comma)
        {
            asm_err(ERR_AINVINDXMODE);
            return 0;
        }
        getsym();
    }
    if (rg2t == am_pc && scale != 1)
    {
        asm_err(ERR_AINVINDXMODE);
        return 0;
    }
    /* swap to get dreg in second pos */
    if (((reg1 !=  - 1 && rg1t == am_dreg) && reg2 !=  - 1 && scale == 1) ||
        rg2t == am_pc)
    {
        int rg3t = rg1t;
        int reg3 = reg1;
        reg2 = reg1;
        rg2t = rg1t;
        reg1 = reg3;
        rg1t = rg3t;
    }
    if (!prm_68020)
    {
        if (reg1 ==  - 1 && reg2 ==  - 1 && (node1 || !node0))
        {
            asm_err(ERR_AINVSELPROC);
            return 0;
        }
        if (reg1 ==  - 1 && reg2 !=  - 1 && (rg2t != am_areg || scale != 1))
        {
            asm_err(ERR_AINVSELPROC);
            return 0;
        }
    }
    if (reg1 ==  - 1 && reg2 ==  - 1 && !node0)
    {
        asm_err(ERR_AINVINDXMODE);
        return 0;
    }

    if (scale != 1 && scale != 2 && scale != 4 && scale != 8)
    {
        asm_err(ERR_ASCALE);
        return 0;
    }
    if (scale == 1)
        scale = 0;
    else if (scale == 2)
        scale = 1;
    else if (scale == 4)
        scale = 2;
    else if (scale == 8)
        scale = 3;
    if (rg1t == am_dreg)
    {
        asm_err(ERR_AAREGEXPECT);
        return 0;
    }
    if (node1 && !usebr)
    {
        asm_err(ERR_AINVINDXMODE);
        return 0;
    }
    rv = xalloc(sizeof(AMODE));
    if (node1)
    {
        rv->offset = node1;
    }
    rv->preg = reg1;
    rv->sreg = reg2;
    rv->scale = scale;
    if (usebr)
    {
        if (!node0)
            rv->offset = makeintnode(en_icon, 0);
        else
            rv->offset = node0;
        if (!node1)
            rv->offset2 = makeintnode(en_icon, 0);
        else
            rv->offset2 = node1;
        rv->sz = scalesize;
        if (rinbr)
        {
            if (reg1 ==  - 1 && reg2 ==  - 1)
                rv->mode = am_iimem;
            else
            if (reg1 !=  - 1)
            {
                if (reg2 !=  - 1)
                {
                    if (rg1t == am_pc)
                    {
                        if (rg2t == am_areg)
                            rv->mode = am_iiprepca;
                        else
                            rv->mode = am_iiprepcd;
                    }
                    else
                        if (rg2t == am_areg)
                            rv->mode = am_iiprea;
                        else
                            rv->mode = am_iipred;

                }
                else
                    if (rg1t == am_pc)
                        rv->mode = am_iiprepca;
                    else
                        rv->mode = am_iiprea;
            }
            else
                if (rg2t == am_areg)
                    rv->mode = am_iiprea;
                else
                    rv->mode = am_iipred;
        }
        else
        {
            if (reg1 ==  - 1 && reg2 ==  - 1)
                rv->mode = am_iimem;
            else
            if (reg1 !=  - 1)
            {
                if (reg2 !=  - 1)
                {
                    if (rg1t == am_pc)
                    {
                        if (rg2t == am_areg)
                            rv->mode = am_iipostpca;
                        else
                            rv->mode = am_iipostpcd;
                    }
                    else
                        if (rg2t == am_areg)
                            rv->mode = am_iiposta;
                        else
                            rv->mode = am_iipostd;
                }
                else
                    if (rg1t == am_pc)
                        rv->mode = am_iipostpca;
                    else
                        rv->mode = am_iiposta;
            }
            else
                if (rg2t == am_areg)
                    rv->mode = am_iiposta;
                else
                    rv->mode = am_iipostd;
        }
    }
    else
    {
        if (reg1 !=  - 1)
        {
            if (reg2 !=  - 1)
            {
                if (!node0)
                    rv->offset = makeintnode(en_icon, 0);
                else
                    rv->offset = node0;
                if (rg1t == am_pc)
                {
                    if (rg2t == am_areg)
                        rv->mode = am_pcindxaddr;
                    else
                        rv->mode = am_pcindxdata;
                }
                else
                    if (rg2t == am_areg)
                        rv->mode = am_baseindxaddr;
                    else
                        rv->mode = am_baseindxdata;
                rv->sz = scalesize;
                if (rv->mode == am_immed && (rv->offset->v.i &0xffff0000) &&
                    !prm_68020)
                    generror(ERR_AINVSELPROC, 0, 0);
            }
            else
            {
                if (!node0)
                {
                    rv->offset = makeintnode(en_icon, 0);
                    if (rg1t == am_pc)
                    {
                        rv->mode = am_pcindx;
                    }
                    else
                    if (lastst == plus)
                    {
                        getsym();
                        rv->mode = am_ainc;
                    }
                    else
                        rv->mode = am_ind;
                }
                else
                {
                    rv->offset = node0;
                    if (rg1t == am_pc)
                        rv->mode = am_pcindx;
                    else
                    {
                        rv->mode = am_indx;
                    }
                    if (rv->mode == am_immed && (rv->offset->v.i &0xffff0000)
                        && !prm_68020)
                        generror(ERR_AINVSELPROC, 0, 0);
                }
            }
        }
        else if (reg2 !=  - 1)
        {
            if (!node0)
                rv->offset = makeintnode(en_icon, 0);
            else
                rv->offset = node0;
            if (rg2t == am_areg)
                rv->mode = am_baseindxaddr;
            else
                rv->mode = am_baseindxdata;
            rv->sz = scalesize;
            if (rv->mode == am_immed && (rv->offset->v.i &0xffff0000) &&
                !prm_68020)
                generror(ERR_AINVSELPROC, 0, 0);

        }
        else
        {
            rv->mode = am_adirect;
            rv->preg = asm_getsize();
            rv->offset = node0;
            if (!rv->length)
                if (prm_smalldata)
                    rv->length = 2;
                else
                    rv->length = 4;
        }
    }
    return rv;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -