/[pcsx2_0.9.7]/trunk/pcsx2/IPU/coroutine.cpp
ViewVC logotype

Contents of /trunk/pcsx2/IPU/coroutine.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 5 months ago) by william
File size: 3782 byte(s)
committing r3113 initial commit again...
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
19 #include "coroutine.h"
20
21 struct coroutine {
22 void* pcalladdr;
23 void *pcurstack;
24
25 uptr storeebx, storeesi, storeedi, storeebp;
26
27 s32 restore; // if nonzero, restore the registers
28 s32 alloc;
29 //struct s_coroutine *caller;
30 //struct s_coroutine *restarget;
31
32 };
33
34 #define CO_STK_ALIGN 256
35 #define CO_STK_COROSIZE ((sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1))
36 #define CO_MIN_SIZE (4 * 1024)
37
38 coroutine* g_pCurrentRoutine;
39
40 coroutine_t so_create(void (*func)(void *), void *data, void *stack, int size)
41 {
42 void* endstack;
43 int alloc = 0; // r = CO_STK_COROSIZE;
44 coroutine *co;
45
46 if ((size &= ~(sizeof(s32) - 1)) < CO_MIN_SIZE) return NULL;
47 if (!stack) {
48 size = (size + sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1);
49 stack = malloc(size);
50 if (!stack) return NULL;
51 alloc = size;
52 }
53 endstack = (char*)stack + size - 64;
54 co = (coroutine*)stack;
55 stack = (char *) stack + CO_STK_COROSIZE;
56 *(void**)endstack = NULL;
57 *(void**)((char*)endstack+sizeof(void*)) = data;
58 co->alloc = alloc;
59 co->pcalladdr = (void*)func;
60 co->pcurstack = endstack;
61 return co;
62 }
63
64 void so_delete(coroutine_t coro)
65 {
66 coroutine *co = (coroutine *) coro;
67 pxAssert( co != NULL );
68 if (co->alloc) free(co);
69 }
70
71 // see acoroutines.S and acoroutines.asm for other asm implementations
72 #if defined(_MSC_VER)
73
74 __declspec(naked) void so_call(coroutine_t coro)
75 {
76 __asm {
77 mov eax, dword ptr [esp+4]
78 test dword ptr [eax+24], 1
79 jnz RestoreRegs
80 mov [eax+8], ebx
81 mov [eax+12], esi
82 mov [eax+16], edi
83 mov [eax+20], ebp
84 mov dword ptr [eax+24], 1
85 jmp CallFn
86 RestoreRegs:
87 // have to load and save at the same time
88 mov ecx, [eax+8]
89 mov edx, [eax+12]
90 mov [eax+8], ebx
91 mov [eax+12], esi
92 mov ebx, ecx
93 mov esi, edx
94 mov ecx, [eax+16]
95 mov edx, [eax+20]
96 mov [eax+16], edi
97 mov [eax+20], ebp
98 mov edi, ecx
99 mov ebp, edx
100
101 CallFn:
102 mov [g_pCurrentRoutine], eax
103 mov ecx, esp
104 mov esp, [eax+4]
105 mov [eax+4], ecx
106
107 jmp dword ptr [eax]
108 }
109 }
110
111 __declspec(naked) void so_resume(void)
112 {
113 __asm {
114 mov eax, [g_pCurrentRoutine]
115 mov ecx, [eax+8]
116 mov edx, [eax+12]
117 mov [eax+8], ebx
118 mov [eax+12], esi
119 mov ebx, ecx
120 mov esi, edx
121 mov ecx, [eax+16]
122 mov edx, [eax+20]
123 mov [eax+16], edi
124 mov [eax+20], ebp
125 mov edi, ecx
126 mov ebp, edx
127
128 // put the return address in pcalladdr
129 mov ecx, [esp]
130 mov [eax], ecx
131 add esp, 4 // remove the return address
132
133 // swap stack pointers
134 mov ecx, [eax+4]
135 mov [eax+4], esp
136 mov esp, ecx
137 ret
138 }
139 }
140
141 __declspec(naked) void so_exit(void)
142 {
143 __asm {
144 mov eax, [g_pCurrentRoutine]
145 mov esp, [eax+4]
146 mov ebx, [eax+8]
147 mov esi, [eax+12]
148 mov edi, [eax+16]
149 mov ebp, [eax+20]
150 ret
151 }
152 }
153 #endif

  ViewVC Help
Powered by ViewVC 1.1.22