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

📄 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 页
字号:
                gen_codes(op_move, BESZ_DWORD, make_immed(ap3->offset->v.i &0xffffffff),
                    push);
                #if sizeof(ULLONG_TYPE) == 4
                    gen_codes(op_move, BESZ_DWORD, make_immed(ap3->offset->v.i < 0 ?  -
                        1: 0), push);
                #else 
                    gen_codes(op_move, BESZ_DWORD, make_immed(ap3->offset->v.i >> 32),
                        push);
                #endif 
                gen_codes(op_move, BESZ_DWORD, makeareg(7), push);
                ss = 12;
            }
            else
            {
                gen_codes(op_pea, BESZ_DWORD, ap, 0);
                ss = 4;
            }
        }
        if (size == 6)
            call_library2("__LQFU", ss);
        else
            call_library2("__LQFS", ss);
        if (pushed)
        {
            gen_codef(op_fmove, 10, makefreg(0), ap2);
            gen_codef(op_fmove, 10, pop, makefreg(0));
        }
        freeop(ap);
        ap->mode = am_doublereg;
        ap->length = size;
    }
    else
    {
        if (ap->mode == am_areg)
        {
            ap2 = temp_data();
            gen_codes(op_move, BESZ_DWORD, ap, ap2);
            freeop(ap);
            ap->preg = ap2->preg;
            ap->mode = ap2->mode;
        }
        ap2 = temp_float();
        gen_codef(op_fmove, ap->length, ap, ap2);
        freeop(ap);
    }
    ap->mode = am_freg;
    ap->preg = ap2->preg;
    ap->tempflag = 1;
    ap->length = 10;
    return ;
}

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

AMODE *floatstore(ENODE *e1, AMODE *ap, AMODE *ap1, int novalue, int size)
{
    if (!ap1)
        ap1 = gen_expr(e1, FALSE, TRUE, BESZ_DWORD);
    if (e1 && isbit(e1))
    {
        do_extend(ap, BESZ_DWORD, F_DREG | F_VOL);
        bit_store(ap, ap1, e1, novalue);
        freeop(ap1);
    }
    else if (ap->mode != am_freg || ap1->mode != am_freg || ap1->preg != ap
        ->preg)
    if (size == 6 || size ==  - 6)
    {
        gen_codef(op_fmove, 10, ap, push);
        if (size == 6)
            call_library2("__LFQU", 16);
        else
            call_library2("__LFQS", 16);
        freeop(ap1);
        ap->mode = am_doublereg;
        ap->length = size;
    }
    else
    {
        gen_codef(op_fmove, size, ap, ap1);
        freeop(ap);
        ap = ap1;
    }
    if (novalue)
        freeop(ap);
    return ap;
}

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

void doshift(int op, AMODE *ap2, AMODE *ap1, int div, int size)
{
    AMODE *apr = copy_addr(ap1),  *ap3;
    if (div)
    {
        // ap2 always a const if we get in here
        freeop(ap2);
        switch (size)
        {
            case BESZ_BYTE:
                case  - BESZ_BYTE: gen_codes(op_btst, BESZ_BYTE, make_immed(7), ap1);
                gen_code(op_beq, make_label(nextlabel), 0);
            case 2:
                case  - 2: do_extend(ap1, BESZ_DWORD, F_DREG | F_VOL);
                gen_codes(op_and, BESZ_DWORD, make_immed(0x8000), ap1);
                gen_code(op_beq, make_label(nextlabel), 0);
                freeop(ap1);
                break;
            case BESZ_DWORD:
            case  - BESZ_DWORD: default:
                if (ap2->mode == am_immed && ap2->offset->v.i == 1 && ap1->mode
                    == am_dreg)
                {
                    gen_codes(op_asr, BESZ_DWORD, ap2, ap1);
                    gen_code(op_bpl, make_label(nextlabel), 0);
                    gen_code(op_bcc, make_label(nextlabel), 0);
                    gen_codes(op_add, BESZ_DWORD, make_immed(1), ap1);
                    gen_label(nextlabel++);
                    return ;
                }
                else
                {
                    if (ap1->mode == am_dreg)
                    {
                        gen_codes(op_tst, BESZ_DWORD, ap1, 0);
                        gen_code(op_bpl, make_label(nextlabel), 0);
                    }
                    else
                    {
                        do_extend(ap1, BESZ_DWORD, F_DREG | F_VOL);
                        gen_codes(op_and, BESZ_DWORD, make_immed(0x80000000), ap1);
                        gen_code(op_beq, make_label(nextlabel), 0);
                        freeop(ap1);
                    }
                    break;
                }
        }
        ap3 = copy_addr(ap2);
        ap3->offset = makeintnode(en_icon, ((1 << ap2->offset->v.i) - 1));
        ap3->length = ap2->length;
        gen_code(op_add, ap3, ap1);
        gen_label(nextlabel++);
    }
    {
        do_extend(apr, size, F_DREG | F_VOL);
        if (ap2->mode == am_immed)
        {
            int temp = ap2->offset->v.i;
            while (temp > 8)
            {
                temp = temp - 8;
                gen_codes(op, size, make_immed(8), apr);
            }
            if (temp != 0)
                gen_codes(op, size, make_immed(temp), apr);
        }
        else
        {
            do_extend(ap2, size, F_DREG);
            gen_codes(op, size, ap2, apr);
            freeop(ap2);
        }
        ap2->mode = am_dreg;
        ap2->preg = apr->preg;
    }
}

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

