daily update
[external/binutils.git] / sim / h8300 / compile.c
index e82fe63..7b4a5fa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Simulator for the Hitachi H8/300 architecture.
+ * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
  *
  * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
  *
@@ -53,7 +53,7 @@ static void set_simcache_size (SIM_DESC, int);
 
 #define X(op, size)  (op * 4 + size)
 
-#define SP (h8300hmode ? SL : SW)
+#define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
 
 #define h8_opcodes ops
 #define DEFINE_TABLE
@@ -484,6 +484,18 @@ enum { POLL_QUIT_INTERVAL = 0x80000 };
   h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4)   \
             | (N << 3) | (Z << 2) | (V << 1) | C)
 
+#define GETSR(SD) \
+  /* Get Status Register (flags).  */          \
+  c = (h8_get_ccr (sd) >> 0) & 1;              \
+  v = (h8_get_ccr (sd) >> 1) & 1;              \
+  nz = !((h8_get_ccr (sd) >> 2) & 1);          \
+  n = (h8_get_ccr (sd) >> 3) & 1;              \
+  u = (h8_get_ccr (sd) >> 4) & 1;              \
+  h = (h8_get_ccr (sd) >> 5) & 1;              \
+  ui = ((h8_get_ccr (sd) >> 6) & 1);           \
+  intMaskBit = (h8_get_ccr (sd) >> 7) & 1
+
+
 #ifdef __CHAR_IS_SIGNED__
 #define SEXTCHAR(x) ((char) (x))
 #endif
@@ -498,6 +510,7 @@ enum { POLL_QUIT_INTERVAL = 0x80000 };
 
 int h8300hmode  = 0;
 int h8300smode  = 0;
+int h8300_normal_mode  = 0;
 int h8300sxmode = 0;
 
 static int memory_size;
@@ -527,7 +540,7 @@ bitfrom (int x)
     case L_32:
       return SL;
     case L_P:
-      return h8300hmode ? SL : SW;
+      return (h8300hmode && !h8300_normal_mode)? SL : SW;
     }
   return 0;
 }
