Merge remote-tracking branch 'remotes/mcayland/qemu-sparc' into staging

* remotes/mcayland/qemu-sparc:
  target-sparc: Add and use CPU_FEATURE_CASA

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-03-12 11:44:59 +00:00
commit 7602e3e4a3
5 changed files with 58 additions and 34 deletions

View file

@ -458,7 +458,8 @@ static const sparc_def_t sparc_defs[] = {
.mmu_trcr_mask = 0xffffffff,
.nwindows = 8,
.features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN,
CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN |
CPU_FEATURE_CASA,
},
#endif
};

View file

@ -271,6 +271,7 @@ typedef struct sparc_def_t {
#define CPU_FEATURE_ASR17 (1 << 15)
#define CPU_FEATURE_CACHE_CTRL (1 << 16)
#define CPU_FEATURE_POWERDOWN (1 << 17)
#define CPU_FEATURE_CASA (1 << 18)
#ifndef TARGET_SPARC64
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
@ -282,7 +283,8 @@ typedef struct sparc_def_t {
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD)
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD | \
CPU_FEATURE_CASA)
enum {
mmu_us_12, // Ultrasparc < III (64 entry TLB)
mmu_us_3, // Ultrasparc III (512 entry TLB)

View file

@ -22,7 +22,6 @@ DEF_HELPER_1(popc, tl, tl)
DEF_HELPER_4(ldda_asi, void, env, tl, int, int)
DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
DEF_HELPER_5(stf_asi, void, env, tl, int, int, int)
DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
DEF_HELPER_5(casx_asi, tl, env, tl, tl, tl, i32)
DEF_HELPER_2(set_softint, void, env, i64)
DEF_HELPER_2(clear_softint, void, env, i64)
@ -31,6 +30,9 @@ DEF_HELPER_2(tick_set_count, void, ptr, i64)
DEF_HELPER_1(tick_get_count, i64, ptr)
DEF_HELPER_2(tick_set_limit, void, ptr, i64)
#endif
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
#endif
DEF_HELPER_3(check_align, void, env, tl, i32)
DEF_HELPER_1(debug, void, env)
DEF_HELPER_1(save, void, env)

View file

@ -584,6 +584,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
}
break;
case 0xb: /* Supervisor data access */
case 0x80:
switch (size) {
case 1:
ret = cpu_ldub_kernel(env, addr);
@ -955,6 +956,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
}
break;
case 0xb: /* Supervisor data access */
case 0x80:
switch (size) {
case 1:
cpu_stb_kernel(env, addr, val);
@ -2232,20 +2234,6 @@ void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
}
}
target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
target_ulong val1, target_ulong val2, uint32_t asi)
{
target_ulong ret;
val2 &= 0xffffffffUL;
ret = helper_ld_asi(env, addr, asi, 4, 0);
ret &= 0xffffffffUL;
if (val2 == ret) {
helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
}
return ret;
}
target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
target_ulong val1, target_ulong val2,
uint32_t asi)
@ -2260,6 +2248,22 @@ target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
}
#endif /* TARGET_SPARC64 */
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
target_ulong val1, target_ulong val2, uint32_t asi)
{
target_ulong ret;
val2 &= 0xffffffffUL;
ret = helper_ld_asi(env, addr, asi, 4, 0);
ret &= 0xffffffffUL;
if (val2 == ret) {
helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
}
return ret;
}
#endif /* !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) */
void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
{
/* XXX add 128 bit load */

View file

@ -2107,18 +2107,6 @@ static inline void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
tcg_temp_free_i64(t64);
}
static inline void gen_cas_asi(DisasContext *dc, TCGv addr,
TCGv val2, int insn, int rd)
{
TCGv val1 = gen_load_gpr(dc, rd);
TCGv dst = gen_dest_gpr(dc, rd);
TCGv_i32 r_asi = gen_get_asi(insn, addr);
gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
tcg_temp_free_i32(r_asi);
gen_store_gpr(dc, rd, dst);
}
static inline void gen_casx_asi(DisasContext *dc, TCGv addr,
TCGv val2, int insn, int rd)
{
@ -2229,6 +2217,22 @@ static inline void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
#endif
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
static inline void gen_cas_asi(DisasContext *dc, TCGv addr,
TCGv val2, int insn, int rd)
{
TCGv val1 = gen_load_gpr(dc, rd);
TCGv dst = gen_dest_gpr(dc, rd);
#ifdef TARGET_SPARC64
TCGv_i32 r_asi = gen_get_asi(insn, addr);
#else
TCGv_i32 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
#endif
gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
tcg_temp_free_i32(r_asi);
gen_store_gpr(dc, rd, dst);
}
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
{
TCGv_i64 r_val;
@ -5103,11 +5107,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
}
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
break;
case 0x3c: /* V9 casa */
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
break;
case 0x3e: /* V9 casxa */
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
@ -5119,6 +5118,22 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 0x36: /* stdcq */
case 0x37: /* stdc */
goto ncp_insn;
#endif
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x3c: /* V9 or LEON3 casa */
#ifndef TARGET_SPARC64
CHECK_IU_FEATURE(dc, CASA);
if (IS_IMM) {
goto illegal_insn;
}
if (!supervisor(dc)) {
goto priv_insn;
}
#endif
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
break;
#endif
default:
goto illegal_insn;