📄 op.c
字号:
/* * MIPS emulation micro-operations for qemu. * * Copyright (c) 2004-2005 Jocelyn Mayer * Copyright (c) 2006 Marius Groeger (FPU operations) * * 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 "config.h"#include "exec.h"#ifndef CALL_FROM_TB0#define CALL_FROM_TB0(func) func();#endif#ifndef CALL_FROM_TB1#define CALL_FROM_TB1(func, arg0) func(arg0);#endif#ifndef CALL_FROM_TB1_CONST16#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0);#endif#ifndef CALL_FROM_TB2#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1);#endif#ifndef CALL_FROM_TB2_CONST16#define CALL_FROM_TB2_CONST16(func, arg0, arg1) \CALL_FROM_TB2(func, arg0, arg1);#endif#ifndef CALL_FROM_TB3#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2);#endif#ifndef CALL_FROM_TB4#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \ func(arg0, arg1, arg2, arg3);#endif#define REG 1#include "op_template.c"#undef REG#define REG 2#include "op_template.c"#undef REG#define REG 3#include "op_template.c"#undef REG#define REG 4#include "op_template.c"#undef REG#define REG 5#include "op_template.c"#undef REG#define REG 6#include "op_template.c"#undef REG#define REG 7#include "op_template.c"#undef REG#define REG 8#include "op_template.c"#undef REG#define REG 9#include "op_template.c"#undef REG#define REG 10#include "op_template.c"#undef REG#define REG 11#include "op_template.c"#undef REG#define REG 12#include "op_template.c"#undef REG#define REG 13#include "op_template.c"#undef REG#define REG 14#include "op_template.c"#undef REG#define REG 15#include "op_template.c"#undef REG#define REG 16#include "op_template.c"#undef REG#define REG 17#include "op_template.c"#undef REG#define REG 18#include "op_template.c"#undef REG#define REG 19#include "op_template.c"#undef REG#define REG 20#include "op_template.c"#undef REG#define REG 21#include "op_template.c"#undef REG#define REG 22#include "op_template.c"#undef REG#define REG 23#include "op_template.c"#undef REG#define REG 24#include "op_template.c"#undef REG#define REG 25#include "op_template.c"#undef REG#define REG 26#include "op_template.c"#undef REG#define REG 27#include "op_template.c"#undef REG#define REG 28#include "op_template.c"#undef REG#define REG 29#include "op_template.c"#undef REG#define REG 30#include "op_template.c"#undef REG#define REG 31#include "op_template.c"#undef REG#define TN#include "op_template.c"#undef TN#ifdef MIPS_USES_FPU#define SFREG 0#define DFREG 0#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 1#include "fop_template.c"#undef SFREG#define SFREG 2#define DFREG 2#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 3#include "fop_template.c"#undef SFREG#define SFREG 4#define DFREG 4#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 5#include "fop_template.c"#undef SFREG#define SFREG 6#define DFREG 6#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 7#include "fop_template.c"#undef SFREG#define SFREG 8#define DFREG 8#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 9#include "fop_template.c"#undef SFREG#define SFREG 10#define DFREG 10#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 11#include "fop_template.c"#undef SFREG#define SFREG 12#define DFREG 12#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 13#include "fop_template.c"#undef SFREG#define SFREG 14#define DFREG 14#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 15#include "fop_template.c"#undef SFREG#define SFREG 16#define DFREG 16#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 17#include "fop_template.c"#undef SFREG#define SFREG 18#define DFREG 18#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 19#include "fop_template.c"#undef SFREG#define SFREG 20#define DFREG 20#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 21#include "fop_template.c"#undef SFREG#define SFREG 22#define DFREG 22#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 23#include "fop_template.c"#undef SFREG#define SFREG 24#define DFREG 24#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 25#include "fop_template.c"#undef SFREG#define SFREG 26#define DFREG 26#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 27#include "fop_template.c"#undef SFREG#define SFREG 28#define DFREG 28#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 29#include "fop_template.c"#undef SFREG#define SFREG 30#define DFREG 30#include "fop_template.c"#undef SFREG#undef DFREG#define SFREG 31#include "fop_template.c"#undef SFREG#define FTN#include "fop_template.c"#undef FTN#endifvoid op_dup_T0 (void){ T2 = T0; RETURN();}void op_load_HI (void){ T0 = env->HI; RETURN();}void op_store_HI (void){ env->HI = T0; RETURN();}void op_load_LO (void){ T0 = env->LO; RETURN();}void op_store_LO (void){ env->LO = T0; RETURN();}/* Load and store */#define MEMSUFFIX _raw#include "op_mem.c"#undef MEMSUFFIX#if !defined(CONFIG_USER_ONLY)#define MEMSUFFIX _user#include "op_mem.c"#undef MEMSUFFIX#define MEMSUFFIX _kernel#include "op_mem.c"#undef MEMSUFFIX#endif/* Arithmetic */void op_add (void){ T0 = (int32_t)((int32_t)T0 + (int32_t)T1); RETURN();}void op_addo (void){ target_ulong tmp; tmp = (int32_t)T0; T0 = (int32_t)T0 + (int32_t)T1; if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) { /* operands of same sign, result different sign */ CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); } T0 = (int32_t)T0; RETURN();}void op_sub (void){ T0 = (int32_t)((int32_t)T0 - (int32_t)T1); RETURN();}void op_subo (void){ target_ulong tmp; tmp = (int32_t)T0; T0 = (int32_t)T0 - (int32_t)T1; if (((tmp ^ T1) & (tmp ^ T0)) >> 31) { /* operands of different sign, first operand and result different sign */ CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); } T0 = (int32_t)T0; RETURN();}void op_mul (void){ T0 = (int32_t)((int32_t)T0 * (int32_t)T1); RETURN();}void op_div (void){ if (T1 != 0) { env->LO = (int32_t)((int32_t)T0 / (int32_t)T1); env->HI = (int32_t)((int32_t)T0 % (int32_t)T1); } RETURN();}void op_divu (void){ if (T1 != 0) { env->LO = (int32_t)((uint32_t)T0 / (uint32_t)T1); env->HI = (int32_t)((uint32_t)T0 % (uint32_t)T1); } RETURN();}#ifdef MIPS_HAS_MIPS64/* Arithmetic */void op_dadd (void){ T0 += T1; RETURN();}void op_daddo (void){ target_long tmp; tmp = T0; T0 += T1; if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) { /* operands of same sign, result different sign */ CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); } RETURN();}void op_dsub (void){ T0 -= T1; RETURN();}void op_dsubo (void){ target_long tmp; tmp = T0; T0 = (int64_t)T0 - (int64_t)T1; if (((tmp ^ T1) & (tmp ^ T0)) >> 63) { /* operands of different sign, first operand and result different sign */ CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); } RETURN();}void op_dmul (void){ T0 = (int64_t)T0 * (int64_t)T1; RETURN();}#if TARGET_LONG_BITS > HOST_LONG_BITS/* Those might call libgcc functions. */void op_ddiv (void){ do_ddiv(); RETURN();}void op_ddivu (void){ do_ddivu(); RETURN();}#elsevoid op_ddiv (void){ if (T1 != 0) { env->LO = (int64_t)T0 / (int64_t)T1; env->HI = (int64_t)T0 % (int64_t)T1; } RETURN();}void op_ddivu (void){ if (T1 != 0) { env->LO = T0 / T1; env->HI = T0 % T1; } RETURN();}#endif#endif /* MIPS_HAS_MIPS64 *//* Logical */void op_and (void){ T0 &= T1; RETURN();}void op_nor (void){ T0 = ~(T0 | T1); RETURN();}void op_or (void){ T0 |= T1; RETURN();}void op_xor (void){ T0 ^= T1; RETURN();}void op_sll (void){ T0 = (int32_t)((uint32_t)T0 << (uint32_t)T1); RETURN();}void op_sra (void){ T0 = (int32_t)((int32_t)T0 >> (uint32_t)T1); RETURN();}void op_srl (void){ T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1); RETURN();}void op_rotr (void){ target_ulong tmp; if (T1) { tmp = (int32_t)((uint32_t)T0 << (0x20 - (uint32_t)T1)); T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1) | tmp; } else T0 = T1; RETURN();}void op_sllv (void){ T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F)); RETURN();}void op_srav (void){ T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F)); RETURN();}void op_srlv (void){ T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F)); RETURN();}void op_rotrv (void){ target_ulong tmp; T0 &= 0x1F; if (T0) { tmp = (int32_t)((uint32_t)T1 << (0x20 - T0)); T0 = (int32_t)((uint32_t)T1 >> T0) | tmp; } else T0 = T1; RETURN();}void op_clo (void){ int n; if (T0 == ~((target_ulong)0)) { T0 = 32; } else { for (n = 0; n < 32; n++) { if (!(T0 & (1 << 31))) break; T0 = T0 << 1; } T0 = n; } RETURN();}void op_clz (void){ int n; if (T0 == 0) { T0 = 32; } else { for (n = 0; n < 32; n++) { if (T0 & (1 << 31)) break; T0 = T0 << 1; } T0 = n; } RETURN();}#ifdef MIPS_HAS_MIPS64#if TARGET_LONG_BITS > HOST_LONG_BITS/* Those might call libgcc functions. */void op_dsll (void){ CALL_FROM_TB0(do_dsll); RETURN();}void op_dsll32 (void){ CALL_FROM_TB0(do_dsll32); RETURN();}void op_dsra (void){ CALL_FROM_TB0(do_dsra); RETURN();}void op_dsra32 (void){ CALL_FROM_TB0(do_dsra32); RETURN();}void op_dsrl (void){ CALL_FROM_TB0(do_dsrl); RETURN();}void op_dsrl32 (void){ CALL_FROM_TB0(do_dsrl32); RETURN();}void op_drotr (void){ CALL_FROM_TB0(do_drotr); RETURN();}void op_drotr32 (void){ CALL_FROM_TB0(do_drotr32); RETURN();}void op_dsllv (void){ CALL_FROM_TB0(do_dsllv); RETURN();}void op_dsrav (void){ CALL_FROM_TB0(do_dsrav); RETURN();}void op_dsrlv (void){ CALL_FROM_TB0(do_dsrlv); RETURN();}void op_drotrv (void){ CALL_FROM_TB0(do_drotrv); RETURN();}#else /* TARGET_LONG_BITS > HOST_LONG_BITS */void op_dsll (void){ T0 = T0 << T1; RETURN();}void op_dsll32 (void){ T0 = T0 << (T1 + 32); RETURN();}void op_dsra (void){ T0 = (int64_t)T0 >> T1; RETURN();}void op_dsra32 (void){ T0 = (int64_t)T0 >> (T1 + 32); RETURN();}void op_dsrl (void){ T0 = T0 >> T1; RETURN();}void op_dsrl32 (void){ T0 = T0 >> (T1 + 32); RETURN();}void op_drotr (void){ target_ulong tmp; if (T1) { tmp = T0 << (0x40 - T1); T0 = (T0 >> T1) | tmp; } else T0 = T1; RETURN();}void op_drotr32 (void){ target_ulong tmp; if (T1) { tmp = T0 << (0x40 - (32 + T1)); T0 = (T0 >> (32 + T1)) | tmp; } else T0 = T1; RETURN();}void op_dsllv (void){ T0 = T1 << (T0 & 0x3F); RETURN();}void op_dsrav (void){ T0 = (int64_t)T1 >> (T0 & 0x3F); RETURN();}void op_dsrlv (void){ T0 = T1 >> (T0 & 0x3F); RETURN();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -