diff --git a/src/arch/sparc.c b/src/arch/sparc.c index 762213d..f66c2bb 100644 --- a/src/arch/sparc.c +++ b/src/arch/sparc.c @@ -63,6 +63,8 @@ ArchPlugin arch_plugin = /* functions */ /* plug-in */ /* sparc_write */ +static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode); static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction, ArchInstructionCall * call, uint32_t * opcode); 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, instruction, call, &opcode) != 0) return -1; + else if((opcode & 0xc0000000) == 0x80000000 && _write_integer(plugin, + instruction, call, &opcode) != 0) + return -1; /* FIXME implement the rest */ opcode = _htob32(opcode); if(fwrite(&opcode, sizeof(opcode), 1, plugin->helper->fp) != 1) @@ -86,6 +91,55 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, 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, ArchInstructionCall * call, uint32_t * opcode) {