*compile.c: Add additional CCR flags (I,UI,H,U)
[deliverable/binutils-gdb.git] / sim / h8300 / compile.c
index 2e02aa07fdc4cfd9934b96fd28c4dc8679084178..d5f72f787e8f1cbbec2f06115fcc643a8bc2f23f 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "config.h"
 
+#include <stdio.h>
 #include <signal.h>
 #ifdef HAVE_TIME_H
 #include <time.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
-#include "wait.h"
+#endif
 #include "ansidecl.h"
+#include "bfd.h"
 #include "callback.h"
 #include "remote-sim.h"
-#include "bfd.h"
+
+#ifndef SIGTRAP
+# define SIGTRAP 5
+#endif
 
 int debug;
 
+host_callback *sim_callback;
 
-#define X(op, size)  op*4+size
+static SIM_OPEN_KIND sim_kind;
+static char *myname;
 
-#define SP (h8300hmode ? SL:SW)
+/* FIXME: Needs to live in header file.
+   This header should also include the things in remote-sim.h.
+   One could move this to remote-sim.h but this function isn't needed
+   by gdb.  */
+void sim_set_simcache_size PARAMS ((int));
+
+#define X(op, size)  op * 4 + size
+
+#define SP (h8300hmode ? SL : SW)
 #define SB 0
 #define SW 1
 #define SL 2
@@ -57,44 +73,50 @@ int debug;
 
 #include "inst.h"
 
+/* The rate at which to call the host's poll_quit callback.  */
+
+#define POLL_QUIT_INTERVAL 0x80000
+
 #define LOW_BYTE(x) ((x) & 0xff)
-#define HIGH_BYTE(x) (((x)>>8) & 0xff)
-#define P(X,Y) ((X<<8) | Y)
+#define HIGH_BYTE(x) (((x) >> 8) & 0xff)
+#define P(X,Y) ((X << 8) | Y)
 
-#define BUILDSR()   cpu.ccr = (N << 3) | (Z << 2) | (V<<1) | C;
+#define BUILDSR()   cpu.ccr = (I << 7) | (UI << 6)| (H<<5) | (U<<4) | \
+                              (N << 3) | (Z << 2) | (V<<1) | C;
 
 #define GETSR()                    \
   c = (cpu.ccr >> 0) & 1;\
   v = (cpu.ccr >> 1) & 1;\
   nz = !((cpu.ccr >> 2) & 1);\
-  n = (cpu.ccr >> 3) & 1;
+  n = (cpu.ccr >> 3) & 1;\
+  u = (cpu.ccr >> 4) & 1;\
+  h = (cpu.ccr >> 5) & 1;\
+  ui = ((cpu.ccr >> 6) & 1);\
+  intMaskBit = (cpu.ccr >> 7) & 1;
 
 #ifdef __CHAR_IS_SIGNED__
-#define SEXTCHAR(x) ((char)(x))
+#define SEXTCHAR(x) ((char) (x))
 #endif
 
 #ifndef SEXTCHAR
-#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff):x)
+#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff): x & 0xff)
 #endif
 
 #define UEXTCHAR(x) ((x) & 0xff)
 #define UEXTSHORT(x) ((x) & 0xffff)
-#define SEXTSHORT(x) ((short)(x))
+#define SEXTSHORT(x) ((short) (x))
 
 static cpu_state_type cpu;
 
 int h8300hmode = 0;
+int h8300smode = 0;
 
 static int memory_size;
 
-
 static int
 get_now ()
 {
-#ifndef WIN32
-  return time (0);
-#endif
-  return 0;
+  return time (0);     /* WinXX HAS UNIX like 'time', so why not using it? */
 }
 
 static int
@@ -103,7 +125,6 @@ now_persec ()
   return 1;
 }
 
-
 static int
 bitfrom (x)
 {
@@ -120,8 +141,7 @@ bitfrom (x)
     }
 }
 
-static
-unsigned int
+static unsigned int
 lvalue (x, rn)
 {
   switch (x / 4)
@@ -134,10 +154,10 @@ lvalue (x, rn)
       return X (OP_REG, SP);
 
     case OP_MEM:
-
       return X (OP_MEM, SP);
+
     default:
-      abort ();
+      abort (); /* ?? May be something more usefull? */
     }
 }
 
@@ -152,21 +172,20 @@ decode (addr, data, dst)
   int rd = 0;
   int rdisp = 0;
   int abs = 0;
-  int plen = 0;
   int bit = 0;
-
-  struct h8_opcode *q = h8_opcodes;
+  int plen = 0;
+  struct h8_opcode *q;
   int size = 0;
+
   dst->dst.type = -1;
   dst->src.type = -1;
