asmlinkage void do_bp(struct pt_regs *regs)
{
+ unsigned long epc = msk_isa16_mode(exception_epc(regs));
unsigned int opcode, bcode;
enum ctx_state prev_state;
- unsigned long epc;
- u16 instr[2];
mm_segment_t seg;
seg = get_fs();
prev_state = exception_enter();
if (get_isa16_mode(regs->cp0_epc)) {
- /* Calculate EPC. */
- epc = exception_epc(regs);
- if (cpu_has_mmips) {
- if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc)) ||
- (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2)))))
- goto out_sigsegv;
- opcode = (instr[0] << 16) | instr[1];
- } else {
+ u16 instr[2];
+
+ if (__get_user(instr[0], (u16 __user *)epc))
+ goto out_sigsegv;
+
+ if (!cpu_has_mmips) {
/* MIPS16e mode */
- if (__get_user(instr[0],
- (u16 __user *)msk_isa16_mode(epc)))
- goto out_sigsegv;
bcode = (instr[0] >> 5) & 0x3f;
- do_trap_or_bp(regs, bcode, "Break");
- goto out;
+ } else if (mm_insn_16bit(instr[0])) {
+ /* 16-bit microMIPS BREAK */
+ bcode = instr[0] & 0xf;
+ } else {
+ /* 32-bit microMIPS BREAK */
+ if (__get_user(instr[1], (u16 __user *)(epc + 2)))
+ goto out_sigsegv;
+ opcode = (instr[0] << 16) | instr[1];
+ bcode = (opcode >> 6) & ((1 << 20) - 1);
}
} else {
- if (__get_user(opcode,
- (unsigned int __user *) exception_epc(regs)))
+ if (__get_user(opcode, (unsigned int __user *)epc))
goto out_sigsegv;
+ bcode = (opcode >> 6) & ((1 << 20) - 1);
}
/*
* Gas is bug-compatible, but not always, grrr...
* We handle both cases with a simple heuristics. --macro
*/
- bcode = ((opcode >> 6) & ((1 << 20) - 1));
if (bcode >= (1 << 10))
bcode >>= 10;