float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp) { float_status *fpst = fpstp; a = float64_squash_input_denormal(a, fpst); b = float64_squash_input_denormal(b, fpst); if ((float64_is_zero(a) && float64_is_infinity(b)) || (float64_is_infinity(a) && float64_is_zero(b))) { /* 2.0 with the sign bit set to sign(A) XOR sign(B) */ return make_float64((1ULL << 62) | ((float64_val(a) ^ float64_val(b)) & (1ULL << 63))); } return float64_mul(a, b, fpst); }
static int put_float64(QEMUFile *f, void *pv, size_t size, VMStateField *field, QJSON *vmdesc) { uint64_t *v = pv; qemu_put_be64(f, float64_val(*v)); return 0; }
int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { XtensaCPU *cpu = XTENSA_CPU(cs); CPUXtensaState *env = &cpu->env; const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; unsigned i; if (n < 0 || n >= env->config->gdb_regmap.num_regs) { return 0; } switch (reg->type) { case 9: /*pc*/ return gdb_get_reg32(mem_buf, env->pc); case 1: /*ar*/ xtensa_sync_phys_from_window(env); return gdb_get_reg32(mem_buf, env->phys_regs[(reg->targno & 0xff) % env->config->nareg]); case 2: /*SR*/ return gdb_get_reg32(mem_buf, env->sregs[reg->targno & 0xff]); case 3: /*UR*/ return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]); case 4: /*f*/ i = reg->targno & 0x0f; switch (reg->size) { case 4: return gdb_get_reg32(mem_buf, float32_val(env->fregs[i].f32[FP_F32_LOW])); case 8: return gdb_get_reg64(mem_buf, float64_val(env->fregs[i].f64)); default: return 0; } case 8: /*a*/ return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]); default: qemu_log_mask(LOG_UNIMP, "%s from reg %d of unsupported type %d\n", __func__, n, reg->type); return 0; } }
static void kvm_get_one_spr(CPUState *cs, uint64_t id, int spr) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; union { uint32_t u32; uint64_t u64; } val; struct kvm_one_reg reg = { .id = id, .addr = (uintptr_t) &val, }; int ret; ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); if (ret != 0) { fprintf(stderr, "Warning: Unable to retrieve SPR %d from KVM: %s\n", spr, strerror(errno)); } else { switch (id & KVM_REG_SIZE_MASK) { case KVM_REG_SIZE_U32: env->spr[spr] = val.u32; break; case KVM_REG_SIZE_U64: env->spr[spr] = val.u64; break; default: /* Don't handle this size yet */ abort(); } } } static void kvm_put_one_spr(CPUState *cs, uint64_t id, int spr) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; union { uint32_t u32; uint64_t u64; } val; struct kvm_one_reg reg = { .id = id, .addr = (uintptr_t) &val, }; int ret; switch (id & KVM_REG_SIZE_MASK) { case KVM_REG_SIZE_U32: val.u32 = env->spr[spr]; break; case KVM_REG_SIZE_U64: val.u64 = env->spr[spr]; break; default: /* Don't handle this size yet */ abort(); } ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); if (ret != 0) { fprintf(stderr, "Warning: Unable to set SPR %d to KVM: %s\n", spr, strerror(errno)); } } static int kvm_put_fp(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; struct kvm_one_reg reg; int i; int ret; if (env->insns_flags & PPC_FLOAT) { uint64_t fpscr = env->fpscr; bool vsx = !!(env->insns_flags2 & PPC2_VSX); reg.id = KVM_REG_PPC_FPSCR; reg.addr = (uintptr_t)&fpscr; ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); if (ret < 0) { dprintf("Unable to set FPSCR to KVM: %s\n", strerror(errno)); return ret; } for (i = 0; i < 32; i++) { uint64_t vsr[2]; vsr[0] = float64_val(env->fpr[i]); vsr[1] = env->vsr[i]; reg.addr = (uintptr_t) &vsr; reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i); ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); if (ret < 0) { dprintf("Unable to set %s%d to KVM: %s\n", vsx ? "VSR" : "FPR", i, strerror(errno)); return ret; } } } if (env->insns_flags & PPC_ALTIVEC) { reg.id = KVM_REG_PPC_VSCR; reg.addr = (uintptr_t)&env->vscr; ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); if (ret < 0) { dprintf("Unable to set VSCR to KVM: %s\n", strerror(errno)); return ret; } for (i = 0; i < 32; i++) { reg.id = KVM_REG_PPC_VR(i); reg.addr = (uintptr_t)&env->avr[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)); return ret; } } } return 0; }
static void put_float64(QEMUFile *f, void *pv, size_t size) { uint64_t *v = pv; qemu_put_be64(f, float64_val(*v)); }