/[pcsx2_0.9.7]/trunk/pcsx2/Interpreter.cpp
ViewVC logotype

Contents of /trunk/pcsx2/Interpreter.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 2 months ago) by william
File size: 9161 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
17 #include "PrecompiledHeader.h"
18 #include "Common.h"
19
20 #include "R5900OpcodeTables.h"
21 #include "R5900Exceptions.h"
22 #include "System/SysThreads.h"
23
24 #include "Elfheader.h"
25
26 #include <float.h>
27
28 using namespace R5900; // for OPCODE and OpcodeImpl
29
30 extern int vu0branch, vu1branch;
31
32 static int branch2 = 0;
33 static u32 cpuBlockCycles = 0; // 3 bit fixed point version of cycle count
34 static std::string disOut;
35
36 static void intEventTest();
37
38 // These macros are used to assemble the repassembler functions
39
40 static void debugI()
41 {
42 if( !IsDevBuild ) return;
43 if( cpuRegs.GPR.n.r0.UD[0] || cpuRegs.GPR.n.r0.UD[1] ) Console.Error("R0 is not zero!!!!");
44 }
45
46 //long int runs=0;
47
48 static void execI()
49 {
50 cpuRegs.code = memRead32( cpuRegs.pc );
51 if( IsDebugBuild )
52 debugI();
53
54 const OPCODE& opcode = GetCurrentInstruction();
55 //use this to find out what opcodes your game uses. very slow! (rama)
56 //runs++;
57 //if (runs > 1599999999){ //leave some time to startup the testgame
58 // if (opcode.Name[0] == 'L') { //find all opcodes beginning with "L"
59 // Console.WriteLn ("Load %s", opcode.Name);
60 // }
61 //}
62
63 // Another method of instruction dumping:
64 /*if( cpuRegs.cycle > 0x4f24d714 )
65 {
66 //CPU_LOG( "%s", disR5900Current.getCString());
67 disOut.clear();
68 opcode.disasm( disOut );
69 disOut += '\n';
70 CPU_LOG( disOut.c_str() );
71 }*/
72
73
74 cpuBlockCycles += opcode.cycles;
75 cpuRegs.pc += 4;
76
77 opcode.interpret();
78 }
79
80 static __fi void _doBranch_shared(u32 tar)
81 {
82 branch2 = cpuRegs.branch = 1;
83 execI();
84
85 // branch being 0 means an exception was thrown, since only the exception
86 // handler should ever clear it.
87
88 if( cpuRegs.branch != 0 )
89 {
90 cpuRegs.pc = tar;
91 cpuRegs.branch = 0;
92 }
93 }
94
95 static void __fastcall doBranch( u32 target )
96 {
97 _doBranch_shared( target );
98 cpuRegs.cycle += cpuBlockCycles >> 3;
99 cpuBlockCycles &= (1<<3)-1;
100 intEventTest();
101 }
102
103 void __fastcall intDoBranch(u32 target)
104 {
105 //Console.WriteLn("Interpreter Branch ");
106 _doBranch_shared( target );
107
108 if( Cpu == &intCpu )
109 {
110 cpuRegs.cycle += cpuBlockCycles >> 3;
111 cpuBlockCycles &= (1<<3)-1;
112 intEventTest();
113 }
114 }
115
116 void intSetBranch()
117 {
118 branch2 = /*cpuRegs.branch =*/ 1;
119 }
120
121 ////////////////////////////////////////////////////////////////////
122 // R5900 Branching Instructions!
123 // These are the interpreter versions of the branch instructions. Unlike other
124 // types of interpreter instructions which can be called safely from the recompilers,
125 // these instructions are not "recSafe" because they may not invoke the
126 // necessary branch test logic that the recs need to maintain sync with the
127 // cpuRegs.pc and delaySlot instruction and such.
128
129 namespace R5900 {
130 namespace Interpreter {
131 namespace OpcodeImpl {
132
133 /*********************************************************
134 * Jump to target *
135 * Format: OP target *
136 *********************************************************/
137 // fixme: looking at the other branching code, shouldn't those _SetLinks in BGEZAL and such only be set
138 // if the condition is true? --arcum42
139
140 void J()
141 {
142 doBranch(_JumpTarget_);
143 }
144
145 void JAL()
146 {
147 _SetLink(31);
148 doBranch(_JumpTarget_);
149 }
150
151 /*********************************************************
152 * Register branch logic *
153 * Format: OP rs, rt, offset *
154 *********************************************************/
155
156 void BEQ() // Branch if Rs == Rt
157 {
158 if (cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0])
159 doBranch(_BranchTarget_);
160 else
161 intEventTest();
162 }
163
164 void BNE() // Branch if Rs != Rt
165 {
166 if (cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0])
167 doBranch(_BranchTarget_);
168 else
169 intEventTest();
170 }
171
172 /*********************************************************
173 * Register branch logic *
174 * Format: OP rs, offset *
175 *********************************************************/
176
177 void BGEZ() // Branch if Rs >= 0
178 {
179 if(cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
180 {
181 doBranch(_BranchTarget_);
182 }
183 }
184
185 void BGEZAL() // Branch if Rs >= 0 and link
186 {
187
188 if (cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
189 {
190 _SetLink(31);
191 doBranch(_BranchTarget_);
192 }
193 }
194
195 void BGTZ() // Branch if Rs > 0
196 {
197 if (cpuRegs.GPR.r[_Rs_].SD[0] > 0)
198 {
199 doBranch(_BranchTarget_);
200 }
201 }
202
203 void BLEZ() // Branch if Rs <= 0
204 {
205 if (cpuRegs.GPR.r[_Rs_].SD[0] <= 0)
206 {
207 doBranch(_BranchTarget_);
208 }
209 }
210
211 void BLTZ() // Branch if Rs < 0
212 {
213 if (cpuRegs.GPR.r[_Rs_].SD[0] < 0)
214 {
215 doBranch(_BranchTarget_);
216 }
217 }
218
219 void BLTZAL() // Branch if Rs < 0 and link
220 {
221 if (cpuRegs.GPR.r[_Rs_].SD[0] < 0)
222 {
223 _SetLink(31);
224 doBranch(_BranchTarget_);
225 }
226 }
227
228 /*********************************************************
229 * Register branch logic Likely *
230 * Format: OP rs, offset *
231 *********************************************************/
232
233
234 void BEQL() // Branch if Rs == Rt
235 {
236 if(cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0])
237 {
238 doBranch(_BranchTarget_);
239 }
240 else
241 {
242 cpuRegs.pc +=4;
243 intEventTest();
244 }
245 }
246
247 void BNEL() // Branch if Rs != Rt
248 {
249 if(cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0])
250 {
251 doBranch(_BranchTarget_);
252 }
253 else
254 {
255 cpuRegs.pc +=4;
256 intEventTest();
257 }
258 }
259
260 void BLEZL() // Branch if Rs <= 0
261 {
262 if(cpuRegs.GPR.r[_Rs_].SD[0] <= 0)
263 {
264 doBranch(_BranchTarget_);
265 }
266 else
267 {
268 cpuRegs.pc +=4;
269 intEventTest();
270 }
271 }
272
273 void BGTZL() // Branch if Rs > 0
274 {
275 if(cpuRegs.GPR.r[_Rs_].SD[0] > 0)
276 {
277 doBranch(_BranchTarget_);
278 }
279 else
280 {
281 cpuRegs.pc +=4;
282 intEventTest();
283 }
284 }
285
286 void BLTZL() // Branch if Rs < 0
287 {
288 if(cpuRegs.GPR.r[_Rs_].SD[0] < 0)
289 {
290 doBranch(_BranchTarget_);
291 }
292 else
293 {
294 cpuRegs.pc +=4;
295 intEventTest();
296 }
297 }
298
299 void BGEZL() // Branch if Rs >= 0
300 {
301 if(cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
302 {
303 doBranch(_BranchTarget_);
304 }
305 else
306 {
307 cpuRegs.pc +=4;
308 intEventTest();
309 }
310 }
311
312 void BLTZALL() // Branch if Rs < 0 and link
313 {
314
315 if(cpuRegs.GPR.r[_Rs_].SD[0] < 0)
316 {
317 _SetLink(31);
318 doBranch(_BranchTarget_);
319 }
320 else
321 {
322 cpuRegs.pc +=4;
323 intEventTest();
324 }
325 }
326
327 void BGEZALL() // Branch if Rs >= 0 and link
328 {
329
330 if(cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
331 {
332 _SetLink(31);
333 doBranch(_BranchTarget_);
334 }
335 else
336 {
337 cpuRegs.pc +=4;
338 intEventTest();
339 }
340 }
341
342 /*********************************************************
343 * Register jump *
344 * Format: OP rs, rd *
345 *********************************************************/
346 void JR()
347 {
348 doBranch(cpuRegs.GPR.r[_Rs_].UL[0]);
349 }
350
351 void JALR()
352 {
353 u32 temp = cpuRegs.GPR.r[_Rs_].UL[0];
354
355 if (_Rd_) _SetLink(_Rd_);
356
357 doBranch(temp);
358 }
359
360 } } } // end namespace R5900::Interpreter::OpcodeImpl
361
362
363 // --------------------------------------------------------------------------------------
364 // R5900cpu/intCpu interface (implementations)
365 // --------------------------------------------------------------------------------------
366
367 static void intReserve()
368 {
369 // fixme : detect cpu for use the optimize asm code
370 }
371
372 static void intAlloc()
373 {
374 // Nothing to do!
375 }
376
377 static void intReset()
378 {
379 cpuRegs.branch = 0;
380 branch2 = 0;
381 }
382
383 static void intEventTest()
384 {
385 // Perform counters, ints, and IOP updates:
386 _cpuEventTest_Shared();
387 }
388
389 static void intExecute()
390 {
391 try {
392 if (g_SkipBiosHack) {
393 do
394 execI();
395 while (cpuRegs.pc != EELOAD_START);
396 eeloadReplaceOSDSYS();
397 }
398 if (ElfEntry != -1) {
399 do
400 execI();
401 while (cpuRegs.pc != ElfEntry);
402 eeGameStarting();
403 } else {
404 while (true)
405 execI();
406 }
407 } catch( Exception::ExitCpuExecute& ) { }
408 }
409
410 static void intCheckExecutionState()
411 {
412 if( GetCoreThread().HasPendingStateChangeRequest() )
413 throw Exception::ExitCpuExecute();
414 }
415
416 static void intStep()
417 {
418 execI();
419 }
420
421 static void intClear(u32 Addr, u32 Size)
422 {
423 }
424
425 static void intShutdown() {
426 }
427
428 static void intThrowException( const BaseR5900Exception& ex )
429 {
430 // No tricks needed; C++ stack unwnding should suffice for MSW and GCC alike.
431 ex.Rethrow();
432 }
433
434 static void intThrowException( const BaseException& ex )
435 {
436 // No tricks needed; C++ stack unwnding should suffice for MSW and GCC alike.
437 ex.Rethrow();
438 }
439
440 static void intSetCacheReserve( uint reserveInMegs )
441 {
442 }
443
444 static uint intGetCacheReserve()
445 {
446 return 0;
447 }
448
449 R5900cpu intCpu =
450 {
451 intReserve,
452 intShutdown,
453
454 intReset,
455 intStep,
456 intExecute,
457
458 intCheckExecutionState,
459 intThrowException,
460 intThrowException,
461 intClear,
462
463 intGetCacheReserve,
464 intSetCacheReserve,
465 };

  ViewVC Help
Powered by ViewVC 1.1.22