[kdb] [hch at infradead.org: Re: [PATCH, RFC] merge i386 and x86_64 kdb arch code]

Christoph Hellwig hch at infradead.org
Thu Dec 25 03:04:49 CST 2008


Should have sent this to the list of course.  Sorry..

----- Forwarded message from Christoph Hellwig <hch at infradead.org> -----

Date: Tue, 23 Dec 2008 03:36:03 -0500
From: Christoph Hellwig <hch at infradead.org>
Subject: Re: [kdb] [PATCH, RFC] merge i386 and x86_64 kdb arch code
To: jidong xiao <jidong.xiao at gmail.com>

On Tue, Dec 23, 2008 at 12:40:37PM +0800, jidong xiao wrote:
> Did you miss something? It seems you are going to delete
> kdbasupport_32.c and kdbasupport_64.c rather than merge them.

Oops, looks like I forgot to quilt add kdbasupport.c.  Here is the full
patch:

Index: xfs-dev/arch/x86/kdb/Makefile
===================================================================
--- xfs-dev.orig/arch/x86/kdb/Makefile	2008-12-23 09:30:36.614197354 +0100
+++ xfs-dev/arch/x86/kdb/Makefile	2008-12-23 09:31:08.700197187 +0100
@@ -1,5 +1,29 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
+#
+
+obj-$(CONFIG_KDB)	+= kdba_bp.o kdbasupport.o x86-dis.o kdba_bt.o \
+			   kdba_io.o kdba_id.o kdba_support.o
+
+ifneq (,$(findstring -fno-optimize-sibling-calls,$(KBUILD_CFLAGS)))
+  CFLAGS_kdba_bt.o += -DNO_SIBLINGS
+endif
+
+REGPARM := $(subst -mregparm=,,$(filter -mregparm=%,$(KBUILD_CFLAGS)))
+ifeq (,$(REGPARM))
 ifeq ($(CONFIG_X86_32),y)
-include ${srctree}/arch/x86/kdb/Makefile_32
+  REGPARM := 3
 else
-include ${srctree}/arch/x86/kdb/Makefile_64
+  REGPARM := 6
+endif
 endif
+
+CFLAGS_kdba_bt.o += -DREGPARM=$(REGPARM) -DCCVERSION="$(CCVERSION)"
+
+override CFLAGS := $(CFLAGS:%-pg=% )
+
+CFLAGS_kdba_io.o += -I $(TOPDIR)/arch/$(SRCARCH)/kdb
Index: xfs-dev/arch/x86/kdb/kdba_bp.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ xfs-dev/arch/x86/kdb/kdba_bp.c	2008-12-23 09:31:08.706197742 +0100
@@ -0,0 +1,914 @@
+/*
+ * Kernel Debugger Architecture Dependent Breakpoint Handling
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+
+static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write",
+			"I/O", "Data Access"};
+
+/*
+ * Table describing processor architecture hardware
+ * breakpoint registers for every CPU.
+ */
+
+static kdbhard_bp_t kdb_hardbreaks[NR_CPUS][KDB_MAXHARDBPT];
+
+/*
+ * kdba_db_trap
+ *
+ * 	Perform breakpoint processing upon entry to the
+ *	processor debugger fault.   Determine and print
+ *	the active breakpoint.
+ *
+ * Parameters:
+ *	regs	Exception frame containing machine register state
+ *	error	Error number passed to kdb.
+ * Outputs:
+ *	None.
+ * Returns:
+ *	KDB_DB_BPT	Standard instruction or data breakpoint encountered
+ *	KDB_DB_SS	Single Step fault ('ss' command or end of 'ssb' command)
+ *	KDB_DB_SSB	Single Step fault, caller should continue ('ssb' command)
+ *	KDB_DB_SSBPT	Single step over breakpoint
+ *	KDB_DB_NOBPT	No existing kdb breakpoint matches this debug exception
+ * Locking:
+ *	None.
+ * Remarks:
+ *	Yup, there be goto's here.
+ *
+ *	If multiple processors receive debug exceptions simultaneously,
+ *	one may be waiting at the kdb fence in kdb() while the user
+ *	issues a 'bc' command to clear the breakpoint the processor
+ *	which is waiting has already encountered.  If this is the case,
+ *	the debug registers will no longer match any entry in the
+ *	breakpoint table, and we'll return the value KDB_DB_NOBPT.
+ *	This can cause a panic in die_if_kernel().  It is safer to
+ *	disable the breakpoint (bd), go until all processors are past
+ *	the breakpoint then clear the breakpoint (bc).  This code
+ *	recognises a breakpoint even when disabled but not when it has
+ *	been cleared.
+ *
+ *	WARNING: This routine clears the debug state.  It should be called
+ *		 once per debug and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_db_trap(struct pt_regs *regs, int error_unused)
+{
+	kdb_machreg_t dr6;
+	kdb_machreg_t dr7;
+	int rw, reg;
+	int i;
+	kdb_dbtrap_t rv = KDB_DB_BPT;
+	kdb_bp_t *bp;
+	int cpu = smp_processor_id();
+
+	if (KDB_NULL_REGS(regs))
+		return KDB_DB_NOBPT;
+
+	dr6 = kdba_getdr6();
+	dr7 = kdba_getdr7();
+
+	if (KDB_DEBUG(BP))
+		kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7);
+	if (dr6 & DR6_BS) {
+		if (KDB_STATE(SSBPT)) {
+			if (KDB_DEBUG(BP))
+				kdb_printf("ssbpt\n");
+			KDB_STATE_CLEAR(SSBPT);
+			for(i=0,bp=kdb_breakpoints;
+			    i < KDB_MAXBPT;
+			    i++, bp++) {
+				if (KDB_DEBUG(BP))
+					kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n",
+						   bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu);
+				if (!bp->bp_enabled)
+					continue;
+				if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+					continue;
+				if (KDB_DEBUG(BP))
+					kdb_printf("bp for this cpu\n");
+				if (bp->bp_delayed) {
+					bp->bp_delayed = 0;
+					if (KDB_DEBUG(BP)){
+						/* Can't be hw breakpoint */
+						if (bp->bp_hardtype)
+							kdb_printf("kdb: Error - hw bp delayed\n");
+						kdb_printf("kdba_installbp\n");
+					}
+					kdba_installbp(regs, bp);
+					if (!KDB_STATE(DOING_SS)) {
+						regs->flags &= ~X86_EFLAGS_TF;
+						return(KDB_DB_SSBPT);
+					}
+					break;
+				}
+			}
+			if (i == KDB_MAXBPT) {
+				kdb_printf("kdb: Unable to find delayed breakpoint\n");
+			}
+			if (!KDB_STATE(DOING_SS)) {
+				regs->flags &= ~X86_EFLAGS_TF;
+				return(KDB_DB_NOBPT);
+			}
+			/* FALLTHROUGH */
+		}
+
+		/*
+		 * KDB_STATE_DOING_SS is set when the kernel debugger is using
+		 * the processor trap flag to single-step a processor.  If a
+		 * single step trap occurs and this flag is clear, the SS trap
+		 * will be ignored by KDB and the kernel will be allowed to deal
+		 * with it as necessary (e.g. for ptrace).
+		 */
+		if (!KDB_STATE(DOING_SS))
+			goto unknown;
+
+		/* single step */
+		rv = KDB_DB_SS;		/* Indicate single step */
+		if (KDB_STATE(DOING_SSB)) {
+			unsigned char instruction[2];
+
+			kdb_id1(regs->ip);
+			if (kdb_getarea(instruction, regs->ip) ||
+			    (instruction[0]&0xf0) == 0xe0 ||	/* short disp jumps */
+			    (instruction[0]&0xf0) == 0x70 ||	/* Misc. jumps */
+			    instruction[0]        == 0xc2 ||	/* ret */
+			    instruction[0]        == 0x9a ||	/* call */
+			    (instruction[0]&0xf8) == 0xc8 ||	/* enter, leave, iret, int, */
+			    ((instruction[0]      == 0x0f) &&
+			     ((instruction[1]&0xf0)== 0x80))
+			   ) {
+				/*
+				 * End the ssb command here.
+				 */
+				KDB_STATE_CLEAR(DOING_SSB);
+				KDB_STATE_CLEAR(DOING_SS);
+			} else {
+				rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */
+			}
+		} else {
+			/*
+			 * Print current insn
+			 */
+			kdb_printf("SS trap at ");
+			kdb_symbol_print(regs->ip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
+			kdb_id1(regs->ip);
+			KDB_STATE_CLEAR(DOING_SS);
+		}
+
+		if (rv != KDB_DB_SSB)
+			regs->flags &= ~X86_EFLAGS_TF;
+	}
+
+	if (dr6 & DR6_B0) {
+		rw = DR7_RW0(dr7);
+		reg = 0;
+		goto handle;
+	}
+
+	if (dr6 & DR6_B1) {
+		rw = DR7_RW1(dr7);
+		reg = 1;
+		goto handle;
+	}
+
+	if (dr6 & DR6_B2) {
+		rw = DR7_RW2(dr7);
+		reg = 2;
+		goto handle;
+	}
+
+	if (dr6 & DR6_B3) {
+		rw = DR7_RW3(dr7);
+		reg = 3;
+		goto handle;
+	}
+
+	if (rv > 0)
+		goto handled;
+
+	goto unknown;	/* dismiss */
+
+handle:
+	/*
+	 * Set Resume Flag
+	 */
+	regs->flags |= X86_EFLAGS_RF;
+
+	/*
+	 * Determine which breakpoint was encountered.
+	 */
+	for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+		if (!(bp->bp_free)
+		 && (bp->bp_global || bp->bp_cpu == smp_processor_id())
+		 && (bp->bp_hard[cpu])
+		 && (bp->bp_hard[cpu]->bph_reg == reg)) {
+			/*
+			 * Hit this breakpoint.
+			 */
+			kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n",
+				  kdba_rwtypes[rw],
+				  i, bp->bp_addr);
+
+			/*
+			 * For an instruction breakpoint, disassemble
+			 * the current instruction.
+			 */
+			if (rw == 0) {
+				kdb_id1(regs->ip);
+			}
+
+			goto handled;
+		}
+	}
+
+unknown:
+	regs->flags |= X86_EFLAGS_RF;	/* Supress further faults */
+	rv = KDB_DB_NOBPT;	/* Cause kdb() to return */
+
+handled:
+
+	/*
+	 * Clear the pending exceptions.
+	 */
+	kdba_putdr6(0);
+
+	return rv;
+}
+
+/*
+ * kdba_bp_trap
+ *
+ * 	Perform breakpoint processing upon entry to the
+ *	processor breakpoint instruction fault.   Determine and print
+ *	the active breakpoint.
+ *
+ * Parameters:
+ *	regs	Exception frame containing machine register state
+ *	error	Error number passed to kdb.
+ * Outputs:
+ *	None.
+ * Returns:
+ *	0	Standard instruction or data breakpoint encountered
+ *	1	Single Step fault ('ss' command)
+ *	2	Single Step fault, caller should continue ('ssb' command)
+ *	3	No existing kdb breakpoint matches this debug exception
+ * Locking:
+ *	None.
+ * Remarks:
+ *
+ * 	If multiple processors receive debug exceptions simultaneously,
+ *	one may be waiting at the kdb fence in kdb() while the user
+ *	issues a 'bc' command to clear the breakpoint the processor which
+ * 	is waiting has already encountered.   If this is the case, the
+ *	debug registers will no longer match any entry in the breakpoint
+ *	table, and we'll return the value '3'.  This can cause a panic
+ *	in die_if_kernel().  It is safer to disable the breakpoint (bd),
+ *	'go' until all processors are past the breakpoint then clear the
+ *	breakpoint (bc).  This code recognises a breakpoint even when
+ *	disabled but not when it has been cleared.
+ *
+ *	WARNING: This routine resets the ip.  It should be called
+ *		 once per breakpoint and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_bp_trap(struct pt_regs *regs, int error_unused)
+{
+	int i;
+	kdb_dbtrap_t rv;
+	kdb_bp_t *bp;
+
+	if (KDB_NULL_REGS(regs))
+		return KDB_DB_NOBPT;
+
+	/*
+	 * Determine which breakpoint was encountered.
+	 */
+	if (KDB_DEBUG(BP))
+		kdb_printf("kdba_bp_trap: ip=0x%lx (not adjusted) "
+			   "flags=0x%lx regs=0x%p sp=0x%lx\n",
+			   regs->ip, regs->flags, regs, regs->sp);
+
+	rv = KDB_DB_NOBPT;	/* Cause kdb() to return */
+
+	for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+		if (bp->bp_free)
+			continue;
+		if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+			continue;
+		 if ((void *)bp->bp_addr == (void *)(regs->ip - bp->bp_adjust)) {
+			/* Hit this breakpoint.  */
+			regs->ip -= bp->bp_adjust;
+			kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n",
+				  i, regs->ip);
+			kdb_id1(regs->ip);
+			rv = KDB_DB_BPT;
+			bp->bp_delay = 1;
+			/* SSBPT is set when the kernel debugger must single
+			 * step a task in order to re-establish an instruction
+			 * breakpoint which uses the instruction replacement
+			 * mechanism.  It is cleared by any action that removes
+			 * the need to single-step the breakpoint.
+			 */
+			KDB_STATE_SET(SSBPT);
+			break;
+		}
+	}
+
+	return rv;
+}
+
+/*
+ * kdba_handle_bp
+ *
+ *	Handle an instruction-breakpoint trap.  Called when re-installing
+ *	an enabled breakpoint which has has the bp_delay bit set.
+ *
+ * Parameters:
+ * Returns:
+ * Locking:
+ * Remarks:
+ *
+ * Ok, we really need to:
+ *	1) Restore the original instruction byte
+ *	2) Single Step
+ *	3) Restore breakpoint instruction
+ *	4) Continue.
+ *
+ *
+ */
+
+static void
+kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
+{
+	if (KDB_NULL_REGS(regs))
+		return;
+
+	if (KDB_DEBUG(BP))
+		kdb_printf("regs->ip = 0x%lx\n", regs->ip);
+
+	/*
+	 * Setup single step
+	 */
+	kdba_setsinglestep(regs);
+
+	/*
+	 * Reset delay attribute
+	 */
+	bp->bp_delay = 0;
+	bp->bp_delayed = 1;
+}
+
+
+/*
+ * kdba_bptype
+ *
+ *	Return a string describing type of breakpoint.
+ *
+ * Parameters:
+ *	bph	Pointer to hardware breakpoint description
+ * Outputs:
+ *	None.
+ * Returns:
+ *	Character string.
+ * Locking:
+ *	None.
+ * Remarks:
+ */
+
+char *
+kdba_bptype(kdbhard_bp_t *bph)
+{
+	char *mode;
+
+	mode = kdba_rwtypes[bph->bph_mode];
+
+	return mode;
+}
+
+/*
+ * kdba_printbpreg
+ *
+ *	Print register name assigned to breakpoint
+ *
+ * Parameters:
+ *	bph	Pointer hardware breakpoint structure
+ * Outputs:
+ *	None.
+ * Returns:
+ *	None.
+ * Locking:
+ *	None.
+ * Remarks:
+ */
+
+static void
+kdba_printbpreg(kdbhard_bp_t *bph)
+{
+	kdb_printf(" in dr%ld", bph->bph_reg);
+}
+
+/*
+ * kdba_printbp
+ *
+ *	Print string describing hardware breakpoint.
+ *
+ * Parameters:
+ *	bph	Pointer to hardware breakpoint description
+ * Outputs:
+ *	None.
+ * Returns:
+ *	None.
+ * Locking:
+ *	None.
+ * Remarks:
+ */
+
+void
+kdba_printbp(kdb_bp_t *bp)
+{
+	int cpu;
+
+	kdb_printf("\n    is enabled");
+	if (bp->bp_hardtype) {
+		if (bp->bp_global)
+			cpu = smp_processor_id();
+		else
+			cpu = bp->bp_cpu;
+		kdba_printbpreg(bp->bp_hard[cpu]);
+		if (bp->bp_hard[cpu]->bph_mode != 0) {
+			kdb_printf(" for %d bytes",
+				   bp->bp_hard[cpu]->bph_length+1);
+		}
+	}
+}
+
+/*
+ * kdba_parsebp
+ *
+ *	Parse architecture dependent portion of the
+ *	breakpoint command.
+ *
+ * Parameters:
+ *	None.
+ * Outputs:
+ *	None.
+ * Returns:
+ *	Zero for success, a kdb diagnostic for failure
+ * Locking:
+ *	None.
+ * Remarks:
+ *	for Ia32 architure, data access, data write and
+ *	I/O breakpoints are supported in addition to instruction
+ * 	breakpoints.
+ *
+ *	{datar|dataw|io|inst} [length]
+ */
+
+int
+kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
+{
+	int nextarg = *nextargp;
+	int diag;
+	kdbhard_bp_t *bph = &bp->bp_template;
+
+	bph->bph_mode = 0;		/* Default to instruction breakpoint */
+	bph->bph_length = 0;		/* Length must be zero for insn bp */
+	if ((argc + 1) != nextarg) {
+		if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
+			bph->bph_mode = 3;
+		} else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
+			bph->bph_mode = 1;
+		} else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
+			bph->bph_mode = 2;
+		} else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
+			bph->bph_mode = 0;
+		} else {
+			return KDB_ARGCOUNT;
+		}
+
+		bph->bph_length = 3;	/* Default to 4 byte */
+
+		nextarg++;
+
+		if ((argc + 1) != nextarg) {
+			unsigned long len;
+
+			diag = kdbgetularg((char *)argv[nextarg],
+					   &len);
+			if (diag)
+				return diag;
+
+
+			if ((len > 4) || (len == 3))
+				return KDB_BADLENGTH;
+
+			bph->bph_length = len;
+			bph->bph_length--; /* Normalize for debug register */
+			nextarg++;
+		}
+
+		if ((argc + 1) != nextarg)
+			return KDB_ARGCOUNT;
+
+		/*
+		 * Indicate to architecture independent level that
+		 * a hardware register assignment is required to enable
+		 * this breakpoint.
+		 */
+
+		bph->bph_free = 0;
+	} else {
+		if (KDB_DEBUG(BP))
+			kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
+		if (bp->bp_forcehw) {
+			/*
+			 * We are forced to use a hardware register for this
+			 * breakpoint because either the bph or bpha
+			 * commands were used to establish this breakpoint.
+			 */
+			bph->bph_free = 0;
+		} else {
+			/*
+			 * Indicate to architecture dependent level that
+			 * the instruction replacement breakpoint technique
+			 * should be used for this breakpoint.
+			 */
+			bph->bph_free = 1;
+			bp->bp_adjust = 1;	/* software, int 3 is one byte */
+		}
+	}
+
+	if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) {
+		kdb_printf("Invalid address for breakpoint, ignoring bp command\n");
+		return KDB_BADADDR;
+	}
+
+	*nextargp = nextarg;
+	return 0;
+}
+
+/*
+ * kdba_allocbp
+ *
+ *	Allocate hw register for bp on specific CPU
+ *
+ * Parameters:
+ *	None.
+ * Outputs:
+ *	None.
+ * Returns:
+ *	A pointer to the allocated register kdbhard_bp_t structure for
+ *	success, Null and a non-zero diagnostic for failure.
+ * Locking:
+ *	None.
+ * Remarks:
+ */
+
+static kdbhard_bp_t *
+kdba_allocbp(kdbhard_bp_t *bph, int *diagp, unsigned int cpu)
+{
+	int i;
+	kdbhard_bp_t *newbph;
+
+	for(i=0; i < KDB_MAXHARDBPT; i++) {
+		newbph=&(kdb_hardbreaks[cpu][i]);
+		if (newbph->bph_free) {
+			break;
+		}
+	}
+
+	if (i == KDB_MAXHARDBPT) {
+		*diagp = KDB_TOOMANYDBREGS;
+		return NULL;
+	}
+
+	*diagp = 0;
+
+	/*
+	 * Copy data from template.  Can't just copy the entire template
+	 * here because the register number in kdb_hardbreaks must be
+	 * preserved.
+	 */
+	newbph->bph_data = bph->bph_data;
+	newbph->bph_write = bph->bph_write;
+	newbph->bph_mode = bph->bph_mode;
+	newbph->bph_length = bph->bph_length;
+
+	/*
+	 * Mark entry allocated.
+	 */
+	newbph->bph_free = 0;
+
+	return newbph;
+}
+
+/*
+ * kdba_alloc_hwbp
+ *
+ *	Associate a hardware registers with a breakpoint.
+ *	If hw bp is global hw registers descriptor will be allocated
+ *	on every CPU.
+ *
+ * Parameters:
+ *	bp - hardware bp
+ *	diagp - pointer to variable that will store error when
+ *	function complete
+ * Outputs:
+ *	None.
+ * Returns:
+ *	None
+ * Locking:
+ *	None.
+ * Remarks:
+ *	Should be called with correct bp->bp_template
+ */
+
+void
+kdba_alloc_hwbp(kdb_bp_t *bp, int *diagp)
+{
+	int i;
+
+	if (bp->bp_global){
+		for (i = 0; i < NR_CPUS; ++i) {
+			if (!cpu_online(i))
+				continue;
+			bp->bp_hard[i] = kdba_allocbp(&bp->bp_template, diagp, i);
+			if (*diagp)
+				break;
+		}
+	} else {
+		bp->bp_hard[bp->bp_cpu] = kdba_allocbp(&bp->bp_template, diagp, bp->bp_cpu);
+	}
+	bp->bp_hardtype = 1;
+}
+
+/*
+ * kdba_freebp
+ *
+ *	Deallocate hw registers descriptor for bp on specific CPU
+ *
+ * Parameters:
+ *	None.
+ * Outputs:
+ *	None.
+ * Returns:
+ *	Zero for success, a kdb diagnostic for failure
+ * Locking:
+ *	None.
+ * Remarks:
+ */
+
+static void
+kdba_freebp(kdbhard_bp_t *bph)
+{
+	bph->bph_free = 1;
+}
+
+/*
+ * kdba_free_hwbp
+ *
+ *	Frees allocated hw registers descriptors for bp.
+ *	If hw bp is global, hw registers descriptors will be freed
+ *	on every CPU.
+ *
+ * Parameters:
+ *	bp - hardware bp
+ * Outputs:
+ *	None.
+ * Returns:
+ *	None
+ * Locking:
+ *	None.
+ * Remarks:
+ *	Should be called with correct bp->bp_template
+ */
+
+void
+kdba_free_hwbp(kdb_bp_t *bp)
+{
+	int i;
+
+	/* When kernel enters KDB, first, all local bps
+	 * are removed, so here we don't need to clear
+	 * debug registers.
+	 */
+
+	if (bp->bp_global){
+		for (i = 0; i < NR_CPUS; ++i) {
+			if (!cpu_online(i))
+				continue;
+			if (bp->bp_hard[i])
+				kdba_freebp(bp->bp_hard[i]);
+			bp->bp_hard[i] = 0;
+		}
+	} else {
+		kdba_freebp(bp->bp_hard[bp->bp_cpu]);
+		bp->bp_hard[bp->bp_cpu] = NULL;
+	}
+	bp->bp_hardtype = 0;
+}
+
+/*
+ * kdba_initbp
+ *
+ *	Initialize the breakpoint table for the hardware breakpoint
+ *	register.
+ *
+ * Parameters:
+ *	None.
+ * Outputs:
+ *	None.
+ * Returns:
+ *	Zero for success, a kdb diagnostic for failure
+ * Locking:
+ *	None.
+ * Remarks:
+ *
+ *	There is one entry per register.  On the ia32 architecture
+ *	all the registers are interchangeable, so no special allocation
+ *	criteria are required.
+ */
+
+void
+kdba_initbp(void)
+{
+	int i,j;
+	kdbhard_bp_t *bph;
+
+	/*
+	 * Clear the hardware breakpoint table
+	 */
+
+	memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks));
+
+	for (i = 0; i < NR_CPUS; ++i) {
+		/* Called early so we don't know actual
+		 * ammount of CPUs
+		 */
+		for(j=0; j < KDB_MAXHARDBPT; j++) {
+			bph=&(kdb_hardbreaks[i][j]);
+			bph->bph_reg = j;
+			bph->bph_free = 1;
+		}
+	}
+}
+
+/*
+ * kdba_installbp
+ *
+ *	Install a breakpoint
+ *
+ * Parameters:
+ *	regs	Exception frame
+ *	bp	Breakpoint structure for the breakpoint to be installed
+ * Outputs:
+ *	None.
+ * Returns:
+ *	0 if breakpoint installed.
+ * Locking:
+ *	None.
+ * Remarks:
+ *	For hardware breakpoints, a debug register is allocated
+ *	and assigned to the breakpoint.  If no debug register is
+ *	available, a warning message is printed and the breakpoint
+ *	is disabled.
+ *
+ *	For instruction replacement breakpoints, we must single-step
+ *	over the replaced instruction at this point so we can re-install
+ *	the breakpoint instruction after the single-step.  SSBPT is set
+ *	when the breakpoint is initially hit and is cleared by any action
+ *	that removes the need for single-step over the breakpoint.
+ */
+
+int
+kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp)
+{
+	int cpu = smp_processor_id();
+
+	/*
+	 * Install the breakpoint, if it is not already installed.
+	 */
+
+	if (KDB_DEBUG(BP)) {
+		kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed);
+	}
+	if (!KDB_STATE(SSBPT))
+		bp->bp_delay = 0;
+
+	if (bp->bp_hardtype) {
+		if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){
+			kdb_printf("kdba_installbp: cpu != bp->bp_cpu for local hw bp\n");
+		}
+
+		if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){
+			kdb_printf("kdba_installbp: Error - bp_hard[smp_processor_id()] is emply\n");
+			return 1;
+		}
+
+		if (!bp->bp_hard[cpu]->bph_installed){
+			kdba_installdbreg(bp);
+			bp->bp_hard[cpu]->bph_installed = 1;
+			if (KDB_DEBUG(BP)) {
+				kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
+			}
+		}
+	} else if (!bp->bp_installed) {
+		if (bp->bp_delay) {
+			if (KDB_DEBUG(BP))
+				kdb_printf("kdba_installbp delayed bp\n");
+			kdba_handle_bp(regs, bp);
+		} else {
+			if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) ||
+			    kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) {
+				kdb_printf("kdba_installbp failed to set software breakpoint at " kdb_bfd_vma_fmt "\n", bp->bp_addr);
+				return(1);
+			}
+			bp->bp_installed = 1;
+			if (KDB_DEBUG(BP))
+				kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n",
+					   IA32_BREAKPOINT_INSTRUCTION, bp->bp_addr);
+		}
+	}
+	return(0);
+}
+
+/*
+ * kdba_removebp
+ *
+ *	Make a breakpoint ineffective.
+ *
+ * Parameters:
+ *	None.
+ * Outputs:
+ *	None.
+ * Returns:
+ *	None.
+ * Locking:
+ *	None.
+ * Remarks:
+ */
+
+int
+kdba_removebp(kdb_bp_t *bp)
+{
+	int cpu = smp_processor_id();
+
+	/*
+	 * For hardware breakpoints, remove it from the active register,
+	 * for software breakpoints, restore the instruction stream.
+	 */
+	if (KDB_DEBUG(BP)) {
+		kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed);
+	}
+
+	if (bp->bp_hardtype) {
+		if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){
+			kdb_printf("kdba_removebp: cpu != bp->bp_cpu for local hw bp\n");
+		}
+
+		if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){
+			kdb_printf("kdba_removebp: Error - bp_hard[smp_processor_id()] is emply\n");
+			return 1;
+		}
+
+		if (KDB_DEBUG(BP)) {
+			kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
+		}
+
+		if (bp->bp_hard[cpu]->bph_installed){
+			if (KDB_DEBUG(BP)) {
+				kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
+			}
+			kdba_removedbreg(bp);
+			bp->bp_hard[cpu]->bph_installed = 0;
+		}
+	} else if (bp->bp_installed) {
+		if (KDB_DEBUG(BP))
+			kdb_printf("kdb: restoring instruction 0x%x at " kdb_bfd_vma_fmt "\n",
+				   bp->bp_inst, bp->bp_addr);
+		if (kdb_putword(bp->bp_addr, bp->bp_inst, 1))
+			return(1);
+		bp->bp_installed = 0;
+	}
+	return(0);
+}
Index: xfs-dev/arch/x86/kdb/kdba_bp_32.c
===================================================================
--- xfs-dev.orig/arch/x86/kdb/kdba_bp_32.c	2008-12-23 09:30:36.621197339 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,914 +0,0 @@
-/*
- * Kernel Debugger Architecture Dependent Breakpoint Handling
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/ptrace.h>
-#include <linux/kdb.h>
-#include <linux/kdbprivate.h>
-
-
-static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write",
-			"I/O", "Data Access"};
-
-/*
- * Table describing processor architecture hardware
- * breakpoint registers for every CPU.
- */
-
-static kdbhard_bp_t kdb_hardbreaks[NR_CPUS][KDB_MAXHARDBPT];
-
-/*
- * kdba_db_trap
- *
- * 	Perform breakpoint processing upon entry to the
- *	processor debugger fault.   Determine and print
- *	the active breakpoint.
- *
- * Parameters:
- *	regs	Exception frame containing machine register state
- *	error	Error number passed to kdb.
- * Outputs:
- *	None.
- * Returns:
- *	KDB_DB_BPT	Standard instruction or data breakpoint encountered
- *	KDB_DB_SS	Single Step fault ('ss' command or end of 'ssb' command)
- *	KDB_DB_SSB	Single Step fault, caller should continue ('ssb' command)
- *	KDB_DB_SSBPT	Single step over breakpoint
- *	KDB_DB_NOBPT	No existing kdb breakpoint matches this debug exception
- * Locking:
- *	None.
- * Remarks:
- *	Yup, there be goto's here.
- *
- *	If multiple processors receive debug exceptions simultaneously,
- *	one may be waiting at the kdb fence in kdb() while the user
- *	issues a 'bc' command to clear the breakpoint the processor
- *	which is waiting has already encountered.  If this is the case,
- *	the debug registers will no longer match any entry in the
- *	breakpoint table, and we'll return the value KDB_DB_NOBPT.
- *	This can cause a panic in die_if_kernel().  It is safer to
- *	disable the breakpoint (bd), go until all processors are past
- *	the breakpoint then clear the breakpoint (bc).  This code
- *	recognises a breakpoint even when disabled but not when it has
- *	been cleared.
- *
- *	WARNING: This routine clears the debug state.  It should be called
- *		 once per debug and the result cached.
- */
-
-kdb_dbtrap_t
-kdba_db_trap(struct pt_regs *regs, int error_unused)
-{
-	kdb_machreg_t dr6;
-	kdb_machreg_t dr7;
-	int rw, reg;
-	int i;
-	kdb_dbtrap_t rv = KDB_DB_BPT;
-	kdb_bp_t *bp;
-	int cpu = smp_processor_id();
-
-	if (KDB_NULL_REGS(regs))
-		return KDB_DB_NOBPT;
-
-	dr6 = kdba_getdr6();
-	dr7 = kdba_getdr7();
-
-	if (KDB_DEBUG(BP))
-		kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7);
-	if (dr6 & DR6_BS) {
-		if (KDB_STATE(SSBPT)) {
-			if (KDB_DEBUG(BP))
-				kdb_printf("ssbpt\n");
-			KDB_STATE_CLEAR(SSBPT);
-			for(i=0,bp=kdb_breakpoints;
-			    i < KDB_MAXBPT;
-			    i++, bp++) {
-				if (KDB_DEBUG(BP))
-					kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n",
-						   bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu);
-				if (!bp->bp_enabled)
-					continue;
-				if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
-					continue;
-				if (KDB_DEBUG(BP))
-					kdb_printf("bp for this cpu\n");
-				if (bp->bp_delayed) {
-					bp->bp_delayed = 0;
-					if (KDB_DEBUG(BP)){
-						/* Can't be hw breakpoint */
-						if (bp->bp_hardtype)
-							kdb_printf("kdb: Error - hw bp delayed\n");
-						kdb_printf("kdba_installbp\n");
-					}
-					kdba_installbp(regs, bp);
-					if (!KDB_STATE(DOING_SS)) {
-						regs->flags &= ~EF_TF;
-						return(KDB_DB_SSBPT);
-					}
-					break;
-				}
-			}
-			if (i == KDB_MAXBPT) {
-				kdb_printf("kdb: Unable to find delayed breakpoint\n");
-			}
-			if (!KDB_STATE(DOING_SS)) {
-				regs->flags &= ~EF_TF;
-				return(KDB_DB_NOBPT);
-			}
-			/* FALLTHROUGH */
-		}
-
-		/*
-		 * KDB_STATE_DOING_SS is set when the kernel debugger is using
-		 * the processor trap flag to single-step a processor.  If a
-		 * single step trap occurs and this flag is clear, the SS trap
-		 * will be ignored by KDB and the kernel will be allowed to deal
-		 * with it as necessary (e.g. for ptrace).
-		 */
-		if (!KDB_STATE(DOING_SS))
-			goto unknown;
-
-		/* single step */
-		rv = KDB_DB_SS;		/* Indicate single step */
-		if (KDB_STATE(DOING_SSB)) {
-			unsigned char instruction[2];
-
-			kdb_id1(regs->ip);
-			if (kdb_getarea(instruction, regs->ip) ||
-			    (instruction[0]&0xf0) == 0xe0 ||	/* short disp jumps */
-			    (instruction[0]&0xf0) == 0x70 ||	/* Misc. jumps */
-			    instruction[0]        == 0xc2 ||	/* ret */
-			    instruction[0]        == 0x9a ||	/* call */
-			    (instruction[0]&0xf8) == 0xc8 ||	/* enter, leave, iret, int, */
-			    ((instruction[0]      == 0x0f) &&
-			     ((instruction[1]&0xf0)== 0x80))
-			   ) {
-				/*
-				 * End the ssb command here.
-				 */
-				KDB_STATE_CLEAR(DOING_SSB);
-				KDB_STATE_CLEAR(DOING_SS);
-			} else {
-				rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */
-			}
-		} else {
-			/*
-			 * Print current insn
-			 */
-			kdb_printf("SS trap at ");
-			kdb_symbol_print(regs->ip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
-			kdb_id1(regs->ip);
-			KDB_STATE_CLEAR(DOING_SS);
-		}
-
-		if (rv != KDB_DB_SSB)
-			regs->flags &= ~EF_TF;
-	}
-
-	if (dr6 & DR6_B0) {
-		rw = DR7_RW0(dr7);
-		reg = 0;
-		goto handle;
-	}
-
-	if (dr6 & DR6_B1) {
-		rw = DR7_RW1(dr7);
-		reg = 1;
-		goto handle;
-	}
-
-	if (dr6 & DR6_B2) {
-		rw = DR7_RW2(dr7);
-		reg = 2;
-		goto handle;
-	}
-
-	if (dr6 & DR6_B3) {
-		rw = DR7_RW3(dr7);
-		reg = 3;
-		goto handle;
-	}
-
-	if (rv > 0)
-		goto handled;
-
-	goto unknown;	/* dismiss */
-
-handle:
-	/*
-	 * Set Resume Flag
-	 */
-	regs->flags |= EF_RF;
-
-	/*
-	 * Determine which breakpoint was encountered.
-	 */
-	for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
-		if (!(bp->bp_free)
-		 && (bp->bp_global || bp->bp_cpu == smp_processor_id())
-		 && (bp->bp_hard[cpu])
-		 && (bp->bp_hard[cpu]->bph_reg == reg)) {
-			/*
-			 * Hit this breakpoint.
-			 */
-			kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n",
-				  kdba_rwtypes[rw],
-				  i, bp->bp_addr);
-
-			/*
-			 * For an instruction breakpoint, disassemble
-			 * the current instruction.
-			 */
-			if (rw == 0) {
-				kdb_id1(regs->ip);
-			}
-
-			goto handled;
-		}
-	}
-
-unknown:
-	regs->flags |= EF_RF;	/* Supress further faults */
-	rv = KDB_DB_NOBPT;	/* Cause kdb() to return */
-
-handled:
-
-	/*
-	 * Clear the pending exceptions.
-	 */
-	kdba_putdr6(0);
-
-	return rv;
-}
-
-/*
- * kdba_bp_trap
- *
- * 	Perform breakpoint processing upon entry to the
- *	processor breakpoint instruction fault.   Determine and print
- *	the active breakpoint.
- *
- * Parameters:
- *	regs	Exception frame containing machine register state
- *	error	Error number passed to kdb.
- * Outputs:
- *	None.
- * Returns:
- *	0	Standard instruction or data breakpoint encountered
- *	1	Single Step fault ('ss' command)
- *	2	Single Step fault, caller should continue ('ssb' command)
- *	3	No existing kdb breakpoint matches this debug exception
- * Locking:
- *	None.
- * Remarks:
- *
- * 	If multiple processors receive debug exceptions simultaneously,
- *	one may be waiting at the kdb fence in kdb() while the user
- *	issues a 'bc' command to clear the breakpoint the processor which
- * 	is waiting has already encountered.   If this is the case, the
- *	debug registers will no longer match any entry in the breakpoint
- *	table, and we'll return the value '3'.  This can cause a panic
- *	in die_if_kernel().  It is safer to disable the breakpoint (bd),
- *	'go' until all processors are past the breakpoint then clear the
- *	breakpoint (bc).  This code recognises a breakpoint even when
- *	disabled but not when it has been cleared.
- *
- *	WARNING: This routine resets the ip.  It should be called
- *		 once per breakpoint and the result cached.
- */
-
-kdb_dbtrap_t
-kdba_bp_trap(struct pt_regs *regs, int error_unused)
-{
-	int i;
-	kdb_dbtrap_t rv;
-	kdb_bp_t *bp;
-
-	if (KDB_NULL_REGS(regs))
-		return KDB_DB_NOBPT;
-
-	/*
-	 * Determine which breakpoint was encountered.
-	 */
-	if (KDB_DEBUG(BP))
-		kdb_printf("kdba_bp_trap: ip=0x%lx (not adjusted) "
-			   "flags=0x%lx regs=0x%p sp=0x%lx\n",
-			   regs->ip, regs->flags, regs, regs->sp);
-
-	rv = KDB_DB_NOBPT;	/* Cause kdb() to return */
-
-	for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
-		if (bp->bp_free)
-			continue;
-		if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
-			continue;
-		 if ((void *)bp->bp_addr == (void *)(regs->ip - bp->bp_adjust)) {
-			/* Hit this breakpoint.  */
-			regs->ip -= bp->bp_adjust;
-			kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n",
-				  i, regs->ip);
-			kdb_id1(regs->ip);
-			rv = KDB_DB_BPT;
-			bp->bp_delay = 1;
-			/* SSBPT is set when the kernel debugger must single
-			 * step a task in order to re-establish an instruction
-			 * breakpoint which uses the instruction replacement
-			 * mechanism.  It is cleared by any action that removes
-			 * the need to single-step the breakpoint.
-			 */
-			KDB_STATE_SET(SSBPT);
-			break;
-		}
-	}
-
-	return rv;
-}
-
-/*
- * kdba_handle_bp
- *
- *	Handle an instruction-breakpoint trap.  Called when re-installing
- *	an enabled breakpoint which has has the bp_delay bit set.
- *
- * Parameters:
- * Returns:
- * Locking:
- * Remarks:
- *
- * Ok, we really need to:
- *	1) Restore the original instruction byte
- *	2) Single Step
- *	3) Restore breakpoint instruction
- *	4) Continue.
- *
- *
- */
-
-static void
-kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
-{
-	if (KDB_NULL_REGS(regs))
-		return;
-
-	if (KDB_DEBUG(BP))
-		kdb_printf("regs->ip = 0x%lx\n", regs->ip);
-
-	/*
-	 * Setup single step
-	 */
-	kdba_setsinglestep(regs);
-
-	/*
-	 * Reset delay attribute
-	 */
-	bp->bp_delay = 0;
-	bp->bp_delayed = 1;
-}
-
-
-/*
- * kdba_bptype
- *
- *	Return a string describing type of breakpoint.
- *
- * Parameters:
- *	bph	Pointer to hardware breakpoint description
- * Outputs:
- *	None.
- * Returns:
- *	Character string.
- * Locking:
- *	None.
- * Remarks:
- */
-
-char *
-kdba_bptype(kdbhard_bp_t *bph)
-{
-	char *mode;
-
-	mode = kdba_rwtypes[bph->bph_mode];
-
-	return mode;
-}
-
-/*
- * kdba_printbpreg
- *
- *	Print register name assigned to breakpoint
- *
- * Parameters:
- *	bph	Pointer hardware breakpoint structure
- * Outputs:
- *	None.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- */
-
-static void
-kdba_printbpreg(kdbhard_bp_t *bph)
-{
-	kdb_printf(" in dr%ld", bph->bph_reg);
-}
-
-/*
- * kdba_printbp
- *
- *	Print string describing hardware breakpoint.
- *
- * Parameters:
- *	bph	Pointer to hardware breakpoint description
- * Outputs:
- *	None.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- */
-
-void
-kdba_printbp(kdb_bp_t *bp)
-{
-	int cpu;
-
-	kdb_printf("\n    is enabled");
-	if (bp->bp_hardtype) {
-		if (bp->bp_global)
-			cpu = smp_processor_id();
-		else
-			cpu = bp->bp_cpu;
-		kdba_printbpreg(bp->bp_hard[cpu]);
-		if (bp->bp_hard[cpu]->bph_mode != 0) {
-			kdb_printf(" for %d bytes",
-				   bp->bp_hard[cpu]->bph_length+1);
-		}
-	}
-}
-
-/*
- * kdba_parsebp
- *
- *	Parse architecture dependent portion of the
- *	breakpoint command.
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	Zero for success, a kdb diagnostic for failure
- * Locking:
- *	None.
- * Remarks:
- *	for Ia32 architure, data access, data write and
- *	I/O breakpoints are supported in addition to instruction
- * 	breakpoints.
- *
- *	{datar|dataw|io|inst} [length]
- */
-
-int
-kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
-{
-	int nextarg = *nextargp;
-	int diag;
-	kdbhard_bp_t *bph = &bp->bp_template;
-
-	bph->bph_mode = 0;		/* Default to instruction breakpoint */
-	bph->bph_length = 0;		/* Length must be zero for insn bp */
-	if ((argc + 1) != nextarg) {
-		if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
-			bph->bph_mode = 3;
-		} else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
-			bph->bph_mode = 1;
-		} else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
-			bph->bph_mode = 2;
-		} else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
-			bph->bph_mode = 0;
-		} else {
-			return KDB_ARGCOUNT;
-		}
-
-		bph->bph_length = 3;	/* Default to 4 byte */
-
-		nextarg++;
-
-		if ((argc + 1) != nextarg) {
-			unsigned long len;
-
-			diag = kdbgetularg((char *)argv[nextarg],
-					   &len);
-			if (diag)
-				return diag;
-
-
-			if ((len > 4) || (len == 3))
-				return KDB_BADLENGTH;
-
-			bph->bph_length = len;
-			bph->bph_length--; /* Normalize for debug register */
-			nextarg++;
-		}
-
-		if ((argc + 1) != nextarg)
-			return KDB_ARGCOUNT;
-
-		/*
-		 * Indicate to architecture independent level that
-		 * a hardware register assignment is required to enable
-		 * this breakpoint.
-		 */
-
-		bph->bph_free = 0;
-	} else {
-		if (KDB_DEBUG(BP))
-			kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
-		if (bp->bp_forcehw) {
-			/*
-			 * We are forced to use a hardware register for this
-			 * breakpoint because either the bph or bpha
-			 * commands were used to establish this breakpoint.
-			 */
-			bph->bph_free = 0;
-		} else {
-			/*
-			 * Indicate to architecture dependent level that
-			 * the instruction replacement breakpoint technique
-			 * should be used for this breakpoint.
-			 */
-			bph->bph_free = 1;
-			bp->bp_adjust = 1;	/* software, int 3 is one byte */
-		}
-	}
-
-	if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) {
-		kdb_printf("Invalid address for breakpoint, ignoring bp command\n");
-		return KDB_BADADDR;
-	}
-
-	*nextargp = nextarg;
-	return 0;
-}
-
-/*
- * kdba_allocbp
- *
- *	Allocate hw register for bp on specific CPU
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	A pointer to the allocated register kdbhard_bp_t structure for
- *	success, Null and a non-zero diagnostic for failure.
- * Locking:
- *	None.
- * Remarks:
- */
-
-static kdbhard_bp_t *
-kdba_allocbp(kdbhard_bp_t *bph, int *diagp, unsigned int cpu)
-{
-	int i;
-	kdbhard_bp_t *newbph;
-
-	for(i=0; i < KDB_MAXHARDBPT; i++) {
-		newbph=&(kdb_hardbreaks[cpu][i]);
-		if (newbph->bph_free) {
-			break;
-		}
-	}
-
-	if (i == KDB_MAXHARDBPT) {
-		*diagp = KDB_TOOMANYDBREGS;
-		return NULL;
-	}
-
-	*diagp = 0;
-
-	/*
-	 * Copy data from template.  Can't just copy the entire template
-	 * here because the register number in kdb_hardbreaks must be
-	 * preserved.
-	 */
-	newbph->bph_data = bph->bph_data;
-	newbph->bph_write = bph->bph_write;
-	newbph->bph_mode = bph->bph_mode;
-	newbph->bph_length = bph->bph_length;
-
-	/*
-	 * Mark entry allocated.
-	 */
-	newbph->bph_free = 0;
-
-	return newbph;
-}
-
-/*
- * kdba_alloc_hwbp
- *
- *	Associate a hardware registers with a breakpoint.
- *	If hw bp is global hw registers descriptor will be allocated
- *	on every CPU.
- *
- * Parameters:
- *	bp - hardware bp
- *	diagp - pointer to variable that will store error when
- *	function complete
- * Outputs:
- *	None.
- * Returns:
- *	None
- * Locking:
- *	None.
- * Remarks:
- *	Should be called with correct bp->bp_template
- */
-
-void
-kdba_alloc_hwbp(kdb_bp_t *bp, int *diagp)
-{
-	int i;
-
-	if (bp->bp_global){
-		for (i = 0; i < NR_CPUS; ++i) {
-			if (!cpu_online(i))
-				continue;
-			bp->bp_hard[i] = kdba_allocbp(&bp->bp_template, diagp, i);
-			if (*diagp)
-				break;
-		}
-	} else {
-		bp->bp_hard[bp->bp_cpu] = kdba_allocbp(&bp->bp_template, diagp, bp->bp_cpu);
-	}
-	bp->bp_hardtype = 1;
-}
-
-/*
- * kdba_freebp
- *
- *	Deallocate hw registers descriptor for bp on specific CPU
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	Zero for success, a kdb diagnostic for failure
- * Locking:
- *	None.
- * Remarks:
- */
-
-static void
-kdba_freebp(kdbhard_bp_t *bph)
-{
-	bph->bph_free = 1;
-}
-
-/*
- * kdba_free_hwbp
- *
- *	Frees allocated hw registers descriptors for bp.
- *	If hw bp is global, hw registers descriptors will be freed
- *	on every CPU.
- *
- * Parameters:
- *	bp - hardware bp
- * Outputs:
- *	None.
- * Returns:
- *	None
- * Locking:
- *	None.
- * Remarks:
- *	Should be called with correct bp->bp_template
- */
-
-void
-kdba_free_hwbp(kdb_bp_t *bp)
-{
-	int i;
-
-	/* When kernel enters KDB, first, all local bps
-	 * are removed, so here we don't need to clear
-	 * debug registers.
-	 */
-
-	if (bp->bp_global){
-		for (i = 0; i < NR_CPUS; ++i) {
-			if (!cpu_online(i))
-				continue;
-			if (bp->bp_hard[i])
-				kdba_freebp(bp->bp_hard[i]);
-			bp->bp_hard[i] = 0;
-		}
-	} else {
-		kdba_freebp(bp->bp_hard[bp->bp_cpu]);
-		bp->bp_hard[bp->bp_cpu] = NULL;
-	}
-	bp->bp_hardtype = 0;
-}
-
-/*
- * kdba_initbp
- *
- *	Initialize the breakpoint table for the hardware breakpoint
- *	register.
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	Zero for success, a kdb diagnostic for failure
- * Locking:
- *	None.
- * Remarks:
- *
- *	There is one entry per register.  On the ia32 architecture
- *	all the registers are interchangeable, so no special allocation
- *	criteria are required.
- */
-
-void
-kdba_initbp(void)
-{
-	int i,j;
-	kdbhard_bp_t *bph;
-
-	/*
-	 * Clear the hardware breakpoint table
-	 */
-
-	memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks));
-
-	for (i = 0; i < NR_CPUS; ++i) {
-		/* Called early so we don't know actual
-		 * ammount of CPUs
-		 */
-		for(j=0; j < KDB_MAXHARDBPT; j++) {
-			bph=&(kdb_hardbreaks[i][j]);
-			bph->bph_reg = j;
-			bph->bph_free = 1;
-		}
-	}
-}
-
-/*
- * kdba_installbp
- *
- *	Install a breakpoint
- *
- * Parameters:
- *	regs	Exception frame
- *	bp	Breakpoint structure for the breakpoint to be installed
- * Outputs:
- *	None.
- * Returns:
- *	0 if breakpoint installed.
- * Locking:
- *	None.
- * Remarks:
- *	For hardware breakpoints, a debug register is allocated
- *	and assigned to the breakpoint.  If no debug register is
- *	available, a warning message is printed and the breakpoint
- *	is disabled.
- *
- *	For instruction replacement breakpoints, we must single-step
- *	over the replaced instruction at this point so we can re-install
- *	the breakpoint instruction after the single-step.  SSBPT is set
- *	when the breakpoint is initially hit and is cleared by any action
- *	that removes the need for single-step over the breakpoint.
- */
-
-int
-kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp)
-{
-	int cpu = smp_processor_id();
-
-	/*
-	 * Install the breakpoint, if it is not already installed.
-	 */
-
-	if (KDB_DEBUG(BP)) {
-		kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed);
-	}
-	if (!KDB_STATE(SSBPT))
-		bp->bp_delay = 0;
-
-	if (bp->bp_hardtype) {
-		if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){
-			kdb_printf("kdba_installbp: cpu != bp->bp_cpu for local hw bp\n");
-		}
-
-		if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){
-			kdb_printf("kdba_installbp: Error - bp_hard[smp_processor_id()] is emply\n");
-			return 1;
-		}
-
-		if (!bp->bp_hard[cpu]->bph_installed){
-			kdba_installdbreg(bp);
-			bp->bp_hard[cpu]->bph_installed = 1;
-			if (KDB_DEBUG(BP)) {
-				kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
-				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
-			}
-		}
-	} else if (!bp->bp_installed) {
-		if (bp->bp_delay) {
-			if (KDB_DEBUG(BP))
-				kdb_printf("kdba_installbp delayed bp\n");
-			kdba_handle_bp(regs, bp);
-		} else {
-			if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) ||
-			    kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) {
-				kdb_printf("kdba_installbp failed to set software breakpoint at 0x%lx\n", bp->bp_addr);
-				return(1);
-			}
-			bp->bp_installed = 1;
-			if (KDB_DEBUG(BP))
-				kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n",
-					   IA32_BREAKPOINT_INSTRUCTION, bp->bp_addr);
-		}
-	}
-	return(0);
-}
-
-/*
- * kdba_removebp
- *
- *	Make a breakpoint ineffective.
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- */
-
-int
-kdba_removebp(kdb_bp_t *bp)
-{
-	int cpu = smp_processor_id();
-
-	/*
-	 * For hardware breakpoints, remove it from the active register,
-	 * for software breakpoints, restore the instruction stream.
-	 */
-	if (KDB_DEBUG(BP)) {
-		kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed);
-	}
-
-	if (bp->bp_hardtype) {
-		if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){
-			kdb_printf("kdba_removebp: cpu != bp->bp_cpu for local hw bp\n");
-		}
-
-		if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){
-			kdb_printf("kdba_removebp: Error - bp_hard[smp_processor_id()] is emply\n");
-			return 1;
-		}
-
-		if (KDB_DEBUG(BP)) {
-			kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n",
-				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
-		}
-
-		if (bp->bp_hard[cpu]->bph_installed){
-			if (KDB_DEBUG(BP)) {
-				kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
-				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
-			}
-			kdba_removedbreg(bp);
-			bp->bp_hard[cpu]->bph_installed = 0;
-		}
-	} else if (bp->bp_installed) {
-		if (KDB_DEBUG(BP))
-			kdb_printf("kdb: restoring instruction 0x%x at " kdb_bfd_vma_fmt "\n",
-				   bp->bp_inst, bp->bp_addr);
-		if (kdb_putword(bp->bp_addr, bp->bp_inst, 1))
-			return(1);
-		bp->bp_installed = 0;
-	}
-	return(0);
-}
Index: xfs-dev/arch/x86/kdb/kdba_bp_64.c
===================================================================
--- xfs-dev.orig/arch/x86/kdb/kdba_bp_64.c	2008-12-23 09:30:36.624197372 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,912 +0,0 @@
-/*
- * Kernel Debugger Architecture Dependent Breakpoint Handling
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/ptrace.h>
-#include <linux/kdb.h>
-#include <linux/kdbprivate.h>
-
-
-static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write",
-			"I/O", "Data Access"};
-
-/*
- * Table describing processor architecture hardware
- * breakpoint registers for every CPU.
- */
-
-static kdbhard_bp_t kdb_hardbreaks[NR_CPUS][KDB_MAXHARDBPT];
-
-/*
- * kdba_db_trap
- *
- * 	Perform breakpoint processing upon entry to the
- *	processor debugger fault.   Determine and print
- *	the active breakpoint.
- *
- * Parameters:
- *	regs	Exception frame containing machine register state
- *	error	Error number passed to kdb.
- * Outputs:
- *	None.
- * Returns:
- *	KDB_DB_BPT	Standard instruction or data breakpoint encountered
- *	KDB_DB_SS	Single Step fault ('ss' command or end of 'ssb' command)
- *	KDB_DB_SSB	Single Step fault, caller should continue ('ssb' command)
- *	KDB_DB_SSBPT	Single step over breakpoint
- *	KDB_DB_NOBPT	No existing kdb breakpoint matches this debug exception
- * Locking:
- *	None.
- * Remarks:
- *	Yup, there be goto's here.
- *
- *	If multiple processors receive debug exceptions simultaneously,
- *	one may be waiting at the kdb fence in kdb() while the user
- *	issues a 'bc' command to clear the breakpoint the processor
- *	which is waiting has already encountered.  If this is the case,
- *	the debug registers will no longer match any entry in the
- *	breakpoint table, and we'll return the value KDB_DB_NOBPT.
- *	This can cause a panic in die_if_kernel().  It is safer to
- *	disable the breakpoint (bd), go until all processors are past
- *	the breakpoint then clear the breakpoint (bc).  This code
- *	recognises a breakpoint even when disabled but not when it has
- *	been cleared.
- *
- *	WARNING: This routine clears the debug state.  It should be called
- *		 once per debug and the result cached.
- */
-
-kdb_dbtrap_t
-kdba_db_trap(struct pt_regs *regs, int error_unused)
-{
-	kdb_machreg_t dr6;
-	kdb_machreg_t dr7;
-	int rw, reg;
-	int i;
-	kdb_dbtrap_t rv = KDB_DB_BPT;
-	kdb_bp_t *bp;
-	int cpu = smp_processor_id();
-
-	if (KDB_NULL_REGS(regs))
-		return KDB_DB_NOBPT;
-
-	dr6 = kdba_getdr6();
-	dr7 = kdba_getdr7();
-
-	if (KDB_DEBUG(BP))
-		kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7);
-	if (dr6 & DR6_BS) {
-		if (KDB_STATE(SSBPT)) {
-			if (KDB_DEBUG(BP))
-				kdb_printf("ssbpt\n");
-			KDB_STATE_CLEAR(SSBPT);
-			for(i=0,bp=kdb_breakpoints;
-			    i < KDB_MAXBPT;
-			    i++, bp++) {
-				if (KDB_DEBUG(BP))
-					kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n",
-						   bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu);
-				if (!bp->bp_enabled)
-					continue;
-				if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
-					continue;
-				if (KDB_DEBUG(BP))
-					kdb_printf("bp for this cpu\n");
-				if (bp->bp_delayed) {
-					bp->bp_delayed = 0;
-					if (KDB_DEBUG(BP)){
-						/* Can't be hw breakpoint */
-						if (bp->bp_hardtype)
-							kdb_printf("kdb: Error - hw bp delayed\n");
-						kdb_printf("kdba_installbp\n");
-					}
-					kdba_installbp(regs, bp);
-					if (!KDB_STATE(DOING_SS)) {
-						regs->flags &= ~X86_EFLAGS_TF;
-						return(KDB_DB_SSBPT);
-					}
-					break;
-				}
-			}
-			if (i == KDB_MAXBPT) {
-				kdb_printf("kdb: Unable to find delayed breakpoint\n");
-			}
-			if (!KDB_STATE(DOING_SS)) {
-				regs->flags &= ~X86_EFLAGS_TF;
-				return(KDB_DB_NOBPT);
-			}
-			/* FALLTHROUGH */
-		}
-
-		/*
-		 * KDB_STATE_DOING_SS is set when the kernel debugger is using
-		 * the processor trap flag to single-step a processor.  If a
-		 * single step trap occurs and this flag is clear, the SS trap
-		 * will be ignored by KDB and the kernel will be allowed to deal
-		 * with it as necessary (e.g. for ptrace).
-		 */
-		if (!KDB_STATE(DOING_SS))
-			goto unknown;
-
-		/* single step */
-		rv = KDB_DB_SS;		/* Indicate single step */
-		if (KDB_STATE(DOING_SSB)) {
-			unsigned char instruction[2];
-
-			kdb_id1(regs->ip);
-			if (kdb_getarea(instruction, regs->ip) ||
-			    (instruction[0]&0xf0) == 0xe0 ||	/* short disp jumps */
-			    (instruction[0]&0xf0) == 0x70 ||	/* Misc. jumps */
-			    instruction[0]        == 0xc2 ||	/* ret */
-			    instruction[0]        == 0x9a ||	/* call */
-			    (instruction[0]&0xf8) == 0xc8 ||	/* enter, leave, iret, int, */
-			    ((instruction[0]      == 0x0f) &&
-			     ((instruction[1]&0xf0)== 0x80))
-			   ) {
-				/*
-				 * End the ssb command here.
-				 */
-				KDB_STATE_CLEAR(DOING_SSB);
-				KDB_STATE_CLEAR(DOING_SS);
-			} else {
-				rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */
-			}
-		} else {
-			/*
-			 * Print current insn
-			 */
-			kdb_printf("SS trap at ");
-			kdb_symbol_print(regs->ip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
-			kdb_id1(regs->ip);
-			KDB_STATE_CLEAR(DOING_SS);
-		}
-
-		if (rv != KDB_DB_SSB)
-			regs->flags &= ~X86_EFLAGS_TF;
-	}
-
-	if (dr6 & DR6_B0) {
-		rw = DR7_RW0(dr7);
-		reg = 0;
-		goto handle;
-	}
-
-	if (dr6 & DR6_B1) {
-		rw = DR7_RW1(dr7);
-		reg = 1;
-		goto handle;
-	}
-
-	if (dr6 & DR6_B2) {
-		rw = DR7_RW2(dr7);
-		reg = 2;
-		goto handle;
-	}
-
-	if (dr6 & DR6_B3) {
-		rw = DR7_RW3(dr7);
-		reg = 3;
-		goto handle;
-	}
-
-	if (rv > 0)
-		goto handled;
-
-	goto unknown;	/* dismiss */
-
-handle:
-	/*
-	 * Set Resume Flag
-	 */
-	regs->flags |= X86_EFLAGS_RF;
-
-	/*
-	 * Determine which breakpoint was encountered.
-	 */
-	for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
-		if (!(bp->bp_free)
-		 && (bp->bp_global || bp->bp_cpu == smp_processor_id())
-		 && (bp->bp_hard[cpu])
-		 && (bp->bp_hard[cpu]->bph_reg == reg)) {
-			/*
-			 * Hit this breakpoint.
-			 */
-			kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n",
-				  kdba_rwtypes[rw],
-				  i, bp->bp_addr);
-
-			/*
-			 * For an instruction breakpoint, disassemble
-			 * the current instruction.
-			 */
-			if (rw == 0) {
-				kdb_id1(regs->ip);
-			}
-
-			goto handled;
-		}
-	}
-
-unknown:
-	regs->flags |= X86_EFLAGS_RF;	/* Supress further faults */
-	rv = KDB_DB_NOBPT;	/* Cause kdb() to return */
-
-handled:
-
-	/*
-	 * Clear the pending exceptions.
-	 */
-	kdba_putdr6(0);
-
-	return rv;
-}
-
-/*
- * kdba_bp_trap
- *
- * 	Perform breakpoint processing upon entry to the
- *	processor breakpoint instruction fault.   Determine and print
- *	the active breakpoint.
- *
- * Parameters:
- *	regs	Exception frame containing machine register state
- *	error	Error number passed to kdb.
- * Outputs:
- *	None.
- * Returns:
- *	0	Standard instruction or data breakpoint encountered
- *	1	Single Step fault ('ss' command)
- *	2	Single Step fault, caller should continue ('ssb' command)
- *	3	No existing kdb breakpoint matches this debug exception
- * Locking:
- *	None.
- * Remarks:
- *
- * 	If multiple processors receive debug exceptions simultaneously,
- *	one may be waiting at the kdb fence in kdb() while the user
- *	issues a 'bc' command to clear the breakpoint the processor which
- * 	is waiting has already encountered.   If this is the case, the
- *	debug registers will no longer match any entry in the breakpoint
- *	table, and we'll return the value '3'.  This can cause a panic
- *	in die_if_kernel().  It is safer to disable the breakpoint (bd),
- *	'go' until all processors are past the breakpoint then clear the
- *	breakpoint (bc).  This code recognises a breakpoint even when
- *	disabled but not when it has been cleared.
- *
- *	WARNING: This routine resets the ip.  It should be called
- *		 once per breakpoint and the result cached.
- */
-
-kdb_dbtrap_t
-kdba_bp_trap(struct pt_regs *regs, int error_unused)
-{
-	int i;
-	kdb_dbtrap_t rv;
-	kdb_bp_t *bp;
-
-	if (KDB_NULL_REGS(regs))
-		return KDB_DB_NOBPT;
-
-	/*
-	 * Determine which breakpoint was encountered.
-	 */
-	if (KDB_DEBUG(BP))
-		kdb_printf("kdba_bp_trap: ip=0x%lx (not adjusted) "
-			   "flags=0x%lx ef=0x%p sp=0x%lx\n",
-			   regs->ip, regs->flags, regs, regs->sp);
-
-	rv = KDB_DB_NOBPT;	/* Cause kdb() to return */
-
-	for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
-		if (bp->bp_free)
-			continue;
-		if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
-			continue;
-		 if ((void *)bp->bp_addr == (void *)(regs->ip - bp->bp_adjust)) {
-			/* Hit this breakpoint.  */
-			regs->ip -= bp->bp_adjust;
-			kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n",
-				  i, regs->ip);
-			kdb_id1(regs->ip);
-			rv = KDB_DB_BPT;
-			bp->bp_delay = 1;
-			/* SSBPT is set when the kernel debugger must single
-			 * step a task in order to re-establish an instruction
-			 * breakpoint which uses the instruction replacement
-			 * mechanism.  It is cleared by any action that removes
-			 * the need to single-step the breakpoint.
-			 */
-			KDB_STATE_SET(SSBPT);
-			break;
-		}
-	}
-
-	return rv;
-}
-
-/*
- * kdba_handle_bp
- *
- *	Handle an instruction-breakpoint trap.  Called when re-installing
- *	an enabled breakpoint which has has the bp_delay bit set.
- *
- * Parameters:
- * Returns:
- * Locking:
- * Remarks:
- *
- * Ok, we really need to:
- *	1) Restore the original instruction byte
- *	2) Single Step
- *	3) Restore breakpoint instruction
- *	4) Continue.
- *
- *
- */
-
-static void
-kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
-{
-	if (KDB_NULL_REGS(regs))
-		return;
-
-	if (KDB_DEBUG(BP))
-		kdb_printf("regs->ip = 0x%lx\n", regs->ip);
-
-	/*
-	 * Setup single step
-	 */
-	kdba_setsinglestep(regs);
-
-	/*
-	 * Reset delay attribute
-	 */
-	bp->bp_delay = 0;
-	bp->bp_delayed = 1;
-}
-
-
-/*
- * kdba_bptype
- *
- *	Return a string describing type of breakpoint.
- *
- * Parameters:
- *	bph	Pointer to hardware breakpoint description
- * Outputs:
- *	None.
- * Returns:
- *	Character string.
- * Locking:
- *	None.
- * Remarks:
- */
-
-char *
-kdba_bptype(kdbhard_bp_t *bph)
-{
-	char *mode;
-
-	mode = kdba_rwtypes[bph->bph_mode];
-
-	return mode;
-}
-
-/*
- * kdba_printbpreg
- *
- *	Print register name assigned to breakpoint
- *
- * Parameters:
- *	bph	Pointer hardware breakpoint structure
- * Outputs:
- *	None.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- */
-
-static void
-kdba_printbpreg(kdbhard_bp_t *bph)
-{
-	kdb_printf(" in dr%ld", bph->bph_reg);
-}
-
-/*
- * kdba_printbp
- *
- *	Print string describing hardware breakpoint.
- *
- * Parameters:
- *	bph	Pointer to hardware breakpoint description
- * Outputs:
- *	None.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- */
-
-void
-kdba_printbp(kdb_bp_t *bp)
-{
-	int cpu;
-
-	kdb_printf("\n    is enabled");
-	if (bp->bp_hardtype) {
-		if (bp->bp_global)
-			cpu = smp_processor_id();
-		else
-			cpu = bp->bp_cpu;
-		kdba_printbpreg(bp->bp_hard[cpu]);
-		if (bp->bp_hard[cpu]->bph_mode != 0) {
-			kdb_printf(" for %d bytes",
-				   bp->bp_hard[cpu]->bph_length+1);
-		}
-	}
-}
-
-/*
- * kdba_parsebp
- *
- *	Parse architecture dependent portion of the
- *	breakpoint command.
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	Zero for success, a kdb diagnostic for failure
- * Locking:
- *	None.
- * Remarks:
- *	for Ia32 architure, data access, data write and
- *	I/O breakpoints are supported in addition to instruction
- * 	breakpoints.
- *
- *	{datar|dataw|io|inst} [length]
- */
-
-int
-kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
-{
-	int nextarg = *nextargp;
-	int diag;
-	kdbhard_bp_t *bph = &bp->bp_template;
-
-	bph->bph_mode = 0;		/* Default to instruction breakpoint */
-	bph->bph_length = 0;		/* Length must be zero for insn bp */
-	if ((argc + 1) != nextarg) {
-		if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
-			bph->bph_mode = 3;
-		} else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
-			bph->bph_mode = 1;
-		} else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
-			bph->bph_mode = 2;
-		} else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
-			bph->bph_mode = 0;
-		} else {
-			return KDB_ARGCOUNT;
-		}
-
-		bph->bph_length = 3;	/* Default to 4 byte */
-
-		nextarg++;
-
-		if ((argc + 1) != nextarg) {
-			unsigned long len;
-
-			diag = kdbgetularg((char *)argv[nextarg],
-					   &len);
-			if (diag)
-				return diag;
-
-
-			if ((len > 4) || (len == 3))
-				return KDB_BADLENGTH;
-
-			bph->bph_length = len;
-			bph->bph_length--; /* Normalize for debug register */
-			nextarg++;
-		}
-
-		if ((argc + 1) != nextarg)
-			return KDB_ARGCOUNT;
-
-		/*
-		 * Indicate to architecture independent level that
-		 * a hardware register assignment is required to enable
-		 * this breakpoint.
-		 */
-
-		bph->bph_free = 0;
-	} else {
-		if (KDB_DEBUG(BP))
-			kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
-		if (bp->bp_forcehw) {
-			/*
-			 * We are forced to use a hardware register for this
-			 * breakpoint because either the bph or bpha
-			 * commands were used to establish this breakpoint.
-			 */
-			bph->bph_free = 0;
-		} else {
-			/*
-			 * Indicate to architecture dependent level that
-			 * the instruction replacement breakpoint technique
-			 * should be used for this breakpoint.
-			 */
-			bph->bph_free = 1;
-			bp->bp_adjust = 1;	/* software, int 3 is one byte */
-		}
-	}
-
-	if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) {
-		kdb_printf("Invalid address for breakpoint, ignoring bp command\n");
-		return KDB_BADADDR;
-	}
-
-	*nextargp = nextarg;
-	return 0;
-}
-
-/*
- * kdba_allocbp
- *
- *	Allocate hw register for bp on specific CPU
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	A pointer to the allocated register kdbhard_bp_t structure for
- *	success, Null and a non-zero diagnostic for failure.
- * Locking:
- *	None.
- * Remarks:
- */
-
-static kdbhard_bp_t *
-kdba_allocbp(kdbhard_bp_t *bph, int *diagp, unsigned int cpu)
-{
-	int i;
-	kdbhard_bp_t *newbph;
-
-	for(i=0; i < KDB_MAXHARDBPT; i++) {
-		newbph=&(kdb_hardbreaks[cpu][i]);
-		if (newbph->bph_free) {
-			break;
-		}
-	}
-
-	if (i == KDB_MAXHARDBPT) {
-		*diagp = KDB_TOOMANYDBREGS;
-		return NULL;
-	}
-
-	*diagp = 0;
-
-	/*
-	 * Copy data from template.  Can't just copy the entire template
-	 * here because the register number in kdb_hardbreaks must be
-	 * preserved.
-	 */
-	newbph->bph_data = bph->bph_data;
-	newbph->bph_write = bph->bph_write;
-	newbph->bph_mode = bph->bph_mode;
-	newbph->bph_length = bph->bph_length;
-
-	/*
-	 * Mark entry allocated.
-	 */
-	newbph->bph_free = 0;
-
-	return newbph;
-}
-
-/*
- * kdba_alloc_hwbp
- *
- *	Associate a hardware registers with a breakpoint.
- *	If hw bp is global hw registers descriptor will be allocated
- *	on every CPU.
- *
- * Parameters:
- *	bp - hardware bp
- *	diagp - pointer to variable that will store error when
- *	function complete
- * Outputs:
- *	None.
- * Returns:
- *	None
- * Locking:
- *	None.
- * Remarks:
- *	Should be called with correct bp->bp_template
- */
-
-void
-kdba_alloc_hwbp(kdb_bp_t *bp, int *diagp)
-{
-	int i;
-
-	if (bp->bp_global){
-		for (i = 0; i < NR_CPUS; ++i) {
-			if (!cpu_online(i))
-				continue;
-			bp->bp_hard[i] = kdba_allocbp(&bp->bp_template, diagp, i);
-			if (*diagp)
-				break;
-		}
-	} else {
-		bp->bp_hard[bp->bp_cpu] = kdba_allocbp(&bp->bp_template, diagp, bp->bp_cpu);
-	}
-	bp->bp_hardtype = 1;
-}
-
-/*
- * kdba_freebp
- *
- *	Deallocate hw registers descriptor for bp on specific CPU
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	Zero for success, a kdb diagnostic for failure
- * Locking:
- *	None.
- * Remarks:
- */
-
-static void
-kdba_freebp(kdbhard_bp_t *bph)
-{
-	bph->bph_free = 1;
-}
-
-/*
- * kdba_free_hwbp
- *
- *	Frees allocated hw registers descriptors for bp.
- *	If hw bp is global, hw registers descriptors will be freed
- *	on every CPU.
- *
- * Parameters:
- *	bp - hardware bp
- * Outputs:
- *	None.
- * Returns:
- *	None
- * Locking:
- *	None.
- * Remarks:
- *	Should be called with correct bp->bp_template
- */
-
-void
-kdba_free_hwbp(kdb_bp_t *bp)
-{
-	int i;
-
-	/* When kernel enters KDB, first, all local bps
-	 * are removed, so here we don't need to clear
-	 * debug registers.
-	 */
-
-	if (bp->bp_global){
-		for (i = 0; i < NR_CPUS; ++i) {
-			if (!cpu_online(i))
-				continue;
-			if (bp->bp_hard[i])
-				kdba_freebp(bp->bp_hard[i]);
-			bp->bp_hard[i] = 0;
-		}
-	} else {
-		kdba_freebp(bp->bp_hard[bp->bp_cpu]);
-		bp->bp_hard[bp->bp_cpu] = NULL;
-	}
-	bp->bp_hardtype = 0;
-}
-
-/*
- * kdba_initbp
- *
- *	Initialize the breakpoint table for the hardware breakpoint
- *	register.
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	Zero for success, a kdb diagnostic for failure
- * Locking:
- *	None.
- * Remarks:
- *
- *	There is one entry per register.  On the ia32 architecture
- *	all the registers are interchangeable, so no special allocation
- *	criteria are required.
- */
-
-void
-kdba_initbp(void)
-{
-	int i,j;
-	kdbhard_bp_t *bph;
-
-	/*
-	 * Clear the hardware breakpoint table
-	 */
-
-	memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks));
-
-	for (i = 0; i < NR_CPUS; ++i) {
-		/* Called early so we don't know actual
-		 * ammount of CPUs
-		 */
-		for(j=0; j < KDB_MAXHARDBPT; j++) {
-			bph=&(kdb_hardbreaks[i][j]);
-			bph->bph_reg = j;
-			bph->bph_free = 1;
-		}
-	}
-}
-
-/*
- * kdba_installbp
- *
- *	Install a breakpoint
- *
- * Parameters:
- *	regs	Exception frame
- *	bp	Breakpoint structure for the breakpoint to be installed
- * Outputs:
- *	None.
- * Returns:
- *	0 if breakpoint installed.
- * Locking:
- *	None.
- * Remarks:
- *	For hardware breakpoints, a debug register is allocated
- *	and assigned to the breakpoint.  If no debug register is
- *	available, a warning message is printed and the breakpoint
- *	is disabled.
- *
- *	For instruction replacement breakpoints, we must single-step
- *	over the replaced instruction at this point so we can re-install
- *	the breakpoint instruction after the single-step.
- */
-
-int
-kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp)
-{
-	int cpu = smp_processor_id();
-
-	/*
-	 * Install the breakpoint, if it is not already installed.
-	 */
-
-	if (KDB_DEBUG(BP)) {
-		kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed);
-	}
-	if (!KDB_STATE(SSBPT))
-		bp->bp_delay = 0;
-
-	if (bp->bp_hardtype) {
-		if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){
-			kdb_printf("kdba_removebp: cpu != bp->bp_cpu for local hw bp\n");
-		}
-
-		if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){
-			kdb_printf("kdba_removebp: Error - bp_hard[smp_processor_id()] is emply\n");
-			return 1;
-		}
-
-		if (!bp->bp_hard[cpu]->bph_installed){
-			kdba_installdbreg(bp);
-			bp->bp_hard[cpu]->bph_installed = 1;
-			if (KDB_DEBUG(BP)) {
-				kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
-				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
-			}
-		}
-	} else if (!bp->bp_installed) {
-		if (bp->bp_delay) {
-			if (KDB_DEBUG(BP))
-				kdb_printf("kdba_installbp delayed bp\n");
-			kdba_handle_bp(regs, bp);
-		} else {
-			if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) ||
-			    kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) {
-				kdb_printf("kdba_installbp failed to set software breakpoint at " kdb_bfd_vma_fmt "\n", bp->bp_addr);
-				return(1);
-			}
-			bp->bp_installed = 1;
-			if (KDB_DEBUG(BP))
-				kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n",
-					   IA32_BREAKPOINT_INSTRUCTION, bp->bp_addr);
-		}
-	}
-	return(0);
-}
-
-/*
- * kdba_removebp
- *
- *	Make a breakpoint ineffective.
- *
- * Parameters:
- *	None.
- * Outputs:
- *	None.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- */
-
-int
-kdba_removebp(kdb_bp_t *bp)
-{
-	int cpu = smp_processor_id();
-
-	/*
-	 * For hardware breakpoints, remove it from the active register,
-	 * for software breakpoints, restore the instruction stream.
-	 */
-	if (KDB_DEBUG(BP)) {
-		kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed);
-	}
-
-	if (bp->bp_hardtype) {
-		if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){
-			kdb_printf("kdba_removebp: cpu != bp->bp_cpu for local hw bp\n");
-		}
-
-		if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){
-			kdb_printf("kdba_removebp: Error - bp_hard[smp_processor_id()] is emply\n");
-			return 1;
-		}
-
-		if (KDB_DEBUG(BP)) {
-			kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n",
-				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
-		}
-
-		if (bp->bp_hard[cpu]->bph_installed){
-			if (KDB_DEBUG(BP)) {
-				kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
-				   bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
-			}
-			kdba_removedbreg(bp);
-			bp->bp_hard[cpu]->bph_installed = 0;
-		}
-	} else if (bp->bp_installed) {
-		if (KDB_DEBUG(BP))
-			kdb_printf("kdb: restoring instruction 0x%x at " kdb_bfd_vma_fmt "\n",
-				   bp->bp_inst, bp->bp_addr);
-		if (kdb_putword(bp->bp_addr, bp->bp_inst, 1))
-			return(1);
-		bp->bp_installed = 0;
-	}
-	return(0);
-}
Index: xfs-dev/arch/x86/kdb/kdbasupport_32.c
===================================================================
--- xfs-dev.orig/arch/x86/kdb/kdbasupport_32.c	2008-12-23 09:30:36.628197882 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,1086 +0,0 @@
-/*
- * Kernel Debugger Architecture Independent Support Functions
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1999-2008 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/string.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/ptrace.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/hardirq.h>
-#include <linux/kdb.h>
-#include <linux/kdbprivate.h>
-
-#include <asm/processor.h>
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/desc.h>
-
-static kdb_machreg_t
-kdba_getcr(int regnum)
-{
-	kdb_machreg_t contents = 0;
-	switch(regnum) {
-	case 0:
-		__asm__ ("movl %%cr0,%0\n\t":"=r"(contents));
-		break;
-	case 1:
-		break;
-	case 2:
-		__asm__ ("movl %%cr2,%0\n\t":"=r"(contents));
-		break;
-	case 3:
-		__asm__ ("movl %%cr3,%0\n\t":"=r"(contents));
-		break;
-	case 4:
-		__asm__ ("movl %%cr4,%0\n\t":"=r"(contents));
-		break;
-	default:
-		break;
-	}
-
-	return contents;
-}
-
-static void
-kdba_putdr(int regnum, kdb_machreg_t contents)
-{
-	switch(regnum) {
-	case 0:
-		__asm__ ("movl %0,%%db0\n\t"::"r"(contents));
-		break;
-	case 1:
-		__asm__ ("movl %0,%%db1\n\t"::"r"(contents));
-		break;
-	case 2:
-		__asm__ ("movl %0,%%db2\n\t"::"r"(contents));
-		break;
-	case 3:
-		__asm__ ("movl %0,%%db3\n\t"::"r"(contents));
-		break;
-	case 4:
-	case 5:
-		break;
-	case 6:
-		__asm__ ("movl %0,%%db6\n\t"::"r"(contents));
-		break;
-	case 7:
-		__asm__ ("movl %0,%%db7\n\t"::"r"(contents));
-		break;
-	default:
-		break;
-	}
-}
-
-kdb_machreg_t
-kdba_getdr(int regnum)
-{
-	kdb_machreg_t contents = 0;
-	switch(regnum) {
-	case 0:
-		__asm__ ("movl %%db0,%0\n\t":"=r"(contents));
-		break;
-	case 1:
-		__asm__ ("movl %%db1,%0\n\t":"=r"(contents));
-		break;
-	case 2:
-		__asm__ ("movl %%db2,%0\n\t":"=r"(contents));
-		break;
-	case 3:
-		__asm__ ("movl %%db3,%0\n\t":"=r"(contents));
-		break;
-	case 4:
-	case 5:
-		break;
-	case 6:
-		__asm__ ("movl %%db6,%0\n\t":"=r"(contents));
-		break;
-	case 7:
-		__asm__ ("movl %%db7,%0\n\t":"=r"(contents));
-		break;
-	default:
-		break;
-	}
-
-	return contents;
-}
-
-kdb_machreg_t
-kdba_getdr6(void)
-{
-	return kdba_getdr(6);
-}
-
-kdb_machreg_t
-kdba_getdr7(void)
-{
-	return kdba_getdr(7);
-}
-
-void
-kdba_putdr6(kdb_machreg_t contents)
-{
-	kdba_putdr(6, contents);
-}
-
-static void
-kdba_putdr7(kdb_machreg_t contents)
-{
-	kdba_putdr(7, contents);
-}
-
-void
-kdba_installdbreg(kdb_bp_t *bp)
-{
-	int cpu = smp_processor_id();
-
-	kdb_machreg_t dr7;
-
-	dr7 = kdba_getdr7();
-
-	kdba_putdr(bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
-
-	dr7 |= DR7_GE;
-	if (cpu_has_de)
-		set_in_cr4(X86_CR4_DE);
-
-	switch (bp->bp_hard[cpu]->bph_reg){
-	case 0:
-		DR7_RW0SET(dr7,bp->bp_hard[cpu]->bph_mode);
-		DR7_LEN0SET(dr7,bp->bp_hard[cpu]->bph_length);
-		DR7_G0SET(dr7);
-		break;
-	case 1:
-		DR7_RW1SET(dr7,bp->bp_hard[cpu]->bph_mode);
-		DR7_LEN1SET(dr7,bp->bp_hard[cpu]->bph_length);
-		DR7_G1SET(dr7);
-		break;
-	case 2:
-		DR7_RW2SET(dr7,bp->bp_hard[cpu]->bph_mode);
-		DR7_LEN2SET(dr7,bp->bp_hard[cpu]->bph_length);
-		DR7_G2SET(dr7);
-		break;
-	case 3:
-		DR7_RW3SET(dr7,bp->bp_hard[cpu]->bph_mode);
-		DR7_LEN3SET(dr7,bp->bp_hard[cpu]->bph_length);
-		DR7_G3SET(dr7);
-		break;
-	default:
-		kdb_printf("kdb: Bad debug register!! %ld\n",
-			   bp->bp_hard[cpu]->bph_reg);
-		break;
-	}
-
-	kdba_putdr7(dr7);
-	return;
-}
-
-void
-kdba_removedbreg(kdb_bp_t *bp)
-{
-	int regnum;
-	kdb_machreg_t dr7;
-	int cpu = smp_processor_id();
-
-	if (!bp->bp_hard[cpu])
-		return;
-
-	regnum = bp->bp_hard[cpu]->bph_reg;
-
-	dr7 = kdba_getdr7();
-
-	kdba_putdr(regnum, 0);
-
-	switch (regnum) {
-	case 0:
-		DR7_G0CLR(dr7);
-		DR7_L0CLR(dr7);
-		break;
-	case 1:
-		DR7_G1CLR(dr7);
-		DR7_L1CLR(dr7);
-		break;
-	case 2:
-		DR7_G2CLR(dr7);
-		DR7_L2CLR(dr7);
-		break;
-	case 3:
-		DR7_G3CLR(dr7);
-		DR7_L3CLR(dr7);
-		break;
-	default:
-		kdb_printf("kdb: Bad debug register!! %d\n", regnum);
-		break;
-	}
-
-	kdba_putdr7(dr7);
-}
-
-
-/*
- * kdba_getregcontents
- *
- *	Return the contents of the register specified by the
- *	input string argument.   Return an error if the string
- *	does not match a machine register.
- *
- *	The following pseudo register names are supported:
- *	   &regs	 - Prints address of exception frame
- *	   kesp		 - Prints kernel stack pointer at time of fault
- *	   cesp		 - Prints current kernel stack pointer, inside kdb
- *	   ceflags	 - Prints current flags, inside kdb
- *	   %<regname>	 - Uses the value of the registers at the
- *			   last time the user process entered kernel
- *			   mode, instead of the registers at the time
- *			   kdb was entered.
- *
- * Parameters:
- *	regname		Pointer to string naming register
- *	regs		Pointer to structure containing registers.
- * Outputs:
- *	*contents	Pointer to unsigned long to recieve register contents
- * Returns:
- *	0		Success
- *	KDB_BADREG	Invalid register name
- * Locking:
- * 	None.
- * Remarks:
- * 	If kdb was entered via an interrupt from the kernel itself then
- *	ss and sp are *not* on the stack.
- */
-
-static struct kdbregs {
-	char   *reg_name;
-	size_t	reg_offset;
-} kdbreglist[] = {
-	{ "ax",		offsetof(struct pt_regs, ax) },
-	{ "bx",		offsetof(struct pt_regs, bx) },
-	{ "cx",		offsetof(struct pt_regs, cx) },
-	{ "dx",		offsetof(struct pt_regs, dx) },
-
-	{ "si",		offsetof(struct pt_regs, si) },
-	{ "di",		offsetof(struct pt_regs, di) },
-	{ "sp",		offsetof(struct pt_regs, sp) },
-	{ "ip",		offsetof(struct pt_regs, ip) },
-
-	{ "bp",		offsetof(struct pt_regs, bp) },
-	{ "ss", 	offsetof(struct pt_regs, ss) },
-	{ "cs",		offsetof(struct pt_regs, cs) },
-	{ "flags", 	offsetof(struct pt_regs, flags) },
-
-	{ "ds", 	offsetof(struct pt_regs, ds) },
-	{ "es", 	offsetof(struct pt_regs, es) },
-	{ "origax",	offsetof(struct pt_regs, orig_ax) },
-
-};
-
-static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
-
-static struct kdbregs dbreglist[] = {
-	{ "dr0", 	0 },
-	{ "dr1", 	1 },
-	{ "dr2",	2 },
-	{ "dr3", 	3 },
-	{ "dr6", 	6 },
-	{ "dr7",	7 },
-};
-
-static const int ndbreglist = sizeof(dbreglist) / sizeof(struct kdbregs);
-
-int
-kdba_getregcontents(const char *regname,
-		    struct pt_regs *regs,
-		    kdb_machreg_t *contents)
-{
-	int i;
-
-	if (strcmp(regname, "cesp") == 0) {
-		asm volatile("movl %%esp,%0":"=m" (*contents));
-		return 0;
-	}
-
-	if (strcmp(regname, "ceflags") == 0) {
-		unsigned long flags;
-		local_save_flags(flags);
-		*contents = flags;
-		return 0;
-	}
-
-	if (regname[0] == '%') {
-		/* User registers:  %%e[a-c]x, etc */
-		regname++;
-		regs = (struct pt_regs *)
-			(kdb_current_task->thread.sp0 - sizeof(struct pt_regs));
-	}
-
-	for (i=0; i<ndbreglist; i++) {
-		if (strnicmp(dbreglist[i].reg_name,
-			     regname,
-			     strlen(regname)) == 0)
-			break;
-	}
-
-	if ((i < ndbreglist)
-	 && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
-		*contents = kdba_getdr(dbreglist[i].reg_offset);
-		return 0;
-	}
-
-	if (!regs) {
-		kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
-		return KDB_BADREG;
-	}
-
-	if (strcmp(regname, "&regs") == 0) {
-		*contents = (unsigned long)regs;
-		return 0;
-	}
-
-	if (strcmp(regname, "kesp") == 0) {
-		*contents = (unsigned long)regs + sizeof(struct pt_regs);
-		if ((regs->cs & 0xffff) == __KERNEL_CS) {
-			/* sp and ss are not on stack */
-			*contents -= 2*4;
-		}
-		return 0;
-	}
-
-	for (i=0; i<nkdbreglist; i++) {
-		if (strnicmp(kdbreglist[i].reg_name,
-			     regname,
-			     strlen(regname)) == 0)
-			break;
-	}
-
-	if ((i < nkdbreglist)
-	 && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
-		if ((regs->cs & 0xffff) == __KERNEL_CS) {
-			/* No cpl switch, sp and ss are not on stack */
-			if (strcmp(kdbreglist[i].reg_name, "sp") == 0) {
-				*contents = (kdb_machreg_t)regs +
-					sizeof(struct pt_regs) - 2*4;
-				return(0);
-			}
-			if (strcmp(kdbreglist[i].reg_name, "xss") == 0) {
-				asm volatile(
-					"pushl %%ss\n"
-					"popl %0\n"
-					:"=m" (*contents));
-				return(0);
-			}
-		}
-		*contents = *(unsigned long *)((unsigned long)regs +
-				kdbreglist[i].reg_offset);
-		return(0);
-	}
-
-	return KDB_BADREG;
-}
-
-/*
- * kdba_setregcontents
- *
- *	Set the contents of the register specified by the
- *	input string argument.   Return an error if the string
- *	does not match a machine register.
- *
- *	Supports modification of user-mode registers via
- *	%<register-name>
- *
- * Parameters:
- *	regname		Pointer to string naming register
- *	regs		Pointer to structure containing registers.
- *	contents	Unsigned long containing new register contents
- * Outputs:
- * Returns:
- *	0		Success
- *	KDB_BADREG	Invalid register name
- * Locking:
- * 	None.
- * Remarks:
- */
-
-int
-kdba_setregcontents(const char *regname,
-		  struct pt_regs *regs,
-		  unsigned long contents)
-{
-	int i;
-
-	if (regname[0] == '%') {
-		regname++;
-		regs = (struct pt_regs *)
-			(kdb_current_task->thread.sp0 - sizeof(struct pt_regs));
-	}
-
-	for (i=0; i<ndbreglist; i++) {
-		if (strnicmp(dbreglist[i].reg_name,
-			     regname,
-			     strlen(regname)) == 0)
-			break;
-	}
-
-	if ((i < ndbreglist)
-	 && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
-		kdba_putdr(dbreglist[i].reg_offset, contents);
-		return 0;
-	}
-
-	if (!regs) {
-		kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
-		return KDB_BADREG;
-	}
-
-	for (i=0; i<nkdbreglist; i++) {
-		if (strnicmp(kdbreglist[i].reg_name,
-			     regname,
-			     strlen(regname)) == 0)
-			break;
-	}
-
-	if ((i < nkdbreglist)
-	 && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
-		*(unsigned long *)((unsigned long)regs
-				   + kdbreglist[i].reg_offset) = contents;
-		return 0;
-	}
-
-	return KDB_BADREG;
-}
-
-/*
- * kdba_dumpregs
- *
- *	Dump the specified register set to the display.
- *
- * Parameters:
- *	regs		Pointer to structure containing registers.
- *	type		Character string identifying register set to dump
- *	extra		string further identifying register (optional)
- * Outputs:
- * Returns:
- *	0		Success
- * Locking:
- * 	None.
- * Remarks:
- *	This function will dump the general register set if the type
- *	argument is NULL (struct pt_regs).   The alternate register
- *	set types supported by this function:
- *
- *	d		Debug registers
- *	c		Control registers
- *	u		User registers at most recent entry to kernel
- *			for the process currently selected with "pid" command.
- * Following not yet implemented:
- *	r		Memory Type Range Registers (extra defines register)
- *
- * MSR on i386/x86_64 are handled by rdmsr/wrmsr commands.
- */
-
-int
-kdba_dumpregs(struct pt_regs *regs,
-	    const char *type,
-	    const char *extra)
-{
-	int i;
-	int count = 0;
-
-	if (type
-	 && (type[0] == 'u')) {
-		type = NULL;
-		regs = (struct pt_regs *)
-			(kdb_current_task->thread.sp0 - sizeof(struct pt_regs));
-	}
-
-	if (type == NULL) {
-		struct kdbregs *rlp;
-		kdb_machreg_t contents;
-
-		if (!regs) {
-			kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
-			return KDB_BADREG;
-		}
-
-		for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) {
-			kdb_printf("%s = ", rlp->reg_name);
-			kdba_getregcontents(rlp->reg_name, regs, &contents);
-			kdb_printf("0x%08lx ", contents);
-			if ((++count % 4) == 0)
-				kdb_printf("\n");
-		}
-
-		kdb_printf("&regs = 0x%p\n", regs);
-
-		return 0;
-	}
-
-	switch (type[0]) {
-	case 'd':
-	{
-		unsigned long dr[8];
-
-		for(i=0; i<8; i++) {
-			if ((i == 4) || (i == 5)) continue;
-			dr[i] = kdba_getdr(i);
-		}
-		kdb_printf("dr0 = 0x%08lx  dr1 = 0x%08lx  dr2 = 0x%08lx  dr3 = 0x%08lx\n",
-			   dr[0], dr[1], dr[2], dr[3]);
-		kdb_printf("dr6 = 0x%08lx  dr7 = 0x%08lx\n",
-			   dr[6], dr[7]);
-		return 0;
-	}
-	case 'c':
-	{
-		unsigned long cr[5];
-
-		for (i=0; i<5; i++) {
-			cr[i] = kdba_getcr(i);
-		}
-		kdb_printf("cr0 = 0x%08lx  cr1 = 0x%08lx  cr2 = 0x%08lx  cr3 = 0x%08lx\ncr4 = 0x%08lx\n",
-			   cr[0], cr[1], cr[2], cr[3], cr[4]);
-		return 0;
-	}
-	case 'r':
-		break;
-	default:
-		return KDB_BADREG;
-	}
-
-	/* NOTREACHED */
-	return 0;
-}
-EXPORT_SYMBOL(kdba_dumpregs);
-
-kdb_machreg_t
-kdba_getpc(struct pt_regs *regs)
-{
-	return regs ? regs->ip : 0;
-}
-
-int
-kdba_setpc(struct pt_regs *regs, kdb_machreg_t newpc)
-{
-	if (KDB_NULL_REGS(regs))
-		return KDB_BADREG;
-	regs->ip = newpc;
-	KDB_STATE_SET(IP_ADJUSTED);
-	return 0;
-}
-
-/*
- * kdba_main_loop
- *
- *	Do any architecture specific set up before entering the main kdb loop.
- *	The primary function of this routine is to make all processes look the
- *	same to kdb, kdb must be able to list a process without worrying if the
- *	process is running or blocked, so make all process look as though they
- *	are blocked.
- *
- * Inputs:
- *	reason		The reason KDB was invoked
- *	error		The hardware-defined error code
- *	error2		kdb's current reason code.  Initially error but can change
- *			acording to kdb state.
- *	db_result	Result from break or debug point.
- *	regs		The exception frame at time of fault/breakpoint.  If reason
- *			is SILENT or CPU_UP then regs is NULL, otherwise it should
- *			always be valid.
- * Returns:
- *	0	KDB was invoked for an event which it wasn't responsible
- *	1	KDB handled the event for which it was invoked.
- * Outputs:
- *	Sets ip and sp in current->thread.
- * Locking:
- *	None.
- * Remarks:
- *	none.
- */
-
-int
-kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
-	       kdb_dbtrap_t db_result, struct pt_regs *regs)
-{
-	int ret;
-	ret = kdb_save_running(regs, reason, reason2, error, db_result);
-	kdb_unsave_running(regs);
-	return ret;
-}
-
-void
-kdba_disableint(kdb_intstate_t *state)
-{
-	unsigned long *fp = (unsigned long *)state;
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	*fp = flags;
-}
-
-void
-kdba_restoreint(kdb_intstate_t *state)
-{
-	unsigned long flags = *(int *)state;
-	local_irq_restore(flags);
-}
-
-void
-kdba_setsinglestep(struct pt_regs *regs)
-{
-	if (KDB_NULL_REGS(regs))
-		return;
-	if (regs->flags & EF_IE)
-		KDB_STATE_SET(A_IF);
-	else
-		KDB_STATE_CLEAR(A_IF);
-	regs->flags = (regs->flags | EF_TF) & ~EF_IE;
-}
-
-void
-kdba_clearsinglestep(struct pt_regs *regs)
-{
-	if (KDB_NULL_REGS(regs))
-		return;
-	if (KDB_STATE(A_IF))
-		regs->flags |= EF_IE;
-	else
-		regs->flags &= ~EF_IE;
-}
-
-int asmlinkage
-kdba_setjmp(kdb_jmp_buf *jb)
-{
-#if defined(CONFIG_FRAME_POINTER)
-	__asm__ ("movl 8(%esp), %eax\n\t"
-		 "movl %ebx, 0(%eax)\n\t"
-		 "movl %esi, 4(%eax)\n\t"
-		 "movl %edi, 8(%eax)\n\t"
-		 "movl (%esp), %ecx\n\t"
-		 "movl %ecx, 12(%eax)\n\t"
-		 "leal 8(%esp), %ecx\n\t"
-		 "movl %ecx, 16(%eax)\n\t"
-		 "movl 4(%esp), %ecx\n\t"
-		 "movl %ecx, 20(%eax)\n\t");
-#else	 /* CONFIG_FRAME_POINTER */
-	__asm__ ("movl 4(%esp), %eax\n\t"
-		 "movl %ebx, 0(%eax)\n\t"
-		 "movl %esi, 4(%eax)\n\t"
-		 "movl %edi, 8(%eax)\n\t"
-		 "movl %ebp, 12(%eax)\n\t"
-		 "leal 4(%esp), %ecx\n\t"
-		 "movl %ecx, 16(%eax)\n\t"
-		 "movl 0(%esp), %ecx\n\t"
-		 "movl %ecx, 20(%eax)\n\t");
-#endif   /* CONFIG_FRAME_POINTER */
-	return 0;
-}
-
-void asmlinkage
-kdba_longjmp(kdb_jmp_buf *jb, int reason)
-{
-#if defined(CONFIG_FRAME_POINTER)
-	__asm__("movl 8(%esp), %ecx\n\t"
-		"movl 12(%esp), %eax\n\t"
-		"movl 20(%ecx), %edx\n\t"
-		"movl 0(%ecx), %ebx\n\t"
-		"movl 4(%ecx), %esi\n\t"
-		"movl 8(%ecx), %edi\n\t"
-		"movl 12(%ecx), %ebp\n\t"
-		"movl 16(%ecx), %esp\n\t"
-		"jmp *%edx\n");
-#else    /* CONFIG_FRAME_POINTER */
-	__asm__("movl 4(%esp), %ecx\n\t"
-		"movl 8(%esp), %eax\n\t"
-		"movl 20(%ecx), %edx\n\t"
-		"movl 0(%ecx), %ebx\n\t"
-		"movl 4(%ecx), %esi\n\t"
-		"movl 8(%ecx), %edi\n\t"
-		"movl 12(%ecx), %ebp\n\t"
-		"movl 16(%ecx), %esp\n\t"
-		"jmp *%edx\n");
-#endif	 /* CONFIG_FRAME_POINTER */
-}
-
-/*
- * kdba_pt_regs
- *
- *	Format a struct pt_regs
- *
- * Inputs:
- *	argc	argument count
- *	argv	argument vector
- * Outputs:
- *	None.
- * Returns:
- *	zero for success, a kdb diagnostic if error
- * Locking:
- *	none.
- * Remarks:
- *	If no address is supplied, it uses the last irq pt_regs.
- */
-
-static int
-kdba_pt_regs(int argc, const char **argv)
-{
-	int diag;
-	kdb_machreg_t addr;
-	long offset = 0;
-	int nextarg;
-	struct pt_regs *p;
-	static const char *fmt = "  %-11.11s 0x%lx\n";
-
-	if (argc == 0) {
-		addr = (kdb_machreg_t) get_irq_regs();
-	} else if (argc == 1) {
-		nextarg = 1;
-		diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL);
-		if (diag)
-			return diag;
-	} else {
-		return KDB_ARGCOUNT;
-	}
-
-	p = (struct pt_regs *) addr;
-	kdb_printf("struct pt_regs 0x%p-0x%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
-	kdb_print_nameval("bx", p->bx);
-	kdb_print_nameval("cx", p->cx);
-	kdb_print_nameval("dx", p->dx);
-	kdb_print_nameval("si", p->si);
-	kdb_print_nameval("di", p->di);
-	kdb_print_nameval("bp", p->bp);
-	kdb_print_nameval("ax", p->ax);
-	kdb_printf(fmt, "ds", p->ds);
-	kdb_printf(fmt, "es", p->es);
-	kdb_print_nameval("orig_ax", p->orig_ax);
-	kdb_print_nameval("ip", p->ip);
-	kdb_printf(fmt, "cs", p->cs);
-	kdb_printf(fmt, "flags", p->flags);
-	kdb_printf(fmt, "sp", p->sp);
-	kdb_printf(fmt, "ss", p->ss);
-	return 0;
-}
-
-/*
- * kdba_stackdepth
- *
- *	Print processes that are using more than a specific percentage of their
- *	stack.
- *
- * Inputs:
- *	argc	argument count
- *	argv	argument vector
- * Outputs:
- *	None.
- * Returns:
- *	zero for success, a kdb diagnostic if error
- * Locking:
- *	none.
- * Remarks:
- *	If no percentage is supplied, it uses 60.
- */
-
-static void
-kdba_stackdepth1(struct task_struct *p, unsigned long sp)
-{
-	struct thread_info *tinfo;
-	int used;
-	const char *type;
-	kdb_ps1(p);
-	do {
-		tinfo = (struct thread_info *)(sp & -THREAD_SIZE);
-		used = sizeof(*tinfo) + THREAD_SIZE - (sp & (THREAD_SIZE-1));
-		type = NULL;
-		if (kdb_task_has_cpu(p)) {
-			struct kdb_activation_record ar;
-			memset(&ar, 0, sizeof(ar));
-			kdba_get_stack_info_alternate(sp, -1, &ar);
-			type = ar.stack.id;
-		}
-		if (!type)
-			type = "process";
-		kdb_printf("  %s stack %p sp %lx used %d\n", type, tinfo, sp, used);
-		sp = tinfo->previous_esp;
-	} while (sp);
-}
-
-static int
-kdba_stackdepth(int argc, const char **argv)
-{
-	int diag, cpu, threshold, used, over;
-	unsigned long percentage;
-	unsigned long esp;
-	long offset = 0;
-	int nextarg;
-	struct task_struct *p, *g;
-	struct kdb_running_process *krp;
-	struct thread_info *tinfo;
-
-	if (argc == 0) {
-		percentage = 60;
-	} else if (argc == 1) {
-		nextarg = 1;
-		diag = kdbgetaddrarg(argc, argv, &nextarg, &percentage, &offset, NULL);
-		if (diag)
-			return diag;
-	} else {
-		return KDB_ARGCOUNT;
-	}
-	percentage = max_t(int, percentage, 1);
-	percentage = min_t(int, percentage, 100);
-	threshold = ((2 * THREAD_SIZE * percentage) / 100 + 1) >> 1;
-	kdb_printf("stackdepth: processes using more than %ld%% (%d bytes) of stack\n",
-		percentage, threshold);
-
-	/* Run the active tasks first, they can have multiple stacks */
-	for (cpu = 0, krp = kdb_running_process; cpu < NR_CPUS; ++cpu, ++krp) {
-		if (!cpu_online(cpu))
-			continue;
-		p = krp->p;
-		esp = krp->arch.sp;
-		over = 0;
-		do {
-			tinfo = (struct thread_info *)(esp & -THREAD_SIZE);
-			used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1));
-			if (used >= threshold)
-				over = 1;
-			esp = tinfo->previous_esp;
-		} while (esp);
-		if (over)
-			kdba_stackdepth1(p, krp->arch.sp);
-	}
-	/* Now the tasks that are not on cpus */
-	kdb_do_each_thread(g, p) {
-		if (kdb_task_has_cpu(p))
-			continue;
-		esp = p->thread.sp;
-		used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1));
-		over = used >= threshold;
-		if (over)
-			kdba_stackdepth1(p, esp);
-	} kdb_while_each_thread(g, p);
-
-	return 0;
-}
-
-asmlinkage int kdb_call(void);
-
-/* Executed once on each cpu at startup. */
-void
-kdba_cpu_up(void)
-{
-}
-
-static int __init
-kdba_arch_init(void)
-{
-	set_intr_gate(KDBENTER_VECTOR, kdb_call);
-	return 0;
-}
-
-arch_initcall(kdba_arch_init);
-
-/*
- * kdba_init
- *
- * 	Architecture specific initialization.
- *
- * Parameters:
- *	None.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- *	None.
- */
-
-void __init
-kdba_init(void)
-{
-	kdba_arch_init();	/* Need to register KDBENTER_VECTOR early */
-	kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0);
-	kdb_register("stackdepth", kdba_stackdepth, "[percentage]", "Print processes using >= stack percentage", 0);
-
-	return;
-}
-
-/*
- * kdba_adjust_ip
- *
- * 	Architecture specific adjustment of instruction pointer before leaving
- *	kdb.
- *
- * Parameters:
- *	reason		The reason KDB was invoked
- *	error		The hardware-defined error code
- *	regs		The exception frame at time of fault/breakpoint.  If reason
- *			is SILENT or CPU_UP then regs is NULL, otherwise it should
- *			always be valid.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- *	noop on ix86.
- */
-
-void
-kdba_adjust_ip(kdb_reason_t reason, int error, struct pt_regs *regs)
-{
-	return;
-}
-
-void
-kdba_set_current_task(const struct task_struct *p)
-{
-	kdb_current_task = p;
-	if (kdb_task_has_cpu(p)) {
-		struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p);
-		kdb_current_regs = krp->regs;
-		return;
-	}
-	kdb_current_regs = NULL;
-}
-
-/*
- * asm-i386 uaccess.h supplies __copy_to_user which relies on MMU to
- * trap invalid addresses in the _xxx fields.  Verify the other address
- * of the pair is valid by accessing the first and last byte ourselves,
- * then any access violations should only be caused by the _xxx
- * addresses,
- */
-
-int
-kdba_putarea_size(unsigned long to_xxx, void *from, size_t size)
-{
-	mm_segment_t oldfs = get_fs();
-	int r;
-	char c;
-	c = *((volatile char *)from);
-	c = *((volatile char *)from + size - 1);
-
-	if (to_xxx < PAGE_OFFSET) {
-		return kdb_putuserarea_size(to_xxx, from, size);
-	}
-
-	set_fs(KERNEL_DS);
-	r = __copy_to_user_inatomic((void __user *)to_xxx, from, size);
-	set_fs(oldfs);
-	return r;
-}
-
-int
-kdba_getarea_size(void *to, unsigned long from_xxx, size_t size)
-{
-	mm_segment_t oldfs = get_fs();
-	int r;
-	*((volatile char *)to) = '\0';
-	*((volatile char *)to + size - 1) = '\0';
-
-	if (from_xxx < PAGE_OFFSET) {
-		return kdb_getuserarea_size(to, from_xxx, size);
-	}
-
-	set_fs(KERNEL_DS);
-	switch (size) {
-	case 1:
-		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 1);
-		break;
-	case 2:
-		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 2);
-		break;
-	case 4:
-		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 4);
-		break;
-	case 8:
-		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 8);
-		break;
-	default:
-		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, size);
-		break;
-	}
-	set_fs(oldfs);
-	return r;
-}
-
-int
-kdba_verify_rw(unsigned long addr, size_t size)
-{
-	unsigned char data[size];
-	return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size));
-}
-
-#ifdef	CONFIG_SMP
-
-#include <mach_ipi.h>
-
-gate_desc save_idt[NR_VECTORS];
-
-void kdba_takeover_vector(int vector)
-{
-	memcpy(&save_idt[vector], &idt_table[vector], sizeof(gate_desc));
-	set_intr_gate(KDB_VECTOR, kdb_interrupt);
-	return;
-}
-
-void kdba_giveback_vector(int vector)
-{
-	native_write_idt_entry(idt_table, vector, &save_idt[vector]);
-	return;
-}
-
-/* When first entering KDB, try a normal IPI.  That reduces backtrace problems
- * on the other cpus.
- */
-void
-smp_kdb_stop(void)
-{
-	if (!KDB_FLAG(NOIPI)) {
-		kdba_takeover_vector(KDB_VECTOR);
-		send_IPI_allbutself(KDB_VECTOR);
-	}
-}
-
-/* The normal KDB IPI handler */
-void
-smp_kdb_interrupt(struct pt_regs *regs)
-{
-	struct pt_regs *old_regs = set_irq_regs(regs);
-	ack_APIC_irq();
-	irq_enter();
-	kdb_ipi(regs, NULL);
-	irq_exit();
-	set_irq_regs(old_regs);
-}
-
-/* Invoked once from kdb_wait_for_cpus when waiting for cpus.  For those cpus
- * that have not responded to the normal KDB interrupt yet, hit them with an
- * NMI event.
- */
-void
-kdba_wait_for_cpus(void)
-{
-	int c;
-	if (KDB_FLAG(CATASTROPHIC))
-		return;
-	kdb_printf("  Sending NMI to non-responding cpu(s): ");
-	for_each_online_cpu(c) {
-		if (kdb_running_process[c].seqno < kdb_seqno - 1) {
-			kdb_printf(" %d", c);
-			send_IPI_mask(cpumask_of_cpu(c), NMI_VECTOR);
-		}
-	}
-	kdb_printf(".\n");
-}
-
-#endif	/* CONFIG_SMP */
Index: xfs-dev/arch/x86/kdb/Makefile_32
===================================================================
--- xfs-dev.orig/arch/x86/kdb/Makefile_32	2008-12-23 09:30:36.632197485 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,25 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
-#
-
-obj-$(CONFIG_KDB)	:= kdba_bp_32.o kdbasupport_32.o i386-dis.o
-
-# The i386 and x86_64 backtrace commands are handled by common code.
-obj-y		+= kdba_bt.o kdba_io.o kdba_id.o kdba_support.o
-ifneq (,$(findstring -fno-optimize-sibling-calls,$(KBUILD_CFLAGS)))
-  CFLAGS_kdba_bt.o += -DNO_SIBLINGS
-endif
-REGPARM := $(subst -mregparm=,,$(filter -mregparm=%,$(KBUILD_CFLAGS)))
-ifeq (,$(REGPARM))
-  REGPARM := 3
-endif
-
-CFLAGS_kdba_bt.o += -DREGPARM=$(REGPARM) -DCCVERSION="$(CCVERSION)"
-
-override CFLAGS := $(CFLAGS:%-pg=% )
-
-CFLAGS_kdba_io.o += -I $(TOPDIR)/arch/$(SRCARCH)/kdb
Index: xfs-dev/arch/x86/kdb/Makefile_64
===================================================================
--- xfs-dev.orig/arch/x86/kdb/Makefile_64	2008-12-23 09:30:36.636221252 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,25 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
-#
-
-obj-$(CONFIG_KDB)	:= kdba_bp_64.o kdbasupport_64.o x86_64-dis.o
-
-# The i386 and x86_64 backtrace commands are handled by common code.
-obj-y		+= kdba_bt.o kdba_io.o kdba_id.o kdba_support.o
-ifneq (,$(findstring -fno-optimize-sibling-calls,$(KBUILD_CFLAGS)))
-  CFLAGS_kdba_bt.o += -DNO_SIBLINGS
-endif
-REGPARM := $(subst -mregparm=,,$(filter -mregparm=%,$(KBUILD_CFLAGS)))
-ifeq (,$(REGPARM))
-  REGPARM := 6
-endif
-
-CFLAGS_kdba_bt.o += -DREGPARM=$(REGPARM) -DCCVERSION="$(CCVERSION)"
-
-override CFLAGS := $(CFLAGS:%-pg=% )
-
-CFLAGS_kdba_io.o += -I $(TOPDIR)/arch/$(SRCARCH)/kdb
Index: xfs-dev/arch/x86/kdb/kdbasupport_64.c
===================================================================
--- xfs-dev.orig/arch/x86/kdb/kdbasupport_64.c	2008-12-23 09:30:36.639197260 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,1042 +0,0 @@
-/*
- * Kernel Debugger Architecture Independent Support Functions
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1999-2008 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/string.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/hardirq.h>
-#include <linux/kdb.h>
-#include <linux/kdbprivate.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/kdebug.h>
-#include <linux/cpumask.h>
-#include <asm/processor.h>
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/hw_irq.h>
-#include <asm/desc.h>
-
-kdb_machreg_t
-kdba_getdr6(void)
-{
-	return kdba_getdr(6);
-}
-
-kdb_machreg_t
-kdba_getdr7(void)
-{
-	return kdba_getdr(7);
-}
-
-void
-kdba_putdr6(kdb_machreg_t contents)
-{
-	kdba_putdr(6, contents);
-}
-
-static void
-kdba_putdr7(kdb_machreg_t contents)
-{
-	kdba_putdr(7, contents);
-}
-
-void
-kdba_installdbreg(kdb_bp_t *bp)
-{
-	int cpu = smp_processor_id();
-
-	kdb_machreg_t	dr7;
-
-	dr7 = kdba_getdr7();
-
-	kdba_putdr(bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
-
-	dr7 |= DR7_GE;
-	if (cpu_has_de)
-		set_in_cr4(X86_CR4_DE);
-
-	switch (bp->bp_hard[cpu]->bph_reg){
-	case 0:
-		DR7_RW0SET(dr7,bp->bp_hard[cpu]->bph_mode);
-		DR7_LEN0SET(dr7,bp->bp_hard[cpu]->bph_length);
-		DR7_G0SET(dr7);
-		break;
-	case 1:
-		DR7_RW1SET(dr7,bp->bp_hard[cpu]->bph_mode);
-		DR7_LEN1SET(dr7,bp->bp_hard[cpu]->bph_length);
-		DR7_G1SET(dr7);
-		break;
-	case 2:
-		DR7_RW2SET(dr7,bp->bp_hard[cpu]->bph_mode);
-		DR7_LEN2SET(dr7,bp->bp_hard[cpu]->bph_length);
-		DR7_G2SET(dr7);
-		break;
-	case 3:
-		DR7_RW3SET(dr7,bp->bp_hard[cpu]->bph_mode);
-		DR7_LEN3SET(dr7,bp->bp_hard[cpu]->bph_length);
-		DR7_G3SET(dr7);
-		break;
-	default:
-		kdb_printf("kdb: Bad debug register!! %ld\n",
-			   bp->bp_hard[cpu]->bph_reg);
-		break;
-	}
-
-	kdba_putdr7(dr7);
-	return;
-}
-
-void
-kdba_removedbreg(kdb_bp_t *bp)
-{
-	int 		regnum;
-	kdb_machreg_t	dr7;
-	int cpu = smp_processor_id();
-
-	if (!bp->bp_hard[cpu])
-		return;
-
-	regnum = bp->bp_hard[cpu]->bph_reg;
-
-	dr7 = kdba_getdr7();
-
-	kdba_putdr(regnum, 0);
-
-	switch (regnum) {
-	case 0:
-		DR7_G0CLR(dr7);
-		DR7_L0CLR(dr7);
-		break;
-	case 1:
-		DR7_G1CLR(dr7);
-		DR7_L1CLR(dr7);
-		break;
-	case 2:
-		DR7_G2CLR(dr7);
-		DR7_L2CLR(dr7);
-		break;
-	case 3:
-		DR7_G3CLR(dr7);
-		DR7_L3CLR(dr7);
-		break;
-	default:
-		kdb_printf("kdb: Bad debug register!! %d\n", regnum);
-		break;
-	}
-
-	kdba_putdr7(dr7);
-}
-
-kdb_machreg_t
-kdba_getdr(int regnum)
-{
-	kdb_machreg_t contents = 0;
-	switch(regnum) {
-	case 0:
-		__asm__ ("movq %%db0,%0\n\t":"=r"(contents));
-		break;
-	case 1:
-		__asm__ ("movq %%db1,%0\n\t":"=r"(contents));
-		break;
-	case 2:
-		__asm__ ("movq %%db2,%0\n\t":"=r"(contents));
-		break;
-	case 3:
-		__asm__ ("movq %%db3,%0\n\t":"=r"(contents));
-		break;
-	case 4:
-	case 5:
-		break;
-	case 6:
-		__asm__ ("movq %%db6,%0\n\t":"=r"(contents));
-		break;
-	case 7:
-		__asm__ ("movq %%db7,%0\n\t":"=r"(contents));
-		break;
-	default:
-		break;
-	}
-
-	return contents;
-}
-
-
-kdb_machreg_t
-kdb_getcr(int regnum)
-{
-	kdb_machreg_t contents = 0;
-	switch(regnum) {
-	case 0:
-		__asm__ ("movq %%cr0,%0\n\t":"=r"(contents));
-		break;
-	case 1:
-		break;
-	case 2:
-		__asm__ ("movq %%cr2,%0\n\t":"=r"(contents));
-		break;
-	case 3:
-		__asm__ ("movq %%cr3,%0\n\t":"=r"(contents));
-		break;
-	case 4:
-		__asm__ ("movq %%cr4,%0\n\t":"=r"(contents));
-		break;
-	default:
-		break;
-	}
-
-	return contents;
-}
-
-void
-kdba_putdr(int regnum, kdb_machreg_t contents)
-{
-	switch(regnum) {
-	case 0:
-		__asm__ ("movq %0,%%db0\n\t"::"r"(contents));
-		break;
-	case 1:
-		__asm__ ("movq %0,%%db1\n\t"::"r"(contents));
-		break;
-	case 2:
-		__asm__ ("movq %0,%%db2\n\t"::"r"(contents));
-		break;
-	case 3:
-		__asm__ ("movq %0,%%db3\n\t"::"r"(contents));
-		break;
-	case 4:
-	case 5:
-		break;
-	case 6:
-		__asm__ ("movq %0,%%db6\n\t"::"r"(contents));
-		break;
-	case 7:
-		__asm__ ("movq %0,%%db7\n\t"::"r"(contents));
-		break;
-	default:
-		break;
-	}
-}
-
-/*
- * kdba_getregcontents
- *
- *	Return the contents of the register specified by the
- *	input string argument.   Return an error if the string
- *	does not match a machine register.
- *
- *	The following pseudo register names are supported:
- *	   &regs	 - Prints address of exception frame
- *	   krsp		 - Prints kernel stack pointer at time of fault
- *	   crsp		 - Prints current kernel stack pointer, inside kdb
- *	   ceflags	 - Prints current flags, inside kdb
- *	   %<regname>	 - Uses the value of the registers at the
- *			   last time the user process entered kernel
- *			   mode, instead of the registers at the time
- *			   kdb was entered.
- *
- * Parameters:
- *	regname		Pointer to string naming register
- *	regs		Pointer to structure containing registers.
- * Outputs:
- *	*contents	Pointer to unsigned long to recieve register contents
- * Returns:
- *	0		Success
- *	KDB_BADREG	Invalid register name
- * Locking:
- * 	None.
- * Remarks:
- * 	If kdb was entered via an interrupt from the kernel itself then
- *	ss and sp are *not* on the stack.
- */
-
-static struct kdbregs {
-	char   *reg_name;
-	size_t	reg_offset;
-} kdbreglist[] = {
-	{ "r15",	offsetof(struct pt_regs, r15) },
-	{ "r14",	offsetof(struct pt_regs, r14) },
-	{ "r13",	offsetof(struct pt_regs, r13) },
-	{ "r12",	offsetof(struct pt_regs, r12) },
-	{ "bp",		offsetof(struct pt_regs, bp) },
-	{ "bx",		offsetof(struct pt_regs, bx) },
-	{ "r11",	offsetof(struct pt_regs, r11) },
-	{ "r10",	offsetof(struct pt_regs, r10) },
-	{ "r9",		offsetof(struct pt_regs, r9) },
-	{ "r8",		offsetof(struct pt_regs, r8) },
-	{ "ax",		offsetof(struct pt_regs, ax) },
-	{ "cx",		offsetof(struct pt_regs, cx) },
-	{ "dx",		offsetof(struct pt_regs, dx) },
-	{ "si",		offsetof(struct pt_regs, si) },
-	{ "di",		offsetof(struct pt_regs, di) },
-	{ "orig_ax",	offsetof(struct pt_regs, orig_ax) },
-	{ "ip",		offsetof(struct pt_regs, ip) },
-	{ "cs",		offsetof(struct pt_regs, cs) },
-	{ "flags", 	offsetof(struct pt_regs, flags) },
-	{ "sp",		offsetof(struct pt_regs, sp) },
-	{ "ss",		offsetof(struct pt_regs, ss) },
-};
-
-static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
-
-static struct kdbregs dbreglist[] = {
-	{ "dr0", 	0 },
-	{ "dr1", 	1 },
-	{ "dr2",	2 },
-	{ "dr3", 	3 },
-	{ "dr6", 	6 },
-	{ "dr7",	7 },
-};
-
-static const int ndbreglist = sizeof(dbreglist) / sizeof(struct kdbregs);
-
-int
-kdba_getregcontents(const char *regname,
-		    struct pt_regs *regs,
-		    kdb_machreg_t *contents)
-{
-	int i;
-
-	if (strcmp(regname, "&regs") == 0) {
-		*contents = (unsigned long)regs;
-		return 0;
-	}
-
-	if (strcmp(regname, "krsp") == 0) {
-		*contents = (unsigned long)regs + sizeof(struct pt_regs);
-		if ((regs->cs & 0xffff) == __KERNEL_CS) {
-			/* sp and ss are not on stack */
-			*contents -= 2*4;
-		}
-		return 0;
-	}
-
-	if (strcmp(regname, "crsp") == 0) {
-		asm volatile("movq %%rsp,%0":"=m" (*contents));
-		return 0;
-	}
-
-	if (strcmp(regname, "ceflags") == 0) {
-		unsigned long flags;
-		local_save_flags(flags);
-		*contents = flags;
-		return 0;
-	}
-
-	if (regname[0] == '%') {
-		/* User registers:  %%r[a-c]x, etc */
-		regname++;
-		regs = (struct pt_regs *)
-			(current->thread.sp0 - sizeof(struct pt_regs));
-	}
-
-	for (i=0; i<nkdbreglist; i++) {
-		if (strnicmp(kdbreglist[i].reg_name,
-			     regname,
-			     strlen(regname)) == 0)
-			break;
-	}
-
-	if ((i < nkdbreglist)
-	 && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
-		if ((regs->cs & 0xffff) == __KERNEL_CS) {
-			/* No cpl switch, sp is not on stack */
-			if (strcmp(kdbreglist[i].reg_name, "sp") == 0) {
-				*contents = (kdb_machreg_t)regs +
-					sizeof(struct pt_regs) - 2*8;
-				return(0);
-			}
-#if 0	/* FIXME */
-			if (strcmp(kdbreglist[i].reg_name, "ss") == 0) {
-				kdb_machreg_t r;
-
-				r = (kdb_machreg_t)regs +
-					sizeof(struct pt_regs) - 2*8;
-				*contents = (kdb_machreg_t)SS(r);	/* XXX */
-				return(0);
-			}
-#endif
-		}
-		*contents = *(unsigned long *)((unsigned long)regs +
-				kdbreglist[i].reg_offset);
-		return(0);
-	}
-
-	for (i=0; i<ndbreglist; i++) {
-		if (strnicmp(dbreglist[i].reg_name,
-			     regname,
-			     strlen(regname)) == 0)
-			break;
-	}
-
-	if ((i < ndbreglist)
-	 && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
-		*contents = kdba_getdr(dbreglist[i].reg_offset);
-		return 0;
-	}
-	return KDB_BADREG;
-}
-
-/*
- * kdba_setregcontents
- *
- *	Set the contents of the register specified by the
- *	input string argument.   Return an error if the string
- *	does not match a machine register.
- *
- *	Supports modification of user-mode registers via
- *	%<register-name>
- *
- * Parameters:
- *	regname		Pointer to string naming register
- *	regs		Pointer to structure containing registers.
- *	contents	Unsigned long containing new register contents
- * Outputs:
- * Returns:
- *	0		Success
- *	KDB_BADREG	Invalid register name
- * Locking:
- * 	None.
- * Remarks:
- */
-
-int
-kdba_setregcontents(const char *regname,
-		  struct pt_regs *regs,
-		  unsigned long contents)
-{
-	int i;
-
-	if (regname[0] == '%') {
-		regname++;
-		regs = (struct pt_regs *)
-			(current->thread.sp0 - sizeof(struct pt_regs));
-	}
-
-	for (i=0; i<nkdbreglist; i++) {
-		if (strnicmp(kdbreglist[i].reg_name,
-			     regname,
-			     strlen(regname)) == 0)
-			break;
-	}
-
-	if ((i < nkdbreglist)
-	 && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
-		*(unsigned long *)((unsigned long)regs
-				   + kdbreglist[i].reg_offset) = contents;
-		return 0;
-	}
-
-	for (i=0; i<ndbreglist; i++) {
-		if (strnicmp(dbreglist[i].reg_name,
-			     regname,
-			     strlen(regname)) == 0)
-			break;
-	}
-
-	if ((i < ndbreglist)
-	 && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
-		kdba_putdr(dbreglist[i].reg_offset, contents);
-		return 0;
-	}
-
-	return KDB_BADREG;
-}
-
-/*
- * kdba_dumpregs
- *
- *	Dump the specified register set to the display.
- *
- * Parameters:
- *	regs		Pointer to structure containing registers.
- *	type		Character string identifying register set to dump
- *	extra		string further identifying register (optional)
- * Outputs:
- * Returns:
- *	0		Success
- * Locking:
- * 	None.
- * Remarks:
- *	This function will dump the general register set if the type
- *	argument is NULL (struct pt_regs).   The alternate register
- *	set types supported by this function:
- *
- *	d		Debug registers
- *	c		Control registers
- *	u		User registers at most recent entry to kernel
- * Following not yet implemented:
- *	r		Memory Type Range Registers (extra defines register)
- *
- * MSR on i386/x86_64 are handled by rdmsr/wrmsr commands.
- */
-
-int
-kdba_dumpregs(struct pt_regs *regs,
-	    const char *type,
-	    const char *extra)
-{
-	int i;
-	int count = 0;
-
-	if (type
-	 && (type[0] == 'u')) {
-		type = NULL;
-		regs = (struct pt_regs *)
-			(current->thread.sp0 - sizeof(struct pt_regs));
-	}
-
-	if (type == NULL) {
-		struct kdbregs *rlp;
-		kdb_machreg_t contents;
-
-		if (!regs) {
-			kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
-			return KDB_BADREG;
-		}
-
-		for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) {
-			kdb_printf("%8s = ", rlp->reg_name);
-			kdba_getregcontents(rlp->reg_name, regs, &contents);
-			kdb_printf("0x%016lx ", contents);
-			if ((++count % 2) == 0)
-				kdb_printf("\n");
-		}
-
-		kdb_printf("&regs = 0x%p\n", regs);
-
-		return 0;
-	}
-
-	switch (type[0]) {
-	case 'd':
-	{
-		unsigned long dr[8];
-
-		for(i=0; i<8; i++) {
-			if ((i == 4) || (i == 5)) continue;
-			dr[i] = kdba_getdr(i);
-		}
-		kdb_printf("dr0 = 0x%08lx  dr1 = 0x%08lx  dr2 = 0x%08lx  dr3 = 0x%08lx\n",
-			   dr[0], dr[1], dr[2], dr[3]);
-		kdb_printf("dr6 = 0x%08lx  dr7 = 0x%08lx\n",
-			   dr[6], dr[7]);
-		return 0;
-	}
-	case 'c':
-	{
-		unsigned long cr[5];
-
-		for (i=0; i<5; i++) {
-			cr[i] = kdb_getcr(i);
-		}
-		kdb_printf("cr0 = 0x%08lx  cr1 = 0x%08lx  cr2 = 0x%08lx  cr3 = 0x%08lx\ncr4 = 0x%08lx\n",
-			   cr[0], cr[1], cr[2], cr[3], cr[4]);
-		return 0;
-	}
-	case 'r':
-		break;
-	default:
-		return KDB_BADREG;
-	}
-
-	/* NOTREACHED */
-	return 0;
-}
-EXPORT_SYMBOL(kdba_dumpregs);
-
-kdb_machreg_t
-kdba_getpc(struct pt_regs *regs)
-{
-	return regs ? regs->ip : 0;
-}
-
-int
-kdba_setpc(struct pt_regs *regs, kdb_machreg_t newpc)
-{
-	if (KDB_NULL_REGS(regs))
-		return KDB_BADREG;
-	regs->ip = newpc;
-	KDB_STATE_SET(IP_ADJUSTED);
-	return 0;
-}
-
-/*
- * kdba_main_loop
- *
- *	Do any architecture specific set up before entering the main kdb loop.
- *	The primary function of this routine is to make all processes look the
- *	same to kdb, kdb must be able to list a process without worrying if the
- *	process is running or blocked, so make all process look as though they
- *	are blocked.
- *
- * Inputs:
- *	reason		The reason KDB was invoked
- *	error		The hardware-defined error code
- *	error2		kdb's current reason code.  Initially error but can change
- *			acording to kdb state.
- *	db_result	Result from break or debug point.
- *	ef		The exception frame at time of fault/breakpoint.  If reason
- *			is SILENT or CPU_UP then regs is NULL, otherwise it should
- *			always be valid.
- * Returns:
- *	0	KDB was invoked for an event which it wasn't responsible
- *	1	KDB handled the event for which it was invoked.
- * Outputs:
- *	Sets ip and sp in current->thread.
- * Locking:
- *	None.
- * Remarks:
- *	none.
- */
-
-int
-kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
-	       kdb_dbtrap_t db_result, struct pt_regs *regs)
-{
-	int ret;
-
-	if (regs)
-		kdba_getregcontents("sp", regs, &(current->thread.sp));
-	ret = kdb_save_running(regs, reason, reason2, error, db_result);
-	kdb_unsave_running(regs);
-	return ret;
-}
-
-void
-kdba_disableint(kdb_intstate_t *state)
-{
-	unsigned long *fp = (unsigned long *)state;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	*fp = flags;
-}
-
-void
-kdba_restoreint(kdb_intstate_t *state)
-{
-	unsigned long flags = *(unsigned long *)state;
-	local_irq_restore(flags);
-}
-
-void
-kdba_setsinglestep(struct pt_regs *regs)
-{
-	if (KDB_NULL_REGS(regs))
-		return;
-	if (regs->flags & X86_EFLAGS_IF)
-		KDB_STATE_SET(A_IF);
-	else
-		KDB_STATE_CLEAR(A_IF);
-	regs->flags = (regs->flags | X86_EFLAGS_TF) & ~X86_EFLAGS_IF;
-}
-
-void
-kdba_clearsinglestep(struct pt_regs *regs)
-{
-	if (KDB_NULL_REGS(regs))
-		return;
-	if (KDB_STATE(A_IF))
-		regs->flags |= X86_EFLAGS_IF;
-	else
-		regs->flags &= ~X86_EFLAGS_IF;
-}
-
-int asmlinkage
-kdba_setjmp(kdb_jmp_buf *jb)
-{
-#ifdef	CONFIG_FRAME_POINTER
-	__asm__ __volatile__
-		("movq %%rbx, (0*8)(%%rdi);"
-		"movq %%rcx, (1*8)(%%rdi);"
-		"movq %%r12, (2*8)(%%rdi);"
-		"movq %%r13, (3*8)(%%rdi);"
-		"movq %%r14, (4*8)(%%rdi);"
-		"movq %%r15, (5*8)(%%rdi);"
-		"leaq 16(%%rsp), %%rdx;"
-		"movq %%rdx, (6*8)(%%rdi);"
-		"movq %%rax, (7*8)(%%rdi)"
-		:
-		: "a" (__builtin_return_address(0)),
-		  "c" (__builtin_frame_address(1))
-		);
-#else	 /* !CONFIG_FRAME_POINTER */
-	__asm__ __volatile__
-		("movq %%rbx, (0*8)(%%rdi);"
-		"movq %%rbp, (1*8)(%%rdi);"
-		"movq %%r12, (2*8)(%%rdi);"
-		"movq %%r13, (3*8)(%%rdi);"
-		"movq %%r14, (4*8)(%%rdi);"
-		"movq %%r15, (5*8)(%%rdi);"
-		"leaq 8(%%rsp), %%rdx;"
-		"movq %%rdx, (6*8)(%%rdi);"
-		"movq %%rax, (7*8)(%%rdi)"
-		:
-		: "a" (__builtin_return_address(0))
-		);
-#endif   /* CONFIG_FRAME_POINTER */
-	return 0;
-}
-
-void asmlinkage
-kdba_longjmp(kdb_jmp_buf *jb, int reason)
-{
-	__asm__("movq (0*8)(%rdi),%rbx;"
-		"movq (1*8)(%rdi),%rbp;"
-		"movq (2*8)(%rdi),%r12;"
-		"movq (3*8)(%rdi),%r13;"
-		"movq (4*8)(%rdi),%r14;"
-		"movq (5*8)(%rdi),%r15;"
-		"movq (7*8)(%rdi),%rdx;"
-		"movq (6*8)(%rdi),%rsp;"
-		"mov %rsi, %rax;"
-		"jmpq *%rdx");
-}
-
-/*
- * kdba_pt_regs
- *
- *	Format a struct pt_regs
- *
- * Inputs:
- *	argc	argument count
- *	argv	argument vector
- * Outputs:
- *	None.
- * Returns:
- *	zero for success, a kdb diagnostic if error
- * Locking:
- *	none.
- * Remarks:
- *	If no address is supplied, it uses the current irq pt_regs.
- */
-
-static int
-kdba_pt_regs(int argc, const char **argv)
-{
-	int diag;
-	kdb_machreg_t addr;
-	long offset = 0;
-	int nextarg;
-	struct pt_regs *p;
-	static const char *fmt = "  %-11.11s 0x%lx\n";
-	static int first_time = 1;
-
-	if (argc == 0) {
-		addr = (kdb_machreg_t) get_irq_regs();
-	} else if (argc == 1) {
-		nextarg = 1;
-		diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL);
-		if (diag)
-			return diag;
-	} else {
-		return KDB_ARGCOUNT;
-	}
-
-	p = (struct pt_regs *) addr;
-	if (first_time) {
-		first_time = 0;
-		kdb_printf("\n+++ Warning: x86_64 pt_regs are not always "
-			   "completely defined, r15-bx may be invalid\n\n");
-	}
-	kdb_printf("struct pt_regs 0x%p-0x%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
-	kdb_print_nameval("r15", p->r15);
-	kdb_print_nameval("r14", p->r14);
-	kdb_print_nameval("r13", p->r13);
-	kdb_print_nameval("r12", p->r12);
-	kdb_print_nameval("bp", p->bp);
-	kdb_print_nameval("bx", p->bx);
-	kdb_print_nameval("r11", p->r11);
-	kdb_print_nameval("r10", p->r10);
-	kdb_print_nameval("r9", p->r9);
-	kdb_print_nameval("r8", p->r8);
-	kdb_print_nameval("ax", p->ax);
-	kdb_print_nameval("cx", p->cx);
-	kdb_print_nameval("dx", p->dx);
-	kdb_print_nameval("si", p->si);
-	kdb_print_nameval("di", p->di);
-	kdb_print_nameval("orig_ax", p->orig_ax);
-	kdb_print_nameval("ip", p->ip);
-	kdb_printf(fmt, "cs", p->cs);
-	kdb_printf(fmt, "flags", p->flags);
-	kdb_printf(fmt, "sp", p->sp);
-	kdb_printf(fmt, "ss", p->ss);
-	return 0;
-}
-
-/*
- * kdba_cpu_pda
- *
- *	Format a struct cpu_pda
- *
- * Inputs:
- *	argc	argument count
- *	argv	argument vector
- * Outputs:
- *	None.
- * Returns:
- *	zero for success, a kdb diagnostic if error
- * Locking:
- *	none.
- * Remarks:
- *	If no cpu is supplied, it prints the current cpu.  If the cpu is '*'
- *	then it prints all cpus.
- */
-
-static int
-kdba_cpu_pda(int argc, const char **argv)
-{
-	int diag, nextarg, all_cpus = 0;
-	long offset = 0;
-	unsigned long cpu;
-	struct x8664_pda *c;
-	static const char *fmtl = "  %-17.17s 0x%lx\n";
-	static const char *fmtd = "  %-17.17s %d\n";
-	static const char *fmtp = "  %-17.17s 0x%p\n";
-
-	if (argc == 0) {
-		cpu = smp_processor_id();
-	} else if (argc == 1) {
-		if (strcmp(argv[1], "*") == 0) {
-			all_cpus = 1;
-			cpu = 0;
-		} else {
-			nextarg = 1;
-			diag = kdbgetaddrarg(argc, argv, &nextarg, &cpu, &offset, NULL);
-			if (diag)
-				return diag;
-		}
-	} else {
-		return KDB_ARGCOUNT;
-	}
-
-	for (; cpu < NR_CPUS; ++cpu) {
-		if (cpu_online(cpu)) {
-			c = cpu_pda(cpu);
-			kdb_printf("struct cpu_pda 0x%p-0x%p\n", c, (unsigned char *)c + sizeof(*c) - 1);
-			kdb_printf(fmtp, "pcurrent", c->pcurrent);
-			kdb_printf(fmtl, "data_offset", c->data_offset);
-			kdb_printf(fmtl, "kernelstack", c->kernelstack);
-			kdb_printf(fmtl, "oldrsp", c->oldrsp);
-			kdb_printf(fmtd, "irqcount", c->irqcount);
-			kdb_printf(fmtd, "cpunumber", c->cpunumber);
-			kdb_printf(fmtp, "irqstackptr", c->irqstackptr);
-			kdb_printf(fmtp, "nodenumber", cpu_to_node(cpu));
-			kdb_printf(fmtd, "__softirq_pending", c->__softirq_pending);
-			kdb_printf(fmtd, "__nmi_count", c->__nmi_count);
-			kdb_printf(fmtd, "mmu_state", c->mmu_state);
-			kdb_printf(fmtp, "active_mm", c->active_mm);
-			kdb_printf(fmtd, "apic_timer_irqs", c->apic_timer_irqs);
-		}
-		if (!all_cpus)
-			break;
-	}
-	return 0;
-}
-
-/*
- * kdba_entry
- *
- *	This is the interface routine between
- *	the notifier die_chain and kdb
- */
-static int kdba_entry( struct notifier_block *b, unsigned long val, void *v)
-{
-	struct die_args *args = v;
-	int err, trap, ret = 0;
-	struct pt_regs *regs;
-
-	regs = args->regs;
-	err  = args->err;
-	trap  = args->trapnr;
-	switch (val){
-#ifdef	CONFIG_SMP
-		case DIE_NMI_IPI:
-			ret = kdb_ipi(regs, NULL);
-			break;
-#endif	/* CONFIG_SMP */
-		case DIE_OOPS:
-			ret = kdb(KDB_REASON_OOPS, err, regs);
-			break;
-		case DIE_CALL:
-			ret = kdb(KDB_REASON_ENTER, err, regs);
-			break;
-		case DIE_DEBUG:
-			ret = kdb(KDB_REASON_DEBUG, err, regs);
-			break;
-		case DIE_NMIWATCHDOG:
-			ret = kdb(KDB_REASON_NMI, err, regs);
-			break;
-		case DIE_INT3:
-			 ret = kdb(KDB_REASON_BREAK, err, regs);
-			// falls thru
-		default:
-			break;
-	}
-	return (ret ? NOTIFY_STOP : NOTIFY_DONE);
-}
-
-/*
- * notifier block for kdb entry
- */
-static struct notifier_block kdba_notifier = {
-	.notifier_call = kdba_entry
-};
-
-asmlinkage int kdb_call(void);
-
-/* Executed once on each cpu at startup. */
-void
-kdba_cpu_up(void)
-{
-}
-
-static int __init
-kdba_arch_init(void)
-{
-	set_intr_gate(KDBENTER_VECTOR, kdb_call);
-	return 0;
-}
-
-arch_initcall(kdba_arch_init);
-
-/*
- * kdba_init
- *
- * 	Architecture specific initialization.
- *
- * Parameters:
- *	None.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- *	None.
- */
-
-void __init
-kdba_init(void)
-{
-	kdba_arch_init();	/* Need to register KDBENTER_VECTOR early */
-	kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0);
-	kdb_register("cpu_pda", kdba_cpu_pda, "<cpu>", "Format struct cpu_pda", 0);
-	register_die_notifier(&kdba_notifier);
-	return;
-}
-
-/*
- * kdba_adjust_ip
- *
- * 	Architecture specific adjustment of instruction pointer before leaving
- *	kdb.
- *
- * Parameters:
- *	reason		The reason KDB was invoked
- *	error		The hardware-defined error code
- *	ef		The exception frame at time of fault/breakpoint.  If reason
- *			is SILENT or CPU_UP then regs is NULL, otherwise it should
- *			always be valid.
- * Returns:
- *	None.
- * Locking:
- *	None.
- * Remarks:
- *	noop on ix86.
- */
-
-void
-kdba_adjust_ip(kdb_reason_t reason, int error, struct pt_regs *ef)
-{
-	return;
-}
-
-void
-kdba_set_current_task(const struct task_struct *p)
-{
-	kdb_current_task = p;
-	if (kdb_task_has_cpu(p)) {
-		struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p);
-		kdb_current_regs = krp->regs;
-		return;
-	}
-	kdb_current_regs = NULL;
-}
-
-#ifdef	CONFIG_SMP
-
-#include <mach_ipi.h>
-
-gate_desc save_idt[NR_VECTORS];
-
-void kdba_takeover_vector(int vector)
-{
-	memcpy(&save_idt[vector], &idt_table[vector], sizeof(gate_desc));
-	set_intr_gate(KDB_VECTOR, kdb_interrupt);
-	return;
-}
-
-void kdba_giveback_vector(int vector)
-{
-	native_write_idt_entry(idt_table, vector, &save_idt[vector]);
-	return;
-}
-
-/* When first entering KDB, try a normal IPI.  That reduces backtrace problems
- * on the other cpus.
- */
-void
-smp_kdb_stop(void)
-{
-	if (!KDB_FLAG(NOIPI)) {
-		kdba_takeover_vector(KDB_VECTOR);
-		send_IPI_allbutself(KDB_VECTOR);
-	}
-}
-
-/* The normal KDB IPI handler */
-extern asmlinkage void smp_kdb_interrupt(struct pt_regs *regs);	/* for sparse */
-asmlinkage void
-smp_kdb_interrupt(struct pt_regs *regs)
-{
-	struct pt_regs *old_regs = set_irq_regs(regs);
-	ack_APIC_irq();
-	irq_enter();
-	kdb_ipi(regs, NULL);
-	irq_exit();
-	set_irq_regs(old_regs);
-}
-
-/* Invoked once from kdb_wait_for_cpus when waiting for cpus.  For those cpus
- * that have not responded to the normal KDB interrupt yet, hit them with an
- * NMI event.
- */
-void
-kdba_wait_for_cpus(void)
-{
-	int c;
-	if (KDB_FLAG(CATASTROPHIC))
-		return;
-	kdb_printf("  Sending NMI to non-responding cpus: ");
-	for_each_online_cpu(c) {
-		if (kdb_running_process[c].seqno < kdb_seqno - 1) {
-			kdb_printf(" %d", c);
-			send_IPI_mask(cpumask_of_cpu(c), NMI_VECTOR);
-		}
-	}
-	kdb_printf(".\n");
-}
-
-#endif	/* CONFIG_SMP */
Index: xfs-dev/arch/x86/kdb/i386-dis.c
===================================================================
--- xfs-dev.orig/arch/x86/kdb/i386-dis.c	2008-12-23 09:30:36.643226545 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,4686 +0,0 @@
-/* Print i386 instructions for GDB, the GNU debugger.
-   Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
- * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
- * required.
- * Keith Owens <kaos at sgi.com> 15 May 2006
- */
-
-/* 80386 instruction printer by Pace Willisson (pace at prep.ai.mit.edu)
-   July 1988
-    modified by John Hassey (hassey at dg-rtp.dg.com)
-    x86-64 support added by Jan Hubicka (jh at suse.cz)
-    VIA PadLock support by Michal Ludvig (mludvig at suse.cz).  */
-
-/* The main tables describing the instructions is essentially a copy
-   of the "Opcode Map" chapter (Appendix A) of the Intel 80386
-   Programmers Manual.  Usually, there is a capital letter, followed
-   by a small letter.  The capital letter tell the addressing mode,
-   and the small letter tells about the operand size.  Refer to
-   the Intel manual for details.  */
-
-#ifdef __KERNEL__
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/dis-asm.h>
-#include <linux/kdb.h>
-#define abort() BUG()
-#else	/* __KERNEL__ */
-#include "dis-asm.h"
-#include "sysdep.h"
-#include "opintl.h"
-#endif	/* __KERNEL__ */
-
-#define MAXLEN 20
-
-#ifndef __KERNEL__
-#include <setjmp.h>
-#endif	/* __KERNEL__ */
-
-#ifndef UNIXWARE_COMPAT
-/* Set non-zero for broken, compatible instructions.  Set to zero for
-   non-broken opcodes.  */
-#define UNIXWARE_COMPAT 1
-#endif
-
-static int fetch_data (struct disassemble_info *, bfd_byte *);
-static void ckprefix (void);
-static const char *prefix_name (int, int);
-static int print_insn (bfd_vma, disassemble_info *);
-static void dofloat (int);
-static void OP_ST (int, int);
-static void OP_STi (int, int);
-static int putop (const char *, int);
-static void oappend (const char *);
-static void append_seg (void);
-static void OP_indirE (int, int);
-static void print_operand_value (char *, int, bfd_vma);
-static void OP_E (int, int);
-static void OP_G (int, int);
-static bfd_vma get64 (void);
-static bfd_signed_vma get32 (void);
-static bfd_signed_vma get32s (void);
-static int get16 (void);
-static void set_op (bfd_vma, int);
-static void OP_REG (int, int);
-static void OP_IMREG (int, int);
-static void OP_I (int, int);
-static void OP_I64 (int, int);
-static void OP_sI (int, int);
-static void OP_J (int, int);
-static void OP_SEG (int, int);
-static void OP_DIR (int, int);
-static void OP_OFF (int, int);
-static void OP_OFF64 (int, int);
-static void ptr_reg (int, int);
-static void OP_ESreg (int, int);
-static void OP_DSreg (int, int);
-static void OP_C (int, int);
-static void OP_D (int, int);
-static void OP_T (int, int);
-static void OP_Rd (int, int);
-static void OP_MMX (int, int);
-static void OP_XMM (int, int);
-static void OP_EM (int, int);
-static void OP_EX (int, int);
-static void OP_MS (int, int);
-static void OP_XS (int, int);
-static void OP_M (int, int);
-static void OP_VMX (int, int);
-static void OP_0fae (int, int);
-static void OP_0f07 (int, int);
-static void NOP_Fixup (int, int);
-static void OP_3DNowSuffix (int, int);
-static void OP_SIMD_Suffix (int, int);
-static void SIMD_Fixup (int, int);
-static void PNI_Fixup (int, int);
-static void SVME_Fixup (int, int);
-static void INVLPG_Fixup (int, int);
-static void BadOp (void);
-static void SEG_Fixup (int, int);
-static void VMX_Fixup (int, int);
-
-struct dis_private {
-  /* Points to first byte not fetched.  */
-  bfd_byte *max_fetched;
-  bfd_byte the_buffer[MAXLEN];
-  bfd_vma insn_start;
-  int orig_sizeflag;
-#ifndef __KERNEL__
-  jmp_buf bailout;
-#endif	/* __KERNEL__ */
-};
-
-/* The opcode for the fwait instruction, which we treat as a prefix
-   when we can.  */
-#define FWAIT_OPCODE (0x9b)
-
-/* Set to 1 for 64bit mode disassembly.  */
-static int mode_64bit;
-
-/* Flags for the prefixes for the current instruction.  See below.  */
-static int prefixes;
-
-/* REX prefix the current instruction.  See below.  */
-static int rex;
-/* Bits of REX we've already used.  */
-static int rex_used;
-#define REX_MODE64	8
-#define REX_EXTX	4
-#define REX_EXTY	2
-#define REX_EXTZ	1
-/* Mark parts used in the REX prefix.  When we are testing for
-   empty prefix (for 8bit register REX extension), just mask it
-   out.  Otherwise test for REX bit is excuse for existence of REX
-   only in case value is nonzero.  */
-#define USED_REX(value)					\
-  {							\
-    if (value)						\
-      rex_used |= (rex & value) ? (value) | 0x40 : 0;	\
-    else						\
-      rex_used |= 0x40;					\
-  }
-
-/* Flags for prefixes which we somehow handled when printing the
-   current instruction.  */
-static int used_prefixes;
-
-/* Flags stored in PREFIXES.  */
-#define PREFIX_REPZ 1
-#define PREFIX_REPNZ 2
-#define PREFIX_LOCK 4
-#define PREFIX_CS 8
-#define PREFIX_SS 0x10
-#define PREFIX_DS 0x20
-#define PREFIX_ES 0x40
-#define PREFIX_FS 0x80
-#define PREFIX_GS 0x100
-#define PREFIX_DATA 0x200
-#define PREFIX_ADDR 0x400
-#define PREFIX_FWAIT 0x800
-
-/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
-   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
-   on error.  */
-#define FETCH_DATA(info, addr) \
-  ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
-   ? 1 : fetch_data ((info), (addr)))
-
-static int
-fetch_data (struct disassemble_info *info, bfd_byte *addr)
-{
-  int status;
-  struct dis_private *priv = (struct dis_private *) info->private_data;
-  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
-
-  status = (*info->read_memory_func) (start,
-				      priv->max_fetched,
-				      addr - priv->max_fetched,
-				      info);
-  if (status != 0)
-    {
-      /* If we did manage to read at least one byte, then
-	 print_insn_i386 will do something sensible.  Otherwise, print
-	 an error.  We do that here because this is where we know
-	 STATUS.  */
-      if (priv->max_fetched == priv->the_buffer)
-	(*info->memory_error_func) (status, start, info);
-#ifndef __KERNEL__
-      longjmp (priv->bailout, 1);
-#else	/* __KERNEL__ */
-	/* XXX - what to do? */
-	kdb_printf("Hmm. longjmp.\n");
-#endif	/* __KERNEL__ */
-    }
-  else
-    priv->max_fetched = addr;
-  return 1;
-}
-
-#define XX NULL, 0
-
-#define Eb OP_E, b_mode
-#define Ev OP_E, v_mode
-#define Ed OP_E, d_mode
-#define Eq OP_E, q_mode
-#define Edq OP_E, dq_mode
-#define Edqw OP_E, dqw_mode
-#define indirEv OP_indirE, branch_v_mode
-#define indirEp OP_indirE, f_mode
-#define Em OP_E, m_mode
-#define Ew OP_E, w_mode
-#define Ma OP_E, v_mode
-#define M OP_M, 0		/* lea, lgdt, etc. */
-#define Mp OP_M, f_mode		/* 32 or 48 bit memory operand for LDS, LES etc */
-#define Gb OP_G, b_mode
-#define Gv OP_G, v_mode
-#define Gd OP_G, d_mode
-#define Gdq OP_G, dq_mode
-#define Gm OP_G, m_mode
-#define Gw OP_G, w_mode
-#define Rd OP_Rd, d_mode
-#define Rm OP_Rd, m_mode
-#define Ib OP_I, b_mode
-#define sIb OP_sI, b_mode	/* sign extened byte */
-#define Iv OP_I, v_mode
-#define Iq OP_I, q_mode
-#define Iv64 OP_I64, v_mode
-#define Iw OP_I, w_mode
-#define I1 OP_I, const_1_mode
-#define Jb OP_J, b_mode
-#define Jv OP_J, v_mode
-#define Cm OP_C, m_mode
-#define Dm OP_D, m_mode
-#define Td OP_T, d_mode
-#define Sv SEG_Fixup, v_mode
-
-#define RMeAX OP_REG, eAX_reg
-#define RMeBX OP_REG, eBX_reg
-#define RMeCX OP_REG, eCX_reg
-#define RMeDX OP_REG, eDX_reg
-#define RMeSP OP_REG, eSP_reg
-#define RMeBP OP_REG, eBP_reg
-#define RMeSI OP_REG, eSI_reg
-#define RMeDI OP_REG, eDI_reg
-#define RMrAX OP_REG, rAX_reg
-#define RMrBX OP_REG, rBX_reg
-#define RMrCX OP_REG, rCX_reg
-#define RMrDX OP_REG, rDX_reg
-#define RMrSP OP_REG, rSP_reg
-#define RMrBP OP_REG, rBP_reg
-#define RMrSI OP_REG, rSI_reg
-#define RMrDI OP_REG, rDI_reg
-#define RMAL OP_REG, al_reg
-#define RMAL OP_REG, al_reg
-#define RMCL OP_REG, cl_reg
-#define RMDL OP_REG, dl_reg
-#define RMBL OP_REG, bl_reg
-#define RMAH OP_REG, ah_reg
-#define RMCH OP_REG, ch_reg
-#define RMDH OP_REG, dh_reg
-#define RMBH OP_REG, bh_reg
-#define RMAX OP_REG, ax_reg
-#define RMDX OP_REG, dx_reg
-
-#define eAX OP_IMREG, eAX_reg
-#define eBX OP_IMREG, eBX_reg
-#define eCX OP_IMREG, eCX_reg
-#define eDX OP_IMREG, eDX_reg
-#define eSP OP_IMREG, eSP_reg
-#define eBP OP_IMREG, eBP_reg
-#define eSI OP_IMREG, eSI_reg
-#define eDI OP_IMREG, eDI_reg
-#define AL OP_IMREG, al_reg
-#define AL OP_IMREG, al_reg
-#define CL OP_IMREG, cl_reg
-#define DL OP_IMREG, dl_reg
-#define BL OP_IMREG, bl_reg
-#define AH OP_IMREG, ah_reg
-#define CH OP_IMREG, ch_reg
-#define DH OP_IMREG, dh_reg
-#define BH OP_IMREG, bh_reg
-#define AX OP_IMREG, ax_reg
-#define DX OP_IMREG, dx_reg
-#define indirDX OP_IMREG, indir_dx_reg
-
-#define Sw OP_SEG, w_mode
-#define Ap OP_DIR, 0
-#define Ob OP_OFF, b_mode
-#define Ob64 OP_OFF64, b_mode
-#define Ov OP_OFF, v_mode
-#define Ov64 OP_OFF64, v_mode
-#define Xb OP_DSreg, eSI_reg
-#define Xv OP_DSreg, eSI_reg
-#define Yb OP_ESreg, eDI_reg
-#define Yv OP_ESreg, eDI_reg
-#define DSBX OP_DSreg, eBX_reg
-
-#define es OP_REG, es_reg
-#define ss OP_REG, ss_reg
-#define cs OP_REG, cs_reg
-#define ds OP_REG, ds_reg
-#define fs OP_REG, fs_reg
-#define gs OP_REG, gs_reg
-
-#define MX OP_MMX, 0
-#define XM OP_XMM, 0
-#define EM OP_EM, v_mode
-#define EX OP_EX, v_mode
-#define MS OP_MS, v_mode
-#define XS OP_XS, v_mode
-#define VM OP_VMX, q_mode
-#define OPSUF OP_3DNowSuffix, 0
-#define OPSIMD OP_SIMD_Suffix, 0
-
-#define cond_jump_flag NULL, cond_jump_mode
-#define loop_jcxz_flag NULL, loop_jcxz_mode
-
-/* bits in sizeflag */
-#define SUFFIX_ALWAYS 4
-#define AFLAG 2
-#define DFLAG 1
-
-#define b_mode 1  /* byte operand */
-#define v_mode 2  /* operand size depends on prefixes */
-#define w_mode 3  /* word operand */
-#define d_mode 4  /* double word operand  */
-#define q_mode 5  /* quad word operand */
-#define t_mode 6  /* ten-byte operand */
-#define x_mode 7  /* 16-byte XMM operand */
-#define m_mode 8  /* d_mode in 32bit, q_mode in 64bit mode.  */
-#define cond_jump_mode 9
-#define loop_jcxz_mode 10
-#define dq_mode 11 /* operand size depends on REX prefixes.  */
-#define dqw_mode 12 /* registers like dq_mode, memory like w_mode.  */
-#define f_mode 13 /* 4- or 6-byte pointer operand */
-#define const_1_mode 14
-#define branch_v_mode 15 /* v_mode for branch.  */
-
-#define es_reg 100
-#define cs_reg 101
-#define ss_reg 102
-#define ds_reg 103
-#define fs_reg 104
-#define gs_reg 105
-
-#define eAX_reg 108
-#define eCX_reg 109
-#define eDX_reg 110
-#define eBX_reg 111
-#define eSP_reg 112
-#define eBP_reg 113
-#define eSI_reg 114
-#define eDI_reg 115
-
-#define al_reg 116
-#define cl_reg 117
-#define dl_reg 118
-#define bl_reg 119
-#define ah_reg 120
-#define ch_reg 121
-#define dh_reg 122
-#define bh_reg 123
-
-#define ax_reg 124
-#define cx_reg 125
-#define dx_reg 126
-#define bx_reg 127
-#define sp_reg 128
-#define bp_reg 129
-#define si_reg 130
-#define di_reg 131
-
-#define rAX_reg 132
-#define rCX_reg 133
-#define rDX_reg 134
-#define rBX_reg 135
-#define rSP_reg 136
-#define rBP_reg 137
-#define rSI_reg 138
-#define rDI_reg 139
-
-#define indir_dx_reg 150
-
-#define FLOATCODE 1
-#define USE_GROUPS 2
-#define USE_PREFIX_USER_TABLE 3
-#define X86_64_SPECIAL 4
-
-#define FLOAT	  NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
-
-#define GRP1b	  NULL, NULL, USE_GROUPS, NULL,  0, NULL, 0
-#define GRP1S	  NULL, NULL, USE_GROUPS, NULL,  1, NULL, 0
-#define GRP1Ss	  NULL, NULL, USE_GROUPS, NULL,  2, NULL, 0
-#define GRP2b	  NULL, NULL, USE_GROUPS, NULL,  3, NULL, 0
-#define GRP2S	  NULL, NULL, USE_GROUPS, NULL,  4, NULL, 0
-#define GRP2b_one NULL, NULL, USE_GROUPS, NULL,  5, NULL, 0
-#define GRP2S_one NULL, NULL, USE_GROUPS, NULL,  6, NULL, 0
-#define GRP2b_cl  NULL, NULL, USE_GROUPS, NULL,  7, NULL, 0
-#define GRP2S_cl  NULL, NULL, USE_GROUPS, NULL,  8, NULL, 0
-#define GRP3b	  NULL, NULL, USE_GROUPS, NULL,  9, NULL, 0
-#define GRP3S	  NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
-#define GRP4	  NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
-#define GRP5	  NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
-#define GRP6	  NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
-#define GRP7	  NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
-#define GRP8	  NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
-#define GRP9	  NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
-#define GRP10	  NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
-#define GRP11	  NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
-#define GRP12	  NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
-#define GRP13	  NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
-#define GRP14	  NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
-#define GRPAMD	  NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
-#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
-#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
-
-#define PREGRP0   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  0, NULL, 0
-#define PREGRP1   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  1, NULL, 0
-#define PREGRP2   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  2, NULL, 0
-#define PREGRP3   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  3, NULL, 0
-#define PREGRP4   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  4, NULL, 0
-#define PREGRP5   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  5, NULL, 0
-#define PREGRP6   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  6, NULL, 0
-#define PREGRP7   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  7, NULL, 0
-#define PREGRP8   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  8, NULL, 0
-#define PREGRP9   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  9, NULL, 0
-#define PREGRP10  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
-#define PREGRP11  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
-#define PREGRP12  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
-#define PREGRP13  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
-#define PREGRP14  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
-#define PREGRP15  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
-#define PREGRP16  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
-#define PREGRP17  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
-#define PREGRP18  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
-#define PREGRP19  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
-#define PREGRP20  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
-#define PREGRP21  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
-#define PREGRP22  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
-#define PREGRP23  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
-#define PREGRP24  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
-#define PREGRP25  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
-#define PREGRP26  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
-#define PREGRP27  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
-#define PREGRP28  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
-#define PREGRP29  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
-#define PREGRP30  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
-#define PREGRP31  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
-#define PREGRP32  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
-
-#define X86_64_0  NULL, NULL, X86_64_SPECIAL, NULL,  0, NULL, 0
-
-typedef void (*op_rtn) (int bytemode, int sizeflag);
-
-struct dis386 {
-  const char *name;
-  op_rtn op1;
-  int bytemode1;
-  op_rtn op2;
-  int bytemode2;
-  op_rtn op3;
-  int bytemode3;
-};
-
-/* Upper case letters in the instruction names here are macros.
-   'A' => print 'b' if no register operands or suffix_always is true
-   'B' => print 'b' if suffix_always is true
-   'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
-   .      size prefix
-   'E' => print 'e' if 32-bit form of jcxz
-   'F' => print 'w' or 'l' depending on address size prefix (loop insns)
-   'H' => print ",pt" or ",pn" branch hint
-   'I' => honor following macro letter even in Intel mode (implemented only
-   .      for some of the macro letters)
-   'J' => print 'l'
-   'L' => print 'l' if suffix_always is true
-   'N' => print 'n' if instruction has no wait "prefix"
-   'O' => print 'd', or 'o'
-   'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
-   .      or suffix_always is true.  print 'q' if rex prefix is present.
-   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
-   .      is true
-   'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
-   'S' => print 'w', 'l' or 'q' if suffix_always is true
-   'T' => print 'q' in 64bit mode and behave as 'P' otherwise
-   'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
-   'W' => print 'b' or 'w' ("w" or "de" in intel mode)
-   'X' => print 's', 'd' depending on data16 prefix (for XMM)
-   'Y' => 'q' if instruction has an REX 64bit overwrite prefix
-
-   Many of the above letters print nothing in Intel mode.  See "putop"
-   for the details.
-
-   Braces '{' and '}', and vertical bars '|', indicate alternative
-   mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
-   modes.  In cases where there are only two alternatives, the X86_64
-   instruction is reserved, and "(bad)" is printed.
-*/
-
-static const struct dis386 dis386[] = {
-  /* 00 */
-  { "addB",		Eb, Gb, XX },
-  { "addS",		Ev, Gv, XX },
-  { "addB",		Gb, Eb, XX },
-  { "addS",		Gv, Ev, XX },
-  { "addB",		AL, Ib, XX },
-  { "addS",		eAX, Iv, XX },
-  { "push{T|}",		es, XX, XX },
-  { "pop{T|}",		es, XX, XX },
-  /* 08 */
-  { "orB",		Eb, Gb, XX },
-  { "orS",		Ev, Gv, XX },
-  { "orB",		Gb, Eb, XX },
-  { "orS",		Gv, Ev, XX },
-  { "orB",		AL, Ib, XX },
-  { "orS",		eAX, Iv, XX },
-  { "push{T|}",		cs, XX, XX },
-  { "(bad)",		XX, XX, XX },	/* 0x0f extended opcode escape */
-  /* 10 */
-  { "adcB",		Eb, Gb, XX },
-  { "adcS",		Ev, Gv, XX },
-  { "adcB",		Gb, Eb, XX },
-  { "adcS",		Gv, Ev, XX },
-  { "adcB",		AL, Ib, XX },
-  { "adcS",		eAX, Iv, XX },
-  { "push{T|}",		ss, XX, XX },
-  { "popT|}",		ss, XX, XX },
-  /* 18 */
-  { "sbbB",		Eb, Gb, XX },
-  { "sbbS",		Ev, Gv, XX },
-  { "sbbB",		Gb, Eb, XX },
-  { "sbbS",		Gv, Ev, XX },
-  { "sbbB",		AL, Ib, XX },
-  { "sbbS",		eAX, Iv, XX },
-  { "push{T|}",		ds, XX, XX },
-  { "pop{T|}",		ds, XX, XX },
-  /* 20 */
-  { "andB",		Eb, Gb, XX },
-  { "andS",		Ev, Gv, XX },
-  { "andB",		Gb, Eb, XX },
-  { "andS",		Gv, Ev, XX },
-  { "andB",		AL, Ib, XX },
-  { "andS",		eAX, Iv, XX },
-  { "(bad)",		XX, XX, XX },	/* SEG ES prefix */
-  { "daa{|}",		XX, XX, XX },
-  /* 28 */
-  { "subB",		Eb, Gb, XX },
-  { "subS",		Ev, Gv, XX },
-  { "subB",		Gb, Eb, XX },
-  { "subS",		Gv, Ev, XX },
-  { "subB",		AL, Ib, XX },
-  { "subS",		eAX, Iv, XX },
-  { "(bad)",		XX, XX, XX },	/* SEG CS prefix */
-  { "das{|}",		XX, XX, XX },
-  /* 30 */
-  { "xorB",		Eb, Gb, XX },
-  { "xorS",		Ev, Gv, XX },
-  { "xorB",		Gb, Eb, XX },
-  { "xorS",		Gv, Ev, XX },
-  { "xorB",		AL, Ib, XX },
-  { "xorS",		eAX, Iv, XX },
-  { "(bad)",		XX, XX, XX },	/* SEG SS prefix */
-  { "aaa{|}",		XX, XX, XX },
-  /* 38 */
-  { "cmpB",		Eb, Gb, XX },
-  { "cmpS",		Ev, Gv, XX },
-  { "cmpB",		Gb, Eb, XX },
-  { "cmpS",		Gv, Ev, XX },
-  { "cmpB",		AL, Ib, XX },
-  { "cmpS",		eAX, Iv, XX },
-  { "(bad)",		XX, XX, XX },	/* SEG DS prefix */
-  { "aas{|}",		XX, XX, XX },
-  /* 40 */
-  { "inc{S|}",		RMeAX, XX, XX },
-  { "inc{S|}",		RMeCX, XX, XX },
-  { "inc{S|}",		RMeDX, XX, XX },
-  { "inc{S|}",		RMeBX, XX, XX },
-  { "inc{S|}",		RMeSP, XX, XX },
-  { "inc{S|}",		RMeBP, XX, XX },
-  { "inc{S|}",		RMeSI, XX, XX },
-  { "inc{S|}",		RMeDI, XX, XX },
-  /* 48 */
-  { "dec{S|}",		RMeAX, XX, XX },
-  { "dec{S|}",		RMeCX, XX, XX },
-  { "dec{S|}",		RMeDX, XX, XX },
-  { "dec{S|}",		RMeBX, XX, XX },
-  { "dec{S|}",		RMeSP, XX, XX },
-  { "dec{S|}",		RMeBP, XX, XX },
-  { "dec{S|}",		RMeSI, XX, XX },
-  { "dec{S|}",		RMeDI, XX, XX },
-  /* 50 */
-  { "pushS",		RMrAX, XX, XX },
-  { "pushS",		RMrCX, XX, XX },
-  { "pushS",		RMrDX, XX, XX },
-  { "pushS",		RMrBX, XX, XX },
-  { "pushS",		RMrSP, XX, XX },
-  { "pushS",		RMrBP, XX, XX },
-  { "pushS",		RMrSI, XX, XX },
-  { "pushS",		RMrDI, XX, XX },
-  /* 58 */
-  { "popS",		RMrAX, XX, XX },
-  { "popS",		RMrCX, XX, XX },
-  { "popS",		RMrDX, XX, XX },
-  { "popS",		RMrBX, XX, XX },
-  { "popS",		RMrSP, XX, XX },
-  { "popS",		RMrBP, XX, XX },
-  { "popS",		RMrSI, XX, XX },
-  { "popS",		RMrDI, XX, XX },
-  /* 60 */
-  { "pusha{P|}",	XX, XX, XX },
-  { "popa{P|}",		XX, XX, XX },
-  { "bound{S|}",	Gv, Ma, XX },
-  { X86_64_0 },
-  { "(bad)",		XX, XX, XX },	/* seg fs */
-  { "(bad)",		XX, XX, XX },	/* seg gs */
-  { "(bad)",		XX, XX, XX },	/* op size prefix */
-  { "(bad)",		XX, XX, XX },	/* adr size prefix */
-  /* 68 */
-  { "pushT",		Iq, XX, XX },
-  { "imulS",		Gv, Ev, Iv },
-  { "pushT",		sIb, XX, XX },
-  { "imulS",		Gv, Ev, sIb },
-  { "ins{b||b|}",	Yb, indirDX, XX },
-  { "ins{R||R|}",	Yv, indirDX, XX },
-  { "outs{b||b|}",	indirDX, Xb, XX },
-  { "outs{R||R|}",	indirDX, Xv, XX },
-  /* 70 */
-  { "joH",		Jb, XX, cond_jump_flag },
-  { "jnoH",		Jb, XX, cond_jump_flag },
-  { "jbH",		Jb, XX, cond_jump_flag },
-  { "jaeH",		Jb, XX, cond_jump_flag },
-  { "jeH",		Jb, XX, cond_jump_flag },
-  { "jneH",		Jb, XX, cond_jump_flag },
-  { "jbeH",		Jb, XX, cond_jump_flag },
-  { "jaH",		Jb, XX, cond_jump_flag },
-  /* 78 */
-  { "jsH",		Jb, XX, cond_jump_flag },
-  { "jnsH",		Jb, XX, cond_jump_flag },
-  { "jpH",		Jb, XX, cond_jump_flag },
-  { "jnpH",		Jb, XX, cond_jump_flag },
-  { "jlH",		Jb, XX, cond_jump_flag },
-  { "jgeH",		Jb, XX, cond_jump_flag },
-  { "jleH",		Jb, XX, cond_jump_flag },
-  { "jgH",		Jb, XX, cond_jump_flag },
-  /* 80 */
-  { GRP1b },
-  { GRP1S },
-  { "(bad)",		XX, XX, XX },
-  { GRP1Ss },
-  { "testB",		Eb, Gb, XX },
-  { "testS",		Ev, Gv, XX },
-  { "xchgB",		Eb, Gb, XX },
-  { "xchgS",		Ev, Gv, XX },
-  /* 88 */
-  { "movB",		Eb, Gb, XX },
-  { "movS",		Ev, Gv, XX },
-  { "movB",		Gb, Eb, XX },
-  { "movS",		Gv, Ev, XX },
-  { "movQ",		Sv, Sw, XX },
-  { "leaS",		Gv, M, XX },
-  { "movQ",		Sw, Sv, XX },
-  { "popU",		Ev, XX, XX },
-  /* 90 */
-  { "nop",		NOP_Fixup, 0, XX, XX },
-  { "xchgS",		RMeCX, eAX, XX },
-  { "xchgS",		RMeDX, eAX, XX },
-  { "xchgS",		RMeBX, eAX, XX },
-  { "xchgS",		RMeSP, eAX, XX },
-  { "xchgS",		RMeBP, eAX, XX },
-  { "xchgS",		RMeSI, eAX, XX },
-  { "xchgS",		RMeDI, eAX, XX },
-  /* 98 */
-  { "cW{tR||tR|}",	XX, XX, XX },
-  { "cR{tO||tO|}",	XX, XX, XX },
-  { "Jcall{T|}",	Ap, XX, XX },
-  { "(bad)",		XX, XX, XX },	/* fwait */
-  { "pushfT",		XX, XX, XX },
-  { "popfT",		XX, XX, XX },
-  { "sahf{|}",		XX, XX, XX },
-  { "lahf{|}",		XX, XX, XX },
-  /* a0 */
-  { "movB",		AL, Ob64, XX },
-  { "movS",		eAX, Ov64, XX },
-  { "movB",		Ob64, AL, XX },
-  { "movS",		Ov64, eAX, XX },
-  { "movs{b||b|}",	Yb, Xb, XX },
-  { "movs{R||R|}",	Yv, Xv, XX },
-  { "cmps{b||b|}",	Xb, Yb, XX },
-  { "cmps{R||R|}",	Xv, Yv, XX },
-  /* a8 */
-  { "testB",		AL, Ib, XX },
-  { "testS",		eAX, Iv, XX },
-  { "stosB",		Yb, AL, XX },
-  { "stosS",		Yv, eAX, XX },
-  { "lodsB",		AL, Xb, XX },
-  { "lodsS",		eAX, Xv, XX },
-  { "scasB",		AL, Yb, XX },
-  { "scasS",		eAX, Yv, XX },
-  /* b0 */
-  { "movB",		RMAL, Ib, XX },
-  { "movB",		RMCL, Ib, XX },
-  { "movB",		RMDL, Ib, XX },
-  { "movB",		RMBL, Ib, XX },
-  { "movB",		RMAH, Ib, XX },
-  { "movB",		RMCH, Ib, XX },
-  { "movB",		RMDH, Ib, XX },
-  { "movB",		RMBH, Ib, XX },
-  /* b8 */
-  { "movS",		RMeAX, Iv64, XX },
-  { "movS",		RMeCX, Iv64, XX },
-  { "movS",		RMeDX, Iv64, XX },
-  { "movS",		RMeBX, Iv64, XX },
-  { "movS",		RMeSP, Iv64, XX },
-  { "movS",		RMeBP, Iv64, XX },
-  { "movS",		RMeSI, Iv64, XX },
-  { "movS",		RMeDI, Iv64, XX },
-  /* c0 */
-  { GRP2b },
-  { GRP2S },
-  { "retT",		Iw, XX, XX },
-  { "retT",		XX, XX, XX },
-  { "les{S|}",		Gv, Mp, XX },
-  { "ldsS",		Gv, Mp, XX },
-  { "movA",		Eb, Ib, XX },
-  { "movQ",		Ev, Iv, XX },
-  /* c8 */
-  { "enterT",		Iw, Ib, XX },
-  { "leaveT",		XX, XX, XX },
-  { "lretP",		Iw, XX, XX },
-  { "lretP",		XX, XX, XX },
-  { "int3",		XX, XX, XX },
-  { "int",		Ib, XX, XX },
-  { "into{|}",		XX, XX, XX },
-  { "iretP",		XX, XX, XX },
-  /* d0 */
-  { GRP2b_one },
-  { GRP2S_one },
-  { GRP2b_cl },
-  { GRP2S_cl },
-  { "aam{|}",		sIb, XX, XX },
-  { "aad{|}",		sIb, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "xlat",		DSBX, XX, XX },
-  /* d8 */
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  /* e0 */
-  { "loopneFH",		Jb, XX, loop_jcxz_flag },
-  { "loopeFH",		Jb, XX, loop_jcxz_flag },
-  { "loopFH",		Jb, XX, loop_jcxz_flag },
-  { "jEcxzH",		Jb, XX, loop_jcxz_flag },
-  { "inB",		AL, Ib, XX },
-  { "inS",		eAX, Ib, XX },
-  { "outB",		Ib, AL, XX },
-  { "outS",		Ib, eAX, XX },
-  /* e8 */
-  { "callT",		Jv, XX, XX },
-  { "jmpT",		Jv, XX, XX },
-  { "Jjmp{T|}",		Ap, XX, XX },
-  { "jmp",		Jb, XX, XX },
-  { "inB",		AL, indirDX, XX },
-  { "inS",		eAX, indirDX, XX },
-  { "outB",		indirDX, AL, XX },
-  { "outS",		indirDX, eAX, XX },
-  /* f0 */
-  { "(bad)",		XX, XX, XX },	/* lock prefix */
-  { "icebp",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },	/* repne */
-  { "(bad)",		XX, XX, XX },	/* repz */
-  { "hlt",		XX, XX, XX },
-  { "cmc",		XX, XX, XX },
-  { GRP3b },
-  { GRP3S },
-  /* f8 */
-  { "clc",		XX, XX, XX },
-  { "stc",		XX, XX, XX },
-  { "cli",		XX, XX, XX },
-  { "sti",		XX, XX, XX },
-  { "cld",		XX, XX, XX },
-  { "std",		XX, XX, XX },
-  { GRP4 },
-  { GRP5 },
-};
-
-static const struct dis386 dis386_twobyte[] = {
-  /* 00 */
-  { GRP6 },
-  { GRP7 },
-  { "larS",		Gv, Ew, XX },
-  { "lslS",		Gv, Ew, XX },
-  { "(bad)",		XX, XX, XX },
-  { "syscall",		XX, XX, XX },
-  { "clts",		XX, XX, XX },
-  { "sysretP",		XX, XX, XX },
-  /* 08 */
-  { "invd",		XX, XX, XX },
-  { "wbinvd",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "ud2a",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { GRPAMD },
-  { "femms",		XX, XX, XX },
-  { "",			MX, EM, OPSUF }, /* See OP_3DNowSuffix.  */
-  /* 10 */
-  { PREGRP8 },
-  { PREGRP9 },
-  { PREGRP30 },
-  { "movlpX",		EX, XM, SIMD_Fixup, 'h' },
-  { "unpcklpX",		XM, EX, XX },
-  { "unpckhpX",		XM, EX, XX },
-  { PREGRP31 },
-  { "movhpX",		EX, XM, SIMD_Fixup, 'l' },
-  /* 18 */
-  { GRP14 },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  /* 20 */
-  { "movL",		Rm, Cm, XX },
-  { "movL",		Rm, Dm, XX },
-  { "movL",		Cm, Rm, XX },
-  { "movL",		Dm, Rm, XX },
-  { "movL",		Rd, Td, XX },
-  { "(bad)",		XX, XX, XX },
-  { "movL",		Td, Rd, XX },
-  { "(bad)",		XX, XX, XX },
-  /* 28 */
-  { "movapX",		XM, EX, XX },
-  { "movapX",		EX, XM, XX },
-  { PREGRP2 },
-  { "movntpX",		Ev, XM, XX },
-  { PREGRP4 },
-  { PREGRP3 },
-  { "ucomisX",		XM,EX, XX },
-  { "comisX",		XM,EX, XX },
-  /* 30 */
-  { "wrmsr",		XX, XX, XX },
-  { "rdtsc",		XX, XX, XX },
-  { "rdmsr",		XX, XX, XX },
-  { "rdpmc",		XX, XX, XX },
-  { "sysenter",		XX, XX, XX },
-  { "sysexit",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  /* 38 */
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  /* 40 */
-  { "cmovo",		Gv, Ev, XX },
-  { "cmovno",		Gv, Ev, XX },
-  { "cmovb",		Gv, Ev, XX },
-  { "cmovae",		Gv, Ev, XX },
-  { "cmove",		Gv, Ev, XX },
-  { "cmovne",		Gv, Ev, XX },
-  { "cmovbe",		Gv, Ev, XX },
-  { "cmova",		Gv, Ev, XX },
-  /* 48 */
-  { "cmovs",		Gv, Ev, XX },
-  { "cmovns",		Gv, Ev, XX },
-  { "cmovp",		Gv, Ev, XX },
-  { "cmovnp",		Gv, Ev, XX },
-  { "cmovl",		Gv, Ev, XX },
-  { "cmovge",		Gv, Ev, XX },
-  { "cmovle",		Gv, Ev, XX },
-  { "cmovg",		Gv, Ev, XX },
-  /* 50 */
-  { "movmskpX",		Gdq, XS, XX },
-  { PREGRP13 },
-  { PREGRP12 },
-  { PREGRP11 },
-  { "andpX",		XM, EX, XX },
-  { "andnpX",		XM, EX, XX },
-  { "orpX",		XM, EX, XX },
-  { "xorpX",		XM, EX, XX },
-  /* 58 */
-  { PREGRP0 },
-  { PREGRP10 },
-  { PREGRP17 },
-  { PREGRP16 },
-  { PREGRP14 },
-  { PREGRP7 },
-  { PREGRP5 },
-  { PREGRP6 },
-  /* 60 */
-  { "punpcklbw",	MX, EM, XX },
-  { "punpcklwd",	MX, EM, XX },
-  { "punpckldq",	MX, EM, XX },
-  { "packsswb",		MX, EM, XX },
-  { "pcmpgtb",		MX, EM, XX },
-  { "pcmpgtw",		MX, EM, XX },
-  { "pcmpgtd",		MX, EM, XX },
-  { "packuswb",		MX, EM, XX },
-  /* 68 */
-  { "punpckhbw",	MX, EM, XX },
-  { "punpckhwd",	MX, EM, XX },
-  { "punpckhdq",	MX, EM, XX },
-  { "packssdw",		MX, EM, XX },
-  { PREGRP26 },
-  { PREGRP24 },
-  { "movd",		MX, Edq, XX },
-  { PREGRP19 },
-  /* 70 */
-  { PREGRP22 },
-  { GRP10 },
-  { GRP11 },
-  { GRP12 },
-  { "pcmpeqb",		MX, EM, XX },
-  { "pcmpeqw",		MX, EM, XX },
-  { "pcmpeqd",		MX, EM, XX },
-  { "emms",		XX, XX, XX },
-  /* 78 */
-  { "vmread",		Em, Gm, XX },
-  { "vmwrite",		Gm, Em, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { PREGRP28 },
-  { PREGRP29 },
-  { PREGRP23 },
-  { PREGRP20 },
-  /* 80 */
-  { "joH",		Jv, XX, cond_jump_flag },
-  { "jnoH",		Jv, XX, cond_jump_flag },
-  { "jbH",		Jv, XX, cond_jump_flag },
-  { "jaeH",		Jv, XX, cond_jump_flag },
-  { "jeH",		Jv, XX, cond_jump_flag },
-  { "jneH",		Jv, XX, cond_jump_flag },
-  { "jbeH",		Jv, XX, cond_jump_flag },
-  { "jaH",		Jv, XX, cond_jump_flag },
-  /* 88 */
-  { "jsH",		Jv, XX, cond_jump_flag },
-  { "jnsH",		Jv, XX, cond_jump_flag },
-  { "jpH",		Jv, XX, cond_jump_flag },
-  { "jnpH",		Jv, XX, cond_jump_flag },
-  { "jlH",		Jv, XX, cond_jump_flag },
-  { "jgeH",		Jv, XX, cond_jump_flag },
-  { "jleH",		Jv, XX, cond_jump_flag },
-  { "jgH",		Jv, XX, cond_jump_flag },
-  /* 90 */
-  { "seto",		Eb, XX, XX },
-  { "setno",		Eb, XX, XX },
-  { "setb",		Eb, XX, XX },
-  { "setae",		Eb, XX, XX },
-  { "sete",		Eb, XX, XX },
-  { "setne",		Eb, XX, XX },
-  { "setbe",		Eb, XX, XX },
-  { "seta",		Eb, XX, XX },
-  /* 98 */
-  { "sets",		Eb, XX, XX },
-  { "setns",		Eb, XX, XX },
-  { "setp",		Eb, XX, XX },
-  { "setnp",		Eb, XX, XX },
-  { "setl",		Eb, XX, XX },
-  { "setge",		Eb, XX, XX },
-  { "setle",		Eb, XX, XX },
-  { "setg",		Eb, XX, XX },
-  /* a0 */
-  { "pushT",		fs, XX, XX },
-  { "popT",		fs, XX, XX },
-  { "cpuid",		XX, XX, XX },
-  { "btS",		Ev, Gv, XX },
-  { "shldS",		Ev, Gv, Ib },
-  { "shldS",		Ev, Gv, CL },
-  { GRPPADLCK2 },
-  { GRPPADLCK1 },
-  /* a8 */
-  { "pushT",		gs, XX, XX },
-  { "popT",		gs, XX, XX },
-  { "rsm",		XX, XX, XX },
-  { "btsS",		Ev, Gv, XX },
-  { "shrdS",		Ev, Gv, Ib },
-  { "shrdS",		Ev, Gv, CL },
-  { GRP13 },
-  { "imulS",		Gv, Ev, XX },
-  /* b0 */
-  { "cmpxchgB",		Eb, Gb, XX },
-  { "cmpxchgS",		Ev, Gv, XX },
-  { "lssS",		Gv, Mp, XX },
-  { "btrS",		Ev, Gv, XX },
-  { "lfsS",		Gv, Mp, XX },
-  { "lgsS",		Gv, Mp, XX },
-  { "movz{bR|x|bR|x}",	Gv, Eb, XX },
-  { "movz{wR|x|wR|x}",	Gv, Ew, XX }, /* yes, there really is movzww ! */
-  /* b8 */
-  { "(bad)",		XX, XX, XX },
-  { "ud2b",		XX, XX, XX },
-  { GRP8 },
-  { "btcS",		Ev, Gv, XX },
-  { "bsfS",		Gv, Ev, XX },
-  { "bsrS",		Gv, Ev, XX },
-  { "movs{bR|x|bR|x}",	Gv, Eb, XX },
-  { "movs{wR|x|wR|x}",	Gv, Ew, XX }, /* yes, there really is movsww ! */
-  /* c0 */
-  { "xaddB",		Eb, Gb, XX },
-  { "xaddS",		Ev, Gv, XX },
-  { PREGRP1 },
-  { "movntiS",		Ev, Gv, XX },
-  { "pinsrw",		MX, Edqw, Ib },
-  { "pextrw",		Gdq, MS, Ib },
-  { "shufpX",		XM, EX, Ib },
-  { GRP9 },
-  /* c8 */
-  { "bswap",		RMeAX, XX, XX },
-  { "bswap",		RMeCX, XX, XX },
-  { "bswap",		RMeDX, XX, XX },
-  { "bswap",		RMeBX, XX, XX },
-  { "bswap",		RMeSP, XX, XX },
-  { "bswap",		RMeBP, XX, XX },
-  { "bswap",		RMeSI, XX, XX },
-  { "bswap",		RMeDI, XX, XX },
-  /* d0 */
-  { PREGRP27 },
-  { "psrlw",		MX, EM, XX },
-  { "psrld",		MX, EM, XX },
-  { "psrlq",		MX, EM, XX },
-  { "paddq",		MX, EM, XX },
-  { "pmullw",		MX, EM, XX },
-  { PREGRP21 },
-  { "pmovmskb",		Gdq, MS, XX },
-  /* d8 */
-  { "psubusb",		MX, EM, XX },
-  { "psubusw",		MX, EM, XX },
-  { "pminub",		MX, EM, XX },
-  { "pand",		MX, EM, XX },
-  { "paddusb",		MX, EM, XX },
-  { "paddusw",		MX, EM, XX },
-  { "pmaxub",		MX, EM, XX },
-  { "pandn",		MX, EM, XX },
-  /* e0 */
-  { "pavgb",		MX, EM, XX },
-  { "psraw",		MX, EM, XX },
-  { "psrad",		MX, EM, XX },
-  { "pavgw",		MX, EM, XX },
-  { "pmulhuw",		MX, EM, XX },
-  { "pmulhw",		MX, EM, XX },
-  { PREGRP15 },
-  { PREGRP25 },
-  /* e8 */
-  { "psubsb",		MX, EM, XX },
-  { "psubsw",		MX, EM, XX },
-  { "pminsw",		MX, EM, XX },
-  { "por",		MX, EM, XX },
-  { "paddsb",		MX, EM, XX },
-  { "paddsw",		MX, EM, XX },
-  { "pmaxsw",		MX, EM, XX },
-  { "pxor",		MX, EM, XX },
-  /* f0 */
-  { PREGRP32 },
-  { "psllw",		MX, EM, XX },
-  { "pslld",		MX, EM, XX },
-  { "psllq",		MX, EM, XX },
-  { "pmuludq",		MX, EM, XX },
-  { "pmaddwd",		MX, EM, XX },
-  { "psadbw",		MX, EM, XX },
-  { PREGRP18 },
-  /* f8 */
-  { "psubb",		MX, EM, XX },
-  { "psubw",		MX, EM, XX },
-  { "psubd",		MX, EM, XX },
-  { "psubq",		MX, EM, XX },
-  { "paddb",		MX, EM, XX },
-  { "paddw",		MX, EM, XX },
-  { "paddd",		MX, EM, XX },
-  { "(bad)",		XX, XX, XX }
-};
-
-static const unsigned char onebyte_has_modrm[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
-  /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
-  /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
-  /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
-  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
-  /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
-  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
-  /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
-  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
-  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
-  /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
-  /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
-  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
-  /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-static const unsigned char twobyte_has_modrm[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
-  /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
-  /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
-  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
-  /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
-  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
-  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
-  /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
-  /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
-  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
-  /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
-  /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-static const unsigned char twobyte_uses_SSE_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
-  /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
-  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
-  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
-  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0  /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-static char obuf[100];
-static char *obufp;
-static char scratchbuf[100];
-static unsigned char *start_codep;
-static unsigned char *insn_codep;
-static unsigned char *codep;
-static disassemble_info *the_info;
-static int mod;
-static int rm;
-static int reg;
-static unsigned char need_modrm;
-
-/* If we are accessing mod/rm/reg without need_modrm set, then the
-   values are stale.  Hitting this abort likely indicates that you
-   need to update onebyte_has_modrm or twobyte_has_modrm.  */
-#define MODRM_CHECK  if (!need_modrm) abort ()
-
-static const char **names64;
-static const char **names32;
-static const char **names16;
-static const char **names8;
-static const char **names8rex;
-static const char **names_seg;
-static const char **index16;
-
-static const char *intel_names64[] = {
-  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
-  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
-};
-static const char *intel_names32[] = {
-  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
-  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
-};
-static const char *intel_names16[] = {
-  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
-  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
-};
-static const char *intel_names8[] = {
-  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
-};
-static const char *intel_names8rex[] = {
-  "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
-  "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
-};
-static const char *intel_names_seg[] = {
-  "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
-};
-static const char *intel_index16[] = {
-  "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
-};
-
-static const char *att_names64[] = {
-  "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
-  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
-};
-static const char *att_names32[] = {
-  "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
-  "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
-};
-static const char *att_names16[] = {
-  "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
-  "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
-};
-static const char *att_names8[] = {
-  "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
-};
-static const char *att_names8rex[] = {
-  "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
-  "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
-};
-static const char *att_names_seg[] = {
-  "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
-};
-static const char *att_index16[] = {
-  "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
-};
-
-static const struct dis386 grps[][8] = {
-  /* GRP1b */
-  {
-    { "addA",	Eb, Ib, XX },
-    { "orA",	Eb, Ib, XX },
-    { "adcA",	Eb, Ib, XX },
-    { "sbbA",	Eb, Ib, XX },
-    { "andA",	Eb, Ib, XX },
-    { "subA",	Eb, Ib, XX },
-    { "xorA",	Eb, Ib, XX },
-    { "cmpA",	Eb, Ib, XX }
-  },
-  /* GRP1S */
-  {
-    { "addQ",	Ev, Iv, XX },
-    { "orQ",	Ev, Iv, XX },
-    { "adcQ",	Ev, Iv, XX },
-    { "sbbQ",	Ev, Iv, XX },
-    { "andQ",	Ev, Iv, XX },
-    { "subQ",	Ev, Iv, XX },
-    { "xorQ",	Ev, Iv, XX },
-    { "cmpQ",	Ev, Iv, XX }
-  },
-  /* GRP1Ss */
-  {
-    { "addQ",	Ev, sIb, XX },
-    { "orQ",	Ev, sIb, XX },
-    { "adcQ",	Ev, sIb, XX },
-    { "sbbQ",	Ev, sIb, XX },
-    { "andQ",	Ev, sIb, XX },
-    { "subQ",	Ev, sIb, XX },
-    { "xorQ",	Ev, sIb, XX },
-    { "cmpQ",	Ev, sIb, XX }
-  },
-  /* GRP2b */
-  {
-    { "rolA",	Eb, Ib, XX },
-    { "rorA",	Eb, Ib, XX },
-    { "rclA",	Eb, Ib, XX },
-    { "rcrA",	Eb, Ib, XX },
-    { "shlA",	Eb, Ib, XX },
-    { "shrA",	Eb, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarA",	Eb, Ib, XX },
-  },
-  /* GRP2S */
-  {
-    { "rolQ",	Ev, Ib, XX },
-    { "rorQ",	Ev, Ib, XX },
-    { "rclQ",	Ev, Ib, XX },
-    { "rcrQ",	Ev, Ib, XX },
-    { "shlQ",	Ev, Ib, XX },
-    { "shrQ",	Ev, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarQ",	Ev, Ib, XX },
-  },
-  /* GRP2b_one */
-  {
-    { "rolA",	Eb, I1, XX },
-    { "rorA",	Eb, I1, XX },
-    { "rclA",	Eb, I1, XX },
-    { "rcrA",	Eb, I1, XX },
-    { "shlA",	Eb, I1, XX },
-    { "shrA",	Eb, I1, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarA",	Eb, I1, XX },
-  },
-  /* GRP2S_one */
-  {
-    { "rolQ",	Ev, I1, XX },
-    { "rorQ",	Ev, I1, XX },
-    { "rclQ",	Ev, I1, XX },
-    { "rcrQ",	Ev, I1, XX },
-    { "shlQ",	Ev, I1, XX },
-    { "shrQ",	Ev, I1, XX },
-    { "(bad)",	XX, XX, XX},
-    { "sarQ",	Ev, I1, XX },
-  },
-  /* GRP2b_cl */
-  {
-    { "rolA",	Eb, CL, XX },
-    { "rorA",	Eb, CL, XX },
-    { "rclA",	Eb, CL, XX },
-    { "rcrA",	Eb, CL, XX },
-    { "shlA",	Eb, CL, XX },
-    { "shrA",	Eb, CL, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarA",	Eb, CL, XX },
-  },
-  /* GRP2S_cl */
-  {
-    { "rolQ",	Ev, CL, XX },
-    { "rorQ",	Ev, CL, XX },
-    { "rclQ",	Ev, CL, XX },
-    { "rcrQ",	Ev, CL, XX },
-    { "shlQ",	Ev, CL, XX },
-    { "shrQ",	Ev, CL, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarQ",	Ev, CL, XX }
-  },
-  /* GRP3b */
-  {
-    { "testA",	Eb, Ib, XX },
-    { "(bad)",	Eb, XX, XX },
-    { "notA",	Eb, XX, XX },
-    { "negA",	Eb, XX, XX },
-    { "mulA",	Eb, XX, XX },	/* Don't print the implicit %al register,  */
-    { "imulA",	Eb, XX, XX },	/* to distinguish these opcodes from other */
-    { "divA",	Eb, XX, XX },	/* mul/imul opcodes.  Do the same for div  */
-    { "idivA",	Eb, XX, XX }	/* and idiv for consistency.		   */
-  },
-  /* GRP3S */
-  {
-    { "testQ",	Ev, Iv, XX },
-    { "(bad)",	XX, XX, XX },
-    { "notQ",	Ev, XX, XX },
-    { "negQ",	Ev, XX, XX },
-    { "mulQ",	Ev, XX, XX },	/* Don't print the implicit register.  */
-    { "imulQ",	Ev, XX, XX },
-    { "divQ",	Ev, XX, XX },
-    { "idivQ",	Ev, XX, XX },
-  },
-  /* GRP4 */
-  {
-    { "incA",	Eb, XX, XX },
-    { "decA",	Eb, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRP5 */
-  {
-    { "incQ",	Ev, XX, XX },
-    { "decQ",	Ev, XX, XX },
-    { "callT",	indirEv, XX, XX },
-    { "JcallT",	indirEp, XX, XX },
-    { "jmpT",	indirEv, XX, XX },
-    { "JjmpT",	indirEp, XX, XX },
-    { "pushU",	Ev, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRP6 */
-  {
-    { "sldtQ",	Ev, XX, XX },
-    { "strQ",	Ev, XX, XX },
-    { "lldt",	Ew, XX, XX },
-    { "ltr",	Ew, XX, XX },
-    { "verr",	Ew, XX, XX },
-    { "verw",	Ew, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX }
-  },
-  /* GRP7 */
-  {
-    { "sgdtIQ", VMX_Fixup, 0, XX, XX },
-    { "sidtIQ", PNI_Fixup, 0, XX, XX },
-    { "lgdt{Q|Q||}",	 M, XX, XX },
-    { "lidt{Q|Q||}",	 SVME_Fixup, 0, XX, XX },
-    { "smswQ",	Ev, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "lmsw",	Ew, XX, XX },
-    { "invlpg",	INVLPG_Fixup, w_mode, XX, XX },
-  },
-  /* GRP8 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "btQ",	Ev, Ib, XX },
-    { "btsQ",	Ev, Ib, XX },
-    { "btrQ",	Ev, Ib, XX },
-    { "btcQ",	Ev, Ib, XX },
-  },
-  /* GRP9 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "cmpxchg8b", Eq, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "",	VM, XX, XX },		/* See OP_VMX.  */
-    { "vmptrst", Eq, XX, XX },
-  },
-  /* GRP10 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psrlw",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psraw",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psllw",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRP11 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psrld",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psrad",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "pslld",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRP12 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psrlq",	MS, Ib, XX },
-    { "psrldq",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psllq",	MS, Ib, XX },
-    { "pslldq",	MS, Ib, XX },
-  },
-  /* GRP13 */
-  {
-    { "fxsave", Ev, XX, XX },
-    { "fxrstor", Ev, XX, XX },
-    { "ldmxcsr", Ev, XX, XX },
-    { "stmxcsr", Ev, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "lfence", OP_0fae, 0, XX, XX },
-    { "mfence", OP_0fae, 0, XX, XX },
-    { "clflush", OP_0fae, 0, XX, XX },
-  },
-  /* GRP14 */
-  {
-    { "prefetchnta", Ev, XX, XX },
-    { "prefetcht0", Ev, XX, XX },
-    { "prefetcht1", Ev, XX, XX },
-    { "prefetcht2", Ev, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRPAMD */
-  {
-    { "prefetch", Eb, XX, XX },
-    { "prefetchw", Eb, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRPPADLCK1 */
-  {
-    { "xstore-rng", OP_0f07, 0, XX, XX },
-    { "xcrypt-ecb", OP_0f07, 0, XX, XX },
-    { "xcrypt-cbc", OP_0f07, 0, XX, XX },
-    { "xcrypt-ctr", OP_0f07, 0, XX, XX },
-    { "xcrypt-cfb", OP_0f07, 0, XX, XX },
-    { "xcrypt-ofb", OP_0f07, 0, XX, XX },
-    { "(bad)",	OP_0f07, 0, XX, XX },
-    { "(bad)",	OP_0f07, 0, XX, XX },
-  },
-  /* GRPPADLCK2 */
-  {
-    { "montmul", OP_0f07, 0, XX, XX },
-    { "xsha1",   OP_0f07, 0, XX, XX },
-    { "xsha256", OP_0f07, 0, XX, XX },
-    { "(bad)",	 OP_0f07, 0, XX, XX },
-    { "(bad)",   OP_0f07, 0, XX, XX },
-    { "(bad)",   OP_0f07, 0, XX, XX },
-    { "(bad)",	 OP_0f07, 0, XX, XX },
-    { "(bad)",	 OP_0f07, 0, XX, XX },
-  }
-};
-
-static const struct dis386 prefix_user_table[][4] = {
-  /* PREGRP0 */
-  {
-    { "addps", XM, EX, XX },
-    { "addss", XM, EX, XX },
-    { "addpd", XM, EX, XX },
-    { "addsd", XM, EX, XX },
-  },
-  /* PREGRP1 */
-  {
-    { "", XM, EX, OPSIMD },	/* See OP_SIMD_SUFFIX.  */
-    { "", XM, EX, OPSIMD },
-    { "", XM, EX, OPSIMD },
-    { "", XM, EX, OPSIMD },
-  },
-  /* PREGRP2 */
-  {
-    { "cvtpi2ps", XM, EM, XX },
-    { "cvtsi2ssY", XM, Ev, XX },
-    { "cvtpi2pd", XM, EM, XX },
-    { "cvtsi2sdY", XM, Ev, XX },
-  },
-  /* PREGRP3 */
-  {
-    { "cvtps2pi", MX, EX, XX },
-    { "cvtss2siY", Gv, EX, XX },
-    { "cvtpd2pi", MX, EX, XX },
-    { "cvtsd2siY", Gv, EX, XX },
-  },
-  /* PREGRP4 */
-  {
-    { "cvttps2pi", MX, EX, XX },
-    { "cvttss2siY", Gv, EX, XX },
-    { "cvttpd2pi", MX, EX, XX },
-    { "cvttsd2siY", Gv, EX, XX },
-  },
-  /* PREGRP5 */
-  {
-    { "divps", XM, EX, XX },
-    { "divss", XM, EX, XX },
-    { "divpd", XM, EX, XX },
-    { "divsd", XM, EX, XX },
-  },
-  /* PREGRP6 */
-  {
-    { "maxps", XM, EX, XX },
-    { "maxss", XM, EX, XX },
-    { "maxpd", XM, EX, XX },
-    { "maxsd", XM, EX, XX },
-  },
-  /* PREGRP7 */
-  {
-    { "minps", XM, EX, XX },
-    { "minss", XM, EX, XX },
-    { "minpd", XM, EX, XX },
-    { "minsd", XM, EX, XX },
-  },
-  /* PREGRP8 */
-  {
-    { "movups", XM, EX, XX },
-    { "movss", XM, EX, XX },
-    { "movupd", XM, EX, XX },
-    { "movsd", XM, EX, XX },
-  },
-  /* PREGRP9 */
-  {
-    { "movups", EX, XM, XX },
-    { "movss", EX, XM, XX },
-    { "movupd", EX, XM, XX },
-    { "movsd", EX, XM, XX },
-  },
-  /* PREGRP10 */
-  {
-    { "mulps", XM, EX, XX },
-    { "mulss", XM, EX, XX },
-    { "mulpd", XM, EX, XX },
-    { "mulsd", XM, EX, XX },
-  },
-  /* PREGRP11 */
-  {
-    { "rcpps", XM, EX, XX },
-    { "rcpss", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP12 */
-  {
-    { "rsqrtps", XM, EX, XX },
-    { "rsqrtss", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP13 */
-  {
-    { "sqrtps", XM, EX, XX },
-    { "sqrtss", XM, EX, XX },
-    { "sqrtpd", XM, EX, XX },
-    { "sqrtsd", XM, EX, XX },
-  },
-  /* PREGRP14 */
-  {
-    { "subps", XM, EX, XX },
-    { "subss", XM, EX, XX },
-    { "subpd", XM, EX, XX },
-    { "subsd", XM, EX, XX },
-  },
-  /* PREGRP15 */
-  {
-    { "(bad)", XM, EX, XX },
-    { "cvtdq2pd", XM, EX, XX },
-    { "cvttpd2dq", XM, EX, XX },
-    { "cvtpd2dq", XM, EX, XX },
-  },
-  /* PREGRP16 */
-  {
-    { "cvtdq2ps", XM, EX, XX },
-    { "cvttps2dq",XM, EX, XX },
-    { "cvtps2dq",XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP17 */
-  {
-    { "cvtps2pd", XM, EX, XX },
-    { "cvtss2sd", XM, EX, XX },
-    { "cvtpd2ps", XM, EX, XX },
-    { "cvtsd2ss", XM, EX, XX },
-  },
-  /* PREGRP18 */
-  {
-    { "maskmovq", MX, MS, XX },
-    { "(bad)", XM, EX, XX },
-    { "maskmovdqu", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP19 */
-  {
-    { "movq", MX, EM, XX },
-    { "movdqu", XM, EX, XX },
-    { "movdqa", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP20 */
-  {
-    { "movq", EM, MX, XX },
-    { "movdqu", EX, XM, XX },
-    { "movdqa", EX, XM, XX },
-    { "(bad)", EX, XM, XX },
-  },
-  /* PREGRP21 */
-  {
-    { "(bad)", EX, XM, XX },
-    { "movq2dq", XM, MS, XX },
-    { "movq", EX, XM, XX },
-    { "movdq2q", MX, XS, XX },
-  },
-  /* PREGRP22 */
-  {
-    { "pshufw", MX, EM, Ib },
-    { "pshufhw", XM, EX, Ib },
-    { "pshufd", XM, EX, Ib },
-    { "pshuflw", XM, EX, Ib },
-  },
-  /* PREGRP23 */
-  {
-    { "movd", Edq, MX, XX },
-    { "movq", XM, EX, XX },
-    { "movd", Edq, XM, XX },
-    { "(bad)", Ed, XM, XX },
-  },
-  /* PREGRP24 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "punpckhqdq", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP25 */
-  {
-    { "movntq", EM, MX, XX },
-    { "(bad)", EM, XM, XX },
-    { "movntdq", EM, XM, XX },
-    { "(bad)", EM, XM, XX },
-  },
-  /* PREGRP26 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "punpcklqdq", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP27 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "addsubpd", XM, EX, XX },
-    { "addsubps", XM, EX, XX },
-  },
-  /* PREGRP28 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "haddpd", XM, EX, XX },
-    { "haddps", XM, EX, XX },
-  },
-  /* PREGRP29 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "hsubpd", XM, EX, XX },
-    { "hsubps", XM, EX, XX },
-  },
-  /* PREGRP30 */
-  {
-    { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
-    { "movsldup", XM, EX, XX },
-    { "movlpd", XM, EX, XX },
-    { "movddup", XM, EX, XX },
-  },
-  /* PREGRP31 */
-  {
-    { "movhpX", XM, EX, SIMD_Fixup, 'l' },
-    { "movshdup", XM, EX, XX },
-    { "movhpd", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP32 */
-  {
-    { "(bad)", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "lddqu", XM, M, XX },
-  },
-};
-
-static const struct dis386 x86_64_table[][2] = {
-  {
-    { "arpl", Ew, Gw, XX },
-    { "movs{||lq|xd}", Gv, Ed, XX },
-  },
-};
-
-#ifdef __KERNEL__
-#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>"
-#else	/* __KERNEL__ */
-#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
-#endif	/* __KERNEL__ */
-
-static void
-ckprefix (void)
-{
-  int newrex;
-  rex = 0;
-  prefixes = 0;
-  used_prefixes = 0;
-  rex_used = 0;
-  while (1)
-    {
-      FETCH_DATA (the_info, codep + 1);
-      newrex = 0;
-      switch (*codep)
-	{
-	/* REX prefixes family.  */
-	case 0x40:
-	case 0x41:
-	case 0x42:
-	case 0x43:
-	case 0x44:
-	case 0x45:
-	case 0x46:
-	case 0x47:
-	case 0x48:
-	case 0x49:
-	case 0x4a:
-	case 0x4b:
-	case 0x4c:
-	case 0x4d:
-	case 0x4e:
-	case 0x4f:
-	    if (mode_64bit)
-	      newrex = *codep;
-	    else
-	      return;
-	  break;
-	case 0xf3:
-	  prefixes |= PREFIX_REPZ;
-	  break;
-	case 0xf2:
-	  prefixes |= PREFIX_REPNZ;
-	  break;
-	case 0xf0:
-	  prefixes |= PREFIX_LOCK;
-	  break;
-	case 0x2e:
-	  prefixes |= PREFIX_CS;
-	  break;
-	case 0x36:
-	  prefixes |= PREFIX_SS;
-	  break;
-	case 0x3e:
-	  prefixes |= PREFIX_DS;
-	  break;
-	case 0x26:
-	  prefixes |= PREFIX_ES;
-	  break;
-	case 0x64:
-	  prefixes |= PREFIX_FS;
-	  break;
-	case 0x65:
-	  prefixes |= PREFIX_GS;
-	  break;
-	case 0x66:
-	  prefixes |= PREFIX_DATA;
-	  break;
-	case 0x67:
-	  prefixes |= PREFIX_ADDR;
-	  break;
-	case FWAIT_OPCODE:
-	  /* fwait is really an instruction.  If there are prefixes
-	     before the fwait, they belong to the fwait, *not* to the
-	     following instruction.  */
-	  if (prefixes)
-	    {
-	      prefixes |= PREFIX_FWAIT;
-	      codep++;
-	      return;
-	    }
-	  prefixes = PREFIX_FWAIT;
-	  break;
-	default:
-	  return;
-	}
-      /* Rex is ignored when followed by another prefix.  */
-      if (rex)
-	{
-	  oappend (prefix_name (rex, 0));
-	  oappend (" ");
-	}
-      rex = newrex;
-      codep++;
-    }
-}
-
-/* Return the name of the prefix byte PREF, or NULL if PREF is not a
-   prefix byte.  */
-
-static const char *
-prefix_name (int pref, int sizeflag)
-{
-  switch (pref)
-    {
-    /* REX prefixes family.  */
-    case 0x40:
-      return "rex";
-    case 0x41:
-      return "rexZ";
-    case 0x42:
-      return "rexY";
-    case 0x43:
-      return "rexYZ";
-    case 0x44:
-      return "rexX";
-    case 0x45:
-      return "rexXZ";
-    case 0x46:
-      return "rexXY";
-    case 0x47:
-      return "rexXYZ";
-    case 0x48:
-      return "rex64";
-    case 0x49:
-      return "rex64Z";
-    case 0x4a:
-      return "rex64Y";
-    case 0x4b:
-      return "rex64YZ";
-    case 0x4c:
-      return "rex64X";
-    case 0x4d:
-      return "rex64XZ";
-    case 0x4e:
-      return "rex64XY";
-    case 0x4f:
-      return "rex64XYZ";
-    case 0xf3:
-      return "repz";
-    case 0xf2:
-      return "repnz";
-    case 0xf0:
-      return "lock";
-    case 0x2e:
-      return "cs";
-    case 0x36:
-      return "ss";
-    case 0x3e:
-      return "ds";
-    case 0x26:
-      return "es";
-    case 0x64:
-      return "fs";
-    case 0x65:
-      return "gs";
-    case 0x66:
-      return (sizeflag & DFLAG) ? "data16" : "data32";
-    case 0x67:
-      if (mode_64bit)
-	return (sizeflag & AFLAG) ? "addr32" : "addr64";
-      else
-	return (sizeflag & AFLAG) ? "addr16" : "addr32";
-    case FWAIT_OPCODE:
-      return "fwait";
-    default:
-      return NULL;
-    }
-}
-
-static char op1out[100], op2out[100], op3out[100];
-static int op_ad, op_index[3];
-static int two_source_ops;
-static bfd_vma op_address[3];
-static bfd_vma op_riprel[3];
-static bfd_vma start_pc;
-
-/*
- *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
- *   (see topic "Redundant prefixes" in the "Differences from 8086"
- *   section of the "Virtual 8086 Mode" chapter.)
- * 'pc' should be the address of this instruction, it will
- *   be used to print the target address if this is a relative jump or call
- * The function returns the length of this instruction in bytes.
- */
-
-static char intel_syntax;
-static char open_char;
-static char close_char;
-static char separator_char;
-static char scale_char;
-
-/* Here for backwards compatibility.  When gdb stops using
-   print_insn_i386_att and print_insn_i386_intel these functions can
-   disappear, and print_insn_i386 be merged into print_insn.  */
-int
-print_insn_i386_att (bfd_vma pc, disassemble_info *info)
-{
-  intel_syntax = 0;
-
-  return print_insn (pc, info);
-}
-
-int
-print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
-{
-  intel_syntax = 1;
-
-  return print_insn (pc, info);
-}
-
-int
-print_insn_i386 (bfd_vma pc, disassemble_info *info)
-{
-  intel_syntax = -1;
-
-  return print_insn (pc, info);
-}
-
-static int
-print_insn (bfd_vma pc, disassemble_info *info)
-{
-  const struct dis386 *dp;
-  int i;
-  char *first, *second, *third;
-  int needcomma;
-  unsigned char uses_SSE_prefix, uses_LOCK_prefix;
-  int sizeflag;
-  const char *p;
-  struct dis_private priv;
-
-  mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
-		|| info->mach == bfd_mach_x86_64);
-
-  if (intel_syntax == (char) -1)
-    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
-		    || info->mach == bfd_mach_x86_64_intel_syntax);
-
-  if (info->mach == bfd_mach_i386_i386
-      || info->mach == bfd_mach_x86_64
-      || info->mach == bfd_mach_i386_i386_intel_syntax
-      || info->mach == bfd_mach_x86_64_intel_syntax)
-    priv.orig_sizeflag = AFLAG | DFLAG;
-  else if (info->mach == bfd_mach_i386_i8086)
-    priv.orig_sizeflag = 0;
-  else
-    abort ();
-
-  for (p = info->disassembler_options; p != NULL; )
-    {
-      if (strncmp (p, "x86-64", 6) == 0)
-	{
-	  mode_64bit = 1;
-	  priv.orig_sizeflag = AFLAG | DFLAG;
-	}
-      else if (strncmp (p, "i386", 4) == 0)
-	{
-	  mode_64bit = 0;
-	  priv.orig_sizeflag = AFLAG | DFLAG;
-	}
-      else if (strncmp (p, "i8086", 5) == 0)
-	{
-	  mode_64bit = 0;
-	  priv.orig_sizeflag = 0;
-	}
-      else if (strncmp (p, "intel", 5) == 0)
-	{
-	  intel_syntax = 1;
-	}
-      else if (strncmp (p, "att", 3) == 0)
-	{
-	  intel_syntax = 0;
-	}
-      else if (strncmp (p, "addr", 4) == 0)
-	{
-	  if (p[4] == '1' && p[5] == '6')
-	    priv.orig_sizeflag &= ~AFLAG;
-	  else if (p[4] == '3' && p[5] == '2')
-	    priv.orig_sizeflag |= AFLAG;
-	}
-      else if (strncmp (p, "data", 4) == 0)
-	{
-	  if (p[4] == '1' && p[5] == '6')
-	    priv.orig_sizeflag &= ~DFLAG;
-	  else if (p[4] == '3' && p[5] == '2')
-	    priv.orig_sizeflag |= DFLAG;
-	}
-      else if (strncmp (p, "suffix", 6) == 0)
-	priv.orig_sizeflag |= SUFFIX_ALWAYS;
-
-      p = strchr (p, ',');
-      if (p != NULL)
-	p++;
-    }
-
-  if (intel_syntax)
-    {
-      names64 = intel_names64;
-      names32 = intel_names32;
-      names16 = intel_names16;
-      names8 = intel_names8;
-      names8rex = intel_names8rex;
-      names_seg = intel_names_seg;
-      index16 = intel_index16;
-      open_char = '[';
-      close_char = ']';
-      separator_char = '+';
-      scale_char = '*';
-    }
-  else
-    {
-      names64 = att_names64;
-      names32 = att_names32;
-      names16 = att_names16;
-      names8 = att_names8;
-      names8rex = att_names8rex;
-      names_seg = att_names_seg;
-      index16 = att_index16;
-      open_char = '(';
-      close_char =  ')';
-      separator_char = ',';
-      scale_char = ',';
-    }
-
-  /* The output looks better if we put 7 bytes on a line, since that
-     puts most long word instructions on a single line.  */
-  info->bytes_per_line = 7;
-
-  info->private_data = &priv;
-  priv.max_fetched = priv.the_buffer;
-  priv.insn_start = pc;
-
-  obuf[0] = 0;
-  op1out[0] = 0;
-  op2out[0] = 0;
-  op3out[0] = 0;
-
-  op_index[0] = op_index[1] = op_index[2] = -1;
-
-  the_info = info;
-  start_pc = pc;
-  start_codep = priv.the_buffer;
-  codep = priv.the_buffer;
-
-#ifndef __KERNEL__
-  if (setjmp (priv.bailout) != 0)
-    {
-      const char *name;
-
-      /* Getting here means we tried for data but didn't get it.  That
-	 means we have an incomplete instruction of some sort.  Just
-	 print the first byte as a prefix or a .byte pseudo-op.  */
-      if (codep > priv.the_buffer)
-	{
-	  name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
-	  if (name != NULL)
-	    (*info->fprintf_func) (info->stream, "%s", name);
-	  else
-	    {
-	      /* Just print the first byte as a .byte instruction.  */
-	      (*info->fprintf_func) (info->stream, ".byte 0x%x",
-				     (unsigned int) priv.the_buffer[0]);
-	    }
-
-	  return 1;
-	}
-
-      return -1;
-    }
-#endif	/* __KERNEL__ */
-
-  obufp = obuf;
-  ckprefix ();
-
-  insn_codep = codep;
-  sizeflag = priv.orig_sizeflag;
-
-  FETCH_DATA (info, codep + 1);
-  two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
-
-  if ((prefixes & PREFIX_FWAIT)
-      && ((*codep < 0xd8) || (*codep > 0xdf)))
-    {
-      const char *name;
-
-      /* fwait not followed by floating point instruction.  Print the
-	 first prefix, which is probably fwait itself.  */
-      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
-      if (name == NULL)
-	name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s", name);
-      return 1;
-    }
-
-  if (*codep == 0x0f)
-    {
-      FETCH_DATA (info, codep + 2);
-      dp = &dis386_twobyte[*++codep];
-      need_modrm = twobyte_has_modrm[*codep];
-      uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
-      uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
-    }
-  else
-    {
-      dp = &dis386[*codep];
-      need_modrm = onebyte_has_modrm[*codep];
-      uses_SSE_prefix = 0;
-      uses_LOCK_prefix = 0;
-    }
-  codep++;
-
-  if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
-    {
-      oappend ("repz ");
-      used_prefixes |= PREFIX_REPZ;
-    }
-  if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
-    {
-      oappend ("repnz ");
-      used_prefixes |= PREFIX_REPNZ;
-    }
-  if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
-    {
-      oappend ("lock ");
-      used_prefixes |= PREFIX_LOCK;
-    }
-
-  if (prefixes & PREFIX_ADDR)
-    {
-      sizeflag ^= AFLAG;
-      if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
-	{
-	  if ((sizeflag & AFLAG) || mode_64bit)
-	    oappend ("addr32 ");
-	  else
-	    oappend ("addr16 ");
-	  used_prefixes |= PREFIX_ADDR;
-	}
-    }
-
-  if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
-    {
-      sizeflag ^= DFLAG;
-      if (dp->bytemode3 == cond_jump_mode
-	  && dp->bytemode1 == v_mode
-	  && !intel_syntax)
-	{
-	  if (sizeflag & DFLAG)
-	    oappend ("data32 ");
-	  else
-	    oappend ("data16 ");
-	  used_prefixes |= PREFIX_DATA;
-	}
-    }
-
-  if (need_modrm)
-    {
-      FETCH_DATA (info, codep + 1);
-      mod = (*codep >> 6) & 3;
-      reg = (*codep >> 3) & 7;
-      rm = *codep & 7;
-    }
-
-  if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
-    {
-      dofloat (sizeflag);
-    }
-  else
-    {
-      int index;
-      if (dp->name == NULL)
-	{
-	  switch (dp->bytemode1)
-	    {
-	    case USE_GROUPS:
-	      dp = &grps[dp->bytemode2][reg];
-	      break;
-
-	    case USE_PREFIX_USER_TABLE:
-	      index = 0;
-	      used_prefixes |= (prefixes & PREFIX_REPZ);
-	      if (prefixes & PREFIX_REPZ)
-		index = 1;
-	      else
-		{
-		  used_prefixes |= (prefixes & PREFIX_DATA);
-		  if (prefixes & PREFIX_DATA)
-		    index = 2;
-		  else
-		    {
-		      used_prefixes |= (prefixes & PREFIX_REPNZ);
-		      if (prefixes & PREFIX_REPNZ)
-			index = 3;
-		    }
-		}
-	      dp = &prefix_user_table[dp->bytemode2][index];
-	      break;
-
-	    case X86_64_SPECIAL:
-	      dp = &x86_64_table[dp->bytemode2][mode_64bit];
-	      break;
-
-	    default:
-	      oappend (INTERNAL_DISASSEMBLER_ERROR);
-	      break;
-	    }
-	}
-
-      if (putop (dp->name, sizeflag) == 0)
-	{
-	  obufp = op1out;
-	  op_ad = 2;
-	  if (dp->op1)
-	    (*dp->op1) (dp->bytemode1, sizeflag);
-
-	  obufp = op2out;
-	  op_ad = 1;
-	  if (dp->op2)
-	    (*dp->op2) (dp->bytemode2, sizeflag);
-
-	  obufp = op3out;
-	  op_ad = 0;
-	  if (dp->op3)
-	    (*dp->op3) (dp->bytemode3, sizeflag);
-	}
-    }
-
-  /* See if any prefixes were not used.  If so, print the first one
-     separately.  If we don't do this, we'll wind up printing an
-     instruction stream which does not precisely correspond to the
-     bytes we are disassembling.  */
-  if ((prefixes & ~used_prefixes) != 0)
-    {
-      const char *name;
-
-      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
-      if (name == NULL)
-	name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s", name);
-      return 1;
-    }
-  if (rex & ~rex_used)
-    {
-      const char *name;
-      name = prefix_name (rex | 0x40, priv.orig_sizeflag);
-      if (name == NULL)
-	name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s ", name);
-    }
-
-  obufp = obuf + strlen (obuf);
-  for (i = strlen (obuf); i < 6; i++)
-    oappend (" ");
-  oappend (" ");
-  (*info->fprintf_func) (info->stream, "%s", obuf);
-
-  /* The enter and bound instructions are printed with operands in the same
-     order as the intel book; everything else is printed in reverse order.  */
-  if (intel_syntax || two_source_ops)
-    {
-      first = op1out;
-      second = op2out;
-      third = op3out;
-      op_ad = op_index[0];
-      op_index[0] = op_index[2];
-      op_index[2] = op_ad;
-    }
-  else
-    {
-      first = op3out;
-      second = op2out;
-      third = op1out;
-    }
-  needcomma = 0;
-  if (*first)
-    {
-      if (op_index[0] != -1 && !op_riprel[0])
-	(*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
-      else
-	(*info->fprintf_func) (info->stream, "%s", first);
-      needcomma = 1;
-    }
-  if (*second)
-    {
-      if (needcomma)
-	(*info->fprintf_func) (info->stream, ",");
-      if (op_index[1] != -1 && !op_riprel[1])
-	(*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
-      else
-	(*info->fprintf_func) (info->stream, "%s", second);
-      needcomma = 1;
-    }
-  if (*third)
-    {
-      if (needcomma)
-	(*info->fprintf_func) (info->stream, ",");
-      if (op_index[2] != -1 && !op_riprel[2])
-	(*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
-      else
-	(*info->fprintf_func) (info->stream, "%s", third);
-    }
-  for (i = 0; i < 3; i++)
-    if (op_index[i] != -1 && op_riprel[i])
-      {
-	(*info->fprintf_func) (info->stream, "        # ");
-	(*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
-						+ op_address[op_index[i]]), info);
-      }
-  return codep - priv.the_buffer;
-}
-
-static const char *float_mem[] = {
-  /* d8 */
-  "fadd{s||s|}",
-  "fmul{s||s|}",
-  "fcom{s||s|}",
-  "fcomp{s||s|}",
-  "fsub{s||s|}",
-  "fsubr{s||s|}",
-  "fdiv{s||s|}",
-  "fdivr{s||s|}",
-  /* d9 */
-  "fld{s||s|}",
-  "(bad)",
-  "fst{s||s|}",
-  "fstp{s||s|}",
-  "fldenvIC",
-  "fldcw",
-  "fNstenvIC",
-  "fNstcw",
-  /* da */
-  "fiadd{l||l|}",
-  "fimul{l||l|}",
-  "ficom{l||l|}",
-  "ficomp{l||l|}",
-  "fisub{l||l|}",
-  "fisubr{l||l|}",
-  "fidiv{l||l|}",
-  "fidivr{l||l|}",
-  /* db */
-  "fild{l||l|}",
-  "fisttp{l||l|}",
-  "fist{l||l|}",
-  "fistp{l||l|}",
-  "(bad)",
-  "fld{t||t|}",
-  "(bad)",
-  "fstp{t||t|}",
-  /* dc */
-  "fadd{l||l|}",
-  "fmul{l||l|}",
-  "fcom{l||l|}",
-  "fcomp{l||l|}",
-  "fsub{l||l|}",
-  "fsubr{l||l|}",
-  "fdiv{l||l|}",
-  "fdivr{l||l|}",
-  /* dd */
-  "fld{l||l|}",
-  "fisttp{ll||ll|}",
-  "fst{l||l|}",
-  "fstp{l||l|}",
-  "frstorIC",
-  "(bad)",
-  "fNsaveIC",
-  "fNstsw",
-  /* de */
-  "fiadd",
-  "fimul",
-  "ficom",
-  "ficomp",
-  "fisub",
-  "fisubr",
-  "fidiv",
-  "fidivr",
-  /* df */
-  "fild",
-  "fisttp",
-  "fist",
-  "fistp",
-  "fbld",
-  "fild{ll||ll|}",
-  "fbstp",
-  "fistp{ll||ll|}",
-};
-
-static const unsigned char float_mem_mode[] = {
-  /* d8 */
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  /* d9 */
-  d_mode,
-  0,
-  d_mode,
-  d_mode,
-  0,
-  w_mode,
-  0,
-  w_mode,
-  /* da */
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  /* db */
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  0,
-  t_mode,
-  0,
-  t_mode,
-  /* dc */
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  /* dd */
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  0,
-  0,
-  0,
-  w_mode,
-  /* de */
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  /* df */
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  t_mode,
-  q_mode,
-  t_mode,
-  q_mode
-};
-
-#define ST OP_ST, 0
-#define STi OP_STi, 0
-
-#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
-#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
-#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
-#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
-#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
-#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
-#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
-#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
-#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
-
-static const struct dis386 float_reg[][8] = {
-  /* d8 */
-  {
-    { "fadd",	ST, STi, XX },
-    { "fmul",	ST, STi, XX },
-    { "fcom",	STi, XX, XX },
-    { "fcomp",	STi, XX, XX },
-    { "fsub",	ST, STi, XX },
-    { "fsubr",	ST, STi, XX },
-    { "fdiv",	ST, STi, XX },
-    { "fdivr",	ST, STi, XX },
-  },
-  /* d9 */
-  {
-    { "fld",	STi, XX, XX },
-    { "fxch",	STi, XX, XX },
-    { FGRPd9_2 },
-    { "(bad)",	XX, XX, XX },
-    { FGRPd9_4 },
-    { FGRPd9_5 },
-    { FGRPd9_6 },
-    { FGRPd9_7 },
-  },
-  /* da */
-  {
-    { "fcmovb",	ST, STi, XX },
-    { "fcmove",	ST, STi, XX },
-    { "fcmovbe",ST, STi, XX },
-    { "fcmovu",	ST, STi, XX },
-    { "(bad)",	XX, XX, XX },
-    { FGRPda_5 },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* db */
-  {
-    { "fcmovnb",ST, STi, XX },
-    { "fcmovne",ST, STi, XX },
-    { "fcmovnbe",ST, STi, XX },
-    { "fcmovnu",ST, STi, XX },
-    { FGRPdb_4 },
-    { "fucomi",	ST, STi, XX },
-    { "fcomi",	ST, STi, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* dc */
-  {
-    { "fadd",	STi, ST, XX },
-    { "fmul",	STi, ST, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-#if UNIXWARE_COMPAT
-    { "fsub",	STi, ST, XX },
-    { "fsubr",	STi, ST, XX },
-    { "fdiv",	STi, ST, XX },
-    { "fdivr",	STi, ST, XX },
-#else
-    { "fsubr",	STi, ST, XX },
-    { "fsub",	STi, ST, XX },
-    { "fdivr",	STi, ST, XX },
-    { "fdiv",	STi, ST, XX },
-#endif
-  },
-  /* dd */
-  {
-    { "ffree",	STi, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "fst",	STi, XX, XX },
-    { "fstp",	STi, XX, XX },
-    { "fucom",	STi, XX, XX },
-    { "fucomp",	STi, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* de */
-  {
-    { "faddp",	STi, ST, XX },
-    { "fmulp",	STi, ST, XX },
-    { "(bad)",	XX, XX, XX },
-    { FGRPde_3 },
-#if UNIXWARE_COMPAT
-    { "fsubp",	STi, ST, XX },
-    { "fsubrp",	STi, ST, XX },
-    { "fdivp",	STi, ST, XX },
-    { "fdivrp",	STi, ST, XX },
-#else
-    { "fsubrp",	STi, ST, XX },
-    { "fsubp",	STi, ST, XX },
-    { "fdivrp",	STi, ST, XX },
-    { "fdivp",	STi, ST, XX },
-#endif
-  },
-  /* df */
-  {
-    { "ffreep",	STi, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { FGRPdf_4 },
-    { "fucomip",ST, STi, XX },
-    { "fcomip", ST, STi, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-};
-
-static char *fgrps[][8] = {
-  /* d9_2  0 */
-  {
-    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
-  },
-
-  /* d9_4  1 */
-  {
-    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
-  },
-
-  /* d9_5  2 */
-  {
-    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
-  },
-
-  /* d9_6  3 */
-  {
-    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
-  },
-
-  /* d9_7  4 */
-  {
-    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
-  },
-
-  /* da_5  5 */
-  {
-    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
-  },
-
-  /* db_4  6 */
-  {
-    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
-    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
-  },
-
-  /* de_3  7 */
-  {
-    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
-  },
-
-  /* df_4  8 */
-  {
-    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
-  },
-};
-
-static void
-dofloat (int sizeflag)
-{
-  const struct dis386 *dp;
-  unsigned char floatop;
-
-  floatop = codep[-1];
-
-  if (mod != 3)
-    {
-      int fp_indx = (floatop - 0xd8) * 8 + reg;
-
-      putop (float_mem[fp_indx], sizeflag);
-      obufp = op1out;
-      OP_E (float_mem_mode[fp_indx], sizeflag);
-      return;
-    }
-  /* Skip mod/rm byte.  */
-  MODRM_CHECK;
-  codep++;
-
-  dp = &float_reg[floatop - 0xd8][reg];
-  if (dp->name == NULL)
-    {
-      putop (fgrps[dp->bytemode1][rm], sizeflag);
-
-      /* Instruction fnstsw is only one with strange arg.  */
-      if (floatop == 0xdf && codep[-1] == 0xe0)
-	strcpy (op1out, names16[0]);
-    }
-  else
-    {
-      putop (dp->name, sizeflag);
-
-      obufp = op1out;
-      if (dp->op1)
-	(*dp->op1) (dp->bytemode1, sizeflag);
-      obufp = op2out;
-      if (dp->op2)
-	(*dp->op2) (dp->bytemode2, sizeflag);
-    }
-}
-
-static void
-OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  oappend ("%st");
-}
-
-static void
-OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  sprintf (scratchbuf, "%%st(%d)", rm);
-  oappend (scratchbuf + intel_syntax);
-}
-
-/* Capital letters in template are macros.  */
-static int
-putop (const char *template, int sizeflag)
-{
-  const char *p;
-  int alt = 0;
-
-  for (p = template; *p; p++)
-    {
-      switch (*p)
-	{
-	default:
-	  *obufp++ = *p;
-	  break;
-	case '{':
-	  alt = 0;
-	  if (intel_syntax)
-	    alt += 1;
-	  if (mode_64bit)
-	    alt += 2;
-	  while (alt != 0)
-	    {
-	      while (*++p != '|')
-		{
-		  if (*p == '}')
-		    {
-		      /* Alternative not valid.  */
-		      strcpy (obuf, "(bad)");
-		      obufp = obuf + 5;
-		      return 1;
-		    }
-		  else if (*p == '\0')
-		    abort ();
-		}
-	      alt--;
-	    }
-	  /* Fall through.  */
-	case 'I':
-	  alt = 1;
-	  continue;
-	case '|':
-	  while (*++p != '}')
-	    {
-	      if (*p == '\0')
-		abort ();
-	    }
-	  break;
-	case '}':
-	  break;
-	case 'A':
-	  if (intel_syntax)
-	    break;
-	  if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
-	    *obufp++ = 'b';
-	  break;
-	case 'B':
-	  if (intel_syntax)
-	    break;
-	  if (sizeflag & SUFFIX_ALWAYS)
-	    *obufp++ = 'b';
-	  break;
-	case 'C':
-	  if (intel_syntax && !alt)
-	    break;
-	  if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
-	    {
-	      if (sizeflag & DFLAG)
-		*obufp++ = intel_syntax ? 'd' : 'l';
-	      else
-		*obufp++ = intel_syntax ? 'w' : 's';
-	      used_prefixes |= (prefixes & PREFIX_DATA);
-	    }
-	  break;
-	case 'E':		/* For jcxz/jecxz */
-	  if (mode_64bit)
-	    {
-	      if (sizeflag & AFLAG)
-		*obufp++ = 'r';
-	      else
-		*obufp++ = 'e';
-	    }
-	  else
-	    if (sizeflag & AFLAG)
-	      *obufp++ = 'e';
-	  used_prefixes |= (prefixes & PREFIX_ADDR);
-	  break;
-	case 'F':
-	  if (intel_syntax)
-	    break;
-	  if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
-	    {
-	      if (sizeflag & AFLAG)
-		*obufp++ = mode_64bit ? 'q' : 'l';
-	      else
-		*obufp++ = mode_64bit ? 'l' : 'w';
-	      used_prefixes |= (prefixes & PREFIX_ADDR);
-	    }
-	  break;
-	case 'H':
-	  if (intel_syntax)
-	    break;
-	  if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
-	      || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
-	    {
-	      used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
-	      *obufp++ = ',';
-	      *obufp++ = 'p';
-	      if (prefixes & PREFIX_DS)
-		*obufp++ = 't';
-	      else
-		*obufp++ = 'n';
-	    }
-	  break;
-	case 'J':
-	  if (intel_syntax)
-	    break;
-	  *obufp++ = 'l';
-	  break;
-	case 'L':
-	  if (intel_syntax)
-	    break;
-	  if (sizeflag & SUFFIX_ALWAYS)
-	    *obufp++ = 'l';
-	  break;
-	case 'N':
-	  if ((prefixes & PREFIX_FWAIT) == 0)
-	    *obufp++ = 'n';
-	  else
-	    used_prefixes |= PREFIX_FWAIT;
-	  break;
-	case 'O':
-	  USED_REX (REX_MODE64);
-	  if (rex & REX_MODE64)
-	    *obufp++ = 'o';
-	  else
-	    *obufp++ = 'd';
-	  break;
-	case 'T':
-	  if (intel_syntax)
-	    break;
-	  if (mode_64bit)
-	    {
-	      *obufp++ = 'q';
-	      break;
-	    }
-	  /* Fall through.  */
-	case 'P':
-	  if (intel_syntax)
-	    break;
-	  if ((prefixes & PREFIX_DATA)
-	      || (rex & REX_MODE64)
-	      || (sizeflag & SUFFIX_ALWAYS))
-	    {
-	      USED_REX (REX_MODE64);
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else
-		{
-		   if (sizeflag & DFLAG)
-		      *obufp++ = 'l';
-		   else
-		     *obufp++ = 'w';
-		   used_prefixes |= (prefixes & PREFIX_DATA);
-		}
-	    }
-	  break;
-	case 'U':
-	  if (intel_syntax)
-	    break;
-	  if (mode_64bit)
-	    {
-	      *obufp++ = 'q';
-	      break;
-	    }
-	  /* Fall through.  */
-	case 'Q':
-	  if (intel_syntax && !alt)
-	    break;
-	  USED_REX (REX_MODE64);
-	  if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
-	    {
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else
-		{
-		  if (sizeflag & DFLAG)
-		    *obufp++ = intel_syntax ? 'd' : 'l';
-		  else
-		    *obufp++ = 'w';
-		  used_prefixes |= (prefixes & PREFIX_DATA);
-		}
-	    }
-	  break;
-	case 'R':
-	  USED_REX (REX_MODE64);
-	  if (intel_syntax)
-	    {
-	      if (rex & REX_MODE64)
-		{
-		  *obufp++ = 'q';
-		  *obufp++ = 't';
-		}
-	      else if (sizeflag & DFLAG)
-		{
-		  *obufp++ = 'd';
-		  *obufp++ = 'q';
-		}
-	      else
-		{
-		  *obufp++ = 'w';
-		  *obufp++ = 'd';
-		}
-	    }
-	  else
-	    {
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else if (sizeflag & DFLAG)
-		*obufp++ = 'l';
-	      else
-		*obufp++ = 'w';
-	    }
-	  if (!(rex & REX_MODE64))
-	    used_prefixes |= (prefixes & PREFIX_DATA);
-	  break;
-	case 'S':
-	  if (intel_syntax)
-	    break;
-	  if (sizeflag & SUFFIX_ALWAYS)
-	    {
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else
-		{
-		  if (sizeflag & DFLAG)
-		    *obufp++ = 'l';
-		  else
-		    *obufp++ = 'w';
-		  used_prefixes |= (prefixes & PREFIX_DATA);
-		}
-	    }
-	  break;
-	case 'X':
-	  if (prefixes & PREFIX_DATA)
-	    *obufp++ = 'd';
-	  else
-	    *obufp++ = 's';
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  break;
-	case 'Y':
-	  if (intel_syntax)
-	    break;
-	  if (rex & REX_MODE64)
-	    {
-	      USED_REX (REX_MODE64);
-	      *obufp++ = 'q';
-	    }
-	  break;
-	  /* implicit operand size 'l' for i386 or 'q' for x86-64 */
-	case 'W':
-	  /* operand size flag for cwtl, cbtw */
-	  USED_REX (0);
-	  if (rex)
-	    *obufp++ = 'l';
-	  else if (sizeflag & DFLAG)
-	    *obufp++ = 'w';
-	  else
-	    *obufp++ = 'b';
-	  if (intel_syntax)
-	    {
-	      if (rex)
-		{
-		  *obufp++ = 'q';
-		  *obufp++ = 'e';
-		}
-	      if (sizeflag & DFLAG)
-		{
-		  *obufp++ = 'd';
-		  *obufp++ = 'e';
-		}
-	      else
-		{
-		  *obufp++ = 'w';
-		}
-	    }
-	  if (!rex)
-	    used_prefixes |= (prefixes & PREFIX_DATA);
-	  break;
-	}
-      alt = 0;
-    }
-  *obufp = 0;
-  return 0;
-}
-
-static void
-oappend (const char *s)
-{
-  strcpy (obufp, s);
-  obufp += strlen (s);
-}
-
-static void
-append_seg (void)
-{
-  if (prefixes & PREFIX_CS)
-    {
-      used_prefixes |= PREFIX_CS;
-      oappend ("%cs:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_DS)
-    {
-      used_prefixes |= PREFIX_DS;
-      oappend ("%ds:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_SS)
-    {
-      used_prefixes |= PREFIX_SS;
-      oappend ("%ss:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_ES)
-    {
-      used_prefixes |= PREFIX_ES;
-      oappend ("%es:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_FS)
-    {
-      used_prefixes |= PREFIX_FS;
-      oappend ("%fs:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_GS)
-    {
-      used_prefixes |= PREFIX_GS;
-      oappend ("%gs:" + intel_syntax);
-    }
-}
-
-static void
-OP_indirE (int bytemode, int sizeflag)
-{
-  if (!intel_syntax)
-    oappend ("*");
-  OP_E (bytemode, sizeflag);
-}
-
-static void
-print_operand_value (char *buf, int hex, bfd_vma disp)
-{
-  if (mode_64bit)
-    {
-      if (hex)
-	{
-	  char tmp[30];
-	  int i;
-	  buf[0] = '0';
-	  buf[1] = 'x';
-	  sprintf_vma (tmp, disp);
-	  for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
-	  strcpy (buf + 2, tmp + i);
-	}
-      else
-	{
-	  bfd_signed_vma v = disp;
-	  char tmp[30];
-	  int i;
-	  if (v < 0)
-	    {
-	      *(buf++) = '-';
-	      v = -disp;
-	      /* Check for possible overflow on 0x8000000000000000.  */
-	      if (v < 0)
-		{
-		  strcpy (buf, "9223372036854775808");
-		  return;
-		}
-	    }
-	  if (!v)
-	    {
-	      strcpy (buf, "0");
-	      return;
-	    }
-
-	  i = 0;
-	  tmp[29] = 0;
-	  while (v)
-	    {
-	      tmp[28 - i] = (v % 10) + '0';
-	      v /= 10;
-	      i++;
-	    }
-	  strcpy (buf, tmp + 29 - i);
-	}
-    }
-  else
-    {
-      if (hex)
-	sprintf (buf, "0x%x", (unsigned int) disp);
-      else
-	sprintf (buf, "%d", (int) disp);
-    }
-}
-
-static void
-OP_E (int bytemode, int sizeflag)
-{
-  bfd_vma disp;
-  int add = 0;
-  int riprel = 0;
-  USED_REX (REX_EXTZ);
-  if (rex & REX_EXTZ)
-    add += 8;
-
-  /* Skip mod/rm byte.  */
-  MODRM_CHECK;
-  codep++;
-
-  if (mod == 3)
-    {
-      switch (bytemode)
-	{
-	case b_mode:
-	  USED_REX (0);
-	  if (rex)
-	    oappend (names8rex[rm + add]);
-	  else
-	    oappend (names8[rm + add]);
-	  break;
-	case w_mode:
-	  oappend (names16[rm + add]);
-	  break;
-	case d_mode:
-	  oappend (names32[rm + add]);
-	  break;
-	case q_mode:
-	  oappend (names64[rm + add]);
-	  break;
-	case m_mode:
-	  if (mode_64bit)
-	    oappend (names64[rm + add]);
-	  else
-	    oappend (names32[rm + add]);
-	  break;
-	case branch_v_mode:
-	  if (mode_64bit)
-	    oappend (names64[rm + add]);
-	  else
-	    {
-	      if ((sizeflag & DFLAG) || bytemode != branch_v_mode)
-		oappend (names32[rm + add]);
-	      else
-		oappend (names16[rm + add]);
-	      used_prefixes |= (prefixes & PREFIX_DATA);
-	    }
-	  break;
-	case v_mode:
-	case dq_mode:
-	case dqw_mode:
-	  USED_REX (REX_MODE64);
-	  if (rex & REX_MODE64)
-	    oappend (names64[rm + add]);
-	  else if ((sizeflag & DFLAG) || bytemode != v_mode)
-	    oappend (names32[rm + add]);
-	  else
-	    oappend (names16[rm + add]);
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  break;
-	case 0:
-	  break;
-	default:
-	  oappend (INTERNAL_DISASSEMBLER_ERROR);
-	  break;
-	}
-      return;
-    }
-
-  disp = 0;
-  append_seg ();
-
-  if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
-    {
-      int havesib;
-      int havebase;
-      int base;
-      int index = 0;
-      int scale = 0;
-
-      havesib = 0;
-      havebase = 1;
-      base = rm;
-
-      if (base == 4)
-	{
-	  havesib = 1;
-	  FETCH_DATA (the_info, codep + 1);
-	  index = (*codep >> 3) & 7;
-	  if (mode_64bit || index != 0x4)
-	    /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored.  */
-	    scale = (*codep >> 6) & 3;
-	  base = *codep & 7;
-	  USED_REX (REX_EXTY);
-	  if (rex & REX_EXTY)
-	    index += 8;
-	  codep++;
-	}
-      base += add;
-
-      switch (mod)
-	{
-	case 0:
-	  if ((base & 7) == 5)
-	    {
-	      havebase = 0;
-	      if (mode_64bit && !havesib)
-		riprel = 1;
-	      disp = get32s ();
-	    }
-	  break;
-	case 1:
-	  FETCH_DATA (the_info, codep + 1);
-	  disp = *codep++;
-	  if ((disp & 0x80) != 0)
-	    disp -= 0x100;
-	  break;
-	case 2:
-	  disp = get32s ();
-	  break;
-	}
-
-      if (!intel_syntax)
-	if (mod != 0 || (base & 7) == 5)
-	  {
-	    print_operand_value (scratchbuf, !riprel, disp);
-	    oappend (scratchbuf);
-	    if (riprel)
-	      {
-		set_op (disp, 1);
-		oappend ("(%rip)");
-	      }
-	  }
-
-      if (havebase || (havesib && (index != 4 || scale != 0)))
-	{
-	  if (intel_syntax)
-	    {
-	      switch (bytemode)
-		{
-		case b_mode:
-		  oappend ("BYTE PTR ");
-		  break;
-		case w_mode:
-		case dqw_mode:
-		  oappend ("WORD PTR ");
-		  break;
-		case branch_v_mode:
-		case v_mode:
-		case dq_mode:
-		  USED_REX (REX_MODE64);
-		  if (rex & REX_MODE64)
-		    oappend ("QWORD PTR ");
-		  else if ((sizeflag & DFLAG) || bytemode == dq_mode)
-		    oappend ("DWORD PTR ");
-		  else
-		    oappend ("WORD PTR ");
-		  used_prefixes |= (prefixes & PREFIX_DATA);
-		  break;
-		case d_mode:
-		  oappend ("DWORD PTR ");
-		  break;
-		case q_mode:
-		  oappend ("QWORD PTR ");
-		  break;
-		case m_mode:
-		  if (mode_64bit)
-		    oappend ("QWORD PTR ");
-		  else
-		    oappend ("DWORD PTR ");
-		  break;
-		case f_mode:
-		  if (sizeflag & DFLAG)
-		    {
-		      used_prefixes |= (prefixes & PREFIX_DATA);
-		      oappend ("FWORD PTR ");
-		    }
-		  else
-		    oappend ("DWORD PTR ");
-		  break;
-		case t_mode:
-		  oappend ("TBYTE PTR ");
-		  break;
-		case x_mode:
-		  oappend ("XMMWORD PTR ");
-		  break;
-		default:
-		  break;
-		}
-	    }
-	  *obufp++ = open_char;
-	  if (intel_syntax && riprel)
-	    oappend ("rip + ");
-	  *obufp = '\0';
-	  if (havebase)
-	    oappend (mode_64bit && (sizeflag & AFLAG)
-		     ? names64[base] : names32[base]);
-	  if (havesib)
-	    {
-	      if (index != 4)
-		{
-		  if (!intel_syntax || havebase)
-		    {
-		      *obufp++ = separator_char;
-		      *obufp = '\0';
-		    }
-		  oappend (mode_64bit && (sizeflag & AFLAG)
-			   ? names64[index] : names32[index]);
-		}
-	      if (scale != 0 || (!intel_syntax && index != 4))
-		{
-		  *obufp++ = scale_char;
-		  *obufp = '\0';
-		  sprintf (scratchbuf, "%d", 1 << scale);
-		  oappend (scratchbuf);
-		}
-	    }
-	  if (intel_syntax && disp)
-	    {
-	      if ((bfd_signed_vma) disp > 0)
-		{
-		  *obufp++ = '+';
-		  *obufp = '\0';
-		}
-	      else if (mod != 1)
-		{
-		  *obufp++ = '-';
-		  *obufp = '\0';
-		  disp = - (bfd_signed_vma) disp;
-		}
-
-	      print_operand_value (scratchbuf, mod != 1, disp);
-	      oappend (scratchbuf);
-	    }
-
-	  *obufp++ = close_char;
-	  *obufp = '\0';
-	}
-      else if (intel_syntax)
-	{
-	  if (mod != 0 || (base & 7) == 5)
-	    {
-	      if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-			      | PREFIX_ES | PREFIX_FS | PREFIX_GS))
-		;
-	      else
-		{
-		  oappend (names_seg[ds_reg - es_reg]);
-		  oappend (":");
-		}
-	      print_operand_value (scratchbuf, 1, disp);
-	      oappend (scratchbuf);
-	    }
-	}
-    }
-  else
-    { /* 16 bit address mode */
-      switch (mod)
-	{
-	case 0:
-	  if (rm == 6)
-	    {
-	      disp = get16 ();
-	      if ((disp & 0x8000) != 0)
-		disp -= 0x10000;
-	    }
-	  break;
-	case 1:
-	  FETCH_DATA (the_info, codep + 1);
-	  disp = *codep++;
-	  if ((disp & 0x80) != 0)
-	    disp -= 0x100;
-	  break;
-	case 2:
-	  disp = get16 ();
-	  if ((disp & 0x8000) != 0)
-	    disp -= 0x10000;
-	  break;
-	}
-
-      if (!intel_syntax)
-	if (mod != 0 || rm == 6)
-	  {
-	    print_operand_value (scratchbuf, 0, disp);
-	    oappend (scratchbuf);
-	  }
-
-      if (mod != 0 || rm != 6)
-	{
-	  *obufp++ = open_char;
-	  *obufp = '\0';
-	  oappend (index16[rm]);
-	  if (intel_syntax && disp)
-	    {
-	      if ((bfd_signed_vma) disp > 0)
-		{
-		  *obufp++ = '+';
-		  *obufp = '\0';
-		}
-	      else if (mod != 1)
-		{
-		  *obufp++ = '-';
-		  *obufp = '\0';
-		  disp = - (bfd_signed_vma) disp;
-		}
-
-	      print_operand_value (scratchbuf, mod != 1, disp);
-	      oappend (scratchbuf);
-	    }
-
-	  *obufp++ = close_char;
-	  *obufp = '\0';
-	}
-      else if (intel_syntax)
-	{
-	  if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-			  | PREFIX_ES | PREFIX_FS | PREFIX_GS))
-	    ;
-	  else
-	    {
-	      oappend (names_seg[ds_reg - es_reg]);
-	      oappend (":");
-	    }
-	  print_operand_value (scratchbuf, 1, disp & 0xffff);
-	  oappend (scratchbuf);
-	}
-    }
-}
-
-static void
-OP_G (int bytemode, int sizeflag)
-{
-  int add = 0;
-  USED_REX (REX_EXTX);
-  if (rex & REX_EXTX)
-    add += 8;
-  switch (bytemode)
-    {
-    case b_mode:
-      USED_REX (0);
-      if (rex)
-	oappend (names8rex[reg + add]);
-      else
-	oappend (names8[reg + add]);
-      break;
-    case w_mode:
-      oappend (names16[reg + add]);
-      break;
-    case d_mode:
-      oappend (names32[reg + add]);
-      break;
-    case q_mode:
-      oappend (names64[reg + add]);
-      break;
-    case v_mode:
-    case dq_mode:
-    case dqw_mode:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	oappend (names64[reg + add]);
-      else if ((sizeflag & DFLAG) || bytemode != v_mode)
-	oappend (names32[reg + add]);
-      else
-	oappend (names16[reg + add]);
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    case m_mode:
-      if (mode_64bit)
-	oappend (names64[reg + add]);
-      else
-	oappend (names32[reg + add]);
-      break;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      break;
-    }
-}
-
-static bfd_vma
-get64 (void)
-{
-  bfd_vma x;
-#ifdef BFD64
-  unsigned int a;
-  unsigned int b;
-
-  FETCH_DATA (the_info, codep + 8);
-  a = *codep++ & 0xff;
-  a |= (*codep++ & 0xff) << 8;
-  a |= (*codep++ & 0xff) << 16;
-  a |= (*codep++ & 0xff) << 24;
-  b = *codep++ & 0xff;
-  b |= (*codep++ & 0xff) << 8;
-  b |= (*codep++ & 0xff) << 16;
-  b |= (*codep++ & 0xff) << 24;
-  x = a + ((bfd_vma) b << 32);
-#else
-  abort ();
-  x = 0;
-#endif
-  return x;
-}
-
-static bfd_signed_vma
-get32 (void)
-{
-  bfd_signed_vma x = 0;
-
-  FETCH_DATA (the_info, codep + 4);
-  x = *codep++ & (bfd_signed_vma) 0xff;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
-  return x;
-}
-
-static bfd_signed_vma
-get32s (void)
-{
-  bfd_signed_vma x = 0;
-
-  FETCH_DATA (the_info, codep + 4);
-  x = *codep++ & (bfd_signed_vma) 0xff;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
-
-  x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
-
-  return x;
-}
-
-static int
-get16 (void)
-{
-  int x = 0;
-
-  FETCH_DATA (the_info, codep + 2);
-  x = *codep++ & 0xff;
-  x |= (*codep++ & 0xff) << 8;
-  return x;
-}
-
-static void
-set_op (bfd_vma op, int riprel)
-{
-  op_index[op_ad] = op_ad;
-  if (mode_64bit)
-    {
-      op_address[op_ad] = op;
-      op_riprel[op_ad] = riprel;
-    }
-  else
-    {
-      /* Mask to get a 32-bit address.  */
-      op_address[op_ad] = op & 0xffffffff;
-      op_riprel[op_ad] = riprel & 0xffffffff;
-    }
-}
-
-static void
-OP_REG (int code, int sizeflag)
-{
-  const char *s;
-  int add = 0;
-  USED_REX (REX_EXTZ);
-  if (rex & REX_EXTZ)
-    add = 8;
-
-  switch (code)
-    {
-    case indir_dx_reg:
-      if (intel_syntax)
-	s = "[dx]";
-      else
-	s = "(%dx)";
-      break;
-    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
-    case sp_reg: case bp_reg: case si_reg: case di_reg:
-      s = names16[code - ax_reg + add];
-      break;
-    case es_reg: case ss_reg: case cs_reg:
-    case ds_reg: case fs_reg: case gs_reg:
-      s = names_seg[code - es_reg + add];
-      break;
-    case al_reg: case ah_reg: case cl_reg: case ch_reg:
-    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
-      USED_REX (0);
-      if (rex)
-	s = names8rex[code - al_reg + add];
-      else
-	s = names8[code - al_reg];
-      break;
-    case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
-    case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
-      if (mode_64bit)
-	{
-	  s = names64[code - rAX_reg + add];
-	  break;
-	}
-      code += eAX_reg - rAX_reg;
-      /* Fall through.  */
-    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
-    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	s = names64[code - eAX_reg + add];
-      else if (sizeflag & DFLAG)
-	s = names32[code - eAX_reg + add];
-      else
-	s = names16[code - eAX_reg + add];
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    default:
-      s = INTERNAL_DISASSEMBLER_ERROR;
-      break;
-    }
-  oappend (s);
-}
-
-static void
-OP_IMREG (int code, int sizeflag)
-{
-  const char *s;
-
-  switch (code)
-    {
-    case indir_dx_reg:
-      if (intel_syntax)
-	s = "[dx]";
-      else
-	s = "(%dx)";
-      break;
-    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
-    case sp_reg: case bp_reg: case si_reg: case di_reg:
-      s = names16[code - ax_reg];
-      break;
-    case es_reg: case ss_reg: case cs_reg:
-    case ds_reg: case fs_reg: case gs_reg:
-      s = names_seg[code - es_reg];
-      break;
-    case al_reg: case ah_reg: case cl_reg: case ch_reg:
-    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
-      USED_REX (0);
-      if (rex)
-	s = names8rex[code - al_reg];
-      else
-	s = names8[code - al_reg];
-      break;
-    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
-    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	s = names64[code - eAX_reg];
-      else if (sizeflag & DFLAG)
-	s = names32[code - eAX_reg];
-      else
-	s = names16[code - eAX_reg];
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    default:
-      s = INTERNAL_DISASSEMBLER_ERROR;
-      break;
-    }
-  oappend (s);
-}
-
-static void
-OP_I (int bytemode, int sizeflag)
-{
-  bfd_signed_vma op;
-  bfd_signed_vma mask = -1;
-
-  switch (bytemode)
-    {
-    case b_mode:
-      FETCH_DATA (the_info, codep + 1);
-      op = *codep++;
-      mask = 0xff;
-      break;
-    case q_mode:
-      if (mode_64bit)
-	{
-	  op = get32s ();
-	  break;
-	}
-      /* Fall through.  */
-    case v_mode:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	op = get32s ();
-      else if (sizeflag & DFLAG)
-	{
-	  op = get32 ();
-	  mask = 0xffffffff;
-	}
-      else
-	{
-	  op = get16 ();
-	  mask = 0xfffff;
-	}
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    case w_mode:
-      mask = 0xfffff;
-      op = get16 ();
-      break;
-    case const_1_mode:
-      if (intel_syntax)
-        oappend ("1");
-      return;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return;
-    }
-
-  op &= mask;
-  scratchbuf[0] = '$';
-  print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
-  scratchbuf[0] = '\0';
-}
-
-static void
-OP_I64 (int bytemode, int sizeflag)
-{
-  bfd_signed_vma op;
-  bfd_signed_vma mask = -1;
-
-  if (!mode_64bit)
-    {
-      OP_I (bytemode, sizeflag);
-      return;
-    }
-
-  switch (bytemode)
-    {
-    case b_mode:
-      FETCH_DATA (the_info, codep + 1);
-      op = *codep++;
-      mask = 0xff;
-      break;
-    case v_mode:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	op = get64 ();
-      else if (sizeflag & DFLAG)
-	{
-	  op = get32 ();
-	  mask = 0xffffffff;
-	}
-      else
-	{
-	  op = get16 ();
-	  mask = 0xfffff;
-	}
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    case w_mode:
-      mask = 0xfffff;
-      op = get16 ();
-      break;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return;
-    }
-
-  op &= mask;
-  scratchbuf[0] = '$';
-  print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
-  scratchbuf[0] = '\0';
-}
-
-static void
-OP_sI (int bytemode, int sizeflag)
-{
-  bfd_signed_vma op;
-  bfd_signed_vma mask = -1;
-
-  switch (bytemode)
-    {
-    case b_mode:
-      FETCH_DATA (the_info, codep + 1);
-      op = *codep++;
-      if ((op & 0x80) != 0)
-	op -= 0x100;
-      mask = 0xffffffff;
-      break;
-    case v_mode:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	op = get32s ();
-      else if (sizeflag & DFLAG)
-	{
-	  op = get32s ();
-	  mask = 0xffffffff;
-	}
-      else
-	{
-	  mask = 0xffffffff;
-	  op = get16 ();
-	  if ((op & 0x8000) != 0)
-	    op -= 0x10000;
-	}
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    case w_mode:
-      op = get16 ();
-      mask = 0xffffffff;
-      if ((op & 0x8000) != 0)
-	op -= 0x10000;
-      break;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return;
-    }
-
-  scratchbuf[0] = '$';
-  print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_J (int bytemode, int sizeflag)
-{
-  bfd_vma disp;
-  bfd_vma mask = -1;
-
-  switch (bytemode)
-    {
-    case b_mode:
-      FETCH_DATA (the_info, codep + 1);
-      disp = *codep++;
-      if ((disp & 0x80) != 0)
-	disp -= 0x100;
-      break;
-    case v_mode:
-      if (sizeflag & DFLAG)
-	disp = get32s ();
-      else
-	{
-	  disp = get16 ();
-	  /* For some reason, a data16 prefix on a jump instruction
-	     means that the pc is masked to 16 bits after the
-	     displacement is added!  */
-	  mask = 0xffff;
-	}
-      break;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return;
-    }
-  disp = (start_pc + codep - start_codep + disp) & mask;
-  set_op (disp, 0);
-  print_operand_value (scratchbuf, 1, disp);
-  oappend (scratchbuf);
-}
-
-static void
-OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  oappend (names_seg[reg]);
-}
-
-static void
-OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
-{
-  int seg, offset;
-
-  if (sizeflag & DFLAG)
-    {
-      offset = get32 ();
-      seg = get16 ();
-    }
-  else
-    {
-      offset = get16 ();
-      seg = get16 ();
-    }
-  used_prefixes |= (prefixes & PREFIX_DATA);
-  if (intel_syntax)
-    sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
-  else
-    sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
-  oappend (scratchbuf);
-}
-
-static void
-OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
-{
-  bfd_vma off;
-
-  append_seg ();
-
-  if ((sizeflag & AFLAG) || mode_64bit)
-    off = get32 ();
-  else
-    off = get16 ();
-
-  if (intel_syntax)
-    {
-      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
-	{
-	  oappend (names_seg[ds_reg - es_reg]);
-	  oappend (":");
-	}
-    }
-  print_operand_value (scratchbuf, 1, off);
-  oappend (scratchbuf);
-}
-
-static void
-OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  bfd_vma off;
-
-  if (!mode_64bit)
-    {
-      OP_OFF (bytemode, sizeflag);
-      return;
-    }
-
-  append_seg ();
-
-  off = get64 ();
-
-  if (intel_syntax)
-    {
-      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
-	{
-	  oappend (names_seg[ds_reg - es_reg]);
-	  oappend (":");
-	}
-    }
-  print_operand_value (scratchbuf, 1, off);
-  oappend (scratchbuf);
-}
-
-static void
-ptr_reg (int code, int sizeflag)
-{
-  const char *s;
-
-  *obufp++ = open_char;
-  used_prefixes |= (prefixes & PREFIX_ADDR);
-  if (mode_64bit)
-    {
-      if (!(sizeflag & AFLAG))
-	s = names32[code - eAX_reg];
-      else
-	s = names64[code - eAX_reg];
-    }
-  else if (sizeflag & AFLAG)
-    s = names32[code - eAX_reg];
-  else
-    s = names16[code - eAX_reg];
-  oappend (s);
-  *obufp++ = close_char;
-  *obufp = 0;
-}
-
-static void
-OP_ESreg (int code, int sizeflag)
-{
-  if (intel_syntax)
-    {
-      if (codep[-1] & 1)
-	{
-	  USED_REX (REX_MODE64);
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  if (rex & REX_MODE64)
-	    oappend ("QWORD PTR ");
-	  else if ((sizeflag & DFLAG))
-	    oappend ("DWORD PTR ");
-	  else
-	    oappend ("WORD PTR ");
-	}
-      else
-	oappend ("BYTE PTR ");
-    }
-
-  oappend ("%es:" + intel_syntax);
-  ptr_reg (code, sizeflag);
-}
-
-static void
-OP_DSreg (int code, int sizeflag)
-{
-  if (intel_syntax)
-    {
-      if (codep[-1] != 0xd7 && (codep[-1] & 1))
-	{
-	  USED_REX (REX_MODE64);
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  if (rex & REX_MODE64)
-	    oappend ("QWORD PTR ");
-	  else if ((sizeflag & DFLAG))
-	    oappend ("DWORD PTR ");
-	  else
-	    oappend ("WORD PTR ");
-	}
-      else
-	oappend ("BYTE PTR ");
-    }
-
-  if ((prefixes
-       & (PREFIX_CS
-	  | PREFIX_DS
-	  | PREFIX_SS
-	  | PREFIX_ES
-	  | PREFIX_FS
-	  | PREFIX_GS)) == 0)
-    prefixes |= PREFIX_DS;
-  append_seg ();
-  ptr_reg (code, sizeflag);
-}
-
-static void
-OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  int add = 0;
-  if (rex & REX_EXTX)
-    {
-      USED_REX (REX_EXTX);
-      add = 8;
-    }
-  else if (!mode_64bit && (prefixes & PREFIX_LOCK))
-    {
-      used_prefixes |= PREFIX_LOCK;
-      add = 8;
-    }
-  sprintf (scratchbuf, "%%cr%d", reg + add);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  int add = 0;
-  USED_REX (REX_EXTX);
-  if (rex & REX_EXTX)
-    add = 8;
-  if (intel_syntax)
-    sprintf (scratchbuf, "db%d", reg + add);
-  else
-    sprintf (scratchbuf, "%%db%d", reg + add);
-  oappend (scratchbuf);
-}
-
-static void
-OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  sprintf (scratchbuf, "%%tr%d", reg);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_Rd (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    OP_E (bytemode, sizeflag);
-  else
-    BadOp ();
-}
-
-static void
-OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  used_prefixes |= (prefixes & PREFIX_DATA);
-  if (prefixes & PREFIX_DATA)
-    {
-      int add = 0;
-      USED_REX (REX_EXTX);
-      if (rex & REX_EXTX)
-	add = 8;
-      sprintf (scratchbuf, "%%xmm%d", reg + add);
-    }
-  else
-    sprintf (scratchbuf, "%%mm%d", reg);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  int add = 0;
-  USED_REX (REX_EXTX);
-  if (rex & REX_EXTX)
-    add = 8;
-  sprintf (scratchbuf, "%%xmm%d", reg + add);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_EM (int bytemode, int sizeflag)
-{
-  if (mod != 3)
-    {
-      if (intel_syntax && bytemode == v_mode)
-	{
-	  bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
-	  used_prefixes |= (prefixes & PREFIX_DATA);
- 	}
-      OP_E (bytemode, sizeflag);
-      return;
-    }
-
-  /* Skip mod/rm byte.  */
-  MODRM_CHECK;
-  codep++;
-  used_prefixes |= (prefixes & PREFIX_DATA);
-  if (prefixes & PREFIX_DATA)
-    {
-      int add = 0;
-
-      USED_REX (REX_EXTZ);
-      if (rex & REX_EXTZ)
-	add = 8;
-      sprintf (scratchbuf, "%%xmm%d", rm + add);
-    }
-  else
-    sprintf (scratchbuf, "%%mm%d", rm);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_EX (int bytemode, int sizeflag)
-{
-  int add = 0;
-  if (mod != 3)
-    {
-      if (intel_syntax && bytemode == v_mode)
-	{
-	  switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
-	    {
-	    case 0:            bytemode = x_mode; break;
-	    case PREFIX_REPZ:  bytemode = d_mode; used_prefixes |= PREFIX_REPZ;  break;
-	    case PREFIX_DATA:  bytemode = x_mode; used_prefixes |= PREFIX_DATA;  break;
-	    case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
-	    default:           bytemode = 0; break;
-	    }
-	}
-      OP_E (bytemode, sizeflag);
-      return;
-    }
-  USED_REX (REX_EXTZ);
-  if (rex & REX_EXTZ)
-    add = 8;
-
-  /* Skip mod/rm byte.  */
-  MODRM_CHECK;
-  codep++;
-  sprintf (scratchbuf, "%%xmm%d", rm + add);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_MS (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    OP_EM (bytemode, sizeflag);
-  else
-    BadOp ();
-}
-
-static void
-OP_XS (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    OP_EX (bytemode, sizeflag);
-  else
-    BadOp ();
-}
-
-static void
-OP_M (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    BadOp ();	/* bad lea,lds,les,lfs,lgs,lss modrm */
-  else
-    OP_E (bytemode, sizeflag);
-}
-
-static void
-OP_0f07 (int bytemode, int sizeflag)
-{
-  if (mod != 3 || rm != 0)
-    BadOp ();
-  else
-    OP_E (bytemode, sizeflag);
-}
-
-static void
-OP_0fae (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    {
-      if (reg == 7)
-	strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
-
-      if (reg < 5 || rm != 0)
-	{
-	  BadOp ();	/* bad sfence, mfence, or lfence */
-	  return;
-	}
-    }
-  else if (reg != 7)
-    {
-      BadOp ();		/* bad clflush */
-      return;
-    }
-
-  OP_E (bytemode, sizeflag);
-}
-
-static void
-NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  /* NOP with REPZ prefix is called PAUSE.  */
-  if (prefixes == PREFIX_REPZ)
-    strcpy (obuf, "pause");
-}
-
-static const char *const Suffix3DNow[] = {
-/* 00 */	NULL,		NULL,		NULL,		NULL,
-/* 04 */	NULL,		NULL,		NULL,		NULL,
-/* 08 */	NULL,		NULL,		NULL,		NULL,
-/* 0C */	"pi2fw",	"pi2fd",	NULL,		NULL,
-/* 10 */	NULL,		NULL,		NULL,		NULL,
-/* 14 */	NULL,		NULL,		NULL,		NULL,
-/* 18 */	NULL,		NULL,		NULL,		NULL,
-/* 1C */	"pf2iw",	"pf2id",	NULL,		NULL,
-/* 20 */	NULL,		NULL,		NULL,		NULL,
-/* 24 */	NULL,		NULL,		NULL,		NULL,
-/* 28 */	NULL,		NULL,		NULL,		NULL,
-/* 2C */	NULL,		NULL,		NULL,		NULL,
-/* 30 */	NULL,		NULL,		NULL,		NULL,
-/* 34 */	NULL,		NULL,		NULL,		NULL,
-/* 38 */	NULL,		NULL,		NULL,		NULL,
-/* 3C */	NULL,		NULL,		NULL,		NULL,
-/* 40 */	NULL,		NULL,		NULL,		NULL,
-/* 44 */	NULL,		NULL,		NULL,		NULL,
-/* 48 */	NULL,		NULL,		NULL,		NULL,
-/* 4C */	NULL,		NULL,		NULL,		NULL,
-/* 50 */	NULL,		NULL,		NULL,		NULL,
-/* 54 */	NULL,		NULL,		NULL,		NULL,
-/* 58 */	NULL,		NULL,		NULL,		NULL,
-/* 5C */	NULL,		NULL,		NULL,		NULL,
-/* 60 */	NULL,		NULL,		NULL,		NULL,
-/* 64 */	NULL,		NULL,		NULL,		NULL,
-/* 68 */	NULL,		NULL,		NULL,		NULL,
-/* 6C */	NULL,		NULL,		NULL,		NULL,
-/* 70 */	NULL,		NULL,		NULL,		NULL,
-/* 74 */	NULL,		NULL,		NULL,		NULL,
-/* 78 */	NULL,		NULL,		NULL,		NULL,
-/* 7C */	NULL,		NULL,		NULL,		NULL,
-/* 80 */	NULL,		NULL,		NULL,		NULL,
-/* 84 */	NULL,		NULL,		NULL,		NULL,
-/* 88 */	NULL,		NULL,		"pfnacc",	NULL,
-/* 8C */	NULL,		NULL,		"pfpnacc",	NULL,
-/* 90 */	"pfcmpge",	NULL,		NULL,		NULL,
-/* 94 */	"pfmin",	NULL,		"pfrcp",	"pfrsqrt",
-/* 98 */	NULL,		NULL,		"pfsub",	NULL,
-/* 9C */	NULL,		NULL,		"pfadd",	NULL,
-/* A0 */	"pfcmpgt",	NULL,		NULL,		NULL,
-/* A4 */	"pfmax",	NULL,		"pfrcpit1",	"pfrsqit1",
-/* A8 */	NULL,		NULL,		"pfsubr",	NULL,
-/* AC */	NULL,		NULL,		"pfacc",	NULL,
-/* B0 */	"pfcmpeq",	NULL,		NULL,		NULL,
-/* B4 */	"pfmul",	NULL,		"pfrcpit2",	"pfmulhrw",
-/* B8 */	NULL,		NULL,		NULL,		"pswapd",
-/* BC */	NULL,		NULL,		NULL,		"pavgusb",
-/* C0 */	NULL,		NULL,		NULL,		NULL,
-/* C4 */	NULL,		NULL,		NULL,		NULL,
-/* C8 */	NULL,		NULL,		NULL,		NULL,
-/* CC */	NULL,		NULL,		NULL,		NULL,
-/* D0 */	NULL,		NULL,		NULL,		NULL,
-/* D4 */	NULL,		NULL,		NULL,		NULL,
-/* D8 */	NULL,		NULL,		NULL,		NULL,
-/* DC */	NULL,		NULL,		NULL,		NULL,
-/* E0 */	NULL,		NULL,		NULL,		NULL,
-/* E4 */	NULL,		NULL,		NULL,		NULL,
-/* E8 */	NULL,		NULL,		NULL,		NULL,
-/* EC */	NULL,		NULL,		NULL,		NULL,
-/* F0 */	NULL,		NULL,		NULL,		NULL,
-/* F4 */	NULL,		NULL,		NULL,		NULL,
-/* F8 */	NULL,		NULL,		NULL,		NULL,
-/* FC */	NULL,		NULL,		NULL,		NULL,
-};
-
-static void
-OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  const char *mnemonic;
-
-  FETCH_DATA (the_info, codep + 1);
-  /* AMD 3DNow! instructions are specified by an opcode suffix in the
-     place where an 8-bit immediate would normally go.  ie. the last
-     byte of the instruction.  */
-  obufp = obuf + strlen (obuf);
-  mnemonic = Suffix3DNow[*codep++ & 0xff];
-  if (mnemonic)
-    oappend (mnemonic);
-  else
-    {
-      /* Since a variable sized modrm/sib chunk is between the start
-	 of the opcode (0x0f0f) and the opcode suffix, we need to do
-	 all the modrm processing first, and don't know until now that
-	 we have a bad opcode.  This necessitates some cleaning up.  */
-      op1out[0] = '\0';
-      op2out[0] = '\0';
-      BadOp ();
-    }
-}
-
-static const char *simd_cmp_op[] = {
-  "eq",
-  "lt",
-  "le",
-  "unord",
-  "neq",
-  "nlt",
-  "nle",
-  "ord"
-};
-
-static void
-OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  unsigned int cmp_type;
-
-  FETCH_DATA (the_info, codep + 1);
-  obufp = obuf + strlen (obuf);
-  cmp_type = *codep++ & 0xff;
-  if (cmp_type < 8)
-    {
-      char suffix1 = 'p', suffix2 = 's';
-      used_prefixes |= (prefixes & PREFIX_REPZ);
-      if (prefixes & PREFIX_REPZ)
-	suffix1 = 's';
-      else
-	{
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  if (prefixes & PREFIX_DATA)
-	    suffix2 = 'd';
-	  else
-	    {
-	      used_prefixes |= (prefixes & PREFIX_REPNZ);
-	      if (prefixes & PREFIX_REPNZ)
-		suffix1 = 's', suffix2 = 'd';
-	    }
-	}
-      sprintf (scratchbuf, "cmp%s%c%c",
-	       simd_cmp_op[cmp_type], suffix1, suffix2);
-      used_prefixes |= (prefixes & PREFIX_REPZ);
-      oappend (scratchbuf);
-    }
-  else
-    {
-      /* We have a bad extension byte.  Clean up.  */
-      op1out[0] = '\0';
-      op2out[0] = '\0';
-      BadOp ();
-    }
-}
-
-static void
-SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
-{
-  /* Change movlps/movhps to movhlps/movlhps for 2 register operand
-     forms of these instructions.  */
-  if (mod == 3)
-    {
-      char *p = obuf + strlen (obuf);
-      *(p + 1) = '\0';
-      *p       = *(p - 1);
-      *(p - 1) = *(p - 2);
-      *(p - 2) = *(p - 3);
-      *(p - 3) = extrachar;
-    }
-}
-
-static void
-PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
-{
-  if (mod == 3 && reg == 1 && rm <= 1)
-    {
-      /* Override "sidt".  */
-      char *p = obuf + strlen (obuf) - 4;
-
-      /* We might have a suffix when disassembling with -Msuffix.  */
-      if (*p == 'i')
-	--p;
-
-      if (rm)
-	{
-	  /* mwait %eax,%ecx  */
-	  strcpy (p, "mwait");
-	  if (!intel_syntax)
-	    strcpy (op1out, names32[0]);
-	}
-      else
-	{
-	  /* monitor %eax,%ecx,%edx"  */
-	  strcpy (p, "monitor");
-	  if (!intel_syntax)
-	    {
-	      if (!mode_64bit)
-		strcpy (op1out, names32[0]);
-	      else if (!(prefixes & PREFIX_ADDR))
-		strcpy (op1out, names64[0]);
-	      else
-		{
-		  strcpy (op1out, names32[0]);
-		  used_prefixes |= PREFIX_ADDR;
-		}
-	      strcpy (op3out, names32[2]);
-	    }
-	}
-      if (!intel_syntax)
-	{
-	  strcpy (op2out, names32[1]);
-	  two_source_ops = 1;
-	}
-
-      codep++;
-    }
-  else
-    OP_M (0, sizeflag);
-}
-
-static void
-SVME_Fixup (int bytemode, int sizeflag)
-{
-  const char *alt;
-  char *p;
-
-  switch (*codep)
-    {
-    case 0xd8:
-      alt = "vmrun";
-      break;
-    case 0xd9:
-      alt = "vmmcall";
-      break;
-    case 0xda:
-      alt = "vmload";
-      break;
-    case 0xdb:
-      alt = "vmsave";
-      break;
-    case 0xdc:
-      alt = "stgi";
-      break;
-    case 0xdd:
-      alt = "clgi";
-      break;
-    case 0xde:
-      alt = "skinit";
-      break;
-    case 0xdf:
-      alt = "invlpga";
-      break;
-    default:
-      OP_M (bytemode, sizeflag);
-      return;
-    }
-  /* Override "lidt".  */
-  p = obuf + strlen (obuf) - 4;
-  /* We might have a suffix.  */
-  if (*p == 'i')
-    --p;
-  strcpy (p, alt);
-  if (!(prefixes & PREFIX_ADDR))
-    {
-      ++codep;
-      return;
-    }
-  used_prefixes |= PREFIX_ADDR;
-  switch (*codep++)
-    {
-    case 0xdf:
-      strcpy (op2out, names32[1]);
-      two_source_ops = 1;
-	  /* Fall through.  */
-    case 0xd8:
-    case 0xda:
-    case 0xdb:
-      *obufp++ = open_char;
-      if (mode_64bit || (sizeflag & AFLAG))
-        alt = names32[0];
-      else
-        alt = names16[0];
-      strcpy (obufp, alt);
-      obufp += strlen (alt);
-      *obufp++ = close_char;
-      *obufp = '\0';
-      break;
-    }
-}
-
-static void
-INVLPG_Fixup (int bytemode, int sizeflag)
-{
-  const char *alt;
-
-  switch (*codep)
-    {
-    case 0xf8:
-      alt = "swapgs";
-      break;
-    case 0xf9:
-      alt = "rdtscp";
-      break;
-    default:
-      OP_M (bytemode, sizeflag);
-      return;
-    }
-  /* Override "invlpg".  */
-  strcpy (obuf + strlen (obuf) - 6, alt);
-  codep++;
-}
-
-static void
-BadOp (void)
-{
-  /* Throw away prefixes and 1st. opcode byte.  */
-  codep = insn_codep + 1;
-  oappend ("(bad)");
-}
-
-static void
-SEG_Fixup (int extrachar, int sizeflag)
-{
-  if (mod == 3)
-    {
-      /* We need to add a proper suffix with
-
-		movw %ds,%ax
-		movl %ds,%eax
-		movq %ds,%rax
-		movw %ax,%ds
-		movl %eax,%ds
-		movq %rax,%ds
-       */
-      const char *suffix;
-
-      if (prefixes & PREFIX_DATA)
-	suffix = "w";
-      else
-	{
-	  USED_REX (REX_MODE64);
-	  if (rex & REX_MODE64)
-	    suffix = "q";
-	  else
-	    suffix = "l";
-	}
-      strcat (obuf, suffix);
-    }
-  else
-    {
-      /* We need to fix the suffix for
-
-		movw %ds,(%eax)
-		movw %ds,(%rax)
-		movw (%eax),%ds
-		movw (%rax),%ds
-
-	 Override "mov[l|q]".  */
-      char *p = obuf + strlen (obuf) - 1;
-
-      /* We might not have a suffix.  */
-      if (*p == 'v')
-	++p;
-      *p = 'w';
-    }
-
-  OP_E (extrachar, sizeflag);
-}
-
-static void
-VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
-{
-  if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
-    {
-      /* Override "sgdt".  */
-      char *p = obuf + strlen (obuf) - 4;
-
-      /* We might have a suffix when disassembling with -Msuffix.  */
-      if (*p == 'g')
-	--p;
-
-      switch (rm)
-	{
-	case 1:
-	  strcpy (p, "vmcall");
-	  break;
-	case 2:
-	  strcpy (p, "vmlaunch");
-	  break;
-	case 3:
-	  strcpy (p, "vmresume");
-	  break;
-	case 4:
-	  strcpy (p, "vmxoff");
-	  break;
-	}
-
-      codep++;
-    }
-  else
-    OP_E (0, sizeflag);
-}
-
-static void
-OP_VMX (int bytemode, int sizeflag)
-{
-  used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
-  if (prefixes & PREFIX_DATA)
-    strcpy (obuf, "vmclear");
-  else if (prefixes & PREFIX_REPZ)
-    strcpy (obuf, "vmxon");
-  else
-    strcpy (obuf, "vmptrld");
-  OP_E (bytemode, sizeflag);
-}
Index: xfs-dev/arch/x86/kdb/x86-dis.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ xfs-dev/arch/x86/kdb/x86-dis.c	2008-12-23 09:31:08.719321763 +0100
@@ -0,0 +1,4686 @@
+/* Print i386 instructions for GDB, the GNU debugger.
+   Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Run through col -b to remove trailing whitespace and various #ifdef/ifndef
+ * __KERNEL__ added.
+ * Keith Owens <kaos at sgi.com> 15 May 2006
+ */
+
+/* 80386 instruction printer by Pace Willisson (pace at prep.ai.mit.edu)
+   July 1988
+    modified by John Hassey (hassey at dg-rtp.dg.com)
+    x86-64 support added by Jan Hubicka (jh at suse.cz)
+    VIA PadLock support by Michal Ludvig (mludvig at suse.cz).  */
+
+/* The main tables describing the instructions is essentially a copy
+   of the "Opcode Map" chapter (Appendix A) of the Intel 80386
+   Programmers Manual.	Usually, there is a capital letter, followed
+   by a small letter.  The capital letter tell the addressing mode,
+   and the small letter tells about the operand size.  Refer to
+   the Intel manual for details.  */
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/dis-asm.h>
+#include <linux/kdb.h>
+#define abort() BUG()
+#else	/* __KERNEL__ */
+#include "dis-asm.h"
+#include "sysdep.h"
+#include "opintl.h"
+#endif	/* __KERNEL__ */
+
+#define MAXLEN 20
+
+#ifndef __KERNEL__
+#include <setjmp.h>
+#endif	/* __KERNEL__ */
+
+#ifndef UNIXWARE_COMPAT
+/* Set non-zero for broken, compatible instructions.  Set to zero for
+   non-broken opcodes.	*/
+#define UNIXWARE_COMPAT 1
+#endif
+
+static int fetch_data (struct disassemble_info *, bfd_byte *);
+static void ckprefix (void);
+static const char *prefix_name (int, int);
+static int print_insn (bfd_vma, disassemble_info *);
+static void dofloat (int);
+static void OP_ST (int, int);
+static void OP_STi (int, int);
+static int putop (const char *, int);
+static void oappend (const char *);
+static void append_seg (void);
+static void OP_indirE (int, int);
+static void print_operand_value (char *, int, bfd_vma);
+static void OP_E (int, int);
+static void OP_G (int, int);
+static bfd_vma get64 (void);
+static bfd_signed_vma get32 (void);
+static bfd_signed_vma get32s (void);
+static int get16 (void);
+static void set_op (bfd_vma, int);
+static void OP_REG (int, int);
+static void OP_IMREG (int, int);
+static void OP_I (int, int);
+static void OP_I64 (int, int);
+static void OP_sI (int, int);
+static void OP_J (int, int);
+static void OP_SEG (int, int);
+static void OP_DIR (int, int);
+static void OP_OFF (int, int);
+static void OP_OFF64 (int, int);
+static void ptr_reg (int, int);
+static void OP_ESreg (int, int);
+static void OP_DSreg (int, int);
+static void OP_C (int, int);
+static void OP_D (int, int);
+static void OP_T (int, int);
+static void OP_Rd (int, int);
+static void OP_MMX (int, int);
+static void OP_XMM (int, int);
+static void OP_EM (int, int);
+static void OP_EX (int, int);
+static void OP_MS (int, int);
+static void OP_XS (int, int);
+static void OP_M (int, int);
+static void OP_VMX (int, int);
+static void OP_0fae (int, int);
+static void OP_0f07 (int, int);
+static void NOP_Fixup (int, int);
+static void OP_3DNowSuffix (int, int);
+static void OP_SIMD_Suffix (int, int);
+static void SIMD_Fixup (int, int);
+static void PNI_Fixup (int, int);
+static void SVME_Fixup (int, int);
+static void INVLPG_Fixup (int, int);
+static void BadOp (void);
+static void SEG_Fixup (int, int);
+static void VMX_Fixup (int, int);
+
+struct dis_private {
+  /* Points to first byte not fetched.	*/
+  bfd_byte *max_fetched;
+  bfd_byte the_buffer[MAXLEN];
+  bfd_vma insn_start;
+  int orig_sizeflag;
+#ifndef __KERNEL__
+  jmp_buf bailout;
+#endif	/* __KERNEL__ */
+};
+
+/* The opcode for the fwait instruction, which we treat as a prefix
+   when we can.	 */
+#define FWAIT_OPCODE (0x9b)
+
+/* Set to 1 for 64bit mode disassembly.	 */
+static int mode_64bit;
+
+/* Flags for the prefixes for the current instruction.	See below.  */
+static int prefixes;
+
+/* REX prefix the current instruction.	See below.  */
+static int rex;
+/* Bits of REX we've already used.  */
+static int rex_used;
+#define REX_MODE64	8
+#define REX_EXTX	4
+#define REX_EXTY	2
+#define REX_EXTZ	1
+/* Mark parts used in the REX prefix.  When we are testing for
+   empty prefix (for 8bit register REX extension), just mask it
+   out.	 Otherwise test for REX bit is excuse for existence of REX
+   only in case value is nonzero.  */
+#define USED_REX(value)					\
+  {							\
+    if (value)						\
+      rex_used |= (rex & value) ? (value) | 0x40 : 0;	\
+    else						\
+      rex_used |= 0x40;					\
+  }
+
+/* Flags for prefixes which we somehow handled when printing the
+   current instruction.	 */
+static int used_prefixes;
+
+/* Flags stored in PREFIXES.  */
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADDR 0x400
+#define PREFIX_FWAIT 0x800
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
+   on error.  */
+#define FETCH_DATA(info, addr) \
+  ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
+   ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (struct disassemble_info *info, bfd_byte *addr)
+{
+  int status;
+  struct dis_private *priv = (struct dis_private *) info->private_data;
+  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+  status = (*info->read_memory_func) (start,
+				      priv->max_fetched,
+				      addr - priv->max_fetched,
+				      info);
+  if (status != 0)
+    {
+      /* If we did manage to read at least one byte, then
+	 print_insn_i386 will do something sensible.  Otherwise, print
+	 an error.  We do that here because this is where we know
+	 STATUS.  */
+      if (priv->max_fetched == priv->the_buffer)
+	(*info->memory_error_func) (status, start, info);
+#ifndef __KERNEL__
+      longjmp (priv->bailout, 1);
+#else	/* __KERNEL__ */
+	/* XXX - what to do? */
+	kdb_printf("Hmm. longjmp.\n");
+#endif	/* __KERNEL__ */
+    }
+  else
+    priv->max_fetched = addr;
+  return 1;
+}
+
+#define XX NULL, 0
+
+#define Eb OP_E, b_mode
+#define Ev OP_E, v_mode
+#define Ed OP_E, d_mode
+#define Eq OP_E, q_mode
+#define Edq OP_E, dq_mode
+#define Edqw OP_E, dqw_mode
+#define indirEv OP_indirE, branch_v_mode
+#define indirEp OP_indirE, f_mode
+#define Em OP_E, m_mode
+#define Ew OP_E, w_mode
+#define Ma OP_E, v_mode
+#define M OP_M, 0		/* lea, lgdt, etc. */
+#define Mp OP_M, f_mode		/* 32 or 48 bit memory operand for LDS, LES etc */
+#define Gb OP_G, b_mode
+#define Gv OP_G, v_mode
+#define Gd OP_G, d_mode
+#define Gdq OP_G, dq_mode
+#define Gm OP_G, m_mode
+#define Gw OP_G, w_mode
+#define Rd OP_Rd, d_mode
+#define Rm OP_Rd, m_mode
+#define Ib OP_I, b_mode
+#define sIb OP_sI, b_mode	/* sign extened byte */
+#define Iv OP_I, v_mode
+#define Iq OP_I, q_mode
+#define Iv64 OP_I64, v_mode
+#define Iw OP_I, w_mode
+#define I1 OP_I, const_1_mode
+#define Jb OP_J, b_mode
+#define Jv OP_J, v_mode
+#define Cm OP_C, m_mode
+#define Dm OP_D, m_mode
+#define Td OP_T, d_mode
+#define Sv SEG_Fixup, v_mode
+
+#define RMeAX OP_REG, eAX_reg
+#define RMeBX OP_REG, eBX_reg
+#define RMeCX OP_REG, eCX_reg
+#define RMeDX OP_REG, eDX_reg
+#define RMeSP OP_REG, eSP_reg
+#define RMeBP OP_REG, eBP_reg
+#define RMeSI OP_REG, eSI_reg
+#define RMeDI OP_REG, eDI_reg
+#define RMrAX OP_REG, rAX_reg
+#define RMrBX OP_REG, rBX_reg
+#define RMrCX OP_REG, rCX_reg
+#define RMrDX OP_REG, rDX_reg
+#define RMrSP OP_REG, rSP_reg
+#define RMrBP OP_REG, rBP_reg
+#define RMrSI OP_REG, rSI_reg
+#define RMrDI OP_REG, rDI_reg
+#define RMAL OP_REG, al_reg
+#define RMAL OP_REG, al_reg
+#define RMCL OP_REG, cl_reg
+#define RMDL OP_REG, dl_reg
+#define RMBL OP_REG, bl_reg
+#define RMAH OP_REG, ah_reg
+#define RMCH OP_REG, ch_reg
+#define RMDH OP_REG, dh_reg
+#define RMBH OP_REG, bh_reg
+#define RMAX OP_REG, ax_reg
+#define RMDX OP_REG, dx_reg
+
+#define eAX OP_IMREG, eAX_reg
+#define eBX OP_IMREG, eBX_reg
+#define eCX OP_IMREG, eCX_reg
+#define eDX OP_IMREG, eDX_reg
+#define eSP OP_IMREG, eSP_reg
+#define eBP OP_IMREG, eBP_reg
+#define eSI OP_IMREG, eSI_reg
+#define eDI OP_IMREG, eDI_reg
+#define AL OP_IMREG, al_reg
+#define AL OP_IMREG, al_reg
+#define CL OP_IMREG, cl_reg
+#define DL OP_IMREG, dl_reg
+#define BL OP_IMREG, bl_reg
+#define AH OP_IMREG, ah_reg
+#define CH OP_IMREG, ch_reg
+#define DH OP_IMREG, dh_reg
+#define BH OP_IMREG, bh_reg
+#define AX OP_IMREG, ax_reg
+#define DX OP_IMREG, dx_reg
+#define indirDX OP_IMREG, indir_dx_reg
+
+#define Sw OP_SEG, w_mode
+#define Ap OP_DIR, 0
+#define Ob OP_OFF, b_mode
+#define Ob64 OP_OFF64, b_mode
+#define Ov OP_OFF, v_mode
+#define Ov64 OP_OFF64, v_mode
+#define Xb OP_DSreg, eSI_reg
+#define Xv OP_DSreg, eSI_reg
+#define Yb OP_ESreg, eDI_reg
+#define Yv OP_ESreg, eDI_reg
+#define DSBX OP_DSreg, eBX_reg
+
+#define es OP_REG, es_reg
+#define ss OP_REG, ss_reg
+#define cs OP_REG, cs_reg
+#define ds OP_REG, ds_reg
+#define fs OP_REG, fs_reg
+#define gs OP_REG, gs_reg
+
+#define MX OP_MMX, 0
+#define XM OP_XMM, 0
+#define EM OP_EM, v_mode
+#define EX OP_EX, v_mode
+#define MS OP_MS, v_mode
+#define XS OP_XS, v_mode
+#define VM OP_VMX, q_mode
+#define OPSUF OP_3DNowSuffix, 0
+#define OPSIMD OP_SIMD_Suffix, 0
+
+#define cond_jump_flag NULL, cond_jump_mode
+#define loop_jcxz_flag NULL, loop_jcxz_mode
+
+/* bits in sizeflag */
+#define SUFFIX_ALWAYS 4
+#define AFLAG 2
+#define DFLAG 1
+
+#define b_mode 1  /* byte operand */
+#define v_mode 2  /* operand size depends on prefixes */
+#define w_mode 3  /* word operand */
+#define d_mode 4  /* double word operand  */
+#define q_mode 5  /* quad word operand */
+#define t_mode 6  /* ten-byte operand */
+#define x_mode 7  /* 16-byte XMM operand */
+#define m_mode 8  /* d_mode in 32bit, q_mode in 64bit mode.  */
+#define cond_jump_mode 9
+#define loop_jcxz_mode 10
+#define dq_mode 11 /* operand size depends on REX prefixes.  */
+#define dqw_mode 12 /* registers like dq_mode, memory like w_mode.  */
+#define f_mode 13 /* 4- or 6-byte pointer operand */
+#define const_1_mode 14
+#define branch_v_mode 15 /* v_mode for branch.	*/
+
+#define es_reg 100
+#define cs_reg 101
+#define ss_reg 102
+#define ds_reg 103
+#define fs_reg 104
+#define gs_reg 105
+
+#define eAX_reg 108
+#define eCX_reg 109
+#define eDX_reg 110
+#define eBX_reg 111
+#define eSP_reg 112
+#define eBP_reg 113
+#define eSI_reg 114
+#define eDI_reg 115
+
+#define al_reg 116
+#define cl_reg 117
+#define dl_reg 118
+#define bl_reg 119
+#define ah_reg 120
+#define ch_reg 121
+#define dh_reg 122
+#define bh_reg 123
+
+#define ax_reg 124
+#define cx_reg 125
+#define dx_reg 126
+#define bx_reg 127
+#define sp_reg 128
+#define bp_reg 129
+#define si_reg 130
+#define di_reg 131
+
+#define rAX_reg 132
+#define rCX_reg 133
+#define rDX_reg 134
+#define rBX_reg 135
+#define rSP_reg 136
+#define rBP_reg 137
+#define rSI_reg 138
+#define rDI_reg 139
+
+#define indir_dx_reg 150
+
+#define FLOATCODE 1
+#define USE_GROUPS 2
+#define USE_PREFIX_USER_TABLE 3
+#define X86_64_SPECIAL 4
+
+#define FLOAT	  NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
+
+#define GRP1b	  NULL, NULL, USE_GROUPS, NULL,	 0, NULL, 0
+#define GRP1S	  NULL, NULL, USE_GROUPS, NULL,	 1, NULL, 0
+#define GRP1Ss	  NULL, NULL, USE_GROUPS, NULL,	 2, NULL, 0
+#define GRP2b	  NULL, NULL, USE_GROUPS, NULL,	 3, NULL, 0
+#define GRP2S	  NULL, NULL, USE_GROUPS, NULL,	 4, NULL, 0
+#define GRP2b_one NULL, NULL, USE_GROUPS, NULL,	 5, NULL, 0
+#define GRP2S_one NULL, NULL, USE_GROUPS, NULL,	 6, NULL, 0
+#define GRP2b_cl  NULL, NULL, USE_GROUPS, NULL,	 7, NULL, 0
+#define GRP2S_cl  NULL, NULL, USE_GROUPS, NULL,	 8, NULL, 0
+#define GRP3b	  NULL, NULL, USE_GROUPS, NULL,	 9, NULL, 0
+#define GRP3S	  NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
+#define GRP4	  NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
+#define GRP5	  NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
+#define GRP6	  NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
+#define GRP7	  NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
+#define GRP8	  NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
+#define GRP9	  NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
+#define GRP10	  NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
+#define GRP11	  NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
+#define GRP12	  NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
+#define GRP13	  NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
+#define GRP14	  NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
+#define GRPAMD	  NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
+#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
+#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
+
+#define PREGRP0	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  0, NULL, 0
+#define PREGRP1	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  1, NULL, 0
+#define PREGRP2	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  2, NULL, 0
+#define PREGRP3	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  3, NULL, 0
+#define PREGRP4	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  4, NULL, 0
+#define PREGRP5	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  5, NULL, 0
+#define PREGRP6	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  6, NULL, 0
+#define PREGRP7	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  7, NULL, 0
+#define PREGRP8	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  8, NULL, 0
+#define PREGRP9	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  9, NULL, 0
+#define PREGRP10  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
+#define PREGRP11  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
+#define PREGRP12  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
+#define PREGRP13  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
+#define PREGRP14  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
+#define PREGRP15  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
+#define PREGRP16  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
+#define PREGRP17  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
+#define PREGRP18  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
+#define PREGRP19  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
+#define PREGRP20  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
+#define PREGRP21  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
+#define PREGRP22  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
+#define PREGRP23  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
+#define PREGRP24  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
+#define PREGRP25  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
+#define PREGRP26  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
+#define PREGRP27  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
+#define PREGRP28  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
+#define PREGRP29  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
+#define PREGRP30  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
+#define PREGRP31  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
+#define PREGRP32  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
+
+#define X86_64_0  NULL, NULL, X86_64_SPECIAL, NULL,  0, NULL, 0
+
+typedef void (*op_rtn) (int bytemode, int sizeflag);
+
+struct dis386 {
+  const char *name;
+  op_rtn op1;
+  int bytemode1;
+  op_rtn op2;
+  int bytemode2;
+  op_rtn op3;
+  int bytemode3;
+};
+
+/* Upper case letters in the instruction names here are macros.
+   'A' => print 'b' if no register operands or suffix_always is true
+   'B' => print 'b' if suffix_always is true
+   'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
+   .	  size prefix
+   'E' => print 'e' if 32-bit form of jcxz
+   'F' => print 'w' or 'l' depending on address size prefix (loop insns)
+   'H' => print ",pt" or ",pn" branch hint
+   'I' => honor following macro letter even in Intel mode (implemented only
+   .	  for some of the macro letters)
+   'J' => print 'l'
+   'L' => print 'l' if suffix_always is true
+   'N' => print 'n' if instruction has no wait "prefix"
+   'O' => print 'd', or 'o'
+   'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
+   .	  or suffix_always is true.  print 'q' if rex prefix is present.
+   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
+   .	  is true
+   'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
+   'S' => print 'w', 'l' or 'q' if suffix_always is true
+   'T' => print 'q' in 64bit mode and behave as 'P' otherwise
+   'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
+   'W' => print 'b' or 'w' ("w" or "de" in intel mode)
+   'X' => print 's', 'd' depending on data16 prefix (for XMM)
+   'Y' => 'q' if instruction has an REX 64bit overwrite prefix
+
+   Many of the above letters print nothing in Intel mode.  See "putop"
+   for the details.
+
+   Braces '{' and '}', and vertical bars '|', indicate alternative
+   mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
+   modes.  In cases where there are only two alternatives, the X86_64
+   instruction is reserved, and "(bad)" is printed.
+*/
+
+static const struct dis386 dis386[] = {
+  /* 00 */
+  { "addB",		Eb, Gb, XX },
+  { "addS",		Ev, Gv, XX },
+  { "addB",		Gb, Eb, XX },
+  { "addS",		Gv, Ev, XX },
+  { "addB",		AL, Ib, XX },
+  { "addS",		eAX, Iv, XX },
+  { "push{T|}",		es, XX, XX },
+  { "pop{T|}",		es, XX, XX },
+  /* 08 */
+  { "orB",		Eb, Gb, XX },
+  { "orS",		Ev, Gv, XX },
+  { "orB",		Gb, Eb, XX },
+  { "orS",		Gv, Ev, XX },
+  { "orB",		AL, Ib, XX },
+  { "orS",		eAX, Iv, XX },
+  { "push{T|}",		cs, XX, XX },
+  { "(bad)",		XX, XX, XX },	/* 0x0f extended opcode escape */
+  /* 10 */
+  { "adcB",		Eb, Gb, XX },
+  { "adcS",		Ev, Gv, XX },
+  { "adcB",		Gb, Eb, XX },
+  { "adcS",		Gv, Ev, XX },
+  { "adcB",		AL, Ib, XX },
+  { "adcS",		eAX, Iv, XX },
+  { "push{T|}",		ss, XX, XX },
+  { "popT|}",		ss, XX, XX },
+  /* 18 */
+  { "sbbB",		Eb, Gb, XX },
+  { "sbbS",		Ev, Gv, XX },
+  { "sbbB",		Gb, Eb, XX },
+  { "sbbS",		Gv, Ev, XX },
+  { "sbbB",		AL, Ib, XX },
+  { "sbbS",		eAX, Iv, XX },
+  { "push{T|}",		ds, XX, XX },
+  { "pop{T|}",		ds, XX, XX },
+  /* 20 */
+  { "andB",		Eb, Gb, XX },
+  { "andS",		Ev, Gv, XX },
+  { "andB",		Gb, Eb, XX },
+  { "andS",		Gv, Ev, XX },
+  { "andB",		AL, Ib, XX },
+  { "andS",		eAX, Iv, XX },
+  { "(bad)",		XX, XX, XX },	/* SEG ES prefix */
+  { "daa{|}",		XX, XX, XX },
+  /* 28 */
+  { "subB",		Eb, Gb, XX },
+  { "subS",		Ev, Gv, XX },
+  { "subB",		Gb, Eb, XX },
+  { "subS",		Gv, Ev, XX },
+  { "subB",		AL, Ib, XX },
+  { "subS",		eAX, Iv, XX },
+  { "(bad)",		XX, XX, XX },	/* SEG CS prefix */
+  { "das{|}",		XX, XX, XX },
+  /* 30 */
+  { "xorB",		Eb, Gb, XX },
+  { "xorS",		Ev, Gv, XX },
+  { "xorB",		Gb, Eb, XX },
+  { "xorS",		Gv, Ev, XX },
+  { "xorB",		AL, Ib, XX },
+  { "xorS",		eAX, Iv, XX },
+  { "(bad)",		XX, XX, XX },	/* SEG SS prefix */
+  { "aaa{|}",		XX, XX, XX },
+  /* 38 */
+  { "cmpB",		Eb, Gb, XX },
+  { "cmpS",		Ev, Gv, XX },
+  { "cmpB",		Gb, Eb, XX },
+  { "cmpS",		Gv, Ev, XX },
+  { "cmpB",		AL, Ib, XX },
+  { "cmpS",		eAX, Iv, XX },
+  { "(bad)",		XX, XX, XX },	/* SEG DS prefix */
+  { "aas{|}",		XX, XX, XX },
+  /* 40 */
+  { "inc{S|}",		RMeAX, XX, XX },
+  { "inc{S|}",		RMeCX, XX, XX },
+  { "inc{S|}",		RMeDX, XX, XX },
+  { "inc{S|}",		RMeBX, XX, XX },
+  { "inc{S|}",		RMeSP, XX, XX },
+  { "inc{S|}",		RMeBP, XX, XX },
+  { "inc{S|}",		RMeSI, XX, XX },
+  { "inc{S|}",		RMeDI, XX, XX },
+  /* 48 */
+  { "dec{S|}",		RMeAX, XX, XX },
+  { "dec{S|}",		RMeCX, XX, XX },
+  { "dec{S|}",		RMeDX, XX, XX },
+  { "dec{S|}",		RMeBX, XX, XX },
+  { "dec{S|}",		RMeSP, XX, XX },
+  { "dec{S|}",		RMeBP, XX, XX },
+  { "dec{S|}",		RMeSI, XX, XX },
+  { "dec{S|}",		RMeDI, XX, XX },
+  /* 50 */
+  { "pushS",		RMrAX, XX, XX },
+  { "pushS",		RMrCX, XX, XX },
+  { "pushS",		RMrDX, XX, XX },
+  { "pushS",		RMrBX, XX, XX },
+  { "pushS",		RMrSP, XX, XX },
+  { "pushS",		RMrBP, XX, XX },
+  { "pushS",		RMrSI, XX, XX },
+  { "pushS",		RMrDI, XX, XX },
+  /* 58 */
+  { "popS",		RMrAX, XX, XX },
+  { "popS",		RMrCX, XX, XX },
+  { "popS",		RMrDX, XX, XX },
+  { "popS",		RMrBX, XX, XX },
+  { "popS",		RMrSP, XX, XX },
+  { "popS",		RMrBP, XX, XX },
+  { "popS",		RMrSI, XX, XX },
+  { "popS",		RMrDI, XX, XX },
+  /* 60 */
+  { "pusha{P|}",	XX, XX, XX },
+  { "popa{P|}",		XX, XX, XX },
+  { "bound{S|}",	Gv, Ma, XX },
+  { X86_64_0 },
+  { "(bad)",		XX, XX, XX },	/* seg fs */
+  { "(bad)",		XX, XX, XX },	/* seg gs */
+  { "(bad)",		XX, XX, XX },	/* op size prefix */
+  { "(bad)",		XX, XX, XX },	/* adr size prefix */
+  /* 68 */
+  { "pushT",		Iq, XX, XX },
+  { "imulS",		Gv, Ev, Iv },
+  { "pushT",		sIb, XX, XX },
+  { "imulS",		Gv, Ev, sIb },
+  { "ins{b||b|}",	Yb, indirDX, XX },
+  { "ins{R||R|}",	Yv, indirDX, XX },
+  { "outs{b||b|}",	indirDX, Xb, XX },
+  { "outs{R||R|}",	indirDX, Xv, XX },
+  /* 70 */
+  { "joH",		Jb, XX, cond_jump_flag },
+  { "jnoH",		Jb, XX, cond_jump_flag },
+  { "jbH",		Jb, XX, cond_jump_flag },
+  { "jaeH",		Jb, XX, cond_jump_flag },
+  { "jeH",		Jb, XX, cond_jump_flag },
+  { "jneH",		Jb, XX, cond_jump_flag },
+  { "jbeH",		Jb, XX, cond_jump_flag },
+  { "jaH",		Jb, XX, cond_jump_flag },
+  /* 78 */
+  { "jsH",		Jb, XX, cond_jump_flag },
+  { "jnsH",		Jb, XX, cond_jump_flag },
+  { "jpH",		Jb, XX, cond_jump_flag },
+  { "jnpH",		Jb, XX, cond_jump_flag },
+  { "jlH",		Jb, XX, cond_jump_flag },
+  { "jgeH",		Jb, XX, cond_jump_flag },
+  { "jleH",		Jb, XX, cond_jump_flag },
+  { "jgH",		Jb, XX, cond_jump_flag },
+  /* 80 */
+  { GRP1b },
+  { GRP1S },
+  { "(bad)",		XX, XX, XX },
+  { GRP1Ss },
+  { "testB",		Eb, Gb, XX },
+  { "testS",		Ev, Gv, XX },
+  { "xchgB",		Eb, Gb, XX },
+  { "xchgS",		Ev, Gv, XX },
+  /* 88 */
+  { "movB",		Eb, Gb, XX },
+  { "movS",		Ev, Gv, XX },
+  { "movB",		Gb, Eb, XX },
+  { "movS",		Gv, Ev, XX },
+  { "movQ",		Sv, Sw, XX },
+  { "leaS",		Gv, M, XX },
+  { "movQ",		Sw, Sv, XX },
+  { "popU",		Ev, XX, XX },
+  /* 90 */
+  { "nop",		NOP_Fixup, 0, XX, XX },
+  { "xchgS",		RMeCX, eAX, XX },
+  { "xchgS",		RMeDX, eAX, XX },
+  { "xchgS",		RMeBX, eAX, XX },
+  { "xchgS",		RMeSP, eAX, XX },
+  { "xchgS",		RMeBP, eAX, XX },
+  { "xchgS",		RMeSI, eAX, XX },
+  { "xchgS",		RMeDI, eAX, XX },
+  /* 98 */
+  { "cW{tR||tR|}",	XX, XX, XX },
+  { "cR{tO||tO|}",	XX, XX, XX },
+  { "Jcall{T|}",	Ap, XX, XX },
+  { "(bad)",		XX, XX, XX },	/* fwait */
+  { "pushfT",		XX, XX, XX },
+  { "popfT",		XX, XX, XX },
+  { "sahf{|}",		XX, XX, XX },
+  { "lahf{|}",		XX, XX, XX },
+  /* a0 */
+  { "movB",		AL, Ob64, XX },
+  { "movS",		eAX, Ov64, XX },
+  { "movB",		Ob64, AL, XX },
+  { "movS",		Ov64, eAX, XX },
+  { "movs{b||b|}",	Yb, Xb, XX },
+  { "movs{R||R|}",	Yv, Xv, XX },
+  { "cmps{b||b|}",	Xb, Yb, XX },
+  { "cmps{R||R|}",	Xv, Yv, XX },
+  /* a8 */
+  { "testB",		AL, Ib, XX },
+  { "testS",		eAX, Iv, XX },
+  { "stosB",		Yb, AL, XX },
+  { "stosS",		Yv, eAX, XX },
+  { "lodsB",		AL, Xb, XX },
+  { "lodsS",		eAX, Xv, XX },
+  { "scasB",		AL, Yb, XX },
+  { "scasS",		eAX, Yv, XX },
+  /* b0 */
+  { "movB",		RMAL, Ib, XX },
+  { "movB",		RMCL, Ib, XX },
+  { "movB",		RMDL, Ib, XX },
+  { "movB",		RMBL, Ib, XX },
+  { "movB",		RMAH, Ib, XX },
+  { "movB",		RMCH, Ib, XX },
+  { "movB",		RMDH, Ib, XX },
+  { "movB",		RMBH, Ib, XX },
+  /* b8 */
+  { "movS",		RMeAX, Iv64, XX },
+  { "movS",		RMeCX, Iv64, XX },
+  { "movS",		RMeDX, Iv64, XX },
+  { "movS",		RMeBX, Iv64, XX },
+  { "movS",		RMeSP, Iv64, XX },
+  { "movS",		RMeBP, Iv64, XX },
+  { "movS",		RMeSI, Iv64, XX },
+  { "movS",		RMeDI, Iv64, XX },
+  /* c0 */
+  { GRP2b },
+  { GRP2S },
+  { "retT",		Iw, XX, XX },
+  { "retT",		XX, XX, XX },
+  { "les{S|}",		Gv, Mp, XX },
+  { "ldsS",		Gv, Mp, XX },
+  { "movA",		Eb, Ib, XX },
+  { "movQ",		Ev, Iv, XX },
+  /* c8 */
+  { "enterT",		Iw, Ib, XX },
+  { "leaveT",		XX, XX, XX },
+  { "lretP",		Iw, XX, XX },
+  { "lretP",		XX, XX, XX },
+  { "int3",		XX, XX, XX },
+  { "int",		Ib, XX, XX },
+  { "into{|}",		XX, XX, XX },
+  { "iretP",		XX, XX, XX },
+  /* d0 */
+  { GRP2b_one },
+  { GRP2S_one },
+  { GRP2b_cl },
+  { GRP2S_cl },
+  { "aam{|}",		sIb, XX, XX },
+  { "aad{|}",		sIb, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "xlat",		DSBX, XX, XX },
+  /* d8 */
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  /* e0 */
+  { "loopneFH",		Jb, XX, loop_jcxz_flag },
+  { "loopeFH",		Jb, XX, loop_jcxz_flag },
+  { "loopFH",		Jb, XX, loop_jcxz_flag },
+  { "jEcxzH",		Jb, XX, loop_jcxz_flag },
+  { "inB",		AL, Ib, XX },
+  { "inS",		eAX, Ib, XX },
+  { "outB",		Ib, AL, XX },
+  { "outS",		Ib, eAX, XX },
+  /* e8 */
+  { "callT",		Jv, XX, XX },
+  { "jmpT",		Jv, XX, XX },
+  { "Jjmp{T|}",		Ap, XX, XX },
+  { "jmp",		Jb, XX, XX },
+  { "inB",		AL, indirDX, XX },
+  { "inS",		eAX, indirDX, XX },
+  { "outB",		indirDX, AL, XX },
+  { "outS",		indirDX, eAX, XX },
+  /* f0 */
+  { "(bad)",		XX, XX, XX },	/* lock prefix */
+  { "icebp",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },	/* repne */
+  { "(bad)",		XX, XX, XX },	/* repz */
+  { "hlt",		XX, XX, XX },
+  { "cmc",		XX, XX, XX },
+  { GRP3b },
+  { GRP3S },
+  /* f8 */
+  { "clc",		XX, XX, XX },
+  { "stc",		XX, XX, XX },
+  { "cli",		XX, XX, XX },
+  { "sti",		XX, XX, XX },
+  { "cld",		XX, XX, XX },
+  { "std",		XX, XX, XX },
+  { GRP4 },
+  { GRP5 },
+};
+
+static const struct dis386 dis386_twobyte[] = {
+  /* 00 */
+  { GRP6 },
+  { GRP7 },
+  { "larS",		Gv, Ew, XX },
+  { "lslS",		Gv, Ew, XX },
+  { "(bad)",		XX, XX, XX },
+  { "syscall",		XX, XX, XX },
+  { "clts",		XX, XX, XX },
+  { "sysretP",		XX, XX, XX },
+  /* 08 */
+  { "invd",		XX, XX, XX },
+  { "wbinvd",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "ud2a",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { GRPAMD },
+  { "femms",		XX, XX, XX },
+  { "",			MX, EM, OPSUF }, /* See OP_3DNowSuffix.	 */
+  /* 10 */
+  { PREGRP8 },
+  { PREGRP9 },
+  { PREGRP30 },
+  { "movlpX",		EX, XM, SIMD_Fixup, 'h' },
+  { "unpcklpX",		XM, EX, XX },
+  { "unpckhpX",		XM, EX, XX },
+  { PREGRP31 },
+  { "movhpX",		EX, XM, SIMD_Fixup, 'l' },
+  /* 18 */
+  { GRP14 },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  /* 20 */
+  { "movL",		Rm, Cm, XX },
+  { "movL",		Rm, Dm, XX },
+  { "movL",		Cm, Rm, XX },
+  { "movL",		Dm, Rm, XX },
+  { "movL",		Rd, Td, XX },
+  { "(bad)",		XX, XX, XX },
+  { "movL",		Td, Rd, XX },
+  { "(bad)",		XX, XX, XX },
+  /* 28 */
+  { "movapX",		XM, EX, XX },
+  { "movapX",		EX, XM, XX },
+  { PREGRP2 },
+  { "movntpX",		Ev, XM, XX },
+  { PREGRP4 },
+  { PREGRP3 },
+  { "ucomisX",		XM,EX, XX },
+  { "comisX",		XM,EX, XX },
+  /* 30 */
+  { "wrmsr",		XX, XX, XX },
+  { "rdtsc",		XX, XX, XX },
+  { "rdmsr",		XX, XX, XX },
+  { "rdpmc",		XX, XX, XX },
+  { "sysenter",		XX, XX, XX },
+  { "sysexit",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  /* 38 */
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  /* 40 */
+  { "cmovo",		Gv, Ev, XX },
+  { "cmovno",		Gv, Ev, XX },
+  { "cmovb",		Gv, Ev, XX },
+  { "cmovae",		Gv, Ev, XX },
+  { "cmove",		Gv, Ev, XX },
+  { "cmovne",		Gv, Ev, XX },
+  { "cmovbe",		Gv, Ev, XX },
+  { "cmova",		Gv, Ev, XX },
+  /* 48 */
+  { "cmovs",		Gv, Ev, XX },
+  { "cmovns",		Gv, Ev, XX },
+  { "cmovp",		Gv, Ev, XX },
+  { "cmovnp",		Gv, Ev, XX },
+  { "cmovl",		Gv, Ev, XX },
+  { "cmovge",		Gv, Ev, XX },
+  { "cmovle",		Gv, Ev, XX },
+  { "cmovg",		Gv, Ev, XX },
+  /* 50 */
+  { "movmskpX",		Gdq, XS, XX },
+  { PREGRP13 },
+  { PREGRP12 },
+  { PREGRP11 },
+  { "andpX",		XM, EX, XX },
+  { "andnpX",		XM, EX, XX },
+  { "orpX",		XM, EX, XX },
+  { "xorpX",		XM, EX, XX },
+  /* 58 */
+  { PREGRP0 },
+  { PREGRP10 },
+  { PREGRP17 },
+  { PREGRP16 },
+  { PREGRP14 },
+  { PREGRP7 },
+  { PREGRP5 },
+  { PREGRP6 },
+  /* 60 */
+  { "punpcklbw",	MX, EM, XX },
+  { "punpcklwd",	MX, EM, XX },
+  { "punpckldq",	MX, EM, XX },
+  { "packsswb",		MX, EM, XX },
+  { "pcmpgtb",		MX, EM, XX },
+  { "pcmpgtw",		MX, EM, XX },
+  { "pcmpgtd",		MX, EM, XX },
+  { "packuswb",		MX, EM, XX },
+  /* 68 */
+  { "punpckhbw",	MX, EM, XX },
+  { "punpckhwd",	MX, EM, XX },
+  { "punpckhdq",	MX, EM, XX },
+  { "packssdw",		MX, EM, XX },
+  { PREGRP26 },
+  { PREGRP24 },
+  { "movd",		MX, Edq, XX },
+  { PREGRP19 },
+  /* 70 */
+  { PREGRP22 },
+  { GRP10 },
+  { GRP11 },
+  { GRP12 },
+  { "pcmpeqb",		MX, EM, XX },
+  { "pcmpeqw",		MX, EM, XX },
+  { "pcmpeqd",		MX, EM, XX },
+  { "emms",		XX, XX, XX },
+  /* 78 */
+  { "vmread",		Em, Gm, XX },
+  { "vmwrite",		Gm, Em, XX },
+  { "(bad)",		XX, XX, XX },
+  { "(bad)",		XX, XX, XX },
+  { PREGRP28 },
+  { PREGRP29 },
+  { PREGRP23 },
+  { PREGRP20 },
+  /* 80 */
+  { "joH",		Jv, XX, cond_jump_flag },
+  { "jnoH",		Jv, XX, cond_jump_flag },
+  { "jbH",		Jv, XX, cond_jump_flag },
+  { "jaeH",		Jv, XX, cond_jump_flag },
+  { "jeH",		Jv, XX, cond_jump_flag },
+  { "jneH",		Jv, XX, cond_jump_flag },
+  { "jbeH",		Jv, XX, cond_jump_flag },
+  { "jaH",		Jv, XX, cond_jump_flag },
+  /* 88 */
+  { "jsH",		Jv, XX, cond_jump_flag },
+  { "jnsH",		Jv, XX, cond_jump_flag },
+  { "jpH",		Jv, XX, cond_jump_flag },
+  { "jnpH",		Jv, XX, cond_jump_flag },
+  { "jlH",		Jv, XX, cond_jump_flag },
+  { "jgeH",		Jv, XX, cond_jump_flag },
+  { "jleH",		Jv, XX, cond_jump_flag },
+  { "jgH",		Jv, XX, cond_jump_flag },
+  /* 90 */
+  { "seto",		Eb, XX, XX },
+  { "setno",		Eb, XX, XX },
+  { "setb",		Eb, XX, XX },
+  { "setae",		Eb, XX, XX },
+  { "sete",		Eb, XX, XX },
+  { "setne",		Eb, XX, XX },
+  { "setbe",		Eb, XX, XX },
+  { "seta",		Eb, XX, XX },
+  /* 98 */
+  { "sets",		Eb, XX, XX },
+  { "setns",		Eb, XX, XX },
+  { "setp",		Eb, XX, XX },
+  { "setnp",		Eb, XX, XX },
+  { "setl",		Eb, XX, XX },
+  { "setge",		Eb, XX, XX },
+  { "setle",		Eb, XX, XX },
+  { "setg",		Eb, XX, XX },
+  /* a0 */
+  { "pushT",		fs, XX, XX },
+  { "popT",		fs, XX, XX },
+  { "cpuid",		XX, XX, XX },
+  { "btS",		Ev, Gv, XX },
+  { "shldS",		Ev, Gv, Ib },
+  { "shldS",		Ev, Gv, CL },
+  { GRPPADLCK2 },
+  { GRPPADLCK1 },
+  /* a8 */
+  { "pushT",		gs, XX, XX },
+  { "popT",		gs, XX, XX },
+  { "rsm",		XX, XX, XX },
+  { "btsS",		Ev, Gv, XX },
+  { "shrdS",		Ev, Gv, Ib },
+  { "shrdS",		Ev, Gv, CL },
+  { GRP13 },
+  { "imulS",		Gv, Ev, XX },
+  /* b0 */
+  { "cmpxchgB",		Eb, Gb, XX },
+  { "cmpxchgS",		Ev, Gv, XX },
+  { "lssS",		Gv, Mp, XX },
+  { "btrS",		Ev, Gv, XX },
+  { "lfsS",		Gv, Mp, XX },
+  { "lgsS",		Gv, Mp, XX },
+  { "movz{bR|x|bR|x}",	Gv, Eb, XX },
+  { "movz{wR|x|wR|x}",	Gv, Ew, XX }, /* yes, there really is movzww ! */
+  /* b8 */
+  { "(bad)",		XX, XX, XX },
+  { "ud2b",		XX, XX, XX },
+  { GRP8 },
+  { "btcS",		Ev, Gv, XX },
+  { "bsfS",		Gv, Ev, XX },
+  { "bsrS",		Gv, Ev, XX },
+  { "movs{bR|x|bR|x}",	Gv, Eb, XX },
+  { "movs{wR|x|wR|x}",	Gv, Ew, XX }, /* yes, there really is movsww ! */
+  /* c0 */
+  { "xaddB",		Eb, Gb, XX },
+  { "xaddS",		Ev, Gv, XX },
+  { PREGRP1 },
+  { "movntiS",		Ev, Gv, XX },
+  { "pinsrw",		MX, Edqw, Ib },
+  { "pextrw",		Gdq, MS, Ib },
+  { "shufpX",		XM, EX, Ib },
+  { GRP9 },
+  /* c8 */
+  { "bswap",		RMeAX, XX, XX },
+  { "bswap",		RMeCX, XX, XX },
+  { "bswap",		RMeDX, XX, XX },
+  { "bswap",		RMeBX, XX, XX },
+  { "bswap",		RMeSP, XX, XX },
+  { "bswap",		RMeBP, XX, XX },
+  { "bswap",		RMeSI, XX, XX },
+  { "bswap",		RMeDI, XX, XX },
+  /* d0 */
+  { PREGRP27 },
+  { "psrlw",		MX, EM, XX },
+  { "psrld",		MX, EM, XX },
+  { "psrlq",		MX, EM, XX },
+  { "paddq",		MX, EM, XX },
+  { "pmullw",		MX, EM, XX },
+  { PREGRP21 },
+  { "pmovmskb",		Gdq, MS, XX },
+  /* d8 */
+  { "psubusb",		MX, EM, XX },
+  { "psubusw",		MX, EM, XX },
+  { "pminub",		MX, EM, XX },
+  { "pand",		MX, EM, XX },
+  { "paddusb",		MX, EM, XX },
+  { "paddusw",		MX, EM, XX },
+  { "pmaxub",		MX, EM, XX },
+  { "pandn",		MX, EM, XX },
+  /* e0 */
+  { "pavgb",		MX, EM, XX },
+  { "psraw",		MX, EM, XX },
+  { "psrad",		MX, EM, XX },
+  { "pavgw",		MX, EM, XX },
+  { "pmulhuw",		MX, EM, XX },
+  { "pmulhw",		MX, EM, XX },
+  { PREGRP15 },
+  { PREGRP25 },
+  /* e8 */
+  { "psubsb",		MX, EM, XX },
+  { "psubsw",		MX, EM, XX },
+  { "pminsw",		MX, EM, XX },
+  { "por",		MX, EM, XX },
+  { "paddsb",		MX, EM, XX },
+  { "paddsw",		MX, EM, XX },
+  { "pmaxsw",		MX, EM, XX },
+  { "pxor",		MX, EM, XX },
+  /* f0 */
+  { PREGRP32 },
+  { "psllw",		MX, EM, XX },
+  { "pslld",		MX, EM, XX },
+  { "psllq",		MX, EM, XX },
+  { "pmuludq",		MX, EM, XX },
+  { "pmaddwd",		MX, EM, XX },
+  { "psadbw",		MX, EM, XX },
+  { PREGRP18 },
+  /* f8 */
+  { "psubb",		MX, EM, XX },
+  { "psubw",		MX, EM, XX },
+  { "psubd",		MX, EM, XX },
+  { "psubq",		MX, EM, XX },
+  { "paddb",		MX, EM, XX },
+  { "paddw",		MX, EM, XX },
+  { "paddd",		MX, EM, XX },
+  { "(bad)",		XX, XX, XX }
+};
+
+static const unsigned char onebyte_has_modrm[256] = {
+  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
+  /*	   -------------------------------	  */
+  /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
+  /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
+  /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
+  /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
+  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
+  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
+  /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
+  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
+  /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
+  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
+  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
+  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
+  /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
+  /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
+  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
+  /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
+  /*	   -------------------------------	  */
+  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
+};
+
+static const unsigned char twobyte_has_modrm[256] = {
+  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
+  /*	   -------------------------------	  */
+  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
+  /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
+  /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
+  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
+  /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
+  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
+  /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
+  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
+  /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
+  /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
+  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
+  /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
+  /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
+  /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
+  /*	   -------------------------------	  */
+  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
+};
+
+static const unsigned char twobyte_uses_SSE_prefix[256] = {
+  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
+  /*	   -------------------------------	  */
+  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
+  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
+  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
+  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
+  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
+  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
+  /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
+  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
+  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
+  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
+  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
+  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
+  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
+  /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0  /* ff */
+  /*	   -------------------------------	  */
+  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
+};
+
+static char obuf[100];
+static char *obufp;
+static char scratchbuf[100];
+static unsigned char *start_codep;
+static unsigned char *insn_codep;
+static unsigned char *codep;
+static disassemble_info *the_info;
+static int mod;
+static int rm;
+static int reg;
+static unsigned char need_modrm;
+
+/* If we are accessing mod/rm/reg without need_modrm set, then the
+   values are stale.  Hitting this abort likely indicates that you
+   need to update onebyte_has_modrm or twobyte_has_modrm.  */
+#define MODRM_CHECK  if (!need_modrm) abort ()
+
+static const char **names64;
+static const char **names32;
+static const char **names16;
+static const char **names8;
+static const char **names8rex;
+static const char **names_seg;
+static const char **index16;
+
+static const char *intel_names64[] = {
+  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+static const char *intel_names32[] = {
+  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
+  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
+};
+static const char *intel_names16[] = {
+  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
+  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
+};
+static const char *intel_names8[] = {
+  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
+};
+static const char *intel_names8rex[] = {
+  "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
+  "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
+};
+static const char *intel_names_seg[] = {
+  "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
+};
+static const char *intel_index16[] = {
+  "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
+};
+
+static const char *att_names64[] = {
+  "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
+  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+};
+static const char *att_names32[] = {
+  "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
+  "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
+};
+static const char *att_names16[] = {
+  "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
+  "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
+};
+static const char *att_names8[] = {
+  "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
+};
+static const char *att_names8rex[] = {
+  "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
+  "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
+};
+static const char *att_names_seg[] = {
+  "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
+};
+static const char *att_index16[] = {
+  "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
+};
+
+static const struct dis386 grps[][8] = {
+  /* GRP1b */
+  {
+    { "addA",	Eb, Ib, XX },
+    { "orA",	Eb, Ib, XX },
+    { "adcA",	Eb, Ib, XX },
+    { "sbbA",	Eb, Ib, XX },
+    { "andA",	Eb, Ib, XX },
+    { "subA",	Eb, Ib, XX },
+    { "xorA",	Eb, Ib, XX },
+    { "cmpA",	Eb, Ib, XX }
+  },
+  /* GRP1S */
+  {
+    { "addQ",	Ev, Iv, XX },
+    { "orQ",	Ev, Iv, XX },
+    { "adcQ",	Ev, Iv, XX },
+    { "sbbQ",	Ev, Iv, XX },
+    { "andQ",	Ev, Iv, XX },
+    { "subQ",	Ev, Iv, XX },
+    { "xorQ",	Ev, Iv, XX },
+    { "cmpQ",	Ev, Iv, XX }
+  },
+  /* GRP1Ss */
+  {
+    { "addQ",	Ev, sIb, XX },
+    { "orQ",	Ev, sIb, XX },
+    { "adcQ",	Ev, sIb, XX },
+    { "sbbQ",	Ev, sIb, XX },
+    { "andQ",	Ev, sIb, XX },
+    { "subQ",	Ev, sIb, XX },
+    { "xorQ",	Ev, sIb, XX },
+    { "cmpQ",	Ev, sIb, XX }
+  },
+  /* GRP2b */
+  {
+    { "rolA",	Eb, Ib, XX },
+    { "rorA",	Eb, Ib, XX },
+    { "rclA",	Eb, Ib, XX },
+    { "rcrA",	Eb, Ib, XX },
+    { "shlA",	Eb, Ib, XX },
+    { "shrA",	Eb, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+    { "sarA",	Eb, Ib, XX },
+  },
+  /* GRP2S */
+  {
+    { "rolQ",	Ev, Ib, XX },
+    { "rorQ",	Ev, Ib, XX },
+    { "rclQ",	Ev, Ib, XX },
+    { "rcrQ",	Ev, Ib, XX },
+    { "shlQ",	Ev, Ib, XX },
+    { "shrQ",	Ev, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+    { "sarQ",	Ev, Ib, XX },
+  },
+  /* GRP2b_one */
+  {
+    { "rolA",	Eb, I1, XX },
+    { "rorA",	Eb, I1, XX },
+    { "rclA",	Eb, I1, XX },
+    { "rcrA",	Eb, I1, XX },
+    { "shlA",	Eb, I1, XX },
+    { "shrA",	Eb, I1, XX },
+    { "(bad)",	XX, XX, XX },
+    { "sarA",	Eb, I1, XX },
+  },
+  /* GRP2S_one */
+  {
+    { "rolQ",	Ev, I1, XX },
+    { "rorQ",	Ev, I1, XX },
+    { "rclQ",	Ev, I1, XX },
+    { "rcrQ",	Ev, I1, XX },
+    { "shlQ",	Ev, I1, XX },
+    { "shrQ",	Ev, I1, XX },
+    { "(bad)",	XX, XX, XX},
+    { "sarQ",	Ev, I1, XX },
+  },
+  /* GRP2b_cl */
+  {
+    { "rolA",	Eb, CL, XX },
+    { "rorA",	Eb, CL, XX },
+    { "rclA",	Eb, CL, XX },
+    { "rcrA",	Eb, CL, XX },
+    { "shlA",	Eb, CL, XX },
+    { "shrA",	Eb, CL, XX },
+    { "(bad)",	XX, XX, XX },
+    { "sarA",	Eb, CL, XX },
+  },
+  /* GRP2S_cl */
+  {
+    { "rolQ",	Ev, CL, XX },
+    { "rorQ",	Ev, CL, XX },
+    { "rclQ",	Ev, CL, XX },
+    { "rcrQ",	Ev, CL, XX },
+    { "shlQ",	Ev, CL, XX },
+    { "shrQ",	Ev, CL, XX },
+    { "(bad)",	XX, XX, XX },
+    { "sarQ",	Ev, CL, XX }
+  },
+  /* GRP3b */
+  {
+    { "testA",	Eb, Ib, XX },
+    { "(bad)",	Eb, XX, XX },
+    { "notA",	Eb, XX, XX },
+    { "negA",	Eb, XX, XX },
+    { "mulA",	Eb, XX, XX },	/* Don't print the implicit %al register,  */
+    { "imulA",	Eb, XX, XX },	/* to distinguish these opcodes from other */
+    { "divA",	Eb, XX, XX },	/* mul/imul opcodes.  Do the same for div  */
+    { "idivA",	Eb, XX, XX }	/* and idiv for consistency.		   */
+  },
+  /* GRP3S */
+  {
+    { "testQ",	Ev, Iv, XX },
+    { "(bad)",	XX, XX, XX },
+    { "notQ",	Ev, XX, XX },
+    { "negQ",	Ev, XX, XX },
+    { "mulQ",	Ev, XX, XX },	/* Don't print the implicit register.  */
+    { "imulQ",	Ev, XX, XX },
+    { "divQ",	Ev, XX, XX },
+    { "idivQ",	Ev, XX, XX },
+  },
+  /* GRP4 */
+  {
+    { "incA",	Eb, XX, XX },
+    { "decA",	Eb, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* GRP5 */
+  {
+    { "incQ",	Ev, XX, XX },
+    { "decQ",	Ev, XX, XX },
+    { "callT",	indirEv, XX, XX },
+    { "JcallT", indirEp, XX, XX },
+    { "jmpT",	indirEv, XX, XX },
+    { "JjmpT",	indirEp, XX, XX },
+    { "pushU",	Ev, XX, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* GRP6 */
+  {
+    { "sldtQ",	Ev, XX, XX },
+    { "strQ",	Ev, XX, XX },
+    { "lldt",	Ew, XX, XX },
+    { "ltr",	Ew, XX, XX },
+    { "verr",	Ew, XX, XX },
+    { "verw",	Ew, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX }
+  },
+  /* GRP7 */
+  {
+    { "sgdtIQ", VMX_Fixup, 0, XX, XX },
+    { "sidtIQ", PNI_Fixup, 0, XX, XX },
+    { "lgdt{Q|Q||}",	 M, XX, XX },
+    { "lidt{Q|Q||}",	 SVME_Fixup, 0, XX, XX },
+    { "smswQ",	Ev, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "lmsw",	Ew, XX, XX },
+    { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
+  },
+  /* GRP8 */
+  {
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "btQ",	Ev, Ib, XX },
+    { "btsQ",	Ev, Ib, XX },
+    { "btrQ",	Ev, Ib, XX },
+    { "btcQ",	Ev, Ib, XX },
+  },
+  /* GRP9 */
+  {
+    { "(bad)",	XX, XX, XX },
+    { "cmpxchg8b", Eq, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "",	VM, XX, XX },		/* See OP_VMX.	*/
+    { "vmptrst", Eq, XX, XX },
+  },
+  /* GRP10 */
+  {
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "psrlw",	MS, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+    { "psraw",	MS, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+    { "psllw",	MS, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* GRP11 */
+  {
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "psrld",	MS, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+    { "psrad",	MS, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+    { "pslld",	MS, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* GRP12 */
+  {
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "psrlq",	MS, Ib, XX },
+    { "psrldq", MS, Ib, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "psllq",	MS, Ib, XX },
+    { "pslldq", MS, Ib, XX },
+  },
+  /* GRP13 */
+  {
+    { "fxsave", Ev, XX, XX },
+    { "fxrstor", Ev, XX, XX },
+    { "ldmxcsr", Ev, XX, XX },
+    { "stmxcsr", Ev, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "lfence", OP_0fae, 0, XX, XX },
+    { "mfence", OP_0fae, 0, XX, XX },
+    { "clflush", OP_0fae, 0, XX, XX },
+  },
+  /* GRP14 */
+  {
+    { "prefetchnta", Ev, XX, XX },
+    { "prefetcht0", Ev, XX, XX },
+    { "prefetcht1", Ev, XX, XX },
+    { "prefetcht2", Ev, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* GRPAMD */
+  {
+    { "prefetch", Eb, XX, XX },
+    { "prefetchw", Eb, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* GRPPADLCK1 */
+  {
+    { "xstore-rng", OP_0f07, 0, XX, XX },
+    { "xcrypt-ecb", OP_0f07, 0, XX, XX },
+    { "xcrypt-cbc", OP_0f07, 0, XX, XX },
+    { "xcrypt-ctr", OP_0f07, 0, XX, XX },
+    { "xcrypt-cfb", OP_0f07, 0, XX, XX },
+    { "xcrypt-ofb", OP_0f07, 0, XX, XX },
+    { "(bad)",	OP_0f07, 0, XX, XX },
+    { "(bad)",	OP_0f07, 0, XX, XX },
+  },
+  /* GRPPADLCK2 */
+  {
+    { "montmul", OP_0f07, 0, XX, XX },
+    { "xsha1",	 OP_0f07, 0, XX, XX },
+    { "xsha256", OP_0f07, 0, XX, XX },
+    { "(bad)",	 OP_0f07, 0, XX, XX },
+    { "(bad)",	 OP_0f07, 0, XX, XX },
+    { "(bad)",	 OP_0f07, 0, XX, XX },
+    { "(bad)",	 OP_0f07, 0, XX, XX },
+    { "(bad)",	 OP_0f07, 0, XX, XX },
+  }
+};
+
+static const struct dis386 prefix_user_table[][4] = {
+  /* PREGRP0 */
+  {
+    { "addps", XM, EX, XX },
+    { "addss", XM, EX, XX },
+    { "addpd", XM, EX, XX },
+    { "addsd", XM, EX, XX },
+  },
+  /* PREGRP1 */
+  {
+    { "", XM, EX, OPSIMD },	/* See OP_SIMD_SUFFIX.	*/
+    { "", XM, EX, OPSIMD },
+    { "", XM, EX, OPSIMD },
+    { "", XM, EX, OPSIMD },
+  },
+  /* PREGRP2 */
+  {
+    { "cvtpi2ps", XM, EM, XX },
+    { "cvtsi2ssY", XM, Ev, XX },
+    { "cvtpi2pd", XM, EM, XX },
+    { "cvtsi2sdY", XM, Ev, XX },
+  },
+  /* PREGRP3 */
+  {
+    { "cvtps2pi", MX, EX, XX },
+    { "cvtss2siY", Gv, EX, XX },
+    { "cvtpd2pi", MX, EX, XX },
+    { "cvtsd2siY", Gv, EX, XX },
+  },
+  /* PREGRP4 */
+  {
+    { "cvttps2pi", MX, EX, XX },
+    { "cvttss2siY", Gv, EX, XX },
+    { "cvttpd2pi", MX, EX, XX },
+    { "cvttsd2siY", Gv, EX, XX },
+  },
+  /* PREGRP5 */
+  {
+    { "divps", XM, EX, XX },
+    { "divss", XM, EX, XX },
+    { "divpd", XM, EX, XX },
+    { "divsd", XM, EX, XX },
+  },
+  /* PREGRP6 */
+  {
+    { "maxps", XM, EX, XX },
+    { "maxss", XM, EX, XX },
+    { "maxpd", XM, EX, XX },
+    { "maxsd", XM, EX, XX },
+  },
+  /* PREGRP7 */
+  {
+    { "minps", XM, EX, XX },
+    { "minss", XM, EX, XX },
+    { "minpd", XM, EX, XX },
+    { "minsd", XM, EX, XX },
+  },
+  /* PREGRP8 */
+  {
+    { "movups", XM, EX, XX },
+    { "movss", XM, EX, XX },
+    { "movupd", XM, EX, XX },
+    { "movsd", XM, EX, XX },
+  },
+  /* PREGRP9 */
+  {
+    { "movups", EX, XM, XX },
+    { "movss", EX, XM, XX },
+    { "movupd", EX, XM, XX },
+    { "movsd", EX, XM, XX },
+  },
+  /* PREGRP10 */
+  {
+    { "mulps", XM, EX, XX },
+    { "mulss", XM, EX, XX },
+    { "mulpd", XM, EX, XX },
+    { "mulsd", XM, EX, XX },
+  },
+  /* PREGRP11 */
+  {
+    { "rcpps", XM, EX, XX },
+    { "rcpss", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+  },
+  /* PREGRP12 */
+  {
+    { "rsqrtps", XM, EX, XX },
+    { "rsqrtss", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+  },
+  /* PREGRP13 */
+  {
+    { "sqrtps", XM, EX, XX },
+    { "sqrtss", XM, EX, XX },
+    { "sqrtpd", XM, EX, XX },
+    { "sqrtsd", XM, EX, XX },
+  },
+  /* PREGRP14 */
+  {
+    { "subps", XM, EX, XX },
+    { "subss", XM, EX, XX },
+    { "subpd", XM, EX, XX },
+    { "subsd", XM, EX, XX },
+  },
+  /* PREGRP15 */
+  {
+    { "(bad)", XM, EX, XX },
+    { "cvtdq2pd", XM, EX, XX },
+    { "cvttpd2dq", XM, EX, XX },
+    { "cvtpd2dq", XM, EX, XX },
+  },
+  /* PREGRP16 */
+  {
+    { "cvtdq2ps", XM, EX, XX },
+    { "cvttps2dq",XM, EX, XX },
+    { "cvtps2dq",XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+  },
+  /* PREGRP17 */
+  {
+    { "cvtps2pd", XM, EX, XX },
+    { "cvtss2sd", XM, EX, XX },
+    { "cvtpd2ps", XM, EX, XX },
+    { "cvtsd2ss", XM, EX, XX },
+  },
+  /* PREGRP18 */
+  {
+    { "maskmovq", MX, MS, XX },
+    { "(bad)", XM, EX, XX },
+    { "maskmovdqu", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+  },
+  /* PREGRP19 */
+  {
+    { "movq", MX, EM, XX },
+    { "movdqu", XM, EX, XX },
+    { "movdqa", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+  },
+  /* PREGRP20 */
+  {
+    { "movq", EM, MX, XX },
+    { "movdqu", EX, XM, XX },
+    { "movdqa", EX, XM, XX },
+    { "(bad)", EX, XM, XX },
+  },
+  /* PREGRP21 */
+  {
+    { "(bad)", EX, XM, XX },
+    { "movq2dq", XM, MS, XX },
+    { "movq", EX, XM, XX },
+    { "movdq2q", MX, XS, XX },
+  },
+  /* PREGRP22 */
+  {
+    { "pshufw", MX, EM, Ib },
+    { "pshufhw", XM, EX, Ib },
+    { "pshufd", XM, EX, Ib },
+    { "pshuflw", XM, EX, Ib },
+  },
+  /* PREGRP23 */
+  {
+    { "movd", Edq, MX, XX },
+    { "movq", XM, EX, XX },
+    { "movd", Edq, XM, XX },
+    { "(bad)", Ed, XM, XX },
+  },
+  /* PREGRP24 */
+  {
+    { "(bad)", MX, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "punpckhqdq", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+  },
+  /* PREGRP25 */
+  {
+    { "movntq", EM, MX, XX },
+    { "(bad)", EM, XM, XX },
+    { "movntdq", EM, XM, XX },
+    { "(bad)", EM, XM, XX },
+  },
+  /* PREGRP26 */
+  {
+    { "(bad)", MX, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "punpcklqdq", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+  },
+  /* PREGRP27 */
+  {
+    { "(bad)", MX, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "addsubpd", XM, EX, XX },
+    { "addsubps", XM, EX, XX },
+  },
+  /* PREGRP28 */
+  {
+    { "(bad)", MX, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "haddpd", XM, EX, XX },
+    { "haddps", XM, EX, XX },
+  },
+  /* PREGRP29 */
+  {
+    { "(bad)", MX, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "hsubpd", XM, EX, XX },
+    { "hsubps", XM, EX, XX },
+  },
+  /* PREGRP30 */
+  {
+    { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
+    { "movsldup", XM, EX, XX },
+    { "movlpd", XM, EX, XX },
+    { "movddup", XM, EX, XX },
+  },
+  /* PREGRP31 */
+  {
+    { "movhpX", XM, EX, SIMD_Fixup, 'l' },
+    { "movshdup", XM, EX, XX },
+    { "movhpd", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+  },
+  /* PREGRP32 */
+  {
+    { "(bad)", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "(bad)", XM, EX, XX },
+    { "lddqu", XM, M, XX },
+  },
+};
+
+static const struct dis386 x86_64_table[][2] = {
+  {
+    { "arpl", Ew, Gw, XX },
+    { "movs{||lq|xd}", Gv, Ed, XX },
+  },
+};
+
+#ifdef	__KERNEL__
+#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>"
+#else	/* __KERNEL__ */
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
+#endif	/* __KERNEL__ */
+
+static void
+ckprefix (void)
+{
+  int newrex;
+  rex = 0;
+  prefixes = 0;
+  used_prefixes = 0;
+  rex_used = 0;
+  while (1)
+    {
+      FETCH_DATA (the_info, codep + 1);
+      newrex = 0;
+      switch (*codep)
+	{
+	/* REX prefixes family.	 */
+	case 0x40:
+	case 0x41:
+	case 0x42:
+	case 0x43:
+	case 0x44:
+	case 0x45:
+	case 0x46:
+	case 0x47:
+	case 0x48:
+	case 0x49:
+	case 0x4a:
+	case 0x4b:
+	case 0x4c:
+	case 0x4d:
+	case 0x4e:
+	case 0x4f:
+	    if (mode_64bit)
+	      newrex = *codep;
+	    else
+	      return;
+	  break;
+	case 0xf3:
+	  prefixes |= PREFIX_REPZ;
+	  break;
+	case 0xf2:
+	  prefixes |= PREFIX_REPNZ;
+	  break;
+	case 0xf0:
+	  prefixes |= PREFIX_LOCK;
+	  break;
+	case 0x2e:
+	  prefixes |= PREFIX_CS;
+	  break;
+	case 0x36:
+	  prefixes |= PREFIX_SS;
+	  break;
+	case 0x3e:
+	  prefixes |= PREFIX_DS;
+	  break;
+	case 0x26:
+	  prefixes |= PREFIX_ES;
+	  break;
+	case 0x64:
+	  prefixes |= PREFIX_FS;
+	  break;
+	case 0x65:
+	  prefixes |= PREFIX_GS;
+	  break;
+	case 0x66:
+	  prefixes |= PREFIX_DATA;
+	  break;
+	case 0x67:
+	  prefixes |= PREFIX_ADDR;
+	  break;
+	case FWAIT_OPCODE:
+	  /* fwait is really an instruction.  If there are prefixes
+	     before the fwait, they belong to the fwait, *not* to the
+	     following instruction.  */
+	  if (prefixes)
+	    {
+	      prefixes |= PREFIX_FWAIT;
+	      codep++;
+	      return;
+	    }
+	  prefixes = PREFIX_FWAIT;
+	  break;
+	default:
+	  return;
+	}
+      /* Rex is ignored when followed by another prefix.  */
+      if (rex)
+	{
+	  oappend (prefix_name (rex, 0));
+	  oappend (" ");
+	}
+      rex = newrex;
+      codep++;
+    }
+}
+
+/* Return the name of the prefix byte PREF, or NULL if PREF is not a
+   prefix byte.	 */
+
+static const char *
+prefix_name (int pref, int sizeflag)
+{
+  switch (pref)
+    {
+    /* REX prefixes family.  */
+    case 0x40:
+      return "rex";
+    case 0x41:
+      return "rexZ";
+    case 0x42:
+      return "rexY";
+    case 0x43:
+      return "rexYZ";
+    case 0x44:
+      return "rexX";
+    case 0x45:
+      return "rexXZ";
+    case 0x46:
+      return "rexXY";
+    case 0x47:
+      return "rexXYZ";
+    case 0x48:
+      return "rex64";
+    case 0x49:
+      return "rex64Z";
+    case 0x4a:
+      return "rex64Y";
+    case 0x4b:
+      return "rex64YZ";
+    case 0x4c:
+      return "rex64X";
+    case 0x4d:
+      return "rex64XZ";
+    case 0x4e:
+      return "rex64XY";
+    case 0x4f:
+      return "rex64XYZ";
+    case 0xf3:
+      return "repz";
+    case 0xf2:
+      return "repnz";
+    case 0xf0:
+      return "lock";
+    case 0x2e:
+      return "cs";
+    case 0x36:
+      return "ss";
+    case 0x3e:
+      return "ds";
+    case 0x26:
+      return "es";
+    case 0x64:
+      return "fs";
+    case 0x65:
+      return "gs";
+    case 0x66:
+      return (sizeflag & DFLAG) ? "data16" : "data32";
+    case 0x67:
+      if (mode_64bit)
+	return (sizeflag & AFLAG) ? "addr32" : "addr64";
+      else
+	return (sizeflag & AFLAG) ? "addr16" : "addr32";
+    case FWAIT_OPCODE:
+      return "fwait";
+    default:
+      return NULL;
+    }
+}
+
+static char op1out[100], op2out[100], op3out[100];
+static int op_ad, op_index[3];
+static int two_source_ops;
+static bfd_vma op_address[3];
+static bfd_vma op_riprel[3];
+static bfd_vma start_pc;
+
+/*
+ *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
+ *   (see topic "Redundant prefixes" in the "Differences from 8086"
+ *   section of the "Virtual 8086 Mode" chapter.)
+ * 'pc' should be the address of this instruction, it will
+ *   be used to print the target address if this is a relative jump or call
+ * The function returns the length of this instruction in bytes.
+ */
+
+static char intel_syntax;
+static char open_char;
+static char close_char;
+static char separator_char;
+static char scale_char;
+
+/* Here for backwards compatibility.  When gdb stops using
+   print_insn_i386_att and print_insn_i386_intel these functions can
+   disappear, and print_insn_i386 be merged into print_insn.  */
+int
+print_insn_i386_att (bfd_vma pc, disassemble_info *info)
+{
+  intel_syntax = 0;
+
+  return print_insn (pc, info);
+}
+
+int
+print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
+{
+  intel_syntax = 1;
+
+  return print_insn (pc, info);
+}
+
+int
+print_insn_i386 (bfd_vma pc, disassemble_info *info)
+{
+  intel_syntax = -1;
+
+  return print_insn (pc, info);
+}
+
+static int
+print_insn (bfd_vma pc, disassemble_info *info)
+{
+  const struct dis386 *dp;
+  int i;
+  char *first, *second, *third;
+  int needcomma;
+  unsigned char uses_SSE_prefix, uses_LOCK_prefix;
+  int sizeflag;
+  const char *p;
+  struct dis_private priv;
+
+  mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
+		|| info->mach == bfd_mach_x86_64);
+
+  if (intel_syntax == (char) -1)
+    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
+		    || info->mach == bfd_mach_x86_64_intel_syntax);
+
+  if (info->mach == bfd_mach_i386_i386
+      || info->mach == bfd_mach_x86_64
+      || info->mach == bfd_mach_i386_i386_intel_syntax
+      || info->mach == bfd_mach_x86_64_intel_syntax)
+    priv.orig_sizeflag = AFLAG | DFLAG;
+  else if (info->mach == bfd_mach_i386_i8086)
+    priv.orig_sizeflag = 0;
+  else
+    abort ();
+
+  for (p = info->disassembler_options; p != NULL; )
+    {
+      if (strncmp (p, "x86-64", 6) == 0)
+	{
+	  mode_64bit = 1;
+	  priv.orig_sizeflag = AFLAG | DFLAG;
+	}
+      else if (strncmp (p, "i386", 4) == 0)
+	{
+	  mode_64bit = 0;
+	  priv.orig_sizeflag = AFLAG | DFLAG;
+	}
+      else if (strncmp (p, "i8086", 5) == 0)
+	{
+	  mode_64bit = 0;
+	  priv.orig_sizeflag = 0;
+	}
+      else if (strncmp (p, "intel", 5) == 0)
+	{
+	  intel_syntax = 1;
+	}
+      else if (strncmp (p, "att", 3) == 0)
+	{
+	  intel_syntax = 0;
+	}
+      else if (strncmp (p, "addr", 4) == 0)
+	{
+	  if (p[4] == '1' && p[5] == '6')
+	    priv.orig_sizeflag &= ~AFLAG;
+	  else if (p[4] == '3' && p[5] == '2')
+	    priv.orig_sizeflag |= AFLAG;
+	}
+      else if (strncmp (p, "data", 4) == 0)
+	{
+	  if (p[4] == '1' && p[5] == '6')
+	    priv.orig_sizeflag &= ~DFLAG;
+	  else if (p[4] == '3' && p[5] == '2')
+	    priv.orig_sizeflag |= DFLAG;
+	}
+      else if (strncmp (p, "suffix", 6) == 0)
+	priv.orig_sizeflag |= SUFFIX_ALWAYS;
+
+      p = strchr (p, ',');
+      if (p != NULL)
+	p++;
+    }
+
+  if (intel_syntax)
+    {
+      names64 = intel_names64;
+      names32 = intel_names32;
+      names16 = intel_names16;
+      names8 = intel_names8;
+      names8rex = intel_names8rex;
+      names_seg = intel_names_seg;
+      index16 = intel_index16;
+      open_char = '[';
+      close_char = ']';
+      separator_char = '+';
+      scale_char = '*';
+    }
+  else
+    {
+      names64 = att_names64;
+      names32 = att_names32;
+      names16 = att_names16;
+      names8 = att_names8;
+      names8rex = att_names8rex;
+      names_seg = att_names_seg;
+      index16 = att_index16;
+      open_char = '(';
+      close_char =  ')';
+      separator_char = ',';
+      scale_char = ',';
+    }
+
+  /* The output looks better if we put 7 bytes on a line, since that
+     puts most long word instructions on a single line.	 */
+  info->bytes_per_line = 7;
+
+  info->private_data = &priv;
+  priv.max_fetched = priv.the_buffer;
+  priv.insn_start = pc;
+
+  obuf[0] = 0;
+  op1out[0] = 0;
+  op2out[0] = 0;
+  op3out[0] = 0;
+
+  op_index[0] = op_index[1] = op_index[2] = -1;
+
+  the_info = info;
+  start_pc = pc;
+  start_codep = priv.the_buffer;
+  codep = priv.the_buffer;
+
+#ifndef __KERNEL__
+  if (setjmp (priv.bailout) != 0)
+    {
+      const char *name;
+
+      /* Getting here means we tried for data but didn't get it.  That
+	 means we have an incomplete instruction of some sort.	Just
+	 print the first byte as a prefix or a .byte pseudo-op.	 */
+      if (codep > priv.the_buffer)
+	{
+	  name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+	  if (name != NULL)
+	    (*info->fprintf_func) (info->stream, "%s", name);
+	  else
+	    {
+	      /* Just print the first byte as a .byte instruction.  */
+	      (*info->fprintf_func) (info->stream, ".byte 0x%x",
+				     (unsigned int) priv.the_buffer[0]);
+	    }
+
+	  return 1;
+	}
+
+      return -1;
+    }
+#endif	/* __KERNEL__ */
+
+  obufp = obuf;
+  ckprefix ();
+
+  insn_codep = codep;
+  sizeflag = priv.orig_sizeflag;
+
+  FETCH_DATA (info, codep + 1);
+  two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
+
+  if ((prefixes & PREFIX_FWAIT)
+      && ((*codep < 0xd8) || (*codep > 0xdf)))
+    {
+      const char *name;
+
+      /* fwait not followed by floating point instruction.  Print the
+	 first prefix, which is probably fwait itself.	*/
+      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+      if (name == NULL)
+	name = INTERNAL_DISASSEMBLER_ERROR;
+      (*info->fprintf_func) (info->stream, "%s", name);
+      return 1;
+    }
+
+  if (*codep == 0x0f)
+    {
+      FETCH_DATA (info, codep + 2);
+      dp = &dis386_twobyte[*++codep];
+      need_modrm = twobyte_has_modrm[*codep];
+      uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
+      uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
+    }
+  else
+    {
+      dp = &dis386[*codep];
+      need_modrm = onebyte_has_modrm[*codep];
+      uses_SSE_prefix = 0;
+      uses_LOCK_prefix = 0;
+    }
+  codep++;
+
+  if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
+    {
+      oappend ("repz ");
+      used_prefixes |= PREFIX_REPZ;
+    }
+  if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
+    {
+      oappend ("repnz ");
+      used_prefixes |= PREFIX_REPNZ;
+    }
+  if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
+    {
+      oappend ("lock ");
+      used_prefixes |= PREFIX_LOCK;
+    }
+
+  if (prefixes & PREFIX_ADDR)
+    {
+      sizeflag ^= AFLAG;
+      if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
+	{
+	  if ((sizeflag & AFLAG) || mode_64bit)
+	    oappend ("addr32 ");
+	  else
+	    oappend ("addr16 ");
+	  used_prefixes |= PREFIX_ADDR;
+	}
+    }
+
+  if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
+    {
+      sizeflag ^= DFLAG;
+      if (dp->bytemode3 == cond_jump_mode
+	  && dp->bytemode1 == v_mode
+	  && !intel_syntax)
+	{
+	  if (sizeflag & DFLAG)
+	    oappend ("data32 ");
+	  else
+	    oappend ("data16 ");
+	  used_prefixes |= PREFIX_DATA;
+	}
+    }
+
+  if (need_modrm)
+    {
+      FETCH_DATA (info, codep + 1);
+      mod = (*codep >> 6) & 3;
+      reg = (*codep >> 3) & 7;
+      rm = *codep & 7;
+    }
+
+  if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
+    {
+      dofloat (sizeflag);
+    }
+  else
+    {
+      int index;
+      if (dp->name == NULL)
+	{
+	  switch (dp->bytemode1)
+	    {
+	    case USE_GROUPS:
+	      dp = &grps[dp->bytemode2][reg];
+	      break;
+
+	    case USE_PREFIX_USER_TABLE:
+	      index = 0;
+	      used_prefixes |= (prefixes & PREFIX_REPZ);
+	      if (prefixes & PREFIX_REPZ)
+		index = 1;
+	      else
+		{
+		  used_prefixes |= (prefixes & PREFIX_DATA);
+		  if (prefixes & PREFIX_DATA)
+		    index = 2;
+		  else
+		    {
+		      used_prefixes |= (prefixes & PREFIX_REPNZ);
+		      if (prefixes & PREFIX_REPNZ)
+			index = 3;
+		    }
+		}
+	      dp = &prefix_user_table[dp->bytemode2][index];
+	      break;
+
+	    case X86_64_SPECIAL:
+	      dp = &x86_64_table[dp->bytemode2][mode_64bit];
+	      break;
+
+	    default:
+	      oappend (INTERNAL_DISASSEMBLER_ERROR);
+	      break;
+	    }
+	}
+
+      if (putop (dp->name, sizeflag) == 0)
+	{
+	  obufp = op1out;
+	  op_ad = 2;
+	  if (dp->op1)
+	    (*dp->op1) (dp->bytemode1, sizeflag);
+
+	  obufp = op2out;
+	  op_ad = 1;
+	  if (dp->op2)
+	    (*dp->op2) (dp->bytemode2, sizeflag);
+
+	  obufp = op3out;
+	  op_ad = 0;
+	  if (dp->op3)
+	    (*dp->op3) (dp->bytemode3, sizeflag);
+	}
+    }
+
+  /* See if any prefixes were not used.	 If so, print the first one
+     separately.  If we don't do this, we'll wind up printing an
+     instruction stream which does not precisely correspond to the
+     bytes we are disassembling.  */
+  if ((prefixes & ~used_prefixes) != 0)
+    {
+      const char *name;
+
+      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+      if (name == NULL)
+	name = INTERNAL_DISASSEMBLER_ERROR;
+      (*info->fprintf_func) (info->stream, "%s", name);
+      return 1;
+    }
+  if (rex & ~rex_used)
+    {
+      const char *name;
+      name = prefix_name (rex | 0x40, priv.orig_sizeflag);
+      if (name == NULL)
+	name = INTERNAL_DISASSEMBLER_ERROR;
+      (*info->fprintf_func) (info->stream, "%s ", name);
+    }
+
+  obufp = obuf + strlen (obuf);
+  for (i = strlen (obuf); i < 6; i++)
+    oappend (" ");
+  oappend (" ");
+  (*info->fprintf_func) (info->stream, "%s", obuf);
+
+  /* The enter and bound instructions are printed with operands in the same
+     order as the intel book; everything else is printed in reverse order.  */
+  if (intel_syntax || two_source_ops)
+    {
+      first = op1out;
+      second = op2out;
+      third = op3out;
+      op_ad = op_index[0];
+      op_index[0] = op_index[2];
+      op_index[2] = op_ad;
+    }
+  else
+    {
+      first = op3out;
+      second = op2out;
+      third = op1out;
+    }
+  needcomma = 0;
+  if (*first)
+    {
+      if (op_index[0] != -1 && !op_riprel[0])
+	(*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
+      else
+	(*info->fprintf_func) (info->stream, "%s", first);
+      needcomma = 1;
+    }
+  if (*second)
+    {
+      if (needcomma)
+	(*info->fprintf_func) (info->stream, ",");
+      if (op_index[1] != -1 && !op_riprel[1])
+	(*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
+      else
+	(*info->fprintf_func) (info->stream, "%s", second);
+      needcomma = 1;
+    }
+  if (*third)
+    {
+      if (needcomma)
+	(*info->fprintf_func) (info->stream, ",");
+      if (op_index[2] != -1 && !op_riprel[2])
+	(*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
+      else
+	(*info->fprintf_func) (info->stream, "%s", third);
+    }
+  for (i = 0; i < 3; i++)
+    if (op_index[i] != -1 && op_riprel[i])
+      {
+	(*info->fprintf_func) (info->stream, "	      # ");
+	(*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
+						+ op_address[op_index[i]]), info);
+      }
+  return codep - priv.the_buffer;
+}
+
+static const char *float_mem[] = {
+  /* d8 */
+  "fadd{s||s|}",
+  "fmul{s||s|}",
+  "fcom{s||s|}",
+  "fcomp{s||s|}",
+  "fsub{s||s|}",
+  "fsubr{s||s|}",
+  "fdiv{s||s|}",
+  "fdivr{s||s|}",
+  /* d9 */
+  "fld{s||s|}",
+  "(bad)",
+  "fst{s||s|}",
+  "fstp{s||s|}",
+  "fldenvIC",
+  "fldcw",
+  "fNstenvIC",
+  "fNstcw",
+  /* da */
+  "fiadd{l||l|}",
+  "fimul{l||l|}",
+  "ficom{l||l|}",
+  "ficomp{l||l|}",
+  "fisub{l||l|}",
+  "fisubr{l||l|}",
+  "fidiv{l||l|}",
+  "fidivr{l||l|}",
+  /* db */
+  "fild{l||l|}",
+  "fisttp{l||l|}",
+  "fist{l||l|}",
+  "fistp{l||l|}",
+  "(bad)",
+  "fld{t||t|}",
+  "(bad)",
+  "fstp{t||t|}",
+  /* dc */
+  "fadd{l||l|}",
+  "fmul{l||l|}",
+  "fcom{l||l|}",
+  "fcomp{l||l|}",
+  "fsub{l||l|}",
+  "fsubr{l||l|}",
+  "fdiv{l||l|}",
+  "fdivr{l||l|}",
+  /* dd */
+  "fld{l||l|}",
+  "fisttp{ll||ll|}",
+  "fst{l||l|}",
+  "fstp{l||l|}",
+  "frstorIC",
+  "(bad)",
+  "fNsaveIC",
+  "fNstsw",
+  /* de */
+  "fiadd",
+  "fimul",
+  "ficom",
+  "ficomp",
+  "fisub",
+  "fisubr",
+  "fidiv",
+  "fidivr",
+  /* df */
+  "fild",
+  "fisttp",
+  "fist",
+  "fistp",
+  "fbld",
+  "fild{ll||ll|}",
+  "fbstp",
+  "fistp{ll||ll|}",
+};
+
+static const unsigned char float_mem_mode[] = {
+  /* d8 */
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  /* d9 */
+  d_mode,
+  0,
+  d_mode,
+  d_mode,
+  0,
+  w_mode,
+  0,
+  w_mode,
+  /* da */
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  /* db */
+  d_mode,
+  d_mode,
+  d_mode,
+  d_mode,
+  0,
+  t_mode,
+  0,
+  t_mode,
+  /* dc */
+  q_mode,
+  q_mode,
+  q_mode,
+  q_mode,
+  q_mode,
+  q_mode,
+  q_mode,
+  q_mode,
+  /* dd */
+  q_mode,
+  q_mode,
+  q_mode,
+  q_mode,
+  0,
+  0,
+  0,
+  w_mode,
+  /* de */
+  w_mode,
+  w_mode,
+  w_mode,
+  w_mode,
+  w_mode,
+  w_mode,
+  w_mode,
+  w_mode,
+  /* df */
+  w_mode,
+  w_mode,
+  w_mode,
+  w_mode,
+  t_mode,
+  q_mode,
+  t_mode,
+  q_mode
+};
+
+#define ST OP_ST, 0
+#define STi OP_STi, 0
+
+#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
+#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
+#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
+#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
+#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
+#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
+#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
+#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
+#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
+
+static const struct dis386 float_reg[][8] = {
+  /* d8 */
+  {
+    { "fadd",	ST, STi, XX },
+    { "fmul",	ST, STi, XX },
+    { "fcom",	STi, XX, XX },
+    { "fcomp",	STi, XX, XX },
+    { "fsub",	ST, STi, XX },
+    { "fsubr",	ST, STi, XX },
+    { "fdiv",	ST, STi, XX },
+    { "fdivr",	ST, STi, XX },
+  },
+  /* d9 */
+  {
+    { "fld",	STi, XX, XX },
+    { "fxch",	STi, XX, XX },
+    { FGRPd9_2 },
+    { "(bad)",	XX, XX, XX },
+    { FGRPd9_4 },
+    { FGRPd9_5 },
+    { FGRPd9_6 },
+    { FGRPd9_7 },
+  },
+  /* da */
+  {
+    { "fcmovb", ST, STi, XX },
+    { "fcmove", ST, STi, XX },
+    { "fcmovbe",ST, STi, XX },
+    { "fcmovu", ST, STi, XX },
+    { "(bad)",	XX, XX, XX },
+    { FGRPda_5 },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* db */
+  {
+    { "fcmovnb",ST, STi, XX },
+    { "fcmovne",ST, STi, XX },
+    { "fcmovnbe",ST, STi, XX },
+    { "fcmovnu",ST, STi, XX },
+    { FGRPdb_4 },
+    { "fucomi", ST, STi, XX },
+    { "fcomi",	ST, STi, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* dc */
+  {
+    { "fadd",	STi, ST, XX },
+    { "fmul",	STi, ST, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+#if UNIXWARE_COMPAT
+    { "fsub",	STi, ST, XX },
+    { "fsubr",	STi, ST, XX },
+    { "fdiv",	STi, ST, XX },
+    { "fdivr",	STi, ST, XX },
+#else
+    { "fsubr",	STi, ST, XX },
+    { "fsub",	STi, ST, XX },
+    { "fdivr",	STi, ST, XX },
+    { "fdiv",	STi, ST, XX },
+#endif
+  },
+  /* dd */
+  {
+    { "ffree",	STi, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "fst",	STi, XX, XX },
+    { "fstp",	STi, XX, XX },
+    { "fucom",	STi, XX, XX },
+    { "fucomp", STi, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+  /* de */
+  {
+    { "faddp",	STi, ST, XX },
+    { "fmulp",	STi, ST, XX },
+    { "(bad)",	XX, XX, XX },
+    { FGRPde_3 },
+#if UNIXWARE_COMPAT
+    { "fsubp",	STi, ST, XX },
+    { "fsubrp", STi, ST, XX },
+    { "fdivp",	STi, ST, XX },
+    { "fdivrp", STi, ST, XX },
+#else
+    { "fsubrp", STi, ST, XX },
+    { "fsubp",	STi, ST, XX },
+    { "fdivrp", STi, ST, XX },
+    { "fdivp",	STi, ST, XX },
+#endif
+  },
+  /* df */
+  {
+    { "ffreep", STi, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { FGRPdf_4 },
+    { "fucomip",ST, STi, XX },
+    { "fcomip", ST, STi, XX },
+    { "(bad)",	XX, XX, XX },
+  },
+};
+
+static char *fgrps[][8] = {
+  /* d9_2  0 */
+  {
+    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* d9_4  1 */
+  {
+    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
+  },
+
+  /* d9_5  2 */
+  {
+    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
+  },
+
+  /* d9_6  3 */
+  {
+    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
+  },
+
+  /* d9_7  4 */
+  {
+    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
+  },
+
+  /* da_5  5 */
+  {
+    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* db_4  6 */
+  {
+    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
+    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+  },
+
+  /* de_3  7 */
+  {
+    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* df_4  8 */
+  {
+    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+};
+
+static void
+dofloat (int sizeflag)
+{
+  const struct dis386 *dp;
+  unsigned char floatop;
+
+  floatop = codep[-1];
+
+  if (mod != 3)
+    {
+      int fp_indx = (floatop - 0xd8) * 8 + reg;
+
+      putop (float_mem[fp_indx], sizeflag);
+      obufp = op1out;
+      OP_E (float_mem_mode[fp_indx], sizeflag);
+      return;
+    }
+  /* Skip mod/rm byte.	*/
+  MODRM_CHECK;
+  codep++;
+
+  dp = &float_reg[floatop - 0xd8][reg];
+  if (dp->name == NULL)
+    {
+      putop (fgrps[dp->bytemode1][rm], sizeflag);
+
+      /* Instruction fnstsw is only one with strange arg.  */
+      if (floatop == 0xdf && codep[-1] == 0xe0)
+	strcpy (op1out, names16[0]);
+    }
+  else
+    {
+      putop (dp->name, sizeflag);
+
+      obufp = op1out;
+      if (dp->op1)
+	(*dp->op1) (dp->bytemode1, sizeflag);
+      obufp = op2out;
+      if (dp->op2)
+	(*dp->op2) (dp->bytemode2, sizeflag);
+    }
+}
+
+static void
+OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  oappend ("%st");
+}
+
+static void
+OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  sprintf (scratchbuf, "%%st(%d)", rm);
+  oappend (scratchbuf + intel_syntax);
+}
+
+/* Capital letters in template are macros.  */
+static int
+putop (const char *template, int sizeflag)
+{
+  const char *p;
+  int alt = 0;
+
+  for (p = template; *p; p++)
+    {
+      switch (*p)
+	{
+	default:
+	  *obufp++ = *p;
+	  break;
+	case '{':
+	  alt = 0;
+	  if (intel_syntax)
+	    alt += 1;
+	  if (mode_64bit)
+	    alt += 2;
+	  while (alt != 0)
+	    {
+	      while (*++p != '|')
+		{
+		  if (*p == '}')
+		    {
+		      /* Alternative not valid.	 */
+		      strcpy (obuf, "(bad)");
+		      obufp = obuf + 5;
+		      return 1;
+		    }
+		  else if (*p == '\0')
+		    abort ();
+		}
+	      alt--;
+	    }
+	  /* Fall through.  */
+	case 'I':
+	  alt = 1;
+	  continue;
+	case '|':
+	  while (*++p != '}')
+	    {
+	      if (*p == '\0')
+		abort ();
+	    }
+	  break;
+	case '}':
+	  break;
+	case 'A':
+	  if (intel_syntax)
+	    break;
+	  if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
+	    *obufp++ = 'b';
+	  break;
+	case 'B':
+	  if (intel_syntax)
+	    break;
+	  if (sizeflag & SUFFIX_ALWAYS)
+	    *obufp++ = 'b';
+	  break;
+	case 'C':
+	  if (intel_syntax && !alt)
+	    break;
+	  if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
+	    {
+	      if (sizeflag & DFLAG)
+		*obufp++ = intel_syntax ? 'd' : 'l';
+	      else
+		*obufp++ = intel_syntax ? 'w' : 's';
+	      used_prefixes |= (prefixes & PREFIX_DATA);
+	    }
+	  break;
+	case 'E':		/* For jcxz/jecxz */
+	  if (mode_64bit)
+	    {
+	      if (sizeflag & AFLAG)
+		*obufp++ = 'r';
+	      else
+		*obufp++ = 'e';
+	    }
+	  else
+	    if (sizeflag & AFLAG)
+	      *obufp++ = 'e';
+	  used_prefixes |= (prefixes & PREFIX_ADDR);
+	  break;
+	case 'F':
+	  if (intel_syntax)
+	    break;
+	  if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
+	    {
+	      if (sizeflag & AFLAG)
+		*obufp++ = mode_64bit ? 'q' : 'l';
+	      else
+		*obufp++ = mode_64bit ? 'l' : 'w';
+	      used_prefixes |= (prefixes & PREFIX_ADDR);
+	    }
+	  break;
+	case 'H':
+	  if (intel_syntax)
+	    break;
+	  if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
+	      || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
+	    {
+	      used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
+	      *obufp++ = ',';
+	      *obufp++ = 'p';
+	      if (prefixes & PREFIX_DS)
+		*obufp++ = 't';
+	      else
+		*obufp++ = 'n';
+	    }
+	  break;
+	case 'J':
+	  if (intel_syntax)
+	    break;
+	  *obufp++ = 'l';
+	  break;
+	case 'L':
+	  if (intel_syntax)
+	    break;
+	  if (sizeflag & SUFFIX_ALWAYS)
+	    *obufp++ = 'l';
+	  break;
+	case 'N':
+	  if ((prefixes & PREFIX_FWAIT) == 0)
+	    *obufp++ = 'n';
+	  else
+	    used_prefixes |= PREFIX_FWAIT;
+	  break;
+	case 'O':
+	  USED_REX (REX_MODE64);
+	  if (rex & REX_MODE64)
+	    *obufp++ = 'o';
+	  else
+	    *obufp++ = 'd';
+	  break;
+	case 'T':
+	  if (intel_syntax)
+	    break;
+	  if (mode_64bit)
+	    {
+	      *obufp++ = 'q';
+	      break;
+	    }
+	  /* Fall through.  */
+	case 'P':
+	  if (intel_syntax)
+	    break;
+	  if ((prefixes & PREFIX_DATA)
+	      || (rex & REX_MODE64)
+	      || (sizeflag & SUFFIX_ALWAYS))
+	    {
+	      USED_REX (REX_MODE64);
+	      if (rex & REX_MODE64)
+		*obufp++ = 'q';
+	      else
+		{
+		   if (sizeflag & DFLAG)
+		      *obufp++ = 'l';
+		   else
+		     *obufp++ = 'w';
+		   used_prefixes |= (prefixes & PREFIX_DATA);
+		}
+	    }
+	  break;
+	case 'U':
+	  if (intel_syntax)
+	    break;
+	  if (mode_64bit)
+	    {
+	      *obufp++ = 'q';
+	      break;
+	    }
+	  /* Fall through.  */
+	case 'Q':
+	  if (intel_syntax && !alt)
+	    break;
+	  USED_REX (REX_MODE64);
+	  if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
+	    {
+	      if (rex & REX_MODE64)
+		*obufp++ = 'q';
+	      else
+		{
+		  if (sizeflag & DFLAG)
+		    *obufp++ = intel_syntax ? 'd' : 'l';
+		  else
+		    *obufp++ = 'w';
+		  used_prefixes |= (prefixes & PREFIX_DATA);
+		}
+	    }
+	  break;
+	case 'R':
+	  USED_REX (REX_MODE64);
+	  if (intel_syntax)
+	    {
+	      if (rex & REX_MODE64)
+		{
+		  *obufp++ = 'q';
+		  *obufp++ = 't';
+		}
+	      else if (sizeflag & DFLAG)
+		{
+		  *obufp++ = 'd';
+		  *obufp++ = 'q';
+		}
+	      else
+		{
+		  *obufp++ = 'w';
+		  *obufp++ = 'd';
+		}
+	    }
+	  else
+	    {
+	      if (rex & REX_MODE64)
+		*obufp++ = 'q';
+	      else if (sizeflag & DFLAG)
+		*obufp++ = 'l';
+	      else
+		*obufp++ = 'w';
+	    }
+	  if (!(rex & REX_MODE64))
+	    used_prefixes |= (prefixes & PREFIX_DATA);
+	  break;
+	case 'S':
+	  if (intel_syntax)
+	    break;
+	  if (sizeflag & SUFFIX_ALWAYS)
+	    {
+	      if (rex & REX_MODE64)
+		*obufp++ = 'q';
+	      else
+		{
+		  if (sizeflag & DFLAG)
+		    *obufp++ = 'l';
+		  else
+		    *obufp++ = 'w';
+		  used_prefixes |= (prefixes & PREFIX_DATA);
+		}
+	    }
+	  break;
+	case 'X':
+	  if (prefixes & PREFIX_DATA)
+	    *obufp++ = 'd';
+	  else
+	    *obufp++ = 's';
+	  used_prefixes |= (prefixes & PREFIX_DATA);
+	  break;
+	case 'Y':
+	  if (intel_syntax)
+	    break;
+	  if (rex & REX_MODE64)
+	    {
+	      USED_REX (REX_MODE64);
+	      *obufp++ = 'q';
+	    }
+	  break;
+	  /* implicit operand size 'l' for i386 or 'q' for x86-64 */
+	case 'W':
+	  /* operand size flag for cwtl, cbtw */
+	  USED_REX (0);
+	  if (rex)
+	    *obufp++ = 'l';
+	  else if (sizeflag & DFLAG)
+	    *obufp++ = 'w';
+	  else
+	    *obufp++ = 'b';
+	  if (intel_syntax)
+	    {
+	      if (rex)
+		{
+		  *obufp++ = 'q';
+		  *obufp++ = 'e';
+		}
+	      if (sizeflag & DFLAG)
+		{
+		  *obufp++ = 'd';
+		  *obufp++ = 'e';
+		}
+	      else
+		{
+		  *obufp++ = 'w';
+		}
+	    }
+	  if (!rex)
+	    used_prefixes |= (prefixes & PREFIX_DATA);
+	  break;
+	}
+      alt = 0;
+    }
+  *obufp = 0;
+  return 0;
+}
+
+static void
+oappend (const char *s)
+{
+  strcpy (obufp, s);
+  obufp += strlen (s);
+}
+
+static void
+append_seg (void)
+{
+  if (prefixes & PREFIX_CS)
+    {
+      used_prefixes |= PREFIX_CS;
+      oappend ("%cs:" + intel_syntax);
+    }
+  if (prefixes & PREFIX_DS)
+    {
+      used_prefixes |= PREFIX_DS;
+      oappend ("%ds:" + intel_syntax);
+    }
+  if (prefixes & PREFIX_SS)
+    {
+      used_prefixes |= PREFIX_SS;
+      oappend ("%ss:" + intel_syntax);
+    }
+  if (prefixes & PREFIX_ES)
+    {
+      used_prefixes |= PREFIX_ES;
+      oappend ("%es:" + intel_syntax);
+    }
+  if (prefixes & PREFIX_FS)
+    {
+      used_prefixes |= PREFIX_FS;
+      oappend ("%fs:" + intel_syntax);
+    }
+  if (prefixes & PREFIX_GS)
+    {
+      used_prefixes |= PREFIX_GS;
+      oappend ("%gs:" + intel_syntax);
+    }
+}
+
+static void
+OP_indirE (int bytemode, int sizeflag)
+{
+  if (!intel_syntax)
+    oappend ("*");
+  OP_E (bytemode, sizeflag);
+}
+
+static void
+print_operand_value (char *buf, int hex, bfd_vma disp)
+{
+  if (mode_64bit)
+    {
+      if (hex)
+	{
+	  char tmp[30];
+	  int i;
+	  buf[0] = '0';
+	  buf[1] = 'x';
+	  sprintf_vma (tmp, disp);
+	  for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
+	  strcpy (buf + 2, tmp + i);
+	}
+      else
+	{
+	  bfd_signed_vma v = disp;
+	  char tmp[30];
+	  int i;
+	  if (v < 0)
+	    {
+	      *(buf++) = '-';
+	      v = -disp;
+	      /* Check for possible overflow on 0x8000000000000000.  */
+	      if (v < 0)
+		{
+		  strcpy (buf, "9223372036854775808");
+		  return;
+		}
+	    }
+	  if (!v)
+	    {
+	      strcpy (buf, "0");
+	      return;
+	    }
+
+	  i = 0;
+	  tmp[29] = 0;
+	  while (v)
+	    {
+	      tmp[28 - i] = (v % 10) + '0';
+	      v /= 10;
+	      i++;
+	    }
+	  strcpy (buf, tmp + 29 - i);
+	}
+    }
+  else
+    {
+      if (hex)
+	sprintf (buf, "0x%x", (unsigned int) disp);
+      else
+	sprintf (buf, "%d", (int) disp);
+    }
+}
+
+static void
+OP_E (int bytemode, int sizeflag)
+{
+  bfd_vma disp;
+  int add = 0;
+  int riprel = 0;
+  USED_REX (REX_EXTZ);
+  if (rex & REX_EXTZ)
+    add += 8;
+
+  /* Skip mod/rm byte.	*/
+  MODRM_CHECK;
+  codep++;
+
+  if (mod == 3)
+    {
+      switch (bytemode)
+	{
+	case b_mode:
+	  USED_REX (0);
+	  if (rex)
+	    oappend (names8rex[rm + add]);
+	  else
+	    oappend (names8[rm + add]);
+	  break;
+	case w_mode:
+	  oappend (names16[rm + add]);
+	  break;
+	case d_mode:
+	  oappend (names32[rm + add]);
+	  break;
+	case q_mode:
+	  oappend (names64[rm + add]);
+	  break;
+	case m_mode:
+	  if (mode_64bit)
+	    oappend (names64[rm + add]);
+	  else
+	    oappend (names32[rm + add]);
+	  break;
+	case branch_v_mode:
+	  if (mode_64bit)
+	    oappend (names64[rm + add]);
+	  else
+	    {
+	      if ((sizeflag & DFLAG) || bytemode != branch_v_mode)
+		oappend (names32[rm + add]);
+	      else
+		oappend (names16[rm + add]);
+	      used_prefixes |= (prefixes & PREFIX_DATA);
+	    }
+	  break;
+	case v_mode:
+	case dq_mode:
+	case dqw_mode:
+	  USED_REX (REX_MODE64);
+	  if (rex & REX_MODE64)
+	    oappend (names64[rm + add]);
+	  else if ((sizeflag & DFLAG) || bytemode != v_mode)
+	    oappend (names32[rm + add]);
+	  else
+	    oappend (names16[rm + add]);
+	  used_prefixes |= (prefixes & PREFIX_DATA);
+	  break;
+	case 0:
+	  break;
+	default:
+	  oappend (INTERNAL_DISASSEMBLER_ERROR);
+	  break;
+	}
+      return;
+    }
+
+  disp = 0;
+  append_seg ();
+
+  if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
+    {
+      int havesib;
+      int havebase;
+      int base;
+      int index = 0;
+      int scale = 0;
+
+      havesib = 0;
+      havebase = 1;
+      base = rm;
+
+      if (base == 4)
+	{
+	  havesib = 1;
+	  FETCH_DATA (the_info, codep + 1);
+	  index = (*codep >> 3) & 7;
+	  if (mode_64bit || index != 0x4)
+	    /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored.  */
+	    scale = (*codep >> 6) & 3;
+	  base = *codep & 7;
+	  USED_REX (REX_EXTY);
+	  if (rex & REX_EXTY)
+	    index += 8;
+	  codep++;
+	}
+      base += add;
+
+      switch (mod)
+	{
+	case 0:
+	  if ((base & 7) == 5)
+	    {
+	      havebase = 0;
+	      if (mode_64bit && !havesib)
+		riprel = 1;
+	      disp = get32s ();
+	    }
+	  break;
+	case 1:
+	  FETCH_DATA (the_info, codep + 1);
+	  disp = *codep++;
+	  if ((disp & 0x80) != 0)
+	    disp -= 0x100;
+	  break;
+	case 2:
+	  disp = get32s ();
+	  break;
+	}
+
+      if (!intel_syntax)
+	if (mod != 0 || (base & 7) == 5)
+	  {
+	    print_operand_value (scratchbuf, !riprel, disp);
+	    oappend (scratchbuf);
+	    if (riprel)
+	      {
+		set_op (disp, 1);
+		oappend ("(%rip)");
+	      }
+	  }
+
+      if (havebase || (havesib && (index != 4 || scale != 0)))
+	{
+	  if (intel_syntax)
+	    {
+	      switch (bytemode)
+		{
+		case b_mode:
+		  oappend ("BYTE PTR ");
+		  break;
+		case w_mode:
+		case dqw_mode:
+		  oappend ("WORD PTR ");
+		  break;
+		case branch_v_mode:
+		case v_mode:
+		case dq_mode:
+		  USED_REX (REX_MODE64);
+		  if (rex & REX_MODE64)
+		    oappend ("QWORD PTR ");
+		  else if ((sizeflag & DFLAG) || bytemode == dq_mode)
+		    oappend ("DWORD PTR ");
+		  else
+		    oappend ("WORD PTR ");
+		  used_prefixes |= (prefixes & PREFIX_DATA);
+		  break;
+		case d_mode:
+		  oappend ("DWORD PTR ");
+		  break;
+		case q_mode:
+		  oappend ("QWORD PTR ");
+		  break;
+		case m_mode:
+		  if (mode_64bit)
+		    oappend ("QWORD PTR ");
+		  else
+		    oappend ("DWORD PTR ");
+		  break;
+		case f_mode:
+		  if (sizeflag & DFLAG)
+		    {
+		      used_prefixes |= (prefixes & PREFIX_DATA);
+		      oappend ("FWORD PTR ");
+		    }
+		  else
+		    oappend ("DWORD PTR ");
+		  break;
+		case t_mode:
+		  oappend ("TBYTE PTR ");
+		  break;
+		case x_mode:
+		  oappend ("XMMWORD PTR ");
+		  break;
+		default:
+		  break;
+		}
+	    }
+	  *obufp++ = open_char;
+	  if (intel_syntax && riprel)
+	    oappend ("rip + ");
+	  *obufp = '\0';
+	  if (havebase)
+	    oappend (mode_64bit && (sizeflag & AFLAG)
+		     ? names64[base] : names32[base]);
+	  if (havesib)
+	    {
+	      if (index != 4)
+		{
+		  if (!intel_syntax || havebase)
+		    {
+		      *obufp++ = separator_char;
+		      *obufp = '\0';
+		    }
+		  oappend (mode_64bit && (sizeflag & AFLAG)
+			   ? names64[index] : names32[index]);
+		}
+	      if (scale != 0 || (!intel_syntax && index != 4))
+		{
+		  *obufp++ = scale_char;
+		  *obufp = '\0';
+		  sprintf (scratchbuf, "%d", 1 << scale);
+		  oappend (scratchbuf);
+		}
+	    }
+	  if (intel_syntax && disp)
+	    {
+	      if ((bfd_signed_vma) disp > 0)
+		{
+		  *obufp++ = '+';
+		  *obufp = '\0';
+		}
+	      else if (mod != 1)
+		{
+		  *obufp++ = '-';
+		  *obufp = '\0';
+		  disp = - (bfd_signed_vma) disp;
+		}
+
+	      print_operand_value (scratchbuf, mod != 1, disp);
+	      oappend (scratchbuf);
+	    }
+
+	  *obufp++ = close_char;
+	  *obufp = '\0';
+	}
+      else if (intel_syntax)
+	{
+	  if (mod != 0 || (base & 7) == 5)
+	    {
+	      if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+			      | PREFIX_ES | PREFIX_FS | PREFIX_GS))
+		;
+	      else
+		{
+		  oappend (names_seg[ds_reg - es_reg]);
+		  oappend (":");
+		}
+	      print_operand_value (scratchbuf, 1, disp);
+	      oappend (scratchbuf);
+	    }
+	}
+    }
+  else
+    { /* 16 bit address mode */
+      switch (mod)
+	{
+	case 0:
+	  if (rm == 6)
+	    {
+	      disp = get16 ();
+	      if ((disp & 0x8000) != 0)
+		disp -= 0x10000;
+	    }
+	  break;
+	case 1:
+	  FETCH_DATA (the_info, codep + 1);
+	  disp = *codep++;
+	  if ((disp & 0x80) != 0)
+	    disp -= 0x100;
+	  break;
+	case 2:
+	  disp = get16 ();
+	  if ((disp & 0x8000) != 0)
+	    disp -= 0x10000;
+	  break;
+	}
+
+      if (!intel_syntax)
+	if (mod != 0 || rm == 6)
+	  {
+	    print_operand_value (scratchbuf, 0, disp);
+	    oappend (scratchbuf);
+	  }
+
+      if (mod != 0 || rm != 6)
+	{
+	  *obufp++ = open_char;
+	  *obufp = '\0';
+	  oappend (index16[rm]);
+	  if (intel_syntax && disp)
+	    {
+	      if ((bfd_signed_vma) disp > 0)
+		{
+		  *obufp++ = '+';
+		  *obufp = '\0';
+		}
+	      else if (mod != 1)
+		{
+		  *obufp++ = '-';
+		  *obufp = '\0';
+		  disp = - (bfd_signed_vma) disp;
+		}
+
+	      print_operand_value (scratchbuf, mod != 1, disp);
+	      oappend (scratchbuf);
+	    }
+
+	  *obufp++ = close_char;
+	  *obufp = '\0';
+	}
+      else if (intel_syntax)
+	{
+	  if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+			  | PREFIX_ES | PREFIX_FS | PREFIX_GS))
+	    ;
+	  else
+	    {
+	      oappend (names_seg[ds_reg - es_reg]);
+	      oappend (":");
+	    }
+	  print_operand_value (scratchbuf, 1, disp & 0xffff);
+	  oappend (scratchbuf);
+	}
+    }
+}
+
+static void
+OP_G (int bytemode, int sizeflag)
+{
+  int add = 0;
+  USED_REX (REX_EXTX);
+  if (rex & REX_EXTX)
+    add += 8;
+  switch (bytemode)
+    {
+    case b_mode:
+      USED_REX (0);
+      if (rex)
+	oappend (names8rex[reg + add]);
+      else
+	oappend (names8[reg + add]);
+      break;
+    case w_mode:
+      oappend (names16[reg + add]);
+      break;
+    case d_mode:
+      oappend (names32[reg + add]);
+      break;
+    case q_mode:
+      oappend (names64[reg + add]);
+      break;
+    case v_mode:
+    case dq_mode:
+    case dqw_mode:
+      USED_REX (REX_MODE64);
+      if (rex & REX_MODE64)
+	oappend (names64[reg + add]);
+      else if ((sizeflag & DFLAG) || bytemode != v_mode)
+	oappend (names32[reg + add]);
+      else
+	oappend (names16[reg + add]);
+      used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
+    case m_mode:
+      if (mode_64bit)
+	oappend (names64[reg + add]);
+      else
+	oappend (names32[reg + add]);
+      break;
+    default:
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      break;
+    }
+}
+
+static bfd_vma
+get64 (void)
+{
+  bfd_vma x;
+#ifdef BFD64
+  unsigned int a;
+  unsigned int b;
+
+  FETCH_DATA (the_info, codep + 8);
+  a = *codep++ & 0xff;
+  a |= (*codep++ & 0xff) << 8;
+  a |= (*codep++ & 0xff) << 16;
+  a |= (*codep++ & 0xff) << 24;
+  b = *codep++ & 0xff;
+  b |= (*codep++ & 0xff) << 8;
+  b |= (*codep++ & 0xff) << 16;
+  b |= (*codep++ & 0xff) << 24;
+  x = a + ((bfd_vma) b << 32);
+#else
+  abort ();
+  x = 0;
+#endif
+  return x;
+}
+
+static bfd_signed_vma
+get32 (void)
+{
+  bfd_signed_vma x = 0;
+
+  FETCH_DATA (the_info, codep + 4);
+  x = *codep++ & (bfd_signed_vma) 0xff;
+  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
+  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
+  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
+  return x;
+}
+
+static bfd_signed_vma
+get32s (void)
+{
+  bfd_signed_vma x = 0;
+
+  FETCH_DATA (the_info, codep + 4);
+  x = *codep++ & (bfd_signed_vma) 0xff;
+  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
+  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
+  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
+
+  x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
+
+  return x;
+}
+
+static int
+get16 (void)
+{
+  int x = 0;
+
+  FETCH_DATA (the_info, codep + 2);
+  x = *codep++ & 0xff;
+  x |= (*codep++ & 0xff) << 8;
+  return x;
+}
+
+static void
+set_op (bfd_vma op, int riprel)
+{
+  op_index[op_ad] = op_ad;
+  if (mode_64bit)
+    {
+      op_address[op_ad] = op;
+      op_riprel[op_ad] = riprel;
+    }
+  else
+    {
+      /* Mask to get a 32-bit address.	*/
+      op_address[op_ad] = op & 0xffffffff;
+      op_riprel[op_ad] = riprel & 0xffffffff;
+    }
+}
+
+static void
+OP_REG (int code, int sizeflag)
+{
+  const char *s;
+  int add = 0;
+  USED_REX (REX_EXTZ);
+  if (rex & REX_EXTZ)
+    add = 8;
+
+  switch (code)
+    {
+    case indir_dx_reg:
+      if (intel_syntax)
+	s = "[dx]";
+      else
+	s = "(%dx)";
+      break;
+    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+    case sp_reg: case bp_reg: case si_reg: case di_reg:
+      s = names16[code - ax_reg + add];
+      break;
+    case es_reg: case ss_reg: case cs_reg:
+    case ds_reg: case fs_reg: case gs_reg:
+      s = names_seg[code - es_reg + add];
+      break;
+    case al_reg: case ah_reg: case cl_reg: case ch_reg:
+    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+      USED_REX (0);
+      if (rex)
+	s = names8rex[code - al_reg + add];
+      else
+	s = names8[code - al_reg];
+      break;
+    case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
+    case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
+      if (mode_64bit)
+	{
+	  s = names64[code - rAX_reg + add];
+	  break;
+	}
+      code += eAX_reg - rAX_reg;
+      /* Fall through.	*/
+    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+      USED_REX (REX_MODE64);
+      if (rex & REX_MODE64)
+	s = names64[code - eAX_reg + add];
+      else if (sizeflag & DFLAG)
+	s = names32[code - eAX_reg + add];
+      else
+	s = names16[code - eAX_reg + add];
+      used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
+    default:
+      s = INTERNAL_DISASSEMBLER_ERROR;
+      break;
+    }
+  oappend (s);
+}
+
+static void
+OP_IMREG (int code, int sizeflag)
+{
+  const char *s;
+
+  switch (code)
+    {
+    case indir_dx_reg:
+      if (intel_syntax)
+	s = "[dx]";
+      else
+	s = "(%dx)";
+      break;
+    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+    case sp_reg: case bp_reg: case si_reg: case di_reg:
+      s = names16[code - ax_reg];
+      break;
+    case es_reg: case ss_reg: case cs_reg:
+    case ds_reg: case fs_reg: case gs_reg:
+      s = names_seg[code - es_reg];
+      break;
+    case al_reg: case ah_reg: case cl_reg: case ch_reg:
+    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+      USED_REX (0);
+      if (rex)
+	s = names8rex[code - al_reg];
+      else
+	s = names8[code - al_reg];
+      break;
+    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+      USED_REX (REX_MODE64);
+      if (rex & REX_MODE64)
+	s = names64[code - eAX_reg];
+      else if (sizeflag & DFLAG)
+	s = names32[code - eAX_reg];
+      else
+	s = names16[code - eAX_reg];
+      used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
+    default:
+      s = INTERNAL_DISASSEMBLER_ERROR;
+      break;
+    }
+  oappend (s);
+}
+
+static void
+OP_I (int bytemode, int sizeflag)
+{
+  bfd_signed_vma op;
+  bfd_signed_vma mask = -1;
+
+  switch (bytemode)
+    {
+    case b_mode:
+      FETCH_DATA (the_info, codep + 1);
+      op = *codep++;
+      mask = 0xff;
+      break;
+    case q_mode:
+      if (mode_64bit)
+	{
+	  op = get32s ();
+	  break;
+	}
+      /* Fall through.	*/
+    case v_mode:
+      USED_REX (REX_MODE64);
+      if (rex & REX_MODE64)
+	op = get32s ();
+      else if (sizeflag & DFLAG)
+	{
+	  op = get32 ();
+	  mask = 0xffffffff;
+	}
+      else
+	{
+	  op = get16 ();
+	  mask = 0xfffff;
+	}
+      used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
+    case w_mode:
+      mask = 0xfffff;
+      op = get16 ();
+      break;
+    case const_1_mode:
+      if (intel_syntax)
+	oappend ("1");
+      return;
+    default:
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      return;
+    }
+
+  op &= mask;
+  scratchbuf[0] = '$';
+  print_operand_value (scratchbuf + 1, 1, op);
+  oappend (scratchbuf + intel_syntax);
+  scratchbuf[0] = '\0';
+}
+
+static void
+OP_I64 (int bytemode, int sizeflag)
+{
+  bfd_signed_vma op;
+  bfd_signed_vma mask = -1;
+
+  if (!mode_64bit)
+    {
+      OP_I (bytemode, sizeflag);
+      return;
+    }
+
+  switch (bytemode)
+    {
+    case b_mode:
+      FETCH_DATA (the_info, codep + 1);
+      op = *codep++;
+      mask = 0xff;
+      break;
+    case v_mode:
+      USED_REX (REX_MODE64);
+      if (rex & REX_MODE64)
+	op = get64 ();
+      else if (sizeflag & DFLAG)
+	{
+	  op = get32 ();
+	  mask = 0xffffffff;
+	}
+      else
+	{
+	  op = get16 ();
+	  mask = 0xfffff;
+	}
+      used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
+    case w_mode:
+      mask = 0xfffff;
+      op = get16 ();
+      break;
+    default:
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      return;
+    }
+
+  op &= mask;
+  scratchbuf[0] = '$';
+  print_operand_value (scratchbuf + 1, 1, op);
+  oappend (scratchbuf + intel_syntax);
+  scratchbuf[0] = '\0';
+}
+
+static void
+OP_sI (int bytemode, int sizeflag)
+{
+  bfd_signed_vma op;
+  bfd_signed_vma mask = -1;
+
+  switch (bytemode)
+    {
+    case b_mode:
+      FETCH_DATA (the_info, codep + 1);
+      op = *codep++;
+      if ((op & 0x80) != 0)
+	op -= 0x100;
+      mask = 0xffffffff;
+      break;
+    case v_mode:
+      USED_REX (REX_MODE64);
+      if (rex & REX_MODE64)
+	op = get32s ();
+      else if (sizeflag & DFLAG)
+	{
+	  op = get32s ();
+	  mask = 0xffffffff;
+	}
+      else
+	{
+	  mask = 0xffffffff;
+	  op = get16 ();
+	  if ((op & 0x8000) != 0)
+	    op -= 0x10000;
+	}
+      used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
+    case w_mode:
+      op = get16 ();
+      mask = 0xffffffff;
+      if ((op & 0x8000) != 0)
+	op -= 0x10000;
+      break;
+    default:
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      return;
+    }
+
+  scratchbuf[0] = '$';
+  print_operand_value (scratchbuf + 1, 1, op);
+  oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_J (int bytemode, int sizeflag)
+{
+  bfd_vma disp;
+  bfd_vma mask = -1;
+
+  switch (bytemode)
+    {
+    case b_mode:
+      FETCH_DATA (the_info, codep + 1);
+      disp = *codep++;
+      if ((disp & 0x80) != 0)
+	disp -= 0x100;
+      break;
+    case v_mode:
+      if (sizeflag & DFLAG)
+	disp = get32s ();
+      else
+	{
+	  disp = get16 ();
+	  /* For some reason, a data16 prefix on a jump instruction
+	     means that the pc is masked to 16 bits after the
+	     displacement is added!  */
+	  mask = 0xffff;
+	}
+      break;
+    default:
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      return;
+    }
+  disp = (start_pc + codep - start_codep + disp) & mask;
+  set_op (disp, 0);
+  print_operand_value (scratchbuf, 1, disp);
+  oappend (scratchbuf);
+}
+
+static void
+OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  oappend (names_seg[reg]);
+}
+
+static void
+OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
+{
+  int seg, offset;
+
+  if (sizeflag & DFLAG)
+    {
+      offset = get32 ();
+      seg = get16 ();
+    }
+  else
+    {
+      offset = get16 ();
+      seg = get16 ();
+    }
+  used_prefixes |= (prefixes & PREFIX_DATA);
+  if (intel_syntax)
+    sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
+  else
+    sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
+  oappend (scratchbuf);
+}
+
+static void
+OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
+{
+  bfd_vma off;
+
+  append_seg ();
+
+  if ((sizeflag & AFLAG) || mode_64bit)
+    off = get32 ();
+  else
+    off = get16 ();
+
+  if (intel_syntax)
+    {
+      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+	{
+	  oappend (names_seg[ds_reg - es_reg]);
+	  oappend (":");
+	}
+    }
+  print_operand_value (scratchbuf, 1, off);
+  oappend (scratchbuf);
+}
+
+static void
+OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  bfd_vma off;
+
+  if (!mode_64bit)
+    {
+      OP_OFF (bytemode, sizeflag);
+      return;
+    }
+
+  append_seg ();
+
+  off = get64 ();
+
+  if (intel_syntax)
+    {
+      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+	{
+	  oappend (names_seg[ds_reg - es_reg]);
+	  oappend (":");
+	}
+    }
+  print_operand_value (scratchbuf, 1, off);
+  oappend (scratchbuf);
+}
+
+static void
+ptr_reg (int code, int sizeflag)
+{
+  const char *s;
+
+  *obufp++ = open_char;
+  used_prefixes |= (prefixes & PREFIX_ADDR);
+  if (mode_64bit)
+    {
+      if (!(sizeflag & AFLAG))
+	s = names32[code - eAX_reg];
+      else
+	s = names64[code - eAX_reg];
+    }
+  else if (sizeflag & AFLAG)
+    s = names32[code - eAX_reg];
+  else
+    s = names16[code - eAX_reg];
+  oappend (s);
+  *obufp++ = close_char;
+  *obufp = 0;
+}
+
+static void
+OP_ESreg (int code, int sizeflag)
+{
+  if (intel_syntax)
+    {
+      if (codep[-1] & 1)
+	{
+	  USED_REX (REX_MODE64);
+	  used_prefixes |= (prefixes & PREFIX_DATA);
+	  if (rex & REX_MODE64)
+	    oappend ("QWORD PTR ");
+	  else if ((sizeflag & DFLAG))
+	    oappend ("DWORD PTR ");
+	  else
+	    oappend ("WORD PTR ");
+	}
+      else
+	oappend ("BYTE PTR ");
+    }
+
+  oappend ("%es:" + intel_syntax);
+  ptr_reg (code, sizeflag);
+}
+
+static void
+OP_DSreg (int code, int sizeflag)
+{
+  if (intel_syntax)
+    {
+      if (codep[-1] != 0xd7 && (codep[-1] & 1))
+	{
+	  USED_REX (REX_MODE64);
+	  used_prefixes |= (prefixes & PREFIX_DATA);
+	  if (rex & REX_MODE64)
+	    oappend ("QWORD PTR ");
+	  else if ((sizeflag & DFLAG))
+	    oappend ("DWORD PTR ");
+	  else
+	    oappend ("WORD PTR ");
+	}
+      else
+	oappend ("BYTE PTR ");
+    }
+
+  if ((prefixes
+       & (PREFIX_CS
+	  | PREFIX_DS
+	  | PREFIX_SS
+	  | PREFIX_ES
+	  | PREFIX_FS
+	  | PREFIX_GS)) == 0)
+    prefixes |= PREFIX_DS;
+  append_seg ();
+  ptr_reg (code, sizeflag);
+}
+
+static void
+OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  int add = 0;
+  if (rex & REX_EXTX)
+    {
+      USED_REX (REX_EXTX);
+      add = 8;
+    }
+  else if (!mode_64bit && (prefixes & PREFIX_LOCK))
+    {
+      used_prefixes |= PREFIX_LOCK;
+      add = 8;
+    }
+  sprintf (scratchbuf, "%%cr%d", reg + add);
+  oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  int add = 0;
+  USED_REX (REX_EXTX);
+  if (rex & REX_EXTX)
+    add = 8;
+  if (intel_syntax)
+    sprintf (scratchbuf, "db%d", reg + add);
+  else
+    sprintf (scratchbuf, "%%db%d", reg + add);
+  oappend (scratchbuf);
+}
+
+static void
+OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  sprintf (scratchbuf, "%%tr%d", reg);
+  oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_Rd (int bytemode, int sizeflag)
+{
+  if (mod == 3)
+    OP_E (bytemode, sizeflag);
+  else
+    BadOp ();
+}
+
+static void
+OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  used_prefixes |= (prefixes & PREFIX_DATA);
+  if (prefixes & PREFIX_DATA)
+    {
+      int add = 0;
+      USED_REX (REX_EXTX);
+      if (rex & REX_EXTX)
+	add = 8;
+      sprintf (scratchbuf, "%%xmm%d", reg + add);
+    }
+  else
+    sprintf (scratchbuf, "%%mm%d", reg);
+  oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  int add = 0;
+  USED_REX (REX_EXTX);
+  if (rex & REX_EXTX)
+    add = 8;
+  sprintf (scratchbuf, "%%xmm%d", reg + add);
+  oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_EM (int bytemode, int sizeflag)
+{
+  if (mod != 3)
+    {
+      if (intel_syntax && bytemode == v_mode)
+	{
+	  bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
+	  used_prefixes |= (prefixes & PREFIX_DATA);
+	}
+      OP_E (bytemode, sizeflag);
+      return;
+    }
+
+  /* Skip mod/rm byte.	*/
+  MODRM_CHECK;
+  codep++;
+  used_prefixes |= (prefixes & PREFIX_DATA);
+  if (prefixes & PREFIX_DATA)
+    {
+      int add = 0;
+
+      USED_REX (REX_EXTZ);
+      if (rex & REX_EXTZ)
+	add = 8;
+      sprintf (scratchbuf, "%%xmm%d", rm + add);
+    }
+  else
+    sprintf (scratchbuf, "%%mm%d", rm);
+  oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_EX (int bytemode, int sizeflag)
+{
+  int add = 0;
+  if (mod != 3)
+    {
+      if (intel_syntax && bytemode == v_mode)
+	{
+	  switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
+	    {
+	    case 0:	       bytemode = x_mode; break;
+	    case PREFIX_REPZ:  bytemode = d_mode; used_prefixes |= PREFIX_REPZ;	 break;
+	    case PREFIX_DATA:  bytemode = x_mode; used_prefixes |= PREFIX_DATA;	 break;
+	    case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
+	    default:	       bytemode = 0; break;
+	    }
+	}
+      OP_E (bytemode, sizeflag);
+      return;
+    }
+  USED_REX (REX_EXTZ);
+  if (rex & REX_EXTZ)
+    add = 8;
+
+  /* Skip mod/rm byte.	*/
+  MODRM_CHECK;
+  codep++;
+  sprintf (scratchbuf, "%%xmm%d", rm + add);
+  oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_MS (int bytemode, int sizeflag)
+{
+  if (mod == 3)
+    OP_EM (bytemode, sizeflag);
+  else
+    BadOp ();
+}
+
+static void
+OP_XS (int bytemode, int sizeflag)
+{
+  if (mod == 3)
+    OP_EX (bytemode, sizeflag);
+  else
+    BadOp ();
+}
+
+static void
+OP_M (int bytemode, int sizeflag)
+{
+  if (mod == 3)
+    BadOp ();	/* bad lea,lds,les,lfs,lgs,lss modrm */
+  else
+    OP_E (bytemode, sizeflag);
+}
+
+static void
+OP_0f07 (int bytemode, int sizeflag)
+{
+  if (mod != 3 || rm != 0)
+    BadOp ();
+  else
+    OP_E (bytemode, sizeflag);
+}
+
+static void
+OP_0fae (int bytemode, int sizeflag)
+{
+  if (mod == 3)
+    {
+      if (reg == 7)
+	strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
+
+      if (reg < 5 || rm != 0)
+	{
+	  BadOp ();	/* bad sfence, mfence, or lfence */
+	  return;
+	}
+    }
+  else if (reg != 7)
+    {
+      BadOp ();		/* bad clflush */
+      return;
+    }
+
+  OP_E (bytemode, sizeflag);
+}
+
+static void
+NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  /* NOP with REPZ prefix is called PAUSE.  */
+  if (prefixes == PREFIX_REPZ)
+    strcpy (obuf, "pause");
+}
+
+static const char *const Suffix3DNow[] = {
+/* 00 */	NULL,		NULL,		NULL,		NULL,
+/* 04 */	NULL,		NULL,		NULL,		NULL,
+/* 08 */	NULL,		NULL,		NULL,		NULL,
+/* 0C */	"pi2fw",	"pi2fd",	NULL,		NULL,
+/* 10 */	NULL,		NULL,		NULL,		NULL,
+/* 14 */	NULL,		NULL,		NULL,		NULL,
+/* 18 */	NULL,		NULL,		NULL,		NULL,
+/* 1C */	"pf2iw",	"pf2id",	NULL,		NULL,
+/* 20 */	NULL,		NULL,		NULL,		NULL,
+/* 24 */	NULL,		NULL,		NULL,		NULL,
+/* 28 */	NULL,		NULL,		NULL,		NULL,
+/* 2C */	NULL,		NULL,		NULL,		NULL,
+/* 30 */	NULL,		NULL,		NULL,		NULL,
+/* 34 */	NULL,		NULL,		NULL,		NULL,
+/* 38 */	NULL,		NULL,		NULL,		NULL,
+/* 3C */	NULL,		NULL,		NULL,		NULL,
+/* 40 */	NULL,		NULL,		NULL,		NULL,
+/* 44 */	NULL,		NULL,		NULL,		NULL,
+/* 48 */	NULL,		NULL,		NULL,		NULL,
+/* 4C */	NULL,		NULL,		NULL,		NULL,
+/* 50 */	NULL,		NULL,		NULL,		NULL,
+/* 54 */	NULL,		NULL,		NULL,		NULL,
+/* 58 */	NULL,		NULL,		NULL,		NULL,
+/* 5C */	NULL,		NULL,		NULL,		NULL,
+/* 60 */	NULL,		NULL,		NULL,		NULL,
+/* 64 */	NULL,		NULL,		NULL,		NULL,
+/* 68 */	NULL,		NULL,		NULL,		NULL,
+/* 6C */	NULL,		NULL,		NULL,		NULL,
+/* 70 */	NULL,		NULL,		NULL,		NULL,
+/* 74 */	NULL,		NULL,		NULL,		NULL,
+/* 78 */	NULL,		NULL,		NULL,		NULL,
+/* 7C */	NULL,		NULL,		NULL,		NULL,
+/* 80 */	NULL,		NULL,		NULL,		NULL,
+/* 84 */	NULL,		NULL,		NULL,		NULL,
+/* 88 */	NULL,		NULL,		"pfnacc",	NULL,
+/* 8C */	NULL,		NULL,		"pfpnacc",	NULL,
+/* 90 */	"pfcmpge",	NULL,		NULL,		NULL,
+/* 94 */	"pfmin",	NULL,		"pfrcp",	"pfrsqrt",
+/* 98 */	NULL,		NULL,		"pfsub",	NULL,
+/* 9C */	NULL,		NULL,		"pfadd",	NULL,
+/* A0 */	"pfcmpgt",	NULL,		NULL,		NULL,
+/* A4 */	"pfmax",	NULL,		"pfrcpit1",	"pfrsqit1",
+/* A8 */	NULL,		NULL,		"pfsubr",	NULL,
+/* AC */	NULL,		NULL,		"pfacc",	NULL,
+/* B0 */	"pfcmpeq",	NULL,		NULL,		NULL,
+/* B4 */	"pfmul",	NULL,		"pfrcpit2",	"pfmulhrw",
+/* B8 */	NULL,		NULL,		NULL,		"pswapd",
+/* BC */	NULL,		NULL,		NULL,		"pavgusb",
+/* C0 */	NULL,		NULL,		NULL,		NULL,
+/* C4 */	NULL,		NULL,		NULL,		NULL,
+/* C8 */	NULL,		NULL,		NULL,		NULL,
+/* CC */	NULL,		NULL,		NULL,		NULL,
+/* D0 */	NULL,		NULL,		NULL,		NULL,
+/* D4 */	NULL,		NULL,		NULL,		NULL,
+/* D8 */	NULL,		NULL,		NULL,		NULL,
+/* DC */	NULL,		NULL,		NULL,		NULL,
+/* E0 */	NULL,		NULL,		NULL,		NULL,
+/* E4 */	NULL,		NULL,		NULL,		NULL,
+/* E8 */	NULL,		NULL,		NULL,		NULL,
+/* EC */	NULL,		NULL,		NULL,		NULL,
+/* F0 */	NULL,		NULL,		NULL,		NULL,
+/* F4 */	NULL,		NULL,		NULL,		NULL,
+/* F8 */	NULL,		NULL,		NULL,		NULL,
+/* FC */	NULL,		NULL,		NULL,		NULL,
+};
+
+static void
+OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  const char *mnemonic;
+
+  FETCH_DATA (the_info, codep + 1);
+  /* AMD 3DNow! instructions are specified by an opcode suffix in the
+     place where an 8-bit immediate would normally go.	ie. the last
+     byte of the instruction.  */
+  obufp = obuf + strlen (obuf);
+  mnemonic = Suffix3DNow[*codep++ & 0xff];
+  if (mnemonic)
+    oappend (mnemonic);
+  else
+    {
+      /* Since a variable sized modrm/sib chunk is between the start
+	 of the opcode (0x0f0f) and the opcode suffix, we need to do
+	 all the modrm processing first, and don't know until now that
+	 we have a bad opcode.	This necessitates some cleaning up.  */
+      op1out[0] = '\0';
+      op2out[0] = '\0';
+      BadOp ();
+    }
+}
+
+static const char *simd_cmp_op[] = {
+  "eq",
+  "lt",
+  "le",
+  "unord",
+  "neq",
+  "nlt",
+  "nle",
+  "ord"
+};
+
+static void
+OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  unsigned int cmp_type;
+
+  FETCH_DATA (the_info, codep + 1);
+  obufp = obuf + strlen (obuf);
+  cmp_type = *codep++ & 0xff;
+  if (cmp_type < 8)
+    {
+      char suffix1 = 'p', suffix2 = 's';
+      used_prefixes |= (prefixes & PREFIX_REPZ);
+      if (prefixes & PREFIX_REPZ)
+	suffix1 = 's';
+      else
+	{
+	  used_prefixes |= (prefixes & PREFIX_DATA);
+	  if (prefixes & PREFIX_DATA)
+	    suffix2 = 'd';
+	  else
+	    {
+	      used_prefixes |= (prefixes & PREFIX_REPNZ);
+	      if (prefixes & PREFIX_REPNZ)
+		suffix1 = 's', suffix2 = 'd';
+	    }
+	}
+      sprintf (scratchbuf, "cmp%s%c%c",
+	       simd_cmp_op[cmp_type], suffix1, suffix2);
+      used_prefixes |= (prefixes & PREFIX_REPZ);
+      oappend (scratchbuf);
+    }
+  else
+    {
+      /* We have a bad extension byte.	Clean up.  */
+      op1out[0] = '\0';
+      op2out[0] = '\0';
+      BadOp ();
+    }
+}
+
+static void
+SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
+{
+  /* Change movlps/movhps to movhlps/movlhps for 2 register operand
+     forms of these instructions.  */
+  if (mod == 3)
+    {
+      char *p = obuf + strlen (obuf);
+      *(p + 1) = '\0';
+      *p       = *(p - 1);
+      *(p - 1) = *(p - 2);
+      *(p - 2) = *(p - 3);
+      *(p - 3) = extrachar;
+    }
+}
+
+static void
+PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+{
+  if (mod == 3 && reg == 1 && rm <= 1)
+    {
+      /* Override "sidt".  */
+      char *p = obuf + strlen (obuf) - 4;
+
+      /* We might have a suffix when disassembling with -Msuffix.  */
+      if (*p == 'i')
+	--p;
+
+      if (rm)
+	{
+	  /* mwait %eax,%ecx  */
+	  strcpy (p, "mwait");
+	  if (!intel_syntax)
+	    strcpy (op1out, names32[0]);
+	}
+      else
+	{
+	  /* monitor %eax,%ecx,%edx"  */
+	  strcpy (p, "monitor");
+	  if (!intel_syntax)
+	    {
+	      if (!mode_64bit)
+		strcpy (op1out, names32[0]);
+	      else if (!(prefixes & PREFIX_ADDR))
+		strcpy (op1out, names64[0]);
+	      else
+		{
+		  strcpy (op1out, names32[0]);
+		  used_prefixes |= PREFIX_ADDR;
+		}
+	      strcpy (op3out, names32[2]);
+	    }
+	}
+      if (!intel_syntax)
+	{
+	  strcpy (op2out, names32[1]);
+	  two_source_ops = 1;
+	}
+
+      codep++;
+    }
+  else
+    OP_M (0, sizeflag);
+}
+
+static void
+SVME_Fixup (int bytemode, int sizeflag)
+{
+  const char *alt;
+  char *p;
+
+  switch (*codep)
+    {
+    case 0xd8:
+      alt = "vmrun";
+      break;
+    case 0xd9:
+      alt = "vmmcall";
+      break;
+    case 0xda:
+      alt = "vmload";
+      break;
+    case 0xdb:
+      alt = "vmsave";
+      break;
+    case 0xdc:
+      alt = "stgi";
+      break;
+    case 0xdd:
+      alt = "clgi";
+      break;
+    case 0xde:
+      alt = "skinit";
+      break;
+    case 0xdf:
+      alt = "invlpga";
+      break;
+    default:
+      OP_M (bytemode, sizeflag);
+      return;
+    }
+  /* Override "lidt".  */
+  p = obuf + strlen (obuf) - 4;
+  /* We might have a suffix.  */
+  if (*p == 'i')
+    --p;
+  strcpy (p, alt);
+  if (!(prefixes & PREFIX_ADDR))
+    {
+      ++codep;
+      return;
+    }
+  used_prefixes |= PREFIX_ADDR;
+  switch (*codep++)
+    {
+    case 0xdf:
+      strcpy (op2out, names32[1]);
+      two_source_ops = 1;
+	  /* Fall through.  */
+    case 0xd8:
+    case 0xda:
+    case 0xdb:
+      *obufp++ = open_char;
+      if (mode_64bit || (sizeflag & AFLAG))
+        alt = names32[0];
+      else
+        alt = names16[0];
+      strcpy (obufp, alt);
+      obufp += strlen (alt);
+      *obufp++ = close_char;
+      *obufp = '\0';
+      break;
+    }
+}
+
+static void
+INVLPG_Fixup (int bytemode, int sizeflag)
+{
+  const char *alt;
+
+  switch (*codep)
+    {
+    case 0xf8:
+      alt = "swapgs";
+      break;
+    case 0xf9:
+      alt = "rdtscp";
+      break;
+    default:
+      OP_M (bytemode, sizeflag);
+      return;
+    }
+  /* Override "invlpg".  */
+  strcpy (obuf + strlen (obuf) - 6, alt);
+  codep++;
+}
+
+static void
+BadOp (void)
+{
+  /* Throw away prefixes and 1st. opcode byte.  */
+  codep = insn_codep + 1;
+  oappend ("(bad)");
+}
+
+static void
+SEG_Fixup (int extrachar, int sizeflag)
+{
+  if (mod == 3)
+    {
+      /* We need to add a proper suffix with
+
+		movw %ds,%ax
+		movl %ds,%eax
+		movq %ds,%rax
+		movw %ax,%ds
+		movl %eax,%ds
+		movq %rax,%ds
+       */
+      const char *suffix;
+
+      if (prefixes & PREFIX_DATA)
+	suffix = "w";
+      else
+	{
+	  USED_REX (REX_MODE64);
+	  if (rex & REX_MODE64)
+	    suffix = "q";
+	  else
+	    suffix = "l";
+	}
+      strcat (obuf, suffix);
+    }
+  else
+    {
+      /* We need to fix the suffix for
+
+		movw %ds,(%eax)
+		movw %ds,(%rax)
+		movw (%eax),%ds
+		movw (%rax),%ds
+
+	 Override "mov[l|q]".  */
+      char *p = obuf + strlen (obuf) - 1;
+
+      /* We might not have a suffix.  */
+      if (*p == 'v')
+	++p;
+      *p = 'w';
+    }
+
+  OP_E (extrachar, sizeflag);
+}
+
+static void
+VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+{
+  if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
+    {
+      /* Override "sgdt".  */
+      char *p = obuf + strlen (obuf) - 4;
+
+      /* We might have a suffix when disassembling with -Msuffix.  */
+      if (*p == 'g')
+	--p;
+
+      switch (rm)
+	{
+	case 1:
+	  strcpy (p, "vmcall");
+	  break;
+	case 2:
+	  strcpy (p, "vmlaunch");
+	  break;
+	case 3:
+	  strcpy (p, "vmresume");
+	  break;
+	case 4:
+	  strcpy (p, "vmxoff");
+	  break;
+	}
+
+      codep++;
+    }
+  else
+    OP_E (0, sizeflag);
+}
+
+static void
+OP_VMX (int bytemode, int sizeflag)
+{
+  used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
+  if (prefixes & PREFIX_DATA)
+    strcpy (obuf, "vmclear");
+  else if (prefixes & PREFIX_REPZ)
+    strcpy (obuf, "vmxon");
+  else
+    strcpy (obuf, "vmptrld");
+  OP_E (bytemode, sizeflag);
+}
Index: xfs-dev/arch/x86/kdb/x86_64-dis.c
===================================================================
--- xfs-dev.orig/arch/x86/kdb/x86_64-dis.c	2008-12-23 09:30:36.650197196 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,4686 +0,0 @@
-/* Print i386 instructions for GDB, the GNU debugger.
-   Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
- * Run through col -b to remove trailing whitespace and various #ifdef/ifndef
- * __KERNEL__ added.
- * Keith Owens <kaos at sgi.com> 15 May 2006
- */
-
-/* 80386 instruction printer by Pace Willisson (pace at prep.ai.mit.edu)
-   July 1988
-    modified by John Hassey (hassey at dg-rtp.dg.com)
-    x86-64 support added by Jan Hubicka (jh at suse.cz)
-    VIA PadLock support by Michal Ludvig (mludvig at suse.cz).  */
-
-/* The main tables describing the instructions is essentially a copy
-   of the "Opcode Map" chapter (Appendix A) of the Intel 80386
-   Programmers Manual.	Usually, there is a capital letter, followed
-   by a small letter.  The capital letter tell the addressing mode,
-   and the small letter tells about the operand size.  Refer to
-   the Intel manual for details.  */
-
-#ifdef __KERNEL__
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/dis-asm.h>
-#include <linux/kdb.h>
-#define abort() BUG()
-#else	/* __KERNEL__ */
-#include "dis-asm.h"
-#include "sysdep.h"
-#include "opintl.h"
-#endif	/* __KERNEL__ */
-
-#define MAXLEN 20
-
-#ifndef __KERNEL__
-#include <setjmp.h>
-#endif	/* __KERNEL__ */
-
-#ifndef UNIXWARE_COMPAT
-/* Set non-zero for broken, compatible instructions.  Set to zero for
-   non-broken opcodes.	*/
-#define UNIXWARE_COMPAT 1
-#endif
-
-static int fetch_data (struct disassemble_info *, bfd_byte *);
-static void ckprefix (void);
-static const char *prefix_name (int, int);
-static int print_insn (bfd_vma, disassemble_info *);
-static void dofloat (int);
-static void OP_ST (int, int);
-static void OP_STi (int, int);
-static int putop (const char *, int);
-static void oappend (const char *);
-static void append_seg (void);
-static void OP_indirE (int, int);
-static void print_operand_value (char *, int, bfd_vma);
-static void OP_E (int, int);
-static void OP_G (int, int);
-static bfd_vma get64 (void);
-static bfd_signed_vma get32 (void);
-static bfd_signed_vma get32s (void);
-static int get16 (void);
-static void set_op (bfd_vma, int);
-static void OP_REG (int, int);
-static void OP_IMREG (int, int);
-static void OP_I (int, int);
-static void OP_I64 (int, int);
-static void OP_sI (int, int);
-static void OP_J (int, int);
-static void OP_SEG (int, int);
-static void OP_DIR (int, int);
-static void OP_OFF (int, int);
-static void OP_OFF64 (int, int);
-static void ptr_reg (int, int);
-static void OP_ESreg (int, int);
-static void OP_DSreg (int, int);
-static void OP_C (int, int);
-static void OP_D (int, int);
-static void OP_T (int, int);
-static void OP_Rd (int, int);
-static void OP_MMX (int, int);
-static void OP_XMM (int, int);
-static void OP_EM (int, int);
-static void OP_EX (int, int);
-static void OP_MS (int, int);
-static void OP_XS (int, int);
-static void OP_M (int, int);
-static void OP_VMX (int, int);
-static void OP_0fae (int, int);
-static void OP_0f07 (int, int);
-static void NOP_Fixup (int, int);
-static void OP_3DNowSuffix (int, int);
-static void OP_SIMD_Suffix (int, int);
-static void SIMD_Fixup (int, int);
-static void PNI_Fixup (int, int);
-static void SVME_Fixup (int, int);
-static void INVLPG_Fixup (int, int);
-static void BadOp (void);
-static void SEG_Fixup (int, int);
-static void VMX_Fixup (int, int);
-
-struct dis_private {
-  /* Points to first byte not fetched.	*/
-  bfd_byte *max_fetched;
-  bfd_byte the_buffer[MAXLEN];
-  bfd_vma insn_start;
-  int orig_sizeflag;
-#ifndef __KERNEL__
-  jmp_buf bailout;
-#endif	/* __KERNEL__ */
-};
-
-/* The opcode for the fwait instruction, which we treat as a prefix
-   when we can.	 */
-#define FWAIT_OPCODE (0x9b)
-
-/* Set to 1 for 64bit mode disassembly.	 */
-static int mode_64bit;
-
-/* Flags for the prefixes for the current instruction.	See below.  */
-static int prefixes;
-
-/* REX prefix the current instruction.	See below.  */
-static int rex;
-/* Bits of REX we've already used.  */
-static int rex_used;
-#define REX_MODE64	8
-#define REX_EXTX	4
-#define REX_EXTY	2
-#define REX_EXTZ	1
-/* Mark parts used in the REX prefix.  When we are testing for
-   empty prefix (for 8bit register REX extension), just mask it
-   out.	 Otherwise test for REX bit is excuse for existence of REX
-   only in case value is nonzero.  */
-#define USED_REX(value)					\
-  {							\
-    if (value)						\
-      rex_used |= (rex & value) ? (value) | 0x40 : 0;	\
-    else						\
-      rex_used |= 0x40;					\
-  }
-
-/* Flags for prefixes which we somehow handled when printing the
-   current instruction.	 */
-static int used_prefixes;
-
-/* Flags stored in PREFIXES.  */
-#define PREFIX_REPZ 1
-#define PREFIX_REPNZ 2
-#define PREFIX_LOCK 4
-#define PREFIX_CS 8
-#define PREFIX_SS 0x10
-#define PREFIX_DS 0x20
-#define PREFIX_ES 0x40
-#define PREFIX_FS 0x80
-#define PREFIX_GS 0x100
-#define PREFIX_DATA 0x200
-#define PREFIX_ADDR 0x400
-#define PREFIX_FWAIT 0x800
-
-/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
-   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
-   on error.  */
-#define FETCH_DATA(info, addr) \
-  ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
-   ? 1 : fetch_data ((info), (addr)))
-
-static int
-fetch_data (struct disassemble_info *info, bfd_byte *addr)
-{
-  int status;
-  struct dis_private *priv = (struct dis_private *) info->private_data;
-  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
-
-  status = (*info->read_memory_func) (start,
-				      priv->max_fetched,
-				      addr - priv->max_fetched,
-				      info);
-  if (status != 0)
-    {
-      /* If we did manage to read at least one byte, then
-	 print_insn_i386 will do something sensible.  Otherwise, print
-	 an error.  We do that here because this is where we know
-	 STATUS.  */
-      if (priv->max_fetched == priv->the_buffer)
-	(*info->memory_error_func) (status, start, info);
-#ifndef __KERNEL__
-      longjmp (priv->bailout, 1);
-#else	/* __KERNEL__ */
-	/* XXX - what to do? */
-	kdb_printf("Hmm. longjmp.\n");
-#endif	/* __KERNEL__ */
-    }
-  else
-    priv->max_fetched = addr;
-  return 1;
-}
-
-#define XX NULL, 0
-
-#define Eb OP_E, b_mode
-#define Ev OP_E, v_mode
-#define Ed OP_E, d_mode
-#define Eq OP_E, q_mode
-#define Edq OP_E, dq_mode
-#define Edqw OP_E, dqw_mode
-#define indirEv OP_indirE, branch_v_mode
-#define indirEp OP_indirE, f_mode
-#define Em OP_E, m_mode
-#define Ew OP_E, w_mode
-#define Ma OP_E, v_mode
-#define M OP_M, 0		/* lea, lgdt, etc. */
-#define Mp OP_M, f_mode		/* 32 or 48 bit memory operand for LDS, LES etc */
-#define Gb OP_G, b_mode
-#define Gv OP_G, v_mode
-#define Gd OP_G, d_mode
-#define Gdq OP_G, dq_mode
-#define Gm OP_G, m_mode
-#define Gw OP_G, w_mode
-#define Rd OP_Rd, d_mode
-#define Rm OP_Rd, m_mode
-#define Ib OP_I, b_mode
-#define sIb OP_sI, b_mode	/* sign extened byte */
-#define Iv OP_I, v_mode
-#define Iq OP_I, q_mode
-#define Iv64 OP_I64, v_mode
-#define Iw OP_I, w_mode
-#define I1 OP_I, const_1_mode
-#define Jb OP_J, b_mode
-#define Jv OP_J, v_mode
-#define Cm OP_C, m_mode
-#define Dm OP_D, m_mode
-#define Td OP_T, d_mode
-#define Sv SEG_Fixup, v_mode
-
-#define RMeAX OP_REG, eAX_reg
-#define RMeBX OP_REG, eBX_reg
-#define RMeCX OP_REG, eCX_reg
-#define RMeDX OP_REG, eDX_reg
-#define RMeSP OP_REG, eSP_reg
-#define RMeBP OP_REG, eBP_reg
-#define RMeSI OP_REG, eSI_reg
-#define RMeDI OP_REG, eDI_reg
-#define RMrAX OP_REG, rAX_reg
-#define RMrBX OP_REG, rBX_reg
-#define RMrCX OP_REG, rCX_reg
-#define RMrDX OP_REG, rDX_reg
-#define RMrSP OP_REG, rSP_reg
-#define RMrBP OP_REG, rBP_reg
-#define RMrSI OP_REG, rSI_reg
-#define RMrDI OP_REG, rDI_reg
-#define RMAL OP_REG, al_reg
-#define RMAL OP_REG, al_reg
-#define RMCL OP_REG, cl_reg
-#define RMDL OP_REG, dl_reg
-#define RMBL OP_REG, bl_reg
-#define RMAH OP_REG, ah_reg
-#define RMCH OP_REG, ch_reg
-#define RMDH OP_REG, dh_reg
-#define RMBH OP_REG, bh_reg
-#define RMAX OP_REG, ax_reg
-#define RMDX OP_REG, dx_reg
-
-#define eAX OP_IMREG, eAX_reg
-#define eBX OP_IMREG, eBX_reg
-#define eCX OP_IMREG, eCX_reg
-#define eDX OP_IMREG, eDX_reg
-#define eSP OP_IMREG, eSP_reg
-#define eBP OP_IMREG, eBP_reg
-#define eSI OP_IMREG, eSI_reg
-#define eDI OP_IMREG, eDI_reg
-#define AL OP_IMREG, al_reg
-#define AL OP_IMREG, al_reg
-#define CL OP_IMREG, cl_reg
-#define DL OP_IMREG, dl_reg
-#define BL OP_IMREG, bl_reg
-#define AH OP_IMREG, ah_reg
-#define CH OP_IMREG, ch_reg
-#define DH OP_IMREG, dh_reg
-#define BH OP_IMREG, bh_reg
-#define AX OP_IMREG, ax_reg
-#define DX OP_IMREG, dx_reg
-#define indirDX OP_IMREG, indir_dx_reg
-
-#define Sw OP_SEG, w_mode
-#define Ap OP_DIR, 0
-#define Ob OP_OFF, b_mode
-#define Ob64 OP_OFF64, b_mode
-#define Ov OP_OFF, v_mode
-#define Ov64 OP_OFF64, v_mode
-#define Xb OP_DSreg, eSI_reg
-#define Xv OP_DSreg, eSI_reg
-#define Yb OP_ESreg, eDI_reg
-#define Yv OP_ESreg, eDI_reg
-#define DSBX OP_DSreg, eBX_reg
-
-#define es OP_REG, es_reg
-#define ss OP_REG, ss_reg
-#define cs OP_REG, cs_reg
-#define ds OP_REG, ds_reg
-#define fs OP_REG, fs_reg
-#define gs OP_REG, gs_reg
-
-#define MX OP_MMX, 0
-#define XM OP_XMM, 0
-#define EM OP_EM, v_mode
-#define EX OP_EX, v_mode
-#define MS OP_MS, v_mode
-#define XS OP_XS, v_mode
-#define VM OP_VMX, q_mode
-#define OPSUF OP_3DNowSuffix, 0
-#define OPSIMD OP_SIMD_Suffix, 0
-
-#define cond_jump_flag NULL, cond_jump_mode
-#define loop_jcxz_flag NULL, loop_jcxz_mode
-
-/* bits in sizeflag */
-#define SUFFIX_ALWAYS 4
-#define AFLAG 2
-#define DFLAG 1
-
-#define b_mode 1  /* byte operand */
-#define v_mode 2  /* operand size depends on prefixes */
-#define w_mode 3  /* word operand */
-#define d_mode 4  /* double word operand  */
-#define q_mode 5  /* quad word operand */
-#define t_mode 6  /* ten-byte operand */
-#define x_mode 7  /* 16-byte XMM operand */
-#define m_mode 8  /* d_mode in 32bit, q_mode in 64bit mode.  */
-#define cond_jump_mode 9
-#define loop_jcxz_mode 10
-#define dq_mode 11 /* operand size depends on REX prefixes.  */
-#define dqw_mode 12 /* registers like dq_mode, memory like w_mode.  */
-#define f_mode 13 /* 4- or 6-byte pointer operand */
-#define const_1_mode 14
-#define branch_v_mode 15 /* v_mode for branch.	*/
-
-#define es_reg 100
-#define cs_reg 101
-#define ss_reg 102
-#define ds_reg 103
-#define fs_reg 104
-#define gs_reg 105
-
-#define eAX_reg 108
-#define eCX_reg 109
-#define eDX_reg 110
-#define eBX_reg 111
-#define eSP_reg 112
-#define eBP_reg 113
-#define eSI_reg 114
-#define eDI_reg 115
-
-#define al_reg 116
-#define cl_reg 117
-#define dl_reg 118
-#define bl_reg 119
-#define ah_reg 120
-#define ch_reg 121
-#define dh_reg 122
-#define bh_reg 123
-
-#define ax_reg 124
-#define cx_reg 125
-#define dx_reg 126
-#define bx_reg 127
-#define sp_reg 128
-#define bp_reg 129
-#define si_reg 130
-#define di_reg 131
-
-#define rAX_reg 132
-#define rCX_reg 133
-#define rDX_reg 134
-#define rBX_reg 135
-#define rSP_reg 136
-#define rBP_reg 137
-#define rSI_reg 138
-#define rDI_reg 139
-
-#define indir_dx_reg 150
-
-#define FLOATCODE 1
-#define USE_GROUPS 2
-#define USE_PREFIX_USER_TABLE 3
-#define X86_64_SPECIAL 4
-
-#define FLOAT	  NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
-
-#define GRP1b	  NULL, NULL, USE_GROUPS, NULL,	 0, NULL, 0
-#define GRP1S	  NULL, NULL, USE_GROUPS, NULL,	 1, NULL, 0
-#define GRP1Ss	  NULL, NULL, USE_GROUPS, NULL,	 2, NULL, 0
-#define GRP2b	  NULL, NULL, USE_GROUPS, NULL,	 3, NULL, 0
-#define GRP2S	  NULL, NULL, USE_GROUPS, NULL,	 4, NULL, 0
-#define GRP2b_one NULL, NULL, USE_GROUPS, NULL,	 5, NULL, 0
-#define GRP2S_one NULL, NULL, USE_GROUPS, NULL,	 6, NULL, 0
-#define GRP2b_cl  NULL, NULL, USE_GROUPS, NULL,	 7, NULL, 0
-#define GRP2S_cl  NULL, NULL, USE_GROUPS, NULL,	 8, NULL, 0
-#define GRP3b	  NULL, NULL, USE_GROUPS, NULL,	 9, NULL, 0
-#define GRP3S	  NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
-#define GRP4	  NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
-#define GRP5	  NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
-#define GRP6	  NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
-#define GRP7	  NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
-#define GRP8	  NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
-#define GRP9	  NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
-#define GRP10	  NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
-#define GRP11	  NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
-#define GRP12	  NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
-#define GRP13	  NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
-#define GRP14	  NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
-#define GRPAMD	  NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
-#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
-#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
-
-#define PREGRP0	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  0, NULL, 0
-#define PREGRP1	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  1, NULL, 0
-#define PREGRP2	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  2, NULL, 0
-#define PREGRP3	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  3, NULL, 0
-#define PREGRP4	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  4, NULL, 0
-#define PREGRP5	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  5, NULL, 0
-#define PREGRP6	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  6, NULL, 0
-#define PREGRP7	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  7, NULL, 0
-#define PREGRP8	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  8, NULL, 0
-#define PREGRP9	  NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  9, NULL, 0
-#define PREGRP10  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
-#define PREGRP11  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
-#define PREGRP12  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
-#define PREGRP13  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
-#define PREGRP14  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
-#define PREGRP15  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
-#define PREGRP16  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
-#define PREGRP17  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
-#define PREGRP18  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
-#define PREGRP19  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
-#define PREGRP20  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
-#define PREGRP21  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
-#define PREGRP22  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
-#define PREGRP23  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
-#define PREGRP24  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
-#define PREGRP25  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
-#define PREGRP26  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
-#define PREGRP27  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
-#define PREGRP28  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
-#define PREGRP29  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
-#define PREGRP30  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
-#define PREGRP31  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
-#define PREGRP32  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
-
-#define X86_64_0  NULL, NULL, X86_64_SPECIAL, NULL,  0, NULL, 0
-
-typedef void (*op_rtn) (int bytemode, int sizeflag);
-
-struct dis386 {
-  const char *name;
-  op_rtn op1;
-  int bytemode1;
-  op_rtn op2;
-  int bytemode2;
-  op_rtn op3;
-  int bytemode3;
-};
-
-/* Upper case letters in the instruction names here are macros.
-   'A' => print 'b' if no register operands or suffix_always is true
-   'B' => print 'b' if suffix_always is true
-   'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
-   .	  size prefix
-   'E' => print 'e' if 32-bit form of jcxz
-   'F' => print 'w' or 'l' depending on address size prefix (loop insns)
-   'H' => print ",pt" or ",pn" branch hint
-   'I' => honor following macro letter even in Intel mode (implemented only
-   .	  for some of the macro letters)
-   'J' => print 'l'
-   'L' => print 'l' if suffix_always is true
-   'N' => print 'n' if instruction has no wait "prefix"
-   'O' => print 'd', or 'o'
-   'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
-   .	  or suffix_always is true.  print 'q' if rex prefix is present.
-   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
-   .	  is true
-   'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
-   'S' => print 'w', 'l' or 'q' if suffix_always is true
-   'T' => print 'q' in 64bit mode and behave as 'P' otherwise
-   'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
-   'W' => print 'b' or 'w' ("w" or "de" in intel mode)
-   'X' => print 's', 'd' depending on data16 prefix (for XMM)
-   'Y' => 'q' if instruction has an REX 64bit overwrite prefix
-
-   Many of the above letters print nothing in Intel mode.  See "putop"
-   for the details.
-
-   Braces '{' and '}', and vertical bars '|', indicate alternative
-   mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
-   modes.  In cases where there are only two alternatives, the X86_64
-   instruction is reserved, and "(bad)" is printed.
-*/
-
-static const struct dis386 dis386[] = {
-  /* 00 */
-  { "addB",		Eb, Gb, XX },
-  { "addS",		Ev, Gv, XX },
-  { "addB",		Gb, Eb, XX },
-  { "addS",		Gv, Ev, XX },
-  { "addB",		AL, Ib, XX },
-  { "addS",		eAX, Iv, XX },
-  { "push{T|}",		es, XX, XX },
-  { "pop{T|}",		es, XX, XX },
-  /* 08 */
-  { "orB",		Eb, Gb, XX },
-  { "orS",		Ev, Gv, XX },
-  { "orB",		Gb, Eb, XX },
-  { "orS",		Gv, Ev, XX },
-  { "orB",		AL, Ib, XX },
-  { "orS",		eAX, Iv, XX },
-  { "push{T|}",		cs, XX, XX },
-  { "(bad)",		XX, XX, XX },	/* 0x0f extended opcode escape */
-  /* 10 */
-  { "adcB",		Eb, Gb, XX },
-  { "adcS",		Ev, Gv, XX },
-  { "adcB",		Gb, Eb, XX },
-  { "adcS",		Gv, Ev, XX },
-  { "adcB",		AL, Ib, XX },
-  { "adcS",		eAX, Iv, XX },
-  { "push{T|}",		ss, XX, XX },
-  { "popT|}",		ss, XX, XX },
-  /* 18 */
-  { "sbbB",		Eb, Gb, XX },
-  { "sbbS",		Ev, Gv, XX },
-  { "sbbB",		Gb, Eb, XX },
-  { "sbbS",		Gv, Ev, XX },
-  { "sbbB",		AL, Ib, XX },
-  { "sbbS",		eAX, Iv, XX },
-  { "push{T|}",		ds, XX, XX },
-  { "pop{T|}",		ds, XX, XX },
-  /* 20 */
-  { "andB",		Eb, Gb, XX },
-  { "andS",		Ev, Gv, XX },
-  { "andB",		Gb, Eb, XX },
-  { "andS",		Gv, Ev, XX },
-  { "andB",		AL, Ib, XX },
-  { "andS",		eAX, Iv, XX },
-  { "(bad)",		XX, XX, XX },	/* SEG ES prefix */
-  { "daa{|}",		XX, XX, XX },
-  /* 28 */
-  { "subB",		Eb, Gb, XX },
-  { "subS",		Ev, Gv, XX },
-  { "subB",		Gb, Eb, XX },
-  { "subS",		Gv, Ev, XX },
-  { "subB",		AL, Ib, XX },
-  { "subS",		eAX, Iv, XX },
-  { "(bad)",		XX, XX, XX },	/* SEG CS prefix */
-  { "das{|}",		XX, XX, XX },
-  /* 30 */
-  { "xorB",		Eb, Gb, XX },
-  { "xorS",		Ev, Gv, XX },
-  { "xorB",		Gb, Eb, XX },
-  { "xorS",		Gv, Ev, XX },
-  { "xorB",		AL, Ib, XX },
-  { "xorS",		eAX, Iv, XX },
-  { "(bad)",		XX, XX, XX },	/* SEG SS prefix */
-  { "aaa{|}",		XX, XX, XX },
-  /* 38 */
-  { "cmpB",		Eb, Gb, XX },
-  { "cmpS",		Ev, Gv, XX },
-  { "cmpB",		Gb, Eb, XX },
-  { "cmpS",		Gv, Ev, XX },
-  { "cmpB",		AL, Ib, XX },
-  { "cmpS",		eAX, Iv, XX },
-  { "(bad)",		XX, XX, XX },	/* SEG DS prefix */
-  { "aas{|}",		XX, XX, XX },
-  /* 40 */
-  { "inc{S|}",		RMeAX, XX, XX },
-  { "inc{S|}",		RMeCX, XX, XX },
-  { "inc{S|}",		RMeDX, XX, XX },
-  { "inc{S|}",		RMeBX, XX, XX },
-  { "inc{S|}",		RMeSP, XX, XX },
-  { "inc{S|}",		RMeBP, XX, XX },
-  { "inc{S|}",		RMeSI, XX, XX },
-  { "inc{S|}",		RMeDI, XX, XX },
-  /* 48 */
-  { "dec{S|}",		RMeAX, XX, XX },
-  { "dec{S|}",		RMeCX, XX, XX },
-  { "dec{S|}",		RMeDX, XX, XX },
-  { "dec{S|}",		RMeBX, XX, XX },
-  { "dec{S|}",		RMeSP, XX, XX },
-  { "dec{S|}",		RMeBP, XX, XX },
-  { "dec{S|}",		RMeSI, XX, XX },
-  { "dec{S|}",		RMeDI, XX, XX },
-  /* 50 */
-  { "pushS",		RMrAX, XX, XX },
-  { "pushS",		RMrCX, XX, XX },
-  { "pushS",		RMrDX, XX, XX },
-  { "pushS",		RMrBX, XX, XX },
-  { "pushS",		RMrSP, XX, XX },
-  { "pushS",		RMrBP, XX, XX },
-  { "pushS",		RMrSI, XX, XX },
-  { "pushS",		RMrDI, XX, XX },
-  /* 58 */
-  { "popS",		RMrAX, XX, XX },
-  { "popS",		RMrCX, XX, XX },
-  { "popS",		RMrDX, XX, XX },
-  { "popS",		RMrBX, XX, XX },
-  { "popS",		RMrSP, XX, XX },
-  { "popS",		RMrBP, XX, XX },
-  { "popS",		RMrSI, XX, XX },
-  { "popS",		RMrDI, XX, XX },
-  /* 60 */
-  { "pusha{P|}",	XX, XX, XX },
-  { "popa{P|}",		XX, XX, XX },
-  { "bound{S|}",	Gv, Ma, XX },
-  { X86_64_0 },
-  { "(bad)",		XX, XX, XX },	/* seg fs */
-  { "(bad)",		XX, XX, XX },	/* seg gs */
-  { "(bad)",		XX, XX, XX },	/* op size prefix */
-  { "(bad)",		XX, XX, XX },	/* adr size prefix */
-  /* 68 */
-  { "pushT",		Iq, XX, XX },
-  { "imulS",		Gv, Ev, Iv },
-  { "pushT",		sIb, XX, XX },
-  { "imulS",		Gv, Ev, sIb },
-  { "ins{b||b|}",	Yb, indirDX, XX },
-  { "ins{R||R|}",	Yv, indirDX, XX },
-  { "outs{b||b|}",	indirDX, Xb, XX },
-  { "outs{R||R|}",	indirDX, Xv, XX },
-  /* 70 */
-  { "joH",		Jb, XX, cond_jump_flag },
-  { "jnoH",		Jb, XX, cond_jump_flag },
-  { "jbH",		Jb, XX, cond_jump_flag },
-  { "jaeH",		Jb, XX, cond_jump_flag },
-  { "jeH",		Jb, XX, cond_jump_flag },
-  { "jneH",		Jb, XX, cond_jump_flag },
-  { "jbeH",		Jb, XX, cond_jump_flag },
-  { "jaH",		Jb, XX, cond_jump_flag },
-  /* 78 */
-  { "jsH",		Jb, XX, cond_jump_flag },
-  { "jnsH",		Jb, XX, cond_jump_flag },
-  { "jpH",		Jb, XX, cond_jump_flag },
-  { "jnpH",		Jb, XX, cond_jump_flag },
-  { "jlH",		Jb, XX, cond_jump_flag },
-  { "jgeH",		Jb, XX, cond_jump_flag },
-  { "jleH",		Jb, XX, cond_jump_flag },
-  { "jgH",		Jb, XX, cond_jump_flag },
-  /* 80 */
-  { GRP1b },
-  { GRP1S },
-  { "(bad)",		XX, XX, XX },
-  { GRP1Ss },
-  { "testB",		Eb, Gb, XX },
-  { "testS",		Ev, Gv, XX },
-  { "xchgB",		Eb, Gb, XX },
-  { "xchgS",		Ev, Gv, XX },
-  /* 88 */
-  { "movB",		Eb, Gb, XX },
-  { "movS",		Ev, Gv, XX },
-  { "movB",		Gb, Eb, XX },
-  { "movS",		Gv, Ev, XX },
-  { "movQ",		Sv, Sw, XX },
-  { "leaS",		Gv, M, XX },
-  { "movQ",		Sw, Sv, XX },
-  { "popU",		Ev, XX, XX },
-  /* 90 */
-  { "nop",		NOP_Fixup, 0, XX, XX },
-  { "xchgS",		RMeCX, eAX, XX },
-  { "xchgS",		RMeDX, eAX, XX },
-  { "xchgS",		RMeBX, eAX, XX },
-  { "xchgS",		RMeSP, eAX, XX },
-  { "xchgS",		RMeBP, eAX, XX },
-  { "xchgS",		RMeSI, eAX, XX },
-  { "xchgS",		RMeDI, eAX, XX },
-  /* 98 */
-  { "cW{tR||tR|}",	XX, XX, XX },
-  { "cR{tO||tO|}",	XX, XX, XX },
-  { "Jcall{T|}",	Ap, XX, XX },
-  { "(bad)",		XX, XX, XX },	/* fwait */
-  { "pushfT",		XX, XX, XX },
-  { "popfT",		XX, XX, XX },
-  { "sahf{|}",		XX, XX, XX },
-  { "lahf{|}",		XX, XX, XX },
-  /* a0 */
-  { "movB",		AL, Ob64, XX },
-  { "movS",		eAX, Ov64, XX },
-  { "movB",		Ob64, AL, XX },
-  { "movS",		Ov64, eAX, XX },
-  { "movs{b||b|}",	Yb, Xb, XX },
-  { "movs{R||R|}",	Yv, Xv, XX },
-  { "cmps{b||b|}",	Xb, Yb, XX },
-  { "cmps{R||R|}",	Xv, Yv, XX },
-  /* a8 */
-  { "testB",		AL, Ib, XX },
-  { "testS",		eAX, Iv, XX },
-  { "stosB",		Yb, AL, XX },
-  { "stosS",		Yv, eAX, XX },
-  { "lodsB",		AL, Xb, XX },
-  { "lodsS",		eAX, Xv, XX },
-  { "scasB",		AL, Yb, XX },
-  { "scasS",		eAX, Yv, XX },
-  /* b0 */
-  { "movB",		RMAL, Ib, XX },
-  { "movB",		RMCL, Ib, XX },
-  { "movB",		RMDL, Ib, XX },
-  { "movB",		RMBL, Ib, XX },
-  { "movB",		RMAH, Ib, XX },
-  { "movB",		RMCH, Ib, XX },
-  { "movB",		RMDH, Ib, XX },
-  { "movB",		RMBH, Ib, XX },
-  /* b8 */
-  { "movS",		RMeAX, Iv64, XX },
-  { "movS",		RMeCX, Iv64, XX },
-  { "movS",		RMeDX, Iv64, XX },
-  { "movS",		RMeBX, Iv64, XX },
-  { "movS",		RMeSP, Iv64, XX },
-  { "movS",		RMeBP, Iv64, XX },
-  { "movS",		RMeSI, Iv64, XX },
-  { "movS",		RMeDI, Iv64, XX },
-  /* c0 */
-  { GRP2b },
-  { GRP2S },
-  { "retT",		Iw, XX, XX },
-  { "retT",		XX, XX, XX },
-  { "les{S|}",		Gv, Mp, XX },
-  { "ldsS",		Gv, Mp, XX },
-  { "movA",		Eb, Ib, XX },
-  { "movQ",		Ev, Iv, XX },
-  /* c8 */
-  { "enterT",		Iw, Ib, XX },
-  { "leaveT",		XX, XX, XX },
-  { "lretP",		Iw, XX, XX },
-  { "lretP",		XX, XX, XX },
-  { "int3",		XX, XX, XX },
-  { "int",		Ib, XX, XX },
-  { "into{|}",		XX, XX, XX },
-  { "iretP",		XX, XX, XX },
-  /* d0 */
-  { GRP2b_one },
-  { GRP2S_one },
-  { GRP2b_cl },
-  { GRP2S_cl },
-  { "aam{|}",		sIb, XX, XX },
-  { "aad{|}",		sIb, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "xlat",		DSBX, XX, XX },
-  /* d8 */
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  { FLOAT },
-  /* e0 */
-  { "loopneFH",		Jb, XX, loop_jcxz_flag },
-  { "loopeFH",		Jb, XX, loop_jcxz_flag },
-  { "loopFH",		Jb, XX, loop_jcxz_flag },
-  { "jEcxzH",		Jb, XX, loop_jcxz_flag },
-  { "inB",		AL, Ib, XX },
-  { "inS",		eAX, Ib, XX },
-  { "outB",		Ib, AL, XX },
-  { "outS",		Ib, eAX, XX },
-  /* e8 */
-  { "callT",		Jv, XX, XX },
-  { "jmpT",		Jv, XX, XX },
-  { "Jjmp{T|}",		Ap, XX, XX },
-  { "jmp",		Jb, XX, XX },
-  { "inB",		AL, indirDX, XX },
-  { "inS",		eAX, indirDX, XX },
-  { "outB",		indirDX, AL, XX },
-  { "outS",		indirDX, eAX, XX },
-  /* f0 */
-  { "(bad)",		XX, XX, XX },	/* lock prefix */
-  { "icebp",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },	/* repne */
-  { "(bad)",		XX, XX, XX },	/* repz */
-  { "hlt",		XX, XX, XX },
-  { "cmc",		XX, XX, XX },
-  { GRP3b },
-  { GRP3S },
-  /* f8 */
-  { "clc",		XX, XX, XX },
-  { "stc",		XX, XX, XX },
-  { "cli",		XX, XX, XX },
-  { "sti",		XX, XX, XX },
-  { "cld",		XX, XX, XX },
-  { "std",		XX, XX, XX },
-  { GRP4 },
-  { GRP5 },
-};
-
-static const struct dis386 dis386_twobyte[] = {
-  /* 00 */
-  { GRP6 },
-  { GRP7 },
-  { "larS",		Gv, Ew, XX },
-  { "lslS",		Gv, Ew, XX },
-  { "(bad)",		XX, XX, XX },
-  { "syscall",		XX, XX, XX },
-  { "clts",		XX, XX, XX },
-  { "sysretP",		XX, XX, XX },
-  /* 08 */
-  { "invd",		XX, XX, XX },
-  { "wbinvd",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "ud2a",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { GRPAMD },
-  { "femms",		XX, XX, XX },
-  { "",			MX, EM, OPSUF }, /* See OP_3DNowSuffix.	 */
-  /* 10 */
-  { PREGRP8 },
-  { PREGRP9 },
-  { PREGRP30 },
-  { "movlpX",		EX, XM, SIMD_Fixup, 'h' },
-  { "unpcklpX",		XM, EX, XX },
-  { "unpckhpX",		XM, EX, XX },
-  { PREGRP31 },
-  { "movhpX",		EX, XM, SIMD_Fixup, 'l' },
-  /* 18 */
-  { GRP14 },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  /* 20 */
-  { "movL",		Rm, Cm, XX },
-  { "movL",		Rm, Dm, XX },
-  { "movL",		Cm, Rm, XX },
-  { "movL",		Dm, Rm, XX },
-  { "movL",		Rd, Td, XX },
-  { "(bad)",		XX, XX, XX },
-  { "movL",		Td, Rd, XX },
-  { "(bad)",		XX, XX, XX },
-  /* 28 */
-  { "movapX",		XM, EX, XX },
-  { "movapX",		EX, XM, XX },
-  { PREGRP2 },
-  { "movntpX",		Ev, XM, XX },
-  { PREGRP4 },
-  { PREGRP3 },
-  { "ucomisX",		XM,EX, XX },
-  { "comisX",		XM,EX, XX },
-  /* 30 */
-  { "wrmsr",		XX, XX, XX },
-  { "rdtsc",		XX, XX, XX },
-  { "rdmsr",		XX, XX, XX },
-  { "rdpmc",		XX, XX, XX },
-  { "sysenter",		XX, XX, XX },
-  { "sysexit",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  /* 38 */
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  /* 40 */
-  { "cmovo",		Gv, Ev, XX },
-  { "cmovno",		Gv, Ev, XX },
-  { "cmovb",		Gv, Ev, XX },
-  { "cmovae",		Gv, Ev, XX },
-  { "cmove",		Gv, Ev, XX },
-  { "cmovne",		Gv, Ev, XX },
-  { "cmovbe",		Gv, Ev, XX },
-  { "cmova",		Gv, Ev, XX },
-  /* 48 */
-  { "cmovs",		Gv, Ev, XX },
-  { "cmovns",		Gv, Ev, XX },
-  { "cmovp",		Gv, Ev, XX },
-  { "cmovnp",		Gv, Ev, XX },
-  { "cmovl",		Gv, Ev, XX },
-  { "cmovge",		Gv, Ev, XX },
-  { "cmovle",		Gv, Ev, XX },
-  { "cmovg",		Gv, Ev, XX },
-  /* 50 */
-  { "movmskpX",		Gdq, XS, XX },
-  { PREGRP13 },
-  { PREGRP12 },
-  { PREGRP11 },
-  { "andpX",		XM, EX, XX },
-  { "andnpX",		XM, EX, XX },
-  { "orpX",		XM, EX, XX },
-  { "xorpX",		XM, EX, XX },
-  /* 58 */
-  { PREGRP0 },
-  { PREGRP10 },
-  { PREGRP17 },
-  { PREGRP16 },
-  { PREGRP14 },
-  { PREGRP7 },
-  { PREGRP5 },
-  { PREGRP6 },
-  /* 60 */
-  { "punpcklbw",	MX, EM, XX },
-  { "punpcklwd",	MX, EM, XX },
-  { "punpckldq",	MX, EM, XX },
-  { "packsswb",		MX, EM, XX },
-  { "pcmpgtb",		MX, EM, XX },
-  { "pcmpgtw",		MX, EM, XX },
-  { "pcmpgtd",		MX, EM, XX },
-  { "packuswb",		MX, EM, XX },
-  /* 68 */
-  { "punpckhbw",	MX, EM, XX },
-  { "punpckhwd",	MX, EM, XX },
-  { "punpckhdq",	MX, EM, XX },
-  { "packssdw",		MX, EM, XX },
-  { PREGRP26 },
-  { PREGRP24 },
-  { "movd",		MX, Edq, XX },
-  { PREGRP19 },
-  /* 70 */
-  { PREGRP22 },
-  { GRP10 },
-  { GRP11 },
-  { GRP12 },
-  { "pcmpeqb",		MX, EM, XX },
-  { "pcmpeqw",		MX, EM, XX },
-  { "pcmpeqd",		MX, EM, XX },
-  { "emms",		XX, XX, XX },
-  /* 78 */
-  { "vmread",		Em, Gm, XX },
-  { "vmwrite",		Gm, Em, XX },
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
-  { PREGRP28 },
-  { PREGRP29 },
-  { PREGRP23 },
-  { PREGRP20 },
-  /* 80 */
-  { "joH",		Jv, XX, cond_jump_flag },
-  { "jnoH",		Jv, XX, cond_jump_flag },
-  { "jbH",		Jv, XX, cond_jump_flag },
-  { "jaeH",		Jv, XX, cond_jump_flag },
-  { "jeH",		Jv, XX, cond_jump_flag },
-  { "jneH",		Jv, XX, cond_jump_flag },
-  { "jbeH",		Jv, XX, cond_jump_flag },
-  { "jaH",		Jv, XX, cond_jump_flag },
-  /* 88 */
-  { "jsH",		Jv, XX, cond_jump_flag },
-  { "jnsH",		Jv, XX, cond_jump_flag },
-  { "jpH",		Jv, XX, cond_jump_flag },
-  { "jnpH",		Jv, XX, cond_jump_flag },
-  { "jlH",		Jv, XX, cond_jump_flag },
-  { "jgeH",		Jv, XX, cond_jump_flag },
-  { "jleH",		Jv, XX, cond_jump_flag },
-  { "jgH",		Jv, XX, cond_jump_flag },
-  /* 90 */
-  { "seto",		Eb, XX, XX },
-  { "setno",		Eb, XX, XX },
-  { "setb",		Eb, XX, XX },
-  { "setae",		Eb, XX, XX },
-  { "sete",		Eb, XX, XX },
-  { "setne",		Eb, XX, XX },
-  { "setbe",		Eb, XX, XX },
-  { "seta",		Eb, XX, XX },
-  /* 98 */
-  { "sets",		Eb, XX, XX },
-  { "setns",		Eb, XX, XX },
-  { "setp",		Eb, XX, XX },
-  { "setnp",		Eb, XX, XX },
-  { "setl",		Eb, XX, XX },
-  { "setge",		Eb, XX, XX },
-  { "setle",		Eb, XX, XX },
-  { "setg",		Eb, XX, XX },
-  /* a0 */
-  { "pushT",		fs, XX, XX },
-  { "popT",		fs, XX, XX },
-  { "cpuid",		XX, XX, XX },
-  { "btS",		Ev, Gv, XX },
-  { "shldS",		Ev, Gv, Ib },
-  { "shldS",		Ev, Gv, CL },
-  { GRPPADLCK2 },
-  { GRPPADLCK1 },
-  /* a8 */
-  { "pushT",		gs, XX, XX },
-  { "popT",		gs, XX, XX },
-  { "rsm",		XX, XX, XX },
-  { "btsS",		Ev, Gv, XX },
-  { "shrdS",		Ev, Gv, Ib },
-  { "shrdS",		Ev, Gv, CL },
-  { GRP13 },
-  { "imulS",		Gv, Ev, XX },
-  /* b0 */
-  { "cmpxchgB",		Eb, Gb, XX },
-  { "cmpxchgS",		Ev, Gv, XX },
-  { "lssS",		Gv, Mp, XX },
-  { "btrS",		Ev, Gv, XX },
-  { "lfsS",		Gv, Mp, XX },
-  { "lgsS",		Gv, Mp, XX },
-  { "movz{bR|x|bR|x}",	Gv, Eb, XX },
-  { "movz{wR|x|wR|x}",	Gv, Ew, XX }, /* yes, there really is movzww ! */
-  /* b8 */
-  { "(bad)",		XX, XX, XX },
-  { "ud2b",		XX, XX, XX },
-  { GRP8 },
-  { "btcS",		Ev, Gv, XX },
-  { "bsfS",		Gv, Ev, XX },
-  { "bsrS",		Gv, Ev, XX },
-  { "movs{bR|x|bR|x}",	Gv, Eb, XX },
-  { "movs{wR|x|wR|x}",	Gv, Ew, XX }, /* yes, there really is movsww ! */
-  /* c0 */
-  { "xaddB",		Eb, Gb, XX },
-  { "xaddS",		Ev, Gv, XX },
-  { PREGRP1 },
-  { "movntiS",		Ev, Gv, XX },
-  { "pinsrw",		MX, Edqw, Ib },
-  { "pextrw",		Gdq, MS, Ib },
-  { "shufpX",		XM, EX, Ib },
-  { GRP9 },
-  /* c8 */
-  { "bswap",		RMeAX, XX, XX },
-  { "bswap",		RMeCX, XX, XX },
-  { "bswap",		RMeDX, XX, XX },
-  { "bswap",		RMeBX, XX, XX },
-  { "bswap",		RMeSP, XX, XX },
-  { "bswap",		RMeBP, XX, XX },
-  { "bswap",		RMeSI, XX, XX },
-  { "bswap",		RMeDI, XX, XX },
-  /* d0 */
-  { PREGRP27 },
-  { "psrlw",		MX, EM, XX },
-  { "psrld",		MX, EM, XX },
-  { "psrlq",		MX, EM, XX },
-  { "paddq",		MX, EM, XX },
-  { "pmullw",		MX, EM, XX },
-  { PREGRP21 },
-  { "pmovmskb",		Gdq, MS, XX },
-  /* d8 */
-  { "psubusb",		MX, EM, XX },
-  { "psubusw",		MX, EM, XX },
-  { "pminub",		MX, EM, XX },
-  { "pand",		MX, EM, XX },
-  { "paddusb",		MX, EM, XX },
-  { "paddusw",		MX, EM, XX },
-  { "pmaxub",		MX, EM, XX },
-  { "pandn",		MX, EM, XX },
-  /* e0 */
-  { "pavgb",		MX, EM, XX },
-  { "psraw",		MX, EM, XX },
-  { "psrad",		MX, EM, XX },
-  { "pavgw",		MX, EM, XX },
-  { "pmulhuw",		MX, EM, XX },
-  { "pmulhw",		MX, EM, XX },
-  { PREGRP15 },
-  { PREGRP25 },
-  /* e8 */
-  { "psubsb",		MX, EM, XX },
-  { "psubsw",		MX, EM, XX },
-  { "pminsw",		MX, EM, XX },
-  { "por",		MX, EM, XX },
-  { "paddsb",		MX, EM, XX },
-  { "paddsw",		MX, EM, XX },
-  { "pmaxsw",		MX, EM, XX },
-  { "pxor",		MX, EM, XX },
-  /* f0 */
-  { PREGRP32 },
-  { "psllw",		MX, EM, XX },
-  { "pslld",		MX, EM, XX },
-  { "psllq",		MX, EM, XX },
-  { "pmuludq",		MX, EM, XX },
-  { "pmaddwd",		MX, EM, XX },
-  { "psadbw",		MX, EM, XX },
-  { PREGRP18 },
-  /* f8 */
-  { "psubb",		MX, EM, XX },
-  { "psubw",		MX, EM, XX },
-  { "psubd",		MX, EM, XX },
-  { "psubq",		MX, EM, XX },
-  { "paddb",		MX, EM, XX },
-  { "paddw",		MX, EM, XX },
-  { "paddd",		MX, EM, XX },
-  { "(bad)",		XX, XX, XX }
-};
-
-static const unsigned char onebyte_has_modrm[256] = {
-  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
-  /*	   -------------------------------	  */
-  /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
-  /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
-  /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
-  /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
-  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
-  /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
-  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
-  /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
-  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
-  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
-  /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
-  /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
-  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
-  /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
-  /*	   -------------------------------	  */
-  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
-};
-
-static const unsigned char twobyte_has_modrm[256] = {
-  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
-  /*	   -------------------------------	  */
-  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
-  /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
-  /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
-  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
-  /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
-  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
-  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
-  /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
-  /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
-  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
-  /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
-  /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
-  /*	   -------------------------------	  */
-  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
-};
-
-static const unsigned char twobyte_uses_SSE_prefix[256] = {
-  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
-  /*	   -------------------------------	  */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
-  /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
-  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
-  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
-  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0  /* ff */
-  /*	   -------------------------------	  */
-  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
-};
-
-static char obuf[100];
-static char *obufp;
-static char scratchbuf[100];
-static unsigned char *start_codep;
-static unsigned char *insn_codep;
-static unsigned char *codep;
-static disassemble_info *the_info;
-static int mod;
-static int rm;
-static int reg;
-static unsigned char need_modrm;
-
-/* If we are accessing mod/rm/reg without need_modrm set, then the
-   values are stale.  Hitting this abort likely indicates that you
-   need to update onebyte_has_modrm or twobyte_has_modrm.  */
-#define MODRM_CHECK  if (!need_modrm) abort ()
-
-static const char **names64;
-static const char **names32;
-static const char **names16;
-static const char **names8;
-static const char **names8rex;
-static const char **names_seg;
-static const char **index16;
-
-static const char *intel_names64[] = {
-  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
-  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
-};
-static const char *intel_names32[] = {
-  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
-  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
-};
-static const char *intel_names16[] = {
-  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
-  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
-};
-static const char *intel_names8[] = {
-  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
-};
-static const char *intel_names8rex[] = {
-  "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
-  "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
-};
-static const char *intel_names_seg[] = {
-  "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
-};
-static const char *intel_index16[] = {
-  "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
-};
-
-static const char *att_names64[] = {
-  "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
-  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
-};
-static const char *att_names32[] = {
-  "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
-  "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
-};
-static const char *att_names16[] = {
-  "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
-  "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
-};
-static const char *att_names8[] = {
-  "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
-};
-static const char *att_names8rex[] = {
-  "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
-  "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
-};
-static const char *att_names_seg[] = {
-  "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
-};
-static const char *att_index16[] = {
-  "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
-};
-
-static const struct dis386 grps[][8] = {
-  /* GRP1b */
-  {
-    { "addA",	Eb, Ib, XX },
-    { "orA",	Eb, Ib, XX },
-    { "adcA",	Eb, Ib, XX },
-    { "sbbA",	Eb, Ib, XX },
-    { "andA",	Eb, Ib, XX },
-    { "subA",	Eb, Ib, XX },
-    { "xorA",	Eb, Ib, XX },
-    { "cmpA",	Eb, Ib, XX }
-  },
-  /* GRP1S */
-  {
-    { "addQ",	Ev, Iv, XX },
-    { "orQ",	Ev, Iv, XX },
-    { "adcQ",	Ev, Iv, XX },
-    { "sbbQ",	Ev, Iv, XX },
-    { "andQ",	Ev, Iv, XX },
-    { "subQ",	Ev, Iv, XX },
-    { "xorQ",	Ev, Iv, XX },
-    { "cmpQ",	Ev, Iv, XX }
-  },
-  /* GRP1Ss */
-  {
-    { "addQ",	Ev, sIb, XX },
-    { "orQ",	Ev, sIb, XX },
-    { "adcQ",	Ev, sIb, XX },
-    { "sbbQ",	Ev, sIb, XX },
-    { "andQ",	Ev, sIb, XX },
-    { "subQ",	Ev, sIb, XX },
-    { "xorQ",	Ev, sIb, XX },
-    { "cmpQ",	Ev, sIb, XX }
-  },
-  /* GRP2b */
-  {
-    { "rolA",	Eb, Ib, XX },
-    { "rorA",	Eb, Ib, XX },
-    { "rclA",	Eb, Ib, XX },
-    { "rcrA",	Eb, Ib, XX },
-    { "shlA",	Eb, Ib, XX },
-    { "shrA",	Eb, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarA",	Eb, Ib, XX },
-  },
-  /* GRP2S */
-  {
-    { "rolQ",	Ev, Ib, XX },
-    { "rorQ",	Ev, Ib, XX },
-    { "rclQ",	Ev, Ib, XX },
-    { "rcrQ",	Ev, Ib, XX },
-    { "shlQ",	Ev, Ib, XX },
-    { "shrQ",	Ev, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarQ",	Ev, Ib, XX },
-  },
-  /* GRP2b_one */
-  {
-    { "rolA",	Eb, I1, XX },
-    { "rorA",	Eb, I1, XX },
-    { "rclA",	Eb, I1, XX },
-    { "rcrA",	Eb, I1, XX },
-    { "shlA",	Eb, I1, XX },
-    { "shrA",	Eb, I1, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarA",	Eb, I1, XX },
-  },
-  /* GRP2S_one */
-  {
-    { "rolQ",	Ev, I1, XX },
-    { "rorQ",	Ev, I1, XX },
-    { "rclQ",	Ev, I1, XX },
-    { "rcrQ",	Ev, I1, XX },
-    { "shlQ",	Ev, I1, XX },
-    { "shrQ",	Ev, I1, XX },
-    { "(bad)",	XX, XX, XX},
-    { "sarQ",	Ev, I1, XX },
-  },
-  /* GRP2b_cl */
-  {
-    { "rolA",	Eb, CL, XX },
-    { "rorA",	Eb, CL, XX },
-    { "rclA",	Eb, CL, XX },
-    { "rcrA",	Eb, CL, XX },
-    { "shlA",	Eb, CL, XX },
-    { "shrA",	Eb, CL, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarA",	Eb, CL, XX },
-  },
-  /* GRP2S_cl */
-  {
-    { "rolQ",	Ev, CL, XX },
-    { "rorQ",	Ev, CL, XX },
-    { "rclQ",	Ev, CL, XX },
-    { "rcrQ",	Ev, CL, XX },
-    { "shlQ",	Ev, CL, XX },
-    { "shrQ",	Ev, CL, XX },
-    { "(bad)",	XX, XX, XX },
-    { "sarQ",	Ev, CL, XX }
-  },
-  /* GRP3b */
-  {
-    { "testA",	Eb, Ib, XX },
-    { "(bad)",	Eb, XX, XX },
-    { "notA",	Eb, XX, XX },
-    { "negA",	Eb, XX, XX },
-    { "mulA",	Eb, XX, XX },	/* Don't print the implicit %al register,  */
-    { "imulA",	Eb, XX, XX },	/* to distinguish these opcodes from other */
-    { "divA",	Eb, XX, XX },	/* mul/imul opcodes.  Do the same for div  */
-    { "idivA",	Eb, XX, XX }	/* and idiv for consistency.		   */
-  },
-  /* GRP3S */
-  {
-    { "testQ",	Ev, Iv, XX },
-    { "(bad)",	XX, XX, XX },
-    { "notQ",	Ev, XX, XX },
-    { "negQ",	Ev, XX, XX },
-    { "mulQ",	Ev, XX, XX },	/* Don't print the implicit register.  */
-    { "imulQ",	Ev, XX, XX },
-    { "divQ",	Ev, XX, XX },
-    { "idivQ",	Ev, XX, XX },
-  },
-  /* GRP4 */
-  {
-    { "incA",	Eb, XX, XX },
-    { "decA",	Eb, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRP5 */
-  {
-    { "incQ",	Ev, XX, XX },
-    { "decQ",	Ev, XX, XX },
-    { "callT",	indirEv, XX, XX },
-    { "JcallT", indirEp, XX, XX },
-    { "jmpT",	indirEv, XX, XX },
-    { "JjmpT",	indirEp, XX, XX },
-    { "pushU",	Ev, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRP6 */
-  {
-    { "sldtQ",	Ev, XX, XX },
-    { "strQ",	Ev, XX, XX },
-    { "lldt",	Ew, XX, XX },
-    { "ltr",	Ew, XX, XX },
-    { "verr",	Ew, XX, XX },
-    { "verw",	Ew, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX }
-  },
-  /* GRP7 */
-  {
-    { "sgdtIQ", VMX_Fixup, 0, XX, XX },
-    { "sidtIQ", PNI_Fixup, 0, XX, XX },
-    { "lgdt{Q|Q||}",	 M, XX, XX },
-    { "lidt{Q|Q||}",	 SVME_Fixup, 0, XX, XX },
-    { "smswQ",	Ev, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "lmsw",	Ew, XX, XX },
-    { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
-  },
-  /* GRP8 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "btQ",	Ev, Ib, XX },
-    { "btsQ",	Ev, Ib, XX },
-    { "btrQ",	Ev, Ib, XX },
-    { "btcQ",	Ev, Ib, XX },
-  },
-  /* GRP9 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "cmpxchg8b", Eq, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "",	VM, XX, XX },		/* See OP_VMX.	*/
-    { "vmptrst", Eq, XX, XX },
-  },
-  /* GRP10 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psrlw",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psraw",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psllw",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRP11 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psrld",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psrad",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "pslld",	MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRP12 */
-  {
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psrlq",	MS, Ib, XX },
-    { "psrldq", MS, Ib, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "psllq",	MS, Ib, XX },
-    { "pslldq", MS, Ib, XX },
-  },
-  /* GRP13 */
-  {
-    { "fxsave", Ev, XX, XX },
-    { "fxrstor", Ev, XX, XX },
-    { "ldmxcsr", Ev, XX, XX },
-    { "stmxcsr", Ev, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "lfence", OP_0fae, 0, XX, XX },
-    { "mfence", OP_0fae, 0, XX, XX },
-    { "clflush", OP_0fae, 0, XX, XX },
-  },
-  /* GRP14 */
-  {
-    { "prefetchnta", Ev, XX, XX },
-    { "prefetcht0", Ev, XX, XX },
-    { "prefetcht1", Ev, XX, XX },
-    { "prefetcht2", Ev, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRPAMD */
-  {
-    { "prefetch", Eb, XX, XX },
-    { "prefetchw", Eb, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* GRPPADLCK1 */
-  {
-    { "xstore-rng", OP_0f07, 0, XX, XX },
-    { "xcrypt-ecb", OP_0f07, 0, XX, XX },
-    { "xcrypt-cbc", OP_0f07, 0, XX, XX },
-    { "xcrypt-ctr", OP_0f07, 0, XX, XX },
-    { "xcrypt-cfb", OP_0f07, 0, XX, XX },
-    { "xcrypt-ofb", OP_0f07, 0, XX, XX },
-    { "(bad)",	OP_0f07, 0, XX, XX },
-    { "(bad)",	OP_0f07, 0, XX, XX },
-  },
-  /* GRPPADLCK2 */
-  {
-    { "montmul", OP_0f07, 0, XX, XX },
-    { "xsha1",	 OP_0f07, 0, XX, XX },
-    { "xsha256", OP_0f07, 0, XX, XX },
-    { "(bad)",	 OP_0f07, 0, XX, XX },
-    { "(bad)",	 OP_0f07, 0, XX, XX },
-    { "(bad)",	 OP_0f07, 0, XX, XX },
-    { "(bad)",	 OP_0f07, 0, XX, XX },
-    { "(bad)",	 OP_0f07, 0, XX, XX },
-  }
-};
-
-static const struct dis386 prefix_user_table[][4] = {
-  /* PREGRP0 */
-  {
-    { "addps", XM, EX, XX },
-    { "addss", XM, EX, XX },
-    { "addpd", XM, EX, XX },
-    { "addsd", XM, EX, XX },
-  },
-  /* PREGRP1 */
-  {
-    { "", XM, EX, OPSIMD },	/* See OP_SIMD_SUFFIX.	*/
-    { "", XM, EX, OPSIMD },
-    { "", XM, EX, OPSIMD },
-    { "", XM, EX, OPSIMD },
-  },
-  /* PREGRP2 */
-  {
-    { "cvtpi2ps", XM, EM, XX },
-    { "cvtsi2ssY", XM, Ev, XX },
-    { "cvtpi2pd", XM, EM, XX },
-    { "cvtsi2sdY", XM, Ev, XX },
-  },
-  /* PREGRP3 */
-  {
-    { "cvtps2pi", MX, EX, XX },
-    { "cvtss2siY", Gv, EX, XX },
-    { "cvtpd2pi", MX, EX, XX },
-    { "cvtsd2siY", Gv, EX, XX },
-  },
-  /* PREGRP4 */
-  {
-    { "cvttps2pi", MX, EX, XX },
-    { "cvttss2siY", Gv, EX, XX },
-    { "cvttpd2pi", MX, EX, XX },
-    { "cvttsd2siY", Gv, EX, XX },
-  },
-  /* PREGRP5 */
-  {
-    { "divps", XM, EX, XX },
-    { "divss", XM, EX, XX },
-    { "divpd", XM, EX, XX },
-    { "divsd", XM, EX, XX },
-  },
-  /* PREGRP6 */
-  {
-    { "maxps", XM, EX, XX },
-    { "maxss", XM, EX, XX },
-    { "maxpd", XM, EX, XX },
-    { "maxsd", XM, EX, XX },
-  },
-  /* PREGRP7 */
-  {
-    { "minps", XM, EX, XX },
-    { "minss", XM, EX, XX },
-    { "minpd", XM, EX, XX },
-    { "minsd", XM, EX, XX },
-  },
-  /* PREGRP8 */
-  {
-    { "movups", XM, EX, XX },
-    { "movss", XM, EX, XX },
-    { "movupd", XM, EX, XX },
-    { "movsd", XM, EX, XX },
-  },
-  /* PREGRP9 */
-  {
-    { "movups", EX, XM, XX },
-    { "movss", EX, XM, XX },
-    { "movupd", EX, XM, XX },
-    { "movsd", EX, XM, XX },
-  },
-  /* PREGRP10 */
-  {
-    { "mulps", XM, EX, XX },
-    { "mulss", XM, EX, XX },
-    { "mulpd", XM, EX, XX },
-    { "mulsd", XM, EX, XX },
-  },
-  /* PREGRP11 */
-  {
-    { "rcpps", XM, EX, XX },
-    { "rcpss", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP12 */
-  {
-    { "rsqrtps", XM, EX, XX },
-    { "rsqrtss", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP13 */
-  {
-    { "sqrtps", XM, EX, XX },
-    { "sqrtss", XM, EX, XX },
-    { "sqrtpd", XM, EX, XX },
-    { "sqrtsd", XM, EX, XX },
-  },
-  /* PREGRP14 */
-  {
-    { "subps", XM, EX, XX },
-    { "subss", XM, EX, XX },
-    { "subpd", XM, EX, XX },
-    { "subsd", XM, EX, XX },
-  },
-  /* PREGRP15 */
-  {
-    { "(bad)", XM, EX, XX },
-    { "cvtdq2pd", XM, EX, XX },
-    { "cvttpd2dq", XM, EX, XX },
-    { "cvtpd2dq", XM, EX, XX },
-  },
-  /* PREGRP16 */
-  {
-    { "cvtdq2ps", XM, EX, XX },
-    { "cvttps2dq",XM, EX, XX },
-    { "cvtps2dq",XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP17 */
-  {
-    { "cvtps2pd", XM, EX, XX },
-    { "cvtss2sd", XM, EX, XX },
-    { "cvtpd2ps", XM, EX, XX },
-    { "cvtsd2ss", XM, EX, XX },
-  },
-  /* PREGRP18 */
-  {
-    { "maskmovq", MX, MS, XX },
-    { "(bad)", XM, EX, XX },
-    { "maskmovdqu", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP19 */
-  {
-    { "movq", MX, EM, XX },
-    { "movdqu", XM, EX, XX },
-    { "movdqa", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP20 */
-  {
-    { "movq", EM, MX, XX },
-    { "movdqu", EX, XM, XX },
-    { "movdqa", EX, XM, XX },
-    { "(bad)", EX, XM, XX },
-  },
-  /* PREGRP21 */
-  {
-    { "(bad)", EX, XM, XX },
-    { "movq2dq", XM, MS, XX },
-    { "movq", EX, XM, XX },
-    { "movdq2q", MX, XS, XX },
-  },
-  /* PREGRP22 */
-  {
-    { "pshufw", MX, EM, Ib },
-    { "pshufhw", XM, EX, Ib },
-    { "pshufd", XM, EX, Ib },
-    { "pshuflw", XM, EX, Ib },
-  },
-  /* PREGRP23 */
-  {
-    { "movd", Edq, MX, XX },
-    { "movq", XM, EX, XX },
-    { "movd", Edq, XM, XX },
-    { "(bad)", Ed, XM, XX },
-  },
-  /* PREGRP24 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "punpckhqdq", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP25 */
-  {
-    { "movntq", EM, MX, XX },
-    { "(bad)", EM, XM, XX },
-    { "movntdq", EM, XM, XX },
-    { "(bad)", EM, XM, XX },
-  },
-  /* PREGRP26 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "punpcklqdq", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP27 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "addsubpd", XM, EX, XX },
-    { "addsubps", XM, EX, XX },
-  },
-  /* PREGRP28 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "haddpd", XM, EX, XX },
-    { "haddps", XM, EX, XX },
-  },
-  /* PREGRP29 */
-  {
-    { "(bad)", MX, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "hsubpd", XM, EX, XX },
-    { "hsubps", XM, EX, XX },
-  },
-  /* PREGRP30 */
-  {
-    { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
-    { "movsldup", XM, EX, XX },
-    { "movlpd", XM, EX, XX },
-    { "movddup", XM, EX, XX },
-  },
-  /* PREGRP31 */
-  {
-    { "movhpX", XM, EX, SIMD_Fixup, 'l' },
-    { "movshdup", XM, EX, XX },
-    { "movhpd", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-  },
-  /* PREGRP32 */
-  {
-    { "(bad)", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "(bad)", XM, EX, XX },
-    { "lddqu", XM, M, XX },
-  },
-};
-
-static const struct dis386 x86_64_table[][2] = {
-  {
-    { "arpl", Ew, Gw, XX },
-    { "movs{||lq|xd}", Gv, Ed, XX },
-  },
-};
-
-#ifdef	__KERNEL__
-#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>"
-#else	/* __KERNEL__ */
-#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
-#endif	/* __KERNEL__ */
-
-static void
-ckprefix (void)
-{
-  int newrex;
-  rex = 0;
-  prefixes = 0;
-  used_prefixes = 0;
-  rex_used = 0;
-  while (1)
-    {
-      FETCH_DATA (the_info, codep + 1);
-      newrex = 0;
-      switch (*codep)
-	{
-	/* REX prefixes family.	 */
-	case 0x40:
-	case 0x41:
-	case 0x42:
-	case 0x43:
-	case 0x44:
-	case 0x45:
-	case 0x46:
-	case 0x47:
-	case 0x48:
-	case 0x49:
-	case 0x4a:
-	case 0x4b:
-	case 0x4c:
-	case 0x4d:
-	case 0x4e:
-	case 0x4f:
-	    if (mode_64bit)
-	      newrex = *codep;
-	    else
-	      return;
-	  break;
-	case 0xf3:
-	  prefixes |= PREFIX_REPZ;
-	  break;
-	case 0xf2:
-	  prefixes |= PREFIX_REPNZ;
-	  break;
-	case 0xf0:
-	  prefixes |= PREFIX_LOCK;
-	  break;
-	case 0x2e:
-	  prefixes |= PREFIX_CS;
-	  break;
-	case 0x36:
-	  prefixes |= PREFIX_SS;
-	  break;
-	case 0x3e:
-	  prefixes |= PREFIX_DS;
-	  break;
-	case 0x26:
-	  prefixes |= PREFIX_ES;
-	  break;
-	case 0x64:
-	  prefixes |= PREFIX_FS;
-	  break;
-	case 0x65:
-	  prefixes |= PREFIX_GS;
-	  break;
-	case 0x66:
-	  prefixes |= PREFIX_DATA;
-	  break;
-	case 0x67:
-	  prefixes |= PREFIX_ADDR;
-	  break;
-	case FWAIT_OPCODE:
-	  /* fwait is really an instruction.  If there are prefixes
-	     before the fwait, they belong to the fwait, *not* to the
-	     following instruction.  */
-	  if (prefixes)
-	    {
-	      prefixes |= PREFIX_FWAIT;
-	      codep++;
-	      return;
-	    }
-	  prefixes = PREFIX_FWAIT;
-	  break;
-	default:
-	  return;
-	}
-      /* Rex is ignored when followed by another prefix.  */
-      if (rex)
-	{
-	  oappend (prefix_name (rex, 0));
-	  oappend (" ");
-	}
-      rex = newrex;
-      codep++;
-    }
-}
-
-/* Return the name of the prefix byte PREF, or NULL if PREF is not a
-   prefix byte.	 */
-
-static const char *
-prefix_name (int pref, int sizeflag)
-{
-  switch (pref)
-    {
-    /* REX prefixes family.  */
-    case 0x40:
-      return "rex";
-    case 0x41:
-      return "rexZ";
-    case 0x42:
-      return "rexY";
-    case 0x43:
-      return "rexYZ";
-    case 0x44:
-      return "rexX";
-    case 0x45:
-      return "rexXZ";
-    case 0x46:
-      return "rexXY";
-    case 0x47:
-      return "rexXYZ";
-    case 0x48:
-      return "rex64";
-    case 0x49:
-      return "rex64Z";
-    case 0x4a:
-      return "rex64Y";
-    case 0x4b:
-      return "rex64YZ";
-    case 0x4c:
-      return "rex64X";
-    case 0x4d:
-      return "rex64XZ";
-    case 0x4e:
-      return "rex64XY";
-    case 0x4f:
-      return "rex64XYZ";
-    case 0xf3:
-      return "repz";
-    case 0xf2:
-      return "repnz";
-    case 0xf0:
-      return "lock";
-    case 0x2e:
-      return "cs";
-    case 0x36:
-      return "ss";
-    case 0x3e:
-      return "ds";
-    case 0x26:
-      return "es";
-    case 0x64:
-      return "fs";
-    case 0x65:
-      return "gs";
-    case 0x66:
-      return (sizeflag & DFLAG) ? "data16" : "data32";
-    case 0x67:
-      if (mode_64bit)
-	return (sizeflag & AFLAG) ? "addr32" : "addr64";
-      else
-	return (sizeflag & AFLAG) ? "addr16" : "addr32";
-    case FWAIT_OPCODE:
-      return "fwait";
-    default:
-      return NULL;
-    }
-}
-
-static char op1out[100], op2out[100], op3out[100];
-static int op_ad, op_index[3];
-static int two_source_ops;
-static bfd_vma op_address[3];
-static bfd_vma op_riprel[3];
-static bfd_vma start_pc;
-
-/*
- *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
- *   (see topic "Redundant prefixes" in the "Differences from 8086"
- *   section of the "Virtual 8086 Mode" chapter.)
- * 'pc' should be the address of this instruction, it will
- *   be used to print the target address if this is a relative jump or call
- * The function returns the length of this instruction in bytes.
- */
-
-static char intel_syntax;
-static char open_char;
-static char close_char;
-static char separator_char;
-static char scale_char;
-
-/* Here for backwards compatibility.  When gdb stops using
-   print_insn_i386_att and print_insn_i386_intel these functions can
-   disappear, and print_insn_i386 be merged into print_insn.  */
-int
-print_insn_i386_att (bfd_vma pc, disassemble_info *info)
-{
-  intel_syntax = 0;
-
-  return print_insn (pc, info);
-}
-
-int
-print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
-{
-  intel_syntax = 1;
-
-  return print_insn (pc, info);
-}
-
-int
-print_insn_i386 (bfd_vma pc, disassemble_info *info)
-{
-  intel_syntax = -1;
-
-  return print_insn (pc, info);
-}
-
-static int
-print_insn (bfd_vma pc, disassemble_info *info)
-{
-  const struct dis386 *dp;
-  int i;
-  char *first, *second, *third;
-  int needcomma;
-  unsigned char uses_SSE_prefix, uses_LOCK_prefix;
-  int sizeflag;
-  const char *p;
-  struct dis_private priv;
-
-  mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
-		|| info->mach == bfd_mach_x86_64);
-
-  if (intel_syntax == (char) -1)
-    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
-		    || info->mach == bfd_mach_x86_64_intel_syntax);
-
-  if (info->mach == bfd_mach_i386_i386
-      || info->mach == bfd_mach_x86_64
-      || info->mach == bfd_mach_i386_i386_intel_syntax
-      || info->mach == bfd_mach_x86_64_intel_syntax)
-    priv.orig_sizeflag = AFLAG | DFLAG;
-  else if (info->mach == bfd_mach_i386_i8086)
-    priv.orig_sizeflag = 0;
-  else
-    abort ();
-
-  for (p = info->disassembler_options; p != NULL; )
-    {
-      if (strncmp (p, "x86-64", 6) == 0)
-	{
-	  mode_64bit = 1;
-	  priv.orig_sizeflag = AFLAG | DFLAG;
-	}
-      else if (strncmp (p, "i386", 4) == 0)
-	{
-	  mode_64bit = 0;
-	  priv.orig_sizeflag = AFLAG | DFLAG;
-	}
-      else if (strncmp (p, "i8086", 5) == 0)
-	{
-	  mode_64bit = 0;
-	  priv.orig_sizeflag = 0;
-	}
-      else if (strncmp (p, "intel", 5) == 0)
-	{
-	  intel_syntax = 1;
-	}
-      else if (strncmp (p, "att", 3) == 0)
-	{
-	  intel_syntax = 0;
-	}
-      else if (strncmp (p, "addr", 4) == 0)
-	{
-	  if (p[4] == '1' && p[5] == '6')
-	    priv.orig_sizeflag &= ~AFLAG;
-	  else if (p[4] == '3' && p[5] == '2')
-	    priv.orig_sizeflag |= AFLAG;
-	}
-      else if (strncmp (p, "data", 4) == 0)
-	{
-	  if (p[4] == '1' && p[5] == '6')
-	    priv.orig_sizeflag &= ~DFLAG;
-	  else if (p[4] == '3' && p[5] == '2')
-	    priv.orig_sizeflag |= DFLAG;
-	}
-      else if (strncmp (p, "suffix", 6) == 0)
-	priv.orig_sizeflag |= SUFFIX_ALWAYS;
-
-      p = strchr (p, ',');
-      if (p != NULL)
-	p++;
-    }
-
-  if (intel_syntax)
-    {
-      names64 = intel_names64;
-      names32 = intel_names32;
-      names16 = intel_names16;
-      names8 = intel_names8;
-      names8rex = intel_names8rex;
-      names_seg = intel_names_seg;
-      index16 = intel_index16;
-      open_char = '[';
-      close_char = ']';
-      separator_char = '+';
-      scale_char = '*';
-    }
-  else
-    {
-      names64 = att_names64;
-      names32 = att_names32;
-      names16 = att_names16;
-      names8 = att_names8;
-      names8rex = att_names8rex;
-      names_seg = att_names_seg;
-      index16 = att_index16;
-      open_char = '(';
-      close_char =  ')';
-      separator_char = ',';
-      scale_char = ',';
-    }
-
-  /* The output looks better if we put 7 bytes on a line, since that
-     puts most long word instructions on a single line.	 */
-  info->bytes_per_line = 7;
-
-  info->private_data = &priv;
-  priv.max_fetched = priv.the_buffer;
-  priv.insn_start = pc;
-
-  obuf[0] = 0;
-  op1out[0] = 0;
-  op2out[0] = 0;
-  op3out[0] = 0;
-
-  op_index[0] = op_index[1] = op_index[2] = -1;
-
-  the_info = info;
-  start_pc = pc;
-  start_codep = priv.the_buffer;
-  codep = priv.the_buffer;
-
-#ifndef __KERNEL__
-  if (setjmp (priv.bailout) != 0)
-    {
-      const char *name;
-
-      /* Getting here means we tried for data but didn't get it.  That
-	 means we have an incomplete instruction of some sort.	Just
-	 print the first byte as a prefix or a .byte pseudo-op.	 */
-      if (codep > priv.the_buffer)
-	{
-	  name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
-	  if (name != NULL)
-	    (*info->fprintf_func) (info->stream, "%s", name);
-	  else
-	    {
-	      /* Just print the first byte as a .byte instruction.  */
-	      (*info->fprintf_func) (info->stream, ".byte 0x%x",
-				     (unsigned int) priv.the_buffer[0]);
-	    }
-
-	  return 1;
-	}
-
-      return -1;
-    }
-#endif	/* __KERNEL__ */
-
-  obufp = obuf;
-  ckprefix ();
-
-  insn_codep = codep;
-  sizeflag = priv.orig_sizeflag;
-
-  FETCH_DATA (info, codep + 1);
-  two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
-
-  if ((prefixes & PREFIX_FWAIT)
-      && ((*codep < 0xd8) || (*codep > 0xdf)))
-    {
-      const char *name;
-
-      /* fwait not followed by floating point instruction.  Print the
-	 first prefix, which is probably fwait itself.	*/
-      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
-      if (name == NULL)
-	name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s", name);
-      return 1;
-    }
-
-  if (*codep == 0x0f)
-    {
-      FETCH_DATA (info, codep + 2);
-      dp = &dis386_twobyte[*++codep];
-      need_modrm = twobyte_has_modrm[*codep];
-      uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
-      uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
-    }
-  else
-    {
-      dp = &dis386[*codep];
-      need_modrm = onebyte_has_modrm[*codep];
-      uses_SSE_prefix = 0;
-      uses_LOCK_prefix = 0;
-    }
-  codep++;
-
-  if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
-    {
-      oappend ("repz ");
-      used_prefixes |= PREFIX_REPZ;
-    }
-  if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
-    {
-      oappend ("repnz ");
-      used_prefixes |= PREFIX_REPNZ;
-    }
-  if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
-    {
-      oappend ("lock ");
-      used_prefixes |= PREFIX_LOCK;
-    }
-
-  if (prefixes & PREFIX_ADDR)
-    {
-      sizeflag ^= AFLAG;
-      if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
-	{
-	  if ((sizeflag & AFLAG) || mode_64bit)
-	    oappend ("addr32 ");
-	  else
-	    oappend ("addr16 ");
-	  used_prefixes |= PREFIX_ADDR;
-	}
-    }
-
-  if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
-    {
-      sizeflag ^= DFLAG;
-      if (dp->bytemode3 == cond_jump_mode
-	  && dp->bytemode1 == v_mode
-	  && !intel_syntax)
-	{
-	  if (sizeflag & DFLAG)
-	    oappend ("data32 ");
-	  else
-	    oappend ("data16 ");
-	  used_prefixes |= PREFIX_DATA;
-	}
-    }
-
-  if (need_modrm)
-    {
-      FETCH_DATA (info, codep + 1);
-      mod = (*codep >> 6) & 3;
-      reg = (*codep >> 3) & 7;
-      rm = *codep & 7;
-    }
-
-  if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
-    {
-      dofloat (sizeflag);
-    }
-  else
-    {
-      int index;
-      if (dp->name == NULL)
-	{
-	  switch (dp->bytemode1)
-	    {
-	    case USE_GROUPS:
-	      dp = &grps[dp->bytemode2][reg];
-	      break;
-
-	    case USE_PREFIX_USER_TABLE:
-	      index = 0;
-	      used_prefixes |= (prefixes & PREFIX_REPZ);
-	      if (prefixes & PREFIX_REPZ)
-		index = 1;
-	      else
-		{
-		  used_prefixes |= (prefixes & PREFIX_DATA);
-		  if (prefixes & PREFIX_DATA)
-		    index = 2;
-		  else
-		    {
-		      used_prefixes |= (prefixes & PREFIX_REPNZ);
-		      if (prefixes & PREFIX_REPNZ)
-			index = 3;
-		    }
-		}
-	      dp = &prefix_user_table[dp->bytemode2][index];
-	      break;
-
-	    case X86_64_SPECIAL:
-	      dp = &x86_64_table[dp->bytemode2][mode_64bit];
-	      break;
-
-	    default:
-	      oappend (INTERNAL_DISASSEMBLER_ERROR);
-	      break;
-	    }
-	}
-
-      if (putop (dp->name, sizeflag) == 0)
-	{
-	  obufp = op1out;
-	  op_ad = 2;
-	  if (dp->op1)
-	    (*dp->op1) (dp->bytemode1, sizeflag);
-
-	  obufp = op2out;
-	  op_ad = 1;
-	  if (dp->op2)
-	    (*dp->op2) (dp->bytemode2, sizeflag);
-
-	  obufp = op3out;
-	  op_ad = 0;
-	  if (dp->op3)
-	    (*dp->op3) (dp->bytemode3, sizeflag);
-	}
-    }
-
-  /* See if any prefixes were not used.	 If so, print the first one
-     separately.  If we don't do this, we'll wind up printing an
-     instruction stream which does not precisely correspond to the
-     bytes we are disassembling.  */
-  if ((prefixes & ~used_prefixes) != 0)
-    {
-      const char *name;
-
-      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
-      if (name == NULL)
-	name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s", name);
-      return 1;
-    }
-  if (rex & ~rex_used)
-    {
-      const char *name;
-      name = prefix_name (rex | 0x40, priv.orig_sizeflag);
-      if (name == NULL)
-	name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s ", name);
-    }
-
-  obufp = obuf + strlen (obuf);
-  for (i = strlen (obuf); i < 6; i++)
-    oappend (" ");
-  oappend (" ");
-  (*info->fprintf_func) (info->stream, "%s", obuf);
-
-  /* The enter and bound instructions are printed with operands in the same
-     order as the intel book; everything else is printed in reverse order.  */
-  if (intel_syntax || two_source_ops)
-    {
-      first = op1out;
-      second = op2out;
-      third = op3out;
-      op_ad = op_index[0];
-      op_index[0] = op_index[2];
-      op_index[2] = op_ad;
-    }
-  else
-    {
-      first = op3out;
-      second = op2out;
-      third = op1out;
-    }
-  needcomma = 0;
-  if (*first)
-    {
-      if (op_index[0] != -1 && !op_riprel[0])
-	(*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
-      else
-	(*info->fprintf_func) (info->stream, "%s", first);
-      needcomma = 1;
-    }
-  if (*second)
-    {
-      if (needcomma)
-	(*info->fprintf_func) (info->stream, ",");
-      if (op_index[1] != -1 && !op_riprel[1])
-	(*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
-      else
-	(*info->fprintf_func) (info->stream, "%s", second);
-      needcomma = 1;
-    }
-  if (*third)
-    {
-      if (needcomma)
-	(*info->fprintf_func) (info->stream, ",");
-      if (op_index[2] != -1 && !op_riprel[2])
-	(*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
-      else
-	(*info->fprintf_func) (info->stream, "%s", third);
-    }
-  for (i = 0; i < 3; i++)
-    if (op_index[i] != -1 && op_riprel[i])
-      {
-	(*info->fprintf_func) (info->stream, "	      # ");
-	(*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
-						+ op_address[op_index[i]]), info);
-      }
-  return codep - priv.the_buffer;
-}
-
-static const char *float_mem[] = {
-  /* d8 */
-  "fadd{s||s|}",
-  "fmul{s||s|}",
-  "fcom{s||s|}",
-  "fcomp{s||s|}",
-  "fsub{s||s|}",
-  "fsubr{s||s|}",
-  "fdiv{s||s|}",
-  "fdivr{s||s|}",
-  /* d9 */
-  "fld{s||s|}",
-  "(bad)",
-  "fst{s||s|}",
-  "fstp{s||s|}",
-  "fldenvIC",
-  "fldcw",
-  "fNstenvIC",
-  "fNstcw",
-  /* da */
-  "fiadd{l||l|}",
-  "fimul{l||l|}",
-  "ficom{l||l|}",
-  "ficomp{l||l|}",
-  "fisub{l||l|}",
-  "fisubr{l||l|}",
-  "fidiv{l||l|}",
-  "fidivr{l||l|}",
-  /* db */
-  "fild{l||l|}",
-  "fisttp{l||l|}",
-  "fist{l||l|}",
-  "fistp{l||l|}",
-  "(bad)",
-  "fld{t||t|}",
-  "(bad)",
-  "fstp{t||t|}",
-  /* dc */
-  "fadd{l||l|}",
-  "fmul{l||l|}",
-  "fcom{l||l|}",
-  "fcomp{l||l|}",
-  "fsub{l||l|}",
-  "fsubr{l||l|}",
-  "fdiv{l||l|}",
-  "fdivr{l||l|}",
-  /* dd */
-  "fld{l||l|}",
-  "fisttp{ll||ll|}",
-  "fst{l||l|}",
-  "fstp{l||l|}",
-  "frstorIC",
-  "(bad)",
-  "fNsaveIC",
-  "fNstsw",
-  /* de */
-  "fiadd",
-  "fimul",
-  "ficom",
-  "ficomp",
-  "fisub",
-  "fisubr",
-  "fidiv",
-  "fidivr",
-  /* df */
-  "fild",
-  "fisttp",
-  "fist",
-  "fistp",
-  "fbld",
-  "fild{ll||ll|}",
-  "fbstp",
-  "fistp{ll||ll|}",
-};
-
-static const unsigned char float_mem_mode[] = {
-  /* d8 */
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  /* d9 */
-  d_mode,
-  0,
-  d_mode,
-  d_mode,
-  0,
-  w_mode,
-  0,
-  w_mode,
-  /* da */
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  /* db */
-  d_mode,
-  d_mode,
-  d_mode,
-  d_mode,
-  0,
-  t_mode,
-  0,
-  t_mode,
-  /* dc */
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  /* dd */
-  q_mode,
-  q_mode,
-  q_mode,
-  q_mode,
-  0,
-  0,
-  0,
-  w_mode,
-  /* de */
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  /* df */
-  w_mode,
-  w_mode,
-  w_mode,
-  w_mode,
-  t_mode,
-  q_mode,
-  t_mode,
-  q_mode
-};
-
-#define ST OP_ST, 0
-#define STi OP_STi, 0
-
-#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
-#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
-#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
-#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
-#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
-#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
-#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
-#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
-#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
-
-static const struct dis386 float_reg[][8] = {
-  /* d8 */
-  {
-    { "fadd",	ST, STi, XX },
-    { "fmul",	ST, STi, XX },
-    { "fcom",	STi, XX, XX },
-    { "fcomp",	STi, XX, XX },
-    { "fsub",	ST, STi, XX },
-    { "fsubr",	ST, STi, XX },
-    { "fdiv",	ST, STi, XX },
-    { "fdivr",	ST, STi, XX },
-  },
-  /* d9 */
-  {
-    { "fld",	STi, XX, XX },
-    { "fxch",	STi, XX, XX },
-    { FGRPd9_2 },
-    { "(bad)",	XX, XX, XX },
-    { FGRPd9_4 },
-    { FGRPd9_5 },
-    { FGRPd9_6 },
-    { FGRPd9_7 },
-  },
-  /* da */
-  {
-    { "fcmovb", ST, STi, XX },
-    { "fcmove", ST, STi, XX },
-    { "fcmovbe",ST, STi, XX },
-    { "fcmovu", ST, STi, XX },
-    { "(bad)",	XX, XX, XX },
-    { FGRPda_5 },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* db */
-  {
-    { "fcmovnb",ST, STi, XX },
-    { "fcmovne",ST, STi, XX },
-    { "fcmovnbe",ST, STi, XX },
-    { "fcmovnu",ST, STi, XX },
-    { FGRPdb_4 },
-    { "fucomi", ST, STi, XX },
-    { "fcomi",	ST, STi, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* dc */
-  {
-    { "fadd",	STi, ST, XX },
-    { "fmul",	STi, ST, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-#if UNIXWARE_COMPAT
-    { "fsub",	STi, ST, XX },
-    { "fsubr",	STi, ST, XX },
-    { "fdiv",	STi, ST, XX },
-    { "fdivr",	STi, ST, XX },
-#else
-    { "fsubr",	STi, ST, XX },
-    { "fsub",	STi, ST, XX },
-    { "fdivr",	STi, ST, XX },
-    { "fdiv",	STi, ST, XX },
-#endif
-  },
-  /* dd */
-  {
-    { "ffree",	STi, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "fst",	STi, XX, XX },
-    { "fstp",	STi, XX, XX },
-    { "fucom",	STi, XX, XX },
-    { "fucomp", STi, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-  /* de */
-  {
-    { "faddp",	STi, ST, XX },
-    { "fmulp",	STi, ST, XX },
-    { "(bad)",	XX, XX, XX },
-    { FGRPde_3 },
-#if UNIXWARE_COMPAT
-    { "fsubp",	STi, ST, XX },
-    { "fsubrp", STi, ST, XX },
-    { "fdivp",	STi, ST, XX },
-    { "fdivrp", STi, ST, XX },
-#else
-    { "fsubrp", STi, ST, XX },
-    { "fsubp",	STi, ST, XX },
-    { "fdivrp", STi, ST, XX },
-    { "fdivp",	STi, ST, XX },
-#endif
-  },
-  /* df */
-  {
-    { "ffreep", STi, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { FGRPdf_4 },
-    { "fucomip",ST, STi, XX },
-    { "fcomip", ST, STi, XX },
-    { "(bad)",	XX, XX, XX },
-  },
-};
-
-static char *fgrps[][8] = {
-  /* d9_2  0 */
-  {
-    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
-  },
-
-  /* d9_4  1 */
-  {
-    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
-  },
-
-  /* d9_5  2 */
-  {
-    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
-  },
-
-  /* d9_6  3 */
-  {
-    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
-  },
-
-  /* d9_7  4 */
-  {
-    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
-  },
-
-  /* da_5  5 */
-  {
-    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
-  },
-
-  /* db_4  6 */
-  {
-    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
-    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
-  },
-
-  /* de_3  7 */
-  {
-    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
-  },
-
-  /* df_4  8 */
-  {
-    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
-  },
-};
-
-static void
-dofloat (int sizeflag)
-{
-  const struct dis386 *dp;
-  unsigned char floatop;
-
-  floatop = codep[-1];
-
-  if (mod != 3)
-    {
-      int fp_indx = (floatop - 0xd8) * 8 + reg;
-
-      putop (float_mem[fp_indx], sizeflag);
-      obufp = op1out;
-      OP_E (float_mem_mode[fp_indx], sizeflag);
-      return;
-    }
-  /* Skip mod/rm byte.	*/
-  MODRM_CHECK;
-  codep++;
-
-  dp = &float_reg[floatop - 0xd8][reg];
-  if (dp->name == NULL)
-    {
-      putop (fgrps[dp->bytemode1][rm], sizeflag);
-
-      /* Instruction fnstsw is only one with strange arg.  */
-      if (floatop == 0xdf && codep[-1] == 0xe0)
-	strcpy (op1out, names16[0]);
-    }
-  else
-    {
-      putop (dp->name, sizeflag);
-
-      obufp = op1out;
-      if (dp->op1)
-	(*dp->op1) (dp->bytemode1, sizeflag);
-      obufp = op2out;
-      if (dp->op2)
-	(*dp->op2) (dp->bytemode2, sizeflag);
-    }
-}
-
-static void
-OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  oappend ("%st");
-}
-
-static void
-OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  sprintf (scratchbuf, "%%st(%d)", rm);
-  oappend (scratchbuf + intel_syntax);
-}
-
-/* Capital letters in template are macros.  */
-static int
-putop (const char *template, int sizeflag)
-{
-  const char *p;
-  int alt = 0;
-
-  for (p = template; *p; p++)
-    {
-      switch (*p)
-	{
-	default:
-	  *obufp++ = *p;
-	  break;
-	case '{':
-	  alt = 0;
-	  if (intel_syntax)
-	    alt += 1;
-	  if (mode_64bit)
-	    alt += 2;
-	  while (alt != 0)
-	    {
-	      while (*++p != '|')
-		{
-		  if (*p == '}')
-		    {
-		      /* Alternative not valid.	 */
-		      strcpy (obuf, "(bad)");
-		      obufp = obuf + 5;
-		      return 1;
-		    }
-		  else if (*p == '\0')
-		    abort ();
-		}
-	      alt--;
-	    }
-	  /* Fall through.  */
-	case 'I':
-	  alt = 1;
-	  continue;
-	case '|':
-	  while (*++p != '}')
-	    {
-	      if (*p == '\0')
-		abort ();
-	    }
-	  break;
-	case '}':
-	  break;
-	case 'A':
-	  if (intel_syntax)
-	    break;
-	  if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
-	    *obufp++ = 'b';
-	  break;
-	case 'B':
-	  if (intel_syntax)
-	    break;
-	  if (sizeflag & SUFFIX_ALWAYS)
-	    *obufp++ = 'b';
-	  break;
-	case 'C':
-	  if (intel_syntax && !alt)
-	    break;
-	  if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
-	    {
-	      if (sizeflag & DFLAG)
-		*obufp++ = intel_syntax ? 'd' : 'l';
-	      else
-		*obufp++ = intel_syntax ? 'w' : 's';
-	      used_prefixes |= (prefixes & PREFIX_DATA);
-	    }
-	  break;
-	case 'E':		/* For jcxz/jecxz */
-	  if (mode_64bit)
-	    {
-	      if (sizeflag & AFLAG)
-		*obufp++ = 'r';
-	      else
-		*obufp++ = 'e';
-	    }
-	  else
-	    if (sizeflag & AFLAG)
-	      *obufp++ = 'e';
-	  used_prefixes |= (prefixes & PREFIX_ADDR);
-	  break;
-	case 'F':
-	  if (intel_syntax)
-	    break;
-	  if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
-	    {
-	      if (sizeflag & AFLAG)
-		*obufp++ = mode_64bit ? 'q' : 'l';
-	      else
-		*obufp++ = mode_64bit ? 'l' : 'w';
-	      used_prefixes |= (prefixes & PREFIX_ADDR);
-	    }
-	  break;
-	case 'H':
-	  if (intel_syntax)
-	    break;
-	  if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
-	      || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
-	    {
-	      used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
-	      *obufp++ = ',';
-	      *obufp++ = 'p';
-	      if (prefixes & PREFIX_DS)
-		*obufp++ = 't';
-	      else
-		*obufp++ = 'n';
-	    }
-	  break;
-	case 'J':
-	  if (intel_syntax)
-	    break;
-	  *obufp++ = 'l';
-	  break;
-	case 'L':
-	  if (intel_syntax)
-	    break;
-	  if (sizeflag & SUFFIX_ALWAYS)
-	    *obufp++ = 'l';
-	  break;
-	case 'N':
-	  if ((prefixes & PREFIX_FWAIT) == 0)
-	    *obufp++ = 'n';
-	  else
-	    used_prefixes |= PREFIX_FWAIT;
-	  break;
-	case 'O':
-	  USED_REX (REX_MODE64);
-	  if (rex & REX_MODE64)
-	    *obufp++ = 'o';
-	  else
-	    *obufp++ = 'd';
-	  break;
-	case 'T':
-	  if (intel_syntax)
-	    break;
-	  if (mode_64bit)
-	    {
-	      *obufp++ = 'q';
-	      break;
-	    }
-	  /* Fall through.  */
-	case 'P':
-	  if (intel_syntax)
-	    break;
-	  if ((prefixes & PREFIX_DATA)
-	      || (rex & REX_MODE64)
-	      || (sizeflag & SUFFIX_ALWAYS))
-	    {
-	      USED_REX (REX_MODE64);
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else
-		{
-		   if (sizeflag & DFLAG)
-		      *obufp++ = 'l';
-		   else
-		     *obufp++ = 'w';
-		   used_prefixes |= (prefixes & PREFIX_DATA);
-		}
-	    }
-	  break;
-	case 'U':
-	  if (intel_syntax)
-	    break;
-	  if (mode_64bit)
-	    {
-	      *obufp++ = 'q';
-	      break;
-	    }
-	  /* Fall through.  */
-	case 'Q':
-	  if (intel_syntax && !alt)
-	    break;
-	  USED_REX (REX_MODE64);
-	  if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
-	    {
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else
-		{
-		  if (sizeflag & DFLAG)
-		    *obufp++ = intel_syntax ? 'd' : 'l';
-		  else
-		    *obufp++ = 'w';
-		  used_prefixes |= (prefixes & PREFIX_DATA);
-		}
-	    }
-	  break;
-	case 'R':
-	  USED_REX (REX_MODE64);
-	  if (intel_syntax)
-	    {
-	      if (rex & REX_MODE64)
-		{
-		  *obufp++ = 'q';
-		  *obufp++ = 't';
-		}
-	      else if (sizeflag & DFLAG)
-		{
-		  *obufp++ = 'd';
-		  *obufp++ = 'q';
-		}
-	      else
-		{
-		  *obufp++ = 'w';
-		  *obufp++ = 'd';
-		}
-	    }
-	  else
-	    {
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else if (sizeflag & DFLAG)
-		*obufp++ = 'l';
-	      else
-		*obufp++ = 'w';
-	    }
-	  if (!(rex & REX_MODE64))
-	    used_prefixes |= (prefixes & PREFIX_DATA);
-	  break;
-	case 'S':
-	  if (intel_syntax)
-	    break;
-	  if (sizeflag & SUFFIX_ALWAYS)
-	    {
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else
-		{
-		  if (sizeflag & DFLAG)
-		    *obufp++ = 'l';
-		  else
-		    *obufp++ = 'w';
-		  used_prefixes |= (prefixes & PREFIX_DATA);
-		}
-	    }
-	  break;
-	case 'X':
-	  if (prefixes & PREFIX_DATA)
-	    *obufp++ = 'd';
-	  else
-	    *obufp++ = 's';
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  break;
-	case 'Y':
-	  if (intel_syntax)
-	    break;
-	  if (rex & REX_MODE64)
-	    {
-	      USED_REX (REX_MODE64);
-	      *obufp++ = 'q';
-	    }
-	  break;
-	  /* implicit operand size 'l' for i386 or 'q' for x86-64 */
-	case 'W':
-	  /* operand size flag for cwtl, cbtw */
-	  USED_REX (0);
-	  if (rex)
-	    *obufp++ = 'l';
-	  else if (sizeflag & DFLAG)
-	    *obufp++ = 'w';
-	  else
-	    *obufp++ = 'b';
-	  if (intel_syntax)
-	    {
-	      if (rex)
-		{
-		  *obufp++ = 'q';
-		  *obufp++ = 'e';
-		}
-	      if (sizeflag & DFLAG)
-		{
-		  *obufp++ = 'd';
-		  *obufp++ = 'e';
-		}
-	      else
-		{
-		  *obufp++ = 'w';
-		}
-	    }
-	  if (!rex)
-	    used_prefixes |= (prefixes & PREFIX_DATA);
-	  break;
-	}
-      alt = 0;
-    }
-  *obufp = 0;
-  return 0;
-}
-
-static void
-oappend (const char *s)
-{
-  strcpy (obufp, s);
-  obufp += strlen (s);
-}
-
-static void
-append_seg (void)
-{
-  if (prefixes & PREFIX_CS)
-    {
-      used_prefixes |= PREFIX_CS;
-      oappend ("%cs:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_DS)
-    {
-      used_prefixes |= PREFIX_DS;
-      oappend ("%ds:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_SS)
-    {
-      used_prefixes |= PREFIX_SS;
-      oappend ("%ss:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_ES)
-    {
-      used_prefixes |= PREFIX_ES;
-      oappend ("%es:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_FS)
-    {
-      used_prefixes |= PREFIX_FS;
-      oappend ("%fs:" + intel_syntax);
-    }
-  if (prefixes & PREFIX_GS)
-    {
-      used_prefixes |= PREFIX_GS;
-      oappend ("%gs:" + intel_syntax);
-    }
-}
-
-static void
-OP_indirE (int bytemode, int sizeflag)
-{
-  if (!intel_syntax)
-    oappend ("*");
-  OP_E (bytemode, sizeflag);
-}
-
-static void
-print_operand_value (char *buf, int hex, bfd_vma disp)
-{
-  if (mode_64bit)
-    {
-      if (hex)
-	{
-	  char tmp[30];
-	  int i;
-	  buf[0] = '0';
-	  buf[1] = 'x';
-	  sprintf_vma (tmp, disp);
-	  for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
-	  strcpy (buf + 2, tmp + i);
-	}
-      else
-	{
-	  bfd_signed_vma v = disp;
-	  char tmp[30];
-	  int i;
-	  if (v < 0)
-	    {
-	      *(buf++) = '-';
-	      v = -disp;
-	      /* Check for possible overflow on 0x8000000000000000.  */
-	      if (v < 0)
-		{
-		  strcpy (buf, "9223372036854775808");
-		  return;
-		}
-	    }
-	  if (!v)
-	    {
-	      strcpy (buf, "0");
-	      return;
-	    }
-
-	  i = 0;
-	  tmp[29] = 0;
-	  while (v)
-	    {
-	      tmp[28 - i] = (v % 10) + '0';
-	      v /= 10;
-	      i++;
-	    }
-	  strcpy (buf, tmp + 29 - i);
-	}
-    }
-  else
-    {
-      if (hex)
-	sprintf (buf, "0x%x", (unsigned int) disp);
-      else
-	sprintf (buf, "%d", (int) disp);
-    }
-}
-
-static void
-OP_E (int bytemode, int sizeflag)
-{
-  bfd_vma disp;
-  int add = 0;
-  int riprel = 0;
-  USED_REX (REX_EXTZ);
-  if (rex & REX_EXTZ)
-    add += 8;
-
-  /* Skip mod/rm byte.	*/
-  MODRM_CHECK;
-  codep++;
-
-  if (mod == 3)
-    {
-      switch (bytemode)
-	{
-	case b_mode:
-	  USED_REX (0);
-	  if (rex)
-	    oappend (names8rex[rm + add]);
-	  else
-	    oappend (names8[rm + add]);
-	  break;
-	case w_mode:
-	  oappend (names16[rm + add]);
-	  break;
-	case d_mode:
-	  oappend (names32[rm + add]);
-	  break;
-	case q_mode:
-	  oappend (names64[rm + add]);
-	  break;
-	case m_mode:
-	  if (mode_64bit)
-	    oappend (names64[rm + add]);
-	  else
-	    oappend (names32[rm + add]);
-	  break;
-	case branch_v_mode:
-	  if (mode_64bit)
-	    oappend (names64[rm + add]);
-	  else
-	    {
-	      if ((sizeflag & DFLAG) || bytemode != branch_v_mode)
-		oappend (names32[rm + add]);
-	      else
-		oappend (names16[rm + add]);
-	      used_prefixes |= (prefixes & PREFIX_DATA);
-	    }
-	  break;
-	case v_mode:
-	case dq_mode:
-	case dqw_mode:
-	  USED_REX (REX_MODE64);
-	  if (rex & REX_MODE64)
-	    oappend (names64[rm + add]);
-	  else if ((sizeflag & DFLAG) || bytemode != v_mode)
-	    oappend (names32[rm + add]);
-	  else
-	    oappend (names16[rm + add]);
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  break;
-	case 0:
-	  break;
-	default:
-	  oappend (INTERNAL_DISASSEMBLER_ERROR);
-	  break;
-	}
-      return;
-    }
-
-  disp = 0;
-  append_seg ();
-
-  if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
-    {
-      int havesib;
-      int havebase;
-      int base;
-      int index = 0;
-      int scale = 0;
-
-      havesib = 0;
-      havebase = 1;
-      base = rm;
-
-      if (base == 4)
-	{
-	  havesib = 1;
-	  FETCH_DATA (the_info, codep + 1);
-	  index = (*codep >> 3) & 7;
-	  if (mode_64bit || index != 0x4)
-	    /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored.  */
-	    scale = (*codep >> 6) & 3;
-	  base = *codep & 7;
-	  USED_REX (REX_EXTY);
-	  if (rex & REX_EXTY)
-	    index += 8;
-	  codep++;
-	}
-      base += add;
-
-      switch (mod)
-	{
-	case 0:
-	  if ((base & 7) == 5)
-	    {
-	      havebase = 0;
-	      if (mode_64bit && !havesib)
-		riprel = 1;
-	      disp = get32s ();
-	    }
-	  break;
-	case 1:
-	  FETCH_DATA (the_info, codep + 1);
-	  disp = *codep++;
-	  if ((disp & 0x80) != 0)
-	    disp -= 0x100;
-	  break;
-	case 2:
-	  disp = get32s ();
-	  break;
-	}
-
-      if (!intel_syntax)
-	if (mod != 0 || (base & 7) == 5)
-	  {
-	    print_operand_value (scratchbuf, !riprel, disp);
-	    oappend (scratchbuf);
-	    if (riprel)
-	      {
-		set_op (disp, 1);
-		oappend ("(%rip)");
-	      }
-	  }
-
-      if (havebase || (havesib && (index != 4 || scale != 0)))
-	{
-	  if (intel_syntax)
-	    {
-	      switch (bytemode)
-		{
-		case b_mode:
-		  oappend ("BYTE PTR ");
-		  break;
-		case w_mode:
-		case dqw_mode:
-		  oappend ("WORD PTR ");
-		  break;
-		case branch_v_mode:
-		case v_mode:
-		case dq_mode:
-		  USED_REX (REX_MODE64);
-		  if (rex & REX_MODE64)
-		    oappend ("QWORD PTR ");
-		  else if ((sizeflag & DFLAG) || bytemode == dq_mode)
-		    oappend ("DWORD PTR ");
-		  else
-		    oappend ("WORD PTR ");
-		  used_prefixes |= (prefixes & PREFIX_DATA);
-		  break;
-		case d_mode:
-		  oappend ("DWORD PTR ");
-		  break;
-		case q_mode:
-		  oappend ("QWORD PTR ");
-		  break;
-		case m_mode:
-		  if (mode_64bit)
-		    oappend ("QWORD PTR ");
-		  else
-		    oappend ("DWORD PTR ");
-		  break;
-		case f_mode:
-		  if (sizeflag & DFLAG)
-		    {
-		      used_prefixes |= (prefixes & PREFIX_DATA);
-		      oappend ("FWORD PTR ");
-		    }
-		  else
-		    oappend ("DWORD PTR ");
-		  break;
-		case t_mode:
-		  oappend ("TBYTE PTR ");
-		  break;
-		case x_mode:
-		  oappend ("XMMWORD PTR ");
-		  break;
-		default:
-		  break;
-		}
-	    }
-	  *obufp++ = open_char;
-	  if (intel_syntax && riprel)
-	    oappend ("rip + ");
-	  *obufp = '\0';
-	  if (havebase)
-	    oappend (mode_64bit && (sizeflag & AFLAG)
-		     ? names64[base] : names32[base]);
-	  if (havesib)
-	    {
-	      if (index != 4)
-		{
-		  if (!intel_syntax || havebase)
-		    {
-		      *obufp++ = separator_char;
-		      *obufp = '\0';
-		    }
-		  oappend (mode_64bit && (sizeflag & AFLAG)
-			   ? names64[index] : names32[index]);
-		}
-	      if (scale != 0 || (!intel_syntax && index != 4))
-		{
-		  *obufp++ = scale_char;
-		  *obufp = '\0';
-		  sprintf (scratchbuf, "%d", 1 << scale);
-		  oappend (scratchbuf);
-		}
-	    }
-	  if (intel_syntax && disp)
-	    {
-	      if ((bfd_signed_vma) disp > 0)
-		{
-		  *obufp++ = '+';
-		  *obufp = '\0';
-		}
-	      else if (mod != 1)
-		{
-		  *obufp++ = '-';
-		  *obufp = '\0';
-		  disp = - (bfd_signed_vma) disp;
-		}
-
-	      print_operand_value (scratchbuf, mod != 1, disp);
-	      oappend (scratchbuf);
-	    }
-
-	  *obufp++ = close_char;
-	  *obufp = '\0';
-	}
-      else if (intel_syntax)
-	{
-	  if (mod != 0 || (base & 7) == 5)
-	    {
-	      if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-			      | PREFIX_ES | PREFIX_FS | PREFIX_GS))
-		;
-	      else
-		{
-		  oappend (names_seg[ds_reg - es_reg]);
-		  oappend (":");
-		}
-	      print_operand_value (scratchbuf, 1, disp);
-	      oappend (scratchbuf);
-	    }
-	}
-    }
-  else
-    { /* 16 bit address mode */
-      switch (mod)
-	{
-	case 0:
-	  if (rm == 6)
-	    {
-	      disp = get16 ();
-	      if ((disp & 0x8000) != 0)
-		disp -= 0x10000;
-	    }
-	  break;
-	case 1:
-	  FETCH_DATA (the_info, codep + 1);
-	  disp = *codep++;
-	  if ((disp & 0x80) != 0)
-	    disp -= 0x100;
-	  break;
-	case 2:
-	  disp = get16 ();
-	  if ((disp & 0x8000) != 0)
-	    disp -= 0x10000;
-	  break;
-	}
-
-      if (!intel_syntax)
-	if (mod != 0 || rm == 6)
-	  {
-	    print_operand_value (scratchbuf, 0, disp);
-	    oappend (scratchbuf);
-	  }
-
-      if (mod != 0 || rm != 6)
-	{
-	  *obufp++ = open_char;
-	  *obufp = '\0';
-	  oappend (index16[rm]);
-	  if (intel_syntax && disp)
-	    {
-	      if ((bfd_signed_vma) disp > 0)
-		{
-		  *obufp++ = '+';
-		  *obufp = '\0';
-		}
-	      else if (mod != 1)
-		{
-		  *obufp++ = '-';
-		  *obufp = '\0';
-		  disp = - (bfd_signed_vma) disp;
-		}
-
-	      print_operand_value (scratchbuf, mod != 1, disp);
-	      oappend (scratchbuf);
-	    }
-
-	  *obufp++ = close_char;
-	  *obufp = '\0';
-	}
-      else if (intel_syntax)
-	{
-	  if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-			  | PREFIX_ES | PREFIX_FS | PREFIX_GS))
-	    ;
-	  else
-	    {
-	      oappend (names_seg[ds_reg - es_reg]);
-	      oappend (":");
-	    }
-	  print_operand_value (scratchbuf, 1, disp & 0xffff);
-	  oappend (scratchbuf);
-	}
-    }
-}
-
-static void
-OP_G (int bytemode, int sizeflag)
-{
-  int add = 0;
-  USED_REX (REX_EXTX);
-  if (rex & REX_EXTX)
-    add += 8;
-  switch (bytemode)
-    {
-    case b_mode:
-      USED_REX (0);
-      if (rex)
-	oappend (names8rex[reg + add]);
-      else
-	oappend (names8[reg + add]);
-      break;
-    case w_mode:
-      oappend (names16[reg + add]);
-      break;
-    case d_mode:
-      oappend (names32[reg + add]);
-      break;
-    case q_mode:
-      oappend (names64[reg + add]);
-      break;
-    case v_mode:
-    case dq_mode:
-    case dqw_mode:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	oappend (names64[reg + add]);
-      else if ((sizeflag & DFLAG) || bytemode != v_mode)
-	oappend (names32[reg + add]);
-      else
-	oappend (names16[reg + add]);
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    case m_mode:
-      if (mode_64bit)
-	oappend (names64[reg + add]);
-      else
-	oappend (names32[reg + add]);
-      break;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      break;
-    }
-}
-
-static bfd_vma
-get64 (void)
-{
-  bfd_vma x;
-#ifdef BFD64
-  unsigned int a;
-  unsigned int b;
-
-  FETCH_DATA (the_info, codep + 8);
-  a = *codep++ & 0xff;
-  a |= (*codep++ & 0xff) << 8;
-  a |= (*codep++ & 0xff) << 16;
-  a |= (*codep++ & 0xff) << 24;
-  b = *codep++ & 0xff;
-  b |= (*codep++ & 0xff) << 8;
-  b |= (*codep++ & 0xff) << 16;
-  b |= (*codep++ & 0xff) << 24;
-  x = a + ((bfd_vma) b << 32);
-#else
-  abort ();
-  x = 0;
-#endif
-  return x;
-}
-
-static bfd_signed_vma
-get32 (void)
-{
-  bfd_signed_vma x = 0;
-
-  FETCH_DATA (the_info, codep + 4);
-  x = *codep++ & (bfd_signed_vma) 0xff;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
-  return x;
-}
-
-static bfd_signed_vma
-get32s (void)
-{
-  bfd_signed_vma x = 0;
-
-  FETCH_DATA (the_info, codep + 4);
-  x = *codep++ & (bfd_signed_vma) 0xff;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
-  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
-
-  x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
-
-  return x;
-}
-
-static int
-get16 (void)
-{
-  int x = 0;
-
-  FETCH_DATA (the_info, codep + 2);
-  x = *codep++ & 0xff;
-  x |= (*codep++ & 0xff) << 8;
-  return x;
-}
-
-static void
-set_op (bfd_vma op, int riprel)
-{
-  op_index[op_ad] = op_ad;
-  if (mode_64bit)
-    {
-      op_address[op_ad] = op;
-      op_riprel[op_ad] = riprel;
-    }
-  else
-    {
-      /* Mask to get a 32-bit address.	*/
-      op_address[op_ad] = op & 0xffffffff;
-      op_riprel[op_ad] = riprel & 0xffffffff;
-    }
-}
-
-static void
-OP_REG (int code, int sizeflag)
-{
-  const char *s;
-  int add = 0;
-  USED_REX (REX_EXTZ);
-  if (rex & REX_EXTZ)
-    add = 8;
-
-  switch (code)
-    {
-    case indir_dx_reg:
-      if (intel_syntax)
-	s = "[dx]";
-      else
-	s = "(%dx)";
-      break;
-    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
-    case sp_reg: case bp_reg: case si_reg: case di_reg:
-      s = names16[code - ax_reg + add];
-      break;
-    case es_reg: case ss_reg: case cs_reg:
-    case ds_reg: case fs_reg: case gs_reg:
-      s = names_seg[code - es_reg + add];
-      break;
-    case al_reg: case ah_reg: case cl_reg: case ch_reg:
-    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
-      USED_REX (0);
-      if (rex)
-	s = names8rex[code - al_reg + add];
-      else
-	s = names8[code - al_reg];
-      break;
-    case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
-    case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
-      if (mode_64bit)
-	{
-	  s = names64[code - rAX_reg + add];
-	  break;
-	}
-      code += eAX_reg - rAX_reg;
-      /* Fall through.	*/
-    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
-    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	s = names64[code - eAX_reg + add];
-      else if (sizeflag & DFLAG)
-	s = names32[code - eAX_reg + add];
-      else
-	s = names16[code - eAX_reg + add];
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    default:
-      s = INTERNAL_DISASSEMBLER_ERROR;
-      break;
-    }
-  oappend (s);
-}
-
-static void
-OP_IMREG (int code, int sizeflag)
-{
-  const char *s;
-
-  switch (code)
-    {
-    case indir_dx_reg:
-      if (intel_syntax)
-	s = "[dx]";
-      else
-	s = "(%dx)";
-      break;
-    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
-    case sp_reg: case bp_reg: case si_reg: case di_reg:
-      s = names16[code - ax_reg];
-      break;
-    case es_reg: case ss_reg: case cs_reg:
-    case ds_reg: case fs_reg: case gs_reg:
-      s = names_seg[code - es_reg];
-      break;
-    case al_reg: case ah_reg: case cl_reg: case ch_reg:
-    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
-      USED_REX (0);
-      if (rex)
-	s = names8rex[code - al_reg];
-      else
-	s = names8[code - al_reg];
-      break;
-    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
-    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	s = names64[code - eAX_reg];
-      else if (sizeflag & DFLAG)
-	s = names32[code - eAX_reg];
-      else
-	s = names16[code - eAX_reg];
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    default:
-      s = INTERNAL_DISASSEMBLER_ERROR;
-      break;
-    }
-  oappend (s);
-}
-
-static void
-OP_I (int bytemode, int sizeflag)
-{
-  bfd_signed_vma op;
-  bfd_signed_vma mask = -1;
-
-  switch (bytemode)
-    {
-    case b_mode:
-      FETCH_DATA (the_info, codep + 1);
-      op = *codep++;
-      mask = 0xff;
-      break;
-    case q_mode:
-      if (mode_64bit)
-	{
-	  op = get32s ();
-	  break;
-	}
-      /* Fall through.	*/
-    case v_mode:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	op = get32s ();
-      else if (sizeflag & DFLAG)
-	{
-	  op = get32 ();
-	  mask = 0xffffffff;
-	}
-      else
-	{
-	  op = get16 ();
-	  mask = 0xfffff;
-	}
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    case w_mode:
-      mask = 0xfffff;
-      op = get16 ();
-      break;
-    case const_1_mode:
-      if (intel_syntax)
-	oappend ("1");
-      return;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return;
-    }
-
-  op &= mask;
-  scratchbuf[0] = '$';
-  print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
-  scratchbuf[0] = '\0';
-}
-
-static void
-OP_I64 (int bytemode, int sizeflag)
-{
-  bfd_signed_vma op;
-  bfd_signed_vma mask = -1;
-
-  if (!mode_64bit)
-    {
-      OP_I (bytemode, sizeflag);
-      return;
-    }
-
-  switch (bytemode)
-    {
-    case b_mode:
-      FETCH_DATA (the_info, codep + 1);
-      op = *codep++;
-      mask = 0xff;
-      break;
-    case v_mode:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	op = get64 ();
-      else if (sizeflag & DFLAG)
-	{
-	  op = get32 ();
-	  mask = 0xffffffff;
-	}
-      else
-	{
-	  op = get16 ();
-	  mask = 0xfffff;
-	}
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    case w_mode:
-      mask = 0xfffff;
-      op = get16 ();
-      break;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return;
-    }
-
-  op &= mask;
-  scratchbuf[0] = '$';
-  print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
-  scratchbuf[0] = '\0';
-}
-
-static void
-OP_sI (int bytemode, int sizeflag)
-{
-  bfd_signed_vma op;
-  bfd_signed_vma mask = -1;
-
-  switch (bytemode)
-    {
-    case b_mode:
-      FETCH_DATA (the_info, codep + 1);
-      op = *codep++;
-      if ((op & 0x80) != 0)
-	op -= 0x100;
-      mask = 0xffffffff;
-      break;
-    case v_mode:
-      USED_REX (REX_MODE64);
-      if (rex & REX_MODE64)
-	op = get32s ();
-      else if (sizeflag & DFLAG)
-	{
-	  op = get32s ();
-	  mask = 0xffffffff;
-	}
-      else
-	{
-	  mask = 0xffffffff;
-	  op = get16 ();
-	  if ((op & 0x8000) != 0)
-	    op -= 0x10000;
-	}
-      used_prefixes |= (prefixes & PREFIX_DATA);
-      break;
-    case w_mode:
-      op = get16 ();
-      mask = 0xffffffff;
-      if ((op & 0x8000) != 0)
-	op -= 0x10000;
-      break;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return;
-    }
-
-  scratchbuf[0] = '$';
-  print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_J (int bytemode, int sizeflag)
-{
-  bfd_vma disp;
-  bfd_vma mask = -1;
-
-  switch (bytemode)
-    {
-    case b_mode:
-      FETCH_DATA (the_info, codep + 1);
-      disp = *codep++;
-      if ((disp & 0x80) != 0)
-	disp -= 0x100;
-      break;
-    case v_mode:
-      if (sizeflag & DFLAG)
-	disp = get32s ();
-      else
-	{
-	  disp = get16 ();
-	  /* For some reason, a data16 prefix on a jump instruction
-	     means that the pc is masked to 16 bits after the
-	     displacement is added!  */
-	  mask = 0xffff;
-	}
-      break;
-    default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return;
-    }
-  disp = (start_pc + codep - start_codep + disp) & mask;
-  set_op (disp, 0);
-  print_operand_value (scratchbuf, 1, disp);
-  oappend (scratchbuf);
-}
-
-static void
-OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  oappend (names_seg[reg]);
-}
-
-static void
-OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
-{
-  int seg, offset;
-
-  if (sizeflag & DFLAG)
-    {
-      offset = get32 ();
-      seg = get16 ();
-    }
-  else
-    {
-      offset = get16 ();
-      seg = get16 ();
-    }
-  used_prefixes |= (prefixes & PREFIX_DATA);
-  if (intel_syntax)
-    sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
-  else
-    sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
-  oappend (scratchbuf);
-}
-
-static void
-OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
-{
-  bfd_vma off;
-
-  append_seg ();
-
-  if ((sizeflag & AFLAG) || mode_64bit)
-    off = get32 ();
-  else
-    off = get16 ();
-
-  if (intel_syntax)
-    {
-      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
-	{
-	  oappend (names_seg[ds_reg - es_reg]);
-	  oappend (":");
-	}
-    }
-  print_operand_value (scratchbuf, 1, off);
-  oappend (scratchbuf);
-}
-
-static void
-OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  bfd_vma off;
-
-  if (!mode_64bit)
-    {
-      OP_OFF (bytemode, sizeflag);
-      return;
-    }
-
-  append_seg ();
-
-  off = get64 ();
-
-  if (intel_syntax)
-    {
-      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
-	{
-	  oappend (names_seg[ds_reg - es_reg]);
-	  oappend (":");
-	}
-    }
-  print_operand_value (scratchbuf, 1, off);
-  oappend (scratchbuf);
-}
-
-static void
-ptr_reg (int code, int sizeflag)
-{
-  const char *s;
-
-  *obufp++ = open_char;
-  used_prefixes |= (prefixes & PREFIX_ADDR);
-  if (mode_64bit)
-    {
-      if (!(sizeflag & AFLAG))
-	s = names32[code - eAX_reg];
-      else
-	s = names64[code - eAX_reg];
-    }
-  else if (sizeflag & AFLAG)
-    s = names32[code - eAX_reg];
-  else
-    s = names16[code - eAX_reg];
-  oappend (s);
-  *obufp++ = close_char;
-  *obufp = 0;
-}
-
-static void
-OP_ESreg (int code, int sizeflag)
-{
-  if (intel_syntax)
-    {
-      if (codep[-1] & 1)
-	{
-	  USED_REX (REX_MODE64);
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  if (rex & REX_MODE64)
-	    oappend ("QWORD PTR ");
-	  else if ((sizeflag & DFLAG))
-	    oappend ("DWORD PTR ");
-	  else
-	    oappend ("WORD PTR ");
-	}
-      else
-	oappend ("BYTE PTR ");
-    }
-
-  oappend ("%es:" + intel_syntax);
-  ptr_reg (code, sizeflag);
-}
-
-static void
-OP_DSreg (int code, int sizeflag)
-{
-  if (intel_syntax)
-    {
-      if (codep[-1] != 0xd7 && (codep[-1] & 1))
-	{
-	  USED_REX (REX_MODE64);
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  if (rex & REX_MODE64)
-	    oappend ("QWORD PTR ");
-	  else if ((sizeflag & DFLAG))
-	    oappend ("DWORD PTR ");
-	  else
-	    oappend ("WORD PTR ");
-	}
-      else
-	oappend ("BYTE PTR ");
-    }
-
-  if ((prefixes
-       & (PREFIX_CS
-	  | PREFIX_DS
-	  | PREFIX_SS
-	  | PREFIX_ES
-	  | PREFIX_FS
-	  | PREFIX_GS)) == 0)
-    prefixes |= PREFIX_DS;
-  append_seg ();
-  ptr_reg (code, sizeflag);
-}
-
-static void
-OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  int add = 0;
-  if (rex & REX_EXTX)
-    {
-      USED_REX (REX_EXTX);
-      add = 8;
-    }
-  else if (!mode_64bit && (prefixes & PREFIX_LOCK))
-    {
-      used_prefixes |= PREFIX_LOCK;
-      add = 8;
-    }
-  sprintf (scratchbuf, "%%cr%d", reg + add);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  int add = 0;
-  USED_REX (REX_EXTX);
-  if (rex & REX_EXTX)
-    add = 8;
-  if (intel_syntax)
-    sprintf (scratchbuf, "db%d", reg + add);
-  else
-    sprintf (scratchbuf, "%%db%d", reg + add);
-  oappend (scratchbuf);
-}
-
-static void
-OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  sprintf (scratchbuf, "%%tr%d", reg);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_Rd (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    OP_E (bytemode, sizeflag);
-  else
-    BadOp ();
-}
-
-static void
-OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  used_prefixes |= (prefixes & PREFIX_DATA);
-  if (prefixes & PREFIX_DATA)
-    {
-      int add = 0;
-      USED_REX (REX_EXTX);
-      if (rex & REX_EXTX)
-	add = 8;
-      sprintf (scratchbuf, "%%xmm%d", reg + add);
-    }
-  else
-    sprintf (scratchbuf, "%%mm%d", reg);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  int add = 0;
-  USED_REX (REX_EXTX);
-  if (rex & REX_EXTX)
-    add = 8;
-  sprintf (scratchbuf, "%%xmm%d", reg + add);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_EM (int bytemode, int sizeflag)
-{
-  if (mod != 3)
-    {
-      if (intel_syntax && bytemode == v_mode)
-	{
-	  bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	}
-      OP_E (bytemode, sizeflag);
-      return;
-    }
-
-  /* Skip mod/rm byte.	*/
-  MODRM_CHECK;
-  codep++;
-  used_prefixes |= (prefixes & PREFIX_DATA);
-  if (prefixes & PREFIX_DATA)
-    {
-      int add = 0;
-
-      USED_REX (REX_EXTZ);
-      if (rex & REX_EXTZ)
-	add = 8;
-      sprintf (scratchbuf, "%%xmm%d", rm + add);
-    }
-  else
-    sprintf (scratchbuf, "%%mm%d", rm);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_EX (int bytemode, int sizeflag)
-{
-  int add = 0;
-  if (mod != 3)
-    {
-      if (intel_syntax && bytemode == v_mode)
-	{
-	  switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
-	    {
-	    case 0:	       bytemode = x_mode; break;
-	    case PREFIX_REPZ:  bytemode = d_mode; used_prefixes |= PREFIX_REPZ;	 break;
-	    case PREFIX_DATA:  bytemode = x_mode; used_prefixes |= PREFIX_DATA;	 break;
-	    case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
-	    default:	       bytemode = 0; break;
-	    }
-	}
-      OP_E (bytemode, sizeflag);
-      return;
-    }
-  USED_REX (REX_EXTZ);
-  if (rex & REX_EXTZ)
-    add = 8;
-
-  /* Skip mod/rm byte.	*/
-  MODRM_CHECK;
-  codep++;
-  sprintf (scratchbuf, "%%xmm%d", rm + add);
-  oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_MS (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    OP_EM (bytemode, sizeflag);
-  else
-    BadOp ();
-}
-
-static void
-OP_XS (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    OP_EX (bytemode, sizeflag);
-  else
-    BadOp ();
-}
-
-static void
-OP_M (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    BadOp ();	/* bad lea,lds,les,lfs,lgs,lss modrm */
-  else
-    OP_E (bytemode, sizeflag);
-}
-
-static void
-OP_0f07 (int bytemode, int sizeflag)
-{
-  if (mod != 3 || rm != 0)
-    BadOp ();
-  else
-    OP_E (bytemode, sizeflag);
-}
-
-static void
-OP_0fae (int bytemode, int sizeflag)
-{
-  if (mod == 3)
-    {
-      if (reg == 7)
-	strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
-
-      if (reg < 5 || rm != 0)
-	{
-	  BadOp ();	/* bad sfence, mfence, or lfence */
-	  return;
-	}
-    }
-  else if (reg != 7)
-    {
-      BadOp ();		/* bad clflush */
-      return;
-    }
-
-  OP_E (bytemode, sizeflag);
-}
-
-static void
-NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  /* NOP with REPZ prefix is called PAUSE.  */
-  if (prefixes == PREFIX_REPZ)
-    strcpy (obuf, "pause");
-}
-
-static const char *const Suffix3DNow[] = {
-/* 00 */	NULL,		NULL,		NULL,		NULL,
-/* 04 */	NULL,		NULL,		NULL,		NULL,
-/* 08 */	NULL,		NULL,		NULL,		NULL,
-/* 0C */	"pi2fw",	"pi2fd",	NULL,		NULL,
-/* 10 */	NULL,		NULL,		NULL,		NULL,
-/* 14 */	NULL,		NULL,		NULL,		NULL,
-/* 18 */	NULL,		NULL,		NULL,		NULL,
-/* 1C */	"pf2iw",	"pf2id",	NULL,		NULL,
-/* 20 */	NULL,		NULL,		NULL,		NULL,
-/* 24 */	NULL,		NULL,		NULL,		NULL,
-/* 28 */	NULL,		NULL,		NULL,		NULL,
-/* 2C */	NULL,		NULL,		NULL,		NULL,
-/* 30 */	NULL,		NULL,		NULL,		NULL,
-/* 34 */	NULL,		NULL,		NULL,		NULL,
-/* 38 */	NULL,		NULL,		NULL,		NULL,
-/* 3C */	NULL,		NULL,		NULL,		NULL,
-/* 40 */	NULL,		NULL,		NULL,		NULL,
-/* 44 */	NULL,		NULL,		NULL,		NULL,
-/* 48 */	NULL,		NULL,		NULL,		NULL,
-/* 4C */	NULL,		NULL,		NULL,		NULL,
-/* 50 */	NULL,		NULL,		NULL,		NULL,
-/* 54 */	NULL,		NULL,		NULL,		NULL,
-/* 58 */	NULL,		NULL,		NULL,		NULL,
-/* 5C */	NULL,		NULL,		NULL,		NULL,
-/* 60 */	NULL,		NULL,		NULL,		NULL,
-/* 64 */	NULL,		NULL,		NULL,		NULL,
-/* 68 */	NULL,		NULL,		NULL,		NULL,
-/* 6C */	NULL,		NULL,		NULL,		NULL,
-/* 70 */	NULL,		NULL,		NULL,		NULL,
-/* 74 */	NULL,		NULL,		NULL,		NULL,
-/* 78 */	NULL,		NULL,		NULL,		NULL,
-/* 7C */	NULL,		NULL,		NULL,		NULL,
-/* 80 */	NULL,		NULL,		NULL,		NULL,
-/* 84 */	NULL,		NULL,		NULL,		NULL,
-/* 88 */	NULL,		NULL,		"pfnacc",	NULL,
-/* 8C */	NULL,		NULL,		"pfpnacc",	NULL,
-/* 90 */	"pfcmpge",	NULL,		NULL,		NULL,
-/* 94 */	"pfmin",	NULL,		"pfrcp",	"pfrsqrt",
-/* 98 */	NULL,		NULL,		"pfsub",	NULL,
-/* 9C */	NULL,		NULL,		"pfadd",	NULL,
-/* A0 */	"pfcmpgt",	NULL,		NULL,		NULL,
-/* A4 */	"pfmax",	NULL,		"pfrcpit1",	"pfrsqit1",
-/* A8 */	NULL,		NULL,		"pfsubr",	NULL,
-/* AC */	NULL,		NULL,		"pfacc",	NULL,
-/* B0 */	"pfcmpeq",	NULL,		NULL,		NULL,
-/* B4 */	"pfmul",	NULL,		"pfrcpit2",	"pfmulhrw",
-/* B8 */	NULL,		NULL,		NULL,		"pswapd",
-/* BC */	NULL,		NULL,		NULL,		"pavgusb",
-/* C0 */	NULL,		NULL,		NULL,		NULL,
-/* C4 */	NULL,		NULL,		NULL,		NULL,
-/* C8 */	NULL,		NULL,		NULL,		NULL,
-/* CC */	NULL,		NULL,		NULL,		NULL,
-/* D0 */	NULL,		NULL,		NULL,		NULL,
-/* D4 */	NULL,		NULL,		NULL,		NULL,
-/* D8 */	NULL,		NULL,		NULL,		NULL,
-/* DC */	NULL,		NULL,		NULL,		NULL,
-/* E0 */	NULL,		NULL,		NULL,		NULL,
-/* E4 */	NULL,		NULL,		NULL,		NULL,
-/* E8 */	NULL,		NULL,		NULL,		NULL,
-/* EC */	NULL,		NULL,		NULL,		NULL,
-/* F0 */	NULL,		NULL,		NULL,		NULL,
-/* F4 */	NULL,		NULL,		NULL,		NULL,
-/* F8 */	NULL,		NULL,		NULL,		NULL,
-/* FC */	NULL,		NULL,		NULL,		NULL,
-};
-
-static void
-OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  const char *mnemonic;
-
-  FETCH_DATA (the_info, codep + 1);
-  /* AMD 3DNow! instructions are specified by an opcode suffix in the
-     place where an 8-bit immediate would normally go.	ie. the last
-     byte of the instruction.  */
-  obufp = obuf + strlen (obuf);
-  mnemonic = Suffix3DNow[*codep++ & 0xff];
-  if (mnemonic)
-    oappend (mnemonic);
-  else
-    {
-      /* Since a variable sized modrm/sib chunk is between the start
-	 of the opcode (0x0f0f) and the opcode suffix, we need to do
-	 all the modrm processing first, and don't know until now that
-	 we have a bad opcode.	This necessitates some cleaning up.  */
-      op1out[0] = '\0';
-      op2out[0] = '\0';
-      BadOp ();
-    }
-}
-
-static const char *simd_cmp_op[] = {
-  "eq",
-  "lt",
-  "le",
-  "unord",
-  "neq",
-  "nlt",
-  "nle",
-  "ord"
-};
-
-static void
-OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
-{
-  unsigned int cmp_type;
-
-  FETCH_DATA (the_info, codep + 1);
-  obufp = obuf + strlen (obuf);
-  cmp_type = *codep++ & 0xff;
-  if (cmp_type < 8)
-    {
-      char suffix1 = 'p', suffix2 = 's';
-      used_prefixes |= (prefixes & PREFIX_REPZ);
-      if (prefixes & PREFIX_REPZ)
-	suffix1 = 's';
-      else
-	{
-	  used_prefixes |= (prefixes & PREFIX_DATA);
-	  if (prefixes & PREFIX_DATA)
-	    suffix2 = 'd';
-	  else
-	    {
-	      used_prefixes |= (prefixes & PREFIX_REPNZ);
-	      if (prefixes & PREFIX_REPNZ)
-		suffix1 = 's', suffix2 = 'd';
-	    }
-	}
-      sprintf (scratchbuf, "cmp%s%c%c",
-	       simd_cmp_op[cmp_type], suffix1, suffix2);
-      used_prefixes |= (prefixes & PREFIX_REPZ);
-      oappend (scratchbuf);
-    }
-  else
-    {
-      /* We have a bad extension byte.	Clean up.  */
-      op1out[0] = '\0';
-      op2out[0] = '\0';
-      BadOp ();
-    }
-}
-
-static void
-SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
-{
-  /* Change movlps/movhps to movhlps/movlhps for 2 register operand
-     forms of these instructions.  */
-  if (mod == 3)
-    {
-      char *p = obuf + strlen (obuf);
-      *(p + 1) = '\0';
-      *p       = *(p - 1);
-      *(p - 1) = *(p - 2);
-      *(p - 2) = *(p - 3);
-      *(p - 3) = extrachar;
-    }
-}
-
-static void
-PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
-{
-  if (mod == 3 && reg == 1 && rm <= 1)
-    {
-      /* Override "sidt".  */
-      char *p = obuf + strlen (obuf) - 4;
-
-      /* We might have a suffix when disassembling with -Msuffix.  */
-      if (*p == 'i')
-	--p;
-
-      if (rm)
-	{
-	  /* mwait %eax,%ecx  */
-	  strcpy (p, "mwait");
-	  if (!intel_syntax)
-	    strcpy (op1out, names32[0]);
-	}
-      else
-	{
-	  /* monitor %eax,%ecx,%edx"  */
-	  strcpy (p, "monitor");
-	  if (!intel_syntax)
-	    {
-	      if (!mode_64bit)
-		strcpy (op1out, names32[0]);
-	      else if (!(prefixes & PREFIX_ADDR))
-		strcpy (op1out, names64[0]);
-	      else
-		{
-		  strcpy (op1out, names32[0]);
-		  used_prefixes |= PREFIX_ADDR;
-		}
-	      strcpy (op3out, names32[2]);
-	    }
-	}
-      if (!intel_syntax)
-	{
-	  strcpy (op2out, names32[1]);
-	  two_source_ops = 1;
-	}
-
-      codep++;
-    }
-  else
-    OP_M (0, sizeflag);
-}
-
-static void
-SVME_Fixup (int bytemode, int sizeflag)
-{
-  const char *alt;
-  char *p;
-
-  switch (*codep)
-    {
-    case 0xd8:
-      alt = "vmrun";
-      break;
-    case 0xd9:
-      alt = "vmmcall";
-      break;
-    case 0xda:
-      alt = "vmload";
-      break;
-    case 0xdb:
-      alt = "vmsave";
-      break;
-    case 0xdc:
-      alt = "stgi";
-      break;
-    case 0xdd:
-      alt = "clgi";
-      break;
-    case 0xde:
-      alt = "skinit";
-      break;
-    case 0xdf:
-      alt = "invlpga";
-      break;
-    default:
-      OP_M (bytemode, sizeflag);
-      return;
-    }
-  /* Override "lidt".  */
-  p = obuf + strlen (obuf) - 4;
-  /* We might have a suffix.  */
-  if (*p == 'i')
-    --p;
-  strcpy (p, alt);
-  if (!(prefixes & PREFIX_ADDR))
-    {
-      ++codep;
-      return;
-    }
-  used_prefixes |= PREFIX_ADDR;
-  switch (*codep++)
-    {
-    case 0xdf:
-      strcpy (op2out, names32[1]);
-      two_source_ops = 1;
-	  /* Fall through.  */
-    case 0xd8:
-    case 0xda:
-    case 0xdb:
-      *obufp++ = open_char;
-      if (mode_64bit || (sizeflag & AFLAG))
-	alt = names32[0];
-      else
-	alt = names16[0];
-      strcpy (obufp, alt);
-      obufp += strlen (alt);
-      *obufp++ = close_char;
-      *obufp = '\0';
-      break;
-    }
-}
-
-static void
-INVLPG_Fixup (int bytemode, int sizeflag)
-{
-  const char *alt;
-
-  switch (*codep)
-    {
-    case 0xf8:
-      alt = "swapgs";
-      break;
-    case 0xf9:
-      alt = "rdtscp";
-      break;
-    default:
-      OP_M (bytemode, sizeflag);
-      return;
-    }
-  /* Override "invlpg".	 */
-  strcpy (obuf + strlen (obuf) - 6, alt);
-  codep++;
-}
-
-static void
-BadOp (void)
-{
-  /* Throw away prefixes and 1st. opcode byte.	*/
-  codep = insn_codep + 1;
-  oappend ("(bad)");
-}
-
-static void
-SEG_Fixup (int extrachar, int sizeflag)
-{
-  if (mod == 3)
-    {
-      /* We need to add a proper suffix with
-
-		movw %ds,%ax
-		movl %ds,%eax
-		movq %ds,%rax
-		movw %ax,%ds
-		movl %eax,%ds
-		movq %rax,%ds
-       */
-      const char *suffix;
-
-      if (prefixes & PREFIX_DATA)
-	suffix = "w";
-      else
-	{
-	  USED_REX (REX_MODE64);
-	  if (rex & REX_MODE64)
-	    suffix = "q";
-	  else
-	    suffix = "l";
-	}
-      strcat (obuf, suffix);
-    }
-  else
-    {
-      /* We need to fix the suffix for
-
-		movw %ds,(%eax)
-		movw %ds,(%rax)
-		movw (%eax),%ds
-		movw (%rax),%ds
-
-	 Override "mov[l|q]".  */
-      char *p = obuf + strlen (obuf) - 1;
-
-      /* We might not have a suffix.  */
-      if (*p == 'v')
-	++p;
-      *p = 'w';
-    }
-
-  OP_E (extrachar, sizeflag);
-}
-
-static void
-VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
-{
-  if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
-    {
-      /* Override "sgdt".  */
-      char *p = obuf + strlen (obuf) - 4;
-
-      /* We might have a suffix when disassembling with -Msuffix.  */
-      if (*p == 'g')
-	--p;
-
-      switch (rm)
-	{
-	case 1:
-	  strcpy (p, "vmcall");
-	  break;
-	case 2:
-	  strcpy (p, "vmlaunch");
-	  break;
-	case 3:
-	  strcpy (p, "vmresume");
-	  break;
-	case 4:
-	  strcpy (p, "vmxoff");
-	  break;
-	}
-
-      codep++;
-    }
-  else
-    OP_E (0, sizeflag);
-}
-
-static void
-OP_VMX (int bytemode, int sizeflag)
-{
-  used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
-  if (prefixes & PREFIX_DATA)
-    strcpy (obuf, "vmclear");
-  else if (prefixes & PREFIX_REPZ)
-    strcpy (obuf, "vmxon");
-  else
-    strcpy (obuf, "vmptrld");
-  OP_E (bytemode, sizeflag);
-}
Index: xfs-dev/arch/x86/kdb/kdbasupport.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ xfs-dev/arch/x86/kdb/kdbasupport.c	2008-12-23 09:32:38.776197919 +0100
@@ -0,0 +1,1577 @@
+/*
+ * Kernel Debugger Architecture Independent Support Functions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2008 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/interrupt.h>
+#include <linux/kdebug.h>
+#include <linux/cpumask.h>
+
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/uaccess.h>
+#include <asm/desc.h>
+
+static kdb_machreg_t
+kdba_getcr(int regnum)
+{
+	kdb_machreg_t contents = 0;
+	switch(regnum) {
+	case 0:
+		__asm__ (_ASM_MOV " %%cr0,%0\n\t":"=r"(contents));
+		break;
+	case 1:
+		break;
+	case 2:
+		__asm__ (_ASM_MOV " %%cr2,%0\n\t":"=r"(contents));
+		break;
+	case 3:
+		__asm__ (_ASM_MOV " %%cr3,%0\n\t":"=r"(contents));
+		break;
+	case 4:
+		__asm__ (_ASM_MOV " %%cr4,%0\n\t":"=r"(contents));
+		break;
+	default:
+		break;
+	}
+
+	return contents;
+}
+
+void
+kdba_putdr(int regnum, kdb_machreg_t contents)
+{
+	switch(regnum) {
+	case 0:
+		__asm__ (_ASM_MOV " %0,%%db0\n\t"::"r"(contents));
+		break;
+	case 1:
+		__asm__ (_ASM_MOV " %0,%%db1\n\t"::"r"(contents));
+		break;
+	case 2:
+		__asm__ (_ASM_MOV " %0,%%db2\n\t"::"r"(contents));
+		break;
+	case 3:
+		__asm__ (_ASM_MOV " %0,%%db3\n\t"::"r"(contents));
+		break;
+	case 4:
+	case 5:
+		break;
+	case 6:
+		__asm__ (_ASM_MOV " %0,%%db6\n\t"::"r"(contents));
+		break;
+	case 7:
+		__asm__ (_ASM_MOV " %0,%%db7\n\t"::"r"(contents));
+		break;
+	default:
+		break;
+	}
+}
+
+kdb_machreg_t
+kdba_getdr(int regnum)
+{
+	kdb_machreg_t contents = 0;
+	switch(regnum) {
+	case 0:
+		__asm__ (_ASM_MOV " %%db0,%0\n\t":"=r"(contents));
+		break;
+	case 1:
+		__asm__ (_ASM_MOV " %%db1,%0\n\t":"=r"(contents));
+		break;
+	case 2:
+		__asm__ (_ASM_MOV " %%db2,%0\n\t":"=r"(contents));
+		break;
+	case 3:
+		__asm__ (_ASM_MOV " %%db3,%0\n\t":"=r"(contents));
+		break;
+	case 4:
+	case 5:
+		break;
+	case 6:
+		__asm__ (_ASM_MOV " %%db6,%0\n\t":"=r"(contents));
+		break;
+	case 7:
+		__asm__ (_ASM_MOV " %%db7,%0\n\t":"=r"(contents));
+		break;
+	default:
+		break;
+	}
+
+	return contents;
+}
+
+kdb_machreg_t
+kdba_getdr6(void)
+{
+	return kdba_getdr(6);
+}
+
+kdb_machreg_t
+kdba_getdr7(void)
+{
+	return kdba_getdr(7);
+}
+
+void
+kdba_putdr6(kdb_machreg_t contents)
+{
+	kdba_putdr(6, contents);
+}
+
+static void
+kdba_putdr7(kdb_machreg_t contents)
+{
+	kdba_putdr(7, contents);
+}
+
+void
+kdba_installdbreg(kdb_bp_t *bp)
+{
+	int cpu = smp_processor_id();
+
+	kdb_machreg_t dr7;
+
+	dr7 = kdba_getdr7();
+
+	kdba_putdr(bp->bp_hard[cpu]->bph_reg, bp->bp_addr);
+
+	dr7 |= DR7_GE;
+	if (cpu_has_de)
+		set_in_cr4(X86_CR4_DE);
+
+	switch (bp->bp_hard[cpu]->bph_reg){
+	case 0:
+		DR7_RW0SET(dr7,bp->bp_hard[cpu]->bph_mode);
+		DR7_LEN0SET(dr7,bp->bp_hard[cpu]->bph_length);
+		DR7_G0SET(dr7);
+		break;
+	case 1:
+		DR7_RW1SET(dr7,bp->bp_hard[cpu]->bph_mode);
+		DR7_LEN1SET(dr7,bp->bp_hard[cpu]->bph_length);
+		DR7_G1SET(dr7);
+		break;
+	case 2:
+		DR7_RW2SET(dr7,bp->bp_hard[cpu]->bph_mode);
+		DR7_LEN2SET(dr7,bp->bp_hard[cpu]->bph_length);
+		DR7_G2SET(dr7);
+		break;
+	case 3:
+		DR7_RW3SET(dr7,bp->bp_hard[cpu]->bph_mode);
+		DR7_LEN3SET(dr7,bp->bp_hard[cpu]->bph_length);
+		DR7_G3SET(dr7);
+		break;
+	default:
+		kdb_printf("kdb: Bad debug register!! %ld\n",
+			   bp->bp_hard[cpu]->bph_reg);
+		break;
+	}
+
+	kdba_putdr7(dr7);
+	return;
+}
+
+void
+kdba_removedbreg(kdb_bp_t *bp)
+{
+	int regnum;
+	kdb_machreg_t dr7;
+	int cpu = smp_processor_id();
+
+	if (!bp->bp_hard[cpu])
+		return;
+
+	regnum = bp->bp_hard[cpu]->bph_reg;
+
+	dr7 = kdba_getdr7();
+
+	kdba_putdr(regnum, 0);
+
+	switch (regnum) {
+	case 0:
+		DR7_G0CLR(dr7);
+		DR7_L0CLR(dr7);
+		break;
+	case 1:
+		DR7_G1CLR(dr7);
+		DR7_L1CLR(dr7);
+		break;
+	case 2:
+		DR7_G2CLR(dr7);
+		DR7_L2CLR(dr7);
+		break;
+	case 3:
+		DR7_G3CLR(dr7);
+		DR7_L3CLR(dr7);
+		break;
+	default:
+		kdb_printf("kdb: Bad debug register!! %d\n", regnum);
+		break;
+	}
+
+	kdba_putdr7(dr7);
+}
+
+struct kdbregs {
+	char   *reg_name;
+	size_t	reg_offset;
+};
+
+static struct kdbregs dbreglist[] = {
+	{ "dr0", 	0 },
+	{ "dr1", 	1 },
+	{ "dr2",	2 },
+	{ "dr3", 	3 },
+	{ "dr6", 	6 },
+	{ "dr7",	7 },
+};
+
+static const int ndbreglist = sizeof(dbreglist) / sizeof(struct kdbregs);
+
+#ifdef CONFIG_X86_32
+static struct kdbregs kdbreglist[] = {
+	{ "ax",		offsetof(struct pt_regs, ax) },
+	{ "bx",		offsetof(struct pt_regs, bx) },
+	{ "cx",		offsetof(struct pt_regs, cx) },
+	{ "dx",		offsetof(struct pt_regs, dx) },
+
+	{ "si",		offsetof(struct pt_regs, si) },
+	{ "di",		offsetof(struct pt_regs, di) },
+	{ "sp",		offsetof(struct pt_regs, sp) },
+	{ "ip",		offsetof(struct pt_regs, ip) },
+
+	{ "bp",		offsetof(struct pt_regs, bp) },
+	{ "ss", 	offsetof(struct pt_regs, ss) },
+	{ "cs",		offsetof(struct pt_regs, cs) },
+	{ "flags", 	offsetof(struct pt_regs, flags) },
+
+	{ "ds", 	offsetof(struct pt_regs, ds) },
+	{ "es", 	offsetof(struct pt_regs, es) },
+	{ "origax",	offsetof(struct pt_regs, orig_ax) },
+
+};
+
+static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
+
+
+/*
+ * kdba_getregcontents
+ *
+ *	Return the contents of the register specified by the
+ *	input string argument.   Return an error if the string
+ *	does not match a machine register.
+ *
+ *	The following pseudo register names are supported:
+ *	   &regs	 - Prints address of exception frame
+ *	   kesp		 - Prints kernel stack pointer at time of fault
+ *	   cesp		 - Prints current kernel stack pointer, inside kdb
+ *	   ceflags	 - Prints current flags, inside kdb
+ *	   %<regname>	 - Uses the value of the registers at the
+ *			   last time the user process entered kernel
+ *			   mode, instead of the registers at the time
+ *			   kdb was entered.
+ *
+ * Parameters:
+ *	regname		Pointer to string naming register
+ *	regs		Pointer to structure containing registers.
+ * Outputs:
+ *	*contents	Pointer to unsigned long to recieve register contents
+ * Returns:
+ *	0		Success
+ *	KDB_BADREG	Invalid register name
+ * Locking:
+ * 	None.
+ * Remarks:
+ * 	If kdb was entered via an interrupt from the kernel itself then
+ *	ss and sp are *not* on the stack.
+ */
+
+int
+kdba_getregcontents(const char *regname,
+		    struct pt_regs *regs,
+		    kdb_machreg_t *contents)
+{
+	int i;
+
+	if (strcmp(regname, "cesp") == 0) {
+		asm volatile("movl %%esp,%0":"=m" (*contents));
+		return 0;
+	}
+
+	if (strcmp(regname, "ceflags") == 0) {
+		unsigned long flags;
+		local_save_flags(flags);
+		*contents = flags;
+		return 0;
+	}
+
+	if (regname[0] == '%') {
+		/* User registers:  %%e[a-c]x, etc */
+		regname++;
+		regs = (struct pt_regs *)
+			(kdb_current_task->thread.sp0 - sizeof(struct pt_regs));
+	}
+
+	for (i=0; i<ndbreglist; i++) {
+		if (strnicmp(dbreglist[i].reg_name,
+			     regname,
+			     strlen(regname)) == 0)
+			break;
+	}
+
+	if ((i < ndbreglist)
+	 && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
+		*contents = kdba_getdr(dbreglist[i].reg_offset);
+		return 0;
+	}
+
+	if (!regs) {
+		kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+		return KDB_BADREG;
+	}
+
+	if (strcmp(regname, "&regs") == 0) {
+		*contents = (unsigned long)regs;
+		return 0;
+	}
+
+	if (strcmp(regname, "kesp") == 0) {
+		*contents = (unsigned long)regs + sizeof(struct pt_regs);
+		if ((regs->cs & 0xffff) == __KERNEL_CS) {
+			/* sp and ss are not on stack */
+			*contents -= 2*4;
+		}
+		return 0;
+	}
+
+	for (i=0; i<nkdbreglist; i++) {
+		if (strnicmp(kdbreglist[i].reg_name,
+			     regname,
+			     strlen(regname)) == 0)
+			break;
+	}
+
+	if ((i < nkdbreglist)
+	 && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+		if ((regs->cs & 0xffff) == __KERNEL_CS) {
+			/* No cpl switch, sp and ss are not on stack */
+			if (strcmp(kdbreglist[i].reg_name, "sp") == 0) {
+				*contents = (kdb_machreg_t)regs +
+					sizeof(struct pt_regs) - 2*4;
+				return(0);
+			}
+			if (strcmp(kdbreglist[i].reg_name, "xss") == 0) {
+				asm volatile(
+					"pushl %%ss\n"
+					"popl %0\n"
+					:"=m" (*contents));
+				return(0);
+			}
+		}
+		*contents = *(unsigned long *)((unsigned long)regs +
+				kdbreglist[i].reg_offset);
+		return(0);
+	}
+
+	return KDB_BADREG;
+}
+
+/*
+ * kdba_setregcontents
+ *
+ *	Set the contents of the register specified by the
+ *	input string argument.   Return an error if the string
+ *	does not match a machine register.
+ *
+ *	Supports modification of user-mode registers via
+ *	%<register-name>
+ *
+ * Parameters:
+ *	regname		Pointer to string naming register
+ *	regs		Pointer to structure containing registers.
+ *	contents	Unsigned long containing new register contents
+ * Outputs:
+ * Returns:
+ *	0		Success
+ *	KDB_BADREG	Invalid register name
+ * Locking:
+ * 	None.
+ * Remarks:
+ */
+
+int
+kdba_setregcontents(const char *regname,
+		  struct pt_regs *regs,
+		  unsigned long contents)
+{
+	int i;
+
+	if (regname[0] == '%') {
+		regname++;
+		regs = (struct pt_regs *)
+			(kdb_current_task->thread.sp0 - sizeof(struct pt_regs));
+	}
+
+	for (i=0; i<ndbreglist; i++) {
+		if (strnicmp(dbreglist[i].reg_name,
+			     regname,
+			     strlen(regname)) == 0)
+			break;
+	}
+
+	if ((i < ndbreglist)
+	 && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
+		kdba_putdr(dbreglist[i].reg_offset, contents);
+		return 0;
+	}
+
+	if (!regs) {
+		kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+		return KDB_BADREG;
+	}
+
+	for (i=0; i<nkdbreglist; i++) {
+		if (strnicmp(kdbreglist[i].reg_name,
+			     regname,
+			     strlen(regname)) == 0)
+			break;
+	}
+
+	if ((i < nkdbreglist)
+	 && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+		*(unsigned long *)((unsigned long)regs
+				   + kdbreglist[i].reg_offset) = contents;
+		return 0;
+	}
+
+	return KDB_BADREG;
+}
+
+/*
+ * kdba_pt_regs
+ *
+ *	Format a struct pt_regs
+ *
+ * Inputs:
+ *	argc	argument count
+ *	argv	argument vector
+ * Outputs:
+ *	None.
+ * Returns:
+ *	zero for success, a kdb diagnostic if error
+ * Locking:
+ *	none.
+ * Remarks:
+ *	If no address is supplied, it uses the last irq pt_regs.
+ */
+
+static int
+kdba_pt_regs(int argc, const char **argv)
+{
+	int diag;
+	kdb_machreg_t addr;
+	long offset = 0;
+	int nextarg;
+	struct pt_regs *p;
+	static const char *fmt = "  %-11.11s 0x%lx\n";
+
+	if (argc == 0) {
+		addr = (kdb_machreg_t) get_irq_regs();
+	} else if (argc == 1) {
+		nextarg = 1;
+		diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL);
+		if (diag)
+			return diag;
+	} else {
+		return KDB_ARGCOUNT;
+	}
+
+	p = (struct pt_regs *) addr;
+	kdb_printf("struct pt_regs 0x%p-0x%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
+	kdb_print_nameval("bx", p->bx);
+	kdb_print_nameval("cx", p->cx);
+	kdb_print_nameval("dx", p->dx);
+	kdb_print_nameval("si", p->si);
+	kdb_print_nameval("di", p->di);
+	kdb_print_nameval("bp", p->bp);
+	kdb_print_nameval("ax", p->ax);
+	kdb_printf(fmt, "ds", p->ds);
+	kdb_printf(fmt, "es", p->es);
+	kdb_print_nameval("orig_ax", p->orig_ax);
+	kdb_print_nameval("ip", p->ip);
+	kdb_printf(fmt, "cs", p->cs);
+	kdb_printf(fmt, "flags", p->flags);
+	kdb_printf(fmt, "sp", p->sp);
+	kdb_printf(fmt, "ss", p->ss);
+	return 0;
+}
+
+#else /* CONFIG_X86_32 */
+
+static struct kdbregs kdbreglist[] = {
+	{ "r15",	offsetof(struct pt_regs, r15) },
+	{ "r14",	offsetof(struct pt_regs, r14) },
+	{ "r13",	offsetof(struct pt_regs, r13) },
+	{ "r12",	offsetof(struct pt_regs, r12) },
+	{ "bp",		offsetof(struct pt_regs, bp) },
+	{ "bx",		offsetof(struct pt_regs, bx) },
+	{ "r11",	offsetof(struct pt_regs, r11) },
+	{ "r10",	offsetof(struct pt_regs, r10) },
+	{ "r9",		offsetof(struct pt_regs, r9) },
+	{ "r8",		offsetof(struct pt_regs, r8) },
+	{ "ax",		offsetof(struct pt_regs, ax) },
+	{ "cx",		offsetof(struct pt_regs, cx) },
+	{ "dx",		offsetof(struct pt_regs, dx) },
+	{ "si",		offsetof(struct pt_regs, si) },
+	{ "di",		offsetof(struct pt_regs, di) },
+	{ "orig_ax",	offsetof(struct pt_regs, orig_ax) },
+	{ "ip",		offsetof(struct pt_regs, ip) },
+	{ "cs",		offsetof(struct pt_regs, cs) },
+	{ "flags", 	offsetof(struct pt_regs, flags) },
+	{ "sp",		offsetof(struct pt_regs, sp) },
+	{ "ss",		offsetof(struct pt_regs, ss) },
+};
+
+static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
+
+
+/*
+ * kdba_getregcontents
+ *
+ *	Return the contents of the register specified by the
+ *	input string argument.   Return an error if the string
+ *	does not match a machine register.
+ *
+ *	The following pseudo register names are supported:
+ *	   &regs	 - Prints address of exception frame
+ *	   krsp		 - Prints kernel stack pointer at time of fault
+ *	   crsp		 - Prints current kernel stack pointer, inside kdb
+ *	   ceflags	 - Prints current flags, inside kdb
+ *	   %<regname>	 - Uses the value of the registers at the
+ *			   last time the user process entered kernel
+ *			   mode, instead of the registers at the time
+ *			   kdb was entered.
+ *
+ * Parameters:
+ *	regname		Pointer to string naming register
+ *	regs		Pointer to structure containing registers.
+ * Outputs:
+ *	*contents	Pointer to unsigned long to recieve register contents
+ * Returns:
+ *	0		Success
+ *	KDB_BADREG	Invalid register name
+ * Locking:
+ * 	None.
+ * Remarks:
+ * 	If kdb was entered via an interrupt from the kernel itself then
+ *	ss and sp are *not* on the stack.
+ */
+int
+kdba_getregcontents(const char *regname,
+		    struct pt_regs *regs,
+		    kdb_machreg_t *contents)
+{
+	int i;
+
+	if (strcmp(regname, "&regs") == 0) {
+		*contents = (unsigned long)regs;
+		return 0;
+	}
+
+	if (strcmp(regname, "krsp") == 0) {
+		*contents = (unsigned long)regs + sizeof(struct pt_regs);
+		if ((regs->cs & 0xffff) == __KERNEL_CS) {
+			/* sp and ss are not on stack */
+			*contents -= 2*4;
+		}
+		return 0;
+	}
+
+	if (strcmp(regname, "crsp") == 0) {
+		asm volatile("movq %%rsp,%0":"=m" (*contents));
+		return 0;
+	}
+
+	if (strcmp(regname, "ceflags") == 0) {
+		unsigned long flags;
+		local_save_flags(flags);
+		*contents = flags;
+		return 0;
+	}
+
+	if (regname[0] == '%') {
+		/* User registers:  %%r[a-c]x, etc */
+		regname++;
+		regs = (struct pt_regs *)
+			(current->thread.sp0 - sizeof(struct pt_regs));
+	}
+
+	for (i=0; i<nkdbreglist; i++) {
+		if (strnicmp(kdbreglist[i].reg_name,
+			     regname,
+			     strlen(regname)) == 0)
+			break;
+	}
+
+	if ((i < nkdbreglist)
+	 && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+		if ((regs->cs & 0xffff) == __KERNEL_CS) {
+			/* No cpl switch, sp is not on stack */
+			if (strcmp(kdbreglist[i].reg_name, "sp") == 0) {
+				*contents = (kdb_machreg_t)regs +
+					sizeof(struct pt_regs) - 2*8;
+				return(0);
+			}
+#if 0	/* FIXME */
+			if (strcmp(kdbreglist[i].reg_name, "ss") == 0) {
+				kdb_machreg_t r;
+
+				r = (kdb_machreg_t)regs +
+					sizeof(struct pt_regs) - 2*8;
+				*contents = (kdb_machreg_t)SS(r);	/* XXX */
+				return(0);
+			}
+#endif
+		}
+		*contents = *(unsigned long *)((unsigned long)regs +
+				kdbreglist[i].reg_offset);
+		return(0);
+	}
+
+	for (i=0; i<ndbreglist; i++) {
+		if (strnicmp(dbreglist[i].reg_name,
+			     regname,
+			     strlen(regname)) == 0)
+			break;
+	}
+
+	if ((i < ndbreglist)
+	 && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
+		*contents = kdba_getdr(dbreglist[i].reg_offset);
+		return 0;
+	}
+	return KDB_BADREG;
+}
+
+/*
+ * kdba_setregcontents
+ *
+ *	Set the contents of the register specified by the
+ *	input string argument.   Return an error if the string
+ *	does not match a machine register.
+ *
+ *	Supports modification of user-mode registers via
+ *	%<register-name>
+ *
+ * Parameters:
+ *	regname		Pointer to string naming register
+ *	regs		Pointer to structure containing registers.
+ *	contents	Unsigned long containing new register contents
+ * Outputs:
+ * Returns:
+ *	0		Success
+ *	KDB_BADREG	Invalid register name
+ * Locking:
+ * 	None.
+ * Remarks:
+ */
+
+int
+kdba_setregcontents(const char *regname,
+		  struct pt_regs *regs,
+		  unsigned long contents)
+{
+	int i;
+
+	if (regname[0] == '%') {
+		regname++;
+		regs = (struct pt_regs *)
+			(current->thread.sp0 - sizeof(struct pt_regs));
+	}
+
+	for (i=0; i<nkdbreglist; i++) {
+		if (strnicmp(kdbreglist[i].reg_name,
+			     regname,
+			     strlen(regname)) == 0)
+			break;
+	}
+
+	if ((i < nkdbreglist)
+	 && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+		*(unsigned long *)((unsigned long)regs
+				   + kdbreglist[i].reg_offset) = contents;
+		return 0;
+	}
+
+	for (i=0; i<ndbreglist; i++) {
+		if (strnicmp(dbreglist[i].reg_name,
+			     regname,
+			     strlen(regname)) == 0)
+			break;
+	}
+
+	if ((i < ndbreglist)
+	 && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
+		kdba_putdr(dbreglist[i].reg_offset, contents);
+		return 0;
+	}
+
+	return KDB_BADREG;
+}
+
+/*
+ * kdba_pt_regs
+ *
+ *	Format a struct pt_regs
+ *
+ * Inputs:
+ *	argc	argument count
+ *	argv	argument vector
+ * Outputs:
+ *	None.
+ * Returns:
+ *	zero for success, a kdb diagnostic if error
+ * Locking:
+ *	none.
+ * Remarks:
+ *	If no address is supplied, it uses the last irq pt_regs.
+ */
+
+static int
+kdba_pt_regs(int argc, const char **argv)
+{
+	int diag;
+	kdb_machreg_t addr;
+	long offset = 0;
+	int nextarg;
+	struct pt_regs *p;
+	static const char *fmt = "  %-11.11s 0x%lx\n";
+	static int first_time = 1;
+
+	if (argc == 0) {
+		addr = (kdb_machreg_t) get_irq_regs();
+	} else if (argc == 1) {
+		nextarg = 1;
+		diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL);
+		if (diag)
+			return diag;
+	} else {
+		return KDB_ARGCOUNT;
+	}
+
+	p = (struct pt_regs *) addr;
+	if (first_time) {
+		first_time = 0;
+		kdb_printf("\n+++ Warning: x86_64 pt_regs are not always "
+			   "completely defined, r15-bx may be invalid\n\n");
+	}
+	kdb_printf("struct pt_regs 0x%p-0x%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
+	kdb_print_nameval("r15", p->r15);
+	kdb_print_nameval("r14", p->r14);
+	kdb_print_nameval("r13", p->r13);
+	kdb_print_nameval("r12", p->r12);
+	kdb_print_nameval("bp", p->bp);
+	kdb_print_nameval("bx", p->bx);
+	kdb_print_nameval("r11", p->r11);
+	kdb_print_nameval("r10", p->r10);
+	kdb_print_nameval("r9", p->r9);
+	kdb_print_nameval("r8", p->r8);
+	kdb_print_nameval("ax", p->ax);
+	kdb_print_nameval("cx", p->cx);
+	kdb_print_nameval("dx", p->dx);
+	kdb_print_nameval("si", p->si);
+	kdb_print_nameval("di", p->di);
+	kdb_print_nameval("orig_ax", p->orig_ax);
+	kdb_print_nameval("ip", p->ip);
+	kdb_printf(fmt, "cs", p->cs);
+	kdb_printf(fmt, "flags", p->flags);
+	kdb_printf(fmt, "sp", p->sp);
+	kdb_printf(fmt, "ss", p->ss);
+	return 0;
+}
+#endif /* CONFIG_X86_32 */
+
+/*
+ * kdba_dumpregs
+ *
+ *	Dump the specified register set to the display.
+ *
+ * Parameters:
+ *	regs		Pointer to structure containing registers.
+ *	type		Character string identifying register set to dump
+ *	extra		string further identifying register (optional)
+ * Outputs:
+ * Returns:
+ *	0		Success
+ * Locking:
+ * 	None.
+ * Remarks:
+ *	This function will dump the general register set if the type
+ *	argument is NULL (struct pt_regs).   The alternate register
+ *	set types supported by this function:
+ *
+ *	d		Debug registers
+ *	c		Control registers
+ *	u		User registers at most recent entry to kernel
+ *			for the process currently selected with "pid" command.
+ * Following not yet implemented:
+ *	r		Memory Type Range Registers (extra defines register)
+ *
+ * MSR on i386/x86_64 are handled by rdmsr/wrmsr commands.
+ */
+
+int
+kdba_dumpregs(struct pt_regs *regs,
+	    const char *type,
+	    const char *extra)
+{
+	int i;
+	int count = 0;
+
+	if (type
+	 && (type[0] == 'u')) {
+		type = NULL;
+		regs = (struct pt_regs *)
+			(kdb_current_task->thread.sp0 - sizeof(struct pt_regs));
+	}
+
+	if (type == NULL) {
+		struct kdbregs *rlp;
+		kdb_machreg_t contents;
+
+		if (!regs) {
+			kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+			return KDB_BADREG;
+		}
+
+#ifdef CONFIG_X86_32
+		for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) {
+			kdb_printf("%s = ", rlp->reg_name);
+			kdba_getregcontents(rlp->reg_name, regs, &contents);
+			kdb_printf("0x%08lx ", contents);
+			if ((++count % 4) == 0)
+				kdb_printf("\n");
+		}
+#else
+		for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) {
+			kdb_printf("%8s = ", rlp->reg_name);
+			kdba_getregcontents(rlp->reg_name, regs, &contents);
+			kdb_printf("0x%016lx ", contents);
+			if ((++count % 2) == 0)
+				kdb_printf("\n");
+		}
+#endif
+
+		kdb_printf("&regs = 0x%p\n", regs);
+
+		return 0;
+	}
+
+	switch (type[0]) {
+	case 'd':
+	{
+		unsigned long dr[8];
+
+		for(i=0; i<8; i++) {
+			if ((i == 4) || (i == 5)) continue;
+			dr[i] = kdba_getdr(i);
+		}
+		kdb_printf("dr0 = 0x%08lx  dr1 = 0x%08lx  dr2 = 0x%08lx  dr3 = 0x%08lx\n",
+			   dr[0], dr[1], dr[2], dr[3]);
+		kdb_printf("dr6 = 0x%08lx  dr7 = 0x%08lx\n",
+			   dr[6], dr[7]);
+		return 0;
+	}
+	case 'c':
+	{
+		unsigned long cr[5];
+
+		for (i=0; i<5; i++) {
+			cr[i] = kdba_getcr(i);
+		}
+		kdb_printf("cr0 = 0x%08lx  cr1 = 0x%08lx  cr2 = 0x%08lx  cr3 = 0x%08lx\ncr4 = 0x%08lx\n",
+			   cr[0], cr[1], cr[2], cr[3], cr[4]);
+		return 0;
+	}
+	case 'r':
+		break;
+	default:
+		return KDB_BADREG;
+	}
+
+	/* NOTREACHED */
+	return 0;
+}
+EXPORT_SYMBOL(kdba_dumpregs);
+
+kdb_machreg_t
+kdba_getpc(struct pt_regs *regs)
+{
+	return regs ? regs->ip : 0;
+}
+
+int
+kdba_setpc(struct pt_regs *regs, kdb_machreg_t newpc)
+{
+	if (KDB_NULL_REGS(regs))
+		return KDB_BADREG;
+	regs->ip = newpc;
+	KDB_STATE_SET(IP_ADJUSTED);
+	return 0;
+}
+
+/*
+ * kdba_main_loop
+ *
+ *	Do any architecture specific set up before entering the main kdb loop.
+ *	The primary function of this routine is to make all processes look the
+ *	same to kdb, kdb must be able to list a process without worrying if the
+ *	process is running or blocked, so make all process look as though they
+ *	are blocked.
+ *
+ * Inputs:
+ *	reason		The reason KDB was invoked
+ *	error		The hardware-defined error code
+ *	error2		kdb's current reason code.  Initially error but can change
+ *			acording to kdb state.
+ *	db_result	Result from break or debug point.
+ *	regs		The exception frame at time of fault/breakpoint.  If reason
+ *			is SILENT or CPU_UP then regs is NULL, otherwise it should
+ *			always be valid.
+ * Returns:
+ *	0	KDB was invoked for an event which it wasn't responsible
+ *	1	KDB handled the event for which it was invoked.
+ * Outputs:
+ *	Sets ip and sp in current->thread.
+ * Locking:
+ *	None.
+ * Remarks:
+ *	none.
+ */
+
+int
+kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
+	       kdb_dbtrap_t db_result, struct pt_regs *regs)
+{
+	int ret;
+
+#ifdef CONFIG_X86_64
+	if (regs)
+		kdba_getregcontents("sp", regs, &(current->thread.sp));
+#endif
+	ret = kdb_save_running(regs, reason, reason2, error, db_result);
+	kdb_unsave_running(regs);
+	return ret;
+}
+
+void
+kdba_disableint(kdb_intstate_t *state)
+{
+	unsigned long *fp = (unsigned long *)state;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	*fp = flags;
+}
+
+void
+kdba_restoreint(kdb_intstate_t *state)
+{
+	unsigned long flags = *(unsigned long *)state;
+	local_irq_restore(flags);
+}
+
+void
+kdba_setsinglestep(struct pt_regs *regs)
+{
+	if (KDB_NULL_REGS(regs))
+		return;
+	if (regs->flags & X86_EFLAGS_IF)
+		KDB_STATE_SET(A_IF);
+	else
+		KDB_STATE_CLEAR(A_IF);
+	regs->flags = (regs->flags | X86_EFLAGS_TF) & ~X86_EFLAGS_IF;
+}
+
+void
+kdba_clearsinglestep(struct pt_regs *regs)
+{
+	if (KDB_NULL_REGS(regs))
+		return;
+	if (KDB_STATE(A_IF))
+		regs->flags |= X86_EFLAGS_IF;
+	else
+		regs->flags &= ~X86_EFLAGS_IF;
+}
+
+#ifdef CONFIG_X86_32
+int asmlinkage
+kdba_setjmp(kdb_jmp_buf *jb)
+{
+#ifdef CONFIG_FRAME_POINTER
+	__asm__ ("movl 8(%esp), %eax\n\t"
+		 "movl %ebx, 0(%eax)\n\t"
+		 "movl %esi, 4(%eax)\n\t"
+		 "movl %edi, 8(%eax)\n\t"
+		 "movl (%esp), %ecx\n\t"
+		 "movl %ecx, 12(%eax)\n\t"
+		 "leal 8(%esp), %ecx\n\t"
+		 "movl %ecx, 16(%eax)\n\t"
+		 "movl 4(%esp), %ecx\n\t"
+		 "movl %ecx, 20(%eax)\n\t");
+#else	 /* CONFIG_FRAME_POINTER */
+	__asm__ ("movl 4(%esp), %eax\n\t"
+		 "movl %ebx, 0(%eax)\n\t"
+		 "movl %esi, 4(%eax)\n\t"
+		 "movl %edi, 8(%eax)\n\t"
+		 "movl %ebp, 12(%eax)\n\t"
+		 "leal 4(%esp), %ecx\n\t"
+		 "movl %ecx, 16(%eax)\n\t"
+		 "movl 0(%esp), %ecx\n\t"
+		 "movl %ecx, 20(%eax)\n\t");
+#endif   /* CONFIG_FRAME_POINTER */
+	return 0;
+}
+
+void asmlinkage
+kdba_longjmp(kdb_jmp_buf *jb, int reason)
+{
+#ifdef CONFIG_FRAME_POINTER
+	__asm__("movl 8(%esp), %ecx\n\t"
+		"movl 12(%esp), %eax\n\t"
+		"movl 20(%ecx), %edx\n\t"
+		"movl 0(%ecx), %ebx\n\t"
+		"movl 4(%ecx), %esi\n\t"
+		"movl 8(%ecx), %edi\n\t"
+		"movl 12(%ecx), %ebp\n\t"
+		"movl 16(%ecx), %esp\n\t"
+		"jmp *%edx\n");
+#else    /* CONFIG_FRAME_POINTER */
+	__asm__("movl 4(%esp), %ecx\n\t"
+		"movl 8(%esp), %eax\n\t"
+		"movl 20(%ecx), %edx\n\t"
+		"movl 0(%ecx), %ebx\n\t"
+		"movl 4(%ecx), %esi\n\t"
+		"movl 8(%ecx), %edi\n\t"
+		"movl 12(%ecx), %ebp\n\t"
+		"movl 16(%ecx), %esp\n\t"
+		"jmp *%edx\n");
+#endif	 /* CONFIG_FRAME_POINTER */
+}
+
+#else /* CONFIG_X86_32 */
+
+int asmlinkage
+kdba_setjmp(kdb_jmp_buf *jb)
+{
+#ifdef	CONFIG_FRAME_POINTER
+	__asm__ __volatile__
+		("movq %%rbx, (0*8)(%%rdi);"
+		"movq %%rcx, (1*8)(%%rdi);"
+		"movq %%r12, (2*8)(%%rdi);"
+		"movq %%r13, (3*8)(%%rdi);"
+		"movq %%r14, (4*8)(%%rdi);"
+		"movq %%r15, (5*8)(%%rdi);"
+		"leaq 16(%%rsp), %%rdx;"
+		"movq %%rdx, (6*8)(%%rdi);"
+		"movq %%rax, (7*8)(%%rdi)"
+		:
+		: "a" (__builtin_return_address(0)),
+		  "c" (__builtin_frame_address(1))
+		);
+#else	 /* !CONFIG_FRAME_POINTER */
+	__asm__ __volatile__
+		("movq %%rbx, (0*8)(%%rdi);"
+		"movq %%rbp, (1*8)(%%rdi);"
+		"movq %%r12, (2*8)(%%rdi);"
+		"movq %%r13, (3*8)(%%rdi);"
+		"movq %%r14, (4*8)(%%rdi);"
+		"movq %%r15, (5*8)(%%rdi);"
+		"leaq 8(%%rsp), %%rdx;"
+		"movq %%rdx, (6*8)(%%rdi);"
+		"movq %%rax, (7*8)(%%rdi)"
+		:
+		: "a" (__builtin_return_address(0))
+		);
+#endif   /* CONFIG_FRAME_POINTER */
+	return 0;
+}
+
+void asmlinkage
+kdba_longjmp(kdb_jmp_buf *jb, int reason)
+{
+	__asm__("movq (0*8)(%rdi),%rbx;"
+		"movq (1*8)(%rdi),%rbp;"
+		"movq (2*8)(%rdi),%r12;"
+		"movq (3*8)(%rdi),%r13;"
+		"movq (4*8)(%rdi),%r14;"
+		"movq (5*8)(%rdi),%r15;"
+		"movq (7*8)(%rdi),%rdx;"
+		"movq (6*8)(%rdi),%rsp;"
+		"mov %rsi, %rax;"
+		"jmpq *%rdx");
+}
+#endif /* CONFIG_X86_32 */
+
+#ifdef CONFIG_X86_32
+/*
+ * kdba_stackdepth
+ *
+ *	Print processes that are using more than a specific percentage of their
+ *	stack.
+ *
+ * Inputs:
+ *	argc	argument count
+ *	argv	argument vector
+ * Outputs:
+ *	None.
+ * Returns:
+ *	zero for success, a kdb diagnostic if error
+ * Locking:
+ *	none.
+ * Remarks:
+ *	If no percentage is supplied, it uses 60.
+ */
+
+static void
+kdba_stackdepth1(struct task_struct *p, unsigned long sp)
+{
+	struct thread_info *tinfo;
+	int used;
+	const char *type;
+	kdb_ps1(p);
+	do {
+		tinfo = (struct thread_info *)(sp & -THREAD_SIZE);
+		used = sizeof(*tinfo) + THREAD_SIZE - (sp & (THREAD_SIZE-1));
+		type = NULL;
+		if (kdb_task_has_cpu(p)) {
+			struct kdb_activation_record ar;
+			memset(&ar, 0, sizeof(ar));
+			kdba_get_stack_info_alternate(sp, -1, &ar);
+			type = ar.stack.id;
+		}
+		if (!type)
+			type = "process";
+		kdb_printf("  %s stack %p sp %lx used %d\n", type, tinfo, sp, used);
+		sp = tinfo->previous_esp;
+	} while (sp);
+}
+
+static int
+kdba_stackdepth(int argc, const char **argv)
+{
+	int diag, cpu, threshold, used, over;
+	unsigned long percentage;
+	unsigned long esp;
+	long offset = 0;
+	int nextarg;
+	struct task_struct *p, *g;
+	struct kdb_running_process *krp;
+	struct thread_info *tinfo;
+
+	if (argc == 0) {
+		percentage = 60;
+	} else if (argc == 1) {
+		nextarg = 1;
+		diag = kdbgetaddrarg(argc, argv, &nextarg, &percentage, &offset, NULL);
+		if (diag)
+			return diag;
+	} else {
+		return KDB_ARGCOUNT;
+	}
+	percentage = max_t(int, percentage, 1);
+	percentage = min_t(int, percentage, 100);
+	threshold = ((2 * THREAD_SIZE * percentage) / 100 + 1) >> 1;
+	kdb_printf("stackdepth: processes using more than %ld%% (%d bytes) of stack\n",
+		percentage, threshold);
+
+	/* Run the active tasks first, they can have multiple stacks */
+	for (cpu = 0, krp = kdb_running_process; cpu < NR_CPUS; ++cpu, ++krp) {
+		if (!cpu_online(cpu))
+			continue;
+		p = krp->p;
+		esp = krp->arch.sp;
+		over = 0;
+		do {
+			tinfo = (struct thread_info *)(esp & -THREAD_SIZE);
+			used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1));
+			if (used >= threshold)
+				over = 1;
+			esp = tinfo->previous_esp;
+		} while (esp);
+		if (over)
+			kdba_stackdepth1(p, krp->arch.sp);
+	}
+	/* Now the tasks that are not on cpus */
+	kdb_do_each_thread(g, p) {
+		if (kdb_task_has_cpu(p))
+			continue;
+		esp = p->thread.sp;
+		used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1));
+		over = used >= threshold;
+		if (over)
+			kdba_stackdepth1(p, esp);
+	} kdb_while_each_thread(g, p);
+
+	return 0;
+}
+#else /* CONFIG_X86_32 */
+
+/*
+ * kdba_cpu_pda
+ *
+ *	Format a struct cpu_pda
+ *
+ * Inputs:
+ *	argc	argument count
+ *	argv	argument vector
+ * Outputs:
+ *	None.
+ * Returns:
+ *	zero for success, a kdb diagnostic if error
+ * Locking:
+ *	none.
+ * Remarks:
+ *	If no cpu is supplied, it prints the current cpu.  If the cpu is '*'
+ *	then it prints all cpus.
+ */
+
+static int
+kdba_cpu_pda(int argc, const char **argv)
+{
+	int diag, nextarg, all_cpus = 0;
+	long offset = 0;
+	unsigned long cpu;
+	struct x8664_pda *c;
+	static const char *fmtl = "  %-17.17s 0x%lx\n";
+	static const char *fmtd = "  %-17.17s %d\n";
+	static const char *fmtp = "  %-17.17s 0x%p\n";
+
+	if (argc == 0) {
+		cpu = smp_processor_id();
+	} else if (argc == 1) {
+		if (strcmp(argv[1], "*") == 0) {
+			all_cpus = 1;
+			cpu = 0;
+		} else {
+			nextarg = 1;
+			diag = kdbgetaddrarg(argc, argv, &nextarg, &cpu, &offset, NULL);
+			if (diag)
+				return diag;
+		}
+	} else {
+		return KDB_ARGCOUNT;
+	}
+
+	for (; cpu < NR_CPUS; ++cpu) {
+		if (cpu_online(cpu)) {
+			c = cpu_pda(cpu);
+			kdb_printf("struct cpu_pda 0x%p-0x%p\n", c, (unsigned char *)c + sizeof(*c) - 1);
+			kdb_printf(fmtp, "pcurrent", c->pcurrent);
+			kdb_printf(fmtl, "data_offset", c->data_offset);
+			kdb_printf(fmtl, "kernelstack", c->kernelstack);
+			kdb_printf(fmtl, "oldrsp", c->oldrsp);
+			kdb_printf(fmtd, "irqcount", c->irqcount);
+			kdb_printf(fmtd, "cpunumber", c->cpunumber);
+			kdb_printf(fmtp, "irqstackptr", c->irqstackptr);
+			kdb_printf(fmtp, "nodenumber", cpu_to_node(cpu));
+			kdb_printf(fmtd, "__softirq_pending", c->__softirq_pending);
+			kdb_printf(fmtd, "__nmi_count", c->__nmi_count);
+			kdb_printf(fmtd, "mmu_state", c->mmu_state);
+			kdb_printf(fmtp, "active_mm", c->active_mm);
+			kdb_printf(fmtd, "apic_timer_irqs", c->apic_timer_irqs);
+		}
+		if (!all_cpus)
+			break;
+	}
+	return 0;
+}
+
+/*
+ * kdba_entry
+ *
+ *	This is the interface routine between
+ *	the notifier die_chain and kdb
+ */
+static int kdba_entry( struct notifier_block *b, unsigned long val, void *v)
+{
+	struct die_args *args = v;
+	int err, trap, ret = 0;
+	struct pt_regs *regs;
+
+	regs = args->regs;
+	err  = args->err;
+	trap  = args->trapnr;
+	switch (val){
+#ifdef	CONFIG_SMP
+		case DIE_NMI_IPI:
+			ret = kdb_ipi(regs, NULL);
+			break;
+#endif	/* CONFIG_SMP */
+		case DIE_OOPS:
+			ret = kdb(KDB_REASON_OOPS, err, regs);
+			break;
+		case DIE_CALL:
+			ret = kdb(KDB_REASON_ENTER, err, regs);
+			break;
+		case DIE_DEBUG:
+			ret = kdb(KDB_REASON_DEBUG, err, regs);
+			break;
+		case DIE_NMIWATCHDOG:
+			ret = kdb(KDB_REASON_NMI, err, regs);
+			break;
+		case DIE_INT3:
+			 ret = kdb(KDB_REASON_BREAK, err, regs);
+			// falls thru
+		default:
+			break;
+	}
+	return (ret ? NOTIFY_STOP : NOTIFY_DONE);
+}
+
+/*
+ * notifier block for kdb entry
+ */
+static struct notifier_block kdba_notifier = {
+	.notifier_call = kdba_entry
+};
+#endif /* CONFIG_X86_32 */
+
+asmlinkage int kdb_call(void);
+
+/* Executed once on each cpu at startup. */
+void
+kdba_cpu_up(void)
+{
+}
+
+static int __init
+kdba_arch_init(void)
+{
+	set_intr_gate(KDBENTER_VECTOR, kdb_call);
+	return 0;
+}
+
+arch_initcall(kdba_arch_init);
+
+/*
+ * kdba_init
+ *
+ * 	Architecture specific initialization.
+ *
+ * Parameters:
+ *	None.
+ * Returns:
+ *	None.
+ * Locking:
+ *	None.
+ * Remarks:
+ *	None.
+ */
+
+void __init
+kdba_init(void)
+{
+	kdba_arch_init();	/* Need to register KDBENTER_VECTOR early */
+	kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0);
+#ifdef CONFIG_X86_32
+	kdb_register("stackdepth", kdba_stackdepth, "[percentage]", "Print processes using >= stack percentage", 0);
+#else
+	kdb_register("cpu_pda", kdba_cpu_pda, "<cpu>", "Format struct cpu_pda", 0);
+	register_die_notifier(&kdba_notifier);
+#endif
+	return;
+}
+
+/*
+ * kdba_adjust_ip
+ *
+ * 	Architecture specific adjustment of instruction pointer before leaving
+ *	kdb.
+ *
+ * Parameters:
+ *	reason		The reason KDB was invoked
+ *	error		The hardware-defined error code
+ *	regs		The exception frame at time of fault/breakpoint.  If reason
+ *			is SILENT or CPU_UP then regs is NULL, otherwise it should
+ *			always be valid.
+ * Returns:
+ *	None.
+ * Locking:
+ *	None.
+ * Remarks:
+ *	noop on ix86.
+ */
+
+void
+kdba_adjust_ip(kdb_reason_t reason, int error, struct pt_regs *regs)
+{
+	return;
+}
+
+void
+kdba_set_current_task(const struct task_struct *p)
+{
+	kdb_current_task = p;
+	if (kdb_task_has_cpu(p)) {
+		struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p);
+		kdb_current_regs = krp->regs;
+		return;
+	}
+	kdb_current_regs = NULL;
+}
+
+#ifdef CONFIG_X86_32
+/*
+ * asm-i386 uaccess.h supplies __copy_to_user which relies on MMU to
+ * trap invalid addresses in the _xxx fields.  Verify the other address
+ * of the pair is valid by accessing the first and last byte ourselves,
+ * then any access violations should only be caused by the _xxx
+ * addresses,
+ */
+
+int
+kdba_putarea_size(unsigned long to_xxx, void *from, size_t size)
+{
+	mm_segment_t oldfs = get_fs();
+	int r;
+	char c;
+	c = *((volatile char *)from);
+	c = *((volatile char *)from + size - 1);
+
+	if (to_xxx < PAGE_OFFSET) {
+		return kdb_putuserarea_size(to_xxx, from, size);
+	}
+
+	set_fs(KERNEL_DS);
+	r = __copy_to_user_inatomic((void __user *)to_xxx, from, size);
+	set_fs(oldfs);
+	return r;
+}
+
+int
+kdba_getarea_size(void *to, unsigned long from_xxx, size_t size)
+{
+	mm_segment_t oldfs = get_fs();
+	int r;
+	*((volatile char *)to) = '\0';
+	*((volatile char *)to + size - 1) = '\0';
+
+	if (from_xxx < PAGE_OFFSET) {
+		return kdb_getuserarea_size(to, from_xxx, size);
+	}
+
+	set_fs(KERNEL_DS);
+	switch (size) {
+	case 1:
+		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 1);
+		break;
+	case 2:
+		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 2);
+		break;
+	case 4:
+		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 4);
+		break;
+	case 8:
+		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 8);
+		break;
+	default:
+		r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, size);
+		break;
+	}
+	set_fs(oldfs);
+	return r;
+}
+
+int
+kdba_verify_rw(unsigned long addr, size_t size)
+{
+	unsigned char data[size];
+	return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size));
+}
+#endif /* CONFIG_X86_32 */
+
+#ifdef	CONFIG_SMP
+
+#include <mach_ipi.h>
+
+gate_desc save_idt[NR_VECTORS];
+
+void kdba_takeover_vector(int vector)
+{
+	memcpy(&save_idt[vector], &idt_table[vector], sizeof(gate_desc));
+	set_intr_gate(KDB_VECTOR, kdb_interrupt);
+	return;
+}
+
+void kdba_giveback_vector(int vector)
+{
+	native_write_idt_entry(idt_table, vector, &save_idt[vector]);
+	return;
+}
+
+/* When first entering KDB, try a normal IPI.  That reduces backtrace problems
+ * on the other cpus.
+ */
+void
+smp_kdb_stop(void)
+{
+	if (!KDB_FLAG(NOIPI)) {
+		kdba_takeover_vector(KDB_VECTOR);
+		send_IPI_allbutself(KDB_VECTOR);
+	}
+}
+
+/* The normal KDB IPI handler */
+#ifdef CONFIG_X86_64
+asmlinkage
+#endif
+void
+smp_kdb_interrupt(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+	ack_APIC_irq();
+	irq_enter();
+	kdb_ipi(regs, NULL);
+	irq_exit();
+	set_irq_regs(old_regs);
+}
+
+/* Invoked once from kdb_wait_for_cpus when waiting for cpus.  For those cpus
+ * that have not responded to the normal KDB interrupt yet, hit them with an
+ * NMI event.
+ */
+void
+kdba_wait_for_cpus(void)
+{
+	int c;
+	if (KDB_FLAG(CATASTROPHIC))
+		return;
+	kdb_printf("  Sending NMI to non-responding cpus: ");
+	for_each_online_cpu(c) {
+		if (kdb_running_process[c].seqno < kdb_seqno - 1) {
+			kdb_printf(" %d", c);
+			send_IPI_mask(cpumask_of_cpu(c), NMI_VECTOR);
+		}
+	}
+	kdb_printf(".\n");
+}
+
+#endif	/* CONFIG_SMP */

----- End forwarded message -----



More information about the kdb mailing list