From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27139 invoked by alias); 21 Apr 2012 00:34:27 -0000 Received: (qmail 26971 invoked by uid 22791); 21 Apr 2012 00:34:26 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from shards.monkeyblade.net (HELO shards.monkeyblade.net) (198.137.202.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 21 Apr 2012 00:34:13 +0000 Received: from localhost (cpe-66-108-118-54.nyc.res.rr.com [66.108.118.54]) (authenticated bits=0) by shards.monkeyblade.net (8.14.4/8.14.4) with ESMTP id q3L0Y9SL007684 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 20 Apr 2012 17:34:11 -0700 Date: Sat, 21 Apr 2012 02:22:00 -0000 Message-Id: <20120420.203408.165318333491237734.davem@davemloft.net> To: gdb-patches@sourceware.org Subject: [PATCH] Handle sparc compare-and-branch From: David Miller Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-04/txt/msg00708.txt.bz2 SPARC-T4 adds a "compare and branch" instruction which fuses a compare and a branch instruction into one. The branch is non-delayed, there are no anulling facilities, and the displacement is 10-bits. This also corrects the existing bit test for Branch on Integer Register. The distinguising characteristic between Branch on Integer Register and Compare-and-Branch is bit 28. The existing code was checking bit 24 for zero, but that's pointless because bit 24 is already covered by the "X_OP2 (insn) == 3" test. Ok to commit? gdb/ * sparc-tdep.c (X_DISP10): Define. (sparc_analyze_control_transfer): Handle compare-and-branch. diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 24d54b7..00bca01 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -85,6 +85,7 @@ struct regset; /* Sign extension macros. */ #define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000) #define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000) +#define X_DISP10(i) ((((((i) >> 11) && 0x300) | (((i) >> 5) & 0xff)) ^ 0x200) - 0x200) #define X_SIMM13(i) ((((i) & 0x1fff) ^ 0x1000) - 0x1000) /* Fetch the instruction at PC. Instructions are always big-endian @@ -1451,14 +1452,24 @@ sparc_analyze_control_transfer (struct frame_info *frame, { unsigned long insn = sparc_fetch_instruction (pc); int conditional_p = X_COND (insn) & 0x7; - int branch_p = 0; + int branch_p = 0, fused_p = 0; long offset = 0; /* Must be signed for sign-extend. */ - if (X_OP (insn) == 0 && X_OP2 (insn) == 3 && (insn & 0x1000000) == 0) + if (X_OP (insn) == 0 && X_OP2 (insn) == 3) { - /* Branch on Integer Register with Prediction (BPr). */ - branch_p = 1; - conditional_p = 1; + if ((insn & 0x10000000) == 0) + { + /* Branch on Integer Register with Prediction (BPr). */ + branch_p = 1; + conditional_p = 1; + } + else + { + /* Compare and Branch */ + branch_p = 1; + fused_p = 1; + offset = 4 * X_DISP10 (insn); + } } else if (X_OP (insn) == 0 && X_OP2 (insn) == 6) { @@ -1495,7 +1506,16 @@ sparc_analyze_control_transfer (struct frame_info *frame, if (branch_p) { - if (conditional_p) + if (fused_p) + { + /* Fused compare-and-branch instructions are non-delayed, + and do not have an annuling capability. So we need to + always set a breakpoint on both the NPC and the branch + target address. */ + gdb_assert (offset != 0); + return pc + offset; + } + else if (conditional_p) { /* For conditional branches, return nPC + 4 iff the annul bit is 1. */