From ff1bd3b6572e08c14940be369b01a90f7e09a71e Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Mon, 28 Nov 2011 02:22:48 +0000 Subject: [PATCH] Better encoding and decoding of Yasep instructions --- src/arch/yasep.c | 42 ++++++++++++++++++++++++++++++++++++++---- src/arch/yasep.ins | 4 ++-- test/yasep.S | 4 ++-- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/arch/yasep.c b/src/arch/yasep.c index 1a0986b..3ea5a67 100644 --- a/src/arch/yasep.c +++ b/src/arch/yasep.c @@ -83,11 +83,28 @@ static int _encode_16(ArchPlugin * plugin, ArchInstruction * instruction, ArchInstructionCall * call) { ArchPluginHelper * helper = plugin->helper; - uint16_t opcode = instruction->opcode; + uint16_t u16 = instruction->opcode; + ArchRegister * ar; + size_t size; + char const * name; - opcode = _htob16(opcode); - if(helper->write(helper->arch, &opcode, sizeof(opcode)) - != sizeof(opcode)) + if((instruction->opcode & 0x03) == 0x0) /* RR */ + { + name = call->operands[0].value._register.name; + size = AO_GET_SIZE(instruction->op1); + if((ar = helper->get_register_by_name_size(helper->arch, name, + size)) == NULL) + return -1; + u16 |= ar->id << 12; + name = call->operands[1].value._register.name; + size = AO_GET_SIZE(instruction->op2); + if((ar = helper->get_register_by_name_size(helper->arch, name, + size)) == NULL) + return -1; + u16 |= ar->id << 8; + } + u16 = _htob16(u16); + if(helper->write(helper->arch, &u16, sizeof(u16)) != sizeof(u16)) return -1; return 0; } @@ -113,6 +130,7 @@ static int _yasep_decode(ArchPlugin * plugin, ArchInstructionCall * call) uint16_t u16; uint16_t opcode; ArchInstruction * ai; + ArchRegister * ar; if(helper->read(helper->arch, &u16, sizeof(u16)) != sizeof(u16)) return -1; @@ -122,5 +140,21 @@ static int _yasep_decode(ArchPlugin * plugin, ArchInstructionCall * call) == NULL) return -1; call->name = ai->name; + if((opcode & 0x3) == 0x0) /* RR */ + { + call->operands[0].definition = ai->op1; + if((ar = helper->get_register_by_id_size(helper->arch, + ((u16 & 0xf000) >> 12) & 0xf, + AO_GET_SIZE(ai->op1))) == NULL) + return -1; + call->operands[0].value._register.name = ar->name; + call->operands[1].definition = ai->op2; + if((ar = helper->get_register_by_id_size(helper->arch, + ((u16 & 0x0f00) >> 8) & 0xf, + AO_GET_SIZE(ai->op2))) == NULL) + return -1; + call->operands[1].value._register.name = ar->name; + call->operands_cnt = 2; + } return 0; } diff --git a/src/arch/yasep.ins b/src/arch/yasep.ins index 89f32e8..0602969 100644 --- a/src/arch/yasep.ins +++ b/src/arch/yasep.ins @@ -17,8 +17,8 @@ /* generic */ /* opcode */ -#define OPIR(opcode) (opcode << 2) -#define OPRR(opcode) ((opcode << 2) | 0x2) +#define OPIR(opcode) ((opcode << 2) | 0x2) +#define OPRR(opcode) (opcode << 2) #define OPIRL(opcode) ((opcode << 2) | 0x1) #define OPRRL(opcode) ((opcode << 2) | 0x3) /* flags */ diff --git a/test/yasep.S b/test/yasep.S index 2a4ce35..ea8c336 100644 --- a/test/yasep.S +++ b/test/yasep.S @@ -1,8 +1,8 @@ /* $Id$ */ .text add %r0, %r1 - and %r0, %r1 - andn %r0, %r1 + and %r2, %r3 + andn %r4, %r5 cmps %r0, %r1 cmpu %r0, %r1 get %r0, %r1