sh: Add a few more branch types to the branch emulator.
authorPaul Mundt <lethal@linux-sh.org>
Wed, 26 Nov 2008 04:06:04 +0000 (13:06 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Mon, 22 Dec 2008 09:43:49 +0000 (18:43 +0900)
This plugs in some extra encodings for matching more bsr/bsrf/jsr
branches.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/kernel/traps_32.c

index 1e5c74e..f249758 100644 (file)
@@ -689,7 +689,7 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
 }
 
 #ifdef CONFIG_SH_FPU_EMU
-static int emulate_branch(unsigned short inst, struct pt_regsregs)
+static int emulate_branch(unsigned short inst, struct pt_regs *regs)
 {
        /*
         * bfs: 8fxx: PC+=d*2+4;
@@ -702,27 +702,32 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
         * jsr: 4x0b: PC=Rn      after PR=PC+4;
         * rts: 000b: PC=PR;
         */
-       if ((inst & 0xfd00) == 0x8d00) {
+       if (((inst & 0xf000) == 0xb000)  ||     /* bsr */
+           ((inst & 0xf0ff) == 0x0003)  ||     /* bsrf */
+           ((inst & 0xf0ff) == 0x400b))        /* jsr */
+               regs->pr = regs->pc + 4;
+
+       if ((inst & 0xfd00) == 0x8d00) {        /* bfs, bts */
                regs->pc += SH_PC_8BIT_OFFSET(inst);
                return 0;
        }
 
-       if ((inst & 0xe000) == 0xa000) {
+       if ((inst & 0xe000) == 0xa000) {        /* bra, bsr */
                regs->pc += SH_PC_12BIT_OFFSET(inst);
                return 0;
        }
 
-       if ((inst & 0xf0df) == 0x0003) {
+       if ((inst & 0xf0df) == 0x0003) {        /* braf, bsrf */
                regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
                return 0;
        }
 
-       if ((inst & 0xf0df) == 0x400b) {
+       if ((inst & 0xf0df) == 0x400b) {        /* jmp, jsr */
                regs->pc = regs->regs[(inst & 0x0f00) >> 8];
                return 0;
        }
 
-       if ((inst & 0xffff) == 0x000b) {
+       if ((inst & 0xffff) == 0x000b) {        /* rts */
                regs->pc = regs->pr;
                return 0;
        }