WONKY



LOG | FILES | OVERVIEW


#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