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

📄 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 页
字号:
        case en_cuw:
        case en_cw:
        case en_cd:
        case en_cld:
        case en_cf:
        case en_bits:
        case en_ll_ref:
        case en_ull_ref:
        case en_l_ref:
        case en_ul_ref:
		case en_a_ref:
		case en_ua_ref:
		case en_i_ref:
		case en_ui_ref:
        case en_ub_ref:
        case en_bool_ref:
        case en_b_ref:
        case en_uw_ref:
        case en_w_ref:
        case en_longdoubleref:
        case en_doubleref:
        case en_floatref:
        case en_fimaginaryref:
        case en_rimaginaryref:
        case en_lrimaginaryref:
        case en_fcomplexref:
        case en_rcomplexref:
        case en_lrcomplexref:
            return 1+depth(node->v.p[0]);
        case en_uminus:
        case en_moveblock:
        case en_stackblock:
        case en_movebyref:
        case en_clearblock:
            return 1+depth(node->v.p[0]);
        case en_fimaginarycon:
        case en_rimaginarycon:
        case en_lrimaginarycon:
        case en_fcomplexcon:
        case en_rcomplexcon:
        case en_lrcomplexcon:
        case en_llcon:
        case en_llucon:
        case en_icon:
        case en_lcon:
        case en_lucon:
        case en_iucon:
        case en_boolcon:
        case en_ccon:
        case en_cucon:
        case en_rcon:
        case en_lrcon:
        case en_fcon:
        case en_absacon:
        case en_trapcall:
        case en_labcon:
        case en_nacon:
        case en_autocon:
        case en_autoreg:
        case en_napccon:
        case en_nalabcon:
        case en_tempref:
        case en_regref:
            return 1;
        case en_not:
        case en_compl:
        case en_substack:
            return 1+depth(node->v.p[0]);
        case en_eq:
        case en_ne:
        case en_lt:
        case en_le:
        case en_gt:
        case en_ge:
        case en_ugt:
        case en_uge:
        case en_ult:
        case en_ule:
        case en_land:
        case en_lor:
        case en_div:
        case en_udiv:
        case en_pdiv:
        case en_mod:
        case en_umod:
        case en_assign:
        case en_refassign:
        case en_lassign:
        case en_asuminus:
        case en_ascompl:
        case en_add:
        case en_sub:
        case en_addstruc:
        case en_umul:
        case en_pmul:
		case en_arrayindex:
        case en_mul:
        case en_and:
        case en_or:
        case en_xor:
        case en_asalsh:
        case en_asarsh:
        case en_alsh:
        case en_arsh:
        case en_arshd:
        case en_asarshd:
        case en_lsh:
        case en_rsh:
        case en_asadd:
        case en_assub:
        case en_asmul:
        case en_asdiv:
        case en_asmod:
        case en_asand:
        case en_asumod:
        case en_asudiv:
        case en_asumul:
        case en_asor:
        case en_aslsh:
        case en_asxor:
        case en_asrsh:
        case en_repcons:
        case en_ainc:
        case en_adec:
            a = depth(node->v.p[0]);
            b = depth(node->v.p[1]);
            if (a > b)
                return 1+a;
            return 1+b;
		case en_array:
            a = depth(node->v.p[0]);
            b = depth(node->v.p[1])-1;
            if (a > b)
                return 1+a;
            return 1+b;
        case en_void:
        case en_cond:
        case en_voidnz:
        case en_dvoid:
            return 1+depth(node->v.p[1]);
        case en_sfcall:
        case en_sfcallb:
        case en_scallblock:
        case en_pfcall:
        case en_pfcallb:
        case en_fcall:
        case en_intcall:
        case en_callblock:
        case en_fcallb:
        case en_pcallblock:
        case en_thiscall:
            return 1;
        case en_cl_reg:
        case en_conslabel:
        case en_destlabel:
        case en_addcast:
            return depth(node->v.p[0]);
        default:
            DIAG("error in depth routine.");
            return 1;
    }
}

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

void noids(AMODE *ap)
{
    switch (ap->mode)
    {
        case am_baseindxaddr:
        case am_baseindxdata:
        case am_pcindxdata:
        case am_pcindxaddr:
        case am_iiprepca:
        case am_iipostpca:
        case am_iiprepcd:
        case am_iipostpcd:
        case am_iiprea:
        case am_iipred:
        case am_iiposta:
        case am_iipostd:
            do_extend(ap, ap->length, F_DREG | F_VOL);
            break;
    }
}

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

AMODE *direct_data(AMODE *ap)
{
    AMODE *ap3;
    int oldlen = ap->length;
    switch (ap->mode)
    {
        case am_ainc:
        case am_adec:
        case am_ind:
            ap->mode = am_indx;
            ap->offset = makeintnode(en_icon, 0);
            return ap;
        case am_adirect:
        case am_direct:
        case am_immed:
        case am_indx:
        case am_pcindx:
            return ap;
        case am_pc:
            ap->mode = am_indx;
            ap->offset = makeintnode(en_icon, 0);
            return ap;
        default:
            freeop(ap);
            ap3 = temp_addr();
            ap->length = BESZ_DWORD;
            gen_code(op_lea, ap, ap3);
            ap3->mode = am_indx;
            ap3->offset = makeintnode(en_icon, 0);
            ap3->length = oldlen;
            freeop(ap);
            return ap3;
    }
}

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