@@ -563,9 +576,9 @@ lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
 static int
 cmdline_location()
 {
-  if (h8300smode)
+  if (h8300smode && !h8300_normal_mode)
     return 0xffff00L;
-  else if (h8300hmode)
+  else if (h8300hmode && !h8300_normal_mode)
     return 0x2ff00L;
   else
     return 0xff00L;
@@ -586,13 +599,18 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
   /* Find the exact opcode/arg combo.  */
   for (q = h8_opcodes; q->name; q++)
     {
-      op_type *nib = q->data.nib;
+      const op_type *nib = q->data.nib;
       unsigned int len = 0;
 
       if ((q->available == AV_H8SX && !h8300sxmode) ||
+         (q->available == AV_H8S  && !h8300smode)  ||
          (q->available == AV_H8H  && !h8300hmode))
        continue;
 
+      cst[0]   = cst[1]   = cst[2]   = 0;
+      reg[0]   = reg[1]   = reg[2]   = 0;
+      rdisp[0] = rdisp[1] = rdisp[2] = 0;
+
       while (1)
        {
          op_type looking_for = *nib;
@@ -757,26 +775,11 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                       (looking_for & MODE) == INDEXB ||
                       (looking_for & MODE) == INDEXW ||
                       (looking_for & MODE) == INDEXL)
-
                {
                  switch (looking_for & SIZE)
                    {
                    case L_2:
                      cst[opnum] = thisnib & 3;
-
-                     /* DISP2 special treatment.  */
-                     if ((looking_for & MODE) == DISP)
-                       {
-                         switch (OP_SIZE (q->how)) {
-                         default: break;
-                         case SW:
-                           cst[opnum] *= 2;
-                           break;
-                         case SL:
-                           cst[opnum] *= 4;
-                           break;
-                         }
-                       }
                      break;
                    case L_8:
                      cst[opnum] = SEXTCHAR (data[len / 2]);
@@ -805,7 +808,9 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                       (looking_for & SIZE) == L_16U)
                {
                  cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
-                 if ((looking_for & SIZE) != L_16U)
+                 /* Immediates are always unsigned.  */
+                 if ((looking_for & SIZE) != L_16U &&
+                     (looking_for & MODE) != IMM)
                    cst[opnum] = (short) cst[opnum];    /* Sign extend.  */
                }
              else if (looking_for & ABSJMP)
@@ -831,6 +836,14 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                {
                  cst[opnum] = data[1];
                }
+             else if ((looking_for & MODE) == VECIND)
+               {
+                 if(h8300_normal_mode)
+                   cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
+                 else
+                   cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
+                 cst[opnum] += h8_get_vbr (sd); /* Add vector base reg.  */
+               }
              else if ((looking_for & SIZE) == L_32)
                {
                  int i = len / 2;
@@ -885,6 +898,10 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                      cst[opnum] = data[len / 2] & 0xff;
                    }
                }
+             else if ((looking_for & SIZE) == L_2)
+               {
+                 cst[opnum] = thisnib & 3;
+               }
              else if ((looking_for & SIZE) == L_3 ||
                       (looking_for & SIZE) == L_3NZ)
                {
@@ -907,7 +924,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
 #endif
                  /* Fill in the args.  */
                  {
-                   op_type *args = q->args.nib;
+                   const op_type *args = q->args.nib;
                    int hadone = 0;
                    int nargs;
 
@@ -1001,7 +1018,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                            p->literal = 0;
                            if (OP_KIND (q->how) == O_JSR ||
                                OP_KIND (q->how) == O_JMP)
-                             if (lvalue (sd, p->type, p->reg, &p->type))
+                             if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
                                goto end;
                          }
                        else if ((x & MODE) == ABS)
@@ -1025,14 +1042,15 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                            else
                              p->reg = ZERO_REGNUM;;
                          }
-                       else if ((x & MODE) == MEMIND)
+                       else if ((x & MODE) == MEMIND ||
+                                (x & MODE) == VECIND)
                          {
                            /* Size doesn't matter.  */
                            p->type = X (OP_MEM, SB);
                            p->literal = cst[opnum];
                            if (OP_KIND (q->how) == O_JSR ||
                                OP_KIND (q->how) == O_JMP)
-                             if (lvalue (sd, p->type, p->reg, &p->type))
+                             if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
                                goto end;
                          }
                        else if ((x & MODE) == PCREL)
@@ -1046,31 +1064,64 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                            p->type = X (OP_IMM, SP);
                            p->literal = cst[opnum];
                          }
-                       else if ((x & MODE) == INDEXB ||
-                                (x & MODE) == INDEXW ||
-                                (x & MODE) == INDEXL ||
-                                (x & MODE) == DISP)
+                       else if ((x & MODE) == INDEXB)
                          {
-                           /* Use the instruction to determine 
-                              the operand size.  */
-                           switch (x & MODE) {
-                           case INDEXB:
-                             p->type = X (OP_INDEXB, OP_SIZE (q->how));
-                             break;
-                           case INDEXW:
-                             p->type = X (OP_INDEXW, OP_SIZE (q->how));
-                             break;
-                           case INDEXL:
-                             p->type = X (OP_INDEXL, OP_SIZE (q->how));
-                             break;
-                           case DISP:
-                             p->type = X (OP_DISP,   OP_SIZE (q->how));
-                             break;
-                           }
-
+                           p->type = X (OP_INDEXB, OP_SIZE (q->how));
+                           p->literal = cst[opnum];
+                           p->reg     = rdisp[opnum];
+                         }
+                       else if ((x & MODE) == INDEXW)
+                         {
+                           p->type = X (OP_INDEXW, OP_SIZE (q->how));
                            p->literal = cst[opnum];
                            p->reg     = rdisp[opnum];
                          }
+                       else if ((x & MODE) == INDEXL)
+                         {
+                           p->type = X (OP_INDEXL, OP_SIZE (q->how));
+                           p->literal = cst[opnum];
+                           p->reg     = rdisp[opnum];
+                         }
+                       else if ((x & MODE) == DISP)
+                         {
+                           /* Yuck -- special for mova args.  */
+                           if (strncmp (q->name, "mova", 4) == 0 &&
+                               (x & SIZE) == L_2)
+                             {
+                               /* Mova can have a DISP2 dest, with an
+                                  INDEXB or INDEXW src.  The multiplier
+                                  for the displacement value is determined
+                                  by the src operand, not by the insn.  */
+
+                               switch (OP_KIND (dst->src.type))
+                                 {
+                                 case OP_INDEXB:
+                                   p->type = X (OP_DISP, SB);
+                                   p->literal = cst[opnum];
+                                   break;
+                                 case OP_INDEXW:
+                                   p->type = X (OP_DISP, SW);
+                                   p->literal = cst[opnum] * 2;
+                                   break;
+                                 default:
+                                   goto fail;
+                                 }
+                             }
+                           else
+                             {
+                               p->type = X (OP_DISP,   OP_SIZE (q->how));
+                               p->literal = cst[opnum];
+                               /* DISP2 is special.  */
+                               if ((x & SIZE) == L_2)
+                                 switch (OP_SIZE (q->how))
+                                   {
+                                   case SB:                  break;
+                                   case SW: p->literal *= 2; break;
+                                   case SL: p->literal *= 4; break;
+                                   }
+                             }
+                           p->reg     = rdisp[opnum];
+                         }
                        else if (x & CTRL)
                          {
                            switch (reg[opnum])
@@ -1104,7 +1155,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                            p->type = OP_EXR;
                          }
                        else
-                         printf ("Hmmmm %x...\n", x);
+                         printf ("Hmmmm 0x%x...\n", x);
 
                        args++;
                      }
