Regerbated after change to Makefile.am
[deliverable/binutils-gdb.git] / opcodes / avr-dis.c
index 2d7eb947df76f4d04041d2c351eb51986b04d4ac..6fcd58cc6f8d33d1c0f8d969dc539de53ac64d8f 100644 (file)
@@ -18,6 +18,7 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
+#include "sysdep.h"
 #include "dis-asm.h"
 #include "opintl.h"
 
@@ -26,10 +27,9 @@ typedef unsigned short u16;
 typedef unsigned long u32;
 
 #define IFMASK(a,b)     ((opcode & (a)) == (b))
-#define CODE_MAX        65537
 
 static char* SREG_flags = "CZNVSHTI";
-static char* sect94[] = {"COM","NEG","SWAP","INC","NULL","ASR","LSR","ROR",
+static char* sect94[] = {"COM","NEG","SWAP","INC",0,"ASR","LSR","ROR",
                         0,0,"DEC",0,0,0,0,0};
 static char* sect98[] = {"CBI","SBIC","SBI","SBIS"};
 static char* branchs[] = {
@@ -38,8 +38,8 @@ static char* branchs[] = {
   "BRCC","BRNE","BRPL","BRVC",
   "BRGE","BRHC","BRTC","BRID"
 };
-static char* last4[] = {"BLD","BST","SBRC","SBRS"};
 
+static char* last4[] = {"BLD","BST","SBRC","SBRS"};
 
 
 static void dispLDD PARAMS ((u16, char *));
@@ -115,6 +115,72 @@ reg20w (opcode, dest)
 }
 
 
+static void reg_fmul_d PARAMS ((u16, char *));
+
+static void
+reg_fmul_d (opcode, dest)
+     u16 opcode;
+     char *dest;
+{
+  sprintf(dest, "R%d", 16 + ((opcode >> 4) & 7));
+}
+
+
+static void reg_fmul_r PARAMS ((u16, char *));
+
+static void
+reg_fmul_r (opcode, dest)
+     u16 opcode;
+     char *dest;
+{
+  sprintf(dest, "R%d", 16 + (opcode & 7));
+}
+
+
+static void reg_muls_d PARAMS ((u16, char *));
+
+static void
+reg_muls_d (opcode, dest)
+     u16 opcode;
+     char *dest;
+{
+  sprintf(dest, "R%d", 16 + ((opcode >> 4) & 0xf));
+}
+
+
+static void reg_muls_r PARAMS ((u16, char *));
+
+static void
+reg_muls_r (opcode, dest)
+     u16 opcode;
+     char *dest;
+{
+  sprintf(dest, "R%d", 16 + (opcode & 0xf));
+}
+
+
+static void reg_movw_d PARAMS ((u16, char *));
+
+static void
+reg_movw_d (opcode, dest)
+     u16 opcode;
+     char *dest;
+{
+  sprintf(dest, "R%d", 2 * ((opcode >> 4) & 0xf));
+}
+
+
+static void reg_movw_r PARAMS ((u16, char *));
+
+static void
+reg_movw_r (opcode, dest)
+     u16 opcode;
+     char *dest;
+{
+  sprintf(dest, "R%d", 2 * (opcode & 0xf));
+}
+
+
 static void lit404 PARAMS ((u16, char *));
 
 static void
@@ -147,8 +213,8 @@ add0fff (op, dest, pc)
      char *dest;
      int pc;
 {
-  int opcode = op & 0x0fff;
-  sprintf(dest, ".%+-8d ; 0x%06X", opcode * 2, pc + 2 + opcode * 2);
+  int rel_addr = (((op & 0xfff) ^ 0x800) - 0x800) * 2;
+  sprintf(dest, ".%+-8d ; 0x%06X", rel_addr, pc + 2 + rel_addr);
 }
 
 
@@ -160,8 +226,8 @@ add03f8 (op, dest, pc)
      char *dest;
      int pc;
 {
-  int opcode = (op >> 3) & 0x7f;
-  sprintf(dest, ".%+-8d ; 0x%06X", opcode * 2, pc + 2 + opcode * 2);
+  int rel_addr = ((((op >> 3) & 0x7f) ^ 0x40) - 0x40) * 2;
+  sprintf(dest, ".%+-8d ; 0x%06X", rel_addr, pc + 2 + rel_addr);
 }
 
 
@@ -223,7 +289,33 @@ print_insn_avr(addr, info)
            switch (opcode & 0x0c00)
              {
              case 0x0000:
-               (*prin) (stream, "    NOP");
+               switch (opcode & 0x0300)
+                 {
+                 case 0x0000:
+                   (*prin) (stream, "    NOP");
+                   break;
+                 case 0x0100:
+                   reg_movw_d(opcode, rd);
+                   reg_movw_r(opcode, rr);
+                   (*prin) (stream, "    MOVW    %s,%s", rd, rr);
+                   break;
+                 case 0x0200:
+                   reg_muls_d(opcode, rd);
+                   reg_muls_r(opcode, rr);
+                   (*prin) (stream, "    MULS    %s,%s", rd, rr);
+                   break;
+                 case 0x0300:
+                   reg_fmul_d(opcode, rd);
+                   reg_fmul_r(opcode, rr);
+                   if (IFMASK(0x88, 0))
+                     (*prin) (stream, "    MULSU   %s,%s", rd, rr);
+                   else if (IFMASK(0x88, 8))
+                     (*prin) (stream, "    FMUL    %s,%s", rd, rr);
+                   else if (IFMASK(0x88, 0x80))
+                     (*prin) (stream, "    FMULS   %s,%s", rd, rr);
+                   else
+                     (*prin) (stream, "    FMULSU  %s,%s", rd, rr);
+                 }
                break;
              case 0x0400:
                (*prin) (stream, "    CPC     %s,%s", rd, rr);
@@ -331,49 +423,43 @@ print_insn_avr(addr, info)
                      }
                      break;
                    case 0x1:
-                     {
-                       (*prin) (stream, "    LD      %s,Z+", rd);
-                     }
+                     (*prin) (stream, "    LD      %s,Z+", rd);
                      break;
                    case 0x2:
-                     {
-                       (*prin) (stream, "    LD      %s,-Z", rd);
-                     }
+                     (*prin) (stream, "    LD      %s,-Z", rd);
+                     break;
+                   case 0x4:
+                     (*prin) (stream, "    LPM     %s,Z", rd);
+                     break;
+                   case 0x5:
+                     (*prin) (stream, "    LPM     %s,Z+", rd);
+                     break;
+                   case 0x6:
+                     (*prin) (stream, "    ELPM    %s,Z", rd);
+                     break;
+                   case 0x7:
+                     (*prin) (stream, "    ELPM    %s,Z+", rd);
                      break;
                    case 0x9:
-                     {
-                       (*prin) (stream, "    LD      %s,Y+", rd);
-                     }
+                     (*prin) (stream, "    LD      %s,Y+", rd);
                      break;
                    case 0xa:
-                     {
-                       (*prin) (stream, "    LD      %s,-Y", rd);
-                     }
+                     (*prin) (stream, "    LD      %s,-Y", rd);
                      break;
                    case 0xc:
-                     {
-                       (*prin) (stream, "    LD      %s,X", rd);
-                     }
+                     (*prin) (stream, "    LD      %s,X", rd);
                      break;
                    case 0xd:
-                     {
-                       (*prin) (stream, "    LD      %s,X+", rd);
-                     }
+                     (*prin) (stream, "    LD      %s,X+", rd);
                      break;
                    case 0xe:
-                     {
-                       (*prin) (stream, "    LD      %s,-X", rd);
-                     }
+                     (*prin) (stream, "    LD      %s,-X", rd);
                      break;
                    case 0xf:
-                     {
-                       (*prin) (stream, "    POP     %s", rd);
-                     }
+                     (*prin) (stream, "    POP     %s", rd);
                      break;
                    default:
-                     {
-                       (*prin) (stream, "    ????");
-                     }
+                     (*prin) (stream, "    ????");
                      break;
                    }
                }
