diff options
author | Steven J. Hill <Steven.Hill@imgtec.com> | 2013-03-25 18:45:19 (GMT) |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2013-05-09 15:55:20 (GMT) |
commit | 8508488fe7028b95bc86c7447c205fbc765cc4cf (patch) | |
tree | d1d10ce3f94efb5ade53e3aaa09d1c0c31afd3a4 /arch/mips/include | |
parent | cd574704ec06904c7b7dd2c897fea5a54f944a95 (diff) | |
download | linux-8508488fe7028b95bc86c7447c205fbc765cc4cf.tar.xz |
MIPS: MIPS16e: Support handling of delay slots.
Add logic needed to properly calculate exceptions for delay slots
when in MIPS16e mode.
Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
Diffstat (limited to 'arch/mips/include')
-rw-r--r-- | arch/mips/include/asm/branch.h | 18 | ||||
-rw-r--r-- | arch/mips/include/asm/inst.h | 3 |
2 files changed, 21 insertions, 0 deletions
diff --git a/arch/mips/include/asm/branch.h b/arch/mips/include/asm/branch.h index 40bb9eb..e28a3e0 100644 --- a/arch/mips/include/asm/branch.h +++ b/arch/mips/include/asm/branch.h @@ -16,6 +16,7 @@ extern int __compute_return_epc(struct pt_regs *regs); extern int __compute_return_epc_for_insn(struct pt_regs *regs, union mips_instruction insn); extern int __microMIPS_compute_return_epc(struct pt_regs *regs); +extern int __MIPS16e_compute_return_epc(struct pt_regs *regs); static inline int delay_slot(struct pt_regs *regs) @@ -41,6 +42,8 @@ static inline int compute_return_epc(struct pt_regs *regs) if (get_isa16_mode(regs->cp0_epc)) { if (cpu_has_mmips) return __microMIPS_compute_return_epc(regs); + if (cpu_has_mips16) + return __MIPS16e_compute_return_epc(regs); return regs->cp0_epc; } @@ -52,4 +55,19 @@ static inline int compute_return_epc(struct pt_regs *regs) return __compute_return_epc(regs); } +static inline int MIPS16e_compute_return_epc(struct pt_regs *regs, + union mips16e_instruction *inst) +{ + if (likely(!delay_slot(regs))) { + if (inst->ri.opcode == MIPS16e_extend_op) { + regs->cp0_epc += 4; + return 0; + } + regs->cp0_epc += 2; + return 0; + } + + return __MIPS16e_compute_return_epc(regs); +} + #endif /* _ASM_BRANCH_H */ diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h index b27091e..22912f7 100644 --- a/arch/mips/include/asm/inst.h +++ b/arch/mips/include/asm/inst.h @@ -82,4 +82,7 @@ struct mm_decoded_insn { int micro_mips_mode; }; +/* Recode table from 16-bit register notation to 32-bit GPR. Do NOT export!!! */ +extern const int reg16to32[]; + #endif /* _ASM_INST_H */ |