support a few ARMv6 instructions
authornotaz <notasas@gmail.com>
Sun, 5 Oct 2014 23:49:56 +0000 (02:49 +0300)
committernotaz <notasas@gmail.com>
Sun, 5 Oct 2014 23:49:56 +0000 (02:49 +0300)
Ea.cpp
Makefile
OpAny.cpp
app.h
config.h

diff --git a/Ea.cpp b/Ea.cpp
index fc4dff9..5969529 100644 (file)
--- a/Ea.cpp
+++ b/Ea.cpp
@@ -372,8 +372,7 @@ int EaRead(int a,int v,int ea,int size,int mask,EaRWType type,int set_nz)
   {\r
     int d_reg=0;\r
     if (shift) {\r
-      ot("  mov r%d,r%d,asl #%d\n",v,d_reg,shift);\r
-      ot("  mov%s r%d,r%d,asr #%d\n",s,v,v,shift);\r
+      SignExtend(v, d_reg, size);\r
       d_reg=v;\r
       flags_set=1;\r
     }\r
@@ -498,8 +497,7 @@ int EaWrite(int a,int v,int ea,int size,int mask,EaRWType type)
     case 1:\r
       if (type != earwt_zero_extend)\r
       {\r
-        ot("  mov r1,r%d,lsl #16\n",v);\r
-        ot("  mov r1,r1,lsr #16\n");\r
+        ZeroExtend(1, v, size);\r
         break;\r
       }\r
       // fallthrough\r
index 8b7a5fd..98a578a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,9 @@ CFLAGS += -Wall -ggdb
 ifdef CONFIG_FILE
 CFLAGS += -DCONFIG_FILE="\"$(CONFIG_FILE)\""
 endif
+ifdef HAVE_ARMv6
+CFLAGS += -DHAVE_ARMv6=$(HAVE_ARMv6)
+endif
 CXXFLAGS += $(CFLAGS)
 
 OBJS = Main.o Ea.o OpAny.o OpArith.o OpBranch.o OpLogic.o OpMove.o Disa/Disa.o
index 8cb8c09..64e2bfe 100644 (file)
--- a/OpAny.cpp
+++ b/OpAny.cpp
@@ -165,6 +165,52 @@ void OpGetFlagsNZ(int rd)
   ot("  orreq r10,r10,#0x40000000 ;@ get NZ, clear CV\n");\r
 }\r
 \r
+// size 0=8bit, 1=16bit\r
+void SignExtend(int rd, int rs, int size)\r
+{\r
+  if (size >= 2)\r
+  {\r
+    if (rd != rs)\r
+      ot("  mov r%d,r%d\n", rd, rs);\r
+    return;\r
+  }\r
+#if defined(HAVE_ARMv6) && (HAVE_ARMv6)\r
+  if (size == 1)\r
+    ot("  sxth r%d,r%d ;@ sign extend\n", rd, rs);\r
+  else\r
+    ot("  sxtb r%d,r%d ;@ sign extend\n", rd, rs);\r
+#else\r
+  int shift = size ? 16 : 24;\r
+  ot("  mov r%d,r%d,asl #%d\n", rd, rs, shift);\r
+  ot("  mov r%d,r%d,asr #%d ;@ sign extend\n", rd, rd, shift);\r
+#endif\r
+}\r
+\r
+void ZeroExtend(int rd, int rs, int size)\r
+{\r
+  if (size >= 2)\r
+  {\r
+    if (rd != rs)\r
+      ot("  mov r%d,r%d\n", rd, rs);\r
+    return;\r
+  }\r
+#if defined(HAVE_ARMv6) && (HAVE_ARMv6)\r
+  if (size == 1)\r
+    ot("  uxth r%d,r%d ;@ zero extend\n", rd, rs);\r
+  else\r
+#else\r
+  if (size == 1)\r
+  {\r
+    ot("  mov r%d,r%d,lsl #16\n", rd, rs);\r
+    ot("  mov r%d,r%d,lsr #16 ;@ zero extend\n", rd, rd);\r
+  }\r
+  else\r
+#endif\r
+  {\r
+    ot("  and r%d,r%d,#0xff ;@ zero extend\n", rd, rs);\r
+  }\r
+}\r
+\r
 // -----------------------------------------------------------------\r
 \r
 int g_op;\r
diff --git a/app.h b/app.h
index cffd2cb..9d01957 100644 (file)
--- a/app.h
+++ b/app.h
@@ -65,6 +65,8 @@ extern int g_op;
 extern int opend_op_changes_cycles, opend_check_interrupt, opend_check_trace;\r
 int OpGetFlags(int subtract,int xbit,int sprecialz=0);\r
 void OpGetFlagsNZ(int rd);\r
+void SignExtend(int rd, int rs, int size);\r
+void ZeroExtend(int rd, int rs, int size);\r
 void OpUse(int op,int use);\r
 void OpStart(int op,int sea=0,int tea=0,int op_changes_cycles=0,int supervisor_check=0);\r
 void OpEnd(int sea=0,int tea=0);\r
index d73b5b5..86bd6e0 100644 (file)
--- a/config.h
+++ b/config.h
@@ -5,6 +5,16 @@
 **/\r
 \r
 \r
+/*\r
+ * By default, only ARMv4 instructions are used.\r
+ * If you want Cyclone to make use of newer ARM instructions, enable the\r
+ * options(s) below. You can also override this using make argument:\r
+ *   make HAVE_ARMv6=1\r
+ */\r
+#ifndef HAVE_ARMv6\r
+#define HAVE_ARMv6                  0\r
+#endif\r
+\r
 /*\r
  * If this option is enabled, Microsoft ARMASM compatible output is generated\r
  * (output file -  Cyclone.asm). Otherwise GNU as syntax is used (Cyclone.s).\r