target-sparc: Use global registers for the register window

Via indirection off cpu_regwptr.

Backports commit d2dc4069e046deeccc4dca0f73c3077ac22ba43f from qemu
This commit is contained in:
Richard Henderson 2018-02-20 20:31:03 -05:00 committed by Lioncash
parent 3653771265
commit d609ab30c2
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 69 additions and 81 deletions

View file

@ -260,41 +260,38 @@ static inline void gen_address_mask(DisasContext *dc, TCGv addr)
static inline TCGv gen_load_gpr(DisasContext *dc, int reg) static inline TCGv gen_load_gpr(DisasContext *dc, int reg)
{ {
TCGContext *tcg_ctx = dc->uc->tcg_ctx; TCGContext *tcg_ctx = dc->uc->tcg_ctx;
if (reg == 0 || reg >= 8) { TCGv **cpu_regs = (TCGv **)tcg_ctx->cpu_regs_sparc;
TCGv t = get_temp_tl(dc);
if (reg == 0) { if (reg > 0) {
tcg_gen_movi_tl(tcg_ctx, t, 0); assert(reg < 32);
} else { return *cpu_regs[reg];
tcg_gen_ld_tl(tcg_ctx, t, tcg_ctx->cpu_regwptr, (reg - 8) * sizeof(target_ulong));
}
return t;
} else { } else {
TCGv **cpu_gregs = (TCGv **)tcg_ctx->cpu_gregs; TCGv t = get_temp_tl(dc);
return *cpu_gregs[reg]; tcg_gen_movi_tl(tcg_ctx, t, 0);
return t;
} }
} }
static inline void gen_store_gpr(DisasContext *dc, int reg, TCGv v) static inline void gen_store_gpr(DisasContext *dc, int reg, TCGv v)
{ {
TCGContext *tcg_ctx = dc->uc->tcg_ctx; TCGContext *tcg_ctx = dc->uc->tcg_ctx;
if (reg > 0) { if (reg > 0) {
if (reg < 8) { TCGv **cpu_regs = (TCGv **)tcg_ctx->cpu_regs_sparc;
TCGv **cpu_gregs = (TCGv **)tcg_ctx->cpu_gregs; assert(reg < 32);
tcg_gen_mov_tl(tcg_ctx, *cpu_gregs[reg], v); tcg_gen_mov_tl(tcg_ctx, *cpu_regs[reg], v);
} else {
tcg_gen_st_tl(tcg_ctx, v, tcg_ctx->cpu_regwptr, (reg - 8) * sizeof(target_ulong));
}
} }
} }
static inline TCGv gen_dest_gpr(DisasContext *dc, int reg) static inline TCGv gen_dest_gpr(DisasContext *dc, int reg)
{ {
if (reg == 0 || reg >= 8) { if (reg > 0) {
return get_temp_tl(dc);
} else {
TCGContext *tcg_ctx = dc->uc->tcg_ctx; TCGContext *tcg_ctx = dc->uc->tcg_ctx;
TCGv **cpu_gregs = (TCGv **)tcg_ctx->cpu_gregs; TCGv **cpu_regs = (TCGv **)tcg_ctx->cpu_regs_sparc;
return *cpu_gregs[reg]; assert(reg < 32);
return *cpu_regs[reg];
} else {
return get_temp_tl(dc);
} }
} }
@ -2292,9 +2289,13 @@ static inline void gen_ldda_asi(DisasContext *dc, TCGv hi, TCGv addr,
tcg_temp_free_i32(tcg_ctx, r_size); tcg_temp_free_i32(tcg_ctx, r_size);
tcg_temp_free_i32(tcg_ctx, r_asi); tcg_temp_free_i32(tcg_ctx, r_asi);
t = gen_dest_gpr(dc, rd + 1); /* ??? Work around an apparent bug in Ubuntu gcc 4.8.2-10ubuntu2+12,
whereby "rd + 1" elicits "error: array subscript is above array".
Since we have already asserted that rd is even, the semantics
are unchanged. */
t = gen_dest_gpr(dc, rd | 1);
tcg_gen_trunc_i64_tl(tcg_ctx, t, t64); tcg_gen_trunc_i64_tl(tcg_ctx, t, t64);
gen_store_gpr(dc, rd + 1, t); gen_store_gpr(dc, rd | 1, t);
tcg_gen_shri_i64(tcg_ctx, t64, t64, 32); tcg_gen_shri_i64(tcg_ctx, t64, t64, 32);
tcg_gen_trunc_i64_tl(tcg_ctx, hi, t64); tcg_gen_trunc_i64_tl(tcg_ctx, hi, t64);
@ -5503,15 +5504,11 @@ void gen_intermediate_code_init(CPUSPARCState *env)
TCGContext *tcg_ctx = env->uc->tcg_ctx; TCGContext *tcg_ctx = env->uc->tcg_ctx;
struct uc_struct *uc = env->uc; struct uc_struct *uc = env->uc;
unsigned int i; unsigned int i;
static const char * const gregnames[8] = { static const char gregnames[32][4] = {
NULL, // g0 not used "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
"g1", "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
"g2", "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
"g3", "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
"g4",
"g5",
"g6",
"g7",
}; };
static const char * const fregnames[32] = { static const char * const fregnames[32] = {
"f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14", "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14",
@ -5521,6 +5518,9 @@ void gen_intermediate_code_init(CPUSPARCState *env)
}; };
/* init various static tables */ /* init various static tables */
if (uc->init_tcg) {
return;
}
tcg_ctx->cpu_env = tcg_global_reg_new_ptr(tcg_ctx, TCG_AREG0, "env"); tcg_ctx->cpu_env = tcg_global_reg_new_ptr(tcg_ctx, TCG_AREG0, "env");
tcg_ctx->cpu_regwptr = tcg_global_mem_new_ptr(tcg_ctx, tcg_ctx->cpu_env, tcg_ctx->cpu_regwptr = tcg_global_mem_new_ptr(tcg_ctx, tcg_ctx->cpu_env,
offsetof(CPUSPARCState, regwptr), offsetof(CPUSPARCState, regwptr),
@ -5533,51 +5533,42 @@ void gen_intermediate_code_init(CPUSPARCState *env)
tcg_ctx->cpu_fprs = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, fprs), tcg_ctx->cpu_fprs = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, fprs),
"fprs"); "fprs");
if (!uc->init_tcg) tcg_ctx->cpu_gsr = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_gsr = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_gsr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, gsr), *(TCGv *)tcg_ctx->cpu_gsr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, gsr),
"gsr"); "gsr");
if (!uc->init_tcg) tcg_ctx->cpu_tick_cmpr = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_tick_cmpr = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_tick_cmpr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, *(TCGv *)tcg_ctx->cpu_tick_cmpr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
offsetof(CPUSPARCState, tick_cmpr), offsetof(CPUSPARCState, tick_cmpr),
"tick_cmpr"); "tick_cmpr");
if (!uc->init_tcg) tcg_ctx->cpu_stick_cmpr = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_stick_cmpr = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_stick_cmpr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, *(TCGv *)tcg_ctx->cpu_stick_cmpr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
offsetof(CPUSPARCState, stick_cmpr), offsetof(CPUSPARCState, stick_cmpr),
"stick_cmpr"); "stick_cmpr");
if (!uc->init_tcg) tcg_ctx->cpu_hstick_cmpr = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_hstick_cmpr = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_hstick_cmpr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, *(TCGv *)tcg_ctx->cpu_hstick_cmpr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
offsetof(CPUSPARCState, hstick_cmpr), offsetof(CPUSPARCState, hstick_cmpr),
"hstick_cmpr"); "hstick_cmpr");
if (!uc->init_tcg) tcg_ctx->cpu_hintp = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_hintp = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_hintp = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, hintp), *(TCGv *)tcg_ctx->cpu_hintp = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, hintp),
"hintp"); "hintp");
if (!uc->init_tcg) tcg_ctx->cpu_htba = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_htba = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_htba = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, htba), *(TCGv *)tcg_ctx->cpu_htba = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, htba),
"htba"); "htba");
if (!uc->init_tcg) tcg_ctx->cpu_hver = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_hver = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_hver = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, hver), *(TCGv *)tcg_ctx->cpu_hver = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, hver),
"hver"); "hver");
if (!uc->init_tcg) tcg_ctx->cpu_ssr = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_ssr = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_ssr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, *(TCGv *)tcg_ctx->cpu_ssr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
offsetof(CPUSPARCState, ssr), "ssr"); offsetof(CPUSPARCState, ssr), "ssr");
if (!uc->init_tcg) tcg_ctx->cpu_ver = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_ver = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_ver = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, *(TCGv *)tcg_ctx->cpu_ver = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
offsetof(CPUSPARCState, version), "ver"); offsetof(CPUSPARCState, version), "ver");
@ -5585,30 +5576,24 @@ void gen_intermediate_code_init(CPUSPARCState *env)
offsetof(CPUSPARCState, softint), offsetof(CPUSPARCState, softint),
"softint"); "softint");
#else #else
if (!uc->init_tcg) tcg_ctx->cpu_wim = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_wim = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_wim = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, wim), *(TCGv *)tcg_ctx->cpu_wim = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, wim),
"wim"); "wim");
#endif #endif
tcg_ctx->cpu_cond = g_malloc0(sizeof(TCGv));
if (!uc->init_tcg)
tcg_ctx->cpu_cond = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_cond = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, cond), *(TCGv *)tcg_ctx->cpu_cond = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, cond),
"cond"); "cond");
if (!uc->init_tcg) tcg_ctx->cpu_cc_src = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_cc_src = g_malloc0(sizeof(TCGv));
*((TCGv *)tcg_ctx->cpu_cc_src) = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, cc_src), *((TCGv *)tcg_ctx->cpu_cc_src) = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, cc_src),
"cc_src"); "cc_src");
if (!uc->init_tcg) tcg_ctx->cpu_cc_src2 = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_cc_src2 = g_malloc0(sizeof(TCGv));
*((TCGv *)tcg_ctx->cpu_cc_src2) = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, *((TCGv *)tcg_ctx->cpu_cc_src2) = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
offsetof(CPUSPARCState, cc_src2), offsetof(CPUSPARCState, cc_src2),
"cc_src2"); "cc_src2");
if (!uc->init_tcg) tcg_ctx->cpu_cc_dst = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_cc_dst = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_cc_dst = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, cc_dst), *(TCGv *)tcg_ctx->cpu_cc_dst = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, cc_dst),
"cc_dst"); "cc_dst");
@ -5617,37 +5602,39 @@ void gen_intermediate_code_init(CPUSPARCState *env)
tcg_ctx->cpu_psr = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, psr), tcg_ctx->cpu_psr = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, psr),
"psr"); "psr");
if (!uc->init_tcg) tcg_ctx->cpu_fsr = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_fsr = g_malloc0(sizeof(TCGv));
*((TCGv *)tcg_ctx->cpu_fsr) = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, fsr), *((TCGv *)tcg_ctx->cpu_fsr) = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, fsr),
"fsr"); "fsr");
if (!uc->init_tcg) tcg_ctx->sparc_cpu_pc = g_malloc0(sizeof(TCGv));
tcg_ctx->sparc_cpu_pc = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->sparc_cpu_pc = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, pc), *(TCGv *)tcg_ctx->sparc_cpu_pc = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, pc),
"pc"); "pc");
if (!uc->init_tcg) tcg_ctx->cpu_npc = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_npc = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_npc = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, npc), *(TCGv *)tcg_ctx->cpu_npc = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, npc),
"npc"); "npc");
if (!uc->init_tcg) tcg_ctx->cpu_y = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_y = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_y = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, y), "y"); *(TCGv *)tcg_ctx->cpu_y = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, y), "y");
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
if (!uc->init_tcg) tcg_ctx->cpu_tbr = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_tbr = g_malloc0(sizeof(TCGv));
*(TCGv *)tcg_ctx->cpu_tbr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, tbr), *(TCGv *)tcg_ctx->cpu_tbr = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPUSPARCState, tbr),
"tbr"); "tbr");
#endif #endif
if (!uc->init_tcg) {
for (i = 0; i < 8; i++) { TCGV_UNUSED(tcg_ctx->cpu_regs[0]);
tcg_ctx->cpu_gregs[i] = g_malloc0(sizeof(TCGv)); for (i = 1; i < 8; ++i) {
*((TCGv *)tcg_ctx->cpu_gregs[i]) = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, tcg_ctx->cpu_regs_sparc[i] = g_malloc0(sizeof(TCGv));
offsetof(CPUSPARCState, gregs[i]), tcg_ctx->cpu_regs_sparc[i] = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
gregnames[i]); offsetof(CPUSPARCState, gregs[i]),
} gregnames[i]);
}
for (i = 8; i < 32; ++i) {
tcg_ctx->cpu_regs_sparc[i] = g_malloc0(sizeof(TCGv));
tcg_ctx->cpu_regs_sparc[i] = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_regwptr,
(i - 8) * sizeof(target_ulong),
gregnames[i]);
} }
for (i = 0; i < TARGET_DPREGS; i++) { for (i = 0; i < TARGET_DPREGS; i++) {

View file

@ -45,8 +45,8 @@ void sparc_release(void *ctx)
g_free(tcg_ctx->cpu_y); g_free(tcg_ctx->cpu_y);
g_free(tcg_ctx->cpu_tbr); g_free(tcg_ctx->cpu_tbr);
for (i = 0; i < 8; i++) { for (i = 0; i < 32; i++) {
g_free(tcg_ctx->cpu_gregs[i]); g_free(tcg_ctx->cpu_regs_sparc[i]);
} }
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
g_free(tcg_ctx->cpu_gpr[i]); g_free(tcg_ctx->cpu_gpr[i]);

View file

@ -811,7 +811,8 @@ struct TCGContext {
TCGv_i64 cpu_fpr[32]; // TARGET_DPREGS = 32 for Sparc64, 16 for Sparc TCGv_i64 cpu_fpr[32]; // TARGET_DPREGS = 32 for Sparc64, 16 for Sparc
// void *cpu_cc_src, *cpu_cc_src2, *cpu_cc_dst; // void *cpu_cc_src, *cpu_cc_src2, *cpu_cc_dst;
void *cpu_fsr, *sparc_cpu_pc, *cpu_npc, *cpu_gregs[8]; void *cpu_fsr, *sparc_cpu_pc, *cpu_npc;
void *cpu_regs_sparc[32];
void *cpu_y; void *cpu_y;
void *cpu_tbr; void *cpu_tbr;
void *cpu_cond; void *cpu_cond;