~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to coregrind/m_dispatch/dispatch-x86-darwin.S

  • Committer: Benjamin Kerensa
  • Date: 2012-11-21 23:57:58 UTC
  • mfrom: (1.1.16)
  • Revision ID: bkerensa@ubuntu.com-20121121235758-bd1rv5uc5vzov2p6
Merge from debian unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
  This file is part of Valgrind, a dynamic binary instrumentation
9
9
  framework.
10
10
 
11
 
  Copyright (C) 2000-2011 Julian Seward 
 
11
  Copyright (C) 2000-2012 Julian Seward 
12
12
     jseward@acm.org
13
13
 
14
14
  This program is free software; you can redistribute it and/or
37
37
#include "libvex_guest_offsets.h"       /* for OFFSET_x86_EIP */
38
38
 
39
39
 
40
 
/* Global variables */
41
 
/* These are defined here instead of in their respective C files to
42
 
   avoid extra PIC branch code here. */
43
 
.data
44
 
.align 2
45
 
 
46
 
/* m_transtab.c */
47
 
.globl VG_(tt_fast)
48
 
.align 4
49
 
VG_(tt_fast):   .space VG_TT_FAST_SIZE*8, 0  /* (2*Addr) [VG_TT_FAST_SIZE] */
50
 
.globl VG_(tt_fastN)
51
 
VG_(tt_fastN):  .space VG_TT_FAST_SIZE*4, 0  /* (UInt *) [VG_TT_FAST_SIZE] */
52
 
 
53
 
/* scheduler.c */
54
 
.globl VG_(dispatch_ctr)
55
 
VG_(dispatch_ctr):      .long 0
56
 
 
57
 
        
58
40
/*------------------------------------------------------------*/
59
41
/*---                                                      ---*/
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.                             ---*/
62
45
/*---                                                      ---*/
63
46
/*------------------------------------------------------------*/
64
47
 
65
48
/*----------------------------------------------------*/
66
 
/*--- Preamble (set everything up)                 ---*/
 
49
/*--- Entry and preamble (set everything up)       ---*/
67
50
/*----------------------------------------------------*/
68
51
 
69
52
/* signature:
70
 
UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
 
53
void VG_(disp_run_translations)( UWord* two_words,
 
54
                                 void*  guest_state, 
 
55
                                 Addr   host_addr );
71
56
*/
72
57
.text
73
 
.globl VG_(run_innerloop)
74
 
VG_(run_innerloop):
75
 
        /* 4(%esp) holds guest_state */
76
 
        /* 8(%esp) holds do_profiling */
77
 
        
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 */
 
64
 
 
65
        /* The preamble */
 
66
 
 
67
        /* Save integer registers, since this is a pseudo-function. */
 
68
        pushl   %eax
79
69
        pushl   %ebx
80
70
        pushl   %ecx
81
71
        pushl   %edx
83
73
        pushl   %edi
84
74
        pushl   %ebp
85
75
        
86
 
        /* 28(%esp) holds guest_state */
87
 
        /* 32(%esp) holds do_profiling */
 
76
        /* 28+4(%esp) holds two_words */
 
77
        /* 28+8(%esp) holds guest_state */
 
78
        /* 28+12(%esp) holds host_addr */
88
79
 
89
 
        /* Set up the guest state pointer */
90
 
        movl    28(%esp), %ebp
91
 
        
92
 
        /* fetch %EIP into %eax */
93
 
        movl    OFFSET_x86_EIP(%ebp), %eax
 
80
        /* Get the host CPU in the state expected by generated code. */
94
81
 
95
82
        /* set host FPU control word to the default mode expected 
96
83
           by VEX-generated code.  See comments in libvex.h for
110
97
L1:
111
98
        /* set dir flag to known value */
112
99
        cld
113
 
        
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)
118
 
        /*NOTREACHED*/
119
 
 
120
 
/*----------------------------------------------------*/
121
 
/*--- NO-PROFILING (standard) dispatcher           ---*/
122
 
/*----------------------------------------------------*/
123
 
 
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 */
128
 
 
129
 
        /* save the jump address in the guest state */
130
 
        movl    %eax, OFFSET_x86_EIP(%ebp)
131
 
 
132
 
        /* Are we out of timeslice?  If yes, defer to scheduler. */
133
 
        subl    $1, VG_(dispatch_ctr)
134
 
        jz      counter_is_zero
135
 
 
136
 
        /* try a fast lookup in the translation cache */
137
 
        movl    %eax, %ebx
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 */
141
 
        cmpl    %eax, %esi
142
 
        jnz     fast_lookup_failed
143
 
 
144
 
        /* Found a match.  Jump to .host. */
145
 
        jmp     *%edi
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). */
149
 
        /*NOTREACHED*/
150
 
 
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 */
155
 
        jmp     gsp_changed
156
 
        ud2
157
 
        /*NOTREACHED*/
158
 
 
159
 
/*----------------------------------------------------*/
160
 
/*--- PROFILING dispatcher (can be much slower)    ---*/
161
 
/*----------------------------------------------------*/
162
 
 
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 */
167
 
 
168
 
        /* save the jump address in the guest state */
169
 
        movl    %eax, OFFSET_x86_EIP(%ebp)
170
 
 
171
 
        /* Are we out of timeslice?  If yes, defer to scheduler. */
172
 
        subl    $1, VG_(dispatch_ctr)
173
 
        jz      counter_is_zero
174
 
 
175
 
        /* try a fast lookup in the translation cache */
176
 
        movl    %eax, %ebx
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 */
180
 
        cmpl    %eax, %esi
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 */
187
 
        addl    $1, (%edx)
188
 
 
189
 
        /* Found a match.  Jump to .host. */
190
 
        jmp     *%edi
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). */
194
 
        /*NOTREACHED*/
195
 
 
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 */
200
 
        jmp     gsp_changed
201
 
        ud2
202
 
        /*NOTREACHED*/
203
 
 
204
 
/*----------------------------------------------------*/
205
 
/*--- exit points                                  ---*/
206
 
/*----------------------------------------------------*/
207
 
 
208
 
gsp_changed:
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. */
216
 
        movl    28(%esp), %esi
217
 
        movl    %eax, OFFSET_x86_EIP(%esi)
218
 
        movl    %ebp, %eax
219
 
        jmp     run_innerloop_exit
220
 
        /*NOTREACHED*/
221
 
 
222
 
counter_is_zero:
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
228
 
        /*NOTREACHED*/
229
 
 
230
 
fast_lookup_failed:
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
236
 
        /*NOTREACHED*/
237
 
 
238
 
 
239
 
 
240
 
/* All exits from the dispatcher go through here.  %eax holds
241
 
   the return value. 
242
 
*/
243
 
run_innerloop_exit: 
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. */
 
100
 
 
101
        /* Set up the guest state pointer */
 
102
        movl    28+8(%esp), %ebp
 
103
 
 
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. */
 
109
        jmpl    *28+12(%esp)
 
110
        /*NOTREACHED*/
 
111
 
 
112
/*----------------------------------------------------*/
 
113
/*--- Postamble and exit.                          ---*/
 
114
/*----------------------------------------------------*/
 
115
 
 
116
postamble:
 
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.) */
 
122
 
 
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 */
249
128
        pushl   $0
252
131
        popl    %esi /* get rid of the word without trashing %eflags */
253
132
        jnz     invariant_violation
254
133
#endif
255
 
        cmpl    $0, VG_(machine_x86_have_mxcsr)
 
134
#       cmpl    $0, VG_(machine_x86_have_mxcsr)
256
135
        jz      L2
257
136
        pushl   $0
258
137
        stmxcsr (%esp)
261
140
        popl    %esi
262
141
        jnz     invariant_violation
263
142
L2:     /* otherwise we're OK */
264
 
        jmp     run_innerloop_exit_REALLY
265
 
 
 
143
        jmp     remove_frame
266
144
invariant_violation:
267
145
        movl    $VG_TRC_INVARIANT_FAILED, %eax
268
 
        jmp     run_innerloop_exit_REALLY
 
146
        movl    $0, %edx
269
147
 
270
 
run_innerloop_exit_REALLY:
 
148
remove_frame:
 
149
        /* Stash return values */
 
150
        movl    28+4(%esp), %edi        /* two_words */
 
151
        movl    %eax, 0(%edi)
 
152
        movl    %edx, 4(%edi)
 
153
        /* Restore int regs and return. */
271
154
        popl    %ebp
272
155
        popl    %edi
