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

📄 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 页
字号:
        DIAG("complexstore: double fregs");
        return apr ;
    }
    ap2 = copy_addr(apr);
    switch(apr->length)
    {
        case BESZ_CFLOAT:
            offs = 4;
            siz = BESZ_FLOAT;
            break;
        case BESZ_CDOUBLE:
            offs = 8;
            siz = BESZ_DOUBLE;
            break;
        case BESZ_CLDOUBLE:
            offs = 10;
            siz = BESZ_LDOUBLE;
            break;
    }
    ap2->offset = makenode(en_add,ap2->offset,makeintnode(en_icon,offs));
    gen_codefs(op_fstp,siz,apr,0);
    gen_codefs(op_fstp,siz,ap2,0);
    freeop(apr);
    apr->mode = am_frfr;
    apr->length = BESZ_CLDOUBLE;
    return apr;
}
//-------------------------------------------------------------------------

AMODE *floatstore(ENODE *node, AMODE *apr, int novalue, int size)
{
    if (isbit(node))
    {
        AMODE *ap1 = fstack();
        do_extend(ap1, BESZ_DWORD , F_DREG | F_VOL);
        bit_store(apr, ap1, node, novalue);
        return ap1;
    }
    else if (size <= BESZ_DWORD )
    {
        int pushed = FALSE;
        if (regs[0] && apr->preg != 0)
        {
            pushed = 1;
            gen_push(EAX, am_dreg, 0);
        }
        do_ftol();
        if (apr->mode != am_dreg || apr->preg != 0)
            gen_codes(op_mov, size, apr, makedreg(EAX));
        if (pushed)
            gen_pop(EAX, am_dreg, 0);
        if (novalue)
            freeop(apr);
        return apr;
    }
    else if (size <= BESZ_QWORD)
    {
        gen_codef(op_fistp, apr, 0);
        if (novalue)
            freeop(apr);
        return apr;
    }
    else
    {
        if (novalue || apr->length == BESZ_LDOUBLE)
        {
            gen_codef(op_fstp, apr, 0);
            return apr;
        }
        else
        {
            gen_codef(op_fst, apr, 0);
            return makefreg(0);
        }
    }
}

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

void complexload(AMODE *ap, int flag)
{
    AMODE *ap2 ;
    int offs = 0, siz = BESZ_BYTE;
    if (ap->mode == am_frfr)
        return;
    if (ap->mode == am_fconst)
    {
        AMODE *ap1;
        int siz1 = ap->length -13;
        int o = prm_optmult ;
        prm_optmult = FALSE;
        if (siz1>BESZ_DOUBLE)
            siz1++;
        ap1 = make_label(queue_floatval(ap->offset->v.c.r, siz1));
        queue_floatval(ap->offset->v.c.i, siz1);
        ap->mode = am_direct;
        ap->offset = ap1->offset;
        prm_optmult = o ;
    }
    ap2 = copy_addr(ap);
    switch(ap->length)
    {
        case BESZ_CFLOAT:
            offs = 4;
            siz = BESZ_FLOAT;
            break;
        case BESZ_CDOUBLE:
            offs = 8;
            siz = BESZ_DOUBLE;
            break;
        case BESZ_CLDOUBLE:
            offs = 10;
            siz = BESZ_LDOUBLE;
            break;
    }
    ap2->offset = makenode(en_add,ap2->offset,makeintnode(en_icon,offs));
    gen_codefs(op_fld,siz,ap2,0);
    gen_codefs(op_fld,siz,ap,0);
    freeop(ap);
    ap->mode = am_frfr;
    ap->length = BESZ_CLDOUBLE;
}
//-------------------------------------------------------------------------

void floatload(AMODE *ap, int flag)
{
    if (ap->mode == am_fconst)
    {
        switch (ap->preg)
        {
            case fczero:
                gen_codef(op_fldz, 0, 0);
                break;
            case fcone:
                gen_codef(op_fld1, 0, 0);
                break;
        }
        ap->mode = am_freg;
        ap->preg = 0;
    }
    else
    if (flag && ap->mode != am_freg)
    {
        if (ap->mode == am_dreg)
        {
            AMODE *ap1 = floatconvpos();
            do_extend(ap, BESZ_DWORD , 0);
            gen_codes(op_mov, BESZ_DWORD , ap1, ap);
            gen_codefs(op_fild, BESZ_DWORD, ap1, 0);
        }
        else
        {
            gen_codef(op_fld, ap, 0);
            freeop(ap);
            ap->mode = am_freg;
            ap->preg = 0;
        }
    }
}

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

