branch.h 1.7 KB

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