created by configure
[fw/sdcc] / sim / ucsim / xa.src / inst.cc
index 1efe594caef32f84459acd439af2e040f2d88e95..c9f7d088558f0b2c9aa4c8555d20ea1ee8a31a84 100644 (file)
@@ -30,6 +30,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "ddconfig.h"
 
+#include <stdlib.h>
+
 // local
 #include "glob.h"
 #include "xacl.h"
@@ -224,6 +226,10 @@ int cl_xa::inst_ASL(uint code, int operands)
           if ((dst & 0xffff) == 0)
             flags |= BIT_Z;
         break;
+        case 2: // ?
+          // not really sure about the encoding here..
+          NOTDONE_ASSERT;
+        break;
         case 3:  // dword
           //dst = reg4(RI_F0);
           dst = reg2(RI_F0) | (reg2(RI_F0 + 2) << 16);
@@ -262,6 +268,10 @@ int cl_xa::inst_ASL(uint code, int operands)
           if ((dst & 0xffff) == 0)
             flags |= BIT_Z;
         break;
+        case 2: // ?
+          // not really sure about the encoding here..
+          NOTDONE_ASSERT;
+        break;
         case 3:  // dword
           dst = reg1(RI_F0 & 0xe);
           cnt = operands & 0x1f;
@@ -282,9 +292,105 @@ int cl_xa::inst_ASL(uint code, int operands)
   return(resGO);
 }
 
+/* arithmetic shift right */
 int cl_xa::inst_ASR(uint code, int operands)
 {
-  NOTDONE_ASSERT;
+  unsigned int dst, cnt;
+  unsigned char flags;
+
+  /* ASR, dest, count
+    while (count != 0)
+      C = dest.0; dest >>= 1;
+      this is a confusing one...
+  */
+
+  flags = get_psw();
+  flags &= ~BIT_ALL; /* clear these bits */
+
+  switch(operands) {
+    case REG_REG :
+      cnt = reg1(RI_0F) & 0x1f;
+      switch (code & 0xc00) {
+        case 0: // byte
+          dst = reg1(RI_F0);
+          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+            flags |= BIT_C;
+          if (dst & 0x01)
+            flags |= BIT_C;
+          dst >>= cnt;
+          set_reg1(RI_F0,dst);
+          if ((dst & 0xff) == 0)
+            flags |= BIT_Z;
+        break;
+        case 1: // word
+          dst = reg2(RI_F0);
+          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+            flags |= BIT_C;
+          dst >>= cnt;
+          set_reg2(RI_F0,dst);
+          if ((dst & 0xffff) == 0)
+            flags |= BIT_Z;
+        break;
+        case 2: // ?
+          // not really sure about the encoding here..
+          NOTDONE_ASSERT;
+        break;
+        case 3:  // dword
+          dst = reg2(RI_F0) | (reg2(RI_F0 + 2) << 16);
+          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+            flags |= BIT_C;
+          dst >>= cnt;
+          set_reg2(RI_F0,dst & 0xffff);
+          set_reg2(RI_F0+2, (dst>>16) & 0xffff);
+          if (dst == 0)
+            flags |= BIT_Z;
+        break;
+      }
+    break;
+
+    case REG_DATA4 :
+    case REG_DATA5 :
+      switch (code & 0xc00) {
+        case 0: // byte
+          dst = reg1(RI_F0);
+          cnt = operands & 0x0f;
+          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+            flags |= BIT_C;
+          dst >>= cnt;
+          set_reg1(RI_F0,dst);
+          if ((dst & 0xff) == 0)
+            flags |= BIT_Z;
+        break;
+        case 1: // word
+          dst = reg2(RI_F0);
+          cnt = operands & 0x0f;
+          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+            flags |= BIT_C;
+          dst >>= cnt;
+          set_reg2(RI_F0,dst);
+          if ((dst & 0xffff) == 0)
+            flags |= BIT_Z;
+        break;
+        case 2: // ?
+          // not really sure about the encoding here..
+          NOTDONE_ASSERT;
+        break;
+        case 3:  // dword
+          dst = reg1(RI_F0 & 0xe);
+          cnt = operands & 0x1f;
+          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+            flags |= BIT_C;
+          dst >>= cnt;
+          set_reg2(RI_F0,dst & 0xffff);
+          set_reg2(RI_F0+2, (dst>>16) & 0xffff);
+          if (dst == 0)
+            flags |= BIT_Z;
+        break;
+      }
+    break;
+  }
+  set_psw(flags);
+
   return(resGO);
 }
 
@@ -791,7 +897,6 @@ int cl_xa::inst_NEG(uint code, int operands)
 }
 int cl_xa::inst_NOP(uint code, int operands)
 {
-  NOTDONE_ASSERT;
   return(resGO);
 }
 int cl_xa::inst_NORM(uint code, int operands)