From 30abcfc7babe4bde680e1a04a1a6d0f1c041cc29 Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Tue, 27 May 2008 21:10:56 +0000 Subject: [PATCH] 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 --- target-cris/cpu.h | 39 +- target-cris/helper.c | 3 +- target-cris/helper.h | 2 +- target-cris/op_helper.c | 93 ++++- target-cris/translate.c | 795 +++++++++++++++++++++++----------------- 5 files changed, 545 insertions(+), 387 deletions(-) diff --git a/target-cris/cpu.h b/target-cris/cpu.h index a26dd80364..ffcf3c02e9 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -120,8 +120,7 @@ typedef struct CPUCRISState { uint32_t cc_result; /* size of the operation, 1 = byte, 2 = word, 4 = dword. */ int cc_size; - /* Extended arithmetics. */ - int cc_x_live; + /* X flag at the time of cc snapshot. */ int cc_x; int exception_index; @@ -130,10 +129,6 @@ typedef struct CPUCRISState { int fault_vector; int trap_vector; - uint32_t debug1; - uint32_t debug2; - uint32_t debug3; - /* FIXME: add a check in the translator to avoid writing to support register sets beyond the 4th. The ISA allows up to 256! but in practice there is no core that implements more than 4. @@ -177,20 +172,14 @@ void do_interrupt(CPUCRISState *env); is returned if the signal was handled by the virtual CPU. */ int cpu_cris_signal_handler(int host_signum, void *pinfo, void *puc); -void cpu_cris_flush_flags(CPUCRISState *, int); - - void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, int is_asi); enum { CC_OP_DYNAMIC, /* Use env->cc_op */ CC_OP_FLAGS, - CC_OP_LOGIC, CC_OP_CMP, CC_OP_MOVE, - CC_OP_MOVE_PD, - CC_OP_MOVE_SD, CC_OP_ADD, CC_OP_ADDC, CC_OP_MCP, @@ -213,32 +202,6 @@ enum { CC_OP_LZ }; -#define CCF_C 0x01 -#define CCF_V 0x02 -#define CCF_Z 0x04 -#define CCF_N 0x08 -#define CCF_X 0x10 - -#define CRIS_SSP 0 -#define CRIS_USP 1 - -void cris_set_irq_level(CPUCRISState *env, int level, uint8_t vector); -void cris_set_macsr(CPUCRISState *env, uint32_t val); -void cris_switch_sp(CPUCRISState *env); - -void do_cris_semihosting(CPUCRISState *env, int nr); - -enum cris_features { - CRIS_FEATURE_CF_ISA_MUL, -}; - -static inline int cris_feature(CPUCRISState *env, int feature) -{ - return (env->features & (1u << feature)) != 0; -} - -void register_cris_insns (CPUCRISState *env); - /* CRIS uses 8k pages. */ #define TARGET_PAGE_BITS 13 #define MMAP_SHIFT TARGET_PAGE_BITS diff --git a/target-cris/helper.c b/target-cris/helper.c index 5548b76073..c16a58a3b0 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -42,9 +42,8 @@ int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, int mmu_idx, int is_softmmu) { env->exception_index = 0xaa; - env->debug1 = address; + env->pregs[PR_EDA] = address; cpu_dump_state(env, stderr, fprintf, 0); - env->pregs[PR_ERP] = env->pc; return 1; } diff --git a/target-cris/helper.h b/target-cris/helper.h index 43a3159d7e..34f6831f4e 100644 --- a/target-cris/helper.h +++ b/target-cris/helper.h @@ -2,7 +2,6 @@ void TCG_HELPER_PROTO helper_raise_exception(uint32_t index); void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid); -void TCG_HELPER_PROTO helper_tlb_flush(void); void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2); void TCG_HELPER_PROTO helper_dummy(void); void TCG_HELPER_PROTO helper_rfe(void); @@ -18,3 +17,4 @@ void TCG_HELPER_PROTO helper_evaluate_flags_alu_4(void); void TCG_HELPER_PROTO helper_evaluate_flags_move_4 (void); void TCG_HELPER_PROTO helper_evaluate_flags_move_2 (void); void TCG_HELPER_PROTO helper_evaluate_flags (void); +void TCG_HELPER_PROTO helper_top_evaluate_flags(void); 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 #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; + } +} diff --git a/target-cris/translate.c b/target-cris/translate.c index 6674ca97ad..615a3fcac5 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -65,6 +65,7 @@ TCGv cpu_env; TCGv cpu_T[2]; TCGv cpu_R[16]; TCGv cpu_PR[16]; +TCGv cc_x; TCGv cc_src; TCGv cc_dest; TCGv cc_result; @@ -93,12 +94,16 @@ typedef struct DisasContext { int cc_op; int cc_size; uint32_t cc_mask; - int flags_live; /* Wether or not $ccs is uptodate. */ - int flagx_live; /* Wether or not flags_x has the x flag known at - translation time. */ - int flags_x; - int clear_x; /* Clear x after this insn? */ + int cc_size_uptodate; /* -1 invalid or last written value. */ + + int cc_x_uptodate; /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate. */ + int flags_uptodate; /* Wether or not $ccs is uptodate. */ + int flagx_known; /* Wether or not flags_x has the x flag known at + translation time. */ + int flags_x; + + int clear_x; /* Clear x after this insn? */ int user; /* user or kernel mode. */ int is_jmp; @@ -267,8 +272,8 @@ static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b) tcg_gen_shri_i64(t0, t0, 32); tcg_gen_trunc_i64_i32(d2, t0); - tcg_gen_discard_i64(t0); - tcg_gen_discard_i64(t1); + tcg_temp_free(t0); + tcg_temp_free(t1); } /* 64-bit unsigned muls, lower result in d and upper in d2. */ @@ -287,8 +292,8 @@ static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b) tcg_gen_shri_i64(t0, t0, 32); tcg_gen_trunc_i64_i32(d2, t0); - tcg_gen_discard_i64(t0); - tcg_gen_discard_i64(t1); + tcg_temp_free(t0); + tcg_temp_free(t1); } /* 32bit branch-free binary search for counting leading zeros. */ @@ -354,15 +359,16 @@ static void t_gen_lz_i32(TCGv d, TCGv x) tcg_gen_addi_i32(d, n, 2); tcg_gen_sub_i32(d, d, m); - tcg_gen_discard_i32(y); - tcg_gen_discard_i32(m); - tcg_gen_discard_i32(n); + tcg_temp_free(y); + tcg_temp_free(m); + tcg_temp_free(n); } -static void t_gen_btst(TCGv d, TCGv s) +static void t_gen_btst(TCGv d, TCGv a, TCGv b) { TCGv sbit; TCGv bset; + TCGv t0; int l1; /* des ref: @@ -390,18 +396,19 @@ static void t_gen_btst(TCGv d, TCGv s) l1 = gen_new_label(); sbit = tcg_temp_new(TCG_TYPE_TL); bset = tcg_temp_new(TCG_TYPE_TL); + t0 = tcg_temp_new(TCG_TYPE_TL); /* Compute bset and sbit. */ - tcg_gen_andi_tl(sbit, s, 31); - tcg_gen_shl_tl(s, tcg_const_tl(1), sbit); - tcg_gen_and_tl(bset, d, s); + tcg_gen_andi_tl(sbit, b, 31); + tcg_gen_shl_tl(t0, tcg_const_tl(1), sbit); + tcg_gen_and_tl(bset, a, t0); tcg_gen_shr_tl(bset, bset, sbit); /* Displace to N_FLAG. */ tcg_gen_shli_tl(bset, bset, 3); tcg_gen_shl_tl(sbit, tcg_const_tl(2), sbit); tcg_gen_subi_tl(sbit, sbit, 1); - tcg_gen_and_tl(sbit, d, sbit); + tcg_gen_and_tl(sbit, a, sbit); tcg_gen_andi_tl(d, cpu_PR[PR_CCS], ~(X_FLAG | N_FLAG | Z_FLAG)); /* or in the N_FLAG. */ @@ -411,11 +418,11 @@ static void t_gen_btst(TCGv d, TCGv s) tcg_gen_ori_tl(d, d, Z_FLAG); gen_set_label(l1); - tcg_gen_discard_tl(sbit); - tcg_gen_discard_tl(bset); + tcg_temp_free(sbit); + tcg_temp_free(bset); } -static void t_gen_cris_dstep(TCGv d, TCGv s) +static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b) { int l1; @@ -426,9 +433,9 @@ static void t_gen_cris_dstep(TCGv d, TCGv s) * if (d >= s) * d -= s; */ - tcg_gen_shli_tl(d, d, 1); - tcg_gen_brcond_tl(TCG_COND_LTU, d, s, l1); - tcg_gen_sub_tl(d, d, s); + tcg_gen_shli_tl(d, a, 1); + tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1); + tcg_gen_sub_tl(d, d, b); gen_set_label(l1); } @@ -444,32 +451,56 @@ static inline void t_gen_add_flag(TCGv d, int flag) if (flag) tcg_gen_shri_tl(c, c, flag); tcg_gen_add_tl(d, d, c); - tcg_gen_discard_tl(c); + tcg_temp_free(c); } -static inline void t_gen_addx_carry(TCGv d) +static inline void t_gen_addx_carry(DisasContext *dc, TCGv d) { - TCGv x, c; + if (dc->flagx_known) { + if (dc->flags_x) { + TCGv c; + + c = tcg_temp_new(TCG_TYPE_TL); + t_gen_mov_TN_preg(c, PR_CCS); + /* C flag is already at bit 0. */ + tcg_gen_andi_tl(c, c, C_FLAG); + tcg_gen_add_tl(d, d, c); + tcg_temp_free(c); + } + } else { + TCGv x, c; - x = tcg_temp_new(TCG_TYPE_TL); - c = tcg_temp_new(TCG_TYPE_TL); - t_gen_mov_TN_preg(x, PR_CCS); - tcg_gen_mov_tl(c, x); + x = tcg_temp_new(TCG_TYPE_TL); + c = tcg_temp_new(TCG_TYPE_TL); + t_gen_mov_TN_preg(x, PR_CCS); + tcg_gen_mov_tl(c, x); - /* Propagate carry into d if X is set. Branch free. */ - tcg_gen_andi_tl(c, c, C_FLAG); - tcg_gen_andi_tl(x, x, X_FLAG); - tcg_gen_shri_tl(x, x, 4); + /* Propagate carry into d if X is set. Branch free. */ + tcg_gen_andi_tl(c, c, C_FLAG); + tcg_gen_andi_tl(x, x, X_FLAG); + tcg_gen_shri_tl(x, x, 4); - tcg_gen_and_tl(x, x, c); - tcg_gen_add_tl(d, d, x); - tcg_gen_discard_tl(x); - tcg_gen_discard_tl(c); + tcg_gen_and_tl(x, x, c); + tcg_gen_add_tl(d, d, x); + tcg_temp_free(x); + tcg_temp_free(c); + } } static inline void t_gen_subx_carry(DisasContext *dc, TCGv d) { - if (dc->flagx_live) { + if (dc->flagx_known) { + if (dc->flags_x) { + TCGv c; + + c = tcg_temp_new(TCG_TYPE_TL); + t_gen_mov_TN_preg(c, PR_CCS); + /* C flag is already at bit 0. */ + tcg_gen_andi_tl(c, c, C_FLAG); + tcg_gen_sub_tl(d, d, c); + tcg_temp_free(c); + } + } else { TCGv x, c; x = tcg_temp_new(TCG_TYPE_TL); @@ -484,18 +515,8 @@ static inline void t_gen_subx_carry(DisasContext *dc, TCGv d) tcg_gen_and_tl(x, x, c); tcg_gen_sub_tl(d, d, x); - tcg_gen_discard_tl(x); - tcg_gen_discard_tl(c); - } else { - if (dc->flags_x) { - TCGv c; - - c = tcg_temp_new(TCG_TYPE_TL); - /* C flag is already at bit 0. */ - tcg_gen_andi_tl(c, c, C_FLAG); - tcg_gen_add_tl(d, d, c); - tcg_gen_discard_tl(c); - } + tcg_temp_free(x); + tcg_temp_free(c); } } @@ -515,8 +536,8 @@ static inline void t_gen_swapb(TCGv d, TCGv s) tcg_gen_shri_tl(t, org_s, 8); tcg_gen_andi_tl(t, t, 0x00ff00ff); tcg_gen_or_tl(d, d, t); - tcg_gen_discard_tl(t); - tcg_gen_discard_tl(org_s); + tcg_temp_free(t); + tcg_temp_free(org_s); } /* Swap the halfwords of the s operand. */ @@ -529,7 +550,7 @@ static inline void t_gen_swapw(TCGv d, TCGv s) tcg_gen_shli_tl(d, t, 16); tcg_gen_shri_tl(t, t, 16); tcg_gen_or_tl(d, d, t); - tcg_gen_discard_tl(t); + tcg_temp_free(t); } /* Reverse the within each byte. @@ -576,8 +597,8 @@ static inline void t_gen_swapr(TCGv d, TCGv s) tcg_gen_andi_tl(t, t, bitrev[i].mask); tcg_gen_or_tl(d, d, t); } - tcg_gen_discard_tl(t); - tcg_gen_discard_tl(org_s); + tcg_temp_free(t); + tcg_temp_free(org_s); } static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false) @@ -595,7 +616,7 @@ static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false) tcg_gen_mov_tl(env_pc, pc_true); gen_set_label(l1); - tcg_gen_discard_tl(btaken); + tcg_temp_free(btaken); } static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) @@ -627,20 +648,24 @@ static int sign_extend(unsigned int val, unsigned int width) static inline void cris_clear_x_flag(DisasContext *dc) { - if (!dc->flagx_live - || (dc->flagx_live && dc->flags_x) - || dc->cc_op == CC_OP_FLAGS) - tcg_gen_andi_i32(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG); - dc->flagx_live = 1; + dc->flagx_known = 1; dc->flags_x = 0; } +static void cris_flush_cc_state(DisasContext *dc) +{ + if (dc->cc_size_uptodate != dc->cc_size) { + tcg_gen_movi_tl(cc_size, dc->cc_size); + dc->cc_size_uptodate = dc->cc_size; + } + tcg_gen_movi_tl(cc_op, dc->cc_op); + tcg_gen_movi_tl(cc_mask, dc->cc_mask); +} + static void cris_evaluate_flags(DisasContext *dc) { - if (!dc->flags_live) { - tcg_gen_movi_tl(cc_op, dc->cc_op); - tcg_gen_movi_tl(cc_size, dc->cc_size); - tcg_gen_movi_tl(cc_mask, dc->cc_mask); + if (!dc->flags_uptodate) { + cris_flush_cc_state(dc); switch (dc->cc_op) { @@ -654,6 +679,12 @@ static void cris_evaluate_flags(DisasContext *dc) tcg_gen_helper_0_0(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: @@ -684,7 +715,7 @@ static void cris_evaluate_flags(DisasContext *dc) } break; } - dc->flags_live = 1; + dc->flags_uptodate = 1; } } @@ -705,132 +736,144 @@ static void cris_cc_mask(DisasContext *dc, unsigned int mask) if (mask == 0) dc->update_cc = 0; else - dc->flags_live = 0; + dc->flags_uptodate = 0; } static void cris_update_cc_op(DisasContext *dc, int op, int size) { dc->cc_op = op; dc->cc_size = size; - dc->flags_live = 0; + dc->flags_uptodate = 0; } -/* op is the operation. - T0, T1 are the operands. - dst is the destination reg. -*/ -static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) +static inline void cris_update_cc_x(DisasContext *dc) +{ + /* Save the x flag state at the time of the cc snapshot. */ + if (dc->flagx_known) { + if (dc->cc_x_uptodate == (2 | dc->flags_x)) + return; + tcg_gen_movi_tl(cc_x, dc->flags_x); + dc->cc_x_uptodate = 2 | dc->flags_x; + } + else { + tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG); + dc->cc_x_uptodate = 1; + } +} + +/* Update cc prior to executing ALU op. Needs source operands untouched. */ +static void cris_pre_alu_update_cc(DisasContext *dc, int op, + TCGv dst, TCGv src, int size) { - int writeback = 1; if (dc->update_cc) { cris_update_cc_op(dc, op, size); - if (op != CC_OP_MOVE) - tcg_gen_mov_tl(cc_dest, cpu_T[0]); + tcg_gen_mov_tl(cc_src, src); - /* FIXME: This shouldn't be needed. But we don't pass the - tests without it. Investigate. */ - t_gen_mov_env_TN(cc_x_live, tcg_const_tl(dc->flagx_live)); - t_gen_mov_env_TN(cc_x, tcg_const_tl(dc->flags_x)); + if (op != CC_OP_MOVE + && op != CC_OP_AND + && op != CC_OP_OR + && op != CC_OP_XOR + && op != CC_OP_ASR + && op != CC_OP_LSR + && op != CC_OP_LSL) + tcg_gen_mov_tl(cc_dest, dst); + + cris_update_cc_x(dc); } +} +/* Update cc after executing ALU op. needs the result. */ +static inline void cris_update_result(DisasContext *dc, TCGv res) +{ + if (dc->update_cc) { + if (dc->cc_size == 4 && + (dc->cc_op == CC_OP_SUB + || dc->cc_op == CC_OP_ADD)) + return; + tcg_gen_mov_tl(cc_result, res); + } +} + +/* Returns one if the write back stage should execute. */ +static void cris_alu_op_exec(DisasContext *dc, int op, + TCGv dst, TCGv a, TCGv b, int size) +{ /* Emit the ALU insns. */ switch (op) { case CC_OP_ADD: - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_add_tl(dst, a, b); /* Extended arithmetics. */ - t_gen_addx_carry(cpu_T[0]); + t_gen_addx_carry(dc, dst); break; case CC_OP_ADDC: - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - t_gen_add_flag(cpu_T[0], 0); /* C_FLAG. */ + tcg_gen_add_tl(dst, a, b); + t_gen_add_flag(dst, 0); /* C_FLAG. */ break; case CC_OP_MCP: - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - t_gen_add_flag(cpu_T[0], 8); /* R_FLAG. */ + tcg_gen_add_tl(dst, a, b); + t_gen_add_flag(dst, 8); /* R_FLAG. */ break; case CC_OP_SUB: - tcg_gen_neg_tl(cpu_T[1], cpu_T[1]); - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_neg_tl(cpu_T[1], cpu_T[1]); - /* CRIS flag evaluation needs ~src. */ - tcg_gen_not_tl(cpu_T[1], cpu_T[1]); - + tcg_gen_sub_tl(dst, a, b); /* Extended arithmetics. */ - t_gen_subx_carry(dc, cpu_T[0]); + t_gen_subx_carry(dc, dst); break; case CC_OP_MOVE: - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(dst, b); break; case CC_OP_OR: - tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_or_tl(dst, a, b); break; case CC_OP_AND: - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_and_tl(dst, a, b); break; case CC_OP_XOR: - tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_xor_tl(dst, a, b); break; case CC_OP_LSL: - t_gen_lsl(cpu_T[0], cpu_T[0], cpu_T[1]); + t_gen_lsl(dst, a, b); break; case CC_OP_LSR: - t_gen_lsr(cpu_T[0], cpu_T[0], cpu_T[1]); + t_gen_lsr(dst, a, b); break; case CC_OP_ASR: - t_gen_asr(cpu_T[0], cpu_T[0], cpu_T[1]); + t_gen_asr(dst, a, b); break; case CC_OP_NEG: - tcg_gen_neg_tl(cpu_T[0], cpu_T[1]); + tcg_gen_neg_tl(dst, b); /* Extended arithmetics. */ - t_gen_subx_carry(dc, cpu_T[0]); + t_gen_subx_carry(dc, dst); break; case CC_OP_LZ: - t_gen_lz_i32(cpu_T[0], cpu_T[1]); + t_gen_lz_i32(dst, b); break; case CC_OP_BTST: - t_gen_btst(cpu_T[0], cpu_T[1]); - writeback = 0; + t_gen_btst(dst, a, b); break; case CC_OP_MULS: - { - TCGv mof; - mof = tcg_temp_new(TCG_TYPE_TL); - t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]); - t_gen_mov_preg_TN(dc, PR_MOF, mof); - tcg_gen_discard_tl(mof); - } - break; + t_gen_muls(dst, cpu_PR[PR_MOF], a, b); + break; case CC_OP_MULU: - { - TCGv mof; - mof = tcg_temp_new(TCG_TYPE_TL); - t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]); - t_gen_mov_preg_TN(dc, PR_MOF, mof); - tcg_gen_discard_tl(mof); - } - break; + t_gen_mulu(dst, cpu_PR[PR_MOF], a, b); + break; case CC_OP_DSTEP: - t_gen_cris_dstep(cpu_T[0], cpu_T[1]); + t_gen_cris_dstep(dst, a, b); break; case CC_OP_BOUND: { int l1; l1 = gen_new_label(); - tcg_gen_brcond_tl(TCG_COND_LEU, - cpu_T[0], cpu_T[1], l1); - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(dst, a); + tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1); + tcg_gen_mov_tl(dst, b); gen_set_label(l1); } break; case CC_OP_CMP: - tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - /* CRIS flag evaluation needs ~src. */ - tcg_gen_not_tl(cpu_T[1], cpu_T[1]); - + tcg_gen_sub_tl(dst, a, b); /* Extended arithmetics. */ - t_gen_subx_carry(dc, cpu_T[0]); - writeback = 0; + t_gen_subx_carry(dc, dst); break; default: fprintf (logfile, "illegal ALU op.\n"); @@ -838,40 +881,58 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) break; } - if (dc->update_cc) - tcg_gen_mov_tl(cc_src, cpu_T[1]); - if (size == 1) - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff); + tcg_gen_andi_tl(dst, dst, 0xff); else if (size == 2) - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff); + tcg_gen_andi_tl(dst, dst, 0xffff); +} + +static void cris_alu(DisasContext *dc, int op, + TCGv d, TCGv op_a, TCGv op_b, int size) +{ + TCGv tmp; + int writeback; + + writeback = 1; + tmp = cpu_T[0]; + if (op == CC_OP_CMP) + writeback = 0; + else if (size == 4) { + tmp = d; + writeback = 0; + } + + cris_pre_alu_update_cc(dc, op, op_a, op_b, size); + cris_alu_op_exec(dc, op, tmp, op_a, op_b, size); + cris_update_result(dc, tmp); /* Writeback. */ if (writeback) { - if (size == 4) - tcg_gen_mov_tl(cpu_R[rd], cpu_T[0]); - else { - if (size == 1) - tcg_gen_andi_tl(cpu_R[rd], cpu_R[rd], ~0xff); - else - tcg_gen_andi_tl(cpu_R[rd], cpu_R[rd], ~0xffff); - tcg_gen_or_tl(cpu_R[rd], cpu_R[rd], cpu_T[0]); - } + if (size == 1) + tcg_gen_andi_tl(d, d, ~0xff); + else + tcg_gen_andi_tl(d, d, ~0xffff); + tcg_gen_or_tl(d, d, tmp); } - if (dc->update_cc) - tcg_gen_mov_tl(cc_result, cpu_T[0]); } static int arith_cc(DisasContext *dc) { if (dc->update_cc) { switch (dc->cc_op) { + case CC_OP_ADDC: return 1; case CC_OP_ADD: return 1; case CC_OP_SUB: return 1; + case CC_OP_DSTEP: return 1; case CC_OP_LSL: return 1; case CC_OP_LSR: return 1; case CC_OP_ASR: return 1; case CC_OP_CMP: return 1; + case CC_OP_NEG: return 1; + case CC_OP_OR: return 1; + case CC_OP_XOR: return 1; + case CC_OP_MULU: return 1; + case CC_OP_MULS: return 1; default: return 0; } @@ -893,7 +954,7 @@ static void gen_tst_cc (DisasContext *dc, int cond) * When this function is done, T0 should be non-zero if the condition * code is true. */ - arith_opt = arith_cc(dc) && !dc->flags_live; + arith_opt = arith_cc(dc) && !dc->flags_uptodate; switch (cond) { case CC_EQ: if (arith_opt) { @@ -982,7 +1043,7 @@ static void gen_tst_cc (DisasContext *dc, int cond) tcg_gen_and_tl(cpu_T[0], tmp, cpu_T[0]); tcg_gen_andi_tl(cpu_T[0], cpu_T[0], Z_FLAG); - tcg_gen_discard_tl(tmp); + tcg_temp_free(tmp); } break; case CC_GE: @@ -1022,8 +1083,8 @@ static void gen_tst_cc (DisasContext *dc, int cond) tcg_gen_and_tl(cpu_T[0], z, n); tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 2); - tcg_gen_discard_tl(n); - tcg_gen_discard_tl(z); + tcg_temp_free(n); + tcg_temp_free(z); } break; case CC_LE: @@ -1043,8 +1104,8 @@ static void gen_tst_cc (DisasContext *dc, int cond) tcg_gen_or_tl(cpu_T[0], z, n); tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 2); - tcg_gen_discard_tl(n); - tcg_gen_discard_tl(z); + tcg_temp_free(n); + tcg_temp_free(z); } break; case CC_P: @@ -1089,7 +1150,6 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr, { int mem_index = cpu_mmu_index(dc->env); - cris_evaluate_flags(dc); if (size == 1) { if (sign) tcg_gen_qemu_ld8s(dst, addr, mem_index); @@ -1103,7 +1163,7 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr, tcg_gen_qemu_ld16u(dst, addr, mem_index); } else { - tcg_gen_qemu_ld32s(dst, addr, mem_index); + tcg_gen_qemu_ld32u(dst, addr, mem_index); } } @@ -1112,8 +1172,6 @@ void gen_store (DisasContext *dc, TCGv addr, TCGv val, { int mem_index = cpu_mmu_index(dc->env); - cris_evaluate_flags(dc); - /* Remember, operands are flipped. CRIS has reversed order. */ if (size == 1) tcg_gen_qemu_st8(val, addr, mem_index); @@ -1129,7 +1187,7 @@ static inline void t_gen_sext(TCGv d, TCGv s, int size) tcg_gen_ext8s_i32(d, s); else if (size == 2) tcg_gen_ext16s_i32(d, s); - else + else if(d != s) tcg_gen_mov_tl(d, s); } @@ -1139,7 +1197,7 @@ static inline void t_gen_zext(TCGv d, TCGv s, int size) tcg_gen_ext8u_i32(d, s); else if (size == 2) tcg_gen_ext16u_i32(d, s); - else + else if (d != s) tcg_gen_mov_tl(d, s); } @@ -1158,12 +1216,12 @@ static char memsize_char(int size) } #endif -static unsigned int memsize_z(DisasContext *dc) +static inline unsigned int memsize_z(DisasContext *dc) { return dc->zsize + 1; } -static unsigned int memsize_zz(DisasContext *dc) +static inline unsigned int memsize_zz(DisasContext *dc) { switch (dc->zzsize) { @@ -1180,13 +1238,13 @@ static inline void do_postinc (DisasContext *dc, int size) tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size); } -static void dec_prep_move_r(DisasContext *dc, int rs, int rd, - int size, int s_ext) +static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd, + int size, int s_ext, TCGv dst) { if (s_ext) - t_gen_sext(cpu_T[1], cpu_R[rs], size); + t_gen_sext(dst, cpu_R[rs], size); else - t_gen_zext(cpu_T[1], cpu_R[rs], size); + t_gen_zext(dst, cpu_R[rs], size); } /* Prepare T0 and T1 for a register alu operation. @@ -1195,7 +1253,7 @@ static void dec_prep_move_r(DisasContext *dc, int rs, int rd, static void dec_prep_alu_r(DisasContext *dc, int rs, int rd, int size, int s_ext) { - dec_prep_move_r(dc, rs, rd, size, s_ext); + dec_prep_move_r(dc, rs, rd, size, s_ext, cpu_T[1]); if (s_ext) t_gen_sext(cpu_T[0], cpu_R[rd], size); @@ -1203,7 +1261,8 @@ static void dec_prep_alu_r(DisasContext *dc, int rs, int rd, t_gen_zext(cpu_T[0], cpu_R[rd], size); } -static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize) +static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize, + TCGv dst) { unsigned int rs, rd; uint32_t imm; @@ -1237,14 +1296,15 @@ static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize) DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n", imm, rd, s_ext, memsize)); - tcg_gen_movi_tl(cpu_T[1], imm); + tcg_gen_movi_tl(dst, imm); dc->postinc = 0; } else { - gen_load(dc, cpu_T[1], cpu_R[rs], memsize, 0); + cris_flush_cc_state(dc); + gen_load(dc, dst, cpu_R[rs], memsize, 0); if (s_ext) - t_gen_sext(cpu_T[1], cpu_T[1], memsize); + t_gen_sext(dst, dst, memsize); else - t_gen_zext(cpu_T[1], cpu_T[1], memsize); + t_gen_zext(dst, dst, memsize); } return insn_len; } @@ -1256,7 +1316,7 @@ static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize) { int insn_len; - insn_len = dec_prep_move_m(dc, s_ext, memsize); + insn_len = dec_prep_move_m(dc, s_ext, memsize, cpu_T[1]); /* put dest in T0. */ tcg_gen_mov_tl(cpu_T[0], cpu_R[dc->op2]); @@ -1317,10 +1377,9 @@ static unsigned int dec_addq(DisasContext *dc) dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); cris_cc_mask(dc, CC_MASK_NZVC); - /* Fetch register operand, */ - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - tcg_gen_movi_tl(cpu_T[1], dc->op1); - crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4); + + cris_alu(dc, CC_OP_ADD, + cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); return 2; } static unsigned int dec_moveq(DisasContext *dc) @@ -1341,10 +1400,8 @@ static unsigned int dec_subq(DisasContext *dc) DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); - /* Fetch register operand, */ - tcg_gen_mov_tl(cpu_T[0], cpu_R[dc->op2]); - tcg_gen_movi_tl(cpu_T[1], dc->op1); - crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); + cris_alu(dc, CC_OP_SUB, + cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); return 2; } static unsigned int dec_cmpq(DisasContext *dc) @@ -1355,9 +1412,9 @@ static unsigned int dec_cmpq(DisasContext *dc) DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - tcg_gen_movi_tl(cpu_T[1], imm); - crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4); + + cris_alu(dc, CC_OP_CMP, + cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4); return 2; } static unsigned int dec_andq(DisasContext *dc) @@ -1368,9 +1425,9 @@ static unsigned int dec_andq(DisasContext *dc) DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - tcg_gen_movi_tl(cpu_T[1], imm); - crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4); + + cris_alu(dc, CC_OP_AND, + cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4); return 2; } static unsigned int dec_orq(DisasContext *dc) @@ -1380,9 +1437,9 @@ static unsigned int dec_orq(DisasContext *dc) imm = sign_extend(dc->op1, 5); DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - tcg_gen_movi_tl(cpu_T[1], imm); - crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4); + + cris_alu(dc, CC_OP_OR, + cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4); return 2; } static unsigned int dec_btstq(DisasContext *dc) @@ -1391,13 +1448,13 @@ static unsigned int dec_btstq(DisasContext *dc) DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - tcg_gen_movi_tl(cpu_T[1], dc->op1); - crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); + t_gen_mov_TN_reg(cpu_T[0], dc->op2); + cris_alu(dc, CC_OP_BTST, + cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); cris_update_cc_op(dc, CC_OP_FLAGS, 4); t_gen_mov_preg_TN(dc, PR_CCS, cpu_T[0]); - dc->flags_live = 1; + dc->flags_uptodate = 1; return 2; } static unsigned int dec_asrq(DisasContext *dc) @@ -1405,9 +1462,10 @@ static unsigned int dec_asrq(DisasContext *dc) dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - tcg_gen_movi_tl(cpu_T[1], dc->op1); - crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4); + + cris_alu(dc, CC_OP_ASR, + cpu_R[dc->op2], + cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); return 2; } static unsigned int dec_lslq(DisasContext *dc) @@ -1416,9 +1474,10 @@ static unsigned int dec_lslq(DisasContext *dc) DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - tcg_gen_movi_tl(cpu_T[1], dc->op1); - crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4); + + cris_alu(dc, CC_OP_LSL, + cpu_R[dc->op2], + cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); return 2; } static unsigned int dec_lsrq(DisasContext *dc) @@ -1427,9 +1486,10 @@ static unsigned int dec_lsrq(DisasContext *dc) DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - tcg_gen_movi_tl(cpu_T[1], dc->op1); - crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4); + + cris_alu(dc, CC_OP_LSR, + cpu_R[dc->op2], + cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); return 2; } @@ -1441,8 +1501,19 @@ static unsigned int dec_move_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - dec_prep_move_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size); + if (size == 4) { + dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]); + cris_cc_mask(dc, CC_MASK_NZ); + cris_update_cc_op(dc, CC_OP_MOVE, 4); + cris_update_cc_x(dc); + cris_update_result(dc, cpu_R[dc->op2]); + } + else { + dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op2], + cpu_R[dc->op2], cpu_T[1], size); + } return 2; } @@ -1480,7 +1551,10 @@ static unsigned int dec_and_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_AND, dc->op2, size); + + cris_alu(dc, CC_OP_AND, + cpu_R[dc->op2], + cpu_R[dc->op2], cpu_T[1], size); return 2; } @@ -1490,7 +1564,8 @@ static unsigned int dec_lz_r(DisasContext *dc) dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); - crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4); + cris_alu(dc, CC_OP_LZ, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); return 2; } @@ -1503,7 +1578,9 @@ static unsigned int dec_lsl_r(DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63); - crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size); + + cris_alu(dc, CC_OP_LSL, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); return 2; } @@ -1516,7 +1593,9 @@ static unsigned int dec_lsr_r(DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63); - crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size); + + cris_alu(dc, CC_OP_LSR, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); return 2; } @@ -1529,7 +1608,9 @@ static unsigned int dec_asr_r(DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1); tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63); - crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size); + + cris_alu(dc, CC_OP_ASR, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); return 2; } @@ -1541,8 +1622,9 @@ static unsigned int dec_muls_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZV); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1); - t_gen_sext(cpu_T[0], cpu_T[0], size); - crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4); + + cris_alu(dc, CC_OP_MULS, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); return 2; } @@ -1554,8 +1636,9 @@ static unsigned int dec_mulu_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZV); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - t_gen_zext(cpu_T[0], cpu_T[0], size); - crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4); + + cris_alu(dc, CC_OP_MULU, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); return 2; } @@ -1564,9 +1647,8 @@ static unsigned int dec_dstep_r(DisasContext *dc) { DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[1], dc->op1); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4); + cris_alu(dc, CC_OP_DSTEP, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4); return 2; } @@ -1578,7 +1660,9 @@ static unsigned int dec_xor_r(DisasContext *dc) BUG_ON(size != 4); /* xor is dword. */ cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4); + + cris_alu(dc, CC_OP_XOR, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); return 2; } @@ -1588,11 +1672,9 @@ static unsigned int dec_bound_r(DisasContext *dc) DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - /* TODO: needs optmimization. */ - dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - /* rd should be 4. */ - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4); + dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]); + cris_alu(dc, CC_OP_BOUND, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); return 2; } @@ -1603,7 +1685,9 @@ static unsigned int dec_cmp_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size); + + cris_alu(dc, CC_OP_CMP, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); return 2; } @@ -1614,14 +1698,15 @@ static unsigned int dec_abs_r(DisasContext *dc) DIS(fprintf (logfile, "abs $r%u, $r%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0); + dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0, cpu_T[1]); /* TODO: consider a branch free approach. */ l1 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_GE, cpu_T[1], 0, l1); tcg_gen_neg_tl(cpu_T[1], cpu_T[1]); gen_set_label(l1); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); return 2; } @@ -1632,7 +1717,9 @@ static unsigned int dec_add_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size); + + cris_alu(dc, CC_OP_ADD, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); return 2; } @@ -1643,7 +1730,8 @@ static unsigned int dec_addc_r(DisasContext *dc) cris_evaluate_flags(dc); cris_cc_mask(dc, CC_MASK_NZVC); dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); - crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4); + cris_alu(dc, CC_OP_ADDC, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); return 2; } @@ -1653,9 +1741,8 @@ static unsigned int dec_mcp_r(DisasContext *dc) dc->op2, dc->op1)); cris_evaluate_flags(dc); cris_cc_mask(dc, CC_MASK_RNZV); - t_gen_mov_TN_reg(cpu_T[0], dc->op1); - t_gen_mov_TN_preg(cpu_T[1], dc->op2); - crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4); + cris_alu(dc, CC_OP_MCP, + cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4); return 2; } @@ -1693,8 +1780,9 @@ static unsigned int dec_swap_r(DisasContext *dc) t_gen_swapb(cpu_T[0], cpu_T[0]); if (dc->op2 & 1) t_gen_swapr(cpu_T[0], cpu_T[0]); - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[0], 4); + return 2; } @@ -1705,7 +1793,9 @@ static unsigned int dec_or_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_OR, dc->op2, size); + + cris_alu(dc, CC_OP_OR, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); return 2; } @@ -1714,10 +1804,8 @@ static unsigned int dec_addi_r(DisasContext *dc) DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n", memsize_char(memsize_zz(dc)), dc->op2, dc->op1)); cris_cc_mask(dc, 0); - dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); - t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize)); - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - t_gen_mov_reg_TN(dc->op1, cpu_T[0]); + tcg_gen_shl_tl(cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->zzsize)); + tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[0]); return 2; } @@ -1726,11 +1814,8 @@ static unsigned int dec_addi_acr(DisasContext *dc) DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n", memsize_char(memsize_zz(dc)), dc->op2, dc->op1)); cris_cc_mask(dc, 0); - dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); - t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize)); - - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - t_gen_mov_reg_TN(R_ACR, cpu_T[0]); + tcg_gen_shl_tl(cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->zzsize)); + tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], cpu_T[0]); return 2; } @@ -1741,7 +1826,9 @@ static unsigned int dec_neg_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size); + + cris_alu(dc, CC_OP_NEG, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); return 2; } @@ -1751,11 +1838,12 @@ static unsigned int dec_btst_r(DisasContext *dc) dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); - crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); + cris_alu(dc, CC_OP_BTST, + cpu_T[0], cpu_T[0], cpu_T[1], 4); cris_update_cc_op(dc, CC_OP_FLAGS, 4); t_gen_mov_preg_TN(dc, PR_CCS, cpu_T[0]); - dc->flags_live = 1; + dc->flags_uptodate = 1; return 2; } @@ -1766,7 +1854,8 @@ static unsigned int dec_sub_r(DisasContext *dc) memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size); + cris_alu(dc, CC_OP_SUB, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); return 2; } @@ -1779,8 +1868,9 @@ static unsigned int dec_movu_r(DisasContext *dc) dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - dec_prep_move_r(dc, dc->op1, dc->op2, size, 0); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); + dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); return 2; } @@ -1795,8 +1885,9 @@ static unsigned int dec_movs_r(DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); t_gen_mov_TN_reg(cpu_T[0], dc->op1); /* Size can only be qi or hi. */ - t_gen_sext(cpu_T[1], cpu_T[0], size); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); + t_gen_sext(cpu_T[1], cpu_R[dc->op1], size); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); return 2; } @@ -1809,11 +1900,10 @@ static unsigned int dec_addu_r(DisasContext *dc) dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); - t_gen_mov_TN_reg(cpu_T[1], dc->op1); /* Size can only be qi or hi. */ - t_gen_zext(cpu_T[1], cpu_T[1], size); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4); + t_gen_zext(cpu_T[1], cpu_R[dc->op1], size); + cris_alu(dc, CC_OP_ADD, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); return 2; } @@ -1826,12 +1916,10 @@ static unsigned int dec_adds_r(DisasContext *dc) dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); - t_gen_mov_TN_reg(cpu_T[1], dc->op1); /* Size can only be qi or hi. */ - t_gen_sext(cpu_T[1], cpu_T[1], size); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - - crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4); + t_gen_sext(cpu_T[1], cpu_R[dc->op1], size); + cris_alu(dc, CC_OP_ADD, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); return 2; } @@ -1844,11 +1932,10 @@ static unsigned int dec_subu_r(DisasContext *dc) dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); - t_gen_mov_TN_reg(cpu_T[1], dc->op1); /* Size can only be qi or hi. */ - t_gen_zext(cpu_T[1], cpu_T[1], size); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); + t_gen_zext(cpu_T[1], cpu_R[dc->op1], size); + cris_alu(dc, CC_OP_SUB, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); return 2; } @@ -1861,11 +1948,10 @@ static unsigned int dec_subs_r(DisasContext *dc) dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); - t_gen_mov_TN_reg(cpu_T[1], dc->op1); /* Size can only be qi or hi. */ - t_gen_sext(cpu_T[1], cpu_T[1], size); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); - crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); + t_gen_sext(cpu_T[1], cpu_R[dc->op1], size); + cris_alu(dc, CC_OP_SUB, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); return 2; } @@ -1879,6 +1965,7 @@ static unsigned int dec_setclrf(DisasContext *dc) DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags)); if (set && flags == 0) { DIS(fprintf (logfile, "nop\n")); + return 2; } else if (!set && (flags & 0x20)) { DIS(fprintf (logfile, "di\n")); } @@ -1889,13 +1976,16 @@ static unsigned int dec_setclrf(DisasContext *dc) } if (set && (flags & X_FLAG)) { - dc->flagx_live = 1; - dc->flags_x = 1; + dc->flagx_known = 1; + dc->flags_x = X_FLAG; + } else { + dc->flagx_known = 0; } /* Simply decode the flags. */ cris_evaluate_flags (dc); cris_update_cc_op(dc, CC_OP_FLAGS, 4); + cris_update_cc_x(dc); tcg_gen_movi_tl(cc_op, dc->cc_op); if (set) { @@ -1910,7 +2000,7 @@ static unsigned int dec_setclrf(DisasContext *dc) else tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags); - dc->flags_live = 1; + dc->flags_uptodate = 1; dc->clear_x = 0; return 2; } @@ -1953,7 +2043,7 @@ static unsigned int dec_move_rp(DisasContext *dc) t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]); if (dc->op2 == PR_CCS) { cris_update_cc_op(dc, CC_OP_FLAGS, 4); - dc->flags_live = 1; + dc->flags_uptodate = 1; } return 2; } @@ -1970,7 +2060,9 @@ static unsigned int dec_move_pr(DisasContext *dc) t_gen_mov_TN_preg(cpu_T[1], dc->op2); } else t_gen_mov_TN_preg(cpu_T[1], dc->op2); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[1], + preg_sizes[dc->op2]); return 2; } @@ -1983,9 +2075,19 @@ static unsigned int dec_move_mr(DisasContext *dc) dc->op1, dc->postinc ? "+]" : "]", dc->op2)); - insn_len = dec_prep_move_m(dc, 0, memsize); - cris_cc_mask(dc, CC_MASK_NZ); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize); + if (memsize == 4) { + insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]); + cris_cc_mask(dc, CC_MASK_NZ); + cris_update_cc_op(dc, CC_OP_MOVE, 4); + cris_update_cc_x(dc); + cris_update_result(dc, cpu_R[dc->op2]); + } + else { + insn_len = dec_prep_move_m(dc, 0, memsize, cpu_T[1]); + cris_cc_mask(dc, CC_MASK_NZ); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], memsize); + } do_postinc(dc, memsize); return insn_len; } @@ -2002,7 +2104,8 @@ static unsigned int dec_movs_m(DisasContext *dc) /* sign extend. */ insn_len = dec_prep_alu_m(dc, 1, memsize); cris_cc_mask(dc, CC_MASK_NZ); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2019,7 +2122,8 @@ static unsigned int dec_addu_m(DisasContext *dc) /* sign extend. */ insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4); + cris_alu(dc, CC_OP_ADD, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2036,7 +2140,8 @@ static unsigned int dec_adds_m(DisasContext *dc) /* sign extend. */ insn_len = dec_prep_alu_m(dc, 1, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4); + cris_alu(dc, CC_OP_ADD, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2053,7 +2158,8 @@ static unsigned int dec_subu_m(DisasContext *dc) /* sign extend. */ insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); + cris_alu(dc, CC_OP_SUB, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2070,7 +2176,8 @@ static unsigned int dec_subs_m(DisasContext *dc) /* sign extend. */ insn_len = dec_prep_alu_m(dc, 1, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); + cris_alu(dc, CC_OP_SUB, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2087,7 +2194,8 @@ static unsigned int dec_movu_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZ); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); + cris_alu(dc, CC_OP_MOVE, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2103,7 +2211,8 @@ static unsigned int dec_cmpu_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4); + cris_alu(dc, CC_OP_CMP, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2119,7 +2228,9 @@ static unsigned int dec_cmps_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 1, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc)); + cris_alu(dc, CC_OP_CMP, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], + memsize_zz(dc)); do_postinc(dc, memsize); return insn_len; } @@ -2135,7 +2246,9 @@ static unsigned int dec_cmp_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc)); + cris_alu(dc, CC_OP_CMP, + cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], + memsize_zz(dc)); do_postinc(dc, memsize); return insn_len; } @@ -2155,9 +2268,9 @@ static unsigned int dec_test_m(DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3); - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); - tcg_gen_movi_tl(cpu_T[1], 0); - crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc)); + cris_alu(dc, CC_OP_CMP, + cpu_R[dc->op2], cpu_T[1], tcg_const_tl(0), + memsize_zz(dc)); do_postinc(dc, memsize); return insn_len; } @@ -2173,7 +2286,9 @@ static unsigned int dec_and_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZ); - crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc)); + cris_alu(dc, CC_OP_AND, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], + memsize_zz(dc)); do_postinc(dc, memsize); return insn_len; } @@ -2189,7 +2304,9 @@ static unsigned int dec_add_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc)); + cris_alu(dc, CC_OP_ADD, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], + memsize_zz(dc)); do_postinc(dc, memsize); return insn_len; } @@ -2205,7 +2322,8 @@ static unsigned int dec_addo_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 1, memsize); cris_cc_mask(dc, 0); - crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4); + cris_alu(dc, CC_OP_ADD, + cpu_R[R_ACR], cpu_T[0], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2221,7 +2339,8 @@ static unsigned int dec_bound_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZ); - crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4); + cris_alu(dc, CC_OP_BOUND, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); do_postinc(dc, memsize); return insn_len; } @@ -2236,7 +2355,8 @@ static unsigned int dec_addc_mr(DisasContext *dc) cris_evaluate_flags(dc); insn_len = dec_prep_alu_m(dc, 0, 4); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4); + cris_alu(dc, CC_OP_ADDC, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); do_postinc(dc, 4); return insn_len; } @@ -2252,7 +2372,8 @@ static unsigned int dec_sub_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZVC); - crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize); + cris_alu(dc, CC_OP_SUB, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], memsize); do_postinc(dc, memsize); return insn_len; } @@ -2268,7 +2389,8 @@ static unsigned int dec_or_m(DisasContext *dc) insn_len = dec_prep_alu_m(dc, 0, memsize); cris_cc_mask(dc, CC_MASK_NZ); - crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc)); + cris_alu(dc, CC_OP_OR, + cpu_R[dc->op2], cpu_T[0], cpu_T[1], memsize_zz(dc)); do_postinc(dc, memsize); return insn_len; } @@ -2316,6 +2438,7 @@ static unsigned int dec_move_pm(DisasContext *dc) if (dc->op2 == PR_CCS) cris_evaluate_flags(dc); t_gen_mov_TN_preg(cpu_T[1], dc->op2); + cris_flush_cc_state(dc); gen_store(dc, cpu_R[dc->op1], cpu_T[1], memsize); cris_cc_mask(dc, 0); @@ -2333,6 +2456,7 @@ static unsigned int dec_movem_mr(DisasContext *dc) dc->postinc ? "+]" : "]", dc->op2)); /* fetch the address into T0 and T1. */ + cris_flush_cc_state(dc); for (i = 0; i <= dc->op2; i++) { tmp[i] = tcg_temp_new(TCG_TYPE_TL); /* Perform the load onto regnum i. Always dword wide. */ @@ -2342,7 +2466,7 @@ static unsigned int dec_movem_mr(DisasContext *dc) for (i = 0; i <= dc->op2; i++) { tcg_gen_mov_tl(cpu_R[i], tmp[i]); - tcg_gen_discard_tl(tmp[i]); + tcg_temp_free(tmp[i]); } /* writeback the updated pointer value. */ @@ -2356,20 +2480,27 @@ static unsigned int dec_movem_mr(DisasContext *dc) static unsigned int dec_movem_rm(DisasContext *dc) { + TCGv tmp; int i; DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1, dc->postinc ? "+]" : "]")); + cris_flush_cc_state(dc); + + tmp = tcg_temp_new(TCG_TYPE_TL); + tcg_gen_movi_tl(tmp, 4); + tcg_gen_mov_tl(cpu_T[0], cpu_R[dc->op1]); for (i = 0; i <= dc->op2; i++) { /* Displace addr. */ - tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4); /* Perform the store. */ gen_store(dc, cpu_T[0], cpu_R[i], 4); + tcg_gen_add_tl(cpu_T[0], cpu_T[0], tmp); } if (dc->postinc) - tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4); + tcg_gen_mov_tl(cpu_R[dc->op1], cpu_T[0]); cris_cc_mask(dc, 0); + tcg_temp_free(tmp); return 2; } @@ -2383,6 +2514,7 @@ static unsigned int dec_move_rm(DisasContext *dc) memsize, dc->op2, dc->op1)); /* prepare store. */ + cris_flush_cc_state(dc); gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize); if (dc->postinc) @@ -2396,8 +2528,7 @@ static unsigned int dec_lapcq(DisasContext *dc) DIS(fprintf (logfile, "lapcq %x, $r%u\n", dc->pc + dc->op1*2, dc->op2)); cris_cc_mask(dc, 0); - tcg_gen_movi_tl(cpu_T[1], dc->pc + dc->op1 * 2); - crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); + tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2); return 2; } @@ -2443,8 +2574,7 @@ static unsigned int dec_jas_r(DisasContext *dc) tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]); if (dc->op2 > 15) abort(); - tcg_gen_movi_tl(cpu_T[0], dc->pc + 4); - tcg_gen_mov_tl(cpu_PR[dc->op2], cpu_T[0]); + t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4)); cris_prepare_dyn_jmp(dc); return 2; @@ -2827,12 +2957,15 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, dc->ppc = pc_start; dc->pc = pc_start; dc->singlestep_enabled = env->singlestep_enabled; - dc->flags_live = 1; - dc->flagx_live = 0; - dc->flags_x = 0; + dc->flags_uptodate = 1; + dc->flagx_known = 1; + dc->flags_x = tb->flags & X_FLAG; + dc->cc_x_uptodate = 0; dc->cc_mask = 0; dc->update_cc = 0; + cris_update_cc_op(dc, CC_OP_FLAGS, 4); + dc->cc_size_uptodate = -1; /* Decode TB flags. */ dc->user = tb->flags & U_FLAG; @@ -2841,7 +2974,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "srch=%d pc=%x %x bt=%x ds=%lld ccs=%x\n" - "pid=%x usp=%x dbg=%x %x %x\n" + "pid=%x usp=%x\n" "%x.%x.%x.%x\n" "%x.%x.%x.%x\n" "%x.%x.%x.%x\n" @@ -2850,7 +2983,6 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, env->btarget, tb->flags & 7, env->pregs[PR_CCS], env->pregs[PR_PID], env->pregs[PR_USP], - env->debug1, env->debug2, env->debug3, env->regs[0], env->regs[1], env->regs[2], env->regs[3], env->regs[4], env->regs[5], env->regs[6], env->regs[7], env->regs[8], env->regs[9], @@ -2890,6 +3022,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, } dc->clear_x = 1; + if (unlikely(loglevel & CPU_LOG_TB_OP)) + tcg_gen_debug_insn_start(dc->pc); insn_len = cris_decoder(dc); dc->ppc = dc->pc; dc->pc += insn_len; @@ -2996,12 +3130,11 @@ void cpu_dump_state (CPUState *env, FILE *f, return; cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n" - "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n" - "debug=%x %x %x\n", + "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n", env->pc, env->pregs[PR_CCS], env->btaken, env->btarget, env->cc_op, - env->cc_src, env->cc_dest, env->cc_result, env->cc_mask, - env->debug1, env->debug2, env->debug3); + env->cc_src, env->cc_dest, env->cc_result, env->cc_mask); + for (i = 0; i < 16; i++) { cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]); @@ -3049,38 +3182,40 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); #endif - cc_src = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + cc_x = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + offsetof(CPUState, cc_x), "cc_x"); + cc_src = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, offsetof(CPUState, cc_src), "cc_src"); - cc_dest = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, - offsetof(CPUState, cc_dest), + cc_dest = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + offsetof(CPUState, cc_dest), "cc_dest"); - cc_result = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, - offsetof(CPUState, cc_result), + cc_result = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + offsetof(CPUState, cc_result), "cc_result"); - cc_op = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + cc_op = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, offsetof(CPUState, cc_op), "cc_op"); - cc_size = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, - offsetof(CPUState, cc_size), + cc_size = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + offsetof(CPUState, cc_size), "cc_size"); - cc_mask = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + cc_mask = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, offsetof(CPUState, cc_mask), "cc_mask"); env_pc = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, - offsetof(CPUState, pc), - "pc"); - env_btarget = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, - offsetof(CPUState, btarget), - "btarget"); + offsetof(CPUState, pc), + "pc"); + env_btarget = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + offsetof(CPUState, btarget), + "btarget"); for (i = 0; i < 16; i++) { - cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, - offsetof(CPUState, regs[i]), + cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + offsetof(CPUState, regs[i]), regnames[i]); } for (i = 0; i < 16; i++) { - cpu_PR[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, - offsetof(CPUState, pregs[i]), + cpu_PR[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + offsetof(CPUState, pregs[i]), pregnames[i]); } @@ -3089,7 +3224,6 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) TCG_HELPER(helper_dump); TCG_HELPER(helper_dummy); - TCG_HELPER(helper_tlb_flush); TCG_HELPER(helper_tlb_flush_pid); TCG_HELPER(helper_movl_sreg_reg); TCG_HELPER(helper_movl_reg_sreg); @@ -3102,6 +3236,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) TCG_HELPER(helper_evaluate_flags_move_4); TCG_HELPER(helper_evaluate_flags_move_2); TCG_HELPER(helper_evaluate_flags); + TCG_HELPER(helper_top_evaluate_flags); cpu_reset(env); return env;