From patchwork Fri May 31 18:07:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jani Kokkonen X-Patchwork-Id: 248013 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 DA90C2C0099 for ; Sat, 1 Jun 2013 06:53:16 +1000 (EST) Received: from localhost ([::1]:53672 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UiWK3-0005TW-1c for incoming@patchwork.ozlabs.org; Fri, 31 May 2013 16:53:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60999) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UiTjy-0008Vt-Qm for qemu-devel@nongnu.org; Fri, 31 May 2013 14:07:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UiTjv-0005Py-Sa for qemu-devel@nongnu.org; Fri, 31 May 2013 14:07:50 -0400 Received: from lhrrgout.huawei.com ([194.213.3.17]:35653) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UiTjv-0005Pr-I3 for qemu-devel@nongnu.org; Fri, 31 May 2013 14:07:47 -0400 Received: from 172.18.7.190 (EHLO lhreml203-edg.china.huawei.com) ([172.18.7.190]) by lhrrg02-dlp.huawei.com (MOS 4.3.5-GA FastPath queued) with ESMTP id ARZ39744; Fri, 31 May 2013 18:07:39 +0000 (GMT) Received: from LHREML404-HUB.china.huawei.com (10.201.5.218) by lhreml203-edg.huawei.com (172.18.7.221) with Microsoft SMTP Server (TLS) id 14.1.323.7; Fri, 31 May 2013 19:07:01 +0100 Received: from [127.0.0.1] (10.220.139.78) by lhreml404-hub.china.huawei.com (10.201.5.218) with Microsoft SMTP Server id 14.1.323.7; Sat, 1 Jun 2013 02:07:31 +0800 Message-ID: <51A8E6E2.1010704@huawei.com> Date: Fri, 31 May 2013 20:07:30 +0200 From: Jani Kokkonen User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20130509 Thunderbird/17.0.6 MIME-Version: 1.0 To: Peter Maydell References: <51A8E339.5000500@huawei.com> In-Reply-To: <51A8E339.5000500@huawei.com> X-Originating-IP: [10.220.139.78] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 194.213.3.17 X-Mailman-Approved-At: Fri, 31 May 2013 16:50:37 -0400 Cc: Laurent Desnogues , Claudio Fontana , qemu-devel@nongnu.org, Richard Henderson Subject: [Qemu-devel] [PATCH 4/4] tcg/aarch64: implement tlb lookup fast path 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 From: Jani Kokkonen implement the fast path for tcg_out_qemu_ld/st. Signed-off-by: Jani Kokkonen --- tcg/aarch64/tcg-target.c | 161 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 4 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 24b2862..47ec4a7 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -700,6 +700,36 @@ static inline void tcg_out_uxt(TCGContext *s, int s_bits, #ifdef CONFIG_SOFTMMU #include "exec/softmmu_defs.h" +/* Load and compare a TLB entry, leaving the flags set. Leaves X2 pointing + to the tlb entry. Clobbers X0,X1,X2,X3 and TMP. */ + +static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, + int s_bits, uint8_t **label_ptr, int tlb_offset) +{ + TCGReg base = TCG_AREG0; + + tcg_out_shr(s, 1, TCG_REG_TMP, addr_reg, TARGET_PAGE_BITS); + tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X1, tlb_offset); + tcg_out_arith(s, ARITH_ADD, 1, TCG_REG_X2, base, TCG_REG_X1, 0); + tcg_out_andi(s, 1, TCG_REG_X0, TCG_REG_TMP, CPU_TLB_BITS, 0); + tcg_out_arith(s, ARITH_ADD, 1, TCG_REG_X2, TCG_REG_X2, + TCG_REG_X0, -CPU_TLB_ENTRY_BITS); +#if TARGET_LONG_BITS == 64 + tcg_out_ldst(s, LDST_64, LDST_LD, TCG_REG_X3, TCG_REG_X2, 0); +#else + tcg_out_ldst(s, LDST_32, LDST_LD, TCG_REG_X3, TCG_REG_X2, 0); +#endif + /* check alignment */ + if (s_bits) { + tcg_out_tst(s, 1, addr_reg, s_bits, 0); + label_ptr[0] = s->code_ptr; + tcg_out_goto_cond_noaddr(s, TCG_COND_NE); + } + tcg_out_cmp(s, 1, TCG_REG_X3, TCG_REG_TMP, -TARGET_PAGE_BITS); + label_ptr[1] = s->code_ptr; + tcg_out_goto_cond_noaddr(s, TCG_COND_NE); +} + /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { @@ -723,18 +753,85 @@ static const void * const qemu_st_helpers[4] = { static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) { TCGReg addr_reg, data_reg; + bool bswap; #ifdef CONFIG_SOFTMMU int mem_index, s_bits; + int i; + uint8_t *label_ptr[2] = { NULL }; + uint8_t *label_ptr2; #endif data_reg = args[0]; addr_reg = args[1]; +#ifdef TARGET_WORDS_BIGENDIAN + bswap = 1; +#else + bswap = 0; +#endif #ifdef CONFIG_SOFTMMU mem_index = args[2]; s_bits = opc & 3; - /* TODO: insert TLB lookup here */ + tcg_out_tlb_read(s, addr_reg, s_bits, label_ptr, + offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)); + tcg_out_ldst(s, LDST_64, LDST_LD, TCG_REG_X1, TCG_REG_X2, + offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read)); + switch (opc) { + case 0: + tcg_out_ldst_r(s, LDST_8, LDST_LD, data_reg, addr_reg, TCG_REG_X1); + break; + case 0 | 4: + tcg_out_ldst_r(s, LDST_8, LDST_LD_S_X, data_reg, addr_reg, TCG_REG_X1); + break; + case 1: + tcg_out_ldst_r(s, LDST_16, LDST_LD, data_reg, addr_reg, TCG_REG_X1); + if (bswap) { + tcg_out_rev16(s, 1, data_reg, data_reg); + } + break; + case 1 | 4: + if (bswap) { + tcg_out_ldst_r(s, LDST_16, LDST_LD, data_reg, addr_reg, TCG_REG_X1); + tcg_out_rev16(s, 1, data_reg, data_reg); + tcg_out_sxt(s, 1, s_bits, data_reg, data_reg); + } else { + tcg_out_ldst_r(s, LDST_16, LDST_LD_S_X, + data_reg, addr_reg, TCG_REG_X1); + } + break; + case 2: + tcg_out_ldst_r(s, LDST_32, LDST_LD, data_reg, addr_reg, TCG_REG_X1); + if (bswap) { + tcg_out_rev32(s, data_reg, data_reg); + } + break; + case 2 | 4: + if (bswap) { + tcg_out_ldst_r(s, LDST_32, LDST_LD, data_reg, addr_reg, TCG_REG_X1); + tcg_out_rev32(s, data_reg, data_reg); + tcg_out_sxt(s, 1, s_bits, data_reg, data_reg); + } else { + tcg_out_ldst_r(s, LDST_32, LDST_LD_S_X, + data_reg, addr_reg, TCG_REG_X1); + } + break; + case 3: + tcg_out_ldst_r(s, LDST_64, LDST_LD, data_reg, addr_reg, TCG_REG_X1); + if (bswap) { + tcg_out_rev(s, 1, data_reg, data_reg); + } + break; + default: + tcg_abort(); + } + label_ptr2 = s->code_ptr; + tcg_out_goto_noaddr(s); + for (i = 0; i < 2; i++) { + if (label_ptr[i]) { + reloc_pc19(label_ptr[i], (tcg_target_long)s->code_ptr); + } + } /* all arguments passed via registers */ tcg_out_movr(s, 1, TCG_REG_X0, TCG_AREG0); tcg_out_movr(s, (TARGET_LONG_BITS == 64), TCG_REG_X1, addr_reg); @@ -748,7 +845,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) } else { tcg_out_movr(s, 1, data_reg, TCG_REG_X0); } - + reloc_pc26(label_ptr2, (tcg_target_long)s->code_ptr); #else /* !CONFIG_SOFTMMU */ tcg_abort(); /* TODO */ #endif @@ -757,8 +854,17 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) { TCGReg addr_reg, data_reg; + bool bswap; #ifdef CONFIG_SOFTMMU int mem_index, s_bits; + int i; + uint8_t *label_ptr[2] = { NULL }; + uint8_t *label_ptr2; +#endif +#ifdef TARGET_WORDS_BIGENDIAN + bswap = 1; +#else + bswap = 0; #endif data_reg = args[0]; addr_reg = args[1]; @@ -767,8 +873,55 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) mem_index = args[2]; s_bits = opc & 3; - /* TODO: insert TLB lookup here */ + tcg_out_tlb_read(s, addr_reg, s_bits, label_ptr, + offsetof(CPUArchState, tlb_table[mem_index][0].addr_write)); + tcg_out_ldst(s, LDST_64, LDST_LD, TCG_REG_X1, TCG_REG_X2, + offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write)); + switch (opc) { + case 0: + tcg_out_ldst_r(s, LDST_8, LDST_ST, data_reg, addr_reg, TCG_REG_X1); + break; + case 1: + if (bswap) { + tcg_out_rev16(s, 1, TCG_REG_X0, data_reg); + tcg_out_ldst_r(s, LDST_16, LDST_ST, TCG_REG_X0, + addr_reg, TCG_REG_X1); + } else { + tcg_out_ldst_r(s, LDST_16, LDST_ST, data_reg, + addr_reg, TCG_REG_X1); + } + break; + case 2: + if (bswap) { + tcg_out_rev32(s, TCG_REG_X0, data_reg); + tcg_out_ldst_r(s, LDST_32, LDST_ST, TCG_REG_X0, + addr_reg, TCG_REG_X1); + } else { + tcg_out_ldst_r(s, LDST_32, LDST_ST, data_reg, + addr_reg, TCG_REG_X1); + } + break; + case 3: + if (bswap) { + tcg_out_rev(s, 1, TCG_REG_X0, data_reg); + tcg_out_ldst_r(s, LDST_64, LDST_ST, TCG_REG_X0, + addr_reg, TCG_REG_X1); + } else { + tcg_out_ldst_r(s, LDST_64, LDST_ST, data_reg, + addr_reg, TCG_REG_X1); + } + break; + default: + tcg_abort(); + } + label_ptr2 = s->code_ptr; + tcg_out_goto_noaddr(s); + for (i = 0; i < 2; i++) { + if (label_ptr[i]) { + reloc_pc19(label_ptr[i], (tcg_target_long)s->code_ptr); + } + } /* all arguments passed via registers */ tcg_out_movr(s, 1, TCG_REG_X0, TCG_AREG0); tcg_out_movr(s, (TARGET_LONG_BITS == 64), TCG_REG_X1, addr_reg); @@ -777,7 +930,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, (tcg_target_long)qemu_st_helpers[s_bits]); tcg_out_callr(s, TCG_REG_TMP); - + reloc_pc26(label_ptr2, (tcg_target_long)s->code_ptr); #else /* !CONFIG_SOFTMMU */ tcg_abort(); /* TODO */ #endif