Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/arm Start adding support for disassembling some...



details:   https://anonhg.NetBSD.org/src/rev/374bb89b6a03
branches:  trunk
changeset: 783385:374bb89b6a03
user:      matt <matt%NetBSD.org@localhost>
date:      Tue Dec 18 06:31:58 2012 +0000

description:
Start adding support for disassembling some NEON instructions.

diffstat:

 sys/arch/arm/arm/disassem.c |  92 ++++++++++++++++++++++++++++++++++----------
 1 files changed, 71 insertions(+), 21 deletions(-)

diffs (170 lines):

diff -r 71bf87eb6d73 -r 374bb89b6a03 sys/arch/arm/arm/disassem.c
--- a/sys/arch/arm/arm/disassem.c       Tue Dec 18 06:30:18 2012 +0000
+++ b/sys/arch/arm/arm/disassem.c       Tue Dec 18 06:31:58 2012 +0000
@@ -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 @@
  *
  *
  * 2 - print Operand 2 of a data processing instruction
+ * a - address operand of ldr/str instruction
+ * b - branch address
+ * c - comment field bits(0-23)
  * 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
  * 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
+ * k - breakpoint comment (bits 0-3, 8-19)
+ * 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
+ * q - neon N register (7, 19-16)
+ * s - s register (bits 8-11)
  * 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)
- * p - saved or current status register
+ * 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
- * D - destination-is-r15 (P) flag on TST, TEQ, CMP, CMN
+ * 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 @@
     { 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 @@
        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 @@
                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 @@
                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 @@
                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 @@
                                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));



Home | Main Index | Thread Index | Old Index