⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 op_helper.c

📁 qemu虚拟机代码
💻 C
字号:
/* *  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;}#endifvoid 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_Mvoid 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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -