diff options
-rwxr-xr-x | configure | 4 | ||||
-rw-r--r-- | target-xtensa/cpu.h | 4 | ||||
-rw-r--r-- | target-xtensa/op_helper.c | 5 | ||||
-rw-r--r-- | target-xtensa/translate.c | 67 | ||||
-rw-r--r-- | tests/tcg/xtensa/Makefile | 21 | ||||
-rw-r--r-- | tests/tcg/xtensa/test_extui.S | 26 |
6 files changed, 93 insertions, 34 deletions
@@ -4507,13 +4507,13 @@ 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 tests/qapi-schema" +DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa" 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" diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index a8f02f6e4b..95103e9e87 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -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_GET_CPU(env)->singlestep_enabled && env->exception_taken) { + *flags |= XTENSA_TBFLAG_EXCEPTION; + } } #include "exec/cpu-all.h" diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 4c41de0668..6ca912c5bb 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -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); } @@ -448,8 +451,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, diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index e692329157..504cc539e3 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -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; @@ -491,7 +496,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 +505,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 +516,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) @@ -826,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); } } @@ -1482,9 +1502,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 +1727,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*/ @@ -2918,8 +2940,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu, gen_tb_start(); - if (cs->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); } diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile index 002fd871d9..1b519cae45 100644 --- a/tests/tcg/xtensa/Makefile +++ b/tests/tcg/xtensa/Makefile @@ -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 @@ -26,6 +28,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 @@ -52,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) diff --git a/tests/tcg/xtensa/test_extui.S b/tests/tcg/xtensa/test_extui.S new file mode 100644 index 0000000000..5d55451704 --- /dev/null +++ b/tests/tcg/xtensa/test_extui.S @@ -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 |