AMODE *doindex(ENODE *node, enum e_node type)
{
    AMODE *ap,  *ap2,  *ap3;
    ENODE node2;
    int scale;
    switch (node->nodetype)
    {
        case en_icon:
            ap = gen_expr(node, FALSE, TRUE, BESZ_DWORD);
            break;
        case en_lsh:
            if ((prm_68020 && (scale = node->v.p[1]->v.i) < 4 && scale) && 
                (!prm_coldfire || (scale < 3)))
            {
                ap = gen_expr(node->v.p[0], FALSE, TRUE, BESZ_DWORD);
                if (node->v.p[0]->nodetype == en_bits)
                    ap = bit_load(ap, node->v.p[0], BESZ_DWORD);
                if (ap->mode != am_immed)
                    do_extend(ap, BESZ_DWORD, F_DREG);
                if (ap->mode == am_immed)
                {
                    while (--scale)
                        ap->offset->v.i <<= 1;
                }
                else
                {
                    do_extend(ap, BESZ_DWORD, F_DREG);
                    if (ap->mode == am_dreg)
                        ap->mode = am_baseindxdata;
                    else
                        ap->mode = am_baseindxaddr;
                    ap->sreg = ap->preg;
                    ap->preg =  - 1;
                    ap->scale = scale;
                    ap->offset = makeintnode(en_icon, 0);
                }
                break;
            }
        default:
            node2.v.p[0] = node;
            node2.nodetype = type;
            ap = gen_deref(&node2, BESZ_DWORD);
            switch (ap->mode)
            {
            case am_ainc:
            case am_adec:
                ap2 = temp_addr();
                gen_lea(ap->length, ap, ap2);
                freeop(ap);
                ap = ap2;
            case am_baseindxdata:
            case am_baseindxaddr:
                if (ap->sreg >= 0 && ap->preg >= 0)
                {
                    freeop(ap);
                    ap3 = temp_addr();
                    gen_lea(BESZ_DWORD, ap, ap3);
                    ap3->mode = am_ind;
                    ap = ap3;
                }

            }
            break;
    }
    return ap;
}

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

AMODE *gen_index(ENODE *node)
/*
 *      generate code to evaluate an index node (^+) and return
 *      the addressing mode of the result. This routine takes no
 *      flags since it always returns either am_ind or am_indx.
 */
{
    AMODE *ap1,  *ap2,  *ap3,  *ap;
    ENODE node2;

    int a = depth(node->v.p[1]) - depth(node->v.p[0]);
    int nsize;
    if (a <= 2)
    {
        ap1 = doindex(node->v.p[0], node->nodetype);
        //               nsize = natural_size(node->v.p[1]) ;
        //               if (nsize == 6 || nsize == -6)
        //                  aprtocx(ap1) ;
        ap2 = doindex(node->v.p[1], node->nodetype);
    }
    else
    {
        ap2 = doindex(node->v.p[1], node->nodetype);
        //               nsize = natural_size(node->v.p[0]) ;
        //               if (nsize == 6 || nsize == -6)
        //                  aprtocx(ap2) ;
        ap1 = doindex(node->v.p[0], node->nodetype);
    }
    tryagain: switch (ap1->mode)
    {
        case am_areg:
            switch (ap2->mode)
            {
            case am_areg:
                ap1->sreg = ap2->preg;
                ap1->mode = am_baseindxaddr;
                ap1->offset = makeintnode(en_icon, 0);
                ap1->scale = 0;
                return ap1;
            case am_dreg:
                ap1->sreg = ap2->preg;
                ap1->mode = am_baseindxdata;
                ap1->offset = makeintnode(en_icon, 0);
                ap1->scale = 0;
                return ap1;
            case am_adirect:
                if ((!prm_largedata && (prm_datarel || !prm_smalldata)) ||
                    prm_68020)
                {
                    ap1->mode = am_indx;
                    ap1->offset = ap2->offset;
                    return ap1;
                }
                ap = temp_addr();
                gen_lea(0, ap2, ap);
                ap1->mode = am_baseindxaddr;
                ap1->offset = makeintnode(en_icon, 0);
                ap1->scale = 0;
                ap1->sreg = ap->preg;
                return ap1;
            case am_immed:
                if ((!prm_largedata && (prm_datarel || !prm_smalldata)) ||
                    prm_68020)
                {
                    ap1->mode = am_indx;
                    ap1->offset = ap2->offset;
                    return ap1;
                }
                ap = temp_data();
                gen_codes(op_move, BESZ_DWORD, ap2, ap);
                ap1->mode = am_baseindxdata;
                ap1->offset = makeintnode(en_icon, 0);
                ap1->scale = 0;
                ap1->sreg = ap->preg;
                return ap1;
            case am_indx:
                if (prm_68020 || isambyte(ap2))
                {
                    ap1->mode = am_baseindxaddr;
                    ap1->offset = ap2->offset;
                    ap1->scale = 0;
                    ap1->sreg = ap2->preg;
                    return ap1;
                }
                freeop(ap2);
                ap = temp_addr();
                gen_lea(0, ap2, ap);
                ap->mode = am_baseindxaddr;
                ap->sreg = ap1->preg;
                ap->scale = 0;
                ap->offset = makeintnode(en_icon, 0);
                return ap;
            case am_ind:
                ap1->mode = am_baseindxaddr;

⌨️ 快捷键说明

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