int is_memory(AMODE *ap)
{
    switch (ap->mode)
    {
        case am_indisp:
        case am_indispscale:
        case am_direct:
            return TRUE;
    }
    return FALSE;
}

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

AMODE *bit_load(AMODE *ap, ENODE *node)
{
    if (ap->mode == am_dreg)
        return ap;
    do_extend(ap, ap->length, F_DREG | F_VOL);
    if (node->startbit)
        gen_code(op_shr, ap, make_immed(node->startbit));
    gen_code(op_and, ap, make_immed(mod_mask(node->bits)));
    return ap;
}

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

void bit_store(AMODE *ap2, AMODE *ap1, ENODE *node, int novalue)
{
    AMODE *ap3;
    if (ap1->mode == am_immed)
    {
        int vb;
        ap3 = make_immed(ap1->offset->v.i &mod_mask(node->bits));
        #ifdef XXXXX
            if (node->bits == 1)
                gen_codes(op_btr, BESZ_DWORD , ap2, make_immed(node->startbit));
            else
        #endif 
            gen_code(op_and, ap2, make_immed(~(mod_mask(node->bits) << node
                ->startbit)));
        #ifdef XXXXX
            if ((vb = single_bit(ap1->offset->v.i)) !=  - 1)
            {
                gen_codes(op_bts, BESZ_DWORD , ap2, make_immed(vb + node->startbit));
            }
            else
        #endif 
        if (ap3->offset->v.i)
        {
            ap3->offset->v.i <<= node->startbit;
            gen_codes(op_or, ap2->length, ap2, ap3);
        }
    }
    else
    {
        do_extend(ap1, ap2->length, F_DREG | F_VOL);
        gen_code(op_and, ap1, make_immed(mod_mask(node->bits)));
        if (!novalue)
            gen_codes(op_push, BESZ_DWORD , ap1, 0);
        if (node->startbit)
            gen_code(op_shl, ap1, make_immed(node->startbit));
        gen_code(op_and, ap2, make_immed(~(mod_mask(node->bits) << node
            ->startbit)));
        gen_code(op_or, ap2, ap1);
        if (!novalue)
            gen_codes(op_pop, BESZ_DWORD , ap1, 0);
    }
    if (novalue)
        freeop(ap2);
}

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

AMODE *aprtocx(AMODE *ap)
{
    AMODE *ap2;
    if (ap->mode == am_indisp && (ap->preg == EAX || ap->preg == EDX) || ap
        ->mode == am_indispscale && (ap->preg == EAX || ap->preg == EDX || ap
        ->sreg == EAX || ap->sreg == EDX))
    {
        //         || ap->mode == am_dreg && (ap->preg == EAX || ap->preg == EDX)) {
        ap2 = tempcx();
        if (ap->mode == am_dreg)
            gen_code(op_mov, ap2, ap);
        else
            gen_code(op_lea, ap2, ap);
        ap2->seg = ap->seg;
        ap->seg = 0;
        freeop(ap);
        *ap =  *ap2;
        ap->mode = am_indisp;
        ap->offset = makeintnode(en_icon, 0);
        ap->length = BESZ_QWORD;
    }
    else if (ap->mode == am_dreg && (ap->preg == EAX || ap->preg == EDX))
    {
        ap2 = tempcx();
        if (ap->mode == am_dreg)
            gen_code(op_mov, ap2, ap);
        else
            gen_code(op_lea, ap2, ap);
        ap2->length = ap->length;
        ap2->seg = ap->seg;
        ap->seg = 0;
        freeop(ap);
        *ap =  *ap2;
    }
    return ap;
}

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

void loadaxdx(AMODE *ap)
{
    if (ap->mode == am_immed)
    {
        tempaxdx();
        gen_codes(op_mov, BESZ_DWORD , makedreg(EAX), make_immed(ap->offset->v.i
            &0xffffffff));
        #if sizeof(ULLONG_TYPE) == 4
            gen_codes(op_mov, BESZ_DWORD , makedreg(EDX), make_immed(ap->offset->v.i < 0 
                ?  - 1: 0));
        #else 
            gen_codes(op_mov, BESZ_DWORD , makedreg(EDX), make_immed(ap->offset->v.i >>
                32));
        #endif 
    }
    else
    {
        AMODE *ap3 = aprtocx(ap);
        tempaxdx();
        gen_codes(op_mov, BESZ_DWORD , makedreg(EAX), ap3);
        ap3->offset = makenode(en_add, ap3->offset, makeintnode(en_icon, 4));
        gen_codes(op_mov, BESZ_DWORD , makedreg(EDX), ap3);
        freeop(ap3);
    }
    ap->mode = am_axdx;
    ap->length = BESZ_QWORD;
}

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

