2 /*--------------------------------------------------------------------*/
3 /*--- begin dispatch-tilegx-linux.S ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2010-2013 Tilera Corp.
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 The GNU General Public License is contained in the file COPYING.
30 /* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
32 #if defined(VGP_tilegx_linux)
33 #include "pub_core_basics_asm.h"
34 #include "pub_core_dispatch_asm.h"
35 #include "pub_core_transtab_asm.h"
36 #include "libvex_guest_offsets.h" /* for OFFSET_tilegx_PC */
38 /*------------------------------------------------------------*/
40 /*--- The dispatch loop. VG_(run_innerloop) is used to ---*/
41 /*--- run all translations except no-redir ones. ---*/
43 /*------------------------------------------------------------*/
45 /*----------------------------------------------------*/
46 /*--- Preamble (set everything up) ---*/
47 /*----------------------------------------------------*/
50 void VG_(disp_run_translations)(UWord* two_words,
53 UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
57 .globl VG_(disp_run_translations)
58 VG_(disp_run_translations):
85 /* ... and r30 - r53 */
112 /* Load the address of guest state into guest state register r50. */
117 /* jump to the code cache. */
122 /*----------------------------------------------------*/
123 /*--- Postamble and exit. ---*/
124 /*----------------------------------------------------*/
127 /* At this point, r12 and r13 contain two
128 words to be returned to the caller. r12
129 holds a TRC value, and r13 optionally may
130 hold another word (for CHAIN_ME exits, the
131 address of the place to patch.) */
133 /* run_innerloop_exit_REALLY:
134 r50 holds VG_TRC_* value to return
135 Return to parent stack
140 /* Restore r0 from stack; holding address of twp words */
142 /* store r12 in two_words[0] */
144 /* store r13 in two_words[1] */
147 /* Restore callee-saved registers... */
173 addli sp, sp, 256 /* stack_size */
178 /*----------------------------------------------------*/
179 /*--- Continuation points ---*/
180 /*----------------------------------------------------*/
182 /* ------ Chain me to slow entry point ------ */
183 .global VG_(disp_cp_chain_me_to_slowEP)
184 VG_(disp_cp_chain_me_to_slowEP):
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_S, RA) */
189 # if (VG_TRC_CHAIN_ME_TO_SLOW_EP > 128)
190 # error ("VG_TRC_CHAIN_ME_TO_SLOW_EP is > 128");
192 moveli r12, VG_TRC_CHAIN_ME_TO_SLOW_EP
194 /* 32 = mkLoadImm_EXACTLY4
200 /* ------ Chain me to slow entry point ------ */
201 .global VG_(disp_cp_chain_me_to_fastEP)
202 VG_(disp_cp_chain_me_to_fastEP):
203 /* We got called. The return address indicates
204 where the patching needs to happen. Collect
205 the return address and, exit back to C land,
206 handing the caller the pair (Chain_me_S, RA) */
207 # if (VG_TRC_CHAIN_ME_TO_FAST_EP > 128)
208 # error ("VG_TRC_CHAIN_ME_TO_FAST_EP is > 128");
210 moveli r12, VG_TRC_CHAIN_ME_TO_FAST_EP
212 /* 32 = mkLoadImm_EXACTLY4
218 /* ------ Indirect but boring jump ------ */
219 .global VG_(disp_cp_xindir)
221 /* Where are we going? */
222 addli r11, r50, OFFSET_tilegx_pc
225 moveli r7, hw2_last(VG_(stats__n_xindirs_32))
226 shl16insli r7, r7, hw1(VG_(stats__n_xindirs_32))
227 shl16insli r7, r7, hw0(VG_(stats__n_xindirs_32))
232 /* try a fast lookup in the translation cache */
233 /* r14 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
234 = (t8 >> 3 & VG_TT_FAST_MASK) << 3 */
237 /* Assume VG_TT_FAST_MASK < 4G */
238 moveli r12, hw1(VG_TT_FAST_MASK)
239 shl16insli r12, r12, hw0(VG_TT_FAST_MASK)
243 /* Note, each tt_fast hash entry has two pointers i.e. 16 Bytes. */
245 /* r13 = (addr of VG_(tt_fast)) + r14 */
246 moveli r13, hw2_last(VG_(tt_fast))
247 shl16insli r13, r13, hw1(VG_(tt_fast))
248 shl16insli r13, r13, hw0(VG_(tt_fast))
252 /* r12 = VG_(tt_fast)[hash] :: ULong* */
260 bnez r7, fast_lookup_failed
262 /* Run the translation */
268 /* %PC is up to date */
269 /* back out decrement of the dispatch counter */
270 /* hold dispatch_ctr in t0 (r8) */
272 moveli r7, hw2_last(VG_(stats__n_xindir_misses_32))
273 shl16insli r7, r7, hw1(VG_(stats__n_xindir_misses_32))
274 shl16insli r7, r7, hw0(VG_(stats__n_xindir_misses_32))
278 moveli r12, VG_TRC_INNER_FASTMISS
282 /* ------ Assisted jump ------ */
283 .global VG_(disp_cp_xassisted)
284 VG_(disp_cp_xassisted):
285 /* guest-state-pointer contains the TRC. Put the value into the
291 /* ------ Event check failed ------ */
292 .global VG_(disp_cp_evcheck_fail)
293 VG_(disp_cp_evcheck_fail):
294 moveli r12, VG_TRC_INNER_COUNTERZERO
298 .size VG_(disp_run_translations), .-VG_(disp_run_translations)
301 /* Let the linker know we do not need an executable stack */
302 .section .note.GNU-stack,"",@progbits
304 #endif /* defined(VGP_tilegx_linux) */
305 /*--------------------------------------------------------------------*/
307 /*--------------------------------------------------------------------*/