avoid using mrs
authornotaz <notasas@gmail.com>
Sun, 8 Sep 2013 23:55:17 +0000 (02:55 +0300)
committernotaz <notasas@gmail.com>
Sun, 8 Sep 2013 23:55:17 +0000 (02:55 +0300)
it's even worse on newer ARMs
only partially converted..

Ea.cpp
OpAny.cpp
OpArith.cpp
OpLogic.cpp
OpMove.cpp
app.h

diff --git a/Ea.cpp b/Ea.cpp
index 234d469..a67f675 100644 (file)
--- a/Ea.cpp
+++ b/Ea.cpp
@@ -305,11 +305,15 @@ int EaCalc(int a,int mask,int ea,int size,int top,int sign_extend)
 // If top is 0 and sign_extend is not, then ARM register v is sign extended,\r
 // e.g. 0xc000 -> 0xffffc000 (else it may or may not be sign extended)\r
 \r
-int EaRead(int a,int v,int ea,int size,int mask,int top,int sign_extend)\r
+int EaRead(int a,int v,int ea,int size,int mask,int top,int sign_extend,int set_nz)\r
 {\r
   char text[32]="";\r
+  const char *s="";\r
+  int flags_set=0;\r
   int shift=0;\r
 \r
+  if (set_nz) s="s";\r
+\r
   shift=32-(8<<size);\r
 \r
   DisaPc=2; DisaGetEa(text,ea,size); // Get text version of the effective address\r
@@ -331,7 +335,8 @@ int EaRead(int a,int v,int ea,int size,int mask,int top,int sign_extend)
     else if (lsl<0) ot("  ldr%s r%d,[r7,r%d,lsr #%i]\n",Narm[nsarm],v,a,-lsl);\r
     else            ot("  ldr%s r%d,[r7,r%d]\n",Sarm[nsarm],v,a);\r
 \r
-    if (top&&shift) ot("  mov r%d,r%d,asl #%d\n",v,v,shift);\r
+    if (top&&shift) ot("  mov%s r%d,r%d,asl #%d\n",s,v,v,shift);\r
+    else if(set_nz) ot("  tst r%d,r%d\n",v,v);\r
 \r
     ot("\n"); return 0;\r
   }\r
@@ -344,8 +349,9 @@ int EaRead(int a,int v,int ea,int size,int mask,int top,int sign_extend)
 \r
     if (top) asl=shift;\r
 \r
-    if (asl) ot("  mov r%d,r%d,asl #%d\n",v,a,asl);\r
-    else if (v!=a) ot("  mov r%d,r%d\n",v,a);\r
+    if (asl)         ot("  mov%s r%d,r%d,asl #%d\n",s,v,a,asl);\r
+    else if (v!=a)   ot("  mov%s r%d,r%d\n",s,v,a);\r
+    else if (set_nz) ot("  tst r%d,r%d\n",v,v);\r
     ot("\n"); return 0;\r
   }\r
 \r
@@ -359,24 +365,35 @@ int EaRead(int a,int v,int ea,int size,int mask,int top,int sign_extend)
   {\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,asl #%d\n",s,v,d_reg,shift);\r
       d_reg=v;\r
+      flags_set=1;\r
     }\r
     if (!top && shift) {\r
-      ot("  mov r%d,r%d,asr #%d\n",v,d_reg,shift);\r
+      ot("  mov%s r%d,r%d,asr #%d\n",s,v,d_reg,shift);\r
       d_reg=v;\r
+      flags_set=1;\r
+    }\r
+    if (d_reg != v) {\r
+      ot("  mov%s r%d,r%d\n",s,v,d_reg);\r
+      flags_set=1;\r
     }\r
-    if (d_reg != v)\r
-      ot("  mov r%d,r%d\n",v,d_reg);\r
   }\r
   else\r
   {\r
-    if (top && shift)\r
-      ot("  mov r%d,r0,asl #%d\n",v,shift);\r
-    else if (v!=0)\r
-      ot("  mov r%d,r0\n",v);\r
+    if (top && shift) {\r
+      ot("  mov%s r%d,r0,asl #%d\n",s,v,shift);\r
+      flags_set=1;\r
+    }\r
+    else if (v!=0) {\r
+      ot("  mov%s r%d,r0\n",s,v);\r
+      flags_set=1;\r
+    }\r
   }\r
 \r
+  if (set_nz&&!flags_set)\r
+    ot("  tst r%d,r%d\n",v,v);\r
+\r
   ot("\n"); return 0;\r
 }\r
 \r
