This commit was generated by cvs2svn to track changes on a CVS vendor
[binutils-gdb.git] / sim / h8300 / compile.c
index d5f72f787e8f1cbbec2f06115fcc643a8bc2f23f..8e4b55d6a2807d280fc74104eba1448fbb337331 100644 (file)
@@ -32,8 +32,9 @@
 #endif
 #include "ansidecl.h"
 #include "bfd.h"
-#include "callback.h"
-#include "remote-sim.h"
+#include "gdb/callback.h"
+#include "gdb/remote-sim.h"
+#include "gdb/sim-h8300.h"
 
 #ifndef SIGTRAP
 # define SIGTRAP 5
@@ -67,6 +68,7 @@ void sim_set_simcache_size PARAMS ((int));
 #define OP_CCR 7
 #define OP_IMM 8
 #define OP_ABS 10
+#define OP_EXR 11
 #define h8_opcodes ops
 #define DEFINE_TABLE
 #include "opcode/h8300.h"
@@ -84,6 +86,9 @@ void sim_set_simcache_size PARAMS ((int));
 #define BUILDSR()   cpu.ccr = (I << 7) | (UI << 6)| (H<<5) | (U<<4) | \
                               (N << 3) | (Z << 2) | (V<<1) | C;
 
+#define BUILDEXR()         \
+  if (h8300smode) cpu.exr = (trace<<7) | intMask;
+
 #define GETSR()                    \
   c = (cpu.ccr >> 0) & 1;\
   v = (cpu.ccr >> 1) & 1;\
@@ -94,6 +99,11 @@ void sim_set_simcache_size PARAMS ((int));
   ui = ((cpu.ccr >> 6) & 1);\
   intMaskBit = (cpu.ccr >> 7) & 1;
 
+#define GETEXR()           \
+  if (h8300smode) { \
+    trace = (cpu.exr >> 7) & 1;\
+    intMask = cpu.exr & 7; }
+
 #ifdef __CHAR_IS_SIGNED__
 #define SEXTCHAR(x) ((char) (x))
 #endif
@@ -412,6 +422,10 @@ decode (addr, data, dst)
                          {
                            p->type = OP_CCR;
                          }
+                       else if (x & EXR)
+                         {
+                           p->type = OP_EXR;
+                         }
                        else
                          printf ("Hmmmm %x", x);
 
@@ -704,7 +718,9 @@ init_pointers ()
       init = 1;
       littleendian.i = 1;
 
-      if (h8300hmode)
+      if (h8300smode)
+       memory_size = H8300S_MSIZE;
+      else if (h8300hmode)
        memory_size = H8300H_MSIZE;
       else
        memory_size = H8300_MSIZE;
@@ -835,7 +851,7 @@ mop (code, bsize, sign)
 }
 
 #define ONOT(name, how) \
-case O(name, SB):                              \
+case O (name, SB):                             \
 {                                              \
   int t;                                       \
   int hm = 0x80;                               \
@@ -843,7 +859,7 @@ case O(name, SB):                           \
   how;                                                 \
   goto shift8;                                 \
 }                                              \
-case O(name, SW):                              \
+case O (name, SW):                             \
 {                                              \
   int t;                                       \
   int hm = 0x8000;                             \
@@ -851,7 +867,7 @@ case O(name, SW):                           \
   how;                                                 \
   goto shift16;                                        \
 }                                              \
-case O(name, SL):                              \
+case O (name, SL):                             \
 {                                              \
   int t;                                       \
   int hm = 0x80000000;                                 \
@@ -861,7 +877,7 @@ case O(name, SL):                           \
 }
 
 #define OSHIFTS(name, how1, how2) \
-case O(name, SB):                              \
+case O (name, SB):                             \
 {                                              \
   int t;                                       \
   int hm = 0x80;                               \
@@ -876,7 +892,7 @@ case O(name, SB):                           \
     }                                          \
   goto shift8;                                 \
 }                                              \
-case O(name, SW):                              \
+case O (name, SW):                             \
 {                                              \
   int t;                                       \
   int hm = 0x8000;                             \
@@ -891,7 +907,7 @@ case O(name, SW):                           \
     }                                          \
   goto shift16;                                        \
 }                                              \
-case O(name, SL):                              \
+case O (name, SL):                             \
 {                                              \
   int t;                                       \
   int hm = 0x80000000;                                 \
@@ -908,14 +924,14 @@ case O(name, SL):                         \
 }
 
 #define OBITOP(name,f, s, op)                  \
