Added initial draft of knight-posix support and first knight-posix test

This commit is contained in:
Jeremiah Orians 2019-02-23 18:33:57 -05:00
parent a456bcc21d
commit b085022577
No known key found for this signature in database
GPG Key ID: 5410E91C14959E87
11 changed files with 608 additions and 106 deletions

View File

@ -26,6 +26,7 @@ Added support for octal and binary numbers
Added support for \0
Added support for GET_MACHINE_FLAGS in tests
Added --architecture flag
Added first knight-posix test
** Changed
Converted M2-Planet to use GNU style error message

2
cc.c
View File

@ -110,7 +110,7 @@ int main(int argc, char** argv)
}
/* Temp solution to aborting when an architecture isn't supported yet but is expected to be fully supported */
if(!in_set(Architecture, "\x02"))
if(!in_set(Architecture, "\x01\x02"))
{
file_print("ALL IS FIRE\n\n", stderr);
exit(EXIT_FAILURE);

342
cc_core.c
View File

@ -60,10 +60,7 @@ void emit_out(char* s)
struct token_list* uniqueID(char* s, struct token_list* l, char* num)
{
l = emit(s, l);
l = emit("_", l);
l = emit(num, l);
l = emit("\n", l);
l = emit("\n", emit(num, emit("_", emit(s, l))));
return l;
}
@ -115,21 +112,33 @@ void function_call(char* s, int bool)
{
require_match("ERROR in process_expression_list\nNo ( was found\n", "(");
int passed = 0;
emit_out("PUSH_edi\t# Prevent overwriting in recursion\n");
emit_out("PUSH_ebp\t# Protect the old base pointer\n");
emit_out("COPY_esp_to_edi\t# Copy new base pointer\n");
if(1 == Architecture)
{
emit_out("PUSHR R13 R15\t# Prevent overwriting in recursion\n");
emit_out("PUSHR R14 R15\t# Protect the old base pointer\n");
emit_out("COPY R13 R15\t# Copy new base pointer\n");
}
else if(2 == Architecture)
{
emit_out("PUSH_edi\t# Prevent overwriting in recursion\n");
emit_out("PUSH_ebp\t# Protect the old base pointer\n");
emit_out("COPY_esp_to_edi\t# Copy new base pointer\n");
}
if(global_token->s[0] != ')')
{
expression();
emit_out("PUSH_eax\t#_process_expression1\n");
if(1 == Architecture) emit_out("PUSHR R0 R15\t#_process_expression1\n");
else if(2 == Architecture) emit_out("PUSH_eax\t#_process_expression1\n");
passed = 1;
while(global_token->s[0] == ',')
{
global_token = global_token->next;
expression();
emit_out("PUSH_eax\t#_process_expression2\n");
if(1 == Architecture) emit_out("PUSHR R0 R15\t#_process_expression2\n");
else if(2 == Architecture) emit_out("PUSH_eax\t#_process_expression2\n");
passed = passed + 1;
}
}
@ -138,31 +147,62 @@ void function_call(char* s, int bool)
if(TRUE == bool)
{
emit_out("LOAD_BASE_ADDRESS_eax %");
emit_out(s);
emit_out("\nLOAD_INTEGER\n");
emit_out("COPY_edi_to_ebp\n");
emit_out("CALL_eax\n");
if(1 == Architecture)
{
emit_out("LOAD R0 R15 @");
emit_out(s);
emit_out("MOVE R14 R13\n");
emit_out("CALL R0 R15\n");
}
else if(2 == Architecture)
{
emit_out("LOAD_BASE_ADDRESS_eax %");
emit_out(s);
emit_out("\nLOAD_INTEGER\n");
emit_out("COPY_edi_to_ebp\n");
emit_out("CALL_eax\n");
}
}
else
{
emit_out("COPY_edi_to_ebp\n");
emit_out("CALL_IMMEDIATE %FUNCTION_");
emit_out(s);
emit_out("\n");
if(1 == Architecture)
{
emit_out("MOVE R14 R13\n");
emit_out("CALLI R15 @FUNCTION_");
emit_out(s);
emit_out("\n");
}
else if(2 == Architecture)
{
emit_out("COPY_edi_to_ebp\n");
emit_out("CALL_IMMEDIATE %FUNCTION_");
emit_out(s);
emit_out("\n");
}
}
for(; passed > 0; passed = passed - 1)
{
emit_out("POP_ebx\t# _process_expression_locals\n");
if(1 == Architecture) emit_out("POPR R1 R15\t# _process_expression_locals\n");
else if(2 == Architecture) emit_out("POP_ebx\t# _process_expression_locals\n");
}
if(1 == Architecture)
{
emit_out("POPR R14 R15\t# Restore old base pointer\n");
emit_out("POPR R13 R15\t# Prevent overwrite\n");
}
else if(2 == Architecture)
{
emit_out("POP_ebp\t# Restore old base pointer\n");
emit_out("POP_edi\t# Prevent overwrite\n");
}
emit_out("POP_ebp\t# Restore old base pointer\n");
emit_out("POP_edi\t# Prevent overwrite\n");
}
void constant_load(struct token_list* a)
{
emit_out("LOAD_IMMEDIATE_eax %");
if(1 == Architecture) emit_out("LOADI R0 @");
else if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax %");
emit_out(a->arguments->s);
emit_out("\n");
}
@ -175,13 +215,17 @@ void variable_load(struct token_list* a)
return;
}
current_target = a->type;
emit_out("LOAD_BASE_ADDRESS_eax %");
if(1 == Architecture) emit_out("ADDI R0 R14 @");
else if(2 == Architecture) emit_out("LOAD_BASE_ADDRESS_eax %");
emit_out(numerate_number(a->depth));
emit_out("\n");
if(TRUE == Address_of) return;
if(match("=", global_token->s)) return;
emit_out("LOAD_INTEGER\n");
if(1 == Architecture) emit_out("LOAD R0 R0 0\n");
else if(2 == Architecture) emit_out("LOAD_INTEGER\n");
}
void function_load(struct token_list* a)
@ -192,7 +236,8 @@ void function_load(struct token_list* a)
return;
}
emit_out("LOAD_IMMEDIATE_eax &FUNCTION_");
if(1 == Architecture) emit_out("LOADUI R0 $FUNCTION_");
else if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax &FUNCTION_");
emit_out(a->s);
emit_out("\n");
}
@ -200,10 +245,15 @@ void function_load(struct token_list* a)
void global_load(struct token_list* a)
{
current_target = a->type;
emit_out("LOAD_IMMEDIATE_eax &GLOBAL_");
if(1 == Architecture) emit_out("LOADUI R0 $GLOBAL_");
else if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax &GLOBAL_");
emit_out(a->s);
emit_out("\n");
if(!match("=", global_token->s)) emit_out("LOAD_INTEGER\n");
if(!match("=", global_token->s))
{
if(1 == Architecture) emit_out("LOAD R0 R0 0\n");
else if(2 == Architecture) emit_out("LOAD_INTEGER\n");
}
}
/*
@ -229,7 +279,8 @@ void primary_expr_string()
{
char* number_string = numerate_number(current_count);
current_count = current_count + 1;
emit_out("LOAD_IMMEDIATE_eax &STRING_");
if(1 == Architecture) emit_out("LOADUI R0 $STRING_");
else if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax &STRING_");
uniqueID_out(function->s, number_string);
/* The target */
@ -243,7 +294,8 @@ void primary_expr_string()
void primary_expr_char()
{
emit_out("LOAD_IMMEDIATE_eax %");
if(1 == Architecture) emit_out("LOADI R0 ");
else if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax %");
emit_out(numerate_number(escape_lookup(global_token->s + 1)));
emit_out("\n");
global_token = global_token->next;
@ -251,7 +303,8 @@ void primary_expr_char()
void primary_expr_number()
{
emit_out("LOAD_IMMEDIATE_eax %");
if(1 == Architecture) emit_out("LOADI R0 ");
else if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax %");
emit_out(global_token->s);
emit_out("\n");
global_token = global_token->next;
@ -329,10 +382,15 @@ void common_recursion(FUNCTION f)
{
last_type = current_target;
global_token = global_token->next;
emit_out("PUSH_eax\t#_common_recursion\n");
if(1 == Architecture) emit_out("PUSHR R0 R15\t#_common_recursion\n");
else if(2 == Architecture) emit_out("PUSH_eax\t#_common_recursion\n");
f();
current_target = promote_type(current_target, last_type);
emit_out("POP_ebx\t# _common_recursion\n");
if(1 == Architecture) emit_out("POPR R1 R15\t# _common_recursion\n");
else if(2 == Architecture) emit_out("POP_ebx\t# _common_recursion\n");
}
void general_recursion( FUNCTION f, char* s, char* name, FUNCTION iterate)
@ -382,14 +440,24 @@ void postfix_expr_arrow()
if(0 != i->offset)
{
emit_out("# -> offset calculation\n");
emit_out("LOAD_IMMEDIATE_ebx %");
emit_out(numerate_number(i->offset));
emit_out("\nADD_ebx_to_eax\n");
if(1 == Architecture)
{
emit_out("ADDUI R0 R0 ");
emit_out(numerate_number(i->offset));
emit_out("\n");
}
else if(2 == Architecture)
{
emit_out("LOAD_IMMEDIATE_ebx %");
emit_out(numerate_number(i->offset));
emit_out("\nADD_ebx_to_eax\n");
}
}
if((!match("=", global_token->s) && (4 >= i->size)))
{
emit_out("LOAD_INTEGER\n");
if(1 == Architecture) emit_out("LOAD R0 R0 0\n");
else if(2 == Architecture) emit_out("LOAD_INTEGER\n");
}
}
@ -398,21 +466,28 @@ void postfix_expr_array()
struct type* array = current_target;
common_recursion(expression);
current_target = array;
char* assign = "LOAD_INTEGER\n";
char* assign;
if(1 == Architecture) assign = "LOAD R0 R0 0\n";
else if(2 == Architecture) assign = "LOAD_INTEGER\n";
/* Add support for Ints */
if(match("char*", current_target->name))
if(match("char*", current_target->name))
{
assign = "LOAD_BYTE\n";
if(1 == Architecture) assign = "LOAD8 R0 R0 0\n";
else if(2 == Architecture) assign = "LOAD_BYTE\n";
}
else
{
emit_out("SAL_eax_Immediate8 !");
if(1 == Architecture) emit_out("SALI R0 ");
else if(2 == Architecture) emit_out("SAL_eax_Immediate8 !");
emit_out(numerate_number(ceil_log2(current_target->indirect->size)));
emit_out("\n");
}
emit_out("ADD_ebx_to_eax\n");
if(1 == Architecture) emit_out("ADD R0 R0 R1\n");
else if(2 == Architecture) emit_out("ADD_ebx_to_eax\n");
require_match("ERROR in postfix_expr\nMissing ]\n", "]");
if(match("=", global_token->s))
@ -438,7 +513,8 @@ void unary_expr_sizeof()
struct type* a = type_name();
require_match("ERROR in unary_expr\nMissing )\n", ")");
emit_out("LOAD_IMMEDIATE_eax %");
if(1 == Architecture) emit_out("LOADUI R0 ");
else if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax %");
emit_out(numerate_number(a->size));
emit_out("\n");
}
@ -477,13 +553,26 @@ void postfix_expr()
*/
void additive_expr_stub()
{
general_recursion(postfix_expr, "ADD_ebx_to_eax\n", "+", additive_expr_stub);
general_recursion(postfix_expr, "SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n", "-", additive_expr_stub);
general_recursion(postfix_expr, "MULTIPLY_eax_by_ebx_into_eax\n", "*", additive_expr_stub);
general_recursion(postfix_expr, "XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nDIVIDE_eax_by_ebx_into_eax\n", "/", additive_expr_stub);
general_recursion(postfix_expr, "XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nMODULUS_eax_from_ebx_into_ebx\nMOVE_edx_to_eax\n", "%", additive_expr_stub);
general_recursion(postfix_expr, "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSAL_eax_cl\n", "<<", additive_expr_stub);
general_recursion(postfix_expr, "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSAR_eax_cl\n", ">>", additive_expr_stub);
if(1 == Architecture)
{
general_recursion(postfix_expr, "ADD R0 R0 R1\n", "+", additive_expr_stub);
general_recursion(postfix_expr, "SUB R0 R1 R0\n", "-", additive_expr_stub);
general_recursion(postfix_expr, "MUL R0 R0 R1\n", "*", additive_expr_stub);
general_recursion(postfix_expr, "DIV R0 R0 R1\n", "/", additive_expr_stub);
general_recursion(postfix_expr, "MOD R0 R0 R1\n", "%", additive_expr_stub);
general_recursion(postfix_expr, "SAL R0 R1 R0\n", "<<", additive_expr_stub);
general_recursion(postfix_expr, "SAR R0 R1 R0\n", ">>", additive_expr_stub);
}
else if(2 == Architecture)
{
general_recursion(postfix_expr, "ADD_ebx_to_eax\n", "+", additive_expr_stub);
general_recursion(postfix_expr, "SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n", "-", additive_expr_stub);
general_recursion(postfix_expr, "MULTIPLY_eax_by_ebx_into_eax\n", "*", additive_expr_stub);
general_recursion(postfix_expr, "XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nDIVIDE_eax_by_ebx_into_eax\n", "/", additive_expr_stub);
general_recursion(postfix_expr, "XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nMODULUS_eax_from_ebx_into_ebx\nMOVE_edx_to_eax\n", "%", additive_expr_stub);
general_recursion(postfix_expr, "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSAL_eax_cl\n", "<<", additive_expr_stub);
general_recursion(postfix_expr, "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSAR_eax_cl\n", ">>", additive_expr_stub);
}
}
@ -505,12 +594,24 @@ void additive_expr()
void relational_expr_stub()
{
general_recursion(additive_expr, "CMP\nSETL\nMOVEZBL\n", "<", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETLE\nMOVEZBL\n", "<=", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETGE\nMOVEZBL\n", ">=", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETG\nMOVEZBL\n", ">", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETE\nMOVEZBL\n", "==", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETNE\nMOVEZBL\n", "!=", relational_expr_stub);
if(1 == Architecture)
{
general_recursion(additive_expr, "CMPSKIP.L R0 R1\nLOADUI R0 1\n", "<", relational_expr_stub);
general_recursion(additive_expr, "CMPSKIP.LE R0 R1\nLOADUI R0 1\n", "<=", relational_expr_stub);
general_recursion(additive_expr, "CMPSKIP.GE R0 R1\nLOADUI R0 1\n", ">=", relational_expr_stub);
general_recursion(additive_expr, "CMPSKIP.G R0 R1\nLOADUI R0 1\n", ">", relational_expr_stub);
general_recursion(additive_expr, "CMPSKIP.E R0 R1\nLOADUI R0 1\n", "==", relational_expr_stub);
general_recursion(additive_expr, "CMPSKIP.NE R0 R1\nLOADUI R0 1\n", "!=", relational_expr_stub);
}
else if(2 == Architecture)
{
general_recursion(additive_expr, "CMP\nSETL\nMOVEZBL\n", "<", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETLE\nMOVEZBL\n", "<=", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETGE\nMOVEZBL\n", ">=", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETG\nMOVEZBL\n", ">", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETE\nMOVEZBL\n", "==", relational_expr_stub);
general_recursion(additive_expr, "CMP\nSETNE\nMOVEZBL\n", "!=", relational_expr_stub);
}
}
void relational_expr()
@ -530,11 +631,22 @@ void relational_expr()
*/
void bitwise_expr_stub()
{
general_recursion(relational_expr, "AND_eax_ebx\n", "&", bitwise_expr_stub);
general_recursion(relational_expr, "AND_eax_ebx\n", "&&", bitwise_expr_stub);
general_recursion(relational_expr, "OR_eax_ebx\n", "|", bitwise_expr_stub);
general_recursion(relational_expr, "OR_eax_ebx\n", "||", bitwise_expr_stub);
general_recursion(relational_expr, "XOR_ebx_eax_into_eax\n", "^", bitwise_expr_stub);
if(1 == Architecture)
{
general_recursion(relational_expr, "AND R0 R0 R1\n", "&", bitwise_expr_stub);
general_recursion(relational_expr, "AND R0 R0 R1\n", "&&", bitwise_expr_stub);
general_recursion(relational_expr, "OR R0 R0 R1\n", "|", bitwise_expr_stub);
general_recursion(relational_expr, "OR R0 R0 R1\n", "||", bitwise_expr_stub);
general_recursion(relational_expr, "XOR R0 R0 R1\n", "^", bitwise_expr_stub);
}
else if(2 == Architecture)
{
general_recursion(relational_expr, "AND_eax_ebx\n", "&", bitwise_expr_stub);
general_recursion(relational_expr, "AND_eax_ebx\n", "&&", bitwise_expr_stub);
general_recursion(relational_expr, "OR_eax_ebx\n", "|", bitwise_expr_stub);
general_recursion(relational_expr, "OR_eax_ebx\n", "||", bitwise_expr_stub);
general_recursion(relational_expr, "XOR_ebx_eax_into_eax\n", "^", bitwise_expr_stub);
}
}
@ -565,20 +677,28 @@ void primary_expr()
if(match("sizeof", global_token->s)) unary_expr_sizeof();
else if('-' == global_token->s[0])
{
emit_out("LOAD_IMMEDIATE_eax %0\n");
if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax %0\n");
common_recursion(primary_expr);
emit_out("SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n");
if(1 == Architecture) emit_out("NEG R0 R0\n");
else if(2 == Architecture) emit_out("SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n");
}
else if('!' == global_token->s[0])
{
emit_out("LOAD_IMMEDIATE_eax %1\n");
if(2 == Architecture) emit_out("LOAD_IMMEDIATE_eax %1\n");
common_recursion(postfix_expr);
emit_out("XOR_ebx_eax_into_eax\n");
if(1 == Architecture) emit_out("XORI R0 R0 1\n");
else if(2 == Architecture) emit_out("XOR_ebx_eax_into_eax\n");
}
else if('~' == global_token->s[0])
{
common_recursion(postfix_expr);
emit_out("NOT_eax\n");
if(1 == Architecture) emit_out("NOT R0 R0\n");
else if(2 == Architecture) emit_out("NOT_eax\n");
}
else if(global_token->s[0] == '(')
{
@ -598,14 +718,16 @@ void expression()
bitwise_expr();
if(match("=", global_token->s))
{
char* store;
char* store = "";
if(!match("]", global_token->prev->s) || !match("char*", current_target->name))
{
store = "STORE_INTEGER\n";
if(1 == Architecture) store = "STORE R0 R1 0\n";
else if(2 == Architecture) store = "STORE_INTEGER\n";
}
else
{
store = "STORE_CHAR\n";
if(1 == Architecture) store = "STORE8 R0 R1 0\n";
else if(2 == Architecture) store = "STORE_CHAR\n";
}
common_recursion(expression);
@ -622,19 +744,23 @@ void collect_local()
struct token_list* a = sym_declare(global_token->s, type_size, function->locals);
if(match("main", function->s) && (NULL == function->locals))
{
a->depth = -20;
if(1 == Architecture) a->depth = 20;
else if(2 == Architecture) a->depth = -20;
}
else if((NULL == function->arguments) && (NULL == function->locals))
{
a->depth = -8;
if(1 == Architecture) a->depth = 8;
else if(2 == Architecture) a->depth = -8;
}
else if(NULL == function->locals)
{
a->depth = function->arguments->depth - 8;
if(1 == Architecture) a->depth = function->arguments->depth + 8;
else if(2 == Architecture) a->depth = function->arguments->depth - 8;
}
else
{
a->depth = function->locals->depth - 4;
if(1 == Architecture) a->depth = function->locals->depth + 4;
else if(2 == Architecture) a->depth = function->locals->depth - 4;
}
function->locals = a;
@ -653,7 +779,8 @@ void collect_local()
require_match("ERROR in collect_local\nMissing ;\n", ";");
emit_out("PUSH_eax\t#");
if(1 == Architecture) emit_out("PUSHR R0 R15\t#");
else if(2 == Architecture) emit_out("PUSH_eax\t#");
emit_out(a->s);
emit_out("\n");
}
@ -673,13 +800,17 @@ void process_if()
require_match("ERROR in process_if\nMISSING (\n", "(");
expression();
emit_out("TEST\nJUMP_EQ %ELSE_");
if(1 == Architecture) emit_out("JUMP.Z R0 @ELSE_");
else if(2 == Architecture) emit_out("TEST\nJUMP_EQ %ELSE_");
uniqueID_out(function->s, number_string);
require_match("ERROR in process_if\nMISSING )\n", ")");
statement();
emit_out("JUMP %_END_IF_");
if(1 == Architecture) emit_out("JUMP @_END_IF_");
else if(2 == Architecture) emit_out("JUMP %_END_IF_");
uniqueID_out(function->s, number_string);
emit_out(":ELSE_");
uniqueID_out(function->s, number_string);
@ -725,9 +856,11 @@ void process_for()
require_match("ERROR in process_for\nMISSING ;1\n", ";");
expression();
emit_out("TEST\nJUMP_EQ %FOR_END_");
if(1 == Architecture) emit_out("JUMP.Z R0 @FOR_END_");
else if(2 == Architecture) emit_out("TEST\nJUMP_EQ %FOR_END_");
uniqueID_out(function->s, number_string);
emit_out("JUMP %FOR_THEN_");
if(1 == Architecture) emit_out("JUMP @FOR_THEN_");
else if(2 == Architecture) emit_out("JUMP %FOR_THEN_");
uniqueID_out(function->s, number_string);
emit_out(":FOR_ITER_");
uniqueID_out(function->s, number_string);
@ -735,7 +868,8 @@ void process_for()
require_match("ERROR in process_for\nMISSING ;2\n", ";");
expression();
emit_out("JUMP %FOR_");
if(1 == Architecture) emit_out("JUMP @FOR_");
else if(2 == Architecture) emit_out("JUMP %FOR_");
uniqueID_out(function->s, number_string);
emit_out(":FOR_THEN_");
uniqueID_out(function->s, number_string);
@ -743,7 +877,8 @@ void process_for()
require_match("ERROR in process_for\nMISSING )\n", ")");
statement();
emit_out("JUMP %FOR_ITER_");
if(1 == Architecture) emit_out("JUMP @FOR_ITER_");
else if(2 == Architecture) emit_out("JUMP %FOR_ITER_");
uniqueID_out(function->s, number_string);
emit_out(":FOR_END_");
uniqueID_out(function->s, number_string);
@ -759,8 +894,8 @@ void process_asm()
{
global_token = global_token->next;
require_match("ERROR in process_asm\nMISSING (\n", "(");
while(34 == global_token->s[0])
{/* 34 == " */
while('"' == global_token->s[0])
{
emit_out((global_token->s + 1));
emit_out("\n");
global_token = global_token->next;
@ -797,7 +932,8 @@ void process_do()
require_match("ERROR in process_do\nMISSING )\n", ")");
require_match("ERROR in process_do\nMISSING ;\n", ";");
emit_out("TEST\nJUMP_NE %DO_");
if(1 == Architecture) emit_out("JUMP.NZ R0 @DO_");
else if(2 == Architecture) emit_out("TEST\nJUMP_NE %DO_");
uniqueID_out(function->s, number_string);
emit_out(":DO_END_");
uniqueID_out(function->s, number_string);
@ -832,7 +968,8 @@ void process_while()
require_match("ERROR in process_while\nMISSING (\n", "(");
expression();
emit_out("TEST\nJUMP_EQ %END_WHILE_");
if(1 == Architecture) emit_out("JUMP.Z R0 @END_WHILE_");
else if(2 == Architecture) emit_out("TEST\nJUMP_EQ %END_WHILE_");
uniqueID_out(function->s, number_string);
emit_out("# THEN_while_");
uniqueID_out(function->s, number_string);
@ -840,7 +977,8 @@ void process_while()
require_match("ERROR in process_while\nMISSING )\n", ")");
statement();
emit_out("JUMP %WHILE_");
if(1 == Architecture) emit_out("JUMP @WHILE_");
else if(2 == Architecture) emit_out("JUMP %WHILE_");
uniqueID_out(function->s, number_string);
emit_out(":END_WHILE_");
uniqueID_out(function->s, number_string);
@ -862,9 +1000,12 @@ void return_result()
struct token_list* i;
for(i = function->locals; NULL != i; i = i->next)
{
emit_out("POP_ebx\t# _return_result_locals\n");
if(1 == Architecture) emit_out("POPR R1 R15\t# _return_result_locals\n");
else if(2 == Architecture) emit_out("POP_ebx\t# _return_result_locals\n");
}
emit_out("RETURN\n");
if(1 == Architecture) emit_out("RET R15\n");
else if(2 == Architecture) emit_out("RETURN\n");
}
void process_break()
@ -879,11 +1020,15 @@ void process_break()
while(i != break_frame)
{
if(NULL == i) break;
emit_out("POP_ebx\t# break_cleanup_locals\n");
if(1 == Architecture) emit_out("POPR R1 R15\t# break_cleanup_locals\n");
else if(2 == Architecture) emit_out("POP_ebx\t# break_cleanup_locals\n");
i = i->next;
}
global_token = global_token->next;
emit_out("JUMP %");
if(1 == Architecture) emit_out("JUMP @");
else if(2 == Architecture) emit_out("JUMP %");
emit_out(break_target_head);
emit_out(break_target_func);
emit_out("_");
@ -904,12 +1049,14 @@ void recursive_statement()
global_token = global_token->next;
/* Clean up any locals added */
if(!match("RETURN\n", out->s))
if(((2 == Architecture) && !match("RETURN\n", out->s)) || ((1 == Architecture) && !match("RET R15\n", out->s)))
{
struct token_list* i;
for(i = function->locals; frame != i; i = i->next)
{
emit_out( "POP_ebx\t# _recursive_statement_locals\n");
if(1 == Architecture) emit_out("POPR R1 R15\t@ _recursive_statement_locals\n");
else if(2 == Architecture) emit_out( "POP_ebx\t# _recursive_statement_locals\n");
}
}
function->locals = frame;
@ -974,7 +1121,8 @@ void statement()
else if(match("goto", global_token->s))
{
global_token = global_token->next;
emit_out("JUMP %");
if(1 == Architecture) emit_out("JUMP @");
else if(2 == Architecture) emit_out("JUMP %");
emit_out(global_token->s);
emit_out("\n");
global_token = global_token->next;
@ -1020,11 +1168,13 @@ void collect_arguments()
struct token_list* a = sym_declare(global_token->s, type_size, function->arguments);
if(NULL == function->arguments)
{
a->depth = -4;
if(1 == Architecture) a->depth = 4;
else if(2 == Architecture) a->depth = -4;
}
else
{
a->depth = function->arguments->depth - 4;
if(1 == Architecture) a->depth = function->arguments->depth + 4;
else if(2 == Architecture) a->depth = function->arguments->depth - 4;
}
global_token = global_token->next;
@ -1059,10 +1209,8 @@ void declare_function()
statement();
/* Prevent duplicate RETURNS */
if(!match("RETURN\n", out->s))
{
emit_out("RETURN\n");
}
if((1 == Architecture) && !match("RET R15\n", out->s)) emit_out("RET R15\n");
else if((2 == Architecture) && !match("RETURN\n", out->s)) emit_out("RETURN\n");
}
}

View File

@ -62,7 +62,8 @@ results:
mkdir -p test/results
# tests
test: test00-binary \
test: test00-x86-binary \
test00-knight-posix-binary \
test01-binary \
test02-binary \
test03-binary \
@ -91,8 +92,11 @@ test: test00-binary \
test100-binary | results
sha256sum -c test/test.answers
test00-binary: M2-Planet | results
test/test00/hello.sh
test00-x86-binary: M2-Planet | results
test/test00/hello-x86.sh
test00-knight-posix-binary: M2-Planet | results
test/test00/hello-knight-posix.sh
test01-binary: M2-Planet | results
test/test01/hello.sh

View File

@ -0,0 +1,25 @@
### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
### This file is part of M2-Planet.
###
### M2-Planet is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### M2-Planet is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
### stage0's hex2 format for x86
### !<label> 1 byte relative
### $<label> 2 byte address
### @<label> 2 byte relative
### &<label> 4 byte address
### %<label> 4 byte relative
### local_<label> function-local
### string_<index> string #<index>

View File

@ -0,0 +1,253 @@
## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see <http://www.gnu.org/licenses/>.
#Registers
DEFINE R0 0
DEFINE R1 1
DEFINE R2 2
DEFINE R3 3
DEFINE R4 4
DEFINE R5 5
DEFINE R6 6
DEFINE R7 7
DEFINE R8 8
DEFINE R9 9
DEFINE R10 A
DEFINE R11 B
DEFINE R12 C
DEFINE R13 D
DEFINE R14 E
DEFINE R15 F
# 4OP Integer Group
DEFINE ADD.CI 0100
DEFINE ADD.CO 0101
DEFINE ADD.CIO 0102
DEFINE ADDU.CI 0103
DEFINE ADDU.CO 0104
DEFINE ADDU.CIO 0105
DEFINE SUB.BI 0106
DEFINE SUB.BO 0107
DEFINE SUB.BIO 0108
DEFINE SUBU.BI 0109
DEFINE SUBU.BO 010A
DEFINE SUBU.BIO 010B
DEFINE MULTIPLY 010C
DEFINE MULTIPLYU 010D
DEFINE DIVIDE 010E
DEFINE DIVIDEU 010F
DEFINE MUX 0110
DEFINE NMUX 0111
DEFINE SORT 0112
DEFINE SORTU 0113
# 3OP Integer Group
DEFINE ADD 05000
DEFINE ADDU 05001
DEFINE SUB 05002
DEFINE SUBU 05003
DEFINE CMP 05004
DEFINE CMPU 05005
DEFINE MUL 05006
DEFINE MULH 05007
DEFINE MULU 05008
DEFINE MULUH 05009
DEFINE DIV 0500A
DEFINE MOD 0500B
DEFINE DIVU 0500C
DEFINE MODU 0500D
DEFINE MAX 05010
DEFINE MAXU 05011
DEFINE MIN 05012
DEFINE MINU 05013
DEFINE AND 05020
DEFINE OR 05021
DEFINE XOR 05022
DEFINE NAND 05023
DEFINE NOR 05024
DEFINE XNOR 05025
DEFINE MPQ 05026
DEFINE LPQ 05027
DEFINE CPQ 05028
DEFINE BPQ 05029
DEFINE SAL 05030
DEFINE SAR 05031
DEFINE SL0 05032
DEFINE SR0 05033
DEFINE SL1 05034
DEFINE SR1 05035
DEFINE ROL 05036
DEFINE ROR 05037
DEFINE LOADX 05038
DEFINE LOADX8 05039
DEFINE LOADXU8 0503A
DEFINE LOADX16 0503B
DEFINE LOADXU16 0503C
DEFINE LOADX32 0503D
DEFINE LOADXU32 0503E
DEFINE STOREX 05048
DEFINE STOREX8 05049
DEFINE STOREX16 0504A
DEFINE STOREX32 0504B
DEFINE CMPJUMP.G 05050
DEFINE CMPJUMP.GE 05051
DEFINE CMPJUMP.E 05052
DEFINE CMPJUMP.NE 05053
DEFINE CMPJUMP.LE 05054
DEFINE CMPJUMP.L 05055
DEFINE CMPJUMPU.G 05060
DEFINE CMPJUMPU.GE 05061
DEFINE CMPJUMPU.LE 05064
DEFINE CMPJUMPU.L 05065
# 2OP Integer Group
DEFINE NEG 090000
DEFINE ABS 090001
DEFINE NABS 090002
DEFINE SWAP 090003
DEFINE COPY 090004
DEFINE MOVE 090005
DEFINE NOT 090006
DEFINE BRANCH 090100
DEFINE CALL 090101
DEFINE PUSHR 090200
DEFINE PUSH8 090201
DEFINE PUSH16 090202
DEFINE PUSH32 090203
DEFINE POPR 090280
DEFINE POP8 090281
DEFINE POPU8 090282
DEFINE POP16 090283
DEFINE POPU16 090284
DEFINE POP32 090285
DEFINE POPU32 090286
DEFINE CMPSKIP.G 090300
DEFINE CMPSKIP.GE 090301
DEFINE CMPSKIP.E 090302
DEFINE CMPSKIP.NE 090303
DEFINE CMPSKIP.LE 090304
DEFINE CMPSKIP.L 090305
DEFINE CMPSKIPU.G 090380
DEFINE CMPSKIPU.GE 090381
DEFINE CMPSKIPU.LE 090384
DEFINE CMPSKIPU.L 090385
# 1OP Group
DEFINE READPC 0D00000
DEFINE READSCID 0D00001
DEFINE FALSE 0D00002
DEFINE TRUE 0D00003
DEFINE JSR_COROUTINE 0D01000
DEFINE RET 0D01001
DEFINE PUSHPC 0D02000
DEFINE POPPC 0D02001
# 2OPI Group
DEFINE ADDI E1000E
DEFINE ADDUI E1000F
DEFINE SUBI E10010
DEFINE SUBUI E10011
DEFINE CMPI E10012
DEFINE LOAD E10013
DEFINE LOAD8 E10014
DEFINE LOADU8 E10015
DEFINE LOAD16 E10016
DEFINE LOADU16 E10017
DEFINE LOAD32 E10018
DEFINE LOADU32 E10019
DEFINE CMPUI E1001F
DEFINE STORE E10020
DEFINE STORE8 E10021
DEFINE STORE16 E10022
DEFINE STORE32 E10023
DEFINE ANDI E100B0
DEFINE ORI E100B1
DEFINE XORI E100B2
DEFINE NANDI E100B3
DEFINE NORI E100B4
DEFINE XNORI E100B5
DEFINE CMPJUMPI.G E100C0
DEFINE CMPJUMPI.GE E100C1
DEFINE CMPJUMPI.E E100C2
DEFINE CMPJUMPI.NE E100C3
DEFINE CMPJUMPI.LE E100C4
DEFINE CMPJUMPI.L E100C5
DEFINE CMPJUMPUI.G E100D0
DEFINE CMPJUMPUI.GE E100D1
DEFINE CMPJUMPUI.LE E100D4
DEFINE CMPJUMPUI.L E100D5
# 1OPI Group
DEFINE JUMP.C E0002C0
DEFINE JUMP.B E0002C1
DEFINE JUMP.O E0002C2
DEFINE JUMP.G E0002C3
DEFINE JUMP.GE E0002C4
DEFINE JUMP.E E0002C5
DEFINE JUMP.NE E0002C6
DEFINE JUMP.LE E0002C7
DEFINE JUMP.L E0002C8
DEFINE JUMP.Z E0002C9
DEFINE JUMP.NZ E0002CA
DEFINE JUMP.P E0002CB
DEFINE JUMP.NP E0002CC
DEFINE CALLI E0002D0
DEFINE LOADI E0002D1
DEFINE LOADUI E0002D2
DEFINE SALI E0002D3
DEFINE SARI E0002D4
DEFINE SL0I E0002D5
DEFINE SR0I E0002D6
DEFINE SL1I E0002D7
DEFINE SR1I E0002D8
DEFINE LOADR E0002E0
DEFINE LOADR8 E0002E1
DEFINE LOADRU8 E0002E2
DEFINE LOADR16 E0002E3
DEFINE LOADRU16 E0002E4
DEFINE LOADR32 E0002E5
DEFINE LOADRU32 E0002E6
DEFINE STORER E0002F0
DEFINE STORER8 E0002F1
DEFINE STORER16 E0002F2
DEFINE STORER32 E0002F3
DEFINE CMPSKIPI.G E000A00
DEFINE CMPSKIPI.GE E000A01
DEFINE CMPSKIPI.E E000A02
DEFINE CMPSKIPI.NE E000A03
DEFINE CMPSKIPI.LE E000A04
DEFINE CMPSKIPI.L E000A05
DEFINE CMPSKIPUI.G E000A10
DEFINE CMPSKIPUI.GE E000A11
DEFINE CMPSKIPUI.LE E000A14
DEFINE CMPSKIPUI.L E000A15
# 0OPI Group
DEFINE JUMP 3C00
# HALCODE Group
DEFINE FOPEN_READ 42100000
DEFINE FOPEN_WRITE 42100001
DEFINE FCLOSE 42100002
DEFINE REWIND 42100003
DEFINE FSEEK 42100004
DEFINE FGETC 42100100
DEFINE FPUTC 42100200
DEFINE HAL_MEM 42110000
# 0OP Group
DEFINE NOP 00000000
DEFINE HALT FFFFFFFF

View File

@ -0,0 +1,29 @@
## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## M2-Planet is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
:_start
LOADUI R15 $ELF_end ; Setup Stack pointer
COPY R14 R15 ; Protect esp
;; Perform the main loop
CALLI R15 @FUNCTION_main
;; Exit to kernel
HALT ; Simply halt for now
;; Our default heap pointer
'00080000'

View File

@ -1,4 +1,5 @@
c52562bd0aabb86ce8ca177f22f8d0455769b444df2d4d62894faab63b7151d8 test/results/test00-binary
96dcb1cde9bc98c736fb33146982215f4509ae8539475e513e9cef326c78cbda test/results/test00-knight-posix-binary
c52562bd0aabb86ce8ca177f22f8d0455769b444df2d4d62894faab63b7151d8 test/results/test00-x86-binary
eae96857f2b6d8e8ba86ac06e72345ea572622b358b23978bb5f2db1baadf41c test/results/test01-binary
8ead336d2f3f72d5874230492e0472edec61d355905e8636e3dfb2731695037c test/results/test02-binary
2313cb3f1a2b9eb6bf15f8d43418e15d6c16f7f1b5c22700fdfc2b38beb59192 test/results/test03-binary
@ -9,7 +10,7 @@ a9a3e332d13ded5f80d7431f8717f26527b3722b33ea57760a9a5723dffc099c test/results/t
f1c01feb865c4d552033186d9ce50dd39468a7e8aebf762886c13ad3e03b5011 test/results/test08-binary
3b39e72f3de90ed690adfaf6145af46157cef2ec5e72867ac577fa27a0229894 test/results/test09-binary
020e86020819cc4963e6185b22e534fcf8306b6cb116f12643f254a24688ff0a test/results/test10-binary
c84d7ca7668837bade38e6e07e018ded3e587643a0a22d513f9dc314fbf17f31 test/results/test100-binary
0a6eca36e9eea6a72595906b3990a16a0433f5404a6add00d245f99fe6308f75 test/results/test100-binary
3fd11bad4a426ce1ff8fd9c6d7d2b943effae9f3f5740b7376e426e9b0555851 test/results/test11-binary
f98ab8e4bb35580e0dde96126d7a56aff66bda208d02c8d89390b40d6cff591c test/results/test12-binary
5051ffca2615144419f8ec1a5d4999486ae81e7781428f59e47e866af97cef92 test/results/test13-binary

View File

@ -0,0 +1,41 @@
#! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## M2-Planet is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
set -x
# Build the test
bin/M2-Planet --architecture knight-posix -f test/test00/return.c \
-o test/test00/return.M1 || exit 1
# Macro assemble with libc written in M1-Macro
M1 -f test/common_knight/knight_defs.M1 \
-f test/common_knight/libc-core.M1 \
-f test/test00/return.M1 \
--BigEndian \
--architecture knight-posix \
-o test/test00/return.hex2 || exit 2
# Resolve all linkages
hex2 -f test/common_knight/ELF-knight.hex2 -f test/test00/return.hex2 --BigEndian --architecture knight-posix --BaseAddress 0x0 -o test/results/test00-knight-posix-binary --exec_enable || exit 3
# Ensure binary works if host machine supports test
if [ "$(get_machine ${GET_MACHINE_FLAGS})" = "knight*" ]
then
# Verify that the compiled program returns the correct result
./test/results/test00-knight-posix-binary
[ 42 = $? ] || exit 3
fi
exit 0

View File

@ -29,13 +29,13 @@ M1 -f test/common_x86/x86_defs.M1 \
-o test/test00/return.hex2 || exit 2
# Resolve all linkages
hex2 -f test/common_x86/ELF-i386.hex2 -f test/test00/return.hex2 --LittleEndian --architecture x86 --BaseAddress 0x8048000 -o test/results/test00-binary --exec_enable || exit 3
hex2 -f test/common_x86/ELF-i386.hex2 -f test/test00/return.hex2 --LittleEndian --architecture x86 --BaseAddress 0x8048000 -o test/results/test00-x86-binary --exec_enable || exit 3
# Ensure binary works if host machine supports test
if [ "$(get_machine ${GET_MACHINE_FLAGS})" = "x86" ]
then
# Verify that the compiled program returns the correct result
./test/results/test00-binary
./test/results/test00-x86-binary
[ 42 = $? ] || exit 3
fi
exit 0

View File

@ -1 +1 @@
0a88d978a2e46b571d0633c09453fb8c622718b06b91ebe89b52735b68cea97d test/test100/proof
690bc220b9748b6328ad98084cccbd83080a4bba09838e364fee5a52dff079d1 test/test100/proof