All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Huth <huth@tuxfamily.org>
To: qemu-devel@nongnu.org, "Michael Rolnik" <mrolnik@gmail.com>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	"Richard Henderson" <rth@twiddle.net>
Cc: Sarah Harris <S.E.Harris@kent.ac.uk>
Subject: [PATCH rc6 16/30] target/avr: Add instruction translation - CPU main translation function
Date: Sun,  5 Jul 2020 16:03:01 +0200	[thread overview]
Message-ID: <20200705140315.260514-17-huth@tuxfamily.org> (raw)
In-Reply-To: <20200705140315.260514-1-huth@tuxfamily.org>

From: Michael Rolnik <mrolnik@gmail.com>

Add the core of translation mechanism.

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>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <aleksandar.m.mail@gmail.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Aleksandar Markovic <aleksandar.m.mail@gmail.com>
Signed-off-by: Thomas Huth <huth@tuxfamily.org>
---
 target/avr/translate.c | 214 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 214 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 806a0f4e78..a6e67488df 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2815,3 +2815,217 @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
 
     return true;
 }
+
+
+/*
+ *  Core translation mechanism functions:
+ *
+ *    - translate()
+ *    - canonicalize_skip()
+ *    - gen_intermediate_code()
+ *    - restore_state_to_opc()
+ *
+ */
+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.26.2



  parent reply	other threads:[~2020-07-05 14:10 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-05 14:02 [PATCH rc6 00/30] target/avr merger Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 01/30] target/avr: Add basic parameters of the new platform Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 02/30] target/avr: Introduce basic CPU class object Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 03/30] target/avr: CPU class: Add interrupt handling support Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 04/30] target/avr: CPU class: Add memory menagement support Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 05/30] target/avr: CPU class: Add migration support Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 06/30] target/avr: CPU class: Add GDB support Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 07/30] target/avr: Introduce enumeration AVRFeature Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 08/30] target/avr: Add defintions of AVR core types Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 09/30] target/avr: Add instruction helpers Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 10/30] target/avr: Add instruction translation - Register definitions Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 11/30] target/avr: Add instruction translation - Arithmetic and Logic Instructions Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 12/30] target/avr: Add instruction translation - Branch Instructions Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 13/30] target/avr: Add instruction translation - Data Transfer Instructions Thomas Huth
2020-07-05 14:02 ` [PATCH rc6 14/30] target/avr: Add instruction translation - Bit and Bit-test Instructions Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 15/30] target/avr: Add instruction translation - MCU Control Instructions Thomas Huth
2020-07-05 14:03 ` Thomas Huth [this message]
2020-07-05 14:03 ` [PATCH rc6 17/30] target/avr: Initialize TCG register variables Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 18/30] target/avr: Add support for disassembling via option '-d in_asm' Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 19/30] hw/char: avr: Add limited support for USART peripheral Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 20/30] hw/timer: avr: Add limited support for 16-bit timer peripheral Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 21/30] hw/misc: avr: Add limited support for power reduction device Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 22/30] target/avr: Register AVR support with the rest of QEMU Thomas Huth
2020-07-06 14:56   ` Eric Blake
2020-07-06 16:36     ` Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 23/30] hw/avr: Add support for loading ELF/raw binaries Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 24/30] hw/avr: Add some ATmega microcontrollers Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 25/30] hw/avr: Add limited support for some Arduino boards Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 26/30] target/avr: Update build system Thomas Huth
2020-07-05 21:30   ` Philippe Mathieu-Daudé
2020-07-05 14:03 ` [PATCH rc6 27/30] tests/machine-none: Add AVR support Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 28/30] tests/boot-serial: Test some Arduino boards (AVR based) Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 29/30] tests/acceptance: Test the Arduino MEGA2560 board Thomas Huth
2020-07-05 14:03 ` [PATCH rc6 30/30] target/avr: Add section into QEMU documentation Thomas Huth
2020-07-05 14:29 ` [PATCH rc6 00/30] target/avr merger no-reply
2020-07-05 18:30   ` Thomas Huth
2020-07-05 18:42     ` Peter Maydell
2020-07-07 17:57 ` Philippe Mathieu-Daudé

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=20200705140315.260514-17-huth@tuxfamily.org \
    --to=huth@tuxfamily.org \
    --cc=S.E.Harris@kent.ac.uk \
    --cc=f4bug@amsat.org \
    --cc=mrolnik@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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.