Module Name:    src
Committed By:   matt
Date:           Tue Dec 18 06:31:58 UTC 2012

Modified Files:
        src/sys/arch/arm/arm: disassem.c

Log Message:
Start adding support for disassembling some NEON instructions.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/arm/arm/disassem.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/arm/arm/disassem.c
diff -u src/sys/arch/arm/arm/disassem.c:1.19 src/sys/arch/arm/arm/disassem.c:1.20
--- src/sys/arch/arm/arm/disassem.c:1.19	Thu Feb 16 02:34:56 2012
+++ src/sys/arch/arm/arm/disassem.c	Tue Dec 18 06:31:58 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: disassem.c,v 1.19 2012/02/16 02:34:56 christos Exp $	*/
+/*	$NetBSD: disassem.c,v 1.20 2012/12/18 06:31:58 matt Exp $	*/
 
 /*
  * Copyright (c) 1996 Mark Brinicombe.
@@ -49,7 +49,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: disassem.c,v 1.19 2012/02/16 02:34:56 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: disassem.c,v 1.20 2012/12/18 06:31:58 matt Exp $");
 
 #include <sys/systm.h>
 #include <arch/arm/arm/disassem.h>
@@ -71,36 +71,42 @@ __KERNEL_RCSID(0, "$NetBSD: disassem.c,v
  *
  *
  * 2 - print Operand 2 of a data processing instruction
- * d - destination register (bits 12-15)
- * n - n register (bits 16-19)
- * s - s register (bits 8-11)
- * o - indirect register rn (bits 16-19) (used by swap)
- * m - m register (bits 0-3)
  * a - address operand of ldr/str instruction
- * l - register list for ldm/stm instruction
+ * b - branch address
+ * c - comment field bits(0-23)
+ * d - destination register (bits 12-15)
  * f - 1st fp operand (register) (bits 12-14)
  * g - 2nd fp operand (register) (bits 16-18)
  * h - 3rd fp operand (register/immediate) (bits 0-4)
- * b - branch address
- * t - thumb branch address (bits 24, 0-23)
  * k - breakpoint comment (bits 0-3, 8-19)
- * X - block transfer type
- * Y - block transfer type (r13 base)
- * c - comment field bits(0-23)
+ * l - register list for ldm/stm instruction
+ * m - m register (bits 0-3)
+ * n - n register (bits 16-19)
+ * o - indirect register rn (bits 16-19) (used by swap)
  * p - saved or current status register
- * F - PSR transfer fields
+ * q - neon N register (7, 19-16)
+ * s - s register (bits 8-11)
+ * t - thumb branch address (bits 24, 0-23)
+ * u - neon M register (5, 3-0)
+ * v - co-processor data transfer registers + addressing mode
+ * w - neon D register (22, 15-12)
+ * x - instruction in hex
+ * y - co-processor data processing registers
+ * z - co-processor register transfer registers
  * D - destination-is-r15 (P) flag on TST, TEQ, CMP, CMN
+ * F - PSR transfer fields
+ * I - NEON operand size
  * L - co-processor transfer size
- * S - set status flag
+ * N - quad neon operand
  * P - fp precision
  * Q - fp precision (for ldf/stf)
  * R - fp rounding
- * v - co-processor data transfer registers + addressing mode
+ * S - set status flag
+ * U - neon unsigned.
  * W - writeback flag
- * x - instruction in hex
+ * X - block transfer type
+ * Y - block transfer type (r13 base)
  * # - co-processor number
- * y - co-processor data processing registers
- * z - co-processor register transfer registers
  */
 
 struct arm32_insn {
@@ -222,6 +228,21 @@ static const struct arm32_insn arm32_i[]
     { 0x0e100090, 0x0c100000, "ldc",	"L#v" },
     { 0xfe100090, 0xfc000000, "stc2",	"L#v" },
     { 0x0e100090, 0x0c000000, "stc",	"L#v" },
+    { 0xffb00f10, 0xf2000110, "vand",	"Nuqw" },
+    { 0xffb00f10, 0xf2100110, "vbic",	"Nuqw" },
+    { 0xffb00f10, 0xf2200110, "vorr",	"Nuqw" },
+    { 0xffb00f10, 0xf2300110, "vorn",	"Nuqw" },
+    { 0xffb00f10, 0xf3000110, "veor",	"Nuqw" },
+    { 0xffb00f10, 0xf3100110, "vbsl",	"Nuqw" },
+    { 0xffb00f10, 0xf3200110, "vbit",	"Nuqw" },
+    { 0xffb00f10, 0xf3300110, "vbif",	"Nuqw" },
+    { 0xfe800f10, 0xf3000400, "vshl",	"SINuqw" },
+    { 0xfe800f10, 0xf3000410, "vqshl",	"SINuqw" },
+    { 0xfe800f10, 0xf3000500, "vrshl",	"SINuqw" },
+    { 0xfe800f10, 0xf3000510, "vqrshl",	"SINuqw" },
+    { 0xffb00f10, 0xf2000800, "vadd",	"INuqw" },
+    { 0xffb00f10, 0xf2000810, "vtst",	"INuqw" },
+    { 0xffb00f10, 0xf3000800, "vsub",	"INuqw" },
     { 0x00000000, 0x00000000, NULL,	NULL }
 };
 
