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

📄 gexpr386.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
                ap->scale = 0;
                ap->offset = makeintnode(en_icon, 0);
                ap->seg = ap2->seg;

                if (!ap->seg)
                    ap->seg = ap1->seg;
                return ap;
            }
            break;
        case am_direct:
        case am_immed:
            switch (ap2->mode)
            {
            case am_dreg:
                ap2->mode = am_indisp;
                ap2->offset = ap1->offset;
                if (!ap2->seg)
                    ap2->seg = ap1->seg;
                return ap2;
            case am_immed:
            case am_direct:
                if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype 
                    == en_icon)
                    ap1->offset->v.i += ap2->offset->v.i;
                else
                    ap1->offset = makenode(en_add, ap1->offset, ap2->offset);
                ap1->mode = am_direct;
                if (!ap1->seg)
                    ap1->seg = ap2->seg;
                return ap1;
            case am_indisp:
            case am_indispscale:
                if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype 
                    == en_icon)
                    ap2->offset->v.i += ap1->offset->v.i;
                else
                    ap2->offset = makenode(en_add, ap1->offset, ap2->offset);
                if (!ap2->seg)
                    ap2->seg = ap1->seg;
                return ap2;
            }
            break;
        case am_indisp:
            switch (ap2->mode)
            {
            case am_dreg:
                ap1->mode = am_indispscale;
                ap1->sreg = ap2->preg;
                ap1->scale = 0;
                if (!ap1->seg)
                    ap1->seg = ap2->seg;
                return ap1;
            case am_immed:
            case am_direct:
                if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype 
                    == en_icon)
                    ap1->offset->v.i += ap2->offset->v.i;
                else
                {
                    ap1->offset = makenode(en_add, ap1->offset, ap2->offset);
                }
                if (!ap1->seg)
                    ap1->seg = ap2->seg;
                return ap1;
            case am_indisp:
                ap1->mode = am_indispscale;
                ap1->sreg = ap2->preg;
                ap1->scale = 0;
                if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype 
                    == en_icon)
                    ap1->offset->v.i += ap2->offset->v.i;
                else
                    ap1->offset = makenode(en_add, ap1->offset, ap2->offset);
                if (!ap1->seg)
                    ap1->seg = ap2->seg;
                return ap1;
            case am_indispscale:
                if (ap2->preg ==  - 1)
                {
                    ap2->preg = ap1->preg;
                    if (ap1->offset->nodetype == en_icon && ap2->offset
                        ->nodetype == en_icon)
                        ap2->offset->v.i += ap1->offset->v.i;
                    else
                        ap2->offset = makenode(en_add, ap1->offset, ap2->offset)
                            ;
                    if (!ap2->seg)
                        ap2->seg = ap1->seg;
                    return ap2;
                }
                ap = indx_data(ap2);
                ap1->sreg = ap->preg;
                ap1->scale = 0;
                ap1->mode = am_indispscale;
                if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype 
                    == en_icon)
                    ap1->offset->v.i += ap2->offset->v.i;
                else
                    ap1->offset = makenode(en_add, ap1->offset, ap2->offset);
                if (!ap1->seg)
                    ap1->seg = ap2->seg;
                return ap1;
            }
            break;
        case am_indispscale:
            switch (ap2->mode)
            {
            case am_dreg:
                if (ap1->preg ==  - 1)
                {
                    ap1->preg = ap2->preg;
                    if (!ap1->seg)
                        ap1->seg = ap2->seg;
                    return ap1;
                }
                ap = indx_data(ap1);
                ap->sreg = ap2->preg;
                ap->scale = 0;
                ap->offset = ap1->offset;
                ap->seg = ap1->seg;
                if (!ap->seg)
                    ap->seg = ap2->seg;
                return ap;
            case am_immed:
            case am_direct:
                if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype 
                    == en_icon)
                    ap1->offset->v.i += ap2->offset->v.i;
                else
                    ap1->offset = makenode(en_add, ap1->offset, ap2->offset);
                if (!ap1->seg)
                    ap1->seg = ap2->seg;
                return ap1;
            case am_indisp:
                if (ap1->preg ==  - 1)
                {
                    ap1->preg = ap2->preg;
                    if (ap1->offset->nodetype == en_icon && ap2->offset
                        ->nodetype == en_icon)
                        ap1->offset->v.i += ap2->offset->v.i;
                    else
                        ap1->offset = makenode(en_add, ap1->offset, ap2->offset)
                            ;
                    if (!ap1->seg)
                        ap1->seg = ap2->seg;
                    return ap1;
                }
                ap = indx_data(ap1);
                ap->sreg = ap2->preg;
                ap->scale = 0;
                ap->mode = am_indispscale;
                ap->seg = ap2->seg;
                if (ap1->offset->nodetype == en_icon && ap2->offset->nodetype 
                    == en_icon)
                    ap->offset->v.i = ap2->offset->v.i + ap1->offset->v.i;
                else
                    ap->offset = makenode(en_add, ap1->offset, ap2->offset);
                if (!ap->seg)
                    ap->seg = ap2->seg;
                return ap;
            case am_indispscale:
                if (ap1->preg ==  - 1 && ap2->preg ==  - 1)
                {
                    if (ap1->scale == 0)
                    {
                        ap2->preg = ap1->sreg;
                        if (ap1->offset->nodetype == en_icon && ap2->offset
                            ->nodetype == en_icon)
                            ap2->offset->v.i += ap1->offset->v.i;
                        else
                            ap2->offset = makenode(en_add, ap1->offset, ap2
                                ->offset);
                        if (!ap2->seg)
                            ap2->seg = ap1->seg;
                        return ap2;
                    }
                    else if (ap2->scale == 0)
                    {
                        ap1->preg = ap2->sreg;
                        if (ap1->offset->nodetype == en_icon && ap2->offset
                            ->nodetype == en_icon)
                            ap1->offset->v.i += ap2->offset->v.i;
                        else
                            ap1->offset = makenode(en_add, ap1->offset, ap2
                                ->offset);
                        if (!ap1->seg)
                            ap1->seg = ap2->seg;
                        return ap1;
                    }
                }
                if (ap1->preg ==  - 1)
                {
                    ap = indx_data(ap2);
                    ap1->preg = ap->preg;
                    if (!ap1->seg)
                        ap1->seg = ap2->seg;
                    return ap1;
                }
                else if (ap2->preg ==  - 1)
                {
                    ap = indx_data(ap1);
                    ap2->preg = ap->preg;
                    if (!ap2->seg)
                        ap2->seg = ap1->seg;
                    return ap2;
                }
                ap = indx_data(ap1);
                ap1 = indx_data(ap2);
                ap->mode = am_indispscale;
                ap->sreg = ap1->preg;
                ap->scale = 0;
                ap->offset = makeintnode(en_icon, 0);
                ap->seg = ap1->seg;
                if (!ap->seg)
                    ap->seg = ap2->seg;

                return ap;
            }
            break;
    }
    DIAG("invalid index conversion");
    return 0;
}

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

AMODE *gen_deref(ENODE *node, int size)
/*
 *      return the addressing mode of a dereferenced node.
 */
{
    AMODE *ap1;
    int siz1;
    switch (node->nodetype) /* get load size */
    {
        case en_substack:
        case en_structret:
            siz1 = BESZ_DWORD ;
            break;
        case en_fp_ref:
            siz1 =  BESZ_FARPTR;
            break;
        case en_ub_ref:
            siz1 = BESZ_BYTE;
            break;
        case en_b_ref:
            siz1 =  - 1;
            break;
        case en_bool_ref:
            siz1 = BESZ_BOOL;
            break;
        case en_uw_ref:
            siz1 = BESZ_WORD;
            break;
        case en_w_ref:
            siz1 =  - BESZ_WORD;
            break;
        case en_l_ref:
		case en_i_ref:
		case en_a_ref:
            siz1 =  - BESZ_DWORD;
            break;

        case en_ul_ref:
		case en_ui_ref:
		case en_ua_ref:
            siz1 = BESZ_DWORD;
            break;
        case en_ull_ref:
            siz1 = BESZ_QWORD;
            break;
        case en_ll_ref:
            siz1 =  - BESZ_QWORD;
            break;
        case en_floatref:
            siz1 = BESZ_FLOAT;
            break;
        case en_doubleref:
            siz1 = BESZ_DOUBLE;
            break;
        case en_longdoubleref:
            siz1 = BESZ_LDOUBLE;
            break;
        case en_fimaginaryref:
            siz1 = BESZ_IFLOAT;
            break;
        case en_rimaginaryref:
            siz1 = BESZ_IDOUBLE;
            break;
        case en_lrimaginaryref:
            siz1 = BESZ_ILDOUBLE;
            break;
        case en_fcomplexref:
            siz1 = BESZ_CFLOAT;
            break;
        case en_rcomplexref:
            siz1 = BESZ_CDOUBLE;
            break;
        case en_lrcomplexref:
            siz1 = BESZ_CLDOUBLE;
            break;
        default:
            siz1 = BESZ_DWORD ;
    }
    if (node->v.p[0]->nodetype == en_add || node->v.p[0]->nodetype ==
        en_addstruc)
    {
        ap1 = gen_index(node->v.p[0]);
        ap1->length = siz1;
        return ap1;
    }
    else if (node->v.p[0]->nodetype == en_autocon || node->v.p[0]->nodetype ==
        en_autoreg)
    {
        SYM *sp = node->v.p[0]->v.sp;
        int i = sp->value.i;
        ap1 = xalloc(sizeof(AMODE));
        ap1->mode = am_indisp;
        ap1->preg = EBP;
        //                if (prm_farkeyword)
            //								if ((currentfunc->value.classdata.cppflags & PF_MEMBER) &&
            //											!(currentfunc->value.classdata.cppflags & PF_STATIC) && i > 0)
            //									i += 4;
        ap1->offset = makeintnode(en_icon, i);
        ap1->length = siz1;
        return ap1;
    }
    else if (node->v.p[0]->nodetype == en_nacon || node->v.p[0]->nodetype ==
        en_napccon)
    {
        ap1 = xalloc(sizeof(AMODE));
        ap1->offset = makenode(node->v.p[0]->nodetype, (void*)node->v.p[0]
            ->v.sp, 0);
        ap1->mode = am_direct;
        ap1->length = siz1;
        return ap1;
    }
    else if (node->v.p[0]->nodetype == en_nalabcon)
    {
        ap1 = xalloc(sizeof(AMODE));
        ap1->offset = makenode(node->v.p[0]->nodetype, node->v.p[0]->v.sp, 0);
        ap1->mode = am_direct;
        ap1->length = siz1;
        return ap1;
    }
    else if (node->v.p[0]->nodetype == en_labcon)
    {
        ap1 = xalloc(sizeof(AMODE));
        ap1->mode = am_direct;
        ap1->offset = makeintnode(node->v.p[0]->nodetype, node->v.p[0]->v.i);
        ap1->length = siz1;
        return ap1;
    }
    else if (node->v.p[0]->nodetype == en_absacon)
    {
        ap1 = xalloc(sizeof(AMODE));
        ap1->mode = am_direct;
        ap1->seg = 0;
        ap1->offset = makeintnode(en_absacon, node->v.p[0]->v.sp->value.i);
        ap1->length = siz1;
        return ap1;

    }
    else if (node->v.p[0]->nodetype == en_regref)
    {
        ap1 = gen_expr(node->v.p[0], FALSE, TRUE, siz1);
        return ap1;
    }
    ap1 = gen_expr(node->v.p[0], FALSE, TRUE, BESZ_DWORD ); /* generate address */
    if (prm_farkeyword && ap1->mode == am_axdx)
    {
        AMODE *ap2 = makedreg(0);
        ap2->seg = temp_seg();
        ap2->mode = am_seg;
        gen_codes(op_mov, BESZ_WORD, ap2, makedreg(EDX));
        ap1->mode = am_dreg;
        ap1->seg = ap2->seg;
    }
    else if (ap1->mode != am_immed)
    {
        do_extend(ap1, BESZ_DWORD , F_DREG);
    }
    ap1->length = siz1;
    if (ap1->mode == am_dreg)
    {
        ap1->mode = am_indisp;
        ap1->offset = makeintnode(en_icon, 0);
        //                ap1->seg = defseg(node->v.p[0]) ;
        return ap1;
    }
    else if (ap1->mode == am_stackedtemp)
    {
        ap1->mode = am_stackedtempaddr;
        if (prm_farkeyword)
            ap1->seg = SS;
        return ap1;
    }
    ap1->mode = am_direct;
    return ap1;
}

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

void get_size(AMODE *ap1, AMODE *ap2, int size, int flags)
{
    if (size > BESZ_QWORD)
        size = BESZ_DWORD ;
    if (chksize(size, ap1->length))
    {
        if (!chksize(size, ap2->length))
            size = ap2->length;
    }
    else
        if (chksize(ap1->length, ap2->length))
            size = ap1->length;
        else
            size = ap2->length;
    if (((ap1->length > 0 || 

⌨️ 快捷键说明

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