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

📄 outco68.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 <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "gen68.h"
#include "diag.h"
#include "lists.h"

#define FULLVERSION

extern struct slit *strtab;
extern ASMNAME oplst[];
extern int global_flag;
extern enum e_sg curseg;
extern SYM *currentfunc;
extern int prm_asmfile;
extern DBGBLOCK *DbgBlocks[];
extern int prm_debug;
extern int prm_68020;
extern int prm_smalldata;

#define PUTWORD(p,x) { tempstore = (x) ; \
*(*(p))++=(((tempstore)>>8)&255); \
*(*(p))++=((tempstore)&255); }

static int fpcop = 1;
static int tempstore; // used in PUTWORD

int outcode_base_address;

EMIT_TAB segs[MAX_SEGS];
LINEBUF *linelist,  *linetail;
VIRTUAL_LIST *virtualFirst,  *virtualLast;


static LABEL **labelbuf;
void outcode_file_init(void)
{
    int i;
    labelbuf = xalloc(400 *sizeof(LABEL*));

    for (i = 0; i < MAX_SEGS; i++)
        memset(&segs[i], 0, sizeof(segs[i]));
    linelist = 0;
    virtualFirst = virtualLast = 0;

} void outcode_func_init(void)
{
    int i;
    //   memset(labelbuf,0,400 * sizeof(LABEL *)) ;

    for (i = 0; i < MAX_SEGS; i++)
        segs[i].curbase = segs[i].curlast;
    if (currentfunc)
    if (curseg == virtseg)
    {
        currentfunc->mainsym->offset = outcode_base_address = 0;
    }
    else
        currentfunc->mainsym->offset = outcode_base_address =
            segs[codeseg].curbase;
}

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

void InsertLabel(int lbl, int address, int seg)
{
    int x = lbl / 512;
    if (!labelbuf[x])
    {
        global_flag++;
        labelbuf[x] = xalloc(512 *sizeof(LABEL));
        global_flag--;
    }
    labelbuf[x][lbl % 512].address = address;
    labelbuf[x][lbl % 512].seg = seg;
}

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

int LabelAddress(int lbl)
{
    if (labelbuf)
    {
        LABEL *p = labelbuf[lbl / 512];
        if (p)
            return p[lbl % 512].address;
    }
    return  - 1;
    //   return labelbuf[lbl/512][lbl%512].address ;
}

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

int LabelSeg(int lbl)
{
    return labelbuf[lbl / 512][lbl % 512].seg;
}

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

void InsertLine(int address, int line, int file)
{
    LINEBUF *l;
    global_flag++;
    l = xalloc(sizeof(LINEBUF));
    global_flag--;
    l->address = address;
    l->lineno = line;
    l->file = file;
    if (linelist)
        linetail = linetail->next = l;
    else
        linelist = linetail = l;
}

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

EMIT_TAB *gettab(int seg)
{
    if (seg == virtseg)
        return virtualLast->seg;
    else
    {
        EMIT_TAB *rv = &segs[seg];
        if (!rv->first)
        {
            global_flag++;
            rv->first = rv->last = xalloc(sizeof(EMIT_LIST));
            global_flag--;
        }
        return rv;
    }
}

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

void emit(int seg, unsigned char *data, int len)
{
    EMIT_TAB *tab = gettab(seg);
    int ofs = 0;
    if (!tab->first)
    {
        global_flag++;
        tab->first = tab->last = xalloc(sizeof(EMIT_LIST));
        global_flag--;
    }
    tab->last->lastfilled = tab->last->filled;
    tab->curlast += len;
    while (len)
    {
        int size = len >= 1024 ? 1024 : len;
        if (tab->last->filled + len > 1024)
        {
            int address = tab->last->address + tab->last->filled;
            global_flag++;
            tab->last = tab->last->next = xalloc(sizeof(EMIT_LIST));
            tab->last->address = address;
            global_flag++;
        }

        memcpy(tab->last->data + tab->last->filled, data + ofs, size);
        tab->last->filled += size;
        len -= size;
        ofs += size;
    }
}

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

void reverseemit(int seg, unsigned char *data, int len)
{
    char buf[256];
    int i;
    for (i = 0; i < len; i++)
        buf[len - i - 1] = data[i];
    emit(seg, buf, len);
}

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

void write_to_seg(int seg, int offset, char *value, int len)
{
    EMIT_TAB *tab = gettab(seg);
    EMIT_LIST *lst = tab->first;
    while (lst->address + lst->filled < offset)
        lst = lst->next;
    memcpy(lst->data + offset - lst->address, value, len);
}

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

