blob: 6d20d4c36c3eab1985ae3add6f9e46b834867f03 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
njnc9539842002-10-02 13:26:35 +00002##--------------------------------------------------------------------##
3##--- The core dispatch loop, for jumping to a code address. ---##
cerion85665ca2005-06-20 15:51:07 +00004##--- dispatch-x86.S ---##
njnc9539842002-10-02 13:26:35 +00005##--------------------------------------------------------------------##
sewardjde4a1d02002-03-22 01:27:54 +00006
7/*
njnb9c427c2004-12-01 14:14:42 +00008 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
sewardjde4a1d02002-03-22 01:27:54 +000010
njn53612422005-03-12 16:22:54 +000011 Copyright (C) 2000-2005 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000012 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
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.
18
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.
23
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.
28
njn25e49d8e72002-09-23 09:36:25 +000029 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000030*/
31
njnc7561b92005-06-19 01:24:32 +000032#include "pub_tool_basics_asm.h"
njna733b5f2005-05-12 13:15:38 +000033#include "pub_core_dispatch_asm.h"
njn2e8f4ef2005-05-14 21:44:20 +000034#include "pub_core_transtab_asm.h"
sewardj0312f512005-03-30 19:04:29 +000035#include "libvex_guest_offsets.h" /* for OFFSET_x86_EIP */
sewardjde4a1d02002-03-22 01:27:54 +000036
37
38/*------------------------------------------------------------*/
njnd6f157d2004-11-30 17:27:21 +000039/*--- The dispatch loop. ---*/
sewardjde4a1d02002-03-22 01:27:54 +000040/*------------------------------------------------------------*/
sewardj0312f512005-03-30 19:04:29 +000041
42/* signature: UWord VG_(run_innerloop) ( void* guest_state ) */
sewardj2a99cf62004-11-24 10:44:19 +000043
sewardjde4a1d02002-03-22 01:27:54 +000044.globl VG_(run_innerloop)
45VG_(run_innerloop):
sewardj2a99cf62004-11-24 10:44:19 +000046 /* 4(%esp) holds guest_state */
47
njn25e49d8e72002-09-23 09:36:25 +000048 /* ----- entry point to VG_(run_innerloop) ----- */
sewardj2e93c502002-04-12 11:12:52 +000049 pushl %ebx
50 pushl %ecx
51 pushl %edx
52 pushl %esi
53 pushl %edi
54 pushl %ebp
fitzhardinge98abfc72003-12-16 02:05:15 +000055
sewardj2a99cf62004-11-24 10:44:19 +000056 /* 28(%esp) holds guest_state */
fitzhardinge98abfc72003-12-16 02:05:15 +000057
njnbd2e75c2004-11-24 16:43:43 +000058 /* Set up the guest state pointer */
sewardj2a99cf62004-11-24 10:44:19 +000059 movl 28(%esp), %ebp
60
njnd6f157d2004-11-30 17:27:21 +000061 /* fetch %EIP into %eax */
sewardj0312f512005-03-30 19:04:29 +000062 movl OFFSET_x86_EIP(%ebp), %eax
sewardjff992722004-12-04 01:45:56 +000063
sewardjaa561fa2004-12-06 14:23:28 +000064 /* set host FPU control word to the default mode expected
sewardj5390e662005-01-10 16:51:14 +000065 by VEX-generated code. See comments in libvex.h for
66 more info. */
sewardjaa561fa2004-12-06 14:23:28 +000067 finit
sewardj5390e662005-01-10 16:51:14 +000068 pushl $0x027F
sewardjaa561fa2004-12-06 14:23:28 +000069 fldcw (%esp)
sewardjff992722004-12-04 01:45:56 +000070 addl $4, %esp
sewardjde4a1d02002-03-22 01:27:54 +000071
sewardjaa561fa2004-12-06 14:23:28 +000072 /* set host SSE control word to the default mode expected
73 by VEX-generated code. */
74 pushl $0x1F80
75 ldmxcsr (%esp)
76 addl $4, %esp
77
78 /* set dir flag to known value */
79 cld
80
sewardj8b635a42004-11-22 19:01:47 +000081 /* fall into main loop */
82
njnd6f157d2004-11-30 17:27:21 +000083 /* Here, %eax is the only live (real) register. The entire
84 simulated state is saved in the ThreadState. */
85
sewardj8b635a42004-11-22 19:01:47 +000086dispatch_boring:
sewardj2a99cf62004-11-24 10:44:19 +000087 /* save the jump address in the guest state */
sewardj0312f512005-03-30 19:04:29 +000088 movl %eax, OFFSET_x86_EIP(%ebp)
sewardj8b635a42004-11-22 19:01:47 +000089
90 /* Are we out of timeslice? If yes, defer to scheduler. */
91 subl $1, VG_(dispatch_ctr)
sewardj8b635a42004-11-22 19:01:47 +000092 jz counter_is_zero
sewardj45f02c42005-02-05 18:27:14 +000093
sewardj8b635a42004-11-22 19:01:47 +000094 /* try a fast lookup in the translation cache */
sewardjfa8ec112005-01-19 11:55:34 +000095 movl %eax, %ebx
96 andl $VG_TT_FAST_MASK, %ebx
97 movl VG_(tt_fast)(,%ebx,4), %ecx
98 cmpl %eax, (%ecx)
99 jnz fast_lookup_failed
sewardj45f02c42005-02-05 18:27:14 +0000100 /* increment bb profile counter */
sewardjfa8ec112005-01-19 11:55:34 +0000101 movl VG_(tt_fastN)(,%ebx,4), %edx
102 incl (%edx)
sewardj8b635a42004-11-22 19:01:47 +0000103
sewardjfa8ec112005-01-19 11:55:34 +0000104 /* Found a match. Call tce[1], which is 8 bytes along, since
105 each tce element is a 64-bit int. */
sewardjfa8ec112005-01-19 11:55:34 +0000106 addl $8, %ecx
107 call *%ecx
sewardj8b635a42004-11-22 19:01:47 +0000108
109 /*
njn25e49d8e72002-09-23 09:36:25 +0000110 %eax holds destination (original) address.
111 %ebp indicates further details of the control transfer
112 requested to the address in %eax.
sewardj2e93c502002-04-12 11:12:52 +0000113
sewardj2a99cf62004-11-24 10:44:19 +0000114 If ebp is unchanged (== * 28(%esp)), just jump next to %eax.
sewardj1ff79572004-11-30 11:18:57 +0000115
116 Otherwise fall out, back to the scheduler, and let it
117 figure out what to do next.
njn25e49d8e72002-09-23 09:36:25 +0000118 */
njn25e49d8e72002-09-23 09:36:25 +0000119
sewardj2a99cf62004-11-24 10:44:19 +0000120 cmpl 28(%esp), %ebp
njn25e49d8e72002-09-23 09:36:25 +0000121 jz dispatch_boring
122
123 jmp dispatch_exceptional
124
sewardjde4a1d02002-03-22 01:27:54 +0000125
sewardjde4a1d02002-03-22 01:27:54 +0000126
sewardj5390e662005-01-10 16:51:14 +0000127/* All exits from the dispatcher go through here. %eax holds
128 the return value.
129*/
130run_innerloop_exit:
131 /* We're leaving. Check that nobody messed with
132 %mxcsr or %fpucw. We can't mess with %eax here as it
133 holds the tentative return value, but any other is OK. */
134 pushl $0
135 fstcw (%esp)
136 cmpl $0x027F, (%esp)
137 popl %esi /* get rid of the word without trashing %eflags */
138 jnz invariant_violation
139 pushl $0
140 stmxcsr (%esp)
141 andl $0xFFFFFFC0, (%esp) /* mask out status flags */
142 cmpl $0x1F80, (%esp)
143 popl %esi
144 jnz invariant_violation
145 /* otherwise we're OK */
146 jmp run_innerloop_exit_REALLY
147
148invariant_violation:
149 movl $VG_TRC_INVARIANT_FAILED, %eax
150 jmp run_innerloop_exit_REALLY
151
152run_innerloop_exit_REALLY:
sewardj2a99cf62004-11-24 10:44:19 +0000153 popl %ebp
sewardjde4a1d02002-03-22 01:27:54 +0000154 popl %edi
155 popl %esi
156 popl %edx
157 popl %ecx
158 popl %ebx
sewardj2e93c502002-04-12 11:12:52 +0000159 ret
160
161
162
163/* Other ways of getting out of the inner loop. Placed out-of-line to
164 make it look cleaner.
165*/
166dispatch_exceptional:
njn25e49d8e72002-09-23 09:36:25 +0000167 /* this is jumped to only, not fallen-through from above */
sewardj2e93c502002-04-12 11:12:52 +0000168
njn25e49d8e72002-09-23 09:36:25 +0000169 /* save %eax in %EIP and defer to sched */
sewardj2a99cf62004-11-24 10:44:19 +0000170 movl 28(%esp), %edi
sewardj0312f512005-03-30 19:04:29 +0000171 movl %eax, OFFSET_x86_EIP(%edi)
fitzhardingea02f8812003-12-18 09:06:09 +0000172 movl %ebp, %eax
sewardj2e93c502002-04-12 11:12:52 +0000173 jmp run_innerloop_exit
174
sewardj5390e662005-01-10 16:51:14 +0000175fast_lookup_failed:
176 /* %EIP is up to date here since dispatch_boring dominates */
177 addl $1, VG_(dispatch_ctr)
178 movl $VG_TRC_INNER_FASTMISS, %eax
179 jmp run_innerloop_exit
180
181counter_is_zero:
182 /* %EIP is up to date here since dispatch_boring dominates */
183 addl $1, VG_(dispatch_ctr)
184 movl $VG_TRC_INNER_COUNTERZERO, %eax
185 jmp run_innerloop_exit
186
sewardj22854b92002-11-30 14:00:47 +0000187
thughes4ad52d02004-06-27 17:37:21 +0000188/* Let the linker know we don't need an executable stack */
189.section .note.GNU-stack,"",@progbits
sewardjde4a1d02002-03-22 01:27:54 +0000190
njnc9539842002-10-02 13:26:35 +0000191##--------------------------------------------------------------------##
njnbb120952004-11-23 18:19:29 +0000192##--- end ---##
njnc9539842002-10-02 13:26:35 +0000193##--------------------------------------------------------------------##