/[pcsx2_0.9.7]/trunk/pcsx2/x86/microVU_Misc.h
ViewVC logotype

Contents of /trunk/pcsx2/x86/microVU_Misc.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 1 month ago) by william
File MIME type: text/plain
File size: 12875 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #pragma once
17
18 using namespace x86Emitter;
19
20 typedef xRegisterSSE xmm;
21 typedef xRegister32 x32;
22
23 struct microVU;
24
25 //------------------------------------------------------------------
26 // Global Variables
27 //------------------------------------------------------------------
28
29 struct mVU_Globals {
30 u32 absclip[4], signbit[4], minvals[4], maxvals[4];
31 u32 one[4];
32 u32 Pi4[4];
33 u32 T1[4], T2[4], T3[4], T4[4], T5[4], T6[4], T7[4], T8[4];
34 u32 S2[4], S3[4], S4[4], S5[4];
35 u32 E1[4], E2[4], E3[4], E4[4], E5[4], E6[4];
36 float FTOI_4[4], FTOI_12[4], FTOI_15[4];
37 float ITOF_4[4], ITOF_12[4], ITOF_15[4];
38 };
39
40 extern const __aligned(32) mVU_Globals mVUglob;
41
42 static const uint _Ibit_ = 1 << 31;
43 static const uint _Ebit_ = 1 << 30;
44 static const uint _Mbit_ = 1 << 29;
45 static const uint _Dbit_ = 1 << 28;
46 static const uint _Tbit_ = 1 << 27;
47 static const uint _DTbit_ = 0; //( _Dbit_ | _Tbit_ ) // ToDo: Implement this stuff...
48
49 static const uint divI = 0x1040000;
50 static const uint divD = 0x2080000;
51
52 //------------------------------------------------------------------
53 // Helper Macros
54 //------------------------------------------------------------------
55
56 #define _Ft_ ((mVU->code >> 16) & 0x1F) // The ft part of the instruction register
57 #define _Fs_ ((mVU->code >> 11) & 0x1F) // The fs part of the instruction register
58 #define _Fd_ ((mVU->code >> 6) & 0x1F) // The fd part of the instruction register
59
60 #define _It_ ((mVU->code >> 16) & 0xF) // The it part of the instruction register
61 #define _Is_ ((mVU->code >> 11) & 0xF) // The is part of the instruction register
62 #define _Id_ ((mVU->code >> 6) & 0xF) // The id part of the instruction register
63
64 #define _X ((mVU->code>>24) & 0x1)
65 #define _Y ((mVU->code>>23) & 0x1)
66 #define _Z ((mVU->code>>22) & 0x1)
67 #define _W ((mVU->code>>21) & 0x1)
68
69 #define _X_Y_Z_W (((mVU->code >> 21 ) & 0xF))
70 #define _XYZW_SS (_X+_Y+_Z+_W==1)
71 #define _XYZW_SS2 (_XYZW_SS && (_X_Y_Z_W != 8))
72 #define _XYZW_PS (_X_Y_Z_W == 0xf)
73 #define _XYZWss(x) ((x==8) || (x==4) || (x==2) || (x==1))
74
75 #define _bc_ (mVU->code & 0x3)
76 #define _bc_x ((mVU->code & 0x3) == 0)
77 #define _bc_y ((mVU->code & 0x3) == 1)
78 #define _bc_z ((mVU->code & 0x3) == 2)
79 #define _bc_w ((mVU->code & 0x3) == 3)
80
81 #define _Fsf_ ((mVU->code >> 21) & 0x03)
82 #define _Ftf_ ((mVU->code >> 23) & 0x03)
83
84 #define _Imm5_ (mVU->Imm5())
85 #define _Imm11_ (mVU->Imm11())
86 #define _Imm12_ (mVU->Imm12())
87 #define _Imm15_ (mVU->Imm15())
88 #define _Imm24_ (mVU->Imm24())
89
90 #define isCOP2 (mVU->cop2 != 0)
91 #define isVU1 (mVU->index != 0)
92 #define isVU0 (mVU->index == 0)
93 #define getIndex (isVU1 ? 1 : 0)
94 #define getVUmem(x) (((isVU1) ? (x & 0x3ff) : ((x >= 0x400) ? (x & 0x43f) : (x & 0xff))) * 16)
95 #define offsetSS ((_X) ? (0) : ((_Y) ? (4) : ((_Z) ? 8: 12)))
96 #define offsetReg ((_X) ? (0) : ((_Y) ? (1) : ((_Z) ? 2: 3)))
97
98 #define xmmT1 xmm0 // Used for regAlloc
99 #define xmmT2 xmm1 // Used for regAlloc
100 #define xmmT3 xmm2 // Used for regAlloc
101 #define xmmT4 xmm3 // Used for regAlloc
102 #define xmmT5 xmm4 // Used for regAlloc
103 #define xmmT6 xmm5 // Used for regAlloc
104 #define xmmT7 xmm6 // Used for regAlloc
105 #define xmmPQ xmm7 // Holds the Value and Backup Values of P and Q regs
106
107 #define gprT1 eax // eax - Temp Reg
108 #define gprT2 ecx // ecx - Temp Reg
109 #define gprT3 edx // edx - Temp Reg
110 #define gprT1b ax // Low 16-bit of gprT1 (eax)
111 #define gprT2b cx // Low 16-bit of gprT2 (ecx)
112 #define gprT3b dx // Low 16-bit of gprT3 (edx)
113
114 #define gprF0 ebx // Status Flag 0
115 #define gprF1 ebp // Status Flag 1
116 #define gprF2 esi // Status Flag 2
117 #define gprF3 edi // Status Flag 3
118
119 // Function Params
120 #define mP microVU* mVU, int recPass
121 #define mV microVU* mVU
122 #define mF int recPass
123 #define mX mVU, recPass
124
125 typedef void __fastcall Fntype_mVUrecInst( microVU* mVU, int recPass );
126 typedef Fntype_mVUrecInst* Fnptr_mVUrecInst;
127
128 // Recursive Inline
129 #ifndef __LINUX__
130 #define __recInline __ri
131 #else
132 #define __recInline inline
133 #endif
134
135 // Function/Template Stuff
136 #define mVUx (vuIndex ? &microVU1 : &microVU0)
137 #define mVUop(opName) static void __fastcall opName (mP)
138 #define _mVUt template<int vuIndex>
139 #define _r static __recInline
140
141 // Define Passes
142 #define pass1 if (recPass == 0)
143 #define pass2 if (recPass == 1)
144 #define pass3 if (recPass == 2)
145 #define pass4 if (recPass == 3)
146
147 // Upper Opcode Cases
148 #define opCase1 if (opCase == 1) // Normal Opcodes
149 #define opCase2 if (opCase == 2) // BC Opcodes
150 #define opCase3 if (opCase == 3) // I Opcodes
151 #define opCase4 if (opCase == 4) // Q Opcodes
152
153 //------------------------------------------------------------------
154 // Define mVUquickSearch
155 //------------------------------------------------------------------
156 #ifndef __LINUX__
157 extern __pagealigned u8 mVUsearchXMM[__pagesize];
158 typedef u32 (__fastcall *mVUCall)(void*, void*);
159 #define mVUquickSearch(dest, src, size) ((((mVUCall)((void*)mVUsearchXMM))(dest, src)) == 0xf)
160 #define mVUemitSearch() { mVUcustomSearch(); }
161 #else
162 // Note: GCC builds crash with custom search function, because
163 // they're not guaranteeing 16-byte alignment on the structs :(
164 // #define mVUquickSearch(dest, src, size) (!memcmp(dest, src, size))
165 #define mVUquickSearch(dest, src, size) (!memcmp_mmx(dest, src, size))
166 #define mVUemitSearch()
167 #endif
168 //------------------------------------------------------------------
169
170 // Misc Macros...
171 #define __four(val) { val, val, val, val }
172 #define mVUcurProg mVU->prog.cur[0]
173 #define mVUblocks mVU->prog.cur->block
174 #define mVUir mVU->prog.IRinfo
175 #define mVUbranch mVU->prog.IRinfo.branch
176 #define mVUcycles mVU->prog.IRinfo.cycles
177 #define mVUcount mVU->prog.IRinfo.count
178 #define mVUpBlock mVU->prog.IRinfo.pBlock
179 #define mVUblock mVU->prog.IRinfo.block
180 #define mVUregs mVU->prog.IRinfo.block.pState
181 #define mVUregsTemp mVU->prog.IRinfo.regsTemp
182 #define iPC mVU->prog.IRinfo.curPC
183 #define mVUsFlagHack mVU->prog.IRinfo.sFlagHack
184 #define mVUconstReg mVU->prog.IRinfo.constReg
185 #define mVUstartPC mVU->prog.IRinfo.startPC
186 #define mVUinfo mVU->prog.IRinfo.info[iPC / 2]
187 #define mVUstall mVUinfo.stall
188 #define mVUup mVUinfo.uOp
189 #define mVUlow mVUinfo.lOp
190 #define sFLAG mVUinfo.sFlag
191 #define mFLAG mVUinfo.mFlag
192 #define cFLAG mVUinfo.cFlag
193 #define mVUrange (mVUcurProg.ranges[0])[0]
194 #define isEvilBlock (mVUpBlock->pState.blockType == 2)
195 #define isBadOrEvil (mVUlow.badBranch || mVUlow.evilBranch)
196 #define xPC ((iPC / 2) * 8)
197 #define curI ((u32*)mVU->regs().Micro)[iPC] //mVUcurProg.data[iPC]
198 #define setCode() { mVU->code = curI; }
199
200 #define incPC(x) (mVU->advancePC(x))
201 #define branchAddr mVU->getBranchAddr()
202 #define branchAddrN mVU->getBranchAddrN()
203
204 #define incPC2(x) { iPC = ((iPC + (x)) & mVU->progMemMask); }
205 #define bSaveAddr (((xPC + 16) & (mVU->microMemSize-8)) / 8)
206 #define shufflePQ (((mVU->p) ? 0xb0 : 0xe0) | ((mVU->q) ? 0x01 : 0x04))
207 #define cmpOffset(x) ((u8*)&(((u8*)x)[it[0].start]))
208 #define Rmem &mVU->regs().VI[REG_R].UL
209 #define aWrap(x, m) ((x > m) ? 0 : x)
210 #define shuffleSS(x) ((x==1)?(0x27):((x==2)?(0xc6):((x==4)?(0xe1):(0xe4))))
211 #define clampE CHECK_VU_EXTRA_OVERFLOW
212 #define elif else if
213
214 // Flag Info (Set if next-block's first 4 ops will read current-block's flags)
215 #define __Status (mVUregs.needExactMatch & 1)
216 #define __Mac (mVUregs.needExactMatch & 2)
217 #define __Clip (mVUregs.needExactMatch & 4)
218
219 // Pass 3 Helper Macros (Used for program logging)
220 #define _Fsf_String ((_Fsf_ == 3) ? "w" : ((_Fsf_ == 2) ? "z" : ((_Fsf_ == 1) ? "y" : "x")))
221 #define _Ftf_String ((_Ftf_ == 3) ? "w" : ((_Ftf_ == 2) ? "z" : ((_Ftf_ == 1) ? "y" : "x")))
222 #define xyzwStr(x,s) (_X_Y_Z_W == x) ? s :
223 #define _XYZW_String (xyzwStr(1, "w") (xyzwStr(2, "z") (xyzwStr(3, "zw") (xyzwStr(4, "y") (xyzwStr(5, "yw") (xyzwStr(6, "yz") (xyzwStr(7, "yzw") (xyzwStr(8, "x") (xyzwStr(9, "xw") (xyzwStr(10, "xz") (xyzwStr(11, "xzw") (xyzwStr(12, "xy") (xyzwStr(13, "xyw") (xyzwStr(14, "xyz") "xyzw"))))))))))))))
224 #define _BC_String (_bc_x ? "x" : (_bc_y ? "y" : (_bc_z ? "z" : "w")))
225 #define mVUlogFtFs() { mVUlog(".%s vf%02d, vf%02d", _XYZW_String, _Ft_, _Fs_); }
226 #define mVUlogFd() { mVUlog(".%s vf%02d, vf%02d", _XYZW_String, _Fd_, _Fs_); }
227 #define mVUlogACC() { mVUlog(".%s ACC, vf%02d", _XYZW_String, _Fs_); }
228 #define mVUlogFt() { mVUlog(", vf%02d", _Ft_); }
229 #define mVUlogBC() { mVUlog(", vf%02d%s", _Ft_, _BC_String); }
230 #define mVUlogI() { mVUlog(", I"); }
231 #define mVUlogQ() { mVUlog(", Q"); }
232 #define mVUlogCLIP() { mVUlog("w.xyz vf%02d, vf%02dw", _Fs_, _Ft_); }
233
234 // Program Logging...
235 #ifdef mVUlogProg
236 #define mVUlog ((isVU1) ? __mVULog<1> : __mVULog<0>)
237 #define mVUdumpProg __mVUdumpProgram<vuIndex>
238 #else
239 #define mVUlog(...) if (0) {}
240 #define mVUdumpProg(...) if (0) {}
241 #endif
242
243 //------------------------------------------------------------------
244 // Optimization Options
245 //------------------------------------------------------------------
246
247 // Reg Alloc
248 static const bool doRegAlloc = 1; // Set to 0 to flush every 32bit Instruction
249 // This turns off reg alloc for the most part, but reg alloc will still
250 // be done within instructions... Also on doSwapOp() regAlloc is needed between
251 // Lower and Upper instructions, so in this case it flushes after the full
252 // 64bit instruction (lower and upper)
253
254 // No Flag Optimizations
255 static const bool noFlagOpts = 0; // Set to 1 to disable all flag setting optimizations
256 // Note: The flag optimizations this disables should all be harmless, so
257 // this option is mainly just for debugging... it effectively forces mVU
258 // to always update Mac and Status Flags (both sticky and non-sticky) whenever
259 // an Upper Instruction updates them. It also always transfers the 4 possible
260 // flag instances between blocks...
261
262 // Constant Propagation
263 static const bool doConstProp = 0; // Set to 1 to turn on vi15 const propagation
264 // Enables Constant Propagation for Jumps based on vi15 'link-register'
265 // allowing us to know many indirect jump target addresses.
266 // Makes GoW a lot slower due to extra recompilation time and extra code-gen!
267
268 // Indirect Jump Caching
269 static const bool doJumpCaching = 1; // Set to 1 to enable jump caching
270 // Indirect jumps (JR/JALR) will remember the entry points to their previously
271 // jumped-to addresses. This allows us to skip the microBlockManager::search()
272 // routine that is performed every indirect jump in order to find a block within a
273 // program that matches the correct pipeline state.
274
275 //------------------------------------------------------------------
276 // Speed Hacks (can cause infinite loops, SPS, Black Screens, etc...)
277 //------------------------------------------------------------------
278
279 // Status Flag Speed Hack
280 #define CHECK_VU_FLAGHACK (EmuConfig.Speedhacks.vuFlagHack)
281 // This hack only updates the Status Flag on blocks that will read it.
282 // Most blocks do not read status flags, so this is a big speedup.
283
284 // Block Flag Instance No-Propagation Hack
285 #define CHECK_VU_BLOCKHACK (EmuConfig.Speedhacks.vuBlockHack)
286 // There are times when it is unknown if future blocks will need old
287 // flag instance data (due to indirect jumps). This hack assumes
288 // that they won't need old flag data. This effectively removes a lot
289 // of end-of-block flag instance shuffling, causing nice speedups.
290
291 // Min/Max Speed Hack
292 #define CHECK_VU_MINMAXHACK (EmuConfig.Speedhacks.vuMinMax)
293 // This hack uses SSE min/max instructions instead of emulated "logical min/max"
294 // The PS2 does not consider denormals as zero on the mini/max opcodes.
295 // This speedup is minor, but on AMD X2 CPUs it can be a 1~3% speedup
296
297 //------------------------------------------------------------------
298 // Unknown Data
299 //------------------------------------------------------------------
300
301 // XG Kick Transfer Delay Amount
302 #define mVU_XGKICK_CYCLES ((CHECK_XGKICKHACK) ? 3 : 1)
303 // Its unknown at recompile time how long the xgkick transfer will take
304 // so give it a value that makes games happy :) (SO3 is fine at 1 cycle delay)
305
306 //------------------------------------------------------------------
307
308 extern void mVUmergeRegs(const xmm& dest, const xmm& src, int xyzw, bool modXYZW=false);
309 extern void mVUsaveReg(const xmm& reg, xAddressVoid ptr, int xyzw, bool modXYZW);
310 extern void mVUloadReg(const xmm& reg, xAddressVoid ptr, int xyzw);

  ViewVC Help
Powered by ViewVC 1.1.22