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

📄 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 页
字号:

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

IMODE *gen_asunary( ENODE *node, int flags, int size, int op)
{
    IMODE *ap;
    int nsize = natural_size(node->v.p[0]);
    ap = gen_expr( node->v.p[0], 0, nsize);
    gen_icode(op, ap, ap, 0);
    return ap;
}

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

IMODE *gen_asbin( ENODE *node, int flags, int size, int op)
/*
 *      generate a plus equal or a minus equal node.
 */
{
    IMODE *ap,  *ap1,  *ap2;
    int ssize, rsize;
    ssize = natural_size(node->v.p[0]);
    rsize = natural_size(node->v.p[1]);
    ap1 = gen_expr( node->v.p[0], 0, ssize);
    ap2 = gen_expr( node->v.p[1], 0, rsize);
#ifdef XXXXX
    if ((ap1->mode != i_direct || ap1->offset->nodetype != en_tempref) && (ap2->mode != i_direct || ap2->offset->nodetype != en_tempref)) {
        IMODE *ap3 ;
        gen_icode(op,ap3 = genasn(0,ssize), ap1, ap2);
        gen_icode(i_assn,ap1,ap3,0);     
        if (ap1->size == ap3->size && !ap1->bits)
            return ap3;   
    } else
#endif
    gen_icode(op, ap1, ap2, 0);
    return ap1 ;
#ifdef XXXXX
    ap = xalloc(sizeof(IMODE));
    ap->bits = ap1->bits;
    ap->startbit = ap1->startbit;
    ap->offset = ap1->offset;
    ap->mode = ap1->mode;
    ap->size = ap1->size;
    return (ap);
#endif
}

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

IMODE *gen_moveblock(ENODE *node, int flags, int size)
/*
 * Generate code to copy one structure to another
 */
{
    IMODE *ap1,  *ap2;
    if (!node->size)
        return (0);
    ap1 = gen_expr( node->v.p[0], F_VOL, ISZ_UINT);
    ap2 = gen_expr( node->v.p[1], F_VOL, ISZ_UINT);
    gen_icode(i_assnblock, ap1, ap2, make_immed(node->size));
    return (ap1);
}
IMODE *gen_clearblock(ENODE *node, int flags, int size)
/*
 * Generate code to copy one structure to another
 */
{
    IMODE *ap1,  *ap2;
    if (!node->size)
        return (0);
    ap1 = gen_expr( node->v.p[0], F_VOL, ISZ_UINT);
    gen_icode(i_clrblock, 0, ap1, make_immed(node->size));
    return (ap1);
}

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

IMODE *gen_assign( ENODE *node, int flags, int size, int ref)
/*
 *      generate code for an assignment node. if the size of the
 *      assignment destination is larger than the size passed then
 *      everything below this node will be evaluated with the
 *      assignment size.
 */
{
    IMODE *ap1, *ap2;
    ENODE *enode;
    if (ref)
    {
        enode = makenode(node->v.p[0]->nodetype, makenode(en_cp, node->v.p[0]
            ->v.p[0], 0), 0);
    }
    else
        enode = node->v.p[0];
	ap1 = gen_expr(enode, 0, natural_size(node->v.p[0]));
    ap2 = gen_expr(node->v.p[1], 0, natural_size(node->v.p[1]));
#ifdef XXXXX
    if ((ap1->mode != i_direct || ap1->offset->nodetype != en_tempref) && (ap2->mode != i_direct || ap2->offset->nodetype != en_tempref)) {
        IMODE *ap3 = ap2;
        gen_icode(i_assn,ap2 = genasn(0,ap2->size), ap2, 0);
    }
#endif
    gen_icode(i_assn, ap1, ap2, 0);
    if (ap1->size == ap2->size && !ap1->bits)
        return ap2;
    return ap1;
}

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