273
156
        popl    %esi
274
157
        popl    %edx
275
158
        popl    %ecx
276
159
        popl    %ebx
 
160
        popl    %eax
277
161
        ret     
278
 
 
279
 
 
280
 
/*------------------------------------------------------------*/
281
 
/*---                                                      ---*/
282
 
/*--- A special dispatcher, for running no-redir           ---*/
283
 
/*--- translations.  Just runs the given translation once. ---*/
284
 
/*---                                                      ---*/
285
 
/*------------------------------------------------------------*/
286
 
 
287
 
/* signature:
288
 
void VG_(run_a_noredir_translation) ( UWord* argblock );
289
 
*/
290
 
 
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)
297
 
*/
298
 
.globl VG_(run_a_noredir_translation)
299
 
VG_(run_a_noredir_translation):
300
 
        /* Save callee-saves regs */
301
 
        pushl %esi
302
 
        pushl %edi
303
 
        pushl %ebp
304
 
        pushl %ebx
305
 
 
306
 
        movl 20(%esp), %edi     /* %edi = argblock */
307
 
        movl 4(%edi), %ebp      /* argblock[1] */
308
 
        jmp *0(%edi)            /* argblock[0] */
309
 
        /*NOTREACHED*/
310
 
        ud2
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):
315
 
        movl 20(%esp), %edi
316
 
        movl %eax, 8(%edi)      /* argblock[2] */
317
 
        movl %ebp, 12(%edi)     /* argblock[3] */
318
 
 
319
 
        popl %ebx
320
 
        popl %ebp
321
 
        popl %edi
322
 
        popl %esi
323
 
        ret
 
162
        
 
163
/*----------------------------------------------------*/
 
164
/*--- Continuation points                          ---*/
 
165
/*----------------------------------------------------*/
 
166
 
 
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
 
175
        popl    %edx
 
176
        /* 5 = movl $VG_(disp_chain_me_to_slowEP), %edx;
 
177
           2 = call *%edx */
 
178
        subl    $5+2, %edx
 
179
        jmp     postamble
 
180
 
 
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
 
189
        popl    %edx
 
190
        /* 5 = movl $VG_(disp_chain_me_to_fastEP), %edx;
 
191
           2 = call *%edx */
 
192
        subl    $5+2, %edx
 
193
        jmp     postamble
 
194
 
 
195
/* ------ Indirect but boring jump ------ */
 
196
.globl VG_(disp_cp_xindir)
 
197
VG_(disp_cp_xindir):
 
198
        /* Where are we going? */
 
199
        movl    OFFSET_x86_EIP(%ebp), %eax
 
200
 
 
201
        /* stats only */
 
202
        addl    $1, VG_(stats__n_xindirs_32)
 
203
        
 
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 */
 
209
        cmpl    %eax, %esi
 
210
        jnz     fast_lookup_failed
 
211
 
 
212
        /* Found a match.  Jump to .host. */
 
213
        jmp     *%edi
 
214
        ud2     /* persuade insn decoders not to speculate past here */
 
215
 
 
216
fast_lookup_failed:
 
217
        /* stats only */
 
218
        addl    $1, VG_(stats__n_xindir_misses_32)
 
219
 
 
220
        movl    $VG_TRC_INNER_FASTMISS, %eax
 
221
        movl    $0, %edx
 
222
        jmp     postamble
 
223
 
 
224
/* ------ Assisted jump ------ */
 
225
.globl VG_(disp_cp_xassisted)
 
226
VG_(disp_cp_xassisted):
 
227
        /* %ebp contains the TRC */
 
228
        movl    %ebp, %eax
 
229
        movl    $0, %edx
 
230
        jmp     postamble
 
231
 
 
232
/* ------ Event check failed ------ */
 
233
.globl VG_(disp_cp_evcheck_fail)
 
234
VG_(disp_cp_evcheck_fail):
 
235
        movl    $VG_TRC_INNER_COUNTERZERO, %eax
 
236
        movl    $0, %edx
 
237
        jmp     postamble
 
238
 
324
239
 
325
240
#endif // defined(VGP_x86_darwin)
326
 
                        
 
241
 
327
242
/*--------------------------------------------------------------------*/
328
243
/*--- end                                                          ---*/
329
244
/*--------------------------------------------------------------------*/