5xxx and el
[deliverable/binutils-gdb.git] / opcodes / m68k-dis.c
index 7c0a493c2b0a327ed268fe74ce6478a99ba968ba..619bcbcd762506c5ee5dc3a7ffa6f866a9c836a7 100644 (file)
@@ -24,6 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* Local function prototypes */
 
+static int
+fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
+
+static void
+dummy_print_address PARAMS ((bfd_vma, struct disassemble_info *));
+
 static int
 fetch_arg PARAMS ((unsigned char *, int, int, disassemble_info *));
 
@@ -68,30 +74,20 @@ static char *const reg_names[] = {
   (p += 4, FETCH_DATA (info, p), \
    (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
 
-/* NEXTSINGLE and NEXTDOUBLE handle alignment problems, but not
- * byte-swapping or other float format differences.  FIXME! */
-
-union number {
-    double d;
-    float f;
-    char c[10];
-};
-
+/* Get a single precision float.  */
 #define NEXTSINGLE(val, p) \
-  { unsigned int i; union number u;\
-    FETCH_DATA (info, p + sizeof (float));\
-    for (i = 0; i < sizeof(float); i++) u.c[i] = *p++; \
-    val = u.f; }
+  (p += 4, FETCH_DATA (info, p), \
+   floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val))
 
+/* Get a double precision float.  */
 #define NEXTDOUBLE(val, p) \
-  { unsigned int i; union number u;\
-    FETCH_DATA (info, p + sizeof (double));\
-    for (i = 0; i < sizeof(double); i++) u.c[i] = *p++; \
-    val = u.d; }
+  (p += 8, FETCH_DATA (info, p), \
+   floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val))
 
-/* Need a function to convert from extended to double precision... */
-#define NEXTEXTEND(p) \
-  (p += 12, FETCH_DATA (info, p), 0.0)
+/* Get an extended precision float.  */
+#define NEXTEXTEND(val, p) \
+  (p += 12, FETCH_DATA (info, p), \
+   floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val))
 
 /* Need a function to convert from packed to double
    precision.   Actually, it's easier to print a
@@ -154,7 +150,7 @@ dummy_printer (file) FILE *file;
 #endif
  { return 0; }
 
-void
+static void
 dummy_print_address (vma, info)
      bfd_vma vma;
      struct disassemble_info *info;
@@ -212,6 +208,11 @@ print_insn_m68k (memaddr, info)
     }
 
   info->private_data = (PTR) &priv;
+  /* Tell objdump to use two bytes per chunk and six bytes per line for
+     displaying raw data.  */
+  info->bytes_per_chunk = 2;
+  info->bytes_per_line = 6;
+  info->display_endian = BFD_ENDIAN_BIG;
   priv.max_fetched = priv.the_buffer;
   priv.insn_start = memaddr;
   if (setjmp (priv.bailout) != 0)
@@ -323,12 +324,29 @@ print_insn_m68k (memaddr, info)
          break;
        }
     }
-  /* Some opcodes like pflusha and lpstop are exceptions; they take no
-     arguments but are two words long.  Recognize them by looking at
-     the lower 16 bits of the mask.  */
+
+  /* pflusha is an exceptions.  It takes no arguments but is two words
+     long.  Recognize it by looking at the lower 16 bits of the mask.  */
   if (p - buffer < 4 && (best->match & 0xFFFF) != 0)
     p = buffer + 4;
-  
+
+  /* lpstop is another exception.  It takes a one word argument but is
+     three words long.  */
+  if (p - buffer < 6
+      && (best->match & 0xffff) == 0xffff
+      && best->args[0] == '#'
+      && best->args[1] == 'w')
+    {
+      /* Copy the one word argument into the usual location for a one
+        word argument, to simplify printing it.  We can get away with
+        this because we know exactly what the second word is, and we
+        aren't going to print anything based on it.  */
+      p = buffer + 6;
+      FETCH_DATA (info, p);
+      buffer[2] = buffer[4];
+      buffer[3] = buffer[5];
+    }
+
   FETCH_DATA (info, p);
   
   d = best->args;
@@ -451,7 +469,7 @@ print_insn_arg (d, buffer, p0, addr, info)
             {"%tc",  0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
              {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
             {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
-            {"%msp", 0x803}, {"%ibsp", 0x804},
+            {"%msp", 0x803}, {"%isp", 0x804},
 
             /* Should we be calling this psr like we do in case 'Y'?  */
             {"%mmusr",0x805},
@@ -613,7 +631,7 @@ print_insn_arg (d, buffer, p0, addr, info)
       val = NEXTWORD (p);
       (*info->fprintf_func)
        (info->stream, "%s@(%d)",
-        reg_names[fetch_arg (buffer, place, 3, info)], val);
+        reg_names[fetch_arg (buffer, place, 3, info) + 8], val);
       break;
 
     case 's':
@@ -639,7 +657,6 @@ print_insn_arg (d, buffer, p0, addr, info)
     case '?':
     case '/':
     case '&':
-    case '`':
     case '|':
     case '<':
     case '>':
@@ -701,7 +718,9 @@ print_insn_arg (d, buffer, p0, addr, info)
 
            case 2:
              val = NEXTWORD (p);
+             (*info->fprintf_func) (info->stream, "%%pc@(");
              (*info->print_address_func) (addr + val, info);
+             (*info->fprintf_func) (info->stream, ")");
              break;
 
            case 3:
@@ -736,10 +755,7 @@ print_insn_arg (d, buffer, p0, addr, info)
                  break;
 
                case 'x':
-                 FETCH_DATA (info, p + 12);
-                 floatformat_to_double (&floatformat_m68881_ext,
-                                        (char *) p, &flval);
-                 p += 12;
+                 NEXTEXTEND(flval, p);
                  break;
 
                case 'p':
This page took 0.025485 seconds and 4 git commands to generate.