Commit 1000822b03f44cc0b0e624cd60e5dce8dde7d463

Authored by aurel32
1 parent ba6a9d8c

SH4: convert branch/jump instructions to TCG

(Shin-ichiro KAWASAKI)

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5111 c046a42c-6fe2-441c-8c8c-71466251a162
target-sh4/op.c
... ... @@ -37,70 +37,6 @@ static inline void cond_t(int cond)
37 37 clr_t();
38 38 }
39 39  
40   -void OPPROTO op_bf_s(void)
41   -{
42   - env->delayed_pc = PARAM1;
43   - if (!(env->sr & SR_T)) {
44   - env->flags |= DELAY_SLOT_TRUE;
45   - }
46   - RETURN();
47   -}
48   -
49   -void OPPROTO op_bt_s(void)
50   -{
51   - env->delayed_pc = PARAM1;
52   - if (env->sr & SR_T) {
53   - env->flags |= DELAY_SLOT_TRUE;
54   - }
55   - RETURN();
56   -}
57   -
58   -void OPPROTO op_store_flags(void)
59   -{
60   - env->flags &= DELAY_SLOT_TRUE;
61   - env->flags |= PARAM1;
62   - RETURN();
63   -}
64   -
65   -void OPPROTO op_bra(void)
66   -{
67   - env->delayed_pc = PARAM1;
68   - RETURN();
69   -}
70   -
71   -void OPPROTO op_braf_T0(void)
72   -{
73   - env->delayed_pc = PARAM1 + T0;
74   - RETURN();
75   -}
76   -
77   -void OPPROTO op_bsr(void)
78   -{
79   - env->pr = PARAM1;
80   - env->delayed_pc = PARAM2;
81   - RETURN();
82   -}
83   -
84   -void OPPROTO op_bsrf_T0(void)
85   -{
86   - env->pr = PARAM1;
87   - env->delayed_pc = PARAM1 + T0;
88   - RETURN();
89   -}
90   -
91   -void OPPROTO op_jsr_T0(void)
92   -{
93   - env->pr = PARAM1;
94   - env->delayed_pc = T0;
95   - RETURN();
96   -}
97   -
98   -void OPPROTO op_rts(void)
99   -{
100   - env->delayed_pc = env->pr;
101   - RETURN();
102   -}
103   -
104 40 void OPPROTO op_ldtlb(void)
105 41 {
106 42 helper_ldtlb();
... ... @@ -119,13 +55,6 @@ void OPPROTO op_fschg(void)
119 55 RETURN();
120 56 }
121 57  
122   -void OPPROTO op_rte(void)
123   -{
124   - env->sr = env->ssr;
125   - env->delayed_pc = env->spc;
126   - RETURN();
127   -}
128   -
129 58 void OPPROTO op_addc_T0_T1(void)
130 59 {
131 60 helper_addc_T0_T1();
... ... @@ -257,12 +186,6 @@ void OPPROTO op_trapa(void)
257 186 RETURN();
258 187 }
259 188  
260   -void OPPROTO op_jmp_T0(void)
261   -{
262   - env->delayed_pc = T0;
263   - RETURN();
264   -}
265   -
266 189 void OPPROTO op_ldcl_rMplus_rN_bank(void)
267 190 {
268 191 env->gregs[PARAM2] = env->gregs[PARAM1];
... ... @@ -568,28 +491,6 @@ void OPPROTO op_movl_FT0_fpul(void)
568 491 RETURN();
569 492 }
570 493  
571   -void OPPROTO op_jT(void)
572   -{
573   - if (env->sr & SR_T)
574   - GOTO_LABEL_PARAM(1);
575   - RETURN();
576   -}
577   -
578   -void OPPROTO op_jdelayed(void)
579   -{
580   - if (env->flags & DELAY_SLOT_TRUE) {
581   - env->flags &= ~DELAY_SLOT_TRUE;
582   - GOTO_LABEL_PARAM(1);
583   - }
584   - RETURN();
585   -}
586   -
587   -void OPPROTO op_movl_delayed_pc_PC(void)
588   -{
589   - env->pc = env->delayed_pc;
590   - RETURN();
591   -}
592   -
593 494 void OPPROTO op_raise_illegal_instruction(void)
594 495 {
595 496 env->exception_index = 0x180;
... ...
target-sh4/translate.c
... ... @@ -62,7 +62,10 @@ static TCGv cpu_env;
62 62 static TCGv cpu_gregs[24];
63 63 static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64 64 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
65   -static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
  65 +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
  66 +
  67 +/* internal register indexes */
  68 +static TCGv cpu_flags, cpu_delayed_pc;
66 69  
67 70 /* dyngen register indexes */
68 71 static TCGv cpu_T[2];
... ... @@ -120,6 +123,12 @@ static void sh4_translate_init(void)
120 123 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
121 124 offsetof(CPUState, fpul), "FPUL");
122 125  
  126 + cpu_flags = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
  127 + offsetof(CPUState, flags), "_flags_");
  128 + cpu_delayed_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
  129 + offsetof(CPUState, delayed_pc),
  130 + "_delayed_pc_");
  131 +
