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));