iout.c

来自「CC386 is a general-purpose 32-bit C comp」· C语言 代码 · 共 1,907 行 · 第 1/3 页

C
1,907 行
字号
}

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

static void op_seta(QUAD *q)
{
    putset(q, "U>");
}

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

static void op_setnz(QUAD *q)
{
    putset(q, "!=");
}

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

static void op_sete(QUAD *q)
{
    putset(q, "==");
}

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

static void op_setnc(QUAD *q)
{
    putset(q, "U>=");
}

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

static void op_setbe(QUAD *q)
{
    putset(q, "U<=");
}

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

static void op_setne(QUAD *q)
{
    putset(q, "!=");
}

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

static void op_setl(QUAD *q)
{
    putset(q, "S<");
}

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

static void op_setg(QUAD *q)
{
    putset(q, "S>");
}

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

static void op_setle(QUAD *q)
{
    putset(q, "S<=");
}

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

static void op_setge(QUAD *q)
{
    putset(q, "S>=");
}

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

static void op_parm(QUAD *q)
{
    oprintf(icdFile, "\tPARM\t");
    putamode(q->dc.left);
}

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

static void op_parmadj(QUAD *q)
{
    oprintf(icdFile, "\tPARMADJ\t");
    putamode(q->dc.left);
}

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

static void op_parmblock(QUAD *q)
{
    fputs("\tPARMBLOCK", icdFile);
    oprintf(icdFile, "{%d}=\t ", (int)q->dc.right);
    putamode(q->dc.left);
}

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

static void op_cppini(QUAD *q)
{
    fputs("\tCPPINI", icdFile);
}

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

static void op_block(QUAD *q)
{
    oprintf(icdFile, "\tBLOCK\t%d", q->dc.label + 1);
}

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

static void op_livein(QUAD *q)
{
    DIAG("op_livein: propogated live-in node");
}

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

static void op_icon(QUAD *q)
{
    oputc('\t', icdFile);
    putamode(q->ans);
    oprintf(icdFile, " = #%llX", q->dc.v.i);
}

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

static void op_fcon(QUAD *q)
{
    oputc('\t', icdFile);
    putamode(q->ans);
    oprintf(icdFile, " = #%f", q->dc.v.f);
}
static void op_imcon(QUAD *q)
{
    oputc('\t', icdFile);
    putamode(q->ans);
    oprintf(icdFile, " = #%f", q->dc.v.f);
}
static void op_cxcon(QUAD *q)
{
    oputc('\t', icdFile);
    putamode(q->ans);
    oprintf(icdFile, " = #%f + %f * I", q->dc.v.c.r, q->dc.v.c.i);
}
static void op_prologue(QUAD *q)
{
	oprintf(icdFile,"\tPROLOGUE");
}
static void op_epilogue(QUAD *q)
{
	oprintf(icdFile,"\tEPILOGUE");
}
static void op_blockstart(QUAD *q)
{
	oprintf(icdFile,"\tDBGBLK START #%d",q->dc.label);
}
static void op_blockend(QUAD *q)
{
	oprintf(icdFile,"\tDBGBLK END #%d",q->dc.label);
}
/* List of opcodes
 * This list MUST be in the same order as the op_ enums 
 */
static void(*oplst[])() = 
{
     /* NOPROTO */
	    op_nop, op_line, op_passthrough, op_label, op_goto, op_gosub, op_trap, op_int,
        op_ret, op_rett, op_add, op_sub, op_udiv, op_umod, op_sdiv, op_smod,
        op_umul, op_smul, op_lsl, op_lsr, op_asl, op_asr, op_neg, op_not,
        op_and, op_or, op_eor, 
        op_asadd, op_assub, op_asudiv, op_asumod, op_assdiv, op_assmod, op_asumul, op_assmul,
        op_aslsl, op_aslsr, op_asasl, op_asasr, op_asand, op_asor, op_aseor, op_asuminus, op_ascompl,
        op_setne, op_sete, op_setc, op_seta, op_setnc,
        op_setbe, op_setl, op_setg, op_setle, op_setge, op_assn, op_genword,
        op_coswitch, op_swbranch, op_dc, op_assnblock, op_clrblock, op_jc, op_ja, op_je, op_jnc, op_jbe,
        op_jne, op_jl, op_jg, op_jle, op_jge, op_parm, op_parmadj, op_parmblock, op_array, op_arrayindex, 
        op_cppini, op_block, op_livein, op_icon, op_fcon, op_imcon, op_cxcon, op_prologue, op_epilogue,
		op_blockstart, op_blockend

};
//-------------------------------------------------------------------------