IMODE *gen_aincdec( ENODE *node, int flags, int size, int op)
/*
 *      generate an auto increment or decrement node. op should be
 *      either op_add (for increment) or op_sub (for decrement).
 */
{
    IMODE *ap1, *ap2,*ap3;
    int siz1;
    siz1 = natural_size(node->v.p[0]);
	ap2 = gen_expr(node->v.p[1], 0, siz1);
    if (flags &F_NOVALUE)
     /* dont need result */
    {
        ap1 = gen_expr( node->v.p[0], F_ADDR, siz1);
        gen_icode(op, ap1, ap1, ap2);
        return ap1;
    }
    ap1 = gen_expr( node->v.p[0], F_ADDR, siz1);
	ap3 = tempreg(siz1,0);
	gen_icode(i_assn, ap3, ap1, 0);
    gen_icode(op, ap1, ap1, ap2);
    return ap3;
}

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

int push_param(ENODE *ep, int size)
/*
 *      push the operand expression onto the stack.
 */
{
    IMODE *ap;
    int rv;
    switch (ep->nodetype)
    {
        case en_imode:
            ap = ep->v.p[0];
            gen_nodag(i_parm, 0, ap, 0);
            rv = ap->size;
            break;
        default:
            rv = natural_size(ep);
            ap = gen_expr( ep, F_ADDR, rv);
            gen_nodag(i_parm, 0, ap, 0);
            rv = ap->size;
            break;
    }
    return (rv < 0 ?  - rv: rv);
}

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

int push_stackblock(ENODE *ep)
/*
 * Push a structure on the stack
 */
{
    IMODE *ap;
    int sz = ep->size;
    if (!sz)
        return (0);
    switch (ep->nodetype)
    {
        case en_imode:
            ap = ep->v.p[0];
            break;
        default:
            ap = gen_expr( ep, F_ADDR, sz);
            break;
    }
    gen_icode(i_parmblock, 0, ap, (IMODE*)sz);
    sz = sz < 0 ?  - sz: sz;
    sz += ISZ_UINT - ISZ_UCHAR;
    sz /= ISZ_UINT;
    sz *= ISZ_UINT;
    return sz;
}

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

int gen_parms(ENODE *plist, int size)
/*
 *      push a list of parameters onto the stack and return the
 *      size of parameters pushed.
 */
{
    int i;
    i = 0;
    while (plist != 0)
    {
        if (plist->nodetype == en_stackblock)
            i += push_stackblock(plist->v.p[0]);
        else
            i += push_param(plist->v.p[0], size);
        plist = plist->v.p[1];
    }
    return i;
}

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

IMODE *gen_tcall(ENODE *node, int flags)
/*
 *      generate a trap call node and return the address mode
 *      of the result.
 */
{
    IMODE *ap,  *result;
    int i, siz1 = ISZ_UINT;
    ap = make_offset(node->v.p[0]->v.p[0]);
    ap->mode = i_immed;
    gen_igosub(i_int, ap);
    if (!(flags &F_NOVALUE)) {
        ap = xalloc(sizeof(IMODE));
        *ap = rret;
        ap->size = siz1;
    }
    return ap;
}

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

IMODE *inlinecall(ENODE *node, int flags)
{
    ENODE *nameref = node,  *thisn = 0;
    SYM *sp;
    IMODE *ap = 0;
    int size;

    if (nameref->nodetype == en_thiscall)
    {
        thisn = nameref->v.p[0];
        nameref = nameref->v.p[1];
    }
    if (nameref->nodetype == en_callblock || nameref->nodetype == en_scallblock)
    {
        size = ISZ_UINT;
        nameref = nameref->v.p[1];
    }
    else
        size = nameref->v.p[0]->v.i;

    nameref = nameref->v.p[1]->v.p[0]->v.p[0];
    if (nameref->nodetype == en_nacon || nameref->nodetype == en_napccon)
    {
        sp = nameref->v.sp;
        if (sp && (sp->value.classdata.cppflags &PF_INLINE))
        {
            int oldretlab = retlab;
            IMODE *ap;
            SYM *oldcurfunc = currentfunc;
            currentfunc = sp;
            retlab = nextlabel++;
            #ifdef XXXXX
                if (sp->value.classdata.cppflags &PF_CONSTRUCTOR)
                {
                    SYM *psp = sp->parentclass;
                    if (psp && psp->value.classdata.baseclass->vtabsp)
                    {
                        ENODE *ts = makenode(en_nacon, psp
                            ->value.classdata.baseclass->vtabsp, 0);
                        thisn = makenode(en_a_ref, thisn, 0);
                        ts = makenode(en_assign, thisn, ts);
                        gen_expr(ts, FALSE, TRUE, ISZ_UINT);
                    }
                }
            #endif 
            genstmt(sp->value.classdata.inlinefunc->stmt);
            if (!(flags &F_NOVALUE)) {
                ap = xalloc(sizeof(IMODE));
                *ap = rret;
                ap->size = size;
            }
        }
    }
    return ap;
}

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

IMODE *gen_fcall( ENODE *node, int flags, int size)
/*
 *      generate a function call node and return the address mode
 *      of the result.
 */
{
    IMODE *ap;
    int i, siz1;
    ENODE *pushthis = 0;
    /* if it returns a structure */
    if (ap = inlinecall(node, flags))
        return ap;
    if (node->nodetype != en_callblock && node->nodetype != en_scallblock)
        if (ap = HandleIntrins(node, flags &F_NOVALUE))
            return ap;
        if (node->nodetype == en_thiscall)
        {
            pushthis = node->v.p[0];
            node = node->v.p[1];
            i = ISZ_UINT;
        }
    if (node->nodetype == en_callblock || node->nodetype == en_scallblock)
    {
        siz1 = ISZ_ADDR;
    }
    else
    {
        siz1 = node->v.p[0]->v.i;
    }
    if (node->nodetype == en_callblock)
    {
        i += gen_parms(node->v.p[1]->v.p[1]->v.p[1]->v.p[0], size);
        ap = gen_expr( node->v.p[0], F_ADDR, ISZ_ADDR);
        gen_icode(i_parm, 0, ap, 0);
        i += ISZ_ADDR;
        node = node->v.p[1];
        siz1 = ISZ_UINT;
    }
    else
    {
        i += gen_parms(node->v.p[1]->v.p[1]->v.p[0], size); /* generate
            parameters */
    }
    if (node->nodetype == en_trapcall)
    {
        /* trap call */
        gen_igosub(i_trap, make_immed(node->v.p[1]->v.p[0]->v.i));
    }
    else if (node->nodetype == en_intcall)
    {
        /* int call */
        ap = make_offset(node->v.p[0]);
        ap->mode = i_immed;
        gen_igosub(i_int, ap);
    }
    else if (pushthis)
    {
//        IMODE *ap2 = gen_expr(pushthis, FALSE, TRUE, ISZ_UINT);
//        gen_icode(i_parm, 0, ap2, 0);
    }
    /* named function */
    if (node->v.p[1]->v.p[0]->nodetype == en_imode)
    {
        ap = node->v.p[1]->v.p[0]->v.p[0]->v.p[0]->v.sp;
        gen_igosub(i_gosub, ap);
    }
    else
    /* pointer to function */
    {
        ap = gen_expr( node->v.p[1]->v.p[0]->v.p[0], 0, ISZ_UINT);
        gen_igosub(i_gosub, ap);
    }
    /* undo pars and make a temp for the result */
    if (node->nodetype != en_fcallb && node->nodetype != en_fcall && node
        ->nodetype != en_callblock)
    if (i != 0)
    {
//        gen_nodag(i_parmadj, 0, make_parmadj(i), 0);
    }
    if (!(flags &F_NOVALUE)) {
        ap = xalloc(sizeof(IMODE));
        *ap = rret;
        ap->size = siz1;
    }
    return ap;
}

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

