* [Qemu-devel] [RFC 01/16] tcg: Change tcg_global_mem_new_* to take a TCGv_ptr
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
@ 2013-09-19 21:24 ` Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 02/16] tcg: Introduce TCGTempType Richard Henderson
` (16 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:24 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Thus, use cpu_env as the parameter, not TCG_AREG0 directly.
Update all uses in the translators.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-alpha/translate.c | 40 +++++++++++----------
target-arm/translate.c | 20 +++++------
target-cris/translate.c | 24 ++++++-------
target-cris/translate_v10.c | 82 +++++++++++++++++++++----------------------
target-i386/translate.c | 56 ++++++++++++++---------------
target-lm32/translate.c | 24 ++++++-------
target-m68k/translate.c | 28 ++++++++-------
target-microblaze/translate.c | 14 ++++----
target-mips/translate.c | 25 ++++++-------
target-moxie/translate.c | 8 ++---
target-openrisc/translate.c | 26 +++++++-------
target-ppc/translate.c | 40 ++++++++++-----------
target-s390x/translate.c | 16 ++++-----
target-sh4/translate.c | 36 +++++++++----------
target-sparc/translate.c | 60 ++++++++++++++++---------------
target-unicore32/translate.c | 2 +-
target-xtensa/translate.c | 10 +++---
tcg/tcg.c | 21 +++--------
tcg/tcg.h | 38 +++++++++++++++-----
19 files changed, 296 insertions(+), 274 deletions(-)
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 28ce436..4c92ce5 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -108,35 +108,39 @@ void alpha_translate_init(void)
p = cpu_reg_names;
for (i = 0; i < 31; i++) {
sprintf(p, "ir%d", i);
- cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_ir[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUAlphaState, ir[i]), p);
p += (i < 10) ? 4 : 5;
sprintf(p, "fir%d", i);
- cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_fir[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUAlphaState, fir[i]), p);
p += (i < 10) ? 5 : 6;
}
- cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_pc = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUAlphaState, pc), "pc");
- cpu_lock_addr = tcg_global_mem_new_i64(TCG_AREG0,
- offsetof(CPUAlphaState, lock_addr),
- "lock_addr");
- cpu_lock_st_addr = tcg_global_mem_new_i64(TCG_AREG0,
- offsetof(CPUAlphaState, lock_st_addr),
- "lock_st_addr");
- cpu_lock_value = tcg_global_mem_new_i64(TCG_AREG0,
- offsetof(CPUAlphaState, lock_value),
- "lock_value");
-
- cpu_unique = tcg_global_mem_new_i64(TCG_AREG0,
- offsetof(CPUAlphaState, unique), "unique");
+ cpu_lock_addr = tcg_global_mem_new_i64(cpu_env,
+ offsetof(CPUAlphaState, lock_addr),
+ "lock_addr");
+ cpu_lock_st_addr = tcg_global_mem_new_i64(cpu_env,
+ offsetof(CPUAlphaState,
+ lock_st_addr),
+ "lock_st_addr");
+ cpu_lock_value = tcg_global_mem_new_i64(cpu_env,
+ offsetof(CPUAlphaState,
+ lock_value),
+ "lock_value");
+
+ cpu_unique = tcg_global_mem_new_i64(cpu_env,
+ offsetof(CPUAlphaState, unique),
+ "unique");
#ifndef CONFIG_USER_ONLY
- cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0,
- offsetof(CPUAlphaState, sysval), "sysval");
- cpu_usp = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_sysval = tcg_global_mem_new_i64(cpu_env,
+ offsetof(CPUAlphaState, sysval),
+ "sysval");
+ cpu_usp = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUAlphaState, usp), "usp");
#endif
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 998bde2..5fb38ca 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -92,25 +92,25 @@ void arm_translate_init(void)
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
for (i = 0; i < 16; i++) {
- cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUARMState, regs[i]),
regnames[i]);
}
- cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
- cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
- cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
- cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
+ cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
+ cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
+ cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
+ cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
- cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_exclusive_addr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
- cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_exclusive_val = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUARMState, exclusive_val), "exclusive_val");
- cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_exclusive_high = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUARMState, exclusive_high), "exclusive_high");
#ifdef CONFIG_USER_ONLY
- cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_exclusive_test = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUARMState, exclusive_test), "exclusive_test");
- cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_exclusive_info = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUARMState, exclusive_info), "exclusive_info");
#endif
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 617e1b4..5e3154c 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3484,41 +3484,41 @@ void cris_initialize_tcg(void)
#include "helper.h"
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cc_x = tcg_global_mem_new(TCG_AREG0,
+ cc_x = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, cc_x), "cc_x");
- cc_src = tcg_global_mem_new(TCG_AREG0,
+ cc_src = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, cc_src), "cc_src");
- cc_dest = tcg_global_mem_new(TCG_AREG0,
+ cc_dest = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, cc_dest),
"cc_dest");
- cc_result = tcg_global_mem_new(TCG_AREG0,
+ cc_result = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, cc_result),
"cc_result");
- cc_op = tcg_global_mem_new(TCG_AREG0,
+ cc_op = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, cc_op), "cc_op");
- cc_size = tcg_global_mem_new(TCG_AREG0,
+ cc_size = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, cc_size),
"cc_size");
- cc_mask = tcg_global_mem_new(TCG_AREG0,
+ cc_mask = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, cc_mask),
"cc_mask");
- env_pc = tcg_global_mem_new(TCG_AREG0,
+ env_pc = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, pc),
"pc");
- env_btarget = tcg_global_mem_new(TCG_AREG0,
+ env_btarget = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, btarget),
"btarget");
- env_btaken = tcg_global_mem_new(TCG_AREG0,
+ env_btaken = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, btaken),
"btaken");
for (i = 0; i < 16; i++) {
- cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_R[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, regs[i]),
regnames[i]);
}
for (i = 0; i < 16; i++) {
- cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_PR[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, pregs[i]),
pregnames[i]);
}
diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
index d6ef084..7544099 100644
--- a/target-cris/translate_v10.c
+++ b/target-cris/translate_v10.c
@@ -1259,45 +1259,45 @@ static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc)
void cris_initialize_crisv10_tcg(void)
{
- int i;
-
- cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cc_x = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, cc_x), "cc_x");
- cc_src = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, cc_src), "cc_src");
- cc_dest = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, cc_dest),
- "cc_dest");
- cc_result = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, cc_result),
- "cc_result");
- cc_op = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, cc_op), "cc_op");
- cc_size = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, cc_size),
- "cc_size");
- cc_mask = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, cc_mask),
- "cc_mask");
-
- env_pc = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, pc),
- "pc");
- env_btarget = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, btarget),
- "btarget");
- env_btaken = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, btaken),
- "btaken");
- for (i = 0; i < 16; i++) {
- cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, regs[i]),
- regnames_v10[i]);
- }
- for (i = 0; i < 16; i++) {
- cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
- offsetof(CPUCRISState, pregs[i]),
- pregnames_v10[i]);
- }
+ int i;
+
+ cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+ cc_x = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, cc_x), "cc_x");
+ cc_src = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, cc_src), "cc_src");
+ cc_dest = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, cc_dest),
+ "cc_dest");
+ cc_result = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, cc_result),
+ "cc_result");
+ cc_op = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, cc_op), "cc_op");
+ cc_size = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, cc_size),
+ "cc_size");
+ cc_mask = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, cc_mask),
+ "cc_mask");
+
+ env_pc = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, pc),
+ "pc");
+ env_btarget = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, btarget),
+ "btarget");
+ env_btaken = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, btaken),
+ "btaken");
+ for (i = 0; i < 16; i++) {
+ cpu_R[i] = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, regs[i]),
+ regnames_v10[i]);
+ }
+ for (i = 0; i < 16; i++) {
+ cpu_PR[i] = tcg_global_mem_new(cpu_env,
+ offsetof(CPUCRISState, pregs[i]),
+ pregnames_v10[i]);
+ }
}
diff --git a/target-i386/translate.c b/target-i386/translate.c
index be74ebc..3a3ba50 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8201,64 +8201,64 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
void optimize_flags_init(void)
{
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, cc_op), "cc_op");
- cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
+ cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
"cc_dst");
- cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src),
+ cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
"cc_src");
- cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src2),
+ cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
"cc_src2");
#ifdef TARGET_X86_64
- cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[R_EAX] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[R_EAX]), "rax");
- cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[R_ECX] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[R_ECX]), "rcx");
- cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[R_EDX] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[R_EDX]), "rdx");
- cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[R_EBX] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[R_EBX]), "rbx");
- cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[R_ESP] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[R_ESP]), "rsp");
- cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[R_EBP] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[R_EBP]), "rbp");
- cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[R_ESI] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[R_ESI]), "rsi");
- cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[R_EDI] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[R_EDI]), "rdi");
- cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[8] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[8]), "r8");
- cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[9] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[9]), "r9");
- cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[10] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[10]), "r10");
- cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[11] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[11]), "r11");
- cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[12] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[12]), "r12");
- cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[13] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[13]), "r13");
- cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[14] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[14]), "r14");
- cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[15] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUX86State, regs[15]), "r15");
#else
- cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_regs[R_EAX] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, regs[R_EAX]), "eax");
- cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_regs[R_ECX] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, regs[R_ECX]), "ecx");
- cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_regs[R_EDX] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, regs[R_EDX]), "edx");
- cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_regs[R_EBX] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, regs[R_EBX]), "ebx");
- cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_regs[R_ESP] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, regs[R_ESP]), "esp");
- cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_regs[R_EBP] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, regs[R_EBP]), "ebp");
- cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_regs[R_ESI] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, regs[R_ESI]), "esi");
- cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_regs[R_EDI] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUX86State, regs[R_EDI]), "edi");
#endif
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 6ea0ecd..510faa3 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1190,48 +1190,48 @@ void lm32_translate_init(void)
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
- cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_R[i] = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, regs[i]),
regnames[i]);
}
for (i = 0; i < ARRAY_SIZE(cpu_bp); i++) {
- cpu_bp[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_bp[i] = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, bp[i]),
regnames[32+i]);
}
for (i = 0; i < ARRAY_SIZE(cpu_wp); i++) {
- cpu_wp[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_wp[i] = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, wp[i]),
regnames[36+i]);
}
- cpu_pc = tcg_global_mem_new(TCG_AREG0,
+ cpu_pc = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, pc),
"pc");
- cpu_ie = tcg_global_mem_new(TCG_AREG0,
+ cpu_ie = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, ie),
"ie");
- cpu_icc = tcg_global_mem_new(TCG_AREG0,
+ cpu_icc = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, icc),
"icc");
- cpu_dcc = tcg_global_mem_new(TCG_AREG0,
+ cpu_dcc = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, dcc),
"dcc");
- cpu_cc = tcg_global_mem_new(TCG_AREG0,
+ cpu_cc = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, cc),
"cc");
- cpu_cfg = tcg_global_mem_new(TCG_AREG0,
+ cpu_cfg = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, cfg),
"cfg");
- cpu_eba = tcg_global_mem_new(TCG_AREG0,
+ cpu_eba = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, eba),
"eba");
- cpu_dc = tcg_global_mem_new(TCG_AREG0,
+ cpu_dc = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, dc),
"dc");
- cpu_deba = tcg_global_mem_new(TCG_AREG0,
+ cpu_deba = tcg_global_mem_new(cpu_env,
offsetof(CPULM32State, deba),
"deba");
}
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0be0a96..3b6485b 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -70,44 +70,48 @@ void m68k_tcg_init(void)
char *p;
int i;
-#define DEFO32(name, offset) QREG_##name = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUM68KState, offset), #name);
-#define DEFO64(name, offset) QREG_##name = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUM68KState, offset), #name);
-#define DEFF64(name, offset) DEFO64(name, offset)
+ cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+
+#define DEFO32(name, offset) \
+ QREG_##name = tcg_global_mem_new_i32(cpu_env, \
+ offsetof(CPUM68KState, offset), #name);
+#define DEFO64(name, offset) \
+ QREG_##name = tcg_global_mem_new_i64(cpu_env, \
+ offsetof(CPUM68KState, offset), #name);
+#define DEFF64(name, offset) DEFO64(name, offset)
#include "qregs.def"
#undef DEFO32
#undef DEFO64
#undef DEFF64
- cpu_halted = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_halted = tcg_global_mem_new_i32(cpu_env,
-offsetof(M68kCPU, env) +
offsetof(CPUState, halted), "HALTED");
- cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-
p = cpu_reg_names;
for (i = 0; i < 8; i++) {
sprintf(p, "D%d", i);
- cpu_dregs[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_dregs[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUM68KState, dregs[i]), p);
p += 3;
sprintf(p, "A%d", i);
- cpu_aregs[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_aregs[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUM68KState, aregs[i]), p);
p += 3;
sprintf(p, "F%d", i);
- cpu_fregs[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_fregs[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUM68KState, fregs[i]), p);
p += 3;
}
for (i = 0; i < 4; i++) {
sprintf(p, "ACC%d", i);
- cpu_macc[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_macc[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUM68KState, macc[i]), p);
p += 5;
}
- NULL_QREG = tcg_global_mem_new(TCG_AREG0, -4, "NULL");
- store_dummy = tcg_global_mem_new(TCG_AREG0, -8, "NULL");
+ NULL_QREG = tcg_global_mem_new(cpu_env, -4, "NULL");
+ store_dummy = tcg_global_mem_new(cpu_env, -8, "NULL");
#define GEN_HELPER 2
#include "helpers.h"
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 0673176..2a76939 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1999,28 +1999,28 @@ void mb_tcg_init(void)
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- env_debug = tcg_global_mem_new(TCG_AREG0,
+ env_debug = tcg_global_mem_new(cpu_env,
offsetof(CPUMBState, debug),
"debug0");
- env_iflags = tcg_global_mem_new(TCG_AREG0,
+ env_iflags = tcg_global_mem_new(cpu_env,
offsetof(CPUMBState, iflags),
"iflags");
- env_imm = tcg_global_mem_new(TCG_AREG0,
+ env_imm = tcg_global_mem_new(cpu_env,
offsetof(CPUMBState, imm),
"imm");
- env_btarget = tcg_global_mem_new(TCG_AREG0,
+ env_btarget = tcg_global_mem_new(cpu_env,
offsetof(CPUMBState, btarget),
"btarget");
- env_btaken = tcg_global_mem_new(TCG_AREG0,
+ env_btaken = tcg_global_mem_new(cpu_env,
offsetof(CPUMBState, btaken),
"btaken");
for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
- cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_R[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUMBState, regs[i]),
regnames[i]);
}
for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
- cpu_SR[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_SR[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUMBState, sregs[i]),
special_regnames[i]);
}
diff --git a/target-mips/translate.c b/target-mips/translate.c
index ad43d59..fd92936 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15845,44 +15845,45 @@ void mips_tcg_init(void)
return;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+
TCGV_UNUSED(cpu_gpr[0]);
for (i = 1; i < 32; i++)
- cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_gpr[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, active_tc.gpr[i]),
regnames[i]);
for (i = 0; i < 32; i++) {
int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
- fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
+ fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
}
- cpu_PC = tcg_global_mem_new(TCG_AREG0,
+ cpu_PC = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, active_tc.PC), "PC");
for (i = 0; i < MIPS_DSP_ACC; i++) {
- cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_HI[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, active_tc.HI[i]),
regnames_HI[i]);
- cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_LO[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, active_tc.LO[i]),
regnames_LO[i]);
- cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_ACX[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, active_tc.ACX[i]),
regnames_ACX[i]);
}
- cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
+ cpu_dspctrl = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, active_tc.DSPControl),
"DSPControl");
- bcond = tcg_global_mem_new(TCG_AREG0,
+ bcond = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, bcond), "bcond");
- btarget = tcg_global_mem_new(TCG_AREG0,
+ btarget = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, btarget), "btarget");
- hflags = tcg_global_mem_new_i32(TCG_AREG0,
+ hflags = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUMIPSState, hflags), "hflags");
- fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
+ fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUMIPSState, active_fpu.fcr0),
"fcr0");
- fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
+ fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUMIPSState, active_fpu.fcr31),
"fcr31");
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index a93196f..e0bb432 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -110,16 +110,16 @@ void moxie_translate_init(void)
return;
}
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_pc = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUMoxieState, pc), "$pc");
for (i = 0; i < 16; i++)
- cpu_gregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUMoxieState, gregs[i]),
gregnames[i]);
- cc_a = tcg_global_mem_new_i32(TCG_AREG0,
+ cc_a = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUMoxieState, cc_a), "cc_a");
- cc_b = tcg_global_mem_new_i32(TCG_AREG0,
+ cc_b = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUMoxieState, cc_b), "cc_b");
done_init = 1;
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 723b77d..4d1d88d 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -74,39 +74,39 @@ void openrisc_translate_init(void)
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cpu_sr = tcg_global_mem_new(TCG_AREG0,
+ cpu_sr = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, sr), "sr");
- env_flags = tcg_global_mem_new_i32(TCG_AREG0,
+ env_flags = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUOpenRISCState, flags),
"flags");
- cpu_pc = tcg_global_mem_new(TCG_AREG0,
+ cpu_pc = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, pc), "pc");
- cpu_npc = tcg_global_mem_new(TCG_AREG0,
+ cpu_npc = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, npc), "npc");
- cpu_ppc = tcg_global_mem_new(TCG_AREG0,
+ cpu_ppc = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, ppc), "ppc");
- jmp_pc = tcg_global_mem_new(TCG_AREG0,
+ jmp_pc = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
- env_btaken = tcg_global_mem_new_i32(TCG_AREG0,
+ env_btaken = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUOpenRISCState, btaken),
"btaken");
- fpcsr = tcg_global_mem_new_i32(TCG_AREG0,
+ fpcsr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUOpenRISCState, fpcsr),
"fpcsr");
- machi = tcg_global_mem_new(TCG_AREG0,
+ machi = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, machi),
"machi");
- maclo = tcg_global_mem_new(TCG_AREG0,
+ maclo = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, maclo),
"maclo");
- fpmaddhi = tcg_global_mem_new(TCG_AREG0,
+ fpmaddhi = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, fpmaddhi),
"fpmaddhi");
- fpmaddlo = tcg_global_mem_new(TCG_AREG0,
+ fpmaddlo = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, fpmaddlo),
"fpmaddlo");
for (i = 0; i < 32; i++) {
- cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_R[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, gpr[i]),
regnames[i]);
}
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2da7bc7..d1537c4 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -90,7 +90,7 @@ void ppc_translate_init(void)
for (i = 0; i < 8; i++) {
snprintf(p, cpu_reg_names_size, "crf%d", i);
- cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_crf[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUPPCState, crf[i]), p);
p += 5;
cpu_reg_names_size -= 5;
@@ -98,30 +98,30 @@ void ppc_translate_init(void)
for (i = 0; i < 32; i++) {
snprintf(p, cpu_reg_names_size, "r%d", i);
- cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_gpr[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, gpr[i]), p);
p += (i < 10) ? 3 : 4;
cpu_reg_names_size -= (i < 10) ? 3 : 4;
#if !defined(TARGET_PPC64)
snprintf(p, cpu_reg_names_size, "r%dH", i);
- cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_gprh[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUPPCState, gprh[i]), p);
p += (i < 10) ? 4 : 5;
cpu_reg_names_size -= (i < 10) ? 4 : 5;
#endif
snprintf(p, cpu_reg_names_size, "fp%d", i);
- cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUPPCState, fpr[i]), p);
p += (i < 10) ? 4 : 5;
cpu_reg_names_size -= (i < 10) ? 4 : 5;
snprintf(p, cpu_reg_names_size, "avr%dH", i);
#ifdef HOST_WORDS_BIGENDIAN
- cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUPPCState, avr[i].u64[0]), p);
#else
- cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUPPCState, avr[i].u64[1]), p);
#endif
p += (i < 10) ? 6 : 7;
@@ -129,50 +129,50 @@ void ppc_translate_init(void)
snprintf(p, cpu_reg_names_size, "avr%dL", i);
#ifdef HOST_WORDS_BIGENDIAN
- cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUPPCState, avr[i].u64[1]), p);
#else
- cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUPPCState, avr[i].u64[0]), p);
#endif
p += (i < 10) ? 6 : 7;
cpu_reg_names_size -= (i < 10) ? 6 : 7;
}
- cpu_nip = tcg_global_mem_new(TCG_AREG0,
+ cpu_nip = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, nip), "nip");
- cpu_msr = tcg_global_mem_new(TCG_AREG0,
+ cpu_msr = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, msr), "msr");
- cpu_ctr = tcg_global_mem_new(TCG_AREG0,
+ cpu_ctr = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, ctr), "ctr");
- cpu_lr = tcg_global_mem_new(TCG_AREG0,
+ cpu_lr = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, lr), "lr");
#if defined(TARGET_PPC64)
- cpu_cfar = tcg_global_mem_new(TCG_AREG0,
+ cpu_cfar = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, cfar), "cfar");
#endif
- cpu_xer = tcg_global_mem_new(TCG_AREG0,
+ cpu_xer = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, xer), "xer");
- cpu_so = tcg_global_mem_new(TCG_AREG0,
+ cpu_so = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, so), "SO");
- cpu_ov = tcg_global_mem_new(TCG_AREG0,
+ cpu_ov = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, ov), "OV");
- cpu_ca = tcg_global_mem_new(TCG_AREG0,
+ cpu_ca = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, ca), "CA");
- cpu_reserve = tcg_global_mem_new(TCG_AREG0,
+ cpu_reserve = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, reserve_addr),
"reserve_addr");
- cpu_fpscr = tcg_global_mem_new(TCG_AREG0,
+ cpu_fpscr = tcg_global_mem_new(cpu_env,
offsetof(CPUPPCState, fpscr), "fpscr");
- cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_access_type = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUPPCState, access_type), "access_type");
/* register helpers */
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index afe90eb..1e3d5ba 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -159,32 +159,32 @@ void s390x_translate_init(void)
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- psw_addr = tcg_global_mem_new_i64(TCG_AREG0,
+ psw_addr = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUS390XState, psw.addr),
"psw_addr");
- psw_mask = tcg_global_mem_new_i64(TCG_AREG0,
+ psw_mask = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUS390XState, psw.mask),
"psw_mask");
- cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUS390XState, cc_op),
+ cc_op = tcg_global_mem_new_i32(cpu_env, offsetof(CPUS390XState, cc_op),
"cc_op");
- cc_src = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_src),
+ cc_src = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_src),
"cc_src");
- cc_dst = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_dst),
+ cc_dst = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_dst),
"cc_dst");
- cc_vr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_vr),
+ cc_vr = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_vr),
"cc_vr");
for (i = 0; i < 16; i++) {
snprintf(cpu_reg_names[i], sizeof(cpu_reg_names[0]), "r%d", i);
- regs[i] = tcg_global_mem_new(TCG_AREG0,
+ regs[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUS390XState, regs[i]),
cpu_reg_names[i]);
}
for (i = 0; i < 16; i++) {
snprintf(cpu_reg_names[i + 16], sizeof(cpu_reg_names[0]), "f%d", i);
- fregs[i] = tcg_global_mem_new(TCG_AREG0,
+ fregs[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUS390XState, fregs[i].d),
cpu_reg_names[i + 16]);
}
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index c06b29f..e6a9c7f 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -99,47 +99,47 @@ void sh4_translate_init(void)
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
for (i = 0; i < 24; i++)
- cpu_gregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, gregs[i]),
gregnames[i]);
- cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_pc = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, pc), "PC");
- cpu_sr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_sr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, sr), "SR");
- cpu_ssr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_ssr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, ssr), "SSR");
- cpu_spc = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_spc = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, spc), "SPC");
- cpu_gbr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_gbr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, gbr), "GBR");
- cpu_vbr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_vbr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, vbr), "VBR");
- cpu_sgr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_sgr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, sgr), "SGR");
- cpu_dbr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_dbr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, dbr), "DBR");
- cpu_mach = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_mach = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, mach), "MACH");
- cpu_macl = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_macl = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, macl), "MACL");
- cpu_pr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_pr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, pr), "PR");
- cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_fpscr = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, fpscr), "FPSCR");
- cpu_fpul = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_fpul = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, fpul), "FPUL");
- cpu_flags = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_flags = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, flags), "_flags_");
- cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_delayed_pc = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, delayed_pc),
"_delayed_pc_");
- cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_ldst = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, ldst), "_ldst_");
for (i = 0; i < 32; i++)
- cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_fregs[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSH4State, fregs[i]),
fregnames[i]);
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 36615f1..6a921f3 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5384,75 +5384,79 @@ void gen_intermediate_code_init(CPUSPARCState *env)
inited = 1;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cpu_regwptr = tcg_global_mem_new_ptr(TCG_AREG0,
+ cpu_regwptr = tcg_global_mem_new_ptr(cpu_env,
offsetof(CPUSPARCState, regwptr),
"regwptr");
#ifdef TARGET_SPARC64
- cpu_xcc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUSPARCState, xcc),
+ cpu_xcc = tcg_global_mem_new_i32(cpu_env, offsetof(CPUSPARCState, xcc),
"xcc");
- cpu_asi = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUSPARCState, asi),
+ cpu_asi = tcg_global_mem_new_i32(cpu_env, offsetof(CPUSPARCState, asi),
"asi");
- cpu_fprs = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUSPARCState, fprs),
+ cpu_fprs = tcg_global_mem_new_i32(cpu_env,
+ offsetof(CPUSPARCState, fprs),
"fprs");
- cpu_gsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, gsr),
+ cpu_gsr = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, gsr),
"gsr");
- cpu_tick_cmpr = tcg_global_mem_new(TCG_AREG0,
+ cpu_tick_cmpr = tcg_global_mem_new(cpu_env,
offsetof(CPUSPARCState, tick_cmpr),
"tick_cmpr");
- cpu_stick_cmpr = tcg_global_mem_new(TCG_AREG0,
+ cpu_stick_cmpr = tcg_global_mem_new(cpu_env,
offsetof(CPUSPARCState, stick_cmpr),
"stick_cmpr");
- cpu_hstick_cmpr = tcg_global_mem_new(TCG_AREG0,
+ cpu_hstick_cmpr = tcg_global_mem_new(cpu_env,
offsetof(CPUSPARCState, hstick_cmpr),
"hstick_cmpr");
- cpu_hintp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, hintp),
+ cpu_hintp = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, hintp),
"hintp");
- cpu_htba = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, htba),
+ cpu_htba = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, htba),
"htba");
- cpu_hver = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, hver),
+ cpu_hver = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, hver),
"hver");
- cpu_ssr = tcg_global_mem_new(TCG_AREG0,
+ cpu_ssr = tcg_global_mem_new(cpu_env,
offsetof(CPUSPARCState, ssr), "ssr");
- cpu_ver = tcg_global_mem_new(TCG_AREG0,
+ cpu_ver = tcg_global_mem_new(cpu_env,
offsetof(CPUSPARCState, version), "ver");
- cpu_softint = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_softint = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUSPARCState, softint),
"softint");
#else
- cpu_wim = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, wim),
+ cpu_wim = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, wim),
"wim");
#endif
- cpu_cond = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, cond),
+ cpu_cond = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, cond),
"cond");
- cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, cc_src),
+ cpu_cc_src = tcg_global_mem_new(cpu_env,
+ offsetof(CPUSPARCState, cc_src),
"cc_src");
- cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0,
+ cpu_cc_src2 = tcg_global_mem_new(cpu_env,
offsetof(CPUSPARCState, cc_src2),
"cc_src2");
- cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, cc_dst),
+ cpu_cc_dst = tcg_global_mem_new(cpu_env,
+ offsetof(CPUSPARCState, cc_dst),
"cc_dst");
- cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUSPARCState, cc_op),
+ cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
+ offsetof(CPUSPARCState, cc_op),
"cc_op");
- cpu_psr = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUSPARCState, psr),
+ cpu_psr = tcg_global_mem_new_i32(cpu_env, offsetof(CPUSPARCState, psr),
"psr");
- cpu_fsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, fsr),
+ cpu_fsr = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, fsr),
"fsr");
- cpu_pc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, pc),
+ cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, pc),
"pc");
- cpu_npc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, npc),
+ cpu_npc = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, npc),
"npc");
- cpu_y = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, y), "y");
+ cpu_y = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, y), "y");
#ifndef CONFIG_USER_ONLY
- cpu_tbr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUSPARCState, tbr),
+ cpu_tbr = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, tbr),
"tbr");
#endif
for (i = 1; i < 8; i++) {
- cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0,
+ cpu_gregs[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUSPARCState, gregs[i]),
gregnames[i]);
}
for (i = 0; i < TARGET_DPREGS; i++) {
- cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUSPARCState, fpr[i]),
fregnames[i]);
}
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 1246895..67c3964 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -71,7 +71,7 @@ void uc32_translate_init(void)
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
for (i = 0; i < 32; i++) {
- cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUUniCore32State, regs[i]), regnames[i]);
}
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 24343bd..bb7dfd0 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -208,24 +208,24 @@ void xtensa_translate_init(void)
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_pc = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, pc), "pc");
for (i = 0; i < 16; i++) {
- cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, regs[i]),
regnames[i]);
}
for (i = 0; i < 16; i++) {
- cpu_FR[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_FR[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, fregs[i]),
fregnames[i]);
}
for (i = 0; i < 256; ++i) {
if (sregnames[i].name) {
- cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_SR[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, sregs[i]),
sregnames[i].name);
}
@@ -233,7 +233,7 @@ void xtensa_translate_init(void)
for (i = 0; i < 256; ++i) {
if (uregnames[i].name) {
- cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_UR[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, uregs[i]),
uregnames[i].name);
}
diff --git a/tcg/tcg.c b/tcg/tcg.c
index fd7fb6b..c72a144 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -389,13 +389,12 @@ TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
return MAKE_TCGV_I64(idx);
}
-static inline int tcg_global_mem_new_internal(TCGType type, int reg,
- intptr_t offset,
- const char *name)
+int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
+ intptr_t offset, const char *name)
{
TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
- int idx;
+ TCGTemp *ts, *base_ts = &s->temps[GET_TCGV_PTR(base)];
+ int idx, reg = base_ts->reg;
idx = s->nb_globals;
#if TCG_TARGET_REG_BITS == 32
@@ -450,18 +449,6 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg,
return idx;
}
-TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name)
-{
- int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
- return MAKE_TCGV_I32(idx);
-}
-
-TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name)
-{
- int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
- return MAKE_TCGV_I64(idx);
-}
-
static inline int tcg_temp_new_internal(TCGType type, int temp_local)
{
TCGContext *s = &tcg_ctx;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 902c751..dade849 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -536,33 +536,55 @@ int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size);
+int tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char *);
+
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
-TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name);
+TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
+
TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
+TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
+
+void tcg_temp_free_i32(TCGv_i32 arg);
+void tcg_temp_free_i64(TCGv_i64 arg);
+
+char *tcg_get_arg_str_i32(TCGContext *s, char *buf,
+ int buf_size, TCGv_i32 arg);
+char *tcg_get_arg_str_i64(TCGContext *s, char *buf,
+ int buf_size, TCGv_i64 arg);
+
+static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
+ const char *name)
+{
+ int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
+ return MAKE_TCGV_I32(idx);
+}
+
static inline TCGv_i32 tcg_temp_new_i32(void)
{
return tcg_temp_new_internal_i32(0);
}
+
static inline TCGv_i32 tcg_temp_local_new_i32(void)
{
return tcg_temp_new_internal_i32(1);
}
-void tcg_temp_free_i32(TCGv_i32 arg);
-char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
-TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
-TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name);
-TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
+static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
+ const char *name)
+{
+ int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
+ return MAKE_TCGV_I64(idx);
+}
+
static inline TCGv_i64 tcg_temp_new_i64(void)
{
return tcg_temp_new_internal_i64(0);
}
+
static inline TCGv_i64 tcg_temp_local_new_i64(void)
{
return tcg_temp_new_internal_i64(1);
}
-void tcg_temp_free_i64(TCGv_i64 arg);
-char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
#if defined(CONFIG_DEBUG_TCG)
/* If you call tcg_clear_temp_count() at the start of a section of
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 02/16] tcg: Introduce TCGTempType
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 01/16] tcg: Change tcg_global_mem_new_* to take a TCGv_ptr Richard Henderson
@ 2013-09-19 21:24 ` Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 03/16] tcg: Change ts->mem_reg to ts->mem_base Richard Henderson
` (15 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:24 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.h | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/tcg/tcg.h b/tcg/tcg.h
index dade849..554a4ee 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -379,16 +379,18 @@ static inline TCGCond tcg_high_cond(TCGCond c)
}
}
-#define TEMP_VAL_DEAD 0
-#define TEMP_VAL_REG 1
-#define TEMP_VAL_MEM 2
-#define TEMP_VAL_CONST 3
+typedef enum TCGTempType {
+ TEMP_VAL_DEAD,
+ TEMP_VAL_REG,
+ TEMP_VAL_MEM,
+ TEMP_VAL_CONST,
+} TCGTempType;
/* XXX: optimize memory layout */
typedef struct TCGTemp {
TCGType base_type;
TCGType type;
- int val_type;
+ TCGTempType val_type;
int reg;
tcg_target_long val;
int mem_reg;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 03/16] tcg: Change ts->mem_reg to ts->mem_base
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 01/16] tcg: Change tcg_global_mem_new_* to take a TCGv_ptr Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 02/16] tcg: Introduce TCGTempType Richard Henderson
@ 2013-09-19 21:24 ` Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 04/16] tcg: Compress TCGLabelQemuLdst Richard Henderson
` (14 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:24 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Chain the temporaries together via pointers intstead of indices.
The mem_reg value is now mem_base->reg. This will be important later.
This does require that the frame pointer have a global temporary
allocated for it. This is simple bar the existing reserved_regs check.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 66 ++++++++++++++++++++++++++++++++++-----------------------------
tcg/tcg.h | 4 ++--
2 files changed, 38 insertions(+), 32 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index c72a144..8fc5588 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -307,13 +307,6 @@ void tcg_prologue_init(TCGContext *s)
#endif
}
-void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size)
-{
- s->frame_start = start;
- s->frame_end = start + size;
- s->frame_reg = reg;
-}
-
void tcg_func_start(TCGContext *s)
{
int i;
@@ -347,19 +340,15 @@ static inline void tcg_temp_alloc(TCGContext *s, int n)
tcg_abort();
}
-static inline int tcg_global_reg_new_internal(TCGType type, int reg,
- const char *name)
+static int tcg_global_reg_new_internal(TCGContext *s, TCGType type,
+ int reg, const char *name)
{
- TCGContext *s = &tcg_ctx;
TCGTemp *ts;
int idx;
-#if TCG_TARGET_REG_BITS == 32
- if (type != TCG_TYPE_I32)
- tcg_abort();
-#endif
- if (tcg_regset_test_reg(s->reserved_regs, reg))
+ if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) {
tcg_abort();
+ }
idx = s->nb_globals;
tcg_temp_alloc(s, s->nb_globals + 1);
ts = &s->temps[s->nb_globals];
@@ -373,19 +362,34 @@ static inline int tcg_global_reg_new_internal(TCGType type, int reg,
return idx;
}
+void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size)
+{
+ s->frame_start = start;
+ s->frame_end = start + size;
+ s->frame_temp = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
+}
+
TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
{
+ TCGContext *s = &tcg_ctx;
int idx;
- idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
+ if (tcg_regset_test_reg(s->reserved_regs, reg)) {
+ tcg_abort();
+ }
+ idx = tcg_global_reg_new_internal(s, TCG_TYPE_I32, reg, name);
return MAKE_TCGV_I32(idx);
}
TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
{
+ TCGContext *s = &tcg_ctx;
int idx;
- idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
+ if (tcg_regset_test_reg(s->reserved_regs, reg)) {
+ tcg_abort();
+ }
+ idx = tcg_global_reg_new_internal(s, TCG_TYPE_I64, reg, name);
return MAKE_TCGV_I64(idx);
}
@@ -394,7 +398,7 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
{
TCGContext *s = &tcg_ctx;
TCGTemp *ts, *base_ts = &s->temps[GET_TCGV_PTR(base)];
- int idx, reg = base_ts->reg;
+ int idx;
idx = s->nb_globals;
#if TCG_TARGET_REG_BITS == 32
@@ -406,7 +410,7 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
ts->type = TCG_TYPE_I32;
ts->fixed_reg = 0;
ts->mem_allocated = 1;
- ts->mem_reg = reg;
+ ts->mem_base = base_ts;
#ifdef TCG_TARGET_WORDS_BIGENDIAN
ts->mem_offset = offset + 4;
#else
@@ -421,7 +425,7 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
ts->type = TCG_TYPE_I32;
ts->fixed_reg = 0;
ts->mem_allocated = 1;
- ts->mem_reg = reg;
+ ts->mem_base = base_ts;
#ifdef TCG_TARGET_WORDS_BIGENDIAN
ts->mem_offset = offset;
#else
@@ -441,7 +445,7 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
ts->type = type;
ts->fixed_reg = 0;
ts->mem_allocated = 1;
- ts->mem_reg = reg;
+ ts->mem_base = base_ts;
ts->mem_offset = offset;
ts->name = name;
s->nb_globals++;
@@ -1519,7 +1523,8 @@ static void dump_regs(TCGContext *s)
printf("%s", tcg_target_reg_names[ts->reg]);
break;
case TEMP_VAL_MEM:
- printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
+ printf("%d(%s)", (int)ts->mem_offset,
+ tcg_target_reg_names[ts->mem_base->reg]);
break;
case TEMP_VAL_CONST:
printf("$0x%" TCG_PRIlx, ts->val);
@@ -1592,7 +1597,7 @@ static void temp_allocate_frame(TCGContext *s, int temp)
tcg_abort();
}
ts->mem_offset = s->current_frame_offset;
- ts->mem_reg = s->frame_reg;
+ ts->mem_base = &s->temps[s->frame_temp];
ts->mem_allocated = 1;
s->current_frame_offset += sizeof(tcg_target_long);
}
@@ -1610,7 +1615,7 @@ static inline void tcg_reg_sync(TCGContext *s, int reg)
if (!ts->mem_allocated) {
temp_allocate_frame(s, temp);
}
- tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
+ tcg_out_st(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
}
ts->mem_coherent = 1;
}
@@ -1823,7 +1828,8 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
|| ts->val_type == TEMP_VAL_MEM) {
ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
if (ts->val_type == TEMP_VAL_MEM) {
- tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset);
+ tcg_out_ld(s, ts->type, ts->reg,
+ ts->mem_base->reg, ts->mem_offset);
ts->mem_coherent = 1;
} else if (ts->val_type == TEMP_VAL_CONST) {
tcg_out_movi(s, ts->type, ts->reg, ts->val);
@@ -1841,7 +1847,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
if (!ots->mem_allocated) {
temp_allocate_frame(s, args[0]);
}
- tcg_out_st(s, ots->type, ts->reg, ots->mem_reg, ots->mem_offset);
+ tcg_out_st(s, ots->type, ts->reg, ots->mem_base->reg, ots->mem_offset);
if (IS_DEAD_ARG(1)) {
temp_dead(s, args[1]);
}
@@ -1912,7 +1918,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
ts = &s->temps[arg];
if (ts->val_type == TEMP_VAL_MEM) {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
+ tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
ts->val_type = TEMP_VAL_REG;
ts->reg = reg;
ts->mem_coherent = 1;
@@ -2101,7 +2107,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
s->reserved_regs);
/* XXX: not correct if reading values from the stack */
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
+ tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
} else if (ts->val_type == TEMP_VAL_CONST) {
reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
@@ -2131,7 +2137,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
tcg_out_mov(s, ts->type, reg, ts->reg);
}
} else if (ts->val_type == TEMP_VAL_MEM) {
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
+ tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
} else if (ts->val_type == TEMP_VAL_CONST) {
/* XXX: sign extend ? */
tcg_out_movi(s, ts->type, reg, ts->val);
@@ -2150,7 +2156,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
const_func_arg = 0;
if (ts->val_type == TEMP_VAL_MEM) {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
+ tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
func_arg = reg;
tcg_regset_set_reg(allocated_regs, reg);
} else if (ts->val_type == TEMP_VAL_REG) {
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 554a4ee..b99302a 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -393,7 +393,7 @@ typedef struct TCGTemp {
TCGTempType val_type;
int reg;
tcg_target_long val;
- int mem_reg;
+ struct TCGTemp *mem_base;
intptr_t mem_offset;
unsigned int fixed_reg:1;
unsigned int mem_coherent:1;
@@ -444,7 +444,7 @@ struct TCGContext {
intptr_t current_frame_offset;
intptr_t frame_start;
intptr_t frame_end;
- int frame_reg;
+ int frame_temp;
uint8_t *code_ptr;
TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 04/16] tcg: Compress TCGLabelQemuLdst
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (2 preceding siblings ...)
2013-09-19 21:24 ` [Qemu-devel] [RFC 03/16] tcg: Change ts->mem_reg to ts->mem_base Richard Henderson
@ 2013-09-19 21:24 ` Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 05/16] tcg: More use of TCGReg where appropriate Richard Henderson
` (13 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:24 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Pack all of the non-pointer data into one 32-bit word.
Use TCGReg.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.h | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/tcg/tcg.h b/tcg/tcg.h
index b99302a..16048ca 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -216,14 +216,17 @@ typedef tcg_target_ulong TCGArg;
TCG_MAX_HELPER_LABELS is defined as same as OPC_BUF_SIZE in exec-all.h. */
#define TCG_MAX_QEMU_LDST 640
+QEMU_BUILD_BUG_ON(TCG_TARGET_NB_REGS > 64);
+QEMU_BUILD_BUG_ON(NB_MMU_MODES > 8);
+
typedef struct TCGLabelQemuLdst {
- int is_ld:1; /* qemu_ld: 1, qemu_st: 0 */
- int opc:4;
- int addrlo_reg; /* reg index for low word of guest virtual addr */
- int addrhi_reg; /* reg index for high word of guest virtual addr */
- int datalo_reg; /* reg index for low word to be loaded or stored */
- int datahi_reg; /* reg index for high word to be loaded or stored */
- int mem_index; /* soft MMU memory index */
+ int is_ld : 1; /* qemu_ld: 1, qemu_st: 0 */
+ int opc : 4;
+ unsigned mem_index : 3; /* asserted max idx < 8 */
+ TCGReg addrlo_reg : 6; /* asserted max regno < 64 */
+ TCGReg addrhi_reg : 6;
+ TCGReg datalo_reg : 6;
+ TCGReg datahi_reg : 6;
uint8_t *raddr; /* gen code addr of the next IR of qemu_ld/st IR */
uint8_t *label_ptr[2]; /* label pointers to be updated */
} TCGLabelQemuLdst;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 05/16] tcg: More use of TCGReg where appropriate
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (3 preceding siblings ...)
2013-09-19 21:24 ` [Qemu-devel] [RFC 04/16] tcg: Compress TCGLabelQemuLdst Richard Henderson
@ 2013-09-19 21:24 ` Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 06/16] tcg: Remove tcg_get_arg_str_i32/64 Richard Henderson
` (12 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:24 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 26 +++++++++++++++-----------
tcg/tcg.h | 8 ++++----
2 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 8fc5588..13dc8f5 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -341,7 +341,7 @@ static inline void tcg_temp_alloc(TCGContext *s, int n)
}
static int tcg_global_reg_new_internal(TCGContext *s, TCGType type,
- int reg, const char *name)
+ TCGReg reg, const char *name)
{
TCGTemp *ts;
int idx;
@@ -362,14 +362,14 @@ static int tcg_global_reg_new_internal(TCGContext *s, TCGType type,
return idx;
}
-void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size)
+void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
{
s->frame_start = start;
s->frame_end = start + size;
s->frame_temp = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
}
-TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
+TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name)
{
TCGContext *s = &tcg_ctx;
int idx;
@@ -381,7 +381,7 @@ TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
return MAKE_TCGV_I32(idx);
}
-TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
+TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name)
{
TCGContext *s = &tcg_ctx;
int idx;
@@ -1550,7 +1550,8 @@ static void dump_regs(TCGContext *s)
static void check_regs(TCGContext *s)
{
- int reg, k;
+ TCGReg reg;
+ int k;
TCGTemp *ts;
char buf[64];
@@ -1603,7 +1604,7 @@ static void temp_allocate_frame(TCGContext *s, int temp)
}
/* sync register 'reg' by saving it to the corresponding temporary */
-static inline void tcg_reg_sync(TCGContext *s, int reg)
+static inline void tcg_reg_sync(TCGContext *s, TCGReg reg)
{
TCGTemp *ts;
int temp;
@@ -1621,7 +1622,7 @@ static inline void tcg_reg_sync(TCGContext *s, int reg)
}
/* free register 'reg' by spilling the corresponding temporary if necessary */
-static void tcg_reg_free(TCGContext *s, int reg)
+static void tcg_reg_free(TCGContext *s, TCGReg reg)
{
int temp;
@@ -1634,9 +1635,10 @@ static void tcg_reg_free(TCGContext *s, int reg)
}
/* Allocate a register belonging to reg1 & ~reg2 */
-static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
+static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
{
- int i, reg;
+ int i;
+ TCGReg reg;
TCGRegSet reg_ct;
tcg_regset_andnot(reg_ct, reg1, reg2);
@@ -1894,7 +1896,8 @@ static void tcg_reg_alloc_op(TCGContext *s,
uint8_t sync_args)
{
TCGRegSet allocated_regs;
- int i, k, nb_iargs, nb_oargs, reg;
+ int i, k, nb_iargs, nb_oargs;
+ TCGReg reg;
TCGArg arg;
const TCGArgConstraint *arg_ct;
TCGTemp *ts;
@@ -2060,7 +2063,8 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
TCGOpcode opc, const TCGArg *args,
uint16_t dead_args, uint8_t sync_args)
{
- int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
+ int nb_iargs, nb_oargs, flags, nb_regs, i, nb_params;
+ TCGReg reg;
TCGArg arg, func_arg;
TCGTemp *ts;
intptr_t stack_offset;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 16048ca..d69d993 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -394,7 +394,7 @@ typedef struct TCGTemp {
TCGType base_type;
TCGType type;
TCGTempType val_type;
- int reg;
+ TCGReg reg;
tcg_target_long val;
struct TCGTemp *mem_base;
intptr_t mem_offset;
@@ -539,12 +539,12 @@ void tcg_func_start(TCGContext *s);
int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
-void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size);
+void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
int tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char *);
-TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
-TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
+TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name);
+TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name);
TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 06/16] tcg: Remove tcg_get_arg_str_i32/64
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (4 preceding siblings ...)
2013-09-19 21:24 ` [Qemu-devel] [RFC 05/16] tcg: More use of TCGReg where appropriate Richard Henderson
@ 2013-09-19 21:24 ` Richard Henderson
2013-09-19 21:24 ` [Qemu-devel] [RFC 07/16] tcg: Change reg_to_temp to TCGTemp pointer Richard Henderson
` (11 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:24 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 10 ----------
tcg/tcg.h | 5 -----
2 files changed, 15 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 13dc8f5..7d379ac 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -832,16 +832,6 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
return buf;
}
-char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
-{
- return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
-}
-
-char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
-{
- return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
-}
-
static int helper_cmp(const void *p1, const void *p2)
{
const TCGHelperInfo *th1 = p1;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index d69d993..275ea9b 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -552,11 +552,6 @@ TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
void tcg_temp_free_i32(TCGv_i32 arg);
void tcg_temp_free_i64(TCGv_i64 arg);
-char *tcg_get_arg_str_i32(TCGContext *s, char *buf,
- int buf_size, TCGv_i32 arg);
-char *tcg_get_arg_str_i64(TCGContext *s, char *buf,
- int buf_size, TCGv_i64 arg);
-
static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
const char *name)
{
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 07/16] tcg: Change reg_to_temp to TCGTemp pointer
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (5 preceding siblings ...)
2013-09-19 21:24 ` [Qemu-devel] [RFC 06/16] tcg: Remove tcg_get_arg_str_i32/64 Richard Henderson
@ 2013-09-19 21:24 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 08/16] tcg: Change temp_dead argument to TCGTemp Richard Henderson
` (10 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:24 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 113 ++++++++++++++++++++++++++++++--------------------------------
tcg/tcg.h | 4 +--
2 files changed, 56 insertions(+), 61 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 7d379ac..35e0c7c 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -809,29 +809,32 @@ static void tcg_reg_alloc_start(TCGContext *s)
ts->mem_allocated = 0;
ts->fixed_reg = 0;
}
- for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
- s->reg_to_temp[i] = -1;
- }
+
+ memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp));
}
-static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
- int idx)
+static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
+ TCGTemp *ts)
{
- TCGTemp *ts;
+ int idx = ts - s->temps;
- assert(idx >= 0 && idx < s->nb_temps);
- ts = &s->temps[idx];
if (idx < s->nb_globals) {
pstrcpy(buf, buf_size, ts->name);
+ } else if (ts->temp_local) {
+ snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
} else {
- if (ts->temp_local)
- snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
- else
- snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
+ snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
}
return buf;
}
+static char *tcg_get_arg_str_idx(TCGContext *s, char *buf,
+ int buf_size, int idx)
+{
+ assert(idx >= 0 && idx < s->nb_temps);
+ return tcg_get_arg_str_ptr(s, buf, buf_size, &s->temps[idx]);
+}
+
static int helper_cmp(const void *p1, const void *p2)
{
const TCGHelperInfo *th1 = p1;
@@ -1530,10 +1533,10 @@ static void dump_regs(TCGContext *s)
}
for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
- if (s->reg_to_temp[i] >= 0) {
+ if (s->reg_to_temp[i] != NULL) {
printf("%s: %s\n",
tcg_target_reg_names[i],
- tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
+ tcg_get_arg_str_ptr(s, buf, sizeof(buf), s->reg_to_temp[i]));
}
}
}
@@ -1545,29 +1548,26 @@ static void check_regs(TCGContext *s)
TCGTemp *ts;
char buf[64];
- for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
- k = s->reg_to_temp[reg];
- if (k >= 0) {
- ts = &s->temps[k];
- if (ts->val_type != TEMP_VAL_REG ||
- ts->reg != reg) {
+ for (reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
+ ts = s->reg_to_temp[reg];
+ if (ts != NULL) {
+ if (ts->val_type != TEMP_VAL_REG || ts->reg != reg) {
printf("Inconsistency for register %s:\n",
tcg_target_reg_names[reg]);
goto fail;
}
}
}
- for(k = 0; k < s->nb_temps; k++) {
+ for (k = 0; k < s->nb_temps; k++) {
ts = &s->temps[k];
- if (ts->val_type == TEMP_VAL_REG &&
- !ts->fixed_reg &&
- s->reg_to_temp[ts->reg] != k) {
- printf("Inconsistency for temp %s:\n",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
+ if (ts->val_type == TEMP_VAL_REG && !ts->fixed_reg
+ && s->reg_to_temp[ts->reg] != ts) {
+ printf("Inconsistency for temp %s:\n",
+ tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts));
fail:
- printf("reg state:\n");
- dump_regs(s);
- tcg_abort();
+ printf("reg state:\n");
+ dump_regs(s);
+ tcg_abort();
}
}
}
@@ -1596,15 +1596,12 @@ static void temp_allocate_frame(TCGContext *s, int temp)
/* sync register 'reg' by saving it to the corresponding temporary */
static inline void tcg_reg_sync(TCGContext *s, TCGReg reg)
{
- TCGTemp *ts;
- int temp;
+ TCGTemp *ts = s->reg_to_temp[reg];
- temp = s->reg_to_temp[reg];
- ts = &s->temps[temp];
assert(ts->val_type == TEMP_VAL_REG);
if (!ts->mem_coherent && !ts->fixed_reg) {
if (!ts->mem_allocated) {
- temp_allocate_frame(s, temp);
+ temp_allocate_frame(s, ts - s->temps);
}
tcg_out_st(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
}
@@ -1614,13 +1611,12 @@ static inline void tcg_reg_sync(TCGContext *s, TCGReg reg)
/* free register 'reg' by spilling the corresponding temporary if necessary */
static void tcg_reg_free(TCGContext *s, TCGReg reg)
{
- int temp;
+ TCGTemp *ts = s->reg_to_temp[reg];
- temp = s->reg_to_temp[reg];
- if (temp != -1) {
+ if (ts != NULL) {
tcg_reg_sync(s, reg);
- s->temps[temp].val_type = TEMP_VAL_MEM;
- s->reg_to_temp[reg] = -1;
+ ts->val_type = TEMP_VAL_MEM;
+ s->reg_to_temp[reg] = NULL;
}
}
@@ -1636,7 +1632,7 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
/* first try free registers */
for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
reg = tcg_target_reg_alloc_order[i];
- if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
+ if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL)
return reg;
}
@@ -1655,12 +1651,11 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
/* mark a temporary as dead. */
static inline void temp_dead(TCGContext *s, int temp)
{
- TCGTemp *ts;
+ TCGTemp *ts = &s->temps[temp];
- ts = &s->temps[temp];
if (!ts->fixed_reg) {
if (ts->val_type == TEMP_VAL_REG) {
- s->reg_to_temp[ts->reg] = -1;
+ s->reg_to_temp[ts->reg] = NULL;
}
if (temp < s->nb_globals || ts->temp_local) {
ts->val_type = TEMP_VAL_MEM;
@@ -1674,16 +1669,15 @@ static inline void temp_dead(TCGContext *s, int temp)
temporary registers needs to be allocated to store a constant. */
static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
{
- TCGTemp *ts;
+ TCGTemp *ts = &s->temps[temp];
- ts = &s->temps[temp];
if (!ts->fixed_reg) {
switch(ts->val_type) {
case TEMP_VAL_CONST:
ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
allocated_regs);
ts->val_type = TEMP_VAL_REG;
- s->reg_to_temp[ts->reg] = temp;
+ s->reg_to_temp[ts->reg] = ts;
ts->mem_coherent = 0;
tcg_out_movi(s, ts->type, ts->reg, ts->val);
/* fallthrough*/
@@ -1785,8 +1779,9 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
tcg_out_movi(s, ots->type, ots->reg, val);
} else {
/* The movi is not explicitly generated here */
- if (ots->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ots->reg] = -1;
+ if (ots->val_type == TEMP_VAL_REG) {
+ s->reg_to_temp[ots->reg] = NULL;
+ }
ots->val_type = TEMP_VAL_CONST;
ots->val = val;
}
@@ -1826,7 +1821,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
} else if (ts->val_type == TEMP_VAL_CONST) {
tcg_out_movi(s, ts->type, ts->reg, ts->val);
}
- s->reg_to_temp[ts->reg] = args[1];
+ s->reg_to_temp[ts->reg] = ts;
ts->val_type = TEMP_VAL_REG;
}
@@ -1847,7 +1842,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
} else if (ts->val_type == TEMP_VAL_CONST) {
/* propagate constant */
if (ots->val_type == TEMP_VAL_REG) {
- s->reg_to_temp[ots->reg] = -1;
+ s->reg_to_temp[ots->reg] = NULL;
}
ots->val_type = TEMP_VAL_CONST;
ots->val = ts->val;
@@ -1858,7 +1853,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
/* the mov can be suppressed */
if (ots->val_type == TEMP_VAL_REG) {
- s->reg_to_temp[ots->reg] = -1;
+ s->reg_to_temp[ots->reg] = NULL;
}
ots->reg = ts->reg;
temp_dead(s, args[1]);
@@ -1873,7 +1868,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
}
ots->val_type = TEMP_VAL_REG;
ots->mem_coherent = 0;
- s->reg_to_temp[ots->reg] = args[0];
+ s->reg_to_temp[ots->reg] = ots;
if (NEED_SYNC_ARG(0)) {
tcg_reg_sync(s, ots->reg);
}
@@ -1915,7 +1910,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
ts->val_type = TEMP_VAL_REG;
ts->reg = reg;
ts->mem_coherent = 1;
- s->reg_to_temp[reg] = arg;
+ s->reg_to_temp[reg] = ts;
} else if (ts->val_type == TEMP_VAL_CONST) {
if (tcg_target_const_match(ts->val, arg_ct)) {
/* constant is OK for instruction */
@@ -1929,7 +1924,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
ts->val_type = TEMP_VAL_REG;
ts->reg = reg;
ts->mem_coherent = 0;
- s->reg_to_temp[reg] = arg;
+ s->reg_to_temp[reg] = ts;
}
}
assert(ts->val_type == TEMP_VAL_REG);
@@ -2010,14 +2005,14 @@ static void tcg_reg_alloc_op(TCGContext *s,
/* if a fixed register is used, then a move will be done afterwards */
if (!ts->fixed_reg) {
if (ts->val_type == TEMP_VAL_REG) {
- s->reg_to_temp[ts->reg] = -1;
+ s->reg_to_temp[ts->reg] = NULL;
}
ts->val_type = TEMP_VAL_REG;
ts->reg = reg;
/* temp value is modified, so the value kept in memory is
potentially not the same */
ts->mem_coherent = 0;
- s->reg_to_temp[reg] = arg;
+ s->reg_to_temp[reg] = ts;
}
oarg_end:
new_args[i] = reg;
@@ -2207,19 +2202,19 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
arg = args[i];
ts = &s->temps[arg];
reg = tcg_target_call_oarg_regs[i];
- assert(s->reg_to_temp[reg] == -1);
+ assert(s->reg_to_temp[reg] == NULL);
if (ts->fixed_reg) {
if (ts->reg != reg) {
tcg_out_mov(s, ts->type, ts->reg, reg);
}
} else {
if (ts->val_type == TEMP_VAL_REG) {
- s->reg_to_temp[ts->reg] = -1;
+ s->reg_to_temp[ts->reg] = NULL;
}
ts->val_type = TEMP_VAL_REG;
ts->reg = reg;
ts->mem_coherent = 0;
- s->reg_to_temp[reg] = arg;
+ s->reg_to_temp[reg] = ts;
if (NEED_SYNC_ARG(i)) {
tcg_reg_sync(s, reg);
}
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 275ea9b..74649fa 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -440,9 +440,9 @@ struct TCGContext {
corresponding output argument needs to be
sync to memory. */
- /* tells in which temporary a given register is. It does not take
+ /* Tells in which temporary a given register is. It does not take
into account fixed registers */
- int reg_to_temp[TCG_TARGET_NB_REGS];
+ TCGTemp *reg_to_temp[TCG_TARGET_NB_REGS];
TCGRegSet reserved_regs;
intptr_t current_frame_offset;
intptr_t frame_start;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 08/16] tcg: Change temp_dead argument to TCGTemp
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (6 preceding siblings ...)
2013-09-19 21:24 ` [Qemu-devel] [RFC 07/16] tcg: Change reg_to_temp to TCGTemp pointer Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 09/16] tcg: Change temp_sync " Richard Henderson
` (9 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 35e0c7c..ee11c94 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1649,19 +1649,16 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
}
/* mark a temporary as dead. */
-static inline void temp_dead(TCGContext *s, int temp)
+static inline void temp_dead(TCGContext *s, TCGTemp *ts)
{
- TCGTemp *ts = &s->temps[temp];
-
if (!ts->fixed_reg) {
+ int idx = ts - s->temps;
+
if (ts->val_type == TEMP_VAL_REG) {
s->reg_to_temp[ts->reg] = NULL;
}
- if (temp < s->nb_globals || ts->temp_local) {
- ts->val_type = TEMP_VAL_MEM;
- } else {
- ts->val_type = TEMP_VAL_DEAD;
- }
+ ts->val_type = (idx < s->nb_globals || ts->temp_local
+ ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
}
}
@@ -1697,13 +1694,15 @@ static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
temporary registers needs to be allocated to store a constant. */
static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
{
+ TCGTemp *ts = &s->temps[temp];
+
#ifdef USE_LIVENESS_ANALYSIS
/* The liveness analysis already ensures that globals are back
in memory. Keep an assert for safety. */
- assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
+ assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
#else
temp_sync(s, temp, allocated_regs);
- temp_dead(s, temp);
+ temp_dead(s, ts);
#endif
}
@@ -1753,7 +1752,7 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
Keep an assert for safety. */
assert(ts->val_type == TEMP_VAL_DEAD);
#else
- temp_dead(s, i);
+ temp_dead(s, ts);
#endif
}
}
@@ -1789,7 +1788,7 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
temp_sync(s, args[0], s->reserved_regs);
}
if (IS_DEAD_ARG(0)) {
- temp_dead(s, args[0]);
+ temp_dead(s, ots);
}
}
@@ -1836,9 +1835,9 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
}
tcg_out_st(s, ots->type, ts->reg, ots->mem_base->reg, ots->mem_offset);
if (IS_DEAD_ARG(1)) {
- temp_dead(s, args[1]);
+ temp_dead(s, ts);
}
- temp_dead(s, args[0]);
+ temp_dead(s, ots);
} else if (ts->val_type == TEMP_VAL_CONST) {
/* propagate constant */
if (ots->val_type == TEMP_VAL_REG) {
@@ -1856,7 +1855,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
s->reg_to_temp[ots->reg] = NULL;
}
ots->reg = ts->reg;
- temp_dead(s, args[1]);
+ temp_dead(s, ts);
} else {
if (ots->val_type != TEMP_VAL_REG) {
/* When allocating a new register, make sure to not spill the
@@ -1962,7 +1961,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
/* mark dead temporaries and free the associated registers */
for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
if (IS_DEAD_ARG(i)) {
- temp_dead(s, args[i]);
+ temp_dead(s, &s->temps[args[i]]);
}
}
@@ -2033,7 +2032,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
tcg_reg_sync(s, reg);
}
if (IS_DEAD_ARG(i)) {
- temp_dead(s, args[i]);
+ temp_dead(s, ts);
}
}
}
@@ -2174,7 +2173,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
/* mark dead temporaries and free the associated registers */
for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
if (IS_DEAD_ARG(i)) {
- temp_dead(s, args[i]);
+ temp_dead(s, &s->temps[args[i]]);
}
}
@@ -2219,7 +2218,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
tcg_reg_sync(s, reg);
}
if (IS_DEAD_ARG(i)) {
- temp_dead(s, args[i]);
+ temp_dead(s, ts);
}
}
}
@@ -2330,7 +2329,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
args += args[0];
goto next;
case INDEX_op_discard:
- temp_dead(s, args[0]);
+ temp_dead(s, &s->temps[args[0]]);
break;
case INDEX_op_set_label:
tcg_reg_alloc_bb_end(s, s->reserved_regs);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 09/16] tcg: Change temp_sync argument to TCGTemp
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (7 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 08/16] tcg: Change temp_dead argument to TCGTemp Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 10/16] tcg: Change temp_save " Richard Henderson
` (8 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index ee11c94..0ca8dbe 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1664,10 +1664,8 @@ static inline void temp_dead(TCGContext *s, TCGTemp *ts)
/* sync a temporary to memory. 'allocated_regs' is used in case a
temporary registers needs to be allocated to store a constant. */
-static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
+static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
{
- TCGTemp *ts = &s->temps[temp];
-
if (!ts->fixed_reg) {
switch(ts->val_type) {
case TEMP_VAL_CONST:
@@ -1701,7 +1699,7 @@ static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
in memory. Keep an assert for safety. */
assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
#else
- temp_sync(s, temp, allocated_regs);
+ temp_sync(s, ts, allocated_regs);
temp_dead(s, ts);
#endif
}
@@ -1726,11 +1724,13 @@ static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
int i;
for (i = 0; i < s->nb_globals; i++) {
+ TCGTemp *ts = &s->temps[i];
#ifdef USE_LIVENESS_ANALYSIS
- assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
- s->temps[i].mem_coherent);
+ assert(ts->val_type != TEMP_VAL_REG
+ || ts->fixed_reg
+ || ts->mem_coherent);
#else
- temp_sync(s, i, allocated_regs);
+ temp_sync(s, ts, allocated_regs);
#endif
}
}
@@ -1785,7 +1785,7 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
ots->val = val;
}
if (NEED_SYNC_ARG(0)) {
- temp_sync(s, args[0], s->reserved_regs);
+ temp_sync(s, ots, s->reserved_regs);
}
if (IS_DEAD_ARG(0)) {
temp_dead(s, ots);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 10/16] tcg: Change temp_save argument to TCGTemp
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (8 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 09/16] tcg: Change temp_sync " Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 11/16] tcg: Introduce temp_load Richard Henderson
` (7 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 0ca8dbe..579541c 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1690,10 +1690,9 @@ static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
/* save a temporary to memory. 'allocated_regs' is used in case a
temporary registers needs to be allocated to store a constant. */
-static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
+static inline void temp_save(TCGContext *s, TCGTemp *ts,
+ TCGRegSet allocated_regs)
{
- TCGTemp *ts = &s->temps[temp];
-
#ifdef USE_LIVENESS_ANALYSIS
/* The liveness analysis already ensures that globals are back
in memory. Keep an assert for safety. */
@@ -1711,8 +1710,8 @@ static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
{
int i;
- for(i = 0; i < s->nb_globals; i++) {
- temp_save(s, i, allocated_regs);
+ for (i = 0; i < s->nb_globals; i++) {
+ temp_save(s, &s->temps[i], allocated_regs);
}
}
@@ -1739,13 +1738,12 @@ static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
all globals are stored at their canonical location. */
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
{
- TCGTemp *ts;
int i;
- for(i = s->nb_globals; i < s->nb_temps; i++) {
- ts = &s->temps[i];
+ for (i = s->nb_globals; i < s->nb_temps; i++) {
+ TCGTemp *ts = &s->temps[i];
if (ts->temp_local) {
- temp_save(s, i, allocated_regs);
+ temp_save(s, ts, allocated_regs);
} else {
#ifdef USE_LIVENESS_ANALYSIS
/* The liveness analysis already ensures that temps are dead.
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 11/16] tcg: Introduce temp_load
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (9 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 10/16] tcg: Change temp_save " Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 12/16] tcg: Tidy temporary allocation Richard Henderson
` (6 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Unify all of the places that realize a temporary into a register.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 192 +++++++++++++++++++++++++++++---------------------------------
1 file changed, 90 insertions(+), 102 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 579541c..6526305 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1648,43 +1648,69 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
tcg_abort();
}
+/* Make sure the temporary is in a register. If needed, allocate the register
+ from DESIRED while avoiding ALLOCATED. */
+static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
+ TCGRegSet allocated_regs)
+{
+ TCGTempType val_type = ts->val_type;
+
+ if (val_type == TEMP_VAL_REG) {
+ return;
+ }
+
+ ts->reg = tcg_reg_alloc(s, desired_regs, allocated_regs);
+ ts->val_type = TEMP_VAL_REG;
+ s->reg_to_temp[ts->reg] = ts;
+
+ switch (val_type) {
+ case TEMP_VAL_CONST:
+ ts->mem_coherent = 0;
+ tcg_out_movi(s, ts->type, ts->reg, ts->val);
+ break;
+ case TEMP_VAL_MEM:
+ ts->mem_coherent = 1;
+ tcg_out_ld(s, ts->type, ts->reg, ts->mem_base->reg, ts->mem_offset);
+ break;
+ case TEMP_VAL_DEAD:
+ default:
+ tcg_abort();
+ }
+}
+
/* mark a temporary as dead. */
static inline void temp_dead(TCGContext *s, TCGTemp *ts)
{
- if (!ts->fixed_reg) {
- int idx = ts - s->temps;
-
- if (ts->val_type == TEMP_VAL_REG) {
- s->reg_to_temp[ts->reg] = NULL;
- }
- ts->val_type = (idx < s->nb_globals || ts->temp_local
- ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
+ int idx = ts - s->temps;
+ if (ts->fixed_reg) {
+ return;
}
+ if (ts->val_type == TEMP_VAL_REG) {
+ s->reg_to_temp[ts->reg] = NULL;
+ }
+ ts->val_type = (idx < s->nb_globals || ts->temp_local
+ ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
}
/* sync a temporary to memory. 'allocated_regs' is used in case a
temporary registers needs to be allocated to store a constant. */
static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
{
- if (!ts->fixed_reg) {
- switch(ts->val_type) {
- case TEMP_VAL_CONST:
- ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
- allocated_regs);
- ts->val_type = TEMP_VAL_REG;
- s->reg_to_temp[ts->reg] = ts;
- ts->mem_coherent = 0;
- tcg_out_movi(s, ts->type, ts->reg, ts->val);
- /* fallthrough*/
- case TEMP_VAL_REG:
- tcg_reg_sync(s, ts->reg);
- break;
- case TEMP_VAL_DEAD:
- case TEMP_VAL_MEM:
- break;
- default:
- tcg_abort();
- }
+ if (ts->fixed_reg) {
+ return;
+ }
+ switch(ts->val_type) {
+ case TEMP_VAL_CONST:
+ temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs);
+ /* fallthrough*/
+ case TEMP_VAL_REG:
+ tcg_reg_sync(s, ts->reg);
+ break;
+ case TEMP_VAL_DEAD:
+ case TEMP_VAL_MEM:
+ break;
+ default:
+ tcg_abort();
}
}
@@ -1810,16 +1836,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
we don't have to reload SOURCE the next time it is used. */
if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
|| ts->val_type == TEMP_VAL_MEM) {
- ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- if (ts->val_type == TEMP_VAL_MEM) {
- tcg_out_ld(s, ts->type, ts->reg,
- ts->mem_base->reg, ts->mem_offset);
- ts->mem_coherent = 1;
- } else if (ts->val_type == TEMP_VAL_CONST) {
- tcg_out_movi(s, ts->type, ts->reg, ts->val);
- }
- s->reg_to_temp[ts->reg] = ts;
- ts->val_type = TEMP_VAL_REG;
+ temp_load(s, ts, arg_ct->u.regs, allocated_regs);
}
if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
@@ -1901,30 +1918,17 @@ static void tcg_reg_alloc_op(TCGContext *s,
arg = args[i];
arg_ct = &def->args_ct[i];
ts = &s->temps[arg];
- if (ts->val_type == TEMP_VAL_MEM) {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
- ts->val_type = TEMP_VAL_REG;
- ts->reg = reg;
- ts->mem_coherent = 1;
- s->reg_to_temp[reg] = ts;
- } else if (ts->val_type == TEMP_VAL_CONST) {
- if (tcg_target_const_match(ts->val, arg_ct)) {
- /* constant is OK for instruction */
- const_args[i] = 1;
- new_args[i] = ts->val;
- goto iarg_end;
- } else {
- /* need to move to a register */
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_movi(s, ts->type, reg, ts->val);
- ts->val_type = TEMP_VAL_REG;
- ts->reg = reg;
- ts->mem_coherent = 0;
- s->reg_to_temp[reg] = ts;
- }
+
+ if (ts->val_type == TEMP_VAL_CONST
+ && tcg_target_const_match(ts->val, arg_ct)) {
+ /* constant is OK for instruction */
+ const_args[i] = 1;
+ new_args[i] = ts->val;
+ goto iarg_end;
}
- assert(ts->val_type == TEMP_VAL_REG);
+
+ temp_load(s, ts, arg_ct->u.regs, allocated_regs);
+
if (arg_ct->ct & TCG_CT_IALIAS) {
if (ts->fixed_reg) {
/* if fixed register, we must allocate a new register
@@ -2087,23 +2091,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
#endif
if (arg != TCG_CALL_DUMMY_ARG) {
ts = &s->temps[arg];
- if (ts->val_type == TEMP_VAL_REG) {
- tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
- } else if (ts->val_type == TEMP_VAL_MEM) {
- reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
- s->reserved_regs);
- /* XXX: not correct if reading values from the stack */
- tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
- tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
- s->reserved_regs);
- /* XXX: sign extend may be needed on some targets */
- tcg_out_movi(s, ts->type, reg, ts->val);
- tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
- } else {
- tcg_abort();
- }
+ temp_load(s, ts, tcg_target_available_regs[ts->type],
+ s->reserved_regs);
+ tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
}
#ifndef TCG_TARGET_STACK_GROWSUP
stack_offset += sizeof(tcg_target_long);
@@ -2118,18 +2108,19 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
ts = &s->temps[arg];
reg = tcg_target_call_iarg_regs[i];
tcg_reg_free(s, reg);
+
if (ts->val_type == TEMP_VAL_REG) {
if (ts->reg != reg) {
tcg_out_mov(s, ts->type, reg, ts->reg);
}
- } else if (ts->val_type == TEMP_VAL_MEM) {
- tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- /* XXX: sign extend ? */
- tcg_out_movi(s, ts->type, reg, ts->val);
} else {
- tcg_abort();
+ TCGRegSet arg_set;
+
+ tcg_regset_clear(arg_set);
+ tcg_regset_set_reg(arg_set, reg);
+ temp_load(s, ts, arg_set, allocated_regs);
}
+
tcg_regset_set_reg(allocated_regs, reg);
}
}
@@ -2140,12 +2131,19 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
ts = &s->temps[func_arg];
func_addr = ts->val;
const_func_arg = 0;
- if (ts->val_type == TEMP_VAL_MEM) {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
- func_arg = reg;
- tcg_regset_set_reg(allocated_regs, reg);
- } else if (ts->val_type == TEMP_VAL_REG) {
+
+ switch (ts->val_type) {
+ case TEMP_VAL_CONST:
+ if (tcg_target_const_match(func_addr, arg_ct)) {
+ const_func_arg = 1;
+ func_arg = func_addr;
+ break;
+ }
+ /* fall through */
+ case TEMP_VAL_MEM:
+ temp_load(s, ts, arg_ct->u.regs, allocated_regs);
+ /* fall through */
+ case TEMP_VAL_REG:
reg = ts->reg;
if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
@@ -2153,21 +2151,11 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
}
func_arg = reg;
tcg_regset_set_reg(allocated_regs, reg);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- if (tcg_target_const_match(func_addr, arg_ct)) {
- const_func_arg = 1;
- func_arg = func_addr;
- } else {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_movi(s, ts->type, reg, func_addr);
- func_arg = reg;
- tcg_regset_set_reg(allocated_regs, reg);
- }
- } else {
+ break;
+ default:
tcg_abort();
}
-
-
+
/* mark dead temporaries and free the associated registers */
for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
if (IS_DEAD_ARG(i)) {
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 12/16] tcg: Tidy temporary allocation
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (10 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 11/16] tcg: Introduce temp_load Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 13/16] tcg: Use temp_idx Richard Henderson
` (5 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
In particular, make sure the memory is memset before use.
Continues the increased use of TCGTemp pointers instead of
integer indices where appropriate.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 128 +++++++++++++++++++++++++++++---------------------------------
1 file changed, 60 insertions(+), 68 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 6526305..a69186a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -334,32 +334,45 @@ void tcg_func_start(TCGContext *s)
#endif
}
-static inline void tcg_temp_alloc(TCGContext *s, int n)
+static inline int temp_idx(TCGContext *s, TCGTemp *ts)
{
- if (n > TCG_MAX_TEMPS)
- tcg_abort();
+ ptrdiff_t n = ts - s->temps;
+ assert(n >= 0 && n < s->nb_temps);
+ return n;
+}
+
+static inline TCGTemp *tcg_temp_alloc(TCGContext *s)
+{
+ int n = s->nb_temps++;
+ assert(n < TCG_MAX_TEMPS);
+ return memset(&s->temps[n], 0, sizeof(TCGTemp));
+}
+
+static inline TCGTemp *tcg_global_alloc(TCGContext *s)
+{
+ assert(s->nb_globals == s->nb_temps);
+ s->nb_globals++;
+ return tcg_temp_alloc(s);
}
static int tcg_global_reg_new_internal(TCGContext *s, TCGType type,
TCGReg reg, const char *name)
{
TCGTemp *ts;
- int idx;
if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) {
tcg_abort();
}
- idx = s->nb_globals;
- tcg_temp_alloc(s, s->nb_globals + 1);
- ts = &s->temps[s->nb_globals];
+
+ ts = tcg_global_alloc(s);
ts->base_type = type;
ts->type = type;
ts->fixed_reg = 1;
ts->reg = reg;
ts->name = name;
- s->nb_globals++;
tcg_regset_set_reg(s->reserved_regs, reg);
- return idx;
+
+ return temp_idx(s, ts);
}
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
@@ -397,109 +410,88 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
intptr_t offset, const char *name)
{
TCGContext *s = &tcg_ctx;
- TCGTemp *ts, *base_ts = &s->temps[GET_TCGV_PTR(base)];
- int idx;
+ TCGTemp *base_ts = &s->temps[GET_TCGV_PTR(base)];
+ TCGTemp *ts = tcg_global_alloc(s);
+ int bigendian = 0;
+#ifdef TCG_TARGET_WORDS_BIGENDIAN
+ bigendian = 1;
+#endif
- idx = s->nb_globals;
-#if TCG_TARGET_REG_BITS == 32
- if (type == TCG_TYPE_I64) {
+ if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
+ TCGTemp *ts2 = tcg_global_alloc(s);
char buf[64];
- tcg_temp_alloc(s, s->nb_globals + 2);
- ts = &s->temps[s->nb_globals];
- ts->base_type = type;
+
+ ts->base_type = TCG_TYPE_I64;
ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 0;
ts->mem_allocated = 1;
ts->mem_base = base_ts;
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- ts->mem_offset = offset + 4;
-#else
- ts->mem_offset = offset;
-#endif
+ ts->mem_offset = offset + bigendian * 4;
pstrcpy(buf, sizeof(buf), name);
pstrcat(buf, sizeof(buf), "_0");
ts->name = strdup(buf);
- ts++;
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 0;
- ts->mem_allocated = 1;
- ts->mem_base = base_ts;
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- ts->mem_offset = offset;
-#else
- ts->mem_offset = offset + 4;
-#endif
+ assert(ts2 == ts + 1);
+ ts2->base_type = TCG_TYPE_I64;
+ ts2->type = TCG_TYPE_I32;
+ ts2->mem_allocated = 1;
+ ts2->mem_base = base_ts;
+ ts2->mem_offset = offset + (1 - bigendian) * 4;
pstrcpy(buf, sizeof(buf), name);
pstrcat(buf, sizeof(buf), "_1");
ts->name = strdup(buf);
-
- s->nb_globals += 2;
- } else
-#endif
- {
- tcg_temp_alloc(s, s->nb_globals + 1);
- ts = &s->temps[s->nb_globals];
+ } else {
ts->base_type = type;
ts->type = type;
- ts->fixed_reg = 0;
ts->mem_allocated = 1;
ts->mem_base = base_ts;
ts->mem_offset = offset;
ts->name = name;
- s->nb_globals++;
}
- return idx;
+ return temp_idx(s, ts);
}
-static inline int tcg_temp_new_internal(TCGType type, int temp_local)
+static int tcg_temp_new_internal(TCGType type, int temp_local)
{
TCGContext *s = &tcg_ctx;
TCGTemp *ts;
int idx, k;
k = type;
- if (temp_local)
+ if (temp_local) {
k += TCG_TYPE_COUNT;
+ }
idx = s->first_free_temp[k];
if (idx != -1) {
- /* There is already an available temp with the
- right type */
+ /* There is already an available temp with the right type. */
ts = &s->temps[idx];
s->first_free_temp[k] = ts->next_free_temp;
ts->temp_allocated = 1;
+
+ assert(ts->base_type == type);
assert(ts->temp_local == temp_local);
} else {
- idx = s->nb_temps;
-#if TCG_TARGET_REG_BITS == 32
- if (type == TCG_TYPE_I64) {
- tcg_temp_alloc(s, s->nb_temps + 2);
- ts = &s->temps[s->nb_temps];
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->temp_allocated = 1;
- ts->temp_local = temp_local;
- ts->name = NULL;
- ts++;
- ts->base_type = TCG_TYPE_I32;
+ ts = tcg_temp_alloc(s);
+ if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
+ TCGTemp *ts2 = tcg_temp_alloc(s);
+
+ ts->base_type = TCG_TYPE_I64;
ts->type = TCG_TYPE_I32;
ts->temp_allocated = 1;
ts->temp_local = temp_local;
- ts->name = NULL;
- s->nb_temps += 2;
- } else
-#endif
- {
- tcg_temp_alloc(s, s->nb_temps + 1);
- ts = &s->temps[s->nb_temps];
+
+ assert(ts2 == ts + 1);
+ ts2->base_type = TCG_TYPE_I64;
+ ts2->type = TCG_TYPE_I32;
+ ts2->temp_allocated = 1;
+ ts2->temp_local = temp_local;
+ } else {
ts->base_type = type;
ts->type = type;
ts->temp_allocated = 1;
ts->temp_local = temp_local;
- ts->name = NULL;
s->nb_temps++;
}
+ idx = temp_idx(s, ts);
}
#if defined(CONFIG_DEBUG_TCG)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 13/16] tcg: Use temp_idx
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (11 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 12/16] tcg: Tidy temporary allocation Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 14/16] tcg: Implement indirect memory registers Richard Henderson
` (4 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index a69186a..3591491 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -808,7 +808,7 @@ static void tcg_reg_alloc_start(TCGContext *s)
static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
TCGTemp *ts)
{
- int idx = ts - s->temps;
+ int idx = temp_idx(s, ts);
if (idx < s->nb_globals) {
pstrcpy(buf, buf_size, ts->name);
@@ -1593,7 +1593,7 @@ static inline void tcg_reg_sync(TCGContext *s, TCGReg reg)
assert(ts->val_type == TEMP_VAL_REG);
if (!ts->mem_coherent && !ts->fixed_reg) {
if (!ts->mem_allocated) {
- temp_allocate_frame(s, ts - s->temps);
+ temp_allocate_frame(s, temp_idx(s, ts));
}
tcg_out_st(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
}
@@ -1673,7 +1673,7 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
/* mark a temporary as dead. */
static inline void temp_dead(TCGContext *s, TCGTemp *ts)
{
- int idx = ts - s->temps;
+ int idx = temp_idx(s, ts);
if (ts->fixed_reg) {
return;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 14/16] tcg: Implement indirect memory registers
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (12 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 13/16] tcg: Use temp_idx Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 15/16] target-sparc: Tidy global register initialization Richard Henderson
` (3 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
That is, global_mem registers whose base is another global_mem
register, rather than a fixed register.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 104 ++++++++++++++++++++++++++++++++++++++++++--------------------
tcg/tcg.h | 2 ++
2 files changed, 73 insertions(+), 33 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3591491..eb4ed0d 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -412,17 +412,23 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
TCGContext *s = &tcg_ctx;
TCGTemp *base_ts = &s->temps[GET_TCGV_PTR(base)];
TCGTemp *ts = tcg_global_alloc(s);
- int bigendian = 0;
+ int indirect_reg = 0, bigendian = 0;
#ifdef TCG_TARGET_WORDS_BIGENDIAN
bigendian = 1;
#endif
+ if (!base_ts->fixed_reg) {
+ indirect_reg = 1;
+ base_ts->indirect_base = 1;
+ }
+
if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
TCGTemp *ts2 = tcg_global_alloc(s);
char buf[64];
ts->base_type = TCG_TYPE_I64;
ts->type = TCG_TYPE_I32;
+ ts->indirect_reg = indirect_reg;
ts->mem_allocated = 1;
ts->mem_base = base_ts;
ts->mem_offset = offset + bigendian * 4;
@@ -433,6 +439,7 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
assert(ts2 == ts + 1);
ts2->base_type = TCG_TYPE_I64;
ts2->type = TCG_TYPE_I32;
+ ts2->indirect_reg = indirect_reg;
ts2->mem_allocated = 1;
ts2->mem_base = base_ts;
ts2->mem_offset = offset + (1 - bigendian) * 4;
@@ -442,6 +449,7 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
} else {
ts->base_type = type;
ts->type = type;
+ ts->indirect_reg = indirect_reg;
ts->mem_allocated = 1;
ts->mem_base = base_ts;
ts->mem_offset = offset;
@@ -1585,8 +1593,10 @@ static void temp_allocate_frame(TCGContext *s, int temp)
s->current_frame_offset += sizeof(tcg_target_long);
}
+static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet);
+
/* sync register 'reg' by saving it to the corresponding temporary */
-static inline void tcg_reg_sync(TCGContext *s, TCGReg reg)
+static void tcg_reg_sync(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
{
TCGTemp *ts = s->reg_to_temp[reg];
@@ -1594,6 +1604,11 @@ static inline void tcg_reg_sync(TCGContext *s, TCGReg reg)
if (!ts->mem_coherent && !ts->fixed_reg) {
if (!ts->mem_allocated) {
temp_allocate_frame(s, temp_idx(s, ts));
+ } else if (ts->indirect_reg) {
+ tcg_regset_set_reg(allocated_regs, ts->reg);
+ temp_load(s, ts->mem_base,
+ tcg_target_available_regs[TCG_TYPE_PTR],
+ allocated_regs);
}
tcg_out_st(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
}
@@ -1601,25 +1616,26 @@ static inline void tcg_reg_sync(TCGContext *s, TCGReg reg)
}
/* free register 'reg' by spilling the corresponding temporary if necessary */
-static void tcg_reg_free(TCGContext *s, TCGReg reg)
+static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
{
TCGTemp *ts = s->reg_to_temp[reg];
if (ts != NULL) {
- tcg_reg_sync(s, reg);
+ tcg_reg_sync(s, reg, allocated_regs);
ts->val_type = TEMP_VAL_MEM;
s->reg_to_temp[reg] = NULL;
}
}
/* Allocate a register belonging to reg1 & ~reg2 */
-static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
+static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
+ TCGRegSet allocated_regs)
{
int i;
TCGReg reg;
TCGRegSet reg_ct;
- tcg_regset_andnot(reg_ct, reg1, reg2);
+ tcg_regset_andnot(reg_ct, desired_regs, allocated_regs);
/* first try free registers */
for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
@@ -1632,7 +1648,7 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
reg = tcg_target_reg_alloc_order[i];
if (tcg_regset_test_reg(reg_ct, reg)) {
- tcg_reg_free(s, reg);
+ tcg_reg_free(s, reg, allocated_regs);
return reg;
}
}
@@ -1652,22 +1668,28 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
}
ts->reg = tcg_reg_alloc(s, desired_regs, allocated_regs);
- ts->val_type = TEMP_VAL_REG;
- s->reg_to_temp[ts->reg] = ts;
switch (val_type) {
case TEMP_VAL_CONST:
- ts->mem_coherent = 0;
tcg_out_movi(s, ts->type, ts->reg, ts->val);
+ ts->mem_coherent = 0;
break;
case TEMP_VAL_MEM:
- ts->mem_coherent = 1;
+ if (ts->indirect_reg) {
+ tcg_regset_set_reg(allocated_regs, ts->reg);
+ temp_load(s, ts->mem_base,
+ tcg_target_available_regs[TCG_TYPE_PTR],
+ allocated_regs);
+ }
tcg_out_ld(s, ts->type, ts->reg, ts->mem_base->reg, ts->mem_offset);
+ ts->mem_coherent = 1;
break;
case TEMP_VAL_DEAD:
default:
tcg_abort();
}
+ ts->val_type = TEMP_VAL_REG;
+ s->reg_to_temp[ts->reg] = ts;
}
/* mark a temporary as dead. */
@@ -1696,7 +1718,7 @@ static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs);
/* fallthrough*/
case TEMP_VAL_REG:
- tcg_reg_sync(s, ts->reg);
+ tcg_reg_sync(s, ts->reg, allocated_regs);
break;
case TEMP_VAL_DEAD:
case TEMP_VAL_MEM:
@@ -1712,13 +1734,16 @@ static inline void temp_save(TCGContext *s, TCGTemp *ts,
TCGRegSet allocated_regs)
{
#ifdef USE_LIVENESS_ANALYSIS
- /* The liveness analysis already ensures that globals are back
- in memory. Keep an assert for safety. */
- assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
-#else
+ /* ??? Liveness does not yet incorporate indirect bases. */
+ if (!ts->indirect_base) {
+ /* The liveness analysis already ensures that globals are back
+ in memory. Keep an assert for safety. */
+ assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
+ return;
+ }
+#endif
temp_sync(s, ts, allocated_regs);
temp_dead(s, ts);
-#endif
}
/* save globals to their canonical location and assume they can be
@@ -1742,13 +1767,17 @@ static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
for (i = 0; i < s->nb_globals; i++) {
TCGTemp *ts = &s->temps[i];
+
#ifdef USE_LIVENESS_ANALYSIS
- assert(ts->val_type != TEMP_VAL_REG
- || ts->fixed_reg
- || ts->mem_coherent);
-#else
- temp_sync(s, ts, allocated_regs);
+ /* ??? Liveness does not yet incorporate indirect bases. */
+ if (!ts->indirect_base) {
+ assert(ts->val_type != TEMP_VAL_REG
+ || ts->fixed_reg
+ || ts->mem_coherent);
+ continue;
+ }
#endif
+ temp_sync(s, ts, allocated_regs);
}
}
@@ -1764,12 +1793,15 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
temp_save(s, ts, allocated_regs);
} else {
#ifdef USE_LIVENESS_ANALYSIS
- /* The liveness analysis already ensures that temps are dead.
- Keep an assert for safety. */
- assert(ts->val_type == TEMP_VAL_DEAD);
-#else
- temp_dead(s, ts);
+ /* ??? Liveness does not yet incorporate indirect bases. */
+ if (!ts->indirect_base) {
+ /* The liveness analysis already ensures that temps are dead.
+ Keep an assert for safety. */
+ assert(ts->val_type == TEMP_VAL_DEAD);
+ continue;
+ }
#endif
+ temp_dead(s, ts);
}
}
@@ -1840,6 +1872,12 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
if (!ots->mem_allocated) {
temp_allocate_frame(s, args[0]);
}
+ if (ots->indirect_reg) {
+ tcg_regset_set_reg(allocated_regs, ts->reg);
+ temp_load(s, ots->mem_base,
+ tcg_target_available_regs[TCG_TYPE_PTR],
+ allocated_regs);
+ }
tcg_out_st(s, ots->type, ts->reg, ots->mem_base->reg, ots->mem_offset);
if (IS_DEAD_ARG(1)) {
temp_dead(s, ts);
@@ -1876,7 +1914,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
ots->mem_coherent = 0;
s->reg_to_temp[ots->reg] = ots;
if (NEED_SYNC_ARG(0)) {
- tcg_reg_sync(s, ots->reg);
+ tcg_reg_sync(s, ots->reg, allocated_regs);
}
}
}
@@ -1966,7 +2004,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
/* XXX: permit generic clobber register list ? */
for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
- tcg_reg_free(s, reg);
+ tcg_reg_free(s, reg, allocated_regs);
}
}
}
@@ -2023,7 +2061,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
tcg_out_mov(s, ts->type, ts->reg, reg);
}
if (NEED_SYNC_ARG(i)) {
- tcg_reg_sync(s, reg);
+ tcg_reg_sync(s, reg, allocated_regs);
}
if (IS_DEAD_ARG(i)) {
temp_dead(s, ts);
@@ -2099,7 +2137,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
if (arg != TCG_CALL_DUMMY_ARG) {
ts = &s->temps[arg];
reg = tcg_target_call_iarg_regs[i];
- tcg_reg_free(s, reg);
+ tcg_reg_free(s, reg, allocated_regs);
if (ts->val_type == TEMP_VAL_REG) {
if (ts->reg != reg) {
@@ -2158,7 +2196,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
/* clobber call registers */
for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
- tcg_reg_free(s, reg);
+ tcg_reg_free(s, reg, allocated_regs);
}
}
@@ -2193,7 +2231,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
ts->mem_coherent = 0;
s->reg_to_temp[reg] = ts;
if (NEED_SYNC_ARG(i)) {
- tcg_reg_sync(s, reg);
+ tcg_reg_sync(s, reg, allocated_regs);
}
if (IS_DEAD_ARG(i)) {
temp_dead(s, ts);
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 74649fa..cff86dc 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -399,6 +399,8 @@ typedef struct TCGTemp {
struct TCGTemp *mem_base;
intptr_t mem_offset;
unsigned int fixed_reg:1;
+ unsigned int indirect_reg:1;
+ unsigned int indirect_base:1;
unsigned int mem_coherent:1;
unsigned int mem_allocated:1;
unsigned int temp_local:1; /* If true, the temp is saved across
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 15/16] target-sparc: Tidy global register initialization
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (13 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 14/16] tcg: Implement indirect memory registers Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-19 21:25 ` [Qemu-devel] [RFC 16/16] target-sparc: Use global registers for the register window Richard Henderson
` (2 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Create tables for the various global registers that need allocation.
Remove one level of indirection from gregnames and fregnames.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 160 +++++++++++++++++++++--------------------------
1 file changed, 71 insertions(+), 89 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 6a921f3..7a51d7f 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5360,112 +5360,94 @@ void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
void gen_intermediate_code_init(CPUSPARCState *env)
{
- unsigned int i;
static int inited;
- static const char * const gregnames[8] = {
- NULL, // g0 not used
- "g1",
- "g2",
- "g3",
- "g4",
- "g5",
- "g6",
- "g7",
+ static const char gregnames[8][4] = {
+ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
};
- static const char * const fregnames[32] = {
+ static const char fregnames[32][4] = {
"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",
};
- /* init various static tables */
- if (!inited) {
- inited = 1;
-
- cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cpu_regwptr = tcg_global_mem_new_ptr(cpu_env,
- offsetof(CPUSPARCState, regwptr),
- "regwptr");
+ static const struct { TCGv_i32 *ptr; int off; const char *name; } r32[] = {
#ifdef TARGET_SPARC64
- cpu_xcc = tcg_global_mem_new_i32(cpu_env, offsetof(CPUSPARCState, xcc),
- "xcc");
- cpu_asi = tcg_global_mem_new_i32(cpu_env, offsetof(CPUSPARCState, asi),
- "asi");
- cpu_fprs = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUSPARCState, fprs),
- "fprs");
- cpu_gsr = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, gsr),
- "gsr");
- cpu_tick_cmpr = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, tick_cmpr),
- "tick_cmpr");
- cpu_stick_cmpr = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, stick_cmpr),
- "stick_cmpr");
- cpu_hstick_cmpr = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, hstick_cmpr),
- "hstick_cmpr");
- cpu_hintp = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, hintp),
- "hintp");
- cpu_htba = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, htba),
- "htba");
- cpu_hver = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, hver),
- "hver");
- cpu_ssr = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, ssr), "ssr");
- cpu_ver = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, version), "ver");
- cpu_softint = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUSPARCState, softint),
- "softint");
+ { &cpu_xcc, offsetof(CPUSPARCState, xcc), "xcc" },
+ { &cpu_asi, offsetof(CPUSPARCState, asi), "asi" },
+ { &cpu_fprs, offsetof(CPUSPARCState, fprs), "fprs" },
+ { &cpu_softint, offsetof(CPUSPARCState, softint), "softint" },
#else
- cpu_wim = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, wim),
- "wim");
+ { &cpu_wim, offsetof(CPUSPARCState, wim), "wim" },
+#endif
+ { &cpu_cc_op, offsetof(CPUSPARCState, cc_op), "cc_op" },
+ { &cpu_psr, offsetof(CPUSPARCState, psr), "psr" },
+ };
+
+ static const struct { TCGv *ptr; int off; const char *name; } rtl[] = {
+#ifdef TARGET_SPARC64
+ { &cpu_gsr, offsetof(CPUSPARCState, gsr), "gsr" },
+ { &cpu_tick_cmpr, offsetof(CPUSPARCState, tick_cmpr), "tick_cmpr" },
+ { &cpu_stick_cmpr, offsetof(CPUSPARCState, stick_cmpr), "stick_cmpr" },
+ { &cpu_hstick_cmpr, offsetof(CPUSPARCState, hstick_cmpr),
+ "hstick_cmpr" },
+ { &cpu_hintp, offsetof(CPUSPARCState, hintp), "hintp" },
+ { &cpu_htba, offsetof(CPUSPARCState, htba), "htba" },
+ { &cpu_hver, offsetof(CPUSPARCState, hver), "hver" },
+ { &cpu_ssr, offsetof(CPUSPARCState, ssr), "ssr" },
+ { &cpu_ver, offsetof(CPUSPARCState, version), "ver" },
#endif
- cpu_cond = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, cond),
- "cond");
- cpu_cc_src = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, cc_src),
- "cc_src");
- cpu_cc_src2 = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, cc_src2),
- "cc_src2");
- cpu_cc_dst = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, cc_dst),
- "cc_dst");
- cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUSPARCState, cc_op),
- "cc_op");
- cpu_psr = tcg_global_mem_new_i32(cpu_env, offsetof(CPUSPARCState, psr),
- "psr");
- cpu_fsr = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, fsr),
- "fsr");
- cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, pc),
- "pc");
- cpu_npc = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, npc),
- "npc");
- cpu_y = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, y), "y");
+ { &cpu_cond, offsetof(CPUSPARCState, cond), "cond" },
+ { &cpu_cc_src, offsetof(CPUSPARCState, cc_src), "cc_src" },
+ { &cpu_cc_src2, offsetof(CPUSPARCState, cc_src2), "cc_src2" },
+ { &cpu_cc_dst, offsetof(CPUSPARCState, cc_dst), "cc_dst" },
+ { &cpu_fsr, offsetof(CPUSPARCState, fsr), "fsr" },
+ { &cpu_pc, offsetof(CPUSPARCState, pc), "pc" },
+ { &cpu_npc, offsetof(CPUSPARCState, npc), "npc" },
+ { &cpu_y, offsetof(CPUSPARCState, y), "y" },
#ifndef CONFIG_USER_ONLY
- cpu_tbr = tcg_global_mem_new(cpu_env, offsetof(CPUSPARCState, tbr),
- "tbr");
+ { &cpu_tbr, offsetof(CPUSPARCState, tbr), "tbr" },
#endif
- for (i = 1; i < 8; i++) {
- cpu_gregs[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, gregs[i]),
- gregnames[i]);
- }
- for (i = 0; i < TARGET_DPREGS; i++) {
- cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
- offsetof(CPUSPARCState, fpr[i]),
- fregnames[i]);
- }
+ };
+
+ unsigned int i;
+
+ /* init various static tables */
+ if (inited) {
+ return;
+ }
+ inited = 1;
+
+ cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- /* register helpers */
+ cpu_regwptr = tcg_global_mem_new_ptr(cpu_env,
+ offsetof(CPUSPARCState, regwptr),
+ "regwptr");
+ for (i = 0; i < ARRAY_SIZE(r32); ++i) {
+ *r32[i].ptr = tcg_global_mem_new_i32(cpu_env, r32[i].off, r32[i].name);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rtl); ++i) {
+ *rtl[i].ptr = tcg_global_mem_new(cpu_env, rtl[i].off, rtl[i].name);
+ }
+
+ TCGV_UNUSED(cpu_gregs[0]);
+ for (i = 1; i < 8; ++i) {
+ cpu_gregs[i] = tcg_global_mem_new(cpu_env,
+ offsetof(CPUSPARCState, gregs[i]),
+ gregnames[i]);
+ }
+
+ for (i = 0; i < TARGET_DPREGS; i++) {
+ cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
+ offsetof(CPUSPARCState, fpr[i]),
+ fregnames[i]);
+ }
+
+ /* register helpers */
#define GEN_HELPER 2
#include "helper.h"
- }
}
void restore_state_to_opc(CPUSPARCState *env, TranslationBlock *tb, int pc_pos)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [RFC 16/16] target-sparc: Use global registers for the register window
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (14 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 15/16] target-sparc: Tidy global register initialization Richard Henderson
@ 2013-09-19 21:25 ` Richard Henderson
2013-09-22 17:28 ` [Qemu-devel] [RFC 00/16] TCG indirect registers Max Filippov
2013-09-23 17:23 ` Blue Swirl
17 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2013-09-19 21:25 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel, aurelien
Via indirection off cpu_regwptr.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 49 ++++++++++++++++++++++++++----------------------
1 file changed, 27 insertions(+), 22 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 7a51d7f..6395ad3 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -43,7 +43,8 @@ static TCGv_ptr cpu_env, cpu_regwptr;
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
static TCGv_i32 cpu_cc_op;
static TCGv_i32 cpu_psr;
-static TCGv cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
+static TCGv cpu_fsr, cpu_pc, cpu_npc;
+static TCGv cpu_regs[32];
static TCGv cpu_y;
#ifndef CONFIG_USER_ONLY
static TCGv cpu_tbr;
@@ -276,36 +277,31 @@ static inline void gen_address_mask(DisasContext *dc, TCGv addr)
static inline TCGv gen_load_gpr(DisasContext *dc, int reg)
{
- if (reg == 0 || reg >= 8) {
+ if (reg > 0) {
+ assert(reg < 32);
+ return cpu_regs[reg];
+ } else {
TCGv t = get_temp_tl(dc);
- if (reg == 0) {
- tcg_gen_movi_tl(t, 0);
- } else {
- tcg_gen_ld_tl(t, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
- }
+ tcg_gen_movi_tl(t, 0);
return t;
- } else {
- return cpu_gregs[reg];
}
}
static inline void gen_store_gpr(DisasContext *dc, int reg, TCGv v)
{
if (reg > 0) {
- if (reg < 8) {
- tcg_gen_mov_tl(cpu_gregs[reg], v);
- } else {
- tcg_gen_st_tl(v, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
- }
+ assert(reg < 32);
+ tcg_gen_mov_tl(cpu_regs[reg], v);
}
}
static inline TCGv gen_dest_gpr(DisasContext *dc, int reg)
{
- if (reg == 0 || reg >= 8) {
- return get_temp_tl(dc);
+ if (reg > 0) {
+ assert(reg < 32);
+ return cpu_regs[reg];
} else {
- return cpu_gregs[reg];
+ return get_temp_tl(dc);
}
}
@@ -5361,8 +5357,11 @@ void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
void gen_intermediate_code_init(CPUSPARCState *env)
{
static int inited;
- static const char gregnames[8][4] = {
+ static const char gregnames[32][4] = {
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
};
static const char fregnames[32][4] = {
"f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14",
@@ -5432,11 +5431,17 @@ void gen_intermediate_code_init(CPUSPARCState *env)
*rtl[i].ptr = tcg_global_mem_new(cpu_env, rtl[i].off, rtl[i].name);
}
- TCGV_UNUSED(cpu_gregs[0]);
+ TCGV_UNUSED(cpu_regs[0]);
for (i = 1; i < 8; ++i) {
- cpu_gregs[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPUSPARCState, gregs[i]),
- gregnames[i]);
+ cpu_regs[i] = tcg_global_mem_new(cpu_env,
+ offsetof(CPUSPARCState, gregs[i]),
+ gregnames[i]);
+ }
+
+ for (i = 8; i < 32; ++i) {
+ cpu_regs[i] = tcg_global_mem_new(cpu_regwptr,
+ (i - 8) * sizeof(target_ulong),
+ gregnames[i]);
}
for (i = 0; i < TARGET_DPREGS; i++) {
--
1.8.1.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [RFC 00/16] TCG indirect registers
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (15 preceding siblings ...)
2013-09-19 21:25 ` [Qemu-devel] [RFC 16/16] target-sparc: Use global registers for the register window Richard Henderson
@ 2013-09-22 17:28 ` Max Filippov
2013-09-23 17:23 ` Blue Swirl
17 siblings, 0 replies; 21+ messages in thread
From: Max Filippov @ 2013-09-22 17:28 UTC (permalink / raw)
To: Richard Henderson; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno
On Fri, Sep 20, 2013 at 1:24 AM, Richard Henderson <rth@twiddle.net> wrote:
> This is an attempt to improve performance of target-sparc
> by exposing the windowed registers as TCG globals, and all
> the optimization that we can do there.
>
> This is done via allowing tcg_global_mem_new to be used
> with any base pointer, not just off of a fixed register.
> Thus the sparc windowed registers are globals off cpu_regwptr.
>
> In the process of working through this, I attempt to remove
> as many uses of "int" as I can throughout the TCG code gen
> paths, replacing them with TCGReg when we're talking about
> hard registers, and TCGTemp pointers when we're talking about
> temporaries. This, IMO, reduces confusion as to what kind of
> "int" we mean at any given time.
>
> By the time we get to patch 14, actually implementing the
> indirect temps, it's fairly easy to recurse in order to
> load the base pointer when we need to load or store an
> indirect temp.
>
> I've not yet tried to measure the performance. As far as
> testing, linux-user-0.3 and sparc-test-0.2 works. I've
> scanned some of the dumps from those. In the cases where
> no real optimization was possible, we generate practically
> the same code -- usually with different registers selected.
> In the cases where we can optimize, I've seen some TB's
> cut in half.
>
> Anyway, I wanted some feedback before I take this any further.
Hi Richard,
I've reimplemented xtensa windowed registers in the same
way as done for sparc on top of this series. Haven't got any
measurable performance change. From op,out_asm output most
TBs got longer by 1-4 instructions and all temp indices got
doubled.
--->8---
>From 73300be7dd6b3d31cbfa45225714d5e43c52f077 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 22 Sep 2013 18:54:53 +0400
Subject: [PATCH] target-xtensa: reimplement windowed registers
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
target-xtensa/cpu.c | 1 +
target-xtensa/cpu.h | 5 +++--
target-xtensa/op_helper.c | 46 ++++++++++------------------------------------
target-xtensa/translate.c | 7 +++++--
4 files changed, 19 insertions(+), 40 deletions(-)
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index c19d17a..a30511d 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -59,6 +59,7 @@ static void xtensa_cpu_reset(CPUState *s)
env->sregs[CACHEATTR] = 0x22222222;
env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
+ rotate_window_abs(env, env->sregs[WINDOW_BASE]);
env->pending_irq_level = 0;
reset_mmu(env);
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 95103e9..8100f18 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -334,11 +334,11 @@ typedef struct XtensaConfigList {
typedef struct CPUXtensaState {
const XtensaConfig *config;
- uint32_t regs[16];
+ uint32_t *regs;
uint32_t pc;
uint32_t sregs[256];
uint32_t uregs[256];
- uint32_t phys_regs[MAX_NAREG];
+ uint32_t phys_regs[MAX_NAREG + 12];
float32 fregs[16];
float_status fp_status;
@@ -396,6 +396,7 @@ void xtensa_timer_irq(CPUXtensaState *env, uint32_t id, uint32_t active);
void xtensa_rearm_ccompare_timer(CPUXtensaState *env);
int cpu_xtensa_signal_handler(int host_signum, void *pinfo, void *puc);
void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf);
+void rotate_window_abs(CPUXtensaState *env, uint32_t position);
void xtensa_sync_window_from_phys(CPUXtensaState *env);
void xtensa_sync_phys_from_window(CPUXtensaState *env);
uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t way);
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index cf97025..ee21550 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -166,39 +166,6 @@ uint32_t HELPER(nsau)(uint32_t v)
return v ? clz32(v) : 32;
}
-static void copy_window_from_phys(CPUXtensaState *env,
- uint32_t window, uint32_t phys, uint32_t n)
-{
- assert(phys < env->config->nareg);
- if (phys + n <= env->config->nareg) {
- memcpy(env->regs + window, env->phys_regs + phys,
- n * sizeof(uint32_t));
- } else {
- uint32_t n1 = env->config->nareg - phys;
- memcpy(env->regs + window, env->phys_regs + phys,
- n1 * sizeof(uint32_t));
- memcpy(env->regs + window + n1, env->phys_regs,
- (n - n1) * sizeof(uint32_t));
- }
-}
-
-static void copy_phys_from_window(CPUXtensaState *env,
- uint32_t phys, uint32_t window, uint32_t n)
-{
- assert(phys < env->config->nareg);
- if (phys + n <= env->config->nareg) {
- memcpy(env->phys_regs + phys, env->regs + window,
- n * sizeof(uint32_t));
- } else {
- uint32_t n1 = env->config->nareg - phys;
- memcpy(env->phys_regs + phys, env->regs + window,
- n1 * sizeof(uint32_t));
- memcpy(env->phys_regs, env->regs + window + n1,
- (n - n1) * sizeof(uint32_t));
- }
-}
-
-
static inline unsigned windowbase_bound(unsigned a, const CPUXtensaState *env)
{
return a & (env->config->nareg / 4 - 1);
@@ -211,18 +178,25 @@ static inline unsigned windowstart_bit(unsigned a, const CPUXtensaState *env)
void xtensa_sync_window_from_phys(CPUXtensaState *env)
{
- copy_window_from_phys(env, 0, env->sregs[WINDOW_BASE] * 4, 16);
+ if (env->sregs[WINDOW_BASE] * 4 + 16 > env->config->nareg)
+ memcpy(env->phys_regs + env->config->nareg, env->phys_regs,
+ (env->sregs[WINDOW_BASE] * 4 + 16 - env->config->nareg) *
+ sizeof(uint32_t));
}
void xtensa_sync_phys_from_window(CPUXtensaState *env)
{
- copy_phys_from_window(env, env->sregs[WINDOW_BASE] * 4, 0, 16);
+ if (env->sregs[WINDOW_BASE] * 4 + 16 > env->config->nareg)
+ memcpy(env->phys_regs, env->phys_regs + env->config->nareg,
+ (env->sregs[WINDOW_BASE] * 4 + 16 - env->config->nareg) *
+ sizeof(uint32_t));
}
-static void rotate_window_abs(CPUXtensaState *env, uint32_t position)
+void rotate_window_abs(CPUXtensaState *env, uint32_t position)
{
xtensa_sync_phys_from_window(env);
env->sregs[WINDOW_BASE] = windowbase_bound(position, env);
+ env->regs = env->phys_regs + env->sregs[WINDOW_BASE] * 4;
xtensa_sync_window_from_phys(env);
}
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index bb7dfd0..61be622 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -70,6 +70,7 @@ typedef struct DisasContext {
} DisasContext;
static TCGv_ptr cpu_env;
+static TCGv_ptr cpu_regs;
static TCGv_i32 cpu_pc;
static TCGv_i32 cpu_R[16];
static TCGv_i32 cpu_FR[16];
@@ -208,12 +209,14 @@ void xtensa_translate_init(void)
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+ cpu_regs = tcg_global_mem_new_ptr(cpu_env,
+ offsetof(CPUXtensaState, regs), "regs");
cpu_pc = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, pc), "pc");
for (i = 0; i < 16; i++) {
- cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUXtensaState, regs[i]),
+ cpu_R[i] = tcg_global_mem_new_i32(cpu_regs,
+ i * sizeof(uint32_t),
regnames[i]);
}
-- 1.8.1.4
--
Thanks.
-- Max
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [RFC 00/16] TCG indirect registers
2013-09-19 21:24 [Qemu-devel] [RFC 00/16] TCG indirect registers Richard Henderson
` (16 preceding siblings ...)
2013-09-22 17:28 ` [Qemu-devel] [RFC 00/16] TCG indirect registers Max Filippov
@ 2013-09-23 17:23 ` Blue Swirl
2013-09-23 18:06 ` Richard Henderson
17 siblings, 1 reply; 21+ messages in thread
From: Blue Swirl @ 2013-09-23 17:23 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, Aurelien Jarno
On Fri, Sep 20, 2013 at 12:24 AM, Richard Henderson <rth@twiddle.net> wrote:
>
> This is an attempt to improve performance of target-sparc
> by exposing the windowed registers as TCG globals, and all
> the optimization that we can do there.
>
> This is done via allowing tcg_global_mem_new to be used
> with any base pointer, not just off of a fixed register.
> Thus the sparc windowed registers are globals off cpu_regwptr.
Nice and simple.
Would it be possible to eliminate regwptr and perform the calculation
of the effective register set during compile time? We could get rid of
register shuffling (memcpy32) and register access would be much
simpler. The downside would be that code which is called from
different register window level would need to be recompiled.
>
> In the process of working through this, I attempt to remove
> as many uses of "int" as I can throughout the TCG code gen
> paths, replacing them with TCGReg when we're talking about
> hard registers, and TCGTemp pointers when we're talking about
> temporaries. This, IMO, reduces confusion as to what kind of
> "int" we mean at any given time.
>
> By the time we get to patch 14, actually implementing the
> indirect temps, it's fairly easy to recurse in order to
> load the base pointer when we need to load or store an
> indirect temp.
>
> I've not yet tried to measure the performance. As far as
> testing, linux-user-0.3 and sparc-test-0.2 works. I've
> scanned some of the dumps from those. In the cases where
> no real optimization was possible, we generate practically
> the same code -- usually with different registers selected.
> In the cases where we can optimize, I've seen some TB's
> cut in half.
>
> Anyway, I wanted some feedback before I take this any further.
>
>
> r~
>
>
> Richard Henderson (16):
> tcg: Change tcg_global_mem_new_* to take a TCGv_ptr
> tcg: Introduce TCGTempType
> tcg: Change ts->mem_reg to ts->mem_base
> tcg: Compress TCGLabelQemuLdst
> tcg: More use of TCGReg where appropriate
> tcg: Remove tcg_get_arg_str_i32/64
> tcg: Change reg_to_temp to TCGTemp pointer
> tcg: Change temp_dead argument to TCGTemp
> tcg: Change temp_sync argument to TCGTemp
> tcg: Change temp_save argument to TCGTemp
> tcg: Introduce temp_load
> tcg: Tidy temporary allocation
> tcg: Use temp_idx
> tcg: Implement indirect memory registers
> target-sparc: Tidy global register initialization
> target-sparc: Use global registers for the register window
>
> target-alpha/translate.c | 40 +--
> target-arm/translate.c | 20 +-
> target-cris/translate.c | 24 +-
> target-cris/translate_v10.c | 82 +++---
> target-i386/translate.c | 56 ++--
> target-lm32/translate.c | 24 +-
> target-m68k/translate.c | 28 +-
> target-microblaze/translate.c | 14 +-
> target-mips/translate.c | 25 +-
> target-moxie/translate.c | 8 +-
> target-openrisc/translate.c | 26 +-
> target-ppc/translate.c | 40 +--
> target-s390x/translate.c | 16 +-
> target-sh4/translate.c | 36 +--
> target-sparc/translate.c | 195 ++++++-------
> target-unicore32/translate.c | 2 +-
> target-xtensa/translate.c | 10 +-
> tcg/tcg.c | 641 +++++++++++++++++++++---------------------
> tcg/tcg.h | 78 +++--
> 19 files changed, 693 insertions(+), 672 deletions(-)
>
> --
> 1.8.1.4
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [RFC 00/16] TCG indirect registers
2013-09-23 17:23 ` Blue Swirl
@ 2013-09-23 18:06 ` Richard Henderson
2013-09-24 13:32 ` Artyom Tarasenko
0 siblings, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2013-09-23 18:06 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel, Aurelien Jarno
On 09/23/2013 10:23 AM, Blue Swirl wrote:
> On Fri, Sep 20, 2013 at 12:24 AM, Richard Henderson <rth@twiddle.net> wrote:
>>
>> This is an attempt to improve performance of target-sparc
>> by exposing the windowed registers as TCG globals, and all
>> the optimization that we can do there.
>>
>> This is done via allowing tcg_global_mem_new to be used
>> with any base pointer, not just off of a fixed register.
>> Thus the sparc windowed registers are globals off cpu_regwptr.
>
> Nice and simple.
>
> Would it be possible to eliminate regwptr and perform the calculation
> of the effective register set during compile time? We could get rid of
> register shuffling (memcpy32) and register access would be much
> simpler. The downside would be that code which is called from
> different register window level would need to be recompiled.
An interesting idea. Yes, it would be possible to grab some bits
from TB->flags and encode the register window setting. I suppose
it all depends on how much overhead there is from the recompilation
as opposed to the indirection + memcpys.
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [RFC 00/16] TCG indirect registers
2013-09-23 18:06 ` Richard Henderson
@ 2013-09-24 13:32 ` Artyom Tarasenko
0 siblings, 0 replies; 21+ messages in thread
From: Artyom Tarasenko @ 2013-09-24 13:32 UTC (permalink / raw)
To: Richard Henderson; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno
On Mon, Sep 23, 2013 at 8:06 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 09/23/2013 10:23 AM, Blue Swirl wrote:
>> On Fri, Sep 20, 2013 at 12:24 AM, Richard Henderson <rth@twiddle.net> wrote:
>>>
>>> This is an attempt to improve performance of target-sparc
>>> by exposing the windowed registers as TCG globals, and all
>>> the optimization that we can do there.
>>>
>>> This is done via allowing tcg_global_mem_new to be used
>>> with any base pointer, not just off of a fixed register.
>>> Thus the sparc windowed registers are globals off cpu_regwptr.
>>
>> Nice and simple.
>>
>> Would it be possible to eliminate regwptr and perform the calculation
>> of the effective register set during compile time? We could get rid of
>> register shuffling (memcpy32) and register access would be much
>> simpler. The downside would be that code which is called from
>> different register window level would need to be recompiled.
>
> An interesting idea. Yes, it would be possible to grab some bits
> from TB->flags and encode the register window setting. I suppose
> it all depends on how much overhead there is from the recompilation
> as opposed to the indirection + memcpys.
Last time I looked into profiler with perl under Debian/sparc64 guest
there was a very small overhead from memcpy32 (less than 1%).
With a newer gcc it could be even less: I couldn't persuade my
gcc (4.4.7) to use sse instructions for memcpy32.
Can't find my profiling results right now, but they were quite close to
Aurelien's ones[1]: tcg_optimize took nearly the same amount of time as
executing the translated code.
Artyom
1. http://www.mail-archive.com/qemu-devel@nongnu.org/msg171104.html
--
Regards,
Artyom Tarasenko
linux/sparc and solaris/sparc under qemu blog:
http://tyom.blogspot.com/search/label/qemu
^ permalink raw reply [flat|nested] 21+ messages in thread