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

📄 gexpr386.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 
Copyright 1994-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

This program is derived from the cc68k complier by 
Matthew Brandt (mattb@walkingdog.net) 

You may contact the author of this derivative at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
 */
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "gen386.h"
#include "diag.h"
extern OCODE *peep_tail,  *frame_ins;
extern SYM *currentfunc;
extern int retlab;

#define ABS(x) ( (x) < 0 ? -(x) : (x))
/*
 *      this module contains all of the code generation routines
 *      for evaluating expressions and conditions.
 */
extern int prm_optmult;
extern SYM *declclass;
extern int stdinttype, stdunstype, stdintsize, stdldoublesize;
extern int stdaddrsize;
extern int stackadd, stackmod;
extern int prm_largedata;
extern AMODE push[], pop[];
extern int prm_68020, prm_intrinsic;
extern int regs[3], sregs[3];
extern long nextlabel;
extern long lc_maxauto;
extern int prm_cmangle;
extern int prm_cplusplus;
extern int prm_farkeyword;

extern int floatstack_mode;
AMODE freg0[] = 
{
    {
        am_freg, 0
    }
};
AMODE sreg[] = 
{
    {
        am_dreg, BESZ_DWORD 
    }
};

int genning_inline;
static int ldx[] = 
{
    op_mov, 0, op_lds, op_les, op_lfs, op_lgs, op_lss
};

/* little ditty to allocate stack space for floating point
 * conversions and return a pointer to it
 * it will be at the bottom for standard stack frames; top for 
 * using ESP for frames
 * 0-7 used for fistp, 8-BESZ_IFLOAT used for long intermediate values
 */
AMODE *floatconvpos(void)
{
    AMODE *ap1;
    int constv = 16;
    //   if (prm_cplusplus)
    //      constv = 12;
    if (!floatstack_mode)
    {
        if (!lc_maxauto)
        {
            OCODE *new = xalloc(sizeof(OCODE));
            new->opcode = op_sub;
            new->oper1 = makedreg(ESP);
            new->oper2 = make_immed(constv);
            new->back = frame_ins;
            new->fwd = frame_ins->fwd;
            frame_ins->fwd->back = new;
            frame_ins->fwd = new;
        }
        else
        {
            frame_ins->oper2->offset->v.i += constv;
        }
        floatstack_mode += constv;
    }
    ap1 = xalloc(sizeof(AMODE));
    ap1->mode = am_indisp;
    ap1->preg = EBP;
    if (prm_farkeyword)
        ap1->seg = SS;
    ap1->offset = makeintnode(en_icon,  - lc_maxauto - constv);
    ap1->length = BESZ_DWORD ;
    return ap1;
}

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

int defseg(ENODE *node)
{
    int rv = 0; // default DS
    if (!prm_farkeyword)
        return rv;
    while (castvalue(node))
        node = node->v.p[0];
    if (node->nodetype == en_napccon)
        rv = CS;
    if (node->nodetype == en_autocon)
        rv = SS;
    return rv;
}

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

AMODE *truncateFloat(AMODE *ap1, int size)
{
    AMODE *ap = floatconvpos();
    do_extend(ap1, size, F_FREG);
    gen_codefs(op_fstp, size, ap, 0);
    gen_codefs(op_fld, size, ap, 0);
    return ap1;
}

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

int chksize(int lsize, int rsize)
{
    int l, r;
    l = lsize;
    r = rsize;
    if (l < 0)
        l =  - l;
    if (r < 0)
        r =  - r;
    if (rsize == BESZ_BOOL)
     /* BESZ_BOOL is used for bools, which are the smallest type now */
        if (lsize == BESZ_BOOL)
            return FALSE;
        else
            return TRUE;
    if (lsize == BESZ_BOOL)
        return FALSE;
    if (rsize ==  BESZ_FARPTR)
        if (lsize ==  BESZ_FARPTR)
            return FALSE;
        else
            return l >= BESZ_QWORD;
        else
            if (lsize ==  BESZ_FARPTR)
                return r < BESZ_QWORD;
    return (l > r);
}

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

AMODE *fstack(void)
{
    AMODE *ap = xalloc(sizeof(AMODE));
    ap->mode = am_freg;
    ap->length = BESZ_LDOUBLE;
    ap->preg = 0;
    ap->sreg = 0;
    ap->offset = 0;
    ap->tempflag = TRUE;
    return (ap);
}

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

AMODE *make_muldivval(AMODE *ap)
{
    int temp;
    AMODE *ap1 = make_label(queue_muldivval(ap->offset->v.i));
    ap1->mode = am_direct;
    return (ap1);
}

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