@@ -1158,7 +1209,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                  return;
                }
              else
-               printf ("Don't understand %x \n", looking_for);
+               printf ("Don't understand 0x%x \n", looking_for);
            }
 
          len++;
@@ -1335,105 +1386,93 @@ fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
       break;
     case X (OP_POSTINC, SB):   /* Register indirect w/post-incr: byte.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_B (t);
+      r = GET_MEMORY_B (t & h8_get_mask (sd));
       if (!twice)
        t += 1;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
     case X (OP_POSTINC, SW):   /* Register indirect w/post-incr: word.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_W (t);
+      r = GET_MEMORY_W (t & h8_get_mask (sd));
       if (!twice)
        t += 2;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
     case X (OP_POSTINC, SL):   /* Register indirect w/post-incr: long.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_L (t);
+      r = GET_MEMORY_L (t & h8_get_mask (sd));
       if (!twice)
        t += 4;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
 
     case X (OP_POSTDEC, SB):   /* Register indirect w/post-decr: byte.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_B (t);
+      r = GET_MEMORY_B (t & h8_get_mask (sd));
       if (!twice)
        t -= 1;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
     case X (OP_POSTDEC, SW):   /* Register indirect w/post-decr: word.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_W (t);
+      r = GET_MEMORY_W (t & h8_get_mask (sd));
       if (!twice)
        t -= 2;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
     case X (OP_POSTDEC, SL):   /* Register indirect w/post-decr: long.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_L (t);
+      r = GET_MEMORY_L (t & h8_get_mask (sd));
       if (!twice)
        t -= 4;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
 
     case X (OP_PREDEC, SB):    /* Register indirect w/pre-decr: byte.  */
       t = GET_L_REG (rn) - 1;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_B (t);
       break;
       
     case X (OP_PREDEC, SW):    /* Register indirect w/pre-decr: word.  */
       t = GET_L_REG (rn) - 2;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_W (t);
       break;
       
     case X (OP_PREDEC, SL):    /* Register indirect w/pre-decr: long.  */
       t = GET_L_REG (rn) - 4;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_L (t);
       break;
       
     case X (OP_PREINC, SB):    /* Register indirect w/pre-incr: byte.  */
       t = GET_L_REG (rn) + 1;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_B (t);
       break;
 
     case X (OP_PREINC, SW):    /* Register indirect w/pre-incr: long.  */
       t = GET_L_REG (rn) + 2;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_W (t);
       break;
 
     case X (OP_PREINC, SL):    /* Register indirect w/pre-incr: long.  */
       t = GET_L_REG (rn) + 4;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_L (t);
       break;
 
@@ -1570,8 +1609,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t -= 1;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_B (t, n);
 
       break;
@@ -1579,8 +1618,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t -= 2;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_W (t, n);
       break;
 
@@ -1588,8 +1627,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t -= 4;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_L (t, n);
       break;
 
@@ -1597,8 +1636,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t += 1;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_B (t, n);
 
       break;
@@ -1606,8 +1645,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t += 2;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_W (t, n);
       break;
 
@@ -1615,45 +1654,51 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t += 4;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_L (t, n);
       break;
 
     case X (OP_POSTDEC, SB):   /* Register indirect w/post-decr, byte.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_B (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t - 1);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_B (t, n);
       break;
 
     case X (OP_POSTDEC, SW):   /* Register indirect w/post-decr, word.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_W (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t - 2);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_W (t, n);
       break;
 
     case X (OP_POSTDEC, SL):   /* Register indirect w/post-decr, long.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_L (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t - 4);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_L (t, n);
       break;
 
     case X (OP_POSTINC, SB):   /* Register indirect w/post-incr, byte.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_B (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t + 1);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_B (t, n);
       break;
 
     case X (OP_POSTINC, SW):   /* Register indirect w/post-incr, word.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_W (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t + 2);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_W (t, n);
       break;
 
     case X (OP_POSTINC, SL):   /* Register indirect w/post-incr, long.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_L (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t + 4);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_L (t, n);
       break;
 
     case X (OP_DISP, SB):      /* Register indirect w/displacement, byte.  */
