Skip to content

Commit

Permalink
target-rl78: Flesh out disas
Browse files Browse the repository at this point in the history
Signed-off-by: Andreas Färber <andreas.faerber@web.de>
  • Loading branch information
afaerber committed Aug 25, 2013
1 parent 7fef083 commit 172b411
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 0 deletions.
6 changes: 6 additions & 0 deletions target-78k0/cpu.c
Expand Up @@ -73,8 +73,14 @@ void cpu_78k0_list(FILE *f, fprintf_function cpu_fprintf)
static void rl78_cpu_initfn(Object *obj) static void rl78_cpu_initfn(Object *obj)
{ {
RL78CPU *cpu = RL78_CPU(obj); RL78CPU *cpu = RL78_CPU(obj);
static bool tcg_initialized = false;


cpu_exec_init(&cpu->env); cpu_exec_init(&cpu->env);

if (tcg_enabled() && !tcg_initialized) {
tcg_initialized = true;
cpu_rl78_translate_init();
}
} }


static void rl78_cpu_class_init(ObjectClass *oc, void *data) static void rl78_cpu_class_init(ObjectClass *oc, void *data)
Expand Down
2 changes: 2 additions & 0 deletions target-78k0/cpu.h
Expand Up @@ -91,6 +91,8 @@ static inline CPU78K0State *cpu_init(const char *cpu_model)
return &cpu->env; return &cpu->env;
} }


void cpu_rl78_translate_init(void);

int cpu_78k0_exec(CPU78K0State *env); int cpu_78k0_exec(CPU78K0State *env);
void rl78_cpu_do_interrupt(CPUState *cpu); void rl78_cpu_do_interrupt(CPUState *cpu);
void rl78_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void rl78_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
Expand Down
128 changes: 128 additions & 0 deletions target-78k0/translate.c
Expand Up @@ -23,10 +23,66 @@
#include "tcg-op.h" #include "tcg-op.h"
#include "qemu/log.h" #include "qemu/log.h"


/* global register indexes */
static TCGv_ptr cpu_env;

#include "helper.h" #include "helper.h"
#define GEN_HELPER 1 #define GEN_HELPER 1
#include "helper.h" #include "helper.h"


#include "exec/gen-icount.h"

//#define RL78_DEBUG_DISAS

#ifdef RL78_DEBUG_DISAS
# define LOG_DISAS(...) printf(__VA_ARGS__)
#else
# define LOG_DISAS(...) do { } while (0)
#endif

#define LOG_ASM(...) \
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { \
qemu_log(__VA_ARGS__); \
}

typedef struct DisasContext DisasContext;
struct DisasContext {
uint32_t pc;
int is_jmp;
struct TranslationBlock *tb;
};


void cpu_rl78_translate_init(void)
{
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");

#define GEN_HELPER 2
#include "helper.h"
}

typedef int (*OpcodeHandler)(RL78CPU *cpu, uint8_t opcode, DisasContext *s);

static const OpcodeHandler rl78_1st_map[256] = {
};

static void disas_rl78_insn(RL78CPU *cpu, DisasContext *s)
{
uint8_t opc;
int ins_len;

opc = cpu_ldub_code(&cpu->env, s->pc);

if (likely(rl78_1st_map[opc] != NULL)) {
ins_len = rl78_1st_map[opc](cpu, opc, s);
} else {
qemu_log("unimplemented opcode 0x%" PRIx8 "\n", opc);
// TODO
ins_len = 1;
}

s->pc += ins_len;
}


/* Generate intermediate code in gen_opc_buf and gen_opparam_buf for /* Generate intermediate code in gen_opc_buf and gen_opparam_buf for
basic block @tb. If @search_pc is %true, also generate PC basic block @tb. If @search_pc is %true, also generate PC
Expand All @@ -35,6 +91,78 @@ static inline void gen_intermediate_code_internal(RL78CPU *cpu,
TranslationBlock *tb, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
DisasContext dc;
target_ulong pc_start;
uint16_t *gen_opc_end;
int num_insns, max_insns;
CPUBreakpoint *bp;
int j, lj = -1;

pc_start = tb->pc;
pc_start &= 0x0fffff;
dc.pc = pc_start;
dc.is_jmp = DISAS_NEXT;
dc.tb = tb;

gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0) {
max_insns = CF_COUNT_MASK;
}

gen_tb_start();

do {
if (unlikely(!QTAILQ_EMPTY(&cpu->env.breakpoints))) {
QTAILQ_FOREACH(bp, &cpu->env.breakpoints, entry) {
if (bp->pc == dc.pc) {
// TODO
break;
}
}
}
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j) {
tcg_ctx.gen_opc_instr_start[lj++] = 0;
}
}
tcg_ctx.gen_opc_pc[lj] = dc.pc;
tcg_ctx.gen_opc_instr_start[lj] = 1;
tcg_ctx.gen_opc_icount[lj] = num_insns;
}

disas_rl78_insn(cpu, &dc);

num_insns++;
if (cs->singlestep_enabled) {
// TODO
}
} while (dc.is_jmp == DISAS_NEXT
&& tcg_ctx.gen_opc_ptr < gen_opc_end && num_insns < max_insns
&& !cs->singlestep_enabled && !singlestep);

/* Generate the return instruction */
if (dc.is_jmp != DISAS_TB_JUMP) {
tcg_gen_exit_tb(0);
}
gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j) {
tcg_ctx.gen_opc_instr_start[lj++] = 0;
}
} else {
tb->size = dc.pc - pc_start;
tb->icount = num_insns;
}
} }


void gen_intermediate_code(CPU78K0State *env, TranslationBlock *tb) void gen_intermediate_code(CPU78K0State *env, TranslationBlock *tb)
Expand Down

0 comments on commit 172b411

Please sign in to comment.