1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* HOW TO USE
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov13 Dec '05 - Linker no longer used (apart from mymalloc)
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovSimply compile and link switchback.c with test_xxx.c,
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanove.g. for ppc64:
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov$ (cd .. && make EXTRA_CFLAGS="-m64" libvex_ppc64_linux.a) && gcc -m64 -mregnames -Wall -Wshadow -Wno-long-long -Winline -O -g -o switchback switchback.c linker.c ../libvex_ppc64_linux.a test_xxx.c
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovTest file test_xxx.c must have an entry point called "entry",
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovwhich expects to take a single argument which is a function pointer
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov(to "serviceFn").
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovTest file may not reference any other symbols.
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovNOTE: POWERPC: it is critical, when using this on ppc, to set
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovCacheLineSize to the right value.  Values we currently know of:
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   imac (G3):   32
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   G5 (ppc970): 128
20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARM64:
22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  (cd .. && make -f Makefile-gcc libvex-arm64-linux.a) \
23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     && $CC -Wall -O -g -o switchback switchback.c linker.c \
24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     ../libvex-arm64-linux.a test_emfloat.c
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h>
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <assert.h>
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdlib.h>
30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <string.h>
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/types.h>
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/stat.h>
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <unistd.h>
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_basictypes.h"
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_guest_x86.h"
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_guest_amd64.h"
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_guest_ppc32.h"
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_guest_ppc64.h"
40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "../pub/libvex_guest_arm64.h"
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex.h"
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_trc_values.h"
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "linker.h"
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong n_bbs_done = 0;
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Int   n_translations_made = 0;
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__i386__)
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define VexGuestState             VexGuestX86State
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define LibVEX_Guest_initialise   LibVEX_GuestX86_initialise
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define VexArch                   VexArchX86
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define VexSubArch                VexSubArchX86_sse1
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define GuestPC                   guest_EIP
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define CacheLineSize             0/*irrelevant*/
56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(__aarch64__) && !defined(__arm__)
58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  define VexGuestState             VexGuestARM64State
59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  define LibVEX_Guest_initialise   LibVEX_GuestARM64_initialise
60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  define VexArch                   VexArchARM64
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define VexSubArch                VexSubArch_NONE
62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  define GuestPC                   guest_PC
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define CacheLineSize             0/*irrelevant*/
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   error "Unknown arch"
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 7: show conversion into IR */
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 6: show after initial opt */
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 5: show after instrumentation */
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 4: show after second opt */
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 3: show after tree building */
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 2: show selected insns */
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 1: show after reg-alloc */
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 0: show final assembly */
77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define TEST_FLAGS ((1<<7)|(1<<3)|(1<<2)|(1<<1)|(1<<0))
78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define DEBUG_TRACE_FLAGS ((0<<7)|(0<<6)|(0<<5)|(0<<4)| \
79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                           (0<<3)|(0<<2)|(0<<1)|(0<<0))
80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef  unsigned long int  Addr;
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* guest state */
85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong gstack[64000] __attribute__((aligned(16)));
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVexGuestState gst;
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVexControl vcon;
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* only used for the switchback transition */
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* i386:  helper1 = &gst, helper2 = %EFLAGS */
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* amd64: helper1 = &gst, helper2 = %EFLAGS */
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ppc32: helper1 = &gst, helper2 = %CR, helper3 = %XER */
93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* arm64: helper1 = &gst, helper2 = 32x0:NZCV:28x0 */
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHWord sb_helper1 = 0;
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHWord sb_helper2 = 0;
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHWord sb_helper3 = 0;
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* translation cache */
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define N_TRANS_CACHE 1000000
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define N_TRANS_TABLE 10000
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovULong trans_cache[N_TRANS_CACHE];
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVexGuestExtents trans_table [N_TRANS_TABLE];
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovULong*          trans_tableP[N_TRANS_TABLE];
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt trans_cache_used = 0;
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt trans_table_used = 0;
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool chase_into_ok ( void* opaque, Addr64 dst ) {
110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return False;
111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic UInt needs_self_check ( void* opaque, VexGuestExtents* vge ) {
114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return 0;
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* For providing services. */
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic HWord serviceFn ( HWord arg1, HWord arg2 )
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   switch (arg1) {
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 0: /* EXIT */
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         printf("---STOP---\n");
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         printf("serviceFn:EXIT\n");
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	 printf("%llu bbs simulated\n", n_bbs_done);
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	 printf("%d translations made, %d tt bytes\n",
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                n_translations_made, 8*trans_cache_used);
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         exit(0);
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 1: /* PUTC */
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         putchar(arg2);
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return 0;
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 2: /* MALLOC */
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return (HWord)malloc(arg2);
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 3: /* FREE */
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         free((void*)arg2);
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return 0;
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      default:
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         assert(0);
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// needed for arm64 ?
144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void invalidate_icache(void *ptr, unsigned long nbytes)
145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // This function, invalidate_icache, for arm64_linux,
147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // is copied from
148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // https://github.com/armvixl/vixl/blob/master/src/a64/cpu-a64.cc
149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // which has the following copyright notice:
150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /*
151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Copyright 2013, ARM Limited
152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   All rights reserved.
153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Redistribution and use in source and binary forms, with or without
155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   modification, are permitted provided that the following conditions are met:
156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   * Redistributions of source code must retain the above copyright notice,
158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     this list of conditions and the following disclaimer.
159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   * Redistributions in binary form must reproduce the above copyright notice,
160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     this list of conditions and the following disclaimer in the documentation
161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     and/or other materials provided with the distribution.
162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   * Neither the name of ARM Limited nor the names of its contributors may be
163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     used to endorse or promote products derived from this software without
164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     specific prior written permission.
165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   */
177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Ask what the I and D line sizes are
179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UInt cache_type_register;
180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Copy the content of the cache type register to a core register.
181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   __asm__ __volatile__ ("mrs %[ctr], ctr_el0" // NOLINT
182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         : [ctr] "=r" (cache_type_register));
183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const Int kDCacheLineSizeShift = 16;
185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const Int kICacheLineSizeShift = 0;
186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const UInt kDCacheLineSizeMask = 0xf << kDCacheLineSizeShift;
187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const UInt kICacheLineSizeMask = 0xf << kICacheLineSizeShift;
188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // The cache type register holds the size of the I and D caches as a power of
190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // two.
191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const UInt dcache_line_size_power_of_two =
192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov       (cache_type_register & kDCacheLineSizeMask) >> kDCacheLineSizeShift;
193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const UInt icache_line_size_power_of_two =
194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov       (cache_type_register & kICacheLineSizeMask) >> kICacheLineSizeShift;
195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const UInt dcache_line_size_ = 1 << dcache_line_size_power_of_two;
197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const UInt icache_line_size_ = 1 << icache_line_size_power_of_two;
198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Addr start = (Addr)ptr;
200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Sizes will be used to generate a mask big enough to cover a pointer.
201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Addr dsize = (Addr)dcache_line_size_;
202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Addr isize = (Addr)icache_line_size_;
203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Cache line sizes are always a power of 2.
205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Addr dstart = start & ~(dsize - 1);
206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Addr istart = start & ~(isize - 1);
207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Addr end    = start + nbytes;
208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   __asm__ __volatile__ (
210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // Clean every line of the D cache containing the target data.
211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "0: \n\t"
212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // dc : Data Cache maintenance
213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // c : Clean
214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // va : by (Virtual) Address
215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // u : to the point of Unification
216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // The point of unification for a processor is the point by which the
217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // instruction and data caches are guaranteed to see the same copy of a
218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // memory location. See ARM DDI 0406B page B2-12 for more information.
219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "dc cvau, %[dline] \n\t"
220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "add %[dline], %[dline], %[dsize] \n\t"
221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "cmp %[dline], %[end] \n\t"
222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "b.lt 0b \n\t"
223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // Barrier to make sure the effect of the code above is visible to the rest
224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // of the world.
225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // dsb : Data Synchronisation Barrier
226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // ish : Inner SHareable domain
227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // The point of unification for an Inner Shareable shareability domain is
228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // the point by which the instruction and data caches of all the processors
229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // in that Inner Shareable shareability domain are guaranteed to see the
230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // same copy of a memory location. See ARM DDI 0406B page B2-12 for more
231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // information.
232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "dsb ish \n\t"
233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // Invalidate every line of the I cache containing the target data.
234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "1: \n\t"
235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // ic : instruction cache maintenance
236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // i : invalidate
237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // va : by address
238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // u : to the point of unification
239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "ic ivau, %[iline] \n\t"
240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "add %[iline], %[iline], %[isize] \n\t"
241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "cmp %[iline], %[end] \n\t"
242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "b.lt 1b \n\t"
243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // Barrier to make sure the effect of the code above is visible to the rest
244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // of the world.
245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "dsb ish \n\t"
246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // Barrier to ensure any prefetching which happened before this code is
247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // discarded.
248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // isb : Instruction Synchronisation Barrier
249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     "isb \n\t"
250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     : [dline] "+r" (dstart),
251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov       [iline] "+r" (istart)
252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     : [dsize] "r" (dsize),
253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov       [isize] "r" (isize),
254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov       [end] "r" (end)
255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // This code does not write to memory but without the dependency gcc might
256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     // move this code before the code is generated.
257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     : "cc", "memory"
258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   );
259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* -------------------- */
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* continue execution on the real CPU (never returns) */
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__i386__)
267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void switchback_asm(void);
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovasm(
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"switchback_asm:\n"
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl sb_helper1, %eax\n"  // eax = guest state ptr
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl  16(%eax), %esp\n"   // switch stacks
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   pushl 56(%eax)\n"         // push continuation addr
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl sb_helper2, %ebx\n"  // get eflags
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   pushl %ebx\n"             // eflags:CA
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   pushl 0(%eax)\n"          //  EAX:eflags:CA
277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl 4(%eax), %ecx\n"
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl 8(%eax), %edx\n"
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl 12(%eax), %ebx\n"
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl 20(%eax), %ebp\n"
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl 24(%eax), %esi\n"
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl 28(%eax), %edi\n"
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   popl %eax\n"
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   popfl\n"
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   ret\n"
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov);
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid switchback ( void )
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sb_helper1 = (HWord)&gst;
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sb_helper2 = LibVEX_GuestX86_get_eflags(&gst);
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   switchback_asm(); // never returns
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(__aarch64__)
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void switchback_asm(HWord x0_gst, HWord x1_pstate);
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovasm(
298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"switchback_asm:"
299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   mrs x30, nzcv"  "\n"
300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   and x30, x30, #0xFFFFFFFF0FFFFFFF"  "\n"
301436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   and x1,  x1,  #0x00000000F0000000"  "\n"
302436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   orr x30, x30, x1"  "\n"
303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   msr nzcv, x30"  "\n"
304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x30, [x0, #16 + 8*37]"  "\n"
306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   msr tpidr_el0, x30"  "\n"
307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x30, [x0, #16 + 8*31]"  "\n"
309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   mov sp,  x30"  "\n"
310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   add x30, x0, #(16 + 8*38 + 16*0)"  "\n"
312436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q0,  [x30], #16"   "\n"
313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q1,  [x30], #16"   "\n"
314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q2,  [x30], #16"   "\n"
315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q3,  [x30], #16"   "\n"
316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q4,  [x30], #16"   "\n"
317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q5,  [x30], #16"   "\n"
318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q6,  [x30], #16"   "\n"
319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q7,  [x30], #16"   "\n"
320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q8,  [x30], #16"   "\n"
321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q9,  [x30], #16"   "\n"
322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q10, [x30], #16"   "\n"
323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q11, [x30], #16"   "\n"
324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q12, [x30], #16"   "\n"
325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q13, [x30], #16"   "\n"
326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q14, [x30], #16"   "\n"
327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q15, [x30], #16"   "\n"
328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q16, [x30], #16"   "\n"
329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q17, [x30], #16"   "\n"
330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q18, [x30], #16"   "\n"
331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q19, [x30], #16"   "\n"
332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q20, [x30], #16"   "\n"
333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q21, [x30], #16"   "\n"
334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q22, [x30], #16"   "\n"
335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q23, [x30], #16"   "\n"
336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q24, [x30], #16"   "\n"
337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q25, [x30], #16"   "\n"
338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q26, [x30], #16"   "\n"
339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q27, [x30], #16"   "\n"
340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q28, [x30], #16"   "\n"
341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q29, [x30], #16"   "\n"
342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q30, [x30], #16"   "\n"
343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr q31, [x30], #16"   "\n"
344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x30, [x0, #16+8*30]"  "\n"
346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x29, [x0, #16+8*29]"  "\n"
347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x28, [x0, #16+8*28]"  "\n"
348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x27, [x0, #16+8*27]"  "\n"
349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x26, [x0, #16+8*26]"  "\n"
350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x25, [x0, #16+8*25]"  "\n"
351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x24, [x0, #16+8*24]"  "\n"
352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x23, [x0, #16+8*23]"  "\n"
353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x22, [x0, #16+8*22]"  "\n"
354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x21, [x0, #16+8*21]"  "\n"
355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x20, [x0, #16+8*20]"  "\n"
356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x19, [x0, #16+8*19]"  "\n"
357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x18, [x0, #16+8*18]"  "\n"
358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x17, [x0, #16+8*17]"  "\n"
359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x16, [x0, #16+8*16]"  "\n"
360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x15, [x0, #16+8*15]"  "\n"
361436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x14, [x0, #16+8*14]"  "\n"
362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x13, [x0, #16+8*13]"  "\n"
363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x12, [x0, #16+8*12]"  "\n"
364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x11, [x0, #16+8*11]"  "\n"
365436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x10, [x0, #16+8*10]"  "\n"
366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x9,  [x0, #16+8*9]"   "\n"
367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x8,  [x0, #16+8*8]"   "\n"
368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x7,  [x0, #16+8*7]"   "\n"
369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x6,  [x0, #16+8*6]"   "\n"
370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x5,  [x0, #16+8*5]"   "\n"
371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x4,  [x0, #16+8*4]"   "\n"
372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x3,  [x0, #16+8*3]"   "\n"
373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x2,  [x0, #16+8*2]"   "\n"
374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x1,  [x0, #16+8*1]"   "\n"
375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr x0,  [x0, #16+8*0]"   "\n"
376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"nop_start_point:"            "\n"
378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   nop"  "\n" // this will be converted into a relative jump
379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"nop_end_point:"              "\n"
380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov);
381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void nop_start_point(void);
383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void nop_end_point(void);
384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid switchback ( void )
386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  assert(offsetof(VexGuestARM64State, guest_X0)  == 16 + 8*0);
388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  assert(offsetof(VexGuestARM64State, guest_X30) == 16 + 8*30);
389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  assert(offsetof(VexGuestARM64State, guest_SP)  == 16 + 8*31);
390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  assert(offsetof(VexGuestARM64State, guest_TPIDR_EL0) == 16 + 8*37);
391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  assert(offsetof(VexGuestARM64State, guest_Q0)  == 16 + 8*38 + 16*0);
392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  HWord arg0 = (HWord)&gst;
394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  HWord arg1 = LibVEX_GuestARM64_get_nzcv(&gst);
395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  /* Copy the entire switchback_asm procedure into writable and
397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     executable memory. */
398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  UChar* sa_start     = (UChar*)&switchback_asm;
400436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  UChar* sa_nop_start = (UChar*)&nop_start_point;
401436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  UChar* sa_end       = (UChar*)&nop_end_point;
402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  Int i;
404436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  Int nbytes       = sa_end - sa_start;
405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  Int off_nopstart = sa_nop_start - sa_start;
406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  if (0)
407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     printf("nbytes = %d, nopstart = %d\n", nbytes, off_nopstart);
408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* copy it into mallocville */
410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UChar* copy = mymalloc(nbytes);
411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   assert(copy);
412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (i = 0; i < nbytes; i++)
413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      copy[i] = sa_start[i];
414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt* p = (UInt*)(&copy[off_nopstart]);
416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Addr64 addr_of_nop = (Addr64)p;
418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Addr64 where_to_go = gst.guest_PC;
419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Long   diff = ((Long)where_to_go) - ((Long)addr_of_nop);
420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
421436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (0) {
422436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     printf("addr of first nop = 0x%llx\n", addr_of_nop);
423436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     printf("where to go       = 0x%llx\n", where_to_go);
424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     printf("diff = 0x%llx\n", diff);
425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (diff < -0x8000000LL || diff >= 0x8000000LL) {
428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     // we're hosed.  Give up
429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     printf("hosed -- offset too large\n");
430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     assert(0);
431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* stay sane ... */
434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(p[0] == 0xd503201f); /* nop */
435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* branch to diff */
437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   p[0] = 0x14000000 | ((diff >> 2) & 0x3FFFFFF);
438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   invalidate_icache( copy, nbytes );
440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   ( (void(*)(HWord,HWord))copy )(arg0, arg1);
442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else
445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# error "Unknown plat"
446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* -------------------- */
451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// f    holds is the host code address
452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// gp   holds the guest state pointer to use
453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// res  is to hold the result.  Or some such.
454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic HWord block[2]; // f, gp;
455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern HWord run_translation_asm(void);
456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void disp_chain_assisted(void);
458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined(__aarch64__)
460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovasm(
461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"run_translation_asm:"            "\n"
462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   stp  x29, x30, [sp, #-16]!"   "\n"
463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   stp  x27, x28, [sp, #-16]!"   "\n"
464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   stp  x25, x26, [sp, #-16]!"   "\n"
465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   stp  x23, x24, [sp, #-16]!"   "\n"
466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   stp  x21, x22, [sp, #-16]!"   "\n"
467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   stp  x19, x20, [sp, #-16]!"   "\n"
468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   stp  x0,  xzr, [sp, #-16]!"   "\n"
469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   adrp x0, block"               "\n"
470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   add  x0, x0, :lo12:block"     "\n"
471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr  x21, [x0, #8]"           "\n"  // load GSP
472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldr  x1,  [x0, #0]"           "\n"  // Host address
473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   br   x1"                 "\n"  // go (we wind up at disp_chain_assisted)
474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"disp_chain_assisted:"            "\n" // x21 holds the trc.  Return it.
476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   mov  x1, x21" "\n"
477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    /* Restore int regs, but not x1. */
478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldp  x0,  xzr, [sp], #16"    "\n"
479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldp  x19, x20, [sp], #16"    "\n"
480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldp  x21, x22, [sp], #16"    "\n"
481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldp  x23, x24, [sp], #16"    "\n"
482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldp  x25, x26, [sp], #16"    "\n"
483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldp  x27, x28, [sp], #16"    "\n"
484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ldp  x29, x30, [sp], #16"    "\n"
485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   mov  x0, x1"                 "\n"
486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"   ret"                         "\n"
487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov);
488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(__i386__)
490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovasm(
492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"run_translation_asm:\n"
493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   pushal\n"
494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl gp, %ebp\n"
495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl f, %eax\n"
496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   call *%eax\n"
497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   movl %eax, res\n"
498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   popal\n"
499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   ret\n"
500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov);
501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else
503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# error "Unknown arch"
504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Run a translation at host address 'translation' and return the TRC.
508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
509436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovHWord run_translation ( HWord translation )
510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (0 && DEBUG_TRACE_FLAGS) {
512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      printf(" run translation %p\n", (void*)translation );
513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      printf(" simulated bb: %llu\n", n_bbs_done);
514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
515436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   block[0] = translation;
516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   block[1] = (HWord)&gst;
517436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   HWord trc = run_translation_asm();
518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   n_bbs_done ++;
519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return trc;
520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHWord find_translation ( Addr64 guest_addr )
523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Int i;
525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   HWord __res;
526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (0)
527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      printf("find translation %p ... ", ULong_to_Ptr(guest_addr));
528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (i = 0; i < trans_table_used; i++)
529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     if (trans_table[i].base[0] == guest_addr)
530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        break;
531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (i == trans_table_used) {
532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (0) printf("none\n");
533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 0; /* not found */
534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Move this translation one step towards the front, so finding it
537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      next time round is just that little bit cheaper. */
538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (i > 2) {
539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VexGuestExtents tmpE = trans_table[i-1];
540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ULong*          tmpP = trans_tableP[i-1];
541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      trans_table[i-1]  = trans_table[i];
542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      trans_tableP[i-1] = trans_tableP[i];
543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      trans_table[i] = tmpE;
544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      trans_tableP[i] = tmpP;
545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      i--;
546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   __res = (HWord)trans_tableP[i];
549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (0) printf("%p\n", (void*)__res);
550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return __res;
551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define N_TRANSBUF 5000
554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UChar transbuf[N_TRANSBUF];
555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid make_translation ( Addr64 guest_addr, Bool verbose )
556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexTranslateArgs   vta;
558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexTranslateResult tres;
559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexArchInfo vex_archinfo;
560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Int trans_used, i, ws_needed;
561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
562436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   memset(&vta, 0, sizeof(vta));
563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   memset(&tres, 0, sizeof(tres));
564436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   memset(&vex_archinfo, 0, sizeof(vex_archinfo));
565436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (trans_table_used >= N_TRANS_TABLE
567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       || trans_cache_used >= N_TRANS_CACHE-1000) {
568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* If things are looking to full, just dump
569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         all the translations. */
570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      trans_cache_used = 0;
571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      trans_table_used = 0;
572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   assert(trans_table_used < N_TRANS_TABLE);
575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (0)
576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      printf("make translation %p\n", ULong_to_Ptr(guest_addr));
577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   LibVEX_default_VexArchInfo(&vex_archinfo);
579436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   //vex_archinfo.subarch = VexSubArch;
580436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   //vex_archinfo.ppc_icache_line_szB = CacheLineSize;
581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* */
583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.arch_guest       = VexArch;
584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.archinfo_guest   = vex_archinfo;
585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.arch_host        = VexArch;
586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.archinfo_host    = vex_archinfo;
587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.guest_bytes      = (UChar*)ULong_to_Ptr(guest_addr);
588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.guest_bytes_addr = (Addr64)guest_addr;
589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.chase_into_ok    = chase_into_ok;
590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//   vta.guest_extents    = &vge;
591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.guest_extents    = &trans_table[trans_table_used];
592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.host_bytes       = transbuf;
593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.host_bytes_size  = N_TRANSBUF;
594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.host_bytes_used  = &trans_used;
595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.instrument1      = NULL;
596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.instrument2      = NULL;
597436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vta.needs_self_check = needs_self_check;
598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vta.traceflags       = verbose ? TEST_FLAGS : DEBUG_TRACE_FLAGS;
599436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
600436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vta.disp_cp_chain_me_to_slowEP = NULL; //disp_chain_fast;
601436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vta.disp_cp_chain_me_to_fastEP = NULL; //disp_chain_slow;
602436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vta.disp_cp_xindir             = NULL; //disp_chain_indir;
603436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vta.disp_cp_xassisted          = disp_chain_assisted;
604436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
605436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vta.addProfInc       = False;
606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tres = LibVEX_Translate ( &vta );
608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
609436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(tres.status == VexTransOK);
610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(tres.offs_profInc == -1);
611436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ws_needed = (trans_used+7) / 8;
613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   assert(ws_needed > 0);
614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   assert(trans_cache_used + ws_needed < N_TRANS_CACHE);
615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   n_translations_made++;
616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (i = 0; i < trans_used; i++) {
618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      HChar* dst = ((HChar*)(&trans_cache[trans_cache_used])) + i;
619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      HChar* src = (HChar*)(&transbuf[i]);
620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *dst = *src;
621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined(__aarch64__)
624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   invalidate_icache( &trans_cache[trans_cache_used], trans_used );
625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   trans_tableP[trans_table_used] = &trans_cache[trans_cache_used];
628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   trans_table_used++;
629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   trans_cache_used += ws_needed;
630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov__attribute__((unused))
634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool overlap ( Addr64 start, UInt len, VexGuestExtents* vge )
635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Int i;
637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (i = 0; i < vge->n_used; i++) {
638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     if (vge->base[i]+vge->len[i] <= start
639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         || vge->base[i] >= start+len) {
640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       /* ok */
641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     } else {
642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        return True;
643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     }
644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return False; /* no overlap */
646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong  stopAfter = 0;
649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UChar* entryP    = NULL;
650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__ ((noreturn))
653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid failure_exit ( void )
655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   fprintf(stdout, "VEX did failure_exit.  Bye.\n");
657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   fprintf(stdout, "bb counter = %llu\n\n", n_bbs_done);
658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   exit(1);
659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid log_bytes ( HChar* bytes, Int nbytes )
663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   fwrite ( bytes, 1, nbytes, stdout );
665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   fflush ( stdout );
666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* run simulated code forever (it will exit by calling
670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   serviceFn(0)). */
671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void run_simulator ( void )
672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   static Addr64 last_guest = 0;
674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Addr64 next_guest;
675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   HWord next_host;
676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (1) {
677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      next_guest = gst.GuestPC;
678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (0)
680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         printf("\nnext_guest: 0x%x\n", (UInt)next_guest);
681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (next_guest == Ptr_to_ULong(&serviceFn)) {
683436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* "do" the function call to serviceFn */
685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#        if defined(__i386__)
686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         {
687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            HWord esp = gst.guest_ESP;
688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            gst.guest_EIP = *(UInt*)(esp+0);
689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            gst.guest_EAX = serviceFn( *(UInt*)(esp+4), *(UInt*)(esp+8) );
690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            gst.guest_ESP = esp+4;
691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            next_guest = gst.guest_EIP;
692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
693436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#        elif defined(__aarch64__)
694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         {
695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            gst.guest_X0 = serviceFn( gst.guest_X0, gst.guest_X1 );
696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            gst.guest_PC = gst.guest_X30;
697436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            next_guest   = gst.guest_PC;
698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#        else
700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#        error "Unknown arch"
701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#        endif
702b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      next_host = find_translation(next_guest);
705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (next_host == 0) {
706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         make_translation(next_guest,False);
707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         next_host = find_translation(next_guest);
708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         assert(next_host != 0);
709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // Switchback
712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (n_bbs_done == stopAfter) {
713b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         printf("---begin SWITCHBACK at bb:%llu---\n", n_bbs_done);
714b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 1
715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (last_guest) {
716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            printf("\n*** Last run translation (bb:%llu):\n", n_bbs_done-1);
717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            make_translation(last_guest,True);
718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0
721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (next_guest) {
722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            printf("\n*** Current translation (bb:%llu):\n", n_bbs_done);
723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            make_translation(next_guest,True);
724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         printf("---  end SWITCHBACK at bb:%llu ---\n", n_bbs_done);
727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         switchback();
728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         assert(0); /*NOTREACHED*/
729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      last_guest = next_guest;
732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      HWord trc = run_translation(next_host);
733436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (0) printf("------- trc = %lu\n", trc);
734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (trc != VEX_TRC_JMP_BORING) {
735436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if (1) printf("------- trc = %lu\n", trc);
736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
737436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      assert(trc == VEX_TRC_JMP_BORING);
738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void usage ( void )
743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   printf("usage: switchback #bbs\n");
745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   printf("   - begins switchback for basic block #bbs\n");
746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   printf("   - use -1 for largest possible run without switchback\n\n");
747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   exit(1);
748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint main ( Int argc, HChar** argv )
752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (argc != 2)
754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      usage();
755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   stopAfter = (ULong)atoll(argv[1]);
757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   extern void entry ( void*(*service)(int,int) );
759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   entryP = (UChar*)&entry;
760b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!entryP) {
762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      printf("switchback: can't find entry point\n");
763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      exit(1);
764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   LibVEX_default_VexControl(&vcon);
767436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vcon.guest_max_insns=50 - 49;
768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vcon.guest_chase_thresh=0;
769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vcon.iropt_level=2;
770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   LibVEX_Init( failure_exit, log_bytes, 1, False, &vcon );
772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   LibVEX_Guest_initialise(&gst);
773436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   gst.host_EvC_COUNTER  = 999999999; // so we should never get an exit
774436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   gst.host_EvC_FAILADDR = 0x5a5a5a5a5a5a5a5a;
775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* set up as if a call to the entry point passing serviceFn as
777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      the one and only parameter */
778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  if defined(__i386__)
779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   gst.guest_EIP = (UInt)entryP;
780436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   gst.guest_ESP = (UInt)&gstack[32000];
781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *(UInt*)(gst.guest_ESP+4) = (UInt)serviceFn;
782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *(UInt*)(gst.guest_ESP+0) = 0x12345678;
783436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
784436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  elif defined(__aarch64__)
785436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   gst.guest_PC = (ULong)entryP;
786436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   gst.guest_SP = (ULong)&gstack[32000];
787436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   gst.guest_X0 = (ULong)serviceFn;
788436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   HWord tpidr_el0 = 0;
789436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   __asm__ __volatile__("mrs %0, tpidr_el0" : "=r"(tpidr_el0));
790436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   gst.guest_TPIDR_EL0 = tpidr_el0;
791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  else
793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  error "Unknown arch"
794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  endif
795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   printf("\n---START---\n");
797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 1
799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   run_simulator();
800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else
801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ( (void(*)(HWord(*)(HWord,HWord))) entryP ) (serviceFn);
802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 0;
806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
807