qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [4376] CRIS: More TCG conversion.


From: Edgar E. Iglesias
Subject: [Qemu-devel] [4376] CRIS: More TCG conversion.
Date: Wed, 07 May 2008 15:24:55 +0000

Revision: 4376
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4376
Author:   edgar_igl
Date:     2008-05-07 15:24:53 +0000 (Wed, 07 May 2008)

Log Message:
-----------
CRIS: More TCG conversion.
* Convert moves to/from support function regs (including TLB updates) to TCG.
* SCC no longer requires T0 to strictly be 0 or 1, relaxed to 0 or non-zero.
* Convert the the condition code evaluation to TCG.
* Convert rfe into a helper and TCG.
* Convert evaluate_bcc and setf to TCG.
* Convert clrf to TCG.
* Convert CRIS exception raising to TCG.
* Convert btst to TCG.

Modified Paths:
--------------
    trunk/target-cris/helper.h
    trunk/target-cris/mmu.c
    trunk/target-cris/mmu.h
    trunk/target-cris/op_helper.c
    trunk/target-cris/translate.c

Modified: trunk/target-cris/helper.h
===================================================================
--- trunk/target-cris/helper.h  2008-05-07 14:41:37 UTC (rev 4375)
+++ trunk/target-cris/helper.h  2008-05-07 15:24:53 UTC (rev 4376)
@@ -1,11 +1,15 @@
 #define TCG_HELPER_PROTO
-void TCG_HELPER_PROTO helper_tlb_update(uint32_t T0);
+
+void TCG_HELPER_PROTO helper_raise_exception(uint32_t index);
 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);
 void TCG_HELPER_PROTO helper_store(uint32_t a0);
 
+void TCG_HELPER_PROTO helper_movl_sreg_reg (uint32_t sreg, uint32_t reg);
+void TCG_HELPER_PROTO helper_movl_reg_sreg (uint32_t reg, uint32_t sreg);
+
 void TCG_HELPER_PROTO helper_evaluate_flags_muls(void);
 void TCG_HELPER_PROTO helper_evaluate_flags_mulu(void);
 void TCG_HELPER_PROTO helper_evaluate_flags_mcp(void);

Modified: trunk/target-cris/mmu.c
===================================================================
--- trunk/target-cris/mmu.c     2008-05-07 14:41:37 UTC (rev 4375)
+++ trunk/target-cris/mmu.c     2008-05-07 15:24:53 UTC (rev 4376)
@@ -265,7 +265,7 @@
 }
 
 /* Give us the vaddr corresponding to the latest TLB update.  */
-target_ulong cris_mmu_tlb_latest_update(CPUState *env, uint32_t new_lo)
+target_ulong cris_mmu_tlb_latest_update(CPUState *env)
 {
        uint32_t sel = env->sregs[SFR_RW_MM_TLB_SEL];
        uint32_t vaddr;

Modified: trunk/target-cris/mmu.h
===================================================================
--- trunk/target-cris/mmu.h     2008-05-07 14:41:37 UTC (rev 4375)
+++ trunk/target-cris/mmu.h     2008-05-07 15:24:53 UTC (rev 4376)
@@ -11,7 +11,7 @@
        int bf_vec;
 };
 
-target_ulong cris_mmu_tlb_latest_update(CPUState *env, uint32_t new_lo);
+target_ulong cris_mmu_tlb_latest_update(CPUState *env);
 int cris_mmu_translate(struct cris_mmu_result_t *res,
                       CPUState *env, uint32_t vaddr,
                       int rw, int mmu_idx);

Modified: trunk/target-cris/op_helper.c
===================================================================
--- trunk/target-cris/op_helper.c       2008-05-07 14:41:37 UTC (rev 4375)
+++ trunk/target-cris/op_helper.c       2008-05-07 15:24:53 UTC (rev 4376)
@@ -79,20 +79,10 @@
     env = saved_env;
 }
 
