Permalink
Browse files

target-rl78: Flesh out disas

Signed-off-by: Andreas Färber <andreas.faerber@web.de>
  • Loading branch information...
1 parent 7fef083 commit 172b411257cfb58cfe2131d6c453e06fcf856942 @afaerber committed Nov 12, 2011
Showing with 136 additions and 0 deletions.
  1. +6 −0 target-78k0/cpu.c
  2. +2 −0 target-78k0/cpu.h
  3. +128 −0 target-78k0/translate.c
View
@@ -73,8 +73,14 @@ void cpu_78k0_list(FILE *f, fprintf_function cpu_fprintf)
static void rl78_cpu_initfn(Object *obj)
{
RL78CPU *cpu = RL78_CPU(obj);
+ static bool tcg_initialized = false;
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)
View
@@ -91,6 +91,8 @@ static inline CPU78K0State *cpu_init(const char *cpu_model)
return &cpu->env;
}
+void cpu_rl78_translate_init(void);
+
int cpu_78k0_exec(CPU78K0State *env);
void rl78_cpu_do_interrupt(CPUState *cpu);
void rl78_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
@@ -23,10 +23,66 @@
#include "tcg-op.h"
#include "qemu/log.h"
+/* global register indexes */
+static TCGv_ptr cpu_env;
+
#include "helper.h"
#define GEN_HELPER 1
#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
basic block @tb. If @search_pc is %true, also generate PC
@@ -35,6 +91,78 @@ static inline void gen_intermediate_code_internal(RL78CPU *cpu,
TranslationBlock *tb,
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)

0 comments on commit 172b411

Please sign in to comment.