#include "qemu-common.h"
#define NO_CPU_IO_DEFS
#include "cpu.h"
+#include "trace.h"
#include "disas/disas.h"
#include "tcg.h"
#if defined(CONFIG_USER_ONLY)
gen_intermediate_code(env, tb);
+ trace_translate_block(tb, tb->pc, tb->tc_ptr);
+
/* generate machine code */
gen_code_buf = tb->tc_ptr;
tb->tb_next_offset[0] = 0xffff;
gen_intermediate_code_pc(env, tb);
- if (use_icount) {
+ if (tb->cflags & CF_USE_ICOUNT) {
/* Reset the cycle counter to the start of the block. */
cpu->icount_decr.u16.low += tb->icount;
/* Clear the IO flag. */
tb = tb_find_pc(retaddr);
if (tb) {
cpu_restore_state_from_tb(cpu, tb, retaddr);
+ if (tb->cflags & CF_NOCACHE) {
+ /* one-shot translation, invalidate it immediately */
+ cpu->current_tb = NULL;
+ tb_phys_invalidate(tb, -1);
+ tb_free(tb);
+ }
return true;
}
return false;
}
#ifdef _WIN32
-static inline void map_exec(void *addr, long size)
+static __attribute__((unused)) void map_exec(void *addr, long size)
{
DWORD old_protect;
VirtualProtect(addr, size,
PAGE_EXECUTE_READWRITE, &old_protect);
}
#else
-static inline void map_exec(void *addr, long size)
+static __attribute__((unused)) void map_exec(void *addr, long size)
{
unsigned long start, end, page_size;
{
/* NOTE: we can always suppose that qemu_host_page_size >=
TARGET_PAGE_SIZE */
-#ifdef _WIN32
- SYSTEM_INFO system_info;
-
- GetSystemInfo(&system_info);
- qemu_real_host_page_size = system_info.dwPageSize;
-#else
qemu_real_host_page_size = getpagesize();
-#endif
if (qemu_host_page_size == 0) {
qemu_host_page_size = qemu_real_host_page_size;
}
#ifdef __mips__
if (cross_256mb(buf, tcg_ctx.code_gen_buffer_size)) {
- /* Try again, with the original still mapped, to avoid re-aquiring
+ /* Try again, with the original still mapped, to avoid re-acquiring
that 256mb crossing. This time don't specify an address. */
size_t size2, size1 = tcg_ctx.code_gen_buffer_size;
void *buf2 = mmap(NULL, size1, PROT_WRITE | PROT_READ | PROT_EXEC,
#else
static inline void *alloc_code_gen_buffer(void)
{
- void *buf = g_malloc(tcg_ctx.code_gen_buffer_size);
+ void *buf = g_try_malloc(tcg_ctx.code_gen_buffer_size);
if (buf == NULL) {
return NULL;
int code_gen_size;
phys_pc = get_page_addr_code(env, pc);
+ if (use_icount) {
+ cflags |= CF_USE_ICOUNT;
+ }
tb = tb_alloc(pc);
if (!tb) {
/* flush must be done */
return &tcg_ctx.tb_ctx.tbs[m_max];
}
-#if defined(TARGET_HAS_ICE) && !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
{
ram_addr_t ram_addr;
+ addr;
tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
}
-#endif /* TARGET_HAS_ICE && !defined(CONFIG_USER_ONLY) */
+#endif /* !defined(CONFIG_USER_ONLY) */
void tb_check_watchpoint(CPUState *cpu)
{
branch. */
#if defined(TARGET_MIPS)
if ((env->hflags & MIPS_HFLAG_BMASK) != 0 && n > 1) {
- env->active_tc.PC -= 4;
+ env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
cpu->icount_decr.u16.low++;
env->hflags &= ~MIPS_HFLAG_BMASK;
}
tcg_dump_info(f, cpu_fprintf);
}
+void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf)
+{
+ tcg_dump_op_count(f, cpu_fprintf);
+}
+
#else /* CONFIG_USER_ONLY */
void cpu_interrupt(CPUState *cpu, int mask)
struct walk_memory_regions_data {
walk_memory_regions_fn fn;
void *priv;
- uintptr_t start;
+ target_ulong start;
int prot;
};
static int walk_memory_regions_end(struct walk_memory_regions_data *data,
- abi_ulong end, int new_prot)
+ target_ulong end, int new_prot)
{
- if (data->start != -1ul) {
+ if (data->start != -1u) {
int rc = data->fn(data->priv, data->start, end, data->prot);
if (rc != 0) {
return rc;
}
}
- data->start = (new_prot ? end : -1ul);
+ data->start = (new_prot ? end : -1u);
data->prot = new_prot;
return 0;
}
static int walk_memory_regions_1(struct walk_memory_regions_data *data,
- abi_ulong base, int level, void **lp)
+ target_ulong base, int level, void **lp)
{
- abi_ulong pa;
+ target_ulong pa;
int i, rc;
if (*lp == NULL) {
void **pp = *lp;
for (i = 0; i < V_L2_SIZE; ++i) {
- pa = base | ((abi_ulong)i <<
+ pa = base | ((target_ulong)i <<
(TARGET_PAGE_BITS + V_L2_BITS * level));
rc = walk_memory_regions_1(data, pa, level - 1, pp + i);
if (rc != 0) {
data.fn = fn;
data.priv = priv;
- data.start = -1ul;
+ data.start = -1u;
data.prot = 0;
for (i = 0; i < V_L1_SIZE; i++) {
- int rc = walk_memory_regions_1(&data, (abi_ulong)i << V_L1_SHIFT,
+ int rc = walk_memory_regions_1(&data, (target_ulong)i << (V_L1_SHIFT + TARGET_PAGE_BITS),
V_L1_SHIFT / V_L2_BITS - 1, l1_map + i);
-
if (rc != 0) {
return rc;
}
return walk_memory_regions_end(&data, 0, 0);
}
-static int dump_region(void *priv, abi_ulong start,
- abi_ulong end, unsigned long prot)
+static int dump_region(void *priv, target_ulong start,
+ target_ulong end, unsigned long prot)
{
FILE *f = (FILE *)priv;
- (void) fprintf(f, TARGET_ABI_FMT_lx"-"TARGET_ABI_FMT_lx
- " "TARGET_ABI_FMT_lx" %c%c%c\n",
+ (void) fprintf(f, TARGET_FMT_lx"-"TARGET_FMT_lx
+ " "TARGET_FMT_lx" %c%c%c\n",
start, end, end - start,
((prot & PAGE_READ) ? 'r' : '-'),
((prot & PAGE_WRITE) ? 'w' : '-'),
/* dump memory mappings */
void page_dump(FILE *f)
{
- const int length = sizeof(abi_ulong) * 2;
+ const int length = sizeof(target_ulong) * 2;
(void) fprintf(f, "%-*s %-*s %-*s %s\n",
length, "start", length, "end", length, "size", "prot");
walk_memory_regions(f, dump_region);
guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
- assert(end < ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
+ assert(end < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
#endif
assert(start < end);
guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
- assert(start < ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
+ assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
#endif
if (len == 0) {