From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45769) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V6PXH-0003hz-Nz for qemu-devel@nongnu.org; Mon, 05 Aug 2013 14:29:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V6PXB-0001B6-Sv for qemu-devel@nongnu.org; Mon, 05 Aug 2013 14:29:39 -0400 Received: from mail-qa0-x22d.google.com ([2607:f8b0:400d:c00::22d]:34483) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V6PXB-0001B2-Np for qemu-devel@nongnu.org; Mon, 05 Aug 2013 14:29:33 -0400 Received: by mail-qa0-f45.google.com with SMTP id l18so1143381qak.18 for ; Mon, 05 Aug 2013 11:29:33 -0700 (PDT) Sender: Richard Henderson From: Richard Henderson Date: Mon, 5 Aug 2013 08:28:38 -1000 Message-Id: <1375727330-30515-4-git-send-email-rth@twiddle.net> In-Reply-To: <1375727330-30515-1-git-send-email-rth@twiddle.net> References: <1375727330-30515-1-git-send-email-rth@twiddle.net> Subject: [Qemu-devel] [PATCH for-next 03/15] tcg-ppc64: Use the branch absolute instruction when possible List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Vassili Karpov (malc)" , Richard Henderson ... before falling back to an indirect branch. Signed-off-by: Richard Henderson --- tcg/ppc64/tcg-target.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 94960a3..fce3e5d 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -173,13 +173,17 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R31 }; +static inline bool in_range_b(intptr_t disp) +{ + return disp >= -0x4000000 && disp < 0x4000000; +} + static uint32_t reloc_pc24_val (void *pc, tcg_target_long target) { tcg_target_long disp; disp = target - (tcg_target_long) pc; - if ((disp << 38) >> 38 != disp) - tcg_abort (); + assert(in_range_b(disp)); return disp & 0x3fffffc; } @@ -195,8 +199,7 @@ static uint16_t reloc_pc14_val (void *pc, tcg_target_long target) tcg_target_long disp; disp = target - (tcg_target_long) pc; - if (disp != (int16_t) disp) - tcg_abort (); + assert(disp == (int16_t)disp); return disp & 0xfffc; } @@ -454,6 +457,7 @@ static int tcg_target_const_match (tcg_target_long val, #define FXM(b) (1 << (19 - (b))) #define LK 1 +#define AA 2 #define TAB(t, a, b) (RT(t) | RA(a) | RB(b)) #define SAB(s, a, b) (RS(s) | RA(a) | RB(b)) @@ -688,17 +692,18 @@ static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c) tcg_out_zori32(s, dst, src, c, XORI, XORIS); } -static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target) +static void tcg_out_b(TCGContext *s, int lk, tcg_target_long target) { - tcg_target_long disp; + tcg_target_long disp = target - (tcg_target_long) s->code_ptr; - disp = target - (tcg_target_long) s->code_ptr; - if ((disp << 38) >> 38 == disp) - tcg_out32 (s, B | (disp & 0x3fffffc) | mask); - else { - tcg_out_movi (s, TCG_TYPE_I64, 0, (tcg_target_long) target); - tcg_out32 (s, MTSPR | RS (0) | CTR); - tcg_out32 (s, BCCTR | BO_ALWAYS | mask); + if (in_range_b(disp)) { + tcg_out32(s, B | (disp & 0x3fffffc) | lk); + } else if (in_range_b(target)) { + tcg_out32(s, B | AA | target | lk); + } else { + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, target); + tcg_out32 (s, MTSPR | RS(TCG_REG_R0) | CTR); + tcg_out32 (s, BCCTR | BO_ALWAYS | lk); } } -- 1.8.3.1