On Tue, Oct 18, 2011 at 6:50 PM, Richard Henderson <r...@twiddle.net> wrote: > This allows a more efficient representation for 64-bit hosts. > It should be about the same for 32-bit hosts, as we can still > access the individual pieces of the double. > > Signed-off-by: Richard Henderson <r...@twiddle.net> > --- > gdbstub.c | 35 +++++++--- > linux-user/signal.c | 28 +++++---- > monitor.c | 96 ++++++++++++++-------------- > target-sparc/cpu.h | 7 +- > target-sparc/cpu_init.c | 6 +- > target-sparc/ldst_helper.c | 71 +++++++++------------ > target-sparc/machine.c | 20 ++---- > target-sparc/translate.c | 146 ++++++++++++++++++++----------------------- > 8 files changed, 199 insertions(+), 210 deletions(-) > > diff --git a/gdbstub.c b/gdbstub.c > index 1d99e19..6c18634 100644 > --- a/gdbstub.c > +++ b/gdbstub.c > @@ -814,7 +814,11 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t > *mem_buf, int n) > #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) > if (n < 64) { > /* fprs */ > - GET_REG32(*((uint32_t *)&env->fpr[n - 32])); > + if (n & 1) { > + GET_REG32(env->fpr[(n - 32) / 2].l.lower); > + } else { > + GET_REG32(env->fpr[(n - 32) / 2].l.upper); > + } > } > /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ > switch (n) { > @@ -831,15 +835,15 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t > *mem_buf, int n) > #else > if (n < 64) { > /* f0-f31 */ > - GET_REG32(*((uint32_t *)&env->fpr[n - 32])); > + if (n & 1) { > + GET_REG32(env->fpr[(n - 32) / 2].l.lower); > + } else { > + GET_REG32(env->fpr[(n - 32) / 2].l.upper); > + } > } > if (n < 80) { > /* f32-f62 (double width, even numbers only) */ > - uint64_t val; > - > - val = (uint64_t)*((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) << 32; > - val |= *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]); > - GET_REG64(val); > + GET_REG64(env->fpr[(n - 32) / 2].ll); > } > switch (n) { > case 80: GET_REGL(env->pc); > @@ -878,7 +882,12 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t > *mem_buf, int n) > #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) > else if (n < 64) { > /* fprs */ > - *((uint32_t *)&env->fpr[n - 32]) = tmp; > + /* f0-f31 */ > + if (n & 1) { > + env->fpr[(n - 32) / 2].l.lower = tmp; > + } else { > + env->fpr[(n - 32) / 2].l.upper = tmp; > + } > } else { > /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ > switch (n) { > @@ -896,12 +905,16 @@ static int cpu_gdb_write_register(CPUState *env, > uint8_t *mem_buf, int n) > #else > else if (n < 64) { > /* f0-f31 */ > - env->fpr[n] = ldfl_p(mem_buf); > + tmp = ldl_p(mem_buf); > + if (n & 1) { > + env->fpr[(n - 32) / 2].l.lower = tmp; > + } else { > + env->fpr[(n - 32) / 2].l.upper = tmp; > + } > return 4; > } else if (n < 80) { > /* f32-f62 (double width, even numbers only) */ > - *((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) = tmp >> 32; > - *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]) = tmp; > + env->fpr[(n - 32) / 2].ll = tmp; > } else { > switch (n) { > case 80: env->pc = tmp; break; > diff --git a/linux-user/signal.c b/linux-user/signal.c > index 89276eb..d68dc94 100644 > --- a/linux-user/signal.c > +++ b/linux-user/signal.c > @@ -2299,12 +2299,14 @@ void sparc64_set_context(CPUSPARCState *env) > */ > err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs)); > { > - uint32_t *src, *dst; > - src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; > - dst = env->fpr; > - /* XXX: check that the CPU storage is the same as user context */ > - for (i = 0; i < 64; i++, dst++, src++) > - err |= __get_user(*dst, src); > + uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; > + for (i = 0; i < 64; i++, src++) { > + if (i & 1) { > + err |= __get_user(env->fpr[i/2].l.lower, src); > + } else { > + err |= __get_user(env->fpr[i/2].l.upper, src); > + } > + } > } > err |= __get_user(env->fsr, > &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr)); > @@ -2393,12 +2395,14 @@ void sparc64_get_context(CPUSPARCState *env) > err |= __put_user(i7, &(mcp->mc_i7)); > > { > - uint32_t *src, *dst; > - src = env->fpr; > - dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; > - /* XXX: check that the CPU storage is the same as user context */ > - for (i = 0; i < 64; i++, dst++, src++) > - err |= __put_user(*src, dst); > + uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; > + for (i = 0; i < 64; i++, dst++) { > + if (i & 1) { > + err |= __put_user(env->fpr[i/2].l.lower, dst); > + } else { > + err |= __put_user(env->fpr[i/2].l.upper, dst); > + } > + } > } > err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr)); > err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr)); > diff --git a/monitor.c b/monitor.c > index da13471..02d7e2e 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -3657,55 +3657,55 @@ static const MonitorDef monitor_defs[] = { > #endif > { "tbr", offsetof(CPUState, tbr) }, > { "fsr", offsetof(CPUState, fsr) }, > - { "f0", offsetof(CPUState, fpr[0]) }, > - { "f1", offsetof(CPUState, fpr[1]) }, > - { "f2", offsetof(CPUState, fpr[2]) }, > - { "f3", offsetof(CPUState, fpr[3]) }, > - { "f4", offsetof(CPUState, fpr[4]) }, > - { "f5", offsetof(CPUState, fpr[5]) }, > - { "f6", offsetof(CPUState, fpr[6]) }, > - { "f7", offsetof(CPUState, fpr[7]) }, > - { "f8", offsetof(CPUState, fpr[8]) }, > - { "f9", offsetof(CPUState, fpr[9]) }, > - { "f10", offsetof(CPUState, fpr[10]) }, > - { "f11", offsetof(CPUState, fpr[11]) }, > - { "f12", offsetof(CPUState, fpr[12]) }, > - { "f13", offsetof(CPUState, fpr[13]) }, > - { "f14", offsetof(CPUState, fpr[14]) }, > - { "f15", offsetof(CPUState, fpr[15]) }, > - { "f16", offsetof(CPUState, fpr[16]) }, > - { "f17", offsetof(CPUState, fpr[17]) }, > - { "f18", offsetof(CPUState, fpr[18]) }, > - { "f19", offsetof(CPUState, fpr[19]) }, > - { "f20", offsetof(CPUState, fpr[20]) }, > - { "f21", offsetof(CPUState, fpr[21]) }, > - { "f22", offsetof(CPUState, fpr[22]) }, > - { "f23", offsetof(CPUState, fpr[23]) }, > - { "f24", offsetof(CPUState, fpr[24]) }, > - { "f25", offsetof(CPUState, fpr[25]) }, > - { "f26", offsetof(CPUState, fpr[26]) }, > - { "f27", offsetof(CPUState, fpr[27]) }, > - { "f28", offsetof(CPUState, fpr[28]) }, > - { "f29", offsetof(CPUState, fpr[29]) }, > - { "f30", offsetof(CPUState, fpr[30]) }, > - { "f31", offsetof(CPUState, fpr[31]) }, > + { "f0", offsetof(CPUState, fpr[0].l.upper) }, > + { "f1", offsetof(CPUState, fpr[0].l.lower) }, > + { "f2", offsetof(CPUState, fpr[1].l.upper) }, > + { "f3", offsetof(CPUState, fpr[1].l.lower) }, > + { "f4", offsetof(CPUState, fpr[2].l.upper) }, > + { "f5", offsetof(CPUState, fpr[2].l.lower) }, > + { "f6", offsetof(CPUState, fpr[3].l.upper) }, > + { "f7", offsetof(CPUState, fpr[3].l.lower) }, > + { "f8", offsetof(CPUState, fpr[4].l.upper) }, > + { "f9", offsetof(CPUState, fpr[4].l.lower) }, > + { "f10", offsetof(CPUState, fpr[5].l.upper) }, > + { "f11", offsetof(CPUState, fpr[5].l.lower) }, > + { "f12", offsetof(CPUState, fpr[6].l.upper) }, > + { "f13", offsetof(CPUState, fpr[6].l.lower) }, > + { "f14", offsetof(CPUState, fpr[7].l.upper) }, > + { "f15", offsetof(CPUState, fpr[7].l.lower) }, > + { "f16", offsetof(CPUState, fpr[8].l.upper) }, > + { "f17", offsetof(CPUState, fpr[8].l.lower) }, > + { "f18", offsetof(CPUState, fpr[9].l.upper) }, > + { "f19", offsetof(CPUState, fpr[9].l.lower) }, > + { "f20", offsetof(CPUState, fpr[10].l.upper) }, > + { "f21", offsetof(CPUState, fpr[10].l.lower) }, > + { "f22", offsetof(CPUState, fpr[11].l.upper) }, > + { "f23", offsetof(CPUState, fpr[11].l.lower) }, > + { "f24", offsetof(CPUState, fpr[12].l.upper) }, > + { "f25", offsetof(CPUState, fpr[12].l.lower) }, > + { "f26", offsetof(CPUState, fpr[13].l.upper) }, > + { "f27", offsetof(CPUState, fpr[13].l.lower) }, > + { "f28", offsetof(CPUState, fpr[14].l.upper) }, > + { "f29", offsetof(CPUState, fpr[14].l.lower) }, > + { "f30", offsetof(CPUState, fpr[15].l.upper) }, > + { "f31", offsetof(CPUState, fpr[15].l.lower) }, > #ifdef TARGET_SPARC64 > - { "f32", offsetof(CPUState, fpr[32]) }, > - { "f34", offsetof(CPUState, fpr[34]) }, > - { "f36", offsetof(CPUState, fpr[36]) }, > - { "f38", offsetof(CPUState, fpr[38]) }, > - { "f40", offsetof(CPUState, fpr[40]) }, > - { "f42", offsetof(CPUState, fpr[42]) }, > - { "f44", offsetof(CPUState, fpr[44]) }, > - { "f46", offsetof(CPUState, fpr[46]) }, > - { "f48", offsetof(CPUState, fpr[48]) }, > - { "f50", offsetof(CPUState, fpr[50]) }, > - { "f52", offsetof(CPUState, fpr[52]) }, > - { "f54", offsetof(CPUState, fpr[54]) }, > - { "f56", offsetof(CPUState, fpr[56]) }, > - { "f58", offsetof(CPUState, fpr[58]) }, > - { "f60", offsetof(CPUState, fpr[60]) }, > - { "f62", offsetof(CPUState, fpr[62]) }, > + { "f32", offsetof(CPUState, fpr[16]) }, > + { "f34", offsetof(CPUState, fpr[17]) }, > + { "f36", offsetof(CPUState, fpr[18]) }, > + { "f38", offsetof(CPUState, fpr[19]) }, > + { "f40", offsetof(CPUState, fpr[20]) }, > + { "f42", offsetof(CPUState, fpr[21]) }, > + { "f44", offsetof(CPUState, fpr[22]) }, > + { "f46", offsetof(CPUState, fpr[23]) }, > + { "f48", offsetof(CPUState, fpr[24]) }, > + { "f50", offsetof(CPUState, fpr[25]) }, > + { "f52", offsetof(CPUState, fpr[26]) }, > + { "f54", offsetof(CPUState, fpr[27]) }, > + { "f56", offsetof(CPUState, fpr[28]) }, > + { "f58", offsetof(CPUState, fpr[29]) }, > + { "f60", offsetof(CPUState, fpr[30]) }, > + { "f62", offsetof(CPUState, fpr[31]) }, > { "asi", offsetof(CPUState, asi) }, > { "pstate", offsetof(CPUState, pstate) }, > { "cansave", offsetof(CPUState, cansave) }, > diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h > index a4419a5..71a890c 100644 > --- a/target-sparc/cpu.h > +++ b/target-sparc/cpu.h > @@ -3,16 +3,17 @@ > > #include "config.h" > #include "qemu-common.h" > +#include "bswap.h" > > #if !defined(TARGET_SPARC64) > #define TARGET_LONG_BITS 32 > -#define TARGET_FPREGS 32 > +#define TARGET_DPREGS 16 > #define TARGET_PAGE_BITS 12 /* 4k */ > #define TARGET_PHYS_ADDR_SPACE_BITS 36 > #define TARGET_VIRT_ADDR_SPACE_BITS 32 > #else > #define TARGET_LONG_BITS 64 > -#define TARGET_FPREGS 64 > +#define TARGET_DPREGS 32 > #define TARGET_PAGE_BITS 13 /* 8k */ > #define TARGET_PHYS_ADDR_SPACE_BITS 41 > # ifdef TARGET_ABI32 > @@ -395,7 +396,7 @@ typedef struct CPUSPARCState { > > uint32_t psr; /* processor state register */ > target_ulong fsr; /* FPU state register */ > - float32 fpr[TARGET_FPREGS]; /* floating point registers */ > + CPU_DoubleU fpr[TARGET_DPREGS]; /* floating point registers */ > uint32_t cwp; /* index of current register window (extracted > from PSR) */ > #if !defined(TARGET_SPARC64) || defined(TARGET_ABI32) > diff --git a/target-sparc/cpu_init.c b/target-sparc/cpu_init.c > index 08b72a9..1118f31 100644 > --- a/target-sparc/cpu_init.c > +++ b/target-sparc/cpu_init.c > @@ -813,11 +813,11 @@ void cpu_dump_state(CPUState *env, FILE *f, > fprintf_function cpu_fprintf, > } > } > cpu_fprintf(f, "\nFloating Point Registers:\n"); > - for (i = 0; i < TARGET_FPREGS; i++) { > + for (i = 0; i < TARGET_DPREGS; i++) { > if ((i & 3) == 0) { > - cpu_fprintf(f, "%%f%02d:", i); > + cpu_fprintf(f, "%%f%02d:", i * 2); > } > - cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]); > + cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll); > if ((i & 3) == 3) { > cpu_fprintf(f, "\n"); > } > diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c > index ec9b5f2..a4254e7 100644 > --- a/target-sparc/ldst_helper.c > +++ b/target-sparc/ldst_helper.c > @@ -2057,7 +2057,7 @@ void helper_ldf_asi(CPUState *env, target_ulong addr, > int asi, int size, > int rd) > { > unsigned int i; > - CPU_DoubleU u; > + target_ulong val; > > helper_check_align(env, addr, 3); > addr = asi_address_mask(env, asi, addr); > @@ -2072,13 +2072,11 @@ void helper_ldf_asi(CPUState *env, target_ulong addr, > int asi, int size, > return; > } > helper_check_align(env, addr, 0x3f); > - for (i = 0; i < 16; i++) { > - *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(env, addr, asi & > 0x8f, > - 4, 0); > - addr += 4; > + for (i = 0; i < 8; i++, rd += 2, addr += 8) { > + env->fpr[rd/2].ll = helper_ld_asi(env, addr, asi & 0x8f, 8, 0); > } > - > return; > + > case 0x16: /* UA2007 Block load primary, user privilege */ > case 0x17: /* UA2007 Block load secondary, user privilege */ > case 0x1e: /* UA2007 Block load primary LE, user privilege */ > @@ -2092,13 +2090,11 @@ void helper_ldf_asi(CPUState *env, target_ulong addr, > int asi, int size, > return; > } > helper_check_align(env, addr, 0x3f); > - for (i = 0; i < 16; i++) { > - *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(env, addr, asi & > 0x19, > - 4, 0); > - addr += 4; > + for (i = 0; i < 8; i++, rd += 2, addr += 4) { > + env->fpr[rd/2].ll = helper_ld_asi(env, addr, asi & 0x19, 8, 0); > } > - > return; > + > default: > break; > } > @@ -2106,20 +2102,19 @@ void helper_ldf_asi(CPUState *env, target_ulong addr, > int asi, int size, > switch (size) { > default: > case 4: > - *((uint32_t *)&env->fpr[rd]) = helper_ld_asi(env, addr, asi, size, > 0); > + val = helper_ld_asi(env, addr, asi, size, 0); > + if (rd & 1) { > + env->fpr[rd/2].l.lower = val; > + } else { > + env->fpr[rd/2].l.upper = val; > + } > break; > case 8: > - u.ll = helper_ld_asi(env, addr, asi, size, 0); > - *((uint32_t *)&env->fpr[rd++]) = u.l.upper; > - *((uint32_t *)&env->fpr[rd++]) = u.l.lower; > + env->fpr[rd/2].ll = helper_ld_asi(env, addr, asi, size, 0); > break; > case 16: > - u.ll = helper_ld_asi(env, addr, asi, 8, 0); > - *((uint32_t *)&env->fpr[rd++]) = u.l.upper; > - *((uint32_t *)&env->fpr[rd++]) = u.l.lower; > - u.ll = helper_ld_asi(env, addr + 8, asi, 8, 0); > - *((uint32_t *)&env->fpr[rd++]) = u.l.upper; > - *((uint32_t *)&env->fpr[rd++]) = u.l.lower; > + env->fpr[rd/2].ll = helper_ld_asi(env, addr, asi, 8, 0); > + env->fpr[rd/2 + 1].ll = helper_ld_asi(env, addr + 8, asi, 8, 0); > break; > } > } > @@ -2128,8 +2123,7 @@ void helper_stf_asi(CPUState *env, target_ulong addr, > int asi, int size, > int rd) > { > unsigned int i; > - target_ulong val = 0; > - CPU_DoubleU u; > + target_ulong val; > > helper_check_align(env, addr, 3); > addr = asi_address_mask(env, asi, addr); > @@ -2146,10 +2140,8 @@ void helper_stf_asi(CPUState *env, target_ulong addr, > int asi, int size, > return; > } > helper_check_align(env, addr, 0x3f); > - for (i = 0; i < 16; i++) { > - val = *(uint32_t *)&env->fpr[rd++]; > - helper_st_asi(env, addr, val, asi & 0x8f, 4); > - addr += 4; > + for (i = 0; i < 8; i++, rd += 2, addr += 8) { > + helper_st_asi(env, addr, env->fpr[rd/2].ll, asi & 0x8f, 8); > } > > return; > @@ -2166,10 +2158,8 @@ void helper_stf_asi(CPUState *env, target_ulong addr, > int asi, int size, > return; > } > helper_check_align(env, addr, 0x3f); > - for (i = 0; i < 16; i++) { > - val = *(uint32_t *)&env->fpr[rd++]; > - helper_st_asi(env, addr, val, asi & 0x19, 4); > - addr += 4; > + for (i = 0; i < 8; i++, rd += 2, addr += 8) { > + helper_st_asi(env, addr, env->fpr[rd/2].ll, asi & 0x19, 8); > } > > return; > @@ -2180,20 +2170,19 @@ void helper_stf_asi(CPUState *env, target_ulong addr, > int asi, int size, > switch (size) { > default: > case 4: > - helper_st_asi(env, addr, *(uint32_t *)&env->fpr[rd], asi, size); > + if (rd & 1) { > + val = env->fpr[rd/2].l.lower; > + } else { > + val = env->fpr[rd/2].l.upper; > + } > + helper_st_asi(env, addr, val, asi, size); > break; > case 8: > - u.l.upper = *(uint32_t *)&env->fpr[rd++]; > - u.l.lower = *(uint32_t *)&env->fpr[rd++]; > - helper_st_asi(env, addr, u.ll, asi, size); > + helper_st_asi(env, addr, env->fpr[rd/2].ll, asi, size); > break; > case 16: > - u.l.upper = *(uint32_t *)&env->fpr[rd++]; > - u.l.lower = *(uint32_t *)&env->fpr[rd++]; > - helper_st_asi(env, addr, u.ll, asi, 8); > - u.l.upper = *(uint32_t *)&env->fpr[rd++]; > - u.l.lower = *(uint32_t *)&env->fpr[rd++]; > - helper_st_asi(env, addr + 8, u.ll, asi, 8); > + helper_st_asi(env, addr, env->fpr[rd/2].ll, asi, 8); > + helper_st_asi(env, addr + 8, env->fpr[rd/2 + 1].ll, asi, 8); > break; > } > } > diff --git a/target-sparc/machine.c b/target-sparc/machine.c > index 56ae041..235b088 100644 > --- a/target-sparc/machine.c > +++ b/target-sparc/machine.c > @@ -21,13 +21,9 @@ void cpu_save(QEMUFile *f, void *opaque) > qemu_put_betls(f, &env->regbase[i]); > > /* FPU */ > - for(i = 0; i < TARGET_FPREGS; i++) { > - union { > - float32 f; > - uint32_t i; > - } u; > - u.f = env->fpr[i]; > - qemu_put_be32(f, u.i); > + for (i = 0; i < TARGET_DPREGS; i++) { > + qemu_put_be32(f, env->fpr[i].l.upper); > + qemu_put_be32(f, env->fpr[i].l.lower); > } > > qemu_put_betls(f, &env->pc); > @@ -128,13 +124,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) > qemu_get_betls(f, &env->regbase[i]); > > /* FPU */ > - for(i = 0; i < TARGET_FPREGS; i++) { > - union { > - float32 f; > - uint32_t i; > - } u; > - u.i = qemu_get_be32(f); > - env->fpr[i] = u.f; > + for (i = 0; i < TARGET_DPREGS; i++) { > + env->fpr[i].l.upper = qemu_get_be32(f); > + env->fpr[i].l.lower = qemu_get_be32(f); > } > > qemu_get_betls(f, &env->pc); > diff --git a/target-sparc/translate.c b/target-sparc/translate.c > index f8d3bf2..97a462b 100644 > --- a/target-sparc/translate.c > +++ b/target-sparc/translate.c > @@ -68,7 +68,7 @@ static TCGv cpu_tmp0; > static TCGv_i32 cpu_tmp32; > static TCGv_i64 cpu_tmp64; > /* Floating point registers */ > -static TCGv_i32 cpu_fpr[TARGET_FPREGS]; > +static TCGv_i64 cpu_fpr[TARGET_DPREGS]; > > static target_ulong gen_opc_npc[OPC_BUF_SIZE]; > static target_ulong gen_opc_jump_pc[2]; > @@ -87,8 +87,8 @@ typedef struct DisasContext { > uint32_t cc_op; /* current CC operation */ > struct TranslationBlock *tb; > sparc_def_t *def; > - TCGv_i64 t64[3]; > - int n_t64; > + TCGv_i32 t32[3]; > + int n_t32; > } DisasContext; > > // This function uses non-native bit order > @@ -131,12 +131,44 @@ static inline void gen_update_fprs_dirty(int rd) > /* floating point registers moves */ > static TCGv_i32 gen_load_fpr_F(DisasContext *dc, unsigned int src) > { > - return cpu_fpr[src]; > +#if TCG_TARGET_REG_BITS == 32 > + if (src & 1) { > + return TCGV_LOW(cpu_fpr[src / 2]); > + } else { > + return TCGV_HIGH(cpu_fpr[src / 2]); > + } > +#else > + if (src & 1) { > + return MAKE_TCGV_I32(GET_TCGV_I64(cpu_fpr[src / 2])); > + } else { > + TCGv_i32 ret = tcg_temp_local_new_i32(); > + TCGv_i64 t = tcg_temp_new_i64(); > + > + tcg_gen_shri_i64(t, cpu_fpr[src / 2], 32); > + tcg_gen_trunc_i64_i32(ret, t); > + tcg_temp_free_i64(t); > + > + dc->t32[dc->n_t32++] = ret; > + assert(dc->n_t32 <= ARRAY_SIZE(dc->t32)); > + > + return ret; > + } > +#endif > } > > static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v) > { > - tcg_gen_mov_i32(cpu_fpr[dst], v); > +#if TCG_TARGET_REG_BITS == 32 > + if (dst & 1) { > + tcg_gen_mov_i32(TCGV_LOW(cpu_fpr[dst / 2]), v); > + } else { > + tcg_gen_mov_i32(TCGV_HIGH(cpu_fpr[dst / 2]), v); > + } > +#else > + TCGv_i64 t = MAKE_TCGV_I64(GET_TCGV_I32(v)); > + tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t, > + (dst & 1 ? 0 : 32), 32); > +#endif > gen_update_fprs_dirty(dst); > } > > @@ -147,42 +179,14 @@ static TCGv_i32 gen_dest_fpr_F(void) > > static TCGv_i64 gen_load_fpr_D(DisasContext *dc, unsigned int src) > { > - TCGv_i64 ret = tcg_temp_new_i64(); > src = DFPREG(src); > - > -#if TCG_TARGET_REG_BITS == 32 > - tcg_gen_mov_i32(TCGV_HIGH(ret), cpu_fpr[src]); > - tcg_gen_mov_i32(TCGV_LOW(ret), cpu_fpr[src + 1]); > -#else > - { > - TCGv_i64 t = tcg_temp_new_i64(); > - tcg_gen_extu_i32_i64(ret, cpu_fpr[src]); > - tcg_gen_extu_i32_i64(t, cpu_fpr[src + 1]); > - tcg_gen_shli_i64(ret, ret, 32); > - tcg_gen_or_i64(ret, ret, t); > - tcg_temp_free_i64(t); > - } > -#endif > - > - dc->t64[dc->n_t64++] = ret; > - assert(dc->n_t64 <= ARRAY_SIZE(dc->t64)); > - > - return ret; > + return cpu_fpr[src / 2]; > } > > static void gen_store_fpr_D(DisasContext *dc, unsigned int dst, TCGv_i64 v) > { > dst = DFPREG(dst); > - > -#if TCG_TARGET_REG_BITS == 32 > - tcg_gen_mov_i32(cpu__fpu[dst], TCGV_HIGH(v)); > - tcg_gen_mov_i32(cpu__fpu[dst + 1], TCGV_LOW(v)); > -#else > - tcg_gen_trunc_i64_i32(cpu_fpr[dst + 1], v); > - tcg_gen_shri_i64(v, v, 32); > - tcg_gen_trunc_i64_i32(cpu_fpr[dst], v); > -#endif > - > + tcg_gen_mov_i64(cpu_fpr[dst / 2], v); > gen_update_fprs_dirty(dst); > } > > @@ -193,50 +197,36 @@ static TCGv_i64 gen_dest_fpr_D(void) > > static void gen_op_load_fpr_QT0(unsigned int src) > { > - tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) + > - offsetof(CPU_QuadU, l.upmost)); > - tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) + > - offsetof(CPU_QuadU, l.upper)); > - tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) + > - offsetof(CPU_QuadU, l.lower)); > - tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) + > - offsetof(CPU_QuadU, l.lowest)); > + tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt0) + > + offsetof(CPU_QuadU, ll.upper)); > + tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) > + > + offsetof(CPU_QuadU, ll.lower)); > } > > static void gen_op_load_fpr_QT1(unsigned int src) > { > - tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt1) + > - offsetof(CPU_QuadU, l.upmost)); > - tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt1) + > - offsetof(CPU_QuadU, l.upper)); > - tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt1) + > - offsetof(CPU_QuadU, l.lower)); > - tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt1) + > - offsetof(CPU_QuadU, l.lowest)); > + tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt1) + > + offsetof(CPU_QuadU, ll.upper)); > + tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt1) > + > + offsetof(CPU_QuadU, ll.lower)); > } > > static void gen_op_store_QT0_fpr(unsigned int dst) > { > - tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) + > - offsetof(CPU_QuadU, l.upmost)); > - tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) + > - offsetof(CPU_QuadU, l.upper)); > - tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) + > - offsetof(CPU_QuadU, l.lower)); > - tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) + > - offsetof(CPU_QuadU, l.lowest)); > + tcg_gen_ld_i64(cpu_fpr[dst / 2], cpu_env, offsetof(CPUSPARCState, qt0) + > + offsetof(CPU_QuadU, ll.upper)); > + tcg_gen_ld_i64(cpu_fpr[dst/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) > + > + offsetof(CPU_QuadU, ll.lower)); > } > > #ifdef TARGET_SPARC64 > -static void gen_move_Q(int rd, int rs) > +static void gen_move_Q(unsigned int rd, unsigned int rs) > { > rd = QFPREG(rd); > rs = QFPREG(rs); > > - tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs]); > - tcg_gen_mov_i32(cpu_fpr[rd + 1], cpu_fpr[rs + 1]); > - tcg_gen_mov_i32(cpu_fpr[rd + 2], cpu_fpr[rs + 2]); > - tcg_gen_mov_i32(cpu_fpr[rd + 3], cpu_fpr[rs + 3]); > + tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]); > + tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]); > gen_update_fprs_dirty(rd); > } > #endif > @@ -5008,6 +4998,13 @@ static void disas_sparc_insn(DisasContext * dc, > unsigned int insn) > egress: > tcg_temp_free(cpu_tmp1); > tcg_temp_free(cpu_tmp2); > + if (dc->n_t32 != 0) { > + int i; > + for (i = dc->n_t32 - 1; i >= 0; --i) { > + tcg_temp_free_i32(dc->t32[i]); > + } > + dc->n_t32 = 0; > + } > } > > static inline void gen_intermediate_code_internal(TranslationBlock * tb, > @@ -5109,9 +5106,6 @@ static inline void > gen_intermediate_code_internal(TranslationBlock * tb, > tcg_temp_free_i64(cpu_tmp64); > tcg_temp_free_i32(cpu_tmp32); > tcg_temp_free(cpu_tmp0); > - for (j = dc->n_t64 - 1; j >= 0; --j) { > - tcg_temp_free_i64(dc->t64[j]); > - } > > if (tb->cflags & CF_LAST_IO) > gen_io_end(); > @@ -5177,15 +5171,11 @@ void gen_intermediate_code_init(CPUSPARCState *env) > "g6", > "g7", > }; > - static const char * const fregnames[64] = { > - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", > - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", > - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", > - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", > - "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", > - "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", > - "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", > - "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63", > + static const char * const fregnames[32] = { > + "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14", > + "f16", "f18", "f20", "f22", "f24", "f26", "f28", "f30", > + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", > + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
Shouldn't these become "d0" etc? > }; > > /* init various static tables */ > @@ -5259,8 +5249,8 @@ void gen_intermediate_code_init(CPUSPARCState *env) > cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0, > offsetof(CPUState, gregs[i]), > gregnames[i]); > - for (i = 0; i < TARGET_FPREGS; i++) > - cpu_fpr[i] = tcg_global_mem_new_i32(TCG_AREG0, > + for (i = 0; i < TARGET_DPREGS; i++) Please add braces. > + cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0, > offsetof(CPUState, fpr[i]), > fregnames[i]); > > -- > 1.7.6.4 > >