#ifndef WONKY_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*);
static map_entry map[AST_TYPE_END]
=
{
[OP_COMMA]=(map_entry)compile_comma_expression_to_intel_asm,
[OP_ADDITION]=(map_entry)compile_addition_to_intel_asm,
[OP_POINTER_ADDITION]=(map_entry)compile_pointer_addition_to_intel_asm,
[OP_SUBTRACTION]=(map_entry)compile_subtraction_to_intel_asm,
[OP_MUL]=(map_entry)compile_multiplication_to_intel_asm,
[OP_DIV]=(map_entry)compile_div_assign_to_intel_asm,
[OP_REMAINDER]=(map_entry)compile_remainder_to_intel_asm,
[OP_COND]=(map_entry)compile_conditional_expression_to_intel_asm,
[OP_FUNCTION]=(map_entry)compile_function_expression_to_intel_asm,
[OP_ASSIGN]=(map_entry)compile_assign_to_intel_asm,
[OP_ADD_ASSIGN]=(map_entry)compile_add_assign_to_intel_asm,
[OP_SUBTRACT_ASSIGN]=(map_entry)compile_sub_assign_to_intel_asm,
[OP_MULTIPLY_ASSIGN]=(map_entry)compile_mul_assign_to_intel_asm,
[OP_REMAINDER_ASSIGN]=(map_entry)compile_rem_assign_to_intel_asm,
[OP_DIV_ASSIGN]=(map_entry)compile_div_assign_to_intel_asm,
[OP_SHIFT_LEFT_ASSIGN]=(map_entry)compile_shift_left_assign_to_intel_asm,
[OP_SHIFT_RIGHT_ASSIGN]=(map_entry)compile_shift_right_assign_to_intel_asm,
[OP_AND_ASSIGN]=(map_entry)compile_and_assign_to_intel_asm,
[OP_XOR_ASSIGN]=(map_entry)compile_xor_assign_to_intel_asm,
[OP_PIPE_ASSIGN]=(map_entry)compile_pipe_assign_to_intel_asm,
[OP_NOP]=(map_entry)compile_nop_to_intel_asm,
[OP_LOGICAL_OR]=(map_entry)compile_logical_or_to_intel_asm,
[OP_LOGICAL_AND]=(map_entry)compile_logical_and_to_intel_asm,
[OP_LOGICAL_NOT]=(map_entry)compile_logical_not_to_intel_asm,
[OP_BITWISE_OR]=(map_entry)compile_logical_or_to_intel_asm,
[OP_BITWISE_AND]=(map_entry)compile_bitwise_and_to_intel_asm,
[OP_BITWISE_XOR]=(map_entry)compile_bitwise_xor_to_intel_asm,
[OP_BITWISE_NOT]=(map_entry)compile_bitwise_not_to_intel_asm,
[OP_ADDR_OF]=(map_entry)compile_get_address_to_intel_asm,
[OP_DEREFERENCE]=(map_entry)compile_dereference_to_intel_asm,
[OP_MEMBER_TROUGH_PTR]=(map_entry)compile_member_from_ptr_to_intel_asm,
[OP_MEMBER]=(map_entry)compile_member_to_intel_asm,
[OP_ARR_SUBSCRIPT]=(map_entry)compile_subscript_to_intel_asm,
[OP_POSTFIX_INC]=(map_entry)compile_postfix_inc_to_intel_asm,
[OP_POSTFIX_DEC]=(map_entry)compile_postfix_dec_to_intel_asm,
[OP_PREFIX_INC]=(map_entry)compile_prefix_inc_to_intel_asm,
[OP_PREFIX_DEC]=(map_entry)compile_prefix_dec_to_intel_asm,
[OP_UNARY_PLUS]=(map_entry)compile_unary_plus_to_intel_asm,
[OP_UNARY_MINUS]=(map_entry)compile_unary_minus_to_intel_asm,
[OP_CAST]=(map_entry)compile_cast_to_intel_asm,
[OP_SHIFT_LEFT]=(map_entry)compile_shift_left_to_intel_asm,
[OP_SHIFT_RIGHT]=(map_entry)compile_shift_right_to_intel_asm,
[OP_LESS_EQ]=(map_entry)compile_less_eq_to_intel_asm,
[OP_GREATER_EQ]=(map_entry)compile_greater_eq_to_intel_asm,
[OP_LESS]=(map_entry)compile_less_to_intel_asm,
[OP_GREATER]=(map_entry)compile_greater_to_intel_asm,
[OP_EQUAL]=(map_entry)compile_equal_to_intel_asm,
[OP_NOT_EQUAL]=(map_entry)compile_not_equal_to_intel_asm,
[OP_DESIGNATOR]=(map_entry)compile_designator_to_intel_asm,
[OP_CONSTANT]=(map_entry)compile_constant_to_intel_asm,
[OP_STRING_LITERAL]=(map_entry)compile_string_literal_to_intel_asm,
[ST_COMPOUND]=(map_entry)compile_compound_statement_to_intel_asm,
[ST_EXPRESSION]=(map_entry)compile_expression_statement,
[ST_SWITCH]=(map_entry)compile_switch_to_intel_asm,
[ST_IF]=(map_entry)compile_if_to_intel_asm,
[ST_WHILE]=(map_entry)compile_while_to_intel_asm,
[ST_DO_WHILE]=(map_entry)compile_do_while_to_intel_asm,
[ST_GOTO]=(map_entry)compile_goto_to_intel_asm,
[ST_LABEL]=(map_entry)compile_labeled_statement_to_intel_asm,
[ST_CASE]=(map_entry)compile_case_to_intel_asm,
[ST_DEFAULT]=(map_entry)compile_default_to_intel_asm,
[ST_CONTINUE]=(map_entry)compile_break_continue_statement_to_intel_asm,
[ST_BREAK]=(map_entry)compile_break_continue_statement_to_intel_asm,
[ST_RETURN]=(map_entry)compile_return_to_intel_asm,
[ST_FOR]=(map_entry)compile_for_to_intel_asm,
[ST_OBJECT_DECLARATION]=(map_entry)compile_object_declaration_to_intel_asm,
[ST_FUNCTION_DEFINITION]=(map_entry)compile_function_definition_to_intel_asm,
};
wonky_assert(is_valid_ast(ast));
wonky_assert(map[ast->type]!=NULL);
map[ast->type](compile_data,ast);
}
void compile_conditional_expression_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Conditional_Expression *expression)
{
struct Intel_Asm_Label *end;
struct Intel_Asm_Label *second;
struct Intel_Asm_Memory_Location *ax_register;
end=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
second=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
compile_ast_to_intel_asm(compile_data,(struct AST*)expression->left);
push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RAX));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(intel_asm_get_ax_register(),intel_asm_get_ax_register(),INTEL_ASM_OP_TEST));
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(second,INTEL_ASM_OP_JZ));
compile_ast_to_intel_asm(compile_data,(struct AST*)expression->center);
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(end,INTEL_ASM_OP_JMP));
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)second);
compile_ast_to_intel_asm(compile_data,(struct AST*)expression->right);
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)end);
}
void compile_function_expression_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Function_Expression *call)
{
int current_register;
ssize_t i;
int size_on_stack_for_arguments=0;
int size_of_stack_padding=0;
/*stack must be aligned to 16 bytes*/
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
{
size_on_stack_for_arguments+=get_expression_value_size(call->arg_list[i]->value);
}
}
size_of_stack_padding=(16-(compile_data->offset_from_stack_frame+size_on_stack_for_arguments)%16)%16;
if(size_of_stack_padding != 0)
reserve_stack_space(compile_data,size_of_stack_padding);
/*at second 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]);
}
}
/*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)
{
if(get_expression_value_size(call->arg_list[i]->value)<=8 && current_register<6)
{
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_R11));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(
get_intel_asm_register(INTEL_ASM_REGISTER_EAX),
get_intel_asm_register(INTEL_ASM_REGISTER_EAX),
INTEL_ASM_OP_XOR));
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(get_intel_asm_register(INTEL_ASM_REGISTER_R11),INTEL_ASM_OP_CALL));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
/*'unalign' the stack*/
if(size_of_stack_padding != 0)
release_stack_space(compile_data,size_of_stack_padding);
release_stack_space(compile_data,size_on_stack_for_arguments);
}
void compile_constant_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Constant *constant)
{
if(constant->value->constant->type->specifier==TS_INT)
{
intel_asm_memory_location_to_rax(compile_data,get_intel_asm_in_instruction_number(*(int*)constant->value->constant->value));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}else
{
intel_asm_memory_location_to_rax(compile_data,
reserve_static_space_for_object(compile_data,(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data),get_type_size(constant->value->constant->type)));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
}
void compile_string_literal_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_String_Literal *literal)
{
struct Intel_Asm_Memory_Location *string_location;
string_location=reserve_static_space_for_string(compile_data,literal->value->constant);
push_intel_asm_instruction(compile_data,
get_intel_asm_binary_instruction(
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
string_location,
INTEL_ASM_OP_MOV
)
);
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_designator_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Designator *designator)
{
intel_asm_memory_location_to_rax(compile_data,get_location_of_value(compile_data,designator->value));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_labeled_statement_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Labeled_Statement *labeled)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_break_continue_statement_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Break_Continue_Statement *br)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_compound_statement_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Compound_Statement *statement)
{
struct Queue_Node *it;
static const _Bool is_expression[AST_TYPE_END]
=
{
[OP_COMMA]=1,
[OP_ADDITION]=1,
[OP_POINTER_ADDITION]=1,
[OP_SUBTRACTION]=1,
[OP_MUL]=1,
[OP_DIV]=1,
[OP_REMAINDER]=1,
[OP_COND]=1,
[OP_FUNCTION]=1,
[OP_ASSIGN]=1,
[OP_ADD_ASSIGN]=1,
[OP_SUBTRACT_ASSIGN]=1,
[OP_MULTIPLY_ASSIGN]=1,
[OP_REMAINDER_ASSIGN]=1,
[OP_DIV_ASSIGN]=1,
[OP_SHIFT_LEFT_ASSIGN]=1,
[OP_SHIFT_RIGHT_ASSIGN]=1,
[OP_AND_ASSIGN]=1,
[OP_XOR_ASSIGN]=1,
[OP_PIPE_ASSIGN]=1,
[OP_LOGICAL_OR]=1,
[OP_LOGICAL_AND]=1,
[OP_LOGICAL_NOT]=1,
[OP_BITWISE_OR]=1,
[OP_BITWISE_AND]=1,
[OP_BITWISE_XOR]=1,
[OP_BITWISE_NOT]=1,
[OP_ADDR_OF]=1,
[OP_DEREFERENCE]=1,
[OP_MEMBER_TROUGH_PTR]=1,
[OP_MEMBER]=1,
[OP_ARR_SUBSCRIPT]=1,
[OP_POSTFIX_INC]=1,
[OP_POSTFIX_DEC]=1,
[OP_PREFIX_INC]=1,
[OP_PREFIX_DEC]=1,
[OP_UNARY_PLUS]=1,
[OP_UNARY_MINUS]=1,
[OP_CAST]=1,
[OP_SHIFT_LEFT]=1,
[OP_SHIFT_RIGHT]=1,
[OP_LESS_EQ]=1,
[OP_GREATER_EQ]=1,
[OP_LESS]=1,
[OP_GREATER]=1,
[OP_EQUAL]=1,
[OP_NOT_EQUAL]=1,
[OP_DESIGNATOR]=1,
[OP_CONSTANT]=1,
[OP_STRING_LITERAL]=1,
[ST_COMPOUND]=1,
};
for(it=statement->components->first;it!=NULL;it=it->prev)
{
compile_ast_to_intel_asm(compile_data,it->data);
if(is_expression[((struct AST*)it->data)->type])
push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RAX));
}
release_stack_space_for_whole_block_intel_asm(compile_data,(struct Normal_Scope*)statement->scope);
}
void compile_for_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_For_Statement *statement)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_while_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_While_Statement *wh)
{
struct Intel_Asm_Label *loop;
struct Intel_Asm_Label *end;
loop=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
end=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)loop);
compile_ast_to_intel_asm(compile_data,wh->condition);
push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RAX));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
INTEL_ASM_OP_TEST));
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(end,INTEL_ASM_OP_JZ));
compile_ast_to_intel_asm(compile_data,wh->body_statement);
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(loop,INTEL_ASM_OP_JMP));
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)end);
}
void compile_do_while_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Do_While_Statement *do_while)
{
struct Intel_Asm_Label *loop;
loop=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)loop);
compile_ast_to_intel_asm(compile_data,do_while->body_statement);
compile_ast_to_intel_asm(compile_data,do_while->condition);
push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RAX));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
INTEL_ASM_OP_TEST));
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(loop,INTEL_ASM_OP_JNZ));
}
void compile_if_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_If_Statement *statement)
{
struct Intel_Asm_Label *if_false;
struct Intel_Asm_Label *end;
end=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
if(statement->else_statement==NULL)
if_false=end;
else
if_false=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
compile_ast_to_intel_asm(compile_data,statement->condition);
push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RAX));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
INTEL_ASM_OP_TEST));
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(if_false,INTEL_ASM_OP_JZ));
compile_ast_to_intel_asm(compile_data,statement->body_statement);
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(end,INTEL_ASM_OP_JMP));
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)if_false);
if(statement->else_statement!=NULL)
compile_ast_to_intel_asm(compile_data,statement->else_statement);
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)end);
}
void compile_goto_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Goto_Statement *jump)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_switch_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Switch_Statement *sw)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_default_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Default_Statement *def)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_case_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Case_Statement *cs)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_return_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Return_Statement *ret)
{
struct Scope *current_scope;
if(ret->return_expression!=NULL)
{
compile_ast_to_intel_asm(compile_data,ret->return_expression);
rvalue_to_ax(compile_data,((struct AST_Expression*)ret->return_expression)->value);
}
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*)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);
}
push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RBP));
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_RET));
}
void compile_object_declaration_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Object_Declaration *objd)
{
reserve_stack_space_for_object(compile_data,objd->object->object);
}
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;
int size_on_stack_for_arguments=0;
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;
export_function_definition(compile_data,def);
if(!gstrn_cmp(def->function->id->data,"main",sizeof("main")-1))
compile_data->in_main=0;
else
compile_data->in_main=1;
if(def->function->location==NULL)
{
def->function->location=(struct Memory_Location*)
get_intel_asm_label_location(
(struct Intel_Asm_Label*)get_intel_asm_label(
gstr_dup(
def->function->id->data,
def->function->id->data+def->function->id->size,
1024
)
)
);
}
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,
get_intel_asm_binary_instruction(
get_intel_asm_register(INTEL_ASM_REGISTER_RBP),
get_intel_asm_register(INTEL_ASM_REGISTER_RSP),
INTEL_ASM_OP_MOV
)
);
/*anotate the function args*/
/*memory class stuff*/
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
{
size_on_stack_for_arguments+=get_type_size(type->arguments[i]->object->type);
reserve_stack_space_for_function_argument(compile_data,type->arguments[i]->object);
}
}
/*push the things on the registers to stack*/
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));
}
void compile_translation_unit_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Translation_Unit *unit)
{
struct Queue_Node *it;
Map_Map_Extended(((struct Normal_Scope*)unit->file_scope)->ordinary,(void (*)(void*,void*))intel_asm_anotate_denoted,compile_data);
for(it=unit->function_definitions->first;it!=NULL;it=it->prev)
compile_ast_to_intel_asm(compile_data,it->data);
}
void compile_expression_statement(struct Compile_Data_Intel_Asm *compile_data,struct AST_Expression *expression)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_comma_expression_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_addition_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_simple_bin_inner(compile_data,bin,INTEL_ASM_OP_ADD);
}
void compile_subtraction_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_simple_bin_inner(compile_data,bin,INTEL_ASM_OP_SUB);
}
void compile_pointer_addition_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_multiplication_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_mul_div_inner(compile_data,bin,INTEL_ASM_OP_MUL);
}
void compile_division_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_mul_div_inner(compile_data,bin,INTEL_ASM_OP_DIV);
}
void compile_remainder_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
if(type_is_scalar(extract_expresion_value_type(bin->left->value)))
{
compile_op_assign_inner(compile_data,bin,INTEL_ASM_OP_MOV);
}else
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
}
void compile_add_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_sub_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_mul_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_rem_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
enum Intel_Asm_Registers ax;
enum Intel_Asm_Registers dx;
int left_size;
left_size=get_expression_value_size(bin->left->value);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
dx=rvalue_to_dx(compile_data,bin->right->value);
lvalue_to_rax(compile_data,bin->left->value);
ax=get_ax_with_size(left_size);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(INTEL_ASM_REGISTER_R11),
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(ax),
get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,left_size),
INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(get_intel_asm_register(dx),
INTEL_ASM_OP_DIV));
if(left_size!=1)
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_by_register(INTEL_ASM_REGISTER_R11,left_size),
get_intel_asm_register(dx),
INTEL_ASM_OP_MOV));
else
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_by_register(INTEL_ASM_REGISTER_R11,left_size),
get_intel_asm_register(INTEL_ASM_REGISTER_AL),
INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_R11));
}
void compile_div_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
enum Intel_Asm_Registers ax;
enum Intel_Asm_Registers dx;
int left_size;
left_size=get_expression_value_size(bin->left->value);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
dx=rvalue_to_dx(compile_data,bin->right->value);
lvalue_to_rax(compile_data,bin->left->value);
ax=get_ax_with_size(left_size);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(INTEL_ASM_REGISTER_R11),
get_intel_asm_register(INTEL_ASM_REGISTER_RAX),
INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(ax),
get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,left_size),
INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(get_intel_asm_register(dx),
INTEL_ASM_OP_DIV));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_by_register(INTEL_ASM_REGISTER_R11,left_size),
get_intel_asm_register(ax),
INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_R11));
}
void compile_shift_left_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_shift_assign_inner(compile_data,bin,INTEL_ASM_OP_SAL);
}
void compile_shift_right_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_shift_assign_inner(compile_data,bin,INTEL_ASM_OP_SAR);
}
void compile_and_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_op_assign_inner(compile_data,bin,INTEL_ASM_OP_AND);
}
void compile_xor_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_op_assign_inner(compile_data,bin,INTEL_ASM_OP_XOR);
}
void compile_pipe_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_op_assign_inner(compile_data,bin,INTEL_ASM_OP_OR);
}
void compile_nop_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,void *dummy)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_logical_or_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_logical_and_or_inner(compile_data,bin,INTEL_ASM_OP_JZ);
}
void compile_logical_and_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_logical_and_or_inner(compile_data,bin,INTEL_ASM_OP_JNZ);
}
void compile_logical_not_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
enum Intel_Asm_Registers reg;
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
reg=rvalue_to_ax(compile_data,unary->operand->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(reg),get_intel_asm_register(reg),INTEL_ASM_OP_TEST));
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(INTEL_ASM_REGISTER_RAX,INTEL_ASM_OP_SETNE));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_bitwise_or_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_simple_bin_inner(compile_data,bin,INTEL_ASM_OP_OR);
}
void compile_bitwise_and_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_simple_bin_inner(compile_data,bin,INTEL_ASM_OP_AND);
}
void compile_bitwise_xor_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_simple_bin_inner(compile_data,bin,INTEL_ASM_OP_XOR);
}
void compile_bitwise_not_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
enum Intel_Asm_Registers reg;
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
reg=rvalue_to_ax(compile_data,unary->operand->value);
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(get_intel_asm_register(reg),INTEL_ASM_OP_NOT));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_get_address_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
}
void compile_dereference_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
enum Intel_Asm_Registers ax;
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
lvalue_to_rax(compile_data,unary->operand->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(INTEL_ASM_REGISTER_RAX),get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,8),INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_member_from_ptr_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_member_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_subscript_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));
}
void compile_postfix_inc_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
compile_postfix_inc_dec_inner(compile_data,unary,INTEL_ASM_OP_INC);
}
void compile_postfix_dec_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
compile_postfix_inc_dec_inner(compile_data,unary,INTEL_ASM_OP_DEC);
}
void compile_prefix_inc_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
compile_prefix_inc_dec_inner(compile_data,unary,INTEL_ASM_OP_INC);
}
void compile_prefix_dec_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
compile_prefix_inc_dec_inner(compile_data,unary,INTEL_ASM_OP_DEC);
}
void compile_unary_plus_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
}
void compile_unary_minus_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
enum Intel_Asm_Registers ax;
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
ax=rvalue_to_ax(compile_data,unary->operand->value);
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(get_intel_asm_register(ax),INTEL_ASM_OP_NEG));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_cast_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary)
{
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
}
void compile_shift_left_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_shift_inner(compile_data,bin,INTEL_ASM_OP_SAL);
}
void compile_shift_right_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_shift_inner(compile_data,bin,INTEL_ASM_OP_SAR);
}
void compile_less_eq_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_comparison_inner(compile_data,bin,INTEL_ASM_OP_SETBE);
}
void compile_greater_eq_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_comparison_inner(compile_data,bin,INTEL_ASM_OP_SETAE);
}
void compile_less_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_comparison_inner(compile_data,bin,INTEL_ASM_OP_SETL);
}
void compile_greater_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_comparison_inner(compile_data,bin,INTEL_ASM_OP_SETG);
}
void compile_equal_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_comparison_inner(compile_data,bin,INTEL_ASM_OP_SETE);
}
void compile_not_equal_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin)
{
compile_comparison_inner(compile_data,bin,INTEL_ASM_OP_SETNE);
}
void compile_prefix_inc_dec_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary,enum Intel_Asm_Instruction_Type op)
{
enum Intel_Asm_Registers reg;
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
lvalue_to_rax(compile_data,unary->operand->value);
reg=get_dx_with_size(get_expression_value_size(unary->operand->value));
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,get_expression_value_size(unary->operand->value)),op));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(reg),get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,get_expression_value_size(unary->operand->value)),INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_postfix_inc_dec_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Unary_Expression *unary,enum Intel_Asm_Instruction_Type op)
{
enum Intel_Asm_Registers reg;
compile_ast_to_intel_asm(compile_data,(struct AST*)unary->operand);
reg=get_dx_with_size(get_expression_value_size(unary->operand->value));
lvalue_to_rax(compile_data,unary->operand->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(reg),get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,get_expression_value_size(unary->operand->value)),INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,get_expression_value_size(unary->operand->value)),op));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_comparison_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin,enum Intel_Asm_Instruction_Type op)
{
enum Intel_Asm_Registers ax;
enum Intel_Asm_Registers dx;
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
dx=rvalue_to_dx(compile_data,bin->right->value);
ax=rvalue_to_ax(compile_data,bin->left->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(ax),get_intel_asm_register(dx),INTEL_ASM_OP_CMP));
intel_asm_finish_comparison(compile_data,op);
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_shift_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin,enum Intel_Asm_Instruction_Type op)
{
enum Intel_Asm_Registers ax;
enum Intel_Asm_Registers dx;
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
dx=rvalue_to_dx(compile_data,bin->right->value);
ax=rvalue_to_ax(compile_data,bin->left->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(INTEL_ASM_REGISTER_CL),get_intel_asm_register(INTEL_ASM_REGISTER_DL),INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(ax),get_intel_asm_register(INTEL_ASM_REGISTER_CL),op));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_simple_bin_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin,enum Intel_Asm_Instruction_Type op)
{
enum Intel_Asm_Registers ax;
enum Intel_Asm_Registers dx;
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
dx=rvalue_to_dx(compile_data,bin->right->value);
ax=rvalue_to_ax(compile_data,bin->left->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(ax),get_intel_asm_register(dx),op));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_mul_div_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin,enum Intel_Asm_Instruction_Type op)
{
enum Intel_Asm_Registers ax;
enum Intel_Asm_Registers dx;
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
ax=rvalue_to_ax(compile_data,bin->right->value);
dx=rvalue_to_dx(compile_data,bin->left->value);
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(get_intel_asm_register(dx),op));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_logical_and_or_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin,enum Intel_Asm_Instruction_Type cmp)
{
struct Intel_Asm_Label *first_is_true;
struct Intel_Asm_Label *end;
enum Intel_Asm_Registers reg;
end=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
first_is_true=(struct Intel_Asm_Label*)get_intel_asm_new_unique_label(compile_data);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
reg=rvalue_to_ax(compile_data,bin->left->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(
get_intel_asm_register(reg),
get_intel_asm_register(reg),
INTEL_ASM_OP_TEST));
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(first_is_true,cmp));
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(
get_intel_asm_register(INTEL_ASM_REGISTER_AL),
INTEL_ASM_OP_SETNE));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
push_intel_asm_instruction(compile_data,get_intel_asm_jump_instruction(end,INTEL_ASM_OP_JMP));
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)first_is_true);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
rvalue_to_ax(compile_data,bin->right->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(
get_intel_asm_register(reg),
get_intel_asm_register(reg),
INTEL_ASM_OP_TEST));
push_intel_asm_instruction(compile_data,get_intel_asm_unary_instruction(
get_intel_asm_register(INTEL_ASM_REGISTER_AL),
INTEL_ASM_OP_SETNE));
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
push_intel_asm_instruction(compile_data,(struct Intel_Asm_Instruction*)end);
}
void compile_op_assign_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin,enum Intel_Asm_Instruction_Type op)
{
enum Intel_Asm_Registers dx;
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
dx=rvalue_to_dx(compile_data,bin->right->value);
lvalue_to_rax(compile_data,bin->left->value);
push_intel_asm_instruction(compile_data,
get_intel_asm_binary_instruction(
get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,get_expression_value_size(bin->left->value)),
get_intel_asm_register(dx),
op)
);
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
void compile_shift_assign_inner(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin,enum Intel_Asm_Instruction_Type op)
{
enum Intel_Asm_Registers dx;
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);
compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);
dx=rvalue_to_dx(compile_data,bin->right->value);
lvalue_to_rax(compile_data,bin->left->value);
push_intel_asm_instruction(compile_data,get_intel_asm_binary_instruction(get_intel_asm_register(INTEL_ASM_REGISTER_CL),get_intel_asm_register(INTEL_ASM_REGISTER_DL),INTEL_ASM_OP_MOV));
push_intel_asm_instruction(compile_data,
get_intel_asm_binary_instruction(
get_intel_asm_by_register(INTEL_ASM_REGISTER_RAX,get_expression_value_size(bin->left->value)),
get_intel_asm_register(INTEL_ASM_REGISTER_CL),
op)
);
push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));
}
#endif