diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index dfd0d1ceda5a1db1e7eb78377f16519b7c514aea..b592efb3332918cdfcc1e12bb60237bbb835944d 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 9e13b20c4615a2b2a25086e67c7c577df8510326..bc2e1b55f67d6c1e81936c51a820c2773980c874 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 6105d4c8ffbe2e6bfc3ba0e931b8d22797bbe97e..f7b1510ab5848f7e2d6101a1d31b0d2c740c05ef 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 86e4849fb652cc9bf8c6d909c37053d9a93f7b2b..f2118c24c03522b09c3a442376ef9257ec1f1e2f 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' : ' '); } } }