-  /* Find the exact opcode/arg combo */
-  while (q->name)
+
+  /* Find the exact opcode/arg combo.  */
+  for (q = h8_opcodes; q->name; q++)
     {
-      op_type *nib;
+      op_type *nib = q->data.nib;
       unsigned int len = 0;
 
-      nib = q->data.nib;
-
       while (1)
        {
          op_type looking_for = *nib;
@@ -185,40 +204,40 @@ decode (addr, data, dst)
                {
                  if (!(((int) thisnib & 0x8) != 0))
                    goto fail;
-                 looking_for = (op_type) ((int) looking_for & ~(int)
-                                          B31);
+
+                 looking_for = (op_type) ((int) looking_for & ~(int) B31);
                  thisnib &= 0x7;
                }
+
              if ((int) looking_for & (int) B30)
                {
                  if (!(((int) thisnib & 0x8) == 0))
                    goto fail;
+
                  looking_for = (op_type) ((int) looking_for & ~(int) B30);
                }
+
              if (looking_for & DBIT)
                {
-                 if ((looking_for & 5) != (thisnib & 5))
+                 /* Exclude adds/subs by looking at bit 0 and 2, and
+                     make sure the operand size, either w or l,
+                     matches by looking at bit 1.  */
+                 if ((looking_for & 7) != (thisnib & 7))
                    goto fail;
+
                  abs = (thisnib & 0x8) ? 2 : 1;
                }
              else if (looking_for & (REG | IND | INC | DEC))
                {
                  if (looking_for & REG)
                    {
-                     /*
-                      * Can work out size from the
-                      * register
-                      */
+                     /* Can work out size from the register.  */
                      size = bitfrom (looking_for);
                    }
                  if (looking_for & SRC)
-                   {
-                     rs = thisnib;
-                   }
+                   rs = thisnib;
                  else
-                   {
-                     rd = thisnib;
-                   }
+                   rd = thisnib;
                }
              else if (looking_for & L_16)
                {
@@ -231,10 +250,7 @@ decode (addr, data, dst)
                }
              else if (looking_for & ABSJMP)
                {
-                 abs =
-                   (data[1] << 16)
-                   | (data[2] << 8)
-                   | (data[3]);
+                 abs = (data[1] << 16) | (data[2] << 8) | (data[3]);
                }
              else if (looking_for & MEMIND)
                {
@@ -243,6 +259,7 @@ decode (addr, data, dst)
              else if (looking_for & L_32)
                {
                  int i = len >> 1;
+
                  abs = (data[i] << 24)
                    | (data[i + 1] << 16)
                    | (data[i + 2] << 8)
@@ -253,12 +270,13 @@ decode (addr, data, dst)
              else if (looking_for & L_24)
                {
                  int i = len >> 1;
+
                  abs = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
                  plen = 24;
                }
              else if (looking_for & IGNORE)
                {
-                 /* nothing to do */
+                 ;
                }
              else if (looking_for & DISPREG)
                {
@@ -277,6 +295,8 @@ decode (addr, data, dst)
                    case 0:
                      abs = 1;
                      break;
+                   default:
+                     goto fail;
                    }
                }
              else if (looking_for & L_8)
@@ -291,9 +311,9 @@ decode (addr, data, dst)
                    {
                      plen = 8;
                      abs = h8300hmode ? ~0xff0000ff : ~0xffff00ff;
-                     abs |= data[len >> 1] & 0xff ;
+                     abs |= data[len >> 1] & 0xff;
                    }
-                  else
+                 else
                    {
                      abs = data[len >> 1] & 0xff;
                    }
@@ -308,7 +328,7 @@ decode (addr, data, dst)
                {
                  dst->op = q;
 
-                 /* Fill in the args */
+                 /* Fill in the args */
                  {
                    op_type *args = q->args.nib;
                    int hadone = 0;
@@ -320,15 +340,11 @@ decode (addr, data, dst)
                        ea_type *p;
 
                        if (x & DST)
-                         {
-                           p = &(dst->dst);
-                         }
+                         p = &(dst->dst);
                        else
-                         {
-                           p = &(dst->src);
-                         }
+                         p = &(dst->src);
 
-                       if (x & (L_3))
+                       if (x & L_3)
                          {
                            p->type = X (OP_IMM, size);
                            p->literal = bit;
@@ -340,8 +356,8 @@ decode (addr, data, dst)
                          }
                        else if (x & REG)
                          {
-                           /* Reset the size, some
-                              ops (like mul) have two sizes */
+                           /* Reset the size.
+                              Some ops (like mul) have two sizes.  */
 
                            size = bitfrom (x);
                            p->type = X (OP_REG, size);
@@ -403,12 +419,9 @@ decode (addr, data, dst)
                      }
                  }
 
-                 /*
-                    * But a jmp or a jsr gets
-                    * automagically lvalued, since we
-                    * branch to their address not their
-                    * contents
-                  */
+                 /* But a jmp or a jsr gets automagically lvalued,
+                    since we branch to their address not their
+                    contents.  */
                  if (q->how == O (O_JSR, SB)
                      || q->how == O (O_JMP, SB))
                    {
@@ -421,7 +434,7 @@ decode (addr, data, dst)
                  dst->opcode = q->how;
                  dst->cycles = q->time;
 
-                 /* And a jsr to 0xc4 is turned into a magic trap */
+                 /* And a jsr to 0xc4 is turned into a magic trap */
 
                  if (dst->opcode == O (O_JSR, SB))
                    {
@@ -435,9 +448,7 @@ decode (addr, data, dst)
                  return;
                }
              else
-               {
-                 printf ("Dont understand %x \n", looking_for);
-               }
+               printf ("Don't understand %x \n", looking_for);
            }
 
          len++;
@@ -445,20 +456,19 @@ decode (addr, data, dst)
        }
 
     fail:
-      q++;
+      ;
     }
 
+  /* Fell off the end.  */
   dst->opcode = O (O_ILL, SB);
 }
 
-
 static void
 compile (pc)
 {
   int idx;
 
-  /* find the next cache entry to use */
-
+  /* Find the next cache entry to use.  */
   idx = cpu.cache_top + 1;
   cpu.compiles++;
   if (idx >= cpu.csize)
@@ -467,16 +477,16 @@ compile (pc)
     }
   cpu.cache_top = idx;
 
-  /* Throw away its old meaning */
+  /* Throw away its old meaning */
   cpu.cache_idx[cpu.cache[idx].oldpc] = 0;
 
-  /* set to new address */
+  /* Set to new address.  */
   cpu.cache[idx].oldpc = pc;
 
-  /* fill in instruction info */
+  /* Fill in instruction info.  */
   decode (pc, cpu.memory + pc, cpu.cache + idx);
 
-  /* point to new cache entry */
+  /* Point to new cache entry.  */
   cpu.cache_idx[pc] = idx;
 }
 
