* [Qemu-devel] [PATCH 01/23] target-sparc: Tidy cpu_dump_state
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 02/23] target-sparc: Make CPU_LOG_INT useful by default Richard Henderson
` (22 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
We don't really need to be told that %g are general register, etc.
Issue a trailing newline to separate blocks.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/cpu.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index f7c004c..71cc9e8 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -792,7 +792,6 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
env->npc);
- cpu_fprintf(f, "General Registers:\n");
for (i = 0; i < 8; i++) {
if (i % REGS_PER_LINE == 0) {
@@ -803,7 +802,6 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "\n");
}
}
- cpu_fprintf(f, "\nCurrent Register Window:\n");
for (x = 0; x < 3; x++) {
for (i = 0; i < 8; i++) {
if (i % REGS_PER_LINE == 0) {
@@ -817,10 +815,10 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
}
}
}
- cpu_fprintf(f, "\nFloating Point Registers:\n");
+
for (i = 0; i < TARGET_DPREGS; i++) {
if ((i & 3) == 0) {
- cpu_fprintf(f, "%%f%02d:", i * 2);
+ cpu_fprintf(f, "%%f%02d: ", i * 2);
}
cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
if ((i & 3) == 3) {
@@ -850,6 +848,7 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
env->fsr, env->y);
#endif
+ cpu_fprintf(f, "\n");
}
static void sparc_cpu_initfn(Object *obj)
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 02/23] target-sparc: Make CPU_LOG_INT useful by default
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 01/23] target-sparc: Tidy cpu_dump_state Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 03/23] target-sparc: Tidy do_branch interfaces Richard Henderson
` (21 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
No need for ifdefs when the log mask does just as well.
No need to print pc/npc when we're dumping the whole cpu state.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/int32_helper.c | 7 ++-----
target-sparc/int64_helper.c | 8 ++------
2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/target-sparc/int32_helper.c b/target-sparc/int32_helper.c
index 5e33d50..9ac5aac 100644
--- a/target-sparc/int32_helper.c
+++ b/target-sparc/int32_helper.c
@@ -21,7 +21,7 @@
#include "trace.h"
#include "sysemu.h"
-//#define DEBUG_PCALL
+#define DEBUG_PCALL
#ifdef DEBUG_PCALL
static const char * const excp_names[0x80] = {
@@ -78,10 +78,7 @@ void do_interrupt(CPUSPARCState *env)
}
}
- qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
- count, name, intno,
- env->pc,
- env->npc, env->regwptr[6]);
+ qemu_log("%6d: %s (v=%02x)\n", count, name, intno);
log_cpu_state(env, 0);
#if 0
{
diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c
index 5e3eff7..5d0bc6c 100644
--- a/target-sparc/int64_helper.c
+++ b/target-sparc/int64_helper.c
@@ -21,7 +21,7 @@
#include "helper.h"
#include "trace.h"
-//#define DEBUG_PCALL
+#define DEBUG_PCALL
#ifdef DEBUG_PCALL
static const char * const excp_names[0x80] = {
@@ -84,11 +84,7 @@ void do_interrupt(CPUSPARCState *env)
}
}
- qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
- " SP=%016" PRIx64 "\n",
- count, name, intno,
- env->pc,
- env->npc, env->regwptr[6]);
+ qemu_log("%6d: %s (v=%04x)\n", count, name, intno);
log_cpu_state(env, 0);
#if 0
{
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 03/23] target-sparc: Tidy do_branch interfaces
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 01/23] target-sparc: Tidy cpu_dump_state Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 02/23] target-sparc: Make CPU_LOG_INT useful by default Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 04/23] target-sparc: Tidy flush_cond interface Richard Henderson
` (20 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
We always pass cpu_cond to the r_cond parameter. Use that global
register directly instead of passing it down.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 38 ++++++++++++++++++--------------------
1 file changed, 18 insertions(+), 20 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index e5ebedf..079a040 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1337,8 +1337,7 @@ static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
}
#endif
-static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
- TCGv r_cond)
+static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
{
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
target_ulong target = dc->pc + offset;
@@ -1368,10 +1367,10 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
tcg_gen_mov_tl(cpu_pc, cpu_npc);
}
} else {
- flush_cond(dc, r_cond);
- gen_cond(r_cond, cc, cond, dc);
+ flush_cond(dc, cpu_cond);
+ gen_cond(cpu_cond, cc, cond, dc);
if (a) {
- gen_branch_a(dc, target, dc->npc, r_cond);
+ gen_branch_a(dc, target, dc->npc, cpu_cond);
dc->is_br = 1;
} else {
dc->pc = dc->npc;
@@ -1387,8 +1386,7 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
}
}
-static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
- TCGv r_cond)
+static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
{
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
target_ulong target = dc->pc + offset;
@@ -1418,10 +1416,10 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
tcg_gen_mov_tl(cpu_pc, cpu_npc);
}
} else {
- flush_cond(dc, r_cond);
- gen_fcond(r_cond, cc, cond);
+ flush_cond(dc, cpu_cond);
+ gen_fcond(cpu_cond, cc, cond);
if (a) {
- gen_branch_a(dc, target, dc->npc, r_cond);
+ gen_branch_a(dc, target, dc->npc, cpu_cond);
dc->is_br = 1;
} else {
dc->pc = dc->npc;
@@ -1439,7 +1437,7 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
#ifdef TARGET_SPARC64
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
- TCGv r_cond, TCGv r_reg)
+ TCGv r_reg)
{
unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
target_ulong target = dc->pc + offset;
@@ -1447,10 +1445,10 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
if (unlikely(AM_CHECK(dc))) {
target &= 0xffffffffULL;
}
- flush_cond(dc, r_cond);
- gen_cond_reg(r_cond, cond, r_reg);
+ flush_cond(dc, cpu_cond);
+ gen_cond_reg(cpu_cond, cond, r_reg);
if (a) {
- gen_branch_a(dc, target, dc->npc, r_cond);
+ gen_branch_a(dc, target, dc->npc, cpu_cond);
dc->is_br = 1;
} else {
dc->pc = dc->npc;
@@ -2421,9 +2419,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
target <<= 2;
cc = GET_FIELD_SP(insn, 20, 21);
if (cc == 0)
- do_branch(dc, target, insn, 0, cpu_cond);
+ do_branch(dc, target, insn, 0);
else if (cc == 2)
- do_branch(dc, target, insn, 1, cpu_cond);
+ do_branch(dc, target, insn, 1);
else
goto illegal_insn;
goto jmp_insn;
@@ -2435,7 +2433,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
target = sign_extend(target, 16);
target <<= 2;
cpu_src1 = get_src1(insn, cpu_src1);
- do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
+ do_branch_reg(dc, target, insn, cpu_src1);
goto jmp_insn;
}
case 0x5: /* V9 FBPcc */
@@ -2446,7 +2444,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
target = GET_FIELD_SP(insn, 0, 18);
target = sign_extend(target, 19);
target <<= 2;
- do_fbranch(dc, target, insn, cc, cpu_cond);
+ do_fbranch(dc, target, insn, cc);
goto jmp_insn;
}
#else
@@ -2460,7 +2458,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
target = GET_FIELD(insn, 10, 31);
target = sign_extend(target, 22);
target <<= 2;
- do_branch(dc, target, insn, 0, cpu_cond);
+ do_branch(dc, target, insn, 0);
goto jmp_insn;
}
case 0x6: /* FBN+x */
@@ -2470,7 +2468,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
target = GET_FIELD(insn, 10, 31);
target = sign_extend(target, 22);
target <<= 2;
- do_fbranch(dc, target, insn, 0, cpu_cond);
+ do_fbranch(dc, target, insn, 0);
goto jmp_insn;
}
case 0x4: /* SETHI */
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 04/23] target-sparc: Tidy flush_cond interface
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (2 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 03/23] target-sparc: Tidy do_branch interfaces Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 05/23] target-sparc: Tidy gen_trap_ifnofpu interface Richard Henderson
` (19 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
We always pass cpu_cond to the cond parameter. Use that global
register directly instead of passing it down.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 079a040..5b2d5ea 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1118,10 +1118,10 @@ static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
/* call this function before using the condition register as it may
have been set for a jump */
-static inline void flush_cond(DisasContext *dc, TCGv cond)
+static inline void flush_cond(DisasContext *dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
+ gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
dc->npc = DYNAMIC_PC;
}
}
@@ -1367,7 +1367,7 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
tcg_gen_mov_tl(cpu_pc, cpu_npc);
}
} else {
- flush_cond(dc, cpu_cond);
+ flush_cond(dc);
gen_cond(cpu_cond, cc, cond, dc);
if (a) {
gen_branch_a(dc, target, dc->npc, cpu_cond);
@@ -1416,7 +1416,7 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
tcg_gen_mov_tl(cpu_pc, cpu_npc);
}
} else {
- flush_cond(dc, cpu_cond);
+ flush_cond(dc);
gen_fcond(cpu_cond, cc, cond);
if (a) {
gen_branch_a(dc, target, dc->npc, cpu_cond);
@@ -1445,7 +1445,7 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
if (unlikely(AM_CHECK(dc))) {
target &= 0xffffffffULL;
}
- flush_cond(dc, cpu_cond);
+ flush_cond(dc);
gen_cond_reg(cpu_cond, cond, r_reg);
if (a) {
gen_branch_a(dc, target, dc->npc, cpu_cond);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 05/23] target-sparc: Tidy gen_trap_ifnofpu interface
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (3 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 04/23] target-sparc: Tidy flush_cond interface Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 06/23] target-sparc: Tidy save_state interface Richard Henderson
` (18 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
We always pass cpu_cond to the cond parameter. Use that global
register directly instead of passing it down.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 46 ++++++++++++++++++++++++++++------------------
1 file changed, 28 insertions(+), 18 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 5b2d5ea..9787664 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1615,13 +1615,13 @@ static inline void gen_op_fpexception_im(int fsr_flags)
tcg_temp_free_i32(r_const);
}
-static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
+static int gen_trap_ifnofpu(DisasContext *dc)
{
#if !defined(CONFIG_USER_ONLY)
if (!dc->fpu_enabled) {
TCGv_i32 r_const;
- save_state(dc, r_cond);
+ save_state(dc, cpu_cond);
r_const = tcg_const_i32(TT_NFPU_INSN);
gen_helper_raise_exception(cpu_env, r_const);
tcg_temp_free_i32(r_const);
@@ -2439,8 +2439,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 0x5: /* V9 FBPcc */
{
int cc = GET_FIELD_SP(insn, 20, 21);
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
target = GET_FIELD_SP(insn, 0, 18);
target = sign_extend(target, 19);
target <<= 2;
@@ -2463,8 +2464,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
}
case 0x6: /* FBN+x */
{
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
target = GET_FIELD(insn, 10, 31);
target = sign_extend(target, 22);
target <<= 2;
@@ -2643,8 +2645,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 0xf: /* V9 membar */
break; /* no effect */
case 0x13: /* Graphics Status */
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
gen_movl_TN_reg(rd, cpu_gsr);
break;
case 0x16: /* Softint */
@@ -2861,8 +2864,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
break;
#endif
} else if (xop == 0x34) { /* FPU Operations */
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
gen_op_clear_ieee_excp_and_FTT();
rs1 = GET_FIELD(insn, 13, 17);
rs2 = GET_FIELD(insn, 27, 31);
@@ -3035,8 +3039,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
#ifdef TARGET_SPARC64
int cond;
#endif
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
gen_op_clear_ieee_excp_and_FTT();
rs1 = GET_FIELD(insn, 13, 17);
rs2 = GET_FIELD(insn, 27, 31);
@@ -3699,8 +3704,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
#endif
break;
case 0x13: /* Graphics Status */
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
break;
case 0x14: /* Softint set */
@@ -4105,8 +4111,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
int opf = GET_FIELD_SP(insn, 5, 13);
rs1 = GET_FIELD(insn, 13, 17);
rs2 = GET_FIELD(insn, 27, 31);
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
switch (opf) {
case 0x000: /* VIS I edge8cc */
@@ -4873,7 +4880,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 0x2d: /* V9 prefetch, no effect */
goto skip_move;
case 0x30: /* V9 ldfa */
- if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
save_state(dc, cpu_cond);
@@ -4881,7 +4888,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
gen_update_fprs_dirty(rd);
goto skip_move;
case 0x33: /* V9 lddfa */
- if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
save_state(dc, cpu_cond);
@@ -4892,7 +4899,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
goto skip_move;
case 0x32: /* V9 ldqfa */
CHECK_FPU_FEATURE(dc, FLOAT128);
- if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
save_state(dc, cpu_cond);
@@ -4908,8 +4915,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
skip_move: ;
#endif
} else if (xop >= 0x20 && xop < 0x24) {
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
save_state(dc, cpu_cond);
switch (xop) {
case 0x20: /* ldf, load fpreg */
@@ -5056,8 +5064,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
goto illegal_insn;
}
} else if (xop > 0x23 && xop < 0x28) {
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
save_state(dc, cpu_cond);
switch (xop) {
case 0x24: /* stf, store fpreg */
@@ -5100,8 +5109,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
#else
if (!supervisor(dc))
goto priv_insn;
- if (gen_trap_ifnofpu(dc, cpu_cond))
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
+ }
goto nfq_insn;
#endif
#endif
@@ -5118,7 +5128,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
switch (xop) {
#ifdef TARGET_SPARC64
case 0x34: /* V9 stfa */
- if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
gen_stf_asi(cpu_addr, insn, 4, rd);
@@ -5128,7 +5138,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
TCGv_i32 r_const;
CHECK_FPU_FEATURE(dc, FLOAT128);
- if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
r_const = tcg_const_i32(7);
@@ -5138,7 +5148,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
}
break;
case 0x37: /* V9 stdfa */
- if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 06/23] target-sparc: Tidy save_state interface
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (4 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 05/23] target-sparc: Tidy gen_trap_ifnofpu interface Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 07/23] target-sparc: Tidy gen_mov_pc_npc interface Richard Henderson
` (17 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Use the cpu_cond global register directly instead of passing it down.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 98 ++++++++++++++++++++++++------------------------
1 file changed, 49 insertions(+), 49 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 9787664..eb95260 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1136,7 +1136,7 @@ static inline void save_npc(DisasContext *dc, TCGv cond)
}
}
-static inline void save_state(DisasContext *dc, TCGv cond)
+static inline void save_state(DisasContext *dc)
{
tcg_gen_movi_tl(cpu_pc, dc->pc);
/* flush pending conditional evaluations before exposing cpu state */
@@ -1144,7 +1144,7 @@ static inline void save_state(DisasContext *dc, TCGv cond)
dc->cc_op = CC_OP_FLAGS;
gen_helper_compute_psr(cpu_env);
}
- save_npc(dc, cond);
+ save_npc(dc, cpu_cond);
}
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
@@ -1621,7 +1621,7 @@ static int gen_trap_ifnofpu(DisasContext *dc)
if (!dc->fpu_enabled) {
TCGv_i32 r_const;
- save_state(dc, cpu_cond);
+ save_state(dc);
r_const = tcg_const_i32(TT_NFPU_INSN);
gen_helper_raise_exception(cpu_env, r_const);
tcg_temp_free_i32(r_const);
@@ -2529,7 +2529,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
cond = GET_FIELD(insn, 3, 6);
if (cond == 0x8) { /* Trap Always */
- save_state(dc, cpu_cond);
+ save_state(dc);
if ((dc->def->features & CPU_FEATURE_HYPV) &&
supervisor(dc))
tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
@@ -2546,7 +2546,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
/* V9 icc/xcc */
int cc = GET_FIELD_SP(insn, 11, 12);
- save_state(dc, cpu_cond);
+ save_state(dc);
if (cc == 0)
gen_cond(r_cond, 0, cond, dc);
else if (cc == 2)
@@ -2554,7 +2554,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
else
goto illegal_insn;
#else
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_cond(r_cond, 0, cond, dc);
#endif
l1 = gen_new_label();
@@ -2854,7 +2854,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
break;
} else if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_helper_flushw(cpu_env);
#else
if (!supervisor(dc))
@@ -2871,7 +2871,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
rs1 = GET_FIELD(insn, 13, 17);
rs2 = GET_FIELD(insn, 27, 31);
xop = GET_FIELD(insn, 18, 26);
- save_state(dc, cpu_cond);
+ save_state(dc);
switch (xop) {
case 0x1: /* fmovs */
cpu_src1_32 = gen_load_fpr_F(dc, rs2);
@@ -3046,7 +3046,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
rs1 = GET_FIELD(insn, 13, 17);
rs2 = GET_FIELD(insn, 27, 31);
xop = GET_FIELD(insn, 18, 26);
- save_state(dc, cpu_cond);
+ save_state(dc);
#ifdef TARGET_SPARC64
if ((xop & 0x11f) == 0x005) { // V9 fmovsr
int l1;
@@ -3607,14 +3607,14 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
dc->cc_op = CC_OP_TSUB;
break;
case 0x22: /* taddcctv */
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
gen_movl_TN_reg(rd, cpu_dst);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADDTV);
dc->cc_op = CC_OP_TADDTV;
break;
case 0x23: /* tsubcctv */
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
gen_movl_TN_reg(rd, cpu_dst);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUBTV);
@@ -3691,7 +3691,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 0x6: /* V9 wrfprs */
tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_op_next_insn();
tcg_gen_exit_tb(0);
dc->is_br = 1;
@@ -3818,7 +3818,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
gen_helper_wrpsr(cpu_env, cpu_dst);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
dc->cc_op = CC_OP_FLAGS;
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_op_next_insn();
tcg_gen_exit_tb(0);
dc->is_br = 1;
@@ -3898,7 +3898,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
TCGv r_tmp = tcg_temp_local_new();
tcg_gen_mov_tl(r_tmp, cpu_tmp0);
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_helper_wrpstate(cpu_env, r_tmp);
tcg_temp_free(r_tmp);
dc->npc = DYNAMIC_PC;
@@ -3909,7 +3909,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
TCGv r_tmp = tcg_temp_local_new();
tcg_gen_mov_tl(r_tmp, cpu_tmp0);
- save_state(dc, cpu_cond);
+ save_state(dc);
tcg_gen_trunc_tl_i32(cpu_tmp32, r_tmp);
tcg_temp_free(r_tmp);
tcg_gen_st_i32(cpu_tmp32, cpu_env,
@@ -3991,7 +3991,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
switch (rd) {
case 0: // hpstate
// XXX gen_op_wrhpstate();
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_op_next_insn();
tcg_gen_exit_tb(0);
dc->is_br = 1;
@@ -4559,7 +4559,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
} else if (xop == 0x39) { /* V9 return */
TCGv_i32 r_const;
- save_state(dc, cpu_cond);
+ save_state(dc);
cpu_src1 = get_src1(insn, cpu_src1);
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 19, 31);
@@ -4635,12 +4635,12 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
/* nop */
break;
case 0x3c: /* save */
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_helper_save(cpu_env);
gen_movl_TN_reg(rd, cpu_dst);
break;
case 0x3d: /* restore */
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_helper_restore(cpu_env);
gen_movl_TN_reg(rd, cpu_dst);
break;
@@ -4723,7 +4723,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
else {
TCGv_i32 r_const;
- save_state(dc, cpu_cond);
+ save_state(dc);
r_const = tcg_const_i32(7);
/* XXX remove alignment check */
gen_helper_check_align(cpu_env, cpu_addr, r_const);
@@ -4774,7 +4774,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
break;
case 0x11: /* lduba, load unsigned byte alternate */
@@ -4784,7 +4784,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
break;
case 0x12: /* lduha, load unsigned halfword alternate */
@@ -4794,7 +4794,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
break;
case 0x13: /* ldda, load double word alternate */
@@ -4806,7 +4806,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
#endif
if (rd & 1)
goto illegal_insn;
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
goto skip_move;
case 0x19: /* ldsba, load signed byte alternate */
@@ -4816,7 +4816,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
break;
case 0x1a: /* ldsha, load signed halfword alternate */
@@ -4826,7 +4826,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
break;
case 0x1d: /* ldstuba -- XXX: should be atomically */
@@ -4836,7 +4836,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ldstub_asi(cpu_val, cpu_addr, insn);
break;
case 0x1f: /* swapa, swap reg with alt. memory. Also
@@ -4848,7 +4848,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_movl_reg_TN(rd, cpu_val);
gen_swap_asi(cpu_val, cpu_addr, insn);
break;
@@ -4870,11 +4870,11 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
break;
case 0x18: /* V9 ldswa */
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
break;
case 0x1b: /* V9 ldxa */
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
break;
case 0x2d: /* V9 prefetch, no effect */
@@ -4883,7 +4883,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ldf_asi(cpu_addr, insn, 4, rd);
gen_update_fprs_dirty(rd);
goto skip_move;
@@ -4891,7 +4891,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
gen_update_fprs_dirty(DFPREG(rd));
goto skip_move;
@@ -4902,7 +4902,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
gen_update_fprs_dirty(QFPREG(rd));
goto skip_move;
@@ -4918,7 +4918,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
- save_state(dc, cpu_cond);
+ save_state(dc);
switch (xop) {
case 0x20: /* ldf, load fpreg */
gen_address_mask(dc, cpu_addr);
@@ -4989,7 +4989,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
else {
TCGv_i32 r_const;
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_address_mask(dc, cpu_addr);
r_const = tcg_const_i32(7);
/* XXX remove alignment check */
@@ -5008,7 +5008,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_st_asi(cpu_val, cpu_addr, insn, 4);
dc->npc = DYNAMIC_PC;
break;
@@ -5019,7 +5019,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_st_asi(cpu_val, cpu_addr, insn, 1);
dc->npc = DYNAMIC_PC;
break;
@@ -5030,7 +5030,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
#endif
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_st_asi(cpu_val, cpu_addr, insn, 2);
dc->npc = DYNAMIC_PC;
break;
@@ -5044,7 +5044,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (rd & 1)
goto illegal_insn;
else {
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_stda_asi(cpu_val, cpu_addr, insn, rd);
}
break;
@@ -5055,7 +5055,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
break;
case 0x1e: /* V9 stxa */
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_st_asi(cpu_val, cpu_addr, insn, 8);
dc->npc = DYNAMIC_PC;
break;
@@ -5067,7 +5067,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
- save_state(dc, cpu_cond);
+ save_state(dc);
switch (xop) {
case 0x24: /* stf, store fpreg */
gen_address_mask(dc, cpu_addr);
@@ -5124,7 +5124,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
goto illegal_insn;
}
} else if (xop > 0x33 && xop < 0x3f) {
- save_state(dc, cpu_cond);
+ save_state(dc);
switch (xop) {
#ifdef TARGET_SPARC64
case 0x34: /* V9 stfa */
@@ -5194,7 +5194,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
{
TCGv_i32 r_const;
- save_state(dc, cpu_cond);
+ save_state(dc);
r_const = tcg_const_i32(TT_ILL_INSN);
gen_helper_raise_exception(cpu_env, r_const);
tcg_temp_free_i32(r_const);
@@ -5205,7 +5205,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
{
TCGv_i32 r_const;
- save_state(dc, cpu_cond);
+ save_state(dc);
r_const = tcg_const_i32(TT_UNIMP_FLUSH);
gen_helper_raise_exception(cpu_env, r_const);
tcg_temp_free_i32(r_const);
@@ -5217,7 +5217,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
{
TCGv_i32 r_const;
- save_state(dc, cpu_cond);
+ save_state(dc);
r_const = tcg_const_i32(TT_PRIV_INSN);
gen_helper_raise_exception(cpu_env, r_const);
tcg_temp_free_i32(r_const);
@@ -5226,13 +5226,13 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
goto egress;
#endif
nfpu_insn:
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
dc->is_br = 1;
goto egress;
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
nfq_insn:
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
dc->is_br = 1;
goto egress;
@@ -5242,7 +5242,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
{
TCGv r_const;
- save_state(dc, cpu_cond);
+ save_state(dc);
r_const = tcg_const_i32(TT_NCP_INSN);
gen_helper_raise_exception(cpu_env, r_const);
tcg_temp_free(r_const);
@@ -5308,7 +5308,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == dc->pc) {
if (dc->pc != pc_start)
- save_state(dc, cpu_cond);
+ save_state(dc);
gen_helper_debug(cpu_env);
tcg_gen_exit_tb(0);
dc->is_br = 1;
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 07/23] target-sparc: Tidy gen_mov_pc_npc interface
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (5 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 06/23] target-sparc: Tidy save_state interface Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 08/23] target-sparc: Tidy save_npc interface Richard Henderson
` (16 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Use the cpu_cond global register directly instead of passing it down.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index eb95260..d9e1b01 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1147,10 +1147,10 @@ static inline void save_state(DisasContext *dc)
save_npc(dc, cpu_cond);
}
-static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
+static inline void gen_mov_pc_npc(DisasContext *dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
+ gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
tcg_gen_mov_tl(cpu_pc, cpu_npc);
dc->pc = DYNAMIC_PC;
} else if (dc->npc == DYNAMIC_PC) {
@@ -2499,7 +2499,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
gen_movl_TN_reg(15, r_const);
tcg_temp_free(r_const);
target += dc->pc;
- gen_mov_pc_npc(dc, cpu_cond);
+ gen_mov_pc_npc(dc);
#ifdef TARGET_SPARC64
if (unlikely(AM_CHECK(dc))) {
target &= 0xffffffffULL;
@@ -4573,7 +4573,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
tcg_gen_mov_tl(cpu_dst, cpu_src1);
}
gen_helper_restore(cpu_env);
- gen_mov_pc_npc(dc, cpu_cond);
+ gen_mov_pc_npc(dc);
r_const = tcg_const_i32(3);
gen_helper_check_align(cpu_env, cpu_dst, r_const);
tcg_temp_free_i32(r_const);
@@ -4603,7 +4603,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
r_pc = tcg_const_tl(dc->pc);
gen_movl_TN_reg(rd, r_pc);
tcg_temp_free(r_pc);
- gen_mov_pc_npc(dc, cpu_cond);
+ gen_mov_pc_npc(dc);
r_const = tcg_const_i32(3);
gen_helper_check_align(cpu_env, cpu_dst, r_const);
tcg_temp_free_i32(r_const);
@@ -4619,7 +4619,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
if (!supervisor(dc))
goto priv_insn;
- gen_mov_pc_npc(dc, cpu_cond);
+ gen_mov_pc_npc(dc);
r_const = tcg_const_i32(3);
gen_helper_check_align(cpu_env, cpu_dst, r_const);
tcg_temp_free_i32(r_const);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 08/23] target-sparc: Tidy save_npc interface
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (6 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 07/23] target-sparc: Tidy gen_mov_pc_npc interface Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 09/23] target-sparc: Tidy gen_generic_branch interface Richard Henderson
` (15 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Use the cpu_cond global register directly instead of passing it down.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index d9e1b01..4cc7887 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1126,10 +1126,10 @@ static inline void flush_cond(DisasContext *dc)
}
}
-static inline void save_npc(DisasContext *dc, TCGv cond)
+static inline void save_npc(DisasContext *dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
+ gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
dc->npc = DYNAMIC_PC;
} else if (dc->npc != DYNAMIC_PC) {
tcg_gen_movi_tl(cpu_npc, dc->npc);
@@ -1144,7 +1144,7 @@ static inline void save_state(DisasContext *dc)
dc->cc_op = CC_OP_FLAGS;
gen_helper_compute_psr(cpu_env);
}
- save_npc(dc, cpu_cond);
+ save_npc(dc);
}
static inline void gen_mov_pc_npc(DisasContext *dc)
@@ -5372,7 +5372,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
} else {
if (dc->pc != DYNAMIC_PC)
tcg_gen_movi_tl(cpu_pc, dc->pc);
- save_npc(dc, cpu_cond);
+ save_npc(dc);
tcg_gen_exit_tb(0);
}
}
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 09/23] target-sparc: Tidy gen_generic_branch interface
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (7 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 08/23] target-sparc: Tidy save_npc interface Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 10/23] target-sparc: Introduce DisasCompare and functions to generate it Richard Henderson
` (14 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
The arguments passed are always the same.
Pass down just DisasContext instead.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 4cc7887..d759da2 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1098,21 +1098,20 @@ static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
}
-static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
- TCGv r_cond)
+static inline void gen_generic_branch(DisasContext *dc)
{
int l1, l2;
l1 = gen_new_label();
l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cond, 0, l1);
- tcg_gen_movi_tl(cpu_npc, npc1);
+ tcg_gen_movi_tl(cpu_npc, dc->jump_pc[0]);
tcg_gen_br(l2);
gen_set_label(l1);
- tcg_gen_movi_tl(cpu_npc, npc2);
+ tcg_gen_movi_tl(cpu_npc, dc->jump_pc[1]);
gen_set_label(l2);
}
@@ -1121,7 +1120,7 @@ static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
static inline void flush_cond(DisasContext *dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
+ gen_generic_branch(dc);
dc->npc = DYNAMIC_PC;
}
}
@@ -1129,7 +1128,7 @@ static inline void flush_cond(DisasContext *dc)
static inline void save_npc(DisasContext *dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
+ gen_generic_branch(dc);
dc->npc = DYNAMIC_PC;
} else if (dc->npc != DYNAMIC_PC) {
tcg_gen_movi_tl(cpu_npc, dc->npc);
@@ -1150,7 +1149,7 @@ static inline void save_state(DisasContext *dc)
static inline void gen_mov_pc_npc(DisasContext *dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
+ gen_generic_branch(dc);
tcg_gen_mov_tl(cpu_pc, cpu_npc);
dc->pc = DYNAMIC_PC;
} else if (dc->npc == DYNAMIC_PC) {
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 10/23] target-sparc: Introduce DisasCompare and functions to generate it
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (8 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 09/23] target-sparc: Tidy gen_generic_branch interface Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 11/23] target-sparc: Use DisasCompare in Tcc Richard Henderson
` (13 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
For the moment gen_cond et al retain their existing interface,
using setcond to turn a (potential) comparison back into a boolean.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 92 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 83 insertions(+), 9 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index d759da2..d61a9a0 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -86,6 +86,13 @@ typedef struct DisasContext {
int n_t32;
} DisasContext;
+typedef struct {
+ TCGCond cond;
+ bool is_bool;
+ bool g1, g2;
+ TCGv c1, c2;
+} DisasCompare;
+
// This function uses non-native bit order
#define GET_FIELD(X, FROM, TO) \
((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
@@ -1166,10 +1173,28 @@ static inline void gen_op_next_insn(void)
tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
}
-static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
- DisasContext *dc)
+static void free_compare(DisasCompare *cmp)
+{
+ if (!cmp->g1) {
+ tcg_temp_free(cmp->c1);
+ }
+ if (!cmp->g2) {
+ tcg_temp_free(cmp->c2);
+ }
+}
+
+static void gen_compare(DisasCompare *cmp, unsigned int cc, unsigned int cond,
+ DisasContext *dc)
{
TCGv_i32 r_src;
+ TCGv r_dst;
+
+ /* For now we still generate a straight boolean result. */
+ cmp->cond = TCG_COND_NE;
+ cmp->is_bool = true;
+ cmp->g1 = cmp->g2 = false;
+ cmp->c1 = r_dst = tcg_temp_new();
+ cmp->c2 = tcg_const_tl(0);
#ifdef TARGET_SPARC64
if (cc)
@@ -1239,9 +1264,17 @@ static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
}
}
-static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
+static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
{
unsigned int offset;
+ TCGv r_dst;
+
+ /* For now we still generate a straight boolean result. */
+ cmp->cond = TCG_COND_NE;
+ cmp->is_bool = true;
+ cmp->g1 = cmp->g2 = false;
+ cmp->c1 = r_dst = tcg_temp_new();
+ cmp->c2 = tcg_const_tl(0);
switch (cc) {
default:
@@ -1311,6 +1344,37 @@ static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
}
}
+static void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
+ DisasContext *dc)
+{
+ DisasCompare cmp;
+ gen_compare(&cmp, cc, cond, dc);
+
+ /* The interface is to return a boolean in r_dst. */
+ if (cmp.is_bool) {
+ tcg_gen_mov_tl(r_dst, cmp.c1);
+ } else {
+ tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
+ }
+
+ free_compare(&cmp);
+}
+
+static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
+{
+ DisasCompare cmp;
+ gen_fcompare(&cmp, cc, cond);
+
+ /* The interface is to return a boolean in r_dst. */
+ if (cmp.is_bool) {
+ tcg_gen_mov_tl(r_dst, cmp.c1);
+ } else {
+ tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
+ }
+
+ free_compare(&cmp);
+}
+
#ifdef TARGET_SPARC64
// Inverted logic
static const int gen_tcg_cond_reg[8] = {
@@ -1324,15 +1388,25 @@ static const int gen_tcg_cond_reg[8] = {
TCG_COND_LT,
};
+static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
+{
+ cmp->cond = tcg_invert_cond(gen_tcg_cond_reg[cond]);
+ cmp->is_bool = false;
+ cmp->g1 = true;
+ cmp->g2 = false;
+ cmp->c1 = r_src;
+ cmp->c2 = tcg_const_tl(0);
+}
+
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
{
- int l1;
+ DisasCompare cmp;
+ gen_compare_reg(&cmp, cond, r_src);
- l1 = gen_new_label();
- tcg_gen_movi_tl(r_dst, 0);
- tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
- tcg_gen_movi_tl(r_dst, 1);
- gen_set_label(l1);
+ /* The interface is to return a boolean in r_dst. */
+ tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
+
+ free_compare(&cmp);
}
#endif
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 11/23] target-sparc: Use DisasCompare in Tcc
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (9 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 10/23] target-sparc: Introduce DisasCompare and functions to generate it Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 12/23] target-sparc: Use DisasCompare and movcond in FMOVR, FMOVCC Richard Henderson
` (12 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index d61a9a0..fa9a057 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2613,25 +2613,28 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
gen_helper_raise_exception(cpu_env, cpu_tmp32);
} else if (cond != 0) {
- TCGv r_cond = tcg_temp_new();
+ DisasCompare cmp;
int l1;
#ifdef TARGET_SPARC64
/* V9 icc/xcc */
int cc = GET_FIELD_SP(insn, 11, 12);
save_state(dc);
- if (cc == 0)
- gen_cond(r_cond, 0, cond, dc);
- else if (cc == 2)
- gen_cond(r_cond, 1, cond, dc);
- else
+ if (cc == 0) {
+ gen_compare(&cmp, 0, cond, dc);
+ } else if (cc == 2) {
+ gen_compare(&cmp, 1, cond, dc);
+ } else {
goto illegal_insn;
+ }
#else
save_state(dc);
- gen_cond(r_cond, 0, cond, dc);
+ gen_compare(&cmp, 0, cond, dc);
#endif
l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
+ tcg_gen_brcond_tl(tcg_invert_cond(cmp.cond),
+ cmp.c1, cmp.c2, l1);
+ free_compare(&cmp);
if ((dc->def->features & CPU_FEATURE_HYPV) &&
supervisor(dc))
@@ -2643,7 +2646,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
gen_helper_raise_exception(cpu_env, cpu_tmp32);
gen_set_label(l1);
- tcg_temp_free(r_cond);
}
gen_op_next_insn();
tcg_gen_exit_tb(0);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 12/23] target-sparc: Use DisasCompare and movcond in FMOVR, FMOVCC
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (10 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 11/23] target-sparc: Use DisasCompare in Tcc Richard Henderson
@ 2012-10-05 23:54 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 13/23] target-sparc: Use DisasCompare and movcond in MOVCC Richard Henderson
` (11 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 203 ++++++++++++++++++++---------------------------
1 file changed, 86 insertions(+), 117 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index fa9a057..a7cd677 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2281,6 +2281,57 @@ static inline TCGv get_src2(unsigned int insn, TCGv def)
}
#ifdef TARGET_SPARC64
+static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
+{
+ TCGv_i32 c32, zero, dst, s1, s2;
+
+ /* We have two choices here: extend the 32 bit data and use movcond_i64,
+ or fold the comparison down to 32 bits and use movcond_i32. Choose
+ the later. */
+ c32 = tcg_temp_new_i32();
+ if (cmp->is_bool) {
+ tcg_gen_trunc_i64_i32(c32, cmp->c1);
+ } else {
+ TCGv_i64 c64 = tcg_temp_new_i64();
+ tcg_gen_setcond_i64(cmp->cond, c64, cmp->c1, cmp->c2);
+ tcg_gen_trunc_i64_i32(c32, c64);
+ tcg_temp_free_i64(c64);
+ }
+
+ s1 = gen_load_fpr_F(dc, rs);
+ s2 = gen_load_fpr_F(dc, rd);
+ dst = gen_dest_fpr_F();
+ zero = tcg_const_i32(0);
+
+ tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
+
+ tcg_temp_free_i32(c32);
+ tcg_temp_free_i32(zero);
+ gen_store_fpr_F(dc, rd, dst);
+}
+
+static void gen_fmovd(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
+{
+ TCGv_i64 dst = gen_dest_fpr_D();
+ tcg_gen_movcond_i64(cmp->cond, dst, cmp->c1, cmp->c2,
+ gen_load_fpr_D(dc, rs),
+ gen_load_fpr_D(dc, rd));
+ gen_store_fpr_D(dc, rd, dst);
+}
+
+static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
+{
+ int qd = QFPREG(rd);
+ int qs = QFPREG(rs);
+
+ tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2], cmp->c1, cmp->c2,
+ cpu_fpr[qs / 2], cpu_fpr[qd / 2]);
+ tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, cmp->c2,
+ cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
+
+ gen_update_fprs_dirty(qd);
+}
+
static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env)
{
TCGv_i32 r_tl = tcg_temp_new_i32();
@@ -3163,168 +3214,86 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
#endif
switch (xop) {
#ifdef TARGET_SPARC64
-#define FMOVSCC(fcc) \
- { \
- TCGv r_cond; \
- int l1; \
- \
- l1 = gen_new_label(); \
- r_cond = tcg_temp_new(); \
- cond = GET_FIELD_SP(insn, 14, 17); \
- gen_fcond(r_cond, fcc, cond); \
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
- 0, l1); \
- cpu_src1_32 = gen_load_fpr_F(dc, rs2); \
- gen_store_fpr_F(dc, rd, cpu_src1_32); \
- gen_set_label(l1); \
- tcg_temp_free(r_cond); \
- }
-#define FMOVDCC(fcc) \
- { \
- TCGv r_cond; \
- int l1; \
- \
- l1 = gen_new_label(); \
- r_cond = tcg_temp_new(); \
- cond = GET_FIELD_SP(insn, 14, 17); \
- gen_fcond(r_cond, fcc, cond); \
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
- 0, l1); \
- cpu_src1_64 = gen_load_fpr_D(dc, rs2); \
- gen_store_fpr_D(dc, rd, cpu_src1_64); \
- gen_set_label(l1); \
- tcg_temp_free(r_cond); \
- }
-#define FMOVQCC(fcc) \
- { \
- TCGv r_cond; \
- int l1; \
- \
- l1 = gen_new_label(); \
- r_cond = tcg_temp_new(); \
+#define FMOVCC(fcc, sz) \
+ do { \
+ DisasCompare cmp; \
cond = GET_FIELD_SP(insn, 14, 17); \
- gen_fcond(r_cond, fcc, cond); \
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
- 0, l1); \
- gen_move_Q(rd, rs2); \
- gen_set_label(l1); \
- tcg_temp_free(r_cond); \
- }
+ gen_fcompare(&cmp, fcc, cond); \
+ gen_fmov##sz(dc, &cmp, rd, rs2); \
+ free_compare(&cmp); \
+ } while (0)
+
case 0x001: /* V9 fmovscc %fcc0 */
- FMOVSCC(0);
+ FMOVCC(0, s);
break;
case 0x002: /* V9 fmovdcc %fcc0 */
- FMOVDCC(0);
+ FMOVCC(0, d);
break;
case 0x003: /* V9 fmovqcc %fcc0 */
CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVQCC(0);
+ FMOVCC(0, q);
break;
case 0x041: /* V9 fmovscc %fcc1 */
- FMOVSCC(1);
+ FMOVCC(1, s);
break;
case 0x042: /* V9 fmovdcc %fcc1 */
- FMOVDCC(1);
+ FMOVCC(1, d);
break;
case 0x043: /* V9 fmovqcc %fcc1 */
CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVQCC(1);
+ FMOVCC(1, q);
break;
case 0x081: /* V9 fmovscc %fcc2 */
- FMOVSCC(2);
+ FMOVCC(2, s);
break;
case 0x082: /* V9 fmovdcc %fcc2 */
- FMOVDCC(2);
+ FMOVCC(2, d);
break;
case 0x083: /* V9 fmovqcc %fcc2 */
CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVQCC(2);
+ FMOVCC(2, q);
break;
case 0x0c1: /* V9 fmovscc %fcc3 */
- FMOVSCC(3);
+ FMOVCC(3, s);
break;
case 0x0c2: /* V9 fmovdcc %fcc3 */
- FMOVDCC(3);
+ FMOVCC(3, d);
break;
case 0x0c3: /* V9 fmovqcc %fcc3 */
CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVQCC(3);
+ FMOVCC(3, q);
break;
-#undef FMOVSCC
-#undef FMOVDCC
-#undef FMOVQCC
-#define FMOVSCC(icc) \
- { \
- TCGv r_cond; \
- int l1; \
- \
- l1 = gen_new_label(); \
- r_cond = tcg_temp_new(); \
- cond = GET_FIELD_SP(insn, 14, 17); \
- gen_cond(r_cond, icc, cond, dc); \
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
- 0, l1); \
- cpu_src1_32 = gen_load_fpr_F(dc, rs2); \
- gen_store_fpr_F(dc, rd, cpu_src1_32); \
- gen_set_label(l1); \
- tcg_temp_free(r_cond); \
- }
-#define FMOVDCC(icc) \
- { \
- TCGv r_cond; \
- int l1; \
- \
- l1 = gen_new_label(); \
- r_cond = tcg_temp_new(); \
+#undef FMOVCC
+#define FMOVCC(xcc, sz) \
+ do { \
+ DisasCompare cmp; \
cond = GET_FIELD_SP(insn, 14, 17); \
- gen_cond(r_cond, icc, cond, dc); \
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
- 0, l1); \
- cpu_src1_64 = gen_load_fpr_D(dc, rs2); \
- gen_store_fpr_D(dc, rd, cpu_src1_64); \
- gen_update_fprs_dirty(DFPREG(rd)); \
- gen_set_label(l1); \
- tcg_temp_free(r_cond); \
- }
-#define FMOVQCC(icc) \
- { \
- TCGv r_cond; \
- int l1; \
- \
- l1 = gen_new_label(); \
- r_cond = tcg_temp_new(); \
- cond = GET_FIELD_SP(insn, 14, 17); \
- gen_cond(r_cond, icc, cond, dc); \
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
- 0, l1); \
- gen_move_Q(rd, rs2); \
- gen_set_label(l1); \
- tcg_temp_free(r_cond); \
- }
+ gen_compare(&cmp, xcc, cond, dc); \
+ gen_fmov##sz(dc, &cmp, rd, rs2); \
+ free_compare(&cmp); \
+ } while (0)
case 0x101: /* V9 fmovscc %icc */
- FMOVSCC(0);
+ FMOVCC(0, s);
break;
case 0x102: /* V9 fmovdcc %icc */
- FMOVDCC(0);
+ FMOVCC(0, d);
break;
case 0x103: /* V9 fmovqcc %icc */
CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVQCC(0);
+ FMOVCC(0, q);
break;
case 0x181: /* V9 fmovscc %xcc */
- FMOVSCC(1);
+ FMOVCC(1, s);
break;
case 0x182: /* V9 fmovdcc %xcc */
- FMOVDCC(1);
+ FMOVCC(1, d);
break;
case 0x183: /* V9 fmovqcc %xcc */
CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVQCC(1);
+ FMOVCC(1, q);
break;
-#undef FMOVSCC
-#undef FMOVDCC
-#undef FMOVQCC
+#undef FMOVCC
#endif
case 0x51: /* fcmps, V9 %fcc */
cpu_src1_32 = gen_load_fpr_F(dc, rs1);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 13/23] target-sparc: Use DisasCompare and movcond in MOVCC
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (11 preceding siblings ...)
2012-10-05 23:54 ` [Qemu-devel] [PATCH 12/23] target-sparc: Use DisasCompare and movcond in FMOVR, FMOVCC Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 14/23] target-sparc: Use DisasCompare and movcond in MOVR Richard Henderson
` (10 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 44 ++++++++++++++++++++------------------------
1 file changed, 20 insertions(+), 24 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index a7cd677..6c9be29 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4075,38 +4075,34 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
{
int cc = GET_FIELD_SP(insn, 11, 12);
int cond = GET_FIELD_SP(insn, 14, 17);
- TCGv r_cond;
- int l1;
+ DisasCompare cmp;
- r_cond = tcg_temp_new();
if (insn & (1 << 18)) {
- if (cc == 0)
- gen_cond(r_cond, 0, cond, dc);
- else if (cc == 2)
- gen_cond(r_cond, 1, cond, dc);
- else
+ if (cc == 0) {
+ gen_compare(&cmp, 0, cond, dc);
+ } else if (cc == 2) {
+ gen_compare(&cmp, 1, cond, dc);
+ } else {
goto illegal_insn;
+ }
} else {
- gen_fcond(r_cond, cc, cond);
+ gen_fcompare(&cmp, cc, cond);
}
- l1 = gen_new_label();
-
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
- if (IS_IMM) { /* immediate */
- TCGv r_const;
-
+ /* The get_src2 above loaded the normal 13-bit
+ immediate field, not the 11-bit field we have
+ in movcc. But it did handle the reg case. */
+ if (IS_IMM) {
simm = GET_FIELD_SPs(insn, 0, 10);
- r_const = tcg_const_tl(simm);
- gen_movl_TN_reg(rd, r_const);
- tcg_temp_free(r_const);
- } else {
- rs2 = GET_FIELD_SP(insn, 0, 4);
- gen_movl_reg_TN(rs2, cpu_tmp0);
- gen_movl_TN_reg(rd, cpu_tmp0);
+ tcg_gen_movi_tl(cpu_src2, simm);
}
- gen_set_label(l1);
- tcg_temp_free(r_cond);
+
+ gen_movl_reg_TN(rd, cpu_dst);
+ tcg_gen_movcond_tl(cmp.cond, cpu_dst,
+ cmp.c1, cmp.c2,
+ cpu_src2, cpu_dst);
+ free_compare(&cmp);
+ gen_movl_TN_reg(rd, cpu_dst);
break;
}
case 0x2d: /* V9 sdivx */
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 14/23] target-sparc: Use DisasCompare and movcond in MOVR
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (12 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 13/23] target-sparc: Use DisasCompare and movcond in MOVCC Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 15/23] target-sparc: Use movcond in gen_generic_branch Richard Henderson
` (9 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 31 ++++++++++++++-----------------
1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 6c9be29..9aef8e5 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4118,27 +4118,24 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 0x2f: /* V9 movr */
{
int cond = GET_FIELD_SP(insn, 10, 12);
- int l1;
-
- cpu_src1 = get_src1(insn, cpu_src1);
-
- l1 = gen_new_label();
+ DisasCompare cmp;
- tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
- cpu_src1, 0, l1);
- if (IS_IMM) { /* immediate */
- TCGv r_const;
+ gen_compare_reg(&cmp, cond, cpu_src1);
+ /* The get_src2 above loaded the normal 13-bit
+ immediate field, not the 10-bit field we have
+ in movr. But it did handle the reg case. */
+ if (IS_IMM) {
simm = GET_FIELD_SPs(insn, 0, 9);
- r_const = tcg_const_tl(simm);
- gen_movl_TN_reg(rd, r_const);
- tcg_temp_free(r_const);
- } else {
- rs2 = GET_FIELD_SP(insn, 0, 4);
- gen_movl_reg_TN(rs2, cpu_tmp0);
- gen_movl_TN_reg(rd, cpu_tmp0);
+ tcg_gen_movi_tl(cpu_src2, simm);
}
- gen_set_label(l1);
+
+ gen_movl_reg_TN(rd, cpu_dst);
+ tcg_gen_movcond_tl(cmp.cond, cpu_dst,
+ cmp.c1, cmp.c2,
+ cpu_src2, cpu_dst);
+ free_compare(&cmp);
+ gen_movl_TN_reg(rd, cpu_dst);
break;
}
#endif
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 15/23] target-sparc: Use movcond in gen_generic_branch
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (13 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 14/23] target-sparc: Use DisasCompare and movcond in MOVR Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 16/23] target-sparc: Move sdivx and udivx out of line Richard Henderson
` (8 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 9aef8e5..c1a1dc4 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1107,19 +1107,15 @@ static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
static inline void gen_generic_branch(DisasContext *dc)
{
- int l1, l2;
-
- l1 = gen_new_label();
- l2 = gen_new_label();
+ TCGv npc0 = tcg_const_tl(dc->jump_pc[0]);
+ TCGv npc1 = tcg_const_tl(dc->jump_pc[1]);
+ TCGv zero = tcg_const_tl(0);
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cond, 0, l1);
+ tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, zero, npc0, npc1);
- tcg_gen_movi_tl(cpu_npc, dc->jump_pc[0]);
- tcg_gen_br(l2);
-
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_npc, dc->jump_pc[1]);
- gen_set_label(l2);
+ tcg_temp_free(npc0);
+ tcg_temp_free(npc1);
+ tcg_temp_free(zero);
}
/* call this function before using the condition register as it may
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 16/23] target-sparc: Move sdivx and udivx out of line
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (14 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 15/23] target-sparc: Use movcond in gen_generic_branch Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 17/23] target-sparc: Tidy Tcc Richard Henderson
` (7 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
The branches around the exception are maintaining an otherwise
unnecessary use of local temps for the cpu destination.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/cpu.h | 1 +
target-sparc/helper.c | 28 +++++++++++++++++++++++++
target-sparc/helper.h | 4 ++++
target-sparc/ldst_helper.c | 4 ++--
target-sparc/translate.c | 52 ++--------------------------------------------
5 files changed, 37 insertions(+), 52 deletions(-)
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index e16b7b3..214d01d 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -714,6 +714,7 @@ trap_state* cpu_tsptr(CPUSPARCState* env);
void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env, target_ulong addr,
int is_write, int is_user,
uintptr_t retaddr);
+void cpu_restore_state2(CPUSPARCState *env, uintptr_t retaddr);
#define TB_FLAG_FPU_ENABLED (1 << 4)
#define TB_FLAG_AM_ENABLED (1 << 5)
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 65e1740..4555d2b 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -75,6 +75,7 @@ static target_ulong helper_udiv_common(CPUSPARCState *env, target_ulong a,
x1 = (b & 0xffffffff);
if (x1 == 0) {
+ cpu_restore_state2(env, GETPC());
helper_raise_exception(env, TT_DIV_ZERO);
}
@@ -113,6 +114,7 @@ static target_ulong helper_sdiv_common(CPUSPARCState *env, target_ulong a,
x1 = (b & 0xffffffff);
if (x1 == 0) {
+ cpu_restore_state2(env, GETPC());
helper_raise_exception(env, TT_DIV_ZERO);
}
@@ -139,3 +141,29 @@ target_ulong helper_sdiv_cc(CPUSPARCState *env, target_ulong a, target_ulong b)
{
return helper_sdiv_common(env, a, b, 1);
}
+
+#ifdef TARGET_SPARC64
+int64_t helper_sdivx(CPUSPARCState *env, int64_t a, int64_t b)
+{
+ if (b == 0) {
+ /* Raise divide by zero trap. */
+ cpu_restore_state2(env, GETPC());
+ helper_raise_exception(env, TT_DIV_ZERO);
+ } else if (b == -1) {
+ /* Avoid overflow trap with i386 divide insn. */
+ return -a;
+ } else {
+ return a / b;
+ }
+}
+
+uint64_t helper_udivx(CPUSPARCState *env, uint64_t a, uint64_t b)
+{
+ if (b == 0) {
+ /* Raise divide by zero trap. */
+ cpu_restore_state2(env, GETPC());
+ helper_raise_exception(env, TT_DIV_ZERO);
+ }
+ return a / b;
+}
+#endif
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index e3c7fdd..827df67 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -38,6 +38,10 @@ DEF_HELPER_3(udiv, tl, env, tl, tl)
DEF_HELPER_3(udiv_cc, tl, env, tl, tl)
DEF_HELPER_3(sdiv, tl, env, tl, tl)
DEF_HELPER_3(sdiv_cc, tl, env, tl, tl)
+#ifdef TARGET_SPARC64
+DEF_HELPER_3(sdivx, s64, env, s64, s64)
+DEF_HELPER_3(udivx, i64, env, i64, i64)
+#endif
DEF_HELPER_3(ldqf, void, env, tl, int)
DEF_HELPER_3(stqf, void, env, tl, int)
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 9bec7a9..2ca9a5c 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -2390,9 +2390,8 @@ void cpu_unassigned_access(CPUSPARCState *env, target_phys_addr_t addr,
#endif
#endif
-#if !defined(CONFIG_USER_ONLY)
/* XXX: make it generic ? */
-static void cpu_restore_state2(CPUSPARCState *env, uintptr_t retaddr)
+void cpu_restore_state2(CPUSPARCState *env, uintptr_t retaddr)
{
TranslationBlock *tb;
@@ -2407,6 +2406,7 @@ static void cpu_restore_state2(CPUSPARCState *env, uintptr_t retaddr)
}
}
+#if !defined(CONFIG_USER_ONLY)
void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write,
int is_user, uintptr_t retaddr)
{
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index c1a1dc4..1628cf3 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -768,44 +768,6 @@ static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
gen_op_multiply(dst, src1, src2, 1);
}
-#ifdef TARGET_SPARC64
-static inline void gen_trap_ifdivzero_tl(TCGv divisor)
-{
- TCGv_i32 r_const;
- int l1;
-
- l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
- r_const = tcg_const_i32(TT_DIV_ZERO);
- gen_helper_raise_exception(cpu_env, r_const);
- tcg_temp_free_i32(r_const);
- gen_set_label(l1);
-}
-
-static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
-{
- int l1, l2;
- TCGv r_temp1, r_temp2;
-
- l1 = gen_new_label();
- l2 = gen_new_label();
- r_temp1 = tcg_temp_local_new();
- r_temp2 = tcg_temp_local_new();
- tcg_gen_mov_tl(r_temp1, src1);
- tcg_gen_mov_tl(r_temp2, src2);
- gen_trap_ifdivzero_tl(r_temp2);
- tcg_gen_brcondi_tl(TCG_COND_NE, r_temp1, INT64_MIN, l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, r_temp2, -1, l1);
- tcg_gen_movi_i64(dst, INT64_MIN);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_div_i64(dst, r_temp1, r_temp2);
- gen_set_label(l2);
- tcg_temp_free(r_temp1);
- tcg_temp_free(r_temp2);
-}
-#endif
-
// 1
static inline void gen_op_eval_ba(TCGv dst)
{
@@ -3591,17 +3553,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
break;
#ifdef TARGET_SPARC64
case 0xd: /* V9 udivx */
- {
- TCGv r_temp1, r_temp2;
- r_temp1 = tcg_temp_local_new();
- r_temp2 = tcg_temp_local_new();
- tcg_gen_mov_tl(r_temp1, cpu_src1);
- tcg_gen_mov_tl(r_temp2, cpu_src2);
- gen_trap_ifdivzero_tl(r_temp2);
- tcg_gen_divu_i64(cpu_dst, r_temp1, r_temp2);
- tcg_temp_free(r_temp1);
- tcg_temp_free(r_temp2);
- }
+ gen_helper_udivx(cpu_dst, cpu_env, cpu_src1, cpu_src2);
break;
#endif
case 0xe: /* udiv */
@@ -4102,7 +4054,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
break;
}
case 0x2d: /* V9 sdivx */
- gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
+ gen_helper_sdivx(cpu_dst, cpu_env, cpu_src1, cpu_src2);
gen_movl_TN_reg(rd, cpu_dst);
break;
case 0x2e: /* V9 popc */
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 17/23] target-sparc: Tidy Tcc
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (15 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 16/23] target-sparc: Move sdivx and udivx out of line Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 18/23] target-sparc: Move taddcctv and tsubcctv out of line Richard Henderson
` (6 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Share more code between unconditional and conditional paths.
Move the computation of the trap number into the conditional BB;
avoid using temporaries that have gone out of scope (cpu_tmp32)
or rely on local temps (cpu_dst).
Fully fold the exception number when the trap number is %g0+imm.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 91 ++++++++++++++++++++++++++++--------------------
1 file changed, 53 insertions(+), 38 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 1628cf3..111c025 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2594,41 +2594,23 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
{
unsigned int xop = GET_FIELD(insn, 7, 12);
if (xop == 0x3a) { /* generate trap */
- int cond;
+ int cond = GET_FIELD(insn, 3, 6);
+ TCGv_i32 trap;
+ int l1 = -1, mask;
- cpu_src1 = get_src1(insn, cpu_src1);
- if (IS_IMM) {
- rs2 = GET_FIELD(insn, 25, 31);
- tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
- } else {
- rs2 = GET_FIELD(insn, 27, 31);
- if (rs2 != 0) {
- gen_movl_reg_TN(rs2, cpu_src2);
- tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
- } else
- tcg_gen_mov_tl(cpu_dst, cpu_src1);
+ if (cond == 0) {
+ /* Trap never. */
+ break;
}
- cond = GET_FIELD(insn, 3, 6);
- if (cond == 0x8) { /* Trap Always */
- save_state(dc);
- if ((dc->def->features & CPU_FEATURE_HYPV) &&
- supervisor(dc))
- tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
- else
- tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
- tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
- tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
- gen_helper_raise_exception(cpu_env, cpu_tmp32);
+ save_state(dc);
- } else if (cond != 0) {
+ if (cond != 8) {
+ /* Conditional trap. */
DisasCompare cmp;
- int l1;
#ifdef TARGET_SPARC64
/* V9 icc/xcc */
int cc = GET_FIELD_SP(insn, 11, 12);
-
- save_state(dc);
if (cc == 0) {
gen_compare(&cmp, 0, cond, dc);
} else if (cc == 2) {
@@ -2637,27 +2619,60 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
goto illegal_insn;
}
#else
- save_state(dc);
gen_compare(&cmp, 0, cond, dc);
#endif
l1 = gen_new_label();
tcg_gen_brcond_tl(tcg_invert_cond(cmp.cond),
cmp.c1, cmp.c2, l1);
free_compare(&cmp);
+ }
- if ((dc->def->features & CPU_FEATURE_HYPV) &&
- supervisor(dc))
- tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
- else
- tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
- tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
- tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
- gen_helper_raise_exception(cpu_env, cpu_tmp32);
+ mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc)
+ ? UA2005_HTRAP_MASK : V8_TRAP_MASK);
+
+ /* Don't use the normal temporaries, as they may well have
+ gone out of scope with the branch above. While we're
+ doing that we might as well pre-truncate to 32-bit. */
+ trap = tcg_temp_new_i32();
+
+ rs1 = GET_FIELD_SP(insn, 14, 18);
+ if (IS_IMM) {
+ rs2 = GET_FIELD_SP(insn, 0, 6);
+ if (rs1 == 0) {
+ tcg_gen_movi_i32(trap, (rs2 & mask) + TT_TRAP);
+ /* Signal that the trap value is fully constant. */
+ mask = 0;
+ } else {
+ TCGv t1 = tcg_temp_new();
+ gen_movl_reg_TN(rs1, t1);
+ tcg_gen_trunc_tl_i32(trap, t1);
+ tcg_temp_free(t1);
+ tcg_gen_addi_i32(trap, trap, rs2);
+ }
+ } else {
+ TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
+ rs2 = GET_FIELD_SP(insn, 0, 4);
+ gen_movl_reg_TN(rs1, t1);
+ gen_movl_reg_TN(rs2, t2);
+ tcg_gen_add_tl(t1, t1, t2);
+ tcg_gen_trunc_tl_i32(trap, t1);
+ tcg_temp_free(t1);
+ tcg_temp_free(t2);
+ }
+ if (mask != 0) {
+ tcg_gen_andi_i32(trap, trap, mask);
+ tcg_gen_addi_i32(trap, trap, TT_TRAP);
+ }
+
+ gen_helper_raise_exception(cpu_env, trap);
+ tcg_temp_free_i32(trap);
+ if (cond != 8) {
gen_set_label(l1);
+ gen_op_next_insn();
+ tcg_gen_exit_tb(0);
}
- gen_op_next_insn();
- tcg_gen_exit_tb(0);
dc->is_br = 1;
goto jmp_insn;
} else if (xop == 0x28) {
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 18/23] target-sparc: Move taddcctv and tsubcctv out of line
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (16 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 17/23] target-sparc: Tidy Tcc Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 19/23] target-sparc: Use movcond in mulscc Richard Henderson
` (5 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
The branches around the exception are maintaining an otherwise
unnecessary use of local temps for the cpu destination.
Note that gen_op_t{add,sub}_cc were identical to gen_op_{add,sub}_cc.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/helper.c | 58 +++++++++++++++++++++++++
target-sparc/helper.h | 2 +
target-sparc/translate.c | 108 +++--------------------------------------------
3 files changed, 66 insertions(+), 102 deletions(-)
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 4555d2b..556ac28 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -167,3 +167,61 @@ uint64_t helper_udivx(CPUSPARCState *env, uint64_t a, uint64_t b)
return a / b;
}
#endif
+
+target_ulong helper_taddcctv(CPUSPARCState *env, target_ulong src1,
+ target_ulong src2)
+{
+ target_ulong dst;
+
+ /* Tag overflow occurs if either input has bits 0 or 1 set. */
+ if ((src1 | src2) & 3) {
+ goto tag_overflow;
+ }
+
+ dst = src1 + src2;
+
+ /* Tag overflow occurs if the addition overflows. */
+ if (~(src1 ^ src2) & (src1 ^ dst) & (1u << 31)) {
+ goto tag_overflow;
+ }
+
+ /* Only modify the CC after any exceptions have been generated. */
+ env->cc_op = CC_OP_TADDTV;
+ env->cc_src = src1;
+ env->cc_src2 = src2;
+ env->cc_dst = dst;
+ return dst;
+
+ tag_overflow:
+ cpu_restore_state2(env, GETPC());
+ helper_raise_exception(env, TT_TOVF);
+}
+
+target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1,
+ target_ulong src2)
+{
+ target_ulong dst;
+
+ /* Tag overflow occurs if either input has bits 0 or 1 set. */
+ if ((src1 | src2) & 3) {
+ goto tag_overflow;
+ }
+
+ dst = src1 - src2;
+
+ /* Tag overflow occurs if the subtraction overflows. */
+ if ((src1 ^ src2) & (src1 ^ dst) & (1u << 31)) {
+ goto tag_overflow;
+ }
+
+ /* Only modify the CC after any exceptions have been generated. */
+ env->cc_op = CC_OP_TSUBTV;
+ env->cc_src = src1;
+ env->cc_src2 = src2;
+ env->cc_dst = dst;
+ return dst;
+
+ tag_overflow:
+ cpu_restore_state2(env, GETPC());
+ helper_raise_exception(env, TT_TOVF);
+}
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 827df67..e1ae3c7 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -38,6 +38,8 @@ DEF_HELPER_3(udiv, tl, env, tl, tl)
DEF_HELPER_3(udiv_cc, tl, env, tl, tl)
DEF_HELPER_3(sdiv, tl, env, tl, tl)
DEF_HELPER_3(sdiv_cc, tl, env, tl, tl)
+DEF_HELPER_3(taddcctv, tl, env, tl, tl)
+DEF_HELPER_3(tsubcctv, tl, env, tl, tl)
#ifdef TARGET_SPARC64
DEF_HELPER_3(sdivx, s64, env, s64, s64)
DEF_HELPER_3(udivx, i64, env, i64, i64)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 111c025..98efb84 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -336,43 +336,6 @@ static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
tcg_gen_andi_tl(reg, reg, 0x1);
}
-static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
-{
- TCGv r_temp;
- TCGv_i32 r_const;
- int l1;
-
- l1 = gen_new_label();
-
- r_temp = tcg_temp_new();
- tcg_gen_xor_tl(r_temp, src1, src2);
- tcg_gen_not_tl(r_temp, r_temp);
- tcg_gen_xor_tl(cpu_tmp0, src1, dst);
- tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
- tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
- r_const = tcg_const_i32(TT_TOVF);
- gen_helper_raise_exception(cpu_env, r_const);
- tcg_temp_free_i32(r_const);
- gen_set_label(l1);
- tcg_temp_free(r_temp);
-}
-
-static inline void gen_tag_tv(TCGv src1, TCGv src2)
-{
- int l1;
- TCGv_i32 r_const;
-
- l1 = gen_new_label();
- tcg_gen_or_tl(cpu_tmp0, src1, src2);
- tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
- r_const = tcg_const_i32(TT_TOVF);
- gen_helper_raise_exception(cpu_env, r_const);
- tcg_temp_free_i32(r_const);
- gen_set_label(l1);
-}
-
static inline void gen_op_addi_cc(TCGv dst, TCGv src1, target_long src2)
{
tcg_gen_mov_tl(cpu_cc_src, src1);
@@ -517,45 +480,6 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
}
}
-static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
-{
- tcg_gen_mov_tl(cpu_cc_src, src1);
- tcg_gen_mov_tl(cpu_cc_src2, src2);
- tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
- tcg_gen_mov_tl(dst, cpu_cc_dst);
-}
-
-static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
-{
- tcg_gen_mov_tl(cpu_cc_src, src1);
- tcg_gen_mov_tl(cpu_cc_src2, src2);
- gen_tag_tv(cpu_cc_src, cpu_cc_src2);
- tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
- gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
- tcg_gen_mov_tl(dst, cpu_cc_dst);
-}
-
-static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
-{
- TCGv r_temp;
- TCGv_i32 r_const;
- int l1;
-
- l1 = gen_new_label();
-
- r_temp = tcg_temp_new();
- tcg_gen_xor_tl(r_temp, src1, src2);
- tcg_gen_xor_tl(cpu_tmp0, src1, dst);
- tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
- tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
- tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
- r_const = tcg_const_i32(TT_TOVF);
- gen_helper_raise_exception(cpu_env, r_const);
- tcg_temp_free_i32(r_const);
- gen_set_label(l1);
- tcg_temp_free(r_temp);
-}
-
static inline void gen_op_subi_cc(TCGv dst, TCGv src1, target_long src2, DisasContext *dc)
{
tcg_gen_mov_tl(cpu_cc_src, src1);
@@ -656,24 +580,6 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
}
}
-static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
-{
- tcg_gen_mov_tl(cpu_cc_src, src1);
- tcg_gen_mov_tl(cpu_cc_src2, src2);
- tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
- tcg_gen_mov_tl(dst, cpu_cc_dst);
-}
-
-static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
-{
- tcg_gen_mov_tl(cpu_cc_src, src1);
- tcg_gen_mov_tl(cpu_cc_src2, src2);
- gen_tag_tv(cpu_cc_src, cpu_cc_src2);
- tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
- gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
- tcg_gen_mov_tl(dst, cpu_cc_dst);
-}
-
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
{
TCGv r_temp;
@@ -3602,29 +3508,27 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
cpu_src2 = get_src2(insn, cpu_src2);
switch (xop) {
case 0x20: /* taddcc */
- gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
+ gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
gen_movl_TN_reg(rd, cpu_dst);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
dc->cc_op = CC_OP_TADD;
break;
case 0x21: /* tsubcc */
- gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
+ gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
gen_movl_TN_reg(rd, cpu_dst);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
dc->cc_op = CC_OP_TSUB;
break;
case 0x22: /* taddcctv */
- save_state(dc);
- gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
+ gen_helper_taddcctv(cpu_dst, cpu_env,
+ cpu_src1, cpu_src2);
gen_movl_TN_reg(rd, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADDTV);
dc->cc_op = CC_OP_TADDTV;
break;
case 0x23: /* tsubcctv */
- save_state(dc);
- gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
+ gen_helper_tsubcctv(cpu_dst, cpu_env,
+ cpu_src1, cpu_src2);
gen_movl_TN_reg(rd, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUBTV);
dc->cc_op = CC_OP_TSUBTV;
break;
case 0x24: /* mulscc */
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 19/23] target-sparc: Use movcond in mulscc
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (17 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 18/23] target-sparc: Move taddcctv and tsubcctv out of line Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 20/23] target-sparc: Use movcond for FMOV*R Richard Henderson
` (4 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 98efb84..614905e 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -582,22 +582,21 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
{
- TCGv r_temp;
- int l1;
+ TCGv r_temp, zero;
- l1 = gen_new_label();
r_temp = tcg_temp_new();
/* old op:
if (!(env->y & 1))
T1 = 0;
*/
+ zero = tcg_const_tl(0);
tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
- tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
- tcg_gen_movi_tl(cpu_cc_src2, 0);
- gen_set_label(l1);
+ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_cc_src2, r_temp, zero,
+ zero, cpu_cc_src2);
+ tcg_temp_free(zero);
// b2 = T0 & 1;
// env->y = (b2 << 31) | (env->y >> 1);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 20/23] target-sparc: Use movcond for FMOV*R
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (18 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 19/23] target-sparc: Use movcond in mulscc Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 21/23] target-sparc: Cleanup "global" temporary allocation Richard Henderson
` (3 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 46 ++++++++++++++++------------------------------
1 file changed, 16 insertions(+), 30 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 614905e..d594284 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -3051,44 +3051,30 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
rs2 = GET_FIELD(insn, 27, 31);
xop = GET_FIELD(insn, 18, 26);
save_state(dc);
-#ifdef TARGET_SPARC64
- if ((xop & 0x11f) == 0x005) { // V9 fmovsr
- int l1;
- l1 = gen_new_label();
- cond = GET_FIELD_SP(insn, 14, 17);
- cpu_src1 = get_src1(insn, cpu_src1);
- tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
- 0, l1);
- cpu_src1_32 = gen_load_fpr_F(dc, rs2);
- gen_store_fpr_F(dc, rd, cpu_src1_32);
- gen_set_label(l1);
+#ifdef TARGET_SPARC64
+#define FMOVR(sz) \
+ do { \
+ DisasCompare cmp; \
+ cond = GET_FIELD_SP(insn, 14, 17); \
+ cpu_src1 = get_src1(insn, cpu_src1); \
+ gen_compare_reg(&cmp, cond, cpu_src1); \
+ gen_fmov##sz(dc, &cmp, rd, rs2); \
+ free_compare(&cmp); \
+ } while (0)
+
+ if ((xop & 0x11f) == 0x005) { /* V9 fmovsr */
+ FMOVR(s);
break;
} else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
- int l1;
-
- l1 = gen_new_label();
- cond = GET_FIELD_SP(insn, 14, 17);
- cpu_src1 = get_src1(insn, cpu_src1);
- tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
- 0, l1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs2);
- gen_store_fpr_D(dc, rd, cpu_src1_64);
- gen_set_label(l1);
+ FMOVR(d);
break;
} else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
- int l1;
-
CHECK_FPU_FEATURE(dc, FLOAT128);
- l1 = gen_new_label();
- cond = GET_FIELD_SP(insn, 14, 17);
- cpu_src1 = get_src1(insn, cpu_src1);
- tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
- 0, l1);
- gen_move_Q(rd, rs2);
- gen_set_label(l1);
+ FMOVR(q);
break;
}
+#undef FMOVR
#endif
switch (xop) {
#ifdef TARGET_SPARC64
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 21/23] target-sparc: Cleanup "global" temporary allocation
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (19 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 20/23] target-sparc: Use movcond for FMOV*R Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 22/23] target-sparc: Fall through from not-taken trap Richard Henderson
` (2 subsequent siblings)
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
There are 6 temporaries that disas_sparc_insn relies on having been
allocated. Now that they are no longer referenced across branches,
they need not be allocated as local temps.
Move the allocation/free of these temporaries to make it clear that
they are local to the translation of a single insn.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index d594284..48c245e 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5177,16 +5177,6 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
dc->singlestep = (env->singlestep_enabled || singlestep);
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
- cpu_tmp0 = tcg_temp_new();
- cpu_tmp32 = tcg_temp_new_i32();
- cpu_tmp64 = tcg_temp_new_i64();
-
- cpu_dst = tcg_temp_local_new();
-
- // loads and stores
- cpu_val = tcg_temp_local_new();
- cpu_addr = tcg_temp_local_new();
-
num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0)
@@ -5222,9 +5212,24 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
gen_io_start();
last_pc = dc->pc;
insn = cpu_ldl_code(env, dc->pc);
+
+ cpu_tmp0 = tcg_temp_new();
+ cpu_tmp32 = tcg_temp_new_i32();
+ cpu_tmp64 = tcg_temp_new_i64();
+ cpu_dst = tcg_temp_new();
+ cpu_val = tcg_temp_new();
+ cpu_addr = tcg_temp_new();
+
disas_sparc_insn(dc, insn);
num_insns++;
+ tcg_temp_free(cpu_addr);
+ tcg_temp_free(cpu_val);
+ tcg_temp_free(cpu_dst);
+ tcg_temp_free_i64(cpu_tmp64);
+ tcg_temp_free_i32(cpu_tmp32);
+ tcg_temp_free(cpu_tmp0);
+
if (dc->is_br)
break;
/* if the next PC is different, we abort now */
@@ -5244,23 +5249,18 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
num_insns < max_insns);
exit_gen_loop:
- tcg_temp_free(cpu_addr);
- tcg_temp_free(cpu_val);
- tcg_temp_free(cpu_dst);
- tcg_temp_free_i64(cpu_tmp64);
- tcg_temp_free_i32(cpu_tmp32);
- tcg_temp_free(cpu_tmp0);
-
- if (tb->cflags & CF_LAST_IO)
+ if (tb->cflags & CF_LAST_IO) {
gen_io_end();
+ }
if (!dc->is_br) {
if (dc->pc != DYNAMIC_PC &&
(dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
/* static PC and NPC: we can use direct chaining */
gen_goto_tb(dc, 0, dc->pc, dc->npc);
} else {
- if (dc->pc != DYNAMIC_PC)
+ if (dc->pc != DYNAMIC_PC) {
tcg_gen_movi_tl(cpu_pc, dc->pc);
+ }
save_npc(dc);
tcg_gen_exit_tb(0);
}
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 22/23] target-sparc: Fall through from not-taken trap
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (20 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 21/23] target-sparc: Cleanup "global" temporary allocation Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC Richard Henderson
2012-10-07 18:44 ` [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Blue Swirl
23 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Now that we've cleaned up global temporary allocation, we can
continue translating the fallthru path of a conditional trap.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 48c245e..a7f6407 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2573,13 +2573,15 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
gen_helper_raise_exception(cpu_env, trap);
tcg_temp_free_i32(trap);
- if (cond != 8) {
+ if (cond == 8) {
+ /* An unconditional trap ends the TB. */
+ dc->is_br = 1;
+ goto jmp_insn;
+ } else {
+ /* A conditional trap falls through to the next insn. */
gen_set_label(l1);
- gen_op_next_insn();
- tcg_gen_exit_tb(0);
+ break;
}
- dc->is_br = 1;
- goto jmp_insn;
} else if (xop == 0x28) {
rs1 = GET_FIELD(insn, 13, 17);
switch(rs1) {
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (21 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 22/23] target-sparc: Fall through from not-taken trap Richard Henderson
@ 2012-10-05 23:55 ` Richard Henderson
2012-10-07 18:48 ` Blue Swirl
2012-10-07 22:40 ` Aurelien Jarno
2012-10-07 18:44 ` [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Blue Swirl
23 siblings, 2 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-05 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Aka "normal" comparisons. We now have the infrastructure to
pass back non-boolean results from gen_compare. This will
automatically get used by both branches and conditional moves.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-sparc/translate.c | 192 ++++++++++++++++++++++++++++++++---------------
1 file changed, 131 insertions(+), 61 deletions(-)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index a7f6407..472eb51 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1046,83 +1046,153 @@ static void free_compare(DisasCompare *cmp)
}
}
-static void gen_compare(DisasCompare *cmp, unsigned int cc, unsigned int cond,
+static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
DisasContext *dc)
{
+ static int subcc_cond[16] = {
+ -1, /* never */
+ TCG_COND_EQ,
+ TCG_COND_LE,
+ TCG_COND_LT,
+ TCG_COND_LEU,
+ TCG_COND_LTU,
+ -1, /* neg */
+ -1, /* overflow */
+ -1, /* always */
+ TCG_COND_NE,
+ TCG_COND_GT,
+ TCG_COND_GE,
+ TCG_COND_GTU,
+ TCG_COND_GEU,
+ -1, /* pos */
+ -1, /* no overflow */
+ };
+
TCGv_i32 r_src;
TCGv r_dst;
- /* For now we still generate a straight boolean result. */
- cmp->cond = TCG_COND_NE;
- cmp->is_bool = true;
- cmp->g1 = cmp->g2 = false;
- cmp->c1 = r_dst = tcg_temp_new();
- cmp->c2 = tcg_const_tl(0);
-
#ifdef TARGET_SPARC64
- if (cc)
+ if (xcc) {
r_src = cpu_xcc;
- else
+ } else {
r_src = cpu_psr;
+ }
#else
r_src = cpu_psr;
#endif
+
switch (dc->cc_op) {
- case CC_OP_FLAGS:
+ case CC_OP_SUB:
+ switch (cond) {
+ case 6: /* neg */
+ case 14: /* pos */
+ cmp->cond = (cond == 6 ? TCG_COND_LT : TCG_COND_GE);
+ cmp->is_bool = false;
+ cmp->g2 = false;
+ cmp->c2 = tcg_const_tl(0);
+#ifdef TARGET_SPARC64
+ if (!xcc) {
+ cmp->g1 = false;
+ cmp->c1 = tcg_temp_new();
+ tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
+ break;
+ }
+#endif
+ cmp->g1 = true;
+ cmp->c1 = cpu_cc_dst;
+ break;
+
+ case 0: /* never */
+ case 8: /* always */
+ case 7: /* overflow */
+ case 15: /* !overflow */
+ goto do_dynamic;
+
+ default:
+ cmp->cond = subcc_cond[cond];
+ cmp->is_bool = false;
+#ifdef TARGET_SPARC64
+ if (!xcc) {
+ /* Note that sign-extension works for unsigned compares as
+ long as both operands are sign-extended. */
+ cmp->g1 = cmp->g2 = false;
+ cmp->c1 = tcg_temp_new();
+ cmp->c2 = tcg_temp_new();
+ tcg_gen_ext32s_tl(cmp->c1, cpu_cc_src);
+ tcg_gen_ext32s_tl(cmp->c2, cpu_cc_src2);
+ }
+#endif
+ cmp->g1 = cmp->g2 = true;
+ cmp->c1 = cpu_cc_src;
+ cmp->c2 = cpu_cc_src2;
+ break;
+ }
break;
+
default:
+ do_dynamic:
gen_helper_compute_psr(cpu_env);
dc->cc_op = CC_OP_FLAGS;
- break;
- }
- switch (cond) {
- case 0x0:
- gen_op_eval_bn(r_dst);
- break;
- case 0x1:
- gen_op_eval_be(r_dst, r_src);
- break;
- case 0x2:
- gen_op_eval_ble(r_dst, r_src);
- break;
- case 0x3:
- gen_op_eval_bl(r_dst, r_src);
- break;
- case 0x4:
- gen_op_eval_bleu(r_dst, r_src);
- break;
- case 0x5:
- gen_op_eval_bcs(r_dst, r_src);
- break;
- case 0x6:
- gen_op_eval_bneg(r_dst, r_src);
- break;
- case 0x7:
- gen_op_eval_bvs(r_dst, r_src);
- break;
- case 0x8:
- gen_op_eval_ba(r_dst);
- break;
- case 0x9:
- gen_op_eval_bne(r_dst, r_src);
- break;
- case 0xa:
- gen_op_eval_bg(r_dst, r_src);
- break;
- case 0xb:
- gen_op_eval_bge(r_dst, r_src);
- break;
- case 0xc:
- gen_op_eval_bgu(r_dst, r_src);
- break;
- case 0xd:
- gen_op_eval_bcc(r_dst, r_src);
- break;
- case 0xe:
- gen_op_eval_bpos(r_dst, r_src);
- break;
- case 0xf:
- gen_op_eval_bvc(r_dst, r_src);
+ /* FALLTHRU */
+
+ case CC_OP_FLAGS:
+ /* We're going to generate a boolean result. */
+ cmp->cond = TCG_COND_NE;
+ cmp->is_bool = true;
+ cmp->g1 = cmp->g2 = false;
+ cmp->c1 = r_dst = tcg_temp_new();
+ cmp->c2 = tcg_const_tl(0);
+
+ switch (cond) {
+ case 0x0:
+ gen_op_eval_bn(r_dst);
+ break;
+ case 0x1:
+ gen_op_eval_be(r_dst, r_src);
+ break;
+ case 0x2:
+ gen_op_eval_ble(r_dst, r_src);
+ break;
+ case 0x3:
+ gen_op_eval_bl(r_dst, r_src);
+ break;
+ case 0x4:
+ gen_op_eval_bleu(r_dst, r_src);
+ break;
+ case 0x5:
+ gen_op_eval_bcs(r_dst, r_src);
+ break;
+ case 0x6:
+ gen_op_eval_bneg(r_dst, r_src);
+ break;
+ case 0x7:
+ gen_op_eval_bvs(r_dst, r_src);
+ break;
+ case 0x8:
+ gen_op_eval_ba(r_dst);
+ break;
+ case 0x9:
+ gen_op_eval_bne(r_dst, r_src);
+ break;
+ case 0xa:
+ gen_op_eval_bg(r_dst, r_src);
+ break;
+ case 0xb:
+ gen_op_eval_bge(r_dst, r_src);
+ break;
+ case 0xc:
+ gen_op_eval_bgu(r_dst, r_src);
+ break;
+ case 0xd:
+ gen_op_eval_bcc(r_dst, r_src);
+ break;
+ case 0xe:
+ gen_op_eval_bpos(r_dst, r_src);
+ break;
+ case 0xf:
+ gen_op_eval_bvc(r_dst, r_src);
+ break;
+ }
break;
}
}
--
1.7.11.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC
2012-10-05 23:55 ` [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC Richard Henderson
@ 2012-10-07 18:48 ` Blue Swirl
2012-10-07 19:16 ` Richard Henderson
2012-10-07 22:40 ` Aurelien Jarno
1 sibling, 1 reply; 28+ messages in thread
From: Blue Swirl @ 2012-10-07 18:48 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Fri, Oct 5, 2012 at 11:55 PM, Richard Henderson <rth@twiddle.net> wrote:
> Aka "normal" comparisons. We now have the infrastructure to
> pass back non-boolean results from gen_compare. This will
> automatically get used by both branches and conditional moves.
This is not yet optimal, we could do the same trick as is done for x86
for cmp/jcc case (target-i386/translate.c:889), but it's still an
improvement so I applied it with others.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
> target-sparc/translate.c | 192 ++++++++++++++++++++++++++++++++---------------
> 1 file changed, 131 insertions(+), 61 deletions(-)
>
> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
> index a7f6407..472eb51 100644
> --- a/target-sparc/translate.c
> +++ b/target-sparc/translate.c
> @@ -1046,83 +1046,153 @@ static void free_compare(DisasCompare *cmp)
> }
> }
>
> -static void gen_compare(DisasCompare *cmp, unsigned int cc, unsigned int cond,
> +static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
> DisasContext *dc)
> {
> + static int subcc_cond[16] = {
> + -1, /* never */
> + TCG_COND_EQ,
> + TCG_COND_LE,
> + TCG_COND_LT,
> + TCG_COND_LEU,
> + TCG_COND_LTU,
> + -1, /* neg */
> + -1, /* overflow */
> + -1, /* always */
> + TCG_COND_NE,
> + TCG_COND_GT,
> + TCG_COND_GE,
> + TCG_COND_GTU,
> + TCG_COND_GEU,
> + -1, /* pos */
> + -1, /* no overflow */
> + };
> +
> TCGv_i32 r_src;
> TCGv r_dst;
>
> - /* For now we still generate a straight boolean result. */
> - cmp->cond = TCG_COND_NE;
> - cmp->is_bool = true;
> - cmp->g1 = cmp->g2 = false;
> - cmp->c1 = r_dst = tcg_temp_new();
> - cmp->c2 = tcg_const_tl(0);
> -
> #ifdef TARGET_SPARC64
> - if (cc)
> + if (xcc) {
> r_src = cpu_xcc;
> - else
> + } else {
> r_src = cpu_psr;
> + }
> #else
> r_src = cpu_psr;
> #endif
> +
> switch (dc->cc_op) {
> - case CC_OP_FLAGS:
> + case CC_OP_SUB:
> + switch (cond) {
> + case 6: /* neg */
> + case 14: /* pos */
> + cmp->cond = (cond == 6 ? TCG_COND_LT : TCG_COND_GE);
> + cmp->is_bool = false;
> + cmp->g2 = false;
> + cmp->c2 = tcg_const_tl(0);
> +#ifdef TARGET_SPARC64
> + if (!xcc) {
> + cmp->g1 = false;
> + cmp->c1 = tcg_temp_new();
> + tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
> + break;
> + }
> +#endif
> + cmp->g1 = true;
> + cmp->c1 = cpu_cc_dst;
> + break;
> +
> + case 0: /* never */
> + case 8: /* always */
> + case 7: /* overflow */
> + case 15: /* !overflow */
> + goto do_dynamic;
> +
> + default:
> + cmp->cond = subcc_cond[cond];
> + cmp->is_bool = false;
> +#ifdef TARGET_SPARC64
> + if (!xcc) {
> + /* Note that sign-extension works for unsigned compares as
> + long as both operands are sign-extended. */
> + cmp->g1 = cmp->g2 = false;
> + cmp->c1 = tcg_temp_new();
> + cmp->c2 = tcg_temp_new();
> + tcg_gen_ext32s_tl(cmp->c1, cpu_cc_src);
> + tcg_gen_ext32s_tl(cmp->c2, cpu_cc_src2);
> + }
> +#endif
> + cmp->g1 = cmp->g2 = true;
> + cmp->c1 = cpu_cc_src;
> + cmp->c2 = cpu_cc_src2;
> + break;
> + }
> break;
> +
> default:
> + do_dynamic:
> gen_helper_compute_psr(cpu_env);
> dc->cc_op = CC_OP_FLAGS;
> - break;
> - }
> - switch (cond) {
> - case 0x0:
> - gen_op_eval_bn(r_dst);
> - break;
> - case 0x1:
> - gen_op_eval_be(r_dst, r_src);
> - break;
> - case 0x2:
> - gen_op_eval_ble(r_dst, r_src);
> - break;
> - case 0x3:
> - gen_op_eval_bl(r_dst, r_src);
> - break;
> - case 0x4:
> - gen_op_eval_bleu(r_dst, r_src);
> - break;
> - case 0x5:
> - gen_op_eval_bcs(r_dst, r_src);
> - break;
> - case 0x6:
> - gen_op_eval_bneg(r_dst, r_src);
> - break;
> - case 0x7:
> - gen_op_eval_bvs(r_dst, r_src);
> - break;
> - case 0x8:
> - gen_op_eval_ba(r_dst);
> - break;
> - case 0x9:
> - gen_op_eval_bne(r_dst, r_src);
> - break;
> - case 0xa:
> - gen_op_eval_bg(r_dst, r_src);
> - break;
> - case 0xb:
> - gen_op_eval_bge(r_dst, r_src);
> - break;
> - case 0xc:
> - gen_op_eval_bgu(r_dst, r_src);
> - break;
> - case 0xd:
> - gen_op_eval_bcc(r_dst, r_src);
> - break;
> - case 0xe:
> - gen_op_eval_bpos(r_dst, r_src);
> - break;
> - case 0xf:
> - gen_op_eval_bvc(r_dst, r_src);
> + /* FALLTHRU */
> +
> + case CC_OP_FLAGS:
> + /* We're going to generate a boolean result. */
> + cmp->cond = TCG_COND_NE;
> + cmp->is_bool = true;
> + cmp->g1 = cmp->g2 = false;
> + cmp->c1 = r_dst = tcg_temp_new();
> + cmp->c2 = tcg_const_tl(0);
> +
> + switch (cond) {
> + case 0x0:
> + gen_op_eval_bn(r_dst);
> + break;
> + case 0x1:
> + gen_op_eval_be(r_dst, r_src);
> + break;
> + case 0x2:
> + gen_op_eval_ble(r_dst, r_src);
> + break;
> + case 0x3:
> + gen_op_eval_bl(r_dst, r_src);
> + break;
> + case 0x4:
> + gen_op_eval_bleu(r_dst, r_src);
> + break;
> + case 0x5:
> + gen_op_eval_bcs(r_dst, r_src);
> + break;
> + case 0x6:
> + gen_op_eval_bneg(r_dst, r_src);
> + break;
> + case 0x7:
> + gen_op_eval_bvs(r_dst, r_src);
> + break;
> + case 0x8:
> + gen_op_eval_ba(r_dst);
> + break;
> + case 0x9:
> + gen_op_eval_bne(r_dst, r_src);
> + break;
> + case 0xa:
> + gen_op_eval_bg(r_dst, r_src);
> + break;
> + case 0xb:
> + gen_op_eval_bge(r_dst, r_src);
> + break;
> + case 0xc:
> + gen_op_eval_bgu(r_dst, r_src);
> + break;
> + case 0xd:
> + gen_op_eval_bcc(r_dst, r_src);
> + break;
> + case 0xe:
> + gen_op_eval_bpos(r_dst, r_src);
> + break;
> + case 0xf:
> + gen_op_eval_bvc(r_dst, r_src);
> + break;
> + }
> break;
> }
> }
> --
> 1.7.11.4
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC
2012-10-07 18:48 ` Blue Swirl
@ 2012-10-07 19:16 ` Richard Henderson
0 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2012-10-07 19:16 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
On 10/07/2012 11:48 AM, Blue Swirl wrote:
> This is not yet optimal, we could do the same trick as is done for x86
> for cmp/jcc case (target-i386/translate.c:889), but it's still an
> improvement so I applied it with others.
It's trickier with sparc, because of the (exceedingly rare) conditional
branch in branch delay slot case. I've yet to come up with a plan to
handle that which is better than the existing cpu_cond global variable.
(Which we now at least initialize with setcond.)
r~
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC
2012-10-05 23:55 ` [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC Richard Henderson
2012-10-07 18:48 ` Blue Swirl
@ 2012-10-07 22:40 ` Aurelien Jarno
1 sibling, 0 replies; 28+ messages in thread
From: Aurelien Jarno @ 2012-10-07 22:40 UTC (permalink / raw)
To: Richard Henderson; +Cc: Blue Swirl, qemu-devel
This patch breaks the boot of a linux sparc64 kernel very early in the
boot process. The boot hangs after:
| OpenBIOS for Sparc64
| Configuration device id QEMU version 1 machine id 0
| kernel addr 404000 size 5be6b8
| kernel cmdline root=/dev/vda4 console=ttyS0
| CPUs: 1 x SUNW,UltraSPARC-IIi
| UUID: 00000000-0000-0000-0000-000000000000
| Welcome to OpenBIOS v1.0 built on Aug 19 2012 13:06
| Type 'help' for detailed information
| [sparc64] Kernel already loaded
|
| [ 0.000000] PROMLIB: Sun IEEE Boot Prom 'OBP 3.10.24 1999/01/01 01:01'
| [ 0.000000] PROMLIB: Root node compatible: sun4u
| [ 0.000000] Initializing cgroup subsys cpuset
| [ 0.000000] Initializing cgroup subsys cpu
| [ 0.000000] Linux version 3.2.0-3-sparc64 (Debian 3.2.23-1) (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-5) ) #1 Fri Aug 3 15:37:15 UTC 2012
| [ 0.000000] bootconsole [earlyprom0] enabled
| [ 0.000000] ARCH: SUN4U
| [ 0.000000] Ethernet address: 52:54:00:12:34:56
| [ 0.000000] Kernel: Using 2 locked TLB entries for main kernel image.
| [ 0.000000] Remapping the kernel... done.
| [ 0.000000] OF stdout device is: /pci@1fe,0/ebus@2/su
| [ 0.000000] PROM: Built device tree with 32122 bytes of memory.
On Fri, Oct 05, 2012 at 04:55:10PM -0700, Richard Henderson wrote:
> Aka "normal" comparisons. We now have the infrastructure to
> pass back non-boolean results from gen_compare. This will
> automatically get used by both branches and conditional moves.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
> target-sparc/translate.c | 192 ++++++++++++++++++++++++++++++++---------------
> 1 file changed, 131 insertions(+), 61 deletions(-)
>
> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
> index a7f6407..472eb51 100644
> --- a/target-sparc/translate.c
> +++ b/target-sparc/translate.c
> @@ -1046,83 +1046,153 @@ static void free_compare(DisasCompare *cmp)
> }
> }
>
> -static void gen_compare(DisasCompare *cmp, unsigned int cc, unsigned int cond,
> +static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
> DisasContext *dc)
> {
> + static int subcc_cond[16] = {
> + -1, /* never */
> + TCG_COND_EQ,
> + TCG_COND_LE,
> + TCG_COND_LT,
> + TCG_COND_LEU,
> + TCG_COND_LTU,
> + -1, /* neg */
> + -1, /* overflow */
> + -1, /* always */
> + TCG_COND_NE,
> + TCG_COND_GT,
> + TCG_COND_GE,
> + TCG_COND_GTU,
> + TCG_COND_GEU,
> + -1, /* pos */
> + -1, /* no overflow */
> + };
> +
> TCGv_i32 r_src;
> TCGv r_dst;
>
> - /* For now we still generate a straight boolean result. */
> - cmp->cond = TCG_COND_NE;
> - cmp->is_bool = true;
> - cmp->g1 = cmp->g2 = false;
> - cmp->c1 = r_dst = tcg_temp_new();
> - cmp->c2 = tcg_const_tl(0);
> -
> #ifdef TARGET_SPARC64
> - if (cc)
> + if (xcc) {
> r_src = cpu_xcc;
> - else
> + } else {
> r_src = cpu_psr;
> + }
> #else
> r_src = cpu_psr;
> #endif
> +
> switch (dc->cc_op) {
> - case CC_OP_FLAGS:
> + case CC_OP_SUB:
> + switch (cond) {
> + case 6: /* neg */
> + case 14: /* pos */
> + cmp->cond = (cond == 6 ? TCG_COND_LT : TCG_COND_GE);
> + cmp->is_bool = false;
> + cmp->g2 = false;
> + cmp->c2 = tcg_const_tl(0);
> +#ifdef TARGET_SPARC64
> + if (!xcc) {
> + cmp->g1 = false;
> + cmp->c1 = tcg_temp_new();
> + tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
> + break;
> + }
> +#endif
> + cmp->g1 = true;
> + cmp->c1 = cpu_cc_dst;
> + break;
> +
> + case 0: /* never */
> + case 8: /* always */
> + case 7: /* overflow */
> + case 15: /* !overflow */
> + goto do_dynamic;
> +
> + default:
> + cmp->cond = subcc_cond[cond];
> + cmp->is_bool = false;
> +#ifdef TARGET_SPARC64
> + if (!xcc) {
> + /* Note that sign-extension works for unsigned compares as
> + long as both operands are sign-extended. */
> + cmp->g1 = cmp->g2 = false;
> + cmp->c1 = tcg_temp_new();
> + cmp->c2 = tcg_temp_new();
> + tcg_gen_ext32s_tl(cmp->c1, cpu_cc_src);
> + tcg_gen_ext32s_tl(cmp->c2, cpu_cc_src2);
> + }
> +#endif
> + cmp->g1 = cmp->g2 = true;
> + cmp->c1 = cpu_cc_src;
> + cmp->c2 = cpu_cc_src2;
> + break;
> + }
> break;
> +
> default:
> + do_dynamic:
> gen_helper_compute_psr(cpu_env);
> dc->cc_op = CC_OP_FLAGS;
> - break;
> - }
> - switch (cond) {
> - case 0x0:
> - gen_op_eval_bn(r_dst);
> - break;
> - case 0x1:
> - gen_op_eval_be(r_dst, r_src);
> - break;
> - case 0x2:
> - gen_op_eval_ble(r_dst, r_src);
> - break;
> - case 0x3:
> - gen_op_eval_bl(r_dst, r_src);
> - break;
> - case 0x4:
> - gen_op_eval_bleu(r_dst, r_src);
> - break;
> - case 0x5:
> - gen_op_eval_bcs(r_dst, r_src);
> - break;
> - case 0x6:
> - gen_op_eval_bneg(r_dst, r_src);
> - break;
> - case 0x7:
> - gen_op_eval_bvs(r_dst, r_src);
> - break;
> - case 0x8:
> - gen_op_eval_ba(r_dst);
> - break;
> - case 0x9:
> - gen_op_eval_bne(r_dst, r_src);
> - break;
> - case 0xa:
> - gen_op_eval_bg(r_dst, r_src);
> - break;
> - case 0xb:
> - gen_op_eval_bge(r_dst, r_src);
> - break;
> - case 0xc:
> - gen_op_eval_bgu(r_dst, r_src);
> - break;
> - case 0xd:
> - gen_op_eval_bcc(r_dst, r_src);
> - break;
> - case 0xe:
> - gen_op_eval_bpos(r_dst, r_src);
> - break;
> - case 0xf:
> - gen_op_eval_bvc(r_dst, r_src);
> + /* FALLTHRU */
> +
> + case CC_OP_FLAGS:
> + /* We're going to generate a boolean result. */
> + cmp->cond = TCG_COND_NE;
> + cmp->is_bool = true;
> + cmp->g1 = cmp->g2 = false;
> + cmp->c1 = r_dst = tcg_temp_new();
> + cmp->c2 = tcg_const_tl(0);
> +
> + switch (cond) {
> + case 0x0:
> + gen_op_eval_bn(r_dst);
> + break;
> + case 0x1:
> + gen_op_eval_be(r_dst, r_src);
> + break;
> + case 0x2:
> + gen_op_eval_ble(r_dst, r_src);
> + break;
> + case 0x3:
> + gen_op_eval_bl(r_dst, r_src);
> + break;
> + case 0x4:
> + gen_op_eval_bleu(r_dst, r_src);
> + break;
> + case 0x5:
> + gen_op_eval_bcs(r_dst, r_src);
> + break;
> + case 0x6:
> + gen_op_eval_bneg(r_dst, r_src);
> + break;
> + case 0x7:
> + gen_op_eval_bvs(r_dst, r_src);
> + break;
> + case 0x8:
> + gen_op_eval_ba(r_dst);
> + break;
> + case 0x9:
> + gen_op_eval_bne(r_dst, r_src);
> + break;
> + case 0xa:
> + gen_op_eval_bg(r_dst, r_src);
> + break;
> + case 0xb:
> + gen_op_eval_bge(r_dst, r_src);
> + break;
> + case 0xc:
> + gen_op_eval_bgu(r_dst, r_src);
> + break;
> + case 0xd:
> + gen_op_eval_bcc(r_dst, r_src);
> + break;
> + case 0xe:
> + gen_op_eval_bpos(r_dst, r_src);
> + break;
> + case 0xf:
> + gen_op_eval_bvc(r_dst, r_src);
> + break;
> + }
> break;
> }
> }
> --
> 1.7.11.4
>
>
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
` (22 preceding siblings ...)
2012-10-05 23:55 ` [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC Richard Henderson
@ 2012-10-07 18:44 ` Blue Swirl
23 siblings, 0 replies; 28+ messages in thread
From: Blue Swirl @ 2012-10-07 18:44 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Fri, Oct 5, 2012 at 11:54 PM, Richard Henderson <rth@twiddle.net> wrote:
> Most of the patches are cleanup. Some of the middle patches that
> make use of setcond and movcond where apropriate do improve code
> generation. But more important that that, we no longer have tcg
> temporaries that are live across basic blocks. Indeed, the only
> remaining uses of brcond are in Tcc and the actual end-of-TB
> branching code.
>
> The final patch begins to make use of the infrastructure added
> during the cleanups. Obviously there's more that can be done
> here, handling addcc and logic ops, but I've run out of time for
> today.
Thanks, applied all.
>
> Tested on
> linux-user-test-0.3 images
> sparc32 works well
> sparc64 no longer crashes, but does exit 1
>
> the shipped openbios image
> sparc32 works well
> sparc64 works as well as head (stalls before prompt)
>
> sparc-test-0.2
> sparc32 boots to prompt
>
>
> r~
>
>
> Richard Henderson (23):
> target-sparc: Tidy cpu_dump_state
> target-sparc: Make CPU_LOG_INT useful by default
> target-sparc: Tidy do_branch interfaces
> target-sparc: Tidy flush_cond interface
> target-sparc: Tidy gen_trap_ifnofpu interface
> target-sparc: Tidy save_state interface
> target-sparc: Tidy gen_mov_pc_npc interface
> target-sparc: Tidy save_npc interface
> target-sparc: Tidy gen_generic_branch interface
> target-sparc: Introduce DisasCompare and functions to generate it
> target-sparc: Use DisasCompare in Tcc
> target-sparc: Use DisasCompare and movcond in FMOVR, FMOVCC
> target-sparc: Use DisasCompare and movcond in MOVCC
> target-sparc: Use DisasCompare and movcond in MOVR
> target-sparc: Use movcond in gen_generic_branch
> target-sparc: Move sdivx and udivx out of line
> target-sparc: Tidy Tcc
> target-sparc: Move taddcctv and tsubcctv out of line
> target-sparc: Use movcond in mulscc
> target-sparc: Use movcond for FMOV*R
> target-sparc: Cleanup "global" temporary allocation
> target-sparc: Fall through from not-taken trap
> target-sparc: Optimize conditionals using SUBCC
>
> target-sparc/cpu.c | 7 +-
> target-sparc/cpu.h | 1 +
> target-sparc/helper.c | 86 ++++
> target-sparc/helper.h | 6 +
> target-sparc/int32_helper.c | 7 +-
> target-sparc/int64_helper.c | 8 +-
> target-sparc/ldst_helper.c | 4 +-
> target-sparc/translate.c | 1133 +++++++++++++++++++++----------------------
> 8 files changed, 653 insertions(+), 599 deletions(-)
>
> --
> 1.7.11.4
>
^ permalink raw reply [flat|nested] 28+ messages in thread