/*
 * SuperH 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"

/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
/* FIXME: We should use XML for this.  */

int superh_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
    CPUSH4State *env = cpu_env(cs);

    switch (n) {
    case 0 ... 7:
        if ((env->sr & (1u << SR_MD)) && (env->sr & (1u << SR_RB))) {
            return gdb_get_regl(mem_buf, env->gregs[n + 16]);
        } else {
            return gdb_get_regl(mem_buf, env->gregs[n]);
        }
    case 8 ... 15:
        return gdb_get_regl(mem_buf, env->gregs[n]);
    case 16:
        return gdb_get_regl(mem_buf, env->pc);
    case 17:
        return gdb_get_regl(mem_buf, env->pr);
    case 18:
        return gdb_get_regl(mem_buf, env->gbr);
    case 19:
        return gdb_get_regl(mem_buf, env->vbr);
    case 20:
        return gdb_get_regl(mem_buf, env->mach);
    case 21:
        return gdb_get_regl(mem_buf, env->macl);
    case 22:
        return gdb_get_regl(mem_buf, cpu_read_sr(env));
    case 23:
        return gdb_get_regl(mem_buf, env->fpul);
    case 24:
        return gdb_get_regl(mem_buf, env->fpscr);
    case 25 ... 40:
        if (env->fpscr & FPSCR_FR) {
            return gdb_get_reg32(mem_buf, env->fregs[n - 9]);
        }
        return gdb_get_reg32(mem_buf, env->fregs[n - 25]);
    case 41:
        return gdb_get_regl(mem_buf, env->ssr);
    case 42:
        return gdb_get_regl(mem_buf, env->spc);
    case 43 ... 50:
        return gdb_get_regl(mem_buf, env->gregs[n - 43]);
    case 51 ... 58:
        return gdb_get_regl(mem_buf, env->gregs[n - (51 - 16)]);
    }

    return 0;
}

int superh_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    CPUSH4State *env = cpu_env(cs);

    switch (n) {
    case 0 ... 7:
        if ((env->sr & (1u << SR_MD)) && (env->sr & (1u << SR_RB))) {
            env->gregs[n + 16] = ldl_p(mem_buf);
        } else {
            env->gregs[n] = ldl_p(mem_buf);
        }
        break;
    case 8 ... 15:
        env->gregs[n] = ldl_p(mem_buf);
        break;
    case 16:
        env->pc = ldl_p(mem_buf);
        break;
    case 17:
        env->pr = ldl_p(mem_buf);
        break;
    case 18:
        env->gbr = ldl_p(mem_buf);
        break;
    case 19:
        env->vbr = ldl_p(mem_buf);
        break;
    case 20:
        env->mach = ldl_p(mem_buf);
        break;
    case 21:
        env->macl = ldl_p(mem_buf);
        break;
    case 22:
        cpu_write_sr(env, ldl_p(mem_buf));
        break;
    case 23:
        env->fpul = ldl_p(mem_buf);
        break;
    case 24:
        env->fpscr = ldl_p(mem_buf);
        break;
    case 25 ... 40:
        if (env->fpscr & FPSCR_FR) {
            env->fregs[n - 9] = ldl_p(mem_buf);
        } else {
            env->fregs[n - 25] = ldl_p(mem_buf);
        }
        break;
    case 41:
        env->ssr = ldl_p(mem_buf);
        break;
    case 42:
        env->spc = ldl_p(mem_buf);
        break;
    case 43 ... 50:
        env->gregs[n - 43] = ldl_p(mem_buf);
        break;
    case 51 ... 58:
        env->gregs[n - (51 - 16)] = ldl_p(mem_buf);
        break;
    default:
        return 0;
    }

    return 4;
}