IMODE *gen_repcons(ENODE *node)
/*
 *      generate a function call node and return the address mode
 *      of the result.
 */
{
    IMODE *ax,  *cx,  *ap,  *ap1,  *ap2,  *ap3,  *ap4;
    ENODE *pushthis = 0,  *onode = node;
    int i = 0, siz1;
    int lab;
    int regax, regdx, regcx;
    node = node->v.p[1];
        if (node->nodetype == en_thiscall)
        {
            pushthis = node->v.p[0];
            node = node->v.p[1];
            i = ISZ_UINT;
        }
    ap1 = gen_expr( onode->v.p[0]->v.p[0], 0, ISZ_UINT);
    ap3 = genasn(onode->v.p[0]->v.p[0], ISZ_UINT);
    if (pushthis)
    {
        ap2 = genasn(pushthis, ISZ_UINT);
    }
    gen_label(lab = nextlabel++);

    /* named function */
    if (node->v.p[1]->v.p[0]->nodetype == en_imode)
    {
        ap = node->v.p[1]->v.p[0]->v.p[0]->v.p[0]->v.sp;
        gen_igosub(i_gosub, ap);
    }
    else
    /* pointer to function */
    {
        ap = gen_expr( node->v.p[1]->v.p[0]->v.p[0], 0, ISZ_UINT);
        gen_igosub(i_gosub, ap);
    }
    gen_icode(i_add, ap3, ap3, make_immed((int)node->v.p[0]->v.p[1]->v.p[0]));
    gen_icode(i_sub, ap1, ap1, make_immed(1));
    gen_icgoto(i_jg, lab, ap1, make_immed(0));
}

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

IMODE *gen_pfcall( ENODE *node, int flags, int size)
/*
 *      generate a function call node and return the address mode
 *      of the result.
 */
{
    IMODE *ap;
    ENODE *pushthis = 0;
    int i, siz1;
    ENODE *invnode = 0,  *anode,  *node2;
    if (ap = inlinecall(node, flags))
        return ap;

    /* invert the parameter list */
    if (node->nodetype == en_pcallblock || node->nodetype == en_scallblock)
        anode = node->v.p[1]->v.p[1]->v.p[1]->v.p[0];
    else
        anode = node->v.p[1]->v.p[1]->v.p[0];
    while (anode)
    {
        invnode = makenode(anode->nodetype, anode->v.p[0], invnode);
        anode = anode->v.p[1];
    }
    /* if it returns a structure */
        if (node->nodetype == en_thiscall)
        {
            pushthis = node->v.p[0];
            node = node->v.p[1];
            i = ISZ_UINT;
        }
    if (node->nodetype == en_pcallblock || node->nodetype == en_scallblock)
    {
        siz1 = ISZ_UINT;
    }
    else
    {
        siz1 = node->v.p[0]->v.i;
    }
    if (pushthis)
    {
  //      IMODE *ap2 = gen_expr(pushthis, FALSE, TRUE, ISZ_UINT);
  //      gen_icode(i_parm, 0, ap2, 0);
    }
    if (node->nodetype == en_callblock || node->nodetype == en_scallblock)
    {
        i = gen_parms(invnode, size);
        ap = gen_expr( node->v.p[0], F_ADDR, ISZ_ADDR);
        gen_icode(i_parm, 0, ap, 0);
        i += ISZ_ADDR;
        node = node->v.p[1];
        siz1 = ISZ_UINT;
    }
    else
    {
        i = gen_parms(invnode, size); /* generate parameters */
        siz1 = natural_size(node->v.p[1]);
    }
    if (node->nodetype == en_trapcall)
    {
        /* trap call */
        gen_igosub(i_trap, make_immed(node->v.p[1]->v.p[0]->v.i));
    }
    else if (node->nodetype == en_intcall)
    {
        /* int call */
        ap = make_offset(node->v.p[0]);
        ap->mode = i_immed;
        gen_igosub(i_int, ap);
    }
    else if (pushthis)
    {
        IMODE *ap2 = gen_expr( pushthis, 0, ISZ_UINT);
        gen_icode(i_parm, 0, ap2, 0);
    }
    /* named function */
    if (node->v.p[1]->v.p[0]->nodetype == en_imode)
    {
        ap = node->v.p[1]->v.p[0]->v.p[0]->v.p[0];
        gen_igosub(i_gosub, ap);
    }
    else
    /* pointer to function */
    {
        ap = gen_expr( node->v.p[1]->v.p[0]->v.p[0], 0, ISZ_UINT);
        gen_igosub(i_gosub, ap);
    }
    if (!(flags &F_NOVALUE)) {
        ap = xalloc(sizeof(IMODE));
        *ap = rret;
        ap->size = size;
    }
    return ap;
}

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

IMODE *gen_expr( ENODE *node, int flags, int size)
/*
 *      general expression evaluation. returns the addressing mode
 *      of the result.

⌨️ 快捷键说明

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