0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _ASM_BRANCH_H
0009 #define _ASM_BRANCH_H
0010
0011 #include <asm/cpu-features.h>
0012 #include <asm/mipsregs.h>
0013 #include <asm/ptrace.h>
0014 #include <asm/inst.h>
0015
0016 extern int __isa_exception_epc(struct pt_regs *regs);
0017 extern int __compute_return_epc(struct pt_regs *regs);
0018 extern int __compute_return_epc_for_insn(struct pt_regs *regs,
0019 union mips_instruction insn);
0020 extern int __microMIPS_compute_return_epc(struct pt_regs *regs);
0021 extern int __MIPS16e_compute_return_epc(struct pt_regs *regs);
0022
0023
0024
0025
0026 #define MM_POOL32A_MINOR_MASK 0x3f
0027 #define MM_POOL32A_MINOR_SHIFT 0x6
0028 #define MM_MIPS32_COND_FC 0x30
0029
0030 int isBranchInstr(struct pt_regs *regs,
0031 struct mm_decoded_insn dec_insn, unsigned long *contpc);
0032
0033 extern int __mm_isBranchInstr(struct pt_regs *regs,
0034 struct mm_decoded_insn dec_insn, unsigned long *contpc);
0035
0036 static inline int mm_isBranchInstr(struct pt_regs *regs,
0037 struct mm_decoded_insn dec_insn, unsigned long *contpc)
0038 {
0039 if (!cpu_has_mmips)
0040 return 0;
0041
0042 return __mm_isBranchInstr(regs, dec_insn, contpc);
0043 }
0044
0045 static inline int delay_slot(struct pt_regs *regs)
0046 {
0047 return regs->cp0_cause & CAUSEF_BD;
0048 }
0049
0050 static inline void clear_delay_slot(struct pt_regs *regs)
0051 {
0052 regs->cp0_cause &= ~CAUSEF_BD;
0053 }
0054
0055 static inline void set_delay_slot(struct pt_regs *regs)
0056 {
0057 regs->cp0_cause |= CAUSEF_BD;
0058 }
0059
0060 static inline unsigned long exception_epc(struct pt_regs *regs)
0061 {
0062 if (likely(!delay_slot(regs)))
0063 return regs->cp0_epc;
0064
0065 if (get_isa16_mode(regs->cp0_epc))
0066 return __isa_exception_epc(regs);
0067
0068 return regs->cp0_epc + 4;
0069 }
0070
0071 #define BRANCH_LIKELY_TAKEN 0x0001
0072
0073 static inline int compute_return_epc(struct pt_regs *regs)
0074 {
0075 if (get_isa16_mode(regs->cp0_epc)) {
0076 if (cpu_has_mmips)
0077 return __microMIPS_compute_return_epc(regs);
0078 if (cpu_has_mips16)
0079 return __MIPS16e_compute_return_epc(regs);
0080 } else if (!delay_slot(regs)) {
0081 regs->cp0_epc += 4;
0082 return 0;
0083 }
0084
0085 return __compute_return_epc(regs);
0086 }
0087
0088 static inline int MIPS16e_compute_return_epc(struct pt_regs *regs,
0089 union mips16e_instruction *inst)
0090 {
0091 if (likely(!delay_slot(regs))) {
0092 if (inst->ri.opcode == MIPS16e_extend_op) {
0093 regs->cp0_epc += 4;
0094 return 0;
0095 }
0096 regs->cp0_epc += 2;
0097 return 0;
0098 }
0099
0100 return __MIPS16e_compute_return_epc(regs);
0101 }
0102
0103 #endif