Add option to disable TB cache, by Herve Poussineau.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3930 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
ths 2008-01-23 19:01:12 +00:00
parent c304f7e23d
commit 40a2e657a5
4 changed files with 110 additions and 2 deletions

View file

@ -20,6 +20,7 @@
#include "config.h"
#include "exec.h"
#include "disas.h"
#include <string.h>
#if !defined(CONFIG_SOFTMMU)
#undef EAX
@ -40,6 +41,9 @@ int tb_invalidated_flag;
//#define DEBUG_EXEC
//#define DEBUG_SIGNAL
/* translation settings */
int translation_settings = 0;
#define SAVE_GLOBALS()
#define RESTORE_GLOBALS()
@ -120,6 +124,56 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
longjmp(env->jmp_env, 1);
}
CPUTranslationSetting cpu_translation_settings[] = {
{ CPU_SETTING_NO_CACHE, "no-cache",
"Do not use translation blocks cache (very slow!)" },
{ 0, NULL, NULL },
};
void cpu_set_translation_settings(int translation_flags)
{
translation_settings = translation_flags;
}
static int cmp1(const char *s1, int n, const char *s2)
{
if (strlen(s2) != n)
return 0;
return memcmp(s1, s2, n) == 0;
}
/* takes a comma separated list of translation settings. Return 0 if error. */
int cpu_str_to_translation_mask(const char *str)
{
CPUTranslationSetting *setting;
int mask;
const char *p, *p1;
p = str;
mask = 0;
for(;;) {
p1 = strchr(p, ',');
if (!p1)
p1 = p + strlen(p);
if(cmp1(p,p1-p,"all")) {
for(setting = cpu_translation_settings; setting->mask != 0; setting++) {
mask |= setting->mask;
}
} else {
for(setting = cpu_translation_settings; setting->mask != 0; setting++) {
if (cmp1(p, p1 - p, setting->name))
goto found;
}
return 0;
}
found:
mask |= setting->mask;
if (*p1 != ',')
break;
p = p1 + 1;
}
return mask;
}
static TranslationBlock *tb_find_slow(target_ulong pc,
target_ulong cs_base,
@ -141,6 +195,9 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
phys_pc = get_phys_addr_code(env, pc);
phys_page1 = phys_pc & TARGET_PAGE_MASK;
phys_page2 = -1;
if (translation_settings & CPU_SETTING_NO_CACHE)
goto not_found;
h = tb_phys_hash_func(phys_pc);
ptb1 = &tb_phys_hash[h];
for(;;) {
@ -264,7 +321,10 @@ static inline TranslationBlock *tb_find_fast(void)
#else
#error unsupported CPU
#endif
tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
if (translation_settings & CPU_SETTING_NO_CACHE)
tb = NULL;
else
tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base ||
tb->flags != flags, 0)) {
tb = tb_find_slow(pc, cs_base, flags);