/*
 *  SH4 emulation
 *
 *  Copyright (c) 2005 Samuel Tardieu
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <assert.h>
#include "exec.h"

void do_raise_exception(void)
{
    cpu_loop_exit();
}

#ifndef CONFIG_USER_ONLY

#define MMUSUFFIX _mmu
#define GETPC() (__builtin_return_address(0))

#define SHIFT 0
#include "softmmu_template.h"

#define SHIFT 1
#include "softmmu_template.h"

#define SHIFT 2
#include "softmmu_template.h"

#define SHIFT 3
#include "softmmu_template.h"

void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
{
    TranslationBlock *tb;
    CPUState *saved_env;
    unsigned long pc;
    int ret;

    /* XXX: hack to restore env in all cases, even if not called from
       generated code */
    saved_env = env;
    env = cpu_single_env;
    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, is_user, 1);
    if (ret) {
	if (retaddr) {
	    /* now we have a real cpu fault */
	    pc = (unsigned long) retaddr;
	    tb = tb_find_pc(pc);
	    if (tb) {
		/* the PC is inside the translated code. It means that we have
		   a virtual CPU fault */
		cpu_restore_state(tb, env, pc, NULL);
	    }
	}
	do_raise_exception();
    }
    env = saved_env;
}

#endif

void helper_addc_T0_T1(void)
{
    uint32_t tmp0, tmp1;

    tmp1 = T0 + T1;
    tmp0 = T1;
    T1 = tmp1 + (env->sr & 1);
    if (tmp0 > tmp1)
	env->sr |= SR_T;
    else
	env->sr &= ~SR_T;
    if (tmp1 > T1)
	env->sr |= SR_T;
}

void helper_addv_T0_T1(void)
{
    uint32_t dest, src, ans;

    if ((int32_t) T1 >= 0)
	dest = 0;
    else
	dest = 1;
    if ((int32_t) T0 >= 0)
	src = 0;
    else
	src = 1;
    src += dest;
    T1 += T0;
    if ((int32_t) T1 >= 0)
	ans = 0;
    else
	ans = 1;
    ans += dest;
    if (src == 0 || src == 2) {
	if (ans == 1)
	    env->sr |= SR_T;
	else
	    env->sr &= ~SR_T;
    } else
	env->sr &= ~SR_T;
}

#define T (env->sr & SR_T)
#define Q (env->sr & SR_Q ? 1 : 0)
#define M (env->sr & SR_M ? 1 : 0)
#define SETT env->sr |= SR_T
#define CLRT env->sr &= ~SR_T
#define SETQ env->sr |= SR_Q
#define CLRQ env->sr &= ~SR_Q
#define SETM env->sr |= SR_M
#define CLRM env->sr &= ~SR_M

void helper_div1_T0_T1(void)
{
    uint32_t tmp0, tmp2;
    uint8_t old_q, tmp1 = 0xff;

    //printf("div1 T0=0x%08x T1=0x%08x M=%d Q=%d T=%d\n", T0, T1, M, Q, T);
    old_q = Q;
    if ((0x80000000 & T1) != 0)
	SETQ;
    else
	CLRQ;
    tmp2 = T0;
    T1 <<= 1;
    T1 |= T;
    switch (old_q) {
    case 0:
	switch (M) {
	case 0:
	    tmp0 = T1;
	    T1 -= tmp2;
	    tmp1 = T1 > tmp0;
	    switch (Q) {
	    case 0:
		if (tmp1)
		    SETQ;
		else
		    CLRQ;
		break;
	    case 1:
		if (tmp1 == 0)
		    SETQ;
		else
		    CLRQ;
		break;
	    }
	    break;
	case 1:
	    tmp0 = T1;
	    T1 += tmp2;
	    tmp1 = T1 < tmp0;
	    switch (Q) {
	    case 0:
		if (tmp1 == 0)
		    SETQ;
		else
		    CLRQ;
		break;
	    case 1:
		if (tmp1)
		    SETQ;
		else
		    CLRQ;
		break;
	    }
	    break;
	}
	break;
    case 1:
	switch (M) {
	case 0:
	    tmp0 = T1;
	    T1 += tmp2;
	    tmp1 = T1 < tmp0;
	    switch (Q) {
	    case 0:
		if (tmp1)
		    SETQ;
		else
		    CLRQ;
		break;
	    case 1:
		if (tmp1 == 0)
		    SETQ;
		else
		    CLRQ;
		break;
	    }
	    break;
	case 1:
	    tmp0 = T1;
	    T1 -= tmp2;
	    tmp1 = T1 > tmp0;
	    switch (Q) {
	    case 0:
		if (tmp1 == 0)
		    SETQ;
		else
		    CLRQ;
		break;
	    case 1:
		if (tmp1)
		    SETQ;
		else
		    CLRQ;
		break;
	    }
	    break;
	}
	break;
    }
    if (Q == M)
	SETT;
    else
	CLRT;
    //printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T);
}

void helper_dmulsl_T0_T1()
{
    int64_t res;

    res = (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
    env->mach = (res >> 32) & 0xffffffff;
    env->macl = res & 0xffffffff;
}

void helper_dmulul_T0_T1()
{
    uint64_t res;

    res = (uint64_t) (uint32_t) T0 *(uint64_t) (uint32_t) T1;
    env->mach = (res >> 32) & 0xffffffff;
    env->macl = res & 0xffffffff;
}

void helper_macl_T0_T1()
{
    int64_t res;

    res = ((uint64_t) env->mach << 32) | env->macl;
    res += (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
    env->mach = (res >> 32) & 0xffffffff;
    env->macl = res & 0xffffffff;
    if (env->sr & SR_S) {
	if (res < 0)
	    env->mach |= 0xffff0000;
	else
	    env->mach &= 0x00007fff;
    }
}

void helper_macw_T0_T1()
{
    int64_t res;

    res = ((uint64_t) env->mach << 32) | env->macl;
    res += (int64_t) (int16_t) T0 *(int64_t) (int16_t) T1;
    env->mach = (res >> 32) & 0xffffffff;
    env->macl = res & 0xffffffff;
    if (env->sr & SR_S) {
	if (res < -0x80000000) {
	    env->mach = 1;
	    env->macl = 0x80000000;
	} else if (res > 0x000000007fffffff) {
	    env->mach = 1;
	    env->macl = 0x7fffffff;
	}
    }
}

void helper_negc_T0()
{
    uint32_t temp;

    temp = -T0;
    T0 = temp - (env->sr & SR_T);
    if (0 < temp)
	env->sr |= SR_T;
    else
	env->sr &= ~SR_T;
    if (temp < T0)
	env->sr |= SR_T;
}

void helper_subc_T0_T1()
{
    uint32_t tmp0, tmp1;

    tmp1 = T1 - T0;
    tmp0 = T1;
    T1 = tmp1 - (env->sr & SR_T);
    if (tmp0 < tmp1)
	env->sr |= SR_T;
    else
	env->sr &= ~SR_T;
    if (tmp1 < T1)
	env->sr |= SR_T;
}

void helper_subv_T0_T1()
{
    int32_t dest, src, ans;

    if ((int32_t) T1 >= 0)
	dest = 0;
    else
	dest = 1;
    if ((int32_t) T0 >= 0)
	src = 0;
    else
	src = 1;
    src += dest;
    T1 -= T0;
    if ((int32_t) T1 >= 0)
	ans = 0;
    else
	ans = 1;
    ans += dest;
    if (src == 1) {
	if (ans == 1)
	    env->sr |= SR_T;
	else
	    env->sr &= ~SR_T;
    } else
	env->sr &= ~SR_T;
}

void helper_rotcl(uint32_t * addr)
{
    uint32_t new;

    new = (*addr << 1) | (env->sr & SR_T);
    if (*addr & 0x80000000)
	env->sr |= SR_T;
    else
	env->sr &= ~SR_T;
    *addr = new;
}

void helper_rotcr(uint32_t * addr)
{
    uint32_t new;

    new = (*addr >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0);
    if (*addr & 1)
	env->sr |= SR_T;
    else
	env->sr &= ~SR_T;
    *addr = new;
}
