Module Name: src
Committed By: matt
Date: Thu Jun 4 02:26:49 UTC 2015
Modified Files:
src/sys/arch/mips/include: mips_opcode.h
src/sys/arch/mips/mips: db_disasm.c
Log Message:
Add a lot of missing mipsNNr2 instruction + cavium specific instructions.
To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/mips/include/mips_opcode.h
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/mips/mips/db_disasm.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.19 src/sys/arch/mips/include/mips_opcode.h:1.20
--- src/sys/arch/mips/include/mips_opcode.h:1.19 Mon Jun 1 22:55:13 2015
+++ src/sys/arch/mips/include/mips_opcode.h Thu Jun 4 02:26:49 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_opcode.h,v 1.19 2015/06/01 22:55:13 matt Exp $ */
+/* $NetBSD: mips_opcode.h,v 1.20 2015/06/04 02:26:49 matt Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -179,7 +179,10 @@ typedef union {
#define OP_PREF 063
#define OP_LLD 064 /* MIPS-II, for r4000 port */
#define OP_LDC1 065
+#define OP_LDC2 066
#define OP_LD 067 /* MIPS-II, for r4000 port */
+#define OP_CVM_BBIT0 OP_LWC2
+#define OP_CVM_BBIT032 OP_LDC2
#define OP_SC 070
#define OP_SWC0 OP_SC /* backwards source compatibility */
@@ -188,7 +191,10 @@ typedef union {
#define OP_RSVD073 073
#define OP_SCD 074 /* MIPS-II, for r4000 port */
#define OP_SDC1 075
+#define OP_SDC2 076
#define OP_SD 077 /* MIPS-II, for r4000 port */
+#define OP_CVM_BBIT1 OP_SWC2
+#define OP_CVM_BBIT132 OP_SDC2
/*
* Values for the 'func' field when 'op' == OP_SPECIAL.
@@ -206,6 +212,16 @@ typedef union {
#define OP_BREAK 015
#define OP_SYNC 017 /* MIPS-II, for r4000 port */
+#define SYNC_CVM_IODBDMA 0x02
+#define SYNC_WMB 0x04
+#define SYNC_CVM_W SYNC_WMB
+#define SYNC_CVM_WS 0x05
+#define SYNC_CVM_S 0x06
+#define SYNC_MB 0x10
+#define SYNC_ACQUIRE 0x11
+#define SYNC_RELEASE 0x12
+#define SYNC_RMB 0x13
+
#define OP_MFHI 020
#define OP_MTHI 021
#define OP_MFLO 022
@@ -256,22 +272,52 @@ typedef union {
/*
* Values for the 'func' field when 'op' == OP_SPECIAL2.
*/
-#define OP_MAD 000 /* QED */
-#define OP_MADU 001 /* QED */
+#define OP_MADD 000 /* QED */
+#define OP_MADDU 001 /* QED */
#define OP_MUL 002 /* QED */
+#define OP_CVM_DMUL 003 /* OCTEON */
#define OP_MSUB 004 /* MIPS32/64 */
#define OP_MSUBU 005 /* MIPS32/64 */
+#define OP_CVM_SAA 030 /* OCTEON */
+#define OP_CVM_SAAD 031 /* OCTEON */
#define OP_CLZ 040 /* MIPS32/64 */
#define OP_CLO 041 /* MIPS32/64 */
#define OP_DCLZ 044 /* MIPS32/64 */
#define OP_DCLO 045 /* MIPS32/64 */
+#define OP_CVM_BADDU 050 /* OCTEON */
+#define OP_CVM_SEQ 052 /* OCTEON */
+#define OP_CVM_SNE 053 /* OCTEON */
+#define OP_CVM_SEQI 056 /* OCTEON */
+#define OP_CVM_SNEI 057 /* OCTEON */
+#define OP_CVM_POP 054 /* OCTEON */
+#define OP_CVM_DPOP 055 /* OCTEON */
+#define OP_CVM_CINS 062 /* OCTEON */
+#define OP_CVM_CINS32 063 /* OCTEON */
+#define OP_CVM_EXTS 072 /* OCTEON */
+#define OP_CVM_EXTS32 073 /* OCTEON */
+#define OP_SDBBP 077 /* MIPS32/MIPS64 */
/*
* Values for the 'func' field when 'op' == OP_SPECIAL3.
*/
+#define OP_EXT 000 /* MIPS32/64 r2 */
+#define OP_DEXTM 001 /* MIPS32/64 r2 */
+#define OP_DEXTU 002 /* MIPS32/64 r2 */
+#define OP_DEXT 003 /* MIPS32/64 r2 */
+#define OP_INS 004 /* MIPS32/64 r2 */
+#define OP_DINSM 005 /* MIPS32/64 r2 */
+#define OP_DINSU 006 /* MIPS32/64 r2 */
+#define OP_DINS 007 /* MIPS32/64 r2 */
#define OP_LX 012 /* DSP */
+#define OP_BSHFL 040 /* MIPS32/64 r2 */
+#define OP_DBSHFL 044 /* MIPS32/64 r2 */
#define OP_RDHWR 073 /* MIPS32/64 r2 */
+#define OP_BSHFL_SBH 2 /* swap bytes within halfwords */
+#define OP_BSHFL_SHD 4 /* swap halfworks within double */
+#define OP_BSHFL_SEB 16 /* sign extend byte */
+#define OP_BSHFL_SEH 24 /* sign extend halfword */
+
#define OP_LX_LWX 0 /* lwx */
#define OP_LX_LHX 4 /* lhx */
#define OP_LX_LBUX 6 /* lbux */
@@ -309,6 +355,7 @@ typedef union {
#define OP_CT 006
#define OP_MTH 007
#define OP_BCx 010
+#define OP_MFM 013 /* MIPS32/64 r2 */
#define OP_BCy 014
/*
Index: src/sys/arch/mips/mips/db_disasm.c
diff -u src/sys/arch/mips/mips/db_disasm.c:1.24 src/sys/arch/mips/mips/db_disasm.c:1.25
--- src/sys/arch/mips/mips/db_disasm.c:1.24 Thu Aug 18 21:04:23 2011
+++ src/sys/arch/mips/mips/db_disasm.c Thu Jun 4 02:26:49 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: db_disasm.c,v 1.24 2011/08/18 21:04:23 matt Exp $ */
+/* $NetBSD: db_disasm.c,v 1.25 2015/06/04 02:26:49 matt Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.24 2011/08/18 21:04:23 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.25 2015/06/04 02:26:49 matt Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -58,13 +58,18 @@ static const char * const op_name[64] =
/*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37",
/*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu",
/*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache",
+#ifdef __OCTEON__
+/*48 */ "ll", "lwc1", "bbit0", "lwc3", "lld", "ldc1", "bbit032", "ld",
+/*56 */ "sc", "swc1", "bbit1", "swc3", "scd", "sdc1", "bbit132", "sd"
+#else
/*48 */ "ll", "lwc1", "lwc2", "lwc3", "lld", "ldc1", "ldc2", "ld",
/*56 */ "sc", "swc1", "swc2", "swc3", "scd", "sdc1", "sdc2", "sd"
+#endif
};
static const char * const spec_name[64] = {
-/* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav",
-/* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","sync",
+/* 0 */ "sll", "movc1","srl", "sra", "sllv", "spec05","srlv","srav",
+/* 8 */ "jr", "jalr", "movz","movn","syscall","break","spec16","sync",
/*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav",
/*24 */ "mult", "multu","div", "divu", "dmult","dmultu","ddiv","ddivu",
/*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor",
@@ -73,8 +78,49 @@ static const char * const spec_name[64]
/*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
};
-static const char * const spec2_name[4] = { /* QED RM4650, R5000, etc. */
-/* 0 */ "mad", "madu", "mul", "spec3"
+static const char * const spec2_name[64] = { /* QED RM4650, R5000, etc. */
+ [OP_MADD] = "madd",
+ [OP_MADDU] = "maddu",
+ [OP_MUL] = "mul",
+#ifdef __OCTEON__
+ [OP_CVM_DMUL] = "baddu",
+#endif
+ [OP_MSUB] = "msub",
+ [OP_MSUBU] = "msubu",
+ [OP_CLZ] = "clz",
+ [OP_CLO] = "clo",
+ [OP_DCLZ] = "dclz",
+ [OP_DCLO] = "dclo",
+#ifdef __OCTEON__
+ [OP_CVM_BADDU] = "baddu",
+ [OP_CVM_POP] = "pop",
+ [OP_CVM_DPOP] = "dpop",
+ [OP_CVM_CINS] = "cins",
+ [OP_CVM_CINS32] = "cins32",
+ [OP_CVM_EXTS] = "exts",
+ [OP_CVM_EXTS32] = "exts32",
+ [OP_CVM_SEQ] = "seq",
+ [OP_CVM_SEQI] = "seqi",
+ [OP_CVM_SNE] = "sne",
+ [OP_CVM_SNEI] = "snei",
+ [OP_CVM_SAA] = "saa",
+ [OP_CVM_SAAD] = "saad",
+#endif
+ [OP_SDBBP] = "sdbbp",
+};
+
+static const char * const spec3_name[64] = {
+ [OP_EXT] = "ext",
+ [OP_DEXTM] = "dextm",
+ [OP_DEXTU] = "dextu",
+ [OP_DEXT] = "dext",
+ [OP_INS] = "ins",
+ [OP_DINSM] = "dinsm",
+ [OP_DINSU] = "dinsu",
+ [OP_DINS] = "dins",
+ [OP_BSHFL] = "bshfl",
+ [OP_DBSHFL] = "dbshfl",
+ [OP_RDHWR] = "rdhwr",
};
static const char * const regimm_name[32] = {
@@ -191,7 +237,8 @@ db_disasm_insn(int insn, db_addr_t loc,
i.word = insn;
switch (i.JType.op) {
- case OP_SPECIAL:
+ case OP_SPECIAL: {
+ const char *name = spec_name[i.RType.func];
if (i.word == 0) {
db_printf("nop");
break;
@@ -206,7 +253,15 @@ db_disasm_insn(int insn, db_addr_t loc,
reg_name[i.RType.rs]);
break;
}
- db_printf("%s", spec_name[i.RType.func]);
+ if ((i.RType.func == OP_SRL || i.RType.func == OP_SRLV)
+ && i.RType.rs == 1) {
+ name = (i.RType.func == OP_SRL) ? "rotr" : "rotrv";
+ } else if ((i.RType.func == OP_DSRL || i.RType.func == OP_DSRLV)
+ && i.RType.shamt == 1) {
+ name = (i.RType.func == OP_DSRL) ? "drotr" : "drotrv";
+ }
+
+ db_printf("%s", name);
switch (i.RType.func) {
case OP_SLL:
case OP_SRL:
@@ -266,7 +321,10 @@ db_disasm_insn(int insn, db_addr_t loc,
case OP_SYSCALL:
+ break;
case OP_SYNC:
+ if (i.RType.shamt != 0)
+ db_printf("\t%d", i.RType.shamt);
break;
case OP_BREAK:
@@ -280,20 +338,150 @@ db_disasm_insn(int insn, db_addr_t loc,
reg_name[i.RType.rt]);
}
break;
+ }
case OP_SPECIAL2:
- if (i.RType.func == OP_MUL)
+ if (spec_name[i.RType.func] == NULL) {
+ db_printf("spec2#%03o\t%s,%s",
+ i.RType.func,
+ reg_name[i.RType.rs],
+ reg_name[i.RType.rt]);
+ break;
+ }
+ if (i.RType.func == OP_MUL
+#ifdef __OCTEON__
+ || i.RType.func == OP_CVM_DMUL
+ || i.RType.func == OP_CVM_SEQ
+ || i.RType.func == OP_CVM_SNE
+#endif
+ || false) {
db_printf("%s\t%s,%s,%s",
- spec2_name[i.RType.func & 0x3],
+ spec2_name[i.RType.func],
reg_name[i.RType.rd],
reg_name[i.RType.rs],
reg_name[i.RType.rt]);
- else
+ break;
+ }
+#ifdef __OCTEON__
+ if (i.RType.func == OP_CVM_CINS
+ || i.RType.func == OP_CVM_CINS32
+ || i.RType.func == OP_CVM_EXTS
+ || i.RType.func == OP_CVM_EXTS32) {
+ db_printf("%s\t%s,%s,%d,%d",
+ spec2_name[i.RType.func],
+ reg_name[i.RType.rt],
+ reg_name[i.RType.rs],
+ i.RType.shamt,
+ i.RType.rd);
+ break;
+ }
+ if (i.RType.func == OP_CVM_SEQI
+ || i.RType.func == OP_CVM_SNEI) {
+ db_printf("%s\t%s,%s,%d",
+ spec2_name[i.RType.func],
+ reg_name[i.RType.rs],
+ reg_name[i.RType.rt],
+ (short)i.IType.imm >> 6);
+ break;
+ }
+ if (i.RType.func == OP_CVM_SAA
+ || i.RType.func == OP_CVM_SAAD) {
+ db_printf("%s\t%s,(%s)",
+ spec2_name[i.RType.func],
+ reg_name[i.RType.rt],
+ reg_name[i.RType.rs]);
+ break;
+ }
+#endif
+ if (i.RType.func == OP_CLO
+ || i.RType.func == OP_DCLO
+#ifdef __OCTEON__
+ || i.RType.func == OP_CVM_POP
+ || i.RType.func == OP_CVM_DPOP
+#endif
+ || i.RType.func == OP_CLZ
+ || i.RType.func == OP_DCLZ) {
db_printf("%s\t%s,%s",
- spec2_name[i.RType.func & 0x3],
+ spec2_name[i.RType.func],
+ reg_name[i.RType.rs],
+ reg_name[i.RType.rd]);
+ break;
+ }
+ db_printf("%s\t%s,%s",
+ spec2_name[i.RType.func],
+ reg_name[i.RType.rs],
+ reg_name[i.RType.rt]);
+ break;
+
+ case OP_SPECIAL3:
+ if (spec3_name[i.RType.func] == NULL) {
+ db_printf("spec3#%03o\t%s,%s",
+ i.RType.func,
reg_name[i.RType.rs],
reg_name[i.RType.rt]);
-
+ break;
+ }
+ if (i.RType.func <= OP_DINS) {
+ int lsb = i.RType.shamt
+ + ((i.RType.func & 3) == 2) ? 32 : 0;
+ int msb = i.RType.rd
+ + (((i.RType.func - 1) & 3) < 2) ? 32 : 0;
+ db_printf("%s\t%s,%s,%d,%d",
+ spec3_name[i.RType.func],
+ reg_name[i.RType.rt],
+ reg_name[i.RType.rs],
+ lsb, msb - lsb + 1);
+ break;
+ }
+ if (i.RType.func == OP_RDHWR) {
+ db_printf("%s\t%s,$%d",
+ spec3_name[i.RType.func],
+ reg_name[i.RType.rt],
+ i.RType.rd);
+ break;
+ }
+ if (i.RType.func == OP_BSHFL) {
+ if (i.RType.shamt == OP_BSHFL_SBH) {
+ db_printf("wsbh\t%s,%s",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt]);
+ } else if (i.RType.shamt == OP_BSHFL_SEB) {
+ db_printf("seb\t%s,%s",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt]);
+ } else if (i.RType.shamt == OP_BSHFL_SEH) {
+ db_printf("seh\t%s,%s",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt]);
+ } else {
+ db_printf("bshfl\t%s,%s,%d",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt],
+ i.RType.shamt);
+ }
+ break;
+ }
+ if (i.RType.func == OP_DBSHFL) {
+ if (i.RType.shamt == OP_BSHFL_SBH) {
+ db_printf("dsbh\t%s,%s",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt]);
+ } else if (i.RType.shamt == OP_BSHFL_SHD) {
+ db_printf("dshd\t%s,%s",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt]);
+ } else {
+ db_printf("dbshfl\t%s,%s,%d",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt],
+ i.RType.shamt);
+ }
+ break;
+ }
+ db_printf("%s\t%s,%s",
+ spec3_name[i.RType.func],
+ reg_name[i.RType.rs],
+ reg_name[i.RType.rt]);
break;
case OP_REGIMM:
@@ -359,6 +547,20 @@ db_disasm_insn(int insn, db_addr_t loc,
c0_reg[i.RType.rd]);
break;
+ case OP_MFM:
+ if (i.RType.rd == MIPS_COP_0_STATUS
+ && i.RType.shamt == 0
+ && (i.RType.func & 31) == 0) {
+ db_printf("%s",
+ i.RType.func & 16 ? "ei" : "di");
+ if (i.RType.rt != 0) {
+ db_printf("\t%s",
+ reg_name[i.RType.rt]);
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+
default:
db_printf("%s", c0_opname[i.FRType.func]);
}
@@ -499,8 +701,27 @@ db_disasm_insn(int insn, db_addr_t loc,
bdslot = true;
break;
+#ifdef __OCTEON__
+ case OP_CVM_BBIT0:
+ case OP_CVM_BBIT032:
+ case OP_CVM_BBIT1:
+ case OP_CVM_BBIT132:
+ db_printf("%s\t%s,%d,",
+ op_name[i.IType.op],
+ reg_name[i.IType.rs],
+ i.IType.rt);
+ goto pr_displ;
+#else
+ case OP_LWC2:
+ case OP_LDC2:
+ case OP_SWC2:
+ case OP_SDC2:
+#endif
+
case OP_LWC1:
case OP_SWC1:
+ case OP_LDC1:
+ case OP_SDC1:
db_printf("%s\tf%d,", op_name[i.IType.op],
i.IType.rt);
goto loadstore;