@@ -600,14 +610,13 @@ fetch (arg, n)
       return t;
 
     default:
-      abort ();
+      abort (); /* ?? May be something more usefull? */
 
     }
 }
 
 
-static
-void
+static void
 store (arg, n)
      ea_type *arg;
      int n;
@@ -683,8 +692,7 @@ static union
 
 littleendian;
 
-static
-void
+static void
 init_pointers ()
 {
   static int init;
@@ -704,7 +712,7 @@ init_pointers ()
       cpu.cache_idx = (unsigned short *) calloc (sizeof (short), memory_size);
       cpu.eightbit = (unsigned char *) calloc (sizeof (char), 256);
 
-      /* `msize' must be a power of two */
+      /* `msize' must be a power of two */
       if ((memory_size & (memory_size - 1)) != 0)
        abort ();
       cpu.mask = memory_size - 1;
@@ -751,9 +759,9 @@ init_pointers ()
 
       lreg[8] = &cpu.regs[8];
 
-      /* initialize the seg registers */
+      /* Initialize the seg registers.  */
       if (!cpu.cache)
-       sim_csize (CSIZE);
+       sim_set_simcache_size (CSIZE);
     }
 }
 
@@ -764,6 +772,7 @@ control_c (sig, code, scp, addr)
      char *scp;
      char *addr;
 {
+  cpu.state = SIM_STATE_STOPPED;
   cpu.exception = SIGINT;
 }
 
@@ -771,6 +780,10 @@ control_c (sig, code, scp, addr)
 #define Z (nz == 0)
 #define V (v != 0)
 #define N (n != 0)
+#define U (u != 0)
+#define H (h != 0)
+#define UI (ui != 0)
+#define I (intMaskBit != 0)
 
 static int
 mop (code, bsize, sign)
@@ -816,11 +829,12 @@ mop (code, bsize, sign)
     {
       SET_L_REG (code->dst.reg, result);
     }
-/*  return ((n==1) << 1) | (nz==1); */
-
+#if 0
+  return ((n == 1) << 1) | (nz == 1);
+#endif
 }
 
-#define OSHIFTS(name, how) \
+#define ONOT(name, how) \
 case O(name, SB):                              \
 {                                              \
   int t;                                       \
@@ -846,6 +860,53 @@ case O(name, SL):                          \
   goto shift32;                                        \
 }
 
