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

Annotation of /trunk/pcsx2/x86/BaseblockEx.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 9 months ago) by william
File MIME type: text/plain
File size: 4145 byte(s)
committing r3113 initial commit again...
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     #pragma once
17    
18     #include <map> // used by BaseBlockEx
19     #include <utility>
20    
21     // Every potential jump point in the PS2's addressable memory has a BASEBLOCK
22     // associated with it. So that means a BASEBLOCK for every 4 bytes of PS2
23     // addressable memory. Yay!
24     struct BASEBLOCK
25     {
26     u32 m_pFnptr;
27    
28     const __inline uptr GetFnptr() const { return m_pFnptr; }
29     void __inline SetFnptr( uptr ptr ) { m_pFnptr = ptr; }
30     };
31    
32     // extra block info (only valid for start of fn)
33     struct BASEBLOCKEX
34     {
35     u32 startpc;
36     uptr fnptr;
37     u16 size; // size in dwords
38     u16 x86size;
39    
40     #ifdef PCSX2_DEVBUILD
41     u32 visited; // number of times called
42     u64 ltime; // regs it assumes to have set already
43     #endif
44    
45     };
46    
47     class BaseBlocks
48     {
49     protected:
50     typedef std::multimap<u32, uptr>::iterator linkiter_t;
51    
52     // switch to a hash map later?
53     std::multimap<u32, uptr> links;
54     uptr recompiler;
55     std::vector<BASEBLOCKEX> blocks;
56    
57     public:
58     BaseBlocks() :
59     recompiler( NULL )
60     , blocks(0)
61     {
62     blocks.reserve(0x4000);
63     }
64    
65     BaseBlocks(uptr recompiler_) :
66     recompiler(recompiler_),
67     blocks(0)
68     {
69     blocks.reserve(0x4000);
70     }
71    
72     void SetJITCompile( void (*recompiler_)() )
73     {
74     recompiler = (uptr)recompiler_;
75     }
76    
77     BASEBLOCKEX* New(u32 startpc, uptr fnptr);
78     int LastIndex (u32 startpc) const;
79     BASEBLOCKEX* GetByX86(uptr ip);
80    
81     __forceinline int Index (u32 startpc) const
82     {
83     int idx = LastIndex(startpc);
84     // fixme: I changed the parenthesis to be unambiguous, but this needs to be checked to see if ((x or y or z) and w)
85     // is correct, or ((x or y) or (z and w)), or some other variation. --arcum42
86     // Mixing &&'s and ||'s is not actually ambiguous; &&'s take precedence. Reverted to old behavior -- ChickenLiver.
87     if ((idx == -1) || (startpc < blocks[idx].startpc) ||
88     ((blocks[idx].size) && (startpc >= blocks[idx].startpc + blocks[idx].size * 4)))
89     return -1;
90     else
91     return idx;
92     }
93    
94     __forceinline BASEBLOCKEX* operator[](int idx)
95     {
96     if (idx < 0 || idx >= (int)blocks.size())
97     return 0;
98     return &blocks[idx];
99     }
100    
101     __forceinline BASEBLOCKEX* Get(u32 startpc)
102     {
103     return (*this)[Index(startpc)];
104     }
105    
106     __forceinline void Remove(int idx)
107     {
108     //u32 startpc = blocks[idx].startpc;
109     std::pair<linkiter_t, linkiter_t> range = links.equal_range(blocks[idx].startpc);
110     for (linkiter_t i = range.first; i != range.second; ++i)
111     *(u32*)i->second = recompiler - (i->second + 4);
112    
113     if( IsDevBuild )
114     {
115     // Clear the first instruction to 0xcc (breakpoint), as a way to assert if some
116     // static jumps get left behind to this block. Note: Do not clear more than the
117     // first byte, since this code is called during exception handlers and event handlers
118     // both of which expect to be able to return to the recompiled code.
119    
120     BASEBLOCKEX effu( blocks[idx] );
121     memset( (void*)effu.fnptr, 0xcc, 1 );
122     }
123    
124     // TODO: remove links from this block?
125     blocks.erase(blocks.begin() + idx);
126     }
127    
128     void Link(u32 pc, s32* jumpptr);
129    
130     __forceinline void Reset()
131     {
132     blocks.clear();
133     links.clear();
134     }
135     };
136    
137     #define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (x)*(sizeof(BASEBLOCK)/4)))
138    
139     static void recLUT_SetPage(uptr reclut[0x10000], uptr hwlut[0x10000],
140     BASEBLOCK *mapbase, uint pagebase, uint pageidx, uint mappage)
141     {
142     uint page = pagebase + pageidx;
143    
144     jASSUME( page < 0x10000 );
145     reclut[page] = (uptr)&mapbase[(mappage - page) << 14];
146     if (hwlut)
147     hwlut[page] = 0u - (pagebase << 16);
148     }
149    
150     C_ASSERT( sizeof(BASEBLOCK) == 4 );

  ViewVC Help
Powered by ViewVC 1.1.22