void do_extend(AMODE *ap, int osize, int flags)
/*
 *      if isize is not equal to osize then the operand ap will be
 *      loaded into a register (if not already) and if osize is
 *      greater than isize it will be extended to match.
 */
{
    AMODE *ap2,  *ap1,  *ap3;

    int isize = ap->length;
    if (isize ==  - BESZ_BOOL)
        isize = BESZ_BOOL;
    if (osize ==  - BESZ_BOOL)
        osize = BESZ_BOOL;
    if (isize && isize != osize && isize !=  - osize && ap->mode != am_immed || osize == BESZ_CLDOUBLE && isize == BESZ_CLDOUBLE)
    {
        if (ap->mode == am_dreg && ap->preg > 3 && (osize == BESZ_BYTE || osize ==  - BESZ_BYTE)
            )
            flags |= F_VOL;
        if (ap->mode == am_dreg && (!(flags &F_VOL) || ap->tempflag) && ((osize
            != BESZ_BYTE && osize !=  - BESZ_BYTE) || ap->preg < 4))
            ap2 = ap;
        else
        {
            if (!(flags &F_NOREUSE))
                freeop(ap);
            ap2 = temp_data();
        }
        if (chksize(isize, osize))
        {
            /* moving to a lower type */
            if (isize > BESZ_QWORD)
            {
                if (isize >= BESZ_CFLOAT) 
                {
                    complexload(ap,TRUE) ;
                    if (osize < BESZ_CFLOAT)
                        if (osize >= BESZ_IFLOAT)
                        {
                            gen_codefs(op_fstp,BESZ_LDOUBLE,floatconvpos(),0);
                            ap->mode = am_freg;
                            ap->length = osize;
                            freeop(ap2);
                        }
                        else
                        {
                            gen_codef(op_fxch,0,0);
                            gen_codefs(op_fstp,BESZ_LDOUBLE,floatconvpos(),0);
                            ap->length = osize;
                            ap->mode = am_freg;
                            freeop(ap2);
                            goto join1 ;
                        }
                }
                else if (isize >= BESZ_IFLOAT)
                {
                    if (osize < BESZ_IFLOAT)
                    {
                        if (ap->mode == am_freg)
                            gen_codefs(op_fstp,BESZ_LDOUBLE,floatconvpos(),0);
                        gen_codef(op_fldz,0,0);
                        freeop(ap2);
                        ap->mode = am_freg;
                        ap->length = osize;
                        goto join1;
                    } 
                    else
                    {
                        if (ap->mode != am_freg) {
                            floatload(ap, TRUE);
                            ap->length = osize;
                            freeop(ap2);
                        }
                    }
                }
                else 
                {
                    if (ap->mode != am_freg)
                        floatload(ap, TRUE);
join1:
                    if (osize == BESZ_QWORD || osize ==  - BESZ_QWORD || osize == BESZ_BOOL)
                    {
                        freeop(ap2);
                        ap2 = floatconvpos();
    
                        memcpy(ap, ap2, sizeof(*ap));
                        gen_codes(op_fistp, BESZ_DOUBLE, ap, 0);
                        ap->length = BESZ_QWORD;
                    }
                    else if (osize < BESZ_QWORD)
                    {
                        int pushed = FALSE;
                        if (regs[0] && ap2->preg != 0)
                        {
                            pushed = 1;
                            gen_push(EAX, am_dreg, 0);
                        }
                        do_ftol();
                        if (ap2->preg != 0)
                            gen_codes(op_mov, BESZ_DWORD , ap2, makedreg(EAX));
                        if (pushed)
                            gen_pop(EAX, am_dreg, 0);
                        ap->mode = ap2->mode;
                        ap->preg = ap2->preg;
                        ap->tempflag = ap2->tempflag;
                        ap->seg = 0;
                        ap->length = osize;
                    }
                    else
                    {
                        freeop(ap2);
                        ap->mode = am_freg;
                        ap->preg = 0;

⌨️ 快捷键说明

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