target-mips: Misaligned memory accesses for MSA

MIPS SIMD Architecture vector loads and stores require misalignment support.
MSA Memory access should work as an atomic operation. Therefore, it has to
check validity of all addresses for a vector store access if it is spanning
into two pages.

Separating helper functions for each data format as format is known in
translation.
To use mmu_idx from cpu_mmu_index() instead of calculating it from hflag.
Removing save_cpu_state() call in translation because it is able to use
cpu_restore_state() on fault as GETRA() is passed.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
[leon.alrae@imgtec.com: remove unused do_* functions]
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
Yongbok Kim 2015-06-01 12:13:24 +01:00 committed by Leon Alrae
parent 3b4afc9e75
commit adc370a48f
3 changed files with 102 additions and 78 deletions

View file

@ -18423,32 +18423,39 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
uint8_t df = (ctx->opcode >> 0) & 0x3;
TCGv_i32 tdf = tcg_const_i32(df);
TCGv_i32 twd = tcg_const_i32(wd);
TCGv_i32 trs = tcg_const_i32(rs);
TCGv_i32 ts10 = tcg_const_i32(s10);
TCGv taddr = tcg_temp_new();
gen_base_offset_addr(ctx, taddr, rs, s10 << df);
switch (MASK_MSA_MINOR(opcode)) {
case OPC_LD_B:
gen_helper_msa_ld_b(cpu_env, twd, taddr);
break;
case OPC_LD_H:
gen_helper_msa_ld_h(cpu_env, twd, taddr);
break;
case OPC_LD_W:
gen_helper_msa_ld_w(cpu_env, twd, taddr);
break;
case OPC_LD_D:
save_cpu_state(ctx, 1);
gen_helper_msa_ld_df(cpu_env, tdf, twd, trs, ts10);
gen_helper_msa_ld_d(cpu_env, twd, taddr);
break;
case OPC_ST_B:
gen_helper_msa_st_b(cpu_env, twd, taddr);
break;
case OPC_ST_H:
gen_helper_msa_st_h(cpu_env, twd, taddr);
break;
case OPC_ST_W:
gen_helper_msa_st_w(cpu_env, twd, taddr);
break;
case OPC_ST_D:
save_cpu_state(ctx, 1);
gen_helper_msa_st_df(cpu_env, tdf, twd, trs, ts10);
gen_helper_msa_st_d(cpu_env, twd, taddr);
break;
}
tcg_temp_free_i32(twd);
tcg_temp_free_i32(tdf);
tcg_temp_free_i32(trs);
tcg_temp_free_i32(ts10);
tcg_temp_free(taddr);
}
break;
default: