From patchwork Tue Oct 29 19:04:43 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Macke X-Patchwork-Id: 287026 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 538942C0366 for ; Wed, 30 Oct 2013 06:06:19 +1100 (EST) Received: from localhost ([::1]:48891 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VbEcK-0003vu-8j for incoming@patchwork.ozlabs.org; Tue, 29 Oct 2013 15:06:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34050) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VbEbc-0003te-Om for qemu-devel@nongnu.org; Tue, 29 Oct 2013 15:05:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VbEbU-0005Pv-QQ for qemu-devel@nongnu.org; Tue, 29 Oct 2013 15:05:32 -0400 Received: from www11.your-server.de ([213.133.104.11]:59954) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VbEbU-0005PF-Gw for qemu-devel@nongnu.org; Tue, 29 Oct 2013 15:05:24 -0400 Received: from [142.103.140.43] (helo=openrisc-VirtualBox.phas.ubc.ca) by www11.your-server.de with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.74) (envelope-from ) id 1VbEbO-00075y-Tj; Tue, 29 Oct 2013 20:05:19 +0100 From: Sebastian Macke To: qemu-devel@nongnu.org, proljc@gmail.com Date: Tue, 29 Oct 2013 20:04:43 +0100 Message-Id: <1383073495-5332-2-git-send-email-sebastian@macke.de> X-Mailer: git-send-email 1.8.4.1 In-Reply-To: <1383073495-5332-1-git-send-email-sebastian@macke.de> References: <1383073495-5332-1-git-send-email-sebastian@macke.de> X-Authenticated-Sender: sebastian@macke.de X-Virus-Scanned: Clear (ClamAV 0.97.8/18033/Tue Oct 29 17:37:37 2013) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 213.133.104.11 Cc: Sebastian Macke , openrisc@lists.openrisc.net, openrisc@lists.opencores.org Subject: [Qemu-devel] [PATCH 01/13] target-openrisc: Implement translation block chaining X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Currently the translation blocks are searched via a hash table every time. But QEMU supports direct block chaining for the pc values which are known. This is true for the instructions l.bf, l.bnf, l.j and l.jal. Because of the delayed slot we have to save several variables to correctly jump after the delayed slot is executed. btaken: temporary flag if the branch is taken or not j_target: jump pc value j_type: Save the type of jump. Static, dynamic or branch The speed is increased by around a factor 2-3. Signed-off-by: Sebastian Macke --- target-openrisc/translate.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index 8fc679b..1047661 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -39,11 +39,21 @@ # define LOG_DIS(...) do { } while (0) #endif +enum { + JUMP_DYNAMIC, /* The address is not known during compile time*/ + JUMP_STATIC, /* The address is known during compile time */ + JUMP_BRANCH /* The two possible destinations are known */ +}; + + typedef struct DisasContext { TranslationBlock *tb; target_ulong pc; uint32_t tb_flags, synced_flags, flags; uint32_t is_jmp; + uint32_t j_state; /* specifies the jump type*/ + target_ulong j_target; /* target address for jump */ + TCGv btaken; /* Temporary variable */ uint32_t mem_idx; int singlestep_enabled; uint32_t delayed_branch; @@ -193,24 +203,31 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0) target_ulong tmp_pc; /* N26, 26bits imm */ tmp_pc = sign_extend((imm<<2), 26) + dc->pc; + dc->j_target = tmp_pc; switch (op0) { case 0x00: /* l.j */ tcg_gen_movi_tl(jmp_pc, tmp_pc); + dc->j_state = JUMP_STATIC; break; case 0x01: /* l.jal */ tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); tcg_gen_movi_tl(jmp_pc, tmp_pc); - break; + dc->j_state = JUMP_STATIC; + break; case 0x03: /* l.bnf */ case 0x04: /* l.bf */ { int lab = gen_new_label(); + dc->btaken = tcg_temp_local_new(); tcg_gen_movi_tl(jmp_pc, dc->pc+8); + tcg_gen_movi_tl(dc->btaken, 0); tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_NE : TCG_COND_EQ, cpu_srf, 0, lab); + tcg_gen_movi_tl(dc->btaken, 1); tcg_gen_movi_tl(jmp_pc, tmp_pc); gen_set_label(lab); + dc->j_state = JUMP_BRANCH; } break; case 0x11: /* l.jr */ @@ -1657,6 +1674,8 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; + dc->j_state = JUMP_DYNAMIC; + dc->j_target = 0; dc->flags = cpu->env.cpucfgr; dc->mem_idx = cpu_mmu_index(&cpu->env); dc->synced_flags = dc->tb_flags = tb->flags; @@ -1709,8 +1728,19 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, if (!dc->delayed_branch) { dc->tb_flags &= ~D_FLAG; gen_sync_flags(dc); - tcg_gen_mov_tl(cpu_pc, jmp_pc); - tcg_gen_exit_tb(0); + if (dc->j_state == JUMP_BRANCH) { + int l1 = gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_NE, dc->btaken, 0, l1); + gen_goto_tb(dc, 1, dc->pc); + gen_set_label(l1); + gen_goto_tb(dc, 0, dc->j_target); + tcg_temp_free(dc->btaken); + } else if (dc->j_state == JUMP_STATIC) { + gen_goto_tb(dc, 0, dc->j_target); + } else { + tcg_gen_mov_tl(cpu_pc, jmp_pc); + tcg_gen_exit_tb(0); + } dc->is_jmp = DISAS_JUMP; break; } @@ -1725,10 +1755,6 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, if (tb->cflags & CF_LAST_IO) { gen_io_end(); } - if (dc->is_jmp == DISAS_NEXT) { - dc->is_jmp = DISAS_UPDATE; - tcg_gen_movi_tl(cpu_pc, dc->pc); - } if (unlikely(cs->singlestep_enabled)) { if (dc->is_jmp == DISAS_NEXT) { tcg_gen_movi_tl(cpu_pc, dc->pc);