Commit 36aa55dcd9775a2164d831d3d3e2a16977995f14

Authored by pbrook
1 parent 436d124b

Add concat_i32_i64 op.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5280 c046a42c-6fe2-441c-8c8c-71466251a162
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. */