AMODE *do6shift(int op, ENODE *node, int div, int size)
{
    AMODE *ecx = makedreg(2),  *ap1 = 0,  *ap2,  *ap3;
    LLONG_TYPE t;
    ap2 = gen_expr(node->v.p[1], FALSE, FALSE, BESZ_DWORD);
    if (div)
    {
        // if we get in here ap2 is a const ...
        ap1 = gen_expr(node->v.p[0], FALSE, FALSE, size);
        do_extend(ap1, size, F_DOUBLEREG);
        gen_codes(op_btst, BESZ_DWORD, make_immed(31), makedreg(0));
        gen_1branch(op_beq, make_label(nextlabel));
        {
            AMODE *ap3 = copy_addr(ap2);
            AMODE *ap4 = copy_addr(ap2);
            t = (1 << ap2->offset->v.i) - 1;
            #if sizeof(ULLONG_TYPE) == 4
                ap3->offset = makeintnode(en_icon, t < 0 ?  - 1: 0);
            #else 
                ap3->offset = makeintnode(en_icon, t >> 32);
            #endif 
            ap4->offset = makeintnode(en_icon, t);
            ap3->length = ap2->length;
            ap4->length = ap2->length;
            gen_codes(op_add, BESZ_DWORD, ap3, makedreg(0));
            gen_codes(op_add, BESZ_DWORD, apBESZ_DWORD, makedreg(1));
            gen_code(op_bcc, make_label(nextlabel), 0);
            gen_codes(op_add, BESZ_DWORD, make_immed(1), makedreg(0));
            gen_label(nextlabel++);
        }
        gen_label(nextlabel++);
    }
    {

        int xchg =  - 1;
        int pushed = FALSE;
        if (dregs[2] && ap2->mode != am_dreg && ap2->preg != 2)
        {
            pushed = TRUE;
            gen_push(2, am_dreg, 0);
        }
        if (ap2->mode == am_doublereg)
            gen_push(1, am_dreg, 0);
        else
        {
            if (ap2->length == 6 || ap2->length ==  - 6)
            {
                if (ap2->offset)
                    ap2->offset = makenode(en_add, ap2->offset, makeintnode
                        (en_icon, 4));
                else
                    ap2->offset = makeintnode(en_icon, 4);
                if (ap2->mode == am_ind)
                    ap2->mode = am_indx;
                ap2->length = BESZ_DWORD;
            }
            else
                do_extend(ap2, BESZ_DWORD, F_ALL);
            gen_codes(op_move, BESZ_DWORD, ap2, push);
        }
        freeop(ap2);
        if (!ap1)
            ap1 = gen_expr(node->v.p[0], FALSE, FALSE, size);
        if (ap1->mode == am_doublereg)
        {
            gen_push(1, am_dreg, 0);
            gen_push(0, am_dreg, 0);
        }
        else if (ap1->mode == am_immed)
        {
            gen_codes(op_move, BESZ_DWORD, make_immed(ap1->offset->v.i), push);
            #if sizeof(LLONG_TYPE) == 4
                gen_codes(op_move, BESZ_DWORD, make_immed(ap1->offset->v.i < 0 ?  - 1: 0)
                    , push);
            #else 
                gen_codes(op_move, BESZ_DWORD, make_immed(ap1->offset->v.i >> 32), push);
            #endif 
        }
        else
        {
            ap2 = copy_addr(ap1);
            if (ap2->offset)
                ap2->offset = makenode(en_add, ap2->offset, makeintnode(en_icon,
                    4));
            else
                ap2->offset = makeintnode(en_icon, 4);
            if (ap2->mode == am_ind)
                ap2->mode = am_indx;
            gen_codes(op_move, BESZ_DWORD, ap2, push);
            gen_codes(op_move, BESZ_DWORD, ap1, push);
        }
        freeop(ap1);
        if (op == op_lsr)
            call_library2("__LXSHR", 12);
        else if (op == op_asr)
            call_library2("__LXSAR", 12);
        else
            call_library2("__LXSHL", 12);
        if (pushed)
            gen_pop(2, am_dreg, 0);
        dregs[0]++;
        dregs[1]++;
    }
    ap1 = xalloc(sizeof(AMODE));
    ap1->mode = am_doublereg;
    ap1->length = 6;
    return ap1;
}

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