@@ -391,49 +477,31 @@ print_insn_avr(addr, info)
                      }
                      break;
                    case 0x1:
-                     {
-                       (*prin) (stream, "    ST      Z+,%s", rd);
-                     }
+                     (*prin) (stream, "    ST      Z+,%s", rd);
                      break;
                    case 0x2:
-                     {
-                       (*prin) (stream, "    ST      -Z,%s", rd);
-                     }
+                     (*prin) (stream, "    ST      -Z,%s", rd);
                      break;
                    case 0x9:
-                     {
-                       (*prin) (stream, "    ST      Y+,%s", rd);
-                     }
+                     (*prin) (stream, "    ST      Y+,%s", rd);
                      break;
                    case 0xa:
-                     {
-                       (*prin) (stream, "    ST      -Y,%s", rd);
-                     }
+                     (*prin) (stream, "    ST      -Y,%s", rd);
                      break;
                    case 0xc:
-                     {
-                       (*prin) (stream, "    ST      X,%s", rd);
-                     }
+                     (*prin) (stream, "    ST      X,%s", rd);
                      break;
                    case 0xd:
-                     {
-                       (*prin) (stream, "    ST      X+,%s", rd);
-                     }
+                     (*prin) (stream, "    ST      X+,%s", rd);
                      break;
                    case 0xe:
-                     {
-                       (*prin) (stream, "    ST      -X,%s", rd);
-                     }
+                     (*prin) (stream, "    ST      -X,%s", rd);
                      break;
                    case 0xf:
-                     {
-                       (*prin) (stream, "    PUSH    %s", rd);
-                     }
+                     (*prin) (stream, "    PUSH    %s", rd);
                      break;
                    default:
-                     {
-                       (*prin) (stream, "    ????");
-                     }
+                     (*prin) (stream, "    ????");
                      break;
                    }
                }
@@ -458,13 +526,20 @@ print_insn_avr(addr, info)
                      else
                        (*prin) (stream, "    SE%c", SREG_flags[sf]);
                    }
-                 else if (IFMASK(0x000f, 0x0009))
+                 else if (IFMASK(0x001f, 0x0009))
                    {
                      if (opcode & 0x0100)
                        (*prin) (stream, "    ICALL");
                      else
                        (*prin) (stream, "    IJMP");
                    }
+                 else if (IFMASK(0x001f, 0x0019))
+                   {
+                     if (opcode & 0x0100)
+                       (*prin) (stream, "    EICALL");
+                     else
+                       (*prin) (stream, "    EIJMP");
+                   }
                  else if (IFMASK(0x010f, 0x0108))
                    {
                      if (IFMASK(0x0090, 0x0000))
@@ -479,6 +554,10 @@ print_insn_avr(addr, info)
                        (*prin) (stream, "    LPM");
                      else if (IFMASK(0x00f0, 0x00d0))
                        (*prin) (stream, "    ELPM");
+                     else if (IFMASK(0x00f0, 0x00e0))
+                       (*prin) (stream, "    SPM");
+                     else if (IFMASK(0x00f0, 0x00f0))
+                       (*prin) (stream, "    ESPM");
                      else
                        (*prin) (stream, "    ????");
                    }
This page took 0.033957 seconds and 4 git commands to generate.