xen: refactor the various "version not supported" messages into a single helper
[valgrind.git] / coregrind / m_dispatch / dispatch-x86-linux.S
blob20517da3f1d91ffedb8da800506c576a188f750a
2 /*--------------------------------------------------------------------*/
3 /*--- The core dispatch loop, for jumping to a code address.       ---*/
4 /*---                                         dispatch-x86-linux.S ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8   This file is part of Valgrind, a dynamic binary instrumentation
9   framework.
11   Copyright (C) 2000-2013 Julian Seward 
12      jseward@acm.org
14   This program is free software; you can redistribute it and/or
15   modify it under the terms of the GNU General Public License as
16   published by the Free Software Foundation; either version 2 of the
17   License, or (at your option) any later version.
19   This program is distributed in the hope that it will be useful, but
20   WITHOUT ANY WARRANTY; without even the implied warranty of
21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22   General Public License for more details.
24   You should have received a copy of the GNU General Public License
25   along with this program; if not, write to the Free Software
26   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27   02111-1307, USA.
29   The GNU General Public License is contained in the file COPYING.
32 #if defined(VGP_x86_linux)
34 #include "pub_core_basics_asm.h"
35 #include "pub_core_dispatch_asm.h"
36 #include "pub_core_transtab_asm.h"
37 #include "libvex_guest_offsets.h"       /* for OFFSET_x86_EIP */
40 /*------------------------------------------------------------*/
41 /*---                                                      ---*/
42 /*--- The dispatch loop.  VG_(disp_run_translations) is    ---*/
43 /*--- used to run all translations,                        ---*/
44 /*--- including no-redir ones.                             ---*/
45 /*---                                                      ---*/
46 /*------------------------------------------------------------*/
48 /*----------------------------------------------------*/
49 /*--- Entry and preamble (set everything up)       ---*/
50 /*----------------------------------------------------*/
52 /* signature:
53 void VG_(disp_run_translations)( UWord* two_words,
54                                  void*  guest_state, 
55                                  Addr   host_addr );
57 .text
58 .globl VG_(disp_run_translations)
59 .type  VG_(disp_run_translations), @function
60 VG_(disp_run_translations):
61         /* 0(%esp) holds our return address. */
62         /* 4(%esp) holds two_words */
63         /* 8(%esp) holds guest_state */
64         /* 12(%esp) holds host_addr */
66         /* The preamble */
68         /* Save integer registers, since this is a pseudo-function. */
69         pushl   %eax
70         pushl   %ebx
71         pushl   %ecx
72         pushl   %edx
73         pushl   %esi
74         pushl   %edi
75         pushl   %ebp
76         
77         /* 28+4(%esp) holds two_words */
78         /* 28+8(%esp) holds guest_state */
79         /* 28+12(%esp) holds host_addr */
81         /* Get the host CPU in the state expected by generated code. */
83         /* set host FPU control word to the default mode expected 
84            by VEX-generated code.  See comments in libvex.h for
85            more info. */
86         finit
87         pushl   $0x027F
88         fldcw   (%esp)
89         addl    $4, %esp
90         
91         /* set host SSE control word to the default mode expected 
92            by VEX-generated code. */
93         cmpl    $0, VG_(machine_x86_have_mxcsr)
94         jz      L1
95         pushl   $0x1F80
96         ldmxcsr (%esp)
97         addl    $4, %esp
98 L1:
99         /* set dir flag to known value */
100         cld
102         /* Set up the guest state pointer */
103         movl    28+8(%esp), %ebp
105         /* and jump into the code cache.  Chained translations in
106            the code cache run, until for whatever reason, they can't
107            continue.  When that happens, the translation in question
108            will jump (or call) to one of the continuation points
109            VG_(cp_...) below. */
110         jmpl    *28+12(%esp)
111         /*NOTREACHED*/
113 /*----------------------------------------------------*/
114 /*--- Postamble and exit.                          ---*/
115 /*----------------------------------------------------*/
117 postamble:
118         /* At this point, %eax and %edx contain two
119            words to be returned to the caller.  %eax
120            holds a TRC value, and %edx optionally may
121            hold another word (for CHAIN_ME exits, the
122            address of the place to patch.) */
124         /* We're leaving.  Check that nobody messed with %mxcsr
125            or %fpucw.  We can't mess with %eax or %edx here as they
126            holds the tentative return value, but any others are OK. */
127 #if !defined(ENABLE_INNER)
128         /* This check fails for self-hosting, so skip in that case */
129         pushl   $0
130         fstcw   (%esp)
131         cmpl    $0x027F, (%esp)
132         popl    %esi /* get rid of the word without trashing %eflags */
133         jnz     invariant_violation
134 #endif
135 #       cmpl    $0, VG_(machine_x86_have_mxcsr)
136         jz      L2
137         pushl   $0
138         stmxcsr (%esp)
139         andl    $0xFFFFFFC0, (%esp)  /* mask out status flags */
140         cmpl    $0x1F80, (%esp)
141         popl    %esi
142         jnz     invariant_violation
143 L2:     /* otherwise we're OK */
144         jmp     remove_frame
145 invariant_violation:
146         movl    $VG_TRC_INVARIANT_FAILED, %eax
147         movl    $0, %edx
149 remove_frame:
150         /* Stash return values */
151         movl    28+4(%esp), %edi        /* two_words */
152         movl    %eax, 0(%edi)
153         movl    %edx, 4(%edi)
154         /* Restore int regs and return. */
155         popl    %ebp
156         popl    %edi
157         popl    %esi
158         popl    %edx
159         popl    %ecx
160         popl    %ebx
161         popl    %eax
162         ret     
163         
164 /*----------------------------------------------------*/
165 /*--- Continuation points                          ---*/
166 /*----------------------------------------------------*/
168 /* ------ Chain me to slow entry point ------ */
169 .global VG_(disp_cp_chain_me_to_slowEP)
170 VG_(disp_cp_chain_me_to_slowEP):
171         /* We got called.  The return address indicates
172            where the patching needs to happen.  Collect
173            the return address and, exit back to C land,
174            handing the caller the pair (Chain_me_S, RA) */
175         movl    $VG_TRC_CHAIN_ME_TO_SLOW_EP, %eax
176         popl    %edx
177         /* 5 = movl $VG_(disp_chain_me_to_slowEP), %edx;
178            2 = call *%edx */
179         subl    $5+2, %edx
180         jmp     postamble
182 /* ------ Chain me to fast entry point ------ */
183 .global VG_(disp_cp_chain_me_to_fastEP)
184 VG_(disp_cp_chain_me_to_fastEP):
185         /* We got called.  The return address indicates
186            where the patching needs to happen.  Collect
187            the return address and, exit back to C land,
188            handing the caller the pair (Chain_me_F, RA) */
189         movl    $VG_TRC_CHAIN_ME_TO_FAST_EP, %eax
190         popl    %edx
191         /* 5 = movl $VG_(disp_chain_me_to_fastEP), %edx;
192            2 = call *%edx */
193         subl    $5+2, %edx
194         jmp     postamble
196 /* ------ Indirect but boring jump ------ */
197 .global VG_(disp_cp_xindir)
198 VG_(disp_cp_xindir):
199         /* Where are we going? */
200         movl    OFFSET_x86_EIP(%ebp), %eax
202         /* stats only */
203         addl    $1, VG_(stats__n_xindirs_32)
204         
205         /* try a fast lookup in the translation cache */
206         movl    %eax, %ebx                      /* next guest addr */
207         andl    $VG_TT_FAST_MASK, %ebx          /* entry# */
208         movl    0+VG_(tt_fast)(,%ebx,8), %esi   /* .guest */
209         movl    4+VG_(tt_fast)(,%ebx,8), %edi   /* .host */
210         cmpl    %eax, %esi
211         jnz     fast_lookup_failed
213         /* Found a match.  Jump to .host. */
214         jmp     *%edi
215         ud2     /* persuade insn decoders not to speculate past here */
217 fast_lookup_failed:
218         /* stats only */
219         addl    $1, VG_(stats__n_xindir_misses_32)
221         movl    $VG_TRC_INNER_FASTMISS, %eax
222         movl    $0, %edx
223         jmp     postamble
225 /* ------ Assisted jump ------ */
226 .global VG_(disp_cp_xassisted)
227 VG_(disp_cp_xassisted):
228         /* %ebp contains the TRC */
229         movl    %ebp, %eax
230         movl    $0, %edx
231         jmp     postamble
233 /* ------ Event check failed ------ */
234 .global VG_(disp_cp_evcheck_fail)
235 VG_(disp_cp_evcheck_fail):
236         movl    $VG_TRC_INNER_COUNTERZERO, %eax
237         movl    $0, %edx
238         jmp     postamble
241 .size VG_(disp_run_translations), .-VG_(disp_run_translations)
243 /* Let the linker know we don't need an executable stack */
244 .section .note.GNU-stack,"",@progbits
246 #endif // defined(VGP_x86_linux)
248 /*--------------------------------------------------------------------*/
249 /*--- end                                                          ---*/
250 /*--------------------------------------------------------------------*/