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

📄 op_helper.c

📁 QEMU 0.91 source code, supports ARM processor including S3C24xx series
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *  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 + -