char *dumpns(NAMESPACE *ns, char *buf, int *done)
{
    if (!ns)
        return buf;
    buf = dumpns(ns->next, buf, done);
    *done = 1;
    *buf++ = '@';
    strcpy(buf, ns->sp->name + prm_cmangle);
    buf += strlen(buf);
    return buf;
}
//-------------------------------------------------------------------------
void putsym(char *buf, SYM *sp, char *p)
{
    int done = 0;
    if (!p)
    {
        buf[0] = 0;
        return ;
    }
    if (sp->staticlabel)
        sprintf(buf, "L_%d", sp->value.i);
    else if (sp->alias)
        strcpy(buf, sp->alias);
    else
    {
        if (sp->pascaldefn)
        {
            char *q = buf;
            if (prm_cmangle)
                p++;
            while (*p)
                *q++ = toupper(*p++);
            *q = 0;
        }
        else if (sp->isstdcall)
        {
            if (prm_cmangle)
                p++;
            strcpy(buf, p);
        }
        else
        {
            char *q;
            if (sp->mangled && !(sp->tp->type == bt_func || sp->tp->type ==
                bt_ifunc))
            {
                q = dumpns(sp->value.classdata.parentns, buf, &done);
                if (done)
                {
                    *q++ = '@';
                    strcpy(q, p + prm_cmangle);
                }
                else
                    strcpy(q, p);
            }
            else
                strcpy(buf, p);
            if (prm_cplusplus)
            {
                // problematic for compiling templates via ASM and TASM
                q = buf;
                while (q = strchr(q, '#'))
                    *q = '%';
            }
        }
    }
}

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

void putconst(ENODE *offset)
/*
 *      put a constant to the icdFile file.
 */
{
    switch (offset->nodetype)
    {
        case en_icon:
        case en_lcon:
        case en_iucon:
        case en_lucon:
        case en_ccon:
        case en_boolcon:
        case en_cucon:
            oprintf(icdFile, "%lX", offset->v.i);
            break;
        case en_llcon:
        case en_llucon:
            oprintf(icdFile, "%llX", offset->v.i);
            break;
        case en_fcon:
        case en_rcon:
        case en_lrcon:
        case en_fimaginarycon:
        case en_rimaginarycon:
        case en_lrimaginarycon:
            oprintf(icdFile, "%e", (double)offset->v.f);
			break;
        case en_tempref:
            oprintf(icdFile, "TEMP%d", ((SYM*)offset->v.sp)->value.i);
            break;
        case en_autoreg:
            oprintf(icdFile, "%s:REG", ((SYM*)offset->v.sp)->name);
            break;
        case en_autocon:
            oprintf(icdFile, "%s:LINK", ((SYM*)offset->v.sp)->name);
            if (offset->v.sp->value.i >= stdretblocksize)
                oprintf(icdFile, "+%d", (offset->v.sp->value.i - stdretblocksize)/stdintsize);
            break;
        case en_nalabcon:
            oprintf(icdFile, "L_%ld:RAM", offset->v.sp->value.i);
            break;
        case en_labcon:
            oprintf(icdFile, "L_%ld:PC", offset->v.i);
            break;
        case en_napccon:
            oprintf(icdFile, "%s:PC", ((SYM*)offset->v.sp)->name);
            break;
        case en_nacon:
            oprintf(icdFile, "%s:RAM", ((SYM*)offset->v.sp)->name);
            break;
        case en_absacon:
            oprintf(icdFile, "$%lX:ABS", ((SYM*)offset->v.sp)->name);
            break;
        case en_add:
            putconst(offset->v.p[0]);
            oprintf(icdFile, "+");
            putconst(offset->v.p[1]);
            break;
        case en_sub:
            putconst(offset->v.p[0]);
            oprintf(icdFile, "-");
            putconst(offset->v.p[1]);
            break;
        case en_uminus:
            oputc('-', icdFile);
            putconst(offset->v.p[0]);
            break;
        default:
            DIAG("putconst: illegal constant node.");
            break;
    }
}

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

void putlen(int l)
/*
 *      append the length field to a value
 */
{
    switch (l)
    {
        case ISZ_NONE:
            oprintf(icdFile, ".0");
            break;
        case ISZ_BOOL:
            oprintf(icdFile, ".BOOL");
            break;
		case ISZ_ADDR:
            oprintf(icdFile, ".A");
            break;
        case ISZ_UCHAR:
            oprintf(icdFile, ".UC");
            break;
            case  - ISZ_UCHAR: oprintf(icdFile, ".C");
            break;
        case ISZ_USHORT:
            oprintf(icdFile, ".US");
            break;
            case  - ISZ_USHORT: oprintf(icdFile, ".S");
            break;
		case ISZ_UINT:
			oprintf(icdFile, ".UI");
			break;
		case -ISZ_UINT:
			oprintf(icdFile, ".I");
			break;
        case ISZ_ULONG:
            oprintf(icdFile, ".UL");
            break;
            case  - ISZ_ULONG: oprintf(icdFile, ".L");
            break;
        case ISZ_ULONGLONG:
            oprintf(icdFile, ".ULL");
            break;
        case  - ISZ_ULONGLONG: oprintf(icdFile, ".LL");
            break;
        case ISZ_FLOAT:
            oprintf(icdFile, ".F");
            break;
        case ISZ_DOUBLE:
            oprintf(icdFile, ".D");
            break;
        case ISZ_LDOUBLE:
            oprintf(icdFile, ".LD");
            break;
        case ISZ_IFLOAT:
            oprintf(icdFile, ".IF");
            break;
        case ISZ_IDOUBLE:
            oprintf(icdFile, ".ID");
            break;
        case ISZ_ILDOUBLE:
            oprintf(icdFile, ".ILD");
            break;
        case ISZ_CFLOAT:
            oprintf(icdFile, ".CF");
            break;
        case ISZ_CDOUBLE:
            oprintf(icdFile, ".CD");
            break;
        case ISZ_CLDOUBLE:
            oprintf(icdFile, ".CLD");
            break;
        default:
            DIAG("putlen: illegal length field.");
            break;
    }
}

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

