diff --git a/Emulator.cpp b/Emulator.cpp index e70fc17..295be24 100644 --- a/Emulator.cpp +++ b/Emulator.cpp @@ -106,6 +106,7 @@ struct FunctionCall struct Statement { int function_enter; + bool dyn_func; int label_pos; bool is_loop; char kind; @@ -114,11 +115,13 @@ struct Statement uint16_t val16; byte val8; FunctionCall *func_calls; + const char *call_reg; char gen_state; Statement() { function_enter = 0; + dyn_func = false; label_pos = 0; is_loop = false; code = 0; @@ -126,11 +129,13 @@ struct Statement val16 = 0; val8 = 0; func_calls = 0; + call_reg = 0; } - void call(uint32_t addr) + void call(uint32_t addr, const char *reg = 0) { kind = 'c'; + call_reg = reg; for (FunctionCall *func_call = func_calls; func_call != 0; func_call = func_call->next) if (func_call->addr == addr) return; @@ -196,7 +201,7 @@ void start_inst(uint32_t pc) cur_stat->val32 = _pc = J; \ if (do_trace) trace(" => jump to %08x\n\n", _pc); \ } -#define CODE_CALL(X) cur_stat->call(X) +#define CODE_CALL(X,R) cur_stat->call(X,R) #define CODE_RETURN cur_stat->kind = 'r' #define CODE_INT cur_stat->kind = 'i'; cur_stat->val32 = _eax @@ -590,6 +595,8 @@ void generate_code(Process *process) fprintf(fout, "\n"); + bool dyn_call = false; + for (uint32_t i = 0; i < len; i++) { Statement *stat = statements[i]; @@ -656,17 +663,32 @@ void generate_code(Process *process) } else if (stat->kind == 'c') { - if (stat->func_calls != 0 && stat->func_calls->next == 0) + if (stat->call_reg == 0) { - uint32_t index = stat->func_calls->addr - start_code; - if (index >= len || statements[index] == 0) - fprintf(fout, "/* Jump ERROR %08x %08x */", stat->val32, index); + if (stat->func_calls != 0 && stat->func_calls->next == 0) + { + uint32_t index = stat->func_calls->addr - start_code; + if (index >= len || statements[index] == 0) + fprintf(fout, "/* Jump ERROR %08x %08x */", stat->val32, index); + else + fprintf(fout, "%s;\t\t\t\t\t%s();", stat->code, name_for_function(stat->func_calls->addr, statements[index]->function_enter)); + } else - fprintf(fout, "%s;\t\t\t\t\t%s();", stat->code, name_for_function(stat->func_calls->addr, statements[index]->function_enter)); + fprintf(fout, "/* ERROR call */"); } else - fprintf(fout, "/* ERROR call */"); - + { + dyn_call = true; + for (FunctionCall *func_call = stat->func_calls; func_call != 0; func_call = func_call->next) + { + uint32_t index = func_call->addr - start_code; + if (index >= len || statements[index] == 0) + fprintf(fout, "/* Jump ERROR %08x %08x */", stat->val32, index); + else + statements[index]->dyn_func = true; + } + fprintf(fout, "%s;\t\t\t\t\t_call_reg(_%s);", stat->code, stat->call_reg); + } } else if (stat->kind == 'i') { @@ -741,6 +763,20 @@ void generate_code(Process *process) } } fprintf(fout, "private:\n"); + if (dyn_call) + { + fprintf(fout, "\tvoid _call_reg(uint32_t addr)\n"); + fprintf(fout, "\t{\n"); + for (uint32_t i = 0; i < len; i++) + { + Statement *stat = statements[i]; + if (stat != 0 && stat->dyn_func) + fprintf(fout, "\t\tif (addr == 0x%08x) { %s(); return; }\n", start_code + i, name_for_function(start_code + i, stat->function_enter)); + } + + fprintf(fout, "\t\tprintf(\"Error, no function for 0x%%08x\\n\", addr); exit(1);\n"); + fprintf(fout, "\t}\n\n"); + } fprintf(fout, "\tuint64_t val64;\n"); fprintf(fout, "\tuint32_t val32;\n"); fprintf(fout, "\tuint16_t val16;\n"); @@ -765,7 +801,7 @@ void generate_code(Process *process) fprintf(fout, "\t\n"); fprintf(fout, "\t\n"); fprintf(fout, "\tMyProcessor processor(main_process);\n"); - fprintf(fout, "\tprocessor.func1();\n"); + fprintf(fout, "\tprocessor.%s();\n", name_for_function(start_code, 1)); fprintf(fout, " \n"); fprintf(fout, "\treturn 0;\n"); fprintf(fout, "}\n"); @@ -1552,7 +1588,7 @@ class Processor break; case 0xD3: - CODE(_flags = _edx - _ebx); + CODE(_flags = _ebx - _edx); if (do_trace) trace(" cmp_ebx,edx\n"); break; @@ -2609,7 +2645,7 @@ class Processor { int32_t offset = (int32_t)getLongPC(); CODE(_process->push(_pc)); - CODE_CALL(_pc + offset); + CODE_CALL(_pc + offset, 0); _pc += offset; if (do_trace) trace(" call %s\n\n", name_for_function(_pc, -1)); indent_depth += 2; @@ -2675,7 +2711,7 @@ class Processor { case 0xD0: CODE(_process->push(_pc)); - CODE_CALL(_eax); + CODE_CALL(_eax, "eax"); _pc = _eax; if (do_trace) trace(" call_eax %08x\n\n", _pc); indent_depth += 2; diff --git a/M1_Emulator.cpp b/M1_Emulator.cpp index 445293b..c83c922 100644 --- a/M1_Emulator.cpp +++ b/M1_Emulator.cpp @@ -74,6 +74,35 @@ bool match(const char *s, const char *p, char *vars) return false; } +int toNumber(const char *s) +{ + int result = 0; + if (*s == '0' && s[1] == 'x') + { + for (s += 2; *s != '\0'; s++) + if ('0' <= *s && *s <= '9') + result = 16 * result + *s - '0'; + else if ('a' <= *s && *s <= 'f') + result = 16 * result + *s - 'a' + 10; + else if ('A' <= *s && *s <= 'F') + result = 16 * result + *s - 'A' + 10; + } + else + { + int sign = 1; + if (*s == '-') + { + s++; + sign = -1; + } + for (; *s != '\0'; s++) + if ('0' <= *s && *s <= '9') + result = 10 * result + *s - '0'; + result *= sign; + } + return result; +} + int main(int argc, char *argv[]) { if (argc != 2) @@ -225,13 +254,19 @@ int main(int argc, char *argv[]) { fprintf(fout, "\t\t_%3.3s = _%3.3s & _%s;\n", vars, vars, vars + 3); } - else if (strcmp(token->value, "ANDI32_EAX") == 0) + else if (match(token->value, "ANDI32_???", vars)) { - fprintf(fout, "\t\tERROR %s\n", token->value); + if (token->next != 0 && token->next->mode == '%') + { + token = token->next; + fprintf(fout, "\t\t_%s = _%s & 0x%08x;\n", vars, vars, toNumber(token->value)); + } + else + fprintf(fout, "\t\tERROR %s\n", token->value); } - else if (strcmp(token->value, "CALL_EAX") == 0) + else if (match(token->value, "CALL_???", vars)) { - fprintf(fout, "\t\tERROR %s\n", token->value); + fprintf(fout, "\t\t_process->push(_pc);\t\t\t\t\t_call_reg(_%s);\n", vars); } else if (strcmp(token->value, "CALL32") == 0) { @@ -261,21 +296,24 @@ int main(int argc, char *argv[]) { fprintf(fout, "\t\t_%3.3s = _%3.3s;\n", vars + 3, vars); } - else if (strcmp(token->value, "IDIV_EBX") == 0) + else if (match(token->value, "IDIV_???", vars)) { - fprintf(fout, "\t\tERROR %s\n", token->value); + fprintf(fout, "\t\tval64 = (int64_t)((((uint64_t)_edx) << 32) | _eax ) ; _edx = (uint32_t)(val64 %% (int32_t) _%s) ; _eax = (uint32_t)(val64 / (int32_t)_%s);\n", + vars, vars); } else if (strcmp(token->value, "IMUL_EAX_by_EBX") == 0) { fprintf(fout, "\t\tERROR %s\n", token->value); } - else if (strcmp(token->value, "IMULI8_EAX") == 0) + else if (match(token->value, "IMULI8_???", vars)) { - fprintf(fout, "\t\tERROR %s\n", token->value); - } - else if (strcmp(token->value, "IMULI8_EBP") == 0) - { - fprintf(fout, "\t\tERROR %s\n", token->value); + if (token->next != 0 && token->next->mode == '!') + { + token = token->next; + fprintf(fout, "\t\t_%s *= SIGNEXT(%s);\n", vars, token->value); + } + else + fprintf(fout, "\t\tERROR %s\n", token->value); } else if (strcmp(token->value, "INT_80") == 0) { @@ -289,7 +327,7 @@ int main(int argc, char *argv[]) default: fprintf(fout, "\t\tint80(); // %d\n", _eax_int_80); } } - else if (strcmp(token->value, "JBE8") == 0) + else if (strcmp(token->value, "c") == 0) { fprintf(fout, "\t\tERROR %s\n", token->value); } @@ -313,9 +351,15 @@ int main(int argc, char *argv[]) else fprintf(fout, "\t\tERROR %s\n", token->value); } - else if (strcmp(token->value, "JG8") == 0) + else if (strcmp(token->value, "JBE8") == 0) { - fprintf(fout, "\t\tERROR %s\n", token->value); + if (token->next != 0 && token->next->mode == '!') + { + fprintf(fout, "\t\tif (_flags <= 0) goto %s;\n", token->next->value); + token = token->next; + } + else + fprintf(fout, "\t\tERROR %s\n", token->value); } else if (strcmp(token->value, "JL32") == 0) { @@ -405,9 +449,9 @@ int main(int argc, char *argv[]) _eax_int_80 = -1; if (token->next != 0 && token->next->mode == '%') { - fprintf(fout, "\t\t_%s = 0x%08x;\n", vars, atoi(token->next->value)); + fprintf(fout, "\t\t_%s = 0x%08x;\n", vars, toNumber(token->next->value)); if (strcmp(vars, "eax") == 0) - _eax_int_80 = atoi(token->next->value); + _eax_int_80 = toNumber(token->next->value); token = token->next; } else if (token->next != 0 && token->next->mode == '&') @@ -444,7 +488,13 @@ int main(int argc, char *argv[]) } else if (match(token->value, "SHRI8_???", vars)) { - fprintf(fout, "\t\t_%s = _%s >> 1;\n", vars, vars); + if (token->next != 0 && token->next->mode == '!') + { + fprintf(fout, "\t\t_%s = _%s >> %d;\n", vars, vars, toNumber(token->next->value)); + token = token->next; + } + else + fprintf(fout, "\t\t// ERROR %s", token->value); } else if (match(token->value, "STORE32_Absolute32_???", vars)) { diff --git a/sdiff.cpp b/sdiff.cpp index 82d8d0e..b8d6c3c 100644 --- a/sdiff.cpp +++ b/sdiff.cpp @@ -307,6 +307,7 @@ int main(int argc, char *argv[]) const char *s_if = ident_string("if"); const char *s_star = characters['*']; const char *s_backslash = characters['\\']; + const char *s_true = ident_string("true"); addFunction(ident_string("_start")); @@ -336,7 +337,6 @@ int main(int argc, char *argv[]) else { printf("Found\n"); - const char *prev_goto = 0; for (;;) { while (line2 != 0 && line2->tokens == 0) @@ -367,8 +367,6 @@ int main(int argc, char *argv[]) break; } - const char *last_goto = 0; - Token *token1 = line1->tokens; Token *token2 = line2->tokens; for (; token1 != 0 && token2 != 0; token1 = token1->next, token2 = token2->next) @@ -412,7 +410,8 @@ int main(int argc, char *argv[]) { if (token1->type == 'n' && token2->type == 'n') { - if (strcmp(token1->text, "252") != 0 || strcmp(token2->text, "-4") != 0) + if ( (strcmp(token1->text, "252") != 0 || strcmp(token2->text, "-4") != 0) + && (strcmp(token1->text, "255") != 0 || strcmp(token2->text, "-1") != 0)) break; } else @@ -449,9 +448,6 @@ int main(int argc, char *argv[]) function_call = token2->text; prev_text = token1->text; - - if (token2->text == s_goto && token2->next != 0) - last_goto = token2->next->text; } } //printf("\n"); @@ -472,24 +468,21 @@ int main(int argc, char *argv[]) line1->print(stdout); line2->print(stdout); /**/ - if (prev_goto == 0) - { - //printf("No prev_goto\n"); - } - else + if ( line1->tokens != 0 && line1->tokens->type == 'i' + && line1->tokens->next != 0 && line1->tokens->next->text == s_colon) { - //printf(" Prev goto %s\n", prev_goto); bool found = false; for (Line *pos_line2 = line2; !found && !end_of_function(pos_line2); pos_line2 = pos_line2->next) - if ( pos_line2->tokens != 0 && pos_line2->tokens->text == prev_goto - && pos_line2->tokens->next != 0 && pos_line2->tokens->next->text == s_colon) + if ( pos_line2->tokens != 0 && pos_line2->tokens->type == 'i' + && pos_line2->tokens->next != 0 && pos_line2->tokens->next->text == s_colon + && getMatch(label_matches, pos_line2->tokens->text) == line1->tokens->text + ) { found = true; line2 = pos_line2; } if (found) { - prev_goto = 0; continue; } } @@ -512,7 +505,6 @@ int main(int argc, char *argv[]) line2->matching = line1; line1 = line1->next; line2 = line2->next; - prev_goto = last_goto; } } }