* interp.c (hash): Update to be more accurate.
authorJeff Law <law@redhat.com>
Thu, 29 Aug 1996 23:39:23 +0000 (23:39 +0000)
committerJeff Law <law@redhat.com>
Thu, 29 Aug 1996 23:39:23 +0000 (23:39 +0000)
        (lookup_hash): Call hash rather than computing the hash
        code here.
        (do_format_1_2): Handle format 1 and format 2 instructions.
        Get operands correctly and call the target function.
        (do_format_6): Get operands correctly and call the target
        function.
        (do_formats_9_10): Rough cut so shift ops will work.
        (sim_resume): Tweak to deal with format 1 and format 2
        handling in a single funtion.  Don't update the PC
        for format 3 insns.  Fix typos.
        * simops.c: Slightly reorganize.  Add condition code handling
        to "add", "addi", "and", "andi", "or", "ori", "xor", "xori"
        and "not" instructions.
        * v850_sim.h (reg_t): Registers are 32bits.
        (_state): The V850 has 32 general registers.  Add a 32bit
        psw and pc register too.  Add accessor macros
Fixing lots of stuff.  Starting to add condition code support.  Basically
check pointing the work to date.

sim/v850/ChangeLog
sim/v850/Makefile.in
sim/v850/interp.c
sim/v850/simops.c
sim/v850/v850_sim.h

index af16356..33a26c5 100644 (file)
@@ -1,5 +1,26 @@
 Thu Aug 29 13:53:29 1996  Jeffrey A Law  (law@cygnus.com)
 
+       * interp.c (hash): Update to be more accurate.
+       (lookup_hash): Call hash rather than computing the hash
+       code here.
+       (do_format_1_2): Handle format 1 and format 2 instructions.
+       Get operands correctly and call the target function.
+       (do_format_6): Get operands correctly and call the target
+       function.
+       (do_formats_9_10): Rough cut so shift ops will work.
+       (sim_resume): Tweak to deal with format 1 and format 2
+       handling in a single funtion.  Don't update the PC
+       for format 3 insns.  Fix typos.
+       * simops.c: Slightly reorganize.  Add condition code handling
+       to "add", "addi", "and", "andi", "or", "ori", "xor", "xori"
+       and "not" instructions.
+       * v850_sim.h (reg_t): Registers are 32bits.
+       (_state): The V850 has 32 general registers.  Add a 32bit
+       psw and pc register too.  Add accessor macros
+
+       * Makefile.in, interp.c, v850_sim.h: Bring over endianness
+       changes from the d10v simulator.
+
        * simops.c: Add shift support.
 
        * simops.c: Add multiply & divide support.  Abort for system
index 0e50939..935e4aa 100644 (file)
@@ -56,7 +56,7 @@ INSTALL_XFORM1= $(INSTALL_XFORM) -b=.1
 AR = @AR@
 AR_FLAGS = rc
 CC = @CC@
-CFLAGS = @CFLAGS@
+CFLAGS = @CFLAGS@ @DEFS@
 MAKEINFO = makeinfo
 RANLIB = @RANLIB@
 CC_FOR_BUILD = @CC_FOR_BUILD@
index 0e9d102..bcbb982 100644 (file)
@@ -28,12 +28,28 @@ static long
 hash(insn)
      long insn;
 {
-  /* XXX This isn't right for 32bit opcodes, hell it isn't even
-     right for 16bit opcodes!  */
-  if (insn & 0x0600)
-    return ((insn & 0x3F000000) >> 24);
-  else
-    return((insn & 0x07E0) >> 5);
+  if ((insn & 0x30) == 0
+      || (insn & 0x38) == 0x10)
+    return (insn & 0x07e0) >> 5;
+  if ((insn & 0x3c) == 0x18
+      || (insn & 0x3c) == 0x1c
+      || (insn & 0x3c) == 0x20
+      || (insn & 0x3c) == 0x24
+      || (insn & 0x3c) == 0x28
+      || (insn & 0x3c) == 0x23)
+    return (insn & 0x07c0) >> 6;
+  if ((insn & 0x38) == 0x30)
+    return (insn & 0x07e0) >> 5;
+  /* What about sub-op field? XXX */
+  if ((insn & 0x38) == 0x38)
+    return (insn & 0x07e0) >> 5;
+  if ((insn & 0x3e) == 0x3c)
+    return (insn & 0x07c0) >> 6;
+  if ((insn & 0x3f) == 0x3e)
+    return (insn & 0xc7e0) >> 5;
+  /* Not really correct.  XXX */
+  return insn & 0xffffffff;
+  
 }
 
 static struct hash_entry *
