Commit 17ac975463baf6cd70538dcb741549262bdab590

Authored by edgar_igl
1 parent ef29a70d

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.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4350 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 90 additions and 64 deletions
target-cris/translate.c
... ... @@ -235,7 +235,7 @@ static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
235 235 l1 = gen_new_label();
236 236 /* Speculative shift. */
237 237 tcg_gen_shl_tl(d, a, b);
238   - tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
  238 + tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
239 239 /* Clear dst if shift operands were to large. */
240 240 tcg_gen_movi_tl(d, 0);
241 241 gen_set_label(l1);
... ... @@ -248,7 +248,7 @@ static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
248 248 l1 = gen_new_label();
249 249 /* Speculative shift. */
250 250 tcg_gen_shr_tl(d, a, b);
251   - tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
  251 + tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
252 252 /* Clear dst if shift operands were to large. */
253 253 tcg_gen_movi_tl(d, 0);
254 254 gen_set_label(l1);
... ... @@ -261,7 +261,7 @@ static void t_gen_asr(TCGv d, TCGv a, TCGv b)
261 261 l1 = gen_new_label();
262 262 /* Speculative shift. */
263 263 tcg_gen_sar_tl(d, a, b);
264   - tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
  264 + tcg_gen_brcond_tl(TCG_COND_LEU, b, tcg_const_tl(31), l1);
265 265 /* Clear dst if shift operands were to large. */
266 266 tcg_gen_sar_tl(d, a, tcg_const_tl(30));
267 267 gen_set_label(l1);
... ... @@ -528,6 +528,24 @@ static inline void t_gen_swapr(TCGv d, TCGv s)
528 528 tcg_gen_discard_tl(org_s);
529 529 }
530 530  
  531 +static void t_gen_cc_jmp(target_ulong pc_true, target_ulong pc_false)
  532 +{
  533 + TCGv btaken;
  534 + int l1;
  535 +
  536 + l1 = gen_new_label();
  537 + btaken = tcg_temp_new(TCG_TYPE_TL);
  538 +
  539 + /* Conditional jmp. */
  540 + t_gen_mov_TN_env(btaken, btaken);
  541 + tcg_gen_movi_tl(env_pc, pc_false);
  542 + tcg_gen_brcond_tl(TCG_COND_EQ, btaken, tcg_const_tl(0), l1);
  543 + tcg_gen_movi_tl(env_pc, pc_true);
  544 + gen_set_label(l1);
  545 +
  546 + tcg_gen_discard_tl(btaken);
  547 +}
  548 +
531 549 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
532 550 {
533 551 TranslationBlock *tb;
... ... @@ -908,7 +926,7 @@ static void gen_tst_cc (DisasContext *dc, int cond)
908 926 break;
909 927 case CC_A:
910 928 cris_evaluate_flags(dc);
911   - gen_op_movl_T0_im (1);
  929 + tcg_gen_movi_tl(cpu_T[0], 1);
912 930 break;
913 931 default:
914 932 BUG();
... ... @@ -957,8 +975,6 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
957 975 {
958 976 int mem_index = cpu_mmu_index(dc->env);
959 977  
960   - /* FIXME: qemu_ld does not act as a barrier? */
961   - tcg_gen_helper_0_0(helper_dummy);
962 978 cris_evaluate_flags(dc);
963 979 if (size == 1) {
964 980 if (sign)
... ... @@ -977,21 +993,20 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
977 993 }
978 994 }
979 995  
980   -void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
  996 +void gen_store (DisasContext *dc, TCGv addr, TCGv val,
  997 + unsigned int size)
981 998 {
982 999 int mem_index = cpu_mmu_index(dc->env);
983 1000  
984   - /* FIXME: qemu_st does not act as a barrier? */
985   - tcg_gen_helper_0_0(helper_dummy);
986 1001 cris_evaluate_flags(dc);
987 1002  
988 1003 /* Remember, operands are flipped. CRIS has reversed order. */
989 1004 if (size == 1)
990   - tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], mem_index);
  1005 + tcg_gen_qemu_st8(val, addr, mem_index);
991 1006 else if (size == 2)
992   - tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], mem_index);
  1007 + tcg_gen_qemu_st16(val, addr, mem_index);
