/* Save Altivec registers if necessary. */
if (env->insns_flags & PPC_ALTIVEC) {
uint32_t *vrsave;
- for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
- ppc_avr_t *avr = &env->avr[i];
+ for (i = 0; i < 32; i++) {
+ ppc_avr_t *avr = cpu_avr_ptr(env, i);
ppc_avr_t *vreg = (ppc_avr_t *)&frame->mc_vregs.altivec[i];
__put_user(avr->u64[PPC_VEC_HI], &vreg->u64[0]);
/* Save VSX second halves */
if (env->insns_flags2 & PPC2_VSX) {
uint64_t *vsregs = (uint64_t *)&frame->mc_vregs.altivec[34];
- for (i = 0; i < ARRAY_SIZE(env->vsr); i++) {
- __put_user(env->vsr[i], &vsregs[i]);
+ for (i = 0; i < 32; i++) {
+ uint64_t *vsrl = cpu_vsrl_ptr(env, i);
+ __put_user(*vsrl, &vsregs[i]);
}
}
/* Save floating point registers. */
if (env->insns_flags & PPC_FLOAT) {
- for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
- __put_user(env->fpr[i], &frame->mc_fregs[i]);
+ for (i = 0; i < 32; i++) {
+ uint64_t *fpr = cpu_fpr_ptr(env, i);
+ __put_user(*fpr, &frame->mc_fregs[i]);
}
__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]);
}
#else
v_regs = (ppc_avr_t *)frame->mc_vregs.altivec;
#endif
- for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
- ppc_avr_t *avr = &env->avr[i];
+ for (i = 0; i < 32; i++) {
+ ppc_avr_t *avr = cpu_avr_ptr(env, i);
ppc_avr_t *vreg = &v_regs[i];
__get_user(avr->u64[PPC_VEC_HI], &vreg->u64[0]);
/* Restore VSX second halves */
if (env->insns_flags2 & PPC2_VSX) {
uint64_t *vsregs = (uint64_t *)&frame->mc_vregs.altivec[34];
- for (i = 0; i < ARRAY_SIZE(env->vsr); i++) {
- __get_user(env->vsr[i], &vsregs[i]);
+ for (i = 0; i < 32; i++) {
+ uint64_t *vsrl = cpu_vsrl_ptr(env, i);
+ __get_user(*vsrl, &vsregs[i]);
}
}
/* Restore floating point registers. */
if (env->insns_flags & PPC_FLOAT) {
uint64_t fpscr;
- for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
- __get_user(env->fpr[i], &frame->mc_fregs[i]);
+ for (i = 0; i < 32; i++) {
+ uint64_t *fpr = cpu_fpr_ptr(env, i);
+ __get_user(*fpr, &frame->mc_fregs[i]);
}
__get_user(fpscr, &frame->mc_fregs[32]);
env->fpscr = (uint32_t) fpscr;
memset(fpregset, 0, sizeof(*fpregset));
for (i = 0; i < 32; i++) {
- fpregset->fpr[i] = cpu_to_dump64(s, cpu->env.fpr[i]);
+ uint64_t *fpr = cpu_fpr_ptr(&cpu->env, i);
+ fpregset->fpr[i] = cpu_to_dump64(s, *fpr);
}
fpregset->fpscr = cpu_to_dump_reg(s, cpu->env.fpscr);
}
for (i = 0; i < 32; i++) {
bool needs_byteswap;
+ ppc_avr_t *avr = cpu_avr_ptr(&cpu->env, i);
#ifdef HOST_WORDS_BIGENDIAN
needs_byteswap = s->dump_info.d_endian == ELFDATA2LSB;
#endif
if (needs_byteswap) {
- vmxregset->avr[i].u64[0] = bswap64(cpu->env.avr[i].u64[1]);
- vmxregset->avr[i].u64[1] = bswap64(cpu->env.avr[i].u64[0]);
+ vmxregset->avr[i].u64[0] = bswap64(avr->u64[1]);
+ vmxregset->avr[i].u64[1] = bswap64(avr->u64[0]);
} else {
- vmxregset->avr[i].u64[0] = cpu->env.avr[i].u64[0];
- vmxregset->avr[i].u64[1] = cpu->env.avr[i].u64[1];
+ vmxregset->avr[i].u64[0] = avr->u64[0];
+ vmxregset->avr[i].u64[1] = avr->u64[1];
}
}
vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr);
memset(vsxregset, 0, sizeof(*vsxregset));
for (i = 0; i < 32; i++) {
- vsxregset->vsr[i] = cpu_to_dump64(s, cpu->env.vsr[i]);
+ uint64_t *vsrl = cpu_vsrl_ptr(&cpu->env, i);
+ vsxregset->vsr[i] = cpu_to_dump64(s, *vsrl);
}
}
/* Floating point execution context */
float_status fp_status;
- /* floating point registers */
- float64 fpr[32];
/* floating point status and control register */
target_ulong fpscr;
/* Special purpose registers */
target_ulong spr[1024];
ppc_spr_t spr_cb[1024];
- /* Altivec registers */
- ppc_avr_t avr[32];
+ /* Vector status and control register */
uint32_t vscr;
- /* VSX registers */
- uint64_t vsr[32];
+ /* VSX registers (including FP and AVR) */
+ ppc_vsr_t vsr[64] QEMU_ALIGNED(16);
/* SPE registers */
uint64_t spe_acc;
uint32_t spe_fscr;
(start + nregs > 32 && (rx >= start || rx < start + nregs - 32));
}
+/* Accessors for FP, VMX and VSX registers */
+static inline uint64_t *cpu_fpr_ptr(CPUPPCState *env, int i)
+{
+ return &env->vsr[i].u64[0];
+}
+
+static inline uint64_t *cpu_vsrl_ptr(CPUPPCState *env, int i)
+{
+ return &env->vsr[i].u64[1];
+}
+
+static inline ppc_avr_t *cpu_avr_ptr(CPUPPCState *env, int i)
+{
+ return &env->vsr[32 + i];
+}
+
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len);
gdb_get_regl(mem_buf, env->gpr[n]);
} else if (n < 64) {
/* fprs */
- stfq_p(mem_buf, env->fpr[n-32]);
+ stfq_p(mem_buf, *cpu_fpr_ptr(env, n - 32));
} else {
switch (n) {
case 64:
gdb_get_reg64(mem_buf, env->gpr[n]);
} else if (n < 64) {
/* fprs */
- stfq_p(mem_buf, env->fpr[n-32]);
+ stfq_p(mem_buf, *cpu_fpr_ptr(env, n - 32));
} else if (n < 96) {
/* Altivec */
stq_p(mem_buf, n - 64);
env->gpr[n] = ldtul_p(mem_buf);
} else if (n < 64) {
/* fprs */
- env->fpr[n-32] = ldfq_p(mem_buf);
+ *cpu_fpr_ptr(env, n - 32) = ldfq_p(mem_buf);
} else {
switch (n) {
case 64:
env->gpr[n] = ldq_p(mem_buf);
} else if (n < 64) {
/* fprs */
- env->fpr[n-32] = ldfq_p(mem_buf);
+ *cpu_fpr_ptr(env, n - 32) = ldfq_p(mem_buf);
} else {
switch (n) {
case 64 + 32:
static inline void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
{
- if (n < 32) {
- vsr->VsrD(0) = env->fpr[n];
- vsr->VsrD(1) = env->vsr[n];
- } else {
- vsr->u64[0] = env->avr[n - 32].u64[0];
- vsr->u64[1] = env->avr[n - 32].u64[1];
- }
+ vsr->VsrD(0) = env->vsr[n].u64[0];
+ vsr->VsrD(1) = env->vsr[n].u64[1];
}
static inline void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
{
- if (n < 32) {
- env->fpr[n] = vsr->VsrD(0);
- env->vsr[n] = vsr->VsrD(1);
- } else {
- env->avr[n - 32].u64[0] = vsr->u64[0];
- env->avr[n - 32].u64[1] = vsr->u64[1];
- }
+ env->vsr[n].u64[0] = vsr->VsrD(0);
+ env->vsr[n].u64[1] = vsr->VsrD(1);
}
void helper_compute_fprf_float16(CPUPPCState *env, float16 arg);
for (i = 0; i < 32; i++) {
uint64_t vsr[2];
+ uint64_t *fpr = cpu_fpr_ptr(&cpu->env, i);
+ uint64_t *vsrl = cpu_vsrl_ptr(&cpu->env, i);
#ifdef HOST_WORDS_BIGENDIAN
- vsr[0] = float64_val(env->fpr[i]);
- vsr[1] = env->vsr[i];
+ vsr[0] = float64_val(*fpr);
+ vsr[1] = *vsrl;
#else
- vsr[0] = env->vsr[i];
- vsr[1] = float64_val(env->fpr[i]);
+ vsr[0] = *vsrl;
+ vsr[1] = float64_val(*fpr);
#endif
reg.addr = (uintptr_t) &vsr;
reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
for (i = 0; i < 32; i++) {
reg.id = KVM_REG_PPC_VR(i);
- reg.addr = (uintptr_t)&env->avr[i];
+ reg.addr = (uintptr_t)cpu_avr_ptr(env, i);
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
if (ret < 0) {
DPRINTF("Unable to set VR%d to KVM: %s\n", i, strerror(errno));
for (i = 0; i < 32; i++) {
uint64_t vsr[2];
+ uint64_t *fpr = cpu_fpr_ptr(&cpu->env, i);
+ uint64_t *vsrl = cpu_vsrl_ptr(&cpu->env, i);
reg.addr = (uintptr_t) &vsr;
reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
return ret;
} else {
#ifdef HOST_WORDS_BIGENDIAN
- env->fpr[i] = vsr[0];
+ *fpr = vsr[0];
if (vsx) {
- env->vsr[i] = vsr[1];
+ *vsrl = vsr[1];
}
#else
- env->fpr[i] = vsr[1];
+ *fpr = vsr[1];
if (vsx) {
- env->vsr[i] = vsr[0];
+ *vsrl = vsr[0];
}
#endif
}
for (i = 0; i < 32; i++) {
reg.id = KVM_REG_PPC_VR(i);
- reg.addr = (uintptr_t)&env->avr[i];
+ reg.addr = (uintptr_t)cpu_avr_ptr(env, i);
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
if (ret < 0) {
DPRINTF("Unable to get VR%d from KVM: %s\n",
uint64_t l;
} u;
u.l = qemu_get_be64(f);
- env->fpr[i] = u.d;
+ *cpu_fpr_ptr(env, i) = u.d;
}
qemu_get_be32s(f, &fpscr);
env->fpscr = fpscr;
};
#define VMSTATE_AVR_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_avr, ppc_avr_t)
+ VMSTATE_SUB_ARRAY(_f, _s, 32, _n, _v, vmstate_info_avr, ppc_avr_t)
#define VMSTATE_AVR_ARRAY(_f, _s, _n) \
VMSTATE_AVR_ARRAY_V(_f, _s, _n, 0)
+static int get_fpr(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field)
+{
+ ppc_vsr_t *v = pv;
+
+ v->u64[0] = qemu_get_be64(f);
+
+ return 0;
+}
+
+static int put_fpr(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field, QJSON *vmdesc)
+{
+ ppc_vsr_t *v = pv;
+
+ qemu_put_be64(f, v->u64[0]);
+ return 0;
+}
+
+static const VMStateInfo vmstate_info_fpr = {
+ .name = "fpr",
+ .get = get_fpr,
+ .put = put_fpr,
+};
+
+#define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_SUB_ARRAY(_f, _s, 0, _n, _v, vmstate_info_fpr, ppc_vsr_t)
+
+#define VMSTATE_FPR_ARRAY(_f, _s, _n) \
+ VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0)
+
+static int get_vsr(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field)
+{
+ ppc_vsr_t *v = pv;
+
+ v->u64[1] = qemu_get_be64(f);
+
+ return 0;
+}
+
+static int put_vsr(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field, QJSON *vmdesc)
+{
+ ppc_vsr_t *v = pv;
+
+ qemu_put_be64(f, v->u64[1]);
+ return 0;
+}
+
+static const VMStateInfo vmstate_info_vsr = {
+ .name = "vsr",
+ .get = get_vsr,
+ .put = put_vsr,
+};
+
+#define VMSTATE_VSR_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_SUB_ARRAY(_f, _s, 0, _n, _v, vmstate_info_vsr, ppc_vsr_t)
+
+#define VMSTATE_VSR_ARRAY(_f, _s, _n) \
+ VMSTATE_VSR_ARRAY_V(_f, _s, _n, 0)
+
static bool cpu_pre_2_8_migration(void *opaque, int version_id)
{
PowerPCCPU *cpu = opaque;
.minimum_version_id = 1,
.needed = fpu_needed,
.fields = (VMStateField[]) {
- VMSTATE_FLOAT64_ARRAY(env.fpr, PowerPCCPU, 32),
+ VMSTATE_FPR_ARRAY(env.vsr, PowerPCCPU, 32),
VMSTATE_UINTTL(env.fpscr, PowerPCCPU),
VMSTATE_END_OF_LIST()
},
.minimum_version_id = 1,
.needed = altivec_needed,
.fields = (VMStateField[]) {
- VMSTATE_AVR_ARRAY(env.avr, PowerPCCPU, 32),
+ VMSTATE_AVR_ARRAY(env.vsr, PowerPCCPU, 32),
VMSTATE_UINT32(env.vscr, PowerPCCPU),
VMSTATE_END_OF_LIST()
},
.minimum_version_id = 1,
.needed = vsx_needed,
.fields = (VMStateField[]) {
- VMSTATE_UINT64_ARRAY(env.vsr, PowerPCCPU, 32),
+ VMSTATE_VSR_ARRAY(env.vsr, PowerPCCPU, 32),
VMSTATE_END_OF_LIST()
},
};
/* Floating point registers */
if ((qemu_tolower(name[0]) == 'f') &&
- ppc_cpu_get_reg_num(name + 1, ARRAY_SIZE(env->fpr), ®num)) {
- *pval = env->fpr[regnum];
+ ppc_cpu_get_reg_num(name + 1, 32, ®num)) {
+ *pval = *cpu_fpr_ptr(env, regnum);
return 0;
}
static inline void get_fpr(TCGv_i64 dst, int regno)
{
- tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, fpr[regno]));
+ tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, vsr[regno].u64[0]));
}
static inline void set_fpr(int regno, TCGv_i64 src)
{
- tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, fpr[regno]));
+ tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[regno].u64[0]));
}
static inline void get_avr64(TCGv_i64 dst, int regno, bool high)
{
#ifdef HOST_WORDS_BIGENDIAN
tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState,
- avr[regno].u64[(high ? 0 : 1)]));
+ vsr[32 + regno].u64[(high ? 0 : 1)]));
#else
tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState,
- avr[regno].u64[(high ? 1 : 0)]));
+ vsr[32 + regno].u64[(high ? 1 : 0)]));
#endif
}
{
#ifdef HOST_WORDS_BIGENDIAN
tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState,
- avr[regno].u64[(high ? 0 : 1)]));
+ vsr[32 + regno].u64[(high ? 0 : 1)]));
#else
tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState,
- avr[regno].u64[(high ? 1 : 0)]));
+ vsr[32 + regno].u64[(high ? 1 : 0)]));
#endif
}
if ((i & (RFPL - 1)) == 0) {
cpu_fprintf(f, "FPR%02d", i);
}
- cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
+ cpu_fprintf(f, " %016" PRIx64, *cpu_fpr_ptr(env, i));
if ((i & (RFPL - 1)) == (RFPL - 1)) {
cpu_fprintf(f, "\n");
}
static inline TCGv_ptr gen_fprp_ptr(int reg)
{
TCGv_ptr r = tcg_temp_new_ptr();
- tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg]));
+ tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, vsr[reg].u64[0]));
return r;
}
static inline TCGv_ptr gen_avr_ptr(int reg)
{
TCGv_ptr r = tcg_temp_new_ptr();
- tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
+ tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, vsr[32 + reg].u64[0]));
return r;
}
+static inline long avr64_offset(int reg, bool high)
+{
+ return offsetof(CPUPPCState, vsr[32 + reg].u64[(high ? 0 : 1)]);
+}
+
#define GEN_VR_LDX(name, opc2, opc3) \
static void glue(gen_, name)(DisasContext *ctx) \
{ \
static inline void get_vsr(TCGv_i64 dst, int n)
{
- tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, vsr[n]));
+ tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, vsr[n].u64[1]));
}
static inline void set_vsr(int n, TCGv_i64 src)
{
- tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[n]));
+ tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[n].u64[1]));
}
static inline void get_cpu_vsrh(TCGv_i64 dst, int n)
static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
if (n < 32) {
- stfq_p(mem_buf, env->fpr[n]);
+ stfq_p(mem_buf, *cpu_fpr_ptr(env, n));
ppc_maybe_bswap_register(env, mem_buf, 8);
return 8;
}
{
if (n < 32) {
ppc_maybe_bswap_register(env, mem_buf, 8);
- env->fpr[n] = ldfq_p(mem_buf);
+ *cpu_fpr_ptr(env, n) = ldfq_p(mem_buf);
return 8;
}
if (n == 32) {
static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
if (n < 32) {
+ ppc_avr_t *avr = cpu_avr_ptr(env, n);
if (!avr_need_swap(env)) {
- stq_p(mem_buf, env->avr[n].u64[0]);
- stq_p(mem_buf+8, env->avr[n].u64[1]);
+ stq_p(mem_buf, avr->u64[0]);
+ stq_p(mem_buf + 8, avr->u64[1]);
} else {
- stq_p(mem_buf, env->avr[n].u64[1]);
- stq_p(mem_buf+8, env->avr[n].u64[0]);
+ stq_p(mem_buf, avr->u64[1]);
+ stq_p(mem_buf + 8, avr->u64[0]);
}
ppc_maybe_bswap_register(env, mem_buf, 8);
ppc_maybe_bswap_register(env, mem_buf + 8, 8);
static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
if (n < 32) {
+ ppc_avr_t *avr = cpu_avr_ptr(env, n);
ppc_maybe_bswap_register(env, mem_buf, 8);
ppc_maybe_bswap_register(env, mem_buf + 8, 8);
if (!avr_need_swap(env)) {
- env->avr[n].u64[0] = ldq_p(mem_buf);
- env->avr[n].u64[1] = ldq_p(mem_buf+8);
+ avr->u64[0] = ldq_p(mem_buf);
+ avr->u64[1] = ldq_p(mem_buf + 8);
} else {
- env->avr[n].u64[1] = ldq_p(mem_buf);
- env->avr[n].u64[0] = ldq_p(mem_buf+8);
+ avr->u64[1] = ldq_p(mem_buf);
+ avr->u64[0] = ldq_p(mem_buf + 8);
}
return 16;
}
static int gdb_get_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
if (n < 32) {
- stq_p(mem_buf, env->vsr[n]);
+ stq_p(mem_buf, *cpu_vsrl_ptr(env, n));
ppc_maybe_bswap_register(env, mem_buf, 8);
return 8;
}
{
if (n < 32) {
ppc_maybe_bswap_register(env, mem_buf, 8);
- env->vsr[n] = ldq_p(mem_buf);
+ *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
return 8;
}
return 0;