diff options
Diffstat (limited to 'qemu/tests/tcg')
771 files changed, 43241 insertions, 0 deletions
diff --git a/qemu/tests/tcg/Makefile b/qemu/tests/tcg/Makefile new file mode 100644 index 000000000..89e3342f3 --- /dev/null +++ b/qemu/tests/tcg/Makefile @@ -0,0 +1,156 @@ +-include ../../config-host.mak +-include $(SRC_PATH)/rules.mak + +$(call set-vpath, $(SRC_PATH)/tests/tcg) + +QEMU=../../i386-linux-user/qemu-i386 +QEMU_X86_64=../../x86_64-linux-user/qemu-x86_64 +CC_X86_64=$(CC_I386) -m64 + +QEMU_INCLUDES += -I../.. +CFLAGS=-Wall -O2 -g -fno-strict-aliasing +#CFLAGS+=-msse2 +LDFLAGS= + +# TODO: automatically detect ARM and MIPS compilers, and run those too + +# runcom maps page 0, so it requires root privileges +# also, pi_10.com runs indefinitely + +I386_TESTS=hello-i386 \ + linux-test \ + testthread \ + sha1-i386 \ + test-i386 \ + test-i386-fprem \ + test-mmap \ + # runcom + +# native i386 compilers sometimes are not biarch. assume cross-compilers are +ifneq ($(ARCH),i386) +I386_TESTS+=run-test-x86_64 +endif + +TESTS = test_path +ifneq ($(call find-in-path, $(CC_I386)),) +TESTS += $(I386_TESTS) +endif + +all: $(patsubst %,run-%,$(TESTS)) +test: all + +# rules to run tests + +.PHONY: $(patsubst %,run-%,$(TESTS)) + +run-%: % + -$(QEMU) ./$* + +run-hello-i386: hello-i386 +run-linux-test: linux-test +run-testthread: testthread +run-sha1-i386: sha1-i386 + +run-test-i386: test-i386 + ./test-i386 > test-i386.ref + -$(QEMU) test-i386 > test-i386.out + @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi + +run-test-i386-fprem: test-i386-fprem + ./test-i386-fprem > test-i386-fprem.ref + -$(QEMU) test-i386-fprem > test-i386-fprem.out + @if diff -u test-i386-fprem.ref test-i386-fprem.out ; then echo "Auto Test OK"; fi + +run-test-x86_64: test-x86_64 + ./test-x86_64 > test-x86_64.ref + -$(QEMU_X86_64) test-x86_64 > test-x86_64.out + @if diff -u test-x86_64.ref test-x86_64.out ; then echo "Auto Test OK"; fi + +run-test-mmap: test-mmap + -$(QEMU) ./test-mmap + -$(QEMU) -p 8192 ./test-mmap 8192 + -$(QEMU) -p 16384 ./test-mmap 16384 + -$(QEMU) -p 32768 ./test-mmap 32768 + +run-runcom: runcom + -$(QEMU) ./runcom $(SRC_PATH)/tests/pi_10.com + +run-test_path: test_path + ./test_path + +# rules to compile tests + +test_path: test_path.o + +test_path.o: test_path.c + +hello-i386: hello-i386.c + $(CC_I386) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $< + strip $@ + +testthread: testthread.c + $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread + +# i386/x86_64 emulation test (test various opcodes) */ +test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \ + test-i386.h test-i386-shift.h test-i386-muldiv.h + $(CC_I386) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ \ + $(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm + +test-i386-fprem: test-i386-fprem.c + $(CC_I386) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ $^ + +test-x86_64: test-i386.c \ + test-i386.h test-i386-shift.h test-i386-muldiv.h + $(CC_X86_64) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ $(<D)/test-i386.c -lm + +# generic Linux and CPU test +linux-test: linux-test.c + $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm + +# vm86 test +runcom: runcom.c + $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< + +test-mmap: test-mmap.c + $(CC_I386) -m32 $(CFLAGS) -Wall -O2 $(LDFLAGS) -o $@ $< + +# speed test +sha1-i386: sha1.c + $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< + +sha1: sha1.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< + +speed: sha1 sha1-i386 + time ./sha1 + time $(QEMU) ./sha1-i386 + +# arm test +hello-arm: hello-arm.o + arm-linux-ld -o $@ $< + +hello-arm.o: hello-arm.c + arm-linux-gcc -Wall -g -O2 -c -o $@ $< + +test-arm-iwmmxt: test-arm-iwmmxt.s + cpp < $< | arm-linux-gnu-gcc -Wall -static -march=iwmmxt -mabi=aapcs -x assembler - -o $@ + +# MIPS test +hello-mips: hello-mips.c + mips-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $< + +hello-mipsel: hello-mips.c + mipsel-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $< + +# testsuite for the CRIS port. +test-cris: + $(MAKE) -C cris check + +# testsuite for the LM32 port. +test-lm32: + $(MAKE) -C lm32 check + +clean: + rm -f *~ *.o test-i386.out test-i386.ref \ + test-x86_64.log test-x86_64.ref qruncom $(TESTS) diff --git a/qemu/tests/tcg/alpha/Makefile b/qemu/tests/tcg/alpha/Makefile new file mode 100644 index 000000000..2b1f03d04 --- /dev/null +++ b/qemu/tests/tcg/alpha/Makefile @@ -0,0 +1,35 @@ +CROSS=alpha-linux-gnu- +CC=$(CROSS)gcc +AS=$(CROSS)as + +SIM=../../alpha-linux-user/qemu-alpha + +CFLAGS=-O +LINK=$(CC) -o $@ crt.o $< -nostdlib + +TESTS=test-cond test-cmov + +all: hello-alpha $(TESTS) + +hello-alpha: hello-alpha.o crt.o + $(LINK) + +test-cond: test-cond.o crt.o + $(LINK) + +test-cmov.o: test-cond.c + $(CC) -c $(CFLAGS) -DTEST_CMOV -o $@ $< + +test-cmov: test-cmov.o crt.o + $(LINK) + +test-ovf: test-ovf.o crt.o + $(LINK) + +check: $(TESTS) + for f in $(TESTS); do $(SIM) $$f || exit 1; done + +clean: + $(RM) *.o *~ hello-alpha $(TESTS) + +.PHONY: clean all check diff --git a/qemu/tests/tcg/alpha/crt.s b/qemu/tests/tcg/alpha/crt.s new file mode 100644 index 000000000..31af8825b --- /dev/null +++ b/qemu/tests/tcg/alpha/crt.s @@ -0,0 +1,26 @@ + .text + + .globl _start + .ent _start,0 +_start: + .frame $15,0,$15 + br $29,1f +1: ldgp $29, 0($29) + .prologue 0 + ldq $27,main($29) !literal!1 + jsr $26,($27) + or $0,$0,$16 + .end _start + + .globl _exit +_exit: + lda $0,1 + callsys + + call_pal 0 + + .globl write +write: + lda $0,4 + callsys + ret diff --git a/qemu/tests/tcg/alpha/hello-alpha.c b/qemu/tests/tcg/alpha/hello-alpha.c new file mode 100644 index 000000000..79892e652 --- /dev/null +++ b/qemu/tests/tcg/alpha/hello-alpha.c @@ -0,0 +1,5 @@ +int main (void) +{ + write (1, "hello\n", 6); + return 0; +} diff --git a/qemu/tests/tcg/alpha/test-cond.c b/qemu/tests/tcg/alpha/test-cond.c new file mode 100644 index 000000000..74adffaa6 --- /dev/null +++ b/qemu/tests/tcg/alpha/test-cond.c @@ -0,0 +1,87 @@ + +#ifdef TEST_CMOV + +#define TEST_COND(N) \ +int test_##N (long a) \ +{ \ + int res = 1; \ + \ + asm ("cmov"#N" %1,$31,%0" \ + : "+r" (res) : "r" (a)); \ + return !res; \ +} + +#else + +#define TEST_COND(N) \ +int test_##N (long a) \ +{ \ + int res = 1; \ + \ + asm ("b"#N" %1,1f\n\t" \ + "addq $31,$31,%0\n\t" \ + "1: unop\n" \ + : "+r" (res) : "r" (a)); \ + return res; \ +} + +#endif + +TEST_COND(eq) +TEST_COND(ne) +TEST_COND(ge) +TEST_COND(gt) +TEST_COND(lbc) +TEST_COND(lbs) +TEST_COND(le) +TEST_COND(lt) + +static struct { + int (*func)(long); + long v; + int r; +} vectors[] = + { + {test_eq, 0, 1}, + {test_eq, 1, 0}, + + {test_ne, 0, 0}, + {test_ne, 1, 1}, + + {test_ge, 0, 1}, + {test_ge, 1, 1}, + {test_ge, -1, 0}, + + {test_gt, 0, 0}, + {test_gt, 1, 1}, + {test_gt, -1, 0}, + + {test_lbc, 0, 1}, + {test_lbc, 1, 0}, + {test_lbc, -1, 0}, + + {test_lbs, 0, 0}, + {test_lbs, 1, 1}, + {test_lbs, -1, 1}, + + {test_le, 0, 1}, + {test_le, 1, 0}, + {test_le, -1, 1}, + + {test_lt, 0, 0}, + {test_lt, 1, 0}, + {test_lt, -1, 1}, + }; + +int main (void) +{ + int i; + + for (i = 0; i < sizeof (vectors)/sizeof(vectors[0]); i++) + if ((*vectors[i].func)(vectors[i].v) != vectors[i].r) { + write(1, "Failed\n", 7); + return 1; + } + write(1, "OK\n", 3); + return 0; +} diff --git a/qemu/tests/tcg/alpha/test-ovf.c b/qemu/tests/tcg/alpha/test-ovf.c new file mode 100644 index 000000000..01c80e752 --- /dev/null +++ b/qemu/tests/tcg/alpha/test-ovf.c @@ -0,0 +1,29 @@ +static long test_subqv (long a, long b) +{ + long res; + + asm ("subq/v %1,%2,%0" + : "=r" (res) : "r" (a), "r" (b)); + return res; +} +static struct { + long (*func)(long, long); + long a; + long b; + long r; +} vectors[] = + { + {test_subqv, 0, 0x7d54000, 0xfffffffff82ac000L} + }; + +int main (void) +{ + int i; + + for (i = 0; i < sizeof (vectors)/sizeof(vectors[0]); i++) + if ((*vectors[i].func)(vectors[i].a, vectors[i].b) != vectors[i].r) { + write(1, "Failed\n", 7); + } + write(1, "OK\n", 3); + return 0; +} diff --git a/qemu/tests/tcg/cris/.gdbinit b/qemu/tests/tcg/cris/.gdbinit new file mode 100644 index 000000000..5e8c1d32f --- /dev/null +++ b/qemu/tests/tcg/cris/.gdbinit @@ -0,0 +1,11 @@ +b main +b _fail +b exit +display /i $pc +display /x $srp +display /x $r0 +display /x $r1 +display /x $r2 +display /x $r3 +display /x $r4 +display /t $ccs diff --git a/qemu/tests/tcg/cris/Makefile b/qemu/tests/tcg/cris/Makefile new file mode 100644 index 000000000..d34bfd8f7 --- /dev/null +++ b/qemu/tests/tcg/cris/Makefile @@ -0,0 +1,155 @@ +-include ../../../config-host.mak + +CROSS=crisv32-axis-linux-gnu- +SIM=../../../cris-linux-user/qemu-cris -L ./ +SIMG=cris-axis-linux-gnu-run --sysroot=./ + +CC = $(CROSS)gcc +#AS = $(CROSS)as +AS = $(CC) -x assembler-with-cpp +SIZE = $(CROSS)size +LD = $(CC) +OBJCOPY = $(CROSS)objcopy + +# we rely on GCC inline:ing the stuff we tell it to in many places here. +CFLAGS = -Winline -Wall -g -O2 -static +NOSTDFLAGS = -nostartfiles -nostdlib +ASFLAGS += -g -Wa,-I,$(SRC_PATH)/tests/tcg/cris/ +LDLIBS = +NOSTDLIBS = -lgcc + +CRT = crt.o +SYS = sys.o +TESTCASES += check_abs.tst +TESTCASES += check_addc.tst +TESTCASES += check_addcm.tst +TESTCASES += check_addo.tst +TESTCASES += check_addoq.tst +TESTCASES += check_addi.tst +TESTCASES += check_addiv32.tst +TESTCASES += check_addm.tst +TESTCASES += check_addr.tst +TESTCASES += check_addq.tst +TESTCASES += check_addxc.tst +TESTCASES += check_addxm.tst +TESTCASES += check_addxr.tst +TESTCASES += check_andc.tst +TESTCASES += check_andm.tst +TESTCASES += check_andr.tst +TESTCASES += check_andq.tst +TESTCASES += check_asr.tst +TESTCASES += check_ba.tst +TESTCASES += check_bas.tst +TESTCASES += check_bcc.tst +TESTCASES += check_bound.tst +TESTCASES += check_boundc.tst +TESTCASES += check_boundr.tst +TESTCASES += check_btst.tst +TESTCASES += check_clearfv32.tst +TESTCASES += check_cmpc.tst +TESTCASES += check_cmpr.tst +TESTCASES += check_cmpq.tst +TESTCASES += check_cmpm.tst +TESTCASES += check_cmpxc.tst +TESTCASES += check_cmpxm.tst +TESTCASES += check_cmp-2.tst +TESTCASES += check_clrjmp1.tst +TESTCASES += check_dstep.tst +TESTCASES += check_ftag.tst +TESTCASES += check_int64.tst +# check_jsr is broken. +#TESTCASES += check_jsr.tst +TESTCASES += check_mcp.tst +TESTCASES += check_movei.tst +TESTCASES += check_mover.tst +TESTCASES += check_moverm.tst +TESTCASES += check_moveq.tst +TESTCASES += check_movemr.tst +TESTCASES += check_movemrv32.tst +TESTCASES += check_movecr.tst +TESTCASES += check_movmp.tst +TESTCASES += check_movpr.tst +TESTCASES += check_movprv32.tst +TESTCASES += check_movdelsr1.tst +TESTCASES += check_movpmv32.tst +TESTCASES += check_movsr.tst +TESTCASES += check_movsm.tst +TESTCASES += check_movscr.tst +TESTCASES += check_movur.tst +TESTCASES += check_movum.tst +TESTCASES += check_movucr.tst +TESTCASES += check_mulx.tst +TESTCASES += check_mulv32.tst +TESTCASES += check_neg.tst +TESTCASES += check_not.tst +TESTCASES += check_lz.tst +TESTCASES += check_lapc.tst +TESTCASES += check_lsl.tst +TESTCASES += check_lsr.tst +TESTCASES += check_orc.tst +TESTCASES += check_orm.tst +TESTCASES += check_orr.tst +TESTCASES += check_orq.tst +TESTCASES += check_ret.tst +TESTCASES += check_swap.tst +TESTCASES += check_scc.tst +TESTCASES += check_subc.tst +TESTCASES += check_subq.tst +TESTCASES += check_subr.tst +TESTCASES += check_subm.tst +TESTCASES += check_glibc_kernelversion.tst +TESTCASES += check_xarith.tst + +TESTCASES += check_hello.ctst +TESTCASES += check_stat1.ctst +TESTCASES += check_stat2.ctst +TESTCASES += check_stat3.ctst +TESTCASES += check_stat4.ctst +TESTCASES += check_openpf1.ctst +TESTCASES += check_openpf2.ctst +TESTCASES += check_openpf3.ctst +TESTCASES += check_openpf4.ctst +TESTCASES += check_openpf5.ctst +TESTCASES += check_mapbrk.ctst +TESTCASES += check_mmap1.ctst +TESTCASES += check_mmap2.ctst +TESTCASES += check_mmap3.ctst +TESTCASES += check_sigalrm.ctst +TESTCASES += check_time1.ctst +TESTCASES += check_time2.ctst +TESTCASES += check_settls1.ctst + +TESTCASES += check_gcctorture_pr28634-1.ctst +#TESTCASES += check_gcctorture_pr28634.ctst + +all: build + +%.o: $(SRC_PATH)/tests/tcg/cris/%.c + $(CC) $(CFLAGS) -c $< -o $@ + +%.o: $(SRC_PATH)/tests/tcg/cris/%.s + $(AS) $(ASFLAGS) -c $< -o $@ + +%.tst: %.o + $(CC) $(CFLAGS) $(NOSTDFLAGS) $(LDLIBS) $(NOSTDLIBS) $(CRT) $< $(SYS) -o $@ + +%.ctst: %.o + $(CC) $(CFLAGS) $(LDLIBS) $< -o $@ + +build: $(CRT) $(SYS) $(TESTCASES) + +check: $(CRT) $(SYS) $(TESTCASES) + @echo -e "\nQEMU simulator." + for case in $(TESTCASES); do \ + echo -n "$$case "; \ + $(SIM) ./$$case; \ + done +check-g: $(CRT) $(SYS) $(TESTCASES) + @echo -e "\nGDB simulator." + @for case in $(TESTCASES); do \ + echo -n "$$case "; \ + $(SIMG) $$case; \ + done + +clean: + $(RM) -fr $(TESTCASES) $(CRT) $(SYS) diff --git a/qemu/tests/tcg/cris/README b/qemu/tests/tcg/cris/README new file mode 100644 index 000000000..2e65a76f1 --- /dev/null +++ b/qemu/tests/tcg/cris/README @@ -0,0 +1 @@ +Test-suite for the cris port. Heavily based on the test-suite for the CRIS port of sim by Hans-Peter Nilsson. diff --git a/qemu/tests/tcg/cris/check_abs.c b/qemu/tests/tcg/cris/check_abs.c new file mode 100644 index 000000000..9770a8d9e --- /dev/null +++ b/qemu/tests/tcg/cris/check_abs.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +static inline int cris_abs(int n) +{ + int r; + asm ("abs\t%1, %0\n" : "=r" (r) : "r" (n)); + return r; +} + +static inline void +verify_abs(int val, int res, + const int n, const int z, const int v, const int c) +{ + int r; + + cris_tst_cc_init(); + r = cris_abs(val); + cris_tst_cc(n, z, v, c); + if (r != res) + err(); +} + +int main(void) +{ + verify_abs(-1, 1, 0, 0, 0, 0); + verify_abs(0x80000000, 0x80000000, 1, 0, 0, 0); + verify_abs(0x7fffffff, 0x7fffffff, 0, 0, 0, 0); + verify_abs(42, 42, 0, 0, 0, 0); + verify_abs(1, 1, 0, 0, 0, 0); + verify_abs(0xffff, 0xffff, 0, 0, 0, 0); + verify_abs(0xffff, 0xffff, 0, 0, 0, 0); + verify_abs(-31, 0x1f, 0, 0, 0, 0); + verify_abs(0, 0, 0, 1, 0, 0); + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_addc.c b/qemu/tests/tcg/cris/check_addc.c new file mode 100644 index 000000000..facd1bea2 --- /dev/null +++ b/qemu/tests/tcg/cris/check_addc.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +static inline int cris_addc(int a, const int b) +{ + asm ("addc\t%1, %0\n" : "+r" (a) : "r" (b)); + return a; +} + +#define verify_addc(a, b, res, n, z, v, c) \ +{ \ + int r; \ + r = cris_addc((a), (b)); \ + cris_tst_cc((n), (z), (v), (c)); \ + if (r != (res)) \ + err(); \ +} + +int main(void) +{ + cris_tst_cc_init(); + asm volatile ("clearf cz"); + verify_addc(0, 0, 0, 0, 0, 0, 0); + + cris_tst_cc_init(); + asm volatile ("setf z"); + verify_addc(0, 0, 0, 0, 1, 0, 0); + + cris_tst_cc_init(); + asm volatile ("setf cz"); + verify_addc(0, 0, 1, 0, 0, 0, 0); + cris_tst_cc_init(); + asm volatile ("clearf c"); + verify_addc(-1, 2, 1, 0, 0, 0, 1); + + cris_tst_cc_init(); + asm volatile ("clearf nzv"); + asm volatile ("setf c"); + verify_addc(-1, 2, 2, 0, 0, 0, 1); + + cris_tst_cc_init(); + asm volatile ("setf c"); + verify_addc(0xffff, 0xffff, 0x1ffff, 0, 0, 0, 0); + + cris_tst_cc_init(); + asm volatile ("clearf nzvc"); + verify_addc(-1, -1, 0xfffffffe, 1, 0, 0, 1); + + cris_tst_cc_init(); + asm volatile ("setf c"); + verify_addc(0x78134452, 0x5432f789, 0xcc463bdc, 1, 0, 1, 0); + + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_addcm.c b/qemu/tests/tcg/cris/check_addcm.c new file mode 100644 index 000000000..7928bc999 --- /dev/null +++ b/qemu/tests/tcg/cris/check_addcm.c @@ -0,0 +1,85 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +/* need to avoid acr as source here. */ +static inline int cris_addc_m(int a, const int *b) +{ + asm volatile ("addc [%1], %0\n" : "+r" (a) : "r" (b)); + return a; +} + +/* 'b' is a crisv32 constrain to avoid postinc with $acr. */ +static inline int cris_addc_pi_m(int a, int **b) +{ + asm volatile ("addc [%1+], %0\n" : "+r" (a), "+b" (*b)); + return a; +} + +#define verify_addc_m(a, b, res, n, z, v, c) \ +{ \ + int r; \ + r = cris_addc_m((a), (b)); \ + cris_tst_cc((n), (z), (v), (c)); \ + if (r != (res)) \ + err(); \ +} + +#define verify_addc_pi_m(a, b, res, n, z, v, c) \ +{ \ + int r; \ + r = cris_addc_pi_m((a), (b)); \ + cris_tst_cc((n), (z), (v), (c)); \ + if (r != (res)) \ + err(); \ +} + +int x[] = { 0, 0, 2, -1, 0xffff, -1, 0x5432f789}; + +int main(void) +{ + int *p = (void *)&x[0]; +#if 1 + cris_tst_cc_init(); + asm volatile ("clearf cz"); + verify_addc_m(0, p, 0, 0, 0, 0, 0); + + cris_tst_cc_init(); + asm volatile ("setf z"); + verify_addc_m(0, p, 0, 0, 1, 0, 0); + + cris_tst_cc_init(); + asm volatile ("setf c"); + verify_addc_m(0, p, 1, 0, 0, 0, 0); + + cris_tst_cc_init(); + asm volatile ("clearf c"); + verify_addc_pi_m(0, &p, 0, 0, 1, 0, 0); + + p = &x[1]; + cris_tst_cc_init(); + asm volatile ("setf c"); + verify_addc_pi_m(0, &p, 1, 0, 0, 0, 0); + + if (p != &x[2]) + err(); + + cris_tst_cc_init(); + asm volatile ("clearf c"); + verify_addc_pi_m(-1, &p, 1, 0, 0, 0, 1); + + if (p != &x[3]) + err(); +#endif + p = &x[3]; + /* TODO: investigate why this one fails. */ + cris_tst_cc_init(); + asm volatile ("setf c"); + verify_addc_m(2, p, 2, 0, 0, 0, 1); + p += 4; + + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_addi.s b/qemu/tests/tcg/cris/check_addi.s new file mode 100644 index 000000000..a00dec02a --- /dev/null +++ b/qemu/tests/tcg/cris/check_addi.s @@ -0,0 +1,57 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 0\n1\n2\n4\nbe02460f\n69d035a6\nc16c14d4\n + + .include "testutils.inc" + start + moveq 0,r3 + moveq 0,r4 + clearf zcvn + addi r4.b,r3 + test_cc 0 0 0 0 + checkr3 0 + + moveq 0,r3 + moveq 1,r4 + setf zcvn + addi r4.b,r3 + test_cc 1 1 1 1 + checkr3 1 + + moveq 0,r3 + moveq 1,r4 + setf cv + clearf zn + addi r4.w,r3 + test_cc 0 0 1 1 + checkr3 2 + + moveq 0,r3 + moveq 1,r4 + clearf cv + setf zn + addi r4.d,r3 + test_cc 1 1 0 0 + checkr3 4 + + move.d 0x12345678,r3 + move.d 0xabcdef97,r4 + clearf cn + setf zv + addi r4.b,r3 + test_cc 0 1 1 0 + checkr3 be02460f + + move.d 0x12345678,r3 + move.d 0xabcdef97,r4 + setf cn + clearf zv + addi r4.w,r3 + test_cc 1 0 0 1 + checkr3 69d035a6 + + move.d 0x12345678,r3 + move.d 0xabcdef97,r4 + addi r4.d,r3 + checkr3 c16c14d4 + + quit diff --git a/qemu/tests/tcg/cris/check_addiv32.s b/qemu/tests/tcg/cris/check_addiv32.s new file mode 100644 index 000000000..20ba25d21 --- /dev/null +++ b/qemu/tests/tcg/cris/check_addiv32.s @@ -0,0 +1,62 @@ +# mach: crisv32 +# output: 4455aa77\n4455aa77\nee19ccff\nff22\n4455aa77\nff224455\n55aa77ff\n + + .include "testutils.inc" + .data +x: + .dword 0x55aa77ff + .dword 0xccff2244 + .dword 0x88ccee19 + + start + setf cv + moveq -1,r0 + move.d x-32768,r5 + move.d 32769,r6 + addi r6.b,r5,acr + test_cc 0 0 1 1 + move.d [acr],r3 + checkr3 4455aa77 + + addu.w 32771,r5 + setf znvc + moveq -1,r8 + addi r8.w,r5,acr + test_cc 1 1 1 1 + move.d [acr],r3 + checkr3 4455aa77 + + moveq 5,r10 + clearf znvc + addi r10.b,acr,acr + test_cc 0 0 0 0 + move.d [acr],r3 + checkr3 ee19ccff + + subq 1,r5 + move.d r5,r8 + subq 1,r8 + moveq 1,r9 + addi r9.d,r8,acr + test_cc 0 0 0 0 + movu.w [acr],r3 + checkr3 ff22 + + moveq -2,r11 + addi r11.w,acr,acr + move.d [acr],r3 + checkr3 4455aa77 + + moveq 5,r9 + addi r9.d,acr,acr + subq 18,acr + move.d [acr],r3 + checkr3 ff224455 + + move.d -76789888/4,r12 + addi r12.d,r5,acr + add.d 76789886,acr + move.d [acr],r3 + checkr3 55aa77ff + + quit diff --git a/qemu/tests/tcg/cris/check_addm.s b/qemu/tests/tcg/cris/check_addm.s new file mode 100644 index 000000000..efece9f53 --- /dev/null +++ b/qemu/tests/tcg/cris/check_addm.s @@ -0,0 +1,96 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n1fffe\nfffffffe\ncc463bdb\nffff0001\n1\nfffe\nfedafffe\n78133bdb\nffffff01\n1\nfe\nfeda49fe\n781344db\n781344d0\n + + .include "testutils.inc" + .data +x: + .dword 2,-1,0xffff,-1,0x5432f789 + .word 2,-1,0xffff,0xf789 + .byte 2,0xff,0x89 + .byte 0x7e + + start + moveq -1,r3 + move.d x,r5 + add.d [r5+],r3 + test_cc 0 0 0 1 + checkr3 1 + + moveq 2,r3 + add.d [r5],r3 + test_cc 0 0 0 1 + addq 4,r5 + checkr3 1 + + move.d 0xffff,r3 + add.d [r5+],r3 + test_cc 0 0 0 0 + checkr3 1fffe + + moveq -1,r3 + add.d [r5+],r3 + test_cc 1 0 0 1 + checkr3 fffffffe + + move.d 0x78134452,r3 + add.d [r5+],r3 + test_cc 1 0 1 0 + checkr3 cc463bdb + + moveq -1,r3 + add.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 ffff0001 + + moveq 2,r3 + add.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 1 + + move.d 0xffff,r3 + add.w [r5],r3 + test_cc 1 0 0 1 + checkr3 fffe + + move.d 0xfedaffff,r3 + add.w [r5+],r3 + test_cc 1 0 0 1 + checkr3 fedafffe + + move.d 0x78134452,r3 + add.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 78133bdb + + moveq -1,r3 + add.b [r5],r3 + test_cc 0 0 0 1 + addq 1,r5 + checkr3 ffffff01 + + moveq 2,r3 + add.b [r5],r3 + test_cc 0 0 0 1 + checkr3 1 + + move.d 0xff,r3 + add.b [r5],r3 + test_cc 1 0 0 1 + checkr3 fe + + move.d 0xfeda49ff,r3 + add.b [r5+],r3 + test_cc 1 0 0 1 + checkr3 feda49fe + + move.d 0x78134452,r3 + add.b [r5+],r3 + test_cc 1 0 0 0 + checkr3 781344db + + move.d 0x78134452,r3 + add.b [r5],r3 + test_cc 1 0 1 0 + checkr3 781344d0 + + quit diff --git a/qemu/tests/tcg/cris/check_addo.c b/qemu/tests/tcg/cris/check_addo.c new file mode 100644 index 000000000..3d8e789f5 --- /dev/null +++ b/qemu/tests/tcg/cris/check_addo.c @@ -0,0 +1,125 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +/* this would be better to do in asm, it's an orgy in GCC inline asm now. */ + +#define cris_addo_b(o, v) \ + asm volatile ("addo.b\t[%0], %1, $acr\n" : : "r" (o), "r" (v) : "acr"); +#define cris_addo_w(o, v) \ + asm volatile ("addo.w\t[%0], %1, $acr\n" : : "r" (o), "r" (v) : "acr"); +#define cris_addo_d(o, v) \ + asm volatile ("addo.d\t[%0], %1, $acr\n" : : "r" (o), "r" (v) : "acr"); +#define cris_addo_pi_b(o, v) \ + asm volatile ("addo.b\t[%0+], %1, $acr\n" \ + : "+b" (o): "r" (v) : "acr"); +#define cris_addo_pi_w(o, v) \ + asm volatile ("addo.w\t[%0+], %1, $acr\n" \ + : "+b" (o): "r" (v) : "acr"); +#define cris_addo_pi_d(o, v) \ + asm volatile ("addo.d\t[%0+], %1, $acr\n" \ + : "+b" (o): "r" (v) : "acr"); + +struct { + uint32_t v1; + uint16_t v2; + uint32_t v3; + uint8_t v4; + uint8_t v5; + uint16_t v6; + uint32_t v7; +} y = { + 32769, + -1, + 5, + 3, -4, + 2, + -76789887 +}; + +static int x[3] = {0x55aa77ff, 0xccff2244, 0x88ccee19}; + +int main(void) +{ + int *r; + unsigned char *t, *p; + + /* Note, this test-case will trig an unaligned access, partly + to x[0] and to [x1]. */ + t = (unsigned char *)x; + t -= 32768; + p = (unsigned char *) &y.v1; + mb(); /* dont reorder anything beyond here. */ + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addo_pi_d(p, t); + cris_tst_cc(1, 1, 1, 1); + asm volatile ("move.d\t$acr, %0\n" : "=r" (r)); + if (*r != 0x4455aa77) + err(); + + + t += 32770; + mb(); /* dont reorder anything beyond here. */ + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addo_pi_w(p, t); + cris_tst_cc(1, 1, 1, 1); + asm volatile ("move.d\t$acr, %0\n" : "=r" (r)); + if (*r != 0x4455aa77) + err(); + + mb(); /* dont reorder anything beyond here. */ + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addo_d(p, r); + cris_tst_cc(1, 1, 1, 1); + p += 4; + asm volatile ("move.d\t$acr, %0\n" : "=r" (r)); + if (*r != 0xee19ccff) + err(); + + mb(); /* dont reorder anything beyond here. */ + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addo_pi_b(p, t); + cris_tst_cc(0, 0, 0, 0); + asm volatile ("move.d\t$acr, %0\n" : "=r" (r)); + if (*(uint16_t*)r != 0xff22) + err(); + + mb(); /* dont reorder anything beyond here. */ + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addo_b(p, r); + cris_tst_cc(1, 1, 1, 1); + p += 1; + asm volatile ("move.d\t$acr, %0\n" : "=r" (r)); + if (*r != 0x4455aa77) + err(); + + mb(); /* dont reorder anything beyond here. */ + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addo_w(p, r); + cris_tst_cc(1, 1, 1, 1); + p += 2; + asm volatile ("move.d\t$acr, %0\n" : "=r" (r)); + if (*r != 0xff224455) + err(); + + mb(); /* dont reorder anything beyond here. */ + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addo_pi_d(p, t); + cris_tst_cc(0, 0, 0, 0); + asm volatile ("move.d\t$acr, %0\n" : "=r" (r)); + r = (void*)(((char *)r) + 76789885); + if (*r != 0x55aa77ff) + err(); + + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_addoq.c b/qemu/tests/tcg/cris/check_addoq.c new file mode 100644 index 000000000..ed509e27e --- /dev/null +++ b/qemu/tests/tcg/cris/check_addoq.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +/* this would be better to do in asm, it's an orgy in GCC inline asm now. */ + +/* ACR will be clobbered. */ +#define cris_addoq(o, v) \ + asm volatile ("addoq\t%1, %0, $acr\n" : : "r" (v), "i" (o) : "acr"); + + +int main(void) +{ + int x[3] = {0x55aa77ff, 0xccff2244, 0x88ccee19}; + int *p, *t = x + 1; + + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addoq(0, t); + cris_tst_cc(1, 1, 1, 1); + asm volatile ("move.d\t$acr, %0\n" : "=r" (p)); + if (*p != 0xccff2244) + err(); + + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_addoq(4, t); + cris_tst_cc(0, 0, 0, 0); + asm volatile ("move.d\t$acr, %0\n" : "=r" (p)); + if (*p != 0x88ccee19) + err(); + + cris_tst_cc_init(); + asm volatile ("clearf\tzvnc\n"); + cris_addoq(-8, t + 1); + cris_tst_cc(0, 0, 0, 0); + asm volatile ("move.d\t$acr, %0\n" : "=r" (p)); + if (*p != 0x55aa77ff) + err(); + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_addq.s b/qemu/tests/tcg/cris/check_addq.s new file mode 100644 index 000000000..e6f874f9b --- /dev/null +++ b/qemu/tests/tcg/cris/check_addq.s @@ -0,0 +1,47 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: ffffffff\n0\n1\n100\n10000\n47\n67\na6\n80000001\n + + .include "testutils.inc" + start + moveq -2,r3 + addq 1,r3 + test_cc 1 0 0 0 + checkr3 ffffffff + + addq 1,r3 + test_cc 0 1 0 1 + checkr3 0 + + addq 1,r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d 0xff,r3 + addq 1,r3 + test_cc 0 0 0 0 + checkr3 100 + + move.d 0xffff,r3 + addq 1,r3 + test_cc 0 0 0 0 + checkr3 10000 + + move.d 0x42,r3 + addq 5,r3 + test_cc 0 0 0 0 + checkr3 47 + + addq 32,r3 + test_cc 0 0 0 0 + checkr3 67 + + addq 63,r3 + test_cc 0 0 0 0 + checkr3 a6 + + move.d 0x7ffffffe,r3 + addq 3,r3 + test_cc 1 0 1 0 + checkr3 80000001 + + quit diff --git a/qemu/tests/tcg/cris/check_addr.s b/qemu/tests/tcg/cris/check_addr.s new file mode 100644 index 000000000..7f55cdc1b --- /dev/null +++ b/qemu/tests/tcg/cris/check_addr.s @@ -0,0 +1,96 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n1fffe\nfffffffe\ncc463bdb\nffff0001\n1\nfffe\nfedafffe\n78133bdb\nffffff01\n1\nfe\nfeda49fe\n781344db\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq 2,r4 + add.d r4,r3 + test_cc 0 0 0 1 + checkr3 1 + + moveq 2,r3 + moveq -1,r4 + add.d r4,r3 + test_cc 0 0 0 1 + checkr3 1 + + move.d 0xffff,r4 + move.d r4,r3 + add.d r4,r3 + test_cc 0 0 0 0 + checkr3 1fffe + + moveq -1,r4 + move.d r4,r3 + add.d r4,r3 + test_cc 1 0 0 1 + checkr3 fffffffe + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + add.d r4,r3 + test_cc 1 0 1 0 + checkr3 cc463bdb + + moveq -1,r3 + moveq 2,r4 + add.w r4,r3 + test_cc 0 0 0 1 + checkr3 ffff0001 + + moveq 2,r3 + moveq -1,r4 + add.w r4,r3 + test_cc 0 0 0 1 + checkr3 1 + + move.d 0xffff,r4 + move.d r4,r3 + add.w r4,r3 + test_cc 1 0 0 1 + checkr3 fffe + + move.d 0xfedaffff,r4 + move.d r4,r3 + add.w r4,r3 + test_cc 1 0 0 1 + checkr3 fedafffe + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + add.w r4,r3 + test_cc 0 0 0 1 + checkr3 78133bdb + + moveq -1,r3 + moveq 2,r4 + add.b r4,r3 + test_cc 0 0 0 1 + checkr3 ffffff01 + + moveq 2,r3 + moveq -1,r4 + add.b r4,r3 + test_cc 0 0 0 1 + checkr3 1 + + move.d 0xff,r4 + move.d r4,r3 + add.b r4,r3 + test_cc 1 0 0 1 + checkr3 fe + + move.d 0xfeda49ff,r4 + move.d r4,r3 + add.b r4,r3 + test_cc 1 0 0 1 + checkr3 feda49fe + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + add.b r4,r3 + test_cc 1 0 0 0 + checkr3 781344db + + quit diff --git a/qemu/tests/tcg/cris/check_addxc.s b/qemu/tests/tcg/cris/check_addxc.s new file mode 100644 index 000000000..09c8355bf --- /dev/null +++ b/qemu/tests/tcg/cris/check_addxc.s @@ -0,0 +1,91 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n101\n10001\n100fe\n1fffe\nfffe\nfffe\nfffffffe\nfe\nfffffffe\n781344db\n781343db\n78143bdb\n78133bdb\n800000ed\n0\n + + .include "testutils.inc" + start + moveq 2,r3 + adds.b 0xff,r3 + test_cc 0 0 0 1 + checkr3 1 + + moveq 2,r3 + adds.w 0xffff,r3 + test_cc 0 0 0 1 + checkr3 1 + + moveq 2,r3 + addu.b 0xff,r3 + checkr3 101 + + moveq 2,r3 + move.d 0xffffffff,r4 + addu.w -1,r3 + test_cc 0 0 0 0 + checkr3 10001 + + move.d 0xffff,r3 + addu.b -1,r3 + test_cc 0 0 0 0 + checkr3 100fe + + move.d 0xffff,r3 + addu.w -1,r3 + test_cc 0 0 0 0 + checkr3 1fffe + + move.d 0xffff,r3 + adds.b 0xff,r3 + test_cc 0 0 0 1 + checkr3 fffe + + move.d 0xffff,r3 + adds.w 0xffff,r3 + test_cc 0 0 0 1 + checkr3 fffe + + moveq -1,r3 + adds.b 0xff,r3 + test_cc 1 0 0 1 + checkr3 fffffffe + + moveq -1,r3 + adds.w 0xff,r3 + test_cc 0 0 0 1 + checkr3 fe + + moveq -1,r3 + adds.w 0xffff,r3 + test_cc 1 0 0 1 + checkr3 fffffffe + + move.d 0x78134452,r3 + addu.b 0x89,r3 + test_cc 0 0 0 0 + checkr3 781344db + + move.d 0x78134452,r3 + adds.b 0x89,r3 + test_cc 0 0 0 1 + checkr3 781343db + + move.d 0x78134452,r3 + addu.w 0xf789,r3 + test_cc 0 0 0 0 + checkr3 78143bdb + + move.d 0x78134452,r3 + adds.w 0xf789,r3 + test_cc 0 0 0 1 + checkr3 78133bdb + + move.d 0x7fffffee,r3 + addu.b 0xff,r3 + test_cc 1 0 1 0 + checkr3 800000ed + + move.d 0x1,r3 + adds.w 0xffff,r3 + test_cc 0 1 0 1 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_addxm.s b/qemu/tests/tcg/cris/check_addxm.s new file mode 100644 index 000000000..7563494b9 --- /dev/null +++ b/qemu/tests/tcg/cris/check_addxm.s @@ -0,0 +1,106 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n101\n10001\n100fe\n1fffe\nfffe\nfffe\nfffffffe\nfe\nfffffffe\n781344db\n781343db\n78143bdb\n78133bdb\n800000ed\n0\n + + .include "testutils.inc" + .data +x: + .byte 0xff + .word 0xffff + .word 0xff + .word 0xffff + .byte 0x89 + .word 0xf789 + .byte 0xff + .word 0xffff + + start + moveq 2,r3 + move.d x,r5 + adds.b [r5+],r3 + test_cc 0 0 0 1 + checkr3 1 + + moveq 2,r3 + adds.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 1 + + moveq 2,r3 + subq 3,r5 + addu.b [r5+],r3 + test_cc 0 0 0 0 + checkr3 101 + + moveq 2,r3 + addu.w [r5+],r3 + subq 3,r5 + test_cc 0 0 0 0 + checkr3 10001 + + move.d 0xffff,r3 + addu.b [r5],r3 + test_cc 0 0 0 0 + checkr3 100fe + + move.d 0xffff,r3 + addu.w [r5],r3 + test_cc 0 0 0 0 + checkr3 1fffe + + move.d 0xffff,r3 + adds.b [r5],r3 + test_cc 0 0 0 1 + checkr3 fffe + + move.d 0xffff,r3 + adds.w [r5],r3 + test_cc 0 0 0 1 + checkr3 fffe + + moveq -1,r3 + adds.b [r5],r3 + test_cc 1 0 0 1 + addq 3,r5 + checkr3 fffffffe + + moveq -1,r3 + adds.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 fe + + moveq -1,r3 + adds.w [r5+],r3 + test_cc 1 0 0 1 + checkr3 fffffffe + + move.d 0x78134452,r3 + addu.b [r5],r3 + test_cc 0 0 0 0 + checkr3 781344db + + move.d 0x78134452,r3 + adds.b [r5+],r3 + test_cc 0 0 0 1 + checkr3 781343db + + move.d 0x78134452,r3 + addu.w [r5],r3 + test_cc 0 0 0 0 + checkr3 78143bdb + + move.d 0x78134452,r3 + adds.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 78133bdb + + move.d 0x7fffffee,r3 + addu.b [r5+],r3 + test_cc 1 0 1 0 + checkr3 800000ed + + move.d 0x1,r3 + adds.w [r5+],r3 + test_cc 0 1 0 1 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_addxr.s b/qemu/tests/tcg/cris/check_addxr.s new file mode 100644 index 000000000..7f55cdc1b --- /dev/null +++ b/qemu/tests/tcg/cris/check_addxr.s @@ -0,0 +1,96 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n1fffe\nfffffffe\ncc463bdb\nffff0001\n1\nfffe\nfedafffe\n78133bdb\nffffff01\n1\nfe\nfeda49fe\n781344db\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq 2,r4 + add.d r4,r3 + test_cc 0 0 0 1 + checkr3 1 + + moveq 2,r3 + moveq -1,r4 + add.d r4,r3 + test_cc 0 0 0 1 + checkr3 1 + + move.d 0xffff,r4 + move.d r4,r3 + add.d r4,r3 + test_cc 0 0 0 0 + checkr3 1fffe + + moveq -1,r4 + move.d r4,r3 + add.d r4,r3 + test_cc 1 0 0 1 + checkr3 fffffffe + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + add.d r4,r3 + test_cc 1 0 1 0 + checkr3 cc463bdb + + moveq -1,r3 + moveq 2,r4 + add.w r4,r3 + test_cc 0 0 0 1 + checkr3 ffff0001 + + moveq 2,r3 + moveq -1,r4 + add.w r4,r3 + test_cc 0 0 0 1 + checkr3 1 + + move.d 0xffff,r4 + move.d r4,r3 + add.w r4,r3 + test_cc 1 0 0 1 + checkr3 fffe + + move.d 0xfedaffff,r4 + move.d r4,r3 + add.w r4,r3 + test_cc 1 0 0 1 + checkr3 fedafffe + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + add.w r4,r3 + test_cc 0 0 0 1 + checkr3 78133bdb + + moveq -1,r3 + moveq 2,r4 + add.b r4,r3 + test_cc 0 0 0 1 + checkr3 ffffff01 + + moveq 2,r3 + moveq -1,r4 + add.b r4,r3 + test_cc 0 0 0 1 + checkr3 1 + + move.d 0xff,r4 + move.d r4,r3 + add.b r4,r3 + test_cc 1 0 0 1 + checkr3 fe + + move.d 0xfeda49ff,r4 + move.d r4,r3 + add.b r4,r3 + test_cc 1 0 0 1 + checkr3 feda49fe + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + add.b r4,r3 + test_cc 1 0 0 0 + checkr3 781344db + + quit diff --git a/qemu/tests/tcg/cris/check_andc.s b/qemu/tests/tcg/cris/check_andc.s new file mode 100644 index 000000000..a947b773c --- /dev/null +++ b/qemu/tests/tcg/cris/check_andc.s @@ -0,0 +1,80 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 2\n2\nffff\nffffffff\n50124400\nffff0002\n2\nfffff\nfedaff0f\n78134400\nffffff02\n2\nf02\n78134401\n78134400\n + + .include "testutils.inc" + start + moveq -1,r3 + and.d 2,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + and.d -1,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + and.d 0xffff,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r3 + and.d -1,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x78134452,r3 + and.d 0x5432f789,r3 + test_move_cc 0 0 0 0 + checkr3 50124400 + + moveq -1,r3 + and.w 2,r3 + test_move_cc 0 0 0 0 + checkr3 ffff0002 + + moveq 2,r3 + and.w -1,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xfffff,r3 + and.w 0xffff,r3 + test_move_cc 1 0 0 0 + checkr3 fffff + + move.d 0xfedaffaf,r3 + and.w 0xff5f,r3 + test_move_cc 1 0 0 0 + checkr3 fedaff0f + + move.d 0x78134452,r3 + and.w 0xf789,r3 + test_move_cc 0 0 0 0 + checkr3 78134400 + + moveq -1,r3 + and.b 2,r3 + test_move_cc 0 0 0 0 + checkr3 ffffff02 + + moveq 2,r3 + and.b -1,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xfa7,r3 + and.b 0x5a,r3 + test_move_cc 0 0 0 0 + checkr3 f02 + + move.d 0x78134453,r3 + and.b 0x89,r3 + test_move_cc 0 0 0 0 + checkr3 78134401 + + and.b 0,r3 + test_move_cc 0 1 0 0 + checkr3 78134400 + + quit diff --git a/qemu/tests/tcg/cris/check_andm.s b/qemu/tests/tcg/cris/check_andm.s new file mode 100644 index 000000000..93858863f --- /dev/null +++ b/qemu/tests/tcg/cris/check_andm.s @@ -0,0 +1,90 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 2\n2\nffff\nffffffff\n50124400\nffff0002\n2\nfffff\nfedaff0f\n78134400\nffffff02\n2\nf02\n78134401\n78134400\n + + .include "testutils.inc" + .data +x: + .dword 2,-1,0xffff,-1,0x5432f789 + .word 2,-1,0xffff,0xff5f,0xf789 + .byte 2,-1,0x5a,0x89,0 + + start + moveq -1,r3 + move.d x,r5 + and.d [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + and.d [r5],r3 + test_move_cc 0 0 0 0 + addq 4,r5 + checkr3 2 + + move.d 0xffff,r3 + and.d [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r3 + and.d [r5+],r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x78134452,r3 + and.d [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 50124400 + + moveq -1,r3 + and.w [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 ffff0002 + + moveq 2,r3 + and.w [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xfffff,r3 + and.w [r5],r3 + test_move_cc 1 0 0 0 + addq 2,r5 + checkr3 fffff + + move.d 0xfedaffaf,r3 + and.w [r5+],r3 + test_move_cc 1 0 0 0 + checkr3 fedaff0f + + move.d 0x78134452,r3 + and.w [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 78134400 + + moveq -1,r3 + and.b [r5],r3 + test_move_cc 0 0 0 0 + addq 1,r5 + checkr3 ffffff02 + + moveq 2,r3 + and.b [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xfa7,r3 + and.b [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 f02 + + move.d 0x78134453,r3 + and.b [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 78134401 + + and.b [r5],r3 + test_move_cc 0 1 0 0 + checkr3 78134400 + + quit diff --git a/qemu/tests/tcg/cris/check_andq.s b/qemu/tests/tcg/cris/check_andq.s new file mode 100644 index 000000000..55aa7b060 --- /dev/null +++ b/qemu/tests/tcg/cris/check_andq.s @@ -0,0 +1,46 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 2\n2\nffff\nffffffff\n1f\nffffffe0\n78134452\n0\n + + .include "testutils.inc" + start + moveq -1,r3 + andq 2,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + andq -1,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + andq -1,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r3 + andq -1,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + andq 31,r3 + test_move_cc 0 0 0 0 + checkr3 1f + + moveq -1,r3 + andq -32,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffe0 + + move.d 0x78134457,r3 + andq -14,r3 + test_move_cc 0 0 0 0 + checkr3 78134452 + + moveq 0,r3 + andq -14,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_andr.s b/qemu/tests/tcg/cris/check_andr.s new file mode 100644 index 000000000..61aa1dc32 --- /dev/null +++ b/qemu/tests/tcg/cris/check_andr.s @@ -0,0 +1,95 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 2\n2\nffff\nffffffff\n50124400\nffff0002\n2\nfffff\nfedaff0f\n78134400\nffffff02\n2\nf02\n78134401\n78134400\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq 2,r4 + and.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + moveq -1,r4 + and.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r4 + move.d r4,r3 + and.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r4 + move.d r4,r3 + and.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + and.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 50124400 + + moveq -1,r3 + moveq 2,r4 + and.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff0002 + + moveq 2,r3 + moveq -1,r4 + and.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xfffff,r3 + move.d 0xffff,r4 + and.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 fffff + + move.d 0xfedaffaf,r3 + move.d 0xff5f,r4 + and.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 fedaff0f + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + and.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 78134400 + + moveq -1,r3 + moveq 2,r4 + and.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffffff02 + + moveq 2,r3 + moveq -1,r4 + and.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0x5a,r4 + move.d 0xfa7,r3 + and.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 f02 + + move.d 0x5432f789,r4 + move.d 0x78134453,r3 + and.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 78134401 + + moveq 0,r7 + and.b r7,r3 + test_move_cc 0 1 0 0 + checkr3 78134400 + + quit diff --git a/qemu/tests/tcg/cris/check_asr.s b/qemu/tests/tcg/cris/check_asr.s new file mode 100644 index 000000000..0a02ae6f7 --- /dev/null +++ b/qemu/tests/tcg/cris/check_asr.s @@ -0,0 +1,230 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: ffffffff\n1\nffffffff\nffffffff\n5a67f\nffffffff\nffffffff\nffffffff\nf699fc67\nffffffff\n1\nffffffff\nffffffff\n5a67f\nda67ffff\nda67ffff\nda67ffff\nda67fc67\nffffffff\nffffffff\n1\nffffffff\nffffffff\n5a670007\nda67f1ff\nda67f1ff\nda67f1ff\nda67f1e7\nffffffff\nffffffff\n1\nffffffff\nffffffff\nffffffff\n5a67f1ff\n5a67f1f9\n0\n5a670000\n + + .include "testutils.inc" + start + moveq -1,r3 + asrq 0,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + asrq 1,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + asrq 31,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + asrq 15,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x5a67f19f,r3 + asrq 12,r3 + test_move_cc 0 0 0 0 + checkr3 5a67f + + move.d 0xda67f19f,r3 + move.d 31,r4 + asr.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0xda67f19f,r3 + move.d 32,r4 + asr.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0xda67f19f,r3 + move.d 33,r4 + asr.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0xda67f19f,r3 + move.d 66,r4 + asr.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 f699fc67 + + moveq -1,r3 + moveq 0,r4 + asr.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + moveq 1,r4 + asr.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + moveq 31,r4 + asr.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + moveq 15,r4 + asr.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x5a67f19f,r3 + moveq 12,r4 + asr.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 5a67f + + move.d 0xda67f19f,r3 + move.d 31,r4 + asr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67ffff + + move.d 0xda67f19f,r3 + move.d 32,r4 + asr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67ffff + + move.d 0xda67f19f,r3 + move.d 33,r4 + asr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67ffff + + move.d 0xda67f19f,r3 + move.d 66,r4 + asr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67fc67 + + moveq -1,r3 + moveq 0,r4 + asr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + moveq 1,r4 + asr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + moveq 1,r4 + asr.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + moveq 31,r4 + asr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + moveq 15,r4 + asr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x5a67719f,r3 + moveq 12,r4 + asr.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 5a670007 + + move.d 0xda67f19f,r3 + move.d 31,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67f1ff + + move.d 0xda67f19f,r3 + move.d 32,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67f1ff + + move.d 0xda67f19f,r3 + move.d 33,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67f1ff + + move.d 0xda67f19f,r3 + move.d 66,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67f1e7 + + moveq -1,r3 + moveq 0,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + moveq 1,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + moveq 1,r4 + asr.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + moveq 31,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + moveq 15,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + moveq 7,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + +; FIXME: was wrong. + move.d 0x5a67f19f,r3 + moveq 12,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 5a67f1ff + +; FIXME: was wrong. + move.d 0x5a67f19f,r3 + moveq 4,r4 + asr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 5a67f1f9 + + move.d 0x5a67f19f,r3 + asrq 31,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0x5a67419f,r3 + moveq 16,r4 + asr.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 5a670000 + + quit diff --git a/qemu/tests/tcg/cris/check_ba.s b/qemu/tests/tcg/cris/check_ba.s new file mode 100644 index 000000000..873a4086c --- /dev/null +++ b/qemu/tests/tcg/cris/check_ba.s @@ -0,0 +1,93 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: a\n + + + .set smalloffset,0 + .set largeoffset,0 + + + .macro fail + jump _fail + .endm + + .global main +main: + moveq 0,$r3 + +; Short forward branch. + ba 0f + addq 1,$r3 + fail + +; Max short forward branch. +1: + ba 2f + addq 1,$r3 + fail + +; Short backward branch. +0: + ba 1b + addq 1,$r3 + fail + + .space 254-2+smalloffset+1b-.,0 + moveq 0,$r3 + +2: +; Transit branch (long). + ba 3f + addq 1,$r3 + fail + + moveq 0,$r3 +4: +; Long forward branch. + ba 5f + addq 1,$r3 + fail + + .space 256-2-smalloffset+4b-.,0 + + moveq 0,$r3 + +; Max short backward branch. +3: + ba 4b + addq 1,$r3 + fail + +5: +; Max long forward branch. + ba 6f + addq 1,$r3 + fail + + .space 32766+largeoffset-2+5b-.,0 + + moveq 0,$r3 +6: +; Transit branch. + ba 7f + addq 1,$r3 + fail + + moveq 0,$r3 +9: + jsr pass + nop + +; Transit branch. + moveq 0,$r3 +7: + ba 8f + addq 1,$r3 + fail + + .space 32768-largeoffset+9b-.,0 + +8: +; Max long backward branch. + ba 9b + addq 1,$r3 + fail diff --git a/qemu/tests/tcg/cris/check_bas.s b/qemu/tests/tcg/cris/check_bas.s new file mode 100644 index 000000000..11929d420 --- /dev/null +++ b/qemu/tests/tcg/cris/check_bas.s @@ -0,0 +1,102 @@ +# mach: crisv32 +# output: 0\n0\n0\nfb349abc\n0\n12124243\n0\n0\neab5baad\n0\nefb37832\n + + .include "testutils.inc" + start +x: + setf zncv + bsr 0f + nop +0: + test_cc 1 1 1 1 + move srp,r3 + sub.d 0b,r3 + checkr3 0 + + bas 1f,mof + moveq 0,r0 +6: + nop + quit + +2: + move srp,r3 + sub.d 3f,r3 + checkr3 0 + move srp,r4 + subq 4,r4 + move.d [r4],r3 + checkr3 fb349abc + + basc 4f,mof + nop + .dword 0x12124243 +7: + nop + quit + +8: + move mof,r3 + sub.d 7f,r3 + checkr3 0 + + move mof,r4 + subq 4,r4 + move.d [r4],r3 + checkr3 eab5baad + + jasc 9f,mof + nop + .dword 0xefb37832 +0: + quit + + quit +9: + move mof,r3 + sub.d 0b,r3 + checkr3 0 + + move mof,r4 + subq 4,r4 + move.d [r4],r3 + checkr3 efb37832 + + quit + +4: + move mof,r3 + sub.d 7b,r3 + checkr3 0 + move mof,r4 + subq 4,r4 + move.d [r4],r3 + checkr3 12124243 + basc 5f,bz + moveq 0,r3 + .dword 0x7634aeba + quit + + .space 32770,0 +1: + move mof,r3 + sub.d 6b,r3 + checkr3 0 + + bsrc 2b + nop + .dword 0xfb349abc +3: + + quit + +5: + move mof,r3 + sub.d 7b,r3 + checkr3 0 + move.d 8b,r6 + jasc r6,mof + nop + .dword 0xeab5baad +7: + quit diff --git a/qemu/tests/tcg/cris/check_bcc.s b/qemu/tests/tcg/cris/check_bcc.s new file mode 100644 index 000000000..c57ffa6fa --- /dev/null +++ b/qemu/tests/tcg/cris/check_bcc.s @@ -0,0 +1,197 @@ + .global main + .type main, @function +main: + clearf nzvc + setf nzv + bcc 0f + addq 1, $r3 + jump dofail + +0: + clearf nzvc + setf nzv + bcs dofail + addq 1,$r3 + + clearf nzvc + setf ncv + bne 1f + addq 1, $r3 + +fail: +dofail: + jump _fail + +1: + clearf nzvc + setf ncv + beq dofail + addq 1,$r3 + + clearf nzvc + setf ncz + bvc 2f + addq 1,$r3 + jump dofail + +2: + clearf nzvc + setf ncz + bvs dofail + addq 1,$r3 + + clearf nzvc + setf vcz + bpl 3f + addq 1,$r3 + jump fail +3: + clearf nzvc + setf vcz + bmi dofail + addq 1,$r3 + + clearf nzvc + setf nv + bls dofail + addq 1,$r3 + + clearf nzvc + setf nv + bhi 4f + addq 1,$r3 + jump dofail + +4: + clearf nzvc + setf zc + bge 5f + addq 1,$r3 + jump dofail + +5: + clearf nzvc + setf zc + blt dofail + addq 1,$r3 + + clearf nzvc + setf c + bgt 6f + addq 1,$r3 + jump fail + +6: + clearf nzvc + setf c + ble dofail + addq 1,$r3 + +;;;;;;;;;; + + setf nzvc + clearf nzv + bcc dofail + addq 1,$r3 + + setf nzvc + clearf nzv + bcs 0f + addq 1,$r3 + jump fail + +0: + setf nzvc + clearf ncv + bne dofail + addq 1,$r3 + + setf nzvc + clearf ncv + beq 1f + addq 1,$r3 + jump fail + +1: + setf nzvc + clearf ncz + bvc dofail + addq 1,$r3 + + setf nzvc + clearf ncz + bvs 2f + addq 1,$r3 + jump fail + +2: + setf nzvc + clearf vcz + bpl dofail + addq 1,$r3 + + setf nzvc + clearf vcz + bmi 3f + addq 1,$r3 + jump fail + +3: + setf nzvc + clearf nv + bls 4f + addq 1,$r3 + jump fail + +4: + setf nzvc + clearf nv + bhi dofail + addq 1,$r3 + + setf zvc + clearf nzc + bge dofail + addq 1,$r3 + + setf nzc + clearf vzc + blt 5f + addq 1,$r3 + jump fail + +5: + setf nzvc + clearf c + bgt dofail + addq 1,$r3 + + setf nzvc + clearf c + ble 6f + addq 1,$r3 + jump fail + +6: + ; do a forward branch. + ba 2f + nop + .fill 100 +1: + ba 3f + nop + .fill 800 +2: + ba 1b + nop + .fill 1024 +3: + + moveq 31, $r0 +1: bne 1b + subq 1, $r0 + + jsr pass + moveq 0, $r10 + ret + nop diff --git a/qemu/tests/tcg/cris/check_bound.c b/qemu/tests/tcg/cris/check_bound.c new file mode 100644 index 000000000..e8831754e --- /dev/null +++ b/qemu/tests/tcg/cris/check_bound.c @@ -0,0 +1,142 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +static inline int cris_bound_b(int v, int b) +{ + int r = v; + asm ("bound.b\t%1, %0\n" : "+r" (r) : "ri" (b)); + return r; +} + +static inline int cris_bound_w(int v, int b) +{ + int r = v; + asm ("bound.w\t%1, %0\n" : "+r" (r) : "ri" (b)); + return r; +} + +static inline int cris_bound_d(int v, int b) +{ + int r = v; + asm ("bound.d\t%1, %0\n" : "+r" (r) : "ri" (b)); + return r; +} + +int main(void) +{ + int r; + + cris_tst_cc_init(); + r = cris_bound_d(-1, 2); + cris_tst_cc(0, 0, 0, 0); + if (r != 2) + err(); + + cris_tst_cc_init(); + r = cris_bound_d(2, 0xffffffff); + cris_tst_cc(0, 0, 0, 0); + if (r != 2) + err(); + + cris_tst_cc_init(); + r = cris_bound_d(0xffff, 0xffff); + cris_tst_cc(0, 0, 0, 0); + if (r != 0xffff) + err(); + + cris_tst_cc_init(); + r = cris_bound_d(-1, 0xffffffff); + cris_tst_cc(1, 0, 0, 0); + if (r != 0xffffffff) + err(); + + cris_tst_cc_init(); + r = cris_bound_d(0x78134452, 0x5432f789); + cris_tst_cc(0, 0, 0, 0); + if (r != 0x5432f789) + err(); + + cris_tst_cc_init(); + r = cris_bound_w(-1, 2); + cris_tst_cc(0, 0, 0, 0); + if (r != 2) + err(); + + cris_tst_cc_init(); + r = cris_bound_w(-1, 0xffff); + cris_tst_cc(0, 0, 0, 0); + if (r != 0xffff) + err(); + + cris_tst_cc_init(); + r = cris_bound_w(2, 0xffff); + cris_tst_cc(0, 0, 0, 0); + if (r != 2) + err(); + + cris_tst_cc_init(); + r = cris_bound_w(0xfedaffff, 0xffff); + cris_tst_cc(0, 0, 0, 0); + if (r != 0xffff) + err(); + + cris_tst_cc_init(); + r = cris_bound_w(0x78134452, 0xf789); + cris_tst_cc(0, 0, 0, 0); + if (r != 0xf789) + err(); + + cris_tst_cc_init(); + r = cris_bound_b(-1, 2); + cris_tst_cc(0, 0, 0, 0); + if (r != 2) + err(); + + cris_tst_cc_init(); + r = cris_bound_b(2, 0xff); + cris_tst_cc(0, 0, 0, 0); + if (r != 2) + err(); + + cris_tst_cc_init(); + r = cris_bound_b(-1, 0xff); + cris_tst_cc(0, 0, 0, 0); + if (r != 0xff) + err(); + + cris_tst_cc_init(); + r = cris_bound_b(0xff, 0xff); + cris_tst_cc(0, 0, 0, 0); + if (r != 0xff) + err(); + + cris_tst_cc_init(); + r = cris_bound_b(0xfeda49ff, 0xff); + cris_tst_cc(0, 0, 0, 0); + if (r != 0xff) + err(); + + cris_tst_cc_init(); + r = cris_bound_b(0x78134452, 0x89); + cris_tst_cc(0, 0, 0, 0); + if (r != 0x89) + err(); + + cris_tst_cc_init(); + r = cris_bound_w(0x78134452, 0); + cris_tst_cc(0, 1, 0, 0); + if (r != 0) + err(); + + cris_tst_cc_init(); + r = cris_bound_b(0xffff, -1); + cris_tst_cc(0, 0, 0, 0); + if (r != 0xff) + err(); + + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_boundc.s b/qemu/tests/tcg/cris/check_boundc.s new file mode 100644 index 000000000..fb9e5bc90 --- /dev/null +++ b/qemu/tests/tcg/cris/check_boundc.s @@ -0,0 +1,101 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 2\n2\nffff\nffffffff\n5432f789\n2\nffff\n2\nffff\nffff\nf789\n2\n2\nff\nff\nff\n89\n0\nff\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq 2,r4 + bound.d 2,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + bound.d 0xffffffff,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + bound.d 0xffff,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r3 + bound.d 0xffffffff,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x78134452,r3 + bound.d 0x5432f789,r3 + test_move_cc 0 0 0 0 + checkr3 5432f789 + + moveq -1,r3 + bound.w 2,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq -1,r3 + bound.w 0xffff,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq 2,r3 + bound.w 0xffff,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + bound.w 0xffff,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + move.d 0xfedaffff,r3 + bound.w 0xffff,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + move.d 0x78134452,r3 + bound.w 0xf789,r3 + test_move_cc 0 0 0 0 + checkr3 f789 + + moveq -1,r3 + bound.b 2,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + bound.b 0xff,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq -1,r3 + bound.b 0xff,r3 + test_move_cc 0 0 0 0 + checkr3 ff + + move.d 0xff,r3 + bound.b 0xff,r3 + test_move_cc 0 0 0 0 + checkr3 ff + + move.d 0xfeda49ff,r3 + bound.b 0xff,r3 + test_move_cc 0 0 0 0 + checkr3 ff + + move.d 0x78134452,r3 + bound.b 0x89,r3 + test_move_cc 0 0 0 0 + checkr3 89 + + bound.w 0,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0xffff,r3 + bound.b -1,r3 + test_move_cc 0 0 0 0 + checkr3 ff + + quit diff --git a/qemu/tests/tcg/cris/check_boundr.s b/qemu/tests/tcg/cris/check_boundr.s new file mode 100644 index 000000000..5c50cc5f6 --- /dev/null +++ b/qemu/tests/tcg/cris/check_boundr.s @@ -0,0 +1,125 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 2\n2\nffff\nffffffff\n5432f789\n2\n2\nffff\nffff\nffff\nf789\n2\n2\nff\nff\n89\nfeda4953\nfeda4962\n0\n0\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq 2,r4 + bound.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + moveq -1,r4 + bound.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r4 + move.d r4,r3 + bound.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r4 + move.d r4,r3 + bound.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + bound.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 5432f789 + + moveq -1,r3 + moveq 2,r4 + bound.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + moveq -1,r4 + bound.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq -1,r3 + bound.w r3,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + move.d 0xffff,r4 + move.d r4,r3 + bound.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + move.d 0xfedaffff,r4 + move.d r4,r3 + bound.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + bound.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 f789 + + moveq -1,r3 + moveq 2,r4 + bound.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + moveq 2,r3 + moveq -1,r4 + bound.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 2 + + move.d 0xff,r4 + move.d r4,r3 + bound.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 ff + + move.d 0xfeda49ff,r4 + move.d r4,r3 + bound.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 ff + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + bound.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 89 + + move.d 0xfeda4956,r3 + move.d 0xfeda4953,r4 + bound.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 feda4953 + + move.d 0xfeda4962,r3 + move.d 0xfeda4963,r4 + bound.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 feda4962 + + move.d 0xfeda4956,r3 + move.d 0,r4 + bound.d r4,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0xfeda4956,r4 + move.d 0,r3 + bound.d r4,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_btst.s b/qemu/tests/tcg/cris/check_btst.s new file mode 100644 index 000000000..e39fc8f4d --- /dev/null +++ b/qemu/tests/tcg/cris/check_btst.s @@ -0,0 +1,96 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1111\n + + .include "testutils.inc" + start + clearf nzvc + moveq -1,r3 + .if 1 ;..asm.arch.cris.v32 + .else + setf vc + .endif + btstq 0,r3 + test_cc 1 0 0 0 + + moveq 2,r3 + btstq 1,r3 + test_cc 1 0 0 0 + + moveq 4,r3 + btstq 1,r3 + test_cc 0 1 0 0 + + moveq -1,r3 + btstq 31,r3 + test_cc 1 0 0 0 + + move.d 0x5a67f19f,r3 + btstq 12,r3 + test_cc 1 0 0 0 + + move.d 0xda67f19f,r3 + move.d 29,r4 + btst r4,r3 + test_cc 0 0 0 0 + + move.d 0xda67f19f,r3 + move.d 32,r4 + btst r4,r3 + test_cc 1 0 0 0 + + move.d 0xda67f191,r3 + move.d 33,r4 + btst r4,r3 + test_cc 0 0 0 0 + + moveq -1,r3 + moveq 0,r4 + btst r4,r3 + test_cc 1 0 0 0 + + moveq 2,r3 + moveq 1,r4 + btst r4,r3 + test_cc 1 0 0 0 + + moveq -1,r3 + moveq 31,r4 + btst r4,r3 + test_cc 1 0 0 0 + + moveq 4,r3 + btstq 1,r3 + test_cc 0 1 0 0 + + moveq -1,r3 + moveq 15,r4 + btst r4,r3 + test_cc 1 0 0 0 + + move.d 0x5a67f19f,r3 + moveq 12,r4 + btst r4,r3 + test_cc 1 0 0 0 + + move.d 0x5a678000,r3 + moveq 11,r4 + btst r4,r3 + test_cc 0 1 0 0 + + move.d 0x5a67f19f,r3 + btst r3,r3 + test_cc 0 0 0 0 + + move.d 0x1111,r3 + checkr3 1111 + + ; check that X gets cleared and that only the NZ flags are touched. + move.d 0xff, $r0 + move $r0, $ccs + btst r3,r3 + move $ccs, $r0 + and.d 0xff, $r0 + cmp.d 0xe3, $r0 + test_cc 0 1 0 0 + + quit diff --git a/qemu/tests/tcg/cris/check_clearfv32.s b/qemu/tests/tcg/cris/check_clearfv32.s new file mode 100644 index 000000000..4e9136027 --- /dev/null +++ b/qemu/tests/tcg/cris/check_clearfv32.s @@ -0,0 +1,19 @@ +# mach: crisv32 +# output: ef\nef\n + +; Check that "clearf x" doesn't trivially fail. + + .include "testutils.inc" + start + setf puixnzvc + clearf x ; Actually, x would be cleared by almost-all other insns. + move ccs,r3 + and.d 0xff, $r3 + checkr3 ef + + setf puixnzvc + moveq 0, $r3 ; moveq should only clear the xflag. + move ccs,r3 + and.d 0xff, $r3 + checkr3 ef + quit diff --git a/qemu/tests/tcg/cris/check_clrjmp1.s b/qemu/tests/tcg/cris/check_clrjmp1.s new file mode 100644 index 000000000..45a7005e2 --- /dev/null +++ b/qemu/tests/tcg/cris/check_clrjmp1.s @@ -0,0 +1,36 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: ffffff00\n + +; A bug resulting in a non-effectual clear.b discovered running the GCC +; testsuite; jump actually wrote to p0. + + .include "testutils.inc" + + start + jump 1f + nop + .p2align 8 +1: + move.d y,r4 + + .if 0 ;0 == ..asm.arch.cris.v32 +; There was a bug causing this insn to set special register p0 +; (byte-clear) to 8 (low 8 bits of location after insn). + jump [r4+] + .endif + +1: + move.d 0f,r4 + +; The corresponding bug would cause this insn too, to set p0. + jump r4 + nop + quit +0: + moveq -1,r3 + clear.b r3 + checkr3 ffffff00 + quit + +y: + .dword 1b diff --git a/qemu/tests/tcg/cris/check_cmp-2.s b/qemu/tests/tcg/cris/check_cmp-2.s new file mode 100644 index 000000000..414d37051 --- /dev/null +++ b/qemu/tests/tcg/cris/check_cmp-2.s @@ -0,0 +1,15 @@ + + +.include "testutils.inc" + + start + + move.d 4294967283, $r0 + move.d $r0, $r10 + cmp.d $r0, $r10 + beq 1f + move.d $r10, $r3 + fail +1: + pass + quit diff --git a/qemu/tests/tcg/cris/check_cmpc.s b/qemu/tests/tcg/cris/check_cmpc.s new file mode 100644 index 000000000..267c9ba8c --- /dev/null +++ b/qemu/tests/tcg/cris/check_cmpc.s @@ -0,0 +1,86 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: ffffffff\n2\nffff\nffffffff\n78134452\nffffffff\n2\nffff\nfedaffff\n78134452\nffffffff\n2\nff\nfeda49ff\n78134452\n85649282\n + + .include "testutils.inc" + start + moveq -1,r3 + cmp.d -2,r3 + test_cc 0 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + cmp.d 1,r3 + test_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + cmp.d -0xffff,r3 + test_cc 0 0 0 1 + checkr3 ffff + + moveq -1,r3 + cmp.d 1,r3 + test_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x78134452,r3 + cmp.d -0x5432f789,r3 + test_cc 1 0 1 1 + checkr3 78134452 + + moveq -1,r3 + cmp.w -2,r3 + test_cc 0 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + cmp.w 1,r3 + test_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + cmp.w 1,r3 + test_cc 1 0 0 0 + checkr3 ffff + + move.d 0xfedaffff,r3 + cmp.w 1,r3 + test_cc 1 0 0 0 + checkr3 fedaffff + + move.d 0x78134452,r3 + cmp.w 0x877,r3 + test_cc 0 0 0 0 + checkr3 78134452 + + moveq -1,r3 + cmp.b -2,r3 + test_cc 0 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + cmp.b 1,r3 + test_cc 0 0 0 0 + checkr3 2 + + move.d 0xff,r3 + cmp.b 1,r3 + test_cc 1 0 0 0 + checkr3 ff + + move.d 0xfeda49ff,r3 + cmp.b 1,r3 + test_cc 1 0 0 0 + checkr3 feda49ff + + move.d 0x78134452,r3 + cmp.b 0x77,r3 + test_cc 1 0 0 1 + checkr3 78134452 + + move.d 0x85649282,r3 + cmp.b 0x82,r3 + test_cc 0 1 0 0 + checkr3 85649282 + + quit diff --git a/qemu/tests/tcg/cris/check_cmpm.s b/qemu/tests/tcg/cris/check_cmpm.s new file mode 100644 index 000000000..e4dde15b3 --- /dev/null +++ b/qemu/tests/tcg/cris/check_cmpm.s @@ -0,0 +1,96 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: ffffffff\n2\nffff\nffffffff\n78134452\nffffffff\n2\nffff\nfedaffff\n78134452\nffffffff\n2\nff\nfeda49ff\n78134452\n85649222\n + + .include "testutils.inc" + .data +x: + .dword -2,1,-0xffff,1,-0x5432f789 + .word -2,1,1,0x877 + .byte -2,1,0x77 + .byte 0x22 + + start + moveq -1,r3 + move.d x,r5 + cmp.d [r5+],r3 + test_cc 0 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + cmp.d [r5],r3 + test_cc 0 0 0 0 + addq 4,r5 + checkr3 2 + + move.d 0xffff,r3 + cmp.d [r5+],r3 + test_cc 0 0 0 1 + checkr3 ffff + + moveq -1,r3 + cmp.d [r5+],r3 + test_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x78134452,r3 + cmp.d [r5+],r3 + test_cc 1 0 1 1 + checkr3 78134452 + + moveq -1,r3 + cmp.w [r5+],r3 + test_cc 0 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + cmp.w [r5+],r3 + test_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + cmp.w [r5],r3 + test_cc 1 0 0 0 + checkr3 ffff + + move.d 0xfedaffff,r3 + cmp.w [r5+],r3 + test_cc 1 0 0 0 + checkr3 fedaffff + + move.d 0x78134452,r3 + cmp.w [r5+],r3 + test_cc 0 0 0 0 + checkr3 78134452 + + moveq -1,r3 + cmp.b [r5],r3 + test_cc 0 0 0 0 + addq 1,r5 + checkr3 ffffffff + + moveq 2,r3 + cmp.b [r5],r3 + test_cc 0 0 0 0 + checkr3 2 + + move.d 0xff,r3 + cmp.b [r5],r3 + test_cc 1 0 0 0 + checkr3 ff + + move.d 0xfeda49ff,r3 + cmp.b [r5+],r3 + test_cc 1 0 0 0 + checkr3 feda49ff + + move.d 0x78134452,r3 + cmp.b [r5+],r3 + test_cc 1 0 0 1 + checkr3 78134452 + + move.d 0x85649222,r3 + cmp.b [r5],r3 + test_cc 0 1 0 0 + checkr3 85649222 + + quit diff --git a/qemu/tests/tcg/cris/check_cmpq.s b/qemu/tests/tcg/cris/check_cmpq.s new file mode 100644 index 000000000..5469141c9 --- /dev/null +++ b/qemu/tests/tcg/cris/check_cmpq.s @@ -0,0 +1,75 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n1\n1f\n1f\nffffffe1\nffffffe1\nffffffe0\n0\n0\nffffffff\nffffffff\n10000\n100\n5678900\n + + .include "testutils.inc" + start + moveq 1,r3 + cmpq 1,r3 + test_cc 0 1 0 0 + checkr3 1 + + cmpq -1,r3 + test_cc 0 0 0 1 + checkr3 1 + + cmpq 31,r3 + test_cc 1 0 0 1 + checkr3 1 + + moveq 31,r3 + cmpq 31,r3 + test_cc 0 1 0 0 + checkr3 1f + + cmpq -31,r3 + test_cc 0 0 0 1 + checkr3 1f + + movs.b -31,r3 + cmpq -31,r3 + test_cc 0 1 0 0 + checkr3 ffffffe1 + + cmpq -32,r3 + test_cc 0 0 0 0 + checkr3 ffffffe1 + + movs.b -32,r3 + cmpq -32,r3 + test_cc 0 1 0 0 + checkr3 ffffffe0 + + moveq 0,r3 + cmpq 1,r3 + test_cc 1 0 0 1 + checkr3 0 + + cmpq -32,r3 + test_cc 0 0 0 1 + checkr3 0 + + moveq -1,r3 + cmpq 1,r3 + test_cc 1 0 0 0 + checkr3 ffffffff + + cmpq -1,r3 + test_cc 0 1 0 0 + checkr3 ffffffff + + move.d 0x10000,r3 + cmpq 1,r3 + test_cc 0 0 0 0 + checkr3 10000 + + move.d 0x100,r3 + cmpq 1,r3 + test_cc 0 0 0 0 + checkr3 100 + + move.d 0x5678900,r3 + cmpq 7,r3 + test_cc 0 0 0 0 + checkr3 5678900 + + quit diff --git a/qemu/tests/tcg/cris/check_cmpr.s b/qemu/tests/tcg/cris/check_cmpr.s new file mode 100644 index 000000000..b30af7a53 --- /dev/null +++ b/qemu/tests/tcg/cris/check_cmpr.s @@ -0,0 +1,102 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: ffffffff\n2\nffff\nffffffff\n78134452\nffffffff\n2\nffff\nfedaffff\n78134452\nffffffff\n2\nff\nfeda49ff\n78134452\n85649222\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq -2,r4 + cmp.d r4,r3 + test_cc 0 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + moveq 1,r4 + cmp.d r4,r3 + test_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + move.d -0xffff,r4 + cmp.d r4,r3 + test_cc 0 0 0 1 + checkr3 ffff + + moveq 1,r4 + moveq -1,r3 + cmp.d r4,r3 + test_cc 1 0 0 0 + checkr3 ffffffff + + move.d -0x5432f789,r4 + move.d 0x78134452,r3 + cmp.d r4,r3 + test_cc 1 0 1 1 + checkr3 78134452 + + moveq -1,r3 + moveq -2,r4 + cmp.w r4,r3 + test_cc 0 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + moveq 1,r4 + cmp.w r4,r3 + test_cc 0 0 0 0 + checkr3 2 + + move.d 0xffff,r3 + move.d -0xffff,r4 + cmp.w r4,r3 + test_cc 1 0 0 0 + checkr3 ffff + + move.d 0xfedaffff,r3 + move.d -0xfedaffff,r4 + cmp.w r4,r3 + test_cc 1 0 0 0 + checkr3 fedaffff + + move.d -0x5432f789,r4 + move.d 0x78134452,r3 + cmp.w r4,r3 + test_cc 0 0 0 0 + checkr3 78134452 + + moveq -1,r3 + moveq -2,r4 + cmp.b r4,r3 + test_cc 0 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + moveq 1,r4 + cmp.b r4,r3 + test_cc 0 0 0 0 + checkr3 2 + + move.d -0xff,r4 + move.d 0xff,r3 + cmp.b r4,r3 + test_cc 1 0 0 0 + checkr3 ff + + move.d -0xfeda49ff,r4 + move.d 0xfeda49ff,r3 + cmp.b r4,r3 + test_cc 1 0 0 0 + checkr3 feda49ff + + move.d -0x5432f789,r4 + move.d 0x78134452,r3 + cmp.b r4,r3 + test_cc 1 0 0 1 + checkr3 78134452 + + move.d 0x85649222,r3 + move.d 0x77445622,r4 + cmp.b r4,r3 + test_cc 0 1 0 0 + checkr3 85649222 + + quit diff --git a/qemu/tests/tcg/cris/check_cmpxc.s b/qemu/tests/tcg/cris/check_cmpxc.s new file mode 100644 index 000000000..b237a9317 --- /dev/null +++ b/qemu/tests/tcg/cris/check_cmpxc.s @@ -0,0 +1,92 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 2\n2\n2\n2\nffff\nffff\nffff\nffff\nffffffff\nffffffff\nffffffff\n78134452\n78134452\n78134452\n78134452\n4452\n80000032\n + + .include "testutils.inc" + start + moveq 2,r3 + cmps.b 0xff,r3 + test_cc 0 0 0 1 + checkr3 2 + + moveq 2,r3 + cmps.w 0xffff,r3 + test_cc 0 0 0 1 + checkr3 2 + + moveq 2,r3 + cmpu.b 0xff,r3 + test_cc 1 0 0 1 + checkr3 2 + + moveq 2,r3 + move.d 0xffffffff,r4 + cmpu.w -1,r3 + test_cc 1 0 0 1 + checkr3 2 + + move.d 0xffff,r3 + cmpu.b -1,r3 + test_cc 0 0 0 0 + checkr3 ffff + + move.d 0xffff,r3 + cmpu.w -1,r3 + test_cc 0 1 0 0 + checkr3 ffff + + move.d 0xffff,r3 + cmps.b 0xff,r3 + test_cc 0 0 0 1 + checkr3 ffff + + move.d 0xffff,r3 + cmps.w 0xffff,r3 + test_cc 0 0 0 1 + checkr3 ffff + + moveq -1,r3 + cmps.b 0xff,r3 + test_cc 0 1 0 0 + checkr3 ffffffff + + moveq -1,r3 + cmps.w 0xff,r3 + test_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + cmps.w 0xffff,r3 + test_cc 0 1 0 0 + checkr3 ffffffff + + move.d 0x78134452,r3 + cmpu.b 0x89,r3 + test_cc 0 0 0 0 + checkr3 78134452 + + move.d 0x78134452,r3 + cmps.b 0x89,r3 + test_cc 0 0 0 1 + checkr3 78134452 + + move.d 0x78134452,r3 + cmpu.w 0xf789,r3 + test_cc 0 0 0 0 + checkr3 78134452 + + move.d 0x78134452,r3 + cmps.w 0xf789,r3 + test_cc 0 0 0 1 + checkr3 78134452 + + move.d 0x4452,r3 + cmps.w 0x8002,r3 + test_cc 0 0 0 1 + checkr3 4452 + + move.d 0x80000032,r3 + cmpu.w 0x764,r3 + test_cc 0 0 1 0 + checkr3 80000032 + + quit diff --git a/qemu/tests/tcg/cris/check_cmpxm.s b/qemu/tests/tcg/cris/check_cmpxm.s new file mode 100644 index 000000000..87ea5bf8e --- /dev/null +++ b/qemu/tests/tcg/cris/check_cmpxm.s @@ -0,0 +1,106 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 2\n2\n2\n2\nffff\nffff\nffff\nffff\nffffffff\nffffffff\nffffffff\n78134452\n78134452\n78134452\n78134452\n4452\n80000032\n + + .include "testutils.inc" + .data +x: + .byte 0xff + .word 0xffff + .word 0xff + .word 0xffff + .byte 0x89 + .word 0xf789 + .word 0x8002 + .word 0x764 + + start + moveq 2,r3 + move.d x,r5 + cmps.b [r5+],r3 + test_cc 0 0 0 1 + checkr3 2 + + moveq 2,r3 + cmps.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 2 + + moveq 2,r3 + subq 3,r5 + cmpu.b [r5+],r3 + test_cc 1 0 0 1 + checkr3 2 + + moveq 2,r3 + cmpu.w [r5+],r3 + test_cc 1 0 0 1 + subq 3,r5 + checkr3 2 + + move.d 0xffff,r3 + cmpu.b [r5],r3 + test_cc 0 0 0 0 + checkr3 ffff + + move.d 0xffff,r3 + cmpu.w [r5],r3 + test_cc 0 1 0 0 + checkr3 ffff + + move.d 0xffff,r3 + cmps.b [r5],r3 + test_cc 0 0 0 1 + checkr3 ffff + + move.d 0xffff,r3 + cmps.w [r5],r3 + test_cc 0 0 0 1 + checkr3 ffff + + moveq -1,r3 + cmps.b [r5],r3 + test_cc 0 1 0 0 + addq 3,r5 + checkr3 ffffffff + + moveq -1,r3 + cmps.w [r5+],r3 + test_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + cmps.w [r5+],r3 + test_cc 0 1 0 0 + checkr3 ffffffff + + move.d 0x78134452,r3 + cmpu.b [r5],r3 + test_cc 0 0 0 0 + checkr3 78134452 + + move.d 0x78134452,r3 + cmps.b [r5+],r3 + test_cc 0 0 0 1 + checkr3 78134452 + + move.d 0x78134452,r3 + cmpu.w [r5],r3 + test_cc 0 0 0 0 + checkr3 78134452 + + move.d 0x78134452,r3 + cmps.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 78134452 + + move.d 0x4452,r3 + cmps.w [r5+],r3 + test_cc 0 0 0 1 + checkr3 4452 + + move.d 0x80000032,r3 + cmpu.w [r5+],r3 + test_cc 0 0 1 0 + checkr3 80000032 + + quit diff --git a/qemu/tests/tcg/cris/check_dstep.s b/qemu/tests/tcg/cris/check_dstep.s new file mode 100644 index 000000000..bd43b838e --- /dev/null +++ b/qemu/tests/tcg/cris/check_dstep.s @@ -0,0 +1,42 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: fffffffc\n4\nffff\nfffffffe\n9bf3911b\n0\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq 2,r4 + dstep r4,r3 + test_move_cc 1 0 0 0 + checkr3 fffffffc + + moveq 2,r3 + moveq -1,r4 + dstep r4,r3 + test_move_cc 0 0 0 0 + checkr3 4 + + move.d 0xffff,r4 + move.d r4,r3 + dstep r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r4 + move.d r4,r3 + dstep r4,r3 + test_move_cc 1 0 0 0 + checkr3 fffffffe + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + dstep r4,r3 + test_move_cc 1 0 0 0 + checkr3 9bf3911b + + move.d 0xffff,r3 + move.d 0x1fffe,r4 + dstep r4,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_ftag.c b/qemu/tests/tcg/cris/check_ftag.c new file mode 100644 index 000000000..908773a38 --- /dev/null +++ b/qemu/tests/tcg/cris/check_ftag.c @@ -0,0 +1,37 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +static inline void cris_ftag_i(unsigned int x) +{ + register unsigned int v asm("$r10") = x; + asm ("ftagi\t[%0]\n" : : "r" (v) ); +} +static inline void cris_ftag_d(unsigned int x) +{ + register unsigned int v asm("$r10") = x; + asm ("ftagd\t[%0]\n" : : "r" (v) ); +} +static inline void cris_fidx_i(unsigned int x) +{ + register unsigned int v asm("$r10") = x; + asm ("fidxi\t[%0]\n" : : "r" (v) ); +} +static inline void cris_fidx_d(unsigned int x) +{ + register unsigned int v asm("$r10") = x; + asm ("fidxd\t[%0]\n" : : "r" (v) ); +} + + +int main(void) +{ + cris_ftag_i(0); + cris_ftag_d(0); + cris_fidx_i(0); + cris_fidx_d(0); + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_gcctorture_pr28634-1.c b/qemu/tests/tcg/cris/check_gcctorture_pr28634-1.c new file mode 100644 index 000000000..45ecd159b --- /dev/null +++ b/qemu/tests/tcg/cris/check_gcctorture_pr28634-1.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/28634. On targets with delayed branches, + dbr_schedule could do the next iteration's addition in the + branch delay slot, then subtract the value again if the branch + wasn't taken. This can lead to rounding errors. */ +int x = -1; +int y = 1; +int +main (void) +{ + while (y > 0) + y += x; + if (y != x + 1) + abort (); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_gcctorture_pr28634.c b/qemu/tests/tcg/cris/check_gcctorture_pr28634.c new file mode 100644 index 000000000..a0c525497 --- /dev/null +++ b/qemu/tests/tcg/cris/check_gcctorture_pr28634.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/28634. On targets with delayed branches, + dbr_schedule could do the next iteration's addition in the + branch delay slot, then subtract the value again if the branch + wasn't taken. This can lead to rounding errors. */ +double x = -0x1.0p53; +double y = 1; +int +main (void) +{ + while (y > 0) + y += x; + if (y != x + 1) + abort (); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_glibc_kernelversion.c b/qemu/tests/tcg/cris/check_glibc_kernelversion.c new file mode 100644 index 000000000..07448722c --- /dev/null +++ b/qemu/tests/tcg/cris/check_glibc_kernelversion.c @@ -0,0 +1,116 @@ +/* + * Check the lz insn. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" + +#define __LINUX_KERNEL_VERSION 131584 + +#define DL_SYSDEP_OSCHECK(FATAL) \ + do { \ + /* Test whether the kernel is new enough. This test is only \ + performed if the library is not compiled to run on all \ + kernels. */ \ + if (__LINUX_KERNEL_VERSION > 0) \ + { \ + char bufmem[64]; \ + char *buf = bufmem; \ + unsigned int version; \ + int parts; \ + char *cp; \ + struct utsname uts; \ + \ + /* Try the uname syscall */ \ + if (__uname (&uts)) \ + { \ + /* This was not successful. Now try reading the /proc \ + filesystem. */ \ + ssize_t reslen; \ + int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY); \ + if (fd == -1 \ + || (reslen = __read (fd, bufmem, sizeof (bufmem))) <= 0) \ + /* This also didn't work. We give up since we cannot \ + make sure the library can actually work. */ \ + FATAL ("FATAL: cannot determine library version\n"); \ + __close (fd); \ + buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0'; \ + } \ + else \ + buf = uts.release; \ + \ + /* Now convert it into a number. The string consists of at most \ + three parts. */ \ + version = 0; \ + parts = 0; \ + cp = buf; \ + while ((*cp >= '0') && (*cp <= '9')) \ + { \ + unsigned int here = *cp++ - '0'; \ + \ + while ((*cp >= '0') && (*cp <= '9')) \ + { \ + here *= 10; \ + here += *cp++ - '0'; \ + } \ + \ + ++parts; \ + version <<= 8; \ + version |= here; \ + \ + if (*cp++ != '.') \ + /* Another part following? */ \ + break; \ + } \ + \ + if (parts < 3) \ + version <<= 8 * (3 - parts); \ + \ + /* Now we can test with the required version. */ \ + if (version < __LINUX_KERNEL_VERSION) \ + /* Not sufficient. */ \ + FATAL ("FATAL: kernel too old\n"); \ + \ + _dl_osversion = version; \ + } \ + } while (0) + +int main(void) +{ + char bufmem[64] = "2.6.22"; + char *buf = bufmem; + unsigned int version; + int parts; + char *cp; + + version = 0; + parts = 0; + cp = buf; + while ((*cp >= '0') && (*cp <= '9')) + { + unsigned int here = *cp++ - '0'; + + while ((*cp >= '0') && (*cp <= '9')) + { + here *= 10; + here += *cp++ - '0'; + } + + ++parts; + version <<= 8; + version |= here; + + if (*cp++ != '.') + /* Another part following? */ + break; + } + + if (parts < 3) + version <<= 8 * (3 - parts); + if (version < __LINUX_KERNEL_VERSION) + err(); + pass(); + exit(0); +} diff --git a/qemu/tests/tcg/cris/check_hello.c b/qemu/tests/tcg/cris/check_hello.c new file mode 100644 index 000000000..fb403ba99 --- /dev/null +++ b/qemu/tests/tcg/cris/check_hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> +#include <stdlib.h> +int main () +{ + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_int64.c b/qemu/tests/tcg/cris/check_int64.c new file mode 100644 index 000000000..fc600176e --- /dev/null +++ b/qemu/tests/tcg/cris/check_int64.c @@ -0,0 +1,47 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + + +static inline int64_t add64(const int64_t a, const int64_t b) +{ + return a + b; +} + +static inline int64_t sub64(const int64_t a, const int64_t b) +{ + return a - b; +} + +int main(void) +{ + int64_t a = 1; + int64_t b = 2; + + /* FIXME: add some tests. */ + a = add64(a, b); + if (a != 3) + err(); + + a = sub64(a, b); + if (a != 1) + err(); + + a = add64(a, -4); + if (a != -3) + err(); + + a = add64(a, 3); + if (a != 0) + err(); + + a = 0; + a = sub64(a, 1); + if (a != -1) + err(); + + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_jsr.s b/qemu/tests/tcg/cris/check_jsr.s new file mode 100644 index 000000000..106023787 --- /dev/null +++ b/qemu/tests/tcg/cris/check_jsr.s @@ -0,0 +1,85 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 0\n0\n0\n0\n0\n0\n + +# Test that jsr Rn and jsr [PC+] work. + + .include "testutils.inc" + start +x: + move.d 0f,r6 + setf nzvc + jsr r6 + .if 1; ..asm.arch.cris.v32 + nop + .endif +0: + test_move_cc 1 1 1 1 + move srp,r3 + sub.d 0b,r3 + checkr3 0 + + move.d 1f,r0 + setf nzvc + jsr r0 + .if 1 ; ..asm.arch.cris.v32 + moveq 0,r0 + .endif +6: + nop + quit + +2: + test_move_cc 0 0 0 0 + move srp,r3 + sub.d 3f,r3 + checkr3 0 + jsr 4f + .if 1 ; ..asm.arch.cris.v32 + nop + .endif +7: + nop + quit + +8: + move srp,r3 + sub.d 7b,r3 + checkr3 0 + quit + +4: + move srp,r3 + sub.d 7b,r3 + checkr3 0 + move.d 5f,r3 + jump r3 + .if 1; ..asm.arch.cris.v32 + moveq 0,r3 + .endif + quit + + .space 32770,0 +1: + test_move_cc 1 1 1 1 + move srp,r3 + sub.d 6b,r3 + checkr3 0 + + clearf cznv + jsr 2b + .if 1; ..asm.arch.cris.v32 + nop + .endif +3: + + quit + +5: + move srp,r3 + sub.d 7b,r3 + checkr3 0 + jump 8b + .if 1 ; ..asm.arch.cris.v32 + nop + .endif + quit diff --git a/qemu/tests/tcg/cris/check_lapc.s b/qemu/tests/tcg/cris/check_lapc.s new file mode 100644 index 000000000..9a6150b74 --- /dev/null +++ b/qemu/tests/tcg/cris/check_lapc.s @@ -0,0 +1,78 @@ +# mach: crisv32 +# output: 0\n0\nfffffffa\nfffffffe\nffffffda\n1e\n1e\n0\n + +.include "testutils.inc" + +; To accommodate dumpr3 with more than one instruction, keep it +; out of lapc operand ranges and difference calculations. + + start + lapc.d 0f,r3 +0: + sub.d .,r3 + checkr3 0 + + lapcq 0f,r3 +0: + sub.d .,r3 + checkr3 0 + + lapc.d .,r3 + sub.d .,r3 + checkr3 fffffffa + + lapcq .,r3 + sub.d .,r3 + checkr3 fffffffe + +0: + .rept 16 + nop + .endr + lapc.d 0b,r3 + sub.d .,r3 + checkr3 ffffffda + + setf zcvn + lapc.d 0f,r3 + test_cc 1 1 1 1 + sub.d .,r3 + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop +0: + checkr3 1e +0: + lapcq 0f,r3 + sub.d 0b,r3 + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop +0: + checkr3 1e + clearf cn + setf zv +1: + lapcq .,r3 + test_cc 0 1 1 0 + sub.d 1b,r3 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_lsl.s b/qemu/tests/tcg/cris/check_lsl.s new file mode 100644 index 000000000..9e2ddd7cd --- /dev/null +++ b/qemu/tests/tcg/cris/check_lsl.s @@ -0,0 +1,217 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: ffffffff\n4\n80000000\nffff8000\n7f19f000\n80000000\n0\n0\n699fc67c\nffffffff\n4\n80000000\nffff8000\n7f19f000\nda670000\nda670000\nda670000\nda67c67c\nffffffff\nfffafffe\n4\nffff0000\nffff8000\n5a67f000\nda67f100\nda67f100\nda67f100\nda67f17c\nfff3faff\nfff3fafe\n4\nffffff00\nffffff00\nffffff80\n5a67f100\n5a67f1f0\n + + .include "testutils.inc" + start + moveq -1,r3 + lslq 0,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + lslq 1,r3 + test_move_cc 0 0 0 0 + checkr3 4 + + moveq -1,r3 + lslq 31,r3 + test_move_cc 1 0 0 0 + checkr3 80000000 + + moveq -1,r3 + lslq 15,r3 + test_move_cc 1 0 0 0 + checkr3 ffff8000 + + move.d 0x5a67f19f,r3 + lslq 12,r3 + test_move_cc 0 0 0 0 + checkr3 7f19f000 + + move.d 0xda67f19f,r3 + move.d 31,r4 + lsl.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 80000000 + + move.d 0xda67f19f,r3 + move.d 32,r4 + lsl.d r4,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0xda67f19f,r3 + move.d 33,r4 + lsl.d r4,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0xda67f19f,r3 + move.d 66,r4 + lsl.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 699fc67c + + moveq -1,r3 + moveq 0,r4 + lsl.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + moveq 1,r4 + lsl.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 4 + + moveq -1,r3 + moveq 31,r4 + lsl.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 80000000 + + moveq -1,r3 + moveq 15,r4 + lsl.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffff8000 + + move.d 0x5a67f19f,r3 + moveq 12,r4 + lsl.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 7f19f000 + + move.d 0xda67f19f,r3 + move.d 31,r4 + lsl.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 da670000 + + move.d 0xda67f19f,r3 + move.d 32,r4 + lsl.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 da670000 + + move.d 0xda67f19f,r3 + move.d 33,r4 + lsl.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 da670000 + + move.d 0xda67f19f,r3 + move.d 66,r4 + lsl.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 da67c67c + + moveq -1,r3 + moveq 0,r4 + lsl.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0xfffaffff,r3 + moveq 1,r4 + lsl.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 fffafffe + + moveq 2,r3 + moveq 1,r4 + lsl.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 4 + + moveq -1,r3 + moveq 31,r4 + lsl.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 ffff0000 + + moveq -1,r3 + moveq 15,r4 + lsl.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffff8000 + + move.d 0x5a67f19f,r3 + moveq 12,r4 + lsl.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 5a67f000 + + move.d 0xda67f19f,r3 + move.d 31,r4 + lsl.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 da67f100 + + move.d 0xda67f19f,r3 + move.d 32,r4 + lsl.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 da67f100 + + move.d 0xda67f19f,r3 + move.d 33,r4 + lsl.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 da67f100 + + move.d 0xda67f19f,r3 + move.d 66,r4 + lsl.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 da67f17c + + move.d 0xfff3faff,r3 + moveq 0,r4 + lsl.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 fff3faff + + move.d 0xfff3faff,r3 + moveq 1,r4 + lsl.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 fff3fafe + + moveq 2,r3 + moveq 1,r4 + lsl.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 4 + + moveq -1,r3 + moveq 31,r4 + lsl.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 ffffff00 + + moveq -1,r3 + moveq 15,r4 + lsl.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 ffffff00 + + moveq -1,r3 + moveq 7,r4 + lsl.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffff80 + + move.d 0x5a67f19f,r3 + moveq 12,r4 + lsl.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 5a67f100 + + move.d 0x5a67f19f,r3 + moveq 4,r4 + lsl.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 5a67f1f0 + + quit diff --git a/qemu/tests/tcg/cris/check_lsr.s b/qemu/tests/tcg/cris/check_lsr.s new file mode 100644 index 000000000..18fdbef9b --- /dev/null +++ b/qemu/tests/tcg/cris/check_lsr.s @@ -0,0 +1,218 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: ffffffff\n1\n1\n1ffff\n5a67f\n1\n0\n0\n3699fc67\nffffffff\n1\n1\n1ffff\n5a67f\nda670000\nda670000\nda670000\nda673c67\nffffffff\nffff7fff\n1\nffff0000\nffff0001\n5a67000f\nda67f100\nda67f100\nda67f100\nda67f127\nffffffff\nffffff7f\n1\nffffff00\nffffff00\nffffff01\n5a67f100\n5a67f109\n + + .include "testutils.inc" + start + moveq -1,r3 + lsrq 0,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + lsrq 1,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + lsrq 31,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + lsrq 15,r3 + test_move_cc 0 0 0 0 + checkr3 1ffff + + move.d 0x5a67f19f,r3 + lsrq 12,r3 + test_move_cc 0 0 0 0 + checkr3 5a67f + + move.d 0xda67f19f,r3 + move.d 31,r4 + lsr.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + move.d 0xda67f19f,r3 + move.d 32,r4 + lsr.d r4,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0xda67f19f,r3 + move.d 33,r4 + lsr.d r4,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0xda67f19f,r3 + move.d 66,r4 + lsr.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 3699fc67 + + moveq -1,r3 + moveq 0,r4 + lsr.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 2,r3 + moveq 1,r4 + lsr.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + moveq 31,r4 + lsr.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + moveq 15,r4 + lsr.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 1ffff + + move.d 0x5a67f19f,r3 + moveq 12,r4 + lsr.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 5a67f + + move.d 0xda67f19f,r3 + move.d 31,r4 + lsr.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 da670000 + + move.d 0xda67f19f,r3 + move.d 32,r4 + lsr.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 da670000 + + move.d 0xda67f19f,r3 + move.d 33,r4 + lsr.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 da670000 + + move.d 0xda67f19f,r3 + move.d 66,r4 + lsr.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 da673c67 + + moveq -1,r3 + moveq 0,r4 + lsr.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + moveq 1,r4 + lsr.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff7fff + + moveq 2,r3 + moveq 1,r4 + lsr.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 1 + +;; FIXME: this was wrong. Z should be set. + moveq -1,r3 + moveq 31,r4 + lsr.w r4,r3 + test_move_cc 0 1 0 0 + checkr3 ffff0000 + + moveq -1,r3 + moveq 15,r4 + lsr.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff0001 + + move.d 0x5a67f19f,r3 + moveq 12,r4 + lsr.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 5a67000f + + move.d 0xda67f19f,r3 + move.d 31,r4 + lsr.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 da67f100 + + move.d 0xda67f19f,r3 + move.d 32,r4 + lsr.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 da67f100 + + move.d 0xda67f19f,r3 + move.d 33,r4 + lsr.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 da67f100 + + move.d 0xda67f19f,r3 + move.d 66,r4 + lsr.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 da67f127 + + moveq -1,r3 + moveq 0,r4 + lsr.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq -1,r3 + moveq 1,r4 + lsr.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffffff7f + + moveq 2,r3 + moveq 1,r4 + lsr.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + moveq -1,r3 + moveq 31,r4 + lsr.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 ffffff00 + + moveq -1,r3 + moveq 15,r4 + lsr.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 ffffff00 + + moveq -1,r3 + moveq 7,r4 + lsr.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffffff01 + + move.d 0x5a67f19f,r3 + moveq 12,r4 + lsr.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 5a67f100 + + move.d 0x5a67f19f,r3 + moveq 4,r4 + lsr.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 5a67f109 + + quit diff --git a/qemu/tests/tcg/cris/check_lz.c b/qemu/tests/tcg/cris/check_lz.c new file mode 100644 index 000000000..69c2e6d4e --- /dev/null +++ b/qemu/tests/tcg/cris/check_lz.c @@ -0,0 +1,49 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" + +static inline int cris_lz(int x) +{ + int r; + asm ("lz\t%1, %0\n" : "=r" (r) : "r" (x)); + return r; +} + +void check_lz(void) +{ + int i; + + if (cris_lz(0) != 32) + err(); + if (cris_lz(1) != 31) + err(); + if (cris_lz(2) != 30) + err(); + if (cris_lz(4) != 29) + err(); + if (cris_lz(8) != 28) + err(); + + /* try all positions with a single bit. */ + for (i = 1; i < 32; i++) { + if (cris_lz(1 << (i-1)) != (32 - i)) + err(); + } + + /* try all positions with all bits. */ + for (i = 1; i < 32; i++) { + /* split up this computation to clarify it. */ + uint32_t val; + val = (unsigned int)-1 >> (32 - i); + if (cris_lz(val) != (32 - i)) + err(); + } +} + +int main(void) +{ + check_lz(); + pass(); + exit(0); +} diff --git a/qemu/tests/tcg/cris/check_mapbrk.c b/qemu/tests/tcg/cris/check_mapbrk.c new file mode 100644 index 000000000..1aff7622b --- /dev/null +++ b/qemu/tests/tcg/cris/check_mapbrk.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> + +/* Basic sanity check that syscalls to implement malloc (brk, mmap2, + munmap) are trivially functional. */ + +int main () +{ + void *p1, *p2, *p3, *p4, *p5, *p6; + + if ((p1 = malloc (8100)) == NULL + || (p2 = malloc (16300)) == NULL + || (p3 = malloc (4000)) == NULL + || (p4 = malloc (500)) == NULL + || (p5 = malloc (1023*1024)) == NULL + || (p6 = malloc (8191*1024)) == NULL) + { + printf ("fail\n"); + exit (1); + } + + free (p1); + free (p2); + free (p3); + free (p4); + free (p5); + free (p6); + + p1 = malloc (64000); + if (p1 == NULL) + { + printf ("fail\n"); + exit (1); + } + free (p1); + + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_mcp.s b/qemu/tests/tcg/cris/check_mcp.s new file mode 100644 index 000000000..e65ccddfd --- /dev/null +++ b/qemu/tests/tcg/cris/check_mcp.s @@ -0,0 +1,49 @@ +# mach: crisv32 +# output: fffffffe\n1\n1ffff\nfffffffe\ncc463bdc\n4c463bdc\n0\n + + .include "testutils.inc" + start + +; Set R, clear C. + move 0x100,ccs + moveq -5,r3 + move 2,mof + mcp mof,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + + moveq 2,r3 + move -1,srp + mcp srp,r3 + test_cc 0 0 0 0 + checkr3 1 + + move 0xffff,srp + move srp,r3 + mcp srp,r3 + test_cc 0 0 0 0 + checkr3 1ffff + + move -1,mof + move mof,r3 + mcp mof,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + + move 0x5432f789,mof + move.d 0x78134452,r3 + mcp mof,r3 + test_cc 1 0 1 0 + checkr3 cc463bdc + + move 0x80000000,srp + mcp srp,r3 + test_cc 0 0 1 0 + checkr3 4c463bdc + + move 0xb3b9c423,srp + mcp srp,r3 + test_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_mmap1.c b/qemu/tests/tcg/cris/check_mmap1.c new file mode 100644 index 000000000..b803f0c43 --- /dev/null +++ b/qemu/tests/tcg/cris/check_mmap1.c @@ -0,0 +1,48 @@ +/* +#notarget: cris*-*-elf +*/ + +#define _GNU_SOURCE +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> + +int main (int argc, char *argv[]) +{ + int fd = open (argv[0], O_RDONLY); + struct stat sb; + int size; + void *a; + const char *str = "a string you'll only find in the program"; + + if (fd == -1) + { + perror ("open"); + abort (); + } + + if (fstat (fd, &sb) < 0) + { + perror ("fstat"); + abort (); + } + + size = sb.st_size; + + /* We want to test mmapping a size that isn't exactly a page. */ + if ((size & 8191) == 0) + size--; + + a = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + + if (memmem (a, size, str, strlen (str) + 1) == NULL) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_mmap2.c b/qemu/tests/tcg/cris/check_mmap2.c new file mode 100644 index 000000000..35139a0ed --- /dev/null +++ b/qemu/tests/tcg/cris/check_mmap2.c @@ -0,0 +1,48 @@ +/* +#notarget: cris*-*-elf +*/ + +#define _GNU_SOURCE +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> + +int main (int argc, char *argv[]) +{ + int fd = open (argv[0], O_RDONLY); + struct stat sb; + int size; + void *a; + const char *str = "a string you'll only find in the program"; + + if (fd == -1) + { + perror ("open"); + abort (); + } + + if (fstat (fd, &sb) < 0) + { + perror ("fstat"); + abort (); + } + + size = sb.st_size; + + /* We want to test mmapping a size that isn't exactly a page. */ + if ((size & 8191) == 0) + size--; + + a = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0); + + if (memmem (a, size, str, strlen (str) + 1) == NULL) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_mmap3.c b/qemu/tests/tcg/cris/check_mmap3.c new file mode 100644 index 000000000..34401fa0c --- /dev/null +++ b/qemu/tests/tcg/cris/check_mmap3.c @@ -0,0 +1,33 @@ +/* +#notarget: cris*-*-elf +*/ + +#define _GNU_SOURCE +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mman.h> + +int main (int argc, char *argv[]) +{ + volatile unsigned char *a; + + /* Check that we can map a non-multiple of a page and still get a full page. */ + a = mmap (NULL, 0x4c, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (a == NULL || a == (unsigned char *) -1) + abort (); + + a[0] = 0xbe; + a[8191] = 0xef; + memset ((char *) a + 1, 0, 8190); + + if (a[0] != 0xbe || a[8191] != 0xef) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_movdelsr1.s b/qemu/tests/tcg/cris/check_movdelsr1.s new file mode 100644 index 000000000..300cc8774 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movdelsr1.s @@ -0,0 +1,33 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: aa117acd\n +# output: eeaabb42\n + +; Bug with move to special register in delay slot, due to +; special flush-insn-cache simulator use. Ordinary move worked; +; special register caused branch to fail. + + .include "testutils.inc" + start + move -1,srp + + move.d 0xaa117acd,r1 + moveq 3,r9 + cmpq 1,r9 + bhi 0f + move.d r1,r3 + + fail +0: + checkr3 aa117acd + + move.d 0xeeaabb42,r1 + moveq 3,r9 + cmpq 1,r9 + bhi 0f + move r1,srp + + fail +0: + move srp,r3 + checkr3 eeaabb42 + quit diff --git a/qemu/tests/tcg/cris/check_movecr.s b/qemu/tests/tcg/cris/check_movecr.s new file mode 100644 index 000000000..da8ec2628 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movecr.s @@ -0,0 +1,37 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: ffffff42\n94\nffff4321\n9234\n76543210\n76540000\n + +; Move constant byte, word, dword to register. Check that no extension is +; performed, that only part of the register is set. + + .include "testutils.inc" + startnostack + moveq -1,r3 + move.b 0x42,r3 + test_move_cc 0 0 0 0 + checkr3 ffffff42 + + moveq 0,r3 + move.b 0x94,r3 + test_move_cc 1 0 0 0 + checkr3 94 + + moveq -1,r3 + move.w 0x4321,r3 + test_move_cc 0 0 0 0 + checkr3 ffff4321 + + moveq 0,r3 + move.w 0x9234,r3 + test_move_cc 1 0 0 0 + checkr3 9234 + + move.d 0x76543210,r3 + test_move_cc 0 0 0 0 + checkr3 76543210 + + move.w 0,r3 + test_move_cc 0 1 0 0 + checkr3 76540000 + + quit diff --git a/qemu/tests/tcg/cris/check_movei.s b/qemu/tests/tcg/cris/check_movei.s new file mode 100644 index 000000000..bbfa63337 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movei.s @@ -0,0 +1,50 @@ +# mach: crisv32 +# output: fffffffe\n +# output: fffffffe\n + +; Check basic integral-write semantics regarding flags. + + .include "testutils.inc" + start + + move.d 0, $r3 +; A write that works. Check that flags are set correspondingly. + move.d d,r4 + ;; store to bring it into the tlb with the right prot bits + move.d r3,[r4] + moveq -2,r5 + setf c + clearf p + move.d [r4],r3 + ax + move.d r5,[r4] + move.d [r4],r3 + + bcc 0f + nop + fail + +0: + checkr3 fffffffe + +; A write that fails; check flags too. + move.d d,r4 + moveq 23,r5 + setf p + clearf c + move.d [r4],r3 + ax + move.d r5,[r4] + move.d [r4],r3 + + bcs 0f + nop + fail + +0: + checkr3 fffffffe + quit + + .data +d: + .dword 42424242 diff --git a/qemu/tests/tcg/cris/check_movemr.s b/qemu/tests/tcg/cris/check_movemr.s new file mode 100644 index 000000000..88489dee3 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movemr.s @@ -0,0 +1,78 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 12345678\n10234567\n12345678\n12344567\n12344523\n76543210\nffffffaa\naa\n9911\nffff9911\n78\n56\n3456\n6712\n + + .include "testutils.inc" + start + + .data +mem1: + .dword 0x12345678 +mem2: + .word 0x4567 +mem3: + .byte 0x23 + .dword 0x76543210 + .byte 0xaa,0x11,0x99 + + .text + move.d mem1,r2 + move.d [r2],r3 + test_move_cc 0 0 0 0 + checkr3 12345678 + + move.d mem2,r3 + move.d [r3],r3 + test_move_cc 0 0 0 0 + checkr3 10234567 + + move.d mem1,r2 + move.d [r2+],r3 + test_move_cc 0 0 0 0 + checkr3 12345678 + + move.w [r2+],r3 + test_move_cc 0 0 0 0 + checkr3 12344567 + + move.b [r2+],r3 + test_move_cc 0 0 0 0 + checkr3 12344523 + + move.d [r2+],r3 + test_move_cc 0 0 0 0 + checkr3 76543210 + + movs.b [r2],r3 + test_move_cc 1 0 0 0 + checkr3 ffffffaa + + movu.b [r2+],r3 + test_move_cc 0 0 0 0 + checkr3 aa + + movu.w [r2],r3 + test_move_cc 0 0 0 0 + checkr3 9911 + + movs.w [r2+],r3 + test_move_cc 1 0 0 0 + checkr3 ffff9911 + + move.d mem1,r13 + movs.b [r13+],r3 + test_move_cc 0 0 0 0 + checkr3 78 + + movu.b [r13],r3 + test_move_cc 0 0 0 0 + checkr3 56 + + movs.w [r13+],r3 + test_move_cc 0 0 0 0 + checkr3 3456 + + movu.w [r13+],r3 + test_move_cc 0 0 0 0 + checkr3 6712 + + quit diff --git a/qemu/tests/tcg/cris/check_movemrv32.s b/qemu/tests/tcg/cris/check_movemrv32.s new file mode 100644 index 000000000..53950abd5 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movemrv32.s @@ -0,0 +1,96 @@ +# mach: crisv32 +# output: 15\n7\n2\nffff1234\nb\n16\nf\n2\nffffffef\nf\nffff1234\nf\nfffffff4\nd\nfffffff2\n10\nfffffff2\nd\n + + .include "testutils.inc" + .data +x: + .dword 8,9,10,11 +y: + .dword -12,13,-14,15,16 + + start + moveq 7,r0 + moveq 2,r1 + move.d 0xffff1234,r2 + moveq 21,r3 + move.d x,r4 + setf zcvn + movem r2,[r4+] + test_cc 1 1 1 1 + subq 12,r4 + + checkr3 15 + + move.d [r4+],r3 + checkr3 7 + + move.d [r4+],r3 + checkr3 2 + + move.d [r4+],r3 + checkr3 ffff1234 + + move.d [r4+],r3 + checkr3 b + + subq 16,r4 + moveq 22,r0 + moveq 15,r1 + clearf zcvn + movem r0,[r4] + test_cc 0 0 0 0 + move.d [r4+],r3 + checkr3 16 + + move.d r1,r3 + checkr3 f + + move.d [r4+],r3 + checkr3 2 + + subq 8,r4 + moveq 10,r2 + moveq -17,r0 + clearf zc + setf vn + movem r1,[r4] + test_cc 1 0 1 0 + move.d [r4+],r3 + checkr3 ffffffef + + move.d [r4+],r3 + checkr3 f + + move.d [r4+],r3 + checkr3 ffff1234 + + move.d y,r4 + setf zc + clearf vn + movem [r4+],r3 + test_cc 0 1 0 1 + checkr3 f + + move.d r0,r3 + checkr3 fffffff4 + + move.d r1,r3 + checkr3 d + + move.d r2,r3 + checkr3 fffffff2 + + move.d [r4],r3 + checkr3 10 + + subq 8,r4 + setf zcvn + movem [r4+],r0 + test_cc 1 1 1 1 + move.d r0,r3 + checkr3 fffffff2 + + move.d r1,r3 + checkr3 d + + quit diff --git a/qemu/tests/tcg/cris/check_moveq.c b/qemu/tests/tcg/cris/check_moveq.c new file mode 100644 index 000000000..80f2dff6a --- /dev/null +++ b/qemu/tests/tcg/cris/check_moveq.c @@ -0,0 +1,51 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +#define cris_moveq(dst, src) \ + asm volatile ("moveq %1, %0\n" : "=r" (dst) : "i" (src)); + + + +int main(void) +{ + int t; + + cris_tst_cc_init(); + asm volatile ("setf\tzvnc\n"); + cris_moveq(t, 10); + cris_tst_cc(1, 1, 1, 1); + if (t != 10) + err(); + + /* make sure moveq doesn't clobber the zflag. */ + cris_tst_cc_init(); + asm volatile ("setf vnc\n"); + asm volatile ("clearf z\n"); + cris_moveq(t, 0); + cris_tst_cc(1, 0, 1, 1); + if (t != 0) + err(); + + /* make sure moveq doesn't clobber the nflag. + Also check large immediates */ + cris_tst_cc_init(); + asm volatile ("setf zvc\n"); + asm volatile ("clearf n\n"); + cris_moveq(t, -31); + cris_tst_cc(0, 1, 1, 1); + if (t != -31) + err(); + + cris_tst_cc_init(); + asm volatile ("setf nzvc\n"); + cris_moveq(t, 31); + cris_tst_cc(1, 1, 1, 1); + if (t != 31) + err(); + + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_mover.s b/qemu/tests/tcg/cris/check_mover.s new file mode 100644 index 000000000..b4db595d6 --- /dev/null +++ b/qemu/tests/tcg/cris/check_mover.s @@ -0,0 +1,28 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: ffffff05\nffff0005\n5\nffffff00\n + +; Move between registers. Check that just the subreg is copied. + + .include "testutils.inc" + startnostack + moveq -30,r3 + moveq 5,r4 + move.b r4,r3 + test_move_cc 0 0 0 0 ; FIXME + checkr3 ffffff05 + + move.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff0005 + + move.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 5 + + moveq -1,r3 + moveq 0,r4 + move.b r4,r3 + test_move_cc 0 1 0 0 + checkr3 ffffff00 + + quit diff --git a/qemu/tests/tcg/cris/check_moverm.s b/qemu/tests/tcg/cris/check_moverm.s new file mode 100644 index 000000000..eabc9588d --- /dev/null +++ b/qemu/tests/tcg/cris/check_moverm.s @@ -0,0 +1,45 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 7823fec2\n10231879\n102318fe\n + + .include "testutils.inc" + start + + .data +mem1: + .dword 0x12345678 +mem2: + .word 0x4567 +mem3: + .byte 0x23 + .dword 0x76543210 + .byte 0xaa,0x11,0x99 + + .text + move.d mem1,r2 + move.d 0x7823fec2,r4 + setf nzvc + move.d r4,[r2+] + test_cc 1 1 1 1 + subq 4,r2 + move.d [r2],r3 + checkr3 7823fec2 + + move.d mem2,r3 + move.d 0x45231879,r4 + clearf nzvc + move.w r4,[r3] + test_cc 0 0 0 0 + move.d [r3],r3 + checkr3 10231879 + + move.d mem2,r2 + moveq -2,r4 + clearf nc + setf zv + move.b r4,[r2+] + test_cc 0 1 1 0 + subq 1,r2 + move.d [r2],r3 + checkr3 102318fe + + quit diff --git a/qemu/tests/tcg/cris/check_movmp.s b/qemu/tests/tcg/cris/check_movmp.s new file mode 100644 index 000000000..7fc11f064 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movmp.s @@ -0,0 +1,131 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: ffffff00\nffff0000\n0\nffffff00\nffff0000\n0\nffffff00\nffff0000\n0\nbb113344\n664433aa\ncc557788\nabcde012\nabcde000\n77880000\n0\n + +# Test generic "move Ps,[]" and "move [],Pd" insns; the ones with +# functionality common to all models. + + .include "testutils.inc" + start + + .data +filler: + .byte 0xaa + .word 0x4433 + .dword 0x55778866 + .byte 0xcc + + .text +; Test that writing to zero-registers is a nop + .if 0 + ; We used to just ignore the writes, but now an error is emitted. We + ; keep the test-code but disabled, in case we need to change this again. + move 0xaa,p0 + move 0x4433,p4 + move 0x55774433,p8 + .endif + + moveq -1,r3 + setf zcvn + clear.b r3 + test_cc 1 1 1 1 + checkr3 ffffff00 + + moveq -1,r3 + clearf zcvn + clear.w r3 + test_cc 0 0 0 0 + checkr3 ffff0000 + + moveq -1,r3 + clear.d r3 + checkr3 0 + +; "Write" using ordinary memory references too. + .if 0 ; See ".if 0" above. + move.d filler,r6 + move [r6],p0 + move [r6],p4 + move [r6],p8 + .endif + +# ffffff00\nffff0000\n0\nffffff00\nffff0000\n0\nbb113344\n664433aa\ncc557788\nabcde012\nabcde000\n77880000\n0\n + + moveq -1,r3 + clear.b r3 + checkr3 ffffff00 + + moveq -1,r3 + clear.w r3 + checkr3 ffff0000 + + moveq -1,r3 + clear.d r3 + checkr3 0 + +; And postincremented. + .if 0 ; See ".if 0" above. + move [r6+],p0 + move [r6+],p4 + move [r6+],p8 + .endif + +# ffffff00\nffff0000\n0\nbb113344\n664433aa\ncc557788\nabcde012\nabcde000\n77880000\n0\n + + moveq -1,r3 + clear.b r3 + checkr3 ffffff00 + + moveq -1,r3 + clear.w r3 + checkr3 ffff0000 + + moveq -1,r3 + clear.d r3 + checkr3 0 + +; Now see that we can write to the registers too. +# bb113344\n664433aa\ncc557788\nabcde012\nabcde000\n77880000\n0\n +; [PC+] + move.d filler,r9 + move 0xbb113344,srp + move srp,r3 + checkr3 bb113344 + +; [R+] + move [r9+],srp + move srp,r3 + checkr3 664433aa + +; [R] + move [r9],srp + move srp,r3 + checkr3 cc557788 + +; And check writing to memory, clear and srp. + + move.d filler,r9 + move 0xabcde012,srp + setf zcvn + move srp,[r9+] + test_cc 1 1 1 1 + subq 4,r9 + move.d [r9],r3 + checkr3 abcde012 + + clearf zcvn + clear.b [r9] + test_cc 0 0 0 0 + move.d [r9],r3 + checkr3 abcde000 + + addq 2,r9 + clear.w [r9+] + subq 2,r9 + move.d [r9],r3 + checkr3 77880000 + + clear.d [r9] + move.d [r9],r3 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_movpmv32.s b/qemu/tests/tcg/cris/check_movpmv32.s new file mode 100644 index 000000000..daf0970e4 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movpmv32.s @@ -0,0 +1,35 @@ +# mach: crisv32 +# output: 11223320\nbb113344\naa557711\n + +# Test v32-specific special registers. FIXME: more registers. + + .include "testutils.inc" + start + .data +store: + .dword 0x11223344 + .dword 0x77665544 + + .text + moveq -1,r3 + move.d store,r4 + move vr,[r4] + move [r4+],mof + move mof,r3 + checkr3 11223320 + + moveq -1,r3 + clearf zcvn + move 0xbb113344,mof + test_cc 0 0 0 0 + move mof,r3 + checkr3 bb113344 + + setf zcvn + move 0xaa557711,mof + test_cc 1 1 1 1 + move mof,[r4] + move.d [r4],r3 + checkr3 aa557711 + + quit diff --git a/qemu/tests/tcg/cris/check_movpr.s b/qemu/tests/tcg/cris/check_movpr.s new file mode 100644 index 000000000..eef9bdb4f --- /dev/null +++ b/qemu/tests/tcg/cris/check_movpr.s @@ -0,0 +1,28 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: ffffff00\nffff0000\n0\nbb113344\n + +# Test generic "move Ps,Rd" and "move Rs,Pd" insns; the ones with +# functionality common to all models. + + .include "testutils.inc" + start + moveq -1,r3 + clear.b r3 + checkr3 ffffff00 + + moveq -1,r3 + clear.w r3 + checkr3 ffff0000 + + moveq -1,r3 + clear.d r3 + checkr3 0 + + moveq -1,r3 + move.d 0xbb113344,r4 + setf zcvn + move r4,srp + move srp,r3 + test_cc 1 1 1 1 + checkr3 bb113344 + quit diff --git a/qemu/tests/tcg/cris/check_movprv32.s b/qemu/tests/tcg/cris/check_movprv32.s new file mode 100644 index 000000000..d0d90e124 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movprv32.s @@ -0,0 +1,21 @@ +# mach: crisv32 +# output: ffffff20\nbb113344\n + +# Test v32-specific special registers. FIXME: more registers. + + .include "testutils.inc" + start + moveq -1,r3 + setf zcvn + move vr,r3 + test_cc 1 1 1 1 + checkr3 ffffff20 + + moveq -1,r3 + move.d 0xbb113344,r4 + clearf cvnz + move r4,mof + test_cc 0 0 0 0 + move mof,r3 + checkr3 bb113344 + quit diff --git a/qemu/tests/tcg/cris/check_movscr.s b/qemu/tests/tcg/cris/check_movscr.s new file mode 100644 index 000000000..53c8ce6b5 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movscr.s @@ -0,0 +1,29 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 42\nffffff85\n7685\nffff8765\n0\n + +; Move constant byte, word, dword to register. Check that sign-extension +; is performed. + + .include "testutils.inc" + start + moveq -1,r3 + movs.b 0x42,r3 + checkr3 42 + + movs.b 0x85,r3 + test_move_cc 1 0 0 0 + checkr3 ffffff85 + + movs.w 0x7685,r3 + test_move_cc 0 0 0 0 + checkr3 7685 + + movs.w 0x8765,r3 + test_move_cc 1 0 0 0 + checkr3 ffff8765 + + movs.w 0,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_movsm.s b/qemu/tests/tcg/cris/check_movsm.s new file mode 100644 index 000000000..7074336e7 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movsm.s @@ -0,0 +1,44 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 5\nfffffff5\n5\nfffffff5\n0\n + +; Movs between registers. Check that sign-extension is performed and the +; full register is set. + + .include "testutils.inc" + + .data +x: + .byte 5,-11 + .word 5,-11 + .word 0 + + start + move.d x,r5 + + moveq -1,r3 + movs.b [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 5 + + moveq 0,r3 + movs.b [r5],r3 + test_move_cc 1 0 0 0 + addq 1,r5 + checkr3 fffffff5 + + moveq -1,r3 + movs.w [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 5 + + moveq 0,r3 + movs.w [r5],r3 + test_move_cc 1 0 0 0 + addq 2,r5 + checkr3 fffffff5 + + movs.w [r5],r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_movsr.s b/qemu/tests/tcg/cris/check_movsr.s new file mode 100644 index 000000000..d1889a7a1 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movsr.s @@ -0,0 +1,46 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 5\nfffffff5\n5\nfffffff5\n0\n + +; Movs between registers. Check that sign-extension is performed and the +; full register is set. + + .include "testutils.inc" + start + moveq -1,r5 + moveq 5,r4 + move.b r4,r5 + moveq -1,r3 + movs.b r5,r3 + test_move_cc 0 0 0 0 + checkr3 5 + + moveq 0,r5 + moveq -11,r4 + move.b r4,r5 + moveq 0,r3 + movs.b r5,r3 + test_move_cc 1 0 0 0 + checkr3 fffffff5 + + moveq -1,r5 + moveq 5,r4 + move.w r4,r5 + moveq -1,r3 + movs.w r5,r3 + test_move_cc 0 0 0 0 + checkr3 5 + + moveq 0,r5 + moveq -11,r4 + move.w r4,r5 + moveq 0,r3 + movs.w r5,r3 + test_move_cc 1 0 0 0 + checkr3 fffffff5 + + moveq 0,r5 + movs.b r5,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_movucr.s b/qemu/tests/tcg/cris/check_movucr.s new file mode 100644 index 000000000..7c8487d1a --- /dev/null +++ b/qemu/tests/tcg/cris/check_movucr.s @@ -0,0 +1,33 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 42\n85\n7685\n8765\n0\n + +; Move constant byte, word, dword to register. Check that zero-extension +; is performed. + + .include "testutils.inc" + start + moveq -1,r3 + movu.b 0x42,r3 + test_move_cc 0 0 0 0 + checkr3 42 + + moveq -1,r3 + movu.b 0x85,r3 + test_move_cc 0 0 0 0 + checkr3 85 + + moveq -1,r3 + movu.w 0x7685,r3 + test_move_cc 0 0 0 0 + checkr3 7685 + + moveq -1,r3 + movu.w 0x8765,r3 + test_move_cc 0 0 0 0 + checkr3 8765 + + movu.b 0,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_movum.s b/qemu/tests/tcg/cris/check_movum.s new file mode 100644 index 000000000..038e53946 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movum.s @@ -0,0 +1,40 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 5\nf5\n5\nfff5\n0\n + +; Movu between registers. Check that zero-extension is performed and the +; full register is set. + + .include "testutils.inc" + + .data +x: + .byte 5,-11 + .word 5,-11 + .word 0 + + start + move.d x,r5 + + movu.b [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 5 + + movu.b [r5],r3 + test_move_cc 0 0 0 0 + addq 1,r5 + checkr3 f5 + + movu.w [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 5 + + movu.w [r5],r3 + test_move_cc 0 0 0 0 + addq 2,r5 + checkr3 fff5 + + movu.w [r5],r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_movur.s b/qemu/tests/tcg/cris/check_movur.s new file mode 100644 index 000000000..3ecf475f7 --- /dev/null +++ b/qemu/tests/tcg/cris/check_movur.s @@ -0,0 +1,45 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 5\nf5\n5\nfff5\n0\n + +; Movu between registers. Check that zero-extension is performed and the +; full register is set. + + .include "testutils.inc" + start + moveq -1,r5 + moveq 5,r4 + move.b r4,r5 + moveq -1,r3 + movu.b r5,r3 + test_move_cc 0 0 0 0 + checkr3 5 + + moveq 0,r5 + moveq -11,r4 + move.b r4,r5 + moveq -1,r3 + movu.b r5,r3 + test_move_cc 0 0 0 0 + checkr3 f5 + + moveq -1,r5 + moveq 5,r4 + move.w r4,r5 + moveq -1,r3 + movu.w r5,r3 + test_move_cc 0 0 0 0 + checkr3 5 + + moveq 0,r5 + moveq -11,r4 + move.w r4,r5 + moveq -1,r3 + movu.w r5,r3 + test_move_cc 0 0 0 0 + checkr3 fff5 + + movu.w 0,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_mulv32.s b/qemu/tests/tcg/cris/check_mulv32.s new file mode 100644 index 000000000..f37935876 --- /dev/null +++ b/qemu/tests/tcg/cris/check_mulv32.s @@ -0,0 +1,51 @@ +# mach: crisv32 +# output: fffffffe\n +# output: ffffffff\n +# output: fffffffe\n +# output: 1\n +# output: fffffffe\n +# output: ffffffff\n +# output: fffffffe\n +# output: 1\n + +; Check that carry is not modified on v32. + + .include "testutils.inc" + start + moveq -1,r3 + moveq 2,r4 + setf c + muls.d r4,r3 + test_cc 1 0 0 1 + checkr3 fffffffe + move mof,r3 + checkr3 ffffffff + + moveq -1,r3 + moveq 2,r4 + setf c + mulu.d r4,r3 + test_cc 0 0 1 1 + checkr3 fffffffe + move mof,r3 + checkr3 1 + + moveq -1,r3 + moveq 2,r4 + clearf c + muls.d r4,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + move mof,r3 + checkr3 ffffffff + + moveq -1,r3 + moveq 2,r4 + clearf c + mulu.d r4,r3 + test_cc 0 0 1 0 + checkr3 fffffffe + move mof,r3 + checkr3 1 + + quit diff --git a/qemu/tests/tcg/cris/check_mulx.s b/qemu/tests/tcg/cris/check_mulx.s new file mode 100644 index 000000000..d43241a6f --- /dev/null +++ b/qemu/tests/tcg/cris/check_mulx.s @@ -0,0 +1,246 @@ +# mach: crisv10 crisv32 +# output: fffffffe\nffffffff\nfffffffe\n1\nfffffffe\nffffffff\nfffffffe\n1\nfffe0001\n0\nfffe0001\n0\n1\n0\n1\nfffffffe\n193eade2\n277e3a49\n193eade2\n277e3a49\nfffffffe\nffffffff\n1fffe\n0\nfffffffe\nffffffff\n1fffe\n0\n1\n0\nfffe0001\n0\nfdbdade2\nffffffff\n420fade2\n0\nfffffffe\nffffffff\n1fe\n0\nfffffffe\nffffffff\n1fe\n0\n1\n0\nfe01\n0\n1\n0\nfe01\n0\nffffd9e2\nffffffff\n2be2\n0\n0\n0\n0\n0\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq 2,r4 + muls.d r4,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + move mof,r3 + checkr3 ffffffff + + moveq -1,r3 + moveq 2,r4 + mulu.d r4,r3 + test_cc 0 0 1 0 + checkr3 fffffffe + move mof,r3 + checkr3 1 + + moveq 2,r3 + moveq -1,r4 + muls.d r4,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + move mof,r3 + checkr3 ffffffff + + moveq 2,r3 + moveq -1,r4 + mulu.d r4,r3 + test_cc 0 0 1 0 + checkr3 fffffffe + move mof,r3 + checkr3 1 + + move.d 0xffff,r4 + move.d r4,r3 + muls.d r4,r3 + test_cc 0 0 1 0 + checkr3 fffe0001 + move mof,r3 + checkr3 0 + + move.d 0xffff,r4 + move.d r4,r3 + mulu.d r4,r3 + test_cc 0 0 0 0 + checkr3 fffe0001 + move mof,r3 + checkr3 0 + + moveq -1,r4 + move.d r4,r3 + muls.d r4,r3 + test_cc 0 0 0 0 + checkr3 1 + move mof,r3 + checkr3 0 + + moveq -1,r4 + move.d r4,r3 + mulu.d r4,r3 + test_cc 1 0 1 0 + checkr3 1 + move mof,r3 + checkr3 fffffffe + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + muls.d r4,r3 + test_cc 0 0 1 0 + checkr3 193eade2 + move mof,r3 + checkr3 277e3a49 + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + mulu.d r4,r3 + test_cc 0 0 1 0 + checkr3 193eade2 + move mof,r3 + checkr3 277e3a49 + + move.d 0xffff,r3 + moveq 2,r4 + muls.w r4,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + move mof,r3 + checkr3 ffffffff + + moveq -1,r3 + moveq 2,r4 + mulu.w r4,r3 + test_cc 0 0 0 0 + checkr3 1fffe + move mof,r3 + checkr3 0 + + moveq 2,r3 + move.d 0xffff,r4 + muls.w r4,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + move mof,r3 + checkr3 ffffffff + + moveq 2,r3 + moveq -1,r4 + mulu.w r4,r3 + test_cc 0 0 0 0 + checkr3 1fffe + move mof,r3 + checkr3 0 + + move.d 0xffff,r4 + move.d r4,r3 + muls.w r4,r3 + test_cc 0 0 0 0 + checkr3 1 + move mof,r3 + checkr3 0 + + moveq -1,r4 + move.d r4,r3 + mulu.w r4,r3 + test_cc 0 0 0 0 + checkr3 fffe0001 + move mof,r3 + checkr3 0 + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + muls.w r4,r3 + test_cc 1 0 0 0 + checkr3 fdbdade2 + move mof,r3 + checkr3 ffffffff + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + mulu.w r4,r3 + test_cc 0 0 0 0 + checkr3 420fade2 + move mof,r3 + checkr3 0 + + move.d 0xff,r3 + moveq 2,r4 + muls.b r4,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + move mof,r3 + checkr3 ffffffff + + moveq -1,r3 + moveq 2,r4 + mulu.b r4,r3 + test_cc 0 0 0 0 + checkr3 1fe + move mof,r3 + checkr3 0 + + moveq 2,r3 + moveq -1,r4 + muls.b r4,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + move mof,r3 + checkr3 ffffffff + + moveq 2,r3 + moveq -1,r4 + mulu.b r4,r3 + test_cc 0 0 0 0 + checkr3 1fe + move mof,r3 + checkr3 0 + + move.d 0xff,r4 + move.d r4,r3 + muls.b r4,r3 + test_cc 0 0 0 0 + checkr3 1 + move mof,r3 + checkr3 0 + + moveq -1,r4 + move.d r4,r3 + mulu.b r4,r3 + test_cc 0 0 0 0 + checkr3 fe01 + move mof,r3 + checkr3 0 + + move.d 0xfeda49ff,r4 + move.d r4,r3 + muls.b r4,r3 + test_cc 0 0 0 0 + checkr3 1 + move mof,r3 + checkr3 0 + + move.d 0xfeda49ff,r4 + move.d r4,r3 + mulu.b r4,r3 + test_cc 0 0 0 0 + checkr3 fe01 + move mof,r3 + checkr3 0 + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + muls.b r4,r3 + test_cc 1 0 0 0 + checkr3 ffffd9e2 + move mof,r3 + checkr3 ffffffff + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + mulu.b r4,r3 + test_cc 0 0 0 0 + checkr3 2be2 + move mof,r3 + checkr3 0 + + moveq 0,r3 + move.d 0xf87f4aeb,r4 + muls.d r4,r3 + test_cc 0 1 0 0 + checkr3 0 + move mof,r3 + checkr3 0 + + move.d 0xf87f4aeb,r3 + moveq 0,r4 + mulu.d r4,r3 + test_cc 0 1 0 0 + checkr3 0 + move mof,r3 + checkr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_neg.s b/qemu/tests/tcg/cris/check_neg.s new file mode 100644 index 000000000..963c4b6f5 --- /dev/null +++ b/qemu/tests/tcg/cris/check_neg.s @@ -0,0 +1,104 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: ffffffff\nffffffff\n0\n80000000\n1\nba987655\nffff\nffff\n0\n89ab8000\nffff0001\n45677655\nff\nff\n0\n89abae80\nffffff01\n45678955\n + + .include "testutils.inc" + start + moveq 0,r3 + moveq 1,r4 + neg.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 1,r3 + moveq 0,r4 + neg.d r3,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + +;; FIXME: this was wrong. + moveq 0,r3 + neg.d r3,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0x80000000,r3 + neg.d r3,r3 + test_move_cc 1 0 0 0 + checkr3 80000000 + + moveq -1,r3 + neg.d r3,r3 + test_move_cc 0 0 0 0 + checkr3 1 + + move.d 0x456789ab,r3 + neg.d r3,r3 + test_move_cc 1 0 0 0 + checkr3 ba987655 + + moveq 0,r3 + moveq 1,r4 + neg.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffff + + moveq 1,r3 + moveq 0,r4 + neg.w r3,r3 + test_move_cc 1 0 0 0 + checkr3 ffff + + moveq 0,r3 + neg.w r3,r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0x89ab8000,r3 + neg.w r3,r3 + test_move_cc 1 0 0 0 + checkr3 89ab8000 + + moveq -1,r3 + neg.w r3,r3 + test_move_cc 0 0 0 0 + checkr3 ffff0001 + + move.d 0x456789ab,r3 + neg.w r3,r3 + test_move_cc 0 0 0 0 + checkr3 45677655 + + moveq 0,r3 + moveq 1,r4 + neg.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 ff + + moveq 1,r3 + moveq 0,r4 + neg.b r3,r3 + test_move_cc 1 0 0 0 + checkr3 ff + + moveq 0,r3 + neg.b r3,r3 + test_move_cc 0 1 0 0 + checkr3 0 + +;; FIXME: was wrong. + move.d 0x89abae80,r3 + neg.b r3,r3 + test_move_cc 1 0 0 1 + checkr3 89abae80 + + moveq -1,r3 + neg.b r3,r3 + test_move_cc 0 0 0 0 + checkr3 ffffff01 + + move.d 0x456789ab,r3 + neg.b r3,r3 + test_move_cc 0 0 0 0 + checkr3 45678955 + + quit diff --git a/qemu/tests/tcg/cris/check_not.s b/qemu/tests/tcg/cris/check_not.s new file mode 100644 index 000000000..33bcf155e --- /dev/null +++ b/qemu/tests/tcg/cris/check_not.s @@ -0,0 +1,31 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: fffffffe\nfffffffd\nffff0f00\n0\n87ecbbad\n + + .include "testutils.inc" + start + moveq 1,r3 + not r3 + test_move_cc 1 0 0 0 + checkr3 fffffffe + + moveq 2,r3 + not r3 + test_move_cc 1 0 0 0 + checkr3 fffffffd + + move.d 0xf0ff,r3 + not r3 + test_move_cc 1 0 0 0 + checkr3 ffff0f00 + + moveq -1,r3 + not r3 + test_move_cc 0 1 0 0 + checkr3 0 + + move.d 0x78134452,r3 + not r3 + test_move_cc 1 0 0 0 + checkr3 87ecbbad + + quit diff --git a/qemu/tests/tcg/cris/check_openpf1.c b/qemu/tests/tcg/cris/check_openpf1.c new file mode 100644 index 000000000..fdcf4c5c3 --- /dev/null +++ b/qemu/tests/tcg/cris/check_openpf1.c @@ -0,0 +1,38 @@ +/* Check that --sysroot is applied to open(2). +#sim: --sysroot=@exedir@ + + We assume, with EXE being the name of the executable: + - The simulator executes with cwd the same directory where the executable + is located (so argv[0] contains a plain filename without directory + components). + - There's no /EXE on the host file system. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +int main (int argc, char *argv[]) +{ + char *fnam = argv[0]; + FILE *f; + if (argv[0][0] != '/') + { + fnam = malloc (strlen (argv[0]) + 2); + if (fnam == NULL) + abort (); + strcpy (fnam, "/"); + strcat (fnam, argv[0]); + } + + f = fopen (fnam, "rb"); + if (f == NULL) + abort (); + fclose(f); + + /* Cover another execution path. */ + if (fopen ("/nonexistent", "rb") != NULL + || errno != ENOENT) + abort (); + printf ("pass\n"); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_openpf2.c b/qemu/tests/tcg/cris/check_openpf2.c new file mode 100644 index 000000000..5d56189f8 --- /dev/null +++ b/qemu/tests/tcg/cris/check_openpf2.c @@ -0,0 +1,16 @@ +/* Check that the simulator has chdir:ed to the --sysroot argument +#sim: --sysroot=@srcdir@ + (or that --sysroot is applied to relative file paths). */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +int main (int argc, char *argv[]) +{ + FILE *f = fopen ("check_openpf2.c", "rb"); + if (f == NULL) + abort (); + fclose(f); + printf ("pass\n"); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_openpf3.c b/qemu/tests/tcg/cris/check_openpf3.c new file mode 100644 index 000000000..557adee92 --- /dev/null +++ b/qemu/tests/tcg/cris/check_openpf3.c @@ -0,0 +1,49 @@ +/* Basic file operations (rename, unlink); once without sysroot. We + also test that the simulator has chdir:ed to PREFIX, when defined. */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#ifndef PREFIX +#define PREFIX +#endif + +void err (const char *s) +{ + perror (s); + abort (); +} + +int main (int argc, char *argv[]) +{ + FILE *f; + struct stat buf; + + unlink (PREFIX "testfoo2.tmp"); + + f = fopen ("testfoo1.tmp", "w"); + if (f == NULL) + err ("open"); + fclose (f); + + if (rename (PREFIX "testfoo1.tmp", PREFIX "testfoo2.tmp") != 0) + err ("rename"); + + if (stat (PREFIX "testfoo2.tmp", &buf) != 0 + || !S_ISREG (buf.st_mode)) + err ("stat 1"); + + if (stat ("testfoo2.tmp", &buf) != 0 + || !S_ISREG (buf.st_mode)) + err ("stat 2"); + + if (unlink (PREFIX "testfoo2.tmp") != 0) + err ("unlink"); + + printf ("pass\n"); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_openpf4.c b/qemu/tests/tcg/cris/check_openpf4.c new file mode 100644 index 000000000..8bbee41a6 --- /dev/null +++ b/qemu/tests/tcg/cris/check_openpf4.c @@ -0,0 +1,5 @@ +/* Basic file operations, now *with* sysroot. +#sim: --sysroot=@exedir@ +*/ +#define PREFIX "/" +#include "check_openpf3.c" diff --git a/qemu/tests/tcg/cris/check_openpf5.c b/qemu/tests/tcg/cris/check_openpf5.c new file mode 100644 index 000000000..1f86ea283 --- /dev/null +++ b/qemu/tests/tcg/cris/check_openpf5.c @@ -0,0 +1,56 @@ +/* Check that TRT happens when error on too many opened files. +#notarget: cris*-*-elf +#sim: --sysroot=@exedir@ +*/ +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +int main (int argc, char *argv[]) +{ + int i; + int filemax; + +#ifdef OPEN_MAX + filemax = OPEN_MAX; +#else + filemax = sysconf (_SC_OPEN_MAX); +#endif + + char *fn = malloc (strlen (argv[0]) + 2); + if (fn == NULL) + abort (); + strcpy (fn, "/"); + strcat (fn, argv[0]); + + for (i = 0; i < filemax + 1; i++) + { + if (open (fn, O_RDONLY) < 0) + { + /* Shouldn't happen too early. */ + if (i < filemax - 3 - 1) + { + fprintf (stderr, "i: %d\n", i); + abort (); + } + if (errno != EMFILE) + { + perror ("open"); + abort (); + } + goto ok; + } + } + abort (); + +ok: + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_orc.s b/qemu/tests/tcg/cris/check_orc.s new file mode 100644 index 000000000..c733f036a --- /dev/null +++ b/qemu/tests/tcg/cris/check_orc.s @@ -0,0 +1,71 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 3\n3\nffff\nffffffff\n7c33f7db\nffff0003\n3\nfedaffff\n7813f7db\n3\n3\nfeb\n781344db\n + + .include "testutils.inc" + start + moveq 1,r3 + or.d 2,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + moveq 2,r3 + or.d 1,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0xf0ff,r3 + or.d 0xff0f,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r3 + or.d -1,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x78134452,r3 + or.d 0x5432f789,r3 + test_move_cc 0 0 0 0 + checkr3 7c33f7db + + move.d 0xffff0001,r3 + or.w 2,r3 + test_move_cc 0 0 0 0 + checkr3 ffff0003 + + moveq 2,r3 + or.w 1,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0xfedaffaf,r3 + or.w 0xff5f,r3 + test_move_cc 1 0 0 0 + checkr3 fedaffff + + move.d 0x78134452,r3 + or.w 0xf789,r3 + test_move_cc 1 0 0 0 + checkr3 7813f7db + + moveq 1,r3 + or.b 2,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + moveq 2,r3 + or.b 1,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0xfa3,r3 + or.b 0x4a,r3 + test_move_cc 1 0 0 0 + checkr3 feb + + move.d 0x78134453,r3 + or.b 0x89,r3 + test_move_cc 1 0 0 0 + checkr3 781344db + + quit diff --git a/qemu/tests/tcg/cris/check_orm.s b/qemu/tests/tcg/cris/check_orm.s new file mode 100644 index 000000000..ee723a6aa --- /dev/null +++ b/qemu/tests/tcg/cris/check_orm.s @@ -0,0 +1,75 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 3\n3\nffff\nffffffff\n7c33f7db\nffff0003\n3\nfedaffff\n7813f7db\n3\n3\nfeb\n781344db\n + + .include "testutils.inc" + .data +x: + .dword 2,1,0xff0f,-1,0x5432f789 + .word 2,1,0xff5f,0xf789 + .byte 2,1,0x4a,0x89 + + start + moveq 1,r3 + move.d x,r5 + or.d [r5+],r3 + checkr3 3 + + moveq 2,r3 + or.d [r5],r3 + addq 4,r5 + checkr3 3 + + move.d 0xf0ff,r3 + or.d [r5+],r3 + checkr3 ffff + + moveq -1,r3 + or.d [r5+],r3 + checkr3 ffffffff + + move.d 0x78134452,r3 + or.d [r5+],r3 + checkr3 7c33f7db + + move.d 0xffff0001,r3 + or.w [r5+],r3 + checkr3 ffff0003 + + moveq 2,r3 + or.w [r5],r3 + addq 2,r5 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0xfedaffaf,r3 + or.w [r5+],r3 + test_move_cc 1 0 0 0 + checkr3 fedaffff + + move.d 0x78134452,r3 + or.w [r5+],r3 + test_move_cc 1 0 0 0 + checkr3 7813f7db + + moveq 1,r3 + or.b [r5+],r3 + test_move_cc 0 0 0 0 + checkr3 3 + + moveq 2,r3 + or.b [r5],r3 + addq 1,r5 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0xfa3,r3 + or.b [r5+],r3 + test_move_cc 1 0 0 0 + checkr3 feb + + move.d 0x78134453,r3 + or.b [r5],r3 + test_move_cc 1 0 0 0 + checkr3 781344db + + quit diff --git a/qemu/tests/tcg/cris/check_orq.s b/qemu/tests/tcg/cris/check_orq.s new file mode 100644 index 000000000..5060edc72 --- /dev/null +++ b/qemu/tests/tcg/cris/check_orq.s @@ -0,0 +1,41 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 3\n3\nffffffff\nffffffff\n1f\nffffffe0\n7813445e\n + + .include "testutils.inc" + start + moveq 1,r3 + orq 2,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + moveq 2,r3 + orq 1,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0xf0ff,r3 + orq -1,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 0,r3 + orq -1,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + moveq 0,r3 + orq 31,r3 + test_move_cc 0 0 0 0 + checkr3 1f + + moveq 0,r3 + orq -32,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffe0 + + move.d 0x78134452,r3 + orq 12,r3 + test_move_cc 0 0 0 0 + checkr3 7813445e + + quit diff --git a/qemu/tests/tcg/cris/check_orr.s b/qemu/tests/tcg/cris/check_orr.s new file mode 100644 index 000000000..a514c11bc --- /dev/null +++ b/qemu/tests/tcg/cris/check_orr.s @@ -0,0 +1,84 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 3\n3\nffff\nffffffff\n7c33f7db\nffff0003\n3\nfedaffff\n7813f7db\n3\n3\nfeb\n781344db\n + + .include "testutils.inc" + start + moveq 1,r3 + moveq 2,r4 + or.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + moveq 2,r3 + moveq 1,r4 + or.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0xff0f,r4 + move.d 0xf0ff,r3 + or.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff + + moveq -1,r4 + move.d r4,r3 + or.d r4,r3 + test_move_cc 1 0 0 0 + checkr3 ffffffff + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + or.d r4,r3 + test_move_cc 0 0 0 0 + checkr3 7c33f7db + + move.d 0xffff0001,r3 + moveq 2,r4 + or.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 ffff0003 + + moveq 2,r3 + move.d 0xffff0001,r4 + or.w r4,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0xfedaffaf,r3 + move.d 0xffffff5f,r4 + or.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 fedaffff + + move.d 0x5432f789,r4 + move.d 0x78134452,r3 + or.w r4,r3 + test_move_cc 1 0 0 0 + checkr3 7813f7db + + moveq 1,r3 + move.d 0xffffff02,r4 + or.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + moveq 2,r3 + moveq 1,r4 + or.b r4,r3 + test_move_cc 0 0 0 0 + checkr3 3 + + move.d 0x4a,r4 + move.d 0xfa3,r3 + or.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 feb + + move.d 0x5432f789,r4 + move.d 0x78134453,r3 + or.b r4,r3 + test_move_cc 1 0 0 0 + checkr3 781344db + + quit diff --git a/qemu/tests/tcg/cris/check_ret.s b/qemu/tests/tcg/cris/check_ret.s new file mode 100644 index 000000000..b44fb2593 --- /dev/null +++ b/qemu/tests/tcg/cris/check_ret.s @@ -0,0 +1,25 @@ +# mach: crisv3 crisv8 crisv10 +# output: 3\n + +# Test that ret works. + + .include "testutils.inc" + start +x: + moveq 0,r3 + jsr z +w: + quit +y: + addq 1,r3 + checkr3 3 + quit + +z: + addq 1,r3 + move srp,r2 + add.d y-w,r2 + move r2,srp + ret + addq 1,r3 + quit diff --git a/qemu/tests/tcg/cris/check_scc.s b/qemu/tests/tcg/cris/check_scc.s new file mode 100644 index 000000000..4a8674cc1 --- /dev/null +++ b/qemu/tests/tcg/cris/check_scc.s @@ -0,0 +1,95 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n0\n1\n0\n1\n0\n1\n0\n0\n1\n1\n0\n1\n0\n1\n0\n1\n0\n0\n1\n0\n1\n1\n0\n1\n0\n0\n1\n1\n0\n1\n1\n0\n + + .include "testutils.inc" + + .macro lcheckr3 v + move $ccs, $r9 + checkr3 \v + move $r9, $ccs + .endm + + start + clearf nzvc + scc r3 + lcheckr3 1 + scs r3 + lcheckr3 0 + sne r3 + lcheckr3 1 + seq r3 + lcheckr3 0 + svc r3 + lcheckr3 1 + svs r3 + lcheckr3 0 + spl r3 + lcheckr3 1 + smi r3 + lcheckr3 0 + sls r3 + lcheckr3 0 + shi r3 + lcheckr3 1 + sge r3 + lcheckr3 1 + slt r3 + lcheckr3 0 + sgt r3 + lcheckr3 1 + sle r3 + lcheckr3 0 + sa r3 + lcheckr3 1 + setf nzvc + scc r3 + lcheckr3 0 + scs r3 + lcheckr3 1 + sne r3 + lcheckr3 0 + svc r3 + lcheckr3 0 + svs r3 + lcheckr3 1 + spl r3 + lcheckr3 0 + smi r3 + lcheckr3 1 + sls r3 + lcheckr3 1 + shi r3 + lcheckr3 0 + sge r3 + lcheckr3 1 + slt r3 + lcheckr3 0 + sgt r3 + lcheckr3 0 + sle r3 + lcheckr3 1 + sa r3 + lcheckr3 1 + clearf n + sge r3 + lcheckr3 0 + slt r3 + lcheckr3 1 + + .if 1 ;..asm.arch.cris.v32 + setf p + ssb r3 + .else + moveq 1,r3 + .endif + lcheckr3 1 + + .if 1 ;..asm.arch.cris.v32 + clearf p + ssb r3 + .else + moveq 0,r3 + .endif + lcheckr3 0 + + quit diff --git a/qemu/tests/tcg/cris/check_settls1.c b/qemu/tests/tcg/cris/check_settls1.c new file mode 100644 index 000000000..69d202652 --- /dev/null +++ b/qemu/tests/tcg/cris/check_settls1.c @@ -0,0 +1,45 @@ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> + +#include <sys/syscall.h> + +#ifndef SYS_set_thread_area +#define SYS_set_thread_area 243 +#endif + +int main (void) +{ + unsigned long tp, old_tp; + int ret; + + asm volatile ("move $pid,%0" : "=r" (old_tp)); + old_tp &= ~0xff; + + ret = syscall (SYS_set_thread_area, 0xf0); + if (ret != -1 || errno != EINVAL) { + syscall (SYS_set_thread_area, old_tp); + perror ("Invalid thread area accepted:"); + abort(); + } + + ret = syscall (SYS_set_thread_area, 0xeddeed00); + if (ret != 0) { + perror ("Valid thread area not accepted: "); + abort (); + } + + asm volatile ("move $pid,%0" : "=r" (tp)); + tp &= ~0xff; + syscall (SYS_set_thread_area, old_tp); + + if (tp != 0xeddeed00) { + * (volatile int *) 0 = 0; + perror ("tls2"); + abort (); + } + + printf ("pass\n"); + return EXIT_SUCCESS; +} diff --git a/qemu/tests/tcg/cris/check_sigalrm.c b/qemu/tests/tcg/cris/check_sigalrm.c new file mode 100644 index 000000000..39fa8d9ba --- /dev/null +++ b/qemu/tests/tcg/cris/check_sigalrm.c @@ -0,0 +1,26 @@ +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +#define MAGIC (0xdeadbeef) + +int s = 0; +void sighandler(int sig) +{ + s = MAGIC; +} + +int main(int argc, char **argv) +{ + int p; + + p = getpid(); + signal(SIGALRM, sighandler); + kill(p, SIGALRM); + if (s != MAGIC) + return EXIT_FAILURE; + + printf ("passed\n"); + return EXIT_SUCCESS; +} diff --git a/qemu/tests/tcg/cris/check_stat1.c b/qemu/tests/tcg/cris/check_stat1.c new file mode 100644 index 000000000..2e2cae51d --- /dev/null +++ b/qemu/tests/tcg/cris/check_stat1.c @@ -0,0 +1,16 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +int main (void) +{ + struct stat buf; + + if (stat (".", &buf) != 0 + || !S_ISDIR (buf.st_mode)) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_stat2.c b/qemu/tests/tcg/cris/check_stat2.c new file mode 100644 index 000000000..e36172ed2 --- /dev/null +++ b/qemu/tests/tcg/cris/check_stat2.c @@ -0,0 +1,20 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +int main (void) +{ + struct stat buf; + + if (lstat (".", &buf) != 0 + || !S_ISDIR (buf.st_mode)) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_stat3.c b/qemu/tests/tcg/cris/check_stat3.c new file mode 100644 index 000000000..36a9d5d27 --- /dev/null +++ b/qemu/tests/tcg/cris/check_stat3.c @@ -0,0 +1,25 @@ +/* Simulator options: +#sim: --sysroot=@exedir@ +*/ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + char path[1024] = "/"; + struct stat buf; + + strncat(path, argv[0], sizeof(path) - 2); + if (stat (".", &buf) != 0 + || !S_ISDIR (buf.st_mode)) + abort (); + if (stat (path, &buf) != 0 + || !S_ISREG (buf.st_mode)) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_stat4.c b/qemu/tests/tcg/cris/check_stat4.c new file mode 100644 index 000000000..04f21fe7c --- /dev/null +++ b/qemu/tests/tcg/cris/check_stat4.c @@ -0,0 +1,27 @@ +/* Simulator options: +#notarget: cris*-*-elf +#sim: --sysroot=@exedir@ +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + char path[1024] = "/"; + struct stat buf; + + strncat(path, argv[0], sizeof(path) - 2); + if (lstat (".", &buf) != 0 + || !S_ISDIR (buf.st_mode)) + abort (); + if (lstat (path, &buf) != 0 + || !S_ISREG (buf.st_mode)) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_subc.s b/qemu/tests/tcg/cris/check_subc.s new file mode 100644 index 000000000..e34b5448e --- /dev/null +++ b/qemu/tests/tcg/cris/check_subc.s @@ -0,0 +1,87 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n1fffe\nfffffffe\ncc463bdb\nffff0001\n1\nfffe\nfedafffe\n78133bdb\nffffff01\n1\nfe\nfeda49fe\n781344db\n85649200\n + + .include "testutils.inc" + start + + moveq -1,r3 + sub.d -2,r3 + test_cc 0 0 0 0 + checkr3 1 + + moveq 2,r3 + sub.d 1,r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d 0xffff,r3 + sub.d -0xffff,r3 + test_cc 0 0 0 1 + checkr3 1fffe + + moveq -1,r3 + sub.d 1,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + + move.d 0x78134452,r3 + sub.d -0x5432f789,r3 + test_cc 1 0 1 1 + checkr3 cc463bdb + + moveq -1,r3 + sub.w -2,r3 + test_cc 0 0 0 0 + checkr3 ffff0001 + + moveq 2,r3 + sub.w 1,r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d 0xffff,r3 + sub.w 1,r3 + test_cc 1 0 0 0 + checkr3 fffe + + move.d 0xfedaffff,r3 + sub.w 1,r3 + test_cc 1 0 0 0 + checkr3 fedafffe + + move.d 0x78134452,r3 + sub.w 0x877,r3 + test_cc 0 0 0 0 + checkr3 78133bdb + + moveq -1,r3 + sub.b -2,r3 + test_cc 0 0 0 0 + checkr3 ffffff01 + + moveq 2,r3 + sub.b 1,r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d 0xff,r3 + sub.b 1,r3 + test_cc 1 0 0 0 + checkr3 fe + + move.d 0xfeda49ff,r3 + sub.b 1,r3 + test_cc 1 0 0 0 + checkr3 feda49fe + + move.d 0x78134452,r3 + sub.b 0x77,r3 + test_cc 1 0 0 1 + checkr3 781344db + + move.d 0x85649282,r3 + sub.b 0x82,r3 + test_cc 0 1 0 0 + checkr3 85649200 + + quit diff --git a/qemu/tests/tcg/cris/check_subm.s b/qemu/tests/tcg/cris/check_subm.s new file mode 100644 index 000000000..e07ea02dd --- /dev/null +++ b/qemu/tests/tcg/cris/check_subm.s @@ -0,0 +1,96 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n1fffe\nfffffffe\ncc463bdb\nffff0001\n1\nfffe\nfedafffe\n78133bdb\nffffff01\n1\nfe\nfeda49fe\n781344db\n85649200\n + + .include "testutils.inc" + .data +x: + .dword -2,1,-0xffff,1,-0x5432f789 + .word -2,1,1,0x877 + .byte -2,1,0x77 + .byte 0x22 + + start + moveq -1,r3 + move.d x,r5 + sub.d [r5+],r3 + test_cc 0 0 0 0 + checkr3 1 + + moveq 2,r3 + sub.d [r5],r3 + test_cc 0 0 0 0 + addq 4,r5 + checkr3 1 + + move.d 0xffff,r3 + sub.d [r5+],r3 + test_cc 0 0 0 1 + checkr3 1fffe + + moveq -1,r3 + sub.d [r5+],r3 + test_cc 1 0 0 0 + checkr3 fffffffe + + move.d 0x78134452,r3 + sub.d [r5+],r3 + test_cc 1 0 1 1 + checkr3 cc463bdb + + moveq -1,r3 + sub.w [r5+],r3 + test_cc 0 0 0 0 + checkr3 ffff0001 + + moveq 2,r3 + sub.w [r5+],r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d 0xffff,r3 + sub.w [r5],r3 + test_cc 1 0 0 0 + checkr3 fffe + + move.d 0xfedaffff,r3 + sub.w [r5+],r3 + test_cc 1 0 0 0 + checkr3 fedafffe + + move.d 0x78134452,r3 + sub.w [r5+],r3 + test_cc 0 0 0 0 + checkr3 78133bdb + + moveq -1,r3 + sub.b [r5],r3 + test_cc 0 0 0 0 + addq 1,r5 + checkr3 ffffff01 + + moveq 2,r3 + sub.b [r5],r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d 0xff,r3 + sub.b [r5],r3 + test_cc 1 0 0 0 + checkr3 fe + + move.d 0xfeda49ff,r3 + sub.b [r5+],r3 + test_cc 1 0 0 0 + checkr3 feda49fe + + move.d 0x78134452,r3 + sub.b [r5+],r3 + test_cc 1 0 0 1 + checkr3 781344db + + move.d 0x85649222,r3 + sub.b [r5],r3 + test_cc 0 1 0 0 + checkr3 85649200 + + quit diff --git a/qemu/tests/tcg/cris/check_subq.s b/qemu/tests/tcg/cris/check_subq.s new file mode 100644 index 000000000..9e34fa31a --- /dev/null +++ b/qemu/tests/tcg/cris/check_subq.s @@ -0,0 +1,52 @@ +# mach: crisv3 crisv8 crisv10 crisv32 +# output: 0\nffffffff\nfffffffe\nffff\nff\n56788f9\n56788d9\n567889a\n0\n7ffffffc\n + + .include "testutils.inc" + start + moveq 1,r3 + subq 1,r3 + test_cc 0 1 0 0 + checkr3 0 + + subq 1,r3 + test_cc 1 0 0 1 + checkr3 ffffffff + + subq 1,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + + move.d 0x10000,r3 + subq 1,r3 + test_cc 0 0 0 0 + checkr3 ffff + + move.d 0x100,r3 + subq 1,r3 + test_cc 0 0 0 0 + checkr3 ff + + move.d 0x5678900,r3 + subq 7,r3 + test_cc 0 0 0 0 + checkr3 56788f9 + + subq 32,r3 + test_cc 0 0 0 0 + checkr3 56788d9 + + subq 63,r3 + test_cc 0 0 0 0 + checkr3 567889a + + move.d 34,r3 + subq 34,r3 + test_cc 0 1 0 0 + checkr3 0 + + move.d 0x80000024,r3 + subq 40,r3 + test_cc 0 0 1 0 + checkr3 7ffffffc + + quit diff --git a/qemu/tests/tcg/cris/check_subr.s b/qemu/tests/tcg/cris/check_subr.s new file mode 100644 index 000000000..742fbc891 --- /dev/null +++ b/qemu/tests/tcg/cris/check_subr.s @@ -0,0 +1,102 @@ +# mach: crisv0 crisv3 crisv8 crisv10 crisv32 +# output: 1\n1\n1fffe\nfffffffe\ncc463bdb\nffff0001\n1\nfffe\nfedafffe\n78133bdb\nffffff01\n1\nfe\nfeda49fe\n781344db\n85649200\n + + .include "testutils.inc" + start + moveq -1,r3 + moveq -2,r4 + sub.d r4,r3 + test_cc 0 0 0 0 + checkr3 1 + + moveq 2,r3 + moveq 1,r4 + sub.d r4,r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d 0xffff,r3 + move.d -0xffff,r4 + sub.d r4,r3 + test_cc 0 0 0 1 + checkr3 1fffe + + moveq 1,r4 + moveq -1,r3 + sub.d r4,r3 + test_cc 1 0 0 0 + checkr3 fffffffe + + move.d -0x5432f789,r4 + move.d 0x78134452,r3 + sub.d r4,r3 + test_cc 1 0 1 1 + checkr3 cc463bdb + + moveq -1,r3 + moveq -2,r4 + sub.w r4,r3 + test_cc 0 0 0 0 + checkr3 ffff0001 + + moveq 2,r3 + moveq 1,r4 + sub.w r4,r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d 0xffff,r3 + move.d -0xffff,r4 + sub.w r4,r3 + test_cc 1 0 0 0 + checkr3 fffe + + move.d 0xfedaffff,r3 + move.d -0xfedaffff,r4 + sub.w r4,r3 + test_cc 1 0 0 0 + checkr3 fedafffe + + move.d -0x5432f789,r4 + move.d 0x78134452,r3 + sub.w r4,r3 + test_cc 0 0 0 0 + checkr3 78133bdb + + moveq -1,r3 + moveq -2,r4 + sub.b r4,r3 + test_cc 0 0 0 0 + checkr3 ffffff01 + + moveq 2,r3 + moveq 1,r4 + sub.b r4,r3 + test_cc 0 0 0 0 + checkr3 1 + + move.d -0xff,r4 + move.d 0xff,r3 + sub.b r4,r3 + test_cc 1 0 0 0 + checkr3 fe + + move.d -0xfeda49ff,r4 + move.d 0xfeda49ff,r3 + sub.b r4,r3 + test_cc 1 0 0 0 + checkr3 feda49fe + + move.d -0x5432f789,r4 + move.d 0x78134452,r3 + sub.b r4,r3 + test_cc 1 0 0 1 + checkr3 781344db + + move.d 0x85649222,r3 + move.d 0x77445622,r4 + sub.b r4,r3 + test_cc 0 1 0 0 + checkr3 85649200 + + quit diff --git a/qemu/tests/tcg/cris/check_swap.c b/qemu/tests/tcg/cris/check_swap.c new file mode 100644 index 000000000..f851cbcef --- /dev/null +++ b/qemu/tests/tcg/cris/check_swap.c @@ -0,0 +1,76 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include "sys.h" +#include "crisutils.h" + +#define N 8 +#define W 4 +#define B 2 +#define R 1 + +static inline int cris_swap(const int mode, int x) +{ + switch (mode) + { + case N: asm ("swapn\t%0\n" : "+r" (x) : "0" (x)); break; + case W: asm ("swapw\t%0\n" : "+r" (x) : "0" (x)); break; + case B: asm ("swapb\t%0\n" : "+r" (x) : "0" (x)); break; + case R: asm ("swapr\t%0\n" : "+r" (x) : "0" (x)); break; + case B|R: asm ("swapbr\t%0\n" : "+r" (x) : "0" (x)); break; + case W|R: asm ("swapwr\t%0\n" : "+r" (x) : "0" (x)); break; + case W|B: asm ("swapwb\t%0\n" : "+r" (x) : "0" (x)); break; + case W|B|R: asm ("swapwbr\t%0\n" : "+r" (x) : "0" (x)); break; + case N|R: asm ("swapnr\t%0\n" : "+r" (x) : "0" (x)); break; + case N|B: asm ("swapnb\t%0\n" : "+r" (x) : "0" (x)); break; + case N|B|R: asm ("swapnbr\t%0\n" : "+r" (x) : "0" (x)); break; + case N|W: asm ("swapnw\t%0\n" : "+r" (x) : "0" (x)); break; + default: + err(); + break; + } + return x; +} + +/* Made this a macro to be able to pick up the location of the errors. */ +#define verify_swap(mode, val, expected, n, z) \ +do { \ + int r; \ + cris_tst_cc_init(); \ + r = cris_swap(mode, val); \ + cris_tst_mov_cc(n, z); \ + if (r != expected) \ + err(); \ +} while(0) + +void check_swap(void) +{ + /* Some of these numbers are borrowed from GDB's cris sim + testsuite. */ + if (cris_swap(N, 0) != 0xffffffff) + err(); + if (cris_swap(W, 0x12345678) != 0x56781234) + err(); + if (cris_swap(B, 0x12345678) != 0x34127856) + err(); + + verify_swap(R, 0x78134452, 0x1ec8224a, 0, 0); + verify_swap(B, 0x78134452, 0x13785244, 0, 0); + verify_swap(B|R, 0x78134452, 0xc81e4a22, 1, 0); + verify_swap(W, 0x78134452, 0x44527813, 0, 0); + verify_swap(W|R, 0x78134452, 0x224a1ec8, 0, 0); + verify_swap(W|B|R, 0x78134452, 0x4a22c81e, 0, 0); + verify_swap(N, 0x78134452, 0x87ecbbad, 1, 0); + verify_swap(N|R, 0x78134452, 0xe137ddb5, 1, 0); + verify_swap(N|B, 0x78134452, 0xec87adbb, 1, 0); + verify_swap(N|B|R, 0x78134452, 0x37e1b5dd, 0, 0); + verify_swap(N|W, 0x78134452, 0xbbad87ec, 1, 0); + verify_swap(N|B|R, 0xffffffff, 0, 0, 1); +} + +int main(void) +{ + check_swap(); + pass(); + return 0; +} diff --git a/qemu/tests/tcg/cris/check_time1.c b/qemu/tests/tcg/cris/check_time1.c new file mode 100644 index 000000000..3fcf0e153 --- /dev/null +++ b/qemu/tests/tcg/cris/check_time1.c @@ -0,0 +1,46 @@ +/* Basic time functionality test: check that milliseconds are + incremented for each syscall (does not work on host). */ +#include <stdio.h> +#include <time.h> +#include <sys/time.h> +#include <string.h> +#include <stdlib.h> + +void err (const char *s) +{ + perror (s); + abort (); +} + +int +main (void) +{ + struct timeval t_m = {0, 0}; + struct timezone t_z = {0, 0}; + struct timeval t_m1 = {0, 0}; + int i; + + if (gettimeofday (&t_m, &t_z) != 0) + err ("gettimeofday"); + + for (i = 1; i < 10000; i++) + if (gettimeofday (&t_m1, NULL) != 0) + err ("gettimeofday 1"); + else + if (t_m1.tv_sec * 1000000 + t_m1.tv_usec + != (t_m.tv_sec * 1000000 + t_m.tv_usec + i * 1000)) + { + fprintf (stderr, "t0 (%ld, %ld), i %d, t1 (%ld, %ld)\n", + t_m.tv_sec, t_m.tv_usec, i, t_m1.tv_sec, t_m1.tv_usec); + abort (); + } + + if (time (NULL) != t_m1.tv_sec) + { + fprintf (stderr, "time != gettod\n"); + abort (); + } + + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_time2.c b/qemu/tests/tcg/cris/check_time2.c new file mode 100644 index 000000000..20b69b4f6 --- /dev/null +++ b/qemu/tests/tcg/cris/check_time2.c @@ -0,0 +1,18 @@ +/* CB_SYS_time doesn't implement the Linux time syscall; the return + value isn't written to the argument. */ + +#include <time.h> +#include <stdio.h> +#include <stdlib.h> + +int +main (void) +{ + time_t x = (time_t) -1; + time_t t = time (&x); + + if (t == (time_t) -1 || t != x) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/qemu/tests/tcg/cris/check_xarith.s b/qemu/tests/tcg/cris/check_xarith.s new file mode 100644 index 000000000..80038b2ab --- /dev/null +++ b/qemu/tests/tcg/cris/check_xarith.s @@ -0,0 +1,72 @@ + +.include "testutils.inc" + + start + + moveq -1, $r0 + moveq 0, $r1 + addq 1, $r0 + ax + addq 0, $r1 + + move.d $r0, $r3 + checkr3 0 + move.d $r1, $r3 + checkr3 1 + + move.d 0, $r0 + moveq -1, $r1 + subq 1, $r0 + ax + subq 0, $r1 + + move.d $r0, $r3 + checkr3 ffffffff + move.d $r1, $r3 + checkr3 fffffffe + + + moveq -1, $r0 + moveq -1, $r1 + cmpq -1, $r0 + ax + cmpq -1, $r1 + beq 1f + nop + fail +1: + cmpq 0, $r0 + ax + cmpq -1, $r1 + bne 1f + nop + fail +1: + + ;; test for broken X sequence, run it several times. + moveq 8, $r0 +1: + moveq 0, $r3 + move.d $r0, $r1 + andq 1, $r1 + lslq 4, $r1 + moveq 1, $r2 + or.d $r1, $r2 + ba 2f + move $r2, $ccs +2: + addq 0, $r3 + move.d $r0, $r4 + move.d $r1, $r5 + move.d $r2, $r6 + move.d $r3, $r7 + lsrq 4, $r1 + move.d $r1, $r8 + xor $r1, $r3 + checkr3 0 + subq 1, $r0 + bne 1b + nop + + pass + quit diff --git a/qemu/tests/tcg/cris/crisutils.h b/qemu/tests/tcg/cris/crisutils.h new file mode 100644 index 000000000..3456b9d50 --- /dev/null +++ b/qemu/tests/tcg/cris/crisutils.h @@ -0,0 +1,76 @@ +#ifndef CRISUTILS_H +#define CRISUTILS_H 1 + +static char *tst_cc_loc = NULL; + +#define cris_tst_cc_init() \ +do { tst_cc_loc = "test_cc failed at " CURRENT_LOCATION; } while(0) + +/* We need a real symbol to signal error. */ +void _err(void) { + if (!tst_cc_loc) + tst_cc_loc = "tst_cc_failed\n"; + _fail(tst_cc_loc); +} + +static inline void cris_tst_cc_n1(void) +{ + asm volatile ("bpl _err\n" + "nop\n"); +} +static inline void cris_tst_cc_n0(void) +{ + asm volatile ("bmi _err\n" + "nop\n"); +} + +static inline void cris_tst_cc_z1(void) +{ + asm volatile ("bne _err\n" + "nop\n"); +} +static inline void cris_tst_cc_z0(void) +{ + asm volatile ("beq _err\n" + "nop\n"); +} +static inline void cris_tst_cc_v1(void) +{ + asm volatile ("bvc _err\n" + "nop\n"); +} +static inline void cris_tst_cc_v0(void) +{ + asm volatile ("bvs _err\n" + "nop\n"); +} + +static inline void cris_tst_cc_c1(void) +{ + asm volatile ("bcc _err\n" + "nop\n"); +} +static inline void cris_tst_cc_c0(void) +{ + asm volatile ("bcs _err\n" + "nop\n"); +} + +static inline void cris_tst_mov_cc(int n, int z) +{ + if (n) cris_tst_cc_n1(); else cris_tst_cc_n0(); + if (z) cris_tst_cc_z1(); else cris_tst_cc_z0(); + asm volatile ("" : : "g" (_err)); +} + +static inline void cris_tst_cc(const int n, const int z, + const int v, const int c) +{ + if (n) cris_tst_cc_n1(); else cris_tst_cc_n0(); + if (z) cris_tst_cc_z1(); else cris_tst_cc_z0(); + if (v) cris_tst_cc_v1(); else cris_tst_cc_v0(); + if (c) cris_tst_cc_c1(); else cris_tst_cc_c0(); + asm volatile ("" : : "g" (_err)); +} + +#endif diff --git a/qemu/tests/tcg/cris/crt.s b/qemu/tests/tcg/cris/crt.s new file mode 100644 index 000000000..af027d747 --- /dev/null +++ b/qemu/tests/tcg/cris/crt.s @@ -0,0 +1,13 @@ + .data +_stack_start: + .space 8192, 0 +_stack_end: + .text + .global _start +_start: + move.d _stack_end, $sp + jsr main + nop + moveq 0, $r10 + jump exit + nop diff --git a/qemu/tests/tcg/cris/sys.c b/qemu/tests/tcg/cris/sys.c new file mode 100644 index 000000000..551c5dd7c --- /dev/null +++ b/qemu/tests/tcg/cris/sys.c @@ -0,0 +1,51 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +static inline int mystrlen(char *s) { + int i = 0; + while (s[i]) + i++; + return i; +} + +void pass(void) { + char s[] = "passed.\n"; + write (1, s, sizeof (s) - 1); + exit (0); +} + +void _fail(char *reason) { + char s[] = "\nfailed: "; + int len = mystrlen(reason); + write (1, s, sizeof (s) - 1); + write (1, reason, len); + write (1, "\n", 1); +// exit (1); +} + +void *memset (void *s, int c, size_t n) { + char *p = s; + int i; + for (i = 0; i < n; i++) + p[i] = c; + return p; +} + +void exit (int status) { + asm volatile ("moveq 1, $r9\n" /* NR_exit. */ + "break 13\n"); + while(1) + ; +} + +ssize_t write (int fd, const void *buf, size_t count) { + int r; + asm ("move.d %0, $r10\n" + "move.d %1, $r11\n" + "move.d %2, $r12\n" + "moveq 4, $r9\n" /* NR_write. */ + "break 13\n" : : "r" (fd), "r" (buf), "r" (count) : "memory"); + asm ("move.d $r10, %0\n" : "=r" (r)); + return r; +} diff --git a/qemu/tests/tcg/cris/sys.h b/qemu/tests/tcg/cris/sys.h new file mode 100644 index 000000000..c5f88e1a2 --- /dev/null +++ b/qemu/tests/tcg/cris/sys.h @@ -0,0 +1,16 @@ +#include <unistd.h> + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +#define CURRENT_LOCATION __FILE__ ":" TOSTRING(__LINE__) + +#define err() \ +{ \ + _fail("at " CURRENT_LOCATION " "); \ +} + +#define mb() asm volatile ("" : : : "memory") + +void pass(void); +void _fail(char *reason); diff --git a/qemu/tests/tcg/cris/testutils.inc b/qemu/tests/tcg/cris/testutils.inc new file mode 100644 index 000000000..aa1641b2e --- /dev/null +++ b/qemu/tests/tcg/cris/testutils.inc @@ -0,0 +1,117 @@ + .syntax no_register_prefix + + .macro start + .text + .global main +main: + .endm + + .macro quit + jump pass + nop + .endm + + .macro pass + jump pass + nop + .endm + + .macro startnostack + start + .endm + + .macro fail + .data +99: + .asciz " checkr3 failed\n" + .text + move.d 99b, $r10 + jsr _fail + nop + .endm + + .macro checkr3 val + cmp.d 0x\val, $r3 + beq 100f + nop + .data +99: + .asciz "checkr3 failed\n" + .text + move.d 99b, $r10 + jsr _fail + nop +100: + .endm + +; Test the condition codes + .macro test_cc N Z V C + .if \N + bpl 9f + nop + .else + bmi 9f + nop + .endif + .if \Z + bne 9f + nop + .else + beq 9f + nop + .endif + .if \V + bvc 9f + nop + .else + bvs 9f + nop + .endif + .if \C + bcc 9f + nop + .else + bcs 9f + nop + .endif + ba 8f + nop +9: + .data +99: + .asciz "test_move_cc failed\n" + .text + move.d 99b, $r10 + jsr _fail + nop +8: + .endm + + + .macro test_move_cc N Z V C + .if \N + bpl 9f + nop + .else + bmi 9f + nop + .endif + .if \Z + bne 9f + nop + .else + beq 9f + nop + .endif + ba 8f + nop +9: + .data +99: + .asciz "test_move_cc failed\n" + .text + move.d 99b, $r10 + jsr _fail + nop +8: + .endm diff --git a/qemu/tests/tcg/hello-arm.c b/qemu/tests/tcg/hello-arm.c new file mode 100644 index 000000000..e0daa7ad9 --- /dev/null +++ b/qemu/tests/tcg/hello-arm.c @@ -0,0 +1,113 @@ +#define __NR_SYSCALL_BASE 0x900000 +#define __NR_exit1 (__NR_SYSCALL_BASE+ 1) +#define __NR_write (__NR_SYSCALL_BASE+ 4) + +#define __sys2(x) #x +#define __sys1(x) __sys2(x) + +#ifndef __syscall +#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t" +#endif + +#define __syscall_return(type, res) \ +do { \ + return (type) (res); \ +} while (0) + +#define _syscall0(type,name) \ +type name(void) { \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + "mov %0,r0" \ + :"=r" (__res) : : "r0","lr"); \ + __syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + __syscall(name) \ + "mov %0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)) \ + : "r0","lr"); \ + __syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + "mov\tr1,%2\n\t" \ + __syscall(name) \ + "mov\t%0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)) \ + : "r0","r1","lr"); \ + __syscall_return(type,__res); \ +} + + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + "mov\tr1,%2\n\t" \ + "mov\tr2,%3\n\t" \ + __syscall(name) \ + "mov\t%0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)) \ + : "r0","r1","r2","lr"); \ + __syscall_return(type,__res); \ +} + + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + "mov\tr1,%2\n\t" \ + "mov\tr2,%3\n\t" \ + "mov\tr3,%4\n\t" \ + __syscall(name) \ + "mov\t%0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)) \ + : "r0","r1","r2","r3","lr"); \ + __syscall_return(type,__res); \ +} + + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ + long __res; \ + __asm__ __volatile__ ( \ + "mov\tr0,%1\n\t" \ + "mov\tr1,%2\n\t" \ + "mov\tr2,%3\n\t" \ + "mov\tr3,%4\n\t" \ + "mov\tr4,%5\n\t" \ + __syscall(name) \ + "mov\t%0,r0" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)), \ + "r" ((long)(arg5)) \ + : "r0","r1","r2","r3","r4","lr"); \ + __syscall_return(type,__res); \ +} + +_syscall1(int,exit1,int,status); +_syscall3(int,write,int,fd,const char *,buf, int, len); + +void _start(void) +{ + write(1, "Hello World\n", 12); + exit1(0); +} diff --git a/qemu/tests/tcg/hello-i386.c b/qemu/tests/tcg/hello-i386.c new file mode 100644 index 000000000..fa00380de --- /dev/null +++ b/qemu/tests/tcg/hello-i386.c @@ -0,0 +1,27 @@ +#include <asm/unistd.h> + +static inline void exit(int status) +{ + int __res; + __asm__ volatile ("movl %%ecx,%%ebx\n"\ + "int $0x80" \ + : "=a" (__res) : "0" (__NR_exit),"c" ((long)(status))); +} + +static inline int write(int fd, const char * buf, int len) +{ + int status; + __asm__ volatile ("pushl %%ebx\n"\ + "movl %%esi,%%ebx\n"\ + "int $0x80\n" \ + "popl %%ebx\n"\ + : "=a" (status) \ + : "0" (__NR_write),"S" ((long)(fd)),"c" ((long)(buf)),"d" ((long)(len))); + return status; +} + +void _start(void) +{ + write(1, "Hello World\n", 12); + exit(0); +} diff --git a/qemu/tests/tcg/hello-mips.c b/qemu/tests/tcg/hello-mips.c new file mode 100644 index 000000000..f8256730d --- /dev/null +++ b/qemu/tests/tcg/hello-mips.c @@ -0,0 +1,64 @@ +/* +* MIPS o32 Linux syscall example +* +* http://www.linux-mips.org/wiki/RISC/os +* http://www.linux-mips.org/wiki/MIPSABIHistory +* http://www.linux.com/howtos/Assembly-HOWTO/mips.shtml +* +* mipsel-linux-gcc -nostdlib -mno-abicalls -fno-PIC -mabi=32 \ +* -O2 -static -o hello-mips hello-mips.c +* +*/ +#define __NR_SYSCALL_BASE 4000 +#define __NR_exit (__NR_SYSCALL_BASE+ 1) +#define __NR_write (__NR_SYSCALL_BASE+ 4) + +static inline void exit1(int status) +{ + register unsigned long __a0 asm("$4") = (unsigned long) status; + + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " li $2, %0 \n" + " syscall \n" + " .set pop " + : + : "i" (__NR_exit), "r" (__a0) + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", + "memory"); +} + +static inline int write(int fd, const char *buf, int len) +{ + register unsigned long __a0 asm("$4") = (unsigned long) fd; + register unsigned long __a1 asm("$5") = (unsigned long) buf; + register unsigned long __a2 asm("$6") = (unsigned long) len; + register unsigned long __a3 asm("$7"); + unsigned long __v0; + + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " li $2, %2 \n" + " syscall \n" + " move %0, $2 \n" + " .set pop " + : "=r" (__v0), "=r" (__a3) + : "i" (__NR_write), "r" (__a0), "r" (__a1), "r" (__a2) + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", + "memory"); + +/* if (__a3 == 0) */ + return (int) __v0; +/* + errno = __v0; + return -1; + */ +} + +void __start(void) +{ + write (1, "Hello, World!\n", 14); + exit1 (42); +} diff --git a/qemu/tests/tcg/linux-test.c b/qemu/tests/tcg/linux-test.c new file mode 100644 index 000000000..1c6c01318 --- /dev/null +++ b/qemu/tests/tcg/linux-test.c @@ -0,0 +1,538 @@ +/* + * linux and CPU test + * + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#define _GNU_SOURCE +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <inttypes.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <errno.h> +#include <utime.h> +#include <time.h> +#include <sys/time.h> +#include <sys/uio.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sched.h> +#include <dirent.h> +#include <setjmp.h> +#include <sys/shm.h> + +#define TESTPATH "/tmp/linux-test.tmp" +#define TESTPORT 7654 +#define STACK_SIZE 16384 + +void error1(const char *filename, int line, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d: ", filename, line); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(1); +} + +int __chk_error(const char *filename, int line, int ret) +{ + if (ret < 0) { + error1(filename, line, "%m (ret=%d, errno=%d)", + ret, errno); + } + return ret; +} + +#define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__) + +#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret)) + +/*******************************************************/ + +#define FILE_BUF_SIZE 300 + +void test_file(void) +{ + int fd, i, len, ret; + uint8_t buf[FILE_BUF_SIZE]; + uint8_t buf2[FILE_BUF_SIZE]; + uint8_t buf3[FILE_BUF_SIZE]; + char cur_dir[1024]; + struct stat st; + struct utimbuf tbuf; + struct iovec vecs[2]; + DIR *dir; + struct dirent *de; + + /* clean up, just in case */ + unlink(TESTPATH "/file1"); + unlink(TESTPATH "/file2"); + unlink(TESTPATH "/file3"); + rmdir(TESTPATH); + + if (getcwd(cur_dir, sizeof(cur_dir)) == NULL) + error("getcwd"); + + chk_error(mkdir(TESTPATH, 0755)); + + chk_error(chdir(TESTPATH)); + + /* open/read/write/close/readv/writev/lseek */ + + fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644)); + for(i=0;i < FILE_BUF_SIZE; i++) + buf[i] = i; + len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2)); + if (len != (FILE_BUF_SIZE / 2)) + error("write"); + vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2); + vecs[0].iov_len = 16; + vecs[1].iov_base = buf + (FILE_BUF_SIZE / 2) + 16; + vecs[1].iov_len = (FILE_BUF_SIZE / 2) - 16; + len = chk_error(writev(fd, vecs, 2)); + if (len != (FILE_BUF_SIZE / 2)) + error("writev"); + chk_error(close(fd)); + + chk_error(rename("file1", "file2")); + + fd = chk_error(open("file2", O_RDONLY)); + + len = chk_error(read(fd, buf2, FILE_BUF_SIZE)); + if (len != FILE_BUF_SIZE) + error("read"); + if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0) + error("memcmp"); + +#define FOFFSET 16 + ret = chk_error(lseek(fd, FOFFSET, SEEK_SET)); + if (ret != 16) + error("lseek"); + vecs[0].iov_base = buf3; + vecs[0].iov_len = 32; + vecs[1].iov_base = buf3 + 32; + vecs[1].iov_len = FILE_BUF_SIZE - FOFFSET - 32; + len = chk_error(readv(fd, vecs, 2)); + if (len != FILE_BUF_SIZE - FOFFSET) + error("readv"); + if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0) + error("memcmp"); + + chk_error(close(fd)); + + /* access */ + chk_error(access("file2", R_OK)); + + /* stat/chmod/utime/truncate */ + + chk_error(chmod("file2", 0600)); + tbuf.actime = 1001; + tbuf.modtime = 1000; + chk_error(truncate("file2", 100)); + chk_error(utime("file2", &tbuf)); + chk_error(stat("file2", &st)); + if (st.st_size != 100) + error("stat size"); + if (!S_ISREG(st.st_mode)) + error("stat mode"); + if ((st.st_mode & 0777) != 0600) + error("stat mode2"); + if (st.st_atime != 1001 || + st.st_mtime != 1000) + error("stat time"); + + chk_error(stat(TESTPATH, &st)); + if (!S_ISDIR(st.st_mode)) + error("stat mode"); + + /* fstat */ + fd = chk_error(open("file2", O_RDWR)); + chk_error(ftruncate(fd, 50)); + chk_error(fstat(fd, &st)); + chk_error(close(fd)); + + if (st.st_size != 50) + error("stat size"); + if (!S_ISREG(st.st_mode)) + error("stat mode"); + + /* symlink/lstat */ + chk_error(symlink("file2", "file3")); + chk_error(lstat("file3", &st)); + if (!S_ISLNK(st.st_mode)) + error("stat mode"); + + /* getdents */ + dir = opendir(TESTPATH); + if (!dir) + error("opendir"); + len = 0; + for(;;) { + de = readdir(dir); + if (!de) + break; + if (strcmp(de->d_name, ".") != 0 && + strcmp(de->d_name, "..") != 0 && + strcmp(de->d_name, "file2") != 0 && + strcmp(de->d_name, "file3") != 0) + error("readdir"); + len++; + } + closedir(dir); + if (len != 4) + error("readdir"); + + chk_error(unlink("file3")); + chk_error(unlink("file2")); + chk_error(chdir(cur_dir)); + chk_error(rmdir(TESTPATH)); +} + +void test_fork(void) +{ + int pid, status; + + pid = chk_error(fork()); + if (pid == 0) { + /* child */ + exit(2); + } + chk_error(waitpid(pid, &status, 0)); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 2) + error("waitpid status=0x%x", status); +} + +void test_time(void) +{ + struct timeval tv, tv2; + struct timespec ts, rem; + struct rusage rusg1, rusg2; + int ti, i; + + chk_error(gettimeofday(&tv, NULL)); + rem.tv_sec = 1; + ts.tv_sec = 0; + ts.tv_nsec = 20 * 1000000; + chk_error(nanosleep(&ts, &rem)); + if (rem.tv_sec != 1) + error("nanosleep"); + chk_error(gettimeofday(&tv2, NULL)); + ti = tv2.tv_sec - tv.tv_sec; + if (ti >= 2) + error("gettimeofday"); + + chk_error(getrusage(RUSAGE_SELF, &rusg1)); + for(i = 0;i < 10000; i++); + chk_error(getrusage(RUSAGE_SELF, &rusg2)); + if ((rusg2.ru_utime.tv_sec - rusg1.ru_utime.tv_sec) < 0 || + (rusg2.ru_stime.tv_sec - rusg1.ru_stime.tv_sec) < 0) + error("getrusage"); +} + +void pstrcpy(char *buf, int buf_size, const char *str) +{ + int c; + char *q = buf; + + if (buf_size <= 0) + return; + + for(;;) { + c = *str++; + if (c == 0 || q >= buf + buf_size - 1) + break; + *q++ = c; + } + *q = '\0'; +} + +/* strcat and truncate. */ +char *pstrcat(char *buf, int buf_size, const char *s) +{ + int len; + len = strlen(buf); + if (len < buf_size) + pstrcpy(buf + len, buf_size - len, s); + return buf; +} + +int server_socket(void) +{ + int val, fd; + struct sockaddr_in sockaddr; + + /* server socket */ + fd = chk_error(socket(PF_INET, SOCK_STREAM, 0)); + + val = 1; + chk_error(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))); + + sockaddr.sin_family = AF_INET; + sockaddr.sin_port = htons(TESTPORT); + sockaddr.sin_addr.s_addr = 0; + chk_error(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))); + chk_error(listen(fd, 0)); + return fd; + +} + +int client_socket(void) +{ + int fd; + struct sockaddr_in sockaddr; + + /* server socket */ + fd = chk_error(socket(PF_INET, SOCK_STREAM, 0)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_port = htons(TESTPORT); + inet_aton("127.0.0.1", &sockaddr.sin_addr); + chk_error(connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))); + return fd; +} + +const char socket_msg[] = "hello socket\n"; + +void test_socket(void) +{ + int server_fd, client_fd, fd, pid, ret, val; + struct sockaddr_in sockaddr; + socklen_t len; + char buf[512]; + + server_fd = server_socket(); + + /* test a few socket options */ + len = sizeof(val); + chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len)); + if (val != SOCK_STREAM) + error("getsockopt"); + + pid = chk_error(fork()); + if (pid == 0) { + client_fd = client_socket(); + send(client_fd, socket_msg, sizeof(socket_msg), 0); + close(client_fd); + exit(0); + } + len = sizeof(sockaddr); + fd = chk_error(accept(server_fd, (struct sockaddr *)&sockaddr, &len)); + + ret = chk_error(recv(fd, buf, sizeof(buf), 0)); + if (ret != sizeof(socket_msg)) + error("recv"); + if (memcmp(buf, socket_msg, sizeof(socket_msg)) != 0) + error("socket_msg"); + chk_error(close(fd)); + chk_error(close(server_fd)); +} + +#define WCOUNT_MAX 512 + +void test_pipe(void) +{ + fd_set rfds, wfds; + int fds[2], fd_max, ret; + uint8_t ch; + int wcount, rcount; + + chk_error(pipe(fds)); + chk_error(fcntl(fds[0], F_SETFL, O_NONBLOCK)); + chk_error(fcntl(fds[1], F_SETFL, O_NONBLOCK)); + wcount = 0; + rcount = 0; + for(;;) { + FD_ZERO(&rfds); + fd_max = fds[0]; + FD_SET(fds[0], &rfds); + + FD_ZERO(&wfds); + FD_SET(fds[1], &wfds); + if (fds[1] > fd_max) + fd_max = fds[1]; + + ret = chk_error(select(fd_max + 1, &rfds, &wfds, NULL, NULL)); + if (ret > 0) { + if (FD_ISSET(fds[0], &rfds)) { + chk_error(read(fds[0], &ch, 1)); + rcount++; + if (rcount >= WCOUNT_MAX) + break; + } + if (FD_ISSET(fds[1], &wfds)) { + ch = 'a'; + chk_error(write(fds[0], &ch, 1)); + wcount++; + } + } + } + chk_error(close(fds[0])); + chk_error(close(fds[1])); +} + +int thread1_res; +int thread2_res; + +int thread1_func(void *arg) +{ + int i; + for(i=0;i<5;i++) { + thread1_res++; + usleep(10 * 1000); + } + return 0; +} + +int thread2_func(void *arg) +{ + int i; + for(i=0;i<6;i++) { + thread2_res++; + usleep(10 * 1000); + } + return 0; +} + +void test_clone(void) +{ + uint8_t *stack1, *stack2; + int pid1, pid2, status1, status2; + + stack1 = malloc(STACK_SIZE); + pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE, + CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1")); + + stack2 = malloc(STACK_SIZE); + pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE, + CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2")); + + while (waitpid(pid1, &status1, 0) != pid1); + free(stack1); + while (waitpid(pid2, &status2, 0) != pid2); + free(stack2); + if (thread1_res != 5 || + thread2_res != 6) + error("clone"); +} + +/***********************************/ + +volatile int alarm_count; +jmp_buf jmp_env; + +void sig_alarm(int sig) +{ + if (sig != SIGALRM) + error("signal"); + alarm_count++; +} + +void sig_segv(int sig, siginfo_t *info, void *puc) +{ + if (sig != SIGSEGV) + error("signal"); + longjmp(jmp_env, 1); +} + +void test_signal(void) +{ + struct sigaction act; + struct itimerval it, oit; + + /* timer test */ + + alarm_count = 0; + + act.sa_handler = sig_alarm; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + chk_error(sigaction(SIGALRM, &act, NULL)); + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 10 * 1000; + it.it_value.tv_sec = 0; + it.it_value.tv_usec = 10 * 1000; + chk_error(setitimer(ITIMER_REAL, &it, NULL)); + chk_error(getitimer(ITIMER_REAL, &oit)); + if (oit.it_value.tv_sec != it.it_value.tv_sec || + oit.it_value.tv_usec != it.it_value.tv_usec) + error("itimer"); + + while (alarm_count < 5) { + usleep(10 * 1000); + } + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + it.it_value.tv_sec = 0; + it.it_value.tv_usec = 0; + memset(&oit, 0xff, sizeof(oit)); + chk_error(setitimer(ITIMER_REAL, &it, &oit)); + if (oit.it_value.tv_sec != 0 || + oit.it_value.tv_usec != 10 * 1000) + error("setitimer"); + + /* SIGSEGV test */ + act.sa_sigaction = sig_segv; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + chk_error(sigaction(SIGSEGV, &act, NULL)); + if (setjmp(jmp_env) == 0) { + *(uint8_t *)0 = 0; + } + + act.sa_handler = SIG_DFL; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + chk_error(sigaction(SIGSEGV, &act, NULL)); +} + +#define SHM_SIZE 32768 + +void test_shm(void) +{ + void *ptr; + int shmid; + + shmid = chk_error(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0777)); + ptr = shmat(shmid, NULL, 0); + if (!ptr) + error("shmat"); + + memset(ptr, 0, SHM_SIZE); + + chk_error(shmctl(shmid, IPC_RMID, 0)); + chk_error(shmdt(ptr)); +} + +int main(int argc, char **argv) +{ + test_file(); + test_fork(); + test_time(); + test_socket(); + // test_clone(); + test_signal(); + test_shm(); + return 0; +} diff --git a/qemu/tests/tcg/lm32/Makefile b/qemu/tests/tcg/lm32/Makefile new file mode 100644 index 000000000..57e7363b2 --- /dev/null +++ b/qemu/tests/tcg/lm32/Makefile @@ -0,0 +1,106 @@ +-include ../../../config-host.mak + +CROSS=lm32-elf- + +SIM = qemu-system-lm32 +SIMFLAGS = -M lm32-evr -nographic -semihosting -net none -kernel + +CC = $(CROSS)gcc +AS = $(CROSS)as +AS = $(CC) -x assembler +SIZE = $(CROSS)size +LD = $(CC) +OBJCOPY = $(CROSS)objcopy + +TSRC_PATH = $(SRC_PATH)/tests/tcg/lm32 + +LDFLAGS = -T$(TSRC_PATH)/linker.ld +ASFLAGS += -Wa,-I,$(TSRC_PATH)/ + +CRT = crt.o +HELPER = helper.o +TESTCASES += test_add.tst +TESTCASES += test_addi.tst +TESTCASES += test_and.tst +TESTCASES += test_andhi.tst +TESTCASES += test_andi.tst +TESTCASES += test_b.tst +TESTCASES += test_be.tst +TESTCASES += test_bg.tst +TESTCASES += test_bge.tst +TESTCASES += test_bgeu.tst +TESTCASES += test_bgu.tst +TESTCASES += test_bi.tst +TESTCASES += test_bne.tst +TESTCASES += test_break.tst +TESTCASES += test_bret.tst +TESTCASES += test_call.tst +TESTCASES += test_calli.tst +TESTCASES += test_cmpe.tst +TESTCASES += test_cmpei.tst +TESTCASES += test_cmpg.tst +TESTCASES += test_cmpgi.tst +TESTCASES += test_cmpge.tst +TESTCASES += test_cmpgei.tst +TESTCASES += test_cmpgeu.tst +TESTCASES += test_cmpgeui.tst +TESTCASES += test_cmpgu.tst +TESTCASES += test_cmpgui.tst +TESTCASES += test_cmpne.tst +TESTCASES += test_cmpnei.tst +TESTCASES += test_divu.tst +TESTCASES += test_eret.tst +TESTCASES += test_lb.tst +TESTCASES += test_lbu.tst +TESTCASES += test_lh.tst +TESTCASES += test_lhu.tst +TESTCASES += test_lw.tst +TESTCASES += test_modu.tst +TESTCASES += test_mul.tst +TESTCASES += test_muli.tst +TESTCASES += test_nor.tst +TESTCASES += test_nori.tst +TESTCASES += test_or.tst +TESTCASES += test_ori.tst +TESTCASES += test_orhi.tst +#TESTCASES += test_rcsr.tst +TESTCASES += test_ret.tst +TESTCASES += test_sb.tst +TESTCASES += test_scall.tst +TESTCASES += test_sextb.tst +TESTCASES += test_sexth.tst +TESTCASES += test_sh.tst +TESTCASES += test_sl.tst +TESTCASES += test_sli.tst +TESTCASES += test_sr.tst +TESTCASES += test_sri.tst +TESTCASES += test_sru.tst +TESTCASES += test_srui.tst +TESTCASES += test_sub.tst +TESTCASES += test_sw.tst +#TESTCASES += test_wcsr.tst +TESTCASES += test_xnor.tst +TESTCASES += test_xnori.tst +TESTCASES += test_xor.tst +TESTCASES += test_xori.tst + +all: build + +%.o: $(TSRC_PATH)/%.c + $(CC) $(CFLAGS) -c $< -o $@ + +%.o: $(TSRC_PATH)/%.S + $(AS) $(ASFLAGS) -c $< -o $@ + +%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT) $(HELPER) + $(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $(HELPER) $< -o $@ + +build: $(TESTCASES) + +check: $(TESTCASES:test_%.tst=check_%) + +check_%: test_%.tst + @$(SIM) $(SIMFLAGS) $< + +clean: + $(RM) -fr $(TESTCASES) $(CRT) $(HELPER) diff --git a/qemu/tests/tcg/lm32/crt.S b/qemu/tests/tcg/lm32/crt.S new file mode 100644 index 000000000..fc437a3de --- /dev/null +++ b/qemu/tests/tcg/lm32/crt.S @@ -0,0 +1,84 @@ +.text +.global _start + +_start: +_reset_handler: + xor r0, r0, r0 + mvhi r1, hi(_start) + ori r1, r1, lo(_start) + wcsr eba, r1 + wcsr deba, r1 + mvhi sp, hi(_fstack) + ori sp, sp, lo(_fstack) + bi _main + +_breakpoint_handler: + ori r25, r25, 1 + addi ra, ba, 4 + ret + nop + nop + nop + nop + nop + +_instruction_bus_error_handler: + ori r25, r25, 2 + addi ra, ea, 4 + ret + nop + nop + nop + nop + nop + +_watchpoint_handler: + ori r25, r25, 4 + addi ra, ba, 4 + ret + nop + nop + nop + nop + nop + +_data_bus_error_handler: + ori r25, r25, 8 + addi ra, ea, 4 + ret + nop + nop + nop + nop + nop + +_divide_by_zero_handler: + ori r25, r25, 16 + addi ra, ea, 4 + ret + nop + nop + nop + nop + nop + +_interrupt_handler: + ori r25, r25, 32 + addi ra, ea, 4 + ret + nop + nop + nop + nop + nop + +_system_call_handler: + ori r25, r25, 64 + addi ra, ea, 4 + ret + nop + nop + nop + nop + nop + diff --git a/qemu/tests/tcg/lm32/helper.S b/qemu/tests/tcg/lm32/helper.S new file mode 100644 index 000000000..3351d41e8 --- /dev/null +++ b/qemu/tests/tcg/lm32/helper.S @@ -0,0 +1,65 @@ +.text +.global _start, _write, _exit +.global _tc_fail, _tc_pass + +_write: + addi sp, sp, -4 + sw (sp+4), r8 + mvi r8, 5 + scall + lw r8, (sp+4) + addi sp, sp, 4 + ret + +_exit: + mvi r8, 1 + scall +1: + bi 1b + +_tc_pass: +.data +1: + .ascii "OK\n" +2: +.text + addi sp, sp, -16 + sw (sp+4), ra + sw (sp+8), r1 + sw (sp+12), r2 + sw (sp+16), r3 + mvi r1, 1 + mvhi r2, hi(1b) + ori r2, r2, lo(1b) + mvi r3, (2b - 1b) + calli _write + lw r3, (sp+16) + lw r2, (sp+12) + lw r1, (sp+8) + lw ra, (sp+4) + addi sp, sp, 16 + ret + +_tc_fail: +.data +1: + .ascii "FAILED\n" +2: +.text + addi sp, sp, -16 + sw (sp+4), ra + sw (sp+8), r1 + sw (sp+12), r2 + sw (sp+16), r3 + sw (sp+4), ra + mvi r1, 1 + mvhi r2, hi(1b) + ori r2, r2, lo(1b) + mvi r3, (2b - 1b) + calli _write + lw r3, (sp+16) + lw r2, (sp+12) + lw r1, (sp+8) + lw ra, (sp+4) + addi sp, sp, 16 + ret diff --git a/qemu/tests/tcg/lm32/linker.ld b/qemu/tests/tcg/lm32/linker.ld new file mode 100644 index 000000000..52d43a4c7 --- /dev/null +++ b/qemu/tests/tcg/lm32/linker.ld @@ -0,0 +1,55 @@ +OUTPUT_FORMAT("elf32-lm32") +ENTRY(_start) + +__DYNAMIC = 0; + +MEMORY { + ram : ORIGIN = 0x08000000, LENGTH = 0x04000000 /* 64M */ +} + +SECTIONS +{ + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > ram + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + _erodata = .; + } > ram + + .data : + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.*) + _edata = .; + } > ram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _ebss = .; + _end = .; + } > ram +} + +PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4); + diff --git a/qemu/tests/tcg/lm32/macros.inc b/qemu/tests/tcg/lm32/macros.inc new file mode 100644 index 000000000..360ad53c9 --- /dev/null +++ b/qemu/tests/tcg/lm32/macros.inc @@ -0,0 +1,90 @@ + +.equ MAX_TESTNAME_LEN, 32 +.macro test_name name + .data +tn_\name: + .ascii "\name" + .space MAX_TESTNAME_LEN - (. - tn_\name), ' ' + .text + .global \name +\name: + addi sp, sp, -12 + sw (sp+4), r1 + sw (sp+8), r2 + sw (sp+12), r3 + mvi r1, 1 + mvhi r2, hi(tn_\name) + ori r2, r2, lo(tn_\name) + mvi r3, MAX_TESTNAME_LEN + calli _write + lw r3, (sp+12) + lw r2, (sp+8) + lw r1, (sp+4) + addi sp, sp, 12 +.endm + +.macro load reg val + mvhi \reg, hi(\val) + ori \reg, \reg, lo(\val) +.endm + +.macro tc_pass + calli _tc_pass +.endm + +.macro tc_fail + addi r12, r12, 1 + calli _tc_fail +.endm + +.macro check_r3 val + mvhi r13, hi(\val) + ori r13, r13, lo(\val) + be r3, r13, 1f + tc_fail + bi 2f +1: + tc_pass +2: +.endm + +.macro check_mem adr val + mvhi r13, hi(\adr) + ori r13, r13, lo(\adr) + mvhi r14, hi(\val) + ori r14, r14, lo(\val) + lw r13, (r13+0) + be r13, r14, 1f + tc_fail + bi 2f +1: + tc_pass +2: +.endm + +.macro check_excp excp + andi r13, r25, \excp + bne r13, r0, 1f + tc_fail + bi 2f +1: + tc_pass +2: +.endm + +.macro start + .global _main + .text +_main: + mvi r12, 0 +.endm + +.macro end + mv r1, r12 + calli _exit +.endm + +# base + +# 0 ctrl +# 4 pass/fail +# 8 ptr to test name diff --git a/qemu/tests/tcg/lm32/test_add.S b/qemu/tests/tcg/lm32/test_add.S new file mode 100644 index 000000000..030ad197b --- /dev/null +++ b/qemu/tests/tcg/lm32/test_add.S @@ -0,0 +1,75 @@ +.include "macros.inc" + +start + +test_name ADD_1 +mvi r1, 0 +mvi r2, 0 +add r3, r1, r2 +check_r3 0 + +test_name ADD_2 +mvi r1, 0 +mvi r2, 1 +add r3, r1, r2 +check_r3 1 + +test_name ADD_3 +mvi r1, 1 +mvi r2, 0 +add r3, r1, r2 +check_r3 1 + +test_name ADD_4 +mvi r1, 1 +mvi r2, -1 +add r3, r1, r2 +check_r3 0 + +test_name ADD_5 +mvi r1, -1 +mvi r2, 1 +add r3, r1, r2 +check_r3 0 + +test_name ADD_6 +mvi r1, -1 +mvi r2, 0 +add r3, r1, r2 +check_r3 -1 + +test_name ADD_7 +mvi r1, 0 +mvi r2, -1 +add r3, r1, r2 +check_r3 -1 + +test_name ADD_8 +mvi r3, 2 +add r3, r3, r3 +check_r3 4 + +test_name ADD_9 +mvi r1, 4 +mvi r3, 2 +add r3, r1, r3 +check_r3 6 + +test_name ADD_10 +mvi r1, 4 +mvi r3, 2 +add r3, r3, r1 +check_r3 6 + +test_name ADD_11 +mvi r1, 4 +add r3, r1, r1 +check_r3 8 + +test_name ADD_12 +load r1 0x12345678 +load r2 0xabcdef97 +add r3, r1, r2 +check_r3 0xbe02460f + +end diff --git a/qemu/tests/tcg/lm32/test_addi.S b/qemu/tests/tcg/lm32/test_addi.S new file mode 100644 index 000000000..68e766d1e --- /dev/null +++ b/qemu/tests/tcg/lm32/test_addi.S @@ -0,0 +1,56 @@ +.include "macros.inc" + +start + +test_name ADDI_1 +mvi r1, 0 +addi r3, r1, 0 +check_r3 0 + +test_name ADDI_2 +mvi r1, 0 +addi r3, r1, 1 +check_r3 1 + +test_name ADDI_3 +mvi r1, 1 +addi r3, r1, 0 +check_r3 1 + +test_name ADDI_4 +mvi r1, 1 +addi r3, r1, -1 +check_r3 0 + +test_name ADDI_5 +mvi r1, -1 +addi r3, r1, 1 +check_r3 0 + +test_name ADDI_6 +mvi r1, -1 +addi r3, r1, 0 +check_r3 -1 + +test_name ADDI_7 +mvi r1, 0 +addi r3, r1, -1 +check_r3 -1 + +test_name ADDI_8 +mvi r3, 4 +addi r3, r3, 4 +check_r3 8 + +test_name ADDI_9 +mvi r3, 4 +addi r3, r3, -4 +check_r3 0 + +test_name ADDI_10 +mvi r3, 4 +addi r3, r3, -5 +check_r3 -1 + +end + diff --git a/qemu/tests/tcg/lm32/test_and.S b/qemu/tests/tcg/lm32/test_and.S new file mode 100644 index 000000000..80962ce7a --- /dev/null +++ b/qemu/tests/tcg/lm32/test_and.S @@ -0,0 +1,45 @@ +.include "macros.inc" + +start + +test_name AND_1 +mvi r1, 0 +mvi r2, 0 +and r3, r1, r2 +check_r3 0 + +test_name AND_2 +mvi r1, 0 +mvi r2, 1 +and r3, r1, r2 +check_r3 0 + +test_name AND_3 +mvi r1, 1 +mvi r2, 1 +and r3, r1, r2 +check_r3 1 + +test_name AND_4 +mvi r3, 7 +and r3, r3, r3 +check_r3 7 + +test_name AND_5 +mvi r1, 7 +and r3, r1, r1 +check_r3 7 + +test_name AND_6 +mvi r1, 7 +mvi r3, 0 +and r3, r1, r3 +check_r3 0 + +test_name AND_7 +load r1 0xaa55aa55 +load r2 0x55aa55aa +and r3, r1, r2 +check_r3 0 + +end diff --git a/qemu/tests/tcg/lm32/test_andhi.S b/qemu/tests/tcg/lm32/test_andhi.S new file mode 100644 index 000000000..4f73af550 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_andhi.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name ANDHI_1 +mvi r1, 0 +andhi r3, r1, 0 +check_r3 0 + +test_name ANDHI_2 +mvi r1, 1 +andhi r3, r1, 1 +check_r3 0 + +test_name ANDHI_3 +load r1 0x000f0000 +andhi r3, r1, 1 +check_r3 0x00010000 + +test_name ANDHI_4 +load r1 0xffffffff +andhi r3, r1, 0xffff +check_r3 0xffff0000 + +test_name ANDHI_5 +load r1 0xffffffff +andhi r3, r1, 0 +check_r3 0 + +test_name ANDHI_6 +load r3 0x55aaffff +andhi r3, r3, 0xaaaa +check_r3 0x00aa0000 + +end diff --git a/qemu/tests/tcg/lm32/test_andi.S b/qemu/tests/tcg/lm32/test_andi.S new file mode 100644 index 000000000..da1b0a32f --- /dev/null +++ b/qemu/tests/tcg/lm32/test_andi.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name ANDI_1 +mvi r1, 0 +andi r3, r1, 0 +check_r3 0 + +test_name ANDI_2 +mvi r1, 1 +andi r3, r1, 1 +check_r3 1 + +test_name ANDI_3 +load r1 0x000f0000 +andi r3, r1, 1 +check_r3 0 + +test_name ANDI_4 +load r1 0xffffffff +andi r3, r1, 0xffff +check_r3 0xffff + +test_name ANDI_5 +load r1 0xffffffff +andi r3, r1, 0 +check_r3 0 + +test_name ANDI_6 +load r3 0xffff55aa +andi r3, r3, 0xaaaa +check_r3 0x000000aa + +end diff --git a/qemu/tests/tcg/lm32/test_b.S b/qemu/tests/tcg/lm32/test_b.S new file mode 100644 index 000000000..98172d8a9 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_b.S @@ -0,0 +1,13 @@ +.include "macros.inc" + +start + +test_name B_1 +load r1 jump +b r1 +tc_fail +end + +jump: +tc_pass +end diff --git a/qemu/tests/tcg/lm32/test_be.S b/qemu/tests/tcg/lm32/test_be.S new file mode 100644 index 000000000..635cabaca --- /dev/null +++ b/qemu/tests/tcg/lm32/test_be.S @@ -0,0 +1,48 @@ +.include "macros.inc" + +start + +test_name BE_1 +mvi r1, 0 +mvi r2, 0 +be r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BE_2 +mvi r1, 1 +mvi r2, 0 +be r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BE_3 +mvi r1, 0 +mvi r2, 1 +be r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +bi 2f +1: +tc_pass +bi 3f +2: +test_name BE_4 +mvi r1, 1 +mvi r2, 1 +be r1, r2, 1b +tc_fail +3: + +end + diff --git a/qemu/tests/tcg/lm32/test_bg.S b/qemu/tests/tcg/lm32/test_bg.S new file mode 100644 index 000000000..81823c230 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_bg.S @@ -0,0 +1,78 @@ +.include "macros.inc" + +start + +test_name BG_1 +mvi r1, 0 +mvi r2, 0 +bg r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BG_2 +mvi r1, 1 +mvi r2, 0 +bg r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BG_3 +mvi r1, 0 +mvi r2, 1 +bg r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BG_4 +mvi r1, 0 +mvi r2, -1 +bg r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BG_5 +mvi r1, -1 +mvi r2, 0 +bg r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BG_6 +mvi r1, -1 +mvi r2, -1 +bg r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +bi 2f +1: +tc_pass +bi 3f +2: +test_name BG_7 +mvi r1, 1 +mvi r2, 0 +bg r1, r2, 1b +tc_fail +3: + +end + diff --git a/qemu/tests/tcg/lm32/test_bge.S b/qemu/tests/tcg/lm32/test_bge.S new file mode 100644 index 000000000..6684d15a5 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_bge.S @@ -0,0 +1,78 @@ +.include "macros.inc" + +start + +test_name BGE_1 +mvi r1, 0 +mvi r2, 0 +bge r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BGE_2 +mvi r1, 1 +mvi r2, 0 +bge r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BGE_3 +mvi r1, 0 +mvi r2, 1 +bge r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BGE_4 +mvi r1, 0 +mvi r2, -1 +bge r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BGE_5 +mvi r1, -1 +mvi r2, 0 +bge r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BGE_6 +mvi r1, -1 +mvi r2, -1 +bge r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +bi 2f +1: +tc_pass +bi 3f +2: +test_name BGE_7 +mvi r1, 1 +mvi r2, 0 +bge r1, r2, 1b +tc_fail +3: + +end + diff --git a/qemu/tests/tcg/lm32/test_bgeu.S b/qemu/tests/tcg/lm32/test_bgeu.S new file mode 100644 index 000000000..be440308f --- /dev/null +++ b/qemu/tests/tcg/lm32/test_bgeu.S @@ -0,0 +1,78 @@ +.include "macros.inc" + +start + +test_name BGEU_1 +mvi r1, 0 +mvi r2, 0 +bgeu r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BGEU_2 +mvi r1, 1 +mvi r2, 0 +bgeu r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BGEU_3 +mvi r1, 0 +mvi r2, 1 +bgeu r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BGEU_4 +mvi r1, 0 +mvi r2, -1 +bgeu r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BGEU_5 +mvi r1, -1 +mvi r2, 0 +bgeu r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BGEU_6 +mvi r1, -1 +mvi r2, -1 +bgeu r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +bi 2f +1: +tc_pass +bi 3f +2: +test_name BGEU_7 +mvi r1, 1 +mvi r2, 0 +bgeu r1, r2, 1b +tc_fail +3: + +end + diff --git a/qemu/tests/tcg/lm32/test_bgu.S b/qemu/tests/tcg/lm32/test_bgu.S new file mode 100644 index 000000000..8cc695b31 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_bgu.S @@ -0,0 +1,78 @@ +.include "macros.inc" + +start + +test_name BGU_1 +mvi r1, 0 +mvi r2, 0 +bgu r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BGU_2 +mvi r1, 1 +mvi r2, 0 +bgu r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BGU_3 +mvi r1, 0 +mvi r2, 1 +bgu r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BGU_4 +mvi r1, 0 +mvi r2, -1 +bgu r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BGU_5 +mvi r1, -1 +mvi r2, 0 +bgu r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BGU_6 +mvi r1, -1 +mvi r2, -1 +bgu r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +bi 2f +1: +tc_pass +bi 3f +2: +test_name BGU_7 +mvi r1, 1 +mvi r2, 0 +bgu r1, r2, 1b +tc_fail +3: + +end + diff --git a/qemu/tests/tcg/lm32/test_bi.S b/qemu/tests/tcg/lm32/test_bi.S new file mode 100644 index 000000000..a1fbd6fc0 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_bi.S @@ -0,0 +1,23 @@ +.include "macros.inc" + +start + +test_name BI_1 +bi jump +tc_fail +end + +jump_back: +tc_pass +end + +jump: +tc_pass + +test_name BI_2 +bi jump_back +tc_fail + +end + + diff --git a/qemu/tests/tcg/lm32/test_bne.S b/qemu/tests/tcg/lm32/test_bne.S new file mode 100644 index 000000000..871a00675 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_bne.S @@ -0,0 +1,48 @@ +.include "macros.inc" + +start + +test_name BNE_1 +mvi r1, 0 +mvi r2, 0 +bne r1, r2, 1f +tc_pass +bi 2f +1: +tc_fail +2: + +test_name BNE_2 +mvi r1, 1 +mvi r2, 0 +bne r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +test_name BNE_3 +mvi r1, 0 +mvi r2, 1 +bne r1, r2, 1f +tc_fail +bi 2f +1: +tc_pass +2: + +bi 2f +1: +tc_fail +bi 3f +2: +test_name BNE_4 +mvi r1, 1 +mvi r2, 1 +bne r1, r2, 1b +tc_pass +3: + +end + diff --git a/qemu/tests/tcg/lm32/test_break.S b/qemu/tests/tcg/lm32/test_break.S new file mode 100644 index 000000000..0384fc612 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_break.S @@ -0,0 +1,20 @@ +.include "macros.inc" + +start + +test_name BREAK_1 +mvi r1, 1 +wcsr IE, r1 +insn: +break +check_excp 1 + +test_name BREAK_2 +mv r3, ba +check_r3 insn + +test_name BREAK_3 +rcsr r3, IE +check_r3 4 + +end diff --git a/qemu/tests/tcg/lm32/test_bret.S b/qemu/tests/tcg/lm32/test_bret.S new file mode 100644 index 000000000..645210e43 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_bret.S @@ -0,0 +1,38 @@ +.include "macros.inc" + +start + +test_name BRET_1 +mvi r1, 4 +wcsr IE, r1 +load ba mark +bret +tc_fail +bi 1f + +mark: +tc_pass + +1: +test_name BRET_2 +rcsr r3, IE +check_r3 5 + +test_name BRET_3 +mvi r1, 0 +wcsr IE, r1 +load ba mark2 +bret +tc_fail +bi 1f + +mark2: +tc_pass + +1: +test_name BRET_4 +rcsr r3, IE +check_r3 0 + +end + diff --git a/qemu/tests/tcg/lm32/test_call.S b/qemu/tests/tcg/lm32/test_call.S new file mode 100644 index 000000000..1b91a5f2b --- /dev/null +++ b/qemu/tests/tcg/lm32/test_call.S @@ -0,0 +1,16 @@ +.include "macros.inc" + +start + +test_name CALL_1 +load r1 mark +call r1 +return: + +tc_fail +end + +mark: +mv r3, ra +check_r3 return +end diff --git a/qemu/tests/tcg/lm32/test_calli.S b/qemu/tests/tcg/lm32/test_calli.S new file mode 100644 index 000000000..1d87ae6e2 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_calli.S @@ -0,0 +1,15 @@ +.include "macros.inc" + +start + +test_name CALLI_1 +calli mark +return: + +tc_fail +end + +mark: +mv r3, ra +check_r3 return +end diff --git a/qemu/tests/tcg/lm32/test_cmpe.S b/qemu/tests/tcg/lm32/test_cmpe.S new file mode 100644 index 000000000..60a885500 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpe.S @@ -0,0 +1,40 @@ +.include "macros.inc" + +start + +test_name CMPE_1 +mvi r1, 0 +mvi r2, 0 +cmpe r3, r1, r2 +check_r3 1 + +test_name CMPE_2 +mvi r1, 0 +mvi r2, 1 +cmpe r3, r1, r2 +check_r3 0 + +test_name CMPE_3 +mvi r1, 1 +mvi r2, 0 +cmpe r3, r1, r2 +check_r3 0 + +test_name CMPE_4 +mvi r3, 0 +mvi r2, 1 +cmpe r3, r3, r2 +check_r3 0 + +test_name CMPE_5 +mvi r3, 0 +mvi r2, 0 +cmpe r3, r3, r2 +check_r3 1 + +test_name CMPE_6 +mvi r3, 0 +cmpe r3, r3, r3 +check_r3 1 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpei.S b/qemu/tests/tcg/lm32/test_cmpei.S new file mode 100644 index 000000000..c3d3566ad --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpei.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name CMPEI_1 +mvi r1, 0 +cmpei r3, r1, 0 +check_r3 1 + +test_name CMPEI_2 +mvi r1, 0 +cmpei r3, r1, 1 +check_r3 0 + +test_name CMPEI_3 +mvi r1, 1 +cmpei r3, r1, 0 +check_r3 0 + +test_name CMPEI_4 +load r1 0xffffffff +cmpei r3, r1, -1 +check_r3 1 + +test_name CMPEI_5 +mvi r3, 0 +cmpei r3, r3, 0 +check_r3 1 + +test_name CMPEI_6 +mvi r3, 0 +cmpei r3, r3, 1 +check_r3 0 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpg.S b/qemu/tests/tcg/lm32/test_cmpg.S new file mode 100644 index 000000000..012407874 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpg.S @@ -0,0 +1,64 @@ +.include "macros.inc" + +start + +test_name CMPG_1 +mvi r1, 0 +mvi r2, 0 +cmpg r3, r1, r2 +check_r3 0 + +test_name CMPG_2 +mvi r1, 0 +mvi r2, 1 +cmpg r3, r1, r2 +check_r3 0 + +test_name CMPG_3 +mvi r1, 1 +mvi r2, 0 +cmpg r3, r1, r2 +check_r3 1 + +test_name CMPG_4 +mvi r1, 1 +mvi r2, 1 +cmpg r3, r1, r2 +check_r3 0 + +test_name CMPG_5 +mvi r1, 0 +mvi r2, -1 +cmpg r3, r1, r2 +check_r3 1 + +test_name CMPG_6 +mvi r1, -1 +mvi r2, 0 +cmpg r3, r1, r2 +check_r3 0 + +test_name CMPG_7 +mvi r1, -1 +mvi r2, -1 +cmpg r3, r1, r2 +check_r3 0 + +test_name CMPG_8 +mvi r3, 0 +mvi r2, 1 +cmpg r3, r3, r2 +check_r3 0 + +test_name CMPG_9 +mvi r3, 1 +mvi r2, 0 +cmpg r3, r3, r2 +check_r3 1 + +test_name CMPG_10 +mvi r3, 0 +cmpg r3, r3, r3 +check_r3 0 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpge.S b/qemu/tests/tcg/lm32/test_cmpge.S new file mode 100644 index 000000000..84620a00e --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpge.S @@ -0,0 +1,64 @@ +.include "macros.inc" + +start + +test_name CMPGE_1 +mvi r1, 0 +mvi r2, 0 +cmpge r3, r1, r2 +check_r3 1 + +test_name CMPGE_2 +mvi r1, 0 +mvi r2, 1 +cmpge r3, r1, r2 +check_r3 0 + +test_name CMPGE_3 +mvi r1, 1 +mvi r2, 0 +cmpge r3, r1, r2 +check_r3 1 + +test_name CMPGE_4 +mvi r1, 1 +mvi r2, 1 +cmpge r3, r1, r2 +check_r3 1 + +test_name CMPGE_5 +mvi r1, 0 +mvi r2, -1 +cmpge r3, r1, r2 +check_r3 1 + +test_name CMPGE_6 +mvi r1, -1 +mvi r2, 0 +cmpge r3, r1, r2 +check_r3 0 + +test_name CMPGE_7 +mvi r1, -1 +mvi r2, -1 +cmpge r3, r1, r2 +check_r3 1 + +test_name CMPGE_8 +mvi r3, 0 +mvi r2, 1 +cmpge r3, r3, r2 +check_r3 0 + +test_name CMPGE_9 +mvi r3, 1 +mvi r2, 0 +cmpge r3, r3, r2 +check_r3 1 + +test_name CMPGE_10 +mvi r3, 0 +cmpge r3, r3, r3 +check_r3 1 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpgei.S b/qemu/tests/tcg/lm32/test_cmpgei.S new file mode 100644 index 000000000..6e388a2a3 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpgei.S @@ -0,0 +1,70 @@ +.include "macros.inc" + +start + +test_name CMPGEI_1 +mvi r1, 0 +cmpgei r3, r1, 0 +check_r3 1 + +test_name CMPGEI_2 +mvi r1, 0 +cmpgei r3, r1, 1 +check_r3 0 + +test_name CMPGEI_3 +mvi r1, 1 +cmpgei r3, r1, 0 +check_r3 1 + +test_name CMPGEI_4 +mvi r1, 1 +cmpgei r3, r1, 1 +check_r3 1 + +test_name CMPGEI_5 +mvi r1, 0 +cmpgei r3, r1, -1 +check_r3 1 + +test_name CMPGEI_6 +mvi r1, -1 +cmpgei r3, r1, 0 +check_r3 0 + +test_name CMPGEI_7 +mvi r1, -1 +cmpgei r3, r1, -1 +check_r3 1 + +test_name CMPGEI_8 +mvi r3, 0 +cmpgei r3, r3, 1 +check_r3 0 + +test_name CMPGEI_9 +mvi r3, 1 +cmpgei r3, r3, 0 +check_r3 1 + +test_name CMPGEI_10 +mvi r3, 0 +cmpgei r3, r3, 0 +check_r3 1 + +test_name CMPGEI_11 +mvi r1, 0 +cmpgei r3, r1, -32768 +check_r3 1 + +test_name CMPGEI_12 +mvi r1, -1 +cmpgei r3, r1, -32768 +check_r3 1 + +test_name CMPGEI_13 +mvi r1, -32768 +cmpgei r3, r1, -32768 +check_r3 1 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpgeu.S b/qemu/tests/tcg/lm32/test_cmpgeu.S new file mode 100644 index 000000000..2110ccb6b --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpgeu.S @@ -0,0 +1,64 @@ +.include "macros.inc" + +start + +test_name CMPGEU_1 +mvi r1, 0 +mvi r2, 0 +cmpgeu r3, r1, r2 +check_r3 1 + +test_name CMPGEU_2 +mvi r1, 0 +mvi r2, 1 +cmpgeu r3, r1, r2 +check_r3 0 + +test_name CMPGEU_3 +mvi r1, 1 +mvi r2, 0 +cmpgeu r3, r1, r2 +check_r3 1 + +test_name CMPGEU_4 +mvi r1, 1 +mvi r2, 1 +cmpgeu r3, r1, r2 +check_r3 1 + +test_name CMPGEU_5 +mvi r1, 0 +mvi r2, -1 +cmpgeu r3, r1, r2 +check_r3 0 + +test_name CMPGEU_6 +mvi r1, -1 +mvi r2, 0 +cmpgeu r3, r1, r2 +check_r3 1 + +test_name CMPGEU_7 +mvi r1, -1 +mvi r2, -1 +cmpgeu r3, r1, r2 +check_r3 1 + +test_name CMPGEU_8 +mvi r3, 0 +mvi r2, 1 +cmpgeu r3, r3, r2 +check_r3 0 + +test_name CMPGEU_9 +mvi r3, 1 +mvi r2, 0 +cmpgeu r3, r3, r2 +check_r3 1 + +test_name CMPGEU_10 +mvi r3, 0 +cmpgeu r3, r3, r3 +check_r3 1 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpgeui.S b/qemu/tests/tcg/lm32/test_cmpgeui.S new file mode 100644 index 000000000..3866d96cb --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpgeui.S @@ -0,0 +1,70 @@ +.include "macros.inc" + +start + +test_name CMPGEUI_1 +mvi r1, 0 +cmpgeui r3, r1, 0 +check_r3 1 + +test_name CMPGEUI_2 +mvi r1, 0 +cmpgeui r3, r1, 1 +check_r3 0 + +test_name CMPGEUI_3 +mvi r1, 1 +cmpgeui r3, r1, 0 +check_r3 1 + +test_name CMPGEUI_4 +mvi r1, 1 +cmpgeui r3, r1, 1 +check_r3 1 + +test_name CMPGEUI_5 +mvi r1, 0 +cmpgeui r3, r1, 0xffff +check_r3 0 + +test_name CMPGEUI_6 +mvi r1, -1 +cmpgeui r3, r1, 0 +check_r3 1 + +test_name CMPGEUI_7 +mvi r1, -1 +cmpgeui r3, r1, 0xffff +check_r3 1 + +test_name CMPGEUI_8 +mvi r3, 0 +cmpgeui r3, r3, 1 +check_r3 0 + +test_name CMPGEUI_9 +mvi r3, 1 +cmpgeui r3, r3, 0 +check_r3 1 + +test_name CMPGEUI_10 +mvi r3, 0 +cmpgeui r3, r3, 0 +check_r3 1 + +test_name CMPGEUI_11 +mvi r1, 0 +cmpgeui r3, r1, 0x8000 +check_r3 0 + +test_name CMPGEUI_12 +mvi r1, -1 +cmpgeui r3, r1, 0x8000 +check_r3 1 + +test_name CMPGEUI_13 +ori r1, r0, 0x8000 +cmpgeui r3, r1, 0x8000 +check_r3 1 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpgi.S b/qemu/tests/tcg/lm32/test_cmpgi.S new file mode 100644 index 000000000..21695f97a --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpgi.S @@ -0,0 +1,70 @@ +.include "macros.inc" + +start + +test_name CMPGI_1 +mvi r1, 0 +cmpgi r3, r1, 0 +check_r3 0 + +test_name CMPGI_2 +mvi r1, 0 +cmpgi r3, r1, 1 +check_r3 0 + +test_name CMPGI_3 +mvi r1, 1 +cmpgi r3, r1, 0 +check_r3 1 + +test_name CMPGI_4 +mvi r1, 1 +cmpgi r3, r1, 1 +check_r3 0 + +test_name CMPGI_5 +mvi r1, 0 +cmpgi r3, r1, -1 +check_r3 1 + +test_name CMPGI_6 +mvi r1, -1 +cmpgi r3, r1, 0 +check_r3 0 + +test_name CMPGI_7 +mvi r1, -1 +cmpgi r3, r1, -1 +check_r3 0 + +test_name CMPGI_8 +mvi r3, 0 +cmpgi r3, r3, 1 +check_r3 0 + +test_name CMPGI_9 +mvi r3, 1 +cmpgi r3, r3, 0 +check_r3 1 + +test_name CMPGI_10 +mvi r3, 0 +cmpgi r3, r3, 0 +check_r3 0 + +test_name CMPGI_11 +mvi r1, 0 +cmpgi r3, r1, -32768 +check_r3 1 + +test_name CMPGI_12 +mvi r1, -1 +cmpgi r3, r1, -32768 +check_r3 1 + +test_name CMPGI_13 +mvi r1, -32768 +cmpgi r3, r1, -32768 +check_r3 0 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpgu.S b/qemu/tests/tcg/lm32/test_cmpgu.S new file mode 100644 index 000000000..dd465471e --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpgu.S @@ -0,0 +1,64 @@ +.include "macros.inc" + +start + +test_name CMPGU_1 +mvi r1, 0 +mvi r2, 0 +cmpgu r3, r1, r2 +check_r3 0 + +test_name CMPGU_2 +mvi r1, 0 +mvi r2, 1 +cmpgu r3, r1, r2 +check_r3 0 + +test_name CMPGU_3 +mvi r1, 1 +mvi r2, 0 +cmpgu r3, r1, r2 +check_r3 1 + +test_name CMPGU_4 +mvi r1, 1 +mvi r2, 1 +cmpgu r3, r1, r2 +check_r3 0 + +test_name CMPGU_5 +mvi r1, 0 +mvi r2, -1 +cmpgu r3, r1, r2 +check_r3 0 + +test_name CMPGU_6 +mvi r1, -1 +mvi r2, 0 +cmpgu r3, r1, r2 +check_r3 1 + +test_name CMPGU_7 +mvi r1, -1 +mvi r2, -1 +cmpgu r3, r1, r2 +check_r3 0 + +test_name CMPGU_8 +mvi r3, 0 +mvi r2, 1 +cmpgu r3, r3, r2 +check_r3 0 + +test_name CMPGU_9 +mvi r3, 1 +mvi r2, 0 +cmpgu r3, r3, r2 +check_r3 1 + +test_name CMPGU_10 +mvi r3, 0 +cmpgu r3, r3, r3 +check_r3 0 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpgui.S b/qemu/tests/tcg/lm32/test_cmpgui.S new file mode 100644 index 000000000..dd9400149 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpgui.S @@ -0,0 +1,70 @@ +.include "macros.inc" + +start + +test_name CMPGUI_1 +mvi r1, 0 +cmpgui r3, r1, 0 +check_r3 0 + +test_name CMPGUI_2 +mvi r1, 0 +cmpgui r3, r1, 1 +check_r3 0 + +test_name CMPGUI_3 +mvi r1, 1 +cmpgui r3, r1, 0 +check_r3 1 + +test_name CMPGUI_4 +mvi r1, 1 +cmpgui r3, r1, 1 +check_r3 0 + +test_name CMPGUI_5 +mvi r1, 0 +cmpgui r3, r1, 0xffff +check_r3 0 + +test_name CMPGUI_6 +mvi r1, -1 +cmpgui r3, r1, 0 +check_r3 1 + +test_name CMPGUI_7 +mvi r1, -1 +cmpgui r3, r1, 0xffff +check_r3 1 + +test_name CMPGUI_8 +mvi r3, 0 +cmpgui r3, r3, 1 +check_r3 0 + +test_name CMPGUI_9 +mvi r3, 1 +cmpgui r3, r3, 0 +check_r3 1 + +test_name CMPGUI_10 +mvi r3, 0 +cmpgui r3, r3, 0 +check_r3 0 + +test_name CMPGUI_11 +mvi r1, 0 +cmpgui r3, r1, 0x8000 +check_r3 0 + +test_name CMPGUI_12 +mvi r1, -1 +cmpgui r3, r1, 0x8000 +check_r3 1 + +test_name CMPGUI_13 +ori r1, r0, 0x8000 +cmpgui r3, r1, 0x8000 +check_r3 0 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpne.S b/qemu/tests/tcg/lm32/test_cmpne.S new file mode 100644 index 000000000..0f1078114 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpne.S @@ -0,0 +1,40 @@ +.include "macros.inc" + +start + +test_name CMPNE_1 +mvi r1, 0 +mvi r2, 0 +cmpne r3, r1, r2 +check_r3 0 + +test_name CMPNE_2 +mvi r1, 0 +mvi r2, 1 +cmpne r3, r1, r2 +check_r3 1 + +test_name CMPNE_3 +mvi r1, 1 +mvi r2, 0 +cmpne r3, r1, r2 +check_r3 1 + +test_name CMPNE_4 +mvi r3, 0 +mvi r2, 1 +cmpne r3, r3, r2 +check_r3 1 + +test_name CMPNE_5 +mvi r3, 0 +mvi r2, 0 +cmpne r3, r3, r2 +check_r3 0 + +test_name CMPNE_6 +mvi r3, 0 +cmpne r3, r3, r3 +check_r3 0 + +end diff --git a/qemu/tests/tcg/lm32/test_cmpnei.S b/qemu/tests/tcg/lm32/test_cmpnei.S new file mode 100644 index 000000000..060dd9d39 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_cmpnei.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name CMPNEI_1 +mvi r1, 0 +cmpnei r3, r1, 0 +check_r3 0 + +test_name CMPNEI_2 +mvi r1, 0 +cmpnei r3, r1, 1 +check_r3 1 + +test_name CMPNEI_3 +mvi r1, 1 +cmpnei r3, r1, 0 +check_r3 1 + +test_name CMPNEI_4 +load r1 0xffffffff +cmpnei r3, r1, -1 +check_r3 0 + +test_name CMPNEI_5 +mvi r3, 0 +cmpnei r3, r3, 0 +check_r3 0 + +test_name CMPNEI_6 +mvi r3, 0 +cmpnei r3, r3, 1 +check_r3 1 + +end diff --git a/qemu/tests/tcg/lm32/test_divu.S b/qemu/tests/tcg/lm32/test_divu.S new file mode 100644 index 000000000..f381d095c --- /dev/null +++ b/qemu/tests/tcg/lm32/test_divu.S @@ -0,0 +1,29 @@ +.include "macros.inc" + +start + +test_name DIVU_1 +mvi r1, 0 +mvi r2, 1 +divu r3, r1, r2 +check_r3 0 + +test_name DIVU_2 +mvi r1, 1 +mvi r2, 1 +divu r3, r1, r2 +check_r3 1 + +test_name DIVU_3 +mvi r1, 0 +mvi r2, 0 +divu r3, r1, r2 +check_excp 16 + +test_name DIVU_4 +load r1 0xabcdef12 +load r2 0x12345 +divu r3, r1, r2 +check_r3 0x9700 + +end diff --git a/qemu/tests/tcg/lm32/test_eret.S b/qemu/tests/tcg/lm32/test_eret.S new file mode 100644 index 000000000..6830bd1ab --- /dev/null +++ b/qemu/tests/tcg/lm32/test_eret.S @@ -0,0 +1,38 @@ +.include "macros.inc" + +start + +test_name ERET_1 +mvi r1, 2 +wcsr IE, r1 +load ea mark +eret +tc_fail +bi 1f + +mark: +tc_pass + +1: +test_name ERET_2 +rcsr r3, IE +check_r3 3 + +test_name ERET_3 +mvi r1, 0 +wcsr IE, r1 +load ea mark2 +eret +tc_fail +bi 1f + +mark2: +tc_pass + +1: +test_name ERET_4 +rcsr r3, IE +check_r3 0 + +end + diff --git a/qemu/tests/tcg/lm32/test_lb.S b/qemu/tests/tcg/lm32/test_lb.S new file mode 100644 index 000000000..d677eea4c --- /dev/null +++ b/qemu/tests/tcg/lm32/test_lb.S @@ -0,0 +1,49 @@ +.include "macros.inc" + +start + +test_name LB_1 +load r1 data +lb r3, (r1+0) +check_r3 0x7e + +test_name LB_2 +load r1 data +lb r3, (r1+1) +check_r3 0x7f + +test_name LB_3 +load r1 data +lb r3, (r1+-1) +check_r3 0x7d + +test_name LB_4 +load r1 data_msb +lb r3, (r1+0) +check_r3 0xfffffffe + +test_name LB_5 +load r1 data_msb +lb r3, (r1+1) +check_r3 0xffffffff + +test_name LB_6 +load r1 data_msb +lb r3, (r1+-1) +check_r3 0xfffffffd + +test_name LB_7 +load r3 data +lb r3, (r3+0) +check_r3 0x7e + +end + +.data + .align 4 + .byte 0x7a, 0x7b, 0x7c, 0x7d +data: + .byte 0x7e, 0x7f, 0x70, 0x71 + .byte 0xfa, 0xfb, 0xfc, 0xfd +data_msb: + .byte 0xfe, 0xff, 0xf0, 0xf1 diff --git a/qemu/tests/tcg/lm32/test_lbu.S b/qemu/tests/tcg/lm32/test_lbu.S new file mode 100644 index 000000000..dc5d5f67d --- /dev/null +++ b/qemu/tests/tcg/lm32/test_lbu.S @@ -0,0 +1,49 @@ +.include "macros.inc" + +start + +test_name LBU_1 +load r1 data +lbu r3, (r1+0) +check_r3 0x7e + +test_name LBU_2 +load r1 data +lbu r3, (r1+1) +check_r3 0x7f + +test_name LBU_3 +load r1 data +lbu r3, (r1+-1) +check_r3 0x7d + +test_name LBU_4 +load r1 data_msb +lbu r3, (r1+0) +check_r3 0xfe + +test_name LBU_5 +load r1 data_msb +lbu r3, (r1+1) +check_r3 0xff + +test_name LBU_6 +load r1 data_msb +lbu r3, (r1+-1) +check_r3 0xfd + +test_name LBU_7 +load r3 data +lbu r3, (r3+0) +check_r3 0x7e + +end + +.data + .align 4 + .byte 0x7a, 0x7b, 0x7c, 0x7d +data: + .byte 0x7e, 0x7f, 0x70, 0x71 + .byte 0xfa, 0xfb, 0xfc, 0xfd +data_msb: + .byte 0xfe, 0xff, 0xf0, 0xf1 diff --git a/qemu/tests/tcg/lm32/test_lh.S b/qemu/tests/tcg/lm32/test_lh.S new file mode 100644 index 000000000..397996bdd --- /dev/null +++ b/qemu/tests/tcg/lm32/test_lh.S @@ -0,0 +1,49 @@ +.include "macros.inc" + +start + +test_name LH_1 +load r1 data +lh r3, (r1+0) +check_r3 0x7e7f + +test_name LH_2 +load r1 data +lh r3, (r1+2) +check_r3 0x7071 + +test_name LH_3 +load r1 data +lh r3, (r1+-2) +check_r3 0x7c7d + +test_name LH_4 +load r1 data_msb +lh r3, (r1+0) +check_r3 0xfffffeff + +test_name LH_5 +load r1 data_msb +lh r3, (r1+2) +check_r3 0xfffff0f1 + +test_name LH_6 +load r1 data_msb +lh r3, (r1+-2) +check_r3 0xfffffcfd + +test_name LH_7 +load r3 data +lh r3, (r3+0) +check_r3 0x7e7f + +end + +.data + .align 4 + .byte 0x7a, 0x7b, 0x7c, 0x7d +data: + .byte 0x7e, 0x7f, 0x70, 0x71 + .byte 0xfa, 0xfb, 0xfc, 0xfd +data_msb: + .byte 0xfe, 0xff, 0xf0, 0xf1 diff --git a/qemu/tests/tcg/lm32/test_lhu.S b/qemu/tests/tcg/lm32/test_lhu.S new file mode 100644 index 000000000..8de7c5256 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_lhu.S @@ -0,0 +1,49 @@ +.include "macros.inc" + +start + +test_name LHU_1 +load r1 data +lhu r3, (r1+0) +check_r3 0x7e7f + +test_name LHU_2 +load r1 data +lhu r3, (r1+2) +check_r3 0x7071 + +test_name LHU_3 +load r1 data +lhu r3, (r1+-2) +check_r3 0x7c7d + +test_name LHU_4 +load r1 data_msb +lhu r3, (r1+0) +check_r3 0xfeff + +test_name LHU_5 +load r1 data_msb +lhu r3, (r1+2) +check_r3 0xf0f1 + +test_name LHU_6 +load r1 data_msb +lhu r3, (r1+-2) +check_r3 0xfcfd + +test_name LHU_7 +load r3 data +lhu r3, (r3+0) +check_r3 0x7e7f + +end + +.data + .align 4 + .byte 0x7a, 0x7b, 0x7c, 0x7d +data: + .byte 0x7e, 0x7f, 0x70, 0x71 + .byte 0xfa, 0xfb, 0xfc, 0xfd +data_msb: + .byte 0xfe, 0xff, 0xf0, 0xf1 diff --git a/qemu/tests/tcg/lm32/test_lw.S b/qemu/tests/tcg/lm32/test_lw.S new file mode 100644 index 000000000..996e5f8c8 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_lw.S @@ -0,0 +1,32 @@ +.include "macros.inc" + +start + +test_name LW_1 +load r1 data +lw r3, (r1+0) +check_r3 0x7e7f7071 + +test_name LW_2 +load r1 data +lw r3, (r1+4) +check_r3 0x72737475 + +test_name LW_3 +load r1 data +lw r3, (r1+-4) +check_r3 0x7a7b7c7d + +test_name LW_4 +load r3 data +lw r3, (r3+0) +check_r3 0x7e7f7071 + +end + +.data + .align 4 + .byte 0x7a, 0x7b, 0x7c, 0x7d +data: + .byte 0x7e, 0x7f, 0x70, 0x71 + .byte 0x72, 0x73, 0x74, 0x75 diff --git a/qemu/tests/tcg/lm32/test_modu.S b/qemu/tests/tcg/lm32/test_modu.S new file mode 100644 index 000000000..42486900b --- /dev/null +++ b/qemu/tests/tcg/lm32/test_modu.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name MODU_1 +mvi r1, 0 +mvi r2, 1 +modu r3, r1, r2 +check_r3 0 + +test_name MODU_2 +mvi r1, 1 +mvi r2, 1 +modu r3, r1, r2 +check_r3 0 + +test_name MODU_3 +mvi r1, 3 +mvi r2, 2 +modu r3, r1, r2 +check_r3 1 + +test_name MODU_4 +mvi r1, 0 +mvi r2, 0 +modu r3, r1, r2 +check_excp 16 + +test_name MODU_5 +load r1 0xabcdef12 +load r2 0x12345 +modu r3, r1, r2 +check_r3 0x3c12 + +end diff --git a/qemu/tests/tcg/lm32/test_mul.S b/qemu/tests/tcg/lm32/test_mul.S new file mode 100644 index 000000000..e9b937e64 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_mul.S @@ -0,0 +1,70 @@ +.include "macros.inc" + +start + +test_name MUL_1 +mvi r1, 0 +mvi r2, 0 +mul r3, r1, r2 +check_r3 0 + +test_name MUL_2 +mvi r1, 1 +mvi r2, 0 +mul r3, r1, r2 +check_r3 0 + +test_name MUL_3 +mvi r1, 0 +mvi r2, 1 +mul r3, r1, r2 +check_r3 0 + +test_name MUL_4 +mvi r1, 1 +mvi r2, 1 +mul r3, r1, r2 +check_r3 1 + +test_name MUL_5 +mvi r1, 2 +mvi r2, -1 +mul r3, r1, r2 +check_r3 -2 + +test_name MUL_6 +mvi r1, -2 +mvi r2, -1 +mul r3, r1, r2 +check_r3 2 + +test_name MUL_7 +mvi r1, 0x1234 +mvi r2, 0x789 +mul r3, r1, r2 +check_r3 0x8929d4 + +test_name MUL_8 +mvi r3, 4 +mul r3, r3, r3 +check_r3 16 + +test_name MUL_9 +mvi r2, 2 +mvi r3, 4 +mul r3, r3, r2 +check_r3 8 + +test_name MUL_10 +load r1 0x12345678 +load r2 0x7bcdef12 +mul r3, r1, r2 +check_r3 0xa801c70 + +test_name MUL_11 +load r1 0x12345678 +load r2 0xabcdef12 +mul r3, r1, r2 +check_r3 0x8a801c70 + +end diff --git a/qemu/tests/tcg/lm32/test_muli.S b/qemu/tests/tcg/lm32/test_muli.S new file mode 100644 index 000000000..d6dd4a0f7 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_muli.S @@ -0,0 +1,45 @@ +.include "macros.inc" + +start + +test_name MULI_1 +mvi r1, 0 +muli r3, r1, 0 +check_r3 0 + +test_name MULI_2 +mvi r1, 1 +muli r3, r1, 0 +check_r3 0 + +test_name MULI_3 +mvi r1, 0 +muli r3, r1, 1 +check_r3 0 + +test_name MULI_4 +mvi r1, 1 +muli r3, r1, 1 +check_r3 1 + +test_name MULI_5 +mvi r1, 2 +muli r3, r1, -1 +check_r3 -2 + +test_name MULI_6 +mvi r1, -2 +muli r3, r1, -1 +check_r3 2 + +test_name MULI_7 +mvi r1, 0x1234 +muli r3, r1, 0x789 +check_r3 0x8929d4 + +test_name MULI_8 +mvi r3, 4 +muli r3, r3, 4 +check_r3 16 + +end diff --git a/qemu/tests/tcg/lm32/test_nor.S b/qemu/tests/tcg/lm32/test_nor.S new file mode 100644 index 000000000..74d759256 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_nor.S @@ -0,0 +1,51 @@ +.include "macros.inc" + +start + +test_name NOR_1 +mvi r1, 0 +mvi r2, 0 +nor r3, r1, r2 +check_r3 0xffffffff + +test_name NOR_2 +mvi r1, 0 +mvi r2, 1 +nor r3, r1, r2 +check_r3 0xfffffffe + +test_name NOR_3 +mvi r1, 1 +mvi r2, 1 +nor r3, r1, r2 +check_r3 0xfffffffe + +test_name NOR_4 +mvi r1, 1 +mvi r2, 0 +nor r3, r1, r2 +check_r3 0xfffffffe + +test_name NOR_5 +load r1 0xaa55aa55 +load r2 0x55aa55aa +nor r3, r1, r2 +check_r3 0 + +test_name NOR_6 +load r1 0xaa550000 +load r2 0x0000aa55 +nor r3, r1, r2 +check_r3 0x55aa55aa + +test_name NOR_7 +load r1 0xaa55aa55 +nor r3, r1, r1 +check_r3 0x55aa55aa + +test_name NOR_8 +load r3 0xaa55aa55 +nor r3, r3, r3 +check_r3 0x55aa55aa + +end diff --git a/qemu/tests/tcg/lm32/test_nori.S b/qemu/tests/tcg/lm32/test_nori.S new file mode 100644 index 000000000..d00309c73 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_nori.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name NORI_1 +mvi r1, 0 +nori r3, r1, 0 +check_r3 0xffffffff + +test_name NORI_2 +mvi r1, 0 +nori r3, r1, 1 +check_r3 0xfffffffe + +test_name NORI_3 +mvi r1, 1 +nori r3, r1, 1 +check_r3 0xfffffffe + +test_name NORI_4 +mvi r1, 1 +nori r3, r1, 0 +check_r3 0xfffffffe + +test_name NORI_5 +load r1 0xaa55aa55 +nori r3, r1, 0x55aa +check_r3 0x55aa0000 + +test_name NORI_6 +load r3 0xaa55aa55 +nori r3, r3, 0x55aa +check_r3 0x55aa0000 + +end diff --git a/qemu/tests/tcg/lm32/test_or.S b/qemu/tests/tcg/lm32/test_or.S new file mode 100644 index 000000000..4ed292330 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_or.S @@ -0,0 +1,51 @@ +.include "macros.inc" + +start + +test_name OR_1 +mvi r1, 0 +mvi r2, 0 +or r3, r1, r2 +check_r3 0 + +test_name OR_2 +mvi r1, 0 +mvi r2, 1 +or r3, r1, r2 +check_r3 1 + +test_name OR_3 +mvi r1, 1 +mvi r2, 1 +or r3, r1, r2 +check_r3 1 + +test_name OR_4 +mvi r1, 1 +mvi r2, 0 +or r3, r1, r2 +check_r3 1 + +test_name OR_5 +load r1 0xaa55aa55 +load r2 0x55aa55aa +or r3, r1, r2 +check_r3 0xffffffff + +test_name OR_6 +load r1 0xaa550000 +load r2 0x0000aa55 +or r3, r1, r2 +check_r3 0xaa55aa55 + +test_name OR_7 +load r1 0xaa55aa55 +or r3, r1, r1 +check_r3 0xaa55aa55 + +test_name OR_8 +load r3 0xaa55aa55 +or r3, r3, r3 +check_r3 0xaa55aa55 + +end diff --git a/qemu/tests/tcg/lm32/test_orhi.S b/qemu/tests/tcg/lm32/test_orhi.S new file mode 100644 index 000000000..78b7600e0 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_orhi.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name ORHI_1 +mvi r1, 0 +orhi r3, r1, 0 +check_r3 0 + +test_name ORHI_2 +mvi r1, 0 +orhi r3, r1, 1 +check_r3 0x00010000 + +test_name ORHI_3 +load r1 0x00010000 +orhi r3, r1, 1 +check_r3 0x00010000 + +test_name ORHI_4 +mvi r1, 1 +orhi r3, r1, 0 +check_r3 1 + +test_name ORHI_5 +load r1 0xaa55aa55 +orhi r3, r1, 0x55aa +check_r3 0xffffaa55 + +test_name ORHI_6 +load r3 0xaa55aa55 +orhi r3, r3, 0x55aa +check_r3 0xffffaa55 + +end diff --git a/qemu/tests/tcg/lm32/test_ori.S b/qemu/tests/tcg/lm32/test_ori.S new file mode 100644 index 000000000..3d576cdb8 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_ori.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name ORI_1 +mvi r1, 0 +ori r3, r1, 0 +check_r3 0 + +test_name ORI_2 +mvi r1, 0 +ori r3, r1, 1 +check_r3 1 + +test_name ORI_3 +mvi r1, 1 +ori r3, r1, 1 +check_r3 1 + +test_name ORI_4 +mvi r1, 1 +ori r3, r1, 0 +check_r3 1 + +test_name ORI_5 +load r1 0xaa55aa55 +ori r3, r1, 0x55aa +check_r3 0xaa55ffff + +test_name ORI_6 +load r3 0xaa55aa55 +ori r3, r3, 0x55aa +check_r3 0xaa55ffff + +end diff --git a/qemu/tests/tcg/lm32/test_ret.S b/qemu/tests/tcg/lm32/test_ret.S new file mode 100644 index 000000000..320264f14 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_ret.S @@ -0,0 +1,14 @@ +.include "macros.inc" + +start + +test_name RET_1 +load ra mark +ret + +tc_fail +end + +mark: +tc_pass +end diff --git a/qemu/tests/tcg/lm32/test_sb.S b/qemu/tests/tcg/lm32/test_sb.S new file mode 100644 index 000000000..b15a89d34 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sb.S @@ -0,0 +1,32 @@ +.include "macros.inc" + +start + +test_name SB_1 +load r1 data +load r2 0xf0f1f2aa +sb (r1+0), r2 +check_mem data 0xaa000000 + +test_name SB_2 +load r1 data +load r2 0xf0f1f2bb +sb (r1+1), r2 +check_mem data 0xaabb0000 + +test_name SB_3 +load r1 data +load r2 0xf0f1f2cc +sb (r1+-1), r2 +check_mem data0 0x000000cc + +end + +.data + .align 4 +data0: + .byte 0, 0, 0, 0 +data: + .byte 0, 0, 0, 0 +data1: + .byte 0, 0, 0, 0 diff --git a/qemu/tests/tcg/lm32/test_scall.S b/qemu/tests/tcg/lm32/test_scall.S new file mode 100644 index 000000000..46032f841 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_scall.S @@ -0,0 +1,24 @@ +.include "macros.inc" + +start + +test_name SCALL_1 +mvi r1, 1 +wcsr IE, r1 +# we are running in a semi hosted environment +# therefore we have to set r8 to some unused system +# call +mvi r8, 0 +insn: +scall +check_excp 64 + +test_name SCALL_2 +mv r3, ea +check_r3 insn + +test_name SCALL_3 +rcsr r3, IE +check_r3 2 + +end diff --git a/qemu/tests/tcg/lm32/test_sextb.S b/qemu/tests/tcg/lm32/test_sextb.S new file mode 100644 index 000000000..58db8ee8b --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sextb.S @@ -0,0 +1,20 @@ +.include "macros.inc" + +start + +test_name SEXTB_1 +mvi r1, 0 +sextb r3, r1 +check_r3 0 + +test_name SEXTB_2 +mvi r1, 0x7f +sextb r3, r1 +check_r3 0x0000007f + +test_name SEXTB_3 +mvi r1, 0x80 +sextb r3, r1 +check_r3 0xffffff80 + +end diff --git a/qemu/tests/tcg/lm32/test_sexth.S b/qemu/tests/tcg/lm32/test_sexth.S new file mode 100644 index 000000000..a059ec3ee --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sexth.S @@ -0,0 +1,20 @@ +.include "macros.inc" + +start + +test_name SEXTH_1 +mvi r1, 0 +sexth r3, r1 +check_r3 0 + +test_name SEXTH_2 +load r1 0x7fff +sexth r3, r1 +check_r3 0x00007fff + +test_name SEXTH_3 +load r1 0x8000 +sexth r3, r1 +check_r3 0xffff8000 + +end diff --git a/qemu/tests/tcg/lm32/test_sh.S b/qemu/tests/tcg/lm32/test_sh.S new file mode 100644 index 000000000..bba10224f --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sh.S @@ -0,0 +1,32 @@ +.include "macros.inc" + +start + +test_name SH_1 +load r1 data +load r2 0xf0f1aaaa +sh (r1+0), r2 +check_mem data 0xaaaa0000 + +test_name SH_2 +load r1 data +load r2 0xf0f1bbbb +sh (r1+2), r2 +check_mem data 0xaaaabbbb + +test_name SH_3 +load r1 data +load r2 0xf0f1cccc +sh (r1+-2), r2 +check_mem data0 0x0000cccc + +end + +.data + .align 4 +data0: + .byte 0, 0, 0, 0 +data: + .byte 0, 0, 0, 0 +data1: + .byte 0, 0, 0, 0 diff --git a/qemu/tests/tcg/lm32/test_sl.S b/qemu/tests/tcg/lm32/test_sl.S new file mode 100644 index 000000000..0aee17fdb --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sl.S @@ -0,0 +1,45 @@ +.include "macros.inc" + +start + +test_name SL_1 +mvi r1, 1 +mvi r2, 0 +sl r3, r1, r2 +check_r3 1 + +test_name SL_2 +mvi r1, 0 +mvi r2, 1 +sl r3, r1, r2 +check_r3 0 + +test_name SL_3 +mvi r1, 1 +mvi r2, 31 +sl r3, r1, r2 +check_r3 0x80000000 + +test_name SL_4 +mvi r1, 16 +mvi r2, 31 +sl r3, r1, r2 +check_r3 0 + +test_name SL_5 +mvi r1, 1 +mvi r2, 34 +sl r3, r1, r2 +check_r3 4 + +test_name SL_6 +mvi r1, 2 +sl r3, r1, r1 +check_r3 8 + +test_name SL_7 +mvi r3, 2 +sl r3, r3, r3 +check_r3 8 + +end diff --git a/qemu/tests/tcg/lm32/test_sli.S b/qemu/tests/tcg/lm32/test_sli.S new file mode 100644 index 000000000..a421de901 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sli.S @@ -0,0 +1,30 @@ +.include "macros.inc" + +start + +test_name SLI_1 +mvi r1, 1 +sli r3, r1, 0 +check_r3 1 + +test_name SLI_2 +mvi r1, 0 +sli r3, r1, 1 +check_r3 0 + +test_name SLI_3 +mvi r1, 1 +sli r3, r1, 31 +check_r3 0x80000000 + +test_name SLI_4 +mvi r1, 16 +sli r3, r1, 31 +check_r3 0 + +test_name SLI_7 +mvi r3, 2 +sli r3, r3, 2 +check_r3 8 + +end diff --git a/qemu/tests/tcg/lm32/test_sr.S b/qemu/tests/tcg/lm32/test_sr.S new file mode 100644 index 000000000..62431a986 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sr.S @@ -0,0 +1,57 @@ +.include "macros.inc" + +start + +test_name SR_1 +mvi r1, 1 +mvi r2, 0 +sr r3, r1, r2 +check_r3 1 + +test_name SR_2 +mvi r1, 0 +mvi r2, 1 +sr r3, r1, r2 +check_r3 0 + +test_name SR_3 +load r1 0x40000000 +mvi r2, 30 +sr r3, r1, r2 +check_r3 1 + +test_name SR_4 +load r1 0x40000000 +mvi r2, 31 +sr r3, r1, r2 +check_r3 0 + +test_name SR_5 +mvi r1, 16 +mvi r2, 34 +sr r3, r1, r2 +check_r3 4 + +test_name SR_6 +mvi r1, 2 +sr r3, r1, r1 +check_r3 0 + +test_name SR_7 +mvi r3, 2 +sr r3, r3, r3 +check_r3 0 + +test_name SR_8 +mvi r1, 0xfffffff0 +mvi r2, 2 +sr r3, r1, r2 +check_r3 0xfffffffc + +test_name SR_9 +mvi r1, 0xfffffff0 +mvi r2, 4 +sr r3, r1, r2 +check_r3 0xffffffff + +end diff --git a/qemu/tests/tcg/lm32/test_sri.S b/qemu/tests/tcg/lm32/test_sri.S new file mode 100644 index 000000000..c1be907b5 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sri.S @@ -0,0 +1,40 @@ +.include "macros.inc" + +start + +test_name SRI_1 +mvi r1, 1 +sri r3, r1, 0 +check_r3 1 + +test_name SRI_2 +mvi r1, 0 +sri r3, r1, 1 +check_r3 0 + +test_name SRI_3 +load r1 0x40000000 +sri r3, r1, 30 +check_r3 1 + +test_name SRI_4 +load r1 0x40000000 +sri r3, r1, 31 +check_r3 0 + +test_name SRI_5 +mvi r3, 2 +sri r3, r3, 2 +check_r3 0 + +test_name SRI_6 +mvi r1, 0xfffffff0 +sri r3, r1, 2 +check_r3 0xfffffffc + +test_name SRI_7 +mvi r1, 0xfffffff0 +sri r3, r1, 4 +check_r3 0xffffffff + +end diff --git a/qemu/tests/tcg/lm32/test_sru.S b/qemu/tests/tcg/lm32/test_sru.S new file mode 100644 index 000000000..2ab0b54c7 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sru.S @@ -0,0 +1,57 @@ +.include "macros.inc" + +start + +test_name SRU_1 +mvi r1, 1 +mvi r2, 0 +sru r3, r1, r2 +check_r3 1 + +test_name SRU_2 +mvi r1, 0 +mvi r2, 1 +sru r3, r1, r2 +check_r3 0 + +test_name SRU_3 +load r1 0x40000000 +mvi r2, 30 +sru r3, r1, r2 +check_r3 1 + +test_name SRU_4 +load r1 0x40000000 +mvi r2, 31 +sru r3, r1, r2 +check_r3 0 + +test_name SRU_5 +mvi r1, 16 +mvi r2, 34 +sru r3, r1, r2 +check_r3 4 + +test_name SRU_6 +mvi r1, 2 +sru r3, r1, r1 +check_r3 0 + +test_name SRU_7 +mvi r3, 2 +sru r3, r3, r3 +check_r3 0 + +test_name SRU_8 +mvi r1, 0xfffffff0 +mvi r2, 2 +sru r3, r1, r2 +check_r3 0x3ffffffc + +test_name SRU_9 +mvi r1, 0xfffffff0 +mvi r2, 4 +sru r3, r1, r2 +check_r3 0x0fffffff + +end diff --git a/qemu/tests/tcg/lm32/test_srui.S b/qemu/tests/tcg/lm32/test_srui.S new file mode 100644 index 000000000..872c37412 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_srui.S @@ -0,0 +1,40 @@ +.include "macros.inc" + +start + +test_name SRUI_1 +mvi r1, 1 +srui r3, r1, 0 +check_r3 1 + +test_name SRUI_2 +mvi r1, 0 +srui r3, r1, 1 +check_r3 0 + +test_name SRUI_3 +load r1 0x40000000 +srui r3, r1, 30 +check_r3 1 + +test_name SRUI_4 +load r1 0x40000000 +srui r3, r1, 31 +check_r3 0 + +test_name SRUI_5 +mvi r3, 2 +srui r3, r3, 2 +check_r3 0 + +test_name SRUI_6 +mvi r1, 0xfffffff0 +srui r3, r1, 2 +check_r3 0x3ffffffc + +test_name SRUI_7 +mvi r1, 0xfffffff0 +srui r3, r1, 4 +check_r3 0x0fffffff + +end diff --git a/qemu/tests/tcg/lm32/test_sub.S b/qemu/tests/tcg/lm32/test_sub.S new file mode 100644 index 000000000..44b74a9e1 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sub.S @@ -0,0 +1,75 @@ +.include "macros.inc" + +start + +test_name SUB_1 +mvi r1, 0 +mvi r2, 0 +sub r3, r1, r2 +check_r3 0 + +test_name SUB_2 +mvi r1, 0 +mvi r2, 1 +sub r3, r1, r2 +check_r3 -1 + +test_name SUB_3 +mvi r1, 1 +mvi r2, 0 +sub r3, r1, r2 +check_r3 1 + +test_name SUB_4 +mvi r1, 1 +mvi r2, -1 +sub r3, r1, r2 +check_r3 2 + +test_name SUB_5 +mvi r1, -1 +mvi r2, 1 +sub r3, r1, r2 +check_r3 -2 + +test_name SUB_6 +mvi r1, -1 +mvi r2, 0 +sub r3, r1, r2 +check_r3 -1 + +test_name SUB_7 +mvi r1, 0 +mvi r2, -1 +sub r3, r1, r2 +check_r3 1 + +test_name SUB_8 +mvi r3, 2 +sub r3, r3, r3 +check_r3 0 + +test_name SUB_9 +mvi r1, 4 +mvi r3, 2 +sub r3, r1, r3 +check_r3 2 + +test_name SUB_10 +mvi r1, 4 +mvi r3, 2 +sub r3, r3, r1 +check_r3 -2 + +test_name SUB_11 +mvi r1, 4 +sub r3, r1, r1 +check_r3 0 + +test_name SUB_12 +load r1 0x12345678 +load r2 0xabcdef97 +sub r3, r1, r2 +check_r3 0x666666e1 + +end diff --git a/qemu/tests/tcg/lm32/test_sw.S b/qemu/tests/tcg/lm32/test_sw.S new file mode 100644 index 000000000..2b1c017e7 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_sw.S @@ -0,0 +1,38 @@ +.include "macros.inc" + +start + +test_name SW_1 +load r1 data +load r2 0xaabbccdd +sw (r1+0), r2 +check_mem data 0xaabbccdd + +test_name SW_2 +load r1 data +load r2 0x00112233 +sw (r1+4), r2 +check_mem data1 0x00112233 + +test_name SW_3 +load r1 data +load r2 0x44556677 +sw (r1+-4), r2 +check_mem data0 0x44556677 + +test_name SW_4 +load r1 data +sw (r1+0), r1 +lw r3, (r1+0) +check_r3 data + +end + +.data + .align 4 +data0: + .byte 0, 0, 0, 0 +data: + .byte 0, 0, 0, 0 +data1: + .byte 0, 0, 0, 0 diff --git a/qemu/tests/tcg/lm32/test_xnor.S b/qemu/tests/tcg/lm32/test_xnor.S new file mode 100644 index 000000000..14a62075f --- /dev/null +++ b/qemu/tests/tcg/lm32/test_xnor.S @@ -0,0 +1,51 @@ +.include "macros.inc" + +start + +test_name XNOR_1 +mvi r1, 0 +mvi r2, 0 +xnor r3, r1, r2 +check_r3 0xffffffff + +test_name XNOR_2 +mvi r1, 0 +mvi r2, 1 +xnor r3, r1, r2 +check_r3 0xfffffffe + +test_name XNOR_3 +mvi r1, 1 +mvi r2, 1 +xnor r3, r1, r2 +check_r3 0xffffffff + +test_name XNOR_4 +mvi r1, 1 +mvi r2, 0 +xnor r3, r1, r2 +check_r3 0xfffffffe + +test_name XNOR_5 +load r1 0xaa55aa55 +load r2 0x55aa55aa +xnor r3, r1, r2 +check_r3 0 + +test_name XNOR_6 +load r1 0xaa550000 +load r2 0x0000aa55 +xnor r3, r1, r2 +check_r3 0x55aa55aa + +test_name XNOR_7 +load r1 0xaa55aa55 +xnor r3, r1, r1 +check_r3 0xffffffff + +test_name XNOR_8 +load r3 0xaa55aa55 +xnor r3, r3, r3 +check_r3 0xffffffff + +end diff --git a/qemu/tests/tcg/lm32/test_xnori.S b/qemu/tests/tcg/lm32/test_xnori.S new file mode 100644 index 000000000..9d9c3c678 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_xnori.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name XNORI_1 +mvi r1, 0 +xnori r3, r1, 0 +check_r3 0xffffffff + +test_name XNORI_2 +mvi r1, 0 +xnori r3, r1, 1 +check_r3 0xfffffffe + +test_name XNORI_3 +mvi r1, 1 +xnori r3, r1, 1 +check_r3 0xffffffff + +test_name XNORI_4 +mvi r1, 1 +xnori r3, r1, 0 +check_r3 0xfffffffe + +test_name XNORI_5 +load r1 0xaa55aa55 +xnori r3, r1, 0x5555 +check_r3 0x55aa00ff + +test_name XNORI_6 +load r3 0xaa55aa55 +xnori r3, r3, 0x5555 +check_r3 0x55aa00ff + +end diff --git a/qemu/tests/tcg/lm32/test_xor.S b/qemu/tests/tcg/lm32/test_xor.S new file mode 100644 index 000000000..6c6e712ba --- /dev/null +++ b/qemu/tests/tcg/lm32/test_xor.S @@ -0,0 +1,51 @@ +.include "macros.inc" + +start + +test_name XOR_1 +mvi r1, 0 +mvi r2, 0 +xor r3, r1, r2 +check_r3 0 + +test_name XOR_2 +mvi r1, 0 +mvi r2, 1 +xor r3, r1, r2 +check_r3 1 + +test_name XOR_3 +mvi r1, 1 +mvi r2, 1 +xor r3, r1, r2 +check_r3 0 + +test_name XOR_4 +mvi r1, 1 +mvi r2, 0 +xor r3, r1, r2 +check_r3 1 + +test_name XOR_5 +load r1 0xaa55aa55 +load r2 0x55aa55aa +xor r3, r1, r2 +check_r3 0xffffffff + +test_name XOR_6 +load r1 0xaa550000 +load r2 0x0000aa55 +xor r3, r1, r2 +check_r3 0xaa55aa55 + +test_name XOR_7 +load r1 0xaa55aa55 +xor r3, r1, r1 +check_r3 0 + +test_name XOR_8 +load r3 0xaa55aa55 +xor r3, r3, r3 +check_r3 0 + +end diff --git a/qemu/tests/tcg/lm32/test_xori.S b/qemu/tests/tcg/lm32/test_xori.S new file mode 100644 index 000000000..2051699f1 --- /dev/null +++ b/qemu/tests/tcg/lm32/test_xori.S @@ -0,0 +1,35 @@ +.include "macros.inc" + +start + +test_name XORI_1 +mvi r1, 0 +xori r3, r1, 0 +check_r3 0 + +test_name XORI_2 +mvi r1, 0 +xori r3, r1, 1 +check_r3 1 + +test_name XORI_3 +mvi r1, 1 +xori r3, r1, 1 +check_r3 0 + +test_name XORI_4 +mvi r1, 1 +xori r3, r1, 0 +check_r3 1 + +test_name XORI_5 +load r1 0xaa55aa55 +xori r3, r1, 0x5555 +check_r3 0xaa55ff00 + +test_name XORI_6 +load r3 0xaa55aa55 +xori r3, r3, 0x5555 +check_r3 0xaa55ff00 + +end diff --git a/qemu/tests/tcg/mips/mips32-dsp/Makefile b/qemu/tests/tcg/mips/mips32-dsp/Makefile new file mode 100644 index 000000000..c3a0a0094 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/Makefile @@ -0,0 +1,136 @@ +-include ../../config-host.mak + +CROSS=mips64el-unknown-linux-gnu- + +SIM=qemu-mipsel +SIM_FLAGS=-cpu 74Kf + +CC = $(CROSS)gcc +CFLAGS = -mabi=32 -march=mips32r2 -mgp32 -mdsp -static + +TESTCASES = absq_s_ph.tst +TESTCASES += absq_s_w.tst +TESTCASES += addq_ph.tst +TESTCASES += addq_s_ph.tst +TESTCASES += addq_s_w.tst +TESTCASES += addsc.tst +TESTCASES += addu_qb.tst +TESTCASES += addu_s_qb.tst +TESTCASES += addwc.tst +TESTCASES += bitrev.tst +TESTCASES += bposge32.tst +TESTCASES += cmp_eq_ph.tst +TESTCASES += cmpgu_eq_qb.tst +TESTCASES += cmpgu_le_qb.tst +TESTCASES += cmpgu_lt_qb.tst +TESTCASES += cmp_le_ph.tst +TESTCASES += cmp_lt_ph.tst +TESTCASES += cmpu_eq_qb.tst +TESTCASES += cmpu_le_qb.tst +TESTCASES += cmpu_lt_qb.tst +TESTCASES += dpaq_sa_l_w.tst +TESTCASES += dpaq_s_w_ph.tst +TESTCASES += dpau_h_qbl.tst +TESTCASES += dpau_h_qbr.tst +TESTCASES += dpsq_sa_l_w.tst +TESTCASES += dpsq_s_w_ph.tst +TESTCASES += dpsu_h_qbl.tst +TESTCASES += dpsu_h_qbr.tst +TESTCASES += extp.tst +TESTCASES += extpdp.tst +TESTCASES += extpdpv.tst +TESTCASES += extpv.tst +TESTCASES += extr_rs_w.tst +TESTCASES += extr_r_w.tst +TESTCASES += extr_s_h.tst +TESTCASES += extrv_rs_w.tst +TESTCASES += extrv_r_w.tst +TESTCASES += extrv_s_h.tst +TESTCASES += extrv_w.tst +TESTCASES += extr_w.tst +TESTCASES += insv.tst +TESTCASES += lbux.tst +TESTCASES += lhx.tst +TESTCASES += lwx.tst +TESTCASES += madd.tst +TESTCASES += maddu.tst +TESTCASES += maq_sa_w_phl.tst +TESTCASES += maq_sa_w_phr.tst +TESTCASES += maq_s_w_phl.tst +TESTCASES += maq_s_w_phr.tst +TESTCASES += mfhi.tst +TESTCASES += mflo.tst +TESTCASES += modsub.tst +TESTCASES += msub.tst +TESTCASES += msubu.tst +TESTCASES += mthi.tst +TESTCASES += mthlip.tst +TESTCASES += mtlo.tst +TESTCASES += muleq_s_w_phl.tst +TESTCASES += muleq_s_w_phr.tst +TESTCASES += muleu_s_ph_qbl.tst +TESTCASES += muleu_s_ph_qbr.tst +TESTCASES += mulq_rs_ph.tst +TESTCASES += mult.tst +TESTCASES += multu.tst +TESTCASES += packrl_ph.tst +TESTCASES += pick_ph.tst +TESTCASES += pick_qb.tst +TESTCASES += precequ_ph_qbla.tst +TESTCASES += precequ_ph_qbl.tst +TESTCASES += precequ_ph_qbra.tst +TESTCASES += precequ_ph_qbr.tst +TESTCASES += preceq_w_phl.tst +TESTCASES += preceq_w_phr.tst +TESTCASES += preceu_ph_qbla.tst +TESTCASES += preceu_ph_qbl.tst +TESTCASES += preceu_ph_qbra.tst +TESTCASES += preceu_ph_qbr.tst +TESTCASES += precrq_ph_w.tst +TESTCASES += precrq_qb_ph.tst +TESTCASES += precrq_rs_ph_w.tst +TESTCASES += precrqu_s_qb_ph.tst +TESTCASES += raddu_w_qb.tst +TESTCASES += rddsp.tst +TESTCASES += repl_ph.tst +TESTCASES += repl_qb.tst +TESTCASES += replv_ph.tst +TESTCASES += replv_qb.tst +TESTCASES += shilo.tst +TESTCASES += shilov.tst +TESTCASES += shll_ph.tst +TESTCASES += shll_qb.tst +TESTCASES += shll_s_ph.tst +TESTCASES += shll_s_w.tst +TESTCASES += shllv_ph.tst +TESTCASES += shllv_qb.tst +TESTCASES += shllv_s_ph.tst +TESTCASES += shllv_s_w.tst +TESTCASES += shra_ph.tst +TESTCASES += shra_r_ph.tst +TESTCASES += shra_r_w.tst +TESTCASES += shrav_ph.tst +TESTCASES += shrav_r_ph.tst +TESTCASES += shrav_r_w.tst +TESTCASES += shrl_qb.tst +TESTCASES += shrlv_qb.tst +TESTCASES += subq_ph.tst +TESTCASES += subq_s_ph.tst +TESTCASES += subq_s_w.tst +TESTCASES += subu_qb.tst +TESTCASES += subu_s_qb.tst +TESTCASES += wrdsp.tst + +all: $(TESTCASES) + +%.tst: %.c + $(CC) $(CFLAGS) $< -o $@ + +check: $(TESTCASES) + @for case in $(TESTCASES); do \ + echo $(SIM) $(SIM_FLAGS) ./$$case;\ + $(SIM) $(SIM_FLAGS) ./$$case; \ + done + +clean: + $(RM) -rf $(TESTCASES) diff --git a/qemu/tests/tcg/mips/mips32-dsp/absq_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/absq_s_ph.c new file mode 100644 index 000000000..aa8411202 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/absq_s_ph.c @@ -0,0 +1,31 @@ +#include<stdio.h> +#include<assert.h> + + +int main() +{ + int rd, rt; + int result; + + rt = 0x10017EFD; + result = 0x10017EFD; + + __asm + ("absq_s.ph %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x8000A536; + result = 0x7FFF5ACA; + + __asm + ("absq_s.ph %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/absq_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/absq_s_w.c new file mode 100644 index 000000000..3f52a4803 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/absq_s_w.c @@ -0,0 +1,37 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x80000000; + result = 0x7FFFFFFF; + __asm + ("absq_s.w %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x80030000; + result = 0x7FFD0000; + __asm + ("absq_s.w %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x31036080; + result = 0x31036080; + __asm + ("absq_s.w %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/addq_ph.c b/qemu/tests/tcg/mips/mips32-dsp/addq_ph.c new file mode 100644 index 000000000..96a549637 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/addq_ph.c @@ -0,0 +1,46 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0xFFFFFFFF; + rt = 0x10101010; + result = 0x100F100F; + __asm + ("addq.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + rs = 0x3712847D; + rt = 0x0031AF2D; + result = 0x374333AA; + __asm + ("addq.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + rs = 0x7fff847D; + rt = 0x0031AF2D; + result = 0x803033AA; + __asm + ("addq.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + __asm("rddsp %0\n\t" + : "=r"(dsp) + ); + assert(((dsp >> 20) & 0x01) == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/addq_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/addq_s_ph.c new file mode 100644 index 000000000..5f865f6cf --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/addq_s_ph.c @@ -0,0 +1,69 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0xFFFFFFFF; + rt = 0x10101010; + result = 0x100F100F; + __asm + ("addq_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + rs = 0x3712847D; + rt = 0x0031AF2D; + result = 0x37438000; + __asm + ("addq_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + __asm + ("rddsp %0\n\t" + : "=r"(dsp) + ); + assert(((dsp >> 20) & 0x01) == 1); + + rs = 0x7fff847D; + rt = 0x0031AF2D; + result = 0x7fff8000; + __asm + ("addq_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + __asm + ("rddsp %0\n\t" + : "=r"(dsp) + ); + assert(((dsp >> 20) & 0x01) == 1); + + rs = 0x8030847D; + rt = 0x8a00AF2D; + result = 0x80008000; + __asm + ("addq_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + __asm + ("rddsp %0\n\t" + : "=r"(dsp) + ); + assert(((dsp >> 20) & 0x01) == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/addq_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/addq_s_w.c new file mode 100644 index 000000000..1e13acf68 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/addq_s_w.c @@ -0,0 +1,44 @@ +#include<stdio.h> +#include<assert.h> + + +int main() +{ + int rd, rs, rt; + int result; + + rt = 0x10017EFD; + rs = 0x11111111; + result = 0x2112900e; + + __asm + ("addq_s.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rt = 0x80017EFD; + rs = 0x81111111; + result = 0x80000000; + + __asm + ("addq_s.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rt = 0x7fffffff; + rs = 0x01111111; + result = 0x7fffffff; + + __asm + ("addq_s.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/addsc.c b/qemu/tests/tcg/mips/mips32-dsp/addsc.c new file mode 100644 index 000000000..ace749f66 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/addsc.c @@ -0,0 +1,33 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x0000000F; + rt = 0x00000001; + result = 0x00000010; + __asm + ("addsc %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x00001110; + __asm + ("addsc %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + assert(((dsp >> 13) & 0x01) == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/addu_qb.c b/qemu/tests/tcg/mips/mips32-dsp/addu_qb.c new file mode 100644 index 000000000..23ba2e90d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/addu_qb.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x00FF00FF; + rt = 0x00010001; + result = 0x00000000; + __asm + ("addu.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + assert(((dsp >> 20) & 0x01) == 1); + + rs = 0xFFFF1111; + rt = 0x00020001; + result = 0xFF011112; + __asm + ("addu.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + assert(((dsp >> 20) & 0x01) == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/addu_s_qb.c b/qemu/tests/tcg/mips/mips32-dsp/addu_s_qb.c new file mode 100644 index 000000000..fe7fd3e6a --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/addu_s_qb.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x10FF01FF; + rt = 0x10010001; + result = 0x20FF01FF; + __asm + ("addu_s.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + assert(((dsp >> 20) & 0x1) == 1); + + rs = 0xFFFF1111; + rt = 0x00020001; + result = 0xFFFF1112; + __asm + ("addu_s.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + assert(((dsp >> 20) & 0x1) == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/addwc.c b/qemu/tests/tcg/mips/mips32-dsp/addwc.c new file mode 100644 index 000000000..8a8d81fab --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/addwc.c @@ -0,0 +1,49 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dspi, dspo; + int result; + + rs = 0x10FF01FF; + rt = 0x10010001; + dspi = 0x00002000; + result = 0x21000201; + __asm + ("wrdsp %3\n" + "addwc %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dspi) + ); + assert(rd == result); + + rs = 0xFFFF1111; + rt = 0x00020001; + dspi = 0x00; + result = 0x00011112; + __asm + ("wrdsp %3\n" + "addwc %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dspi) + ); + assert(rd == result); + + rs = 0x8FFF1111; + rt = 0x80020001; + dspi = 0x00; + result = 0x10011112; + __asm + ("wrdsp %4\n" + "addwc %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspo) + : "r"(rs), "r"(rt), "r"(dspi) + ); + assert(rd == result); + assert(((dspo >> 20) & 0x01) == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/bitrev.c b/qemu/tests/tcg/mips/mips32-dsp/bitrev.c new file mode 100644 index 000000000..04d8a3844 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/bitrev.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x12345678; + result = 0x00001E6A; + + __asm + ("bitrev %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/bposge32.c b/qemu/tests/tcg/mips/mips32-dsp/bposge32.c new file mode 100644 index 000000000..d25417ea7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/bposge32.c @@ -0,0 +1,44 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int dsp, sum; + int result; + + dsp = 0x20; + sum = 0x01; + result = 0x02; + + __asm + ("wrdsp %1\n\t" + "bposge32 test1\n\t" + "nop\n\t" + "addi %0, 0xA2\n\t" + "nop\n\t" + "test1:\n\t" + "addi %0, 0x01\n\t" + : "+r"(sum) + : "r"(dsp) + ); + assert(sum == result); + + dsp = 0x10; + sum = 0x01; + result = 0xA4; + + __asm + ("wrdsp %1\n\t" + "bposge32 test2\n\t" + "nop\n\t" + "addi %0, 0xA2\n\t" + "nop\n\t" + "test2:\n\t" + "addi %0, 0x01\n\t" + : "+r"(sum) + : "r"(dsp) + ); + assert(sum == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c b/qemu/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c new file mode 100644 index 000000000..957bd88ce --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x11777066; + rt = 0x55AA33FF; + result = 0x00; + __asm + ("cmp.eq.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + rd = (rd >> 24) & 0x03; + assert(rd == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x03; + __asm + ("cmp.eq.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + rd = (rd >> 24) & 0x03; + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmp_le_ph.c b/qemu/tests/tcg/mips/mips32-dsp/cmp_le_ph.c new file mode 100644 index 000000000..356f156c5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmp_le_ph.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x11777066; + rt = 0x55AA33FF; + result = 0x02; + __asm + ("cmp.le.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + rd = (rd >> 24) & 0x03; + assert(rd == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x03; + __asm + ("cmp.le.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + rd = (rd >> 24) & 0x03; + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c b/qemu/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c new file mode 100644 index 000000000..3fb4827ad --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x11777066; + rt = 0x55AA33FF; + result = 0x02; + __asm + ("cmp.lt.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + rd = (rd >> 24) & 0x03; + assert(rd == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x00; + __asm + ("cmp.lt.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + rd = (rd >> 24) & 0x03; + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c new file mode 100644 index 000000000..2615c84c7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c @@ -0,0 +1,31 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x02; + __asm + ("cmpgu.eq.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + assert(rd == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x0F; + __asm + ("cmpgu.eq.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c new file mode 100644 index 000000000..65d0813c3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c @@ -0,0 +1,31 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0F; + __asm + ("cmpgu.le.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + assert(rd == result); + + rs = 0x11777066; + rt = 0x11766066; + result = 0x09; + __asm + ("cmpgu.le.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c new file mode 100644 index 000000000..7dddad985 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c @@ -0,0 +1,31 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0D; + __asm + ("cmpgu.lt.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + assert(rd == result); + + rs = 0x11777066; + rt = 0x11766066; + result = 0x00; + __asm + ("cmpgu.lt.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c new file mode 100644 index 000000000..680f2a199 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int dsp; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x02; + __asm + ("cmpu.eq.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(dsp == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x0F; + __asm + ("cmpu.eq.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(dsp == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c new file mode 100644 index 000000000..43cfa509c --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int dsp; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0F; + __asm + ("cmpu.le.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(dsp == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x0F; + __asm + ("cmpu.le.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(dsp == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c b/qemu/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c new file mode 100644 index 000000000..074ca5b40 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int dsp; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0D; + __asm + ("cmpu.lt.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(dsp == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x00; + __asm + ("cmpu.lt.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(dsp == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c b/qemu/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c new file mode 100644 index 000000000..a6425b6ed --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c @@ -0,0 +1,31 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, dsp; + int ach = 0, acl = 0; + int resulth, resultl, resultdsp; + + rs = 0x800000FF; + rt = 0x80000002; + resulth = 0x00; + resultl = 0x800003FB; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = dsp >> 17 & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c b/qemu/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c new file mode 100644 index 000000000..cbf900713 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c @@ -0,0 +1,125 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, dsp; + int ach = 0, acl = 0; + int resulth, resultl, resultdsp; + + rs = 0x80000000; + rt = 0x80000000; + resulth = 0x7FFFFFFF; + resultl = 0xFFFFFFFF; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x00000012; + acl = 0x00000048; + rs = 0x80000000; + rt = 0x80000000; + + resulth = 0x7FFFFFFF; + resultl = 0xFFFFFFFF; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x741532A0; + acl = 0xFCEABB08; + rs = 0x80000000; + rt = 0x80000000; + + resulth = 0x7FFFFFFF; + resultl = 0xFFFFFFFF; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0; + acl = 0; + rs = 0xC0000000; + rt = 0x7FFFFFFF; + + resulth = 0xC0000000; + resultl = 0x80000000; + resultdsp = 0; + __asm + ("wrdsp $0\n\t" + "mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x20000000; + acl = 0; + rs = 0xE0000000; + rt = 0x7FFFFFFF; + + resulth = 0; + resultl = 0x40000000; + resultdsp = 0; + __asm + ("wrdsp $0\n\t" + "mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c new file mode 100644 index 000000000..6017b5e73 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c @@ -0,0 +1,27 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 3; + int resulth, resultl; + + rs = 0x800000FF; + rt = 0x80000002; + resulth = 0x05; + resultl = 0x4003; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpau.h.qbl $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c new file mode 100644 index 000000000..e4abb2e2a --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c @@ -0,0 +1,27 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 3; + int resulth, resultl; + + rs = 0x800000FF; + rt = 0x80000002; + resulth = 0x05; + resultl = 0x0201; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpau.h.qbr $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c b/qemu/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c new file mode 100644 index 000000000..74058fe7e --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c @@ -0,0 +1,45 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 5; + int resulth, resultl; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x00000004; + resultl = 0xF15F94A3; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_s.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x1424EF1F; + acl = 0x1035219A; + rs = 0x800083AD; + rt = 0x80003721; + resulth = 0x1424EF1E; + resultl = 0xC5C0D901; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_s.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c b/qemu/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c new file mode 100644 index 000000000..eda3b14e2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c @@ -0,0 +1,55 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, dsp; + int ach = 5, acl = 5; + int resulth, resultl, resultdsp; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x00BD3A22; + resultl = 0xD138776B; + resultdsp = 0x00; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x54321123; + acl = 5; + rs = 0x80000000; + rt = 0x80000000; + + resulth = 0xd4321123; + resultl = 0x06; + resultdsp = 0x01; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c new file mode 100644 index 000000000..94e2bf625 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c @@ -0,0 +1,27 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 5; + int resulth, resultl; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x04; + resultl = 0xFFFFFEE5; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsu.h.qbl $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c new file mode 100644 index 000000000..a1e663563 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c @@ -0,0 +1,27 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 5; + int resulth, resultl; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x04; + resultl = 0xFFFFE233; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsu.h.qbr $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extp.c b/qemu/tests/tcg/mips/mips32-dsp/extp.c new file mode 100644 index 000000000..b18bdb34c --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extp.c @@ -0,0 +1,62 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + result = 0x000C; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extp %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 14) & 0x01; + assert(dsp == 0); + assert(result == rt); + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x01; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extp %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 14) & 0x01; + assert(dsp == 1); + + ach = 0; + acl = 0x80000001; + dsp = 0x1F; + result = 0x80000001; + + __asm + ("wrdsp %1\n\t" + "mthi %2, $ac2\n\t" + "mtlo %3, $ac2\n\t" + "extp %0, $ac2, 0x1F\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 14) & 0x01; + assert(dsp == 0); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extpdp.c b/qemu/tests/tcg/mips/mips32-dsp/extpdp.c new file mode 100644 index 000000000..79ee16e8b --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extpdp.c @@ -0,0 +1,64 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, ach, acl, dsp, pos, efi; + int result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + result = 0x000C; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdp %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + pos = dsp & 0x3F; + efi = (dsp >> 14) & 0x01; + assert(pos == 3); + assert(efi == 0); + assert(result == rt); + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x01; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdp %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + efi = (dsp >> 14) & 0x01; + assert(efi == 1); + + + ach = 0; + acl = 0; + dsp = 0; + result = 0; + + __asm + ("wrdsp %1\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdp %0, $ac1, 0x00\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + assert(dsp == 0x3F); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extpdpv.c b/qemu/tests/tcg/mips/mips32-dsp/extpdpv.c new file mode 100644 index 000000000..f5774eed3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extpdpv.c @@ -0,0 +1,47 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs, ach, acl, dsp, pos, efi; + int result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0x000C; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdpv %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl), "r"(rs) + ); + pos = dsp & 0x3F; + efi = (dsp >> 14) & 0x01; + assert(pos == 3); + assert(efi == 0); + assert(result == rt); + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x01; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdpv %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl), "r"(rs) + ); + efi = (dsp >> 14) & 0x01; + assert(efi == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extpv.c b/qemu/tests/tcg/mips/mips32-dsp/extpv.c new file mode 100644 index 000000000..401b94afa --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extpv.c @@ -0,0 +1,45 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, ac, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + ac = 0x03; + result = 0x000C; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpv %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl), "r"(ac) + ); + dsp = (dsp >> 14) & 0x01; + assert(dsp == 0); + assert(result == rt); + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x01; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpv %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl), "r"(ac) + ); + dsp = (dsp >> 14) & 0x01; + assert(dsp == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extr_r_w.c b/qemu/tests/tcg/mips/mips32-dsp/extr_r_w.c new file mode 100644 index 000000000..489c1931b --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extr_r_w.c @@ -0,0 +1,94 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + result = 0xA0001699; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_r.w %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4D; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_r.w %0, $ac1, 0x04\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x3fffffff; + acl = 0x2bcdef01; + result = 0x7ffffffe; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_r.w %0, $ac1, 0x1F\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0xFFFFFFFF; + acl = 0xFFFFFFFF; + result = 0; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_r.w %0, $ac1, 0x1F\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extr_rs_w.c b/qemu/tests/tcg/mips/mips32-dsp/extr_rs_w.c new file mode 100644 index 000000000..f9d2ed646 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extr_rs_w.c @@ -0,0 +1,117 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + result = 0x7FFFFFFF; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_rs.w %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4D; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_rs.w %0, $ac1, 0x04\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x3fffffff; + acl = 0x2bcdef01; + result = 0x7ffffffe; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_rs.w %0, $ac1, 0x1F\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x80000000; + acl = 0x00000000; + result = 0x80000000; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_rs.w %0, $ac1, 0x1F\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0xFFFFFFFF; + acl = 0xFFFFFFFF; + result = 0; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_rs.w %0, $ac1, 0x1F\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extr_s_h.c b/qemu/tests/tcg/mips/mips32-dsp/extr_s_h.c new file mode 100644 index 000000000..9bc2a63cc --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extr_s_h.c @@ -0,0 +1,86 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + result = 0x00007FFF; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_s.h %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + ach = 0xffffffff; + acl = 0x12344321; + result = 0xFFFF8000; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_s.h %0, $ac1, 0x08\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dsp */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x00; + acl = 0x4321; + result = 0x432; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_s.h %0, $ac1, 0x04\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dsp */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x123; + acl = 0x87654321; + result = 0x1238; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_s.h %0, $ac1, 28\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extr_w.c b/qemu/tests/tcg/mips/mips32-dsp/extr_w.c new file mode 100644 index 000000000..cf926146d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extr_w.c @@ -0,0 +1,94 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + result = 0xA0001699; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr.w %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4C; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr.w %0, $ac1, 0x04\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x3fffffff; + acl = 0x2bcdef01; + result = 0x7ffffffe; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr.w %0, $ac1, 0x1F\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0xFFFFFFFF; + acl = 0xFFFFFFFF; + result = 0xFFFFFFFF; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr.w %0, $ac1, 0x1F\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extrv_r_w.c b/qemu/tests/tcg/mips/mips32-dsp/extrv_r_w.c new file mode 100644 index 000000000..2403b3afe --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extrv_r_w.c @@ -0,0 +1,79 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0xA0001699; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_r.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 4; + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4D; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_r.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 31; + ach = 0x3fffffff; + acl = 0x2bcdef01; + result = 0x7ffffffe; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_r.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extrv_rs_w.c b/qemu/tests/tcg/mips/mips32-dsp/extrv_rs_w.c new file mode 100644 index 000000000..ccceeb9f4 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extrv_rs_w.c @@ -0,0 +1,77 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs, ach, acl, dsp; + int result; + + rs = 0x03; + ach = 0x05; + acl = 0xB4CB; + result = 0x7FFFFFFF; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_rs.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 0x04; + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4D; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_rs.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 0x1F; + ach = 0x3fffffff; + acl = 0x2bcdef01; + result = 0x7ffffffe; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_rs.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extrv_s_h.c b/qemu/tests/tcg/mips/mips32-dsp/extrv_s_h.c new file mode 100644 index 000000000..feac3e2e3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extrv_s_h.c @@ -0,0 +1,88 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0x00007FFF; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_s.h %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + rs = 0x08; + ach = 0xffffffff; + acl = 0x12344321; + result = 0xFFFF8000; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_s.h %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dsp */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 0x04; + ach = 0x00; + acl = 0x4321; + result = 0x432; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_s.h %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + rs = 0x1C; + ach = 0x123; + acl = 0x87654321; + result = 0x1238; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_s.h %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/extrv_w.c b/qemu/tests/tcg/mips/mips32-dsp/extrv_w.c new file mode 100644 index 000000000..9e8b238a0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/extrv_w.c @@ -0,0 +1,80 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs, ach, acl, dsp; + int result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0xA0001699; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 1); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 4; + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4C; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 31; + ach = 0x3fffffff; + acl = 0x2bcdef01; + result = 0x7ffffffe; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + assert(dsp == 0); + assert(result == rt); + + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/insv.c b/qemu/tests/tcg/mips/mips32-dsp/insv.c new file mode 100644 index 000000000..9d674697c --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/insv.c @@ -0,0 +1,36 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs, dsp; + int result; + + /* msb = 10, lsb = 5 */ + dsp = 0x305; + rt = 0x12345678; + rs = 0x87654321; + result = 0x12345438; + __asm + ("wrdsp %2, 0x03\n\t" + "insv %0, %1\n\t" + : "+r"(rt) + : "r"(rs), "r"(dsp) + ); + assert(rt == result); + + dsp = 0x1000; + rt = 0xF0F0F0F0; + rs = 0xA5A5A5A5; + result = 0xA5A5A5A5; + + __asm + ("wrdsp %2\n\t" + "insv %0, %1\n\t" + : "+r"(rt) + : "r"(rs), "r"(dsp) + ); + assert(rt == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/lbux.c b/qemu/tests/tcg/mips/mips32-dsp/lbux.c new file mode 100644 index 000000000..2337abea2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/lbux.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <assert.h> + +int main(void) +{ + int value, rd; + int *p; + unsigned long addr, index; + int result; + + value = 0xBCDEF389; + p = &value; + addr = (unsigned long)p; + index = 0; + result = value & 0xFF; + __asm + ("lbux %0, %1(%2)\n\t" + : "=r"(rd) + : "r"(index), "r"(addr) + ); + + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/lhx.c b/qemu/tests/tcg/mips/mips32-dsp/lhx.c new file mode 100644 index 000000000..10be3b385 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/lhx.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <assert.h> + +int main(void) +{ + int value, rd; + int *p; + unsigned long addr, index; + int result; + + value = 0xBCDEF389; + p = &value; + addr = (unsigned long)p; + index = 0; + result = 0xFFFFF389; + __asm + ("lhx %0, %1(%2)\n\t" + : "=r"(rd) + : "r"(index), "r"(addr) + ); + + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/lwx.c b/qemu/tests/tcg/mips/mips32-dsp/lwx.c new file mode 100644 index 000000000..e6543c9e7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/lwx.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <assert.h> + +int main(void) +{ + int value, rd; + int *p; + unsigned long addr, index; + int result; + + value = 0xBCDEF389; + p = &value; + addr = (unsigned long)p; + index = 0; + result = 0xBCDEF389; + __asm + ("lwx %0, %1(%2)\n\t" + : "=r"(rd) + : "r"(index), "r"(addr) + ); + + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/madd.c b/qemu/tests/tcg/mips/mips32-dsp/madd.c new file mode 100644 index 000000000..af4bfcfe9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/madd.c @@ -0,0 +1,31 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs; + int achi, acli; + int acho, aclo; + int resulth, resultl; + + achi = 0x05; + acli = 0xB4CB; + rs = 0x01; + rt = 0x01; + resulth = 0x05; + resultl = 0xB4CC; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "madd $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/maddu.c b/qemu/tests/tcg/mips/mips32-dsp/maddu.c new file mode 100644 index 000000000..af4bfcfe9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/maddu.c @@ -0,0 +1,31 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs; + int achi, acli; + int acho, aclo; + int resulth, resultl; + + achi = 0x05; + acli = 0xB4CB; + rs = 0x01; + rt = 0x01; + resulth = 0x05; + resultl = 0xB4CC; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "madd $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/main.c b/qemu/tests/tcg/mips/mips32-dsp/main.c new file mode 100644 index 000000000..b296b20c9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/main.c @@ -0,0 +1,6 @@ +#include<stdio.h> + +int main() +{ + printf("hello world\n"); +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c b/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c new file mode 100644 index 000000000..0f7c07015 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c @@ -0,0 +1,55 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs; + int achi, acli; + int dsp; + int acho, aclo; + int resulth, resultl; + int resdsp; + + achi = 0x00000005; + acli = 0x0000B4CB; + rs = 0xFF060000; + rt = 0xCB000000; + resulth = 0x00000005; + resultl = 0x006838CB; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.w.phl $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + + achi = 0x00000006; + acli = 0x0000B4CB; + rs = 0x80000000; + rt = 0x80000000; + resulth = 0x00000006; + resultl = 0x8000B4CA; + resdsp = 1; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.w.phl $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + assert(((dsp >> 17) & 0x01) == resdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c b/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c new file mode 100644 index 000000000..942722a53 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c @@ -0,0 +1,55 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs; + int achi, acli; + int dsp; + int acho, aclo; + int resulth, resultl; + int resdsp; + + achi = 0x00000005; + acli = 0x0000B4CB; + rs = 0x0000FF06; + rt = 0x0000CB00; + resulth = 0x00000005; + resultl = 0x006838CB; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.w.phr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + + achi = 0x00000006; + acli = 0x0000B4CB; + rs = 0x00008000; + rt = 0x00008000; + resulth = 0x00000006; + resultl = 0x8000B4CA; + resdsp = 1; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.w.phr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + assert(((dsp >> 17) & 0x01) == resdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c b/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c new file mode 100644 index 000000000..d83dce6f3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c @@ -0,0 +1,55 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs; + int achi, acli; + int dsp; + int acho, aclo; + int resulth, resultl; + int resdsp; + + achi = 0x00000000; + acli = 0x0000B4CB; + rs = 0xFF060000; + rt = 0xCB000000; + resulth = 0x00000000; + resultl = 0x006838CB; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_sa.w.phl $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + + achi = 0x00000000; + acli = 0x0000B4CB; + rs = 0x80000000; + rt = 0x80000000; + resulth = 0x00; + resultl = 0x7fffffff; + resdsp = 0x01; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.phl $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + assert(((dsp >> 17) & 0x01) == 0x01); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c b/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c new file mode 100644 index 000000000..d2331118a --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c @@ -0,0 +1,55 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rt, rs; + int achi, acli; + int dsp; + int acho, aclo; + int resulth, resultl; + int resdsp; + + achi = 0x00000000; + acli = 0x0000B4CB; + rs = 0x0000FF06; + rt = 0x0000CB00; + resulth = 0x00000000; + resultl = 0x006838CB; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_sa.w.phr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + + achi = 0x00000000; + acli = 0x0000B4CB; + rs = 0x00008000; + rt = 0x00008000; + resulth = 0x00000000; + resultl = 0x7FFFFFFF; + resdsp = 0x01; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.phr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(resulth == acho); + assert(resultl == aclo); + assert(((dsp >> 17) & 0x01) == 0x01); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/mfhi.c b/qemu/tests/tcg/mips/mips32-dsp/mfhi.c new file mode 100644 index 000000000..43a80669d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/mfhi.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int achi, acho; + int result; + + achi = 0x004433; + result = 0x004433; + + __asm + ("mthi %1, $ac1\n\t" + "mfhi %0, $ac1\n\t" + : "=r"(acho) + : "r"(achi) + ); + assert(result == acho); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/mflo.c b/qemu/tests/tcg/mips/mips32-dsp/mflo.c new file mode 100644 index 000000000..caeafdb05 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/mflo.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int acli, aclo; + int result; + + acli = 0x004433; + result = 0x004433; + + __asm + ("mthi %1, $ac1\n\t" + "mfhi %0, $ac1\n\t" + : "=r"(aclo) + : "r"(acli) + ); + assert(result == aclo); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/modsub.c b/qemu/tests/tcg/mips/mips32-dsp/modsub.c new file mode 100644 index 000000000..c294eebb5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/modsub.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0xFFFFFFFF; + rt = 0x000000FF; + result = 0xFFFFFF00; + __asm + ("modsub %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + rs = 0x00000000; + rt = 0x00CD1FFF; + result = 0x0000CD1F; + __asm + ("modsub %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/msub.c b/qemu/tests/tcg/mips/mips32-dsp/msub.c new file mode 100644 index 000000000..5779e6f47 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/msub.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int achi, acli, rs, rt; + int acho, aclo; + int resulth, resultl; + + rs = 0x00BBAACC; + rt = 0x0B1C3D2F; + achi = 0x00004433; + acli = 0xFFCC0011; + resulth = 0xFFF81F29; + resultl = 0xB355089D; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "msub $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(acho == resulth); + assert(aclo == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/msubu.c b/qemu/tests/tcg/mips/mips32-dsp/msubu.c new file mode 100644 index 000000000..e0f9b5a77 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/msubu.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int achi, acli, rs, rt; + int acho, aclo; + int resulth, resultl; + + rs = 0x00BBAACC; + rt = 0x0B1C3D2F; + achi = 0x00004433; + acli = 0xFFCC0011; + resulth = 0xFFF81F29; + resultl = 0xB355089D; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "msubu $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + assert(acho == resulth); + assert(aclo == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/mthi.c b/qemu/tests/tcg/mips/mips32-dsp/mthi.c new file mode 100644 index 000000000..43a80669d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/mthi.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int achi, acho; + int result; + + achi = 0x004433; + result = 0x004433; + + __asm + ("mthi %1, $ac1\n\t" + "mfhi %0, $ac1\n\t" + : "=r"(acho) + : "r"(achi) + ); + assert(result == acho); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/mthlip.c b/qemu/tests/tcg/mips/mips32-dsp/mthlip.c new file mode 100644 index 000000000..85f94d845 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/mthlip.c @@ -0,0 +1,58 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, ach, acl, dsp; + int result, resulth, resultl; + + dsp = 0x07; + ach = 0x05; + acl = 0xB4CB; + rs = 0x00FFBBAA; + resulth = 0xB4CB; + resultl = 0x00FFBBAA; + result = 0x27; + + __asm + ("wrdsp %0, 0x01\n\t" + "mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "mthlip %3, $ac1\n\t" + "mfhi %1, $ac1\n\t" + "mflo %2, $ac1\n\t" + "rddsp %0\n\t" + : "+r"(dsp), "+r"(ach), "+r"(acl) + : "r"(rs) + ); + dsp = dsp & 0x3F; + assert(dsp == result); + assert(ach == resulth); + assert(acl == resultl); + + dsp = 0x1f; + ach = 0x05; + acl = 0xB4CB; + rs = 0x00FFBBAA; + resulth = 0xB4CB; + resultl = 0x00FFBBAA; + result = 0x3f; + + __asm + ("wrdsp %0, 0x01\n\t" + "mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "mthlip %3, $ac1\n\t" + "mfhi %1, $ac1\n\t" + "mflo %2, $ac1\n\t" + "rddsp %0\n\t" + : "+r"(dsp), "+r"(ach), "+r"(acl) + : "r"(rs) + ); + dsp = dsp & 0x3F; + assert(dsp == result); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/mtlo.c b/qemu/tests/tcg/mips/mips32-dsp/mtlo.c new file mode 100644 index 000000000..caeafdb05 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/mtlo.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int acli, aclo; + int result; + + acli = 0x004433; + result = 0x004433; + + __asm + ("mthi %1, $ac1\n\t" + "mfhi %0, $ac1\n\t" + : "=r"(aclo) + : "r"(acli) + ); + assert(result == aclo); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c b/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c new file mode 100644 index 000000000..b3a5370fe --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c @@ -0,0 +1,41 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x80001234; + rt = 0x80001234; + result = 0x7FFFFFFF; + resultdsp = 1; + + __asm + ("muleq_s.w.phl %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + rs = 0x12349988; + rt = 0x43219988; + result = 0x98be968; + resultdsp = 1; + + __asm + ("muleq_s.w.phl %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c b/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c new file mode 100644 index 000000000..8066d7d02 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c @@ -0,0 +1,40 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x8000; + rt = 0x8000; + result = 0x7FFFFFFF; + resultdsp = 1; + + __asm + ("muleq_s.w.phr %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + rs = 0x1234; + rt = 0x4321; + result = 0x98be968; + resultdsp = 1; + + __asm + ("muleq_s.w.phr %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c new file mode 100644 index 000000000..66a382806 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c @@ -0,0 +1,25 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0xFFFF0000; + resultdsp = 1; + + __asm + ("muleu_s.ph.qbl %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c new file mode 100644 index 000000000..4cc6c8f7c --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c @@ -0,0 +1,25 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x8000; + rt = 0x80004321; + result = 0xFFFF0000; + resultdsp = 1; + + __asm + ("muleu_s.ph.qbr %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c b/qemu/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c new file mode 100644 index 000000000..370c2a801 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c @@ -0,0 +1,42 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0x7FFF098C; + resultdsp = 1; + + __asm + ("wrdsp $0\n\t" + "mulq_rs.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + rs = 0x80011234; + rt = 0x80024321; + result = 0x7FFD098C; + resultdsp = 0; + + __asm + ("wrdsp $0\n\t" + "mulq_rs.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/mult.c b/qemu/tests/tcg/mips/mips32-dsp/mult.c new file mode 100644 index 000000000..15e6fde92 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/mult.c @@ -0,0 +1,24 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, ach, acl; + int result, resulth, resultl; + + rs = 0x00FFBBAA; + rt = 0x4B231000; + resulth = 0x4b0f01; + resultl = 0x71f8a000; + __asm + ("mult $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(ach), "=r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/multu.c b/qemu/tests/tcg/mips/mips32-dsp/multu.c new file mode 100644 index 000000000..85d36c1b6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/multu.c @@ -0,0 +1,24 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, ach, acl; + int result, resulth, resultl; + + rs = 0x00FFBBAA; + rt = 0x4B231000; + resulth = 0x4b0f01; + resultl = 0x71f8a000; + __asm + ("multu $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(ach), "=r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/packrl_ph.c b/qemu/tests/tcg/mips/mips32-dsp/packrl_ph.c new file mode 100644 index 000000000..1f8e69992 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/packrl_ph.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x56788765; + + __asm + ("packrl.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/pick_ph.c b/qemu/tests/tcg/mips/mips32-dsp/pick_ph.c new file mode 100644 index 000000000..929a002e7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/pick_ph.c @@ -0,0 +1,49 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result; + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x0A000000; + result = 0x12344321; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + assert(rd == result); + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x03000000; + result = 0x12345678; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + assert(rd == result); + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x00000000; + result = 0x87654321; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/pick_qb.c b/qemu/tests/tcg/mips/mips32-dsp/pick_qb.c new file mode 100644 index 000000000..a79047524 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/pick_qb.c @@ -0,0 +1,36 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result; + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x0f000000; + result = 0x12345678; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + assert(rd == result); + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x00000000; + result = 0x87654321; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phl.c b/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phl.c new file mode 100644 index 000000000..bf70bf7d3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phl.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x87650000; + + __asm + ("preceq.w.phl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phr.c b/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phr.c new file mode 100644 index 000000000..3f885ef58 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/preceq_w_phr.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x43210000; + + __asm + ("preceq.w.phr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c new file mode 100644 index 000000000..63b7a9568 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x43803280; + + __asm + ("precequ.ph.qbl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c new file mode 100644 index 000000000..31627f0bd --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x43802180; + + __asm + ("precequ.ph.qbla %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c new file mode 100644 index 000000000..b6f72d3cb --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x21801080; + + __asm + ("precequ.ph.qbr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c new file mode 100644 index 000000000..4764fd031 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x32801080; + + __asm + ("precequ.ph.qbra %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c new file mode 100644 index 000000000..fa95c26cc --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x00870065; + + __asm + ("preceu.ph.qbl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c new file mode 100644 index 000000000..021f21a74 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x00870043; + + __asm + ("preceu.ph.qbla %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c new file mode 100644 index 000000000..03df18c72 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x00430021; + + __asm + ("preceu.ph.qbr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c new file mode 100644 index 000000000..634327618 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0x00650021; + + __asm + ("preceu.ph.qbra %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/precrq_ph_w.c b/qemu/tests/tcg/mips/mips32-dsp/precrq_ph_w.c new file mode 100644 index 000000000..25d45f1a9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/precrq_ph_w.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x12348765; + + __asm + ("precrq.ph.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c b/qemu/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c new file mode 100644 index 000000000..fe23acce8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x12568743; + + __asm + ("precrq.qb.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c b/qemu/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c new file mode 100644 index 000000000..da6845bf2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c @@ -0,0 +1,51 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x12348765; + + __asm + ("wrdsp $0\n\t" + "precrq_rs.ph.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + rs = 0x7FFFC678; + rt = 0x865432A0; + result = 0x7FFF8654; + + __asm + ("wrdsp $0\n\t" + "precrq_rs.ph.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(((dsp >> 22) & 0x01) == 1); + assert(result == rd); + + rs = 0xBEEFFEED; + rt = 0x7FFF8000; + result = 0xBEF07FFF; + + __asm + ("wrdsp $0\n\t" + "precrq_rs.ph.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(((dsp >> 22) & 0x01) == 1); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c b/qemu/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c new file mode 100644 index 000000000..7481d5af3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c @@ -0,0 +1,24 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x12345678; + rt = 0x87657FFF; + result = 0x24AC00FF; + + __asm + ("precrqu_s.qb.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + assert(((dsp >> 22) & 0x01) == 0x01); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/raddu_w_qb.c b/qemu/tests/tcg/mips/mips32-dsp/raddu_w_qb.c new file mode 100644 index 000000000..77a983c0d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/raddu_w_qb.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs; + int result; + + rs = 0x12345678; + result = 0x114; + + __asm + ("raddu.w.qb %0, %1\n\t" + : "=r"(rd) + : "r"(rs) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/rddsp.c b/qemu/tests/tcg/mips/mips32-dsp/rddsp.c new file mode 100644 index 000000000..2f3028503 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/rddsp.c @@ -0,0 +1,46 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int dsp_i, dsp_o; + int ccond_i, outflag_i, efi_i, c_i, scount_i, pos_i; + int ccond_o, outflag_o, efi_o, c_o, scount_o, pos_o; + + ccond_i = 0x0000000C; /* 4 */ + outflag_i = 0x0000001B; /* 3 */ + efi_i = 0x00000001; /* 5 */ + c_i = 0x00000001; /* 2 */ + scount_i = 0x0000000F; /* 1 */ + pos_i = 0x0000000C; /* 0 */ + + dsp_i = (ccond_i << 24) | \ + (outflag_i << 16) | \ + (efi_i << 14) | \ + (c_i << 13) | \ + (scount_i << 7) | \ + pos_i; + + __asm + ("wrdsp %1, 0x3F\n\t" + "rddsp %0, 0x3F\n\t" + : "=r"(dsp_o) + : "r"(dsp_i) + ); + + ccond_o = (dsp_o >> 24) & 0xFF; + outflag_o = (dsp_o >> 16) & 0xFF; + efi_o = (dsp_o >> 14) & 0x01; + c_o = (dsp_o >> 14) & 0x01; + scount_o = (dsp_o >> 7) & 0x3F; + pos_o = dsp_o & 0x1F; + + assert(ccond_o == ccond_i); + assert(outflag_o == outflag_i); + assert(efi_o == efi_i); + assert(c_o == c_i); + assert(scount_o == scount_i); + assert(pos_o == pos_i); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/repl_ph.c b/qemu/tests/tcg/mips/mips32-dsp/repl_ph.c new file mode 100644 index 000000000..21074953b --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/repl_ph.c @@ -0,0 +1,23 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, result; + + result = 0x01BF01BF; + __asm + ("repl.ph %0, 0x1BF\n\t" + : "=r"(rd) + ); + assert(rd == result); + + result = 0x01FF01FF; + __asm + ("repl.ph %0, 0x01FF\n\t" + : "=r"(rd) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/repl_qb.c b/qemu/tests/tcg/mips/mips32-dsp/repl_qb.c new file mode 100644 index 000000000..6631393ea --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/repl_qb.c @@ -0,0 +1,16 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, result; + + result = 0xBFBFBFBF; + __asm + ("repl.qb %0, 0xBF\n\t" + : "=r"(rd) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/replv_ph.c b/qemu/tests/tcg/mips/mips32-dsp/replv_ph.c new file mode 100644 index 000000000..07fb15f1f --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/replv_ph.c @@ -0,0 +1,19 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x12345678; + result = 0x56785678; + __asm + ("replv.ph %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/replv_qb.c b/qemu/tests/tcg/mips/mips32-dsp/replv_qb.c new file mode 100644 index 000000000..dd1271fed --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/replv_qb.c @@ -0,0 +1,19 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x12345678; + result = 0x78787878; + __asm + ("replv.qb %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shilo.c b/qemu/tests/tcg/mips/mips32-dsp/shilo.c new file mode 100644 index 000000000..ce8ebc69c --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shilo.c @@ -0,0 +1,45 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int ach, acl; + int resulth, resultl; + + ach = 0xBBAACCFF; + acl = 0x1C3B001D; + + resulth = 0x17755; + resultl = 0x99fe3876; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "shilo $ac1, 0x0F\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + ); + assert(ach == resulth); + assert(acl == resultl); + + + ach = 0x1; + acl = 0x80000000; + + resulth = 0x3; + resultl = 0x0; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "shilo $ac1, -1\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shilov.c b/qemu/tests/tcg/mips/mips32-dsp/shilov.c new file mode 100644 index 000000000..e1d6cea4b --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shilov.c @@ -0,0 +1,49 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, ach, acl; + int resulth, resultl; + + rs = 0x0F; + ach = 0xBBAACCFF; + acl = 0x1C3B001D; + + resulth = 0x17755; + resultl = 0x99fe3876; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "shilov $ac1, %2\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs) + ); + assert(ach == resulth); + assert(acl == resultl); + + + rs = 0xffffffff; + ach = 0x1; + acl = 0x80000000; + + resulth = 0x3; + resultl = 0x0; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "shilov $ac1, %2\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shll_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shll_ph.c new file mode 100644 index 000000000..5fa58ccf6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shll_ph.c @@ -0,0 +1,55 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt, dsp; + int result, resultdsp; + + rt = 0x12345678; + result = 0xA000C000; + resultdsp = 1; + + __asm + ("wrdsp $0\n\t" + "shll.ph %0, %2, 0x0B\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rt = 0x7fff8000; + result = 0xfffe0000; + resultdsp = 1; + + __asm + ("wrdsp $0\n\t" + "shll.ph %0, %2, 0x01\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rt = 0x00000001; + result = 0x00008000; + resultdsp = 1; + + __asm + ("wrdsp $0\n\t" + "shll.ph %0, %2, 0x0F\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shll_qb.c b/qemu/tests/tcg/mips/mips32-dsp/shll_qb.c new file mode 100644 index 000000000..729716d62 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shll_qb.c @@ -0,0 +1,55 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt, dsp; + int result, resultdsp; + + rt = 0x87654321; + result = 0x87654321; + resultdsp = 0x00; + + __asm + ("wrdsp $0\n\t" + "shll.qb %0, %2, 0x00\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rt = 0x87654321; + result = 0x38281808; + resultdsp = 0x01; + + __asm + ("wrdsp $0\n\t" + "shll.qb %0, %2, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rt = 0x00000001; + result = 0x00000080; + resultdsp = 0x00; + + __asm + ("wrdsp $0\n\t" + "shll.qb %0, %2, 0x07\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shll_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shll_s_ph.c new file mode 100644 index 000000000..910fea3b3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shll_s_ph.c @@ -0,0 +1,24 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt, dsp; + int result, resultdsp; + + rt = 0x12345678; + result = 0x7FFF7FFF; + resultdsp = 0x01; + + __asm + ("shll_s.ph %0, %2, 0x0B\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shll_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/shll_s_w.c new file mode 100644 index 000000000..628c75210 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shll_s_w.c @@ -0,0 +1,52 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt, dsp; + int result, resultdsp; + + rt = 0x82345678; + result = 0x82345678; + resultdsp = 0x00; + + __asm + ("shll_s.w %0, %2, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rt = 0x82345678; + result = 0x80000000; + resultdsp = 0x01; + + __asm + ("shll_s.w %0, %2, 0x0B\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rt = 0x12345678; + result = 0x7FFFFFFF; + resultdsp = 0x01; + + __asm + ("shll_s.w %0, %2, 0x0B\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shllv_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shllv_ph.c new file mode 100644 index 000000000..f98a6322d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shllv_ph.c @@ -0,0 +1,40 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x0; + rt = 0x12345678; + result = 0x12345678; + resultdsp = 0; + + __asm + ("shllv.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x0B; + rt = 0x12345678; + result = 0xA000C000; + resultdsp = 1; + + __asm + ("shllv.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shllv_qb.c b/qemu/tests/tcg/mips/mips32-dsp/shllv_qb.c new file mode 100644 index 000000000..6d8ff4a25 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shllv_qb.c @@ -0,0 +1,38 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x03; + rt = 0x87654321; + result = 0x38281808; + resultdsp = 0x01; + + __asm + ("shllv.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + assert(rd == result); + + rs = 0x00; + rt = 0x87654321; + result = 0x87654321; + resultdsp = 0x01; + + __asm + ("shllv.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shllv_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shllv_s_ph.c new file mode 100644 index 000000000..fc9bd3276 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shllv_s_ph.c @@ -0,0 +1,40 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x0; + rt = 0x12345678; + result = 0x12345678; + resultdsp = 0x0; + + __asm + ("shllv_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x0B; + rt = 0x12345678; + result = 0x7FFF7FFF; + resultdsp = 0x01; + + __asm + ("shllv_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shllv_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/shllv_s_w.c new file mode 100644 index 000000000..350c25617 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shllv_s_w.c @@ -0,0 +1,40 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x0B; + rt = 0x12345678; + result = 0x7FFFFFFF; + resultdsp = 0x01; + + __asm + ("shllv_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x0; + rt = 0x12345678; + result = 0x12345678; + resultdsp = 0x01; + + __asm + ("shllv_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shra_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shra_ph.c new file mode 100644 index 000000000..5b2d840a6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shra_ph.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0xF0EC0864; + + __asm + ("shra.ph %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x87654321; + result = 0x87654321; + + __asm + ("shra.ph %0, %1, 0x00\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shra_r_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shra_r_ph.c new file mode 100644 index 000000000..adc4ae68b --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shra_r_ph.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0xF0ED0864; + + __asm + ("shra_r.ph %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x87654321; + result = 0x87654321; + + __asm + ("shra_r.ph %0, %1, 0x00\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shra_r_w.c b/qemu/tests/tcg/mips/mips32-dsp/shra_r_w.c new file mode 100644 index 000000000..ec0cf2c72 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shra_r_w.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x87654321; + result = 0xF0ECA864; + + __asm + ("shra_r.w %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x87654321; + result = 0x87654321; + + __asm + ("shra_r.w %0, %1, 0x0\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrav_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shrav_ph.c new file mode 100644 index 000000000..6e42aaf8e --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shrav_ph.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x03; + rt = 0x87654321; + result = 0xF0EC0864; + + __asm + ("shrav.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + rs = 0x00; + rt = 0x87654321; + result = 0x87654321; + + __asm + ("shrav.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrav_r_ph.c b/qemu/tests/tcg/mips/mips32-dsp/shrav_r_ph.c new file mode 100644 index 000000000..f03b978d0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shrav_r_ph.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x03; + rt = 0x87654321; + result = 0xF0ED0864; + + __asm + ("shrav_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + rs = 0x00; + rt = 0x87654321; + result = 0x87654321; + + __asm + ("shrav_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrav_r_w.c b/qemu/tests/tcg/mips/mips32-dsp/shrav_r_w.c new file mode 100644 index 000000000..2ab03bb5d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shrav_r_w.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x03; + rt = 0x87654321; + result = 0xF0ECA864; + + __asm + ("shrav_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + rs = 0x00; + rt = 0x40000000; + result = 0x40000000; + + __asm + ("shrav_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + assert(rd == result); + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrl_qb.c b/qemu/tests/tcg/mips/mips32-dsp/shrl_qb.c new file mode 100644 index 000000000..a7e4e6a5e --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shrl_qb.c @@ -0,0 +1,31 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x12345678; + result = 0x00010203; + + __asm + ("shrl.qb %0, %1, 0x05\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x12345678; + result = 0x12345678; + + __asm + ("shrl.qb %0, %1, 0x0\n\t" + : "=r"(rd) + : "r"(rt) + ); + + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/shrlv_qb.c b/qemu/tests/tcg/mips/mips32-dsp/shrlv_qb.c new file mode 100644 index 000000000..db77f6d0e --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/shrlv_qb.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x05; + rt = 0x12345678; + result = 0x00010203; + + __asm + ("shrlv.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + rs = 0x00; + rt = 0x12345678; + result = 0x12345678; + + __asm + ("shrlv.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/subq_ph.c b/qemu/tests/tcg/mips/mips32-dsp/subq_ph.c new file mode 100644 index 000000000..fdd7b38b6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/subq_ph.c @@ -0,0 +1,40 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x77777777; + rt = 0x67654321; + result = 0x10123456; + resultdsp = 0x0; + + __asm + ("subq.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x12345678; + rt = 0x87654321; + result = 0x8ACF1357; + resultdsp = 0x01; + + __asm + ("subq.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/subq_s_ph.c b/qemu/tests/tcg/mips/mips32-dsp/subq_s_ph.c new file mode 100644 index 000000000..64c89ebd5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/subq_s_ph.c @@ -0,0 +1,58 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x7FFF1357; + resultdsp = 0x01; + + __asm + ("wrdsp $0\n\t" + "subq_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x12348000; + rt = 0x87657000; + result = 0x7FFF8000; + resultdsp = 0x01; + + __asm + ("wrdsp $0\n\t" + "subq_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x12340000; + rt = 0x87658000; + result = 0x7FFF7FFF; + resultdsp = 0x01; + + __asm + ("wrdsp $0\n\t" + "subq_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/subq_s_w.c b/qemu/tests/tcg/mips/mips32-dsp/subq_s_w.c new file mode 100644 index 000000000..9d456a90f --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/subq_s_w.c @@ -0,0 +1,74 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x7FFFFFFF; + resultdsp = 0x01; + + __asm + ("wrdsp $0\n\t" + "subq_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x66666; + rt = 0x55555; + result = 0x11111; + resultdsp = 0x0; + + __asm + ("wrdsp $0\n\t" + "subq_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x0; + rt = 0x80000000; + result = 0x7FFFFFFF; + resultdsp = 0x01; + + __asm + ("wrdsp $0\n\t" + "subq_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x80000000; + rt = 0x80000000; + result = 0; + resultdsp = 0x00; + + __asm + ("wrdsp $0\n\t" + "subq_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/subu_qb.c b/qemu/tests/tcg/mips/mips32-dsp/subu_qb.c new file mode 100644 index 000000000..420909615 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/subu_qb.c @@ -0,0 +1,25 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x8BCF1357; + resultdsp = 0x01; + + __asm + ("subu.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/subu_s_qb.c b/qemu/tests/tcg/mips/mips32-dsp/subu_s_qb.c new file mode 100644 index 000000000..3d650533d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/subu_s_qb.c @@ -0,0 +1,25 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x00001357; + resultdsp = 0x01; + + __asm + ("subu_s.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dsp/wrdsp.c b/qemu/tests/tcg/mips/mips32-dsp/wrdsp.c new file mode 100644 index 000000000..dc54943a9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dsp/wrdsp.c @@ -0,0 +1,46 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int dsp_i, dsp_o; + int ccond_i, outflag_i, efi_i, c_i, scount_i, pos_i; + int ccond_o, outflag_o, efi_o, c_o, scount_o, pos_o; + + ccond_i = 0x000000BC; /* 4 */ + outflag_i = 0x0000001B; /* 3 */ + efi_i = 0x00000001; /* 5 */ + c_i = 0x00000001; /* 2 */ + scount_i = 0x0000000F; /* 1 */ + pos_i = 0x0000000C; /* 0 */ + + dsp_i = (ccond_i << 24) | \ + (outflag_i << 16) | \ + (efi_i << 14) | \ + (c_i << 13) | \ + (scount_i << 7) | \ + pos_i; + + __asm + ("wrdsp %1, 0x3F\n\t" + "rddsp %0, 0x3F\n\t" + : "=r"(dsp_o) + : "r"(dsp_i) + ); + + ccond_o = (dsp_o >> 24) & 0xFF; + outflag_o = (dsp_o >> 16) & 0xFF; + efi_o = (dsp_o >> 14) & 0x01; + c_o = (dsp_o >> 14) & 0x01; + scount_o = (dsp_o >> 7) & 0x3F; + pos_o = dsp_o & 0x1F; + + assert(ccond_o == (ccond_i & 0x0F)); + assert(outflag_o == outflag_i); + assert(efi_o == efi_i); + assert(c_o == c_i); + assert(scount_o == scount_i); + assert(pos_o == pos_i); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/Makefile b/qemu/tests/tcg/mips/mips32-dspr2/Makefile new file mode 100644 index 000000000..ed19581c7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/Makefile @@ -0,0 +1,71 @@ +-include ../../config-host.mak + +CROSS=mips64el-unknown-linux-gnu- + +SIM=qemu-mipsel +SIM_FLAGS=-cpu 74Kf + +CC = $(CROSS)gcc +CFLAGS = -mabi=32 -march=mips32r2 -mgp32 -mdspr2 -static + +TESTCASES = absq_s_qb.tst +TESTCASES += addqh_ph.tst +TESTCASES += addqh_r_ph.tst +TESTCASES += addqh_r_w.tst +TESTCASES += addqh_w.tst +TESTCASES += adduh_qb.tst +TESTCASES += adduh_r_qb.tst +TESTCASES += addu_ph.tst +TESTCASES += addu_s_ph.tst +TESTCASES += append.tst +TESTCASES += balign.tst +TESTCASES += cmpgdu_eq_qb.tst +TESTCASES += cmpgdu_le_qb.tst +TESTCASES += cmpgdu_lt_qb.tst +TESTCASES += dpaqx_sa_w_ph.tst +TESTCASES += dpa_w_ph.tst +TESTCASES += dpax_w_ph.tst +TESTCASES += dpaqx_s_w_ph.tst +TESTCASES += dpsqx_sa_w_ph.tst +TESTCASES += dpsqx_s_w_ph.tst +TESTCASES += dps_w_ph.tst +TESTCASES += dpsx_w_ph.tst +TESTCASES += mul_ph.tst +TESTCASES += mulq_rs_w.tst +TESTCASES += mulq_s_ph.tst +TESTCASES += mulq_s_w.tst +TESTCASES += mulsaq_s_w_ph.tst +TESTCASES += mulsa_w_ph.tst +TESTCASES += mul_s_ph.tst +TESTCASES += precr_qb_ph.tst +TESTCASES += precr_sra_ph_w.tst +TESTCASES += precr_sra_r_ph_w.tst +TESTCASES += prepend.tst +TESTCASES += shra_qb.tst +TESTCASES += shra_r_qb.tst +TESTCASES += shrav_qb.tst +TESTCASES += shrav_r_qb.tst +TESTCASES += shrl_ph.tst +TESTCASES += shrlv_ph.tst +TESTCASES += subqh_ph.tst +TESTCASES += subqh_r_ph.tst +TESTCASES += subqh_r_w.tst +TESTCASES += subqh_w.tst +TESTCASES += subuh_qb.tst +TESTCASES += subuh_r_qb.tst +TESTCASES += subu_ph.tst +TESTCASES += subu_s_ph.tst + +all: $(TESTCASES) + +%.tst: %.c + $(CC) $(CFLAGS) $< -o $@ + +check: $(TESTCASES) + @for case in $(TESTCASES); do \ + echo $(SIM) $(SIM_FLAGS) ./$$case;\ + $(SIM) $(SIM_FLAGS) ./$$case; \ + done + +clean: + $(RM) -rf $(TESTCASES) diff --git a/qemu/tests/tcg/mips/mips32-dspr2/absq_s_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/absq_s_qb.c new file mode 100644 index 000000000..af4683f30 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/absq_s_qb.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int input, result, dsp; + int hope; + + input = 0x701BA35E; + hope = 0x701B5D5E; + + __asm + ("absq_s.qb %0, %1\n\t" + : "=r"(result) + : "r"(input) + ); + assert(result == hope); + + + input = 0x801BA35E; + hope = 0x7F1B5D5E; + + __asm + ("absq_s.qb %0, %2\n\t" + "rddsp %1\n\t" + : "=r"(result), "=r"(dsp) + : "r"(input) + ); + dsp = dsp >> 20; + dsp &= 0x01; + assert(dsp == 1); + assert(result == hope); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/addqh_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/addqh_ph.c new file mode 100644 index 000000000..921f0eaf3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/addqh_ph.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x706A13FE; + rt = 0x13065174; + result = 0x41B832B9; + __asm + ("addqh.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0x81000100; + rt = 0xc2000100; + result = 0xa1800100; + __asm + ("addqh.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/addqh_r_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/addqh_r_ph.c new file mode 100644 index 000000000..213ba3725 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/addqh_r_ph.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x706A13FE; + rt = 0x13065174; + result = 0x41B832B9; + __asm + ("addqh_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0x81010100; + rt = 0xc2000100; + result = 0xa1810100; + __asm + ("addqh_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/addqh_r_w.c b/qemu/tests/tcg/mips/mips32-dspr2/addqh_r_w.c new file mode 100644 index 000000000..75a75c50f --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/addqh_r_w.c @@ -0,0 +1,34 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x00000010; + rt = 0x00000001; + result = 0x00000009; + + __asm + ("addqh_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + assert(rd == result); + + rs = 0xFFFFFFFE; + rt = 0x00000001; + result = 0x00000000; + + __asm + ("addqh_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/addqh_w.c b/qemu/tests/tcg/mips/mips32-dspr2/addqh_w.c new file mode 100644 index 000000000..de6926ebb --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/addqh_w.c @@ -0,0 +1,34 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x00000010; + rt = 0x00000001; + result = 0x00000008; + + __asm + ("addqh.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + assert(rd == result); + + rs = 0xFFFFFFFE; + rt = 0x00000001; + result = 0xFFFFFFFF; + + __asm + ("addqh.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/addu_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/addu_ph.c new file mode 100644 index 000000000..1d7a25a2a --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/addu_ph.c @@ -0,0 +1,33 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x00FF00FF; + rt = 0x00010001; + result = 0x01000100; + __asm + ("addu.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0xFFFF1111; + rt = 0x00020001; + result = 0x00011112; + __asm + ("addu.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + assert(((dsp >> 20) & 0x01) == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/addu_s_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/addu_s_ph.c new file mode 100644 index 000000000..979651bfc --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/addu_s_ph.c @@ -0,0 +1,33 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x00FE00FE; + rt = 0x00020001; + result = 0x010000FF; + __asm + ("addu_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0xFFFF1111; + rt = 0x00020001; + result = 0xFFFF1112; + __asm + ("addu_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + assert(((dsp >> 20) & 0x01) == 1); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/adduh_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/adduh_qb.c new file mode 100644 index 000000000..a1f5d631b --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/adduh_qb.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0xFF0055AA; + rt = 0x0113421B; + result = 0x80094B62; + __asm + ("adduh.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x7F800888; + __asm + ("adduh.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/adduh_r_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/adduh_r_qb.c new file mode 100644 index 000000000..81e98c190 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/adduh_r_qb.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0xFF0055AA; + rt = 0x01112211; + result = 0x80093C5E; + __asm + ("adduh_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x80800888; + __asm + ("adduh_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/append.c b/qemu/tests/tcg/mips/mips32-dspr2/append.c new file mode 100644 index 000000000..9a91e1650 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/append.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int result; + + rs = 0xFF0055AA; + rt = 0x0113421B; + result = 0x02268436; + __asm + ("append %0, %1, 0x01\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(rt == result); + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x0010111F; + __asm + ("append %0, %1, 0x04\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(rt == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/balign.c b/qemu/tests/tcg/mips/mips32-dspr2/balign.c new file mode 100644 index 000000000..537cf0451 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/balign.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int result; + + rs = 0xFF0055AA; + rt = 0x0113421B; + result = 0x13421BFF; + __asm + ("balign %0, %1, 0x01\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(rt == result); + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x11FFFF0F; + __asm + ("balign %0, %1, 0x03\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(rt == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c new file mode 100644 index 000000000..2d6340d6f --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c @@ -0,0 +1,37 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x02; + __asm + ("cmpgdu.eq.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(rd == result); + assert(dsp == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x0F; + __asm + ("cmpgdu.eq.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(rd == result); + assert(dsp == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c new file mode 100644 index 000000000..a0ecdca2a --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c @@ -0,0 +1,37 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0F; + __asm + ("cmpgdu.le.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(rd == result); + assert(dsp == result); + + rs = 0x11777066; + rt = 0x11707066; + result = 0x0B; + __asm + ("cmpgdu.le.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(rd == result); + assert(dsp == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c new file mode 100644 index 000000000..dba99e392 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c @@ -0,0 +1,37 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0D; + __asm + ("cmpgdu.lt.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(rd == result); + assert(dsp == result); + + rs = 0x11777066; + rt = 0x11777066; + result = 0x00; + __asm + ("cmpgdu.lt.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + assert(rd == result); + assert(dsp == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/dpa_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/dpa_w_ph.c new file mode 100644 index 000000000..fae49f10e --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/dpa_w_ph.c @@ -0,0 +1,44 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 5; + int resulth, resultl; + + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x05; + resultl = 0x0302; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpa.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + ach = 6, acl = 7; + rs = 0xFFFF00FF; + rt = 0xFFFF0002; + resulth = 0x06; + resultl = 0x206; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpa.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c new file mode 100644 index 000000000..ce8783024 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c @@ -0,0 +1,79 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, dsp; + int ach = 5, acl = 5; + int resulth, resultl, resultdsp; + + rs = 0x800000FF; + rt = 0x00018000; + resulth = 0x05; + resultl = 0x80000202; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 5; + acl = 5; + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x05; + resultl = 0x05FF; + /*********************************************************** + * Because of we set outflag at last time, although this + * time we set nothing, but it is stay the last time value. + **********************************************************/ + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 5; + acl = 5; + rs = 0x800000FF; + rt = 0x00028000; + resulth = 0x05; + resultl = 0x80000400; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c new file mode 100644 index 000000000..d551d64ae --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c @@ -0,0 +1,57 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, dsp; + int ach, acl; + int resulth, resultl, resultdsp; + + ach = 0x00000005; + acl = 0x00000005; + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x00; + resultl = 0x7FFFFFFF; + resultdsp = 0x01; + dsp = 0; + __asm + ("wrdsp %2\n\t" + "mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_sa.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "+r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(dsp >> (16 + 1) == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x00000009; + acl = 0x0000000B; + rs = 0x800000FF; + rt = 0x00018000; + resulth = 0x00; + resultl = 0x7FFFFFFF; + resultdsp = 0x01; + dsp = 0; + __asm + ("wrdsp %2\n\t" + "mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_sa.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "+r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(dsp >> (16 + 1) == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/dpax_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/dpax_w_ph.c new file mode 100644 index 000000000..514797cfd --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/dpax_w_ph.c @@ -0,0 +1,44 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 5; + int resulth, resultl; + + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x05; + resultl = 0x0302; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpax.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + ach = 6, acl = 7; + rs = 0xFFFF00FF; + rt = 0xFFFF0002; + resulth = 0x05; + resultl = 0xFFFFFF06; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpax.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/dps_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/dps_w_ph.c new file mode 100644 index 000000000..f51f9b9d1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/dps_w_ph.c @@ -0,0 +1,44 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 5; + int resulth, resultl; + + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x04; + resultl = 0xFFFFFD08; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dps.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + ach = 6, acl = 7; + rs = 0xFFFF00FF; + rt = 0xFFFF0002; + resulth = 0x05; + resultl = 0xFFFFFE08; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dps.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c new file mode 100644 index 000000000..e40543fd8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c @@ -0,0 +1,54 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, dsp; + int ach = 5, acl = 5; + int resulth, resultl, resultdsp; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x00000005; + resultl = 0x1CE5E09B; + resultdsp = 0x00; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x99F13005; + acl = 0x51730062; + rs = 0x80008000; + rt = 0x80008000; + + resulth = 0x99F13004; + resultl = 0x51730064; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c new file mode 100644 index 000000000..7da278eac --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c @@ -0,0 +1,53 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, dsp; + int ach = 5, acl = 5; + int resulth, resultl, resultdsp; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x00; + resultl = 0x7FFFFFFF; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsqx_sa.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x8c0b354A; + acl = 0xbbc02249; + rs = 0x800023AD; + rt = 0x01648000; + resulth = 0xffffffff; + resultl = 0x80000000; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsqx_sa.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c new file mode 100644 index 000000000..bb49a4031 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c @@ -0,0 +1,27 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int ach = 5, acl = 5; + int resulth, resultl; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x05; + resultl = 0xE72F050; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsx.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/mul_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/mul_ph.c new file mode 100644 index 000000000..c7e9d60d1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/mul_ph.c @@ -0,0 +1,47 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x03FB1234; + rt = 0x0BCC4321; + result = 0xF504F4B4; + resultdsp = 1; + + __asm + ("mul.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 0x00210010; + rt = 0x00110005; + result = 0x2310050; + resultdsp = 0; + + __asm + ("mul.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/mul_s_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/mul_s_ph.c new file mode 100644 index 000000000..33da110de --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/mul_s_ph.c @@ -0,0 +1,62 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x03FB1234; + rt = 0x0BCC4321; + result = 0x7fff7FFF; + resultdsp = 1; + + __asm + ("mul_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + rs = 0x7fffff00; + rt = 0xff007fff; + result = 0x80008000; + resultdsp = 1; + + __asm + ("mul_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 0x00320001; + rt = 0x00210002; + result = 0x06720002; + resultdsp = 0; + + __asm + ("mul_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/mulq_rs_w.c b/qemu/tests/tcg/mips/mips32-dspr2/mulq_rs_w.c new file mode 100644 index 000000000..7ba633bc1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/mulq_rs_w.c @@ -0,0 +1,36 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0x7FFFAAAB; + + __asm + ("mulq_rs.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0x80000000; + rt = 0x80000000; + result = 0x7FFFFFFF; + resultdsp = 1; + + __asm + ("mulq_rs.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/mulq_s_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/mulq_s_ph.c new file mode 100644 index 000000000..00e015542 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/mulq_s_ph.c @@ -0,0 +1,40 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x80000000; + rt = 0x0ffc0000; + result = 0xF0040000; + resultdsp = 0; + + __asm + ("mulq_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + rs = 0x80001234; + rt = 0x80004321; + result = 0x7FFF098B; + resultdsp = 1; + + __asm + ("mulq_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/mulq_s_w.c b/qemu/tests/tcg/mips/mips32-dspr2/mulq_s_w.c new file mode 100644 index 000000000..9c2be06cc --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/mulq_s_w.c @@ -0,0 +1,36 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0x7FFFAAAB; + + __asm + ("mulq_s.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0x80000000; + rt = 0x80000000; + result = 0x7FFFFFFF; + resultdsp = 1; + + __asm + ("mulq_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c new file mode 100644 index 000000000..a6940939c --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c @@ -0,0 +1,29 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, ach, acl; + int resulth, resultl; + + ach = 0x05; + acl = 0x00BBDDCC; + rs = 0x80001234; + rt = 0x80004321; + resulth = 0x05; + resultl = 0x3BF5E918; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "mulsa.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c new file mode 100644 index 000000000..06c91a43e --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c @@ -0,0 +1,29 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt, ach, acl; + int resulth, resultl; + + ach = 0x05; + acl = 0x00BBDDCC; + rs = 0x80001234; + rt = 0x80004321; + resulth = 0x05; + resultl = 0x772ff463; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "mulsaq_s.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + assert(ach == resulth); + assert(acl == resultl); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/precr_qb_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/precr_qb_ph.c new file mode 100644 index 000000000..3a2b3fde0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/precr_qb_ph.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x34786521; + + __asm + ("precr.qb.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(result == rd); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c b/qemu/tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c new file mode 100644 index 000000000..5c9baab03 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x43215678; + + __asm + ("precr_sra.ph.w %0, %1, 0x00\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(result == rt); + + rs = 0x12345678; + rt = 0x87654321; + result = 0xFFFF0000; + + __asm + ("precr_sra.ph.w %0, %1, 0x1F\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c b/qemu/tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c new file mode 100644 index 000000000..6474a108c --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x43215678; + + __asm + ("precr_sra_r.ph.w %0, %1, 0x00\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(result == rt); + + rs = 0x12345678; + rt = 0x87654321; + result = 0xFFFF0000; + + __asm + ("precr_sra_r.ph.w %0, %1, 0x1F\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(result == rt); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/prepend.c b/qemu/tests/tcg/mips/mips32-dspr2/prepend.c new file mode 100644 index 000000000..f6bcd47b2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/prepend.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x87654321; + __asm + ("prepend %0, %1, 0x00\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(rt == result); + + rs = 0x12345678; + rt = 0x87654321; + result = 0xACF10ECA; + __asm + ("prepend %0, %1, 0x0F\n\t" + : "+r"(rt) + : "r"(rs) + ); + assert(rt == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/shra_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/shra_qb.c new file mode 100644 index 000000000..48193de87 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/shra_qb.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x12345678; + result = 0x02060A0F; + + __asm + ("shra.qb %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x87654321; + result = 0xF00C0804; + + __asm + ("shra.qb %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/shra_r_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/shra_r_qb.c new file mode 100644 index 000000000..29afa0e4b --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/shra_r_qb.c @@ -0,0 +1,30 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x12345678; + result = 0x02070B0F; + + __asm + ("shra_r.qb %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + rt = 0x87654321; + result = 0xF10D0804; + + __asm + ("shra_r.qb %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/shrav_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/shrav_qb.c new file mode 100644 index 000000000..b21e1b7ca --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/shrav_qb.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x03; + rt = 0x12345678; + result = 0x02060A0F; + + __asm + ("shrav.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + rs = 0x03; + rt = 0x87654321; + result = 0xF00C0804; + + __asm + ("shrav.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/shrav_r_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/shrav_r_qb.c new file mode 100644 index 000000000..9ea8aa0cb --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/shrav_r_qb.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x03; + rt = 0x12345678; + result = 0x02070B0F; + + __asm + ("shrav_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + rs = 0x03; + rt = 0x87654321; + result = 0xF10D0804; + + __asm + ("shrav_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/shrl_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/shrl_ph.c new file mode 100644 index 000000000..724b9a7a4 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/shrl_ph.c @@ -0,0 +1,20 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt; + int result; + + rt = 0x12345678; + result = 0x009102B3; + + __asm + ("shrl.ph %0, %1, 0x05\n\t" + : "=r"(rd) + : "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/shrlv_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/shrlv_ph.c new file mode 100644 index 000000000..ac79aa69a --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/shrlv_ph.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x05; + rt = 0x12345678; + result = 0x009102B3; + + __asm + ("shrlv.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/subqh_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/subqh_ph.c new file mode 100644 index 000000000..dbc096734 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/subqh_ph.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x456709AB; + + __asm + ("subqh.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/subqh_r_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/subqh_r_ph.c new file mode 100644 index 000000000..24ef0f1ae --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/subqh_r_ph.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x456809AC; + + __asm + ("subqh_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/subqh_r_w.c b/qemu/tests/tcg/mips/mips32-dspr2/subqh_r_w.c new file mode 100644 index 000000000..d460f8630 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/subqh_r_w.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x456789AC; + + __asm + ("subqh_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/subqh_w.c b/qemu/tests/tcg/mips/mips32-dspr2/subqh_w.c new file mode 100644 index 000000000..42be3deb8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/subqh_w.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x456789AB; + + __asm + ("subqh.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/subu_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/subu_ph.c new file mode 100644 index 000000000..0d39a017c --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/subu_ph.c @@ -0,0 +1,40 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x87654321; + rt = 0x11111111; + result = 0x76543210; + resultdsp = 0x00; + + __asm + ("subu.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x87654321; + rt = 0x12345678; + result = 0x7531ECA9; + resultdsp = 0x01; + + __asm + ("subu.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/subu_s_ph.c b/qemu/tests/tcg/mips/mips32-dspr2/subu_s_ph.c new file mode 100644 index 000000000..8e4da4f3e --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/subu_s_ph.c @@ -0,0 +1,25 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt, dsp; + int result, resultdsp; + + rs = 0x87654321; + rt = 0x12345678; + result = 0x75310000; + resultdsp = 0x01; + + __asm + ("subu_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + assert(dsp == resultdsp); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/subuh_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/subuh_qb.c new file mode 100644 index 000000000..92cfc764b --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/subuh_qb.c @@ -0,0 +1,21 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0xC5E7092B; + + __asm + ("subuh.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips32-dspr2/subuh_r_qb.c b/qemu/tests/tcg/mips/mips32-dspr2/subuh_r_qb.c new file mode 100644 index 000000000..dac81d47d --- /dev/null +++ b/qemu/tests/tcg/mips/mips32-dspr2/subuh_r_qb.c @@ -0,0 +1,32 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0xC6E80A2C; + + __asm + ("subuh_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + rs = 0xBEFC292A; + rt = 0x9205C1B4; + result = 0x167cb4bb; + + __asm + ("subuh_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + assert(rd == result); + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/Makefile b/qemu/tests/tcg/mips/mips64-dsp/Makefile new file mode 100644 index 000000000..b2ac6b3ff --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/Makefile @@ -0,0 +1,306 @@ + +CROSS_COMPILE ?= mips64el-unknown-linux-gnu- + +SIM = qemu-system-mips64el +SIMFLAGS = -nographic -cpu mips64dspr2 -kernel + +AS = $(CROSS_COMPILE)as +LD = $(CROSS_COMPILE)ld +CC = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar +NM = $(CROSS_COMPILE)nm +STRIP = $(CROSS_COMPILE)strip +RANLIB = $(CROSS_COMPILE)ranlib +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump + +VECTORS_OBJ ?= ./head.o ./printf.o + +HEAD_FLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe \ + -msoft-float -march=mips64 -Wa,-mips64 -Wa,--trap \ + -msym32 -DKBUILD_64BIT_SYM32 -I./ + +CFLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -fno-builtin \ + -pipe -march=mips64r2 -mgp64 -mdsp -static -Wa,--trap -msym32 \ + -DKBUILD_64BIT_SYM32 -I./ + +LDFLAGS = -T./mips_boot.lds -L./ +FLAGS = -nostdlib -mabi=64 -march=mips64r2 -mgp64 -mdsp + + +#TESTCASES = absq_s_ob.tst +TESTCASES = absq_s_ph.tst +TESTCASES += absq_s_pw.tst +TESTCASES += absq_s_qh.tst +TESTCASES += absq_s_w.tst +TESTCASES += addq_ph.tst +TESTCASES += addq_pw.tst +TESTCASES += addq_qh.tst +TESTCASES += addq_s_ph.tst +TESTCASES += addq_s_pw.tst +TESTCASES += addq_s_qh.tst +TESTCASES += addq_s_w.tst +TESTCASES += addsc.tst +TESTCASES += addu_ob.tst +TESTCASES += addu_qb.tst +TESTCASES += addu_s_ob.tst +TESTCASES += addu_s_qb.tst +TESTCASES += addwc.tst +TESTCASES += bitrev.tst +TESTCASES += bposge32.tst +TESTCASES += bposge64.tst +TESTCASES += cmp_eq_ph.tst +TESTCASES += cmp_eq_pw.tst +TESTCASES += cmp_eq_qh.tst +TESTCASES += cmpgu_eq_ob.tst +TESTCASES += cmpgu_eq_qb.tst +TESTCASES += cmpgu_le_ob.tst +TESTCASES += cmpgu_le_qb.tst +TESTCASES += cmpgu_lt_ob.tst +TESTCASES += cmpgu_lt_qb.tst +TESTCASES += cmp_le_ph.tst +TESTCASES += cmp_le_pw.tst +TESTCASES += cmp_le_qh.tst +TESTCASES += cmp_lt_ph.tst +TESTCASES += cmp_lt_pw.tst +TESTCASES += cmp_lt_qh.tst +TESTCASES += cmpu_eq_ob.tst +TESTCASES += cmpu_eq_qb.tst +TESTCASES += cmpu_le_ob.tst +TESTCASES += cmpu_le_qb.tst +TESTCASES += cmpu_lt_ob.tst +TESTCASES += cmpu_lt_qb.tst +#TESTCASES += dappend.tst +TESTCASES += dextp.tst +TESTCASES += dextpdp.tst +TESTCASES += dextpdpv.tst +TESTCASES += dextpv.tst +TESTCASES += dextr_l.tst +TESTCASES += dextr_r_l.tst +TESTCASES += dextr_rs_l.tst +TESTCASES += dextr_rs_w.tst +TESTCASES += dextr_r_w.tst +TESTCASES += dextr_s_h.tst +TESTCASES += dextrv_l.tst +TESTCASES += dextrv_r_l.tst +TESTCASES += dextrv_rs_l.tst +TESTCASES += dextrv_rs_w.tst +TESTCASES += dextrv_r_w.tst +TESTCASES += dextrv_s_h.tst +TESTCASES += dextrv_w.tst +TESTCASES += dextr_w.tst +TESTCASES += dinsv.tst +TESTCASES += dmadd.tst +TESTCASES += dmaddu.tst +TESTCASES += dmsub.tst +TESTCASES += dmsubu.tst +TESTCASES += dmthlip.tst +TESTCASES += dpaq_sa_l_pw.tst +TESTCASES += dpaq_sa_l_w.tst +TESTCASES += dpaq_s_w_ph.tst +TESTCASES += dpaq_s_w_qh.tst +TESTCASES += dpau_h_obl.tst +TESTCASES += dpau_h_obr.tst +TESTCASES += dpau_h_qbl.tst +TESTCASES += dpau_h_qbr.tst +TESTCASES += dpsq_sa_l_pw.tst +TESTCASES += dpsq_sa_l_w.tst +TESTCASES += dpsq_s_w_ph.tst +TESTCASES += dpsq_s_w_qh.tst +TESTCASES += dpsu_h_obl.tst +TESTCASES += dpsu_h_obr.tst +TESTCASES += dpsu_h_qbl.tst +TESTCASES += dpsu_h_qbr.tst +TESTCASES += dshilo.tst +TESTCASES += dshilov.tst +TESTCASES += extp.tst +TESTCASES += extpdp.tst +TESTCASES += extpdpv.tst +TESTCASES += extpv.tst +TESTCASES += extr_rs_w.tst +TESTCASES += extr_r_w.tst +TESTCASES += extr_s_h.tst +TESTCASES += extrv_rs_w.tst +TESTCASES += extrv_r_w.tst +TESTCASES += extrv_s_h.tst +TESTCASES += extrv_w.tst +TESTCASES += extr_w.tst +TESTCASES += insv.tst +TESTCASES += lbux.tst +TESTCASES += lhx.tst +TESTCASES += lwx.tst +TESTCASES += ldx.tst +TESTCASES += madd.tst +TESTCASES += maddu.tst +TESTCASES += maq_sa_w_phl.tst +TESTCASES += maq_sa_w_phr.tst +TESTCASES += maq_sa_w_qhll.tst +TESTCASES += maq_sa_w_qhlr.tst +TESTCASES += maq_sa_w_qhrl.tst +TESTCASES += maq_sa_w_qhrr.tst +TESTCASES += maq_s_l_pwl.tst +TESTCASES += maq_s_l_pwr.tst +TESTCASES += maq_s_w_phl.tst +TESTCASES += maq_s_w_phr.tst +TESTCASES += maq_s_w_qhll.tst +TESTCASES += maq_s_w_qhlr.tst +TESTCASES += maq_s_w_qhrl.tst +TESTCASES += maq_s_w_qhrr.tst +TESTCASES += mfhi.tst +TESTCASES += mflo.tst +TESTCASES += modsub.tst +TESTCASES += msub.tst +TESTCASES += msubu.tst +TESTCASES += mthi.tst +TESTCASES += mthlip.tst +TESTCASES += mtlo.tst +TESTCASES += muleq_s_pw_qhl.tst +TESTCASES += muleq_s_pw_qhr.tst +TESTCASES += muleq_s_w_phl.tst +TESTCASES += muleq_s_w_phr.tst +TESTCASES += muleu_s_ph_qbl.tst +TESTCASES += muleu_s_ph_qbr.tst +TESTCASES += muleu_s_qh_obl.tst +TESTCASES += muleu_s_qh_obr.tst +TESTCASES += mulq_rs_ph.tst +TESTCASES += mulq_rs_qh.tst +TESTCASES += mulsaq_s_l_pw.tst +TESTCASES += mulsaq_s_w_qh.tst +TESTCASES += mult.tst +TESTCASES += multu.tst +TESTCASES += packrl_ph.tst +TESTCASES += packrl_pw.tst +TESTCASES += pick_ob.tst +TESTCASES += pick_ph.tst +TESTCASES += pick_pw.tst +TESTCASES += pick_qb.tst +TESTCASES += pick_qh.tst +#TESTCASES += preceq_l_pwl.tst +#TESTCASES += preceq_l_pwr.tst +TESTCASES += preceq_pw_qhla.tst +TESTCASES += preceq_pw_qhl.tst +TESTCASES += preceq_pw_qhra.tst +TESTCASES += preceq_pw_qhr.tst +TESTCASES += precequ_ph_qbla.tst +TESTCASES += precequ_ph_qbl.tst +TESTCASES += precequ_ph_qbra.tst +TESTCASES += precequ_ph_qbr.tst +#TESTCASES += precequ_qh_obla.tst +#TESTCASES += precequ_qh_obl.tst +#TESTCASES += precequ_qh_obra.tst +#TESTCASES += precequ_qh_obr.tst +TESTCASES += preceq_w_phl.tst +TESTCASES += preceq_w_phr.tst +TESTCASES += preceu_ph_qbla.tst +TESTCASES += preceu_ph_qbl.tst +TESTCASES += preceu_ph_qbra.tst +TESTCASES += preceu_ph_qbr.tst +TESTCASES += preceu_qh_obla.tst +TESTCASES += preceu_qh_obl.tst +TESTCASES += preceu_qh_obra.tst +TESTCASES += preceu_qh_obr.tst +#TESTCASES += precr_ob_qh.tst +TESTCASES += precrq_ob_qh.tst +TESTCASES += precrq_ph_w.tst +TESTCASES += precrq_pw_l.tst +TESTCASES += precrq_qb_ph.tst +TESTCASES += precrq_qh_pw.tst +TESTCASES += precrq_rs_ph_w.tst +TESTCASES += precrq_rs_qh_pw.tst +TESTCASES += precrqu_s_ob_qh.tst +TESTCASES += precrqu_s_qb_ph.tst +#TESTCASES += precr_sra_qh_pw.tst +#TESTCASES += precr_sra_r_qh_pw.tst +#TESTCASES += prependd.tst +#TESTCASES += prependw.tst +#TESTCASES += raddu_l_ob.tst +TESTCASES += raddu_w_qb.tst +TESTCASES += rddsp.tst +TESTCASES += repl_ob.tst +TESTCASES += repl_ph.tst +TESTCASES += repl_pw.tst +TESTCASES += repl_qb.tst +TESTCASES += repl_qh.tst +TESTCASES += replv_ob.tst +TESTCASES += replv_ph.tst +TESTCASES += replv_pw.tst +TESTCASES += replv_qb.tst +TESTCASES += shilo.tst +TESTCASES += shilov.tst +TESTCASES += shll_ob.tst +TESTCASES += shll_ph.tst +TESTCASES += shll_pw.tst +TESTCASES += shll_qb.tst +TESTCASES += shll_qh.tst +TESTCASES += shll_s_ph.tst +TESTCASES += shll_s_pw.tst +TESTCASES += shll_s_qh.tst +TESTCASES += shll_s_w.tst +TESTCASES += shllv_ob.tst +TESTCASES += shllv_ph.tst +TESTCASES += shllv_pw.tst +TESTCASES += shllv_qb.tst +TESTCASES += shllv_qh.tst +TESTCASES += shllv_s_ph.tst +TESTCASES += shllv_s_pw.tst +TESTCASES += shllv_s_qh.tst +TESTCASES += shllv_s_w.tst +#TESTCASES += shra_ob.tst +TESTCASES += shra_ph.tst +TESTCASES += shra_pw.tst +TESTCASES += shra_qh.tst +#TESTCASES += shra_r_ob.tst +TESTCASES += shra_r_ph.tst +TESTCASES += shra_r_pw.tst +TESTCASES += shra_r_qh.tst +TESTCASES += shra_r_w.tst +TESTCASES += shrav_ph.tst +TESTCASES += shrav_pw.tst +TESTCASES += shrav_qh.tst +TESTCASES += shrav_r_ph.tst +TESTCASES += shrav_r_pw.tst +TESTCASES += shrav_r_qh.tst +TESTCASES += shrav_r_w.tst +TESTCASES += shrl_ob.tst +TESTCASES += shrl_qb.tst +#TESTCASES += shrl_qh.tst +TESTCASES += shrlv_ob.tst +TESTCASES += shrlv_qb.tst +#TESTCASES += shrlv_qh.tst +TESTCASES += subq_ph.tst +TESTCASES += subq_pw.tst +TESTCASES += subq_qh.tst +TESTCASES += subq_s_ph.tst +TESTCASES += subq_s_pw.tst +TESTCASES += subq_s_qh.tst +TESTCASES += subq_s_w.tst +TESTCASES += subu_ob.tst +TESTCASES += subu_qb.tst +TESTCASES += subu_s_ob.tst +TESTCASES += subu_s_qb.tst +TESTCASES += wrdsp.tst + +all: build + +head.o : head.S + $(Q)$(CC) $(HEAD_FLAGS) -D"STACK_TOP=0xffffffff80200000" -c $< -o $@ + +%.o : %.S + $(CC) $(CFLAGS) -c $< -o $@ + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +%.tst: %.o $(VECTORS_OBJ) + $(CC) $(VECTORS_OBJ) $(FLAGS) $(LDFLAGS) $< -o $@ + +build: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES) + +check: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES) + @for case in $(TESTCASES); do \ + echo $(SIM) $(SIMFLAGS) ./$$case; \ + $(SIM) $(SIMFLAGS) ./$$case & (sleep 1; killall $(SIM)); \ + done + +clean: + $(Q)rm -f *.o *.tst *.a diff --git a/qemu/tests/tcg/mips/mips64-dsp/absq_s_ob.c b/qemu/tests/tcg/mips/mips64-dsp/absq_s_ob.c new file mode 100644 index 000000000..621403157 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/absq_s_ob.c @@ -0,0 +1,63 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result, dspcontrol; + rt = 0x7F7F7F7F7F7F7F7F; + result = 0x7F7F7F7F7F7F7F7F; + + + __asm + (".set mips64\n\t" + "absq_s.ob %0 %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("absq_s.ob test 1 error\n"); + + return -1; + } + + __asm + ("rddsp %0\n\t" + : "=r"(rd) + ); + rd >> 20; + rd = rd & 0x1; + if (rd != 0) { + printf("absq_s.ob test 1 dspcontrol overflow flag error\n"); + + return -1; + } + + rt = 0x80FFFFFFFFFFFFFF; + result = 0x7F01010101010101; + + __asm + ("absq_s.ob %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("absq_s.ob test 2 error\n"); + + return -1; + } + + __asm + ("rddsp %0\n\t" + : "=r"(rd) + ); + rd = rd >> 20; + rd = rd & 0x1; + if (rd != 1) { + printf("absq_s.ob test 2 dspcontrol overflow flag error\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/absq_s_ph.c b/qemu/tests/tcg/mips/mips64-dsp/absq_s_ph.c new file mode 100644 index 000000000..238416d43 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/absq_s_ph.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x10017EFD; + result = 0x10017EFD; + + __asm + ("absq_s.ph %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("absq_s.ph wrong\n"); + + return -1; + } + + rt = 0x8000A536; + result = 0x7FFF5ACA; + + __asm + ("absq_s.ph %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("absq_s.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/absq_s_pw.c b/qemu/tests/tcg/mips/mips64-dsp/absq_s_pw.c new file mode 100644 index 000000000..48fc763b4 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/absq_s_pw.c @@ -0,0 +1,66 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result, dspcontrol; + rd = 0; + rt = 0x7F7F7F7F7F7F7F7F; + result = 0x7F7F7F7F7F7F7F7F; + + + __asm + ("absq_s.pw %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("absq_s.pw test 1 error\n"); + + return -1; + } + + rd = 0; + __asm + ("rddsp %0\n\t" + : "=r"(rd) + ); + rd >> 20; + rd = rd & 0x1; + if (rd != 0) { + printf("absq_s.pw test 1 dspcontrol overflow flag error\n"); + + return -1; + } + + rd = 0; + rt = 0x80000000FFFFFFFF; + result = 0x7FFFFFFF00000001; + + __asm + ("absq_s.pw %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("absq_s.pw test 2 error\n"); + + return -1; + } + + rd = 0; + __asm + ("rddsp %0\n\t" + : "=r"(rd) + ); + rd = rd >> 20; + rd = rd & 0x1; + if (rd != 1) { + printf("absq_s.pw test 2 dspcontrol overflow flag error\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/absq_s_qh.c b/qemu/tests/tcg/mips/mips64-dsp/absq_s_qh.c new file mode 100644 index 000000000..9001a9e16 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/absq_s_qh.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result, dspcontrol; + rd = 0; + rt = 0x7F7F7F7F7F7F7F7F; + result = 0x7F7F7F7F7F7F7F7F; + + + __asm + ("absq_s.qh %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("absq_s.qh test 1 error\n"); + + return -1; + } + + rd = 0; + rt = 0x8000FFFFFFFFFFFF; + result = 0x7FFF000100000001; + + __asm + ("absq_s.pw %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("absq_s.rw test 2 error\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/absq_s_w.c b/qemu/tests/tcg/mips/mips64-dsp/absq_s_w.c new file mode 100644 index 000000000..414c8bd3f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/absq_s_w.c @@ -0,0 +1,48 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x80000000; + result = 0x7FFFFFFF; + __asm + ("absq_s.w %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("absq_s_w.ph wrong\n"); + + return -1; + } + + rt = 0x80030000; + result = 0x7FFD0000; + __asm + ("absq_s.w %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("absq_s_w.ph wrong\n"); + + return -1; + } + + rt = 0x31036080; + result = 0x31036080; + __asm + ("absq_s.w %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("absq_s_w.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addq_ph.c b/qemu/tests/tcg/mips/mips64-dsp/addq_ph.c new file mode 100644 index 000000000..22a36d980 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addq_ph.c @@ -0,0 +1,57 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0xFFFFFFFF; + rt = 0x10101010; + result = 0x100F100F; + __asm + ("addq.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("1 addq.ph wrong\n"); + + return -1; + } + + rs = 0x3712847D; + rt = 0x0031AF2D; + result = 0x374333AA; + __asm + ("addq.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("2 addq.ph wrong\n"); + + return -1; + } + + rs = 0x7fff847D; + rt = 0x0031AF2D; + result = 0xffffffff803033AA; + __asm + ("addq.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + __asm("rddsp %0\n\t" + : "=r"(dsp) + ); + + if (rd != result || (((dsp >> 20) & 0x01) != 1)) { + printf("3 addq.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addq_pw.c b/qemu/tests/tcg/mips/mips64-dsp/addq_pw.c new file mode 100644 index 000000000..99a7668c0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addq_pw.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + + rs = 0x123456787FFFFFFF; + rt = 0x1111111100000101; + result = 0x2345678980000100; + dspresult = 0x1; + + __asm + ("addq.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("addq.pw error\n"); + + return -1; + } + + rs = 0x1234567880FFFFFF; + rt = 0x1111111180000001; + result = 0x2345678901000000; + dspresult = 0x1; + + __asm + ("addq.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("addq.pw error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addq_qh.c b/qemu/tests/tcg/mips/mips64-dsp/addq_qh.c new file mode 100644 index 000000000..4b874afb8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addq_qh.c @@ -0,0 +1,28 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + + rs = 0x123456787FFF8010; + rt = 0x1111111100018000; + result = 0x2345678980000010; + dspresult = 0x1; + + __asm + ("addq.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + + if ((rd != result) || (dspreg != dspresult)) { + printf("addq.qh error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addq_s_ph.c b/qemu/tests/tcg/mips/mips64-dsp/addq_s_ph.c new file mode 100644 index 000000000..ad84cdcfe --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addq_s_ph.c @@ -0,0 +1,84 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0xFFFFFFFF; + rt = 0x10101010; + result = 0x100F100F; + __asm + ("addq_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("1 addq_s.ph wrong\n"); + + return -1; + } + + rs = 0x3712847D; + rt = 0x0031AF2D; + result = 0x37438000; + __asm + ("addq_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + __asm + ("rddsp %0\n\t" + : "=r"(dsp) + ); + + if ((rd != result) || (((dsp >> 20) & 0x01) != 1)) { + printf("2 addq_s.ph wrong\n"); + + return -1; + } + + rs = 0x7fff847D; + rt = 0x0031AF2D; + result = 0x7fff8000; + __asm + ("addq_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + __asm + ("rddsp %0\n\t" + : "=r"(dsp) + ); + + if ((rd != result) || (((dsp >> 20) & 0x01) != 1)) { + printf("3 addq_s.ph wrong\n"); + + return -1; + } + + rs = 0x8030847D; + rt = 0x8a00AF2D; + result = 0xffffffff80008000; + __asm + ("addq_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + __asm + ("rddsp %0\n\t" + : "=r"(dsp) + ); + + if ((rd != result) || (((dsp >> 20) & 0x01) != 1)) { + printf("4 addq_s.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addq_s_pw.c b/qemu/tests/tcg/mips/mips64-dsp/addq_s_pw.c new file mode 100644 index 000000000..2e380bbfc --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addq_s_pw.c @@ -0,0 +1,45 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + rs = 0x123456787FFFFFFF; + rt = 0x1111111100000001; + result = 0x234567897FFFFFFF; + dspresult = 0x1; + + __asm + ("addq_s.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("addq_s.pw error\n"); + + return -1; + } + + rs = 0x80FFFFFFE00000FF; + rt = 0x80000001200000DD; + result = 0x80000000000001DC; + dspresult = 0x01; + + __asm + ("addq_s.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("addq_s.pw error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addq_s_qh.c b/qemu/tests/tcg/mips/mips64-dsp/addq_s_qh.c new file mode 100644 index 000000000..b638a2b93 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addq_s_qh.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + rs = 0x123456787FFF8000; + rt = 0x1111111100028000; + result = 0x234567897FFF8000; + dspresult = 0x1; + + __asm + ("addq_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("addq_s.qh error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addq_s_w.c b/qemu/tests/tcg/mips/mips64-dsp/addq_s_w.c new file mode 100644 index 000000000..3e08f5d48 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addq_s_w.c @@ -0,0 +1,48 @@ +#include "io.h" + +int main() +{ + long long rd, rs, rt; + long long result; + + rt = 0x10017EFD; + rs = 0x11111111; + result = 0x2112900e; + + __asm + ("addq_s.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("addq_s.w error\n"); + } + + rt = 0x80017EFD; + rs = 0x81111111; + result = 0xffffffff80000000; + + __asm + ("addq_s.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("addq_s.w error\n"); + } + + rt = 0x7fffffff; + rs = 0x01111111; + result = 0x7fffffff; + + __asm + ("addq_s.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("addq_s.w error\n"); + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addsc.c b/qemu/tests/tcg/mips/mips64-dsp/addsc.c new file mode 100644 index 000000000..4b684b9b9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addsc.c @@ -0,0 +1,39 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x0000000F; + rt = 0x00000001; + result = 0x00000010; + __asm + ("addsc %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("1 addsc wrong\n"); + + return -1; + } + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x00001110; + __asm + ("addsc %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((rd != result) || (((dsp >> 13) & 0x01) != 1)) { + printf("2 addsc wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addu_ob.c b/qemu/tests/tcg/mips/mips64-dsp/addu_ob.c new file mode 100644 index 000000000..17f9c668c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addu_ob.c @@ -0,0 +1,28 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x3456123498DEF390; + result = 0x468A68AC329AD180; + dspresult = 0x01; + + __asm + ("addu.ob %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + + if ((rd != result) || (dspreg != dspresult)) { + printf("addu.ob error\n\t"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addu_qb.c b/qemu/tests/tcg/mips/mips64-dsp/addu_qb.c new file mode 100644 index 000000000..3b9b5fc5b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addu_qb.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x00FF00FF; + rt = 0x00010001; + result = 0x00000000; + __asm + ("addu.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((rd != result) || (((dsp >> 20) & 0x01) != 1)) { + printf("1 addu.qb wrong\n"); + + return -1; + } + + rs = 0xFFFF1111; + rt = 0x00020001; + result = 0xFFFFFFFFFF011112; + __asm + ("addu.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((rd != result) || (((dsp >> 20) & 0x01) != 1)) { + printf("2 addu.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addu_s_ob.c b/qemu/tests/tcg/mips/mips64-dsp/addu_s_ob.c new file mode 100644 index 000000000..e89a4638b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addu_s_ob.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + rs = 0x123456789ABCDEF0; + rt = 0x3456123498DEF390; + result = 0x468A68ACFFFFFFFF; + dspresult = 0x01; + + __asm + ("addu_s.ob %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + + if ((rd != result) || (dspreg != dspresult)) { + printf("addu_s.ob error\n\t"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addu_s_qb.c b/qemu/tests/tcg/mips/mips64-dsp/addu_s_qb.c new file mode 100644 index 000000000..cb84293ad --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addu_s_qb.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x10FF01FF; + rt = 0x10010001; + result = 0x20FF01FF; + __asm + ("addu_s.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((rd != result) || (((dsp >> 20) & 0x1) != 1)) { + printf("1 addu_s.qb error 1\n"); + + return -1; + } + + rs = 0xFFFFFFFFFFFF1111; + rt = 0x00020001; + result = 0xFFFFFFFFFFFF1112; + __asm + ("addu_s.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((rd != result) || (((dsp >> 20) & 0x1) != 1)) { + printf("2 addu_s.qb error 2\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/addwc.c b/qemu/tests/tcg/mips/mips64-dsp/addwc.c new file mode 100644 index 000000000..5929cd2f5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/addwc.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dspi, dspo; + long long result; + + rs = 0x10FF01FF; + rt = 0x10010001; + dspi = 0x00002000; + result = 0x21000201; + __asm + ("wrdsp %3\n" + "addwc %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dspi) + ); + if (rd != result) { + printf("1 addwc wrong\n"); + + return -1; + } + + rs = 0xFFFF1111; + rt = 0x00020001; + dspi = 0x00; + result = 0x00011112; + __asm + ("wrdsp %3\n" + "addwc %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dspi) + ); + if (rd != result) { + printf("2 addwc wrong\n"); + + return -1; + } + + rs = 0x8FFF1111; + rt = 0x80020001; + dspi = 0x00; + result = 0x10011112; + __asm + ("wrdsp %4\n" + "addwc %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspo) + : "r"(rs), "r"(rt), "r"(dspi) + ); + if ((rd != result) || (((dspo >> 20) & 0x01) != 1)) { + printf("3 addwc wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/bitrev.c b/qemu/tests/tcg/mips/mips64-dsp/bitrev.c new file mode 100644 index 000000000..ac24ef3f5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/bitrev.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x12345678; + result = 0x00001E6A; + + __asm + ("bitrev %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("bitrev wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/bposge32.c b/qemu/tests/tcg/mips/mips64-dsp/bposge32.c new file mode 100644 index 000000000..97bce4460 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/bposge32.c @@ -0,0 +1,50 @@ +#include "io.h" + +int main(void) +{ + long long dsp, sum; + long long result; + + dsp = 0x20; + sum = 0x01; + result = 0x02; + + __asm + ("wrdsp %1\n\t" + "bposge32 test1\n\t" + "nop\n\t" + "addi %0, 0xA2\n\t" + "nop\n\t" + "test1:\n\t" + "addi %0, 0x01\n\t" + : "+r"(sum) + : "r"(dsp) + ); + if (sum != result) { + printf("bposge32 wrong\n"); + + return -1; + } + + dsp = 0x10; + sum = 0x01; + result = 0xA4; + + __asm + ("wrdsp %1\n\t" + "bposge32 test2\n\t" + "nop\n\t" + "addi %0, 0xA2\n\t" + "nop\n\t" + "test2:\n\t" + "addi %0, 0x01\n\t" + : "+r"(sum) + : "r"(dsp) + ); + if (sum != result) { + printf("bposge32 wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/bposge64.c b/qemu/tests/tcg/mips/mips64-dsp/bposge64.c new file mode 100644 index 000000000..36161ad85 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/bposge64.c @@ -0,0 +1,50 @@ +#include "io.h" + +int main(void) +{ + long long dsp, sum; + long long result; + + dsp = 0x40; + sum = 0x01; + result = 0x02; + + __asm + ("wrdsp %1\n\t" + "bposge64 test1\n\t" + "nop\n\t" + "addi %0, 0xA2\n\t" + "nop\n\t" + "test1:\n\t" + "addi %0, 0x01\n\t" + : "+r"(sum) + : "r"(dsp) + ); + if (sum != result) { + printf("bposge64 wrong\n"); + + return -1; + } + + dsp = 0x10; + sum = 0x01; + result = 0xA4; + + __asm + ("wrdsp %1\n\t" + "bposge64 test2\n\t" + "nop\n\t" + "addi %0, 0xA2\n\t" + "nop\n\t" + "test2:\n\t" + "addi %0, 0x01\n\t" + : "+r"(sum) + : "r"(dsp) + ); + if (sum != result) { + printf("bposge64 wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_ph.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_ph.c new file mode 100644 index 000000000..63069d0da --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_ph.c @@ -0,0 +1,42 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x11777066; + rt = 0x55AA33FF; + result = 0x00; + __asm + ("cmp.eq.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + rd = (rd >> 24) & 0x03; + if (rd != result) { + printf("cmp.eq.ph wrong\n"); + + return -1; + } + + rs = 0x11777066; + rt = 0x11777066; + result = 0x03; + __asm + ("cmp.eq.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + rd = (rd >> 24) & 0x03; + if (rd != result) { + printf("cmp.eq.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_pw.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_pw.c new file mode 100644 index 000000000..bae4c06cc --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_pw.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dspreg, dspresult; + + rs = 0x123456789ABCDEFF; + rt = 0x123456789ABCDEFF; + dspresult = 0x03; + + __asm + ("cmp.eq.pw %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x03); + + if (dspreg != dspresult) { + printf("1 cmp.eq.pw error\n"); + + return -1; + } + + rs = 0x123456799ABCDEFe; + rt = 0x123456789ABCDEFF; + dspresult = 0x00; + + __asm + ("cmp.eq.pw %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x03); + + if (dspreg != dspresult) { + printf("2 cmp.eq.pw error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_qh.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_qh.c new file mode 100644 index 000000000..49ea27100 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_eq_qh.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x0E; + + __asm + ("cmp.eq.qh %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x0F); + + if (dspreg != dspresult) { + printf("cmp.eq.qh error\n"); + + return -1; + } + + rs = 0x12355a789A4CD3F0; + rt = 0x123456789ABCDEFF; + dspresult = 0x00; + + __asm + ("cmp.eq.qh %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x0F); + + if (dspreg != dspresult) { + printf("cmp.eq.qh error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_le_ph.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_le_ph.c new file mode 100644 index 000000000..12d24f178 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_le_ph.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x11777066; + rt = 0x55AA33FF; + result = 0x02; + __asm + ("cmp.le.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + rd = (rd >> 24) & 0x03; + if (rd != result) { + printf("cmp.le.ph wrong\n"); + + return -1; + } + rs = 0x11777066; + rt = 0x11777066; + result = 0x03; + __asm + ("cmp.le.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + rd = (rd >> 24) & 0x03; + if (rd != result) { + printf("cmp.le.ph wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_le_pw.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_le_pw.c new file mode 100644 index 000000000..6acc43cd5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_le_pw.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x03; + + __asm + ("cmp.le.pw %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x03); + + if (dspreg != dspresult) { + printf("1 cmp.le.pw error\n"); + + return -1; + } + + rs = 0x123456799ABCEEFF; + rt = 0x123456789ABCDEFF; + dspresult = 0x00; + + __asm + ("cmp.le.pw %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x03); + + if (dspreg != dspresult) { + printf("2 cmp.le.pw error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_le_qh.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_le_qh.c new file mode 100644 index 000000000..c9ce21667 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_le_qh.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x0F; + + __asm + ("cmp.le.qh %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x0F); + + if (dspreg != dspresult) { + printf("cmp.le.qh error\n"); + + return -1; + } + + rs = 0x823456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x0f; + + __asm + ("cmp.le.qh %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x0F); + + if (dspreg != dspresult) { + printf("cmp.le.qh error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_ph.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_ph.c new file mode 100644 index 000000000..1d91228c3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_ph.c @@ -0,0 +1,41 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x11777066; + rt = 0x55AA33FF; + result = 0x02; + __asm + ("cmp.lt.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + rd = (rd >> 24) & 0x03; + if (rd != result) { + printf("cmp.lt.ph wrong\n"); + + return -1; + } + rs = 0x11777066; + rt = 0x11777066; + result = 0x00; + __asm + ("cmp.lt.ph %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + rd = (rd >> 24) & 0x03; + if (rd != result) { + printf("cmp.lt.ph2 wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_pw.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_pw.c new file mode 100644 index 000000000..87e74caf3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_pw.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x01; + + __asm + ("cmp.lt.pw %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x03); + + if (dspreg != dspresult) { + printf("cmp.lt.pw error\n"); + + return -1; + } + + rs = 0x123456779ABCDEFf; + rt = 0x123456789ABCDEFF; + dspresult = 0x02; + + __asm + ("cmp.lt.pw %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x03); + + if (dspreg != dspresult) { + printf("cmp.lt.pw error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_qh.c b/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_qh.c new file mode 100644 index 000000000..0a13a5eaa --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmp_lt_qh.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dspreg, dspresult; + + rs = 0x123558789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x01; + + __asm + ("cmp.lt.qh %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x0F); + + if (dspreg != dspresult) { + printf("cmp.lt.qh error\n"); + + return -1; + } + + rs = 0x123356779ABbDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x0f; + + __asm + ("cmp.lt.qh %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0x0F); + + if (dspreg != dspresult) { + printf("cmp.lt.qh error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpgu_eq_ob.c b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_eq_ob.c new file mode 100644 index 000000000..697d73dd1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_eq_ob.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + result = 0xFE; + + __asm + ("cmpgu.eq.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("cmpgu.eq.ob error\n"); + + return -1; + } + + rs = 0x133456789ABCDEF0; + rt = 0x123556789ABCDEFF; + result = 0x3E; + + __asm + ("cmpgu.eq.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("cmpgu.eq.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpgu_eq_qb.c b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_eq_qb.c new file mode 100644 index 000000000..b41c4430f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_eq_qb.c @@ -0,0 +1,38 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x02; + __asm + ("cmpgu.eq.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("cmpgu.eq.ph wrong\n"); + + return -1; + } + + rs = 0x11777066; + rt = 0x11777066; + result = 0x0F; + __asm + ("cmpgu.eq.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("cmpgu.eq.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpgu_le_ob.c b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_le_ob.c new file mode 100644 index 000000000..8b65f18c0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_le_ob.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + result = 0xFF; + + __asm + ("cmpgu.le.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("cmpgu.le.ob error\n"); + + return -1; + } + + rs = 0x823556789ABCDEF0; + rt = 0x123456789ABCDEFF; + result = 0x3F; + + __asm + ("cmpgu.le.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("cmpgu.le.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpgu_le_qb.c b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_le_qb.c new file mode 100644 index 000000000..dd2b091f6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_le_qb.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0F; + __asm + ("cmpgu.le.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("cmpgu.le.qb wrong\n"); + + return -1; + } + + rs = 0x11777066; + rt = 0x11766066; + result = 0x09; + __asm + ("cmpgu.le.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("cmpgu.le.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpgu_lt_ob.c b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_lt_ob.c new file mode 100644 index 000000000..3e5c9dd6d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_lt_ob.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + result = 0x01; + + __asm + ("cmpgu.lt.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("cmpgu.lt.ob error\n"); + + return -1; + } + + rs = 0x823455789ABCDEF0; + rt = 0x123356789ABCDEFF; + result = 0x21; + + __asm + ("cmpgu.lt.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("cmpgu.lt.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpgu_lt_qb.c b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_lt_qb.c new file mode 100644 index 000000000..a467cb78d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpgu_lt_qb.c @@ -0,0 +1,38 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0D; + __asm + ("cmpgu.lt.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("cmpgu.lt.qb wrong\n"); + + return -1; + } + + rs = 0x11777066; + rt = 0x11766066; + result = 0x00; + __asm + ("cmpgu.lt.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("cmpgu.lt.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpu_eq_ob.c b/qemu/tests/tcg/mips/mips64-dsp/cmpu_eq_ob.c new file mode 100644 index 000000000..4d1983e5e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpu_eq_ob.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0xFE; + + __asm + ("cmpu.eq.ob %1, %2\n\t" + "rddsp %0" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0xFF); + + if (dspreg != dspresult) { + printf("cmpu.eq.ob error\n"); + + return -1; + } + + rs = 0x133516713A0CD1F0; + rt = 0x123456789ABCDEFF; + dspresult = 0x00; + + __asm + ("cmpu.eq.ob %1, %2\n\t" + "rddsp %0" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0xFF); + + if (dspreg != dspresult) { + printf("cmpu.eq.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpu_eq_qb.c b/qemu/tests/tcg/mips/mips64-dsp/cmpu_eq_qb.c new file mode 100644 index 000000000..28f3bec25 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpu_eq_qb.c @@ -0,0 +1,42 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long dsp; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x02; + __asm + ("cmpu.eq.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (dsp != result) { + printf("cmpu.eq.qb wrong\n"); + + return -1; + } + + rs = 0x11777066; + rt = 0x11777066; + result = 0x0F; + __asm + ("cmpu.eq.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (dsp != result) { + printf("cmpu.eq.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpu_le_ob.c b/qemu/tests/tcg/mips/mips64-dsp/cmpu_le_ob.c new file mode 100644 index 000000000..8acbd1c4b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpu_le_ob.c @@ -0,0 +1,44 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0xFF; + + __asm + ("cmpu.le.ob %1, %2\n\t" + "rddsp %0" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = dspreg >> 24; + if (dspreg != dspresult) { + printf("cmpu.le.ob error\n"); + + return -1; + } + + rs = 0x823656789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x3F; + + __asm + ("cmpu.le.ob %1, %2\n\t" + "rddsp %0" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = dspreg >> 24; + if (dspreg != dspresult) { + printf("cmpu.le.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpu_le_qb.c b/qemu/tests/tcg/mips/mips64-dsp/cmpu_le_qb.c new file mode 100644 index 000000000..8a17a0851 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpu_le_qb.c @@ -0,0 +1,41 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long dsp; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0F; + __asm + ("cmpu.le.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (dsp != result) { + printf("cmpu.le.qb wrong\n"); + + return -1; + } + + rs = 0x11777066; + rt = 0x11777066; + result = 0x0F; + __asm + ("cmpu.le.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (dsp != result) { + printf("cmpu.le.qb wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpu_lt_ob.c b/qemu/tests/tcg/mips/mips64-dsp/cmpu_lt_ob.c new file mode 100644 index 000000000..34e312d81 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpu_lt_ob.c @@ -0,0 +1,44 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x01; + + __asm + ("cmpu.lt.ob %1, %2\n\t" + "rddsp %0" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = dspreg >> 24; + if (dspreg != dspresult) { + printf("cmpu.lt.ob error\n"); + + return -1; + } + + rs = 0x823156789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x41; + + __asm + ("cmpu.lt.ob %1, %2\n\t" + "rddsp %0" + : "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = dspreg >> 24; + if (dspreg != dspresult) { + printf("cmpu.lt.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/cmpu_lt_qb.c b/qemu/tests/tcg/mips/mips64-dsp/cmpu_lt_qb.c new file mode 100644 index 000000000..adb75eed5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/cmpu_lt_qb.c @@ -0,0 +1,42 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long dsp; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0D; + __asm + ("cmpu.lt.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (dsp != result) { + printf("cmpu.lt.qb wrong\n"); + + return -1; + } + + rs = 0x11777066; + rt = 0x11777066; + result = 0x00; + __asm + ("cmpu.lt.qb %1, %2\n\t" + "rddsp %0\n\t" + : "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (dsp != result) { + printf("cmpu.lt.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dappend.c b/qemu/tests/tcg/mips/mips64-dsp/dappend.c new file mode 100644 index 000000000..ba8e12182 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dappend.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long res; + rt = 0x1234567887654321; + rs = 0xabcd1234abcd8765; + + res = 0x1234567887654321; + __asm + ("dappend %0, %1, 0x0\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("dappend error\n"); + return -1; + } + + rt = 0x1234567887654321; + rs = 0xabcd1234abcd8765; + + res = 0x2345678876543215; + __asm + ("dappend %0, %1, 0x4\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("dappend error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextp.c b/qemu/tests/tcg/mips/mips64-dsp/dextp.c new file mode 100644 index 000000000..a469cc036 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextp.c @@ -0,0 +1,54 @@ +#include "io.h" + +int main(void) +{ + long long rt, dsp; + long long achi, acli; + long long res, resdsp; + int rs; + + rs = 0xabcd1234; + + achi = 0x12345678; + acli = 0x87654321; + res = 0xff; + resdsp = 0x0; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "wrdsp %4\n\t" + "dextp %0, $ac1, 0x7\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + dsp = (dsp >> 14) & 0x1; + if ((dsp != resdsp) || (rt != res)) { + printf("dextp error\n"); + return -1; + } + + rs = 0xabcd1200; + + achi = 0x12345678; + acli = 0x87654321; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "wrdsp %4\n\t" + "dextp %0, $ac1, 0x7\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + dsp = (dsp >> 14) & 0x1; + if (dsp != resdsp) { + printf("dextp error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextpdp.c b/qemu/tests/tcg/mips/mips64-dsp/dextpdp.c new file mode 100644 index 000000000..a2361e2d4 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextpdp.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rt, dsp; + long long achi, acli; + long long res, resdsp, resdsppos; + int rs; + int tmp1, tmp2; + + rs = 0xabcd1234; + + achi = 0x12345678; + acli = 0x87654321; + res = 0xff; + resdsp = 0x0; + resdsppos = 0x2c; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "wrdsp %4\n\t" + "dextpdp %0, $ac1, 0x7\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + tmp1 = (dsp >> 14) & 0x1; + tmp2 = dsp & 0x3f; + + if ((tmp1 != resdsp) || (rt != res) || (tmp2 != resdsppos)) { + printf("dextpdp error\n"); + return -1; + } + + rs = 0xabcd1200; + + achi = 0x12345678; + acli = 0x87654321; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "wrdsp %4\n\t" + "dextpdp %0, $ac1, 0x7\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + tmp1 = (dsp >> 14) & 0x1; + + if (tmp1 != resdsp) { + printf("dextpdp error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextpdpv.c b/qemu/tests/tcg/mips/mips64-dsp/dextpdpv.c new file mode 100644 index 000000000..09c0b5b41 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextpdpv.c @@ -0,0 +1,63 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long res, resdsp, resdsppos; + int rsdsp; + int tmp1, tmp2; + + rsdsp = 0xabcd1234; + rs = 0x7; + achi = 0x12345678; + acli = 0x87654321; + res = 0xff; + resdsp = 0x0; + resdsppos = 0x2c; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "wrdsp %4, 0x1\n\t" + "wrdsp %4\n\t" + "dextpdpv %0, $ac1, %5\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rsdsp), "r"(rs) + ); + + tmp1 = (dsp >> 14) & 0x1; + tmp2 = dsp & 0x3f; + + if ((tmp1 != resdsp) || (rt != res) || (tmp2 != resdsppos)) { + printf("dextpdpv error\n"); + return -1; + } + + rsdsp = 0xabcd1200; + rs = 0x7; + achi = 0x12345678; + acli = 0x87654321; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "wrdsp %4, 0x1\n\t" + "wrdsp %4\n\t" + "dextpdpv %0, $ac1, %5\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rsdsp), "r"(rs) + ); + + tmp1 = (dsp >> 14) & 0x1; + + if (tmp1 != resdsp) { + printf("dextpdpv error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextpv.c b/qemu/tests/tcg/mips/mips64-dsp/dextpv.c new file mode 100644 index 000000000..2626f3d98 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextpv.c @@ -0,0 +1,58 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long res, resdsp; + int rsdsp; + + rsdsp = 0xabcd1234; + rs = 0x7; + + achi = 0x12345678; + acli = 0x87654321; + res = 0xff; + resdsp = 0x0; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "wrdsp %4, 0x1\n\t" + "wrdsp %4\n\t" + "dextpv %0, $ac1, %5\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rsdsp), "r"(rs) + ); + dsp = (dsp >> 14) & 0x1; + if ((dsp != resdsp) || (rt != res)) { + printf("dextpv error\n"); + return -1; + } + + rsdsp = 0xabcd1200; + rs = 0x7; + + achi = 0x12345678; + acli = 0x87654321; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "wrdsp %4, 0x1\n\t" + "wrdsp %4\n\t" + "dextpv %0, $ac1, %5\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rsdsp), "r"(rs) + ); + dsp = (dsp >> 14) & 0x1; + if (dsp != resdsp) { + printf("dextpv error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextr_l.c b/qemu/tests/tcg/mips/mips64-dsp/dextr_l.c new file mode 100644 index 000000000..538846df1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextr_l.c @@ -0,0 +1,44 @@ +#include "io.h" + +int main(void) +{ + long long rt; + long long achi, acli; + long long res; + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x2100000000123456; + + __asm + ("mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "dextr.l %0, $ac1, 0x8\n\t" + : "=r"(rt) + : "r"(achi), "r"(acli) + ); + if (rt != res) { + printf("dextr.l error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x12345678; + + __asm + ("mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "dextr.l %0, $ac1, 0x0\n\t" + : "=r"(rt) + : "r"(achi), "r"(acli) + ); + if (rt != res) { + printf("dextr.l error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextr_r_l.c b/qemu/tests/tcg/mips/mips64-dsp/dextr_r_l.c new file mode 100644 index 000000000..a10a9ab40 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextr_r_l.c @@ -0,0 +1,54 @@ +#include "io.h" + +int main(void) +{ + long long rt, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x2100000000123456; + resdsp = 0x01; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_r.l %0, $ac1, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextr_r.l error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x12345678; + resdsp = 0x01; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_r.l %0, $ac1, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextr_r.l error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextr_r_w.c b/qemu/tests/tcg/mips/mips64-dsp/dextr_r_w.c new file mode 100644 index 000000000..2774e9bfc --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextr_r_w.c @@ -0,0 +1,54 @@ +#include "io.h" + +int main(void) +{ + long long rt, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x123456; + resdsp = 0x01; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_r.w %0, $ac1, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextr_r.w error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x12345678; + resdsp = 0x01; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_r.w %0, $ac1, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextr_r.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextr_rs_l.c b/qemu/tests/tcg/mips/mips64-dsp/dextr_rs_l.c new file mode 100644 index 000000000..1a202fefa --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextr_rs_l.c @@ -0,0 +1,52 @@ +#include "io.h" + +int main(void) +{ + long long rt, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x8000000000000000; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_rs.l %0, $ac1, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextr_rs.l error\n"); + return -1; + } + + achi = 0x00; + acli = 0x12345678; + + res = 0x12345678; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_rs.l %0, $ac1, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextr_rs.l error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextr_rs_w.c b/qemu/tests/tcg/mips/mips64-dsp/dextr_rs_w.c new file mode 100644 index 000000000..ebe5f99db --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextr_rs_w.c @@ -0,0 +1,52 @@ +#include "io.h" + +int main(void) +{ + long long rt, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + + res = 0xffffffff80000000; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_rs.w %0, $ac1, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextr_rs.w error\n"); + return -1; + } + + achi = 0x00; + acli = 0x12345678; + + res = 0x123456; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_rs.w %0, $ac1, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextr_rs.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextr_s_h.c b/qemu/tests/tcg/mips/mips64-dsp/dextr_s_h.c new file mode 100644 index 000000000..1adb5549a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextr_s_h.c @@ -0,0 +1,73 @@ +#include "io.h" + +int main(void) +{ + long long rt, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + + res = 0xffffffffffff8000; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_s.h %0, $ac1, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("1 dextr_s.h error\n"); + return -1; + } + + achi = 0x77654321; + acli = 0x12345678; + + res = 0x7fff; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_s.h %0, $ac1, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("2 dextr_s.h error\n"); + return -1; + } + + achi = 0x00; + acli = 0x78; + + res = 0x7; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextr_s.h %0, $ac1, 0x4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("3 dextr_s.h error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextr_w.c b/qemu/tests/tcg/mips/mips64-dsp/dextr_w.c new file mode 100644 index 000000000..79bed5da3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextr_w.c @@ -0,0 +1,44 @@ +#include "io.h" + +int main(void) +{ + long long rt; + long long achi, acli; + long long res; + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x123456; + + __asm + ("mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "dextr.w %0, $ac1, 0x8\n\t" + : "=r"(rt) + : "r"(achi), "r"(acli) + ); + if (rt != res) { + printf("dextr.w error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + + res = 0x12345678; + + __asm + ("mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "dextr.w %0, $ac1, 0x0\n\t" + : "=r"(rt) + : "r"(achi), "r"(acli) + ); + if (rt != res) { + printf("dextr.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextrv_l.c b/qemu/tests/tcg/mips/mips64-dsp/dextrv_l.c new file mode 100644 index 000000000..2e6187f72 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextrv_l.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long res; + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x8; + + res = 0x2100000000123456; + + __asm + ("mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "dextrv.l %0, $ac1, %3\n\t" + : "=r"(rt) + : "r"(achi), "r"(acli), "r"(rs) + ); + if (rt != res) { + printf("dextrv.l error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x0; + + res = 0x12345678; + + __asm + ("mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "dextrv.l %0, $ac1, %3\n\t" + : "=r"(rt) + : "r"(achi), "r"(acli), "r"(rs) + ); + if (rt != res) { + printf("dextrv.l error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextrv_r_l.c b/qemu/tests/tcg/mips/mips64-dsp/dextrv_r_l.c new file mode 100644 index 000000000..b47a0177d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextrv_r_l.c @@ -0,0 +1,56 @@ +#include "io.h" + +int main(void) +{ + long long rt, dsp, rs; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x8; + + res = 0x2100000000123456; + resdsp = 0x01; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_r.l %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_r.l error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x0; + + res = 0x12345678; + resdsp = 0x01; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_r.l %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_r.l error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextrv_r_w.c b/qemu/tests/tcg/mips/mips64-dsp/dextrv_r_w.c new file mode 100644 index 000000000..cd201deb2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextrv_r_w.c @@ -0,0 +1,56 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x8; + + res = 0x123456; + resdsp = 0x01; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_r.w %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_r.w error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x0; + + res = 0x12345678; + resdsp = 0x01; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_r.w %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_r.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextrv_rs_l.c b/qemu/tests/tcg/mips/mips64-dsp/dextrv_rs_l.c new file mode 100644 index 000000000..6ce418546 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextrv_rs_l.c @@ -0,0 +1,54 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x8; + + res = 0x8000000000000000; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_rs.l %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_rs.l error\n"); + return -1; + } + + achi = 0x00; + acli = 0x12345678; + rs = 0x0; + + res = 0x12345678; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_rs.l %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_rs.l error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextrv_rs_w.c b/qemu/tests/tcg/mips/mips64-dsp/dextrv_rs_w.c new file mode 100644 index 000000000..a65183c03 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextrv_rs_w.c @@ -0,0 +1,54 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x8; + + res = 0xffffffff80000000; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_rs.w %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_rs.w error\n"); + return -1; + } + + achi = 0x00; + acli = 0x12345678; + rs = 0x8; + + res = 0x123456; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_rs.w %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_rs.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextrv_s_h.c b/qemu/tests/tcg/mips/mips64-dsp/dextrv_s_h.c new file mode 100644 index 000000000..87d3aeedc --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextrv_s_h.c @@ -0,0 +1,32 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long res, resdsp; + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x8; + + res = 0xffffffffffff8000; + resdsp = 0x1; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dextrv_s.h %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs) + ); + dsp = (dsp >> 23) & 0x1; + + if ((dsp != resdsp) || (rt != res)) { + printf("dextrv_s.h error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dextrv_w.c b/qemu/tests/tcg/mips/mips64-dsp/dextrv_w.c new file mode 100644 index 000000000..973765c1c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dextrv_w.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long res; + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x8; + + res = 0x123456; + + __asm + ("mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "dextrv.w %0, $ac1, %3\n\t" + : "=r"(rt) + : "r"(achi), "r"(acli), "r"(rs) + ); + if (rt != res) { + printf("dextrv.w error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x0; + + res = 0x12345678; + + __asm + ("mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "dextrv.w %0, $ac1, %3\n\t" + : "=r"(rt) + : "r"(achi), "r"(acli), "r"(rs) + ); + if (rt != res) { + printf("dextrv.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dinsv.c b/qemu/tests/tcg/mips/mips64-dsp/dinsv.c new file mode 100644 index 000000000..f6192188c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dinsv.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long res; + + rs = 0x1234567887654321; + rt = 0x1234567812345678; + dsp = 0x2222; + res = 0x1234567812345678; + __asm + ("wrdsp %1, 0x3\n\t" + "wrdsp %1\n\t" + "dinsv %0, %2\n\t" + : "+r"(rt) + : "r"(dsp), "r"(rs) + ); + + if (rt != res) { + printf("dinsv error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dmadd.c b/qemu/tests/tcg/mips/mips64-dsp/dmadd.c new file mode 100644 index 000000000..fb2261472 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dmadd.c @@ -0,0 +1,57 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + + achi = 0x1; + acli = 0x1; + + rs = 0x0000000100000001; + rt = 0x0000000200000002; + + resh = 0x1; + resl = 0x5; + __asm + ("mthi %2, $ac1 \t\n" + "mtlo %3, $ac1 \t\n" + "dmadd $ac1, %4, %5\t\n" + "mfhi %0, $ac1 \t\n" + "mflo %1, $ac1 \t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("1 dmadd error\n"); + + return -1; + } + + achi = 0x1; + acli = 0x1; + + rs = 0xaaaabbbbccccdddd; + rt = 0xaaaabbbbccccdddd; + + resh = 0x0000000000000000; + resl = 0xffffffffca860b63; + + __asm + ("mthi %2, $ac1 \t\n" + "mtlo %3, $ac1 \t\n" + "dmadd $ac1, %4, %5\t\n" + "mfhi %0, $ac1 \t\n" + "mflo %1, $ac1 \t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("2 dmadd error\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dmaddu.c b/qemu/tests/tcg/mips/mips64-dsp/dmaddu.c new file mode 100644 index 000000000..39ab0c10d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dmaddu.c @@ -0,0 +1,56 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + achi = 0x1; + acli = 0x2; + + rs = 0x0000000200000002; + rt = 0x0000000200000002; + resh = 0x1; + resl = 0xa; + __asm + ("mthi %2, $ac1 \t\n" + "mtlo %3, $ac1 \t\n" + "dmaddu $ac1, %4, %5\t\n" + "mfhi %0, $ac1 \t\n" + "mflo %1, $ac1 \t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("1 dmaddu error\n"); + + return -1; + } + + achi = 0x1; + acli = 0x1; + + rs = 0xaaaabbbbccccdddd; + rt = 0xaaaabbbbccccdddd; + + resh = 0x0000000000000002; + resl = 0xffffffffca860b63; + + __asm + ("mthi %2, $ac1 \t\n" + "mtlo %3, $ac1 \t\n" + "dmaddu $ac1, %4, %5\t\n" + "mfhi %0, $ac1 \t\n" + "mflo %1, $ac1 \t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("2 dmaddu error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dmsub.c b/qemu/tests/tcg/mips/mips64-dsp/dmsub.c new file mode 100644 index 000000000..16be6170e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dmsub.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + achi = 0x1; + acli = 0x8; + + rs = 0x0000000100000001; + rt = 0x0000000200000002; + + resh = 0x1; + resl = 0x4; + + __asm + ("mthi %2, $ac1 \t\n" + "mtlo %3, $ac1 \t\n" + "dmsub $ac1, %4, %5\t\n" + "mfhi %0, $ac1 \t\n" + "mflo %1, $ac1 \t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("1 dmsub error\n"); + + return -1; + } + + achi = 0xfffffffF; + acli = 0xfffffffF; + + rs = 0x8888999977776666; + rt = 0x9999888877776666; + + resh = 0xffffffffffffffff; + resl = 0x789aae13; + + __asm + ("mthi %2, $ac1 \t\n" + "mtlo %3, $ac1 \t\n" + "dmsub $ac1, %4, %5\t\n" + "mfhi %0, $ac1 \t\n" + "mflo %1, $ac1 \t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("2 dmsub error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dmsubu.c b/qemu/tests/tcg/mips/mips64-dsp/dmsubu.c new file mode 100644 index 000000000..cc4838ad5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dmsubu.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + achi = 0x1; + acli = 0x8; + + rs = 0x0000000100000001; + rt = 0x0000000200000002; + + resh = 0x1; + resl = 0x4; + + __asm + ("mthi %2, $ac1 \t\n" + "mtlo %3, $ac1 \t\n" + "dmsubu $ac1, %4, %5\t\n" + "mfhi %0, $ac1 \t\n" + "mflo %1, $ac1 \t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("1 dmsubu error\n"); + + return -1; + } + + achi = 0xfffffffF; + acli = 0xfffffffF; + + rs = 0x8888999977776666; + rt = 0x9999888877776666; + + resh = 0xffffffffffffffff; + resl = 0x789aae13; + + __asm + ("mthi %2, $ac1 \t\n" + "mtlo %3, $ac1 \t\n" + "dmsubu $ac1, %4, %5\t\n" + "mfhi %0, $ac1 \t\n" + "mflo %1, $ac1 \t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("2 dmsubu error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dmthlip.c b/qemu/tests/tcg/mips/mips64-dsp/dmthlip.c new file mode 100644 index 000000000..027555fb5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dmthlip.c @@ -0,0 +1,41 @@ +#include "io.h" + +int main(void) +{ + long long rs, dsp; + long long achi, acli; + + long long rsdsp; + long long acho, aclo; + + long long res; + long long reshi, reslo; + + + rs = 0xaaaabbbbccccdddd; + achi = 0x87654321; + acli = 0x12345678; + dsp = 0x22; + + res = 0x62; + reshi = 0x12345678; + reslo = 0xffffffffccccdddd; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "wrdsp %5\n\t" + "dmthlip %6, $ac1\n\t" + "rddsp %0\n\t" + "mfhi %1, $ac1\n\t" + "mflo %2, $ac1\n\t" + : "=r"(rsdsp), "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(dsp), "r"(rs) + ); + if ((rsdsp != res) || (acho != reshi) || (aclo != reslo)) { + printf("dmthlip error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpaq_s_w_ph.c b/qemu/tests/tcg/mips/mips64-dsp/dpaq_s_w_ph.c new file mode 100644 index 000000000..1bca93500 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpaq_s_w_ph.c @@ -0,0 +1,32 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long ach = 0, acl = 0; + long long resulth, resultl, resultdsp; + + rs = 0x800000FF; + rt = 0x80000002; + resulth = 0x00; + resultl = 0xFFFFFFFF800003FB; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = dsp >> 17 & 0x01; + if ((dsp != resultdsp) || (ach != resulth) || (acl != resultl)) { + printf("dpaq_w.w.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpaq_s_w_qh.c b/qemu/tests/tcg/mips/mips64-dsp/dpaq_s_w_qh.c new file mode 100644 index 000000000..844a34742 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpaq_s_w_qh.c @@ -0,0 +1,57 @@ +#include"io.h" +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + + achi = 0x1; + acli = 0x1; + rs = 0x0001000100010001; + rt = 0x0002000200020002; + resh = 0x1; + resl = 0x11; + + __asm + ("mthi %2, $ac1\t\n" + "mtlo %3, $ac1\t\n" + "dpaq_s.w.qh $ac1, %4, %5\t\n" + "mfhi %0, $ac1\t\n" + "mflo %1, $ac1\t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("1 dpaq_s.w.qh error\n"); + + return -1; + } + + achi = 0xffffffff; + acli = 0xaaaaaaaa; + + rs = 0x1111222233334444; + rt = 0xffffeeeeddddcccc; + + resh = 0x00; + resl = 0xffffffffd27ad82e; + + __asm + ("mthi %2, $ac1\t\n" + "mtlo %3, $ac1\t\n" + "dpaq_s.w.qh $ac1, %4, %5\t\n" + "mfhi %0, $ac1\t\n" + "mflo %1, $ac1\t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("2 dpaq_s.w.qh error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpaq_sa_l_pw.c b/qemu/tests/tcg/mips/mips64-dsp/dpaq_sa_l_pw.c new file mode 100644 index 000000000..1bb2ec2f2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpaq_sa_l_pw.c @@ -0,0 +1,88 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long achi, acli; + long long acho, aclo; + long long dsp; + long long resh, resl; + long long resdsp; + + rs = 0x0000000100000001; + rt = 0x0000000200000002; + achi = 0x1; + acli = 0x1; + resh = 0xffffffffffffffff; + resl = 0x0; + resdsp = 0x01; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "dpaq_sa.l.pw $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl) || ((dsp >> (16 + 1)) != resdsp)) { + printf("1 dpaq_sa_l_pw error\n"); + + return -1; + } + + rs = 0xaaaabbbbccccdddd; + rt = 0x3333444455556666; + achi = 0x88888888; + acli = 0x66666666; + + resh = 0xffffffff88888887; + resl = 0xffffffff9e2661da; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dpaq_sa.l.pw $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("2 dpaq_sa_l_pw error\n"); + + return -1; + } + + rs = 0x8000000080000000; + rt = 0x8000000080000000; + achi = 0x88888888; + acli = 0x66666666; + + resh = 0xffffffffffffffff; + resl = 0x00; + resdsp = 0x01; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "dpaq_sa.l.pw $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl) || ((dsp >> (16 + 1)) != resdsp)) { + printf("2 dpaq_sa_l_pw error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpaq_sa_l_w.c b/qemu/tests/tcg/mips/mips64-dsp/dpaq_sa_l_w.c new file mode 100644 index 000000000..f840cdd76 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpaq_sa_l_w.c @@ -0,0 +1,82 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long ach = 0, acl = 0; + long long resulth, resultl, resultdsp; + + rs = 0x80000000; + rt = 0x80000000; + resulth = 0x7FFFFFFF; + resultl = 0xffffffffFFFFFFFF; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %0, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if ((dsp != resultdsp) || (ach != resulth) || (acl != resultl)) { + printf("dpaq_sa.l.w error\n"); + + return -1; + } + + ach = 0x12; + acl = 0x48; + rs = 0x80000000; + rt = 0x80000000; + + resulth = 0x7FFFFFFF; + resultl = 0xffffffffFFFFFFFF; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %0, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if ((dsp != resultdsp) || (ach != resulth) || (acl != resultl)) { + printf("dpaq_sa.l.w error\n"); + + return -1; + } + + ach = 0x741532A0; + acl = 0xfceabb08; + rs = 0x80000000; + rt = 0x80000000; + + resulth = 0x7fffffff; + resultl = 0xffffffffffffffff; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %0, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if ((dsp != resultdsp) || (ach != resulth) || (acl != resultl)) { + printf("dpaq_sa.l.w error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpau_h_obl.c b/qemu/tests/tcg/mips/mips64-dsp/dpau_h_obl.c new file mode 100644 index 000000000..54905e8f9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpau_h_obl.c @@ -0,0 +1,59 @@ + +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + + rs = 0x0000000100000001; + rt = 0x0000000200000002; + achi = 0x1; + acli = 0x1; + resh = 0x1; + resl = 0x3; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dpau.h.obl $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 dpau.h.obl error\n"); + + return -1; + } + + rs = 0xaaaabbbbccccdddd; + rt = 0x3333444455556666; + achi = 0x88888888; + acli = 0x66666666; + + resh = 0xffffffff88888888; + resl = 0x66670d7a; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dpau.h.obl $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 dpau.h.obl error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpau_h_obr.c b/qemu/tests/tcg/mips/mips64-dsp/dpau_h_obr.c new file mode 100644 index 000000000..d7aa60b4b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpau_h_obr.c @@ -0,0 +1,59 @@ + +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + + rs = 0x0000000100000001; + rt = 0x0000000200000002; + achi = 0x1; + acli = 0x1; + resh = 0x1; + resl = 0x3; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dpau.h.obr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 dpau.h.obr error\n"); + + return -1; + } + + rs = 0xccccddddaaaabbbb; + rt = 0x5555666633334444; + achi = 0x88888888; + acli = 0x66666666; + + resh = 0xffffffff88888888; + resl = 0x66670d7a; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dpau.h.obr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 dpau.h.obr error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpau_h_qbl.c b/qemu/tests/tcg/mips/mips64-dsp/dpau_h_qbl.c new file mode 100644 index 000000000..fcfd76431 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpau_h_qbl.c @@ -0,0 +1,29 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 3; + long long resulth, resultl; + + rs = 0x800000FF; + rt = 0x80000002; + resulth = 0x05; + resultl = 0x4003; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpau.h.qbl $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("dpau.h.qbl wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpau_h_qbr.c b/qemu/tests/tcg/mips/mips64-dsp/dpau_h_qbr.c new file mode 100644 index 000000000..3282461a7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpau_h_qbr.c @@ -0,0 +1,29 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 3; + long long resulth, resultl; + + rs = 0x800000FF; + rt = 0x80000002; + resulth = 0x05; + resultl = 0x0201; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpau.h.qbr $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("dpau.h.qbr wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpsq_s_w_ph.c b/qemu/tests/tcg/mips/mips64-dsp/dpsq_s_w_ph.c new file mode 100644 index 000000000..7660f037d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpsq_s_w_ph.c @@ -0,0 +1,51 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 5; + long long resulth, resultl; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x04; + resultl = 0xFFFFFFFFEE9794A3; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_s.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("1 dpsq_s.w.ph wrong\n"); + + return -1; + } + + ach = 0x1424Ef1f; + acl = 0x1035219A; + rs = 0x800083AD; + rt = 0x80003721; + resulth = 0x1424ef1e; + resultl = 0x577ed901; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_s.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("2 dpsq_s.w.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpsq_s_w_qh.c b/qemu/tests/tcg/mips/mips64-dsp/dpsq_s_w_qh.c new file mode 100644 index 000000000..2cc50c577 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpsq_s_w_qh.c @@ -0,0 +1,56 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + + rs = 0xffffeeeeddddcccc; + rt = 0x9999888877776666; + achi = 0x67576; + acli = 0x98878; + + resh = 0x67576; + resl = 0x5b1682c4; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dpsq_s.w.qh $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("1 dpsq_s.w.qh wrong\n"); + + return -1; + } + + rs = 0x8000800080008000; + rt = 0x8000800080008000; + achi = 0x67576; + acli = 0x98878; + + resh = 0x67575; + resl = 0x0009887c; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dpsq_s.w.qh $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("2 dpsq_s.w.qh wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpsq_sa_l_pw.c b/qemu/tests/tcg/mips/mips64-dsp/dpsq_sa_l_pw.c new file mode 100644 index 000000000..7fc2503fc --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpsq_sa_l_pw.c @@ -0,0 +1,76 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long achi, acli; + long long resh, resl, resdsp; + + rs = 0x89789BC0123AD; + rt = 0x5467591643721; + + achi = 0x98765437; + acli = 0x65489709; + + resh = 0xffffffffffffffff; + resl = 0x00; + + resdsp = 0x01; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_sa.l.pw $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(achi), "+r"(acli), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x01; + if ((dsp != resdsp) || (achi != resh) || (acli != resl)) { + printf("1 dpsq_sa.l.pw wrong\n"); + + return -1; + } + + /* clear dspcontrol reg for next test use. */ + dsp = 0; + __asm + ("wrdsp %0" + : + : "r"(dsp) + ); + + rs = 0x8B78980000000; + rt = 0x5867580000000; + + achi = 0x98765437; + acli = 0x65489709; + + resh = 0xffffffff98765436; + resl = 0x11d367d0; + + resdsp = 0x01; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_sa.l.pw $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(achi), "+r"(acli), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x01; + if ((dsp != resdsp) || (achi != resh) || (acli != resl)) { + printf("2 dpsq_sa.l.pw wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpsq_sa_l_w.c b/qemu/tests/tcg/mips/mips64-dsp/dpsq_sa_l_w.c new file mode 100644 index 000000000..f55afc909 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpsq_sa_l_w.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long ach = 5, acl = 5; + long long resulth, resultl, resultdsp; + + rs = 0xBC0123AD; + rt = 0x01643721; + + resulth = 0xfffffffffdf4cbe0; + resultl = 0xFFFFFFFFd138776b; + resultdsp = 0x00; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if ((dsp != resultdsp) || (ach != resulth) || (acl != resultl)) { + printf("1 dpsq_sa.l.w wrong\n"); + + return -1; + } + + ach = 0x54321123; + acl = 5; + rs = 0x80000000; + rt = 0x80000000; + + resulth = 0xffffffffd4321123; + resultl = 0x06; + resultdsp = 0x01; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if ((dsp != resultdsp) || (ach != resulth) || (acl != resultl)) { + printf("2 dpsq_sa.l.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_obl.c b/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_obl.c new file mode 100644 index 000000000..c0a8f4d7a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_obl.c @@ -0,0 +1,32 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 5; + long long resulth, resultl; + + rs = 0x88886666BC0123AD; + rt = 0x9999888801643721; + + resulth = 0x04; + resultl = 0xFFFFFFFFFFFEF115; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsu.h.obl $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + + if ((ach != resulth) || (acl != resultl)) { + printf("dpsu.h.obl wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_obr.c b/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_obr.c new file mode 100644 index 000000000..aa0d47a06 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_obr.c @@ -0,0 +1,32 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 5; + long long resulth, resultl; + + rs = 0x7878878888886666; + rt = 0x9865454399998888; + + resulth = 0x04; + resultl = 0xFFFFFFFFFFFeF115; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsu.h.obr $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + + if ((ach != resulth) || (acl != resultl)) { + printf("dpsu.h.qbr wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_qbl.c b/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_qbl.c new file mode 100644 index 000000000..da6dbb615 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_qbl.c @@ -0,0 +1,29 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 5; + long long resulth, resultl; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x04; + resultl = 0xFFFFFFFFFFFFFEE5; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsu.h.qbl $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("dpsu.h.qbl wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_qbr.c b/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_qbr.c new file mode 100644 index 000000000..bf00b70aa --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dpsu_h_qbr.c @@ -0,0 +1,29 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 5; + long long resulth, resultl; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x04; + resultl = 0xFFFFFFFFFFFFE233; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsu.h.qbr $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("dpsu.h.qbr wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dshilo.c b/qemu/tests/tcg/mips/mips64-dsp/dshilo.c new file mode 100644 index 000000000..f50584b9c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dshilo.c @@ -0,0 +1,52 @@ +#include "io.h" + +int main(void) +{ + long long achi, acli; + long long acho, aclo; + long long reshi, reslo; + + achi = 0x87654321; + acli = 0x12345678; + + reshi = 0xfffffffff8765432; + reslo = 0x1234567; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dshilo $ac1, 0x4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli) + ); + + if ((acho != reshi) || (aclo != reslo)) { + printf("1 dshilo error\n"); + return -1; + } + + achi = 0x87654321; + acli = 0x12345678; + + reshi = 0x1234567; + reslo = 0x00; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dshilo $ac1, -60\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli) + ); + + if ((acho != reshi) || (aclo != reslo)) { + printf("2 dshilo error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/dshilov.c b/qemu/tests/tcg/mips/mips64-dsp/dshilov.c new file mode 100644 index 000000000..792bd2373 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/dshilov.c @@ -0,0 +1,54 @@ +#include "io.h" + +int main(void) +{ + long long achi, acli, rs; + long long acho, aclo; + long long reshi, reslo; + + achi = 0x87654321; + acli = 0x12345678; + rs = 0x4; + + reshi = 0xfffffffff8765432; + reslo = 0x1234567; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dshilov $ac1, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs) + ); + + if ((acho != reshi) || (aclo != reslo)) { + printf("dshilov error\n"); + return -1; + } + + rs = 0x44; + achi = 0x87654321; + acli = 0x12345678; + + reshi = 0x1234567; + reslo = 0x00; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "dshilov $ac1, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs) + ); + + if ((acho != reshi) || (aclo != reslo)) { + printf("dshilov error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extp.c b/qemu/tests/tcg/mips/mips64-dsp/extp.c new file mode 100644 index 000000000..c72f54bac --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extp.c @@ -0,0 +1,50 @@ +#include "io.h" + +int main(void) +{ + long long rt, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + result = 0x000C; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extp %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 14) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("extp wrong\n"); + + return -1; + } + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x01; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extp %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 14) & 0x01; + if (dsp != 1) { + printf("extp wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extpdp.c b/qemu/tests/tcg/mips/mips64-dsp/extpdp.c new file mode 100644 index 000000000..f43019384 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extpdp.c @@ -0,0 +1,51 @@ +#include "io.h" + +int main(void) +{ + long long rt, ach, acl, dsp, pos, efi; + long long result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + result = 0x000C; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdp %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + pos = dsp & 0x3F; + efi = (dsp >> 14) & 0x01; + if ((pos != 3) || (efi != 0) || (result != rt)) { + printf("extpdp wrong\n"); + + return -1; + } + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x01; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdp %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl) + ); + efi = (dsp >> 14) & 0x01; + if (efi != 1) { + printf("extpdp wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extpdpv.c b/qemu/tests/tcg/mips/mips64-dsp/extpdpv.c new file mode 100644 index 000000000..ba57426d2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extpdpv.c @@ -0,0 +1,52 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, ach, acl, dsp, pos, efi; + long long result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0x000C; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdpv %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl), "r"(rs) + ); + pos = dsp & 0x3F; + efi = (dsp >> 14) & 0x01; + if ((pos != 3) || (efi != 0) || (result != rt)) { + printf("extpdpv wrong\n"); + + return -1; + } + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x01; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpdpv %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl), "r"(rs) + ); + efi = (dsp >> 14) & 0x01; + if (efi != 1) { + printf("extpdpv wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extpv.c b/qemu/tests/tcg/mips/mips64-dsp/extpv.c new file mode 100644 index 000000000..158472bf9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extpv.c @@ -0,0 +1,51 @@ +#include "io.h" + +int main(void) +{ + long long rt, ac, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + ac = 0x03; + result = 0x000C; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpv %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl), "r"(ac) + ); + dsp = (dsp >> 14) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("extpv wrong\n"); + + return -1; + } + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x01; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extpv %0, $ac1, %4\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(ach), "r"(acl), "r"(ac) + ); + dsp = (dsp >> 14) & 0x01; + if (dsp != 1) { + printf("extpv wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extr_r_w.c b/qemu/tests/tcg/mips/mips64-dsp/extr_r_w.c new file mode 100644 index 000000000..94572ad15 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extr_r_w.c @@ -0,0 +1,53 @@ +#include "io.h" + +int main(void) +{ + long long rt, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + result = 0xFFFFFFFFA0001699; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_r.w %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("1 extr_r.w wrong\n"); + + return -1; + } + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4D; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_r.w %0, $ac1, 0x04\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("2 extr_r.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extr_rs_w.c b/qemu/tests/tcg/mips/mips64-dsp/extr_rs_w.c new file mode 100644 index 000000000..73551f96b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extr_rs_w.c @@ -0,0 +1,53 @@ +#include "io.h" + +int main(void) +{ + long long rt, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + result = 0x7FFFFFFF; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_rs.w %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("1 extr_rs.w wrong\n"); + + return -1; + } + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4D; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_rs.w %0, $ac1, 0x04\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("2 extr_rs.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extr_s_h.c b/qemu/tests/tcg/mips/mips64-dsp/extr_s_h.c new file mode 100644 index 000000000..de10cb57a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extr_s_h.c @@ -0,0 +1,71 @@ +#include "io.h" + +int main(void) +{ + long long rt, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + result = 0x00007FFF; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_s.h %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("extr_s.h wrong\n"); + + return -1; + } + + ach = 0xffffffff; + acl = 0x12344321; + result = 0xffffffffFFFF8000; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_s.h %0, $ac1, 0x08\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("extr_s.h wrong\n"); + + return -1; + } + + /* Clear dsp */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x00; + acl = 0x4321; + result = 0x432; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr_s.h %0, $ac1, 0x04\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("extr_s.h wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extr_w.c b/qemu/tests/tcg/mips/mips64-dsp/extr_w.c new file mode 100644 index 000000000..bd6957668 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extr_w.c @@ -0,0 +1,53 @@ +#include "io.h" + +int main(void) +{ + long long rt, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + result = 0xFFFFFFFFA0001699; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr.w %0, $ac1, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("extr.w wrong\n"); + + return -1; + } + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4C; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "extr.w %0, $ac1, 0x04\n\t" + "rddsp %1\n\t" + : "=r"(rt), "=r"(dsp) + : "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("extr.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extrv_r_w.c b/qemu/tests/tcg/mips/mips64-dsp/extrv_r_w.c new file mode 100644 index 000000000..837972978 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extrv_r_w.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0xFFFFFFFFA0001699; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_r.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("extrv_r.w wrong\n"); + + return -1; + } + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 4; + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4D; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_r.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("extrv_r.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extrv_rs_w.c b/qemu/tests/tcg/mips/mips64-dsp/extrv_rs_w.c new file mode 100644 index 000000000..8707cd117 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extrv_rs_w.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0x7FFFFFFF; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_rs.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("1 extrv_rs.w wrong\n"); + + return -1; + } + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 4; + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4D; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_rs.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("2 extrv_rs.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extrv_s_h.c b/qemu/tests/tcg/mips/mips64-dsp/extrv_s_h.c new file mode 100644 index 000000000..b6dcaebcb --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extrv_s_h.c @@ -0,0 +1,79 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0x00007FFF; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_s.h %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("extrv_s.h wrong\n"); + + return -1; + } + + rs = 0x08; + ach = 0xffffffff; + acl = 0x12344321; + result = 0xffffffffFFFF8000; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_s.h %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("extrv_s.h wrong\n"); + + return -1; + } + + /* Clear dsp */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 0x04; + ach = 0x00; + acl = 0x4321; + result = 0x432; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv_s.h %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("extrv_s.h wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/extrv_w.c b/qemu/tests/tcg/mips/mips64-dsp/extrv_w.c new file mode 100644 index 000000000..8adffb395 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/extrv_w.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, ach, acl, dsp; + long long result; + + ach = 0x05; + acl = 0xB4CB; + dsp = 0x07; + rs = 0x03; + result = 0xFFFFFFFFA0001699; + + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 1) || (result != rt)) { + printf("extrv.w wrong\n"); + + return -1; + } + + /* Clear dspcontrol */ + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 4; + ach = 0x01; + acl = 0xB4CB; + result = 0x10000B4C; + __asm + ("wrdsp %1, 0x01\n\t" + "mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "extrv.w %0, $ac1, %2\n\t" + "rddsp %1\n\t" + : "=r"(rt), "+r"(dsp) + : "r"(rs), "r"(ach), "r"(acl) + ); + dsp = (dsp >> 23) & 0x01; + if ((dsp != 0) || (result != rt)) { + printf("extrv.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/head.S b/qemu/tests/tcg/mips/mips64-dsp/head.S new file mode 100644 index 000000000..9a099ae42 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/head.S @@ -0,0 +1,16 @@ +/* + * Startup Code for MIPS64 CPU-core + * + */ +.text +.globl _start +.align 4 +_start: + ori $2, $2, 0xffff + sll $2, $2, 16 + ori $2, $2, 0xffff + mtc0 $2, $12, 0 + jal main + +end: + b end diff --git a/qemu/tests/tcg/mips/mips64-dsp/insv.c b/qemu/tests/tcg/mips/mips64-dsp/insv.c new file mode 100644 index 000000000..fc5696f4c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/insv.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long result; + + /* msb = 10, lsb = 5 */ + dsp = 0x305; + rt = 0x12345678; + rs = 0xffffffff87654321; + result = 0x12345338; + __asm + ("wrdsp %2, 0x03\n\t" + "insv %0, %1\n\t" + : "+r"(rt) + : "r"(rs), "r"(dsp) + ); + if (rt != result) { + printf("insv wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/io.h b/qemu/tests/tcg/mips/mips64-dsp/io.h new file mode 100644 index 000000000..b7db61d7c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/io.h @@ -0,0 +1,22 @@ +#ifndef _ASM_IO_H +#define _ASM_IO_H +extern int printf(const char *fmt, ...); +extern unsigned long get_ticks(void); + +#define _read(source) \ +({ unsigned long __res; \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __read(source) \ +({ unsigned long __res; \ + __asm__ __volatile__( \ + "move\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#endif diff --git a/qemu/tests/tcg/mips/mips64-dsp/lbux.c b/qemu/tests/tcg/mips/mips64-dsp/lbux.c new file mode 100644 index 000000000..dbdc87bff --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/lbux.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long value, rd; + long long *p; + unsigned long long addr, index; + long long result; + + value = 0xBCDEF389; + p = &value; + addr = (unsigned long long)p; + index = 0; + result = value & 0xFF; + __asm + ("lbux %0, %1(%2)\n\t" + : "=r"(rd) + : "r"(index), "r"(addr) + ); + if (rd != result) { + printf("lbux wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/ldx.c b/qemu/tests/tcg/mips/mips64-dsp/ldx.c new file mode 100644 index 000000000..787d9f00b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/ldx.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long value, rd; + long long *p; + unsigned long long addr, index; + long long result; + + value = 0xBCDEF389; + p = &value; + addr = (unsigned long long)p; + index = 0; + result = 0xBCDEF389; + __asm + ("ldx %0, %1(%2)\n\t" + : "=r"(rd) + : "r"(index), "r"(addr) + ); + if (rd != result) { + printf("lwx wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/lhx.c b/qemu/tests/tcg/mips/mips64-dsp/lhx.c new file mode 100644 index 000000000..2020e5686 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/lhx.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long value, rd; + long long *p; + unsigned long long addr, index; + long long result; + + value = 0xBCDEF389; + p = &value; + addr = (unsigned long long)p; + index = 0; + result = 0xFFFFFFFFFFFFF389; + __asm + ("lhx %0, %1(%2)\n\t" + : "=r"(rd) + : "r"(index), "r"(addr) + ); + if (rd != result) { + printf("lhx wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/lwx.c b/qemu/tests/tcg/mips/mips64-dsp/lwx.c new file mode 100644 index 000000000..6a81414d6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/lwx.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long value, rd; + long long *p; + unsigned long long addr, index; + long long result; + + value = 0xBCDEF389; + p = &value; + addr = (unsigned long long)p; + index = 0; + result = 0xFFFFFFFFBCDEF389; + __asm + ("lwx %0, %1(%2)\n\t" + : "=r"(rd) + : "r"(index), "r"(addr) + ); + if (rd != result) { + printf("lwx wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/madd.c b/qemu/tests/tcg/mips/mips64-dsp/madd.c new file mode 100644 index 000000000..de6e44fbc --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/madd.c @@ -0,0 +1,33 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0xB4CB; + rs = 0x01; + rt = 0x01; + resulth = 0x05; + resultl = 0xB4CC; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "madd $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo)) { + printf("madd wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maddu.c b/qemu/tests/tcg/mips/mips64-dsp/maddu.c new file mode 100644 index 000000000..e9f426a37 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maddu.c @@ -0,0 +1,33 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0xB4CB; + rs = 0x01; + rt = 0x01; + resulth = 0x05; + resultl = 0xB4CC; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "madd $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo)) { + printf("maddu wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_s_l_pwl.c b/qemu/tests/tcg/mips/mips64-dsp/maq_s_l_pwl.c new file mode 100644 index 000000000..c196b4353 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_s_l_pwl.c @@ -0,0 +1,56 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0xB4CB; + rs = 0x98765432FF060000; + rt = 0xfdeca987CB000000; + resulth = 0x05; + resultl = 0x18278587; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.l.pwl $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo)) { + printf("maq_s_l.w.pwl wrong 1\n"); + + return -1; + } + + achi = 0x05; + acli = 0xB4CB; + rs = 0x80000000FF060000; + rt = 0x80000000CB000000; + resulth = 0x05; + resultl = 0xb4ca; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.l.pwl $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("maq_s_l.w.pwl wrong 2\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_s_l_pwr.c b/qemu/tests/tcg/mips/mips64-dsp/maq_s_l_pwr.c new file mode 100644 index 000000000..e2af69fe2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_s_l_pwr.c @@ -0,0 +1,56 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0xB4CB; + rs = 0x87898765432; + rt = 0x7878fdeca987; + resulth = 0x05; + resultl = 0x18278587; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.l.pwr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo)) { + printf("maq_s.w.pwr wrong\n"); + + return -1; + } + + achi = 0x05; + acli = 0xB4CB; + rs = 0x89899980000000; + rt = 0x88780000000; + resulth = 0x05; + resultl = 0xb4ca; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.l.pwr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("maq_s.w.pwr wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_phl.c b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_phl.c new file mode 100644 index 000000000..7dba8746e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_phl.c @@ -0,0 +1,60 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long dsp; + long long acho, aclo; + long long resulth, resultl; + long long resdsp; + + achi = 0x05; + acli = 0xB4CB; + rs = 0xFF060000; + rt = 0xCB000000; + resulth = 0x04; + resultl = 0xffffffff947438CB; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.w.phl $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo)) { + printf("1 maq_s.w.phl error\n"); + + return -1; + } + + achi = 0x06; + acli = 0xB4CB; + rs = 0x80000000; + rt = 0x80000000; + resulth = 0x6; + resultl = 0xffffffff8000b4ca; + resdsp = 1; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.w.phl $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo) || + (((dsp >> 17) & 0x01) != resdsp)) { + printf("2 maq_s.w.phl error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_phr.c b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_phr.c new file mode 100644 index 000000000..138ee2a69 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_phr.c @@ -0,0 +1,60 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long dsp; + long long acho, aclo; + long long resulth, resultl; + long long resdsp; + + achi = 0x05; + acli = 0xB4CB; + rs = 0xFF06; + rt = 0xCB00; + resulth = 0x04; + resultl = 0xffffffff947438CB; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.w.phr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo)) { + printf("1 maq_s.w.phr error\n"); + + return -1; + } + + achi = 0x06; + acli = 0xB4CB; + rs = 0x8000; + rt = 0x8000; + resulth = 0x6; + resultl = 0xffffffff8000b4ca; + resdsp = 1; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.w.phr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo) || + (((dsp >> 17) & 0x01) != resdsp)) { + printf("2 maq_s.w.phr error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhll.c b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhll.c new file mode 100644 index 000000000..234a0af29 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhll.c @@ -0,0 +1,62 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0x05; + + rs = 0x1234888899990000; + rt = 0x9876888899990000; + + resulth = 0x05; + resultl = 0x15ae87f5; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.w.qhll $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((resulth != acho) || (resultl != aclo)) { + printf("maq_s.w.qhll wrong\n"); + + return -1; + } + + + achi = 0x04; + acli = 0x06; + rs = 0x8000888899990000; + rt = 0x8000888899990000; + + resulth = 0x04; + resultl = 0xffffffff80000005; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.w.qhll $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("maq_s.w.qhll wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhlr.c b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhlr.c new file mode 100644 index 000000000..8768cbaa3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhlr.c @@ -0,0 +1,62 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0x05; + + rs = 0x1234123412340000; + rt = 0x9876987698760000; + + resulth = 0x05; + resultl = 0x15ae87f5; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.w.qhlr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((resulth != acho) || (resultl != aclo)) { + printf("1 maq_s.w.qhlr wrong\n"); + + return -1; + } + + + achi = 0x04; + acli = 0x06; + rs = 0x8000800080000000; + rt = 0x8000800080000000; + + resulth = 0x04; + resultl = 0xffffffff80000005; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.w.qhlr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("2 maq_s.w.qhlr wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhrl.c b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhrl.c new file mode 100644 index 000000000..5006e2be3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhrl.c @@ -0,0 +1,63 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0x05; + + rs = 0x1234888812340000; + rt = 0x9876888898760000; + + resulth = 0x05; + resultl = 0x15ae87f5; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.w.qhrl $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((resulth != acho) || (resultl != aclo)) { + printf("1 maq_s.w.qhrl wrong\n"); + + return -1; + } + + + achi = 0x04; + acli = 0x06; + rs = 0x8888999980000000; + rt = 0x8888999980000000; + + resulth = 0x04; + resultl = 0xffffffff80000005; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.w.qhrl $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("2 maq_s.w.qhrl wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhrr.c b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhrr.c new file mode 100644 index 000000000..1d213a51b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_s_w_qhrr.c @@ -0,0 +1,63 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0x05; + + rs = 0x1234888812341234; + rt = 0x9876888898769876; + + resulth = 0x05; + resultl = 0x15ae87f5; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_s.w.qhrr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((resulth != acho) || (resultl != aclo)) { + printf("1 maq_s.w.qhrr wrong\n"); + + return -1; + } + + + achi = 0x04; + acli = 0x06; + rs = 0x8000888899998000; + rt = 0x8000888899998000; + + resulth = 0x04; + resultl = 0xffffffff80000005; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_s.w.qhrr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("2 maq_s.w.qhrr wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_phl.c b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_phl.c new file mode 100644 index 000000000..5530ffbe6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_phl.c @@ -0,0 +1,60 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long dsp; + long long acho, aclo; + long long resulth, resultl; + long long resdsp; + + achi = 0x05; + acli = 0xB4CB; + rs = 0xFF060000; + rt = 0xCB000000; + resulth = 0xffffffffffffffff; + resultl = 0xffffffff947438cb; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_sa.w.phl $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo)) { + printf("1 maq_sa.w.phl error\n"); + + return -1; + } + + achi = 0x06; + acli = 0xB4CB; + rs = 0x80000000; + rt = 0x80000000; + resulth = 0x00; + resultl = 0x7fffffff; + resdsp = 0x01; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.phl $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo) || + (((dsp >> 17) & 0x01) != 0x01)) { + printf("2 maq_sa.w.phl error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_phr.c b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_phr.c new file mode 100644 index 000000000..b611cfa91 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_phr.c @@ -0,0 +1,60 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long dsp; + long long acho, aclo; + long long resulth, resultl; + long long resdsp; + + achi = 0x05; + acli = 0xB4CB; + rs = 0xFF06; + rt = 0xCB00; + resulth = 0xffffffffffffffff; + resultl = 0xffffffff947438cb; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_sa.w.phr $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo)) { + printf("1 maq_sa.w.phr error\n"); + + return -1; + } + + achi = 0x06; + acli = 0xB4CB; + rs = 0x8000; + rt = 0x8000; + resulth = 0x00; + resultl = 0x7fffffff; + resdsp = 0x01; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.phr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((resulth != acho) || (resultl != aclo) || + (((dsp >> 17) & 0x01) != 0x01)) { + printf("2 maq_sa.w.phr error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhll.c b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhll.c new file mode 100644 index 000000000..136ff2d77 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhll.c @@ -0,0 +1,62 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0x05; + + rs = 0x1234888899990000; + rt = 0x9876888899990000; + + resulth = 0x00; + resultl = 0x15ae87f5; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "maq_sa.w.qhll $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((resulth != acho) || (resultl != aclo)) { + printf("1 maq_sa.w.qhll wrong\n"); + + return -1; + } + + + achi = 0x04; + acli = 0x06; + rs = 0x8000888899990000; + rt = 0x8000888899990000; + + resulth = 0x00; + resultl = 0x7fffffff; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.qhll $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("2 maq_sa.w.qhll wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhlr.c b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhlr.c new file mode 100644 index 000000000..dd0ae1cca --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhlr.c @@ -0,0 +1,64 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0x05; + + rs = 0x1234123412340000; + rt = 0x9876987699990000; + + resulth = 0x0; + resultl = 0x15ae87f5; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.qhlr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x0) || (resulth != acho) || (resultl != aclo)) { + printf("maq_sa.w.qhlr wrong\n"); + + return -1; + } + + + achi = 0x04; + acli = 0x06; + rs = 0x8000800099990000; + rt = 0x8000800099990000; + + resulth = 0x00; + resultl = 0x7fffffff; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.qhlr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("maq_sa.w.qhlr wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrl.c b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrl.c new file mode 100644 index 000000000..a3de6f8e2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrl.c @@ -0,0 +1,64 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0x05; + + rs = 0x1234123412340000; + rt = 0x9876987698760000; + + resulth = 0x0; + resultl = 0x15ae87f5; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.qhrl $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x0) || (resulth != acho) || (resultl != aclo)) { + printf("1 maq_sa.w.qhrl wrong\n"); + + return -1; + } + + + achi = 0x04; + acli = 0x06; + rs = 0x8000800080000000; + rt = 0x8000800080000000; + + resulth = 0x00; + resultl = 0x7fffffff; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.qhrl $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("2 maq_sa.w.qhrl wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrr.c b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrr.c new file mode 100644 index 000000000..f02173736 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrr.c @@ -0,0 +1,64 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs, dsp; + long long achi, acli; + long long acho, aclo; + long long resulth, resultl; + + achi = 0x05; + acli = 0x05; + + rs = 0x1234123412341234; + rt = 0x9876987698769876; + + resulth = 0x0; + resultl = 0x15ae87f5; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.qhrr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x0) || (resulth != acho) || (resultl != aclo)) { + printf("1 maq_sa.w.qhrr wrong\n"); + + return -1; + } + + + achi = 0x04; + acli = 0x06; + rs = 0x8000800080008000; + rt = 0x8000800080008000; + + resulth = 0x00; + resultl = 0x7fffffff; + + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "maq_sa.w.qhrr $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (resulth != acho) || (resultl != aclo)) { + printf("2 maq_sa.w.qhrr wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mfhi.c b/qemu/tests/tcg/mips/mips64-dsp/mfhi.c new file mode 100644 index 000000000..ee915f796 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mfhi.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long achi, acho; + long long result; + + achi = 0x004433; + result = 0x004433; + + __asm + ("mthi %1, $ac1\n\t" + "mfhi %0, $ac1\n\t" + : "=r"(acho) + : "r"(achi) + ); + if (result != acho) { + printf("mfhi wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mflo.c b/qemu/tests/tcg/mips/mips64-dsp/mflo.c new file mode 100644 index 000000000..cdc646b5f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mflo.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long acli, aclo; + long long result; + + acli = 0x004433; + result = 0x004433; + + __asm + ("mtlo %1, $ac1\n\t" + "mflo %0, $ac1\n\t" + : "=r"(aclo) + : "r"(acli) + ); + if (result != aclo) { + printf("mflo wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mips_boot.lds b/qemu/tests/tcg/mips/mips64-dsp/mips_boot.lds new file mode 100644 index 000000000..bd7c0c0f3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mips_boot.lds @@ -0,0 +1,31 @@ +OUTPUT_ARCH(mips) +SECTIONS +{ + . = 0xffffffff80100000; + . = ALIGN((1 << 13)); + .text : + { + *(.text) + *(.rodata) + *(.rodata.*) + } + + __init_begin = .; + . = ALIGN((1 << 12)); + .init.text : AT(ADDR(.init.text) - 0) + { + *(.init.text) + } + .init.data : AT(ADDR(.init.data) - 0) + { + *(.init.data) + } + . = ALIGN((1 << 12)); + __init_end = .; + + . = ALIGN((1 << 13)); + .data : + { + *(.data) + } +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/modsub.c b/qemu/tests/tcg/mips/mips64-dsp/modsub.c new file mode 100644 index 000000000..2c91cb4c5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/modsub.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0xFFFFFFFF; + rt = 0x000000FF; + result = 0xFFFFFF00; + __asm + ("modsub %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("modsub wrong\n"); + + return -1; + } + + rs = 0x00000000; + rt = 0x00CD1FFF; + result = 0x0000CD1F; + __asm + ("modsub %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("modsub wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/msub.c b/qemu/tests/tcg/mips/mips64-dsp/msub.c new file mode 100644 index 000000000..75066b591 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/msub.c @@ -0,0 +1,32 @@ +#include "io.h" + +int main(void) +{ + long long achi, acli, rs, rt; + long long acho, aclo; + long long resulth, resultl; + + rs = 0x00BBAACC; + rt = 0x0B1C3D2F; + achi = 0x00004433; + acli = 0xFFCC0011; + resulth = 0xFFFFFFFFFFF81F29; + resultl = 0xFFFFFFFFB355089D; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "msub $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resulth) || (aclo != resultl)) { + printf("msub wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/msubu.c b/qemu/tests/tcg/mips/mips64-dsp/msubu.c new file mode 100644 index 000000000..55f8ae046 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/msubu.c @@ -0,0 +1,32 @@ +#include "io.h" + +int main(void) +{ + long long achi, acli, rs, rt; + long long acho, aclo; + long long resulth, resultl; + + rs = 0x00BBAACC; + rt = 0x0B1C3D2F; + achi = 0x00004433; + acli = 0xFFCC0011; + resulth = 0xFFFFFFFFFFF81F29; + resultl = 0xFFFFFFFFB355089D; + + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "msubu $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resulth) || (aclo != resultl)) { + printf("msubu wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mthi.c b/qemu/tests/tcg/mips/mips64-dsp/mthi.c new file mode 100644 index 000000000..857005139 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mthi.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long achi, acho; + long long result; + + achi = 0x004433; + result = 0x004433; + + __asm + ("mthi %1, $ac1\n\t" + "mfhi %0, $ac1\n\t" + : "=r"(acho) + : "r"(achi) + ); + if (result != acho) { + printf("mthi wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mthlip.c b/qemu/tests/tcg/mips/mips64-dsp/mthlip.c new file mode 100644 index 000000000..957cd426f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mthlip.c @@ -0,0 +1,61 @@ +#include "io.h" + +int main(void) +{ + long long rs, ach, acl, dsp; + long long result, resulth, resultl; + + dsp = 0x07; + ach = 0x05; + acl = 0xB4CB; + rs = 0x00FFBBAA; + resulth = 0xB4CB; + resultl = 0x00FFBBAA; + result = 0x27; + + __asm + ("wrdsp %0, 0x01\n\t" + "mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "mthlip %3, $ac1\n\t" + "mfhi %1, $ac1\n\t" + "mflo %2, $ac1\n\t" + "rddsp %0\n\t" + : "+r"(dsp), "+r"(ach), "+r"(acl) + : "r"(rs) + ); + dsp = dsp & 0x3F; + if ((dsp != result) || (ach != resulth) || (acl != resultl)) { + printf("mthlip wrong\n"); + + return -1; + } + + dsp = 0x3f; + ach = 0x05; + acl = 0xB4CB; + rs = 0x00FFBBAA; + resulth = 0xB4CB; + resultl = 0x00FFBBAA; + result = 0x3f; + + __asm + ("wrdsp %0, 0x01\n\t" + "mthi %1, $ac1\n\t" + "mtlo %2, $ac1\n\t" + "mthlip %3, $ac1\n\t" + "mfhi %1, $ac1\n\t" + "mflo %2, $ac1\n\t" + "rddsp %0\n\t" + : "+r"(dsp), "+r"(ach), "+r"(acl) + : "r"(rs) + ); + dsp = dsp & 0x3F; + if ((dsp != result) || (ach != resulth) || (acl != resultl)) { + printf("mthlip wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mtlo.c b/qemu/tests/tcg/mips/mips64-dsp/mtlo.c new file mode 100644 index 000000000..304fffbe7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mtlo.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long acli, aclo; + long long result; + + acli = 0x004433; + result = 0x004433; + + __asm + ("mthi %1, $ac1\n\t" + "mfhi %0, $ac1\n\t" + : "=r"(aclo) + : "r"(acli) + ); + if (result != aclo) { + printf("mtlo wrong\n"); + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhl.c b/qemu/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhl.c new file mode 100644 index 000000000..6c68d45af --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhl.c @@ -0,0 +1,56 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result; + + rd = 0; + rs = 0x45BCFFFF12345678; + rt = 0x98529AD287654321; + result = 0x52fbec7035a2ca5c; + + __asm + ("muleq_s.pw.qhl %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (result != rd) { + printf("1 muleq_s.pw.qhl error\n"); + + return -1; + } + + rd = 0; + rs = 0x45BC800012345678; + rt = 0x9852800087654321; + result = 0x52fbec707FFFFFFF; + + __asm + ("muleq_s.pw.qhl %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (result != rd) { + printf("2 muleq_s.pw.qhl error\n"); + + return -1; + } + + rd = 0; + __asm + ("rddsp %0\n\t" + : "=r"(rd) + ); + rd = rd >> 21; + rd = rd & 0x1; + + if (rd != 1) { + printf("3 muleq_s.pw.qhl error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhr.c b/qemu/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhr.c new file mode 100644 index 000000000..fa8b41fd3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhr.c @@ -0,0 +1,57 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rd = 0; + rs = 0x1234567845BCFFFF; + rt = 0x8765432198529AD2; + result = 0x52fbec7035a2ca5c; + + __asm + ("muleq_s.pw.qhr %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (result != rd) { + printf("1 muleq_s.pw.qhr error\n"); + + return -1; + } + + rd = 0; + rs = 0x1234567845BC8000; + rt = 0x8765432198528000; + result = 0x52fbec707FFFFFFF; + + __asm + ("muleq_s.pw.qhr %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (result != rd) { + printf("2 muleq_s.pw.qhr error\n"); + + return -1; + } + + rd = 0; + __asm + ("rddsp %0\n\t" + : "=r"(rd) + ); + rd = rd >> 21; + rd = rd & 0x1; + + if (rd != 1) { + printf("3 muleq_s.pw.qhr error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/muleq_s_w_phl.c b/qemu/tests/tcg/mips/mips64-dsp/muleq_s_w_phl.c new file mode 100644 index 000000000..997a9f64d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/muleq_s_w_phl.c @@ -0,0 +1,46 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x80009988; + rt = 0x80009988; + result = 0x7FFFFFFF; + resultdsp = 1; + + __asm + ("muleq_s.w.phl %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (dsp != resultdsp)) { + printf("muleq_s.w.phl wrong\n"); + + return -1; + } + + rs = 0x12343322; + rt = 0x43213322; + result = 0x98be968; + resultdsp = 1; + + __asm + ("muleq_s.w.phl %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (dsp != resultdsp)) { + printf("muleq_s.w.phl wrong\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/muleq_s_w_phr.c b/qemu/tests/tcg/mips/mips64-dsp/muleq_s_w_phr.c new file mode 100644 index 000000000..0e594794d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/muleq_s_w_phr.c @@ -0,0 +1,45 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x8000; + rt = 0x8000; + result = 0x7FFFFFFF; + resultdsp = 1; + + __asm + ("muleq_s.w.phr %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (dsp != resultdsp)) { + printf("muleq_s.w.phr wrong\n"); + + return -1; + } + + rs = 0x1234; + rt = 0x4321; + result = 0x98be968; + resultdsp = 1; + + __asm + ("muleq_s.w.phr %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (dsp != resultdsp)) { + printf("muleq_s.w.phr wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbl.c b/qemu/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbl.c new file mode 100644 index 000000000..2f444c9f8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbl.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0xFFFFFFFFFFFF0000; + resultdsp = 1; + + __asm + ("muleu_s.ph.qbl %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (dsp != resultdsp)) { + printf("muleu_s.ph.qbl wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbr.c b/qemu/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbr.c new file mode 100644 index 000000000..8bd0e9942 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbr.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x8000; + rt = 0x80004321; + result = 0xFFFFFFFFFFFF0000; + resultdsp = 1; + + __asm + ("muleu_s.ph.qbr %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (dsp != resultdsp)) { + printf("muleu_s.ph.qbr wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/muleu_s_qh_obl.c b/qemu/tests/tcg/mips/mips64-dsp/muleu_s_qh_obl.c new file mode 100644 index 000000000..db0d386e8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/muleu_s_qh_obl.c @@ -0,0 +1,30 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long resdsp, result; + + rd = 0; + rs = 0x1234567802020202; + rt = 0x0034432112344321; + result = 0x03A8FFFFFFFFFFFF; + resdsp = 0x01; + + __asm + ("muleu_s.qh.obl %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (resdsp != dsp)) { + printf("muleu_s.qh.obl error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/muleu_s_qh_obr.c b/qemu/tests/tcg/mips/mips64-dsp/muleu_s_qh_obr.c new file mode 100644 index 000000000..52ed9c095 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/muleu_s_qh_obr.c @@ -0,0 +1,31 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long resdsp, result; + + rd = 0; + rs = 0x0202020212345678; + + rt = 0x0034432112344321; + result = 0x03A8FFFFFFFFFFFF; + resdsp = 0x01; + + __asm + ("muleu_s.qh.obr %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (resdsp != dsp)) { + printf("muleu_s.qh.obr error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mulq_rs_ph.c b/qemu/tests/tcg/mips/mips64-dsp/mulq_rs_ph.c new file mode 100644 index 000000000..fd6233d4d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mulq_rs_ph.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0x7FFF098C; + resultdsp = 1; + + __asm + ("mulq_rs.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if ((rd != result) || (dsp != resultdsp)) { + printf("mulq_rs.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mulq_rs_qh.c b/qemu/tests/tcg/mips/mips64-dsp/mulq_rs_qh.c new file mode 100644 index 000000000..7863c0591 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mulq_rs_qh.c @@ -0,0 +1,33 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dsp, dspresult; + rt = 0x80003698CE8F9201; + rs = 0x800034634BCDE321; + result = 0x7fff16587a530313; + + dspresult = 0x01; + + __asm + ("mulq_rs.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + if (rd != result) { + printf("mulq_rs.qh error\n"); + + return -1; + } + + dsp = (dsp >> 21) & 0x01; + if (dsp != dspresult) { + printf("mulq_rs.qh DSPControl Reg ouflag error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mulsaq_s_l_pw.c b/qemu/tests/tcg/mips/mips64-dsp/mulsaq_s_l_pw.c new file mode 100644 index 000000000..02548f85c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mulsaq_s_l_pw.c @@ -0,0 +1,59 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long achi, acli; + long long acho, aclo; + long long resl, resh; + + achi = 0x4; + acli = 0x4; + + rs = 0x1234567887654321; + rt = 0x8765432112345678; + + resh = 0x4; + resl = 0x4; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "mulsaq_s.l.pw $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 mulsaq_s.l.pw wrong\n"); + + return -1; + } + + achi = 0x4; + acli = 0x4; + + rs = 0x8000000087654321; + rt = 0x8000000012345678; + + resh = 0x4; + resl = 0x1e8ee513; + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "mulsaq_s.l.pw $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (acho != resh) || (aclo != resl)) { + printf("2 mulsaq_s.l.pw wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mulsaq_s_w_qh.c b/qemu/tests/tcg/mips/mips64-dsp/mulsaq_s_w_qh.c new file mode 100644 index 000000000..92d7a0b4f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mulsaq_s_w_qh.c @@ -0,0 +1,57 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long achi, acli; + long long acho, aclo; + long long resl, resh; + + achi = 0x4; + acli = 0x4; + + rs = 0x5678123443218765; + rt = 0x4321876556781234; + + resh = 0x4; + resl = 0x342fcbd4; + __asm + ("mthi %2, $ac1\n\t" + "mtlo %3, $ac1\n\t" + "mulsaq_s.w.qh $ac1, %4, %5\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 mulsaq_s.w.qh wrong\n"); + return -1; + } + + achi = 0x4; + acli = 0x4; + + rs = 0x8000800087654321; + rt = 0x8000800012345678; + + resh = 0x3; + resl = 0xffffffffe5e81a1c; + __asm + ("mthi %3, $ac1\n\t" + "mtlo %4, $ac1\n\t" + "mulsaq_s.w.qh $ac1, %5, %6\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "=r"(acho), "=r"(aclo), "=r"(dsp) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x1; + if ((dsp != 0x1) || (acho != resh) || (aclo != resl)) { + printf("2 mulsaq_s.w.qh wrong\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/mult.c b/qemu/tests/tcg/mips/mips64-dsp/mult.c new file mode 100644 index 000000000..4a294d1a0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/mult.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, ach, acl; + long long result, resulth, resultl; + + rs = 0x00FFBBAA; + rt = 0x4B231000; + resulth = 0x4b0f01; + resultl = 0x71f8a000; + __asm + ("mult $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(ach), "=r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("mult wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/multu.c b/qemu/tests/tcg/mips/mips64-dsp/multu.c new file mode 100644 index 000000000..21a8a7c77 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/multu.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt, ach, acl; + long long result, resulth, resultl; + + rs = 0x00FFBBAA; + rt = 0x4B231000; + resulth = 0x4b0f01; + resultl = 0x71f8a000; + __asm + ("multu $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "=r"(ach), "=r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("multu wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/packrl_ph.c b/qemu/tests/tcg/mips/mips64-dsp/packrl_ph.c new file mode 100644 index 000000000..3722b0ae6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/packrl_ph.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x56788765; + + __asm + ("packrl.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("packrl.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/packrl_pw.c b/qemu/tests/tcg/mips/mips64-dsp/packrl_pw.c new file mode 100644 index 000000000..780741883 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/packrl_pw.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long res; + + rs = 0x1234567887654321; + rt = 0xabcdef9812345678; + + res = 0x87654321abcdef98; + + __asm + ("packrl.pw %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != res) { + printf("packrl.pw error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/pick_ob.c b/qemu/tests/tcg/mips/mips64-dsp/pick_ob.c new file mode 100644 index 000000000..160049ffd --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/pick_ob.c @@ -0,0 +1,66 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long res; + + dsp = 0xff000000; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x1234567812345678; + + __asm + ("wrdsp %1, 0x10\n\t" + "pick.ob %0, %2, %3\n\t" + : "=r"(rd) + : "r"(dsp), "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("1 pick.ob error\n"); + return -1; + } + + dsp = 0x00000000; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x8765432187654321; + + __asm + ("wrdsp %1, 0x10\n\t" + "pick.ob %0, %2, %3\n\t" + : "=r"(rd) + : "r"(dsp), "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("2 pick.ob error\n"); + return -1; + } + + dsp = 0x34000000; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x8765567887344321; + + __asm + ("wrdsp %1, 0x10\n\t" + "pick.ob %0, %2, %3\n\t" + : "=r"(rd) + : "r"(dsp), "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("3 pick.ob error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/pick_ph.c b/qemu/tests/tcg/mips/mips64-dsp/pick_ph.c new file mode 100644 index 000000000..8800c14d1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/pick_ph.c @@ -0,0 +1,60 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x0A000000; + result = 0x12344321; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + if (rd != result) { + printf("1 pick.ph wrong\n"); + + return -1; + } + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x03000000; + result = 0x12345678; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + if (rd != result) { + printf("2 pick.ph wrong\n"); + + return -1; + } + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x00000000; + result = 0xffffffff87654321; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + if (rd != result) { + printf("3 pick.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/pick_pw.c b/qemu/tests/tcg/mips/mips64-dsp/pick_pw.c new file mode 100644 index 000000000..24d80f551 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/pick_pw.c @@ -0,0 +1,48 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long res; + dsp = 0xff000000; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x1234567812345678; + + __asm + ("wrdsp %1, 0x10\n\t" + "wrdsp %1\n\t" + "pick.pw %0, %2, %3\n\t" + : "=r"(rd), "+r"(dsp) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("pick.pw error\n"); + return -1; + } + + dsp = 0x00000000; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x8765432187654321; + + __asm + ("wrdsp %1, 0x10\n\t" + "wrdsp %1\n\t" + "pick.pw %0, %2, %3\n\t" + : "=r"(rd), "+r"(dsp) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("pick.pw error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/pick_qb.c b/qemu/tests/tcg/mips/mips64-dsp/pick_qb.c new file mode 100644 index 000000000..0d5de9db9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/pick_qb.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x0f000000; + result = 0x12345678; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + if (rd != result) { + printf("pick.qb wrong\n"); + + return -1; + } + + rs = 0x12345678; + rt = 0x87654321; + dsp = 0x00000000; + result = 0xffffffff87654321; + + __asm + ("wrdsp %3, 0x10\n\t" + "pick.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt), "r"(dsp) + ); + if (rd != result) { + printf("pick.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/pick_qh.c b/qemu/tests/tcg/mips/mips64-dsp/pick_qh.c new file mode 100644 index 000000000..aa2e2938a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/pick_qh.c @@ -0,0 +1,48 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long res; + dsp = 0xff000000; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x1234567812345678; + + __asm + ("wrdsp %1, 0x10\n\t" + "wrdsp %1\n\t" + "pick.qh %0, %2, %3\n\t" + : "=r"(rd), "+r"(dsp) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("pick.qh error\n"); + return -1; + } + + dsp = 0x00000000; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x8765432187654321; + + __asm + ("wrdsp %1, 0x10\n\t" + "wrdsp %1\n\t" + "pick.qh %0, %2, %3\n\t" + : "=r"(rd), "+r"(dsp) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("pick.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceq_l_pwl.c b/qemu/tests/tcg/mips/mips64-dsp/preceq_l_pwl.c new file mode 100644 index 000000000..64551007c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceq_l_pwl.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + rt = 0xFFFFFFFF11111111; + result = 0xFFFFFFFF00000000; + + __asm + ("preceq.l.pwl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("preceq.l.pwl wrong\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceq_l_pwr.c b/qemu/tests/tcg/mips/mips64-dsp/preceq_l_pwr.c new file mode 100644 index 000000000..1e05339d2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceq_l_pwr.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + rt = 0xFFFFFFFF11111111; + result = 0x1111111100000000; + + __asm + ("preceq.l.pwl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("preceq.l.pwr wrong\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhl.c b/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhl.c new file mode 100644 index 000000000..f44b94049 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhl.c @@ -0,0 +1,21 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + rt = 0x0123456789ABCDEF; + result = 0x0123000045670000; + + __asm + ("preceq.pw.qhl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("preceq.pw.qhl error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhla.c b/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhla.c new file mode 100644 index 000000000..f0f78f43c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhla.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + + rt = 0x123456789ABCDEF0; + result = 0x123400009ABC0000; + + __asm + ("preceq.pw.qhla %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("preceq.pw.qhla error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhr.c b/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhr.c new file mode 100644 index 000000000..709d4f900 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhr.c @@ -0,0 +1,21 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + rt = 0x0123456789ABCDEF; + result = 0x89AB0000CDEF0000; + + __asm + ("preceq.pw.qhr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("preceq.pw.qhr error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhra.c b/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhra.c new file mode 100644 index 000000000..4d071ec86 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceq_pw_qhra.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + + rt = 0x123456789ABCDEF0; + result = 0x56780000DEF00000; + + __asm + ("preceq.pw.qhra %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("preceq.pw.qhra error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceq_w_phl.c b/qemu/tests/tcg/mips/mips64-dsp/preceq_w_phl.c new file mode 100644 index 000000000..4ed3fc030 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceq_w_phl.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0xFFFFFFFF87650000; + + __asm + ("preceq.w.phl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("preceq.w.phl wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceq_w_phr.c b/qemu/tests/tcg/mips/mips64-dsp/preceq_w_phr.c new file mode 100644 index 000000000..e2ea0933b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceq_w_phr.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x43210000; + + __asm + ("preceq.w.phr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("preceq.w.phr wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbl.c b/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbl.c new file mode 100644 index 000000000..17b73311d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbl.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x43803280; + + __asm + ("precequ.ph.qbl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("precequ.ph.qbl wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbla.c b/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbla.c new file mode 100644 index 000000000..15e94946b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbla.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x43802180; + + __asm + ("precequ.ph.qbla %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("precequ.ph.qbla wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbr.c b/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbr.c new file mode 100644 index 000000000..495368ce0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbr.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x21801080; + + __asm + ("precequ.ph.qbr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("precequ.ph.qbr wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbra.c b/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbra.c new file mode 100644 index 000000000..7c6636975 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precequ_ph_qbra.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x32801080; + + __asm + ("precequ.ph.qbra %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("precequ.ph.qbra wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obl.c b/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obl.c new file mode 100644 index 000000000..176d2365a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obl.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + rt = 0x123456789ABCDEF0; + result = 0x09001A002B003C00; + + __asm + ("precequ.qh.obla %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("precequ.qh.obla error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obla.c b/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obla.c new file mode 100644 index 000000000..93a36a485 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obla.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + rt = 0x123456789ABCDEF0; + result = 0x09002B004D006F00; + + __asm + ("precequ.qh.obla %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("precequ.qh.obla error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obr.c b/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obr.c new file mode 100644 index 000000000..121473083 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obr.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + + rt = 0x123456789ABCDEF0; + result = 0x4D005E006F007000; + + __asm + ("precequ.qh.obr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("precequ.qh.obr error\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obra.c b/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obra.c new file mode 100644 index 000000000..3aa0e096c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precequ_qh_obra.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + + rt = 0x123456789ABCDEF0; + result = 0x1A003C005D007000; + + __asm + ("precequ.qh.obra %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("precequ.qh.obra error\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbl.c b/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbl.c new file mode 100644 index 000000000..81f7917c1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbl.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x00870065; + + __asm + ("preceu.ph.qbl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("preceu.ph.qbl wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbla.c b/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbla.c new file mode 100644 index 000000000..38cf6a62b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbla.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x00870043; + + __asm + ("preceu.ph.qbla %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("preceu.ph.qbla wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbr.c b/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbr.c new file mode 100644 index 000000000..70c32b671 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbr.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x00430021; + + __asm + ("preceu.ph.qbr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("preceu.ph.qbr wrong"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbra.c b/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbra.c new file mode 100644 index 000000000..c6638aaaf --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceu_ph_qbra.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0x00650021; + + __asm + ("preceu.ph.qbra %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (result != rd) { + printf("preceu.ph.qbra wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obl.c b/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obl.c new file mode 100644 index 000000000..63f9373b0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obl.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + rt = 0x123456789ABCDEF0; + result = 0x0012003400560078; + + __asm + ("preceu.qh.obl %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("preceu.qh.obl error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obla.c b/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obla.c new file mode 100644 index 000000000..5fb65e404 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obla.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + rt = 0x123456789ABCDEF0; + result = 0x00120056009A00DE; + + __asm + ("preceu.qh.obla %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("preceu.qh.obla error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obr.c b/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obr.c new file mode 100644 index 000000000..9af3b6372 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obr.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + + rt = 0x123456789ABCDEF0; + result = 0x009A00BC00DE00F0; + + __asm + ("preceu.qh.obr %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("preceu.qh.obr error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obra.c b/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obra.c new file mode 100644 index 000000000..fd0408337 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/preceu_qh_obra.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + + rt = 0x123456789ABCDEF0; + result = 0x0034007800BC00F0; + + __asm + ("preceu.qh.obra %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("preceu.qh.obra error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precr_ob_qh.c b/qemu/tests/tcg/mips/mips64-dsp/precr_ob_qh.c new file mode 100644 index 000000000..ce2da79af --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precr_ob_qh.c @@ -0,0 +1,25 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long res; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x3478347865216521; + + __asm + ("precr.ob.qh %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("precr.ob.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precr_sra_qh_pw.c b/qemu/tests/tcg/mips/mips64-dsp/precr_sra_qh_pw.c new file mode 100644 index 000000000..8bb16de9a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precr_sra_qh_pw.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long res; + + rt = 0x8765432187654321; + rs = 0x1234567812345678; + + res = 0x4321432156785678; + + __asm + ("precr_sra.qh.pw %0, %1, 0x0\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("precr_sra.qh.pw error\n"); + return -1; + } + + rt = 0x8765432187654321; + rs = 0x1234567812345678; + + res = 0x5432543245674567; + + __asm + ("precr_sra.qh.pw %0, %1, 0x4\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("precr_sra.qh.pw error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precr_sra_r_qh_pw.c b/qemu/tests/tcg/mips/mips64-dsp/precr_sra_r_qh_pw.c new file mode 100644 index 000000000..734ac322e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precr_sra_r_qh_pw.c @@ -0,0 +1,40 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long res; + + rt = 0x8765432187654321; + rs = 0x1234567812345678; + + res = 0x4321432156785678; + + __asm + ("precr_sra_r.qh.pw %0, %1, 0x0\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("precr_sra_r.qh.pw error\n"); + return -1; + } + + rt = 0x8765432187654321; + rs = 0x1234567812345678; + + res = 0x5432543245684568; + + __asm + ("precr_sra_r.qh.pw %0, %1, 0x4\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("precr_sra_r.qh.pw error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrq_ob_qh.c b/qemu/tests/tcg/mips/mips64-dsp/precrq_ob_qh.c new file mode 100644 index 000000000..4f61b1709 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrq_ob_qh.c @@ -0,0 +1,25 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long res; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x1256125687438743; + + __asm + ("precrq.ob.qh %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("precrq.ob.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrq_ph_w.c b/qemu/tests/tcg/mips/mips64-dsp/precrq_ph_w.c new file mode 100644 index 000000000..f0946abdc --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrq_ph_w.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x12348765; + + __asm + ("precrq.ph.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("precrq.ph.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrq_pw_l.c b/qemu/tests/tcg/mips/mips64-dsp/precrq_pw_l.c new file mode 100644 index 000000000..da957c074 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrq_pw_l.c @@ -0,0 +1,25 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long res; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x1234567887654321; + + __asm + ("precrq.pw.l %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("precrq.pw.l error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrq_qb_ph.c b/qemu/tests/tcg/mips/mips64-dsp/precrq_qb_ph.c new file mode 100644 index 000000000..f417c9f34 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrq_qb_ph.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x12568743; + + __asm + ("precrq.qb.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("precrq.qb.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrq_qh_pw.c b/qemu/tests/tcg/mips/mips64-dsp/precrq_qh_pw.c new file mode 100644 index 000000000..4a4ffef8e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrq_qh_pw.c @@ -0,0 +1,25 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long res; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x1234123487658765; + + __asm + ("precrq.qh.pw %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("precrq.qh.pw error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrq_rs_ph_w.c b/qemu/tests/tcg/mips/mips64-dsp/precrq_rs_ph_w.c new file mode 100644 index 000000000..61da3331f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrq_rs_ph_w.c @@ -0,0 +1,41 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x12348765; + + __asm + ("precrq_rs.ph.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("1 precrq_rs.ph.w wrong\n"); + + return -1; + } + + rs = 0x7fffC678; + rt = 0x865432A0; + result = 0x7fff8654; + + __asm + ("precrq_rs.ph.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((result != rd) || (((dsp >> 22) & 0x01) != 1)) { + printf("2 precrq_rs.ph.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrq_rs_qh_pw.c b/qemu/tests/tcg/mips/mips64-dsp/precrq_rs_qh_pw.c new file mode 100644 index 000000000..ac78728ab --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrq_rs_qh_pw.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long res; + + rs = 0x1234567812345678; + rt = 0x8765432187654321; + + res = 0x1234123487658765; + + __asm + ("precrq_rs.qh.pw %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("precrq_rs.qh.pw error\n"); + return -1; + } + + rs = 0x7fffC67812345678; + rt = 0x8765432187654321; + + res = 0x7fff123487658765; + + __asm + ("precrq_rs.qh.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + + if (rd != res) { + printf("precrq_rs.qh.pw error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrqu_s_ob_qh.c b/qemu/tests/tcg/mips/mips64-dsp/precrqu_s_ob_qh.c new file mode 100644 index 000000000..e27c36b7f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrqu_s_ob_qh.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long res, resdsp; + + rs = 0x7fff567812345678; + rt = 0x8765432187654321; + + res = 0xffac24ac00860086; + resdsp = 0x1; + + __asm + ("precrqu_s.ob.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 22) & 0x1; + if ((rd != res) || (dsp != resdsp)) { + printf("precrq_s.ob.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/precrqu_s_qb_ph.c b/qemu/tests/tcg/mips/mips64-dsp/precrqu_s_qb_ph.c new file mode 100644 index 000000000..cb1fee450 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/precrqu_s_qb_ph.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x12345678; + rt = 0x87657fff; + result = 0x24AC00FF; + + __asm + ("precrqu_s.qb.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((result != rd) || (((dsp >> 22) & 0x01) != 0x01)) { + printf("precrqu_s.qb.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/prependd.c b/qemu/tests/tcg/mips/mips64-dsp/prependd.c new file mode 100644 index 000000000..b4208c2da --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/prependd.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long res; + rt = 0x1234567887654321; + rs = 0xabcd1234abcd8765; + + res = 0x1234567887654321; + __asm + ("prependd %0, %1, 0x0\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("prependd error\n"); + return -1; + } + + rt = 0x1234567887654321; + rs = 0xabcd1234abcd8765; + + res = 0xd876512345678876; + __asm + ("prependd %0, %1, 0x4\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("prependd error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/prependw.c b/qemu/tests/tcg/mips/mips64-dsp/prependw.c new file mode 100644 index 000000000..d91bd2023 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/prependw.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long res; + rt = 0x1234567887654321; + rs = 0xabcd1234abcd8765; + + res = 0x1234567887654321; + __asm + ("prependw %0, %1, 0x0\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("prependw error\n"); + return -1; + } + + rt = 0x1234567887654321; + rs = 0xabcd1234abcd8765; + + res = 0x5123456788765432; + __asm + ("prependw %0, %1, 0x4\n\t" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("prependw error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/printf.c b/qemu/tests/tcg/mips/mips64-dsp/printf.c new file mode 100644 index 000000000..cf8676d39 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/printf.c @@ -0,0 +1,266 @@ + +typedef unsigned long va_list; + +#define ACC 4 +#define __read(source) \ +({ va_list __res; \ + __asm__ __volatile__( \ + "move\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +enum format_type { + FORMAT_TYPE_NONE, + FORMAT_TYPE_HEX, + FORMAT_TYPE_ULONG, + FORMAT_TYPE_FLOAT +}; + +struct printf_spec { + char type; +}; + +static int format_decode(char *fmt, struct printf_spec *spec) +{ + char *start = fmt; + + for (; *fmt ; ++fmt) { + if (*fmt == '%') { + break; + } + } + + switch (*++fmt) { + case 'x': + spec->type = FORMAT_TYPE_HEX; + break; + + case 'd': + spec->type = FORMAT_TYPE_ULONG; + break; + + case 'f': + spec->type = FORMAT_TYPE_FLOAT; + break; + + default: + spec->type = FORMAT_TYPE_NONE; + } + + return ++fmt - start; +} + +void *memcpy(void *dest, void *src, int n) +{ + int i; + char *s = src; + char *d = dest; + + for (i = 0; i < n; i++) { + d[i] = s[i]; + } + return dest; +} + +char *number(char *buf, va_list num) +{ + int i; + char *str = buf; + static char digits[16] = "0123456789abcdef"; + str = str + sizeof(num) * 2; + + for (i = 0; i < sizeof(num) * 2; i++) { + *--str = digits[num & 15]; + num >>= 4; + } + + return buf + sizeof(num) * 2; +} + +char *__number(char *buf, va_list num) +{ + int i; + va_list mm = num; + char *str = buf; + + if (!num) { + *str++ = '0'; + return str; + } + + for (i = 0; mm; mm = mm/10, i++) { + /* Do nothing. */ + } + + str = str + i; + + while (num) { + *--str = num % 10 + 48; + num = num / 10; + } + + return str + i; +} + +va_list modf(va_list args, va_list *integer, va_list *num) +{ + int i; + double dot_v = 0; + va_list E, DOT, DOT_V; + + if (!args) { + return 0; + } + + for (i = 0, args = args << 1 >> 1; i < 52; i++) { + if ((args >> i) & 0x1) { + break; + } + } + + *integer = 0; + + if ((args >> 56 != 0x3f) || (args >> 52 == 0x3ff)) { + E = (args >> 52) - 1023; + DOT = 52 - E - i; + DOT_V = args << (12 + E) >> (12 + E) >> i; + *integer = ((args << 12 >> 12) >> (i + DOT)) | (1 << E); + } else { + E = ~((args >> 52) - 1023) + 1; + DOT_V = args << 12 >> 12; + + dot_v += 1.0 / (1 << E); + + for (i = 1; i <= 16; i++) { + if ((DOT_V >> (52 - i)) & 0x1) { + dot_v += 1.0 / (1 << E + i); + } + } + + for (i = 1, E = 0; i <= ACC; i++) { + dot_v *= 10; + if (!(va_list)dot_v) { + E++; + } + } + + *num = E; + + return dot_v; + } + + if (args & 0xf) { + for (i = 1; i <= 16; i++) { + if ((DOT_V >> (DOT - i)) & 0x1) { + dot_v += 1.0 / (1 << i); + } + } + + for (i = 1, E = 0; i <= ACC; i++) { + dot_v *= 10; + if (!(va_list)dot_v) { + E++; + } + } + + *num = E; + + return dot_v; + } else if (DOT) { + for (i = 1; i <= DOT; i++) { + if ((DOT_V >> (DOT - i)) & 0x1) { + dot_v += 1.0 / (1 << i); + } + } + + for (i = 1; i <= ACC; i++) { + dot_v = dot_v * 10; + } + + return dot_v; + } + + return 0; +} + +int vsnprintf(char *buf, int size, char *fmt, va_list args) +{ + char *str, *mm; + struct printf_spec spec = {0}; + + str = mm = buf; + + while (*fmt) { + char *old_fmt = fmt; + int read = format_decode(fmt, &spec); + + fmt += read; + + switch (spec.type) { + case FORMAT_TYPE_NONE: { + memcpy(str, old_fmt, read); + str += read; + break; + } + case FORMAT_TYPE_HEX: { + memcpy(str, old_fmt, read); + str = number(str + read, args); + for (; *mm ; ++mm) { + if (*mm == '%') { + *mm = '0'; + break; + } + } + break; + } + case FORMAT_TYPE_ULONG: { + memcpy(str, old_fmt, read - 2); + str = __number(str + read - 2, args); + break; + } + case FORMAT_TYPE_FLOAT: { + va_list integer, dot_v, num; + dot_v = modf(args, &integer, &num); + memcpy(str, old_fmt, read - 2); + str += read - 2; + if ((args >> 63 & 0x1)) { + *str++ = '-'; + } + str = __number(str, integer); + if (dot_v) { + *str++ = '.'; + while (num--) { + *str++ = '0'; + } + str = __number(str, dot_v); + } + break; + } + } + } + *str = '\0'; + + return str - buf; +} + +static void serial_out(char *str) +{ + while (*str) { + *(char *)0xffffffffb80003f8 = *str++; + } +} + +int vprintf(char *fmt, va_list args) +{ + int printed_len = 0; + static char printf_buf[512]; + printed_len = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args); + serial_out(printf_buf); + return printed_len; +} + +int printf(char *fmt, ...) +{ + return vprintf(fmt, __read($5)); +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/raddu_l_ob.c b/qemu/tests/tcg/mips/mips64-dsp/raddu_l_ob.c new file mode 100644 index 000000000..76ddf25fb --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/raddu_l_ob.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, result; + rs = 0x12345678ABCDEF0; + result = 0x000000000001E258; + + __asm + ("raddu.l.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs) + ); + + if (rd != result) { + printf("raddu.l.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/raddu_w_qb.c b/qemu/tests/tcg/mips/mips64-dsp/raddu_w_qb.c new file mode 100644 index 000000000..c9d6535bb --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/raddu_w_qb.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs; + long long result; + + rs = 0x12345678; + result = 0x114; + + __asm + ("raddu.w.qb %0, %1\n\t" + : "=r"(rd) + : "r"(rs) + ); + if (rd != result) { + printf("raddu.w.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/rddsp.c b/qemu/tests/tcg/mips/mips64-dsp/rddsp.c new file mode 100644 index 000000000..716557243 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/rddsp.c @@ -0,0 +1,53 @@ +#include "io.h" + +int main(void) +{ + long long dsp_i, dsp_o; + long long ccond_i, outflag_i, efi_i, c_i, scount_i, pos_i; + long long ccond_o, outflag_o, efi_o, c_o, scount_o, pos_o; + long long ccond_r, outflag_r, efi_r, c_r, scount_r, pos_r; + + ccond_i = 0x000000BC;/* 4 */ + outflag_i = 0x0000001B;/* 3 */ + efi_i = 0x00000001;/* 5 */ + c_i = 0x00000001;/* 2 */ + scount_i = 0x0000000F;/* 1 */ + pos_i = 0x0000000C;/* 0 */ + + dsp_i = (ccond_i << 24) | \ + (outflag_i << 16) | \ + (efi_i << 14) | \ + (c_i << 13) | \ + (scount_i << 7) | \ + pos_i; + + ccond_r = ccond_i; + outflag_r = outflag_i; + efi_r = efi_i; + c_r = c_i; + scount_r = scount_i; + pos_r = pos_i; + + __asm + ("wrdsp %1, 0x3F\n\t" + "rddsp %0, 0x3F\n\t" + : "=r"(dsp_o) + : "r"(dsp_i) + ); + + ccond_o = (dsp_o >> 24) & 0xFF; + outflag_o = (dsp_o >> 16) & 0xFF; + efi_o = (dsp_o >> 14) & 0x01; + c_o = (dsp_o >> 14) & 0x01; + scount_o = (dsp_o >> 7) & 0x3F; + pos_o = dsp_o & 0x1F; + + if ((ccond_o != ccond_r) || (outflag_o != outflag_r) || (efi_o != efi_r) \ + || (c_o != c_r) || (scount_o != scount_r) || (pos_o != pos_r)) { + printf("rddsp wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/repl_ob.c b/qemu/tests/tcg/mips/mips64-dsp/repl_ob.c new file mode 100644 index 000000000..20cb78013 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/repl_ob.c @@ -0,0 +1,21 @@ +#include "io.h" + +int main(void) +{ + long long rd, result; + rd = 0; + result = 0xFFFFFFFFFFFFFFFF; + + __asm + ("repl.ob %0, 0xFF\n\t" + : "=r"(rd) + ); + + if (result != rd) { + printf("repl.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/repl_ph.c b/qemu/tests/tcg/mips/mips64-dsp/repl_ph.c new file mode 100644 index 000000000..11d29bdbc --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/repl_ph.c @@ -0,0 +1,30 @@ +#include "io.h" + +int main(void) +{ + long long rd, result; + + result = 0x01BF01BF; + __asm + ("repl.ph %0, 0x1BF\n\t" + : "=r"(rd) + ); + if (rd != result) { + printf("repl.ph wrong\n"); + + return -1; + } + + result = 0x01FF01FF; + __asm + ("repl.ph %0, 0x01FF\n\t" + : "=r"(rd) + ); + if (rd != result) { + printf("repl.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/repl_pw.c b/qemu/tests/tcg/mips/mips64-dsp/repl_pw.c new file mode 100644 index 000000000..d35376a2a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/repl_pw.c @@ -0,0 +1,34 @@ +#include "io.h" + +int main(void) +{ + long long rd, result; + rd = 0; + result = 0x000001FF000001FF; + + __asm + ("repl.pw %0, 0x1FF\n\t" + : "=r"(rd) + ); + + if (result != rd) { + printf("repl.pw error1\n"); + + return -1; + } + + rd = 0; + result = 0xFFFFFE00FFFFFE00; + __asm + ("repl.pw %0, 0xFFFFFFFFFFFFFE00\n\t" + : "=r"(rd) + ); + + if (result != rd) { + printf("repl.pw error2\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/repl_qb.c b/qemu/tests/tcg/mips/mips64-dsp/repl_qb.c new file mode 100644 index 000000000..592feaecb --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/repl_qb.c @@ -0,0 +1,19 @@ +#include "io.h" + +int main(void) +{ + long long rd, result; + + result = 0xFFFFFFFFBFBFBFBF; + __asm + ("repl.qb %0, 0xBF\n\t" + : "=r"(rd) + ); + if (rd != result) { + printf("repl.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/repl_qh.c b/qemu/tests/tcg/mips/mips64-dsp/repl_qh.c new file mode 100644 index 000000000..82afc3716 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/repl_qh.c @@ -0,0 +1,34 @@ +#include "io.h" + +int main(void) +{ + long long rd, result; + rd = 0; + result = 0x01FF01FF01FF01FF; + + __asm + ("repl.qh %0, 0x1FF\n\t" + : "=r"(rd) + ); + + if (result != rd) { + printf("repl.qh error 1\n"); + + return -1; + } + + rd = 0; + result = 0xFE00FE00FE00FE00; + __asm + ("repl.qh %0, 0xFFFFFFFFFFFFFE00\n\t" + : "=r"(rd) + ); + + if (result != rd) { + printf("repl.qh error 2\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/replv_ob.c b/qemu/tests/tcg/mips/mips64-dsp/replv_ob.c new file mode 100644 index 000000000..31ff3186d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/replv_ob.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + + rt = 0xFF; + result = 0xFFFFFFFFFFFFFFFF; + + __asm + ("replv.ob %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("replv.ob error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/replv_ph.c b/qemu/tests/tcg/mips/mips64-dsp/replv_ph.c new file mode 100644 index 000000000..0af7a36b4 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/replv_ph.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x12345678; + result = 0x56785678; + __asm + ("replv.ph %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("replv.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/replv_pw.c b/qemu/tests/tcg/mips/mips64-dsp/replv_pw.c new file mode 100644 index 000000000..e1789af4c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/replv_pw.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, result; + rd = 0; + rt = 0xFFFFFFFF; + result = 0xFFFFFFFFFFFFFFFF; + + __asm + ("replv.pw %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (result != rd) { + printf("replv.pw error\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/replv_qb.c b/qemu/tests/tcg/mips/mips64-dsp/replv_qb.c new file mode 100644 index 000000000..d99298c31 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/replv_qb.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x12345678; + result = 0x78787878; + __asm + ("replv.qb %0, %1\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("replv.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shilo.c b/qemu/tests/tcg/mips/mips64-dsp/shilo.c new file mode 100644 index 000000000..5f454f69e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shilo.c @@ -0,0 +1,29 @@ +#include "io.h" + +int main(void) +{ + long long ach, acl; + long long resulth, resultl; + + ach = 0xBBAACCFF; + acl = 0x1C3B001D; + + resulth = 0x17755; + resultl = 0xFFFFFFFF99fe3876; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "shilo $ac1, 0x0F\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("shilo wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shilov.c b/qemu/tests/tcg/mips/mips64-dsp/shilov.c new file mode 100644 index 000000000..e82615a8c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shilov.c @@ -0,0 +1,31 @@ +#include "io.h" + +int main(void) +{ + long long rs, ach, acl; + long long resulth, resultl; + + rs = 0x0F; + ach = 0xBBAACCFF; + acl = 0x1C3B001D; + + resulth = 0x17755; + resultl = 0xFFFFFFFF99fe3876; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "shilov $ac1, %2\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("shilov wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_ob.c b/qemu/tests/tcg/mips/mips64-dsp/shll_ob.c new file mode 100644 index 000000000..7dcb58ff4 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_ob.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long res, resdsp; + + rt = 0x9ba8765433456789; + res = 0x9ba8765433456789; + resdsp = 0x0; + __asm + ("shll.ob %0, %2, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x1; + + if ((dsp != resdsp) || (rd != res)) { + printf("shll.ob error\n"); + return -1; + } + + rt = 0x9ba8765433456789; + res = 0xd840b0a098283848; + resdsp = 0x1; + __asm + ("shll.ob %0, %2, 0x3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x1; + + if ((dsp != resdsp) || (rd != res)) { + printf("shll.ob error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_ph.c b/qemu/tests/tcg/mips/mips64-dsp/shll_ph.c new file mode 100644 index 000000000..42b462d20 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_ph.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long result, resultdsp; + + rt = 0x12345678; + result = 0x12345678; + resultdsp = 0; + + __asm + ("shll.ph %0, %2, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll.ph wrong\n"); + + return -1; + } + + rt = 0x12345678; + result = 0xFFFFFFFFA000C000; + resultdsp = 1; + + __asm + ("shll.ph %0, %2, 0x0B\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll.ph wrong1\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_pw.c b/qemu/tests/tcg/mips/mips64-dsp/shll_pw.c new file mode 100644 index 000000000..d7878b279 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_pw.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long result, resultdsp; + + rt = 0x8765432112345678; + result = 0x8765432112345678; + resultdsp = 0; + + __asm + ("shll.pw %0, %2, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll.pw wrong\n"); + return -1; + } + + rt = 0x8765432112345678; + result = 0x6543210034567800; + resultdsp = 1; + + __asm + ("shll.pw %0, %2, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll.pw wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_qb.c b/qemu/tests/tcg/mips/mips64-dsp/shll_qb.c new file mode 100644 index 000000000..c21ab6698 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_qb.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long result, resultdsp; + + rt = 0x87654321; + result = 0x38281808; + resultdsp = 0x01; + + __asm + ("shll.qb %0, %2, 0x03\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + if (rd != result) { + printf("shll.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shll_qh.c new file mode 100644 index 000000000..1380825a3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_qh.c @@ -0,0 +1,42 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long res, resdsp; + + rt = 0x9ba8765433456789; + res = 0x9ba8765433456789; + resdsp = 0x0; + __asm + ("shll.qh %0, %2, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x1; + + if ((dsp != resdsp) || (rd != res)) { + printf("shll.qh error\n"); + return -1; + } + + rt = 0x9ba8765433456789; + res = 0xdd40b2a09a283c48; + resdsp = 0x1; + __asm + ("shll.qh %0, %2, 0x3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x1; + + if ((dsp != resdsp) || (rd != res)) { + printf("shll.qh error1\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_s_ph.c b/qemu/tests/tcg/mips/mips64-dsp/shll_s_ph.c new file mode 100644 index 000000000..1cf5d6da6 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_s_ph.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long result, resultdsp; + + rt = 0x12345678; + result = 0x12345678; + resultdsp = 0x0; + + __asm + ("shll_s.ph %0, %2, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll_s.ph wrong\n"); + + return -1; + } + + rt = 0x12345678; + result = 0x7FFF7FFF; + resultdsp = 0x01; + + __asm + ("shll_s.ph %0, %2, 0x0B\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll_s.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_s_pw.c b/qemu/tests/tcg/mips/mips64-dsp/shll_s_pw.c new file mode 100644 index 000000000..e38f6860c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_s_pw.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long result, resultdsp; + + rt = 0x8765432112345678; + result = 0x8765432112345678; + resultdsp = 0; + + __asm + ("shll_s.pw %0, %2, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll_s.pw wrong\n"); + return -1; + } + + rt = 0x8765432112345678; + result = 0x800000007fffffff; + resultdsp = 1; + + __asm + ("shll_s.pw %0, %2, 0x8\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll_s.pw wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_s_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shll_s_qh.c new file mode 100644 index 000000000..f2f57fa27 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_s_qh.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long res, resdsp; + + rt = 0x9ba8765433456789; + res = 0x9ba8765433456789; + resdsp = 0x0; + __asm + ("shll_s.qh %0, %2, 0x0\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x1; + + if ((dsp != resdsp) || (rd != res)) { + printf("shll_s.qh error\n"); + return -1; + } + + rt = 0x9ba8765433456789; + res = 0x80007fff7fff7fff; + resdsp = 0x1; + __asm + ("shll_s.qh %0, %2, 0x3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + + dsp = (dsp >> 22) & 0x1; + + if ((dsp != resdsp) || (rd != res)) { + printf("shll_s.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shll_s_w.c b/qemu/tests/tcg/mips/mips64-dsp/shll_s_w.c new file mode 100644 index 000000000..57800615d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shll_s_w.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, dsp; + long long result, resultdsp; + + rt = 0x12345678; + result = 0x7FFFFFFF; + resultdsp = 0x01; + + __asm + ("shll_s.w %0, %2, 0x0B\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shll_s.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_ob.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_ob.c new file mode 100644 index 000000000..96a2e6f55 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_ob.c @@ -0,0 +1,45 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs, dsp; + long long result, resultdsp; + + rt = 0x8765432112345678; + rs = 0x0; + result = 0x8765432112345678; + resultdsp = 0; + + __asm + ("shllv.ob %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv.ob wrong\n"); + return -1; + } + + rt = 0x8765432112345678; + rs = 0x4; + result = 0x7050301020406080; + resultdsp = 1; + + __asm + ("shllv.ob %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv.ob wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_ph.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_ph.c new file mode 100644 index 000000000..532291f3f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_ph.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x0B; + rt = 0x12345678; + result = 0xFFFFFFFFA000C000; + resultdsp = 1; + + __asm + ("shllv.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_pw.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_pw.c new file mode 100644 index 000000000..8d4ec295b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_pw.c @@ -0,0 +1,45 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs, dsp; + long long result, resultdsp; + rt = 0x8765432112345678; + rs = 0x0; + result = 0x8765432112345678; + resultdsp = 0; + + __asm + ("shllv.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv.pw wrong\n"); + return -1; + } + + + rt = 0x8765432112345678; + rs = 0x8; + result = 0x6543210034567800; + resultdsp = 1; + + __asm + ("shllv.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv.pw wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_qb.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_qb.c new file mode 100644 index 000000000..e49356b8e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_qb.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x03; + rt = 0x87654321; + result = 0x38281808; + resultdsp = 0x01; + + __asm + ("shllv.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + if (rd != result) { + printf("shllv.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_qh.c new file mode 100644 index 000000000..0de4077e7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_qh.c @@ -0,0 +1,45 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs, dsp; + long long result, resultdsp; + + rt = 0x8765432112345678; + rs = 0x0; + result = 0x8765432112345678; + resultdsp = 0; + + __asm + ("shllv.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv.qh wrong\n"); + return -1; + } + + rt = 0x8765432112345678; + rs = 0x4; + result = 0x7650321023406780; + resultdsp = 1; + + __asm + ("shllv.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv.qh wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_s_ph.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_s_ph.c new file mode 100644 index 000000000..7e69f941f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_s_ph.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x0B; + rt = 0x12345678; + result = 0x7FFF7FFF; + resultdsp = 0x01; + + __asm + ("shllv_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv_s.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_s_pw.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_s_pw.c new file mode 100644 index 000000000..f8dc8d296 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_s_pw.c @@ -0,0 +1,45 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs, dsp; + long long result, resultdsp; + + rt = 0x8765432112345678; + rs = 0x0; + result = 0x8765432112345678; + resultdsp = 0; + + __asm + ("shllv_s.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv_s.pw wrong\n"); + return -1; + } + + rt = 0x8765432112345678; + rs = 0x8; + result = 0x800000007fffffff; + resultdsp = 1; + + __asm + ("shllv_s.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv_s.pw wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_s_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_s_qh.c new file mode 100644 index 000000000..db3832d09 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_s_qh.c @@ -0,0 +1,45 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs, dsp; + long long result, resultdsp; + + rt = 0x8765432112345678; + rs = 0x0; + result = 0x8765432112345678; + resultdsp = 0; + + __asm + ("shllv_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv_s.qh wrong\n"); + return -1; + } + + rt = 0x8765432112345678; + rs = 0x4; + result = 0x80007fff7fff7fff; + resultdsp = 1; + + __asm + ("shllv_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv_s.qh wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shllv_s_w.c b/qemu/tests/tcg/mips/mips64-dsp/shllv_s_w.c new file mode 100644 index 000000000..5f6af8b8c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shllv_s_w.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x0B; + rt = 0x12345678; + result = 0x7FFFFFFF; + resultdsp = 0x01; + + __asm + ("shllv_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt), "r"(rs) + ); + dsp = (dsp >> 22) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("shllv_s.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_ob.c b/qemu/tests/tcg/mips/mips64-dsp/shra_ob.c new file mode 100644 index 000000000..d7fcfa816 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_ob.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main() +{ + long long rd, rt; + long long res; + + rt = 0xbc98756abc654389; + res = 0xfbf9f7f6fb0604f8; + + __asm + ("shra.ob %0, %1, 0x4\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra.ob error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_ph.c b/qemu/tests/tcg/mips/mips64-dsp/shra_ph.c new file mode 100644 index 000000000..a2dc01474 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_ph.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0xFFFFFFFFF0EC0864; + + __asm + ("shra.ph %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shra.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_pw.c b/qemu/tests/tcg/mips/mips64-dsp/shra_pw.c new file mode 100644 index 000000000..33b1b8fe7 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_pw.c @@ -0,0 +1,36 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long res; + + rt = 0x1234567887654321; + res = 0x01234567f8765432; + + __asm + ("shra.pw %0, %1, 0x4" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra.pw error\n"); + return -1; + } + + rt = 0x1234567887654321; + res = 0x1234567887654321; + + __asm + ("shra.pw %0, %1, 0x0" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra.pw error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shra_qh.c new file mode 100644 index 000000000..85dbfef3e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_qh.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long res; + + rt = 0x8512345654323454; + res = 0xf851034505430345; + + __asm + ("shra.qh %0, %1, 0x4\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra.qh error\n"); + return -1; + } + + rt = 0x8512345654323454; + res = 0x8512345654323454; + + __asm + ("shra.qh %0, %1, 0x0\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra.qh error1\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_r_ob.c b/qemu/tests/tcg/mips/mips64-dsp/shra_r_ob.c new file mode 100644 index 000000000..184709443 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_r_ob.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main() +{ + long long rd, rt; + long long res; + + rt = 0xbc98756abc654389; + res = 0xfcfaf8f7fc0705f9; + + __asm + ("shra_r.ob %0, %1, 0x4\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra_r.ob error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_r_ph.c b/qemu/tests/tcg/mips/mips64-dsp/shra_r_ph.c new file mode 100644 index 000000000..e0943ad47 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_r_ph.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0xFFFFFFFFF0ED0864; + + __asm + ("shra_r.ph %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shra_r.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_r_pw.c b/qemu/tests/tcg/mips/mips64-dsp/shra_r_pw.c new file mode 100644 index 000000000..6a86e684b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_r_pw.c @@ -0,0 +1,36 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long res; + + rt = 0x1234567887654321; + res = 0x01234568f8765432; + + __asm + ("shra_r.pw %0, %1, 0x4" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra_r.pw error\n"); + return -1; + } + + rt = 0x1234567887654321; + res = 0x1234567887654321; + + __asm + ("shra_r.pw %0, %1, 0x0" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra_r.pw error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_r_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shra_r_qh.c new file mode 100644 index 000000000..d5c2110ef --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_r_qh.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long res; + + rt = 0x8512345654323454; + res = 0xf0a2068b0a86068b; + + __asm + ("shra_r.qh %0, %1, 0x3\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra_r.qh error\n"); + return -1; + } + + rt = 0x8512345654323454; + res = 0x8512345654323454; + + __asm + ("shra_r.qh %0, %1, 0x0\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shra_r.qh error1\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shra_r_w.c b/qemu/tests/tcg/mips/mips64-dsp/shra_r_w.c new file mode 100644 index 000000000..36d2c9c88 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shra_r_w.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x87654321; + result = 0xFFFFFFFFF0ECA864; + + __asm + ("shra_r.w %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shra_r.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrav_ph.c b/qemu/tests/tcg/mips/mips64-dsp/shrav_ph.c new file mode 100644 index 000000000..1b4e98374 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrav_ph.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x03; + rt = 0x87654321; + result = 0xFFFFFFFFF0EC0864; + + __asm + ("shrav.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrav.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrav_pw.c b/qemu/tests/tcg/mips/mips64-dsp/shrav_pw.c new file mode 100644 index 000000000..e19d51579 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrav_pw.c @@ -0,0 +1,38 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs; + long long res; + + rt = 0x1234567887654321; + rs = 0x4; + res = 0x01234567f8765432; + + __asm + ("shrav.pw %0, %1, %2" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrav.pw error\n"); + return -1; + } + + rt = 0x1234567887654321; + rs = 0x0; + res = 0x1234567887654321; + + __asm + ("shrav.pw %0, %1, %2" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrav.pw error1\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrav_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shrav_qh.c new file mode 100644 index 000000000..dc92e09d4 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrav_qh.c @@ -0,0 +1,39 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs; + long long res; + + rt = 0x8512345654323454; + rs = 0x4; + res = 0xf851034505430345; + + __asm + ("shrav.qh %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrav.qh error\n"); + return -1; + } + + rt = 0x8512345654323454; + rs = 0x0; + res = 0x8512345654323454; + + __asm + ("shrav.qh %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrav.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrav_r_ph.c b/qemu/tests/tcg/mips/mips64-dsp/shrav_r_ph.c new file mode 100644 index 000000000..350d5294f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrav_r_ph.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x03; + rt = 0x87654321; + result = 0xFFFFFFFFF0ED0864; + + __asm + ("shrav_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrav_r.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrav_r_pw.c b/qemu/tests/tcg/mips/mips64-dsp/shrav_r_pw.c new file mode 100644 index 000000000..25b054593 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrav_r_pw.c @@ -0,0 +1,37 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs; + long long res; + + rt = 0x1234567887654321; + rs = 0x4; + res = 0x01234568f8765432; + + __asm + ("shrav_r.pw %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrav_r.pw error\n"); + return -1; + } + + rt = 0x1234567887654321; + rs = 0x0; + res = 0x1234567887654321; + + __asm + ("shrav_r.pw %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != res) { + printf("shrav_r.pw error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrav_r_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shrav_r_qh.c new file mode 100644 index 000000000..fd187a1e0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrav_r_qh.c @@ -0,0 +1,39 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs; + long long res; + + rt = 0x8512345654323454; + rs = 0x3; + res = 0xf0a2068b0a86068b; + + __asm + ("shrav_r.qh %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrav_r.qh error\n"); + return -1; + } + + rt = 0x400000000000000; + rs = 0x0; + res = 0x400000000000000; + + __asm + ("shrav_r.qh %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrav_r.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrav_r_w.c b/qemu/tests/tcg/mips/mips64-dsp/shrav_r_w.c new file mode 100644 index 000000000..3766c7255 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrav_r_w.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x03; + rt = 0x87654321; + result = 0xFFFFFFFFF0ECA864; + + __asm + ("shrav_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrav_r.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrl_ob.c b/qemu/tests/tcg/mips/mips64-dsp/shrl_ob.c new file mode 100644 index 000000000..a1145713a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrl_ob.c @@ -0,0 +1,38 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long res; + + rt = 0xab76543212345678; + res = 0x150e0a0602060a0f; + + __asm + ("shrl.ob %0, %1, 0x3\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shrl.ob error\n"); + return -1; + } + + rt = 0xab76543212345678; + res = 0xab76543212345678; + + __asm + ("shrl.ob %0, %1, 0x0\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shrl.ob error\n"); + return -1; + } + + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrl_qb.c b/qemu/tests/tcg/mips/mips64-dsp/shrl_qb.c new file mode 100644 index 000000000..c0e36dba1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrl_qb.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x12345678; + result = 0x00010203; + + __asm + ("shrl.qb %0, %1, 0x05\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shrl.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrl_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shrl_qh.c new file mode 100644 index 000000000..c1562463e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrl_qh.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt; + long long res; + + rt = 0x8765679abc543786; + res = 0x087606790bc50378; + + __asm + ("shrl.qh %0, %1, 0x4\n\t" + : "=r"(rd) + : "r"(rt) + ); + + if (rd != res) { + printf("shrl.qh error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrlv_ob.c b/qemu/tests/tcg/mips/mips64-dsp/shrlv_ob.c new file mode 100644 index 000000000..cb39c4671 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrlv_ob.c @@ -0,0 +1,39 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs; + long long res; + + rt = 0xab76543212345678; + rs = 0x3; + res = 0x150e0a0602060a0f; + + __asm + ("shrlv.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrlv.ob error\n"); + return -1; + } + + rt = 0xab76543212345678; + rs = 0x0; + res = 0xab76543212345678; + + __asm + ("shrlv.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrlv.ob error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrlv_qb.c b/qemu/tests/tcg/mips/mips64-dsp/shrlv_qb.c new file mode 100644 index 000000000..5616aa9c5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrlv_qb.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x05; + rt = 0x12345678; + result = 0x00010203; + + __asm + ("shrlv.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrlv.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/shrlv_qh.c b/qemu/tests/tcg/mips/mips64-dsp/shrlv_qh.c new file mode 100644 index 000000000..05de2fd6c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/shrlv_qh.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs; + long long res; + + rt = 0x8765679abc543786; + rs = 0x4; + res = 0x087606790bc50378; + + __asm + ("shrlv.qh %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shrlv.qh error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/subq_ph.c b/qemu/tests/tcg/mips/mips64-dsp/subq_ph.c new file mode 100644 index 000000000..6a1b18610 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subq_ph.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0xFFFFFFFF8ACF1357; + resultdsp = 0x01; + + __asm + ("subq.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("subq.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/subq_pw.c b/qemu/tests/tcg/mips/mips64-dsp/subq_pw.c new file mode 100644 index 000000000..32f96ba4b --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subq_pw.c @@ -0,0 +1,44 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + rt = 0x123456789ABCDEF0; + rs = 0x123456789ABCDEF0; + result = 0x0; + dspresult = 0x0; + + __asm + ("subq.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + dspreg = (dspreg >> 20) & 0x1; + if ((rd != result) || (dspreg != dspresult)) { + printf("subq.pw error1\n\t"); + + return -1; + } + + rt = 0x123456789ABCDEF1; + rs = 0x123456789ABCDEF2; + result = 0x0000000000000001; + dspresult = 0x0; + + __asm + ("subq.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + dspreg = (dspreg >> 20) & 0x1; + if ((rd != result) || (dspreg != dspresult)) { + printf("subq.pw error2\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/subq_qh.c b/qemu/tests/tcg/mips/mips64-dsp/subq_qh.c new file mode 100644 index 000000000..76d5f0a10 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subq_qh.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + rt = 0x123456789ABCDEF0; + rs = 0x123456789ABCDEF0; + result = 0x0; + dspresult = 0x0; + + __asm + ("subq.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + dspreg = (dspreg >> 20) & 0x1; + if ((rd != result) || (dspreg != dspresult)) { + printf("subq.qh error\n\t"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/subq_s_ph.c b/qemu/tests/tcg/mips/mips64-dsp/subq_s_ph.c new file mode 100644 index 000000000..0b162f07e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subq_s_ph.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x7FFF1357; + resultdsp = 0x01; + + __asm + ("subq_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("subq_s.ph wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/subq_s_pw.c b/qemu/tests/tcg/mips/mips64-dsp/subq_s_pw.c new file mode 100644 index 000000000..e8e0b0567 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subq_s_pw.c @@ -0,0 +1,63 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + rt = 0x9FFFFFFD9FFFFFFD; + rs = 0x4000000080000000; + result = 0x7fffffffe0000003; + dspresult = 0x1; + + __asm + ("subq_s.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + dspreg = (dspreg >> 20) & 0x1; + if ((rd != result) || (dspreg != dspresult)) { + printf("subq_s.pw error1\n"); + + return -1; + } + + rt = 0x123456789ABCDEF1; + rs = 0x123456789ABCDEF2; + result = 0x0000000000000001; + /* This time we do not set dspctrl, but it setted in pre-action. */ + dspresult = 0x1; + + __asm + ("subq_s.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + dspreg = (dspreg >> 20) & 0x1; + if ((rd != result) || (dspreg != dspresult)) { + printf("subq_s.pw error2\n"); + + return -1; + } + + rt = 0x8000000080000000; + rs = 0x7000000070000000; + dspresult = 0x1; + + __asm + ("subq_s.pw %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = (dspreg >> 20) & 0x1; + if ((dspreg != dspresult)) { + printf("subq_s.pw error3\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/subq_s_qh.c b/qemu/tests/tcg/mips/mips64-dsp/subq_s_qh.c new file mode 100644 index 000000000..4053b6b88 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subq_s_qh.c @@ -0,0 +1,61 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEF0; + result = 0x0; + dspresult = 0x0; + + __asm + ("subq_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + dspreg = (dspreg >> 20) & 0x1; + if ((rd != result) || (dspreg != dspresult)) { + printf("subq_s.qh error1\n"); + + return -1; + } + + rs = 0x4000000080000000; + rt = 0x9FFD00009FFC0000; + result = 0x7FFF0000E0040000; + dspresult = 0x1; + + __asm + ("subq_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + dspreg = (dspreg >> 20) & 0x1; + if ((rd != result) || (dspreg != dspresult)) { + printf("subq_s.qh error2\n"); + + return -1; + } + + rs = 0x8000000000000000; + rt = 0x7000000000000000; + result = 0x8000000000000000; + dspresult = 0x1; + __asm + ("subq_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = (dspreg >> 20) & 0x1; + if ((rd != result) || (dspreg != dspresult)) { + printf("subq_s.qh error3\n"); + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/subq_s_w.c b/qemu/tests/tcg/mips/mips64-dsp/subq_s_w.c new file mode 100644 index 000000000..91d32da17 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subq_s_w.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x7FFFFFFF; + resultdsp = 0x01; + + __asm + ("subq_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("subq_s.w wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/subu_ob.c b/qemu/tests/tcg/mips/mips64-dsp/subu_ob.c new file mode 100644 index 000000000..f67096711 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subu_ob.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + rs = 0x6F6F6F6F6F6F6F6F; + rt = 0x5E5E5E5E5E5E5E5E; + result = 0x1111111111111111; + dspresult = 0x0; + + __asm + ("subu.ob %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + if ((rd != result) || (dspreg != dspresult)) { + printf("subu.ob error\n"); + + return -1; + } + + return 0; +} + diff --git a/qemu/tests/tcg/mips/mips64-dsp/subu_qb.c b/qemu/tests/tcg/mips/mips64-dsp/subu_qb.c new file mode 100644 index 000000000..9eb80df37 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subu_qb.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0xFFFFFFFF8BCF1357; + resultdsp = 0x01; + + __asm + ("subu.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("subu.qb wrong\n"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/subu_s_ob.c b/qemu/tests/tcg/mips/mips64-dsp/subu_s_ob.c new file mode 100644 index 000000000..5df64e5ff --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subu_s_ob.c @@ -0,0 +1,26 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dspreg, result, dspresult; + rs = 0x12345678ABCDEF0; + rt = 0x12345678ABCDEF1; + result = 0x00000000000; + dspresult = 0x01; + + __asm + ("subu_s.ob %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("subu_s.ob error\n\t"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/subu_s_qb.c b/qemu/tests/tcg/mips/mips64-dsp/subu_s_qb.c new file mode 100644 index 000000000..9de76f4a1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/subu_s_qb.c @@ -0,0 +1,27 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x00001357; + resultdsp = 0x01; + + __asm + ("subu_s.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + if ((dsp != resultdsp) || (rd != result)) { + printf("subu_s_qb wrong"); + + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dsp/wrdsp.c b/qemu/tests/tcg/mips/mips64-dsp/wrdsp.c new file mode 100644 index 000000000..3033fd88d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dsp/wrdsp.c @@ -0,0 +1,48 @@ +#include "io.h" + +int main(void) +{ + long long dsp_i, dsp_o; + long long ccond_i, outflag_i, efi_i, c_i, scount_i, pos_i; + long long ccond_o, outflag_o, efi_o, c_o, scount_o, pos_o; + long long ccond_r, outflag_r, efi_r, c_r, scount_r, pos_r; + + ccond_i = 0x000000BC;/* 4 */ + outflag_i = 0x0000001B;/* 3 */ + efi_i = 0x00000001;/* 5 */ + c_i = 0x00000001;/* 2 */ + scount_i = 0x0000000F;/* 1 */ + pos_i = 0x0000000C;/* 0 */ + + dsp_i = (ccond_i << 24) | (outflag_i << 16) | (efi_i << 14) | (c_i << 13) + | (scount_i << 7) | pos_i; + + ccond_r = ccond_i; + outflag_r = outflag_i; + efi_r = efi_i; + c_r = c_i; + scount_r = scount_i; + pos_r = pos_i; + + __asm + ("wrdsp %1, 0x3F\n\t" + "rddsp %0, 0x3F\n\t" + : "=r"(dsp_o) + : "r"(dsp_i) + ); + + ccond_o = (dsp_o >> 24) & 0xFF; + outflag_o = (dsp_o >> 16) & 0xFF; + efi_o = (dsp_o >> 14) & 0x01; + c_o = (dsp_o >> 14) & 0x01; + scount_o = (dsp_o >> 7) & 0x3F; + pos_o = dsp_o & 0x1F; + + if ((ccond_o != ccond_r) || (outflag_o != outflag_r) || (efi_o != efi_r) \ + || (c_o != c_r) || (scount_o != scount_r) || (pos_o != pos_r)) { + printf("wrddsp wrong\n"); + + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/.directory b/qemu/tests/tcg/mips/mips64-dspr2/.directory new file mode 100644 index 000000000..c75a91451 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/.directory @@ -0,0 +1,2 @@ +[Dolphin] +Timestamp=2012,8,3,16,41,52 diff --git a/qemu/tests/tcg/mips/mips64-dspr2/Makefile b/qemu/tests/tcg/mips/mips64-dspr2/Makefile new file mode 100644 index 000000000..ba44bb9c0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/Makefile @@ -0,0 +1,116 @@ +CROSS_COMPILE ?= mips64el-unknown-linux-gnu- + +SIM = qemu-system-mips64el +SIMFLAGS = -nographic -cpu mips64dspr2 -kernel + +AS = $(CROSS_COMPILE)as +LD = $(CROSS_COMPILE)ld +CC = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar +NM = $(CROSS_COMPILE)nm +STRIP = $(CROSS_COMPILE)strip +RANLIB = $(CROSS_COMPILE)ranlib +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump + +VECTORS_OBJ ?= ./head.o ./printf.o + +HEAD_FLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe \ + -msoft-float -march=mips64 -Wa,-mips64 -Wa,--trap \ + -msym32 -DKBUILD_64BIT_SYM32 -I./ + +CFLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -fno-builtin \ + -pipe -march=mips64r2 -mgp64 -mdspr2 -static -Wa,--trap -msym32 \ + -DKBUILD_64BIT_SYM32 -I./ + +LDFLAGS = -T./mips_boot.lds -L./ +FLAGS = -nostdlib -mabi=64 -march=mips64r2 -mgp64 -mdspr2 + +TESTCASES = absq_s_qb.tst +TESTCASES += addqh_ph.tst +TESTCASES += addqh_r_ph.tst +TESTCASES += addqh_r_w.tst +TESTCASES += addqh_w.tst +#TESTCASES += adduh_ob.tst +TESTCASES += adduh_qb.tst +#TESTCASES += adduh_r_ob.tst +TESTCASES += adduh_r_qb.tst +TESTCASES += addu_ph.tst +#TESTCASES += addu_qh.tst +TESTCASES += addu_s_ph.tst +#TESTCASES += addu_s_qh.tst +TESTCASES += append.tst +TESTCASES += balign.tst +#TESTCASES += cmpgdu_eq_ob.tst +TESTCASES += cmpgdu_eq_qb.tst +#TESTCASES += cmpgdu_le_ob.tst +TESTCASES += cmpgdu_le_qb.tst +#TESTCASES += cmpgdu_lt_ob.tst +TESTCASES += cmpgdu_lt_qb.tst +#TESTCASES += dbalign.tst +TESTCASES += dpaqx_sa_w_ph.tst +TESTCASES += dpaqx_s_w_ph.tst +TESTCASES += dpa_w_ph.tst +#TESTCASES += dpa_w_qh.tst +TESTCASES += dpax_w_ph.tst +TESTCASES += dpsqx_sa_w_ph.tst +TESTCASES += dpsqx_s_w_ph.tst +TESTCASES += dps_w_ph.tst +#TESTCASES += dps_w_qh.tst +TESTCASES += dpsx_w_ph.tst +TESTCASES += mul_ph.tst +TESTCASES += mulq_rs_w.tst +TESTCASES += mulq_s_ph.tst +TESTCASES += mulq_s_w.tst +TESTCASES += mulsaq_s_w_ph.tst +TESTCASES += mulsa_w_ph.tst +TESTCASES += mul_s_ph.tst +TESTCASES += precr_qb_ph.tst +TESTCASES += precr_sra_ph_w.tst +TESTCASES += precr_sra_r_ph_w.tst +TESTCASES += prepend.tst +TESTCASES += shra_qb.tst +TESTCASES += shra_r_qb.tst +#TESTCASES += shrav_ob.tst +TESTCASES += shrav_qb.tst +#TESTCASES += shrav_r_ob.tst +TESTCASES += shrav_r_qb.tst +TESTCASES += shrl_ph.tst +TESTCASES += shrlv_ph.tst +TESTCASES += subqh_ph.tst +TESTCASES += subqh_r_ph.tst +TESTCASES += subqh_r_w.tst +TESTCASES += subqh_w.tst +#TESTCASES += subuh_ob.tst +TESTCASES += subuh_qb.tst +#TESTCASES += subuh_r_ob.tst +TESTCASES += subuh_r_qb.tst +TESTCASES += subu_ph.tst +#TESTCASES += subu_qh.tst +TESTCASES += subu_s_ph.tst +#TESTCASES += subu_s_qh.tst + +all: build + +head.o : head.S + $(Q)$(CC) $(HEAD_FLAGS) -D"STACK_TOP=0xffffffff80200000" -c $< -o $@ + +%.o : %.S + $(CC) $(CFLAGS) -c $< -o $@ + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +%.tst: %.o $(VECTORS_OBJ) + $(CC) $(VECTORS_OBJ) $(FLAGS) $(LDFLAGS) $< -o $@ + +build: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES) + +check: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES) + @for case in $(TESTCASES); do \ + echo $(SIM) $(SIMFLAGS) ./$$case; \ + $(SIM) $(SIMFLAGS) ./$$case & (sleep 1; killall $(SIM)); \ + done + +clean: + $(Q)rm -f *.o *.tst *.a diff --git a/qemu/tests/tcg/mips/mips64-dspr2/absq_s_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/absq_s_qb.c new file mode 100644 index 000000000..f7aec3e56 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/absq_s_qb.c @@ -0,0 +1,42 @@ +#include "io.h" +int main() +{ + long long input, result, dsp; + long long hope; + + input = 0x701BA35E; + hope = 0x701B5D5E; + + __asm + ("absq_s.qb %0, %1\n\t" + : "=r"(result) + : "r"(input) + ); + if (result != hope) { + printf("absq_s.qb error\n"); + return -1; + } + + input = 0x801BA35E; + hope = 0x7F1B5D5E; + + __asm + ("absq_s.qb %0, %2\n\t" + "rddsp %1\n\t" + : "=r"(result), "=r"(dsp) + : "r"(input) + ); + dsp = dsp >> 20; + dsp &= 0x01; + if (result != hope) { + printf("absq_s.qb error\n"); + return -1; + } + + if (dsp != 1) { + printf("absq_s.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/addqh_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/addqh_ph.c new file mode 100644 index 000000000..6b43cb8d0 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/addqh_ph.c @@ -0,0 +1,35 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x706A13FE; + rt = 0x13065174; + result = 0x41B832B9; + __asm + ("addqh.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("addqh.ph error!\n"); + return -1; + } + + rs = 0x81000100; + rt = 0xc2000100; + result = 0xffffffffa1800100; + __asm + ("addqh.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("addqh.ph error!\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/addqh_r_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/addqh_r_ph.c new file mode 100644 index 000000000..890ec98d9 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/addqh_r_ph.c @@ -0,0 +1,35 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x706A13FE; + rt = 0x13065174; + result = 0x41B832B9; + __asm + ("addqh_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("addqh_r.ph error\n"); + return -1; + } + + rs = 0x81010100; + rt = 0xc2000100; + result = 0xffffffffa1810100; + __asm + ("addqh_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("addqh_r.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/addqh_r_w.c b/qemu/tests/tcg/mips/mips64-dspr2/addqh_r_w.c new file mode 100644 index 000000000..d324decbd --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/addqh_r_w.c @@ -0,0 +1,38 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x00000010; + rt = 0x00000001; + result = 0x00000009; + + __asm + ("addqh_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("addqh_r.w error!\n"); + return -1; + } + rs = 0xFFFFFFFE; + rt = 0x00000001; + result = 0x00000000; + + __asm + ("addqh_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("addqh_r.w error!\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/addqh_w.c b/qemu/tests/tcg/mips/mips64-dspr2/addqh_w.c new file mode 100644 index 000000000..78559e678 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/addqh_w.c @@ -0,0 +1,39 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x00000010; + rt = 0x00000001; + result = 0x00000008; + + __asm + ("addqh.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("addqh.w wrong\n"); + return -1; + } + + rs = 0xFFFFFFFE; + rt = 0x00000001; + result = 0xFFFFFFFFFFFFFFFF; + + __asm + ("addqh.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("addqh.w wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/addu_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/addu_ph.c new file mode 100644 index 000000000..d64c8cde8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/addu_ph.c @@ -0,0 +1,37 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x00FF00FF; + rt = 0x00010001; + result = 0x01000100; + __asm + ("addu.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("1 addu.ph error\n"); + return -1; + } + + rs = 0xFFFF1111; + rt = 0x00020001; + result = 0x00011112; + __asm + ("addu.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((rd != result) || (((dsp >> 20) & 0x01) != 1)) { + printf("2 addu.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/addu_qh.c b/qemu/tests/tcg/mips/mips64-dspr2/addu_qh.c new file mode 100644 index 000000000..edcbf342c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/addu_qh.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dspreg; + long long result, dspresult; + + rs = 0x123456787FFF0000; + rt = 0x1111111180000000; + result = 0x23456789FFFF0000; + dspresult = 0x0; + + __asm("addu.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("addu.qh error\n"); + return -1; + } + + rs = 0x123456787FFF0000; + rt = 0x1111111180020000; + result = 0x23456789FFFF0000; + dspresult = 0x01; + + __asm("addu.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("addu.qh overflow error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/addu_s_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/addu_s_ph.c new file mode 100644 index 000000000..9250edb45 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/addu_s_ph.c @@ -0,0 +1,37 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x00FE00FE; + rt = 0x00020001; + result = 0x010000FF; + __asm + ("addu_s.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("addu_s.ph error\n"); + return -1; + } + + rs = 0xFFFF1111; + rt = 0x00020001; + result = 0xFFFFFFFFFFFF1112; + __asm + ("addu_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((rd != result) || (((dsp >> 20) & 0x01) != 1)) { + printf("addu_s.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/addu_s_qh.c b/qemu/tests/tcg/mips/mips64-dspr2/addu_s_qh.c new file mode 100644 index 000000000..b0c162625 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/addu_s_qh.c @@ -0,0 +1,43 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dspreg; + long long result, dspresult; + + rs = 0x123456787FFF0000; + rt = 0x1111111180000000; + result = 0x23456789FFFF0000; + dspresult = 0x0; + + __asm("addu_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("1 addu_s.qh error\n"); + return -1; + } + + rs = 0x12345678FFFF0000; + rt = 0x11111111000F0000; + result = 0x23456789FFFF0000; + dspresult = 0x01; + + __asm("addu_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("2 addu_s.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/adduh_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/adduh_ob.c new file mode 100644 index 000000000..9b309f6f1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/adduh_ob.c @@ -0,0 +1,35 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result; + rs = 0xFF987CDEBCEF2356; + rt = 0xFF987CDEBCEF2354; + result = 0xFF987CDEBCEF2355; + + __asm("adduh.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("adduh.ob error\n\t"); + return -1; + } + + rs = 0xac50691729945316; + rt = 0xb9234ca3f5573162; + result = 0xb2395a5d8f75423c; + + __asm("adduh.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("adduh.ob error\n\t"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/adduh_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/adduh_qb.c new file mode 100644 index 000000000..796b409a8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/adduh_qb.c @@ -0,0 +1,35 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0xFF0055AA; + rt = 0x0113421B; + result = 0xffffffff80094B62; + __asm + ("adduh.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("adduh.qb error\n"); + return -1; + } + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x7F800888; + + __asm + ("adduh.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("adduh.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/adduh_r_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/adduh_r_ob.c new file mode 100644 index 000000000..832de833e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/adduh_r_ob.c @@ -0,0 +1,35 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result; + rs = 0xFF987CDEBCEF2356; + rt = 0xFF987CDEBCEF2355; + result = 0xFF987CDEBCEF2356; + + __asm("adduh_r.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("1 adduh_r.ob error\n\t"); + return -1; + } + + rs = 0xac50691729945316; + rt = 0xb9234ca3f5573162; + result = 0xb33a5b5d8f76423c; + + __asm("adduh_r.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("2 adduh_r.ob error\n\t"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/adduh_r_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/adduh_r_qb.c new file mode 100644 index 000000000..ae65fa5e1 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/adduh_r_qb.c @@ -0,0 +1,35 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0xFF0055AA; + rt = 0x01112211; + result = 0xffffffff80093C5E; + __asm + ("adduh_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("adduh_r.qb error\n"); + return -1; + } + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0xffffffff80800888; + __asm + ("adduh_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("adduh_r.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/append.c b/qemu/tests/tcg/mips/mips64-dspr2/append.c new file mode 100644 index 000000000..68a7cecc4 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/append.c @@ -0,0 +1,35 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt; + long long result; + + rs = 0xFF0055AA; + rt = 0x0113421B; + result = 0x02268436; + __asm + ("append %0, %1, 0x01\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (rt != result) { + printf("append error\n"); + return -1; + } + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x0010111F; + __asm + ("append %0, %1, 0x04\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (rt != result) { + printf("append error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/balign.c b/qemu/tests/tcg/mips/mips64-dspr2/balign.c new file mode 100644 index 000000000..7fbe81578 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/balign.c @@ -0,0 +1,35 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt; + long long result; + + rs = 0xFF0055AA; + rt = 0x0113421B; + result = 0x13421BFF; + __asm + ("balign %0, %1, 0x01\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (rt != result) { + printf("balign error\n"); + return -1; + } + + rs = 0xFFFF0FFF; + rt = 0x00010111; + result = 0x11FFFF0F; + __asm + ("balign %0, %1, 0x03\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (rt != result) { + printf("balign error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_ob.c new file mode 100644 index 000000000..61217f38c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_ob.c @@ -0,0 +1,44 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + result = 0xFE; + dspresult = 0xFE; + + __asm("cmpgdu.eq.ob %0, %2, %3\n\t" + "rddsp %1" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0xFF); + + if ((rd != result) || (dspreg != dspresult)) { + printf("1 cmpgdu.eq.ob error\n"); + return -1; + } + + rs = 0x133256789ABCDEF0; + rt = 0x123456789ABCDEFF; + result = 0x3E; + dspresult = 0x3E; + + __asm("cmpgdu.eq.ob %0, %2, %3\n\t" + "rddsp %1" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0xFF); + + if ((rd != result) || (dspreg != dspresult)) { + printf("2 cmpgdu.eq.ob error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_qb.c new file mode 100644 index 000000000..c63f6480e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_qb.c @@ -0,0 +1,41 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x02; + __asm + ("cmpgdu.eq.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if ((rd != result) || (dsp != result)) { + printf("cmpgdu.eq.qb error\n"); + return -1; + } + + rs = 0x11777066; + rt = 0x11777066; + result = 0x0F; + __asm + ("cmpgdu.eq.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + + if ((rd != result) || (dsp != result)) { + printf("cmpgdu.eq.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_le_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_le_ob.c new file mode 100644 index 000000000..b3da09818 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_le_ob.c @@ -0,0 +1,44 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + + rs = 0x123456789abcdef0; + rt = 0x123456789abcdeff; + dspresult = 0xff; + result = 0xff; + + __asm("cmpgdu.le.ob %0, %2, %3\n\t" + "rddsp %1" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0xff); + + if ((rd != result) || (dspreg != dspresult)) { + printf("cmpgdu.le.ob error\n"); + return -1; + } + + rs = 0x113556789ABCDEF0; + rt = 0x123456789ABCDEFF; + result = 0xBE; + dspresult = 0xFE; + + __asm("cmpgdu.eq.ob %0, %2, %3\n\t" + "rddsp %1" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0xFF); + + if ((rd != result) || (dspreg != dspresult)) { + printf("cmpgdu.eq.ob error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_le_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_le_qb.c new file mode 100644 index 000000000..f0a60ea4e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_le_qb.c @@ -0,0 +1,48 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0F; + __asm + ("cmpgdu.le.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (rd != result) { + printf("cmpgdu.le.qb error\n"); + return -1; + } + if (dsp != result) { + printf("cmpgdu.le.qb error\n"); + return -1; + } + + rs = 0x11777066; + rt = 0x11707066; + result = 0x0B; + __asm + ("cmpgdu.le.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (rd != result) { + printf("cmpgdu.le.qb error\n"); + return -1; + } + if (dsp != result) { + printf("cmpgdu.le.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_ob.c new file mode 100644 index 000000000..d80b4e6ab --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_ob.c @@ -0,0 +1,44 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result, dspreg, dspresult; + + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x01; + result = 0x01; + + __asm("cmpgdu.lt.ob %0, %2, %3\n\t" + "rddsp %1" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0xFF); + + if ((rd != result) || (dspreg != dspresult)) { + printf("cmpgdu.lt.ob error\n"); + return -1; + } + + rs = 0x143356789ABCDEF0; + rt = 0x123456789ABCDEFF; + dspresult = 0x41; + result = 0x41; + + __asm("cmpgdu.lt.ob %0, %2, %3\n\t" + "rddsp %1" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 24) & 0xFF); + + if ((rd != result) || (dspreg != dspresult)) { + printf("cmpgdu.lt.ob error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_qb.c new file mode 100644 index 000000000..a71e4e307 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_qb.c @@ -0,0 +1,48 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long dsp; + long long result; + + rs = 0x11777066; + rt = 0x55AA70FF; + result = 0x0D; + __asm + ("cmpgdu.lt.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (rd != result) { + printf("cmpgdu.lt.qb error\n"); + return -1; + } + if (dsp != result) { + printf("cmpgdu.lt.qb error\n"); + return -1; + } + + rs = 0x11777066; + rt = 0x11777066; + result = 0x00; + __asm + ("cmpgdu.lt.qb %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 24) & 0x0F; + if (rd != result) { + printf("cmpgdu.lt.qb error\n"); + return -1; + } + if (dsp != result) { + printf("cmpgdu.lt.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dbalign.c b/qemu/tests/tcg/mips/mips64-dspr2/dbalign.c new file mode 100644 index 000000000..c7431b185 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dbalign.c @@ -0,0 +1,39 @@ +#include "io.h" + +int main(void) +{ + long long rt, rs; + long long res; + + rt = 0x1234567887654321; + rs = 0xabcd1234abcd1234; + + res = 0x34567887654321ab; + + asm ("dbalign %0, %1, 0x1\n" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("dbalign error\n"); + return -1; + } + + rt = 0x1234567887654321; + rs = 0xabcd1234abcd1234; + + res = 0x7887654321abcd12; + + asm ("dbalign %0, %1, 0x3\n" + : "=r"(rt) + : "r"(rs) + ); + + if (rt != res) { + printf("dbalign error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dpa_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/dpa_w_ph.c new file mode 100644 index 000000000..39dc99aa5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dpa_w_ph.c @@ -0,0 +1,47 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 5; + long long resulth, resultl; + + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x05; + resultl = 0x0302; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpa.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("1 dpa.w.ph error\n"); + return -1; + } + + ach = 6, acl = 7; + rs = 0xFFFF00FF; + rt = 0xFFFF0002; + resulth = 0x05; + resultl = 0xfffffffffffe0206; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpa.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if ((ach != resulth) || (acl != resultl)) { + printf("2 dpa.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dpa_w_qh.c b/qemu/tests/tcg/mips/mips64-dspr2/dpa_w_qh.c new file mode 100644 index 000000000..1411e44be --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dpa_w_qh.c @@ -0,0 +1,56 @@ +#include"io.h" +int main(void) +{ + long long rt, rs; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + + achi = 0x1; + acli = 0x1; + + rs = 0x0001000100010001; + rt = 0x0002000200020002; + + resh = 0x1; + resl = 0x9; + + asm("mthi %2, $ac1\t\n" + "mtlo %3, $ac1\t\n" + "dpa.w.qh $ac1, %4, %5\t\n" + "mfhi %0, $ac1\t\n" + "mflo %1, $ac1\t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 dpa.w.qh error\n"); + return -1; + } + + + achi = 0xffffffff; + acli = 0xaaaaaaaa; + + rs = 0xaaaabbbbccccdddd; + rt = 0x7777888899996666; + + resh = 0xffffffffffffffff; + resl = 0x320cdf02; + + asm("mthi %2, $ac1\t\n" + "mtlo %3, $ac1\t\n" + "dpa.w.qh $ac1, %4, %5\t\n" + "mfhi %0, $ac1\t\n" + "mflo %1, $ac1\t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + if ((acho != resh) || (aclo != resl)) { + printf("2 dpa.w.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dpaqx_s_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/dpaqx_s_w_ph.c new file mode 100644 index 000000000..51252fb98 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dpaqx_s_w_ph.c @@ -0,0 +1,97 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long ach = 5, acl = 5; + long long resulth, resultl, resultdsp; + + rs = 0x800000FF; + rt = 0x00018000; + resulth = 0x05; + resultl = 0xFFFFFFFF80000202; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if (dsp != resultdsp) { + printf("dpaqx_s.w.ph error\n"); + return -1; + } + if (ach != resulth) { + printf("dpaqx_s.w.ph error\n"); + return -1; + } + if (acl != resultl) { + printf("dpaqx_s.w.ph error\n"); + return -1; + } + + ach = 5; + acl = 5; + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x05; + resultl = 0x05FF; + /*********************************************************** + * Because of we set outflag at last time, although this + * time we set nothing, but it is stay the last time value. + **********************************************************/ + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if (dsp != resultdsp) { + printf("dpaqx_s.w.ph error\n"); + return -1; + } + if (ach != resulth) { + printf("dpaqx_s.w.ph error\n"); + return -1; + } + if (acl != resultl) { + printf("dpaqx_s.w.ph error\n"); + return -1; + } + + ach = 5; + acl = 5; + rs = 0x800000FF; + rt = 0x00028000; + resulth = 0x05; + resultl = 0xffffffff80000400; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if ((dsp != resultdsp) || (ach != resulth) || (acl != resultl)) { + printf("dpaqx_s.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dpaqx_sa_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/dpaqx_sa_w_ph.c new file mode 100644 index 000000000..18d6b3a98 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dpaqx_sa_w_ph.c @@ -0,0 +1,54 @@ +#include "io.h" + +int main() +{ + long long rs, rt, dsp; + long long ach = 5, acl = 5; + long long resulth, resultl, resultdsp; + + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x00; + resultl = 0x7FFFFFFF; + resultdsp = 0x01; + __asm + ("wrdsp %2\n\t" + "mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_sa.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "+r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((dsp >> (16 + 1) != resultdsp) || (ach != resulth) || + (acl != resultl)) { + printf("dpaqx_sa.w.ph errror\n"); + } + + ach = 9; + acl = 0xb; + rs = 0x800000FF; + rt = 0x00018000; + resulth = 0x00; + resultl = 0x7fffffff; + resultdsp = 0x01; + __asm + ("wrdsp %2\n\t" + "mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaqx_sa.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "+r"(dsp) + : "r"(rs), "r"(rt) + ); + if ((dsp >> (16 + 1) != resultdsp) || (ach != resulth) || + (acl != resultl)) { + printf("dpaqx_sa.w.ph errror\n"); + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dpax_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/dpax_w_ph.c new file mode 100644 index 000000000..9d595fc14 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dpax_w_ph.c @@ -0,0 +1,32 @@ +#include"io.h" + +int main(void) +{ + long rs, rt; + long ach = 5, acl = 5; + long resulth, resultl; + + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x05; + resultl = 0x0302; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpax.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if (ach != resulth) { + printf("dpax.w.ph error\n"); + return -1; + } + if (acl != resultl) { + printf("dpax.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dps_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/dps_w_ph.c new file mode 100644 index 000000000..99f292ecb --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dps_w_ph.c @@ -0,0 +1,28 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 5; + long long resulth, resultl; + + rs = 0x00FF00FF; + rt = 0x00010002; + resulth = 0x04; + resultl = 0xFFFFFFFFFFFFFFD08; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dps.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if (ach != resulth || acl != resultl) { + printf("dps.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dps_w_qh.c b/qemu/tests/tcg/mips/mips64-dspr2/dps_w_qh.c new file mode 100644 index 000000000..61277eb30 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dps_w_qh.c @@ -0,0 +1,55 @@ +#include "io.h" + +int main(void) +{ + long long rs, rt; + long long achi, acli; + long long acho, aclo; + long long resh, resl; + + rs = 0x0000000100000001; + rt = 0x0000000200000002; + achi = 0x1; + acli = 0x8; + + resh = 0x1; + resl = 0x4; + + asm ("mthi %2, $ac1\t\n" + "mtlo %3, $ac1\t\n" + "dps.w.qh $ac1, %4, %5\t\n" + "mfhi %0, $ac1\t\n" + "mflo %1, $ac1\t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 dps.w.qh error\n"); + return -1; + } + + rs = 0xaaaabbbbccccdddd; + rt = 0xaaaabbbbccccdddd; + + achi = 0x88888888; + achi = 0x55555555; + + resh = 0xfffffffff7777777; + resl = 0x0a38b181; + + asm ("mthi %2, $ac1\t\n" + "mtlo %3, $ac1\t\n" + "dps.w.qh $ac1, %4, %5\t\n" + "mfhi %0, $ac1\t\n" + "mflo %1, $ac1\t\n" + : "=r"(acho), "=r"(aclo) + : "r"(achi), "r"(acli), "r"(rs), "r"(rt) + ); + + if ((acho != resh) || (aclo != resl)) { + printf("1 dps.w.qh error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dpsqx_s_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/dpsqx_s_w_ph.c new file mode 100644 index 000000000..ba46a9269 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dpsqx_s_w_ph.c @@ -0,0 +1,55 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt, dsp; + long long ach = 5, acl = 5; + long long resulth, resultl, resultdsp; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x04; + resultl = 0xFFFFFFFFAEA3E09B; + resultdsp = 0x00; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if (dsp != resultdsp || ach != resulth || acl != resultl) { + printf("dpsqx_s.w.ph error\n"); + return -1; + } + + ach = 0x99f13005; + acl = 0x51730062; + rs = 0x80008000; + rt = 0x80008000; + + resulth = 0xffffffff99f13004; + resultl = 0x51730064; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsqx_s.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if (dsp != resultdsp || ach != resulth || acl != resultl) { + printf("dpsqx_s.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dpsqx_sa_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/dpsqx_sa_w_ph.c new file mode 100644 index 000000000..24c888134 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dpsqx_sa_w_ph.c @@ -0,0 +1,53 @@ +#include"io.h" +int main() +{ + long long rs, rt, dsp; + long long ach = 5, acl = 5; + long long resulth, resultl, resultdsp; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x00; + resultl = 0x7FFFFFFF; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsqx_sa.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if (dsp != resultdsp || ach != resulth || acl != resultl) { + printf("dpsqx_sa.w.ph error\n"); + return -1; + } + + ach = 0x8c0b354A; + acl = 0xbbc02249; + rs = 0x800023AD; + rt = 0x01648000; + resulth = 0xffffffffffffffff; + resultl = 0xffffffff80000000; + resultdsp = 0x01; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsqx_sa.w.ph $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + if (dsp != resultdsp || ach != resulth || acl != resultl) { + printf("dpsqx_sa.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/dpsx_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/dpsx_w_ph.c new file mode 100644 index 000000000..b6291b5eb --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/dpsx_w_ph.c @@ -0,0 +1,28 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt; + long long ach = 5, acl = 5; + long long resulth, resultl; + + rs = 0xBC0123AD; + rt = 0x01643721; + resulth = 0x04; + resultl = 0xFFFFFFFFD751F050; + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpsx.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if (ach != resulth || acl != resultl) { + printf("dpsx.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/head.S b/qemu/tests/tcg/mips/mips64-dspr2/head.S new file mode 100644 index 000000000..9a099ae42 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/head.S @@ -0,0 +1,16 @@ +/* + * Startup Code for MIPS64 CPU-core + * + */ +.text +.globl _start +.align 4 +_start: + ori $2, $2, 0xffff + sll $2, $2, 16 + ori $2, $2, 0xffff + mtc0 $2, $12, 0 + jal main + +end: + b end diff --git a/qemu/tests/tcg/mips/mips64-dspr2/io.h b/qemu/tests/tcg/mips/mips64-dspr2/io.h new file mode 100644 index 000000000..b7db61d7c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/io.h @@ -0,0 +1,22 @@ +#ifndef _ASM_IO_H +#define _ASM_IO_H +extern int printf(const char *fmt, ...); +extern unsigned long get_ticks(void); + +#define _read(source) \ +({ unsigned long __res; \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __read(source) \ +({ unsigned long __res; \ + __asm__ __volatile__( \ + "move\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#endif diff --git a/qemu/tests/tcg/mips/mips64-dspr2/mips_boot.lds b/qemu/tests/tcg/mips/mips64-dspr2/mips_boot.lds new file mode 100644 index 000000000..bd7c0c0f3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/mips_boot.lds @@ -0,0 +1,31 @@ +OUTPUT_ARCH(mips) +SECTIONS +{ + . = 0xffffffff80100000; + . = ALIGN((1 << 13)); + .text : + { + *(.text) + *(.rodata) + *(.rodata.*) + } + + __init_begin = .; + . = ALIGN((1 << 12)); + .init.text : AT(ADDR(.init.text) - 0) + { + *(.init.text) + } + .init.data : AT(ADDR(.init.data) - 0) + { + *(.init.data) + } + . = ALIGN((1 << 12)); + __init_end = .; + + . = ALIGN((1 << 13)); + .data : + { + *(.data) + } +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/mul_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/mul_ph.c new file mode 100644 index 000000000..5a3d05cb2 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/mul_ph.c @@ -0,0 +1,50 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x03FB1234; + rt = 0x0BCC4321; + result = 0xFFFFFFFFF504F4B4; + resultdsp = 1; + + __asm + ("mul.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if (rd != result || dsp != resultdsp) { + printf("mul.ph wrong\n"); + return -1; + } + + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 0x00210010; + rt = 0x00110005; + result = 0x2310050; + resultdsp = 0; + + __asm + ("mul.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if (rd != result || dsp != resultdsp) { + printf("mul.ph wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/mul_s_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/mul_s_ph.c new file mode 100644 index 000000000..7c8b2c718 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/mul_s_ph.c @@ -0,0 +1,67 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x03FB1234; + rt = 0x0BCC4321; + result = 0x7fff7FFF; + resultdsp = 1; + + __asm + ("mul_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if (rd != result || dsp != resultdsp) { + printf("1 mul_s.ph error\n"); + return -1; + } + + rs = 0x7fffff00; + rt = 0xff007fff; + result = 0xffffffff80008000; + resultdsp = 1; + + __asm + ("mul_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if (rd != result || dsp != resultdsp) { + printf("2 mul_s.ph error\n"); + return -1; + } + + dsp = 0; + __asm + ("wrdsp %0\n\t" + : + : "r"(dsp) + ); + + rs = 0x00320001; + rt = 0x00210002; + result = 0x06720002; + resultdsp = 0; + + __asm + ("mul_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if (rd != result || dsp != resultdsp) { + printf("3 mul_s.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/mulq_rs_w.c b/qemu/tests/tcg/mips/mips64-dspr2/mulq_rs_w.c new file mode 100644 index 000000000..ffdc66d54 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/mulq_rs_w.c @@ -0,0 +1,40 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0xFFFFFFFF80005555; + + __asm + ("mulq_rs.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("mulq_rs.w error!\n"); + return -1; + } + + rs = 0x80000000; + rt = 0x80000000; + result = 0x7FFFFFFF; + resultdsp = 1; + + __asm + ("mulq_rs.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if (rd != result || dsp != resultdsp) { + printf("mulq_rs.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/mulq_s_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/mulq_s_ph.c new file mode 100644 index 000000000..b8c20c68c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/mulq_s_ph.c @@ -0,0 +1,26 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0x7FFF098B; + resultdsp = 1; + + __asm + ("mulq_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if (rd != result || dsp != resultdsp) { + printf("mulq_s.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/mulq_s_w.c b/qemu/tests/tcg/mips/mips64-dspr2/mulq_s_w.c new file mode 100644 index 000000000..db74b713f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/mulq_s_w.c @@ -0,0 +1,40 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x80001234; + rt = 0x80004321; + result = 0xFFFFFFFF80005555; + + __asm + ("mulq_s.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("mulq_s.w error\n"); + return -1; + } + + rs = 0x80000000; + rt = 0x80000000; + result = 0x7FFFFFFF; + resultdsp = 1; + + __asm + ("mulq_s.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + if (rd != result || dsp != resultdsp) { + printf("mulq_s.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/mulsa_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/mulsa_w_ph.c new file mode 100644 index 000000000..5b22a60a8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/mulsa_w_ph.c @@ -0,0 +1,30 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt, ach, acl; + long long resulth, resultl; + + ach = 0x05; + acl = 0x00BBDDCC; + rs = 0x80001234; + rt = 0x80004321; + resulth = 0x05; + resultl = 0x3BF5E918; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "mulsa.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if (ach != resulth || acl != resultl) { + printf("mulsa.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/mulsaq_s_w_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/mulsaq_s_w_ph.c new file mode 100644 index 000000000..835a73d47 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/mulsaq_s_w_ph.c @@ -0,0 +1,30 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt, ach, acl; + long long resulth, resultl; + + ach = 0x05; + acl = 0x00BBDDCC; + rs = 0x80001234; + rt = 0x80004321; + resulth = 0x05; + resultl = 0x772ff463; + + __asm + ("mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "mulsaq_s.w.ph $ac1, %2, %3\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + : "+r"(ach), "+r"(acl) + : "r"(rs), "r"(rt) + ); + if (ach != resulth || acl != resultl) { + printf("mulsaq_s.w.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/precr_qb_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/precr_qb_ph.c new file mode 100644 index 000000000..80d5e8dce --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/precr_qb_ph.c @@ -0,0 +1,23 @@ +#include"io.h" + +int main() +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x34786521; + + __asm + ("precr.qb.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (result != rd) { + printf("precr.qb.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/precr_sra_ph_w.c b/qemu/tests/tcg/mips/mips64-dspr2/precr_sra_ph_w.c new file mode 100644 index 000000000..b1d7bcdf8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/precr_sra_ph_w.c @@ -0,0 +1,37 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x43215678; + + __asm + ("precr_sra.ph.w %0, %1, 0x00\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (result != rt) { + printf("precr_sra.ph.w error\n"); + return -1; + } + + rs = 0x12345678; + rt = 0x87654321; + result = 0xFFFFFFFFFFFF0000; + + __asm + ("precr_sra.ph.w %0, %1, 0x1F\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (result != rt) { + printf("precr_sra.ph.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/precr_sra_r_ph_w.c b/qemu/tests/tcg/mips/mips64-dspr2/precr_sra_r_ph_w.c new file mode 100644 index 000000000..62d220dca --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/precr_sra_r_ph_w.c @@ -0,0 +1,37 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x43215678; + + __asm + ("precr_sra_r.ph.w %0, %1, 0x00\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (result != rt) { + printf("precr_sra_r.ph.w error\n"); + return -1; + } + + rs = 0x12345678; + rt = 0x87654321; + result = 0xFFFFFFFFFFFF0000; + + __asm + ("precr_sra_r.ph.w %0, %1, 0x1F\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (result != rt) { + printf("precr_sra_r.ph.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/prepend.c b/qemu/tests/tcg/mips/mips64-dspr2/prepend.c new file mode 100644 index 000000000..4ab083e96 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/prepend.c @@ -0,0 +1,35 @@ +#include"io.h" + +int main(void) +{ + long long rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0xFFFFFFFF87654321; + __asm + ("prepend %0, %1, 0x00\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (rt != result) { + printf("prepend error\n"); + return -1; + } + + rs = 0x12345678; + rt = 0x87654321; + result = 0xFFFFFFFFACF10ECA; + __asm + ("prepend %0, %1, 0x0F\n\t" + : "+r"(rt) + : "r"(rs) + ); + if (rt != result) { + printf("prepend error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/printf.c b/qemu/tests/tcg/mips/mips64-dspr2/printf.c new file mode 100644 index 000000000..cf8676d39 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/printf.c @@ -0,0 +1,266 @@ + +typedef unsigned long va_list; + +#define ACC 4 +#define __read(source) \ +({ va_list __res; \ + __asm__ __volatile__( \ + "move\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +enum format_type { + FORMAT_TYPE_NONE, + FORMAT_TYPE_HEX, + FORMAT_TYPE_ULONG, + FORMAT_TYPE_FLOAT +}; + +struct printf_spec { + char type; +}; + +static int format_decode(char *fmt, struct printf_spec *spec) +{ + char *start = fmt; + + for (; *fmt ; ++fmt) { + if (*fmt == '%') { + break; + } + } + + switch (*++fmt) { + case 'x': + spec->type = FORMAT_TYPE_HEX; + break; + + case 'd': + spec->type = FORMAT_TYPE_ULONG; + break; + + case 'f': + spec->type = FORMAT_TYPE_FLOAT; + break; + + default: + spec->type = FORMAT_TYPE_NONE; + } + + return ++fmt - start; +} + +void *memcpy(void *dest, void *src, int n) +{ + int i; + char *s = src; + char *d = dest; + + for (i = 0; i < n; i++) { + d[i] = s[i]; + } + return dest; +} + +char *number(char *buf, va_list num) +{ + int i; + char *str = buf; + static char digits[16] = "0123456789abcdef"; + str = str + sizeof(num) * 2; + + for (i = 0; i < sizeof(num) * 2; i++) { + *--str = digits[num & 15]; + num >>= 4; + } + + return buf + sizeof(num) * 2; +} + +char *__number(char *buf, va_list num) +{ + int i; + va_list mm = num; + char *str = buf; + + if (!num) { + *str++ = '0'; + return str; + } + + for (i = 0; mm; mm = mm/10, i++) { + /* Do nothing. */ + } + + str = str + i; + + while (num) { + *--str = num % 10 + 48; + num = num / 10; + } + + return str + i; +} + +va_list modf(va_list args, va_list *integer, va_list *num) +{ + int i; + double dot_v = 0; + va_list E, DOT, DOT_V; + + if (!args) { + return 0; + } + + for (i = 0, args = args << 1 >> 1; i < 52; i++) { + if ((args >> i) & 0x1) { + break; + } + } + + *integer = 0; + + if ((args >> 56 != 0x3f) || (args >> 52 == 0x3ff)) { + E = (args >> 52) - 1023; + DOT = 52 - E - i; + DOT_V = args << (12 + E) >> (12 + E) >> i; + *integer = ((args << 12 >> 12) >> (i + DOT)) | (1 << E); + } else { + E = ~((args >> 52) - 1023) + 1; + DOT_V = args << 12 >> 12; + + dot_v += 1.0 / (1 << E); + + for (i = 1; i <= 16; i++) { + if ((DOT_V >> (52 - i)) & 0x1) { + dot_v += 1.0 / (1 << E + i); + } + } + + for (i = 1, E = 0; i <= ACC; i++) { + dot_v *= 10; + if (!(va_list)dot_v) { + E++; + } + } + + *num = E; + + return dot_v; + } + + if (args & 0xf) { + for (i = 1; i <= 16; i++) { + if ((DOT_V >> (DOT - i)) & 0x1) { + dot_v += 1.0 / (1 << i); + } + } + + for (i = 1, E = 0; i <= ACC; i++) { + dot_v *= 10; + if (!(va_list)dot_v) { + E++; + } + } + + *num = E; + + return dot_v; + } else if (DOT) { + for (i = 1; i <= DOT; i++) { + if ((DOT_V >> (DOT - i)) & 0x1) { + dot_v += 1.0 / (1 << i); + } + } + + for (i = 1; i <= ACC; i++) { + dot_v = dot_v * 10; + } + + return dot_v; + } + + return 0; +} + +int vsnprintf(char *buf, int size, char *fmt, va_list args) +{ + char *str, *mm; + struct printf_spec spec = {0}; + + str = mm = buf; + + while (*fmt) { + char *old_fmt = fmt; + int read = format_decode(fmt, &spec); + + fmt += read; + + switch (spec.type) { + case FORMAT_TYPE_NONE: { + memcpy(str, old_fmt, read); + str += read; + break; + } + case FORMAT_TYPE_HEX: { + memcpy(str, old_fmt, read); + str = number(str + read, args); + for (; *mm ; ++mm) { + if (*mm == '%') { + *mm = '0'; + break; + } + } + break; + } + case FORMAT_TYPE_ULONG: { + memcpy(str, old_fmt, read - 2); + str = __number(str + read - 2, args); + break; + } + case FORMAT_TYPE_FLOAT: { + va_list integer, dot_v, num; + dot_v = modf(args, &integer, &num); + memcpy(str, old_fmt, read - 2); + str += read - 2; + if ((args >> 63 & 0x1)) { + *str++ = '-'; + } + str = __number(str, integer); + if (dot_v) { + *str++ = '.'; + while (num--) { + *str++ = '0'; + } + str = __number(str, dot_v); + } + break; + } + } + } + *str = '\0'; + + return str - buf; +} + +static void serial_out(char *str) +{ + while (*str) { + *(char *)0xffffffffb80003f8 = *str++; + } +} + +int vprintf(char *fmt, va_list args) +{ + int printed_len = 0; + static char printf_buf[512]; + printed_len = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args); + serial_out(printf_buf); + return printed_len; +} + +int printf(char *fmt, ...) +{ + return vprintf(fmt, __read($5)); +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/shra_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/shra_qb.c new file mode 100644 index 000000000..cac310235 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/shra_qb.c @@ -0,0 +1,35 @@ +#include"io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x12345678; + result = 0x02060A0F; + + __asm + ("shra.qb %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shra.qb error\n"); + return -1; + } + + rt = 0x87654321; + result = 0xFFFFFFFFF00C0804; + + __asm + ("shra.qb %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shra.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/shra_r_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/shra_r_qb.c new file mode 100644 index 000000000..9c64f75bd --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/shra_r_qb.c @@ -0,0 +1,35 @@ +#include "io.h" + +int main() +{ + int rd, rt; + int result; + + rt = 0x12345678; + result = 0x02070B0F; + + __asm + ("shra_r.qb %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shra_r.qb wrong\n"); + return -1; + } + + rt = 0x87654321; + result = 0xF10D0804; + + __asm + ("shra_r.qb %0, %1, 0x03\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shra_r.qb wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/shrav_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/shrav_ob.c new file mode 100644 index 000000000..fbdfbab35 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/shrav_ob.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs; + long long res; + + rt = 0x1234567887654321; + rs = 0x4; + res = 0xf1f3f5f7f8060402; + + asm ("shrav.ob %0, %1, %2" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shra.ob error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/shrav_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/shrav_qb.c new file mode 100644 index 000000000..a716203d8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/shrav_qb.c @@ -0,0 +1,37 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x03; + rt = 0x12345678; + result = 0x02060A0F; + + __asm + ("shrav.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrav.qb error\n"); + return -1; + } + + rs = 0x03; + rt = 0x87654321; + result = 0xFFFFFFFFF00C0804; + + __asm + ("shrav.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrav.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/shrav_r_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/shrav_r_ob.c new file mode 100644 index 000000000..b80100a7c --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/shrav_r_ob.c @@ -0,0 +1,22 @@ +#include "io.h" + +int main(void) +{ + long long rd, rt, rs; + long long res; + + rt = 0x1234567887654321; + rs = 0x4; + res = 0xe3e7ebf0f1ede9e5; + + asm ("shrav_r.ob %0, %1, %2" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + + if (rd != res) { + printf("shra_r.ob error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/shrav_r_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/shrav_r_qb.c new file mode 100644 index 000000000..009080b2a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/shrav_r_qb.c @@ -0,0 +1,37 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x03; + rt = 0x12345678; + result = 0x02070B0F; + + __asm + ("shrav_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrav_r.qb error\n"); + return -1; + } + + rs = 0x03; + rt = 0x87654321; + result = 0xFFFFFFFFF10D0804; + + __asm + ("shrav_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrav_r.qb error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/shrl_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/shrl_ph.c new file mode 100644 index 000000000..e32d97662 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/shrl_ph.c @@ -0,0 +1,22 @@ +#include"io.h" + +int main(void) +{ + long long rd, rt; + long long result; + + rt = 0x12345678; + result = 0x009102B3; + + __asm + ("shrl.ph %0, %1, 0x05\n\t" + : "=r"(rd) + : "r"(rt) + ); + if (rd != result) { + printf("shrl.ph error!\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/shrlv_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/shrlv_ph.c new file mode 100644 index 000000000..58c5488b5 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/shrlv_ph.c @@ -0,0 +1,23 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x05; + rt = 0x12345678; + result = 0x009102B3; + + __asm + ("shrlv.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rt), "r"(rs) + ); + if (rd != result) { + printf("shrlv.ph error!\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subqh_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/subqh_ph.c new file mode 100644 index 000000000..90374019a --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subqh_ph.c @@ -0,0 +1,23 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x456709AB; + + __asm + ("subqh.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("subqh.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subqh_r_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/subqh_r_ph.c new file mode 100644 index 000000000..b8f9d2fee --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subqh_r_ph.c @@ -0,0 +1,23 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x456809AC; + + __asm + ("subqh_r.ph %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("subqh_r.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subqh_r_w.c b/qemu/tests/tcg/mips/mips64-dspr2/subqh_r_w.c new file mode 100644 index 000000000..b025e40a3 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subqh_r_w.c @@ -0,0 +1,23 @@ +#include"io.h" + +int main() +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x456789AC; + + __asm + ("subqh_r.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("subqh_r.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subqh_w.c b/qemu/tests/tcg/mips/mips64-dspr2/subqh_w.c new file mode 100644 index 000000000..65f17603d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subqh_w.c @@ -0,0 +1,23 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x456789AB; + + __asm + ("subqh.w %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("subqh.w error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subu_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/subu_ph.c new file mode 100644 index 000000000..60a6b1b7d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subu_ph.c @@ -0,0 +1,26 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x87654321; + rt = 0x12345678; + result = 0x7531ECA9; + resultdsp = 0x01; + + __asm + ("subu.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + if (dsp != resultdsp || rd != result) { + printf("subu.ph error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subu_qh.c b/qemu/tests/tcg/mips/mips64-dspr2/subu_qh.c new file mode 100644 index 000000000..911cb349d --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subu_qh.c @@ -0,0 +1,24 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dspreg, result, dspresult; + rs = 0x123456789ABCDEF0; + rt = 0x123456789ABCDEF1; + result = 0x000000000000000F; + dspresult = 0x01; + + __asm("subu.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("subu.qh error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subu_s_ph.c b/qemu/tests/tcg/mips/mips64-dspr2/subu_s_ph.c new file mode 100644 index 000000000..ae32cc06f --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subu_s_ph.c @@ -0,0 +1,25 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt, dsp; + long long result, resultdsp; + + rs = 0x87654321; + rt = 0x12345678; + result = 0x75310000; + resultdsp = 0x01; + + __asm + ("subu_s.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 20) & 0x01; + if (dsp != resultdsp || rd != result) { + printf("subu_s.ph error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subu_s_qh.c b/qemu/tests/tcg/mips/mips64-dspr2/subu_s_qh.c new file mode 100644 index 000000000..de7a29e77 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subu_s_qh.c @@ -0,0 +1,42 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, dspreg, result, dspresult; + rs = 0x1111111111111111; + rt = 0x2222222222222222; + result = 0x1111111111111111; + dspresult = 0x00; + + __asm("subu_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("subu_s.qh error\n\t"); + return -1; + } + + + rs = 0x8888888888888888; + rt = 0xa888a888a888a888; + result = 0x0000000000000000; + dspresult = 0x01; + + __asm("subu_s.qh %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dspreg) + : "r"(rs), "r"(rt) + ); + + dspreg = ((dspreg >> 20) & 0x01); + if ((rd != result) || (dspreg != dspresult)) { + printf("subu_s.qh error\n\t"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subuh_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/subuh_ob.c new file mode 100644 index 000000000..3fc452bf8 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subuh_ob.c @@ -0,0 +1,36 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result; + + rd = 0x0; + rs = 0x246856789ABCDEF0; + rt = 0x123456789ABCDEF0; + result = 0x091A000000000000; + + __asm("subuh.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("subuh.ob error\n"); + return -1; + } + + rs = 0x246856789ABCDEF0; + rt = 0x1131517191B1D1F1; + result = 0x1b4f2d2d51637577; + + __asm("subuh.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("subuh.ob error\n"); + return -1; + } + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subuh_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/subuh_qb.c new file mode 100644 index 000000000..aac7a834e --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subuh_qb.c @@ -0,0 +1,23 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0xC5E7092B; + + __asm + ("subuh.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("subuh.qb wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subuh_r_ob.c b/qemu/tests/tcg/mips/mips64-dspr2/subuh_r_ob.c new file mode 100644 index 000000000..fc20ffd09 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subuh_r_ob.c @@ -0,0 +1,23 @@ +#include "io.h" + +int main(void) +{ + long long rd, rs, rt, result; + + rd = 0x0; + rs = 0x246956789ABCDEF0; + rt = 0x123456789ABCDEF0; + result = 0x091B000000000000; + + __asm("subuh.ob %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + + if (rd != result) { + printf("subuh.ob error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/mips/mips64-dspr2/subuh_r_qb.c b/qemu/tests/tcg/mips/mips64-dspr2/subuh_r_qb.c new file mode 100644 index 000000000..66d468044 --- /dev/null +++ b/qemu/tests/tcg/mips/mips64-dspr2/subuh_r_qb.c @@ -0,0 +1,37 @@ +#include"io.h" + +int main(void) +{ + long long rd, rs, rt; + long long result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0xC6E80A2C; + + __asm + ("subuh_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("1 subuh_r.qb wrong\n"); + return -1; + } + + rs = 0xBEFC292A; + rt = 0x9205C1B4; + result = 0x167cb4bb; + + __asm + ("subuh_r.qb %0, %1, %2\n\t" + : "=r"(rd) + : "r"(rs), "r"(rt) + ); + if (rd != result) { + printf("2 subuh_r.qb wrong\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/Makefile b/qemu/tests/tcg/openrisc/Makefile new file mode 100644 index 000000000..7e6588876 --- /dev/null +++ b/qemu/tests/tcg/openrisc/Makefile @@ -0,0 +1,71 @@ +-include ../../config-host.mak + +CROSS = or32-linux- + +SIM = qemu-or32 + +CC = $(CROSS)gcc + +TESTCASES = test_add.tst +TESTCASES += test_sub.tst +TESTCASES += test_addc.tst +TESTCASES += test_addi.tst +TESTCASES += test_addic.tst +TESTCASES += test_and_or.tst +TESTCASES += test_bf.tst +TESTCASES += test_bnf.tst +TESTCASES += test_div.tst +TESTCASES += test_divu.tst +TESTCASES += test_extx.tst +TESTCASES += test_fx.tst +TESTCASES += test_jal.tst +TESTCASES += test_j.tst +TESTCASES += test_lf_div.tst +TESTCASES += test_lf_eqs.tst +TESTCASES += test_lf_ges.tst +TESTCASES += test_lf_gts.tst +TESTCASES += test_lf_les.tst +TESTCASES += test_lf_lts.tst +TESTCASES += test_lf_mul.tst +TESTCASES += test_lf_nes.tst +TESTCASES += test_lf_rem.tst +TESTCASES += test_lf_sub.tst +TESTCASES += test_lf_add.tst +TESTCASES += test_logic.tst +TESTCASES += test_lx.tst +TESTCASES += test_movhi.tst +TESTCASES += test_mul.tst +TESTCASES += test_mulu.tst +TESTCASES += test_muli.tst +TESTCASES += test_sfeq.tst +TESTCASES += test_sfeqi.tst +TESTCASES += test_sfges.tst +TESTCASES += test_sfgesi.tst +TESTCASES += test_sfgeu.tst +TESTCASES += test_sfgeui.tst +TESTCASES += test_sfgts.tst +TESTCASES += test_sfgtsi.tst +TESTCASES += test_sfgtu.tst +TESTCASES += test_sfgtui.tst +TESTCASES += test_sfles.tst +TESTCASES += test_sflesi.tst +TESTCASES += test_sfleu.tst +TESTCASES += test_sfleui.tst +TESTCASES += test_sflts.tst +TESTCASES += test_sfltsi.tst +TESTCASES += test_sfltu.tst +TESTCASES += test_sfltui.tst +TESTCASES += test_sfne.tst +TESTCASES += test_sfnei.tst + +all: $(TESTCASES) + +%.tst: %.c + $(CC) -static $< -o $@ + + +check: $(TESTCASES) + @for case in $(TESTCASES); do $(SIM) $$case; echo $$case pass!; sleep 0.2; done + +clean: + $(RM) -rf $(TESTCASES) diff --git a/qemu/tests/tcg/openrisc/test_add.c b/qemu/tests/tcg/openrisc/test_add.c new file mode 100644 index 000000000..3d23592e7 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_add.c @@ -0,0 +1,43 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, d; + int result; + + a = 0x100; + b = 0x100; + result = 0x200; + __asm + ("l.add %0, %0, %1\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("add error\n"); + return -1; + } + + a = 0xffff; + b = 0x1; + result = 0x10000; + __asm + ("l.add %0, %0, %1\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("add error\n"); + return -1; + } + + a = 0x7fffffff; + b = 0x1; + __asm + ("l.add %0, %1, %2\n\t" + : "=r"(d) + : "r"(b), "r"(a) + ); + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_addc.c b/qemu/tests/tcg/openrisc/test_addc.c new file mode 100644 index 000000000..a8f756a69 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_addc.c @@ -0,0 +1,40 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + b = 0x01; + c = 0xffffffff; + result = 0; + __asm + ("l.add r1, r1, r0\n\t" /* clear carry */ + "l.addc %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("first addc error\n"); + return -1; + } + + b = 0x01; + c = 0xffffffff; + result = 0x80000001; + __asm + ("l.add r1, r1, r0\n\t" /* clear carry */ + "l.addc %0, %1, %2\n\t" + "l.movhi %2, 0x7fff\n\t" + "l.ori %2, %2, 0xffff\n\t" + "l.addc %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("addc error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_addi.c b/qemu/tests/tcg/openrisc/test_addi.c new file mode 100644 index 000000000..bbf5a5ffa --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_addi.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + b = 0x01; + result = 0x00; + __asm + ("l.addi %0, %1, 0xffff\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("addi error\n\t"); + return -1; + } + + b = 0x010000; + result = 0xffff; + __asm + ("l.addi %0, %1, 0xffff\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("addi error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_addic.c b/qemu/tests/tcg/openrisc/test_addic.c new file mode 100644 index 000000000..857aaa133 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_addic.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + a = 1; + result = 0x0; + __asm + ("l.add r1, r1, r0\n\t" /* clear carry */ + "l.addic %0, %0, 0xffff\n\t" + : "+r"(a) + ); + if (a != result) { + printf("first addic error\n"); + return -1; + } + + a = -1; + result = 0x201; + __asm + ("l.add r1, r1, r0\n\t" /* clear carry */ + "l.addic %0, %0, 0x1\n\t" + "l.ori %0, r0, 0x100\n\t" + "l.addic %0, %0, 0x100\n\t" + : "+r"(a) + ); + if (a != result) { + printf("second addic error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_and_or.c b/qemu/tests/tcg/openrisc/test_and_or.c new file mode 100644 index 000000000..810d868c7 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_and_or.c @@ -0,0 +1,65 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + b = 0x2; + c = 0x1; + result = 0; + __asm + ("l.and %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("and error\n"); + return -1; + } + + result = 0x2; + __asm + ("l.andi %0, %1, 0x3\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("andi error %x\n", a); + return -1; + } + + result = 0x3; + __asm + ("l.or %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("or error\n"); + return -1; + } + + result = 0x3; + __asm + ("l.xor %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("xor error\n"); + return -1; + } + + __asm + ("l.xori %0, %1, 0x1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("xori error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_bf.c b/qemu/tests/tcg/openrisc/test_bf.c new file mode 100644 index 000000000..79f3fb99a --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_bf.c @@ -0,0 +1,47 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + a = 0; + b = 10; + c = 11; + result = 0x2; + __asm + ("1:\n\t" + "l.addi %1, %1, 0x01\n\t" + "l.addi %0, %0, 0x01\n\t" + "l.sfeq %1, %2\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("sfeq error\n"); + return -1; + } + + a = 0x00; + b = 0x11; + c = 0x11; + result = 0x01; + __asm + ("1:\n\t" + "l.addi %1, %1, 0x01\n\t" + "l.addi %0, %0, 0x01\n\t" + "l.sfeq %1, %2\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("sfeq error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_bnf.c b/qemu/tests/tcg/openrisc/test_bnf.c new file mode 100644 index 000000000..f716215f1 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_bnf.c @@ -0,0 +1,51 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + b = 0; + result = 0x3; + __asm + ("l.sfeqi %1, 0x0\n\t" + "l.bnf 1f\n\t" + "l.nop\n\t" + "\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "\n\t" + "1:\n\t" + "l.addi %0, %0, 0x1\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("l.bnf error\n"); + return -1; + } + + a = 0; + b = 0; + result = 1; + __asm + ("l.sfeqi %1, 0x1\n\t" + "l.bnf 1f\n\t" + "l.nop\n\t" + "\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "\n\t" + "1:\n\t" + "l.addi %0, %0, 0x1\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("l.bnf error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_div.c b/qemu/tests/tcg/openrisc/test_div.c new file mode 100644 index 000000000..9b65f6e67 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_div.c @@ -0,0 +1,54 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + b = 0x120; + c = 0x4; + result = 0x48; + __asm + ("l.div %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("div error\n"); + return -1; + } + + result = 0x4; + __asm + ("l.div %0, %1, %0\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("div error\n"); + return -1; + } + + b = 0xffffffff; + c = 0x80000000; + result = 0; + __asm + ("l.div %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("div error\n"); + return -1; + } + + b = 0x80000000; + c = 0xffffffff; + __asm + ("l.div %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_divu.c b/qemu/tests/tcg/openrisc/test_divu.c new file mode 100644 index 000000000..bff9e3ea5 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_divu.c @@ -0,0 +1,34 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + b = 0x120; + c = 0x4; + result = 0x48; + + __asm + ("l.divu %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("divu error\n"); + return -1; + } + + result = 0x4; + __asm + ("l.divu %0, %1, %0\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("divu error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_extx.c b/qemu/tests/tcg/openrisc/test_extx.c new file mode 100644 index 000000000..09221484a --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_extx.c @@ -0,0 +1,78 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + b = 0x83; + result = 0xffffff83; + __asm + ("l.extbs %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("extbs error\n"); + return -1; + } + + result = 0x83; + __asm + ("l.extbz %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("extbz error\n"); + return -1; + } + + b = 0x8083; + result = 0xffff8083; + __asm + ("l.exths %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("exths error\n"); + return -1; + } + + result = 0x8083; + __asm + ("l.exthz %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("exthz error\n"); + return -1; + } + + b = 0x11; + result = 0x11; + __asm + ("l.extws %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + + if (a != result) { + printf("extws error\n"); + return -1; + } + + __asm + ("l.extwz %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("extwz error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_fx.c b/qemu/tests/tcg/openrisc/test_fx.c new file mode 100644 index 000000000..df86000d9 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_fx.c @@ -0,0 +1,57 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + b = 0x123; + result = 1; + __asm + ("l.ff1 %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("ff1 error\n"); + return -1; + } + + b = 0x0; + result = 0; + __asm + ("l.ff1 %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("ff1 error\n"); + return -1; + } + + b = 0x123; + result = 9; + __asm + ("l.fl1 %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("fl1 error\n"); + return -1; + } + + b = 0x0; + result = 0; + __asm + ("l.fl1 %0, %1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("fl1 error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_j.c b/qemu/tests/tcg/openrisc/test_j.c new file mode 100644 index 000000000..9ddf8bfbb --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_j.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + a = 0; + result = 2; + __asm + ("l.addi %0, %0, 1\n\t" + "l.j j\n\t" + "l.nop\n\t" + "l.addi %0, %0, 1\n\t" + "l.nop\n\t" + "j:\n\t" + "l.addi %0, %0, 1\n\t" + : "+r"(a) + ); + if (a != result) { + printf("j error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_jal.c b/qemu/tests/tcg/openrisc/test_jal.c new file mode 100644 index 000000000..7e2da4016 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_jal.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + a = 0; + result = 2; + __asm + ("l.addi %0, %0, 1\n\t" + "l.jal jal\n\t" + "l.nop\n\t" + "l.addi %0, %0, 1\n\t" + "l.nop\n\t" + "jal:\n\t" + "l.addi %0, %0, 1\n\t" + : "+r"(a) + ); + if (a != result) { + printf("jal error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_add.c b/qemu/tests/tcg/openrisc/test_lf_add.c new file mode 100644 index 000000000..e00212dad --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_add.c @@ -0,0 +1,39 @@ +#include <stdio.h> + +int main(void) +{ + float a, b; + float res2; + + a = 1.5; + b = 2.5; + res2 = 4.0; + __asm + ("lf.add.s %0, %0, %1\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != res2) { + printf("lf.add.s error, %f\n", a); + return -1; + } + +/* double c, d; + double res1; + + c = 1.5; + d = 1.5; + res1 = 3.00; + __asm + ("lf.add.d %0, %1, %2\n\t" + : "+r"(c) + : "r"(d) + ); + + if ((e - res1) > 0.002) { + printf("lf.add.d error, %f\n", e - res1); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_div.c b/qemu/tests/tcg/openrisc/test_lf_div.c new file mode 100644 index 000000000..70b5d1c17 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_div.c @@ -0,0 +1,37 @@ +#include <stdio.h> + +int main(void) +{ + float a, b, c; + float result; + + b = 1.5; + c = 0.5; + result = 3.0; + __asm + ("lf.div.s %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.div.s error\n"); + return -1; + } + +/* double a, b, c, res; + + b = 0x80000000; + c = 0x40; + result = 0x2000000; + __asm + ("lf.div.d %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.div.d error\n"); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_eqs.c b/qemu/tests/tcg/openrisc/test_lf_eqs.c new file mode 100644 index 000000000..a176bd6fe --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_eqs.c @@ -0,0 +1,88 @@ +#include <stdio.h> + +int main(void) +{ + int a, result; + float b, c; + + a = 0x1; + b = 122.5; + c = 123.5; + result = 0x3; + __asm + ("lfeqd:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfeq.s %1, %2\n\t" + "l.bf lfeqd\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfeq.s error\n"); + return -1; + } + + b = 13.5; + c = 13.5; + result = 0x3; + __asm + ("lf.sfeq.s %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi r4, r4, 0x1\n\t" + "1:\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfeq.s error\n"); + return -1; + } + +/* double b, c; + double result; + int a; + + a = 0x1; + b = 122.5; + c = 133.5; + result = 0x3; + + __asm + ("lfeqd:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfeq.d %1, %2\n\t" + "l.bf lfeqd\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfeq.d error\n"); + return -1; + } + + double c, d, res; + int e = 0; + c = 11.5; + d = 11.5; + res = 1; + __asm + ("lf.sfeq.d %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + "1:\n\t" + : "+r"(e) + : "r"(c), "r"(d) + ); + if (e != res) { + printf("lf.sfeq.d error\n"); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_ges.c b/qemu/tests/tcg/openrisc/test_lf_ges.c new file mode 100644 index 000000000..98e7f50b6 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_ges.c @@ -0,0 +1,88 @@ +#include <stdio.h> + +int main(void) +{ + int a, result; + float b, c; + + a = 0; + b = 122.5; + c = 123.5; + result = 0x1; + __asm + ("lfges:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfge.s %1, %2\n\t" + "l.bf lfges\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfge.s error\n"); + return -1; + } + + b = 133.5; + c = 13.5; + result = 0x3; + __asm + ("l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfge.s %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "1:\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfge.s error\n"); + return -1; + } + +/* int a, result; + double b, c; + + a = 0x1; + b = 122.5; + c = 123.5; + result = 0x2; + __asm + ("lfged:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfge.d %1, %2\n\t" + "l.bf lfged\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfge.d error\n"); + return -1; + } + + b = 133.5; + c = 13.5; + result = 0x4; + __asm + ("lf.sfge.d %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "1:\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfge.d error\n"); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_gts.c b/qemu/tests/tcg/openrisc/test_lf_gts.c new file mode 100644 index 000000000..f3df27958 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_gts.c @@ -0,0 +1,86 @@ +#include <stdio.h> + +int main(void) +{ + int a, result; + float b, c; + + a = 0; + b = 122.5; + c = 123.5; + result = 0x1; + __asm + ("lfgts:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfgt.s %1, %2\n\t" + "l.bf lfgts\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfgt.s error\n"); + return -1; + } + + b = 133.5; + c = 13.5; + result = 0x1; + __asm + ("lf.sfgt.s %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "1:\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfgt.s error\n"); + return -1; + } + +/* int a, result; + double b, c; + + a = 0; + b = 122.5; + c = 123.5; + result = 0x1; + __asm + ("lfgtd:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfgt.d %1, %2\n\t" + "l.bf lfgtd\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfgt.d error\n"); + return -1; + } + + b = 133.5; + c = 13.5; + result = 0x3; + __asm + ("l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfgt.d %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "1:\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfgt.d error, %x\n", a); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_les.c b/qemu/tests/tcg/openrisc/test_lf_les.c new file mode 100644 index 000000000..046c511d9 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_les.c @@ -0,0 +1,88 @@ +#include <stdio.h> + +int main(void) +{ + int a; + float b, c; + int result; + + a = 0; + b = 1234.2; + c = 12.4; + result = 0x1; + __asm + ("lfles:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfle.s %1, %2\n\t" + "l.bf lfles\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfle.s error\n"); + return -1; + } + + b = 1.1; + c = 19.4; + result = 0x3; + __asm + ("l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfle.s %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "1:\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfle.s error\n"); + return -1; + } + +/* int a; + double b, c; + int result; + + a = 0; + b = 1212.5; + c = 123.5; + result = 0x1; + __asm + ("lfled:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfle.d %1, %2\n\t" + "l.bf lfled\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfle.d error\n"); + return -1; + } + + b = 13.5; + c = 113.5; + result = 0x2; + __asm + ("l.addi %0, %0, 0x1\n\t" + "lf.sfle.d %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + "1:\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfle.d error\n"); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_lts.c b/qemu/tests/tcg/openrisc/test_lf_lts.c new file mode 100644 index 000000000..fa56721df --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_lts.c @@ -0,0 +1,92 @@ +#include <stdio.h> + +int main(void) +{ + int a; + float b, c, d; + int result; + + a = 0; + b = 124.5; + c = 1.4; + result = 1; + __asm + ("lfltd:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sflt.s %1, %2\n\t" + "l.bf lfltd\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sflt.s error\n"); + return -1; + } + + a = 0; + b = 11.1; + c = 13.1; + d = 1.0; + result = 2; + __asm + ("1:\n\t" + "lf.add.s %1, %1, %3\n\t" + "l.addi %0, %0, 1\n\t" + "lf.sflt.s %1, %2\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c), "r"(d) + ); + if (a != result) { + printf("lf.sflt.s error\n"); + return -1; + } + +/* int a; + double b, c; + int result; + + a = 0; + b = 1432.1; + c = 2.4; + result = 0x1; + __asm + ("lfltd:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sflt.d %1, %2\n\t" + "l.bf lfltd\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sflt.d error\n"); + return -1; + } + + a = 0; + b = 1.1; + c = 19.7; + result = 2; + __asm + ("lf.sflt.d %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 1\n\t" + "l.addi %0, %0, 1\n\t" + "l.addi %0, %0, 1\n\t" + "1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.addi %0, %0, 1\n\t" + : "+r"(a), "+r"(b) + : "r"(c) + ); + if (a != result) { + printf("lf.sflt.d error\n"); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_mul.c b/qemu/tests/tcg/openrisc/test_lf_mul.c new file mode 100644 index 000000000..bc8ad800c --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_mul.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +int main(void) +{ + float a, b, c; + float result; + + b = 1.5; + c = 4.0; + result = 6.0; + __asm + ("lf.mul.s %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.mul.s error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_nes.c b/qemu/tests/tcg/openrisc/test_lf_nes.c new file mode 100644 index 000000000..613631005 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_nes.c @@ -0,0 +1,89 @@ +#include <stdio.h> + +int main(void) +{ + int a; + float b, c; + int result; + + a = 0; + b = 23.1; + c = 23.1; + result = 0x1; + __asm + ("lfnes:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfne.s %1, %2\n\t" + "l.bf lfnes\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfne.s error"); + return -1; + } + + b = 12.4; + c = 7.8; + result = 0x3; + __asm + ("l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfne.s %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "1:\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfne.s error\n"); + return -1; + } +/* int a; + double b, c; + int result; + + a = 0; + b = 124.3; + c = 124.3; + result = 0x1; + __asm + ("lfned:\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfne.d %1, %2\n\t" + "l.bf lfned\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfne.d error\n"); + return -1; + } + + b = 11.5; + c = 16.7; + result = 0x3; + __asm + ("l.addi %0, %0, 0x1\n\t" + "l.addi %0, %0, 0x1\n\t" + "lf.sfne.d %1, %2\n\t" + "l.bf 1f\n\t" + "l.nop\n\t" + "l.addi r4, r4, 0x1\n\t" + "l.addi r4, r4, 0x1\n\t" + "1:\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sfne.d error\n"); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_rem.c b/qemu/tests/tcg/openrisc/test_lf_rem.c new file mode 100644 index 000000000..bd6090d69 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_rem.c @@ -0,0 +1,32 @@ +#include <stdio.h> + +int main(void) +{ + float a, b, c; + float result; + + b = 101.5; + c = 10; + result = 1.5; +/* __asm + ("lf.rem.d %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.rem.d error\n"); + return -1; + }*/ + + __asm + ("lf.rem.s %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.rem.s error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lf_sub.c b/qemu/tests/tcg/openrisc/test_lf_sub.c new file mode 100644 index 000000000..5ee9b0391 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lf_sub.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +int main(void) +{ + float a, b, c; + float result; + + b = 10.5; + c = 1.5; + result = 9.0; + __asm + ("lf.sub.s %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sub.s error\n"); + return -1; + } + +/* b = 0x999; + c = 0x654; + result = 0x345; + __asm + ("lf.sub.d %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("lf.sub.d error\n"); + return -1; + }*/ + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_logic.c b/qemu/tests/tcg/openrisc/test_logic.c new file mode 100644 index 000000000..46d173f48 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_logic.c @@ -0,0 +1,105 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + b = 0x9743; + c = 0x2; + result = 0x25d0c; + __asm + ("l.sll %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("sll error\n"); + return -1; + } + + b = 0x9743; + result = 0x25d0c; + __asm + ("l.slli %0, %1, 0x2\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("slli error\n"); + return -1; + } + + b = 0x7654; + c = 0x03; + result = 0xeca; + __asm + ("l.srl %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + + b = 0x7654; + result = 0xeca; + __asm + ("l.srli %0, %1, 0x3\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("srli error\n"); + return -1; + } + + b = 0x80000001; + c = 0x4; + result = 0x18000000; + __asm + ("l.ror %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("ror error\n"); + return -1; + } + + b = 0x80000001; + result = 0x18000000; + __asm + ("l.rori %0, %1, 0x4\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("rori error\n"); + return -1; + } + + b = 0x80000001; + c = 0x03; + result = 0xf0000000; + __asm + ("l.sra %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("sra error\n"); + return -1; + } + + b = 0x80000001; + result = 0xf0000000; + __asm + ("l.srai %0, %1, 0x3\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("srai error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_lx.c b/qemu/tests/tcg/openrisc/test_lx.c new file mode 100644 index 000000000..792e3d5c7 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_lx.c @@ -0,0 +1,84 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int p[50]; + int result; + + result = 0x23; + __asm + ("l.ori r8, r0, 0x123\n\t" + "l.sb 0x4 + %1, r8\n\t" + "\n\t" + "l.lbz %0, 0x4 + %1\n\t" + : "=r"(a), "+m"(*p) + ); + if (a != result) { + printf("lbz error, %x\n", a); + return -1; + } + + result = 0x23; + __asm + ("l.lbs %0, 0x4 + %1\n\t" + : "=r"(a) + : "m"(*p) + ); + if (a != result) { + printf("lbs error\n"); + return -1; + } + + result = 0x1111; + __asm + ("l.ori r8, r0, 0x1111\n\t" + "l.sh 0x20 + %1, r8\n\t" + "\n\t" + "l.lhs %0, 0x20 + %1\n\t" + : "=r"(a), "=m"(*p) + ); + if (a != result) { + printf("lhs error, %x\n", a); + return -1; + } + + result = 0x1111; + __asm + ("l.lhz %0, 0x20 + %1\n\t" + : "=r"(a) + : "m"(*p) + ); + if (a != result) { + printf("lhz error\n"); + return -1; + } + + result = 0x1111233; + __asm + ("l.ori r8, r0, 0x1233\n\t" + "l.movhi r1, 0x111\n\t" + "l.or r8, r8, r1\n\t" + "l.sw 0x123 + %1, r8\n\t" + "\n\t" + "l.lws %0, 0x123 + %1\n\t" + : "=r"(a), "+m"(*p) + ); + if (a != result) { + printf("lws error, %x\n", a); + return -1; + } + + result = 0x1111233; + __asm + ("l.lwz %0, 0x123 + %1\n\t" + : "=r"(a) + : "m"(*p) + ); + if (a != result) { + printf("lwz error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_movhi.c b/qemu/tests/tcg/openrisc/test_movhi.c new file mode 100644 index 000000000..737f75b9f --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_movhi.c @@ -0,0 +1,31 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + result = 0x1222; + __asm + ("l.movhi r3, 0x1222\n\t" + "l.srli %0, r3, 16\n\t" + : "=r"(a) + ); + if (a != result) { + printf("movhi error\n"); + return -1; + } + + result = 0x1111; + __asm + ("l.movhi r8, 0x1111\n\t" + "l.srli %0, r8, 16\n\t" + : "=r"(a) + ); + if (a != result) { + printf("movhi error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_mul.c b/qemu/tests/tcg/openrisc/test_mul.c new file mode 100644 index 000000000..130101fde --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_mul.c @@ -0,0 +1,61 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + b = 0x4; + c = 0x1; + result = 0x4; + __asm + ("l.mul %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("mul error\n"); + return -1; + } + + b = 0x1; + c = 0x0; + result = 0x0; + __asm + ("l.mul %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("mul error\n"); + return -1; + } + + b = 0x1; + c = 0xff; + result = 0xff; + __asm + ("l.mul %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("mul error\n"); + return -1; + } + + b = 0x7fffffff; + c = 0x2; + result = 0xfffffffe; + __asm + ("l.mul %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("mul error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_muli.c b/qemu/tests/tcg/openrisc/test_muli.c new file mode 100644 index 000000000..f1042e98d --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_muli.c @@ -0,0 +1,48 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + b = 0x4; + c = 0x1; + result = 0x4; + __asm + ("l.muli %0, %1, 0x1\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("muli error\n"); + return -1; + } + + b = 0x1; + c = 0x0; + result = 0x0; + __asm + ("l.muli %0, %1, 0x0\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("muli error\n"); + return -1; + } + + b = 0x1; + c = 0xff; + result = 0xff; + __asm + ("l.muli %0, %1, 0xff\n\t" + : "=r"(a) + : "r"(b) + ); + if (a != result) { + printf("muli error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_mulu.c b/qemu/tests/tcg/openrisc/test_mulu.c new file mode 100644 index 000000000..2d1e97d16 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_mulu.c @@ -0,0 +1,48 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + b = 0x4; + c = 0x1; + result = 0x4; + __asm + ("l.mulu %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("mulu error\n"); + return -1; + } + + b = 0x1; + c = 0x0; + result = 0x0; + __asm + ("l.mulu %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("mulu error\n"); + return -1; + } + + b = 0x1; + c = 0xff; + result = 0xff; + __asm + ("l.mulu %0, %1, %2\n\t" + : "=r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("mulu error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfeq.c b/qemu/tests/tcg/openrisc/test_sfeq.c new file mode 100644 index 000000000..bd7f875b7 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfeq.c @@ -0,0 +1,43 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0x1; + b = 0x80; + result = 0x2; + __asm + ("1:\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.sfeq %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfeq error\n"); + return -1; + } + + a = 0x7f; + b = 0x80; + result = 0x81; + __asm + ("2:\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.sfeq %0, %1\n\t" + "l.bf 2b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfeq error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfeqi.c b/qemu/tests/tcg/openrisc/test_sfeqi.c new file mode 100644 index 000000000..574261321 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfeqi.c @@ -0,0 +1,39 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + a = 1; + result = 2; + __asm + ("1:\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.sfeqi %0, 0x80\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfeqi error\n"); + return -1; + } + + a = 0x7f; + result = 0x81; + __asm + ("2:\n\t" + "l.addi %0, %0, 0x1\n\t" + "l.sfeqi %0, 0x80\n\t" + "l.bf 2b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfeqi error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfges.c b/qemu/tests/tcg/openrisc/test_sfges.c new file mode 100644 index 000000000..23761d7f5 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfges.c @@ -0,0 +1,44 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + a = 0; + b = 3; + result = 1; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfges %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfges error\n"); + return -1; + } + + a = 0xff; + b = 3; + c = 0x1; + result = 2; + __asm + ("1:\n\t" + "l.sub %0, %0, %2\n\t" + "l.sfges %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("sfges error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfgesi.c b/qemu/tests/tcg/openrisc/test_sfgesi.c new file mode 100644 index 000000000..54a2d51cd --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfgesi.c @@ -0,0 +1,40 @@ +#include <stdio.h> +int main(void) +{ + int a, b; + int result; + + a = 0; + result = 1; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfgesi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfgesi error\n"); + return -1; + } + + a = 0xff; + b = 1; + result = 2; + __asm + ("1:\n\t" + "l.sub %0, %0, %1\n\t" + "l.sfgesi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfgesi error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfgeu.c b/qemu/tests/tcg/openrisc/test_sfgeu.c new file mode 100644 index 000000000..2a491d91e --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfgeu.c @@ -0,0 +1,44 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + a = 0; + b = 3; + result = 1; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfgeu %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfgeu error\n"); + return -1; + } + + a = 0xff; + b = 3; + c = 1; + result = 2; + __asm + ("1:\n\t" + "l.sub %0, %0, %2\n\t" + "l.sfgeu %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("sfgeu error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfgeui.c b/qemu/tests/tcg/openrisc/test_sfgeui.c new file mode 100644 index 000000000..40af35c68 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfgeui.c @@ -0,0 +1,41 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + result = 1; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfgeui %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfgeui error\n"); + return -1; + } + + a = 0xff; + b = 1; + result = 2; + __asm + ("1:\n\t" + "l.sub %0, %0, %1\n\t" + "l.sfgeui %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfgeui error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfgts.c b/qemu/tests/tcg/openrisc/test_sfgts.c new file mode 100644 index 000000000..4481a9cc3 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfgts.c @@ -0,0 +1,45 @@ +#include <stdio.h> + +int main(void) +{ + int a, b, c; + int result; + + a = 0; + b = 3; + result = 1; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfgts %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfgts error\n"); + return -1; + } + + + a = 0xff; + b = 3; + c = 1; + result = 3; + __asm + ("1:\n\t" + "l.sub %0, %0, %2\n\t" + "l.sfgts %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("sfgts error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfgtsi.c b/qemu/tests/tcg/openrisc/test_sfgtsi.c new file mode 100644 index 000000000..7366e1292 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfgtsi.c @@ -0,0 +1,41 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + result = 1; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfgtsi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfgtsi error\n"); + return -1; + } + + a = 0xff; + b = 1; + result = 3; + __asm + ("1:\n\t" + "l.sub %0, %0, %1\n\t" + "l.sfgtsi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfgtsi error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfgtu.c b/qemu/tests/tcg/openrisc/test_sfgtu.c new file mode 100644 index 000000000..da2868916 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfgtu.c @@ -0,0 +1,43 @@ +#include <stdio.h> +int main(void) +{ + int a, b, c; + int result; + + a = 0; + b = 3; + result = 1; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfgtu %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfgtu error\n"); + return -1; + } + + a = 0xff; + b = 3; + c = 1; + result = 3; + __asm + ("1:\n\t" + "l.sub %0, %0, %2\n\t" + "l.sfgtu %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b), "r"(c) + ); + if (a != result) { + printf("sfgtu error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfgtui.c b/qemu/tests/tcg/openrisc/test_sfgtui.c new file mode 100644 index 000000000..565d44f11 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfgtui.c @@ -0,0 +1,42 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + result = 1; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfgtui %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfgtui error\n"); + return -1; + } + + + a = 0xff; + b = 1; + result = 3; + __asm + ("1:\n\t" + "l.sub %0, %0, %1\n\t" + "l.sfgtui %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfgtui error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfles.c b/qemu/tests/tcg/openrisc/test_sfles.c new file mode 100644 index 000000000..f5735228f --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfles.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + b = 3; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 4\n\t" + "l.sfles %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfles error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sflesi.c b/qemu/tests/tcg/openrisc/test_sflesi.c new file mode 100644 index 000000000..16fe6053e --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sflesi.c @@ -0,0 +1,39 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + a = 0; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 4\n\t" + "l.sflesi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sflesi error\n"); + return -1; + } + + a = 0; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sflesi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sflesi error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfleu.c b/qemu/tests/tcg/openrisc/test_sfleu.c new file mode 100644 index 000000000..be0a3c3f4 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfleu.c @@ -0,0 +1,43 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + b = 3; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 4\n\t" + "l.sfleu %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfleu error\n"); + return -1; + } + + a = 0; + b = 3; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfleu %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfleu error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfleui.c b/qemu/tests/tcg/openrisc/test_sfleui.c new file mode 100644 index 000000000..38d3c8970 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfleui.c @@ -0,0 +1,39 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + a = 0; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 4\n\t" + "l.sfleui %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfleui error\n"); + return -1; + } + + a = 0; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfleui %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfleui error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sflts.c b/qemu/tests/tcg/openrisc/test_sflts.c new file mode 100644 index 000000000..7deeb48d0 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sflts.c @@ -0,0 +1,43 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + b = 3; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 4\n\t" + "l.sflts %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sflts error\n"); + return -1; + } + + a = 0; + b = 3; + result = 3; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sflts %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sflts error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfltsi.c b/qemu/tests/tcg/openrisc/test_sfltsi.c new file mode 100644 index 000000000..3cb1f0285 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfltsi.c @@ -0,0 +1,39 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + a = 0; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 4\n\t" + "l.sfltsi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfltsi error\n"); + return -1; + } + + a = 0; + result = 3; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfltsi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfltsi error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfltu.c b/qemu/tests/tcg/openrisc/test_sfltu.c new file mode 100644 index 000000000..7ed3b2685 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfltu.c @@ -0,0 +1,43 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + b = 3; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 4\n\t" + "l.sfltu %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfltu error\n"); + return -1; + } + + a = 0; + b = 3; + result = 3; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfltu %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfltu error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfltui.c b/qemu/tests/tcg/openrisc/test_sfltui.c new file mode 100644 index 000000000..a5cb9f6a9 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfltui.c @@ -0,0 +1,39 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + a = 0; + result = 4; + __asm + ("1:\n\t" + "l.addi %0, %0, 4\n\t" + "l.sfltsi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfltui error\n"); + return -1; + } + + a = 0; + result = 3; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfltsi %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfltui error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfne.c b/qemu/tests/tcg/openrisc/test_sfne.c new file mode 100644 index 000000000..b33a35cf9 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfne.c @@ -0,0 +1,43 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0; + b = 3; + result = 3; + __asm + ("1:\n\t" + "l.addi %0, %0, 3\n\t" + "l.sfne %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfne error\n"); + return -1; + } + + a = 0; + b = 3; + result = 3; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfne %0, %1\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sfne error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sfnei.c b/qemu/tests/tcg/openrisc/test_sfnei.c new file mode 100644 index 000000000..d311c9e66 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sfnei.c @@ -0,0 +1,39 @@ +#include <stdio.h> + +int main(void) +{ + int a; + int result; + + a = 0; + result = 3; + __asm + ("1:\n\t" + "l.addi %0, %0, 3\n\t" + "l.sfnei %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfnei error\n"); + return -1; + } + + a = 0; + result = 3; + __asm + ("1:\n\t" + "l.addi %0, %0, 1\n\t" + "l.sfnei %0, 0x3\n\t" + "l.bf 1b\n\t" + "l.nop\n\t" + : "+r"(a) + ); + if (a != result) { + printf("sfnei error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/openrisc/test_sub.c b/qemu/tests/tcg/openrisc/test_sub.c new file mode 100644 index 000000000..474ec6055 --- /dev/null +++ b/qemu/tests/tcg/openrisc/test_sub.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +int main(void) +{ + int a, b; + int result; + + a = 0x100; + b = 0x100; + result = 0x0; + __asm + ("l.sub %0, %0, %1\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sub error\n"); + return -1; + } + + a = 0xffff; + b = 0x1; + result = 0xfffe; + __asm + ("l.sub %0, %0, %1\n\t" + : "+r"(a) + : "r"(b) + ); + if (a != result) { + printf("sub error\n"); + return -1; + } + + return 0; +} diff --git a/qemu/tests/tcg/pi_10.com b/qemu/tests/tcg/pi_10.com Binary files differnew file mode 100644 index 000000000..8993ba1a5 --- /dev/null +++ b/qemu/tests/tcg/pi_10.com diff --git a/qemu/tests/tcg/runcom.c b/qemu/tests/tcg/runcom.c new file mode 100644 index 000000000..d60342bfc --- /dev/null +++ b/qemu/tests/tcg/runcom.c @@ -0,0 +1,192 @@ +/* + * Simple example of use of vm86: launch a basic .com DOS executable + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <signal.h> + +#include <linux/unistd.h> +#include <asm/vm86.h> + +extern int vm86 (unsigned long int subfunction, + struct vm86plus_struct *info); + +#define VIF_MASK 0x00080000 + +//#define SIGTEST + +#define COM_BASE_ADDR 0x10100 + +static void usage(void) +{ + printf("runcom version 0.1 (c) 2003 Fabrice Bellard\n" + "usage: runcom file.com\n" + "VM86 Run simple .com DOS executables (linux vm86 test mode)\n"); + exit(1); +} + +static inline void set_bit(uint8_t *a, unsigned int bit) +{ + a[bit / 8] |= (1 << (bit % 8)); +} + +static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg) +{ + return (uint8_t *)((seg << 4) + (reg & 0xffff)); +} + +static inline void pushw(struct vm86_regs *r, int val) +{ + r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff); + *(uint16_t *)seg_to_linear(r->ss, r->esp) = val; +} + +void dump_regs(struct vm86_regs *r) +{ + fprintf(stderr, + "EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n" + "ESI=%08lx EDI=%08lx EBP=%08lx ESP=%08lx\n" + "EIP=%08lx EFL=%08lx\n" + "CS=%04x DS=%04x ES=%04x SS=%04x FS=%04x GS=%04x\n", + r->eax, r->ebx, r->ecx, r->edx, r->esi, r->edi, r->ebp, r->esp, + r->eip, r->eflags, + r->cs, r->ds, r->es, r->ss, r->fs, r->gs); +} + +#ifdef SIGTEST +void alarm_handler(int sig) +{ + fprintf(stderr, "alarm signal=%d\n", sig); + alarm(1); +} +#endif + +int main(int argc, char **argv) +{ + uint8_t *vm86_mem; + const char *filename; + int fd, ret, seg; + struct vm86plus_struct ctx; + struct vm86_regs *r; + + if (argc != 2) + usage(); + filename = argv[1]; + + vm86_mem = mmap((void *)0x00000000, 0x110000, + PROT_WRITE | PROT_READ | PROT_EXEC, + MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); + if (vm86_mem == MAP_FAILED) { + perror("mmap"); + exit(1); + } +#ifdef SIGTEST + { + struct sigaction act; + + act.sa_handler = alarm_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + alarm(1); + } +#endif + + /* load the MSDOS .com executable */ + fd = open(filename, O_RDONLY); + if (fd < 0) { + perror(filename); + exit(1); + } + ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256); + if (ret < 0) { + perror("read"); + exit(1); + } + close(fd); + + memset(&ctx, 0, sizeof(ctx)); + /* init basic registers */ + r = &ctx.regs; + r->eip = 0x100; + r->esp = 0xfffe; + seg = (COM_BASE_ADDR - 0x100) >> 4; + r->cs = seg; + r->ss = seg; + r->ds = seg; + r->es = seg; + r->fs = seg; + r->gs = seg; + r->eflags = VIF_MASK; + + /* put return code */ + set_bit((uint8_t *)&ctx.int_revectored, 0x21); + *seg_to_linear(r->cs, 0) = 0xb4; /* mov ah, $0 */ + *seg_to_linear(r->cs, 1) = 0x00; + *seg_to_linear(r->cs, 2) = 0xcd; /* int $0x21 */ + *seg_to_linear(r->cs, 3) = 0x21; + pushw(&ctx.regs, 0x0000); + + /* the value of these registers seem to be assumed by pi_10.com */ + r->esi = 0x100; + r->ecx = 0xff; + r->ebp = 0x0900; + r->edi = 0xfffe; + + for(;;) { + ret = vm86(VM86_ENTER, &ctx); + switch(VM86_TYPE(ret)) { + case VM86_INTx: + { + int int_num, ah; + + int_num = VM86_ARG(ret); + if (int_num != 0x21) + goto unknown_int; + ah = (r->eax >> 8) & 0xff; + switch(ah) { + case 0x00: /* exit */ + exit(0); + case 0x02: /* write char */ + { + uint8_t c = r->edx; + write(1, &c, 1); + } + break; + case 0x09: /* write string */ + { + uint8_t c; + for(;;) { + c = *seg_to_linear(r->ds, r->edx); + if (c == '$') + break; + write(1, &c, 1); + } + r->eax = (r->eax & ~0xff) | '$'; + } + break; + default: + unknown_int: + fprintf(stderr, "unsupported int 0x%02x\n", int_num); + dump_regs(&ctx.regs); + // exit(1); + } + } + break; + case VM86_SIGNAL: + /* a signal came, we just ignore that */ + break; + case VM86_STI: + break; + default: + fprintf(stderr, "unhandled vm86 return code (0x%x)\n", ret); + dump_regs(&ctx.regs); + exit(1); + } + } +} diff --git a/qemu/tests/tcg/sha1.c b/qemu/tests/tcg/sha1.c new file mode 100644 index 000000000..93b7c8e80 --- /dev/null +++ b/qemu/tests/tcg/sha1.c @@ -0,0 +1,240 @@ + +/* from valgrind tests */ + +/* ================ sha1.c ================ */ +/* +SHA-1 in C +By Steve Reid <steve@edmweb.com> +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#define SHA1HANDSOFF + +#include <stdio.h> +#include <string.h> +#include <stdint.h> + +/* ================ sha1.h ================ */ +/* +SHA-1 in C +By Steve Reid <steve@edmweb.com> +100% Public Domain +*/ + +typedef struct { + uint32_t state[5]; + uint32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); +void SHA1Init(SHA1_CTX* context); +void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); +void SHA1Final(unsigned char digest[20], SHA1_CTX* context); +/* ================ end of sha1.h ================ */ +#include <endian.h> + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#elif BYTE_ORDER == BIG_ENDIAN +#define blk0(i) block->l[i] +#else +#error "Endianness not defined!" +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) +{ +uint32_t a, b, c, d, e; +typedef union { + unsigned char c[64]; + uint32_t l[16]; +} CHAR64LONG16; +#ifdef SHA1HANDSOFF +CHAR64LONG16 block[1]; /* use array to appear as a pointer */ + memcpy(block, buffer, 64); +#else + /* The following had better never be used because it causes the + * pointer-to-const buffer to be cast into a pointer to non-const. + * And the result is written through. I threw a "const" in, hoping + * this will cause a diagnostic. + */ +CHAR64LONG16* block = (const CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +#ifdef SHA1HANDSOFF + memset(block, '\0', sizeof(block)); +#endif +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) +{ +uint32_t i; +uint32_t j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1]++; + context->count[1] += (len>>29); + j = (j >> 3) & 63; + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ +unsigned i; +unsigned char finalcount[8]; +unsigned char c; + +#if 0 /* untested "improvement" by DHR */ + /* Convert context->count to a sequence of bytes + * in finalcount. Second element first, but + * big-endian order within element. + * But we do it all backwards. + */ + unsigned char *fcp = &finalcount[8]; + + for (i = 0; i < 2; i++) + { + uint32_t t = context->count[i]; + int j; + + for (j = 0; j < 4; t >>= 8, j++) + *--fcp = (unsigned char) t; + } +#else + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } +#endif + c = 0200; + SHA1Update(context, &c, 1); + while ((context->count[0] & 504) != 448) { + c = 0000; + SHA1Update(context, &c, 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + memset(context, '\0', sizeof(*context)); + memset(&finalcount, '\0', sizeof(finalcount)); +} +/* ================ end of sha1.c ================ */ + +#define BUFSIZE 4096 + +int +main(int argc, char **argv) +{ + SHA1_CTX ctx; + unsigned char hash[20], buf[BUFSIZE]; + int i; + + for(i=0;i<BUFSIZE;i++) + buf[i] = i; + + SHA1Init(&ctx); + for(i=0;i<1000;i++) + SHA1Update(&ctx, buf, BUFSIZE); + SHA1Final(hash, &ctx); + + printf("SHA1="); + for(i=0;i<20;i++) + printf("%02x", hash[i]); + printf("\n"); + return 0; +} diff --git a/qemu/tests/tcg/test-arm-iwmmxt.s b/qemu/tests/tcg/test-arm-iwmmxt.s new file mode 100644 index 000000000..d647f9404 --- /dev/null +++ b/qemu/tests/tcg/test-arm-iwmmxt.s @@ -0,0 +1,49 @@ +@ Checks whether iwMMXt is functional. +.code 32 +.globl main + +main: +ldr r0, =data0 +ldr r1, =data1 +ldr r2, =data2 +#ifndef FPA +wldrd wr0, [r0, #0] +wldrd wr1, [r0, #8] +wldrd wr2, [r1, #0] +wldrd wr3, [r1, #8] +wsubb wr2, wr2, wr0 +wsubb wr3, wr3, wr1 +wldrd wr0, [r2, #0] +wldrd wr1, [r2, #8] +waddb wr0, wr0, wr2 +waddb wr1, wr1, wr3 +wstrd wr0, [r2, #0] +wstrd wr1, [r2, #8] +#else +ldfe f0, [r0, #0] +ldfe f1, [r0, #8] +ldfe f2, [r1, #0] +ldfe f3, [r1, #8] +adfdp f2, f2, f0 +adfdp f3, f3, f1 +ldfe f0, [r2, #0] +ldfe f1, [r2, #8] +adfd f0, f0, f2 +adfd f1, f1, f3 +stfe f0, [r2, #0] +stfe f1, [r2, #8] +#endif +mov r0, #1 +mov r1, r2 +mov r2, #0x11 +swi #0x900004 +mov r0, #0 +swi #0x900001 + +.data +data0: +.string "aaaabbbbccccdddd" +data1: +.string "bbbbccccddddeeee" +data2: +.string "hvLLWs\x1fsdrs9\x1fNJ-\n" diff --git a/qemu/tests/tcg/test-i386-code16.S b/qemu/tests/tcg/test-i386-code16.S new file mode 100644 index 000000000..816c24b96 --- /dev/null +++ b/qemu/tests/tcg/test-i386-code16.S @@ -0,0 +1,79 @@ + .code16 + .globl code16_start + .globl code16_end + +CS_SEG = 0xf + +code16_start: + + .globl code16_func1 + + /* basic test */ +code16_func1 = . - code16_start + mov $1, %eax + data32 lret + +/* test push/pop in 16 bit mode */ + .globl code16_func2 +code16_func2 = . - code16_start + xor %eax, %eax + mov $0x12345678, %ebx + movl %esp, %ecx + push %bx + subl %esp, %ecx + pop %ax + data32 lret + +/* test various jmp opcodes */ + .globl code16_func3 +code16_func3 = . - code16_start + jmp 1f + nop +1: + mov $4, %eax + mov $0x12345678, %ebx + xor %bx, %bx + jz 2f + add $2, %ax +2: + + call myfunc + + lcall $CS_SEG, $(myfunc2 - code16_start) + + ljmp $CS_SEG, $(myjmp1 - code16_start) +myjmp1_next: + + cs lcall *myfunc2_addr - code16_start + + cs ljmp *myjmp2_addr - code16_start +myjmp2_next: + + data32 lret + +myfunc2_addr: + .short myfunc2 - code16_start + .short CS_SEG + +myjmp2_addr: + .short myjmp2 - code16_start + .short CS_SEG + +myjmp1: + add $8, %ax + jmp myjmp1_next + +myjmp2: + add $16, %ax + jmp myjmp2_next + +myfunc: + add $1, %ax + ret + +myfunc2: + add $4, %ax + lret + + +code16_end: diff --git a/qemu/tests/tcg/test-i386-fprem.c b/qemu/tests/tcg/test-i386-fprem.c new file mode 100644 index 000000000..e91fb1ae9 --- /dev/null +++ b/qemu/tests/tcg/test-i386-fprem.c @@ -0,0 +1,353 @@ +/* + * x86 FPREM test - executes the FPREM and FPREM1 instructions with corner case + * operands and prints the operands, result and FPU status word. + * + * Run this on real hardware, then under QEMU, and diff the outputs, to compare + * QEMU's implementation to your hardware. The 'run-test-i386-fprem' make + * target does this. + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2012 Catalin Patulea + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#include "qemu/compiler.h" +#include "qemu/osdep.h" +#include <stdio.h> +#include <inttypes.h> + +/* + * Inspired by <ieee754.h>'s union ieee854_long_double, but with single + * long long mantissa fields and assuming little-endianness for simplicity. + */ +union float80u { + long double d; + + /* This is the IEEE 854 double-extended-precision format. */ + struct { + unsigned long long mantissa:63; + unsigned int one:1; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; + } QEMU_PACKED ieee; + + /* This is for NaNs in the IEEE 854 double-extended-precision format. */ + struct { + unsigned long long mantissa:62; + unsigned int quiet_nan:1; + unsigned int one:1; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; + } QEMU_PACKED ieee_nan; +}; + +#define IEEE854_LONG_DOUBLE_BIAS 0x3fff + +static const union float80u q_nan = { + .ieee_nan.negative = 0, /* X */ + .ieee_nan.exponent = 0x7fff, + .ieee_nan.one = 1, + .ieee_nan.quiet_nan = 1, + .ieee_nan.mantissa = 0, +}; + +static const union float80u s_nan = { + .ieee_nan.negative = 0, /* X */ + .ieee_nan.exponent = 0x7fff, + .ieee_nan.one = 1, + .ieee_nan.quiet_nan = 0, + .ieee_nan.mantissa = 1, /* nonzero */ +}; + +static const union float80u pos_inf = { + .ieee.negative = 0, + .ieee.exponent = 0x7fff, + .ieee.one = 1, + .ieee.mantissa = 0, +}; + +static const union float80u pseudo_pos_inf = { /* "unsupported" */ + .ieee.negative = 0, + .ieee.exponent = 0x7fff, + .ieee.one = 0, + .ieee.mantissa = 0, +}; + +static const union float80u pos_denorm = { + .ieee.negative = 0, + .ieee.exponent = 0, + .ieee.one = 0, + .ieee.mantissa = 1, +}; + +static const union float80u smallest_positive_norm = { + .ieee.negative = 0, + .ieee.exponent = 1, + .ieee.one = 1, + .ieee.mantissa = 0, +}; + +static void fninit() +{ + asm volatile ("fninit\n"); +} + +static long double fprem(long double a, long double b, uint16_t *sw) +{ + long double result; + asm volatile ("fprem\n" + "fnstsw %1\n" + : "=t" (result), "=m" (*sw) + : "0" (a), "u" (b) + : "st(1)"); + return result; +} + +static long double fprem1(long double a, long double b, uint16_t *sw) +{ + long double result; + asm volatile ("fprem1\n" + "fnstsw %1\n" + : "=t" (result), "=m" (*sw) + : "0" (a), "u" (b) + : "st(1)"); + return result; +} + +#define FPUS_IE (1 << 0) +#define FPUS_DE (1 << 1) +#define FPUS_ZE (1 << 2) +#define FPUS_OE (1 << 3) +#define FPUS_UE (1 << 4) +#define FPUS_PE (1 << 5) +#define FPUS_SF (1 << 6) +#define FPUS_SE (1 << 7) +#define FPUS_C0 (1 << 8) +#define FPUS_C1 (1 << 9) +#define FPUS_C2 (1 << 10) +#define FPUS_TOP 0x3800 +#define FPUS_C3 (1 << 14) +#define FPUS_B (1 << 15) + +#define FPUS_EMASK 0x007f + +#define FPUC_EM 0x3f + +static void psw(uint16_t sw) +{ + printf("SW: C3 TopC2C1C0\n"); + printf("SW: %c %d %3d %d %d %d %c %c %c %c %c %c %c %c\n", + sw & FPUS_B ? 'B' : 'b', + !!(sw & FPUS_C3), + (sw & FPUS_TOP) >> 11, + !!(sw & FPUS_C2), + !!(sw & FPUS_C1), + !!(sw & FPUS_C0), + (sw & FPUS_SE) ? 'S' : 's', + (sw & FPUS_SF) ? 'F' : 'f', + (sw & FPUS_PE) ? 'P' : 'p', + (sw & FPUS_UE) ? 'U' : 'u', + (sw & FPUS_OE) ? 'O' : 'o', + (sw & FPUS_ZE) ? 'Z' : 'z', + (sw & FPUS_DE) ? 'D' : 'd', + (sw & FPUS_IE) ? 'I' : 'i'); +} + +static void do_fprem(long double a, long double b) +{ + const union float80u au = {.d = a}; + const union float80u bu = {.d = b}; + union float80u ru; + uint16_t sw; + + printf("A: S=%d Exp=%04x Int=%d (QNaN=%d) Sig=%016llx (%.06Le)\n", + au.ieee.negative, au.ieee.exponent, au.ieee.one, + au.ieee_nan.quiet_nan, (unsigned long long)au.ieee.mantissa, + a); + printf("B: S=%d Exp=%04x Int=%d (QNaN=%d) Sig=%016llx (%.06Le)\n", + bu.ieee.negative, bu.ieee.exponent, bu.ieee.one, + bu.ieee_nan.quiet_nan, (unsigned long long)bu.ieee.mantissa, + b); + fflush(stdout); + + fninit(); + ru.d = fprem(a, b, &sw); + psw(sw); + + printf("R : S=%d Exp=%04x Int=%d (QNaN=%d) Sig=%016llx (%.06Le)\n", + ru.ieee.negative, ru.ieee.exponent, ru.ieee.one, + ru.ieee_nan.quiet_nan, (unsigned long long)ru.ieee.mantissa, + ru.d); + + fninit(); + ru.d = fprem1(a, b, &sw); + psw(sw); + + printf("R1: S=%d Exp=%04x Int=%d (QNaN=%d) Sig=%016llx (%.06Le)\n", + ru.ieee.negative, ru.ieee.exponent, ru.ieee.one, + ru.ieee_nan.quiet_nan, (unsigned long long)ru.ieee.mantissa, + ru.d); + + printf("\n"); +} + +static void do_fprem_stack_underflow(void) +{ + const long double a = 1.0; + union float80u ru; + uint16_t sw; + + fninit(); + asm volatile ("fprem\n" + "fnstsw %1\n" + : "=t" (ru.d), "=m" (sw) + : "0" (a) + : "st(1)"); + psw(sw); + + printf("R: S=%d Exp=%04x Int=%d (QNaN=%d) Sig=%016llx (%.06Le)\n", + ru.ieee.negative, ru.ieee.exponent, ru.ieee.one, + ru.ieee_nan.quiet_nan, (unsigned long long)ru.ieee.mantissa, + ru.d); + printf("\n"); +} + +static void test_fprem_cases(void) +{ + printf("= stack underflow =\n"); + do_fprem_stack_underflow(); + + printf("= invalid operation =\n"); + do_fprem(s_nan.d, 1.0); + do_fprem(1.0, 0.0); + do_fprem(pos_inf.d, 1.0); + do_fprem(pseudo_pos_inf.d, 1.0); + + printf("= denormal =\n"); + do_fprem(pos_denorm.d, 1.0); + do_fprem(1.0, pos_denorm.d); + + /* printf("= underflow =\n"); */ + /* TODO: Is there a case where FPREM raises underflow? */ +} + +static void test_fprem_pairs(void) +{ + unsigned long long count; + + unsigned int negative_index_a = 0; + unsigned int negative_index_b = 0; + static const unsigned int negative_values[] = { + 0, + 1, + }; + + unsigned int exponent_index_a = 0; + unsigned int exponent_index_b = 0; + static const unsigned int exponent_values[] = { + 0, + 1, + 2, + IEEE854_LONG_DOUBLE_BIAS - 1, + IEEE854_LONG_DOUBLE_BIAS, + IEEE854_LONG_DOUBLE_BIAS + 1, + 0x7ffd, + 0x7ffe, + 0x7fff, + }; + + unsigned int one_index_a = 0; + unsigned int one_index_b = 0; + static const unsigned int one_values[] = { + 0, + 1, + }; + + unsigned int quiet_nan_index_a = 0; + unsigned int quiet_nan_index_b = 0; + static const unsigned int quiet_nan_values[] = { + 0, + 1, + }; + + unsigned int mantissa_index_a = 0; + unsigned int mantissa_index_b = 0; + static const unsigned long long mantissa_values[] = { + 0, + 1, + 2, + 0x3ffffffffffffffdULL, + 0x3ffffffffffffffeULL, + 0x3fffffffffffffffULL, + }; + + for (count = 0; ; ++count) { +#define INIT_FIELD(var, field) \ + .ieee_nan.field = field##_values[field##_index_##var] + const union float80u a = { + INIT_FIELD(a, negative), + INIT_FIELD(a, exponent), + INIT_FIELD(a, one), + INIT_FIELD(a, quiet_nan), + INIT_FIELD(a, mantissa), + }; + const union float80u b = { + INIT_FIELD(b, negative), + INIT_FIELD(b, exponent), + INIT_FIELD(b, one), + INIT_FIELD(b, quiet_nan), + INIT_FIELD(b, mantissa), + }; +#undef INIT_FIELD + + do_fprem(a.d, b.d); + + int carry = 1; +#define CARRY_INTO(var, field) do { \ + if (carry) { \ + if (++field##_index_##var == ARRAY_SIZE(field##_values)) { \ + field##_index_##var = 0; \ + } else { \ + carry = 0; \ + } \ + } \ + } while (0) + CARRY_INTO(b, mantissa); + CARRY_INTO(b, quiet_nan); + CARRY_INTO(b, one); + CARRY_INTO(b, exponent); + CARRY_INTO(b, negative); + CARRY_INTO(a, mantissa); + CARRY_INTO(a, quiet_nan); + CARRY_INTO(a, one); + CARRY_INTO(a, exponent); + CARRY_INTO(a, negative); +#undef CARRY_INTO + + if (carry) { + break; + } + } + + fprintf(stderr, "test-i386-fprem: tested %llu cases\n", count); +} + +int main(int argc, char **argv) +{ + test_fprem_cases(); + test_fprem_pairs(); + return 0; +} diff --git a/qemu/tests/tcg/test-i386-muldiv.h b/qemu/tests/tcg/test-i386-muldiv.h new file mode 100644 index 000000000..015f59e15 --- /dev/null +++ b/qemu/tests/tcg/test-i386-muldiv.h @@ -0,0 +1,76 @@ + +void glue(glue(test_, OP), b)(long op0, long op1) +{ + long res, s1, s0, flags; + s0 = op0; + s1 = op1; + res = s0; + flags = 0; + asm ("push %4\n\t" + "popf\n\t" + stringify(OP)"b %b2\n\t" + "pushf\n\t" + "pop %1\n\t" + : "=a" (res), "=g" (flags) + : "q" (s1), "0" (res), "1" (flags)); + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n", + stringify(OP) "b", s0, s1, res, flags & CC_MASK); +} + +void glue(glue(test_, OP), w)(long op0h, long op0, long op1) +{ + long res, s1, flags, resh; + s1 = op1; + resh = op0h; + res = op0; + flags = 0; + asm ("push %5\n\t" + "popf\n\t" + stringify(OP) "w %w3\n\t" + "pushf\n\t" + "pop %1\n\t" + : "=a" (res), "=g" (flags), "=d" (resh) + : "q" (s1), "0" (res), "1" (flags), "2" (resh)); + printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n", + stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK); +} + +void glue(glue(test_, OP), l)(long op0h, long op0, long op1) +{ + long res, s1, flags, resh; + s1 = op1; + resh = op0h; + res = op0; + flags = 0; + asm ("push %5\n\t" + "popf\n\t" + stringify(OP) "l %k3\n\t" + "pushf\n\t" + "pop %1\n\t" + : "=a" (res), "=g" (flags), "=d" (resh) + : "q" (s1), "0" (res), "1" (flags), "2" (resh)); + printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n", + stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK); +} + +#if defined(__x86_64__) +void glue(glue(test_, OP), q)(long op0h, long op0, long op1) +{ + long res, s1, flags, resh; + s1 = op1; + resh = op0h; + res = op0; + flags = 0; + asm ("push %5\n\t" + "popf\n\t" + stringify(OP) "q %3\n\t" + "pushf\n\t" + "pop %1\n\t" + : "=a" (res), "=g" (flags), "=d" (resh) + : "q" (s1), "0" (res), "1" (flags), "2" (resh)); + printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n", + stringify(OP) "q", op0h, op0, s1, resh, res, flags & CC_MASK); +} +#endif + +#undef OP diff --git a/qemu/tests/tcg/test-i386-shift.h b/qemu/tests/tcg/test-i386-shift.h new file mode 100644 index 000000000..3d8f84bff --- /dev/null +++ b/qemu/tests/tcg/test-i386-shift.h @@ -0,0 +1,185 @@ + +#define exec_op glue(exec_, OP) +#define exec_opq glue(glue(exec_, OP), q) +#define exec_opl glue(glue(exec_, OP), l) +#define exec_opw glue(glue(exec_, OP), w) +#define exec_opb glue(glue(exec_, OP), b) + +#ifndef OP_SHIFTD + +#ifdef OP_NOBYTE +#define EXECSHIFT(size, rsize, res, s1, s2, flags) \ + asm ("push %4\n\t"\ + "popf\n\t"\ + stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \ + "pushf\n\t"\ + "pop %1\n\t"\ + : "=g" (res), "=g" (flags)\ + : "r" (s1), "0" (res), "1" (flags)); +#else +#define EXECSHIFT(size, rsize, res, s1, s2, flags) \ + asm ("push %4\n\t"\ + "popf\n\t"\ + stringify(OP) size " %%cl, %" rsize "0\n\t" \ + "pushf\n\t"\ + "pop %1\n\t"\ + : "=q" (res), "=g" (flags)\ + : "c" (s1), "0" (res), "1" (flags)); +#endif + +#if defined(__x86_64__) +void exec_opq(long s2, long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECSHIFT("q", "", res, s1, s2, flags); + /* overflow is undefined if count != 1 */ + if (s1 != 1) + flags &= ~CC_O; + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", + stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK); +} +#endif + +void exec_opl(long s2, long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECSHIFT("l", "k", res, s1, s2, flags); + /* overflow is undefined if count != 1 */ + if (s1 != 1) + flags &= ~CC_O; + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", + stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK); +} + +void exec_opw(long s2, long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECSHIFT("w", "w", res, s1, s2, flags); + /* overflow is undefined if count != 1 */ + if (s1 != 1) + flags &= ~CC_O; + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", + stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK); +} + +#else +#define EXECSHIFT(size, rsize, res, s1, s2, flags) \ + asm ("push %4\n\t"\ + "popf\n\t"\ + stringify(OP) size " %%cl, %" rsize "5, %" rsize "0\n\t" \ + "pushf\n\t"\ + "pop %1\n\t"\ + : "=g" (res), "=g" (flags)\ + : "c" (s1), "0" (res), "1" (flags), "r" (s2)); + +#if defined(__x86_64__) +void exec_opq(long s2, long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECSHIFT("q", "", res, s1, s2, flags); + /* overflow is undefined if count != 1 */ + if (s1 != 1) + flags &= ~CC_O; + printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", + stringify(OP) "q", s0, s2, s1, res, iflags, flags & CC_MASK); +} +#endif + +void exec_opl(long s2, long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECSHIFT("l", "k", res, s1, s2, flags); + /* overflow is undefined if count != 1 */ + if (s1 != 1) + flags &= ~CC_O; + printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", + stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK); +} + +void exec_opw(long s2, long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECSHIFT("w", "w", res, s1, s2, flags); + /* overflow is undefined if count != 1 */ + if (s1 != 1) + flags &= ~CC_O; + printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", + stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK); +} + +#endif + +#ifndef OP_NOBYTE +void exec_opb(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECSHIFT("b", "b", res, s1, 0, flags); + /* overflow is undefined if count != 1 */ + if (s1 != 1) + flags &= ~CC_O; + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", + stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK); +} +#endif + +void exec_op(long s2, long s0, long s1) +{ + s2 = i2l(s2); + s0 = i2l(s0); +#if defined(__x86_64__) + exec_opq(s2, s0, s1, 0); +#endif + exec_opl(s2, s0, s1, 0); +#ifdef OP_SHIFTD + exec_opw(s2, s0, s1, 0); +#else + exec_opw(s2, s0, s1, 0); +#endif +#ifndef OP_NOBYTE + exec_opb(s0, s1, 0); +#endif +#ifdef OP_CC +#if defined(__x86_64__) + exec_opq(s2, s0, s1, CC_C); +#endif + exec_opl(s2, s0, s1, CC_C); + exec_opw(s2, s0, s1, CC_C); + exec_opb(s0, s1, CC_C); +#endif +} + +void glue(test_, OP)(void) +{ + int i, n; +#if defined(__x86_64__) + n = 64; +#else + n = 32; +#endif + for(i = 0; i < n; i++) + exec_op(0x21ad3d34, 0x12345678, i); + for(i = 0; i < n; i++) + exec_op(0x813f3421, 0x82345679, i); +} + +void *glue(_test_, OP) __init_call = glue(test_, OP); + +#undef OP +#undef OP_CC +#undef OP_SHIFTD +#undef OP_NOBYTE +#undef EXECSHIFT diff --git a/qemu/tests/tcg/test-i386-ssse3.c b/qemu/tests/tcg/test-i386-ssse3.c new file mode 100644 index 000000000..0a42bd03e --- /dev/null +++ b/qemu/tests/tcg/test-i386-ssse3.c @@ -0,0 +1,57 @@ +/* See if various MMX/SSE SSSE3 instructions give expected results */ +#include <stdio.h> +#include <string.h> +#include <stdint.h> + +int main(int argc, char *argv[]) { + char hello[16]; + const char ehlo[8] = "EHLO "; + uint64_t mask = 0x8080800302020001; + + uint64_t a = 0x0000000000090007; + uint64_t b = 0x0000000000000000; + uint32_t c; + uint16_t d; + + const char e[16] = "LLOaaaaaaaaaaaaa"; + const char f[16] = "aaaaaaaaaaaaaaHE"; + + /* pshufb mm1/xmm1, mm2/xmm2 */ + asm volatile ("movq (%0), %%mm0" : : "r" (ehlo) : "mm0", "mm1"); + asm volatile ("movq %0, %%mm1" : : "m" (mask)); + asm volatile ("pshufb %mm1, %mm0"); + asm volatile ("movq %%mm0, %0" : "=m" (hello)); + printf("%s\n", hello); + + /* pshufb mm1/xmm1, m64/m128 */ + asm volatile ("movq (%0), %%mm0" : : "r" (ehlo) : "mm0"); + asm volatile ("pshufb %0, %%mm0" : : "m" (mask)); + asm volatile ("movq %%mm0, %0" : "=m" (hello)); + printf("%s\n", hello); + + /* psubsw mm1/xmm1, m64/m128 */ + asm volatile ("movq %0, %%mm0" : : "r" (a) : "mm0"); + asm volatile ("phsubsw %0, %%mm0" : : "m" (b)); + asm volatile ("movq %%mm0, %0" : "=m" (a)); + printf("%i - %i = %i\n", 9, 7, -(int16_t) a); + + /* palignr mm1/xmm1, m64/m128, imm8 */ + asm volatile ("movdqa (%0), %%xmm0" : : "r" (e) : "xmm0"); + asm volatile ("palignr $14, (%0), %%xmm0" : : "r" (f)); + asm volatile ("movdqa %%xmm0, (%0)" : : "r" (hello)); + printf("%5.5s\n", hello); + +#if 1 /* SSE4 */ + /* popcnt r64, r/m64 */ + asm volatile ("movq $0x8421000010009c63, %%rax" : : : "rax"); + asm volatile ("popcnt %%ax, %%dx" : : : "dx"); + asm volatile ("popcnt %%eax, %%ecx" : : : "ecx"); + asm volatile ("popcnt %rax, %rax"); + asm volatile ("movq %%rax, %0" : "=m" (a)); + asm volatile ("movl %%ecx, %0" : "=m" (c)); + asm volatile ("movw %%dx, %0" : "=m" (d)); + printf("%i = %i\n%i = %i = %i\n", 13, (int) a, 9, c, d + 1); +#endif + + return 0; +} diff --git a/qemu/tests/tcg/test-i386-vm86.S b/qemu/tests/tcg/test-i386-vm86.S new file mode 100644 index 000000000..3bb96c992 --- /dev/null +++ b/qemu/tests/tcg/test-i386-vm86.S @@ -0,0 +1,103 @@ + .code16 + .globl vm86_code_start + .globl vm86_code_end + +#define GET_OFFSET(x) ((x) - vm86_code_start + 0x100) + +vm86_code_start: + movw $GET_OFFSET(hello_world), %dx + movb $0x09, %ah + int $0x21 + + /* prepare int 0x90 vector */ + xorw %ax, %ax + movw %ax, %es + es movw $GET_OFFSET(int90_test), 0x90 * 4 + es movw %cs, 0x90 * 4 + 2 + + /* launch int 0x90 */ + + int $0x90 + + /* test IF support */ + movw $GET_OFFSET(IF_msg), %dx + movb $0x09, %ah + int $0x21 + + pushf + popw %dx + movb $0xff, %ah + int $0x21 + + cli + pushf + popw %dx + movb $0xff, %ah + int $0x21 + + sti + pushfl + popl %edx + movb $0xff, %ah + int $0x21 + +#if 0 + movw $GET_OFFSET(IF_msg1), %dx + movb $0x09, %ah + int $0x21 + + pushf + movw %sp, %bx + andw $~0x200, (%bx) + popf +#else + cli +#endif + + pushf + popw %dx + movb $0xff, %ah + int $0x21 + + pushfl + movw %sp, %bx + orw $0x200, (%bx) + popfl + + pushfl + popl %edx + movb $0xff, %ah + int $0x21 + + movb $0x00, %ah + int $0x21 + +int90_test: + pushf + pop %dx + movb $0xff, %ah + int $0x21 + + movw %sp, %bx + movw 4(%bx), %dx + movb $0xff, %ah + int $0x21 + + movw $GET_OFFSET(int90_msg), %dx + movb $0x09, %ah + int $0x21 + iret + +int90_msg: + .string "INT90 started\n$" + +hello_world: + .string "Hello VM86 world\n$" + +IF_msg: + .string "VM86 IF test\n$" + +IF_msg1: + .string "If you see a diff here, your Linux kernel is buggy, please update to 2.4.20 kernel\n$" + +vm86_code_end: diff --git a/qemu/tests/tcg/test-i386.c b/qemu/tests/tcg/test-i386.c new file mode 100644 index 000000000..b05572b73 --- /dev/null +++ b/qemu/tests/tcg/test-i386.c @@ -0,0 +1,2765 @@ +/* + * x86 CPU test + * + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#define _GNU_SOURCE +#include "qemu/compiler.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <math.h> +#include <signal.h> +#include <setjmp.h> +#include <errno.h> +#include <sys/ucontext.h> +#include <sys/mman.h> + +#if !defined(__x86_64__) +//#define TEST_VM86 +#define TEST_SEGS +#endif +//#define LINUX_VM86_IOPL_FIX +//#define TEST_P4_FLAGS +#ifdef __SSE__ +#define TEST_SSE +#define TEST_CMOV 1 +#define TEST_FCOMI 1 +#else +#undef TEST_SSE +#define TEST_CMOV 1 +#define TEST_FCOMI 1 +#endif + +#if defined(__x86_64__) +#define FMT64X "%016lx" +#define FMTLX "%016lx" +#define X86_64_ONLY(x) x +#else +#define FMT64X "%016" PRIx64 +#define FMTLX "%08lx" +#define X86_64_ONLY(x) +#endif + +#ifdef TEST_VM86 +#include <asm/vm86.h> +#endif + +#define xglue(x, y) x ## y +#define glue(x, y) xglue(x, y) +#define stringify(s) tostring(s) +#define tostring(s) #s + +#define CC_C 0x0001 +#define CC_P 0x0004 +#define CC_A 0x0010 +#define CC_Z 0x0040 +#define CC_S 0x0080 +#define CC_O 0x0800 + +#define __init_call __attribute__ ((unused,__section__ ("initcall"))) + +#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) + +#if defined(__x86_64__) +static inline long i2l(long v) +{ + return v | ((v ^ 0xabcd) << 32); +} +#else +static inline long i2l(long v) +{ + return v; +} +#endif + +#define OP add +#include "test-i386.h" + +#define OP sub +#include "test-i386.h" + +#define OP xor +#include "test-i386.h" + +#define OP and +#include "test-i386.h" + +#define OP or +#include "test-i386.h" + +#define OP cmp +#include "test-i386.h" + +#define OP adc +#define OP_CC +#include "test-i386.h" + +#define OP sbb +#define OP_CC +#include "test-i386.h" + +#define OP inc +#define OP_CC +#define OP1 +#include "test-i386.h" + +#define OP dec +#define OP_CC +#define OP1 +#include "test-i386.h" + +#define OP neg +#define OP_CC +#define OP1 +#include "test-i386.h" + +#define OP not +#define OP_CC +#define OP1 +#include "test-i386.h" + +#undef CC_MASK +#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O) + +#define OP shl +#include "test-i386-shift.h" + +#define OP shr +#include "test-i386-shift.h" + +#define OP sar +#include "test-i386-shift.h" + +#define OP rol +#include "test-i386-shift.h" + +#define OP ror +#include "test-i386-shift.h" + +#define OP rcr +#define OP_CC +#include "test-i386-shift.h" + +#define OP rcl +#define OP_CC +#include "test-i386-shift.h" + +#define OP shld +#define OP_SHIFTD +#define OP_NOBYTE +#include "test-i386-shift.h" + +#define OP shrd +#define OP_SHIFTD +#define OP_NOBYTE +#include "test-i386-shift.h" + +/* XXX: should be more precise ? */ +#undef CC_MASK +#define CC_MASK (CC_C) + +#define OP bt +#define OP_NOBYTE +#include "test-i386-shift.h" + +#define OP bts +#define OP_NOBYTE +#include "test-i386-shift.h" + +#define OP btr +#define OP_NOBYTE +#include "test-i386-shift.h" + +#define OP btc +#define OP_NOBYTE +#include "test-i386-shift.h" + +/* lea test (modrm support) */ +#define TEST_LEAQ(STR)\ +{\ + asm("lea " STR ", %0"\ + : "=r" (res)\ + : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ + printf("lea %s = " FMTLX "\n", STR, res);\ +} + +#define TEST_LEA(STR)\ +{\ + asm("lea " STR ", %0"\ + : "=r" (res)\ + : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ + printf("lea %s = " FMTLX "\n", STR, res);\ +} + +#define TEST_LEA16(STR)\ +{\ + asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\ + : "=r" (res)\ + : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ + printf("lea %s = %08lx\n", STR, res);\ +} + + +void test_lea(void) +{ + long eax, ebx, ecx, edx, esi, edi, res; + eax = i2l(0x0001); + ebx = i2l(0x0002); + ecx = i2l(0x0004); + edx = i2l(0x0008); + esi = i2l(0x0010); + edi = i2l(0x0020); + + TEST_LEA("0x4000"); + + TEST_LEA("(%%eax)"); + TEST_LEA("(%%ebx)"); + TEST_LEA("(%%ecx)"); + TEST_LEA("(%%edx)"); + TEST_LEA("(%%esi)"); + TEST_LEA("(%%edi)"); + + TEST_LEA("0x40(%%eax)"); + TEST_LEA("0x40(%%ebx)"); + TEST_LEA("0x40(%%ecx)"); + TEST_LEA("0x40(%%edx)"); + TEST_LEA("0x40(%%esi)"); + TEST_LEA("0x40(%%edi)"); + + TEST_LEA("0x4000(%%eax)"); + TEST_LEA("0x4000(%%ebx)"); + TEST_LEA("0x4000(%%ecx)"); + TEST_LEA("0x4000(%%edx)"); + TEST_LEA("0x4000(%%esi)"); + TEST_LEA("0x4000(%%edi)"); + + TEST_LEA("(%%eax, %%ecx)"); + TEST_LEA("(%%ebx, %%edx)"); + TEST_LEA("(%%ecx, %%ecx)"); + TEST_LEA("(%%edx, %%ecx)"); + TEST_LEA("(%%esi, %%ecx)"); + TEST_LEA("(%%edi, %%ecx)"); + + TEST_LEA("0x40(%%eax, %%ecx)"); + TEST_LEA("0x4000(%%ebx, %%edx)"); + + TEST_LEA("(%%ecx, %%ecx, 2)"); + TEST_LEA("(%%edx, %%ecx, 4)"); + TEST_LEA("(%%esi, %%ecx, 8)"); + + TEST_LEA("(,%%eax, 2)"); + TEST_LEA("(,%%ebx, 4)"); + TEST_LEA("(,%%ecx, 8)"); + + TEST_LEA("0x40(,%%eax, 2)"); + TEST_LEA("0x40(,%%ebx, 4)"); + TEST_LEA("0x40(,%%ecx, 8)"); + + + TEST_LEA("-10(%%ecx, %%ecx, 2)"); + TEST_LEA("-10(%%edx, %%ecx, 4)"); + TEST_LEA("-10(%%esi, %%ecx, 8)"); + + TEST_LEA("0x4000(%%ecx, %%ecx, 2)"); + TEST_LEA("0x4000(%%edx, %%ecx, 4)"); + TEST_LEA("0x4000(%%esi, %%ecx, 8)"); + +#if defined(__x86_64__) + TEST_LEAQ("0x4000"); + TEST_LEAQ("0x4000(%%rip)"); + + TEST_LEAQ("(%%rax)"); + TEST_LEAQ("(%%rbx)"); + TEST_LEAQ("(%%rcx)"); + TEST_LEAQ("(%%rdx)"); + TEST_LEAQ("(%%rsi)"); + TEST_LEAQ("(%%rdi)"); + + TEST_LEAQ("0x40(%%rax)"); + TEST_LEAQ("0x40(%%rbx)"); + TEST_LEAQ("0x40(%%rcx)"); + TEST_LEAQ("0x40(%%rdx)"); + TEST_LEAQ("0x40(%%rsi)"); + TEST_LEAQ("0x40(%%rdi)"); + + TEST_LEAQ("0x4000(%%rax)"); + TEST_LEAQ("0x4000(%%rbx)"); + TEST_LEAQ("0x4000(%%rcx)"); + TEST_LEAQ("0x4000(%%rdx)"); + TEST_LEAQ("0x4000(%%rsi)"); + TEST_LEAQ("0x4000(%%rdi)"); + + TEST_LEAQ("(%%rax, %%rcx)"); + TEST_LEAQ("(%%rbx, %%rdx)"); + TEST_LEAQ("(%%rcx, %%rcx)"); + TEST_LEAQ("(%%rdx, %%rcx)"); + TEST_LEAQ("(%%rsi, %%rcx)"); + TEST_LEAQ("(%%rdi, %%rcx)"); + + TEST_LEAQ("0x40(%%rax, %%rcx)"); + TEST_LEAQ("0x4000(%%rbx, %%rdx)"); + + TEST_LEAQ("(%%rcx, %%rcx, 2)"); + TEST_LEAQ("(%%rdx, %%rcx, 4)"); + TEST_LEAQ("(%%rsi, %%rcx, 8)"); + + TEST_LEAQ("(,%%rax, 2)"); + TEST_LEAQ("(,%%rbx, 4)"); + TEST_LEAQ("(,%%rcx, 8)"); + + TEST_LEAQ("0x40(,%%rax, 2)"); + TEST_LEAQ("0x40(,%%rbx, 4)"); + TEST_LEAQ("0x40(,%%rcx, 8)"); + + + TEST_LEAQ("-10(%%rcx, %%rcx, 2)"); + TEST_LEAQ("-10(%%rdx, %%rcx, 4)"); + TEST_LEAQ("-10(%%rsi, %%rcx, 8)"); + + TEST_LEAQ("0x4000(%%rcx, %%rcx, 2)"); + TEST_LEAQ("0x4000(%%rdx, %%rcx, 4)"); + TEST_LEAQ("0x4000(%%rsi, %%rcx, 8)"); +#else + /* limited 16 bit addressing test */ + TEST_LEA16("0x4000"); + TEST_LEA16("(%%bx)"); + TEST_LEA16("(%%si)"); + TEST_LEA16("(%%di)"); + TEST_LEA16("0x40(%%bx)"); + TEST_LEA16("0x40(%%si)"); + TEST_LEA16("0x40(%%di)"); + TEST_LEA16("0x4000(%%bx)"); + TEST_LEA16("0x4000(%%si)"); + TEST_LEA16("(%%bx,%%si)"); + TEST_LEA16("(%%bx,%%di)"); + TEST_LEA16("0x40(%%bx,%%si)"); + TEST_LEA16("0x40(%%bx,%%di)"); + TEST_LEA16("0x4000(%%bx,%%si)"); + TEST_LEA16("0x4000(%%bx,%%di)"); +#endif +} + +#define TEST_JCC(JCC, v1, v2)\ +{\ + int res;\ + asm("movl $1, %0\n\t"\ + "cmpl %2, %1\n\t"\ + "j" JCC " 1f\n\t"\ + "movl $0, %0\n\t"\ + "1:\n\t"\ + : "=r" (res)\ + : "r" (v1), "r" (v2));\ + printf("%-10s %d\n", "j" JCC, res);\ +\ + asm("movl $0, %0\n\t"\ + "cmpl %2, %1\n\t"\ + "set" JCC " %b0\n\t"\ + : "=r" (res)\ + : "r" (v1), "r" (v2));\ + printf("%-10s %d\n", "set" JCC, res);\ + if (TEST_CMOV) {\ + long val = i2l(1);\ + long res = i2l(0x12345678);\ +X86_64_ONLY(\ + asm("cmpl %2, %1\n\t"\ + "cmov" JCC "q %3, %0\n\t"\ + : "=r" (res)\ + : "r" (v1), "r" (v2), "m" (val), "0" (res));\ + printf("%-10s R=" FMTLX "\n", "cmov" JCC "q", res);)\ + asm("cmpl %2, %1\n\t"\ + "cmov" JCC "l %k3, %k0\n\t"\ + : "=r" (res)\ + : "r" (v1), "r" (v2), "m" (val), "0" (res));\ + printf("%-10s R=" FMTLX "\n", "cmov" JCC "l", res);\ + asm("cmpl %2, %1\n\t"\ + "cmov" JCC "w %w3, %w0\n\t"\ + : "=r" (res)\ + : "r" (v1), "r" (v2), "r" (1), "0" (res));\ + printf("%-10s R=" FMTLX "\n", "cmov" JCC "w", res);\ + } \ +} + +/* various jump tests */ +void test_jcc(void) +{ + TEST_JCC("ne", 1, 1); + TEST_JCC("ne", 1, 0); + + TEST_JCC("e", 1, 1); + TEST_JCC("e", 1, 0); + + TEST_JCC("l", 1, 1); + TEST_JCC("l", 1, 0); + TEST_JCC("l", 1, -1); + + TEST_JCC("le", 1, 1); + TEST_JCC("le", 1, 0); + TEST_JCC("le", 1, -1); + + TEST_JCC("ge", 1, 1); + TEST_JCC("ge", 1, 0); + TEST_JCC("ge", -1, 1); + + TEST_JCC("g", 1, 1); + TEST_JCC("g", 1, 0); + TEST_JCC("g", 1, -1); + + TEST_JCC("b", 1, 1); + TEST_JCC("b", 1, 0); + TEST_JCC("b", 1, -1); + + TEST_JCC("be", 1, 1); + TEST_JCC("be", 1, 0); + TEST_JCC("be", 1, -1); + + TEST_JCC("ae", 1, 1); + TEST_JCC("ae", 1, 0); + TEST_JCC("ae", 1, -1); + + TEST_JCC("a", 1, 1); + TEST_JCC("a", 1, 0); + TEST_JCC("a", 1, -1); + + + TEST_JCC("p", 1, 1); + TEST_JCC("p", 1, 0); + + TEST_JCC("np", 1, 1); + TEST_JCC("np", 1, 0); + + TEST_JCC("o", 0x7fffffff, 0); + TEST_JCC("o", 0x7fffffff, -1); + + TEST_JCC("no", 0x7fffffff, 0); + TEST_JCC("no", 0x7fffffff, -1); + + TEST_JCC("s", 0, 1); + TEST_JCC("s", 0, -1); + TEST_JCC("s", 0, 0); + + TEST_JCC("ns", 0, 1); + TEST_JCC("ns", 0, -1); + TEST_JCC("ns", 0, 0); +} + +#define TEST_LOOP(insn) \ +{\ + for(i = 0; i < sizeof(ecx_vals) / sizeof(long); i++) {\ + ecx = ecx_vals[i];\ + for(zf = 0; zf < 2; zf++) {\ + asm("test %2, %2\n\t"\ + "movl $1, %0\n\t"\ + insn " 1f\n\t" \ + "movl $0, %0\n\t"\ + "1:\n\t"\ + : "=a" (res)\ + : "c" (ecx), "b" (!zf)); \ + printf("%-10s ECX=" FMTLX " ZF=%ld r=%d\n", insn, ecx, zf, res); \ + }\ + }\ +} + +void test_loop(void) +{ + long ecx, zf; + const long ecx_vals[] = { + 0, + 1, + 0x10000, + 0x10001, +#if defined(__x86_64__) + 0x100000000L, + 0x100000001L, +#endif + }; + int i, res; + +#if !defined(__x86_64__) + TEST_LOOP("jcxz"); + TEST_LOOP("loopw"); + TEST_LOOP("loopzw"); + TEST_LOOP("loopnzw"); +#endif + + TEST_LOOP("jecxz"); + TEST_LOOP("loopl"); + TEST_LOOP("loopzl"); + TEST_LOOP("loopnzl"); +} + +#undef CC_MASK +#ifdef TEST_P4_FLAGS +#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) +#else +#define CC_MASK (CC_O | CC_C) +#endif + +#define OP mul +#include "test-i386-muldiv.h" + +#define OP imul +#include "test-i386-muldiv.h" + +void test_imulw2(long op0, long op1) +{ + long res, s1, s0, flags; + s0 = op0; + s1 = op1; + res = s0; + flags = 0; + asm volatile ("push %4\n\t" + "popf\n\t" + "imulw %w2, %w0\n\t" + "pushf\n\t" + "pop %1\n\t" + : "=q" (res), "=g" (flags) + : "q" (s1), "0" (res), "1" (flags)); + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n", + "imulw", s0, s1, res, flags & CC_MASK); +} + +void test_imull2(long op0, long op1) +{ + long res, s1, s0, flags; + s0 = op0; + s1 = op1; + res = s0; + flags = 0; + asm volatile ("push %4\n\t" + "popf\n\t" + "imull %k2, %k0\n\t" + "pushf\n\t" + "pop %1\n\t" + : "=q" (res), "=g" (flags) + : "q" (s1), "0" (res), "1" (flags)); + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n", + "imull", s0, s1, res, flags & CC_MASK); +} + +#if defined(__x86_64__) +void test_imulq2(long op0, long op1) +{ + long res, s1, s0, flags; + s0 = op0; + s1 = op1; + res = s0; + flags = 0; + asm volatile ("push %4\n\t" + "popf\n\t" + "imulq %2, %0\n\t" + "pushf\n\t" + "pop %1\n\t" + : "=q" (res), "=g" (flags) + : "q" (s1), "0" (res), "1" (flags)); + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n", + "imulq", s0, s1, res, flags & CC_MASK); +} +#endif + +#define TEST_IMUL_IM(size, rsize, op0, op1)\ +{\ + long res, flags, s1;\ + flags = 0;\ + res = 0;\ + s1 = op1;\ + asm volatile ("push %3\n\t"\ + "popf\n\t"\ + "imul" size " $" #op0 ", %" rsize "2, %" rsize "0\n\t" \ + "pushf\n\t"\ + "pop %1\n\t"\ + : "=r" (res), "=g" (flags)\ + : "r" (s1), "1" (flags), "0" (res));\ + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",\ + "imul" size " im", (long)op0, (long)op1, res, flags & CC_MASK);\ +} + + +#undef CC_MASK +#define CC_MASK (0) + +#define OP div +#include "test-i386-muldiv.h" + +#define OP idiv +#include "test-i386-muldiv.h" + +void test_mul(void) +{ + test_imulb(0x1234561d, 4); + test_imulb(3, -4); + test_imulb(0x80, 0x80); + test_imulb(0x10, 0x10); + + test_imulw(0, 0x1234001d, 45); + test_imulw(0, 23, -45); + test_imulw(0, 0x8000, 0x8000); + test_imulw(0, 0x100, 0x100); + + test_imull(0, 0x1234001d, 45); + test_imull(0, 23, -45); + test_imull(0, 0x80000000, 0x80000000); + test_imull(0, 0x10000, 0x10000); + + test_mulb(0x1234561d, 4); + test_mulb(3, -4); + test_mulb(0x80, 0x80); + test_mulb(0x10, 0x10); + + test_mulw(0, 0x1234001d, 45); + test_mulw(0, 23, -45); + test_mulw(0, 0x8000, 0x8000); + test_mulw(0, 0x100, 0x100); + + test_mull(0, 0x1234001d, 45); + test_mull(0, 23, -45); + test_mull(0, 0x80000000, 0x80000000); + test_mull(0, 0x10000, 0x10000); + + test_imulw2(0x1234001d, 45); + test_imulw2(23, -45); + test_imulw2(0x8000, 0x8000); + test_imulw2(0x100, 0x100); + + test_imull2(0x1234001d, 45); + test_imull2(23, -45); + test_imull2(0x80000000, 0x80000000); + test_imull2(0x10000, 0x10000); + + TEST_IMUL_IM("w", "w", 45, 0x1234); + TEST_IMUL_IM("w", "w", -45, 23); + TEST_IMUL_IM("w", "w", 0x8000, 0x80000000); + TEST_IMUL_IM("w", "w", 0x7fff, 0x1000); + + TEST_IMUL_IM("l", "k", 45, 0x1234); + TEST_IMUL_IM("l", "k", -45, 23); + TEST_IMUL_IM("l", "k", 0x8000, 0x80000000); + TEST_IMUL_IM("l", "k", 0x7fff, 0x1000); + + test_idivb(0x12341678, 0x127e); + test_idivb(0x43210123, -5); + test_idivb(0x12340004, -1); + + test_idivw(0, 0x12345678, 12347); + test_idivw(0, -23223, -45); + test_idivw(0, 0x12348000, -1); + test_idivw(0x12343, 0x12345678, 0x81238567); + + test_idivl(0, 0x12345678, 12347); + test_idivl(0, -233223, -45); + test_idivl(0, 0x80000000, -1); + test_idivl(0x12343, 0x12345678, 0x81234567); + + test_divb(0x12341678, 0x127e); + test_divb(0x43210123, -5); + test_divb(0x12340004, -1); + + test_divw(0, 0x12345678, 12347); + test_divw(0, -23223, -45); + test_divw(0, 0x12348000, -1); + test_divw(0x12343, 0x12345678, 0x81238567); + + test_divl(0, 0x12345678, 12347); + test_divl(0, -233223, -45); + test_divl(0, 0x80000000, -1); + test_divl(0x12343, 0x12345678, 0x81234567); + +#if defined(__x86_64__) + test_imulq(0, 0x1234001d1234001d, 45); + test_imulq(0, 23, -45); + test_imulq(0, 0x8000000000000000, 0x8000000000000000); + test_imulq(0, 0x100000000, 0x100000000); + + test_mulq(0, 0x1234001d1234001d, 45); + test_mulq(0, 23, -45); + test_mulq(0, 0x8000000000000000, 0x8000000000000000); + test_mulq(0, 0x100000000, 0x100000000); + + test_imulq2(0x1234001d1234001d, 45); + test_imulq2(23, -45); + test_imulq2(0x8000000000000000, 0x8000000000000000); + test_imulq2(0x100000000, 0x100000000); + + TEST_IMUL_IM("q", "", 45, 0x12341234); + TEST_IMUL_IM("q", "", -45, 23); + TEST_IMUL_IM("q", "", 0x8000, 0x8000000000000000); + TEST_IMUL_IM("q", "", 0x7fff, 0x10000000); + + test_idivq(0, 0x12345678abcdef, 12347); + test_idivq(0, -233223, -45); + test_idivq(0, 0x8000000000000000, -1); + test_idivq(0x12343, 0x12345678, 0x81234567); + + test_divq(0, 0x12345678abcdef, 12347); + test_divq(0, -233223, -45); + test_divq(0, 0x8000000000000000, -1); + test_divq(0x12343, 0x12345678, 0x81234567); +#endif +} + +#define TEST_BSX(op, size, op0)\ +{\ + long res, val, resz;\ + val = op0;\ + asm("xor %1, %1\n"\ + "mov $0x12345678, %0\n"\ + #op " %" size "2, %" size "0 ; setz %b1" \ + : "=&r" (res), "=&q" (resz)\ + : "r" (val));\ + printf("%-10s A=" FMTLX " R=" FMTLX " %ld\n", #op, val, res, resz);\ +} + +void test_bsx(void) +{ + TEST_BSX(bsrw, "w", 0); + TEST_BSX(bsrw, "w", 0x12340128); + TEST_BSX(bsfw, "w", 0); + TEST_BSX(bsfw, "w", 0x12340128); + TEST_BSX(bsrl, "k", 0); + TEST_BSX(bsrl, "k", 0x00340128); + TEST_BSX(bsfl, "k", 0); + TEST_BSX(bsfl, "k", 0x00340128); +#if defined(__x86_64__) + TEST_BSX(bsrq, "", 0); + TEST_BSX(bsrq, "", 0x003401281234); + TEST_BSX(bsfq, "", 0); + TEST_BSX(bsfq, "", 0x003401281234); +#endif +} + +/**********************************************/ + +union float64u { + double d; + uint64_t l; +}; + +union float64u q_nan = { .l = 0xFFF8000000000000LL }; +union float64u s_nan = { .l = 0xFFF0000000000000LL }; + +void test_fops(double a, double b) +{ + printf("a=%f b=%f a+b=%f\n", a, b, a + b); + printf("a=%f b=%f a-b=%f\n", a, b, a - b); + printf("a=%f b=%f a*b=%f\n", a, b, a * b); + printf("a=%f b=%f a/b=%f\n", a, b, a / b); + printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b)); + printf("a=%f sqrt(a)=%f\n", a, sqrt(a)); + printf("a=%f sin(a)=%f\n", a, sin(a)); + printf("a=%f cos(a)=%f\n", a, cos(a)); + printf("a=%f tan(a)=%f\n", a, tan(a)); + printf("a=%f log(a)=%f\n", a, log(a)); + printf("a=%f exp(a)=%f\n", a, exp(a)); + printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b)); + /* just to test some op combining */ + printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a))); + printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a))); + printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a))); + +} + +void fpu_clear_exceptions(void) +{ + struct QEMU_PACKED { + uint16_t fpuc; + uint16_t dummy1; + uint16_t fpus; + uint16_t dummy2; + uint16_t fptag; + uint16_t dummy3; + uint32_t ignored[4]; + long double fpregs[8]; + } float_env32; + + asm volatile ("fnstenv %0\n" : "=m" (float_env32)); + float_env32.fpus &= ~0x7f; + asm volatile ("fldenv %0\n" : : "m" (float_env32)); +} + +/* XXX: display exception bits when supported */ +#define FPUS_EMASK 0x0000 +//#define FPUS_EMASK 0x007f + +void test_fcmp(double a, double b) +{ + long eflags, fpus; + + fpu_clear_exceptions(); + asm("fcom %2\n" + "fstsw %%ax\n" + : "=a" (fpus) + : "t" (a), "u" (b)); + printf("fcom(%f %f)=%04lx\n", + a, b, fpus & (0x4500 | FPUS_EMASK)); + fpu_clear_exceptions(); + asm("fucom %2\n" + "fstsw %%ax\n" + : "=a" (fpus) + : "t" (a), "u" (b)); + printf("fucom(%f %f)=%04lx\n", + a, b, fpus & (0x4500 | FPUS_EMASK)); + if (TEST_FCOMI) { + /* test f(u)comi instruction */ + fpu_clear_exceptions(); + asm("fcomi %3, %2\n" + "fstsw %%ax\n" + "pushf\n" + "pop %0\n" + : "=r" (eflags), "=a" (fpus) + : "t" (a), "u" (b)); + printf("fcomi(%f %f)=%04lx %02lx\n", + a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C)); + fpu_clear_exceptions(); + asm("fucomi %3, %2\n" + "fstsw %%ax\n" + "pushf\n" + "pop %0\n" + : "=r" (eflags), "=a" (fpus) + : "t" (a), "u" (b)); + printf("fucomi(%f %f)=%04lx %02lx\n", + a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C)); + } + fpu_clear_exceptions(); + asm volatile("fxam\n" + "fstsw %%ax\n" + : "=a" (fpus) + : "t" (a)); + printf("fxam(%f)=%04lx\n", a, fpus & 0x4700); + fpu_clear_exceptions(); +} + +void test_fcvt(double a) +{ + float fa; + long double la; + int16_t fpuc; + int i; + int64_t lla; + int ia; + int16_t wa; + double ra; + + fa = a; + la = a; + printf("(float)%f = %f\n", a, fa); + printf("(long double)%f = %Lf\n", a, la); + printf("a=" FMT64X "\n", *(uint64_t *)&a); + printf("la=" FMT64X " %04x\n", *(uint64_t *)&la, + *(unsigned short *)((char *)(&la) + 8)); + + /* test all roundings */ + asm volatile ("fstcw %0" : "=m" (fpuc)); + for(i=0;i<4;i++) { + uint16_t val16; + val16 = (fpuc & ~0x0c00) | (i << 10); + asm volatile ("fldcw %0" : : "m" (val16)); + asm volatile ("fist %0" : "=m" (wa) : "t" (a)); + asm volatile ("fistl %0" : "=m" (ia) : "t" (a)); + asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st"); + asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a)); + asm volatile ("fldcw %0" : : "m" (fpuc)); + printf("(short)a = %d\n", wa); + printf("(int)a = %d\n", ia); + printf("(int64_t)a = " FMT64X "\n", lla); + printf("rint(a) = %f\n", ra); + } +} + +#define TEST(N) \ + asm("fld" #N : "=t" (a)); \ + printf("fld" #N "= %f\n", a); + +void test_fconst(void) +{ + double a; + TEST(1); + TEST(l2t); + TEST(l2e); + TEST(pi); + TEST(lg2); + TEST(ln2); + TEST(z); +} + +void test_fbcd(double a) +{ + unsigned short bcd[5]; + double b; + + asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st"); + asm("fbld %1" : "=t" (b) : "m" (bcd[0])); + printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n", + a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b); +} + +#define TEST_ENV(env, save, restore)\ +{\ + memset((env), 0xaa, sizeof(*(env)));\ + for(i=0;i<5;i++)\ + asm volatile ("fldl %0" : : "m" (dtab[i]));\ + asm volatile (save " %0\n" : : "m" (*(env)));\ + asm volatile (restore " %0\n": : "m" (*(env)));\ + for(i=0;i<5;i++)\ + asm volatile ("fstpl %0" : "=m" (rtab[i]));\ + for(i=0;i<5;i++)\ + printf("res[%d]=%f\n", i, rtab[i]);\ + printf("fpuc=%04x fpus=%04x fptag=%04x\n",\ + (env)->fpuc,\ + (env)->fpus & 0xff00,\ + (env)->fptag);\ +} + +void test_fenv(void) +{ + struct __attribute__((__packed__)) { + uint16_t fpuc; + uint16_t dummy1; + uint16_t fpus; + uint16_t dummy2; + uint16_t fptag; + uint16_t dummy3; + uint32_t ignored[4]; + long double fpregs[8]; + } float_env32; + struct __attribute__((__packed__)) { + uint16_t fpuc; + uint16_t fpus; + uint16_t fptag; + uint16_t ignored[4]; + long double fpregs[8]; + } float_env16; + double dtab[8]; + double rtab[8]; + int i; + + for(i=0;i<8;i++) + dtab[i] = i + 1; + + TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv"); + TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor"); + TEST_ENV(&float_env32, "fnstenv", "fldenv"); + TEST_ENV(&float_env32, "fnsave", "frstor"); + + /* test for ffree */ + for(i=0;i<5;i++) + asm volatile ("fldl %0" : : "m" (dtab[i])); + asm volatile("ffree %st(2)"); + asm volatile ("fnstenv %0\n" : : "m" (float_env32)); + asm volatile ("fninit"); + printf("fptag=%04x\n", float_env32.fptag); +} + + +#define TEST_FCMOV(a, b, eflags, CC)\ +{\ + double res;\ + asm("push %3\n"\ + "popf\n"\ + "fcmov" CC " %2, %0\n"\ + : "=t" (res)\ + : "0" (a), "u" (b), "g" (eflags));\ + printf("fcmov%s eflags=0x%04lx-> %f\n", \ + CC, (long)eflags, res);\ +} + +void test_fcmov(void) +{ + double a, b; + long eflags, i; + + a = 1.0; + b = 2.0; + for(i = 0; i < 4; i++) { + eflags = 0; + if (i & 1) + eflags |= CC_C; + if (i & 2) + eflags |= CC_Z; + TEST_FCMOV(a, b, eflags, "b"); + TEST_FCMOV(a, b, eflags, "e"); + TEST_FCMOV(a, b, eflags, "be"); + TEST_FCMOV(a, b, eflags, "nb"); + TEST_FCMOV(a, b, eflags, "ne"); + TEST_FCMOV(a, b, eflags, "nbe"); + } + TEST_FCMOV(a, b, 0, "u"); + TEST_FCMOV(a, b, CC_P, "u"); + TEST_FCMOV(a, b, 0, "nu"); + TEST_FCMOV(a, b, CC_P, "nu"); +} + +void test_floats(void) +{ + test_fops(2, 3); + test_fops(1.4, -5); + test_fcmp(2, -1); + test_fcmp(2, 2); + test_fcmp(2, 3); + test_fcmp(2, q_nan.d); + test_fcmp(q_nan.d, -1); + test_fcmp(-1.0/0.0, -1); + test_fcmp(1.0/0.0, -1); + test_fcvt(0.5); + test_fcvt(-0.5); + test_fcvt(1.0/7.0); + test_fcvt(-1.0/9.0); + test_fcvt(32768); + test_fcvt(-1e20); + test_fcvt(-1.0/0.0); + test_fcvt(1.0/0.0); + test_fcvt(q_nan.d); + test_fconst(); + test_fbcd(1234567890123456.0); + test_fbcd(-123451234567890.0); + test_fenv(); + if (TEST_CMOV) { + test_fcmov(); + } +} + +/**********************************************/ +#if !defined(__x86_64__) + +#define TEST_BCD(op, op0, cc_in, cc_mask)\ +{\ + int res, flags;\ + res = op0;\ + flags = cc_in;\ + asm ("push %3\n\t"\ + "popf\n\t"\ + #op "\n\t"\ + "pushf\n\t"\ + "pop %1\n\t"\ + : "=a" (res), "=g" (flags)\ + : "0" (res), "1" (flags));\ + printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\ + #op, op0, res, cc_in, flags & cc_mask);\ +} + +void test_bcd(void) +{ + TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + + TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); + + TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A)); + TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A)); + TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A)); + TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A)); + TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A)); + TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A)); + TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A)); + TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A)); + + TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A)); + TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A)); + TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A)); + TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A)); + TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A)); + TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A)); + TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A)); + TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A)); + + TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); + TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); +} +#endif + +#define TEST_XCHG(op, size, opconst)\ +{\ + long op0, op1;\ + op0 = i2l(0x12345678);\ + op1 = i2l(0xfbca7654);\ + asm(#op " %" size "0, %" size "1" \ + : "=q" (op0), opconst (op1) \ + : "0" (op0));\ + printf("%-10s A=" FMTLX " B=" FMTLX "\n",\ + #op, op0, op1);\ +} + +#define TEST_CMPXCHG(op, size, opconst, eax)\ +{\ + long op0, op1, op2;\ + op0 = i2l(0x12345678);\ + op1 = i2l(0xfbca7654);\ + op2 = i2l(eax);\ + asm(#op " %" size "0, %" size "1" \ + : "=q" (op0), opconst (op1) \ + : "0" (op0), "a" (op2));\ + printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\ + #op, op2, op0, op1);\ +} + +void test_xchg(void) +{ +#if defined(__x86_64__) + TEST_XCHG(xchgq, "", "+q"); +#endif + TEST_XCHG(xchgl, "k", "+q"); + TEST_XCHG(xchgw, "w", "+q"); + TEST_XCHG(xchgb, "b", "+q"); + +#if defined(__x86_64__) + TEST_XCHG(xchgq, "", "=m"); +#endif + TEST_XCHG(xchgl, "k", "+m"); + TEST_XCHG(xchgw, "w", "+m"); + TEST_XCHG(xchgb, "b", "+m"); + +#if defined(__x86_64__) + TEST_XCHG(xaddq, "", "+q"); +#endif + TEST_XCHG(xaddl, "k", "+q"); + TEST_XCHG(xaddw, "w", "+q"); + TEST_XCHG(xaddb, "b", "+q"); + + { + int res; + res = 0x12345678; + asm("xaddl %1, %0" : "=r" (res) : "0" (res)); + printf("xaddl same res=%08x\n", res); + } + +#if defined(__x86_64__) + TEST_XCHG(xaddq, "", "+m"); +#endif + TEST_XCHG(xaddl, "k", "+m"); + TEST_XCHG(xaddw, "w", "+m"); + TEST_XCHG(xaddb, "b", "+m"); + +#if defined(__x86_64__) + TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfbca7654); +#endif + TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfbca7654); + TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfbca7654); + TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfbca7654); + +#if defined(__x86_64__) + TEST_CMPXCHG(cmpxchgq, "", "+q", 0xfffefdfc); +#endif + TEST_CMPXCHG(cmpxchgl, "k", "+q", 0xfffefdfc); + TEST_CMPXCHG(cmpxchgw, "w", "+q", 0xfffefdfc); + TEST_CMPXCHG(cmpxchgb, "b", "+q", 0xfffefdfc); + +#if defined(__x86_64__) + TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfbca7654); +#endif + TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfbca7654); + TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfbca7654); + TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfbca7654); + +#if defined(__x86_64__) + TEST_CMPXCHG(cmpxchgq, "", "+m", 0xfffefdfc); +#endif + TEST_CMPXCHG(cmpxchgl, "k", "+m", 0xfffefdfc); + TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfffefdfc); + TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfffefdfc); + + { + uint64_t op0, op1, op2; + long eax, edx; + long i, eflags; + + for(i = 0; i < 2; i++) { + op0 = 0x123456789abcdLL; + eax = i2l(op0 & 0xffffffff); + edx = i2l(op0 >> 32); + if (i == 0) + op1 = 0xfbca765423456LL; + else + op1 = op0; + op2 = 0x6532432432434LL; + asm("cmpxchg8b %2\n" + "pushf\n" + "pop %3\n" + : "=a" (eax), "=d" (edx), "=m" (op1), "=g" (eflags) + : "0" (eax), "1" (edx), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32))); + printf("cmpxchg8b: eax=" FMTLX " edx=" FMTLX " op1=" FMT64X " CC=%02lx\n", + eax, edx, op1, eflags & CC_Z); + } + } +} + +#ifdef TEST_SEGS +/**********************************************/ +/* segmentation tests */ + +#include <sys/syscall.h> +#include <unistd.h> +#include <asm/ldt.h> +#include <linux/version.h> + +static inline int modify_ldt(int func, void * ptr, unsigned long bytecount) +{ + return syscall(__NR_modify_ldt, func, ptr, bytecount); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66) +#define modify_ldt_ldt_s user_desc +#endif + +#define MK_SEL(n) (((n) << 3) | 7) + +uint8_t seg_data1[4096]; +uint8_t seg_data2[4096]; + +#define TEST_LR(op, size, seg, mask)\ +{\ + int res, res2;\ + uint16_t mseg = seg;\ + res = 0x12345678;\ + asm (op " %" size "2, %" size "0\n" \ + "movl $0, %1\n"\ + "jnz 1f\n"\ + "movl $1, %1\n"\ + "1:\n"\ + : "=r" (res), "=r" (res2) : "m" (mseg), "0" (res));\ + printf(op ": Z=%d %08x\n", res2, res & ~(mask));\ +} + +#define TEST_ARPL(op, size, op1, op2)\ +{\ + long a, b, c; \ + a = (op1); \ + b = (op2); \ + asm volatile(op " %" size "3, %" size "0\n"\ + "movl $0,%1\n"\ + "jnz 1f\n"\ + "movl $1,%1\n"\ + "1:\n"\ + : "=r" (a), "=r" (c) : "0" (a), "r" (b)); \ + printf(op size " A=" FMTLX " B=" FMTLX " R=" FMTLX " z=%ld\n",\ + (long)(op1), (long)(op2), a, c);\ +} + +/* NOTE: we use Linux modify_ldt syscall */ +void test_segs(void) +{ + struct modify_ldt_ldt_s ldt; + long long ldt_table[3]; + int res, res2; + char tmp; + struct { + uint32_t offset; + uint16_t seg; + } __attribute__((__packed__)) segoff; + + ldt.entry_number = 1; + ldt.base_addr = (unsigned long)&seg_data1; + ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; + ldt.seg_32bit = 1; + ldt.contents = MODIFY_LDT_CONTENTS_DATA; + ldt.read_exec_only = 0; + ldt.limit_in_pages = 1; + ldt.seg_not_present = 0; + ldt.useable = 1; + modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ + + ldt.entry_number = 2; + ldt.base_addr = (unsigned long)&seg_data2; + ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12; + ldt.seg_32bit = 1; + ldt.contents = MODIFY_LDT_CONTENTS_DATA; + ldt.read_exec_only = 0; + ldt.limit_in_pages = 1; + ldt.seg_not_present = 0; + ldt.useable = 1; + modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ + + modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */ +#if 0 + { + int i; + for(i=0;i<3;i++) + printf("%d: %016Lx\n", i, ldt_table[i]); + } +#endif + /* do some tests with fs or gs */ + asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); + + seg_data1[1] = 0xaa; + seg_data2[1] = 0x55; + + asm volatile ("fs movzbl 0x1, %0" : "=r" (res)); + printf("FS[1] = %02x\n", res); + + asm volatile ("pushl %%gs\n" + "movl %1, %%gs\n" + "gs movzbl 0x1, %0\n" + "popl %%gs\n" + : "=r" (res) + : "r" (MK_SEL(2))); + printf("GS[1] = %02x\n", res); + + /* tests with ds/ss (implicit segment case) */ + tmp = 0xa5; + asm volatile ("pushl %%ebp\n\t" + "pushl %%ds\n\t" + "movl %2, %%ds\n\t" + "movl %3, %%ebp\n\t" + "movzbl 0x1, %0\n\t" + "movzbl (%%ebp), %1\n\t" + "popl %%ds\n\t" + "popl %%ebp\n\t" + : "=r" (res), "=r" (res2) + : "r" (MK_SEL(1)), "r" (&tmp)); + printf("DS[1] = %02x\n", res); + printf("SS[tmp] = %02x\n", res2); + + segoff.seg = MK_SEL(2); + segoff.offset = 0xabcdef12; + asm volatile("lfs %2, %0\n\t" + "movl %%fs, %1\n\t" + : "=r" (res), "=g" (res2) + : "m" (segoff)); + printf("FS:reg = %04x:%08x\n", res2, res); + + TEST_LR("larw", "w", MK_SEL(2), 0x0100); + TEST_LR("larl", "", MK_SEL(2), 0x0100); + TEST_LR("lslw", "w", MK_SEL(2), 0); + TEST_LR("lsll", "", MK_SEL(2), 0); + + TEST_LR("larw", "w", 0xfff8, 0); + TEST_LR("larl", "", 0xfff8, 0); + TEST_LR("lslw", "w", 0xfff8, 0); + TEST_LR("lsll", "", 0xfff8, 0); + + TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1); + TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3); + TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1); +} + +/* 16 bit code test */ +extern char code16_start, code16_end; +extern char code16_func1; +extern char code16_func2; +extern char code16_func3; + +void test_code16(void) +{ + struct modify_ldt_ldt_s ldt; + int res, res2; + + /* build a code segment */ + ldt.entry_number = 1; + ldt.base_addr = (unsigned long)&code16_start; + ldt.limit = &code16_end - &code16_start; + ldt.seg_32bit = 0; + ldt.contents = MODIFY_LDT_CONTENTS_CODE; + ldt.read_exec_only = 0; + ldt.limit_in_pages = 0; + ldt.seg_not_present = 0; + ldt.useable = 1; + modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ + + /* call the first function */ + asm volatile ("lcall %1, %2" + : "=a" (res) + : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc"); + printf("func1() = 0x%08x\n", res); + asm volatile ("lcall %2, %3" + : "=a" (res), "=c" (res2) + : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc"); + printf("func2() = 0x%08x spdec=%d\n", res, res2); + asm volatile ("lcall %1, %2" + : "=a" (res) + : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc"); + printf("func3() = 0x%08x\n", res); +} +#endif + +#if defined(__x86_64__) +asm(".globl func_lret\n" + "func_lret:\n" + "movl $0x87654641, %eax\n" + "lretq\n"); +#else +asm(".globl func_lret\n" + "func_lret:\n" + "movl $0x87654321, %eax\n" + "lret\n" + + ".globl func_iret\n" + "func_iret:\n" + "movl $0xabcd4321, %eax\n" + "iret\n"); +#endif + +extern char func_lret; +extern char func_iret; + +void test_misc(void) +{ + char table[256]; + long res, i; + + for(i=0;i<256;i++) table[i] = 256 - i; + res = 0x12345678; + asm ("xlat" : "=a" (res) : "b" (table), "0" (res)); + printf("xlat: EAX=" FMTLX "\n", res); + +#if defined(__x86_64__) +#if 0 + { + /* XXX: see if Intel Core2 and AMD64 behavior really + differ. Here we implemented the Intel way which is not + compatible yet with QEMU. */ + static struct QEMU_PACKED { + uint64_t offset; + uint16_t seg; + } desc; + long cs_sel; + + asm volatile ("mov %%cs, %0" : "=r" (cs_sel)); + + asm volatile ("push %1\n" + "call func_lret\n" + : "=a" (res) + : "r" (cs_sel) : "memory", "cc"); + printf("func_lret=" FMTLX "\n", res); + + desc.offset = (long)&func_lret; + desc.seg = cs_sel; + + asm volatile ("xor %%rax, %%rax\n" + "rex64 lcall *(%%rcx)\n" + : "=a" (res) + : "c" (&desc) + : "memory", "cc"); + printf("func_lret2=" FMTLX "\n", res); + + asm volatile ("push %2\n" + "mov $ 1f, %%rax\n" + "push %%rax\n" + "rex64 ljmp *(%%rcx)\n" + "1:\n" + : "=a" (res) + : "c" (&desc), "b" (cs_sel) + : "memory", "cc"); + printf("func_lret3=" FMTLX "\n", res); + } +#endif +#else + asm volatile ("push %%cs ; call %1" + : "=a" (res) + : "m" (func_lret): "memory", "cc"); + printf("func_lret=" FMTLX "\n", res); + + asm volatile ("pushf ; push %%cs ; call %1" + : "=a" (res) + : "m" (func_iret): "memory", "cc"); + printf("func_iret=" FMTLX "\n", res); +#endif + +#if defined(__x86_64__) + /* specific popl test */ + asm volatile ("push $12345432 ; push $0x9abcdef ; pop (%%rsp) ; pop %0" + : "=g" (res)); + printf("popl esp=" FMTLX "\n", res); +#else + /* specific popl test */ + asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0" + : "=g" (res)); + printf("popl esp=" FMTLX "\n", res); + + /* specific popw test */ + asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0" + : "=g" (res)); + printf("popw esp=" FMTLX "\n", res); +#endif +} + +uint8_t str_buffer[4096]; + +#define TEST_STRING1(OP, size, DF, REP)\ +{\ + long esi, edi, eax, ecx, eflags;\ +\ + esi = (long)(str_buffer + sizeof(str_buffer) / 2);\ + edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\ + eax = i2l(0x12345678);\ + ecx = 17;\ +\ + asm volatile ("push $0\n\t"\ + "popf\n\t"\ + DF "\n\t"\ + REP #OP size "\n\t"\ + "cld\n\t"\ + "pushf\n\t"\ + "pop %4\n\t"\ + : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\ + : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\ + printf("%-10s ESI=" FMTLX " EDI=" FMTLX " EAX=" FMTLX " ECX=" FMTLX " EFL=%04x\n",\ + REP #OP size, esi, edi, eax, ecx,\ + (int)(eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)));\ +} + +#define TEST_STRING(OP, REP)\ + TEST_STRING1(OP, "b", "", REP);\ + TEST_STRING1(OP, "w", "", REP);\ + TEST_STRING1(OP, "l", "", REP);\ + X86_64_ONLY(TEST_STRING1(OP, "q", "", REP));\ + TEST_STRING1(OP, "b", "std", REP);\ + TEST_STRING1(OP, "w", "std", REP);\ + TEST_STRING1(OP, "l", "std", REP);\ + X86_64_ONLY(TEST_STRING1(OP, "q", "std", REP)) + +void test_string(void) +{ + int i; + for(i = 0;i < sizeof(str_buffer); i++) + str_buffer[i] = i + 0x56; + TEST_STRING(stos, ""); + TEST_STRING(stos, "rep "); + TEST_STRING(lods, ""); /* to verify stos */ + TEST_STRING(lods, "rep "); + TEST_STRING(movs, ""); + TEST_STRING(movs, "rep "); + TEST_STRING(lods, ""); /* to verify stos */ + + /* XXX: better tests */ + TEST_STRING(scas, ""); + TEST_STRING(scas, "repz "); + TEST_STRING(scas, "repnz "); + TEST_STRING(cmps, ""); + TEST_STRING(cmps, "repz "); + TEST_STRING(cmps, "repnz "); +} + +#ifdef TEST_VM86 +/* VM86 test */ + +static inline void set_bit(uint8_t *a, unsigned int bit) +{ + a[bit / 8] |= (1 << (bit % 8)); +} + +static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg) +{ + return (uint8_t *)((seg << 4) + (reg & 0xffff)); +} + +static inline void pushw(struct vm86_regs *r, int val) +{ + r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff); + *(uint16_t *)seg_to_linear(r->ss, r->esp) = val; +} + +static inline int vm86(int func, struct vm86plus_struct *v86) +{ + return syscall(__NR_vm86, func, v86); +} + +extern char vm86_code_start; +extern char vm86_code_end; + +#define VM86_CODE_CS 0x100 +#define VM86_CODE_IP 0x100 + +void test_vm86(void) +{ + struct vm86plus_struct ctx; + struct vm86_regs *r; + uint8_t *vm86_mem; + int seg, ret; + + vm86_mem = mmap((void *)0x00000000, 0x110000, + PROT_WRITE | PROT_READ | PROT_EXEC, + MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); + if (vm86_mem == MAP_FAILED) { + printf("ERROR: could not map vm86 memory"); + return; + } + memset(&ctx, 0, sizeof(ctx)); + + /* init basic registers */ + r = &ctx.regs; + r->eip = VM86_CODE_IP; + r->esp = 0xfffe; + seg = VM86_CODE_CS; + r->cs = seg; + r->ss = seg; + r->ds = seg; + r->es = seg; + r->fs = seg; + r->gs = seg; + r->eflags = VIF_MASK; + + /* move code to proper address. We use the same layout as a .com + dos program. */ + memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP, + &vm86_code_start, &vm86_code_end - &vm86_code_start); + + /* mark int 0x21 as being emulated */ + set_bit((uint8_t *)&ctx.int_revectored, 0x21); + + for(;;) { + ret = vm86(VM86_ENTER, &ctx); + switch(VM86_TYPE(ret)) { + case VM86_INTx: + { + int int_num, ah, v; + + int_num = VM86_ARG(ret); + if (int_num != 0x21) + goto unknown_int; + ah = (r->eax >> 8) & 0xff; + switch(ah) { + case 0x00: /* exit */ + goto the_end; + case 0x02: /* write char */ + { + uint8_t c = r->edx; + putchar(c); + } + break; + case 0x09: /* write string */ + { + uint8_t c, *ptr; + ptr = seg_to_linear(r->ds, r->edx); + for(;;) { + c = *ptr++; + if (c == '$') + break; + putchar(c); + } + r->eax = (r->eax & ~0xff) | '$'; + } + break; + case 0xff: /* extension: write eflags number in edx */ + v = (int)r->edx; +#ifndef LINUX_VM86_IOPL_FIX + v &= ~0x3000; +#endif + printf("%08x\n", v); + break; + default: + unknown_int: + printf("unsupported int 0x%02x\n", int_num); + goto the_end; + } + } + break; + case VM86_SIGNAL: + /* a signal came, we just ignore that */ + break; + case VM86_STI: + break; + default: + printf("ERROR: unhandled vm86 return code (0x%x)\n", ret); + goto the_end; + } + } + the_end: + printf("VM86 end\n"); + munmap(vm86_mem, 0x110000); +} +#endif + +/* exception tests */ +#if defined(__i386__) && !defined(REG_EAX) +#define REG_EAX EAX +#define REG_EBX EBX +#define REG_ECX ECX +#define REG_EDX EDX +#define REG_ESI ESI +#define REG_EDI EDI +#define REG_EBP EBP +#define REG_ESP ESP +#define REG_EIP EIP +#define REG_EFL EFL +#define REG_TRAPNO TRAPNO +#define REG_ERR ERR +#endif + +#if defined(__x86_64__) +#define REG_EIP REG_RIP +#endif + +jmp_buf jmp_env; +int v1; +int tab[2]; + +void sig_handler(int sig, siginfo_t *info, void *puc) +{ + struct ucontext *uc = puc; + + printf("si_signo=%d si_errno=%d si_code=%d", + info->si_signo, info->si_errno, info->si_code); + printf(" si_addr=0x%08lx", + (unsigned long)info->si_addr); + printf("\n"); + + printf("trapno=" FMTLX " err=" FMTLX, + (long)uc->uc_mcontext.gregs[REG_TRAPNO], + (long)uc->uc_mcontext.gregs[REG_ERR]); + printf(" EIP=" FMTLX, (long)uc->uc_mcontext.gregs[REG_EIP]); + printf("\n"); + longjmp(jmp_env, 1); +} + +void test_exceptions(void) +{ + struct sigaction act; + volatile int val; + + act.sa_sigaction = sig_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO | SA_NODEFER; + sigaction(SIGFPE, &act, NULL); + sigaction(SIGILL, &act, NULL); + sigaction(SIGSEGV, &act, NULL); + sigaction(SIGBUS, &act, NULL); + sigaction(SIGTRAP, &act, NULL); + + /* test division by zero reporting */ + printf("DIVZ exception:\n"); + if (setjmp(jmp_env) == 0) { + /* now divide by zero */ + v1 = 0; + v1 = 2 / v1; + } + +#if !defined(__x86_64__) + printf("BOUND exception:\n"); + if (setjmp(jmp_env) == 0) { + /* bound exception */ + tab[0] = 1; + tab[1] = 10; + asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0])); + } +#endif + +#ifdef TEST_SEGS + printf("segment exceptions:\n"); + if (setjmp(jmp_env) == 0) { + /* load an invalid segment */ + asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1)); + } + if (setjmp(jmp_env) == 0) { + /* null data segment is valid */ + asm volatile ("movl %0, %%fs" : : "r" (3)); + /* null stack segment */ + asm volatile ("movl %0, %%ss" : : "r" (3)); + } + + { + struct modify_ldt_ldt_s ldt; + ldt.entry_number = 1; + ldt.base_addr = (unsigned long)&seg_data1; + ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; + ldt.seg_32bit = 1; + ldt.contents = MODIFY_LDT_CONTENTS_DATA; + ldt.read_exec_only = 0; + ldt.limit_in_pages = 1; + ldt.seg_not_present = 1; + ldt.useable = 1; + modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ + + if (setjmp(jmp_env) == 0) { + /* segment not present */ + asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); + } + } +#endif + + /* test SEGV reporting */ + printf("PF exception:\n"); + if (setjmp(jmp_env) == 0) { + val = 1; + /* we add a nop to test a weird PC retrieval case */ + asm volatile ("nop"); + /* now store in an invalid address */ + *(char *)0x1234 = 1; + } + + /* test SEGV reporting */ + printf("PF exception:\n"); + if (setjmp(jmp_env) == 0) { + val = 1; + /* read from an invalid address */ + v1 = *(char *)0x1234; + } + + /* test illegal instruction reporting */ + printf("UD2 exception:\n"); + if (setjmp(jmp_env) == 0) { + /* now execute an invalid instruction */ + asm volatile("ud2"); + } + printf("lock nop exception:\n"); + if (setjmp(jmp_env) == 0) { + /* now execute an invalid instruction */ + asm volatile(".byte 0xf0, 0x90"); + } + + printf("INT exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("int $0xfd"); + } + if (setjmp(jmp_env) == 0) { + asm volatile ("int $0x01"); + } + if (setjmp(jmp_env) == 0) { + asm volatile (".byte 0xcd, 0x03"); + } + if (setjmp(jmp_env) == 0) { + asm volatile ("int $0x04"); + } + if (setjmp(jmp_env) == 0) { + asm volatile ("int $0x05"); + } + + printf("INT3 exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("int3"); + } + + printf("CLI exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("cli"); + } + + printf("STI exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("cli"); + } + +#if !defined(__x86_64__) + printf("INTO exception:\n"); + if (setjmp(jmp_env) == 0) { + /* overflow exception */ + asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); + } +#endif + + printf("OUTB exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0)); + } + + printf("INB exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321)); + } + + printf("REP OUTSB exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1)); + } + + printf("REP INSB exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1)); + } + + printf("HLT exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("hlt"); + } + + printf("single step exception:\n"); + val = 0; + if (setjmp(jmp_env) == 0) { + asm volatile ("pushf\n" + "orl $0x00100, (%%esp)\n" + "popf\n" + "movl $0xabcd, %0\n" + "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory"); + } + printf("val=0x%x\n", val); +} + +#if !defined(__x86_64__) +/* specific precise single step test */ +void sig_trap_handler(int sig, siginfo_t *info, void *puc) +{ + struct ucontext *uc = puc; + printf("EIP=" FMTLX "\n", (long)uc->uc_mcontext.gregs[REG_EIP]); +} + +const uint8_t sstep_buf1[4] = { 1, 2, 3, 4}; +uint8_t sstep_buf2[4]; + +void test_single_step(void) +{ + struct sigaction act; + volatile int val; + int i; + + val = 0; + act.sa_sigaction = sig_trap_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + sigaction(SIGTRAP, &act, NULL); + asm volatile ("pushf\n" + "orl $0x00100, (%%esp)\n" + "popf\n" + "movl $0xabcd, %0\n" + + /* jmp test */ + "movl $3, %%ecx\n" + "1:\n" + "addl $1, %0\n" + "decl %%ecx\n" + "jnz 1b\n" + + /* movsb: the single step should stop at each movsb iteration */ + "movl $sstep_buf1, %%esi\n" + "movl $sstep_buf2, %%edi\n" + "movl $0, %%ecx\n" + "rep movsb\n" + "movl $3, %%ecx\n" + "rep movsb\n" + "movl $1, %%ecx\n" + "rep movsb\n" + + /* cmpsb: the single step should stop at each cmpsb iteration */ + "movl $sstep_buf1, %%esi\n" + "movl $sstep_buf2, %%edi\n" + "movl $0, %%ecx\n" + "rep cmpsb\n" + "movl $4, %%ecx\n" + "rep cmpsb\n" + + /* getpid() syscall: single step should skip one + instruction */ + "movl $20, %%eax\n" + "int $0x80\n" + "movl $0, %%eax\n" + + /* when modifying SS, trace is not done on the next + instruction */ + "movl %%ss, %%ecx\n" + "movl %%ecx, %%ss\n" + "addl $1, %0\n" + "movl $1, %%eax\n" + "movl %%ecx, %%ss\n" + "jmp 1f\n" + "addl $1, %0\n" + "1:\n" + "movl $1, %%eax\n" + "pushl %%ecx\n" + "popl %%ss\n" + "addl $1, %0\n" + "movl $1, %%eax\n" + + "pushf\n" + "andl $~0x00100, (%%esp)\n" + "popf\n" + : "=m" (val) + : + : "cc", "memory", "eax", "ecx", "esi", "edi"); + printf("val=%d\n", val); + for(i = 0; i < 4; i++) + printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]); +} + +/* self modifying code test */ +uint8_t code[] = { + 0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */ + 0xc3, /* ret */ +}; + +asm(".section \".data\"\n" + "smc_code2:\n" + "movl 4(%esp), %eax\n" + "movl %eax, smc_patch_addr2 + 1\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "smc_patch_addr2:\n" + "movl $1, %eax\n" + "ret\n" + ".previous\n" + ); + +typedef int FuncType(void); +extern int smc_code2(int); +void test_self_modifying_code(void) +{ + int i; + printf("self modifying code:\n"); + printf("func1 = 0x%x\n", ((FuncType *)code)()); + for(i = 2; i <= 4; i++) { + code[1] = i; + printf("func%d = 0x%x\n", i, ((FuncType *)code)()); + } + + /* more difficult test : the modified code is just after the + modifying instruction. It is forbidden in Intel specs, but it + is used by old DOS programs */ + for(i = 2; i <= 4; i++) { + printf("smc_code2(%d) = %d\n", i, smc_code2(i)); + } +} +#endif + +long enter_stack[4096]; + +#if defined(__x86_64__) +#define RSP "%%rsp" +#define RBP "%%rbp" +#else +#define RSP "%%esp" +#define RBP "%%ebp" +#endif + +#if !defined(__x86_64__) +/* causes an infinite loop, disable it for now. */ +#define TEST_ENTER(size, stack_type, level) +#else +#define TEST_ENTER(size, stack_type, level)\ +{\ + long esp_save, esp_val, ebp_val, ebp_save, i;\ + stack_type *ptr, *stack_end, *stack_ptr;\ + memset(enter_stack, 0, sizeof(enter_stack));\ + stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\ + ebp_val = (long)stack_ptr;\ + for(i=1;i<=32;i++)\ + *--stack_ptr = i;\ + esp_val = (long)stack_ptr;\ + asm("mov " RSP ", %[esp_save]\n"\ + "mov " RBP ", %[ebp_save]\n"\ + "mov %[esp_val], " RSP "\n"\ + "mov %[ebp_val], " RBP "\n"\ + "enter" size " $8, $" #level "\n"\ + "mov " RSP ", %[esp_val]\n"\ + "mov " RBP ", %[ebp_val]\n"\ + "mov %[esp_save], " RSP "\n"\ + "mov %[ebp_save], " RBP "\n"\ + : [esp_save] "=r" (esp_save),\ + [ebp_save] "=r" (ebp_save),\ + [esp_val] "=r" (esp_val),\ + [ebp_val] "=r" (ebp_val)\ + : "[esp_val]" (esp_val),\ + "[ebp_val]" (ebp_val));\ + printf("level=%d:\n", level);\ + printf("esp_val=" FMTLX "\n", esp_val - (long)stack_end);\ + printf("ebp_val=" FMTLX "\n", ebp_val - (long)stack_end);\ + for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\ + printf(FMTLX "\n", (long)ptr[0]);\ +} +#endif + +static void test_enter(void) +{ +#if defined(__x86_64__) + TEST_ENTER("q", uint64_t, 0); + TEST_ENTER("q", uint64_t, 1); + TEST_ENTER("q", uint64_t, 2); + TEST_ENTER("q", uint64_t, 31); +#else + TEST_ENTER("l", uint32_t, 0); + TEST_ENTER("l", uint32_t, 1); + TEST_ENTER("l", uint32_t, 2); + TEST_ENTER("l", uint32_t, 31); +#endif + + TEST_ENTER("w", uint16_t, 0); + TEST_ENTER("w", uint16_t, 1); + TEST_ENTER("w", uint16_t, 2); + TEST_ENTER("w", uint16_t, 31); +} + +#ifdef TEST_SSE + +typedef int __m64 __attribute__ ((__mode__ (__V2SI__))); +typedef float __m128 __attribute__ ((__mode__(__V4SF__))); + +typedef union { + double d[2]; + float s[4]; + uint32_t l[4]; + uint64_t q[2]; + __m128 dq; +} XMMReg; + +static uint64_t __attribute__((aligned(16))) test_values[4][2] = { + { 0x456723c698694873, 0xdc515cff944a58ec }, + { 0x1f297ccd58bad7ab, 0x41f21efba9e3e146 }, + { 0x007c62c2085427f8, 0x231be9e8cde7438d }, + { 0x0f76255a085427f8, 0xc233e9e8c4c9439a }, +}; + +#define SSE_OP(op)\ +{\ + asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ + printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ + #op,\ + a.q[1], a.q[0],\ + b.q[1], b.q[0],\ + r.q[1], r.q[0]);\ +} + +#define SSE_OP2(op)\ +{\ + int i;\ + for(i=0;i<2;i++) {\ + a.q[0] = test_values[2*i][0];\ + a.q[1] = test_values[2*i][1];\ + b.q[0] = test_values[2*i+1][0];\ + b.q[1] = test_values[2*i+1][1];\ + SSE_OP(op);\ + }\ +} + +#define MMX_OP2(op)\ +{\ + int i;\ + for(i=0;i<2;i++) {\ + a.q[0] = test_values[2*i][0];\ + b.q[0] = test_values[2*i+1][0];\ + asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\ + printf("%-9s: a=" FMT64X " b=" FMT64X " r=" FMT64X "\n",\ + #op,\ + a.q[0],\ + b.q[0],\ + r.q[0]);\ + }\ + SSE_OP2(op);\ +} + +#define SHUF_OP(op, ib)\ +{\ + a.q[0] = test_values[0][0];\ + a.q[1] = test_values[0][1];\ + b.q[0] = test_values[1][0];\ + b.q[1] = test_values[1][1];\ + asm volatile (#op " $" #ib ", %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ + printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ + #op,\ + a.q[1], a.q[0],\ + b.q[1], b.q[0],\ + ib,\ + r.q[1], r.q[0]);\ +} + +#define PSHUF_OP(op, ib)\ +{\ + int i;\ + for(i=0;i<2;i++) {\ + a.q[0] = test_values[2*i][0];\ + a.q[1] = test_values[2*i][1];\ + asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\ + printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ + #op,\ + a.q[1], a.q[0],\ + ib,\ + r.q[1], r.q[0]);\ + }\ +} + +#define SHIFT_IM(op, ib)\ +{\ + int i;\ + for(i=0;i<2;i++) {\ + a.q[0] = test_values[2*i][0];\ + a.q[1] = test_values[2*i][1];\ + asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\ + printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ + #op,\ + a.q[1], a.q[0],\ + ib,\ + r.q[1], r.q[0]);\ + }\ +} + +#define SHIFT_OP(op, ib)\ +{\ + int i;\ + SHIFT_IM(op, ib);\ + for(i=0;i<2;i++) {\ + a.q[0] = test_values[2*i][0];\ + a.q[1] = test_values[2*i][1];\ + b.q[0] = ib;\ + b.q[1] = 0;\ + asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ + printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ + #op,\ + a.q[1], a.q[0],\ + b.q[1], b.q[0],\ + r.q[1], r.q[0]);\ + }\ +} + +#define MOVMSK(op)\ +{\ + int i, reg;\ + for(i=0;i<2;i++) {\ + a.q[0] = test_values[2*i][0];\ + a.q[1] = test_values[2*i][1];\ + asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\ + printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\ + #op,\ + a.q[1], a.q[0],\ + reg);\ + }\ +} + +#define SSE_OPS(a) \ +SSE_OP(a ## ps);\ +SSE_OP(a ## ss); + +#define SSE_OPD(a) \ +SSE_OP(a ## pd);\ +SSE_OP(a ## sd); + +#define SSE_COMI(op, field)\ +{\ + unsigned int eflags;\ + XMMReg a, b;\ + a.field[0] = a1;\ + b.field[0] = b1;\ + asm volatile (#op " %2, %1\n"\ + "pushf\n"\ + "pop %0\n"\ + : "=m" (eflags)\ + : "x" (a.dq), "x" (b.dq));\ + printf("%-9s: a=%f b=%f cc=%04x\n",\ + #op, a1, b1,\ + eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\ +} + +void test_sse_comi(double a1, double b1) +{ + SSE_COMI(ucomiss, s); + SSE_COMI(ucomisd, d); + SSE_COMI(comiss, s); + SSE_COMI(comisd, d); +} + +#define CVT_OP_XMM(op)\ +{\ + asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\ + printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ + #op,\ + a.q[1], a.q[0],\ + r.q[1], r.q[0]);\ +} + +/* Force %xmm0 usage to avoid the case where both register index are 0 + to test instruction decoding more extensively */ +#define CVT_OP_XMM2MMX(op)\ +{\ + asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \ + : "%xmm0"); \ + asm volatile("emms\n"); \ + printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\ + #op,\ + a.q[1], a.q[0],\ + r.q[0]);\ +} + +#define CVT_OP_MMX2XMM(op)\ +{\ + asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\ + asm volatile("emms\n"); \ + printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\ + #op,\ + a.q[0],\ + r.q[1], r.q[0]);\ +} + +#define CVT_OP_REG2XMM(op)\ +{\ + asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\ + printf("%-9s: a=%08x r=" FMT64X "" FMT64X "\n",\ + #op,\ + a.l[0],\ + r.q[1], r.q[0]);\ +} + +#define CVT_OP_XMM2REG(op)\ +{\ + asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\ + printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\ + #op,\ + a.q[1], a.q[0],\ + r.l[0]);\ +} + +struct fpxstate { + uint16_t fpuc; + uint16_t fpus; + uint16_t fptag; + uint16_t fop; + uint32_t fpuip; + uint16_t cs_sel; + uint16_t dummy0; + uint32_t fpudp; + uint16_t ds_sel; + uint16_t dummy1; + uint32_t mxcsr; + uint32_t mxcsr_mask; + uint8_t fpregs1[8 * 16]; + uint8_t xmm_regs[8 * 16]; + uint8_t dummy2[224]; +}; + +static struct fpxstate fpx_state __attribute__((aligned(16))); +static struct fpxstate fpx_state2 __attribute__((aligned(16))); + +void test_fxsave(void) +{ + struct fpxstate *fp = &fpx_state; + struct fpxstate *fp2 = &fpx_state2; + int i, nb_xmm; + XMMReg a, b; + a.q[0] = test_values[0][0]; + a.q[1] = test_values[0][1]; + b.q[0] = test_values[1][0]; + b.q[1] = test_values[1][1]; + + asm("movdqa %2, %%xmm0\n" + "movdqa %3, %%xmm7\n" +#if defined(__x86_64__) + "movdqa %2, %%xmm15\n" +#endif + " fld1\n" + " fldpi\n" + " fldln2\n" + " fxsave %0\n" + " fxrstor %0\n" + " fxsave %1\n" + " fninit\n" + : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp) + : "m" (a), "m" (b)); + printf("fpuc=%04x\n", fp->fpuc); + printf("fpus=%04x\n", fp->fpus); + printf("fptag=%04x\n", fp->fptag); + for(i = 0; i < 3; i++) { + printf("ST%d: " FMT64X " %04x\n", + i, + *(uint64_t *)&fp->fpregs1[i * 16], + *(uint16_t *)&fp->fpregs1[i * 16 + 8]); + } + printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80); +#if defined(__x86_64__) + nb_xmm = 16; +#else + nb_xmm = 8; +#endif + for(i = 0; i < nb_xmm; i++) { + printf("xmm%d: " FMT64X "" FMT64X "\n", + i, + *(uint64_t *)&fp->xmm_regs[i * 16], + *(uint64_t *)&fp->xmm_regs[i * 16 + 8]); + } +} + +void test_sse(void) +{ + XMMReg r, a, b; + int i; + + MMX_OP2(punpcklbw); + MMX_OP2(punpcklwd); + MMX_OP2(punpckldq); + MMX_OP2(packsswb); + MMX_OP2(pcmpgtb); + MMX_OP2(pcmpgtw); + MMX_OP2(pcmpgtd); + MMX_OP2(packuswb); + MMX_OP2(punpckhbw); + MMX_OP2(punpckhwd); + MMX_OP2(punpckhdq); + MMX_OP2(packssdw); + MMX_OP2(pcmpeqb); + MMX_OP2(pcmpeqw); + MMX_OP2(pcmpeqd); + + MMX_OP2(paddq); + MMX_OP2(pmullw); + MMX_OP2(psubusb); + MMX_OP2(psubusw); + MMX_OP2(pminub); + MMX_OP2(pand); + MMX_OP2(paddusb); + MMX_OP2(paddusw); + MMX_OP2(pmaxub); + MMX_OP2(pandn); + + MMX_OP2(pmulhuw); + MMX_OP2(pmulhw); + + MMX_OP2(psubsb); + MMX_OP2(psubsw); + MMX_OP2(pminsw); + MMX_OP2(por); + MMX_OP2(paddsb); + MMX_OP2(paddsw); + MMX_OP2(pmaxsw); + MMX_OP2(pxor); + MMX_OP2(pmuludq); + MMX_OP2(pmaddwd); + MMX_OP2(psadbw); + MMX_OP2(psubb); + MMX_OP2(psubw); + MMX_OP2(psubd); + MMX_OP2(psubq); + MMX_OP2(paddb); + MMX_OP2(paddw); + MMX_OP2(paddd); + + MMX_OP2(pavgb); + MMX_OP2(pavgw); + + asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678)); + printf("%-9s: r=" FMT64X "\n", "pinsrw", r.q[0]); + + asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678)); + printf("%-9s: r=" FMT64X "" FMT64X "\n", "pinsrw", r.q[1], r.q[0]); + + a.q[0] = test_values[0][0]; + a.q[1] = test_values[0][1]; + asm volatile ("pextrw $1, %1, %0" : "=r" (r.l[0]) : "y" (a.q[0])); + printf("%-9s: r=%08x\n", "pextrw", r.l[0]); + + asm volatile ("pextrw $5, %1, %0" : "=r" (r.l[0]) : "x" (a.dq)); + printf("%-9s: r=%08x\n", "pextrw", r.l[0]); + + asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0])); + printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]); + + asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq)); + printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]); + + { + r.q[0] = -1; + r.q[1] = -1; + + a.q[0] = test_values[0][0]; + a.q[1] = test_values[0][1]; + b.q[0] = test_values[1][0]; + b.q[1] = test_values[1][1]; + asm volatile("maskmovq %1, %0" : + : "y" (a.q[0]), "y" (b.q[0]), "D" (&r) + : "memory"); + printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n", + "maskmov", + r.q[0], + a.q[0], + b.q[0]); + asm volatile("maskmovdqu %1, %0" : + : "x" (a.dq), "x" (b.dq), "D" (&r) + : "memory"); + printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n", + "maskmov", + r.q[1], r.q[0], + a.q[1], a.q[0], + b.q[1], b.q[0]); + } + + asm volatile ("emms"); + + SSE_OP2(punpcklqdq); + SSE_OP2(punpckhqdq); + SSE_OP2(andps); + SSE_OP2(andpd); + SSE_OP2(andnps); + SSE_OP2(andnpd); + SSE_OP2(orps); + SSE_OP2(orpd); + SSE_OP2(xorps); + SSE_OP2(xorpd); + + SSE_OP2(unpcklps); + SSE_OP2(unpcklpd); + SSE_OP2(unpckhps); + SSE_OP2(unpckhpd); + + SHUF_OP(shufps, 0x78); + SHUF_OP(shufpd, 0x02); + + PSHUF_OP(pshufd, 0x78); + PSHUF_OP(pshuflw, 0x78); + PSHUF_OP(pshufhw, 0x78); + + SHIFT_OP(psrlw, 7); + SHIFT_OP(psrlw, 16); + SHIFT_OP(psraw, 7); + SHIFT_OP(psraw, 16); + SHIFT_OP(psllw, 7); + SHIFT_OP(psllw, 16); + + SHIFT_OP(psrld, 7); + SHIFT_OP(psrld, 32); + SHIFT_OP(psrad, 7); + SHIFT_OP(psrad, 32); + SHIFT_OP(pslld, 7); + SHIFT_OP(pslld, 32); + + SHIFT_OP(psrlq, 7); + SHIFT_OP(psrlq, 32); + SHIFT_OP(psllq, 7); + SHIFT_OP(psllq, 32); + + SHIFT_IM(psrldq, 16); + SHIFT_IM(psrldq, 7); + SHIFT_IM(pslldq, 16); + SHIFT_IM(pslldq, 7); + + MOVMSK(movmskps); + MOVMSK(movmskpd); + + /* FPU specific ops */ + + { + uint32_t mxcsr; + asm volatile("stmxcsr %0" : "=m" (mxcsr)); + printf("mxcsr=%08x\n", mxcsr & 0x1f80); + asm volatile("ldmxcsr %0" : : "m" (mxcsr)); + } + + test_sse_comi(2, -1); + test_sse_comi(2, 2); + test_sse_comi(2, 3); + test_sse_comi(2, q_nan.d); + test_sse_comi(q_nan.d, -1); + + for(i = 0; i < 2; i++) { + a.s[0] = 2.7; + a.s[1] = 3.4; + a.s[2] = 4; + a.s[3] = -6.3; + b.s[0] = 45.7; + b.s[1] = 353.4; + b.s[2] = 4; + b.s[3] = 56.3; + if (i == 1) { + a.s[0] = q_nan.d; + b.s[3] = q_nan.d; + } + + SSE_OPS(add); + SSE_OPS(mul); + SSE_OPS(sub); + SSE_OPS(min); + SSE_OPS(div); + SSE_OPS(max); + SSE_OPS(sqrt); + SSE_OPS(cmpeq); + SSE_OPS(cmplt); + SSE_OPS(cmple); + SSE_OPS(cmpunord); + SSE_OPS(cmpneq); + SSE_OPS(cmpnlt); + SSE_OPS(cmpnle); + SSE_OPS(cmpord); + + + a.d[0] = 2.7; + a.d[1] = -3.4; + b.d[0] = 45.7; + b.d[1] = -53.4; + if (i == 1) { + a.d[0] = q_nan.d; + b.d[1] = q_nan.d; + } + SSE_OPD(add); + SSE_OPD(mul); + SSE_OPD(sub); + SSE_OPD(min); + SSE_OPD(div); + SSE_OPD(max); + SSE_OPD(sqrt); + SSE_OPD(cmpeq); + SSE_OPD(cmplt); + SSE_OPD(cmple); + SSE_OPD(cmpunord); + SSE_OPD(cmpneq); + SSE_OPD(cmpnlt); + SSE_OPD(cmpnle); + SSE_OPD(cmpord); + } + + /* float to float/int */ + a.s[0] = 2.7; + a.s[1] = 3.4; + a.s[2] = 4; + a.s[3] = -6.3; + CVT_OP_XMM(cvtps2pd); + CVT_OP_XMM(cvtss2sd); + CVT_OP_XMM2MMX(cvtps2pi); + CVT_OP_XMM2MMX(cvttps2pi); + CVT_OP_XMM2REG(cvtss2si); + CVT_OP_XMM2REG(cvttss2si); + CVT_OP_XMM(cvtps2dq); + CVT_OP_XMM(cvttps2dq); + + a.d[0] = 2.6; + a.d[1] = -3.4; + CVT_OP_XMM(cvtpd2ps); + CVT_OP_XMM(cvtsd2ss); + CVT_OP_XMM2MMX(cvtpd2pi); + CVT_OP_XMM2MMX(cvttpd2pi); + CVT_OP_XMM2REG(cvtsd2si); + CVT_OP_XMM2REG(cvttsd2si); + CVT_OP_XMM(cvtpd2dq); + CVT_OP_XMM(cvttpd2dq); + + /* sse/mmx moves */ + CVT_OP_XMM2MMX(movdq2q); + CVT_OP_MMX2XMM(movq2dq); + + /* int to float */ + a.l[0] = -6; + a.l[1] = 2; + a.l[2] = 100; + a.l[3] = -60000; + CVT_OP_MMX2XMM(cvtpi2ps); + CVT_OP_MMX2XMM(cvtpi2pd); + CVT_OP_REG2XMM(cvtsi2ss); + CVT_OP_REG2XMM(cvtsi2sd); + CVT_OP_XMM(cvtdq2ps); + CVT_OP_XMM(cvtdq2pd); + + /* XXX: test PNI insns */ +#if 0 + SSE_OP2(movshdup); +#endif + asm volatile ("emms"); +} + +#endif + +#define TEST_CONV_RAX(op)\ +{\ + unsigned long a, r;\ + a = i2l(0x8234a6f8);\ + r = a;\ + asm volatile(#op : "=a" (r) : "0" (r));\ + printf("%-10s A=" FMTLX " R=" FMTLX "\n", #op, a, r);\ +} + +#define TEST_CONV_RAX_RDX(op)\ +{\ + unsigned long a, d, r, rh; \ + a = i2l(0x8234a6f8);\ + d = i2l(0x8345a1f2);\ + r = a;\ + rh = d;\ + asm volatile(#op : "=a" (r), "=d" (rh) : "0" (r), "1" (rh)); \ + printf("%-10s A=" FMTLX " R=" FMTLX ":" FMTLX "\n", #op, a, r, rh); \ +} + +void test_conv(void) +{ + TEST_CONV_RAX(cbw); + TEST_CONV_RAX(cwde); +#if defined(__x86_64__) + TEST_CONV_RAX(cdqe); +#endif + + TEST_CONV_RAX_RDX(cwd); + TEST_CONV_RAX_RDX(cdq); +#if defined(__x86_64__) + TEST_CONV_RAX_RDX(cqo); +#endif + + { + unsigned long a, r; + a = i2l(0x12345678); + asm volatile("bswapl %k0" : "=r" (r) : "0" (a)); + printf("%-10s: A=" FMTLX " R=" FMTLX "\n", "bswapl", a, r); + } +#if defined(__x86_64__) + { + unsigned long a, r; + a = i2l(0x12345678); + asm volatile("bswapq %0" : "=r" (r) : "0" (a)); + printf("%-10s: A=" FMTLX " R=" FMTLX "\n", "bswapq", a, r); + } +#endif +} + +extern void *__start_initcall; +extern void *__stop_initcall; + + +int main(int argc, char **argv) +{ + void **ptr; + void (*func)(void); + + ptr = &__start_initcall; + while (ptr != &__stop_initcall) { + func = *ptr++; + func(); + } + test_bsx(); + test_mul(); + test_jcc(); + test_loop(); + test_floats(); +#if !defined(__x86_64__) + test_bcd(); +#endif + test_xchg(); + test_string(); + test_misc(); + test_lea(); +#ifdef TEST_SEGS + test_segs(); + test_code16(); +#endif +#ifdef TEST_VM86 + test_vm86(); +#endif +#if !defined(__x86_64__) + test_exceptions(); + test_self_modifying_code(); + test_single_step(); +#endif + test_enter(); + test_conv(); +#ifdef TEST_SSE + test_sse(); + test_fxsave(); +#endif + return 0; +} diff --git a/qemu/tests/tcg/test-i386.h b/qemu/tests/tcg/test-i386.h new file mode 100644 index 000000000..75106b8ce --- /dev/null +++ b/qemu/tests/tcg/test-i386.h @@ -0,0 +1,152 @@ + +#define exec_op glue(exec_, OP) +#define exec_opq glue(glue(exec_, OP), q) +#define exec_opl glue(glue(exec_, OP), l) +#define exec_opw glue(glue(exec_, OP), w) +#define exec_opb glue(glue(exec_, OP), b) + +#define EXECOP2(size, rsize, res, s1, flags) \ + asm ("push %4\n\t"\ + "popf\n\t"\ + stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \ + "pushf\n\t"\ + "pop %1\n\t"\ + : "=q" (res), "=g" (flags)\ + : "q" (s1), "0" (res), "1" (flags)); \ + printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", \ + stringify(OP) size, s0, s1, res, iflags, flags & CC_MASK); + +#define EXECOP1(size, rsize, res, flags) \ + asm ("push %3\n\t"\ + "popf\n\t"\ + stringify(OP) size " %" rsize "0\n\t" \ + "pushf\n\t"\ + "pop %1\n\t"\ + : "=q" (res), "=g" (flags)\ + : "0" (res), "1" (flags)); \ + printf("%-10s A=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", \ + stringify(OP) size, s0, res, iflags, flags & CC_MASK); + +#ifdef OP1 +#if defined(__x86_64__) +void exec_opq(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECOP1("q", "", res, flags); +} +#endif + +void exec_opl(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECOP1("l", "k", res, flags); +} + +void exec_opw(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECOP1("w", "w", res, flags); +} + +void exec_opb(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECOP1("b", "b", res, flags); +} +#else +#if defined(__x86_64__) +void exec_opq(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECOP2("q", "", res, s1, flags); +} +#endif + +void exec_opl(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECOP2("l", "k", res, s1, flags); +} + +void exec_opw(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECOP2("w", "w", res, s1, flags); +} + +void exec_opb(long s0, long s1, long iflags) +{ + long res, flags; + res = s0; + flags = iflags; + EXECOP2("b", "b", res, s1, flags); +} +#endif + +void exec_op(long s0, long s1) +{ + s0 = i2l(s0); + s1 = i2l(s1); +#if defined(__x86_64__) + exec_opq(s0, s1, 0); +#endif + exec_opl(s0, s1, 0); + exec_opw(s0, s1, 0); + exec_opb(s0, s1, 0); +#ifdef OP_CC +#if defined(__x86_64__) + exec_opq(s0, s1, CC_C); +#endif + exec_opl(s0, s1, CC_C); + exec_opw(s0, s1, CC_C); + exec_opb(s0, s1, CC_C); +#endif +} + +void glue(test_, OP)(void) +{ + exec_op(0x12345678, 0x812FADA); + exec_op(0x12341, 0x12341); + exec_op(0x12341, -0x12341); + exec_op(0xffffffff, 0); + exec_op(0xffffffff, -1); + exec_op(0xffffffff, 1); + exec_op(0xffffffff, 2); + exec_op(0x7fffffff, 0); + exec_op(0x7fffffff, 1); + exec_op(0x7fffffff, -1); + exec_op(0x80000000, -1); + exec_op(0x80000000, 1); + exec_op(0x80000000, -2); + exec_op(0x12347fff, 0); + exec_op(0x12347fff, 1); + exec_op(0x12347fff, -1); + exec_op(0x12348000, -1); + exec_op(0x12348000, 1); + exec_op(0x12348000, -2); + exec_op(0x12347f7f, 0); + exec_op(0x12347f7f, 1); + exec_op(0x12347f7f, -1); + exec_op(0x12348080, -1); + exec_op(0x12348080, 1); + exec_op(0x12348080, -2); +} + +void *glue(_test_, OP) __init_call = glue(test_, OP); + +#undef OP +#undef OP_CC diff --git a/qemu/tests/tcg/test-mmap.c b/qemu/tests/tcg/test-mmap.c new file mode 100644 index 000000000..3982fa2c7 --- /dev/null +++ b/qemu/tests/tcg/test-mmap.c @@ -0,0 +1,484 @@ +/* + * Small test program to verify simulated mmap behaviour. + * + * When running qemu-linux-user with the -p flag, you may need to tell + * this test program about the pagesize because getpagesize() will not reflect + * the -p choice. Simply pass one argument being the pagesize. + * + * Copyright (c) 2007 AXIS Communications AB + * Written by Edgar E. Iglesias. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +#include <sys/mman.h> + +#define D(x) + +#define fail_unless(x) \ +do \ +{ \ + if (!(x)) { \ + fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \ + exit (EXIT_FAILURE); \ + } \ +} while (0); + +unsigned char *dummybuf; +static unsigned int pagesize; +static unsigned int pagemask; +int test_fd; +size_t test_fsize; + +void check_aligned_anonymous_unfixed_mmaps(void) +{ + void *p1; + void *p2; + void *p3; + void *p4; + void *p5; + uintptr_t p; + int i; + + fprintf (stderr, "%s", __func__); + for (i = 0; i < 0x1fff; i++) + { + size_t len; + + len = pagesize + (pagesize * i & 7); + p1 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p2 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p3 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p4 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p5 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + fail_unless (p1 != MAP_FAILED); + fail_unless (p2 != MAP_FAILED); + fail_unless (p3 != MAP_FAILED); + fail_unless (p4 != MAP_FAILED); + fail_unless (p5 != MAP_FAILED); + p = (uintptr_t) p1; + D(printf ("p=%x\n", p)); + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p2; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p3; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p4; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p5; + fail_unless ((p & pagemask) == 0); + + /* Make sure we can read from the entire area. */ + memcpy (dummybuf, p1, pagesize); + memcpy (dummybuf, p2, pagesize); + memcpy (dummybuf, p3, pagesize); + memcpy (dummybuf, p4, pagesize); + memcpy (dummybuf, p5, pagesize); + + munmap (p1, len); + munmap (p2, len); + munmap (p3, len); + munmap (p4, len); + munmap (p5, len); + } + fprintf (stderr, " passed\n"); +} + +void check_large_anonymous_unfixed_mmap(void) +{ + void *p1; + uintptr_t p; + size_t len; + + fprintf (stderr, "%s", __func__); + + len = 0x02000000; + p1 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + fail_unless (p1 != MAP_FAILED); + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + + /* Make sure we can read from the entire area. */ + memcpy (dummybuf, p1, pagesize); + munmap (p1, len); + fprintf (stderr, " passed\n"); +} + +void check_aligned_anonymous_unfixed_colliding_mmaps(void) +{ + char *p1; + char *p2; + char *p3; + uintptr_t p; + int i; + + fprintf (stderr, "%s", __func__); + for (i = 0; i < 0x2fff; i++) + { + int nlen; + p1 = mmap(NULL, pagesize, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + fail_unless (p1 != MAP_FAILED); + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + memcpy (dummybuf, p1, pagesize); + + p2 = mmap(NULL, pagesize, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + fail_unless (p2 != MAP_FAILED); + p = (uintptr_t) p2; + fail_unless ((p & pagemask) == 0); + memcpy (dummybuf, p2, pagesize); + + + munmap (p1, pagesize); + nlen = pagesize * 8; + p3 = mmap(NULL, nlen, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + fail_unless (p3 != MAP_FAILED); + + /* Check if the mmaped areas collide. */ + if (p3 < p2 + && (p3 + nlen) > p2) + fail_unless (0); + + memcpy (dummybuf, p3, pagesize); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p3; + fail_unless ((p & pagemask) == 0); + munmap (p2, pagesize); + munmap (p3, nlen); + } + fprintf (stderr, " passed\n"); +} + +void check_aligned_anonymous_fixed_mmaps(void) +{ + char *addr; + void *p1; + uintptr_t p; + int i; + + /* Find a suitable address to start with. */ + addr = mmap(NULL, pagesize * 40, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + fprintf (stderr, "%s addr=%p", __func__, addr); + fail_unless (addr != MAP_FAILED); + + for (i = 0; i < 40; i++) + { + /* Create submaps within our unfixed map. */ + p1 = mmap(addr, pagesize, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0); + /* Make sure we get pages aligned with the pagesize. + The target expects this. */ + p = (uintptr_t) p1; + fail_unless (p1 == addr); + fail_unless ((p & pagemask) == 0); + memcpy (dummybuf, p1, pagesize); + munmap (p1, pagesize); + addr += pagesize; + } + fprintf (stderr, " passed\n"); +} + +void check_aligned_anonymous_fixed_mmaps_collide_with_host(void) +{ + char *addr; + void *p1; + uintptr_t p; + int i; + + /* Find a suitable address to start with. Right were the x86 hosts + stack is. */ + addr = ((void *)0x80000000); + fprintf (stderr, "%s addr=%p", __func__, addr); + fprintf (stderr, "FIXME: QEMU fails to track pages used by the host."); + + for (i = 0; i < 20; i++) + { + /* Create submaps within our unfixed map. */ + p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0); + /* Make sure we get pages aligned with the pagesize. + The target expects this. */ + p = (uintptr_t) p1; + fail_unless (p1 == addr); + fail_unless ((p & pagemask) == 0); + memcpy (p1, dummybuf, pagesize); + munmap (p1, pagesize); + addr += pagesize; + } + fprintf (stderr, " passed\n"); +} + +void check_file_unfixed_mmaps(void) +{ + unsigned int *p1, *p2, *p3; + uintptr_t p; + int i; + + fprintf (stderr, "%s", __func__); + for (i = 0; i < 0x10; i++) + { + size_t len; + + len = pagesize; + p1 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, 0); + p2 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, pagesize); + p3 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, pagesize * 2); + + fail_unless (p1 != MAP_FAILED); + fail_unless (p2 != MAP_FAILED); + fail_unless (p3 != MAP_FAILED); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p2; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p3; + fail_unless ((p & pagemask) == 0); + + /* Verify that the file maps was made correctly. */ + D(printf ("p1=%d p2=%d p3=%d\n", *p1, *p2, *p3)); + fail_unless (*p1 == 0); + fail_unless (*p2 == (pagesize / sizeof *p2)); + fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); + + memcpy (dummybuf, p1, pagesize); + memcpy (dummybuf, p2, pagesize); + memcpy (dummybuf, p3, pagesize); + munmap (p1, len); + munmap (p2, len); + munmap (p3, len); + } + fprintf (stderr, " passed\n"); +} + +void check_file_unfixed_eof_mmaps(void) +{ + char *cp; + unsigned int *p1; + uintptr_t p; + int i; + + fprintf (stderr, "%s", __func__); + for (i = 0; i < 0x10; i++) + { + p1 = mmap(NULL, pagesize, PROT_READ, + MAP_PRIVATE, + test_fd, + (test_fsize - sizeof *p1) & ~pagemask); + + fail_unless (p1 != MAP_FAILED); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + /* Verify that the file maps was made correctly. */ + fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] + == ((test_fsize - sizeof *p1) / sizeof *p1)); + + /* Verify that the end of page is accessible and zeroed. */ + cp = (void *) p1; + fail_unless (cp[pagesize - 4] == 0); + munmap (p1, pagesize); + } + fprintf (stderr, " passed\n"); +} + +void check_file_fixed_eof_mmaps(void) +{ + char *addr; + char *cp; + unsigned int *p1; + uintptr_t p; + int i; + + /* Find a suitable address to start with. */ + addr = mmap(NULL, pagesize * 44, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + + fprintf (stderr, "%s addr=%p", __func__, (void *)addr); + fail_unless (addr != MAP_FAILED); + + for (i = 0; i < 0x10; i++) + { + /* Create submaps within our unfixed map. */ + p1 = mmap(addr, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, + (test_fsize - sizeof *p1) & ~pagemask); + + fail_unless (p1 != MAP_FAILED); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + + /* Verify that the file maps was made correctly. */ + fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] + == ((test_fsize - sizeof *p1) / sizeof *p1)); + + /* Verify that the end of page is accessible and zeroed. */ + cp = (void *)p1; + fail_unless (cp[pagesize - 4] == 0); + munmap (p1, pagesize); + addr += pagesize; + } + fprintf (stderr, " passed\n"); +} + +void check_file_fixed_mmaps(void) +{ + unsigned char *addr; + unsigned int *p1, *p2, *p3, *p4; + int i; + + /* Find a suitable address to start with. */ + addr = mmap(NULL, pagesize * 40 * 4, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + fprintf (stderr, "%s addr=%p", __func__, (void *)addr); + fail_unless (addr != MAP_FAILED); + + for (i = 0; i < 40; i++) + { + p1 = mmap(addr, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, 0); + p2 = mmap(addr + pagesize, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, pagesize); + p3 = mmap(addr + pagesize * 2, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, pagesize * 2); + p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, pagesize * 3); + + /* Make sure we get pages aligned with the pagesize. + The target expects this. */ + fail_unless (p1 == (void *)addr); + fail_unless (p2 == (void *)addr + pagesize); + fail_unless (p3 == (void *)addr + pagesize * 2); + fail_unless (p4 == (void *)addr + pagesize * 3); + + /* Verify that the file maps was made correctly. */ + fail_unless (*p1 == 0); + fail_unless (*p2 == (pagesize / sizeof *p2)); + fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); + fail_unless (*p4 == ((pagesize * 3) / sizeof *p4)); + + memcpy (dummybuf, p1, pagesize); + memcpy (dummybuf, p2, pagesize); + memcpy (dummybuf, p3, pagesize); + memcpy (dummybuf, p4, pagesize); + + munmap (p1, pagesize); + munmap (p2, pagesize); + munmap (p3, pagesize); + munmap (p4, pagesize); + addr += pagesize * 4; + } + fprintf (stderr, " passed\n"); +} + +void checked_write(int fd, const void *buf, size_t count) +{ + ssize_t rc = write(fd, buf, count); + fail_unless(rc == count); +} + +int main(int argc, char **argv) +{ + char tempname[] = "/tmp/.cmmapXXXXXX"; + unsigned int i; + + /* Trust the first argument, otherwise probe the system for our + pagesize. */ + if (argc > 1) + pagesize = strtoul(argv[1], NULL, 0); + else + pagesize = sysconf(_SC_PAGESIZE); + + /* Assume pagesize is a power of two. */ + pagemask = pagesize - 1; + dummybuf = malloc (pagesize); + printf ("pagesize=%u pagemask=%x\n", pagesize, pagemask); + + test_fd = mkstemp(tempname); + unlink(tempname); + + /* Fill the file with int's counting from zero and up. */ + for (i = 0; i < (pagesize * 4) / sizeof i; i++) { + checked_write(test_fd, &i, sizeof i); + } + + /* Append a few extra writes to make the file end at non + page boundary. */ + checked_write(test_fd, &i, sizeof i); i++; + checked_write(test_fd, &i, sizeof i); i++; + checked_write(test_fd, &i, sizeof i); i++; + + test_fsize = lseek(test_fd, 0, SEEK_CUR); + + /* Run the tests. */ + check_aligned_anonymous_unfixed_mmaps(); + check_aligned_anonymous_unfixed_colliding_mmaps(); + check_aligned_anonymous_fixed_mmaps(); + check_file_unfixed_mmaps(); + check_file_fixed_mmaps(); + check_file_fixed_eof_mmaps(); + check_file_unfixed_eof_mmaps(); + + /* Fails at the moment. */ + /* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */ + + return EXIT_SUCCESS; +} diff --git a/qemu/tests/tcg/test_path.c b/qemu/tests/tcg/test_path.c new file mode 100644 index 000000000..1c29bce26 --- /dev/null +++ b/qemu/tests/tcg/test_path.c @@ -0,0 +1,157 @@ +/* Test path override code */ +#include "config-host.h" +#include "util/cutils.c" +#include "util/hexdump.c" +#include "util/iov.c" +#include "util/path.c" +#include "util/qemu-timer-common.c" +#include <stdarg.h> +#include <sys/stat.h> +#include <fcntl.h> + +void qemu_log(const char *fmt, ...); + +/* Any log message kills the test. */ +void qemu_log(const char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "FATAL: "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +#define NO_CHANGE(_path) \ + do { \ + if (strcmp(path(_path), _path) != 0) return __LINE__; \ + } while(0) + +#define CHANGE_TO(_path, _newpath) \ + do { \ + if (strcmp(path(_path), _newpath) != 0) return __LINE__; \ + } while(0) + +static void cleanup(void) +{ + unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE"); + unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE2"); + unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE3"); + unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE4"); + unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE5"); + rmdir("/tmp/qemu-test_path/DIR1/DIR2"); + rmdir("/tmp/qemu-test_path/DIR1/DIR3"); + rmdir("/tmp/qemu-test_path/DIR1"); + rmdir("/tmp/qemu-test_path"); +} + +static unsigned int do_test(void) +{ + if (mkdir("/tmp/qemu-test_path", 0700) != 0) + return __LINE__; + + if (mkdir("/tmp/qemu-test_path/DIR1", 0700) != 0) + return __LINE__; + + if (mkdir("/tmp/qemu-test_path/DIR1/DIR2", 0700) != 0) + return __LINE__; + + if (mkdir("/tmp/qemu-test_path/DIR1/DIR3", 0700) != 0) + return __LINE__; + + if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE", 0600)) != 0) + return __LINE__; + + if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE2", 0600)) != 0) + return __LINE__; + + if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE3", 0600)) != 0) + return __LINE__; + + if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE4", 0600)) != 0) + return __LINE__; + + if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE5", 0600)) != 0) + return __LINE__; + + init_paths("/tmp/qemu-test_path"); + + NO_CHANGE("/tmp"); + NO_CHANGE("/tmp/"); + NO_CHANGE("/tmp/qemu-test_path"); + NO_CHANGE("/tmp/qemu-test_path/"); + NO_CHANGE("/tmp/qemu-test_path/D"); + NO_CHANGE("/tmp/qemu-test_path/DI"); + NO_CHANGE("/tmp/qemu-test_path/DIR"); + NO_CHANGE("/tmp/qemu-test_path/DIR1"); + NO_CHANGE("/tmp/qemu-test_path/DIR1/"); + + NO_CHANGE("/D"); + NO_CHANGE("/DI"); + NO_CHANGE("/DIR"); + NO_CHANGE("/DIR2"); + NO_CHANGE("/DIR1."); + + CHANGE_TO("/DIR1", "/tmp/qemu-test_path/DIR1"); + CHANGE_TO("/DIR1/", "/tmp/qemu-test_path/DIR1"); + + NO_CHANGE("/DIR1/D"); + NO_CHANGE("/DIR1/DI"); + NO_CHANGE("/DIR1/DIR"); + NO_CHANGE("/DIR1/DIR1"); + + CHANGE_TO("/DIR1/DIR2", "/tmp/qemu-test_path/DIR1/DIR2"); + CHANGE_TO("/DIR1/DIR2/", "/tmp/qemu-test_path/DIR1/DIR2"); + + CHANGE_TO("/DIR1/DIR3", "/tmp/qemu-test_path/DIR1/DIR3"); + CHANGE_TO("/DIR1/DIR3/", "/tmp/qemu-test_path/DIR1/DIR3"); + + NO_CHANGE("/DIR1/DIR2/F"); + NO_CHANGE("/DIR1/DIR2/FI"); + NO_CHANGE("/DIR1/DIR2/FIL"); + NO_CHANGE("/DIR1/DIR2/FIL."); + + CHANGE_TO("/DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + CHANGE_TO("/DIR1/DIR2/FILE2", "/tmp/qemu-test_path/DIR1/DIR2/FILE2"); + CHANGE_TO("/DIR1/DIR2/FILE3", "/tmp/qemu-test_path/DIR1/DIR2/FILE3"); + CHANGE_TO("/DIR1/DIR2/FILE4", "/tmp/qemu-test_path/DIR1/DIR2/FILE4"); + CHANGE_TO("/DIR1/DIR2/FILE5", "/tmp/qemu-test_path/DIR1/DIR2/FILE5"); + + NO_CHANGE("/DIR1/DIR2/FILE6"); + NO_CHANGE("/DIR1/DIR2/FILE/X"); + + CHANGE_TO("/DIR1/../DIR1", "/tmp/qemu-test_path/DIR1"); + CHANGE_TO("/DIR1/../DIR1/", "/tmp/qemu-test_path/DIR1"); + CHANGE_TO("/../DIR1", "/tmp/qemu-test_path/DIR1"); + CHANGE_TO("/../DIR1/", "/tmp/qemu-test_path/DIR1"); + CHANGE_TO("/DIR1/DIR2/../DIR2", "/tmp/qemu-test_path/DIR1/DIR2"); + CHANGE_TO("/DIR1/DIR2/../DIR2/../../DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + CHANGE_TO("/DIR1/DIR2/../DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + + NO_CHANGE("/DIR1/DIR2/../DIR1"); + NO_CHANGE("/DIR1/DIR2/../FILE"); + + CHANGE_TO("/./DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + CHANGE_TO("/././DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + CHANGE_TO("/DIR1/./DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + CHANGE_TO("/DIR1/././DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + CHANGE_TO("/DIR1/DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + CHANGE_TO("/DIR1/DIR2/././FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + CHANGE_TO("/./DIR1/./DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); + + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret; + + ret = do_test(); + cleanup(); + if (ret) { + fprintf(stderr, "test_path: failed on line %i\n", ret); + return 1; + } + return 0; +} diff --git a/qemu/tests/tcg/testthread.c b/qemu/tests/tcg/testthread.c new file mode 100644 index 000000000..2679af119 --- /dev/null +++ b/qemu/tests/tcg/testthread.c @@ -0,0 +1,58 @@ +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <inttypes.h> +#include <pthread.h> +#include <sys/wait.h> +#include <sched.h> + +void checked_write(int fd, const void *buf, size_t count) +{ + ssize_t rc = write(fd, buf, count); + assert(rc == count); +} + +void *thread1_func(void *arg) +{ + int i; + char buf[512]; + + for(i=0;i<10;i++) { + snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); + checked_write(1, buf, strlen(buf)); + usleep(100 * 1000); + } + return NULL; +} + +void *thread2_func(void *arg) +{ + int i; + char buf[512]; + for(i=0;i<20;i++) { + snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); + checked_write(1, buf, strlen(buf)); + usleep(150 * 1000); + } + return NULL; +} + +void test_pthread(void) +{ + pthread_t tid1, tid2; + + pthread_create(&tid1, NULL, thread1_func, "hello1"); + pthread_create(&tid2, NULL, thread2_func, "hello2"); + pthread_join(tid1, NULL); + pthread_join(tid2, NULL); + printf("End of pthread test.\n"); +} + +int main(int argc, char **argv) +{ + test_pthread(); + return 0; +} diff --git a/qemu/tests/tcg/xtensa/Makefile b/qemu/tests/tcg/xtensa/Makefile new file mode 100644 index 000000000..522a63e36 --- /dev/null +++ b/qemu/tests/tcg/xtensa/Makefile @@ -0,0 +1,92 @@ +-include ../../../config-host.mak + +CORE=dc232b +CROSS=xtensa-$(CORE)-elf- + +ifndef XT +SIM = ../../../xtensa-softmmu/qemu-system-xtensa +SIMFLAGS = -M sim -cpu $(CORE) -nographic -semihosting $(EXTFLAGS) -kernel +SIMDEBUG = -s -S +else +SIM = xt-run +SIMFLAGS = --xtensa-core=DC_B_232L --exit_with_target_code $(EXTFLAGS) +SIMDEBUG = --gdbserve=0 +endif + +HOST_CC = gcc +CC = $(CROSS)gcc +AS = $(CROSS)gcc -x assembler-with-cpp +LD = $(CROSS)ld + +XTENSA_SRC_PATH = $(SRC_PATH)/tests/tcg/xtensa +INCLUDE_DIRS = $(XTENSA_SRC_PATH) $(SRC_PATH)/target-xtensa/core-$(CORE) +XTENSA_INC = $(addprefix -I,$(INCLUDE_DIRS)) + +LDFLAGS = -Tlinker.ld + +CRT = crt.o vectors.o + +TESTCASES += test_b.tst +TESTCASES += test_bi.tst +#TESTCASES += test_boolean.tst +TESTCASES += test_break.tst +TESTCASES += test_bz.tst +TESTCASES += test_cache.tst +TESTCASES += test_clamps.tst +TESTCASES += test_extui.tst +TESTCASES += test_fail.tst +TESTCASES += test_interrupt.tst +TESTCASES += test_loop.tst +TESTCASES += test_mac16.tst +TESTCASES += test_max.tst +TESTCASES += test_min.tst +TESTCASES += test_mmu.tst +TESTCASES += test_mul16.tst +TESTCASES += test_mul32.tst +TESTCASES += test_nsa.tst +ifdef XT +TESTCASES += test_pipeline.tst +endif +TESTCASES += test_quo.tst +TESTCASES += test_rem.tst +TESTCASES += test_rst0.tst +TESTCASES += test_s32c1i.tst +TESTCASES += test_sar.tst +TESTCASES += test_sext.tst +TESTCASES += test_shift.tst +TESTCASES += test_sr.tst +TESTCASES += test_timer.tst +TESTCASES += test_windowed.tst + +all: build + +linker.ld: $(XTENSA_SRC_PATH)/linker.ld.S + $(HOST_CC) $(XTENSA_INC) -E -P $< -o $@ + +%.o: $(XTENSA_SRC_PATH)/%.c + $(CC) $(XTENSA_INC) $(CFLAGS) -c $< -o $@ + +%.o: $(XTENSA_SRC_PATH)/%.S + $(CC) $(XTENSA_INC) $(ASFLAGS) -c $< -o $@ + +%.tst: %.o linker.ld $(XTENSA_SRC_PATH)/macros.inc $(CRT) Makefile + $(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@ + +build: $(TESTCASES) + +check: $(addprefix run-, $(TESTCASES)) + +run-%.tst: %.tst + $(SIM) $(SIMFLAGS) ./$< + +run-test_fail.tst: test_fail.tst + ! $(SIM) $(SIMFLAGS) ./$< + +debug-%.tst: %.tst + $(SIM) $(SIMDEBUG) $(SIMFLAGS) ./$< + +host-debug-%.tst: %.tst + gdb --args $(SIM) $(SIMFLAGS) ./$< + +clean: + $(RM) -fr $(TESTCASES) $(CRT) linker.ld diff --git a/qemu/tests/tcg/xtensa/crt.S b/qemu/tests/tcg/xtensa/crt.S new file mode 100644 index 000000000..d9846acac --- /dev/null +++ b/qemu/tests/tcg/xtensa/crt.S @@ -0,0 +1,24 @@ +.section .init + j 1f +.section .init.text +1: + movi a2, _start + jx a2 + +.text +.global _start +_start: + movi a2, 1 + wsr a2, windowstart + movi a2, 0 + wsr a2, windowbase + movi a1, _fstack + movi a2, 0x4000f + wsr a2, ps + isync + + call0 main + + mov a3, a2 + movi a2, 1 + simcall diff --git a/qemu/tests/tcg/xtensa/linker.ld.S b/qemu/tests/tcg/xtensa/linker.ld.S new file mode 100644 index 000000000..f1e7fa9f8 --- /dev/null +++ b/qemu/tests/tcg/xtensa/linker.ld.S @@ -0,0 +1,130 @@ +#include <core-isa.h> + +#if XTENSA_HAVE_BE +OUTPUT_FORMAT("elf32-xtensa-be") +#else +OUTPUT_FORMAT("elf32-xtensa-le") +#endif +ENTRY(_start) + +__DYNAMIC = 0; + +MEMORY { + ram : ORIGIN = XCHAL_VECBASE_RESET_VADDR, LENGTH = 0x08000000 /* 128M */ + rom : ORIGIN = XCHAL_RESET_VECTOR_VADDR, LENGTH = 0x00001000 /* 4k */ +} + +SECTIONS +{ + .init : + { + *(.init) + *(.init.*) + } > rom + + .vector : + { + . = XCHAL_WINDOW_OF4_VECOFS; + *(.vector.window_overflow_4) + *(.vector.window_overflow_4.*) + . = XCHAL_WINDOW_UF4_VECOFS; + *(.vector.window_underflow_4) + *(.vector.window_underflow_4.*) + . = XCHAL_WINDOW_OF8_VECOFS; + *(.vector.window_overflow_8) + *(.vector.window_overflow_8.*) + . = XCHAL_WINDOW_UF8_VECOFS; + *(.vector.window_underflow_8) + *(.vector.window_underflow_8.*) + . = XCHAL_WINDOW_OF12_VECOFS; + *(.vector.window_overflow_12) + *(.vector.window_overflow_12.*) + . = XCHAL_WINDOW_UF12_VECOFS; + *(.vector.window_underflow_12) + *(.vector.window_underflow_12.*) + +#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI >= 2 + . = XCHAL_INTLEVEL2_VECOFS; + *(.vector.level2) + *(.vector.level2.*) +#endif +#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI >= 3 + . = XCHAL_INTLEVEL3_VECOFS; + *(.vector.level3) + *(.vector.level3.*) +#endif +#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI >= 4 + . = XCHAL_INTLEVEL4_VECOFS; + *(.vector.level4) + *(.vector.level4.*) +#endif +#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI >= 5 + . = XCHAL_INTLEVEL5_VECOFS; + *(.vector.level5) + *(.vector.level5.*) +#endif +#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI >= 6 + . = XCHAL_INTLEVEL6_VECOFS; + *(.vector.level6) + *(.vector.level6.*) +#endif +#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI >= 7 + . = XCHAL_INTLEVEL7_VECOFS; + *(.vector.level7) + *(.vector.level7.*) +#endif + + . = XCHAL_KERNEL_VECOFS; + *(.vector.kernel) + *(.vector.kernel.*) + . = XCHAL_USER_VECOFS; + *(.vector.user) + *(.vector.user.*) + . = XCHAL_DOUBLEEXC_VECOFS; + *(.vector.double) + *(.vector.double.*) + } > ram + + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.* .literal .literal.*) + _etext = .; + } > ram + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + _erodata = .; + } > ram + + .data : + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.*) + _edata = .; + } > ram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _ebss = .; + _end = .; + } > ram +} + +PROVIDE(_fstack = (ORIGIN(ram) & 0xf0000000) + LENGTH(ram) - 16); diff --git a/qemu/tests/tcg/xtensa/macros.inc b/qemu/tests/tcg/xtensa/macros.inc new file mode 100644 index 000000000..4ebd30ab8 --- /dev/null +++ b/qemu/tests/tcg/xtensa/macros.inc @@ -0,0 +1,91 @@ +#include "core-isa.h" + +.macro test_suite name +.data +status: .word result +result: .space 256 +.text +.global main +.align 4 +main: +.endm + +.macro reset_ps + movi a2, 0x4000f + wsr a2, ps + isync +.endm + +.macro test_suite_end + reset_ps + movi a0, status + l32i a2, a0, 0 + movi a0, result + sub a2, a2, a0 + movi a3, 0 + loopnez a2, 1f + l8ui a2, a0, 0 + or a3, a3, a2 + addi a0, a0, 1 +1: + exit +.endm + +.macro print text +.data +97: .ascii "\text\n" +98: + .align 4 +.text + movi a2, 4 + movi a3, 2 + movi a4, 97b + movi a5, 98b + sub a5, a5, a4 + simcall +.endm + +.macro test_init +.endm + +.macro test name + //print test_\name + test_init +test_\name: +.global test_\name +.endm + +.macro test_end +99: + reset_ps + movi a2, status + l32i a3, a2, 0 + addi a3, a3, 1 + s32i a3, a2, 0 +.endm + +.macro exit + movi a2, 1 + simcall +.endm + +.macro test_fail + movi a2, status + l32i a2, a2, 0 + movi a3, 1 + s8i a3, a2, 0 + j 99f +.endm + +.macro assert cond, arg1, arg2 + b\cond \arg1, \arg2, 90f + test_fail +90: + nop +.endm + +.macro set_vector vector, addr + movi a2, handler_\vector + movi a3, \addr + s32i a3, a2, 0 +.endm diff --git a/qemu/tests/tcg/xtensa/test_b.S b/qemu/tests/tcg/xtensa/test_b.S new file mode 100644 index 000000000..8e81f956d --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_b.S @@ -0,0 +1,221 @@ +#include "macros.inc" + +test_suite b + +test bnone + movi a2, 0xa5a5ff00 + movi a3, 0x5a5a00ff + bnone a2, a3, 1f + test_fail +1: + movi a2, 0xa5a5ff01 + bnone a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test beq + movi a2, 0 + movi a3, 0 + beq a2, a3, 1f + test_fail +1: + movi a2, 1 + beq a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test blt + movi a2, 6 + movi a3, 7 + blt a2, a3, 1f + test_fail +1: + movi a2, 0xffffffff + blt a2, a3, 1f + test_fail +1: + movi a2, 7 + blt a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bltu + movi a2, 6 + movi a3, 7 + bltu a2, a3, 1f + test_fail +1: + movi a2, 7 + bltu a2, a3, 1f + j 2f +1: + test_fail +2: + movi a2, 0xffffffff + bltu a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test ball + movi a2, 0xa5a5ffa5 + movi a3, 0xa5a5ff00 + ball a2, a3, 1f + test_fail +1: + movi a2, 0xa5a5a5a5 + ball a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bbc + movi a2, 0xfffffffd + movi a3, 0xffffff01 + bbc a2, a3, 1f + test_fail +1: + movi a2, 8 + movi a3, 0xffffff03 + bbc a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bbci + movi a2, 0xfffdffff + bbci a2, 17, 1f + test_fail +1: + movi a2, 0x00020000 + bbci a2, 17, 1f + j 2f +1: + test_fail +2: +test_end + +test bany + movi a2, 0xa5a5ff01 + movi a3, 0x5a5a00ff + bany a2, a3, 1f + test_fail +1: + movi a2, 0xa5a5ff00 + bany a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bne + movi a2, 1 + movi a3, 0 + bne a2, a3, 1f + test_fail +1: + movi a2, 0 + bne a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bge + movi a2, 7 + movi a3, 7 + bge a2, a3, 1f + test_fail +1: + movi a2, 6 + bge a2, a3, 1f + j 2f +1: + test_fail +2: + movi a2, 0xffffffff + bge a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bgeu + movi a2, 7 + movi a3, 7 + bgeu a2, a3, 1f + test_fail +1: + movi a2, 0xffffffff + bgeu a2, a3, 1f + test_fail +1: + movi a2, 6 + bgeu a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bnall + movi a2, 0xa5a5a5a5 + movi a3, 0xa5a5ff00 + bnall a2, a3, 1f + test_fail +1: + movi a2, 0xa5a5ffa5 + bnall a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bbs + movi a2, 8 + movi a3, 0xffffff03 + bbs a2, a3, 1f + test_fail +1: + movi a2, 0xfffffffd + movi a3, 0xffffff01 + bbs a2, a3, 1f + j 2f +1: + test_fail +2: +test_end + +test bbsi + movi a2, 0x00020000 + bbsi a2, 17, 1f + test_fail +1: + movi a2, 0xfffdffff + bbsi a2, 17, 1f + j 2f +1: + test_fail +2: +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_bi.S b/qemu/tests/tcg/xtensa/test_bi.S new file mode 100644 index 000000000..4f94c0c7e --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_bi.S @@ -0,0 +1,103 @@ +#include "macros.inc" + +test_suite bi + +test beqi + movi a2, 7 + beqi a2, 7, 1f + test_fail +1: + movi a2, 1 + beqi a2, 7, 1f + j 2f +1: + test_fail +2: +test_end + +test bnei + movi a2, 1 + bnei a2, 7, 1f + test_fail +1: + movi a2, 7 + bnei a2, 7, 1f + j 2f +1: + test_fail +2: +test_end + +test blti + movi a2, 6 + blti a2, 7, 1f + test_fail +1: + movi a2, 0xffffffff + blti a2, 7, 1f + test_fail +1: + movi a2, 7 + blti a2, 7, 1f + j 2f +1: + test_fail +2: +test_end + +test bgei + movi a2, 7 + bgei a2, 7, 1f + test_fail +1: + movi a2, 6 + bgei a2, 7, 1f + j 2f +1: + test_fail +2: + movi a2, 0xffffffff + bgei a2, 7, 1f + j 2f +1: + test_fail +2: +test_end + +test bltui + movi a2, 6 + bltui a2, 7, 1f + test_fail +1: + movi a2, 7 + bltui a2, 7, 1f + j 2f +1: + test_fail +2: + movi a2, 0xffffffff + bltui a2, 7, 1f + j 2f +1: + test_fail +2: +test_end + +test bgeui + movi a2, 7 + bgeui a2, 7, 1f + test_fail +1: + movi a2, 0xffffffff + bgeui a2, 7, 1f + test_fail +1: + movi a2, 6 + bgeui a2, 7, 1f + j 2f +1: + test_fail +2: +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_boolean.S b/qemu/tests/tcg/xtensa/test_boolean.S new file mode 100644 index 000000000..eac40e097 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_boolean.S @@ -0,0 +1,23 @@ +#include "macros.inc" + +test_suite boolean + +test all4 + movi a2, 0xfec0 + wsr a2, br + all4 b0, b0 + rsr a3, br + assert eq, a2, a3 + all4 b0, b4 + rsr a3, br + assert eq, a2, a3 + all4 b0, b8 + rsr a3, br + assert eq, a2, a3 + all4 b0, b12 + rsr a3, br + addi a2, a2, 1 + assert eq, a2, a3 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_break.S b/qemu/tests/tcg/xtensa/test_break.S new file mode 100644 index 000000000..775cd7c26 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_break.S @@ -0,0 +1,257 @@ +#include "macros.inc" + +#define debug_level 6 +#define debug_vector level6 + +test_suite break + +test break + set_vector debug_vector, 0 + rsil a2, debug_level + _break 0, 0 + + set_vector debug_vector, 2f + rsil a2, debug_level - 1 +1: + _break 0, 0 + test_fail +2: + rsr a2, ps + movi a3, 0x1f + and a2, a2, a3 + movi a3, 0x10 | debug_level + assert eq, a2, a3 + rsr a2, epc6 + movi a3, 1b + assert eq, a2, a3 + rsr a2, debugcause + movi a3, 0x8 + assert eq, a2, a3 +test_end + +test breakn + set_vector debug_vector, 0 + rsil a2, debug_level + _break.n 0 + + set_vector debug_vector, 2f + rsil a2, debug_level - 1 +1: + _break.n 0 + test_fail +2: + rsr a2, ps + movi a3, 0x1f + and a2, a2, a3 + movi a3, 0x10 | debug_level + assert eq, a2, a3 + rsr a2, epc6 + movi a3, 1b + assert eq, a2, a3 + rsr a2, debugcause + movi a3, 0x10 + assert eq, a2, a3 +test_end + +test ibreak + set_vector debug_vector, 0 + rsil a2, debug_level + movi a2, 1f + wsr a2, ibreaka0 + movi a2, 1 + wsr a2, ibreakenable + isync +1: + rsil a2, debug_level - 1 + movi a2, 1f + wsr a2, ibreaka0 + movi a2, 0 + wsr a2, ibreakenable + isync +1: + set_vector debug_vector, 2f + movi a2, 1f + wsr a2, ibreaka0 + movi a2, 1 + wsr a2, ibreakenable + isync +1: + test_fail +2: + rsr a2, ps + movi a3, 0x1f + and a2, a2, a3 + movi a3, 0x10 | debug_level + assert eq, a2, a3 + rsr a2, epc6 + movi a3, 1b + assert eq, a2, a3 + rsr a2, debugcause + movi a3, 0x2 + assert eq, a2, a3 +test_end + +test ibreak_remove + set_vector debug_vector, 3f + rsil a2, debug_level - 1 + movi a2, 2f + wsr a2, ibreaka0 + movi a3, 1 +1: + wsr a3, ibreakenable + isync +2: + beqz a3, 4f + test_fail +3: + assert eqi, a3, 1 + rsr a2, ps + movi a3, 0x1f + and a2, a2, a3 + movi a3, 0x10 | debug_level + assert eq, a2, a3 + rsr a2, epc6 + movi a3, 2b + assert eq, a2, a3 + rsr a2, debugcause + movi a3, 0x2 + assert eq, a2, a3 + + movi a2, 0x40000 + wsr a2, ps + isync + movi a3, 0 + j 1b +4: +test_end + +test ibreak_priority + set_vector debug_vector, 2f + rsil a2, debug_level - 1 + movi a2, 1f + wsr a2, ibreaka0 + movi a2, 1 + wsr a2, ibreakenable + isync +1: + break 0, 0 + test_fail +2: + rsr a2, debugcause + movi a3, 0x2 + assert eq, a2, a3 +test_end + +test icount + set_vector debug_vector, 2f + rsil a2, debug_level - 1 + movi a2, -2 + wsr a2, icount + movi a2, 1 + wsr a2, icountlevel + isync + rsil a2, 0 + nop +1: + break 0, 0 + test_fail +2: + movi a2, 0 + wsr a2, icountlevel + rsr a2, epc6 + movi a3, 1b + assert eq, a2, a3 + rsr a2, debugcause + movi a3, 0x1 + assert eq, a2, a3 +test_end + +.macro check_dbreak dr + rsr a2, epc6 + movi a3, 1b + assert eq, a2, a3 + rsr a2, debugcause + movi a3, 0x4 | (\dr << 8) + assert eq, a2, a3 + movi a2, 0 + wsr a2, dbreakc\dr +.endm + +.macro dbreak_test dr, ctl, break, access, op + set_vector debug_vector, 2f + rsil a2, debug_level - 1 + movi a2, \ctl + wsr a2, dbreakc\dr + movi a2, \break + wsr a2, dbreaka\dr + movi a2, \access + isync +1: + \op a3, a2, 0 + test_fail +2: + check_dbreak \dr + reset_ps +.endm + +test dbreak_exact + dbreak_test 0, 0x4000003f, 0xd000007f, 0xd000007f, l8ui + dbreak_test 1, 0x4000003e, 0xd000007e, 0xd000007e, l16ui + dbreak_test 0, 0x4000003c, 0xd000007c, 0xd000007c, l32i + + dbreak_test 1, 0x8000003f, 0xd000007f, 0xd000007f, s8i + dbreak_test 0, 0x8000003e, 0xd000007e, 0xd000007e, s16i + dbreak_test 1, 0x8000003c, 0xd000007c, 0xd000007c, s32i +test_end + +test dbreak_overlap + dbreak_test 0, 0x4000003f, 0xd000007d, 0xd000007c, l16ui + dbreak_test 1, 0x4000003f, 0xd000007d, 0xd000007c, l32i + + dbreak_test 0, 0x4000003e, 0xd000007e, 0xd000007f, l8ui + dbreak_test 1, 0x4000003e, 0xd000007e, 0xd000007c, l32i + + dbreak_test 0, 0x4000003c, 0xd000007c, 0xd000007d, l8ui + dbreak_test 1, 0x4000003c, 0xd000007c, 0xd000007c, l16ui + + dbreak_test 0, 0x40000038, 0xd0000078, 0xd000007b, l8ui + dbreak_test 1, 0x40000038, 0xd0000078, 0xd000007a, l16ui + dbreak_test 0, 0x40000038, 0xd0000078, 0xd000007c, l32i + + dbreak_test 1, 0x40000030, 0xd0000070, 0xd0000075, l8ui + dbreak_test 0, 0x40000030, 0xd0000070, 0xd0000076, l16ui + dbreak_test 1, 0x40000030, 0xd0000070, 0xd0000078, l32i + + dbreak_test 0, 0x40000020, 0xd0000060, 0xd000006f, l8ui + dbreak_test 1, 0x40000020, 0xd0000060, 0xd0000070, l16ui + dbreak_test 0, 0x40000020, 0xd0000060, 0xd0000074, l32i + + + dbreak_test 0, 0x8000003f, 0xd000007d, 0xd000007c, s16i + dbreak_test 1, 0x8000003f, 0xd000007d, 0xd000007c, s32i + + dbreak_test 0, 0x8000003e, 0xd000007e, 0xd000007f, s8i + dbreak_test 1, 0x8000003e, 0xd000007e, 0xd000007c, s32i + + dbreak_test 0, 0x8000003c, 0xd000007c, 0xd000007d, s8i + dbreak_test 1, 0x8000003c, 0xd000007c, 0xd000007c, s16i + + dbreak_test 0, 0x80000038, 0xd0000078, 0xd000007b, s8i + dbreak_test 1, 0x80000038, 0xd0000078, 0xd000007a, s16i + dbreak_test 0, 0x80000038, 0xd0000078, 0xd000007c, s32i + + dbreak_test 1, 0x80000030, 0xd0000070, 0xd0000075, s8i + dbreak_test 0, 0x80000030, 0xd0000070, 0xd0000076, s16i + dbreak_test 1, 0x80000030, 0xd0000070, 0xd0000078, s32i + + dbreak_test 0, 0x80000020, 0xd0000060, 0xd000006f, s8i + dbreak_test 1, 0x80000020, 0xd0000060, 0xd0000070, s16i + dbreak_test 0, 0x80000020, 0xd0000060, 0xd0000074, s32i +test_end + +test dbreak_invalid + dbreak_test 0, 0x40000030, 0xd0000071, 0xd0000070, l16ui + dbreak_test 1, 0x40000035, 0xd0000072, 0xd0000070, l32i +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_bz.S b/qemu/tests/tcg/xtensa/test_bz.S new file mode 100644 index 000000000..b68135011 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_bz.S @@ -0,0 +1,57 @@ +#include "macros.inc" + +test_suite bz + +test beqz + movi a2, 0 + _beqz a2, 1f + test_fail +1: + movi a2, 1 + _beqz a2, 1f + j 2f +1: + test_fail +2: +test_end + +test bnez + movi a2, 1 + _bnez a2, 1f + test_fail +1: + movi a2, 0 + _bnez a2, 1f + j 2f +1: + test_fail +2: +test_end + +test bltz + movi a2, 0xffffffff + bltz a2, 1f + test_fail +1: + movi a2, 0 + bltz a2, 1f + j 2f +1: + test_fail +2: +test_end + +test bgez + movi a2, 0 + bgez a2, 1f + test_fail +1: + movi a2, 0xffffffff + bgez a2, 1f + j 2f +1: + test_fail +2: +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_cache.S b/qemu/tests/tcg/xtensa/test_cache.S new file mode 100644 index 000000000..6b2df9734 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_cache.S @@ -0,0 +1,97 @@ +#include "macros.inc" + +.purgem test_init +.macro test_init + call0 cache_unlock_invalidate +.endm + +test_suite cache + +.macro pf_op op + \op a2, 0 + \op a3, 0 + \op a4, 0 +.endm + +test prefetch + movi a2, 0xd0000000 /* cacheable */ + movi a3, 0xd8000000 /* non-cacheable */ + movi a4, 0x00001235 /* unmapped */ + + pf_op dpfr + pf_op dpfro + pf_op dpfw + pf_op dpfwo + pf_op ipf + + dpfl a2, 0 + ipfl a2, 0 +test_end + +.macro cache_fault op, addr, exc_code + set_vector kernel, 2f + + movi a4, \addr +1: + \op a4, 0 + test_fail +2: + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + rsr a2, excvaddr + assert eq, a2, a4 + rsr a2, exccause + movi a3, \exc_code + assert eq, a2, a3 +.endm + +test dpfl_tlb_miss + cache_fault dpfl, 0x00002345, 24 +test_end + +test dhwb_tlb_miss + cache_fault dhwb, 0x00002345, 24 +test_end + +test dhwbi_tlb_miss + cache_fault dhwbi, 0x00002345, 24 +test_end + +test dhi_tlb_miss + cache_fault dhi, 0x00002345, 24 +test_end + +test dhu_tlb_miss + cache_fault dhu, 0x00002345, 24 +test_end + + +test ipfl_tlb_miss + cache_fault ipfl, 0x00002345, 16 +test_end + +test ihu_tlb_miss + cache_fault ihu, 0x00002345, 16 +test_end + +test ihi_tlb_miss + cache_fault ihi, 0x00002345, 16 +test_end + +test_suite_end + +.macro cache_all op1, op2, size, linesize + movi a2, 0 + movi a3, \size +1: + \op1 a2, 0 + \op2 a2, 0 + addi a2, a2, \linesize + bltu a2, a3, 1b +.endm + +cache_unlock_invalidate: + cache_all diu, dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE + cache_all iiu, iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE + ret diff --git a/qemu/tests/tcg/xtensa/test_clamps.S b/qemu/tests/tcg/xtensa/test_clamps.S new file mode 100644 index 000000000..3efabfd9d --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_clamps.S @@ -0,0 +1,42 @@ +#include "macros.inc" + +test_suite clamps + +test clamps + movi a2, 0 + movi a3, 0 + clamps a4, a2, 7 + assert eq, a3, a4 + + movi a2, 0x7f + movi a3, 0x7f + clamps a4, a2, 7 + assert eq, a3, a4 + + movi a2, 0xffffff80 + movi a3, 0xffffff80 + clamps a4, a2, 7 + assert eq, a3, a4 + + movi a2, 0x80 + movi a3, 0x7f + clamps a2, a2, 7 + assert eq, a3, a2 + + movi a2, 0xffffff7f + movi a3, 0xffffff80 + clamps a2, a2, 7 + assert eq, a3, a2 + + movi a2, 0x7fffffff + movi a3, 0x7f + clamps a2, a2, 7 + assert eq, a3, a2 + + movi a2, 0x80000000 + movi a3, 0xffffff80 + clamps a2, a2, 7 + assert eq, a3, a2 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_extui.S b/qemu/tests/tcg/xtensa/test_extui.S new file mode 100644 index 000000000..c32bb824d --- /dev/null +++ b/qemu/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 diff --git a/qemu/tests/tcg/xtensa/test_fail.S b/qemu/tests/tcg/xtensa/test_fail.S new file mode 100644 index 000000000..1c26d5079 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_fail.S @@ -0,0 +1,9 @@ +#include "macros.inc" + +test_suite fail + +test fail + test_fail +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_interrupt.S b/qemu/tests/tcg/xtensa/test_interrupt.S new file mode 100644 index 000000000..334ddab28 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_interrupt.S @@ -0,0 +1,194 @@ +#include "macros.inc" + +test_suite interrupt + +.macro clear_interrupts + movi a2, 0 + wsr a2, intenable + wsr a2, ccompare0 + wsr a2, ccompare1 + wsr a2, ccompare2 + esync + rsr a2, interrupt + wsr a2, intclear + + esync + rsr a2, interrupt + assert eqi, a2, 0 +.endm + +.macro check_l1 + rsr a2, ps + movi a3, 0x1f /* EXCM | INTMASK */ + and a2, a2, a3 + assert eqi, a2, 0x10 /* only EXCM is set for level-1 interrupt */ + rsr a2, exccause + assert eqi, a2, 4 +.endm + +test rsil + clear_interrupts + + rsr a2, ps + rsil a3, 7 + rsr a4, ps + assert eq, a2, a3 + movi a2, 0xf + and a2, a4, a2 + assert eqi, a2, 7 + xor a3, a3, a4 + movi a2, 0xfffffff0 + and a2, a3, a2 + assert eqi, a2, 0 +test_end + +test soft_disabled + set_vector kernel, 1f + clear_interrupts + + movi a2, 0x80 + wsr a2, intset + esync + rsr a3, interrupt + assert eq, a2, a3 + wsr a2, intclear + esync + rsr a3, interrupt + assert eqi, a3, 0 + j 2f +1: + test_fail +2: +test_end + +test soft_intenable + set_vector kernel, 1f + clear_interrupts + + movi a2, 0x80 + wsr a2, intset + esync + rsr a3, interrupt + assert eq, a2, a3 + rsil a3, 0 + wsr a2, intenable + esync + test_fail +1: + check_l1 +test_end + +test soft_rsil + set_vector kernel, 1f + clear_interrupts + + movi a2, 0x80 + wsr a2, intset + esync + rsr a3, interrupt + assert eq, a2, a3 + wsr a2, intenable + rsil a3, 0 + esync + test_fail +1: + check_l1 +test_end + +test soft_waiti + set_vector kernel, 1f + clear_interrupts + + movi a2, 0x80 + wsr a2, intset + esync + rsr a3, interrupt + assert eq, a2, a3 + wsr a2, intenable + waiti 0 + test_fail +1: + check_l1 +test_end + +test soft_user + set_vector kernel, 1f + set_vector user, 2f + clear_interrupts + + movi a2, 0x80 + wsr a2, intset + esync + rsr a3, interrupt + assert eq, a2, a3 + wsr a2, intenable + + rsr a2, ps + movi a3, 0x20 + or a2, a2, a3 + wsr a2, ps + waiti 0 +1: + test_fail +2: + check_l1 +test_end + +test soft_priority + set_vector kernel, 1f + set_vector level3, 2f + clear_interrupts + + movi a2, 0x880 + wsr a2, intenable + rsil a3, 0 + esync + wsr a2, intset + esync +1: + test_fail +2: + rsr a2, ps + movi a3, 0x1f /* EXCM | INTMASK */ + and a2, a2, a3 + movi a3, 0x13 + assert eq, a2, a3 /* EXCM and INTMASK are set + for high-priority interrupt */ +test_end + +test eps_epc_rfi + set_vector level3, 3f + clear_interrupts + reset_ps + + movi a2, 0x880 + wsr a2, intenable + rsil a3, 0 + rsr a3, ps + esync + wsr a2, intset +1: + esync +2: + test_fail +3: + rsr a2, eps3 + assert eq, a2, a3 + rsr a2, epc3 + movi a3, 1b + assert ge, a2, a3 + movi a3, 2b + assert ge, a3, a2 + movi a2, 4f + wsr a2, epc3 + movi a2, 0x40003 + wsr a2, eps3 + rfi 3 + test_fail +4: + rsr a2, ps + movi a3, 0x40003 + assert eq, a2, a3 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_loop.S b/qemu/tests/tcg/xtensa/test_loop.S new file mode 100644 index 000000000..5755578d0 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_loop.S @@ -0,0 +1,163 @@ +#include "macros.inc" + +test_suite loop + +test loop + movi a2, 0 + movi a3, 5 + loop a3, 1f + addi a2, a2, 1 +1: + assert eqi, a2, 5 +test_end + +test loop0 + movi a2, 0 + loop a2, 1f + rsr a2, lcount + assert eqi, a2, -1 + j 1f +1: +test_end + +test loop_jump + movi a2, 0 + movi a3, 5 + loop a3, 1f + addi a2, a2, 1 + j 1f +1: + assert eqi, a2, 1 +test_end + +test loop_branch + movi a2, 0 + movi a3, 5 + loop a3, 1f + addi a2, a2, 1 + beqi a2, 3, 1f +1: + assert eqi, a2, 3 +test_end + +test loop_manual + movi a2, 0 + movi a3, 5 + movi a4, 1f + movi a5, 2f + wsr a3, lcount + wsr a4, lbeg + wsr a5, lend + isync + j 1f +.align 4 +1: + addi a2, a2, 1 +2: + assert eqi, a2, 6 +test_end + +test loop_excm + movi a2, 0 + movi a3, 5 + rsr a4, ps + movi a5, 0x10 + or a4, a4, a5 + wsr a4, ps + isync + loop a3, 1f + addi a2, a2, 1 +1: + xor a4, a4, a5 + isync + wsr a4, ps + assert eqi, a2, 1 +test_end + +test lbeg_invalidation + movi a2, 0 + movi a3, 1 + movi a4, 1f + movi a5, 3f + wsr a3, lcount + wsr a4, lbeg + wsr a5, lend + isync + j 1f +.align 4 +1: + addi a2, a2, 1 + j 2f +.align 4 +2: + addi a2, a2, 2 + movi a3, 2b + wsr a3, lbeg + isync + nop +3: + assert eqi, a2, 5 +test_end + +test lend_invalidation + movi a2, 0 + movi a3, 5 + movi a4, 1f + movi a5, 2f + wsr a3, lcount + wsr a4, lbeg + wsr a5, lend + isync + j 1f +.align 4 +1: + addi a2, a2, 1 +2: + beqi a3, 3, 1f + assert eqi, a2, 6 + movi a3, 3 + wsr a3, lcount + wsr a4, lend + isync + j 1b +1: + assert eqi, a2, 7 +test_end + +test loopnez + movi a2, 0 + movi a3, 5 + loopnez a3, 1f + addi a2, a2, 1 +1: + assert eqi, a2, 5 + + movi a2, 0 + movi a3, 0 + loopnez a3, 1f + test_fail +1: +test_end + +test loopgtz + movi a2, 0 + movi a3, 5 + loopgtz a3, 1f + addi a2, a2, 1 +1: + assert eqi, a2, 5 + + movi a2, 0 + movi a3, 0 + loopgtz a3, 1f + test_fail +1: + + movi a2, 0 + movi a3, 0x80000000 + loopgtz a3, 1f + test_fail +1: +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_mac16.S b/qemu/tests/tcg/xtensa/test_mac16.S new file mode 100644 index 000000000..512025d84 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_mac16.S @@ -0,0 +1,243 @@ +#include "macros.inc" + +test_suite mac16 + +#define ext16(v) (((v) & 0xffff) | (((v) & 0x8000) * 0x1ffffffe)) +#define mul16(a, b) ((ext16(a) * ext16(b))) + +.macro assert_acc_value v + rsr a4, ACCLO + movi a5, (\v) & 0xffffffff + assert eq, a4, a5 + rsr a4, ACCHI + movi a5, (\v) >> 32 + sext a5, a5, 7 + assert eq, a4, a5 +.endm + +.macro init_reg sr, reg, val + .if (\sr) + movi a4, \val + wsr a4, \reg + .else + movi \reg, \val + .endif +.endm + +.macro test_mulxx mulop, comb, s, t, a, b + init_reg \comb & 2, \s, \a + init_reg \comb & 1, \t, \b + + \mulop\().ll \s, \t + assert_acc_value mul16(\a, \b) + + \mulop\().lh \s, \t + assert_acc_value mul16(\a, (\b >> 16)) + + \mulop\().hl \s, \t + assert_acc_value mul16((\a >> 16), \b) + + \mulop\().hh \s, \t + assert_acc_value mul16((\a >> 16), (\b >> 16)) +.endm + +test mul_aa + test_mulxx mul.aa, 0, a2, a3, 0xf7315a5a, 0xa5a5137f +test_end + +test mul_ad + test_mulxx mul.ad, 1, a2, m2, 0xf7315a5a, 0xa5a5137f +test_end + +test mul_da + test_mulxx mul.da, 2, m1, a3, 0xf7315a5a, 0xa5a5137f +test_end + +test mul_dd + test_mulxx mul.dd, 3, m0, m3, 0xf7315a5a, 0xa5a5137f +test_end + + +.macro init_acc iv + movi a4, (\iv) & 0xffffffff + wsr a4, ACCLO + movi a4, (\iv) >> 32 + wsr a4, ACCHI +.endm + +.macro test_mulxxx mulop, comb, s, t, a, b, iv, op + init_reg \comb & 2, \s, \a + init_reg \comb & 1, \t, \b + + init_acc \iv + \mulop\().ll \s, \t + assert_acc_value (\iv \op mul16(\a, \b)) + + init_acc \iv + \mulop\().lh \s, \t + assert_acc_value (\iv \op mul16(\a, (\b >> 16))) + + init_acc \iv + \mulop\().hl \s, \t + assert_acc_value (\iv \op mul16((\a >> 16), \b)) + + init_acc \iv + \mulop\().hh \s, \t + assert_acc_value (\iv \op mul16((\a >> 16), (\b >> 16))) +.endm + + +test mula_aa + test_mulxxx mula.aa, 0, a2, a3, 0xf7315a5a, 0xa5a5137f, 0xfff73155aa, + +test_end + +test mula_ad + test_mulxxx mula.ad, 1, a2, m2, 0xf7315a5a, 0xa5a5137f, 0xfff73155aa, + +test_end + +test mula_da + test_mulxxx mula.da, 2, m1, a3, 0xf7315a5a, 0xa5a5137f, 0x0ff73155aa, + +test_end + +test mula_dd + test_mulxxx mula.dd, 3, m0, m3, 0xf7315a5a, 0xa5a5137f, 0x0ff73155aa, + +test_end + + +test muls_aa + test_mulxxx muls.aa, 0, a2, a3, 0xf7315a5a, 0xa5a5137f, 0x0ff73155aa, - +test_end + +test muls_ad + test_mulxxx muls.ad, 1, a2, m2, 0xf7315a5a, 0xa5a5137f, 0x0ff73155aa, - +test_end + +test muls_da + test_mulxxx muls.da, 2, m1, a3, 0xf7315a5a, 0xa5a5137f, 0xfff73155aa, - +test_end + +test muls_dd + test_mulxxx muls.dd, 3, m0, m3, 0xf7315a5a, 0xa5a5137f, 0xfff73155aa, - +test_end + +test ldinc + movi a2, 1f - 4 + ldinc m0, a2 + movi a3, 1f + assert eq, a2, a3 + rsr a3, m0 + movi a4, 0x55aa137f + assert eq, a3, a4 + ldinc m1, a2 + movi a3, 1f + 4 + assert eq, a2, a3 + rsr a3, m1 + movi a4, 0x12345678 + assert eq, a3, a4 + +.data +1: .word 0x55aa137f, 0x12345678, 0x137fa5a5 +.text +test_end + +test lddec + movi a2, 1f + lddec m2, a2 + movi a3, 1f - 4 + assert eq, a2, a3 + rsr a3, m2 + movi a4, 0x12345678 + assert eq, a3, a4 + lddec m3, a2 + movi a3, 1f - 8 + assert eq, a2, a3 + rsr a3, m3 + movi a4, 0x55aa137f + assert eq, a3, a4 +.data + .word 0x55aa137f, 0x12345678 +1: +.text +test_end + + +.macro test_mulxxx_ld mulop, ldop, comb, w, x, s, t, a, b, iv, op + init_reg \comb & 2, \s, \a + init_reg \comb & 1, \t, \b + + init_acc \iv + \mulop\().ll.\ldop \w, \x, \s, \t + assert_acc_value (\iv \op mul16(\a, \b)) + + init_acc \iv + \mulop\().lh.\ldop \w, \x, \s, \t + assert_acc_value (\iv \op mul16(\a, (\b >> 16))) + + init_acc \iv + \mulop\().hl.\ldop \w, \x, \s, \t + assert_acc_value (\iv \op mul16((\a >> 16), \b)) + + init_acc \iv + \mulop\().hh.\ldop \w, \x, \s, \t + assert_acc_value (\iv \op mul16((\a >> 16), (\b >> 16))) +.endm + +test mula_da_ldinc + movi a2, 1f - 4 + test_mulxxx_ld mula.da, ldinc, 2, m1, a2, m1, a3, \ + 0xf7315a5a, 0xa5a5137f, 0x0ff73155aa, + + movi a3, 1f + 12 + assert eq, a2, a3 + rsr a2, m1 + movi a3, 0x12345678 + assert eq, a2, a3 +.data +1: .word 0xf7315a5a, 0xf7315a5a, 0xf7315a5a, 0x12345678 +.text +test_end + +test mula_dd_ldinc + movi a2, 1f - 4 + test_mulxxx_ld mula.dd, ldinc, 3, m2, a2, m1, m2, \ + 0xf7315a5a, 0xa5a5137f, 0x0ff73155aa, + + movi a3, 1f + 12 + assert eq, a2, a3 + rsr a2, m2 + movi a3, 0x12345678 + assert eq, a2, a3 +.data +1: .word 0xa5a5137f, 0xa5a5137f, 0xa5a5137f, 0x12345678 +.text +test_end + +test mula_da_lddec + movi a2, 1f + test_mulxxx_ld mula.da, lddec, 2, m1, a2, m1, a3, \ + 0xf7315a5a, 0xa5a5137f, 0x0ff73155aa, + + movi a3, 1f - 16 + assert eq, a2, a3 + rsr a2, m1 + movi a3, 0x12345678 + assert eq, a2, a3 +.data + .word 0x12345678, 0xf7315a5a, 0xf7315a5a, 0xf7315a5a +1: +.text +test_end + +test mula_dd_lddec + movi a2, 1f + test_mulxxx_ld mula.dd, lddec, 3, m2, a2, m1, m2, \ + 0xf7315a5a, 0xa5a5137f, 0x0ff73155aa, + + movi a3, 1f - 16 + assert eq, a2, a3 + rsr a2, m2 + movi a3, 0x12345678 + assert eq, a2, a3 +.data + .word 0x12345678, 0xa5a5137f, 0xa5a5137f, 0xa5a5137f +1: +.text +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_max.S b/qemu/tests/tcg/xtensa/test_max.S new file mode 100644 index 000000000..3caa207ea --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_max.S @@ -0,0 +1,81 @@ +#include "macros.inc" + +test_suite max + +test max + movi a2, 0xffffffff + movi a3, 1 + movi a4, 1 + max a5, a2, a3 + assert eq, a5, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 1 + max a5, a2, a3 + assert eq, a5, a4 + + movi a2, 0xffffffff + movi a3, 1 + movi a4, 1 + max a2, a2, a3 + assert eq, a2, a4 + + movi a2, 0xffffffff + movi a3, 1 + movi a4, 1 + max a3, a2, a3 + assert eq, a3, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 1 + max a2, a2, a3 + assert eq, a2, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 1 + max a3, a2, a3 + assert eq, a3, a4 +test_end + +test maxu + movi a2, 0xffffffff + movi a3, 1 + movi a4, 0xffffffff + maxu a5, a2, a3 + assert eq, a5, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 0xffffffff + maxu a5, a2, a3 + assert eq, a5, a4 + + movi a2, 0xffffffff + movi a3, 1 + movi a4, 0xffffffff + maxu a2, a2, a3 + assert eq, a2, a4 + + movi a2, 0xffffffff + movi a3, 1 + movi a4, 0xffffffff + maxu a3, a2, a3 + assert eq, a3, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 0xffffffff + maxu a2, a2, a3 + assert eq, a2, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 0xffffffff + maxu a3, a2, a3 + assert eq, a3, a4 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_min.S b/qemu/tests/tcg/xtensa/test_min.S new file mode 100644 index 000000000..551cf591e --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_min.S @@ -0,0 +1,81 @@ +#include "macros.inc" + +test_suite min + +test min + movi a2, 0xffffffff + movi a3, 1 + movi a4, 0xffffffff + min a5, a2, a3 + assert eq, a5, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 0xffffffff + min a5, a2, a3 + assert eq, a5, a4 + + movi a2, 0xffffffff + movi a3, 1 + movi a4, 0xffffffff + min a2, a2, a3 + assert eq, a2, a4 + + movi a2, 0xffffffff + movi a3, 1 + movi a4, 0xffffffff + min a3, a2, a3 + assert eq, a3, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 0xffffffff + min a2, a2, a3 + assert eq, a2, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 0xffffffff + min a3, a2, a3 + assert eq, a3, a4 +test_end + +test minu + movi a2, 0xffffffff + movi a3, 1 + movi a4, 1 + minu a5, a2, a3 + assert eq, a5, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 1 + minu a5, a2, a3 + assert eq, a5, a4 + + movi a2, 0xffffffff + movi a3, 1 + movi a4, 1 + minu a2, a2, a3 + assert eq, a2, a4 + + movi a2, 0xffffffff + movi a3, 1 + movi a4, 1 + minu a3, a2, a3 + assert eq, a3, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 1 + minu a2, a2, a3 + assert eq, a2, a4 + + movi a2, 1 + movi a3, 0xffffffff + movi a4, 1 + minu a3, a2, a3 + assert eq, a3, a4 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_mmu.S b/qemu/tests/tcg/xtensa/test_mmu.S new file mode 100644 index 000000000..a15316ffb --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_mmu.S @@ -0,0 +1,743 @@ +#include "macros.inc" + +test_suite mmu + +.purgem test_init + +.macro clean_tlb_way way, page_size, n_entries + movi a2, \way + movi a3, \page_size + movi a4, \n_entries + loop a4, 1f + idtlb a2 + iitlb a2 + add a2, a2, a3 +1: +.endm + +.macro test_init + clean_tlb_way 0, 0x00001000, 4 + clean_tlb_way 1, 0x00001000, 4 + clean_tlb_way 2, 0x00001000, 4 + clean_tlb_way 3, 0x00001000, 4 + clean_tlb_way 4, 0x00100000, 4 + movi a2, 0x00000007 + idtlb a2 + movi a2, 0x00000008 + idtlb a2 + movi a2, 0x00000009 + idtlb a2 +.endm + +test tlb_group + movi a2, 0x04000002 /* PPN */ + movi a3, 0x01200004 /* VPN */ + wdtlb a2, a3 + witlb a2, a3 + movi a3, 0x00200004 + rdtlb0 a1, a3 + ritlb0 a2, a3 + movi a3, 0x01000001 + assert eq, a1, a3 + assert eq, a2, a3 + movi a3, 0x00200004 + rdtlb1 a1, a3 + ritlb1 a2, a3 + movi a3, 0x04000002 + assert eq, a1, a3 + assert eq, a2, a3 + movi a3, 0x01234567 + pdtlb a1, a3 + pitlb a2, a3 + movi a3, 0x01234014 + assert eq, a1, a3 + movi a3, 0x0123400c + assert eq, a2, a3 + movi a3, 0x00200004 + idtlb a3 + iitlb a3 + movi a3, 0x01234567 + pdtlb a1, a3 + pitlb a2, a3 + movi a3, 0x00000010 + and a1, a1, a3 + assert eqi, a1, 0 + movi a3, 0x00000008 + and a2, a2, a3 + assert eqi, a2, 0 +test_end + +test itlb_miss + set_vector kernel, 1f + + movi a3, 0x00100000 + jx a3 + test_fail +1: + rsr a2, excvaddr + assert eq, a2, a3 + rsr a2, exccause + movi a3, 16 + assert eq, a2, a3 +test_end + +test dtlb_miss + set_vector kernel, 1f + + movi a3, 0x00100000 + l8ui a2, a3, 0 + test_fail +1: + rsr a2, excvaddr + assert eq, a2, a3 + rsr a2, exccause + movi a3, 24 + assert eq, a2, a3 +test_end + +test itlb_multi_hit + set_vector kernel, 1f + + movi a2, 0x04000002 /* PPN */ + movi a3, 0xf0000004 /* VPN */ + witlb a2, a3 + movi a3, 0xf0000000 + pitlb a2, a3 + test_fail +1: + rsr a2, exccause + movi a3, 17 + assert eq, a2, a3 +test_end + +test dtlb_multi_hit + set_vector kernel, 1f + + movi a2, 0x04000002 /* PPN */ + movi a3, 0x01200004 /* VPN */ + wdtlb a2, a3 + movi a3, 0x01200007 /* VPN */ + wdtlb a2, a3 + movi a3, 0x01200000 + pdtlb a2, a3 + test_fail +1: + rsr a2, exccause + movi a3, 25 + assert eq, a2, a3 +test_end + +test inst_fetch_privilege + set_vector kernel, 3f + + movi a2, 0x4004f + wsr a2, ps +1: + isync + nop +2: + test_fail +3: + movi a1, 1b + rsr a2, excvaddr + rsr a3, epc1 + assert ge, a2, a1 + assert ge, a3, a1 + movi a1, 2b + assert lt, a2, a1 + assert lt, a3, a1 + rsr a2, exccause + movi a3, 18 + assert eq, a2, a3 + rsr a2, ps + movi a3, 0x4005f + assert eq, a2, a3 +test_end + +test load_store_privilege + set_vector kernel, 2f + + movi a3, 10f + pitlb a3, a3 + ritlb1 a2, a3 + movi a1, 0x10 + or a2, a2, a1 + movi a1, 0x000ff000 + and a3, a3, a1 + movi a1, 4 + or a3, a3, a1 + witlb a2, a3 + movi a3, 10f + movi a1, 0x000fffff + and a1, a3, a1 + + movi a2, 0x04000003 /* PPN */ + movi a3, 0x01200004 /* VPN */ + wdtlb a2, a3 + movi a3, 0x01200001 + movi a2, 0x4004f + jx a1 +10: + wsr a2, ps + isync +1: + l8ui a2, a3, 0 + test_fail +2: + rsr a2, excvaddr + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 1b + movi a1, 0x000fffff + and a3, a3, a1 + assert eq, a2, a3 + rsr a2, exccause + movi a3, 26 + assert eq, a2, a3 + rsr a2, ps + movi a3, 0x4005f + assert eq, a2, a3 +test_end + +test cring_load_store_privilege + set_vector kernel, 0 + set_vector double, 2f + + movi a2, 0x04000003 /* PPN */ + movi a3, 0x01200004 /* VPN */ + wdtlb a2, a3 + movi a3, 0x01200004 + movi a2, 0x4005f /* ring 1 + excm => cring == 0 */ + wsr a2, ps + isync + l8ui a2, a3, 0 /* cring used */ +1: + l32e a2, a3, -4 /* ring used */ + test_fail +2: + rsr a2, excvaddr + addi a2, a2, 4 + assert eq, a2, a3 + rsr a2, depc + movi a3, 1b + assert eq, a2, a3 + rsr a2, exccause + movi a3, 26 + assert eq, a2, a3 + rsr a2, ps + movi a3, 0x4005f + assert eq, a2, a3 +test_end + +test inst_fetch_prohibited + set_vector kernel, 2f + + movi a3, 10f + pitlb a3, a3 + ritlb1 a2, a3 + movi a1, 0xfffff000 + and a2, a2, a1 + movi a1, 0x4 + or a2, a2, a1 + movi a1, 0x000ff000 + and a3, a3, a1 + movi a1, 4 + or a3, a3, a1 + witlb a2, a3 + movi a3, 10f + movi a1, 0x000fffff + and a1, a3, a1 + jx a1 + .align 4 +10: + nop + test_fail +2: + rsr a2, excvaddr + assert eq, a2, a1 + rsr a2, epc1 + assert eq, a2, a1 + rsr a2, exccause + movi a3, 20 + assert eq, a2, a3 +test_end + +test load_prohibited + set_vector kernel, 2f + + movi a2, 0x0400000c /* PPN */ + movi a3, 0x01200004 /* VPN */ + wdtlb a2, a3 + movi a3, 0x01200002 +1: + l8ui a2, a3, 0 + test_fail +2: + rsr a2, excvaddr + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + rsr a2, exccause + movi a3, 28 + assert eq, a2, a3 +test_end + +test store_prohibited + set_vector kernel, 2f + + movi a2, 0x04000001 /* PPN */ + movi a3, 0x01200004 /* VPN */ + wdtlb a2, a3 + movi a3, 0x01200003 + l8ui a2, a3, 0 +1: + s8i a2, a3, 0 + test_fail +2: + rsr a2, excvaddr + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + rsr a2, exccause + movi a3, 29 + assert eq, a2, a3 +test_end + +/* Set up page table entry vaddr->paddr, ring=pte_ring, attr=pte_attr + * and DTLB way 7 to cover this PTE, ring=pt_ring, attr=pt_attr + */ +.macro pt_setup pt_ring, pt_attr, pte_ring, vaddr, paddr, pte_attr + movi a2, 0x80000000 + wsr a2, ptevaddr + + movi a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */ + movi a4, 0x04000003 | ((\pt_ring) << 4) /* PADDR 64M */ + wdtlb a4, a3 + isync + + movi a3, ((\paddr) & 0xfffff000) | ((\pte_ring) << 4) | (\pte_attr) + movi a1, ((\vaddr) >> 12) << 2 + add a2, a1, a2 + s32i a3, a2, 0 + + movi a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */ + movi a4, 0x04000000 | ((\pt_ring) << 4) | (\pt_attr) /* PADDR 64M */ + wdtlb a4, a3 + isync + + movi a3, (\vaddr) +.endm + +/* out: PS.RING=ring, PS.EXCM=excm, a3=vaddr */ +.macro go_ring ring, excm, vaddr + movi a3, 10f + pitlb a3, a3 + ritlb1 a2, a3 + movi a1, 0x10 + or a2, a2, a1 + movi a1, 0x000ff000 + and a3, a3, a1 + movi a1, 4 + or a3, a3, a1 + witlb a2, a3 + movi a3, 10f + movi a1, 0x000fffff + and a1, a3, a1 + + movi a2, 0 + wsr a2, excvaddr + + movi a3, \vaddr + movi a2, 0x4000f | ((\ring) << 6) | ((\excm) << 4) + jx a1 +10: + wsr a2, ps + isync +.endm + +/* in: a3 -- virtual address to test */ +.macro assert_auto_tlb + movi a2, 0x4000f + wsr a2, ps + isync + pdtlb a2, a3 + movi a1, 0xfffff01f + and a2, a2, a1 + movi a1, 0xfffff000 + and a1, a1, a3 + xor a1, a1, a2 + assert gei, a1, 0x10 + movi a2, 0x14 + assert lt, a1, a2 +.endm + +/* in: a3 -- virtual address to test */ +.macro assert_no_auto_tlb + movi a2, 0x4000f + wsr a2, ps + isync + pdtlb a2, a3 + movi a1, 0x10 + and a1, a1, a2 + assert eqi, a1, 0 +.endm + +.macro assert_sr sr, v + rsr a2, \sr + movi a1, (\v) + assert eq, a1, a2 +.endm + +.macro assert_epc1_1m vaddr + movi a2, (\vaddr) + movi a1, 0xfffff + and a1, a1, a2 + rsr a2, epc1 + assert eq, a1, a2 +.endm + +test dtlb_autoload + set_vector kernel, 0 + + pt_setup 0, 3, 1, 0x1000, 0x1000, 3 + assert_no_auto_tlb + + l8ui a1, a3, 0 + + rsr a2, excvaddr + assert eq, a2, a3 + + assert_auto_tlb +test_end + +test autoload_load_store_privilege + set_vector kernel, 0 + set_vector double, 2f + + pt_setup 0, 3, 0, 0x2000, 0x2000, 3 + movi a3, 0x2004 + assert_no_auto_tlb + + movi a2, 0x4005f /* ring 1 + excm => cring == 0 */ + wsr a2, ps + isync +1: + l32e a2, a3, -4 /* ring used */ + test_fail +2: + rsr a2, excvaddr + addi a1, a3, -4 + assert eq, a1, a2 + + assert_auto_tlb + assert_sr depc, 1b + assert_sr exccause, 26 +test_end + +test autoload_pte_load_prohibited + set_vector kernel, 2f + + pt_setup 0, 3, 0, 0x3000, 0, 0xc + assert_no_auto_tlb +1: + l32i a2, a3, 0 + test_fail +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_auto_tlb + assert_sr epc1, 1b + assert_sr exccause, 28 +test_end + +test autoload_pt_load_prohibited + set_vector kernel, 2f + + pt_setup 0, 0xc, 0, 0x4000, 0x4000, 3 + assert_no_auto_tlb +1: + l32i a2, a3, 0 + test_fail +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_no_auto_tlb + assert_sr epc1, 1b + assert_sr exccause, 24 +test_end + +test autoload_pt_privilege + set_vector kernel, 2f + pt_setup 0, 3, 1, 0x5000, 0, 3 + go_ring 1, 0, 0x5001 + + l8ui a2, a3, 0 +1: + syscall +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_auto_tlb + assert_epc1_1m 1b + assert_sr exccause, 1 +test_end + +test autoload_pte_privilege + set_vector kernel, 2f + pt_setup 0, 3, 0, 0x6000, 0, 3 + go_ring 1, 0, 0x6001 +1: + l8ui a2, a3, 0 + syscall +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_auto_tlb + assert_epc1_1m 1b + assert_sr exccause, 26 +test_end + +test autoload_3_level_pt + set_vector kernel, 2f + pt_setup 1, 3, 1, 0x00400000, 0, 3 + pt_setup 1, 3, 1, 0x80001000, 0x2000000, 3 + go_ring 1, 0, 0x00400001 +1: + l8ui a2, a3, 0 + syscall +2: + rsr a2, excvaddr + assert eq, a2, a3 + + assert_no_auto_tlb + assert_epc1_1m 1b + assert_sr exccause, 24 +test_end + +test cross_page_insn + set_vector kernel, 2f + + movi a2, 0x04000003 /* PPN */ + movi a3, 0x00007000 /* VPN */ + witlb a2, a3 + wdtlb a2, a3 + movi a3, 0x00008000 /* VPN */ + witlb a2, a3 + wdtlb a2, a3 + + movi a2, 0x00007fff + movi a3, 20f + movi a4, 21f + sub a4, a4, a3 + loop a4, 1f + l8ui a5, a3, 0 + s8i a5, a2, 0 + addi a2, a2, 1 + addi a3, a3, 1 +1: + movi a2, 0x00007fff + movi a3, 0x00008000 + /* DTLB: OK, ITLB: OK */ + jx a2 + + .begin no-transform +20: + l32i a2, a3, 0 + syscall +21: + .end no-transform + +2: + rsr a2, exccause + movi a3, 1 + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 0x8002 + assert eq, a2, a3 + rsr a2, excsave1 + movi a3, 0x00007fff + assert ne, a2, a3 + + reset_ps + set_vector kernel, 3f + + movi a2, 0x0400000c /* PPN */ + movi a3, 0x00008000 /* VPN */ + wdtlb a2, a3 + movi a2, 0x00007fff + movi a3, 0x00008000 + /* DTLB: FAIL, ITLB: OK */ + jx a2 +3: + rsr a2, exccause + movi a3, 28 + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 0x7fff + assert eq, a2, a3 + rsr a2, excsave1 + movi a3, 0x00007fff + assert eq, a2, a3 + + reset_ps + set_vector kernel, 4f + + movi a2, 0x0400000c /* PPN */ + movi a3, 0x00008000 /* VPN */ + witlb a2, a3 + movi a2, 0x04000003 /* PPN */ + wdtlb a2, a3 + movi a2, 0x00007fff + movi a3, 0x00008000 + /* DTLB: OK, ITLB: FAIL */ + jx a2 +4: + rsr a2, exccause + movi a3, 20 + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 0x7fff + assert eq, a2, a3 + rsr a2, excsave1 + movi a3, 0x00007fff + assert eq, a2, a3 + + reset_ps + set_vector kernel, 5f + + movi a2, 0x0400000c /* PPN */ + movi a3, 0x00008000 /* VPN */ + wdtlb a2, a3 + movi a2, 0x00007fff + movi a3, 0x00008000 + /* DTLB: FAIL, ITLB: FAIL */ + jx a2 +5: + rsr a2, exccause + movi a3, 20 + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 0x7fff + assert eq, a2, a3 + rsr a2, excsave1 + movi a3, 0x00007fff + assert eq, a2, a3 +test_end + +test cross_page_tb + set_vector kernel, 2f + + movi a2, 0x04000003 /* PPN */ + movi a3, 0x00007000 /* VPN */ + witlb a2, a3 + wdtlb a2, a3 + movi a3, 0x00008000 /* VPN */ + witlb a2, a3 + wdtlb a2, a3 + + movi a2, 0x00007ffc + movi a3, 20f + movi a4, 21f + sub a4, a4, a3 + loop a4, 1f + l8ui a5, a3, 0 + s8i a5, a2, 0 + addi a2, a2, 1 + addi a3, a3, 1 +1: + movi a2, 0x00007ffc + movi a3, 0x00008000 + /* DTLB: OK, ITLB: OK */ + jx a2 + + .begin no-transform +20: + l32i a2, a3, 0 + syscall +21: + .end no-transform + +2: + rsr a2, exccause + movi a3, 1 + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 0x7fff + assert eq, a2, a3 + rsr a2, excsave1 + movi a3, 0x00007ffc + assert ne, a2, a3 + + reset_ps + set_vector kernel, 3f + + movi a2, 0x0400000c /* PPN */ + movi a3, 0x00008000 /* VPN */ + wdtlb a2, a3 + movi a2, 0x00007ffc + movi a3, 0x00008000 + /* DTLB: FAIL, ITLB: OK */ + jx a2 +3: + rsr a2, exccause + movi a3, 28 + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 0x7ffc + assert eq, a2, a3 + rsr a2, excsave1 + movi a3, 0x00007ffc + assert eq, a2, a3 + + reset_ps + set_vector kernel, 4f + + movi a2, 0x0400000c /* PPN */ + movi a3, 0x00008000 /* VPN */ + witlb a2, a3 + movi a2, 0x04000003 /* PPN */ + wdtlb a2, a3 + movi a2, 0x00007ffc + movi a3, 0x00008000 + /* DTLB: OK, ITLB: FAIL */ + jx a2 +4: + rsr a2, exccause + movi a3, 20 + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 0x7fff + assert eq, a2, a3 + rsr a2, excsave1 + movi a3, 0x00007ffc + assert ne, a2, a3 + + reset_ps + set_vector kernel, 5f + + movi a2, 0x0400000c /* PPN */ + movi a3, 0x00008000 /* VPN */ + wdtlb a2, a3 + movi a2, 0x00007ffc + movi a3, 0x00008000 + /* DTLB: FAIL, ITLB: FAIL */ + jx a2 +5: + rsr a2, exccause + movi a3, 28 + assert eq, a2, a3 + rsr a2, epc1 + movi a3, 0x7ffc + assert eq, a2, a3 + rsr a2, excsave1 + movi a3, 0x00007ffc + assert eq, a2, a3 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_mul16.S b/qemu/tests/tcg/xtensa/test_mul16.S new file mode 100644 index 000000000..98fa7042b --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_mul16.S @@ -0,0 +1,83 @@ +#include "macros.inc" + +test_suite mul16 + +test mul16u_pp + movi a2, 0x137f5a5a + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x06e180a6 + mul16u a5, a2, a4 + assert eq, a5, a6 + mul16u a2, a2, a4 + assert eq, a2, a6 + mul16u a3, a4, a3 + assert eq, a3, a6 +test_end + +test mul16u_np + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x0c9d6bdb + mul16u a5, a2, a4 + assert eq, a5, a6 + mul16u a2, a2, a4 + assert eq, a2, a6 + mul16u a3, a4, a3 + assert eq, a3, a6 +test_end + +test mul16u_nn + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5f731 + movi a6, 0x9ff1e795 + mul16u a5, a2, a4 + assert eq, a5, a6 + mul16u a2, a2, a4 + assert eq, a2, a6 + mul16u a3, a4, a3 + assert eq, a3, a6 +test_end + +test mul16s_pp + movi a2, 0x137f5a5a + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x06e180a6 + mul16s a5, a2, a4 + assert eq, a5, a6 + mul16s a2, a2, a4 + assert eq, a2, a6 + mul16s a3, a4, a3 + assert eq, a3, a6 +test_end + +test mul16s_np + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xf91e6bdb + mul16s a5, a2, a4 + assert eq, a5, a6 + mul16s a2, a2, a4 + assert eq, a2, a6 + mul16s a3, a4, a3 + assert eq, a3, a6 +test_end + +test mul16s_nn + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5f731 + movi a6, 0x031be795 + mul16s a5, a2, a4 + assert eq, a5, a6 + mul16s a2, a2, a4 + assert eq, a2, a6 + mul16s a3, a4, a3 + assert eq, a3, a6 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_mul32.S b/qemu/tests/tcg/xtensa/test_mul32.S new file mode 100644 index 000000000..b288ead9f --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_mul32.S @@ -0,0 +1,20 @@ +#include "macros.inc" + +test_suite mul32 + +test mull + movi a2, 0x137f5a5a + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x5de480a6 + mull a5, a2, a4 + assert eq, a5, a6 + mull a2, a2, a4 + assert eq, a2, a6 + mull a3, a4, a3 + assert eq, a3, a6 +test_end + +/* unfortunately dc232b doesn't have muluh/mulsh*/ + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_nsa.S b/qemu/tests/tcg/xtensa/test_nsa.S new file mode 100644 index 000000000..479b2e242 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_nsa.S @@ -0,0 +1,59 @@ +#include "macros.inc" + +test_suite nsa + +test nsa + movi a2, 0 + movi a3, 31 + nsa a4, a2 + assert eq, a3, a4 + + movi a2, 0xffffffff + movi a3, 31 + nsa a4, a2 + assert eq, a3, a4 + + movi a2, 1 + movi a3, 30 + nsa a2, a2 + assert eq, a3, a2 + + movi a2, 0xfffffffe + movi a3, 30 + nsa a2, a2 + assert eq, a3, a2 + + movi a2, 0x5a5a5a5a + movi a3, 0 + nsa a4, a2 + assert eq, a3, a4 + + movi a2, 0xa5a5a5a5 + movi a3, 0 + nsa a4, a2 + assert eq, a3, a4 +test_end + +test nsau + movi a2, 0 + movi a3, 32 + nsau a4, a2 + assert eq, a3, a4 + + movi a2, 0xffffffff + movi a3, 0 + nsau a4, a2 + assert eq, a3, a4 + + movi a2, 1 + movi a3, 31 + nsau a2, a2 + assert eq, a3, a2 + + movi a2, 0x5a5a5a5a + movi a3, 1 + nsau a2, a2 + assert eq, a3, a2 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_pipeline.S b/qemu/tests/tcg/xtensa/test_pipeline.S new file mode 100644 index 000000000..f418c1197 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_pipeline.S @@ -0,0 +1,157 @@ +#include "macros.inc" + +.purgem test +.macro test name + movi a2, 1f + movi a3, 99f +0: + ipf a2, 0 + ipf a2, 4 + ipf a2, 8 + ipf a2, 12 + addi a2, a2, 16 + blt a2, a3, 0b + j 1f + .align 4 +1: +.endm + +test_suite pipeline + +test register_no_stall + rsr a3, ccount + add a5, a6, a6 + add a6, a5, a5 + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 3 +test_end + +test register_stall + l32i a5, a1, 0 /* data cache preload */ + nop + rsr a3, ccount + l32i a5, a1, 0 + add a6, a5, a5 /* M-to-E interlock */ + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 4 +test_end + +test j0_stall + rsr a3, ccount + j 1f /* E + 2-cycle penalty */ +1: + rsr a4, ccount /* E */ + sub a3, a4, a3 + assert eqi, a3, 4 +test_end + +test j1_stall + rsr a3, ccount + j 1f + nop +1: + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 4 +test_end + +test j5_stall + rsr a3, ccount + j 1f + nop + nop + nop + nop + nop +1: + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 4 +test_end + +test b_no_stall + movi a5, 1 + rsr a3, ccount + beqi a5, 2, 1f + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 2 +1: +test_end + +test b1_stall + movi a5, 1 + rsr a3, ccount + beqi a5, 1, 1f + nop +1: + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 4 +test_end + +test b5_stall + movi a5, 1 + rsr a3, ccount + beqi a5, 1, 1f + nop + nop + nop + nop + nop +1: + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 4 +test_end + +/* PS *SYNC */ + +test ps_dsync + rsr a5, ps + isync + rsr a3, ccount + wsr a5, ps + dsync + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 5 +test_end + +test ps_esync + rsr a5, ps + isync + rsr a3, ccount + wsr a5, ps + esync + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 5 +test_end + +test ps_rsync + rsr a5, ps + isync + rsr a3, ccount + wsr a5, ps + rsync + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 5 +test_end + +test ps_isync + rsr a5, ps + isync + rsr a3, ccount + wsr a5, ps + isync + rsr a4, ccount + sub a3, a4, a3 + movi a4, 9 + assert eq, a3, a4 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_quo.S b/qemu/tests/tcg/xtensa/test_quo.S new file mode 100644 index 000000000..5b3ae383d --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_quo.S @@ -0,0 +1,147 @@ +#include "macros.inc" + +test_suite quo + +test quou_pp + movi a2, 0x5a5a137f + mov a3, a2 + movi a4, 0x137f5a5a + movi a6, 0x4 + quou a5, a2, a4 + assert eq, a5, a6 + quou a2, a2, a4 + assert eq, a2, a6 + quou a4, a3, a4 + assert eq, a4, a6 +test_end + +test quou_np + movi a2, 0xa5a5137f + mov a3, a2 + movi a4, 0x137f5a5a + movi a6, 0x8 + quou a5, a2, a4 + assert eq, a5, a6 + quou a2, a2, a4 + assert eq, a2, a6 + quou a4, a3, a4 + assert eq, a4, a6 +test_end + +test quou_pn + movi a2, 0x5a5a137f + mov a3, a2 + movi a4, 0xf7315a5a + movi a6, 0 + quou a5, a2, a4 + assert eq, a5, a6 + quou a2, a2, a4 + assert eq, a2, a6 + quou a4, a3, a4 + assert eq, a4, a6 +test_end + +test quou_nn + movi a2, 0xf7315a5a + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x1 + quou a5, a2, a4 + assert eq, a5, a6 + quou a2, a2, a4 + assert eq, a2, a6 + quou a4, a3, a4 + assert eq, a4, a6 +test_end + +test quou_exc + set_vector kernel, 2f + movi a2, 0xf7315a5a + movi a4, 0x00000000 +1: + quou a5, a2, a4 + test_fail +2: + rsr a2, exccause + assert eqi, a2, 6 /* INTEGER_DIVIDE_BY_ZERO_CAUSE */ + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 +test_end + +test quos_pp + movi a2, 0x5a5a137f + mov a3, a2 + movi a4, 0x137f5a5a + movi a6, 0x4 + quos a5, a2, a4 + assert eq, a5, a6 + quos a2, a2, a4 + assert eq, a2, a6 + quos a4, a3, a4 + assert eq, a4, a6 +test_end + +test quos_np + movi a2, 0xa5a5137f + mov a3, a2 + movi a4, 0x137f5a5a + movi a6, 0xfffffffc + quos a5, a2, a4 + assert eq, a5, a6 + quos a2, a2, a4 + assert eq, a2, a6 + quos a4, a3, a4 + assert eq, a4, a6 +test_end + +test quos_pn + movi a2, 0x5a5a137f + mov a3, a2 + movi a4, 0xf7315a5a + movi a6, 0xfffffff6 + quos a5, a2, a4 + assert eq, a5, a6 + quos a2, a2, a4 + assert eq, a2, a6 + quos a4, a3, a4 + assert eq, a4, a6 +test_end + +test quos_nn + movi a2, 0xf7315a5a + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0 + quos a5, a2, a4 + assert eq, a5, a6 + quos a2, a2, a4 + assert eq, a2, a6 + quos a4, a3, a4 + assert eq, a4, a6 +test_end + +test quos_over + movi a2, 0x80000000 + movi a4, 0xffffffff + movi a6, 0x80000000 + quos a5, a2, a4 + assert eq, a5, a6 +test_end + +test quos_exc + set_vector kernel, 2f + movi a2, 0xf7315a5a + movi a4, 0x00000000 +1: + quos a5, a2, a4 + test_fail +2: + rsr a2, exccause + assert eqi, a2, 6 /* INTEGER_DIVIDE_BY_ZERO_CAUSE */ + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_rem.S b/qemu/tests/tcg/xtensa/test_rem.S new file mode 100644 index 000000000..6357e520d --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_rem.S @@ -0,0 +1,147 @@ +#include "macros.inc" + +test_suite rem + +test remu_pp + movi a2, 0x5a5a137f + mov a3, a2 + movi a4, 0x137f5a5a + movi a6, 0x0c5caa17 + remu a5, a2, a4 + assert eq, a5, a6 + remu a2, a2, a4 + assert eq, a2, a6 + remu a4, a3, a4 + assert eq, a4, a6 +test_end + +test remu_np + movi a2, 0xa5a5137f + mov a3, a2 + movi a4, 0x137f5a5a + movi a6, 0x9aa40af + remu a5, a2, a4 + assert eq, a5, a6 + remu a2, a2, a4 + assert eq, a2, a6 + remu a4, a3, a4 + assert eq, a4, a6 +test_end + +test remu_pn + movi a2, 0x5a5a137f + mov a3, a2 + movi a4, 0xf7315a5a + movi a6, 0x5a5a137f + remu a5, a2, a4 + assert eq, a5, a6 + remu a2, a2, a4 + assert eq, a2, a6 + remu a4, a3, a4 + assert eq, a4, a6 +test_end + +test remu_nn + movi a2, 0xf7315a5a + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x518c46db + remu a5, a2, a4 + assert eq, a5, a6 + remu a2, a2, a4 + assert eq, a2, a6 + remu a4, a3, a4 + assert eq, a4, a6 +test_end + +test remu_exc + set_vector kernel, 2f + movi a2, 0xf7315a5a + movi a4, 0x00000000 +1: + remu a5, a2, a4 + test_fail +2: + rsr a2, exccause + assert eqi, a2, 6 /* INTEGER_DIVIDE_BY_ZERO_CAUSE */ + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 +test_end + +test rems_pp + movi a2, 0x5a5a137f + mov a3, a2 + movi a4, 0x137f5a5a + movi a6, 0x0c5caa17 + rems a5, a2, a4 + assert eq, a5, a6 + rems a2, a2, a4 + assert eq, a2, a6 + rems a4, a3, a4 + assert eq, a4, a6 +test_end + +test rems_np + movi a2, 0xa5a5137f + mov a3, a2 + movi a4, 0x137f5a5a + movi a6, 0xf3a27ce7 + rems a5, a2, a4 + assert eq, a5, a6 + rems a2, a2, a4 + assert eq, a2, a6 + rems a4, a3, a4 + assert eq, a4, a6 +test_end + +test rems_pn + movi a2, 0x5a5a137f + mov a3, a2 + movi a4, 0xf7315a5a + movi a6, 0x02479b03 + rems a5, a2, a4 + assert eq, a5, a6 + rems a2, a2, a4 + assert eq, a2, a6 + rems a4, a3, a4 + assert eq, a4, a6 +test_end + +test rems_nn + movi a2, 0xf7315a5a + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xf7315a5a + rems a5, a2, a4 + assert eq, a5, a6 + rems a2, a2, a4 + assert eq, a2, a6 + rems a4, a3, a4 + assert eq, a4, a6 +test_end + +test rems_over + movi a2, 0x80000000 + movi a4, 0xffffffff + movi a6, 0 + rems a5, a2, a4 + assert eq, a5, a6 +test_end + +test rems_exc + set_vector kernel, 2f + movi a2, 0xf7315a5a + movi a4, 0x00000000 +1: + rems a5, a2, a4 + test_fail +2: + rsr a2, exccause + assert eqi, a2, 6 /* INTEGER_DIVIDE_BY_ZERO_CAUSE */ + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_rst0.S b/qemu/tests/tcg/xtensa/test_rst0.S new file mode 100644 index 000000000..a73366b12 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_rst0.S @@ -0,0 +1,148 @@ +#include "macros.inc" + +test_suite rst0 + +test and + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x01250125 + and a5, a2, a4 + assert eq, a5, a6 + and a2, a2, a4 + assert eq, a2, a6 + and a3, a4, a3 + assert eq, a3, a6 +test_end + +test or + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xb7ffb7ff + or a5, a2, a4 + assert eq, a5, a6 + or a2, a2, a4 + assert eq, a2, a6 + or a3, a4, a3 + assert eq, a3, a6 +test_end + +test xor + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xb6dab6da + xor a5, a2, a4 + assert eq, a5, a6 + xor a2, a2, a4 + assert eq, a2, a6 + xor a3, a4, a3 + assert eq, a3, a6 +test_end + +test add + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xb924b924 + add a5, a2, a4 + assert eq, a5, a6 + add a2, a2, a4 + assert eq, a2, a6 + add a4, a3, a4 + assert eq, a4, a6 +test_end + +test addx2 + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xcca45ec9 + addx2 a5, a2, a4 + assert eq, a5, a6 + addx2 a2, a2, a4 + assert eq, a2, a6 + addx2 a4, a3, a4 + assert eq, a4, a6 +test_end + +test addx4 + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xf3a3aa13 + addx4 a5, a2, a4 + assert eq, a5, a6 + addx4 a2, a2, a4 + assert eq, a2, a6 + addx4 a4, a3, a4 + assert eq, a4, a6 +test_end + +test addx8 + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x41a240a7 + addx8 a5, a2, a4 + assert eq, a5, a6 + addx8 a2, a2, a4 + assert eq, a2, a6 + addx8 a4, a3, a4 + assert eq, a4, a6 +test_end + +test sub + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x6dda9226 + sub a5, a2, a4 + assert eq, a5, a6 + sub a2, a2, a4 + assert eq, a2, a6 + sub a4, a3, a4 + assert eq, a4, a6 +test_end + +test subx2 + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0x815a37cb + subx2 a5, a2, a4 + assert eq, a5, a6 + subx2 a2, a2, a4 + assert eq, a2, a6 + subx2 a4, a3, a4 + assert eq, a4, a6 +test_end + +test subx4 + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xa8598315 + subx4 a5, a2, a4 + assert eq, a5, a6 + subx4 a2, a2, a4 + assert eq, a2, a6 + subx4 a4, a3, a4 + assert eq, a4, a6 +test_end + +test subx8 + movi a2, 0x137fa5a5 + mov a3, a2 + movi a4, 0xa5a5137f + movi a6, 0xf65819a9 + subx8 a5, a2, a4 + assert eq, a5, a6 + subx8 a2, a2, a4 + assert eq, a2, a6 + subx8 a4, a3, a4 + assert eq, a4, a6 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_s32c1i.S b/qemu/tests/tcg/xtensa/test_s32c1i.S new file mode 100644 index 000000000..93b575db9 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_s32c1i.S @@ -0,0 +1,39 @@ +#include "macros.inc" + +test_suite s32c1i + +test s32c1i_nowrite + movi a2, 1f + movi a3, 1 + wsr a3, scompare1 + movi a1, 2 + s32c1i a1, a2, 0 + assert ne, a1, a3 + l32i a1, a2, 0 + assert eqi, a1, 3 + +.data +.align 4 +1: + .word 3 +.text +test_end + +test s32c1i_write + movi a2, 1f + movi a3, 3 + wsr a3, scompare1 + movi a1, 2 + s32c1i a1, a2, 0 + assert eq, a1, a3 + l32i a1, a2, 0 + assert eqi, a1, 2 + +.data +.align 4 +1: + .word 3 +.text +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_sar.S b/qemu/tests/tcg/xtensa/test_sar.S new file mode 100644 index 000000000..b615a5576 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_sar.S @@ -0,0 +1,111 @@ +#include "macros.inc" + +test_suite sar + +.macro test_sar prefix, imm + \prefix\()_set \imm + \prefix\()_ver \imm +.endm + +.macro tests_sar prefix + test_sar \prefix, 0 + test_sar \prefix, 1 + test_sar \prefix, 2 + test_sar \prefix, 3 + test_sar \prefix, 0x1f + test_sar \prefix, 0x20 + test_sar \prefix, 0x3f + test_sar \prefix, 0x40 + test_sar \prefix, 0xfffffffe +.endm + +.macro sar_set imm + movi a2, \imm + wsr a2, sar +.endm + +.macro sar_ver imm + rsr a3, sar + movi a2, \imm & 0x3f + assert eq, a2, a3 +.endm + +test sar + tests_sar sar +test_end + +.macro ssr_set imm + movi a2, \imm + ssr a2 +.endm + +.macro ssr_ver imm + rsr a3, sar + movi a2, \imm & 0x1f + assert eq, a2, a3 +.endm + +test ssr + tests_sar ssr +test_end + +.macro ssl_set imm + movi a2, \imm + ssl a2 +.endm + +.macro ssl_ver imm + rsr a3, sar + movi a2, 32 - (\imm & 0x1f) + assert eq, a2, a3 +.endm + +test ssl + tests_sar ssl +test_end + +.macro ssa8l_set imm + movi a2, \imm + ssa8l a2 +.endm + +.macro ssa8l_ver imm + rsr a3, sar + movi a2, (\imm & 0x3) << 3 + assert eq, a2, a3 +.endm + +test ssa8l + tests_sar ssa8l +test_end + +.macro ssa8b_set imm + movi a2, \imm + ssa8b a2 +.endm + +.macro ssa8b_ver imm + rsr a3, sar + movi a2, 32 - ((\imm & 0x3) << 3) + assert eq, a2, a3 +.endm + +test ssa8b + tests_sar ssa8b +test_end + +.macro ssai_set imm + ssai \imm & 0x1f +.endm + +.macro ssai_ver imm + rsr a3, sar + movi a2, \imm & 0x1f + assert eq, a2, a3 +.endm + +test ssai + tests_sar ssai +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_sext.S b/qemu/tests/tcg/xtensa/test_sext.S new file mode 100644 index 000000000..087a6333a --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_sext.S @@ -0,0 +1,69 @@ +#include "macros.inc" + +test_suite sext + +test sext + movi a2, 0xffffff5a + movi a3, 0x0000005a + sext a4, a2, 7 + assert eq, a3, a4 + + movi a2, 0x000000a5 + movi a3, 0xffffffa5 + sext a4, a2, 7 + assert eq, a3, a4 + + movi a2, 0xfffffaa5 + movi a3, 0x000000a5 + sext a4, a2, 8 + assert eq, a3, a4 + + movi a2, 0x0000055a + movi a3, 0xffffff5a + sext a4, a2, 8 + assert eq, a3, a4 + + movi a2, 0xffff5a5a + movi a3, 0x00005a5a + sext a4, a2, 15 + assert eq, a3, a4 + + movi a2, 0x0000a5a5 + movi a3, 0xffffa5a5 + sext a4, a2, 15 + assert eq, a3, a4 + + movi a2, 0x00055a5a + movi a3, 0xffff5a5a + sext a4, a2, 16 + assert eq, a3, a4 + + movi a2, 0x000aa5a5 + movi a3, 0x0000a5a5 + sext a4, a2, 16 + assert eq, a3, a4 + + movi a2, 0x005a5a5a + movi a3, 0xffda5a5a + sext a4, a2, 22 + assert eq, a3, a4 + + movi a2, 0xffa5a5a5 + movi a3, 0x0025a5a5 + sext a4, a2, 22 + assert eq, a3, a4 +test_end + +test sext_same_rs + movi a2, 0xffffff5a + movi a3, 0x0000005a + sext a2, a2, 7 + assert eq, a3, a2 + + movi a2, 0x000000a5 + movi a3, 0xffffffa5 + sext a2, a2, 7 + assert eq, a3, a2 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_shift.S b/qemu/tests/tcg/xtensa/test_shift.S new file mode 100644 index 000000000..5df9ed4b1 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_shift.S @@ -0,0 +1,206 @@ +#include "macros.inc" + +test_suite shift + +.macro test_shift prefix, dst, src, v, imm + \prefix\()_set \dst, \src, \v, \imm + \prefix\()_ver \dst, \v, \imm +.endm + +.macro test_shift_sd prefix, v, imm + test_shift \prefix, a3, a2, \v, \imm + test_shift \prefix, a2, a2, \v, \imm +.endm + +.macro tests_imm_shift prefix, v + test_shift_sd \prefix, \v, 1 + test_shift_sd \prefix, \v, 2 + test_shift_sd \prefix, \v, 7 + test_shift_sd \prefix, \v, 8 + test_shift_sd \prefix, \v, 15 + test_shift_sd \prefix, \v, 16 + test_shift_sd \prefix, \v, 31 +.endm + +.macro tests_shift prefix, v + test_shift_sd \prefix, \v, 0 + tests_imm_shift \prefix, \v + test_shift_sd \prefix, \v, 32 +.endm + + +.macro slli_set dst, src, v, imm + movi \src, \v + slli \dst, \src, \imm +.endm + +.macro slli_ver dst, v, imm + mov a2, \dst + movi a3, ((\v) << (\imm)) & 0xffffffff + assert eq, a2, a3 +.endm + +test slli + tests_imm_shift slli, 0xa3c51249 +test_end + + +.macro srai_set dst, src, v, imm + movi \src, \v + srai \dst, \src, \imm +.endm + +.macro srai_ver dst, v, imm + mov a2, \dst + .if (\imm) + movi a3, (((\v) >> (\imm)) & 0xffffffff) | \ + ~((((\v) & 0x80000000) >> ((\imm) - 1)) - 1) + .else + movi a3, \v + .endif + assert eq, a2, a3 +.endm + +test srai + tests_imm_shift srai, 0x49a3c512 + tests_imm_shift srai, 0xa3c51249 +test_end + + +.macro srli_set dst, src, v, imm + movi \src, \v + srli \dst, \src, \imm +.endm + +.macro srli_ver dst, v, imm + mov a2, \dst + movi a3, (((\v) >> (\imm)) & 0xffffffff) + assert eq, a2, a3 +.endm + +test srli + tests_imm_shift srli, 0x49a3c512 + tests_imm_shift srli, 0xa3c51249 +test_end + + +.macro sll_set dst, src, v, imm + movi a2, \imm + ssl a2 + movi \src, \v + sll \dst, \src +.endm + +.macro sll_sar_set dst, src, v, imm + movi a2, 32 - \imm + wsr a2, sar + movi \src, \v + sll \dst, \src +.endm + +.macro sll_ver dst, v, imm + slli_ver \dst, \v, (\imm) & 0x1f +.endm + +.macro sll_sar_ver dst, v, imm + slli_ver \dst, \v, \imm +.endm + +test sll + tests_shift sll, 0xa3c51249 + tests_shift sll_sar, 0xa3c51249 +test_end + + +.macro srl_set dst, src, v, imm + movi a2, \imm + ssr a2 + movi \src, \v + srl \dst, \src +.endm + +.macro srl_sar_set dst, src, v, imm + movi a2, \imm + wsr a2, sar + movi \src, \v + srl \dst, \src +.endm + +.macro srl_ver dst, v, imm + srli_ver \dst, \v, (\imm) & 0x1f +.endm + +.macro srl_sar_ver dst, v, imm + srli_ver \dst, \v, \imm +.endm + +test srl + tests_shift srl, 0xa3c51249 + tests_shift srl_sar, 0xa3c51249 + tests_shift srl, 0x49a3c512 + tests_shift srl_sar, 0x49a3c512 +test_end + + +.macro sra_set dst, src, v, imm + movi a2, \imm + ssr a2 + movi \src, \v + sra \dst, \src +.endm + +.macro sra_sar_set dst, src, v, imm + movi a2, \imm + wsr a2, sar + movi \src, \v + sra \dst, \src +.endm + +.macro sra_ver dst, v, imm + srai_ver \dst, \v, (\imm) & 0x1f +.endm + +.macro sra_sar_ver dst, v, imm + srai_ver \dst, \v, \imm +.endm + +test sra + tests_shift sra, 0xa3c51249 + tests_shift sra_sar, 0xa3c51249 + tests_shift sra, 0x49a3c512 + tests_shift sra_sar, 0x49a3c512 +test_end + + +.macro src_set dst, src, v, imm + movi a2, \imm + ssr a2 + movi \src, (\v) & 0xffffffff + movi a4, (\v) >> 32 + src \dst, a4, \src +.endm + +.macro src_sar_set dst, src, v, imm + movi a2, \imm + wsr a2, sar + movi \src, (\v) & 0xffffffff + movi a4, (\v) >> 32 + src \dst, a4, \src +.endm + +.macro src_ver dst, v, imm + src_sar_ver \dst, \v, (\imm) & 0x1f +.endm + +.macro src_sar_ver dst, v, imm + mov a2, \dst + movi a3, ((\v) >> (\imm)) & 0xffffffff + assert eq, a2, a3 +.endm + +test src + tests_shift src, 0xa3c51249215c3a94 + tests_shift src_sar, 0xa3c51249215c3a94 +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_sr.S b/qemu/tests/tcg/xtensa/test_sr.S new file mode 100644 index 000000000..4fac46e80 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_sr.S @@ -0,0 +1,90 @@ +#include "macros.inc" + +test_suite sr + +.macro sr_op sym, op_sym, op_byte, sr + .if \sym + \op_sym a4, \sr + .else + .byte 0x40, \sr, \op_byte + .endif +.endm + +.macro test_sr_op sym, mask, op, op_byte, sr + movi a4, 0 + .if (\mask) + set_vector kernel, 0 + sr_op \sym, \op, \op_byte, \sr + .else + set_vector kernel, 2f +1: + sr_op \sym, \op, \op_byte, \sr + test_fail +2: + reset_ps + rsr a2, exccause + assert eqi, a2, 0 + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + .endif +.endm + +.macro test_sr_mask sr, sym, mask +test \sr + test_sr_op \sym, \mask & 1, rsr, 0x03, \sr + test_sr_op \sym, \mask & 2, wsr, 0x13, \sr + test_sr_op \sym, \mask & 4, xsr, 0x61, \sr +test_end +.endm + +.macro test_sr sr, conf + test_sr_mask \sr, \conf, 7 +.endm + +test_sr acchi, 1 +test_sr acclo, 1 +test_sr_mask /*atomctl*/99, 0, 0 +test_sr_mask /*br*/4, 0, 0 +test_sr_mask /*cacheattr*/98, 0, 0 +test_sr ccompare0, 1 +test_sr ccount, 1 +test_sr cpenable, 1 +test_sr dbreaka0, 1 +test_sr dbreakc0, 1 +test_sr_mask debugcause, 1, 1 +test_sr depc, 1 +test_sr dtlbcfg, 1 +test_sr epc1, 1 +test_sr epc2, 1 +test_sr eps2, 1 +test_sr exccause, 1 +test_sr excsave1, 1 +test_sr excsave2, 1 +test_sr excvaddr, 1 +test_sr ibreaka0, 1 +test_sr ibreakenable, 1 +test_sr icount, 1 +test_sr icountlevel, 1 +test_sr_mask /*intclear*/227, 0, 2 +test_sr_mask /*interrupt*/226, 0, 3 +test_sr intenable, 1 +test_sr itlbcfg, 1 +test_sr lbeg, 1 +test_sr lcount, 1 +test_sr lend, 1 +test_sr litbase, 1 +test_sr m0, 1 +test_sr misc0, 1 +test_sr_mask /*prefctl*/40, 0, 0 +test_sr_mask /*prid*/235, 0, 1 +test_sr ps, 1 +test_sr ptevaddr, 1 +test_sr rasid, 1 +test_sr sar, 1 +test_sr scompare1, 1 +test_sr vecbase, 1 +test_sr windowbase, 1 +test_sr windowstart, 1 + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_timer.S b/qemu/tests/tcg/xtensa/test_timer.S new file mode 100644 index 000000000..f8c6f7423 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_timer.S @@ -0,0 +1,178 @@ +#include "macros.inc" + +test_suite timer + +test ccount + rsr a3, ccount + rsr a4, ccount + sub a3, a4, a3 + assert eqi, a3, 1 +test_end + +test ccompare + movi a2, 0 + wsr a2, intenable + rsr a2, interrupt + wsr a2, intclear + movi a2, 0 + wsr a2, ccompare1 + wsr a2, ccompare2 + + movi a3, 20 + rsr a2, ccount + addi a2, a2, 20 + wsr a2, ccompare0 + rsr a2, interrupt + assert eqi, a2, 0 + loop a3, 1f + rsr a3, interrupt + bnez a3, 2f +1: + test_fail +2: +test_end + +test ccompare0_interrupt + set_vector kernel, 2f + movi a2, 0 + wsr a2, intenable + rsr a2, interrupt + wsr a2, intclear + movi a2, 0 + wsr a2, ccompare1 + wsr a2, ccompare2 + + movi a3, 20 + rsr a2, ccount + addi a2, a2, 20 + wsr a2, ccompare0 + rsync + rsr a2, interrupt + assert eqi, a2, 0 + + movi a2, 0x40 + wsr a2, intenable + rsil a2, 0 + loop a3, 1f + nop +1: + test_fail +2: + rsr a2, exccause + assert eqi, a2, 4 /* LEVEL1_INTERRUPT_CAUSE */ +test_end + +test ccompare1_interrupt + set_vector level3, 2f + movi a2, 0 + wsr a2, intenable + rsr a2, interrupt + wsr a2, intclear + movi a2, 0 + wsr a2, ccompare0 + wsr a2, ccompare2 + + movi a3, 20 + rsr a2, ccount + addi a2, a2, 20 + wsr a2, ccompare1 + rsync + rsr a2, interrupt + assert eqi, a2, 0 + movi a2, 0x400 + wsr a2, intenable + rsil a2, 2 + loop a3, 1f + nop +1: + test_fail +2: +test_end + +test ccompare2_interrupt + set_vector level5, 2f + movi a2, 0 + wsr a2, intenable + rsr a2, interrupt + wsr a2, intclear + movi a2, 0 + wsr a2, ccompare0 + wsr a2, ccompare1 + + movi a3, 20 + rsr a2, ccount + addi a2, a2, 20 + wsr a2, ccompare2 + rsync + rsr a2, interrupt + assert eqi, a2, 0 + movi a2, 0x2000 + wsr a2, intenable + rsil a2, 4 + loop a3, 1f + nop +1: + test_fail +2: +test_end + +test ccompare_interrupt_masked + set_vector kernel, 2f + movi a2, 0 + wsr a2, intenable + rsr a2, interrupt + wsr a2, intclear + movi a2, 0 + wsr a2, ccompare2 + + movi a3, 40 + rsr a2, ccount + addi a2, a2, 20 + wsr a2, ccompare1 + addi a2, a2, 20 + wsr a2, ccompare0 + rsync + rsr a2, interrupt + assert eqi, a2, 0 + + movi a2, 0x40 + wsr a2, intenable + rsil a2, 0 + loop a3, 1f + nop +1: + test_fail +2: + rsr a2, exccause + assert eqi, a2, 4 /* LEVEL1_INTERRUPT_CAUSE */ +test_end + +test ccompare_interrupt_masked_waiti + set_vector kernel, 2f + movi a2, 0 + wsr a2, intenable + rsr a2, interrupt + wsr a2, intclear + movi a2, 0 + wsr a2, ccompare2 + + movi a3, 40 + rsr a2, ccount + addi a2, a2, 20 + wsr a2, ccompare1 + addi a2, a2, 20 + wsr a2, ccompare0 + rsync + rsr a2, interrupt + assert eqi, a2, 0 + + movi a2, 0x40 + wsr a2, intenable + waiti 0 + test_fail +2: + rsr a2, exccause + assert eqi, a2, 4 /* LEVEL1_INTERRUPT_CAUSE */ +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/test_windowed.S b/qemu/tests/tcg/xtensa/test_windowed.S new file mode 100644 index 000000000..d851e8f43 --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_windowed.S @@ -0,0 +1,353 @@ +#include "macros.inc" + +test_suite windowed + +.altmacro + +.macro reset_window start + movi a2, 0xff + wsr a2, windowstart + rsync + movi a2, 0 + wsr a2, windowbase + rsync + movi a2, \start + wsr a2, windowstart + rsync +.endm + +.macro overflow_test shift, window, probe_ok, probe_ex + set_vector window_overflow_4, 0 + set_vector window_overflow_8, 0 + set_vector window_overflow_12, 0 + + movi a2, 1 | (((1 << ((\window) / 4)) | 1) << ((\shift) / 4)) + wsr a2, windowstart + reset_ps + + mov a2, a\probe_ok + set_vector window_overflow_\window, 10f +1: + mov a2, a\probe_ex + test_fail +10: + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + movi a2, 2f + wsr a2, epc1 + + rsr a2, windowbase + movi a3, (\shift) / 4 + assert eq, a2, a3 + rsr a2, ps + movi a3, 0x4001f + assert eq, a2, a3 + rfwo + test_fail +2: + rsr a2, windowbase + assert eqi, a2, 0 + rsr a2, windowstart + movi a3, 1 | ((1 << ((\window) / 4)) << ((\shift) / 4)) + assert eq, a2, a3 + rsr a2, ps + movi a3, 0x4000f + assert eq, a2, a3 +.endm + +.macro overflow_tests shift, window, probe + .if \probe < 15 + overflow_test \shift, \window, %((\shift) - 1), \probe + overflow_tests \shift, \window, %((\probe) + 1) + .endif +.endm + +.macro all_overflow_tests + .irp shift, 4, 8, 12 + .irp window, 4, 8, 12 + overflow_tests \shift, \window, \shift + .endr + .endr +.endm + +test overflow + all_overflow_tests +test_end + + +.macro underflow_test window + set_vector window_underflow_4, 0 + set_vector window_underflow_8, 0 + set_vector window_underflow_12, 0 + + set_vector window_underflow_\window, 10f + + reset_window 1 + reset_ps + + ssai 2 + movi a2, 2f + slli a2, a2, 2 + movi a3, (\window) / 4 + src a0, a3, a2 +1: + retw + test_fail +10: + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + movi a2, 2f + wsr a2, epc1 + + rsr a2, ps + movi a3, 0x4001f + assert eq, a2, a3 + rsr a2, windowbase + assert eqi, a2, 8 - ((\window) / 4) + rsr a2, windowstart + assert eqi, a2, 1 + rfwu +2: + rsr a2, ps + movi a3, 0x4000f + assert eq, a2, a3 + rsr a2, windowbase + assert eqi, a2, 0 + rsr a2, windowstart + assert bsi, a2, 0 + assert bsi, a2, 8 - ((\window) / 4) +.endm + +test underflow + set_vector window_overflow_4, 0 + set_vector window_overflow_8, 0 + set_vector window_overflow_12, 0 + + underflow_test 4 + underflow_test 8 + underflow_test 12 +test_end + + +.macro retw_test window + reset_window %(1 | (1 << (8 - (\window) / 4))) + reset_ps + + ssai 2 + movi a2, 1f + slli a2, a2, 2 + movi a3, (\window) / 4 + src a0, a3, a2 + retw + test_fail +1: + rsr a2, ps + movi a3, 0x4000f + assert eq, a2, a3 + rsr a2, windowbase + assert eqi, a2, 8 - ((\window) / 4) + rsr a2, windowstart + assert bci, a2, 0 + assert bsi, a2, 8 - ((\window) / 4) +.endm + +test retw + set_vector window_underflow_4, 0 + set_vector window_underflow_8, 0 + set_vector window_underflow_12, 0 + + retw_test 4 + retw_test 8 + retw_test 12 +test_end + +test movsp + set_vector kernel, 2f + + reset_window 1 + reset_ps +1: + movsp a2, a3 + test_fail +2: + rsr a2, exccause + assert eqi, a2, 5 + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + + set_vector kernel, 0 + + reset_window 0x81 + reset_ps + + movsp a2, a3 +test_end + +test rotw + reset_window 0x4b + reset_ps + + movi a3, 0x10 + + rotw 1 + rsr a2, windowbase + assert eqi, a2, 1 + movi a3, 0x11 + movi a7, 0x12 + + rotw 2 + rsr a2, windowbase + assert eqi, a2, 3 + movi a3, 0x13 + movi a7, 0x14 + movi a11, 0x15 + + rotw 3 + rsr a2, windowbase + assert eqi, a2, 6 + movi a3, 0x16 + movi a7, 0x17 + + movi a2, 0x44 + wsr a2, windowstart + rsync + + movi a2, 0x10 + assert eq, a2, a11 + movi a11, 0x18 + movi a2, 0x11 + assert eq, a2, a15 + movi a15, 0x19 + + rotw 4 + movi a2, 0x12 + assert eq, a2, a3 + movi a2, 0x13 + assert eq, a2, a7 + movi a2, 0x14 + assert eq, a2, a11 + movi a2, 0x15 + assert eq, a2, a15 + + movi a2, 0x5 + wsr a2, windowstart + rsync + + rotw -2 + movi a2, 0x18 + assert eq, a2, a3 + movi a2, 0x19 + assert eq, a2, a7 +test_end + +.macro callw_test window + call\window 2f +1: + test_fail + .align 4 +2: + rsr a2, windowbase + assert eqi, a2, 0 + rsr a2, ps + movi a3, 0x4000f | ((\window) << 14) + assert eq, a2, a3 + movi a2, 1b + slli a2, a2, 2 + ssai 2 + movi a3, (\window) / 4 + src a2, a3, a2 + assert eq, a2, a\window +.endm + +test callw + reset_window 0x1 + reset_ps + + callw_test 4 + callw_test 8 + callw_test 12 +test_end + + +.macro entry_test window + reset_window 0x1 + reset_ps + movi a2, 0x4000f | ((\window) << 14) + wsr a2, ps + isync + movi a3, 0x12345678 + j 1f + .align 4 +1: + entry a3, 0x5678 + movi a2, 0x12340000 + assert eq, a2, a3 + rsr a2, windowbase + assert eqi, a2, (\window) / 4 + rsr a2, windowstart + movi a3, 1 | (1 << ((\window) / 4)) + assert eq, a2, a3 + rotw -(\window) / 4 +.endm + +test entry + entry_test 4 + entry_test 8 + entry_test 12 +test_end + +.macro entry_overflow_test window, free, next_window + set_vector window_overflow_4, 0 + set_vector window_overflow_8, 0 + set_vector window_overflow_12, 0 + set_vector window_overflow_\next_window, 10f + + movi a2, \window + movi a2, \free + movi a2, \next_window + reset_window %(1 | ((1 | (1 << ((\next_window) / 4))) << ((\free) / 4))) + reset_ps + movi a2, 0x4000f | ((\window) << 14) + wsr a2, ps + isync + movi a3, 0x12345678 + j 1f + .align 4 +1: + entry a3, 0x5678 + test_fail + .align 4 +10: + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + movi a2, 2f + wsr a2, epc1 + + rsr a2, windowbase + movi a3, (\free) / 4 + assert eq, a2, a3 + rfwo +2: +.endm + +.macro all_entry_overflow_tests + .irp window, 4, 8, 12 + .irp next_window, 4, 8, 12 + .irp free, 4, 8, 12 + .if \free <= \window + entry_overflow_test \window, \free, \next_window + .endif + .endr + .endr + .endr +.endm + +test entry_overflow + all_entry_overflow_tests +test_end + +test_suite_end diff --git a/qemu/tests/tcg/xtensa/vectors.S b/qemu/tests/tcg/xtensa/vectors.S new file mode 100644 index 000000000..265a18123 --- /dev/null +++ b/qemu/tests/tcg/xtensa/vectors.S @@ -0,0 +1,39 @@ +.macro vector name + +.section .vector.\name + j 1f +.section .vector.\name\().text +1: + wsr a2, excsave1 + movi a2, handler_\name + l32i a2, a2, 0 + beqz a2, 1f + jx a2 +1: + movi a3, 1b + movi a2, 1 + simcall + +.align 4 +.global handler_\name +handler_\name\(): .word 0 + +.endm + +vector window_overflow_4 +vector window_overflow_8 +vector window_overflow_12 +vector window_underflow_4 +vector window_underflow_8 +vector window_underflow_12 + +vector level2 +vector level3 +vector level4 +vector level5 +vector level6 +vector level7 + +vector kernel +vector user +vector double |