some more optimizations
[picodrive.git] / cpu / Cyclone / OpBranch.cpp
index 31e82fc..f8eb584 100644 (file)
@@ -287,50 +287,60 @@ int OpDbra(int op)
   if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
   OpStart(op);\r
 \r
-  if (cc>=2)\r
+  switch (cc)\r
   {\r
-    ot(";@ Is the condition true?\n");\r
-    if ((cc&~1)==2) ot("  eor r9,r9,#0x20000000 ;@ Invert carry for hi/ls\n");\r
-    ot("  msr cpsr_flg,r9 ;@ ARM flags = 68000 flags\n");\r
-    if ((cc&~1)==2) ot("  eor r9,r9,#0x20000000\n");\r
-    ot(";@ If so, don't dbra\n");\r
-    ot("  b%s DbraTrue%.4x\n",Cond[cc],op);\r
-    ot("\n");\r
+    case 0: // T\r
+    case 1: // F\r
+      break;\r
+    case 2: // hi\r
+      ot("  tst r9,#0x60000000 ;@ hi: !C && !Z\n");\r
+      ot("  beq DbraTrue%.4x\n\n",op);\r
+      break;\r
+    case 3: // ls\r
+      ot("  tst r9,#0x60000000 ;@ ls: C || Z\n");\r
+      ot("  bne DbraTrue%.4x\n\n",op);\r
+      break;\r
+    default:\r
+      ot(";@ Is the condition true?\n");\r
+      ot("  msr cpsr_flg,r9 ;@ ARM flags = 68000 flags\n");\r
+      ot(";@ If so, don't dbra\n");\r
+      ot("  b%s DbraTrue%.4x\n\n",Cond[cc],op);\r
+      break;\r
   }\r
 \r
-  ot(";@ Decrement Dn.w\n");\r
-  ot("  and r1,r8,#0x0007\n");\r
-  ot("  mov r1,r1,lsl #2\n");\r
-  ot("  ldrsh r0,[r7,r1]\n");\r
-  ot("  sub r0,r0,#1\n");\r
-  ot("  strh r0,[r7,r1]\n");\r
-  ot("\n");\r
+  if (cc!=0)\r
+  {\r
+    ot(";@ Decrement Dn.w\n");\r
+    ot("  and r1,r8,#0x0007\n");\r
+    ot("  mov r1,r1,lsl #2\n");\r
+    ot("  ldrsh r0,[r7,r1]\n");\r
+    ot("  sub r0,r0,#1\n");\r
+    ot("  strh r0,[r7,r1]\n");\r
+    ot("\n");\r
 \r
-  ot(";@ Check if Dn.w is -1\n");\r
-  ot("  cmps r0,#-1\n");\r
-  ot("  beq DbraMin1%.4x\n",op);\r
-  ot("\n");\r
+    ot(";@ Check if Dn.w is -1\n");\r
+    ot("  cmn r0,#1\n");\r
+    ot("\n");\r
 \r
-  ot(";@ Get Branch offset:\n");\r
-  ot("  ldrsh r0,[r4]\n");\r
-  ot("  add r4,r4,r0 ;@ r4 = New PC\n");\r
-  ot("\n");\r
-  Cycles=12-2;\r
-  OpEnd();\r
+    ot(";@ Get Branch offset:\n");\r
+    ot("  ldrnesh r0,[r4]\n");\r
+    ot("  addeq r4,r4,#2 ;@ Skip branch offset\n");\r
+    ot("  subeq r5,r5,#4 ;@ additional cycles\n");\r
+    ot("  addne r4,r4,r0 ;@ r4 = New PC\n");\r
+    ot("\n");\r
+    Cycles=12-2;\r
+    OpEnd();\r
+  }\r
   \r
-  ot(";@ Dn.w is -1:\n");\r
-  ot("DbraMin1%.4x%s\n", op, ms?"":":");\r
-  ot("  add r4,r4,#2 ;@ Skip branch offset\n");\r
-  ot("\n");\r
-  Cycles=12+2;\r
-  OpEnd();\r
-\r
-  ot(";@ condition true:\n");\r
-  ot("DbraTrue%.4x%s\n", op, ms?"":":");\r
-  ot("  add r4,r4,#2 ;@ Skip branch offset\n");\r
-  ot("\n");\r
-  Cycles=12;\r
-  OpEnd();\r
+  if (cc==0||cc>=2)\r
+  {\r
+    ot(";@ condition true:\n");\r
+    ot("DbraTrue%.4x%s\n", op, ms?"":":");\r
+    ot("  add r4,r4,#2 ;@ Skip branch offset\n");\r
+    ot("\n");\r
+    Cycles=12;\r
+    OpEnd();\r
+  }\r
 \r
   return 0;\r
 }\r