blob: 5165367f99387990a3e0af023fff1d8eb234fa77 [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001/*
2 * Host code generation
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
David 'Digit' Turner2910f182010-05-10 18:48:35 -070017 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080018 */
David 'Digit' Turnerff9a2b82014-02-17 22:31:24 +010019#ifdef _WIN32
20#include <windows.h>
21#else
22#include <sys/types.h>
23#include <sys/mman.h>
24#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080025#include <stdarg.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <string.h>
29#include <inttypes.h>
30
31#include "config.h"
32
33#define NO_CPU_IO_DEFS
34#include "cpu.h"
David 'Digit' Turnerff9a2b82014-02-17 22:31:24 +010035#include "exec/cputlb.h"
David 'Digit' Turner852088c2013-12-14 23:04:12 +010036#include "exec/exec-all.h"
David 'Digit' Turnercc33b2d2013-12-15 00:09:42 +010037#include "disas/disas.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080038#include "tcg.h"
David 'Digit' Turner7a78db72013-12-14 11:46:01 +010039#include "qemu/timer.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080040
David 'Digit' Turnerff9a2b82014-02-17 22:31:24 +010041typedef struct PageDesc {
42 /* list of TBs intersecting this ram page */
43 TranslationBlock *first_tb;
44 /* in order to optimize self modifying code, we count the number
45 of lookups we do to a given page to use a bitmap */
46 unsigned int code_write_count;
47 uint8_t *code_bitmap;
48#if defined(CONFIG_USER_ONLY)
49 unsigned long flags;
50#endif
51} PageDesc;
52
53#define L2_BITS 10
54#if defined(CONFIG_USER_ONLY) && defined(TARGET_VIRT_ADDR_SPACE_BITS)
55/* XXX: this is a temporary hack for alpha target.
56 * In the future, this is to be replaced by a multi-level table
57 * to actually be able to handle the complete 64 bits address space.
58 */
59#define L1_BITS (TARGET_VIRT_ADDR_SPACE_BITS - L2_BITS - TARGET_PAGE_BITS)
60#else
61#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
62#endif
63
64#define L1_SIZE (1 << L1_BITS)
65#define L2_SIZE (1 << L2_BITS)
66
67uintptr_t qemu_real_host_page_size;
68uintptr_t qemu_host_page_size;
69uintptr_t qemu_host_page_mask;
70
71/* XXX: for system emulation, it could just be an array */
72static PageDesc *l1_map[L1_SIZE];
73static PhysPageDesc **l1_phys_map;
74
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080075/* code generation context */
76TCGContext tcg_ctx;
77
78uint16_t gen_opc_buf[OPC_BUF_SIZE];
79TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
80
81target_ulong gen_opc_pc[OPC_BUF_SIZE];
82uint16_t gen_opc_icount[OPC_BUF_SIZE];
83uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
84#if defined(TARGET_I386)
85uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
86#elif defined(TARGET_SPARC)
87target_ulong gen_opc_npc[OPC_BUF_SIZE];
88target_ulong gen_opc_jump_pc[2];
89#elif defined(TARGET_MIPS) || defined(TARGET_SH4)
90uint32_t gen_opc_hflags[OPC_BUF_SIZE];
91#endif
92
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080093#ifdef CONFIG_MEMCHECK
94/*
95 * Memchecker code in this module copies TB PC <-> Guest PC map to the TB
96 * descriptor after guest code has been translated in cpu_gen_init routine.
97 */
98#include "memcheck/memcheck_api.h"
99
100/* Array of (tb_pc, guest_pc) pairs, big enough for all translations. This
101 * array is used to obtain guest PC address from a translated PC address.
102 * tcg_gen_code_common will fill it up when memchecker is enabled. */
David 'Digit' Turnerd9b6cb92010-10-20 19:07:28 +0200103static void* gen_opc_tpc2gpc[OPC_BUF_SIZE * 2];
104void** gen_opc_tpc2gpc_ptr = &gen_opc_tpc2gpc[0];
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800105/* Number of (tb_pc, guest_pc) pairs stored in gen_opc_tpc2gpc array. */
106unsigned int gen_opc_tpc2gpc_pairs;
107#endif // CONFIG_MEMCHECK
108
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800109/* XXX: suppress that */
110unsigned long code_gen_max_block_size(void)
111{
112 static unsigned long max;
113
114 if (max == 0) {
115 max = TCG_MAX_OP_SIZE;
David 'Digit' Turnerf1d9bf12011-05-11 18:19:41 +0200116#define DEF(name, iarg, oarg, carg, flags) DEF2((iarg) + (oarg) + (carg))
117#define DEF2(copy_size) max = (copy_size > max) ? copy_size : max;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800118#include "tcg-opc.h"
119#undef DEF
David 'Digit' Turnerf1d9bf12011-05-11 18:19:41 +0200120#undef DEF2
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800121 max *= OPC_MAX_SIZE;
122 }
123
124 return max;
125}
126
127void cpu_gen_init(void)
128{
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800129 tcg_context_init(&tcg_ctx);
David 'Digit' Turnere2678e12014-01-16 15:56:43 +0100130 tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUOldState, temp_buf),
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800131 CPU_TEMP_BUF_NLONGS * sizeof(long));
132}
133
134/* return non zero if the very first instruction is invalid so that
135 the virtual CPU can trigger an exception.
136
137 '*gen_code_size_ptr' contains the size of the generated code (host
138 code).
139*/
David 'Digit' Turner4d6613c2014-01-22 18:19:00 +0100140int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800141{
142 TCGContext *s = &tcg_ctx;
143 uint8_t *gen_code_buf;
144 int gen_code_size;
145#ifdef CONFIG_PROFILER
146 int64_t ti;
147#endif
148
149#ifdef CONFIG_PROFILER
150 s->tb_count1++; /* includes aborted translations because of
151 exceptions */
152 ti = profile_getclock();
153#endif
154 tcg_func_start(s);
155
156 gen_intermediate_code(env, tb);
157
158 /* generate machine code */
159 gen_code_buf = tb->tc_ptr;
160 tb->tb_next_offset[0] = 0xffff;
161 tb->tb_next_offset[1] = 0xffff;
162 s->tb_next_offset = tb->tb_next_offset;
163#ifdef USE_DIRECT_JUMP
164 s->tb_jmp_offset = tb->tb_jmp_offset;
165 s->tb_next = NULL;
166 /* the following two entries are optional (only used for string ops) */
167 /* XXX: not used ? */
168 tb->tb_jmp_offset[2] = 0xffff;
169 tb->tb_jmp_offset[3] = 0xffff;
170#else
171 s->tb_jmp_offset = NULL;
172 s->tb_next = tb->tb_next;
173#endif
174
175#ifdef CONFIG_PROFILER
176 s->tb_count++;
177 s->interm_time += profile_getclock() - ti;
178 s->code_time -= profile_getclock();
179#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700180 gen_code_size = tcg_gen_code(s, gen_code_buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800181 *gen_code_size_ptr = gen_code_size;
182#ifdef CONFIG_PROFILER
183 s->code_time += profile_getclock();
184 s->code_in_len += tb->size;
185 s->code_out_len += gen_code_size;
186#endif
187
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800188#ifdef CONFIG_MEMCHECK
189 /* Save translated PC -> guest PC map into TB. */
190 if (memcheck_enabled && gen_opc_tpc2gpc_pairs && is_cpu_user(env)) {
191 tb->tpc2gpc =
David 'Digit' Turneraa8236d2014-01-10 17:02:29 +0100192 g_malloc(gen_opc_tpc2gpc_pairs * 2 * sizeof(uintptr_t));
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800193 if (tb->tpc2gpc != NULL) {
194 memcpy(tb->tpc2gpc, gen_opc_tpc2gpc_ptr,
Andrey Petrovc5111a02013-07-10 19:57:36 -0700195 gen_opc_tpc2gpc_pairs * 2 * sizeof(uintptr_t));
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800196 tb->tpc2gpc_pairs = gen_opc_tpc2gpc_pairs;
197 }
Andrey Petrovc5111a02013-07-10 19:57:36 -0700198
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800199 }
200#endif // CONFIG_MEMCHECK
201
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800202#ifdef DEBUG_DISAS
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700203 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
204 qemu_log("OUT: [size=%d]\n", *gen_code_size_ptr);
205 log_disas(tb->tc_ptr, *gen_code_size_ptr);
206 qemu_log("\n");
207 qemu_log_flush();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800208 }
209#endif
210 return 0;
211}
212
213/* The cpu state corresponding to 'searched_pc' is restored.
214 */
David 'Digit' Turner85c62202014-02-16 20:53:40 +0100215bool cpu_restore_state(TranslationBlock *tb,
216 CPUArchState *env, uintptr_t searched_pc)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800217{
218 TCGContext *s = &tcg_ctx;
219 int j;
David 'Digit' Turner85c62202014-02-16 20:53:40 +0100220 uintptr_t tc_ptr;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800221#ifdef CONFIG_PROFILER
222 int64_t ti;
223#endif
224
225#ifdef CONFIG_PROFILER
226 ti = profile_getclock();
227#endif
228 tcg_func_start(s);
229
230 gen_intermediate_code_pc(env, tb);
231
232 if (use_icount) {
233 /* Reset the cycle counter to the start of the block. */
234 env->icount_decr.u16.low += tb->icount;
235 /* Clear the IO flag. */
236 env->can_do_io = 0;
237 }
238
239 /* find opc index corresponding to search_pc */
David 'Digit' Turner85c62202014-02-16 20:53:40 +0100240 tc_ptr = (uintptr_t)tb->tc_ptr;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800241 if (searched_pc < tc_ptr)
242 return -1;
243
244 s->tb_next_offset = tb->tb_next_offset;
245#ifdef USE_DIRECT_JUMP
246 s->tb_jmp_offset = tb->tb_jmp_offset;
247 s->tb_next = NULL;
248#else
249 s->tb_jmp_offset = NULL;
250 s->tb_next = tb->tb_next;
251#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700252 j = tcg_gen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800253 if (j < 0)
David 'Digit' Turner85c62202014-02-16 20:53:40 +0100254 return false;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800255 /* now find start of instruction before */
256 while (gen_opc_instr_start[j] == 0)
257 j--;
258 env->icount_decr.u16.low -= gen_opc_icount[j];
259
David 'Digit' Turnerd3d44682011-05-10 17:49:00 +0200260 restore_state_to_opc(env, tb, j);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800261
262#ifdef CONFIG_PROFILER
263 s->restore_time += profile_getclock() - ti;
264 s->restore_count++;
265#endif
David 'Digit' Turner85c62202014-02-16 20:53:40 +0100266 return true;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800267}
David 'Digit' Turner3dc53fc2014-01-17 01:23:40 +0100268
David 'Digit' Turnerff9a2b82014-02-17 22:31:24 +0100269#ifdef _WIN32
270static void map_exec(void *addr, long size)
271{
272 DWORD old_protect;
273 VirtualProtect(addr, size,
274 PAGE_EXECUTE_READWRITE, &old_protect);
275
276}
277#else
278static void map_exec(void *addr, long size)
279{
280 unsigned long start, end, page_size;
281
282 page_size = getpagesize();
283 start = (unsigned long)addr;
284 start &= ~(page_size - 1);
285
286 end = (unsigned long)addr + size;
287 end += page_size - 1;
288 end &= ~(page_size - 1);
289
290 mprotect((void *)start, end - start,
291 PROT_READ | PROT_WRITE | PROT_EXEC);
292}
293#endif
294
295static void page_init(void)
296{
297 /* NOTE: we can always suppose that qemu_host_page_size >=
298 TARGET_PAGE_SIZE */
299#ifdef _WIN32
300 {
301 SYSTEM_INFO system_info;
302
303 GetSystemInfo(&system_info);
304 qemu_real_host_page_size = system_info.dwPageSize;
305 }
306#else
307 qemu_real_host_page_size = getpagesize();
308#endif
309 if (qemu_host_page_size == 0)
310 qemu_host_page_size = qemu_real_host_page_size;
311 if (qemu_host_page_size < TARGET_PAGE_SIZE)
312 qemu_host_page_size = TARGET_PAGE_SIZE;
313 qemu_host_page_mask = ~(qemu_host_page_size - 1);
314 l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
315 memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
316
317#if !defined(_WIN32) && defined(CONFIG_USER_ONLY)
318 {
319 long long startaddr, endaddr;
320 FILE *f;
321 int n;
322
323 mmap_lock();
324 last_brk = (unsigned long)sbrk(0);
325 f = fopen("/proc/self/maps", "r");
326 if (f) {
327 do {
328 n = fscanf (f, "%llx-%llx %*[^\n]\n", &startaddr, &endaddr);
329 if (n == 2) {
330 startaddr = MIN(startaddr,
331 (1ULL << TARGET_PHYS_ADDR_SPACE_BITS) - 1);
332 endaddr = MIN(endaddr,
333 (1ULL << TARGET_PHYS_ADDR_SPACE_BITS) - 1);
334 page_set_flags(startaddr & TARGET_PAGE_MASK,
335 TARGET_PAGE_ALIGN(endaddr),
336 PAGE_RESERVED);
337 }
338 } while (!feof(f));
339 fclose(f);
340 }
341 mmap_unlock();
342 }
343#endif
344}
345
346static inline PageDesc **page_l1_map(target_ulong index)
347{
348#if TARGET_LONG_BITS > 32
349 /* Host memory outside guest VM. For 32-bit targets we have already
350 excluded high addresses. */
351 if (index > ((target_ulong)L2_SIZE * L1_SIZE))
352 return NULL;
353#endif
354 return &l1_map[index >> L2_BITS];
355}
356
357static inline PageDesc *page_find_alloc(target_ulong index)
358{
359 PageDesc **lp, *p;
360 lp = page_l1_map(index);
361 if (!lp)
362 return NULL;
363
364 p = *lp;
365 if (!p) {
366 /* allocate if not found */
367#if defined(CONFIG_USER_ONLY)
368 size_t len = sizeof(PageDesc) * L2_SIZE;
369 /* Don't use g_malloc because it may recurse. */
370 p = mmap(NULL, len, PROT_READ | PROT_WRITE,
371 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
372 *lp = p;
373 if (h2g_valid(p)) {
374 unsigned long addr = h2g(p);
375 page_set_flags(addr & TARGET_PAGE_MASK,
376 TARGET_PAGE_ALIGN(addr + len),
377 PAGE_RESERVED);
378 }
379#else
380 p = g_malloc0(sizeof(PageDesc) * L2_SIZE);
381 *lp = p;
382#endif
383 }
384 return p + (index & (L2_SIZE - 1));
385}
386
387static inline PageDesc *page_find(target_ulong index)
388{
389 PageDesc **lp, *p;
390 lp = page_l1_map(index);
391 if (!lp)
392 return NULL;
393
394 p = *lp;
395 if (!p) {
396 return NULL;
397 }
398 return p + (index & (L2_SIZE - 1));
399}
400
401PhysPageDesc *phys_page_find_alloc(hwaddr index, int alloc)
402{
403 void **lp, **p;
404 PhysPageDesc *pd;
405
406 p = (void **)l1_phys_map;
407#if TARGET_PHYS_ADDR_SPACE_BITS > 32
408
409#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)
410#error unsupported TARGET_PHYS_ADDR_SPACE_BITS
411#endif
412 lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
413 p = *lp;
414 if (!p) {
415 /* allocate if not found */
416 if (!alloc)
417 return NULL;
418 p = qemu_vmalloc(sizeof(void *) * L1_SIZE);
419 memset(p, 0, sizeof(void *) * L1_SIZE);
420 *lp = p;
421 }
422#endif
423 lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
424 pd = *lp;
425 if (!pd) {
426 int i;
427 /* allocate if not found */
428 if (!alloc)
429 return NULL;
430 pd = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
431 *lp = pd;
432 for (i = 0; i < L2_SIZE; i++) {
433 pd[i].phys_offset = IO_MEM_UNASSIGNED;
434 pd[i].region_offset = (index + i) << TARGET_PAGE_BITS;
435 }
436 }
437 return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
438}
439
440PhysPageDesc *phys_page_find(hwaddr index)
441{
442 return phys_page_find_alloc(index, 0);
443}
444
445#if !defined(CONFIG_USER_ONLY)
446#define mmap_lock() do { } while(0)
447#define mmap_unlock() do { } while(0)
448#endif
449
450#if !defined(CONFIG_USER_ONLY)
451/* TB consistency checks only implemented for usermode emulation. */
452#undef DEBUG_TB_CHECK
453#endif
454
455#define SMC_BITMAP_USE_THRESHOLD 10
456
457int code_gen_max_blocks;
458
459#if defined(__arm__) || defined(__sparc_v9__)
460/* The prologue must be reachable with a direct jump. ARM and Sparc64
461 have limited branch ranges (possibly also PPC) so place it in a
462 section close to code segment. */
463#define code_gen_section \
464 __attribute__((__section__(".gen_code"))) \
465 __attribute__((aligned (32)))
466#elif defined(_WIN32)
467/* Maximum alignment for Win32 is 16. */
468#define code_gen_section \
469 __attribute__((aligned (16)))
470#else
471#define code_gen_section \
472 __attribute__((aligned (32)))
473#endif
474
475uint8_t code_gen_prologue[1024] code_gen_section;
476static uint8_t *code_gen_buffer;
477static unsigned long code_gen_buffer_size;
478/* threshold to flush the translated code buffer */
479static unsigned long code_gen_buffer_max_size;
480uint8_t *code_gen_ptr;
481
482#define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024)
483
484#if defined(CONFIG_USER_ONLY)
485/* Currently it is not recommended to allocate big chunks of data in
486 user mode. It will change when a dedicated libc will be used */
487#define USE_STATIC_CODE_GEN_BUFFER
488#endif
489
490#ifdef USE_STATIC_CODE_GEN_BUFFER
491static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE];
492#endif
493
494static void code_gen_alloc(unsigned long tb_size)
495{
496#ifdef USE_STATIC_CODE_GEN_BUFFER
497 code_gen_buffer = static_code_gen_buffer;
498 code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
499 map_exec(code_gen_buffer, code_gen_buffer_size);
500#else
501 code_gen_buffer_size = tb_size;
502 if (code_gen_buffer_size == 0) {
503#if defined(CONFIG_USER_ONLY)
504 /* in user mode, phys_ram_size is not meaningful */
505 code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
506#else
507 /* XXX: needs adjustments */
508 code_gen_buffer_size = (unsigned long)(ram_size / 4);
509#endif
510 }
511 if (code_gen_buffer_size < MIN_CODE_GEN_BUFFER_SIZE)
512 code_gen_buffer_size = MIN_CODE_GEN_BUFFER_SIZE;
513 /* The code gen buffer location may have constraints depending on
514 the host cpu and OS */
515#if defined(__linux__)
516 {
517 int flags;
518 void *start = NULL;
519
520 flags = MAP_PRIVATE | MAP_ANONYMOUS;
521#if defined(__x86_64__)
522 flags |= MAP_32BIT;
523 /* Cannot map more than that */
524 if (code_gen_buffer_size > (800 * 1024 * 1024))
525 code_gen_buffer_size = (800 * 1024 * 1024);
526#elif defined(__sparc_v9__)
527 // Map the buffer below 2G, so we can use direct calls and branches
528 flags |= MAP_FIXED;
529 start = (void *) 0x60000000UL;
530 if (code_gen_buffer_size > (512 * 1024 * 1024))
531 code_gen_buffer_size = (512 * 1024 * 1024);
532#elif defined(__arm__)
533 /* Map the buffer below 32M, so we can use direct calls and branches */
534 flags |= MAP_FIXED;
535 start = (void *) 0x01000000UL;
536 if (code_gen_buffer_size > 16 * 1024 * 1024)
537 code_gen_buffer_size = 16 * 1024 * 1024;
538#elif defined(__s390x__)
539 /* Map the buffer so that we can use direct calls and branches. */
540 /* We have a +- 4GB range on the branches; leave some slop. */
541 if (code_gen_buffer_size > (3ul * 1024 * 1024 * 1024)) {
542 code_gen_buffer_size = 3ul * 1024 * 1024 * 1024;
543 }
544 start = (void *)0x90000000UL;
545#endif
546 code_gen_buffer = mmap(start, code_gen_buffer_size,
547 PROT_WRITE | PROT_READ | PROT_EXEC,
548 flags, -1, 0);
549 if (code_gen_buffer == MAP_FAILED) {
550 fprintf(stderr, "Could not allocate dynamic translator buffer\n");
551 exit(1);
552 }
553 }
554#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
555 || defined(__DragonFly__) || defined(__OpenBSD__)
556 {
557 int flags;
558 void *addr = NULL;
559 flags = MAP_PRIVATE | MAP_ANONYMOUS;
560#if defined(__x86_64__)
561 /* FreeBSD doesn't have MAP_32BIT, use MAP_FIXED and assume
562 * 0x40000000 is free */
563 flags |= MAP_FIXED;
564 addr = (void *)0x40000000;
565 /* Cannot map more than that */
566 if (code_gen_buffer_size > (800 * 1024 * 1024))
567 code_gen_buffer_size = (800 * 1024 * 1024);
568#elif defined(__sparc_v9__)
569 // Map the buffer below 2G, so we can use direct calls and branches
570 flags |= MAP_FIXED;
571 addr = (void *) 0x60000000UL;
572 if (code_gen_buffer_size > (512 * 1024 * 1024)) {
573 code_gen_buffer_size = (512 * 1024 * 1024);
574 }
575#endif
576 code_gen_buffer = mmap(addr, code_gen_buffer_size,
577 PROT_WRITE | PROT_READ | PROT_EXEC,
578 flags, -1, 0);
579 if (code_gen_buffer == MAP_FAILED) {
580 fprintf(stderr, "Could not allocate dynamic translator buffer\n");
581 exit(1);
582 }
583 }
584#else
585 code_gen_buffer = g_malloc(code_gen_buffer_size);
586 map_exec(code_gen_buffer, code_gen_buffer_size);
587#endif
588#endif /* !USE_STATIC_CODE_GEN_BUFFER */
589 map_exec(code_gen_prologue, sizeof(code_gen_prologue));
590 code_gen_buffer_max_size = code_gen_buffer_size -
591 code_gen_max_block_size();
592 code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
593 tcg_ctx.tb_ctx.tbs = g_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
594}
595
596/* Must be called before using the QEMU cpus. 'tb_size' is the size
597 (in bytes) allocated to the translation buffer. Zero means default
598 size. */
599void tcg_exec_init(unsigned long tb_size)
600{
601 cpu_gen_init();
602 code_gen_alloc(tb_size);
603 code_gen_ptr = code_gen_buffer;
604 page_init();
605#if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
606 /* There's no guest base to take into account, so go ahead and
607 initialize the prologue now. */
608 tcg_prologue_init(&tcg_ctx);
609#endif
610}
611
612bool tcg_enabled(void)
613{
614 return code_gen_buffer != NULL;
615}
616
617/* add the tb in the target page and protect it if necessary */
618void tb_free(TranslationBlock *tb)
619{
620 /* In practice this is mostly used for single use temporary TB
621 Ignore the hard cases and just back up if this TB happens to
622 be the last one generated. */
623 if (tcg_ctx.tb_ctx.nb_tbs > 0 && tb == &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs - 1]) {
624 code_gen_ptr = tb->tc_ptr;
625 tcg_ctx.tb_ctx.nb_tbs--;
626 }
627}
628
629static inline void invalidate_page_bitmap(PageDesc *p)
630{
631 if (p->code_bitmap) {
632 g_free(p->code_bitmap);
633 p->code_bitmap = NULL;
634 }
635 p->code_write_count = 0;
636}
637
638static inline void tb_alloc_page(TranslationBlock *tb,
639 unsigned int n, target_ulong page_addr)
640{
641 PageDesc *p;
642 TranslationBlock *last_first_tb;
643
644 tb->page_addr[n] = page_addr;
645 p = page_find_alloc(page_addr >> TARGET_PAGE_BITS);
646 tb->page_next[n] = p->first_tb;
647 last_first_tb = p->first_tb;
648 p->first_tb = (TranslationBlock *)((long)tb | n);
649 invalidate_page_bitmap(p);
650
651#if defined(TARGET_HAS_SMC) || 1
652
653#if defined(CONFIG_USER_ONLY)
654 if (p->flags & PAGE_WRITE) {
655 target_ulong addr;
656 PageDesc *p2;
657 int prot;
658
659 /* force the host page as non writable (writes will have a
660 page fault + mprotect overhead) */
661 page_addr &= qemu_host_page_mask;
662 prot = 0;
663 for(addr = page_addr; addr < page_addr + qemu_host_page_size;
664 addr += TARGET_PAGE_SIZE) {
665
666 p2 = page_find (addr >> TARGET_PAGE_BITS);
667 if (!p2)
668 continue;
669 prot |= p2->flags;
670 p2->flags &= ~PAGE_WRITE;
671 page_get_flags(addr);
672 }
673 mprotect(g2h(page_addr), qemu_host_page_size,
674 (prot & PAGE_BITS) & ~PAGE_WRITE);
675#ifdef DEBUG_TB_INVALIDATE
676 printf("protecting code page: 0x" TARGET_FMT_lx "\n",
677 page_addr);
678#endif
679 }
680#else
681 /* if some code is already present, then the pages are already
682 protected. So we handle the case where only the first TB is
683 allocated in a physical page */
684 if (!last_first_tb) {
685 tlb_protect_code(page_addr);
686 }
687#endif
688
689#endif /* TARGET_HAS_SMC */
690}
691
692/* Allocate a new translation block. Flush the translation buffer if
693 too many translation blocks or too much generated code. */
694TranslationBlock *tb_alloc(target_ulong pc)
695{
696 TranslationBlock *tb;
697
698 if (tcg_ctx.tb_ctx.nb_tbs >= code_gen_max_blocks ||
699 (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size)
700 return NULL;
701 tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
702 tb->pc = pc;
703 tb->cflags = 0;
704#ifdef CONFIG_MEMCHECK
705 tb->tpc2gpc = NULL;
706 tb->tpc2gpc_pairs = 0;
707#endif // CONFIG_MEMCHECK
708 return tb;
709}
710
711/* set to NULL all the 'first_tb' fields in all PageDescs */
712static void page_flush_tb(void)
713{
714 int i, j;
715 PageDesc *p;
716
717 for(i = 0; i < L1_SIZE; i++) {
718 p = l1_map[i];
719 if (p) {
720 for(j = 0; j < L2_SIZE; j++) {
721 p->first_tb = NULL;
722 invalidate_page_bitmap(p);
723 p++;
724 }
725 }
726 }
727}
728
729/* flush all the translation blocks */
730/* XXX: tb_flush is currently not thread safe */
731void tb_flush(CPUArchState *env1)
732{
733 CPUArchState *env;
734#if defined(DEBUG_FLUSH)
735 printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
736 (unsigned long)(code_gen_ptr - code_gen_buffer),
737 nb_tbs, nb_tbs > 0 ?
738 ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
739#endif
740 if ((unsigned long)(code_gen_ptr - code_gen_buffer) > code_gen_buffer_size)
741 cpu_abort(env1, "Internal error: code buffer overflow\n");
742
743 tcg_ctx.tb_ctx.nb_tbs = 0;
744
745 for(env = first_cpu; env != NULL; env = env->next_cpu) {
746#ifdef CONFIG_MEMCHECK
747 int tb_to_clean;
748 for (tb_to_clean = 0; tb_to_clean < TB_JMP_CACHE_SIZE; tb_to_clean++) {
749 if (env->tb_jmp_cache[tb_to_clean] != NULL &&
750 env->tb_jmp_cache[tb_to_clean]->tpc2gpc != NULL) {
751 g_free(env->tb_jmp_cache[tb_to_clean]->tpc2gpc);
752 env->tb_jmp_cache[tb_to_clean]->tpc2gpc = NULL;
753 env->tb_jmp_cache[tb_to_clean]->tpc2gpc_pairs = 0;
754 }
755 }
756#endif // CONFIG_MEMCHECK
757 memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
758 }
759
760 memset (tcg_ctx.tb_ctx.tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
761 page_flush_tb();
762
763 code_gen_ptr = code_gen_buffer;
764 /* XXX: flush processor icache at this point if cache flush is
765 expensive */
766 tcg_ctx.tb_ctx.tb_flush_count++;
767}
768
769#ifdef DEBUG_TB_CHECK
770
771static void tb_invalidate_check(target_ulong address)
772{
773 TranslationBlock *tb;
774 int i;
775 address &= TARGET_PAGE_MASK;
776 for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
777 for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
778 if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
779 address >= tb->pc + tb->size)) {
780 printf("ERROR invalidate: address=" TARGET_FMT_lx
781 " PC=%08lx size=%04x\n",
782 address, (long)tb->pc, tb->size);
783 }
784 }
785 }
786}
787
788/* verify that all the pages have correct rights for code */
789static void tb_page_check(void)
790{
791 TranslationBlock *tb;
792 int i, flags1, flags2;
793
794 for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
795 for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
796 flags1 = page_get_flags(tb->pc);
797 flags2 = page_get_flags(tb->pc + tb->size - 1);
798 if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
799 printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
800 (long)tb->pc, tb->size, flags1, flags2);
801 }
802 }
803 }
804}
805
806#endif
807
808/* invalidate one TB */
809static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
810 int next_offset)
811{
812 TranslationBlock *tb1;
813 for(;;) {
814 tb1 = *ptb;
815 if (tb1 == tb) {
816 *ptb = *(TranslationBlock **)((char *)tb1 + next_offset);
817 break;
818 }
819 ptb = (TranslationBlock **)((char *)tb1 + next_offset);
820 }
821}
822
823static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
824{
825 TranslationBlock *tb1;
826 unsigned int n1;
827
828 for(;;) {
829 tb1 = *ptb;
830 n1 = (long)tb1 & 3;
831 tb1 = (TranslationBlock *)((long)tb1 & ~3);
832 if (tb1 == tb) {
833 *ptb = tb1->page_next[n1];
834 break;
835 }
836 ptb = &tb1->page_next[n1];
837 }
838}
839
840static inline void tb_jmp_remove(TranslationBlock *tb, int n)
841{
842 TranslationBlock *tb1, **ptb;
843 unsigned int n1;
844
845 ptb = &tb->jmp_next[n];
846 tb1 = *ptb;
847 if (tb1) {
848 /* find tb(n) in circular list */
849 for(;;) {
850 tb1 = *ptb;
851 n1 = (long)tb1 & 3;
852 tb1 = (TranslationBlock *)((long)tb1 & ~3);
853 if (n1 == n && tb1 == tb)
854 break;
855 if (n1 == 2) {
856 ptb = &tb1->jmp_first;
857 } else {
858 ptb = &tb1->jmp_next[n1];
859 }
860 }
861 /* now we can suppress tb(n) from the list */
862 *ptb = tb->jmp_next[n];
863
864 tb->jmp_next[n] = NULL;
865 }
866}
867
868/* reset the jump entry 'n' of a TB so that it is not chained to
869 another TB */
870static inline void tb_reset_jump(TranslationBlock *tb, int n)
871{
872 tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
873}
874
875void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
876{
877 CPUArchState *env;
878 PageDesc *p;
879 unsigned int h, n1;
880 hwaddr phys_pc;
881 TranslationBlock *tb1, *tb2;
882
883 /* remove the TB from the hash list */
884 phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
885 h = tb_phys_hash_func(phys_pc);
886 tb_remove(&tcg_ctx.tb_ctx.tb_phys_hash[h], tb,
887 offsetof(TranslationBlock, phys_hash_next));
888
889 /* remove the TB from the page list */
890 if (tb->page_addr[0] != page_addr) {
891 p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
892 tb_page_remove(&p->first_tb, tb);
893 invalidate_page_bitmap(p);
894 }
895 if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
896 p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
897 tb_page_remove(&p->first_tb, tb);
898 invalidate_page_bitmap(p);
899 }
900
901 tcg_ctx.tb_ctx.tb_invalidated_flag = 1;
902
903 /* remove the TB from the hash list */
904 h = tb_jmp_cache_hash_func(tb->pc);
905 for(env = first_cpu; env != NULL; env = env->next_cpu) {
906 if (env->tb_jmp_cache[h] == tb)
907 env->tb_jmp_cache[h] = NULL;
908 }
909
910 /* suppress this TB from the two jump lists */
911 tb_jmp_remove(tb, 0);
912 tb_jmp_remove(tb, 1);
913
914 /* suppress any remaining jumps to this TB */
915 tb1 = tb->jmp_first;
916 for(;;) {
917 n1 = (long)tb1 & 3;
918 if (n1 == 2)
919 break;
920 tb1 = (TranslationBlock *)((long)tb1 & ~3);
921 tb2 = tb1->jmp_next[n1];
922 tb_reset_jump(tb1, n1);
923 tb1->jmp_next[n1] = NULL;
924 tb1 = tb2;
925 }
926 tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
927
928#ifdef CONFIG_MEMCHECK
929 if (tb->tpc2gpc != NULL) {
930 g_free(tb->tpc2gpc);
931 tb->tpc2gpc = NULL;
932 tb->tpc2gpc_pairs = 0;
933 }
934#endif // CONFIG_MEMCHECK
935
936 tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
937}
938
939static inline void set_bits(uint8_t *tab, int start, int len)
940{
941 int end, mask, end1;
942
943 end = start + len;
944 tab += start >> 3;
945 mask = 0xff << (start & 7);
946 if ((start & ~7) == (end & ~7)) {
947 if (start < end) {
948 mask &= ~(0xff << (end & 7));
949 *tab |= mask;
950 }
951 } else {
952 *tab++ |= mask;
953 start = (start + 8) & ~7;
954 end1 = end & ~7;
955 while (start < end1) {
956 *tab++ = 0xff;
957 start += 8;
958 }
959 if (start < end) {
960 mask = ~(0xff << (end & 7));
961 *tab |= mask;
962 }
963 }
964}
965
966static void build_page_bitmap(PageDesc *p)
967{
968 int n, tb_start, tb_end;
969 TranslationBlock *tb;
970
971 p->code_bitmap = g_malloc0(TARGET_PAGE_SIZE / 8);
972
973 tb = p->first_tb;
974 while (tb != NULL) {
975 n = (long)tb & 3;
976 tb = (TranslationBlock *)((long)tb & ~3);
977 /* NOTE: this is subtle as a TB may span two physical pages */
978 if (n == 0) {
979 /* NOTE: tb_end may be after the end of the page, but
980 it is not a problem */
981 tb_start = tb->pc & ~TARGET_PAGE_MASK;
982 tb_end = tb_start + tb->size;
983 if (tb_end > TARGET_PAGE_SIZE)
984 tb_end = TARGET_PAGE_SIZE;
985 } else {
986 tb_start = 0;
987 tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
988 }
989 set_bits(p->code_bitmap, tb_start, tb_end - tb_start);
990 tb = tb->page_next[n];
991 }
992}
993
994TranslationBlock *tb_gen_code(CPUArchState *env,
995 target_ulong pc, target_ulong cs_base,
996 int flags, int cflags)
997{
998 TranslationBlock *tb;
999 uint8_t *tc_ptr;
1000 target_ulong phys_pc, phys_page2, virt_page2;
1001 int code_gen_size;
1002
1003 phys_pc = get_page_addr_code(env, pc);
1004 tb = tb_alloc(pc);
1005 if (!tb) {
1006 /* flush must be done */
1007 tb_flush(env);
1008 /* cannot fail at this point */
1009 tb = tb_alloc(pc);
1010 /* Don't forget to invalidate previous TB info. */
1011 tcg_ctx.tb_ctx.tb_invalidated_flag = 1;
1012 }
1013 tc_ptr = code_gen_ptr;
1014 tb->tc_ptr = tc_ptr;
1015 tb->cs_base = cs_base;
1016 tb->flags = flags;
1017 tb->cflags = cflags;
1018 cpu_gen_code(env, tb, &code_gen_size);
1019 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
1020
1021 /* check next page if needed */
1022 virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
1023 phys_page2 = -1;
1024 if ((pc & TARGET_PAGE_MASK) != virt_page2) {
1025 phys_page2 = get_page_addr_code(env, virt_page2);
1026 }
1027 tb_link_phys(tb, phys_pc, phys_page2);
1028 return tb;
1029}
1030
1031/* invalidate all TBs which intersect with the target physical page
1032 starting in range [start;end[. NOTE: start and end must refer to
1033 the same physical page. 'is_cpu_write_access' should be true if called
1034 from a real cpu write access: the virtual CPU will exit the current
1035 TB if code is modified inside this TB. */
1036void tb_invalidate_phys_page_range(hwaddr start, hwaddr end,
1037 int is_cpu_write_access)
1038{
1039 TranslationBlock *tb, *tb_next, *saved_tb;
1040 CPUArchState *env = cpu_single_env;
1041 target_ulong tb_start, tb_end;
1042 PageDesc *p;
1043 int n;
1044#ifdef TARGET_HAS_PRECISE_SMC
1045 int current_tb_not_found = is_cpu_write_access;
1046 TranslationBlock *current_tb = NULL;
1047 int current_tb_modified = 0;
1048 target_ulong current_pc = 0;
1049 target_ulong current_cs_base = 0;
1050 int current_flags = 0;
1051#endif /* TARGET_HAS_PRECISE_SMC */
1052
1053 p = page_find(start >> TARGET_PAGE_BITS);
1054 if (!p)
1055 return;
1056 if (!p->code_bitmap &&
1057 ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD &&
1058 is_cpu_write_access) {
1059 /* build code bitmap */
1060 build_page_bitmap(p);
1061 }
1062
1063 /* we remove all the TBs in the range [start, end[ */
1064 /* XXX: see if in some cases it could be faster to invalidate all the code */
1065 tb = p->first_tb;
1066 while (tb != NULL) {
1067 n = (long)tb & 3;
1068 tb = (TranslationBlock *)((long)tb & ~3);
1069 tb_next = tb->page_next[n];
1070 /* NOTE: this is subtle as a TB may span two physical pages */
1071 if (n == 0) {
1072 /* NOTE: tb_end may be after the end of the page, but
1073 it is not a problem */
1074 tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
1075 tb_end = tb_start + tb->size;
1076 } else {
1077 tb_start = tb->page_addr[1];
1078 tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
1079 }
1080 if (!(tb_end <= start || tb_start >= end)) {
1081#ifdef TARGET_HAS_PRECISE_SMC
1082 if (current_tb_not_found) {
1083 current_tb_not_found = 0;
1084 current_tb = NULL;
1085 if (env->mem_io_pc) {
1086 /* now we have a real cpu fault */
1087 current_tb = tb_find_pc(env->mem_io_pc);
1088 }
1089 }
1090 if (current_tb == tb &&
1091 (current_tb->cflags & CF_COUNT_MASK) != 1) {
1092 /* If we are modifying the current TB, we must stop
1093 its execution. We could be more precise by checking
1094 that the modification is after the current PC, but it
1095 would require a specialized function to partially
1096 restore the CPU state */
1097
1098 current_tb_modified = 1;
1099 cpu_restore_state(current_tb, env, env->mem_io_pc);
1100 cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
1101 &current_flags);
1102 }
1103#endif /* TARGET_HAS_PRECISE_SMC */
1104 /* we need to do that to handle the case where a signal
1105 occurs while doing tb_phys_invalidate() */
1106 saved_tb = NULL;
1107 if (env) {
1108 saved_tb = env->current_tb;
1109 env->current_tb = NULL;
1110 }
1111 tb_phys_invalidate(tb, -1);
1112 if (env) {
1113 env->current_tb = saved_tb;
1114 if (env->interrupt_request && env->current_tb)
1115 cpu_interrupt(env, env->interrupt_request);
1116 }
1117 }
1118 tb = tb_next;
1119 }
1120#if !defined(CONFIG_USER_ONLY)
1121 /* if no code remaining, no need to continue to use slow writes */
1122 if (!p->first_tb) {
1123 invalidate_page_bitmap(p);
1124 if (is_cpu_write_access) {
1125 tlb_unprotect_code_phys(env, start, env->mem_io_vaddr);
1126 }
1127 }
1128#endif
1129#ifdef TARGET_HAS_PRECISE_SMC
1130 if (current_tb_modified) {
1131 /* we generate a block containing just the instruction
1132 modifying the memory. It will ensure that it cannot modify
1133 itself */
1134 env->current_tb = NULL;
1135 tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
1136 cpu_resume_from_signal(env, NULL);
1137 }
1138#endif
1139}
1140
1141/* len must be <= 8 and start must be a multiple of len */
1142static inline void tb_invalidate_phys_page_fast(hwaddr start, int len)
1143{
1144 PageDesc *p;
1145 int offset, b;
1146#if 0
1147 if (1) {
1148 qemu_log("modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
1149 cpu_single_env->mem_io_vaddr, len,
1150 cpu_single_env->eip,
1151 cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
1152 }
1153#endif
1154 p = page_find(start >> TARGET_PAGE_BITS);
1155 if (!p)
1156 return;
1157 if (p->code_bitmap) {
1158 offset = start & ~TARGET_PAGE_MASK;
1159 b = p->code_bitmap[offset >> 3] >> (offset & 7);
1160 if (b & ((1 << len) - 1))
1161 goto do_invalidate;
1162 } else {
1163 do_invalidate:
1164 tb_invalidate_phys_page_range(start, start + len, 1);
1165 }
1166}
1167
1168void tb_invalidate_phys_page_fast0(hwaddr start, int len) {
1169 tb_invalidate_phys_page_fast(start, len);
1170}
1171
1172#if !defined(CONFIG_SOFTMMU)
1173static void tb_invalidate_phys_page(hwaddr addr,
1174 unsigned long pc, void *puc)
1175{
1176 TranslationBlock *tb;
1177 PageDesc *p;
1178 int n;
1179#ifdef TARGET_HAS_PRECISE_SMC
1180 TranslationBlock *current_tb = NULL;
1181 CPUArchState *env = cpu_single_env;
1182 int current_tb_modified = 0;
1183 target_ulong current_pc = 0;
1184 target_ulong current_cs_base = 0;
1185 int current_flags = 0;
1186#endif
1187
1188 addr &= TARGET_PAGE_MASK;
1189 p = page_find(addr >> TARGET_PAGE_BITS);
1190 if (!p)
1191 return;
1192 tb = p->first_tb;
1193#ifdef TARGET_HAS_PRECISE_SMC
1194 if (tb && pc != 0) {
1195 current_tb = tb_find_pc(pc);
1196 }
1197#endif
1198 while (tb != NULL) {
1199 n = (long)tb & 3;
1200 tb = (TranslationBlock *)((long)tb & ~3);
1201#ifdef TARGET_HAS_PRECISE_SMC
1202 if (current_tb == tb &&
1203 (current_tb->cflags & CF_COUNT_MASK) != 1) {
1204 /* If we are modifying the current TB, we must stop
1205 its execution. We could be more precise by checking
1206 that the modification is after the current PC, but it
1207 would require a specialized function to partially
1208 restore the CPU state */
1209
1210 current_tb_modified = 1;
1211 cpu_restore_state(current_tb, env, pc);
1212 cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
1213 &current_flags);
1214 }
1215#endif /* TARGET_HAS_PRECISE_SMC */
1216 tb_phys_invalidate(tb, addr);
1217 tb = tb->page_next[n];
1218 }
1219 p->first_tb = NULL;
1220#ifdef TARGET_HAS_PRECISE_SMC
1221 if (current_tb_modified) {
1222 /* we generate a block containing just the instruction
1223 modifying the memory. It will ensure that it cannot modify
1224 itself */
1225 env->current_tb = NULL;
1226 tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
1227 cpu_resume_from_signal(env, puc);
1228 }
1229#endif
1230}
1231#endif
1232
1233/* add a new TB and link it to the physical page tables. phys_page2 is
1234 (-1) to indicate that only one page contains the TB. */
1235void tb_link_phys(TranslationBlock *tb,
1236 target_ulong phys_pc, target_ulong phys_page2)
1237{
1238 unsigned int h;
1239 TranslationBlock **ptb;
1240
1241 /* Grab the mmap lock to stop another thread invalidating this TB
1242 before we are done. */
1243 mmap_lock();
1244 /* add in the physical hash table */
1245 h = tb_phys_hash_func(phys_pc);
1246 ptb = &tcg_ctx.tb_ctx.tb_phys_hash[h];
1247 tb->phys_hash_next = *ptb;
1248 *ptb = tb;
1249
1250 /* add in the page list */
1251 tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
1252 if (phys_page2 != -1)
1253 tb_alloc_page(tb, 1, phys_page2);
1254 else
1255 tb->page_addr[1] = -1;
1256
1257 tb->jmp_first = (TranslationBlock *)((long)tb | 2);
1258 tb->jmp_next[0] = NULL;
1259 tb->jmp_next[1] = NULL;
1260
1261 /* init original jump addresses */
1262 if (tb->tb_next_offset[0] != 0xffff)
1263 tb_reset_jump(tb, 0);
1264 if (tb->tb_next_offset[1] != 0xffff)
1265 tb_reset_jump(tb, 1);
1266
1267#ifdef DEBUG_TB_CHECK
1268 tb_page_check();
1269#endif
1270 mmap_unlock();
1271}
1272
1273/* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
1274 tb[1].tc_ptr. Return NULL if not found */
1275TranslationBlock *tb_find_pc(unsigned long tc_ptr)
1276{
1277 int m_min, m_max, m;
1278 unsigned long v;
1279 TranslationBlock *tb;
1280
1281 if (tcg_ctx.tb_ctx.nb_tbs <= 0)
1282 return NULL;
1283 if (tc_ptr < (unsigned long)code_gen_buffer ||
1284 tc_ptr >= (unsigned long)code_gen_ptr)
1285 return NULL;
1286 /* binary search (cf Knuth) */
1287 m_min = 0;
1288 m_max = tcg_ctx.tb_ctx.nb_tbs - 1;
1289 while (m_min <= m_max) {
1290 m = (m_min + m_max) >> 1;
1291 tb = &tcg_ctx.tb_ctx.tbs[m];
1292 v = (unsigned long)tb->tc_ptr;
1293 if (v == tc_ptr)
1294 return tb;
1295 else if (tc_ptr < v) {
1296 m_max = m - 1;
1297 } else {
1298 m_min = m + 1;
1299 }
1300 }
1301 return &tcg_ctx.tb_ctx.tbs[m_max];
1302}
1303
1304static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
1305{
1306 TranslationBlock *tb1, *tb_next, **ptb;
1307 unsigned int n1;
1308
1309 tb1 = tb->jmp_next[n];
1310 if (tb1 != NULL) {
1311 /* find head of list */
1312 for(;;) {
1313 n1 = (long)tb1 & 3;
1314 tb1 = (TranslationBlock *)((long)tb1 & ~3);
1315 if (n1 == 2)
1316 break;
1317 tb1 = tb1->jmp_next[n1];
1318 }
1319 /* we are now sure now that tb jumps to tb1 */
1320 tb_next = tb1;
1321
1322 /* remove tb from the jmp_first list */
1323 ptb = &tb_next->jmp_first;
1324 for(;;) {
1325 tb1 = *ptb;
1326 n1 = (long)tb1 & 3;
1327 tb1 = (TranslationBlock *)((long)tb1 & ~3);
1328 if (n1 == n && tb1 == tb)
1329 break;
1330 ptb = &tb1->jmp_next[n1];
1331 }
1332 *ptb = tb->jmp_next[n];
1333 tb->jmp_next[n] = NULL;
1334
1335 /* suppress the jump to next tb in generated code */
1336 tb_reset_jump(tb, n);
1337
1338 /* suppress jumps in the tb on which we could have jumped */
1339 tb_reset_jump_recursive(tb_next);
1340 }
1341}
1342
1343void tb_reset_jump_recursive(TranslationBlock *tb)
1344{
1345 tb_reset_jump_recursive2(tb, 0);
1346 tb_reset_jump_recursive2(tb, 1);
1347}
1348
1349/* in deterministic execution mode, instructions doing device I/Os
1350 must be at the end of the TB */
1351void cpu_io_recompile(CPUArchState *env, uintptr_t retaddr)
1352{
1353 TranslationBlock *tb;
1354 uint32_t n, cflags;
1355 target_ulong pc, cs_base;
1356 uint64_t flags;
1357
1358 tb = tb_find_pc(retaddr);
1359 if (!tb) {
1360 cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p",
1361 (void*)retaddr);
1362 }
1363 n = env->icount_decr.u16.low + tb->icount;
1364 cpu_restore_state(tb, env, retaddr);
1365 /* Calculate how many instructions had been executed before the fault
1366 occurred. */
1367 n = n - env->icount_decr.u16.low;
1368 /* Generate a new TB ending on the I/O insn. */
1369 n++;
1370 /* On MIPS and SH, delay slot instructions can only be restarted if
1371 they were already the first instruction in the TB. If this is not
1372 the first instruction in a TB then re-execute the preceding
1373 branch. */
1374#if defined(TARGET_MIPS)
1375 if ((env->hflags & MIPS_HFLAG_BMASK) != 0 && n > 1) {
1376 env->active_tc.PC -= 4;
1377 env->icount_decr.u16.low++;
1378 env->hflags &= ~MIPS_HFLAG_BMASK;
1379 }
1380#elif defined(TARGET_SH4)
1381 if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0
1382 && n > 1) {
1383 env->pc -= 2;
1384 env->icount_decr.u16.low++;
1385 env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1386 }
1387#endif
1388 /* This should never happen. */
1389 if (n > CF_COUNT_MASK)
1390 cpu_abort(env, "TB too big during recompile");
1391
1392 cflags = n | CF_LAST_IO;
1393 pc = tb->pc;
1394 cs_base = tb->cs_base;
1395 flags = tb->flags;
1396 tb_phys_invalidate(tb, -1);
1397 /* FIXME: In theory this could raise an exception. In practice
1398 we have already translated the block once so it's probably ok. */
1399 tb_gen_code(env, pc, cs_base, flags, cflags);
1400 /* TODO: If env->pc != tb->pc (i.e. the faulting instruction was not
1401 the first in the TB) then we end up generating a whole new TB and
1402 repeating the fault, which is horribly inefficient.
1403 Better would be to execute just this insn uncached, or generate a
1404 second new TB. */
1405 cpu_resume_from_signal(env, NULL);
1406}
1407
1408#if !defined(CONFIG_USER_ONLY)
1409
1410void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
1411{
1412 int i, target_code_size, max_target_code_size;
1413 int direct_jmp_count, direct_jmp2_count, cross_page;
1414 TranslationBlock *tb;
1415
1416 target_code_size = 0;
1417 max_target_code_size = 0;
1418 cross_page = 0;
1419 direct_jmp_count = 0;
1420 direct_jmp2_count = 0;
1421 for(i = 0; i < tcg_ctx.tb_ctx.nb_tbs; i++) {
1422 tb = &tcg_ctx.tb_ctx.tbs[i];
1423 target_code_size += tb->size;
1424 if (tb->size > max_target_code_size)
1425 max_target_code_size = tb->size;
1426 if (tb->page_addr[1] != -1)
1427 cross_page++;
1428 if (tb->tb_next_offset[0] != 0xffff) {
1429 direct_jmp_count++;
1430 if (tb->tb_next_offset[1] != 0xffff) {
1431 direct_jmp2_count++;
1432 }
1433 }
1434 }
1435 /* XXX: avoid using doubles ? */
1436 cpu_fprintf(f, "Translation buffer state:\n");
1437 cpu_fprintf(f, "gen code size %td/%ld\n",
1438 code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size);
1439 cpu_fprintf(f, "TB count %d/%d\n",
1440 tcg_ctx.tb_ctx.nb_tbs, code_gen_max_blocks);
1441 cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
1442 tcg_ctx.tb_ctx.nb_tbs ? target_code_size / tcg_ctx.tb_ctx.nb_tbs : 0,
1443 max_target_code_size);
1444 cpu_fprintf(f, "TB avg host size %td bytes (expansion ratio: %0.1f)\n",
1445 tcg_ctx.tb_ctx.nb_tbs ? (code_gen_ptr - code_gen_buffer) / tcg_ctx.tb_ctx.nb_tbs : 0,
1446 target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
1447 cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
1448 cross_page,
1449 tcg_ctx.tb_ctx.nb_tbs ? (cross_page * 100) / tcg_ctx.tb_ctx.nb_tbs : 0);
1450 cpu_fprintf(f, "direct jump count %d (%d%%) (2 jumps=%d %d%%)\n",
1451 direct_jmp_count,
1452 tcg_ctx.tb_ctx.nb_tbs ? (direct_jmp_count * 100) / tcg_ctx.tb_ctx.nb_tbs : 0,
1453 direct_jmp2_count,
1454 tcg_ctx.tb_ctx.nb_tbs ? (direct_jmp2_count * 100) / tcg_ctx.tb_ctx.nb_tbs : 0);
1455 cpu_fprintf(f, "\nStatistics:\n");
1456 cpu_fprintf(f, "TB flush count %d\n", tcg_ctx.tb_ctx.tb_flush_count);
1457 cpu_fprintf(f, "TB invalidate count %d\n", tcg_ctx.tb_ctx.tb_phys_invalidate_count);
1458 cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count);
1459 tcg_dump_info(f, cpu_fprintf);
1460}
1461
1462#endif
1463
David 'Digit' Turner3dc53fc2014-01-17 01:23:40 +01001464void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr)
1465{
1466 unsigned int i;
1467
1468 /* Discard jump cache entries for any tb which might potentially
1469 overlap the flushed page. */
1470 i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
1471 memset (&env->tb_jmp_cache[i], 0,
1472 TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
1473
1474 i = tb_jmp_cache_hash_page(addr);
1475 memset (&env->tb_jmp_cache[i], 0,
1476 TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
1477}