Skip to contentSkip to conversation

target-xtensa queue

PATCH New Max Filippov 1 participant 7 messages Jul 21, 2013

lore
Share & tools
lore
#0 lore raw

cover target-xtensa queue

Hello.

This is my current target-xtensa patch queue. There's a number of assorted fixes, new testcase and performance optimization patch.

The following changes since commit 24943978cbe79634a9a8b02a20efb25b29b3ab49:

boot-order-test: Add tests for Sun4u (2013-07-18 13:27:47 -0500)

are available in the git repository at:

git://github.com/OSLL/qemu-xtensa.git tags/20130721-xtensa

for you to fetch changes up to fd402139e7575a7d9e210a028c4e3cd640cf4a6a:

target-xtensa: check register window inline (2013-07-21 15:35:09 +0400)

----------------------------------------------------------------
Andreas Färber (1):
tests/tcg/xtensa: Fix out-of-tree build

Max Filippov (5):
target-xtensa: add extui unit test
target-xtensa: add fallthrough markers
target-xtensa: avoid double-stopping at breakpoints
target-xtensa: don't generate dead code to access invalid SRs
target-xtensa: check register window inline

 configure                     |  5 ++--
 target-xtensa/cpu.h           |  4 +++
 target-xtensa/op_helper.c     |  5 ++++
 target-xtensa/translate.c     | 67 ++++++++++++++++++++++++++++---------------
 tests/tcg/xtensa/Makefile     | 21 ++++++++------
 tests/tcg/xtensa/test_extui.S | 26 +++++++++++++++++
 6 files changed, 94 insertions(+), 34 deletions(-)
 create mode 100644 tests/tcg/xtensa/test_extui.S
Signature · 1 line
1.8.1.4
#1 lore raw

PATCH 1/6 target-xtensa: add extui unit test

---
 tests/tcg/xtensa/Makefile     |  1 +
 tests/tcg/xtensa/test_extui.S | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 tests/tcg/xtensa/test_extui.S
tests/tcg/xtensa/Makefile +1 -0
index 002fd87..9e50d8d 100644
@@ -26,6 +26,7 @@ TESTCASES += test_bi.tst
 TESTCASES += test_break.tst
 TESTCASES += test_bz.tst
 TESTCASES += test_clamps.tst
+TESTCASES += test_extui.tst
 TESTCASES += test_fail.tst
 TESTCASES += test_interrupt.tst
 TESTCASES += test_loop.tst
tests/tcg/xtensa/test_extui.S new file +26 -0
new file mode 100644
index 0000000..5d55451
@@ -0,0 +1,26 @@
+.include "macros.inc"
+
+test_suite extui
+
+.macro test_extui v, shiftimm, maskimm
+    .if     \shiftimm + \maskimm <= 32
+    movi    a2, \v
+    extui   a3, a2, \shiftimm, \maskimm
+    movi    a4, ((\v) >> (\shiftimm)) & ((1 << (\maskimm)) - 1)
+    assert  eq, a3, a4
+    .endif
+.endm
+
+test extui
+    .set    shiftimm, 0
+    .rept   32
+    .set    maskimm, 1
+    .rept   16
+    test_extui 0xc8df1370, shiftimm, maskimm
+    .set    maskimm, maskimm + 1
+    .endr
+    .set    shiftimm, shiftimm + 1
+    .endr
+test_end
+
+test_suite_end
Signature · 1 line
1.8.1.4
#2 lore raw

PATCH 2/6 target-xtensa: add fallthrough markers

In reply to Max Filippov

Explicitly mark cases where we are deliberately falling through to the following code.

---
 target-xtensa/op_helper.c | 2 ++
 1 file changed, 2 insertions(+)
target-xtensa/op_helper.c +2 -0
index 4c41de0..834fe90 100644
@@ -448,8 +448,10 @@ void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
     switch (access & PAGE_CACHE_MASK) {
     case PAGE_CACHE_WB:
         atomctl >>= 2;
+        /* fall through */
     case PAGE_CACHE_WT:
         atomctl >>= 2;
+        /* fall through */
     case PAGE_CACHE_BYPASS:
         if ((atomctl & 0x3) == 0) {
             HELPER(exception_cause_vaddr)(env, pc,
Signature · 1 line
1.8.1.4
#3 lore raw

PATCH 3/6 target-xtensa: avoid double-stopping at breakpoints

In reply to Max Filippov

env->exception_taken is set every time an exception is taken. It is used to allow single-stepping to stop at the first exception handler instruction. This however must exclude debug exceptions, as otherwise first step from the instruction where breakpoint was hit stops at that same instruction.
Also don't check env->exception_taken directly from the gen_intermediate_code_internal, instead allocate and use TB flag XTENSA_TBFLAG_EXCEPTION.

---
 target-xtensa/cpu.h       | 4 ++++
 target-xtensa/op_helper.c | 3 +++
 target-xtensa/translate.c | 3 +--
 3 files changed, 8 insertions(+), 2 deletions(-)
target-xtensa/cpu.h +4 -0
index 6c9fc35..c19aeb9 100644
@@ -484,6 +484,7 @@ static inline int cpu_mmu_index(CPUXtensaState *env)
 #define XTENSA_TBFLAG_ICOUNT 0x20
 #define XTENSA_TBFLAG_CPENABLE_MASK 0x3fc0
 #define XTENSA_TBFLAG_CPENABLE_SHIFT 6
+#define XTENSA_TBFLAG_EXCEPTION 0x4000
 
 static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
         target_ulong *cs_base, int *flags)
@@ -510,6 +511,9 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
     if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
         *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
     }
+    if (env->singlestep_enabled && env->exception_taken) {
+        *flags |= XTENSA_TBFLAG_EXCEPTION;
+    }
 }
 
 #include "exec/cpu-all.h"