void bit_store(AMODE *ap1, AMODE *ap2, ENODE *node, int novalue)
{
    if (prm_68020 && !prm_coldfire)
    {
        AMODE *ap3;
        if (ap1->mode != am_dreg)
            do_extend(ap1, BESZ_DWORD, F_DREG | F_VOL);
        gen_code3(op_bfins, 0, ap1, ap2, makebf(node, ap2, ap1->length));
        ap1->mode = ap3->mode;
        ap1->preg = ap3->preg;
        ap1->tempflag = ap3->tempflag;
    }
    else if (ap1->mode == am_immed)
    {
        int vb;
        AMODE *ap3;
        if (prm_coldfire)
            do_extend(ap2, BESZ_DWORD, F_DREG | F_VOL);
        ap3 = make_immed(ap1->offset->v.i &mod_mask(node->bits));
        //         if (node->bits == 1) {
        //            if (!ap1->offset->v.i)
        //               gen_codes(op_bclr,BESZ_DWORD,make_immed(node->startbit),ap2);
        //         } else
        if (mod_mask(node->bits) != ap3->offset->v.i)
            gen_codes(op_andi, ap2->length, make_immed(~(mod_mask(node->bits)
                << node->startbit)), ap2);
        //         if ((vb = single_bit(ap1->offset->v.i)) != -1) {
        //            gen_codes(op_bset,BESZ_DWORD,make_immed(vb+node->startbit),ap2);
        //         }else 
        if (ap3->offset->v.i)
        {
            ap3->offset->v.i <<= node->startbit;
            gen_codes(op_or, ap2->length, ap3, ap2);
        }
        ap1->mode = ap2->mode;
        ap1->preg = ap2->preg;
        ap1->tempflag = ap2->tempflag;
    }
    else
    {
        do_extend(ap1, ap2->length, F_DREG | F_VOL);
        gen_codes(op_andi, BESZ_DWORD, make_immed(mod_mask(node->bits)), ap1);
        if (!novalue)
            gen_codes(op_move, BESZ_DWORD, ap1, push);
        if (node->startbit)
            doshift(op_asl, make_immed(node->startbit), ap1, FALSE, ap1->length)
                ;
        gen_codes(op_andi, ap2->length, make_immed(~(mod_mask(node->bits) <<
            node->startbit)), ap2);
        gen_codes(op_or, ap2->length, ap1, ap2);
        if (!novalue)
            gen_codes(op_move, BESZ_DWORD, pop, ap1);
    }
}

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

AMODE *bit_load(AMODE *ap, ENODE *node, int size)
{
    if (prm_68020 && !prm_coldfire)
    {
        AMODE *ap1 = temp_data();
        ap1->tempflag = TRUE;
        if (ap1->mode == am_immed)
            gen_codes(op_move, BESZ_DWORD, ap1, ap);
        else
            gen_code3(op_bfextu, 0, ap, makebf(node, ap, size), ap1);
        return ap1;
    }
    else
    {
        do_extend(ap, ap->length, F_DREG | F_VOL);
        if (node->startbit)
            doshift(op_asr, make_immed(node->startbit), ap, FALSE, ap->length);
        gen_codes(op_andi, ap->length, make_immed(mod_mask(node->bits)), ap);
        return ap;
    }
}

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

void loaddoublereg(AMODE *ap)
{
    if (ap->mode == am_immed)
    {
        temp_doubledregs();
        gen_codes(op_move, BESZ_DWORD, make_immed(ap->offset->v.i &0xffffffff), makedreg
            (1));
        #if sizeof(ULLONG_TYPE) == 4
            gen_codes(op_move, BESZ_DWORD, make_immed(ap->offset->v.i < 0 ?  - 1: 0),
                makedreg(0));
        #else 
            gen_codes(op_move, BESZ_DWORD, make_immed(ap->offset->v.i >> 32), makedreg(0)
                );
        #endif 
    }
    else
    {
        AMODE *ap2;
        ap = direct_data(ap);
        temp_doubledregs();
        gen_codes(op_move, BESZ_DWORD, ap, makedreg(0));
        ap2 = copy_addr(ap);
        if (ap2->offset)
            ap2->offset = makenode(en_add, ap2->offset, makeintnode(en_icon, 4))
                ;
        else
            ap2->offset = makeintnode(en_icon, 4);

⌨️ 快捷键说明

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