From patchwork Sat Dec 24 11:40:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 708652 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tm3Px22sRz9t0G for ; Sat, 24 Dec 2016 22:46:45 +1100 (AEDT) Received: from localhost ([::1]:43149 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cKkmh-000405-6R for incoming@patchwork.ozlabs.org; Sat, 24 Dec 2016 06:46:43 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45423) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cKkh5-0007Ra-Rj for qemu-devel@nongnu.org; Sat, 24 Dec 2016 06:40:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cKkh2-000833-Mn for qemu-devel@nongnu.org; Sat, 24 Dec 2016 06:40:55 -0500 Received: from mout.kundenserver.de ([217.72.192.73]:50359) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cKkh2-00081e-9k for qemu-devel@nongnu.org; Sat, 24 Dec 2016 06:40:52 -0500 Received: from Quad.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue102 [212.227.15.183]) with ESMTPSA (Nemesis) id 0MDPKv-1cM8Fv3upR-00GosD; Sat, 24 Dec 2016 12:40:39 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Sat, 24 Dec 2016 12:40:22 +0100 Message-Id: <1482579633-3393-2-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1482579633-3393-1-git-send-email-laurent@vivier.eu> References: <1482579633-3393-1-git-send-email-laurent@vivier.eu> X-Provags-ID: V03:K0:997io6tf+zL5CF2aC2v7rcSK7tODRCu35nKltpyEkEdS5B0q+QW kAaToVmFDXg3hOqFJi61vMf0Mwq7TWc2RURFJQcEDfq9+g8C18c7/O3x4FkBFgd1PgQ/1Hd BgEbx6yjW+t3PAU6IK1jZJ3O11O3hofKrDfUVP0TmabI0TMISlJWsEZbT3GSQ+b0Jn7UdXS uNJKLWSUTnJnBmFz23OoA== X-UI-Out-Filterresults: notjunk:1; V01:K0:OhS1eiKvRkg=:IYGgET8xXu39XLSWygY2Ic ksrwuy/6UGG0XJ8rIzOQACKPAXf17zDSU1gHzhTGqYBnHdBVbn7AUJGa9SRRRB7kjaSr8WC9B YBlVXbTcp3Xo8U3klLGRgjgFYXoyaFCHcc9SVJrY4LiSEbn9B4+kzCBEK3wEhpCsaScXTfWrO klo36vnaRSshnL+30WQCadGbrYgd0fRTv38eoAiWPFQC3ynoMD24ZQr7kKpaaTZpJnsikFrNj UUuESFHbaeKW5XD1oVVrQ4CMRDlpKiOEL6VDIwXYWz6rY8gaGtEjW8a+F5y2QlFoNuS5vXw0O iLwtjBv+Is254SXev0Dnomrc+h2BV8/Pz8db8x1yyCG+axyVQnLkpbT0+m+Ij5uzjkhi7+dMC d9OObIdr/T1y+VuEGdyRpxmzWV5NzbJQKPy4r8Y5Ui4ETOBjU6OEV+MoYHCiVTH7DPOYL31nU yxikOKys6yQjQZrzIV+OH2oHaGKP7G0+nQvD5N8QKLbfl+Ury/u2xL7NDJjFlR3Zmcb67x2c6 LwpDpWvTDEpamNaCEw5qsMhOGThx2mMLqDTDoApJ9IHzQBPzsVDzh8IRAAQoaaAL874c6h46P IIZJV4/FtNpUr59f3B74bCJpCLv8K9tsrLnCe02IoiY1QksyR5DB4R9LLz3IRqjos9Wm97ZrJ KhLkv1Zg5pvs57nHecai7cWcEM/1BJUTmy6ebsV8IA1zJaEa41wW6Ux/MT9pH99SEDmQ= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 217.72.192.73 Subject: [Qemu-devel] [PULL 01/12] target-m68k: Delay autoinc writeback X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Signed-off-by: Richard Henderson Message-Id: <1478206203-4606-2-git-send-email-rth@twiddle.net> --- target/m68k/translate.c | 84 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 20 deletions(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index d6ed883..a9066dc 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -59,12 +59,12 @@ static TCGv cpu_aregs[8]; static TCGv_i64 cpu_fregs[8]; static TCGv_i64 cpu_macc[4]; -#define REG(insn, pos) (((insn) >> (pos)) & 7) +#define REG(insn, pos) (((insn) >> (pos)) & 7) #define DREG(insn, pos) cpu_dregs[REG(insn, pos)] -#define AREG(insn, pos) cpu_aregs[REG(insn, pos)] +#define AREG(insn, pos) get_areg(s, REG(insn, pos)) #define FREG(insn, pos) cpu_fregs[REG(insn, pos)] -#define MACREG(acc) cpu_macc[acc] -#define QREG_SP cpu_aregs[7] +#define MACREG(acc) cpu_macc[acc] +#define QREG_SP get_areg(s, 7) static TCGv NULL_QREG; #define IS_NULL_QREG(t) (TCGV_EQUAL(t, NULL_QREG)) @@ -141,8 +141,55 @@ typedef struct DisasContext { int singlestep_enabled; TCGv_i64 mactmp; int done_mac; + int writeback_mask; + TCGv writeback[8]; } DisasContext; +static TCGv get_areg(DisasContext *s, unsigned regno) +{ + if (s->writeback_mask & (1 << regno)) { + return s->writeback[regno]; + } else { + return cpu_aregs[regno]; + } +} + +static void delay_set_areg(DisasContext *s, unsigned regno, + TCGv val, bool give_temp) +{ + if (s->writeback_mask & (1 << regno)) { + if (give_temp) { + tcg_temp_free(s->writeback[regno]); + s->writeback[regno] = val; + } else { + tcg_gen_mov_i32(s->writeback[regno], val); + } + } else { + s->writeback_mask |= 1 << regno; + if (give_temp) { + s->writeback[regno] = val; + } else { + TCGv tmp = tcg_temp_new(); + s->writeback[regno] = tmp; + tcg_gen_mov_i32(tmp, val); + } + } +} + +static void do_writebacks(DisasContext *s) +{ + unsigned mask = s->writeback_mask; + if (mask) { + s->writeback_mask = 0; + do { + unsigned regno = ctz32(mask); + tcg_gen_mov_i32(cpu_aregs[regno], s->writeback[regno]); + tcg_temp_free(s->writeback[regno]); + mask &= mask - 1; + } while (mask); + } +} + #define DISAS_JUMP_NEXT 4 #if defined(CONFIG_USER_ONLY) @@ -331,7 +378,7 @@ static inline uint32_t read_im32(CPUM68KState *env, DisasContext *s) } /* Calculate and address index. */ -static TCGv gen_addr_index(uint16_t ext, TCGv tmp) +static TCGv gen_addr_index(DisasContext *s, uint16_t ext, TCGv tmp) { TCGv add; int scale; @@ -388,7 +435,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) tmp = tcg_temp_new(); if ((ext & 0x44) == 0) { /* pre-index */ - add = gen_addr_index(ext, tmp); + add = gen_addr_index(s, ext, tmp); } else { add = NULL_QREG; } @@ -417,7 +464,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) /* memory indirect */ base = gen_load(s, OS_LONG, add, 0); if ((ext & 0x44) == 4) { - add = gen_addr_index(ext, tmp); + add = gen_addr_index(s, ext, tmp); tcg_gen_add_i32(tmp, add, base); add = tmp; } else { @@ -441,7 +488,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) } else { /* brief extension word format */ tmp = tcg_temp_new(); - add = gen_addr_index(ext, tmp); + add = gen_addr_index(s, ext, tmp); if (!IS_NULL_QREG(base)) { tcg_gen_add_i32(tmp, add, base); if ((int8_t)ext) @@ -755,10 +802,11 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, case 3: /* Indirect postincrement. */ reg = AREG(insn, 0); result = gen_ldst(s, opsize, reg, val, what); - /* ??? This is not exception safe. The instruction may still - fault after this point. */ - if (what == EA_STORE || !addrp) - tcg_gen_addi_i32(reg, reg, opsize_bytes(opsize)); + if (what == EA_STORE || !addrp) { + TCGv tmp = tcg_temp_new(); + tcg_gen_addi_i32(tmp, reg, opsize_bytes(opsize)); + delay_set_areg(s, REG(insn, 0), tmp, true); + } return result; case 4: /* Indirect predecrememnt. */ { @@ -773,11 +821,8 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, *addrp = tmp; } result = gen_ldst(s, opsize, tmp, val, what); - /* ??? This is not exception safe. The instruction may still - fault after this point. */ if (what == EA_STORE || !addrp) { - reg = AREG(insn, 0); - tcg_gen_mov_i32(reg, tmp); + delay_set_areg(s, REG(insn, 0), tmp, false); } } return result; @@ -3446,11 +3491,9 @@ void register_m68k_insns (CPUM68KState *env) write back the result to memory before setting the condition codes. */ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s) { - uint16_t insn; - - insn = read_im16(env, s); - + uint16_t insn = read_im16(env, s); opcode_table[insn](env, s, insn); + do_writebacks(s); } /* generate intermediate code for basic block 'tb'. */ @@ -3478,6 +3521,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) dc->fpcr = env->fpcr; dc->user = (env->sr & SR_S) == 0; dc->done_mac = 0; + dc->writeback_mask = 0; num_insns = 0; max_insns = tb->cflags & CF_COUNT_MASK; if (max_insns == 0) {