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

📄 iexpr.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
        case en_cd:
            return ISZ_DOUBLE;
        case en_cld:
            return ISZ_LDOUBLE;
        case en_cf:
            return ISZ_ULONGLONG;
        case en_not:
        case en_compl:
        case en_uminus:
        case en_assign:
        case en_refassign:
        case en_lassign:
        case en_ainc:
        case en_adec:
        case en_moveblock:
        case en_stackblock:
        case en_movebyref:
        case en_clearblock:
            return natural_size(node->v.p[0]);
        case en_add:
        case en_sub:
        case en_addstruc:
        case en_umul:
        case en_udiv:
        case en_umod:
        case en_pmul:
		case en_arrayindex:
        case en_mul:
        case en_div:
        case en_pdiv:
        case en_mod:
        case en_and:
        case en_or:
        case en_xor:
        case en_asalsh:
        case en_asarsh:
        case en_alsh:
        case en_arsh:
        case en_lsh:
        case en_rsh:
        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_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_asarshd:
        case en_arshd:
            siz0 = natural_size(node->v.p[0]);
            siz1 = natural_size(node->v.p[1]);
            if (chksize(siz1, siz0))
                return siz1;
            else
                return siz0;
		case en_array:
			return ISZ_ADDR ;
        case en_void:
        case en_cond:
        case en_repcons:
            return natural_size(node->v.p[1]);
        case en_voidnz:
            return natural_size(node->v.p[1]);
        case en_conslabel:
        case en_destlabel:
        case en_addcast:
            return natural_size(node->v.p[0]);
        default:
            DIAG("natural size error.");
            break;
    }
    return 0;
}

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

void gen_compare(ENODE *node, int btype, int label)
/*
 *      generate code to do a comparison of the two operands of
 *      node.
 */
{
    IMODE *ap1,  *ap2;
    int size;
    size = natural_size(node);
    ap1 = gen_expr( node->v.p[0], 0, size);
    ap2 = gen_expr( node->v.p[1], 0, size);
    gen_icgoto(btype, label, ap1, ap2);
}

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

IMODE *gen_set(ENODE *node, int btype, int aa)
{
    IMODE *ap1,  *ap2,  *ap3;
    int size;
    ap1 = gen_expr( node->v.p[0], 0, size);
    ap2 = gen_expr( node->v.p[1], 0, size);
    ap3 = tempreg(ISZ_UINT, 0);
    gen_icode(btype, ap3, ap2, ap1);

    return ap3;
}

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

IMODE *defcond(ENODE *node)
{
    IMODE *ap1,  *ap2,  *ap3;
    int size;
    ap1 = gen_expr( node->v.p[0], 0, size);
    ap2 = make_immed(0);
    ap3 = tempreg(ISZ_UINT, 0);
    gen_icode(i_setne, ap3, ap2, ap1);
    return ap3;
}

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


static IMODE *truerelat(ENODE *node)
{
    IMODE *ap1;
    if (node == 0)
        return 0;
    switch (node->nodetype)
    {
        case en_eq:
            ap1 = gen_set(node, i_sete, 0);
            break;
        case en_ne:
            ap1 = gen_set(node, i_setne, 0);
            break;
        case en_lt:
            ap1 = gen_set(node, i_setl, 0);
            break;
        case en_le:
            ap1 = gen_set(node, i_setle, 0);
            break;
        case en_gt:
            ap1 = gen_set(node, i_setg, 0);
            break;
        case en_ge:
            ap1 = gen_set(node, i_setge, 0);
            break;
        case en_ult:
            ap1 = gen_set(node, i_setc, 0);
            break;
        case en_ule:
            ap1 = gen_set(node, i_setbe, 0);
            break;
        case en_ugt:
            ap1 = gen_set(node, i_seta, 0);
            break;
        case en_uge:
            ap1 = gen_set(node, i_setnc, 0);
            break;
        case en_not:
            ap1 = defcond(node);
            break;
        default:
            DIAG("True-relat error");
            break;
    }
    ap1->size = ISZ_UCHAR;
    return ap1;
}

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

