diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-11-25 23:06:04 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-12-22 04:43:49 -0500 |
commit | edfd6da0405520b147ab1473ad183a5b32be7082 (patch) | |
tree | 3b97d63cda99bf19f305a16e6f86bf5da68d8935 /arch/sh/kernel/traps_32.c | |
parent | 5dd614761f05f56b93c94541aa92e6449920516c (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.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 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 |
692 | static int emulate_branch(unsigned short inst, struct pt_regs* regs) | 692 | static 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 | } |