Signed-off-by: Michael Rolnik <mrol...@gmail.com> --- target-avr/Makefile.objs | 4 ++- target-avr/translate.c | 91 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 86 insertions(+), 9 deletions(-)
diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs index c503546..bbd2409 100644 --- a/target-avr/Makefile.objs +++ b/target-avr/Makefile.objs @@ -1,3 +1,5 @@ -obj-y += translate.o cpu.o helper.o +obj-y += translate.o helper.o cpu.o obj-y += gdbstub.o obj-$(CONFIG_SOFTMMU) += machine.o + +obj-y += decode.o diff --git a/target-avr/translate.c b/target-avr/translate.c index e98aaef..5a7436f 100644 --- a/target-avr/translate.c +++ b/target-avr/translate.c @@ -30,13 +30,32 @@ #include "exec/helper-gen.h" #include "exec/log.h" +uint32_t get_opcode( + uint8_t const *code, + unsigned bitBase, + unsigned bitSize); + typedef struct DisasContext DisasContext; typedef struct InstInfo InstInfo; +typedef int (*translate_function_t)( + CPUAVRState *env, + DisasContext *ctx, + uint8_t const *opcode); +struct InstInfo { + target_long cpc; + target_long npc; + uint32_t opcode; + translate_function_t translate; + unsigned length; +}; + /*This is the state at translation time. */ struct DisasContext { struct TranslationBlock *tb; + InstInfo inst[2]; /* two consequitive instructions */ + /*Routine used to access memory */ int memidx; int bstate; @@ -144,6 +163,55 @@ static inline void gen_goto_tb(CPUAVRState *env, } } +#include "translate.c.inc" + +typedef int (*translate_function_t)( + CPUAVRState *env, + DisasContext *ctx, + uint8_t const *opcode); +void avr_decode( + uint32_t pc, + uint32_t *length, + uint8_t const *code, + translate_function_t *translate); + + +static void decode_opc( + AVRCPU *cpu, + DisasContext *ctx, + InstInfo *inst) +{ + CPUAVRState *env = &cpu->env; + + inst->opcode = cpu_ldl_code(env, inst->cpc * 2); /* pc points to words */ + inst->length = 16; + inst->translate = NULL; + + /* the following function looks onto the opcode as a string of bytes */ + avr_decode(inst->cpc, &inst->length, (uint8_t const *)&inst->opcode, &inst->translate); + + if (inst->length == 16) { + inst->npc = inst->cpc + 1; + /* get opcode as 16bit value */ + inst->opcode = inst->opcode & 0x0000ffff; + } + if (inst->length == 32) { + inst->npc = inst->cpc + 2; + /* get opcode as 32bit value */ + inst->opcode = (inst->opcode << 16) + | (inst->opcode >> 16); + } +} + +uint32_t get_opcode( + uint8_t const *code, + unsigned bitBase, + unsigned bitSize) +{ + return *(uint16_t *)code; +} + + /*generate intermediate code for basic block 'tb'. */ void gen_intermediate_code( CPUAVRState *env, @@ -176,18 +244,21 @@ void gen_intermediate_code( gen_tb_start(tb); /* decode first instruction */ - cpc = pc_start; - npc = cpc + 1; + ctx.inst[0].cpc = pc_start; + decode_opc(cpu, &ctx, &ctx.inst[0]); do { - /* translate current instruction */ + /* set curr/next PCs */ + cpc = ctx.inst[0].cpc; + npc = ctx.inst[0].npc; + + /* decode next instruction */ + ctx.inst[1].cpc = ctx.inst[0].npc; + decode_opc(cpu, &ctx, &ctx.inst[1]); + + /* translate current instruction */ tcg_gen_insn_start(cpc); num_insns++; - /* just skip to next instruction */ - cpc++; - npc++; - ctx.bstate = BS_NONE; - if (unlikely(cpu_breakpoint_test(cs, cpc * 2, BP_ANY))) { tcg_gen_movi_i32(cpu_pc, cpc); gen_helper_debug(cpu_env); @@ -199,6 +270,8 @@ void gen_intermediate_code( goto done_generating; } + ctx.bstate = ctx.inst[0].translate(env, &ctx, (uint8_t const *)&ctx.inst[0].opcode); + if (num_insns >= max_insns) { break; /* max translated instructions limit reached */ } @@ -208,6 +281,8 @@ void gen_intermediate_code( if ((cpc & (TARGET_PAGE_SIZE - 1)) == 0) { break; /* page boundary */ } + + ctx.inst[0] = ctx.inst[1]; /* make next inst curr */ } while (ctx.bstate == BS_NONE && !tcg_op_buf_full()); if (tb->cflags & CF_LAST_IO) { -- 2.4.9 (Apple Git-60)