-case  O(name, SB):                             \
+case (name, SB):                             \
 {                                              \
   int m;                                       \
   int b;                                       \
   if (f) ea = fetch (&code->dst);              \
-  m=1<< fetch(&code->src);                     \
+  m=1<< fetch (&code->src);                    \
   op;                                          \
-  if(s) store (&code->dst,ea); goto next;      \
+  if (s) store (&code->dst,ea); goto next;     \
 }
 
 int
@@ -927,6 +943,28 @@ sim_stop (sd)
   return 1;
 }
 
+#define R0_REGNUM      0
+#define R1_REGNUM      1
+#define R2_REGNUM      2
+#define R3_REGNUM      3
+#define R4_REGNUM      4
+#define R5_REGNUM      5
+#define R6_REGNUM      6
+#define R7_REGNUM      7
+
+#define SP_REGNUM       R7_REGNUM      /* Contains address of top of stack */
+#define FP_REGNUM       R6_REGNUM      /* Contains address of executing
+                                        * stack frame */
+
+#define CCR_REGNUM      8      /* Contains processor status */
+#define PC_REGNUM       9      /* Contains program counter */
+
+#define CYCLE_REGNUM    10
+
+#define EXR_REGNUM     11
+#define INST_REGNUM     12
+#define TICK_REGNUM     13
+
 void
 sim_resume (sd, step, siggnal)
      SIM_DESC sd;
@@ -944,6 +982,7 @@ sim_resume (sd, step, siggnal)
   int bit;
   int pc;
   int c, nz, v, n, u, h, ui, intMaskBit;
+  int trace, intMask;
   int oldmask;
   init_pointers ();
 
@@ -967,6 +1006,8 @@ sim_resume (sd, step, siggnal)
     abort ();
 
   GETSR ();
+  GETEXR ();
+
   oldmask = cpu.mask;
   if (!h8300hmode)
     cpu.mask = 0xffff;
@@ -981,15 +1022,15 @@ sim_resume (sd, step, siggnal)
 
 
 #define ALUOP(STORE, NAME, HOW) \
-    case O(NAME,SB):  HOW; if(STORE)goto alu8;else goto just_flags_alu8;  \
-    case O(NAME, SW): HOW; if(STORE)goto alu16;else goto just_flags_alu16; \
-    case O(NAME,SL):  HOW; if(STORE)goto alu32;else goto just_flags_alu32;
+    case O (NAME,SB):  HOW; if (STORE)goto alu8;else goto just_flags_alu8;  \
+    case O (NAME, SW): HOW; if (STORE)goto alu16;else goto just_flags_alu16; \
+    case O (NAME,SL):  HOW; if (STORE)goto alu32;else goto just_flags_alu32;
 
 
 #define LOGOP(NAME, HOW) \
-    case O(NAME,SB): HOW; goto log8;\
-    case O(NAME, SW): HOW; goto log16;\
-    case O(NAME,SL): HOW; goto log32;
+    case O (NAME,SB): HOW; goto log8;\
+    case O (NAME, SW): HOW; goto log16;\
+    case O (NAME,SL): HOW; goto log32;
 
 
 
@@ -1004,10 +1045,10 @@ sim_resume (sd, step, siggnal)
 #endif
 
       if (code->opcode)
