Prepare section based linker

This commit is contained in:
drmortalwombat 2021-09-19 22:22:16 +02:00
parent 10bb751449
commit d3d20bee26
13 changed files with 996 additions and 532 deletions

View File

@ -369,6 +369,10 @@ void * sformat(void * data, putstrfn fn, const char * fmt, int * fps)
{
data = fn(data, (char *)*fps++);
}
else if (c == 'c')
{
buff[bi++] = *fps++;
}
else if (c)
{
buff[bi++] = c;

View File

@ -3067,521 +3067,9 @@ ByteCodeBasicBlock* ByteCodeProcedure::CompileBlock(InterCodeProcedure* iproc, I
return block;
}
const char* ByteCodeProcedure::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc)
void ByteCodeProcedure::Disassemble(FILE* file, ByteCodeGenerator* generator, InterCodeProcedure* proc)
{
if (tmp == BC_REG_ADDR)
return "ADDR";
else if (tmp == BC_REG_ACCU)
return "ACCU";
else if (tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
{
int i = 0;
while (i < proc->mTempOffset.Size() && proc->mTempOffset[i] != tmp - BC_REG_TMP)
i++;
if (i < proc->mTempOffset.Size())
sprintf_s(buffer, 10, "T%d", i);
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else
{
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
}
void ByteCodeProcedure::Disassemble(FILE * file, ByteCodeGenerator * generator, InterCodeProcedure * proc)
{
fprintf(file, "--------------------------------------------------------------------\n");
if (proc->mIdent)
fprintf(file, "%s:\n", proc->mIdent->mString);
char tbuffer[10];
#if 0
for (int i = 0; i < proc->mTemporaries.Size(); i++)
printf("T%d = $%.2x\n", i, BC_REG_TMP + proc->mTempOffset[i]);
#endif
int i = 0;
while (i < mProgSize)
{
ByteCode bc = ByteCode(generator->mMemory[mProgStart + i] / 2);
fprintf(file, "%04x:\t", mProgStart + i);
i++;
switch (bc)
{
case BC_NOP:
fprintf(file, "NOP");
break;
case BC_EXIT:
fprintf(file, "EXIT");
break;
case BC_CONST_8:
fprintf(file, "MOVB\t%s, #%d", TempName(generator->mMemory[mProgStart + i], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_CONST_P8:
fprintf(file, "MOV\t%s, #%d", TempName(generator->mMemory[mProgStart + i], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_CONST_N8:
fprintf(file, "MOV\t%s, #%d", TempName(generator->mMemory[mProgStart + i], tbuffer, proc), int(generator->mMemory[mProgStart + i + 1]) - 0x100);
i += 2;
break;
case BC_CONST_16:
fprintf(file, "MOV\t%s, #$%04x", TempName(generator->mMemory[mProgStart + i], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_CONST_32:
fprintf(file, "MOVD\t%s, #$%08x", TempName(generator->mMemory[mProgStart + i], tbuffer, proc), uint32(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2] + 0x10000 * generator->mMemory[mProgStart + i + 3] + 0x1000000 * generator->mMemory[mProgStart + i + 4]));
i += 5;
break;
case BC_LOAD_REG_8:
fprintf(file, "MOVB\tACCU, %s", TempName(generator->mMemory[mProgStart + i], tbuffer, proc));
i += 1;
break;
case BC_STORE_REG_8:
fprintf(file, "MOVB\t%s, ACCU", TempName(generator->mMemory[mProgStart + i], tbuffer, proc));
i += 1;
break;
case BC_LOAD_REG_16:
fprintf(file, "MOV\tACCU, %s", TempName(generator->mMemory[mProgStart + i], tbuffer, proc));
i += 1;
break;
case BC_STORE_REG_16:
fprintf(file, "MOV\t%s, ACCU", TempName(generator->mMemory[mProgStart + i], tbuffer, proc));
i += 1;
break;
case BC_LOAD_REG_32:
fprintf(file, "MOVD\tACCU, %s", TempName(generator->mMemory[mProgStart + i], tbuffer, proc));
i += 1;
break;
case BC_STORE_REG_32:
fprintf(file, "MOVD\t%s, ACCU", TempName(generator->mMemory[mProgStart + i], tbuffer, proc));
i += 1;
break;
case BC_ADDR_REG:
fprintf(file, "MOV\tADDR, %s", TempName(generator->mMemory[mProgStart + i], tbuffer, proc));
i += 1;
break;
case BC_LOAD_ABS_8:
fprintf(file, "MOVUB\t%s, $%04x", TempName(generator->mMemory[mProgStart + i + 2], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 3;
break;
case BC_LOAD_ABS_U8:
fprintf(file, "MOVUB\t%s, $%04x", TempName(generator->mMemory[mProgStart + i + 2], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 3;
break;
case BC_LOAD_ABS_I8:
fprintf(file, "MOVSB\t%s, $%04x", TempName(generator->mMemory[mProgStart + i + 2], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 3;
break;
case BC_LOAD_ABS_16:
fprintf(file, "MOV\t%s, $%04x", TempName(generator->mMemory[mProgStart + i + 2], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 3;
break;
case BC_LOAD_ABS_32:
fprintf(file, "MOVD\t%s, $%04x", TempName(generator->mMemory[mProgStart + i + 2], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 3;
break;
case BC_LEA_ABS:
fprintf(file, "LEA\t%s, $%04x", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_STORE_ABS_8:
fprintf(file, "MOVB\t$%04x, %s", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]), TempName(generator->mMemory[mProgStart + i + 2], tbuffer, proc));
i += 3;
break;
case BC_STORE_ABS_16:
fprintf(file, "MOV\t$%04x, %s", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]), TempName(generator->mMemory[mProgStart + i + 2], tbuffer, proc));
i += 3;
break;
case BC_STORE_ABS_32:
fprintf(file, "MOVD\t$%04x, %s", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]), TempName(generator->mMemory[mProgStart + i + 2], tbuffer, proc));
i += 3;
break;
case BC_LOAD_LOCAL_8:
fprintf(file, "MOVB\t%s, %d(FP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_U8:
fprintf(file, "MOVUB\t%s, %d(FP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_I8:
fprintf(file, "MOVSB\t%s, %d(FP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_16:
fprintf(file, "MOV\t%s, %d(FP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_32:
fprintf(file, "MOVD\t%s, %d(FP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_STORE_LOCAL_8:
fprintf(file, "MOVB\t%d(FP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_LOCAL_16:
fprintf(file, "MOV\t%d(FP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_LOCAL_32:
fprintf(file, "MOVD\t%d(FP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
case BC_LEA_LOCAL:
fprintf(file, "LEA\t%s, %d(FP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_LEA_FRAME:
fprintf(file, "LEA\t%s, %d(SP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_STORE_FRAME_8:
fprintf(file, "MOVB\t%d(SP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_FRAME_16:
fprintf(file, "MOV\t%d(SP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_FRAME_32:
fprintf(file, "MOVD\t%d(SP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
case BC_BINOP_ADDR_16:
fprintf(file, "ADD\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SUBR_16:
fprintf(file, "SUB\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_MULR_16:
fprintf(file, "MUL\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_DIVR_U16:
fprintf(file, "DIVU\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_MODR_U16:
fprintf(file, "MODU\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_DIVR_I16:
fprintf(file, "DIVS\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_MODR_I16:
fprintf(file, "MODS\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_ANDR_16:
fprintf(file, "AND\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_ORR_16:
fprintf(file, "OR\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_XORR_16:
fprintf(file, "XOR\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SHLR_16:
fprintf(file, "SHL\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SHRR_I16:
fprintf(file, "SHRU\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SHRR_U16:
fprintf(file, "SHRI\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_ADDI_16:
fprintf(file, "ADD\t%s, #$%04X", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_BINOP_SUBI_16:
fprintf(file, "SUBR\t%s, #$%04X", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_BINOP_ANDI_16:
fprintf(file, "AND\t%s, #$%04X", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_BINOP_ORI_16:
fprintf(file, "OR\t%s, #$%04X", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_BINOP_MULI8_16:
fprintf(file, "MUL\t%s, #%d", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_CONV_I8_I16:
fprintf(file, "SEXT8\t%s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i ++;
break;
case BC_BINOP_SHLI_16:
fprintf(file, "SHL\tACCU, #%d", uint8(generator->mMemory[mProgStart + i + 0]));
i += 1;
break;
case BC_BINOP_SHRI_U16:
fprintf(file, "SHRU\tACCU, #%d", uint8(generator->mMemory[mProgStart + i + 0]));
i += 1;
break;
case BC_BINOP_SHRI_I16:
fprintf(file, "SHRS\tACCU, #%d", uint8(generator->mMemory[mProgStart + i + 0]));
i += 1;
break;
case BC_BINOP_CMPUR_16:
fprintf(file, "CMPU\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_CMPSR_16:
fprintf(file, "CMPS\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_CMPUI_16:
fprintf(file, "CMPU\tACCU, #$%04X", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_BINOP_CMPSI_16:
fprintf(file, "CMPS\tACCU, #$%04X", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_BINOP_ADD_F32:
fprintf(file, "ADDF\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SUB_F32:
fprintf(file, "SUBF\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_MUL_F32:
fprintf(file, "MULF\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_DIV_F32:
fprintf(file, "DIVF\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_CMP_F32:
fprintf(file, "CMPF\tACCU, %s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 1;
break;
case BC_COPY:
fprintf(file, "COPY\t#%d", generator->mMemory[mProgStart + i + 0]);
i++;
break;
case BC_COPY_LONG:
fprintf(file, "COPYL\t#%d", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_OP_NEGATE_16:
fprintf(file, "NEG\tACCU");
break;
case BC_OP_INVERT_16:
fprintf(file, "NOT\tACCU");
break;
case BC_OP_NEGATE_F32:
fprintf(file, "NEGF\tACCU");
break;
case BC_OP_ABS_F32:
fprintf(file, "ABSF\tACCU");
break;
case BC_OP_FLOOR_F32:
fprintf(file, "FLOORF\tACCU");
break;
case BC_OP_CEIL_F32:
fprintf(file, "CEILF\tACCU");
break;
case BC_CONV_U16_F32:
fprintf(file, "CNVUF\tACCU");
break;
case BC_CONV_I16_F32:
fprintf(file, "CNVSF\tACCU");
break;
case BC_CONV_F32_U16:
fprintf(file, "CNVFU\tACCU");
break;
case BC_CONV_F32_I16:
fprintf(file, "CNVFS\tACCU");
break;
case BC_JUMPS:
fprintf(file, "JUMP\t$%04X", mProgStart + i + 1 + int8(generator->mMemory[mProgStart + i + 0]));
i++;
break;
case BC_BRANCHS_EQ:
fprintf(file, "BEQ\t$%04X", mProgStart + i + 1 + int8(generator->mMemory[mProgStart + i + 0]));
i++;
break;
case BC_BRANCHS_NE:
fprintf(file, "BNE\t$%04X", mProgStart + i + 1 + int8(generator->mMemory[mProgStart + i + 0]));
i++;
break;
case BC_BRANCHS_GT:
fprintf(file, "BGT\t$%04X", mProgStart + i + 1 + int8(generator->mMemory[mProgStart + i + 0]));
i++;
break;
case BC_BRANCHS_GE:
fprintf(file, "BGE\t$%04X", mProgStart + i + 1 + int8(generator->mMemory[mProgStart + i + 0]));
i++;
break;
case BC_BRANCHS_LT:
fprintf(file, "BLT\t$%04X", mProgStart + i + 1 + int8(generator->mMemory[mProgStart + i + 0]));
i++;
break;
case BC_BRANCHS_LE:
fprintf(file, "BLE\t$%04X", mProgStart + i + 1 + int8(generator->mMemory[mProgStart + i + 0]));
i++;
break;
case BC_JUMPF:
fprintf(file, "JUMPF\t$%04X", mProgStart + i + 2 + int16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_BRANCHF_EQ:
fprintf(file, "BEQF\t$%04X", mProgStart + i + 2 + int16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_BRANCHF_NE:
fprintf(file, "BNEF\t$%04X", mProgStart + i + 2 + int16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_BRANCHF_GT:
fprintf(file, "BGTF\t$%04X", mProgStart + i + 2 + int16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_BRANCHF_GE:
fprintf(file, "BGEF\t$%04X", mProgStart + i + 2 + int16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_BRANCHF_LT:
fprintf(file, "BLTF\t$%04X", mProgStart + i + 2 + int16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_BRANCHF_LE:
fprintf(file, "BLEF\t$%04X", mProgStart + i + 2 + int16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_SET_EQ:
fprintf(file, "SEQ");
break;
case BC_SET_NE:
fprintf(file, "SNE");
break;
case BC_SET_GT:
fprintf(file, "SGT");
break;
case BC_SET_GE:
fprintf(file, "SGE");
break;
case BC_SET_LT:
fprintf(file, "SLT");
break;
case BC_SET_LE:
fprintf(file, "SLE");
break;
case BC_ENTER:
fprintf(file, "ENTER\t%d, %d", generator->mMemory[mProgStart + i + 2], uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 3;
break;
case BC_RETURN:
fprintf(file, "RETURN\t%d, %d", generator->mMemory[mProgStart + i], uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_CALL:
fprintf(file, "CALL");
break;
case BC_JSR:
fprintf(file, "JSR\t$%04x", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_PUSH_FRAME:
fprintf(file, "PUSH\t#$%04X", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_POP_FRAME:
fprintf(file, "POP\t#$%04X", uint16(generator->mMemory[mProgStart + i + 0] + 256 * generator->mMemory[mProgStart + i + 1]));
i += 2;
break;
case BC_LOAD_ADDR_8:
fprintf(file, "MOVB\t%s, (ADDR + %d)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_U8:
fprintf(file, "MOVUB\t%s, (ADDR + %d)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_I8:
fprintf(file, "MOVSB\t%s, (ADDR + %d)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_16:
fprintf(file, "MOV\t%s, (ADDR + %d)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_32:
fprintf(file, "MOVD\t%s, (ADDR + %d)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), generator->mMemory[mProgStart + i + 1]);
i += 2;
break;
case BC_STORE_ADDR_8:
fprintf(file, "MOVB\t(ADDR + %d), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_ADDR_16:
fprintf(file, "MOV\t(ADDR + %d), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_ADDR_32:
fprintf(file, "MOV\t(ADDR + %d), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2;
break;
}
fprintf(file, "\n");
}
mDisassembler.Disassemble(file, generator->mMemory, mProgStart, mProgSize, proc);
}
ByteCodeGenerator::ByteCodeGenerator(void)

View File

@ -2,6 +2,7 @@
#include "InterCode.h"
#include "Ident.h"
#include "Disassembler.h"
enum ByteCode
{
@ -258,7 +259,7 @@ public:
void Disassemble(FILE * file, ByteCodeGenerator* generator, InterCodeProcedure* proc);
protected:
const char* TempName(uint8 tmp, char * buffer, InterCodeProcedure* proc);
ByteCodeDisassembler mDisassembler;
};
class ByteCodeGenerator

650
oscar64/Disassembler.cpp Normal file
View File

@ -0,0 +1,650 @@
#include "Disassembler.h"
#include "ByteCodeGenerator.h"
#include "Assembler.h"
ByteCodeDisassembler::ByteCodeDisassembler(void)
{
}
ByteCodeDisassembler::~ByteCodeDisassembler(void)
{
}
const char* ByteCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc)
{
if (tmp == BC_REG_ADDR)
return "ADDR";
else if (tmp == BC_REG_ACCU)
return "ACCU";
else if (proc && tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
{
int i = 0;
while (i < proc->mTempOffset.Size() && proc->mTempOffset[i] != tmp - BC_REG_TMP)
i++;
if (i < proc->mTempOffset.Size())
sprintf_s(buffer, 10, "T%d", i);
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else
{
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
}
void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc)
{
fprintf(file, "--------------------------------------------------------------------\n");
if (proc->mIdent)
fprintf(file, "%s:\n", proc->mIdent->mString);
char tbuffer[10];
#if 0
for (int i = 0; i < proc->mTemporaries.Size(); i++)
printf("T%d = $%.2x\n", i, BC_REG_TMP + proc->mTempOffset[i]);
#endif
int i = 0;
while (i < size)
{
ByteCode bc = ByteCode(memory[start + i] / 2);
fprintf(file, "%04x:\t", start + i);
i++;
switch (bc)
{
case BC_NOP:
fprintf(file, "NOP");
break;
case BC_EXIT:
fprintf(file, "EXIT");
break;
case BC_CONST_8:
fprintf(file, "MOVB\t%s, #%d", TempName(memory[start + i], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_CONST_P8:
fprintf(file, "MOV\t%s, #%d", TempName(memory[start + i], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_CONST_N8:
fprintf(file, "MOV\t%s, #%d", TempName(memory[start + i], tbuffer, proc), int(memory[start + i + 1]) - 0x100);
i += 2;
break;
case BC_CONST_16:
fprintf(file, "MOV\t%s, #$%04x", TempName(memory[start + i], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_CONST_32:
fprintf(file, "MOVD\t%s, #$%08x", TempName(memory[start + i], tbuffer, proc), uint32(memory[start + i + 1] + 256 * memory[start + i + 2] + 0x10000 * memory[start + i + 3] + 0x1000000 * memory[start + i + 4]));
i += 5;
break;
case BC_LOAD_REG_8:
fprintf(file, "MOVB\tACCU, %s", TempName(memory[start + i], tbuffer, proc));
i += 1;
break;
case BC_STORE_REG_8:
fprintf(file, "MOVB\t%s, ACCU", TempName(memory[start + i], tbuffer, proc));
i += 1;
break;
case BC_LOAD_REG_16:
fprintf(file, "MOV\tACCU, %s", TempName(memory[start + i], tbuffer, proc));
i += 1;
break;
case BC_STORE_REG_16:
fprintf(file, "MOV\t%s, ACCU", TempName(memory[start + i], tbuffer, proc));
i += 1;
break;
case BC_LOAD_REG_32:
fprintf(file, "MOVD\tACCU, %s", TempName(memory[start + i], tbuffer, proc));
i += 1;
break;
case BC_STORE_REG_32:
fprintf(file, "MOVD\t%s, ACCU", TempName(memory[start + i], tbuffer, proc));
i += 1;
break;
case BC_ADDR_REG:
fprintf(file, "MOV\tADDR, %s", TempName(memory[start + i], tbuffer, proc));
i += 1;
break;
case BC_LOAD_ABS_8:
fprintf(file, "MOVUB\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3;
break;
case BC_LOAD_ABS_U8:
fprintf(file, "MOVUB\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3;
break;
case BC_LOAD_ABS_I8:
fprintf(file, "MOVSB\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3;
break;
case BC_LOAD_ABS_16:
fprintf(file, "MOV\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3;
break;
case BC_LOAD_ABS_32:
fprintf(file, "MOVD\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3;
break;
case BC_LEA_ABS:
fprintf(file, "LEA\t%s, $%04x", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_STORE_ABS_8:
fprintf(file, "MOVB\t$%04x, %s", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), TempName(memory[start + i + 2], tbuffer, proc));
i += 3;
break;
case BC_STORE_ABS_16:
fprintf(file, "MOV\t$%04x, %s", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), TempName(memory[start + i + 2], tbuffer, proc));
i += 3;
break;
case BC_STORE_ABS_32:
fprintf(file, "MOVD\t$%04x, %s", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), TempName(memory[start + i + 2], tbuffer, proc));
i += 3;
break;
case BC_LOAD_LOCAL_8:
fprintf(file, "MOVB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_U8:
fprintf(file, "MOVUB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_I8:
fprintf(file, "MOVSB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_16:
fprintf(file, "MOV\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_32:
fprintf(file, "MOVD\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_STORE_LOCAL_8:
fprintf(file, "MOVB\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_LOCAL_16:
fprintf(file, "MOV\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_LOCAL_32:
fprintf(file, "MOVD\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
case BC_LEA_LOCAL:
fprintf(file, "LEA\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_LEA_FRAME:
fprintf(file, "LEA\t%s, %d(SP)", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_STORE_FRAME_8:
fprintf(file, "MOVB\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_FRAME_16:
fprintf(file, "MOV\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_FRAME_32:
fprintf(file, "MOVD\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
case BC_BINOP_ADDR_16:
fprintf(file, "ADD\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SUBR_16:
fprintf(file, "SUB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_MULR_16:
fprintf(file, "MUL\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_DIVR_U16:
fprintf(file, "DIVU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_MODR_U16:
fprintf(file, "MODU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_DIVR_I16:
fprintf(file, "DIVS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_MODR_I16:
fprintf(file, "MODS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_ANDR_16:
fprintf(file, "AND\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_ORR_16:
fprintf(file, "OR\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_XORR_16:
fprintf(file, "XOR\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SHLR_16:
fprintf(file, "SHL\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SHRR_I16:
fprintf(file, "SHRU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SHRR_U16:
fprintf(file, "SHRI\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_ADDI_16:
fprintf(file, "ADD\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_BINOP_SUBI_16:
fprintf(file, "SUBR\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_BINOP_ANDI_16:
fprintf(file, "AND\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_BINOP_ORI_16:
fprintf(file, "OR\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_BINOP_MULI8_16:
fprintf(file, "MUL\t%s, #%d", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_CONV_I8_I16:
fprintf(file, "SEXT8\t%s", TempName(memory[start + i + 0], tbuffer, proc));
i++;
break;
case BC_BINOP_SHLI_16:
fprintf(file, "SHL\tACCU, #%d", uint8(memory[start + i + 0]));
i += 1;
break;
case BC_BINOP_SHRI_U16:
fprintf(file, "SHRU\tACCU, #%d", uint8(memory[start + i + 0]));
i += 1;
break;
case BC_BINOP_SHRI_I16:
fprintf(file, "SHRS\tACCU, #%d", uint8(memory[start + i + 0]));
i += 1;
break;
case BC_BINOP_CMPUR_16:
fprintf(file, "CMPU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_CMPSR_16:
fprintf(file, "CMPS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_CMPUI_16:
fprintf(file, "CMPU\tACCU, #$%04X", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BINOP_CMPSI_16:
fprintf(file, "CMPS\tACCU, #$%04X", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BINOP_ADD_F32:
fprintf(file, "ADDF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SUB_F32:
fprintf(file, "SUBF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_MUL_F32:
fprintf(file, "MULF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_DIV_F32:
fprintf(file, "DIVF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_CMP_F32:
fprintf(file, "CMPF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_COPY:
fprintf(file, "COPY\t#%d", memory[start + i + 0]);
i++;
break;
case BC_COPY_LONG:
fprintf(file, "COPYL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_OP_NEGATE_16:
fprintf(file, "NEG\tACCU");
break;
case BC_OP_INVERT_16:
fprintf(file, "NOT\tACCU");
break;
case BC_OP_NEGATE_F32:
fprintf(file, "NEGF\tACCU");
break;
case BC_OP_ABS_F32:
fprintf(file, "ABSF\tACCU");
break;
case BC_OP_FLOOR_F32:
fprintf(file, "FLOORF\tACCU");
break;
case BC_OP_CEIL_F32:
fprintf(file, "CEILF\tACCU");
break;
case BC_CONV_U16_F32:
fprintf(file, "CNVUF\tACCU");
break;
case BC_CONV_I16_F32:
fprintf(file, "CNVSF\tACCU");
break;
case BC_CONV_F32_U16:
fprintf(file, "CNVFU\tACCU");
break;
case BC_CONV_F32_I16:
fprintf(file, "CNVFS\tACCU");
break;
case BC_JUMPS:
fprintf(file, "JUMP\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_EQ:
fprintf(file, "BEQ\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_NE:
fprintf(file, "BNE\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_GT:
fprintf(file, "BGT\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_GE:
fprintf(file, "BGE\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_LT:
fprintf(file, "BLT\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_LE:
fprintf(file, "BLE\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_JUMPF:
fprintf(file, "JUMPF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_EQ:
fprintf(file, "BEQF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_NE:
fprintf(file, "BNEF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_GT:
fprintf(file, "BGTF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_GE:
fprintf(file, "BGEF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_LT:
fprintf(file, "BLTF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_LE:
fprintf(file, "BLEF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_SET_EQ:
fprintf(file, "SEQ");
break;
case BC_SET_NE:
fprintf(file, "SNE");
break;
case BC_SET_GT:
fprintf(file, "SGT");
break;
case BC_SET_GE:
fprintf(file, "SGE");
break;
case BC_SET_LT:
fprintf(file, "SLT");
break;
case BC_SET_LE:
fprintf(file, "SLE");
break;
case BC_ENTER:
fprintf(file, "ENTER\t%d, %d", memory[start + i + 2], uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3;
break;
case BC_RETURN:
fprintf(file, "RETURN\t%d, %d", memory[start + i], uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_CALL:
fprintf(file, "CALL");
break;
case BC_JSR:
fprintf(file, "JSR\t$%04x", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_PUSH_FRAME:
fprintf(file, "PUSH\t#$%04X", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_POP_FRAME:
fprintf(file, "POP\t#$%04X", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_LOAD_ADDR_8:
fprintf(file, "MOVB\t%s, (ADDR + %d)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_U8:
fprintf(file, "MOVUB\t%s, (ADDR + %d)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_I8:
fprintf(file, "MOVSB\t%s, (ADDR + %d)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_16:
fprintf(file, "MOV\t%s, (ADDR + %d)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_32:
fprintf(file, "MOVD\t%s, (ADDR + %d)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_STORE_ADDR_8:
fprintf(file, "MOVB\t(ADDR + %d), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_ADDR_16:
fprintf(file, "MOV\t(ADDR + %d), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
case BC_STORE_ADDR_32:
fprintf(file, "MOV\t(ADDR + %d), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
i += 2;
break;
}
fprintf(file, "\n");
}
}
NativeCodeDisassembler::NativeCodeDisassembler(void)
{
}
NativeCodeDisassembler::~NativeCodeDisassembler(void)
{
}
void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc)
{
fprintf(file, "--------------------------------------------------------------------\n");
if (proc->mIdent)
fprintf(file, "%s:\n", proc->mIdent->mString);
char tbuffer[10];
int ip = start;
while (ip < start + size)
{
int iip = ip;
uint8 opcode = memory[ip++];
AsmInsData d = DecInsData[opcode];
int addr = 0;
switch (d.mMode)
{
case ASMIM_IMPLIED:
fprintf(file, "%04x : %02x __ __ %s\n", iip, memory[iip], AsmInstructionNames[d.mType]);
break;
case ASMIM_IMMEDIATE:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_ZERO_PAGE:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
break;
case ASMIM_ZERO_PAGE_X:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
break;
case ASMIM_ZERO_PAGE_Y:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
break;
case ASMIM_ABSOLUTE:
addr = memory[ip] + 256 * memory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x\n", iip, memory[iip], memory[iip + 1], memory[iip + 2], AsmInstructionNames[d.mType], addr);
ip += 2;
break;
case ASMIM_ABSOLUTE_X:
addr = memory[ip] + 256 * memory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x\n", iip, memory[iip], memory[iip + 1], memory[iip + 2], AsmInstructionNames[d.mType], addr);
ip += 2;
break;
case ASMIM_ABSOLUTE_Y:
addr = memory[ip] + 256 * memory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y\n", iip, memory[iip], memory[iip + 1], memory[iip + 2], AsmInstructionNames[d.mType], addr);
ip += 2;
break;
case ASMIM_INDIRECT:
addr = memory[ip] + 256 * memory[ip + 1];
ip += 2;
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, memory[iip], memory[iip + 1], memory[iip + 2], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_INDIRECT_X:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
break;
case ASMIM_INDIRECT_Y:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
break;
case ASMIM_RELATIVE:
addr = memory[ip++];
if (addr & 0x80)
addr = addr + ip - 256;
else
addr = addr + ip;
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
}
}
}
const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc)
{
if (tmp >= BC_REG_ADDR && tmp <= BC_REG_ADDR + 3)
{
sprintf_s(buffer, 10, "ADDR + %d", tmp - BC_REG_ADDR);
return buffer;
}
else if (tmp >= BC_REG_ACCU && tmp <= BC_REG_ACCU + 3)
{
sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU);
return buffer;
}
else if (proc && tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
{
int i = 0;
while (i < proc->mTempOffset.Size() && tmp >= proc->mTempOffset[i] + BC_REG_TMP && tmp < proc->mTempOffset[i] + proc->mTempSizes[i] + BC_REG_TMP)
i++;
if (i < proc->mTempOffset.Size())
sprintf_s(buffer, 10, "T%d + %d", i, tmp - (proc->mTempOffset[i] + BC_REG_TMP));
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else
{
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
}

30
oscar64/Disassembler.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <stdio.h>
#include "InterCode.h"
class ByteCodeGenerator;
class ByteCodeDisassembler
{
public:
ByteCodeDisassembler(void);
~ByteCodeDisassembler(void);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc);
protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
};
class NativeCodeDisassembler
{
public:
NativeCodeDisassembler(void);
~NativeCodeDisassembler(void);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc);
protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
};

View File

@ -3365,7 +3365,7 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
}
InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & location, const Ident* ident)
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1),
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1), mTempSizes(0),
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
mValueForwardingTable(NULL), mLocalVars(InterVariable()), mModule(mod),
mIdent(ident), mNativeProcedure(false), mLeafProcedure(false)
@ -3917,11 +3917,13 @@ void InterCodeProcedure::ReduceTemporaries(void)
if (callerSavedTemps + size <= 16 && !callerSaved[i])
{
mTempOffset.Push(callerSavedTemps);
mTempSizes.Push(size);
callerSavedTemps += size;
}
else
{
mTempOffset.Push(calleeSavedTemps);
mTempSizes.Push(size);
calleeSavedTemps += size;
}
}

View File

@ -486,7 +486,7 @@ protected:
public:
GrowingInterCodeBasicBlockPtrArray mBlocks;
GrowingTypeArray mTemporaries;
GrowingIntArray mTempOffset;
GrowingIntArray mTempOffset, mTempSizes;
int mTempSize, mCommonFrameSize;
bool mLeafProcedure, mNativeProcedure;

View File

@ -1,4 +1,6 @@
#include "Linker.h"
#include <string.h>
#include <stdio.h>
Linker::Linker(Errors* errors)
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr)
@ -13,20 +15,206 @@ Linker::~Linker(void)
int Linker::AddSection(const Ident* section, int start, int size)
{
return 0;
LinkerSection* lsec = new LinkerSection;
lsec->mID = mSections.Size();
lsec->mIdent = section;
lsec->mStart = start;
lsec->mSize = size;
lsec->mUsed = 0;
mSections.Push(lsec);
return lsec->mID;
}
void Linker::AddSectionData(const Ident* section, int id, const uint8* data, int size)
int Linker::AddObject(const Location& location, const Ident* ident, const Ident* section, LinkerObjectType type)
{
LinkerObject* obj = new LinkerObject;
obj->mLocation = location;
obj->mID = mObjects.Size();
obj->mType = type;
obj->mData = nullptr;
obj->mSize = 0;
obj->mIdent = ident;
obj->mSection = section;
obj->mProc = nullptr;
mObjects.Push(obj);
return obj->mID;
}
uint8* Linker::AddSectionSpace(const Ident* section, int id, int size)
void Linker::AddObjectData(int id, const uint8* data, int size)
{
return nullptr;
LinkerObject* obj = mObjects[id];
obj->mSize = size;
obj->mData = new uint8[size];
memcpy(obj->mData, data, size);
}
uint8* Linker::AddObjectSpace(int id, int size)
{
LinkerObject* obj = mObjects[id];
obj->mSize = size;
obj->mData = new uint8[size];
memset(obj->mData, 0, size);
return obj->mData;
}
void Linker::AttachObjectProcedure(int id, InterCodeProcedure* proc)
{
LinkerObject* obj = mObjects[id];
obj->mProc = proc;
}
void Linker::AddReference(const LinkerReference& ref)
{
LinkerReference* nref = new LinkerReference(ref);
mReferences.Push(nref);
}
void Linker::Link(void)
{
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* obj = mObjects[i];
LinkerSection* lsec;
int j = 0;
while (j < mSections.Size() && !(mSections[j]->mIdent == obj->mSection && mSections[j]->mUsed + obj->mSize <= mSections[j]->mSize))
j++;
if (j < mSections.Size())
{
LinkerSection* lsec = mSections[j];
obj->mLinkerSection = lsec;
obj->mAddress = lsec->mUsed;
lsec->mUsed += obj->mSize;
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
}
else
mErrors->Error(obj->mLocation, "Out of space in section", obj->mSection->mString);
}
if (mErrors->mErrorCount == 0)
{
mProgramStart = 0xffff;
mProgramEnd = 0x0801;
int address = 0;
for (int i = 0; i < mSections.Size(); i++)
{
LinkerSection* lsec = mSections[i];
if (lsec->mStart == 0)
lsec->mStart = address;
address = lsec->mStart + lsec->mUsed;
if (lsec->mUsed > 0)
{
if (address > mProgramEnd)
mProgramEnd = address;
}
}
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* obj = mObjects[i];
obj->mAddress += obj->mLinkerSection->mStart;
}
for (int i = 0; i < mReferences.Size(); i++)
{
LinkerReference* ref = mReferences[i];
LinkerObject* obj = mObjects[ref->mID];
LinkerObject* robj = mObjects[ref->mRefID];
int raddr = robj->mAddress + ref->mRefOffset;
uint8* dp = mMemory + obj->mAddress + ref->mOffset;
if (ref->mLowByte)
*dp++ = raddr & 0xff;
if (ref->mHighByte)
*dp++ = (raddr >> 8) & 0xff;
}
}
}
static const char * LinkerObjectTypeNames[] =
{
"NONE",
"PAD",
"BASIC",
"BYTE_CODE",
"NATIVE_CODE",
"RUNTIME",
"DATA",
"BSS",
"STACK"
};
bool Linker::WritePrgFile(const char* filename)
{
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
{
mMemory[mProgramStart - 2] = mProgramStart & 0xff;
mMemory[mProgramStart - 1] = mProgramStart >> 8;
int done = fwrite(mMemory + mProgramStart - 2, 1, mProgramEnd - mProgramStart + 2, file);
fclose(file);
return done == mProgramEnd - mProgramStart + 2;
}
else
return false;
}
bool Linker::WriteMapFile(const char* filename)
{
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
{
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* obj = mObjects[i];
if (obj->mIdent)
fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
else
fprintf(file, "%04x - %04x : *, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
}
fclose(file);
return true;
}
else
return false;
}
bool Linker::WriteAsmFile(const char* filename)
{
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
{
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* obj = mObjects[i];
switch (obj->mType)
{
case LOT_BYTE_CODE:
mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc);
break;
case LOT_NATIVE_CODE:
mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc);
break;
}
}
fclose(file);
return true;
}
else
return false;
}

View File

@ -4,11 +4,27 @@
#include "Ident.h"
#include "Array.h"
#include "Errors.h"
#include "Disassembler.h"
class InterCodeProcedure;
enum LinkerObjectType
{
LOT_NONE,
LOT_PAD,
LOT_BASIC,
LOT_BYTE_CODE,
LOT_NATIVE_CODE,
LOT_RUNTIME,
LOT_DATA,
LOT_BSS,
LOT_STACK
};
struct LinkerReference
{
int mSection, mID, mOffset;
int mRefSection, mRefID, mRefOffset;
int mID, mOffset;
int mRefID, mRefOffset;
bool mLowByte, mHighByte;
};
@ -16,15 +32,20 @@ struct LinkerSection
{
const Ident* mIdent;
int mID;
int mStart, mSize;
int mStart, mSize, mUsed;
};
struct LinkerObject
{
const Ident* mIdent;
Location mLocation;
const Ident* mIdent, * mSection;
LinkerObjectType mType;
int mID;
int mAddress;
int mSize;
LinkerSection* mLinkerSection;
uint8* mData;
InterCodeProcedure* mProc;
};
class Linker
@ -34,15 +55,30 @@ public:
~Linker(void);
int AddSection(const Ident* section, int start, int size);
void AddSectionData(const Ident* section, int id, const uint8* data, int size);
uint8 * AddSectionSpace(const Ident* section, int id, int size);
int AddObject(const Location & location, const Ident* ident, const Ident* section, LinkerObjectType type);
void AddObjectData(int id, const uint8* data, int size);
uint8 * AddObjectSpace(int id, int size);
void AttachObjectProcedure(int id, InterCodeProcedure* proc);
void AddReference(const LinkerReference& ref);
bool WritePrgFile(const char* filename);
bool WriteMapFile(const char* filename);
bool WriteAsmFile(const char* filename);
GrowingArray<LinkerReference*> mReferences;
GrowingArray<LinkerSection*> mSections;
GrowingArray<LinkerObject*> mObjects;
uint8 mMemory[0x10000];
void Link(void);
protected:
NativeCodeDisassembler mNativeDisassembler;
ByteCodeDisassembler mByteCodeDisassembler;
int mProgramStart, mProgramEnd;
Errors* mErrors;
};

View File

@ -1202,7 +1202,12 @@ Expression* Parser::ParsePrefixExpression(void)
if (nexp->mToken == TK_MUL)
{
if (nexp->mLeft->mDecType->mType == DT_TYPE_POINTER || nexp->mLeft->mDecType->mType == DT_TYPE_ARRAY)
{
// no pointer to function dereferencing
if (nexp->mLeft->mDecType->mBase->mType == DT_TYPE_FUNCTION)
return nexp->mLeft;
nexp->mDecType = nexp->mLeft->mDecType;
}
else
mErrors->Error(nexp->mLocation, "Pointer or array type expected");
}

View File

@ -146,6 +146,7 @@
<ClCompile Include="CompilationUnits.cpp" />
<ClCompile Include="Compiler.cpp" />
<ClCompile Include="Declaration.cpp" />
<ClCompile Include="Disassembler.cpp" />
<ClCompile Include="Emulator.cpp" />
<ClCompile Include="Errors.cpp" />
<ClCompile Include="Ident.cpp" />
@ -167,6 +168,7 @@
<ClInclude Include="CompilationUnits.h" />
<ClInclude Include="Compiler.h" />
<ClInclude Include="Declaration.h" />
<ClInclude Include="Disassembler.h" />
<ClInclude Include="Emulator.h" />
<ClInclude Include="Errors.h" />
<ClInclude Include="Ident.h" />

View File

@ -66,6 +66,9 @@
<ClCompile Include="Linker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Disassembler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Array.h">
@ -131,6 +134,9 @@
<ClInclude Include="Linker.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Disassembler.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="oscar64.rc">

View File

@ -22,6 +22,12 @@
}
"Entry"
{
"MsmKey" = "8:_11003A1822704117BBF4B206A133EAD9"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_317711E6E48744A18655469B4C53767E"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -46,6 +52,12 @@
}
"Entry"
{
"MsmKey" = "8:_A27837E885F24200AC5CD5D9F8A0C2A4"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_A32310DEFD4E41118CD7D36A8614C0D4"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -205,6 +217,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_11003A1822704117BBF4B206A133EAD9"
{
"SourcePath" = "8:..\\include\\conio.h"
"TargetName" = "8:conio.h"
"Tag" = "8:"
"Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_317711E6E48744A18655469B4C53767E"
{
"SourcePath" = "8:..\\include\\math.c"
@ -285,6 +317,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A27837E885F24200AC5CD5D9F8A0C2A4"
{
"SourcePath" = "8:..\\include\\conio.c"
"TargetName" = "8:conio.c"
"Tag" = "8:"
"Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A32310DEFD4E41118CD7D36A8614C0D4"
{
"SourcePath" = "8:..\\include\\limits.h"
@ -513,7 +565,7 @@
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64"
"ProductCode" = "8:{3661BD30-0CEA-48FD-9F79-F3EE87E35F13}"
"PackageCode" = "8:{E524D01A-EAC6-47DD-A7F3-1E088056634C}"
"PackageCode" = "8:{A215641A-3D35-468B-AAAA-AB1067861712}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE"
@ -1034,7 +1086,7 @@
{
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
{
"SourcePath" = "8:..\\Release\\oscar64.exe"
"SourcePath" = "8:..\\Debug\\oscar64.exe"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_C95D3F098F884652A04D707B55B980EE"