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

📄 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 页
字号:
 *
 *			The first argument of this and other routines is a target for
 *			assignmennt.  If this is 0 and a target is needed a temp will be
 *			used; otherwise the target will be evaluated annd used.
 */
{
    IMODE *ap1,  *ap2,  *ap3;
    int lab0, lab1, lab2;
    int natsize, siz1;
    if (node == 0)
    {
//        DIAG("null node in gen_expr.");
        return 0;
    }
    switch (node->nodetype)
    {
        case en_cl_reg:
            ap1 = gen_expr( node->v.p[0], flags, size);
            return ap1;
        case en_cb:
            siz1 =  - ISZ_UCHAR;
            goto castjoin;
        case en_cub:
        case en_cbool:
            siz1 = ISZ_UCHAR;
            goto castjoin;
        case en_cw:
            siz1 =  - ISZ_USHORT;
            goto castjoin;
        case en_cuw:
            siz1 = ISZ_USHORT;
            goto castjoin;
        case en_ci:
            siz1 =  - ISZ_UINT;
            goto castjoin;
        case en_cui:
            siz1 = ISZ_UINT;
            goto castjoin;
        case en_cl:
            siz1 =  - ISZ_ULONG;
            goto castjoin;
        case en_cul:
            siz1 = ISZ_ULONG;
            goto castjoin;
        case en_cll:
            siz1 =  - ISZ_ULONGLONG;
            goto castjoin;
        case en_cull:
            siz1 = ISZ_ULONGLONG;
            goto castjoin;

        case en_cf:
            siz1 = ISZ_FLOAT;
            goto castjoin;
        case en_cd:
            siz1 = ISZ_DOUBLE;
            goto castjoin;
        case en_cld:
            siz1 = ISZ_LDOUBLE;
            goto castjoin;
        case en_cfi:
            siz1 = ISZ_IFLOAT;
            goto castjoin;
        case en_cri:
            siz1 = ISZ_IDOUBLE;
            goto castjoin;
        case en_clri:
            siz1 = ISZ_ILDOUBLE;
            goto castjoin;
        case en_cfc:
            siz1 = ISZ_CFLOAT;
            goto castjoin;
        case en_crc:
            siz1 = ISZ_CDOUBLE;
            goto castjoin;
        case en_clrc:
            siz1 = ISZ_CLDOUBLE;
            goto castjoin;
        case en_cp:
            siz1 = ISZ_UINT;
            castjoin: ap1 = gen_expr( node->v.p[0], flags, natural_size(node
                ->v.p[0]));
#ifdef XXXXX
            if (ap1->mode == i_immed) {
                if (isintconst(ap1->offset->nodetype))
                    if (siz1 <= ISZ_ULONGLONG) {
                        ap1->offset->nodetype = en_llucon;
                        ap1->offset->v.i = CastToInt(siz1,ap1->offset->v.i);
                    } else {
                        ap1->offset->nodetype = en_llucon;
                        ap1->offset->v.i = CastToInt(siz1,ap1->offset->v.f);   
                    }
                else if (isfloatconst(ap1->offset->nodetype))
                    if (siz1 <= ISZ_ULONGLONG) {
                        ap1->offset->nodetype = en_lrcon;
                        ap1->offset->v.f = CastToFloat(siz1,ap1->offset->v.i);
                    } else {
                        ap1->offset->nodetype = en_lrcon;
                        ap1->offset->v.f = CastToFloat(siz1,ap1->offset->v.i);
                    }
            }
#endif
            if (ap1->size == siz1)
                ap2 = ap1;
            else
            {
                gen_icode(i_assn, ap2 = tempreg(siz1, 0), ap1, 0);
            }
            return ap2;
        case en_structret:
            if (!structret_imode) {
                SYM *sp = makesym(sc_auto);
                ENODE *en;
                sp->tp = maketype(bt_int, stdintsize); // dummy so backend is happy
                sp->name = "structret";
                en = makenode(en_autocon, (void *)sp, 0);
                
                ap1 = xalloc(sizeof(IMODE));
                ap1->mode = i_direct;
                ap1->size = ISZ_ADDR;
                ap1->offset = en;
                if ((currentfunc->pascaldefn || currentfunc->isstdcall) &&
                    currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM*)
                    - 1)
                    sp->value.i = (currentfunc->tp->lst.head
                    ->value.i + ((currentfunc->tp->lst.head->tp->size + stdintsize-1)
                    &-stdintsize));
                else
                    if (declclass && !(currentfunc->value.classdata.cppflags
                        &PF_STATIC))
                        sp->value.i = stdretblocksize + stdintsize+(currentfunc
                            ->farproc * stdintsize);
                    else
                        sp->value.i = stdretblocksize+(currentfunc->farproc
                            *stdintsize);
                structret_imode = ap1;            
            }                        
            return structret_imode;
        case en_napccon:
        case en_nacon:
        case en_autocon:
        case en_autoreg:
        case en_absacon:
        case en_nalabcon:
            ap1 = make_imaddress(node, ISZ_ADDR);
            return ap1; /* return reg */
        case en_labcon:
            ap1 = xalloc(sizeof(IMODE));
            ap1->offset = node;
            ap1->mode = i_direct;
            ap1->size = size;
            return ap1; /* return reg */
        case en_imode:
            ap2 = node->v.p[0];
            return ap2; /* return reg */
        case en_boolcon:
        case en_ccon:
        case en_cucon:
        case en_icon:
        case en_lcon:
        case en_lucon:
        case en_iucon:
        case en_llcon:
        case en_llucon:
            ap1 = make_immed(node->v.i);
            ap1->offset->nodetype = node->nodetype;
            return ap1;
        case en_fcon:
        case en_rcon:
        case en_lrcon:
        case en_fimaginarycon:
        case en_rimaginarycon:
        case en_lrimaginarycon:
        case en_fcomplexcon:
        case en_rcomplexcon:
        case en_lrcomplexcon:
            ap1 = make_fimmed(node->v.f);
            ap1->offset->nodetype = node->nodetype;
            return ap1;
        case en_bool_ref:
        case en_b_ref:
        case en_w_ref:
        case en_ub_ref:
        case en_uw_ref:
        case en_l_ref:
		case en_a_ref:
		case en_ua_ref:
		case en_i_ref:
		case en_ui_ref:
        case en_ptr_ref:
        case en_ul_ref:
        case en_floatref:
        case en_doubleref:
        case en_longdoubleref:
        case en_ll_ref:
        case en_ull_ref:
        case en_fimaginaryref:
        case en_rimaginaryref:
        case en_lrimaginaryref:
        case en_fcomplexref:
        case en_rcomplexref:
        case en_lrcomplexref:
            ap1 = gen_deref(node, flags, size);
            return ap1;
        case en_regref:
            ap1 = xalloc(sizeof(IMODE));
            ap1->offset = node;
            ap1->mode = i_direct;
            ap1->size = ISZ_UINT;
            return ap1;
        case en_bits:
            size = natural_size(node->v.p[0]);
            ap1 = gen_expr( node->v.p[0], 0, size);
            ap1 = make_bf(node, ap1, size);
            return ap1;

        case en_asuminus:
            return gen_asunary(node, flags, size, i_neg);
        case en_ascompl:
            return gen_asunary(node, flags, size, i_not);
        case en_uminus:
            return gen_unary(node, flags, size, i_neg);
        case en_compl:
            return gen_unary(node, flags, size, i_not);
        case en_add:
        case en_addstruc:
            return gen_binary(node, flags, size, i_add);
        case en_addcast:
            lab0 = nextlabel++;
            ap1 = gen_expr( node, flags, size);
            gen_icgoto(i_je, lab0, ap1, make_immed(0));
            ap2 = gen_expr( node->v.p[1], 0, size);
            gen_icode(i_add, ap3 = genasn(0, size), ap1, ap2);
            gen_label(lab0);
            return ap3;
        case en_sub:
            return gen_binary(node, flags, size, i_sub);
        case en_and:
            return gen_binary(node, flags, size, i_and);
        case en_or:
            return gen_binary(node, flags, size, i_or);
        case en_xor:
            return gen_binary(node, flags, size, i_eor);
        case en_pmul:
            return gen_pmul(node, flags, size);
        case en_pdiv:
            return gen_pdiv(node, flags, size);
        case en_mul:
            return gen_binary(node, flags, size, i_smul);
        case en_umul:
            return gen_binary(node, flags, size, i_umul);
        case en_div:
            return gen_binary(node, flags, size, i_sdiv);
        case en_udiv:
            return gen_binary(node, flags, size, i_udiv);
        case en_mod:
            return gen_binary(node, flags, size, i_smod);
        case en_umod:
            return gen_binary(node, flags, size, i_umod);
        case en_alsh:
            return gen_binary(node, flags, size, i_asl);
        case en_arsh:
        case en_arshd:
            return gen_binary(node, flags, size, i_asr);
        case en_lsh:
            return gen_binary(node, flags, size, i_lsl);
        case en_rsh:
            return gen_binary(node, flags, size, i_lsr);
        case en_asadd:
            return gen_asbin(node, flags, size, i_asadd);
        case en_assub:
            return gen_asbin(node, flags, size, i_assub);
        case en_asand:
            return gen_asbin(node, flags, size, i_asand);
        case en_asor:
            return gen_asbin(node, flags, size, i_asor);
        case en_asxor:
            return gen_asbin(node, flags, size, i_aseor);
        case en_aslsh:
            return gen_asbin(node, flags, size, i_aslsl);
        case en_asrsh:
            return gen_asbin(node, flags, size, i_aslsr);
        case en_asalsh:
            return gen_asbin(node, flags, size, i_asasl);
        case en_asarsh:
        case en_asarshd:
            return gen_asbin(node, flags, size, i_asasr);
        case en_asmul:
            return gen_asbin(node, flags, size, i_assmul);
        case en_asumul:
            return gen_asbin(node, flags, size, i_asumul);
        case en_asdiv:
            return gen_asbin(node, flags, size, i_assdiv);
        case en_asudiv:
            return gen_asbin(node, flags, size, i_asudiv);
        case en_asmod:
            return gen_asbin(node, flags, size, i_assmod);
        case en_asumod:
            return gen_asbin(node, flags, size, i_asumod);
        case en_assign:
            return gen_assign(node, flags, size, FALSE);
        case en_refassign:
            return gen_assign(node, flags | F_NOVALUE, size, TRUE);
        case en_moveblock:
            return gen_moveblock(node, flags, size);
        case en_clearblock:
            return gen_clearblock(node, flags, size);
        case en_ainc:
            return gen_aincdec(node, flags, size, i_add);
        case en_adec:
            return gen_aincdec(node, flags, size, i_sub);
        case en_land:
        case en_lor:
        case en_eq:
        case en_ne:
        case en_lt:
        case en_le:
        case en_gt:
        case en_ge:
        case en_ult:
        case en_ule:
        case en_ugt:
        case en_uge:
        case en_not:
            return gen_relat(node);
        case en_cond:
            return gen_hook(node, flags, size);
        case en_void:
            gen_void(node->v.p[0]);
            return gen_expr( node->v.p[1], flags, size);
		case en_arrayindex:
			return gen_binary(node,flags,size,i_arrayindex);
		case en_array:
			return gen_binary(node,flags,size,i_array);
        case en_dvoid:
            ap1 = gen_expr( node->v.p[0], flags, size);
            gen_expr( node->v.p[1], flags, size);
            return ap1;
        case en_voidnz:
            lab0 = nextlabel++;
            falsejp(node->v.p[0]->v.p[0], lab0);
            gen_void(node->v.p[1]);
            gen_label(lab0);
            return gen_expr( node->v.p[0]->v.p[1], 0, ISZ_UINT); /* will typically
                be part of a void tree, or top of tree */
        case en_pfcall:
        case en_pfcallb:
        case en_pcallblock:
            return gen_pfcall(node, flags, size);
        case en_fcall:
        case en_callblock:
        case en_fcallb:
        case en_sfcall:
        case en_scallblock:
        case en_sfcallb:
        case en_intcall:
        case en_trapcall:
        case en_thiscall:
            return gen_fcall(node, flags, size);
        case en_repcons:
            return gen_repcons(node);
        case en_conslabel:
            if (node->v.p[1]->v.sp->nullsym)
                return 0;
            node->v.p[1]->v.sp->value.classdata.conslabel = nextlabel;
            gen_label(nextlabel++);
            return gen_expr( node->v.p[0], flags, size);
        case en_destlabel:
            if (node->v.p[1]->v.sp->nullsym)
                return 0;
            node->v.p[1]->v.sp->value.classdata.destlabel = nextlabel;
            gen_label(nextlabel++);
            return gen_expr(node->v.p[0], flags, size);
        default:
        case en_movebyref:
             /* explicitly uncoded */
            DIAG("uncoded node in gen_expr.");
            return 0;
    }
}

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

