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

📄 gexpr68.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (ap2->mode == am_ind)
            ap2->mode = am_indx;
        gen_codes(op_move, BESZ_DWORD, ap2, makedreg(1));
        freeop(ap);
    }
    ap->mode = am_doublereg;
    ap->length = 6;
}

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

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;

    int isize = ap->length;
    if (osize ==  - 5)
        osize = 5;
    if (isize && isize != osize && isize !=  - osize && ap->mode != am_immed)
    {
        if (ap->mode == am_dreg && (!(flags &F_VOL) || ap->tempflag))
            ap2 = ap;
        else
        {
            if (!(flags &F_NOREUSE))
                freeop(ap);
            ap2 = temp_data();
        }
        if (chksize(isize, osize))
        {
            /* moving to a lower type */
            if (isize > 6)
            {
                tofloat(ap, isize);
                if (osize <= 6)
                {
                    int pushed = FALSE;
                    ap2 = floatstore(0, ap, ap2, FALSE, osize);
                    ap->mode = ap2->mode;
                    ap->preg = ap2->preg;
                    ap->sreg = ap2->sreg;
                    ap->offset = ap2->offset;
                    ap->length = osize;
                    ap->tempflag = 1;

                }
            }
            else
            {
                if (ap->mode != am_dreg || ap->preg != ap2->preg)
                    if (isize == 6 || isize ==  - 6)
                if (ap->mode == am_doublereg)
                {
                    if (ap2->preg != 1)
                    {
                        dregs[ap2->preg]--;
                        dregs[1]++;
                    }
                    ap2->mode = am_dreg;
                    ap2->preg = 1;
                    ap2->tempflag = 1;
                }
                else
                    gen_codes(op_move, BESZ_DWORD, ap, ap2);
                else
                    gen_codes(op_move, isize, ap, ap2);
                ap->mode = ap2->mode;
                ap->preg = ap2->preg;
                ap->length = osize;
                ap->tempflag = ap2->tempflag;
            }
        }
        else
        {
            /* moving up in type */
            if (isize > 6)
            {
                tofloat(ap, isize);
                freeop(ap2);
            }
            else if (isize == 6 || isize ==  - 6 || osize > 6)
            {
                tofloat(ap, isize);
                ap->tempflag = 1;
            }
            else
            {
                int size6 = osize == 6 || osize ==  - 6;
                if (osize == 6 || osize ==  - 6)
                    osize = BESZ_DWORD;
                if (ap->mode == am_areg && (isize == BESZ_BYTE || isize ==  - BESZ_BYTE))
                    gen_codes(op_move, BESZ_DWORD, ap, ap2);
                if (size6 && (isize == BESZ_DWORD || isize ==  - BESZ_DWORD))
                    gen_codes(op_move, isize, ap, ap2);
                else if (isize < 0)
                {
                    if (!equal_address(ap, ap2))
                    {
                        gen_codes(op_move, isize, ap, ap2);
                        freeop(ap);
                    }
                    if ((isize == BESZ_BYTE || isize ==  - BESZ_BYTE) && osize ==  - BESZ_DWORD && 
                        (prm_68020 || prm_coldfire))
                        gen_codes(op_extb, BESZ_DWORD, ap2, 0);
                    else
                    {
                        if (isize == BESZ_BYTE || isize ==  - BESZ_BYTE)
                            gen_codes(op_ext, 2, ap2, 0);
                        if (osize ==  - BESZ_DWORD || osize == BESZ_DWORD)
                            gen_codes(op_ext, BESZ_DWORD, ap2, 0);
                    }
                }
                else
                {
                    if (equal_address(ap, ap2))
                        ap2 = temp_data();
                    gen_codes(op_moveq, 0, make_immed(0), ap2);
                    gen_codes(op_move, ap->length, ap, ap2);
                    freeop(ap);
                }
                if (size6)
                {
                    freeop(ap2);
                    temp_doubledregs();
                    if (ap2->preg != 1)
                        gen_codes(op_move, BESZ_DWORD, ap2, makedreg(1));
                    gen_codes(op_moveq, BESZ_DWORD, make_immed(0), makedreg(0));
                    if (isize < 0)
                    {
                        int label = nextlabel++;
                        gen_codes(op_tst, BESZ_DWORD, makedreg(1), 0);
                        gen_1branch(op_bpl, make_label(label));
                        gen_codes(op_subq, BESZ_DWORD, make_immed(1), makedreg(0));
                        gen_label(label);
                    }
                    ap->mode = am_doublereg;
                    ap->length = 6;
                    osize = 6;
                }
                else
                {
                    ap->mode = am_dreg;
                    ap->preg = ap2->preg;
                    ap->tempflag = ap2->tempflag;
                    ap->length = osize;
                }
            }
        }
    }
    if (((flags &F_VOL) == 0) || ap->tempflag)
    {
        switch (ap->mode)
        {
            case am_doublereg:
                if (flags &F_DOUBLEREG)
                    return ;
                break;
            case am_freg:
                if (flags &F_FREG)
                    return ;
                break;
            case am_immed:
                if (flags &F_IMMED)
                    return ;
                 /* mode ok */
                break;
            case am_areg:
                if (flags &F_AREG)
                    return ;
                break;
            case am_dreg:
                if (flags &F_DREG)
                    return ;
                break;
            case am_indx:
            case am_ind:
            case am_ainc:
            case am_adec:
                if (flags &F_REGI)
                    return ;
                break;
            case am_baseindxdata:
            case am_baseindxaddr:
                if (flags &F_REGIX)
                    return ;
                break;
            case am_adirect:
            case am_direct:
                if (flags &F_ABS)
                    return ;
            case am_pcindx:
                if (flags &(F_PCI | F_PCIX))
                    return ;
                break;
        }
    }
    if (flags &(F_FREG | F_DREG))
    {
        if (flags &F_DREG)
        {
            if (ap->mode != am_dreg || !ap->tempflag && (flags &F_VOL))
            if (isize == osize || isize ==  - osize || ap->mode == am_immed)
            {
                if (osize < 7)
                {
                    freeop(ap);
                    ap2 = temp_data();
                    ap2->length = osize;
                    gen_code(op_move, ap, ap2);
                    ap->mode = ap2->mode;
                    ap->preg = ap2->preg;
                    ap->tempflag = ap2->tempflag;
                }
                else
                {
                    tofloat(ap, isize);
                }
            }
        }
        else if (ap->mode != am_freg)
        {
            tofloat(ap, isize);
        }
        else if (flags &F_VOL)
        {
            ap2 = temp_float();
            ap2->length = osize;
            gen_codes(op_fmove, osize, ap, ap2);
            ap->mode = ap2->mode;
            ap->preg = ap2->preg;
            ap->tempflag = ap2->tempflag;
        }

    }
    if ((flags &F_DOUBLEREG) && !(flags &(F_MEM | F_IMMED)) && ap->mode !=
        am_doublereg)
        loaddoublereg(ap);
    if (flags &F_AREG)
    {
        if (isize ==  - BESZ_BYTE)
        {
            freeop(ap);
            ap2 = temp_data();
            gen_codes(op_move, BESZ_BYTE, ap, ap2);
            gen_codes(op_ext, 2, ap2, 0);
            ap->mode = ap2->mode;
            ap->preg = ap2->preg;
            ap->tempflag = 1;
            isize =  - 2;
        }
        if (isize == BESZ_BYTE)
        {
            freeop(ap);
            ap2 = temp_data();
            gen_codes(op_move, BESZ_BYTE, ap, ap2);
            gen_codes(op_and, 2, make_immed(0xff), ap2);
            ap->mode = ap2->mode;
            ap->preg = ap2->preg;
            ap->tempflag = 1;
            isize = 2;
        }
        freeop(ap);
        ap2 = temp_addr();
        gen_codes(op_move, isize, ap, ap2);
        ap->mode = am_areg;
        ap->preg = ap2->preg;
        ap->tempflag = 1;
    }
    if (osize != isize && osize == 5)
    {
        int lab = nextlabel++;
        ap2 = temp_data();
        gen_codes(op_moveq, BESZ_DWORD, make_immed(0), ap2);
        gen_codes(op_cmp, BESZ_BYTE, make_immed(0), ap);
        gen_code(op_beq, make_label(lab), 0);
        gen_codes(op_moveq, BESZ_BYTE, make_immed(1), ap2);
        gen_label(lab);
        freeop(ap);
        ap->mode = ap->mode;
        ap->tempflag = ap2->tempflag;
        ap->length = ap2->length;
        ap->preg = ap2->preg;
    }
    ap->length = osize;
    if (osize == 5)
        ap->length = 5;
}

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

