Lines Matching +full:non +full:- +full:pc

1 // SPDX-License-Identifier: GPL-2.0
9 * Copyright (C) 2002 - 2010 Paul Mundt
98 * - note that PC _may not_ point to the faulting instruction
100 * - return 0 if emulation okay, -EFAULT on existential error
111 rn = &regs->regs[index]; in handle_unaligned_ins()
114 rm = &regs->regs[index]; in handle_unaligned_ins()
125 ret = -EFAULT; in handle_unaligned_ins()
131 srcu += regs->regs[0]; in handle_unaligned_ins()
136 dst += 4-count; in handle_unaligned_ins()
138 if (ma->from(dst, srcu, count)) in handle_unaligned_ins()
146 src += 4-count; in handle_unaligned_ins()
149 dstu += regs->regs[0]; in handle_unaligned_ins()
151 if (ma->to(dstu, src, count)) in handle_unaligned_ins()
162 if (ma->to(dstu, src, 4)) in handle_unaligned_ins()
167 case 2: /* mov.[bwl] to memory, possibly with pre-decrement */ in handle_unaligned_ins()
169 *rn -= count; in handle_unaligned_ins()
173 src += 4-count; in handle_unaligned_ins()
175 if (ma->to(dstu, src, count)) in handle_unaligned_ins()
186 if (ma->from(dst, srcu, 4)) in handle_unaligned_ins()
191 case 6: /* mov.[bwl] from memory, possibly with post-increment */ in handle_unaligned_ins()
199 dst += 4-count; in handle_unaligned_ins()
201 if (ma->from(dst, srcu, count)) in handle_unaligned_ins()
210 src = (unsigned char *) &regs->regs[0]; in handle_unaligned_ins()
217 if (ma->to(dstu, src, 2)) in handle_unaligned_ins()
225 dst = (unsigned char *) &regs->regs[0]; in handle_unaligned_ins()
231 if (ma->from(dst, srcu, 2)) in handle_unaligned_ins()
239 case 9: /* mov.w @(disp,PC),Rn */ in handle_unaligned_ins()
240 srcu = (unsigned char __user *)regs->pc; in handle_unaligned_ins()
250 if (ma->from(dst, srcu, 2)) in handle_unaligned_ins()
256 case 0xd: /* mov.l @(disp,PC),Rn */ in handle_unaligned_ins()
257 srcu = (unsigned char __user *)(regs->pc & ~0x3); in handle_unaligned_ins()
263 if (ma->from(dst, srcu, 4)) in handle_unaligned_ins()
271 /* Argh. Address not only misaligned but also non-existent. in handle_unaligned_ins()
275 return -EFAULT; in handle_unaligned_ins()
280 * - fetches the instruction from PC+2
287 void __user *addr = (void __user *)(regs->pc + in handle_delayslot()
291 /* the instruction-fetch faulted */ in handle_delayslot()
293 return -EFAULT; in handle_delayslot()
296 die("delay-slot-insn faulting in handle_unaligned_delayslot", in handle_delayslot()
305 * - have to be careful of branch delay-slot instructions that fault
307 * - if the branch would be taken PC points to the branch
308 * - if the branch would not be taken, PC points to delay-slot
310 * - PC always points to delayed branch
311 * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
314 /* Macros to determine offset from current PC for branch instructions */
327 * XXX: We can't handle mixed 16/32-bit instructions yet in handle_unaligned_access()
330 return -EINVAL; in handle_unaligned_access()
333 rm = regs->regs[index]; in handle_unaligned_access()
348 ret = -EFAULT; in handle_unaligned_access()
355 regs->pc = regs->pr; in handle_unaligned_access()
361 regs->pc += rm + 4; in handle_unaligned_access()
367 regs->pr = regs->pc + 4; in handle_unaligned_access()
368 regs->pc += rm + 4; in handle_unaligned_access()
380 case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */ in handle_unaligned_access()
388 regs->pc = rm; in handle_unaligned_access()
394 regs->pr = regs->pc + 4; in handle_unaligned_access()
395 regs->pc = rm; in handle_unaligned_access()
407 case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */ in handle_unaligned_access()
416 case 0x0B00: /* bf lab - no delayslot*/ in handle_unaligned_access()
423 if ((regs->sr & 0x00000001) != 0) in handle_unaligned_access()
424 regs->pc += 4; /* next after slot */ in handle_unaligned_access()
427 regs->pc += SH_PC_8BIT_OFFSET(instruction); in handle_unaligned_access()
430 case 0x0900: /* bt lab - no delayslot */ in handle_unaligned_access()
437 if ((regs->sr & 0x00000001) == 0) in handle_unaligned_access()
438 regs->pc += 4; /* next after slot */ in handle_unaligned_access()
441 regs->pc += SH_PC_8BIT_OFFSET(instruction); in handle_unaligned_access()
453 regs->pc += SH_PC_12BIT_OFFSET(instruction); in handle_unaligned_access()
459 regs->pr = regs->pc + 4; in handle_unaligned_access()
460 regs->pc += SH_PC_12BIT_OFFSET(instruction); in handle_unaligned_access()
469 /* handle non-delay-slot instruction */ in handle_unaligned_access()
473 regs->pc += instruction_size(instruction); in handle_unaligned_access()
479 * - instruction address error:
480 * misaligned PC
481 * PC >= 0x80000000 in user mode
482 * - data address error (read and write)
508 if (copy_from_user(&instruction, (insn_size_t __user *)(regs->pc & ~1), in do_address_error()
523 regs->pc += instruction_size(instruction); in do_address_error()
528 /* bad PC is not something we can fix */ in do_address_error()
529 if (regs->pc & 1) { in do_address_error()
542 "access (PC %lx PR %lx)\n", current->comm, regs->pc, in do_address_error()
543 regs->pr); in do_address_error()
549 if (regs->pc & 1) in do_address_error()
552 if (copy_from_kernel_nofault(&instruction, (void *)(regs->pc), in do_address_error()
555 This should never happen non-SMP in do_address_error()
569 * SH-DSP support gerg@snapgear.com.
579 if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) in is_dsp_inst()
582 get_user(inst, ((unsigned short *) regs->pc)); in is_dsp_inst()
625 get_user(inst, (unsigned short __user *)regs->pc); in do_reserved_inst()
629 regs->pc += instruction_size(inst); in do_reserved_inst()
639 regs->sr |= SR_DSP; in do_reserved_inst()
641 current->thread.dsp_status.status |= SR_DSP; in do_reserved_inst()
657 * bfs: 8fxx: PC+=d*2+4; in emulate_branch()
658 * bts: 8dxx: PC+=d*2+4; in emulate_branch()
659 * bra: axxx: PC+=D*2+4; in emulate_branch()
660 * bsr: bxxx: PC+=D*2+4 after PR=PC+4; in emulate_branch()
661 * braf:0x23: PC+=Rn*2+4; in emulate_branch()
662 * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4; in emulate_branch()
663 * jmp: 4x2b: PC=Rn; in emulate_branch()
664 * jsr: 4x0b: PC=Rn after PR=PC+4; in emulate_branch()
665 * rts: 000b: PC=PR; in emulate_branch()
670 regs->pr = regs->pc + 4; in emulate_branch()
673 regs->pc += SH_PC_8BIT_OFFSET(inst); in emulate_branch()
678 regs->pc += SH_PC_12BIT_OFFSET(inst); in emulate_branch()
683 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; in emulate_branch()
688 regs->pc = regs->regs[(inst & 0x0f00) >> 8]; in emulate_branch()
693 regs->pc = regs->pr; in emulate_branch()
706 if (kprobe_handle_illslot(regs->pc) == 0) in do_illegal_slot_inst()
710 get_user(inst, (unsigned short __user *)regs->pc + 1); in do_illegal_slot_inst()
712 get_user(inst, (unsigned short __user *)regs->pc); in do_illegal_slot_inst()
770 * For SH-4 lacking an FPU, treat floating point instructions as in trap_init()
771 * reserved. They'll be handled in the math-emu case, or faulted on in trap_init()