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

📄 gstmt68.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 (flag &1)
    {
        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_move, BESZ_DWORD, makedreg(1), push);
                gen_codes(op_move, BESZ_DWORD, makedreg(0), push);
            }
            gen_expr(currentfunc->value.classdata.eofdest, TRUE, FALSE, 0);
            if (returndreg)
            {
                gen_codes(op_move, BESZ_DWORD, pop, makedreg(0));
                if (currentfunc->tp->btp->type == bt_longlong || currentfunc
                    ->tp->btp->type == bt_unsignedlonglong)
                    gen_codes(op_move, BESZ_DWORD, pop, makedreg(1));
            }

        }
        if ((conscount || try_block_list || currentfunc
            ->value.classdata.throwlist && currentfunc
            ->value.classdata.throwlist->data) && prm_xcept)
            call_library2("__RundownExceptBlock", 0);
        if ((!prm_linkreg || currentfunc->intflag) && (lc_maxauto))
        if (lc_maxauto > 8)
        {
            AMODE *ap = xalloc(sizeof(AMODE));
            ap->mode = am_indx;
            ap->offset = makeintnode(en_icon, lc_maxauto);
            ap->preg = 7;
            gen_codes(op_lea, 0, ap, makeareg(7));
        }
        else
            gen_codes(op_add, BESZ_DWORD, make_immed(lc_maxauto), makeareg(7));
        if (fsave_mask != 0)
            gen_codes(op_fmovem, BESZ_LDOUBLE, pop, make_mask(fsave_mask, 1));
        if (save_mask != 0)
            if (prm_coldfire)
        if (rmaskcnt > 1)
        {
            gen_codes(op_movem, BESZ_DWORD, mvma7, make_mask(save_mask, 0));
            mvn1 = xalloc(sizeof(struct enode));
            mvn1->nodetype = en_icon;
            mvn1->v.i = (rmaskcnt << 2);
            ap3 = xalloc(sizeof(struct amode));
            ap3->mode = am_indx;
            ap3->preg = 7;
            ap3->offset = mvn1;
            gen_codes(op_lea, BESZ_DWORD, ap3, mvma7i);
            freeop(ap3);
        }
        else
            gen_codes(op_move, BESZ_DWORD, pop, make_mask(save_mask, 0));
        else
            gen_codes(op_movem, BESZ_DWORD, pop, make_mask(save_mask, 0));
        if (prm_cplusplus && prm_xcept || prm_linkreg && !currentfunc->intflag
            && (currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM*)
            - 1 || lc_maxauto) || !prm_smartframes || (currentfunc
            ->value.classdata.cppflags &PF_MEMBER) && !(currentfunc
            ->value.classdata.cppflags &PF_STATIC))
        {
            gen_codes(op_unlk, 0, makeareg(linkreg), 0);
        } if (currentfunc->intflag)
            gen_codes(op_rte, 0, 0, 0);
        else
        if (currentfunc->pascaldefn || currentfunc->isstdcall)
        {
            long retsize = 0;
            if (currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM*)
                - 1)
            {
                retsize = currentfunc->paramsize;
                if (prm_linkreg)
                    retsize -= 8;
            }
            if (currentfunc->tp->btp && isstructured(currentfunc->tp->btp))
                retsize += 4;
            if (retsize)
            {
                if (prm_68020 || prm_68010)
                    gen_codes(op_rtd, 0, make_immed(retsize), 0);
                else
                {
                    ap = temp_addr();
                    freeop(ap);
                    gen_codes(op_move, BESZ_DWORD, pop, ap);
                    if (retsize > 8)
                    {
                        ap1 = xalloc(sizeof(AMODE));
                        ap1->mode = am_indx;
                        ap1->offset = makeintnode(en_icon, retsize);
                        ap1->preg = 7;
                        gen_codes(op_lea, 0, ap1, makeareg(7));
                    }
                    else
                        gen_codes(op_add, BESZ_DWORD, make_immed(retsize), makeareg(7));
                    ap->mode = am_ind;
                    gen_codes(op_jmp, 0, ap, 0);
                }
                return ;
            }
        }
        gen_codes(op_rts, 0, 0, 0);
    }
    else
    {
        if (retlab ==  - 1)
            retlab = nextlabel++;
        gen_codes(op_bra, 0, make_label(retlab), 0);
    }
}

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

void gen_tryblock(void *val)
{
    AMODE *ap1 = xalloc(sizeof(AMODE));
    ap1->mode = am_indx;
    ap1->preg = linkreg;
    ap1->offset = makeintnode(en_icon,  - xceptoffs + 12); // ESP in XCEPTDATA
    // this is a little buggy, it doesn't push FP regs
    switch ((int)val)
    {
        case 0:
            // start of try block
            gen_move(BESZ_DWORD, makedreg(3), push);
            gen_move(BESZ_DWORD, makedreg(4), push);
            gen_move(BESZ_DWORD, makedreg(5), push);
            gen_move(BESZ_DWORD, makedreg(6), push);
            gen_move(BESZ_DWORD, makedreg(7), push);
            gen_move(BESZ_DWORD, ap1, push);
            gen_move(BESZ_DWORD, makeareg(7), ap1);
            break;
        case 1:
            //start of catch block
            gen_move(BESZ_DWORD, ap1, makeareg(7));
            gen_move(BESZ_DWORD, pop, ap1);
            gen_move(BESZ_DWORD, pop, makedreg(7));
            gen_move(BESZ_DWORD, pop, makedreg(6));
            gen_move(BESZ_DWORD, pop, makedreg(5));
            gen_move(BESZ_DWORD, pop, makedreg(4));
            gen_move(BESZ_DWORD, pop, makedreg(3));
            break;
        case 2:
            //end of try block
            gen_move(BESZ_DWORD, ap1, makeareg(7));
            gen_move(BESZ_DWORD, pop, ap1);
            gen_codes(op_add, BESZ_DWORD, make_immed(4 *5), makedreg(7));
            break;
    }
}

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