123 132 /* register helpers */
124 133 #undef DEF_HELPER
125 134 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
... ... @@ -249,7 +258,7 @@ static void gen_jump(DisasContext * ctx)
249 258 if (ctx->delayed_pc == (uint32_t) - 1) {
250 259 /* Target is not statically known, it comes necessarily from a
251 260 delayed jump as immediate jump are conditinal jumps */
252   - gen_op_movl_delayed_pc_PC();
  261 + tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
253 262 if (ctx->singlestep_enabled)
254 263 gen_op_debug();
255 264 tcg_gen_exit_tb(0);
... ... @@ -258,6 +267,16 @@ static void gen_jump(DisasContext * ctx)
258 267 }
259 268 }
260 269  
  270 +static inline void gen_branch_slot(uint32_t delayed_pc, int t)
  271 +{
  272 + int label = gen_new_label();
  273 + tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
  274 + tcg_gen_andi_i32(cpu_T[0], cpu_sr, SR_T);
  275 + tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], t ? SR_T : 0, label);
  276 + tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
  277 + gen_set_label(label);
  278 +}
  279 +
261 280 /* Immediate conditional jump (bt or bf) */
262 281 static void gen_conditional_jump(DisasContext * ctx,
263 282 target_ulong ift, target_ulong ifnott)
... ... @@ -265,7 +284,8 @@ static void gen_conditional_jump(DisasContext * ctx,
265 284 int l1;
266 285  
267 286 l1 = gen_new_label();
268   - gen_op_jT(l1);
  287 + tcg_gen_andi_i32(cpu_T[0], cpu_sr, SR_T);
  288 + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], SR_T, l1);
269 289 gen_goto_tb(ctx, 0, ifnott);
270 290 gen_set_label(l1);
271 291 gen_goto_tb(ctx, 1, ift);
... ... @@ -277,9 +297,11 @@ static void gen_delayed_conditional_jump(DisasContext * ctx)
277 297 int l1;
278 298  
279 299 l1 = gen_new_label();
280   - gen_op_jdelayed(l1);
  300 + tcg_gen_andi_i32(cpu_T[0], cpu_flags, DELAY_SLOT_TRUE);
  301 + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], DELAY_SLOT_TRUE, l1);
281 302 gen_goto_tb(ctx, 1, ctx->pc + 2);
282 303 gen_set_label(l1);
  304 + tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
283 305 gen_jump(ctx);
284 306 }
285 307  
... ... @@ -317,6 +339,12 @@ static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
317 339 gen_set_label(label2);
318 340 }
319 341  
  342 +static inline void gen_store_flags(uint32_t flags)
  343 +{
  344 + tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
  345 + tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
  346 +}
  347 +
320 348 #define B3_0 (ctx->opcode & 0xf)
321 349 #define B6_4 ((ctx->opcode >> 4) & 0x7)
322 350 #define B7_4 ((ctx->opcode >> 4) & 0xf)
... ... @@ -353,7 +381,8 @@ void _decode_opc(DisasContext * ctx)
353 381 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
354 382 return;
355 383 case 0x000b: /* rts */
356   - CHECK_NOT_DELAY_SLOT gen_op_rts();
  384 + CHECK_NOT_DELAY_SLOT
  385 + tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
357 386 ctx->flags |= DELAY_SLOT;
358 387 ctx->delayed_pc = (uint32_t) - 1;
359 388 return;
... ... @@ -375,7 +404,9 @@ void _decode_opc(DisasContext * ctx)
375 404 #endif
376 405 return;
377 406 case 0x002b: /* rte */
378   - CHECK_NOT_DELAY_SLOT gen_op_rte();
  407 + CHECK_NOT_DELAY_SLOT
  408 + tcg_gen_mov_i32(cpu_sr, cpu_ssr);
  409 + tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
379 410 ctx->flags |= DELAY_SLOT;
380 411 ctx->delayed_pc = (uint32_t) - 1;
381 412 return;
... ... @@ -436,13 +467,15 @@ void _decode_opc(DisasContext * ctx)
436 467 return;
437 468 case 0xa000: /* bra disp */
438 469 CHECK_NOT_DELAY_SLOT
439   - gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
  470 + ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
  471 + tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
440 472 ctx->flags |= DELAY_SLOT;
441 473 return;
442 474 case 0xb000: /* bsr disp */
443 475 CHECK_NOT_DELAY_SLOT
444   - gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
445   - ctx->pc + 4 + B11_0s * 2);
  476 + tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
  477 + ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
  478 + tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
446 479 ctx->flags |= DELAY_SLOT;
447 480 return;
448 481 }
... ... @@ -930,7 +963,7 @@ void _decode_opc(DisasContext * ctx)
930 963 return;
931 964 case 0x8f00: /* bf/s label */
932 965 CHECK_NOT_DELAY_SLOT
933   - gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
  966 + gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
934 967 ctx->flags |= DELAY_SLOT_CONDITIONAL;
935 968 return;
936 969 case 0x8900: /* bt label */
... ... @@ -941,7 +974,7 @@ void _decode_opc(DisasContext * ctx)
941 974 return;
942 975 case 0x8d00: /* bt/s label */
943 976 CHECK_NOT_DELAY_SLOT
944   - gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
  977 + gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
945 978 ctx->flags |= DELAY_SLOT_CONDITIONAL;
946 979 return;
947 980 case 0x8800: /* cmp/eq #imm,R0 */
... ... @@ -1083,13 +1116,14 @@ void _decode_opc(DisasContext * ctx)
1083 1116 switch (ctx->opcode & 0xf0ff) {
1084 1117 case 0x0023: /* braf Rn */
1085 1118 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1086   - gen_op_braf_T0(ctx->pc + 4);
  1119 + tcg_gen_addi_i32(cpu_delayed_pc, cpu_T[0], ctx->pc + 4);
1087 1120 ctx->flags |= DELAY_SLOT;
1088 1121 ctx->delayed_pc = (uint32_t) - 1;
1089 1122 return;
1090 1123 case 0x0003: /* bsrf Rn */
1091 1124 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1092   - gen_op_bsrf_T0(ctx->pc + 4);
  1125 + tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
  1126 + tcg_gen_add_i32(cpu_delayed_pc, cpu_T[0], cpu_pr);
1093 1127 ctx->flags |= DELAY_SLOT;
1094 1128 ctx->delayed_pc = (uint32_t) - 1;
1095 1129 return;
... ... @@ -1107,13 +1141,14 @@ void _decode_opc(DisasContext * ctx)
1107 1141 return;
1108 1142 case 0x402b: /* jmp @Rn */
1109 1143 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1110   - gen_op_jmp_T0();
  1144 + tcg_gen_mov_i32(cpu_delayed_pc, cpu_T[0]);
1111 1145 ctx->flags |= DELAY_SLOT;
1112 1146 ctx->delayed_pc = (uint32_t) - 1;
1113 1147 return;
1114 1148 case 0x400b: /* jsr @Rn */
1115 1149 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1116   - gen_op_jsr_T0(ctx->pc + 4);
  1150 + tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
  1151 + tcg_gen_mov_i32(cpu_delayed_pc, cpu_T[0]);
1117 1152 ctx->flags |= DELAY_SLOT;
1118 1153 ctx->delayed_pc = (uint32_t) - 1;
1119 1154 return;
... ... @@ -1332,12 +1367,12 @@ void decode_opc(DisasContext * ctx)
1332 1367  
1333 1368 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1334 1369 if (ctx->flags & DELAY_SLOT_CLEARME) {
1335   - gen_op_store_flags(0);
  1370 + gen_store_flags(0);
1336 1371 } else {
1337 1372 /* go out of the delay slot */
1338 1373 uint32_t new_flags = ctx->flags;
1339 1374 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1340   - gen_op_store_flags(new_flags);
  1375 + gen_store_flags(new_flags);
1341 1376 }
1342 1377 ctx->flags = 0;
1343 1378 ctx->bstate = BS_BRANCH;
... ... @@ -1351,7 +1386,7 @@ void decode_opc(DisasContext * ctx)
1351 1386  
1352 1387 /* go into a delay slot */
1353 1388 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1354   - gen_op_store_flags(ctx->flags);
  1389 + gen_store_flags(ctx->flags);
1355 1390 }
1356 1391  
1357 1392 static inline void
... ... @@ -1448,7 +1483,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1448 1483 /* fall through */
1449 1484 case BS_NONE:
1450 1485 if (ctx.flags) {
1451   - gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
  1486 + gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1452 1487 }
1453 1488 gen_goto_tb(&ctx, 0, ctx.pc);
1454 1489 break;
... ...