@@ -42,10 +58,7 @@ lookup_hash (ins)
 {
   struct hash_entry *h;
 
-  if (ins & 0x0f00)
-    h = &hash_table[(ins & 0x3F000000) >> 24];
-  else
-    h = &hash_table[(ins & 0x07E0) >> 5];
+  h = &hash_table[hash(ins)];
 
   while ( (ins & h->mask) != h->opcode)
     {
@@ -60,56 +73,108 @@ lookup_hash (ins)
 }
 
 uint32
-get_longword_swap (x)
-      uint16 x;
+get_longword (x)
+      uint8 *x;
 {
-  uint8 *a = (uint8 *)(x + State.imem);
-  return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + (a[3]);
+  uint8 *a = x;
+  return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
+}
+
+int64
+get_longlong (x)
+      uint8 *x;
+{
+  uint8 *a = x;
+  return ((int64)a[0]<<56) + ((int64)a[1]<<48) + ((int64)a[2]<<40) + ((int64)a[3]<<32) +
+    ((int64)a[4]<< 24) + ((int64)a[5]<<16) + ((int64)a[6]<<8) + (int64)a[7];
 }
 
 uint16
-get_word_swap (x)
-      uint16 x;
+get_word (x)
+      uint8 *x;
 {
-  uint8 *a = (uint8 *)(x + State.imem);
-  return (a[0]<<8) + a[1];
+  uint8 *a = x;
+  return ((uint16)a[0]<<8) + a[1];
 }
 
+
 void
-write_word_swap (addr, data)
-     uint16 addr, data;
+write_word (addr, data)
+     uint8 *addr;
+     uint16 data;
 {
-  uint8 *a = (uint8 *)(addr + State.imem);
+  uint8 *a = addr;
   a[0] = data >> 8;
   a[1] = data & 0xff;
 }
 
+void
+write_longword (addr, data)
+     uint8 *addr;
+     uint32 data;
+{
+  addr[0] = (data >> 24) & 0xff;
+  addr[1] = (data >> 16) & 0xff;
+  addr[2] = (data >> 8) & 0xff;
+  addr[3] = data & 0xff;
+}
+
+void
+write_longlong (addr, data)
+     uint8 *addr;
+     int64 data;
+{
+  uint8 *a = addr;
+  a[0] = data >> 56;
+  a[1] = (data >> 48) & 0xff;
+  a[2] = (data >> 40) & 0xff;
+  a[3] = (data >> 32) & 0xff;
+  a[4] = (data >> 24) & 0xff;
+  a[5] = (data >> 16) & 0xff;
+  a[6] = (data >> 8) & 0xff;
+  a[7] = data & 0xff;
+}
+
 static void
-do_format_1 (insn)
-     uint32 insn;
+get_operands (struct simops *s, uint32 ins)
 {
-  printf("format 1 0x%x\n", insn >> 16);
+  int i, shift, bits, flags;
+  uint32 mask;
+  for (i=0; i < s->numops; i++)
+    {
+      shift = s->operands[3*i];
+      bits = s->operands[3*i+1];
+      flags = s->operands[3*i+2];
+      mask = 0x7FFFFFFF >> (31 - bits);
+      OP[i] = (ins >> shift) & mask;
+    }
 }
 
 static void
-do_format_2 (insn)
+do_format_1_2 (insn)
      uint32 insn;
 {
-  printf("format 2 0x%x\n", insn >> 16);
+  struct hash_entry *h;
+  printf("format 1 or 2 0x%x\n", insn);
+
+  h = lookup_hash (insn);
+  OP[0] = insn & 0x1f;
+  OP[1] = (insn >> 11) & 0x1f;
+  (h->ops->func) ();
 }
 
 static void
 do_format_3 (insn)
      uint32 insn;
 {
-  printf("format 3 0x%x\n", insn >> 16);
+  printf("format 3 0x%x\n", insn);
 }
 
 static void
 do_format_4 (insn)
      uint32 insn;
 {
-  printf("format 4 0x%x\n", insn >> 16);
+  printf("format 4 0x%x\n", insn);
 }
 
 static void
@@ -123,7 +188,14 @@ static void
 do_format_6 (insn)
      uint32 insn;
 {
+  struct hash_entry *h;
   printf("format 6 0x%x\n", insn);
+
+  h = lookup_hash (insn);
+  OP[0] = (insn >> 16) & 0xffff;
+  OP[1] = insn & 0x1f;
+  OP[2] = (insn >> 11) & 0x1f;
+  (h->ops->func) ();
 }
 
 static void
@@ -144,7 +216,13 @@ static void
 do_formats_9_10 (insn)
      uint32 insn;
 {
+  struct hash_entry *h;
   printf("formats 9 and 10 0x%x\n", insn);
+
+  h = lookup_hash (insn);
+  OP[0] = insn & 0x1f;
+  OP[1] = (insn >> 11) & 0x1f;
+  (h->ops->func) ();
 }
 
 void
@@ -263,15 +341,11 @@ sim_resume (step, siggnal)
    {
      inst = RLW (PC);
      oldpc = PC;
-     opcode = (inst & 0x07e00000) >> 21;
-     if ((opcode & 0x30) == 0)
-       {
-        do_format_1 (inst >> 16);
-        PC += 2;
-       }
-     else if ((opcode & 0x38) == 0x10)
+     opcode = (inst & 0x07e0) >> 5;
+     if ((opcode & 0x30) == 0
+        || (opcode & 0x38) == 0x10)
        {
-        do_format_2 (inst >> 16);
+        do_format_1_2 (inst & 0xffff);
         PC += 2;
        }
      else if ((opcode & 0x3C) == 0x18
@@ -280,13 +354,13 @@ sim_resume (step, siggnal)
              || (opcode & 0x3C) == 0x24
              || (opcode & 0x3C) == 0x28)
        {
-        do_format_4 (inst >> 16);
+        do_format_4 (inst & 0xffff);
         PC += 2;
        }
-     else if ((opcode& 0x3C) == 0x23)
+     else if ((opcode & 0x3C) == 0x23)
        {
-        do_format_3 (inst >> 16);
-        PC += 2;
+        do_format_3 (inst & 0xffff);
+        /* No PC update, it's done in the instruction.  */
        }
      else if ((opcode & 0x38) == 0x30)
        {
@@ -303,7 +377,7 @@ sim_resume (step, siggnal)
         do_format_5 (inst);
         PC += 4;
        }
-     else if ((opcode & 0x3E) == 0x3C)
+     else if ((opcode & 0x3F) == 0x3E)
        {
         do_format_8 (inst);
         PC += 4;
index 8ec7871..1a36dc1 100644 (file)
@@ -123,39 +123,85 @@ OP_660 ()
 }
 
 
-/* add reg, reg
-
-   XXX condition codes.  */
+/* add reg, reg */
 void
 OP_1C0 ()
 {
-  State.regs[OP[1]] += State.regs[OP[0]];
-}
+  unsigned int op0, op1, result, z, s, cy, ov;
 
-/* add sign_extend(imm5), reg
+  /* Compute the result.  */
+  op0 = State.regs[OP[0]];
+  op1 = State.regs[OP[1]];
+  result = op0 + op1;
 
-   XXX condition codes.  */
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+  cy = (result < op0 || result < op1);
+  ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
+       && (op0 & 0x80000000) != (result & 0x80000000));
+
+  /* Store the result and condition codes.  */
+  State.regs[OP[1]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+               | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
+}
+
+/* add sign_extend(imm5), reg */
 void
 OP_240 ()
 {
-  int value = OP[0];
-  value = (value << 27) >> 27;
+  unsigned int op0, op1, result, z, s, cy, ov;
+  int temp;
 
-  State.regs[OP[1]] += value;
-}
+  /* Compute the result.  */
+  temp = (OP[0] & 0x1f);
+  temp = (temp << 27) >> 27;
+  op0 = temp;
+  op1 = State.regs[OP[1]];
+  result = op0 + op1;
+  
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+  cy = (result < op0 || result < op1);
+  ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
+       && (op0 & 0x80000000) != (result & 0x80000000));
 
