WONKY



LOG | FILES | OVERVIEW


#ifndef WONKY_INTEL_ASM_INSTRUCTION_C
#define WONKY_INTEL_ASM_INSTRUCTION_C WONKY_INTEL_ASM_INSTRUCTION_C
#include <intel_instruction.h>

struct Intel_Asm_Instruction* get_intel_asm_import(char *what)
{
	return get_intel_asm_label_inner(what,INTEL_ASM_OP_IMPORT);
}
struct Intel_Asm_Instruction* get_intel_asm_export(char *what)
{
	return get_intel_asm_label_inner(what,INTEL_ASM_OP_EXPORT);
}
struct Intel_Asm_Instruction* get_intel_asm_label_inner(char *label,enum Intel_Asm_Instruction_Type type)
{

	struct Intel_Asm_Label *ret;

	ret=wonky_malloc(sizeof(struct Intel_Asm_Label));
	ret->type=type;
	ret->label_name=label;

	return (struct Intel_Asm_Instruction*)ret;
}
struct Intel_Asm_Instruction* get_intel_asm_label(char *label)
{
	return get_intel_asm_label_inner(label,INTEL_ASM_OP_LABEL);
}

struct Intel_Asm_Instruction* get_intel_asm_new_unique_label(struct Compile_Data_Intel_Asm *compile_data)
{
	struct Intel_Asm_Label *ret;
	char *label;
	label=wonky_calloc(1,1024);

	if(snprintf(label,1024,"_label_%d",compile_data->number_of_anon_labels)!=1024)
		label[1023]='\0';/*TODO throw an error*/

	++compile_data->number_of_anon_labels;

	ret=wonky_malloc(sizeof(struct Intel_Asm_Label));
	ret->type=INTEL_ASM_OP_LABEL;
	ret->label_name=label;

	return (struct Intel_Asm_Instruction*)ret;
}
struct Intel_Asm_Instruction* get_intel_asm_binary_instruction(struct Intel_Asm_Memory_Location *left,struct Intel_Asm_Memory_Location *right,enum Intel_Asm_Instruction_Type type)
{
	struct Intel_Asm_Instruction_Binary *ret;
	ret=wonky_malloc(sizeof(struct Intel_Asm_Instruction_Binary));
	ret->type=type;
	ret->left=left;
	ret->right=right;

	return (struct Intel_Asm_Instruction*)ret;
}
struct Intel_Asm_Instruction* get_intel_asm_unary_instruction(struct Intel_Asm_Memory_Location *operand,enum Intel_Asm_Instruction_Type type)
{
	struct Intel_Asm_Instruction_Unary *ret;
	ret=wonky_malloc(sizeof(struct Intel_Asm_Instruction_Unary));
	ret->type=type;
	ret->operand=operand;

	return (struct Intel_Asm_Instruction*)ret;
}
struct Intel_Asm_Instruction* get_intel_asm_jump_instruction(struct Intel_Asm_Label *where_to,enum Intel_Asm_Instruction_Type type)
{
	struct Intel_Asm_Instruction_Jump *ret;
	ret=wonky_malloc(sizeof(struct Intel_Asm_Instruction_Jump));
	ret->type=type;
	ret->where_to=where_to;


	return (struct Intel_Asm_Instruction*)ret;
}
struct Intel_Asm_Instruction* get_intel_asm_simple_instruction(enum Intel_Asm_Instruction_Type type)
{
	struct Intel_Asm_Instruction *ret;
	ret=wonky_malloc(sizeof(struct Intel_Asm_Instruction));
	ret->type=type;

	return ret;
}
struct Intel_Asm_Instruction* get_intel_asm_define_bytes(unsigned char *bytes,int number_of_bytes)
{
	struct Intel_Asm_Instruction_Define_Bytes *ret;
	int i;
	ret=wonky_malloc(sizeof(struct Intel_Asm_Instruction_Define_Bytes));
	ret->type=INTEL_ASM_OP_DEFINE_BYTES;
	ret->number_of_bytes=number_of_bytes;
	ret->bytes=wonky_malloc(number_of_bytes);

	for(i=0;i<number_of_bytes;++i)
		ret->bytes[i]=bytes[i];

	return (struct Intel_Asm_Instruction*)ret;
}
struct Intel_Asm_Instruction* intel_asm_get_pop(enum Intel_Asm_Memory_Location_Type reg)
{
	return get_intel_asm_unary_instruction(get_intel_asm_register(reg),INTEL_ASM_OP_POP);
}
struct Intel_Asm_Instruction* intel_asm_get_push(enum Intel_Asm_Memory_Location_Type reg)
{
	return get_intel_asm_unary_instruction(get_intel_asm_register(reg),INTEL_ASM_OP_PUSH);
}
void save_intel_asm_instruction(struct Intel_Asm_Instruction *instruction,struct wonky_stream *out)
{
	typedef void (*map_entry)(void *,struct wonky_stream *out);
	static const map_entry map[INTEL_ASM_OP_END]
		=
		{
			[INTEL_ASM_OP_ADD]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_SUB]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_MOV]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_MUL]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_DIV]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_JMP]=(map_entry)save_intel_asm_jump_instruction,
			[INTEL_ASM_OP_TEST]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_CMP]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_SETL]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_SETE]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_SETNE]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_SETG]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_SETAE]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_SETBE]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_JE]=(map_entry)save_intel_asm_jump_instruction,
			[INTEL_ASM_OP_JL]=(map_entry)save_intel_asm_jump_instruction,
			[INTEL_ASM_OP_JNZ]=(map_entry)save_intel_asm_jump_instruction,
			[INTEL_ASM_OP_JZ]=(map_entry)save_intel_asm_jump_instruction,
			[INTEL_ASM_OP_RET]=(map_entry)save_intel_asm_simple_instruction,
			[INTEL_ASM_OP_CALL]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_AND]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_XOR]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_OR]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_NOP]=(map_entry)save_intel_asm_simple_instruction,
			[INTEL_ASM_OP_LABEL]=(map_entry)save_intel_asm_label,
			[INTEL_ASM_OP_IMPORT]=(map_entry)save_intel_asm_import,
			[INTEL_ASM_OP_EXPORT]=(map_entry)save_intel_asm_export,
			[INTEL_ASM_OP_POP]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_SAL]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_SAR]=(map_entry)save_intel_asm_binary_instruction,
			[INTEL_ASM_OP_PUSH]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_NEG]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_INC]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_DEC]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_NOT]=(map_entry)save_intel_asm_unary_instruction,
			[INTEL_ASM_OP_DEFINE_BYTES]=(map_entry)save_intel_asm_define_bytes,
		};
	wonky_assert(map[instruction->type]!=NULL);
	map[instruction->type](instruction,out);
}
void save_intel_asm_label(struct Intel_Asm_Label *label,struct wonky_stream *out)
{
	wonky_fprintf(out,"%s:\n",label->label_name);
}
void save_intel_asm_import(struct Intel_Asm_Label *im,struct wonky_stream *out)
{
	wonky_fprintf(out,"extern %s\n",im->label_name);
}
void save_intel_asm_export(struct Intel_Asm_Label *ex,struct wonky_stream *out)
{
	wonky_fprintf(out,"global %s\n",ex->label_name);
}
void save_intel_asm_binary_instruction(struct Intel_Asm_Instruction_Binary *bin,struct wonky_stream *out)
{
	const char *map[INTEL_ASM_OP_END]
		=
		{
			[INTEL_ASM_OP_ADD]="ADD",
			[INTEL_ASM_OP_SUB]="SUB",
			[INTEL_ASM_OP_MOV]="MOV",
			[INTEL_ASM_OP_TEST]="TEST",
			[INTEL_ASM_OP_AND]="AND",
			[INTEL_ASM_OP_XOR]="XOR",
			[INTEL_ASM_OP_OR]="OR",
			[INTEL_ASM_OP_CMP]="CMP",
			[INTEL_ASM_OP_SAL]="SAL",
			[INTEL_ASM_OP_SAR]="SAR",
		};
	wonky_assert(map[bin->type]!=NULL);
	wonky_fprintf(out,"%s ",map[bin->type]);
	save_intel_asm_location(bin->left,out);
	wonky_fprintf(out,", ");
	save_intel_asm_location(bin->right,out);
	wonky_fprintf(out,"\n");
	

}
void save_intel_asm_unary_instruction(struct Intel_Asm_Instruction_Unary *unary,struct wonky_stream *out)
{
	const char *map[INTEL_ASM_OP_END]
		=
		{
			[INTEL_ASM_OP_POP]="POP",
			[INTEL_ASM_OP_PUSH]="PUSH",
			[INTEL_ASM_OP_CALL]="CALL",
			[INTEL_ASM_OP_MUL]="MUL",
			[INTEL_ASM_OP_DIV]="DIV",
			[INTEL_ASM_OP_SETL]="SETL",
			[INTEL_ASM_OP_SETE]="SETE",
			[INTEL_ASM_OP_SETNE]="SETNE",
			[INTEL_ASM_OP_SETG]="SETG",
			[INTEL_ASM_OP_SETAE]="SETAE",
			[INTEL_ASM_OP_SETBE]="SETBE",
			[INTEL_ASM_OP_NEG]="NEG",
			[INTEL_ASM_OP_INC]="INC",
			[INTEL_ASM_OP_DEC]="DEC",
			[INTEL_ASM_OP_NOT]="NOT",
		};
	wonky_assert(map[unary->type]!=NULL);
	wonky_fprintf(out,"%s ",map[unary->type]);
	save_intel_asm_location(unary->operand,out);
	wonky_fprintf(out,"\n");
}
void save_intel_asm_jump_instruction(struct Intel_Asm_Instruction_Jump *jmp,struct wonky_stream *out)
{
	const char *map[INTEL_ASM_OP_END]
		=
		{
			[INTEL_ASM_OP_JMP]="JMP",
			[INTEL_ASM_OP_JE]="JE",
			[INTEL_ASM_OP_JL]="JL",
			[INTEL_ASM_OP_JNZ]="JNZ",
			[INTEL_ASM_OP_JZ]="JZ",
		};
	wonky_assert(map[jmp->type]!=NULL);
	wonky_fprintf(out,"%s %s",map[jmp->type],jmp->where_to->label_name);
	wonky_fprintf(out,"\n");
}
void save_intel_asm_simple_instruction(struct Intel_Asm_Instruction *instruction,struct wonky_stream *out)
{
	static const char *map[INTEL_ASM_OP_END]
		=
		{
			[INTEL_ASM_OP_RET]="RET",
			[INTEL_ASM_OP_NOP]="NOP",
		};
	wonky_assert(map[instruction->type]!=NULL);
	wonky_fprintf(out,"%s\n",map[instruction->type]);

}
void save_intel_asm_define_bytes(struct Intel_Asm_Instruction_Define_Bytes *instruction,struct wonky_stream *out)
{
	int i;

	wonky_fprintf(out,"db ");
	for(i=0;i<instruction->number_of_bytes;++i)
	{
		wonky_fprintf(out,"0x%x",instruction->bytes[i]);
		if(i<instruction->number_of_bytes-1)
			wonky_fprintf(out,", ");
	}
	wonky_fprintf(out,"\n");
}
#endif