Add concat_i32_i64 op.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5280 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									436d124b7d
								
							
						
					
					
						commit
						36aa55dcd9
					
				| 
						 | 
				
			
			@ -1447,10 +1447,7 @@ static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
 | 
			
		|||
 | 
			
		||||
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
 | 
			
		||||
{
 | 
			
		||||
    tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
 | 
			
		||||
    tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
 | 
			
		||||
    tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
 | 
			
		||||
    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
 | 
			
		||||
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
 | 
			
		||||
    iwmmxt_store_reg(cpu_V0, rn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4663,14 +4660,11 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
			
		|||
                    } else {
 | 
			
		||||
                        tmp = neon_load_reg(rm + pass, 0);
 | 
			
		||||
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
 | 
			
		||||
                        tcg_gen_extu_i32_i64(cpu_V0, tmp);
 | 
			
		||||
                        tmp3 = neon_load_reg(rm + pass, 1);
 | 
			
		||||
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
 | 
			
		||||
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
 | 
			
		||||
                        dead_tmp(tmp);
 | 
			
		||||
                        tmp = neon_load_reg(rm + pass, 1);
 | 
			
		||||
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
 | 
			
		||||
                        tcg_gen_extu_i32_i64(cpu_V1, tmp);
 | 
			
		||||
                        dead_tmp(tmp);
 | 
			
		||||
                        tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
 | 
			
		||||
                        tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
 | 
			
		||||
                        dead_tmp(tmp3);
 | 
			
		||||
                    }
 | 
			
		||||
                    tmp = new_tmp();
 | 
			
		||||
                    if (op == 8 && !u) {
 | 
			
		||||
| 
						 | 
				
			
			@ -5600,7 +5594,7 @@ static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
 | 
			
		|||
    TCGv tmp;
 | 
			
		||||
    TCGv tmp2;
 | 
			
		||||
 | 
			
		||||
    /* Load 64-bit value rd:rn.  */
 | 
			
		||||
    /* Load value and extend to 64 bits.  */
 | 
			
		||||
    tmp = tcg_temp_new(TCG_TYPE_I64);
 | 
			
		||||
    tmp2 = load_reg(s, rlow);
 | 
			
		||||
    tcg_gen_extu_i32_i64(tmp, tmp2);
 | 
			
		||||
| 
						 | 
				
			
			@ -5612,19 +5606,16 @@ static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
 | 
			
		|||
static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
 | 
			
		||||
{
 | 
			
		||||
    TCGv tmp;
 | 
			
		||||
    TCGv tmp2;
 | 
			
		||||
    TCGv tmpl;
 | 
			
		||||
    TCGv tmph;
 | 
			
		||||
 | 
			
		||||
    /* Load 64-bit value rd:rn.  */
 | 
			
		||||
    tmpl = load_reg(s, rlow);
 | 
			
		||||
    tmph = load_reg(s, rhigh);
 | 
			
		||||
    tmp = tcg_temp_new(TCG_TYPE_I64);
 | 
			
		||||
    tmp2 = load_reg(s, rhigh);
 | 
			
		||||
    tcg_gen_extu_i32_i64(tmp, tmp2);
 | 
			
		||||
    dead_tmp(tmp2);
 | 
			
		||||
    tcg_gen_shli_i64(tmp, tmp, 32);
 | 
			
		||||
    tcg_gen_add_i64(val, val, tmp);
 | 
			
		||||
 | 
			
		||||
    tmp2 = load_reg(s, rlow);
 | 
			
		||||
    tcg_gen_extu_i32_i64(tmp, tmp2);
 | 
			
		||||
    dead_tmp(tmp2);
 | 
			
		||||
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
 | 
			
		||||
    dead_tmp(tmpl);
 | 
			
		||||
    dead_tmp(tmph);
 | 
			
		||||
    tcg_gen_add_i64(val, val, tmp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -693,13 +693,7 @@ static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
 | 
			
		|||
    if (ctx->hflags & MIPS_HFLAG_F64)
 | 
			
		||||
        tcg_gen_mov_i64(t, fpu_fpr64[reg]);
 | 
			
		||||
    else {
 | 
			
		||||
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
 | 
			
		||||
 | 
			
		||||
        tcg_gen_extu_i32_i64(t, fpu_fpr32[reg | 1]);
 | 
			
		||||
        tcg_gen_shli_i64(t, t, 32);
 | 
			
		||||
        tcg_gen_extu_i32_i64(r_tmp2, fpu_fpr32[reg & ~1]);
 | 
			
		||||
        tcg_gen_or_i64(t, t, r_tmp2);
 | 
			
		||||
        tcg_temp_free(r_tmp2);
 | 
			
		||||
        tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -6546,22 +6540,17 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
 | 
			
		|||
    case FOP(38, 16):
 | 
			
		||||
        check_cp1_64bitmode(ctx);
 | 
			
		||||
        {
 | 
			
		||||
            TCGv fp64_0 = tcg_temp_new(TCG_TYPE_I64);
 | 
			
		||||
            TCGv fp64_1 = tcg_temp_new(TCG_TYPE_I64);
 | 
			
		||||
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
 | 
			
		||||
            TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32);
 | 
			
		||||
            TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32);
 | 
			
		||||
 | 
			
		||||
            gen_load_fpr32(fp32_0, fs);
 | 
			
		||||
            gen_load_fpr32(fp32_1, ft);
 | 
			
		||||
            tcg_gen_extu_i32_i64(fp64_0, fp32_0);
 | 
			
		||||
            tcg_gen_extu_i32_i64(fp64_1, fp32_1);
 | 
			
		||||
            tcg_temp_free(fp32_0);
 | 
			
		||||
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
 | 
			
		||||
            tcg_temp_free(fp32_1);
 | 
			
		||||
            tcg_gen_shli_i64(fp64_1, fp64_1, 32);
 | 
			
		||||
            tcg_gen_or_i64(fp64_0, fp64_0, fp64_1);
 | 
			
		||||
            tcg_temp_free(fp64_1);
 | 
			
		||||
            gen_store_fpr64(ctx, fp64_0, fd);
 | 
			
		||||
            tcg_temp_free(fp64_0);
 | 
			
		||||
            tcg_temp_free(fp32_0);
 | 
			
		||||
            gen_store_fpr64(ctx, fp64, fd);
 | 
			
		||||
            tcg_temp_free(fp64);
 | 
			
		||||
        }
 | 
			
		||||
        opn = "cvt.ps.s";
 | 
			
		||||
        break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5300,12 +5300,7 @@ static always_inline void gen_load_gpr64(TCGv t, int reg) {
 | 
			
		|||
#if defined(TARGET_PPC64)
 | 
			
		||||
    tcg_gen_mov_i64(t, cpu_gpr[reg]);
 | 
			
		||||
#else
 | 
			
		||||
    tcg_gen_extu_i32_i64(t, cpu_gprh[reg]);
 | 
			
		||||
    tcg_gen_shli_i64(t, t, 32);
 | 
			
		||||
    TCGv tmp = tcg_temp_local_new(TCG_TYPE_I64);
 | 
			
		||||
    tcg_gen_extu_i32_i64(tmp, cpu_gpr[reg]);
 | 
			
		||||
    tcg_gen_or_i64(t, t, tmp);
 | 
			
		||||
    tcg_temp_free(tmp);
 | 
			
		||||
    tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -400,15 +400,12 @@ static inline void gen_load_fpr32(TCGv t, int reg)
 | 
			
		|||
static inline void gen_load_fpr64(TCGv t, int reg)
 | 
			
		||||
{
 | 
			
		||||
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32);
 | 
			
		||||
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
 | 
			
		||||
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I32);
 | 
			
		||||
 | 
			
		||||
    tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
 | 
			
		||||
    tcg_gen_extu_i32_i64(t, tmp1);
 | 
			
		||||
    tcg_gen_shli_i64(t, t, 32);
 | 
			
		||||
    tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg + 1]));
 | 
			
		||||
    tcg_gen_extu_i32_i64(tmp2, tmp1);
 | 
			
		||||
    tcg_gen_ld_i32(tmp2, cpu_env, offsetof(CPUState, fregs[reg + 1]));
 | 
			
		||||
    tcg_gen_concat_i32_i64(t, tmp2, tmp1);
 | 
			
		||||
    tcg_temp_free(tmp1);
 | 
			
		||||
    tcg_gen_or_i64(t, t, tmp2);
 | 
			
		||||
    tcg_temp_free(tmp2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -265,6 +265,10 @@ Convert t1 (32 bit) to t0 (64 bit) and does zero extension
 | 
			
		|||
* trunc_i64_i32 t0, t1
 | 
			
		||||
Truncate t1 (64 bit) to t0 (32 bit)
 | 
			
		||||
 | 
			
		||||
* concat_i32_i64 t0, t1, t2
 | 
			
		||||
Construct t0 (64-bit) taking the low half from t1 (32 bit) and the high half
 | 
			
		||||
from t2 (32 bit).
 | 
			
		||||
 | 
			
		||||
********* Load/Store
 | 
			
		||||
 | 
			
		||||
* ld_i32/i64 t0, t1, offset
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								tcg/tcg-op.h
								
								
								
								
							
							
						
						
									
										17
									
								
								tcg/tcg-op.h
								
								
								
								
							| 
						 | 
				
			
			@ -1395,6 +1395,23 @@ static inline void tcg_gen_discard_i64(TCGv arg)
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static inline void tcg_gen_concat_i32_i64(TCGv dest, TCGv low, TCGv high)
 | 
			
		||||
{
 | 
			
		||||
#if TCG_TARGET_REG_BITS == 32
 | 
			
		||||
    tcg_gen_mov_i32(dest, low);
 | 
			
		||||
    tcg_gen_mov_i32(TCGV_HIGH(dest), high);
 | 
			
		||||
#else
 | 
			
		||||
    TCGv tmp = tcg_temp_new (TCG_TYPE_I64);
 | 
			
		||||
    /* This extension is only needed for type correctness.
 | 
			
		||||
       We may be able to do better given target specific information.  */
 | 
			
		||||
    tcg_gen_extu_i32_i64(tmp, high);
 | 
			
		||||
    tcg_gen_shli_i64(tmp, tmp, 32);
 | 
			
		||||
    tcg_gen_extu_i32_i64(dest, low);
 | 
			
		||||
    tcg_gen_or_i64(dest, dest, tmp);
 | 
			
		||||
    tcg_temp_free(tmp);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************/
 | 
			
		||||
/* QEMU specific operations. Their type depend on the QEMU CPU
 | 
			
		||||
   type. */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue