From patchwork Tue Apr 2 04:23:17 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 232882 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0F32B2C00F7 for ; Tue, 2 Apr 2013 16:23:11 +1100 (EST) Received: from localhost ([::1]:48964 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UMsrQ-00029n-St for incoming@patchwork.ozlabs.org; Tue, 02 Apr 2013 00:30:16 -0400 Received: from eggs.gnu.org ([208.118.235.92]:57951) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UMslk-00038h-PD for qemu-devel@nongnu.org; Tue, 02 Apr 2013 00:24:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UMslg-0007PE-RH for qemu-devel@nongnu.org; Tue, 02 Apr 2013 00:24:24 -0400 Received: from mail-yh0-x236.google.com ([2607:f8b0:4002:c01::236]:45248) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UMslg-0007P2-Lj for qemu-devel@nongnu.org; Tue, 02 Apr 2013 00:24:20 -0400 Received: by mail-yh0-f54.google.com with SMTP id 29so3053yhr.13 for ; Mon, 01 Apr 2013 21:24:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=qI2aq29t/PvfwZJ91ukG4PebB7TL+w/mGnoejg6tHuI=; b=ZJR2prsBw7SB5L+giv6cDJjM6oJWIe/pwUqeQwtkCshimLJ28a9N6JYIg6RaA3tzKc Qc5+QMvF1QpjcP0Axd/kRSRHm7sA52Biqzvp+I4OuoQhkOOWDXtb4XPh2sRno7tysI70 V0T/le77z8m/fv5PohUBAXb4GvWj/s+wllWpDy8ymP5c9nUWTLCS6nXwoa37cEV1cwRg MEduKekS71uSX2CsjOcaMYIfH3cdleYVdsmt+C7U25orciKarLeNMYZ/Jt3IluyX/kdr ubpx7zP/PTExw7XG78ozJC5BIQZIEZB3tTewe/vPqTK9LHaNWcV07xCs97m0LjRHmz7I boyg== X-Received: by 10.236.81.101 with SMTP id l65mr12933355yhe.131.1364876660252; Mon, 01 Apr 2013 21:24:20 -0700 (PDT) Received: from pebble.com ([12.236.175.36]) by mx.google.com with ESMTPS id z64sm32502731yhc.24.2013.04.01.21.24.18 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 01 Apr 2013 21:24:19 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 1 Apr 2013 21:23:17 -0700 Message-Id: <1364876610-3933-15-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1364876610-3933-1-git-send-email-rth@twiddle.net> References: <1364876610-3933-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4002:c01::236 Cc: av1474@comtv.ru, agraf@suse.de, aurelien@aurel32.net Subject: [Qemu-devel] [PATCH v3 14/27] tcg-ppc64: Streamline qemu_ld/st insn selection 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 Using a table to look up insns of the right width and sign. Include support for the Power 2.05 LDBRX and STDBRX insns included in e.g. Power6. Signed-off-by: Richard Henderson Reviewed-by: Aurelien Jarno --- tcg/ppc64/tcg-target.c | 166 +++++++++++++++++-------------------------------- 1 file changed, 56 insertions(+), 110 deletions(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 51a5545..8c19f98 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -44,6 +44,8 @@ static uint8_t *tb_ret_addr; #define GUEST_BASE 0 #endif +#define HAVE_ISA_2_06 0 + #ifdef CONFIG_USE_GUEST_BASE #define TCG_GUEST_BASE_REG 30 #else @@ -368,8 +370,10 @@ static int tcg_target_const_match (tcg_target_long val, #define CMPL XO31( 32) #define LHBRX XO31(790) #define LWBRX XO31(534) +#define LDBRX XO31(532) #define STHBRX XO31(918) #define STWBRX XO31(662) +#define STDBRX XO31(660) #define MFSPR XO31(339) #define MTSPR XO31(467) #define SRAWI XO31(824) @@ -759,22 +763,44 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg r0, TCGReg r1, TCGReg r2, } #endif +static const uint32_t qemu_ldx_opc[8] = { +#ifdef TARGET_WORDS_BIGENDIAN + LBZX, LHZX, LWZX, LDX, + 0, LHAX, LWAX, LDX +#else + LBZX, LHBRX, LWBRX, LDBRX, + 0, 0, 0, LDBRX, +#endif +}; + +static const uint32_t qemu_stx_opc[4] = { +#ifdef TARGET_WORDS_BIGENDIAN + STBX, STHX, STWX, STDX +#else + STBX, STHBRX, STWBRX, STDBRX, +#endif +}; + +static const uint32_t qemu_exts_opc[4] = { + EXTSB, EXTSH, EXTSW, 0 +}; + static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) { TCGReg addr_reg, data_reg, r0, r1, rbase; - int bswap; + uint32_t insn, s_bits; #ifdef CONFIG_SOFTMMU TCGReg r2, ir; - int mem_index, s_bits; + int mem_index; void *label1_ptr, *label2_ptr; #endif data_reg = *args++; addr_reg = *args++; + s_bits = opc & 3; #ifdef CONFIG_SOFTMMU mem_index = *args; - s_bits = opc & 3; r0 = 3; r1 = 4; @@ -799,23 +825,11 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1); - switch (opc) { - case 0|4: - tcg_out32 (s, EXTSB | RA (data_reg) | RS (3)); - break; - case 1|4: - tcg_out32 (s, EXTSH | RA (data_reg) | RS (3)); - break; - case 2|4: - tcg_out32 (s, EXTSW | RA (data_reg) | RS (3)); - break; - case 0: - case 1: - case 2: - case 3: - if (data_reg != 3) - tcg_out_mov (s, TCG_TYPE_I64, data_reg, 3); - break; + if (opc & 4) { + insn = qemu_exts_opc[s_bits]; + tcg_out32(s, insn | RA(data_reg) | RS(3)); + } else if (data_reg != 3) { + tcg_out_mov(s, TCG_TYPE_I64, data_reg, 3); } label2_ptr = s->code_ptr; tcg_out32 (s, B); @@ -842,65 +856,19 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0; #endif -#ifdef TARGET_WORDS_BIGENDIAN - bswap = 0; -#else - bswap = 1; -#endif - switch (opc) { - default: - case 0: - tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0)); - break; - case 0|4: - tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0)); - tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg)); - break; - case 1: - if (bswap) - tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0)); - else - tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0)); - break; - case 1|4: - if (bswap) { - tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0)); - tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg)); - } - else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0)); - break; - case 2: - if (bswap) - tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0)); - else - tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0)); - break; - case 2|4: - if (bswap) { - tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0)); - tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg)); - } - else tcg_out32 (s, LWAX | TAB (data_reg, rbase, r0)); - break; - case 3: -#ifdef CONFIG_USE_GUEST_BASE - if (bswap) { - tcg_out32(s, ADDI | TAI(r1, r0, 4)); - tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0)); - tcg_out32 (s, LWBRX | TAB ( r1, rbase, r1)); - tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0); - } - else tcg_out32 (s, LDX | TAB (data_reg, rbase, r0)); -#else - if (bswap) { - tcg_out_movi32 (s, 0, 4); - tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0)); - tcg_out32 (s, LWBRX | RT ( r1) | RA (r0)); - tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0); - } - else tcg_out32 (s, LD | RT (data_reg) | RA (r0)); -#endif - break; + insn = qemu_ldx_opc[opc]; + if (!HAVE_ISA_2_06 && insn == LDBRX) { + tcg_out32(s, ADDI | TAI(r1, r0, 4)); + tcg_out32(s, LWBRX | TAB(data_reg, rbase, r0)); + tcg_out32(s, LWBRX | TAB( r1, rbase, r1)); + tcg_out_rld(s, RLDIMI, data_reg, r1, 32, 0); + } else if (insn) { + tcg_out32(s, insn | TAB(data_reg, rbase, r0)); + } else { + insn = qemu_ldx_opc[s_bits]; + tcg_out32(s, insn | TAB(data_reg, rbase, r0)); + insn = qemu_exts_opc[s_bits]; + tcg_out32 (s, insn | RA(data_reg) | RS(data_reg)); } #ifdef CONFIG_SOFTMMU @@ -911,7 +879,7 @@ 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, r0, r1, rbase, data_reg; - int bswap; + uint32_t insn; #ifdef CONFIG_SOFTMMU TCGReg r2, ir; int mem_index; @@ -975,36 +943,14 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0; #endif -#ifdef TARGET_WORDS_BIGENDIAN - bswap = 0; -#else - bswap = 1; -#endif - switch (opc) { - case 0: - tcg_out32 (s, STBX | SAB (data_reg, rbase, r0)); - break; - case 1: - if (bswap) - tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0)); - else - tcg_out32 (s, STHX | SAB (data_reg, rbase, r0)); - break; - case 2: - if (bswap) - tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0)); - else - tcg_out32 (s, STWX | SAB (data_reg, rbase, r0)); - break; - case 3: - if (bswap) { - tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0)); - tcg_out32(s, ADDI | TAI(r1, r0, 4)); - tcg_out_shri64(s, 0, data_reg, 32); - tcg_out32 (s, STWBRX | SAB (0, rbase, r1)); - } - else tcg_out32 (s, STDX | SAB (data_reg, rbase, r0)); - break; + insn = qemu_stx_opc[opc]; + if (!HAVE_ISA_2_06 && insn == STDBRX) { + tcg_out32(s, STWBRX | SAB(data_reg, rbase, r0)); + tcg_out32(s, ADDI | TAI(r1, r0, 4)); + tcg_out_shri64(s, 0, data_reg, 32); + tcg_out32(s, STWBRX | SAB(0, rbase, r1)); + } else { + tcg_out32(s, insn | SAB(data_reg, rbase, r0)); } #ifdef CONFIG_SOFTMMU