Commit 1000822b03f44cc0b0e624cd60e5dce8dde7d463
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
Showing
2 changed files
with
54 additions
and
118 deletions
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; | ... | ... |