1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- The core dispatch loop, for jumping to a code address.       ---*/
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---                                       dispatch-s390x-linux.S ---*/
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  This file is part of Valgrind, a dynamic binary instrumentation
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  framework.
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  Copyright IBM Corp. 2010-2011
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  This program is free software; you can redistribute it and/or
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  modify it under the terms of the GNU General Public License as
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  published by the Free Software Foundation; either version 2 of the
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  License, or (at your option) any later version.
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  This program is distributed in the hope that it will be useful, but
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  WITHOUT ANY WARRANTY; without even the implied warranty of
20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  General Public License for more details.
22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  You should have received a copy of the GNU General Public License
24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  along with this program; if not, write to the Free Software
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  02111-1307, USA.
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  The GNU General Public License is contained in the file COPYING.
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Contributed by Florian Krohm and Christian Borntraeger */
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_basics_asm.h"
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_dispatch_asm.h"
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_transtab_asm.h"
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "libvex_guest_offsets.h"
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "libvex_s390x_common.h"
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGA_s390x)
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---                                                      ---*/
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- The dispatch loop.  VG_(run_innerloop) is used to    ---*/
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- run all translations except no-redir ones.           ---*/
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---                                                      ---*/
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Convenience definitions for readability */
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef  SP
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP S390_REGNO_STACK_POINTER
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef  LR
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define LR S390_REGNO_LINK_REGISTER
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Location of valgrind's saved FPC register */
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define S390_LOC_SAVED_FPC_V S390_OFFSET_SAVED_FPC_V(SP)
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Location of saved guest state pointer */
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define S390_LOC_SAVED_GSP S390_OFFSET_SAVED_GSP(SP)
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Location of saved R2 register */
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define S390_LOC_SAVED_R2 S390_OFFSET_SAVED_R2(SP)
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------*/
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- Preamble (set everything up)                 ---*/
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------*/
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* signature:
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.text
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.align   4
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.globl VG_(run_innerloop)
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVG_(run_innerloop):
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* r2 holds address of guest_state */
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* r3 holds do_profiling (a flag) */
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Save gprs   ABI: r6...r13 and r15 */
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        stmg %r6,%r15,48(SP)
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* New stack frame */
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        aghi SP,-S390_INNERLOOP_FRAME_SIZE
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Save fprs:   ABI: f8...f15 */
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f8,160+0(SP)
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f9,160+8(SP)
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f10,160+16(SP)
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f11,160+24(SP)
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f12,160+32(SP)
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f13,160+40(SP)
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f14,160+48(SP)
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f15,160+56(SP)
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Load address of guest state into guest state register (r13) */
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lgr  %r13,%r2
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Store address of guest state pointer on stack.
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           It will be needed later because upon return from a VEX translation
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           r13 may contain a special value. So the old value will be used to
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           determine whether r13 contains a special value. */
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        stg  %r13,S390_LOC_SAVED_GSP
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Save valgrind's FPC on stack so run_innerloop_exit can restore
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           it later . */
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        stfpc S390_LOC_SAVED_FPC_V
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Load the FPC the way the client code wants it. I.e. pull the
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           value from the guest state.
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lfpc OFFSET_s390x_fpc(%r13)
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Get the IA from the guest state */
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lg   %r2,OFFSET_s390x_IA(%r13)
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Get VG_(dispatch_ctr) -- a 32-bit value -- and store it in a reg */
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        larl %r6,VG_(dispatch_ctr)
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        l    S390_REGNO_DISPATCH_CTR,0(%r6)
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Fall into main loop (the right one) */
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* r3 = 1 --> do_profiling. We may trash r3 later on. That's OK,
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           because it's a volatile register (does not need to be preserved). */
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ltgr %r3,%r3
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        je   run_innerloop__dispatch_unprofiled
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        j    run_innerloop__dispatch_profiled
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------*/
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- NO-PROFILING (standard) dispatcher           ---*/
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------*/
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovrun_innerloop__dispatch_unprofiled:
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Load the link register with the address the jitted code will
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           return to when it's done executing. The link register is loaded
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           exactly once per loop. This is safe, because the jitted code
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           cannot possibly modify the LR. How else would it be able to return
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           to the location in the LR otherwise? */
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        basr LR,0
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Loop begins here */
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* This is the story:
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           r2  = IA = next guest address
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           r12 = VG_(dispatch_ctr)
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           r13 = guest state pointer or (upon return from guest code) some
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 special value
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           r15 = stack pointer (as usual)
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        */
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovinnermost_loop:
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Has the guest state pointer been messed with? If yes, exit.
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           The mess is recognised by r13 containing an odd value. */
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        tmll %r13,1
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        jne  gsp_changed
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Save the jump address in the guest state */
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        stg  %r2,OFFSET_s390x_IA(%r13)
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* Try a fast lookup in the translation cache:
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           Compute offset (not index) into VT_(tt_fast):
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           offset = VG_TT_FAST_HASH(addr) * sizeof(FastCacheEntry)
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           with VG_TT_FAST_HASH(addr) == (addr >> 1) & VG_TT_FAST_MASK
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           and  sizeof(FastCacheEntry) == 16
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           offset = ((addr >> 1) & VG_TT_FAST_MASK) << 4
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           which is
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           offset = ((addr & (VG_TT_FAST_MASK << 1) ) << 3
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        */
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        larl  %r8, VG_(tt_fast)
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        llill %r5,( VG_TT_FAST_MASK << 1) & 0xffff
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if ((( VG_TT_FAST_MASK << 1) & 0xffff0000) >> 16 != 0)
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        iilh %r5,(( VG_TT_FAST_MASK << 1) & 0xffff0000) >> 16
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ngr  %r5,%r2
177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        sllg %r7,%r5,3
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* Are we out of timeslice?  If yes, defer to scheduler. */
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ahi  S390_REGNO_DISPATCH_CTR,-1
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        jz   counter_is_zero
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lg   %r11, 8(%r8,%r7)      /* .host */
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        cg   %r2,  0(%r8,%r7)      /* next guest address == .guest ? */
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        jne  fast_lookup_failed
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Found a match.  Call .host.
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           r11 is an address. There we will find the instrumented client code.
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           That code may modify the guest state register r13. The client code
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           will return to the beginning of this loop start by issuing br LR.
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           We can simply branch to the host code */
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        br %r11
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------*/
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- PROFILING dispatcher (can be much slower)    ---*/
197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------*/
198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovrun_innerloop__dispatch_profiled:
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        stg  %r2,S390_LOC_SAVED_R2
201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Load the link register with the address the jitted code will
203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           return to when it's done executing. */
204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        bras LR,innermost_loop
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Jitted code returns here. Update profile counter for previous IA */
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        llill %r5,( VG_TT_FAST_MASK << 1) & 0xffff
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if ((( VG_TT_FAST_MASK << 1) & 0xffff0000) >> 16 != 0)
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        iilh %r5,(( VG_TT_FAST_MASK << 1) & 0xffff0000) >> 16
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ng   %r5,S390_LOC_SAVED_R2
213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        sllg %r7,%r5,2
214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Increment bb profile counter */
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        larl %r8, VG_(tt_fastN)
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lg   %r9,0(%r8,%r7)
218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        l    %r10,0(%r9)
219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ahi  %r10,1
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        st   %r10,0(%r9)
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        j    run_innerloop__dispatch_profiled
223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------*/
225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- exit points                                  ---*/
226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------*/
227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovgsp_changed:
229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* Someone messed with the gsp (in r13).  Have to
230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           defer to scheduler to resolve this.  The register
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           holding VG_(dispatch_ctr) is not yet decremented,
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           so no need to increment. */
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Update the IA in the guest state */
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lg  %r6,S390_LOC_SAVED_GSP       /* r6 = original guest state pointer */
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        stg %r2,OFFSET_s390x_IA(%r6)
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Return the special guest state pointer value */
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lgr %r2, %r13
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	j   run_innerloop_exit
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovcounter_is_zero:
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* IA is up to date */
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* Back out decrement of the dispatch counter */
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ahi S390_REGNO_DISPATCH_CTR,1
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Set return value for the scheduler */
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lghi %r2,VG_TRC_INNER_COUNTERZERO
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        j    run_innerloop_exit
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovfast_lookup_failed:
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* IA is up to date */
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* Back out decrement of the dispatch counter */
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ahi S390_REGNO_DISPATCH_CTR,1
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Set return value for the scheduler */
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lghi %r2,VG_TRC_INNER_FASTMISS
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        j    run_innerloop_exit
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* All exits from the dispatcher go through here.
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           When we come here r2 holds the return value. */
267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovrun_innerloop_exit:
268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* Restore valgrind's FPC, as client code may have changed it. */
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lfpc S390_LOC_SAVED_FPC_V
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Write ctr to VG_(dispatch_ctr) (=32bit value) */
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        larl %r6,VG_(dispatch_ctr)
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        st   S390_REGNO_DISPATCH_CTR,0(%r6)
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Restore callee-saved registers... */
277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Floating-point regs */
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f8,160+0(SP)
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f9,160+8(SP)
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f10,160+16(SP)
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f11,160+24(SP)
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f12,160+32(SP)
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f13,160+40(SP)
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f14,160+48(SP)
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f15,160+56(SP)
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Remove atack frame */
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        aghi SP,S390_INNERLOOP_FRAME_SIZE
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* General-purpose regs. This also restores the original link
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           register (r14) and stack pointer (r15). */
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lmg %r6,%r15,48(SP)
294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Return */
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        br  LR
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---                                                      ---*/
300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- A special dispatcher, for running no-redir           ---*/
301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- translations.  Just runs the given translation once. ---*/
302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---                                                      ---*/
303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* signature:
306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid VG_(run_a_noredir_translation) ( UWord* argblock );
307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Run a no-redir translation.  argblock points to 4 UWords, 2 to carry args
310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   and 2 to carry results:
311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      0: input:  ptr to translation
312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      1: input:  ptr to guest state
313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      2: output: next guest PC
314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      3: output: guest state pointer afterwards (== thread return code)
315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.text
317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.align   4
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.globl VG_(run_a_noredir_translation)
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVG_(run_a_noredir_translation):
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        stmg %r6,%r15,48(SP)
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        aghi SP,-S390_INNERLOOP_FRAME_SIZE
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f8,160+0(SP)
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f9,160+8(SP)
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f10,160+16(SP)
325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f11,160+24(SP)
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f12,160+32(SP)
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f13,160+40(SP)
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f14,160+48(SP)
329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        std  %f15,160+56(SP)
330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Load address of guest state into guest state register (r13) */
332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lg   %r13,8(%r2)
333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Get the IA */
335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lg   %r11,0(%r2)
336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* save r2 (argblock) as it is clobbered */
338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	stg  %r2,160+64(SP)
339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* the call itself */
341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        basr LR,%r11
342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* restore argblock */
344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg   %r1,160+64(SP)
345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* save the next guest PC */
346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	stg  %r2,16(%r1)
347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* save the guest state */
349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	stg  %r13,24(%r1)
350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        /* Restore Floating-point regs */
352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f8,160+0(SP)
353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f9,160+8(SP)
354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f10,160+16(SP)
355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f11,160+24(SP)
356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f12,160+32(SP)
357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f13,160+40(SP)
358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f14,160+48(SP)
359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ld  %f15,160+56(SP)
360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        aghi SP,S390_INNERLOOP_FRAME_SIZE
362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        lmg %r6,%r15,48(SP)
364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	br  %r14
365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Let the linker know we don't need an executable stack */
368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.section .note.GNU-stack,"",@progbits
369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* VGA_s390x */
371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- end                                   dispatch-s390x-linux.S ---*/
374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
375