1384740dcSRalf Baechle /*
2384740dcSRalf Baechle * This file is subject to the terms and conditions of the GNU General Public
3384740dcSRalf Baechle * License. See the file "COPYING" in the main directory of this archive
4384740dcSRalf Baechle * for more details.
5384740dcSRalf Baechle *
6384740dcSRalf Baechle * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle
7384740dcSRalf Baechle */
8384740dcSRalf Baechle #ifndef _ASM_BRANCH_H
9384740dcSRalf Baechle #define _ASM_BRANCH_H
10384740dcSRalf Baechle
115160d45dSRalf Baechle #include <asm/cpu-features.h>
125160d45dSRalf Baechle #include <asm/mipsregs.h>
13384740dcSRalf Baechle #include <asm/ptrace.h>
14d8d4e3aeSManeesh Soni #include <asm/inst.h>
15384740dcSRalf Baechle
16fb6883e5SLeonid Yegoshin extern int __isa_exception_epc(struct pt_regs *regs);
17fb6883e5SLeonid Yegoshin extern int __compute_return_epc(struct pt_regs *regs);
18fb6883e5SLeonid Yegoshin extern int __compute_return_epc_for_insn(struct pt_regs *regs,
19fb6883e5SLeonid Yegoshin union mips_instruction insn);
20fb6883e5SLeonid Yegoshin extern int __microMIPS_compute_return_epc(struct pt_regs *regs);
218508488fSSteven J. Hill extern int __MIPS16e_compute_return_epc(struct pt_regs *regs);
22fb6883e5SLeonid Yegoshin
2376fbfc31SRalf Baechle /*
2476fbfc31SRalf Baechle * microMIPS bitfields
2576fbfc31SRalf Baechle */
2676fbfc31SRalf Baechle #define MM_POOL32A_MINOR_MASK 0x3f
2776fbfc31SRalf Baechle #define MM_POOL32A_MINOR_SHIFT 0x6
2876fbfc31SRalf Baechle #define MM_MIPS32_COND_FC 0x30
2976fbfc31SRalf Baechle
30*c05b5940SHuacai Chen int isBranchInstr(struct pt_regs *regs,
31*c05b5940SHuacai Chen struct mm_decoded_insn dec_insn, unsigned long *contpc);
32*c05b5940SHuacai Chen
3376fbfc31SRalf Baechle extern int __mm_isBranchInstr(struct pt_regs *regs,
3476fbfc31SRalf Baechle struct mm_decoded_insn dec_insn, unsigned long *contpc);
3576fbfc31SRalf Baechle
mm_isBranchInstr(struct pt_regs * regs,struct mm_decoded_insn dec_insn,unsigned long * contpc)3676fbfc31SRalf Baechle static inline int mm_isBranchInstr(struct pt_regs *regs,
3776fbfc31SRalf Baechle struct mm_decoded_insn dec_insn, unsigned long *contpc)
3876fbfc31SRalf Baechle {
3976fbfc31SRalf Baechle if (!cpu_has_mmips)
4076fbfc31SRalf Baechle return 0;
4176fbfc31SRalf Baechle
4276fbfc31SRalf Baechle return __mm_isBranchInstr(regs, dec_insn, contpc);
4376fbfc31SRalf Baechle }
44fb6883e5SLeonid Yegoshin
delay_slot(struct pt_regs * regs)45384740dcSRalf Baechle static inline int delay_slot(struct pt_regs *regs)
46384740dcSRalf Baechle {
47384740dcSRalf Baechle return regs->cp0_cause & CAUSEF_BD;
48384740dcSRalf Baechle }
49384740dcSRalf Baechle
clear_delay_slot(struct pt_regs * regs)505a7ebbf8SRalf Baechle static inline void clear_delay_slot(struct pt_regs *regs)
515a7ebbf8SRalf Baechle {
525a7ebbf8SRalf Baechle regs->cp0_cause &= ~CAUSEF_BD;
535a7ebbf8SRalf Baechle }
545a7ebbf8SRalf Baechle
set_delay_slot(struct pt_regs * regs)555a7ebbf8SRalf Baechle static inline void set_delay_slot(struct pt_regs *regs)
565a7ebbf8SRalf Baechle {
575a7ebbf8SRalf Baechle regs->cp0_cause |= CAUSEF_BD;
585a7ebbf8SRalf Baechle }
595a7ebbf8SRalf Baechle
exception_epc(struct pt_regs * regs)60384740dcSRalf Baechle static inline unsigned long exception_epc(struct pt_regs *regs)
61384740dcSRalf Baechle {
62fb6883e5SLeonid Yegoshin if (likely(!delay_slot(regs)))
63384740dcSRalf Baechle return regs->cp0_epc;
64384740dcSRalf Baechle
65fb6883e5SLeonid Yegoshin if (get_isa16_mode(regs->cp0_epc))
66fb6883e5SLeonid Yegoshin return __isa_exception_epc(regs);
67fb6883e5SLeonid Yegoshin
68384740dcSRalf Baechle return regs->cp0_epc + 4;
69384740dcSRalf Baechle }
70384740dcSRalf Baechle
71d8d4e3aeSManeesh Soni #define BRANCH_LIKELY_TAKEN 0x0001
72d8d4e3aeSManeesh Soni
compute_return_epc(struct pt_regs * regs)73384740dcSRalf Baechle static inline int compute_return_epc(struct pt_regs *regs)
74384740dcSRalf Baechle {
75fb6883e5SLeonid Yegoshin if (get_isa16_mode(regs->cp0_epc)) {
76fb6883e5SLeonid Yegoshin if (cpu_has_mmips)
77fb6883e5SLeonid Yegoshin return __microMIPS_compute_return_epc(regs);
788508488fSSteven J. Hill if (cpu_has_mips16)
798508488fSSteven J. Hill return __MIPS16e_compute_return_epc(regs);
8011a3799dSMaciej W. Rozycki } else if (!delay_slot(regs)) {
81384740dcSRalf Baechle regs->cp0_epc += 4;
82384740dcSRalf Baechle return 0;
83384740dcSRalf Baechle }
84384740dcSRalf Baechle
85384740dcSRalf Baechle return __compute_return_epc(regs);
86384740dcSRalf Baechle }
87384740dcSRalf Baechle
MIPS16e_compute_return_epc(struct pt_regs * regs,union mips16e_instruction * inst)888508488fSSteven J. Hill static inline int MIPS16e_compute_return_epc(struct pt_regs *regs,
898508488fSSteven J. Hill union mips16e_instruction *inst)
908508488fSSteven J. Hill {
918508488fSSteven J. Hill if (likely(!delay_slot(regs))) {
928508488fSSteven J. Hill if (inst->ri.opcode == MIPS16e_extend_op) {
938508488fSSteven J. Hill regs->cp0_epc += 4;
948508488fSSteven J. Hill return 0;
958508488fSSteven J. Hill }
968508488fSSteven J. Hill regs->cp0_epc += 2;
978508488fSSteven J. Hill return 0;
988508488fSSteven J. Hill }
998508488fSSteven J. Hill
1008508488fSSteven J. Hill return __MIPS16e_compute_return_epc(regs);
1018508488fSSteven J. Hill }
1028508488fSSteven J. Hill
103384740dcSRalf Baechle #endif /* _ASM_BRANCH_H */
104