?? op_helper.c
字號:
/* * MIPS emulation helpers for qemu. * * Copyright (c) 2004-2005 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdlib.h>#include "exec.h"#include "host-utils.h"#ifdef __s390__# define GETPC() ((void*)((unsigned long)__builtin_return_address(0) & 0x7fffffffUL))#else# define GETPC() (__builtin_return_address(0))#endif/*****************************************************************************//* Exceptions processing helpers */void do_raise_exception_err (uint32_t exception, int error_code){#if 1 if (logfile && exception < 0x100) fprintf(logfile, "%s: %d %d\n", __func__, exception, error_code);#endif env->exception_index = exception; env->error_code = error_code; T0 = 0; cpu_loop_exit();}void do_raise_exception (uint32_t exception){ do_raise_exception_err(exception, 0);}void do_restore_state (void *pc_ptr){ TranslationBlock *tb; unsigned long pc = (unsigned long) pc_ptr; tb = tb_find_pc (pc); cpu_restore_state (tb, env, pc, NULL);}void do_raise_exception_direct_err (uint32_t exception, int error_code){ do_restore_state (GETPC ()); do_raise_exception_err (exception, error_code);}void do_raise_exception_direct (uint32_t exception){ do_raise_exception_direct_err (exception, 0);}#if defined(TARGET_MIPS64)#if TARGET_LONG_BITS > HOST_LONG_BITS/* Those might call libgcc functions. */void do_dsll (void){ T0 = T0 << T1;}void do_dsll32 (void){ T0 = T0 << (T1 + 32);}void do_dsra (void){ T0 = (int64_t)T0 >> T1;}void do_dsra32 (void){ T0 = (int64_t)T0 >> (T1 + 32);}void do_dsrl (void){ T0 = T0 >> T1;}void do_dsrl32 (void){ T0 = T0 >> (T1 + 32);}void do_drotr (void){ target_ulong tmp; if (T1) { tmp = T0 << (0x40 - T1); T0 = (T0 >> T1) | tmp; }}void do_drotr32 (void){ target_ulong tmp; tmp = T0 << (0x40 - (32 + T1)); T0 = (T0 >> (32 + T1)) | tmp;}void do_dsllv (void){ T0 = T1 << (T0 & 0x3F);}void do_dsrav (void){ T0 = (int64_t)T1 >> (T0 & 0x3F);}void do_dsrlv (void){ T0 = T1 >> (T0 & 0x3F);}void do_drotrv (void){ target_ulong tmp; T0 &= 0x3F; if (T0) { tmp = T1 << (0x40 - T0); T0 = (T1 >> T0) | tmp; } else T0 = T1;}void do_dclo (void){ T0 = clo64(T0);}void do_dclz (void){ T0 = clz64(T0);}#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */#endif /* TARGET_MIPS64 *//* 64 bits arithmetic for 32 bits hosts */#if TARGET_LONG_BITS > HOST_LONG_BITSstatic always_inline uint64_t get_HILO (void){ return (env->HI[0][env->current_tc] << 32) | (uint32_t)env->LO[0][env->current_tc];}static always_inline void set_HILO (uint64_t HILO){ env->LO[0][env->current_tc] = (int32_t)HILO; env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);}static always_inline void set_HIT0_LO (uint64_t HILO){ env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF); T0 = env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);}static always_inline void set_HI_LOT0 (uint64_t HILO){ T0 = env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF); env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);}void do_mult (void){ set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);}void do_multu (void){ set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);}void do_madd (void){ int64_t tmp; tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); set_HILO((int64_t)get_HILO() + tmp);}void do_maddu (void){ uint64_t tmp; tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); set_HILO(get_HILO() + tmp);}void do_msub (void){ int64_t tmp; tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); set_HILO((int64_t)get_HILO() - tmp);}void do_msubu (void){ uint64_t tmp; tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); set_HILO(get_HILO() - tmp);}/* Multiplication variants of the vr54xx. */void do_muls (void){ set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));}void do_mulsu (void){ set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));}void do_macc (void){ set_HI_LOT0(((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));}void do_macchi (void){ set_HIT0_LO(((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));}void do_maccu (void){ set_HI_LOT0(((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));}void do_macchiu (void){ set_HIT0_LO(((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));}void do_msac (void){ set_HI_LOT0(((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));}void do_msachi (void){ set_HIT0_LO(((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));}void do_msacu (void){ set_HI_LOT0(((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));}void do_msachiu (void){ set_HIT0_LO(((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));}void do_mulhi (void){ set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);}void do_mulhiu (void){ set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);}void do_mulshi (void){ set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));}void do_mulshiu (void){ set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));}#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */#if HOST_LONG_BITS < 64void do_div (void){ /* 64bit datatypes because we may see overflow/underflow. */ if (T1 != 0) { env->LO[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1); env->HI[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1); }}#endif#if defined(TARGET_MIPS64)void do_ddiv (void){ if (T1 != 0) { int64_t arg0 = (int64_t)T0; int64_t arg1 = (int64_t)T1; if (arg0 == ((int64_t)-1 << 63) && arg1 == (int64_t)-1) { env->LO[0][env->current_tc] = arg0; env->HI[0][env->current_tc] = 0; } else { lldiv_t res = lldiv(arg0, arg1); env->LO[0][env->current_tc] = res.quot; env->HI[0][env->current_tc] = res.rem; } }}#if TARGET_LONG_BITS > HOST_LONG_BITSvoid do_ddivu (void){ if (T1 != 0) { env->LO[0][env->current_tc] = T0 / T1; env->HI[0][env->current_tc] = T0 % T1; }}#endif#endif /* TARGET_MIPS64 */#if defined(CONFIG_USER_ONLY)void do_mfc0_random (void){ cpu_abort(env, "mfc0 random\n");}void do_mfc0_count (void){ cpu_abort(env, "mfc0 count\n");}void cpu_mips_store_count(CPUState *env, uint32_t value){ cpu_abort(env, "mtc0 count\n");}void cpu_mips_store_compare(CPUState *env, uint32_t value){
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -