aboutsummaryrefslogtreecommitdiff
path: root/target-cris/op_helper.c
diff options
context:
space:
mode:
authoredgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-27 21:10:56 +0000
committeredgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-27 21:10:56 +0000
commit30abcfc7babe4bde680e1a04a1a6d0f1c041cc29 (patch)
tree4ee2139a9bad1d0571a4750f33b5d9381d8babeb /target-cris/op_helper.c
parent9bcd77d6b1815db0716b56a605806ba2d2101656 (diff)
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
Diffstat (limited to 'target-cris/op_helper.c')
-rw-r--r--target-cris/op_helper.c93
1 files changed, 77 insertions, 16 deletions
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index abcf9b47ff..ebff31a1de 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 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
/* 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 @@ void helper_tlb_flush_pid(uint32_t pid)
#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 @@ static void evaluate_flags_writeback(uint32_t flags)
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 @@ void helper_evaluate_flags_alu_4(void)
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_alu_4(void)
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 @@ void helper_evaluate_flags (void)
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 @@ void helper_evaluate_flags (void)
}
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;
+ }
+}