1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle 7 */ 8#ifndef _ASM_BRANCH_H 9#define _ASM_BRANCH_H 10 11#include <asm/ptrace.h> 12#include <asm/inst.h> 13 14static inline int delay_slot(struct pt_regs *regs) 15{ 16 return regs->cp0_cause & CAUSEF_BD; 17} 18 19extern int __isa_exception_epc(struct pt_regs *regs); 20 21static inline unsigned long exception_epc(struct pt_regs *regs) 22{ 23 if (likely(!delay_slot(regs))) 24 return regs->cp0_epc; 25 26 if (is16mode(regs)) 27 return __isa_exception_epc(regs); 28 29 return regs->cp0_epc + 4; 30} 31 32extern int __compute_return_epc(struct pt_regs *regs); 33extern int __MIPS16e_compute_return_epc(struct pt_regs *regs); 34extern int __microMIPS_compute_return_epc(struct pt_regs *regs); 35 36/* only for MIPS32/64 but not 16bits variants */ 37static inline int compute_return_epc(struct pt_regs *regs) 38{ 39 if (is16mode(regs)) { 40 if (cpu_has_mips16) 41 return __MIPS16e_compute_return_epc(regs); 42 if (cpu_has_mmips) 43 return __microMIPS_compute_return_epc(regs); 44 return regs->cp0_epc; 45 } 46 47 if (!delay_slot(regs)) { 48 regs->cp0_epc += 4; 49 return 0; 50 } 51 52 return __compute_return_epc(regs); 53} 54 55static inline int MIPS16e_compute_return_epc(struct pt_regs *regs, 56 union mips16e_instruction *inst) 57{ 58 if (likely(!delay_slot(regs))) { 59 if (inst->ri.opcode == MIPS16e_extend_op) { 60 regs->cp0_epc += 4; 61 return 0; 62 } 63 regs->cp0_epc += 2; 64 return 0; 65 } 66 67 return __MIPS16e_compute_return_epc(regs); 68} 69 70#endif /* _ASM_BRANCH_H */ 71