From d3d20bee26911b99d44a2b8e49bb920e9f722eb6 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 19 Sep 2021 22:22:16 +0200 Subject: [PATCH] Prepare section based linker --- include/stdio.c | 4 + oscar64/ByteCodeGenerator.cpp | 516 +----------------------- oscar64/ByteCodeGenerator.h | 3 +- oscar64/Disassembler.cpp | 650 +++++++++++++++++++++++++++++++ oscar64/Disassembler.h | 30 ++ oscar64/InterCode.cpp | 4 +- oscar64/InterCode.h | 2 +- oscar64/Linker.cpp | 200 +++++++++- oscar64/Linker.h | 50 ++- oscar64/Parser.cpp | 5 + oscar64/oscar64.vcxproj | 2 + oscar64/oscar64.vcxproj.filters | 6 + oscar64setup/oscar64setup.vdproj | 56 ++- 13 files changed, 996 insertions(+), 532 deletions(-) create mode 100644 oscar64/Disassembler.cpp create mode 100644 oscar64/Disassembler.h diff --git a/include/stdio.c b/include/stdio.c index e1b298a..8f34cee 100644 --- a/include/stdio.c +++ b/include/stdio.c @@ -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; diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 135f19c..cb66883 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -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) diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index 4ef44b1..8c6bb2b 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -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 diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp new file mode 100644 index 0000000..ae1c203 --- /dev/null +++ b/oscar64/Disassembler.cpp @@ -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; + } + +} + diff --git a/oscar64/Disassembler.h b/oscar64/Disassembler.h new file mode 100644 index 0000000..8e68953 --- /dev/null +++ b/oscar64/Disassembler.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#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); +}; + + diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 2d8c126..a1655d4 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -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; } } diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index bfd98ed..67da839 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -486,7 +486,7 @@ protected: public: GrowingInterCodeBasicBlockPtrArray mBlocks; GrowingTypeArray mTemporaries; - GrowingIntArray mTempOffset; + GrowingIntArray mTempOffset, mTempSizes; int mTempSize, mCommonFrameSize; bool mLeafProcedure, mNativeProcedure; diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index ba010b5..326b8db 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -1,4 +1,6 @@ #include "Linker.h" +#include +#include 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; +} + diff --git a/oscar64/Linker.h b/oscar64/Linker.h index 29ce025..1c1a4e9 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -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 mReferences; GrowingArray mSections; GrowingArray mObjects; + uint8 mMemory[0x10000]; + void Link(void); protected: + NativeCodeDisassembler mNativeDisassembler; + ByteCodeDisassembler mByteCodeDisassembler; + + int mProgramStart, mProgramEnd; + Errors* mErrors; }; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 08ac840..bc66a1d 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -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"); } diff --git a/oscar64/oscar64.vcxproj b/oscar64/oscar64.vcxproj index 3e41516..0a1c27c 100644 --- a/oscar64/oscar64.vcxproj +++ b/oscar64/oscar64.vcxproj @@ -146,6 +146,7 @@ + @@ -167,6 +168,7 @@ + diff --git a/oscar64/oscar64.vcxproj.filters b/oscar64/oscar64.vcxproj.filters index eb80a32..b37d7f7 100644 --- a/oscar64/oscar64.vcxproj.filters +++ b/oscar64/oscar64.vcxproj.filters @@ -66,6 +66,9 @@ Source Files + + Source Files + @@ -131,6 +134,9 @@ Header Files + + Header Files + diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index fb4fc38..e21c41e 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -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"