exec-all.h revision fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0af
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * internal execution defines for qemu
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  Copyright (c) 2003 Fabrice Bellard
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This library is free software; you can redistribute it and/or
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * modify it under the terms of the GNU Lesser General Public
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * License as published by the Free Software Foundation; either
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * version 2 of the License, or (at your option) any later version.
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This library is distributed in the hope that it will be useful,
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Lesser General Public License for more details.
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * You should have received a copy of the GNU Lesser General Public
172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * License along with this library; if not, see <http://www.gnu.org/licenses/>.
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _EXEC_ALL_H_
215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define _EXEC_ALL_H_
225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h"
240e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner#include "exec/cpu-common.h"
250e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner#include "exec/cpu-all.h"
265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* allow to see translation results - the slowdown should be negligible, so we leave it */
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DEBUG_DISAS
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner/* Page tracking code uses ram addresses in system mode, and virtual
31280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner   addresses in userspace mode.  Define tb_page_addr_t to be an appropriate
32280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner   type.  */
33280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#if defined(CONFIG_USER_ONLY)
34280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnertypedef abi_ulong tb_page_addr_t;
35280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#else
36280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnertypedef ram_addr_t tb_page_addr_t;
37280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#endif
38280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* is_jmp field values */
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DISAS_NEXT    0 /* next instruction can be analyzed */
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DISAS_JUMP    1 /* only pc was modified dynamically */
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DISAS_UPDATE  2 /* cpu state was modified dynamically */
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DISAS_TB_JUMP 3 /* only pc was modified statically */
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
454d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnerstruct TranslationBlock;
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TranslationBlock TranslationBlock;
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: make safe guess about sizes */
49fb02a555a0a2a34e84389d9e441749cc58428531David 'Digit' Turner#define MAX_OP_PER_INSTR 208
50fb02a555a0a2a34e84389d9e441749cc58428531David 'Digit' Turner
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* A Call op needs up to 6 + 2N parameters (N = number of arguments).  */
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_OPC_PARAM 10
53bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner#define OPC_BUF_SIZE 2048
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Maximum size a TCG op can expand to.  This is complicated because a
572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner   single op may require several host instructions and register reloads.
582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner   For now take a wild guess at 192 bytes, which should allow at least
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   a couple of fixup instructions per argument.  */
602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#define TCG_MAX_OP_SIZE 192
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
64e1e03df288d5a44bfbffbd86588395c7cbbc27dfDavid 'Digit' Turner#include "qemu/log.h"
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
664d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);
674d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid gen_intermediate_code_pc(CPUArchState *env, struct TranslationBlock *tb);
684d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
694d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner                          int pc_pos);
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned long code_gen_max_block_size(void);
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_gen_init(void);
73ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' Turnervoid tcg_exec_init(unsigned long tb_size);
744d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnerint cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 int *gen_code_size_ptr);
763e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnerbool cpu_restore_state(CPUArchState *env, uintptr_t searched_pc);
773e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner
784d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid QEMU_NORETURN cpu_resume_from_signal(CPUArchState *env1, void *puc);
7985c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid QEMU_NORETURN cpu_io_recompile(CPUArchState *env, uintptr_t retaddr);
803e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' TurnerTranslationBlock *tb_gen_code(CPUArchState *env,
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              target_ulong pc, target_ulong cs_base, int flags,
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              int cflags);
834d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid cpu_exec_init(CPUArchState *env);
8485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid QEMU_NORETURN cpu_loop_exit(CPUArchState *env1);
8585c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerint page_unprotect(target_ulong address, uintptr_t pc, void *puc);
863e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnervoid tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   int is_cpu_write_access);
883e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnervoid tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
893e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner                              int is_cpu_write_access);
901348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#if !defined(CONFIG_USER_ONLY)
913e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner/* cputlb.c */
924d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid tlb_flush_page(CPUArchState *env, target_ulong addr);
934d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid tlb_flush(CPUArchState *env, int flush_global);
940d8b235c0c6c02de86a4e7415d574175b4518ff0David 'Digit' Turnervoid tlb_set_page(CPUArchState *env, target_ulong vaddr,
950d8b235c0c6c02de86a4e7415d574175b4518ff0David 'Digit' Turner                  hwaddr paddr, int prot,
960d8b235c0c6c02de86a4e7415d574175b4518ff0David 'Digit' Turner                  int mmu_idx, target_ulong size);
97ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' Turnervoid tb_reset_jump_recursive(TranslationBlock *tb);
983e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnervoid tb_invalidate_phys_addr(hwaddr addr);
991348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#else
1001348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerstatic inline void tlb_flush_page(CPUArchState *env, target_ulong addr)
1011348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner{
1021348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner}
1031348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner
1041348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerstatic inline void tlb_flush(CPUArchState *env, int flush_global)
1051348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner{
1061348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner}
1071348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#endif
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1093dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turnertypedef struct PhysPageDesc {
1103dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner    /* offset in host memory of the page + io_index in the low bits */
1113dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner    ram_addr_t phys_offset;
1123dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner    ram_addr_t region_offset;
1133dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner} PhysPageDesc;
1143dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner
1153dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' TurnerPhysPageDesc *phys_page_find(hwaddr index);
116ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' TurnerPhysPageDesc *phys_page_find_alloc(hwaddr index, int alloc);
1173dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner
1183dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turnerint io_mem_watch;
1193dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_PHYS_HASH_BITS     15
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_PHYS_HASH_SIZE     (1 << CODE_GEN_PHYS_HASH_BITS)
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* estimated block size for TB allocation */
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: use a per code average code fragment size and modulate it
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   according to the host CPU */
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(CONFIG_SOFTMMU)
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_AVG_BLOCK_SIZE 128
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_AVG_BLOCK_SIZE 64
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1344d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner#if defined(__arm__) || defined(_ARCH_PPC) \
1354d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner    || defined(__x86_64__) || defined(__i386__) \
1364d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner    || defined(__sparc__) || defined(__aarch64__) \
1374d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner    || defined(CONFIG_TCG_INTERPRETER)
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USE_DIRECT_JUMP
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct TranslationBlock {
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong cs_base; /* CS base for this block */
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t flags; /* flags defining in which context the code was generated */
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t size;      /* size of target code for this block (1 <=
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           size <= TARGET_PAGE_SIZE) */
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t cflags;    /* compile flags */
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CF_COUNT_MASK  0x7fff
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CF_LAST_IO     0x8000 /* Last insn may be an IO access.  */
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *tc_ptr;    /* pointer to the translated code */
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* next matching tb for physical address. */
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct TranslationBlock *phys_hash_next;
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* first and second physical page containing code. The lower bit
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       of the pointer tells the index in page_next[] */
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct TranslationBlock *page_next[2];
15785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    tb_page_addr_t page_addr[2];
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* the following data are used to directly call another TB from
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       the code of this one. */
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t tb_next_offset[2]; /* offset of original jump target */
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef USE_DIRECT_JUMP
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
16585c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    uintptr_t tb_next[2]; /* address of jump generated code */
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* list of TBs jumping to this one. This is a circular list using
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       the two least significant bits of the pointers to tell what is
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 =
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       jmp_first */
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct TranslationBlock *jmp_next[2];
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct TranslationBlock *jmp_first;
173171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner    uint32_t icount;
1745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1755bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK
1765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Maps PCs in this translation block to corresponding PCs in guest address
1775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * space. The array is arranged in such way, that every even entry contains
1785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * PC in the translation block, followed by an odd entry that contains
1795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * guest PC corresponding to that PC in the translation block. This
1805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * arrangement is set by tcg_gen_code_common that initializes this array
1815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * when performing guest code translation. */
182c5111a01ca209a29fdcb1a9a8917cc08ae5af9cbAndrey Petrov    uintptr_t*   tpc2gpc;
1835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Number of pairs (pc_tb, pc_guest) in tpc2gpc array. */
1845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    unsigned int    tpc2gpc_pairs;
1855bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif  // CONFIG_ANDROID_MEMCHECK
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1881348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#include "exec/spinlock.h"
1891348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner
1901348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnertypedef struct TBContext TBContext;
1911348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner
1921348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerstruct TBContext {
1931348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner
1941348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    TranslationBlock *tbs;
1951348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
1961348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    int nb_tbs;
1971348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    /* any access to the tbs or the page table must use this lock */
1981348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    spinlock_t tb_lock;
1991348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner
2001348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    /* statistics */
2011348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    int tb_flush_count;
2021348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    int tb_phys_invalidate_count;
2031348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner
2041348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    int tb_invalidated_flag;
2051348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner};
2061348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong tmp;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong tmp;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    | (tmp & TB_JMP_ADDR_MASK));
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22285c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerstatic inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
224280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner    return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1);
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2275bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK
2285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Gets translated PC for a given (translated PC, guest PC) pair.
2295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
2305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  Translated PC, or NULL if pair index was too large.
2315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
2325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline target_ulong
2335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinetb_get_tb_pc(const TranslationBlock* tb, unsigned int pair)
2345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
2355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return (tb->tpc2gpc != NULL && pair < tb->tpc2gpc_pairs) ?
2365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                                                    tb->tpc2gpc[pair * 2] : 0;
2375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
2385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Gets guest PC for a given (translated PC, guest PC) pair.
2405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
2415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  Guest PC, or NULL if pair index was too large.
2425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
2435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline target_ulong
2445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinetb_get_guest_pc(const TranslationBlock* tb, unsigned int pair)
2455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
2465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return (tb->tpc2gpc != NULL && pair < tb->tpc2gpc_pairs) ?
2475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            tb->tpc2gpc[pair * 2 + 1] : 0;
2485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
2495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Gets guest PC for a given translated PC.
2515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
2525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  Guest PC for a given translated PC, or NULL if there was no pair, matching
2535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  translated PC in tb's tpc2gpc array.
2545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
2555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline target_ulong
2565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinetb_search_guest_pc_from_tb_pc(const TranslationBlock* tb, target_ulong tb_pc)
2575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
2585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (tb->tpc2gpc != NULL && tb->tpc2gpc_pairs != 0) {
2595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        unsigned int m_min = 0;
2605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        unsigned int m_max = (tb->tpc2gpc_pairs - 1) << 1;
2615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* Make sure that tb_pc is within TB array. */
2625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (tb_pc < tb->tpc2gpc[0]) {
2635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            return 0;
2645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
2655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        while (m_min <= m_max) {
2665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            const unsigned int m = ((m_min + m_max) >> 1) & ~1;
2675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (tb_pc < tb->tpc2gpc[m]) {
2685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                m_max = m - 2;
2695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            } else if (m == m_max || tb_pc < tb->tpc2gpc[m + 2]) {
2705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                return tb->tpc2gpc[m + 1];
2715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            } else {
2725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                m_min = m + 2;
2735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            }
2745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
2755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return tb->tpc2gpc[m_max + 1];
2765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return 0;
2785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
2795bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif  // CONFIG_ANDROID_MEMCHECK
2805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tb_free(TranslationBlock *tb);
2824d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid tb_flush(CPUArchState *env);
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tb_link_phys(TranslationBlock *tb,
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  target_ulong phys_pc, target_ulong phys_page2);
28585c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
286ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' Turnervoid tb_invalidate_phys_page_fast0(hwaddr start, int len);
287ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' Turner
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern uint8_t *code_gen_ptr;
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern int code_gen_max_blocks;
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(USE_DIRECT_JUMP)
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29385c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#if defined(CONFIG_TCG_INTERPRETER)
29485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerstatic inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
29585c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner{
29685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    /* patch the branch destination */
29785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
29885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    /* no need to flush icache explicitly */
29985c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner}
30085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#elif defined(_ARCH_PPC)
30185c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tb_set_jmp_target1 ppc_tb_set_jmp_target
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__i386__) || defined(__x86_64__)
30485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerstatic inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* patch the branch destination */
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* no need to flush icache explicitly */
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
31085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#elif defined(__aarch64__)
31185c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);
31285c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#define tb_set_jmp_target1 aarch64_tb_set_jmp_target
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__arm__)
31485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerstatic inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
31685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#if !QEMU_GNUC_PREREQ(4, 1)
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    register unsigned long _beg __asm ("a1");
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    register unsigned long _end __asm ("a2");
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    register unsigned long _flg __asm ("a3");
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */
3232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    *(uint32_t *)jmp_addr =
3242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        (*(uint32_t *)jmp_addr & ~0xffffff)
3252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        | (((addr - (jmp_addr + 8)) >> 2) & 0xffffff);
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if QEMU_GNUC_PREREQ(4, 1)
32885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    __builtin___clear_cache((char *) jmp_addr, (char *) jmp_addr + 4);
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* flush icache */
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    _beg = jmp_addr;
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    _end = jmp_addr + 4;
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    _flg = 0;
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
33785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#elif defined(__sparc__)
33885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
33985c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#else
34085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#error tb_set_jmp_target1 is missing
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tb_set_jmp_target(TranslationBlock *tb,
34485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner                                     int n, uintptr_t addr)
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
34685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    uint16_t offset = tb->tb_jmp_offset[n];
34785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr);
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    offset = tb->tb_jmp_offset[n + 2];
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (offset != 0xffff)
35085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner        tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr);
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* set the jump target */
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tb_set_jmp_target(TranslationBlock *tb,
35785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner                                     int n, uintptr_t addr)
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb->tb_next[n] = addr;
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tb_add_jump(TranslationBlock *tb, int n,
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               TranslationBlock *tb_next)
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* NOTE: this test is only needed for thread safety */
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!tb->jmp_next[n]) {
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* patch the native jump address */
37085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner        tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* add in TB jmp circular list */
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tb->jmp_next[n] = tb_next->jmp_first;
37485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner        tb_next->jmp_first = (TranslationBlock *)((uintptr_t)(tb) | (n));
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3781348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner/* GETRA is the true target of the return instruction that we'll execute,
3791348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner   defined here for simplicity of defining the follow-up macros.  */
3801348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#if defined(CONFIG_TCG_INTERPRETER)
3811348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerextern uintptr_t tci_tb_ptr;
3821348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner# define GETRA() tci_tb_ptr
3831348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#else
3841348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner# define GETRA() \
3851348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner    ((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0)))
3861348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#endif
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3881348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner/* The true return address will often point to a host insn that is part of
3891348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner   the next translated guest insn.  Adjust the address backward to point to
3901348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner   the middle of the call insn.  Subtracting one would do the job except for
3911348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner   several compressed mode architectures (arm, mips) which set the low bit
3921348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner   to indicate the compressed mode; subtracting two works around that.  It
3931348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner   is also the case that there are no host isas that contain a call insn
3941348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner   smaller than 4 bytes, so we don't worry about special-casing this.  */
3951348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#if defined(CONFIG_TCG_INTERPRETER)
3961348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner# define GETPC_ADJ   0
3971348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#else
3981348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner# define GETPC_ADJ   2
3991348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#endif
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
401eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner#define GETPC()  (GETRA() - GETPC_ADJ)
402eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner
4031348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#if !defined(CONFIG_USER_ONLY)
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4051348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnervoid phys_mem_set_alloc(void *(*alloc)(size_t));
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4073e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' TurnerTranslationBlock *tb_find_pc(uintptr_t pc_ptr);
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
409fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turneruint64_t io_mem_read(int index, hwaddr addr, unsigned size);
410fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turnervoid io_mem_write(int index, hwaddr addr, uint64_t value, unsigned size);
411fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turner
412fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turnerextern CPUWriteMemoryFunc *_io_mem_write[IO_MEM_NB_ENTRIES][4];
413fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turnerextern CPUReadMemoryFunc *_io_mem_read[IO_MEM_NB_ENTRIES][4];
4141348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerextern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
416eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turnervoid tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
417eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner              uintptr_t retaddr);
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
419852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_defs.h"
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ACCESS_TYPE (NB_MMU_MODES + 1)
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MEMSUFFIX _code
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define env cpu_single_env
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DATA_SIZE 1
426852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_header.h"
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DATA_SIZE 2
429852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_header.h"
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DATA_SIZE 4
432852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_header.h"
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DATA_SIZE 8
435852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_header.h"
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef ACCESS_TYPE
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef MEMSUFFIX
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef env
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(CONFIG_USER_ONLY)
4443e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnerstatic inline tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return addr;
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
44901ee5b8ded901c76731bab7a12a87c2002479014David 'Digit' Turnertb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr);
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4524d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnertypedef void (CPUDebugExcpHandler)(CPUArchState *env);
4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4541348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnervoid cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* vl.c */
4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern int singlestep;
4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4593e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner/* cpu-exec.c */
4603e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnerextern volatile sig_atomic_t exit_request;
4613e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner
4629b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner/* Deterministic execution requires that IO only be performed on the last
4639b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner   instruction of a TB so that interrupts take effect immediately.  */
4649b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turnerstatic inline int can_do_io(CPUArchState *env)
4659b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner{
46685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    if (!use_icount) {
4679b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner        return 1;
46885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    }
4699b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner    /* If not executing code then assume we are ok.  */
4703e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner    if (env->current_tb == NULL) {
4719b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner        return 1;
47285c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    }
4739b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner    return env->can_do_io != 0;
4749b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner}
4759b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
477