[binutils-gdb] opcodes: Fix branch displacement mask in M*Core disassembler

Alan Modra amodra@sourceware.org
Sat Jan 24 03:23:45 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6e11566d9e64a4908622a016d126866efbd64d89

commit 6e11566d9e64a4908622a016d126866efbd64d89
Author: Michal Sobon <msobon@hex-rays.com>
Date:   Fri Jan 23 14:38:28 2026 +0100

    opcodes: Fix branch displacement mask in M*Core disassembler
    
    The BT, BF, BR, and BSR instructions use the Scaled 11-Bit Displacement
    addressing mode. According to the Motorola M*Core Reference Manual,
    the instruction format has:
    - bits 15-11: opcode
    - bits 10-0: 11-bit signed displacement field
    
    The displacement calculation is: PC <- PC + 2 + (sign-extended disp11 << 1)
    
    The disassembler was incorrectly masking with 0x3FF (10 bits) instead of
    0x7FF (11 bits). This masked off bit 10, which is the sign bit for the
    11-bit signed displacement. As a result, negative (backward) branches
    were incorrectly disassembled as forward branches.
    
    opcodes/
            * mcore-dis.c (print_insn_mcore): Fix displacement mask from
            0x3FF to 0x7FF in BR case to correctly extract all 11 bits
            including the sign bit.
    
    Signed-off-by: Michal Sobon <msobon@hex-rays.com>

Diff:
---
 opcodes/mcore-dis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/opcodes/mcore-dis.c b/opcodes/mcore-dis.c
index a3e7d0b9e95..629ae1b9eea 100644
--- a/opcodes/mcore-dis.c
+++ b/opcodes/mcore-dis.c
@@ -199,7 +199,7 @@ print_insn_mcore (bfd_vma memaddr,
 
 	case BR:
 	  {
-	    uint32_t val = ((inst & 0x3FF) ^ 0x400) - 0x400;
+	    uint32_t val = ((inst & 0x7FF) ^ 0x400) - 0x400;
 
 	    val = memaddr + 2 + (val << 1);
 	    (*print_func) (stream, "\t0x%x", val);


More information about the Binutils-cvs mailing list