-void helper_tlb_update(uint32_t T0)
+void helper_raise_exception(uint32_t index)
 {
-#if !defined(CONFIG_USER_ONLY)
-       uint32_t vaddr;
-       uint32_t srs = env->pregs[PR_SRS];
-
-       if (srs != 1 && srs != 2)
-               return;
-
-       vaddr = cris_mmu_tlb_latest_update(env, T0);
-       D(fprintf(logfile, "flush old_vaddr=%x vaddr=%x T0=%x\n", vaddr, 
-                env->sregs[SFR_R_MM_CAUSE] & TARGET_PAGE_MASK, T0));
-       tlb_flush_page(env, vaddr);
-#endif
+       env->exception_index = index;
+       cpu_loop_exit();
 }
 
 void helper_tlb_flush(void)
@@ -110,13 +100,105 @@
 
 }
 
-/* Only used for debugging at the moment.  */
+void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
+{
+       uint32_t srs;
+       srs = env->pregs[PR_SRS];
+       srs &= 3;
+       env->sregs[srs][sreg] = env->regs[reg];
+
+#if !defined(CONFIG_USER_ONLY)
+       if (srs == 1 || srs == 2) {
+               if (sreg == 6) {
+                       /* Writes to tlb-hi write to mm_cause as a side 
+                          effect.  */
+                       env->sregs[SFR_RW_MM_TLB_HI] = T0;
+                       env->sregs[SFR_R_MM_CAUSE] = T0;
+               }
+               else if (sreg == 5) {
+                       uint32_t set;
+                       uint32_t idx;
+                       uint32_t lo, hi;
+                       uint32_t vaddr;
+
+                       vaddr = cris_mmu_tlb_latest_update(env);
+                       D(fprintf(logfile, "tlb flush vaddr=%x\n", vaddr));
+                       tlb_flush_page(env, vaddr);
+
+                       idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
+                       set >>= 4;
+                       set &= 3;
+
+                       idx &= 15;
+                       /* We've just made a write to tlb_lo.  */
+                       lo = env->sregs[SFR_RW_MM_TLB_LO];
+                       /* Writes are done via r_mm_cause.  */
+                       hi = env->sregs[SFR_R_MM_CAUSE];
+                       env->tlbsets[srs - 1][set][idx].lo = lo;
+                       env->tlbsets[srs - 1][set][idx].hi = hi;
+               }
+       }
+#endif
+}
+
+void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg)
+{
+       uint32_t srs;
+       env->pregs[PR_SRS] &= 3;
+       srs = env->pregs[PR_SRS];
+       
+#if !defined(CONFIG_USER_ONLY)
+       if (srs == 1 || srs == 2)
+       {
+               uint32_t set;
+               uint32_t idx;
+               uint32_t lo, hi;
+
+               idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
+               set >>= 4;
+               set &= 3;
+               idx &= 15;
+
+               /* Update the mirror regs.  */
+               hi = env->tlbsets[srs - 1][set][idx].hi;
+               lo = env->tlbsets[srs - 1][set][idx].lo;
+               env->sregs[SFR_RW_MM_TLB_HI] = hi;
+               env->sregs[SFR_RW_MM_TLB_LO] = lo;
+       }
+#endif
+       env->regs[reg] = env->sregs[srs][sreg];
+       RETURN();
+}
+
+static void cris_ccs_rshift(CPUState *env)
+{
+       uint32_t ccs;
+
+       /* Apply the ccs shift.  */
+       ccs = env->pregs[PR_CCS];
+       ccs = (ccs & 0xc0000000) | ((ccs & 0x0fffffff) >> 10);
+       if (ccs & U_FLAG)
+       {
+               /* Enter user mode.  */
+               env->ksp = env->regs[R_SP];
+               env->regs[R_SP] = env->pregs[PR_USP];
+       }
+
+       env->pregs[PR_CCS] = ccs;
+}
+
 void helper_rfe(void)
 {
        D(fprintf(logfile, "rfe: erp=%x pid=%x ccs=%x btarget=%x\n", 
                 env->pregs[PR_ERP], env->pregs[PR_PID],
                 env->pregs[PR_CCS],
                 env->btarget));
+
+       cris_ccs_rshift(env);
+
+       /* RFE sets the P_FLAG only if the R_FLAG is not set.  */
+       if (!(env->pregs[PR_CCS] & R_FLAG))
+               env->pregs[PR_CCS] |= P_FLAG;
 }
 
 void helper_store(uint32_t a0)
