1
2/*--------------------------------------------------------------------*/
3/*--- begin                                dispatch-tilegx-linux.S ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7  This file is part of Valgrind, a dynamic binary instrumentation
8  framework.
9
10  Copyright (C) 2010-2013  Tilera Corp.
11
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.
16
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.
21
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
25  02111-1307, USA.
26
27  The GNU General Public License is contained in the file COPYING.
28*/
29
30/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
31
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 */
37
38        /*------------------------------------------------------------*/
39        /*---                                                      ---*/
40        /*--- The dispatch loop.  VG_(run_innerloop) is used to    ---*/
41        /*--- run all translations except no-redir ones.           ---*/
42        /*---                                                      ---*/
43        /*------------------------------------------------------------*/
44
45        /*----------------------------------------------------*/
46        /*--- Preamble (set everything up)                 ---*/
47        /*----------------------------------------------------*/
48
49        /* signature:
50        void VG_(disp_run_translations)(UWord* two_words,
51        void*  guest_state,
52        Addr   host_addr );
53        UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
54        */
55
56        .text
57        .globl  VG_(disp_run_translations)
58        VG_(disp_run_translations):
59
60        /* r0 holds two_words
61           r1 holds guest_state
62           r2 holds host_addr */
63
64        /* New stack frame */
65        addli sp, sp, -256
66        addi  r29, sp, 8
67        /*
68        high memory of stack
69        216  lr
70        208  r53
71        200  r52
72        192  r51
73        ...
74        48   r33
75        40   r32
76        32   r31
77        24   r30
78        16   r1 <---
79        8    r0
80        0       <-sp
81        */
82        st_add r29, r0, 8
83        st_add r29, r1, 8
84
85        /* ... and r30 - r53 */
86        st_add  r29, r30, 8
87        st_add  r29, r31, 8
88        st_add  r29, r32, 8
89        st_add  r29, r33, 8
90        st_add  r29, r34, 8
91        st_add  r29, r35, 8
92        st_add  r29, r36, 8
93        st_add  r29, r37, 8
94        st_add  r29, r38, 8
95        st_add  r29, r39, 8
96        st_add  r29, r40, 8
97        st_add  r29, r41, 8
98        st_add  r29, r42, 8
99        st_add  r29, r43, 8
100        st_add  r29, r44, 8
101        st_add  r29, r45, 8
102        st_add  r29, r46, 8
103        st_add  r29, r47, 8
104        st_add  r29, r48, 8
105        st_add  r29, r49, 8
106        st_add  r29, r50, 8
107        st_add  r29, r51, 8
108        st_add  r29, r52, 8
109        st_add  r29, r53, 8
110        st      r29, lr
111
112        /* Load the address of guest state into guest state register r50. */
113        move r50, r1
114
115        //j postamble
116
117        /* jump to the code cache. */
118        jr  r2
119        /*NOTREACHED*/
120
121
122       /*----------------------------------------------------*/
123       /*--- Postamble and exit.                          ---*/
124       /*----------------------------------------------------*/
125
126postamble:
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.) */
132
133        /* run_innerloop_exit_REALLY:
134        r50 holds VG_TRC_* value to return
135        Return to parent stack
136        addli  sp, sp, 256 */
137
138        addi r29, sp, 8
139
140        /* Restore r0 from stack; holding address of twp words */
141        ld_add  r0, r29, 16
142        /* store r12 in two_words[0] */
143        st_add  r0, r12, 8
144        /* store r13 in two_words[1] */
145        st  r0, r13
146
147        /* Restore callee-saved registers... */
148        ld_add  r30, r29, 8
149        ld_add  r31, r29, 8
150        ld_add  r32, r29, 8
151        ld_add  r33, r29, 8
152        ld_add  r34, r29, 8
153        ld_add  r35, r29, 8
154        ld_add  r36, r29, 8
155        ld_add  r37, r29, 8
156        ld_add  r38, r29, 8
157        ld_add  r39, r29, 8
158        ld_add  r40, r29, 8
159        ld_add  r41, r29, 8
160        ld_add  r42, r29, 8
161        ld_add  r43, r29, 8
162        ld_add  r44, r29, 8
163        ld_add  r45, r29, 8
164        ld_add  r46, r29, 8
165        ld_add  r47, r29, 8
166        ld_add  r48, r29, 8
167        ld_add  r49, r29, 8
168        ld_add  r50, r29, 8
169        ld_add  r51, r29, 8
170        ld_add  r52, r29, 8
171        ld_add  r53, r29, 8
172        ld      lr, r29
173        addli   sp, sp, 256   /* stack_size */
174        jr      lr
175        nop
176
177
178       /*----------------------------------------------------*/
179       /*---           Continuation points                ---*/
180       /*----------------------------------------------------*/
181
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");
191        # endif
192        moveli r12, VG_TRC_CHAIN_ME_TO_SLOW_EP
193        move   r13, lr
194        /* 32 = mkLoadImm_EXACTLY4
195        8 = jalr r9
196        8 = nop */
197        addi   r13, r13, -40
198        j      postamble
199
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");
209        # endif
210        moveli r12, VG_TRC_CHAIN_ME_TO_FAST_EP
211        move   r13, lr
212        /* 32 = mkLoadImm_EXACTLY4
213        8 = jalr r9
214        8 = nop */
215        addi   r13, r13, -40
216        j      postamble
217
218        /* ------ Indirect but boring jump ------ */
219        .global VG_(disp_cp_xindir)
220        VG_(disp_cp_xindir):
221        /* Where are we going? */
222        addli    r11, r50, OFFSET_tilegx_pc
223        ld       r11, r11
224
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))
228        ld4u   r6, r7
229        addi   r6, r6, 1
230        st4    r7, r6
231
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 */
235
236        move    r14, r11
237        /* Assume VG_TT_FAST_MASK < 4G */
238        moveli  r12, hw1(VG_TT_FAST_MASK)
239        shl16insli r12, r12, hw0(VG_TT_FAST_MASK)
240        shrui   r14, r14, 3
241        and     r14, r14, r12
242        shli    r14, r14, 4
243        /* Note, each tt_fast hash entry has two pointers i.e. 16 Bytes. */
244
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))
249
250        add     r13, r13, r14
251
252        /* r12 = VG_(tt_fast)[hash] :: ULong* */
253        ld_add  r12, r13, 8
254
255        {
256        ld      r25, r13
257        sub     r7, r12, r11
258        }
259
260        bnez     r7, fast_lookup_failed
261
262        /* Run the translation */
263        jr      r25
264
265        .quad   0x0
266
267fast_lookup_failed:
268        /* %PC is up to date */
269        /* back out decrement of the dispatch counter */
270        /* hold dispatch_ctr in t0 (r8) */
271
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))
275        ld4u  r6, r7
276        addi  r6, r6, 1
277        st4   r7, r6
278        moveli  r12, VG_TRC_INNER_FASTMISS
279        movei   r13, 0
280        j       postamble
281
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
286        return register */
287        move    r12, r50
288        movei   r13, 0
289        j       postamble
290
291        /* ------ Event check failed ------ */
292        .global VG_(disp_cp_evcheck_fail)
293        VG_(disp_cp_evcheck_fail):
294        moveli  r12, VG_TRC_INNER_COUNTERZERO
295        movei   r13, 0
296        j       postamble
297
298        .size VG_(disp_run_translations), .-VG_(disp_run_translations)
299
300
301        /* Let the linker know we do not need an executable stack */
302        .section .note.GNU-stack,"",@progbits
303
304#endif /* defined(VGP_tilegx_linux) */
305/*--------------------------------------------------------------------*/
306/*--- end                                                          ---*/
307/*--------------------------------------------------------------------*/
308
309