-       {
-        cycles += code->cycles;
-        insts++;
-       }
+       {
+         cycles += code->cycles;
+         insts++;
+       }
 
       switch (code->opcode)
        {
@@ -1035,8 +1076,8 @@ sim_resume (sd, step, siggnal)
          res = rd + ea;
          goto alu8;
 
-#define EA    ea = fetch(&code->src);
-#define RD_EA ea = fetch(&code->src); rd = fetch(&code->dst);
+#define EA    ea = fetch (&code->src);
+#define RD_EA ea = fetch (&code->src); rd = fetch (&code->dst);
 
          ALUOP (1, O_SUB, RD_EA;
                 ea = -ea;
@@ -1097,6 +1138,37 @@ sim_resume (sd, step, siggnal)
          SET_L_REG (code->dst.reg, res);
          goto just_flags_log32;
 
+       case O (O_EEPMOV, SB):
+       case O (O_EEPMOV, SW):
+         if (h8300hmode||h8300smode)
+           {
+             register unsigned char *_src,*_dst;
+             unsigned int count = (code->opcode == O(O_EEPMOV, SW))?cpu.regs[R4_REGNUM]&0xffff:
+               cpu.regs[R4_REGNUM]&0xff;
+
+             _src = cpu.regs[R5_REGNUM] < memory_size ? cpu.memory+cpu.regs[R5_REGNUM] :
+               cpu.eightbit + (cpu.regs[R5_REGNUM] & 0xff);
+             if ((_src+count)>=(cpu.memory+memory_size))
+               {
+                 if ((_src+count)>=(cpu.eightbit+0x100))
+                   goto illegal;
+               }
+             _dst = cpu.regs[R6_REGNUM] < memory_size ? cpu.memory+cpu.regs[R6_REGNUM] :
+                                                             cpu.eightbit + (cpu.regs[R6_REGNUM] & 0xff);
+             if ((_dst+count)>=(cpu.memory+memory_size))
+               {
+                 if ((_dst+count)>=(cpu.eightbit+0x100))
+                   goto illegal;
+               }
+             memcpy(_dst,_src,count);
+
+             cpu.regs[R5_REGNUM]+=count;
+             cpu.regs[R6_REGNUM]+=count;
+             cpu.regs[R4_REGNUM]&=(code->opcode == O(O_EEPMOV, SW))?(~0xffff):(~0xff);
+             cycles += 2*count;
+             goto next;
+           }
+         goto illegal;
 
        case O (O_ADDS, SL):
          SET_L_REG (code->dst.reg,
@@ -1176,23 +1248,69 @@ sim_resume (sd, step, siggnal)
          SET_L_REG (code->dst.reg, res);
          goto just_flags_inc32;
 
-
 #define GET_CCR(x) BUILDSR();x = cpu.ccr
+#define GET_EXR(x) BUILDEXR ();x = cpu.exr
+
+       case O (O_LDC, SB):
+       case O (O_LDC, SW):
+         res = fetch (&code->src);
+         goto setc;
+       case O (O_STC, SB):
+       case O (O_STC, SW):
+         if (code->src.type == OP_CCR)
+           {
+             GET_CCR (res);
+           }
+         else if (code->src.type == OP_EXR && h8300smode)
+           {
+             GET_EXR (res);
+           }
+         else
+           goto illegal;
+         store (&code->dst, res);
+         goto next;
 
        case O (O_ANDC, SB):
-         GET_CCR (rd);
+         if (code->dst.type == OP_CCR)
+           {
+             GET_CCR (rd);
+           }
+         else if (code->dst.type == OP_EXR && h8300smode)
+           {
+             GET_EXR (rd);
+           }
+         else
+           goto illegal;
          ea = code->src.literal;
          res = rd & ea;
          goto setc;
 
        case O (O_ORC, SB):
-         GET_CCR (rd);
+         if (code->dst.type == OP_CCR)
+           {
+             GET_CCR (rd);
+           }
+         else if (code->dst.type == OP_EXR && h8300smode)
+           {
+             GET_EXR (rd);
+           }
+         else
+           goto illegal;
          ea = code->src.literal;
          res = rd | ea;
          goto setc;
 
        case O (O_XORC, SB):
-         GET_CCR (rd);
+         if (code->dst.type == OP_CCR)
+           {
+             GET_CCR (rd);
+           }
+         else if (code->dst.type == OP_EXR && h8300smode)
+           {
+             GET_EXR (rd);
+           }
+         else
+           goto illegal;
          ea = code->src.literal;
          res = rd ^ ea;
          goto setc;
@@ -1293,7 +1411,7 @@ sim_resume (sd, step, siggnal)
                   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 );
+                  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);
@@ -1372,7 +1490,7 @@ sim_resume (sd, step, siggnal)
              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])) 
+         if (! SIM_WIFEXITED (cpu.regs[0]) && SIM_WIFSIGNALED (cpu.regs[0]))
            cpu.exception = SIGILL;
          else
            cpu.exception = SIGTRAP;
@@ -1385,7 +1503,7 @@ sim_resume (sd, step, siggnal)
          OBITOP (O_BNOT, 1, 1, ea ^= m);
          OBITOP (O_BTST, 1, 0, nz = ea & m);
          OBITOP (O_BCLR, 1, 1, ea &= ~m);
