/*
 * LOONGARCH gdb server stub
 *
 * Copyright (c) 2021 Loongson Technology Corporation Limited
 *
 * SPDX-License-Identifier: LGPL-2.1+
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "internals.h"
#include "exec/gdbstub.h"
#include "gdbstub/helpers.h"
#include "vec.h"

uint64_t read_fcc(CPULoongArchState *env)
{
    uint64_t ret = 0;

    for (int i = 0; i < 8; ++i) {
        ret |= (uint64_t)env->cf[i] << (i * 8);
    }

    return ret;
}

void write_fcc(CPULoongArchState *env, uint64_t val)
{
    for (int i = 0; i < 8; ++i) {
        env->cf[i] = (val >> (i * 8)) & 1;
    }
}

int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
    CPULoongArchState *env = cpu_env(cs);
    uint64_t val;

    if (0 <= n && n < 32) {
        val = env->gpr[n];
    } else if (n == 32) {
        /* orig_a0 */
        val = 0;
    } else if (n == 33) {
        val = env->pc;
    } else if (n == 34) {
        val = env->CSR_BADV;
    }

    if (0 <= n && n <= 34) {
        if (is_la64(env)) {
            return gdb_get_reg64(mem_buf, val);
        } else {
            return gdb_get_reg32(mem_buf, val);
        }
    }
    return 0;
}

int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    CPULoongArchState *env = cpu_env(cs);
    target_ulong tmp;
    int read_length;
    int length = 0;

    if (is_la64(env)) {
        tmp = ldq_p(mem_buf);
        read_length = 8;
    } else {
        tmp = ldl_p(mem_buf);
        read_length = 4;
    }

    if (0 <= n && n < 32) {
        env->gpr[n] = tmp;
        length = read_length;
    } else if (n == 33) {
        set_pc(env, tmp);
        length = read_length;
    }
    return length;
}

static int loongarch_gdb_get_fpu(CPUState *cs, GByteArray *mem_buf, int n)
{
    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
    CPULoongArchState *env = &cpu->env;

    if (0 <= n && n < 32) {
        return gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(0));
    } else if (32 <= n && n < 40) {
        return gdb_get_reg8(mem_buf, env->cf[n - 32]);
    } else if (n == 40) {
        return gdb_get_reg32(mem_buf, env->fcsr0);
    }
    return 0;
}

static int loongarch_gdb_set_fpu(CPUState *cs, uint8_t *mem_buf, int n)
{
    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
    CPULoongArchState *env = &cpu->env;
    int length = 0;

    if (0 <= n && n < 32) {
        env->fpr[n].vreg.D(0) = ldq_p(mem_buf);
        length = 8;
    } else if (32 <= n && n < 40) {
        env->cf[n - 32] = ldub_p(mem_buf);
        length = 1;
    } else if (n == 40) {
        env->fcsr0 = ldl_p(mem_buf);
        length = 4;
    }
    return length;
}

void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs)
{
    gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu,
                             gdb_find_static_feature("loongarch-fpu.xml"), 0);
}
