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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 6 months ago) by william
File MIME type: text/plain
File size: 3817 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 #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 __fi int Index (u32 startpc) const
82 {
83 int idx = LastIndex(startpc);
84 if ((idx == -1) || (startpc < blocks[idx].startpc) ||
85 ((blocks[idx].size) && (startpc >= blocks[idx].startpc + blocks[idx].size * 4)))
86 return -1;
87 else
88 return idx;
89 }
90
91 __fi BASEBLOCKEX* operator[](int idx)
92 {
93 if (idx < 0 || idx >= (int)blocks.size())
94 return 0;
95 return &blocks[idx];
96 }
97
98 __fi BASEBLOCKEX* Get(u32 startpc)
99 {
100 return (*this)[Index(startpc)];
101 }
102
103 __fi void Remove(int idx)
104 {
105 //u32 startpc = blocks[idx].startpc;
106 std::pair<linkiter_t, linkiter_t> range = links.equal_range(blocks[idx].startpc);
107 for (linkiter_t i = range.first; i != range.second; ++i)
108 *(u32*)i->second = recompiler - (i->second + 4);
109
110 if( IsDevBuild )
111 {
112 // Clear the first instruction to 0xcc (breakpoint), as a way to assert if some
113 // static jumps get left behind to this block. Note: Do not clear more than the
114 // first byte, since this code is called during exception handlers and event handlers
115 // both of which expect to be able to return to the recompiled code.
116
117 BASEBLOCKEX effu( blocks[idx] );
118 memset( (void*)effu.fnptr, 0xcc, 1 );
119 }
120
121 // TODO: remove links from this block?
122 blocks.erase(blocks.begin() + idx);
123 }
124
125 void Link(u32 pc, s32* jumpptr);
126
127 __fi void Reset()
128 {
129 blocks.clear();
130 links.clear();
131 }
132 };
133
134 #define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (x)*(sizeof(BASEBLOCK)/4)))
135
136 static void recLUT_SetPage(uptr reclut[0x10000], uptr hwlut[0x10000],
137 BASEBLOCK *mapbase, uint pagebase, uint pageidx, uint mappage)
138 {
139 // this value is in 64k pages!
140 uint page = pagebase + pageidx;
141
142 pxAssume( page < 0x10000 );
143 reclut[page] = (uptr)&mapbase[(mappage - page) << 14];
144 if (hwlut)
145 hwlut[page] = 0u - (pagebase << 16);
146 }
147
148 C_ASSERT( sizeof(BASEBLOCK) == 4 );

  ViewVC Help
Powered by ViewVC 1.1.22