linux/arch/mips/include/asm/branch.h
<<
>>
Prefs
   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
  14extern int __isa_exception_epc(struct pt_regs *regs);
  15extern int __compute_return_epc(struct pt_regs *regs);
  16extern int __compute_return_epc_for_insn(struct pt_regs *regs,
  17                                         union mips_instruction insn);
  18extern int __microMIPS_compute_return_epc(struct pt_regs *regs);
  19extern int __MIPS16e_compute_return_epc(struct pt_regs *regs);
  20
  21
  22static inline int delay_slot(struct pt_regs *regs)
  23{
  24        return regs->cp0_cause & CAUSEF_BD;
  25}
  26
  27static inline unsigned long exception_epc(struct pt_regs *regs)
  28{
  29        if (likely(!delay_slot(regs)))
  30                return regs->cp0_epc;
  31
  32        if (get_isa16_mode(regs->cp0_epc))
  33                return __isa_exception_epc(regs);
  34
  35        return regs->cp0_epc + 4;
  36}
  37
  38#define BRANCH_LIKELY_TAKEN 0x0001
  39
  40static inline int compute_return_epc(struct pt_regs *regs)
  41{
  42        if (get_isa16_mode(regs->cp0_epc)) {
  43                if (cpu_has_mmips)
  44                        return __microMIPS_compute_return_epc(regs);
  45                if (cpu_has_mips16)
  46                        return __MIPS16e_compute_return_epc(regs);
  47                return regs->cp0_epc;
  48        }
  49
  50        if (!delay_slot(regs)) {
  51                regs->cp0_epc += 4;
  52                return 0;
  53        }
  54
  55        return __compute_return_epc(regs);
  56}
  57
  58static inline int MIPS16e_compute_return_epc(struct pt_regs *regs,
  59                                             union mips16e_instruction *inst)
  60{
  61        if (likely(!delay_slot(regs))) {
  62                if (inst->ri.opcode == MIPS16e_extend_op) {
  63                        regs->cp0_epc += 4;
  64                        return 0;
  65                }
  66                regs->cp0_epc += 2;
  67                return 0;
  68        }
  69
  70        return __MIPS16e_compute_return_epc(regs);
  71}
  72
  73#endif /* _ASM_BRANCH_H */
  74