int isshort(ENODE *node)
/*
 *      return true if the node passed can be generated as a short
 *      offset.
 */
{
    return (isintconst(node->nodetype) || node->nodetype == en_absacon) && 
        (node->v.i >=  - 32768 && node->v.i <= 32767);
}

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

int isbyte(ENODE *node)
/*
 *      return true if the node passed can be evaluated as a byte
 *      offset.
 */
{
    return isintconst(node->nodetype) && ( - 128 <= node->v.i && node->v.i <=
        127);
}

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

int isamshort(AMODE *ap)
{
    LLONG_TYPE v;
    if (ap->offset->nodetype != en_icon)
        return TRUE;
    v = ap->offset->v.i;
    return (v >=  - 32768 && v < 32767);
}

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

int isamshort2(AMODE *ap, AMODE *ap2)
{
    LLONG_TYPE v;
    if (ap->offset->nodetype != en_icon || ap2->offset->nodetype != en_icon)
        return TRUE;
    v = ap->offset->v.i + ap2->offset->v.i;
    return (v >=  - 32768 && v < 32767);
}

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

int isambyte(AMODE *ap)
{
    long v;
    if (ap->offset->nodetype != en_icon)
        return FALSE;
    v = ap->offset->v.i;
    return (v >=  - 128 && v < 128);
}

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

int isambyte2(AMODE *ap, AMODE *ap2)
{
    long v;
    if (ap->offset->nodetype != en_icon || ap2->offset->nodetype != en_icon)
        return FALSE;
    v = ap->offset->v.i + ap2->offset->v.i;
    return (v >=  - 128 && v < 128);
}

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

static int depth(ENODE *node)
{
    int a, b;
    if (!node)
        return 0;
    switch (node->nodetype)
    {
        case en_structret:
            return 0;
        case en_cfi:
        case en_cfc:
        case en_cri:
        case en_crc:
        case en_clri:
        case en_clrc:
        case en_cll:
        case en_cull:
		case en_ci:
		case en_cui:
        case en_cl:
        case en_cul:
        case en_cp:
        case en_cbool:
        case en_cub:
        case en_cb:

⌨️ 快捷键说明

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