qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [4350] More TCG updates for CRIS


From: Edgar E. Iglesias
Subject: [Qemu-devel] [4350] More TCG updates for CRIS
Date: Tue, 06 May 2008 08:30:17 +0000

Revision: 4350
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4350
Author:   edgar_igl
Date:     2008-05-06 08:30:15 +0000 (Tue, 06 May 2008)

Log Message:
-----------
More TCG updates for CRIS
* Convert parts of the jump logic to TCG.
* Stores no longer have to go via T0/T1.
* Use the byte and halfword ldx_code variants when appropriate for insn 
fetching.
* Do not disassemble beyond the translation block.

Modified Paths:
--------------
    trunk/target-cris/translate.c

Modified: trunk/target-cris/translate.c
===================================================================
--- trunk/target-cris/translate.c       2008-05-06 08:04:40 UTC (rev 4349)
+++ trunk/target-cris/translate.c       2008-05-06 08:30:15 UTC (rev 4350)
@@ -235,7 +235,7 @@
        l1 = gen_new_label();
        /* Speculative shift. */
        tcg_gen_shl_tl(d, a, b);
-       tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
+       tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
        /* Clear dst if shift operands were to large.  */
        tcg_gen_movi_tl(d, 0);
        gen_set_label(l1);
@@ -248,7 +248,7 @@
        l1 = gen_new_label();
        /* Speculative shift. */
        tcg_gen_shr_tl(d, a, b);
-       tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
+       tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
        /* Clear dst if shift operands were to large.  */
        tcg_gen_movi_tl(d, 0);
        gen_set_label(l1);
@@ -261,7 +261,7 @@
        l1 = gen_new_label();
        /* Speculative shift. */
        tcg_gen_sar_tl(d, a, b);
-       tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
+       tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
        /* Clear dst if shift operands were to large.  */
        tcg_gen_sar_tl(d, a, tcg_const_tl(30));
        gen_set_label(l1);
@@ -528,6 +528,24 @@
        tcg_gen_discard_tl(org_s);
 }
 
+static void t_gen_cc_jmp(target_ulong pc_true, target_ulong pc_false)
+{
+       TCGv btaken;
+       int l1;
+
+       l1 = gen_new_label();
+       btaken = tcg_temp_new(TCG_TYPE_TL);
+
+       /* Conditional jmp.  */
+       t_gen_mov_TN_env(btaken, btaken);
+       tcg_gen_movi_tl(env_pc, pc_false);
+       tcg_gen_brcond_tl(TCG_COND_EQ, btaken, tcg_const_tl(0), l1);
+       tcg_gen_movi_tl(env_pc, pc_true);
+       gen_set_label(l1);
+
+       tcg_gen_discard_tl(btaken);
+}
+
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
        TranslationBlock *tb;
@@ -908,7 +926,7 @@
                        break;
                case CC_A:
                        cris_evaluate_flags(dc);
-                       gen_op_movl_T0_im (1);
+                       tcg_gen_movi_tl(cpu_T[0], 1);
                        break;
                default:
                        BUG();
@@ -957,8 +975,6 @@
 {
        int mem_index = cpu_mmu_index(dc->env);
 
-       /* FIXME: qemu_ld does not act as a barrier?  */
-       tcg_gen_helper_0_0(helper_dummy);
        cris_evaluate_flags(dc);
        if (size == 1) {
                if (sign)
@@ -977,21 +993,20 @@
        }
 }
 
-void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
+void gen_store (DisasContext *dc, TCGv addr, TCGv val,
+               unsigned int size)
 {
        int mem_index = cpu_mmu_index(dc->env);
 
-       /* FIXME: qemu_st does not act as a barrier?  */
-       tcg_gen_helper_0_0(helper_dummy);
        cris_evaluate_flags(dc);
 
        /* Remember, operands are flipped. CRIS has reversed order.  */
        if (size == 1)
-               tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], mem_index);
+               tcg_gen_qemu_st8(val, addr, mem_index);
        else if (size == 2)
-               tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], mem_index);
+               tcg_gen_qemu_st16(val, addr, mem_index);
        else
-               tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], mem_index);
+               tcg_gen_qemu_st32(val, addr, mem_index);
 }
 
 static inline void t_gen_sext(TCGv d, TCGv s, int size)
@@ -1096,22 +1111,28 @@
                if (memsize == 1)
                        insn_len++;
 
