aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPhil Edworthy <Phil.Edworthy@renesas.com>2011-08-24 06:43:59 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-08-29 02:32:10 -0400
commit34f7145a63211eb7ecfcafa6c2a8db5646baf953 (patch)
treedaaa5fe82c1d80c806c6da6cb69cd96218f27072 /arch
parent0710b91c516ffd448db6e80e9026f11778a80d45 (diff)
sh: Add unaligned memory access for PC relative intructions
This adds unaligned memory access support for the following instructions: mov.w @(disp,PC),Rn mov.l @(disp,PC),Rn These instructions are often used on SH2A toolchains. Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/kernel/traps_32.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 61fa4a5bc72b..7bbef95c9d1b 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -316,6 +316,35 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
316 break; 316 break;
317 } 317 }
318 break; 318 break;
319
320 case 9: /* mov.w @(disp,PC),Rn */
321 srcu = (unsigned char __user *)regs->pc;
322 srcu += 4;
323 srcu += (instruction & 0x00FF) << 1;
324 dst = (unsigned char *)rn;
325 *(unsigned long *)dst = 0;
326
327#if !defined(__LITTLE_ENDIAN__)
328 dst += 2;
329#endif
330
331 if (ma->from(dst, srcu, 2))
332 goto fetch_fault;
333 sign_extend(2, dst);
334 ret = 0;
335 break;
336
337 case 0xd: /* mov.l @(disp,PC),Rn */
338 srcu = (unsigned char __user *)(regs->pc & ~0x3);
339 srcu += 4;
340 srcu += (instruction & 0x00FF) << 2;
341 dst = (unsigned char *)rn;
342 *(unsigned long *)dst = 0;
343
344 if (ma->from(dst, srcu, 4))
345 goto fetch_fault;
346 ret = 0;
347 break;
319 } 348 }
320 return ret; 349 return ret;
321 350
@@ -496,6 +525,9 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
496 } 525 }
497 break; 526 break;
498 527
528 case 0x9000: /* mov.w @(disp,Rm),Rn */
529 goto simple;
530
499 case 0xA000: /* bra label */ 531 case 0xA000: /* bra label */
500 ret = handle_delayslot(regs, instruction, ma); 532 ret = handle_delayslot(regs, instruction, ma);
501 if (ret==0) 533 if (ret==0)
@@ -509,6 +541,9 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
509 regs->pc += SH_PC_12BIT_OFFSET(instruction); 541 regs->pc += SH_PC_12BIT_OFFSET(instruction);
510 } 542 }
511 break; 543 break;
544
545 case 0xD000: /* mov.l @(disp,Rm),Rn */
546 goto simple;
512 } 547 }
513 return ret; 548 return ret;
514 549