forked from user1095108/generic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
savestate.hpp
179 lines (171 loc) · 4.94 KB
/
savestate.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#ifndef SAVESTATE_H
# define SAVESTATE_H
# pragma once
struct statebuf
{
void* sp;
void* bp;
void* label;
};
#if defined(__GNUC__)
static inline bool __attribute__((always_inline)) savestate(
statebuf& ssb) noexcept
{
bool r;
#if defined(i386) || defined(__i386) || defined(__i386__)
asm volatile (
"movl %%esp, %0\n\t" // store sp
"movl %%ebp, %1\n\t" // store bp
"movl $1f, %2\n\t" // store label
"movb $0, %3\n\t" // return false
"jmp 2f\n\t"
"1:"
"movb $1, %3\n\t" // return true
"2:"
: "=m" (ssb.sp), "=m" (ssb.bp), "=m" (ssb.label), "=r" (r)
:
: "memory"
);
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
asm volatile (
"movq %%rsp, %0\n\t" // store sp
"movq %%rbp, %1\n\t" // store bp
"movq $1f, %2\n\t" // store label
"movb $0, %3\n\t" // return false
"jmp 2f\n\t"
"1:"
"movb $1, %3\n\t" // return true
"2:"
: "=m" (ssb.sp), "=m" (ssb.bp), "=m" (ssb.label), "=r" (r)
:
: "memory"
);
#elif defined(__aarch64__)
asm volatile (
"mov x7, sp\n\t"
"str x7, %0\n\t" // store sp
"str fp, %1\n\t" // store fp
"ldr x7, =1f\n\t" // load label into x3
"str x7, %2\n\t" // store x3 into label
"mov %w3, #0\n\t" // store 0 into result
"b 2f\n\t"
"1:"
"mov %w3, #1\n\t" // store 1 into result
"2:"
: "=m" (ssb.sp), "=m" (ssb.bp), "=m" (ssb.label), "=r" (r)
:
: "x7", "memory"
);
#elif defined(__ARM_ARCH) && (7 == __ARM_ARCH)
asm volatile (
"str sp, %0\n\t" // store sp
"str r7, %1\n\t" // store fp
"ldr r3, =1f\n\t" // load label into r3
"str r3, %2\n\t" // store r3 into label
"mov %3, $0\n\t" // store 0 into result
"b 2f\n\t"
"1:"
"mov %3, $1\n\t" // store 1 into result
"2:"
: "=m" (ssb.sp), "=m" (ssb.bp), "=m" (ssb.label), "=r" (r)
:
: "r3", "memory"
);
#elif defined(__arm__)
asm volatile (
"str sp, %0\n\t" // store sp
"str fp, %1\n\t" // store fp
"ldr r3, =1f\n\t" // load label into r3
"str r3, %2\n\t" // store r3 into label
"mov %3, $0\n\t" // store 0 into result
"b 2f\n\t"
"1:"
"mov %3, $1\n\t" // store 1 into result
"2:"
: "=m" (ssb.sp), "=m" (ssb.bp), "=m" (ssb.label), "=r" (r)
:
: "r3", "memory"
);
#endif
return r;
}
#elif defined(_MSC_VER)
__forceinline bool savestate(statebuf& ssb) noexcept
{
bool r;
__asm {
mov ebx, ssb
mov [ebx]ssb.sp, esp
mov [ebx]ssb.bp, ebp
mov [ebx]ssb.label, offset _1f
mov r, 0x0
jmp _2f
_1f:
mov r, 0x1
_2f:
}
return r;
}
#else
# error "unsupported compiler"
#endif
#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
#define restorestate(SSB) \
asm volatile ( \
"movl %0, %%esp\n\t" \
"movl %1, %%ebp\n\t" \
"jmp *%2" \
: \
: "m" (SSB.sp), "r" (SSB.bp), "r" (SSB.label)\
);
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
#define restorestate(SSB) \
asm volatile ( \
"movq %0, %%rsp\n\t" \
"movq %1, %%rbp\n\t" \
"jmp *%2" \
: \
: "m" (SSB.sp), "r" (SSB.bp), "r" (SSB.label)\
);
#elif defined(__aarch64__)
#define restorestate(SSB) \
asm volatile ( \
"mov sp, %0\n\t" \
"mov fp, %1\n\t" \
"ret %2" \
: \
: "r" (SSB.sp), "r" (SSB.bp), "r" (SSB.label)\
);
#elif defined(__ARM_ARCH) && (7 == __ARM_ARCH)
#define restorestate(SSB) \
asm volatile ( \
"ldr sp, %0\n\t" \
"mov r7, %1\n\t" \
"mov pc, %2" \
: \
: "m" (SSB.sp), "r" (SSB.bp), "r" (SSB.label)\
);
#elif defined(__arm__)
#define restorestate(SSB) \
asm volatile ( \
"ldr sp, %0\n\t" \
"mov fp, %1\n\t" \
"mov pc, %2" \
: \
: "m" (SSB.sp), "r" (SSB.bp), "r" (SSB.label)\
);
#else
# error "unsupported architecture"
#endif
#elif defined(_MSC_VER)
#define restorestate(SSB) \
__asm mov ebx, this \
__asm add ebx, [SSB] \
__asm mov esp, [ebx]SSB.sp\
__asm mov ebp, [ebx]SSB.bp\
__asm jmp [ebx]SSB.label
#else
# error "unsupported compiler"
#endif
#endif // SAVESTATE_H