2005-04-16 15:20:36 -07:00
/*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
* Copyright ( C ) 1996 , 1997 , 1998 , 2001 by Ralf Baechle
*/
# ifndef _ASM_BRANCH_H
# define _ASM_BRANCH_H
# include <asm/ptrace.h>
2011-11-08 17:07:11 +05:30
# include <asm/inst.h>
2005-04-16 15:20:36 -07:00
2013-03-25 13:08:40 -05:00
extern int __isa_exception_epc ( struct pt_regs * regs ) ;
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 ) ;
2013-03-25 13:45:19 -05:00
extern int __MIPS16e_compute_return_epc ( struct pt_regs * regs ) ;
2013-03-25 13:08:40 -05:00
2005-04-16 15:20:36 -07:00
static inline int delay_slot ( struct pt_regs * regs )
{
return regs - > cp0_cause & CAUSEF_BD ;
}
static inline unsigned long exception_epc ( struct pt_regs * regs )
{
2013-03-25 13:08:40 -05:00
if ( likely ( ! delay_slot ( regs ) ) )
2005-04-16 15:20:36 -07:00
return regs - > cp0_epc ;
2013-03-25 13:08:40 -05:00
if ( get_isa16_mode ( regs - > cp0_epc ) )
return __isa_exception_epc ( regs ) ;
2005-04-16 15:20:36 -07:00
return regs - > cp0_epc + 4 ;
}
2011-11-08 17:07:11 +05:30
# define BRANCH_LIKELY_TAKEN 0x0001
2005-04-16 15:20:36 -07:00
static inline int compute_return_epc ( struct pt_regs * regs )
{
2013-03-25 13:08:40 -05:00
if ( get_isa16_mode ( regs - > cp0_epc ) ) {
if ( cpu_has_mmips )
return __microMIPS_compute_return_epc ( regs ) ;
2013-03-25 13:45:19 -05:00
if ( cpu_has_mips16 )
return __MIPS16e_compute_return_epc ( regs ) ;
2013-03-25 13:08:40 -05:00
return regs - > cp0_epc ;
}
2005-04-16 15:20:36 -07:00
if ( ! delay_slot ( regs ) ) {
regs - > cp0_epc + = 4 ;
return 0 ;
}
return __compute_return_epc ( regs ) ;
}
2013-03-25 13:45:19 -05:00
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 ) ;
}
2005-04-16 15:20:36 -07:00
# endif /* _ASM_BRANCH_H */