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. */ | ... | ... |