+#define OSHIFTS(name, how1, how2) \
+case O(name, SB):                              \
+{                                              \
+  int t;                                       \
+  int hm = 0x80;                               \
+  rd = GET_B_REG (code->src.reg);              \
+  if ((GET_MEMORY_B (pc + 1) & 0x40) == 0)     \
+    {                                          \
+      how1;                                    \
+    }                                          \
+  else                                         \
+    {                                          \
+      how2;                                    \
+    }                                          \
+  goto shift8;                                 \
+}                                              \
+case O(name, SW):                              \
+{                                              \
+  int t;                                       \
+  int hm = 0x8000;                             \
+  rd = GET_W_REG (code->src.reg);              \
+  if ((GET_MEMORY_B (pc + 1) & 0x40) == 0)     \
+    {                                          \
+      how1;                                    \
+    }                                          \
+  else                                         \
+    {                                          \
+      how2;                                    \
+    }                                          \
+  goto shift16;                                        \
+}                                              \
+case O(name, SL):                              \
+{                                              \
+  int t;                                       \
+  int hm = 0x80000000;                                 \
+  rd = GET_L_REG (code->src.reg);              \
+  if ((GET_MEMORY_B (pc + 1) & 0x40) == 0)     \
+    {                                          \
+      how1;                                    \
+    }                                          \
+  else                                         \
+    {                                          \
+      how2;                                    \
+    }                                          \
+  goto shift32;                                        \
+}
+
 #define OBITOP(name,f, s, op)                  \
 case  O(name, SB):                             \
 {                                              \
@@ -857,8 +918,18 @@ case  O(name, SB):                         \
   if(s) store (&code->dst,ea); goto next;      \
 }
 
+int
+sim_stop (sd)
+     SIM_DESC sd;
+{
+  cpu.state = SIM_STATE_STOPPED;
+  cpu.exception = SIGINT;
+  return 1;
+}
+
 void
