Skip to content

Commit

Permalink
Fix problem with call eax.
Browse files Browse the repository at this point in the history
Also made some other small fixes and some improvements
to M1_Emulator.cpp and sdiff.cpp.
  • Loading branch information
FransFaase committed Feb 9, 2024
1 parent 7e30498 commit 607f380
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 48 deletions.
62 changes: 49 additions & 13 deletions Emulator.cpp
Expand Up @@ -106,6 +106,7 @@ struct FunctionCall
struct Statement
{
int function_enter;
bool dyn_func;
int label_pos;
bool is_loop;
char kind;
Expand All @@ -114,23 +115,27 @@ 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;
val32 = 0;
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;
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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')
{
Expand Down Expand Up @@ -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");
Expand All @@ -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");
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
86 changes: 68 additions & 18 deletions M1_Emulator.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
}
Expand All @@ -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)
{
Expand Down Expand Up @@ -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 == '&')
Expand Down Expand Up @@ -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))
{
Expand Down
26 changes: 9 additions & 17 deletions sdiff.cpp
Expand Up @@ -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"));

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand All @@ -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;
}
}
Expand All @@ -512,7 +505,6 @@ int main(int argc, char *argv[])
line2->matching = line1;
line1 = line1->next;
line2 = line2->next;
prev_goto = last_goto;
}
}
}
Expand Down

0 comments on commit 607f380

Please sign in to comment.