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

📄 gstmt386.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
    {
        if (retlab !=  - 1)
            gen_label(retlab);
        if (flag &2)
        {
            return ap;
        }
        if (currentfunc->value.classdata.eofdest)
        {
            if (returndreg)
            {
                if (currentfunc->tp->btp->type == bt_longlong || currentfunc
                    ->tp->btp->type == bt_unsignedlonglong)
                    gen_codes(op_push, BESZ_DWORD , makedreg(2), 0);
                gen_codes(op_push, BESZ_DWORD , makedreg(0), 0);

            }
            gen_expr(currentfunc->value.classdata.eofdest, TRUE, FALSE, 0);
            if (returndreg)
            {
                gen_codes(op_pop, BESZ_DWORD , makedreg(0), 0);
                if (currentfunc->tp->btp->type == bt_longlong || currentfunc
                    ->tp->btp->type == bt_unsignedlonglong)
                    gen_codes(op_pop, BESZ_DWORD , makedreg(2), 0);
            }

        }
        if ((conscount || try_block_list || currentfunc
            ->value.classdata.throwlist && currentfunc
            ->value.classdata.throwlist->data) && prm_xcept)
            call_library("__RundownExceptBlock");
        if (fsave_mask != 0)
            diag("Float restore in return");
        if (currentfunc->loadds && !currentfunc->intflag)
            gen_code(op_pop, makesegreg(DS), 0);
        if (save_mask != 0)
            popregs(save_mask);
        if (prm_cplusplus && prm_xcept || (funcfloat || lc_maxauto ||
            currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM*) -
            1)
             || (currentfunc->value.classdata.cppflags &PF_MEMBER) && !
                 (currentfunc->value.classdata.cppflags &PF_STATIC)
         || !prm_smartframes)
        {
            /* LEAVE is a little faster in simple tests, but since this version
             * can be paired with other instructions on later processors we
             * do it this way.  Also don't reload ESP if no local vars...
             */
            if (funcfloat || lc_maxauto)
                gen_code(op_mov, makedreg(ESP), makedreg(EBP));
            else
                initstack();
            if (!currentfunc->intflag)
                gen_code(op_pop, makedreg(EBP), 0);
        }
        if (currentfunc->intflag || currentfunc->faultflag)
        {
            gen_codes(op_popad, 0, 0, 0);
            if (prm_farkeyword)
            {
                gen_pop(GS + 24, am_dreg, 0);
                gen_pop(FS + 24, am_dreg, 0);
                gen_pop(ES + 24, am_dreg, 0);
            }
        }
        if (currentfunc->loadds && currentfunc->intflag)
            gen_code(op_pop, makesegreg(DS), 0);
        if (currentfunc->faultflag)
        {
            gen_codes(op_add, BESZ_DWORD , makedreg(ESP), make_immed(4));
            gen_codes(op_iretd, 0, 0, 0);
        }
        if (currentfunc->intflag)
        {
            gen_codes(op_iretd, 0, 0, 0);
        }
        else
        {
            int retop = op_ret;
            if (currentfunc->farproc)
                retop = op_retf;
            if (currentfunc->pascaldefn || currentfunc->isstdcall)
            {
                long retsize = 0;
                if (currentfunc->tp->lst.head && currentfunc->tp->lst.head != 
                    (SYM*) - 1)
                {
                    retsize = currentfunc->paramsize - 8;
                }
                if (currentfunc->tp->btp && isstructured(currentfunc->tp->btp))
                    retsize += 4;
                if (currentfunc->farproc)
                    retsize -= 4;
                if (retsize)
                {
                    gen_codes(retop, 0, make_immed(retsize), 0);
                    return 0;
                }
            }
            gen_codes(retop, 0, 0, 0);
        }
    }
    else
    {
        gen_codes(op_jmp, 0, make_label(retlab), 0);
    }
    return 0;
}

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

void gen_tryblock(void *val)
{
    AMODE *ap1 = xalloc(sizeof(AMODE));
    ap1->mode = am_indisp;
    ap1->preg = EBP;
    ap1->offset = makeintnode(en_icon,  - xceptoffs + 12); // ESP
    switch ((int)val)
    {
        case 0:
            // begin try
            gen_codes(op_push, BESZ_DWORD , makedreg(EBX), 0);
            gen_codes(op_push, BESZ_DWORD , makedreg(ESI), 0);
            gen_codes(op_push, BESZ_DWORD , makedreg(EDI), 0);
            gen_codes(op_push, BESZ_DWORD , ap1, 0);
            gen_codes(op_mov, BESZ_DWORD , ap1, makedreg(ESP));
            break;
        case 1:
            // begin catch
            gen_codes(op_mov, BESZ_DWORD , makedreg(ESP), ap1);
            gen_codes(op_pop, BESZ_DWORD , ap1, 0);
            gen_codes(op_pop, BESZ_DWORD , makedreg(EDI), 0);
            gen_codes(op_pop, BESZ_DWORD , makedreg(ESI), 0);
            gen_codes(op_pop, BESZ_DWORD , makedreg(EBX), 0);
            break;
        case 2:
            // end try
            gen_codes(op_mov, BESZ_DWORD , makedreg(ESP), ap1);
            gen_codes(op_pop, BESZ_DWORD , ap1, 0);
            gen_codes(op_add, BESZ_DWORD , makedreg(ESP), make_immed(3 *4));
            break;
    }
}

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

void genstmt(SNODE *stmt)
/*
 *      genstmt will generate a statement and follow the next pointer
 *      until the block is generated.
 */
{
    while (stmt != 0)
    {
        OCODE *result;
        switch (stmt->stype)
        {
            case st_case:
                if ((int)stmt->label >= 0)
                    gen_label((int)stmt->label);
                break;
            case st_block:
                result = gen_codes(op_blockstart, 0, 0, 0);
                result->blocknum = (int)stmt->label;
                genstmt(stmt->exp);
                result = gen_codes(op_blockend, 0, 0, 0);
                result->blocknum = (int)stmt->label;
                break;
            case st_label:
                gen_label((int)stmt->label);
                break;
            case st_goto:
                gen_codes(op_jmp, 0, make_label((int)stmt->label), 0);
                break;
            case st_tryblock:
                initstack(); // important!!!
                gen_tryblock(stmt->label);
                break;
            case st_expr:
                gen_void(stmt->exp);
                initstack();
                break;
            case st_return:
                genreturn(stmt, 0);
                break;
            case st_if:
                genif(stmt);
                break;
            case st_while:
                genwhile(stmt);
                break;
            case st_do:
                gendo(stmt);
                break;
            case st_for:
                gen_for(stmt);
                break;
            case st_continue:
                gen_codes(op_jmp, 0, make_label(contlab), 0);
                break;
            case st_break:
                gen_codes(op_jmp, 0, make_label(breaklab), 0);
                break;
            case st_switch:
                genxswitch(stmt);
                break;
            case st_line:
                gen_line(stmt);
                break;
            case st_asm:
                if (stmt->exp)
                    add_peep(stmt->exp);
                break;
            case st__genword:
                gen_codes(op_genword, 0, make_immed((int)stmt->exp), 0);
                break;
            default:

                DIAG("unknown statement.");
                break;
        }
        stmt = stmt->next;
    }
}

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

    void scppinit(void)
    /*
     * code in MAIN to execute C++ startup routines
     * it is safe to do it in MAIN since you cannot call main or take its address
     *
     */
    {
        #ifdef OLD
            if (!strcmp(currentfunc->name, "_main"))
            {
                AMODE *ap1,  *ap2,  *ap3,  *ap4;
                int lbl = nextlabel++;
                initstack();
                ap1 = makedreg(ESI);
                ap4 = makedreg(EAX);
                ap2 = set_symbol("cppistart", 0);
                ap3 = set_symbol("cppiend", 0);
                gen_code(op_push, ap1, 0);
                gen_code(op_mov, ap1, ap2);
                gen_label(lbl);
                gen_code(op_lodsd, 0, 0);
                gen_code(op_call, ap4, 0);
                gen_codes(op_cmp, BESZ_DWORD , ap1, ap3);
                gen_code(op_jb, make_label(lbl), 0);
                gen_code(op_pop, ap1, 0);
                freeop(ap1);
            }
        #endif 
    }
    SYM *gen_mp_virtual_thunk(SYM *vsp)
    {
        LIST *v = mpthunklist;
        SYM *sp;
        AMODE *ap1,  *ap2;
        char buf[256];
        while (v)
        {
            sp = (SYM*)v->data;
            if (sp->value.i == vsp->value.classdata.vtabindex)
                if (isstructured(vsp->tp->btp) == isstructured(sp->tp->btp))
                    return sp;
            v = v->link;
        }
        global_flag++;
        sp = makesym(sc_static);
        sp->tp = vsp->tp;
        sp->value.i = vsp->value.classdata.vtabindex;
        sprintf(buf, "@$mpt$%d$%d", sp->value.i, isstructured(sp->tp->btp));
        sp->name = litlate(buf);
        sp->staticlabel = FALSE;
        v = xalloc(sizeof(LIST));
        v->data = sp;
        v->link = mpthunklist;
        mpthunklist = v;
        global_flag--;
        //   gen_codelab(sp) ;
        gen_virtual(sp, FALSE);
        ap1 = makedreg(ESP);
        ap1->mode = am_indisp;
        ap1->offset = makeintnode(en_icon, isstructured(sp->tp->btp) ? 8 : 4);
        gen_codes(op_mov, BESZ_DWORD , makedreg(EAX), ap1);
        ap1->preg = 0;
        if (sp->value.classdata.vtaboffs)
            ap1->offset = makeintnode(en_icon, sp->value.classdata.vtaboffs);
        else
            ap1->offset = makeintnode(en_icon, 0);
        gen_codes(op_mov, BESZ_DWORD , makedreg(EAX), ap1);
        ap1->offset = makeintnode(en_icon, sp->value.i);
        gen_codes(op_jmp, BESZ_DWORD , ap1, 0);
        flush_peep();
        gen_endvirtual(sp);
        return sp;
    }
    SYM *gen_vsn_virtual_thunk(SYM *func, int ofs)
    {
        SYM *sp;
        AMODE *ap1,  *ap2;
        char buf[256];
        global_flag++;
        sp = makesym(sc_static);
        sp->value.i = ofs;
        sprintf(buf, "@$vsn%s$%d", func->name, sp->value.i);
        sp->name = litlate(buf);
        sp->staticlabel = FALSE;
        sp->tp = func->mainsym; // strange use of the TP field here 
        global_flag--;
        gen_virtual(sp, FALSE);
        ap1 = makedreg(ESP);
        ap1->mode = am_indisp;
        ap1->offset = makeintnode(en_icon, BESZ_DWORD );
        gen_codes(op_add, BESZ_DWORD , ap1, make_immed( - ofs));
        ap2 = xalloc(sizeof(AMODE));
        ap2->offset = makenode(en_napccon, (void*)func, 0);
        ap2->mode = am_immed;
        gen_codes(op_jmp, BESZ_DWORD , ap2, 0);
        flush_peep();
        gen_endvirtual(sp);
        return sp;

    }
void genfunc(SNODE *stmt)
/*
 *      generate a function body.
 */
{
    //int isconst = FALSE;
    cseg();
    currentfunc->gennedvirtfunc = (virtualfuncs || (currentfunc
        ->value.classdata.cppflags &(PF_HEADERFUNC | PF_INSTANTIATED)));
    if (currentfunc->storage_class == sc_global && !(currentfunc
        ->value.classdata.cppflags &PF_INLINE))
        if (!currentfunc->gennedvirtfunc)
            globaldef(currentfunc);
    returndreg = FALSE;
    retsize = 0;
    contlab = breaklab =  - 1;
    retlab = nextlabel++;
    startlab = nextlabel++;
    funcfloat = 0;
    if (funcstmt)
        gen_line(funcstmt);
    funcstmt = 0;
        if (currentfunc->gennedvirtfunc)
            gen_virtual(templateSP ? templateSP : currentfunc, FALSE);
        else
        gen_codelab(currentfunc);
     /* name of function */

    opt1(stmt); /* push args & also subtracts SP */
        #ifdef XXXXX
            if (isconst)
            {
                SYM *psp = currentfunc->parentclass;
                if (currentfunc->value.classdata.basecons)
                    gen_void(currentfunc->value.classdata.basecons);
                if (psp->value.classdata.baseclass->vtabsp)
                {
                    CLASSLIST *l = psp->value.classdata.baseclass;
                    ENODE *thisn = copynode(thisenode);
                    ENODE *ts = makenode(en_nacon, psp
                        ->value.classdata.baseclass->vtabsp, 0);
                    ENODE *exp1,  *exp2;
                    thisn = makenode(en_a_ref, thisn, 0);
                    while (l)
                    {
                        if (l->flags &CL_VTAB)
                        {
                            exp1 = makenode(en_addstruc, ts, makeintnode
                                (en_icon, l->vtaboffs));
                            exp2 = makenode(en_addstruc, thisn, makeintnode
                                (en_icon, l->offset));
                            exp2 = makenode(en_a_ref, exp2, 0);
                            exp2 = makenode(en_assign, exp2, exp1);
                            initstack();
                            gen_expr(exp2, FALSE, TRUE, BESZ_DWORD );
                        }
                        l = l->link;
                    }
                }
            }
        #endif 
        if (prm_cplusplus)
            scppinit();
    initstack();
    genstmt(stmt);
        if (block_rundown)
            if (retsize)
        if (retsize > 4)
        {
            gen_code(op_fstp, floatconvpos(), 0);
            gen_void(block_rundown);
            gen_code(op_fld, floatconvpos(), 0);
        }
        else
        {
            gen_code(op_push, makedreg(EAX), 0);
            gen_void(block_rundown);
            gen_code(op_pop, makedreg(EAX), 0);
        }
        else
            gen_void(block_rundown);
    if (funcendstmt)
        gen_line(funcendstmt);
    funcendstmt = 0;
    genreturn(0, 1);
        thissp->inreg = FALSE;
        thissp->value.i = 8;
    flush_peep();
        if (currentfunc->gennedvirtfunc)
            gen_endvirtual(templateSP ? templateSP : currentfunc);
        if ((conscount || try_block_list || currentfunc
            ->value.classdata.throwlist && currentfunc
            ->value.classdata.throwlist->data) && prm_xcept)
            dumpXceptBlock(currentfunc);
}

⌨️ 快捷键说明

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