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 + -
显示快捷键?