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,70 +37,6 @@ static inline void cond_t(int cond)
37 clr_t(); 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 void OPPROTO op_ldtlb(void) 40 void OPPROTO op_ldtlb(void)
105 { 41 {
106 helper_ldtlb(); 42 helper_ldtlb();
@@ -119,13 +55,6 @@ void OPPROTO op_fschg(void) @@ -119,13 +55,6 @@ void OPPROTO op_fschg(void)
119 RETURN(); 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 void OPPROTO op_addc_T0_T1(void) 58 void OPPROTO op_addc_T0_T1(void)
130 { 59 {
131 helper_addc_T0_T1(); 60 helper_addc_T0_T1();
@@ -257,12 +186,6 @@ void OPPROTO op_trapa(void) @@ -257,12 +186,6 @@ void OPPROTO op_trapa(void)
257 RETURN(); 186 RETURN();
258 } 187 }
259 188
260 -void OPPROTO op_jmp_T0(void)  
261 -{  
262 - env->delayed_pc = T0;  
263 - RETURN();  
264 -}  
265 -  
266 void OPPROTO op_ldcl_rMplus_rN_bank(void) 189 void OPPROTO op_ldcl_rMplus_rN_bank(void)
267 { 190 {
268 env->gregs[PARAM2] = env->gregs[PARAM1]; 191 env->gregs[PARAM2] = env->gregs[PARAM1];
@@ -568,28 +491,6 @@ void OPPROTO op_movl_FT0_fpul(void) @@ -568,28 +491,6 @@ void OPPROTO op_movl_FT0_fpul(void)
568 RETURN(); 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 void OPPROTO op_raise_illegal_instruction(void) 494 void OPPROTO op_raise_illegal_instruction(void)
594 { 495 {
595 env->exception_index = 0x180; 496 env->exception_index = 0x180;
target-sh4/translate.c
@@ -62,7 +62,10 @@ static TCGv cpu_env; @@ -62,7 +62,10 @@ static TCGv cpu_env;
62 static TCGv cpu_gregs[24]; 62 static TCGv cpu_gregs[24];
63 static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; 63 static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; 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 /* dyngen register indexes */ 70 /* dyngen register indexes */
68 static TCGv cpu_T[2]; 71 static TCGv cpu_T[2];
@@ -120,6 +123,12 @@ static void sh4_translate_init(void) @@ -120,6 +123,12 @@ static void sh4_translate_init(void)
120 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, 123 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
121 offsetof(CPUState, fpul), "FPUL"); 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 /* register helpers */ 132 /* register helpers */
124 #undef DEF_HELPER 133 #undef DEF_HELPER
125 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name); 134 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
@@ -249,7 +258,7 @@ static void gen_jump(DisasContext * ctx) @@ -249,7 +258,7 @@ static void gen_jump(DisasContext * ctx)
249 if (ctx->delayed_pc == (uint32_t) - 1) { 258 if (ctx->delayed_pc == (uint32_t) - 1) {
250 /* Target is not statically known, it comes necessarily from a 259 /* Target is not statically known, it comes necessarily from a
251 delayed jump as immediate jump are conditinal jumps */ 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 if (ctx->singlestep_enabled) 262 if (ctx->singlestep_enabled)
254 gen_op_debug(); 263 gen_op_debug();
255 tcg_gen_exit_tb(0); 264 tcg_gen_exit_tb(0);
@@ -258,6 +267,16 @@ static void gen_jump(DisasContext * ctx) @@ -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 /* Immediate conditional jump (bt or bf) */ 280 /* Immediate conditional jump (bt or bf) */
262 static void gen_conditional_jump(DisasContext * ctx, 281 static void gen_conditional_jump(DisasContext * ctx,
263 target_ulong ift, target_ulong ifnott) 282 target_ulong ift, target_ulong ifnott)
@@ -265,7 +284,8 @@ static void gen_conditional_jump(DisasContext * ctx, @@ -265,7 +284,8 @@ static void gen_conditional_jump(DisasContext * ctx,
265 int l1; 284 int l1;
266 285
267 l1 = gen_new_label(); 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 gen_goto_tb(ctx, 0, ifnott); 289 gen_goto_tb(ctx, 0, ifnott);
270 gen_set_label(l1); 290 gen_set_label(l1);
271 gen_goto_tb(ctx, 1, ift); 291 gen_goto_tb(ctx, 1, ift);
@@ -277,9 +297,11 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) @@ -277,9 +297,11 @@ static void gen_delayed_conditional_jump(DisasContext * ctx)
277 int l1; 297 int l1;
278 298
279 l1 = gen_new_label(); 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 gen_goto_tb(ctx, 1, ctx->pc + 2); 302 gen_goto_tb(ctx, 1, ctx->pc + 2);
282 gen_set_label(l1); 303 gen_set_label(l1);
  304 + tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
283 gen_jump(ctx); 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,6 +339,12 @@ static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
317 gen_set_label(label2); 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 #define B3_0 (ctx->opcode & 0xf) 348 #define B3_0 (ctx->opcode & 0xf)
321 #define B6_4 ((ctx->opcode >> 4) & 0x7) 349 #define B6_4 ((ctx->opcode >> 4) & 0x7)
322 #define B7_4 ((ctx->opcode >> 4) & 0xf) 350 #define B7_4 ((ctx->opcode >> 4) & 0xf)
@@ -353,7 +381,8 @@ void _decode_opc(DisasContext * ctx) @@ -353,7 +381,8 @@ void _decode_opc(DisasContext * ctx)
353 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T)); 381 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
354 return; 382 return;
355 case 0x000b: /* rts */ 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 ctx->flags |= DELAY_SLOT; 386 ctx->flags |= DELAY_SLOT;
358 ctx->delayed_pc = (uint32_t) - 1; 387 ctx->delayed_pc = (uint32_t) - 1;
359 return; 388 return;
@@ -375,7 +404,9 @@ void _decode_opc(DisasContext * ctx) @@ -375,7 +404,9 @@ void _decode_opc(DisasContext * ctx)
375 #endif 404 #endif
376 return; 405 return;
377 case 0x002b: /* rte */ 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 ctx->flags |= DELAY_SLOT; 410 ctx->flags |= DELAY_SLOT;
380 ctx->delayed_pc = (uint32_t) - 1; 411 ctx->delayed_pc = (uint32_t) - 1;
381 return; 412 return;
@@ -436,13 +467,15 @@ void _decode_opc(DisasContext * ctx) @@ -436,13 +467,15 @@ void _decode_opc(DisasContext * ctx)
436 return; 467 return;
437 case 0xa000: /* bra disp */ 468 case 0xa000: /* bra disp */
438 CHECK_NOT_DELAY_SLOT 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 ctx->flags |= DELAY_SLOT; 472 ctx->flags |= DELAY_SLOT;
441 return; 473 return;
442 case 0xb000: /* bsr disp */ 474 case 0xb000: /* bsr disp */
443 CHECK_NOT_DELAY_SLOT 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 ctx->flags |= DELAY_SLOT; 479 ctx->flags |= DELAY_SLOT;
447 return; 480 return;
448 } 481 }
@@ -930,7 +963,7 @@ void _decode_opc(DisasContext * ctx) @@ -930,7 +963,7 @@ void _decode_opc(DisasContext * ctx)
930 return; 963 return;
931 case 0x8f00: /* bf/s label */ 964 case 0x8f00: /* bf/s label */
932 CHECK_NOT_DELAY_SLOT 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 ctx->flags |= DELAY_SLOT_CONDITIONAL; 967 ctx->flags |= DELAY_SLOT_CONDITIONAL;
935 return; 968 return;
936 case 0x8900: /* bt label */ 969 case 0x8900: /* bt label */
@@ -941,7 +974,7 @@ void _decode_opc(DisasContext * ctx) @@ -941,7 +974,7 @@ void _decode_opc(DisasContext * ctx)
941 return; 974 return;
942 case 0x8d00: /* bt/s label */ 975 case 0x8d00: /* bt/s label */
943 CHECK_NOT_DELAY_SLOT 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 ctx->flags |= DELAY_SLOT_CONDITIONAL; 978 ctx->flags |= DELAY_SLOT_CONDITIONAL;
946 return; 979 return;
947 case 0x8800: /* cmp/eq #imm,R0 */ 980 case 0x8800: /* cmp/eq #imm,R0 */
@@ -1083,13 +1116,14 @@ void _decode_opc(DisasContext * ctx) @@ -1083,13 +1116,14 @@ void _decode_opc(DisasContext * ctx)
1083 switch (ctx->opcode & 0xf0ff) { 1116 switch (ctx->opcode & 0xf0ff) {
1084 case 0x0023: /* braf Rn */ 1117 case 0x0023: /* braf Rn */
1085 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]); 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 ctx->flags |= DELAY_SLOT; 1120 ctx->flags |= DELAY_SLOT;
1088 ctx->delayed_pc = (uint32_t) - 1; 1121 ctx->delayed_pc = (uint32_t) - 1;
1089 return; 1122 return;
1090 case 0x0003: /* bsrf Rn */ 1123 case 0x0003: /* bsrf Rn */
1091 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]); 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 ctx->flags |= DELAY_SLOT; 1127 ctx->flags |= DELAY_SLOT;
1094 ctx->delayed_pc = (uint32_t) - 1; 1128 ctx->delayed_pc = (uint32_t) - 1;
1095 return; 1129 return;
@@ -1107,13 +1141,14 @@ void _decode_opc(DisasContext * ctx) @@ -1107,13 +1141,14 @@ void _decode_opc(DisasContext * ctx)
1107 return; 1141 return;
1108 case 0x402b: /* jmp @Rn */ 1142 case 0x402b: /* jmp @Rn */
1109 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]); 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 ctx->flags |= DELAY_SLOT; 1145 ctx->flags |= DELAY_SLOT;
1112 ctx->delayed_pc = (uint32_t) - 1; 1146 ctx->delayed_pc = (uint32_t) - 1;
1113 return; 1147 return;
1114 case 0x400b: /* jsr @Rn */ 1148 case 0x400b: /* jsr @Rn */
1115 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]); 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 ctx->flags |= DELAY_SLOT; 1152 ctx->flags |= DELAY_SLOT;
1118 ctx->delayed_pc = (uint32_t) - 1; 1153 ctx->delayed_pc = (uint32_t) - 1;
1119 return; 1154 return;
@@ -1332,12 +1367,12 @@ void decode_opc(DisasContext * ctx) @@ -1332,12 +1367,12 @@ void decode_opc(DisasContext * ctx)
1332 1367
1333 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { 1368 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1334 if (ctx->flags & DELAY_SLOT_CLEARME) { 1369 if (ctx->flags & DELAY_SLOT_CLEARME) {
1335 - gen_op_store_flags(0); 1370 + gen_store_flags(0);
1336 } else { 1371 } else {
1337 /* go out of the delay slot */ 1372 /* go out of the delay slot */
1338 uint32_t new_flags = ctx->flags; 1373 uint32_t new_flags = ctx->flags;
1339 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL); 1374 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1340 - gen_op_store_flags(new_flags); 1375 + gen_store_flags(new_flags);
1341 } 1376 }
1342 ctx->flags = 0; 1377 ctx->flags = 0;
1343 ctx->bstate = BS_BRANCH; 1378 ctx->bstate = BS_BRANCH;
@@ -1351,7 +1386,7 @@ void decode_opc(DisasContext * ctx) @@ -1351,7 +1386,7 @@ void decode_opc(DisasContext * ctx)
1351 1386
1352 /* go into a delay slot */ 1387 /* go into a delay slot */
1353 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) 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 static inline void 1392 static inline void
@@ -1448,7 +1483,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, @@ -1448,7 +1483,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1448 /* fall through */ 1483 /* fall through */
1449 case BS_NONE: 1484 case BS_NONE:
1450 if (ctx.flags) { 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 gen_goto_tb(&ctx, 0, ctx.pc); 1488 gen_goto_tb(&ctx, 0, ctx.pc);
1454 break; 1489 break;