diff --git a/src/arch/sparc.c b/src/arch/sparc.c index f66c2bb..0eca75f 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_branch(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode); static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction, ArchInstructionCall * call, uint32_t * opcode); static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction, @@ -75,22 +77,49 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, { uint32_t opcode = instruction->opcode; - if((opcode & 0xc0000000) == 0xc0000000 && _write_loadstore(plugin, - instruction, call, &opcode) != 0) + if((opcode & 0xc0000000) == 0xc0000000) + { + if(_write_loadstore(plugin, instruction, call, &opcode) != 0) + return -1; + } + else if((opcode & 0xc1c00000) == 0x01000000) + { + if(_write_sethi(plugin, instruction, call, &opcode) != 0) + return -1; + } + else if((opcode & 0xc0000000) == 0x80000000) + { + if(_write_integer(plugin, instruction, call, &opcode) != 0) + return -1; + } + else if((opcode & 0xc1c00000) == 0x00800000) + { + if(_write_branch(plugin, instruction, call, &opcode) != 0) + return -1; + } + else return -1; - 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) return -1; return 0; } +static int _write_branch(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode) +{ + uint32_t disp; + + if(AO_GET_TYPE(instruction->op1) != AOT_IMMEDIATE) + return -1; + disp = call->operands[0].value.immediate.value; + if(call->operands[0].value.immediate.negative) + disp = -disp; + disp &= (0x003fffff); + *opcode |= disp; + return 0; +} + static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction, ArchInstructionCall * call, uint32_t * opcode) { diff --git a/test/sparc.S b/test/sparc.S index c657abc..e8cfec6 100644 --- a/test/sparc.S +++ b/test/sparc.S @@ -22,7 +22,7 @@ bge $0x3 bl $0x3 ble $0x3 - bne $0x3 + bne $0x3 /* 0x12800003 */ bz $0x3 ld [%r4 + %r7], %r11 ld [%r23], %r19