CRIS: Restructure the translator to allow for better code generation.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4594 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index abcf9b4..ebff31a 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -22,6 +22,7 @@
 #include <assert.h>
 #include "exec.h"
 #include "mmu.h"
+#include "helper.h"
 
 #define MMUSUFFIX _mmu
 
@@ -67,6 +68,9 @@
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
                 cpu_restore_state(tb, env, pc, NULL);
+
+		/* Evaluate flags after retranslation.  */
+                helper_top_evaluate_flags();
             }
         }
         cpu_loop_exit();
@@ -87,12 +91,7 @@
 #endif
 }
 
-void helper_tlb_flush(void)
-{
-	tlb_flush(env, 1);
-}
-
-void helper_dump(uint32_t a0, uint32_t a1)
+void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
 {
 	(fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1)); 
 }
@@ -236,13 +235,7 @@
 	int x;
 
 	/* Extended arithmetics, leave the z flag alone.  */
-	env->debug3 = env->pregs[PR_CCS];
-
-	if (env->cc_x_live)
-		x = env->cc_x;
-	else
-		x = env->pregs[PR_CCS] & X_FLAG;
-
+	x = env->cc_x;
 	if ((x || env->cc_op == CC_OP_ADDC)
 	    && flags & Z_FLAG)
 		env->cc_mask &= ~Z_FLAG;
@@ -359,7 +352,23 @@
 
 	src = env->cc_src;
 	dst = env->cc_dest;
-	res = env->cc_result;
+
+	/* Reconstruct the result.  */
+	switch (env->cc_op)
+	{
+		case CC_OP_SUB:
+			res = dst - src;
+			break;
+		case CC_OP_ADD:
+			res = dst + src;
+			break;
+		default:
+			res = env->cc_result;
+			break;
+	}
+
+	if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
+		src = ~src;
 
 	if ((res & 0x80000000L) != 0L)
 	{
@@ -396,11 +405,9 @@
 
 void  helper_evaluate_flags_move_4 (void)
 {
-	uint32_t src;
 	uint32_t res;
 	uint32_t flags = 0;
 
-	src = env->cc_src;
 	res = env->cc_result;
 
 	if ((int32_t)res < 0)
@@ -440,6 +447,8 @@
 	dst = env->cc_dest;
 	res = env->cc_result;
 
+	if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
+		src = ~src;
 
 	/* Now, evaluate the flags. This stuff is based on
 	   Per Zander's CRISv10 simulator.  */
@@ -548,3 +557,55 @@
 	}
 	evaluate_flags_writeback(flags);
 }
+
+void helper_top_evaluate_flags(void)
+{
+	switch (env->cc_op)
+	{
+		case CC_OP_MCP:
+			helper_evaluate_flags_mcp();
+			break;
+		case CC_OP_MULS:
+			helper_evaluate_flags_muls();
+			break;
+		case CC_OP_MULU:
+			helper_evaluate_flags_mulu();
+			break;
+		case CC_OP_MOVE:
+		case CC_OP_AND:
+		case CC_OP_OR:
+		case CC_OP_XOR:
+		case CC_OP_ASR:
+		case CC_OP_LSR:
+		case CC_OP_LSL:
+			switch (env->cc_size)
+			{
+				case 4:
+					helper_evaluate_flags_move_4();
+					break;
+				case 2:
+					helper_evaluate_flags_move_2();
+					break;
+				default:
+					helper_evaluate_flags();
+					break;
+			}
+			break;
+		case CC_OP_FLAGS:
+			/* live.  */
+			break;
+		default:
+		{
+			switch (env->cc_size)
+			{
+				case 4:
+					helper_evaluate_flags_alu_4();
+					break;
+				default:
+					helper_evaluate_flags();
+					break;
+			}
+		}
+		break;
+	}
+}