From 9b692011ca3022b94d1452bffc774f611c1fa46a Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Thu, 21 Apr 2011 16:16:07 +0000 Subject: [PATCH] Encoding "load and store" instructions much better already --- src/arch/sparc.c | 103 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 6 deletions(-) diff --git a/src/arch/sparc.c b/src/arch/sparc.c index 990164e..059dd81 100644 --- a/src/arch/sparc.c +++ b/src/arch/sparc.c @@ -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; +}