mirror of
https://github.com/iritmaximus/ttk91-compiler.git
synced 2026-10-12 19:13:40 +03:00
implemented many intel asm printing functions
This commit is contained in:
@@ -26,6 +26,7 @@ struct expr {
|
|||||||
|
|
||||||
struct expr * expr_create(expr_t kind, struct label *l, struct oper *o, struct ttk_register *f_arg, struct value *s_arg, struct comment *c, struct expr *n);
|
struct expr * expr_create(expr_t kind, struct label *l, struct oper *o, struct ttk_register *f_arg, struct value *s_arg, struct comment *c, struct expr *n);
|
||||||
int expr_print(struct expr *e);
|
int expr_print(struct expr *e);
|
||||||
|
int expr_print_intel_asm(struct expr *e);
|
||||||
|
|
||||||
void expr_copy(struct expr *orig, struct expr *copy);
|
void expr_copy(struct expr *orig, struct expr *copy);
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ struct label {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct label * label_create(label_t kind, char* name, int value);
|
struct label * label_create(label_t kind, char* name, int value);
|
||||||
|
int label_print_intel_asm(struct label *l);
|
||||||
int label_print(struct label *l);
|
int label_print(struct label *l);
|
||||||
|
|
||||||
struct label * label_create_const(char* name);
|
struct label * label_create_const(char* name);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ struct oper {
|
|||||||
|
|
||||||
struct oper * oper_create(oper_t kind, char* oper_name);
|
struct oper * oper_create(oper_t kind, char* oper_name);
|
||||||
int oper_print(struct oper *o);
|
int oper_print(struct oper *o);
|
||||||
|
int oper_print_intel_asm(struct oper *o);
|
||||||
|
|
||||||
struct oper * oper_create_data(char* oper_name);
|
struct oper * oper_create_data(char* oper_name);
|
||||||
struct oper * oper_create_arithmetic(char* oper_name);
|
struct oper * oper_create_arithmetic(char* oper_name);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
|
||||||
int program_print(struct expr *program);
|
int program_print(struct expr *program);
|
||||||
|
int program_print_intel_asm(struct expr *program);
|
||||||
void program_free(struct expr *program);
|
void program_free(struct expr *program);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ struct ttk_register * ttk_register_create_register(char* name);
|
|||||||
struct ttk_register * ttk_register_create_stack_register(char* name);
|
struct ttk_register * ttk_register_create_stack_register(char* name);
|
||||||
|
|
||||||
int ttk_register_print(struct ttk_register *ttk_reg);
|
int ttk_register_print(struct ttk_register *ttk_reg);
|
||||||
|
int ttk_register_print_intel_asm(struct ttk_register *ttk_reg);
|
||||||
|
|
||||||
void ttk_register_free(struct ttk_register *ttk_reg);
|
void ttk_register_free(struct ttk_register *ttk_reg);
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,10 @@ struct pure_value * pure_value_create_label(struct label *l);
|
|||||||
|
|
||||||
struct pure_value * pure_value_create(value_t kind, struct ttk_register *ttk_reg, int num, struct label *l);
|
struct pure_value * pure_value_create(value_t kind, struct ttk_register *ttk_reg, int num, struct label *l);
|
||||||
addr_mode_t parse_addr_mode(char* addr_mode);
|
addr_mode_t parse_addr_mode(char* addr_mode);
|
||||||
|
int pure_value_print(struct pure_value *p_v);
|
||||||
int value_print(struct value *v);
|
int value_print(struct value *v);
|
||||||
|
int pure_value_print_intel_asm(struct pure_value *p_v);
|
||||||
|
int value_print_intel_asm(struct value *v);
|
||||||
|
|
||||||
|
|
||||||
void value_free(struct value *v);
|
void value_free(struct value *v);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.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);
|
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)
|
int expr_print(struct expr *e)
|
||||||
{
|
{
|
||||||
if (!e)
|
if (!e)
|
||||||
|
|||||||
@@ -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_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
|
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)
|
int label_print(struct label *l)
|
||||||
{
|
{
|
||||||
if (!l->name)
|
if (!l->name)
|
||||||
|
|||||||
+31
-9
@@ -4,9 +4,9 @@
|
|||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "program.h"
|
#include "program.h"
|
||||||
|
|
||||||
//#define FILENAME "../docs/example-file-harder.k91"
|
// #define FILENAME "../docs/example-file-harder.k91"
|
||||||
//#define FILENAME "../docs/example-file.k91"
|
#define FILENAME "../docs/example-file.k91"
|
||||||
#define FILENAME "../docs/example-file-simple.k91"
|
// #define FILENAME "../docs/example-file-simple.k91"
|
||||||
|
|
||||||
// scanner
|
// scanner
|
||||||
extern FILE *yyin;
|
extern FILE *yyin;
|
||||||
@@ -14,13 +14,19 @@ extern int yylex();
|
|||||||
extern char *yytext;
|
extern char *yytext;
|
||||||
|
|
||||||
// parser
|
// 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) {
|
if (!yyin) {
|
||||||
printf("Couldn't open file\n");
|
printf("Couldn't open file\n");
|
||||||
@@ -30,21 +36,37 @@ int main()
|
|||||||
struct expr *parse_result = malloc(sizeof(*parse_result));
|
struct expr *parse_result = malloc(sizeof(*parse_result));
|
||||||
if (!parse_result)
|
if (!parse_result)
|
||||||
{
|
{
|
||||||
|
fclose(yyin);
|
||||||
printf("ERROR: Failed to allocate memory for parse_result.\n");
|
printf("ERROR: Failed to allocate memory for parse_result.\n");
|
||||||
return ALLOC_FAILED;
|
return ALLOC_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (yyparse(parse_result) == 0) {
|
if (yyparse(parse_result) != 0)
|
||||||
printf("Parse succesful :)\n");
|
{
|
||||||
} else {
|
fclose(yyin);
|
||||||
program_free(parse_result);
|
program_free(parse_result);
|
||||||
|
printf("Error parsing the file\n");
|
||||||
return PARSE_ERROR;
|
return PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
printf("Parse successful\n");
|
||||||
|
|
||||||
|
fclose(yyin);
|
||||||
|
|
||||||
int err = program_print(parse_result);
|
int err = program_print(parse_result);
|
||||||
if (err!=0)
|
if (err!=0)
|
||||||
|
{
|
||||||
|
printf("Error printing program\n");
|
||||||
return err;
|
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);
|
program_free(parse_result);
|
||||||
// TODO handle errors with assertions
|
// TODO handle errors with assertions
|
||||||
|
|||||||
@@ -36,6 +36,87 @@ int oper_print(struct oper *o)
|
|||||||
return 0;
|
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)
|
void oper_free(struct oper *o)
|
||||||
{
|
{
|
||||||
if (o->oper_name) free(o->oper_name);
|
if (o->oper_name) free(o->oper_name);
|
||||||
|
|||||||
@@ -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)
|
void program_free(struct expr *program)
|
||||||
{
|
{
|
||||||
struct expr *current = program;
|
struct expr *current = program;
|
||||||
|
|||||||
@@ -68,6 +68,48 @@ int parse_register_num(char* name, ttk_register_t kind)
|
|||||||
return value;
|
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)
|
int ttk_register_print(struct ttk_register *ttk_reg)
|
||||||
{
|
{
|
||||||
if (!ttk_reg || !ttk_reg->id)
|
if (!ttk_reg || !ttk_reg->id)
|
||||||
|
|||||||
@@ -76,6 +76,77 @@ addr_mode_t parse_addr_mode(char* addr_mode)
|
|||||||
return DIRECT;
|
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)
|
int pure_value_print(struct pure_value *p_v)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user