@@ -155,7 +237,6 @@
        env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);
        flags &= env->cc_mask;
        env->pregs[PR_CCS] |= flags;
-       RETURN();
 }
 
 void helper_evaluate_flags_muls(void)
@@ -164,8 +245,7 @@
        uint32_t dst;
        uint32_t res;
        uint32_t flags = 0;
-       /* were gonna have to redo the muls.  */
-       int64_t tmp, t0 ,t1;
+       int64_t tmp;
        int32_t mof;
        int dneg;
 
@@ -173,14 +253,12 @@
        dst = env->cc_dest;
        res = env->cc_result;
 
-
-       /* cast into signed values to make GCC sign extend.  */
-       t0 = (int32_t)src;
-       t1 = (int32_t)dst;
        dneg = ((int32_t)res) < 0;
 
-       tmp = t0 * t1;
-       mof = tmp >> 32;
+       mof = env->pregs[PR_MOF];
+       tmp = mof;
+       tmp <<= 32;
+       tmp |= res;
        if (tmp == 0)
                flags |= Z_FLAG;
        else if (tmp < 0)
@@ -197,21 +275,17 @@
        uint32_t dst;
        uint32_t res;
        uint32_t flags = 0;
-       /* were gonna have to redo the muls.  */
-       uint64_t tmp, t0 ,t1;
+       uint64_t tmp;
        uint32_t mof;
 
        src = env->cc_src;
        dst = env->cc_dest;
        res = env->cc_result;
 
-
-       /* cast into signed values to make GCC sign extend.  */
-       t0 = src;
-       t1 = dst;
-
-       tmp = t0 * t1;
-       mof = tmp >> 32;
+       mof = env->pregs[PR_MOF];
+       tmp = mof;
+       tmp <<= 32;
+       tmp |= res;
        if (tmp == 0)
                flags |= Z_FLAG;
        else if (tmp >> 63)

Modified: trunk/target-cris/translate.c
===================================================================
--- trunk/target-cris/translate.c       2008-05-07 14:41:37 UTC (rev 4375)
+++ trunk/target-cris/translate.c       2008-05-07 15:24:53 UTC (rev 4376)
@@ -223,9 +223,9 @@
        }
 }
 
-static inline void t_gen_mov_TN_im(TCGv tn, int32_t val)
+static inline void t_gen_raise_exception(uint32_t index)
 {
-       tcg_gen_movi_tl(tn, val);
+       tcg_gen_helper_0_1(helper_raise_exception, tcg_const_tl(index));
 }
 
 static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
@@ -375,6 +375,62 @@
        tcg_gen_discard_i32(n);
 }
 