@@ -387,7 +404,7 @@ int EaRead(int a,int v,int ea,int size,int mask,int top,int sign_extend)
 // size values 0, 1, 2 ~ byte, word, long\r
 // r_ea is reg to store ea in (-1 means ea is not needed), r is dst reg\r
 // if sign_extend is 0, non-32bit values will have MS bits undefined\r
-int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend)\r
+int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend,int set_nz)\r
 {\r
   if (ea<0x10)\r
   {\r
@@ -407,7 +424,7 @@ int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend)
   }\r
 \r
   EaCalc (r_ea,mask,ea,size,0,sign_extend);\r
-  EaRead (r_ea,   r,ea,size,mask,0,sign_extend);\r
+  EaRead (r_ea,   r,ea,size,mask,0,sign_extend,set_nz);\r
 \r
   return 0;\r
 }\r
index 63a7e1f..8cb8c09 100644 (file)
--- a/OpAny.cpp
+++ b/OpAny.cpp
@@ -159,6 +159,12 @@ int OpGetFlags(int subtract,int xbit,int specialz)
   return 0;\r
 }\r
 \r
+void OpGetFlagsNZ(int rd)\r
+{\r
+  ot("  and r10,r%d,#0x80000000 ;@ r10=N_flag\n",rd);\r
+  ot("  orreq r10,r10,#0x40000000 ;@ get NZ, clear CV\n");\r
+}\r
+\r
 // -----------------------------------------------------------------\r
 \r
 int g_op;\r
index ca279da..e956831 100644 (file)
@@ -45,19 +45,17 @@ int OpArith(int op)
 \r
   ot(";@ Do arithmetic:\n");\r
 \r
-  if (type==0) ot("  orr r1,r10,r0%s\n",shiftstr);\r
-  if (type==1) ot("  and r1,r10,r0%s\n",shiftstr);\r
+  if (type==0) ot("  orrs r1,r10,r0%s\n",shiftstr);\r
+  if (type==1) ot("  ands r1,r10,r0%s\n",shiftstr);\r
   if (type==2||type==6)\r
                ot("  rsbs r1,r10,r0%s ;@ Defines NZCV\n",shiftstr);\r
   if (type==3) ot("  adds r1,r10,r0%s ;@ Defines NZCV\n",shiftstr);\r
-  if (type==5) ot("  eor r1,r10,r0%s\n",shiftstr);\r
+  if (type==5) ot("  eors r1,r10,r0%s\n",shiftstr);\r
 \r
-  if (type<2 || type==5) ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n"); // 0,1,5\r
-\r
-  if (type< 2) OpGetFlags(0,0); // Ori/And\r
+  if (type< 2) OpGetFlagsNZ(1); // Ori/And\r
   if (type==2) OpGetFlags(1,1); // Sub: Subtract/X-bit\r
   if (type==3) OpGetFlags(0,1); // Add: X-bit\r
-  if (type==5) OpGetFlags(0,0); // Eor\r
+  if (type==5) OpGetFlagsNZ(1); // Eor\r
   if (type==6) OpGetFlags(1,0); // Cmp: Subtract\r
   ot("\n");\r
 \r
@@ -182,9 +180,9 @@ int OpArithReg(int op)
   EaCalcReadNoSE(dir?-1:11,1,rea,size,0x0e00);\r
 \r
   ot(";@ Do arithmetic:\n");\r
-  if (type==0) strop = "orr";\r
+  if (type==0) strop = "orrs";\r
   if (type==1) strop = (char *) (dir ? "subs" : "rsbs");\r
-  if (type==4) strop = "and";\r
+  if (type==4) strop = "ands";\r
   if (type==5) strop = "adds";\r
 \r
   if (size==0) asl=",asl #24";\r
@@ -193,9 +191,8 @@ int OpArithReg(int op)
   if (size<2) ot("  mov r0,r0%s\n",asl);\r
   ot("  %s r1,r0,r1%s\n",strop,asl);\r
 \r
-  if ((type&1)==0) ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
-\r
-  OpGetFlags(type==1,type&1); // 1==subtract\r
+  if (type&1) OpGetFlags(type==1,type&1); // add/subtract\r
+  else        OpGetFlagsNZ(1);\r
   ot("\n");\r
 \r
   ot(";@ Save result:\n");\r
@@ -327,9 +324,8 @@ int OpMul(int op)
       ot("\n");\r
     }\r
 \r
