diff options
Diffstat (limited to 'target-sparc/translate.c')
-rw-r--r-- | target-sparc/translate.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 6150b22f8f..46d7859e97 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -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); @@ -5120,6 +5119,22 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) 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; } |