IMODE *gen_void(ENODE *node)
{
    gen_expr( node, 0, natural_size(node));
    //   gen_code(op_void,0,0);
    return 0;
}

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

int natural_size(ENODE *node)
/*
 *      return the natural evaluation size of a node.
 */
{
    int siz0, siz1;
    if (node == 0)
        return 0;
    switch (node->nodetype)
    {
        case en_structret:
            return ISZ_ADDR;
        case en_asuminus:
        case en_ascompl:
        case en_bits:
        case en_cl_reg:
            return natural_size(node->v.p[0]);
            ;
        case en_ccon:
        case en_cucon:
            return ISZ_UCHAR;
        case en_lcon:
        case en_icon:
            return  - ISZ_UINT;
        case en_lucon:
        case en_iucon:
            return ISZ_UINT;
        case en_rcon:
        case en_doubleref:
            return ISZ_DOUBLE;
        case en_lrcon:
        case en_longdoubleref:
            return ISZ_LDOUBLE;
        case en_floatref:
        case en_fcon:
            return ISZ_FLOAT;
        case en_fimaginaryref:
        case en_fimaginarycon:
        case en_cfi:
            return ISZ_IFLOAT;
        case en_rimaginaryref:
        case en_rimaginarycon:
        case en_cri:
            return ISZ_IDOUBLE;
        case en_lrimaginaryref:
        case en_lrimaginarycon:
        case en_clri:
            return ISZ_ILDOUBLE;
        case en_fcomplexref:
        case en_fcomplexcon:
        case en_cfc:
            return ISZ_CFLOAT;
        case en_rcomplexref:
        case en_rcomplexcon:
        case en_crc:
            return ISZ_CDOUBLE;
        case en_lrcomplexref:
        case en_lrcomplexcon:
        case en_clrc:
            return ISZ_CLDOUBLE;
        case en_boolcon:
            return ISZ_BOOL;
        case en_llucon:
            return ISZ_ULONGLONG;
        case en_llcon:
            return  - ISZ_ULONGLONG;
        case en_imode:
            return ISZ_ADDR;
        case en_cl:
        case en_l_ref:
            return  - ISZ_ULONG;
		case en_i_ref:
		case en_ci:
			return - ISZ_UINT ;
		case en_a_ref:
			return ISZ_ADDR;
        case en_ptr_ref:
        case en_trapcall:
        case en_labcon:
        case en_nacon:
        case en_autocon:
        case en_napccon:
        case en_absacon:
        case en_nalabcon:
            return ISZ_ADDR;
        case en_autoreg:
            return ISZ_REG;
        case en_fcall:
        case en_callblock:
        case en_fcallb:
        case en_sfcall:
        case en_scallblock:
        case en_sfcallb:
        case en_pfcall:
        case en_pcallblock:
        case en_pfcallb:
        case en_intcall:
            return natural_size(node->v.p[1]);
        case en_tempref:
            return ISZ_UINT;
        case en_regref:
            return ISZ_REG;
        case en_ull_ref:
        case en_cull:
            return ISZ_ULONGLONG;
        case en_ll_ref:
        case en_cll:
            return  - ISZ_ULONGLONG;
        case en_ul_ref:
        case en_cul:
            return ISZ_ULONG;
		case en_ui_ref:
		case en_cui:
			return ISZ_UINT;
		case en_ua_ref:
        case en_cp:
			return ISZ_ADDR;
        case en_bool_ref:
        case en_cbool:
            return ISZ_BOOL;
        case en_ub_ref:
        case en_cub:
            return ISZ_UCHAR;
        case en_b_ref:
        case en_cb:
            return  - ISZ_UCHAR;
        case en_uw_ref:
        case en_cuw:
            return ISZ_USHORT;
        case en_cw:
        case en_w_ref:
            return  - ISZ_USHORT;

⌨️ 快捷键说明

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