From patchwork Wed Oct 10 16:02:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 190708 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 30BD12C0088 for ; Thu, 11 Oct 2012 03:04:55 +1100 (EST) Received: from localhost ([::1]:34138 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TLymD-0000SR-Ao for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2012 12:04:53 -0400 Received: from eggs.gnu.org ([208.118.235.92]:52874) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TLykd-0005tV-8d for qemu-devel@nongnu.org; Wed, 10 Oct 2012 12:03:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TLykW-0007iZ-SS for qemu-devel@nongnu.org; Wed, 10 Oct 2012 12:03:15 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:50072) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TLykW-0007dV-Ls for qemu-devel@nongnu.org; Wed, 10 Oct 2012 12:03:08 -0400 Received: by mail-pb0-f45.google.com with SMTP id rp2so850961pbb.4 for ; Wed, 10 Oct 2012 09:03:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=tTH7LbVAtcGJZmnCRAf4lcnskixqgsyMEhjkhdAWj88=; b=OOyLSf/KHf0/WPafV0R6P8cP58BBNwlJQMet2pWC/DscdsnNhH2rKI8D6L+O/dP03m +wQDd8639e9UtdaQ/nGjRyN9w0GU0QPkXQqDnHSj6W74hflDriu4bP2Kf8CmjL9k1kAx rHkZer4gKes2HlUG7WtX3iAYsQEy12hXQeGR5L2hLSXxC2Wxl0AL8xwgu8rN/R8LnRT1 wEPo5KXn5gIRM4VaXDdIgJHQnhnRWDCvnvHGjlSE0KZApQJBf8OGJD1kRQP9w8JBxeP6 mABoBqHl52EbYIFnY0HJPzFGrxg274Bj/yDQEVSqkCBNJBWCH2M+InOlC5KDtlKdMJaO JyuQ== Received: by 10.68.131.35 with SMTP id oj3mr65226647pbb.128.1349884988277; Wed, 10 Oct 2012 09:03:08 -0700 (PDT) Received: from anchor.twiddle.home.com (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPS id sj5sm1216694pbc.30.2012.10.10.09.03.07 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 10 Oct 2012 09:03:07 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2012 09:02:46 -0700 Message-Id: <1349884967-4608-13-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.11.4 In-Reply-To: <1349884967-4608-1-git-send-email-rth@twiddle.net> References: <1349884967-4608-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: Blue Swirl Subject: [Qemu-devel] [PATCH 12/13] tcg-sparc: Emit BPr insns for brcond_i64 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 Signed-off-by: Richard Henderson --- tcg/sparc/tcg-target.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index ab47c98..3b18fce 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -126,6 +126,7 @@ static const int tcg_target_call_oarg_regs[] = { #define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff)) #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff)) +#define INSN_OFF16(x) ((((x) >> 2) & 0x3fff) | ((((x) >> 16) & 3) << 20)) #define INSN_OFF19(x) (((x) >> 2) & 0x07ffff) #define INSN_COND(x) ((x) << 25) @@ -147,6 +148,13 @@ static const int tcg_target_call_oarg_regs[] = { #define COND_VC 0xf #define BA (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2)) +#define RCOND_Z 1 +#define RCOND_LEZ 2 +#define RCOND_LZ 3 +#define RCOND_NZ 5 +#define RCOND_GZ 6 +#define RCOND_GEZ 7 + #define MOVCC_ICC (1 << 18) #define MOVCC_XCC (1 << 18 | 1 << 12) @@ -156,6 +164,8 @@ static const int tcg_target_call_oarg_regs[] = { #define BPCC_PN 0 #define BPCC_A (1 << 29) +#define BPR_PT BPCC_PT + #define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00)) #define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10)) #define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01)) @@ -251,6 +261,16 @@ static void patch_reloc(uint8_t *code_ptr, int type, } *(uint32_t *)code_ptr = value; break; + case R_SPARC_WDISP16: + value -= (long)code_ptr; + if (!check_fit_tl(value >> 2, 16)) { + tcg_abort(); + } + insn = *(uint32_t *)code_ptr; + insn &= ~INSN_OFF16(-1); + insn |= INSN_OFF16(value); + *(uint32_t *)code_ptr = insn; + break; case R_SPARC_WDISP19: value -= (long)code_ptr; if (!check_fit_tl(value >> 2, 19)) { @@ -502,6 +522,15 @@ static const uint8_t tcg_cond_to_bcond[] = { [TCG_COND_GTU] = COND_GU, }; +static const uint8_t tcg_cond_to_rcond[] = { + [TCG_COND_EQ] = RCOND_Z, + [TCG_COND_NE] = RCOND_NZ, + [TCG_COND_LT] = RCOND_LZ, + [TCG_COND_GT] = RCOND_GZ, + [TCG_COND_LE] = RCOND_LEZ, + [TCG_COND_GE] = RCOND_GEZ +}; + static void tcg_out_bpcc0(TCGContext *s, int scond, int flags, int off19) { tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19); @@ -555,8 +584,24 @@ static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGArg ret, static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGArg arg1, TCGArg arg2, int const_arg2, int label) { - tcg_out_cmp(s, arg1, arg2, const_arg2); - tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label); + /* For 64-bit signed comparisons vs zero, we can avoid the compare. */ + if (arg2 == 0 && !is_unsigned_cond(cond)) { + TCGLabel *l = &s->labels[label]; + int off16; + + if (l->has_value) { + off16 = INSN_OFF16(l->u.value - (unsigned long)s->code_ptr); + } else { + /* Make sure to preserve destinations during retranslation. */ + off16 = *(uint32_t *)s->code_ptr & INSN_OFF16(-1); + tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, label, 0); + } + tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1) + | INSN_COND(tcg_cond_to_rcond[cond]) | off16); + } else { + tcg_out_cmp(s, arg1, arg2, const_arg2); + tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label); + } tcg_out_nop(s); }