target-alpha: Turn CPU definitions into subclasses
Make TYPE_ALPHA_CPU abstract and add types <name>-alpha-cpu. Use type inheritence, and turn "2*" models into aliases. Move cpu_alpha_init() to cpu.c and split out CPU realization. Default to creating type "ev67-alpha-cpu" as before. Signed-off-by: Andreas Färber <afaerber@suse.de> Acked-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
c92458538f
commit
0c28246fcd
|
@ -21,8 +21,175 @@
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void alpha_cpu_realize(Object *obj, Error **errp)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(obj);
|
||||||
|
|
||||||
|
qemu_init_vcpu(&cpu->env);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Models */
|
||||||
|
|
||||||
|
#define TYPE(model) model "-" TYPE_ALPHA_CPU
|
||||||
|
|
||||||
|
typedef struct AlphaCPUAlias {
|
||||||
|
const char *alias;
|
||||||
|
const char *typename;
|
||||||
|
} AlphaCPUAlias;
|
||||||
|
|
||||||
|
static const AlphaCPUAlias alpha_cpu_aliases[] = {
|
||||||
|
{ "21064", TYPE("ev4") },
|
||||||
|
{ "21164", TYPE("ev5") },
|
||||||
|
{ "21164a", TYPE("ev56") },
|
||||||
|
{ "21164pc", TYPE("pca56") },
|
||||||
|
{ "21264", TYPE("ev6") },
|
||||||
|
{ "21264a", TYPE("ev67") },
|
||||||
|
};
|
||||||
|
|
||||||
|
static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model)
|
||||||
|
{
|
||||||
|
ObjectClass *oc = NULL;
|
||||||
|
char *typename;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (cpu_model == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
oc = object_class_by_name(cpu_model);
|
||||||
|
if (oc != NULL) {
|
||||||
|
return oc;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(alpha_cpu_aliases); i++) {
|
||||||
|
if (strcmp(cpu_model, alpha_cpu_aliases[i].alias) == 0) {
|
||||||
|
oc = object_class_by_name(alpha_cpu_aliases[i].typename);
|
||||||
|
assert(oc != NULL);
|
||||||
|
return oc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typename = g_strdup_printf("%s-" TYPE_ALPHA_CPU, cpu_model);
|
||||||
|
oc = object_class_by_name(typename);
|
||||||
|
g_free(typename);
|
||||||
|
return oc;
|
||||||
|
}
|
||||||
|
|
||||||
|
AlphaCPU *cpu_alpha_init(const char *cpu_model)
|
||||||
|
{
|
||||||
|
AlphaCPU *cpu;
|
||||||
|
CPUAlphaState *env;
|
||||||
|
ObjectClass *cpu_class;
|
||||||
|
|
||||||
|
cpu_class = alpha_cpu_class_by_name(cpu_model);
|
||||||
|
if (cpu_class == NULL) {
|
||||||
|
/* Default to ev67; no reason not to emulate insns by default. */
|
||||||
|
cpu_class = object_class_by_name(TYPE("ev67"));
|
||||||
|
}
|
||||||
|
cpu = ALPHA_CPU(object_new(object_class_get_name(cpu_class)));
|
||||||
|
env = &cpu->env;
|
||||||
|
|
||||||
|
env->cpu_model_str = cpu_model;
|
||||||
|
|
||||||
|
alpha_cpu_realize(OBJECT(cpu), NULL);
|
||||||
|
return cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ev4_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(obj);
|
||||||
|
CPUAlphaState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->implver = IMPLVER_2106x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo ev4_cpu_type_info = {
|
||||||
|
.name = TYPE("ev4"),
|
||||||
|
.parent = TYPE_ALPHA_CPU,
|
||||||
|
.instance_init = ev4_cpu_initfn,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ev5_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(obj);
|
||||||
|
CPUAlphaState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->implver = IMPLVER_21164;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo ev5_cpu_type_info = {
|
||||||
|
.name = TYPE("ev5"),
|
||||||
|
.parent = TYPE_ALPHA_CPU,
|
||||||
|
.instance_init = ev5_cpu_initfn,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ev56_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(obj);
|
||||||
|
CPUAlphaState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->amask |= AMASK_BWX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo ev56_cpu_type_info = {
|
||||||
|
.name = TYPE("ev56"),
|
||||||
|
.parent = TYPE("ev5"),
|
||||||
|
.instance_init = ev56_cpu_initfn,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pca56_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(obj);
|
||||||
|
CPUAlphaState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->amask |= AMASK_MVI;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo pca56_cpu_type_info = {
|
||||||
|
.name = TYPE("pca56"),
|
||||||
|
.parent = TYPE("ev56"),
|
||||||
|
.instance_init = pca56_cpu_initfn,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ev6_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(obj);
|
||||||
|
CPUAlphaState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->implver = IMPLVER_21264;
|
||||||
|
env->amask = AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo ev6_cpu_type_info = {
|
||||||
|
.name = TYPE("ev6"),
|
||||||
|
.parent = TYPE_ALPHA_CPU,
|
||||||
|
.instance_init = ev6_cpu_initfn,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ev67_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(obj);
|
||||||
|
CPUAlphaState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->amask |= AMASK_CIX | AMASK_PREFETCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo ev67_cpu_type_info = {
|
||||||
|
.name = TYPE("ev67"),
|
||||||
|
.parent = TYPE("ev6"),
|
||||||
|
.instance_init = ev67_cpu_initfn,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const TypeInfo ev68_cpu_type_info = {
|
||||||
|
.name = TYPE("ev68"),
|
||||||
|
.parent = TYPE("ev67"),
|
||||||
|
};
|
||||||
|
|
||||||
static void alpha_cpu_initfn(Object *obj)
|
static void alpha_cpu_initfn(Object *obj)
|
||||||
{
|
{
|
||||||
AlphaCPU *cpu = ALPHA_CPU(obj);
|
AlphaCPU *cpu = ALPHA_CPU(obj);
|
||||||
|
@ -31,6 +198,8 @@ static void alpha_cpu_initfn(Object *obj)
|
||||||
cpu_exec_init(env);
|
cpu_exec_init(env);
|
||||||
tlb_flush(env, 1);
|
tlb_flush(env, 1);
|
||||||
|
|
||||||
|
alpha_translate_init();
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
env->ps = PS_USER_MODE;
|
env->ps = PS_USER_MODE;
|
||||||
cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
|
cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
|
||||||
|
@ -46,13 +215,20 @@ static const TypeInfo alpha_cpu_type_info = {
|
||||||
.parent = TYPE_CPU,
|
.parent = TYPE_CPU,
|
||||||
.instance_size = sizeof(AlphaCPU),
|
.instance_size = sizeof(AlphaCPU),
|
||||||
.instance_init = alpha_cpu_initfn,
|
.instance_init = alpha_cpu_initfn,
|
||||||
.abstract = false,
|
.abstract = true,
|
||||||
.class_size = sizeof(AlphaCPUClass),
|
.class_size = sizeof(AlphaCPUClass),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void alpha_cpu_register_types(void)
|
static void alpha_cpu_register_types(void)
|
||||||
{
|
{
|
||||||
type_register_static(&alpha_cpu_type_info);
|
type_register_static(&alpha_cpu_type_info);
|
||||||
|
type_register_static(&ev4_cpu_type_info);
|
||||||
|
type_register_static(&ev5_cpu_type_info);
|
||||||
|
type_register_static(&ev56_cpu_type_info);
|
||||||
|
type_register_static(&pca56_cpu_type_info);
|
||||||
|
type_register_static(&ev6_cpu_type_info);
|
||||||
|
type_register_static(&ev67_cpu_type_info);
|
||||||
|
type_register_static(&ev68_cpu_type_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
type_init(alpha_cpu_register_types)
|
type_init(alpha_cpu_register_types)
|
||||||
|
|
|
@ -425,6 +425,8 @@ enum {
|
||||||
IR_ZERO = 31,
|
IR_ZERO = 31,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void alpha_translate_init(void);
|
||||||
|
|
||||||
AlphaCPU *cpu_alpha_init(const char *cpu_model);
|
AlphaCPU *cpu_alpha_init(const char *cpu_model);
|
||||||
|
|
||||||
static inline CPUAlphaState *cpu_init(const char *cpu_model)
|
static inline CPUAlphaState *cpu_init(const char *cpu_model)
|
||||||
|
|
|
@ -90,7 +90,7 @@ static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
|
||||||
|
|
||||||
#include "gen-icount.h"
|
#include "gen-icount.h"
|
||||||
|
|
||||||
static void alpha_translate_init(void)
|
void alpha_translate_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -3493,62 +3493,6 @@ void gen_intermediate_code_pc (CPUAlphaState *env, struct TranslationBlock *tb)
|
||||||
gen_intermediate_code_internal(env, tb, 1);
|
gen_intermediate_code_internal(env, tb, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cpu_def_t {
|
|
||||||
const char *name;
|
|
||||||
int implver, amask;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct cpu_def_t cpu_defs[] = {
|
|
||||||
{ "ev4", IMPLVER_2106x, 0 },
|
|
||||||
{ "ev5", IMPLVER_21164, 0 },
|
|
||||||
{ "ev56", IMPLVER_21164, AMASK_BWX },
|
|
||||||
{ "pca56", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
|
|
||||||
{ "ev6", IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
|
|
||||||
{ "ev67", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
|
|
||||||
| AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
|
|
||||||
{ "ev68", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
|
|
||||||
| AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
|
|
||||||
{ "21064", IMPLVER_2106x, 0 },
|
|
||||||
{ "21164", IMPLVER_21164, 0 },
|
|
||||||
{ "21164a", IMPLVER_21164, AMASK_BWX },
|
|
||||||
{ "21164pc", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
|
|
||||||
{ "21264", IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
|
|
||||||
{ "21264a", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
|
|
||||||
| AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), }
|
|
||||||
};
|
|
||||||
|
|
||||||
AlphaCPU *cpu_alpha_init(const char *cpu_model)
|
|
||||||
{
|
|
||||||
AlphaCPU *cpu;
|
|
||||||
CPUAlphaState *env;
|
|
||||||
int implver, amask, i, max;
|
|
||||||
|
|
||||||
cpu = ALPHA_CPU(object_new(TYPE_ALPHA_CPU));
|
|
||||||
env = &cpu->env;
|
|
||||||
|
|
||||||
alpha_translate_init();
|
|
||||||
|
|
||||||
/* Default to ev67; no reason not to emulate insns by default. */
|
|
||||||
implver = IMPLVER_21264;
|
|
||||||
amask = (AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_MVI
|
|
||||||
| AMASK_TRAP | AMASK_PREFETCH);
|
|
||||||
|
|
||||||
max = ARRAY_SIZE(cpu_defs);
|
|
||||||
for (i = 0; i < max; i++) {
|
|
||||||
if (strcmp (cpu_model, cpu_defs[i].name) == 0) {
|
|
||||||
implver = cpu_defs[i].implver;
|
|
||||||
amask = cpu_defs[i].amask;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
env->implver = implver;
|
|
||||||
env->amask = amask;
|
|
||||||
env->cpu_model_str = cpu_model;
|
|
||||||
|
|
||||||
qemu_init_vcpu(env);
|
|
||||||
return cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos)
|
void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos)
|
||||||
{
|
{
|
||||||
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
|
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
|
||||||
|
|
Loading…
Reference in a new issue