Encoding "load and store" instructions much better already

This commit is contained in:
Pierre Pronchery 2011-04-21 16:16:07 +00:00
parent b2a710ed6f
commit 9b692011ca

View File

@ -41,7 +41,7 @@ static ArchInstruction _sparc_instructions[] =
/* prototypes */
/* plug-in */
static int _sparc_write(ArchPlugin * arch, ArchInstruction * instruction,
static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
@ -63,15 +63,106 @@ ArchPlugin arch_plugin =
/* functions */
/* plug-in */
/* sparc_write */
static int _sparc_write(ArchPlugin * arch, ArchInstruction * instruction,
static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode);
static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
uint32_t buf;
uint32_t opcode = instruction->opcode;
buf = instruction->opcode;
if((opcode & 0xc0000000) == 0xc0000000 && _write_loadstore(plugin,
instruction, call, &opcode) != 0)
return -1;
/* FIXME implement the rest */
buf = _htob32(buf);
if(fwrite(&buf, sizeof(buf), 1, arch->helper->fp) != 1)
opcode = _htob32(opcode);
if(fwrite(&opcode, sizeof(opcode), 1, plugin->helper->fp) != 1)
return -1;
return 0;
}
static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode)
{
ArchPluginHelper * helper = plugin->helper;
uint32_t rd;
uint32_t rs1;
uint32_t rs2;
char const * name;
ArchRegister * ar;
if(instruction->opcode & (1 << 21)) /* store instruction */
{
/* rd */
if(AO_GET_TYPE(instruction->op1) != AOT_REGISTER)
return -1;
name = call->operands[0].value._register.name;
if((ar = helper->get_register_by_name_size(helper->arch,
name, 32)) == NULL)
return -1;
rd = (ar->id << 25);
/* [rs1 + rs2] */
if(AO_GET_TYPE(instruction->op2) == AOT_DREGISTER2)
{
name = call->operands[1].value.dregister2.name;
if((ar = helper->get_register_by_name_size(helper->arch,
name, 32)) == NULL)
return -1;
rs1 = (ar->id << 14);
name = call->operands[1].value.dregister2.name2;
if((ar = helper->get_register_by_name_size(helper->arch,
name, 32)) == NULL)
return -1;
rs2 = ar->id;
}
else if(AO_GET_TYPE(instruction->op2) == AOT_DREGISTER)
{
name = call->operands[1].value.dregister.name;
if((ar = helper->get_register_by_name_size(helper->arch,
name, 32)) == NULL)
return -1;
rs1 = (ar->id << 14);
rs2 = 0; /* FIXME implement */
}
else
return -1;
}
else
{
/* [rs1 + rs2] */
if(AO_GET_TYPE(instruction->op1) == AOT_DREGISTER2)
{
name = call->operands[0].value.dregister2.name;
if((ar = helper->get_register_by_name_size(helper->arch,
name, 32)) == NULL)
return -1;
rs1 = (ar->id << 14);
name = call->operands[0].value.dregister2.name2;
if((ar = helper->get_register_by_name_size(helper->arch,
name, 32)) == NULL)
return -1;
rs2 = ar->id;
}
else if(AO_GET_TYPE(instruction->op1) == AOT_DREGISTER)
{
name = call->operands[0].value.dregister.name;
if((ar = helper->get_register_by_name_size(helper->arch,
name, 32)) == NULL)
return -1;
rs1 = (ar->id << 14);
rs2 = 0; /* FIXME implement */
}
else
return -1;
/* rd */
if(AO_GET_TYPE(instruction->op2) != AOT_REGISTER)
return -1;
name = call->operands[1].value._register.name;
if((ar = helper->get_register_by_name_size(helper->arch,
name, 32)) == NULL)
return -1;
rd = (ar->id << 25);
}
*opcode |= (rd | rs1 | rs2);
return 0;
}