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,10 +1447,7 @@ static void gen_iwmmxt_movl_T0_T1_wRn(int rn) | ||
1447 | 1447 | ||
1448 | static void gen_iwmmxt_movl_wRn_T0_T1(int rn) | 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 | iwmmxt_store_reg(cpu_V0, rn); | 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,14 +4660,11 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) | ||
4663 | } else { | 4660 | } else { |
4664 | tmp = neon_load_reg(rm + pass, 0); | 4661 | tmp = neon_load_reg(rm + pass, 0); |
4665 | gen_neon_shift_narrow(size, tmp, tmp2, q, u); | 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 | dead_tmp(tmp); | 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 | tmp = new_tmp(); | 4669 | tmp = new_tmp(); |
4676 | if (op == 8 && !u) { | 4670 | if (op == 8 && !u) { |
@@ -5600,7 +5594,7 @@ static void gen_addq_lo(DisasContext *s, TCGv val, int rlow) | @@ -5600,7 +5594,7 @@ static void gen_addq_lo(DisasContext *s, TCGv val, int rlow) | ||
5600 | TCGv tmp; | 5594 | TCGv tmp; |
5601 | TCGv tmp2; | 5595 | TCGv tmp2; |
5602 | 5596 | ||
5603 | - /* Load 64-bit value rd:rn. */ | 5597 | + /* Load value and extend to 64 bits. */ |
5604 | tmp = tcg_temp_new(TCG_TYPE_I64); | 5598 | tmp = tcg_temp_new(TCG_TYPE_I64); |
5605 | tmp2 = load_reg(s, rlow); | 5599 | tmp2 = load_reg(s, rlow); |
5606 | tcg_gen_extu_i32_i64(tmp, tmp2); | 5600 | tcg_gen_extu_i32_i64(tmp, tmp2); |
@@ -5612,19 +5606,16 @@ static void gen_addq_lo(DisasContext *s, TCGv val, int rlow) | @@ -5612,19 +5606,16 @@ static void gen_addq_lo(DisasContext *s, TCGv val, int rlow) | ||
5612 | static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh) | 5606 | static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh) |
5613 | { | 5607 | { |
5614 | TCGv tmp; | 5608 | TCGv tmp; |
5615 | - TCGv tmp2; | 5609 | + TCGv tmpl; |
5610 | + TCGv tmph; | ||
5616 | 5611 | ||
5617 | /* Load 64-bit value rd:rn. */ | 5612 | /* Load 64-bit value rd:rn. */ |
5613 | + tmpl = load_reg(s, rlow); | ||
5614 | + tmph = load_reg(s, rhigh); | ||
5618 | tmp = tcg_temp_new(TCG_TYPE_I64); | 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 | tcg_gen_add_i64(val, val, tmp); | 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,13 +693,7 @@ static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg) | ||
693 | if (ctx->hflags & MIPS_HFLAG_F64) | 693 | if (ctx->hflags & MIPS_HFLAG_F64) |
694 | tcg_gen_mov_i64(t, fpu_fpr64[reg]); | 694 | tcg_gen_mov_i64(t, fpu_fpr64[reg]); |
695 | else { | 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,22 +6540,17 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, | ||
6546 | case FOP(38, 16): | 6540 | case FOP(38, 16): |
6547 | check_cp1_64bitmode(ctx); | 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 | TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32); | 6544 | TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32); |
6552 | TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32); | 6545 | TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32); |
6553 | 6546 | ||
6554 | gen_load_fpr32(fp32_0, fs); | 6547 | gen_load_fpr32(fp32_0, fs); |
6555 | gen_load_fpr32(fp32_1, ft); | 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 | tcg_temp_free(fp32_1); | 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 | opn = "cvt.ps.s"; | 6555 | opn = "cvt.ps.s"; |
6567 | break; | 6556 | break; |
target-ppc/translate.c
@@ -5300,12 +5300,7 @@ static always_inline void gen_load_gpr64(TCGv t, int reg) { | @@ -5300,12 +5300,7 @@ static always_inline void gen_load_gpr64(TCGv t, int reg) { | ||
5300 | #if defined(TARGET_PPC64) | 5300 | #if defined(TARGET_PPC64) |
5301 | tcg_gen_mov_i64(t, cpu_gpr[reg]); | 5301 | tcg_gen_mov_i64(t, cpu_gpr[reg]); |
5302 | #else | 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 | #endif | 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,15 +400,12 @@ static inline void gen_load_fpr32(TCGv t, int reg) | ||
400 | static inline void gen_load_fpr64(TCGv t, int reg) | 400 | static inline void gen_load_fpr64(TCGv t, int reg) |
401 | { | 401 | { |
402 | TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32); | 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 | tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg])); | 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 | tcg_temp_free(tmp1); | 408 | tcg_temp_free(tmp1); |
411 | - tcg_gen_or_i64(t, t, tmp2); | ||
412 | tcg_temp_free(tmp2); | 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,6 +265,10 @@ Convert t1 (32 bit) to t0 (64 bit) and does zero extension | ||
265 | * trunc_i64_i32 t0, t1 | 265 | * trunc_i64_i32 t0, t1 |
266 | Truncate t1 (64 bit) to t0 (32 bit) | 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 | ********* Load/Store | 272 | ********* Load/Store |
269 | 273 | ||
270 | * ld_i32/i64 t0, t1, offset | 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,6 +1395,23 @@ static inline void tcg_gen_discard_i64(TCGv arg) | ||
1395 | } | 1395 | } |
1396 | #endif | 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 | /* QEMU specific operations. Their type depend on the QEMU CPU | 1416 | /* QEMU specific operations. Their type depend on the QEMU CPU |
1400 | type. */ | 1417 | type. */ |