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:
commit
7602e3e4a3
@ -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
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user