@@ -1726,9 +1771,9 @@ init_pointers (SIM_DESC sd)
 
       littleendian.i = 1;
 
-      if (h8300smode)
+      if (h8300smode && !h8300_normal_mode)
        memory_size = H8300S_MSIZE;
-      else if (h8300hmode)
+      else if (h8300hmode && !h8300_normal_mode)
        memory_size = H8300H_MSIZE;
       else
        memory_size = H8300_MSIZE;
@@ -1840,7 +1885,7 @@ case O (name, SB):                                \
       goto end;                                        \
   if (fetch (sd, &code->src, &tmp))            \
     goto end;                                  \
-  m = 1 << tmp;                                        \
+  m = 1 << (tmp & 7);                          \
   op;                                          \
   if (s)                                       \
     if (store (sd, &code->dst,ea))             \
@@ -1893,14 +1938,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
     }
 
   /* Get Status Register (flags).  */
-  c = (h8_get_ccr (sd) >> 0) & 1;
-  v = (h8_get_ccr (sd) >> 1) & 1;
-  nz = !((h8_get_ccr (sd) >> 2) & 1);
-  n = (h8_get_ccr (sd) >> 3) & 1;
-  u = (h8_get_ccr (sd) >> 4) & 1;
-  h = (h8_get_ccr (sd) >> 5) & 1;
-  ui = ((h8_get_ccr (sd) >> 6) & 1);
-  intMaskBit = (h8_get_ccr (sd) >> 7) & 1;
+  GETSR (sd);
 
   if (h8300smode)      /* Get exr.  */
     {
@@ -1909,7 +1947,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
     }
 
   oldmask = h8_get_mask (sd);
-  if (!h8300hmode)
+  if (!h8300hmode || h8300_normal_mode)
     h8_set_mask (sd, 0xffff);
   do
     {
@@ -1960,8 +1998,47 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
                (mova/b, mova/w, mova/l).
             4) Add literal value of 1st argument (src).
             5) Store result in 3rd argument (op3).
+         */
+
+         /* Alas, since this is the only instruction with 3 arguments, 
+            decode doesn't handle them very well.  Some fix-up is required.
 
+            a) The size of dst is determined by whether src is 
+               INDEXB or INDEXW.  */
+
+         if (OP_KIND (code->src.type) == OP_INDEXB)
+           code->dst.type = X (OP_KIND (code->dst.type), SB);
+         else if (OP_KIND (code->src.type) == OP_INDEXW)
+           code->dst.type = X (OP_KIND (code->dst.type), SW);
+
+         /* b) If op3 == null, then this is the short form of the insn.
+               Dst is the dispreg of src, and op3 is the 32-bit form
+               of the same register.
          */
+
+         if (code->op3.type == 0)
+           {
+             /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
+                We get to compose dst and op3 as follows:
+
+                    op3 is a 32-bit register, ID == src.reg.
+                    dst is the same register, but 8 or 16 bits
+                    depending on whether src is INDEXB or INDEXW.
+             */
+
+             code->op3.type = X (OP_REG, SL);
+             code->op3.reg  = code->src.reg;
+             code->op3.literal = 0;
+
+             if (OP_KIND (code->src.type) == OP_INDEXB)
+               {
+                 code->dst.type = X (OP_REG, SB);
+                 code->dst.reg = code->op3.reg + 8;
+               }
+             else
+               code->dst.type = X (OP_REG, SW);
+           }
+
          if (fetch (sd, &code->dst, &ea))
            goto end;
 
@@ -2197,7 +2274,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            goto end;
          goto just_flags_log32;
 
-       case O (O_MOVMD, SB):           /* movsd.b */
+       case O (O_MOVMD, SB):           /* movmd.b */
          ea = GET_W_REG (4);
          if (ea == 0)
            ea = 0x10000;
@@ -2212,7 +2289,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            }
          goto next;
 
-       case O (O_MOVMD, SW):           /* movsd.b */
+       case O (O_MOVMD, SW):           /* movmd.w */
          ea = GET_W_REG (4);
          if (ea == 0)
            ea = 0x10000;
@@ -2227,7 +2304,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            }
          goto next;
 
-       case O (O_MOVMD, SL):           /* movsd.b */
+       case O (O_MOVMD, SL):           /* movmd.l */
          ea = GET_W_REG (4);
          if (ea == 0)
            ea = 0x10000;
@@ -2486,7 +2563,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            {
              if (h8300smode)
                h8_set_exr (sd, (trace << 7) | intMask);
-             res = h8_get_exr (sd);
+             rd = h8_get_exr (sd);
            }
          else
            goto illegal;
