All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Rolnik <mrolnik@gmail.com>
To: qemu-devel@nongnu.org
Cc: thuth@redhat.com, Michael Rolnik <mrolnik@gmail.com>,
	me@xcancerberox.com.ar, richard.henderson@linaro.org,
	dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com,
	aleksandar.m.mail@gmail.com
Subject: [PATCH v37 09/17] target/avr: Add instruction translation - CPU main translation function
Date: Wed, 27 Nov 2019 19:52:49 +0200	[thread overview]
Message-ID: <20191127175257.23480-10-mrolnik@gmail.com> (raw)
In-Reply-To: <20191127175257.23480-1-mrolnik@gmail.com>

Co-developed-by: Richard Henderson <richard.henderson@linaro.org>
Co-developed-by: Michael Rolnik <mrolnik@gmail.com>

Signed-off-by: Michael Rolnik <mrolnik@gmail.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 target/avr/translate.c | 234 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 234 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 54b384f00b..941db8e168 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2805,3 +2805,237 @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
 
     return true;
 }
+
+
+void avr_cpu_tcg_init(void)
+{
+    int i;
+
+#define AVR_REG_OFFS(x) offsetof(CPUAVRState, x)
+    cpu_pc = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(pc_w), "pc");
+    cpu_Cf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregC), "Cf");
+    cpu_Zf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregZ), "Zf");
+    cpu_Nf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregN), "Nf");
+    cpu_Vf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregV), "Vf");
+    cpu_Sf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregS), "Sf");
+    cpu_Hf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregH), "Hf");
+    cpu_Tf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregT), "Tf");
+    cpu_If = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregI), "If");
+    cpu_rampD = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampD), "rampD");
+    cpu_rampX = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampX), "rampX");
+    cpu_rampY = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampY), "rampY");
+    cpu_rampZ = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampZ), "rampZ");
+    cpu_eind = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(eind), "eind");
+    cpu_sp = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sp), "sp");
+    cpu_skip = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(skip), "skip");
+
+    for (i = 0; i < NUMBER_OF_CPU_REGISTERS; i++) {
+        cpu_r[i] = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(r[i]),
+                                          reg_names[i]);
+    }
+#undef AVR_REG_OFFS
+}
+
+static void translate(DisasContext *ctx)
+{
+    uint32_t opcode = next_word(ctx);
+
+    if (!decode_insn(ctx, opcode)) {
+        gen_helper_unsupported(cpu_env);
+        ctx->bstate = DISAS_NORETURN;
+    }
+}
+
+/* Standardize the cpu_skip condition to NE.  */
+static bool canonicalize_skip(DisasContext *ctx)
+{
+    switch (ctx->skip_cond) {
+    case TCG_COND_NEVER:
+        /* Normal case: cpu_skip is known to be false.  */
+        return false;
+
+    case TCG_COND_ALWAYS:
+        /*
+         * Breakpoint case: cpu_skip is known to be true, via TB_FLAGS_SKIP.
+         * The breakpoint is on the instruction being skipped, at the start
+         * of the TranslationBlock.  No need to update.
+         */
+        return false;
+
+    case TCG_COND_NE:
+        if (ctx->skip_var1 == NULL) {
+            tcg_gen_mov_tl(cpu_skip, ctx->skip_var0);
+        } else {
+            tcg_gen_xor_tl(cpu_skip, ctx->skip_var0, ctx->skip_var1);
+            ctx->skip_var1 = NULL;
+        }
+        break;
+
+    default:
+        /* Convert to a NE condition vs 0. */
+        if (ctx->skip_var1 == NULL) {
+            tcg_gen_setcondi_tl(ctx->skip_cond, cpu_skip, ctx->skip_var0, 0);
+        } else {
+            tcg_gen_setcond_tl(ctx->skip_cond, cpu_skip,
+                               ctx->skip_var0, ctx->skip_var1);
+            ctx->skip_var1 = NULL;
+        }
+        ctx->skip_cond = TCG_COND_NE;
+        break;
+    }
+    if (ctx->free_skip_var0) {
+        tcg_temp_free(ctx->skip_var0);
+        ctx->free_skip_var0 = false;
+    }
+    ctx->skip_var0 = cpu_skip;
+    return true;
+}
+
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+{
+    CPUAVRState *env = cs->env_ptr;
+    DisasContext ctx = {
+        .tb = tb,
+        .cs = cs,
+        .env = env,
+        .memidx = 0,
+        .bstate = DISAS_NEXT,
+        .skip_cond = TCG_COND_NEVER,
+        .singlestep = cs->singlestep_enabled,
+    };
+    target_ulong pc_start = tb->pc / 2;
+    int num_insns = 0;
+
+    if (tb->flags & TB_FLAGS_FULL_ACCESS) {
+        /*
+         * This flag is set by ST/LD instruction we will regenerate it ONLY
+         * with mem/cpu memory access instead of mem access
+         */
+        max_insns = 1;
+    }
+    if (ctx.singlestep) {
+        max_insns = 1;
+    }
+
+    gen_tb_start(tb);
+
+    ctx.npc = pc_start;
+    if (tb->flags & TB_FLAGS_SKIP) {
+        ctx.skip_cond = TCG_COND_ALWAYS;
+        ctx.skip_var0 = cpu_skip;
+    }
+
+    do {
+        TCGLabel *skip_label = NULL;
+
+        /* translate current instruction */
+        tcg_gen_insn_start(ctx.npc);
+        num_insns++;
+
+        /*
+         * this is due to some strange GDB behavior
+         * let's assume main has address 0x100
+         * b main   - sets breakpoint at address 0x00000100 (code)
+         * b *0x100 - sets breakpoint at address 0x00800100 (data)
+         */
+        if (unlikely(!ctx.singlestep &&
+                (cpu_breakpoint_test(cs, OFFSET_CODE + ctx.npc * 2, BP_ANY) ||
+                 cpu_breakpoint_test(cs, OFFSET_DATA + ctx.npc * 2, BP_ANY)))) {
+            canonicalize_skip(&ctx);
+            tcg_gen_movi_tl(cpu_pc, ctx.npc);
+            gen_helper_debug(cpu_env);
+            goto done_generating;
+        }
+
+        /* Conditionally skip the next instruction, if indicated.  */
+        if (ctx.skip_cond != TCG_COND_NEVER) {
+            skip_label = gen_new_label();
+            if (ctx.skip_var0 == cpu_skip) {
+                /*
+                 * Copy cpu_skip so that we may zero it before the branch.
+                 * This ensures that cpu_skip is non-zero after the label
+                 * if and only if the skipped insn itself sets a skip.
+                 */
+                ctx.free_skip_var0 = true;
+                ctx.skip_var0 = tcg_temp_new();
+                tcg_gen_mov_tl(ctx.skip_var0, cpu_skip);
+                tcg_gen_movi_tl(cpu_skip, 0);
+            }
+            if (ctx.skip_var1 == NULL) {
+                tcg_gen_brcondi_tl(ctx.skip_cond, ctx.skip_var0, 0, skip_label);
+            } else {
+                tcg_gen_brcond_tl(ctx.skip_cond, ctx.skip_var0,
+                                  ctx.skip_var1, skip_label);
+                ctx.skip_var1 = NULL;
+            }
+            if (ctx.free_skip_var0) {
+                tcg_temp_free(ctx.skip_var0);
+                ctx.free_skip_var0 = false;
+            }
+            ctx.skip_cond = TCG_COND_NEVER;
+            ctx.skip_var0 = NULL;
+        }
+
+        translate(&ctx);
+
+        if (skip_label) {
+            canonicalize_skip(&ctx);
+            gen_set_label(skip_label);
+            if (ctx.bstate == DISAS_NORETURN) {
+                ctx.bstate = DISAS_CHAIN;
+            }
+        }
+    } while (ctx.bstate == DISAS_NEXT
+             && num_insns < max_insns
+             && (ctx.npc - pc_start) * 2 < TARGET_PAGE_SIZE - 4
+             && !tcg_op_buf_full());
+
+    if (tb->cflags & CF_LAST_IO) {
+        gen_io_end();
+    }
+
+    bool nonconst_skip = canonicalize_skip(&ctx);
+
+    switch (ctx.bstate) {
+    case DISAS_NORETURN:
+        assert(!nonconst_skip);
+        break;
+    case DISAS_NEXT:
+    case DISAS_TOO_MANY:
+    case DISAS_CHAIN:
+        if (!nonconst_skip) {
+            /* Note gen_goto_tb checks singlestep.  */
+            gen_goto_tb(&ctx, 1, ctx.npc);
+            break;
+        }
+        tcg_gen_movi_tl(cpu_pc, ctx.npc);
+        /* fall through */
+    case DISAS_LOOKUP:
+        if (!ctx.singlestep) {
+            tcg_gen_lookup_and_goto_ptr();
+            break;
+        }
+        /* fall through */
+    case DISAS_EXIT:
+        if (ctx.singlestep) {
+            gen_helper_debug(cpu_env);
+        } else {
+            tcg_gen_exit_tb(NULL, 0);
+        }
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+done_generating:
+    gen_tb_end(tb, num_insns);
+
+    tb->size = (ctx.npc - pc_start) * 2;
+    tb->icount = num_insns;
+}
+
+void restore_state_to_opc(CPUAVRState *env, TranslationBlock *tb,
+                            target_ulong *data)
+{
+    env->pc_w = data[0];
+}
-- 
2.17.2 (Apple Git-113)



  parent reply	other threads:[~2019-11-27 18:14 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-27 17:52 [PATCH v37 00/17] QEMU AVR 8 bit cores Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 01/17] target/avr: Add outward facing interfaces and core CPU logic Michael Rolnik
2019-11-27 22:25   ` Philippe Mathieu-Daudé
2019-11-28 12:04     ` Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 02/17] target/avr: Add instruction helpers Michael Rolnik
2019-11-27 22:26   ` Philippe Mathieu-Daudé
2019-11-27 17:52 ` [PATCH v37 03/17] target/avr: Add instruction decoding Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 04/17] target/avr: Add instruction translation - Registers definition Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 05/17] target/avr: Add instruction translation - Arithmetic and Logic Instructions Michael Rolnik
2019-11-30 10:33   ` Aleksandar Markovic
2019-11-30 16:29     ` Aleksandar Markovic
2019-11-30 17:05       ` Michael Rolnik
2019-11-30 17:14         ` Aleksandar Markovic
2019-11-30 23:11         ` Aleksandar Markovic
2019-12-02  7:41           ` Michael Rolnik
2019-12-02  8:55             ` Aleksandar Markovic
2019-12-02  9:01               ` Aleksandar Markovic
2019-11-27 17:52 ` [PATCH v37 06/17] target/avr: Add instruction translation - Branch Instructions Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 07/17] target/avr: Add instruction translation - Bit and Bit-test Instructions Michael Rolnik
2019-12-05 12:28   ` Aleksandar Markovic
2019-12-05 13:17     ` Michael Rolnik
2019-12-05 13:28       ` Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 08/17] target/avr: Add instruction translation - MCU Control Instructions Michael Rolnik
2019-11-27 17:52 ` Michael Rolnik [this message]
2019-11-27 17:52 ` [PATCH v37 10/17] target/avr: Add instruction disassembly function Michael Rolnik
2019-12-02  0:28   ` Aleksandar Markovic
2019-12-02  7:04     ` Michael Rolnik
2019-12-02 10:12       ` Aleksandar Markovic
2019-12-02 12:01       ` Aleksandar Markovic
2019-12-03 11:18       ` Philippe Mathieu-Daudé
2019-12-03 14:24         ` Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 11/17] target/avr: Add limited support for USART and 16 bit timer peripherals Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 12/17] target/avr: Add example board configuration Michael Rolnik
2019-11-30 10:49   ` Aleksandar Markovic
2019-11-30 16:57     ` Michael Rolnik
2019-12-03 11:29       ` Philippe Mathieu-Daudé
2019-11-27 17:52 ` [PATCH v37 13/17] target/avr: Register AVR support with the rest of QEMU Michael Rolnik
2019-12-05 12:55   ` Aleksandar Markovic
2019-11-27 17:52 ` [PATCH v37 14/17] target/avr: Update build system Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 15/17] target/avr: Add boot serial test Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 16/17] target/avr: Add Avocado test Michael Rolnik
2019-11-27 17:52 ` [PATCH v37 17/17] target/avr: Update MAINTAINERS file Michael Rolnik
2019-11-28 20:19   ` Philippe Mathieu-Daudé
2019-11-30 13:43   ` Aleksandar Markovic
2019-11-27 21:06 ` [PATCH v37 00/17] QEMU AVR 8 bit cores Aleksandar Markovic
2019-11-28 12:28   ` Michael Rolnik
2019-11-28 13:22     ` Aleksandar Markovic
2019-11-28 13:25       ` Michael Rolnik
2019-11-28 13:31         ` Aleksandar Markovic
2019-11-28 16:20           ` Alex Bennée
2019-11-28 19:32             ` Aleksandar Markovic
2019-11-29 22:49             ` Aleksandar Markovic
2019-11-29 23:52               ` Aleksandar Markovic
2019-11-28 13:34         ` Philippe Mathieu-Daudé
2019-11-28 13:41           ` Aleksandar Markovic
2019-11-28 13:46             ` Michael Rolnik
2019-11-28 14:16               ` Philippe Mathieu-Daudé
2019-11-28 14:50                 ` Aleksandar Markovic
2019-11-28 18:09                 ` Aleksandar Markovic
2019-12-01 13:09               ` Aleksandar Markovic
2019-12-01 13:11                 ` Aleksandar Markovic
2019-11-29  9:24     ` Sarah Harris
2019-11-28 15:00 ` Aleksandar Markovic
2019-11-30 11:28 ` Aleksandar Markovic
2019-11-30 17:00   ` Michael Rolnik
2019-12-02  9:35     ` Aleksandar Markovic
2019-12-02  9:59       ` Aleksandar Markovic
2019-12-02 13:24         ` Michael Rolnik
2019-12-02 14:01           ` Aleksandar Markovic
2019-12-02 16:09             ` Michael Rolnik
2019-12-02 21:15               ` Aleksandar Markovic
2019-12-02 23:37                 ` Aleksandar Markovic
2019-12-03  1:17                   ` Aleksandar Markovic
2019-12-03  1:48                     ` Aleksandar Markovic
2019-12-03  9:56                       ` Michael Rolnik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191127175257.23480-10-mrolnik@gmail.com \
    --to=mrolnik@gmail.com \
    --cc=aleksandar.m.mail@gmail.com \
    --cc=dovgaluk@ispras.ru \
    --cc=imammedo@redhat.com \
    --cc=me@xcancerberox.com.ar \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.