-               imm = ldl_code(dc->pc + 2);
                if (memsize != 4) {
                        if (s_ext) {
-                               imm = sign_extend(imm, (memsize * 8) - 1);
+                               if (memsize == 1)
+                                       imm = ldsb_code(dc->pc + 2);
+                               else
+                                       imm = ldsw_code(dc->pc + 2);
                        } else {
                                if (memsize == 1)
-                                       imm &= 0xff;
+                                       imm = ldub_code(dc->pc + 2);
                                else
-                                       imm &= 0xffff;
+                                       imm = lduw_code(dc->pc + 2);
                        }
-               }
+               } else
+                       imm = ldl_code(dc->pc + 2);
+                       
                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);
                dc->postinc = 0;
        } else {
+               /* FIXME: qemu_ld does not act as a barrier?  */
+               tcg_gen_helper_0_0(helper_dummy);
                gen_load(dc, cpu_T[1], cpu_R[rs], memsize, 0);
                if (s_ext)
                        t_gen_sext(cpu_T[1], cpu_T[1], memsize);
@@ -1250,6 +1271,8 @@
 {
        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);
@@ -1601,6 +1624,7 @@
 {
        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);
@@ -2162,36 +2186,47 @@
                     dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
 
        /* prepare store. Address in T0, value in T1.  */
+       if (dc->op2 == PR_CCS)
+               cris_evaluate_flags(dc);
        t_gen_mov_TN_preg(cpu_T[1], dc->op2);
-       t_gen_mov_TN_reg(cpu_T[0], dc->op1);
-       gen_store_T0_T1(dc, memsize);
+
+       /* FIXME: qemu_st does not act as a barrier?  */
+       tcg_gen_helper_0_0(helper_dummy);
+       gen_store(dc, cpu_R[dc->op1], cpu_T[1], memsize);
+
        cris_cc_mask(dc, 0);
        if (dc->postinc)
-       {
-               tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
-               t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
-       }
+               tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
        return 2;
 }
 
 static unsigned int dec_movem_mr(DisasContext *dc)
 {
+       TCGv tmp[16];
        int i;
 
        DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
                    dc->postinc ? "+]" : "]", dc->op2));
 
+       /* FIXME: qemu_ld does not act as a barrier?  */
+       tcg_gen_helper_0_0(helper_dummy);
+
        /* fetch the address into T0 and T1.  */
-       t_gen_mov_TN_reg(cpu_T[1], dc->op1);
        for (i = 0; i <= dc->op2; i++) {
+               tmp[i] = tcg_temp_new(TCG_TYPE_TL);
                /* Perform the load onto regnum i. Always dword wide.  */
-               tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
-               gen_load(dc, cpu_R[i], cpu_T[1], 4, 0);
-               tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 4);
+               tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4);
+               gen_load(dc, tmp[i], cpu_T[0], 4, 0);
        }
+
+       for (i = 0; i <= dc->op2; i++) {
+               tcg_gen_mov_tl(cpu_R[i], tmp[i]);
+               tcg_gen_discard_tl(tmp[i]);
+       }
+
        /* writeback the updated pointer value.  */
        if (dc->postinc)
-               t_gen_mov_reg_TN(dc->op1, cpu_T[1]);
+               tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4);
 
        /* gen_load might want to evaluate the previous insns flags.  */
        cris_cc_mask(dc, 0);
@@ -2205,23 +2240,17 @@
        DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
                     dc->postinc ? "+]" : "]"));
 
+       /* FIXME: qemu_st does not act as a barrier?  */
+       tcg_gen_helper_0_0(helper_dummy);
+
        for (i = 0; i <= dc->op2; i++) {
-               /* Fetch register i into T1.  */
-               t_gen_mov_TN_reg(cpu_T[1], i);
-               /* Fetch the address into T0.  */
-               t_gen_mov_TN_reg(cpu_T[0], dc->op1);
-               /* Displace it.  */
-               tcg_gen_addi_tl(cpu_T[0], cpu_T[0], i * 4);
+               /* Displace addr.  */
+               tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4);
                /* Perform the store.  */
-               gen_store_T0_T1(dc, 4);
+               gen_store(dc, cpu_T[0], cpu_R[i], 4);
        }
-       if (dc->postinc) {
-               /* T0 should point to the last written addr, advance one more
-                  step. */
-               tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 4);
-               /* writeback the updated pointer value.  */
-               t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
-       }
+       if (dc->postinc)
+               tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4);
        cris_cc_mask(dc, 0);
        return 2;
 }
@@ -2236,14 +2265,12 @@
                     memsize, dc->op2, dc->op1));
 
        /* prepare store.  */
-       t_gen_mov_TN_reg(cpu_T[0], dc->op1);
-       t_gen_mov_TN_reg(cpu_T[1], dc->op2);
-       gen_store_T0_T1(dc, memsize);
+       /* FIXME: qemu_st does not act as a barrier?  */
+       tcg_gen_helper_0_0(helper_dummy);
+       gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
+
        if (dc->postinc)
-       {
-               tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
-               t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
-       }
+               tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
        cris_cc_mask(dc, 0);
        return 2;
 }
@@ -2280,11 +2307,13 @@
 static unsigned int dec_jump_p(DisasContext *dc)
 {
        DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
-       cris_cc_mask(dc, 0);
 
+       if (dc->op2 == PR_CCS)
+               cris_evaluate_flags(dc);
        t_gen_mov_TN_preg(cpu_T[0], dc->op2);
        /* rete will often have low bit set to indicate delayslot.  */
        tcg_gen_andi_tl(env_btarget, cpu_T[0], ~1);
+       cris_cc_mask(dc, 0);
        cris_prepare_dyn_jmp(dc);
        return 2;
 }
@@ -2298,7 +2327,8 @@
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
        if (dc->op2 > 15)
                abort();
-       tcg_gen_movi_tl(cpu_PR[dc->op2], dc->pc + 4);
+       tcg_gen_movi_tl(cpu_T[0], dc->pc + 4);
+       tcg_gen_mov_tl(cpu_PR[dc->op2], cpu_T[0]);
 
        cris_prepare_dyn_jmp(dc);
        return 2;
@@ -2312,7 +2342,7 @@
 
        DIS(fprintf (logfile, "jas 0x%x\n", imm));
        cris_cc_mask(dc, 0);
-       /* Stor the return address in Pd.  */
+       /* Store the return address in Pd.  */
        tcg_gen_movi_tl(env_btarget, imm);
        t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8));
        cris_prepare_dyn_jmp(dc);
@@ -2327,7 +2357,7 @@
 
        DIS(fprintf (logfile, "jasc 0x%x\n", imm));
        cris_cc_mask(dc, 0);
-       /* Stor the return address in Pd.  */
+       /* Store the return address in Pd.  */
        tcg_gen_movi_tl(cpu_T[0], imm);
        t_gen_mov_env_TN(btarget, cpu_T[0]);
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4);
@@ -2340,7 +2370,7 @@
 {
        DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
        cris_cc_mask(dc, 0);
-       /* Stor the return address in Pd.  */
+       /* Store the return address in Pd.  */
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
        t_gen_mov_env_TN(btarget, cpu_T[0]);
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4);
@@ -2354,8 +2384,7 @@
        int32_t offset;
        uint32_t cond = dc->op2;
 
-       offset = ldl_code(dc->pc + 2);
-       offset = sign_extend(offset, 15);
+       offset = ldsw_code(dc->pc + 2);
 
        DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
                    cc_name(cond), offset,
@@ -2579,12 +2608,10 @@
 cris_decoder(DisasContext *dc)
 {
        unsigned int insn_len = 2;
-       uint32_t tmp;
        int i;
 
        /* Load a halfword onto the instruction register.  */
-       tmp = ldl_code(dc->pc);
-       dc->ir = tmp & 0xffff;
+       dc->ir = lduw_code(dc->pc);
 
        /* Now decode it.  */
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
@@ -2720,12 +2747,11 @@
                        if (dc->delayed_branch == 0)
                        {
                                if (dc->bcc == CC_A) {
-                                       gen_op_jmp1 ();
+                                       tcg_gen_mov_tl(env_pc, env_btarget);
                                        dc->is_jmp = DISAS_JUMP;
                                }
                                else {
-                                       /* Conditional jmp.  */
-                                       gen_op_cc_jmp (dc->delayed_pc, dc->pc);
+                                       t_gen_cc_jmp(dc->delayed_pc, dc->pc);
                                        dc->is_jmp = DISAS_JUMP;
                                }
                        }
@@ -2785,7 +2811,7 @@
        if (loglevel & CPU_LOG_TB_IN_ASM) {
                fprintf(logfile, "--------------\n");
                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
-               target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
+               target_disas(logfile, pc_start, dc->pc - pc_start, 0);
                fprintf(logfile, "\nisize=%d osize=%d\n", 
                        dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
        }
@@ -2942,5 +2968,5 @@
 void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
                  unsigned long searched_pc, int pc_pos, void *puc)
 {
-    env->pc = gen_opc_pc[pc_pos];
+       env->pc = gen_opc_pc[pc_pos];
 }






reply via email to

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