+static void t_gen_btst(TCGv d, TCGv s)
+{
+        TCGv sbit;
+        TCGv bset;
+       int l1;
+
+        /* des ref:
+           The N flag is set according to the selected bit in the dest reg.
+           The Z flag is set if the selected bit and all bits to the right are
+           zero.
+           The X flag is cleared.
+           Other flags are left untouched.
+           The destination reg is not affected.
+
+        unsigned int fz, sbit, bset, mask, masked_t0;
+
+        sbit = T1 & 31;
+        bset = !!(T0 & (1 << sbit));
+        mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
+        masked_t0 = T0 & mask;
+        fz = !(masked_t0 | bset);
+
+        // Clear the X, N and Z flags.
+        T0 = env->pregs[PR_CCS] & ~(X_FLAG | N_FLAG | Z_FLAG);
+        // Set the N and Z flags accordingly.
+        T0 |= (bset << 3) | (fz << 2);
+        */
+
+       l1 = gen_new_label();
+        sbit = tcg_temp_new(TCG_TYPE_TL);
+        bset = 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_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_andi_tl(d, cpu_PR[PR_CCS], ~(X_FLAG | N_FLAG | Z_FLAG));
+       /* or in the N_FLAG.  */
+        tcg_gen_or_tl(d, d, bset);
+       tcg_gen_brcond_tl(TCG_COND_NE, sbit, tcg_const_tl(0), l1);
+       /* or in the Z_FLAG.  */
+       tcg_gen_ori_tl(d, d, Z_FLAG);
+       gen_set_label(l1);
+
+        tcg_gen_discard_tl(sbit);
+        tcg_gen_discard_tl(bset);
+}
+
 static void t_gen_cris_dstep(TCGv d, TCGv s)
 {
        int l1;
@@ -738,7 +794,7 @@
                        t_gen_lz_i32(cpu_T[0], cpu_T[1]);
                        break;
                case CC_OP_BTST:
-                       gen_op_btst_T0_T1();
+                       t_gen_btst(cpu_T[0], cpu_T[1]);
                        writeback = 0;
                        break;
                case CC_OP_MULS:
@@ -846,83 +902,172 @@
        int arith_opt;
 
        /* TODO: optimize more condition codes.  */
+
+       /*
+        * If the flags are live, we've gotta look into the bits of CCS.
+        * Otherwise, if we just did an arithmetic operation we try to
+        * evaluate the condition code faster.
+        *
+        * When this function is done, T0 should be non-zero if the condition
+        * code is true.
+        */
        arith_opt = arith_cc(dc) && !dc->flags_live;
        switch (cond) {
                case CC_EQ:
-                       if (arith_opt)
-                               gen_op_tst_cc_eq_fast ();
+                       if (arith_opt) {
+                               /* If cc_result is zero, T0 should be 
+                                  non-zero otherwise T0 should be zero.  */
+                               int l1;
+                               l1 = gen_new_label();
+                               tcg_gen_movi_tl(cpu_T[0], 0);
+                               tcg_gen_brcond_tl(TCG_COND_NE, cc_result, 
+                                                 tcg_const_tl(0), l1);
+                               tcg_gen_movi_tl(cpu_T[0], 1);
+                               gen_set_label(l1);
+                       }
                        else {
                                cris_evaluate_flags(dc);
-                               gen_op_tst_cc_eq ();
+                               tcg_gen_andi_tl(cpu_T[0], 
+                                               cpu_PR[PR_CCS], Z_FLAG);
                        }
                        break;
                case CC_NE:
                        if (arith_opt)
-                               gen_op_tst_cc_ne_fast ();
+                               tcg_gen_mov_tl(cpu_T[0], cc_result);
                        else {
                                cris_evaluate_flags(dc);
-                               gen_op_tst_cc_ne ();
+                               tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
+                                               Z_FLAG);
+                               tcg_gen_andi_tl(cpu_T[0], cpu_T[0], Z_FLAG);
                        }
                        break;
                case CC_CS:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_cs ();
+                       tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], C_FLAG);
                        break;
                case CC_CC:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_cc ();
+                       tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
+                                       C_FLAG);
+                       tcg_gen_andi_tl(cpu_T[0], cpu_T[0], C_FLAG);
                        break;
                case CC_VS:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_vs ();
+                       tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], V_FLAG);
                        break;
                case CC_VC:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_vc ();
+                       tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
+                                       V_FLAG);
+                       tcg_gen_andi_tl(cpu_T[0], cpu_T[0], V_FLAG);
                        break;
                case CC_PL:
                        if (arith_opt)
-                               gen_op_tst_cc_pl_fast ();
+                               tcg_gen_shli_tl(cpu_T[0], cc_result, 31);
                        else {
                                cris_evaluate_flags(dc);
-                               gen_op_tst_cc_pl ();
+                               tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS],
+                                               N_FLAG);
+                               tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
                        }
                        break;
                case CC_MI:
