* ppc-opc.c (powerpc_operands): New operand type MBE to handle a
authorIan Lance Taylor <ian@airs.com>
Sat, 5 Feb 1994 04:46:34 +0000 (04:46 +0000)
committerIan Lance Taylor <ian@airs.com>
Sat, 5 Feb 1994 04:46:34 +0000 (04:46 +0000)
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.

opcodes/ChangeLog
opcodes/ppc-opc.c

index 2b5cc5e8d60c5393667b507598c4bc6e239c7b82..8a1cc0a20c877da8014a87e6f021b9584afaec73 100644 (file)
@@ -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
index b46d586065793b4215a586c53cce1d4833d88c30..d1328b23e3eda748e6e19b914553ba4a0e7b439c 100644 (file)
@@ -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]);
+\f
+/* 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]);