-sim_resume (step, siggnal)
+sim_resume (sd, step, siggnal)
+     SIM_DESC sd;
 {
   static int init1;
   int cycles = 0;
@@ -872,7 +943,7 @@ sim_resume (step, siggnal)
   int ea;
   int bit;
   int pc;
-  int c, nz, v, n;
+  int c, nz, v, n, u, h, ui, intMaskBit;
   int oldmask;
   init_pointers ();
 
@@ -880,10 +951,12 @@ sim_resume (step, siggnal)
 
   if (step)
     {
+      cpu.state = SIM_STATE_STOPPED;
       cpu.exception = SIGTRAP;
     }
   else
     {
+      cpu.state = SIM_STATE_RUNNING;
       cpu.exception = 0;
     }
 
@@ -930,8 +1003,12 @@ sim_resume (step, siggnal)
 
 #endif
 
-      cycles += code->cycles;
-      insts++;
+      if (code->opcode)
+       {
+        cycles += code->cycles;
+        insts++;
+       }
+
       switch (code->opcode)
        {
        case 0:
@@ -1198,41 +1275,37 @@ sim_resume (step, siggnal)
          goto next;
 
        case O (O_SYSCALL, SB):
-         printf ("%c", cpu.regs[2]);
+         {
+           char c = cpu.regs[2];
+           sim_callback->write_stdout (sim_callback, &c, 1);
+         }
          goto next;
 
-         OSHIFTS (O_NOT, rd = ~rd; v = 0;);
-         OSHIFTS (O_SHLL, c = rd & hm; v = 0;
-                  rd <<= 1);
-         OSHIFTS (O_SHLR, c = rd & 1; v = 0;
-                  rd = (unsigned int) rd >> 1);
-         OSHIFTS (O_SHAL, c = rd & hm;
-                  v = (rd & hm) != ((rd & (hm >> 1)) << 1);
-                  rd <<= 1);
-         OSHIFTS (O_SHAR, t = rd & hm;
-                  c = rd & 1;
-                  v = 0;
-                  rd >>= 1;
-                  rd |= t;
-                  );
-         OSHIFTS (O_ROTL, c = rd & hm;
-                  v = 0;
-                  rd <<= 1;
-                  rd |= C);
-         OSHIFTS (O_ROTR, c = rd & 1;
-                  v = 0;
-                  rd = (unsigned int) rd >> 1;
-                  if (c) rd |= hm;);
-         OSHIFTS (O_ROTXL, t = rd & hm;
-                  rd <<= 1;
-                  rd |= C;
-                  c = t;
-                  v = 0;
-                  );
-         OSHIFTS (O_ROTXR, t = rd & 1;
-                  rd = (unsigned int) rd >> 1;
-                  if (C) rd |= hm; c = t;
-                  v = 0;);
+         ONOT (O_NOT, rd = ~rd; v = 0;);
+         OSHIFTS (O_SHLL,
+                  c = rd & hm; v = 0; rd <<= 1,
+                  c = rd & (hm >> 1); v = 0; rd <<= 2);
+         OSHIFTS (O_SHLR,
+                  c = rd & 1; v = 0; rd = (unsigned int) rd >> 1,
+                  c = rd & 2; v = 0; rd = (unsigned int) rd >> 2);
+         OSHIFTS (O_SHAL,
+                  c = rd & hm; v = (rd & hm) != ((rd & (hm >> 1)) << 1); rd <<= 1,
+                  c = rd & (hm >> 1); v = (rd & (hm >> 1)) != ((rd & (hm >> 2)) << 2); rd <<= 2);
+         OSHIFTS (O_SHAR,
+                  t = rd & hm; c = rd & 1; v = 0; rd >>= 1; rd |= t,
+                  t = rd & hm; c = rd & 2; v = 0; rd >>= 2; rd |= t | t >> 1 );
+         OSHIFTS (O_ROTL,
+                  c = rd & hm; v = 0; rd <<= 1; rd |= C,
+                  c = rd & hm; v = 0; rd <<= 1; rd |= C; c = rd & hm; rd <<= 1; rd |= C);
+         OSHIFTS (O_ROTR,
+                  c = rd & 1; v = 0; rd = (unsigned int) rd >> 1; if (c) rd |= hm,
+                  c = rd & 1; v = 0; rd = (unsigned int) rd >> 1; if (c) rd |= hm; c = rd & 1; rd = (unsigned int) rd >> 1; if (c) rd |= hm);
+         OSHIFTS (O_ROTXL,
+                  t = rd & hm; rd <<= 1; rd |= C; c = t; v = 0,
+                  t = rd & hm; rd <<= 1; rd |= C; c = t; v = 0; t = rd & hm; rd <<= 1; rd |= C; c = t);
+         OSHIFTS (O_ROTXR,
+                  t = rd & 1; rd = (unsigned int) rd >> 1; if (C) rd |= hm; c = t; v = 0,
+                  t = rd & 1; rd = (unsigned int) rd >> 1; if (C) rd |= hm; c = t; v = 0; t = rd & 1; rd = (unsigned int) rd >> 1; if (C) rd |= hm; c = t);
 
        case O (O_JMP, SB):
          {
@@ -1266,7 +1339,7 @@ sim_resume (step, siggnal)
          pc = code->src.literal;
          goto call;
 
-       case O (O_RTS, SB):
+       case O (O_RTS, SN):
          {
            int tmp;
 
@@ -1288,18 +1361,24 @@ sim_resume (step, siggnal)
          }
 
        case O (O_ILL, SB):
+         cpu.state = SIM_STATE_STOPPED;
          cpu.exception = SIGILL;
          goto end;
-       case O (O_SLEEP, SB):
-         /* The format of r0 is defined by devo/include/wait.h.
-            cpu.exception handling needs some cleanup: we need to make the
-            the handling of normal exits vs signals, etc. more sensible.  */
-         if (! WIFEXITED (cpu.regs[0]) && WIFSIGNALED (cpu.regs[0]))
+       case O (O_SLEEP, SN):
+         /* FIXME: Doesn't this break for breakpoints when r0
+            contains just the right (er, wrong) value?  */
+         cpu.state = SIM_STATE_STOPPED;
+         /* The format of r0 is defined by target newlib.  Expand
+             the macros here instead of looking for .../sys/wait.h.  */
+#define SIM_WIFEXITED(v) (((v) & 0xff) == 0)
+#define SIM_WIFSIGNALED(v) (((v) & 0x7f) > 0 && (((v) & 0x7f) < 0x7f))
+         if (! SIM_WIFEXITED (cpu.regs[0]) && SIM_WIFSIGNALED (cpu.regs[0])) 
            cpu.exception = SIGILL;
          else
            cpu.exception = SIGTRAP;
          goto end;
-       case O (O_BPT, SB):
+       case O (O_BPT, SN):
+         cpu.state = SIM_STATE_STOPPED;
          cpu.exception = SIGTRAP;
          goto end;
 
@@ -1320,8 +1399,9 @@ sim_resume (step, siggnal)
          OBITOP (O_BXOR, 1, 0, c = (ea & m) != C);
          OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C);
 
-
-#define MOP(bsize, signed) mop(code, bsize,signed); goto next;
+#define MOP(bsize, signed)                     \
+  mop (code, bsize, signed);                   \
+  goto next;
 
        case O (O_MULS, SB):
          MOP (1, 1);
@@ -1343,8 +1423,8 @@ sim_resume (step, siggnal)
            ea = GET_B_REG (code->src.reg);
            if (ea)
              {
-               tmp = (unsigned)rd % ea;
-               rd = (unsigned)rd / ea;
+               tmp = (unsigned) rd % ea;
+               rd = (unsigned) rd / ea;
              }
            SET_W_REG (code->dst.reg, (rd & 0xff) | (tmp << 8));
            n = ea & 0x80;
@@ -1360,8 +1440,8 @@ sim_resume (step, siggnal)
            nz = ea & 0xffff;
            if (ea)
              {
-               tmp = (unsigned)rd % ea;
-               rd = (unsigned)rd / ea;
+               tmp = (unsigned) rd % ea;
+               rd = (unsigned) rd / ea;
              }
            SET_L_REG (code->dst.reg, (rd & 0xffff) | (tmp << 16));
            goto next;
@@ -1421,10 +1501,45 @@ sim_resume (step, siggnal)
          res = rd + ea;
          goto log32;
 
-       case O (O_NOP, SB):
+       case O (O_NOP, SN):
+         goto next;
+
+       case O (O_STM, SL):
+         {
+           int nregs, firstreg, i;
+
+           nregs = GET_MEMORY_B (pc + 1);
+           nregs >>= 4;
+           nregs &= 0xf;
+           firstreg = GET_MEMORY_B (pc + 3);
+           firstreg &= 0xf;
+           for (i = firstreg; i <= firstreg + nregs; i++)
+             {
+               cpu.regs[7] -= 4;
+               SET_MEMORY_L (cpu.regs[7], cpu.regs[i]);
+             }
+         }
+         goto next;
+
+       case O (O_LDM, SL):
+         {
+           int nregs, firstreg, i;
+
+           nregs = GET_MEMORY_B (pc + 1);
+           nregs >>= 4;
+           nregs &= 0xf;
+           firstreg = GET_MEMORY_B (pc + 3);
+           firstreg &= 0xf;
+           for (i = firstreg; i >= firstreg - nregs; i--)
+             {
+               cpu.regs[i] = GET_MEMORY_L (cpu.regs[7]);
+               cpu.regs[7] += 4;
+             }
+         }
          goto next;
 
        default:
+         cpu.state = SIM_STATE_STOPPED;
          cpu.exception = SIGILL;
          goto end;
 
@@ -1592,47 +1707,42 @@ sim_resume (step, siggnal)
 
     end:
       ;
-      /*      if (cpu.regs[8] ) abort(); */
-
-#if defined (WIN32)
-      /* Poll after every 100th insn, */
-      if (poll_count++ > 100)
-       {
-         poll_count = 0;
-         if (win32pollquit())
-           {
-             control_c();
-           }
-       }
+#if 0
+      if (cpu.regs[8])
+       abort ();
 #endif
-#if defined(__GO32__)
-      /* Poll after every 100th insn, */
-      if (poll_count++ > 100)
+
+      if (--poll_count < 0)
        {
-         poll_count = 0;
-         if (kbhit ())
-           {
-             int c = getkey ();
-             control_c ();
-           }
+         poll_count = POLL_QUIT_INTERVAL;
+         if ((*sim_callback->poll_quit) != NULL
+             && (*sim_callback->poll_quit) (sim_callback))
+           sim_stop (sd);
        }
-#endif
 
     }
-  while (!cpu.exception);
+  while (cpu.state == SIM_STATE_RUNNING);
   cpu.ticks += get_now () - tick_start;
   cpu.cycles += cycles;
   cpu.insts += insts;
-  
+
   cpu.pc = pc;
   BUILDSR ();
   cpu.mask = oldmask;
   signal (SIGINT, prev);
 }
 
+int
+sim_trace (sd)
+     SIM_DESC sd;
+{
+  /* FIXME: Unfinished.  */
+  abort ();
+}
 
 int
-sim_write (addr, buffer, size)
+sim_write (sd, addr, buffer, size)
+     SIM_DESC sd;
      SIM_ADDR addr;
      unsigned char *buffer;
      int size;
@@ -1656,7 +1766,8 @@ sim_write (addr, buffer, size)
 }
 
 int
-sim_read (addr, buffer, size)
+sim_read (sd, addr, buffer, size)
+     SIM_DESC sd;
      SIM_ADDR addr;
      unsigned char *buffer;
      int size;
@@ -1683,7 +1794,7 @@ sim_read (addr, buffer, size)
 
 #define SP_REGNUM       R7_REGNUM      /* Contains address of top of stack */
 #define FP_REGNUM       R6_REGNUM      /* Contains address of executing
-                                          * stack frame */
+                                        * stack frame */
 
 #define CCR_REGNUM      8      /* Contains processor status */
 #define PC_REGNUM       9      /* Contains program counter */
@@ -1693,10 +1804,12 @@ sim_read (addr, buffer, size)
 #define TICK_REGNUM     12
 
 
-void
-sim_store_register (rn, value)
+int
+sim_store_register (sd, rn, value, length)
+     SIM_DESC sd;
      int rn;
      unsigned char *value;
+     int length;
 {
   int longval;
   int shortval;
@@ -1738,12 +1851,15 @@ sim_store_register (rn, value)
       cpu.ticks = longval;
       break;
     }
+  return -1;
 }
 
-void
-sim_fetch_register (rn, buf)
+int
+sim_fetch_register (sd, rn, buf, length)
+     SIM_DESC sd;
      int rn;
      unsigned char *buf;
