diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 2b5cc5e8d60..8a1cc0a20c8 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,29 @@
+Fri Feb  4 23:38:03 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+	* ppc-opc.c (powerpc_operands): New operand type MBE to handle a
+	single number giving a bitmask for the MB and ME fields of an M
+	form instruction.  Change NB to accept 32, and turn it into 0;
+	also turn 0 into 32 when disassembling.  Seperated SH from NB.
+	(insert_mbe, extract_mbe): New functions.
+	(insert_nb, extract_nb): New functions.
+	(SC_MASK): Mask out SA and LK bits.
+	(powerpc_opcodes): Change "cal" to use RT, D, RA rather than RT,
+	RA, SI.  Change "liu" and "cau" to use UI rather than SI.  Mark
+	"bctr" and "bctrl" as accepted by POWER.  Change "rlwimi",
+	"rlimi", "rlwimi.", "rlimi.", "rlwinm", "rlinm", "rlwinm.",
+	"rlinm.", "rlmi", "rlmi.", "rlwnm", "rlnm", "rlwnm.", "rlnm." to
+	use MBE rather than MB.  Add "mfmq" and "mtmq" POWER instructions.
+	(powerpc_macros): Define table of macro definitions.
+	(powerpc_num_macros): Define.
+
+	* ppc-dis.c (print_insn_powerpc): Don't skip optional operands
+	if PPC_OPERAND_NEXT is set.
+
+Sat Jan 22 23:10:07 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+	* i960-dis.c (print_insn_i960): Make buffer bfd_byte instead of
+	char.  Retrieve contents using bfd_getl32 instead of shifting.
+
 Fri Jan 21 19:01:39 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
 	* ppc-opc.c: New file.  Opcode table for PowerPC, including
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index b46d5860657..d1328b23e3e 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -55,8 +55,12 @@ 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_rbs PARAMS ((unsigned long, long, const char **));
@@ -226,12 +230,12 @@ const struct powerpc_operand powerpc_operands[] =
   /* The LI field in an I form instruction.  The lower two bits are
      forced to zero.  */
 #define LI (LEV + 1)
-  { 25, 0, 1, insert_li, extract_li, PPC_OPERAND_RELATIVE },
+  { 26, 0, 1, insert_li, extract_li, PPC_OPERAND_RELATIVE },
 
   /* The LI field in an I form instruction when used as an absolute
      address.  */
 #define LIA (LI + 1)
-  { 25, 0, 1, insert_li, extract_li, PPC_OPERAND_ABSOLUTE },
+  { 26, 0, 1, insert_li, extract_li, PPC_OPERAND_ABSOLUTE },
 
   /* The MB field in an M form instruction.  */
 #define MB (LIA + 1)
@@ -243,19 +247,25 @@ const struct powerpc_operand powerpc_operands[] =
 #define ME_MASK (0x1f << 1)
   { 5, 1, 0, 0, 0, 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 (ME + 1)
+  { 5, 6, 0, 0, 0, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
+  { 32, 0, 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 (ME + 1)
+#define MB6 (MBE + 2)
 #define ME6 (MB6)
 #define MB6_MASK (0x3f << 5)
   { 6, 5, 0, insert_mb6, extract_mb6, 0 },
 
-  /* The NB field in an X form instruction or the SH field in an X or
-     M form instruction.  */
+  /* The NB field in an X form instruction.  The value 32 is stored as
+     0.  */
 #define NB (MB6 + 1)
-#define SH (NB)
-#define SH_MASK (0x1f << 11)
-  { 5, 11, 0, 0, 0, 0 },
+  { 6, 11, 0, insert_nb, extract_nb, 0 },
 
   /* The NSI field in a D form instruction.  This is the same as the
      SI field, only negated.  */
@@ -286,8 +296,13 @@ const struct powerpc_operand powerpc_operands[] =
 #define RT_MASK (0x1f << 21)
   { 5, 21, 0, 0, 0, PPC_OPERAND_GPR },
 
+  /* The SH field in an X or M form instruction.  */
+#define SH (RS + 1)
+#define SH_MASK (0x1f << 11)
+  { 5, 11, 0, 0, 0, 0 },
+
   /* The SH field in an MD form instruction.  This is split.  */
-#define SH6 (RS + 1)
+#define SH6 (SH + 1)
 #define SH6_MASK ((0x1f << 11) | (1 << 1))
   { 6, 1, 0, insert_sh6, extract_sh6, 0 },
 
@@ -636,6 +651,73 @@ extract_li (insn, invalid)
     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 (insn, value, errmsg)
+     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 (insn, invalid)
+     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.  */
 
@@ -658,8 +740,38 @@ extract_mb6 (insn, 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 (insn, value, errmsg)
+     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 (insn, invalid)
+     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 mark it as
+   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.  */
 
@@ -851,7 +963,7 @@ extract_spr (insn, invalid)
 
 /* An SC form instruction.  */
 #define SC(op, sa, lk) (OP (op) | (((sa) & 1) << 1) | ((lk) & 1))
-#define SC_MASK (OP_MASK | (0x3ff << 16))
+#define SC_MASK (OP_MASK | (0x3ff << 16) | (1 << 1) | 1)
 
 /* An X form instruction.  */
 #define X(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
@@ -1093,14 +1205,14 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 { "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, 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, SI } },
-{ "liu",     OP(15),	DRA_MASK,	POWER,		{ RT, SI } },
+{ "liu",     OP(15),	DRA_MASK,	POWER,		{ RT, UI } },
 { "addis",   OP(15),	OP_MASK,	PPC,		{ RT, RA, SI } },
-{ "cau",     OP(15),	OP_MASK,	POWER,		{ RT, RA, SI } },
+{ "cau",     OP(15),	OP_MASK,	POWER,		{ RT, RA, UI } },
 { "subis",   OP(15),	OP_MASK,	PPC,		{ RT, RA, NSI } },
 
 { "bdnz-",   BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC,	{ BDM } },
@@ -1561,8 +1673,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 { "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,	{ 0 } },
-{ "bctrl",   XLO(19,BOU,528,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "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 } },
@@ -1656,30 +1768,30 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 { "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,MB,ME } },
-{ "rlimi",   M(20,0),	M_MASK,		POWER,		{ RA,RS,SH,MB,ME } },
+{ "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,MB,ME } },
-{ "rlimi.",  M(20,1),	M_MASK,		POWER,		{ RA,RS,SH,MB,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,MB,ME } },
-{ "rlinm",   M(21,0),	M_MASK,		POWER,		{ RA,RS,SH,MB,ME } },
+{ "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,MB,ME } },
-{ "rlinm.",  M(21,1),	M_MASK,		POWER,		{ RA,RS,SH,MB,ME } },
+{ "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,		{ RA,RS,RB,MB,ME } },
-{ "rlmi.",   M(22,1),	M_MASK,		POWER,		{ RA,RS,RB,MB,ME } },
+{ "rlmi",    M(22,0),	M_MASK,		POWER,		{ RA,RS,RB,MBE,ME } },
+{ "rlmi.",   M(22,1),	M_MASK,		POWER,		{ 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,MB,ME } },
-{ "rlnm",    M(23,0),	M_MASK,		POWER,		{ RA,RS,RB,MB,ME } },
+{ "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,MB,ME } },
-{ "rlnm.",   M(23,1),	M_MASK,		POWER,		{ RA,RS,RB,MB,ME } },
+{ "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 } },
@@ -2047,6 +2159,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 { "divo",    XO(31,331,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
 { "divo.",   XO(31,331,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
 
+{ "mfmq",    XSPR(31,339,0), XSPR_MASK,	POWER,		{ RT } },
 { "mfxer",   XSPR(31,339,1), XSPR_MASK,	PPC|POWER,	{ RT } },
 { "mflr",    XSPR(31,339,8), XSPR_MASK,	PPC|POWER,	{ RT } },
 { "mfctr",   XSPR(31,339,9), XSPR_MASK,	PPC|POWER,	{ RT } },
@@ -2103,6 +2216,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 { "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,		{ 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 } },
@@ -2461,3 +2575,51 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 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]);