Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
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;
    }
}
Пример #4
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, &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, &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, &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, &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, &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, &reg);
            if (ret < 0) {
                dprintf("Unable to set VR%d to KVM: %s\n", i, strerror(errno));
                return ret;
            }
        }
    }

    return 0;
}
Пример #5
0
static void put_float64(QEMUFile *f, void *pv, size_t size)
{
    uint64_t *v = pv;

    qemu_put_be64(f, float64_val(*v));
}