-/* addi sign_extend(imm16), reg, reg
+  /* Store the result and condition codes.  */
+  State.regs[OP[1]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+               | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
+}
 
-   XXX condition codes.  */
+/* addi sign_extend(imm16), reg, reg */
 void
 OP_600 ()
 {
-  int value = OP[0];
-  value = (value << 16) >> 16;
-
-  State.regs[OP[2]] = State.regs[OP[1]] + value;
+  unsigned int op0, op1, result, z, s, cy, ov;
+  int temp;
+
+  /* Compute the result.  */
+  temp = (OP[0] & 0xffff);
+  temp = (temp << 16) >> 16;
+  op0 = temp;
+  op1 = State.regs[OP[1]];
+  result = op0 + op1;
+  
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+  cy = (result < op0 || result < op1);
+  ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
+       && (op0 & 0x80000000) != (result & 0x80000000));
+
+  /* Store the result and condition codes.  */
+  State.regs[OP[2]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+               | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
 }
 
 /* sub reg1, reg2
@@ -327,15 +373,6 @@ OP_80 ()
 {
 }
 
-/* not reg1, reg2
-
-   XXX condition codes */
-void
-OP_20 ()
-{
-  State.regs[OP[1]] = ~State.regs[OP[0]];
-}
-
 /* sar zero_extend(imm5),reg1
 
    XXX condition codes.  */
