From ddd44279fdbc545a9182cb642645af8a4672c267 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 29 Jun 2015 10:50:03 +0300 Subject: target-xtensa: add 64-bit floating point registers Xtensa ISA got specification for 64-bit floating point registers and opcodes, see ISA, 4.3.11 "Floating point coprocessor option". Add 64-bit FP registers. Although 64-bit floating point is currently not supported by xtensa translator, these registers need to be reported to gdb with proper size, otherwise it wouldn't find other registers. Signed-off-by: Max Filippov --- target-xtensa/cpu.h | 18 +++++++++++++++++- target-xtensa/gdbstub.c | 25 +++++++++++++++++++++---- target-xtensa/overlay_tool.h | 2 +- target-xtensa/translate.c | 7 ++++--- 4 files changed, 43 insertions(+), 9 deletions(-) (limited to 'target-xtensa') diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index dfd0d1ceda..b592efb333 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -287,6 +287,7 @@ typedef struct XtensaGdbReg { int targno; int type; int group; + unsigned size; } XtensaGdbReg; typedef struct XtensaGdbRegmap { @@ -336,6 +337,18 @@ typedef struct XtensaConfigList { struct XtensaConfigList *next; } XtensaConfigList; +#ifdef HOST_WORDS_BIGENDIAN +enum { + FP_F32_HIGH, + FP_F32_LOW, +}; +#else +enum { + FP_F32_LOW, + FP_F32_HIGH, +}; +#endif + typedef struct CPUXtensaState { const XtensaConfig *config; uint32_t regs[16]; @@ -343,7 +356,10 @@ typedef struct CPUXtensaState { uint32_t sregs[256]; uint32_t uregs[256]; uint32_t phys_regs[MAX_NAREG]; - float32 fregs[16]; + union { + float32 f32[2]; + float64 f64; + } fregs[16]; float_status fp_status; xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE]; diff --git a/target-xtensa/gdbstub.c b/target-xtensa/gdbstub.c index 9e13b20c46..bc2e1b55f6 100644 --- a/target-xtensa/gdbstub.c +++ b/target-xtensa/gdbstub.c @@ -26,6 +26,7 @@ int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) XtensaCPU *cpu = XTENSA_CPU(cs); CPUXtensaState *env = &cpu->env; const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; + unsigned i; if (n < 0 || n >= env->config->gdb_regmap.num_regs) { return 0; @@ -47,8 +48,16 @@ int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]); case 4: /*f*/ - return gdb_get_reg32(mem_buf, float32_val(env->fregs[reg->targno - & 0x0f])); + i = reg->targno & 0x0f; + switch (reg->size) { + case 4: + return gdb_get_reg32(mem_buf, + float32_val(env->fregs[i].f32[FP_F32_LOW])); + case 8: + return gdb_get_reg64(mem_buf, float64_val(env->fregs[i].f64)); + default: + return 0; + } case 8: /*a*/ return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]); @@ -92,8 +101,16 @@ int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) break; case 4: /*f*/ - env->fregs[reg->targno & 0x0f] = make_float32(tmp); - break; + switch (reg->size) { + case 4: + env->fregs[reg->targno & 0x0f].f32[FP_F32_LOW] = make_float32(tmp); + return 4; + case 8: + env->fregs[reg->targno & 0x0f].f64 = make_float64(tmp); + return 8; + default: + return 0; + } case 8: /*a*/ env->regs[reg->targno & 0x0f] = tmp; diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h index 6105d4c8ff..f7b1510ab5 100644 --- a/target-xtensa/overlay_tool.h +++ b/target-xtensa/overlay_tool.h @@ -27,7 +27,7 @@ #define XTREG(idx, ofs, bi, sz, al, no, flags, cp, typ, grp, name, \ a1, a2, a3, a4, a5, a6) \ - { .targno = (no), .type = (typ), .group = (grp) }, + { .targno = (no), .type = (typ), .group = (grp), .size = (sz) }, #ifndef XCHAL_HAVE_DIV32 #define XCHAL_HAVE_DIV32 0 diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 86e4849fb6..f2118c24c0 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -228,7 +228,7 @@ void xtensa_translate_init(void) for (i = 0; i < 16; i++) { cpu_FR[i] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUXtensaState, fregs[i]), + offsetof(CPUXtensaState, fregs[i].f32[FP_F32_LOW]), fregnames[i]); } @@ -3206,8 +3206,9 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f, for (i = 0; i < 16; ++i) { cpu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i, - float32_val(env->fregs[i]), - *(float *)&env->fregs[i], (i % 2) == 1 ? '\n' : ' '); + float32_val(env->fregs[i].f32[FP_F32_LOW]), + *(float *)(env->fregs[i].f32 + FP_F32_LOW), + (i % 2) == 1 ? '\n' : ' '); } } } -- cgit v1.2.1