/*
 * SPARC gdb server stub
 *
 * Copyright (c) 2003-2005 Fabrice Bellard
 * Copyright (c) 2013 SUSE LINUX Products GmbH
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
#include "qemu/osdep.h"
#include "cpu.h"
#include "gdbstub/helpers.h"

#ifdef TARGET_ABI32
#define gdb_get_rega(buf, val) gdb_get_reg32(buf, val)
#else
#define gdb_get_rega(buf, val) gdb_get_regl(buf, val)
#endif

int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
    CPUSPARCState *env = cpu_env(cs);

    if (n < 8) {
        /* g0..g7 */
        return gdb_get_rega(mem_buf, env->gregs[n]);
    }
    if (n < 32) {
        /* register window */
        return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
    }
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
    if (n < 64) {
        /* fprs */
        if (n & 1) {
            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
        } else {
            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
        }
    }
    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
    switch (n) {
    case 64:
        return gdb_get_rega(mem_buf, env->y);
    case 65:
        return gdb_get_rega(mem_buf, cpu_get_psr(env));
    case 66:
        return gdb_get_rega(mem_buf, env->wim);
    case 67:
        return gdb_get_rega(mem_buf, env->tbr);
    case 68:
        return gdb_get_rega(mem_buf, env->pc);
    case 69:
        return gdb_get_rega(mem_buf, env->npc);
    case 70:
        return gdb_get_rega(mem_buf, cpu_get_fsr(env));
    case 71:
        return gdb_get_rega(mem_buf, 0); /* csr */
    default:
        return gdb_get_rega(mem_buf, 0);
    }
#else
    if (n < 64) {
        /* f0-f31 */
        if (n & 1) {
            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
        } else {
            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
        }
    }
    if (n < 80) {
        /* f32-f62 (double width, even numbers only) */
        return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
    }
    switch (n) {
    case 80:
        return gdb_get_regl(mem_buf, env->pc);
    case 81:
        return gdb_get_regl(mem_buf, env->npc);
    case 82:
        return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
                                     ((env->asi & 0xff) << 24) |
                                     ((env->pstate & 0xfff) << 8) |
                                     cpu_get_cwp64(env));
    case 83:
        return gdb_get_regl(mem_buf, cpu_get_fsr(env));
    case 84:
        return gdb_get_regl(mem_buf, env->fprs);
    case 85:
        return gdb_get_regl(mem_buf, env->y);
    }
#endif
    return 0;
}

int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    SPARCCPU *cpu = SPARC_CPU(cs);
    CPUSPARCState *env = &cpu->env;
#if defined(TARGET_ABI32)
    abi_ulong tmp;

    tmp = ldl_p(mem_buf);
#else
    target_ulong tmp;

    tmp = ldtul_p(mem_buf);
#endif

    if (n < 8) {
        /* g0..g7 */
        env->gregs[n] = tmp;
    } else if (n < 32) {
        /* register window */
        env->regwptr[n - 8] = tmp;
    }
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
    else if (n < 64) {
        /* fprs */
        /* f0-f31 */
        if (n & 1) {
            env->fpr[(n - 32) / 2].l.lower = tmp;
        } else {
            env->fpr[(n - 32) / 2].l.upper = tmp;
        }
    } else {
        /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
        switch (n) {
        case 64:
            env->y = tmp;
            break;
        case 65:
            cpu_put_psr(env, tmp);
            break;
        case 66:
            env->wim = tmp;
            break;
        case 67:
            env->tbr = tmp;
            break;
        case 68:
            env->pc = tmp;
            break;
        case 69:
            env->npc = tmp;
            break;
        case 70:
            cpu_put_fsr(env, tmp);
            break;
        default:
            return 0;
        }
    }
    return 4;
#else
    else if (n < 64) {
        /* f0-f31 */
        tmp = ldl_p(mem_buf);
        if (n & 1) {
            env->fpr[(n - 32) / 2].l.lower = tmp;
        } else {
            env->fpr[(n - 32) / 2].l.upper = tmp;
        }
        return 4;
    } else if (n < 80) {
        /* f32-f62 (double width, even numbers only) */
        env->fpr[(n - 32) / 2].ll = tmp;
    } else {
        switch (n) {
        case 80:
            env->pc = tmp;
            break;
        case 81:
            env->npc = tmp;
            break;
        case 82:
            cpu_put_ccr(env, tmp >> 32);
            env->asi = (tmp >> 24) & 0xff;
            env->pstate = (tmp >> 8) & 0xfff;
            cpu_put_cwp64(env, tmp & 0xff);
            break;
        case 83:
            cpu_put_fsr(env, tmp);
            break;
        case 84:
            env->fprs = tmp;
            break;
        case 85:
            env->y = tmp;
            break;
        default:
            return 0;
        }
    }
    return 8;
#endif
}