void putamode(IMODE *ap)
/*
 *      output a general addressing mode.
 */
{
    /* We want to see if the compiler does anything wrong with
     * volatiles
     */
    if (ap->offset && ap->offset->cflags &DF_VOL)
        oputc('%', icdFile);
    switch (ap->mode)
    {
        case i_immed:
            oputc('#', icdFile);
            putconst(ap->offset);
            break;
        case i_ind:
            oputc('*', icdFile);
        case i_direct:
            putconst(ap->offset);
            break;
        case i_rsp:
            oprintf(icdFile, "SP");
            break;
        case i_rret:
            oprintf(icdFile, "RV");
            break;
        case i_rlink:
            oprintf(icdFile, "LINK");
            break;
        case i_rstruct:
            oprintf(icdFile, "STRUCTRET");
            return ;
        case i_rstructstar:
            oprintf(icdFile, "*STRUCTRET");
            return ;
        default:
            DIAG("putamode: illegal address mode.");
            break;
    }
    if (ap->bits)
        oprintf(icdFile, "{%d:%d}", ap->startbit, ap->bits);
    putlen(ap->size);
}

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

void put_code(QUAD *q)
/*
 *      output a generic instruction.
 */
{
    (*oplst[q->dc.opcode])(q);
    oputc('\n', icdFile);
}

/*
 * Low level routinne to rewrite code for processor and dump it.
 * Here we only need dump
 */
void rewrite_icode(void)
{
    QUAD *q = intermed_head;
    while (q)
    {
        put_code(q);
        q = q->fwd;
    }
    intermed_head = 0;
}

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

void gen_strlab(SYM *sp)
/*
 *      generate a named label.
 */
{
    char buf[100];
    putsym(buf, sp, sp->name);
	newlabel = TRUE;
    oprintf(icdFile, "%s:\n", buf);
    dataofs = 0;
}

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

void put_label(int lab)
/*
 *      icdFile a compiler generated label.
 */
{
    sprintf(dataname, "L_%d", lab);
    oprintf(icdFile, "%s:\n", dataname);
    dataofs = 0;
}

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

void put_staticlabel(long label)
{
    put_label(label);
}

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

void genfloat(float val)
/*
 * Output a float value
 */
{
    if (gentype == floatgen && outcol < 60)
    {
        oprintf(icdFile, ",%f", val);
        outcol += 8;
    }
    else
    {
        nl();
        oprintf(icdFile, "\tDC.S\t%f", val);
        gentype = floatgen;
        outcol = 19;
    }
    dataofs += 4;
}

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

void gendouble(double val)
/*
 * Output a double value
 */
{
    if (gentype == doublegen && outcol < 60)
    {
        oprintf(icdFile, ",%f", val);
        outcol += 8;
    }
    else
    {
        nl();
        oprintf(icdFile, "\tDC.D\t%f", val);
        gentype = doublegen;
        outcol = 19;
    }
    dataofs += 8;
}

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

void genlongdouble(long double val)
/*
 * Output a double value
 */
{
    if (gentype == longdoublegen && outcol < 60)
    {
        oprintf(icdFile, ",%f", val);
        outcol += 8;
    }
    else
    {
        nl();
        oprintf(icdFile, "\tDC.X\t%f", val);
        gentype = longdoublegen;
        outcol = 19;
    }
    dataofs += 8;
}

//-------------------------------------------------------------------------
int genstring(char *str, int uselong, int len)
/*
 * Generate a string literal
 */
{
    if (uselong)
    {
        len /= 2;
        while (len--)
        {
            genword(*((short*)str));
            str += 2;
        }
        return pstrlen(str) *2;
    }
    else
    {
        while (len--)
            genbyte(*str++);
        return strlen(str);
    }
}

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

void genbyte(long val)
/*
 * Output a byte value
 */
{
    if (gentype == bytegen && outcol < 60)
    {
        oprintf(icdFile, ",$%X", val &0x00ff);
        outcol += 4;
    }
    else
    {
        nl();
        oprintf(icdFile, "\tDC.B\t$%X", val &0x00ff);
        gentype = bytegen;
        outcol = 19;
    }
    dataofs += 1;
}
void genbool(int val)
{
	genbyte(val);
}
//-------------------------------------------------------------------------

void genword(long val)
/*
 * Output a word value
 */
{
    if (gentype == wordgen && outcol < 58)

⌨️ 快捷键说明

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