@@ -2713,7 +2790,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
            /* Setting char_ptr_size to the sizeof (char *) on the different
               architectures.  */
-           if (h8300hmode || h8300smode)
+           if ((h8300hmode || h8300smode) && !h8300_normal_mode)
              {
                char_ptr_size = 4;
              }
@@ -2727,7 +2804,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
                ind_arg_len = 0;
 
                /* The size of the commandline argument.  */
-               ind_arg_len = strlen (h8_get_cmdline_arg (sd, i) + 1);
+               ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
 
                /* The total size of the command line string.  */
                size_cmdline += ind_arg_len;
@@ -2782,7 +2859,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            for (i = 0; i < no_of_args; i++)
              {
                /* Saving the argv pointer.  */
-               if (h8300hmode || h8300smode)
+               if ((h8300hmode || h8300smode) && !h8300_normal_mode)
                  {
                    SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
                  }
@@ -2798,7 +2875,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
            /* Required by POSIX, Setting 0x0 at the end of the list of argv
               pointers.  */
-           if (h8300hmode || h8300smode)
+           if ((h8300hmode || h8300smode) && !h8300_normal_mode)
              {
                SET_MEMORY_L (old_sp, 0x0);
              }
@@ -2837,7 +2914,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
            /* Setting filename_ptr to first argument of open,  */
            /* and trying to get mode.  */
-           if (h8300sxmode || h8300hmode || h8300smode)
+           if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
              {
                filename_ptr = GET_L_REG (0);
                mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
@@ -2888,8 +2965,8 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int read_return = 0;        /* Return value from callback to
                                           read.  */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
-           buf_size = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+           buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
            char_ptr = (char *) malloc (sizeof (char) * buf_size);
 
@@ -2923,9 +3000,9 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int write_return;   /* Return value from callback to write.  */
            int i = 0;          /* Loop counter */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
-           char_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
-           len = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+           char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
+           len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
            /* Allocating space for the characters to be written.  */
            ptr = (char *) malloc (sizeof (char) * len);
@@ -2955,9 +3032,9 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int origin;         /* Origin */
            int lseek_return;   /* Return value from callback to lseek.  */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
-           offset = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
-           origin = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+           offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
+           origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
            /* Callback lseek and return offset.  */
            lseek_return =
@@ -2973,7 +3050,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int fd;             /* File descriptor */
            int close_return;   /* Return value from callback to close.  */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
            /* Callback close and return.  */
            close_return = sim_callback->close (sim_callback, fd);
@@ -2991,10 +3068,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int stat_ptr;       /* Pointer to stat record.  */
            char *temp_stat_ptr;        /* Temporary stat_rec pointer.  */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
            /* Setting stat_ptr to second argument of stat.  */
-           stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
+           stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
 
            /* Callback stat and return.  */
            fstat_return = sim_callback->fstat (sim_callback, fd, &stat_rec);
@@ -3043,7 +3120,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int i = 0;          /* Loop Counter */
 
            /* Setting filename_ptr to first argument of open.  */
-           filename_ptr = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+           filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
            /* Trying to find the length of the filename.  */
            temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
@@ -3067,7 +3144,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
            /* Setting stat_ptr to second argument of stat.  */
            /* stat_ptr = h8_get_reg (sd, 1); */
-           stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
+           stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
 
            /* Callback stat and return.  */
            stat_return =
@@ -3134,10 +3211,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
 
-         if (code->src.type == X (OP_IMM, SB))
+         if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+           ea = 1;             /* unary  op */
+         else                  /* binary op */
            fetch (sd, &code->src, &ea);
-         else
-           ea = 1;
 
          if (code->opcode == O (O_SHLL, SB))
            {
@@ -3158,10 +3235,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
 
-         if (code->src.type == X (OP_IMM, SW))
-           fetch (sd, &code->src, &ea);
+         if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+           ea = 1;             /* unary  op */
          else
-           ea = 1;
+           fetch (sd, &code->src, &ea);
 
          if (code->opcode == O (O_SHLL, SW))
            {
@@ -3182,10 +3259,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
 
-         if (code->src.type == X (OP_IMM, SL))
-           fetch (sd, &code->src, &ea);
+         if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+           ea = 1;             /* unary  op */
          else
-           ea = 1;
+           fetch (sd, &code->src, &ea);
 
          if (code->opcode == O (O_SHLL, SL))
            {
@@ -3463,36 +3540,31 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
         case O (O_JMP, SL):
         case O (O_JMP, SB):            /* jmp */
         case O (O_JMP, SW):
-         {
-           fetch (sd, &code->src, &pc);
-           goto end;
-         }
+         fetch (sd, &code->src, &pc);
+         goto end;
 
        case O (O_JSR, SN):
        case O (O_JSR, SL):
        case O (O_JSR, SB):             /* jsr, jump to subroutine */
        case O (O_JSR, SW):
-         {
-           int tmp;
-           if (fetch (sd, &code->src, &pc))
-             goto end;
-         call:
-           tmp = h8_get_reg (sd, SP_REGNUM);
+         if (fetch (sd, &code->src, &pc))
+           goto end;
+       call:
+         tmp = h8_get_reg (sd, SP_REGNUM);
 
-           if (h8300hmode)
-             {
-               tmp -= 4;
-               SET_MEMORY_L (tmp, code->next_pc);
-             }
-           else
-             {
-               tmp -= 2;
-               SET_MEMORY_W (tmp, code->next_pc);
-             }
-           h8_set_reg (sd, SP_REGNUM, tmp);
+         if (h8300hmode && !h8300_normal_mode)
+           {
+             tmp -= 4;
+             SET_MEMORY_L (tmp, code->next_pc);
+           }
+         else
+           {
+             tmp -= 2;
+             SET_MEMORY_W (tmp, code->next_pc);
+           }
+         h8_set_reg (sd, SP_REGNUM, tmp);
 
-           goto end;
-         }
+         goto end;
 
        case O (O_BSR, SW):
        case O (O_BSR, SL):
@@ -3502,26 +3574,52 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          pc = code->next_pc + res;
          goto call;
 
-       case O (O_RTS, SN):             /* rts, return from subroutine */
-         {
-           int tmp;
+       case O (O_RTE, SN):             /* rte, return from exception */
+       rte:
+         /* Pops exr and ccr before pc -- otherwise identical to rts.  */
+         tmp = h8_get_reg (sd, SP_REGNUM);
 
-           tmp = h8_get_reg (sd, SP_REGNUM);
+         if (h8300smode)                       /* pop exr */
+           {
+             h8_set_exr (sd, GET_MEMORY_L (tmp));
+             tmp += 4;
+           }
+         if (h8300hmode && !h8300_normal_mode)
+           {
+             h8_set_ccr (sd, GET_MEMORY_L (tmp));
+             tmp += 4;
+             pc = GET_MEMORY_L (tmp);
+             tmp += 4;
+           }
+         else
+           {
+             h8_set_ccr (sd, GET_MEMORY_W (tmp));
+             tmp += 2;
+             pc = GET_MEMORY_W (tmp);
+             tmp += 2;
+           }
 
-           if (h8300hmode)
-             {
-               pc = GET_MEMORY_L (tmp);
-               tmp += 4;
-             }
-           else
-             {
-               pc = GET_MEMORY_W (tmp);
-               tmp += 2;
-             }
+         GETSR (sd);
+         h8_set_reg (sd, SP_REGNUM, tmp);
+         goto end;
 
-           h8_set_reg (sd, SP_REGNUM, tmp);
-           goto end;
-         }
+       case O (O_RTS, SN):             /* rts, return from subroutine */
+       rts:
+         tmp = h8_get_reg (sd, SP_REGNUM);
+
+         if (h8300hmode && !h8300_normal_mode)
+           {
+             pc = GET_MEMORY_L (tmp);
+             tmp += 4;
+           }
+         else
+           {
+             pc = GET_MEMORY_W (tmp);
+             tmp += 2;
+           }
+
+         h8_set_reg (sd, SP_REGNUM, tmp);
+         goto end;
 
        case O (O_ILL, SB):             /* illegal */
          sim_engine_set_run_state (sd, sim_stopped, SIGILL);
@@ -3537,6 +3635,17 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              sim_engine_set_run_state (sd, sim_exited, 
                                        SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
            }
+#if 0
+         /* Unfortunately this won't really work, because
+            when we take a breakpoint trap, R0 has a "random", 
+            user-defined value.  Don't see any immediate solution.  */
+         else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
+           {
+             /* Pass the stop signal up to gdb.  */
+             sim_engine_set_run_state (sd, sim_stopped, 
+                                       SIM_WSTOPSIG (h8_get_reg (sd, 0)));
+           }
+#endif
          else
            {
              /* Treat it as a sigtrap.  */
@@ -3544,6 +3653,42 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            }
          goto end;
 
+       case O (O_TRAPA, SB):           /* trapa */
+         if (fetch (sd, &code->src, &res))
+           goto end;                   /* res is vector number.  */
+  
+         tmp = h8_get_reg (sd, SP_REGNUM);
+         if(h8300_normal_mode)
+           {
+             tmp -= 2;
+             SET_MEMORY_W (tmp, code->next_pc);
+             tmp -= 2;
+             SET_MEMORY_W (tmp, h8_get_ccr (sd));
+           }
+         else
+           {
+             tmp -= 4;
+             SET_MEMORY_L (tmp, code->next_pc);
+             tmp -= 4;
+             SET_MEMORY_L (tmp, h8_get_ccr (sd));
+           }
+         intMaskBit = 1;
+         BUILDSR (sd);
+         if (h8300smode)
+           {
+             tmp -= 4;
+             SET_MEMORY_L (tmp, h8_get_exr (sd));
+           }
+
+         h8_set_reg (sd, SP_REGNUM, tmp);
+
+         if(h8300_normal_mode)
+           pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
+         else
+           pc = GET_MEMORY_L (0x20 + res * 4);
+         goto end;
+
        case O (O_BPT, SN):
          sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
          goto end;
@@ -3738,13 +3883,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfff0;
-         else
-           ea = SEXTSHORT (ea);
-
+         ea = SEXTSHORT (ea);
          res = SEXTSHORT (ea * SEXTSHORT (rd));
 
          n  = res & 0x8000;
@@ -3759,11 +3898,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-
          res = ea * rd;
 
          n  = res & 0x80000000;
@@ -3777,11 +3911,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-
          /* Compute upper 32 bits of the 64-bit result.  */
          res = (((long long) ea) * ((long long) rd)) >> 32;
 
@@ -3837,13 +3966,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-         else
-           ea = SEXTCHAR (ea);
-
+         ea = SEXTCHAR (ea);
          res = ea * SEXTCHAR (rd);
 
          n  = res & 0x8000;
@@ -3858,13 +3981,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfff0;
-         else
-           ea = SEXTSHORT (ea);
-
+         ea = SEXTSHORT (ea);
          res = ea * SEXTSHORT (rd & 0xffff);
 
          n  = res & 0x80000000;
@@ -3898,19 +4015,19 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
          goto next;
 
-       case O (O_TAS, SB):             /* tas, (test and set?) */
-         if (!h8300smode || code->src.type != X (OP_REG, SL))
-           goto illegal;
-         switch (code->src.reg)
-           {
-           case R0_REGNUM:
-           case R1_REGNUM:
-           case R4_REGNUM:
-           case R5_REGNUM:
-             break;
-           default:
-             goto illegal;
-           }
+       case O (O_TAS, SB):             /* tas (test and set) */
+         if (!h8300sxmode)             /* h8sx can use any register. */
+           switch (code->src.reg)
+             {
+             case R0_REGNUM:
+             case R1_REGNUM:
+             case R4_REGNUM:
+             case R5_REGNUM:
+               break;
+             default:
+               goto illegal;
+             }
+
          if (fetch (sd, &code->src, &res))
            goto end;
          if (store (sd, &code->src, res | 0x80))
@@ -3955,11 +4072,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-
          if (ea)
            {
              res = SEXTSHORT (rd) / SEXTSHORT (ea);
@@ -3981,11 +4093,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-
          if (ea)
            {
              res = rd / ea;
@@ -4023,7 +4130,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              res = 0;
            }
 
-         if (store (sd, &code->dst, (res & 0xffff) | (tmp << 8)))
+         if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
            goto end;
          goto next;
 
@@ -4057,13 +4164,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            goto end;
 
          rd = SEXTSHORT (rd);
-
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-         else
-           ea = SEXTCHAR (ea);
+         ea = SEXTCHAR (ea);
 
          if (ea)
            {
@@ -4088,12 +4189,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-         else
-           ea = SEXTSHORT (ea);
+         ea = SEXTSHORT (ea);
 
          if (ea)
            {
@@ -4190,25 +4286,33 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          goto next;
 
        case O (O_LDM, SL):                     /* ldm,  load from memory */
+       case O (O_RTEL, SN):                    /* rte/l, ldm plus rte */
+       case O (O_RTSL, SN):                    /* rts/l, ldm plus rts */
          {
            int nregs, firstreg, i;
 
-           nregs = GET_MEMORY_B (pc + 1);
-           nregs >>= 4;
-           nregs &= 0xf;
-           firstreg = code->dst.reg;
-           firstreg &= 0xf;
+           nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
+           firstreg = code->dst.reg & 0xf;
            for (i = firstreg; i >= firstreg - nregs; i--)
              {
                h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
                h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
              }
          }
-         goto next;
+         switch (code->opcode) {
+         case O (O_RTEL, SN):
+           goto rte;
+         case O (O_RTSL, SN):
+           goto rts;
+         case O (O_LDM, SL):
+           goto next;
+         default:
+           goto illegal;
+         }
 
        case O (O_DAA, SB):
          /* Decimal Adjust Addition.  This is for BCD arithmetic.  */
-         res = GET_B_REG (code->src.reg);
+         res = GET_B_REG (code->src.reg);      /* FIXME fetch? */
          if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) && 
              !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
            res = res;          /* Value added == 0.  */
@@ -4274,15 +4378,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          code->dst.type == X (OP_CCR, SW))
        {
          h8_set_ccr (sd, res);
-         /* Get Status Register (flags).  */
-         c = (h8_get_ccr (sd) >> 0) & 1;
-         v = (h8_get_ccr (sd) >> 1) & 1;
-         nz = !((h8_get_ccr (sd) >> 2) & 1);
-         n = (h8_get_ccr (sd) >> 3) & 1;
-         u = (h8_get_ccr (sd) >> 4) & 1;
-         h = (h8_get_ccr (sd) >> 5) & 1;
-         ui = ((h8_get_ccr (sd) >> 6) & 1);
-         intMaskBit = (h8_get_ccr (sd) >> 7) & 1;
+         GETSR (sd);
        }
       else if (h8300smode &&
               (code->dst.type == X (OP_EXR, SB) ||
@@ -4520,7 +4616,7 @@ sim_trace (SIM_DESC sd)
 }
 
 int
-sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
+sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
 {
   int i;
 
@@ -4569,6 +4665,12 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
   init_pointers (sd);
   switch (rn)
     {
+    case PC_REGNUM:
+      if(h8300_normal_mode)
+        h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */
+      else
+        h8_set_pc (sd, intval);
+      break;
     default:
       (*sim_callback->printf_filtered) (sim_callback, 
                                        "sim_store_register: bad regnum %d.\n",
@@ -4583,9 +4685,6 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
     case R7_REGNUM:
       h8_set_reg (sd, rn, intval);
       break;
-    case PC_REGNUM:
-      h8_set_pc (sd, intval);
-      break;
     case CCR_REGNUM:
       h8_set_ccr (sd, intval);
       break;
@@ -4607,14 +4706,16 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
     case CYCLE_REGNUM:
       h8_set_cycles (sd, longval);
       break;
+
     case INST_REGNUM:
       h8_set_insts (sd, longval);
       break;
+
     case TICK_REGNUM:
       h8_set_ticks (sd, longval);
       break;
     }
-  return -1;
+  return length;
 }
 
 int
@@ -4679,7 +4780,8 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
       longreg = 1;
       break;
     }
-  if (h8300hmode || longreg)
+  /* In Normal mode PC is 2 byte, but other registers are 4 byte */
+  if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
     {
       buf[0] = v >> 24;
       buf[1] = v >> 16;
@@ -4776,7 +4878,9 @@ set_h8300h (unsigned long machine)
      This function being replaced by a sim_open:ARGV configuration
      option.  */
 
-  if (machine == bfd_mach_h8300sx)
+  h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
+
+  if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
     h8300sxmode = 1;
 
   if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
@@ -4784,6 +4888,9 @@ set_h8300h (unsigned long machine)
 
   if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
     h8300hmode = 1;
+
+  if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
+    h8300_normal_mode = 1;
 }
 
 /* Cover function of sim_state_free to free the cpu buffers as well.  */
@@ -4893,7 +5000,7 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
   if (abfd != NULL)
     prog_bfd = abfd;
   else
-    prog_bfd = bfd_openr (prog, "coff-h8300");
+    prog_bfd = bfd_openr (prog, NULL);
   if (prog_bfd != NULL)
     {
       /* Set the cpu type.  We ignore failure from bfd_check_format
@@ -4919,9 +5026,9 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
      switching between H8/300 and H8/300H programs without exiting
      gdb.  */
 
-  if (h8300smode)
+  if (h8300smode && !h8300_normal_mode)
     memory_size = H8300S_MSIZE;
-  else if (h8300hmode)
+  else if (h8300hmode && !h8300_normal_mode)
     memory_size = H8300H_MSIZE;
   else
     memory_size = H8300_MSIZE;
@@ -4937,6 +5044,7 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
                     calloc (sizeof (char), memory_size));
   h8_set_cache_idx_buf (sd, (unsigned short *) 
                        calloc (sizeof (short), memory_size));
+  sd->memory_size = memory_size;
   h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
 
   /* `msize' must be a power of two.  */
@@ -5000,13 +5108,6 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
 }
 
 void
-sim_do_command (SIM_DESC sd, char *cmd)
-{
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "This simulator does not accept any commands.\n");
-}
-
-void
 sim_set_callbacks (struct host_callback_struct *ptr)
 {
   sim_callback = ptr;