-                       if (arith_opt)
-                               gen_op_tst_cc_mi_fast ();
+                       if (arith_opt) {
+                               tcg_gen_shli_tl(cpu_T[0], cc_result, 31);
+                               tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1);
+                       }
                        else {
                                cris_evaluate_flags(dc);
-                               gen_op_tst_cc_mi ();
+                               tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS],
+                                               N_FLAG);
                        }
                        break;
                case CC_LS:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_ls ();
+                       tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS],
+                                       C_FLAG | Z_FLAG);
                        break;
                case CC_HI:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_hi ();
+                       {
+                               TCGv tmp;
+
+                               tmp = tcg_temp_new(TCG_TYPE_TL);
+                               tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
+                                               C_FLAG | Z_FLAG);
+                               /* Overlay the C flag on top of the Z.  */
+                               tcg_gen_shli_tl(cpu_T[0], tmp, 2);
+                               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);
+                       }
                        break;
                case CC_GE:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_ge ();
+                       /* Overlay the V flag on top of the N.  */
+                       tcg_gen_shli_tl(cpu_T[0], cpu_PR[PR_CCS], 2);
+                       tcg_gen_xor_tl(cpu_T[0],
+                                      cpu_PR[PR_CCS], cpu_T[0]);
+                       tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
+                       tcg_gen_xori_tl(cpu_T[0], cpu_T[0], N_FLAG);
                        break;
                case CC_LT:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_lt ();
+                       /* Overlay the V flag on top of the N.  */
+                       tcg_gen_shli_tl(cpu_T[0], cpu_PR[PR_CCS], 2);
+                       tcg_gen_xor_tl(cpu_T[0],
+                                      cpu_PR[PR_CCS], cpu_T[0]);
+                       tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG);
                        break;
                case CC_GT:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_gt ();
+                       {
+                               TCGv n, z;
+
+                               n = tcg_temp_new(TCG_TYPE_TL);
+                               z = tcg_temp_new(TCG_TYPE_TL);
+
+                               /* To avoid a shift we overlay everything on
+                                  the V flag.  */
+                               tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
+                               tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
+                               /* invert Z.  */
+                               tcg_gen_xori_tl(z, z, 2);
+
+                               tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
+                               tcg_gen_xori_tl(n, n, 2);
+                               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);
+                       }
                        break;
                case CC_LE:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_le ();
+                       {
+                               TCGv n, z;
+
+                               n = tcg_temp_new(TCG_TYPE_TL);
+                               z = tcg_temp_new(TCG_TYPE_TL);
+
+                               /* To avoid a shift we overlay everything on
+                                  the V flag.  */
+                               tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
+                               tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
+
+                               tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
+                               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);
+                       }
                        break;
                case CC_P:
                        cris_evaluate_flags(dc);
-                       gen_op_tst_cc_p ();
+                       tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], P_FLAG);
                        break;
                case CC_A:
                        cris_evaluate_flags(dc);
@@ -944,7 +1089,7 @@
        if (cond != CC_A)
        {
                gen_tst_cc (dc, cond);
-               gen_op_evaluate_bcc ();
+               t_gen_mov_env_TN(btaken, cpu_T[0]);
        }
        tcg_gen_movi_tl(env_btarget, dc->delayed_pc);
 }
@@ -1225,7 +1370,7 @@
        cris_cc_mask(dc, CC_MASK_NZVC);
        /* Fetch register operand,  */
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
-       t_gen_mov_TN_im(cpu_T[1], dc->op1);
+       tcg_gen_movi_tl(cpu_T[1], dc->op1);
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
        return 2;
 }
@@ -1238,7 +1383,7 @@
        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);
-       t_gen_mov_TN_im(cpu_T[1], imm);
+       tcg_gen_movi_tl(cpu_T[1], imm);
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
        return 2;
 }
@@ -1251,7 +1396,7 @@
        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);
-       t_gen_mov_TN_im(cpu_T[1], imm);
+       tcg_gen_movi_tl(cpu_T[1], imm);
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
        return 2;
 }
@@ -1263,7 +1408,7 @@
        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);
-       t_gen_mov_TN_im(cpu_T[1], imm);
+       tcg_gen_movi_tl(cpu_T[1], imm);
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
        return 2;
 }
@@ -1272,10 +1417,9 @@
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
        DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
 
-       cris_evaluate_flags(dc);
        cris_cc_mask(dc, CC_MASK_NZ);
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
-       t_gen_mov_TN_im(cpu_T[1], dc->op1);
+       tcg_gen_movi_tl(cpu_T[1], dc->op1);
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
 
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
@@ -1289,7 +1433,7 @@
        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);
-       t_gen_mov_TN_im(cpu_T[1], dc->op1);
+       tcg_gen_movi_tl(cpu_T[1], dc->op1);
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
        return 2;
 }
@@ -1300,7 +1444,7 @@
 
        cris_cc_mask(dc, CC_MASK_NZ);
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
-       t_gen_mov_TN_im(cpu_T[1], dc->op1);
+       tcg_gen_movi_tl(cpu_T[1], dc->op1);
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
        return 2;
 }
@@ -1311,7 +1455,7 @@
 
        cris_cc_mask(dc, CC_MASK_NZ);
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
-       t_gen_mov_TN_im(cpu_T[1], dc->op1);
+       tcg_gen_movi_tl(cpu_T[1], dc->op1);
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
        return 2;
 }
@@ -1338,14 +1482,20 @@
 
        if (cond != CC_A)
        {
+               int l1;
+
                gen_tst_cc (dc, cond);
-               tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
+
+               l1 = gen_new_label();
+               tcg_gen_movi_tl(cpu_R[dc->op1], 0);
+               tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
+               tcg_gen_movi_tl(cpu_R[dc->op1], 1);
+               gen_set_label(l1);
        }
        else
-               tcg_gen_movi_tl(cpu_T[1], 1);
+               tcg_gen_movi_tl(cpu_R[dc->op1], 1);
 
        cris_cc_mask(dc, 0);
-       crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
        return 2;
 }
 
@@ -1624,7 +1774,6 @@
 {
        DIS(fprintf (logfile, "btst $r%u, $r%u\n",
                    dc->op1, dc->op2));
-       cris_evaluate_flags(dc);
        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);
@@ -1772,10 +1921,18 @@
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
        tcg_gen_movi_tl(cc_op, dc->cc_op);
 
-       if (set)
-               gen_op_setf(flags);
+       if (set) {
+               if (!dc->user && (flags & U_FLAG)) {
+                       /* Enter user mode.  */
+                       t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
+                       tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
+                       dc->is_jmp = DISAS_UPDATE;
+               }
+               tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
+       }
        else
-               gen_op_clrf(flags);
+               tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
+
        dc->flags_live = 1;
        dc->clear_x = 0;
        return 2;
@@ -1785,28 +1942,19 @@
 {
        DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
        cris_cc_mask(dc, 0);
-       t_gen_mov_TN_reg(cpu_T[0], dc->op1);
-       gen_op_movl_sreg_T0(dc->op2);
-
-#if !defined(CONFIG_USER_ONLY)
-       if (dc->op2 == 6)
-               gen_op_movl_tlb_hi_T0();
-       else if (dc->op2 == 5) { /* srs is checked at runtime.  */
-               tcg_gen_helper_0_1(helper_tlb_update, cpu_T[0]);
-               gen_op_movl_tlb_lo_T0();
-       }
-#endif
+       tcg_gen_helper_0_2(helper_movl_sreg_reg, 
+                          tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
        return 2;
 }
 static unsigned int dec_move_sr(DisasContext *dc)
 {
        DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op2, dc->op1));
        cris_cc_mask(dc, 0);
-       gen_op_movl_T0_sreg(dc->op2);
-       tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
-       crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
+       tcg_gen_helper_0_2(helper_movl_reg_sreg, 
+                          tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
        return 2;
 }
+
 static unsigned int dec_move_rp(DisasContext *dc)
 {
        DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
@@ -2024,9 +2172,11 @@
                    dc->op1, dc->postinc ? "+]" : "]",
                    dc->op2));
 
+       cris_evaluate_flags(dc);
+
        insn_len = dec_prep_alu_m(dc, 0, memsize);
        cris_cc_mask(dc, CC_MASK_NZ);
-       gen_op_clrf(3);
+       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);
@@ -2444,10 +2594,6 @@
                case 2:
                        /* rfe.  */
                        cris_evaluate_flags(dc);
-                       gen_op_ccs_rshift();
-                       /* FIXME: don't set the P-FLAG if R is set.  */
-                       tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], P_FLAG);
-                       /* Debug helper.  */
                        tcg_gen_helper_0_0(helper_rfe);
                        dc->is_jmp = DISAS_UPDATE;
                        break;
@@ -2460,7 +2606,9 @@
                        tcg_gen_movi_tl(cpu_T[0], dc->pc);
                        t_gen_mov_env_TN(pc, cpu_T[0]);
                        /* Breaks start at 16 in the exception vector.  */
-                       gen_op_break_im(dc->op1 + 16);
+                       t_gen_mov_env_TN(trap_vector, 
+                                        tcg_const_tl(dc->op1 + 16));
+                       t_gen_raise_exception(EXCP_BREAK);
                        dc->is_jmp = DISAS_UPDATE;
                        break;
                default:
@@ -2642,7 +2790,7 @@
                                cris_evaluate_flags (dc);
                                tcg_gen_movi_tl(cpu_T[0], dc->pc);
                                t_gen_mov_env_TN(pc, cpu_T[0]);
-                               gen_op_debug();
+                               t_gen_raise_exception(EXCP_DEBUG);
                                dc->is_jmp = DISAS_UPDATE;
                        }
                }
@@ -2689,13 +2837,14 @@
 
        if (loglevel & CPU_LOG_TB_IN_ASM) {
                fprintf(logfile,
-                       "search=%d pc=%x ccs=%x pid=%x usp=%x\n"
+                       "search=%d pc=%x ccs=%x pid=%x usp=%x dbg=%x %x %x\n"
                        "%x.%x.%x.%x\n"
                        "%x.%x.%x.%x\n"
                        "%x.%x.%x.%x\n"
                        "%x.%x.%x.%x\n",
                        search_pc, env->pc, 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],
@@ -2733,7 +2882,6 @@
 
                dc->clear_x = 1;
                insn_len = cris_decoder(dc);
-               STATS(gen_op_exec_insn());
                dc->ppc = dc->pc;
                dc->pc += insn_len;
                if (dc->clear_x)
@@ -2778,7 +2926,7 @@
        cris_evaluate_flags (dc);
   done:
        if (__builtin_expect(env->singlestep_enabled, 0)) {
-               gen_op_debug();
+               t_gen_raise_exception(EXCP_DEBUG);
        } else {
                switch(dc->is_jmp) {
                        case DISAS_NEXT:
@@ -2933,13 +3081,16 @@
                                               pregnames[i]);
        }
 
-       TCG_HELPER(helper_tlb_update);
-       TCG_HELPER(helper_tlb_flush);
-       TCG_HELPER(helper_rfe);
+       TCG_HELPER(helper_raise_exception);
        TCG_HELPER(helper_store);
        TCG_HELPER(helper_dump);
        TCG_HELPER(helper_dummy);
 
+       TCG_HELPER(helper_tlb_flush);
+       TCG_HELPER(helper_movl_sreg_reg);
+       TCG_HELPER(helper_movl_reg_sreg);
+       TCG_HELPER(helper_rfe);
+
        TCG_HELPER(helper_evaluate_flags_muls);
        TCG_HELPER(helper_evaluate_flags_mulu);
        TCG_HELPER(helper_evaluate_flags_mcp);






reply via email to

[Prev in Thread] Current Thread [Next in Thread]