CPU feature selection support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4399 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
0828b4485a
commit
64a88d5d3a
@ -43,6 +43,7 @@
|
|||||||
#define TT_TOVF 0x0a
|
#define TT_TOVF 0x0a
|
||||||
#define TT_EXTINT 0x10
|
#define TT_EXTINT 0x10
|
||||||
#define TT_CODE_ACCESS 0x21
|
#define TT_CODE_ACCESS 0x21
|
||||||
|
#define TT_UNIMP_FLUSH 0x25
|
||||||
#define TT_DATA_ACCESS 0x29
|
#define TT_DATA_ACCESS 0x29
|
||||||
#define TT_DIV_ZERO 0x2a
|
#define TT_DIV_ZERO 0x2a
|
||||||
#define TT_NCP_INSN 0x24
|
#define TT_NCP_INSN 0x24
|
||||||
@ -52,6 +53,7 @@
|
|||||||
#define TT_TMISS 0x09
|
#define TT_TMISS 0x09
|
||||||
#define TT_CODE_ACCESS 0x0a
|
#define TT_CODE_ACCESS 0x0a
|
||||||
#define TT_ILL_INSN 0x10
|
#define TT_ILL_INSN 0x10
|
||||||
|
#define TT_UNIMP_FLUSH TT_ILL_INSN
|
||||||
#define TT_PRIV_INSN 0x11
|
#define TT_PRIV_INSN 0x11
|
||||||
#define TT_NFPU_INSN 0x20
|
#define TT_NFPU_INSN 0x20
|
||||||
#define TT_FP_EXCP 0x21
|
#define TT_FP_EXCP 0x21
|
||||||
@ -244,9 +246,7 @@ typedef struct CPUSPARCState {
|
|||||||
/* temporary float registers */
|
/* temporary float registers */
|
||||||
float32 ft0, ft1;
|
float32 ft0, ft1;
|
||||||
float64 dt0, dt1;
|
float64 dt0, dt1;
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
float128 qt0, qt1;
|
float128 qt0, qt1;
|
||||||
#endif
|
|
||||||
float_status fp_status;
|
float_status fp_status;
|
||||||
#if defined(TARGET_SPARC64)
|
#if defined(TARGET_SPARC64)
|
||||||
#define MAXTL 4
|
#define MAXTL 4
|
||||||
@ -272,7 +272,32 @@ typedef struct CPUSPARCState {
|
|||||||
void *hstick; // UA 2005
|
void *hstick; // UA 2005
|
||||||
#endif
|
#endif
|
||||||
target_ulong t1, t2;
|
target_ulong t1, t2;
|
||||||
|
uint32_t features;
|
||||||
} CPUSPARCState;
|
} CPUSPARCState;
|
||||||
|
|
||||||
|
#define CPU_FEATURE_FLOAT (1 << 0)
|
||||||
|
#define CPU_FEATURE_FLOAT128 (1 << 1)
|
||||||
|
#define CPU_FEATURE_SWAP (1 << 2)
|
||||||
|
#define CPU_FEATURE_MUL (1 << 3)
|
||||||
|
#define CPU_FEATURE_DIV (1 << 4)
|
||||||
|
#define CPU_FEATURE_FLUSH (1 << 5)
|
||||||
|
#define CPU_FEATURE_FSQRT (1 << 6)
|
||||||
|
#define CPU_FEATURE_FMUL (1 << 7)
|
||||||
|
#define CPU_FEATURE_VIS1 (1 << 8)
|
||||||
|
#define CPU_FEATURE_VIS2 (1 << 9)
|
||||||
|
#ifndef TARGET_SPARC64
|
||||||
|
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
|
||||||
|
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
|
||||||
|
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
||||||
|
CPU_FEATURE_FMUL)
|
||||||
|
#else
|
||||||
|
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
|
||||||
|
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
|
||||||
|
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
||||||
|
CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
|
||||||
|
CPU_FEATURE_VIS2)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TARGET_SPARC64)
|
#if defined(TARGET_SPARC64)
|
||||||
#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
|
#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
|
||||||
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
||||||
@ -292,7 +317,6 @@ typedef struct CPUSPARCState {
|
|||||||
CPUSPARCState *cpu_sparc_init(const char *cpu_model);
|
CPUSPARCState *cpu_sparc_init(const char *cpu_model);
|
||||||
void gen_intermediate_code_init(CPUSPARCState *env);
|
void gen_intermediate_code_init(CPUSPARCState *env);
|
||||||
int cpu_sparc_exec(CPUSPARCState *s);
|
int cpu_sparc_exec(CPUSPARCState *s);
|
||||||
int cpu_sparc_close(CPUSPARCState *s);
|
|
||||||
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
|
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
|
||||||
...));
|
...));
|
||||||
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
|
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
|
||||||
|
@ -39,10 +39,8 @@ register uint32_t T2 asm(AREG3);
|
|||||||
#define FT1 (env->ft1)
|
#define FT1 (env->ft1)
|
||||||
#define DT0 (env->dt0)
|
#define DT0 (env->dt0)
|
||||||
#define DT1 (env->dt1)
|
#define DT1 (env->dt1)
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
#define QT0 (env->qt0)
|
#define QT0 (env->qt0)
|
||||||
#define QT1 (env->qt1)
|
#define QT1 (env->qt1)
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "exec-all.h"
|
#include "exec-all.h"
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
|
||||||
//#define DEBUG_MMU
|
//#define DEBUG_MMU
|
||||||
|
//#define DEBUG_FEATURES
|
||||||
|
|
||||||
typedef struct sparc_def_t sparc_def_t;
|
typedef struct sparc_def_t sparc_def_t;
|
||||||
|
|
||||||
@ -43,9 +44,10 @@ struct sparc_def_t {
|
|||||||
uint32_t mmu_cxr_mask;
|
uint32_t mmu_cxr_mask;
|
||||||
uint32_t mmu_sfsr_mask;
|
uint32_t mmu_sfsr_mask;
|
||||||
uint32_t mmu_trcr_mask;
|
uint32_t mmu_trcr_mask;
|
||||||
|
uint32_t features;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
|
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const unsigned char *cpu_model);
|
||||||
|
|
||||||
/* Sparc MMU emulation */
|
/* Sparc MMU emulation */
|
||||||
|
|
||||||
@ -684,19 +686,14 @@ void cpu_reset(CPUSPARCState *env)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
|
static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
|
||||||
{
|
{
|
||||||
CPUSPARCState *env;
|
sparc_def_t def1, *def = &def1;
|
||||||
const sparc_def_t *def;
|
|
||||||
|
|
||||||
def = cpu_sparc_find_by_name(cpu_model);
|
if (cpu_sparc_find_by_name(def, cpu_model) < 0)
|
||||||
if (!def)
|
return -1;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
env = qemu_mallocz(sizeof(CPUSPARCState));
|
env->features = def->features;
|
||||||
if (!env)
|
|
||||||
return NULL;
|
|
||||||
cpu_exec_init(env);
|
|
||||||
env->cpu_model_str = cpu_model;
|
env->cpu_model_str = cpu_model;
|
||||||
env->version = def->iu_version;
|
env->version = def->iu_version;
|
||||||
env->fsr = def->fpu_version;
|
env->fsr = def->fpu_version;
|
||||||
@ -709,9 +706,29 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model)
|
|||||||
env->mmuregs[0] |= def->mmu_version;
|
env->mmuregs[0] |= def->mmu_version;
|
||||||
cpu_sparc_set_id(env, 0);
|
cpu_sparc_set_id(env, 0);
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cpu_sparc_close(CPUSPARCState *env)
|
||||||
|
{
|
||||||
|
free(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
|
||||||
|
{
|
||||||
|
CPUSPARCState *env;
|
||||||
|
|
||||||
|
env = qemu_mallocz(sizeof(CPUSPARCState));
|
||||||
|
if (!env)
|
||||||
|
return NULL;
|
||||||
|
cpu_exec_init(env);
|
||||||
|
|
||||||
gen_intermediate_code_init(env);
|
gen_intermediate_code_init(env);
|
||||||
|
|
||||||
|
if (cpu_sparc_register(env, cpu_model) < 0) {
|
||||||
|
cpu_sparc_close(env);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
cpu_reset(env);
|
cpu_reset(env);
|
||||||
|
|
||||||
return env;
|
return env;
|
||||||
@ -732,6 +749,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Fujitsu Sparc64 III",
|
.name = "Fujitsu Sparc64 III",
|
||||||
@ -739,6 +757,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Fujitsu Sparc64 IV",
|
.name = "Fujitsu Sparc64 IV",
|
||||||
@ -746,6 +765,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Fujitsu Sparc64 V",
|
.name = "Fujitsu Sparc64 V",
|
||||||
@ -753,6 +773,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI UltraSparc I",
|
.name = "TI UltraSparc I",
|
||||||
@ -760,6 +781,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI UltraSparc II",
|
.name = "TI UltraSparc II",
|
||||||
@ -767,6 +789,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI UltraSparc IIi",
|
.name = "TI UltraSparc IIi",
|
||||||
@ -774,6 +797,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI UltraSparc IIe",
|
.name = "TI UltraSparc IIe",
|
||||||
@ -781,6 +805,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Sun UltraSparc III",
|
.name = "Sun UltraSparc III",
|
||||||
@ -788,6 +813,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Sun UltraSparc III Cu",
|
.name = "Sun UltraSparc III Cu",
|
||||||
@ -795,6 +821,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Sun UltraSparc IIIi",
|
.name = "Sun UltraSparc IIIi",
|
||||||
@ -802,6 +829,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Sun UltraSparc IV",
|
.name = "Sun UltraSparc IV",
|
||||||
@ -809,6 +837,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Sun UltraSparc IV+",
|
.name = "Sun UltraSparc IV+",
|
||||||
@ -816,6 +845,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Sun UltraSparc IIIi+",
|
.name = "Sun UltraSparc IIIi+",
|
||||||
@ -823,6 +853,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "NEC UltraSparc I",
|
.name = "NEC UltraSparc I",
|
||||||
@ -830,6 +861,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
.fpu_version = 0x00000000,
|
.fpu_version = 0x00000000,
|
||||||
.mmu_version = 0,
|
.mmu_version = 0,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
@ -842,6 +874,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_FEATURE_FLOAT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Fujitsu MB86904",
|
.name = "Fujitsu MB86904",
|
||||||
@ -853,6 +886,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x000000ff,
|
.mmu_cxr_mask = 0x000000ff,
|
||||||
.mmu_sfsr_mask = 0x00016fff,
|
.mmu_sfsr_mask = 0x00016fff,
|
||||||
.mmu_trcr_mask = 0x00ffffff,
|
.mmu_trcr_mask = 0x00ffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Fujitsu MB86907",
|
.name = "Fujitsu MB86907",
|
||||||
@ -864,6 +898,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x000000ff,
|
.mmu_cxr_mask = 0x000000ff,
|
||||||
.mmu_sfsr_mask = 0x00016fff,
|
.mmu_sfsr_mask = 0x00016fff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "LSI L64811",
|
.name = "LSI L64811",
|
||||||
@ -875,6 +910,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Cypress CY7C601",
|
.name = "Cypress CY7C601",
|
||||||
@ -886,6 +922,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Cypress CY7C611",
|
.name = "Cypress CY7C611",
|
||||||
@ -897,6 +934,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI SuperSparc II",
|
.name = "TI SuperSparc II",
|
||||||
@ -908,6 +946,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000ffff,
|
.mmu_cxr_mask = 0x0000ffff,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI MicroSparc I",
|
.name = "TI MicroSparc I",
|
||||||
@ -919,6 +958,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0x00016fff,
|
.mmu_sfsr_mask = 0x00016fff,
|
||||||
.mmu_trcr_mask = 0x0000003f,
|
.mmu_trcr_mask = 0x0000003f,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI MicroSparc II",
|
.name = "TI MicroSparc II",
|
||||||
@ -930,6 +970,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x000000ff,
|
.mmu_cxr_mask = 0x000000ff,
|
||||||
.mmu_sfsr_mask = 0x00016fff,
|
.mmu_sfsr_mask = 0x00016fff,
|
||||||
.mmu_trcr_mask = 0x00ffffff,
|
.mmu_trcr_mask = 0x00ffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI MicroSparc IIep",
|
.name = "TI MicroSparc IIep",
|
||||||
@ -941,6 +982,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x000000ff,
|
.mmu_cxr_mask = 0x000000ff,
|
||||||
.mmu_sfsr_mask = 0x00016bff,
|
.mmu_sfsr_mask = 0x00016bff,
|
||||||
.mmu_trcr_mask = 0x00ffffff,
|
.mmu_trcr_mask = 0x00ffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI SuperSparc 51",
|
.name = "TI SuperSparc 51",
|
||||||
@ -952,6 +994,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000ffff,
|
.mmu_cxr_mask = 0x0000ffff,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "TI SuperSparc 61",
|
.name = "TI SuperSparc 61",
|
||||||
@ -963,6 +1006,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000ffff,
|
.mmu_cxr_mask = 0x0000ffff,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Ross RT625",
|
.name = "Ross RT625",
|
||||||
@ -974,6 +1018,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Ross RT620",
|
.name = "Ross RT620",
|
||||||
@ -985,6 +1030,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "BIT B5010",
|
.name = "BIT B5010",
|
||||||
@ -996,6 +1042,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Matsushita MN10501",
|
.name = "Matsushita MN10501",
|
||||||
@ -1007,6 +1054,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Weitek W8601",
|
.name = "Weitek W8601",
|
||||||
@ -1018,6 +1066,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "LEON2",
|
.name = "LEON2",
|
||||||
@ -1029,6 +1078,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "LEON3",
|
.name = "LEON3",
|
||||||
@ -1040,20 +1090,137 @@ static const sparc_def_t sparc_defs[] = {
|
|||||||
.mmu_cxr_mask = 0x0000003f,
|
.mmu_cxr_mask = 0x0000003f,
|
||||||
.mmu_sfsr_mask = 0xffffffff,
|
.mmu_sfsr_mask = 0xffffffff,
|
||||||
.mmu_trcr_mask = 0xffffffff,
|
.mmu_trcr_mask = 0xffffffff,
|
||||||
|
.features = CPU_DEFAULT_FEATURES,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
|
static const char * const feature_name[] = {
|
||||||
|
"float",
|
||||||
|
"float128",
|
||||||
|
"swap",
|
||||||
|
"mul",
|
||||||
|
"div",
|
||||||
|
"flush",
|
||||||
|
"fsqrt",
|
||||||
|
"fmul",
|
||||||
|
"vis1",
|
||||||
|
"vis2",
|
||||||
|
};
|
||||||
|
|
||||||
|
static void print_features(FILE *f,
|
||||||
|
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
|
||||||
|
uint32_t features, const char *prefix)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(feature_name); i++)
|
||||||
|
if (feature_name[i] && (features & (1 << i))) {
|
||||||
|
if (prefix)
|
||||||
|
(*cpu_fprintf)(f, "%s", prefix);
|
||||||
|
(*cpu_fprintf)(f, "%s ", feature_name[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(feature_name); i++)
|
||||||
|
if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
|
||||||
|
*features |= 1 << i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "CPU feature %s not found\n", flagname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const unsigned char *cpu_model)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
const sparc_def_t *def = NULL;
|
||||||
|
char *s = strdup(cpu_model);
|
||||||
|
char *featurestr, *name = strtok(s, ",");
|
||||||
|
uint32_t plus_features = 0;
|
||||||
|
uint32_t minus_features = 0;
|
||||||
|
long long iu_version;
|
||||||
|
uint32_t fpu_version, mmu_version;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
|
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
|
||||||
if (strcasecmp(name, sparc_defs[i].name) == 0) {
|
if (strcasecmp(name, sparc_defs[i].name) == 0) {
|
||||||
return &sparc_defs[i];
|
def = &sparc_defs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
if (!def)
|
||||||
|
goto error;
|
||||||
|
memcpy(cpu_def, def, sizeof(*def));
|
||||||
|
|
||||||
|
featurestr = strtok(NULL, ",");
|
||||||
|
while (featurestr) {
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
if (featurestr[0] == '+') {
|
||||||
|
add_flagname_to_bitmaps(featurestr + 1, &plus_features);
|
||||||
|
} else if (featurestr[0] == '-') {
|
||||||
|
add_flagname_to_bitmaps(featurestr + 1, &minus_features);
|
||||||
|
} else if ((val = strchr(featurestr, '='))) {
|
||||||
|
*val = 0; val++;
|
||||||
|
if (!strcmp(featurestr, "iu_version")) {
|
||||||
|
char *err;
|
||||||
|
|
||||||
|
iu_version = strtoll(val, &err, 0);
|
||||||
|
if (!*val || *err) {
|
||||||
|
fprintf(stderr, "bad numerical value %s\n", val);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
cpu_def->iu_version = iu_version;
|
||||||
|
#ifdef DEBUG_FEATURES
|
||||||
|
fprintf(stderr, "iu_version %llx\n", iu_version);
|
||||||
|
#endif
|
||||||
|
} else if (!strcmp(featurestr, "fpu_version")) {
|
||||||
|
char *err;
|
||||||
|
|
||||||
|
fpu_version = strtol(val, &err, 0);
|
||||||
|
if (!*val || *err) {
|
||||||
|
fprintf(stderr, "bad numerical value %s\n", val);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
cpu_def->fpu_version = fpu_version;
|
||||||
|
#ifdef DEBUG_FEATURES
|
||||||
|
fprintf(stderr, "fpu_version %llx\n", fpu_version);
|
||||||
|
#endif
|
||||||
|
} else if (!strcmp(featurestr, "mmu_version")) {
|
||||||
|
char *err;
|
||||||
|
|
||||||
|
mmu_version = strtol(val, &err, 0);
|
||||||
|
if (!*val || *err) {
|
||||||
|
fprintf(stderr, "bad numerical value %s\n", val);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
cpu_def->mmu_version = mmu_version;
|
||||||
|
#ifdef DEBUG_FEATURES
|
||||||
|
fprintf(stderr, "mmu_version %llx\n", mmu_version);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unrecognized feature %s\n", featurestr);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
featurestr = strtok(NULL, ",");
|
||||||
|
}
|
||||||
|
cpu_def->features |= plus_features;
|
||||||
|
cpu_def->features &= ~minus_features;
|
||||||
|
#ifdef DEBUG_FEATURES
|
||||||
|
print_features(stderr, fprintf, cpu_def->features, NULL);
|
||||||
|
#endif
|
||||||
|
free(s);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
free(s);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
|
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
|
||||||
@ -1061,12 +1228,19 @@ void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
|
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
|
||||||
(*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
|
(*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x ",
|
||||||
sparc_defs[i].name,
|
sparc_defs[i].name,
|
||||||
sparc_defs[i].iu_version,
|
sparc_defs[i].iu_version,
|
||||||
sparc_defs[i].fpu_version,
|
sparc_defs[i].fpu_version,
|
||||||
sparc_defs[i].mmu_version);
|
sparc_defs[i].mmu_version);
|
||||||
|
print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES & ~sparc_defs[i].features, "-");
|
||||||
|
print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES & sparc_defs[i].features, "+");
|
||||||
|
(*cpu_fprintf)(f, "\n");
|
||||||
}
|
}
|
||||||
|
(*cpu_fprintf)(f, "CPU feature flags (+/-): ");
|
||||||
|
print_features(f, cpu_fprintf, -1, NULL);
|
||||||
|
(*cpu_fprintf)(f, "\n");
|
||||||
|
(*cpu_fprintf)(f, "Numerical features (=): iu_version fpu_version mmu_version\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
|
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
|
||||||
|
@ -48,10 +48,8 @@ uint64_t TCG_HELPER_PROTO helper_pack64(target_ulong high, target_ulong low);
|
|||||||
void TCG_HELPER_PROTO helper_std_i386(target_ulong addr, int mem_idx);
|
void TCG_HELPER_PROTO helper_std_i386(target_ulong addr, int mem_idx);
|
||||||
void TCG_HELPER_PROTO helper_stdf(target_ulong addr, int mem_idx);
|
void TCG_HELPER_PROTO helper_stdf(target_ulong addr, int mem_idx);
|
||||||
void TCG_HELPER_PROTO helper_lddf(target_ulong addr, int mem_idx);
|
void TCG_HELPER_PROTO helper_lddf(target_ulong addr, int mem_idx);
|
||||||
#if defined(CONFIG_USER_ONLY)
|
void TCG_HELPER_PROTO helper_ldqf(target_ulong addr, int mem_idx);
|
||||||
void TCG_HELPER_PROTO helper_ldqf(target_ulong addr);
|
void TCG_HELPER_PROTO helper_stqf(target_ulong addr, int mem_idx);
|
||||||
void TCG_HELPER_PROTO helper_stqf(target_ulong addr);
|
|
||||||
#endif
|
|
||||||
uint64_t TCG_HELPER_PROTO helper_ld_asi(target_ulong addr, int asi,
|
uint64_t TCG_HELPER_PROTO helper_ld_asi(target_ulong addr, int asi,
|
||||||
int size, int sign);
|
int size, int sign);
|
||||||
void TCG_HELPER_PROTO helper_st_asi(target_ulong addr, uint64_t val, int asi,
|
void TCG_HELPER_PROTO helper_st_asi(target_ulong addr, uint64_t val, int asi,
|
||||||
@ -67,11 +65,9 @@ void TCG_HELPER_PROTO helper_fcmps(void);
|
|||||||
void TCG_HELPER_PROTO helper_fcmpd(void);
|
void TCG_HELPER_PROTO helper_fcmpd(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmpes(void);
|
void TCG_HELPER_PROTO helper_fcmpes(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmped(void);
|
void TCG_HELPER_PROTO helper_fcmped(void);
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
void TCG_HELPER_PROTO helper_fsqrtq(void);
|
void TCG_HELPER_PROTO helper_fsqrtq(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmpq(void);
|
void TCG_HELPER_PROTO helper_fcmpq(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmpeq(void);
|
void TCG_HELPER_PROTO helper_fcmpeq(void);
|
||||||
#endif
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
void TCG_HELPER_PROTO helper_fabsd(void);
|
void TCG_HELPER_PROTO helper_fabsd(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmps_fcc1(void);
|
void TCG_HELPER_PROTO helper_fcmps_fcc1(void);
|
||||||
@ -86,7 +82,6 @@ void TCG_HELPER_PROTO helper_fcmpes_fcc2(void);
|
|||||||
void TCG_HELPER_PROTO helper_fcmped_fcc2(void);
|
void TCG_HELPER_PROTO helper_fcmped_fcc2(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmpes_fcc3(void);
|
void TCG_HELPER_PROTO helper_fcmpes_fcc3(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmped_fcc3(void);
|
void TCG_HELPER_PROTO helper_fcmped_fcc3(void);
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
void TCG_HELPER_PROTO helper_fabsq(void);
|
void TCG_HELPER_PROTO helper_fabsq(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmpq_fcc1(void);
|
void TCG_HELPER_PROTO helper_fcmpq_fcc1(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmpq_fcc2(void);
|
void TCG_HELPER_PROTO helper_fcmpq_fcc2(void);
|
||||||
@ -95,19 +90,12 @@ void TCG_HELPER_PROTO helper_fcmpeq_fcc1(void);
|
|||||||
void TCG_HELPER_PROTO helper_fcmpeq_fcc2(void);
|
void TCG_HELPER_PROTO helper_fcmpeq_fcc2(void);
|
||||||
void TCG_HELPER_PROTO helper_fcmpeq_fcc3(void);
|
void TCG_HELPER_PROTO helper_fcmpeq_fcc3(void);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
void TCG_HELPER_PROTO raise_exception(int tt);
|
void TCG_HELPER_PROTO raise_exception(int tt);
|
||||||
#define F_HELPER_0_0(name) void TCG_HELPER_PROTO helper_f ## name(void)
|
#define F_HELPER_0_0(name) void TCG_HELPER_PROTO helper_f ## name(void)
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
#define F_HELPER_SDQ_0_0(name) \
|
#define F_HELPER_SDQ_0_0(name) \
|
||||||
F_HELPER_0_0(name ## s); \
|
F_HELPER_0_0(name ## s); \
|
||||||
F_HELPER_0_0(name ## d); \
|
F_HELPER_0_0(name ## d); \
|
||||||
F_HELPER_0_0(name ## q)
|
F_HELPER_0_0(name ## q)
|
||||||
#else
|
|
||||||
#define F_HELPER_SDQ_0_0(name) \
|
|
||||||
F_HELPER_0_0(name ## s); \
|
|
||||||
F_HELPER_0_0(name ## d);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
F_HELPER_SDQ_0_0(add);
|
F_HELPER_SDQ_0_0(add);
|
||||||
F_HELPER_SDQ_0_0(sub);
|
F_HELPER_SDQ_0_0(sub);
|
||||||
@ -124,23 +112,17 @@ F_HELPER_SDQ_0_0(xto);
|
|||||||
#endif
|
#endif
|
||||||
F_HELPER_0_0(dtos);
|
F_HELPER_0_0(dtos);
|
||||||
F_HELPER_0_0(stod);
|
F_HELPER_0_0(stod);
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
F_HELPER_0_0(qtos);
|
F_HELPER_0_0(qtos);
|
||||||
F_HELPER_0_0(stoq);
|
F_HELPER_0_0(stoq);
|
||||||
F_HELPER_0_0(qtod);
|
F_HELPER_0_0(qtod);
|
||||||
F_HELPER_0_0(dtoq);
|
F_HELPER_0_0(dtoq);
|
||||||
#endif
|
|
||||||
F_HELPER_0_0(stoi);
|
F_HELPER_0_0(stoi);
|
||||||
F_HELPER_0_0(dtoi);
|
F_HELPER_0_0(dtoi);
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
F_HELPER_0_0(qtoi);
|
F_HELPER_0_0(qtoi);
|
||||||
#endif
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
F_HELPER_0_0(stox);
|
F_HELPER_0_0(stox);
|
||||||
F_HELPER_0_0(dtox);
|
F_HELPER_0_0(dtox);
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
F_HELPER_0_0(qtox);
|
F_HELPER_0_0(qtox);
|
||||||
#endif
|
|
||||||
F_HELPER_0_0(aligndata);
|
F_HELPER_0_0(aligndata);
|
||||||
void TCG_HELPER_PROTO helper_movl_FT0_0(void);
|
void TCG_HELPER_PROTO helper_movl_FT0_0(void);
|
||||||
void TCG_HELPER_PROTO helper_movl_DT0_0(void);
|
void TCG_HELPER_PROTO helper_movl_DT0_0(void);
|
||||||
|
@ -61,7 +61,6 @@ void helper_check_align(target_ulong addr, uint32_t align)
|
|||||||
|
|
||||||
#define F_HELPER(name, p) void helper_f##name##p(void)
|
#define F_HELPER(name, p) void helper_f##name##p(void)
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
#define F_BINOP(name) \
|
#define F_BINOP(name) \
|
||||||
F_HELPER(name, s) \
|
F_HELPER(name, s) \
|
||||||
{ \
|
{ \
|
||||||
@ -75,17 +74,6 @@ void helper_check_align(target_ulong addr, uint32_t align)
|
|||||||
{ \
|
{ \
|
||||||
QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
|
QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define F_BINOP(name) \
|
|
||||||
F_HELPER(name, s) \
|
|
||||||
{ \
|
|
||||||
FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
|
|
||||||
} \
|
|
||||||
F_HELPER(name, d) \
|
|
||||||
{ \
|
|
||||||
DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
F_BINOP(add);
|
F_BINOP(add);
|
||||||
F_BINOP(sub);
|
F_BINOP(sub);
|
||||||
@ -100,14 +88,12 @@ void helper_fsmuld(void)
|
|||||||
&env->fp_status);
|
&env->fp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
void helper_fdmulq(void)
|
void helper_fdmulq(void)
|
||||||
{
|
{
|
||||||
QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
|
QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
|
||||||
float64_to_float128(DT1, &env->fp_status),
|
float64_to_float128(DT1, &env->fp_status),
|
||||||
&env->fp_status);
|
&env->fp_status);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
F_HELPER(neg, s)
|
F_HELPER(neg, s)
|
||||||
{
|
{
|
||||||
@ -120,13 +106,11 @@ F_HELPER(neg, d)
|
|||||||
DT0 = float64_chs(DT1);
|
DT0 = float64_chs(DT1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
F_HELPER(neg, q)
|
F_HELPER(neg, q)
|
||||||
{
|
{
|
||||||
QT0 = float128_chs(QT1);
|
QT0 = float128_chs(QT1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Integer to float conversion. */
|
/* Integer to float conversion. */
|
||||||
F_HELPER(ito, s)
|
F_HELPER(ito, s)
|
||||||
@ -139,12 +123,10 @@ F_HELPER(ito, d)
|
|||||||
DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
|
DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
F_HELPER(ito, q)
|
F_HELPER(ito, q)
|
||||||
{
|
{
|
||||||
QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
|
QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
F_HELPER(xto, s)
|
F_HELPER(xto, s)
|
||||||
@ -156,13 +138,12 @@ F_HELPER(xto, d)
|
|||||||
{
|
{
|
||||||
DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
|
DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
F_HELPER(xto, q)
|
F_HELPER(xto, q)
|
||||||
{
|
{
|
||||||
QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
|
QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#undef F_HELPER
|
#undef F_HELPER
|
||||||
|
|
||||||
/* floating point conversion */
|
/* floating point conversion */
|
||||||
@ -176,7 +157,6 @@ void helper_fstod(void)
|
|||||||
DT0 = float32_to_float64(FT1, &env->fp_status);
|
DT0 = float32_to_float64(FT1, &env->fp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
void helper_fqtos(void)
|
void helper_fqtos(void)
|
||||||
{
|
{
|
||||||
FT0 = float128_to_float32(QT1, &env->fp_status);
|
FT0 = float128_to_float32(QT1, &env->fp_status);
|
||||||
@ -196,7 +176,6 @@ void helper_fdtoq(void)
|
|||||||
{
|
{
|
||||||
QT0 = float64_to_float128(DT1, &env->fp_status);
|
QT0 = float64_to_float128(DT1, &env->fp_status);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Float to integer conversion. */
|
/* Float to integer conversion. */
|
||||||
void helper_fstoi(void)
|
void helper_fstoi(void)
|
||||||
@ -209,12 +188,10 @@ void helper_fdtoi(void)
|
|||||||
*((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
|
*((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
void helper_fqtoi(void)
|
void helper_fqtoi(void)
|
||||||
{
|
{
|
||||||
*((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status);
|
*((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
void helper_fstox(void)
|
void helper_fstox(void)
|
||||||
@ -227,12 +204,10 @@ void helper_fdtox(void)
|
|||||||
*((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
|
*((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
void helper_fqtox(void)
|
void helper_fqtox(void)
|
||||||
{
|
{
|
||||||
*((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
|
*((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void helper_faligndata(void)
|
void helper_faligndata(void)
|
||||||
{
|
{
|
||||||
@ -722,13 +697,11 @@ void helper_fabsd(void)
|
|||||||
DT0 = float64_abs(DT1);
|
DT0 = float64_abs(DT1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
void helper_fabsq(void)
|
void helper_fabsq(void)
|
||||||
{
|
{
|
||||||
QT0 = float128_abs(QT1);
|
QT0 = float128_abs(QT1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
void helper_fsqrts(void)
|
void helper_fsqrts(void)
|
||||||
{
|
{
|
||||||
@ -740,12 +713,10 @@ void helper_fsqrtd(void)
|
|||||||
DT0 = float64_sqrt(DT1, &env->fp_status);
|
DT0 = float64_sqrt(DT1, &env->fp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
void helper_fsqrtq(void)
|
void helper_fsqrtq(void)
|
||||||
{
|
{
|
||||||
QT0 = float128_sqrt(QT1, &env->fp_status);
|
QT0 = float128_sqrt(QT1, &env->fp_status);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP) \
|
#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP) \
|
||||||
void glue(helper_, name) (void) \
|
void glue(helper_, name) (void) \
|
||||||
@ -784,38 +755,34 @@ GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0);
|
|||||||
GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1);
|
GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1);
|
||||||
GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1);
|
GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1);
|
||||||
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
|
||||||
GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
|
GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
|
||||||
GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
|
GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0);
|
GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0);
|
||||||
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
|
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
|
||||||
|
GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
|
||||||
|
|
||||||
GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0);
|
GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0);
|
||||||
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
|
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
|
||||||
|
GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
|
||||||
|
|
||||||
GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0);
|
GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0);
|
||||||
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
|
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
|
||||||
|
GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
|
||||||
|
|
||||||
GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1);
|
GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1);
|
||||||
GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
|
GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
|
||||||
|
GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
|
||||||
|
|
||||||
GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1);
|
GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1);
|
||||||
GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
|
GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
|
||||||
|
GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
|
||||||
|
|
||||||
GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
|
GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
|
||||||
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
|
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
|
||||||
#ifdef CONFIG_USER_ONLY
|
|
||||||
GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
|
|
||||||
GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
|
|
||||||
GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
|
|
||||||
GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
|
|
||||||
GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
|
|
||||||
GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
|
GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && defined(DEBUG_MXCC)
|
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && defined(DEBUG_MXCC)
|
||||||
static void dump_mxcc(CPUState *env)
|
static void dump_mxcc(CPUState *env)
|
||||||
@ -2074,11 +2041,9 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
|
|||||||
case 8:
|
case 8:
|
||||||
*((int64_t *)&DT0) = val;
|
*((int64_t *)&DT0) = val;
|
||||||
break;
|
break;
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
case 16:
|
case 16:
|
||||||
// XXX
|
// XXX
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2119,11 +2084,9 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
|
|||||||
case 8:
|
case 8:
|
||||||
val = *((int64_t *)&DT0);
|
val = *((int64_t *)&DT0);
|
||||||
break;
|
break;
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
case 16:
|
case 16:
|
||||||
// XXX
|
// XXX
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
helper_st_asi(addr, val, asi, size);
|
helper_st_asi(addr, val, asi, size);
|
||||||
}
|
}
|
||||||
@ -2299,27 +2262,73 @@ void helper_lddf(target_ulong addr, int mem_idx)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
void helper_ldqf(target_ulong addr, int mem_idx)
|
||||||
void helper_ldqf(target_ulong addr)
|
|
||||||
{
|
{
|
||||||
// XXX add 128 bit load
|
// XXX add 128 bit load
|
||||||
CPU_QuadU u;
|
CPU_QuadU u;
|
||||||
|
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
switch (mem_idx) {
|
||||||
|
case 0:
|
||||||
|
u.ll.upper = ldq_user(ADDR(addr));
|
||||||
|
u.ll.lower = ldq_user(ADDR(addr + 8));
|
||||||
|
QT0 = u.q;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
u.ll.upper = ldq_kernel(ADDR(addr));
|
||||||
|
u.ll.lower = ldq_kernel(ADDR(addr + 8));
|
||||||
|
QT0 = u.q;
|
||||||
|
break;
|
||||||
|
#ifdef TARGET_SPARC64
|
||||||
|
case 2:
|
||||||
|
u.ll.upper = ldq_hypv(ADDR(addr));
|
||||||
|
u.ll.lower = ldq_hypv(ADDR(addr + 8));
|
||||||
|
QT0 = u.q;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
u.ll.upper = ldq_raw(ADDR(addr));
|
u.ll.upper = ldq_raw(ADDR(addr));
|
||||||
u.ll.lower = ldq_raw(ADDR(addr + 8));
|
u.ll.lower = ldq_raw(ADDR(addr + 8));
|
||||||
QT0 = u.q;
|
QT0 = u.q;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_stqf(target_ulong addr)
|
void helper_stqf(target_ulong addr, int mem_idx)
|
||||||
{
|
{
|
||||||
// XXX add 128 bit store
|
// XXX add 128 bit store
|
||||||
CPU_QuadU u;
|
CPU_QuadU u;
|
||||||
|
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
switch (mem_idx) {
|
||||||
|
case 0:
|
||||||
|
u.q = QT0;
|
||||||
|
stq_user(ADDR(addr), u.ll.upper);
|
||||||
|
stq_user(ADDR(addr + 8), u.ll.lower);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
u.q = QT0;
|
||||||
|
stq_kernel(ADDR(addr), u.ll.upper);
|
||||||
|
stq_kernel(ADDR(addr + 8), u.ll.lower);
|
||||||
|
break;
|
||||||
|
#ifdef TARGET_SPARC64
|
||||||
|
case 2:
|
||||||
|
u.q = QT0;
|
||||||
|
stq_hypv(ADDR(addr), u.ll.upper);
|
||||||
|
stq_hypv(ADDR(addr + 8), u.ll.lower);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
u.q = QT0;
|
u.q = QT0;
|
||||||
stq_raw(ADDR(addr), u.ll.upper);
|
stq_raw(ADDR(addr), u.ll.upper);
|
||||||
stq_raw(ADDR(addr + 8), u.ll.lower);
|
stq_raw(ADDR(addr + 8), u.ll.lower);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#undef ADDR
|
#undef ADDR
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user