993 1008 else
994   - tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], mem_index);
  1009 + tcg_gen_qemu_st32(val, addr, mem_index);
995 1010 }
996 1011  
997 1012 static inline void t_gen_sext(TCGv d, TCGv s, int size)
... ... @@ -1096,22 +1111,28 @@ static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
1096 1111 if (memsize == 1)
1097 1112 insn_len++;
1098 1113  
1099   - imm = ldl_code(dc->pc + 2);
1100 1114 if (memsize != 4) {
1101 1115 if (s_ext) {
1102   - imm = sign_extend(imm, (memsize * 8) - 1);
  1116 + if (memsize == 1)
  1117 + imm = ldsb_code(dc->pc + 2);
  1118 + else
  1119 + imm = ldsw_code(dc->pc + 2);
1103 1120 } else {
1104 1121 if (memsize == 1)
1105   - imm &= 0xff;
  1122 + imm = ldub_code(dc->pc + 2);
1106 1123 else
1107   - imm &= 0xffff;
  1124 + imm = lduw_code(dc->pc + 2);
1108 1125 }
1109   - }
  1126 + } else
  1127 + imm = ldl_code(dc->pc + 2);
  1128 +
1110 1129 DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
1111 1130 imm, rd, s_ext, memsize));
1112 1131 tcg_gen_movi_tl(cpu_T[1], imm);
1113 1132 dc->postinc = 0;
1114 1133 } else {
  1134 + /* FIXME: qemu_ld does not act as a barrier? */
  1135 + tcg_gen_helper_0_0(helper_dummy);
1115 1136 gen_load(dc, cpu_T[1], cpu_R[rs], memsize, 0);
1116 1137 if (s_ext)
1117 1138 t_gen_sext(cpu_T[1], cpu_T[1], memsize);
... ... @@ -1250,6 +1271,8 @@ static unsigned int dec_btstq(DisasContext *dc)
1250 1271 {
1251 1272 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1252 1273 DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
  1274 +
  1275 + cris_evaluate_flags(dc);
1253 1276 cris_cc_mask(dc, CC_MASK_NZ);
1254 1277 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1255 1278 t_gen_mov_TN_im(cpu_T[1], dc->op1);
... ... @@ -1601,6 +1624,7 @@ static unsigned int dec_btst_r(DisasContext *dc)
1601 1624 {
1602 1625 DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1603 1626 dc->op1, dc->op2));
  1627 + cris_evaluate_flags(dc);
1604 1628 cris_cc_mask(dc, CC_MASK_NZ);
1605 1629 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1606 1630 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
... ... @@ -2162,36 +2186,47 @@ static unsigned int dec_move_pm(DisasContext *dc)
2162 2186 dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
2163 2187  
2164 2188 /* prepare store. Address in T0, value in T1. */
  2189 + if (dc->op2 == PR_CCS)
  2190 + cris_evaluate_flags(dc);
2165 2191 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
2166   - t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2167   - gen_store_T0_T1(dc, memsize);
  2192 +
  2193 + /* FIXME: qemu_st does not act as a barrier? */
  2194 + tcg_gen_helper_0_0(helper_dummy);
  2195 + gen_store(dc, cpu_R[dc->op1], cpu_T[1], memsize);
  2196 +
2168 2197 cris_cc_mask(dc, 0);
2169 2198 if (dc->postinc)
2170   - {
2171   - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
2172   - t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2173   - }
  2199 + tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2174 2200 return 2;
2175 2201 }
2176 2202  
2177 2203 static unsigned int dec_movem_mr(DisasContext *dc)
2178 2204 {
  2205 + TCGv tmp[16];
2179 2206 int i;
2180 2207  
2181 2208 DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
2182 2209 dc->postinc ? "+]" : "]", dc->op2));
2183 2210  
  2211 + /* FIXME: qemu_ld does not act as a barrier? */
  2212 + tcg_gen_helper_0_0(helper_dummy);
  2213 +
2184 2214 /* fetch the address into T0 and T1. */
2185   - t_gen_mov_TN_reg(cpu_T[1], dc->op1);
2186 2215 for (i = 0; i <= dc->op2; i++) {
  2216 + tmp[i] = tcg_temp_new(TCG_TYPE_TL);
2187 2217 /* Perform the load onto regnum i. Always dword wide. */
2188   - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
2189   - gen_load(dc, cpu_R[i], cpu_T[1], 4, 0);
2190   - tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 4);
  2218 + tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4);
  2219 + gen_load(dc, tmp[i], cpu_T[0], 4, 0);
