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,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
.nwindows = 8,
|
.nwindows = 8,
|
||||||
.features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
|
.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
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -271,6 +271,7 @@ typedef struct sparc_def_t {
|
|||||||
#define CPU_FEATURE_ASR17 (1 << 15)
|
#define CPU_FEATURE_ASR17 (1 << 15)
|
||||||
#define CPU_FEATURE_CACHE_CTRL (1 << 16)
|
#define CPU_FEATURE_CACHE_CTRL (1 << 16)
|
||||||
#define CPU_FEATURE_POWERDOWN (1 << 17)
|
#define CPU_FEATURE_POWERDOWN (1 << 17)
|
||||||
|
#define CPU_FEATURE_CASA (1 << 18)
|
||||||
|
|
||||||
#ifndef TARGET_SPARC64
|
#ifndef TARGET_SPARC64
|
||||||
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
|
#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_MUL | CPU_FEATURE_DIV | \
|
||||||
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
||||||
CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
|
CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
|
||||||
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD)
|
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD | \
|
||||||
|
CPU_FEATURE_CASA)
|
||||||
enum {
|
enum {
|
||||||
mmu_us_12, // Ultrasparc < III (64 entry TLB)
|
mmu_us_12, // Ultrasparc < III (64 entry TLB)
|
||||||
mmu_us_3, // Ultrasparc III (512 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_4(ldda_asi, void, env, tl, int, int)
|
||||||
DEF_HELPER_5(ldf_asi, void, env, tl, int, 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(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_5(casx_asi, tl, env, tl, tl, tl, i32)
|
||||||
DEF_HELPER_2(set_softint, void, env, i64)
|
DEF_HELPER_2(set_softint, void, env, i64)
|
||||||
DEF_HELPER_2(clear_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_1(tick_get_count, i64, ptr)
|
||||||
DEF_HELPER_2(tick_set_limit, void, ptr, i64)
|
DEF_HELPER_2(tick_set_limit, void, ptr, i64)
|
||||||
#endif
|
#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_3(check_align, void, env, tl, i32)
|
||||||
DEF_HELPER_1(debug, void, env)
|
DEF_HELPER_1(debug, void, env)
|
||||||
DEF_HELPER_1(save, 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;
|
break;
|
||||||
case 0xb: /* Supervisor data access */
|
case 0xb: /* Supervisor data access */
|
||||||
|
case 0x80:
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
ret = cpu_ldub_kernel(env, addr);
|
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;
|
break;
|
||||||
case 0xb: /* Supervisor data access */
|
case 0xb: /* Supervisor data access */
|
||||||
|
case 0x80:
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
cpu_stb_kernel(env, addr, val);
|
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 helper_casx_asi(CPUSPARCState *env, target_ulong addr,
|
||||||
target_ulong val1, target_ulong val2,
|
target_ulong val1, target_ulong val2,
|
||||||
uint32_t asi)
|
uint32_t asi)
|
||||||
@ -2260,6 +2248,22 @@ target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
|
|||||||
}
|
}
|
||||||
#endif /* TARGET_SPARC64 */
|
#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)
|
void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
|
||||||
{
|
{
|
||||||
/* XXX add 128 bit load */
|
/* 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);
|
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,
|
static inline void gen_casx_asi(DisasContext *dc, TCGv addr,
|
||||||
TCGv val2, int insn, int rd)
|
TCGv val2, int insn, int rd)
|
||||||
{
|
{
|
||||||
@ -2229,6 +2217,22 @@ static inline void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
#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)
|
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
|
||||||
{
|
{
|
||||||
TCGv_i64 r_val;
|
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));
|
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
|
||||||
break;
|
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 */
|
case 0x3e: /* V9 casxa */
|
||||||
rs2 = GET_FIELD(insn, 27, 31);
|
rs2 = GET_FIELD(insn, 27, 31);
|
||||||
cpu_src2 = gen_load_gpr(dc, rs2);
|
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 0x36: /* stdcq */
|
||||||
case 0x37: /* stdc */
|
case 0x37: /* stdc */
|
||||||
goto ncp_insn;
|
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
|
#endif
|
||||||
default:
|
default:
|
||||||
goto illegal_insn;
|
goto illegal_insn;
|
||||||
|
Loading…
Reference in New Issue
Block a user