/*
 *  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 cpu_loop_exit(void)
{
    longjmp(env->jmp_env, 1);
}

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;
}
