qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [4350] More TCG updates for CRIS
@ 2008-05-06  8:30 Edgar E. Iglesias
  0 siblings, 0 replies; only message in thread
From: Edgar E. Iglesias @ 2008-05-06  8:30 UTC (permalink / raw)
  To: qemu-devel

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];
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-06  8:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-06  8:30 [Qemu-devel] [4350] More TCG updates for CRIS Edgar E. Iglesias

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).