+     int length;
 {
   int v;
   int longreg = 0;
@@ -1754,10 +1870,10 @@ sim_fetch_register (rn, buf)
     {
     default:
       abort ();
-    case 8:
+    case CCR_REGNUM:
       v = cpu.ccr;
       break;
-    case 9:
+    case PC_REGNUM:
       v = cpu.pc;
       break;
     case R0_REGNUM:
@@ -1770,15 +1886,15 @@ sim_fetch_register (rn, buf)
     case R7_REGNUM:
       v = cpu.regs[rn];
       break;
-    case 10:
+    case CYCLE_REGNUM:
       v = cpu.cycles;
       longreg = 1;
       break;
-    case 11:
+    case TICK_REGNUM:
       v = cpu.ticks;
       longreg = 1;
       break;
-    case 12:
+    case INST_REGNUM:
       v = cpu.insts;
       longreg = 1;
       break;
@@ -1795,18 +1911,41 @@ sim_fetch_register (rn, buf)
       buf[0] = v >> 8;
       buf[1] = v;
     }
+  return -1;
 }
 
 void
-sim_stop_reason (reason, sigrc)
+sim_stop_reason (sd, reason, sigrc)
+     SIM_DESC sd;
      enum sim_stop *reason;
      int *sigrc;
 {
+#if 0 /* FIXME: This should work but we can't use it.
+        grep for SLEEP above.  */
+  switch (cpu.state)
+    {
+    case SIM_STATE_EXITED : *reason = sim_exited; break;
+    case SIM_STATE_SIGNALLED : *reason = sim_signalled; break;
+    case SIM_STATE_STOPPED : *reason = sim_stopped; break;
+    default : abort ();
+    }
+#else
   *reason = sim_stopped;
+#endif
   *sigrc = cpu.exception;
 }
 
