diff options
Diffstat (limited to 'arch/sh/kernel/traps_32.c')
-rw-r--r-- | arch/sh/kernel/traps_32.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 1e5c74efbac..f2497585cac 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -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_regs* regs) +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; } |