target-xtensa/op_helper.c +3 -0
index 834fe90..6ca912c 100644
@@ -96,6 +96,9 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
 void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
 {
     env->exception_index = excp;
+    if (excp == EXCP_DEBUG) {
+        env->exception_taken = 0;
+    }
     cpu_loop_exit(env);
 }
 
target-xtensa/translate.c +1 -2
index e4cf828..ef97db0 100644
@@ -2917,8 +2917,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
 
     gen_tb_start();
 
-    if (env->singlestep_enabled && env->exception_taken) {
-        env->exception_taken = 0;
+    if (tb->flags & XTENSA_TBFLAG_EXCEPTION) {
         tcg_gen_movi_i32(cpu_pc, dc.pc);
         gen_exception(&dc, EXCP_DEBUG);
     }
Signature · 1 line
1.8.1.4
#4 lore raw

PATCH 4/6 tests/tcg/xtensa: Fix out-of-tree build

In reply to Max Filippov

From: Andreas Färber <[email protected]>

---
 configure                 |  5 +++--
 tests/tcg/xtensa/Makefile | 20 +++++++++++---------
 2 files changed, 14 insertions(+), 11 deletions(-)
configure +3 -2
index 9e1cd19..4888c3a 100755
@@ -4487,13 +4487,14 @@ if [ "$dtc_internal" = "yes" ]; then
 fi
 
 # build tree in object directory in case the source is not in the current directory
-DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos"
+DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/tcg/xtensa"
+DIRS="$DIRS tests/libqos"
 DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS qapi-generated"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
-FILES="$FILES tests/tcg/lm32/Makefile po/Makefile"
+FILES="$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES pc-bios/s390-ccw/Makefile"
tests/tcg/xtensa/Makefile +11 -9
index 9e50d8d..1b519ca 100644
@@ -1,9 +1,9 @@
--include ../../config-host.mak
+-include ../../../config-host.mak
 
 CROSS=xtensa-dc232b-elf-
 
 ifndef XT
-SIM = qemu-system-xtensa
+SIM = ../../../xtensa-softmmu/qemu-system-xtensa
 SIMFLAGS = -M sim -cpu dc232b -nographic -semihosting $(EXTFLAGS) -kernel
 SIMDEBUG = -s -S
 else
@@ -13,10 +13,12 @@ SIMDEBUG = --gdbserve=0
 endif
 
 CC      = $(CROSS)gcc
-AS      = $(CROSS)gcc -x assembler
+AS      = $(CROSS)gcc -x assembler-with-cpp
 LD      = $(CROSS)ld
 
-LDFLAGS = -Tlinker.ld
+XTENSA_SRC_PATH = $(SRC_PATH)/tests/tcg/xtensa
+
+LDFLAGS = -T$(XTENSA_SRC_PATH)/linker.ld
 
 CRT        = crt.o vectors.o
 
@@ -53,13 +55,13 @@ TESTCASES += test_windowed.tst
 
 all: build
 
-%.o: $(SRC_PATH)/tests/xtensa/%.c
-	$(CC) $(CFLAGS) -c $< -o $@
+%.o: $(XTENSA_SRC_PATH)/%.c
+	$(CC) -I$(XTENSA_SRC_PATH) $(CFLAGS) -c $< -o $@
 
-%.o: $(SRC_PATH)/tests/xtensa/%.S
-	$(AS) $(ASFLAGS) -c $< -o $@
+%.o: $(XTENSA_SRC_PATH)/%.S
+	$(AS) -Wa,-I,$(XTENSA_SRC_PATH) $(ASFLAGS) -c $< -o $@
 
-%.tst: %.o macros.inc $(CRT) Makefile
+%.tst: %.o $(XTENSA_SRC_PATH)/macros.inc $(CRT) Makefile
 	$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@
 
 build: $(TESTCASES)
Signature · 1 line
1.8.1.4
#5 lore raw

PATCH 5/6 target-xtensa: don't generate dead code to access invalid SRs

In reply to Max Filippov

This fixes the following test failure caused by access to undefined SR:

qemu-system-xtensa -M sim -cpu dc232b -nographic -semihosting -kernel ./test_sr.tst
QEMU 1.4.50 monitor - type 'help' for more information
(qemu) QEMU 1.4.50 monitor - type 'help' for more information
(qemu) qemu-system-xtensa: tcg/tcg.c:1673: temp_save: Assertion `s->temps[temp].val_type == 2 || s->temps[temp].fixed_reg' failed.

---
 target-xtensa/translate.c | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)
target-xtensa/translate.c +18 -13
index ef97db0..dcd506f 100644
@@ -491,7 +491,7 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond,
     tcg_temp_free(tmp);
 }
 
-static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
+static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
 {
     if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
         if (sregnames[sr].name) {
@@ -500,6 +500,7 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
             qemu_log("SR %d is not implemented\n", sr);
         }
         gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
+        return false;
     } else if (!(sregnames[sr].access & access)) {
         static const char * const access_text[] = {
             [SR_R] = "rsr",
@@ -510,7 +511,9 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
         qemu_log("SR %s is not available for %s\n", sregnames[sr].name,
                 access_text[access]);
         gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
+        return false;
     }
+    return true;
 }
 
 static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
@@ -1482,9 +1485,9 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 break;
 
             case 6: /*XSR*/
-                {
+                if (gen_check_sr(dc, RSR_SR, SR_X)) {
                     TCGv_i32 tmp = tcg_temp_new_i32();
-                    gen_check_sr(dc, RSR_SR, SR_X);
+
                     if (RSR_SR >= 64) {
                         gen_check_privilege(dc);
                     }
@@ -1707,21 +1710,23 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
         case 3: /*RST3*/
             switch (OP2) {
             case 0: /*RSR*/
-                gen_check_sr(dc, RSR_SR, SR_R);
-                if (RSR_SR >= 64) {
-                    gen_check_privilege(dc);
+                if (gen_check_sr(dc, RSR_SR, SR_R)) {
+                    if (RSR_SR >= 64) {
+                        gen_check_privilege(dc);
+                    }
+                    gen_window_check1(dc, RRR_T);
+                    gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
                 }
-                gen_window_check1(dc, RRR_T);
-                gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
                 break;
 
             case 1: /*WSR*/
-                gen_check_sr(dc, RSR_SR, SR_W);
-                if (RSR_SR >= 64) {
-                    gen_check_privilege(dc);
+                if (gen_check_sr(dc, RSR_SR, SR_W)) {
+                    if (RSR_SR >= 64) {
+                        gen_check_privilege(dc);
+                    }
+                    gen_window_check1(dc, RRR_T);
+                    gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
                 }
-                gen_window_check1(dc, RRR_T);
-                gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
                 break;
 
             case 2: /*SEXTu*/
Signature · 1 line
1.8.1.4
#6 lore raw

PATCH 6/6 target-xtensa: check register window inline

In reply to Max Filippov

This lowers time spent in helper_window_check as reported by perf top from ~8% to ~0.15% accelerating register-intensive tests by ~20%.

---
 target-xtensa/translate.c | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)
target-xtensa/translate.c +25 -8
index dcd506f..5be7226 100644
@@ -305,16 +305,21 @@ static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
     tcg_temp_free(tmp);
 }
 
-static void gen_advance_ccount(DisasContext *dc)
+static void gen_advance_ccount_cond(DisasContext *dc)
 {
     if (dc->ccount_delta > 0) {
         TCGv_i32 tmp = tcg_const_i32(dc->ccount_delta);
-        dc->ccount_delta = 0;
         gen_helper_advance_ccount(cpu_env, tmp);
         tcg_temp_free(tmp);
     }
 }
 
+static void gen_advance_ccount(DisasContext *dc)
+{
+    gen_advance_ccount_cond(dc);
+    dc->ccount_delta = 0;
+}
+
 static void reset_used_window(DisasContext *dc)
 {
     dc->used_window = 0;
@@ -829,15 +834,27 @@ static void gen_window_check1(DisasContext *dc, unsigned r1)
     }
     if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) &&
             r1 / 4 > dc->used_window) {
-        TCGv_i32 pc = tcg_const_i32(dc->pc);
-        TCGv_i32 w = tcg_const_i32(r1 / 4);
+        int label = gen_new_label();
+        TCGv_i32 ws = tcg_temp_new_i32();
 
         dc->used_window = r1 / 4;
-        gen_advance_ccount(dc);
-        gen_helper_window_check(cpu_env, pc, w);
+        tcg_gen_deposit_i32(ws, cpu_SR[WINDOW_START], cpu_SR[WINDOW_START],
+                dc->config->nareg / 4, dc->config->nareg / 4);
+        tcg_gen_shr_i32(ws, ws, cpu_SR[WINDOW_BASE]);
+        tcg_gen_andi_i32(ws, ws, (2 << (r1 / 4)) - 2);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, ws, 0, label);
+        {
+            TCGv_i32 pc = tcg_const_i32(dc->pc);
+            TCGv_i32 w = tcg_const_i32(r1 / 4);
+
+            gen_advance_ccount_cond(dc);
+            gen_helper_window_check(cpu_env, pc, w);
 
-        tcg_temp_free(w);
-        tcg_temp_free(pc);
+            tcg_temp_free(w);
+            tcg_temp_free(pc);
+        }
+        gen_set_label(label);
+        tcg_temp_free(ws);
     }
 }
 
Signature · 1 line
1.8.1.4