Commit 36aa55dcd9775a2164d831d3d3e2a16977995f14
1 parent
436d124b
Add concat_i32_i64 op.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5280 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
44 additions
and
51 deletions
target-arm/translate.c
| ... | ... | @@ -1447,10 +1447,7 @@ static void gen_iwmmxt_movl_T0_T1_wRn(int rn) |
| 1447 | 1447 | |
| 1448 | 1448 | static void gen_iwmmxt_movl_wRn_T0_T1(int rn) |
| 1449 | 1449 | { |
| 1450 | - tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]); | |
| 1451 | - tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]); | |
| 1452 | - tcg_gen_shli_i64(cpu_V1, cpu_V1, 32); | |
| 1453 | - tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); | |
| 1450 | + tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]); | |
| 1454 | 1451 | iwmmxt_store_reg(cpu_V0, rn); |
| 1455 | 1452 | } |
| 1456 | 1453 | |
| ... | ... | @@ -4663,14 +4660,11 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 4663 | 4660 | } else { |
| 4664 | 4661 | tmp = neon_load_reg(rm + pass, 0); |
| 4665 | 4662 | gen_neon_shift_narrow(size, tmp, tmp2, q, u); |
| 4666 | - tcg_gen_extu_i32_i64(cpu_V0, tmp); | |
| 4663 | + tmp3 = neon_load_reg(rm + pass, 1); | |
| 4664 | + gen_neon_shift_narrow(size, tmp3, tmp2, q, u); | |
| 4665 | + tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3); | |
| 4667 | 4666 | dead_tmp(tmp); |
| 4668 | - tmp = neon_load_reg(rm + pass, 1); | |
| 4669 | - gen_neon_shift_narrow(size, tmp, tmp2, q, u); | |
| 4670 | - tcg_gen_extu_i32_i64(cpu_V1, tmp); | |
| 4671 | - dead_tmp(tmp); | |
| 4672 | - tcg_gen_shli_i64(cpu_V1, cpu_V1, 32); | |
| 4673 | - tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); | |
| 4667 | + dead_tmp(tmp3); | |
| 4674 | 4668 | } |
| 4675 | 4669 | tmp = new_tmp(); |
| 4676 | 4670 | if (op == 8 && !u) { |
| ... | ... | @@ -5600,7 +5594,7 @@ static void gen_addq_lo(DisasContext *s, TCGv val, int rlow) |
| 5600 | 5594 | TCGv tmp; |
| 5601 | 5595 | TCGv tmp2; |
| 5602 | 5596 | |
| 5603 | - /* Load 64-bit value rd:rn. */ | |
| 5597 | + /* Load value and extend to 64 bits. */ | |
| 5604 | 5598 | tmp = tcg_temp_new(TCG_TYPE_I64); |
| 5605 | 5599 | tmp2 = load_reg(s, rlow); |
| 5606 | 5600 | tcg_gen_extu_i32_i64(tmp, tmp2); |
| ... | ... | @@ -5612,19 +5606,16 @@ static void gen_addq_lo(DisasContext *s, TCGv val, int rlow) |
| 5612 | 5606 | static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh) |
| 5613 | 5607 | { |
| 5614 | 5608 | TCGv tmp; |
| 5615 | - TCGv tmp2; | |
| 5609 | + TCGv tmpl; | |
| 5610 | + TCGv tmph; | |
| 5616 | 5611 | |
| 5617 | 5612 | /* Load 64-bit value rd:rn. */ |
| 5613 | + tmpl = load_reg(s, rlow); | |
| 5614 | + tmph = load_reg(s, rhigh); | |
| 5618 | 5615 | tmp = tcg_temp_new(TCG_TYPE_I64); |
| 5619 | - tmp2 = load_reg(s, rhigh); | |
| 5620 | - tcg_gen_extu_i32_i64(tmp, tmp2); | |
| 5621 | - dead_tmp(tmp2); | |
| 5622 | - tcg_gen_shli_i64(tmp, tmp, 32); | |
| 5623 | - tcg_gen_add_i64(val, val, tmp); | |
| 5624 | - | |
| 5625 | - tmp2 = load_reg(s, rlow); | |
| 5626 | - tcg_gen_extu_i32_i64(tmp, tmp2); | |
| 5627 | - dead_tmp(tmp2); | |
| 5616 | + tcg_gen_concat_i32_i64(tmp, tmpl, tmph); | |
| 5617 | + dead_tmp(tmpl); | |
| 5618 | + dead_tmp(tmph); | |
| 5628 | 5619 | tcg_gen_add_i64(val, val, tmp); |
| 5629 | 5620 | } |
| 5630 | 5621 | ... | ... |
target-mips/translate.c
| ... | ... | @@ -693,13 +693,7 @@ static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg) |
| 693 | 693 | if (ctx->hflags & MIPS_HFLAG_F64) |
| 694 | 694 | tcg_gen_mov_i64(t, fpu_fpr64[reg]); |
| 695 | 695 | else { |
| 696 | - TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); | |
| 697 | - | |
| 698 | - tcg_gen_extu_i32_i64(t, fpu_fpr32[reg | 1]); | |
| 699 | - tcg_gen_shli_i64(t, t, 32); | |
| 700 | - tcg_gen_extu_i32_i64(r_tmp2, fpu_fpr32[reg & ~1]); | |
| 701 | - tcg_gen_or_i64(t, t, r_tmp2); | |
| 702 | - tcg_temp_free(r_tmp2); | |
| 696 | + tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]); | |
| 703 | 697 | } |
| 704 | 698 | } |
| 705 | 699 | |
| ... | ... | @@ -6546,22 +6540,17 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6546 | 6540 | case FOP(38, 16): |
| 6547 | 6541 | check_cp1_64bitmode(ctx); |
| 6548 | 6542 | { |
| 6549 | - TCGv fp64_0 = tcg_temp_new(TCG_TYPE_I64); | |
| 6550 | - TCGv fp64_1 = tcg_temp_new(TCG_TYPE_I64); | |
| 6543 | + TCGv fp64 = tcg_temp_new(TCG_TYPE_I64); | |
| 6551 | 6544 | TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32); |
| 6552 | 6545 | TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32); |
| 6553 | 6546 | |
| 6554 | 6547 | gen_load_fpr32(fp32_0, fs); |
| 6555 | 6548 | gen_load_fpr32(fp32_1, ft); |
| 6556 | - tcg_gen_extu_i32_i64(fp64_0, fp32_0); | |
| 6557 | - tcg_gen_extu_i32_i64(fp64_1, fp32_1); | |
| 6558 | - tcg_temp_free(fp32_0); | |
| 6549 | + tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1); | |
| 6559 | 6550 | tcg_temp_free(fp32_1); |
| 6560 | - tcg_gen_shli_i64(fp64_1, fp64_1, 32); | |
| 6561 | - tcg_gen_or_i64(fp64_0, fp64_0, fp64_1); | |
| 6562 | - tcg_temp_free(fp64_1); | |
| 6563 | - gen_store_fpr64(ctx, fp64_0, fd); | |
| 6564 | - tcg_temp_free(fp64_0); | |
| 6551 | + tcg_temp_free(fp32_0); | |
| 6552 | + gen_store_fpr64(ctx, fp64, fd); | |
| 6553 | + tcg_temp_free(fp64); | |
| 6565 | 6554 | } |
| 6566 | 6555 | opn = "cvt.ps.s"; |
| 6567 | 6556 | break; | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -5300,12 +5300,7 @@ static always_inline void gen_load_gpr64(TCGv t, int reg) { |
| 5300 | 5300 | #if defined(TARGET_PPC64) |
| 5301 | 5301 | tcg_gen_mov_i64(t, cpu_gpr[reg]); |
| 5302 | 5302 | #else |
| 5303 | - tcg_gen_extu_i32_i64(t, cpu_gprh[reg]); | |
| 5304 | - tcg_gen_shli_i64(t, t, 32); | |
| 5305 | - TCGv tmp = tcg_temp_local_new(TCG_TYPE_I64); | |
| 5306 | - tcg_gen_extu_i32_i64(tmp, cpu_gpr[reg]); | |
| 5307 | - tcg_gen_or_i64(t, t, tmp); | |
| 5308 | - tcg_temp_free(tmp); | |
| 5303 | + tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]); | |
| 5309 | 5304 | #endif |
| 5310 | 5305 | } |
| 5311 | 5306 | ... | ... |
target-sh4/translate.c
| ... | ... | @@ -400,15 +400,12 @@ static inline void gen_load_fpr32(TCGv t, int reg) |
| 400 | 400 | static inline void gen_load_fpr64(TCGv t, int reg) |
| 401 | 401 | { |
| 402 | 402 | TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32); |
| 403 | - TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64); | |
| 403 | + TCGv tmp2 = tcg_temp_new(TCG_TYPE_I32); | |
| 404 | 404 | |
| 405 | 405 | tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg])); |
| 406 | - tcg_gen_extu_i32_i64(t, tmp1); | |
| 407 | - tcg_gen_shli_i64(t, t, 32); | |
| 408 | - tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg + 1])); | |
| 409 | - tcg_gen_extu_i32_i64(tmp2, tmp1); | |
| 406 | + tcg_gen_ld_i32(tmp2, cpu_env, offsetof(CPUState, fregs[reg + 1])); | |
| 407 | + tcg_gen_concat_i32_i64(t, tmp2, tmp1); | |
| 410 | 408 | tcg_temp_free(tmp1); |
| 411 | - tcg_gen_or_i64(t, t, tmp2); | |
| 412 | 409 | tcg_temp_free(tmp2); |
| 413 | 410 | } |
| 414 | 411 | ... | ... |
tcg/README
| ... | ... | @@ -265,6 +265,10 @@ Convert t1 (32 bit) to t0 (64 bit) and does zero extension |
| 265 | 265 | * trunc_i64_i32 t0, t1 |
| 266 | 266 | Truncate t1 (64 bit) to t0 (32 bit) |
| 267 | 267 | |
| 268 | +* concat_i32_i64 t0, t1, t2 | |
| 269 | +Construct t0 (64-bit) taking the low half from t1 (32 bit) and the high half | |
| 270 | +from t2 (32 bit). | |
| 271 | + | |
| 268 | 272 | ********* Load/Store |
| 269 | 273 | |
| 270 | 274 | * ld_i32/i64 t0, t1, offset | ... | ... |
tcg/tcg-op.h
| ... | ... | @@ -1395,6 +1395,23 @@ static inline void tcg_gen_discard_i64(TCGv arg) |
| 1395 | 1395 | } |
| 1396 | 1396 | #endif |
| 1397 | 1397 | |
| 1398 | +static inline void tcg_gen_concat_i32_i64(TCGv dest, TCGv low, TCGv high) | |
| 1399 | +{ | |
| 1400 | +#if TCG_TARGET_REG_BITS == 32 | |
| 1401 | + tcg_gen_mov_i32(dest, low); | |
| 1402 | + tcg_gen_mov_i32(TCGV_HIGH(dest), high); | |
| 1403 | +#else | |
| 1404 | + TCGv tmp = tcg_temp_new (TCG_TYPE_I64); | |
| 1405 | + /* This extension is only needed for type correctness. | |
| 1406 | + We may be able to do better given target specific information. */ | |
| 1407 | + tcg_gen_extu_i32_i64(tmp, high); | |
| 1408 | + tcg_gen_shli_i64(tmp, tmp, 32); | |
| 1409 | + tcg_gen_extu_i32_i64(dest, low); | |
| 1410 | + tcg_gen_or_i64(dest, dest, tmp); | |
| 1411 | + tcg_temp_free(tmp); | |
| 1412 | +#endif | |
| 1413 | +} | |
| 1414 | + | |
| 1398 | 1415 | /***************************************/ |
| 1399 | 1416 | /* QEMU specific operations. Their type depend on the QEMU CPU |
| 1400 | 1417 | type. */ | ... | ... |