Module Name:    src
Committed By:   matt
Date:           Wed Aug 17 06:59:29 UTC 2011

Modified Files:
        src/sys/arch/mips/include: mips_opcode.h
        src/sys/arch/mips/mips: mips_emul.c

Log Message:
emulate the special3 opcode LX (lwx, ldx, lhx, lbux) instructions.


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/mips/include/mips_opcode.h
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/mips/mips/mips_emul.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/include/mips_opcode.h
diff -u src/sys/arch/mips/include/mips_opcode.h:1.16 src/sys/arch/mips/include/mips_opcode.h:1.17
--- src/sys/arch/mips/include/mips_opcode.h:1.16	Tue Mar 15 07:33:54 2011
+++ src/sys/arch/mips/include/mips_opcode.h	Wed Aug 17 06:59:28 2011
@@ -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.
  */

Index: src/sys/arch/mips/mips/mips_emul.c
diff -u src/sys/arch/mips/mips/mips_emul.c:1.23 src/sys/arch/mips/mips/mips_emul.c:1.24
--- src/sys/arch/mips/mips/mips_emul.c:1.23	Tue Mar 15 07:39:23 2011
+++ src/sys/arch/mips/mips/mips_emul.c	Wed Aug 17 06:59:29 2011
@@ -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];

Reply via email to