target/loongarch: Add LSX data type VReg
Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Song Gao <gaosong@loongson.cn> Message-Id: <20230504122810.4094787-2-gaosong@loongson.cn>
This commit is contained in:
parent
eb5c3932a3
commit
16f5396cec
@ -128,7 +128,7 @@ static void setup_sigframe(CPULoongArchState *env,
|
||||
|
||||
fpu_ctx = (struct target_fpu_context *)(info + 1);
|
||||
for (i = 0; i < 32; ++i) {
|
||||
__put_user(env->fpr[i], &fpu_ctx->regs[i]);
|
||||
__put_user(env->fpr[i].vreg.D(0), &fpu_ctx->regs[i]);
|
||||
}
|
||||
__put_user(read_fcc(env), &fpu_ctx->fcc);
|
||||
__put_user(env->fcsr0, &fpu_ctx->fcsr);
|
||||
@ -193,7 +193,7 @@ static void restore_sigframe(CPULoongArchState *env,
|
||||
uint64_t fcc;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
__get_user(env->fpr[i], &fpu_ctx->regs[i]);
|
||||
__get_user(env->fpr[i].vreg.D(0), &fpu_ctx->regs[i]);
|
||||
}
|
||||
__get_user(fcc, &fpu_ctx->fcc);
|
||||
write_fcc(env, fcc);
|
||||
|
@ -656,7 +656,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
||||
/* fpr */
|
||||
if (flags & CPU_DUMP_FPU) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
qemu_fprintf(f, " %s %016" PRIx64, fregnames[i], env->fpr[i]);
|
||||
qemu_fprintf(f, " %s %016" PRIx64, fregnames[i], env->fpr[i].vreg.D(0));
|
||||
if ((i & 3) == 3) {
|
||||
qemu_fprintf(f, "\n");
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef LOONGARCH_CPU_H
|
||||
#define LOONGARCH_CPU_H
|
||||
|
||||
#include "qemu/int128.h"
|
||||
#include "exec/cpu-defs.h"
|
||||
#include "fpu/softfloat-types.h"
|
||||
#include "hw/registerfields.h"
|
||||
@ -241,6 +242,24 @@ FIELD(TLB_MISC, ASID, 1, 10)
|
||||
FIELD(TLB_MISC, VPPN, 13, 35)
|
||||
FIELD(TLB_MISC, PS, 48, 6)
|
||||
|
||||
#define LSX_LEN (128)
|
||||
typedef union VReg {
|
||||
int8_t B[LSX_LEN / 8];
|
||||
int16_t H[LSX_LEN / 16];
|
||||
int32_t W[LSX_LEN / 32];
|
||||
int64_t D[LSX_LEN / 64];
|
||||
uint8_t UB[LSX_LEN / 8];
|
||||
uint16_t UH[LSX_LEN / 16];
|
||||
uint32_t UW[LSX_LEN / 32];
|
||||
uint64_t UD[LSX_LEN / 64];
|
||||
Int128 Q[LSX_LEN / 128];
|
||||
}VReg;
|
||||
|
||||
typedef union fpr_t fpr_t;
|
||||
union fpr_t {
|
||||
VReg vreg;
|
||||
};
|
||||
|
||||
struct LoongArchTLB {
|
||||
uint64_t tlb_misc;
|
||||
/* Fields corresponding to CSR_TLBELO0/1 */
|
||||
@ -253,7 +272,7 @@ typedef struct CPUArchState {
|
||||
uint64_t gpr[32];
|
||||
uint64_t pc;
|
||||
|
||||
uint64_t fpr[32];
|
||||
fpr_t fpr[32];
|
||||
float_status fp_status;
|
||||
bool cf[8];
|
||||
|
||||
|
@ -69,7 +69,7 @@ static int loongarch_gdb_get_fpu(CPULoongArchState *env,
|
||||
GByteArray *mem_buf, int n)
|
||||
{
|
||||
if (0 <= n && n < 32) {
|
||||
return gdb_get_reg64(mem_buf, env->fpr[n]);
|
||||
return gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(0));
|
||||
} else if (n == 32) {
|
||||
uint64_t val = read_fcc(env);
|
||||
return gdb_get_reg64(mem_buf, val);
|
||||
@ -85,7 +85,7 @@ static int loongarch_gdb_set_fpu(CPULoongArchState *env,
|
||||
int length = 0;
|
||||
|
||||
if (0 <= n && n < 32) {
|
||||
env->fpr[n] = ldq_p(mem_buf);
|
||||
env->fpr[n].vreg.D(0) = ldq_p(mem_buf);
|
||||
length = 8;
|
||||
} else if (n == 32) {
|
||||
uint64_t val = ldq_p(mem_buf);
|
||||
|
@ -21,6 +21,28 @@
|
||||
/* Global bit for huge page */
|
||||
#define LOONGARCH_HGLOBAL_SHIFT 12
|
||||
|
||||
#if HOST_BIG_ENDIAN
|
||||
#define B(x) B[15 - (x)]
|
||||
#define H(x) H[7 - (x)]
|
||||
#define W(x) W[3 - (x)]
|
||||
#define D(x) D[1 - (x)]
|
||||
#define UB(x) UB[15 - (x)]
|
||||
#define UH(x) UH[7 - (x)]
|
||||
#define UW(x) UW[3 - (x)]
|
||||
#define UD(x) UD[1 -(x)]
|
||||
#define Q(x) Q[x]
|
||||
#else
|
||||
#define B(x) B[x]
|
||||
#define H(x) H[x]
|
||||
#define W(x) W[x]
|
||||
#define D(x) D[x]
|
||||
#define UB(x) UB[x]
|
||||
#define UH(x) UH[x]
|
||||
#define UW(x) UW[x]
|
||||
#define UD(x) UD[x]
|
||||
#define Q(x) Q[x]
|
||||
#endif
|
||||
|
||||
void loongarch_translate_init(void);
|
||||
|
||||
void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
|
||||
|
@ -10,6 +10,72 @@
|
||||
#include "migration/cpu.h"
|
||||
#include "internals.h"
|
||||
|
||||
static const VMStateDescription vmstate_fpu_reg = {
|
||||
.name = "fpu_reg",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(UD(0), VReg),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
#define VMSTATE_FPU_REGS(_field, _state, _start) \
|
||||
VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
|
||||
vmstate_fpu_reg, fpr_t)
|
||||
|
||||
static bool fpu_needed(void *opaque)
|
||||
{
|
||||
LoongArchCPU *cpu = opaque;
|
||||
|
||||
return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, FP);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_fpu = {
|
||||
.name = "cpu/fpu",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = fpu_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_FPU_REGS(env.fpr, LoongArchCPU, 0),
|
||||
VMSTATE_UINT32(env.fcsr0, LoongArchCPU),
|
||||
VMSTATE_BOOL_ARRAY(env.cf, LoongArchCPU, 8),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_lsxh_reg = {
|
||||
.name = "lsxh_reg",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(UD(1), VReg),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
#define VMSTATE_LSXH_REGS(_field, _state, _start) \
|
||||
VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
|
||||
vmstate_lsxh_reg, fpr_t)
|
||||
|
||||
static bool lsx_needed(void *opaque)
|
||||
{
|
||||
LoongArchCPU *cpu = opaque;
|
||||
|
||||
return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LSX);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_lsx = {
|
||||
.name = "cpu/lsx",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = lsx_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_LSXH_REGS(env.fpr, LoongArchCPU, 0),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
/* TLB state */
|
||||
const VMStateDescription vmstate_tlb = {
|
||||
.name = "cpu/tlb",
|
||||
@ -24,18 +90,13 @@ const VMStateDescription vmstate_tlb = {
|
||||
};
|
||||
|
||||
/* LoongArch CPU state */
|
||||
|
||||
const VMStateDescription vmstate_loongarch_cpu = {
|
||||
.name = "cpu",
|
||||
.version_id = 0,
|
||||
.minimum_version_id = 0,
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
|
||||
VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
|
||||
VMSTATE_UINTTL(env.pc, LoongArchCPU),
|
||||
VMSTATE_UINT64_ARRAY(env.fpr, LoongArchCPU, 32),
|
||||
VMSTATE_UINT32(env.fcsr0, LoongArchCPU),
|
||||
VMSTATE_BOOL_ARRAY(env.cf, LoongArchCPU, 8),
|
||||
|
||||
/* Remaining CSRs */
|
||||
VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
|
||||
@ -99,4 +160,8 @@ const VMStateDescription vmstate_loongarch_cpu = {
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription*[]) {
|
||||
&vmstate_fpu,
|
||||
&vmstate_lsx,
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user