Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/mips emulate the special3 opcode LX (lwx, ldx, lhx, ...
details: https://anonhg.NetBSD.org/src/rev/32996fff9fe3
branches: trunk
changeset: 768450:32996fff9fe3
user: matt <matt%NetBSD.org@localhost>
date: Wed Aug 17 06:59:28 2011 +0000
description:
emulate the special3 opcode LX (lwx, ldx, lhx, lbux) instructions.
diffstat:
sys/arch/mips/include/mips_opcode.h | 8 ++++-
sys/arch/mips/mips/mips_emul.c | 58 +++++++++++++++++++++++++++++++++++-
2 files changed, 63 insertions(+), 3 deletions(-)
diffs (110 lines):
diff -r a42682966a82 -r 32996fff9fe3 sys/arch/mips/include/mips_opcode.h
--- a/sys/arch/mips/include/mips_opcode.h Wed Aug 17 05:32:09 2011 +0000
+++ b/sys/arch/mips/include/mips_opcode.h Wed Aug 17 06:59:28 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_opcode.h,v 1.16 2011/03/15 07:33:54 matt Exp $ */
+/* $NetBSD: mips_opcode.h,v 1.17 2011/08/17 06:59:28 matt Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -266,8 +266,14 @@
/*
* Values for the 'func' field when 'op' == OP_SPECIAL3.
*/
+#define OP_LX 012 /* DSP */
#define OP_RDHWR 073 /* MIPS32/64 r2 */
+#define OP_LX_LWX 0 /* lwx */
+#define OP_LX_LHX 4 /* lhx */
+#define OP_LX_LBUX 6 /* lbux */
+#define OP_LX_LDX 8 /* ldx */
+
/*
* Values for the 'func' field when 'op' == OP_BCOND.
*/
diff -r a42682966a82 -r 32996fff9fe3 sys/arch/mips/mips/mips_emul.c
--- a/sys/arch/mips/mips/mips_emul.c Wed Aug 17 05:32:09 2011 +0000
+++ b/sys/arch/mips/mips/mips_emul.c Wed Aug 17 06:59:28 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_emul.c,v 1.23 2011/03/15 07:39:23 matt Exp $ */
+/* $NetBSD: mips_emul.c,v 1.24 2011/08/17 06:59:29 matt Exp $ */
/*
* Copyright (c) 1999 Shuichiro URATA. All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_emul.c,v 1.23 2011/03/15 07:39:23 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_emul.c,v 1.24 2011/08/17 06:59:29 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -399,6 +399,59 @@
ksiginfo_t ksi;
const InstFmt instfmt = { .word = inst };
switch (instfmt.RType.func) {
+ case OP_LX: {
+ const intptr_t vaddr = tf->tf_regs[instfmt.RType.rs]
+ + tf->tf_regs[instfmt.RType.rt];
+ mips_reg_t r;
+ int error = EFAULT;
+ if (vaddr < 0) {
+ addr_err:
+ send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
+ return;
+ }
+ switch (instfmt.RType.shamt) {
+#if !defined(__mips_o32)
+ case OP_LX_LDX: {
+ uint64_t tmp64;
+ if (vaddr & 7)
+ goto addr_err;
+ error = copyin((void *)vaddr, &tmp64, sizeof(tmp64));
+ r = tmp64;
+ break;
+ }
+#endif
+ case OP_LX_LWX: {
+ int32_t tmp32;
+ if (vaddr & 3)
+ goto addr_err;
+ error = copyin((void *)vaddr, &tmp32, sizeof(tmp32));
+ r = tmp32;
+ break;
+ }
+ case OP_LX_LHX: {
+ int16_t tmp16;
+ if (vaddr & 1)
+ goto addr_err;
+ error = copyin((void *)vaddr, &tmp16, sizeof(tmp16));
+ r = tmp16;
+ break;
+ }
+ case OP_LX_LBUX: {
+ uint8_t tmp8;
+ error = copyin((void *)vaddr, &tmp8, sizeof(tmp8));
+ r = tmp8;
+ break;
+ }
+ default:
+ goto illopc;
+ }
+ if (error) {
+ send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
+ return;
+ }
+ tf->tf_regs[instfmt.RType.rd] = r;
+ break;
+ }
case OP_RDHWR:
switch (instfmt.RType.rd) {
case 29:
@@ -407,6 +460,7 @@
break;
}
/* FALLTHROUGH */
+ illopc:
default:
tf->tf_regs[_R_CAUSE] = cause;
tf->tf_regs[_R_BADVADDR] = tf->tf_regs[_R_PC];
Home |
Main Index |
Thread Index |
Old Index