void make_floatconst(AMODE *ap)
{
    int size = ap->length;
    if (isintconst(ap->offset->nodetype))
    {
        ap->offset->v.f = ap->offset->v.i;
        ap->offset->nodetype = en_rcon;
        size = BESZ_FLOAT;
    }
    else
    {
        switch (ap->offset->nodetype)
        {
            case en_fcon:
                size = BESZ_FLOAT;
                break;
            case en_rcon:
                size = BESZ_DOUBLE;
                break;
            case en_lrcon:
                size = BESZ_LDOUBLE;
                break;
            case en_fimaginarycon:
                size = BESZ_IFLOAT;
                break;
            case en_rimaginarycon:
                size = BESZ_IDOUBLE;
                break;
            case en_lrimaginarycon:
                size = BESZ_ILDOUBLE;
                break;
            case en_fcomplexcon:
                size = BESZ_CFLOAT;
                break;
            case en_rcomplexcon:
                size = BESZ_CDOUBLE;
                break;
            case en_lrcomplexcon:
                size = BESZ_CLDOUBLE;
                break;
        }
    }
    if (ap->offset->v.f == 1.0)
    {
        ap->mode = am_fconst;
        ap->preg = fcone;
    }
    else if (ap->offset->v.f == 0.0)
    {
        ap->mode = am_fconst;
        ap->preg = fczero;
    }
    else if (size >= BESZ_CFLOAT)
    {
        AMODE *ap1;
        int siz1 = size -13;
        int o = prm_optmult ;
        prm_optmult = FALSE;
        if (siz1>BESZ_DOUBLE)
            siz1++;
        ap1 = make_label(queue_floatval(ap->offset->v.c.r, siz1));
        queue_floatval(ap->offset->v.c.i, siz1);
        ap->mode = am_direct;
        ap->length = size;
        ap->offset = ap1->offset;
        prm_optmult = o ;
    }
    else
    {
        AMODE *ap1 = make_label(queue_floatval(ap->offset->v.f, size));
        ap->mode = am_direct;
        ap->length = size;
        ap->offset = ap1->offset;
    }
}

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

AMODE *make_label(int lab)
/*
 *      construct a reference node for an internal label number.
 */
{
    ENODE *lnode;
    AMODE *ap;
    lnode = xalloc(sizeof(ENODE));
    lnode->nodetype = en_labcon;
    lnode->v.i = lab;
    ap = xalloc(sizeof(AMODE));
    ap->mode = am_immed;
    ap->offset = lnode;
    return ap;
}

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

AMODE *makesegreg(int seg)
{
    AMODE *ap = xalloc(sizeof(AMODE));
    ap->mode = am_seg;
    ap->seg = seg;
    return ap;
}

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

AMODE *make_immed(long i)
/*
 *      make a node to reference an immediate value i.
 */
{
    AMODE *ap;
    ENODE *ep;
    ep = xalloc(sizeof(ENODE));
    ep->nodetype = en_icon;
    ep->v.i = i;
    ap = xalloc(sizeof(AMODE));
    ap->mode = am_immed;
    ap->offset = ep;
    return ap;
}

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

AMODE *make_immedt(long i, int size)
/*
 *      make a node to reference an immediate value i.
 */
{
    switch (size)
    {
        case BESZ_BYTE:
            case  - 1: i &= 0xff;
            break;
        case BESZ_WORD:
            case  - BESZ_WORD: i &= 0xffff;
            break;
        case BESZ_DWORD :
            case  - BESZ_DWORD : i &= 0xffffffff;
            break;
    }
    return make_immed(i);
}

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

AMODE *make_offset(ENODE *node)
/*
 *      make a direct reference to a node.
 */
{
    AMODE *ap;
    ap = xalloc(sizeof(AMODE));
    ap->mode = am_direct;
    ap->offset = node;
    ap->seg = 0;
    return ap;
}

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

AMODE *make_stack(int number)
{
    AMODE *ap = xalloc(sizeof(AMODE));
    ENODE *ep = xalloc(sizeof(ENODE));
    ep->nodetype = en_icon;
    ep->v.i =  - number;
    ap->mode = am_indisp;
    ap->preg = ESP;
    ap->offset = ep;
    return (ap);
}

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

void do_ftol(void)
{
    if (prm_intrinsic)
    {
        AMODE *sp, vv,  *e8,  *e0,  *ax;
        gen_code(op_sub, sp = makedreg(ESP), make_immed(12));
        memset(&vv, 0, sizeof(vv));
        vv.mode = am_indisp;
        vv.preg = ESP;
        vv.offset = e8 = makeintnode(en_icon, 8);
        gen_code(op_fnstcw, copy_addr(&vv), 0);
        gen_codes(op_mov, BESZ_WORD, ax = makedreg(EAX), copy_addr(&vv));
        gen_codes(op_or, 1, makedreg(4), make_immed(0xc));
        vv.offset = makeintnode(en_icon, BESZ_LDOUBLE);
        gen_codes(op_mov, BESZ_WORD, copy_addr(&vv), ax);
        gen_code(op_fldcw, copy_addr(&vv), 0);
        vv.offset = e0 = makeintnode(en_icon, 0);
        gen_codes(op_fistp, BESZ_DOUBLE, copy_addr(&vv), 0);
        vv.offset = e8;
        gen_code(op_fldcw, copy_addr(&vv), 0);
        vv.offset = e0;
        gen_codes(op_mov, BESZ_DWORD , makedreg(EAX), copy_addr(&vv));
        gen_code(op_add, sp, make_immed(12));

    }
    else
        call_library("__ftol");
}

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

AMODE *complexstore(ENODE *node, AMODE *apr, int novalue, int size)
{
    AMODE *ap2 ;
    int offs = 0, siz = BESZ_BYTE;
    if (apr->mode == am_frfr)
    {

⌨️ 快捷键说明

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