Lines Matching +full:non +full:- +full:pc
1 // SPDX-License-Identifier: GPL-2.0
9 * Copyright (C) 2002 - 2010 Paul Mundt
99 * - note that PC _may not_ point to the faulting instruction
101 * - return 0 if emulation okay, -EFAULT on existential error
112 rn = ®s->regs[index]; in handle_unaligned_ins()
115 rm = ®s->regs[index]; in handle_unaligned_ins()
126 ret = -EFAULT; in handle_unaligned_ins()
132 srcu += regs->regs[0]; in handle_unaligned_ins()
137 dst += 4-count; in handle_unaligned_ins()
139 if (ma->from(dst, srcu, count)) in handle_unaligned_ins()
147 src += 4-count; in handle_unaligned_ins()
150 dstu += regs->regs[0]; in handle_unaligned_ins()
152 if (ma->to(dstu, src, count)) in handle_unaligned_ins()
163 if (ma->to(dstu, src, 4)) in handle_unaligned_ins()
168 case 2: /* mov.[bwl] to memory, possibly with pre-decrement */ in handle_unaligned_ins()
170 *rn -= count; in handle_unaligned_ins()
174 src += 4-count; in handle_unaligned_ins()
176 if (ma->to(dstu, src, count)) in handle_unaligned_ins()
187 if (ma->from(dst, srcu, 4)) in handle_unaligned_ins()
192 case 6: /* mov.[bwl] from memory, possibly with post-increment */ in handle_unaligned_ins()
200 dst += 4-count; in handle_unaligned_ins()
202 if (ma->from(dst, srcu, count)) in handle_unaligned_ins()
211 src = (unsigned char *) ®s->regs[0]; in handle_unaligned_ins()
218 if (ma->to(dstu, src, 2)) in handle_unaligned_ins()
226 dst = (unsigned char *) ®s->regs[0]; in handle_unaligned_ins()
232 if (ma->from(dst, srcu, 2)) in handle_unaligned_ins()
240 case 9: /* mov.w @(disp,PC),Rn */ in handle_unaligned_ins()
241 srcu = (unsigned char __user *)regs->pc; in handle_unaligned_ins()
251 if (ma->from(dst, srcu, 2)) in handle_unaligned_ins()
257 case 0xd: /* mov.l @(disp,PC),Rn */ in handle_unaligned_ins()
258 srcu = (unsigned char __user *)(regs->pc & ~0x3); in handle_unaligned_ins()
264 if (ma->from(dst, srcu, 4)) in handle_unaligned_ins()
272 /* Argh. Address not only misaligned but also non-existent. in handle_unaligned_ins()
276 return -EFAULT; in handle_unaligned_ins()
281 * - fetches the instruction from PC+2
288 void __user *addr = (void __user *)(regs->pc + in handle_delayslot()
292 /* the instruction-fetch faulted */ in handle_delayslot()
294 return -EFAULT; in handle_delayslot()
297 die("delay-slot-insn faulting in handle_unaligned_delayslot", in handle_delayslot()
306 * - have to be careful of branch delay-slot instructions that fault
308 * - if the branch would be taken PC points to the branch
309 * - if the branch would not be taken, PC points to delay-slot
311 * - PC always points to delayed branch
312 * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
315 /* Macros to determine offset from current PC for branch instructions */
328 * XXX: We can't handle mixed 16/32-bit instructions yet in handle_unaligned_access()
331 return -EINVAL; in handle_unaligned_access()
334 rm = regs->regs[index]; in handle_unaligned_access()
349 ret = -EFAULT; in handle_unaligned_access()
356 regs->pc = regs->pr; in handle_unaligned_access()
362 regs->pc += rm + 4; in handle_unaligned_access()
368 regs->pr = regs->pc + 4; in handle_unaligned_access()
369 regs->pc += rm + 4; in handle_unaligned_access()
381 case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */ in handle_unaligned_access()
389 regs->pc = rm; in handle_unaligned_access()
395 regs->pr = regs->pc + 4; in handle_unaligned_access()
396 regs->pc = rm; in handle_unaligned_access()
408 case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */ in handle_unaligned_access()
417 case 0x0B00: /* bf lab - no delayslot*/ in handle_unaligned_access()
424 if ((regs->sr & 0x00000001) != 0) in handle_unaligned_access()
425 regs->pc += 4; /* next after slot */ in handle_unaligned_access()
428 regs->pc += SH_PC_8BIT_OFFSET(instruction); in handle_unaligned_access()
431 case 0x0900: /* bt lab - no delayslot */ in handle_unaligned_access()
438 if ((regs->sr & 0x00000001) == 0) in handle_unaligned_access()
439 regs->pc += 4; /* next after slot */ in handle_unaligned_access()
442 regs->pc += SH_PC_8BIT_OFFSET(instruction); in handle_unaligned_access()
454 regs->pc += SH_PC_12BIT_OFFSET(instruction); in handle_unaligned_access()
460 regs->pr = regs->pc + 4; in handle_unaligned_access()
461 regs->pc += SH_PC_12BIT_OFFSET(instruction); in handle_unaligned_access()
470 /* handle non-delay-slot instruction */ in handle_unaligned_access()
474 regs->pc += instruction_size(instruction); in handle_unaligned_access()
480 * - instruction address error:
481 * misaligned PC
482 * PC >= 0x80000000 in user mode
483 * - data address error (read and write)
509 if (copy_from_user(&instruction, (insn_size_t __user *)(regs->pc & ~1), in do_address_error()
524 regs->pc += instruction_size(instruction); in do_address_error()
529 /* bad PC is not something we can fix */ in do_address_error()
530 if (regs->pc & 1) { in do_address_error()
543 "access (PC %lx PR %lx)\n", current->comm, regs->pc, in do_address_error()
544 regs->pr); in do_address_error()
550 if (regs->pc & 1) in do_address_error()
553 if (copy_from_kernel_nofault(&instruction, (void *)(regs->pc), in do_address_error()
556 This should never happen non-SMP in do_address_error()
570 * SH-DSP support [email protected].
580 if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) in is_dsp_inst()
583 get_user(inst, ((unsigned short *) regs->pc)); in is_dsp_inst()
626 get_user(inst, (unsigned short __user *)regs->pc); in do_reserved_inst()
630 regs->pc += instruction_size(inst); in do_reserved_inst()
640 regs->sr |= SR_DSP; in do_reserved_inst()
642 current->thread.dsp_status.status |= SR_DSP; in do_reserved_inst()
658 * bfs: 8fxx: PC+=d*2+4; in emulate_branch()
659 * bts: 8dxx: PC+=d*2+4; in emulate_branch()
660 * bra: axxx: PC+=D*2+4; in emulate_branch()
661 * bsr: bxxx: PC+=D*2+4 after PR=PC+4; in emulate_branch()
662 * braf:0x23: PC+=Rn*2+4; in emulate_branch()
663 * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4; in emulate_branch()
664 * jmp: 4x2b: PC=Rn; in emulate_branch()
665 * jsr: 4x0b: PC=Rn after PR=PC+4; in emulate_branch()
666 * rts: 000b: PC=PR; in emulate_branch()
671 regs->pr = regs->pc + 4; in emulate_branch()
674 regs->pc += SH_PC_8BIT_OFFSET(inst); in emulate_branch()
679 regs->pc += SH_PC_12BIT_OFFSET(inst); in emulate_branch()
684 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; in emulate_branch()
689 regs->pc = regs->regs[(inst & 0x0f00) >> 8]; in emulate_branch()
694 regs->pc = regs->pr; in emulate_branch()
707 if (kprobe_handle_illslot(regs->pc) == 0) in do_illegal_slot_inst()
711 get_user(inst, (unsigned short __user *)regs->pc + 1); in do_illegal_slot_inst()
713 get_user(inst, (unsigned short __user *)regs->pc); in do_illegal_slot_inst()
771 * For SH-4 lacking an FPU, treat floating point instructions as in trap_init()
772 * reserved. They'll be handled in the math-emu case, or faulted on in trap_init()