diff options
-rw-r--r-- | target-cris/helper.h | 14 | ||||
-rw-r--r-- | target-cris/op_helper.c | 167 | ||||
-rw-r--r-- | target-cris/translate.c | 133 |
3 files changed, 154 insertions, 160 deletions
diff --git a/target-cris/helper.h b/target-cris/helper.h index 339a59a04a..093063a14b 100644 --- a/target-cris/helper.h +++ b/target-cris/helper.h @@ -13,13 +13,13 @@ DEF_HELPER_2(movl_reg_sreg, void, i32, i32) DEF_HELPER_FLAGS_1(lz, TCG_CALL_PURE, i32, i32); DEF_HELPER_FLAGS_3(btst, TCG_CALL_PURE, i32, i32, i32, i32); -DEF_HELPER_0(evaluate_flags_muls, void) -DEF_HELPER_0(evaluate_flags_mulu, void) -DEF_HELPER_0(evaluate_flags_mcp, void) -DEF_HELPER_0(evaluate_flags_alu_4, void) -DEF_HELPER_0(evaluate_flags_sub_4, void) -DEF_HELPER_0(evaluate_flags_move_4, void) -DEF_HELPER_0(evaluate_flags_move_2, void) +DEF_HELPER_FLAGS_3(evaluate_flags_muls, TCG_CALL_PURE, i32, i32, i32, i32) +DEF_HELPER_FLAGS_3(evaluate_flags_mulu, TCG_CALL_PURE, i32, i32, i32, i32) +DEF_HELPER_FLAGS_4(evaluate_flags_mcp, TCG_CALL_PURE, i32, i32, i32, i32, i32) +DEF_HELPER_FLAGS_4(evaluate_flags_alu_4, TCG_CALL_PURE, i32, i32, i32, i32, i32) +DEF_HELPER_FLAGS_4(evaluate_flags_sub_4, TCG_CALL_PURE, i32, i32, i32, i32, i32) +DEF_HELPER_FLAGS_2(evaluate_flags_move_4, TCG_CALL_PURE, i32, i32, i32) +DEF_HELPER_FLAGS_2(evaluate_flags_move_2, TCG_CALL_PURE, i32, i32, i32) DEF_HELPER_0(evaluate_flags, void) DEF_HELPER_0(top_evaluate_flags, void) diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c index 144da9c3e1..c96e48d837 100644 --- a/target-cris/op_helper.c +++ b/target-cris/op_helper.c @@ -275,7 +275,7 @@ uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs) return ccs; } -static void evaluate_flags_writeback(uint32_t flags) +static inline uint32_t evaluate_flags_writeback(uint32_t flags, uint32_t ccs) { unsigned int x, z, mask; @@ -289,27 +289,19 @@ static void evaluate_flags_writeback(uint32_t flags) flags &= mask; /* all insn clear the x-flag except setf or clrf. */ - env->pregs[PR_CCS] &= ~mask; - env->pregs[PR_CCS] |= flags; + ccs &= ~mask; + ccs |= flags; + return ccs; } -void helper_evaluate_flags_muls(void) +uint32_t helper_evaluate_flags_muls(uint32_t ccs, uint32_t res, uint32_t mof) { - uint32_t src; - uint32_t dst; - uint32_t res; uint32_t flags = 0; int64_t tmp; - int32_t mof; int dneg; - src = env->cc_src; - dst = env->cc_dest; - res = env->cc_result; - dneg = ((int32_t)res) < 0; - mof = env->pregs[PR_MOF]; tmp = mof; tmp <<= 32; tmp |= res; @@ -320,23 +312,14 @@ void helper_evaluate_flags_muls(void) if ((dneg && mof != -1) || (!dneg && mof != 0)) flags |= V_FLAG; - evaluate_flags_writeback(flags); + return evaluate_flags_writeback(flags, ccs); } -void helper_evaluate_flags_mulu(void) +uint32_t helper_evaluate_flags_mulu(uint32_t ccs, uint32_t res, uint32_t mof) { - uint32_t src; - uint32_t dst; - uint32_t res; uint32_t flags = 0; uint64_t tmp; - uint32_t mof; - src = env->cc_src; - dst = env->cc_dest; - res = env->cc_result; - - mof = env->pregs[PR_MOF]; tmp = mof; tmp <<= 32; tmp |= res; @@ -347,19 +330,16 @@ void helper_evaluate_flags_mulu(void) if (mof) flags |= V_FLAG; - evaluate_flags_writeback(flags); + return evaluate_flags_writeback(flags, ccs); } -void helper_evaluate_flags_mcp(void) +uint32_t helper_evaluate_flags_mcp(uint32_t ccs, + uint32_t src, uint32_t dst, uint32_t res) { - uint32_t src; - uint32_t dst; - uint32_t res; uint32_t flags = 0; - src = env->cc_src & 0x80000000; - dst = env->cc_dest & 0x80000000; - res = env->cc_result; + src = src & 0x80000000; + dst = dst & 0x80000000; if ((res & 0x80000000L) != 0L) { @@ -379,19 +359,16 @@ void helper_evaluate_flags_mcp(void) flags |= R_FLAG; } - evaluate_flags_writeback(flags); + return evaluate_flags_writeback(flags, ccs); } -void helper_evaluate_flags_alu_4(void) +uint32_t helper_evaluate_flags_alu_4(uint32_t ccs, + uint32_t src, uint32_t dst, uint32_t res) { - uint32_t src; - uint32_t dst; - uint32_t res; uint32_t flags = 0; - src = env->cc_src & 0x80000000; - dst = env->cc_dest & 0x80000000; - res = env->cc_result; + src = src & 0x80000000; + dst = dst & 0x80000000; if ((res & 0x80000000L) != 0L) { @@ -411,19 +388,16 @@ void helper_evaluate_flags_alu_4(void) flags |= C_FLAG; } - evaluate_flags_writeback(flags); + return evaluate_flags_writeback(flags, ccs); } -void helper_evaluate_flags_sub_4(void) +uint32_t helper_evaluate_flags_sub_4(uint32_t ccs, + uint32_t src, uint32_t dst, uint32_t res) { - uint32_t src; - uint32_t dst; - uint32_t res; uint32_t flags = 0; - src = (~env->cc_src) & 0x80000000; - dst = env->cc_dest & 0x80000000; - res = env->cc_result; + src = (~src) & 0x80000000; + dst = dst & 0x80000000; if ((res & 0x80000000L) != 0L) { @@ -444,47 +418,37 @@ void helper_evaluate_flags_sub_4(void) } flags ^= C_FLAG; - evaluate_flags_writeback(flags); + return evaluate_flags_writeback(flags, ccs); } -void helper_evaluate_flags_move_4 (void) +uint32_t helper_evaluate_flags_move_4(uint32_t ccs, uint32_t res) { - uint32_t res; uint32_t flags = 0; - res = env->cc_result; - if ((int32_t)res < 0) flags |= N_FLAG; else if (res == 0L) flags |= Z_FLAG; - evaluate_flags_writeback(flags); + return evaluate_flags_writeback(flags, ccs); } -void helper_evaluate_flags_move_2 (void) +uint32_t helper_evaluate_flags_move_2(uint32_t ccs, uint32_t res) { - uint32_t src; uint32_t flags = 0; - uint16_t res; - - src = env->cc_src; - res = env->cc_result; if ((int16_t)res < 0L) flags |= N_FLAG; else if (res == 0) flags |= Z_FLAG; - evaluate_flags_writeback(flags); + return evaluate_flags_writeback(flags, ccs); } /* TODO: This is expensive. We could split things up and only evaluate part of CCR on a need to know basis. For now, we simply re-evaluate everything. */ -void helper_evaluate_flags (void) +void helper_evaluate_flags(void) { - uint32_t src; - uint32_t dst; - uint32_t res; + uint32_t src, dst, res; uint32_t flags = 0; src = env->cc_src; @@ -595,11 +559,10 @@ void helper_evaluate_flags (void) break; } - if (env->cc_op == CC_OP_SUB - || env->cc_op == CC_OP_CMP) { + if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP) flags ^= C_FLAG; - } - evaluate_flags_writeback(flags); + + env->pregs[PR_CCS] = evaluate_flags_writeback(flags, env->pregs[PR_CCS]); } void helper_top_evaluate_flags(void) @@ -607,13 +570,19 @@ void helper_top_evaluate_flags(void) switch (env->cc_op) { case CC_OP_MCP: - helper_evaluate_flags_mcp(); + env->pregs[PR_CCS] = helper_evaluate_flags_mcp( + env->pregs[PR_CCS], env->cc_src, + env->cc_dest, env->cc_result); break; case CC_OP_MULS: - helper_evaluate_flags_muls(); + env->pregs[PR_CCS] = helper_evaluate_flags_muls( + env->pregs[PR_CCS], env->cc_result, + env->pregs[PR_MOF]); break; case CC_OP_MULU: - helper_evaluate_flags_mulu(); + env->pregs[PR_CCS] = helper_evaluate_flags_mulu( + env->pregs[PR_CCS], env->cc_result, + env->pregs[PR_MOF]); break; case CC_OP_MOVE: case CC_OP_AND: @@ -622,26 +591,36 @@ void helper_top_evaluate_flags(void) 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; + switch (env->cc_size) + { + case 4: + env->pregs[PR_CCS] = + helper_evaluate_flags_move_4( + env->pregs[PR_CCS], + env->cc_result); + break; + case 2: + env->pregs[PR_CCS] = + helper_evaluate_flags_move_2( + env->pregs[PR_CCS], + env->cc_result); + break; + default: + helper_evaluate_flags(); + break; + } + break; case CC_OP_FLAGS: /* live. */ break; case CC_OP_SUB: case CC_OP_CMP: if (env->cc_size == 4) - helper_evaluate_flags_sub_4(); + env->pregs[PR_CCS] = + helper_evaluate_flags_sub_4( + env->pregs[PR_CCS], + env->cc_src, env->cc_dest, + env->cc_result); else helper_evaluate_flags(); break; @@ -649,12 +628,16 @@ void helper_top_evaluate_flags(void) { switch (env->cc_size) { - case 4: - helper_evaluate_flags_alu_4(); - break; - default: - helper_evaluate_flags(); - break; + case 4: + env->pregs[PR_CCS] = + helper_evaluate_flags_alu_4( + env->pregs[PR_CCS], + env->cc_src, env->cc_dest, + env->cc_result); + break; + default: + helper_evaluate_flags(); + break; } } break; diff --git a/target-cris/translate.c b/target-cris/translate.c index 735e4442a4..03ac7ea74b 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -565,74 +565,85 @@ static void cris_flush_cc_state(DisasContext *dc) static void cris_evaluate_flags(DisasContext *dc) { - if (!dc->flags_uptodate) { - cris_flush_cc_state(dc); + if (dc->flags_uptodate) + return; - switch (dc->cc_op) + cris_flush_cc_state(dc); + + switch (dc->cc_op) + { + case CC_OP_MCP: + gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], cc_src, + cc_dest, cc_result); + break; + case CC_OP_MULS: + gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], cc_result, + cpu_PR[PR_MOF]); + break; + case CC_OP_MULU: + gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], cc_result, + cpu_PR[PR_MOF]); + 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 (dc->cc_size) { - case CC_OP_MCP: - gen_helper_evaluate_flags_mcp(); - break; - case CC_OP_MULS: - gen_helper_evaluate_flags_muls(); - break; - case CC_OP_MULU: - gen_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 (dc->cc_size) - { - case 4: - gen_helper_evaluate_flags_move_4(); - break; - case 2: - gen_helper_evaluate_flags_move_2(); - break; - default: - gen_helper_evaluate_flags(); - break; - } - break; - case CC_OP_FLAGS: - /* live. */ - break; - case CC_OP_SUB: - case CC_OP_CMP: - if (dc->cc_size == 4) - gen_helper_evaluate_flags_sub_4(); - else - gen_helper_evaluate_flags(); + case 4: + gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], cc_result); + break; + case 2: + gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], cc_result); + break; + default: + gen_helper_evaluate_flags(); + break; + } + break; + case CC_OP_FLAGS: + /* live. */ + break; + case CC_OP_SUB: + case CC_OP_CMP: + if (dc->cc_size == 4) + gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], cc_src, cc_dest, cc_result); + else + gen_helper_evaluate_flags(); + break; + default: + switch (dc->cc_size) + { + case 4: + gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], cc_src, cc_dest, cc_result); break; default: - switch (dc->cc_size) - { - case 4: - gen_helper_evaluate_flags_alu_4(); - break; - default: - gen_helper_evaluate_flags(); - break; - } - break; + gen_helper_evaluate_flags(); + break; } - if (dc->flagx_known) { - if (dc->flags_x) - tcg_gen_ori_tl(cpu_PR[PR_CCS], - cpu_PR[PR_CCS], X_FLAG); - else - tcg_gen_andi_tl(cpu_PR[PR_CCS], - cpu_PR[PR_CCS], ~X_FLAG); - } - - dc->flags_uptodate = 1; + break; } + + if (dc->flagx_known) { + if (dc->flags_x) + tcg_gen_ori_tl(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], X_FLAG); + else + tcg_gen_andi_tl(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], ~X_FLAG); + } + dc->flags_uptodate = 1; } static void cris_cc_mask(DisasContext *dc, unsigned int mask) |