* [PATCH] Handle sparc compare-and-branch
@ 2012-04-21 2:22 David Miller
2012-04-21 17:10 ` Mark Kettenis
0 siblings, 1 reply; 3+ messages in thread
From: David Miller @ 2012-04-21 2:22 UTC (permalink / raw)
To: gdb-patches
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. */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Handle sparc compare-and-branch
2012-04-21 2:22 [PATCH] Handle sparc compare-and-branch David Miller
@ 2012-04-21 17:10 ` Mark Kettenis
2012-04-21 22:29 ` David Miller
0 siblings, 1 reply; 3+ messages in thread
From: Mark Kettenis @ 2012-04-21 17:10 UTC (permalink / raw)
To: davem; +Cc: gdb-patches
> Date: Fri, 20 Apr 2012 20:34:08 -0400 (EDT)
> From: David Miller <davem@davemloft.net>
>
> 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.
Is this new instruction documented anywhere?
> 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?
Makes sense to me, so please go ahead.
> gdb/
>
> * sparc-tdep.c (X_DISP10): Define.
> (sparc_analyze_control_transfer): Handle compare-and-branch.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Handle sparc compare-and-branch
2012-04-21 17:10 ` Mark Kettenis
@ 2012-04-21 22:29 ` David Miller
0 siblings, 0 replies; 3+ messages in thread
From: David Miller @ 2012-04-21 22:29 UTC (permalink / raw)
To: mark.kettenis; +Cc: gdb-patches
From: Mark Kettenis <mark.kettenis@xs4all.nl>
Date: Sat, 21 Apr 2012 12:11:34 +0200 (CEST)
>> Date: Fri, 20 Apr 2012 20:34:08 -0400 (EDT)
>> From: David Miller <davem@davemloft.net>
>>
>> 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.
>
> Is this new instruction documented anywhere?
Not publicly at the current time, but such documents will be available
soon.
I've posted binutils patches the other day if you're interested in the
opcodes :-)
>> 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?
>
> Makes sense to me, so please go ahead.
Thanks.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-04-21 19:04 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-21 2:22 [PATCH] Handle sparc compare-and-branch David Miller
2012-04-21 17:10 ` Mark Kettenis
2012-04-21 22:29 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox