/*
 *  Helpers for loads and stores
 *
 *  Copyright (c) 2007 Jocelyn Mayer
 *
 * 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 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 "exec/helper-proto.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"

/* Softmmu support */
#ifndef CONFIG_USER_ONLY

uint64_t helper_ldl_phys(CPUAlphaState *env, uint64_t p)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    return (int32_t)ldl_phys(cs->as, p);
}

uint64_t helper_ldq_phys(CPUAlphaState *env, uint64_t p)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    return ldq_phys(cs->as, p);
}

uint64_t helper_ldl_l_phys(CPUAlphaState *env, uint64_t p)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    env->lock_addr = p;
    return env->lock_value = (int32_t)ldl_phys(cs->as, p);
}

uint64_t helper_ldq_l_phys(CPUAlphaState *env, uint64_t p)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    env->lock_addr = p;
    return env->lock_value = ldq_phys(cs->as, p);
}

void helper_stl_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    stl_phys(cs->as, p, v);
}

void helper_stq_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    stq_phys(cs->as, p, v);
}

uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    uint64_t ret = 0;

    if (p == env->lock_addr) {
        int32_t old = ldl_phys(cs->as, p);
        if (old == (int32_t)env->lock_value) {
            stl_phys(cs->as, p, v);
            ret = 1;
        }
    }
    env->lock_addr = -1;

    return ret;
}

uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    uint64_t ret = 0;

    if (p == env->lock_addr) {
        uint64_t old = ldq_phys(cs->as, p);
        if (old == env->lock_value) {
            stq_phys(cs->as, p, v);
            ret = 1;
        }
    }
    env->lock_addr = -1;

    return ret;
}

void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
                                   MMUAccessType access_type,
                                   int mmu_idx, uintptr_t retaddr,
                                   unsigned size)
{
    AlphaCPU *cpu = ALPHA_CPU(cs);
    CPUAlphaState *env = &cpu->env;
    uint64_t pc;
    uint32_t insn;

    (void)size;

    if (retaddr) {
        cpu_restore_state(cs, retaddr);
    }

    pc = env->pc;
    insn = cpu_ldl_code(env, pc);

    env->trap_arg0 = addr;
    env->trap_arg1 = insn >> 26;                /* opcode */
    env->trap_arg2 = (insn >> 21) & 31;         /* dest regno */
    cs->exception_index = EXCP_UNALIGN;
    env->error_code = 0;
    cpu_loop_exit(cs);
}

void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
                                 bool is_write, bool is_exec, int unused,
                                 unsigned size)
{
    AlphaCPU *cpu = ALPHA_CPU(cs);
    CPUAlphaState *env = &cpu->env;

    env->trap_arg0 = addr;
    env->trap_arg1 = is_write ? 1 : 0;
    cs->exception_index = EXCP_MCHK;
    env->error_code = 0;

    /* ??? We should cpu_restore_state to the faulting insn, but this hook
       does not have access to the retaddr value from the original helper.
       It's all moot until the QEMU PALcode grows an MCHK handler.  */

    cpu_loop_exit(cs);
}

/* try to fill the TLB and return an exception if error. If retaddr is
   NULL, it means that the function was called in C code (i.e. not
   from generated code or from helper.c) */
/* XXX: fix it to restore all registers */
void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
              int mmu_idx, uintptr_t retaddr)
{
    int ret;

    ret = alpha_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
    if (unlikely(ret != 0)) {
        if (retaddr) {
            cpu_restore_state(cs, retaddr);
        }
        /* Exception index and error code are already set */
        cpu_loop_exit(cs);
    }
}
#endif /* CONFIG_USER_ONLY */
