37
37
#include "libvex_guest_offsets.h" /* for OFFSET_x86_EIP */
40
/* Global variables */
41
/* These are defined here instead of in their respective C files to
42
avoid extra PIC branch code here. */
49
VG_(tt_fast): .space VG_TT_FAST_SIZE*8, 0 /* (2*Addr) [VG_TT_FAST_SIZE] */
51
VG_(tt_fastN): .space VG_TT_FAST_SIZE*4, 0 /* (UInt *) [VG_TT_FAST_SIZE] */
54
.globl VG_(dispatch_ctr)
55
VG_(dispatch_ctr): .long 0
58
40
/*------------------------------------------------------------*/
60
/*--- The dispatch loop. VG_(run_innerloop) is used to ---*/
61
/*--- run all translations except no-redir ones. ---*/
42
/*--- The dispatch loop. VG_(disp_run_translations) is ---*/
43
/*--- used to run all translations, ---*/
44
/*--- including no-redir ones. ---*/
63
46
/*------------------------------------------------------------*/
65
48
/*----------------------------------------------------*/
66
/*--- Preamble (set everything up) ---*/
49
/*--- Entry and preamble (set everything up) ---*/
67
50
/*----------------------------------------------------*/
70
UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
53
void VG_(disp_run_translations)( UWord* two_words,
73
.globl VG_(run_innerloop)
75
/* 4(%esp) holds guest_state */
76
/* 8(%esp) holds do_profiling */
78
/* ----- entry point to VG_(run_innerloop) ----- */
58
.globl VG_(disp_run_translations)
59
VG_(disp_run_translations):
60
/* 0(%esp) holds our return address. */
61
/* 4(%esp) holds two_words */
62
/* 8(%esp) holds guest_state */
63
/* 12(%esp) holds host_addr */
67
/* Save integer registers, since this is a pseudo-function. */
111
98
/* set dir flag to known value */
114
/* fall into main loop (the right one) */
115
cmpl $0, 32(%esp) /* do_profiling */
116
je VG_(run_innerloop__dispatch_unassisted_unprofiled)
117
jmp VG_(run_innerloop__dispatch_unassisted_profiled)
120
/*----------------------------------------------------*/
121
/*--- NO-PROFILING (standard) dispatcher ---*/
122
/*----------------------------------------------------*/
124
.globl VG_(run_innerloop__dispatch_unassisted_unprofiled)
125
VG_(run_innerloop__dispatch_unassisted_unprofiled):
126
/* AT ENTRY: %eax is next guest addr, %ebp is the
127
unmodified guest state ptr */
129
/* save the jump address in the guest state */
130
movl %eax, OFFSET_x86_EIP(%ebp)
132
/* Are we out of timeslice? If yes, defer to scheduler. */
133
subl $1, VG_(dispatch_ctr)
136
/* try a fast lookup in the translation cache */
138
andl $VG_TT_FAST_MASK, %ebx
139
movl 0+VG_(tt_fast)(,%ebx,8), %esi /* .guest */
140
movl 4+VG_(tt_fast)(,%ebx,8), %edi /* .host */
142
jnz fast_lookup_failed
144
/* Found a match. Jump to .host. */
146
ud2 /* persuade insn decoders not to speculate past here */
147
/* generated code should run, then jump back to
148
VG_(run_innerloop__dispatch_{un,}assisted_unprofiled). */
151
.globl VG_(run_innerloop__dispatch_assisted_unprofiled)
152
VG_(run_innerloop__dispatch_assisted_unprofiled):
153
/* AT ENTRY: %eax is next guest addr, %ebp is the
154
modified guest state ptr */
159
/*----------------------------------------------------*/
160
/*--- PROFILING dispatcher (can be much slower) ---*/
161
/*----------------------------------------------------*/
163
.globl VG_(run_innerloop__dispatch_unassisted_profiled)
164
VG_(run_innerloop__dispatch_unassisted_profiled):
165
/* AT ENTRY: %eax is next guest addr, %ebp is the
166
unmodified guest state ptr */
168
/* save the jump address in the guest state */
169
movl %eax, OFFSET_x86_EIP(%ebp)
171
/* Are we out of timeslice? If yes, defer to scheduler. */
172
subl $1, VG_(dispatch_ctr)
175
/* try a fast lookup in the translation cache */
177
andl $VG_TT_FAST_MASK, %ebx
178
movl 0+VG_(tt_fast)(,%ebx,8), %esi /* .guest */
179
movl 4+VG_(tt_fast)(,%ebx,8), %edi /* .host */
181
jnz fast_lookup_failed
182
/* increment bb profile counter */
183
/* note: innocuous as this sounds, it causes a huge amount more
184
stress on D1 and significantly slows everything down. */
185
movl VG_(tt_fastN)(,%ebx,4), %edx
186
/* Use "addl $1", not "incl", to avoid partial-flags stall on P4 */
189
/* Found a match. Jump to .host. */
191
ud2 /* persuade insn decoders not to speculate past here */
192
/* generated code should run, then jump back to
193
VG_(run_innerloop__dispatch_{un,}assisted_profiled). */
196
.globl VG_(run_innerloop__dispatch_assisted_profiled)
197
VG_(run_innerloop__dispatch_assisted_profiled):
198
/* AT ENTRY: %eax is next guest addr, %ebp is the
199
modified guest state ptr */
204
/*----------------------------------------------------*/
205
/*--- exit points ---*/
206
/*----------------------------------------------------*/
209
/* Someone messed with the gsp. Have to
210
defer to scheduler to resolve this. dispatch ctr
211
is not yet decremented, so no need to increment. */
212
/* %EIP is NOT up to date here. First, need to write
213
%eax back to %EIP, but without trashing %ebp since
214
that holds the value we want to return to the scheduler.
215
Hence use %esi transiently for the guest state pointer. */
217
movl %eax, OFFSET_x86_EIP(%esi)
219
jmp run_innerloop_exit
223
/* %EIP is up to date here */
224
/* back out decrement of the dispatch counter */
225
addl $1, VG_(dispatch_ctr)
226
movl $VG_TRC_INNER_COUNTERZERO, %eax
227
jmp run_innerloop_exit
231
/* %EIP is up to date here */
232
/* back out decrement of the dispatch counter */
233
addl $1, VG_(dispatch_ctr)
234
movl $VG_TRC_INNER_FASTMISS, %eax
235
jmp run_innerloop_exit
240
/* All exits from the dispatcher go through here. %eax holds
244
/* We're leaving. Check that nobody messed with
245
%mxcsr or %fpucw. We can't mess with %eax here as it
246
holds the tentative return value, but any other is OK. */
101
/* Set up the guest state pointer */
102
movl 28+8(%esp), %ebp
104
/* and jump into the code cache. Chained translations in
105
the code cache run, until for whatever reason, they can't
106
continue. When that happens, the translation in question
107
will jump (or call) to one of the continuation points
108
VG_(cp_...) below. */
112
/*----------------------------------------------------*/
113
/*--- Postamble and exit. ---*/
114
/*----------------------------------------------------*/
117
/* At this point, %eax and %edx contain two
118
words to be returned to the caller. %eax
119
holds a TRC value, and %edx optionally may
120
hold another word (for CHAIN_ME exits, the
121
address of the place to patch.) */
123
/* We're leaving. Check that nobody messed with %mxcsr
124
or %fpucw. We can't mess with %eax or %edx here as they
125
holds the tentative return value, but any others are OK. */
247
126
#if !defined(ENABLE_INNER)
248
127
/* This check fails for self-hosting, so skip in that case */
262
141
jnz invariant_violation
263
142
L2: /* otherwise we're OK */
264
jmp run_innerloop_exit_REALLY
266
144
invariant_violation:
267
145
movl $VG_TRC_INVARIANT_FAILED, %eax
268
jmp run_innerloop_exit_REALLY
270
run_innerloop_exit_REALLY:
149
/* Stash return values */
150
movl 28+4(%esp), %edi /* two_words */
153
/* Restore int regs and return. */
280
/*------------------------------------------------------------*/
282
/*--- A special dispatcher, for running no-redir ---*/
283
/*--- translations. Just runs the given translation once. ---*/
285
/*------------------------------------------------------------*/
288
void VG_(run_a_noredir_translation) ( UWord* argblock );
291
/* Run a no-redir translation. argblock points to 4 UWords, 2 to carry args
292
and 2 to carry results:
293
0: input: ptr to translation
294
1: input: ptr to guest state
295
2: output: next guest PC
296
3: output: guest state pointer afterwards (== thread return code)
298
.globl VG_(run_a_noredir_translation)
299
VG_(run_a_noredir_translation):
300
/* Save callee-saves regs */
306
movl 20(%esp), %edi /* %edi = argblock */
307
movl 4(%edi), %ebp /* argblock[1] */
308
jmp *0(%edi) /* argblock[0] */
311
/* If the translation has been correctly constructed, we
312
should resume at the the following label. */
313
.globl VG_(run_a_noredir_translation__return_point)
314
VG_(run_a_noredir_translation__return_point):
316
movl %eax, 8(%edi) /* argblock[2] */
317
movl %ebp, 12(%edi) /* argblock[3] */
163
/*----------------------------------------------------*/
164
/*--- Continuation points ---*/
165
/*----------------------------------------------------*/
167
/* ------ Chain me to slow entry point ------ */
168
.globl VG_(disp_cp_chain_me_to_slowEP)
169
VG_(disp_cp_chain_me_to_slowEP):
170
/* We got called. The return address indicates
171
where the patching needs to happen. Collect
172
the return address and, exit back to C land,
173
handing the caller the pair (Chain_me_S, RA) */
174
movl $VG_TRC_CHAIN_ME_TO_SLOW_EP, %eax
176
/* 5 = movl $VG_(disp_chain_me_to_slowEP), %edx;
181
/* ------ Chain me to fast entry point ------ */
182
.globl VG_(disp_cp_chain_me_to_fastEP)
183
VG_(disp_cp_chain_me_to_fastEP):
184
/* We got called. The return address indicates
185
where the patching needs to happen. Collect
186
the return address and, exit back to C land,
187
handing the caller the pair (Chain_me_F, RA) */
188
movl $VG_TRC_CHAIN_ME_TO_FAST_EP, %eax
190
/* 5 = movl $VG_(disp_chain_me_to_fastEP), %edx;
195
/* ------ Indirect but boring jump ------ */
196
.globl VG_(disp_cp_xindir)
198
/* Where are we going? */
199
movl OFFSET_x86_EIP(%ebp), %eax
202
addl $1, VG_(stats__n_xindirs_32)
204
/* try a fast lookup in the translation cache */
205
movl %eax, %ebx /* next guest addr */
206
andl $VG_TT_FAST_MASK, %ebx /* entry# */
207
movl 0+VG_(tt_fast)(,%ebx,8), %esi /* .guest */
208
movl 4+VG_(tt_fast)(,%ebx,8), %edi /* .host */
210
jnz fast_lookup_failed
212
/* Found a match. Jump to .host. */
214
ud2 /* persuade insn decoders not to speculate past here */
218
addl $1, VG_(stats__n_xindir_misses_32)
220
movl $VG_TRC_INNER_FASTMISS, %eax
224
/* ------ Assisted jump ------ */
225
.globl VG_(disp_cp_xassisted)
226
VG_(disp_cp_xassisted):
227
/* %ebp contains the TRC */
232
/* ------ Event check failed ------ */
233
.globl VG_(disp_cp_evcheck_fail)
234
VG_(disp_cp_evcheck_fail):
235
movl $VG_TRC_INNER_COUNTERZERO, %eax
325
240
#endif // defined(VGP_x86_darwin)
327
242
/*--------------------------------------------------------------------*/
329
244
/*--------------------------------------------------------------------*/