Encoding instructions for integer operations as well

This commit is contained in:
Pierre Pronchery 2011-04-21 16:39:36 +00:00
parent 33039927e3
commit f8312d08fb

View File

@ -63,6 +63,8 @@ ArchPlugin arch_plugin =
/* functions */ /* functions */
/* plug-in */ /* plug-in */
/* sparc_write */ /* sparc_write */
static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode);
static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction, static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode); ArchInstructionCall * call, uint32_t * opcode);
static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction, static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction,
@ -79,6 +81,9 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
else if((opcode & 0x01000000) == 0x01000000 && _write_sethi(plugin, else if((opcode & 0x01000000) == 0x01000000 && _write_sethi(plugin,
instruction, call, &opcode) != 0) instruction, call, &opcode) != 0)
return -1; return -1;
else if((opcode & 0xc0000000) == 0x80000000 && _write_integer(plugin,
instruction, call, &opcode) != 0)
return -1;
/* FIXME implement the rest */ /* FIXME implement the rest */
opcode = _htob32(opcode); opcode = _htob32(opcode);
if(fwrite(&opcode, sizeof(opcode), 1, plugin->helper->fp) != 1) if(fwrite(&opcode, sizeof(opcode), 1, plugin->helper->fp) != 1)
@ -86,6 +91,55 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
return 0; return 0;
} }
static int _write_integer(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;
/* rs1 */
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;
rs1 = (ar->id << 14);
/* rs2 */
if(AO_GET_TYPE(instruction->op2) == AOT_REGISTER)
{
name = call->operands[1].value._register.name;
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_IMMEDIATE)
{
rs2 = call->operands[1].value.immediate.value;
if(call->operands[1].value.immediate.negative)
rs2 = -rs2;
rs2 &= 0x00001fff;
rs2 |= (1 << 13);
}
else
return -1;
/* rd */
if(AO_GET_TYPE(instruction->op3) != AOT_REGISTER)
return -1;
name = call->operands[2].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;
}
static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction, static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode) ArchInstructionCall * call, uint32_t * opcode)
{ {