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
6 * Copyright (C) 1996, 97, 2000, 2001 by Ralf Baechle
7 * Copyright (C) 2001 MIPS Technologies, Inc.
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/signal.h>
12 #include <linux/module.h>
13 #include <asm/branch.h>
15 #include <asm/cpu-features.h>
17 #include <asm/fpu_emulator.h>
19 #include <asm/ptrace.h>
20 #include <asm/uaccess.h>
23 * Calculate and return exception PC in case of branch delay
24 * slot for microMIPS. It does not clear the ISA mode bit.
26 int __isa_exception_epc(struct pt_regs
*regs
)
28 long epc
= regs
->cp0_epc
;
31 /* Calculate exception PC in branch delay slot. */
32 if (__get_user(inst
, (u16 __user
*) msk_isa16_mode(epc
))) {
33 /* This should never happen because delay slot was checked. */
34 force_sig(SIGSEGV
, current
);
38 if (mm_insn_16bit(inst
))
47 * Compute return address and emulate branch in microMIPS mode after an
48 * exception only. It does not handle compact branches/jumps and cannot
49 * be used in interrupt context. (Compact branches/jumps do not cause
52 int __microMIPS_compute_return_epc(struct pt_regs
*regs
)
58 struct mm_decoded_insn mminsn
= { 0 };
60 mminsn
.micro_mips_mode
= 1;
62 /* This load never faults. */
63 pc16
= (unsigned short __user
*)msk_isa16_mode(regs
->cp0_epc
);
64 __get_user(halfword
, pc16
);
66 contpc
= regs
->cp0_epc
+ 2;
67 word
= ((unsigned int)halfword
<< 16);
70 if (!mm_insn_16bit(halfword
)) {
71 __get_user(halfword
, pc16
);
73 contpc
= regs
->cp0_epc
+ 4;
79 if (get_user(halfword
, pc16
))
81 mminsn
.next_pc_inc
= 2;
82 word
= ((unsigned int)halfword
<< 16);
84 if (!mm_insn_16bit(halfword
)) {
86 if (get_user(halfword
, pc16
))
88 mminsn
.next_pc_inc
= 4;
91 mminsn
.next_insn
= word
;
93 mm_isBranchInstr(regs
, mminsn
, &contpc
);
95 regs
->cp0_epc
= contpc
;
100 force_sig(SIGSEGV
, current
);
105 * __compute_return_epc_for_insn - Computes the return address and do emulate
106 * branch simulation, if required.
108 * @regs: Pointer to pt_regs
109 * @insn: branch instruction to decode
110 * @returns: -EFAULT on error and forces SIGBUS, and on success
111 * returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
112 * evaluating the branch.
114 int __compute_return_epc_for_insn(struct pt_regs
*regs
,
115 union mips_instruction insn
)
117 unsigned int bit
, fcr31
, dspcontrol
;
118 long epc
= regs
->cp0_epc
;
121 switch (insn
.i_format
.opcode
) {
123 * jr and jalr are in r_format format.
126 switch (insn
.r_format
.func
) {
128 regs
->regs
[insn
.r_format
.rd
] = epc
+ 8;
131 regs
->cp0_epc
= regs
->regs
[insn
.r_format
.rs
];
137 * This group contains:
138 * bltz_op, bgez_op, bltzl_op, bgezl_op,
139 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
142 switch (insn
.i_format
.rt
) {
145 if ((long)regs
->regs
[insn
.i_format
.rs
] < 0) {
146 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
147 if (insn
.i_format
.rt
== bltzl_op
)
148 ret
= BRANCH_LIKELY_TAKEN
;
156 if ((long)regs
->regs
[insn
.i_format
.rs
] >= 0) {
157 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
158 if (insn
.i_format
.rt
== bgezl_op
)
159 ret
= BRANCH_LIKELY_TAKEN
;
167 regs
->regs
[31] = epc
+ 8;
168 if ((long)regs
->regs
[insn
.i_format
.rs
] < 0) {
169 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
170 if (insn
.i_format
.rt
== bltzall_op
)
171 ret
= BRANCH_LIKELY_TAKEN
;
179 regs
->regs
[31] = epc
+ 8;
180 if ((long)regs
->regs
[insn
.i_format
.rs
] >= 0) {
181 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
182 if (insn
.i_format
.rt
== bgezall_op
)
183 ret
= BRANCH_LIKELY_TAKEN
;
193 dspcontrol
= rddsp(0x01);
195 if (dspcontrol
>= 32) {
196 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
205 * These are unconditional and in j_format.
208 regs
->regs
[31] = regs
->cp0_epc
+ 8;
213 epc
|= (insn
.j_format
.target
<< 2);
215 if (insn
.i_format
.opcode
== jalx_op
)
216 set_isa16_mode(regs
->cp0_epc
);
220 * These are conditional and in i_format.
224 if (regs
->regs
[insn
.i_format
.rs
] ==
225 regs
->regs
[insn
.i_format
.rt
]) {
226 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
227 if (insn
.i_format
.rt
== beql_op
)
228 ret
= BRANCH_LIKELY_TAKEN
;
236 if (regs
->regs
[insn
.i_format
.rs
] !=
237 regs
->regs
[insn
.i_format
.rt
]) {
238 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
239 if (insn
.i_format
.rt
== bnel_op
)
240 ret
= BRANCH_LIKELY_TAKEN
;
246 case blez_op
: /* not really i_format */
248 /* rt field assumed to be zero */
249 if ((long)regs
->regs
[insn
.i_format
.rs
] <= 0) {
250 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
251 if (insn
.i_format
.rt
== bnel_op
)
252 ret
= BRANCH_LIKELY_TAKEN
;
260 /* rt field assumed to be zero */
261 if ((long)regs
->regs
[insn
.i_format
.rs
] > 0) {
262 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
263 if (insn
.i_format
.rt
== bnel_op
)
264 ret
= BRANCH_LIKELY_TAKEN
;
271 * And now the FPA/cp1 branch instructions.
276 asm volatile("cfc1\t%0,$31" : "=r" (fcr31
));
278 fcr31
= current
->thread
.fpu
.fcr31
;
281 bit
= (insn
.i_format
.rt
>> 2);
284 switch (insn
.i_format
.rt
& 3) {
287 if (~fcr31
& (1 << bit
)) {
288 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
289 if (insn
.i_format
.rt
== 2)
290 ret
= BRANCH_LIKELY_TAKEN
;
298 if (fcr31
& (1 << bit
)) {
299 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
300 if (insn
.i_format
.rt
== 3)
301 ret
= BRANCH_LIKELY_TAKEN
;
308 #ifdef CONFIG_CPU_CAVIUM_OCTEON
309 case lwc2_op
: /* This is bbit0 on Octeon */
310 if ((regs
->regs
[insn
.i_format
.rs
] & (1ull<<insn
.i_format
.rt
))
312 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
317 case ldc2_op
: /* This is bbit032 on Octeon */
318 if ((regs
->regs
[insn
.i_format
.rs
] &
319 (1ull<<(insn
.i_format
.rt
+32))) == 0)
320 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
325 case swc2_op
: /* This is bbit1 on Octeon */
326 if (regs
->regs
[insn
.i_format
.rs
] & (1ull<<insn
.i_format
.rt
))
327 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
332 case sdc2_op
: /* This is bbit132 on Octeon */
333 if (regs
->regs
[insn
.i_format
.rs
] &
334 (1ull<<(insn
.i_format
.rt
+32)))
335 epc
= epc
+ 4 + (insn
.i_format
.simmediate
<< 2);
346 printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current
->comm
);
347 force_sig(SIGBUS
, current
);
350 EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn
);
352 int __compute_return_epc(struct pt_regs
*regs
)
354 unsigned int __user
*addr
;
356 union mips_instruction insn
;
363 * Read the instruction
365 addr
= (unsigned int __user
*) epc
;
366 if (__get_user(insn
.word
, addr
)) {
367 force_sig(SIGSEGV
, current
);
371 return __compute_return_epc_for_insn(regs
, insn
);
374 printk("%s: unaligned epc - sending SIGBUS.\n", current
->comm
);
375 force_sig(SIGBUS
, current
);