summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/libdisasm/Makefile7
-rw-r--r--usr/src/lib/libdisasm/Makefile.com7
-rw-r--r--usr/src/lib/libdisasm/common/libdisasm.h1
-rw-r--r--usr/src/lib/libdisasm/common/linktest_stand.c3
-rw-r--r--usr/src/lib/libdisasm/sparc/Makefile38
-rw-r--r--usr/src/lib/libdisasm/sparc/dis_sparc.c339
-rw-r--r--usr/src/lib/libdisasm/sparc/dis_sparc.h109
-rw-r--r--usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c2422
-rw-r--r--usr/src/lib/libdisasm/sparc/dis_sparc_fmt.h124
-rw-r--r--usr/src/lib/libdisasm/sparc/instr.c1625
-rw-r--r--usr/src/lib/libdisasm/sparcv9/Makefile39
-rw-r--r--usr/src/pkgdefs/etc/exception_list_sparc1
-rw-r--r--usr/src/tools/scripts/mkclosed.sh19
13 files changed, 4710 insertions, 24 deletions
diff --git a/usr/src/lib/libdisasm/Makefile b/usr/src/lib/libdisasm/Makefile
index 69dbd89f35..fbff822dc2 100644
--- a/usr/src/lib/libdisasm/Makefile
+++ b/usr/src/lib/libdisasm/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -30,9 +30,8 @@ include ../Makefile.lib
HDRS= libdisasm.h
HDRDIR= common
-$(INTEL_BLD)SUBDIRS= $(MACH)
-$(INTEL_BLD)$(BUILD64)SUBDIRS += $(MACH64)
-$(CLOSED_BUILD)SUBDIRS += $(CLOSED)/lib/libdisasm
+SUBDIRS= $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
all := TARGET = all
clean := TARGET = clean
diff --git a/usr/src/lib/libdisasm/Makefile.com b/usr/src/lib/libdisasm/Makefile.com
index 343ff60f5b..07280f6d5a 100644
--- a/usr/src/lib/libdisasm/Makefile.com
+++ b/usr/src/lib/libdisasm/Makefile.com
@@ -50,10 +50,11 @@ COMDIR= $(SRC)/lib/libdisasm/common
# Architecture-dependent files common to both versions of libdisasm
#
OBJECTS_common_i386 = dis_i386.o dis_tables.o
-OBJECTS_common_sparc = dis_sparc.o
+OBJECTS_common_sparc = dis_sparc.o instr.o dis_sparc_fmt.o
SRCS_common_i386 = $(ISASRCDIR)/dis_i386.c $(SRC)/common/dis/i386/dis_tables.c
-SRCS_common_sparc = $(ISASRCDIR)/dis_sparc.c
+SRCS_common_sparc = $(ISASRCDIR)/dis_sparc.c $(ISASRCDIR)/instr.c \
+ $(ISASRCDIR)/dis_sparc_fmt.c
#
# Architecture-independent files common to both version of libdisasm
@@ -112,7 +113,7 @@ STAND_RENAMED_FUNCS= \
snprintf
CPPFLAGS_standalone = -DDIS_STANDALONE $(STAND_RENAMED_FUNCS:%=-D%=mdb_%) \
- -I$(SRC)/cmd/mdb/common
+ -Dvsnprintf=mdb_iob_vsnprintf -I$(SRC)/cmd/mdb/common
CPPFLAGS_library = -D_REENTRANT
CPPFLAGS += -I$(COMDIR) $(CPPFLAGS_$(CURTYPE))
diff --git a/usr/src/lib/libdisasm/common/libdisasm.h b/usr/src/lib/libdisasm/common/libdisasm.h
index 3ecdea0860..bcd7318cd1 100644
--- a/usr/src/lib/libdisasm/common/libdisasm.h
+++ b/usr/src/lib/libdisasm/common/libdisasm.h
@@ -43,6 +43,7 @@ typedef struct dis_handle dis_handle_t;
#define DIS_SPARC_V8 0x01
#define DIS_SPARC_V9 0x02
#define DIS_SPARC_V9_SGI 0x04
+#define DIS_SPARC_V9_OPL 0x08
/* x86 diassembler flags (mutually exclusive) */
#define DIS_X86_SIZE16 0x08
diff --git a/usr/src/lib/libdisasm/common/linktest_stand.c b/usr/src/lib/libdisasm/common/linktest_stand.c
index 88f3e2ce8b..36466b24fa 100644
--- a/usr/src/lib/libdisasm/common/linktest_stand.c
+++ b/usr/src/lib/libdisasm/common/linktest_stand.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,6 +33,7 @@
void mdb_free(void) {}
void snprintf(void) {}
+void vsnprintf(void) {}
void mdb_zalloc(void) {}
void strcmp(void) {}
void strlen(void) {}
diff --git a/usr/src/lib/libdisasm/sparc/Makefile b/usr/src/lib/libdisasm/sparc/Makefile
new file mode 100644
index 0000000000..1c6db3c840
--- /dev/null
+++ b/usr/src/lib/libdisasm/sparc/Makefile
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+ISASRCDIR=.
+
+include ../Makefile.com
+
+TYPES=library standalone
+
+INSTALL_DEPS_library = $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBS)
+INSTALL_DEPS_standalone = $(ROOTLIBS)
+
+include ../Makefile.targ
+
+C99MODE = $(C99_ENABLE)
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc.c b/usr/src/lib/libdisasm/sparc/dis_sparc.c
new file mode 100644
index 0000000000..b9821a304c
--- /dev/null
+++ b/usr/src/lib/libdisasm/sparc/dis_sparc.c
@@ -0,0 +1,339 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2007 Jason King. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * The sparc disassembler is mostly straightforward, each instruction is
+ * represented by an inst_t structure. The inst_t definitions are organized
+ * into tables. The tables are correspond to the opcode maps documented in the
+ * various sparc architecture manuals. Each table defines the bit range of the
+ * instruction whose value act as an index into the array of instructions. A
+ * table can also refer to another table if needed. Each table also contains
+ * a function pointer of type format_fcn that knows how to output the
+ * instructions in the table, as well as handle any synthetic instructions
+ *
+ * Unfortunately, the changes from sparcv8 -> sparcv9 not only include new
+ * instructions, they sometimes renamed or just reused the same instruction to
+ * do different operations (i.e. the sparcv8 coprocessor instructions). To
+ * accommodate this, each table can define an overlay table. The overlay table
+ * is a list of (table index, architecture, new instruction definition) values.
+ *
+ *
+ * Traversal starts with the first table,
+ * get index value from the instruction
+ * if an relevant overlay entry exists for this index,
+ * grab the overlay definition
+ * else
+ * grab the definition from the array (corresponding to the index value)
+ *
+ * If the entry is an instruction,
+ * call print function of instruction.
+ * If the entry is a pointer to another table
+ * traverse the table
+ * If not valid,
+ * return an error
+ *
+ *
+ * To keep dis happy, for sparc, instead of actually returning an error, if
+ * the instruction cannot be disassembled, we instead merely place the value
+ * of the instruction into the output buffer.
+ *
+ * Adding new instructions:
+ *
+ * With the above information, it hopefully makes it clear how to add support
+ * for decoding new instructions. Presumably, with new instructions will come
+ * a new dissassembly mode (I.e. DIS_SPARC_V8, DIS_SPARC_V9, etc.).
+ *
+ * If the dissassembled format does not correspond to one of the existing
+ * formats, a new formatter will have to be written. The 'flags' value of
+ * inst_t is intended to instruct the corresponding formatter about how to
+ * output the instruction.
+ *
+ * If the corresponding entry in the correct table is currently unoccupied,
+ * simply replace the INVALID entry with the correct definition. The INST and
+ * TABLE macros are suggested to be used for this. If there is already an
+ * instruction defined, then the entry must be placed in an overlay table. If
+ * no overlay table exists for the instruction table, one will need to be
+ * created.
+ */
+
+#include <libdisasm.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/byteorder.h>
+#include <string.h>
+
+#include "libdisasm_impl.h"
+#include "dis_sparc.h"
+
+static const inst_t *dis_get_overlay(dis_handle_t *, const table_t *,
+ uint32_t);
+static uint32_t dis_get_bits(uint32_t, int, int);
+
+#if !defined(DIS_STANDALONE)
+static void do_binary(uint32_t);
+#endif /* DIS_STANDALONE */
+
+dis_handle_t *
+dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
+ dis_read_f read_func)
+{
+
+#if !defined(DIS_STANDALONE)
+ char *opt = NULL;
+ char *opt2, *save, *end;
+#endif
+ dis_handle_t *dhp;
+
+ if ((flags & (DIS_SPARC_V8|DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0) {
+ (void) dis_seterrno(E_DIS_INVALFLAG);
+ return (NULL);
+ }
+
+ if ((dhp = dis_zalloc(sizeof (struct dis_handle))) == NULL) {
+ (void) dis_seterrno(E_DIS_NOMEM);
+ return (NULL);
+ }
+
+ dhp->dh_lookup = lookup_func;
+ dhp->dh_read = read_func;
+ dhp->dh_flags = flags;
+ dhp->dh_data = data;
+ dhp->dh_debug = DIS_DEBUG_COMPAT;
+
+#if !defined(DIS_STANDALONE)
+
+ opt = getenv("_LIBDISASM_DEBUG");
+ if (opt == NULL)
+ return (dhp);
+
+ opt2 = strdup(opt);
+ if (opt2 == NULL) {
+ dis_handle_destroy(dhp);
+ (void) dis_seterrno(E_DIS_NOMEM);
+ return (NULL);
+ }
+ save = opt2;
+
+ while (opt2 != NULL) {
+ end = strchr(opt2, ',');
+
+ if (end != 0)
+ *end++ = '\0';
+
+ if (strcasecmp("synth-all", opt2) == 0)
+ dhp->dh_debug |= DIS_DEBUG_SYN_ALL;
+
+ if (strcasecmp("compat", opt2) == 0)
+ dhp->dh_debug |= DIS_DEBUG_COMPAT;
+
+ if (strcasecmp("synth-none", opt2) == 0)
+ dhp->dh_debug &= ~(DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT);
+
+ if (strcasecmp("binary", opt2) == 0)
+ dhp->dh_debug |= DIS_DEBUG_PRTBIN;
+
+ if (strcasecmp("format", opt2) == 0)
+ dhp->dh_debug |= DIS_DEBUG_PRTFMT;
+
+ if (strcasecmp("all", opt2) == 0)
+ dhp->dh_debug = DIS_DEBUG_ALL;
+
+ if (strcasecmp("none", opt2) == 0)
+ dhp->dh_debug = DIS_DEBUG_NONE;
+
+ opt2 = end;
+ }
+ free(save);
+#endif /* DIS_STANDALONE */
+ return (dhp);
+}
+
+void
+dis_handle_destroy(dis_handle_t *dhp)
+{
+ dis_free(dhp, sizeof (dis_handle_t));
+}
+
+void
+dis_set_data(dis_handle_t *dhp, void *data)
+{
+ dhp->dh_data = data;
+}
+
+void
+dis_flags_set(dis_handle_t *dhp, int f)
+{
+ dhp->dh_flags |= f;
+}
+
+void
+dis_flags_clear(dis_handle_t *dhp, int f)
+{
+ dhp->dh_flags &= ~f;
+}
+
+/* ARGSUSED */
+int
+dis_max_instrlen(dis_handle_t *dhp)
+{
+ return (4);
+}
+
+/*
+ * The dis_i386.c comment for this says it returns the previous instruction,
+ * however, I'm fairly sure it's actually returning the _address_ of the
+ * nth previous instruction.
+ */
+/* ARGSUSED */
+uint64_t
+dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
+{
+ if (n <= 0)
+ return (pc);
+
+ if (pc < n)
+ return (pc);
+
+ return (pc - n*4);
+}
+
+int
+dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
+{
+ const table_t *tp = &initial_table;
+ const inst_t *inp = NULL;
+
+ uint32_t instr;
+ uint32_t idx = 0;
+
+ if (dhp->dh_read(dhp->dh_data, addr, &instr, sizeof (instr)) !=
+ sizeof (instr))
+ return (-1);
+
+ dhp->dh_buf = buf;
+ dhp->dh_buflen = buflen;
+ dhp->dh_addr = addr;
+
+ buf[0] = '\0';
+
+ /* this allows sparc code to be tested on x86 */
+ instr = BE_32(instr);
+
+#if !defined(DIS_STANDALONE)
+ if ((dhp->dh_debug & DIS_DEBUG_PRTBIN) != 0)
+ do_binary(instr);
+#endif /* DIS_STANDALONE */
+
+ /* CONSTCOND */
+ while (1) {
+ idx = dis_get_bits(instr, tp->tbl_field, tp->tbl_len);
+ inp = &tp->tbl_inp[idx];
+
+ inp = dis_get_overlay(dhp, tp, idx);
+
+ if ((inp->in_type == INST_NONE) ||
+ ((inp->in_arch & dhp->dh_flags) == 0))
+ goto error;
+
+ if (inp->in_type == INST_TBL) {
+ tp = inp->in_data.in_tbl;
+ continue;
+ }
+
+ break;
+ }
+
+ if (tp->tbl_fmt(dhp, instr, inp, idx) == 0)
+ return (0);
+
+error:
+
+ (void) snprintf(buf, buflen,
+ ((dhp->dh_flags & DIS_OCTAL) != 0) ? "0%011lo" : "0x%08lx",
+ instr);
+
+ return (0);
+}
+
+static uint32_t
+dis_get_bits(uint32_t instr, int offset, int length)
+{
+ uint32_t mask, val;
+ int i;
+
+ for (i = 0, mask = 0; i < length; ++i)
+ mask |= (1UL << i);
+
+ mask = mask << (offset - length + 1);
+
+ val = instr & mask;
+
+ val = val >> (offset - length + 1);
+
+ return (val);
+}
+
+static const inst_t *
+dis_get_overlay(dis_handle_t *dhp, const table_t *tp, uint32_t idx)
+{
+ const inst_t *ip = &tp->tbl_inp[idx];
+ int i;
+
+ if (tp->tbl_ovp == NULL)
+ return (ip);
+
+ for (i = 0; tp->tbl_ovp[i].ov_idx != -1; ++i) {
+ if (tp->tbl_ovp[i].ov_idx != idx)
+ continue;
+
+ if ((tp->tbl_ovp[i].ov_inst.in_arch & dhp->dh_flags) == 0)
+ continue;
+
+ ip = &tp->tbl_ovp[i].ov_inst;
+ break;
+ }
+
+ return (ip);
+}
+
+#if !defined(DIS_STANDALONE)
+static void
+do_binary(uint32_t instr)
+{
+ (void) fprintf(stderr, "DISASM: ");
+ prt_binary(instr, 32);
+ (void) fprintf(stderr, "\n");
+}
+#endif /* DIS_STANDALONE */
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc.h b/usr/src/lib/libdisasm/sparc/dis_sparc.h
new file mode 100644
index 0000000000..8ebeda18b7
--- /dev/null
+++ b/usr/src/lib/libdisasm/sparc/dis_sparc.h
@@ -0,0 +1,109 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2007 Jason King. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#ifndef _DIS_SPARC_H
+#define _DIS_SPARC_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+#define DIS_DEBUG_NONE 0x00L
+#define DIS_DEBUG_COMPAT 0x01L
+#define DIS_DEBUG_SYN_ALL 0x02L
+#define DIS_DEBUG_PRTBIN 0x04L
+#define DIS_DEBUG_PRTFMT 0x08L
+
+#define DIS_DEBUG_ALL DIS_DEBUG_SYN_ALL|DIS_DEBUG_PRTBIN|DIS_DEBUG_PRTFMT
+
+struct dis_handle {
+ void *dh_data;
+ dis_lookup_f dh_lookup;
+ dis_read_f dh_read;
+ int dh_flags;
+
+ char *dh_buf;
+ size_t dh_buflen;
+ uint64_t dh_addr;
+ int dh_debug;
+};
+
+/* different types of things we can have in inst_t */
+#define INST_NONE 0x00
+#define INST_DEF 0x01
+#define INST_TBL 0x02
+
+struct inst;
+struct overlay;
+
+typedef struct inst inst_t;
+typedef struct overlay overlay_t;
+
+typedef int (*format_fcn)(dis_handle_t *, uint32_t, const inst_t *, int);
+
+typedef struct table {
+ const struct inst *tbl_inp;
+ const struct overlay *tbl_ovp;
+ format_fcn tbl_fmt;
+ uint32_t tbl_field;
+ uint32_t tbl_len;
+} table_t;
+
+struct inst {
+ int in_type;
+ int in_arch;
+ union {
+ struct {
+ const char *in_name;
+ uint32_t in_flags;
+ } in_def;
+ const table_t *in_tbl;
+ } in_data;
+};
+
+struct overlay {
+ int ov_idx;
+ inst_t ov_inst;
+};
+
+extern const table_t initial_table;
+
+void prt_binary(uint32_t, int);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DIS_SPARC_H */
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c b/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c
new file mode 100644
index 0000000000..b49c381d96
--- /dev/null
+++ b/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c
@@ -0,0 +1,2422 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2007 Jason King. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/byteorder.h>
+#include <stdarg.h>
+
+#if !defined(DIS_STANDALONE)
+#include <stdio.h>
+#endif /* DIS_STANDALONE */
+
+#include "libdisasm.h"
+#include "libdisasm_impl.h"
+#include "dis_sparc.h"
+#include "dis_sparc_fmt.h"
+
+extern char *strncpy(char *, const char *, size_t);
+extern size_t strlen(const char *);
+extern int strcmp(const char *, const char *);
+extern int strncmp(const char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
+extern int snprintf(char *, size_t, const char *, ...);
+extern int vsnprintf(char *, size_t, const char *, va_list);
+
+/*
+ * This file has the functions that do all the dirty work of outputting the
+ * disassembled instruction
+ *
+ * All the non-static functions follow the format_fcn (in dis_sparc.h):
+ * Input:
+ * disassembler handle/context
+ * instruction to disassemble
+ * instruction definition pointer (inst_t *)
+ * index in the table of the instruction
+ * Return:
+ * 0 Success
+ * !0 Invalid instruction
+ *
+ * Generally, instructions found in the same table use the same output format
+ * or have a few minor differences (which are described in the 'flags' field
+ * of the instruction definition. In some cases, certain instructions differ
+ * radically enough from those in the same table, that their own format
+ * function is used.
+ *
+ * Typically each table has a unique format function defined in this file. In
+ * some cases (such as branches) a common one for all the tables is used.
+ *
+ * When adding support for new instructions, it is largely a judgement call
+ * as to when a new format function is defined.
+ */
+
+/* The various instruction formats of a sparc instruction */
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format1 {
+ uint32_t op:2;
+ uint32_t disp30:30;
+} format1_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format1 {
+ uint32_t disp30:30;
+ uint32_t op:2;
+} format1_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format2 {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op2:3;
+ uint32_t imm22:22;
+} format2_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format2 {
+ uint32_t imm22:22;
+ uint32_t op2:3;
+ uint32_t rd:5;
+ uint32_t op:2;
+} format2_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format2a {
+ uint32_t op:2;
+ uint32_t a:1;
+ uint32_t cond:4;
+ uint32_t op2:3;
+ uint32_t disp22:22;
+} format2a_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format2a {
+ uint32_t disp22:22;
+ uint32_t op2:3;
+ uint32_t cond:4;
+ uint32_t a:1;
+ uint32_t op:2;
+} format2a_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format2b {
+ uint32_t op:2;
+ uint32_t a:1;
+ uint32_t cond:4;
+ uint32_t op2:3;
+ uint32_t cc:2;
+ uint32_t p:1;
+ uint32_t disp19:19;
+} format2b_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format2b {
+ uint32_t disp19:19;
+ uint32_t p:1;
+ uint32_t cc:2;
+ uint32_t op2:3;
+ uint32_t cond:4;
+ uint32_t a:1;
+ uint32_t op:2;
+} format2b_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format2c {
+ uint32_t op:2;
+ uint32_t a:1;
+ uint32_t cond:4;
+ uint32_t op2:3;
+ uint32_t d16hi:2;
+ uint32_t p:1;
+ uint32_t rs1:5;
+ uint32_t d16lo:14;
+} format2c_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format2c {
+ uint32_t d16lo:14;
+ uint32_t rs1:5;
+ uint32_t p:1;
+ uint32_t d16hi:2;
+ uint32_t op2:3;
+ uint32_t cond:4;
+ uint32_t a:1;
+ uint32_t op:2;
+} format2c_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format3 {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t i:1;
+ uint32_t asi:8;
+ uint32_t rs2:5;
+} format3_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format3 {
+ uint32_t rs2:5;
+ uint32_t asi:8;
+ uint32_t i:1;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} format3_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format3a {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t i:1;
+ uint32_t simm13:13;
+} format3a_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format3a {
+ uint32_t simm13:13;
+ uint32_t i:1;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} format3a_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format3b {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t i:1;
+ uint32_t x:1;
+ uint32_t undef:6;
+ uint32_t shcnt:6;
+} format3b_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format3b {
+ uint32_t shcnt:6;
+ uint32_t undef:6;
+ uint32_t x:1;
+ uint32_t i:1;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} format3b_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format3c {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t cc2:1;
+ uint32_t cond:4;
+ uint32_t i:1;
+ uint32_t cc:2;
+ uint32_t simm11:11;
+} format3c_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format3c {
+ uint32_t simm11:11;
+ uint32_t cc:2;
+ uint32_t i:1;
+ uint32_t cond:4;
+ uint32_t cc2:1;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} format3c_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct format3d {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t i:1;
+ uint32_t rcond:3;
+ uint32_t simm10:10;
+} format3d_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct format3d {
+ uint32_t simm10:10;
+ uint32_t rcond:3;
+ uint32_t i:1;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} format3d_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct formatcp {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t opc:9;
+ uint32_t rs2:5;
+} formatcp_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct formatcp {
+ uint32_t rs2:5;
+ uint32_t opc:9;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} formatcp_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct formattcc {
+ uint32_t op:2;
+ uint32_t undef:1;
+ uint32_t cond:4;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t i:1;
+ uint32_t cc:2;
+ uint32_t undef2:3;
+ uint32_t immtrap:8;
+} formattcc_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct formattcc {
+ uint32_t immtrap:8;
+ uint32_t undef2:3;
+ uint32_t cc:2;
+ uint32_t i:1;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t cond:4;
+ uint32_t undef:1;
+ uint32_t op:2;
+} formattcc_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct formattcc2 {
+ uint32_t op:2;
+ uint32_t undef:1;
+ uint32_t cond:4;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t i:1;
+ uint32_t cc:2;
+ uint32_t undef2:6;
+ uint32_t rs2:5;
+} formattcc2_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct formattcc2 {
+ uint32_t rs2:5;
+ uint32_t undef2:6;
+ uint32_t cc:2;
+ uint32_t i:1;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t cond:4;
+ uint32_t undef:1;
+ uint32_t op:2;
+} formattcc2_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct formatmbr {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t i:1;
+ uint32_t undef:6;
+ uint32_t cmask:3;
+ uint32_t mmask:4;
+} formatmbr_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct formatmbr {
+ uint32_t mmask:4;
+ uint32_t cmask:3;
+ uint32_t undef:6;
+ uint32_t i:1;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} formatmbr_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct formatfcmp {
+ uint32_t op:2;
+ uint32_t undef:3;
+ uint32_t cc:2;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t opf:9;
+ uint32_t rs2:5;
+} formatfcmp_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct formatfcmp {
+ uint32_t rs2:5;
+ uint32_t opf:9;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t cc:2;
+ uint32_t undef:3;
+ uint32_t op:2;
+} formatfcmp_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct formatfmov {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t undef:1;
+ uint32_t cond:4;
+ uint32_t cc:3;
+ uint32_t opf:6;
+ uint32_t rs2:5;
+} formatfmov_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct formatfmov {
+ uint32_t rs2:5;
+ uint32_t opf:6;
+ uint32_t cc:3;
+ uint32_t cond:4;
+ uint32_t undef:1;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} formatfmov_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+#if defined(_BIT_FIELDS_HTOL)
+typedef struct formatfused {
+ uint32_t op:2;
+ uint32_t rd:5;
+ uint32_t op3:6;
+ uint32_t rs1:5;
+ uint32_t rs3:5;
+ uint32_t op5:4;
+ uint32_t rs2:5;
+} formatfused_t;
+#elif defined(_BIT_FIELDS_LTOH)
+typedef struct formatfused {
+ uint32_t rs2:5;
+ uint32_t op5:4;
+ uint32_t rs3:5;
+ uint32_t rs1:5;
+ uint32_t op3:6;
+ uint32_t rd:5;
+ uint32_t op:2;
+} formatfused_t;
+#else
+#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif
+
+typedef union ifmt {
+ uint32_t i;
+ format1_t f1;
+ format2_t f2;
+ format2a_t f2a;
+ format2b_t f2b;
+ format2c_t f2c;
+ format3_t f3;
+ format3a_t f3a;
+ format3b_t f3b;
+ format3c_t f3c;
+ format3d_t f3d;
+ formatcp_t fcp;
+ formattcc_t ftcc;
+ formattcc2_t ftcc2;
+ formatfcmp_t fcmp;
+ formatmbr_t fmb;
+ formatfmov_t fmv;
+ formatfused_t fused;
+} ifmt_t;
+
+/* integer register names */
+static const char *reg_names[32] = {
+ "%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
+ "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
+ "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
+ "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7"
+};
+
+/* floating point register names */
+static const char *freg_names[32] = {
+ "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
+ "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
+ "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
+ "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"
+};
+
+/* double precision register names */
+static const char *fdreg_names[32] = {
+ "%d0", "%d32", "%d2", "%d34", "%d4", "%d36", "%d6", "%d38",
+ "%d8", "%d40", "%d10", "%d42", "%d12", "%d44", "%d14", "%d46",
+ "%d16", "%d48", "%d18", "%d50", "%d20", "%d52", "%d22", "%d54",
+ "%d24", "%d56", "%d26", "%d58", "%d28", "%d60", "%d30", "%d62"
+};
+
+static const char *compat_fdreg_names[32] = {
+ "%f0", "%f32", "%f2", "%f34", "%f4", "%f36", "%f6", "%f38",
+ "%f8", "%f40", "%f10", "%f42", "%f12", "%f44", "%f14", "%f46",
+ "%f16", "%f48", "%f18", "%f50", "%f20", "%f52", "%f22", "%f54",
+ "%f24", "%f56", "%f26", "%f58", "%f28", "%f60", "%f30", "%f62"
+};
+
+
+static const char *fqreg_names[32] = {
+ "%q0", "%q32", "%f2", "%f3", "%f4", "%q4", "%q36", "%f6",
+ "%f7", "%q8", "%q40", "%f10", "%f11", "%q12", "%q44", "%f14",
+ "%f15", "%q16", "%q48", "%f18", "%f19", "%q20", "%q52", "%f22",
+ "%f23", "%q24", "%q56", "%f26", "%f27", "%q28", "%q60", "%f30",
+};
+
+
+/* coprocessor register names -- sparcv8 only */
+static const char *cpreg_names[32] = {
+ "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7",
+ "%c8", "%c9", "%c10", "%c11", "%c12", "%c13", "%c14", "%c15",
+ "%c16", "%c17", "%c18", "%c19", "%c20", "%c21", "%c22", "%c23",
+ "%c24", "%c25", "%c26", "%c27", "%c28", "%c29", "%c30", "%c31",
+};
+
+/* floating point condition code names */
+static const char *fcc_names[4] = {
+ "%fcc0", "%fcc1", "%fcc2", "%fcc3"
+};
+
+/* condition code names */
+static const char *icc_names[4] = {
+ "%icc", NULL, "%xcc", NULL
+};
+
+/* bitmask values for membar */
+static const char *membar_mmask[4] = {
+ "#LoadLoad", "#StoreLoad", "#LoadStore", "#StoreStore"
+};
+
+static const char *membar_cmask[3] = {
+ "#Lookaside", "#MemIssue", "#Sync"
+};
+
+/* v8 ancillary state register names */
+static const char *asr_names[32] = {
+ "%y", "%asr1", "%asr2", "%asr3",
+ "%asr4", "%asr5", "%asr6", "%asr7",
+ "%asr8", "%asr9", "%asr10", "%asr11",
+ "%asr12", "%asr13", "%asr14", "%asr15",
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL
+};
+static const uint32_t asr_rdmask = 0x0000ffffL;
+static const uint32_t asr_wrmask = 0x0000ffffL;
+
+static const char *v9_asr_names[32] = {
+ "%y", NULL, "%ccr", "%asi",
+ "%tick", "%pc", "%fprs", NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ "%pcr", "%pic", NULL, "%gsr",
+ "%softint_set", "%softint_clr", "%softint", "%tick_cmpr",
+ "%stick", "%stick_cmpr", NULL, NULL,
+ NULL, NULL, NULL, NULL
+};
+/*
+ * on v9, only certain registers are valid for read or writing
+ * these are bitmasks corresponding to which registers are valid in which
+ * case
+ */
+static const uint32_t v9_asr_rdmask = 0x03cb007d;
+static const uint32_t v9_asr_wrmask = 0x02fb004d;
+
+/* privledged register names on v9 */
+/* TODO: compat - NULL to %priv_nn */
+static const char *v9_privreg_names[32] = {
+ "%tpc", "%tnpc", "%tstate", "%tt",
+ "%tick", "%tba", "%pstate", "%tl",
+ "%pil", "%cwp", "%cansave", "%canrestore",
+ "%cleanwin", "%otherwin", "%wstate", "%fq",
+ "%gl", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "%ver"
+};
+
+static const uint32_t v9_pr_rdmask = 0x80017fff;
+static const uint32_t v9_pr_wrmask = 0x00017fef;
+
+static const char *prefetch_str[32] = {
+ "#n_reads", "#one_read",
+ "#n_writes", "#one_write",
+ "#page", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, "#unified", NULL, NULL,
+ "#n_reads_strong", "#one_read_strong",
+ "#n_writes_strong", "#one_write_strong",
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL
+};
+
+static void prt_field(const char *, uint32_t, int);
+
+static const char *get_regname(dis_handle_t *, int, uint32_t);
+static int32_t sign_extend(int32_t, int32_t);
+
+static void prt_name(dis_handle_t *, const char *, int);
+
+#define IMM_SIGNED 0x01 /* Is immediate value signed */
+#define IMM_ADDR 0x02 /* Is immediate value part of an address */
+static void prt_imm(dis_handle_t *, uint32_t, int);
+
+static void prt_asi(dis_handle_t *, uint32_t);
+static void prt_address(dis_handle_t *, uint32_t, int);
+static void prt_aluargs(dis_handle_t *, uint32_t, uint32_t);
+static void bprintf(dis_handle_t *, const char *, ...);
+
+/*
+ * print out val (which is 'bitlen' bits long) in binary
+ */
+#if defined(DIS_STANDALONE)
+/* ARGSUSED */
+void
+prt_binary(uint32_t val, int bitlen)
+{
+
+}
+
+#else
+
+void
+prt_binary(uint32_t val, int bitlen)
+{
+ int i;
+
+ for (i = bitlen - 1; i >= 0; --i) {
+ (void) fprintf(stderr, ((val & (1L << i)) != 0) ? "1" : "0");
+
+ if (i % 4 == 0 && i != 0)
+ (void) fprintf(stderr, " ");
+ }
+}
+#endif /* DIS_STANDALONE */
+
+
+/*
+ * print out a call instruction
+ * format: call address <name>
+ */
+/* ARGSUSED1 */
+int
+fmt_call(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+
+ int32_t disp;
+ size_t curlen;
+
+ int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f1.op, 2);
+ prt_field("disp30", f->f1.disp30, 30);
+ }
+
+ disp = sign_extend(f->f1.disp30, 30) * 4;
+
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+
+ bprintf(dhp, (octal != 0) ? "%s0%-11lo" : "%s0x%-10lx",
+ (disp < 0) ? "-" : "+",
+ (disp < 0) ? (-disp) : disp);
+
+ (void) strlcat(dhp->dh_buf, " <", dhp->dh_buflen);
+
+ curlen = strlen(dhp->dh_buf);
+ dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
+ dhp->dh_buf + curlen, dhp->dh_buflen - curlen - 1, NULL,
+ NULL);
+ (void) strlcat(dhp->dh_buf, ">", dhp->dh_buflen);
+
+
+ return (0);
+}
+
+int
+fmt_sethi(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f2.op, 2);
+ prt_field("op2", f->f2.op2, 3);
+ prt_field("rd", f->f2.rd, 5);
+ prt_field("imm22", f->f2.imm22, 22);
+ }
+
+ if (idx == 0) {
+ /* unimp / illtrap */
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+ prt_imm(dhp, f->f2.imm22, 0);
+ return (0);
+ }
+
+ if (f->f2.imm22 == 0 && f->f2.rd == 0) {
+ prt_name(dhp, "nop", 0);
+ return (0);
+ }
+
+ /* ?? Should we return -1 if rd == 0 && disp != 0 */
+
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+
+ bprintf(dhp,
+ ((dhp->dh_flags & DIS_OCTAL) != 0) ?
+ "%%hi(0%lo), %s" : "%%hi(0x%lx), %s",
+ f->f2.imm22 << 10,
+ reg_names[f->f2.rd]);
+
+ return (0);
+}
+
+/* ARGSUSED3 */
+int
+fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ const char *name = inp->in_data.in_def.in_name;
+ const char *r = NULL;
+ const char *annul = "";
+ const char *pred = "";
+
+ char buf[15];
+
+ ifmt_t *f = (ifmt_t *)&instr;
+
+ size_t curlen;
+ int32_t disp;
+ uint32_t flags = inp->in_data.in_def.in_flags;
+ int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f2.op, 2);
+ prt_field("op2", f->f2.op2, 3);
+
+ switch (FLG_DISP_VAL(flags)) {
+ case DISP22:
+ prt_field("cond", f->f2a.cond, 4);
+ prt_field("a", f->f2a.a, 1);
+ prt_field("disp22", f->f2a.disp22, 22);
+ break;
+
+ case DISP19:
+ prt_field("cond", f->f2a.cond, 4);
+ prt_field("a", f->f2a.a, 1);
+ prt_field("p", f->f2b.p, 1);
+ prt_field("cc", f->f2b.cc, 2);
+ prt_field("disp19", f->f2b.disp19, 19);
+ break;
+
+ case DISP16:
+ prt_field("bit 28", ((instr & (1L << 28)) >> 28), 1);
+ prt_field("rcond", f->f2c.cond, 3);
+ prt_field("p", f->f2c.p, 1);
+ prt_field("rs1", f->f2c.rs1, 5);
+ prt_field("d16hi", f->f2c.d16hi, 2);
+ prt_field("d16lo", f->f2c.d16lo, 14);
+ break;
+ }
+ }
+
+ if (f->f2b.op2 == 0x01 && idx == 0x00 && f->f2b.p == 1 &&
+ f->f2b.cc == 0x02 && ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) != 0)) {
+ name = "iprefetch";
+ flags = FLG_RS1(REG_NONE)|FLG_DISP(DISP19);
+ }
+
+ switch (FLG_DISP_VAL(flags)) {
+ case DISP22:
+ disp = sign_extend(f->f2a.disp22, 22);
+ break;
+
+ case DISP19:
+ disp = sign_extend(f->f2b.disp19, 19);
+ break;
+
+ case DISP16:
+ disp = sign_extend((f->f2c.d16hi << 14)|f->f2c.d16lo, 16);
+ break;
+
+ }
+
+ disp *= 4;
+
+ if ((FLG_RS1_VAL(flags) == REG_ICC) || (FLG_RS1_VAL(flags) == REG_FCC))
+ r = get_regname(dhp, FLG_RS1_VAL(flags), f->f2b.cc);
+ else
+ r = get_regname(dhp, FLG_RS1_VAL(flags), f->f2c.rs1);
+
+ if (r == NULL)
+ return (-1);
+
+ if (f->f2a.a == 1)
+ annul = ",a";
+
+ if ((flags & FLG_PRED) != 0) {
+ if (f->f2b.p == 0) {
+ pred = ",pn";
+ } else {
+ if ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0)
+ pred = ",pt";
+ }
+ }
+
+ (void) snprintf(buf, sizeof (buf), "%s%s%s", name, annul, pred);
+ prt_name(dhp, buf, 1);
+
+
+ switch (FLG_DISP_VAL(flags)) {
+ case DISP22:
+ bprintf(dhp,
+ (octal != 0) ? "%s0%-11lo <" : "%s0x%-10lx <",
+ (disp < 0) ? "-" : "+",
+ (disp < 0) ? (-disp) : disp);
+ break;
+
+ case DISP19:
+ bprintf(dhp,
+ (octal != 0) ? "%s, %s0%-5lo <" : "%s, %s0x%-04lx <",
+ r,
+ (disp < 0) ? "-" : "+",
+ (disp < 0) ? (-disp) : disp);
+ break;
+
+ case DISP16:
+ bprintf(dhp,
+ (octal != 0) ? "%s, %s0%-6lo <" : "%s, %s0x%-5lx <",
+ r,
+ (disp < 0) ? "-" : "+",
+ (disp < 0) ? (-disp) : disp);
+ break;
+ }
+
+ curlen = strlen(dhp->dh_buf);
+ dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
+ dhp->dh_buf + curlen, dhp->dh_buflen - curlen - 1, NULL, NULL);
+
+ (void) strlcat(dhp->dh_buf, ">", dhp->dh_buflen);
+
+ return (0);
+}
+
+
+
+/*
+ * print out the compare and swap instructions (casa/casxa)
+ * format: casa/casxa [%rs1] imm_asi, %rs2, %rd
+ * casa/casxa [%rs1] %asi, %rs2, %rd
+ *
+ * If DIS_DEBUG_SYN_ALL is set, synthetic instructions are emitted
+ * when an immediate ASI value is given as follows:
+ *
+ * casa [%rs1]#ASI_P, %rs2, %rd -> cas [%rs1], %rs2, %rd
+ * casa [%rs1]#ASI_P_L, %rs2, %rd -> casl [%rs1], %rs2, %rd
+ * casxa [%rs1]#ASI_P, %rs2, %rd -> casx [%rs1], %rs2, %rd
+ * casxa [%rs1]#ASI_P_L, %rs2, %rd -> casxl [%rs1], %rs2, %rd
+ */
+static int
+fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ int noasi = 0;
+
+ if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT)) != 0) {
+ if (f->f3.op3 == 0x3c && f->f3.i == 0) {
+ if (f->f3.asi == 0x80) {
+ noasi = 1;
+ name = "cas";
+ }
+
+ if (f->f3.asi == 0x88) {
+ noasi = 1;
+ name = "casl";
+ }
+ }
+
+ if (f->f3.op3 == 0x3e && f->f3.i == 0) {
+ if (f->f3.asi == 0x80) {
+ noasi = 1;
+ name = "casx";
+ }
+
+ if (f->f3.asi == 0x88) {
+ noasi = 1;
+ name = "casxl";
+ }
+ }
+ }
+
+ prt_name(dhp, name, 1);
+
+ bprintf(dhp, "[%s]", reg_names[f->f3.rs1]);
+
+ if (noasi == 0) {
+ (void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
+ prt_asi(dhp, instr);
+ }
+
+ bprintf(dhp, ", %s, %s", reg_names[f->f3.rs2], reg_names[f->f3.rd]);
+
+ return (0);
+}
+
+/*
+ * format a load/store instruction
+ * format: ldXX [%rs1 + %rs2], %rd load, i==0
+ * ldXX [%rs1 +/- nn], %rd load, i==1
+ * ldXX [%rs1 + %rs2] #XX, %rd load w/ imm_asi, i==0
+ * ldXX [%rs1 +/- nn] %asi, %rd load from asi[%asi], i==1
+ *
+ * stXX %rd, [%rs1 + %rs2] store, i==0
+ * stXX %rd, [%rs1 +/- nn] store, i==1
+ * stXX %rd, [%rs1 + %rs1] #XX store to imm_asi, i==0
+ * stXX %rd, [%rs1 +/-nn] %asi store to asi[%asi], i==1
+ *
+ * The register sets used for %rd are set in the instructions flags field
+ * The asi variants are used if FLG_ASI is set in the instructions flags field
+ *
+ * If DIS_DEBUG_SYNTH_ALL or DIS_DEBUG_COMPAT are set,
+ * When %rs1, %rs2 or nn are 0, they are not printed, i.e.
+ * [ %rs1 + 0x0 ], %rd -> [%rs1], %rd for example
+ *
+ * The following synthetic instructions are also implemented:
+ *
+ * stb %g0, [addr] -> clrb [addr] DIS_DEBUG_SYNTH_ALL
+ * sth %g0, [addr] -> crlh [addr] DIS_DEBUG_SYNTH_ALL
+ * stw %g0, [addr] -> clr [addr] DIS_DEBUG_SYNTH_ALL|DIS_DEBUG_COMPAT
+ * stx %g0, [addr] -> clrx [addr] DIS_DEBUG_SYNTH_ALL
+ *
+ * If DIS_DEBUG_COMPAT is set, the following substitutions also take place
+ * lduw -> ld
+ * ldtw -> ld
+ * stuw -> st
+ * sttw -> st
+ */
+int
+fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ const char *regstr = NULL;
+
+ const char *iname = inp->in_data.in_def.in_name;
+ uint32_t flags = inp->in_data.in_def.in_flags;
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f3.op, 2);
+ prt_field("op3", f->f3.op3, 6);
+ prt_field("rs1", f->f3.rs1, 5);
+ prt_field("i", f->f3.i, 1);
+ if (f->f3.i != 0) {
+ prt_field("simm13", f->f3a.simm13, 13);
+ } else {
+ if ((flags & FLG_ASI) != 0)
+ prt_field("imm_asi", f->f3.asi, 8);
+ prt_field("rs2", f->f3.rs2, 5);
+ }
+ prt_field("rd", f->f3.rd, 5);
+ }
+
+ if (idx == 0x2d || idx == 0x3d) {
+ /* prefetch / prefetcha */
+
+ prt_name(dhp, iname, 1);
+
+ prt_address(dhp, instr, 0);
+
+ if (idx == 0x3d) {
+ (void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
+ prt_asi(dhp, instr);
+ }
+
+ (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+
+ /* fcn field is the same as rd */
+ if (prefetch_str[f->f3.rd] != NULL)
+ (void) strlcat(dhp->dh_buf, prefetch_str[f->f3.rd],
+ dhp->dh_buflen);
+ else
+ prt_imm(dhp, f->f3.rd, 0);
+
+ return (0);
+ }
+
+ /* casa / casxa */
+ if (idx == 0x3c || idx == 0x3e)
+ return (fmt_cas(dhp, instr, iname));
+
+ /* synthetic instructions & special cases */
+ switch (idx) {
+ case 0x00:
+ /* ld */
+ if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ iname = "lduw";
+ break;
+
+ case 0x03:
+ if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ iname = "ldtw";
+ break;
+
+ case 0x04:
+ /* stw */
+ if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ iname = "stuw";
+
+ if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
+ == 0)
+ break;
+
+ if (f->f3.rd == 0) {
+ iname = "clr";
+ flags = FLG_RD(REG_NONE);
+ }
+ break;
+
+ case 0x05:
+ /* stb */
+ if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
+ == 0)
+ break;
+
+ if (f->f3.rd == 0) {
+ iname = "clrb";
+ flags = FLG_RD(REG_NONE);
+ }
+ break;
+
+ case 0x06:
+ /* sth */
+ if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
+ == 0)
+ break;
+
+ if (f->f3.rd == 0) {
+ iname = "clrh";
+ flags = FLG_RD(REG_NONE);
+ }
+ break;
+
+ case 0x07:
+ if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ iname = "sttw";
+ break;
+
+ case 0x0e:
+ /* stx */
+
+ if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
+ == 0)
+ break;
+
+ if (f->f3.rd == 0) {
+ iname = "clrx";
+ flags = FLG_RD(REG_NONE);
+ }
+ break;
+
+ case 0x13:
+ /* ldtwa */
+ if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) &&
+ ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
+ iname = "ldtwa";
+ break;
+
+ case 0x17:
+ /* sttwa */
+ if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) &&
+ ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
+ iname = "sttwa";
+ break;
+
+ case 0x21:
+ case 0x25:
+ /*
+ * on sparcv8 it merely says that rd != 1 should generate an
+ * exception, on v9, it is illegal
+ */
+ if ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0)
+ break;
+
+ iname = (idx == 0x21) ? "ldx" : "stx";
+
+ if (f->f3.rd > 1)
+ return (-1);
+
+ break;
+
+ case 0x31:
+ /* stda */
+ switch (f->f3.asi) {
+ case 0xc0:
+ case 0xc1:
+ case 0xc8:
+ case 0xc9:
+ case 0xc2:
+ case 0xc3:
+ case 0xca:
+ case 0xcb:
+ case 0xc4:
+ case 0xc5:
+ case 0xcc:
+ case 0xcd:
+ /*
+ * store partial floating point, only valid w/
+ * vis
+ *
+ * Somewhat confusingly, it uses the same op
+ * code as 'stda' -- store double to alternate
+ * space. It is distinguised by specific
+ * imm_asi values (as seen above), and
+ * has a slightly different output syntax
+ */
+
+ if ((dhp->dh_flags & DIS_SPARC_V9_SGI) == 0)
+ break;
+ if (f->f3.i != 0)
+ break;
+ prt_name(dhp, iname, 1);
+ bprintf(dhp, "%s, %s, [%s] ",
+ get_regname(dhp, REG_FPD, f->f3.rd),
+ get_regname(dhp, REG_FPD, f->f3.rs2),
+ get_regname(dhp, REG_FPD, f->f3.rs1));
+ prt_asi(dhp, instr);
+ return (0);
+
+ default:
+ break;
+ }
+
+ }
+
+ regstr = get_regname(dhp, FLG_RD_VAL(flags), f->f3.rd);
+
+ prt_name(dhp, iname, 1);
+
+ if ((flags & FLG_STORE) != 0) {
+ if (regstr[0] != '\0') {
+ (void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
+ (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ }
+
+ prt_address(dhp, instr, 0);
+ if ((flags & FLG_ASI) != 0) {
+ (void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
+ prt_asi(dhp, instr);
+ }
+ } else {
+ prt_address(dhp, instr, 0);
+ if ((flags & FLG_ASI) != 0) {
+ (void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
+ prt_asi(dhp, instr);
+ }
+
+ if (regstr[0] != '\0') {
+ (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
+ }
+ }
+
+ return (0);
+}
+
+static int
+fmt_cpop(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ int flags = FLG_P1(REG_CP)|FLG_P2(REG_CP)|FLG_NOIMM|FLG_P3(REG_CP);
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->fcp.op, 2);
+ prt_field("op3", f->fcp.op3, 6);
+ prt_field("opc", f->fcp.opc, 9);
+ prt_field("rs1", f->fcp.rs1, 5);
+ prt_field("rs2", f->fcp.rs2, 5);
+ prt_field("rd", f->fcp.rd, 5);
+ }
+
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+ prt_imm(dhp, f->fcp.opc, 0);
+
+ (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) prt_aluargs(dhp, instr, flags);
+
+ return (0);
+}
+
+static int
+dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ const char *psr_str = "%psr";
+ const char *wim_str = "%wim";
+ const char *tbr_str = "%tbr";
+
+ const char *name = inp->in_data.in_def.in_name;
+ const char *regstr = NULL;
+
+ ifmt_t *f = (ifmt_t *)&instr;
+
+ int rd = (idx < 0x30);
+ int v9 = (dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI));
+ int ridx = f->f3.rs1;
+ int i, first;
+ int pr_rs1 = 1;
+ int pr_rs2 = 1;
+
+ int use_mask = 1;
+ uint32_t mask;
+
+ if (rd == 0)
+ ridx = f->f3.rd;
+
+ switch (idx) {
+ case 0x28:
+ /* rd */
+
+ /* stbar */
+ if ((f->f3.rd == 0) && (f->f3.rs1 == 15) && (f->f3.i == 0)) {
+ prt_name(dhp, "stbar", 0);
+ return (0);
+ }
+
+ /* membar */
+ if ((v9 != 0) && (f->f3.rd == 0) && (f->f3.rs1 == 15) &&
+ (f->f3.i == 1) && ((f->i & (1L << 12)) == 0)) {
+
+ prt_name(dhp, "membar",
+ ((f->fmb.cmask != 0) || (f->fmb.mmask != 0)));
+
+ first = 0;
+
+ for (i = 0; i < 4; ++i) {
+ if ((f->fmb.cmask & (1L << i)) != 0) {
+ bprintf(dhp, "%s%s",
+ (first != 0) ? "|" : "",
+ membar_cmask[i]);
+ first = 1;
+ }
+ }
+
+ for (i = 0; i < 5; ++i) {
+ if ((f->fmb.mmask & (1L << i)) != 0) {
+ bprintf(dhp, "%s%s",
+ (first != 0) ? "|" : "",
+ membar_mmask[i]);
+ first = 1;
+ }
+ }
+
+ return (0);
+ }
+
+ if (v9 != 0) {
+ regstr = v9_asr_names[ridx];
+ mask = v9_asr_rdmask;
+ } else {
+ regstr = asr_names[ridx];
+ mask = asr_rdmask;
+ }
+ break;
+
+ case 0x29:
+ /*
+ * NOTE: due to an overlay entry, this only gets executed when
+ * disassembling v8 instructions
+ */
+ regstr = psr_str;
+ use_mask = 0;
+ break;
+
+ case 0x2a:
+ if (v9 != 0) {
+ regstr = v9_privreg_names[ridx];
+ mask = v9_pr_rdmask;
+ } else {
+ regstr = wim_str;
+ use_mask = 0;
+ }
+ break;
+
+ case 0x2b:
+ if (v9 != 0) {
+ /* flushw */
+ prt_name(dhp, name, 0);
+ return (0);
+ }
+
+ regstr = tbr_str;
+ use_mask = 0;
+ break;
+
+ case 0x30:
+ if (v9 != 0) {
+ regstr = v9_asr_names[ridx];
+ mask = v9_asr_wrmask;
+ } else {
+ regstr = asr_names[ridx];
+ mask = asr_wrmask;
+ }
+
+ /* synth: mov */
+ if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
+ == 0)
+ break;
+
+ if (f->f3.rs1 == 0) {
+ name = "mov";
+ pr_rs1 = 0;
+ }
+
+ if ((f->f3.i == 0 && f->f3.rs2 == 0) ||
+ (f->f3.i == 1 && f->f3a.simm13 == 0)) {
+ name = "mov";
+ pr_rs2 = 0;
+ }
+
+ if (pr_rs1 == 0)
+ pr_rs2 = 1;
+
+ break;
+
+ case 0x31:
+ /*
+ * NOTE: due to the presence of an overlay entry for another
+ * table, this case only happens when doing v8 instructions
+ * only
+ */
+ regstr = psr_str;
+ use_mask = 0;
+ break;
+
+ case 0x32:
+ if (v9 != 0) {
+ regstr = v9_privreg_names[ridx];
+ mask = v9_pr_wrmask;
+ } else {
+ regstr = wim_str;
+ use_mask = 0;
+ }
+ break;
+
+ case 0x33:
+ /* NOTE: due to an overlay entry, this is v8 only */
+ regstr = tbr_str;
+ use_mask = 0;
+ break;
+ }
+
+ if (regstr == NULL)
+ return (-1);
+
+ if (use_mask != 0 && ((1L << ridx) & mask) == 0)
+ return (-1);
+
+ prt_name(dhp, name, 1);
+
+ if (rd != 0) {
+ bprintf(dhp, "%s, %s", regstr, reg_names[f->f3.rd]);
+ } else {
+ if (pr_rs1 == 1)
+ bprintf(dhp, "%s, ", reg_names[f->f3.rs1]);
+
+ if (pr_rs2 != 0) {
+ if (f->f3.i == 1)
+ prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
+ IMM_SIGNED);
+ else
+ (void) strlcat(dhp->dh_buf,
+ reg_names[f->f3.rs2], dhp->dh_buflen);
+ (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ }
+
+ (void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
+ }
+
+ return (0);
+}
+
+/* ARGSUSED3 */
+int
+fmt_trap(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+
+ int v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
+ int p_rs1, p_t;
+
+ if (f->ftcc.undef != 0)
+ return (-1);
+
+ if (icc_names[f->ftcc.cc] == NULL)
+ return (-1);
+
+ if (f->ftcc.i == 1 && f->ftcc.undef2 != 0)
+ return (-1);
+
+ if (f->ftcc2.i == 0 && f->ftcc2.undef2 != 0)
+ return (-1);
+
+ p_rs1 = ((f->ftcc.rs1 != 0) ||
+ ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0));
+
+ if (f->ftcc.i == 0) {
+ p_t = (f->f3.rs2 != 0 || p_rs1 == 0);
+
+ bprintf(dhp, "%-9s %s%s%s%s%s", inp->in_data.in_def.in_name,
+ (v9 != 0) ? icc_names[f->ftcc2.cc] : "",
+ (v9 != 0) ? ", " : "",
+ (p_rs1 != 0) ? reg_names[f->ftcc2.rs1] : "",
+ (p_rs1 != 0) ? " + " : "",
+ (p_t != 0) ? reg_names[f->f3.rs2] : "");
+ } else {
+ bprintf(dhp, "%-9s %s%s%s%s0x%x", inp->in_data.in_def.in_name,
+ (v9 != 0) ? icc_names[f->ftcc2.cc] : "",
+ (v9 != 0) ? ", " : "",
+ (p_rs1 != 0) ? reg_names[f->ftcc2.rs1] : "",
+ (p_rs1 != 0) ? " + " : "",
+ f->ftcc.immtrap);
+ }
+
+ return (0);
+}
+
+static int
+prt_shift(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
+{
+ char name[5];
+ uint32_t cnt;
+
+ ifmt_t *f = (ifmt_t *)&instr;
+ int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
+
+ name[0] = '\0';
+ (void) strlcat(name, inp->in_data.in_def.in_name, sizeof (name));
+
+ if (f->f3b.i == 1)
+ cnt = f->f3.rs2;
+
+ if (f->f3b.x == 1 && ((dhp->dh_flags & DIS_SPARC_V8) == 0)) {
+ cnt = f->f3b.shcnt;
+ (void) strlcat(name, "x", sizeof (name));
+ }
+
+ prt_name(dhp, name, 1);
+
+ if (f->f3b.i == 1)
+ bprintf(dhp, (octal != 0) ? "%s, 0%lo, %s" : "%s, 0x%lx, %s",
+ reg_names[f->f3.rs1], cnt, reg_names[f->f3.rd]);
+ else
+ bprintf(dhp, "%s, %s, %s", reg_names[f->f3.rs1],
+ reg_names[f->f3.rs2], reg_names[f->f3.rd]);
+
+ return (0);
+}
+
+/* ARGSUSED3 */
+static int
+prt_jmpl(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ const char *name = inp->in_data.in_def.in_name;
+ ifmt_t *f = (ifmt_t *)&instr;
+
+ if (f->f3.rd == 15 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0))
+ name = "call";
+
+ if (f->f3.rd == 0) {
+ if (f->f3.i == 1 && f->f3a.simm13 == 8) {
+ if (f->f3.rs1 == 15) {
+ prt_name(dhp, "retl", 0);
+ return (0);
+ }
+
+ if (f->f3.rs1 == 31) {
+ prt_name(dhp, "ret", 0);
+ return (0);
+ }
+ }
+
+ name = "jmp";
+ }
+
+ prt_name(dhp, name, 1);
+ prt_address(dhp, instr, 1);
+
+ if (f->f3.rd == 0)
+ return (0);
+
+ if (f->f3.rd == 15 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0))
+ return (0);
+
+ bprintf(dhp, ", %s", reg_names[f->f3.rd]);
+
+ return (0);
+}
+
+int
+fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+
+ const char *name = inp->in_data.in_def.in_name;
+ int flags = inp->in_data.in_def.in_flags;
+ int arg = 0;
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f3.op, 2);
+ prt_field("op3", f->f3.op3, 6);
+ prt_field("rs1", f->f3.rs1, 5);
+
+ switch (idx) {
+ /* TODO: more formats */
+
+ default:
+ if (f->f3.i == 0)
+ prt_field("rs2", f->f3.rs2, 5);
+ else
+ prt_field("simm13", f->f3a.simm13, 13);
+
+ prt_field("rd", f->f3.rd, 5);
+ }
+
+ }
+
+ switch (idx) {
+ case 0x00:
+ /* add */
+
+ if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
+ break;
+
+ if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
+ f->f3a.simm13 == 1) {
+ name = "inc";
+ flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
+ break;
+ }
+
+ if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
+ f->f3a.simm13 != 1) {
+ name = "inc";
+ flags = FLG_P1(REG_NONE);
+ break;
+ }
+ break;
+
+ case 0x02:
+ /* or */
+
+ if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ == 0)
+ break;
+
+ if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) != 0) {
+ if (f->f3.rs1 == f->f3.rd) {
+ name = "bset";
+ flags = FLG_P1(REG_NONE);
+ break;
+ }
+ }
+
+ if (((f->f3.i == 0 && f->f3.rs2 == 0) ||
+ (f->f3.i == 1 && f->f3a.simm13 == 0)) &&
+ (f->f3.rs1 == 0)) {
+ name = "clr";
+ flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
+ break;
+ }
+
+ if (f->f3.rs1 == 0) {
+ name = "mov";
+ flags = FLG_P1(REG_NONE);
+ break;
+ }
+ break;
+
+ case 0x04:
+ /* sub */
+
+ if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ == 0)
+ break;
+
+ if (f->f3.rs1 == 0 && f->f3.i == 0 && f->f3.rs2 == f->f3.rd) {
+ name = "neg";
+ flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE);
+ break;
+ }
+
+ if (f->f3.rs1 == 0 && f->f3.i == 0 && f->f3.rs2 != f->f3.rd) {
+ name = "neg";
+ flags = FLG_P1(REG_NONE);
+ break;
+ }
+
+ if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
+ break;
+
+ if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
+ f->f3a.simm13 == 1) {
+ name = "dec";
+ flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
+ break;
+ }
+
+ if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
+ f->f3a.simm13 != 1) {
+ name = "dec";
+ flags = FLG_P1(REG_NONE);
+ break;
+ }
+ break;
+
+ case 0x07:
+ /* xnor */
+
+ if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ == 0)
+ break;
+
+ /*
+ * xnor -> not when you have:
+ * xnor %rs1, 0x0 or %g0, %rd
+ */
+ if ((f->f3.i == 0 && f->f3.rs2 != 0) ||
+ (f->f3.i == 1 && f->f3a.simm13 != 0))
+ break;
+
+ name = "not";
+
+ if (f->f3.rs1 == f->f3.rd)
+ flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM|
+ FLG_P3(REG_INT);
+ else
+ flags = FLG_P1(REG_INT)|FLG_P2(REG_NONE)|FLG_NOIMM|
+ FLG_P3(REG_INT);
+
+ break;
+
+ case 0x10:
+ /* addcc */
+
+ if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
+ break;
+
+ if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
+ f->f3a.simm13 == 1) {
+ name = "inccc";
+ flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
+ break;
+ }
+
+ if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
+ f->f3a.simm13 != 1) {
+ name = "inccc";
+ flags = FLG_P1(REG_NONE);
+ break;
+ }
+ break;
+
+ case 0x11:
+ /* andcc */
+
+ if (f->f3.rd != 0)
+ break;
+
+ if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
+ == 0)
+ break;
+
+ if (((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0) &&
+ ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0))
+ break;
+
+ name = "btst";
+ flags = FLG_P1(REG_NONE);
+ f->f3.rd = f->f3.rs1;
+ break;
+
+ case 0x12:
+ /* orcc */
+
+ if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ == 0)
+ break;
+
+ if (f->f3.rs1 == 0 && f->f3.rd == 0 && f->f3.i == 0) {
+ name = "tst";
+ flags = FLG_P1(REG_NONE)|FLG_P3(REG_NONE);
+ break;
+ }
+
+ if (f->f3.rs2 == 0 && f->f3.rd == 0 && f->f3.i == 0) {
+ name = "tst";
+ flags = FLG_P2(REG_NONE)|FLG_P3(REG_NONE);
+ break;
+ }
+
+ break;
+
+ case 0x14:
+ /* subcc */
+
+ if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ == 0)
+ break;
+
+ if (f->f3.rd == 0) {
+ name = "cmp";
+ flags = FLG_P3(REG_NONE);
+ break;
+ }
+
+ if ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0)
+ break;
+
+ if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
+ f->f3a.simm13 == 1) {
+ name = "deccc";
+ flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
+ break;
+ }
+
+ if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
+ f->f3a.simm13 != 1) {
+ name = "deccc";
+ flags = FLG_P1(REG_NONE);
+ break;
+ }
+
+ break;
+
+ case 0x25:
+ case 0x26:
+ case 0x27:
+ return (prt_shift(dhp, instr, inp));
+
+ case 0x28:
+ case 0x29:
+ case 0x2a:
+ case 0x2b:
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ return (dis_fmt_rdwr(dhp, instr, inp, idx));
+
+ case 0x36:
+ case 0x37:
+ /* NOTE: overlayed on v9 */
+ if ((dhp->dh_flags & DIS_SPARC_V8) != 0)
+ return (fmt_cpop(dhp, instr, inp));
+ break;
+
+ case 0x38:
+ /* jmpl */
+ return (prt_jmpl(dhp, instr, inp, idx));
+
+ case 0x39:
+ /* rett / return */
+ prt_name(dhp, name, 1);
+ prt_address(dhp, instr, 1);
+ return (0);
+
+ case 0x3b:
+ /* flush */
+ prt_name(dhp, name, 1);
+ prt_address(dhp, instr, 0);
+ return (0);
+
+ case 0x3c:
+ case 0x3d:
+ /* save / restore */
+ if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ == 0)
+ break;
+
+ if (f->f3.rs1 != 0 || f->f3.rs2 != 0 || f->f3.rd != 0)
+ break;
+
+ if (f->f3.i != 0 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0))
+ break;
+
+ prt_name(dhp, name, 0);
+ return (0);
+ }
+
+ if (FLG_P1_VAL(flags) != REG_NONE || FLG_P2_VAL(flags) != REG_NONE ||
+ FLG_P3_VAL(flags) != REG_NONE)
+ arg = 1;
+
+ prt_name(dhp, name, (arg != 0));
+ prt_aluargs(dhp, instr, flags);
+
+ return (0);
+}
+
+/* ARGSUSED1 */
+int
+fmt_regwin(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ prt_name(dhp, inp->in_data.in_def.in_name, 0);
+ return (0);
+}
+
+/* ARGSUSED1 */
+int
+fmt_trap_ret(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ prt_name(dhp, inp->in_data.in_def.in_name, 0);
+ return (0);
+}
+
+/* ARGSUSED3 */
+int
+fmt_movcc(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ const char **regs = NULL;
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f3c.op, 2);
+ prt_field("op3", f->f3c.op3, 6);
+ prt_field("cond", f->f3c.cond, 4);
+ prt_field("cc2", f->f3c.cc2, 1);
+ prt_field("cc", f->f3c.cc, 2);
+ prt_field("i", f->f3c.i, 1);
+
+ if (f->f3c.i == 0)
+ prt_field("rs2", f->f3.rs2, 5);
+ else
+ prt_field("simm11", f->f3c.simm11, 11);
+
+ prt_field("rd", f->f3.rd, 5);
+ }
+
+ if (f->f3c.cc2 == 0) {
+ regs = fcc_names;
+ } else {
+ regs = icc_names;
+ if (regs[f->f3c.cc] == NULL)
+ return (-1);
+ }
+
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+
+ bprintf(dhp, "%s, ", regs[f->f3c.cc]);
+
+ if (f->f3c.i == 1)
+ prt_imm(dhp, sign_extend(f->f3c.simm11, 11), IMM_SIGNED);
+ else
+ (void) strlcat(dhp->dh_buf, reg_names[f->f3.rs2],
+ dhp->dh_buflen);
+
+ bprintf(dhp, ", %s", reg_names[f->f3.rd]);
+
+ return (0);
+}
+
+/* ARGSUSED3 */
+int
+fmt_movr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+
+ bprintf(dhp, "%s, ", reg_names[f->f3d.rs1]);
+
+ if (f->f3d.i == 1)
+ prt_imm(dhp, sign_extend(f->f3d.simm10, 10), IMM_SIGNED);
+ else
+ (void) strlcat(dhp->dh_buf, reg_names[f->f3.rs2],
+ dhp->dh_buflen);
+
+ bprintf(dhp, ", %s", reg_names[f->f3.rd]);
+
+ return (0);
+}
+
+/* ARGSUSED3 */
+int
+fmt_fpop1(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ int flags = inp->in_data.in_def.in_flags;
+
+ flags |= FLG_NOIMM;
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f3.op, 2);
+ prt_field("op3", f->f3.op3, 6);
+ prt_field("opf", f->fcmp.opf, 9);
+ prt_field("rs1", f->f3.rs1, 5);
+ prt_field("rs2", f->f3.rs2, 5);
+ prt_field("rd", f->f3.rd, 5);
+ }
+
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+ prt_aluargs(dhp, instr, flags);
+
+ return (0);
+}
+
+int
+fmt_fpop2(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ static const char *condstr_icc[16] = {
+ "n", "e", "le", "l", "leu", "lu", "neg", "vs",
+ "a", "nz", "g", "ge", "gu", "geu", "pos", "vc"
+ };
+
+ static const char *condstr_fcc[16] = {
+ "n", "nz", "lg", "ul", "l", "ug", "g", "u",
+ "a", "e", "ue", "ge", "uge", "le", "ule", "o"
+ };
+
+ ifmt_t *f = (ifmt_t *)&instr;
+ const char *ccstr = "";
+ char name[15];
+
+ int flags = inp->in_data.in_def.in_flags;
+ int is_cmp = (idx == 0x51 || idx == 0x52 || idx == 0x53 ||
+ idx == 0x55 || idx == 0x56 || idx == 0x57);
+ int is_fmov = (idx & 0x3f);
+ int is_v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
+ int is_compat = ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0);
+
+ int p_cc = 0;
+
+ is_fmov = (is_fmov == 0x1 || is_fmov == 0x2 || is_fmov == 0x3);
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f3.op, 2);
+ prt_field("op3", f->f3.op3, 6);
+ prt_field("opf", f->fcmp.opf, 9);
+
+ switch (idx & 0x3f) {
+ case 0x51:
+ case 0x52:
+ case 0x53:
+ case 0x55:
+ case 0x56:
+ case 0x57:
+ prt_field("cc", f->fcmp.cc, 2);
+ prt_field("rs1", f->f3.rs1, 5);
+ prt_field("rs2", f->f3.rs2, 5);
+ break;
+
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ prt_field("opf_low", f->fmv.opf, 6);
+ prt_field("cond", f->fmv.cond, 4);
+ prt_field("opf_cc", f->fmv.cc, 3);
+ prt_field("rs2", f->fmv.rs2, 5);
+ break;
+
+ default:
+ prt_field("rs1", f->f3.rs1, 5);
+ prt_field("rs2", f->f3.rs2, 5);
+ prt_field("rd", f->f3.rd, 5);
+ }
+ }
+
+ name[0] = '\0';
+ (void) strlcat(name, inp->in_data.in_def.in_name, sizeof (name));
+
+ if (is_fmov != 0) {
+ (void) strlcat(name,
+ (f->fmv.cc < 4) ? condstr_fcc[f->fmv.cond]
+ : condstr_icc[f->fmv.cond],
+ sizeof (name));
+ }
+
+ prt_name(dhp, name, 1);
+
+ if (is_cmp != 0)
+ ccstr = fcc_names[f->fcmp.cc];
+
+ if (is_fmov != 0)
+ ccstr = (f->fmv.cc < 4) ? fcc_names[f->fmv.cc & 0x3]
+ : icc_names[f->fmv.cc & 0x3];
+
+ if (ccstr == NULL)
+ return (-1);
+
+ p_cc = (is_compat == 0 || is_v9 != 0 ||
+ (is_cmp != 0 && f->fcmp.cc != 0) ||
+ (is_fmov != 0 && f->fmv.cc != 0));
+
+ if (p_cc != 0)
+ bprintf(dhp, "%s, ", ccstr);
+
+ prt_aluargs(dhp, instr, flags);
+
+ return (0);
+}
+
+int
+fmt_vis(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ int flags = inp->in_data.in_def.in_flags;
+
+ if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ prt_field("op", f->f3.op, 2);
+ prt_field("op3", f->f3.op3, 6);
+ prt_field("opf", f->fcmp.opf, 9);
+
+ if (idx == 0x081) {
+ prt_field("mode", instr & 02L, 2);
+ } else {
+ prt_field("rs1", f->f3.rs1, 5);
+ prt_field("rs2", f->f3.rs2, 5);
+ prt_field("rd", f->f3.rd, 5);
+ }
+ }
+
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+
+ if (idx == 0x081) {
+ /* siam */
+ bprintf(dhp, "%d", instr & 0x7L);
+ return (0);
+ }
+
+ prt_aluargs(dhp, instr, flags);
+
+ return (0);
+}
+
+/* ARGSUSED3 */
+int
+fmt_fused(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ int flags = inp->in_data.in_def.in_flags;
+
+ prt_name(dhp, inp->in_data.in_def.in_name, 1);
+ bprintf(dhp, "%s, %s, %s, %s",
+ get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs1),
+ get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs2),
+ get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs3),
+ get_regname(dhp, FLG_P1_VAL(flags), f->fused.rd));
+
+ return (0);
+}
+/*
+ * put name into the output buffer
+ * if add_space !=0, append a space after it
+ */
+static void
+prt_name(dis_handle_t *dhp, const char *name, int add_space)
+{
+ bprintf(dhp, (add_space == 0) ? "%s" : "%-9s ", name);
+}
+
+/*
+ * For debugging, print out a field of the instruction
+ * field is the name of the field
+ * val is the value of the field
+ * len is the length of the field (in bits)
+ */
+#if defined(DIS_STANDALONE)
+/* ARGSUSED */
+static void
+prt_field(const char *field, uint32_t val, int len)
+{
+
+}
+
+#else
+static void
+prt_field(const char *field, uint32_t val, int len)
+{
+ (void) fprintf(stderr, "DISASM: %8s = 0x%-8ulx (", field, val);
+ prt_binary(val, len);
+ (void) fprintf(stderr, ")\n");
+}
+#endif /* DIS_STANDALONE */
+
+/*
+ * sign extend a val (that is 'bits' bits in length) to a 32-bit signed
+ * integer
+ */
+static int32_t
+sign_extend(int32_t val, int32_t bits)
+{
+ if ((val & (1L << (bits - 1))) == 0)
+ return (val);
+
+ return ((-1L << bits) | val);
+}
+
+/*
+ * print out an immediate (i.e. constant) value
+ * val is the value
+ * format indicates if it is:
+ * 0 Unsigned
+ * IMM_SIGNED A signed value (prepend +/- to the value)
+ * IMM_ADDR Part of an address expression (prepend +/- but with a space
+ * between the sign and the value for things like [%i1 + 0x55]
+ */
+static void
+prt_imm(dis_handle_t *dhp, uint32_t val, int format)
+{
+ const char *fmtstr = NULL;
+ int32_t sv = (int32_t)val;
+ int octal = dhp->dh_flags & DIS_OCTAL;
+
+ switch (format) {
+ case IMM_ADDR:
+ if (sv < 0) {
+ sv = -sv;
+ fmtstr = (octal != 0) ? "- 0%lo" : "- 0x%lx";
+ } else {
+ fmtstr = (octal != 0) ? "+ 0%lo" : "+ 0x%lx";
+ }
+ break;
+
+ case IMM_SIGNED:
+ if (sv < 0) {
+ sv = -sv;
+ fmtstr = (octal != 0) ? "-0%lo" : "-0x%lx";
+ break;
+ }
+ /* fall through */
+
+ default:
+ fmtstr = (octal != 0) ? "0%lo" : "0x%lx";
+ }
+
+ bprintf(dhp, fmtstr, sv);
+}
+
+/*
+ * return the symbolic name of a register
+ * regset is one of the REG_* values indicating which type of register it is
+ * such as integer, floating point, etc.
+ * idx is the numeric value of the register
+ *
+ * If regset is REG_NONE, an empty, but non-NULL string is returned
+ * NULL may be returned if the index indicates an invalid register value
+ * such as with the %icc/%xcc sets
+ */
+static const char *
+get_regname(dis_handle_t *dhp, int regset, uint32_t idx)
+{
+ const char *regname = NULL;
+
+ switch (regset) {
+ case REG_INT:
+ regname = reg_names[idx];
+ break;
+
+ case REG_FP:
+ regname = freg_names[idx];
+ break;
+
+ case REG_FPD:
+ if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ regname = fdreg_names[idx];
+ else
+ regname = compat_fdreg_names[idx];
+
+ break;
+
+ case REG_FPQ:
+ if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ regname = fqreg_names[idx];
+ else
+ regname = freg_names[idx];
+
+ break;
+
+ case REG_CP:
+ regname = cpreg_names[idx];
+ break;
+
+ case REG_ICC:
+ regname = icc_names[idx];
+ break;
+
+ case REG_FCC:
+ regname = fcc_names[idx];
+ break;
+
+ case REG_FSR:
+ regname = "%fsr";
+ break;
+
+ case REG_CSR:
+ regname = "%csr";
+ break;
+
+ case REG_CQ:
+ regname = "%cq";
+ break;
+
+ case REG_NONE:
+ regname = "";
+ break;
+ }
+
+ return (regname);
+}
+
+/*
+ * output the asi value from the instruction
+ *
+ * TODO: investigate if this should perhaps have a mask -- are undefined ASI
+ * values for an instruction still disassembled??
+ */
+static void
+prt_asi(dis_handle_t *dhp, uint32_t instr)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
+
+ if (f->f3.i != 0)
+ bprintf(dhp, "%%asi");
+ else
+ bprintf(dhp, (octal != 0) ? "0%03o" : "0x%02x", f->f3.asi);
+
+}
+
+/*
+ * put an address expression into the output buffer
+ *
+ * instr is the instruction to use
+ * if nobrackets != 0, [] are not added around the instruction
+ *
+ * Currently this option is set when printing out the address portion
+ * of a jmpl instruction, but otherwise 0 for load/stores
+ *
+ * If no debug flags are set, the full expression is output, even when
+ * %g0 or 0x0 appears in the address
+ *
+ * If DIS_DEBUG_SYN_ALL or DIS_DEBUG_COMPAT are set, when %g0 or 0x0
+ * appear in the address, they are not output. If the wierd (and probably
+ * shouldn't happen) address of [%g0 + %g0] or [%g0 + 0x0] is encountered,
+ * [%g0] is output
+ */
+static void
+prt_address(dis_handle_t *dhp, uint32_t instr, int nobrackets)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ int32_t simm13;
+ int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
+ int p1 = ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
+ int p2 = ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
+
+ if (f->f3a.i == 0) {
+ p1 |= ((f->f3a.rs1 != 0) || f->f3.rs2 == 0);
+ p2 |= (f->f3.rs2 != 0);
+
+ bprintf(dhp, "%s%s%s%s%s",
+ (nobrackets == 0) ? "[" : "",
+ (p1 != 0) ? reg_names[f->f3a.rs1] : "",
+ (p1 != 0 && p2 != 0) ? " + " : "",
+ (p2 != 0) ? reg_names[f->f3.rs2] : "",
+ (nobrackets == 0) ? "]" : "");
+ } else {
+ const char *sign;
+
+ simm13 = sign_extend(f->f3a.simm13, 13);
+ sign = (simm13 < 0) ? "-" : "+";
+
+ p1 |= (f->f3a.rs1 != 0);
+ p2 |= (p1 == 0 || simm13 != 0);
+
+ if (p1 == 0 && simm13 == 0)
+ p2 = 1;
+
+ if (p1 == 0 && simm13 >= 0)
+ sign = "";
+
+ if (p2 != 0)
+ bprintf(dhp,
+ (octal != 0) ? "%s%s%s%s%s0%lo%s" :
+ "%s%s%s%s%s0x%lx%s",
+ (nobrackets == 0) ? "[" : "",
+ (p1 != 0) ? reg_names[f->f3a.rs1] : "",
+ (p1 != 0) ? " " : "",
+ sign,
+ (p1 != 0) ? " " : "",
+ (simm13 < 0) ? -(simm13) : simm13,
+ (nobrackets == 0) ? "]" : "");
+ else
+ bprintf(dhp, "%s%s%s",
+ (nobrackets == 0) ? "[" : "",
+ reg_names[f->f3a.rs1],
+ (nobrackets == 0) ? "]" : "");
+ }
+}
+
+/*
+ * print out the arguments to an alu operation (add, sub, etc.)
+ * conatined in 'instr'
+ *
+ * alu instructions have the following format:
+ * %rs1, %rs2, %rd (i == 0)
+ * %rs1, 0xnnn, %rd (i == 1)
+ * ^ ^ ^
+ * | | |
+ * p1 p2 p3
+ *
+ * flags indicates the register set to use for each position (p1, p2, p3)
+ * as well as if immediate values (i == 1) are allowed
+ *
+ * if flags indicates a specific position has REG_NONE set as it's register
+ * set, it is omitted from the output. This is primarly used for certain
+ * floating point operations
+ */
+static void
+prt_aluargs(dis_handle_t *dhp, uint32_t instr, uint32_t flags)
+{
+ ifmt_t *f = (ifmt_t *)&instr;
+ const char *r1, *r2, *r3;
+ int p1, p2, p3;
+
+ r1 = get_regname(dhp, FLG_P1_VAL(flags), f->f3.rs1);
+ r2 = get_regname(dhp, FLG_P2_VAL(flags), f->f3.rs2);
+ r3 = get_regname(dhp, FLG_P3_VAL(flags), f->f3.rd);
+
+ p1 = (FLG_P1_VAL(flags) != REG_NONE);
+ p2 = (((flags & FLG_NOIMM) == 0) || (FLG_P2_VAL(flags) != REG_NONE));
+ p3 = (FLG_RD_VAL(flags) != REG_NONE);
+
+ if (r1 == NULL || r1[0] == '\0')
+ p1 = 0;
+
+ if (f->f3a.i == 0 && (r2 == NULL || r2[0] == '\0'))
+ p2 = 0;
+
+ if (r3 == NULL || r3[0] == '\0')
+ p3 = 0;
+
+ if (p1 != 0) {
+ (void) strlcat(dhp->dh_buf, r1, dhp->dh_buflen);
+ if (p2 != 0 || p3 != 0)
+ (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ }
+
+ if (p2 != 0) {
+ if (f->f3.i == 0 || ((flags & FLG_NOIMM) != 0))
+ (void) strlcat(dhp->dh_buf, r2, dhp->dh_buflen);
+ else
+ prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
+ IMM_SIGNED);
+
+ if (p3 != 0)
+ (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ }
+
+ if (p3 != 0)
+ (void) strlcat(dhp->dh_buf, r3, dhp->dh_buflen);
+}
+
+/*
+ * just a handy function that takes care of managing the buffer length
+ * w/ printf
+ */
+
+/*
+ * PRINTF LIKE 1
+ */
+static void
+bprintf(dis_handle_t *dhp, const char *fmt, ...)
+{
+ size_t curlen;
+ va_list ap;
+
+ curlen = strlen(dhp->dh_buf);
+
+ va_start(ap, fmt);
+ (void) vsnprintf(dhp->dh_buf + curlen, dhp->dh_buflen - curlen, fmt,
+ ap);
+ va_end(ap);
+}
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.h b/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.h
new file mode 100644
index 0000000000..4630c8114e
--- /dev/null
+++ b/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.h
@@ -0,0 +1,124 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2007 Jason King. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef _DIS_SPARC_FMT_H
+#define _DIS_SPARC_FMT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include "libdisasm.h"
+#include "dis_sparc.h"
+
+/* which set of registers are used with an instruction */
+#define REG_INT 0x00 /* regular integer registers */
+#define REG_FP 0x01 /* single-precision fp registers */
+#define REG_FPD 0x02 /* double-precision fp registers */
+#define REG_FPQ 0x03 /* quad-precision fp registers */
+#define REG_CP 0x04 /* coprocessor registers (v8) */
+#define REG_ICC 0x05 /* %icc / % xcc */
+#define REG_FCC 0x06 /* %fccn */
+#define REG_FSR 0x07 /* %fsr */
+#define REG_CSR 0x08 /* %csr */
+#define REG_CQ 0x09 /* %cq */
+#define REG_NONE 0x0a /* no registers */
+
+/* the size fo the displacement for branches */
+#define DISP22 0x00
+#define DISP19 0x01
+#define DISP16 0x02
+#define CONST22 0x03
+
+/* get/set the register set name for the rd field of an instruction */
+#define FLG_RD(x) (x)
+#define FLG_RD_VAL(x) (x & 0xfL)
+
+#define FLG_STORE (0x1L << 24) /* the instruction is not a load */
+#define FLG_ASI (0x2L << 24) /* the load/store includes an asi value */
+
+
+/* flags for ALU instructions */
+
+/* set/get register set name for 1st argument position */
+#define FLG_P1(x) (x << 8)
+#define FLG_P1_VAL(x) ((x >> 8) & 0xfL)
+
+/* get/set reg set for 2nd argument position */
+#define FLG_P2(x) (x << 4)
+#define FLG_P2_VAL(x) ((x >> 4) & 0xfL)
+
+/* get/set for 3rd argument position */
+#define FLG_P3(x) (x)
+#define FLG_P3_VAL(x) (x & 0xfL)
+
+/* set if the arguments do not contain immediate values */
+#define FLG_NOIMM (0x01L << 24)
+
+
+
+/* flags for branch instructions */
+
+/* has branch prediction */
+#define FLG_PRED (0x01L << 24)
+
+/* get/set condition code register set -- usually REG_NONE */
+#define FLG_RS1(x) (x)
+#define FLG_RS1_VAL(x) (x & 0xfL)
+
+/* get/set displacement size */
+#define FLG_DISP(x) (x << 4L)
+#define FLG_DISP_VAL(x) ((x >> 4L) & 0x0fL)
+
+
+int fmt_call(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_ls(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_alu(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_branch(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_sethi(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_fpop1(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_fpop2(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_vis(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_trap(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_regwin(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_trap_ret(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_movcc(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_movr(dis_handle_t *, uint32_t, const inst_t *, int);
+int fmt_fused(dis_handle_t *, uint32_t, const inst_t *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DIS_SPARC_FMT_H */
diff --git a/usr/src/lib/libdisasm/sparc/instr.c b/usr/src/lib/libdisasm/sparc/instr.c
new file mode 100644
index 0000000000..4be67e5949
--- /dev/null
+++ b/usr/src/lib/libdisasm/sparc/instr.c
@@ -0,0 +1,1625 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2007 Jason King. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libdisasm.h"
+#include "libdisasm_impl.h"
+#include "dis_sparc.h"
+#include "dis_sparc_fmt.h"
+
+#define INVALID \
+{ \
+ .in_type = INST_NONE, \
+ .in_arch = 0, \
+ .in_data = { \
+ .in_tbl = NULL \
+ } \
+}
+
+#define INVALIDA(_arch) \
+{ \
+ .in_type = INST_NONE, \
+ .in_arch = _arch, \
+ .in_data = { \
+ .in_tbl = NULL \
+ } \
+}
+
+#define INST(_name, _arch, _flags) \
+{ \
+ .in_type = INST_DEF, \
+ .in_arch = _arch, \
+ .in_data = { \
+ .in_def = { \
+ .in_name = _name, \
+ .in_flags = _flags \
+ } \
+ } \
+}
+
+#define TABLE(_name, _arch) \
+{ \
+ .in_type = INST_TBL, \
+ .in_arch = _arch, \
+ .in_data = { \
+ .in_tbl = &_name \
+ } \
+}
+
+#define OVERLAY(_idx, _inst) \
+{ \
+ .ov_idx = _idx, \
+ .ov_inst = _inst \
+}
+
+#define OVERLAY_END { .ov_idx = -1, .ov_inst = INVALID }
+
+#define V8 DIS_SPARC_V8
+#define V9 DIS_SPARC_V9
+#define V9S DIS_SPARC_V9_SGI
+#define V9O DIS_SPARC_V9_OPL
+#define VALL V8|V9|V9S|V9O
+
+/* branches */
+static const inst_t BPcc_table_def[16] = {
+ INST("bn", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("be", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("ble", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bl", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+
+ INST("bleu", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bcs", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bneg", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bvs", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+
+ INST("ba", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bne", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bg", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bge", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+
+ INST("bgu", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bcc", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bpos", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19)),
+ INST("bvc", V9|V9S, FLG_PRED|FLG_RS1(REG_ICC)|FLG_DISP(DISP19))
+};
+
+static const table_t BPcc_table = {
+ .tbl_field = 28,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_branch,
+ .tbl_inp = BPcc_table_def
+};
+
+static const inst_t Bicc_table_def[16] = {
+ INST("bn", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("be", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("ble", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("bl", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+
+ INST("bleu", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ /* docs say it's 'bcs' but disassembler calles it synonym 'blu' */
+ INST("blu", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("bneg", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("bvs", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+
+ INST("ba", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("bne", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("bg", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("bge", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+
+ INST("bgu", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ /*
+ * while the docs say it's officially 'bcc', existing disassembler
+ * uses the synonym bgeu
+ */
+ INST("bgeu", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("bpos", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("bvc", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE))
+};
+
+static const table_t Bicc_table = {
+ .tbl_field = 28,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_branch,
+ .tbl_inp = Bicc_table_def
+};
+
+static const inst_t BPr_table_def[16] = {
+ INVALID,
+ INST("brz", V9|V9S, FLG_PRED|FLG_DISP(DISP16)|FLG_RS1(REG_INT)),
+ INST("brlez", V9|V9S, FLG_PRED|FLG_DISP(DISP16)|FLG_RS1(REG_INT)),
+ INST("brlz", V9|V9S, FLG_PRED|FLG_DISP(DISP16)|FLG_RS1(REG_INT)),
+
+ INVALID,
+ INST("brnz", V9|V9S, FLG_PRED|FLG_DISP(DISP16)|FLG_RS1(REG_INT)),
+ INST("brgz", V9|V9S, FLG_PRED|FLG_DISP(DISP16)|FLG_RS1(REG_INT)),
+ INST("brgez", V9|V9S, FLG_PRED|FLG_DISP(DISP16)|FLG_RS1(REG_INT)),
+
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID
+};
+
+static const table_t BPr_table = {
+ .tbl_field = 28,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_branch,
+ .tbl_inp = BPr_table_def
+};
+
+static const inst_t FBPfcc_table_def[16] = {
+ INST("fbn", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbne", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fblg", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbul", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+
+ INST("fbl", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbug", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbg", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbu", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+
+ INST("fba", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbe", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbue", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbge", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+
+ INST("fbuge", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fble", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbule", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC)),
+ INST("fbo", V9|V9S, FLG_PRED|FLG_DISP(DISP19)|FLG_RS1(REG_FCC))
+};
+
+static const table_t FBPfcc_table = {
+ .tbl_field = 28,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_branch,
+ .tbl_inp = FBPfcc_table_def
+};
+
+static const inst_t FBfcc_table_def[16] = {
+ INST("fbn", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbne", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fblg", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbul", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+
+ INST("fbl", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbug", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbg", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbu", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+
+ INST("fba", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbe", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbue", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbge", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+
+ INST("fbuge", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fble", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbule", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("fbo", VALL, FLG_DISP(DISP22)|FLG_RS1(REG_NONE))
+};
+
+static const table_t FBfcc_table = {
+ .tbl_field = 28,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_branch,
+ .tbl_inp = FBfcc_table_def
+};
+
+static const inst_t CBccc_table_def[16] = {
+ INST("cbn", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb123", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb12", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb13", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb1", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb23", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb2", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb3", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cba", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb0", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb03", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb02", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb023", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb01", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb013", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE)),
+ INST("cb012", V8, FLG_DISP(DISP22)|FLG_RS1(REG_NONE))
+};
+
+static const table_t CBccc_table = {
+ .tbl_field = 28,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_branch,
+ .tbl_inp = CBccc_table_def
+};
+
+static const inst_t branch_table_def[8] = {
+ INST("unimp", VALL, 0),
+ TABLE(BPcc_table, V9|V9S),
+ TABLE(Bicc_table, VALL),
+ TABLE(BPr_table, V9|V9S),
+
+ INST("sethi", VALL, 0),
+ TABLE(FBPfcc_table, V9|V9S),
+ TABLE(FBfcc_table, VALL),
+ TABLE(CBccc_table, V8)
+};
+
+static const overlay_t branch_ov_table[] = {
+ OVERLAY(0x00, INST("illtrap", V9|V9S, 0)),
+ OVERLAY_END
+};
+
+static const table_t branch_table = {
+ .tbl_field = 24,
+ .tbl_len = 3,
+ .tbl_ovp = branch_ov_table,
+ .tbl_fmt = fmt_sethi,
+ .tbl_inp = branch_table_def
+};
+
+/* load/stores */
+static const inst_t ls_table_def[64] = {
+ /* 0x00 */
+ INST("ld", VALL, 0),
+ INST("ldub", VALL, 0),
+ INST("lduh", VALL, 0),
+ INST("ldd", VALL, 0),
+
+ INST("st", VALL, FLG_STORE),
+ INST("stb", VALL, FLG_STORE),
+ INST("sth", VALL, FLG_STORE),
+ INST("std", VALL, FLG_STORE),
+
+ /* 0x08 */
+ INST("ldsw", V9|V9S, 0),
+ INST("ldsb", VALL, 0),
+ INST("ldsh", VALL, 0),
+ INST("ldx", V9|V9S, 0),
+
+ INVALID,
+ INST("ldstub", VALL, 0),
+ INST("stx", V9|V9S, FLG_STORE),
+ INST("swap", VALL, 0),
+
+ /* 0x10 */
+ INST("lda", VALL, FLG_ASI),
+ INST("lduba", VALL, FLG_ASI),
+ INST("lduha", VALL, FLG_ASI),
+ INST("ldda", VALL, FLG_ASI),
+
+ INST("sta", VALL, FLG_STORE|FLG_ASI),
+ INST("stba", VALL, FLG_STORE|FLG_ASI),
+ INST("stha", VALL, FLG_STORE|FLG_ASI),
+ INST("stda", VALL, FLG_STORE|FLG_ASI),
+
+ /* 0x18 */
+ INST("ldswa", V9|V9S, FLG_ASI),
+ INST("ldsba", VALL, FLG_ASI),
+ INST("ldsha", VALL, FLG_ASI),
+ INST("ldxa", V9|V9S, FLG_ASI),
+
+ INVALID,
+ INST("ldstuba", VALL, FLG_ASI),
+ INST("stxa", V9|V9S, FLG_STORE|FLG_ASI),
+ INST("swapa", VALL, FLG_ASI),
+
+ /* 0x20 */
+ INST("ld", VALL, FLG_RD(REG_FP)),
+ /* ldx on v9 */
+ INST("ld", VALL, FLG_RD(REG_FSR)),
+ INST("ldq", V9|V9S, FLG_RD(REG_FPQ)),
+ INST("ldd", VALL, FLG_RD(REG_FPD)),
+
+ INST("st", VALL, FLG_STORE|FLG_RD(REG_FP)),
+ /* stx on v9 */
+ INST("st", VALL, FLG_STORE|FLG_RD(REG_FSR)),
+ INST("stq", VALL, FLG_STORE|FLG_RD(REG_FPQ)),
+ INST("std", VALL, FLG_STORE|FLG_RD(REG_FPD)),
+
+ /* 0x28 */
+ INVALID,
+ INVALID,
+ INVALID,
+ INVALID,
+
+ INVALID,
+ INST("prefetch", V9|V9S, 0),
+ INVALID,
+ INVALID,
+
+ /* 0x30 */
+ INST("ld", V8, FLG_RD(REG_CP)),
+ INST("ld", V8, FLG_RD(REG_CSR)),
+ INST("ldqa", V9|V9S, FLG_ASI|FLG_RD(REG_FPQ)),
+ INST("ldd", V8, FLG_RD(REG_CP)),
+
+ INST("st", V8, FLG_STORE|FLG_RD(REG_CP)),
+ INST("st", V8, FLG_STORE|FLG_RD(REG_CSR)),
+ INST("std", V8, FLG_STORE|FLG_RD(REG_CQ)),
+ INST("std", V8, FLG_STORE|FLG_RD(REG_CP)),
+
+ /* 0x38 */
+ INVALID,
+ INVALID,
+ INVALID,
+ INVALID,
+
+ INST("casa", V9|V9S, 0),
+ INST("prefetcha", V9|V9S, FLG_STORE|FLG_ASI),
+ INST("casxa", V9|V9S, 0),
+ INVALID
+};
+
+static const overlay_t ld_ov_table[] = {
+ OVERLAY(0x10, INST("lduwa", V9|V9S, FLG_ASI|FLG_RD(REG_INT))),
+ OVERLAY(0x14, INST("stwa", V9|V9S,
+ FLG_STORE|FLG_ASI|FLG_RD(REG_INT))),
+ OVERLAY(0x30, INST("lda", V9|V9S, FLG_ASI|FLG_RD(REG_FP))),
+ OVERLAY(0x33, INST("ldda", V9|V9S, FLG_ASI|FLG_RD(REG_FPD))),
+
+ OVERLAY(0x34, INST("sta", V9|V9S, FLG_STORE|FLG_ASI|FLG_RD(REG_FP))),
+ OVERLAY(0x36, INST("stqa", V9|V9S,
+ FLG_STORE|FLG_ASI|FLG_RD(REG_FPQ))),
+ OVERLAY(0x37, INST("stda", V9|V9S,
+ FLG_STORE|FLG_ASI|FLG_RD(REG_FPD))),
+
+ OVERLAY_END
+};
+
+static const table_t ls_table = {
+ .tbl_field = 24,
+ .tbl_len = 6,
+ .tbl_ovp = ld_ov_table,
+ .tbl_fmt = fmt_ls,
+ .tbl_inp = ls_table_def
+};
+
+/* ALU operations */
+static const inst_t Tcc_table_def[16] = {
+ INST("tn", VALL, 0),
+ INST("te", VALL, 0),
+ INST("tle", VALL, 0),
+ INST("tl", VALL, 0),
+
+ INST("tleu", VALL, 0),
+ INST("tcs", VALL, 0),
+ INST("tneg", VALL, 0),
+ INST("tvs", VALL, 0),
+
+ INST("ta", VALL, 0),
+ INST("tne", VALL, 0),
+ INST("tg", VALL, 0),
+ INST("tge", VALL, 0),
+
+ INST("tgu", VALL, 0),
+ INST("tcc", VALL, 0),
+ INST("tpos", VALL, 0),
+ INST("tvc", VALL, 0)
+};
+
+static const table_t Tcc_table = {
+ .tbl_field = 28,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_trap,
+ .tbl_inp = Tcc_table_def
+};
+
+static const inst_t rwin_table_def[32] = {
+ /* 0x00 */
+ INST("saved", V9|V9S, 0),
+ INST("restored", V9|V9S, 0),
+ INST("allclean", V9|V9S, 0),
+ INST("otherw", V9|V9S, 0),
+
+ INST("normalw", V9|V9S, 0),
+ INST("invalw", V9|V9S, 0),
+ INVALID,
+ INVALID,
+
+ /* 0x08 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x10 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID
+};
+
+static const table_t rwin_table = {
+ .tbl_field = 29,
+ .tbl_len = 5,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_regwin,
+ .tbl_inp = rwin_table_def
+};
+
+static const inst_t tr_table_def[32] = {
+ /* 0x00 */
+ INST("done", V9|V9S, 0),
+ INST("retry", V9|V9S, 0),
+ INVALID,
+ INVALID,
+
+ INVALID,
+ INVALID,
+ INVALID,
+ INVALID,
+
+ /* 0x08 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x10 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID
+};
+
+static const table_t tr_table = {
+ .tbl_field = 29,
+ .tbl_len = 5,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_trap_ret,
+ .tbl_inp = tr_table_def
+};
+
+static const inst_t movicc_table_def[16] = {
+ INST("movn", V9|V9S, 0),
+ INST("move", V9|V9S, 0),
+ INST("movle", V9|V9S, 0),
+ INST("movl", V9|V9S, 0),
+
+ INST("movleu", V9|V9S, 0),
+ INST("movcs", V9|V9S, 0),
+ INST("movneg", V9|V9S, 0),
+ INST("movvs", V9|V9S, 0),
+
+ INST("mova", V9|V9S, 0),
+ INST("movne", V9|V9S, 0),
+ INST("movg", V9|V9S, 0),
+ INST("movge", V9|V9S, 0),
+
+ INST("movgu", V9|V9S, 0),
+ INST("movcc", V9|V9S, 0),
+ INST("movpos", V9|V9S, 0),
+ INST("movvc", V9|V9S, 0)
+};
+
+static const inst_t movfcc_table_def[16] = {
+ INST("movn", V9|V9S, 0),
+ INST("movne", V9|V9S, 0),
+ INST("movlg", V9|V9S, 0),
+ INST("movul", V9|V9S, 0),
+
+ INST("movl", V9|V9S, 0),
+ INST("movug", V9|V9S, 0),
+ INST("movg", V9|V9S, 0),
+ INST("movu", V9|V9S, 0),
+
+ INST("mova", V9|V9S, 0),
+ INST("move", V9|V9S, 0),
+ INST("movue", V9|V9S, 0),
+ INST("movge", V9|V9S, 0),
+
+ INST("movuge", V9|V9S, 0),
+ INST("movle", V9|V9S, 0),
+ INST("movule", V9|V9S, 0),
+ INST("movo", V9|V9S, 0)
+};
+
+static const table_t movfcc_table = {
+ .tbl_field = 17,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_movcc,
+ .tbl_inp = movfcc_table_def
+};
+
+static const table_t movicc_table = {
+ .tbl_field = 17,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_movcc,
+ .tbl_inp = movicc_table_def
+};
+
+static const inst_t movcc_table_def[2] = {
+ TABLE(movfcc_table, V9|V9S),
+ TABLE(movicc_table, V9|V9S)
+};
+
+static const table_t movcc_table = {
+ .tbl_field = 18,
+ .tbl_len = 1,
+ .tbl_ovp = NULL,
+ .tbl_fmt = NULL,
+ .tbl_inp = movcc_table_def
+};
+
+static const inst_t movr_table_def[8] = {
+ INVALID,
+ /* aka movrz */
+ INST("movre", V9|V9S, 0),
+ INST("movrlez", V9|V9S, 0),
+ INST("movrlz", V9|V9S, 0),
+
+ INVALID,
+ /* aka movrnz */
+ INST("movrne", V9|V9S, 0),
+ INST("movrgz", V9|V9S, 0),
+ INST("movrgez", V9|V9S, 0)
+};
+
+static const table_t movr_table = {
+ .tbl_field = 12,
+ .tbl_len = 3,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_movr,
+ .tbl_inp = movr_table_def
+};
+
+static const inst_t FPop1_table_def[512] = {
+ /* 0x000 */
+ INVALID,
+ INST("fmovs", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fmovd", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fmovq", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID,
+ INST("fnegs", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fnegd", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fnegq", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ /* 0x008 */
+ INVALID,
+ INST("fabss", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fabsd", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fabsq", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x010 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x020 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x028 */
+ INVALID,
+ INST("fsqrts", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fsqrtd", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fsqrtq", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x30 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x40 */
+ INVALID,
+ INST("fadds", VALL,
+ FLG_P1(REG_FP)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("faddd", VALL,
+ FLG_P1(REG_FPD)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("faddq", VALL,
+ FLG_P1(REG_FPQ)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID,
+ INST("fsubs", VALL,
+ FLG_P1(REG_FP)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fsubd", VALL,
+ FLG_P1(REG_FPD)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fsubq", VALL,
+ FLG_P1(REG_FPQ)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ /* 0x048 */
+ INVALID,
+ INST("fmuls", VALL,
+ FLG_P1(REG_FP)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fmuld", VALL,
+ FLG_P1(REG_FPD)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fmulq", VALL,
+ FLG_P1(REG_FPQ)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID,
+ INST("fdivs", VALL,
+ FLG_P1(REG_FP)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fdivd", VALL,
+ FLG_P1(REG_FPD)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fdivq", VALL,
+ FLG_P1(REG_FPQ)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ /* 0x050 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x060 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x068 */
+ INVALID,
+ INST("fsmuld", VALL,
+ FLG_P1(REG_FP)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INVALID,
+ INVALID,
+
+ INVALID,
+ INVALID,
+ INST("fdmulq", VALL,
+ FLG_P1(REG_FPD)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+ INVALID,
+
+ /* 0x070 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x080 */
+ INVALID,
+ INST("fstox", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fdtox", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fqtox", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPD)),
+
+ INST("fxtos", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|
+ FLG_P3(REG_FP)),
+ INVALID,
+ INVALID,
+ INVALID,
+
+ /* 0x088 */
+ INST("fxtod", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INVALID,
+ INVALID,
+ INVALID,
+
+ INST("fxtoq", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+ INVALID,
+ INVALID,
+ INVALID,
+
+ /* 0x090 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0a0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0b0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0c0 */
+ INVALID, INVALID, INVALID, INVALID,
+
+ INST("fitos", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INVALID,
+ INST("fdtos", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fqtos", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FP)),
+
+ /* 0x0c8 */
+ INST("fitod", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fstod", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INVALID,
+ INST("fqtod", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPD)),
+
+ INST("fitoq", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+ INST("fstoq", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+ INST("fdtoq", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+ INVALID,
+
+ /* 0x0d0 */
+ INVALID,
+ INST("fstoi", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fdtoi", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fqtoi", VALL,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0d8 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0e0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0f0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x100 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x110 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x120 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x130 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x140 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x150 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x160 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x170 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x180 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x190 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1a0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1b0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1c0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1d0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1e0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1f0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID
+};
+
+static const table_t FPop1_table = {
+ .tbl_field = 13,
+ .tbl_len = 9,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_fpop1,
+ .tbl_inp = FPop1_table_def
+};
+
+static const inst_t FPop2_table_def[512] = {
+ /* 0x000 */
+ INVALID,
+ INST("fmovs", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fmovd", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fmovq", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x008 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x010 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x020 */
+ INVALID, INVALID, INVALID, INVALID,
+
+ INST("fmovrsz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fmovrdz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fmovrqz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FPQ)|FLG_P3(REG_FPQ)),
+ INVALID,
+
+ /* 0x028 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x030 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x040 */
+ INVALID,
+ INST("fmovs", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fmovd", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fmovq", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INST("fmovrslez", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fmovrdlez", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fmovrqlez", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FPQ)|FLG_P3(REG_FPQ)),
+ INVALID,
+
+ /* 0x048 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x050 */
+ INVALID,
+ INST("fcmps", VALL, FLG_P1(REG_FP)|FLG_P2(REG_FP)|FLG_P3(REG_NONE)
+ |FLG_NOIMM),
+ INST("fcmpd", VALL, FLG_P1(REG_FPD)|FLG_P2(REG_FPD)|FLG_P3(REG_NONE)
+ |FLG_NOIMM),
+ INST("fcmpq", VALL, FLG_P1(REG_FPQ)|FLG_P2(REG_FPQ)|FLG_P3(REG_NONE)
+ |FLG_NOIMM),
+
+ INVALID,
+ INST("fcmpes", VALL, FLG_P1(REG_FP)|FLG_P2(REG_FP)|FLG_P3(REG_NONE)
+ |FLG_NOIMM),
+ INST("fcmped", VALL, FLG_P1(REG_FPD)|FLG_P2(REG_FPD)|FLG_P3(REG_NONE)
+ |FLG_NOIMM),
+ INST("fcmpeq", VALL, FLG_P1(REG_FPQ)|FLG_P2(REG_FPQ)|FLG_P3(REG_NONE)
+ |FLG_NOIMM),
+
+ /* 0x058 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x060 */
+ INVALID, INVALID, INVALID, INVALID,
+
+ INVALID,
+ INST("fmovrslz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fmovrdlz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fmovrqlz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FPQ)|FLG_P3(REG_FPQ)),
+
+ /* 0x068 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x070 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x080 */
+ INVALID,
+ INST("fmovs", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FP)|FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fmovd", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fmovq", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x088 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x090 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0a0 */
+ INVALID, INVALID, INVALID, INVALID,
+
+ INVALID,
+ INST("fmovrsnz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fmovrdnz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fmovrqnz", V9|V9S,
+ FLG_P1(REG_INT)|FLG_NOIMM|FLG_P2(REG_FPQ)|FLG_P3(REG_FPQ)),
+
+ /* 0x0a8 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0b0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0c0 */
+ INVALID,
+ INST("fmovs", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FP)|
+ FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fmovd", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|
+ FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fmovq", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|
+ FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID,
+ INST("fmovrsgz", V9|V9S, FLG_P1(REG_INT)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fmovrdgz", V9|V9S, FLG_P1(REG_INT)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fmovrqgz", V9|V9S, FLG_P1(REG_INT)|FLG_NOIMM|
+ FLG_P2(REG_FPQ)|FLG_P3(REG_FPQ)),
+
+ /* 0x0c8 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0d0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0e0 */
+ INVALID, INVALID, INVALID, INVALID,
+
+ INVALID,
+ INST("fmovrsgez", V9|V9S, FLG_P1(REG_INT)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fmovrdgez", V9|V9S, FLG_P1(REG_INT)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fmovrqgez", V9|V9S, FLG_P1(REG_INT)|FLG_NOIMM|
+ FLG_P2(REG_FPQ)|FLG_P3(REG_FPQ)),
+
+ /* 0x0e8 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0f0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x100 */
+ INVALID,
+ INST("fmovs", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FP)|
+ FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fmovd", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|
+ FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fmovq", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|
+ FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x108 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x110 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x120 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x130 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x140 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x150 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x160 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x170 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x180 */
+ INVALID,
+ INST("fmovs", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FP)|
+ FLG_NOIMM|FLG_P3(REG_FP)),
+ INST("fmovd", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|
+ FLG_NOIMM|FLG_P3(REG_FPD)),
+ INST("fmovq", V9|V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPQ)|
+ FLG_NOIMM|FLG_P3(REG_FPQ)),
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x188 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x190 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1a0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1b0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1c0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1d0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1e0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1f0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID
+};
+
+static const table_t FPop2_table = {
+ .tbl_field = 13,
+ .tbl_len = 9,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_fpop2,
+ .tbl_inp = FPop2_table_def
+};
+
+static const inst_t vis_table_def[512] = {
+ /* 0x000 */
+ INST("edge8cc", V9S, FLG_NOIMM),
+ INST("edge8n", V9S, FLG_NOIMM),
+ INST("edge8lcc", V9S, FLG_NOIMM),
+ INST("edge8ln", V9S, FLG_NOIMM),
+
+ INST("edge16cc", V9S, FLG_NOIMM),
+ INST("edge16n", V9S, FLG_NOIMM),
+ INST("edge16lcc", V9S, FLG_NOIMM),
+ INST("edge16ln", V9S, FLG_NOIMM),
+
+ /* 0x008 */
+ INST("edge32cc", V9S, FLG_NOIMM),
+ INST("edge32n", V9S, FLG_NOIMM),
+ INST("edge32lcc", V9S, FLG_NOIMM),
+ INST("edge32ln", V9S, FLG_NOIMM),
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x010 */
+ INST("array8", V9S, FLG_NOIMM),
+ INVALID,
+ INST("array16", V9S, FLG_NOIMM),
+ INVALID,
+
+ INST("array32", V9S, FLG_NOIMM),
+ INVALID,
+ INVALID,
+ INVALID,
+
+ /* 0x018 */
+ INST("alignaddr", V9S, FLG_NOIMM),
+ INST("bmask", V9S, FLG_NOIMM),
+ INST("alignaddrl", V9S, FLG_NOIMM),
+ INVALID,
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x020 */
+ INST("fcmple16", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_INT)),
+ INVALID,
+ INST("fcmpne16", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_INT)),
+ INVALID,
+
+ INST("fcmple32", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_INT)),
+ INVALID,
+ INST("fcmpne32", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_INT)),
+ INVALID,
+
+ /* 0x028 */
+ INST("fcmpgt16", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_INT)),
+ INVALID,
+ INST("fcmpeq16", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_INT)),
+ INVALID,
+
+ INST("fcmpgt32", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_INT)),
+ INVALID,
+ INST("fcmpeq32", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_INT)),
+ INVALID,
+
+ /* 0x030 */
+ INVALID,
+ INST("fmul8x16", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INVALID,
+ INST("fmul8x16au", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FPD)),
+
+ INVALID,
+ INST("fmul8x16al", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FPD)),
+ INST("fmul8sux16", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fmul8ulx16", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+
+ /* 0x038 */
+ INST("fmuld8sux16", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FPD)),
+ INST("fmuld8ulx16", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FPD)),
+ INST("fpack32", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fpack16", V9S, FLG_P1(REG_NONE)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FP)),
+
+ INVALID,
+ INST("fpackfix", V9S, FLG_P1(REG_NONE)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FP)),
+ INST("pdist", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INVALID,
+
+ /* 0x040 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x048 */
+ INST("faligndata", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INVALID,
+ INVALID,
+ INST("fpmerge", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FPD)),
+
+ INST("bshuffle", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fexpand", V9S, FLG_P1(REG_NONE)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FPD)),
+ INVALID,
+ INVALID,
+
+ /* 0x050 */
+ INST("fpadd16", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fpadd16s", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fpadd32", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fpadd32s", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+
+ INST("fpsub16", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fpsub16s", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fpsub32", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fpsub32s", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+
+ /* 0x058 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x060 */
+ INST("fzero", V9S, FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|
+ FLG_P3(REG_FPD)),
+ INST("fzeros", V9S, FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|
+ FLG_P3(REG_FP)),
+ INST("fnor", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fnors", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+
+ INST("fandnot2", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fandnot2s", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fnot2", V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|
+ FLG_P3(REG_FPD)),
+ INST("fnot2s", V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FP)|
+ FLG_P3(REG_FP)),
+
+ /* 0x068 */
+ INST("fandnot1", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fandnot1s", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fnot1", V9S, FLG_P1(REG_FPD)|FLG_P2(REG_NONE)|
+ FLG_P3(REG_FPD)),
+ INST("fnot1s", V9S, FLG_P1(REG_FP)|FLG_P2(REG_NONE)|
+ FLG_P3(REG_FP)),
+
+ INST("fxor", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fxors", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fnand", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fnands", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+
+ /* 0x070 */
+ INST("fand", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fands", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fxnor", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fxnors", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+
+ INST("fsrc1", V9S, FLG_P1(REG_FPD)|FLG_P2(REG_NONE)|
+ FLG_P3(REG_FPD)),
+ INST("fsrc1s", V9S, FLG_P1(REG_FP)|FLG_P2(REG_NONE)|
+ FLG_P3(REG_FP)),
+ INST("fornot2", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fornot2s", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+
+ /* 0x078 */
+ INST("fsrc2", V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FPD)|
+ FLG_P3(REG_FPD)),
+ INST("fsrc2s", V9S, FLG_P1(REG_NONE)|FLG_P2(REG_FP)|
+ FLG_P3(REG_FP)),
+ INST("fornot1", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fornot1s", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+
+ INST("for", V9S, FLG_P1(REG_FPD)|FLG_NOIMM|
+ FLG_P2(REG_FPD)|FLG_P3(REG_FPD)),
+ INST("fors", V9S, FLG_P1(REG_FP)|FLG_NOIMM|
+ FLG_P2(REG_FP)|FLG_P3(REG_FP)),
+ INST("fone", V9S, FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|
+ FLG_P3(REG_FPD)),
+ INST("fones", V9S, FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|
+ FLG_P3(REG_FP)),
+
+ /* 0x080 */
+ INST("shutdown", V9S, 0),
+ INST("siam", V9S, 0),
+ INVALID,
+ INVALID,
+
+ INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x088 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x090 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0a0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0b0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0c0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0d0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0e0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x0f0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x100 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x110 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x120 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x130 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x140 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x150 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x160 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x170 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x180 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x190 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1a0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1b0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1c0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1d0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1e0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+
+ /* 0x1f0 */
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID
+};
+
+static const table_t vis_table = {
+ .tbl_field = 13,
+ .tbl_len = 9,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_vis,
+ .tbl_inp = vis_table_def
+};
+
+static const inst_t fused_table_def[16] = {
+ /* 0x0 */
+ INVALID,
+ INST("fmadds", V9O, FLG_P1(REG_FP)),
+ INST("fmaddd", V9O, FLG_P1(REG_FPD)),
+ INVALID,
+
+ /* 0x4 */
+ INVALID,
+ INST("fmsubs", V9O, FLG_P1(REG_FP)),
+ INST("fmsubd", V9O, FLG_P1(REG_FPD)),
+ INVALID,
+
+ /* 0x8 */
+ INVALID,
+ INST("fnmsubs", V9O, FLG_P1(REG_FP)),
+ INST("fnmsubd", V9O, FLG_P1(REG_FPD)),
+ INVALID,
+
+ /* 0xc */
+ INVALID,
+ INST("fnmadds", V9O, FLG_P1(REG_FP)),
+ INST("fnmaddd", V9O, FLG_P1(REG_FPD)),
+ INVALID
+};
+
+static const table_t fused_table = {
+ .tbl_field = 5,
+ .tbl_len = 4,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_fused,
+ .tbl_inp = fused_table_def
+};
+
+static const inst_t alu_table_def[64] = {
+ /* 0x00 */
+ INST("add", VALL, 0),
+ INST("and", VALL, 0),
+ INST("or", VALL, 0),
+ INST("xor", VALL, 0),
+
+ INST("sub", VALL, 0),
+ INST("andn", VALL, 0),
+ INST("orn", VALL, 0),
+ INST("xnor", VALL, 0),
+
+ /* 0x08 */
+ INST("addx", VALL, 0),
+ INST("mulx", V9|V9S, 0),
+ INST("umul", VALL, 0),
+ INST("smul", VALL, 0),
+
+ INST("subx", VALL, 0),
+ INST("udivx", V9|V9S, 0),
+ INST("udiv", VALL, 0),
+ INST("sdiv", VALL, 0),
+
+ /* 0x10 */
+ INST("addcc", VALL, 0),
+ INST("andcc", VALL, 0),
+ INST("orcc", VALL, 0),
+ INST("xorcc", VALL, 0),
+
+ INST("subcc", VALL, 0),
+ INST("andncc", VALL, 0),
+ INST("orncc", VALL, 0),
+ INST("xnorcc", VALL, 0),
+
+ /* 0x18 */
+ INST("addxcc", VALL, 0),
+ INVALID,
+ INST("umulcc", VALL, 0),
+ INST("smulcc", VALL, 0),
+
+ INST("subxcc", VALL, 0),
+ INVALID,
+ INST("udivcc", VALL, 0),
+ INST("sdivcc", VALL, 0),
+
+ /* 0x20 */
+ INST("taddcc", VALL, 0),
+ INST("tsubcc", VALL, 0),
+ INST("taddcctv", VALL, 0),
+ INST("tsubcctv", VALL, 0),
+
+ INST("mulscc", VALL, 0),
+ INST("sll", VALL, 0),
+ INST("srl", VALL, 0),
+ INST("sra", VALL, 0),
+
+ /* 0x28 */
+ INST("rd", VALL, 0),
+ INST("rd", V8, 0),
+ INST("rd", V8, 0),
+ INST("rd", V8, 0),
+
+ TABLE(movcc_table, V9|V9S),
+ INST("sdivx", V9|V9S, 0),
+ INST("popc", V9|V9S,
+ FLG_P1(REG_NONE)|FLG_P2(REG_INT)|FLG_P3(REG_INT)),
+ TABLE(movr_table, V9|V9S),
+
+ /* 0x30 */
+ INST("wr", VALL, 0),
+ INST("wr", V8, 0),
+ INST("wr", V8, 0),
+ INST("wr", V8, 0),
+
+ TABLE(FPop1_table, VALL),
+ TABLE(FPop2_table, VALL),
+ INST("cpop1", V8, 0),
+ INST("cpop2", V8, 0), /* impdep2 */
+
+ /* 0x38 */
+ INST("jmpl", VALL, 0),
+ INST("rett", VALL, 0),
+ TABLE(Tcc_table, VALL),
+ INST("flush", VALL, 0),
+
+ INST("save", VALL, 0),
+ INST("restore", VALL, 0),
+ TABLE(tr_table, V9|V9S),
+ INVALID
+};
+
+static const overlay_t alu_ov_table[] = {
+ OVERLAY(0x08, INST("addc", V9|V9S, 0)),
+ OVERLAY(0x0c, INST("subc", V9|V9S, 0)),
+ OVERLAY(0x18, INST("addccc", V9|V9S, 0)),
+ OVERLAY(0x1c, INST("subccc", V9|V9S, 0)),
+
+ OVERLAY(0x29, INVALIDA(V9|V9S)),
+ OVERLAY(0x2a, INST("rdpr", V9|V9S, 0)),
+ OVERLAY(0x2b, INST("flushw", V9|V9S, 0)),
+ OVERLAY(0x31, TABLE(rwin_table, V9|V9S)),
+
+ OVERLAY(0x32, INST("wrpr", V9|V9S, 0)),
+ OVERLAY(0x33, INVALIDA(V9|V9S)),
+ OVERLAY(0x36, TABLE(vis_table, V9S)),
+ OVERLAY(0x37, TABLE(fused_table, V9O)),
+ OVERLAY(0x39, INST("return", VALL, 0)),
+
+ OVERLAY_END
+};
+
+static const table_t alu_table = {
+ .tbl_field = 24,
+ .tbl_len = 6,
+ .tbl_ovp = alu_ov_table,
+ .tbl_fmt = fmt_alu,
+ .tbl_inp = alu_table_def
+};
+
+static const inst_t initial_table_def[4] = {
+ TABLE(branch_table, VALL),
+ INST("call", VALL, 0),
+ TABLE(alu_table, VALL),
+ TABLE(ls_table, VALL)
+};
+
+/* NOTE: this must not be made static */
+const table_t initial_table = {
+ .tbl_field = 31,
+ .tbl_len = 2,
+ .tbl_ovp = NULL,
+ .tbl_fmt = fmt_call,
+ .tbl_inp = initial_table_def
+};
diff --git a/usr/src/lib/libdisasm/sparcv9/Makefile b/usr/src/lib/libdisasm/sparcv9/Makefile
new file mode 100644
index 0000000000..fcf90265a1
--- /dev/null
+++ b/usr/src/lib/libdisasm/sparcv9/Makefile
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+ISASRCDIR=../$(MACH)/
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+TYPES=library standalone
+
+INSTALL_DEPS_library = $(ROOTLINKS64) $(ROOTLINT64) $(ROOTLIBS64)
+INSTALL_DEPS_standalone = $(ROOTLIBS64)
+
+include ../Makefile.targ
+
+C99MODE = $(C99_ENABLE)
diff --git a/usr/src/pkgdefs/etc/exception_list_sparc b/usr/src/pkgdefs/etc/exception_list_sparc
index 321746afcb..1c16bebe31 100644
--- a/usr/src/pkgdefs/etc/exception_list_sparc
+++ b/usr/src/pkgdefs/etc/exception_list_sparc
@@ -866,6 +866,7 @@ usr/include/sys/scsi/adapters/mpapi_scsi_vhci.h sparc
# This library is installed in the proto area by the build of libdisasm, and is
# only used when building the KMDB disasm module.
#
+usr/lib/libstanddisasm.so sparc
usr/lib/sparcv9/libstanddisasm.so sparc
#
# TSol: tsol doesn't ship lint source, and tsnet isn't for customers at all.
diff --git a/usr/src/tools/scripts/mkclosed.sh b/usr/src/tools/scripts/mkclosed.sh
index 55f1f82e4f..3f1c1c410f 100644
--- a/usr/src/tools/scripts/mkclosed.sh
+++ b/usr/src/tools/scripts/mkclosed.sh
@@ -67,21 +67,8 @@ mkdir -p $closedroot || exit 1
# rather than a tar pipeline to make it easier to detect errors.
#
# We need /lib/libc_i18n.a & /lib/{sparcv9,amd64}/libc_i18n.a
-# libdisasm is open on x86, but closed on sparc - how confusing...
#
-(
- echo lib/libc_i18n.a
- [ -n "$plat64" ] && echo lib/$plat64/libc_i18n.a
- if [ "$isa" = "sparc" ]; then
- echo usr/lib/libdisasm.so.1
- echo usr/lib/libdisasm.so
- echo usr/lib/$plat64/libdisasm.so.1
- echo usr/lib/$plat64/libdisasm.so
- echo usr/lib/$plat64/libstanddisasm.so
- echo usr/lib/$plat64/llib-ldisasm.ln
- echo usr/lib/llib-ldisasm
- echo usr/lib/mdb/disasm
- echo usr/lib/llib-ldisasm.ln
- fi
-) | cpio -dpu $closedroot
+mkdir -p $closedroot/lib/$plat64
+cp lib/libc_i18n.a $closedroot/lib
+cp lib/$plat64/libc_i18n.a $closedroot/lib/$plat64