Skip to content

Commit

Permalink
Lecture 150 - Generating structures part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
dragonzapeducation committed Aug 25, 2022
1 parent e363aa1 commit bb908ff
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
52 changes: 47 additions & 5 deletions codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void codegen_generate_exp_node(struct node *node, struct history *history);
const char *codegen_sub_register(const char *original_register, size_t size);
void codegen_generate_entity_access_for_function_call(struct resolver_result* result, struct resolver_entity* entity);
void codegen_generate_structure_push(struct resolver_entity* entity, struct history* history, int start_pos);

void codegen_plus_or_minus_string_for_value(char* out, int val, size_t len);
void codegen_new_scope(int flags)
{
resolver_default_new_scope(current_process->resolver, flags);
Expand Down Expand Up @@ -186,6 +186,18 @@ void asm_push_ins_push(const char *fmt, int stack_entity_type, const char *stack
stackframe_push(current_function, &(struct stack_frame_element){.type = stack_entity_type, .name = stack_entity_name});
}

void asm_push_ins_push_with_flags(const char* fmt, int stack_entity_type, const char* stack_entity_name, int flags, ...)
{
char tmp_buf[200];
sprintf(tmp_buf, "push %s", fmt);
va_list args;
va_start(args, flags);
asm_push_args(tmp_buf, args);
va_end(args);
assert(current_function);
stackframe_push(current_function, &(struct stack_frame_element){.flags=flags,.type=stack_entity_type,.name=stack_entity_name});
}

int asm_push_ins_pop(const char *fmt, int expecting_stack_entity_type, const char *expecting_stack_entity_name, ...)
{
char tmp_buf[200];
Expand Down Expand Up @@ -563,12 +575,29 @@ void codegen_reduce_register(const char *reg, size_t size, bool is_signed)
asm_push("%s eax, %s", codegen_sub_register("eax", size));
}
}

void codegen_gen_mem_access_get_address(struct node* node, int flags, struct resolver_entity* entity)
{
asm_push("lea ebx, [%s]", codegen_entity_private(entity)->address);
asm_push_ins_push_with_flags("ebx", STACK_FRAME_ELEMENT_TYPE_PUSHED_VALUE, "result_value", STACK_FRAME_ELEMENT_FLAG_IS_PUSHED_ADDRESS);
}

void codegen_generate_structure_push_or_return(struct resolver_entity* entity, struct history* history, int start_pos)
{
codegen_generate_structure_push(entity, history, start_pos);
}

void codegen_gen_mem_access(struct node *node, int flags, struct resolver_entity *entity)
{
#warning "generate & address"
#warning "generate structure non pointer access"

if (datatype_element_size(&entity->dtype) != DATA_SIZE_DWORD)
if (datatype_is_struct_or_union_non_pointer(&entity->dtype))
{
codegen_gen_mem_access_get_address(node, 0, entity);
asm_push_ins_pop("ebx", STACK_FRAME_ELEMENT_TYPE_PUSHED_VALUE, "result_value");
codegen_generate_structure_push_or_return(entity, history_begin(0), 0);
}
else if (datatype_element_size(&entity->dtype) != DATA_SIZE_DWORD)
{
asm_push("mov eax, [%s]", codegen_entity_private(entity)->address);
codegen_reduce_register("eax", datatype_element_size(&entity->dtype), entity->dtype.flags & DATATYPE_FLAG_IS_SIGNED);
Expand Down Expand Up @@ -825,6 +854,19 @@ void codegen_generate_entity_access_for_assignment_left_operand(struct resolver_
}
}

void codegen_generate_move_struct(struct datatype* dtype, const char* base_address, off_t offset)
{
size_t structure_size = align_value(datatype_size(dtype), DATA_SIZE_DWORD);
int pops = structure_size / DATA_SIZE_DWORD;
for (int i = 0; i < pops; i++)
{
asm_push_ins_pop("eax", STACK_FRAME_ELEMENT_TYPE_PUSHED_VALUE, "result_value");
char fmt[10];
int chunk_offset = offset + (i*DATA_SIZE_DWORD);
codegen_plus_or_minus_string_for_value(fmt, chunk_offset, sizeof(fmt));
asm_push("mov [%s%s], eax", base_address, fmt);
}
}
void codegen_generate_assignment_part(struct node *node, const char *op, struct history *history)
{
struct datatype right_operand_dtype;
Expand All @@ -838,7 +880,7 @@ void codegen_generate_assignment_part(struct node *node, const char *op, struct
{
if (datatype_is_struct_or_union_non_pointer(&result->last_entity->dtype))
{
#warning "generate a move struct"
codegen_generate_move_struct(&result->last_entity->dtype, result->base.address, 0);
}
else
{
Expand Down Expand Up @@ -1402,7 +1444,7 @@ void codegen_generate_structure_push(struct resolver_entity* entity, struct hist
asm_push("; STRUCTURE PUSH");
size_t structure_size= align_value(entity->dtype.size, DATA_SIZE_DWORD);
int pushes = structure_size / DATA_SIZE_DWORD;
for (int i = pushes-1; i >= start_pos; i++)
for (int i = pushes-1; i >= start_pos; i--)
{
char fmt[10];
int chunk_offset = (i * DATA_SIZE_DWORD);
Expand Down
Binary file modified test
Binary file not shown.
7 changes: 4 additions & 3 deletions test.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ struct dog
char kk;
};

struct dog a;

int main()
{
int e;
a.kk = 10;
struct dog a;
struct dog b;
a = b;

}

0 comments on commit bb908ff

Please sign in to comment.