-    ot("  mov r1,r3,lsl #16 ;@ Clip to 16-bits\n");\r
-    ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
-    OpGetFlags(0,0);\r
+    ot("  movs r1,r3,lsl #16 ;@ Clip to 16-bits\n");\r
+    OpGetFlagsNZ(1);\r
 \r
     ot("  mov r1,r1,lsr #16\n");\r
     ot("  orr r1,r1,r2,lsl #16 ;@ Insert remainder\n");\r
@@ -343,9 +339,8 @@ int OpMul(int op)
     ot("  mov r2,r2,%s #16\n",sign?"asr":"lsr");\r
     ot("\n");\r
 \r
-    ot("  mul r1,r2,r0\n");\r
-    ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
-    OpGetFlags(0,0);\r
+    ot("  muls r1,r2,r0\n");\r
+    OpGetFlagsNZ(1);\r
   }\r
   ot("\n");\r
 \r
@@ -716,14 +711,16 @@ int OpCmpEor(int op)
   if (size<2) asl=(char *)(size?",asl #16":",asl #24");\r
 \r
   ot(";@ Do arithmetic:\n");\r
-  if (eor==0) ot("  rsbs r1,r0,r1%s\n",asl);\r
   if (eor)\r
   {\r
-    ot("  eor r1,r0,r1%s\n",asl);\r
-    ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
+    ot("  eors r1,r0,r1%s\n",asl);\r
+    OpGetFlagsNZ(1);\r
+  }\r
+  else\r
+  {\r
+    ot("  rsbs r1,r0,r1%s\n",asl);\r
+    OpGetFlags(1,0); // Cmp like subtract\r
   }\r
-\r
-  OpGetFlags(eor==0,0); // Cmp like subtract\r
   ot("\n");\r
 \r
   if (eor) EaWrite(11, 1,ea,size,0x003f,1);\r
@@ -800,18 +797,18 @@ int OpChk(int op)
   EaCalcReadNoSE(-1,1,rea,size,0x0e00);\r
 \r
   if (size<2) ot("  mov r0,r0,asl #%d\n",size?16:24);\r
-  if (size<2) ot("  mov r1,r1,asl #%d\n\n",size?16:24);\r
+\r
+  if (size<2) ot("  movs r1,r1,asl #%d\n\n",size?16:24);\r
+  else        ot("  adds r1,r1,#0 ;@ Define flags\n");\r
 \r
   ot(";@ get flags, including undocumented ones\n");\r
   ot("  and r3,r10,#0x80000000\n");\r
-  ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
-  OpGetFlags(0,0);\r
+  OpGetFlagsNZ(1);\r
 \r
   ot(";@ is reg negative?\n");\r
   ot("  bmi chktrap%.4x\n",op);\r
 \r
   ot(";@ Do arithmetic:\n");\r
-  ot("  bic r10,r10,#0x80000000 ;@ N\n");\r
   ot("  cmp r1,r0\n");\r
   ot("  bgt chktrap%.4x\n",op);\r
 \r
index 19ec569..4d4312c 100644 (file)
@@ -285,12 +285,11 @@ int OpNeg(int op)
     ot(";@ Not:\n");\r
     if(size!=2) {\r
       ot("  mov r0,r0,asl #%i\n",size?16:24);\r
-      ot("  mvn r1,r0,asr #%i\n",size?16:24);\r
+      ot("  mvns r1,r0,asr #%i\n",size?16:24);\r
     }\r
     else\r
-      ot("  mvn r1,r0\n");\r
-    ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
-    OpGetFlags(0,0);\r
+      ot("  mvns r1,r0\n");\r
+    OpGetFlagsNZ(1);\r
     ot("\n");\r
   }\r
 \r
@@ -318,9 +317,8 @@ int OpSwap(int op)
   EaCalc (11,0x0007,ea,2,1);\r
   EaRead (11,     0,ea,2,0x0007,1);\r
 \r
-  ot("  mov r1,r0,ror #16\n");\r
-  ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
-  OpGetFlags(0,0);\r
+  ot("  movs r1,r0,ror #16\n");\r
+  OpGetFlagsNZ(1);\r
 \r
   EaWrite(11,     1,8,2,0x0007,1);\r
 \r
@@ -347,11 +345,10 @@ int OpTst(int op)
 \r
   OpStart(op,sea); Cycles=4;\r
 \r
-  EaCalc ( 0,0x003f,sea,size,1);\r
-  EaRead ( 0,     0,sea,size,0x003f,1);\r
+  EaCalc (0,0x003f,sea,size,1);\r
+  EaRead (0,     0,sea,size,0x003f,1,0,1);\r
 \r
-  ot("  adds r0,r0,#0 ;@ Defines NZ, clears CV\n");\r
-  ot("  mrs r10,cpsr ;@ r10=flags\n");\r
+  OpGetFlagsNZ(0);\r
   ot("\n");\r
 \r
   OpEnd(sea);\r
@@ -378,9 +375,8 @@ int OpExt(int op)
   EaCalc (11,0x0007,ea,size+1,0,0);\r
   EaRead (11,     0,ea,size+1,0x0007,0,0);\r
 \r
-  ot("  mov r0,r0,asl #%d\n",shift);\r
-  ot("  adds r0,r0,#0 ;@ Defines NZ, clears CV\n");\r
-  ot("  mrs r10,cpsr ;@ r10=flags\n");\r
+  ot("  movs r0,r0,asl #%d\n",shift);\r
+  OpGetFlagsNZ(0);\r
   ot("  mov r1,r0,asr #%d\n",shift);\r
   ot("\n");\r
 \r
@@ -596,8 +592,8 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
       ot("  b nozerox%.4x\n",op);\r
       ot("norotx_%.4x%s\n",op,ms?"":":");\r
       ot("  ldr r2,[r7,#0x4c]\n");\r
-      ot("  adds r0,r0,#0 ;@ Defines NZ, clears CV\n");\r
-      OpGetFlags(0,0);\r
+      ot("  adds r0,r0,#0 ;@ Define flags\n");\r
+      OpGetFlagsNZ(0);\r
       ot("  and r2,r2,#0x20000000\n");\r
       ot("  orr r10,r10,r2 ;@ C = old_X\n");\r
       ot("nozerox%.4x%s\n",op,ms?"":":");\r
@@ -746,10 +742,9 @@ int OpTas(int op, int gen_special)
   if(ea>=8) Cycles+=10;\r
 \r
   EaCalc (11,0x003f,ea,0,1);\r
-  EaRead (11,     1,ea,0,0x003f,1);\r
+  EaRead (11,     1,ea,0,0x003f,1,0,1);\r
 \r
-  ot("  adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
-  OpGetFlags(0,0);\r
+  OpGetFlagsNZ(1);\r
   ot("\n");\r
 \r
 #if CYCLONE_FOR_GENESIS\r
index 1e24566..82c589c 100644 (file)
@@ -133,9 +133,8 @@ int OpMove(int op)
 \r
   if (movea==0)\r
   {\r
-    EaCalcRead(-1,0,sea,size,0x003f);\r
-    ot("  adds r1,r0,#0 ;@ Defines NZ, clears CV\n");\r
-    ot("  mrs r10,cpsr ;@ r10=NZCV flags\n");\r
+    EaCalcRead(-1,1,sea,size,0x003f,1,1);\r
+    OpGetFlagsNZ(1);\r
     ot("\n");\r
   }\r
   else\r
@@ -530,7 +529,7 @@ int OpMoveq(int op)
   ot("  movs r0,r8,asl #24\n");\r
   ot("  and r1,r8,#0x0e00\n");\r
   ot("  mov r0,r0,asr #24 ;@ Sign extended Quick value\n");\r
-  ot("  mrs r10,cpsr ;@ r10=NZ flags\n");\r
+  OpGetFlagsNZ(0);\r
   ot("  str r0,[r7,r1,lsr #7] ;@ Store into Dn\n");\r
   ot("\n");\r
 \r
diff --git a/app.h b/app.h
index 4a23630..f041dff 100644 (file)
--- a/app.h
+++ b/app.h
@@ -33,8 +33,8 @@ extern int g_pea_cycle_table[];
 extern int g_movem_cycle_table[];\r
 int Ea_add_ns(int *tab, int ea); // add nonstandard EA cycles\r
 int EaCalc(int a,int mask,int ea,int size,int top=0,int sign_extend=1); // 6\r
-int EaRead(int a,int v,int ea,int size,int mask,int top=0,int sign_extend=1); // 7\r
-int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend=1); // 6\r
+int EaRead(int a,int v,int ea,int size,int mask,int top=0,int sign_extend=1,int set_nz=0); // 8\r
+int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend=1,int set_nz=0); // 7\r
 int EaCalcReadNoSE(int r_ea,int r,int ea,int size,int mask);\r
 int EaCanRead(int ea,int size);\r
 int EaWrite(int a,int v,int ea,int size,int mask,int top=0,int sign_extend_ea=1);\r
@@ -58,6 +58,7 @@ void FlushPC(void);
 extern int g_op;\r
 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 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