-         OBITOP (O_BSET, 1, 1, ea |= m);       
+         OBITOP (O_BSET, 1, 1, ea |= m);
          OBITOP (O_BLD, 1, 0, c = ea & m);
          OBITOP (O_BILD, 1, 0, c = !(ea & m));
          OBITOP (O_BST, 1, 1, ea &= ~m;
@@ -1416,6 +1534,22 @@ sim_resume (sd, step, siggnal)
          MOP (0, 0);
          break;
 
+       case O (O_TAS, SB):
+         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;
+           }
+         res = fetch (&code->src);
+         store (&code->src,res|0x80);
+         goto just_flags_log8;
 
        case O (O_DIVU, SB):
          {
@@ -1539,6 +1673,7 @@ sim_resume (sd, step, siggnal)
          goto next;
 
        default:
+        illegal:
          cpu.state = SIM_STATE_STOPPED;
          cpu.exception = SIGILL;
          goto end;
@@ -1547,8 +1682,19 @@ sim_resume (sd, step, siggnal)
       abort ();
 
     setc:
-      cpu.ccr = res;
-      GETSR ();
+      if (code->dst.type == OP_CCR)
+       {
+         cpu.ccr = res;
+         GETSR ();
+       }
+      else if (code->dst.type == OP_EXR && h8300smode)
+       {
+         cpu.exr = res;
+         GETEXR ();
+       }
+      else
+       goto illegal;
+
       goto next;
 
     condtrue:
@@ -1728,6 +1874,7 @@ sim_resume (sd, step, siggnal)
 
   cpu.pc = pc;
   BUILDSR ();
+  BUILDEXR ();
   cpu.mask = oldmask;
   signal (SIGINT, prev);
 }
@@ -1783,27 +1930,6 @@ sim_read (sd, addr, buffer, size)
 }
 
 
-#define R0_REGNUM      0
-#define R1_REGNUM      1
-#define R2_REGNUM      2
-#define R3_REGNUM      3
-#define R4_REGNUM      4
-#define R5_REGNUM      5
-#define R6_REGNUM      6
-#define R7_REGNUM      7
-
-#define SP_REGNUM       R7_REGNUM      /* Contains address of top of stack */
-#define FP_REGNUM       R6_REGNUM      /* Contains address of executing
-                                        * stack frame */
-
-#define CCR_REGNUM      8      /* Contains processor status */
-#define PC_REGNUM       9      /* Contains program counter */
-
-#define CYCLE_REGNUM    10
-#define INST_REGNUM     11
-#define TICK_REGNUM     12
-
-
 int
 sim_store_register (sd, rn, value, length)
      SIM_DESC sd;
@@ -1839,6 +1965,9 @@ sim_store_register (sd, rn, value, length)
     case CCR_REGNUM:
       cpu.ccr = intval;
       break;
+    case EXR_REGNUM:
+      cpu.exr = intval;
+      break;
     case CYCLE_REGNUM:
       cpu.cycles = longval;
       break;
@@ -1866,6 +1995,8 @@ sim_fetch_register (sd, rn, buf, length)
 
   init_pointers ();
 
+  if (!h8300smode && rn >=EXR_REGNUM)
+    rn++;
   switch (rn)
     {
     default:
@@ -1873,6 +2004,9 @@ sim_fetch_register (sd, rn, buf, length)
     case CCR_REGNUM:
       v = cpu.ccr;
       break;
+    case EXR_REGNUM:
+      v = cpu.exr;
+      break;
     case PC_REGNUM:
       v = cpu.pc;
       break;
@@ -2008,13 +2142,14 @@ sim_info (sd, verbose)
    FLAG is non-zero for the H8/300H.  */
 
 void
-set_h8300h (flag)
-     int flag;
+set_h8300h (h_flag, s_flag)
+     int h_flag, s_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;
+  h8300hmode = h_flag;
+  h8300smode = s_flag;
 }
 
 SIM_DESC
@@ -2069,8 +2204,8 @@ sim_load (sd, prog, abfd, from_tty)
       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);
+         set_h8300h (mach == bfd_mach_h8300h || mach == bfd_mach_h8300s,
+                     mach == bfd_mach_h8300s);
        }
     }
 
@@ -2088,7 +2223,10 @@ sim_load (sd, prog, abfd, from_tty)
      so we just reallocate memory now; this will also allow us to handle
      switching between H8/300 and H8/300H programs without exiting
      gdb.  */
-  if (h8300hmode)
+
+  if (h8300smode)
+    memory_size = H8300S_MSIZE;
+  else if (h8300hmode)
     memory_size = H8300H_MSIZE;
   else
     memory_size = H8300_MSIZE;