-sim_csize (n)
+/* FIXME: Rename to sim_set_mem_size.  */
+
+void
+sim_size (n)
+     int n;
+{
+  /* Memory size is fixed.  */
+}
+
+void
+sim_set_simcache_size (n)
 {
   if (cpu.cache)
     free (cpu.cache);
@@ -1819,81 +1958,120 @@ sim_csize (n)
 
 
 void
-sim_info (verbose)
+sim_info (sd, verbose)
+     SIM_DESC sd;
      int verbose;
 {
   double timetaken = (double) cpu.ticks / (double) now_persec ();
   double virttime = cpu.cycles / 10.0e6;
 
-  printf_filtered ("\n\n#instructions executed  %10d\n", cpu.insts);
-  printf_filtered ("#cycles (v approximate) %10d\n", cpu.cycles);
-  printf_filtered ("#real time taken        %10.4f\n", timetaken);
-  printf_filtered ("#virtual time taked     %10.4f\n", virttime);
+  (*sim_callback->printf_filtered) (sim_callback,
+                                   "\n\n#instructions executed  %10d\n",
+                                   cpu.insts);
+  (*sim_callback->printf_filtered) (sim_callback,
+                                   "#cycles (v approximate) %10d\n",
+                                   cpu.cycles);
+  (*sim_callback->printf_filtered) (sim_callback,
+                                   "#real time taken        %10.4f\n",
+                                   timetaken);
+  (*sim_callback->printf_filtered) (sim_callback,
+                                   "#virtual time taked     %10.4f\n",
+                                   virttime);
   if (timetaken != 0.0)
-    printf_filtered ("#simulation ratio       %10.4f\n", virttime / timetaken);
-  printf_filtered ("#compiles               %10d\n", cpu.compiles);
-  printf_filtered ("#cache size             %10d\n", cpu.csize);
+    (*sim_callback->printf_filtered) (sim_callback,
+                                     "#simulation ratio       %10.4f\n",
+                                     virttime / timetaken);
+  (*sim_callback->printf_filtered) (sim_callback,
+                                   "#compiles               %10d\n",
+                                   cpu.compiles);
+  (*sim_callback->printf_filtered) (sim_callback,
+                                   "#cache size             %10d\n",
+                                   cpu.csize);
 
 #ifdef ADEBUG
-  if (verbose)
+  /* This to be conditional on `what' (aka `verbose'),
+     however it was never passed as non-zero.  */
+  if (1)
     {
       int i;
       for (i = 0; i < O_LAST; i++)
        {
          if (cpu.stats[i])
-           printf_filtered ("%d: %d\n", i, cpu.stats[i]);
+           (*sim_callback->printf_filtered) (sim_callback,
+                                             "%d: %d\n", i, cpu.stats[i]);
        }
     }
 #endif
 }
 
-/* Indicate whether the cpu is an h8/300 or h8/300h.
-   FLAG is non-zero for the h8/300h.  */
+/* Indicate whether the cpu is an H8/300 or H8/300H.
+   FLAG is non-zero for the H8/300H.  */
 
 void
 set_h8300h (flag)
      int flag;
 {
+  /* FIXME: Much of the code in sim_load can be moved to sim_open.
+     This function being replaced by a sim_open:ARGV configuration
+     option.  */
   h8300hmode = flag;
 }
 
-void
-sim_kill ()
+SIM_DESC
+sim_open (kind, ptr, abfd, argv)
+     SIM_OPEN_KIND kind;
+     struct host_callback_struct *ptr;
+     struct _bfd *abfd;
+     char **argv;
 {
-  /* nothing to do */
-}
+  /* FIXME: Much of the code in sim_load can be moved here.  */
 
-void
-sim_open (args)
-     char *args;
-{
-  /* nothing to do */
+  sim_kind = kind;
+  myname = argv[0];
+  sim_callback = ptr;
+  /* Fudge our descriptor.  */
+  return (SIM_DESC) 1;
 }
 
 void
-sim_close (quitting)
+sim_close (sd, quitting)
+     SIM_DESC sd;
      int quitting;
 {
-  /* nothing to do */
+  /* Nothing to do.  */
 }
 
 /* Called by gdb to load a program into memory.  */
 
-int
-sim_load (prog, from_tty)
+SIM_RC
+sim_load (sd, prog, abfd, from_tty)
+     SIM_DESC sd;
      char *prog;
+     bfd *abfd;
      int from_tty;
 {
-  bfd *abfd;
+  bfd *prog_bfd;
+
+  /* FIXME: The code below that sets a specific variant of the H8/300
+     being simulated should be moved to sim_open().  */
 
-  /* See if the file is for the h8/300 or h8/300h.  */
+  /* See if the file is for the H8/300 or H8/300H.  */
   /* ??? This may not be the most efficient way.  The z8k simulator
      does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO).  */
-  if ((abfd = bfd_openr (prog, "coff-h8300")) != 0)
+  if (abfd != NULL)
+    prog_bfd = abfd;
+  else
+    prog_bfd = bfd_openr (prog, "coff-h8300");
+  if (prog_bfd != NULL)
     {
-      if (bfd_check_format (abfd, bfd_object)) 
-       set_h8300h (abfd->arch_info->mach == bfd_mach_h8300h);
-      bfd_close (abfd);
+      /* Set the cpu type.  We ignore failure from bfd_check_format
+        and bfd_openr as sim_load_file checks too.  */
+      if (bfd_check_format (prog_bfd, bfd_object))
+       {
+         unsigned long mach = bfd_get_mach (prog_bfd);
+         set_h8300h (mach == bfd_mach_h8300h
+                     || mach == bfd_mach_h8300s);
+       }
     }
 
   /* If we're using gdb attached to the simulator, then we have to
@@ -1904,11 +2082,11 @@ sim_load (prog, from_tty)
      simulator memory.
 
      The problem is when we do that, we don't know whether we're
-     debugging an h8/300 or h8/300h program.
+     debugging an H8/300 or H8/300H program.
 
      This is the first point at which we can make that determination,
      so we just reallocate memory now; this will also allow us to handle
-     switching between h8/300 and h8/300h programs without exiting
+     switching between H8/300 and H8/300H programs without exiting
      gdb.  */
   if (h8300hmode)
     memory_size = H8300H_MSIZE;
@@ -1926,37 +2104,54 @@ sim_load (prog, from_tty)
   cpu.cache_idx = (unsigned short *) calloc (sizeof (short), memory_size);
   cpu.eightbit = (unsigned char *) calloc (sizeof (char), 256);
 
-  /* `msize' must be a power of two */
+  /* `msize' must be a power of two */
   if ((memory_size & (memory_size - 1)) != 0)
     abort ();
   cpu.mask = memory_size - 1;
 
-  /* Return non-zero so gdb will handle it.  */
-  return 1;
+  if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
+                    sim_kind == SIM_OPEN_DEBUG,
+                    0, sim_write)
+      == NULL)
+    {
+      /* Close the bfd if we opened it.  */
+      if (abfd == NULL && prog_bfd != NULL)
+       bfd_close (prog_bfd);
+      return SIM_RC_FAIL;
+    }
+
+  /* Close the bfd if we opened it.  */
+  if (abfd == NULL && prog_bfd != NULL)
+    bfd_close (prog_bfd);
+  return SIM_RC_OK;
 }
 
-void
-sim_create_inferior (start_address, argv, env)
-     SIM_ADDR start_address;
+SIM_RC
+sim_create_inferior (sd, abfd, argv, env)
+     SIM_DESC sd;
+     struct _bfd *abfd;
      char **argv;
      char **env;
 {
-  cpu.pc = start_address;
+  if (abfd != NULL)
+    cpu.pc = bfd_get_start_address (abfd);
+  else
+    cpu.pc = 0;
+  return SIM_RC_OK;
 }
 
 void
-sim_do_command (cmd)
+sim_do_command (sd, cmd)
+     SIM_DESC sd;
      char *cmd;
 {
-  printf_filtered ("This simulator does not accept any commands.\n");
+  (*sim_callback->printf_filtered) (sim_callback,
+                                   "This simulator does not accept any commands.\n");
 }
 
-
-
 void
 sim_set_callbacks (ptr)
-struct host_callback_struct *ptr;
+     struct host_callback_struct *ptr;
 {
-
+  sim_callback = ptr;
 }
-
This page took 0.048442 seconds and 4 git commands to generate.