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

Annotation of /trunk/pcsx2/Interpreter.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (hide annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 1 month ago) by william
File size: 9161 byte(s)
re-commit (had local access denied errors when committing)
1 william 31 /* 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 william 62 #include "R5900Exceptions.h"
22 william 31 #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 william 62 static __fi void _doBranch_shared(u32 tar)
81 william 31 {
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 william 280 // --------------------------------------------------------------------------------------
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 william 31 static void intAlloc()
373     {
374 william 280 // Nothing to do!
375 william 31 }
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 william 62 _cpuEventTest_Shared();
387 william 31 }
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 william 62 static void intThrowException( const BaseR5900Exception& ex )
429     {
430 william 280 // No tricks needed; C++ stack unwnding should suffice for MSW and GCC alike.
431 william 62 ex.Rethrow();
432     }
433    
434     static void intThrowException( const BaseException& ex )
435     {
436 william 280 // No tricks needed; C++ stack unwnding should suffice for MSW and GCC alike.
437 william 62 ex.Rethrow();
438     }
439    
440 william 280 static void intSetCacheReserve( uint reserveInMegs )
441     {
442     }
443    
444     static uint intGetCacheReserve()
445     {
446     return 0;
447     }
448    
449 william 31 R5900cpu intCpu =
450     {
451 william 280 intReserve,
452 william 31 intShutdown,
453    
454     intReset,
455     intStep,
456     intExecute,
457    
458     intCheckExecutionState,
459 william 62 intThrowException,
460     intThrowException,
461 william 31 intClear,
462 william 280
463     intGetCacheReserve,
464     intSetCacheReserve,
465 william 31 };

  ViewVC Help
Powered by ViewVC 1.1.22