2191 2220 }
  2221 +
  2222 + for (i = 0; i <= dc->op2; i++) {
  2223 + tcg_gen_mov_tl(cpu_R[i], tmp[i]);
  2224 + tcg_gen_discard_tl(tmp[i]);
  2225 + }
  2226 +
2192 2227 /* writeback the updated pointer value. */
2193 2228 if (dc->postinc)
2194   - t_gen_mov_reg_TN(dc->op1, cpu_T[1]);
  2229 + tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4);
2195 2230  
2196 2231 /* gen_load might want to evaluate the previous insns flags. */
2197 2232 cris_cc_mask(dc, 0);
... ... @@ -2205,23 +2240,17 @@ static unsigned int dec_movem_rm(DisasContext *dc)
2205 2240 DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2206 2241 dc->postinc ? "+]" : "]"));
2207 2242  
  2243 + /* FIXME: qemu_st does not act as a barrier? */
  2244 + tcg_gen_helper_0_0(helper_dummy);
  2245 +
2208 2246 for (i = 0; i <= dc->op2; i++) {
2209   - /* Fetch register i into T1. */
2210   - t_gen_mov_TN_reg(cpu_T[1], i);
2211   - /* Fetch the address into T0. */
2212   - t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2213   - /* Displace it. */
2214   - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], i * 4);
  2247 + /* Displace addr. */
  2248 + tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4);
2215 2249 /* Perform the store. */
2216   - gen_store_T0_T1(dc, 4);
2217   - }
2218   - if (dc->postinc) {
2219   - /* T0 should point to the last written addr, advance one more
2220   - step. */
2221   - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 4);
2222   - /* writeback the updated pointer value. */
2223   - t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
  2250 + gen_store(dc, cpu_T[0], cpu_R[i], 4);
2224 2251 }
  2252 + if (dc->postinc)
  2253 + tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4);
2225 2254 cris_cc_mask(dc, 0);
2226 2255 return 2;
2227 2256 }
... ... @@ -2236,14 +2265,12 @@ static unsigned int dec_move_rm(DisasContext *dc)
2236 2265 memsize, dc->op2, dc->op1));
2237 2266  
2238 2267 /* prepare store. */
2239   - t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2240   - t_gen_mov_TN_reg(cpu_T[1], dc->op2);
2241   - gen_store_T0_T1(dc, memsize);
  2268 + /* FIXME: qemu_st does not act as a barrier? */
  2269 + tcg_gen_helper_0_0(helper_dummy);
  2270 + gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
  2271 +
2242 2272 if (dc->postinc)
2243   - {
2244   - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
2245   - t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2246   - }
  2273 + tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2247 2274 cris_cc_mask(dc, 0);
2248 2275 return 2;
2249 2276 }
... ... @@ -2280,11 +2307,13 @@ static unsigned int dec_lapc_im(DisasContext *dc)
2280 2307 static unsigned int dec_jump_p(DisasContext *dc)
2281 2308 {
2282 2309 DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
2283   - cris_cc_mask(dc, 0);
2284 2310  
  2311 + if (dc->op2 == PR_CCS)
  2312 + cris_evaluate_flags(dc);
2285 2313 t_gen_mov_TN_preg(cpu_T[0], dc->op2);
2286 2314 /* rete will often have low bit set to indicate delayslot. */
2287 2315 tcg_gen_andi_tl(env_btarget, cpu_T[0], ~1);
  2316 + cris_cc_mask(dc, 0);
2288 2317 cris_prepare_dyn_jmp(dc);
2289 2318 return 2;
2290 2319 }
... ... @@ -2298,7 +2327,8 @@ static unsigned int dec_jas_r(DisasContext *dc)
2298 2327 tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2299 2328 if (dc->op2 > 15)
2300 2329 abort();
2301   - tcg_gen_movi_tl(cpu_PR[dc->op2], dc->pc + 4);
  2330 + tcg_gen_movi_tl(cpu_T[0], dc->pc + 4);
  2331 + tcg_gen_mov_tl(cpu_PR[dc->op2], cpu_T[0]);
2302 2332  
2303 2333 cris_prepare_dyn_jmp(dc);
2304 2334 return 2;
... ... @@ -2312,7 +2342,7 @@ static unsigned int dec_jas_im(DisasContext *dc)
2312 2342  
2313 2343 DIS(fprintf (logfile, "jas 0x%x\n", imm));
2314 2344 cris_cc_mask(dc, 0);
2315   - /* Stor the return address in Pd. */
  2345 + /* Store the return address in Pd. */
2316 2346 tcg_gen_movi_tl(env_btarget, imm);
2317 2347 t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8));
2318 2348 cris_prepare_dyn_jmp(dc);
... ... @@ -2327,7 +2357,7 @@ static unsigned int dec_jasc_im(DisasContext *dc)
2327 2357  
2328 2358 DIS(fprintf (logfile, "jasc 0x%x\n", imm));
2329 2359 cris_cc_mask(dc, 0);
2330   - /* Stor the return address in Pd. */
  2360 + /* Store the return address in Pd. */
2331 2361 tcg_gen_movi_tl(cpu_T[0], imm);
2332 2362 t_gen_mov_env_TN(btarget, cpu_T[0]);
2333 2363 tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4);
... ... @@ -2340,7 +2370,7 @@ static unsigned int dec_jasc_r(DisasContext *dc)
2340 2370 {
2341 2371 DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
2342 2372 cris_cc_mask(dc, 0);
2343   - /* Stor the return address in Pd. */
  2373 + /* Store the return address in Pd. */
2344 2374 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2345 2375 t_gen_mov_env_TN(btarget, cpu_T[0]);
2346 2376 tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4);
... ... @@ -2354,8 +2384,7 @@ static unsigned int dec_bcc_im(DisasContext *dc)
2354 2384 int32_t offset;
2355 2385 uint32_t cond = dc->op2;
2356 2386  
2357   - offset = ldl_code(dc->pc + 2);
2358   - offset = sign_extend(offset, 15);
  2387 + offset = ldsw_code(dc->pc + 2);
2359 2388  
2360 2389 DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
2361 2390 cc_name(cond), offset,
... ... @@ -2579,12 +2608,10 @@ static inline unsigned int
2579 2608 cris_decoder(DisasContext *dc)
2580 2609 {
2581 2610 unsigned int insn_len = 2;
2582   - uint32_t tmp;
2583 2611 int i;
2584 2612  
2585 2613 /* Load a halfword onto the instruction register. */
2586   - tmp = ldl_code(dc->pc);
2587   - dc->ir = tmp & 0xffff;
  2614 + dc->ir = lduw_code(dc->pc);
2588 2615  
2589 2616 /* Now decode it. */
2590 2617 dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11);
... ... @@ -2720,12 +2747,11 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2720 2747 if (dc->delayed_branch == 0)
2721 2748 {
2722 2749 if (dc->bcc == CC_A) {
2723   - gen_op_jmp1 ();
  2750 + tcg_gen_mov_tl(env_pc, env_btarget);
2724 2751 dc->is_jmp = DISAS_JUMP;
2725 2752 }
2726 2753 else {
2727   - /* Conditional jmp. */
2728   - gen_op_cc_jmp (dc->delayed_pc, dc->pc);
  2754 + t_gen_cc_jmp(dc->delayed_pc, dc->pc);
2729 2755 dc->is_jmp = DISAS_JUMP;
2730 2756 }
2731 2757 }
... ... @@ -2785,7 +2811,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2785 2811 if (loglevel & CPU_LOG_TB_IN_ASM) {
2786 2812 fprintf(logfile, "--------------\n");
2787 2813 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2788   - target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
  2814 + target_disas(logfile, pc_start, dc->pc - pc_start, 0);
2789 2815 fprintf(logfile, "\nisize=%d osize=%d\n",
2790 2816 dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
2791 2817 }
... ... @@ -2942,5 +2968,5 @@ void cpu_reset (CPUCRISState *env)
2942 2968 void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
2943 2969 unsigned long searched_pc, int pc_pos, void *puc)
2944 2970 {
2945   - env->pc = gen_opc_pc[pc_pos];
  2971 + env->pc = gen_opc_pc[pc_pos];
2946 2972 }
... ...