void gen_symbol_fixup(enum mode xmode, int seg, int address, SYM *pub, int size,
    int ofs)
{
    FIXUP *fixup;
    EMIT_TAB *tab = gettab(seg);
    global_flag++;
    fixup = xalloc(sizeof(FIXUP));
    global_flag--;
    fixup->fmode = xmode;
    fixup->address = address;
    fixup->size = size;
    fixup->ofs = ofs;
    fixup->sym = pub;
    if (tab->last->fixups)
        tab->last->lastfixup = tab->last->lastfixup->next = fixup;
    else
        tab->last->fixups = tab->last->lastfixup = fixup;

} void gen_label_fixup(enum mode xmode, int seg, int address, int lab, int size,
    int ofs)
{
    FIXUP *fixup;
    EMIT_TAB *tab = gettab(seg);
    global_flag++;
    fixup = xalloc(sizeof(FIXUP));
    global_flag--;
    fixup->fmode = xmode;
    fixup->address = address;
    fixup->size = size;
    fixup->ofs = ofs;
    fixup->label = lab;
    if (tab->last->fixups)
        tab->last->lastfixup = tab->last->lastfixup->next = fixup;
    else
        tab->last->fixups = tab->last->lastfixup = fixup;

} void outcode_dump_muldivval(void){}
void outcode_dump_browsedata(unsigned char *buf, int len)
{
    emit(browseseg, buf, len);
}

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

void outcode_dumplits(void)
{
    struct slit *v = strtab;
    int val = 0;
    xstringseg();
    while (v != 0)
    {
        InsertLabel(v->label, segs[stringseg].curlast, stringseg);
        emit(curseg, v->str, v->len - 1);

        if (v->type)
            emit(curseg, (unsigned char*) &val, 2);
        else
            emit(curseg, (unsigned char*) &val, 1);
        v = v->next;
    } nl();
}

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

void outcode_genref(SYM *sp, int offset)
{
    EMIT_TAB *seg = gettab(curseg);
    reverseemit(curseg, &offset, 4);

    gen_symbol_fixup(fm_symbol, curseg, seg->last->address + seg->last
        ->lastfilled, sp, 4, offset);
}

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

void outcode_gen_labref(int n)
{
    int i = 0;
    EMIT_TAB *seg = gettab(curseg);
    emit(curseg, &i, 4);
    gen_label_fixup(fm_label, curseg, seg->last->address + seg->last
        ->lastfilled, n, 4, 0);
}

/* the labels will already be resolved well enough by this point */
void outcode_gen_labdifref(int n1, int n2)
{
    int i = LabelAddress(n1) - LabelAddress(n2);
    EMIT_TAB *seg = gettab(curseg);
    emit(curseg, &i, 4);
}

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

void outcode_gensrref(SYM *sp, int val)
{
    int vv = 0;
    EMIT_TAB *seg = gettab(curseg);
    emit(curseg, &vv, 4);
    gen_symbol_fixup(fm_symbol, curseg, seg->last->address + seg->last
        ->lastfilled, sp, 4, 0);
    reverseemit(curseg, &val, 4);
}

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

void outcode_genstorage(int len)
{
    char buf[256];
    memset(buf, 0, 256);
    while (len >= 256)
    {
        emit(curseg, buf, 256);
        len -= 256;
    }
    if (len)
        emit(curseg, buf, len);
}

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

void outcode_genfloat(long double val)
{
    float f = val;
    reverseemit(curseg, &f, 4);
}

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

void outcode_gendouble(long double val)
{
    double d = val;
    reverseemit(curseg, &d, 8);
}

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

void outcode_genlongdouble(long double val)
{
    reverseemit(curseg, &val, 10);
}

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

void outcode_genstring(char *string, int len)
{
    emit(curseg, string, len);
}

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

void outcode_genbyte(int val)
{
    emit(curseg, &val, 1);
}

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

void outcode_genword(int val)
{
    reverseemit(curseg, &val, 2);
}

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

void outcode_genlong(int val)
{
    reverseemit(curseg, &val, 4);
}

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

void outcode_genlonglong(LLONG_TYPE val)
{
    int vv = val;
    #ifdef BCC32
        val = val < 0 ?  - 1: 0;
    #else 
        val = val >> 32;
    #endif 
    reverseemit(curseg, &val, 4);
    reverseemit(curseg, &vv, 4);
}

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

void outcode_align(int size)
{
    EMIT_TAB *seg = gettab(curseg);
    int adr = seg->last->address + seg->last->filled;
    adr = size - adr % size;
    if (size != adr)
        outcode_genstorage(adr);
}

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

void outcode_put_label(int lab)
{
    EMIT_TAB *seg = gettab(curseg);
    InsertLabel(lab, seg->last->address + seg->last->filled, curseg);
}

///////////////////////////////////////////////////

static int putbased(OCODE *ins, AMODE *data, int reg, unsigned char **p)
{
    long val;
    int resolved = 1;

    val = ResolveOffset(ins, data->offset, &resolved);
    if (!resolved)
    {
        if (prm_68020)
        {
            PUTWORD(p, 0x130 + (data->sreg << 12) + (data->mode ==
                am_baseindxdata ? 0 : 0x8000) + (data->scale << 9) + (data->sz 

⌨️ 快捷键说明

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