F diff --git a/src/backend/asm/intel/intel_asm.c b/src/backend/asm/intel/intel_asm.c
--- a/src/backend/asm/intel/intel_asm.c
+++ b/src/backend/asm/intel/intel_asm.c
ret->errors=data->errors;
ret->instructions=data->instructions;
ret->data_block=data->data_block;
+ ret->imports=data->imports;
+ ret->exports=data->exports;
return ret;
}
void save_compiled_intel_asm(struct Compiled_Object_Intel_Asm *object,FILE *out)
{
struct Queue_Node *it;
+ for(it=object->exports->first;it!=NULL;it=it->prev)
+ save_intel_asm_instruction(it->data,out);
+ for(it=object->imports->first;it!=NULL;it=it->prev)
+ save_intel_asm_instruction(it->data,out);
for(it=object->data_block->first;it!=NULL;it=it->prev)
save_intel_asm_instruction(it->data,out);
for(it=object->instructions->first;it!=NULL;it=it->prev)
void save_compiled_intel_asm_as_nasm(struct Compiled_Object_Intel_Asm *object,FILE *out)
{
struct Queue_Node *it;
- fprintf(out,"[BITS 64]\n");
- fprintf(out,"section .data\n");
+ fprintf(out,"[BITS 64]\n\n");
+ for(it=object->exports->first;it!=NULL;it=it->prev)
+ save_intel_asm_instruction(it->data,out);
+ for(it=object->imports->first;it!=NULL;it=it->prev)
+ save_intel_asm_instruction(it->data,out);
+ fprintf(out,"\nsection .data\n");
for(it=object->data_block->first;it!=NULL;it=it->prev)
save_intel_asm_instruction(it->data,out);
fprintf(out,"\nsection .text\n");
ret->data_block=wonky_malloc(sizeof(struct Queue));
Queue_Init(ret->data_block);
+ ret->exports=wonky_malloc(sizeof(struct Queue));
+ Queue_Init(ret->exports);
+
+ ret->imports=wonky_malloc(sizeof(struct Queue));
+ Queue_Init(ret->imports);
+
ret->instructions=wonky_malloc(sizeof(struct Queue));
Queue_Init(ret->instructions);
object->location=(struct Location*)ret;
return ret;
}
+ struct Intel_Asm_Memory_Location* reserve_stack_space_for_function_argument(struct Compile_Data_Intel_Asm *compile_data,struct Object *object)
+ {
+ int size;
+ struct Intel_Asm_Memory_Location *ret;
+ size=(int)get_type_size(object->type);
+
+ compile_data->offset_from_stack_frame+=size;
+ ret=get_intel_asm_stack_offset(compile_data->offset_from_stack_frame);
+
+ object->location=(struct Location*)ret;
+ return ret;
+ }
void release_object_from_stack(struct Compile_Data_Intel_Asm *compile_data,struct Object *object)
{
release_stack_space(compile_data,get_type_size(object->type));
void export_function_definition(struct Compile_Data_Intel_Asm *compile_data,struct AST_Function_Definition *function)
{
wonky_assert(function!=NULL && function->type==ST_FUNCTION_DEFINITION);
- Queue_Push(compile_data->instructions,get_intel_asm_export(gstr_dup(function->function->id->data,function->function->id->data+function->function->id->data_size,1024)));
+ Queue_Push(compile_data->exports,get_intel_asm_export(gstr_dup(function->function->id->data,function->function->id->data+function->function->id->data_size,1024)));
}
void export_object_definition(struct Compile_Data_Intel_Asm *compile_data,struct AST_Object_Declaration *object)
{
wonky_assert(object!=NULL && object->type==ST_OBJECT_DECLARATION);
- Queue_Push(compile_data->instructions,get_intel_asm_export(gstr_dup(object->object->id->data,object->object->id->data+object->object->id->data_size,1024)));
+ Queue_Push(compile_data->exports,get_intel_asm_export(gstr_dup(object->object->id->data,object->object->id->data+object->object->id->data_size,1024)));
}
void import_function_definition(struct Compile_Data_Intel_Asm *compile_data,struct AST_Function_Declaration *function)
{
wonky_assert(function!=NULL && function->type==ST_FUNCTION_DECLARATION);
- Queue_Push(compile_data->instructions,get_intel_asm_import(gstr_dup(function->function->id->data,function->function->id->data+function->function->id->data_size,1024)));
+ Queue_Push(compile_data->imports,get_intel_asm_import(gstr_dup(function->function->id->data,function->function->id->data+function->function->id->data_size,1024)));
}
void import_object_definition(struct Compile_Data_Intel_Asm *compile_data,struct AST_Object_Declaration *object)
{
wonky_assert(object!=NULL && object->type==ST_OBJECT_DECLARATION);
wonky_assert(object->initializer==NULL);/*we only ask for objects without initialisers*/
- Queue_Push(compile_data->instructions,get_intel_asm_import(gstr_dup(object->object->id->data,object->object->id->data+object->object->id->data_size,1024)));
+ Queue_Push(compile_data->imports,get_intel_asm_import(gstr_dup(object->object->id->data,object->object->id->data+object->object->id->data_size,1024)));
}
#endif
F diff --git a/src/backend/asm/intel/intel_asm.h b/src/backend/asm/intel/intel_asm.h
--- a/src/backend/asm/intel/intel_asm.h
+++ b/src/backend/asm/intel/intel_asm.h
struct Queue *errors;
struct Queue *data_block;
+ struct Queue *exports;
+ struct Queue *imports;
struct Queue *instructions;
int number_of_anon_labels;
struct Queue *errors;
struct Queue *data_block;
+ struct Queue *exports;
+ struct Queue *imports;
struct Queue *instructions;
};
void release_value_from_stack(struct Compile_Data_Intel_Asm *compile_data,struct Expression_Value *value);
struct Intel_Asm_Memory_Location* reserve_stack_space_for_object(struct Compile_Data_Intel_Asm *compile_data,struct Object *object);
+ struct Intel_Asm_Memory_Location* reserve_stack_space_for_function_argument(struct Compile_Data_Intel_Asm *compile_data,struct Object *object);
void release_object_from_stack(struct Compile_Data_Intel_Asm *compile_data,struct Object *object);
struct Intel_Asm_Memory_Location* get_location_of_value(struct Compile_Data_Intel_Asm *compile_data,struct Expression_Value *value);
F diff --git a/src/backend/asm/intel/intel_compile.c b/src/backend/asm/intel/intel_compile.c
--- a/src/backend/asm/intel/intel_compile.c
+++ b/src/backend/asm/intel/intel_compile.c
#define WONKY_INTEL_COMPILE_C WONKY_INTEL_COMPILE_C
#include <intel_compile.h>
+ /*the x64 abi is a little more complex TODO*/
+ static const enum Intel_Asm_Registers register_order[6]
+ =
+ {
+ [0]=INTEL_ASM_REGISTER_RDI,
+ [1]=INTEL_ASM_REGISTER_RSI,
+ [2]=INTEL_ASM_REGISTER_RDX,
+ [3]=INTEL_ASM_REGISTER_RCX,
+ [4]=INTEL_ASM_REGISTER_R8,
+ [5]=INTEL_ASM_REGISTER_R9,
+ };
+
void compile_ast_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST *ast)
{
typedef void (*map_entry)(struct Compile_Data_Intel_Asm*,void*);
}
void compile_function_expression_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Function_Expression *call)
{
- /*the x64 abi is a little more complex TODO*/
- static const enum Intel_Asm_Registers register_order[6]
- =
- {
- [0]=INTEL_ASM_REGISTER_RDI,
- [1]=INTEL_ASM_REGISTER_RSI,
- [2]=INTEL_ASM_REGISTER_RDX,
- [3]=INTEL_ASM_REGISTER_RCX,
- [4]=INTEL_ASM_REGISTER_R8,
- [5]=INTEL_ASM_REGISTER_R9,
- };
- int current_register=0;
- size_t i;
+ int current_register;
+ ssize_t i;
+ /*at first pass we store the memory class stuff on the stack*/
+ for(i=call->number_of_arguments-1,current_register=0;i>=0;--i)
+ {
+ if(get_expression_value_size(call->arg_list[i]->value)<=8 && current_register<6)
+ {
+ ++current_register;
+ }else
+ {
+ compile_ast_to_intel_asm(compile_data,(struct AST*)call->arg_list[i]);
+ }
+ }
- for(i=0;i<call->number_of_arguments;++i)
+ /*at the third pass we store the things that go to the registers into the stack*/
+ for(i=call->number_of_arguments-1,current_register=0;i>=0;--i)
{
- compile_ast_to_intel_asm(compile_data,(struct AST*)call->arg_list[i]);
if(get_expression_value_size(call->arg_list[i]->value)<=8 && current_register<6)
{
- push_intel_asm_instruction(compile_data,intel_asm_get_pop(register_order[current_register]));
+ compile_ast_to_intel_asm(compile_data,(struct AST*)call->arg_list[i]);
+ rvalue_to_ax(compile_data,call->arg_list[i]->value);
+ push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
++current_register;
}
}
+ /*we extract the registers from the stack*/
+ for(i=current_register-1,current_register--;i>=0;--i)
+ {
+ push_intel_asm_instruction(compile_data,intel_asm_get_pop(register_order[current_register-i]));
+ }
+
+
+
compile_ast_to_intel_asm(compile_data,(struct AST*)call->id);
push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RAX));
for(current_scope=ret->checkpoint;current_scope!=NULL;current_scope=current_scope->parent)
{
if(current_scope->type==BLOCK_SCOPE)
- release_stack_space_for_whole_block_intel_asm(compile_data,(struct Normal_Scope*)ret->checkpoint);
+ release_stack_space_for_whole_block_intel_asm(compile_data,(struct Normal_Scope*)current_scope);
+ else if(current_scope->type==FUNCTION_PROTOTYPE_SCOPE)
+ release_stack_space_for_whole_block_intel_asm(compile_data,(struct Normal_Scope*)current_scope);
}
}
void compile_function_definition_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Function_Definition *def)
{
+ int current_register;
+ ssize_t i;
+ struct Type_Function *type;
+ enum Intel_Asm_Registers reg;
+
+ type=(struct Type_Function*)def->function->type;
+
compile_data->offset_from_stack_frame=0;
compile_data->stack_space_taken_for_current_block=0;
compile_data->current_function=def;
}
+
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)((struct Intel_Asm_Memory_Location_By_Label*)def->function->location)->label);
+
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RBP));
push_intel_asm_instruction(compile_data,
)
);
+
+ /*anotate the function args*/
+ for(i=type->number_of_arguments-1,current_register=0;i>=0;--i)
+ {
+ if(get_type_size(type->arguments[i]->object->type)<=8 && current_register<6)
+ {
+ ++current_register;
+ }else
+ {
+ reserve_stack_space_for_function_argument(compile_data,type->arguments[i]->object);
+ }
+ }
+
+ for(i=type->number_of_arguments-1,current_register=0;i>=0;--i)
+ {
+ if(get_type_size(type->arguments[i]->object->type)<=8 && current_register<6)
+ {
+ reserve_stack_space_for_object(compile_data,type->arguments[i]->object);
+ push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(INTEL_ASM_REGISTER_RAX),get_intel_asm_register(register_order[current_register]),INTEL_ASM_OP_MOV));
+ reg=get_ax_with_size(get_type_size(type->arguments[i]->object->type));
+ push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(
+ get_intel_asm_by_stack_offset_from_stack_offset((struct Intel_Asm_Memory_Location*)type->arguments[i]->object->location,get_type_size(type->arguments[i]->object->type)),
+ get_intel_asm_register(reg),INTEL_ASM_OP_MOV));
+ ++current_register;
+ }
+ }
+
+
compile_compound_statement_to_intel_asm(compile_data,def->body);
+
push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RBP));
/*if there are no returns we return jiberrish*/
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_RET));
F diff --git a/src/backend/asm/intel/intel_instruction.c b/src/backend/asm/intel/intel_instruction.c
--- a/src/backend/asm/intel/intel_instruction.c
+++ b/src/backend/asm/intel/intel_instruction.c
}
void save_intel_asm_export(struct Intel_Asm_Label *ex,FILE *out)
{
- fprintf(out,"global %s:\n",ex->label_name);
+ fprintf(out,"global %s\n",ex->label_name);
}
void save_intel_asm_binary_instruction(struct Intel_Asm_Instruction_Binary *bin,FILE *out)
{
F diff --git a/src/backend/asm/intel/intel_location.c b/src/backend/asm/intel/intel_location.c
--- a/src/backend/asm/intel/intel_location.c
+++ b/src/backend/asm/intel/intel_location.c
return (struct Intel_Asm_Memory_Location*)ret;
}
- struct Intel_Asm_Memory_Location* get_intel_by_asm_stack_offset(int offset,size_t size)
+ struct Intel_Asm_Memory_Location* get_intel_asm_by_stack_offset(int offset,size_t size)
{
struct Intel_Asm_Memory_Location_By_Stack_Offset *ret;
ret=wonky_malloc(sizeof(struct Intel_Asm_Memory_Location_By_Stack_Offset));
return (struct Intel_Asm_Memory_Location*)ret;
}
+ struct Intel_Asm_Memory_Location* get_intel_asm_by_stack_offset_from_stack_offset(struct Intel_Asm_Memory_Location *location,size_t size)
+ {
+ int offset;
+ wonky_assert(location->type==INTEL_ASM_MEMORY_LOCATION_STACK_OFFSET);
+ offset=((struct Intel_Asm_Memory_Location_Stack_Offset*)location)->offset;
+
+ return get_intel_asm_by_stack_offset(offset,size);
+
+ }
struct Intel_Asm_Memory_Location* get_intel_asm_in_instruction_number(int number)
{
{
fprintf(out,"%s [RBP-%d]",memory_size_map[sp->size],sp->offset);
}
- void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_By_Stack_Offset *sp,FILE *out)
+ void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_Stack_Offset *sp,FILE *out)
{
- fprintf(out,"%s [RBP-%d]",memory_size_map[sp->size],sp->offset);
+ fprintf(out,"RBP-%d",sp->offset);
}
void save_intel_asm_by_register_location(struct Intel_Asm_Memory_Location_By_Register *reg,FILE *out)
{
F diff --git a/src/backend/asm/intel/intel_location.h b/src/backend/asm/intel/intel_location.h
--- a/src/backend/asm/intel/intel_location.h
+++ b/src/backend/asm/intel/intel_location.h
void save_intel_asm_location(struct Intel_Asm_Memory_Location *location,FILE *out);
void save_intel_asm_label_location(struct Intel_Asm_Memory_Location_By_Label *label,FILE *out);
- void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_By_Stack_Offset *sp,FILE *out);
+ void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_Stack_Offset *sp,FILE *out);
void save_intel_asm_by_stack_offset_location(struct Intel_Asm_Memory_Location_By_Stack_Offset *sp,FILE *out);
void save_intel_asm_by_register_location(struct Intel_Asm_Memory_Location_By_Register *reg,FILE *out);
void save_intel_asm_register_location(struct Intel_Asm_Memory_Location_Register *reg,FILE *out);
struct Intel_Asm_Memory_Location* get_intel_asm_label_location(struct Intel_Asm_Label *label);
struct Intel_Asm_Memory_Location* get_intel_asm_stack_offset(int offset);
struct Intel_Asm_Memory_Location* get_intel_asm_by_stack_offset(int offset,size_t size);
+ struct Intel_Asm_Memory_Location* get_intel_asm_by_stack_offset_from_stack_offset(struct Intel_Asm_Memory_Location *location,size_t size);
struct Intel_Asm_Memory_Location* get_intel_asm_in_instruction_number(int number);
struct Intel_Asm_Memory_Location* intel_asm_get_ax_register();
struct Intel_Asm_Memory_Location* intel_asm_get_dx_register();
F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c
--- a/src/frontend/parse/parse_declaration.c
+++ b/src/frontend/parse/parse_declaration.c
wonky_assert(is_valid_denoted_function(function) && is_valid_type((struct Type*)function_type));
+ resolve_function_linkage(scope,translation_data,function);
+ Scope_Push(scope,(struct Denoted*)function,translation_data);
+
function_body
=
(struct AST_Compound_Statement*)
wonky_assert(is_valid_compound_statement(function_body));
- resolve_function_linkage(scope,translation_data,function);
-
- Scope_Push(scope,(struct Denoted*)function,translation_data);
function_definition=get_function_definition_tree(scope,function,function_body,translation_data);