tests/vg_regtest: Always evaluate prerequisite expressions with sh
[valgrind.git] / coregrind / m_dispatch / dispatch-amd64-linux.S
blob245f693cdc12727d34e85859002359b5ed720db9
2 /*--------------------------------------------------------------------*/
3 /*--- The core dispatch loop, for jumping to a code address.       ---*/
4 /*---                                       dispatch-amd64-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_amd64_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_amd64_RIP */
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         /* %rdi holds two_words    */
62         /* %rsi holds guest_state  */
63         /* %rdx holds host_addr    */
65         /* The preamble */
67         /* Save integer registers, since this is a pseudo-function. */
68         pushq   %rax
69         pushq   %rbx
70         pushq   %rcx
71         pushq   %rdx
72         pushq   %rsi
73         pushq   %rbp
74         pushq   %r8
75         pushq   %r9
76         pushq   %r10
77         pushq   %r11
78         pushq   %r12
79         pushq   %r13
80         pushq   %r14
81         pushq   %r15
82         /* %rdi must be saved last */
83         pushq   %rdi
85         /* Get the host CPU in the state expected by generated code. */
87         /* set host FPU control word to the default mode expected 
88            by VEX-generated code.  See comments in libvex.h for
89            more info. */
90         finit
91         pushq   $0x027F
92         fldcw   (%rsp)
93         addq    $8, %rsp
94         
95         /* set host SSE control word to the default mode expected 
96            by VEX-generated code. */
97         pushq   $0x1F80
98         ldmxcsr (%rsp)
99         addq    $8, %rsp
101         /* set dir flag to known value */
102         cld
104         /* Set up the guest state pointer */
105         movq    %rsi, %rbp
107         /* and jump into the code cache.  Chained translations in
108            the code cache run, until for whatever reason, they can't
109            continue.  When that happens, the translation in question
110            will jump (or call) to one of the continuation points
111            VG_(cp_...) below. */
112         jmpq    *%rdx
113         /*NOTREACHED*/  
115 /*----------------------------------------------------*/
116 /*--- Postamble and exit.                          ---*/
117 /*----------------------------------------------------*/
119 postamble:
120         /* At this point, %rax and %rdx contain two
121            words to be returned to the caller.  %rax
122            holds a TRC value, and %rdx optionally may
123            hold another word (for CHAIN_ME exits, the
124            address of the place to patch.) */
125         
126         /* We're leaving.  Check that nobody messed with %mxcsr
127            or %fpucw.  We can't mess with %rax or %rdx here as they
128            hold the tentative return values, but any others are OK. */
129 #if !defined(ENABLE_INNER)
130         /* This check fails for self-hosting, so skip in that case */
131         pushq   $0
132         fstcw   (%rsp)
133         cmpl    $0x027F, (%rsp)
134         popq    %r15 /* get rid of the word without trashing %rflags */
135         jnz     invariant_violation
136 #endif
137         pushq   $0
138         stmxcsr (%rsp)
139         andl    $0xFFFFFFC0, (%rsp)  /* mask out status flags */
140         cmpl    $0x1F80, (%rsp)
141         popq    %r15
142         jnz     invariant_violation
143         /* otherwise we're OK */
144         jmp     remove_frame
145 invariant_violation:
146         movq    $VG_TRC_INVARIANT_FAILED, %rax
147         movq    $0, %rdx
149 remove_frame:
150         /* Pop %rdi, stash return values */
151         popq    %rdi
152         movq    %rax, 0(%rdi)
153         movq    %rdx, 8(%rdi)
154         /* Now pop everything else */
155         popq    %r15
156         popq    %r14
157         popq    %r13
158         popq    %r12
159         popq    %r11
160         popq    %r10
161         popq    %r9
162         popq    %r8
163         popq    %rbp
164         popq    %rsi
165         popq    %rdx
166         popq    %rcx
167         popq    %rbx
168         popq    %rax
169         ret     
170         
171 /*----------------------------------------------------*/
172 /*--- Continuation points                          ---*/
173 /*----------------------------------------------------*/
175 /* ------ Chain me to slow entry point ------ */
176 .global VG_(disp_cp_chain_me_to_slowEP)
177 VG_(disp_cp_chain_me_to_slowEP):
178         /* We got called.  The return address indicates
179            where the patching needs to happen.  Collect
180            the return address and, exit back to C land,
181            handing the caller the pair (Chain_me_S, RA) */
182         movq    $VG_TRC_CHAIN_ME_TO_SLOW_EP, %rax
183         popq    %rdx
184         /* 10 = movabsq $VG_(disp_chain_me_to_slowEP), %r11;
185            3  = call *%r11 */
186         subq    $10+3, %rdx
187         jmp     postamble
189 /* ------ Chain me to fast entry point ------ */
190 .global VG_(disp_cp_chain_me_to_fastEP)
191 VG_(disp_cp_chain_me_to_fastEP):
192         /* We got called.  The return address indicates
193            where the patching needs to happen.  Collect
194            the return address and, exit back to C land,
195            handing the caller the pair (Chain_me_F, RA) */
196         movq    $VG_TRC_CHAIN_ME_TO_FAST_EP, %rax
197         popq    %rdx
198         /* 10 = movabsq $VG_(disp_chain_me_to_fastEP), %r11;
199            3  = call *%r11 */
200         subq    $10+3, %rdx
201         jmp     postamble
203 /* ------ Indirect but boring jump ------ */
204 .global VG_(disp_cp_xindir)
205 VG_(disp_cp_xindir):
206         /* Where are we going? */
207         movq    OFFSET_amd64_RIP(%rbp), %rax
209         /* stats only */
210         addl    $1, VG_(stats__n_xindirs_32)
211         
212         /* try a fast lookup in the translation cache */
213         movabsq $VG_(tt_fast), %rcx
214         movq    %rax, %rbx              /* next guest addr */
215         andq    $VG_TT_FAST_MASK, %rbx  /* entry# */
216         shlq    $4, %rbx                /* entry# * sizeof(FastCacheEntry) */
217         movq    0(%rcx,%rbx,1), %r10    /* .guest */
218         movq    8(%rcx,%rbx,1), %r11    /* .host */
219         cmpq    %rax, %r10
220         jnz     fast_lookup_failed
222         /* Found a match.  Jump to .host. */
223         jmp     *%r11
224         ud2     /* persuade insn decoders not to speculate past here */
226 fast_lookup_failed:
227         /* stats only */
228         addl    $1, VG_(stats__n_xindir_misses_32)
230         movq    $VG_TRC_INNER_FASTMISS, %rax
231         movq    $0, %rdx
232         jmp     postamble
234 /* ------ Assisted jump ------ */
235 .global VG_(disp_cp_xassisted)
236 VG_(disp_cp_xassisted):
237         /* %rbp contains the TRC */
238         movq    %rbp, %rax
239         movq    $0, %rdx
240         jmp     postamble
242 /* ------ Event check failed ------ */
243 .global VG_(disp_cp_evcheck_fail)
244 VG_(disp_cp_evcheck_fail):
245         movq    $VG_TRC_INNER_COUNTERZERO, %rax
246         movq    $0, %rdx
247         jmp     postamble
250 .size VG_(disp_run_translations), .-VG_(disp_run_translations)
252 /* Let the linker know we don't need an executable stack */
253 .section .note.GNU-stack,"",@progbits
255 #endif // defined(VGP_amd64_linux)
257 /*--------------------------------------------------------------------*/
258 /*--- end                                                          ---*/
259 /*--------------------------------------------------------------------*/