kdb
[Top] [All Lists]

[hch@xxxxxxxxxxxxx: Re: [kdb] [PATCH, RFC] merge i386 and x86_64 kdb arc

To: kdb@xxxxxxxxxxx
Subject: [hch@xxxxxxxxxxxxx: Re: [kdb] [PATCH, RFC] merge i386 and x86_64 kdb arch code]
From: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Date: Thu, 25 Dec 2008 04:04:49 -0500
User-agent: Mutt/1.5.18 (2008-05-17)
Should have sent this to the list of course.  Sorry..

----- Forwarded message from Christoph Hellwig <hch@xxxxxxxxxxxxx> -----

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

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@xxxxxxx> 15 May 2006
- */
-
-/* 80386 instruction printer by Pace Willisson (pace@xxxxxxxxxxxxxxx)
-   July 1988
-    modified by John Hassey (hassey@xxxxxxxxxxxxx)
-    x86-64 support added by Jan Hubicka (jh@xxxxxxx)
-    VIA PadLock support by Michal Ludvig (mludvig@xxxxxxx).  */
-
-/* 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@xxxxxxx> 15 May 2006
+ */
+
+/* 80386 instruction printer by Pace Willisson (pace@xxxxxxxxxxxxxxx)
+   July 1988
+    modified by John Hassey (hassey@xxxxxxxxxxxxx)
+    x86-64 support added by Jan Hubicka (jh@xxxxxxx)
+    VIA PadLock support by Michal Ludvig (mludvig@xxxxxxx).  */
+
+/* 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@xxxxxxx> 15 May 2006
- */
-
-/* 80386 instruction printer by Pace Willisson (pace@xxxxxxxxxxxxxxx)
-   July 1988
-    modified by John Hassey (hassey@xxxxxxxxxxxxx)
-    x86-64 support added by Jan Hubicka (jh@xxxxxxx)
-    VIA PadLock support by Michal Ludvig (mludvig@xxxxxxx).  */
-
-/* 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 -----

<Prev in Thread] Current Thread [Next in Thread>
  • [hch@xxxxxxxxxxxxx: Re: [kdb] [PATCH, RFC] merge i386 and x86_64 kdb arch code], Christoph Hellwig <=