@@ -413,70 +450,148 @@ OP_7E0 ()
 {
 }
 
-/* or reg, reg
-
-   XXX condition codes.  */
+/* or reg, reg */
 void
 OP_100 ()
 {
-  State.regs[OP[1]] |= State.regs[OP[0]];
-}
+  unsigned int op0, op1, result, z, s, cy, ov;
 
-/* ori zero_extend(imm16), reg, reg
+  /* Compute the result.  */
+  op0 = State.regs[OP[0]];
+  op1 = State.regs[OP[1]];
+  result = op0 | op1;
 
-   XXX condition codes */
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+
+  /* Store the result and condition codes.  */
+  State.regs[OP[1]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
+}
+
+/* ori zero_extend(imm16), reg, reg */
 void
 OP_680 ()
 {
-  int value = OP[0];
-  value &= 0xffff;
+  unsigned int op0, op1, result, z, s, cy, ov;
 
-  State.regs[OP[2]] = State.regs[OP[1]] | value;
-}
+  op0 = OP[0] & 0xffff;
+  op1 = State.regs[OP[1]];
+  result = op0 | op1;
 
-/* and reg, reg
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
 
-   XXX condition codes.  */
+  /* Store the result and condition codes.  */
+  State.regs[OP[2]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
+  State.psw |= (z ? PSW_Z : 0);
+}
+
+/* and reg, reg */
 void
 OP_140 ()
 {
-  State.regs[OP[1]] &= State.regs[OP[0]];
-}
+  unsigned int op0, op1, result, z, s, cy, ov;
 
-/* andi zero_extend(imm16), reg, reg
+  /* Compute the result.  */
+  op0 = State.regs[OP[0]];
+  op1 = State.regs[OP[1]];
+  result = op0 & op1;
 
-   XXX condition codes.  */
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+
+  /* Store the result and condition codes.  */
+  State.regs[OP[1]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
+}
+
+/* andi zero_extend(imm16), reg, reg */
 void
 OP_6C0 ()
 {
-  int value = OP[0];
-  value &= 0xffff;
+  unsigned int op0, op1, result, z, s, cy, ov;
 
-  State.regs[OP[2]] = State.regs[OP[1]] & value;
-}
+  op0 = OP[0] & 0xffff;
+  op1 = State.regs[OP[1]];
+  result = op0 & op1;
 
-/* xor reg, reg
+  /* Compute the condition codes.  */
+  z = (result == 0);
 
-   XXX condition codes.  */
+  /* Store the result and condition codes.  */
+  State.regs[OP[2]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
+  State.psw |= (z ? PSW_Z : 0);
+}
+
+/* xor reg, reg */
 void
 OP_120 ()
 {
-  State.regs[OP[1]] ^= State.regs[OP[0]];
-}
+  unsigned int op0, op1, result, z, s, cy, ov;
 
-/* xori zero_extend(imm16), reg, reg
+  /* Compute the result.  */
+  op0 = State.regs[OP[0]];
+  op1 = State.regs[OP[1]];
+  result = op0 ^ op1;
 
