qemu-devel.nongnu.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).