target_ulong cpu_read_xer(CPUPPCState *env)
{
+ if (is_isa300(env)) {
+ return env->xer | (env->so << XER_SO) |
+ (env->ov << XER_OV) | (env->ca << XER_CA) |
+ (env->ov32 << XER_OV32) | (env->ca32 << XER_CA32);
+ }
+
return env->xer | (env->so << XER_SO) | (env->ov << XER_OV) |
(env->ca << XER_CA);
}
env->so = (xer >> XER_SO) & 1;
env->ov = (xer >> XER_OV) & 1;
env->ca = (xer >> XER_CA) & 1;
- env->xer = xer & ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA));
+ /* write all the flags, while reading back check of isa300 */
+ env->ov32 = (xer >> XER_OV32) & 1;
+ env->ca32 = (xer >> XER_CA32) & 1;
+ env->xer = xer & ~((1ul << XER_SO) |
+ (1ul << XER_OV) | (1ul << XER_CA) |
+ (1ul << XER_OV32) | (1ul << XER_CA32));
}
target_ulong so;
target_ulong ov;
target_ulong ca;
+ target_ulong ov32;
+ target_ulong ca32;
/* Reservation address */
target_ulong reserve_addr;
/* Reservation value */
#define XER_SO 31
#define XER_OV 30
#define XER_CA 29
+#define XER_OV32 19
+#define XER_CA32 18
#define XER_CMP 8
#define XER_BC 0
#define xer_so (env->so)
#define xer_ov (env->ov)
#define xer_ca (env->ca)
+#define xer_ov32 (env->ov)
+#define xer_ca32 (env->ca)
#define xer_cmp ((env->xer >> XER_CMP) & 0xFF)
#define xer_bc ((env->xer >> XER_BC) & 0x7F)
/*****************************************************************************/
+#define is_isa300(ctx) (!!(ctx->insns_flags2 & PPC2_ISA300))
target_ulong cpu_read_xer(CPUPPCState *env);
void cpu_write_xer(CPUPPCState *env, target_ulong xer);
#if defined(TARGET_PPC64)
static TCGv cpu_cfar;
#endif
-static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca;
+static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca, cpu_ov32, cpu_ca32;
static TCGv cpu_reserve;
static TCGv cpu_fpscr;
static TCGv_i32 cpu_access_type;
offsetof(CPUPPCState, ov), "OV");
cpu_ca = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, ca), "CA");
+ cpu_ov32 = tcg_global_mem_new(cpu_env,
+ offsetof(CPUPPCState, ov32), "OV32");
+ cpu_ca32 = tcg_global_mem_new(cpu_env,
+ offsetof(CPUPPCState, ca32), "CA32");
cpu_reserve = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, reserve_addr),
/*** Processor control ***/
-static void gen_read_xer(TCGv dst)
+static void gen_read_xer(DisasContext *ctx, TCGv dst)
{
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
tcg_gen_or_tl(t0, t0, t1);
tcg_gen_or_tl(dst, dst, t2);
tcg_gen_or_tl(dst, dst, t0);
+ if (is_isa300(ctx)) {
+ tcg_gen_shli_tl(t0, cpu_ov32, XER_OV32);
+ tcg_gen_or_tl(dst, dst, t0);
+ tcg_gen_shli_tl(t0, cpu_ca32, XER_CA32);
+ tcg_gen_or_tl(dst, dst, t0);
+ }
tcg_temp_free(t0);
tcg_temp_free(t1);
tcg_temp_free(t2);
static void gen_write_xer(TCGv src)
{
+ /* Write all flags, while reading back check for isa300 */
tcg_gen_andi_tl(cpu_xer, src,
- ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA)));
+ ~((1u << XER_SO) |
+ (1u << XER_OV) | (1u << XER_OV32) |
+ (1u << XER_CA) | (1u << XER_CA32)));
+ tcg_gen_extract_tl(cpu_ov32, src, XER_OV32, 1);
+ tcg_gen_extract_tl(cpu_ca32, src, XER_CA32, 1);
tcg_gen_extract_tl(cpu_so, src, XER_SO, 1);
tcg_gen_extract_tl(cpu_ov, src, XER_OV, 1);
tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1);