@@ -298,6 +319,8 @@ disasm(const disasm_interface_t *di, vad
 	fmt = 0;
 	matchp = 0;
 	insn = di->di_readword(loc);
+	char neonfmt = 'd';
+	char neonsign = 'u';
 
 /*	di->di_printf("loc=%08x insn=%08x : ", loc, insn);*/
 
@@ -347,6 +370,11 @@ disasm(const disasm_interface_t *di, vad
 		case 'd':
 			di->di_printf("r%d", ((insn >> 12) & 0x0f));
 			break;
+		/* u - neon destination register (bits 22, 12-15) */
+		case 'u':
+			di->di_printf("%c%d", neonfmt,
+			    ((insn >> 18) & 0x10)|((insn >> 12) & 0x0f));
+			break;
 		/* D - insert 'p' if Rd is R15 */
 		case 'D':
 			if (((insn >> 12) & 0x0f) == 15)
@@ -356,6 +384,11 @@ disasm(const disasm_interface_t *di, vad
 		case 'n':
 			di->di_printf("r%d", ((insn >> 16) & 0x0f));
 			break;
+		/* q - neon n register (bits 7, 16-19) */
+		case 'q':
+			di->di_printf("%c%d", neonfmt,
+			    ((insn >> 3) & 0x10)|((insn >> 16) & 0x0f));
+			break;
 		/* s - s register (bits 8-11) */
 		case 's':
 			di->di_printf("r%d", ((insn >> 8) & 0x0f));
@@ -364,10 +397,15 @@ disasm(const disasm_interface_t *di, vad
 		case 'o':
 			di->di_printf("[r%d]", ((insn >> 16) & 0x0f));
 			break;
-		/* m - m register (bits 0-4) */
+		/* m - m register (bits 0-3) */
 		case 'm':
 			di->di_printf("r%d", ((insn >> 0) & 0x0f));
 			break;
+		/* w - neon m register (bits 5, 0-3) */
+		case 'w':
+			di->di_printf("%c%d", neonfmt,
+			    ((insn >> 1) & 0x10)|(insn & 0x0f));
+			break;
 		/* a - address operand of ldr/str instruction */
 		case 'a':
 			disasm_insn_ldrstr(di, insn, loc);
@@ -410,6 +448,18 @@ disasm(const disasm_interface_t *di, vad
 				branch |= 0xfc000000;
 			di->di_printaddr(loc + 8 + branch);
 			break;
+		case 'N':
+			if (insn & 0x40)
+				neonfmt = 'q';
+			break;
+		case 'U':
+			if (insn & (1 << 24))
+				neonsign = 's';
+			break;
+		case 'I':
+			di->di_printf(".%c%d", neonsign,
+			    8 << ((insn >> 20) & 3));
+			break;
 		/* X - block transfer type */
 		case 'X':
 			di->di_printf("%s", insn_blktrans(insn));

Reply via email to