2012-11-01 15:19:01 +00:00
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
2012-11-04 22:01:49 +00:00
// the Free Software Foundation, version 2.0 or later versions.
2012-11-01 15:19:01 +00:00
// This program 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 General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
# pragma once
2013-05-19 22:56:37 +00:00
# include "util/random/rng.h"
2013-12-30 09:17:11 +00:00
# include "Common/CommonTypes.h"
2014-05-27 06:55:48 +00:00
# include "Core/CoreParameter.h"
2014-03-15 09:45:39 +00:00
# include "Core/Opcode.h"
2012-11-01 15:19:01 +00:00
2014-03-15 18:22:19 +00:00
class PointerWrap ;
2013-08-24 21:43:49 +00:00
typedef Memory : : Opcode MIPSOpcode ;
2014-12-12 22:48:48 +00:00
// Unlike on the PPC, opcode 0 is not unused and thus we have to choose another fake
// opcode to represent JIT blocks and other emu hacks.
// I've chosen 0x68000000.
# define MIPS_EMUHACK_OPCODE 0x68000000
# define MIPS_EMUHACK_MASK 0xFC000000
# define MIPS_JITBLOCK_MASK 0xFF000000
# define MIPS_EMUHACK_VALUE_MASK 0x00FFFFFF
// There are 2 bits available for sub-opcodes, 0x03000000.
# define EMUOP_RUNBLOCK 0 // Runs a JIT block
# define EMUOP_RETKERNEL 1 // Returns to the simulated PSP kernel from a thread
# define EMUOP_CALL_REPLACEMENT 2
# define MIPS_IS_EMUHACK(op) (((op) & 0xFC000000) == MIPS_EMUHACK_OPCODE) // masks away the subop
# define MIPS_IS_RUNBLOCK(op) (((op) & 0xFF000000) == MIPS_EMUHACK_OPCODE) // masks away the subop
# define MIPS_IS_REPLACEMENT(op) (((op) & 0xFF000000) == (MIPS_EMUHACK_OPCODE | (EMUOP_CALL_REPLACEMENT << 24))) // masks away the subop
# define MIPS_EMUHACK_CALL_REPLACEMENT (MIPS_EMUHACK_OPCODE | (EMUOP_CALL_REPLACEMENT << 24))
2014-10-09 19:38:25 +00:00
enum MIPSGPReg {
2012-11-01 15:19:01 +00:00
MIPS_REG_ZERO = 0 ,
MIPS_REG_COMPILER_SCRATCH = 1 ,
MIPS_REG_V0 = 2 ,
MIPS_REG_V1 = 3 ,
MIPS_REG_A0 = 4 ,
MIPS_REG_A1 = 5 ,
MIPS_REG_A2 = 6 ,
MIPS_REG_A3 = 7 ,
2014-10-05 12:20:30 +00:00
MIPS_REG_A4 = 8 ,
2012-11-01 15:19:01 +00:00
MIPS_REG_A5 = 9 ,
2014-10-05 12:20:30 +00:00
MIPS_REG_T2 = 10 ,
MIPS_REG_T3 = 11 ,
2013-11-08 11:30:31 +00:00
MIPS_REG_T4 = 12 ,
MIPS_REG_T5 = 13 ,
MIPS_REG_T6 = 14 ,
MIPS_REG_T7 = 15 ,
2012-11-01 15:19:01 +00:00
MIPS_REG_S0 = 16 ,
MIPS_REG_S1 = 17 ,
MIPS_REG_S2 = 18 ,
MIPS_REG_S3 = 19 ,
MIPS_REG_S4 = 20 ,
MIPS_REG_S5 = 21 ,
MIPS_REG_S6 = 22 ,
MIPS_REG_S7 = 23 ,
2013-11-08 11:30:31 +00:00
MIPS_REG_T8 = 24 ,
MIPS_REG_T9 = 25 ,
2012-11-01 15:19:01 +00:00
MIPS_REG_K0 = 26 ,
MIPS_REG_K1 = 27 ,
MIPS_REG_GP = 28 ,
MIPS_REG_SP = 29 ,
MIPS_REG_FP = 30 ,
MIPS_REG_RA = 31 ,
2013-11-09 02:51:49 +00:00
// Not real regs, just for convenience/jit mapping.
MIPS_REG_HI = 32 ,
MIPS_REG_LO = 33 ,
2013-11-11 15:46:22 +00:00
MIPS_REG_FPCOND = 34 ,
2013-11-12 10:48:38 +00:00
MIPS_REG_VFPUCC = 35 ,
2014-10-09 19:38:25 +00:00
MIPS_REG_INVALID = - 1 ,
2012-11-01 15:19:01 +00:00
} ;
2014-10-09 19:38:25 +00:00
enum {
2012-11-01 15:19:01 +00:00
VFPU_CTRL_SPREFIX ,
VFPU_CTRL_TPREFIX ,
VFPU_CTRL_DPREFIX ,
VFPU_CTRL_CC ,
VFPU_CTRL_INF4 ,
VFPU_CTRL_RSV5 ,
VFPU_CTRL_RSV6 ,
VFPU_CTRL_REV ,
VFPU_CTRL_RCX0 ,
VFPU_CTRL_RCX1 ,
VFPU_CTRL_RCX2 ,
VFPU_CTRL_RCX3 ,
VFPU_CTRL_RCX4 ,
VFPU_CTRL_RCX5 ,
VFPU_CTRL_RCX6 ,
VFPU_CTRL_RCX7 ,
2012-11-22 19:14:24 +00:00
VFPU_CTRL_MAX ,
2012-11-01 15:19:01 +00:00
//unknown....
} ;
2013-07-31 20:29:16 +00:00
enum VCondition
{
VC_FL ,
VC_EQ ,
VC_LT ,
VC_LE ,
VC_TR ,
VC_NE ,
VC_GE ,
VC_GT ,
VC_EZ ,
VC_EN ,
VC_EI ,
VC_ES ,
VC_NZ ,
VC_NN ,
VC_NI ,
VC_NS
} ;
2013-11-27 21:45:17 +00:00
// In memory, we order the VFPU registers differently.
// Games use columns a whole lot more than rows, and it would thus be good if columns
// were contiguous in memory. Also, matrices aren't but should be.
extern u8 voffset [ 128 ] ;
extern u8 fromvoffset [ 128 ] ;
2013-01-08 13:20:06 +00:00
class MIPSState
2012-11-01 15:19:01 +00:00
{
public :
MIPSState ( ) ;
~ MIPSState ( ) ;
2014-01-28 10:32:54 +00:00
void Init ( ) ;
void Shutdown ( ) ;
2012-11-01 15:19:01 +00:00
void Reset ( ) ;
2014-05-27 06:55:48 +00:00
void UpdateCore ( CPUCore desired ) ;
2014-01-28 10:32:54 +00:00
2012-12-28 04:33:10 +00:00
void DoState ( PointerWrap & p ) ;
2012-11-01 15:19:01 +00:00
2013-08-15 08:26:16 +00:00
// MUST start with r and be followed by f!
2012-11-01 15:19:01 +00:00
u32 r [ 32 ] ;
2013-06-11 19:36:59 +00:00
union {
float f [ 32 ] ;
u32 fi [ 32 ] ;
int fs [ 32 ] ;
} ;
union {
float v [ 128 ] ;
u32 vi [ 128 ] ;
} ;
2013-07-31 08:33:44 +00:00
// Temps don't get flushed so we don't reserve space for them.
// If vfpuCtrl (prefixes) get mysterious values, check the VFPU regcache code.
2012-11-01 15:19:01 +00:00
u32 vfpuCtrl [ 16 ] ;
2013-08-15 08:26:16 +00:00
union {
struct {
u32 pc ;
2013-01-11 23:44:18 +00:00
2013-08-15 08:26:16 +00:00
u32 hi ;
u32 lo ;
2012-11-01 15:19:01 +00:00
2013-08-15 08:26:16 +00:00
u32 fcr31 ; //fpu control register
u32 fpcond ; // cache the cond flag of fcr31 (& 1 << 23)
} ;
u32 other [ 6 ] ;
} ;
u32 nextPC ;
int downcount ; // This really doesn't belong here, it belongs in CoreTiming. But you gotta do what you gotta do, this needs to be reachable in the ARM JIT.
2012-11-01 15:19:01 +00:00
bool inDelaySlot ;
2012-11-07 16:34:25 +00:00
int llBit ; // ll/sc
2013-11-12 13:42:42 +00:00
u32 temp ; // can be used to save temporaries during calculations when we need more than R0 and R1
2013-12-29 23:11:29 +00:00
2013-01-11 23:44:18 +00:00
GMRng rng ; // VFPU hardware random number generator. Probably not the right type.
2012-11-01 15:19:01 +00:00
// Debug stuff
u32 debugCount ; // can be used to count basic blocks before crashes, etc.
2013-11-14 06:41:25 +00:00
static const u32 FCR0_VALUE = 0x00003351 ;
2013-02-15 21:56:38 +00:00
u8 VfpuWriteMask ( ) const {
return ( vfpuCtrl [ VFPU_CTRL_DPREFIX ] > > 8 ) & 0xF ;
}
bool VfpuWriteMask ( int i ) const {
return ( vfpuCtrl [ VFPU_CTRL_DPREFIX ] > > ( 8 + i ) ) & 1 ;
}
2012-11-01 15:19:01 +00:00
2014-06-28 06:21:22 +00:00
bool HasDefaultPrefix ( ) const ;
2012-11-01 15:19:01 +00:00
void SingleStep ( ) ;
2012-11-19 13:16:37 +00:00
int RunLoopUntil ( u64 globalTicks ) ;
2013-09-01 07:32:17 +00:00
// To clear jit caches, etc.
void InvalidateICache ( u32 address , int length = 4 ) ;
2014-12-12 22:48:48 +00:00
void ClearJitCache ( ) ;
2012-11-01 15:19:01 +00:00
} ;
class MIPSDebugInterface ;
//The one we are compiling or running currently
extern MIPSState * currentMIPS ;
extern MIPSDebugInterface * currentDebugMIPS ;
extern MIPSState mipsr4k ;
2013-07-27 20:14:01 +00:00
extern const float cst_constants [ 32 ] ;