#ifndef WONKY_INTEL_ASM_LOCATION_C
#define WONKY_INTEL_ASM_LOCATION_C WONKY_INTEL_ASM_LOCATION_C
#include <intel_location.h>
static const char *register_map[INTEL_ASM_REGISTER_END]
=
{
[INTEL_ASM_REGISTER_EAX]="EAX",
[INTEL_ASM_REGISTER_AX]="AX",
[INTEL_ASM_REGISTER_AL]="AL",
[INTEL_ASM_REGISTER_AH]="AH",
[INTEL_ASM_REGISTER_BX]="BX",
[INTEL_ASM_REGISTER_EDX]="EDX",
[INTEL_ASM_REGISTER_DX]="DX",
[INTEL_ASM_REGISTER_DL]="DL",
[INTEL_ASM_REGISTER_DH]="DH",
[INTEL_ASM_REGISTER_DI]="DI",
[INTEL_ASM_REGISTER_SI]="SI",
[INTEL_ASM_REGISTER_CX]="CX",
[INTEL_ASM_REGISTER_CL]="CL",
[INTEL_ASM_REGISTER_CH]="CH",
[INTEL_ASM_REGISTER_RSP]="RSP",
[INTEL_ASM_REGISTER_RDI]="RDI",
[INTEL_ASM_REGISTER_RSI]="RSI",
[INTEL_ASM_REGISTER_RDX]="RDX",
[INTEL_ASM_REGISTER_RCX]="RCX",
[INTEL_ASM_REGISTER_R8]="R8",
[INTEL_ASM_REGISTER_R9]="R9",
[INTEL_ASM_REGISTER_R11]="R11",
[INTEL_ASM_REGISTER_RAX]="RAX",
[INTEL_ASM_REGISTER_RBP]="RBP",
};
static const char *memory_size_map[INTEL_ASM_MEMORY_SIZE_END]
=
{
[INTEL_ASM_MEMORY_SIZE_BYTE]="BYTE",
[INTEL_ASM_MEMORY_SIZE_WORD]="WORD",
[INTEL_ASM_MEMORY_SIZE_DWORD]="DWORD",
[INTEL_ASM_MEMORY_SIZE_QWORD]="QWORD",
};
struct Intel_Asm_Memory_Location* get_intel_asm_by_register(enum Intel_Asm_Registers reg,size_t size)
{
struct Intel_Asm_Memory_Location_By_Register *ret;
ret=wonky_malloc(sizeof(struct Intel_Asm_Memory_Location_By_Register));
ret->type=INTEL_ASM_MEMORY_LOCATION_BY_REGISTER;
ret->reg=reg;
switch(size)
{
case 1:
ret->size=INTEL_ASM_MEMORY_SIZE_BYTE;
break;
case 2:
ret->size=INTEL_ASM_MEMORY_SIZE_WORD;
break;
case 4:
ret->size=INTEL_ASM_MEMORY_SIZE_DWORD;
break;
case 8:
ret->size=INTEL_ASM_MEMORY_SIZE_QWORD;
break;
default:
wonky_assert(SHOULD_NOT_REACH_HERE);
}
return (struct Intel_Asm_Memory_Location*)ret;
}
struct Intel_Asm_Memory_Location* get_intel_asm_register(enum Intel_Asm_Registers reg)
{
struct Intel_Asm_Memory_Location_Register *ret;
ret=wonky_malloc(sizeof(struct Intel_Asm_Memory_Location_Register));
ret->type=INTEL_ASM_MEMORY_LOCATION_REGISTER;
ret->reg=reg;
return (struct Intel_Asm_Memory_Location*)ret;
}
struct Intel_Asm_Memory_Location* get_intel_asm_label_location(struct Intel_Asm_Label *label)
{
struct Intel_Asm_Memory_Location_By_Label *ret;
ret=wonky_malloc(sizeof(struct Intel_Asm_Memory_Location_By_Label));
ret->type=INTEL_ASM_MEMORY_LOCATION_BY_LABEL;
ret->label=label;
return (struct Intel_Asm_Memory_Location*)ret;
}
struct Intel_Asm_Memory_Location* get_intel_asm_stack_offset(int offset)
{
struct Intel_Asm_Memory_Location_Stack_Offset *ret;
ret=wonky_malloc(sizeof(struct Intel_Asm_Memory_Location_Stack_Offset));
ret->type=INTEL_ASM_MEMORY_LOCATION_STACK_OFFSET;
ret->offset=offset;
return (struct Intel_Asm_Memory_Location*)ret;
}
struct Intel_Asm_Memory_Location* get_intel_asm_by_stack_offset(int offset,size_t size)
{
struct Intel_Asm_Memory_Location_By_Stack_Offset *ret;
ret=wonky_malloc(sizeof(struct Intel_Asm_Memory_Location_By_Stack_Offset));
ret->type=INTEL_ASM_MEMORY_LOCATION_BY_STACK_OFFSET;
ret->offset=offset;
switch(size)
{
case 1:
ret->size=INTEL_ASM_MEMORY_SIZE_BYTE;
break;
case 2:
ret->size=INTEL_ASM_MEMORY_SIZE_WORD;
break;
case 4:
ret->size=INTEL_ASM_MEMORY_SIZE_DWORD;
break;
case 8:
ret->size=INTEL_ASM_MEMORY_SIZE_QWORD;
break;
default:
wonky_assert(SHOULD_NOT_REACH_HERE);
}
return (struct Intel_Asm_Memory_Location*)ret;
}
struct Intel_Asm_Memory_Location* get_intel_asm_by_stack_offset_from_stack_offset(struct Intel_Asm_Memory_Location *location,size_t size)
{
int offset;
wonky_assert(location->type==INTEL_ASM_MEMORY_LOCATION_STACK_OFFSET);
offset=((struct Intel_Asm_Memory_Location_Stack_Offset*)location)->offset;
return get_intel_asm_by_stack_offset(offset,size);
}
struct Intel_Asm_Memory_Location* get_intel_asm_in_instruction_number(int number)
{
struct Intel_Asm_Memory_Location_In_Instruction_Number *ret;
ret=wonky_malloc(sizeof(struct Intel_Asm_Memory_Location_In_Instruction_Number));
ret->type=INTEL_ASM_MEMORY_LOCATION_IN_INSTRUCTION_NUMBER;
ret->number=number;
return (struct Intel_Asm_Memory_Location*)ret;
}
struct Intel_Asm_Memory_Location* intel_asm_get_ax_register()
{
return get_intel_asm_register(INTEL_ASM_REGISTER_AX);
}
struct Intel_Asm_Memory_Location* intel_asm_get_dx_register()
{
return get_intel_asm_register(INTEL_ASM_REGISTER_DX);
}
void save_intel_asm_label_location(struct Intel_Asm_Memory_Location_By_Label *label,struct wonky_stream *out)
{
wonky_fprintf(out,"%s",label->label->label_name);
}
void save_intel_asm_by_stack_offset_location(struct Intel_Asm_Memory_Location_By_Stack_Offset *sp,struct wonky_stream *out)
{
if(sp->offset>=0)
wonky_fprintf(out,"%s [RBP-%d]",memory_size_map[sp->size],sp->offset);
else
wonky_fprintf(out,"%s [RBP+%d]",memory_size_map[sp->size],sp->offset);
}
void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_Stack_Offset *sp,struct wonky_stream *out)
{
if(sp->offset>=0)
wonky_fprintf(out,"RBP-%d",sp->offset);
else
wonky_fprintf(out,"RBP+%d",sp->offset);
}
void save_intel_asm_by_register_location(struct Intel_Asm_Memory_Location_By_Register *reg,struct wonky_stream *out)
{
wonky_assert(register_map[reg->reg]!=NULL);
wonky_fprintf(out,"%s [%s]",memory_size_map[reg->size],register_map[reg->reg]);
}
void save_intel_asm_register_location(struct Intel_Asm_Memory_Location_Register *reg,struct wonky_stream *out)
{
wonky_assert(register_map[reg->reg]!=NULL);
wonky_fprintf(out,"%s",register_map[reg->reg]);
}
void save_intel_asm_location(struct Intel_Asm_Memory_Location *location,struct wonky_stream *out)
{
typedef void (*map_entry)(void *,struct wonky_stream *out);
static const map_entry map[INTEL_ASM_MEMORY_LOCATION_END]
=
{
[INTEL_ASM_MEMORY_LOCATION_BY_REGISTER]=(map_entry)save_intel_asm_by_register_location,
[INTEL_ASM_MEMORY_LOCATION_REGISTER]=(map_entry)save_intel_asm_register_location,
[INTEL_ASM_MEMORY_LOCATION_BY_LABEL]=(map_entry)save_intel_asm_label_location,
[INTEL_ASM_MEMORY_LOCATION_STACK_OFFSET]=(map_entry)save_intel_asm_stack_offset_location,
[INTEL_ASM_MEMORY_LOCATION_BY_STACK_OFFSET]=(map_entry)save_intel_asm_by_stack_offset_location,
[INTEL_ASM_MEMORY_LOCATION_IN_INSTRUCTION_NUMBER]=(map_entry)save_intel_asm_number_in_instruction,
};
wonky_assert(map[location->type]!=NULL);
map[location->type](location,out);
}
void save_intel_asm_number_in_instruction(struct Intel_Asm_Memory_Location_In_Instruction_Number *num,struct wonky_stream *out)
{
wonky_fprintf(out,"%d",num->number);
}
#endif