static int complex_relat(ENODE *node)
{
    if (!node)
        return 0;
    switch (node->nodetype)
    {
        case en_cl_reg:
            return complex_relat(node->v.p[0]);
        case en_ull_ref:
        case en_ll_ref:
        case en_cull:
        case en_cll:
        case en_llcon:
        case en_llucon:
            return 1;
        case en_bits:
		case en_a_ref:
		case en_ua_ref:
		case en_i_ref:
		case en_ui_ref:
        case en_l_ref:
        case en_cl:
        case en_ul_ref:
        case en_cul:
		case en_ci:
		case en_cui:
        case en_cp:
        case en_ub_ref:
        case en_cub:
        case en_bool_ref:
        case en_cbool:
        case en_b_ref:
        case en_cb:
        case en_uw_ref:
        case en_cuw:
        case en_cw:
        case en_w_ref:
        case en_cd:
        case en_cld:
        case en_cf:
        case en_cfc:
        case en_crc:
        case en_clrc:
        case en_cfi:
        case en_cri:
        case en_clri:
        case en_uminus:
        case en_ainc:
        case en_adec:
        case en_moveblock:
        case en_stackblock:
        case en_movebyref:
        case en_clearblock:
            return complex_relat(node->v.p[0]);
        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_doubleref:
        case en_lrcon:
        case en_longdoubleref:
        case en_fcon:
        case en_floatref:
        case en_fimaginaryref:
        case en_rimaginaryref:
        case en_lrimaginaryref:
        case en_fcomplexref:
        case en_rcomplexref:
        case en_lrcomplexref:
        case en_fimaginarycon:
        case en_rimaginarycon:
        case en_lrimaginarycon:
        case en_fcomplexcon:
        case en_rcomplexcon:
        case en_lrcomplexcon:
        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 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_not:
        case en_compl:
            return 1;
        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_addcast:
        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_array:
            return complex_relat(node->v.p[0]) || complex_relat(node->v.p[1]);
        case en_void:
        case en_cond:
        case en_voidnz:
            return complex_relat(node->v.p[1]);
        case en_conslabel:
        case en_destlabel:
            return complex_relat(node->v.p[0]);
        case en_sfcall:
        case en_sfcallb:
        case en_scallblock:
        case en_pfcall:
        case en_pfcallb:
        case en_thiscall:
        case en_fcall:
        case en_intcall:
        case en_callblock:
        case en_fcallb:
        case en_pcallblock:
            return 0;
        default:
            DIAG("error in complex_relat routine.");
            return 1;
    }
}

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

IMODE *gen_relat(ENODE *node)
{
    long lab1, lab2;
    IMODE *ap1;
    int size = natural_size(node);
    if (node->nodetype != en_land && node->nodetype != en_lor && !complex_relat
        (node->v.p[0]) && !complex_relat(node->v.p[1]))
    {
        ap1 = truerelat(node);
    }
    else
    {
        ap1 = tempreg(ISZ_UINT, 0);
        lab1 = nextlabel++, lab2 = nextlabel++;
        truejp(node, lab1);
        gen_iiconst(ap1,0);
        gen_igoto(lab2);
        gen_label(lab1);
        gen_iiconst(ap1,1);
        gen_label(lab2);
    }
    return ap1;
}

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

void truejp(ENODE *node, int label)
/*
 *      generate a jump to label if the node passed evaluates to
 *      a true condition.
 */
{
    IMODE *ap1;
    int siz1;
    int lab0;
    if (node == 0)
        return ;
    switch (node->nodetype)
    {
        case en_eq:
            gen_compare(node, i_je, label);
            break;
        case en_ne:
            gen_compare(node, i_jne, label);
            break;
        case en_lt:
            gen_compare(node, i_jl, label);
            break;
        case en_le:
            gen_compare(node, i_jle, label);
            break;
        case en_gt:
            gen_compare(node, i_jg, label);
            break;
        case en_ge:
            gen_compare(node, i_jge, label);
            break;
        case en_ult:
            gen_compare(node, i_jc, label);
            break;
        case en_ule:
            gen_compare(node, i_jbe, label);
            break;
        case en_ugt:
            gen_compare(node, i_ja, label);
            break;
        case en_uge:
            gen_compare(node, i_jnc, label);
            break;
        case en_land:
            lab0 = nextlabel++;
            falsejp(node->v.p[0], lab0);
            truejp(node->v.p[1], label);
            gen_label(lab0);
            break;
        case en_lor:
            truejp(node->v.p[0], label);
            truejp(node->v.p[1], label);
            break;
        case en_not:
            falsejp(node->v.p[0], label);
            break;
        default:
            siz1 = natural_size(node);
            ap1 = gen_expr( node, 0, siz1);
            gen_icgoto(i_jne, label, ap1, make_immed(0));
            break;
    }
}

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

void falsejp(ENODE *node, int label)
/*
 *      generate code to execute a jump to label if the expression
 *      passed is false.
 */
{
    IMODE *ap;
    int siz1;
    int lab0;
    if (node == 0)
        return ;
    switch (node->nodetype)
    {
        case en_eq:
            gen_compare(node, i_jne, label);
            break;
        case en_ne:
            gen_compare(node, i_je, label);
            break;
        case en_lt:
            gen_compare(node, i_jge, label);
            break;
        case en_le:
            gen_compare(node, i_jg, label);
            break;
        case en_gt:
            gen_compare(node, i_jle, label);
            break;
        case en_ge:
            gen_compare(node, i_jl, label);
            break;
        case en_ult:
            gen_compare(node, i_jnc, label);
            break;
        case en_ule:
            gen_compare(node, i_ja, label);
            break;
        case en_ugt:
            gen_compare(node, i_jbe, label);
            break;
        case en_uge:
            gen_compare(node, i_jc, label);
            break;
        case en_land:
            falsejp(node->v.p[0], label);
            falsejp(node->v.p[1], label);
            break;
        case en_lor:
            lab0 = nextlabel++;
            truejp(node->v.p[0], lab0);
            falsejp(node->v.p[1], label);
            gen_label(lab0);
            break;
        case en_not:
            truejp(node->v.p[0], label);
            break;
        default:
            siz1 = natural_size(node);
            ap = gen_expr( node, 0, siz1);
            gen_icgoto(i_je, label, ap, make_immed(0));
            break;
    }
}

⌨️ 快捷键说明

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