target/sparc: Add FQ and FSR.QNE
Add support for, and migrate, a single-entry fp instruction queue for sparc32. Signed-off-by: Carl Hauser <chauser@pullman.com> [rth: Split from a larger patch; adjust representation with union; add migration state] Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Carl Hauser <chauser@pullman.com>
This commit is contained in:
parent
a4eb31c678
commit
e412e9973a
@ -184,6 +184,8 @@ enum {
|
||||
#define FSR_FTT_SEQ_ERROR (4ULL << 14)
|
||||
#define FSR_FTT_INVAL_FPR (6ULL << 14)
|
||||
|
||||
#define FSR_QNE (1ULL << 13)
|
||||
|
||||
#define FSR_FCC0_SHIFT 10
|
||||
#define FSR_FCC1_SHIFT 32
|
||||
#define FSR_FCC2_SHIFT 34
|
||||
@ -438,6 +440,26 @@ struct CPUArchState {
|
||||
uint32_t fsr_cexc_ftt; /* cexc, ftt */
|
||||
uint32_t fcc[TARGET_FCCREGS]; /* fcc* */
|
||||
|
||||
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
|
||||
/*
|
||||
* Single-element FPU fault queue, with address and insn,
|
||||
* packaged into the double-word with which it is stored.
|
||||
*/
|
||||
uint32_t fsr_qne; /* qne */
|
||||
union {
|
||||
uint64_t d;
|
||||
struct {
|
||||
#if HOST_BIG_ENDIAN
|
||||
uint32_t addr;
|
||||
uint32_t insn;
|
||||
#else
|
||||
uint32_t insn;
|
||||
uint32_t addr;
|
||||
#endif
|
||||
} s;
|
||||
} fq;
|
||||
#endif
|
||||
|
||||
CPU_DoubleU fpr[TARGET_DPREGS]; /* floating point registers */
|
||||
uint32_t cwp; /* index of current register window (extracted
|
||||
from PSR) */
|
||||
|
@ -545,6 +545,8 @@ target_ulong cpu_get_fsr(CPUSPARCState *env)
|
||||
fsr |= (uint64_t)env->fcc[1] << FSR_FCC1_SHIFT;
|
||||
fsr |= (uint64_t)env->fcc[2] << FSR_FCC2_SHIFT;
|
||||
fsr |= (uint64_t)env->fcc[3] << FSR_FCC3_SHIFT;
|
||||
#elif !defined(CONFIG_USER_ONLY)
|
||||
fsr |= env->fsr_qne;
|
||||
#endif
|
||||
|
||||
/* VER is kept completely separate until re-assembly. */
|
||||
@ -591,6 +593,8 @@ void cpu_put_fsr(CPUSPARCState *env, target_ulong fsr)
|
||||
env->fcc[1] = extract64(fsr, FSR_FCC1_SHIFT, 2);
|
||||
env->fcc[2] = extract64(fsr, FSR_FCC2_SHIFT, 2);
|
||||
env->fcc[3] = extract64(fsr, FSR_FCC3_SHIFT, 2);
|
||||
#elif !defined(CONFIG_USER_ONLY)
|
||||
env->fsr_qne = fsr & FSR_QNE;
|
||||
#endif
|
||||
|
||||
set_fsr_nonsplit(env, fsr);
|
||||
|
@ -143,6 +143,24 @@ static const VMStateInfo vmstate_xcc = {
|
||||
.get = get_xcc,
|
||||
.put = put_xcc,
|
||||
};
|
||||
#else
|
||||
static bool fq_needed(void *opaque)
|
||||
{
|
||||
SPARCCPU *cpu = opaque;
|
||||
return cpu->env.fsr_qne;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_fq = {
|
||||
.name = "cpu/fq",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = fq_needed,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32(env.fq.s.addr, SPARCCPU),
|
||||
VMSTATE_UINT32(env.fq.s.insn, SPARCCPU),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static int cpu_pre_save(void *opaque)
|
||||
@ -265,4 +283,11 @@ const VMStateDescription vmstate_sparc_cpu = {
|
||||
#endif
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
#ifndef TARGET_SPARC64
|
||||
.subsections = (const VMStateDescription * const []) {
|
||||
&vmstate_fq,
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user