-   XXX condition codes.  */
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+
+  /* Store the result and condition codes.  */
+  State.regs[OP[1]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
+}
+
+/* xori zero_extend(imm16), reg, reg */
 void
 OP_6A0 ()
 {
-  int value = OP[0];
-  value &= 0xffff;
+  unsigned int op0, op1, result, z, s, cy, ov;
+
+  op0 = OP[0] & 0xffff;
+  op1 = State.regs[OP[1]];
+  result = op0 ^ op1;
+
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+
+  /* Store the result and condition codes.  */
+  State.regs[OP[2]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
+  State.psw |= (z ? PSW_Z : 0);
+}
+
+/* not reg1, reg2 */
+void
+OP_20 ()
+{
+  unsigned int op0, result, z, s, cy, ov;
+
+  /* Compute the result.  */
+  op0 = State.regs[OP[0]];
+  result = ~op0;
+
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
 
-  State.regs[OP[2]] = State.regs[OP[1]] ^ value;
+  /* Store the result and condition codes.  */
+  State.regs[OP[1]] = result;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
+  State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
 }
 
 void
index a840da1..b7402ae 100644 (file)
@@ -13,7 +13,7 @@ typedef signed int int32;
 typedef signed long long int64;
 
 /* FIXME: V850 defines */
-typedef uint16 reg_t;
+typedef uint32 reg_t;
 
 struct simops 
 {
@@ -26,21 +26,9 @@ struct simops
 
 struct _state
 {
-  reg_t regs[16];              /* general-purpose registers */
-  reg_t cregs[16];     /* control registers */
-  int64 a[2];  /* accumulators */
-  uint8 SM;
-  uint8 EA;
-  uint8 DB;
-  uint8 IE;
-  uint8 RP;
-  uint8 MD;
-  uint8 FX;
-  uint8 ST;
-  uint8 F0;
-  uint8 F1;
-  uint8 C;
-  uint8 exe;
+  reg_t regs[32];              /* general-purpose registers */
+  reg_t pc;
+  reg_t psw;
   uint8 *imem;
   uint8 *dmem;
   int   exception;
@@ -49,16 +37,17 @@ struct _state
 extern uint16 OP[4];
 extern struct simops Simops[];
 
-#define PC     (State.cregs[2])
-#define PSW    (State.cregs[0])
-#define BPSW   (State.cregs[1])
-#define BPC    (State.cregs[3])
-#define RPT_C  (State.cregs[7])
-#define RPT_S  (State.cregs[8])
-#define RPT_E  (State.cregs[9])
-#define MOD_S  (State.cregs[10])
-#define MOD_E  (State.cregs[11])
-#define IBA    (State.cregs[14])
+#define PC     (State.pc)
+#define PSW    (State.psw)
+
+#define PSW_NP 0x80
+#define PSW_EP 0x40
+#define PSW_ID 0x20
+#define PSW_SAT 0x10
+#define PSW_CY 0x8
+#define PSW_OV 0x4
+#define PSW_S 0x2
+#define PSW_Z 0x1
 
 #define SEXT3(x)       ((((x)&0x7)^(~3))+4)    
 
@@ -95,17 +84,28 @@ extern struct simops Simops[];
 
 #ifdef WORDS_BIGENDIAN
 
-#define RW(x)  (*((uint16 *)((x)+State.imem)))
-#define RLW(x) (*((uint32 *)((x)+State.imem)))
-#define SW(addr,data)  RW(addr)=data
+#define RW(x)                  (*((uint16 *)((x)+State.imem)))
+#define RLW(x)                 (*((uint32 *)((x)+State.imem)))
+#define SW(addr,data)          RW(addr)=data
+#define READ_16(x)             (*((int16 *)(x)))
+#define WRITE_16(addr,data)    (*(int16 *)(addr)=data) 
+#define READ_64(x)             (*((int64 *)(x)))
+#define WRITE_64(addr,data)    (*(int64 *)(addr)=data) 
 
 #else
 
-uint32 get_longword_swap PARAMS ((uint16 x));
-uint16 get_word_swap PARAMS ((uint16 x));
-void write_word_swap PARAMS ((uint16 addr, uint16 data));
-#define SW(addr,data)  write_word_swap(addr,data)
-#define RW(x)  get_word_swap(x)
-#define RLW(x) get_longword_swap(x)
+uint32 get_longword PARAMS ((uint8 *));
+uint16 get_word PARAMS ((uint8 *));
+int64 get_longlong PARAMS ((uint8 *));
+void write_word PARAMS ((uint8 *addr, uint16 data));
+void write_longlong PARAMS ((uint8 *addr, int64 data));
+
+#define SW(addr,data)          write_word((long)(addr)+State.imem,data)
+#define RW(x)                  get_word((long)(x)+State.imem)
+#define RLW(x)                 get_longword((long)(x)+State.imem)
+#define READ_16(x)             get_word(x)
+#define WRITE_16(addr,data)    write_word(addr,data)
+#define READ_64(x)             get_longlong(x)
+#define WRITE_64(addr,data)    write_longlong(addr,data)
 
 #endif /* not WORDS_BIGENDIAN */