Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/ppc/xmon/Makefile b/arch/ppc/xmon/Makefile
new file mode 100644
index 0000000..9aa260b
--- /dev/null
+++ b/arch/ppc/xmon/Makefile
@@ -0,0 +1,8 @@
+# Makefile for xmon
+
+ifdef CONFIG_8xx
+obj-y		:= start_8xx.o
+else
+obj-y		:= start.o
+endif
+obj-y		+= xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
diff --git a/arch/ppc/xmon/adb.c b/arch/ppc/xmon/adb.c
new file mode 100644
index 0000000..e91384d
--- /dev/null
+++ b/arch/ppc/xmon/adb.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include "nonstdio.h"
+#include "privinst.h"
+
+#define scanhex	xmon_scanhex
+#define skipbl	xmon_skipbl
+
+#define ADB_B		(*(volatile unsigned char *)0xf3016000)
+#define ADB_SR		(*(volatile unsigned char *)0xf3017400)
+#define ADB_ACR		(*(volatile unsigned char *)0xf3017600)
+#define ADB_IFR		(*(volatile unsigned char *)0xf3017a00)
+
+static inline void eieio(void) { asm volatile ("eieio" : :); }
+
+#define N_ADB_LOG	1000
+struct adb_log {
+    unsigned char b;
+    unsigned char ifr;
+    unsigned char acr;
+    unsigned int time;
+} adb_log[N_ADB_LOG];
+int n_adb_log;
+
+void
+init_adb_log(void)
+{
+    adb_log[0].b = ADB_B;
+    adb_log[0].ifr = ADB_IFR;
+    adb_log[0].acr = ADB_ACR;
+    adb_log[0].time = get_dec();
+    n_adb_log = 0;
+}
+
+void
+dump_adb_log(void)
+{
+    unsigned t, t0;
+    struct adb_log *ap;
+    int i;
+
+    ap = adb_log;
+    t0 = ap->time;
+    for (i = 0; i <= n_adb_log; ++i, ++ap) {
+	t = t0 - ap->time;
+	printf("b=%x ifr=%x acr=%x at %d.%.7d\n", ap->b, ap->ifr, ap->acr,
+	       t / 1000000000, (t % 1000000000) / 100);
+    }
+}
+
+void
+adb_chklog(void)
+{
+    struct adb_log *ap = &adb_log[n_adb_log + 1];
+
+    ap->b = ADB_B;
+    ap->ifr = ADB_IFR;
+    ap->acr = ADB_ACR;
+    if (ap->b != ap[-1].b || (ap->ifr & 4) != (ap[-1].ifr & 4)
+	|| ap->acr != ap[-1].acr) {
+	ap->time = get_dec();
+	++n_adb_log;
+    }
+}
+
+int
+adb_bitwait(int bmask, int bval, int fmask, int fval)
+{
+    int i;
+    struct adb_log *ap;
+
+    for (i = 10000; i > 0; --i) {
+	adb_chklog();
+	ap = &adb_log[n_adb_log];
+	if ((ap->b & bmask) == bval && (ap->ifr & fmask) == fval)
+	    return 0;
+    }
+    return -1;
+}
+
+int
+adb_wait(void)
+{
+    if (adb_bitwait(0, 0, 4, 4) < 0) {
+	printf("adb: ready wait timeout\n");
+	return -1;
+    }
+    return 0;
+}
+
+void
+adb_readin(void)
+{
+    int i, j;
+    unsigned char d[64];
+
+    if (ADB_B & 8) {
+	printf("ADB_B: %x\n", ADB_B);
+	return;
+    }
+    i = 0;
+    adb_wait();
+    j = ADB_SR;
+    eieio();
+    ADB_B &= ~0x20;
+    eieio();
+    for (;;) {
+	if (adb_wait() < 0)
+	    break;
+	d[i++] = ADB_SR;
+	eieio();
+	if (ADB_B & 8)
+	    break;
+	ADB_B ^= 0x10;
+	eieio();
+    }
+    ADB_B |= 0x30;
+    if (adb_wait() == 0)
+	j = ADB_SR;
+    for (j = 0; j < i; ++j)
+	printf("%.2x ", d[j]);
+    printf("\n");
+}
+
+int
+adb_write(unsigned char *d, int i)
+{
+    int j;
+    unsigned x;
+
+    if ((ADB_B & 8) == 0) {
+	printf("r: ");
+	adb_readin();
+    }
+    for (;;) {
+	ADB_ACR = 0x1c;
+	eieio();
+	ADB_SR = d[0];
+	eieio();
+	ADB_B &= ~0x20;
+	eieio();
+	if (ADB_B & 8)
+	    break;
+	ADB_ACR = 0xc;
+	eieio();
+	ADB_B |= 0x20;
+	eieio();
+	adb_readin();
+    }
+    adb_wait();
+    for (j = 1; j < i; ++j) {
+	ADB_SR = d[j];
+	eieio();
+	ADB_B ^= 0x10;
+	eieio();
+	if (adb_wait() < 0)
+	    break;
+    }
+    ADB_ACR = 0xc;
+    eieio();
+    x = ADB_SR;
+    eieio();
+    ADB_B |= 0x30;
+    return j;
+}
+
+void
+adbcmds(void)
+{
+    char cmd;
+    unsigned rtcu, rtcl, dec, pdec, x;
+    int i, j;
+    unsigned char d[64];
+
+    cmd = skipbl();
+    switch (cmd) {
+    case 't':
+	for (;;) {
+	    rtcl = get_rtcl();
+	    rtcu = get_rtcu();
+	    dec = get_dec();
+	    printf("rtc u=%u l=%u dec=%x (%d = %d.%.7d)\n",
+		   rtcu, rtcl, dec, pdec - dec, (pdec - dec) / 1000000000,
+		   ((pdec - dec) % 1000000000) / 100);
+	    pdec = dec;
+	    if (cmd == 'x')
+		break;
+	    while (xmon_read(stdin, &cmd, 1) != 1)
+		;
+	}
+	break;
+    case 'r':
+	init_adb_log();
+	while (adb_bitwait(8, 0, 0, 0) == 0)
+	    adb_readin();
+	break;
+    case 'w':
+	i = 0;
+	while (scanhex(&x))
+	    d[i++] = x;
+	init_adb_log();
+	j = adb_write(d, i);
+	printf("sent %d bytes\n", j);
+	while (adb_bitwait(8, 0, 0, 0) == 0)
+	    adb_readin();
+	break;
+    case 'l':
+	dump_adb_log();
+	break;
+    }
+}
diff --git a/arch/ppc/xmon/ansidecl.h b/arch/ppc/xmon/ansidecl.h
new file mode 100644
index 0000000..c9b9f09
--- /dev/null
+++ b/arch/ppc/xmon/ansidecl.h
@@ -0,0 +1,141 @@
+/* ANSI and traditional C compatibility macros
+   Copyright 1991, 1992 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* ANSI and traditional C compatibility macros
+
+   ANSI C is assumed if __STDC__ is #defined.
+
+   Macro	ANSI C definition	Traditional C definition
+   -----	---- - ----------	----------- - ----------
+   PTR		`void *'		`char *'
+   LONG_DOUBLE	`long double'		`double'
+   VOLATILE	`volatile'		`'
+   SIGNED	`signed'		`'
+   PTRCONST	`void *const'		`char *'
+   ANSI_PROTOTYPES  1			not defined
+
+   CONST is also defined, but is obsolete.  Just use const.
+
+   DEFUN (name, arglist, args)
+
+	Defines function NAME.
+
+	ARGLIST lists the arguments, separated by commas and enclosed in
+	parentheses.  ARGLIST becomes the argument list in traditional C.
+
+	ARGS list the arguments with their types.  It becomes a prototype in
+	ANSI C, and the type declarations in traditional C.  Arguments should
+	be separated with `AND'.  For functions with a variable number of
+	arguments, the last thing listed should be `DOTS'.
+
+   DEFUN_VOID (name)
+
+	Defines a function NAME, which takes no arguments.
+
+   obsolete --     EXFUN (name, (prototype))	-- obsolete.
+
+	Replaced by PARAMS.  Do not use; will disappear someday soon.
+	Was used in external function declarations.
+	In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
+	parentheses).  In traditional C it is `NAME()'.
+	For a function that takes no arguments, PROTOTYPE should be `(void)'.
+
+    PARAMS ((args))
+
+	We could use the EXFUN macro to handle prototype declarations, but
+	the name is misleading and the result is ugly.  So we just define a
+	simple macro to handle the parameter lists, as in:
+
+	      static int foo PARAMS ((int, char));
+
+	This produces:  `static int foo();' or `static int foo (int, char);'
+
+	EXFUN would have done it like this:
+
+	      static int EXFUN (foo, (int, char));
+
+	but the function is not external...and it's hard to visually parse
+	the function name out of the mess.   EXFUN should be considered
+	obsolete; new code should be written to use PARAMS.
+
+    For example:
+	extern int printf PARAMS ((CONST char *format DOTS));
+	int DEFUN(fprintf, (stream, format),
+		  FILE *stream AND CONST char *format DOTS) { ... }
+	void DEFUN_VOID(abort) { ... }
+*/
+
+#ifndef	_ANSIDECL_H
+
+#define	_ANSIDECL_H	1
+
+
+/* Every source file includes this file,
+   so they will all get the switch for lint.  */
+/* LINTLIBRARY */
+
+
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32)
+/* All known AIX compilers implement these things (but don't always
+   define __STDC__).  The RISC/OS MIPS compiler defines these things
+   in SVR4 mode, but does not define __STDC__.  */
+
+#define	PTR		void *
+#define	PTRCONST	void *CONST
+#define	LONG_DOUBLE	long double
+
+#define	AND		,
+#define	NOARGS		void
+#define	CONST		const
+#define	VOLATILE	volatile
+#define	SIGNED		signed
+#define	DOTS		, ...
+
+#define	EXFUN(name, proto)		name proto
+#define	DEFUN(name, arglist, args)	name(args)
+#define	DEFUN_VOID(name)		name(void)
+
+#define PROTO(type, name, arglist)	type name arglist
+#define PARAMS(paramlist)		paramlist
+#define ANSI_PROTOTYPES			1
+
+#else	/* Not ANSI C.  */
+
+#define	PTR		char *
+#define	PTRCONST	PTR
+#define	LONG_DOUBLE	double
+
+#define	AND		;
+#define	NOARGS
+#define	CONST
+#ifndef const /* some systems define it in header files for non-ansi mode */
+#define	const
+#endif
+#define	VOLATILE
+#define	SIGNED
+#define	DOTS
+
+#define	EXFUN(name, proto)		name()
+#define	DEFUN(name, arglist, args)	name arglist args;
+#define	DEFUN_VOID(name)		name()
+#define PROTO(type, name, arglist) type name ()
+#define PARAMS(paramlist)		()
+
+#endif	/* ANSI C.  */
+
+#endif	/* ansidecl.h	*/
diff --git a/arch/ppc/xmon/nonstdio.h b/arch/ppc/xmon/nonstdio.h
new file mode 100644
index 0000000..0240bc5
--- /dev/null
+++ b/arch/ppc/xmon/nonstdio.h
@@ -0,0 +1,22 @@
+typedef int	FILE;
+extern FILE *xmon_stdin, *xmon_stdout;
+#define EOF	(-1)
+#define stdin	xmon_stdin
+#define stdout	xmon_stdout
+#define printf	xmon_printf
+#define fprintf	xmon_fprintf
+#define fputs	xmon_fputs
+#define fgets	xmon_fgets
+#define putchar	xmon_putchar
+#define getchar	xmon_getchar
+#define putc	xmon_putc
+#define getc	xmon_getc
+#define fopen(n, m)	NULL
+#define fflush(f)	do {} while (0)
+#define fclose(f)	do {} while (0)
+extern char *fgets(char *, int, void *);
+extern void xmon_fprintf(void *, const char *, ...);
+extern void xmon_sprintf(char *, const char *, ...);
+extern void xmon_puts(char*);
+
+#define perror(s)	printf("%s: no files!\n", (s))
diff --git a/arch/ppc/xmon/ppc-dis.c b/arch/ppc/xmon/ppc-dis.c
new file mode 100644
index 0000000..798ac1a
--- /dev/null
+++ b/arch/ppc/xmon/ppc-dis.c
@@ -0,0 +1,190 @@
+/* ppc-dis.c -- Disassemble PowerPC instructions
+   Copyright 1994 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "nonstdio.h"
+#include "ansidecl.h"
+#include "ppc.h"
+
+static int print_insn_powerpc PARAMS ((FILE *, unsigned long insn,
+				       unsigned memaddr, int dialect));
+
+extern void print_address PARAMS((unsigned memaddr));
+
+/* Print a big endian PowerPC instruction.  For convenience, also
+   disassemble instructions supported by the Motorola PowerPC 601.  */
+
+int
+print_insn_big_powerpc (FILE *out, unsigned long insn, unsigned memaddr)
+{
+  return print_insn_powerpc (out, insn, memaddr,
+			     PPC_OPCODE_PPC | PPC_OPCODE_601);
+}
+
+/* Print a PowerPC or POWER instruction.  */
+
+static int
+print_insn_powerpc (FILE *out, unsigned long insn, unsigned memaddr,
+		    int dialect)
+{
+  const struct powerpc_opcode *opcode;
+  const struct powerpc_opcode *opcode_end;
+  unsigned long op;
+
+  /* Get the major opcode of the instruction.  */
+  op = PPC_OP (insn);
+
+  /* Find the first match in the opcode table.  We could speed this up
+     a bit by doing a binary search on the major opcode.  */
+  opcode_end = powerpc_opcodes + powerpc_num_opcodes;
+  for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
+    {
+      unsigned long table_op;
+      const unsigned char *opindex;
+      const struct powerpc_operand *operand;
+      int invalid;
+      int need_comma;
+      int need_paren;
+
+      table_op = PPC_OP (opcode->opcode);
+      if (op < table_op)
+		break;
+      if (op > table_op)
+		continue;
+
+      if ((insn & opcode->mask) != opcode->opcode
+	  || (opcode->flags & dialect) == 0)
+		continue;
+
+      /* Make two passes over the operands.  First see if any of them
+		 have extraction functions, and, if they do, make sure the
+		 instruction is valid.  */
+      invalid = 0;
+      for (opindex = opcode->operands; *opindex != 0; opindex++)
+		{
+		  operand = powerpc_operands + *opindex;
+		  if (operand->extract)
+		    (*operand->extract) (insn, &invalid);
+		}
+      if (invalid)
+		continue;
+
+      /* The instruction is valid.  */
+      fprintf(out, "%s", opcode->name);
+      if (opcode->operands[0] != 0)
+		fprintf(out, "\t");
+
+      /* Now extract and print the operands.  */
+      need_comma = 0;
+      need_paren = 0;
+      for (opindex = opcode->operands; *opindex != 0; opindex++)
+		{
+		  long value;
+
+		  operand = powerpc_operands + *opindex;
+
+		  /* Operands that are marked FAKE are simply ignored.  We
+		     already made sure that the extract function considered
+		     the instruction to be valid.  */
+		  if ((operand->flags & PPC_OPERAND_FAKE) != 0)
+		    continue;
+
+		  /* Extract the value from the instruction.  */
+		  if (operand->extract)
+		    value = (*operand->extract) (insn, (int *) 0);
+		  else
+		    {
+		      value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+		      if ((operand->flags & PPC_OPERAND_SIGNED) != 0
+			  && (value & (1 << (operand->bits - 1))) != 0)
+			value -= 1 << operand->bits;
+		    }
+
+		  /* If the operand is optional, and the value is zero, don't
+		     print anything.  */
+		  if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+		      && (operand->flags & PPC_OPERAND_NEXT) == 0
+		      && value == 0)
+		    continue;
+
+		  if (need_comma)
+		    {
+		      fprintf(out, ",");
+		      need_comma = 0;
+		    }
+
+		  /* Print the operand as directed by the flags.  */
+		  if ((operand->flags & PPC_OPERAND_GPR) != 0)
+		    fprintf(out, "r%ld", value);
+		  else if ((operand->flags & PPC_OPERAND_FPR) != 0)
+		    fprintf(out, "f%ld", value);
+		  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
+		    print_address (memaddr + value);
+		  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+		    print_address (value & 0xffffffff);
+		  else if ((operand->flags & PPC_OPERAND_CR) == 0
+			   || (dialect & PPC_OPCODE_PPC) == 0)
+		    fprintf(out, "%ld", value);
+		  else
+		    {
+		      if (operand->bits == 3)
+				fprintf(out, "cr%d", value);
+		      else
+			{
+			  static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
+			  int cr;
+			  int cc;
+
+			  cr = value >> 2;
+			  if (cr != 0)
+			    fprintf(out, "4*cr%d", cr);
+			  cc = value & 3;
+			  if (cc != 0)
+			    {
+			      if (cr != 0)
+					fprintf(out, "+");
+			      fprintf(out, "%s", cbnames[cc]);
+			    }
+			}
+	    }
+
+	  if (need_paren)
+	    {
+	      fprintf(out, ")");
+	      need_paren = 0;
+	    }
+
+	  if ((operand->flags & PPC_OPERAND_PARENS) == 0)
+	    need_comma = 1;
+	  else
+	    {
+	      fprintf(out, "(");
+	      need_paren = 1;
+	    }
+	}
+
+      /* We have found and printed an instruction; return.  */
+      return 4;
+    }
+
+  /* We could not find a match.  */
+  fprintf(out, ".long 0x%lx", insn);
+
+  return 4;
+}
diff --git a/arch/ppc/xmon/ppc-opc.c b/arch/ppc/xmon/ppc-opc.c
new file mode 100644
index 0000000..533a6c9
--- /dev/null
+++ b/arch/ppc/xmon/ppc-opc.c
@@ -0,0 +1,2721 @@
+/* ppc-opc.c -- PowerPC opcode list
+   Copyright 1994 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <linux/posix_types.h>
+#include "ansidecl.h"
+#include "ppc.h"
+
+/* This file holds the PowerPC opcode table.  The opcode table
+   includes almost all of the extended instruction mnemonics.  This
+   permits the disassembler to use them, and simplifies the assembler
+   logic, at the cost of increasing the table size.  The table is
+   strictly constant data, so the compiler should be able to put it in
+   the .text section.
+
+   This file also holds the operand table.  All knowledge about
+   inserting operands into instructions and vice-versa is kept in this
+   file.  */
+
+/* Local insertion and extraction functions.  */
+
+static unsigned long insert_bat PARAMS ((unsigned long, long, const char **));
+static long extract_bat PARAMS ((unsigned long, int *));
+static unsigned long insert_bba PARAMS ((unsigned long, long, const char **));
+static long extract_bba PARAMS ((unsigned long, int *));
+static unsigned long insert_bd PARAMS ((unsigned long, long, const char **));
+static long extract_bd PARAMS ((unsigned long, int *));
+static unsigned long insert_bdm PARAMS ((unsigned long, long, const char **));
+static long extract_bdm PARAMS ((unsigned long, int *));
+static unsigned long insert_bdp PARAMS ((unsigned long, long, const char **));
+static long extract_bdp PARAMS ((unsigned long, int *));
+static unsigned long insert_bo PARAMS ((unsigned long, long, const char **));
+static long extract_bo PARAMS ((unsigned long, int *));
+static unsigned long insert_boe PARAMS ((unsigned long, long, const char **));
+static long extract_boe PARAMS ((unsigned long, int *));
+static unsigned long insert_ds PARAMS ((unsigned long, long, const char **));
+static long extract_ds PARAMS ((unsigned long, int *));
+static unsigned long insert_li PARAMS ((unsigned long, long, const char **));
+static long extract_li PARAMS ((unsigned long, int *));
+static unsigned long insert_mbe PARAMS ((unsigned long, long, const char **));
+static long extract_mbe PARAMS ((unsigned long, int *));
+static unsigned long insert_mb6 PARAMS ((unsigned long, long, const char **));
+static long extract_mb6 PARAMS ((unsigned long, int *));
+static unsigned long insert_nb PARAMS ((unsigned long, long, const char **));
+static long extract_nb PARAMS ((unsigned long, int *));
+static unsigned long insert_nsi PARAMS ((unsigned long, long, const char **));
+static long extract_nsi PARAMS ((unsigned long, int *));
+static unsigned long insert_ral PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_ram PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_ras PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_rbs PARAMS ((unsigned long, long, const char **));
+static long extract_rbs PARAMS ((unsigned long, int *));
+static unsigned long insert_sh6 PARAMS ((unsigned long, long, const char **));
+static long extract_sh6 PARAMS ((unsigned long, int *));
+static unsigned long insert_spr PARAMS ((unsigned long, long, const char **));
+static long extract_spr PARAMS ((unsigned long, int *));
+static unsigned long insert_tbr PARAMS ((unsigned long, long, const char **));
+static long extract_tbr PARAMS ((unsigned long, int *));
+
+/* The operands table.
+
+   The fields are bits, shift, signed, insert, extract, flags.  */
+
+const struct powerpc_operand powerpc_operands[] =
+{
+  /* The zero index is used to indicate the end of the list of
+     operands.  */
+#define UNUSED (0)
+  { 0, 0, NULL, NULL, 0 },
+
+  /* The BA field in an XL form instruction.  */
+#define BA (1)
+#define BA_MASK (0x1f << 16)
+  { 5, 16, NULL, NULL, PPC_OPERAND_CR },
+
+  /* The BA field in an XL form instruction when it must be the same
+     as the BT field in the same instruction.  */
+#define BAT (2)
+  { 5, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE },
+
+  /* The BB field in an XL form instruction.  */
+#define BB (3)
+#define BB_MASK (0x1f << 11)
+  { 5, 11, NULL, NULL, PPC_OPERAND_CR },
+
+  /* The BB field in an XL form instruction when it must be the same
+     as the BA field in the same instruction.  */
+#define BBA (4)
+  { 5, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE },
+
+  /* The BD field in a B form instruction.  The lower two bits are
+     forced to zero.  */
+#define BD (5)
+  { 16, 0, insert_bd, extract_bd, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when absolute addressing is
+     used.  */
+#define BDA (6)
+  { 16, 0, insert_bd, extract_bd, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when the - modifier is used.
+     This sets the y bit of the BO field appropriately.  */
+#define BDM (7)
+  { 16, 0, insert_bdm, extract_bdm,
+      PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when the - modifier is used
+     and absolute address is used.  */
+#define BDMA (8)
+  { 16, 0, insert_bdm, extract_bdm,
+      PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when the + modifier is used.
+     This sets the y bit of the BO field appropriately.  */
+#define BDP (9)
+  { 16, 0, insert_bdp, extract_bdp,
+      PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when the + modifier is used
+     and absolute addressing is used.  */
+#define BDPA (10)
+  { 16, 0, insert_bdp, extract_bdp,
+      PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+  /* The BF field in an X or XL form instruction.  */
+#define BF (11)
+  { 3, 23, NULL, NULL, PPC_OPERAND_CR },
+
+  /* An optional BF field.  This is used for comparison instructions,
+     in which an omitted BF field is taken as zero.  */
+#define OBF (12)
+  { 3, 23, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+
+  /* The BFA field in an X or XL form instruction.  */
+#define BFA (13)
+  { 3, 18, NULL, NULL, PPC_OPERAND_CR },
+
+  /* The BI field in a B form or XL form instruction.  */
+#define BI (14)
+#define BI_MASK (0x1f << 16)
+  { 5, 16, NULL, NULL, PPC_OPERAND_CR },
+
+  /* The BO field in a B form instruction.  Certain values are
+     illegal.  */
+#define BO (15)
+#define BO_MASK (0x1f << 21)
+  { 5, 21, insert_bo, extract_bo, 0 },
+
+  /* The BO field in a B form instruction when the + or - modifier is
+     used.  This is like the BO field, but it must be even.  */
+#define BOE (16)
+  { 5, 21, insert_boe, extract_boe, 0 },
+
+  /* The BT field in an X or XL form instruction.  */
+#define BT (17)
+  { 5, 21, NULL, NULL, PPC_OPERAND_CR },
+
+  /* The condition register number portion of the BI field in a B form
+     or XL form instruction.  This is used for the extended
+     conditional branch mnemonics, which set the lower two bits of the
+     BI field.  This field is optional.  */
+#define CR (18)
+  { 3, 18, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+
+  /* The D field in a D form instruction.  This is a displacement off
+     a register, and implies that the next operand is a register in
+     parentheses.  */
+#define D (19)
+  { 16, 0, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+
+  /* The DS field in a DS form instruction.  This is like D, but the
+     lower two bits are forced to zero.  */
+#define DS (20)
+  { 16, 0, insert_ds, extract_ds, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+
+  /* The FL1 field in a POWER SC form instruction.  */
+#define FL1 (21)
+  { 4, 12, NULL, NULL, 0 },
+
+  /* The FL2 field in a POWER SC form instruction.  */
+#define FL2 (22)
+  { 3, 2, NULL, NULL, 0 },
+
+  /* The FLM field in an XFL form instruction.  */
+#define FLM (23)
+  { 8, 17, NULL, NULL, 0 },
+
+  /* The FRA field in an X or A form instruction.  */
+#define FRA (24)
+#define FRA_MASK (0x1f << 16)
+  { 5, 16, NULL, NULL, PPC_OPERAND_FPR },
+
+  /* The FRB field in an X or A form instruction.  */
+#define FRB (25)
+#define FRB_MASK (0x1f << 11)
+  { 5, 11, NULL, NULL, PPC_OPERAND_FPR },
+
+  /* The FRC field in an A form instruction.  */
+#define FRC (26)
+#define FRC_MASK (0x1f << 6)
+  { 5, 6, NULL, NULL, PPC_OPERAND_FPR },
+
+  /* The FRS field in an X form instruction or the FRT field in a D, X
+     or A form instruction.  */
+#define FRS (27)
+#define FRT (FRS)
+  { 5, 21, NULL, NULL, PPC_OPERAND_FPR },
+
+  /* The FXM field in an XFX instruction.  */
+#define FXM (28)
+#define FXM_MASK (0xff << 12)
+  { 8, 12, NULL, NULL, 0 },
+
+  /* The L field in a D or X form instruction.  */
+#define L (29)
+  { 1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
+
+  /* The LEV field in a POWER SC form instruction.  */
+#define LEV (30)
+  { 7, 5, NULL, NULL, 0 },
+
+  /* The LI field in an I form instruction.  The lower two bits are
+     forced to zero.  */
+#define LI (31)
+  { 26, 0, insert_li, extract_li, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+  /* The LI field in an I form instruction when used as an absolute
+     address.  */
+#define LIA (32)
+  { 26, 0, insert_li, extract_li, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+  /* The MB field in an M form instruction.  */
+#define MB (33)
+#define MB_MASK (0x1f << 6)
+  { 5, 6, NULL, NULL, 0 },
+
+  /* The ME field in an M form instruction.  */
+#define ME (34)
+#define ME_MASK (0x1f << 1)
+  { 5, 1, NULL, NULL, 0 },
+
+  /* The MB and ME fields in an M form instruction expressed a single
+     operand which is a bitmask indicating which bits to select.  This
+     is a two operand form using PPC_OPERAND_NEXT.  See the
+     description in opcode/ppc.h for what this means.  */
+#define MBE (35)
+  { 5, 6, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
+  { 32, 0, insert_mbe, extract_mbe, 0 },
+
+  /* The MB or ME field in an MD or MDS form instruction.  The high
+     bit is wrapped to the low end.  */
+#define MB6 (37)
+#define ME6 (MB6)
+#define MB6_MASK (0x3f << 5)
+  { 6, 5, insert_mb6, extract_mb6, 0 },
+
+  /* The NB field in an X form instruction.  The value 32 is stored as
+     0.  */
+#define NB (38)
+  { 6, 11, insert_nb, extract_nb, 0 },
+
+  /* The NSI field in a D form instruction.  This is the same as the
+     SI field, only negated.  */
+#define NSI (39)
+  { 16, 0, insert_nsi, extract_nsi,
+      PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
+
+  /* The RA field in an D, DS, X, XO, M, or MDS form instruction.  */
+#define RA (40)
+#define RA_MASK (0x1f << 16)
+  { 5, 16, NULL, NULL, PPC_OPERAND_GPR },
+
+  /* The RA field in a D or X form instruction which is an updating
+     load, which means that the RA field may not be zero and may not
+     equal the RT field.  */
+#define RAL (41)
+  { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR },
+
+  /* The RA field in an lmw instruction, which has special value
+     restrictions.  */
+#define RAM (42)
+  { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR },
+
+  /* The RA field in a D or X form instruction which is an updating
+     store or an updating floating point load, which means that the RA
+     field may not be zero.  */
+#define RAS (43)
+  { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR },
+
+  /* The RB field in an X, XO, M, or MDS form instruction.  */
+#define RB (44)
+#define RB_MASK (0x1f << 11)
+  { 5, 11, NULL, NULL, PPC_OPERAND_GPR },
+
+  /* The RB field in an X form instruction when it must be the same as
+     the RS field in the instruction.  This is used for extended
+     mnemonics like mr.  */
+#define RBS (45)
+  { 5, 1, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
+
+  /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
+     instruction or the RT field in a D, DS, X, XFX or XO form
+     instruction.  */
+#define RS (46)
+#define RT (RS)
+#define RT_MASK (0x1f << 21)
+  { 5, 21, NULL, NULL, PPC_OPERAND_GPR },
+
+  /* The SH field in an X or M form instruction.  */
+#define SH (47)
+#define SH_MASK (0x1f << 11)
+  { 5, 11, NULL, NULL, 0 },
+
+  /* The SH field in an MD form instruction.  This is split.  */
+#define SH6 (48)
+#define SH6_MASK ((0x1f << 11) | (1 << 1))
+  { 6, 1, insert_sh6, extract_sh6, 0 },
+
+  /* The SI field in a D form instruction.  */
+#define SI (49)
+  { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED },
+
+  /* The SI field in a D form instruction when we accept a wide range
+     of positive values.  */
+#define SISIGNOPT (50)
+  { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT },
+
+  /* The SPR field in an XFX form instruction.  This is flipped--the
+     lower 5 bits are stored in the upper 5 and vice- versa.  */
+#define SPR (51)
+#define SPR_MASK (0x3ff << 11)
+  { 10, 11, insert_spr, extract_spr, 0 },
+
+  /* The BAT index number in an XFX form m[ft]ibat[lu] instruction.  */
+#define SPRBAT (52)
+#define SPRBAT_MASK (0x3 << 17)
+  { 2, 17, NULL, NULL, 0 },
+
+  /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
+#define SPRG (53)
+#define SPRG_MASK (0x3 << 16)
+  { 2, 16, NULL, NULL, 0 },
+
+  /* The SR field in an X form instruction.  */
+#define SR (54)
+  { 4, 16, NULL, NULL, 0 },
+
+  /* The SV field in a POWER SC form instruction.  */
+#define SV (55)
+  { 14, 2, NULL, NULL, 0 },
+
+  /* The TBR field in an XFX form instruction.  This is like the SPR
+     field, but it is optional.  */
+#define TBR (56)
+  { 10, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
+
+  /* The TO field in a D or X form instruction.  */
+#define TO (57)
+#define TO_MASK (0x1f << 21)
+  { 5, 21, NULL, NULL, 0 },
+
+  /* The U field in an X form instruction.  */
+#define U (58)
+  { 4, 12, NULL, NULL, 0 },
+
+  /* The UI field in a D form instruction.  */
+#define UI (59)
+  { 16, 0, NULL, NULL, 0 },
+};
+
+/* The functions used to insert and extract complicated operands.  */
+
+/* The BA field in an XL form instruction when it must be the same as
+   the BT field in the same instruction.  This operand is marked FAKE.
+   The insertion function just copies the BT field into the BA field,
+   and the extraction function just checks that the fields are the
+   same.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bat(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | (((insn >> 21) & 0x1f) << 16);
+}
+
+static long
+extract_bat(unsigned long insn, int *invalid)
+{
+  if (invalid != (int *) NULL
+      && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
+    *invalid = 1;
+  return 0;
+}
+
+/* The BB field in an XL form instruction when it must be the same as
+   the BA field in the same instruction.  This operand is marked FAKE.
+   The insertion function just copies the BA field into the BB field,
+   and the extraction function just checks that the fields are the
+   same.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bba(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | (((insn >> 16) & 0x1f) << 11);
+}
+
+static long
+extract_bba(unsigned long insn, int *invalid)
+{
+  if (invalid != (int *) NULL
+      && ((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f))
+    *invalid = 1;
+  return 0;
+}
+
+/* The BD field in a B form instruction.  The lower two bits are
+   forced to zero.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bd(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | (value & 0xfffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_bd(unsigned long insn, int *invalid)
+{
+  if ((insn & 0x8000) != 0)
+    return (insn & 0xfffc) - 0x10000;
+  else
+    return insn & 0xfffc;
+}
+
+/* The BD field in a B form instruction when the - modifier is used.
+   This modifier means that the branch is not expected to be taken.
+   We must set the y bit of the BO field to 1 if the offset is
+   negative.  When extracting, we require that the y bit be 1 and that
+   the offset be positive, since if the y bit is 0 we just want to
+   print the normal form of the instruction.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bdm(unsigned long insn, long value, const char **errmsg)
+{
+  if ((value & 0x8000) != 0)
+    insn |= 1 << 21;
+  return insn | (value & 0xfffc);
+}
+
+static long
+extract_bdm(unsigned long insn, int *invalid)
+{
+  if (invalid != (int *) NULL
+      && ((insn & (1 << 21)) == 0
+	  || (insn & (1 << 15)) == 0))
+    *invalid = 1;
+  if ((insn & 0x8000) != 0)
+    return (insn & 0xfffc) - 0x10000;
+  else
+    return insn & 0xfffc;
+}
+
+/* The BD field in a B form instruction when the + modifier is used.
+   This is like BDM, above, except that the branch is expected to be
+   taken.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bdp(unsigned long insn, long value, const char **errmsg)
+{
+  if ((value & 0x8000) == 0)
+    insn |= 1 << 21;
+  return insn | (value & 0xfffc);
+}
+
+static long
+extract_bdp(unsigned long insn, int *invalid)
+{
+  if (invalid != (int *) NULL
+      && ((insn & (1 << 21)) == 0
+	  || (insn & (1 << 15)) != 0))
+    *invalid = 1;
+  if ((insn & 0x8000) != 0)
+    return (insn & 0xfffc) - 0x10000;
+  else
+    return insn & 0xfffc;
+}
+
+/* Check for legal values of a BO field.  */
+
+static int
+valid_bo (long value)
+{
+  /* Certain encodings have bits that are required to be zero.  These
+     are (z must be zero, y may be anything):
+         001zy
+	 011zy
+	 1z00y
+	 1z01y
+	 1z1zz
+     */
+  switch (value & 0x14)
+    {
+    default:
+    case 0:
+      return 1;
+    case 0x4:
+      return (value & 0x2) == 0;
+    case 0x10:
+      return (value & 0x8) == 0;
+    case 0x14:
+      return value == 0x14;
+    }
+}
+
+/* The BO field in a B form instruction.  Warn about attempts to set
+   the field to an illegal value.  */
+
+static unsigned long
+insert_bo(unsigned long insn, long value, const char **errmsg)
+{
+  if (errmsg != (const char **) NULL
+      && ! valid_bo (value))
+    *errmsg = "invalid conditional option";
+  return insn | ((value & 0x1f) << 21);
+}
+
+static long
+extract_bo(unsigned long insn, int *invalid)
+{
+  long value;
+
+  value = (insn >> 21) & 0x1f;
+  if (invalid != (int *) NULL
+      && ! valid_bo (value))
+    *invalid = 1;
+  return value;
+}
+
+/* The BO field in a B form instruction when the + or - modifier is
+   used.  This is like the BO field, but it must be even.  When
+   extracting it, we force it to be even.  */
+
+static unsigned long
+insert_boe(unsigned long insn, long value, const char **errmsg)
+{
+  if (errmsg != (const char **) NULL)
+    {
+      if (! valid_bo (value))
+	*errmsg = "invalid conditional option";
+      else if ((value & 1) != 0)
+	*errmsg = "attempt to set y bit when using + or - modifier";
+    }
+  return insn | ((value & 0x1f) << 21);
+}
+
+static long
+extract_boe(unsigned long insn, int *invalid)
+{
+  long value;
+
+  value = (insn >> 21) & 0x1f;
+  if (invalid != (int *) NULL
+      && ! valid_bo (value))
+    *invalid = 1;
+  return value & 0x1e;
+}
+
+/* The DS field in a DS form instruction.  This is like D, but the
+   lower two bits are forced to zero.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_ds(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | (value & 0xfffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_ds(unsigned long insn, int *invalid)
+{
+  if ((insn & 0x8000) != 0)
+    return (insn & 0xfffc) - 0x10000;
+  else
+    return insn & 0xfffc;
+}
+
+/* The LI field in an I form instruction.  The lower two bits are
+   forced to zero.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_li(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | (value & 0x3fffffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_li(unsigned long insn, int *invalid)
+{
+  if ((insn & 0x2000000) != 0)
+    return (insn & 0x3fffffc) - 0x4000000;
+  else
+    return insn & 0x3fffffc;
+}
+
+/* The MB and ME fields in an M form instruction expressed as a single
+   operand which is itself a bitmask.  The extraction function always
+   marks it as invalid, since we never want to recognize an
+   instruction which uses a field of this type.  */
+
+static unsigned long
+insert_mbe(unsigned long insn, long value, const char **errmsg)
+{
+  unsigned long uval;
+  int mb, me;
+
+  uval = value;
+
+  if (uval == 0)
+    {
+      if (errmsg != (const char **) NULL)
+	*errmsg = "illegal bitmask";
+      return insn;
+    }
+
+  me = 31;
+  while ((uval & 1) == 0)
+    {
+      uval >>= 1;
+      --me;
+    }
+
+  mb = me;
+  uval >>= 1;
+  while ((uval & 1) != 0)
+    {
+      uval >>= 1;
+      --mb;
+    }
+
+  if (uval != 0)
+    {
+      if (errmsg != (const char **) NULL)
+	*errmsg = "illegal bitmask";
+    }
+
+  return insn | (mb << 6) | (me << 1);
+}
+
+static long
+extract_mbe(unsigned long insn, int *invalid)
+{
+  long ret;
+  int mb, me;
+  int i;
+
+  if (invalid != (int *) NULL)
+    *invalid = 1;
+
+  ret = 0;
+  mb = (insn >> 6) & 0x1f;
+  me = (insn >> 1) & 0x1f;
+  for (i = mb; i < me; i++)
+    ret |= 1 << (31 - i);
+  return ret;
+}
+
+/* The MB or ME field in an MD or MDS form instruction.  The high bit
+   is wrapped to the low end.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_mb6(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | ((value & 0x1f) << 6) | (value & 0x20);
+}
+
+/*ARGSUSED*/
+static long
+extract_mb6(unsigned long insn, int *invalid)
+{
+  return ((insn >> 6) & 0x1f) | (insn & 0x20);
+}
+
+/* The NB field in an X form instruction.  The value 32 is stored as
+   0.  */
+
+static unsigned long
+insert_nb(unsigned long insn, long value, const char **errmsg)
+{
+  if (value < 0 || value > 32)
+    *errmsg = "value out of range";
+  if (value == 32)
+    value = 0;
+  return insn | ((value & 0x1f) << 11);
+}
+
+/*ARGSUSED*/
+static long
+extract_nb(unsigned long insn, int *invalid)
+{
+  long ret;
+
+  ret = (insn >> 11) & 0x1f;
+  if (ret == 0)
+    ret = 32;
+  return ret;
+}
+
+/* The NSI field in a D form instruction.  This is the same as the SI
+   field, only negated.  The extraction function always marks it as
+   invalid, since we never want to recognize an instruction which uses
+   a field of this type.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_nsi(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | ((- value) & 0xffff);
+}
+
+static long
+extract_nsi(unsigned long insn, int *invalid)
+{
+  if (invalid != (int *) NULL)
+    *invalid = 1;
+  if ((insn & 0x8000) != 0)
+    return - ((insn & 0xffff) - 0x10000);
+  else
+    return - (insn & 0xffff);
+}
+
+/* The RA field in a D or X form instruction which is an updating
+   load, which means that the RA field may not be zero and may not
+   equal the RT field.  */
+
+static unsigned long
+insert_ral(unsigned long insn, long value, const char **errmsg)
+{
+  if (value == 0
+      || value == ((insn >> 21) & 0x1f))
+    *errmsg = "invalid register operand when updating";
+  return insn | ((value & 0x1f) << 16);
+}
+
+/* The RA field in an lmw instruction, which has special value
+   restrictions.  */
+
+static unsigned long
+insert_ram(unsigned long insn, long value, const char **errmsg)
+{
+  if (value >= ((insn >> 21) & 0x1f))
+    *errmsg = "index register in load range";
+  return insn | ((value & 0x1f) << 16);
+}
+
+/* The RA field in a D or X form instruction which is an updating
+   store or an updating floating point load, which means that the RA
+   field may not be zero.  */
+
+static unsigned long
+insert_ras(unsigned long insn, long value, const char **errmsg)
+{
+  if (value == 0)
+    *errmsg = "invalid register operand when updating";
+  return insn | ((value & 0x1f) << 16);
+}
+
+/* The RB field in an X form instruction when it must be the same as
+   the RS field in the instruction.  This is used for extended
+   mnemonics like mr.  This operand is marked FAKE.  The insertion
+   function just copies the BT field into the BA field, and the
+   extraction function just checks that the fields are the same.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_rbs(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | (((insn >> 21) & 0x1f) << 11);
+}
+
+static long
+extract_rbs(unsigned long insn, int *invalid)
+{
+  if (invalid != (int *) NULL
+      && ((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f))
+    *invalid = 1;
+  return 0;
+}
+
+/* The SH field in an MD form instruction.  This is split.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_sh6(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
+}
+
+/*ARGSUSED*/
+static long
+extract_sh6(unsigned long insn, int *invalid)
+{
+  return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
+}
+
+/* The SPR field in an XFX form instruction.  This is flipped--the
+   lower 5 bits are stored in the upper 5 and vice- versa.  */
+
+static unsigned long
+insert_spr(unsigned long insn, long value, const char **errmsg)
+{
+  return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+}
+
+static long
+extract_spr(unsigned long insn, int *invalid)
+{
+  return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+}
+
+/* The TBR field in an XFX instruction.  This is just like SPR, but it
+   is optional.  When TBR is omitted, it must be inserted as 268 (the
+   magic number of the TB register).  These functions treat 0
+   (indicating an omitted optional operand) as 268.  This means that
+   ``mftb 4,0'' is not handled correctly.  This does not matter very
+   much, since the architecture manual does not define mftb as
+   accepting any values other than 268 or 269.  */
+
+#define TB (268)
+
+static unsigned long
+insert_tbr(unsigned long insn, long value, const char **errmsg)
+{
+  if (value == 0)
+    value = TB;
+  return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+}
+
+static long
+extract_tbr(unsigned long insn, int *invalid)
+{
+  long ret;
+
+  ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+  if (ret == TB)
+    ret = 0;
+  return ret;
+}
+
+/* Macros used to form opcodes.  */
+
+/* The main opcode.  */
+#define OP(x) (((x) & 0x3f) << 26)
+#define OP_MASK OP (0x3f)
+
+/* The main opcode combined with a trap code in the TO field of a D
+   form instruction.  Used for extended mnemonics for the trap
+   instructions.  */
+#define OPTO(x,to) (OP (x) | (((to) & 0x1f) << 21))
+#define OPTO_MASK (OP_MASK | TO_MASK)
+
+/* The main opcode combined with a comparison size bit in the L field
+   of a D form or X form instruction.  Used for extended mnemonics for
+   the comparison instructions.  */
+#define OPL(x,l) (OP (x) | (((l) & 1) << 21))
+#define OPL_MASK OPL (0x3f,1)
+
+/* An A form instruction.  */
+#define A(op, xop, rc) (OP (op) | (((xop) & 0x1f) << 1) | ((rc) & 1))
+#define A_MASK A (0x3f, 0x1f, 1)
+
+/* An A_MASK with the FRB field fixed.  */
+#define AFRB_MASK (A_MASK | FRB_MASK)
+
+/* An A_MASK with the FRC field fixed.  */
+#define AFRC_MASK (A_MASK | FRC_MASK)
+
+/* An A_MASK with the FRA and FRC fields fixed.  */
+#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
+
+/* A B form instruction.  */
+#define B(op, aa, lk) (OP (op) | (((aa) & 1) << 1) | ((lk) & 1))
+#define B_MASK B (0x3f, 1, 1)
+
+/* A B form instruction setting the BO field.  */
+#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | (((bo) & 0x1f) << 21))
+#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)
+
+/* A BBO_MASK with the y bit of the BO field removed.  This permits
+   matching a conditional branch regardless of the setting of the y
+   bit.  */
+#define Y_MASK (1 << 21)
+#define BBOY_MASK (BBO_MASK &~ Y_MASK)
+
+/* A B form instruction setting the BO field and the condition bits of
+   the BI field.  */
+#define BBOCB(op, bo, cb, aa, lk) \
+  (BBO ((op), (bo), (aa), (lk)) | (((cb) & 0x3) << 16))
+#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)
+
+/* A BBOCB_MASK with the y bit of the BO field removed.  */
+#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)
+
+/* A BBOYCB_MASK in which the BI field is fixed.  */
+#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)
+
+/* The main opcode mask with the RA field clear.  */
+#define DRA_MASK (OP_MASK | RA_MASK)
+
+/* A DS form instruction.  */
+#define DSO(op, xop) (OP (op) | ((xop) & 0x3))
+#define DS_MASK DSO (0x3f, 3)
+
+/* An M form instruction.  */
+#define M(op, rc) (OP (op) | ((rc) & 1))
+#define M_MASK M (0x3f, 1)
+
+/* An M form instruction with the ME field specified.  */
+#define MME(op, me, rc) (M ((op), (rc)) | (((me) & 0x1f) << 1))
+
+/* An M_MASK with the MB and ME fields fixed.  */
+#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK)
+
+/* An M_MASK with the SH and ME fields fixed.  */
+#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK)
+
+/* An MD form instruction.  */
+#define MD(op, xop, rc) (OP (op) | (((xop) & 0x7) << 2) | ((rc) & 1))
+#define MD_MASK MD (0x3f, 0x7, 1)
+
+/* An MD_MASK with the MB field fixed.  */
+#define MDMB_MASK (MD_MASK | MB6_MASK)
+
+/* An MD_MASK with the SH field fixed.  */
+#define MDSH_MASK (MD_MASK | SH6_MASK)
+
+/* An MDS form instruction.  */
+#define MDS(op, xop, rc) (OP (op) | (((xop) & 0xf) << 1) | ((rc) & 1))
+#define MDS_MASK MDS (0x3f, 0xf, 1)
+
+/* An MDS_MASK with the MB field fixed.  */
+#define MDSMB_MASK (MDS_MASK | MB6_MASK)
+
+/* An SC form instruction.  */
+#define SC(op, sa, lk) (OP (op) | (((sa) & 1) << 1) | ((lk) & 1))
+#define SC_MASK (OP_MASK | (0x3ff << 16) | (1 << 1) | 1)
+
+/* An X form instruction.  */
+#define X(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
+
+/* An X form instruction with the RC bit specified.  */
+#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
+
+/* The mask for an X form instruction.  */
+#define X_MASK XRC (0x3f, 0x3ff, 1)
+
+/* An X_MASK with the RA field fixed.  */
+#define XRA_MASK (X_MASK | RA_MASK)
+
+/* An X_MASK with the RB field fixed.  */
+#define XRB_MASK (X_MASK | RB_MASK)
+
+/* An X_MASK with the RT field fixed.  */
+#define XRT_MASK (X_MASK | RT_MASK)
+
+/* An X_MASK with the RA and RB fields fixed.  */
+#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
+
+/* An X_MASK with the RT and RA fields fixed.  */
+#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK)
+
+/* An X form comparison instruction.  */
+#define XCMPL(op, xop, l) (X ((op), (xop)) | (((l) & 1) << 21))
+
+/* The mask for an X form comparison instruction.  */
+#define XCMP_MASK (X_MASK | (1 << 22))
+
+/* The mask for an X form comparison instruction with the L field
+   fixed.  */
+#define XCMPL_MASK (XCMP_MASK | (1 << 21))
+
+/* An X form trap instruction with the TO field specified.  */
+#define XTO(op, xop, to) (X ((op), (xop)) | (((to) & 0x1f) << 21))
+#define XTO_MASK (X_MASK | TO_MASK)
+
+/* An XFL form instruction.  */
+#define XFL(op, xop, rc) (OP (op) | (((xop) & 0x3ff) << 1) | ((rc) & 1))
+#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (1 << 25) | (1 << 16))
+
+/* An XL form instruction with the LK field set to 0.  */
+#define XL(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
+
+/* An XL form instruction which uses the LK field.  */
+#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1))
+
+/* The mask for an XL form instruction.  */
+#define XL_MASK XLLK (0x3f, 0x3ff, 1)
+
+/* An XL form instruction which explicitly sets the BO field.  */
+#define XLO(op, bo, xop, lk) \
+  (XLLK ((op), (xop), (lk)) | (((bo) & 0x1f) << 21))
+#define XLO_MASK (XL_MASK | BO_MASK)
+
+/* An XL form instruction which explicitly sets the y bit of the BO
+   field.  */
+#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | (((y) & 1) << 21))
+#define XLYLK_MASK (XL_MASK | Y_MASK)
+
+/* An XL form instruction which sets the BO field and the condition
+   bits of the BI field.  */
+#define XLOCB(op, bo, cb, xop, lk) \
+  (XLO ((op), (bo), (xop), (lk)) | (((cb) & 3) << 16))
+#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1)
+
+/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed.  */
+#define XLBB_MASK (XL_MASK | BB_MASK)
+#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
+#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
+
+/* An XL_MASK with the BO and BB fields fixed.  */
+#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
+
+/* An XL_MASK with the BO, BI and BB fields fixed.  */
+#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK)
+
+/* An XO form instruction.  */
+#define XO(op, xop, oe, rc) \
+  (OP (op) | (((xop) & 0x1ff) << 1) | (((oe) & 1) << 10) | ((rc) & 1))
+#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
+
+/* An XO_MASK with the RB field fixed.  */
+#define XORB_MASK (XO_MASK | RB_MASK)
+
+/* An XS form instruction.  */
+#define XS(op, xop, rc) (OP (op) | (((xop) & 0x1ff) << 2) | ((rc) & 1))
+#define XS_MASK XS (0x3f, 0x1ff, 1)
+
+/* A mask for the FXM version of an XFX form instruction.  */
+#define XFXFXM_MASK (X_MASK | (1 << 20) | (1 << 11))
+
+/* An XFX form instruction with the FXM field filled in.  */
+#define XFXM(op, xop, fxm) \
+  (X ((op), (xop)) | (((fxm) & 0xff) << 12))
+
+/* An XFX form instruction with the SPR field filled in.  */
+#define XSPR(op, xop, spr) \
+  (X ((op), (xop)) | (((spr) & 0x1f) << 16) | (((spr) & 0x3e0) << 6))
+#define XSPR_MASK (X_MASK | SPR_MASK)
+
+/* An XFX form instruction with the SPR field filled in except for the
+   SPRBAT field.  */
+#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK)
+
+/* An XFX form instruction with the SPR field filled in except for the
+   SPRG field.  */
+#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
+
+/* The BO encodings used in extended conditional branch mnemonics.  */
+#define BODNZF	(0x0)
+#define BODNZFP	(0x1)
+#define BODZF	(0x2)
+#define BODZFP	(0x3)
+#define BOF	(0x4)
+#define BOFP	(0x5)
+#define BODNZT	(0x8)
+#define BODNZTP	(0x9)
+#define BODZT	(0xa)
+#define BODZTP	(0xb)
+#define BOT	(0xc)
+#define BOTP	(0xd)
+#define BODNZ	(0x10)
+#define BODNZP	(0x11)
+#define BODZ	(0x12)
+#define BODZP	(0x13)
+#define BOU	(0x14)
+
+/* The BI condition bit encodings used in extended conditional branch
+   mnemonics.  */
+#define CBLT	(0)
+#define CBGT	(1)
+#define CBEQ	(2)
+#define CBSO	(3)
+
+/* The TO encodings used in extended trap mnemonics.  */
+#define TOLGT	(0x1)
+#define TOLLT	(0x2)
+#define TOEQ	(0x4)
+#define TOLGE	(0x5)
+#define TOLNL	(0x5)
+#define TOLLE	(0x6)
+#define TOLNG	(0x6)
+#define TOGT	(0x8)
+#define TOGE	(0xc)
+#define TONL	(0xc)
+#define TOLT	(0x10)
+#define TOLE	(0x14)
+#define TONG	(0x14)
+#define TONE	(0x18)
+#define TOU	(0x1f)
+
+/* Smaller names for the flags so each entry in the opcodes table will
+   fit on a single line.  */
+#undef PPC
+#define PPC PPC_OPCODE_PPC
+#define POWER PPC_OPCODE_POWER
+#define POWER2 PPC_OPCODE_POWER2
+#define B32 PPC_OPCODE_32
+#define B64 PPC_OPCODE_64
+#define M601 PPC_OPCODE_601
+
+/* The opcode table.
+
+   The format of the opcode table is:
+
+   NAME	     OPCODE	MASK		FLAGS		{ OPERANDS }
+
+   NAME is the name of the instruction.
+   OPCODE is the instruction opcode.
+   MASK is the opcode mask; this is used to tell the disassembler
+     which bits in the actual opcode must match OPCODE.
+   FLAGS are flags indicated what processors support the instruction.
+   OPERANDS is the list of operands.
+
+   The disassembler reads the table in order and prints the first
+   instruction which matches, so this table is sorted to put more
+   specific instructions before more general instructions.  It is also
+   sorted by major opcode.  */
+
+const struct powerpc_opcode powerpc_opcodes[] = {
+{ "tdlgti",  OPTO(2,TOLGT), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdllti",  OPTO(2,TOLLT), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdeqi",   OPTO(2,TOEQ), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlgei",  OPTO(2,TOLGE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlnli",  OPTO(2,TOLNL), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdllei",  OPTO(2,TOLLE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlngi",  OPTO(2,TOLNG), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdgti",   OPTO(2,TOGT), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdgei",   OPTO(2,TOGE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdnli",   OPTO(2,TONL), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlti",   OPTO(2,TOLT), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlei",   OPTO(2,TOLE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdngi",   OPTO(2,TONG), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdnei",   OPTO(2,TONE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdi",     OP(2),	OP_MASK,	PPC|B64,	{ TO, RA, SI } },
+
+{ "twlgti",  OPTO(3,TOLGT), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlgti",   OPTO(3,TOLGT), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twllti",  OPTO(3,TOLLT), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tllti",   OPTO(3,TOLLT), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "tweqi",   OPTO(3,TOEQ), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "teqi",    OPTO(3,TOEQ), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlgei",  OPTO(3,TOLGE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlgei",   OPTO(3,TOLGE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlnli",  OPTO(3,TOLNL), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlnli",   OPTO(3,TOLNL), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twllei",  OPTO(3,TOLLE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tllei",   OPTO(3,TOLLE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlngi",  OPTO(3,TOLNG), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlngi",   OPTO(3,TOLNG), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twgti",   OPTO(3,TOGT), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tgti",    OPTO(3,TOGT), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twgei",   OPTO(3,TOGE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tgei",    OPTO(3,TOGE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twnli",   OPTO(3,TONL), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tnli",    OPTO(3,TONL), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlti",   OPTO(3,TOLT), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlti",    OPTO(3,TOLT), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlei",   OPTO(3,TOLE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlei",    OPTO(3,TOLE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twngi",   OPTO(3,TONG), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tngi",    OPTO(3,TONG), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twnei",   OPTO(3,TONE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tnei",    OPTO(3,TONE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twi",     OP(3),	OP_MASK,	PPC,		{ TO, RA, SI } },
+{ "ti",      OP(3),	OP_MASK,	POWER,		{ TO, RA, SI } },
+
+{ "mulli",   OP(7),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "muli",    OP(7),	OP_MASK,	POWER,		{ RT, RA, SI } },
+
+{ "subfic",  OP(8),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "sfi",     OP(8),	OP_MASK,	POWER,		{ RT, RA, SI } },
+
+{ "dozi",    OP(9),	OP_MASK,	POWER|M601,	{ RT, RA, SI } },
+
+{ "cmplwi",  OPL(10,0),	OPL_MASK,	PPC,		{ OBF, RA, UI } },
+{ "cmpldi",  OPL(10,1), OPL_MASK,	PPC|B64,	{ OBF, RA, UI } },
+{ "cmpli",   OP(10),	OP_MASK,	PPC,		{ BF, L, RA, UI } },
+{ "cmpli",   OP(10),	OP_MASK,	POWER,		{ BF, RA, UI } },
+
+{ "cmpwi",   OPL(11,0),	OPL_MASK,	PPC,		{ OBF, RA, SI } },
+{ "cmpdi",   OPL(11,1),	OPL_MASK,	PPC|B64,	{ OBF, RA, SI } },
+{ "cmpi",    OP(11),	OP_MASK,	PPC,		{ BF, L, RA, SI } },
+{ "cmpi",    OP(11),	OP_MASK,	POWER,		{ BF, RA, SI } },
+
+{ "addic",   OP(12),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "ai",	     OP(12),	OP_MASK,	POWER,		{ RT, RA, SI } },
+{ "subic",   OP(12),	OP_MASK,	PPC,		{ RT, RA, NSI } },
+
+{ "addic.",  OP(13),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "ai.",     OP(13),	OP_MASK,	POWER,		{ RT, RA, SI } },
+{ "subic.",  OP(13),	OP_MASK,	PPC,		{ RT, RA, NSI } },
+
+{ "li",	     OP(14),	DRA_MASK,	PPC,		{ RT, SI } },
+{ "lil",     OP(14),	DRA_MASK,	POWER,		{ RT, SI } },
+{ "addi",    OP(14),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "cal",     OP(14),	OP_MASK,	POWER,		{ RT, D, RA } },
+{ "subi",    OP(14),	OP_MASK,	PPC,		{ RT, RA, NSI } },
+{ "la",	     OP(14),	OP_MASK,	PPC,		{ RT, D, RA } },
+
+{ "lis",     OP(15),	DRA_MASK,	PPC,		{ RT, SISIGNOPT } },
+{ "liu",     OP(15),	DRA_MASK,	POWER,		{ RT, SISIGNOPT } },
+{ "addis",   OP(15),	OP_MASK,	PPC,		{ RT,RA,SISIGNOPT } },
+{ "cau",     OP(15),	OP_MASK,	POWER,		{ RT,RA,SISIGNOPT } },
+{ "subis",   OP(15),	OP_MASK,	PPC,		{ RT, RA, NSI } },
+
+{ "bdnz-",   BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC,	{ BDM } },
+{ "bdnz+",   BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC,	{ BDP } },
+{ "bdnz",    BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC,	{ BD } },
+{ "bdn",     BBO(16,BODNZ,0,0), BBOYBI_MASK, POWER,	{ BD } },
+{ "bdnzl-",  BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC,	{ BDM } },
+{ "bdnzl+",  BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC,	{ BDP } },
+{ "bdnzl",   BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC,	{ BD } },
+{ "bdnl",    BBO(16,BODNZ,0,1), BBOYBI_MASK, POWER,	{ BD } },
+{ "bdnza-",  BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC,	{ BDMA } },
+{ "bdnza+",  BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC,	{ BDPA } },
+{ "bdnza",   BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC,	{ BDA } },
+{ "bdna",    BBO(16,BODNZ,1,0), BBOYBI_MASK, POWER,	{ BDA } },
+{ "bdnzla-", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC,	{ BDMA } },
+{ "bdnzla+", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC,	{ BDPA } },
+{ "bdnzla",  BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC,	{ BDA } },
+{ "bdnla",   BBO(16,BODNZ,1,1), BBOYBI_MASK, POWER,	{ BDA } },
+{ "bdz-",    BBO(16,BODZ,0,0), BBOYBI_MASK, PPC,	{ BDM } },
+{ "bdz+",    BBO(16,BODZ,0,0), BBOYBI_MASK, PPC,	{ BDP } },
+{ "bdz",     BBO(16,BODZ,0,0), BBOYBI_MASK, PPC|POWER,	{ BD } },
+{ "bdzl-",   BBO(16,BODZ,0,1), BBOYBI_MASK, PPC,	{ BDM } },
+{ "bdzl+",   BBO(16,BODZ,0,1), BBOYBI_MASK, PPC,	{ BDP } },
+{ "bdzl",    BBO(16,BODZ,0,1), BBOYBI_MASK, PPC|POWER,	{ BD } },
+{ "bdza-",   BBO(16,BODZ,1,0), BBOYBI_MASK, PPC,	{ BDMA } },
+{ "bdza+",   BBO(16,BODZ,1,0), BBOYBI_MASK, PPC,	{ BDPA } },
+{ "bdza",    BBO(16,BODZ,1,0), BBOYBI_MASK, PPC|POWER,	{ BDA } },
+{ "bdzla-",  BBO(16,BODZ,1,1), BBOYBI_MASK, PPC,	{ BDMA } },
+{ "bdzla+",  BBO(16,BODZ,1,1), BBOYBI_MASK, PPC,	{ BDPA } },
+{ "bdzla",   BBO(16,BODZ,1,1), BBOYBI_MASK, PPC|POWER,	{ BDA } },
+{ "blt-",    BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "blt+",    BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "blt",     BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bltl-",   BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bltl+",   BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bltl",    BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "blta-",   BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "blta+",   BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "blta",    BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bltla-",  BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bltla+",  BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bltla",   BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bgt-",    BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bgt+",    BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bgt",     BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bgtl-",   BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bgtl+",   BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bgtl",    BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bgta-",   BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bgta+",   BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bgta",    BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bgtla-",  BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bgtla+",  BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bgtla",   BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "beq-",    BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "beq+",    BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "beq",     BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "beql-",   BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "beql+",   BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "beql",    BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "beqa-",   BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "beqa+",   BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "beqa",    BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "beqla-",  BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "beqla+",  BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "beqla",   BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bso-",    BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bso+",    BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bso",     BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bsol-",   BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bsol+",   BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bsol",    BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bsoa-",   BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bsoa+",   BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bsoa",    BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bsola-",  BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bsola+",  BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bsola",   BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bun-",    BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bun+",    BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bun",     BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BD } },
+{ "bunl-",   BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bunl+",   BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bunl",    BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BD } },
+{ "buna-",   BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "buna+",   BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "buna",    BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDA } },
+{ "bunla-",  BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bunla+",  BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bunla",   BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDA } },
+{ "bge-",    BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bge+",    BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bge",     BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bgel-",   BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bgel+",   BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bgel",    BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bgea-",   BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bgea+",   BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bgea",    BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bgela-",  BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bgela+",  BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bgela",   BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnl-",    BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnl+",    BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnl",     BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnll-",   BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnll+",   BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnll",    BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnla-",   BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnla+",   BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnla",    BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnlla-",  BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnlla+",  BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnlla",   BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "ble-",    BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "ble+",    BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "ble",     BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "blel-",   BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "blel+",   BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "blel",    BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "blea-",   BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "blea+",   BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "blea",    BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "blela-",  BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "blela+",  BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "blela",   BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bng-",    BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bng+",    BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bng",     BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bngl-",   BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bngl+",   BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bngl",    BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnga-",   BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnga+",   BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnga",    BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bngla-",  BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bngla+",  BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bngla",   BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bne-",    BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bne+",    BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bne",     BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnel-",   BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnel+",   BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnel",    BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnea-",   BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnea+",   BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnea",    BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnela-",  BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnela+",  BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnela",   BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bns-",    BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bns+",    BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bns",     BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnsl-",   BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnsl+",   BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnsl",    BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnsa-",   BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnsa+",   BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnsa",    BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnsla-",  BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnsla+",  BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnsla",   BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnu-",    BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnu+",    BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnu",     BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BD } },
+{ "bnul-",   BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnul+",   BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnul",    BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BD } },
+{ "bnua-",   BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnua+",   BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnua",    BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDA } },
+{ "bnula-",  BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnula+",  BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnula",   BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDA } },
+{ "bdnzt-",  BBO(16,BODNZT,0,0), BBOY_MASK, PPC,	{ BI, BDM } },
+{ "bdnzt+",  BBO(16,BODNZT,0,0), BBOY_MASK, PPC,	{ BI, BDP } },
+{ "bdnzt",   BBO(16,BODNZT,0,0), BBOY_MASK, PPC,	{ BI, BD } },
+{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, PPC,	{ BI, BDM } },
+{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, PPC,	{ BI, BDP } },
+{ "bdnztl",  BBO(16,BODNZT,0,1), BBOY_MASK, PPC,	{ BI, BD } },
+{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, PPC,	{ BI, BDMA } },
+{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, PPC,	{ BI, BDPA } },
+{ "bdnzta",  BBO(16,BODNZT,1,0), BBOY_MASK, PPC,	{ BI, BDA } },
+{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, PPC,	{ BI, BDMA } },
+{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, PPC,	{ BI, BDPA } },
+{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPC,	{ BI, BDA } },
+{ "bdnzf-",  BBO(16,BODNZF,0,0), BBOY_MASK, PPC,	{ BI, BDM } },
+{ "bdnzf+",  BBO(16,BODNZF,0,0), BBOY_MASK, PPC,	{ BI, BDP } },
+{ "bdnzf",   BBO(16,BODNZF,0,0), BBOY_MASK, PPC,	{ BI, BD } },
+{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, PPC,	{ BI, BDM } },
+{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, PPC,	{ BI, BDP } },
+{ "bdnzfl",  BBO(16,BODNZF,0,1), BBOY_MASK, PPC,	{ BI, BD } },
+{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, PPC,	{ BI, BDMA } },
+{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, PPC,	{ BI, BDPA } },
+{ "bdnzfa",  BBO(16,BODNZF,1,0), BBOY_MASK, PPC,	{ BI, BDA } },
+{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, PPC,	{ BI, BDMA } },
+{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, PPC,	{ BI, BDPA } },
+{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPC,	{ BI, BDA } },
+{ "bt-",     BBO(16,BOT,0,0), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bt+",     BBO(16,BOT,0,0), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bt",	     BBO(16,BOT,0,0), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bbt",     BBO(16,BOT,0,0), BBOY_MASK, POWER,		{ BI, BD } },
+{ "btl-",    BBO(16,BOT,0,1), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "btl+",    BBO(16,BOT,0,1), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "btl",     BBO(16,BOT,0,1), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bbtl",    BBO(16,BOT,0,1), BBOY_MASK, POWER,		{ BI, BD } },
+{ "bta-",    BBO(16,BOT,1,0), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bta+",    BBO(16,BOT,1,0), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bta",     BBO(16,BOT,1,0), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bbta",    BBO(16,BOT,1,0), BBOY_MASK, POWER,		{ BI, BDA } },
+{ "btla-",   BBO(16,BOT,1,1), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "btla+",   BBO(16,BOT,1,1), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "btla",    BBO(16,BOT,1,1), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bbtla",   BBO(16,BOT,1,1), BBOY_MASK, POWER,		{ BI, BDA } },
+{ "bf-",     BBO(16,BOF,0,0), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bf+",     BBO(16,BOF,0,0), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bf",	     BBO(16,BOF,0,0), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bbf",     BBO(16,BOF,0,0), BBOY_MASK, POWER,		{ BI, BD } },
+{ "bfl-",    BBO(16,BOF,0,1), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bfl+",    BBO(16,BOF,0,1), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bfl",     BBO(16,BOF,0,1), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bbfl",    BBO(16,BOF,0,1), BBOY_MASK, POWER,		{ BI, BD } },
+{ "bfa-",    BBO(16,BOF,1,0), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bfa+",    BBO(16,BOF,1,0), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bfa",     BBO(16,BOF,1,0), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bbfa",    BBO(16,BOF,1,0), BBOY_MASK, POWER,		{ BI, BDA } },
+{ "bfla-",   BBO(16,BOF,1,1), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bfla+",   BBO(16,BOF,1,1), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bfla",    BBO(16,BOF,1,1), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bbfla",   BBO(16,BOF,1,1), BBOY_MASK, POWER,		{ BI, BDA } },
+{ "bdzt-",   BBO(16,BODZT,0,0), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bdzt+",   BBO(16,BODZT,0,0), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bdzt",    BBO(16,BODZT,0,0), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bdztl-",  BBO(16,BODZT,0,1), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bdztl+",  BBO(16,BODZT,0,1), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bdztl",   BBO(16,BODZT,0,1), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bdzta-",  BBO(16,BODZT,1,0), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bdzta+",  BBO(16,BODZT,1,0), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bdzta",   BBO(16,BODZT,1,0), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bdztla",  BBO(16,BODZT,1,1), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bdzf-",   BBO(16,BODZF,0,0), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bdzf+",   BBO(16,BODZF,0,0), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bdzf",    BBO(16,BODZF,0,0), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bdzfl-",  BBO(16,BODZF,0,1), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bdzfl+",  BBO(16,BODZF,0,1), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bdzfl",   BBO(16,BODZF,0,1), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bdzfa-",  BBO(16,BODZF,1,0), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bdzfa+",  BBO(16,BODZF,1,0), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bdzfa",   BBO(16,BODZF,1,0), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bdzfla",  BBO(16,BODZF,1,1), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bc-",     B(16,0,0),	B_MASK,		PPC,		{ BOE, BI, BDM } },
+{ "bc+",     B(16,0,0),	B_MASK,		PPC,		{ BOE, BI, BDP } },
+{ "bc",	     B(16,0,0),	B_MASK,		PPC|POWER,	{ BO, BI, BD } },
+{ "bcl-",    B(16,0,1),	B_MASK,		PPC,		{ BOE, BI, BDM } },
+{ "bcl+",    B(16,0,1),	B_MASK,		PPC,		{ BOE, BI, BDP } },
+{ "bcl",     B(16,0,1),	B_MASK,		PPC|POWER,	{ BO, BI, BD } },
+{ "bca-",    B(16,1,0),	B_MASK,		PPC,		{ BOE, BI, BDMA } },
+{ "bca+",    B(16,1,0),	B_MASK,		PPC,		{ BOE, BI, BDPA } },
+{ "bca",     B(16,1,0),	B_MASK,		PPC|POWER,	{ BO, BI, BDA } },
+{ "bcla-",   B(16,1,1),	B_MASK,		PPC,		{ BOE, BI, BDMA } },
+{ "bcla+",   B(16,1,1),	B_MASK,		PPC,		{ BOE, BI, BDPA } },
+{ "bcla",    B(16,1,1),	B_MASK,		PPC|POWER,	{ BO, BI, BDA } },
+
+{ "sc",      SC(17,1,0), 0xffffffff,	PPC,		{ 0 } },
+{ "svc",     SC(17,0,0), SC_MASK,	POWER,		{ LEV, FL1, FL2 } },
+{ "svcl",    SC(17,0,1), SC_MASK,	POWER,		{ LEV, FL1, FL2 } },
+{ "svca",    SC(17,1,0), SC_MASK,	POWER,		{ SV } },
+{ "svcla",   SC(17,1,1), SC_MASK,	POWER,		{ SV } },
+
+{ "b",	     B(18,0,0),	B_MASK,		PPC|POWER,	{ LI } },
+{ "bl",      B(18,0,1),	B_MASK,		PPC|POWER,	{ LI } },
+{ "ba",      B(18,1,0),	B_MASK,		PPC|POWER,	{ LIA } },
+{ "bla",     B(18,1,1),	B_MASK,		PPC|POWER,	{ LIA } },
+
+{ "mcrf",    XL(19,0),	XLBB_MASK|(3<<21)|(3<<16), PPC|POWER, { BF, BFA } },
+
+{ "blr",     XLO(19,BOU,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "br",      XLO(19,BOU,16,0), XLBOBIBB_MASK, POWER,	{ 0 } },
+{ "blrl",    XLO(19,BOU,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "brl",     XLO(19,BOU,16,1), XLBOBIBB_MASK, POWER,	{ 0 } },
+{ "bdnzlr",  XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlr",   XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlr-",  XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlr+",  XLO(19,BODZP,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlrl",  XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bltlr",   XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlr-",  XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlr+",  XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltr",    XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bltlrl",  XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltrl",   XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bgtlr",   XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlr-",  XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlr+",  XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtr",    XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bgtlrl",  XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtrl",   XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "beqlr",   XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlr-",  XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlr+",  XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqr",    XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "beqlrl",  XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqrl",   XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bsolr",   XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolr-",  XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolr+",  XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsor",    XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bsolrl",  XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsorl",   XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bunlr",   XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlr-",  XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlr+",  XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl",  XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr",   XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr-",  XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr+",  XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bger",    XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bgelrl",  XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgerl",   XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnllr",   XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllr-",  XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllr+",  XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlr",    XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnllrl",  XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlrl",   XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "blelr",   XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelr-",  XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelr+",  XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bler",    XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "blelrl",  XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blerl",   XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnglr",   XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglr-",  XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglr+",  XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngr",    XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnglrl",  XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngrl",   XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnelr",   XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelr-",  XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelr+",  XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bner",    XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnelrl",  XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnerl",   XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnslr",   XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslr-",  XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslr+",  XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsr",    XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnslrl",  XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsrl",   XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnulr",   XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulr-",  XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulr+",  XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl",  XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "btlr",    XLO(19,BOT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btlr-",   XLO(19,BOT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btlr+",   XLO(19,BOTP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bbtr",    XLO(19,BOT,16,0), XLBOBB_MASK, POWER,	{ BI } },
+{ "btlrl",   XLO(19,BOT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "btlrl-",  XLO(19,BOT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "btlrl+",  XLO(19,BOTP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bbtrl",   XLO(19,BOT,16,1), XLBOBB_MASK, POWER,	{ BI } },
+{ "bflr",    XLO(19,BOF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bflr-",   XLO(19,BOF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bflr+",   XLO(19,BOFP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bbfr",    XLO(19,BOF,16,0), XLBOBB_MASK, POWER,	{ BI } },
+{ "bflrl",   XLO(19,BOF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bflrl-",  XLO(19,BOF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bflrl+",  XLO(19,BOFP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bbfrl",   XLO(19,BOF,16,1), XLBOBB_MASK, POWER,	{ BI } },
+{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlr",  XLO(19,BODZT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflr",  XLO(19,BODZF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bclr",    XLLK(19,16,0), XLYBB_MASK,	PPC,		{ BO, BI } },
+{ "bclrl",   XLLK(19,16,1), XLYBB_MASK,	PPC,		{ BO, BI } },
+{ "bclr+",   XLYLK(19,16,1,0), XLYBB_MASK, PPC,		{ BOE, BI } },
+{ "bclrl+",  XLYLK(19,16,1,1), XLYBB_MASK, PPC,		{ BOE, BI } },
+{ "bclr-",   XLYLK(19,16,0,0), XLYBB_MASK, PPC,		{ BOE, BI } },
+{ "bclrl-",  XLYLK(19,16,0,1), XLYBB_MASK, PPC,		{ BOE, BI } },
+{ "bcr",     XLLK(19,16,0), XLBB_MASK,	POWER,		{ BO, BI } },
+{ "bcrl",    XLLK(19,16,1), XLBB_MASK,	POWER,		{ BO, BI } },
+
+{ "crnot",   XL(19,33), XL_MASK,	PPC,		{ BT, BA, BBA } },
+{ "crnor",   XL(19,33),	XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "rfi",     XL(19,50),	0xffffffff,	PPC|POWER,	{ 0 } },
+{ "rfci",    XL(19,51),	0xffffffff,	PPC,		{ 0 } },
+
+{ "rfsvc",   XL(19,82),	0xffffffff,	POWER,		{ 0 } },
+
+{ "crandc",  XL(19,129), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "isync",   XL(19,150), 0xffffffff,	PPC,		{ 0 } },
+{ "ics",     XL(19,150), 0xffffffff,	POWER,		{ 0 } },
+
+{ "crclr",   XL(19,193), XL_MASK,	PPC,		{ BT, BAT, BBA } },
+{ "crxor",   XL(19,193), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crnand",  XL(19,225), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crand",   XL(19,257), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crset",   XL(19,289), XL_MASK,	PPC,		{ BT, BAT, BBA } },
+{ "creqv",   XL(19,289), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crorc",   XL(19,417), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crmove",  XL(19,449), XL_MASK,	PPC,		{ BT, BA, BBA } },
+{ "cror",    XL(19,449), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "bctr",    XLO(19,BOU,528,0), XLBOBIBB_MASK, PPC|POWER, { 0 } },
+{ "bctrl",   XLO(19,BOU,528,1), XLBOBIBB_MASK, PPC|POWER, { 0 } },
+{ "bltctr",  XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctr-", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl", XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr",  XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr",  XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr",  XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr",  XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr",  XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr",  XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr",  XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr",  XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr",  XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr",  XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr",  XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "btctr",   XLO(19,BOT,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctr-",  XLO(19,BOT,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctr+",  XLO(19,BOTP,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctrl",  XLO(19,BOT,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctrl-", XLO(19,BOT,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctr",   XLO(19,BOF,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctr-",  XLO(19,BOF,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctr+",  XLO(19,BOFP,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctrl",  XLO(19,BOF,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctrl-", XLO(19,BOF,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bcctr",   XLLK(19,528,0), XLYBB_MASK, PPC,		{ BO, BI } },
+{ "bcctr-",  XLYLK(19,528,0,0), XLYBB_MASK, PPC,	{ BOE, BI } },
+{ "bcctr+",  XLYLK(19,528,1,0), XLYBB_MASK, PPC,	{ BOE, BI } },
+{ "bcctrl",  XLLK(19,528,1), XLYBB_MASK, PPC,		{ BO, BI } },
+{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPC,	{ BOE, BI } },
+{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPC,	{ BOE, BI } },
+{ "bcc",     XLLK(19,528,0), XLBB_MASK,	POWER,		{ BO, BI } },
+{ "bccl",    XLLK(19,528,1), XLBB_MASK,	POWER,		{ BO, BI } },
+
+{ "rlwimi",  M(20,0),	M_MASK,		PPC,		{ RA,RS,SH,MBE,ME } },
+{ "rlimi",   M(20,0),	M_MASK,		POWER,		{ RA,RS,SH,MBE,ME } },
+
+{ "rlwimi.", M(20,1),	M_MASK,		PPC,		{ RA,RS,SH,MBE,ME } },
+{ "rlimi.",  M(20,1),	M_MASK,		POWER,		{ RA,RS,SH,MBE,ME } },
+
+{ "rotlwi",  MME(21,31,0), MMBME_MASK,	PPC,		{ RA, RS, SH } },
+{ "clrlwi",  MME(21,31,0), MSHME_MASK,	PPC,		{ RA, RS, MB } },
+{ "rlwinm",  M(21,0),	M_MASK,		PPC,		{ RA,RS,SH,MBE,ME } },
+{ "rlinm",   M(21,0),	M_MASK,		POWER,		{ RA,RS,SH,MBE,ME } },
+{ "rotlwi.", MME(21,31,1), MMBME_MASK,	PPC,		{ RA,RS,SH } },
+{ "clrlwi.", MME(21,31,1), MSHME_MASK,	PPC,		{ RA, RS, MB } },
+{ "rlwinm.", M(21,1),	M_MASK,		PPC,		{ RA,RS,SH,MBE,ME } },
+{ "rlinm.",  M(21,1),	M_MASK,		POWER,		{ RA,RS,SH,MBE,ME } },
+
+{ "rlmi",    M(22,0),	M_MASK,		POWER|M601,	{ RA,RS,RB,MBE,ME } },
+{ "rlmi.",   M(22,1),	M_MASK,		POWER|M601,	{ RA,RS,RB,MBE,ME } },
+
+{ "rotlw",   MME(23,31,0), MMBME_MASK,	PPC,		{ RA, RS, RB } },
+{ "rlwnm",   M(23,0),	M_MASK,		PPC,		{ RA,RS,RB,MBE,ME } },
+{ "rlnm",    M(23,0),	M_MASK,		POWER,		{ RA,RS,RB,MBE,ME } },
+{ "rotlw.",  MME(23,31,1), MMBME_MASK,	PPC,		{ RA, RS, RB } },
+{ "rlwnm.",  M(23,1),	M_MASK,		PPC,		{ RA,RS,RB,MBE,ME } },
+{ "rlnm.",   M(23,1),	M_MASK,		POWER,		{ RA,RS,RB,MBE,ME } },
+
+{ "nop",     OP(24),	0xffffffff,	PPC,		{ 0 } },
+{ "ori",     OP(24),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "oril",    OP(24),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "oris",    OP(25),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "oriu",    OP(25),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "xori",    OP(26),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "xoril",   OP(26),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "xoris",   OP(27),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "xoriu",   OP(27),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "andi.",   OP(28),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "andil.",  OP(28),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "andis.",  OP(29),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "andiu.",  OP(29),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "rotldi",  MD(30,0,0), MDMB_MASK,	PPC|B64,	{ RA, RS, SH6 } },
+{ "clrldi",  MD(30,0,0), MDSH_MASK,	PPC|B64,	{ RA, RS, MB6 } },
+{ "rldicl",  MD(30,0,0), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+{ "rotldi.", MD(30,0,1), MDMB_MASK,	PPC|B64,	{ RA, RS, SH6 } },
+{ "clrldi.", MD(30,0,1), MDSH_MASK,	PPC|B64,	{ RA, RS, MB6 } },
+{ "rldicl.", MD(30,0,1), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+
+{ "rldicr",  MD(30,1,0), MD_MASK,	PPC|B64,	{ RA, RS, SH6, ME6 } },
+{ "rldicr.", MD(30,1,1), MD_MASK,	PPC|B64,	{ RA, RS, SH6, ME6 } },
+
+{ "rldic",   MD(30,2,0), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+{ "rldic.",  MD(30,2,1), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+
+{ "rldimi",  MD(30,3,0), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+{ "rldimi.", MD(30,3,1), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+
+{ "rotld",   MDS(30,8,0), MDSMB_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "rldcl",   MDS(30,8,0), MDS_MASK,	PPC|B64,	{ RA, RS, RB, MB6 } },
+{ "rotld.",  MDS(30,8,1), MDSMB_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "rldcl.",  MDS(30,8,1), MDS_MASK,	PPC|B64,	{ RA, RS, RB, MB6 } },
+
+{ "rldcr",   MDS(30,9,0), MDS_MASK,	PPC|B64,	{ RA, RS, RB, ME6 } },
+{ "rldcr.",  MDS(30,9,1), MDS_MASK,	PPC|B64,	{ RA, RS, RB, ME6 } },
+
+{ "cmpw",    XCMPL(31,0,0), XCMPL_MASK, PPC,		{ OBF, RA, RB } },
+{ "cmpd",    XCMPL(31,0,1), XCMPL_MASK, PPC|B64,	{ OBF, RA, RB } },
+{ "cmp",     X(31,0),	XCMP_MASK,	PPC,		{ BF, L, RA, RB } },
+{ "cmp",     X(31,0),	XCMPL_MASK,	POWER,		{ BF, RA, RB } },
+
+{ "twlgt",   XTO(31,4,TOLGT), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlgt",    XTO(31,4,TOLGT), XTO_MASK, POWER,		{ RA, RB } },
+{ "twllt",   XTO(31,4,TOLLT), XTO_MASK, PPC,		{ RA, RB } },
+{ "tllt",    XTO(31,4,TOLLT), XTO_MASK, POWER,		{ RA, RB } },
+{ "tweq",    XTO(31,4,TOEQ), XTO_MASK,	PPC,		{ RA, RB } },
+{ "teq",     XTO(31,4,TOEQ), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twlge",   XTO(31,4,TOLGE), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlge",    XTO(31,4,TOLGE), XTO_MASK, POWER,		{ RA, RB } },
+{ "twlnl",   XTO(31,4,TOLNL), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlnl",    XTO(31,4,TOLNL), XTO_MASK, POWER,		{ RA, RB } },
+{ "twlle",   XTO(31,4,TOLLE), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlle",    XTO(31,4,TOLLE), XTO_MASK, POWER,		{ RA, RB } },
+{ "twlng",   XTO(31,4,TOLNG), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlng",    XTO(31,4,TOLNG), XTO_MASK, POWER,		{ RA, RB } },
+{ "twgt",    XTO(31,4,TOGT), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tgt",     XTO(31,4,TOGT), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twge",    XTO(31,4,TOGE), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tge",     XTO(31,4,TOGE), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twnl",    XTO(31,4,TONL), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tnl",     XTO(31,4,TONL), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twlt",    XTO(31,4,TOLT), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tlt",     XTO(31,4,TOLT), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twle",    XTO(31,4,TOLE), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tle",     XTO(31,4,TOLE), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twng",    XTO(31,4,TONG), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tng",     XTO(31,4,TONG), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twne",    XTO(31,4,TONE), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tne",     XTO(31,4,TONE), XTO_MASK,	POWER,		{ RA, RB } },
+{ "trap",    XTO(31,4,TOU), 0xffffffff,	PPC,		{ 0 } },
+{ "tw",      X(31,4),	X_MASK,		PPC,		{ TO, RA, RB } },
+{ "t",       X(31,4),	X_MASK,		POWER,		{ TO, RA, RB } },
+
+{ "subfc",   XO(31,8,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sf",      XO(31,8,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subc",    XO(31,8,0,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfc.",  XO(31,8,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sf.",     XO(31,8,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subc.",   XO(31,8,0,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfco",  XO(31,8,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfo",     XO(31,8,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subco",   XO(31,8,1,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfco.", XO(31,8,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfo.",    XO(31,8,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subco.",  XO(31,8,1,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+
+{ "mulhdu",  XO(31,9,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulhdu.", XO(31,9,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "addc",    XO(31,10,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "a",       XO(31,10,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addc.",   XO(31,10,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "a.",      XO(31,10,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addco",   XO(31,10,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "ao",      XO(31,10,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addco.",  XO(31,10,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "ao.",     XO(31,10,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "mulhwu",  XO(31,11,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "mulhwu.", XO(31,11,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+
+{ "mfcr",    X(31,19),	XRARB_MASK,	POWER|PPC,	{ RT } },
+
+{ "lwarx",   X(31,20),	X_MASK,		PPC,		{ RT, RA, RB } },
+
+{ "ldx",     X(31,21),	X_MASK,		PPC|B64,	{ RT, RA, RB } },
+
+{ "lwzx",    X(31,23),	X_MASK,		PPC,		{ RT, RA, RB } },
+{ "lx",      X(31,23),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "slw",     XRC(31,24,0), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sl",      XRC(31,24,0), X_MASK,	POWER,		{ RA, RS, RB } },
+{ "slw.",    XRC(31,24,1), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sl.",     XRC(31,24,1), X_MASK,	POWER,		{ RA, RS, RB } },
+
+{ "cntlzw",  XRC(31,26,0), XRB_MASK,	PPC,		{ RA, RS } },
+{ "cntlz",   XRC(31,26,0), XRB_MASK,	POWER,		{ RA, RS } },
+{ "cntlzw.", XRC(31,26,1), XRB_MASK,	PPC,		{ RA, RS } },
+{ "cntlz.",  XRC(31,26,1), XRB_MASK, 	POWER,		{ RA, RS } },
+
+{ "sld",     XRC(31,27,0), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "sld.",    XRC(31,27,1), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+
+{ "and",     XRC(31,28,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "and.",    XRC(31,28,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "maskg",   XRC(31,29,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "maskg.",  XRC(31,29,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "cmplw",   XCMPL(31,32,0), XCMPL_MASK, PPC,		{ OBF, RA, RB } },
+{ "cmpld",   XCMPL(31,32,1), XCMPL_MASK, PPC|B64,	{ OBF, RA, RB } },
+{ "cmpl",    X(31,32),	XCMP_MASK,	PPC,		{ BF, L, RA, RB } },
+{ "cmpl",    X(31,32),	XCMPL_MASK,	POWER,		{ BF, RA, RB } },
+
+{ "subf",    XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sub",     XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subf.",   XO(31,40,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sub.",    XO(31,40,0,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfo",   XO(31,40,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "subo",    XO(31,40,1,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfo.",  XO(31,40,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "subo.",   XO(31,40,1,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+
+{ "ldux",    X(31,53),	X_MASK,		PPC|B64,	{ RT, RAL, RB } },
+
+{ "dcbst",   X(31,54),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "lwzux",   X(31,55),	X_MASK,		PPC,		{ RT, RAL, RB } },
+{ "lux",     X(31,55),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "cntlzd",  XRC(31,58,0), XRB_MASK,	PPC|B64,	{ RA, RS } },
+{ "cntlzd.", XRC(31,58,1), XRB_MASK,	PPC|B64,	{ RA, RS } },
+
+{ "andc",    XRC(31,60,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "andc.",   XRC(31,60,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "tdlgt",   XTO(31,68,TOLGT), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdllt",   XTO(31,68,TOLLT), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdeq",    XTO(31,68,TOEQ), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlge",   XTO(31,68,TOLGE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlnl",   XTO(31,68,TOLNL), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlle",   XTO(31,68,TOLLE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlng",   XTO(31,68,TOLNG), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdgt",    XTO(31,68,TOGT), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdge",    XTO(31,68,TOGE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdnl",    XTO(31,68,TONL), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlt",    XTO(31,68,TOLT), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdle",    XTO(31,68,TOLE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdng",    XTO(31,68,TONG), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdne",    XTO(31,68,TONE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "td",	     X(31,68),	X_MASK,		PPC|B64,	{ TO, RA, RB } },
+
+{ "mulhd",   XO(31,73,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulhd.",  XO(31,73,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "mulhw",   XO(31,75,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "mulhw.",  XO(31,75,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+
+{ "mfmsr",   X(31,83),	XRARB_MASK,	PPC|POWER,	{ RT } },
+
+{ "ldarx",   X(31,84),	X_MASK,		PPC|B64,	{ RT, RA, RB } },
+
+{ "dcbf",    X(31,86),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "lbzx",    X(31,87),	X_MASK,		PPC|POWER,	{ RT, RA, RB } },
+
+{ "neg",     XO(31,104,0,0), XORB_MASK,	PPC|POWER,	{ RT, RA } },
+{ "neg.",    XO(31,104,0,1), XORB_MASK,	PPC|POWER,	{ RT, RA } },
+{ "nego",    XO(31,104,1,0), XORB_MASK,	PPC|POWER,	{ RT, RA } },
+{ "nego.",   XO(31,104,1,1), XORB_MASK,	PPC|POWER,	{ RT, RA } },
+
+{ "mul",     XO(31,107,0,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "mul.",    XO(31,107,0,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "mulo",    XO(31,107,1,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "mulo.",   XO(31,107,1,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "clf",     X(31,118), XRB_MASK,	POWER,		{ RT, RA } },
+
+{ "lbzux",   X(31,119),	X_MASK,		PPC|POWER,	{ RT, RAL, RB } },
+
+{ "not",     XRC(31,124,0), X_MASK,	PPC|POWER,	{ RA, RS, RBS } },
+{ "nor",     XRC(31,124,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "not.",    XRC(31,124,1), X_MASK,	PPC|POWER,	{ RA, RS, RBS } },
+{ "nor.",    XRC(31,124,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "subfe",   XO(31,136,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfe",     XO(31,136,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subfe.",  XO(31,136,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfe.",    XO(31,136,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subfeo",  XO(31,136,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfeo",    XO(31,136,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subfeo.", XO(31,136,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfeo.",   XO(31,136,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "adde",    XO(31,138,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "ae",      XO(31,138,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "adde.",   XO(31,138,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "ae.",     XO(31,138,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addeo",   XO(31,138,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "aeo",     XO(31,138,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addeo.",  XO(31,138,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "aeo.",    XO(31,138,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "mtcr",    XFXM(31,144,0xff), XFXFXM_MASK|FXM_MASK, PPC|POWER, { RS }},
+{ "mtcrf",   X(31,144),	XFXFXM_MASK,	PPC|POWER,	{ FXM, RS } },
+
+{ "mtmsr",   X(31,146),	XRARB_MASK,	PPC|POWER,	{ RS } },
+
+{ "stdx",    X(31,149), X_MASK,		PPC|B64,	{ RS, RA, RB } },
+
+{ "stwcx.",  XRC(31,150,1), X_MASK,	PPC,		{ RS, RA, RB } },
+
+{ "stwx",    X(31,151), X_MASK,		PPC,		{ RS, RA, RB } },
+{ "stx",     X(31,151), X_MASK,		POWER,		{ RS, RA, RB } },
+
+{ "slq",     XRC(31,152,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "slq.",    XRC(31,152,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "sle",     XRC(31,153,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sle.",    XRC(31,153,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "stdux",   X(31,181),	X_MASK,		PPC|B64,	{ RS, RAS, RB } },
+
+{ "stwux",   X(31,183),	X_MASK,		PPC,		{ RS, RAS, RB } },
+{ "stux",    X(31,183),	X_MASK,		POWER,		{ RS, RA, RB } },
+
+{ "sliq",    XRC(31,184,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "sliq.",   XRC(31,184,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "subfze",  XO(31,200,0,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfze",    XO(31,200,0,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfze.", XO(31,200,0,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfze.",   XO(31,200,0,1), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfzeo",   XO(31,200,1,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfzeo.",  XO(31,200,1,1), XORB_MASK, POWER,		{ RT, RA } },
+
+{ "addze",   XO(31,202,0,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "aze",     XO(31,202,0,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "addze.",  XO(31,202,0,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "aze.",    XO(31,202,0,1), XORB_MASK, POWER,		{ RT, RA } },
+{ "addzeo",  XO(31,202,1,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "azeo",    XO(31,202,1,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "azeo.",   XO(31,202,1,1), XORB_MASK, POWER,		{ RT, RA } },
+
+{ "mtsr",    X(31,210),	XRB_MASK|(1<<20), PPC|POWER|B32, { SR, RS } },
+
+{ "stdcx.",  XRC(31,214,1), X_MASK,	PPC|B64,	{ RS, RA, RB } },
+
+{ "stbx",    X(31,215),	X_MASK,		PPC|POWER,	{ RS, RA, RB } },
+
+{ "sllq",    XRC(31,216,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sllq.",   XRC(31,216,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "sleq",    XRC(31,217,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sleq.",   XRC(31,217,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "subfme",  XO(31,232,0,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfme",    XO(31,232,0,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfme.", XO(31,232,0,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfme.",   XO(31,232,0,1), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfmeo",   XO(31,232,1,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfmeo.",  XO(31,232,1,1), XORB_MASK, POWER,		{ RT, RA } },
+
+{ "mulld",   XO(31,233,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulld.",  XO(31,233,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulldo",  XO(31,233,1,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulldo.", XO(31,233,1,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "addme",   XO(31,234,0,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "ame",     XO(31,234,0,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "addme.",  XO(31,234,0,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "ame.",    XO(31,234,0,1), XORB_MASK, POWER,		{ RT, RA } },
+{ "addmeo",  XO(31,234,1,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "ameo",    XO(31,234,1,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "ameo.",   XO(31,234,1,1), XORB_MASK, POWER,		{ RT, RA } },
+
+{ "mullw",   XO(31,235,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "muls",    XO(31,235,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "mullw.",  XO(31,235,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "muls.",   XO(31,235,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "mullwo",  XO(31,235,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "mulso",   XO(31,235,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "mullwo.", XO(31,235,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "mulso.",  XO(31,235,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "mtsrin",  X(31,242),	XRA_MASK,	PPC|B32,	{ RS, RB } },
+{ "mtsri",   X(31,242),	XRA_MASK,	POWER|B32,	{ RS, RB } },
+
+{ "dcbtst",  X(31,246),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "stbux",   X(31,247),	X_MASK,		PPC|POWER,	{ RS, RAS, RB } },
+
+{ "slliq",   XRC(31,248,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "slliq.",  XRC(31,248,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "doz",     XO(31,264,0,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "doz.",    XO(31,264,0,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "dozo",    XO(31,264,1,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "dozo.",   XO(31,264,1,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "add",     XO(31,266,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "cax",     XO(31,266,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "add.",    XO(31,266,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "cax.",    XO(31,266,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addo",    XO(31,266,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "caxo",    XO(31,266,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addo.",   XO(31,266,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "caxo.",   XO(31,266,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "lscbx",   XRC(31,277,0), X_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "lscbx.",  XRC(31,277,1), X_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "dcbt",    X(31,278),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "lhzx",    X(31,279),	X_MASK,		PPC|POWER,	{ RT, RA, RB } },
+
+{ "icbt",    X(31,262),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "eqv",     XRC(31,284,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "eqv.",    XRC(31,284,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "tlbie",   X(31,306),	XRTRA_MASK,	PPC,		{ RB } },
+{ "tlbi",    X(31,306),	XRTRA_MASK,	POWER,		{ RB } },
+
+{ "eciwx",   X(31,310), X_MASK,		PPC,		{ RT, RA, RB } },
+
+{ "lhzux",   X(31,311),	X_MASK,		PPC|POWER,	{ RT, RAL, RB } },
+
+{ "xor",     XRC(31,316,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "xor.",    XRC(31,316,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "mfdcr",   X(31,323),	X_MASK,		PPC,		{ RT, SPR } },
+
+{ "div",     XO(31,331,0,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "div.",    XO(31,331,0,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divo",    XO(31,331,1,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divo.",   XO(31,331,1,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "mfmq",    XSPR(31,339,0), XSPR_MASK,	POWER|M601,	{ RT } },
+{ "mfxer",   XSPR(31,339,1), XSPR_MASK,	PPC|POWER,	{ RT } },
+{ "mfrtcu",  XSPR(31,339,4), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfrtcl",  XSPR(31,339,5), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfdec",   XSPR(31,339,6), XSPR_MASK, POWER|M601,	{ RT } },
+{ "mflr",    XSPR(31,339,8), XSPR_MASK,	PPC|POWER,	{ RT } },
+{ "mfctr",   XSPR(31,339,9), XSPR_MASK,	PPC|POWER,	{ RT } },
+{ "mftid",   XSPR(31,339,17), XSPR_MASK, POWER,		{ RT } },
+{ "mfdsisr", XSPR(31,339,18), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfdar",   XSPR(31,339,19), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfdec",   XSPR(31,339,22), XSPR_MASK, PPC,		{ RT } },
+{ "mfsdr0",  XSPR(31,339,24), XSPR_MASK, POWER,		{ RT } },
+{ "mfsdr1",  XSPR(31,339,25), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfsrr0",  XSPR(31,339,26), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfsrr1",  XSPR(31,339,27), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfsprg",  XSPR(31,339,272), XSPRG_MASK, PPC,		{ RT, SPRG } },
+{ "mfasr",   XSPR(31,339,280), XSPR_MASK, PPC|B64,	{ RT } },
+{ "mfear",   XSPR(31,339,282), XSPR_MASK, PPC,		{ RT } },
+{ "mfpvr",   XSPR(31,339,287), XSPR_MASK, PPC,		{ RT } },
+{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+{ "mfdbatl", XSPR(31,339,537), XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+{ "mfspr",   X(31,339),	X_MASK,		PPC|POWER,	{ RT, SPR } },
+
+{ "lwax",    X(31,341),	X_MASK,		PPC|B64,	{ RT, RA, RB } },
+
+{ "lhax",    X(31,343),	X_MASK,		PPC|POWER,	{ RT, RA, RB } },
+
+{ "dccci",   X(31,454),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "abs",     XO(31,360,0,0), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "abs.",    XO(31,360,0,1), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "abso",    XO(31,360,1,0), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "abso.",   XO(31,360,1,1), XORB_MASK, POWER|M601,	{ RT, RA } },
+
+{ "divs",    XO(31,363,0,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divs.",   XO(31,363,0,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divso",   XO(31,363,1,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divso.",  XO(31,363,1,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "tlbia",   X(31,370),	0xffffffff,	PPC,		{ 0 } },
+
+{ "mftbu",   XSPR(31,371,269), XSPR_MASK, PPC,		{ RT } },
+{ "mftb",    X(31,371),	X_MASK,		PPC,		{ RT, TBR } },
+
+{ "lwaux",   X(31,373),	X_MASK,		PPC|B64,	{ RT, RAL, RB } },
+
+{ "lhaux",   X(31,375),	X_MASK,		PPC|POWER,	{ RT, RAL, RB } },
+
+{ "sthx",    X(31,407),	X_MASK,		PPC|POWER,	{ RS, RA, RB } },
+
+{ "lfqx",    X(31,791),	X_MASK,		POWER2,		{ FRT, RA, RB } },
+
+{ "lfqux",   X(31,823),	X_MASK,		POWER2,		{ FRT, RA, RB } },
+
+{ "stfqx",   X(31,919),	X_MASK,		POWER2,		{ FRS, RA, RB } },
+
+{ "stfqux",  X(31,951),	X_MASK,		POWER2,		{ FRS, RA, RB } },
+
+{ "orc",     XRC(31,412,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "orc.",    XRC(31,412,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "sradi",   XS(31,413,0), XS_MASK,	PPC|B64,	{ RA, RS, SH6 } },
+{ "sradi.",  XS(31,413,1), XS_MASK,	PPC|B64,	{ RA, RS, SH6 } },
+
+{ "slbie",   X(31,434),	XRTRA_MASK,	PPC|B64,	{ RB } },
+
+{ "ecowx",   X(31,438),	X_MASK,		PPC,		{ RT, RA, RB } },
+
+{ "sthux",   X(31,439),	X_MASK,		PPC|POWER,	{ RS, RAS, RB } },
+
+{ "mr",	     XRC(31,444,0), X_MASK,	PPC|POWER,	{ RA, RS, RBS } },
+{ "or",      XRC(31,444,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "mr.",     XRC(31,444,1), X_MASK,	PPC|POWER,	{ RA, RS, RBS } },
+{ "or.",     XRC(31,444,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "mtdcr",   X(31,451),	X_MASK,		PPC,		{ SPR, RS } },
+
+{ "divdu",   XO(31,457,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divdu.",  XO(31,457,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divduo",  XO(31,457,1,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divduo.", XO(31,457,1,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "divwu",   XO(31,459,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwu.",  XO(31,459,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwuo",  XO(31,459,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwuo.", XO(31,459,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+
+{ "mtmq",    XSPR(31,467,0), XSPR_MASK,	POWER|M601,	{ RS } },
+{ "mtxer",   XSPR(31,467,1), XSPR_MASK,	PPC|POWER,	{ RS } },
+{ "mtlr",    XSPR(31,467,8), XSPR_MASK,	PPC|POWER,	{ RS } },
+{ "mtctr",   XSPR(31,467,9), XSPR_MASK,	PPC|POWER,	{ RS } },
+{ "mttid",   XSPR(31,467,17), XSPR_MASK, POWER,		{ RS } },
+{ "mtdsisr", XSPR(31,467,18), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtdar",   XSPR(31,467,19), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtrtcu",  XSPR(31,467,20), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtrtcl",  XSPR(31,467,21), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtdec",   XSPR(31,467,22), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtsdr0",  XSPR(31,467,24), XSPR_MASK, POWER,		{ RS } },
+{ "mtsdr1",  XSPR(31,467,25), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtsrr0",  XSPR(31,467,26), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtsrr1",  XSPR(31,467,27), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtsprg",  XSPR(31,467,272), XSPRG_MASK, PPC,		{ SPRG, RS } },
+{ "mtasr",   XSPR(31,467,280), XSPR_MASK, PPC|B64,	{ RS } },
+{ "mtear",   XSPR(31,467,282), XSPR_MASK, PPC,		{ RS } },
+{ "mttbl",   XSPR(31,467,284), XSPR_MASK, PPC,		{ RS } },
+{ "mttbu",   XSPR(31,467,285), XSPR_MASK, PPC,		{ RS } },
+{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+{ "mtdbatl", XSPR(31,467,537), XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+{ "mtspr",   X(31,467),	X_MASK,		PPC|POWER,	{ SPR, RS } },
+
+{ "dcbi",    X(31,470),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "nand",    XRC(31,476,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "nand.",   XRC(31,476,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "nabs",    XO(31,488,0,0), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "nabs.",   XO(31,488,0,1), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "nabso",   XO(31,488,1,0), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "nabso.",  XO(31,488,1,1), XORB_MASK, POWER|M601,	{ RT, RA } },
+
+{ "divd",    XO(31,489,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divd.",   XO(31,489,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divdo",   XO(31,489,1,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divdo.",  XO(31,489,1,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "divw",    XO(31,491,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divw.",   XO(31,491,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwo",   XO(31,491,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwo.",  XO(31,491,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+
+{ "slbia",   X(31,498),	0xffffffff,	PPC|B64,	{ 0 } },
+
+{ "cli",     X(31,502), XRB_MASK,	POWER,		{ RT, RA } },
+
+{ "mcrxr",   X(31,512),	XRARB_MASK|(3<<21), PPC|POWER,	{ BF } },
+
+{ "clcs",    X(31,531), XRB_MASK,	POWER|M601,	{ RT, RA } },
+
+{ "lswx",    X(31,533),	X_MASK,		PPC,		{ RT, RA, RB } },
+{ "lsx",     X(31,533),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "lwbrx",   X(31,534),	X_MASK,		PPC,		{ RT, RA, RB } },
+{ "lbrx",    X(31,534),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "lfsx",    X(31,535),	X_MASK,		PPC|POWER,	{ FRT, RA, RB } },
+
+{ "srw",     XRC(31,536,0), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sr",      XRC(31,536,0), X_MASK,	POWER,		{ RA, RS, RB } },
+{ "srw.",    XRC(31,536,1), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sr.",     XRC(31,536,1), X_MASK,	POWER,		{ RA, RS, RB } },
+
+{ "rrib",    XRC(31,537,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "rrib.",   XRC(31,537,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "srd",     XRC(31,539,0), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "srd.",    XRC(31,539,1), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+
+{ "maskir",  XRC(31,541,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "maskir.", XRC(31,541,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "tlbsync", X(31,566),	0xffffffff,	PPC,		{ 0 } },
+
+{ "lfsux",   X(31,567),	X_MASK,		PPC|POWER,	{ FRT, RAS, RB } },
+
+{ "mfsr",    X(31,595),	XRB_MASK|(1<<20), PPC|POWER|B32, { RT, SR } },
+
+{ "lswi",    X(31,597),	X_MASK,		PPC,		{ RT, RA, NB } },
+{ "lsi",     X(31,597),	X_MASK,		POWER,		{ RT, RA, NB } },
+
+{ "sync",    X(31,598), 0xffffffff,	PPC,		{ 0 } },
+{ "dcs",     X(31,598), 0xffffffff,	POWER,		{ 0 } },
+
+{ "lfdx",    X(31,599), X_MASK,		PPC|POWER,	{ FRT, RA, RB } },
+
+{ "mfsri",   X(31,627), X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "dclst",   X(31,630), XRB_MASK,	POWER,		{ RS, RA } },
+
+{ "lfdux",   X(31,631), X_MASK,		PPC|POWER,	{ FRT, RAS, RB } },
+
+{ "mfsrin",  X(31,659), XRA_MASK,	PPC|B32,	{ RT, RB } },
+
+{ "stswx",   X(31,661), X_MASK,		PPC,		{ RS, RA, RB } },
+{ "stsx",    X(31,661), X_MASK,		POWER,		{ RS, RA, RB } },
+
+{ "stwbrx",  X(31,662), X_MASK,		PPC,		{ RS, RA, RB } },
+{ "stbrx",   X(31,662), X_MASK,		POWER,		{ RS, RA, RB } },
+
+{ "stfsx",   X(31,663), X_MASK,		PPC|POWER,	{ FRS, RA, RB } },
+
+{ "srq",     XRC(31,664,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "srq.",    XRC(31,664,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "sre",     XRC(31,665,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sre.",    XRC(31,665,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "stfsux",  X(31,695),	X_MASK,		PPC|POWER,	{ FRS, RAS, RB } },
+
+{ "sriq",    XRC(31,696,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "sriq.",   XRC(31,696,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "stswi",   X(31,725),	X_MASK,		PPC,		{ RS, RA, NB } },
+{ "stsi",    X(31,725),	X_MASK,		POWER,		{ RS, RA, NB } },
+
+{ "stfdx",   X(31,727),	X_MASK,		PPC|POWER,	{ FRS, RA, RB } },
+
+{ "srlq",    XRC(31,728,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "srlq.",   XRC(31,728,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "sreq",    XRC(31,729,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sreq.",   XRC(31,729,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "stfdux",  X(31,759),	X_MASK,		PPC|POWER,	{ FRS, RAS, RB } },
+
+{ "srliq",   XRC(31,760,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "srliq.",  XRC(31,760,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "lhbrx",   X(31,790),	X_MASK,		PPC|POWER,	{ RT, RA, RB } },
+
+{ "sraw",    XRC(31,792,0), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sra",     XRC(31,792,0), X_MASK,	POWER,		{ RA, RS, RB } },
+{ "sraw.",   XRC(31,792,1), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sra.",    XRC(31,792,1), X_MASK,	POWER,		{ RA, RS, RB } },
+
+{ "srad",    XRC(31,794,0), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "srad.",   XRC(31,794,1), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+
+{ "rac",     X(31,818),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "srawi",   XRC(31,824,0), X_MASK,	PPC,		{ RA, RS, SH } },
+{ "srai",    XRC(31,824,0), X_MASK,	POWER,		{ RA, RS, SH } },
+{ "srawi.",  XRC(31,824,1), X_MASK,	PPC,		{ RA, RS, SH } },
+{ "srai.",   XRC(31,824,1), X_MASK,	POWER,		{ RA, RS, SH } },
+
+{ "eieio",   X(31,854),	0xffffffff,	PPC,		{ 0 } },
+
+{ "sthbrx",  X(31,918),	X_MASK,		PPC|POWER,	{ RS, RA, RB } },
+
+{ "sraq",    XRC(31,920,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sraq.",   XRC(31,920,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "srea",    XRC(31,921,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "srea.",   XRC(31,921,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "extsh",   XRC(31,922,0), XRB_MASK,	PPC,		{ RA, RS } },
+{ "exts",    XRC(31,922,0), XRB_MASK,	POWER,		{ RA, RS } },
+{ "extsh.",  XRC(31,922,1), XRB_MASK,	PPC,		{ RA, RS } },
+{ "exts.",   XRC(31,922,1), XRB_MASK,	POWER,		{ RA, RS } },
+
+{ "sraiq",   XRC(31,952,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "sraiq.",  XRC(31,952,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "extsb",   XRC(31,954,0), XRB_MASK,	PPC,		{ RA, RS} },
+{ "extsb.",  XRC(31,954,1), XRB_MASK,	PPC,		{ RA, RS} },
+
+{ "iccci",   X(31,966),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "icbi",    X(31,982),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "stfiwx",  X(31,983),	X_MASK,		PPC,		{ FRS, RA, RB } },
+
+{ "extsw",   XRC(31,986,0), XRB_MASK,	PPC,		{ RA, RS } },
+{ "extsw.",  XRC(31,986,1), XRB_MASK,	PPC,		{ RA, RS } },
+
+{ "dcbz",    X(31,1014), XRT_MASK,	PPC,		{ RA, RB } },
+{ "dclz",    X(31,1014), XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "lwz",     OP(32),	OP_MASK,	PPC,		{ RT, D, RA } },
+{ "l",	     OP(32),	OP_MASK,	POWER,		{ RT, D, RA } },
+
+{ "lwzu",    OP(33),	OP_MASK,	PPC,		{ RT, D, RAL } },
+{ "lu",      OP(33),	OP_MASK,	POWER,		{ RT, D, RA } },
+
+{ "lbz",     OP(34),	OP_MASK,	PPC|POWER,	{ RT, D, RA } },
+
+{ "lbzu",    OP(35),	OP_MASK,	PPC|POWER,	{ RT, D, RAL } },
+
+{ "stw",     OP(36),	OP_MASK,	PPC,		{ RS, D, RA } },
+{ "st",      OP(36),	OP_MASK,	POWER,		{ RS, D, RA } },
+
+{ "stwu",    OP(37),	OP_MASK,	PPC,		{ RS, D, RAS } },
+{ "stu",     OP(37),	OP_MASK,	POWER,		{ RS, D, RA } },
+
+{ "stb",     OP(38),	OP_MASK,	PPC|POWER,	{ RS, D, RA } },
+
+{ "stbu",    OP(39),	OP_MASK,	PPC|POWER,	{ RS, D, RAS } },
+
+{ "lhz",     OP(40),	OP_MASK,	PPC|POWER,	{ RT, D, RA } },
+
+{ "lhzu",    OP(41),	OP_MASK,	PPC|POWER,	{ RT, D, RAL } },
+
+{ "lha",     OP(42),	OP_MASK,	PPC|POWER,	{ RT, D, RA } },
+
+{ "lhau",    OP(43),	OP_MASK,	PPC|POWER,	{ RT, D, RAL } },
+
+{ "sth",     OP(44),	OP_MASK,	PPC|POWER,	{ RS, D, RA } },
+
+{ "sthu",    OP(45),	OP_MASK,	PPC|POWER,	{ RS, D, RAS } },
+
+{ "lmw",     OP(46),	OP_MASK,	PPC,		{ RT, D, RAM } },
+{ "lm",      OP(46),	OP_MASK,	POWER,		{ RT, D, RA } },
+
+{ "stmw",    OP(47),	OP_MASK,	PPC,		{ RS, D, RA } },
+{ "stm",     OP(47),	OP_MASK,	POWER,		{ RS, D, RA } },
+
+{ "lfs",     OP(48),	OP_MASK,	PPC|POWER,	{ FRT, D, RA } },
+
+{ "lfsu",    OP(49),	OP_MASK,	PPC|POWER,	{ FRT, D, RAS } },
+
+{ "lfd",     OP(50),	OP_MASK,	PPC|POWER,	{ FRT, D, RA } },
+
+{ "lfdu",    OP(51),	OP_MASK,	PPC|POWER,	{ FRT, D, RAS } },
+
+{ "stfs",    OP(52),	OP_MASK,	PPC|POWER,	{ FRS, D, RA } },
+
+{ "stfsu",   OP(53),	OP_MASK,	PPC|POWER,	{ FRS, D, RAS } },
+
+{ "stfd",    OP(54),	OP_MASK,	PPC|POWER,	{ FRS, D, RA } },
+
+{ "stfdu",   OP(55),	OP_MASK,	PPC|POWER,	{ FRS, D, RAS } },
+
+{ "lfq",     OP(56),	OP_MASK,	POWER2,		{ FRT, D, RA } },
+
+{ "lfqu",    OP(57),	OP_MASK,	POWER2,		{ FRT, D, RA } },
+
+{ "ld",      DSO(58,0),	DS_MASK,	PPC|B64,	{ RT, DS, RA } },
+
+{ "ldu",     DSO(58,1), DS_MASK,	PPC|B64,	{ RT, DS, RAL } },
+
+{ "lwa",     DSO(58,2), DS_MASK,	PPC|B64,	{ RT, DS, RA } },
+
+{ "fdivs",   A(59,18,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fdivs.",  A(59,18,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+
+{ "fsubs",   A(59,20,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fsubs.",  A(59,20,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+
+{ "fadds",   A(59,21,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fadds.",  A(59,21,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+
+{ "fsqrts",  A(59,22,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+{ "fsqrts.", A(59,22,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+
+{ "fres",    A(59,24,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+{ "fres.",   A(59,24,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+
+{ "fmuls",   A(59,25,0), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+{ "fmuls.",  A(59,25,1), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+
+{ "fmsubs",  A(59,28,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fmsubs.", A(59,28,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "fmadds",  A(59,29,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fmadds.", A(59,29,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "fnmsubs", A(59,30,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnmsubs.",A(59,30,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "fnmadds", A(59,31,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnmadds.",A(59,31,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "stfq",    OP(60),	OP_MASK,	POWER2,		{ FRS, D, RA } },
+
+{ "stfqu",   OP(61),	OP_MASK,	POWER2,		{ FRS, D, RA } },
+
+{ "std",     DSO(62,0),	DS_MASK,	PPC|B64,	{ RS, DS, RA } },
+
+{ "stdu",    DSO(62,1),	DS_MASK,	PPC|B64,	{ RS, DS, RAS } },
+
+{ "fcmpu",   X(63,0),	X_MASK|(3<<21),	PPC|POWER,	{ BF, FRA, FRB } },
+
+{ "frsp",    XRC(63,12,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "frsp.",   XRC(63,12,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "fctiw",   XRC(63,14,0), XRA_MASK,	PPC,		{ FRT, FRB } },
+{ "fcir",    XRC(63,14,0), XRA_MASK,	POWER2,		{ FRT, FRB } },
+{ "fctiw.",  XRC(63,14,1), XRA_MASK,	PPC,		{ FRT, FRB } },
+{ "fcir.",   XRC(63,14,1), XRA_MASK,	POWER2,		{ FRT, FRB } },
+
+{ "fctiwz",  XRC(63,15,0), XRA_MASK,	PPC,		{ FRT, FRB } },
+{ "fcirz",   XRC(63,15,0), XRA_MASK,	POWER2,		{ FRT, FRB } },
+{ "fctiwz.", XRC(63,15,1), XRA_MASK,	PPC,		{ FRT, FRB } },
+{ "fcirz.",  XRC(63,15,1), XRA_MASK,	POWER2,		{ FRT, FRB } },
+
+{ "fdiv",    A(63,18,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fd",      A(63,18,0), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+{ "fdiv.",   A(63,18,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fd.",     A(63,18,1), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+
+{ "fsub",    A(63,20,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fs",      A(63,20,0), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+{ "fsub.",   A(63,20,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fs.",     A(63,20,1), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+
+{ "fadd",    A(63,21,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fa",      A(63,21,0), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+{ "fadd.",   A(63,21,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fa.",     A(63,21,1), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+
+{ "fsqrt",   A(63,22,0), AFRAFRC_MASK,	PPC|POWER2,	{ FRT, FRB } },
+{ "fsqrt.",  A(63,22,1), AFRAFRC_MASK,	PPC|POWER2,	{ FRT, FRB } },
+
+{ "fsel",    A(63,23,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fsel.",   A(63,23,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "fmul",    A(63,25,0), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+{ "fm",      A(63,25,0), AFRB_MASK,	POWER,		{ FRT, FRA, FRC } },
+{ "fmul.",   A(63,25,1), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+{ "fm.",     A(63,25,1), AFRB_MASK,	POWER,		{ FRT, FRA, FRC } },
+
+{ "frsqrte", A(63,26,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+{ "frsqrte.",A(63,26,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+
+{ "fmsub",   A(63,28,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fms",     A(63,28,0), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+{ "fmsub.",  A(63,28,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fms.",    A(63,28,1), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+
+{ "fmadd",   A(63,29,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fma",     A(63,29,0), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+{ "fmadd.",  A(63,29,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fma.",    A(63,29,1), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+
+{ "fnmsub",  A(63,30,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnms",    A(63,30,0), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+{ "fnmsub.", A(63,30,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnms.",   A(63,30,1), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+
+{ "fnmadd",  A(63,31,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnma",    A(63,31,0), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+{ "fnmadd.", A(63,31,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnma.",   A(63,31,1), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+
+{ "fcmpo",   X(63,30),	X_MASK|(3<<21),	PPC|POWER,	{ BF, FRA, FRB } },
+
+{ "mtfsb1",  XRC(63,38,0), XRARB_MASK,	PPC|POWER,	{ BT } },
+{ "mtfsb1.", XRC(63,38,1), XRARB_MASK,	PPC|POWER,	{ BT } },
+
+{ "fneg",    XRC(63,40,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "fneg.",   XRC(63,40,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "mcrfs",   X(63,64),	XRB_MASK|(3<<21)|(3<<16), PPC|POWER, { BF, BFA } },
+
+{ "mtfsb0",  XRC(63,70,0), XRARB_MASK,	PPC|POWER,	{ BT } },
+{ "mtfsb0.", XRC(63,70,1), XRARB_MASK,	PPC|POWER,	{ BT } },
+
+{ "fmr",     XRC(63,72,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "fmr.",    XRC(63,72,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "mtfsfi",  XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), PPC|POWER, { BF, U } },
+{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), PPC|POWER, { BF, U } },
+
+{ "fnabs",   XRC(63,136,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "fnabs.",  XRC(63,136,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "fabs",    XRC(63,264,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "fabs.",   XRC(63,264,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "mffs",    XRC(63,583,0), XRARB_MASK,	PPC|POWER,	{ FRT } },
+{ "mffs.",   XRC(63,583,1), XRARB_MASK,	PPC|POWER,	{ FRT } },
+
+{ "mtfsf",   XFL(63,711,0), XFL_MASK,	PPC|POWER,	{ FLM, FRB } },
+{ "mtfsf.",  XFL(63,711,1), XFL_MASK,	PPC|POWER,	{ FLM, FRB } },
+
+{ "fctid",   XRC(63,814,0), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+{ "fctid.",  XRC(63,814,1), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+
+{ "fctidz",  XRC(63,815,0), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+{ "fctidz.", XRC(63,815,1), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+
+{ "fcfid",   XRC(63,846,0), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+{ "fcfid.",  XRC(63,846,1), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+
+};
+
+const int powerpc_num_opcodes =
+  sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
+
+/* The macro table.  This is only used by the assembler.  */
+
+const struct powerpc_macro powerpc_macros[] = {
+{ "extldi",  4,   PPC|B64,	"rldicr %0,%1,%3,(%2)-1" },
+{ "extldi.", 4,   PPC|B64,	"rldicr. %0,%1,%3,(%2)-1" },
+{ "extrdi",  4,   PPC|B64,	"rldicl %0,%1,(%2)+(%3),64-(%2)" },
+{ "extrdi.", 4,   PPC|B64,	"rldicl. %0,%1,(%2)+(%3),64-(%2)" },
+{ "insrdi",  4,   PPC|B64,	"rldimi %0,%1,64-((%2)+(%3)),%3" },
+{ "insrdi.", 4,   PPC|B64,	"rldimi. %0,%1,64-((%2)+(%3)),%3" },
+{ "rotrdi",  3,   PPC|B64,	"rldicl %0,%1,64-(%2),0" },
+{ "rotrdi.", 3,   PPC|B64,	"rldicl. %0,%1,64-(%2),0" },
+{ "sldi",    3,   PPC|B64,	"rldicr %0,%1,%2,63-(%2)" },
+{ "sldi.",   3,   PPC|B64,	"rldicr. %0,%1,%2,63-(%2)" },
+{ "srdi",    3,   PPC|B64,	"rldicl %0,%1,64-(%2),%2" },
+{ "srdi.",   3,   PPC|B64,	"rldicl. %0,%1,64-(%2),%2" },
+{ "clrrdi",  3,   PPC|B64,	"rldicr %0,%1,0,63-(%2)" },
+{ "clrrdi.", 3,   PPC|B64,	"rldicr. %0,%1,0,63-(%2)" },
+{ "clrlsldi",4,   PPC|B64,	"rldic %0,%1,%3,(%2)-(%3)" },
+{ "clrlsldi.",4,  PPC|B64,	"rldic. %0,%1,%3,(%2)-(%3)" },
+
+{ "extlwi",  4,   PPC,		"rlwinm %0,%1,%3,0,(%2)-1" },
+{ "extlwi.", 4,   PPC,		"rlwinm. %0,%1,%3,0,(%2)-1" },
+{ "extrwi",  4,   PPC,		"rlwinm %0,%1,(%2)+(%3),32-(%2),31" },
+{ "extrwi.", 4,   PPC,		"rlwinm. %0,%1,(%2)+(%3),32-(%2),31" },
+{ "inslwi",  4,   PPC,		"rlwimi %0,%1,32-(%3),%3,(%2)+(%3)-1" },
+{ "inslwi.", 4,   PPC,		"rlwimi. %0,%1,32-(%3),%3,(%2)+(%3)-1" },
+{ "insrwi",  4,   PPC,		"rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },
+{ "insrwi.", 4,   PPC,		"rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"},
+{ "rotrwi",  3,   PPC,		"rlwinm %0,%1,32-(%2),0,31" },
+{ "rotrwi.", 3,   PPC,		"rlwinm. %0,%1,32-(%2),0,31" },
+{ "slwi",    3,   PPC,		"rlwinm %0,%1,%2,0,31-(%2)" },
+{ "sli",     3,   POWER,	"rlinm %0,%1,%2,0,31-(%2)" },
+{ "slwi.",   3,   PPC,		"rlwinm. %0,%1,%2,0,31-(%2)" },
+{ "sli.",    3,   POWER,	"rlinm. %0,%1,%2,0,31-(%2)" },
+{ "srwi",    3,   PPC,		"rlwinm %0,%1,32-(%2),%2,31" },
+{ "sri",     3,   POWER,	"rlinm %0,%1,32-(%2),%2,31" },
+{ "srwi.",   3,   PPC,		"rlwinm. %0,%1,32-(%2),%2,31" },
+{ "sri.",    3,   POWER,	"rlinm. %0,%1,32-(%2),%2,31" },
+{ "clrrwi",  3,   PPC,		"rlwinm %0,%1,0,0,31-(%2)" },
+{ "clrrwi.", 3,   PPC,		"rlwinm. %0,%1,0,0,31-(%2)" },
+{ "clrlslwi",4,   PPC,		"rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" },
+{ "clrlslwi.",4,  PPC,		"rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
+
+};
+
+const int powerpc_num_macros =
+  sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
diff --git a/arch/ppc/xmon/ppc.h b/arch/ppc/xmon/ppc.h
new file mode 100644
index 0000000..2345ecb
--- /dev/null
+++ b/arch/ppc/xmon/ppc.h
@@ -0,0 +1,240 @@
+/* ppc.h -- Header file for PowerPC opcode table
+   Copyright 1994 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef PPC_H
+#define PPC_H
+
+/* The opcode table is an array of struct powerpc_opcode.  */
+
+struct powerpc_opcode
+{
+  /* The opcode name.  */
+  const char *name;
+
+  /* The opcode itself.  Those bits which will be filled in with
+     operands are zeroes.  */
+  unsigned long opcode;
+
+  /* The opcode mask.  This is used by the disassembler.  This is a
+     mask containing ones indicating those bits which must match the
+     opcode field, and zeroes indicating those bits which need not
+     match (and are presumably filled in by operands).  */
+  unsigned long mask;
+
+  /* One bit flags for the opcode.  These are used to indicate which
+     specific processors support the instructions.  The defined values
+     are listed below.  */
+  unsigned long flags;
+
+  /* An array of operand codes.  Each code is an index into the
+     operand table.  They appear in the order which the operands must
+     appear in assembly code, and are terminated by a zero.  */
+  unsigned char operands[8];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise
+   in the order in which the disassembler should consider
+   instructions.  */
+extern const struct powerpc_opcode powerpc_opcodes[];
+extern const int powerpc_num_opcodes;
+
+/* Values defined for the flags field of a struct powerpc_opcode.  */
+
+/* Opcode is defined for the PowerPC architecture.  */
+#define PPC_OPCODE_PPC (01)
+
+/* Opcode is defined for the POWER (RS/6000) architecture.  */
+#define PPC_OPCODE_POWER (02)
+
+/* Opcode is defined for the POWER2 (Rios 2) architecture.  */
+#define PPC_OPCODE_POWER2 (04)
+
+/* Opcode is only defined on 32 bit architectures.  */
+#define PPC_OPCODE_32 (010)
+
+/* Opcode is only defined on 64 bit architectures.  */
+#define PPC_OPCODE_64 (020)
+
+/* Opcode is supported by the Motorola PowerPC 601 processor.  The 601
+   is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
+   but it also supports many additional POWER instructions.  */
+#define PPC_OPCODE_601 (040)
+
+/* A macro to extract the major opcode from an instruction.  */
+#define PPC_OP(i) (((i) >> 26) & 0x3f)
+
+/* The operands table is an array of struct powerpc_operand.  */
+
+struct powerpc_operand
+{
+  /* The number of bits in the operand.  */
+  int bits;
+
+  /* How far the operand is left shifted in the instruction.  */
+  int shift;
+
+  /* Insertion function.  This is used by the assembler.  To insert an
+     operand value into an instruction, check this field.
+
+     If it is NULL, execute
+         i |= (op & ((1 << o->bits) - 1)) << o->shift;
+     (i is the instruction which we are filling in, o is a pointer to
+     this structure, and op is the opcode value; this assumes twos
+     complement arithmetic).
+
+     If this field is not NULL, then simply call it with the
+     instruction and the operand value.  It will return the new value
+     of the instruction.  If the ERRMSG argument is not NULL, then if
+     the operand value is illegal, *ERRMSG will be set to a warning
+     string (the operand will be inserted in any case).  If the
+     operand value is legal, *ERRMSG will be unchanged (most operands
+     can accept any value).  */
+  unsigned long (*insert) PARAMS ((unsigned long instruction, long op,
+				   const char **errmsg));
+
+  /* Extraction function.  This is used by the disassembler.  To
+     extract this operand type from an instruction, check this field.
+
+     If it is NULL, compute
+         op = ((i) >> o->shift) & ((1 << o->bits) - 1);
+	 if ((o->flags & PPC_OPERAND_SIGNED) != 0
+	     && (op & (1 << (o->bits - 1))) != 0)
+	   op -= 1 << o->bits;
+     (i is the instruction, o is a pointer to this structure, and op
+     is the result; this assumes twos complement arithmetic).
+
+     If this field is not NULL, then simply call it with the
+     instruction value.  It will return the value of the operand.  If
+     the INVALID argument is not NULL, *INVALID will be set to
+     non-zero if this operand type can not actually be extracted from
+     this operand (i.e., the instruction does not match).  If the
+     operand is valid, *INVALID will not be changed.  */
+  long (*extract) PARAMS ((unsigned long instruction, int *invalid));
+
+  /* One bit syntax flags.  */
+  unsigned long flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+   the operands field of the powerpc_opcodes table.  */
+
+extern const struct powerpc_operand powerpc_operands[];
+
+/* Values defined for the flags field of a struct powerpc_operand.  */
+
+/* This operand takes signed values.  */
+#define PPC_OPERAND_SIGNED (01)
+
+/* This operand takes signed values, but also accepts a full positive
+   range of values when running in 32 bit mode.  That is, if bits is
+   16, it takes any value from -0x8000 to 0xffff.  In 64 bit mode,
+   this flag is ignored.  */
+#define PPC_OPERAND_SIGNOPT (02)
+
+/* This operand does not actually exist in the assembler input.  This
+   is used to support extended mnemonics such as mr, for which two
+   operands fields are identical.  The assembler should call the
+   insert function with any op value.  The disassembler should call
+   the extract function, ignore the return value, and check the value
+   placed in the valid argument.  */
+#define PPC_OPERAND_FAKE (04)
+
+/* The next operand should be wrapped in parentheses rather than
+   separated from this one by a comma.  This is used for the load and
+   store instructions which want their operands to look like
+       reg,displacement(reg)
+   */
+#define PPC_OPERAND_PARENS (010)
+
+/* This operand may use the symbolic names for the CR fields, which
+   are
+       lt  0	gt  1	eq  2	so  3	un  3
+       cr0 0	cr1 1	cr2 2	cr3 3
+       cr4 4	cr5 5	cr6 6	cr7 7
+   These may be combined arithmetically, as in cr2*4+gt.  These are
+   only supported on the PowerPC, not the POWER.  */
+#define PPC_OPERAND_CR (020)
+
+/* This operand names a register.  The disassembler uses this to print
+   register names with a leading 'r'.  */
+#define PPC_OPERAND_GPR (040)
+
+/* This operand names a floating point register.  The disassembler
+   prints these with a leading 'f'.  */
+#define PPC_OPERAND_FPR (0100)
+
+/* This operand is a relative branch displacement.  The disassembler
+   prints these symbolically if possible.  */
+#define PPC_OPERAND_RELATIVE (0200)
+
+/* This operand is an absolute branch address.  The disassembler
+   prints these symbolically if possible.  */
+#define PPC_OPERAND_ABSOLUTE (0400)
+
+/* This operand is optional, and is zero if omitted.  This is used for
+   the optional BF and L fields in the comparison instructions.  The
+   assembler must count the number of operands remaining on the line,
+   and the number of operands remaining for the opcode, and decide
+   whether this operand is present or not.  The disassembler should
+   print this operand out only if it is not zero.  */
+#define PPC_OPERAND_OPTIONAL (01000)
+
+/* This flag is only used with PPC_OPERAND_OPTIONAL.  If this operand
+   is omitted, then for the next operand use this operand value plus
+   1, ignoring the next operand field for the opcode.  This wretched
+   hack is needed because the Power rotate instructions can take
+   either 4 or 5 operands.  The disassembler should print this operand
+   out regardless of the PPC_OPERAND_OPTIONAL field.  */
+#define PPC_OPERAND_NEXT (02000)
+
+/* This operand should be regarded as a negative number for the
+   purposes of overflow checking (i.e., the normal most negative
+   number is disallowed and one more than the normal most positive
+   number is allowed).  This flag will only be set for a signed
+   operand.  */
+#define PPC_OPERAND_NEGATIVE (04000)
+
+/* The POWER and PowerPC assemblers use a few macros.  We keep them
+   with the operands table for simplicity.  The macro table is an
+   array of struct powerpc_macro.  */
+
+struct powerpc_macro
+{
+  /* The macro name.  */
+  const char *name;
+
+  /* The number of operands the macro takes.  */
+  unsigned int operands;
+
+  /* One bit flags for the opcode.  These are used to indicate which
+     specific processors support the instructions.  The values are the
+     same as those for the struct powerpc_opcode flags field.  */
+  unsigned long flags;
+
+  /* A format string to turn the macro into a normal instruction.
+     Each %N in the string is replaced with operand number N (zero
+     based).  */
+  const char *format;
+};
+
+extern const struct powerpc_macro powerpc_macros[];
+extern const int powerpc_num_macros;
+
+#endif /* PPC_H */
diff --git a/arch/ppc/xmon/privinst.h b/arch/ppc/xmon/privinst.h
new file mode 100644
index 0000000..93978c0
--- /dev/null
+++ b/arch/ppc/xmon/privinst.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include <linux/config.h>
+
+#define GETREG(reg)		\
+    static inline int get_ ## reg (void)	\
+	{ int ret; asm volatile ("mf" #reg " %0" : "=r" (ret) :); return ret; }
+
+#define SETREG(reg)		\
+    static inline void set_ ## reg (int val)	\
+	{ asm volatile ("mt" #reg " %0" : : "r" (val)); }
+
+GETREG(msr)
+SETREG(msr)
+GETREG(cr)
+
+#define GSETSPR(n, name)	\
+    static inline int get_ ## name (void) \
+	{ int ret; asm volatile ("mfspr %0," #n : "=r" (ret) : ); return ret; } \
+    static inline void set_ ## name (int val) \
+	{ asm volatile ("mtspr " #n ",%0" : : "r" (val)); }
+
+GSETSPR(0, mq)
+GSETSPR(1, xer)
+GSETSPR(4, rtcu)
+GSETSPR(5, rtcl)
+GSETSPR(8, lr)
+GSETSPR(9, ctr)
+GSETSPR(18, dsisr)
+GSETSPR(19, dar)
+GSETSPR(22, dec)
+GSETSPR(25, sdr1)
+GSETSPR(26, srr0)
+GSETSPR(27, srr1)
+GSETSPR(272, sprg0)
+GSETSPR(273, sprg1)
+GSETSPR(274, sprg2)
+GSETSPR(275, sprg3)
+GSETSPR(282, ear)
+GSETSPR(287, pvr)
+#ifndef CONFIG_8xx
+GSETSPR(528, bat0u)
+GSETSPR(529, bat0l)
+GSETSPR(530, bat1u)
+GSETSPR(531, bat1l)
+GSETSPR(532, bat2u)
+GSETSPR(533, bat2l)
+GSETSPR(534, bat3u)
+GSETSPR(535, bat3l)
+GSETSPR(1008, hid0)
+GSETSPR(1009, hid1)
+GSETSPR(1010, iabr)
+GSETSPR(1013, dabr)
+GSETSPR(1023, pir)
+#else
+GSETSPR(144, cmpa)
+GSETSPR(145, cmpb)
+GSETSPR(146, cmpc)
+GSETSPR(147, cmpd)
+GSETSPR(158, ictrl)
+#endif
+
+static inline int get_sr(int n)
+{
+    int ret;
+
+    asm (" mfsrin %0,%1" : "=r" (ret) : "r" (n << 28));
+    return ret;
+}
+
+static inline void set_sr(int n, int val)
+{
+    asm ("mtsrin %0,%1" : : "r" (val), "r" (n << 28));
+}
+
+static inline void store_inst(void *p)
+{
+    asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
+}
+
+static inline void cflush(void *p)
+{
+    asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+    asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
+
diff --git a/arch/ppc/xmon/setjmp.c b/arch/ppc/xmon/setjmp.c
new file mode 100644
index 0000000..28352ba
--- /dev/null
+++ b/arch/ppc/xmon/setjmp.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * NB this file must be compiled with -O2.
+ */
+
+int
+xmon_setjmp(long *buf)
+{
+    asm ("mflr 0; stw 0,0(%0);"
+	 "stw 1,4(%0); stw 2,8(%0);"
+	 "mfcr 0; stw 0,12(%0);"
+	 "stmw 13,16(%0)"
+	 : : "r" (buf));
+    /* XXX should save fp regs as well */
+    return 0;
+}
+
+void
+xmon_longjmp(long *buf, int val)
+{
+    if (val == 0)
+	val = 1;
+    asm ("lmw 13,16(%0);"
+	 "lwz 0,12(%0); mtcrf 0x38,0;"
+	 "lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);"
+	 "mtlr 0; mr 3,%1"
+	 : : "r" (buf), "r" (val));
+}
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
new file mode 100644
index 0000000..507d4ee
--- /dev/null
+++ b/arch/ppc/xmon/start.c
@@ -0,0 +1,646 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/cuda.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sysrq.h>
+#include <linux/bitops.h>
+#include <asm/xmon.h>
+#include <asm/prom.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/errno.h>
+#include <asm/pmac_feature.h>
+#include <asm/processor.h>
+#include <asm/delay.h>
+#include <asm/btext.h>
+
+static volatile unsigned char *sccc, *sccd;
+unsigned int TXRDY, RXRDY, DLAB;
+static int xmon_expect(const char *str, unsigned int timeout);
+
+static int use_serial;
+static int use_screen;
+static int via_modem;
+static int xmon_use_sccb;
+static struct device_node *channel_node;
+
+#define TB_SPEED	25000000
+
+static inline unsigned int readtb(void)
+{
+	unsigned int ret;
+
+	asm volatile("mftb %0" : "=r" (ret) :);
+	return ret;
+}
+
+void buf_access(void)
+{
+	if (DLAB)
+		sccd[3] &= ~DLAB;	/* reset DLAB */
+}
+
+extern int adb_init(void);
+
+#ifdef CONFIG_PPC_CHRP
+/*
+ * This looks in the "ranges" property for the primary PCI host bridge
+ * to find the physical address of the start of PCI/ISA I/O space.
+ * It is basically a cut-down version of pci_process_bridge_OF_ranges.
+ */
+static unsigned long chrp_find_phys_io_base(void)
+{
+	struct device_node *node;
+	unsigned int *ranges;
+	unsigned long base = CHRP_ISA_IO_BASE;
+	int rlen = 0;
+	int np;
+
+	node = find_devices("isa");
+	if (node != NULL) {
+		node = node->parent;
+		if (node == NULL || node->type == NULL
+		    || strcmp(node->type, "pci") != 0)
+			node = NULL;
+	}
+	if (node == NULL)
+		node = find_devices("pci");
+	if (node == NULL)
+		return base;
+
+	ranges = (unsigned int *) get_property(node, "ranges", &rlen);
+	np = prom_n_addr_cells(node) + 5;
+	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+		if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
+			/* I/O space starting at 0, grab the phys base */
+			base = ranges[np - 3];
+			break;
+		}
+		ranges += np;
+	}
+	return base;
+}
+#endif /* CONFIG_PPC_CHRP */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static void sysrq_handle_xmon(int key, struct pt_regs *regs,
+			      struct tty_struct *tty)
+{
+	xmon(regs);
+}
+
+static struct sysrq_key_op sysrq_xmon_op =
+{
+	.handler =	sysrq_handle_xmon,
+	.help_msg =	"Xmon",
+	.action_msg =	"Entering xmon",
+};
+#endif
+
+void
+xmon_map_scc(void)
+{
+#ifdef CONFIG_PPC_MULTIPLATFORM
+	volatile unsigned char *base;
+
+	if (_machine == _MACH_Pmac) {
+		struct device_node *np;
+		unsigned long addr;
+#ifdef CONFIG_BOOTX_TEXT
+		if (!use_screen && !use_serial
+		    && !machine_is_compatible("iMac")) {
+			/* see if there is a keyboard in the device tree
+			   with a parent of type "adb" */
+			for (np = find_devices("keyboard"); np; np = np->next)
+				if (np->parent && np->parent->type
+				    && strcmp(np->parent->type, "adb") == 0)
+					break;
+
+			/* needs to be hacked if xmon_printk is to be used
+			   from within find_via_pmu() */
+#ifdef CONFIG_ADB_PMU
+			if (np != NULL && boot_text_mapped && find_via_pmu())
+				use_screen = 1;
+#endif
+#ifdef CONFIG_ADB_CUDA
+			if (np != NULL && boot_text_mapped && find_via_cuda())
+				use_screen = 1;
+#endif
+		}
+		if (!use_screen && (np = find_devices("escc")) != NULL) {
+			/*
+			 * look for the device node for the serial port
+			 * we're using and see if it says it has a modem
+			 */
+			char *name = xmon_use_sccb? "ch-b": "ch-a";
+			char *slots;
+			int l;
+
+			np = np->child;
+			while (np != NULL && strcmp(np->name, name) != 0)
+				np = np->sibling;
+			if (np != NULL) {
+				/* XXX should parse this properly */
+				channel_node = np;
+				slots = get_property(np, "slot-names", &l);
+				if (slots != NULL && l >= 10
+				    && strcmp(slots+4, "Modem") == 0)
+					via_modem = 1;
+			}
+		}
+		btext_drawstring("xmon uses ");
+		if (use_screen)
+			btext_drawstring("screen and keyboard\n");
+		else {
+			if (via_modem)
+				btext_drawstring("modem on ");
+			btext_drawstring(xmon_use_sccb? "printer": "modem");
+			btext_drawstring(" port\n");
+		}
+
+#endif /* CONFIG_BOOTX_TEXT */
+
+#ifdef CHRP_ESCC
+		addr = 0xc1013020;
+#else
+		addr = 0xf3013020;
+#endif
+		TXRDY = 4;
+		RXRDY = 1;
+	
+		np = find_devices("mac-io");
+		if (np && np->n_addrs)
+			addr = np->addrs[0].address + 0x13020;
+		base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
+		sccc = base + (addr & ~PAGE_MASK);
+		sccd = sccc + 0x10;
+
+	} else {
+		base = (volatile unsigned char *) isa_io_base;
+		if (_machine == _MACH_chrp)
+			base = (volatile unsigned char *)
+				ioremap(chrp_find_phys_io_base(), 0x1000);
+
+		sccc = base + 0x3fd;
+		sccd = base + 0x3f8;
+		if (xmon_use_sccb) {
+			sccc -= 0x100;
+			sccd -= 0x100;
+		}
+		TXRDY = 0x20;
+		RXRDY = 1;
+		DLAB = 0x80;
+	}
+#elif defined(CONFIG_GEMINI)
+	/* should already be mapped by the kernel boot */
+	sccc = (volatile unsigned char *) 0xffeffb0d;
+	sccd = (volatile unsigned char *) 0xffeffb08;
+	TXRDY = 0x20;
+	RXRDY = 1;
+	DLAB = 0x80;
+#elif defined(CONFIG_405GP)
+	sccc = (volatile unsigned char *)0xef600305;
+	sccd = (volatile unsigned char *)0xef600300;
+	TXRDY = 0x20;
+	RXRDY = 1;
+	DLAB = 0x80;
+#endif /* platform */
+
+	register_sysrq_key('x', &sysrq_xmon_op);
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+extern void cuda_poll(void);
+
+static inline void do_poll_adb(void)
+{
+#ifdef CONFIG_ADB_PMU
+	if (sys_ctrler == SYS_CTRLER_PMU)
+		pmu_poll_adb();
+#endif /* CONFIG_ADB_PMU */
+#ifdef CONFIG_ADB_CUDA
+	if (sys_ctrler == SYS_CTRLER_CUDA)
+		cuda_poll();
+#endif /* CONFIG_ADB_CUDA */
+}
+
+int
+xmon_write(void *handle, void *ptr, int nb)
+{
+	char *p = ptr;
+	int i, c, ct;
+
+#ifdef CONFIG_SMP
+	static unsigned long xmon_write_lock;
+	int lock_wait = 1000000;
+	int locked;
+
+	while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
+		if (--lock_wait == 0)
+			break;
+#endif
+
+#ifdef CONFIG_BOOTX_TEXT
+	if (use_screen) {
+		/* write it on the screen */
+		for (i = 0; i < nb; ++i)
+			btext_drawchar(*p++);
+		goto out;
+	}
+#endif
+	if (!scc_initialized)
+		xmon_init_scc();
+	ct = 0;
+	for (i = 0; i < nb; ++i) {
+		while ((*sccc & TXRDY) == 0)
+			do_poll_adb();
+		c = p[i];
+		if (c == '\n' && !ct) {
+			c = '\r';
+			ct = 1;
+			--i;
+		} else {
+			ct = 0;
+		}
+		buf_access();
+		*sccd = c;
+		eieio();
+	}
+
+ out:
+#ifdef CONFIG_SMP
+	if (!locked)
+		clear_bit(0, &xmon_write_lock);
+#endif
+	return nb;
+}
+
+int xmon_wants_key;
+int xmon_adb_keycode;
+
+#ifdef CONFIG_BOOTX_TEXT
+static int xmon_adb_shiftstate;
+
+static unsigned char xmon_keytab[128] =
+	"asdfhgzxcv\000bqwer"				/* 0x00 - 0x0f */
+	"yt123465=97-80]o"				/* 0x10 - 0x1f */
+	"u[ip\rlj'k;\\,/nm."				/* 0x20 - 0x2f */
+	"\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"		/* 0x30 - 0x3f */
+	"\0.\0*\0+\0\0\0\0\0/\r\0-\0"			/* 0x40 - 0x4f */
+	"\0\0000123456789\0\0\0";			/* 0x50 - 0x5f */
+
+static unsigned char xmon_shift_keytab[128] =
+	"ASDFHGZXCV\000BQWER"				/* 0x00 - 0x0f */
+	"YT!@#$^%+(&_*)}O"				/* 0x10 - 0x1f */
+	"U{IP\rLJ\"K:|<?NM>"				/* 0x20 - 0x2f */
+	"\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"		/* 0x30 - 0x3f */
+	"\0.\0*\0+\0\0\0\0\0/\r\0-\0"			/* 0x40 - 0x4f */
+	"\0\0000123456789\0\0\0";			/* 0x50 - 0x5f */
+
+static int
+xmon_get_adb_key(void)
+{
+	int k, t, on;
+
+	xmon_wants_key = 1;
+	for (;;) {
+		xmon_adb_keycode = -1;
+		t = 0;
+		on = 0;
+		do {
+			if (--t < 0) {
+				on = 1 - on;
+				btext_drawchar(on? 0xdb: 0x20);
+				btext_drawchar('\b');
+				t = 200000;
+			}
+			do_poll_adb();
+		} while (xmon_adb_keycode == -1);
+		k = xmon_adb_keycode;
+		if (on)
+			btext_drawstring(" \b");
+
+		/* test for shift keys */
+		if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
+			xmon_adb_shiftstate = (k & 0x80) == 0;
+			continue;
+		}
+		if (k >= 0x80)
+			continue;	/* ignore up transitions */
+		k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
+		if (k != 0)
+			break;
+	}
+	xmon_wants_key = 0;
+	return k;
+}
+#endif /* CONFIG_BOOTX_TEXT */
+
+int
+xmon_read(void *handle, void *ptr, int nb)
+{
+    char *p = ptr;
+    int i;
+
+#ifdef CONFIG_BOOTX_TEXT
+    if (use_screen) {
+	for (i = 0; i < nb; ++i)
+	    *p++ = xmon_get_adb_key();
+	return i;
+    }
+#endif
+    if (!scc_initialized)
+	xmon_init_scc();
+    for (i = 0; i < nb; ++i) {
+	while ((*sccc & RXRDY) == 0)
+	    do_poll_adb();
+	buf_access();
+	*p++ = *sccd;
+    }
+    return i;
+}
+
+int
+xmon_read_poll(void)
+{
+	if ((*sccc & RXRDY) == 0) {
+		do_poll_adb();
+		return -1;
+	}
+	buf_access();
+	return *sccd;
+}
+
+static unsigned char scc_inittab[] = {
+    13, 0,		/* set baud rate divisor */
+    12, 1,
+    14, 1,		/* baud rate gen enable, src=rtxc */
+    11, 0x50,		/* clocks = br gen */
+    5,  0xea,		/* tx 8 bits, assert DTR & RTS */
+    4,  0x46,		/* x16 clock, 1 stop */
+    3,  0xc1,		/* rx enable, 8 bits */
+};
+
+void
+xmon_init_scc(void)
+{
+	if ( _machine == _MACH_chrp )
+	{
+		sccd[3] = 0x83; eieio();	/* LCR = 8N1 + DLAB */
+		sccd[0] = 12; eieio();		/* DLL = 9600 baud */
+		sccd[1] = 0; eieio();
+		sccd[2] = 0; eieio();		/* FCR = 0 */
+		sccd[3] = 3; eieio();		/* LCR = 8N1 */
+		sccd[1] = 0; eieio();		/* IER = 0 */
+	}
+	else if ( _machine == _MACH_Pmac )
+	{
+		int i, x;
+
+		if (channel_node != 0)
+			pmac_call_feature(
+				PMAC_FTR_SCC_ENABLE,
+				channel_node,
+				PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
+			printk(KERN_INFO "Serial port locked ON by debugger !\n");
+		if (via_modem && channel_node != 0) {
+			unsigned int t0;
+
+			pmac_call_feature(
+				PMAC_FTR_MODEM_ENABLE,
+				channel_node, 0, 1);
+			printk(KERN_INFO "Modem powered up by debugger !\n");
+			t0 = readtb();
+			while (readtb() - t0 < 3*TB_SPEED)
+				eieio();
+		}
+		/* use the B channel if requested */
+		if (xmon_use_sccb) {
+			sccc = (volatile unsigned char *)
+				((unsigned long)sccc & ~0x20);
+			sccd = sccc + 0x10;
+		}
+		for (i = 20000; i != 0; --i) {
+			x = *sccc; eieio();
+		}
+		*sccc = 9; eieio();		/* reset A or B side */
+		*sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
+		for (i = 0; i < sizeof(scc_inittab); ++i) {
+			*sccc = scc_inittab[i];
+			eieio();
+		}
+	}
+	scc_initialized = 1;
+	if (via_modem) {
+		for (;;) {
+			xmon_write(NULL, "ATE1V1\r", 7);
+			if (xmon_expect("OK", 5)) {
+				xmon_write(NULL, "ATA\r", 4);
+				if (xmon_expect("CONNECT", 40))
+					break;
+			}
+			xmon_write(NULL, "+++", 3);
+			xmon_expect("OK", 3);
+		}
+	}
+}
+
+#if 0
+extern int (*prom_entry)(void *);
+
+int
+xmon_exit(void)
+{
+    struct prom_args {
+	char *service;
+    } args;
+
+    for (;;) {
+	args.service = "exit";
+	(*prom_entry)(&args);
+    }
+}
+#endif
+
+void *xmon_stdin;
+void *xmon_stdout;
+void *xmon_stderr;
+
+void
+xmon_init(void)
+{
+}
+
+int
+xmon_putc(int c, void *f)
+{
+    char ch = c;
+
+    if (c == '\n')
+	xmon_putc('\r', f);
+    return xmon_write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+xmon_putchar(int c)
+{
+    return xmon_putc(c, xmon_stdout);
+}
+
+int
+xmon_fputs(char *str, void *f)
+{
+    int n = strlen(str);
+
+    return xmon_write(f, str, n) == n? 0: -1;
+}
+
+int
+xmon_readchar(void)
+{
+    char ch;
+
+    for (;;) {
+	switch (xmon_read(xmon_stdin, &ch, 1)) {
+	case 1:
+	    return ch;
+	case -1:
+	    xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+	    return -1;
+	}
+    }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int xmon_expect(const char *str, unsigned int timeout)
+{
+	int c;
+	unsigned int t0;
+
+	timeout *= TB_SPEED;
+	t0 = readtb();
+	do {
+		lineptr = line;
+		for (;;) {
+			c = xmon_read_poll();
+			if (c == -1) {
+				if (readtb() - t0 > timeout)
+					return 0;
+				continue;
+			}
+			if (c == '\n')
+				break;
+			if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+				*lineptr++ = c;
+		}
+		*lineptr = 0;
+	} while (strstr(line, str) == NULL);
+	return 1;
+}
+
+int
+xmon_getchar(void)
+{
+    int c;
+
+    if (lineleft == 0) {
+	lineptr = line;
+	for (;;) {
+	    c = xmon_readchar();
+	    if (c == -1 || c == 4)
+		break;
+	    if (c == '\r' || c == '\n') {
+		*lineptr++ = '\n';
+		xmon_putchar('\n');
+		break;
+	    }
+	    switch (c) {
+	    case 0177:
+	    case '\b':
+		if (lineptr > line) {
+		    xmon_putchar('\b');
+		    xmon_putchar(' ');
+		    xmon_putchar('\b');
+		    --lineptr;
+		}
+		break;
+	    case 'U' & 0x1F:
+		while (lineptr > line) {
+		    xmon_putchar('\b');
+		    xmon_putchar(' ');
+		    xmon_putchar('\b');
+		    --lineptr;
+		}
+		break;
+	    default:
+		if (lineptr >= &line[sizeof(line) - 1])
+		    xmon_putchar('\a');
+		else {
+		    xmon_putchar(c);
+		    *lineptr++ = c;
+		}
+	    }
+	}
+	lineleft = lineptr - line;
+	lineptr = line;
+    }
+    if (lineleft == 0)
+	return -1;
+    --lineleft;
+    return *lineptr++;
+}
+
+char *
+xmon_fgets(char *str, int nb, void *f)
+{
+    char *p;
+    int c;
+
+    for (p = str; p < str + nb - 1; ) {
+	c = xmon_getchar();
+	if (c == -1) {
+	    if (p == str)
+		return NULL;
+	    break;
+	}
+	*p++ = c;
+	if (c == '\n')
+	    break;
+    }
+    *p = 0;
+    return str;
+}
+
+void
+xmon_enter(void)
+{
+#ifdef CONFIG_ADB_PMU
+	if (_machine == _MACH_Pmac) {
+		pmu_suspend();
+	}
+#endif
+}
+
+void
+xmon_leave(void)
+{
+#ifdef CONFIG_ADB_PMU
+	if (_machine == _MACH_Pmac) {
+		pmu_resume();
+	}
+#endif
+}
diff --git a/arch/ppc/xmon/start_8xx.c b/arch/ppc/xmon/start_8xx.c
new file mode 100644
index 0000000..a48bd59
--- /dev/null
+++ b/arch/ppc/xmon/start_8xx.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 2000 Dan Malek.
+ * Quick hack of Paul's code to make XMON work on 8xx processors.  Lots
+ * of assumptions, like the SMC1 is used, it has been initialized by the
+ * loader at some point, and we can just stuff and suck bytes.
+ * We rely upon the 8xx uart driver to support us, as the interface
+ * changes between boot up and operational phases of the kernel.
+ */
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/kernel.h>
+#include <asm/8xx_immap.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+
+extern void xmon_printf(const char *fmt, ...);
+extern int xmon_8xx_write(char *str, int nb);
+extern int xmon_8xx_read_poll(void);
+extern int xmon_8xx_read_char(void);
+void prom_drawhex(uint);
+void prom_drawstring(const char *str);
+
+static int use_screen = 1; /* default */
+
+#define TB_SPEED	25000000
+
+static inline unsigned int readtb(void)
+{
+	unsigned int ret;
+
+	asm volatile("mftb %0" : "=r" (ret) :);
+	return ret;
+}
+
+void buf_access(void)
+{
+}
+
+void
+xmon_map_scc(void)
+{
+
+	cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+	use_screen = 0;
+	
+	prom_drawstring("xmon uses serial port\n");
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+
+int
+xmon_write(void *handle, void *ptr, int nb)
+{
+	char *p = ptr;
+	int i, c, ct;
+
+	if (!scc_initialized)
+		xmon_init_scc();
+
+	return(xmon_8xx_write(ptr, nb));
+}
+
+int xmon_wants_key;
+
+int
+xmon_read(void *handle, void *ptr, int nb)
+{
+	char *p = ptr;
+	int i;
+
+	if (!scc_initialized)
+		xmon_init_scc();
+
+	for (i = 0; i < nb; ++i) {
+		*p++ = xmon_8xx_read_char();
+	}
+	return i;
+}
+
+int
+xmon_read_poll(void)
+{
+	return(xmon_8xx_read_poll());
+}
+
+void
+xmon_init_scc()
+{
+	scc_initialized = 1;
+}
+
+#if 0
+extern int (*prom_entry)(void *);
+
+int
+xmon_exit(void)
+{
+    struct prom_args {
+	char *service;
+    } args;
+
+    for (;;) {
+	args.service = "exit";
+	(*prom_entry)(&args);
+    }
+}
+#endif
+
+void *xmon_stdin;
+void *xmon_stdout;
+void *xmon_stderr;
+
+void
+xmon_init(void)
+{
+}
+
+int
+xmon_putc(int c, void *f)
+{
+    char ch = c;
+
+    if (c == '\n')
+	xmon_putc('\r', f);
+    return xmon_write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+xmon_putchar(int c)
+{
+    return xmon_putc(c, xmon_stdout);
+}
+
+int
+xmon_fputs(char *str, void *f)
+{
+    int n = strlen(str);
+
+    return xmon_write(f, str, n) == n? 0: -1;
+}
+
+int
+xmon_readchar(void)
+{
+    char ch;
+
+    for (;;) {
+	switch (xmon_read(xmon_stdin, &ch, 1)) {
+	case 1:
+	    return ch;
+	case -1:
+	    xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+	    return -1;
+	}
+    }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+#if 0
+int xmon_expect(const char *str, unsigned int timeout)
+{
+	int c;
+	unsigned int t0;
+
+	timeout *= TB_SPEED;
+	t0 = readtb();
+	do {
+		lineptr = line;
+		for (;;) {
+			c = xmon_read_poll();
+			if (c == -1) {
+				if (readtb() - t0 > timeout)
+					return 0;
+				continue;
+			}
+			if (c == '\n')
+				break;
+			if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+				*lineptr++ = c;
+		}
+		*lineptr = 0;
+	} while (strstr(line, str) == NULL);
+	return 1;
+}
+#endif
+
+int
+xmon_getchar(void)
+{
+    int c;
+
+    if (lineleft == 0) {
+	lineptr = line;
+	for (;;) {
+	    c = xmon_readchar();
+	    if (c == -1 || c == 4)
+		break;
+	    if (c == '\r' || c == '\n') {
+		*lineptr++ = '\n';
+		xmon_putchar('\n');
+		break;
+	    }
+	    switch (c) {
+	    case 0177:
+	    case '\b':
+		if (lineptr > line) {
+		    xmon_putchar('\b');
+		    xmon_putchar(' ');
+		    xmon_putchar('\b');
+		    --lineptr;
+		}
+		break;
+	    case 'U' & 0x1F:
+		while (lineptr > line) {
+		    xmon_putchar('\b');
+		    xmon_putchar(' ');
+		    xmon_putchar('\b');
+		    --lineptr;
+		}
+		break;
+	    default:
+		if (lineptr >= &line[sizeof(line) - 1])
+		    xmon_putchar('\a');
+		else {
+		    xmon_putchar(c);
+		    *lineptr++ = c;
+		}
+	    }
+	}
+	lineleft = lineptr - line;
+	lineptr = line;
+    }
+    if (lineleft == 0)
+	return -1;
+    --lineleft;
+    return *lineptr++;
+}
+
+char *
+xmon_fgets(char *str, int nb, void *f)
+{
+    char *p;
+    int c;
+
+    for (p = str; p < str + nb - 1; ) {
+	c = xmon_getchar();
+	if (c == -1) {
+	    if (p == str)
+		return 0;
+	    break;
+	}
+	*p++ = c;
+	if (c == '\n')
+	    break;
+    }
+    *p = 0;
+    return str;
+}
+
+void
+prom_drawhex(uint val)
+{
+	unsigned char buf[10];
+
+	int i;
+	for (i = 7;  i >= 0;  i--)
+	{
+		buf[i] = "0123456789abcdef"[val & 0x0f];
+		val >>= 4;
+	}
+	buf[8] = '\0';
+	xmon_fputs(buf, xmon_stdout);
+}
+
+void
+prom_drawstring(const char *str)
+{
+	xmon_fputs(str, xmon_stdout);
+}
diff --git a/arch/ppc/xmon/subr_prf.c b/arch/ppc/xmon/subr_prf.c
new file mode 100644
index 0000000..126624f
--- /dev/null
+++ b/arch/ppc/xmon/subr_prf.c
@@ -0,0 +1,55 @@
+/*
+ * Written by Cort Dougan to replace the version originally used
+ * by Paul Mackerras, which came from NetBSD and thus had copyright
+ * conflicts with Linux.
+ *
+ * This file makes liberal use of the standard linux utility
+ * routines to reduce the size of the binary.  We assume we can
+ * trust some parts of Linux inside the debugger.
+ *   -- Cort (cort@cs.nmt.edu)
+ *
+ * Copyright (C) 1999 Cort Dougan.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <stdarg.h>
+#include "nonstdio.h"
+
+extern int xmon_write(void *, void *, int);
+
+void
+xmon_vfprintf(void *f, const char *fmt, va_list ap)
+{
+	static char xmon_buf[2048];
+	int n;
+
+	n = vsprintf(xmon_buf, fmt, ap);
+	xmon_write(f, xmon_buf, n);
+}
+
+void
+xmon_printf(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	xmon_vfprintf(stdout, fmt, ap);
+	va_end(ap);
+}
+
+void
+xmon_fprintf(void *f, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	xmon_vfprintf(f, fmt, ap);
+	va_end(ap);
+}
+
+void
+xmon_puts(char *s)
+{
+	xmon_write(stdout, s, strlen(s));
+}
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
new file mode 100644
index 0000000..8565f49
--- /dev/null
+++ b/arch/ppc/xmon/xmon.c
@@ -0,0 +1,2008 @@
+/*
+ * Routines providing a simple monitor for use on the PowerMac.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <asm/ptrace.h>
+#include <asm/string.h>
+#include <asm/prom.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/xmon.h>
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+#include "nonstdio.h"
+#include "privinst.h"
+
+#define scanhex	xmon_scanhex
+#define skipbl	xmon_skipbl
+
+#ifdef CONFIG_SMP
+static unsigned long cpus_in_xmon = 0;
+static unsigned long got_xmon = 0;
+static volatile int take_xmon = -1;
+#endif /* CONFIG_SMP */
+
+static unsigned adrs;
+static int size = 1;
+static unsigned ndump = 64;
+static unsigned nidump = 16;
+static unsigned ncsum = 4096;
+static int termch;
+
+static u_int bus_error_jmp[100];
+#define setjmp xmon_setjmp
+#define longjmp xmon_longjmp
+
+/* Breakpoint stuff */
+struct bpt {
+	unsigned address;
+	unsigned instr;
+	unsigned count;
+	unsigned char enabled;
+};
+
+#define NBPTS	16
+static struct bpt bpts[NBPTS];
+static struct bpt dabr;
+static struct bpt iabr;
+static unsigned bpinstr = 0x7fe00008;	/* trap */
+
+/* Prototypes */
+extern void (*debugger_fault_handler)(struct pt_regs *);
+static int cmds(struct pt_regs *);
+static int mread(unsigned, void *, int);
+static int mwrite(unsigned, void *, int);
+static void handle_fault(struct pt_regs *);
+static void byterev(unsigned char *, int);
+static void memex(void);
+static int bsesc(void);
+static void dump(void);
+static void prdump(unsigned, int);
+#ifdef __MWERKS__
+static void prndump(unsigned, int);
+static int nvreadb(unsigned);
+#endif
+static int ppc_inst_dump(unsigned, int);
+void print_address(unsigned);
+static int getsp(void);
+static void dump_hash_table(void);
+static void backtrace(struct pt_regs *);
+static void excprint(struct pt_regs *);
+static void prregs(struct pt_regs *);
+static void memops(int);
+static void memlocate(void);
+static void memzcan(void);
+static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
+int skipbl(void);
+int scanhex(unsigned *valp);
+static void scannl(void);
+static int hexdigit(int);
+void getstring(char *, int);
+static void flush_input(void);
+static int inchar(void);
+static void take_input(char *);
+/* static void openforth(void); */
+static unsigned read_spr(int);
+static void write_spr(int, unsigned);
+static void super_regs(void);
+static void print_sysmap(void);
+static void sysmap_lookup(void);
+static void remove_bpts(void);
+static void insert_bpts(void);
+static struct bpt *at_breakpoint(unsigned pc);
+static void bpt_cmds(void);
+static void cacheflush(void);
+#ifdef CONFIG_SMP
+static void cpu_cmd(void);
+#endif /* CONFIG_SMP */
+static int pretty_print_addr(unsigned long addr);
+static void csum(void);
+#ifdef CONFIG_BOOTX_TEXT
+static void vidcmds(void);
+#endif
+static void bootcmds(void);
+static void proccall(void);
+static void printtime(void);
+
+extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
+extern void printf(const char *fmt, ...);
+extern int putchar(int ch);
+extern int setjmp(u_int *);
+extern void longjmp(u_int *, int);
+
+extern void xmon_enter(void);
+extern void xmon_leave(void);
+extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr);
+extern unsigned long xmon_symbol_to_addr(char* symbol);
+
+static unsigned start_tb[NR_CPUS][2];
+static unsigned stop_tb[NR_CPUS][2];
+
+#define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
+
+#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
+			 || ('a' <= (c) && (c) <= 'f') \
+			 || ('A' <= (c) && (c) <= 'F'))
+#define isalnum(c)	(('0' <= (c) && (c) <= '9') \
+			 || ('a' <= (c) && (c) <= 'z') \
+			 || ('A' <= (c) && (c) <= 'Z'))
+#define isspace(c)	(c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
+
+static char *help_string = "\
+Commands:\n\
+  d	dump bytes\n\
+  di	dump instructions\n\
+  df	dump float values\n\
+  dd	dump double values\n\
+  e	print exception information\n\
+  h	dump hash table\n\
+  m	examine/change memory\n\
+  mm	move a block of memory\n\
+  ms	set a block of memory\n\
+  md	compare two blocks of memory\n\
+  M	print System.map\n\
+  r	print registers\n\
+  S	print special registers\n\
+  t	print backtrace\n\
+  la	lookup address in system.map\n\
+  ls	lookup symbol in system.map\n\
+  x	exit monitor\n\
+";
+
+static int xmon_trace[NR_CPUS];
+#define SSTEP	1		/* stepping because of 's' command */
+#define BRSTEP	2		/* stepping over breakpoint */
+
+static struct pt_regs *xmon_regs[NR_CPUS];
+
+extern inline void sync(void)
+{
+	asm volatile("sync; isync");
+}
+
+extern inline void __delay(unsigned int loops)
+{
+	if (loops != 0)
+		__asm__ __volatile__("mtctr %0; 1: bdnz 1b" : :
+				     "r" (loops) : "ctr");
+}
+
+static void get_tb(unsigned *p)
+{
+	unsigned hi, lo, hiagain;
+
+	if ((get_pvr() >> 16) == 1)
+		return;
+
+	do {
+		asm volatile("mftbu %0; mftb %1; mftbu %2"
+			     : "=r" (hi), "=r" (lo), "=r" (hiagain));
+	} while (hi != hiagain);
+	p[0] = hi;
+	p[1] = lo;
+}
+
+void
+xmon(struct pt_regs *excp)
+{
+	struct pt_regs regs;
+	int msr, cmd;
+
+	get_tb(stop_tb[smp_processor_id()]);
+	if (excp == NULL) {
+		asm volatile ("stw	0,0(%0)\n\
+			lwz	0,0(1)\n\
+			stw	0,4(%0)\n\
+			stmw	2,8(%0)" : : "b" (&regs));
+		regs.nip = regs.link = ((unsigned long *)regs.gpr[1])[1];
+		regs.msr = get_msr();
+		regs.ctr = get_ctr();
+		regs.xer = get_xer();
+		regs.ccr = get_cr();
+		regs.trap = 0;
+		excp = &regs;
+	}
+
+	msr = get_msr();
+	set_msr(msr & ~0x8000);	/* disable interrupts */
+	xmon_regs[smp_processor_id()] = excp;
+	xmon_enter();
+	excprint(excp);
+#ifdef CONFIG_SMP
+	if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon))
+		for (;;)
+			;
+	while (test_and_set_bit(0, &got_xmon)) {
+		if (take_xmon == smp_processor_id()) {
+			take_xmon = -1;
+			break;
+		}
+	}
+	/*
+	 * XXX: breakpoints are removed while any cpu is in xmon
+	 */
+#endif /* CONFIG_SMP */
+	remove_bpts();
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if( setjmp(bus_error_jmp) == 0 ) {
+		debugger_fault_handler = handle_fault;
+		sync();
+		set_backlight_enable(1);
+		set_backlight_level(BACKLIGHT_MAX);
+		sync();
+	}
+	debugger_fault_handler = NULL;
+#endif	/* CONFIG_PMAC_BACKLIGHT */
+	cmd = cmds(excp);
+	if (cmd == 's') {
+		xmon_trace[smp_processor_id()] = SSTEP;
+		excp->msr |= 0x400;
+	} else if (at_breakpoint(excp->nip)) {
+		xmon_trace[smp_processor_id()] = BRSTEP;
+		excp->msr |= 0x400;
+	} else {
+		xmon_trace[smp_processor_id()] = 0;
+		insert_bpts();
+	}
+	xmon_leave();
+	xmon_regs[smp_processor_id()] = NULL;
+#ifdef CONFIG_SMP
+	clear_bit(0, &got_xmon);
+	clear_bit(smp_processor_id(), &cpus_in_xmon);
+#endif /* CONFIG_SMP */
+	set_msr(msr);		/* restore interrupt enable */
+	get_tb(start_tb[smp_processor_id()]);
+}
+
+irqreturn_t
+xmon_irq(int irq, void *d, struct pt_regs *regs)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	printf("Keyboard interrupt\n");
+	xmon(regs);
+	local_irq_restore(flags);
+	return IRQ_HANDLED;
+}
+
+int
+xmon_bpt(struct pt_regs *regs)
+{
+	struct bpt *bp;
+
+	bp = at_breakpoint(regs->nip);
+	if (!bp)
+		return 0;
+	if (bp->count) {
+		--bp->count;
+		remove_bpts();
+		excprint(regs);
+		xmon_trace[smp_processor_id()] = BRSTEP;
+		regs->msr |= 0x400;
+	} else {
+		xmon(regs);
+	}
+	return 1;
+}
+
+int
+xmon_sstep(struct pt_regs *regs)
+{
+	if (!xmon_trace[smp_processor_id()])
+		return 0;
+	if (xmon_trace[smp_processor_id()] == BRSTEP) {
+		xmon_trace[smp_processor_id()] = 0;
+		insert_bpts();
+	} else {
+		xmon(regs);
+	}
+	return 1;
+}
+
+int
+xmon_dabr_match(struct pt_regs *regs)
+{
+	if (dabr.enabled && dabr.count) {
+		--dabr.count;
+		remove_bpts();
+		excprint(regs);
+		xmon_trace[smp_processor_id()] = BRSTEP;
+		regs->msr |= 0x400;
+	} else {
+		dabr.instr = regs->nip;
+		xmon(regs);
+	}
+	return 1;
+}
+
+int
+xmon_iabr_match(struct pt_regs *regs)
+{
+	if (iabr.enabled && iabr.count) {
+		--iabr.count;
+		remove_bpts();
+		excprint(regs);
+		xmon_trace[smp_processor_id()] = BRSTEP;
+		regs->msr |= 0x400;
+	} else {
+		xmon(regs);
+	}
+	return 1;
+}
+
+static struct bpt *
+at_breakpoint(unsigned pc)
+{
+	int i;
+	struct bpt *bp;
+
+	if (dabr.enabled && pc == dabr.instr)
+		return &dabr;
+	if (iabr.enabled && pc == iabr.address)
+		return &iabr;
+	bp = bpts;
+	for (i = 0; i < NBPTS; ++i, ++bp)
+		if (bp->enabled && pc == bp->address)
+			return bp;
+	return NULL;
+}
+
+static void
+insert_bpts(void)
+{
+	int i;
+	struct bpt *bp;
+
+	bp = bpts;
+	for (i = 0; i < NBPTS; ++i, ++bp) {
+		if (!bp->enabled)
+			continue;
+		if (mread(bp->address, &bp->instr, 4) != 4
+		    || mwrite(bp->address, &bpinstr, 4) != 4) {
+			printf("Couldn't insert breakpoint at %x, disabling\n",
+			       bp->address);
+			bp->enabled = 0;
+		}
+		store_inst((void *) bp->address);
+	}
+#if !defined(CONFIG_8xx)
+	if (dabr.enabled)
+		set_dabr(dabr.address);
+	if (iabr.enabled)
+		set_iabr(iabr.address);
+#endif
+}
+
+static void
+remove_bpts(void)
+{
+	int i;
+	struct bpt *bp;
+	unsigned instr;
+
+#if !defined(CONFIG_8xx)
+	set_dabr(0);
+	set_iabr(0);
+#endif
+	bp = bpts;
+	for (i = 0; i < NBPTS; ++i, ++bp) {
+		if (!bp->enabled)
+			continue;
+		if (mread(bp->address, &instr, 4) == 4
+		    && instr == bpinstr
+		    && mwrite(bp->address, &bp->instr, 4) != 4)
+			printf("Couldn't remove breakpoint at %x\n",
+			       bp->address);
+		store_inst((void *) bp->address);
+	}
+}
+
+static char *last_cmd;
+
+/* Command interpreting routine */
+static int
+cmds(struct pt_regs *excp)
+{
+	int cmd;
+
+	last_cmd = NULL;
+	for(;;) {
+#ifdef CONFIG_SMP
+		printf("%d:", smp_processor_id());
+#endif /* CONFIG_SMP */
+		printf("mon> ");
+		fflush(stdout);
+		flush_input();
+		termch = 0;
+		cmd = skipbl();
+		if( cmd == '\n' ) {
+			if (last_cmd == NULL)
+				continue;
+			take_input(last_cmd);
+			last_cmd = NULL;
+			cmd = inchar();
+		}
+		switch (cmd) {
+		case 'm':
+			cmd = inchar();
+			switch (cmd) {
+			case 'm':
+			case 's':
+			case 'd':
+				memops(cmd);
+				break;
+			case 'l':
+				memlocate();
+				break;
+			case 'z':
+				memzcan();
+				break;
+			default:
+				termch = cmd;
+				memex();
+			}
+			break;
+		case 'd':
+			dump();
+			break;
+		case 'l':
+			sysmap_lookup();
+			break;
+		case 'r':
+			if (excp != NULL)
+				prregs(excp);	/* print regs */
+			break;
+		case 'e':
+			if (excp == NULL)
+				printf("No exception information\n");
+			else
+				excprint(excp);
+			break;
+		case 'M':
+			print_sysmap();
+			break;
+		case 'S':
+			super_regs();
+			break;
+		case 't':
+			backtrace(excp);
+			break;
+		case 'f':
+			cacheflush();
+			break;
+		case 'h':
+			dump_hash_table();
+			break;
+		case 's':
+		case 'x':
+		case EOF:
+			return cmd;
+		case '?':
+			printf(help_string);
+			break;
+		default:
+			printf("Unrecognized command: ");
+			if( ' ' < cmd && cmd <= '~' )
+				putchar(cmd);
+			else
+				printf("\\x%x", cmd);
+			printf(" (type ? for help)\n");
+			break;
+		case 'b':
+			bpt_cmds();
+			break;
+		case 'C':
+			csum();
+			break;
+#ifdef CONFIG_SMP
+		case 'c':
+			cpu_cmd();
+			break;
+#endif /* CONFIG_SMP */
+#ifdef CONFIG_BOOTX_TEXT
+		case 'v':
+			vidcmds();
+			break;
+#endif
+		case 'z':
+			bootcmds();
+			break;
+		case 'p':
+			proccall();
+			break;
+		case 'T':
+			printtime();
+			break;
+		}
+	}
+}
+
+extern unsigned tb_to_us;
+
+#define mulhwu(x,y) \
+({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+
+static void printtime(void)
+{
+	unsigned int delta;
+
+	delta = stop_tb[smp_processor_id()][1]
+		- start_tb[smp_processor_id()][1];
+	delta = mulhwu(tb_to_us, delta);
+	printf("%u.%06u seconds\n", delta / 1000000, delta % 1000000);
+}
+
+static void bootcmds(void)
+{
+	int cmd;
+
+	cmd = inchar();
+	if (cmd == 'r')
+		ppc_md.restart(NULL);
+	else if (cmd == 'h')
+		ppc_md.halt();
+	else if (cmd == 'p')
+		ppc_md.power_off();
+}
+
+#ifdef CONFIG_SMP
+static void cpu_cmd(void)
+{
+	unsigned cpu;
+	int timeout;
+	int cmd;
+
+	cmd = inchar();
+	if (cmd == 'i') {
+		/* interrupt other cpu(s) */
+		cpu = MSG_ALL_BUT_SELF;
+		if (scanhex(&cpu))
+			smp_send_xmon_break(cpu);
+		return;
+	}
+	termch = cmd;
+	if (!scanhex(&cpu)) {
+		/* print cpus waiting or in xmon */
+		printf("cpus stopped:");
+		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+			if (test_bit(cpu, &cpus_in_xmon)) {
+				printf(" %d", cpu);
+				if (cpu == smp_processor_id())
+					printf("*", cpu);
+			}
+		}
+		printf("\n");
+		return;
+	}
+	/* try to switch to cpu specified */
+	take_xmon = cpu;
+	timeout = 10000000;
+	while (take_xmon >= 0) {
+		if (--timeout == 0) {
+			/* yes there's a race here */
+			take_xmon = -1;
+			printf("cpu %u didn't take control\n", cpu);
+			return;
+		}
+	}
+	/* now have to wait to be given control back */
+	while (test_and_set_bit(0, &got_xmon)) {
+		if (take_xmon == smp_processor_id()) {
+			take_xmon = -1;
+			break;
+		}
+	}
+}
+#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_BOOTX_TEXT
+extern boot_infos_t disp_bi;
+
+static void vidcmds(void)
+{
+	int c = inchar();
+	unsigned int val, w;
+	extern int boot_text_mapped;
+
+	if (!boot_text_mapped)
+		return;
+	if (c != '\n' && scanhex(&val)) {
+		switch (c) {
+		case 'd':
+			w = disp_bi.dispDeviceRowBytes
+				/ (disp_bi.dispDeviceDepth >> 3);
+			disp_bi.dispDeviceDepth = val;
+			disp_bi.dispDeviceRowBytes = w * (val >> 3);
+			return;
+		case 'p':
+			disp_bi.dispDeviceRowBytes = val;
+			return;
+		case 'w':
+			disp_bi.dispDeviceRect[2] = val;
+			return;
+		case 'h':
+			disp_bi.dispDeviceRect[3] = val;
+			return;
+		}
+	}
+	printf("W = %d (0x%x) H = %d (0x%x) D = %d (0x%x) P = %d (0x%x)\n",
+	       disp_bi.dispDeviceRect[2], disp_bi.dispDeviceRect[2],
+	       disp_bi.dispDeviceRect[3], disp_bi.dispDeviceRect[3],
+	       disp_bi.dispDeviceDepth, disp_bi.dispDeviceDepth,
+	       disp_bi.dispDeviceRowBytes, disp_bi.dispDeviceRowBytes);
+}
+#endif /* CONFIG_BOOTX_TEXT */
+
+static unsigned short fcstab[256] = {
+	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+#define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
+
+static void
+csum(void)
+{
+	unsigned int i;
+	unsigned short fcs;
+	unsigned char v;
+
+	if (!scanhex(&adrs))
+		return;
+	if (!scanhex(&ncsum))
+		return;
+	fcs = 0xffff;
+	for (i = 0; i < ncsum; ++i) {
+		if (mread(adrs+i, &v, 1) == 0) {
+			printf("csum stopped at %x\n", adrs+i);
+			break;
+		}
+		fcs = FCS(fcs, v);
+	}
+	printf("%x\n", fcs);
+}
+
+static void
+bpt_cmds(void)
+{
+	int cmd;
+	unsigned a;
+	int mode, i;
+	struct bpt *bp;
+
+	cmd = inchar();
+	switch (cmd) {
+#if !defined(CONFIG_8xx)
+	case 'd':
+		mode = 7;
+		cmd = inchar();
+		if (cmd == 'r')
+			mode = 5;
+		else if (cmd == 'w')
+			mode = 6;
+		else
+			termch = cmd;
+		cmd = inchar();
+		if (cmd == 'p')
+			mode &= ~4;
+		else
+			termch = cmd;
+		dabr.address = 0;
+		dabr.count = 0;
+		dabr.enabled = scanhex(&dabr.address);
+		scanhex(&dabr.count);
+		if (dabr.enabled)
+			dabr.address = (dabr.address & ~7) | mode;
+		break;
+	case 'i':
+		cmd = inchar();
+		if (cmd == 'p')
+			mode = 2;
+		else
+			mode = 3;
+		iabr.address = 0;
+		iabr.count = 0;
+		iabr.enabled = scanhex(&iabr.address);
+		if (iabr.enabled)
+			iabr.address |= mode;
+		scanhex(&iabr.count);
+		break;
+#endif
+	case 'c':
+		if (!scanhex(&a)) {
+			/* clear all breakpoints */
+			for (i = 0; i < NBPTS; ++i)
+				bpts[i].enabled = 0;
+			iabr.enabled = 0;
+			dabr.enabled = 0;
+			printf("All breakpoints cleared\n");
+		} else {
+			bp = at_breakpoint(a);
+			if (bp == 0) {
+				printf("No breakpoint at %x\n", a);
+			} else {
+				bp->enabled = 0;
+			}
+		}
+		break;
+	default:
+		termch = cmd;
+		if (!scanhex(&a)) {
+			/* print all breakpoints */
+			printf("type  address   count\n");
+			if (dabr.enabled) {
+				printf("data %.8x %8x [", dabr.address & ~7,
+				       dabr.count);
+				if (dabr.address & 1)
+					printf("r");
+				if (dabr.address & 2)
+					printf("w");
+				if (!(dabr.address & 4))
+					printf("p");
+				printf("]\n");
+			}
+			if (iabr.enabled)
+				printf("inst %.8x %8x\n", iabr.address & ~3,
+				       iabr.count);
+			for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
+				if (bp->enabled)
+					printf("trap %.8x %8x\n", bp->address,
+					       bp->count);
+			break;
+		}
+		bp = at_breakpoint(a);
+		if (bp == 0) {
+			for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
+				if (!bp->enabled)
+					break;
+			if (bp >= &bpts[NBPTS]) {
+				printf("Sorry, no free breakpoints\n");
+				break;
+			}
+		}
+		bp->enabled = 1;
+		bp->address = a;
+		bp->count = 0;
+		scanhex(&bp->count);
+		break;
+	}
+}
+
+static void
+backtrace(struct pt_regs *excp)
+{
+	unsigned sp;
+	unsigned stack[2];
+	struct pt_regs regs;
+	extern char ret_from_except, ret_from_except_full, ret_from_syscall;
+
+	printf("backtrace:\n");
+	
+	if (excp != NULL)
+		sp = excp->gpr[1];
+	else
+		sp = getsp();
+	scanhex(&sp);
+	scannl();
+	for (; sp != 0; sp = stack[0]) {
+		if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
+			break;
+		pretty_print_addr(stack[1]);
+		printf(" ");
+		if (stack[1] == (unsigned) &ret_from_except
+		    || stack[1] == (unsigned) &ret_from_except_full
+		    || stack[1] == (unsigned) &ret_from_syscall) {
+			if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs))
+				break;
+			printf("\nexception:%x [%x] %x ", regs.trap, sp+16,
+			       regs.nip);
+			sp = regs.gpr[1];
+			if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
+				break;
+		}
+		printf("\n");
+	}
+}
+
+int
+getsp(void)
+{
+    int x;
+
+    asm("mr %0,1" : "=r" (x) :);
+    return x;
+}
+
+void
+excprint(struct pt_regs *fp)
+{
+	int trap;
+
+#ifdef CONFIG_SMP
+	printf("cpu %d: ", smp_processor_id());
+#endif /* CONFIG_SMP */
+	printf("vector: %x at pc = ", fp->trap);
+	pretty_print_addr(fp->nip);
+	printf(", lr = ");
+	pretty_print_addr(fp->link);
+	printf("\nmsr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp);
+	trap = TRAP(fp);
+	if (trap == 0x300 || trap == 0x600)
+		printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr);
+	if (current)
+		printf("current = %x, pid = %d, comm = %s\n",
+		       current, current->pid, current->comm);
+}
+
+void
+prregs(struct pt_regs *fp)
+{
+	int n;
+	unsigned base;
+
+	if (scanhex(&base))
+		fp = (struct pt_regs *) base;
+	for (n = 0; n < 32; ++n) {
+		printf("R%.2d = %.8x%s", n, fp->gpr[n],
+		       (n & 3) == 3? "\n": "   ");
+		if (n == 12 && !FULL_REGS(fp)) {
+			printf("\n");
+			break;
+		}
+	}
+	printf("pc  = %.8x   msr = %.8x   lr  = %.8x   cr  = %.8x\n",
+	       fp->nip, fp->msr, fp->link, fp->ccr);
+	printf("ctr = %.8x   xer = %.8x   trap = %4x\n",
+	       fp->ctr, fp->xer, fp->trap);
+}
+
+void
+cacheflush(void)
+{
+	int cmd;
+	unsigned nflush;
+
+	cmd = inchar();
+	if (cmd != 'i')
+		termch = cmd;
+	scanhex(&adrs);
+	if (termch != '\n')
+		termch = 0;
+	nflush = 1;
+	scanhex(&nflush);
+	nflush = (nflush + 31) / 32;
+	if (cmd != 'i') {
+		for (; nflush > 0; --nflush, adrs += 0x20)
+			cflush((void *) adrs);
+	} else {
+		for (; nflush > 0; --nflush, adrs += 0x20)
+			cinval((void *) adrs);
+	}
+}
+
+unsigned int
+read_spr(int n)
+{
+    unsigned int instrs[2];
+    int (*code)(void);
+
+    instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
+    instrs[1] = 0x4e800020;
+    store_inst(instrs);
+    store_inst(instrs+1);
+    code = (int (*)(void)) instrs;
+    return code();
+}
+
+void
+write_spr(int n, unsigned int val)
+{
+    unsigned int instrs[2];
+    int (*code)(unsigned int);
+
+    instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
+    instrs[1] = 0x4e800020;
+    store_inst(instrs);
+    store_inst(instrs+1);
+    code = (int (*)(unsigned int)) instrs;
+    code(val);
+}
+
+static unsigned int regno;
+extern char exc_prolog;
+extern char dec_exc;
+
+void
+print_sysmap(void)
+{
+	extern char *sysmap;
+	if ( sysmap ) {
+		printf("System.map: \n");
+		if( setjmp(bus_error_jmp) == 0 ) {
+			debugger_fault_handler = handle_fault;
+			sync();
+			xmon_puts(sysmap);
+			sync();
+		}
+		debugger_fault_handler = NULL;
+	}
+	else
+		printf("No System.map\n");
+}
+
+void
+super_regs(void)
+{
+	int i, cmd;
+	unsigned val;
+
+	cmd = skipbl();
+	if (cmd == '\n') {
+		printf("msr = %x, pvr = %x\n", get_msr(), get_pvr());
+		printf("sprg0-3 = %x %x %x %x\n", get_sprg0(), get_sprg1(),
+		       get_sprg2(), get_sprg3());
+		printf("srr0 = %x, srr1 = %x\n", get_srr0(), get_srr1());
+#ifdef CONFIG_PPC_STD_MMU
+		printf("sr0-15 =");
+		for (i = 0; i < 16; ++i)
+			printf(" %x", get_sr(i));
+		printf("\n");
+#endif
+		asm("mr %0,1" : "=r" (i) :);
+		printf("sp = %x ", i);
+		asm("mr %0,2" : "=r" (i) :);
+		printf("toc = %x\n", i);
+		return;
+	}
+
+	scanhex(&regno);
+	switch (cmd) {
+	case 'w':
+		val = read_spr(regno);
+		scanhex(&val);
+		write_spr(regno, val);
+		/* fall through */
+	case 'r':
+		printf("spr %x = %x\n", regno, read_spr(regno));
+		break;
+	case 's':
+		val = get_sr(regno);
+		scanhex(&val);
+		set_sr(regno, val);
+		break;
+	case 'm':
+		val = get_msr();
+		scanhex(&val);
+		set_msr(val);
+		break;
+	}
+	scannl();
+}
+
+#ifndef CONFIG_PPC_STD_MMU
+static void
+dump_hash_table(void)
+{
+	printf("This CPU doesn't have a hash table.\n");
+}
+#else
+
+#ifndef CONFIG_PPC64BRIDGE
+static void
+dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+{
+	extern void *Hash;
+	extern unsigned long Hash_size;
+	unsigned *htab = Hash;
+	unsigned hsize = Hash_size;
+	unsigned v, hmask, va, last_va = 0;
+	int found, last_found, i;
+	unsigned *hg, w1, last_w2 = 0, last_va0 = 0;
+
+	last_found = 0;
+	hmask = hsize / 64 - 1;
+	va = start;
+	start = (start >> 12) & 0xffff;
+	end = (end >> 12) & 0xffff;
+	for (v = start; v < end; ++v) {
+		found = 0;
+		hg = htab + (((v ^ seg) & hmask) * 16);
+		w1 = 0x80000000 | (seg << 7) | (v >> 10);
+		for (i = 0; i < 8; ++i, hg += 2) {
+			if (*hg == w1) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found) {
+			w1 ^= 0x40;
+			hg = htab + ((~(v ^ seg) & hmask) * 16);
+			for (i = 0; i < 8; ++i, hg += 2) {
+				if (*hg == w1) {
+					found = 1;
+					break;
+				}
+			}
+		}
+		if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) {
+			if (last_found) {
+				if (last_va != last_va0)
+					printf(" ... %x", last_va);
+				printf("\n");
+			}
+			if (found) {
+				printf("%x to %x", va, hg[1]);
+				last_va0 = va;
+			}
+			last_found = found;
+		}
+		if (found) {
+			last_w2 = hg[1] & ~0x180;
+			last_va = va;
+		}
+		va += 4096;
+	}
+	if (last_found)
+		printf(" ... %x\n", last_va);
+}
+
+#else /* CONFIG_PPC64BRIDGE */
+static void
+dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+{
+	extern void *Hash;
+	extern unsigned long Hash_size;
+	unsigned *htab = Hash;
+	unsigned hsize = Hash_size;
+	unsigned v, hmask, va, last_va;
+	int found, last_found, i;
+	unsigned *hg, w1, last_w2, last_va0;
+
+	last_found = 0;
+	hmask = hsize / 128 - 1;
+	va = start;
+	start = (start >> 12) & 0xffff;
+	end = (end >> 12) & 0xffff;
+	for (v = start; v < end; ++v) {
+		found = 0;
+		hg = htab + (((v ^ seg) & hmask) * 32);
+		w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4);
+		for (i = 0; i < 8; ++i, hg += 4) {
+			if (hg[1] == w1) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found) {
+			w1 ^= 2;
+			hg = htab + ((~(v ^ seg) & hmask) * 32);
+			for (i = 0; i < 8; ++i, hg += 4) {
+				if (hg[1] == w1) {
+					found = 1;
+					break;
+				}
+			}
+		}
+		if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) {
+			if (last_found) {
+				if (last_va != last_va0)
+					printf(" ... %x", last_va);
+				printf("\n");
+			}
+			if (found) {
+				printf("%x to %x", va, hg[3]);
+				last_va0 = va;
+			}
+			last_found = found;
+		}
+		if (found) {
+			last_w2 = hg[3] & ~0x180;
+			last_va = va;
+		}
+		va += 4096;
+	}
+	if (last_found)
+		printf(" ... %x\n", last_va);
+}
+#endif /* CONFIG_PPC64BRIDGE */
+
+static unsigned hash_ctx;
+static unsigned hash_start;
+static unsigned hash_end;
+
+static void
+dump_hash_table(void)
+{
+	int seg;
+	unsigned seg_start, seg_end;
+
+	hash_ctx = 0;
+	hash_start = 0;
+	hash_end = 0xfffff000;
+	scanhex(&hash_ctx);
+	scanhex(&hash_start);
+	scanhex(&hash_end);
+	printf("Mappings for context %x\n", hash_ctx);
+	seg_start = hash_start;
+	for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) {
+		seg_end = (seg << 28) | 0x0ffff000;
+		if (seg_end > hash_end)
+			seg_end = hash_end;
+		dump_hash_table_seg((hash_ctx << 4) + (seg * 0x111),
+				    seg_start, seg_end);
+		seg_start = seg_end + 0x1000;
+	}
+}
+#endif /* CONFIG_PPC_STD_MMU */
+
+/*
+ * Stuff for reading and writing memory safely
+ */
+
+int
+mread(unsigned adrs, void *buf, int size)
+{
+	volatile int n;
+	char *p, *q;
+
+	n = 0;
+	if( setjmp(bus_error_jmp) == 0 ){
+		debugger_fault_handler = handle_fault;
+		sync();
+		p = (char *) adrs;
+		q = (char *) buf;
+		switch (size) {
+		case 2: *(short *)q = *(short *)p;	break;
+		case 4: *(int *)q = *(int *)p;		break;
+		default:
+			for( ; n < size; ++n ) {
+				*q++ = *p++;
+				sync();
+			}
+		}
+		sync();
+		/* wait a little while to see if we get a machine check */
+		__delay(200);
+		n = size;
+	}
+	debugger_fault_handler = NULL;
+	return n;
+}
+
+int
+mwrite(unsigned adrs, void *buf, int size)
+{
+	volatile int n;
+	char *p, *q;
+
+	n = 0;
+	if( setjmp(bus_error_jmp) == 0 ){
+		debugger_fault_handler = handle_fault;
+		sync();
+		p = (char *) adrs;
+		q = (char *) buf;
+		switch (size) {
+		case 2: *(short *)p = *(short *)q;	break;
+		case 4: *(int *)p = *(int *)q;		break;
+		default:
+			for( ; n < size; ++n ) {
+				*p++ = *q++;
+				sync();
+			}
+		}
+		sync();
+		n = size;
+	} else {
+		printf("*** Error writing address %x\n", adrs + n);
+	}
+	debugger_fault_handler = NULL;
+	return n;
+}
+
+static int fault_type;
+static int fault_except;
+static char *fault_chars[] = { "--", "**", "##" };
+
+static void
+handle_fault(struct pt_regs *regs)
+{
+	fault_except = TRAP(regs);
+	fault_type = TRAP(regs) == 0x200? 0: TRAP(regs) == 0x300? 1: 2;
+	longjmp(bus_error_jmp, 1);
+}
+
+#define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
+
+void
+byterev(unsigned char *val, int size)
+{
+	int t;
+	
+	switch (size) {
+	case 2:
+		SWAP(val[0], val[1], t);
+		break;
+	case 4:
+		SWAP(val[0], val[3], t);
+		SWAP(val[1], val[2], t);
+		break;
+	}
+}
+
+static int brev;
+static int mnoread;
+
+void
+memex(void)
+{
+    int cmd, inc, i, nslash;
+    unsigned n;
+    unsigned char val[4];
+
+    last_cmd = "m\n";
+    scanhex(&adrs);
+    while ((cmd = skipbl()) != '\n') {
+	switch( cmd ){
+	case 'b':	size = 1;	break;
+	case 'w':	size = 2;	break;
+	case 'l':	size = 4;	break;
+	case 'r': 	brev = !brev;	break;
+	case 'n':	mnoread = 1;	break;
+	case '.':	mnoread = 0;	break;
+	}
+    }
+    if( size <= 0 )
+	size = 1;
+    else if( size > 4 )
+	size = 4;
+    for(;;){
+	if (!mnoread)
+	    n = mread(adrs, val, size);
+	printf("%.8x%c", adrs, brev? 'r': ' ');
+	if (!mnoread) {
+	    if (brev)
+		byterev(val, size);
+	    putchar(' ');
+	    for (i = 0; i < n; ++i)
+		printf("%.2x", val[i]);
+	    for (; i < size; ++i)
+		printf("%s", fault_chars[fault_type]);
+	}
+	putchar(' ');
+	inc = size;
+	nslash = 0;
+	for(;;){
+	    if( scanhex(&n) ){
+		for (i = 0; i < size; ++i)
+		    val[i] = n >> (i * 8);
+		if (!brev)
+		    byterev(val, size);
+		mwrite(adrs, val, size);
+		inc = size;
+	    }
+	    cmd = skipbl();
+	    if (cmd == '\n')
+		break;
+	    inc = 0;
+	    switch (cmd) {
+	    case '\'':
+		for(;;){
+		    n = inchar();
+		    if( n == '\\' )
+			n = bsesc();
+		    else if( n == '\'' )
+			break;
+		    for (i = 0; i < size; ++i)
+			val[i] = n >> (i * 8);
+		    if (!brev)
+			byterev(val, size);
+		    mwrite(adrs, val, size);
+		    adrs += size;
+		}
+		adrs -= size;
+		inc = size;
+		break;
+	    case ',':
+		adrs += size;
+		break;
+	    case '.':
+		mnoread = 0;
+		break;
+	    case ';':
+		break;
+	    case 'x':
+	    case EOF:
+		scannl();
+		return;
+	    case 'b':
+	    case 'v':
+		size = 1;
+		break;
+	    case 'w':
+		size = 2;
+		break;
+	    case 'l':
+		size = 4;
+		break;
+	    case '^':
+		adrs -= size;
+		break;
+		break;
+	    case '/':
+		if (nslash > 0)
+		    adrs -= 1 << nslash;
+		else
+		    nslash = 0;
+		nslash += 4;
+		adrs += 1 << nslash;
+		break;
+	    case '\\':
+		if (nslash < 0)
+		    adrs += 1 << -nslash;
+		else
+		    nslash = 0;
+		nslash -= 4;
+		adrs -= 1 << -nslash;
+		break;
+	    case 'm':
+		scanhex(&adrs);
+		break;
+	    case 'n':
+		mnoread = 1;
+		break;
+	    case 'r':
+		brev = !brev;
+		break;
+	    case '<':
+		n = size;
+		scanhex(&n);
+		adrs -= n;
+		break;
+	    case '>':
+		n = size;
+		scanhex(&n);
+		adrs += n;
+		break;
+	    }
+	}
+	adrs += inc;
+    }
+}
+
+int
+bsesc(void)
+{
+	int c;
+
+	c = inchar();
+	switch( c ){
+	case 'n':	c = '\n';	break;
+	case 'r':	c = '\r';	break;
+	case 'b':	c = '\b';	break;
+	case 't':	c = '\t';	break;
+	}
+	return c;
+}
+
+void
+dump(void)
+{
+	int c;
+
+	c = inchar();
+	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
+		termch = c;
+	scanhex(&adrs);
+	if( termch != '\n')
+		termch = 0;
+	if( c == 'i' ){
+		scanhex(&nidump);
+		if( nidump == 0 )
+			nidump = 16;
+		adrs += ppc_inst_dump(adrs, nidump);
+		last_cmd = "di\n";
+	} else {
+		scanhex(&ndump);
+		if( ndump == 0 )
+			ndump = 64;
+		prdump(adrs, ndump);
+		adrs += ndump;
+		last_cmd = "d\n";
+	}
+}
+
+void
+prdump(unsigned adrs, int ndump)
+{
+	register int n, m, c, r, nr;
+	unsigned char temp[16];
+
+	for( n = ndump; n > 0; ){
+		printf("%.8x", adrs);
+		putchar(' ');
+		r = n < 16? n: 16;
+		nr = mread(adrs, temp, r);
+		adrs += nr;
+		for( m = 0; m < r; ++m ){
+			putchar((m & 3) == 0 && m > 0? '.': ' ');
+			if( m < nr )
+				printf("%.2x", temp[m]);
+			else
+				printf("%s", fault_chars[fault_type]);
+		}
+		for(; m < 16; ++m )
+			printf("   ");
+		printf("  |");
+		for( m = 0; m < r; ++m ){
+			if( m < nr ){
+				c = temp[m];
+				putchar(' ' <= c && c <= '~'? c: '.');
+			} else
+				putchar(' ');
+		}
+		n -= r;
+		for(; m < 16; ++m )
+			putchar(' ');
+		printf("|\n");
+		if( nr < r )
+			break;
+	}
+}
+
+int
+ppc_inst_dump(unsigned adr, int count)
+{
+	int nr, dotted;
+	unsigned first_adr;
+	unsigned long inst, last_inst = 0;
+	unsigned char val[4];
+
+	dotted = 0;
+	for (first_adr = adr; count > 0; --count, adr += 4){
+		nr = mread(adr, val, 4);
+		if( nr == 0 ){
+			const char *x = fault_chars[fault_type];
+			printf("%.8x  %s%s%s%s\n", adr, x, x, x, x);
+			break;
+		}
+		inst = GETWORD(val);
+		if (adr > first_adr && inst == last_inst) {
+			if (!dotted) {
+				printf(" ...\n");
+				dotted = 1;
+			}
+			continue;
+		}
+		dotted = 0;
+		last_inst = inst;
+		printf("%.8x  ", adr);
+		printf("%.8x\t", inst);
+		print_insn_big_powerpc(stdout, inst, adr);	/* always returns 4 */
+		printf("\n");
+	}
+	return adr - first_adr;
+}
+
+void
+print_address(unsigned addr)
+{
+	printf("0x%x", addr);
+}
+
+/*
+ * Memory operations - move, set, print differences
+ */
+static unsigned mdest;		/* destination address */
+static unsigned msrc;		/* source address */
+static unsigned mval;		/* byte value to set memory to */
+static unsigned mcount;		/* # bytes to affect */
+static unsigned mdiffs;		/* max # differences to print */
+
+void
+memops(int cmd)
+{
+	scanhex(&mdest);
+	if( termch != '\n' )
+		termch = 0;
+	scanhex(cmd == 's'? &mval: &msrc);
+	if( termch != '\n' )
+		termch = 0;
+	scanhex(&mcount);
+	switch( cmd ){
+	case 'm':
+		memmove((void *)mdest, (void *)msrc, mcount);
+		break;
+	case 's':
+		memset((void *)mdest, mval, mcount);
+		break;
+	case 'd':
+		if( termch != '\n' )
+			termch = 0;
+		scanhex(&mdiffs);
+		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
+		break;
+	}
+}
+
+void
+memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
+{
+	unsigned n, prt;
+
+	prt = 0;
+	for( n = nb; n > 0; --n )
+		if( *p1++ != *p2++ )
+			if( ++prt <= maxpr )
+				printf("%.8x %.2x # %.8x %.2x\n", (unsigned)p1 - 1,
+					p1[-1], (unsigned)p2 - 1, p2[-1]);
+	if( prt > maxpr )
+		printf("Total of %d differences\n", prt);
+}
+
+static unsigned mend;
+static unsigned mask;
+
+void
+memlocate(void)
+{
+	unsigned a, n;
+	unsigned char val[4];
+
+	last_cmd = "ml";
+	scanhex(&mdest);
+	if (termch != '\n') {
+		termch = 0;
+		scanhex(&mend);
+		if (termch != '\n') {
+			termch = 0;
+			scanhex(&mval);
+			mask = ~0;
+			if (termch != '\n') termch = 0;
+			scanhex(&mask);
+		}
+	}
+	n = 0;
+	for (a = mdest; a < mend; a += 4) {
+		if (mread(a, val, 4) == 4
+			&& ((GETWORD(val) ^ mval) & mask) == 0) {
+			printf("%.8x:  %.8x\n", a, GETWORD(val));
+			if (++n >= 10)
+				break;
+		}
+	}
+}
+
+static unsigned mskip = 0x1000;
+static unsigned mlim = 0xffffffff;
+
+void
+memzcan(void)
+{
+	unsigned char v;
+	unsigned a;
+	int ok, ook;
+
+	scanhex(&mdest);
+	if (termch != '\n') termch = 0;
+	scanhex(&mskip);
+	if (termch != '\n') termch = 0;
+	scanhex(&mlim);
+	ook = 0;
+	for (a = mdest; a < mlim; a += mskip) {
+		ok = mread(a, &v, 1);
+		if (ok && !ook) {
+			printf("%.8x .. ", a);
+			fflush(stdout);
+		} else if (!ok && ook)
+			printf("%.8x\n", a - mskip);
+		ook = ok;
+		if (a + mskip < a)
+			break;
+	}
+	if (ook)
+		printf("%.8x\n", a - mskip);
+}
+
+void proccall(void)
+{
+	unsigned int args[8];
+	unsigned int ret;
+	int i;
+	typedef unsigned int (*callfunc_t)(unsigned int, unsigned int,
+			unsigned int, unsigned int, unsigned int,
+			unsigned int, unsigned int, unsigned int);
+	callfunc_t func;
+
+	scanhex(&adrs);
+	if (termch != '\n')
+		termch = 0;
+	for (i = 0; i < 8; ++i)
+		args[i] = 0;
+	for (i = 0; i < 8; ++i) {
+		if (!scanhex(&args[i]) || termch == '\n')
+			break;
+		termch = 0;
+	}
+	func = (callfunc_t) adrs;
+	ret = 0;
+	if (setjmp(bus_error_jmp) == 0) {
+		debugger_fault_handler = handle_fault;
+		sync();
+		ret = func(args[0], args[1], args[2], args[3],
+			   args[4], args[5], args[6], args[7]);
+		sync();
+		printf("return value is %x\n", ret);
+	} else {
+		printf("*** %x exception occurred\n", fault_except);
+	}
+	debugger_fault_handler = NULL;
+}
+
+/* Input scanning routines */
+int
+skipbl(void)
+{
+	int c;
+
+	if( termch != 0 ){
+		c = termch;
+		termch = 0;
+	} else
+		c = inchar();
+	while( c == ' ' || c == '\t' )
+		c = inchar();
+	return c;
+}
+
+#define N_PTREGS	44
+static char *regnames[N_PTREGS] = {
+	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "mq",
+	"trap", "dar", "dsisr", "res"
+};
+
+int
+scanhex(unsigned *vp)
+{
+	int c, d;
+	unsigned v;
+
+	c = skipbl();
+	if (c == '%') {
+		/* parse register name */
+		char regname[8];
+		int i;
+
+		for (i = 0; i < sizeof(regname) - 1; ++i) {
+			c = inchar();
+			if (!isalnum(c)) {
+				termch = c;
+				break;
+			}
+			regname[i] = c;
+		}
+		regname[i] = 0;
+		for (i = 0; i < N_PTREGS; ++i) {
+			if (strcmp(regnames[i], regname) == 0) {
+				unsigned *rp = (unsigned *)
+					xmon_regs[smp_processor_id()];
+				if (rp == NULL) {
+					printf("regs not available\n");
+					return 0;
+				}
+				*vp = rp[i];
+				return 1;
+			}
+		}
+		printf("invalid register name '%%%s'\n", regname);
+		return 0;
+	} else if (c == '$') {
+		static char symname[64];
+		int i;
+		for (i=0; i<63; i++) {
+			c = inchar();
+			if (isspace(c)) {
+				termch = c;
+				break;
+			}
+			symname[i] = c;
+		}
+		symname[i++] = 0;
+		*vp = xmon_symbol_to_addr(symname);
+		if (!(*vp)) {
+			printf("unknown symbol\n");
+			return 0;
+		}
+		return 1;
+	}
+
+	d = hexdigit(c);
+	if( d == EOF ){
+		termch = c;
+		return 0;
+	}
+	v = 0;
+	do {
+		v = (v << 4) + d;
+		c = inchar();
+		d = hexdigit(c);
+	} while( d != EOF );
+	termch = c;
+	*vp = v;
+	return 1;
+}
+
+void
+scannl(void)
+{
+	int c;
+
+	c = termch;
+	termch = 0;
+	while( c != '\n' )
+		c = inchar();
+}
+
+int hexdigit(int c)
+{
+	if( '0' <= c && c <= '9' )
+		return c - '0';
+	if( 'A' <= c && c <= 'F' )
+		return c - ('A' - 10);
+	if( 'a' <= c && c <= 'f' )
+		return c - ('a' - 10);
+	return EOF;
+}
+
+void
+getstring(char *s, int size)
+{
+	int c;
+
+	c = skipbl();
+	do {
+		if( size > 1 ){
+			*s++ = c;
+			--size;
+		}
+		c = inchar();
+	} while( c != ' ' && c != '\t' && c != '\n' );
+	termch = c;
+	*s = 0;
+}
+
+static char line[256];
+static char *lineptr;
+
+void
+flush_input(void)
+{
+	lineptr = NULL;
+}
+
+int
+inchar(void)
+{
+	if (lineptr == NULL || *lineptr == 0) {
+		if (fgets(line, sizeof(line), stdin) == NULL) {
+			lineptr = NULL;
+			return EOF;
+		}
+		lineptr = line;
+	}
+	return *lineptr++;
+}
+
+void
+take_input(char *str)
+{
+	lineptr = str;
+}
+
+void
+sysmap_lookup(void)
+{
+	int type = inchar();
+	unsigned addr;
+	static char tmp[64];
+	char* cur;
+
+	extern char *sysmap;
+	extern unsigned long sysmap_size;
+	if ( !sysmap || !sysmap_size )
+		return;
+
+	switch(type) {
+		case 'a':
+			if (scanhex(&addr)) {
+				pretty_print_addr(addr);
+				printf("\n");
+			}
+			termch = 0;
+			break;
+		case 's':
+			getstring(tmp, 64);
+			if( setjmp(bus_error_jmp) == 0 ) {
+				debugger_fault_handler = handle_fault;
+				sync();
+				cur = sysmap;
+				do {
+					cur = strstr(cur, tmp);
+					if (cur) {
+						static char res[64];
+						char *p, *d;
+						p = cur;
+						while(p > sysmap && *p != 10)
+							p--;
+						if (*p == 10) p++;
+						d = res;
+						while(*p && p < (sysmap + sysmap_size) && *p != 10)
+							*(d++) = *(p++);
+						*(d++) = 0;
+						printf("%s\n", res);
+						cur++;
+					}
+				} while (cur);
+				sync();
+			}
+			debugger_fault_handler = NULL;
+			termch = 0;
+			break;
+	}
+}
+
+static int
+pretty_print_addr(unsigned long addr)
+{
+	char *sym;
+	unsigned long saddr;
+	
+	printf("%08x", addr);
+	sym = xmon_find_symbol(addr, &saddr);
+	if (sym)
+		printf(" (%s+0x%x)", sym, addr-saddr);
+	return (sym != 0);
+}
+
+char*
+xmon_find_symbol(unsigned long addr, unsigned long* saddr)
+{
+	static char rbuffer[64];
+	char *p, *ep, *limit;
+	unsigned long prev, next;
+	char* psym;
+
+	extern char *sysmap;
+	extern unsigned long sysmap_size;
+	if ( !sysmap || !sysmap_size )
+		return NULL;
+	
+	prev = 0;
+	psym = NULL;
+	p = sysmap;
+	limit = p + sysmap_size;
+	if( setjmp(bus_error_jmp) == 0 ) {
+		debugger_fault_handler = handle_fault;
+		sync();
+		do {
+			next = simple_strtoul(p, &p, 16);
+			if (next > addr && prev <= addr) {
+				if (!psym)
+					goto bail;
+				ep = rbuffer;
+				p = psym;
+				while(*p && p < limit && *p == 32)
+					p++;
+				while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63)
+					*(ep++) = *(p++);
+				*(ep++) = 0;
+				if (saddr)
+					*saddr = prev;
+				debugger_fault_handler = NULL;
+				return rbuffer;
+			}
+			prev = next;
+			psym = p;
+			while(*p && p < limit && *p != 10)
+				p++;
+			if (*p) p++;
+		} while(*p && p < limit && next);
+bail:
+		sync();
+	}
+	debugger_fault_handler = NULL;
+	return NULL;
+}
+
+unsigned long
+xmon_symbol_to_addr(char* symbol)
+{
+	char *p, *cur;
+	char *match = NULL;
+	int goodness = 0;
+	int result = 0;
+	
+	extern char *sysmap;
+	extern unsigned long sysmap_size;
+	if ( !sysmap || !sysmap_size )
+		return 0;
+
+	if( setjmp(bus_error_jmp) == 0 ) {
+		debugger_fault_handler = handle_fault;
+		sync();
+		cur = sysmap;
+		while(cur) {
+			cur = strstr(cur, symbol);
+			if (cur) {
+				int gd = 1;
+
+				/* best match if equal, better match if
+				 * begins with
+				 */
+				if (cur == sysmap || *(cur-1) == ' ') {
+					gd++;
+					if (cur[strlen(symbol)] == 10)
+						gd++;
+				}
+				if (gd > goodness) {
+					match = cur;
+					goodness = gd;
+					if (gd == 3)
+						break;
+				}
+				cur++;
+			}
+		}	
+		if (goodness) {
+			p = match;
+			while(p > sysmap && *p != 10)
+				p--;
+			if (*p == 10) p++;
+			result = simple_strtoul(p, &p, 16);
+		}
+		sync();
+	}
+	debugger_fault_handler = NULL;
+	return result;
+}