implemented many intel asm printing functions

This commit is contained in:
Aaro Koivukangas
2025-05-06 12:50:17 +03:00
parent 0add89fa17
commit c6cad7e60b
13 changed files with 346 additions and 9 deletions
+93
View File
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "error.h"
#include "expr.h"
@@ -61,6 +62,98 @@ struct expr *expr_create_comment(struct comment *c)
return expr_create(COMMENT, NULL, NULL, NULL, NULL, c, NULL);
}
int expr_print_intel_asm(struct expr *e)
{
// TODO: Delve deeper into this. This works a bit differently than ttk91
// For ex. LOAD R1, =2(R2) needs to be translated into multiple instructions in assembly.
if (!e)
return VARIABLE_NULL;
switch (e->kind)
{
case INSTRUCTION:
{
if (e->label)
printf("\"LABEL\"");
// operator
int err = oper_print_intel_asm(e->oper);
if (err!=0)
return err;
printf(" ");
// If oper is STORE switch arguments around
if (e->oper && strcasecmp("STORE", e->oper->oper_name) == 0)
{
// Second argument
int err = value_print_intel_asm(e->second_arg);
if (err!=0)
return err;
printf(", ");
// First argument
err = ttk_register_print_intel_asm(e->first_arg);
if (err!=0)
return err;
}
else
{
// first argument
err = ttk_register_print_intel_asm(e->first_arg);
if (err!=0)
return err;
printf(", ");
// second argument
err = value_print_intel_asm(e->second_arg);
if (err!=0)
return err;
}
printf("\n");
break;
}
case LABEL_DEF:
{
int err = label_print_intel_asm(e->label);
if (err)
return err;
printf(" ");
err = oper_print_intel_asm(e->oper);
if (err)
return err;
printf(" ");
if (!e->second_arg)
return VARIABLE_NULL;
err = pure_value_print_intel_asm(e->second_arg->value);
if (err)
return err;
printf("\n");
break;
}
case COMMENT:
{
// Comments are skipped.
break;
}
default:
printf("NOT IMPLEMENTED %d\n", e->kind);
break;
}
return 0;
}
int expr_print(struct expr *e)
{
if (!e)
+5
View File
@@ -23,6 +23,11 @@ struct label * label_create_const(char* name) { return label_create(LABEL_
struct label * label_create_const_sys(char* name) { return label_create(LABEL_CONST, name, 0); } // FIXME value
struct label * label_create_tag(char* name) { return label_create(LABEL_TAG, name, 0); } // FIXME also this
int label_print_intel_asm(struct label *l)
{
return label_print(l);
}
int label_print(struct label *l)
{
if (!l->name)
+31 -9
View File
@@ -4,9 +4,9 @@
#include "token.h"
#include "program.h"
//#define FILENAME "../docs/example-file-harder.k91"
//#define FILENAME "../docs/example-file.k91"
#define FILENAME "../docs/example-file-simple.k91"
// #define FILENAME "../docs/example-file-harder.k91"
#define FILENAME "../docs/example-file.k91"
// #define FILENAME "../docs/example-file-simple.k91"
// scanner
extern FILE *yyin;
@@ -14,13 +14,19 @@ extern int yylex();
extern char *yytext;
// parser
extern int yyparse();
extern int yyparse(struct expr*);
int main()
int main(int argc, char **argv)
{
yyin = fopen(FILENAME, "r");
if (argc <= 1)
{
printf("Using default file %s\n", FILENAME);
yyin = fopen(FILENAME, "r");
}
else
yyin = fopen(argv[1], "r");
if (!yyin) {
printf("Couldn't open file\n");
@@ -30,21 +36,37 @@ int main()
struct expr *parse_result = malloc(sizeof(*parse_result));
if (!parse_result)
{
fclose(yyin);
printf("ERROR: Failed to allocate memory for parse_result.\n");
return ALLOC_FAILED;
}
if (yyparse(parse_result) == 0) {
printf("Parse succesful :)\n");
} else {
if (yyparse(parse_result) != 0)
{
fclose(yyin);
program_free(parse_result);
printf("Error parsing the file\n");
return PARSE_ERROR;
}
printf("Parse successful\n");
fclose(yyin);
int err = program_print(parse_result);
if (err!=0)
{
printf("Error printing program\n");
return err;
}
printf("\n");
err = program_print_intel_asm(parse_result);
if (err!=0)
{
printf("Error printing program in intel asm.\n");
return err;
}
program_free(parse_result);
// TODO handle errors with assertions
+81
View File
@@ -36,6 +36,87 @@ int oper_print(struct oper *o)
return 0;
}
int oper_print_intel_asm(struct oper *o)
{
if (!o)
{
printf("ERROR: Null oper given.\n");
return VARIABLE_NULL;
}
switch (o->kind)
{
case OPER_DATA:
{
if (strcasecmp("LOAD", o->oper_name) == 0)
printf("mov");
else if (strcasecmp("STORE", o->oper_name) == 0)
printf("mov");
else if (strcasecmp("IN", o->oper_name) == 0)
printf("\"IN\"");
else if (strcasecmp("OUT", o->oper_name) == 0)
printf("\"OUT\"");
break;
}
case OPER_AR:
{
if (strcasecmp("ADD", o->oper_name) == 0)
printf("add");
else if (strcasecmp("SUB", o->oper_name) == 0)
printf("sub");
else if (strcasecmp("MUL", o->oper_name) == 0)
printf("mul");
else if (strcasecmp("DIV", o->oper_name) == 0)
printf("div");
else
printf("\"%s\"", o->oper_name);
break;
}
case OPER_COMPILER:
{
if (strcasecmp("DEF", o->oper_name) == 0)
printf("\"%s\"", o->oper_name);
else
printf("dw");
break;
}
case OPER_LOGIC:
{
printf("\"%s\"", o->oper_name);
break;
}
case OPER_BRANCH:
{
printf("\"%s\"", o->oper_name);
break;
}
case OPER_STACK:
{
printf("\"%s\"", o->oper_name);
break;
}
case OPER_SYS:
{
printf("\"%s\"", o->oper_name);
break;
}
default:
{
return SWITCH_NOT_MATCHED;
}
}
return 0;
}
void oper_free(struct oper *o)
{
if (o->oper_name) free(o->oper_name);
+15
View File
@@ -18,6 +18,21 @@ int program_print(struct expr *program)
}
int program_print_intel_asm(struct expr *program)
{
struct expr *current = program;
while (current != NULL)
{
int err = expr_print_intel_asm(current);
if (err != 0)
return err;
current = current->next;
}
return 0;
}
void program_free(struct expr *program)
{
struct expr *current = program;
+42
View File
@@ -68,6 +68,48 @@ int parse_register_num(char* name, ttk_register_t kind)
return value;
}
int ttk_register_print_intel_asm(struct ttk_register *ttk_reg)
{
// EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI
if (!ttk_reg || !ttk_reg->id)
{
printf("ttk_register missing while trying to print it.\n");
return VARIABLE_NULL;
}
switch (ttk_reg->id)
{
case 1:
printf("eax");
break;
case 2:
printf("ebx");
break;
case 3:
printf("ecx");
break;
case 4:
printf("edx");
break;
case 5:
printf("esp");
break;
case 6:
printf("ebp");
break;
case 7:
printf("esi");
break;
case 0:
printf("edi"); // TODO: this is possibly not correct
break;
default:
printf("ERROR: No matching register\n");
return SWITCH_NOT_MATCHED;
}
return 0;
}
int ttk_register_print(struct ttk_register *ttk_reg)
{
if (!ttk_reg || !ttk_reg->id)
+71
View File
@@ -76,6 +76,77 @@ addr_mode_t parse_addr_mode(char* addr_mode)
return DIRECT;
}
int pure_value_print_intel_asm(struct pure_value *p_v)
{
return pure_value_print(p_v);
}
int value_print_intel_asm(struct value *v)
{
if (!v)
{
printf("ERROR: Value not defined.\n");
return VARIABLE_NULL;
}
if (v->indexing_mode == NONE)
{
switch (v->addr_mode)
{
case IMMEDIATE:
{
int err = pure_value_print_intel_asm(v->value);
if (err!=0)
return err;
break;
}
case DIRECT:
case INDIRECT:
{
if (v->value && v->value->kind != NUMBER)
{
int err = pure_value_print_intel_asm(v->value);
if (err!=0)
return err;
}
else {
printf("[");
int err = pure_value_print_intel_asm(v->value);
if (err!=0)
return err;
printf("]");
}
break;
}
}
}
else if (v->indexing_mode == INDEXED)
{
switch (v->addr_mode)
{
case IMMEDIATE:
{
printf("[");
int err = ttk_register_print_intel_asm(v->index_register);
if (err!=0)
return err;
printf(" + ");
err = pure_value_print_intel_asm(v->value);
if (err!=0)
return err;
printf("]");
}
}
}
else
return SWITCH_NOT_MATCHED;
return 0;
}
int pure_value_print(struct pure_value *p_v)
{