aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/traps_32.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-11-25 23:06:04 -0500
committerPaul Mundt <lethal@linux-sh.org>2008-12-22 04:43:49 -0500
commitedfd6da0405520b147ab1473ad183a5b32be7082 (patch)
tree3b97d63cda99bf19f305a16e6f86bf5da68d8935 /arch/sh/kernel/traps_32.c
parent5dd614761f05f56b93c94541aa92e6449920516c (diff)
sh: Add a few more branch types to the branch emulator.
This plugs in some extra encodings for matching more bsr/bsrf/jsr branches. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/traps_32.c')
-rw-r--r--arch/sh/kernel/traps_32.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 1e5c74efbacc..f2497585cac0 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,
689} 689}
690 690
691#ifdef CONFIG_SH_FPU_EMU 691#ifdef CONFIG_SH_FPU_EMU
692static int emulate_branch(unsigned short inst, struct pt_regs* regs) 692static int emulate_branch(unsigned short inst, struct pt_regs *regs)
693{ 693{
694 /* 694 /*
695 * bfs: 8fxx: PC+=d*2+4; 695 * bfs: 8fxx: PC+=d*2+4;
@@ -702,27 +702,32 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
702 * jsr: 4x0b: PC=Rn after PR=PC+4; 702 * jsr: 4x0b: PC=Rn after PR=PC+4;
703 * rts: 000b: PC=PR; 703 * rts: 000b: PC=PR;
704 */ 704 */
705 if ((inst & 0xfd00) == 0x8d00) { 705 if (((inst & 0xf000) == 0xb000) || /* bsr */
706 ((inst & 0xf0ff) == 0x0003) || /* bsrf */
707 ((inst & 0xf0ff) == 0x400b)) /* jsr */
708 regs->pr = regs->pc + 4;
709
710 if ((inst & 0xfd00) == 0x8d00) { /* bfs, bts */
706 regs->pc += SH_PC_8BIT_OFFSET(inst); 711 regs->pc += SH_PC_8BIT_OFFSET(inst);
707 return 0; 712 return 0;
708 } 713 }
709 714
710 if ((inst & 0xe000) == 0xa000) { 715 if ((inst & 0xe000) == 0xa000) { /* bra, bsr */
711 regs->pc += SH_PC_12BIT_OFFSET(inst); 716 regs->pc += SH_PC_12BIT_OFFSET(inst);
712 return 0; 717 return 0;
713 } 718 }
714 719
715 if ((inst & 0xf0df) == 0x0003) { 720 if ((inst & 0xf0df) == 0x0003) { /* braf, bsrf */
716 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; 721 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
717 return 0; 722 return 0;
718 } 723 }
719 724
720 if ((inst & 0xf0df) == 0x400b) { 725 if ((inst & 0xf0df) == 0x400b) { /* jmp, jsr */
721 regs->pc = regs->regs[(inst & 0x0f00) >> 8]; 726 regs->pc = regs->regs[(inst & 0x0f00) >> 8];
722 return 0; 727 return 0;
723 } 728 }
724 729
725 if ((inst & 0xffff) == 0x000b) { 730 if ((inst & 0xffff) == 0x000b) { /* rts */
726 regs->pc = regs->pr; 731 regs->pc = regs->pr;
727 return 0; 732 return 0;
728 } 733 }