Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/pure_interp.c
2 views
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1* Mupen64plus - pure_interp.c *2* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *3* Copyright (C) 2002 Hacktarux *4* *5* This program is free software; you can redistribute it and/or modify *6* it under the terms of the GNU General Public License as published by *7* the Free Software Foundation; either version 2 of the License, or *8* (at your option) any later version. *9* *10* This program is distributed in the hope that it will be useful, *11* but WITHOUT ANY WARRANTY; without even the implied warranty of *12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *13* GNU General Public License for more details. *14* *15* You should have received a copy of the GNU General Public License *16* along with this program; if not, write to the *17* Free Software Foundation, Inc., *18* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *19* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2021#include <stdlib.h>22#include <math.h>2324#include "api/m64p_types.h"25#include "api/callbacks.h"26#include "api/debugger.h"27#include "memory/memory.h"28#include "main/rom.h"29#include "osal/preproc.h"3031#include "r4300.h"32#include "ops.h"33#include "exception.h"34#include "macros.h"35#include "interupt.h"3637#ifdef DBG38#include "debugger/dbg_types.h"39#include "debugger/debugger.h"40#endif4142static precomp_instr interp_PC;43unsigned int op;4445static void prefetch(void);4647#define PCADDR interp_PC.addr48#define ADD_TO_PC(x) interp_PC.addr += x*4;49#define DECLARE_INSTRUCTION(name) static void name(void)50#define DECLARE_JUMP(name, destination, condition, link, likely, cop1) \51static void name(void) \52{ \53const int take_jump = (condition); \54const unsigned int jump_target = (destination); \55long long int *link_register = (link); \56if (cop1 && check_cop1_unusable()) return; \57if (!likely || take_jump) \58{ \59interp_PC.addr += 4; \60delay_slot=1; \61prefetch(); \62PC->ops(); \63update_count(); \64delay_slot=0; \65if (take_jump && !skip_jump) \66{ \67if (link_register != ®[0]) \68{ \69*link_register=interp_PC.addr; \70sign_extended(*link_register); \71} \72interp_PC.addr = jump_target; \73} \74} \75else \76{ \77interp_PC.addr += 8; \78update_count(); \79} \80last_addr = interp_PC.addr; \81if (next_interupt <= Count) gen_interupt(); \82} \83static void name##_IDLE(void) \84{ \85const int take_jump = (condition); \86int skip; \87if (cop1 && check_cop1_unusable()) return; \88if (take_jump) \89{ \90update_count(); \91skip = next_interupt - Count; \92if (skip > 3) Count += (skip & 0xFFFFFFFC); \93else name(); \94} \95else name(); \96}97#define CHECK_MEMORY()9899#include "interpreter.def"100101// two functions are defined from the macros above but never used102// these prototype declarations will prevent a warning103#if defined(__GNUC__)104void JR_IDLE(void) __attribute__((used));105void JALR_IDLE(void) __attribute__((used));106#endif107108static cpu_instruction_table pure_interpreter_table = {109LB,110LBU,111LH,112LHU,113LW,114LWL,115LWR,116SB,117SH,118SW,119SWL,120SWR,121122LD,123LDL,124LDR,125LL,126LWU,127SC,128SD,129SDL,130SDR,131SYNC,132133ADDI,134ADDIU,135SLTI,136SLTIU,137ANDI,138ORI,139XORI,140LUI,141142DADDI,143DADDIU,144145ADD,146ADDU,147SUB,148SUBU,149SLT,150SLTU,151AND,152OR,153XOR,154NOR,155156DADD,157DADDU,158DSUB,159DSUBU,160161MULT,162MULTU,163DIV,164DIVU,165MFHI,166MTHI,167MFLO,168MTLO,169170DMULT,171DMULTU,172DDIV,173DDIVU,174175J,176J, // _OUT (unused)177J_IDLE,178JAL,179JAL, // _OUT (unused)180JAL_IDLE,181JR,182JALR,183BEQ,184BEQ, // _OUT (unused)185BEQ_IDLE,186BNE,187BNE, // _OUT (unused)188BNE_IDLE,189BLEZ,190BLEZ, // _OUT (unused)191BLEZ_IDLE,192BGTZ,193BGTZ, // _OUT (unused)194BGTZ_IDLE,195BLTZ,196BLTZ, // _OUT (unused)197BLTZ_IDLE,198BGEZ,199BGEZ, // _OUT (unused)200BGEZ_IDLE,201BLTZAL,202BLTZAL, // _OUT (unused)203BLTZAL_IDLE,204BGEZAL,205BGEZAL, // _OUT (unused)206BGEZAL_IDLE,207208BEQL,209BEQL, // _OUT (unused)210BEQL_IDLE,211BNEL,212BNEL, // _OUT (unused)213BNEL_IDLE,214BLEZL,215BLEZL, // _OUT (unused)216BLEZL_IDLE,217BGTZL,218BGTZL, // _OUT (unused)219BGTZL_IDLE,220BLTZL,221BLTZL, // _OUT (unused)222BLTZL_IDLE,223BGEZL,224BGEZL, // _OUT (unused)225BGEZL_IDLE,226BLTZALL,227BLTZALL, // _OUT (unused)228BLTZALL_IDLE,229BGEZALL,230BGEZALL, // _OUT (unused)231BGEZALL_IDLE,232BC1TL,233BC1TL, // _OUT (unused)234BC1TL_IDLE,235BC1FL,236BC1FL, // _OUT (unused)237BC1FL_IDLE,238239SLL,240SRL,241SRA,242SLLV,243SRLV,244SRAV,245246DSLL,247DSRL,248DSRA,249DSLLV,250DSRLV,251DSRAV,252DSLL32,253DSRL32,254DSRA32,255256MTC0,257MFC0,258259TLBR,260TLBWI,261TLBWR,262TLBP,263CACHE,264ERET,265266LWC1,267SWC1,268MTC1,269MFC1,270CTC1,271CFC1,272BC1T,273BC1T, // _OUT (unused)274BC1T_IDLE,275BC1F,276BC1F, // _OUT (unused)277BC1F_IDLE,278279DMFC1,280DMTC1,281LDC1,282SDC1,283284CVT_S_D,285CVT_S_W,286CVT_S_L,287CVT_D_S,288CVT_D_W,289CVT_D_L,290CVT_W_S,291CVT_W_D,292CVT_L_S,293CVT_L_D,294295ROUND_W_S,296ROUND_W_D,297ROUND_L_S,298ROUND_L_D,299300TRUNC_W_S,301TRUNC_W_D,302TRUNC_L_S,303TRUNC_L_D,304305CEIL_W_S,306CEIL_W_D,307CEIL_L_S,308CEIL_L_D,309310FLOOR_W_S,311FLOOR_W_D,312FLOOR_L_S,313FLOOR_L_D,314315ADD_S,316ADD_D,317318SUB_S,319SUB_D,320321MUL_S,322MUL_D,323324DIV_S,325DIV_D,326327ABS_S,328ABS_D,329330MOV_S,331MOV_D,332333NEG_S,334NEG_D,335336SQRT_S,337SQRT_D,338339C_F_S,340C_F_D,341C_UN_S,342C_UN_D,343C_EQ_S,344C_EQ_D,345C_UEQ_S,346C_UEQ_D,347C_OLT_S,348C_OLT_D,349C_ULT_S,350C_ULT_D,351C_OLE_S,352C_OLE_D,353C_ULE_S,354C_ULE_D,355C_SF_S,356C_SF_D,357C_NGLE_S,358C_NGLE_D,359C_SEQ_S,360C_SEQ_D,361C_NGL_S,362C_NGL_D,363C_LT_S,364C_LT_D,365C_NGE_S,366C_NGE_D,367C_LE_S,368C_LE_D,369C_NGT_S,370C_NGT_D,371372SYSCALL,373374TEQ,375376NOP,377RESERVED,378NI,379380NULL, // FIN_BLOCK381NULL, // NOTCOMPILED382NULL, // NOTCOMPILED2383};384385static void prefetch(void)386{387unsigned int *mem = fast_mem_access(interp_PC.addr);388if (mem != NULL)389{390prefetch_opcode(mem[0], mem[1]);391}392else393{394DebugMessage(M64MSG_ERROR, "prefetch() execute address :%x", PC->addr);395stop=1;396}397}398399void pure_interpreter(void)400{401stop=0;402PC = &interp_PC;403PC->addr = last_addr = 0xa4000040;404405/*#ifdef DBG406if (g_DebuggerActive)407update_debugger(PC->addr);408#endif*/409410current_instruction_table = pure_interpreter_table;411412while (!stop)413{414prefetch();415#ifdef COMPARE_CORE416CoreCompareCallback();417#endif418#ifdef DBG419if (g_DebuggerActive) update_debugger(PC->addr, -1);420#endif421TRACECB();422PC->ops();423}424}425426427