void genstmt(SNODE *stmt)
/*
 *      genstmt will generate a statement and follow the next pointer
 *      until the block is generated.
 */
{
    while (stmt != 0)
    {
        switch (stmt->stype)
        {
            case st_case:
                if ((int)stmt->label >= 0)
                    gen_label((int)stmt->label);
                break;
            case st_block:
                genstmt(stmt->exp);
                break;
            case st_label:
                gen_label((int)stmt->label);
                break;
            case st_goto:
                gen_codes(op_bra, 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_line:
                gen_line(stmt);
                break;
            case st_continue:
                gen_codes(op_bra, 0, make_label(contlab), 0);
                break;
            case st_break:
                gen_codes(op_bra, 0, make_label(breaklab), 0);
                break;
            case st_switch:
                genxswitch(stmt);
                break;
            case st__genword:
                gen_genword(stmt);
                break;
            case st_asm:
                if (stmt->exp)
                    add_peep(stmt->exp);
                break;
            default:
                DIAG("unknown statement.");
                break;
        }
        stmt = stmt->next;
    }
}

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

    void scppinit(void)
    /*
     * Call C++ reference variable and class initializers
     */
    {
        #ifdef XXXXX
            if (!strcmp(currentfunc->name, "_main"))
            {
                AMODE *ap1,  *ap2,  *ap3,  *ap4;
                int lbl = nextlabel++;
                initstack();
                ap1 = temp_addr();
                ap4 = xalloc(sizeof(AMODE));
                ap4->preg = ap1->preg;
                ap4->mode = am_ind;
                ap2 = set_symbol("CPPSTART", 0);
                ap3 = set_symbol("CPPEND", 0);
                gen_codes(op_lea, BESZ_DWORD, ap2, ap1);
                gen_label(lbl);
                gen_codes(op_move, BESZ_DWORD, ap1, push);
                gen_codes(op_jsr, BESZ_DWORD, ap4, 0);
                gen_codes(op_move, BESZ_DWORD, pop, ap1);
                gen_codes(op_add, BESZ_DWORD, make_immed(4), ap1);
                gen_codes(op_cmp, BESZ_DWORD, ap3, ap1);
                gen_codes(op_bhi, 0, make_label(lbl), 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(7);
        ap1->mode = am_indx;
        ap1->offset = makeintnode(en_icon, isstructured(sp->tp->btp) ? 8 : 4);
        gen_codes(op_move, BESZ_DWORD, ap1, makedreg(0));
        ap1->preg = 0;
        ap1->mode = am_indx;
        if (sp->value.classdata.vtaboffs)
            ap1->offset = makeintnode(en_icon, sp->value.classdata.vtaboffs);
        else
            ap1->offset = makeintnode(en_icon, 0);
        gen_codes(op_move, BESZ_DWORD, ap1, makedreg(0));
        ap1->mode = am_ind;
        gen_codes(op_move, BESZ_DWORD, ap1, makedreg(0));
        ap1->offset = makeintnode(en_icon, sp->value.i);
        ap1->mode = am_indx;
        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(7);
        ap1->mode = am_indx;
        ap1->offset = makeintnode(en_icon, 4);
        gen_codes(op_add, BESZ_DWORD, make_immed( - ofs), ap1);
        ap2 = xalloc(sizeof(AMODE));
        ap2->offset = makenode(en_napccon, (void*)func, 0);
        ap2->mode = am_immed;
        gen_codes(op_bra, 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;
    stackdepth = 0;
    contlab = breaklab =  - 1;
    retlab = nextlabel++;
    funcfloat = 0;
    if (funcstmt)
        gen_line(funcstmt);
    funcstmt = 0;
    #ifdef XXXXX
        if (stmt->stype == st_line)
        {
            gen_line(stmt);
            stmt = stmt->next;
        }
        if (!stmt)
        {
            if (currentfunc->gennedvirtfunc)
                gen_virtual(currentfunc, FALSE);
            else
                gen_codelab(currentfunc);
            gen_codes(op_rts, 0, 0, 0);
            flush_peep();
            if (currentfunc->gennedvirtfunc)
                gen_endvirtual(currentfunc);
            return ;
        }
    #endif 
        #ifdef XXXXX              
            if (currentfunc->value.classdata.cppflags &PF_CONSTRUCTOR)
            {
                isconst = TRUE;
            }
        #endif 
        if (currentfunc->gennedvirtfunc)
            gen_virtual(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 > BESZ_DWORD)
        {
            if (retsize == BESZ_QWORD) {
                gen_codes(op_move, BESZ_DWORD, makedreg(0), push);
                gen_codes(op_move, BESZ_DWORD, makedreg(1), push);
                gen_void(block_rundown);
                gen_codes(op_move, BESZ_DWORD, pop, makedreg(1));
                gen_codes(op_move, BESZ_DWORD, pop, makedreg(0));
            } else {
                gen_codes(op_fmove, BESZ_LDOUBLE, makefreg(0), push);
                gen_void(block_rundown);
                gen_codes(op_fmove, BESZ_LDOUBLE, pop, makefreg(0));
            }
        }
        else
        {
            gen_codes(op_move, BESZ_DWORD, makedreg(0), push);
            gen_void(block_rundown);
            gen_codes(op_move, BESZ_DWORD, pop, makedreg(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(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 + -