Lines Matching +full:non +full:- +full:pc
1 // SPDX-License-Identifier: GPL-2.0
9 * Copyright (C) 2002 - 2010 Paul Mundt
81 * - note that PC _may not_ point to the faulting instruction
83 * - return 0 if emulation okay, -EFAULT on existential error
94 rn = ®s->regs[index]; in handle_unaligned_ins()
97 rm = ®s->regs[index]; in handle_unaligned_ins()
108 ret = -EFAULT; in handle_unaligned_ins()
114 srcu += regs->regs[0]; in handle_unaligned_ins()
119 dst += 4-count; in handle_unaligned_ins()
121 if (ma->from(dst, srcu, count)) in handle_unaligned_ins()
129 src += 4-count; in handle_unaligned_ins()
132 dstu += regs->regs[0]; in handle_unaligned_ins()
134 if (ma->to(dstu, src, count)) in handle_unaligned_ins()
145 if (ma->to(dstu, src, 4)) in handle_unaligned_ins()
150 case 2: /* mov.[bwl] to memory, possibly with pre-decrement */ in handle_unaligned_ins()
152 *rn -= count; in handle_unaligned_ins()
156 src += 4-count; in handle_unaligned_ins()
158 if (ma->to(dstu, src, count)) in handle_unaligned_ins()
169 if (ma->from(dst, srcu, 4)) in handle_unaligned_ins()
174 case 6: /* mov.[bwl] from memory, possibly with post-increment */ in handle_unaligned_ins()
182 dst += 4-count; in handle_unaligned_ins()
184 if (ma->from(dst, srcu, count)) in handle_unaligned_ins()
193 src = (unsigned char *) ®s->regs[0]; in handle_unaligned_ins()
200 if (ma->to(dstu, src, 2)) in handle_unaligned_ins()
208 dst = (unsigned char *) ®s->regs[0]; in handle_unaligned_ins()
214 if (ma->from(dst, srcu, 2)) in handle_unaligned_ins()
222 case 9: /* mov.w @(disp,PC),Rn */ in handle_unaligned_ins()
223 srcu = (unsigned char __user *)regs->pc; in handle_unaligned_ins()
233 if (ma->from(dst, srcu, 2)) in handle_unaligned_ins()
239 case 0xd: /* mov.l @(disp,PC),Rn */ in handle_unaligned_ins()
240 srcu = (unsigned char __user *)(regs->pc & ~0x3); in handle_unaligned_ins()
246 if (ma->from(dst, srcu, 4)) in handle_unaligned_ins()
254 /* Argh. Address not only misaligned but also non-existent. in handle_unaligned_ins()
258 return -EFAULT; in handle_unaligned_ins()
263 * - fetches the instruction from PC+2
270 void __user *addr = (void __user *)(regs->pc + in handle_delayslot()
274 /* the instruction-fetch faulted */ in handle_delayslot()
276 return -EFAULT; in handle_delayslot()
279 die("delay-slot-insn faulting in handle_unaligned_delayslot", in handle_delayslot()
288 * - have to be careful of branch delay-slot instructions that fault
290 * - if the branch would be taken PC points to the branch
291 * - if the branch would not be taken, PC points to delay-slot
293 * - PC always points to delayed branch
294 * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
297 /* Macros to determine offset from current PC for branch instructions */
310 * XXX: We can't handle mixed 16/32-bit instructions yet in handle_unaligned_access()
313 return -EINVAL; in handle_unaligned_access()
316 rm = regs->regs[index]; in handle_unaligned_access()
331 ret = -EFAULT; in handle_unaligned_access()
338 regs->pc = regs->pr; in handle_unaligned_access()
344 regs->pc += rm + 4; in handle_unaligned_access()
350 regs->pr = regs->pc + 4; in handle_unaligned_access()
351 regs->pc += rm + 4; in handle_unaligned_access()
363 case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */ in handle_unaligned_access()
371 regs->pc = rm; in handle_unaligned_access()
377 regs->pr = regs->pc + 4; in handle_unaligned_access()
378 regs->pc = rm; in handle_unaligned_access()
390 case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */ in handle_unaligned_access()
399 case 0x0B00: /* bf lab - no delayslot*/ in handle_unaligned_access()
406 if ((regs->sr & 0x00000001) != 0) in handle_unaligned_access()
407 regs->pc += 4; /* next after slot */ in handle_unaligned_access()
410 regs->pc += SH_PC_8BIT_OFFSET(instruction); in handle_unaligned_access()
413 case 0x0900: /* bt lab - no delayslot */ in handle_unaligned_access()
420 if ((regs->sr & 0x00000001) == 0) in handle_unaligned_access()
421 regs->pc += 4; /* next after slot */ in handle_unaligned_access()
424 regs->pc += SH_PC_8BIT_OFFSET(instruction); in handle_unaligned_access()
436 regs->pc += SH_PC_12BIT_OFFSET(instruction); in handle_unaligned_access()
442 regs->pr = regs->pc + 4; in handle_unaligned_access()
443 regs->pc += SH_PC_12BIT_OFFSET(instruction); in handle_unaligned_access()
452 /* handle non-delay-slot instruction */ in handle_unaligned_access()
456 regs->pc += instruction_size(instruction); in handle_unaligned_access()
462 * - instruction address error:
463 * misaligned PC
464 * PC >= 0x80000000 in user mode
465 * - data address error (read and write)
493 if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1), in do_address_error()
510 regs->pc += instruction_size(instruction); in do_address_error()
515 /* bad PC is not something we can fix */ in do_address_error()
516 if (regs->pc & 1) { in do_address_error()
531 "access (PC %lx PR %lx)\n", current->comm, regs->pc, in do_address_error()
532 regs->pr); in do_address_error()
538 if (regs->pc & 1) in do_address_error()
542 if (copy_from_user(&instruction, (void __user *)(regs->pc), in do_address_error()
545 This should never happen non-SMP in do_address_error()
561 * SH-DSP support gerg@snapgear.com.
571 if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) in is_dsp_inst()
574 get_user(inst, ((unsigned short *) regs->pc)); in is_dsp_inst()
617 get_user(inst, (unsigned short*)regs->pc); in do_reserved_inst()
621 regs->pc += instruction_size(inst); in do_reserved_inst()
631 regs->sr |= SR_DSP; in do_reserved_inst()
633 current->thread.dsp_status.status |= SR_DSP; in do_reserved_inst()
649 * bfs: 8fxx: PC+=d*2+4; in emulate_branch()
650 * bts: 8dxx: PC+=d*2+4; in emulate_branch()
651 * bra: axxx: PC+=D*2+4; in emulate_branch()
652 * bsr: bxxx: PC+=D*2+4 after PR=PC+4; in emulate_branch()
653 * braf:0x23: PC+=Rn*2+4; in emulate_branch()
654 * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4; in emulate_branch()
655 * jmp: 4x2b: PC=Rn; in emulate_branch()
656 * jsr: 4x0b: PC=Rn after PR=PC+4; in emulate_branch()
657 * rts: 000b: PC=PR; in emulate_branch()
662 regs->pr = regs->pc + 4; in emulate_branch()
665 regs->pc += SH_PC_8BIT_OFFSET(inst); in emulate_branch()
670 regs->pc += SH_PC_12BIT_OFFSET(inst); in emulate_branch()
675 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; in emulate_branch()
680 regs->pc = regs->regs[(inst & 0x0f00) >> 8]; in emulate_branch()
685 regs->pc = regs->pr; in emulate_branch()
698 if (kprobe_handle_illslot(regs->pc) == 0) in do_illegal_slot_inst()
702 get_user(inst, (unsigned short *)regs->pc + 1); in do_illegal_slot_inst()
704 get_user(inst, (unsigned short *)regs->pc); in do_illegal_slot_inst()
762 * For SH-4 lacking an FPU, treat floating point instructions as in trap_init()
763 * reserved. They'll be handled in the math-emu case, or faulted on in trap_init()